2 * Copyright 1985, 1987, 1990, 1998 The Open Group
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
18 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 * Except as contained in this notice, the names of the authors or their
22 * institutions shall not be used in advertising or otherwise to promote the
23 * sale, use or other dealings in this Software without prior written
24 * authorization from the authors.
28 * Copyright © 2009 Dan Nicholson
30 * Permission is hereby granted, free of charge, to any person obtaining a
31 * copy of this software and associated documentation files (the "Software"),
32 * to deal in the Software without restriction, including without limitation
33 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
34 * and/or sell copies of the Software, and to permit persons to whom the
35 * Software is furnished to do so, subject to the following conditions:
37 * The above copyright notice and this permission notice (including the next
38 * paragraph) shall be included in all copies or substantial portions of the
41 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
44 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
46 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
47 * DEALINGS IN THE SOFTWARE.
50 #include "xkbcommon/xkbcommon.h"
52 #include "ks_tables.h"
56 xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
59 const unsigned char *entry;
60 unsigned char val1, val2, val3, val4;
62 if ((ks & ((unsigned long) ~0x1fffffff)) != 0) {
63 snprintf(buffer, size, "Invalid");
67 /* Try to find it in our hash table. */
68 if (ks <= 0x1fffffff) {
70 val2 = (ks >> 16) & 0xff;
71 val3 = (ks >> 8) & 0xff;
77 while ((idx = hashKeysym[i])) {
78 entry = &_XkeyTable[idx];
80 if ((entry[0] == val1) && (entry[1] == val2) &&
81 (entry[2] == val3) && (entry[3] == val4)) {
82 return snprintf(buffer, size, "%s", entry + 4);
94 if (ks >= 0x01000100 && ks <= 0x0110ffff)
95 /* Unnamed Unicode codepoint. */
96 return snprintf(buffer, size, "U%lx", ks & 0xffffffUL);
98 /* Unnamed, non-Unicode, symbol (shouldn't generally happen). */
99 return snprintf(buffer, size, "0x%08x", ks);
102 XKB_EXPORT xkb_keysym_t
103 xkb_keysym_from_name(const char *s)
109 const unsigned char *entry;
110 unsigned char sig1, sig2;
114 sig = (sig << 1) + c;
116 i = sig % KTABLESIZE;
118 sig1 = (sig >> 8) & 0xff;
122 while ((idx = hashString[i])) {
123 entry = &_XkeyTable[idx];
125 if ((entry[0] == sig1) && (entry[1] == sig2) &&
126 streq(s, (const char *) entry + 6)) {
127 val = (entry[2] << 24) | (entry[3] << 16) |
128 (entry[4] << 8) | entry[5];
130 val = XKB_KEY_VoidSymbol;
143 val = strtoul(&s[1], &tmp, 16);
144 if (tmp && *tmp != '\0')
145 return XKB_KEY_NoSymbol;
147 if (val < 0x20 || (val > 0x7e && val < 0xa0))
148 return XKB_KEY_NoSymbol;
152 return XKB_KEY_NoSymbol;
153 return val | 0x01000000;
155 else if (s[0] == '0' && s[1] == 'x') {
156 val = strtoul(&s[2], &tmp, 16);
157 if (tmp && *tmp != '\0')
158 return XKB_KEY_NoSymbol;
163 /* Stupid inconsistency between the headers and XKeysymDB: the former has
164 * no separating underscore, while some XF86* syms in the latter did.
165 * As a last ditch effort, try without. */
166 if (strncmp(s, "XF86_", 5) == 0) {
170 return XKB_KEY_NoSymbol;
171 memmove(&tmp[4], &tmp[5], strlen(s) - 5 + 1);
172 ret = xkb_keysym_from_name(tmp);
177 return XKB_KEY_NoSymbol;
181 xkb_keysym_is_keypad(xkb_keysym_t keysym)
183 return keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_Equal;
187 XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper);
190 xkb_keysym_is_lower(xkb_keysym_t ks)
192 xkb_keysym_t lower, upper;
194 XConvertCase(ks, &lower, &upper);
199 return (ks == lower ? true : false);
203 xkb_keysym_is_upper(xkb_keysym_t ks)
205 xkb_keysym_t lower, upper;
207 XConvertCase(ks, &lower, &upper);
212 return (ks == upper ? true : false);
216 * The following is copied verbatim from libX11:src/KeyBind.c, commit
217 * d45b3fc19fbe95c41afc4e51d768df6d42332010, with the following changes:
218 * - unsigned -> uint32_t
219 * - unsigend short -> uint16_t
222 * XXX: If newlocale() and iswlower_l()/iswupper_l() interface ever
223 * become portable, we should use that in conjunction with
224 * xkb_keysym_to_utf32(), instead of all this stuff. We should
225 * be sure to give the same results as libX11, though, and be
226 * locale independent; this information is used by xkbcomp to
227 * find the automatic type to assign to key groups.
231 UCSConvertCase(uint32_t code, xkb_keysym_t *lower, xkb_keysym_t *upper)
233 /* Case conversion for UCS, as in Unicode Data version 4.0.0 */
234 /* NB: Only converts simple one-to-one mappings. */
236 /* Tables are used where they take less space than */
237 /* the code to work out the mappings. Zero values mean */
238 /* undefined code points. */
240 static uint16_t const IPAExt_upper_mapping[] = { /* part only */
241 0x0181, 0x0186, 0x0255, 0x0189, 0x018A,
242 0x0258, 0x018F, 0x025A, 0x0190, 0x025C, 0x025D, 0x025E, 0x025F,
243 0x0193, 0x0261, 0x0262, 0x0194, 0x0264, 0x0265, 0x0266, 0x0267,
244 0x0197, 0x0196, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x019C,
245 0x0270, 0x0271, 0x019D, 0x0273, 0x0274, 0x019F, 0x0276, 0x0277,
246 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F,
247 0x01A6, 0x0281, 0x0282, 0x01A9, 0x0284, 0x0285, 0x0286, 0x0287,
248 0x01AE, 0x0289, 0x01B1, 0x01B2, 0x028C, 0x028D, 0x028E, 0x028F,
249 0x0290, 0x0291, 0x01B7
252 static uint16_t const LatinExtB_upper_mapping[] = { /* first part only */
253 0x0180, 0x0181, 0x0182, 0x0182, 0x0184, 0x0184, 0x0186, 0x0187,
254 0x0187, 0x0189, 0x018A, 0x018B, 0x018B, 0x018D, 0x018E, 0x018F,
255 0x0190, 0x0191, 0x0191, 0x0193, 0x0194, 0x01F6, 0x0196, 0x0197,
256 0x0198, 0x0198, 0x019A, 0x019B, 0x019C, 0x019D, 0x0220, 0x019F,
257 0x01A0, 0x01A0, 0x01A2, 0x01A2, 0x01A4, 0x01A4, 0x01A6, 0x01A7,
258 0x01A7, 0x01A9, 0x01AA, 0x01AB, 0x01AC, 0x01AC, 0x01AE, 0x01AF,
259 0x01AF, 0x01B1, 0x01B2, 0x01B3, 0x01B3, 0x01B5, 0x01B5, 0x01B7,
260 0x01B8, 0x01B8, 0x01BA, 0x01BB, 0x01BC, 0x01BC, 0x01BE, 0x01F7,
261 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C4, 0x01C4, 0x01C7,
262 0x01C7, 0x01C7, 0x01CA, 0x01CA, 0x01CA
265 static uint16_t const LatinExtB_lower_mapping[] = { /* first part only */
266 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188,
267 0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259,
268 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268,
269 0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275,
270 0x01A1, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x0280, 0x01A8,
271 0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01B0,
272 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292,
273 0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF,
274 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9,
275 0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC
278 static uint16_t const Greek_upper_mapping[] = {
279 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000,
280 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000,
281 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x0386, 0x0387,
282 0x0388, 0x0389, 0x038A, 0x0000, 0x038C, 0x0000, 0x038E, 0x038F,
283 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
284 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
285 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
286 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x0386, 0x0388, 0x0389, 0x038A,
287 0x03B0, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
288 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
289 0x03A0, 0x03A1, 0x03A3, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
290 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x038C, 0x038E, 0x038F, 0x0000,
291 0x0392, 0x0398, 0x03D2, 0x03D3, 0x03D4, 0x03A6, 0x03A0, 0x03D7,
292 0x03D8, 0x03D8, 0x03DA, 0x03DA, 0x03DC, 0x03DC, 0x03DE, 0x03DE,
293 0x03E0, 0x03E0, 0x03E2, 0x03E2, 0x03E4, 0x03E4, 0x03E6, 0x03E6,
294 0x03E8, 0x03E8, 0x03EA, 0x03EA, 0x03EC, 0x03EC, 0x03EE, 0x03EE,
295 0x039A, 0x03A1, 0x03F9, 0x03F3, 0x03F4, 0x0395, 0x03F6, 0x03F7,
296 0x03F7, 0x03F9, 0x03FA, 0x03FA, 0x0000, 0x0000, 0x0000, 0x0000
299 static uint16_t const Greek_lower_mapping[] = {
300 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000,
301 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000,
302 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x03AC, 0x0387,
303 0x03AD, 0x03AE, 0x03AF, 0x0000, 0x03CC, 0x0000, 0x03CD, 0x03CE,
304 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
305 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
306 0x03C0, 0x03C1, 0x0000, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
307 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
308 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
309 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
310 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
311 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000,
312 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7,
313 0x03D9, 0x03D9, 0x03DB, 0x03DB, 0x03DD, 0x03DD, 0x03DF, 0x03DF,
314 0x03E1, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7,
315 0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF,
316 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03B8, 0x03F5, 0x03F6, 0x03F8,
317 0x03F8, 0x03F2, 0x03FB, 0x03FB, 0x0000, 0x0000, 0x0000, 0x0000
320 static uint16_t const GreekExt_lower_mapping[] = {
321 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
322 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07,
323 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
324 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000,
325 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
326 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27,
327 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
328 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37,
329 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
330 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000,
331 0x1F50, 0x1F51, 0x1F52, 0x1F53, 0x1F54, 0x1F55, 0x1F56, 0x1F57,
332 0x0000, 0x1F51, 0x0000, 0x1F53, 0x0000, 0x1F55, 0x0000, 0x1F57,
333 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
334 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67,
335 0x1F70, 0x1F71, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F76, 0x1F77,
336 0x1F78, 0x1F79, 0x1F7A, 0x1F7B, 0x1F7C, 0x1F7D, 0x0000, 0x0000,
337 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
338 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87,
339 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
340 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97,
341 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
342 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7,
343 0x1FB0, 0x1FB1, 0x1FB2, 0x1FB3, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7,
344 0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x1FBD, 0x1FBE, 0x1FBF,
345 0x1FC0, 0x1FC1, 0x1FC2, 0x1FC3, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7,
346 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x1FCD, 0x1FCE, 0x1FCF,
347 0x1FD0, 0x1FD1, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7,
348 0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF,
349 0x1FE0, 0x1FE1, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FE5, 0x1FE6, 0x1FE7,
350 0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x1FED, 0x1FEE, 0x1FEF,
351 0x0000, 0x0000, 0x1FF2, 0x1FF3, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7,
352 0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x1FFD, 0x1FFE, 0x0000
355 static uint16_t const GreekExt_upper_mapping[] = {
356 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
357 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F,
358 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000,
359 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000,
360 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F,
361 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F,
362 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
363 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F,
364 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000,
365 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000,
366 0x1F50, 0x1F59, 0x1F52, 0x1F5B, 0x1F54, 0x1F5D, 0x1F56, 0x1F5F,
367 0x0000, 0x1F59, 0x0000, 0x1F5B, 0x0000, 0x1F5D, 0x0000, 0x1F5F,
368 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
369 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F,
370 0x1FBA, 0x1FBB, 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FDA, 0x1FDB,
371 0x1FF8, 0x1FF9, 0x1FEA, 0x1FEB, 0x1FFA, 0x1FFB, 0x0000, 0x0000,
372 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F,
373 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F,
374 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
375 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F,
376 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF,
377 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF,
378 0x1FB8, 0x1FB9, 0x1FB2, 0x1FBC, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7,
379 0x1FB8, 0x1FB9, 0x1FBA, 0x1FBB, 0x1FBC, 0x1FBD, 0x0399, 0x1FBF,
380 0x1FC0, 0x1FC1, 0x1FC2, 0x1FCC, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7,
381 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FCC, 0x1FCD, 0x1FCE, 0x1FCF,
382 0x1FD8, 0x1FD9, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7,
383 0x1FD8, 0x1FD9, 0x1FDA, 0x1FDB, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF,
384 0x1FE8, 0x1FE9, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FEC, 0x1FE6, 0x1FE7,
385 0x1FE8, 0x1FE9, 0x1FEA, 0x1FEB, 0x1FEC, 0x1FED, 0x1FEE, 0x1FEF,
386 0x0000, 0x0000, 0x1FF2, 0x1FFC, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7,
387 0x1FF8, 0x1FF9, 0x1FFA, 0x1FFB, 0x1FFC, 0x1FFD, 0x1FFE, 0x0000
393 /* Basic Latin and Latin-1 Supplement, U+0000 to U+00FF */
394 if (code <= 0x00ff) {
395 if (code >= 0x0041 && code <= 0x005a) /* A-Z */
397 else if (code >= 0x0061 && code <= 0x007a) /* a-z */
399 else if ( (code >= 0x00c0 && code <= 0x00d6) ||
400 (code >= 0x00d8 && code <= 0x00de) )
402 else if ( (code >= 0x00e0 && code <= 0x00f6) ||
403 (code >= 0x00f8 && code <= 0x00fe) )
405 else if (code == 0x00ff) /* y with diaeresis */
407 else if (code == 0x00b5) /* micro sign */
412 /* Latin Extended-A, U+0100 to U+017F */
413 if (code >= 0x0100 && code <= 0x017f) {
414 if ( (code >= 0x0100 && code <= 0x012f) ||
415 (code >= 0x0132 && code <= 0x0137) ||
416 (code >= 0x014a && code <= 0x0177) ) {
420 else if ( (code >= 0x0139 && code <= 0x0148) ||
421 (code >= 0x0179 && code <= 0x017e) ) {
427 else if (code == 0x0130)
429 else if (code == 0x0131)
431 else if (code == 0x0178)
433 else if (code == 0x017f)
438 /* Latin Extended-B, U+0180 to U+024F */
439 if (code >= 0x0180 && code <= 0x024f) {
440 if (code >= 0x01cd && code <= 0x01dc) {
446 else if ( (code >= 0x01de && code <= 0x01ef) ||
447 (code >= 0x01f4 && code <= 0x01f5) ||
448 (code >= 0x01f8 && code <= 0x021f) ||
449 (code >= 0x0222 && code <= 0x0233) ) {
453 else if (code >= 0x0180 && code <= 0x01cc) {
454 *lower = LatinExtB_lower_mapping[code - 0x0180];
455 *upper = LatinExtB_upper_mapping[code - 0x0180];
457 else if (code == 0x01dd)
459 else if (code == 0x01f1 || code == 0x01f2) {
463 else if (code == 0x01f3)
465 else if (code == 0x01f6)
467 else if (code == 0x01f7)
469 else if (code == 0x0220)
474 /* IPA Extensions, U+0250 to U+02AF */
475 if (code >= 0x0253 && code <= 0x0292) {
476 *upper = IPAExt_upper_mapping[code - 0x0253];
479 /* Combining Diacritical Marks, U+0300 to U+036F */
480 if (code == 0x0345) {
484 /* Greek and Coptic, U+0370 to U+03FF */
485 if (code >= 0x0370 && code <= 0x03ff) {
486 *lower = Greek_lower_mapping[code - 0x0370];
487 *upper = Greek_upper_mapping[code - 0x0370];
494 /* Cyrillic and Cyrillic Supplementary, U+0400 to U+052F */
495 if ( (code >= 0x0400 && code <= 0x04ff) ||
496 (code >= 0x0500 && code <= 0x052f) ) {
497 if (code >= 0x0400 && code <= 0x040f)
499 else if (code >= 0x0410 && code <= 0x042f)
501 else if (code >= 0x0430 && code <= 0x044f)
503 else if (code >= 0x0450 && code <= 0x045f)
505 else if ( (code >= 0x0460 && code <= 0x0481) ||
506 (code >= 0x048a && code <= 0x04bf) ||
507 (code >= 0x04d0 && code <= 0x04f5) ||
508 (code >= 0x04f8 && code <= 0x04f9) ||
509 (code >= 0x0500 && code <= 0x050f) ) {
513 else if (code >= 0x04c1 && code <= 0x04ce) {
521 /* Armenian, U+0530 to U+058F */
522 if (code >= 0x0530 && code <= 0x058f) {
523 if (code >= 0x0531 && code <= 0x0556)
525 else if (code >=0x0561 && code <= 0x0586)
529 /* Latin Extended Additional, U+1E00 to U+1EFF */
530 if (code >= 0x1e00 && code <= 0x1eff) {
531 if ( (code >= 0x1e00 && code <= 0x1e95) ||
532 (code >= 0x1ea0 && code <= 0x1ef9) ) {
536 else if (code == 0x1e9b)
540 /* Greek Extended, U+1F00 to U+1FFF */
541 if (code >= 0x1f00 && code <= 0x1fff) {
542 *lower = GreekExt_lower_mapping[code - 0x1f00];
543 *upper = GreekExt_upper_mapping[code - 0x1f00];
550 /* Letterlike Symbols, U+2100 to U+214F */
551 if (code >= 0x2100 && code <= 0x214f) {
553 case 0x2126: *lower = 0x03c9; break;
554 case 0x212a: *lower = 0x006b; break;
555 case 0x212b: *lower = 0x00e5; break;
558 /* Number Forms, U+2150 to U+218F */
559 else if (code >= 0x2160 && code <= 0x216f)
561 else if (code >= 0x2170 && code <= 0x217f)
563 /* Enclosed Alphanumerics, U+2460 to U+24FF */
564 else if (code >= 0x24b6 && code <= 0x24cf)
566 else if (code >= 0x24d0 && code <= 0x24e9)
568 /* Halfwidth and Fullwidth Forms, U+FF00 to U+FFEF */
569 else if (code >= 0xff21 && code <= 0xff3a)
571 else if (code >= 0xff41 && code <= 0xff5a)
573 /* Deseret, U+10400 to U+104FF */
574 else if (code >= 0x10400 && code <= 0x10427)
576 else if (code >= 0x10428 && code <= 0x1044f)
581 XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper)
585 UCSConvertCase(sym, lower, upper);
590 if ((sym & 0xff000000) == 0x01000000) {
591 UCSConvertCase((sym & 0x00ffffff), lower, upper);
592 *upper |= 0x01000000;
593 *lower |= 0x01000000;
603 case 1: /* Latin 2 */
604 /* Assume the KeySym is a legal value (ignore discontinuities) */
605 if (sym == XKB_KEY_Aogonek)
606 *lower = XKB_KEY_aogonek;
607 else if (sym >= XKB_KEY_Lstroke && sym <= XKB_KEY_Sacute)
608 *lower += (XKB_KEY_lstroke - XKB_KEY_Lstroke);
609 else if (sym >= XKB_KEY_Scaron && sym <= XKB_KEY_Zacute)
610 *lower += (XKB_KEY_scaron - XKB_KEY_Scaron);
611 else if (sym >= XKB_KEY_Zcaron && sym <= XKB_KEY_Zabovedot)
612 *lower += (XKB_KEY_zcaron - XKB_KEY_Zcaron);
613 else if (sym == XKB_KEY_aogonek)
614 *upper = XKB_KEY_Aogonek;
615 else if (sym >= XKB_KEY_lstroke && sym <= XKB_KEY_sacute)
616 *upper -= (XKB_KEY_lstroke - XKB_KEY_Lstroke);
617 else if (sym >= XKB_KEY_scaron && sym <= XKB_KEY_zacute)
618 *upper -= (XKB_KEY_scaron - XKB_KEY_Scaron);
619 else if (sym >= XKB_KEY_zcaron && sym <= XKB_KEY_zabovedot)
620 *upper -= (XKB_KEY_zcaron - XKB_KEY_Zcaron);
621 else if (sym >= XKB_KEY_Racute && sym <= XKB_KEY_Tcedilla)
622 *lower += (XKB_KEY_racute - XKB_KEY_Racute);
623 else if (sym >= XKB_KEY_racute && sym <= XKB_KEY_tcedilla)
624 *upper -= (XKB_KEY_racute - XKB_KEY_Racute);
626 case 2: /* Latin 3 */
627 /* Assume the KeySym is a legal value (ignore discontinuities) */
628 if (sym >= XKB_KEY_Hstroke && sym <= XKB_KEY_Hcircumflex)
629 *lower += (XKB_KEY_hstroke - XKB_KEY_Hstroke);
630 else if (sym >= XKB_KEY_Gbreve && sym <= XKB_KEY_Jcircumflex)
631 *lower += (XKB_KEY_gbreve - XKB_KEY_Gbreve);
632 else if (sym >= XKB_KEY_hstroke && sym <= XKB_KEY_hcircumflex)
633 *upper -= (XKB_KEY_hstroke - XKB_KEY_Hstroke);
634 else if (sym >= XKB_KEY_gbreve && sym <= XKB_KEY_jcircumflex)
635 *upper -= (XKB_KEY_gbreve - XKB_KEY_Gbreve);
636 else if (sym >= XKB_KEY_Cabovedot && sym <= XKB_KEY_Scircumflex)
637 *lower += (XKB_KEY_cabovedot - XKB_KEY_Cabovedot);
638 else if (sym >= XKB_KEY_cabovedot && sym <= XKB_KEY_scircumflex)
639 *upper -= (XKB_KEY_cabovedot - XKB_KEY_Cabovedot);
641 case 3: /* Latin 4 */
642 /* Assume the KeySym is a legal value (ignore discontinuities) */
643 if (sym >= XKB_KEY_Rcedilla && sym <= XKB_KEY_Tslash)
644 *lower += (XKB_KEY_rcedilla - XKB_KEY_Rcedilla);
645 else if (sym >= XKB_KEY_rcedilla && sym <= XKB_KEY_tslash)
646 *upper -= (XKB_KEY_rcedilla - XKB_KEY_Rcedilla);
647 else if (sym == XKB_KEY_ENG)
648 *lower = XKB_KEY_eng;
649 else if (sym == XKB_KEY_eng)
650 *upper = XKB_KEY_ENG;
651 else if (sym >= XKB_KEY_Amacron && sym <= XKB_KEY_Umacron)
652 *lower += (XKB_KEY_amacron - XKB_KEY_Amacron);
653 else if (sym >= XKB_KEY_amacron && sym <= XKB_KEY_umacron)
654 *upper -= (XKB_KEY_amacron - XKB_KEY_Amacron);
656 case 6: /* Cyrillic */
657 /* Assume the KeySym is a legal value (ignore discontinuities) */
658 if (sym >= XKB_KEY_Serbian_DJE && sym <= XKB_KEY_Serbian_DZE)
659 *lower -= (XKB_KEY_Serbian_DJE - XKB_KEY_Serbian_dje);
660 else if (sym >= XKB_KEY_Serbian_dje && sym <= XKB_KEY_Serbian_dze)
661 *upper += (XKB_KEY_Serbian_DJE - XKB_KEY_Serbian_dje);
662 else if (sym >= XKB_KEY_Cyrillic_YU && sym <= XKB_KEY_Cyrillic_HARDSIGN)
663 *lower -= (XKB_KEY_Cyrillic_YU - XKB_KEY_Cyrillic_yu);
664 else if (sym >= XKB_KEY_Cyrillic_yu && sym <= XKB_KEY_Cyrillic_hardsign)
665 *upper += (XKB_KEY_Cyrillic_YU - XKB_KEY_Cyrillic_yu);
668 /* Assume the KeySym is a legal value (ignore discontinuities) */
669 if (sym >= XKB_KEY_Greek_ALPHAaccent && sym <= XKB_KEY_Greek_OMEGAaccent)
670 *lower += (XKB_KEY_Greek_alphaaccent - XKB_KEY_Greek_ALPHAaccent);
671 else if (sym >= XKB_KEY_Greek_alphaaccent && sym <= XKB_KEY_Greek_omegaaccent &&
672 sym != XKB_KEY_Greek_iotaaccentdieresis &&
673 sym != XKB_KEY_Greek_upsilonaccentdieresis)
674 *upper -= (XKB_KEY_Greek_alphaaccent - XKB_KEY_Greek_ALPHAaccent);
675 else if (sym >= XKB_KEY_Greek_ALPHA && sym <= XKB_KEY_Greek_OMEGA)
676 *lower += (XKB_KEY_Greek_alpha - XKB_KEY_Greek_ALPHA);
677 else if (sym >= XKB_KEY_Greek_alpha && sym <= XKB_KEY_Greek_omega &&
678 sym != XKB_KEY_Greek_finalsmallsigma)
679 *upper -= (XKB_KEY_Greek_alpha - XKB_KEY_Greek_ALPHA);
681 case 0x13: /* Latin 9 */
682 if (sym == XKB_KEY_OE)
684 else if (sym == XKB_KEY_oe)
686 else if (sym == XKB_KEY_Ydiaeresis)
687 *lower = XKB_KEY_ydiaeresis;