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
)
141 /* Check for modifiers. */
143 if (string
[0] == '^' && string
[1] != '\0') {
144 modifiers
|= KEYC_CTRL
;
147 modifiers
|= key_string_get_modifiers(&string
);
148 if (string
[0] == '\0')
151 /* Is this a standard ASCII key? */
152 if (string
[1] == '\0') {
153 key
= (u_char
) string
[0];
154 if (key
< 32 || key
== 127 || key
> 255)
157 /* Otherwise look the key up in the table. */
158 key
= key_string_search_table(string
);
159 if (key
== KEYC_NONE
)
163 /* Convert the standard control keys. */
164 if (key
< KEYC_BASE
&& (modifiers
& KEYC_CTRL
)) {
165 if (key
>= 97 && key
<= 122)
167 else if (key
>= 64 && key
<= 95)
175 modifiers
&= ~KEYC_CTRL
;
178 return (key
| modifiers
);
181 /* Convert a key code into string format, with prefix if necessary. */
183 key_string_lookup_key(int key
)
192 * Special case: display C-@ as C-Space. Could do this below in
193 * the (key >= 0 && key <= 32), but this way we let it be found
194 * in key_string_table, for the unlikely chance that we might
197 if ((key
& KEYC_MASK_KEY
) == 0)
198 key
= ' ' | KEYC_CTRL
| (key
& KEYC_MASK_MOD
);
200 /* Fill in the modifiers. */
202 strlcat(out
, "C-", sizeof out
);
203 if (key
& KEYC_ESCAPE
)
204 strlcat(out
, "M-", sizeof out
);
205 if (key
& KEYC_SHIFT
)
206 strlcat(out
, "S-", sizeof out
);
207 key
&= KEYC_MASK_KEY
;
209 /* Try the key against the string table. */
210 for (i
= 0; i
< nitems(key_string_table
); i
++) {
211 if (key
== key_string_table
[i
].key
)
214 if (i
!= nitems(key_string_table
)) {
215 strlcat(out
, key_string_table
[i
].string
, sizeof out
);
219 /* Invalid keys are errors. */
220 if (key
== 127 || key
> 255)
223 /* Check for standard or control key. */
224 if (key
>= 0 && key
<= 32) {
225 if (key
== 0 || key
> 26)
226 xsnprintf(tmp
, sizeof tmp
, "C-%c", 64 + key
);
228 xsnprintf(tmp
, sizeof tmp
, "C-%c", 96 + key
);
229 } else if (key
>= 32 && key
<= 126) {
232 } else if (key
>= 128)
233 xsnprintf(tmp
, sizeof tmp
, "\\%o", key
);
235 strlcat(out
, tmp
, sizeof out
);