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.
51 #include "xkbcommon/xkbcommon.h"
54 #include "ks_tables.h"
57 compare_by_keysym(const void *a, const void *b)
59 const struct name_keysym *key = a, *entry = b;
60 return key->keysym - (int32_t)entry->keysym;
64 compare_by_name(const void *a, const void *b)
66 const struct name_keysym *key = a, *entry = b;
67 return strcmp(key->name, entry->name);
71 xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
73 const struct name_keysym search = { .name = NULL, .keysym = ks };
74 const struct name_keysym *entry;
76 if ((ks & ((unsigned long) ~0x1fffffff)) != 0) {
77 snprintf(buffer, size, "Invalid");
81 entry = bsearch(&search, keysym_to_name,
82 sizeof(keysym_to_name) / sizeof(*keysym_to_name),
83 sizeof(*keysym_to_name),
86 return snprintf(buffer, size, "%s", entry->name);
88 if (ks >= 0x01000100 && ks <= 0x0110ffff)
89 /* Unnamed Unicode codepoint. */
90 return snprintf(buffer, size, "U%lx", ks & 0xffffffUL);
92 /* Unnamed, non-Unicode, symbol (shouldn't generally happen). */
93 return snprintf(buffer, size, "0x%08x", ks);
96 XKB_EXPORT xkb_keysym_t
97 xkb_keysym_from_name(const char *s)
99 const struct name_keysym search = { .name = s, .keysym = 0 };
100 const struct name_keysym *entry;
104 entry = bsearch(&search, name_to_keysym,
105 sizeof(name_to_keysym) / sizeof(*name_to_keysym),
106 sizeof(*name_to_keysym),
109 return entry->keysym;
112 val = strtoul(&s[1], &tmp, 16);
113 if (tmp && *tmp != '\0')
114 return XKB_KEY_NoSymbol;
116 if (val < 0x20 || (val > 0x7e && val < 0xa0))
117 return XKB_KEY_NoSymbol;
121 return XKB_KEY_NoSymbol;
122 return val | 0x01000000;
124 else if (s[0] == '0' && s[1] == 'x') {
125 val = strtoul(&s[2], &tmp, 16);
126 if (tmp && *tmp != '\0')
127 return XKB_KEY_NoSymbol;
132 /* Stupid inconsistency between the headers and XKeysymDB: the former has
133 * no separating underscore, while some XF86* syms in the latter did.
134 * As a last ditch effort, try without. */
135 if (strncmp(s, "XF86_", 5) == 0) {
139 return XKB_KEY_NoSymbol;
140 memmove(&tmp[4], &tmp[5], strlen(s) - 5 + 1);
141 ret = xkb_keysym_from_name(tmp);
146 return XKB_KEY_NoSymbol;
150 xkb_keysym_is_keypad(xkb_keysym_t keysym)
152 return keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_Equal;
156 XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper);
159 xkb_keysym_is_lower(xkb_keysym_t ks)
161 xkb_keysym_t lower, upper;
163 XConvertCase(ks, &lower, &upper);
168 return (ks == lower ? true : false);
172 xkb_keysym_is_upper(xkb_keysym_t ks)
174 xkb_keysym_t lower, upper;
176 XConvertCase(ks, &lower, &upper);
181 return (ks == upper ? true : false);
185 * The following is copied verbatim from libX11:src/KeyBind.c, commit
186 * d45b3fc19fbe95c41afc4e51d768df6d42332010, with the following changes:
187 * - unsigned -> uint32_t
188 * - unsigend short -> uint16_t
191 * XXX: If newlocale() and iswlower_l()/iswupper_l() interface ever
192 * become portable, we should use that in conjunction with
193 * xkb_keysym_to_utf32(), instead of all this stuff. We should
194 * be sure to give the same results as libX11, though, and be
195 * locale independent; this information is used by xkbcomp to
196 * find the automatic type to assign to key groups.
200 UCSConvertCase(uint32_t code, xkb_keysym_t *lower, xkb_keysym_t *upper)
202 /* Case conversion for UCS, as in Unicode Data version 4.0.0 */
203 /* NB: Only converts simple one-to-one mappings. */
205 /* Tables are used where they take less space than */
206 /* the code to work out the mappings. Zero values mean */
207 /* undefined code points. */
209 static uint16_t const IPAExt_upper_mapping[] = { /* part only */
210 0x0181, 0x0186, 0x0255, 0x0189, 0x018A,
211 0x0258, 0x018F, 0x025A, 0x0190, 0x025C, 0x025D, 0x025E, 0x025F,
212 0x0193, 0x0261, 0x0262, 0x0194, 0x0264, 0x0265, 0x0266, 0x0267,
213 0x0197, 0x0196, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x019C,
214 0x0270, 0x0271, 0x019D, 0x0273, 0x0274, 0x019F, 0x0276, 0x0277,
215 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F,
216 0x01A6, 0x0281, 0x0282, 0x01A9, 0x0284, 0x0285, 0x0286, 0x0287,
217 0x01AE, 0x0289, 0x01B1, 0x01B2, 0x028C, 0x028D, 0x028E, 0x028F,
218 0x0290, 0x0291, 0x01B7
221 static uint16_t const LatinExtB_upper_mapping[] = { /* first part only */
222 0x0180, 0x0181, 0x0182, 0x0182, 0x0184, 0x0184, 0x0186, 0x0187,
223 0x0187, 0x0189, 0x018A, 0x018B, 0x018B, 0x018D, 0x018E, 0x018F,
224 0x0190, 0x0191, 0x0191, 0x0193, 0x0194, 0x01F6, 0x0196, 0x0197,
225 0x0198, 0x0198, 0x019A, 0x019B, 0x019C, 0x019D, 0x0220, 0x019F,
226 0x01A0, 0x01A0, 0x01A2, 0x01A2, 0x01A4, 0x01A4, 0x01A6, 0x01A7,
227 0x01A7, 0x01A9, 0x01AA, 0x01AB, 0x01AC, 0x01AC, 0x01AE, 0x01AF,
228 0x01AF, 0x01B1, 0x01B2, 0x01B3, 0x01B3, 0x01B5, 0x01B5, 0x01B7,
229 0x01B8, 0x01B8, 0x01BA, 0x01BB, 0x01BC, 0x01BC, 0x01BE, 0x01F7,
230 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C4, 0x01C4, 0x01C7,
231 0x01C7, 0x01C7, 0x01CA, 0x01CA, 0x01CA
234 static uint16_t const LatinExtB_lower_mapping[] = { /* first part only */
235 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188,
236 0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259,
237 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268,
238 0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275,
239 0x01A1, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x0280, 0x01A8,
240 0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01B0,
241 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292,
242 0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF,
243 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9,
244 0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC
247 static uint16_t const Greek_upper_mapping[] = {
248 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000,
249 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000,
250 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x0386, 0x0387,
251 0x0388, 0x0389, 0x038A, 0x0000, 0x038C, 0x0000, 0x038E, 0x038F,
252 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
253 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
254 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
255 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x0386, 0x0388, 0x0389, 0x038A,
256 0x03B0, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
257 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
258 0x03A0, 0x03A1, 0x03A3, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
259 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x038C, 0x038E, 0x038F, 0x0000,
260 0x0392, 0x0398, 0x03D2, 0x03D3, 0x03D4, 0x03A6, 0x03A0, 0x03D7,
261 0x03D8, 0x03D8, 0x03DA, 0x03DA, 0x03DC, 0x03DC, 0x03DE, 0x03DE,
262 0x03E0, 0x03E0, 0x03E2, 0x03E2, 0x03E4, 0x03E4, 0x03E6, 0x03E6,
263 0x03E8, 0x03E8, 0x03EA, 0x03EA, 0x03EC, 0x03EC, 0x03EE, 0x03EE,
264 0x039A, 0x03A1, 0x03F9, 0x03F3, 0x03F4, 0x0395, 0x03F6, 0x03F7,
265 0x03F7, 0x03F9, 0x03FA, 0x03FA, 0x0000, 0x0000, 0x0000, 0x0000
268 static uint16_t const Greek_lower_mapping[] = {
269 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000,
270 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000,
271 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x03AC, 0x0387,
272 0x03AD, 0x03AE, 0x03AF, 0x0000, 0x03CC, 0x0000, 0x03CD, 0x03CE,
273 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
274 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
275 0x03C0, 0x03C1, 0x0000, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
276 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
277 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
278 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
279 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
280 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000,
281 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7,
282 0x03D9, 0x03D9, 0x03DB, 0x03DB, 0x03DD, 0x03DD, 0x03DF, 0x03DF,
283 0x03E1, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7,
284 0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF,
285 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03B8, 0x03F5, 0x03F6, 0x03F8,
286 0x03F8, 0x03F2, 0x03FB, 0x03FB, 0x0000, 0x0000, 0x0000, 0x0000
289 static uint16_t const GreekExt_lower_mapping[] = {
290 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
291 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
292 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
293 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
294 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
295 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
296 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
297 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
298 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
299 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
300 0x1F50, 0x1F51, 0x1F52, 0x1F53, 0x1F54, 0x1F55, 0x1F56, 0x1F57,
301 0x0000, 0x1F51, 0x0000, 0x1F53, 0x0000, 0x1F55, 0x0000, 0x1F57,
302 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
303 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
304 0x1F70, 0x1F71, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F76, 0x1F77,
305 0x1F78, 0x1F79, 0x1F7A, 0x1F7B, 0x1F7C, 0x1F7D, 0x0000, 0x0000,
306 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
307 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
308 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
309 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
310 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
311 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
312 0x1FB0, 0x1FB1, 0x1FB2, 0x1FB3, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7,
313 0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x1FBD, 0x1FBE, 0x1FBF,
314 0x1FC0, 0x1FC1, 0x1FC2, 0x1FC3, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7,
315 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x1FCD, 0x1FCE, 0x1FCF,
316 0x1FD0, 0x1FD1, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7,
317 0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF,
318 0x1FE0, 0x1FE1, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FE5, 0x1FE6, 0x1FE7,
319 0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x1FED, 0x1FEE, 0x1FEF,
320 0x0000, 0x0000, 0x1FF2, 0x1FF3, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7,
321 0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x1FFD, 0x1FFE, 0x0000
324 static uint16_t const GreekExt_upper_mapping[] = {
325 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
326 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
327 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000,
328 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000,
329 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F,
330 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F,
331 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
332 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
333 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000,
334 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000,
335 0x1F50, 0x1F59, 0x1F52, 0x1F5B, 0x1F54, 0x1F5D, 0x1F56, 0x1F5F,
336 0x0000, 0x1F59, 0x0000, 0x1F5B, 0x0000, 0x1F5D, 0x0000, 0x1F5F,
337 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
338 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
339 0x1FBA, 0x1FBB, 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FDA, 0x1FDB,
340 0x1FF8, 0x1FF9, 0x1FEA, 0x1FEB, 0x1FFA, 0x1FFB, 0x0000, 0x0000,
341 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F,
342 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F,
343 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
344 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
345 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF,
346 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF,
347 0x1FB8, 0x1FB9, 0x1FB2, 0x1FBC, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7,
348 0x1FB8, 0x1FB9, 0x1FBA, 0x1FBB, 0x1FBC, 0x1FBD, 0x0399, 0x1FBF,
349 0x1FC0, 0x1FC1, 0x1FC2, 0x1FCC, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7,
350 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FCC, 0x1FCD, 0x1FCE, 0x1FCF,
351 0x1FD8, 0x1FD9, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7,
352 0x1FD8, 0x1FD9, 0x1FDA, 0x1FDB, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF,
353 0x1FE8, 0x1FE9, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FEC, 0x1FE6, 0x1FE7,
354 0x1FE8, 0x1FE9, 0x1FEA, 0x1FEB, 0x1FEC, 0x1FED, 0x1FEE, 0x1FEF,
355 0x0000, 0x0000, 0x1FF2, 0x1FFC, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7,
356 0x1FF8, 0x1FF9, 0x1FFA, 0x1FFB, 0x1FFC, 0x1FFD, 0x1FFE, 0x0000
362 /* Basic Latin and Latin-1 Supplement, U+0000 to U+00FF */
363 if (code <= 0x00ff) {
364 if (code >= 0x0041 && code <= 0x005a) /* A-Z */
366 else if (code >= 0x0061 && code <= 0x007a) /* a-z */
368 else if ( (code >= 0x00c0 && code <= 0x00d6) ||
369 (code >= 0x00d8 && code <= 0x00de) )
371 else if ( (code >= 0x00e0 && code <= 0x00f6) ||
372 (code >= 0x00f8 && code <= 0x00fe) )
374 else if (code == 0x00ff) /* y with diaeresis */
376 else if (code == 0x00b5) /* micro sign */
381 /* Latin Extended-A, U+0100 to U+017F */
382 if (code >= 0x0100 && code <= 0x017f) {
383 if ( (code >= 0x0100 && code <= 0x012f) ||
384 (code >= 0x0132 && code <= 0x0137) ||
385 (code >= 0x014a && code <= 0x0177) ) {
389 else if ( (code >= 0x0139 && code <= 0x0148) ||
390 (code >= 0x0179 && code <= 0x017e) ) {
396 else if (code == 0x0130)
398 else if (code == 0x0131)
400 else if (code == 0x0178)
402 else if (code == 0x017f)
407 /* Latin Extended-B, U+0180 to U+024F */
408 if (code >= 0x0180 && code <= 0x024f) {
409 if (code >= 0x01cd && code <= 0x01dc) {
415 else if ( (code >= 0x01de && code <= 0x01ef) ||
416 (code >= 0x01f4 && code <= 0x01f5) ||
417 (code >= 0x01f8 && code <= 0x021f) ||
418 (code >= 0x0222 && code <= 0x0233) ) {
422 else if (code >= 0x0180 && code <= 0x01cc) {
423 *lower = LatinExtB_lower_mapping[code - 0x0180];
424 *upper = LatinExtB_upper_mapping[code - 0x0180];
426 else if (code == 0x01dd)
428 else if (code == 0x01f1 || code == 0x01f2) {
432 else if (code == 0x01f3)
434 else if (code == 0x01f6)
436 else if (code == 0x01f7)
438 else if (code == 0x0220)
443 /* IPA Extensions, U+0250 to U+02AF */
444 if (code >= 0x0253 && code <= 0x0292) {
445 *upper = IPAExt_upper_mapping[code - 0x0253];
448 /* Combining Diacritical Marks, U+0300 to U+036F */
449 if (code == 0x0345) {
453 /* Greek and Coptic, U+0370 to U+03FF */
454 if (code >= 0x0370 && code <= 0x03ff) {
455 *lower = Greek_lower_mapping[code - 0x0370];
456 *upper = Greek_upper_mapping[code - 0x0370];
463 /* Cyrillic and Cyrillic Supplementary, U+0400 to U+052F */
464 if ( (code >= 0x0400 && code <= 0x04ff) ||
465 (code >= 0x0500 && code <= 0x052f) ) {
466 if (code >= 0x0400 && code <= 0x040f)
468 else if (code >= 0x0410 && code <= 0x042f)
470 else if (code >= 0x0430 && code <= 0x044f)
472 else if (code >= 0x0450 && code <= 0x045f)
474 else if ( (code >= 0x0460 && code <= 0x0481) ||
475 (code >= 0x048a && code <= 0x04bf) ||
476 (code >= 0x04d0 && code <= 0x04f5) ||
477 (code >= 0x04f8 && code <= 0x04f9) ||
478 (code >= 0x0500 && code <= 0x050f) ) {
482 else if (code >= 0x04c1 && code <= 0x04ce) {
490 /* Armenian, U+0530 to U+058F */
491 if (code >= 0x0530 && code <= 0x058f) {
492 if (code >= 0x0531 && code <= 0x0556)
494 else if (code >=0x0561 && code <= 0x0586)
498 /* Latin Extended Additional, U+1E00 to U+1EFF */
499 if (code >= 0x1e00 && code <= 0x1eff) {
500 if ( (code >= 0x1e00 && code <= 0x1e95) ||
501 (code >= 0x1ea0 && code <= 0x1ef9) ) {
505 else if (code == 0x1e9b)
509 /* Greek Extended, U+1F00 to U+1FFF */
510 if (code >= 0x1f00 && code <= 0x1fff) {
511 *lower = GreekExt_lower_mapping[code - 0x1f00];
512 *upper = GreekExt_upper_mapping[code - 0x1f00];
519 /* Letterlike Symbols, U+2100 to U+214F */
520 if (code >= 0x2100 && code <= 0x214f) {
522 case 0x2126: *lower = 0x03c9; break;
523 case 0x212a: *lower = 0x006b; break;
524 case 0x212b: *lower = 0x00e5; break;
527 /* Number Forms, U+2150 to U+218F */
528 else if (code >= 0x2160 && code <= 0x216f)
530 else if (code >= 0x2170 && code <= 0x217f)
532 /* Enclosed Alphanumerics, U+2460 to U+24FF */
533 else if (code >= 0x24b6 && code <= 0x24cf)
535 else if (code >= 0x24d0 && code <= 0x24e9)
537 /* Halfwidth and Fullwidth Forms, U+FF00 to U+FFEF */
538 else if (code >= 0xff21 && code <= 0xff3a)
540 else if (code >= 0xff41 && code <= 0xff5a)
542 /* Deseret, U+10400 to U+104FF */
543 else if (code >= 0x10400 && code <= 0x10427)
545 else if (code >= 0x10428 && code <= 0x1044f)
550 XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper)
554 UCSConvertCase(sym, lower, upper);
559 if ((sym & 0xff000000) == 0x01000000) {
560 UCSConvertCase((sym & 0x00ffffff), lower, upper);
561 *upper |= 0x01000000;
562 *lower |= 0x01000000;
572 case 1: /* Latin 2 */
573 /* Assume the KeySym is a legal value (ignore discontinuities) */
574 if (sym == XKB_KEY_Aogonek)
575 *lower = XKB_KEY_aogonek;
576 else if (sym >= XKB_KEY_Lstroke && sym <= XKB_KEY_Sacute)
577 *lower += (XKB_KEY_lstroke - XKB_KEY_Lstroke);
578 else if (sym >= XKB_KEY_Scaron && sym <= XKB_KEY_Zacute)
579 *lower += (XKB_KEY_scaron - XKB_KEY_Scaron);
580 else if (sym >= XKB_KEY_Zcaron && sym <= XKB_KEY_Zabovedot)
581 *lower += (XKB_KEY_zcaron - XKB_KEY_Zcaron);
582 else if (sym == XKB_KEY_aogonek)
583 *upper = XKB_KEY_Aogonek;
584 else if (sym >= XKB_KEY_lstroke && sym <= XKB_KEY_sacute)
585 *upper -= (XKB_KEY_lstroke - XKB_KEY_Lstroke);
586 else if (sym >= XKB_KEY_scaron && sym <= XKB_KEY_zacute)
587 *upper -= (XKB_KEY_scaron - XKB_KEY_Scaron);
588 else if (sym >= XKB_KEY_zcaron && sym <= XKB_KEY_zabovedot)
589 *upper -= (XKB_KEY_zcaron - XKB_KEY_Zcaron);
590 else if (sym >= XKB_KEY_Racute && sym <= XKB_KEY_Tcedilla)
591 *lower += (XKB_KEY_racute - XKB_KEY_Racute);
592 else if (sym >= XKB_KEY_racute && sym <= XKB_KEY_tcedilla)
593 *upper -= (XKB_KEY_racute - XKB_KEY_Racute);
595 case 2: /* Latin 3 */
596 /* Assume the KeySym is a legal value (ignore discontinuities) */
597 if (sym >= XKB_KEY_Hstroke && sym <= XKB_KEY_Hcircumflex)
598 *lower += (XKB_KEY_hstroke - XKB_KEY_Hstroke);
599 else if (sym >= XKB_KEY_Gbreve && sym <= XKB_KEY_Jcircumflex)
600 *lower += (XKB_KEY_gbreve - XKB_KEY_Gbreve);
601 else if (sym >= XKB_KEY_hstroke && sym <= XKB_KEY_hcircumflex)
602 *upper -= (XKB_KEY_hstroke - XKB_KEY_Hstroke);
603 else if (sym >= XKB_KEY_gbreve && sym <= XKB_KEY_jcircumflex)
604 *upper -= (XKB_KEY_gbreve - XKB_KEY_Gbreve);
605 else if (sym >= XKB_KEY_Cabovedot && sym <= XKB_KEY_Scircumflex)
606 *lower += (XKB_KEY_cabovedot - XKB_KEY_Cabovedot);
607 else if (sym >= XKB_KEY_cabovedot && sym <= XKB_KEY_scircumflex)
608 *upper -= (XKB_KEY_cabovedot - XKB_KEY_Cabovedot);
610 case 3: /* Latin 4 */
611 /* Assume the KeySym is a legal value (ignore discontinuities) */
612 if (sym >= XKB_KEY_Rcedilla && sym <= XKB_KEY_Tslash)
613 *lower += (XKB_KEY_rcedilla - XKB_KEY_Rcedilla);
614 else if (sym >= XKB_KEY_rcedilla && sym <= XKB_KEY_tslash)
615 *upper -= (XKB_KEY_rcedilla - XKB_KEY_Rcedilla);
616 else if (sym == XKB_KEY_ENG)
617 *lower = XKB_KEY_eng;
618 else if (sym == XKB_KEY_eng)
619 *upper = XKB_KEY_ENG;
620 else if (sym >= XKB_KEY_Amacron && sym <= XKB_KEY_Umacron)
621 *lower += (XKB_KEY_amacron - XKB_KEY_Amacron);
622 else if (sym >= XKB_KEY_amacron && sym <= XKB_KEY_umacron)
623 *upper -= (XKB_KEY_amacron - XKB_KEY_Amacron);
625 case 6: /* Cyrillic */
626 /* Assume the KeySym is a legal value (ignore discontinuities) */
627 if (sym >= XKB_KEY_Serbian_DJE && sym <= XKB_KEY_Serbian_DZE)
628 *lower -= (XKB_KEY_Serbian_DJE - XKB_KEY_Serbian_dje);
629 else if (sym >= XKB_KEY_Serbian_dje && sym <= XKB_KEY_Serbian_dze)
630 *upper += (XKB_KEY_Serbian_DJE - XKB_KEY_Serbian_dje);
631 else if (sym >= XKB_KEY_Cyrillic_YU && sym <= XKB_KEY_Cyrillic_HARDSIGN)
632 *lower -= (XKB_KEY_Cyrillic_YU - XKB_KEY_Cyrillic_yu);
633 else if (sym >= XKB_KEY_Cyrillic_yu && sym <= XKB_KEY_Cyrillic_hardsign)
634 *upper += (XKB_KEY_Cyrillic_YU - XKB_KEY_Cyrillic_yu);
637 /* Assume the KeySym is a legal value (ignore discontinuities) */
638 if (sym >= XKB_KEY_Greek_ALPHAaccent && sym <= XKB_KEY_Greek_OMEGAaccent)
639 *lower += (XKB_KEY_Greek_alphaaccent - XKB_KEY_Greek_ALPHAaccent);
640 else if (sym >= XKB_KEY_Greek_alphaaccent && sym <= XKB_KEY_Greek_omegaaccent &&
641 sym != XKB_KEY_Greek_iotaaccentdieresis &&
642 sym != XKB_KEY_Greek_upsilonaccentdieresis)
643 *upper -= (XKB_KEY_Greek_alphaaccent - XKB_KEY_Greek_ALPHAaccent);
644 else if (sym >= XKB_KEY_Greek_ALPHA && sym <= XKB_KEY_Greek_OMEGA)
645 *lower += (XKB_KEY_Greek_alpha - XKB_KEY_Greek_ALPHA);
646 else if (sym >= XKB_KEY_Greek_alpha && sym <= XKB_KEY_Greek_omega &&
647 sym != XKB_KEY_Greek_finalsmallsigma)
648 *upper -= (XKB_KEY_Greek_alpha - XKB_KEY_Greek_ALPHA);
650 case 0x13: /* Latin 9 */
651 if (sym == XKB_KEY_OE)
653 else if (sym == XKB_KEY_oe)
655 else if (sym == XKB_KEY_Ydiaeresis)
656 *lower = XKB_KEY_ydiaeresis;