1 /* $NetBSD: xkbcomp-KeyBind.c,v 1.1.1.1 2008/07/29 05:01:23 mrg Exp $ */
3 /* $Xorg: KeyBind.c,v 1.4 2001/02/09 02:03:34 xorgcvs Exp $ */
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
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 */
34 #include <X11/Xlibint.h>
35 #include <X11/Xutil.h>
45 #include <X11/keysymdef.h>
50 #ifdef USE_OWN_COMPOSE
56 #define XKeycodeToKeysym _XKeycodeToKeysym
57 #define XKeysymToKeycode _XKeysymToKeycode
58 #define XLookupKeysym _XLookupKeysym
59 #define XRefreshKeyboardMapping _XRefreshKeyboardMapping
60 #define XLookupString _XLookupString
63 #define XkbKeysymToModifiers _XKeysymToModifiers
66 #define AllMods (ShiftMask|LockMask|ControlMask| \
67 Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)
71 static void ComputeMaskFromKeytrans();
72 int _XKeyInitialize();
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 */
85 #if NeedFunctionPrototypes
86 KeyCodetoKeySym(register Display
*dpy
, KeyCode keycode
, int col
)
88 KeyCodetoKeySym(dpy
, keycode
, col
)
89 register Display
*dpy
;
94 register int per
= dpy
->keysyms_per_keycode
;
95 register KeySym
*syms
;
98 if ((col
< 0) || ((col
>= per
) && (col
> 3)) ||
99 ((int)keycode
< dpy
->min_keycode
) || ((int)keycode
> dpy
->max_keycode
))
102 syms
= &dpy
->keysyms
[(keycode
- dpy
->min_keycode
) * per
];
105 while ((per
> 2) && (syms
[per
- 1] == NoSymbol
))
110 if ((per
<= (col
|1)) || (syms
[col
|1] == NoSymbol
)) {
111 XConvertCase(syms
[col
&~1], &lsym
, &usym
);
114 else if (usym
== lsym
)
123 #if NeedFunctionPrototypes
125 XKeycodeToKeysym(Display
*dpy
,
126 #if NeedWidePrototypes
134 XKeycodeToKeysym(dpy
, kc
, col
)
140 if ((! dpy
->keysyms
) && (! _XKeyInitialize(dpy
)))
142 return KeyCodetoKeySym(dpy
, kc
, col
);
146 XKeysymToKeycode(dpy
, ks
)
152 if ((! dpy
->keysyms
) && (! _XKeyInitialize(dpy
)))
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
)
164 XLookupKeysym(event
, col
)
165 register XKeyEvent
*event
;
168 if ((! event
->display
->keysyms
) && (! _XKeyInitialize(event
->display
)))
170 return KeyCodetoKeySym(event
->display
, event
->keycode
, col
);
177 register XModifierKeymap
*map
;
178 register int i
, j
, n
;
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
;
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
;
205 /* Now find any Mod<n> modifier acting as the Group or Numlock modifier */
206 dpy
->mode_switch
= 0;
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
);
226 register XModifierKeymap
*map
;
228 if (! (map
= XGetModifierMapping(dpy
)))
231 if (dpy
->modifiermap
)
232 XFreeModifiermap(dpy
->modifiermap
);
233 dpy
->modifiermap
= map
;
234 dpy
->free_funcs
->modifiermap
= XFreeModifiermap
;
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
);
279 * lets go get the keysyms from the server.
282 n
= dpy
->max_keycode
- dpy
->min_keycode
+ 1;
283 keysyms
= XGetKeyboardMapping (dpy
, (KeyCode
) dpy
->min_keycode
,
285 /* keysyms may be NULL */
286 if (! keysyms
) return 0;
290 Xfree ((char *)dpy
->keysyms
);
291 dpy
->keysyms
= keysyms
;
292 dpy
->keysyms_per_keycode
= per
;
293 if (dpy
->modifiermap
)
297 if (!dpy
->modifiermap
)
298 return InitModMap(dpy
);
305 XConvertCase(sym
, lower
, upper
)
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
);
327 case 1: /* Latin 2 */
328 /* Assume the KeySym is a legal value (ignore discontinuities) */
329 if (sym
== 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
)
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
);
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
);
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
)
373 else if (sym
== 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
);
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
);
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
);
405 case 0x14: /* Armenian */
406 if (sym
>= XK_Armenian_AYB
&& sym
<= XK_Armenian_fe
) {
414 #if __disabled_for_imakeicide__ /* { */
417 #if NeedFunctionPrototypes
418 _XTranslateKey( register Display
*dpy
,
420 register unsigned int modifiers
,
421 unsigned int *modifiers_return
,
422 KeySym
*keysym_return
)
424 _XTranslateKey(dpy
, keycode
, modifiers
, modifiers_return
, keysym_return
)
425 register Display
*dpy
;
427 register unsigned int modifiers
;
428 unsigned int *modifiers_return
;
429 KeySym
*keysym_return
;
433 register KeySym
*syms
;
434 KeySym sym
, lsym
, usym
;
436 if ((! dpy
->keysyms
) && (! _XKeyInitialize(dpy
)))
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
;
445 per
= dpy
->keysyms_per_keycode
;
446 syms
= &dpy
->keysyms
[(keycode
- dpy
->min_keycode
) * per
];
447 while ((per
> 2) && (syms
[per
- 1] == NoSymbol
))
449 if ((per
> 2) && (modifiers
& dpy
->mode_switch
)) {
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];
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
);
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
;
472 if ((per
== 1) || ((sym
= syms
[1]) == NoSymbol
))
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
;
486 _XTranslateKeySym(dpy
, symbol
, modifiers
, buffer
, nbytes
)
488 register KeySym symbol
;
489 unsigned int modifiers
;
493 register struct _XKeytrans
*p
;
495 unsigned long hiBytes
;
496 register unsigned char c
;
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
)) {
504 if (length
> nbytes
) length
= nbytes
;
505 memcpy (buffer
, p
->string
, length
);
509 /* try to convert to Latin-1, handling control */
510 hiBytes
= symbol
>> 8;
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
))))))
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)
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;
546 XLookupString (event
, buffer
, nbytes
, keysym
, status
)
547 register XKeyEvent
*event
;
548 char *buffer
; /* buffer */
549 int nbytes
; /* space in buffer for characters */
551 XComposeStatus
*status
; /* not implemented */
553 unsigned int modifiers
;
556 if (! _XTranslateKey(event
->display
, event
->keycode
, event
->state
,
557 &modifiers
, &symbol
))
560 #ifdef USE_OWN_COMPOSE
562 static int been_here
= 0;
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
) ) {
574 switch (XimCompProcessSym(status
,symbol
,&rtrn
)) {
575 case XIM_COMP_IGNORE
:
577 case XIM_COMP_IN_PROGRESS
:
584 for (n
=len
=0;rtrn
.sym
[n
]!=XK_VoidSymbol
;n
++) {
585 if ( nbytes
-len
> 0 ) {
586 len
+= _XTranslateKeySym(event
->display
,rtrn
.sym
[n
],
588 buffer
+len
,nbytes
-len
);
591 if ( keysym
!=NULL
) {
592 if ( n
==1 ) *keysym
= rtrn
.sym
[0];
593 else *keysym
= NoSymbol
;
597 case XIM_COMP_SUCCEED
:
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
);
609 len
= _XTranslateKeySym(event
->display
,symbol
,
613 for (n
=0;rtrn
.sym
[n
]!=XK_VoidSymbol
;n
++) {
614 if ( nbytes
-len
> 0 ) {
615 len
+= _XTranslateKeySym(event
->display
,rtrn
.sym
[n
],
617 buffer
+len
,nbytes
-len
);
629 /* arguable whether to use (event->state & ~modifiers) here */
630 return _XTranslateKeySym(event
->display
, symbol
, event
->state
,
635 _XFreeKeyBindings (dpy
)
638 register struct _XKeytrans
*p
, *np
;
640 for (p
= dpy
->key_bindings
; p
; p
= np
) {
643 Xfree((char *)p
->modifiers
);
649 #if NeedFunctionPrototypes
654 int nm
, /* number of modifiers in mlist */
655 _Xconst
unsigned char *str
,
658 XRebindKeysym (dpy
, keysym
, mlist
, nm
, str
, nbytes
)
662 int nm
; /* number of modifiers in mlist */
667 register struct _XKeytrans
*tmp
, *p
;
670 if ((! dpy
->keysyms
) && (! _XKeyInitialize(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
))) &&
679 ((! (p
->modifiers
= (KeySym
*) Xmalloc( (unsigned) nb
))) &&
682 if (p
->string
) Xfree(p
->string
);
683 if (p
->modifiers
) Xfree((char *) p
->modifiers
);
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
);
695 memcpy ((char *) p
->modifiers
, (char *) mlist
, nb
);
698 ComputeMaskFromKeytrans(dpy
, p
);
704 _XKeysymToModifiers(dpy
,ks
)
709 register KeySym
*kmax
;
711 register XModifierKeymap
*m
;
713 if ((! dpy
->keysyms
) && (! _XKeyInitialize(dpy
)))
715 kmax
= dpy
->keysyms
+
716 (dpy
->max_keycode
- dpy
->min_keycode
+ 1) * dpy
->keysyms_per_keycode
;
718 m
= dpy
->modifiermap
;
722 register int j
= m
->max_keypermod
<<3;
724 code
=(((k
-dpy
->keysyms
)/dpy
->keysyms_per_keycode
)+dpy
->min_keycode
);
727 if (code
== m
->modifiermap
[j
])
728 mods
|= (1<<(j
/m
->max_keypermod
));
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.
743 ComputeMaskFromKeytrans(dpy
, p
)
745 register struct _XKeytrans
*p
;
749 p
->state
= AnyModifier
;
750 for (i
= 0; i
< p
->mlen
; i
++) {
751 p
->state
|= XkbKeysymToModifiers(dpy
,p
->modifiers
[i
]);
756 #endif /* __disabled_for_imakeicide__ } */