| File: | src/KeyBind.c |
| Location: | line 944, column 5 |
| Description: | Null pointer argument in call to memory copy function |
| 1 | /* | |||||
| 2 | ||||||
| 3 | Copyright 1985, 1987, 1998 The Open Group | |||||
| 4 | ||||||
| 5 | Permission to use, copy, modify, distribute, and sell this software and its | |||||
| 6 | documentation for any purpose is hereby granted without fee, provided that | |||||
| 7 | the above copyright notice appear in all copies and that both that | |||||
| 8 | copyright notice and this permission notice appear in supporting | |||||
| 9 | documentation. | |||||
| 10 | ||||||
| 11 | The above copyright notice and this permission notice shall be included in | |||||
| 12 | all copies or substantial portions of the Software. | |||||
| 13 | ||||||
| 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 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||||
| 18 | AN 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. | |||||
| 20 | ||||||
| 21 | Except as contained in this notice, the name of The Open Group shall not be | |||||
| 22 | used in advertising or otherwise to promote the sale, use or other dealings | |||||
| 23 | in this Software without prior written authorization from The Open Group. | |||||
| 24 | ||||||
| 25 | */ | |||||
| 26 | ||||||
| 27 | /* Beware, here be monsters (still under construction... - JG */ | |||||
| 28 | ||||||
| 29 | #ifdef HAVE_CONFIG_H1 | |||||
| 30 | #include <config.h> | |||||
| 31 | #endif | |||||
| 32 | #include <X11/Xlibint.h> | |||||
| 33 | #include <X11/Xutil.h> | |||||
| 34 | #define XK_MISCELLANY | |||||
| 35 | #define XK_LATIN1 | |||||
| 36 | #define XK_LATIN2 | |||||
| 37 | #define XK_LATIN3 | |||||
| 38 | #define XK_LATIN4 | |||||
| 39 | #define XK_LATIN8 | |||||
| 40 | #define XK_LATIN9 | |||||
| 41 | #define XK_CYRILLIC | |||||
| 42 | #define XK_GREEK | |||||
| 43 | #define XK_ARMENIAN | |||||
| 44 | #define XK_CAUCASUS | |||||
| 45 | #define XK_VIETNAMESE | |||||
| 46 | #define XK_XKB_KEYS | |||||
| 47 | #define XK_SINHALA | |||||
| 48 | #include <X11/keysymdef.h> | |||||
| 49 | #include <stdio.h> | |||||
| 50 | ||||||
| 51 | #include "Xresource.h" | |||||
| 52 | #include "Key.h" | |||||
| 53 | ||||||
| 54 | #ifdef XKB1 | |||||
| 55 | #include "XKBlib.h" | |||||
| 56 | #include "XKBlibint.h" | |||||
| 57 | #define XKeycodeToKeysym_XKeycodeToKeysym _XKeycodeToKeysym | |||||
| 58 | #define XKeysymToKeycode_XKeysymToKeycode _XKeysymToKeycode | |||||
| 59 | #define XLookupKeysym_XLookupKeysym _XLookupKeysym | |||||
| 60 | #define XRefreshKeyboardMapping_XRefreshKeyboardMapping _XRefreshKeyboardMapping | |||||
| 61 | #define XLookupString_XLookupString _XLookupString | |||||
| 62 | /* XKBBind.c */ | |||||
| 63 | #else | |||||
| 64 | #define XkbKeysymToModifiers _XKeysymToModifiers | |||||
| 65 | #endif | |||||
| 66 | ||||||
| 67 | #define AllMods((1<<0)|(1<<1)|(1<<2)| (1<<3)|(1<< 4)|(1<<5)|(1<<6)|(1<<7)) (ShiftMask(1<<0)|LockMask(1<<1)|ControlMask(1<<2)| \ | |||||
| 68 | Mod1Mask(1<<3)|Mod2Mask(1<<4)|Mod3Mask(1<<5)|Mod4Mask(1<<6)|Mod5Mask(1<<7)) | |||||
| 69 | ||||||
| 70 | static void | |||||
| 71 | ComputeMaskFromKeytrans( | |||||
| 72 | Display *dpy, | |||||
| 73 | register struct _XKeytrans *p); | |||||
| 74 | ||||||
| 75 | struct _XKeytrans { | |||||
| 76 | struct _XKeytrans *next;/* next on list */ | |||||
| 77 | char *string; /* string to return when the time comes */ | |||||
| 78 | int len; /* length of string (since NULL is legit)*/ | |||||
| 79 | KeySym key; /* keysym rebound */ | |||||
| 80 | unsigned int state; /* modifier state */ | |||||
| 81 | KeySym *modifiers; /* modifier keysyms you want */ | |||||
| 82 | int mlen; /* length of modifier list */ | |||||
| 83 | }; | |||||
| 84 | ||||||
| 85 | static KeySym | |||||
| 86 | KeyCodetoKeySym(register Display *dpy, KeyCode keycode, int col) | |||||
| 87 | { | |||||
| 88 | register int per = dpy->keysyms_per_keycode; | |||||
| 89 | register KeySym *syms; | |||||
| 90 | KeySym lsym, usym; | |||||
| 91 | ||||||
| 92 | if ((col < 0) || ((col >= per) && (col > 3)) || | |||||
| 93 | ((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode)) | |||||
| 94 | return NoSymbol0L; | |||||
| 95 | ||||||
| 96 | syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per]; | |||||
| 97 | if (col < 4) { | |||||
| 98 | if (col > 1) { | |||||
| 99 | while ((per > 2) && (syms[per - 1] == NoSymbol0L)) | |||||
| 100 | per--; | |||||
| 101 | if (per < 3) | |||||
| 102 | col -= 2; | |||||
| 103 | } | |||||
| 104 | if ((per <= (col|1)) || (syms[col|1] == NoSymbol0L)) { | |||||
| 105 | XConvertCase(syms[col&~1], &lsym, &usym); | |||||
| 106 | if (!(col & 1)) | |||||
| 107 | return lsym; | |||||
| 108 | else if (usym == lsym) | |||||
| 109 | return NoSymbol0L; | |||||
| 110 | else | |||||
| 111 | return usym; | |||||
| 112 | } | |||||
| 113 | } | |||||
| 114 | return syms[col]; | |||||
| 115 | } | |||||
| 116 | ||||||
| 117 | KeySym | |||||
| 118 | XKeycodeToKeysym_XKeycodeToKeysym(Display *dpy, | |||||
| 119 | #if NeedWidePrototypes1 | |||||
| 120 | unsigned int kc, | |||||
| 121 | #else | |||||
| 122 | KeyCode kc, | |||||
| 123 | #endif | |||||
| 124 | int col) | |||||
| 125 | { | |||||
| 126 | if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) | |||||
| 127 | return NoSymbol0L; | |||||
| 128 | return KeyCodetoKeySym(dpy, kc, col); | |||||
| 129 | } | |||||
| 130 | ||||||
| 131 | KeyCode | |||||
| 132 | XKeysymToKeycode_XKeysymToKeycode( | |||||
| 133 | Display *dpy, | |||||
| 134 | KeySym ks) | |||||
| 135 | { | |||||
| 136 | register int i, j; | |||||
| 137 | ||||||
| 138 | if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) | |||||
| 139 | return (KeyCode) 0; | |||||
| 140 | for (j = 0; j < dpy->keysyms_per_keycode; j++) { | |||||
| 141 | for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) { | |||||
| 142 | if (KeyCodetoKeySym(dpy, (KeyCode) i, j) == ks) | |||||
| 143 | return i; | |||||
| 144 | } | |||||
| 145 | } | |||||
| 146 | return 0; | |||||
| 147 | } | |||||
| 148 | ||||||
| 149 | KeySym | |||||
| 150 | XLookupKeysym_XLookupKeysym( | |||||
| 151 | register XKeyEvent *event, | |||||
| 152 | int col) | |||||
| 153 | { | |||||
| 154 | if ((! event->display->keysyms) && (! _XKeyInitialize(event->display))) | |||||
| 155 | return NoSymbol0L; | |||||
| 156 | return KeyCodetoKeySym(event->display, event->keycode, col); | |||||
| 157 | } | |||||
| 158 | ||||||
| 159 | static void | |||||
| 160 | ResetModMap( | |||||
| 161 | Display *dpy) | |||||
| 162 | { | |||||
| 163 | register XModifierKeymap *map; | |||||
| 164 | register int i, j, n; | |||||
| 165 | KeySym sym; | |||||
| 166 | register struct _XKeytrans *p; | |||||
| 167 | ||||||
| 168 | map = dpy->modifiermap; | |||||
| 169 | /* If any Lock key contains Caps_Lock, then interpret as Caps_Lock, | |||||
| 170 | * else if any contains Shift_Lock, then interpret as Shift_Lock, | |||||
| 171 | * else ignore Lock altogether. | |||||
| 172 | */ | |||||
| 173 | dpy->lock_meaning = NoSymbol0L; | |||||
| 174 | /* Lock modifiers are in the second row of the matrix */ | |||||
| 175 | n = 2 * map->max_keypermod; | |||||
| 176 | for (i = map->max_keypermod; i < n; i++) { | |||||
| 177 | for (j = 0; j < dpy->keysyms_per_keycode; j++) { | |||||
| 178 | sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j); | |||||
| 179 | if (sym == XK_Caps_Lock0xffe5) { | |||||
| 180 | dpy->lock_meaning = XK_Caps_Lock0xffe5; | |||||
| 181 | break; | |||||
| 182 | } else if (sym == XK_Shift_Lock0xffe6) { | |||||
| 183 | dpy->lock_meaning = XK_Shift_Lock0xffe6; | |||||
| 184 | } | |||||
| 185 | else if (sym == XK_ISO_Lock0xfe01) { | |||||
| 186 | dpy->lock_meaning = XK_Caps_Lock0xffe5; | |||||
| 187 | break; | |||||
| 188 | } | |||||
| 189 | } | |||||
| 190 | } | |||||
| 191 | /* Now find any Mod<n> modifier acting as the Group or Numlock modifier */ | |||||
| 192 | dpy->mode_switch = 0; | |||||
| 193 | dpy->num_lock = 0; | |||||
| 194 | n *= 4; | |||||
| 195 | for (i = 3*map->max_keypermod; i < n; i++) { | |||||
| 196 | for (j = 0; j < dpy->keysyms_per_keycode; j++) { | |||||
| 197 | sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j); | |||||
| 198 | if (sym == XK_Mode_switch0xff7e) | |||||
| 199 | dpy->mode_switch |= 1 << (i / map->max_keypermod); | |||||
| 200 | if (sym == XK_Num_Lock0xff7f) | |||||
| 201 | dpy->num_lock |= 1 << (i / map->max_keypermod); | |||||
| 202 | } | |||||
| 203 | } | |||||
| 204 | for (p = dpy->key_bindings; p; p = p->next) | |||||
| 205 | ComputeMaskFromKeytrans(dpy, p); | |||||
| 206 | } | |||||
| 207 | ||||||
| 208 | static int | |||||
| 209 | InitModMap( | |||||
| 210 | Display *dpy) | |||||
| 211 | { | |||||
| 212 | register XModifierKeymap *map; | |||||
| 213 | ||||||
| 214 | if (! (map = XGetModifierMapping(dpy))) | |||||
| 215 | return 0; | |||||
| 216 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
| 217 | if (dpy->modifiermap) | |||||
| 218 | XFreeModifiermap(dpy->modifiermap); | |||||
| 219 | dpy->modifiermap = map; | |||||
| 220 | dpy->free_funcs->modifiermap = XFreeModifiermap; | |||||
| 221 | if (dpy->keysyms) | |||||
| 222 | ResetModMap(dpy); | |||||
| 223 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
| 224 | return 1; | |||||
| 225 | } | |||||
| 226 | ||||||
| 227 | int | |||||
| 228 | XRefreshKeyboardMapping_XRefreshKeyboardMapping(register XMappingEvent *event) | |||||
| 229 | { | |||||
| 230 | ||||||
| 231 | if(event->request == MappingKeyboard1) { | |||||
| 232 | /* XXX should really only refresh what is necessary | |||||
| 233 | * for now, make initialize test fail | |||||
| 234 | */ | |||||
| 235 | LockDisplay(event->display)if ((event->display)->lock_fns) (*(event->display)-> lock_fns->lock_display)(event->display); | |||||
| 236 | if (event->display->keysyms) { | |||||
| 237 | Xfree (event->display->keysyms)free((event->display->keysyms)); | |||||
| 238 | event->display->keysyms = NULL((void*)0); | |||||
| 239 | } | |||||
| 240 | UnlockDisplay(event->display)if ((event->display)->lock_fns) (*(event->display)-> lock_fns->unlock_display)(event->display); | |||||
| 241 | } | |||||
| 242 | if(event->request == MappingModifier0) { | |||||
| 243 | LockDisplay(event->display)if ((event->display)->lock_fns) (*(event->display)-> lock_fns->lock_display)(event->display); | |||||
| 244 | if (event->display->modifiermap) { | |||||
| 245 | XFreeModifiermap(event->display->modifiermap); | |||||
| 246 | event->display->modifiermap = NULL((void*)0); | |||||
| 247 | } | |||||
| 248 | UnlockDisplay(event->display)if ((event->display)->lock_fns) (*(event->display)-> lock_fns->unlock_display)(event->display); | |||||
| 249 | /* go ahead and get it now, since initialize test may not fail */ | |||||
| 250 | if (event->display->keysyms) | |||||
| 251 | (void) InitModMap(event->display); | |||||
| 252 | } | |||||
| 253 | return 1; | |||||
| 254 | } | |||||
| 255 | ||||||
| 256 | int | |||||
| 257 | _XKeyInitialize( | |||||
| 258 | Display *dpy) | |||||
| 259 | { | |||||
| 260 | int per, n; | |||||
| 261 | KeySym *keysyms; | |||||
| 262 | ||||||
| 263 | /* | |||||
| 264 | * lets go get the keysyms from the server. | |||||
| 265 | */ | |||||
| 266 | if (!dpy->keysyms) { | |||||
| 267 | n = dpy->max_keycode - dpy->min_keycode + 1; | |||||
| 268 | keysyms = XGetKeyboardMapping (dpy, (KeyCode) dpy->min_keycode, | |||||
| 269 | n, &per); | |||||
| 270 | /* keysyms may be NULL */ | |||||
| 271 | if (! keysyms) return 0; | |||||
| 272 | ||||||
| 273 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
| 274 | ||||||
| 275 | Xfree (dpy->keysyms)free((dpy->keysyms)); | |||||
| 276 | dpy->keysyms = keysyms; | |||||
| 277 | dpy->keysyms_per_keycode = per; | |||||
| 278 | if (dpy->modifiermap) | |||||
| 279 | ResetModMap(dpy); | |||||
| 280 | ||||||
| 281 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
| 282 | } | |||||
| 283 | if (!dpy->modifiermap) | |||||
| 284 | return InitModMap(dpy); | |||||
| 285 | return 1; | |||||
| 286 | } | |||||
| 287 | ||||||
| 288 | static void | |||||
| 289 | UCSConvertCase( register unsigned code, | |||||
| 290 | KeySym *lower, | |||||
| 291 | KeySym *upper ) | |||||
| 292 | { | |||||
| 293 | /* Case conversion for UCS, as in Unicode Data version 4.0.0 */ | |||||
| 294 | /* NB: Only converts simple one-to-one mappings. */ | |||||
| 295 | ||||||
| 296 | /* Tables are used where they take less space than */ | |||||
| 297 | /* the code to work out the mappings. Zero values mean */ | |||||
| 298 | /* undefined code points. */ | |||||
| 299 | ||||||
| 300 | static unsigned short const IPAExt_upper_mapping[] = { /* part only */ | |||||
| 301 | 0x0181, 0x0186, 0x0255, 0x0189, 0x018A, | |||||
| 302 | 0x0258, 0x018F, 0x025A, 0x0190, 0x025C, 0x025D, 0x025E, 0x025F, | |||||
| 303 | 0x0193, 0x0261, 0x0262, 0x0194, 0x0264, 0x0265, 0x0266, 0x0267, | |||||
| 304 | 0x0197, 0x0196, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x019C, | |||||
| 305 | 0x0270, 0x0271, 0x019D, 0x0273, 0x0274, 0x019F, 0x0276, 0x0277, | |||||
| 306 | 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F, | |||||
| 307 | 0x01A6, 0x0281, 0x0282, 0x01A9, 0x0284, 0x0285, 0x0286, 0x0287, | |||||
| 308 | 0x01AE, 0x0289, 0x01B1, 0x01B2, 0x028C, 0x028D, 0x028E, 0x028F, | |||||
| 309 | 0x0290, 0x0291, 0x01B7 | |||||
| 310 | }; | |||||
| 311 | ||||||
| 312 | static unsigned short const LatinExtB_upper_mapping[] = { /* first part only */ | |||||
| 313 | 0x0180, 0x0181, 0x0182, 0x0182, 0x0184, 0x0184, 0x0186, 0x0187, | |||||
| 314 | 0x0187, 0x0189, 0x018A, 0x018B, 0x018B, 0x018D, 0x018E, 0x018F, | |||||
| 315 | 0x0190, 0x0191, 0x0191, 0x0193, 0x0194, 0x01F6, 0x0196, 0x0197, | |||||
| 316 | 0x0198, 0x0198, 0x019A, 0x019B, 0x019C, 0x019D, 0x0220, 0x019F, | |||||
| 317 | 0x01A0, 0x01A0, 0x01A2, 0x01A2, 0x01A4, 0x01A4, 0x01A6, 0x01A7, | |||||
| 318 | 0x01A7, 0x01A9, 0x01AA, 0x01AB, 0x01AC, 0x01AC, 0x01AE, 0x01AF, | |||||
| 319 | 0x01AF, 0x01B1, 0x01B2, 0x01B3, 0x01B3, 0x01B5, 0x01B5, 0x01B7, | |||||
| 320 | 0x01B8, 0x01B8, 0x01BA, 0x01BB, 0x01BC, 0x01BC, 0x01BE, 0x01F7, | |||||
| 321 | 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C4, 0x01C4, 0x01C7, | |||||
| 322 | 0x01C7, 0x01C7, 0x01CA, 0x01CA, 0x01CA | |||||
| 323 | }; | |||||
| 324 | ||||||
| 325 | static unsigned short const LatinExtB_lower_mapping[] = { /* first part only */ | |||||
| 326 | 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188, | |||||
| 327 | 0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259, | |||||
| 328 | 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268, | |||||
| 329 | 0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275, | |||||
| 330 | 0x01A1, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x0280, 0x01A8, | |||||
| 331 | 0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01B0, | |||||
| 332 | 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292, | |||||
| 333 | 0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF, | |||||
| 334 | 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9, | |||||
| 335 | 0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC | |||||
| 336 | }; | |||||
| 337 | ||||||
| 338 | static unsigned short const Greek_upper_mapping[] = { | |||||
| 339 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000, | |||||
| 340 | 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000, | |||||
| 341 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x0386, 0x0387, | |||||
| 342 | 0x0388, 0x0389, 0x038A, 0x0000, 0x038C, 0x0000, 0x038E, 0x038F, | |||||
| 343 | 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, | |||||
| 344 | 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, | |||||
| 345 | 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, | |||||
| 346 | 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x0386, 0x0388, 0x0389, 0x038A, | |||||
| 347 | 0x03B0, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, | |||||
| 348 | 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, | |||||
| 349 | 0x03A0, 0x03A1, 0x03A3, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, | |||||
| 350 | 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x038C, 0x038E, 0x038F, 0x0000, | |||||
| 351 | 0x0392, 0x0398, 0x03D2, 0x03D3, 0x03D4, 0x03A6, 0x03A0, 0x03D7, | |||||
| 352 | 0x03D8, 0x03D8, 0x03DA, 0x03DA, 0x03DC, 0x03DC, 0x03DE, 0x03DE, | |||||
| 353 | 0x03E0, 0x03E0, 0x03E2, 0x03E2, 0x03E4, 0x03E4, 0x03E6, 0x03E6, | |||||
| 354 | 0x03E8, 0x03E8, 0x03EA, 0x03EA, 0x03EC, 0x03EC, 0x03EE, 0x03EE, | |||||
| 355 | 0x039A, 0x03A1, 0x03F9, 0x03F3, 0x03F4, 0x0395, 0x03F6, 0x03F7, | |||||
| 356 | 0x03F7, 0x03F9, 0x03FA, 0x03FA, 0x0000, 0x0000, 0x0000, 0x0000 | |||||
| 357 | }; | |||||
| 358 | ||||||
| 359 | static unsigned short const Greek_lower_mapping[] = { | |||||
| 360 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000, | |||||
| 361 | 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000, | |||||
| 362 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x03AC, 0x0387, | |||||
| 363 | 0x03AD, 0x03AE, 0x03AF, 0x0000, 0x03CC, 0x0000, 0x03CD, 0x03CE, | |||||
| 364 | 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, | |||||
| 365 | 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, | |||||
| 366 | 0x03C0, 0x03C1, 0x0000, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, | |||||
| 367 | 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, | |||||
| 368 | 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, | |||||
| 369 | 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, | |||||
| 370 | 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, | |||||
| 371 | 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000, | |||||
| 372 | 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7, | |||||
| 373 | 0x03D9, 0x03D9, 0x03DB, 0x03DB, 0x03DD, 0x03DD, 0x03DF, 0x03DF, | |||||
| 374 | 0x03E1, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7, | |||||
| 375 | 0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF, | |||||
| 376 | 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03B8, 0x03F5, 0x03F6, 0x03F8, | |||||
| 377 | 0x03F8, 0x03F2, 0x03FB, 0x03FB, 0x0000, 0x0000, 0x0000, 0x0000 | |||||
| 378 | }; | |||||
| 379 | ||||||
| 380 | static unsigned short const GreekExt_lower_mapping[] = { | |||||
| 381 | 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07, | |||||
| 382 | 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07, | |||||
| 383 | 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000, | |||||
| 384 | 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000, | |||||
| 385 | 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27, | |||||
| 386 | 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27, | |||||
| 387 | 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37, | |||||
| 388 | 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37, | |||||
| 389 | 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000, | |||||
| 390 | 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000, | |||||
| 391 | 0x1F50, 0x1F51, 0x1F52, 0x1F53, 0x1F54, 0x1F55, 0x1F56, 0x1F57, | |||||
| 392 | 0x0000, 0x1F51, 0x0000, 0x1F53, 0x0000, 0x1F55, 0x0000, 0x1F57, | |||||
| 393 | 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67, | |||||
| 394 | 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67, | |||||
| 395 | 0x1F70, 0x1F71, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F76, 0x1F77, | |||||
| 396 | 0x1F78, 0x1F79, 0x1F7A, 0x1F7B, 0x1F7C, 0x1F7D, 0x0000, 0x0000, | |||||
| 397 | 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87, | |||||
| 398 | 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87, | |||||
| 399 | 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97, | |||||
| 400 | 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97, | |||||
| 401 | 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7, | |||||
| 402 | 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7, | |||||
| 403 | 0x1FB0, 0x1FB1, 0x1FB2, 0x1FB3, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7, | |||||
| 404 | 0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x1FBD, 0x1FBE, 0x1FBF, | |||||
| 405 | 0x1FC0, 0x1FC1, 0x1FC2, 0x1FC3, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7, | |||||
| 406 | 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x1FCD, 0x1FCE, 0x1FCF, | |||||
| 407 | 0x1FD0, 0x1FD1, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7, | |||||
| 408 | 0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF, | |||||
| 409 | 0x1FE0, 0x1FE1, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FE5, 0x1FE6, 0x1FE7, | |||||
| 410 | 0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x1FED, 0x1FEE, 0x1FEF, | |||||
| 411 | 0x0000, 0x0000, 0x1FF2, 0x1FF3, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7, | |||||
| 412 | 0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x1FFD, 0x1FFE, 0x0000 | |||||
| 413 | }; | |||||
| 414 | ||||||
| 415 | static unsigned short const GreekExt_upper_mapping[] = { | |||||
| 416 | 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F, | |||||
| 417 | 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F, | |||||
| 418 | 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000, | |||||
| 419 | 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000, | |||||
| 420 | 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F, | |||||
| 421 | 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F, | |||||
| 422 | 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F, | |||||
| 423 | 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F, | |||||
| 424 | 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000, | |||||
| 425 | 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000, | |||||
| 426 | 0x1F50, 0x1F59, 0x1F52, 0x1F5B, 0x1F54, 0x1F5D, 0x1F56, 0x1F5F, | |||||
| 427 | 0x0000, 0x1F59, 0x0000, 0x1F5B, 0x0000, 0x1F5D, 0x0000, 0x1F5F, | |||||
| 428 | 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F, | |||||
| 429 | 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F, | |||||
| 430 | 0x1FBA, 0x1FBB, 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FDA, 0x1FDB, | |||||
| 431 | 0x1FF8, 0x1FF9, 0x1FEA, 0x1FEB, 0x1FFA, 0x1FFB, 0x0000, 0x0000, | |||||
| 432 | 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F, | |||||
| 433 | 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F, | |||||
| 434 | 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F, | |||||
| 435 | 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F, | |||||
| 436 | 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF, | |||||
| 437 | 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF, | |||||
| 438 | 0x1FB8, 0x1FB9, 0x1FB2, 0x1FBC, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7, | |||||
| 439 | 0x1FB8, 0x1FB9, 0x1FBA, 0x1FBB, 0x1FBC, 0x1FBD, 0x0399, 0x1FBF, | |||||
| 440 | 0x1FC0, 0x1FC1, 0x1FC2, 0x1FCC, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7, | |||||
| 441 | 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FCC, 0x1FCD, 0x1FCE, 0x1FCF, | |||||
| 442 | 0x1FD8, 0x1FD9, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7, | |||||
| 443 | 0x1FD8, 0x1FD9, 0x1FDA, 0x1FDB, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF, | |||||
| 444 | 0x1FE8, 0x1FE9, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FEC, 0x1FE6, 0x1FE7, | |||||
| 445 | 0x1FE8, 0x1FE9, 0x1FEA, 0x1FEB, 0x1FEC, 0x1FED, 0x1FEE, 0x1FEF, | |||||
| 446 | 0x0000, 0x0000, 0x1FF2, 0x1FFC, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7, | |||||
| 447 | 0x1FF8, 0x1FF9, 0x1FFA, 0x1FFB, 0x1FFC, 0x1FFD, 0x1FFE, 0x0000 | |||||
| 448 | }; | |||||
| 449 | ||||||
| 450 | *lower = code; | |||||
| 451 | *upper = code; | |||||
| 452 | ||||||
| 453 | /* Basic Latin and Latin-1 Supplement, U+0000 to U+00FF */ | |||||
| 454 | if (code <= 0x00ff) { | |||||
| 455 | if (code >= 0x0041 && code <= 0x005a) /* A-Z */ | |||||
| 456 | *lower += 0x20; | |||||
| 457 | else if (code >= 0x0061 && code <= 0x007a) /* a-z */ | |||||
| 458 | *upper -= 0x20; | |||||
| 459 | else if ( (code >= 0x00c0 && code <= 0x00d6) || | |||||
| 460 | (code >= 0x00d8 && code <= 0x00de) ) | |||||
| 461 | *lower += 0x20; | |||||
| 462 | else if ( (code >= 0x00e0 && code <= 0x00f6) || | |||||
| 463 | (code >= 0x00f8 && code <= 0x00fe) ) | |||||
| 464 | *upper -= 0x20; | |||||
| 465 | else if (code == 0x00ff) /* y with diaeresis */ | |||||
| 466 | *upper = 0x0178; | |||||
| 467 | else if (code == 0x00b5) /* micro sign */ | |||||
| 468 | *upper = 0x039c; | |||||
| 469 | return; | |||||
| 470 | } | |||||
| 471 | ||||||
| 472 | /* Latin Extended-A, U+0100 to U+017F */ | |||||
| 473 | if (code >= 0x0100 && code <= 0x017f) { | |||||
| 474 | if ( (code >= 0x0100 && code <= 0x012f) || | |||||
| 475 | (code >= 0x0132 && code <= 0x0137) || | |||||
| 476 | (code >= 0x014a && code <= 0x0177) ) { | |||||
| 477 | *upper = code & ~1; | |||||
| 478 | *lower = code | 1; | |||||
| 479 | } | |||||
| 480 | else if ( (code >= 0x0139 && code <= 0x0148) || | |||||
| 481 | (code >= 0x0179 && code <= 0x017e) ) { | |||||
| 482 | if (code & 1) | |||||
| 483 | *lower += 1; | |||||
| 484 | else | |||||
| 485 | *upper -= 1; | |||||
| 486 | } | |||||
| 487 | else if (code == 0x0130) | |||||
| 488 | *lower = 0x0069; | |||||
| 489 | else if (code == 0x0131) | |||||
| 490 | *upper = 0x0049; | |||||
| 491 | else if (code == 0x0178) | |||||
| 492 | *lower = 0x00ff; | |||||
| 493 | else if (code == 0x017f) | |||||
| 494 | *upper = 0x0053; | |||||
| 495 | return; | |||||
| 496 | } | |||||
| 497 | ||||||
| 498 | /* Latin Extended-B, U+0180 to U+024F */ | |||||
| 499 | if (code >= 0x0180 && code <= 0x024f) { | |||||
| 500 | if (code >= 0x01cd && code <= 0x01dc) { | |||||
| 501 | if (code & 1) | |||||
| 502 | *lower += 1; | |||||
| 503 | else | |||||
| 504 | *upper -= 1; | |||||
| 505 | } | |||||
| 506 | else if ( (code >= 0x01de && code <= 0x01ef) || | |||||
| 507 | (code >= 0x01f4 && code <= 0x01f5) || | |||||
| 508 | (code >= 0x01f8 && code <= 0x021f) || | |||||
| 509 | (code >= 0x0222 && code <= 0x0233) ) { | |||||
| 510 | *lower |= 1; | |||||
| 511 | *upper &= ~1; | |||||
| 512 | } | |||||
| 513 | else if (code >= 0x0180 && code <= 0x01cc) { | |||||
| 514 | *lower = LatinExtB_lower_mapping[code - 0x0180]; | |||||
| 515 | *upper = LatinExtB_upper_mapping[code - 0x0180]; | |||||
| 516 | } | |||||
| 517 | else if (code == 0x01dd) | |||||
| 518 | *upper = 0x018e; | |||||
| 519 | else if (code == 0x01f1 || code == 0x01f2) { | |||||
| 520 | *lower = 0x01f3; | |||||
| 521 | *upper = 0x01f1; | |||||
| 522 | } | |||||
| 523 | else if (code == 0x01f3) | |||||
| 524 | *upper = 0x01f1; | |||||
| 525 | else if (code == 0x01f6) | |||||
| 526 | *lower = 0x0195; | |||||
| 527 | else if (code == 0x01f7) | |||||
| 528 | *lower = 0x01bf; | |||||
| 529 | else if (code == 0x0220) | |||||
| 530 | *lower = 0x019e; | |||||
| 531 | return; | |||||
| 532 | } | |||||
| 533 | ||||||
| 534 | /* IPA Extensions, U+0250 to U+02AF */ | |||||
| 535 | if (code >= 0x0253 && code <= 0x0292) { | |||||
| 536 | *upper = IPAExt_upper_mapping[code - 0x0253]; | |||||
| 537 | } | |||||
| 538 | ||||||
| 539 | /* Combining Diacritical Marks, U+0300 to U+036F */ | |||||
| 540 | if (code == 0x0345) { | |||||
| 541 | *upper = 0x0399; | |||||
| 542 | } | |||||
| 543 | ||||||
| 544 | /* Greek and Coptic, U+0370 to U+03FF */ | |||||
| 545 | if (code >= 0x0370 && code <= 0x03ff) { | |||||
| 546 | *lower = Greek_lower_mapping[code - 0x0370]; | |||||
| 547 | *upper = Greek_upper_mapping[code - 0x0370]; | |||||
| 548 | if (*upper == 0) | |||||
| 549 | *upper = code; | |||||
| 550 | if (*lower == 0) | |||||
| 551 | *lower = code; | |||||
| 552 | } | |||||
| 553 | ||||||
| 554 | /* Cyrillic and Cyrillic Supplementary, U+0400 to U+052F */ | |||||
| 555 | if ( (code >= 0x0400 && code <= 0x04ff) || | |||||
| 556 | (code >= 0x0500 && code <= 0x052f) ) { | |||||
| 557 | if (code >= 0x0400 && code <= 0x040f) | |||||
| 558 | *lower += 0x50; | |||||
| 559 | else if (code >= 0x0410 && code <= 0x042f) | |||||
| 560 | *lower += 0x20; | |||||
| 561 | else if (code >= 0x0430 && code <= 0x044f) | |||||
| 562 | *upper -= 0x20; | |||||
| 563 | else if (code >= 0x0450 && code <= 0x045f) | |||||
| 564 | *upper -= 0x50; | |||||
| 565 | else if ( (code >= 0x0460 && code <= 0x0481) || | |||||
| 566 | (code >= 0x048a && code <= 0x04bf) || | |||||
| 567 | (code >= 0x04d0 && code <= 0x04f5) || | |||||
| 568 | (code >= 0x04f8 && code <= 0x04f9) || | |||||
| 569 | (code >= 0x0500 && code <= 0x050f) ) { | |||||
| 570 | *upper &= ~1; | |||||
| 571 | *lower |= 1; | |||||
| 572 | } | |||||
| 573 | else if (code >= 0x04c1 && code <= 0x04ce) { | |||||
| 574 | if (code & 1) | |||||
| 575 | *lower += 1; | |||||
| 576 | else | |||||
| 577 | *upper -= 1; | |||||
| 578 | } | |||||
| 579 | } | |||||
| 580 | ||||||
| 581 | /* Armenian, U+0530 to U+058F */ | |||||
| 582 | if (code >= 0x0530 && code <= 0x058f) { | |||||
| 583 | if (code >= 0x0531 && code <= 0x0556) | |||||
| 584 | *lower += 0x30; | |||||
| 585 | else if (code >=0x0561 && code <= 0x0586) | |||||
| 586 | *upper -= 0x30; | |||||
| 587 | } | |||||
| 588 | ||||||
| 589 | /* Latin Extended Additional, U+1E00 to U+1EFF */ | |||||
| 590 | if (code >= 0x1e00 && code <= 0x1eff) { | |||||
| 591 | if ( (code >= 0x1e00 && code <= 0x1e95) || | |||||
| 592 | (code >= 0x1ea0 && code <= 0x1ef9) ) { | |||||
| 593 | *upper &= ~1; | |||||
| 594 | *lower |= 1; | |||||
| 595 | } | |||||
| 596 | else if (code == 0x1e9b) | |||||
| 597 | *upper = 0x1e60; | |||||
| 598 | } | |||||
| 599 | ||||||
| 600 | /* Greek Extended, U+1F00 to U+1FFF */ | |||||
| 601 | if (code >= 0x1f00 && code <= 0x1fff) { | |||||
| 602 | *lower = GreekExt_lower_mapping[code - 0x1f00]; | |||||
| 603 | *upper = GreekExt_upper_mapping[code - 0x1f00]; | |||||
| 604 | if (*upper == 0) | |||||
| 605 | *upper = code; | |||||
| 606 | if (*lower == 0) | |||||
| 607 | *lower = code; | |||||
| 608 | } | |||||
| 609 | ||||||
| 610 | /* Letterlike Symbols, U+2100 to U+214F */ | |||||
| 611 | if (code >= 0x2100 && code <= 0x214f) { | |||||
| 612 | switch (code) { | |||||
| 613 | case 0x2126: *lower = 0x03c9; break; | |||||
| 614 | case 0x212a: *lower = 0x006b; break; | |||||
| 615 | case 0x212b: *lower = 0x00e5; break; | |||||
| 616 | } | |||||
| 617 | } | |||||
| 618 | /* Number Forms, U+2150 to U+218F */ | |||||
| 619 | else if (code >= 0x2160 && code <= 0x216f) | |||||
| 620 | *lower += 0x10; | |||||
| 621 | else if (code >= 0x2170 && code <= 0x217f) | |||||
| 622 | *upper -= 0x10; | |||||
| 623 | /* Enclosed Alphanumerics, U+2460 to U+24FF */ | |||||
| 624 | else if (code >= 0x24b6 && code <= 0x24cf) | |||||
| 625 | *lower += 0x1a; | |||||
| 626 | else if (code >= 0x24d0 && code <= 0x24e9) | |||||
| 627 | *upper -= 0x1a; | |||||
| 628 | /* Halfwidth and Fullwidth Forms, U+FF00 to U+FFEF */ | |||||
| 629 | else if (code >= 0xff21 && code <= 0xff3a) | |||||
| 630 | *lower += 0x20; | |||||
| 631 | else if (code >= 0xff41 && code <= 0xff5a) | |||||
| 632 | *upper -= 0x20; | |||||
| 633 | /* Deseret, U+10400 to U+104FF */ | |||||
| 634 | else if (code >= 0x10400 && code <= 0x10427) | |||||
| 635 | *lower += 0x28; | |||||
| 636 | else if (code >= 0x10428 && code <= 0x1044f) | |||||
| 637 | *upper -= 0x28; | |||||
| 638 | } | |||||
| 639 | ||||||
| 640 | void | |||||
| 641 | XConvertCase( | |||||
| 642 | register KeySym sym, | |||||
| 643 | KeySym *lower, | |||||
| 644 | KeySym *upper) | |||||
| 645 | { | |||||
| 646 | /* Latin 1 keysym */ | |||||
| 647 | if (sym < 0x100) { | |||||
| 648 | UCSConvertCase(sym, lower, upper); | |||||
| 649 | return; | |||||
| 650 | } | |||||
| 651 | ||||||
| 652 | /* Unicode keysym */ | |||||
| 653 | if ((sym & 0xff000000) == 0x01000000) { | |||||
| 654 | UCSConvertCase((sym & 0x00ffffff), lower, upper); | |||||
| 655 | *upper |= 0x01000000; | |||||
| 656 | *lower |= 0x01000000; | |||||
| 657 | return; | |||||
| 658 | } | |||||
| 659 | ||||||
| 660 | /* Legacy keysym */ | |||||
| 661 | ||||||
| 662 | *lower = sym; | |||||
| 663 | *upper = sym; | |||||
| 664 | ||||||
| 665 | switch(sym >> 8) { | |||||
| 666 | case 1: /* Latin 2 */ | |||||
| 667 | /* Assume the KeySym is a legal value (ignore discontinuities) */ | |||||
| 668 | if (sym == XK_Aogonek0x01a1) | |||||
| 669 | *lower = XK_aogonek0x01b1; | |||||
| 670 | else if (sym >= XK_Lstroke0x01a3 && sym <= XK_Sacute0x01a6) | |||||
| 671 | *lower += (XK_lstroke0x01b3 - XK_Lstroke0x01a3); | |||||
| 672 | else if (sym >= XK_Scaron0x01a9 && sym <= XK_Zacute0x01ac) | |||||
| 673 | *lower += (XK_scaron0x01b9 - XK_Scaron0x01a9); | |||||
| 674 | else if (sym >= XK_Zcaron0x01ae && sym <= XK_Zabovedot0x01af) | |||||
| 675 | *lower += (XK_zcaron0x01be - XK_Zcaron0x01ae); | |||||
| 676 | else if (sym == XK_aogonek0x01b1) | |||||
| 677 | *upper = XK_Aogonek0x01a1; | |||||
| 678 | else if (sym >= XK_lstroke0x01b3 && sym <= XK_sacute0x01b6) | |||||
| 679 | *upper -= (XK_lstroke0x01b3 - XK_Lstroke0x01a3); | |||||
| 680 | else if (sym >= XK_scaron0x01b9 && sym <= XK_zacute0x01bc) | |||||
| 681 | *upper -= (XK_scaron0x01b9 - XK_Scaron0x01a9); | |||||
| 682 | else if (sym >= XK_zcaron0x01be && sym <= XK_zabovedot0x01bf) | |||||
| 683 | *upper -= (XK_zcaron0x01be - XK_Zcaron0x01ae); | |||||
| 684 | else if (sym >= XK_Racute0x01c0 && sym <= XK_Tcedilla0x01de) | |||||
| 685 | *lower += (XK_racute0x01e0 - XK_Racute0x01c0); | |||||
| 686 | else if (sym >= XK_racute0x01e0 && sym <= XK_tcedilla0x01fe) | |||||
| 687 | *upper -= (XK_racute0x01e0 - XK_Racute0x01c0); | |||||
| 688 | break; | |||||
| 689 | case 2: /* Latin 3 */ | |||||
| 690 | /* Assume the KeySym is a legal value (ignore discontinuities) */ | |||||
| 691 | if (sym >= XK_Hstroke0x02a1 && sym <= XK_Hcircumflex0x02a6) | |||||
| 692 | *lower += (XK_hstroke0x02b1 - XK_Hstroke0x02a1); | |||||
| 693 | else if (sym >= XK_Gbreve0x02ab && sym <= XK_Jcircumflex0x02ac) | |||||
| 694 | *lower += (XK_gbreve0x02bb - XK_Gbreve0x02ab); | |||||
| 695 | else if (sym >= XK_hstroke0x02b1 && sym <= XK_hcircumflex0x02b6) | |||||
| 696 | *upper -= (XK_hstroke0x02b1 - XK_Hstroke0x02a1); | |||||
| 697 | else if (sym >= XK_gbreve0x02bb && sym <= XK_jcircumflex0x02bc) | |||||
| 698 | *upper -= (XK_gbreve0x02bb - XK_Gbreve0x02ab); | |||||
| 699 | else if (sym >= XK_Cabovedot0x02c5 && sym <= XK_Scircumflex0x02de) | |||||
| 700 | *lower += (XK_cabovedot0x02e5 - XK_Cabovedot0x02c5); | |||||
| 701 | else if (sym >= XK_cabovedot0x02e5 && sym <= XK_scircumflex0x02fe) | |||||
| 702 | *upper -= (XK_cabovedot0x02e5 - XK_Cabovedot0x02c5); | |||||
| 703 | break; | |||||
| 704 | case 3: /* Latin 4 */ | |||||
| 705 | /* Assume the KeySym is a legal value (ignore discontinuities) */ | |||||
| 706 | if (sym >= XK_Rcedilla0x03a3 && sym <= XK_Tslash0x03ac) | |||||
| 707 | *lower += (XK_rcedilla0x03b3 - XK_Rcedilla0x03a3); | |||||
| 708 | else if (sym >= XK_rcedilla0x03b3 && sym <= XK_tslash0x03bc) | |||||
| 709 | *upper -= (XK_rcedilla0x03b3 - XK_Rcedilla0x03a3); | |||||
| 710 | else if (sym == XK_ENG0x03bd) | |||||
| 711 | *lower = XK_eng0x03bf; | |||||
| 712 | else if (sym == XK_eng0x03bf) | |||||
| 713 | *upper = XK_ENG0x03bd; | |||||
| 714 | else if (sym >= XK_Amacron0x03c0 && sym <= XK_Umacron0x03de) | |||||
| 715 | *lower += (XK_amacron0x03e0 - XK_Amacron0x03c0); | |||||
| 716 | else if (sym >= XK_amacron0x03e0 && sym <= XK_umacron0x03fe) | |||||
| 717 | *upper -= (XK_amacron0x03e0 - XK_Amacron0x03c0); | |||||
| 718 | break; | |||||
| 719 | case 6: /* Cyrillic */ | |||||
| 720 | /* Assume the KeySym is a legal value (ignore discontinuities) */ | |||||
| 721 | if (sym >= XK_Serbian_DJE0x06b1 && sym <= XK_Serbian_DZE0x06bf) | |||||
| 722 | *lower -= (XK_Serbian_DJE0x06b1 - XK_Serbian_dje0x06a1); | |||||
| 723 | else if (sym >= XK_Serbian_dje0x06a1 && sym <= XK_Serbian_dze0x06af) | |||||
| 724 | *upper += (XK_Serbian_DJE0x06b1 - XK_Serbian_dje0x06a1); | |||||
| 725 | else if (sym >= XK_Cyrillic_YU0x06e0 && sym <= XK_Cyrillic_HARDSIGN0x06ff) | |||||
| 726 | *lower -= (XK_Cyrillic_YU0x06e0 - XK_Cyrillic_yu0x06c0); | |||||
| 727 | else if (sym >= XK_Cyrillic_yu0x06c0 && sym <= XK_Cyrillic_hardsign0x06df) | |||||
| 728 | *upper += (XK_Cyrillic_YU0x06e0 - XK_Cyrillic_yu0x06c0); | |||||
| 729 | break; | |||||
| 730 | case 7: /* Greek */ | |||||
| 731 | /* Assume the KeySym is a legal value (ignore discontinuities) */ | |||||
| 732 | if (sym >= XK_Greek_ALPHAaccent0x07a1 && sym <= XK_Greek_OMEGAaccent0x07ab) | |||||
| 733 | *lower += (XK_Greek_alphaaccent0x07b1 - XK_Greek_ALPHAaccent0x07a1); | |||||
| 734 | else if (sym >= XK_Greek_alphaaccent0x07b1 && sym <= XK_Greek_omegaaccent0x07bb && | |||||
| 735 | sym != XK_Greek_iotaaccentdieresis0x07b6 && | |||||
| 736 | sym != XK_Greek_upsilonaccentdieresis0x07ba) | |||||
| 737 | *upper -= (XK_Greek_alphaaccent0x07b1 - XK_Greek_ALPHAaccent0x07a1); | |||||
| 738 | else if (sym >= XK_Greek_ALPHA0x07c1 && sym <= XK_Greek_OMEGA0x07d9) | |||||
| 739 | *lower += (XK_Greek_alpha0x07e1 - XK_Greek_ALPHA0x07c1); | |||||
| 740 | else if (sym >= XK_Greek_alpha0x07e1 && sym <= XK_Greek_omega0x07f9 && | |||||
| 741 | sym != XK_Greek_finalsmallsigma0x07f3) | |||||
| 742 | *upper -= (XK_Greek_alpha0x07e1 - XK_Greek_ALPHA0x07c1); | |||||
| 743 | break; | |||||
| 744 | case 0x13: /* Latin 9 */ | |||||
| 745 | if (sym == XK_OE0x13bc) | |||||
| 746 | *lower = XK_oe0x13bd; | |||||
| 747 | else if (sym == XK_oe0x13bd) | |||||
| 748 | *upper = XK_OE0x13bc; | |||||
| 749 | else if (sym == XK_Ydiaeresis0x13be) | |||||
| 750 | *lower = XK_ydiaeresis0x00ff; | |||||
| 751 | break; | |||||
| 752 | } | |||||
| 753 | } | |||||
| 754 | ||||||
| 755 | int | |||||
| 756 | _XTranslateKey( register Display *dpy, | |||||
| 757 | KeyCode keycode, | |||||
| 758 | register unsigned int modifiers, | |||||
| 759 | unsigned int *modifiers_return, | |||||
| 760 | KeySym *keysym_return) | |||||
| 761 | { | |||||
| 762 | int per; | |||||
| 763 | register KeySym *syms; | |||||
| 764 | KeySym sym, lsym, usym; | |||||
| 765 | ||||||
| 766 | if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) | |||||
| 767 | return 0; | |||||
| 768 | *modifiers_return = ((ShiftMask(1<<0)|LockMask(1<<1)) | |||||
| 769 | | dpy->mode_switch | dpy->num_lock); | |||||
| 770 | if (((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode)) | |||||
| 771 | { | |||||
| 772 | *keysym_return = NoSymbol0L; | |||||
| 773 | return 1; | |||||
| 774 | } | |||||
| 775 | per = dpy->keysyms_per_keycode; | |||||
| 776 | syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per]; | |||||
| 777 | while ((per > 2) && (syms[per - 1] == NoSymbol0L)) | |||||
| 778 | per--; | |||||
| 779 | if ((per > 2) && (modifiers & dpy->mode_switch)) { | |||||
| 780 | syms += 2; | |||||
| 781 | per -= 2; | |||||
| 782 | } | |||||
| 783 | if ((modifiers & dpy->num_lock) && | |||||
| 784 | (per > 1 && (IsKeypadKey(syms[1])(((KeySym)(syms[1]) >= 0xff80) && ((KeySym)(syms[1 ]) <= 0xffbd)) || IsPrivateKeypadKey(syms[1])(((KeySym)(syms[1]) >= 0x11000000) && ((KeySym)(syms [1]) <= 0x1100FFFF))))) { | |||||
| 785 | if ((modifiers & ShiftMask(1<<0)) || | |||||
| 786 | ((modifiers & LockMask(1<<1)) && (dpy->lock_meaning == XK_Shift_Lock0xffe6))) | |||||
| 787 | *keysym_return = syms[0]; | |||||
| 788 | else | |||||
| 789 | *keysym_return = syms[1]; | |||||
| 790 | } else if (!(modifiers & ShiftMask(1<<0)) && | |||||
| 791 | (!(modifiers & LockMask(1<<1)) || (dpy->lock_meaning == NoSymbol0L))) { | |||||
| 792 | if ((per == 1) || (syms[1] == NoSymbol0L)) | |||||
| 793 | XConvertCase(syms[0], keysym_return, &usym); | |||||
| 794 | else | |||||
| 795 | *keysym_return = syms[0]; | |||||
| 796 | } else if (!(modifiers & LockMask(1<<1)) || | |||||
| 797 | (dpy->lock_meaning != XK_Caps_Lock0xffe5)) { | |||||
| 798 | if ((per == 1) || ((usym = syms[1]) == NoSymbol0L)) | |||||
| 799 | XConvertCase(syms[0], &lsym, &usym); | |||||
| 800 | *keysym_return = usym; | |||||
| 801 | } else { | |||||
| 802 | if ((per == 1) || ((sym = syms[1]) == NoSymbol0L)) | |||||
| 803 | sym = syms[0]; | |||||
| 804 | XConvertCase(sym, &lsym, &usym); | |||||
| 805 | if (!(modifiers & ShiftMask(1<<0)) && (sym != syms[0]) && | |||||
| 806 | ((sym != usym) || (lsym == usym))) | |||||
| 807 | XConvertCase(syms[0], &lsym, &usym); | |||||
| 808 | *keysym_return = usym; | |||||
| 809 | } | |||||
| 810 | if (*keysym_return == XK_VoidSymbol0xffffff) | |||||
| 811 | *keysym_return = NoSymbol0L; | |||||
| 812 | return 1; | |||||
| 813 | } | |||||
| 814 | ||||||
| 815 | int | |||||
| 816 | _XTranslateKeySym( | |||||
| 817 | Display *dpy, | |||||
| 818 | register KeySym symbol, | |||||
| 819 | unsigned int modifiers, | |||||
| 820 | char *buffer, | |||||
| 821 | int nbytes) | |||||
| 822 | { | |||||
| 823 | register struct _XKeytrans *p; | |||||
| 824 | int length; | |||||
| 825 | unsigned long hiBytes; | |||||
| 826 | register unsigned char c; | |||||
| 827 | ||||||
| 828 | if (!symbol) | |||||
| 829 | return 0; | |||||
| 830 | /* see if symbol rebound, if so, return that string. */ | |||||
| 831 | for (p = dpy->key_bindings; p; p = p->next) { | |||||
| 832 | if (((modifiers & AllMods((1<<0)|(1<<1)|(1<<2)| (1<<3)|(1<< 4)|(1<<5)|(1<<6)|(1<<7))) == p->state) && (symbol == p->key)) { | |||||
| 833 | length = p->len; | |||||
| 834 | if (length > nbytes) length = nbytes; | |||||
| 835 | memcpy (buffer, p->string, length)__builtin___memcpy_chk (buffer, p->string, length, __builtin_object_size (buffer, 0)); | |||||
| 836 | return length; | |||||
| 837 | } | |||||
| 838 | } | |||||
| 839 | /* try to convert to Latin-1, handling control */ | |||||
| 840 | hiBytes = symbol >> 8; | |||||
| 841 | if (!(nbytes && | |||||
| 842 | ((hiBytes == 0) || | |||||
| 843 | ((hiBytes == 0xFF) && | |||||
| 844 | (((symbol >= XK_BackSpace0xff08) && (symbol <= XK_Clear0xff0b)) || | |||||
| 845 | (symbol == XK_Return0xff0d) || | |||||
| 846 | (symbol == XK_Escape0xff1b) || | |||||
| 847 | (symbol == XK_KP_Space0xff80) || | |||||
| 848 | (symbol == XK_KP_Tab0xff89) || | |||||
| 849 | (symbol == XK_KP_Enter0xff8d) || | |||||
| 850 | ((symbol >= XK_KP_Multiply0xffaa) && (symbol <= XK_KP_90xffb9)) || | |||||
| 851 | (symbol == XK_KP_Equal0xffbd) || | |||||
| 852 | (symbol == XK_Delete0xffff)))))) | |||||
| 853 | return 0; | |||||
| 854 | ||||||
| 855 | /* if X keysym, convert to ascii by grabbing low 7 bits */ | |||||
| 856 | if (symbol == XK_KP_Space0xff80) | |||||
| 857 | c = XK_space0x0020 & 0x7F; /* patch encoding botch */ | |||||
| 858 | else if (hiBytes == 0xFF) | |||||
| 859 | c = symbol & 0x7F; | |||||
| 860 | else | |||||
| 861 | c = symbol & 0xFF; | |||||
| 862 | /* only apply Control key if it makes sense, else ignore it */ | |||||
| 863 | if (modifiers & ControlMask(1<<2)) { | |||||
| 864 | if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F; | |||||
| 865 | else if (c == '2') c = '\000'; | |||||
| 866 | else if (c >= '3' && c <= '7') c -= ('3' - '\033'); | |||||
| 867 | else if (c == '8') c = '\177'; | |||||
| 868 | else if (c == '/') c = '_' & 0x1F; | |||||
| 869 | } | |||||
| 870 | buffer[0] = c; | |||||
| 871 | return 1; | |||||
| 872 | } | |||||
| 873 | ||||||
| 874 | /*ARGSUSED*/ | |||||
| 875 | int | |||||
| 876 | XLookupString_XLookupString ( | |||||
| 877 | register XKeyEvent *event, | |||||
| 878 | char *buffer, /* buffer */ | |||||
| 879 | int nbytes, /* space in buffer for characters */ | |||||
| 880 | KeySym *keysym, | |||||
| 881 | XComposeStatus *status) /* not implemented */ | |||||
| 882 | { | |||||
| 883 | unsigned int modifiers; | |||||
| 884 | KeySym symbol; | |||||
| 885 | ||||||
| 886 | if (! _XTranslateKey(event->display, event->keycode, event->state, | |||||
| 887 | &modifiers, &symbol)) | |||||
| 888 | return 0; | |||||
| 889 | ||||||
| 890 | if (keysym) | |||||
| 891 | *keysym = symbol; | |||||
| 892 | /* arguable whether to use (event->state & ~modifiers) here */ | |||||
| 893 | return _XTranslateKeySym(event->display, symbol, event->state, | |||||
| 894 | buffer, nbytes); | |||||
| 895 | } | |||||
| 896 | ||||||
| 897 | static void | |||||
| 898 | _XFreeKeyBindings( | |||||
| 899 | Display *dpy) | |||||
| 900 | { | |||||
| 901 | register struct _XKeytrans *p, *np; | |||||
| 902 | ||||||
| 903 | for (p = dpy->key_bindings; p; p = np) { | |||||
| 904 | np = p->next; | |||||
| 905 | Xfree(p->string)free((p->string)); | |||||
| 906 | Xfree(p->modifiers)free((p->modifiers)); | |||||
| 907 | Xfree(p)free((p)); | |||||
| 908 | } | |||||
| 909 | } | |||||
| 910 | ||||||
| 911 | int | |||||
| 912 | XRebindKeysym ( | |||||
| 913 | Display *dpy, | |||||
| 914 | KeySym keysym, | |||||
| 915 | KeySym *mlist, | |||||
| 916 | int nm, /* number of modifiers in mlist */ | |||||
| 917 | _Xconstconst unsigned char *str, | |||||
| 918 | int nbytes) | |||||
| 919 | { | |||||
| 920 | register struct _XKeytrans *tmp, *p; | |||||
| 921 | int nb; | |||||
| 922 | ||||||
| 923 | if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) | |||||
| 924 | return 0; | |||||
| 925 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | |||||
| 926 | tmp = dpy->key_bindings; | |||||
| 927 | nb = sizeof(KeySym) * nm; | |||||
| 928 | ||||||
| 929 | if ((! (p = Xcalloc( 1, sizeof(struct _XKeytrans))calloc(((1) == 0 ? 1 : (1)), (sizeof(struct _XKeytrans))))) || | |||||
| ||||||
| 930 | ((! (p->string = Xmalloc(nbytes)malloc(((nbytes) == 0 ? 1 : (nbytes))))) && (nbytes > 0)) || | |||||
| 931 | ((! (p->modifiers = Xmalloc(nb)malloc(((nb) == 0 ? 1 : (nb))))) && (nb > 0))) { | |||||
| 932 | if (p) { | |||||
| 933 | Xfree(p->string)free((p->string)); | |||||
| 934 | Xfree(p->modifiers)free((p->modifiers)); | |||||
| 935 | Xfree(p)free((p)); | |||||
| 936 | } | |||||
| 937 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
| 938 | return 0; | |||||
| 939 | } | |||||
| 940 | ||||||
| 941 | dpy->key_bindings = p; | |||||
| 942 | dpy->free_funcs->key_bindings = _XFreeKeyBindings; | |||||
| 943 | p->next = tmp; /* chain onto list */ | |||||
| 944 | memcpy (p->string, str, nbytes)__builtin___memcpy_chk (p->string, str, nbytes, __builtin_object_size (p->string, 0)); | |||||
| ||||||
| 945 | p->len = nbytes; | |||||
| 946 | memcpy ((char *) p->modifiers, (char *) mlist, nb)__builtin___memcpy_chk ((char *) p->modifiers, (char *) mlist , nb, __builtin_object_size ((char *) p->modifiers, 0)); | |||||
| 947 | p->key = keysym; | |||||
| 948 | p->mlen = nm; | |||||
| 949 | ComputeMaskFromKeytrans(dpy, p); | |||||
| 950 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | |||||
| 951 | return 0; | |||||
| 952 | } | |||||
| 953 | ||||||
| 954 | unsigned | |||||
| 955 | _XKeysymToModifiers( | |||||
| 956 | Display *dpy, | |||||
| 957 | KeySym ks) | |||||
| 958 | { | |||||
| 959 | CARD8 code,mods; | |||||
| 960 | register KeySym *kmax; | |||||
| 961 | register KeySym *k; | |||||
| 962 | register XModifierKeymap *m; | |||||
| 963 | ||||||
| 964 | if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) | |||||
| 965 | return 0; | |||||
| 966 | kmax = dpy->keysyms + | |||||
| 967 | (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode; | |||||
| 968 | k = dpy->keysyms; | |||||
| 969 | m = dpy->modifiermap; | |||||
| 970 | mods= 0; | |||||
| 971 | while (k<kmax) { | |||||
| 972 | if (*k == ks ) { | |||||
| 973 | register int j = m->max_keypermod<<3; | |||||
| 974 | ||||||
| 975 | code=(((k-dpy->keysyms)/dpy->keysyms_per_keycode)+dpy->min_keycode); | |||||
| 976 | ||||||
| 977 | while (--j >= 0) { | |||||
| 978 | if (code == m->modifiermap[j]) | |||||
| 979 | mods|= (1<<(j/m->max_keypermod)); | |||||
| 980 | } | |||||
| 981 | } | |||||
| 982 | k++; | |||||
| 983 | } | |||||
| 984 | return mods; | |||||
| 985 | } | |||||
| 986 | ||||||
| 987 | /* | |||||
| 988 | * given a list of modifiers, computes the mask necessary for later matching. | |||||
| 989 | * This routine must lookup the key in the Keymap and then search to see | |||||
| 990 | * what modifier it is bound to, if any. Sets the AnyModifier bit if it | |||||
| 991 | * can't map some keysym to a modifier. | |||||
| 992 | */ | |||||
| 993 | static void | |||||
| 994 | ComputeMaskFromKeytrans( | |||||
| 995 | Display *dpy, | |||||
| 996 | register struct _XKeytrans *p) | |||||
| 997 | { | |||||
| 998 | register int i; | |||||
| 999 | ||||||
| 1000 | p->state = AnyModifier(1<<15); | |||||
| 1001 | for (i = 0; i < p->mlen; i++) { | |||||
| 1002 | p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]); | |||||
| 1003 | } | |||||
| 1004 | p->state &= AllMods((1<<0)|(1<<1)|(1<<2)| (1<<3)|(1<< 4)|(1<<5)|(1<<6)|(1<<7)); | |||||
| 1005 | } |