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