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