1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
29 #elif defined(HAVE_CONFIG_H)
35 #include <X11/Xproto.h>
38 #include <X11/keysym.h>
39 #define XKBSRV_NEED_FILE_FUNCS
42 /***====================================================================***/
44 #define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol)
45 #define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l))
48 XkbKeyTypesForCoreSymbols(XkbDescPtr xkb
,
51 unsigned int protected,
52 int *types_inout
, KeySym
* xkb_syms_rtrn
)
56 int nSyms
[XkbNumKbdGroups
];
57 int nGroups
, tmp
, groupsWidth
;
58 BOOL replicated
= FALSE
;
60 /* Section 12.2 of the protocol describes this process in more detail */
61 /* Step 1: find the # of symbols in the core mapping per group */
63 for (i
= 0; i
< XkbNumKbdGroups
; i
++) {
64 if ((protected & (1 << i
)) && (types_inout
[i
] < xkb
->map
->num_types
)) {
65 nSyms
[i
] = xkb
->map
->types
[types_inout
[i
]].num_levels
;
66 if (nSyms
[i
] > groupsWidth
)
67 groupsWidth
= nSyms
[i
];
70 types_inout
[i
] = XkbTwoLevelIndex
; /* don't really know, yet */
74 if (nSyms
[XkbGroup1Index
] < 2)
75 nSyms
[XkbGroup1Index
] = 2;
76 if (nSyms
[XkbGroup2Index
] < 2)
77 nSyms
[XkbGroup2Index
] = 2;
78 /* Step 2: Copy the symbols from the core ordering to XKB ordering */
79 /* symbols in the core are in the order: */
80 /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */
81 xkb_syms_rtrn
[XKB_OFFSET(XkbGroup1Index
, 0)] = CORE_SYM(0);
82 xkb_syms_rtrn
[XKB_OFFSET(XkbGroup1Index
, 1)] = CORE_SYM(1);
83 for (i
= 2; i
< nSyms
[XkbGroup1Index
]; i
++) {
84 xkb_syms_rtrn
[XKB_OFFSET(XkbGroup1Index
, i
)] = CORE_SYM(2 + i
);
86 xkb_syms_rtrn
[XKB_OFFSET(XkbGroup2Index
, 0)] = CORE_SYM(2);
87 xkb_syms_rtrn
[XKB_OFFSET(XkbGroup2Index
, 1)] = CORE_SYM(3);
88 tmp
= 2 + (nSyms
[XkbGroup1Index
] - 2); /* offset to extra group2 syms */
89 for (i
= 2; i
< nSyms
[XkbGroup2Index
]; i
++) {
90 xkb_syms_rtrn
[XKB_OFFSET(XkbGroup2Index
, i
)] = CORE_SYM(tmp
+ i
);
93 /* Special case: if only the first group is explicit, and the symbols
94 * replicate across all groups, then we have a Section 12.4 replication */
95 if ((protected & ~XkbExplicitKeyType1Mask
) == 0) {
96 int j
, width
= nSyms
[XkbGroup1Index
];
100 /* Check ABAB in ABABCDECDEABCDE */
101 if ((width
> 0 && CORE_SYM(0) != CORE_SYM(2)) ||
102 (width
> 1 && CORE_SYM(1) != CORE_SYM(3)))
105 /* Check CDECDE in ABABCDECDEABCDE */
106 for (i
= 2; i
< width
&& replicated
; i
++) {
107 if (CORE_SYM(2 + i
) != CORE_SYM(i
+ width
))
111 /* Check ABCDE in ABABCDECDEABCDE */
112 for (j
= 2; replicated
&&
113 j
< XkbNumKbdGroups
&& map_width
>= width
* (j
+ 1); j
++) {
114 for (i
= 0; i
< width
&& replicated
; i
++) {
115 if (CORE_SYM(((i
< 2) ? i
: 2 + i
)) != CORE_SYM(i
+ width
* j
))
122 nSyms
[XkbGroup2Index
] = 0;
123 nSyms
[XkbGroup3Index
] = 0;
124 nSyms
[XkbGroup4Index
] = 0;
128 tmp
= nSyms
[XkbGroup1Index
] + nSyms
[XkbGroup2Index
];
129 if ((tmp
>= map_width
) &&
130 ((protected & (XkbExplicitKeyType3Mask
| XkbExplicitKeyType4Mask
))
132 nSyms
[XkbGroup3Index
] = 0;
133 nSyms
[XkbGroup4Index
] = 0;
138 for (i
= 0; i
< nSyms
[XkbGroup3Index
]; i
++, tmp
++) {
139 xkb_syms_rtrn
[XKB_OFFSET(XkbGroup3Index
, i
)] = CORE_SYM(tmp
);
141 if ((tmp
< map_width
) || (protected & XkbExplicitKeyType4Mask
)) {
143 for (i
= 0; i
< nSyms
[XkbGroup4Index
]; i
++, tmp
++) {
144 xkb_syms_rtrn
[XKB_OFFSET(XkbGroup4Index
, i
)] =
149 nSyms
[XkbGroup4Index
] = 0;
153 /* steps 3&4: alphanumeric expansion, assign canonical types */
155 for (i
= 0; i
< nGroups
; i
++) {
158 syms
= &xkb_syms_rtrn
[XKB_OFFSET(i
, 0)];
159 if ((nSyms
[i
] > 1) && (syms
[1] == NoSymbol
) && (syms
[0] != NoSymbol
)) {
162 XkbConvertCase(syms
[0], &lower
, &upper
);
163 if (upper
!= lower
) {
164 xkb_syms_rtrn
[XKB_OFFSET(i
, 0)] = lower
;
165 xkb_syms_rtrn
[XKB_OFFSET(i
, 1)] = upper
;
166 if ((protected & (1 << i
)) == 0)
167 types_inout
[i
] = XkbAlphabeticIndex
;
169 else if ((protected & (1 << i
)) == 0) {
170 types_inout
[i
] = XkbOneLevelIndex
;
174 if (((protected & (1 << i
)) == 0) &&
175 (types_inout
[i
] == XkbTwoLevelIndex
)) {
176 if (XkbKSIsKeypad(syms
[0]) || XkbKSIsKeypad(syms
[1]))
177 types_inout
[i
] = XkbKeypadIndex
;
181 XkbConvertCase(syms
[0], &lower
, &upper
);
182 if ((syms
[0] == lower
) && (syms
[1] == upper
))
183 types_inout
[i
] = XkbAlphabeticIndex
;
186 if (syms
[0] == NoSymbol
) {
190 for (n
= 1, found
= FALSE
; (!found
) && (n
< nSyms
[i
]); n
++) {
191 found
= (syms
[n
] != NoSymbol
);
197 /* step 5: squoosh out empty groups */
199 for (i
= nGroups
- 1; i
>= 0; i
--) {
200 if (((empty
& (1 << i
)) == 0) || (protected & (1 << i
)))
208 /* step 6: replicate group 1 into group two, if necessary */
210 ((empty
& (XkbGroup1Mask
| XkbGroup2Mask
)) == XkbGroup2Mask
)) {
211 if ((protected & (XkbExplicitKeyType1Mask
| XkbExplicitKeyType2Mask
)) ==
213 nSyms
[XkbGroup2Index
] = nSyms
[XkbGroup1Index
];
214 types_inout
[XkbGroup2Index
] = types_inout
[XkbGroup1Index
];
215 memcpy((char *) &xkb_syms_rtrn
[2], (char *) xkb_syms_rtrn
,
218 else if (types_inout
[XkbGroup1Index
] == types_inout
[XkbGroup2Index
]) {
219 memcpy((char *) &xkb_syms_rtrn
[nSyms
[XkbGroup1Index
]],
220 (char *) xkb_syms_rtrn
,
221 nSyms
[XkbGroup1Index
] * sizeof(KeySym
));
225 /* step 7: check for all groups identical or all width 1
227 * Special feature: if group 1 has an explicit type and all other groups
228 * have canonical types with same symbols, we assume it's info lost from
229 * the core replication.
232 Bool sameType
, allOneLevel
, canonical
= TRUE
;
234 allOneLevel
= (xkb
->map
->types
[types_inout
[0]].num_levels
== 1);
235 for (i
= 1, sameType
= TRUE
; (allOneLevel
|| sameType
) && (i
< nGroups
);
237 sameType
= (sameType
&&
238 (types_inout
[i
] == types_inout
[XkbGroup1Index
]));
240 allOneLevel
= (xkb
->map
->types
[types_inout
[i
]].num_levels
== 1);
241 if (types_inout
[i
] > XkbLastRequiredType
)
244 if (((sameType
) || canonical
) &&
246 (XkbExplicitKeyTypesMask
& ~XkbExplicitKeyType1Mask
)))) {
250 for (i
= 1, identical
= TRUE
; identical
&& (i
< nGroups
); i
++) {
253 if (nSyms
[i
] != nSyms
[XkbGroup1Index
])
255 syms
= &xkb_syms_rtrn
[XKB_OFFSET(i
, 0)];
256 for (s
= 0; identical
&& (s
< nSyms
[i
]); s
++) {
257 if (syms
[s
] != xkb_syms_rtrn
[s
])
264 if (allOneLevel
&& (nGroups
> 1)) {
267 syms
= &xkb_syms_rtrn
[nSyms
[XkbGroup1Index
]];
268 nSyms
[XkbGroup1Index
] = 1;
269 for (i
= 1; i
< nGroups
; i
++) {
270 xkb_syms_rtrn
[i
] = syms
[0];
279 static XkbSymInterpretPtr
280 _XkbFindMatchingInterp(XkbDescPtr xkb
,
281 KeySym sym
, unsigned int real_mods
, unsigned int level
)
284 XkbSymInterpretPtr interp
, rtrn
;
288 interp
= xkb
->compat
->sym_interpret
;
289 for (i
= 0; i
< xkb
->compat
->num_si
; i
++, interp
++) {
290 if ((interp
->sym
== NoSymbol
) || (sym
== interp
->sym
)) {
293 if ((level
== 0) || ((interp
->match
& XkbSI_LevelOneOnly
) == 0))
297 switch (interp
->match
& XkbSI_OpMask
) {
299 match
= ((interp
->mods
& mods
) == 0);
301 case XkbSI_AnyOfOrNone
:
302 match
= ((mods
== 0) || ((interp
->mods
& mods
) != 0));
305 match
= ((interp
->mods
& mods
) != 0);
308 match
= ((interp
->mods
& mods
) == interp
->mods
);
311 match
= (interp
->mods
== mods
);
318 if (interp
->sym
!= NoSymbol
) {
321 else if (rtrn
== NULL
) {
331 _XkbAddKeyChange(KeyCode
*pFirst
, unsigned char *pNum
, KeyCode newKey
)
335 last
= (*pFirst
) + (*pNum
);
336 if (newKey
< *pFirst
) {
338 *pNum
= (last
- newKey
) + 1;
340 else if (newKey
> last
) {
341 *pNum
= (last
- *pFirst
) + 1;
347 _XkbSetActionKeyMods(XkbDescPtr xkb
, XkbAction
*act
, unsigned mods
)
353 case XkbSA_LatchMods
:
355 if (act
->mods
.flags
& XkbSA_UseModMapMods
)
356 act
->mods
.real_mods
= act
->mods
.mask
= mods
;
357 if ((tmp
= XkbModActionVMods(&act
->mods
)) != 0) {
358 XkbVirtualModsToReal(xkb
, tmp
, &tmp
);
359 act
->mods
.mask
|= tmp
;
363 if (act
->iso
.flags
& XkbSA_UseModMapMods
)
364 act
->iso
.real_mods
= act
->iso
.mask
= mods
;
365 if ((tmp
= XkbModActionVMods(&act
->iso
)) != 0) {
366 XkbVirtualModsToReal(xkb
, tmp
, &tmp
);
367 act
->iso
.mask
|= tmp
;
377 XkbApplyCompatMapToKey(XkbDescPtr xkb
, KeyCode key
, XkbChangesPtr changes
)
380 unsigned char explicit, mods
;
381 XkbSymInterpretPtr
*interps
, ibuf
[IBUF_SIZE
];
383 unsigned changed
, tmp
;
385 if ((!xkb
) || (!xkb
->map
) || (!xkb
->map
->key_sym_map
) ||
386 (!xkb
->compat
) || (!xkb
->compat
->sym_interpret
) ||
387 (key
< xkb
->min_key_code
) || (key
> xkb
->max_key_code
)) {
390 if (((!xkb
->server
) || (!xkb
->server
->key_acts
)) &&
391 (XkbAllocServerMap(xkb
, XkbAllServerInfoMask
, 0) != Success
)) {
394 changed
= 0; /* keeps track of what has changed in _this_ call */
395 explicit = xkb
->server
->explicit[key
];
396 if (explicit & XkbExplicitInterpretMask
) /* nothing to do */
398 mods
= (xkb
->map
->modmap
? xkb
->map
->modmap
[key
] : 0);
399 nSyms
= XkbKeyNumSyms(xkb
, key
);
400 syms
= XkbKeySymsPtr(xkb
, key
);
401 if (nSyms
> IBUF_SIZE
) {
402 interps
= calloc(nSyms
, sizeof(XkbSymInterpretPtr
));
403 if (interps
== NULL
) {
412 for (n
= 0; n
< nSyms
; n
++) {
413 unsigned level
= (n
% XkbKeyGroupsWidth(xkb
, key
));
416 if (syms
[n
] != NoSymbol
) {
417 interps
[n
] = _XkbFindMatchingInterp(xkb
, syms
[n
], mods
, level
);
418 if (interps
[n
] && interps
[n
]->act
.type
!= XkbSA_NoAction
)
424 /* 1/28/96 (ef) -- XXX! WORKING HERE */
426 if (xkb
->server
->key_acts
[key
] != 0) {
427 xkb
->server
->key_acts
[key
] = 0;
428 changed
|= XkbKeyActionsMask
;
433 unsigned int new_vmodmask
;
435 changed
|= XkbKeyActionsMask
;
436 pActs
= XkbResizeKeyActions(xkb
, key
, nSyms
);
438 if (nSyms
> IBUF_SIZE
)
443 for (n
= 0; n
< nSyms
; n
++) {
447 pActs
[n
] = *((XkbAction
*) &interps
[n
]->act
);
448 if ((n
== 0) || ((interps
[n
]->match
& XkbSI_LevelOneOnly
) == 0)) {
450 if (interps
[n
]->virtual_mod
!= XkbNoModifier
)
451 new_vmodmask
|= (1 << interps
[n
]->virtual_mod
);
455 _XkbSetActionKeyMods(xkb
, &pActs
[n
], effMods
);
458 pActs
[n
].type
= XkbSA_NoAction
;
460 if (((explicit & XkbExplicitVModMapMask
) == 0) &&
461 (xkb
->server
->vmodmap
[key
] != new_vmodmask
)) {
462 changed
|= XkbVirtualModMapMask
;
463 xkb
->server
->vmodmap
[key
] = new_vmodmask
;
466 if ((interps
[0]->flags
& XkbSI_LockingKey
) &&
467 ((explicit & XkbExplicitBehaviorMask
) == 0)) {
468 xkb
->server
->behaviors
[key
].type
= XkbKB_Lock
;
469 changed
|= XkbKeyBehaviorsMask
;
471 if (((explicit & XkbExplicitAutoRepeatMask
) == 0) && (xkb
->ctrls
)) {
474 old
= BitIsOn(xkb
->ctrls
->per_key_repeat
, key
);
475 if (interps
[0]->flags
& XkbSI_AutoRepeat
)
476 SetBit(xkb
->ctrls
->per_key_repeat
, key
);
478 ClearBit(xkb
->ctrls
->per_key_repeat
, key
);
479 if (changes
&& old
!= BitIsOn(xkb
->ctrls
->per_key_repeat
, key
))
480 changes
->ctrls
.changed_ctrls
|= XkbPerKeyRepeatMask
;
484 if ((!found
) || (interps
[0] == NULL
)) {
485 if (((explicit & XkbExplicitAutoRepeatMask
) == 0) && (xkb
->ctrls
)) {
488 old
= BitIsOn(xkb
->ctrls
->per_key_repeat
, key
);
489 SetBit(xkb
->ctrls
->per_key_repeat
, key
);
490 if (changes
&& (old
!= BitIsOn(xkb
->ctrls
->per_key_repeat
, key
)))
491 changes
->ctrls
.changed_ctrls
|= XkbPerKeyRepeatMask
;
493 if (((explicit & XkbExplicitBehaviorMask
) == 0) &&
494 (xkb
->server
->behaviors
[key
].type
== XkbKB_Lock
)) {
495 xkb
->server
->behaviors
[key
].type
= XkbKB_Default
;
496 changed
|= XkbKeyBehaviorsMask
;
503 tmp
= (changed
& mc
->changed
);
504 if (tmp
& XkbKeyActionsMask
)
505 _XkbAddKeyChange(&mc
->first_key_act
, &mc
->num_key_acts
, key
);
506 else if (changed
& XkbKeyActionsMask
) {
507 mc
->changed
|= XkbKeyActionsMask
;
508 mc
->first_key_act
= key
;
509 mc
->num_key_acts
= 1;
511 if (tmp
& XkbKeyBehaviorsMask
) {
512 _XkbAddKeyChange(&mc
->first_key_behavior
, &mc
->num_key_behaviors
,
515 else if (changed
& XkbKeyBehaviorsMask
) {
516 mc
->changed
|= XkbKeyBehaviorsMask
;
517 mc
->first_key_behavior
= key
;
518 mc
->num_key_behaviors
= 1;
520 if (tmp
& XkbVirtualModMapMask
)
521 _XkbAddKeyChange(&mc
->first_vmodmap_key
, &mc
->num_vmodmap_keys
,
523 else if (changed
& XkbVirtualModMapMask
) {
524 mc
->changed
|= XkbVirtualModMapMask
;
525 mc
->first_vmodmap_key
= key
;
526 mc
->num_vmodmap_keys
= 1;
528 mc
->changed
|= changed
;
536 XkbChangeTypesOfKey(XkbDescPtr xkb
,
539 unsigned groups
, int *newTypesIn
, XkbMapChangesPtr changes
)
541 XkbKeyTypePtr pOldType
, pNewType
;
543 int width
, nOldGroups
, oldWidth
, newTypes
[XkbNumKbdGroups
];
545 if ((!xkb
) || (!XkbKeycodeInRange(xkb
, key
)) || (!xkb
->map
) ||
546 (!xkb
->map
->types
) || (!newTypesIn
) ||
547 ((groups
& XkbAllGroupsMask
) == 0) || (nGroups
> XkbNumKbdGroups
)) {
551 for (i
= 0; i
< XkbNumKbdGroups
; i
++) {
552 xkb
->map
->key_sym_map
[key
].kt_index
[i
] = XkbOneLevelIndex
;
554 i
= xkb
->map
->key_sym_map
[key
].group_info
;
555 i
= XkbSetNumGroups(i
, 0);
556 xkb
->map
->key_sym_map
[key
].group_info
= i
;
557 XkbResizeKeySyms(xkb
, key
, 0);
561 nOldGroups
= XkbKeyNumGroups(xkb
, key
);
562 oldWidth
= XkbKeyGroupsWidth(xkb
, key
);
563 for (width
= i
= 0; i
< nGroups
; i
++) {
564 if (groups
& (1 << i
))
565 newTypes
[i
] = newTypesIn
[i
];
566 else if (i
< nOldGroups
)
567 newTypes
[i
] = XkbKeyKeyTypeIndex(xkb
, key
, i
);
568 else if (nOldGroups
> 0)
569 newTypes
[i
] = XkbKeyKeyTypeIndex(xkb
, key
, XkbGroup1Index
);
571 newTypes
[i
] = XkbTwoLevelIndex
;
572 if (newTypes
[i
] > xkb
->map
->num_types
)
574 pNewType
= &xkb
->map
->types
[newTypes
[i
]];
575 if (pNewType
->num_levels
> width
)
576 width
= pNewType
->num_levels
;
578 if ((xkb
->ctrls
) && (nGroups
> xkb
->ctrls
->num_groups
))
579 xkb
->ctrls
->num_groups
= nGroups
;
580 if ((width
!= oldWidth
) || (nGroups
!= nOldGroups
)) {
581 KeySym oldSyms
[XkbMaxSymsPerKey
], *pSyms
;
584 if (nOldGroups
== 0) {
585 pSyms
= XkbResizeKeySyms(xkb
, key
, width
* nGroups
);
587 i
= xkb
->map
->key_sym_map
[key
].group_info
;
588 i
= XkbSetNumGroups(i
, nGroups
);
589 xkb
->map
->key_sym_map
[key
].group_info
= i
;
590 xkb
->map
->key_sym_map
[key
].width
= width
;
591 for (i
= 0; i
< nGroups
; i
++) {
592 xkb
->map
->key_sym_map
[key
].kt_index
[i
] = newTypes
[i
];
598 pSyms
= XkbKeySymsPtr(xkb
, key
);
599 memcpy(oldSyms
, pSyms
, XkbKeyNumSyms(xkb
, key
) * sizeof(KeySym
));
600 pSyms
= XkbResizeKeySyms(xkb
, key
, width
* nGroups
);
603 memset(pSyms
, 0, width
* nGroups
* sizeof(KeySym
));
604 for (i
= 0; (i
< nGroups
) && (i
< nOldGroups
); i
++) {
605 pOldType
= XkbKeyKeyType(xkb
, key
, i
);
606 pNewType
= &xkb
->map
->types
[newTypes
[i
]];
607 if (pNewType
->num_levels
> pOldType
->num_levels
)
608 nCopy
= pOldType
->num_levels
;
610 nCopy
= pNewType
->num_levels
;
611 memcpy(&pSyms
[i
* width
], &oldSyms
[i
* oldWidth
],
612 nCopy
* sizeof(KeySym
));
614 if (XkbKeyHasActions(xkb
, key
)) {
615 XkbAction oldActs
[XkbMaxSymsPerKey
], *pActs
;
617 pActs
= XkbKeyActionsPtr(xkb
, key
);
618 memcpy(oldActs
, pActs
, XkbKeyNumSyms(xkb
, key
) * sizeof(XkbAction
));
619 pActs
= XkbResizeKeyActions(xkb
, key
, width
* nGroups
);
622 memset(pActs
, 0, width
* nGroups
* sizeof(XkbAction
));
623 for (i
= 0; (i
< nGroups
) && (i
< nOldGroups
); i
++) {
624 pOldType
= XkbKeyKeyType(xkb
, key
, i
);
625 pNewType
= &xkb
->map
->types
[newTypes
[i
]];
626 if (pNewType
->num_levels
> pOldType
->num_levels
)
627 nCopy
= pOldType
->num_levels
;
629 nCopy
= pNewType
->num_levels
;
630 memcpy(&pActs
[i
* width
], &oldActs
[i
* oldWidth
],
631 nCopy
* sizeof(XkbAction
));
634 i
= xkb
->map
->key_sym_map
[key
].group_info
;
635 i
= XkbSetNumGroups(i
, nGroups
);
636 xkb
->map
->key_sym_map
[key
].group_info
= i
;
637 xkb
->map
->key_sym_map
[key
].width
= width
;
640 for (i
= 0; i
< nGroups
; i
++) {
641 xkb
->map
->key_sym_map
[key
].kt_index
[i
] = newTypes
[i
];
642 if (xkb
->map
->types
[newTypes
[i
]].num_levels
> width
)
643 width
= xkb
->map
->types
[newTypes
[i
]].num_levels
;
645 xkb
->map
->key_sym_map
[key
].width
= width
;
646 if (changes
!= NULL
) {
647 if (changes
->changed
& XkbKeySymsMask
) {
648 _XkbAddKeyChange(&changes
->first_key_sym
, &changes
->num_key_syms
,
652 changes
->changed
|= XkbKeySymsMask
;
653 changes
->first_key_sym
= key
;
654 changes
->num_key_syms
= 1;
660 /***====================================================================***/
663 XkbVirtualModsToReal(XkbDescPtr xkb
, unsigned virtual_mask
, unsigned *mask_rtrn
)
666 register unsigned mask
;
670 if (virtual_mask
== 0) {
674 if (xkb
->server
== NULL
)
676 for (i
= mask
= 0, bit
= 1; i
< XkbNumVirtualMods
; i
++, bit
<<= 1) {
677 if (virtual_mask
& bit
)
678 mask
|= xkb
->server
->vmods
[i
];
684 /***====================================================================***/
687 XkbUpdateActionVirtualMods(XkbDescPtr xkb
, XkbAction
*act
, unsigned changed
)
693 case XkbSA_LatchMods
:
695 if (((tmp
= XkbModActionVMods(&act
->mods
)) & changed
) != 0) {
696 XkbVirtualModsToReal(xkb
, tmp
, &tmp
);
697 act
->mods
.mask
= act
->mods
.real_mods
;
698 act
->mods
.mask
|= tmp
;
703 if ((((tmp
= XkbModActionVMods(&act
->iso
)) != 0) & changed
) != 0) {
704 XkbVirtualModsToReal(xkb
, tmp
, &tmp
);
705 act
->iso
.mask
= act
->iso
.real_mods
;
706 act
->iso
.mask
|= tmp
;
715 XkbUpdateKeyTypeVirtualMods(XkbDescPtr xkb
,
717 unsigned int changed
, XkbChangesPtr changes
)
719 register unsigned int i
;
722 XkbVirtualModsToReal(xkb
, type
->mods
.vmods
, &mask
);
723 type
->mods
.mask
= type
->mods
.real_mods
| mask
;
724 if ((type
->map_count
> 0) && (type
->mods
.vmods
!= 0)) {
725 XkbKTMapEntryPtr entry
;
727 for (i
= 0, entry
= type
->map
; i
< type
->map_count
; i
++, entry
++) {
728 if (entry
->mods
.vmods
!= 0) {
729 XkbVirtualModsToReal(xkb
, entry
->mods
.vmods
, &mask
);
730 entry
->mods
.mask
= entry
->mods
.real_mods
| mask
;
731 /* entry is active if vmods are bound */
732 entry
->active
= (mask
!= 0);
741 type_ndx
= type
- xkb
->map
->types
;
742 if ((type_ndx
< 0) || (type_ndx
> xkb
->map
->num_types
))
744 if (changes
->map
.changed
& XkbKeyTypesMask
) {
747 last
= changes
->map
.first_type
+ changes
->map
.num_types
- 1;
748 if (type_ndx
< changes
->map
.first_type
) {
749 changes
->map
.first_type
= type_ndx
;
750 changes
->map
.num_types
= (last
- type_ndx
) + 1;
752 else if (type_ndx
> last
) {
753 changes
->map
.num_types
=
754 (type_ndx
- changes
->map
.first_type
) + 1;
758 changes
->map
.changed
|= XkbKeyTypesMask
;
759 changes
->map
.first_type
= type_ndx
;
760 changes
->map
.num_types
= 1;
767 XkbApplyVirtualModChanges(XkbDescPtr xkb
, unsigned changed
,
768 XkbChangesPtr changes
)
771 unsigned int checkState
= 0;
773 if ((!xkb
) || (!xkb
->map
) || (changed
== 0))
775 for (i
= 0; i
< xkb
->map
->num_types
; i
++) {
776 if (xkb
->map
->types
[i
].mods
.vmods
& changed
)
777 XkbUpdateKeyTypeVirtualMods(xkb
, &xkb
->map
->types
[i
], changed
,
780 if (changed
& xkb
->ctrls
->internal
.vmods
) {
781 unsigned int newMask
;
783 XkbVirtualModsToReal(xkb
, xkb
->ctrls
->internal
.vmods
, &newMask
);
784 newMask
|= xkb
->ctrls
->internal
.real_mods
;
785 if (xkb
->ctrls
->internal
.mask
!= newMask
) {
786 xkb
->ctrls
->internal
.mask
= newMask
;
788 changes
->ctrls
.changed_ctrls
|= XkbInternalModsMask
;
793 if (changed
& xkb
->ctrls
->ignore_lock
.vmods
) {
794 unsigned int newMask
;
796 XkbVirtualModsToReal(xkb
, xkb
->ctrls
->ignore_lock
.vmods
, &newMask
);
797 newMask
|= xkb
->ctrls
->ignore_lock
.real_mods
;
798 if (xkb
->ctrls
->ignore_lock
.mask
!= newMask
) {
799 xkb
->ctrls
->ignore_lock
.mask
= newMask
;
801 changes
->ctrls
.changed_ctrls
|= XkbIgnoreLockModsMask
;
806 if (xkb
->indicators
!= NULL
) {
807 XkbIndicatorMapPtr map
;
809 map
= &xkb
->indicators
->maps
[0];
810 for (i
= 0; i
< XkbNumIndicators
; i
++, map
++) {
811 if (map
->mods
.vmods
& changed
) {
812 unsigned int newMask
;
814 XkbVirtualModsToReal(xkb
, map
->mods
.vmods
, &newMask
);
815 newMask
|= map
->mods
.real_mods
;
816 if (newMask
!= map
->mods
.mask
) {
817 map
->mods
.mask
= newMask
;
819 changes
->indicators
.map_changes
|= (1 << i
);
826 if (xkb
->compat
!= NULL
) {
827 XkbCompatMapPtr compat
;
829 compat
= xkb
->compat
;
830 for (i
= 0; i
< XkbNumKbdGroups
; i
++) {
831 unsigned int newMask
;
833 XkbVirtualModsToReal(xkb
, compat
->groups
[i
].vmods
, &newMask
);
834 newMask
|= compat
->groups
[i
].real_mods
;
835 if (compat
->groups
[i
].mask
!= newMask
) {
836 compat
->groups
[i
].mask
= newMask
;
838 changes
->compat
.changed_groups
|= (1 << i
);
844 if (xkb
->map
&& xkb
->server
) {
845 int highChange
= 0, lowChange
= -1;
847 for (i
= xkb
->min_key_code
; i
<= xkb
->max_key_code
; i
++) {
848 if (XkbKeyHasActions(xkb
, i
)) {
849 register XkbAction
*pAct
;
852 pAct
= XkbKeyActionsPtr(xkb
, i
);
853 for (n
= XkbKeyNumActions(xkb
, i
); n
> 0; n
--, pAct
++) {
854 if ((pAct
->type
!= XkbSA_NoAction
) &&
855 XkbUpdateActionVirtualMods(xkb
, pAct
, changed
)) {
863 if (changes
&& (lowChange
> 0)) { /* something changed */
864 if (changes
->map
.changed
& XkbKeyActionsMask
) {
867 if (changes
->map
.first_key_act
< lowChange
)
868 lowChange
= changes
->map
.first_key_act
;
870 changes
->map
.first_key_act
+ changes
->map
.num_key_acts
- 1;
871 if (last
> highChange
)
874 changes
->map
.changed
|= XkbKeyActionsMask
;
875 changes
->map
.first_key_act
= lowChange
;
876 changes
->map
.num_key_acts
= (highChange
- lowChange
) + 1;