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 { "PPage", KEYC_PPAGE
},
60 { "BTab", KEYC_BTAB
},
62 { "BSpace", KEYC_BSPACE
},
68 { "Down", KEYC_DOWN
},
69 { "Left", KEYC_LEFT
},
70 { "Right", KEYC_RIGHT
},
73 { "KP/", KEYC_KP_SLASH
},
74 { "KP*", KEYC_KP_STAR
},
75 { "KP-", KEYC_KP_MINUS
},
76 { "KP7", KEYC_KP_SEVEN
},
77 { "KP8", KEYC_KP_EIGHT
},
78 { "KP9", KEYC_KP_NINE
},
79 { "KP+", KEYC_KP_PLUS
},
80 { "KP4", KEYC_KP_FOUR
},
81 { "KP5", KEYC_KP_FIVE
},
82 { "KP6", KEYC_KP_SIX
},
83 { "KP1", KEYC_KP_ONE
},
84 { "KP2", KEYC_KP_TWO
},
85 { "KP3", KEYC_KP_THREE
},
86 { "KPEnter", KEYC_KP_ENTER
},
87 { "KP0", KEYC_KP_ZERO
},
88 { "KP.", KEYC_KP_PERIOD
},
91 /* Find key string in table. */
93 key_string_search_table(const char *string
)
97 for (i
= 0; i
< nitems(key_string_table
); i
++) {
98 if (strcasecmp(string
, key_string_table
[i
].string
) == 0)
99 return (key_string_table
[i
].key
);
104 /* Find modifiers. */
106 key_string_get_modifiers(const char **string
)
111 while (((*string
)[0] != '\0') && (*string
)[1] == '-') {
112 switch ((*string
)[0]) {
115 modifiers
|= KEYC_CTRL
;
119 modifiers
|= KEYC_ESCAPE
;
123 modifiers
|= KEYC_SHIFT
;
131 /* Lookup a string and convert to a key value. */
133 key_string_lookup_string(const char *string
)
137 /* Check for modifiers. */
139 if (string
[0] == '^' && string
[1] != '\0') {
140 modifiers
|= KEYC_CTRL
;
143 modifiers
|= key_string_get_modifiers(&string
);
144 if (string
[0] == '\0')
147 /* Is this a standard ASCII key? */
148 if (string
[1] == '\0') {
149 key
= (u_char
) string
[0];
150 if (key
< 32 || key
> 126)
153 /* Otherwise look the key up in the table. */
154 key
= key_string_search_table(string
);
155 if (key
== KEYC_NONE
)
159 /* Convert the standard control keys. */
160 if (key
< KEYC_BASE
&& (modifiers
& KEYC_CTRL
)) {
161 if (key
>= 97 && key
<= 122)
163 else if (key
>= 64 && key
<= 95)
171 modifiers
&= ~KEYC_CTRL
;
174 return (key
| modifiers
);
177 /* Convert a key code into string format, with prefix if necessary. */
179 key_string_lookup_key(int key
)
188 * Special case: display C-@ as C-Space. Could do this below in
189 * the (key >= 0 && key <= 32), but this way we let it be found
190 * in key_string_table, for the unlikely chance that we might
193 if ((key
& KEYC_MASK_KEY
) == 0)
194 key
= ' ' | KEYC_CTRL
| (key
& KEYC_MASK_MOD
);
196 /* Fill in the modifiers. */
198 strlcat(out
, "C-", sizeof out
);
199 if (key
& KEYC_ESCAPE
)
200 strlcat(out
, "M-", sizeof out
);
201 if (key
& KEYC_SHIFT
)
202 strlcat(out
, "S-", sizeof out
);
203 key
&= KEYC_MASK_KEY
;
205 /* Try the key against the string table. */
206 for (i
= 0; i
< nitems(key_string_table
); i
++) {
207 if (key
== key_string_table
[i
].key
)
210 if (i
!= nitems(key_string_table
)) {
211 strlcat(out
, key_string_table
[i
].string
, sizeof out
);
215 /* Invalid keys are errors. */
219 /* Check for standard or control key. */
220 if (key
>= 0 && key
<= 32) {
221 if (key
== 0 || key
> 26)
222 xsnprintf(tmp
, sizeof tmp
, "C-%c", 64 + key
);
224 xsnprintf(tmp
, sizeof tmp
, "C-%c", 96 + key
);
225 } else if (key
>= 32 && key
<= 126) {
229 strlcat(out
, tmp
, sizeof out
);