Sync usage with man page.
[netbsd-mini2440.git] / x11 / tools / xkbcomp / xkbcomp-KeyBind.c
blob5a301d0eea8efa4a1fd506f37e7c34f586fcd3c3
1 /* $NetBSD$ */
3 /* $Xorg: KeyBind.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */
4 /*
6 Copyright 1985, 1987, 1998 The Open Group
8 Permission to use, copy, modify, distribute, and sell this software and its
9 documentation for any purpose is hereby granted without fee, provided that
10 the above copyright notice appear in all copies and that both that
11 copyright notice and this permission notice appear in supporting
12 documentation.
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Except as contained in this notice, the name of The Open Group shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from The Open Group.
29 /* $XFree86: xc/lib/X11/KeyBind.c,v 1.5 2001/12/14 19:54:02 dawes Exp $ */
31 /* Beware, here be monsters (still under construction... - JG */
33 #define NEED_EVENTS
34 #include <X11/Xlibint.h>
35 #include <X11/Xutil.h>
36 #define XK_MISCELLANY
37 #define XK_LATIN1
38 #define XK_LATIN2
39 #define XK_LATIN3
40 #define XK_LATIN4
41 #define XK_CYRILLIC
42 #define XK_GREEK
43 #define XK_ARMENIAN
44 #define XK_XKB_KEYS
45 #include <X11/keysymdef.h>
46 #include <stdio.h>
48 #include "XKBlib.h"
50 #ifdef USE_OWN_COMPOSE
51 #include "imComp.h"
53 #endif
55 #ifdef XKB
56 #define XKeycodeToKeysym _XKeycodeToKeysym
57 #define XKeysymToKeycode _XKeysymToKeycode
58 #define XLookupKeysym _XLookupKeysym
59 #define XRefreshKeyboardMapping _XRefreshKeyboardMapping
60 #define XLookupString _XLookupString
61 /* XKBBind.c */
62 #else
63 #define XkbKeysymToModifiers _XKeysymToModifiers
64 #endif
66 #define AllMods (ShiftMask|LockMask|ControlMask| \
67 Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)
69 #if 0 /* { */
71 static void ComputeMaskFromKeytrans();
72 int _XKeyInitialize();
74 struct _XKeytrans {
75 struct _XKeytrans *next;/* next on list */
76 char *string; /* string to return when the time comes */
77 int len; /* length of string (since NULL is legit)*/
78 KeySym key; /* keysym rebound */
79 unsigned int state; /* modifier state */
80 KeySym *modifiers; /* modifier keysyms you want */
81 int mlen; /* length of modifier list */
84 static KeySym
85 #if NeedFunctionPrototypes
86 KeyCodetoKeySym(register Display *dpy, KeyCode keycode, int col)
87 #else
88 KeyCodetoKeySym(dpy, keycode, col)
89 register Display *dpy;
90 KeyCode keycode;
91 int col;
92 #endif
94 register int per = dpy->keysyms_per_keycode;
95 register KeySym *syms;
96 KeySym lsym, usym;
98 if ((col < 0) || ((col >= per) && (col > 3)) ||
99 ((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
100 return NoSymbol;
102 syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
103 if (col < 4) {
104 if (col > 1) {
105 while ((per > 2) && (syms[per - 1] == NoSymbol))
106 per--;
107 if (per < 3)
108 col -= 2;
110 if ((per <= (col|1)) || (syms[col|1] == NoSymbol)) {
111 XConvertCase(syms[col&~1], &lsym, &usym);
112 if (!(col & 1))
113 return lsym;
114 else if (usym == lsym)
115 return NoSymbol;
116 else
117 return usym;
120 return syms[col];
123 #if NeedFunctionPrototypes
124 KeySym
125 XKeycodeToKeysym(Display *dpy,
126 #if NeedWidePrototypes
127 unsigned int kc,
128 #else
129 KeyCode kc,
130 #endif
131 int col)
132 #else
133 KeySym
134 XKeycodeToKeysym(dpy, kc, col)
135 Display *dpy;
136 KeyCode kc;
137 int col;
138 #endif
140 if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
141 return NoSymbol;
142 return KeyCodetoKeySym(dpy, kc, col);
145 KeyCode
146 XKeysymToKeycode(dpy, ks)
147 Display *dpy;
148 KeySym ks;
150 register int i, j;
152 if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
153 return (KeyCode) 0;
154 for (j = 0; j < dpy->keysyms_per_keycode; j++) {
155 for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) {
156 if (KeyCodetoKeySym(dpy, (KeyCode) i, j) == ks)
157 return i;
160 return 0;
163 KeySym
164 XLookupKeysym(event, col)
165 register XKeyEvent *event;
166 int col;
168 if ((! event->display->keysyms) && (! _XKeyInitialize(event->display)))
169 return NoSymbol;
170 return KeyCodetoKeySym(event->display, event->keycode, col);
173 static void
174 ResetModMap(dpy)
175 Display *dpy;
177 register XModifierKeymap *map;
178 register int i, j, n;
179 KeySym sym;
180 register struct _XKeytrans *p;
182 map = dpy->modifiermap;
183 /* If any Lock key contains Caps_Lock, then interpret as Caps_Lock,
184 * else if any contains Shift_Lock, then interpret as Shift_Lock,
185 * else ignore Lock altogether.
187 dpy->lock_meaning = NoSymbol;
188 /* Lock modifiers are in the second row of the matrix */
189 n = 2 * map->max_keypermod;
190 for (i = map->max_keypermod; i < n; i++) {
191 for (j = 0; j < dpy->keysyms_per_keycode; j++) {
192 sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j);
193 if (sym == XK_Caps_Lock) {
194 dpy->lock_meaning = XK_Caps_Lock;
195 break;
196 } else if (sym == XK_Shift_Lock) {
197 dpy->lock_meaning = XK_Shift_Lock;
199 else if (sym == XK_ISO_Lock) {
200 dpy->lock_meaning = XK_Caps_Lock;
201 break;
205 /* Now find any Mod<n> modifier acting as the Group or Numlock modifier */
206 dpy->mode_switch = 0;
207 dpy->num_lock = 0;
208 n *= 4;
209 for (i = 3*map->max_keypermod; i < n; i++) {
210 for (j = 0; j < dpy->keysyms_per_keycode; j++) {
211 sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j);
212 if (sym == XK_Mode_switch)
213 dpy->mode_switch |= 1 << (i / map->max_keypermod);
214 if (sym == XK_Num_Lock)
215 dpy->num_lock |= 1 << (i / map->max_keypermod);
218 for (p = dpy->key_bindings; p; p = p->next)
219 ComputeMaskFromKeytrans(dpy, p);
222 static int
223 InitModMap(dpy)
224 Display *dpy;
226 register XModifierKeymap *map;
228 if (! (map = XGetModifierMapping(dpy)))
229 return 0;
230 LockDisplay(dpy);
231 if (dpy->modifiermap)
232 XFreeModifiermap(dpy->modifiermap);
233 dpy->modifiermap = map;
234 dpy->free_funcs->modifiermap = XFreeModifiermap;
235 if (dpy->keysyms)
236 ResetModMap(dpy);
237 UnlockDisplay(dpy);
238 return 1;
242 XRefreshKeyboardMapping(event)
243 register XMappingEvent *event;
246 if(event->request == MappingKeyboard) {
247 /* XXX should really only refresh what is necessary
248 * for now, make initialize test fail
250 LockDisplay(event->display);
251 if (event->display->keysyms) {
252 Xfree ((char *)event->display->keysyms);
253 event->display->keysyms = NULL;
255 UnlockDisplay(event->display);
257 if(event->request == MappingModifier) {
258 LockDisplay(event->display);
259 if (event->display->modifiermap) {
260 XFreeModifiermap(event->display->modifiermap);
261 event->display->modifiermap = NULL;
263 UnlockDisplay(event->display);
264 /* go ahead and get it now, since initialize test may not fail */
265 if (event->display->keysyms)
266 (void) InitModMap(event->display);
268 return 1;
272 _XKeyInitialize(dpy)
273 Display *dpy;
275 int per, n;
276 KeySym *keysyms;
279 * lets go get the keysyms from the server.
281 if (!dpy->keysyms) {
282 n = dpy->max_keycode - dpy->min_keycode + 1;
283 keysyms = XGetKeyboardMapping (dpy, (KeyCode) dpy->min_keycode,
284 n, &per);
285 /* keysyms may be NULL */
286 if (! keysyms) return 0;
288 LockDisplay(dpy);
289 if (dpy->keysyms)
290 Xfree ((char *)dpy->keysyms);
291 dpy->keysyms = keysyms;
292 dpy->keysyms_per_keycode = per;
293 if (dpy->modifiermap)
294 ResetModMap(dpy);
295 UnlockDisplay(dpy);
297 if (!dpy->modifiermap)
298 return InitModMap(dpy);
299 return 1;
302 #endif /* } */
304 void
305 XConvertCase(sym, lower, upper)
306 register KeySym sym;
307 KeySym *lower;
308 KeySym *upper;
310 *lower = sym;
311 *upper = sym;
312 switch(sym >> 8) {
313 case 0: /* Latin 1 */
314 if ((sym >= XK_A) && (sym <= XK_Z))
315 *lower += (XK_a - XK_A);
316 else if ((sym >= XK_a) && (sym <= XK_z))
317 *upper -= (XK_a - XK_A);
318 else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
319 *lower += (XK_agrave - XK_Agrave);
320 else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
321 *upper -= (XK_agrave - XK_Agrave);
322 else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
323 *lower += (XK_oslash - XK_Ooblique);
324 else if ((sym >= XK_oslash) && (sym <= XK_thorn))
325 *upper -= (XK_oslash - XK_Ooblique);
326 break;
327 case 1: /* Latin 2 */
328 /* Assume the KeySym is a legal value (ignore discontinuities) */
329 if (sym == XK_Aogonek)
330 *lower = XK_aogonek;
331 else if (sym >= XK_Lstroke && sym <= XK_Sacute)
332 *lower += (XK_lstroke - XK_Lstroke);
333 else if (sym >= XK_Scaron && sym <= XK_Zacute)
334 *lower += (XK_scaron - XK_Scaron);
335 else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
336 *lower += (XK_zcaron - XK_Zcaron);
337 else if (sym == XK_aogonek)
338 *upper = XK_Aogonek;
339 else if (sym >= XK_lstroke && sym <= XK_sacute)
340 *upper -= (XK_lstroke - XK_Lstroke);
341 else if (sym >= XK_scaron && sym <= XK_zacute)
342 *upper -= (XK_scaron - XK_Scaron);
343 else if (sym >= XK_zcaron && sym <= XK_zabovedot)
344 *upper -= (XK_zcaron - XK_Zcaron);
345 else if (sym >= XK_Racute && sym <= XK_Tcedilla)
346 *lower += (XK_racute - XK_Racute);
347 else if (sym >= XK_racute && sym <= XK_tcedilla)
348 *upper -= (XK_racute - XK_Racute);
349 break;
350 case 2: /* Latin 3 */
351 /* Assume the KeySym is a legal value (ignore discontinuities) */
352 if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
353 *lower += (XK_hstroke - XK_Hstroke);
354 else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
355 *lower += (XK_gbreve - XK_Gbreve);
356 else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
357 *upper -= (XK_hstroke - XK_Hstroke);
358 else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
359 *upper -= (XK_gbreve - XK_Gbreve);
360 else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
361 *lower += (XK_cabovedot - XK_Cabovedot);
362 else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
363 *upper -= (XK_cabovedot - XK_Cabovedot);
364 break;
365 case 3: /* Latin 4 */
366 /* Assume the KeySym is a legal value (ignore discontinuities) */
367 if (sym >= XK_Rcedilla && sym <= XK_Tslash)
368 *lower += (XK_rcedilla - XK_Rcedilla);
369 else if (sym >= XK_rcedilla && sym <= XK_tslash)
370 *upper -= (XK_rcedilla - XK_Rcedilla);
371 else if (sym == XK_ENG)
372 *lower = XK_eng;
373 else if (sym == XK_eng)
374 *upper = XK_ENG;
375 else if (sym >= XK_Amacron && sym <= XK_Umacron)
376 *lower += (XK_amacron - XK_Amacron);
377 else if (sym >= XK_amacron && sym <= XK_umacron)
378 *upper -= (XK_amacron - XK_Amacron);
379 break;
380 case 6: /* Cyrillic */
381 /* Assume the KeySym is a legal value (ignore discontinuities) */
382 if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
383 *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
384 else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
385 *upper += (XK_Serbian_DJE - XK_Serbian_dje);
386 else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
387 *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
388 else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
389 *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
390 break;
391 case 7: /* Greek */
392 /* Assume the KeySym is a legal value (ignore discontinuities) */
393 if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
394 *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
395 else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
396 sym != XK_Greek_iotaaccentdieresis &&
397 sym != XK_Greek_upsilonaccentdieresis)
398 *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
399 else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
400 *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
401 else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
402 sym != XK_Greek_finalsmallsigma)
403 *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
404 break;
405 case 0x14: /* Armenian */
406 if (sym >= XK_Armenian_AYB && sym <= XK_Armenian_fe) {
407 *lower = sym | 1;
408 *upper = sym & ~1;
410 break;
414 #if __disabled_for_imakeicide__ /* { */
417 #if NeedFunctionPrototypes
418 _XTranslateKey( register Display *dpy,
419 KeyCode keycode,
420 register unsigned int modifiers,
421 unsigned int *modifiers_return,
422 KeySym *keysym_return)
423 #else
424 _XTranslateKey(dpy, keycode, modifiers, modifiers_return, keysym_return)
425 register Display *dpy;
426 KeyCode keycode;
427 register unsigned int modifiers;
428 unsigned int *modifiers_return;
429 KeySym *keysym_return;
430 #endif
432 int per;
433 register KeySym *syms;
434 KeySym sym, lsym, usym;
436 if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
437 return 0;
438 *modifiers_return = ((ShiftMask|LockMask)
439 | dpy->mode_switch | dpy->num_lock);
440 if (((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
442 *keysym_return = NoSymbol;
443 return 1;
445 per = dpy->keysyms_per_keycode;
446 syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
447 while ((per > 2) && (syms[per - 1] == NoSymbol))
448 per--;
449 if ((per > 2) && (modifiers & dpy->mode_switch)) {
450 syms += 2;
451 per -= 2;
453 if ((modifiers & dpy->num_lock) &&
454 (per > 1 && (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) {
455 if ((modifiers & ShiftMask) ||
456 ((modifiers & LockMask) && (dpy->lock_meaning == XK_Shift_Lock)))
457 *keysym_return = syms[0];
458 else
459 *keysym_return = syms[1];
460 } else if (!(modifiers & ShiftMask) &&
461 (!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) {
462 if ((per == 1) || (syms[1] == NoSymbol))
463 XConvertCase(syms[0], keysym_return, &usym);
464 else
465 *keysym_return = syms[0];
466 } else if (!(modifiers & LockMask) ||
467 (dpy->lock_meaning != XK_Caps_Lock)) {
468 if ((per == 1) || ((usym = syms[1]) == NoSymbol))
469 XConvertCase(syms[0], &lsym, &usym);
470 *keysym_return = usym;
471 } else {
472 if ((per == 1) || ((sym = syms[1]) == NoSymbol))
473 sym = syms[0];
474 XConvertCase(sym, &lsym, &usym);
475 if (!(modifiers & ShiftMask) && (sym != syms[0]) &&
476 ((sym != usym) || (lsym == usym)))
477 XConvertCase(syms[0], &lsym, &usym);
478 *keysym_return = usym;
480 if (*keysym_return == XK_VoidSymbol)
481 *keysym_return = NoSymbol;
482 return 1;
486 _XTranslateKeySym(dpy, symbol, modifiers, buffer, nbytes)
487 Display *dpy;
488 register KeySym symbol;
489 unsigned int modifiers;
490 char *buffer;
491 int nbytes;
493 register struct _XKeytrans *p;
494 int length;
495 unsigned long hiBytes;
496 register unsigned char c;
498 if (!symbol)
499 return 0;
500 /* see if symbol rebound, if so, return that string. */
501 for (p = dpy->key_bindings; p; p = p->next) {
502 if (((modifiers & AllMods) == p->state) && (symbol == p->key)) {
503 length = p->len;
504 if (length > nbytes) length = nbytes;
505 memcpy (buffer, p->string, length);
506 return length;
509 /* try to convert to Latin-1, handling control */
510 hiBytes = symbol >> 8;
511 if (!(nbytes &&
512 ((hiBytes == 0) ||
513 ((hiBytes == 0xFF) &&
514 (((symbol >= XK_BackSpace) && (symbol <= XK_Clear)) ||
515 (symbol == XK_Return) ||
516 (symbol == XK_Escape) ||
517 (symbol == XK_KP_Space) ||
518 (symbol == XK_KP_Tab) ||
519 (symbol == XK_KP_Enter) ||
520 ((symbol >= XK_KP_Multiply) && (symbol <= XK_KP_9)) ||
521 (symbol == XK_KP_Equal) ||
522 (symbol == XK_Delete))))))
523 return 0;
525 /* if X keysym, convert to ascii by grabbing low 7 bits */
526 if (symbol == XK_KP_Space)
527 c = XK_space & 0x7F; /* patch encoding botch */
528 else if (hiBytes == 0xFF)
529 c = symbol & 0x7F;
530 else
531 c = symbol & 0xFF;
532 /* only apply Control key if it makes sense, else ignore it */
533 if (modifiers & ControlMask) {
534 if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
535 else if (c == '2') c = '\000';
536 else if (c >= '3' && c <= '7') c -= ('3' - '\033');
537 else if (c == '8') c = '\177';
538 else if (c == '/') c = '_' & 0x1F;
540 buffer[0] = c;
541 return 1;
544 /*ARGSUSED*/
546 XLookupString (event, buffer, nbytes, keysym, status)
547 register XKeyEvent *event;
548 char *buffer; /* buffer */
549 int nbytes; /* space in buffer for characters */
550 KeySym *keysym;
551 XComposeStatus *status; /* not implemented */
553 unsigned int modifiers;
554 KeySym symbol;
556 if (! _XTranslateKey(event->display, event->keycode, event->state,
557 &modifiers, &symbol))
558 return 0;
560 #ifdef USE_OWN_COMPOSE
561 if ( status ) {
562 static int been_here= 0;
563 if ( !been_here ) {
564 XimCompInitTables();
565 been_here = 1;
567 if ( !XimCompLegalStatus(status) ) {
568 status->compose_ptr = NULL;
569 status->chars_matched = 0;
571 if ( ((status->chars_matched>0)&&(status->compose_ptr!=NULL)) ||
572 XimCompIsComposeKey(symbol,event->keycode,status) ) {
573 XimCompRtrn rtrn;
574 switch (XimCompProcessSym(status,symbol,&rtrn)) {
575 case XIM_COMP_IGNORE:
576 break;
577 case XIM_COMP_IN_PROGRESS:
578 if ( keysym!=NULL )
579 *keysym = NoSymbol;
580 return 0;
581 case XIM_COMP_FAIL:
583 int n = 0, len= 0;
584 for (n=len=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
585 if ( nbytes-len > 0 ) {
586 len+= _XTranslateKeySym(event->display,rtrn.sym[n],
587 event->state,
588 buffer+len,nbytes-len);
591 if ( keysym!=NULL ) {
592 if ( n==1 ) *keysym = rtrn.sym[0];
593 else *keysym = NoSymbol;
595 return len;
597 case XIM_COMP_SUCCEED:
599 int len,n = 0;
601 symbol = rtrn.matchSym;
602 if ( keysym!=NULL ) *keysym = symbol;
603 if ( rtrn.str[0]!='\0' ) {
604 strncpy(buffer,rtrn.str,nbytes-1);
605 buffer[nbytes-1]= '\0';
606 len = strlen(buffer);
608 else {
609 len = _XTranslateKeySym(event->display,symbol,
610 event->state,
611 buffer,nbytes);
613 for (n=0;rtrn.sym[n]!=XK_VoidSymbol;n++) {
614 if ( nbytes-len > 0 ) {
615 len+= _XTranslateKeySym(event->display,rtrn.sym[n],
616 event->state,
617 buffer+len,nbytes-len);
620 return len;
625 #endif
627 if (keysym)
628 *keysym = symbol;
629 /* arguable whether to use (event->state & ~modifiers) here */
630 return _XTranslateKeySym(event->display, symbol, event->state,
631 buffer, nbytes);
634 static void
635 _XFreeKeyBindings (dpy)
636 Display *dpy;
638 register struct _XKeytrans *p, *np;
640 for (p = dpy->key_bindings; p; p = np) {
641 np = p->next;
642 Xfree(p->string);
643 Xfree((char *)p->modifiers);
644 Xfree((char *)p);
649 #if NeedFunctionPrototypes
650 XRebindKeysym (
651 Display *dpy,
652 KeySym keysym,
653 KeySym *mlist,
654 int nm, /* number of modifiers in mlist */
655 _Xconst unsigned char *str,
656 int nbytes)
657 #else
658 XRebindKeysym (dpy, keysym, mlist, nm, str, nbytes)
659 Display *dpy;
660 KeySym keysym;
661 KeySym *mlist;
662 int nm; /* number of modifiers in mlist */
663 unsigned char *str;
664 int nbytes;
665 #endif
667 register struct _XKeytrans *tmp, *p;
668 int nb;
670 if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
671 return 0;
672 LockDisplay(dpy);
673 tmp = dpy->key_bindings;
674 nb = sizeof(KeySym) * nm;
676 if ((! (p = (struct _XKeytrans *) Xmalloc( sizeof(struct _XKeytrans)))) ||
677 ((! (p->string = (char *) Xmalloc( (unsigned) nbytes))) &&
678 (nbytes > 0)) ||
679 ((! (p->modifiers = (KeySym *) Xmalloc( (unsigned) nb))) &&
680 (nb > 0))) {
681 if (p) {
682 if (p->string) Xfree(p->string);
683 if (p->modifiers) Xfree((char *) p->modifiers);
684 Xfree((char *) p);
686 UnlockDisplay(dpy);
687 return 0;
690 dpy->key_bindings = p;
691 dpy->free_funcs->key_bindings = _XFreeKeyBindings;
692 p->next = tmp; /* chain onto list */
693 memcpy (p->string, (char *) str, nbytes);
694 p->len = nbytes;
695 memcpy ((char *) p->modifiers, (char *) mlist, nb);
696 p->key = keysym;
697 p->mlen = nm;
698 ComputeMaskFromKeytrans(dpy, p);
699 UnlockDisplay(dpy);
700 return 0;
703 unsigned
704 _XKeysymToModifiers(dpy,ks)
705 Display *dpy;
706 KeySym ks;
708 CARD8 code,mods;
709 register KeySym *kmax;
710 register KeySym *k;
711 register XModifierKeymap *m;
713 if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
714 return 0;
715 kmax = dpy->keysyms +
716 (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode;
717 k = dpy->keysyms;
718 m = dpy->modifiermap;
719 mods= 0;
720 while (k<kmax) {
721 if (*k == ks ) {
722 register int j = m->max_keypermod<<3;
724 code=(((k-dpy->keysyms)/dpy->keysyms_per_keycode)+dpy->min_keycode);
726 while (--j >= 0) {
727 if (code == m->modifiermap[j])
728 mods|= (1<<(j/m->max_keypermod));
731 k++;
733 return mods;
737 * given a list of modifiers, computes the mask necessary for later matching.
738 * This routine must lookup the key in the Keymap and then search to see
739 * what modifier it is bound to, if any. Sets the AnyModifier bit if it
740 * can't map some keysym to a modifier.
742 static void
743 ComputeMaskFromKeytrans(dpy, p)
744 Display *dpy;
745 register struct _XKeytrans *p;
747 register int i;
749 p->state = AnyModifier;
750 for (i = 0; i < p->mlen; i++) {
751 p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]);
753 p->state &= AllMods;
756 #endif /* __disabled_for_imakeicide__ } */