Run source tree through uncrustify
[platform/upstream/libxkbcommon.git] / src / keysym.c
1 /*
2  * Copyright 1985, 1987, 1990, 1998  The Open Group
3  * Copyright 2008  Dan Nicholson
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Except as contained in this notice, the names of the authors or their
23  * institutions shall not be used in advertising or otherwise to promote the
24  * sale, use or other dealings in this Software without prior written
25  * authorization from the authors.
26  */
27
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31
32 #include "xkb-priv.h"
33 #include "ks_tables.h"
34
35 _X_EXPORT void
36 xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
37 {
38     int i, n, h, idx;
39     const unsigned char *entry;
40     unsigned char val1, val2, val3, val4;
41
42     if ((ks & ((unsigned long) ~0x1fffffff)) != 0) {
43         snprintf(buffer, size, "Invalid");
44         return;
45     }
46
47     /* Try to find it in our hash table. */
48     if (ks <= 0x1fffffff) {
49         val1 = ks >> 24;
50         val2 = (ks >> 16) & 0xff;
51         val3 = (ks >> 8) & 0xff;
52         val4 = ks & 0xff;
53         i = ks % VTABLESIZE;
54         h = i + 1;
55         n = VMAXHASH;
56
57         while ((idx = hashKeysym[i])) {
58             entry = &_XkeyTable[idx];
59
60             if ((entry[0] == val1) && (entry[1] == val2) &&
61                 (entry[2] == val3) && (entry[3] == val4)) {
62                 snprintf(buffer, size, "%s", entry + 4);
63                 return;
64             }
65
66             if (!--n)
67                 break;
68
69             i += h;
70             if (i >= VTABLESIZE)
71                 i -= VTABLESIZE;
72         }
73     }
74
75     if (ks >= 0x01000100 && ks <= 0x0110ffff)
76         /* Unnamed Unicode codepoint. */
77         snprintf(buffer, size, "U%lx", ks & 0xffffffUL);
78     else
79         /* Unnamed, non-Unicode, symbol (shouldn't generally happen). */
80         snprintf(buffer, size, "0x%08x", ks);
81 }
82
83 _X_EXPORT xkb_keysym_t
84 xkb_keysym_from_name(const char *s)
85 {
86     int i, n, h, c, idx;
87     uint32_t sig = 0;
88     const char *p = s;
89     char *tmp;
90     const unsigned char *entry;
91     unsigned char sig1, sig2;
92     xkb_keysym_t val;
93
94     while ((c = *p++))
95         sig = (sig << 1) + c;
96
97     i = sig % KTABLESIZE;
98     h = i + 1;
99     sig1 = (sig >> 8) & 0xff;
100     sig2 = sig & 0xff;
101     n = KMAXHASH;
102
103     while ((idx = hashString[i])) {
104         entry = &_XkeyTable[idx];
105
106         if ((entry[0] == sig1) && (entry[1] == sig2) &&
107             !strcmp(s, (const char *) entry + 6)) {
108             val = (entry[2] << 24) | (entry[3] << 16) |
109                   (entry[4] << 8) | entry[5];
110             if (!val)
111                 val = XKB_KEY_VoidSymbol;
112             return val;
113         }
114
115         if (!--n)
116             break;
117
118         i += h;
119         if (i >= KTABLESIZE)
120             i -= KTABLESIZE;
121     }
122
123     if (*s == 'U') {
124         val = strtoul(&s[1], &tmp, 16);
125         if (tmp && *tmp != '\0')
126             return XKB_KEY_NoSymbol;
127
128         if (val < 0x20 || (val > 0x7e && val < 0xa0))
129             return XKB_KEY_NoSymbol;
130         if (val < 0x100)
131             return val;
132         if (val > 0x10ffff)
133             return XKB_KEY_NoSymbol;
134         return val | 0x01000000;
135     }
136     else if (s[0] == '0' && s[1] == 'x') {
137         val = strtoul(&s[2], &tmp, 16);
138         if (tmp && *tmp != '\0')
139             return XKB_KEY_NoSymbol;
140
141         return val;
142     }
143
144     /* Stupid inconsistency between the headers and XKeysymDB: the former has
145      * no separating underscore, while some XF86* syms in the latter did.
146      * As a last ditch effort, try without. */
147     if (strncmp(s, "XF86_", 5) == 0) {
148         xkb_keysym_t ret;
149         tmp = strdup(s);
150         if (!tmp)
151             return XKB_KEY_NoSymbol;
152         memmove(&tmp[4], &tmp[5], strlen(s) - 5 + 1);
153         ret = xkb_keysym_from_name(tmp);
154         free(tmp);
155         return ret;
156     }
157
158     return XKB_KEY_NoSymbol;
159 }
160
161 enum keysym_case {
162     NONE,
163     LOWERCASE,
164     UPPERCASE,
165 };
166
167 static enum keysym_case
168 keysym_get_case(xkb_keysym_t ks)
169 {
170     unsigned set = (ks & (~0xff)) >> 8;
171
172     switch (set) {
173     case 0: /* latin 1 */
174         if ((ks >= XKB_KEY_A && ks <= XKB_KEY_Z) ||
175             (ks >= XKB_KEY_Agrave && ks <= XKB_KEY_THORN && ks !=
176              XKB_KEY_multiply))
177             return UPPERCASE;
178         if ((ks >= XKB_KEY_a && ks <= XKB_KEY_z) ||
179             (ks >= XKB_KEY_agrave && ks <= XKB_KEY_ydiaeresis))
180             return LOWERCASE;
181         break;
182
183     case 1: /* latin 2 */
184         if ((ks >= XKB_KEY_Aogonek && ks <= XKB_KEY_Zabovedot && ks !=
185              XKB_KEY_breve) ||
186             (ks >= XKB_KEY_Racute && ks <= XKB_KEY_Tcedilla))
187             return UPPERCASE;
188         if ((ks >= XKB_KEY_aogonek && ks <= XKB_KEY_zabovedot && ks !=
189              XKB_KEY_caron) ||
190             (ks >= XKB_KEY_racute && ks <= XKB_KEY_tcedilla))
191             return LOWERCASE;
192         break;
193
194     case 2: /* latin 3 */
195         if ((ks >= XKB_KEY_Hstroke && ks <= XKB_KEY_Jcircumflex) ||
196             (ks >= XKB_KEY_Cabovedot && ks <= XKB_KEY_Scircumflex))
197             return UPPERCASE;
198         if ((ks >= XKB_KEY_hstroke && ks <= XKB_KEY_jcircumflex) ||
199             (ks >= XKB_KEY_cabovedot && ks <= XKB_KEY_scircumflex))
200             return LOWERCASE;
201         break;
202
203     case 3: /* latin 4 */
204         if ((ks >= XKB_KEY_Rcedilla && ks <= XKB_KEY_Tslash) ||
205             (ks == XKB_KEY_ENG) ||
206             (ks >= XKB_KEY_Amacron && ks <= XKB_KEY_Umacron))
207             return UPPERCASE;
208         if ((ks >= XKB_KEY_rcedilla && ks <= XKB_KEY_tslash) ||
209             (ks == XKB_KEY_eng) ||
210             (ks >= XKB_KEY_amacron && ks <= XKB_KEY_umacron))
211             return LOWERCASE;
212         break;
213
214     case 6: /* Cyrillic */
215         if ((ks >= XKB_KEY_Serbian_DJE && ks <= XKB_KEY_Serbian_DZE) ||
216             (ks >= XKB_KEY_Cyrillic_YU && ks <= XKB_KEY_Cyrillic_HARDSIGN))
217             return UPPERCASE;
218         if ((ks >= XKB_KEY_Serbian_dje && ks <= XKB_KEY_Serbian_dze) ||
219             (ks >= XKB_KEY_Cyrillic_yu && ks <= XKB_KEY_Cyrillic_hardsign))
220             return LOWERCASE;
221         break;
222
223     case 7: /* Greek */
224         if ((ks >= XKB_KEY_Greek_ALPHAaccent &&
225              ks <= XKB_KEY_Greek_OMEGAaccent) ||
226             (ks >= XKB_KEY_Greek_ALPHA && ks <= XKB_KEY_Greek_OMEGA))
227             return UPPERCASE;
228         if ((ks >= XKB_KEY_Greek_alphaaccent &&
229              ks <= XKB_KEY_Greek_omegaaccent) ||
230             (ks >= XKB_KEY_Greek_alpha && ks <= XKB_KEY_Greek_OMEGA))
231             return LOWERCASE;
232         break;
233
234     case 18: /* latin 8 */
235         if ((ks == XKB_KEY_Wcircumflex) ||
236             (ks == XKB_KEY_Ycircumflex) ||
237             (ks == XKB_KEY_Babovedot) ||
238             (ks == XKB_KEY_Dabovedot) ||
239             (ks == XKB_KEY_Fabovedot) ||
240             (ks == XKB_KEY_Mabovedot) ||
241             (ks == XKB_KEY_Pabovedot) ||
242             (ks == XKB_KEY_Sabovedot) ||
243             (ks == XKB_KEY_Tabovedot) ||
244             (ks == XKB_KEY_Wdiaeresis) ||
245             (ks == XKB_KEY_Ygrave))
246             return UPPERCASE;
247         if ((ks == XKB_KEY_wcircumflex) ||
248             (ks == XKB_KEY_ycircumflex) ||
249             (ks == XKB_KEY_babovedot) ||
250             (ks == XKB_KEY_dabovedot) ||
251             (ks == XKB_KEY_fabovedot) ||
252             (ks == XKB_KEY_mabovedot) ||
253             (ks == XKB_KEY_pabovedot) ||
254             (ks == XKB_KEY_sabovedot) ||
255             (ks == XKB_KEY_tabovedot) ||
256             (ks == XKB_KEY_wdiaeresis) ||
257             (ks == XKB_KEY_ygrave))
258             return LOWERCASE;
259         break;
260
261     case 19: /* latin 9 */
262         if (ks == XKB_KEY_OE || ks == XKB_KEY_Ydiaeresis)
263             return UPPERCASE;
264         if (ks == XKB_KEY_oe)
265             return LOWERCASE;
266         break;
267     }
268
269     return NONE;
270 }
271
272 bool
273 xkb_keysym_is_lower(xkb_keysym_t keysym)
274 {
275     return keysym_get_case(keysym) == LOWERCASE;
276 }
277
278 bool
279 xkb_keysym_is_upper(xkb_keysym_t keysym)
280 {
281     return keysym_get_case(keysym) == UPPERCASE;
282 }
283
284 bool
285 xkb_keysym_is_keypad(xkb_keysym_t keysym)
286 {
287     return keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_Equal;
288 }