2 * Copyright 1985, 1987, 1990, 1998 The Open Group
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
18 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 * Except as contained in this notice, the names of the authors or their
22 * institutions shall not be used in advertising or otherwise to promote the
23 * sale, use or other dealings in this Software without prior written
24 * authorization from the authors.
28 * Copyright © 2009 Dan Nicholson
30 * Permission is hereby granted, free of charge, to any person obtaining a
31 * copy of this software and associated documentation files (the "Software"),
32 * to deal in the Software without restriction, including without limitation
33 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
34 * and/or sell copies of the Software, and to permit persons to whom the
35 * Software is furnished to do so, subject to the following conditions:
37 * The above copyright notice and this permission notice (including the next
38 * paragraph) shall be included in all copies or substantial portions of the
41 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
44 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
46 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
47 * DEALINGS IN THE SOFTWARE.
50 #include "xkbcommon/xkbcommon.h"
52 #include "ks_tables.h"
56 xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
59 const unsigned char *entry;
60 unsigned char val1, val2, val3, val4;
62 if ((ks & ((unsigned long) ~0x1fffffff)) != 0) {
63 snprintf(buffer, size, "Invalid");
67 /* Try to find it in our hash table. */
68 if (ks <= 0x1fffffff) {
70 val2 = (ks >> 16) & 0xff;
71 val3 = (ks >> 8) & 0xff;
77 while ((idx = hashKeysym[i])) {
78 entry = &_XkeyTable[idx];
80 if ((entry[0] == val1) && (entry[1] == val2) &&
81 (entry[2] == val3) && (entry[3] == val4)) {
82 return snprintf(buffer, size, "%s", entry + 4);
94 if (ks >= 0x01000100 && ks <= 0x0110ffff)
95 /* Unnamed Unicode codepoint. */
96 return snprintf(buffer, size, "U%lx", ks & 0xffffffUL);
98 /* Unnamed, non-Unicode, symbol (shouldn't generally happen). */
99 return snprintf(buffer, size, "0x%08x", ks);
102 XKB_EXPORT xkb_keysym_t
103 xkb_keysym_from_name(const char *s)
109 const unsigned char *entry;
110 unsigned char sig1, sig2;
114 sig = (sig << 1) + c;
116 i = sig % KTABLESIZE;
118 sig1 = (sig >> 8) & 0xff;
122 while ((idx = hashString[i])) {
123 entry = &_XkeyTable[idx];
125 if ((entry[0] == sig1) && (entry[1] == sig2) &&
126 streq(s, (const char *) entry + 6)) {
127 val = (entry[2] << 24) | (entry[3] << 16) |
128 (entry[4] << 8) | entry[5];
130 val = XKB_KEY_VoidSymbol;
143 val = strtoul(&s[1], &tmp, 16);
144 if (tmp && *tmp != '\0')
145 return XKB_KEY_NoSymbol;
147 if (val < 0x20 || (val > 0x7e && val < 0xa0))
148 return XKB_KEY_NoSymbol;
152 return XKB_KEY_NoSymbol;
153 return val | 0x01000000;
155 else if (s[0] == '0' && s[1] == 'x') {
156 val = strtoul(&s[2], &tmp, 16);
157 if (tmp && *tmp != '\0')
158 return XKB_KEY_NoSymbol;
163 /* Stupid inconsistency between the headers and XKeysymDB: the former has
164 * no separating underscore, while some XF86* syms in the latter did.
165 * As a last ditch effort, try without. */
166 if (strncmp(s, "XF86_", 5) == 0) {
170 return XKB_KEY_NoSymbol;
171 memmove(&tmp[4], &tmp[5], strlen(s) - 5 + 1);
172 ret = xkb_keysym_from_name(tmp);
177 return XKB_KEY_NoSymbol;
186 static enum keysym_case
187 keysym_get_case(xkb_keysym_t ks)
189 unsigned set = (ks & (~0xff)) >> 8;
192 case 0: /* latin 1 */
193 if ((ks >= XKB_KEY_A && ks <= XKB_KEY_Z) ||
194 (ks >= XKB_KEY_Agrave && ks <= XKB_KEY_THORN && ks !=
197 if ((ks >= XKB_KEY_a && ks <= XKB_KEY_z) ||
198 (ks >= XKB_KEY_agrave && ks <= XKB_KEY_ydiaeresis))
202 case 1: /* latin 2 */
203 if ((ks >= XKB_KEY_Aogonek && ks <= XKB_KEY_Zabovedot && ks !=
205 (ks >= XKB_KEY_Racute && ks <= XKB_KEY_Tcedilla))
207 if ((ks >= XKB_KEY_aogonek && ks <= XKB_KEY_zabovedot && ks !=
209 (ks >= XKB_KEY_racute && ks <= XKB_KEY_tcedilla))
213 case 2: /* latin 3 */
214 if ((ks >= XKB_KEY_Hstroke && ks <= XKB_KEY_Jcircumflex) ||
215 (ks >= XKB_KEY_Cabovedot && ks <= XKB_KEY_Scircumflex))
217 if ((ks >= XKB_KEY_hstroke && ks <= XKB_KEY_jcircumflex) ||
218 (ks >= XKB_KEY_cabovedot && ks <= XKB_KEY_scircumflex))
222 case 3: /* latin 4 */
223 if ((ks >= XKB_KEY_Rcedilla && ks <= XKB_KEY_Tslash) ||
224 (ks == XKB_KEY_ENG) ||
225 (ks >= XKB_KEY_Amacron && ks <= XKB_KEY_Umacron))
227 if ((ks >= XKB_KEY_rcedilla && ks <= XKB_KEY_tslash) ||
228 (ks == XKB_KEY_eng) ||
229 (ks >= XKB_KEY_amacron && ks <= XKB_KEY_umacron))
233 case 6: /* Cyrillic */
234 if ((ks >= XKB_KEY_Serbian_DJE && ks <= XKB_KEY_Serbian_DZE) ||
235 (ks >= XKB_KEY_Cyrillic_YU && ks <= XKB_KEY_Cyrillic_HARDSIGN))
237 if ((ks >= XKB_KEY_Serbian_dje && ks <= XKB_KEY_Serbian_dze) ||
238 (ks >= XKB_KEY_Cyrillic_yu && ks <= XKB_KEY_Cyrillic_hardsign))
243 if ((ks >= XKB_KEY_Greek_ALPHAaccent &&
244 ks <= XKB_KEY_Greek_OMEGAaccent) ||
245 (ks >= XKB_KEY_Greek_ALPHA && ks <= XKB_KEY_Greek_OMEGA))
247 if ((ks >= XKB_KEY_Greek_alphaaccent &&
248 ks <= XKB_KEY_Greek_omegaaccent) ||
249 (ks >= XKB_KEY_Greek_alpha && ks <= XKB_KEY_Greek_OMEGA))
253 case 18: /* latin 8 */
254 if ((ks == XKB_KEY_Wcircumflex) ||
255 (ks == XKB_KEY_Ycircumflex) ||
256 (ks == XKB_KEY_Babovedot) ||
257 (ks == XKB_KEY_Dabovedot) ||
258 (ks == XKB_KEY_Fabovedot) ||
259 (ks == XKB_KEY_Mabovedot) ||
260 (ks == XKB_KEY_Pabovedot) ||
261 (ks == XKB_KEY_Sabovedot) ||
262 (ks == XKB_KEY_Tabovedot) ||
263 (ks == XKB_KEY_Wdiaeresis) ||
264 (ks == XKB_KEY_Ygrave))
266 if ((ks == XKB_KEY_wcircumflex) ||
267 (ks == XKB_KEY_ycircumflex) ||
268 (ks == XKB_KEY_babovedot) ||
269 (ks == XKB_KEY_dabovedot) ||
270 (ks == XKB_KEY_fabovedot) ||
271 (ks == XKB_KEY_mabovedot) ||
272 (ks == XKB_KEY_pabovedot) ||
273 (ks == XKB_KEY_sabovedot) ||
274 (ks == XKB_KEY_tabovedot) ||
275 (ks == XKB_KEY_wdiaeresis) ||
276 (ks == XKB_KEY_ygrave))
280 case 19: /* latin 9 */
281 if (ks == XKB_KEY_OE || ks == XKB_KEY_Ydiaeresis)
283 if (ks == XKB_KEY_oe)
292 xkb_keysym_is_lower(xkb_keysym_t keysym)
294 return keysym_get_case(keysym) == LOWERCASE;
298 xkb_keysym_is_upper(xkb_keysym_t keysym)
300 return keysym_get_case(keysym) == UPPERCASE;
304 xkb_keysym_is_keypad(xkb_keysym_t keysym)
306 return keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_Equal;