4 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
25 int key_string_search_table(const char *);
26 int key_string_get_modifiers(const char **);
31 } key_string_table
[] = {
55 { "Home", KEYC_HOME
},
57 { "NPage", KEYC_NPAGE
},
58 { "PageDown", KEYC_NPAGE
},
59 { "PgDn", KEYC_NPAGE
},
60 { "PPage", KEYC_PPAGE
},
61 { "PageUp", KEYC_PPAGE
},
62 { "PgUp", KEYC_PPAGE
},
64 { "BTab", KEYC_BTAB
},
66 { "BSpace", KEYC_BSPACE
},
72 { "Down", KEYC_DOWN
},
73 { "Left", KEYC_LEFT
},
74 { "Right", KEYC_RIGHT
},
77 { "KP/", KEYC_KP_SLASH
},
78 { "KP*", KEYC_KP_STAR
},
79 { "KP-", KEYC_KP_MINUS
},
80 { "KP7", KEYC_KP_SEVEN
},
81 { "KP8", KEYC_KP_EIGHT
},
82 { "KP9", KEYC_KP_NINE
},
83 { "KP+", KEYC_KP_PLUS
},
84 { "KP4", KEYC_KP_FOUR
},
85 { "KP5", KEYC_KP_FIVE
},
86 { "KP6", KEYC_KP_SIX
},
87 { "KP1", KEYC_KP_ONE
},
88 { "KP2", KEYC_KP_TWO
},
89 { "KP3", KEYC_KP_THREE
},
90 { "KPEnter", KEYC_KP_ENTER
},
91 { "KP0", KEYC_KP_ZERO
},
92 { "KP.", KEYC_KP_PERIOD
},
95 /* Find key string in table. */
97 key_string_search_table(const char *string
)
101 for (i
= 0; i
< nitems(key_string_table
); i
++) {
102 if (strcasecmp(string
, key_string_table
[i
].string
) == 0)
103 return (key_string_table
[i
].key
);
108 /* Find modifiers. */
110 key_string_get_modifiers(const char **string
)
115 while (((*string
)[0] != '\0') && (*string
)[1] == '-') {
116 switch ((*string
)[0]) {
119 modifiers
|= KEYC_CTRL
;
123 modifiers
|= KEYC_ESCAPE
;
127 modifiers
|= KEYC_SHIFT
;
135 /* Lookup a string and convert to a key value. */
137 key_string_lookup_string(const char *string
)
139 static const char *other
= "!#()+,-.0123456789:;<=>?'\r\t";
144 /* Is this a hexadecimal value? */
145 if (string
[0] == '0' && string
[1] == 'x') {
146 if (sscanf(string
+ 2, "%hx%n", &u
, &size
) != 1 || size
> 4)
151 /* Check for modifiers. */
153 if (string
[0] == '^' && string
[1] != '\0') {
154 modifiers
|= KEYC_CTRL
;
157 modifiers
|= key_string_get_modifiers(&string
);
158 if (string
[0] == '\0')
161 /* Is this a standard ASCII key? */
162 if (string
[1] == '\0') {
163 key
= (u_char
) string
[0];
164 if (key
< 32 || key
== 127 || key
> 255)
167 /* Otherwise look the key up in the table. */
168 key
= key_string_search_table(string
);
169 if (key
== KEYC_NONE
)
173 /* Convert the standard control keys. */
174 if (key
< KEYC_BASE
&& (modifiers
& KEYC_CTRL
) && !strchr(other
, key
)) {
175 if (key
>= 97 && key
<= 122)
177 else if (key
>= 64 && key
<= 95)
185 modifiers
&= ~KEYC_CTRL
;
188 return (key
| modifiers
);
191 /* Convert a key code into string format, with prefix if necessary. */
193 key_string_lookup_key(int key
)
202 if (key
== KEYC_NONE
)
206 * Special case: display C-@ as C-Space. Could do this below in
207 * the (key >= 0 && key <= 32), but this way we let it be found
208 * in key_string_table, for the unlikely chance that we might
211 if ((key
& KEYC_MASK_KEY
) == 0)
212 key
= ' ' | KEYC_CTRL
| (key
& KEYC_MASK_MOD
);
214 /* Fill in the modifiers. */
216 strlcat(out
, "C-", sizeof out
);
217 if (key
& KEYC_ESCAPE
)
218 strlcat(out
, "M-", sizeof out
);
219 if (key
& KEYC_SHIFT
)
220 strlcat(out
, "S-", sizeof out
);
221 key
&= KEYC_MASK_KEY
;
223 /* Try the key against the string table. */
224 for (i
= 0; i
< nitems(key_string_table
); i
++) {
225 if (key
== key_string_table
[i
].key
)
228 if (i
!= nitems(key_string_table
)) {
229 strlcat(out
, key_string_table
[i
].string
, sizeof out
);
233 /* Invalid keys are errors. */
234 if (key
== 127 || key
> 255)
237 /* Check for standard or control key. */
238 if (key
>= 0 && key
<= 32) {
239 if (key
== 0 || key
> 26)
240 xsnprintf(tmp
, sizeof tmp
, "C-%c", 64 + key
);
242 xsnprintf(tmp
, sizeof tmp
, "C-%c", 96 + key
);
243 } else if (key
>= 32 && key
<= 126) {
246 } else if (key
>= 128)
247 xsnprintf(tmp
, sizeof tmp
, "\\%o", key
);
249 strlcat(out
, tmp
, sizeof out
);