1
/* $Xorg: XKBMisc.c,v 1.4 2000/08/17 19:45:02 cpqbld Exp $ */
2
/************************************************************
3
Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
5
Permission to use, copy, modify, and distribute this
6
software and its documentation for any purpose and without
7
fee is hereby granted, provided that the above copyright
8
notice appear in all copies and that both that copyright
9
notice and this permission notice appear in supporting
10
documentation, and that the name of Silicon Graphics not be
11
used in advertising or publicity pertaining to distribution
12
of the software without specific prior written permission.
13
Silicon Graphics makes no representation about the suitability
14
of this software for any purpose. It is provided "as is"
15
without any express or implied warranty.
17
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
18
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
20
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
21
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
23
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
24
THE USE OR PERFORMANCE OF THIS SOFTWARE.
26
********************************************************/
27
/* $XFree86: xc/lib/X11/XKBMisc.c,v 3.5 2001/10/28 03:32:33 tsi Exp $ */
35
#include <X11/extensions/XKBproto.h>
36
#include <X11/keysym.h>
37
#include "XKBlibint.h"
48
#include <X11/keysym.h>
49
#define XKBSRV_NEED_FILE_FUNCS
52
#endif /* XKB_IN_SERVER */
54
/***====================================================================***/
56
#define mapSize(m) (sizeof(m)/sizeof(XkbKTMapEntryRec))
57
static XkbKTMapEntryRec map2Level[]= {
58
{ True, ShiftMask, {1, ShiftMask, 0} }
61
static XkbKTMapEntryRec mapAlpha[]= {
62
{ True, ShiftMask, { 1, ShiftMask, 0 } },
63
{ True, LockMask, { 0, LockMask, 0 } }
66
static XkbModsRec preAlpha[]= {
68
{ LockMask, LockMask, 0 }
71
#define NL_VMOD_MASK 0
72
static XkbKTMapEntryRec mapKeypad[]= {
73
{ True, ShiftMask, { 1, ShiftMask, 0 } },
74
{ False, 0, { 1, 0, NL_VMOD_MASK } }
77
static XkbKeyTypeRec canonicalTypes[XkbNumRequiredTypes] = {
84
{ { ShiftMask, ShiftMask, 0 },
86
mapSize(map2Level), /* map_count */
90
{ { ShiftMask|LockMask, ShiftMask|LockMask, 0 },
92
mapSize(mapAlpha), /* map_count */
96
{ { ShiftMask, ShiftMask, NL_VMOD_MASK },
98
mapSize(mapKeypad), /* map_count */
105
#if NeedFunctionPrototypes
106
XkbInitCanonicalKeyTypes(XkbDescPtr xkb,unsigned which,int keypadVMod)
108
XkbInitCanonicalKeyTypes(xkb,which,keypadVMod)
115
XkbKeyTypePtr from,to;
120
rtrn= XkbAllocClientMap(xkb,XkbKeyTypesMask,XkbNumRequiredTypes);
124
if ((which&XkbAllRequiredTypes)==0)
127
from= canonicalTypes;
129
if (which&XkbOneLevelMask)
130
rtrn= XkbCopyKeyType(&from[XkbOneLevelIndex],&to[XkbOneLevelIndex]);
131
if ((which&XkbTwoLevelMask)&&(rtrn==Success))
132
rtrn= XkbCopyKeyType(&from[XkbTwoLevelIndex],&to[XkbTwoLevelIndex]);
133
if ((which&XkbAlphabeticMask)&&(rtrn==Success))
134
rtrn= XkbCopyKeyType(&from[XkbAlphabeticIndex],&to[XkbAlphabeticIndex]);
135
if ((which&XkbKeypadMask)&&(rtrn==Success)) {
137
rtrn= XkbCopyKeyType(&from[XkbKeypadIndex],&to[XkbKeypadIndex]);
138
type= &to[XkbKeypadIndex];
139
if ((keypadVMod>=0)&&(keypadVMod<XkbNumVirtualMods)&&(rtrn==Success)) {
140
type->mods.vmods= (1<<keypadVMod);
141
type->map[0].active= True;
142
type->map[0].mods.mask= ShiftMask;
143
type->map[0].mods.real_mods= ShiftMask;
144
type->map[0].mods.vmods= 0;
145
type->map[0].level= 1;
146
type->map[1].active= False;
147
type->map[1].mods.mask= 0;
148
type->map[1].mods.real_mods= 0;
149
type->map[1].mods.vmods= (1<<keypadVMod);
150
type->map[1].level= 1;
156
/***====================================================================***/
158
#define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol)
159
#define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l))
162
#if NeedFunctionPrototypes
163
XkbKeyTypesForCoreSymbols( XkbDescPtr xkb,
166
unsigned int protected,
168
KeySym * xkb_syms_rtrn)
170
XkbKeyTypesForCoreSymbols(xkb,map_width,core_syms,protected,types_inout,
175
unsigned int protected;
177
KeySym * xkb_syms_rtrn;
182
int nSyms[XkbNumKbdGroups];
183
int nGroups,tmp,groupsWidth;
185
/* Section 12.2 of the protocol describes this process in more detail */
186
/* Step 1: find the # of symbols in the core mapping per group */
188
for (i=0;i<XkbNumKbdGroups;i++) {
189
if ((protected&(1<<i))&&(types_inout[i]<xkb->map->num_types)) {
190
nSyms[i]= xkb->map->types[types_inout[i]].num_levels;
191
if (nSyms[i]>groupsWidth)
192
groupsWidth= nSyms[i];
195
types_inout[i]= XkbTwoLevelIndex; /* don't really know, yet */
199
if (nSyms[XkbGroup1Index]<2)
200
nSyms[XkbGroup1Index]= 2;
201
if (nSyms[XkbGroup2Index]<2)
202
nSyms[XkbGroup2Index]= 2;
203
/* Step 2: Copy the symbols from the core ordering to XKB ordering */
204
/* symbols in the core are in the order: */
205
/* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */
206
xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,0)]= CORE_SYM(0);
207
xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,1)]= CORE_SYM(1);
208
for (i=2;i<nSyms[XkbGroup1Index];i++) {
209
xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,i)]= CORE_SYM(2+i);
211
xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,0)]= CORE_SYM(2);
212
xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,1)]= CORE_SYM(3);
213
tmp= 2+(nSyms[XkbGroup1Index]-2); /* offset to extra group2 syms */
214
for (i=2;i<nSyms[XkbGroup2Index];i++) {
215
xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,i)]= CORE_SYM(tmp+i);
217
tmp= nSyms[XkbGroup1Index]+nSyms[XkbGroup2Index];
218
if ((tmp>=map_width)&&
219
((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) {
220
nSyms[XkbGroup3Index]= 0;
221
nSyms[XkbGroup4Index]= 0;
226
for (i=0;i<nSyms[XkbGroup3Index];i++,tmp++) {
227
xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index,i)]= CORE_SYM(tmp);
229
if ((tmp<map_width)||(protected&XkbExplicitKeyType4Mask)) {
231
for (i=0;i<nSyms[XkbGroup4Index];i++,tmp++) {
232
xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index,i)]= CORE_SYM(tmp);
236
nSyms[XkbGroup4Index]= 0;
239
/* steps 3&4: alphanumeric expansion, assign canonical types */
241
for (i=0;i<nGroups;i++) {
243
syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
244
if ((nSyms[i]>1)&&(syms[1]==NoSymbol)&&(syms[0]!=NoSymbol)) {
246
XConvertCase(syms[0],&lower,&upper);
248
xkb_syms_rtrn[XKB_OFFSET(i,0)]= lower;
249
xkb_syms_rtrn[XKB_OFFSET(i,1)]= upper;
250
if ((protected&(1<<i))==0)
251
types_inout[i]= XkbAlphabeticIndex;
253
else if ((protected&(1<<i))==0) {
254
types_inout[i]= XkbOneLevelIndex;
258
if (((protected&(1<<i))==0)&&(types_inout[i]==XkbTwoLevelIndex)) {
259
if (IsKeypadKey(syms[0])||IsKeypadKey(syms[1]))
260
types_inout[i]= XkbKeypadIndex;
263
XConvertCase(syms[0],&lower,&upper);
264
if ((syms[0]==lower)&&(syms[1]==upper))
265
types_inout[i]= XkbAlphabeticIndex;
268
if (syms[0]==NoSymbol) {
271
for (n=1,found=False;(!found)&&(n<nSyms[i]);n++) {
272
found= (syms[n]!=NoSymbol);
278
/* step 5: squoosh out empty groups */
280
for (i=nGroups-1;i>=0;i--) {
281
if (((empty&(1<<i))==0)||(protected&(1<<i)))
289
/* step 6: replicate group 1 into group two, if necessary */
290
if ((nGroups>1)&&((empty&(XkbGroup1Mask|XkbGroup2Mask))==XkbGroup2Mask)) {
291
if ((protected&(XkbExplicitKeyType1Mask|XkbExplicitKeyType2Mask))==0) {
292
nSyms[XkbGroup2Index]= nSyms[XkbGroup1Index];
293
types_inout[XkbGroup2Index]= types_inout[XkbGroup1Index];
294
memcpy((char *)&xkb_syms_rtrn[2],(char *)xkb_syms_rtrn,
297
else if (types_inout[XkbGroup1Index]==types_inout[XkbGroup2Index]) {
298
memcpy((char *)&xkb_syms_rtrn[nSyms[XkbGroup1Index]],
299
(char *)xkb_syms_rtrn,
300
nSyms[XkbGroup1Index]*sizeof(KeySym));
304
/* step 7: check for all groups identical or all width 1 */
306
Bool sameType,allOneLevel;
307
allOneLevel= (xkb->map->types[types_inout[0]].num_levels==1);
308
for (i=1,sameType=True;(allOneLevel||sameType)&&(i<nGroups);i++) {
309
sameType=(sameType&&(types_inout[i]==types_inout[XkbGroup1Index]));
311
allOneLevel= (xkb->map->types[types_inout[i]].num_levels==1);
314
(!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){
317
for (i=1,identical=True;identical&&(i<nGroups);i++) {
319
syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
320
for (s=0;identical&&(s<nSyms[i]);s++) {
321
if (syms[s]!=xkb_syms_rtrn[s])
328
if (allOneLevel && (nGroups>1)) {
330
syms= &xkb_syms_rtrn[nSyms[XkbGroup1Index]];
331
nSyms[XkbGroup1Index]= 1;
332
for (i=1;i<nGroups;i++) {
333
xkb_syms_rtrn[i]= syms[0];
342
static XkbSymInterpretPtr
343
#if NeedFunctionPrototypes
344
_XkbFindMatchingInterp( XkbDescPtr xkb,
346
unsigned int real_mods,
349
_XkbFindMatchingInterp(xkb,sym,real_mods,level)
352
unsigned int real_mods;
357
XkbSymInterpretPtr interp,rtrn;
361
interp= xkb->compat->sym_interpret;
362
for (i=0;i<xkb->compat->num_si;i++,interp++) {
363
if ((interp->sym==NoSymbol)||(sym==interp->sym)) {
365
if ((level==0)||((interp->match&XkbSI_LevelOneOnly)==0))
368
switch (interp->match&XkbSI_OpMask) {
370
match= ((interp->mods&mods)==0);
372
case XkbSI_AnyOfOrNone:
373
match= ((mods==0)||((interp->mods&mods)!=0));
376
match= ((interp->mods&mods)!=0);
379
match= ((interp->mods&mods)==interp->mods);
382
match= (interp->mods==mods);
389
if (interp->sym!=NoSymbol) {
392
else if (rtrn==NULL) {
402
#if NeedFunctionPrototypes
403
_XkbAddKeyChange(KeyCode *pFirst,unsigned char *pNum,KeyCode newKey)
405
_XkbAddKeyChange(pFirst,pNum,newKey)
407
unsigned char * pNum;
413
last= (*pFirst)+(*pNum);
414
if (newKey<*pFirst) {
416
*pNum= (last-newKey)+1;
418
else if (newKey>last) {
419
*pNum= (last-*pFirst)+1;
425
#if NeedFunctionPrototypes
426
_XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
428
_XkbSetActionKeyMods(xkb,act,mods)
437
case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
438
if (act->mods.flags&XkbSA_UseModMapMods)
439
act->mods.real_mods= act->mods.mask= mods;
440
if ((tmp= XkbModActionVMods(&act->mods))!=0) {
441
XkbVirtualModsToReal(xkb,tmp,&tmp);
442
act->mods.mask|= tmp;
446
if (act->iso.flags&XkbSA_UseModMapMods)
447
act->iso.real_mods= act->iso.mask= mods;
448
if ((tmp= XkbModActionVMods(&act->iso))!=0) {
449
XkbVirtualModsToReal(xkb,tmp,&tmp);
460
#if NeedFunctionPrototypes
461
XkbApplyCompatMapToKey(XkbDescPtr xkb,KeyCode key,XkbChangesPtr changes)
463
XkbApplyCompatMapToKey(xkb,key,changes)
466
XkbChangesPtr changes;
470
unsigned char explicit,mods;
471
XkbSymInterpretPtr *interps,ibuf[IBUF_SIZE];
473
unsigned changed,tmp;
475
if ((!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)||
476
(!xkb->compat)||(!xkb->compat->sym_interpret)||
477
(key<xkb->min_key_code)||(key>xkb->max_key_code)) {
480
if (((!xkb->server)||(!xkb->server->key_acts))&&
481
(XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success)) {
484
changed= 0; /* keeps track of what has changed in _this_ call */
485
explicit= xkb->server->explicit[key];
486
if (explicit&XkbExplicitInterpretMask) /* nothing to do */
488
mods= (xkb->map->modmap?xkb->map->modmap[key]:0);
489
nSyms= XkbKeyNumSyms(xkb,key);
490
syms= XkbKeySymsPtr(xkb,key);
491
if (nSyms>IBUF_SIZE) {
492
interps= _XkbTypedCalloc(nSyms,XkbSymInterpretPtr);
502
for (n=0;n<nSyms;n++) {
503
unsigned level= (n%XkbKeyGroupsWidth(xkb,key));
505
if (syms[n]!=NoSymbol) {
506
interps[n]= _XkbFindMatchingInterp(xkb,syms[n],mods,level);
507
if (interps[n]&&interps[n]->act.type!=XkbSA_NoAction)
509
else interps[n]= NULL;
512
/* 1/28/96 (ef) -- XXX! WORKING HERE */
514
if (xkb->server->key_acts[key]!=0) {
515
xkb->server->key_acts[key]= 0;
516
changed|= XkbKeyActionsMask;
521
unsigned int new_vmodmask;
522
changed|= XkbKeyActionsMask;
523
pActs= XkbResizeKeyActions(xkb,key,nSyms);
527
for (n=0;n<nSyms;n++) {
531
pActs[n]= *((XkbAction *)&interps[n]->act);
532
if ((n==0)||((interps[n]->match&XkbSI_LevelOneOnly)==0)) {
534
if (interps[n]->virtual_mod!=XkbNoModifier)
535
new_vmodmask|= (1<<interps[n]->virtual_mod);
538
_XkbSetActionKeyMods(xkb,&pActs[n],effMods);
540
else pActs[n].type= XkbSA_NoAction;
542
if (((explicit&XkbExplicitVModMapMask)==0)&&
543
(xkb->server->vmodmap[key]!=new_vmodmask)) {
544
changed|= XkbVirtualModMapMask;
545
xkb->server->vmodmap[key]= new_vmodmask;
548
if ((interps[0]->flags&XkbSI_LockingKey)&&
549
((explicit&XkbExplicitBehaviorMask)==0)) {
550
xkb->server->behaviors[key].type= XkbKB_Lock;
551
changed|= XkbKeyBehaviorsMask;
553
if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
555
old= xkb->ctrls->per_key_repeat[key/8];
556
if (interps[0]->flags&XkbSI_AutoRepeat)
557
xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
558
else xkb->ctrls->per_key_repeat[key/8]&= ~(1<<(key%8));
559
if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
560
changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
564
if ((!found)||(interps[0]==NULL)) {
565
if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
567
old= xkb->ctrls->per_key_repeat[key/8];
568
#ifdef RETURN_SHOULD_REPEAT
569
if (*XkbKeySymsPtr(xkb,key) != XK_Return)
571
xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
572
if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
573
changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
575
if (((explicit&XkbExplicitBehaviorMask)==0)&&
576
(xkb->server->behaviors[key].type==XkbKB_Lock)) {
577
xkb->server->behaviors[key].type= XkbKB_Default;
578
changed|= XkbKeyBehaviorsMask;
584
tmp= (changed&mc->changed);
585
if (tmp&XkbKeyActionsMask)
586
_XkbAddKeyChange(&mc->first_key_act,&mc->num_key_acts,key);
587
else if (changed&XkbKeyActionsMask) {
588
mc->changed|= XkbKeyActionsMask;
589
mc->first_key_act= key;
592
if (tmp&XkbKeyBehaviorsMask) {
593
_XkbAddKeyChange(&mc->first_key_behavior,&mc->num_key_behaviors,
596
else if (changed&XkbKeyBehaviorsMask) {
597
mc->changed|= XkbKeyBehaviorsMask;
598
mc->first_key_behavior= key;
599
mc->num_key_behaviors= 1;
601
if (tmp&XkbVirtualModMapMask)
602
_XkbAddKeyChange(&mc->first_vmodmap_key,&mc->num_vmodmap_keys,key);
603
else if (changed&XkbVirtualModMapMask) {
604
mc->changed|= XkbVirtualModMapMask;
605
mc->first_vmodmap_key= key;
606
mc->num_vmodmap_keys= 1;
608
mc->changed|= changed;
616
#if NeedFunctionPrototypes
617
XkbUpdateMapFromCore( XkbDescPtr xkb,
621
KeySym * core_keysyms,
622
XkbChangesPtr changes)
624
XkbUpdateMapFromCore(xkb,first_key,num_keys,map_width,core_keysyms,changes)
629
KeySym * core_keysyms;
630
XkbChangesPtr changes;
633
register int key,last_key;
636
syms= &core_keysyms[(first_key-xkb->min_key_code)*map_width];
638
if (changes->map.changed&XkbKeySymsMask) {
639
_XkbAddKeyChange(&changes->map.first_key_sym,
640
&changes->map.num_key_syms,first_key);
642
_XkbAddKeyChange(&changes->map.first_key_sym,
643
&changes->map.num_key_syms,
644
first_key+num_keys-1);
648
changes->map.changed|= XkbKeySymsMask;
649
changes->map.first_key_sym= first_key;
650
changes->map.num_key_syms= num_keys;
653
last_key= first_key+num_keys-1;
654
for (key=first_key;key<=last_key;key++,syms+= map_width) {
657
KeySym tsyms[XkbMaxSymsPerKey];
658
int types[XkbNumKbdGroups];
661
explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask;
662
types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
663
types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index);
664
types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index);
665
types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index);
666
nG= XkbKeyTypesForCoreSymbols(xkb,map_width,syms,explicit,types,tsyms);
670
XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc);
671
memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms,
672
XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
673
XkbApplyCompatMapToKey(xkb,key,changes);
676
if ((xkb->server->vmods!=NULL)&&(xkb->map->modmap!=NULL)&&(changes)&&
677
(changes->map.changed&(XkbVirtualModMapMask|XkbModifierMapMask))) {
678
unsigned char newVMods[XkbNumVirtualMods];
679
register unsigned bit,i;
682
bzero(newVMods,XkbNumVirtualMods);
684
for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
685
if (xkb->server->vmodmap[key]==0)
687
for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
688
if (bit&xkb->server->vmodmap[key]) {
690
newVMods[i]|= xkb->map->modmap[key];
694
for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
695
if ((bit&present)&&(newVMods[i]!=xkb->server->vmods[i])) {
696
changes->map.changed|= XkbVirtualModsMask;
697
changes->map.vmods|= bit;
698
xkb->server->vmods[i]= newVMods[i];
702
if (changes && (changes->map.changed&XkbVirtualModsMask))
703
XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes);
708
#if NeedFunctionPrototypes
709
XkbChangeTypesOfKey( XkbDescPtr xkb,
714
XkbMapChangesPtr changes)
716
XkbChangeTypesOfKey(xkb,key,nGroups,groups,newTypesIn,changes)
722
XkbMapChangesPtr changes;
725
XkbKeyTypePtr pOldType,pNewType;
727
int width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups];
729
if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) ||
730
(!xkb->map->types)||(!newTypes)||((groups&XkbAllGroupsMask)==0)||
731
(nGroups>XkbNumKbdGroups)) {
735
for (i=0;i<XkbNumKbdGroups;i++) {
736
xkb->map->key_sym_map[key].kt_index[i]= XkbOneLevelIndex;
738
i= xkb->map->key_sym_map[key].group_info;
739
i= XkbSetNumGroups(i,0);
740
xkb->map->key_sym_map[key].group_info= i;
741
XkbResizeKeySyms(xkb,key,0);
745
nOldGroups= XkbKeyNumGroups(xkb,key);
746
oldWidth= XkbKeyGroupsWidth(xkb,key);
747
for (width=i=0;i<nGroups;i++) {
749
newTypes[i]= newTypesIn[i];
750
else if (i<nOldGroups)
751
newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,i);
752
else if (nOldGroups>0)
753
newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
754
else newTypes[i]= XkbTwoLevelIndex;
755
if (newTypes[i]>xkb->map->num_types)
757
pNewType= &xkb->map->types[newTypes[i]];
758
if (pNewType->num_levels>width)
759
width= pNewType->num_levels;
761
if ((xkb->ctrls)&&(nGroups>xkb->ctrls->num_groups))
762
xkb->ctrls->num_groups= nGroups;
763
if ((width!=oldWidth)||(nGroups!=nOldGroups)) {
764
KeySym oldSyms[XkbMaxSymsPerKey],*pSyms;
768
pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
770
i= xkb->map->key_sym_map[key].group_info;
771
i= XkbSetNumGroups(i,nGroups);
772
xkb->map->key_sym_map[key].group_info= i;
773
xkb->map->key_sym_map[key].width= width;
774
for (i=0;i<nGroups;i++) {
775
xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
781
pSyms= XkbKeySymsPtr(xkb,key);
782
memcpy(oldSyms,pSyms,XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
783
pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
786
bzero(pSyms,width*nGroups*sizeof(KeySym));
787
for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
788
pOldType= XkbKeyKeyType(xkb,key,i);
789
pNewType= &xkb->map->types[newTypes[i]];
790
if (pNewType->num_levels>pOldType->num_levels)
791
nCopy= pOldType->num_levels;
792
else nCopy= pNewType->num_levels;
793
memcpy(&pSyms[i*width],&oldSyms[i*oldWidth],nCopy*sizeof(KeySym));
795
if (XkbKeyHasActions(xkb,key)) {
796
XkbAction oldActs[XkbMaxSymsPerKey],*pActs;
797
pActs= XkbKeyActionsPtr(xkb,key);
798
memcpy(oldActs,pActs,XkbKeyNumSyms(xkb,key)*sizeof(XkbAction));
799
pActs= XkbResizeKeyActions(xkb,key,width*nGroups);
802
bzero(pActs,width*nGroups*sizeof(XkbAction));
803
for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
804
pOldType= XkbKeyKeyType(xkb,key,i);
805
pNewType= &xkb->map->types[newTypes[i]];
806
if (pNewType->num_levels>pOldType->num_levels)
807
nCopy= pOldType->num_levels;
808
else nCopy= pNewType->num_levels;
809
memcpy(&pActs[i*width],&oldActs[i*oldWidth],
810
nCopy*sizeof(XkbAction));
813
i= xkb->map->key_sym_map[key].group_info;
814
i= XkbSetNumGroups(i,nGroups);
815
xkb->map->key_sym_map[key].group_info= i;
816
xkb->map->key_sym_map[key].width= width;
819
for (i=0;i<nGroups;i++) {
820
xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
821
if (xkb->map->types[newTypes[i]].num_levels>width)
822
width= xkb->map->types[newTypes[i]].num_levels;
824
xkb->map->key_sym_map[key].width= width;
826
if (changes->changed&XkbKeySymsMask) {
827
_XkbAddKeyChange(&changes->first_key_sym,&changes->num_key_syms,
831
changes->changed|= XkbKeySymsMask;
832
changes->first_key_sym= key;
833
changes->num_key_syms= 1;
839
/***====================================================================***/
842
#if NeedFunctionPrototypes
843
XkbVirtualModsToReal(XkbDescPtr xkb,unsigned virtual_mask,unsigned *mask_rtrn)
845
XkbVirtualModsToReal(xkb,virtual_mask,mask_rtrn)
847
unsigned virtual_mask;
848
unsigned * mask_rtrn;
852
register unsigned mask;
856
if (virtual_mask==0) {
860
if (xkb->server==NULL)
862
for (i=mask=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
863
if (virtual_mask&bit)
864
mask|= xkb->server->vmods[i];
870
/***====================================================================***/
873
#if NeedFunctionPrototypes
874
XkbUpdateActionVirtualMods(XkbDescPtr xkb,XkbAction *act,unsigned changed)
876
XkbUpdateActionVirtualMods(xkb,act,changed)
885
case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
886
if (((tmp= XkbModActionVMods(&act->mods))&changed)!=0) {
887
XkbVirtualModsToReal(xkb,tmp,&tmp);
888
act->mods.mask= act->mods.real_mods;
889
act->mods.mask|= tmp;
894
if ((((tmp= XkbModActionVMods(&act->iso))!=0)&changed)!=0) {
895
XkbVirtualModsToReal(xkb,tmp,&tmp);
896
act->iso.mask= act->iso.real_mods;
906
#if NeedFunctionPrototypes
907
XkbUpdateKeyTypeVirtualMods( XkbDescPtr xkb,
909
unsigned int changed,
910
XkbChangesPtr changes)
912
XkbUpdateKeyTypeVirtualMods(xkb,type,changed,changes)
915
unsigned int changed;
916
XkbChangesPtr changes;
919
register unsigned int i;
922
XkbVirtualModsToReal(xkb,type->mods.vmods,&mask);
923
type->mods.mask= type->mods.real_mods|mask;
924
if ((type->map_count>0)&&(type->mods.vmods!=0)) {
925
XkbKTMapEntryPtr entry;
926
for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
927
if (entry->mods.vmods!=0) {
928
XkbVirtualModsToReal(xkb,entry->mods.vmods,&mask);
929
entry->mods.mask=entry->mods.real_mods|mask;
930
/* entry is active if vmods are bound*/
931
entry->active= (mask!=0);
933
else entry->active= 1;
938
type_ndx= type-xkb->map->types;
939
if ((type_ndx<0)||(type_ndx>xkb->map->num_types))
941
if (changes->map.changed&XkbKeyTypesMask) {
943
last= changes->map.first_type+changes->map.num_types-1;
944
if (type_ndx<changes->map.first_type) {
945
changes->map.first_type= type_ndx;
946
changes->map.num_types= (last-type_ndx)+1;
948
else if (type_ndx>last) {
949
changes->map.num_types= (type_ndx-changes->map.first_type)+1;
953
changes->map.changed|= XkbKeyTypesMask;
954
changes->map.first_type= type_ndx;
955
changes->map.num_types= 1;
962
#if NeedFunctionPrototypes
963
XkbApplyVirtualModChanges(XkbDescPtr xkb,unsigned changed,XkbChangesPtr changes)
965
XkbApplyVirtualModChanges(xkb,changed,changes)
968
XkbChangesPtr changes;
972
unsigned int checkState = 0;
974
if ((!xkb) || (!xkb->map) || (changed==0))
976
for (i=0;i<xkb->map->num_types;i++) {
977
if (xkb->map->types[i].mods.vmods & changed)
978
XkbUpdateKeyTypeVirtualMods(xkb,&xkb->map->types[i],changed,changes);
980
if (changed&xkb->ctrls->internal.vmods) {
981
unsigned int newMask;
982
XkbVirtualModsToReal(xkb,xkb->ctrls->internal.vmods,&newMask);
983
newMask|= xkb->ctrls->internal.real_mods;
984
if (xkb->ctrls->internal.mask!=newMask) {
985
xkb->ctrls->internal.mask= newMask;
987
changes->ctrls.changed_ctrls|= XkbInternalModsMask;
992
if (changed&xkb->ctrls->ignore_lock.vmods) {
993
unsigned int newMask;
994
XkbVirtualModsToReal(xkb,xkb->ctrls->ignore_lock.vmods,&newMask);
995
newMask|= xkb->ctrls->ignore_lock.real_mods;
996
if (xkb->ctrls->ignore_lock.mask!=newMask) {
997
xkb->ctrls->ignore_lock.mask= newMask;
999
changes->ctrls.changed_ctrls|= XkbIgnoreLockModsMask;
1004
if (xkb->indicators!=NULL) {
1005
XkbIndicatorMapPtr map;
1006
map= &xkb->indicators->maps[0];
1007
for (i=0;i<XkbNumIndicators;i++,map++) {
1008
if (map->mods.vmods&changed) {
1009
unsigned int newMask;
1010
XkbVirtualModsToReal(xkb,map->mods.vmods,&newMask);
1011
newMask|= map->mods.real_mods;
1012
if (newMask!=map->mods.mask) {
1013
map->mods.mask= newMask;
1015
changes->indicators.map_changes|= (1<<i);
1022
if (xkb->compat!=NULL) {
1023
XkbCompatMapPtr compat;
1024
compat= xkb->compat;
1025
for (i=0;i<XkbNumKbdGroups;i++) {
1026
unsigned int newMask;
1027
XkbVirtualModsToReal(xkb,compat->groups[i].vmods,&newMask);
1028
newMask|= compat->groups[i].real_mods;
1029
if (compat->groups[i].mask!=newMask) {
1030
compat->groups[i].mask= newMask;
1032
changes->compat.changed_groups|= (1<<i);
1038
if (xkb->map && xkb->server) {
1039
int highChange = 0, lowChange = -1;
1040
for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
1041
if (XkbKeyHasActions(xkb,i)) {
1042
register XkbAction *pAct;
1045
pAct= XkbKeyActionsPtr(xkb,i);
1046
for (n=XkbKeyNumActions(xkb,i);n>0;n--,pAct++) {
1047
if ((pAct->type!=XkbSA_NoAction)&&
1048
XkbUpdateActionVirtualMods(xkb,pAct,changed)) {
1056
if (changes && (lowChange>0)) { /* something changed */
1057
if (changes->map.changed&XkbKeyActionsMask) {
1059
if (changes->map.first_key_act<lowChange)
1060
lowChange= changes->map.first_key_act;
1061
last= changes->map.first_key_act+changes->map.num_key_acts-1;
1062
if (last>highChange)
1065
changes->map.changed|= XkbKeyActionsMask;
1066
changes->map.first_key_act= lowChange;
1067
changes->map.num_key_acts= (highChange-lowChange)+1;