xref: /aosp_15_r20/external/libxkbcommon/src/keysym.c (revision 2b949d0487e80d67f1fda82db69e101e761f8064)
1*2b949d04SAndroid Build Coastguard Worker /*
2*2b949d04SAndroid Build Coastguard Worker  * Copyright 1985, 1987, 1990, 1998  The Open Group
3*2b949d04SAndroid Build Coastguard Worker  *
4*2b949d04SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*2b949d04SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*2b949d04SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*2b949d04SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*2b949d04SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*2b949d04SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*2b949d04SAndroid Build Coastguard Worker  *
11*2b949d04SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
12*2b949d04SAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
13*2b949d04SAndroid Build Coastguard Worker  *
14*2b949d04SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*2b949d04SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*2b949d04SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17*2b949d04SAndroid Build Coastguard Worker  * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
18*2b949d04SAndroid Build Coastguard Worker  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19*2b949d04SAndroid Build Coastguard Worker  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20*2b949d04SAndroid Build Coastguard Worker  *
21*2b949d04SAndroid Build Coastguard Worker  * Except as contained in this notice, the names of the authors or their
22*2b949d04SAndroid Build Coastguard Worker  * institutions shall not be used in advertising or otherwise to promote the
23*2b949d04SAndroid Build Coastguard Worker  * sale, use or other dealings in this Software without prior written
24*2b949d04SAndroid Build Coastguard Worker  * authorization from the authors.
25*2b949d04SAndroid Build Coastguard Worker  */
26*2b949d04SAndroid Build Coastguard Worker 
27*2b949d04SAndroid Build Coastguard Worker /*
28*2b949d04SAndroid Build Coastguard Worker  * Copyright © 2009 Dan Nicholson
29*2b949d04SAndroid Build Coastguard Worker  *
30*2b949d04SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
31*2b949d04SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
32*2b949d04SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
33*2b949d04SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
34*2b949d04SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
35*2b949d04SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
36*2b949d04SAndroid Build Coastguard Worker  *
37*2b949d04SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
38*2b949d04SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
39*2b949d04SAndroid Build Coastguard Worker  * Software.
40*2b949d04SAndroid Build Coastguard Worker  *
41*2b949d04SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42*2b949d04SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43*2b949d04SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
44*2b949d04SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45*2b949d04SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
46*2b949d04SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
47*2b949d04SAndroid Build Coastguard Worker  * DEALINGS IN THE SOFTWARE.
48*2b949d04SAndroid Build Coastguard Worker  */
49*2b949d04SAndroid Build Coastguard Worker 
50*2b949d04SAndroid Build Coastguard Worker #include "config.h"
51*2b949d04SAndroid Build Coastguard Worker 
52*2b949d04SAndroid Build Coastguard Worker #include <stdlib.h>
53*2b949d04SAndroid Build Coastguard Worker #include "xkbcommon/xkbcommon.h"
54*2b949d04SAndroid Build Coastguard Worker #include "utils.h"
55*2b949d04SAndroid Build Coastguard Worker #include "keysym.h"
56*2b949d04SAndroid Build Coastguard Worker #include "ks_tables.h"
57*2b949d04SAndroid Build Coastguard Worker 
58*2b949d04SAndroid Build Coastguard Worker static inline const char *
get_name(const struct name_keysym * entry)59*2b949d04SAndroid Build Coastguard Worker get_name(const struct name_keysym *entry)
60*2b949d04SAndroid Build Coastguard Worker {
61*2b949d04SAndroid Build Coastguard Worker     return keysym_names + entry->offset;
62*2b949d04SAndroid Build Coastguard Worker }
63*2b949d04SAndroid Build Coastguard Worker 
64*2b949d04SAndroid Build Coastguard Worker XKB_EXPORT int
xkb_keysym_get_name(xkb_keysym_t ks,char * buffer,size_t size)65*2b949d04SAndroid Build Coastguard Worker xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
66*2b949d04SAndroid Build Coastguard Worker {
67*2b949d04SAndroid Build Coastguard Worker     if ((ks & ((unsigned long) ~0x1fffffff)) != 0) {
68*2b949d04SAndroid Build Coastguard Worker         snprintf(buffer, size, "Invalid");
69*2b949d04SAndroid Build Coastguard Worker         return -1;
70*2b949d04SAndroid Build Coastguard Worker     }
71*2b949d04SAndroid Build Coastguard Worker 
72*2b949d04SAndroid Build Coastguard Worker     int32_t lo = 0, hi = ARRAY_SIZE(keysym_to_name) - 1;
73*2b949d04SAndroid Build Coastguard Worker     while (hi >= lo) {
74*2b949d04SAndroid Build Coastguard Worker         int32_t mid = (lo + hi) / 2;
75*2b949d04SAndroid Build Coastguard Worker         if (ks > keysym_to_name[mid].keysym) {
76*2b949d04SAndroid Build Coastguard Worker             lo = mid + 1;
77*2b949d04SAndroid Build Coastguard Worker         } else if (ks < keysym_to_name[mid].keysym) {
78*2b949d04SAndroid Build Coastguard Worker             hi = mid - 1;
79*2b949d04SAndroid Build Coastguard Worker         } else {
80*2b949d04SAndroid Build Coastguard Worker             return snprintf(buffer, size, "%s", get_name(&keysym_to_name[mid]));
81*2b949d04SAndroid Build Coastguard Worker         }
82*2b949d04SAndroid Build Coastguard Worker     }
83*2b949d04SAndroid Build Coastguard Worker 
84*2b949d04SAndroid Build Coastguard Worker     /* Unnamed Unicode codepoint. */
85*2b949d04SAndroid Build Coastguard Worker     if (ks >= 0x01000100 && ks <= 0x0110ffff) {
86*2b949d04SAndroid Build Coastguard Worker         const int width = (ks & 0xff0000UL) ? 8 : 4;
87*2b949d04SAndroid Build Coastguard Worker         return snprintf(buffer, size, "U%0*lX", width, ks & 0xffffffUL);
88*2b949d04SAndroid Build Coastguard Worker     }
89*2b949d04SAndroid Build Coastguard Worker 
90*2b949d04SAndroid Build Coastguard Worker     /* Unnamed, non-Unicode, symbol (shouldn't generally happen). */
91*2b949d04SAndroid Build Coastguard Worker     return snprintf(buffer, size, "0x%08x", ks);
92*2b949d04SAndroid Build Coastguard Worker }
93*2b949d04SAndroid Build Coastguard Worker 
94*2b949d04SAndroid Build Coastguard Worker /*
95*2b949d04SAndroid Build Coastguard Worker  * Parse the numeric part of a 0xXXXX and UXXXX keysym.
96*2b949d04SAndroid Build Coastguard Worker  * Not using strtoul -- it's slower and accepts a bunch of stuff
97*2b949d04SAndroid Build Coastguard Worker  * we don't want to allow, like signs, spaces, even locale stuff.
98*2b949d04SAndroid Build Coastguard Worker  */
99*2b949d04SAndroid Build Coastguard Worker static bool
parse_keysym_hex(const char * s,uint32_t * out)100*2b949d04SAndroid Build Coastguard Worker parse_keysym_hex(const char *s, uint32_t *out)
101*2b949d04SAndroid Build Coastguard Worker {
102*2b949d04SAndroid Build Coastguard Worker     uint32_t result = 0;
103*2b949d04SAndroid Build Coastguard Worker     int i;
104*2b949d04SAndroid Build Coastguard Worker     for (i = 0; i < 8 && s[i] != '\0'; i++) {
105*2b949d04SAndroid Build Coastguard Worker         result <<= 4;
106*2b949d04SAndroid Build Coastguard Worker         if ('0' <= s[i] && s[i] <= '9')
107*2b949d04SAndroid Build Coastguard Worker             result += s[i] - '0';
108*2b949d04SAndroid Build Coastguard Worker         else if ('a' <= s[i] && s[i] <= 'f')
109*2b949d04SAndroid Build Coastguard Worker             result += 10 + s[i] - 'a';
110*2b949d04SAndroid Build Coastguard Worker         else if ('A' <= s[i] && s[i] <= 'F')
111*2b949d04SAndroid Build Coastguard Worker             result += 10 + s[i] - 'A';
112*2b949d04SAndroid Build Coastguard Worker         else
113*2b949d04SAndroid Build Coastguard Worker             return false;
114*2b949d04SAndroid Build Coastguard Worker     }
115*2b949d04SAndroid Build Coastguard Worker     *out = result;
116*2b949d04SAndroid Build Coastguard Worker     return s[i] == '\0' && i > 0;
117*2b949d04SAndroid Build Coastguard Worker }
118*2b949d04SAndroid Build Coastguard Worker 
119*2b949d04SAndroid Build Coastguard Worker XKB_EXPORT xkb_keysym_t
xkb_keysym_from_name(const char * name,enum xkb_keysym_flags flags)120*2b949d04SAndroid Build Coastguard Worker xkb_keysym_from_name(const char *name, enum xkb_keysym_flags flags)
121*2b949d04SAndroid Build Coastguard Worker {
122*2b949d04SAndroid Build Coastguard Worker     const struct name_keysym *entry = NULL;
123*2b949d04SAndroid Build Coastguard Worker     char *tmp;
124*2b949d04SAndroid Build Coastguard Worker     uint32_t val;
125*2b949d04SAndroid Build Coastguard Worker     bool icase = (flags & XKB_KEYSYM_CASE_INSENSITIVE);
126*2b949d04SAndroid Build Coastguard Worker 
127*2b949d04SAndroid Build Coastguard Worker     if (flags & ~XKB_KEYSYM_CASE_INSENSITIVE)
128*2b949d04SAndroid Build Coastguard Worker         return XKB_KEY_NoSymbol;
129*2b949d04SAndroid Build Coastguard Worker 
130*2b949d04SAndroid Build Coastguard Worker     /*
131*2b949d04SAndroid Build Coastguard Worker      * We need to !icase case to be fast, for e.g. Compose file parsing.
132*2b949d04SAndroid Build Coastguard Worker      * So do it in a fast path.
133*2b949d04SAndroid Build Coastguard Worker      */
134*2b949d04SAndroid Build Coastguard Worker     if (!icase) {
135*2b949d04SAndroid Build Coastguard Worker         size_t pos = keysym_name_perfect_hash(name);
136*2b949d04SAndroid Build Coastguard Worker         if (pos < ARRAY_SIZE(name_to_keysym)) {
137*2b949d04SAndroid Build Coastguard Worker             const char *s = get_name(&name_to_keysym[pos]);
138*2b949d04SAndroid Build Coastguard Worker             if (strcmp(name, s) == 0)
139*2b949d04SAndroid Build Coastguard Worker                 return name_to_keysym[pos].keysym;
140*2b949d04SAndroid Build Coastguard Worker         }
141*2b949d04SAndroid Build Coastguard Worker     }
142*2b949d04SAndroid Build Coastguard Worker     /*
143*2b949d04SAndroid Build Coastguard Worker     * Find the correct keysym for case-insensitive match.
144*2b949d04SAndroid Build Coastguard Worker     *
145*2b949d04SAndroid Build Coastguard Worker     * The name_to_keysym table is sorted by istrcmp(). So the binary
146*2b949d04SAndroid Build Coastguard Worker     * search may return _any_ of all possible case-insensitive duplicates. This
147*2b949d04SAndroid Build Coastguard Worker     * code searches the entry, all previous and all next entries that match by
148*2b949d04SAndroid Build Coastguard Worker     * case-insensitive comparison and returns the "best" case-insensitive
149*2b949d04SAndroid Build Coastguard Worker     * match.
150*2b949d04SAndroid Build Coastguard Worker     *
151*2b949d04SAndroid Build Coastguard Worker     * The "best" case-insensitive match is the lower-case keysym which we find
152*2b949d04SAndroid Build Coastguard Worker     * with the help of xkb_keysym_is_lower(). The only keysyms that only differ
153*2b949d04SAndroid Build Coastguard Worker     * by letter-case are keysyms that are available as lower-case and
154*2b949d04SAndroid Build Coastguard Worker     * upper-case variant (like KEY_a and KEY_A). So returning the first
155*2b949d04SAndroid Build Coastguard Worker     * lower-case match is enough in this case.
156*2b949d04SAndroid Build Coastguard Worker     */
157*2b949d04SAndroid Build Coastguard Worker     else {
158*2b949d04SAndroid Build Coastguard Worker         int32_t lo = 0, hi = ARRAY_SIZE(name_to_keysym) - 1;
159*2b949d04SAndroid Build Coastguard Worker         while (hi >= lo) {
160*2b949d04SAndroid Build Coastguard Worker             int32_t mid = (lo + hi) / 2;
161*2b949d04SAndroid Build Coastguard Worker             int cmp = istrcmp(name, get_name(&name_to_keysym[mid]));
162*2b949d04SAndroid Build Coastguard Worker             if (cmp > 0) {
163*2b949d04SAndroid Build Coastguard Worker                 lo = mid + 1;
164*2b949d04SAndroid Build Coastguard Worker             } else if (cmp < 0) {
165*2b949d04SAndroid Build Coastguard Worker                 hi = mid - 1;
166*2b949d04SAndroid Build Coastguard Worker             } else {
167*2b949d04SAndroid Build Coastguard Worker                 entry = &name_to_keysym[mid];
168*2b949d04SAndroid Build Coastguard Worker                 break;
169*2b949d04SAndroid Build Coastguard Worker             }
170*2b949d04SAndroid Build Coastguard Worker         }
171*2b949d04SAndroid Build Coastguard Worker         if (entry) {
172*2b949d04SAndroid Build Coastguard Worker             const struct name_keysym *iter, *last;
173*2b949d04SAndroid Build Coastguard Worker 
174*2b949d04SAndroid Build Coastguard Worker             if (icase && xkb_keysym_is_lower(entry->keysym))
175*2b949d04SAndroid Build Coastguard Worker                 return entry->keysym;
176*2b949d04SAndroid Build Coastguard Worker 
177*2b949d04SAndroid Build Coastguard Worker             for (iter = entry - 1; iter >= name_to_keysym; --iter) {
178*2b949d04SAndroid Build Coastguard Worker                 if (istrcmp(get_name(iter), get_name(entry)) != 0)
179*2b949d04SAndroid Build Coastguard Worker                     break;
180*2b949d04SAndroid Build Coastguard Worker                 if (xkb_keysym_is_lower(iter->keysym))
181*2b949d04SAndroid Build Coastguard Worker                     return iter->keysym;
182*2b949d04SAndroid Build Coastguard Worker             }
183*2b949d04SAndroid Build Coastguard Worker 
184*2b949d04SAndroid Build Coastguard Worker             last = name_to_keysym + ARRAY_SIZE(name_to_keysym);
185*2b949d04SAndroid Build Coastguard Worker             for (iter = entry + 1; iter < last; ++iter) {
186*2b949d04SAndroid Build Coastguard Worker                 if (istrcmp(get_name(iter), get_name(entry)) != 0)
187*2b949d04SAndroid Build Coastguard Worker                     break;
188*2b949d04SAndroid Build Coastguard Worker                 if (xkb_keysym_is_lower(iter->keysym))
189*2b949d04SAndroid Build Coastguard Worker                     return iter->keysym;
190*2b949d04SAndroid Build Coastguard Worker             }
191*2b949d04SAndroid Build Coastguard Worker 
192*2b949d04SAndroid Build Coastguard Worker             return entry->keysym;
193*2b949d04SAndroid Build Coastguard Worker         }
194*2b949d04SAndroid Build Coastguard Worker     }
195*2b949d04SAndroid Build Coastguard Worker 
196*2b949d04SAndroid Build Coastguard Worker     if (*name == 'U' || (icase && *name == 'u')) {
197*2b949d04SAndroid Build Coastguard Worker         if (!parse_keysym_hex(&name[1], &val))
198*2b949d04SAndroid Build Coastguard Worker             return XKB_KEY_NoSymbol;
199*2b949d04SAndroid Build Coastguard Worker 
200*2b949d04SAndroid Build Coastguard Worker         if (val < 0x20 || (val > 0x7e && val < 0xa0))
201*2b949d04SAndroid Build Coastguard Worker             return XKB_KEY_NoSymbol;
202*2b949d04SAndroid Build Coastguard Worker         if (val < 0x100)
203*2b949d04SAndroid Build Coastguard Worker             return (xkb_keysym_t) val;
204*2b949d04SAndroid Build Coastguard Worker         if (val > 0x10ffff)
205*2b949d04SAndroid Build Coastguard Worker             return XKB_KEY_NoSymbol;
206*2b949d04SAndroid Build Coastguard Worker         return (xkb_keysym_t) val | 0x01000000;
207*2b949d04SAndroid Build Coastguard Worker     }
208*2b949d04SAndroid Build Coastguard Worker     else if (name[0] == '0' && (name[1] == 'x' || (icase && name[1] == 'X'))) {
209*2b949d04SAndroid Build Coastguard Worker         if (!parse_keysym_hex(&name[2], &val))
210*2b949d04SAndroid Build Coastguard Worker             return XKB_KEY_NoSymbol;
211*2b949d04SAndroid Build Coastguard Worker         return (xkb_keysym_t) val;
212*2b949d04SAndroid Build Coastguard Worker     }
213*2b949d04SAndroid Build Coastguard Worker 
214*2b949d04SAndroid Build Coastguard Worker     /* Stupid inconsistency between the headers and XKeysymDB: the former has
215*2b949d04SAndroid Build Coastguard Worker      * no separating underscore, while some XF86* syms in the latter did.
216*2b949d04SAndroid Build Coastguard Worker      * As a last ditch effort, try without. */
217*2b949d04SAndroid Build Coastguard Worker     if (strncmp(name, "XF86_", 5) == 0 ||
218*2b949d04SAndroid Build Coastguard Worker         (icase && istrncmp(name, "XF86_", 5) == 0)) {
219*2b949d04SAndroid Build Coastguard Worker         xkb_keysym_t ret;
220*2b949d04SAndroid Build Coastguard Worker         tmp = strdup(name);
221*2b949d04SAndroid Build Coastguard Worker         if (!tmp)
222*2b949d04SAndroid Build Coastguard Worker             return XKB_KEY_NoSymbol;
223*2b949d04SAndroid Build Coastguard Worker         memmove(&tmp[4], &tmp[5], strlen(name) - 5 + 1);
224*2b949d04SAndroid Build Coastguard Worker         ret = xkb_keysym_from_name(tmp, flags);
225*2b949d04SAndroid Build Coastguard Worker         free(tmp);
226*2b949d04SAndroid Build Coastguard Worker         return ret;
227*2b949d04SAndroid Build Coastguard Worker     }
228*2b949d04SAndroid Build Coastguard Worker 
229*2b949d04SAndroid Build Coastguard Worker     return XKB_KEY_NoSymbol;
230*2b949d04SAndroid Build Coastguard Worker }
231*2b949d04SAndroid Build Coastguard Worker 
232*2b949d04SAndroid Build Coastguard Worker bool
xkb_keysym_is_keypad(xkb_keysym_t keysym)233*2b949d04SAndroid Build Coastguard Worker xkb_keysym_is_keypad(xkb_keysym_t keysym)
234*2b949d04SAndroid Build Coastguard Worker {
235*2b949d04SAndroid Build Coastguard Worker     return keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_Equal;
236*2b949d04SAndroid Build Coastguard Worker }
237*2b949d04SAndroid Build Coastguard Worker 
238*2b949d04SAndroid Build Coastguard Worker 
239*2b949d04SAndroid Build Coastguard Worker bool
xkb_keysym_is_modifier(xkb_keysym_t keysym)240*2b949d04SAndroid Build Coastguard Worker xkb_keysym_is_modifier(xkb_keysym_t keysym)
241*2b949d04SAndroid Build Coastguard Worker {
242*2b949d04SAndroid Build Coastguard Worker     return
243*2b949d04SAndroid Build Coastguard Worker         (keysym >= XKB_KEY_Shift_L && keysym <= XKB_KEY_Hyper_R) ||
244*2b949d04SAndroid Build Coastguard Worker         /* libX11 only goes upto XKB_KEY_ISO_Level5_Lock. */
245*2b949d04SAndroid Build Coastguard Worker         (keysym >= XKB_KEY_ISO_Lock && keysym <= XKB_KEY_ISO_Last_Group_Lock) ||
246*2b949d04SAndroid Build Coastguard Worker         keysym == XKB_KEY_Mode_switch ||
247*2b949d04SAndroid Build Coastguard Worker         keysym == XKB_KEY_Num_Lock;
248*2b949d04SAndroid Build Coastguard Worker }
249*2b949d04SAndroid Build Coastguard Worker 
250*2b949d04SAndroid Build Coastguard Worker static void
251*2b949d04SAndroid Build Coastguard Worker XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper);
252*2b949d04SAndroid Build Coastguard Worker 
253*2b949d04SAndroid Build Coastguard Worker bool
xkb_keysym_is_lower(xkb_keysym_t ks)254*2b949d04SAndroid Build Coastguard Worker xkb_keysym_is_lower(xkb_keysym_t ks)
255*2b949d04SAndroid Build Coastguard Worker {
256*2b949d04SAndroid Build Coastguard Worker     xkb_keysym_t lower, upper;
257*2b949d04SAndroid Build Coastguard Worker 
258*2b949d04SAndroid Build Coastguard Worker     XConvertCase(ks, &lower, &upper);
259*2b949d04SAndroid Build Coastguard Worker 
260*2b949d04SAndroid Build Coastguard Worker     if (lower == upper)
261*2b949d04SAndroid Build Coastguard Worker         return false;
262*2b949d04SAndroid Build Coastguard Worker 
263*2b949d04SAndroid Build Coastguard Worker     return (ks == lower ? true : false);
264*2b949d04SAndroid Build Coastguard Worker }
265*2b949d04SAndroid Build Coastguard Worker 
266*2b949d04SAndroid Build Coastguard Worker bool
xkb_keysym_is_upper(xkb_keysym_t ks)267*2b949d04SAndroid Build Coastguard Worker xkb_keysym_is_upper(xkb_keysym_t ks)
268*2b949d04SAndroid Build Coastguard Worker {
269*2b949d04SAndroid Build Coastguard Worker     xkb_keysym_t lower, upper;
270*2b949d04SAndroid Build Coastguard Worker 
271*2b949d04SAndroid Build Coastguard Worker     XConvertCase(ks, &lower, &upper);
272*2b949d04SAndroid Build Coastguard Worker 
273*2b949d04SAndroid Build Coastguard Worker     if (lower == upper)
274*2b949d04SAndroid Build Coastguard Worker         return false;
275*2b949d04SAndroid Build Coastguard Worker 
276*2b949d04SAndroid Build Coastguard Worker     return (ks == upper ? true : false);
277*2b949d04SAndroid Build Coastguard Worker }
278*2b949d04SAndroid Build Coastguard Worker 
279*2b949d04SAndroid Build Coastguard Worker XKB_EXPORT xkb_keysym_t
xkb_keysym_to_lower(xkb_keysym_t ks)280*2b949d04SAndroid Build Coastguard Worker xkb_keysym_to_lower(xkb_keysym_t ks)
281*2b949d04SAndroid Build Coastguard Worker {
282*2b949d04SAndroid Build Coastguard Worker     xkb_keysym_t lower, upper;
283*2b949d04SAndroid Build Coastguard Worker 
284*2b949d04SAndroid Build Coastguard Worker     XConvertCase(ks, &lower, &upper);
285*2b949d04SAndroid Build Coastguard Worker 
286*2b949d04SAndroid Build Coastguard Worker     return lower;
287*2b949d04SAndroid Build Coastguard Worker }
288*2b949d04SAndroid Build Coastguard Worker 
289*2b949d04SAndroid Build Coastguard Worker XKB_EXPORT xkb_keysym_t
xkb_keysym_to_upper(xkb_keysym_t ks)290*2b949d04SAndroid Build Coastguard Worker xkb_keysym_to_upper(xkb_keysym_t ks)
291*2b949d04SAndroid Build Coastguard Worker {
292*2b949d04SAndroid Build Coastguard Worker     xkb_keysym_t lower, upper;
293*2b949d04SAndroid Build Coastguard Worker 
294*2b949d04SAndroid Build Coastguard Worker     XConvertCase(ks, &lower, &upper);
295*2b949d04SAndroid Build Coastguard Worker 
296*2b949d04SAndroid Build Coastguard Worker     return upper;
297*2b949d04SAndroid Build Coastguard Worker }
298*2b949d04SAndroid Build Coastguard Worker 
299*2b949d04SAndroid Build Coastguard Worker /*
300*2b949d04SAndroid Build Coastguard Worker  * The following is copied verbatim from libX11:src/KeyBind.c, commit
301*2b949d04SAndroid Build Coastguard Worker  * d45b3fc19fbe95c41afc4e51d768df6d42332010, with the following changes:
302*2b949d04SAndroid Build Coastguard Worker  *  - unsigned -> uint32_t
303*2b949d04SAndroid Build Coastguard Worker  *  - unsigend short -> uint16_t
304*2b949d04SAndroid Build Coastguard Worker  *  - s/XK_/XKB_KEY_
305*2b949d04SAndroid Build Coastguard Worker  *
306*2b949d04SAndroid Build Coastguard Worker  * XXX: If newlocale() and iswlower_l()/iswupper_l() interface ever
307*2b949d04SAndroid Build Coastguard Worker  *      become portable, we should use that in conjunction with
308*2b949d04SAndroid Build Coastguard Worker  *      xkb_keysym_to_utf32(), instead of all this stuff.  We should
309*2b949d04SAndroid Build Coastguard Worker  *      be sure to give the same results as libX11, though, and be
310*2b949d04SAndroid Build Coastguard Worker  *      locale independent; this information is used by xkbcomp to
311*2b949d04SAndroid Build Coastguard Worker  *      find the automatic type to assign to key groups.
312*2b949d04SAndroid Build Coastguard Worker  */
313*2b949d04SAndroid Build Coastguard Worker 
314*2b949d04SAndroid Build Coastguard Worker static void
UCSConvertCase(uint32_t code,xkb_keysym_t * lower,xkb_keysym_t * upper)315*2b949d04SAndroid Build Coastguard Worker UCSConvertCase(uint32_t code, xkb_keysym_t *lower, xkb_keysym_t *upper)
316*2b949d04SAndroid Build Coastguard Worker {
317*2b949d04SAndroid Build Coastguard Worker     /* Case conversion for UCS, as in Unicode Data version 4.0.0 */
318*2b949d04SAndroid Build Coastguard Worker     /* NB: Only converts simple one-to-one mappings. */
319*2b949d04SAndroid Build Coastguard Worker 
320*2b949d04SAndroid Build Coastguard Worker     /* Tables are used where they take less space than     */
321*2b949d04SAndroid Build Coastguard Worker     /* the code to work out the mappings. Zero values mean */
322*2b949d04SAndroid Build Coastguard Worker     /* undefined code points.                              */
323*2b949d04SAndroid Build Coastguard Worker 
324*2b949d04SAndroid Build Coastguard Worker     static uint16_t const IPAExt_upper_mapping[] = { /* part only */
325*2b949d04SAndroid Build Coastguard Worker                             0x0181, 0x0186, 0x0255, 0x0189, 0x018A,
326*2b949d04SAndroid Build Coastguard Worker     0x0258, 0x018F, 0x025A, 0x0190, 0x025C, 0x025D, 0x025E, 0x025F,
327*2b949d04SAndroid Build Coastguard Worker     0x0193, 0x0261, 0x0262, 0x0194, 0x0264, 0x0265, 0x0266, 0x0267,
328*2b949d04SAndroid Build Coastguard Worker     0x0197, 0x0196, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x019C,
329*2b949d04SAndroid Build Coastguard Worker     0x0270, 0x0271, 0x019D, 0x0273, 0x0274, 0x019F, 0x0276, 0x0277,
330*2b949d04SAndroid Build Coastguard Worker     0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F,
331*2b949d04SAndroid Build Coastguard Worker     0x01A6, 0x0281, 0x0282, 0x01A9, 0x0284, 0x0285, 0x0286, 0x0287,
332*2b949d04SAndroid Build Coastguard Worker     0x01AE, 0x0289, 0x01B1, 0x01B2, 0x028C, 0x028D, 0x028E, 0x028F,
333*2b949d04SAndroid Build Coastguard Worker     0x0290, 0x0291, 0x01B7
334*2b949d04SAndroid Build Coastguard Worker     };
335*2b949d04SAndroid Build Coastguard Worker 
336*2b949d04SAndroid Build Coastguard Worker     static uint16_t const LatinExtB_upper_mapping[] = { /* first part only */
337*2b949d04SAndroid Build Coastguard Worker     0x0180, 0x0181, 0x0182, 0x0182, 0x0184, 0x0184, 0x0186, 0x0187,
338*2b949d04SAndroid Build Coastguard Worker     0x0187, 0x0189, 0x018A, 0x018B, 0x018B, 0x018D, 0x018E, 0x018F,
339*2b949d04SAndroid Build Coastguard Worker     0x0190, 0x0191, 0x0191, 0x0193, 0x0194, 0x01F6, 0x0196, 0x0197,
340*2b949d04SAndroid Build Coastguard Worker     0x0198, 0x0198, 0x019A, 0x019B, 0x019C, 0x019D, 0x0220, 0x019F,
341*2b949d04SAndroid Build Coastguard Worker     0x01A0, 0x01A0, 0x01A2, 0x01A2, 0x01A4, 0x01A4, 0x01A6, 0x01A7,
342*2b949d04SAndroid Build Coastguard Worker     0x01A7, 0x01A9, 0x01AA, 0x01AB, 0x01AC, 0x01AC, 0x01AE, 0x01AF,
343*2b949d04SAndroid Build Coastguard Worker     0x01AF, 0x01B1, 0x01B2, 0x01B3, 0x01B3, 0x01B5, 0x01B5, 0x01B7,
344*2b949d04SAndroid Build Coastguard Worker     0x01B8, 0x01B8, 0x01BA, 0x01BB, 0x01BC, 0x01BC, 0x01BE, 0x01F7,
345*2b949d04SAndroid Build Coastguard Worker     0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C4, 0x01C4, 0x01C7,
346*2b949d04SAndroid Build Coastguard Worker     0x01C7, 0x01C7, 0x01CA, 0x01CA, 0x01CA
347*2b949d04SAndroid Build Coastguard Worker     };
348*2b949d04SAndroid Build Coastguard Worker 
349*2b949d04SAndroid Build Coastguard Worker     static uint16_t const LatinExtB_lower_mapping[] = { /* first part only */
350*2b949d04SAndroid Build Coastguard Worker     0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188,
351*2b949d04SAndroid Build Coastguard Worker     0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259,
352*2b949d04SAndroid Build Coastguard Worker     0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268,
353*2b949d04SAndroid Build Coastguard Worker     0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275,
354*2b949d04SAndroid Build Coastguard Worker     0x01A1, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x0280, 0x01A8,
355*2b949d04SAndroid Build Coastguard Worker     0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01B0,
356*2b949d04SAndroid Build Coastguard Worker     0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292,
357*2b949d04SAndroid Build Coastguard Worker     0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF,
358*2b949d04SAndroid Build Coastguard Worker     0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9,
359*2b949d04SAndroid Build Coastguard Worker     0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC
360*2b949d04SAndroid Build Coastguard Worker     };
361*2b949d04SAndroid Build Coastguard Worker 
362*2b949d04SAndroid Build Coastguard Worker     static uint16_t const Greek_upper_mapping[] = {
363*2b949d04SAndroid Build Coastguard Worker     0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000,
364*2b949d04SAndroid Build Coastguard Worker     0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000,
365*2b949d04SAndroid Build Coastguard Worker     0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x0386, 0x0387,
366*2b949d04SAndroid Build Coastguard Worker     0x0388, 0x0389, 0x038A, 0x0000, 0x038C, 0x0000, 0x038E, 0x038F,
367*2b949d04SAndroid Build Coastguard Worker     0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
368*2b949d04SAndroid Build Coastguard Worker     0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
369*2b949d04SAndroid Build Coastguard Worker     0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
370*2b949d04SAndroid Build Coastguard Worker     0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x0386, 0x0388, 0x0389, 0x038A,
371*2b949d04SAndroid Build Coastguard Worker     0x03B0, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
372*2b949d04SAndroid Build Coastguard Worker     0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
373*2b949d04SAndroid Build Coastguard Worker     0x03A0, 0x03A1, 0x03A3, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
374*2b949d04SAndroid Build Coastguard Worker     0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x038C, 0x038E, 0x038F, 0x0000,
375*2b949d04SAndroid Build Coastguard Worker     0x0392, 0x0398, 0x03D2, 0x03D3, 0x03D4, 0x03A6, 0x03A0, 0x03D7,
376*2b949d04SAndroid Build Coastguard Worker     0x03D8, 0x03D8, 0x03DA, 0x03DA, 0x03DC, 0x03DC, 0x03DE, 0x03DE,
377*2b949d04SAndroid Build Coastguard Worker     0x03E0, 0x03E0, 0x03E2, 0x03E2, 0x03E4, 0x03E4, 0x03E6, 0x03E6,
378*2b949d04SAndroid Build Coastguard Worker     0x03E8, 0x03E8, 0x03EA, 0x03EA, 0x03EC, 0x03EC, 0x03EE, 0x03EE,
379*2b949d04SAndroid Build Coastguard Worker     0x039A, 0x03A1, 0x03F9, 0x03F3, 0x03F4, 0x0395, 0x03F6, 0x03F7,
380*2b949d04SAndroid Build Coastguard Worker     0x03F7, 0x03F9, 0x03FA, 0x03FA, 0x0000, 0x0000, 0x0000, 0x0000
381*2b949d04SAndroid Build Coastguard Worker     };
382*2b949d04SAndroid Build Coastguard Worker 
383*2b949d04SAndroid Build Coastguard Worker     static uint16_t const Greek_lower_mapping[] = {
384*2b949d04SAndroid Build Coastguard Worker     0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000,
385*2b949d04SAndroid Build Coastguard Worker     0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000,
386*2b949d04SAndroid Build Coastguard Worker     0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x03AC, 0x0387,
387*2b949d04SAndroid Build Coastguard Worker     0x03AD, 0x03AE, 0x03AF, 0x0000, 0x03CC, 0x0000, 0x03CD, 0x03CE,
388*2b949d04SAndroid Build Coastguard Worker     0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
389*2b949d04SAndroid Build Coastguard Worker     0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
390*2b949d04SAndroid Build Coastguard Worker     0x03C0, 0x03C1, 0x0000, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
391*2b949d04SAndroid Build Coastguard Worker     0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
392*2b949d04SAndroid Build Coastguard Worker     0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
393*2b949d04SAndroid Build Coastguard Worker     0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
394*2b949d04SAndroid Build Coastguard Worker     0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
395*2b949d04SAndroid Build Coastguard Worker     0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000,
396*2b949d04SAndroid Build Coastguard Worker     0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7,
397*2b949d04SAndroid Build Coastguard Worker     0x03D9, 0x03D9, 0x03DB, 0x03DB, 0x03DD, 0x03DD, 0x03DF, 0x03DF,
398*2b949d04SAndroid Build Coastguard Worker     0x03E1, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7,
399*2b949d04SAndroid Build Coastguard Worker     0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF,
400*2b949d04SAndroid Build Coastguard Worker     0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03B8, 0x03F5, 0x03F6, 0x03F8,
401*2b949d04SAndroid Build Coastguard Worker     0x03F8, 0x03F2, 0x03FB, 0x03FB, 0x0000, 0x0000, 0x0000, 0x0000
402*2b949d04SAndroid Build Coastguard Worker     };
403*2b949d04SAndroid Build Coastguard Worker 
404*2b949d04SAndroid Build Coastguard Worker     static uint16_t const GreekExt_lower_mapping[] = {
405*2b949d04SAndroid Build Coastguard Worker     0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
406*2b949d04SAndroid Build Coastguard Worker     0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
407*2b949d04SAndroid Build Coastguard Worker     0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
408*2b949d04SAndroid Build Coastguard Worker     0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
409*2b949d04SAndroid Build Coastguard Worker     0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
410*2b949d04SAndroid Build Coastguard Worker     0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
411*2b949d04SAndroid Build Coastguard Worker     0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
412*2b949d04SAndroid Build Coastguard Worker     0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
413*2b949d04SAndroid Build Coastguard Worker     0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
414*2b949d04SAndroid Build Coastguard Worker     0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
415*2b949d04SAndroid Build Coastguard Worker     0x1F50, 0x1F51, 0x1F52, 0x1F53, 0x1F54, 0x1F55, 0x1F56, 0x1F57,
416*2b949d04SAndroid Build Coastguard Worker     0x0000, 0x1F51, 0x0000, 0x1F53, 0x0000, 0x1F55, 0x0000, 0x1F57,
417*2b949d04SAndroid Build Coastguard Worker     0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
418*2b949d04SAndroid Build Coastguard Worker     0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
419*2b949d04SAndroid Build Coastguard Worker     0x1F70, 0x1F71, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F76, 0x1F77,
420*2b949d04SAndroid Build Coastguard Worker     0x1F78, 0x1F79, 0x1F7A, 0x1F7B, 0x1F7C, 0x1F7D, 0x0000, 0x0000,
421*2b949d04SAndroid Build Coastguard Worker     0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
422*2b949d04SAndroid Build Coastguard Worker     0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
423*2b949d04SAndroid Build Coastguard Worker     0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
424*2b949d04SAndroid Build Coastguard Worker     0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
425*2b949d04SAndroid Build Coastguard Worker     0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
426*2b949d04SAndroid Build Coastguard Worker     0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
427*2b949d04SAndroid Build Coastguard Worker     0x1FB0, 0x1FB1, 0x1FB2, 0x1FB3, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7,
428*2b949d04SAndroid Build Coastguard Worker     0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x1FBD, 0x1FBE, 0x1FBF,
429*2b949d04SAndroid Build Coastguard Worker     0x1FC0, 0x1FC1, 0x1FC2, 0x1FC3, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7,
430*2b949d04SAndroid Build Coastguard Worker     0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x1FCD, 0x1FCE, 0x1FCF,
431*2b949d04SAndroid Build Coastguard Worker     0x1FD0, 0x1FD1, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7,
432*2b949d04SAndroid Build Coastguard Worker     0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF,
433*2b949d04SAndroid Build Coastguard Worker     0x1FE0, 0x1FE1, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FE5, 0x1FE6, 0x1FE7,
434*2b949d04SAndroid Build Coastguard Worker     0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x1FED, 0x1FEE, 0x1FEF,
435*2b949d04SAndroid Build Coastguard Worker     0x0000, 0x0000, 0x1FF2, 0x1FF3, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7,
436*2b949d04SAndroid Build Coastguard Worker     0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x1FFD, 0x1FFE, 0x0000
437*2b949d04SAndroid Build Coastguard Worker     };
438*2b949d04SAndroid Build Coastguard Worker 
439*2b949d04SAndroid Build Coastguard Worker     static uint16_t const GreekExt_upper_mapping[] = {
440*2b949d04SAndroid Build Coastguard Worker     0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
441*2b949d04SAndroid Build Coastguard Worker     0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
442*2b949d04SAndroid Build Coastguard Worker     0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000,
443*2b949d04SAndroid Build Coastguard Worker     0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000,
444*2b949d04SAndroid Build Coastguard Worker     0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F,
445*2b949d04SAndroid Build Coastguard Worker     0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F,
446*2b949d04SAndroid Build Coastguard Worker     0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
447*2b949d04SAndroid Build Coastguard Worker     0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
448*2b949d04SAndroid Build Coastguard Worker     0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000,
449*2b949d04SAndroid Build Coastguard Worker     0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000,
450*2b949d04SAndroid Build Coastguard Worker     0x1F50, 0x1F59, 0x1F52, 0x1F5B, 0x1F54, 0x1F5D, 0x1F56, 0x1F5F,
451*2b949d04SAndroid Build Coastguard Worker     0x0000, 0x1F59, 0x0000, 0x1F5B, 0x0000, 0x1F5D, 0x0000, 0x1F5F,
452*2b949d04SAndroid Build Coastguard Worker     0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
453*2b949d04SAndroid Build Coastguard Worker     0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
454*2b949d04SAndroid Build Coastguard Worker     0x1FBA, 0x1FBB, 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FDA, 0x1FDB,
455*2b949d04SAndroid Build Coastguard Worker     0x1FF8, 0x1FF9, 0x1FEA, 0x1FEB, 0x1FFA, 0x1FFB, 0x0000, 0x0000,
456*2b949d04SAndroid Build Coastguard Worker     0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F,
457*2b949d04SAndroid Build Coastguard Worker     0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F,
458*2b949d04SAndroid Build Coastguard Worker     0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
459*2b949d04SAndroid Build Coastguard Worker     0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
460*2b949d04SAndroid Build Coastguard Worker     0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF,
461*2b949d04SAndroid Build Coastguard Worker     0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF,
462*2b949d04SAndroid Build Coastguard Worker     0x1FB8, 0x1FB9, 0x1FB2, 0x1FBC, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7,
463*2b949d04SAndroid Build Coastguard Worker     0x1FB8, 0x1FB9, 0x1FBA, 0x1FBB, 0x1FBC, 0x1FBD, 0x0399, 0x1FBF,
464*2b949d04SAndroid Build Coastguard Worker     0x1FC0, 0x1FC1, 0x1FC2, 0x1FCC, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7,
465*2b949d04SAndroid Build Coastguard Worker     0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FCC, 0x1FCD, 0x1FCE, 0x1FCF,
466*2b949d04SAndroid Build Coastguard Worker     0x1FD8, 0x1FD9, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7,
467*2b949d04SAndroid Build Coastguard Worker     0x1FD8, 0x1FD9, 0x1FDA, 0x1FDB, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF,
468*2b949d04SAndroid Build Coastguard Worker     0x1FE8, 0x1FE9, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FEC, 0x1FE6, 0x1FE7,
469*2b949d04SAndroid Build Coastguard Worker     0x1FE8, 0x1FE9, 0x1FEA, 0x1FEB, 0x1FEC, 0x1FED, 0x1FEE, 0x1FEF,
470*2b949d04SAndroid Build Coastguard Worker     0x0000, 0x0000, 0x1FF2, 0x1FFC, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7,
471*2b949d04SAndroid Build Coastguard Worker     0x1FF8, 0x1FF9, 0x1FFA, 0x1FFB, 0x1FFC, 0x1FFD, 0x1FFE, 0x0000
472*2b949d04SAndroid Build Coastguard Worker     };
473*2b949d04SAndroid Build Coastguard Worker 
474*2b949d04SAndroid Build Coastguard Worker     *lower = code;
475*2b949d04SAndroid Build Coastguard Worker     *upper = code;
476*2b949d04SAndroid Build Coastguard Worker 
477*2b949d04SAndroid Build Coastguard Worker     /* Basic Latin and Latin-1 Supplement, U+0000 to U+00FF */
478*2b949d04SAndroid Build Coastguard Worker     if (code <= 0x00ff) {
479*2b949d04SAndroid Build Coastguard Worker         if (code >= 0x0041 && code <= 0x005a)             /* A-Z */
480*2b949d04SAndroid Build Coastguard Worker             *lower += 0x20;
481*2b949d04SAndroid Build Coastguard Worker         else if (code >= 0x0061 && code <= 0x007a)        /* a-z */
482*2b949d04SAndroid Build Coastguard Worker             *upper -= 0x20;
483*2b949d04SAndroid Build Coastguard Worker         else if ( (code >= 0x00c0 && code <= 0x00d6) ||
484*2b949d04SAndroid Build Coastguard Worker 	          (code >= 0x00d8 && code <= 0x00de) )
485*2b949d04SAndroid Build Coastguard Worker             *lower += 0x20;
486*2b949d04SAndroid Build Coastguard Worker         else if ( (code >= 0x00e0 && code <= 0x00f6) ||
487*2b949d04SAndroid Build Coastguard Worker 	          (code >= 0x00f8 && code <= 0x00fe) )
488*2b949d04SAndroid Build Coastguard Worker             *upper -= 0x20;
489*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x00ff)      /* y with diaeresis */
490*2b949d04SAndroid Build Coastguard Worker             *upper = 0x0178;
491*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x00b5)      /* micro sign */
492*2b949d04SAndroid Build Coastguard Worker             *upper = 0x039c;
493*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x00df)      /* ssharp */
494*2b949d04SAndroid Build Coastguard Worker             *upper = 0x1e9e;
495*2b949d04SAndroid Build Coastguard Worker 	return;
496*2b949d04SAndroid Build Coastguard Worker     }
497*2b949d04SAndroid Build Coastguard Worker 
498*2b949d04SAndroid Build Coastguard Worker     /* Latin Extended-A, U+0100 to U+017F */
499*2b949d04SAndroid Build Coastguard Worker     if (code >= 0x0100 && code <= 0x017f) {
500*2b949d04SAndroid Build Coastguard Worker         if ( (code >= 0x0100 && code <= 0x012f) ||
501*2b949d04SAndroid Build Coastguard Worker              (code >= 0x0132 && code <= 0x0137) ||
502*2b949d04SAndroid Build Coastguard Worker              (code >= 0x014a && code <= 0x0177) ) {
503*2b949d04SAndroid Build Coastguard Worker             *upper = code & ~1;
504*2b949d04SAndroid Build Coastguard Worker             *lower = code | 1;
505*2b949d04SAndroid Build Coastguard Worker         }
506*2b949d04SAndroid Build Coastguard Worker         else if ( (code >= 0x0139 && code <= 0x0148) ||
507*2b949d04SAndroid Build Coastguard Worker                   (code >= 0x0179 && code <= 0x017e) ) {
508*2b949d04SAndroid Build Coastguard Worker             if (code & 1)
509*2b949d04SAndroid Build Coastguard Worker 	        *lower += 1;
510*2b949d04SAndroid Build Coastguard Worker             else
511*2b949d04SAndroid Build Coastguard Worker 	        *upper -= 1;
512*2b949d04SAndroid Build Coastguard Worker         }
513*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x0130)
514*2b949d04SAndroid Build Coastguard Worker             *lower = 0x0069;
515*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x0131)
516*2b949d04SAndroid Build Coastguard Worker             *upper = 0x0049;
517*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x0178)
518*2b949d04SAndroid Build Coastguard Worker             *lower = 0x00ff;
519*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x017f)
520*2b949d04SAndroid Build Coastguard Worker             *upper = 0x0053;
521*2b949d04SAndroid Build Coastguard Worker         return;
522*2b949d04SAndroid Build Coastguard Worker     }
523*2b949d04SAndroid Build Coastguard Worker 
524*2b949d04SAndroid Build Coastguard Worker     /* Latin Extended-B, U+0180 to U+024F */
525*2b949d04SAndroid Build Coastguard Worker     if (code >= 0x0180 && code <= 0x024f) {
526*2b949d04SAndroid Build Coastguard Worker         if (code >= 0x01cd && code <= 0x01dc) {
527*2b949d04SAndroid Build Coastguard Worker 	    if (code & 1)
528*2b949d04SAndroid Build Coastguard Worker 	       *lower += 1;
529*2b949d04SAndroid Build Coastguard Worker 	    else
530*2b949d04SAndroid Build Coastguard Worker 	       *upper -= 1;
531*2b949d04SAndroid Build Coastguard Worker         }
532*2b949d04SAndroid Build Coastguard Worker         else if ( (code >= 0x01de && code <= 0x01ef) ||
533*2b949d04SAndroid Build Coastguard Worker                   (code >= 0x01f4 && code <= 0x01f5) ||
534*2b949d04SAndroid Build Coastguard Worker                   (code >= 0x01f8 && code <= 0x021f) ||
535*2b949d04SAndroid Build Coastguard Worker                   (code >= 0x0222 && code <= 0x0233) ) {
536*2b949d04SAndroid Build Coastguard Worker             *lower |= 1;
537*2b949d04SAndroid Build Coastguard Worker             *upper &= ~1;
538*2b949d04SAndroid Build Coastguard Worker         }
539*2b949d04SAndroid Build Coastguard Worker         else if (code >= 0x0180 && code <= 0x01cc) {
540*2b949d04SAndroid Build Coastguard Worker             *lower = LatinExtB_lower_mapping[code - 0x0180];
541*2b949d04SAndroid Build Coastguard Worker             *upper = LatinExtB_upper_mapping[code - 0x0180];
542*2b949d04SAndroid Build Coastguard Worker         }
543*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x01dd)
544*2b949d04SAndroid Build Coastguard Worker             *upper = 0x018e;
545*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x01f1 || code == 0x01f2) {
546*2b949d04SAndroid Build Coastguard Worker             *lower = 0x01f3;
547*2b949d04SAndroid Build Coastguard Worker             *upper = 0x01f1;
548*2b949d04SAndroid Build Coastguard Worker         }
549*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x01f3)
550*2b949d04SAndroid Build Coastguard Worker             *upper = 0x01f1;
551*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x01f6)
552*2b949d04SAndroid Build Coastguard Worker             *lower = 0x0195;
553*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x01f7)
554*2b949d04SAndroid Build Coastguard Worker             *lower = 0x01bf;
555*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x0220)
556*2b949d04SAndroid Build Coastguard Worker             *lower = 0x019e;
557*2b949d04SAndroid Build Coastguard Worker         return;
558*2b949d04SAndroid Build Coastguard Worker     }
559*2b949d04SAndroid Build Coastguard Worker 
560*2b949d04SAndroid Build Coastguard Worker     /* IPA Extensions, U+0250 to U+02AF */
561*2b949d04SAndroid Build Coastguard Worker     if (code >= 0x0253 && code <= 0x0292) {
562*2b949d04SAndroid Build Coastguard Worker         *upper = IPAExt_upper_mapping[code - 0x0253];
563*2b949d04SAndroid Build Coastguard Worker     }
564*2b949d04SAndroid Build Coastguard Worker 
565*2b949d04SAndroid Build Coastguard Worker     /* Combining Diacritical Marks, U+0300 to U+036F */
566*2b949d04SAndroid Build Coastguard Worker     if (code == 0x0345) {
567*2b949d04SAndroid Build Coastguard Worker         *upper = 0x0399;
568*2b949d04SAndroid Build Coastguard Worker     }
569*2b949d04SAndroid Build Coastguard Worker 
570*2b949d04SAndroid Build Coastguard Worker     /* Greek and Coptic, U+0370 to U+03FF */
571*2b949d04SAndroid Build Coastguard Worker     if (code >= 0x0370 && code <= 0x03ff) {
572*2b949d04SAndroid Build Coastguard Worker         *lower = Greek_lower_mapping[code - 0x0370];
573*2b949d04SAndroid Build Coastguard Worker         *upper = Greek_upper_mapping[code - 0x0370];
574*2b949d04SAndroid Build Coastguard Worker         if (*upper == 0)
575*2b949d04SAndroid Build Coastguard Worker             *upper = code;
576*2b949d04SAndroid Build Coastguard Worker         if (*lower == 0)
577*2b949d04SAndroid Build Coastguard Worker             *lower = code;
578*2b949d04SAndroid Build Coastguard Worker     }
579*2b949d04SAndroid Build Coastguard Worker 
580*2b949d04SAndroid Build Coastguard Worker     /* Cyrillic and Cyrillic Supplementary, U+0400 to U+052F */
581*2b949d04SAndroid Build Coastguard Worker     if ( (code >= 0x0400 && code <= 0x04ff) ||
582*2b949d04SAndroid Build Coastguard Worker          (code >= 0x0500 && code <= 0x052f) ) {
583*2b949d04SAndroid Build Coastguard Worker         if (code >= 0x0400 && code <= 0x040f)
584*2b949d04SAndroid Build Coastguard Worker             *lower += 0x50;
585*2b949d04SAndroid Build Coastguard Worker         else if (code >= 0x0410 && code <= 0x042f)
586*2b949d04SAndroid Build Coastguard Worker             *lower += 0x20;
587*2b949d04SAndroid Build Coastguard Worker         else if (code >= 0x0430 && code <= 0x044f)
588*2b949d04SAndroid Build Coastguard Worker             *upper -= 0x20;
589*2b949d04SAndroid Build Coastguard Worker         else if (code >= 0x0450 && code <= 0x045f)
590*2b949d04SAndroid Build Coastguard Worker             *upper -= 0x50;
591*2b949d04SAndroid Build Coastguard Worker         else if ( (code >= 0x0460 && code <= 0x0481) ||
592*2b949d04SAndroid Build Coastguard Worker                   (code >= 0x048a && code <= 0x04bf) ||
593*2b949d04SAndroid Build Coastguard Worker 	          (code >= 0x04d0 && code <= 0x04f5) ||
594*2b949d04SAndroid Build Coastguard Worker 	          (code >= 0x04f8 && code <= 0x04f9) ||
595*2b949d04SAndroid Build Coastguard Worker                   (code >= 0x0500 && code <= 0x050f) ) {
596*2b949d04SAndroid Build Coastguard Worker             *upper &= ~1;
597*2b949d04SAndroid Build Coastguard Worker             *lower |= 1;
598*2b949d04SAndroid Build Coastguard Worker         }
599*2b949d04SAndroid Build Coastguard Worker         else if (code >= 0x04c1 && code <= 0x04ce) {
600*2b949d04SAndroid Build Coastguard Worker 	    if (code & 1)
601*2b949d04SAndroid Build Coastguard Worker 	        *lower += 1;
602*2b949d04SAndroid Build Coastguard Worker 	    else
603*2b949d04SAndroid Build Coastguard Worker 	        *upper -= 1;
604*2b949d04SAndroid Build Coastguard Worker         }
605*2b949d04SAndroid Build Coastguard Worker     }
606*2b949d04SAndroid Build Coastguard Worker 
607*2b949d04SAndroid Build Coastguard Worker     /* Armenian, U+0530 to U+058F */
608*2b949d04SAndroid Build Coastguard Worker     if (code >= 0x0530 && code <= 0x058f) {
609*2b949d04SAndroid Build Coastguard Worker         if (code >= 0x0531 && code <= 0x0556)
610*2b949d04SAndroid Build Coastguard Worker             *lower += 0x30;
611*2b949d04SAndroid Build Coastguard Worker         else if (code >=0x0561 && code <= 0x0586)
612*2b949d04SAndroid Build Coastguard Worker             *upper -= 0x30;
613*2b949d04SAndroid Build Coastguard Worker     }
614*2b949d04SAndroid Build Coastguard Worker 
615*2b949d04SAndroid Build Coastguard Worker     /* Latin Extended Additional, U+1E00 to U+1EFF */
616*2b949d04SAndroid Build Coastguard Worker     if (code >= 0x1e00 && code <= 0x1eff) {
617*2b949d04SAndroid Build Coastguard Worker         if ( (code >= 0x1e00 && code <= 0x1e95) ||
618*2b949d04SAndroid Build Coastguard Worker              (code >= 0x1ea0 && code <= 0x1ef9) ) {
619*2b949d04SAndroid Build Coastguard Worker             *upper &= ~1;
620*2b949d04SAndroid Build Coastguard Worker             *lower |= 1;
621*2b949d04SAndroid Build Coastguard Worker         }
622*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x1e9b)
623*2b949d04SAndroid Build Coastguard Worker             *upper = 0x1e60;
624*2b949d04SAndroid Build Coastguard Worker         else if (code == 0x1e9e)
625*2b949d04SAndroid Build Coastguard Worker             *lower = 0x00df; /* ssharp */
626*2b949d04SAndroid Build Coastguard Worker     }
627*2b949d04SAndroid Build Coastguard Worker 
628*2b949d04SAndroid Build Coastguard Worker     /* Greek Extended, U+1F00 to U+1FFF */
629*2b949d04SAndroid Build Coastguard Worker     if (code >= 0x1f00 && code <= 0x1fff) {
630*2b949d04SAndroid Build Coastguard Worker         *lower = GreekExt_lower_mapping[code - 0x1f00];
631*2b949d04SAndroid Build Coastguard Worker         *upper = GreekExt_upper_mapping[code - 0x1f00];
632*2b949d04SAndroid Build Coastguard Worker         if (*upper == 0)
633*2b949d04SAndroid Build Coastguard Worker             *upper = code;
634*2b949d04SAndroid Build Coastguard Worker         if (*lower == 0)
635*2b949d04SAndroid Build Coastguard Worker             *lower = code;
636*2b949d04SAndroid Build Coastguard Worker     }
637*2b949d04SAndroid Build Coastguard Worker 
638*2b949d04SAndroid Build Coastguard Worker     /* Letterlike Symbols, U+2100 to U+214F */
639*2b949d04SAndroid Build Coastguard Worker     if (code >= 0x2100 && code <= 0x214f) {
640*2b949d04SAndroid Build Coastguard Worker         switch (code) {
641*2b949d04SAndroid Build Coastguard Worker         case 0x2126: *lower = 0x03c9; break;
642*2b949d04SAndroid Build Coastguard Worker         case 0x212a: *lower = 0x006b; break;
643*2b949d04SAndroid Build Coastguard Worker         case 0x212b: *lower = 0x00e5; break;
644*2b949d04SAndroid Build Coastguard Worker         }
645*2b949d04SAndroid Build Coastguard Worker     }
646*2b949d04SAndroid Build Coastguard Worker     /* Number Forms, U+2150 to U+218F */
647*2b949d04SAndroid Build Coastguard Worker     else if (code >= 0x2160 && code <= 0x216f)
648*2b949d04SAndroid Build Coastguard Worker         *lower += 0x10;
649*2b949d04SAndroid Build Coastguard Worker     else if (code >= 0x2170 && code <= 0x217f)
650*2b949d04SAndroid Build Coastguard Worker         *upper -= 0x10;
651*2b949d04SAndroid Build Coastguard Worker     /* Enclosed Alphanumerics, U+2460 to U+24FF */
652*2b949d04SAndroid Build Coastguard Worker     else if (code >= 0x24b6 && code <= 0x24cf)
653*2b949d04SAndroid Build Coastguard Worker         *lower += 0x1a;
654*2b949d04SAndroid Build Coastguard Worker     else if (code >= 0x24d0 && code <= 0x24e9)
655*2b949d04SAndroid Build Coastguard Worker         *upper -= 0x1a;
656*2b949d04SAndroid Build Coastguard Worker     /* Halfwidth and Fullwidth Forms, U+FF00 to U+FFEF */
657*2b949d04SAndroid Build Coastguard Worker     else if (code >= 0xff21 && code <= 0xff3a)
658*2b949d04SAndroid Build Coastguard Worker         *lower += 0x20;
659*2b949d04SAndroid Build Coastguard Worker     else if (code >= 0xff41 && code <= 0xff5a)
660*2b949d04SAndroid Build Coastguard Worker         *upper -= 0x20;
661*2b949d04SAndroid Build Coastguard Worker     /* Deseret, U+10400 to U+104FF */
662*2b949d04SAndroid Build Coastguard Worker     else if (code >= 0x10400 && code <= 0x10427)
663*2b949d04SAndroid Build Coastguard Worker         *lower += 0x28;
664*2b949d04SAndroid Build Coastguard Worker     else if (code >= 0x10428 && code <= 0x1044f)
665*2b949d04SAndroid Build Coastguard Worker         *upper -= 0x28;
666*2b949d04SAndroid Build Coastguard Worker }
667*2b949d04SAndroid Build Coastguard Worker 
668*2b949d04SAndroid Build Coastguard Worker static void
XConvertCase(xkb_keysym_t sym,xkb_keysym_t * lower,xkb_keysym_t * upper)669*2b949d04SAndroid Build Coastguard Worker XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper)
670*2b949d04SAndroid Build Coastguard Worker {
671*2b949d04SAndroid Build Coastguard Worker     /* Latin 1 keysym */
672*2b949d04SAndroid Build Coastguard Worker     if (sym < 0x100) {
673*2b949d04SAndroid Build Coastguard Worker         UCSConvertCase(sym, lower, upper);
674*2b949d04SAndroid Build Coastguard Worker 	return;
675*2b949d04SAndroid Build Coastguard Worker     }
676*2b949d04SAndroid Build Coastguard Worker 
677*2b949d04SAndroid Build Coastguard Worker     /* Unicode keysym */
678*2b949d04SAndroid Build Coastguard Worker     if ((sym & 0xff000000) == 0x01000000) {
679*2b949d04SAndroid Build Coastguard Worker         UCSConvertCase((sym & 0x00ffffff), lower, upper);
680*2b949d04SAndroid Build Coastguard Worker         *upper |= 0x01000000;
681*2b949d04SAndroid Build Coastguard Worker         *lower |= 0x01000000;
682*2b949d04SAndroid Build Coastguard Worker         return;
683*2b949d04SAndroid Build Coastguard Worker     }
684*2b949d04SAndroid Build Coastguard Worker 
685*2b949d04SAndroid Build Coastguard Worker     /* Legacy keysym */
686*2b949d04SAndroid Build Coastguard Worker 
687*2b949d04SAndroid Build Coastguard Worker     *lower = sym;
688*2b949d04SAndroid Build Coastguard Worker     *upper = sym;
689*2b949d04SAndroid Build Coastguard Worker 
690*2b949d04SAndroid Build Coastguard Worker     switch(sym >> 8) {
691*2b949d04SAndroid Build Coastguard Worker     case 1: /* Latin 2 */
692*2b949d04SAndroid Build Coastguard Worker 	/* Assume the KeySym is a legal value (ignore discontinuities) */
693*2b949d04SAndroid Build Coastguard Worker 	if (sym == XKB_KEY_Aogonek)
694*2b949d04SAndroid Build Coastguard Worker 	    *lower = XKB_KEY_aogonek;
695*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_Lstroke && sym <= XKB_KEY_Sacute)
696*2b949d04SAndroid Build Coastguard Worker 	    *lower += (XKB_KEY_lstroke - XKB_KEY_Lstroke);
697*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_Scaron && sym <= XKB_KEY_Zacute)
698*2b949d04SAndroid Build Coastguard Worker 	    *lower += (XKB_KEY_scaron - XKB_KEY_Scaron);
699*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_Zcaron && sym <= XKB_KEY_Zabovedot)
700*2b949d04SAndroid Build Coastguard Worker 	    *lower += (XKB_KEY_zcaron - XKB_KEY_Zcaron);
701*2b949d04SAndroid Build Coastguard Worker 	else if (sym == XKB_KEY_aogonek)
702*2b949d04SAndroid Build Coastguard Worker 	    *upper = XKB_KEY_Aogonek;
703*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_lstroke && sym <= XKB_KEY_sacute)
704*2b949d04SAndroid Build Coastguard Worker 	    *upper -= (XKB_KEY_lstroke - XKB_KEY_Lstroke);
705*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_scaron && sym <= XKB_KEY_zacute)
706*2b949d04SAndroid Build Coastguard Worker 	    *upper -= (XKB_KEY_scaron - XKB_KEY_Scaron);
707*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_zcaron && sym <= XKB_KEY_zabovedot)
708*2b949d04SAndroid Build Coastguard Worker 	    *upper -= (XKB_KEY_zcaron - XKB_KEY_Zcaron);
709*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_Racute && sym <= XKB_KEY_Tcedilla)
710*2b949d04SAndroid Build Coastguard Worker 	    *lower += (XKB_KEY_racute - XKB_KEY_Racute);
711*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_racute && sym <= XKB_KEY_tcedilla)
712*2b949d04SAndroid Build Coastguard Worker 	    *upper -= (XKB_KEY_racute - XKB_KEY_Racute);
713*2b949d04SAndroid Build Coastguard Worker 	break;
714*2b949d04SAndroid Build Coastguard Worker     case 2: /* Latin 3 */
715*2b949d04SAndroid Build Coastguard Worker 	/* Assume the KeySym is a legal value (ignore discontinuities) */
716*2b949d04SAndroid Build Coastguard Worker 	if (sym >= XKB_KEY_Hstroke && sym <= XKB_KEY_Hcircumflex)
717*2b949d04SAndroid Build Coastguard Worker 	    *lower += (XKB_KEY_hstroke - XKB_KEY_Hstroke);
718*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_Gbreve && sym <= XKB_KEY_Jcircumflex)
719*2b949d04SAndroid Build Coastguard Worker 	    *lower += (XKB_KEY_gbreve - XKB_KEY_Gbreve);
720*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_hstroke && sym <= XKB_KEY_hcircumflex)
721*2b949d04SAndroid Build Coastguard Worker 	    *upper -= (XKB_KEY_hstroke - XKB_KEY_Hstroke);
722*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_gbreve && sym <= XKB_KEY_jcircumflex)
723*2b949d04SAndroid Build Coastguard Worker 	    *upper -= (XKB_KEY_gbreve - XKB_KEY_Gbreve);
724*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_Cabovedot && sym <= XKB_KEY_Scircumflex)
725*2b949d04SAndroid Build Coastguard Worker 	    *lower += (XKB_KEY_cabovedot - XKB_KEY_Cabovedot);
726*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_cabovedot && sym <= XKB_KEY_scircumflex)
727*2b949d04SAndroid Build Coastguard Worker 	    *upper -= (XKB_KEY_cabovedot - XKB_KEY_Cabovedot);
728*2b949d04SAndroid Build Coastguard Worker 	break;
729*2b949d04SAndroid Build Coastguard Worker     case 3: /* Latin 4 */
730*2b949d04SAndroid Build Coastguard Worker 	/* Assume the KeySym is a legal value (ignore discontinuities) */
731*2b949d04SAndroid Build Coastguard Worker 	if (sym >= XKB_KEY_Rcedilla && sym <= XKB_KEY_Tslash)
732*2b949d04SAndroid Build Coastguard Worker 	    *lower += (XKB_KEY_rcedilla - XKB_KEY_Rcedilla);
733*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_rcedilla && sym <= XKB_KEY_tslash)
734*2b949d04SAndroid Build Coastguard Worker 	    *upper -= (XKB_KEY_rcedilla - XKB_KEY_Rcedilla);
735*2b949d04SAndroid Build Coastguard Worker 	else if (sym == XKB_KEY_ENG)
736*2b949d04SAndroid Build Coastguard Worker 	    *lower = XKB_KEY_eng;
737*2b949d04SAndroid Build Coastguard Worker 	else if (sym == XKB_KEY_eng)
738*2b949d04SAndroid Build Coastguard Worker 	    *upper = XKB_KEY_ENG;
739*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_Amacron && sym <= XKB_KEY_Umacron)
740*2b949d04SAndroid Build Coastguard Worker 	    *lower += (XKB_KEY_amacron - XKB_KEY_Amacron);
741*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_amacron && sym <= XKB_KEY_umacron)
742*2b949d04SAndroid Build Coastguard Worker 	    *upper -= (XKB_KEY_amacron - XKB_KEY_Amacron);
743*2b949d04SAndroid Build Coastguard Worker 	break;
744*2b949d04SAndroid Build Coastguard Worker     case 6: /* Cyrillic */
745*2b949d04SAndroid Build Coastguard Worker 	/* Assume the KeySym is a legal value (ignore discontinuities) */
746*2b949d04SAndroid Build Coastguard Worker 	if (sym >= XKB_KEY_Serbian_DJE && sym <= XKB_KEY_Serbian_DZE)
747*2b949d04SAndroid Build Coastguard Worker 	    *lower -= (XKB_KEY_Serbian_DJE - XKB_KEY_Serbian_dje);
748*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_Serbian_dje && sym <= XKB_KEY_Serbian_dze)
749*2b949d04SAndroid Build Coastguard Worker 	    *upper += (XKB_KEY_Serbian_DJE - XKB_KEY_Serbian_dje);
750*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_Cyrillic_YU && sym <= XKB_KEY_Cyrillic_HARDSIGN)
751*2b949d04SAndroid Build Coastguard Worker 	    *lower -= (XKB_KEY_Cyrillic_YU - XKB_KEY_Cyrillic_yu);
752*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_Cyrillic_yu && sym <= XKB_KEY_Cyrillic_hardsign)
753*2b949d04SAndroid Build Coastguard Worker 	    *upper += (XKB_KEY_Cyrillic_YU - XKB_KEY_Cyrillic_yu);
754*2b949d04SAndroid Build Coastguard Worker         break;
755*2b949d04SAndroid Build Coastguard Worker     case 7: /* Greek */
756*2b949d04SAndroid Build Coastguard Worker 	/* Assume the KeySym is a legal value (ignore discontinuities) */
757*2b949d04SAndroid Build Coastguard Worker 	if (sym >= XKB_KEY_Greek_ALPHAaccent && sym <= XKB_KEY_Greek_OMEGAaccent)
758*2b949d04SAndroid Build Coastguard Worker 	    *lower += (XKB_KEY_Greek_alphaaccent - XKB_KEY_Greek_ALPHAaccent);
759*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_Greek_alphaaccent && sym <= XKB_KEY_Greek_omegaaccent &&
760*2b949d04SAndroid Build Coastguard Worker 		 sym != XKB_KEY_Greek_iotaaccentdieresis &&
761*2b949d04SAndroid Build Coastguard Worker 		 sym != XKB_KEY_Greek_upsilonaccentdieresis)
762*2b949d04SAndroid Build Coastguard Worker 	    *upper -= (XKB_KEY_Greek_alphaaccent - XKB_KEY_Greek_ALPHAaccent);
763*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_Greek_ALPHA && sym <= XKB_KEY_Greek_OMEGA)
764*2b949d04SAndroid Build Coastguard Worker 	    *lower += (XKB_KEY_Greek_alpha - XKB_KEY_Greek_ALPHA);
765*2b949d04SAndroid Build Coastguard Worker 	else if (sym >= XKB_KEY_Greek_alpha && sym <= XKB_KEY_Greek_omega &&
766*2b949d04SAndroid Build Coastguard Worker 		 sym != XKB_KEY_Greek_finalsmallsigma)
767*2b949d04SAndroid Build Coastguard Worker 	    *upper -= (XKB_KEY_Greek_alpha - XKB_KEY_Greek_ALPHA);
768*2b949d04SAndroid Build Coastguard Worker         break;
769*2b949d04SAndroid Build Coastguard Worker     case 0x13: /* Latin 9 */
770*2b949d04SAndroid Build Coastguard Worker         if (sym == XKB_KEY_OE)
771*2b949d04SAndroid Build Coastguard Worker             *lower = XKB_KEY_oe;
772*2b949d04SAndroid Build Coastguard Worker         else if (sym == XKB_KEY_oe)
773*2b949d04SAndroid Build Coastguard Worker             *upper = XKB_KEY_OE;
774*2b949d04SAndroid Build Coastguard Worker         else if (sym == XKB_KEY_Ydiaeresis)
775*2b949d04SAndroid Build Coastguard Worker             *lower = XKB_KEY_ydiaeresis;
776*2b949d04SAndroid Build Coastguard Worker         break;
777*2b949d04SAndroid Build Coastguard Worker     }
778*2b949d04SAndroid Build Coastguard Worker }
779