~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/lib/X11/XKBMisc.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.
 
4
 
 
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.
 
16
 
 
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.
 
25
 
 
26
********************************************************/
 
27
/* $XFree86: xc/lib/X11/XKBMisc.c,v 3.5 2001/10/28 03:32:33 tsi Exp $ */
 
28
 
 
29
#ifndef XKB_IN_SERVER
 
30
 
 
31
#include <stdio.h>
 
32
#define NEED_REPLIES
 
33
#define NEED_EVENTS
 
34
#include "Xlibint.h"
 
35
#include <X11/extensions/XKBproto.h>
 
36
#include <X11/keysym.h>
 
37
#include "XKBlibint.h"
 
38
 
 
39
#else 
 
40
 
 
41
#include <stdio.h>
 
42
#include "X.h"
 
43
#define NEED_EVENTS
 
44
#define NEED_REPLIES
 
45
#include "Xproto.h"
 
46
#include "misc.h"
 
47
#include "inputstr.h"
 
48
#include <X11/keysym.h>
 
49
#define XKBSRV_NEED_FILE_FUNCS
 
50
#include "XKBsrv.h"
 
51
 
 
52
#endif /* XKB_IN_SERVER */
 
53
 
 
54
/***====================================================================***/
 
55
 
 
56
#define mapSize(m)      (sizeof(m)/sizeof(XkbKTMapEntryRec))
 
57
static  XkbKTMapEntryRec map2Level[]= { 
 
58
  { True, ShiftMask, {1, ShiftMask, 0} }
 
59
};
 
60
 
 
61
static  XkbKTMapEntryRec mapAlpha[]= { 
 
62
  { True, ShiftMask, { 1, ShiftMask, 0 } },
 
63
  { True, LockMask,  { 0,  LockMask, 0 } }
 
64
};
 
65
 
 
66
static  XkbModsRec preAlpha[]= {
 
67
        {        0,        0, 0 },
 
68
        { LockMask, LockMask, 0 }
 
69
};
 
70
 
 
71
#define NL_VMOD_MASK    0
 
72
static  XkbKTMapEntryRec mapKeypad[]= { 
 
73
        { True, ShiftMask, { 1, ShiftMask,            0 } },
 
74
        { False,        0, { 1,         0, NL_VMOD_MASK } }
 
75
};
 
76
 
 
77
static  XkbKeyTypeRec   canonicalTypes[XkbNumRequiredTypes] = {
 
78
        { { 0, 0, 0 }, 
 
79
          1,    /* num_levels */
 
80
          0,    /* map_count */
 
81
          NULL,         NULL,
 
82
          None,         NULL
 
83
        },
 
84
        { { ShiftMask, ShiftMask, 0 }, 
 
85
          2,    /* num_levels */
 
86
          mapSize(map2Level),   /* map_count */
 
87
          map2Level,    NULL,
 
88
          None,         NULL
 
89
        },
 
90
        { { ShiftMask|LockMask, ShiftMask|LockMask, 0 }, 
 
91
          2,                            /* num_levels */
 
92
          mapSize(mapAlpha),            /* map_count */
 
93
          mapAlpha,     preAlpha,
 
94
          None,         NULL
 
95
        },
 
96
        { { ShiftMask, ShiftMask, NL_VMOD_MASK },
 
97
          2,                            /* num_levels */
 
98
          mapSize(mapKeypad),           /* map_count */
 
99
          mapKeypad,    NULL,
 
100
          None,         NULL
 
101
        }
 
102
};
 
103
 
 
104
Status
 
105
#if NeedFunctionPrototypes
 
106
XkbInitCanonicalKeyTypes(XkbDescPtr xkb,unsigned which,int keypadVMod)
 
107
#else
 
108
XkbInitCanonicalKeyTypes(xkb,which,keypadVMod)
 
109
    XkbDescPtr          xkb;
 
110
    unsigned            which;
 
111
    int                 keypadVMod;
 
112
#endif
 
113
{
 
114
XkbClientMapPtr map;
 
115
XkbKeyTypePtr   from,to;
 
116
Status          rtrn;
 
117
 
 
118
    if (!xkb)
 
119
        return BadMatch;
 
120
    rtrn= XkbAllocClientMap(xkb,XkbKeyTypesMask,XkbNumRequiredTypes);
 
121
    if (rtrn!=Success)
 
122
        return rtrn;
 
123
    map= xkb->map;
 
124
    if ((which&XkbAllRequiredTypes)==0)
 
125
        return Success;
 
126
    rtrn= Success;
 
127
    from= canonicalTypes;
 
128
    to= map->types;
 
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)) {
 
136
        XkbKeyTypePtr type;
 
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;
 
151
        }
 
152
    }
 
153
    return Success;
 
154
}
 
155
 
 
156
/***====================================================================***/
 
157
 
 
158
#define CORE_SYM(i)     (i<map_width?core_syms[i]:NoSymbol)
 
159
#define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l))
 
160
 
 
161
int
 
162
#if NeedFunctionPrototypes
 
163
XkbKeyTypesForCoreSymbols(      XkbDescPtr      xkb,
 
164
                                int             map_width,
 
165
                                KeySym *        core_syms,
 
166
                                unsigned int    protected,
 
167
                                int *           types_inout,
 
168
                                KeySym *        xkb_syms_rtrn)
 
169
#else
 
170
XkbKeyTypesForCoreSymbols(xkb,map_width,core_syms,protected,types_inout,
 
171
                                                                xkb_syms_rtrn)
 
172
    XkbDescPtr          xkb;
 
173
    int                 map_width;
 
174
    KeySym *            core_syms;
 
175
    unsigned int        protected;
 
176
    int *               types_inout;
 
177
    KeySym *            xkb_syms_rtrn;
 
178
#endif
 
179
{
 
180
register int    i;
 
181
unsigned int    empty;
 
182
int             nSyms[XkbNumKbdGroups];
 
183
int             nGroups,tmp,groupsWidth;
 
184
 
 
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 */
 
187
    groupsWidth= 2;
 
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];
 
193
        }
 
194
        else {
 
195
            types_inout[i]= XkbTwoLevelIndex;   /* don't really know, yet */
 
196
            nSyms[i]= 2;
 
197
        }
 
198
    }
 
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);
 
210
    }
 
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);
 
216
    }
 
217
    tmp= nSyms[XkbGroup1Index]+nSyms[XkbGroup2Index];
 
218
    if ((tmp>=map_width)&&
 
219
         ((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) {
 
220
        nSyms[XkbGroup3Index]= 0;
 
221
        nSyms[XkbGroup4Index]= 0;
 
222
        nGroups= 2;
 
223
    }
 
224
    else {
 
225
        nGroups= 3;
 
226
        for (i=0;i<nSyms[XkbGroup3Index];i++,tmp++) {
 
227
            xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index,i)]= CORE_SYM(tmp);
 
228
        }
 
229
        if ((tmp<map_width)||(protected&XkbExplicitKeyType4Mask)) {
 
230
            nGroups= 4;
 
231
            for (i=0;i<nSyms[XkbGroup4Index];i++,tmp++) {
 
232
                xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index,i)]= CORE_SYM(tmp);
 
233
            }
 
234
        }
 
235
        else {
 
236
            nSyms[XkbGroup4Index]= 0;
 
237
        }
 
238
    }
 
239
    /* steps 3&4: alphanumeric expansion,  assign canonical types */
 
240
    empty= 0;
 
241
    for (i=0;i<nGroups;i++) {
 
242
        KeySym *syms;
 
243
        syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
 
244
        if ((nSyms[i]>1)&&(syms[1]==NoSymbol)&&(syms[0]!=NoSymbol)) {
 
245
            KeySym upper,lower;
 
246
            XConvertCase(syms[0],&lower,&upper);
 
247
            if (upper!=lower) {
 
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;
 
252
            }
 
253
            else if ((protected&(1<<i))==0) {
 
254
                types_inout[i]= XkbOneLevelIndex;
 
255
        /*      nSyms[i]=       1;*/
 
256
            }
 
257
        }
 
258
        if (((protected&(1<<i))==0)&&(types_inout[i]==XkbTwoLevelIndex)) {
 
259
            if (IsKeypadKey(syms[0])||IsKeypadKey(syms[1]))
 
260
                types_inout[i]= XkbKeypadIndex;
 
261
            else {
 
262
                KeySym upper,lower;
 
263
                XConvertCase(syms[0],&lower,&upper);
 
264
                if ((syms[0]==lower)&&(syms[1]==upper))
 
265
                    types_inout[i]= XkbAlphabeticIndex;
 
266
            }
 
267
        }
 
268
        if (syms[0]==NoSymbol) {
 
269
            register int n;
 
270
            Bool        found;
 
271
            for (n=1,found=False;(!found)&&(n<nSyms[i]);n++) {
 
272
                found= (syms[n]!=NoSymbol);
 
273
            }
 
274
            if (!found)
 
275
                empty|= (1<<i);
 
276
        }
 
277
    }
 
278
    /* step 5: squoosh out empty groups */
 
279
    if (empty) {
 
280
        for (i=nGroups-1;i>=0;i--) {
 
281
            if (((empty&(1<<i))==0)||(protected&(1<<i)))
 
282
                break;
 
283
            nGroups--;
 
284
        }
 
285
    }
 
286
    if (nGroups<1)
 
287
        return 0;
 
288
 
 
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,
 
295
                                                        2*sizeof(KeySym));
 
296
        }
 
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));
 
301
        }
 
302
    }
 
303
 
 
304
    /* step 7: check for all groups identical or all width 1 */
 
305
    if (nGroups>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]));
 
310
            if (allOneLevel)
 
311
                allOneLevel= (xkb->map->types[types_inout[i]].num_levels==1);
 
312
        }
 
313
        if ((sameType)&&
 
314
            (!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){
 
315
            register int s;
 
316
            Bool        identical;
 
317
            for (i=1,identical=True;identical&&(i<nGroups);i++) {
 
318
                KeySym *syms;
 
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])
 
322
                        identical= False;
 
323
                }
 
324
            }
 
325
            if (identical)
 
326
                nGroups= 1;
 
327
        }
 
328
        if (allOneLevel && (nGroups>1)) {
 
329
            KeySym *syms;
 
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];
 
334
                syms+= nSyms[i];
 
335
                nSyms[i]= 1;
 
336
            }
 
337
        }
 
338
    }
 
339
    return nGroups;
 
340
}
 
341
 
 
342
static XkbSymInterpretPtr
 
343
#if NeedFunctionPrototypes
 
344
_XkbFindMatchingInterp( XkbDescPtr      xkb,
 
345
                        KeySym          sym,
 
346
                        unsigned int    real_mods,
 
347
                        unsigned int    level)
 
348
#else
 
349
_XkbFindMatchingInterp(xkb,sym,real_mods,level)
 
350
    XkbDescPtr          xkb;
 
351
    KeySym              sym;
 
352
    unsigned int        real_mods;
 
353
    unsigned int        level;
 
354
#endif
 
355
{
 
356
register unsigned        i;
 
357
XkbSymInterpretPtr       interp,rtrn;
 
358
CARD8                    mods;
 
359
 
 
360
    rtrn= NULL;
 
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)) {
 
364
            int match;
 
365
            if ((level==0)||((interp->match&XkbSI_LevelOneOnly)==0))
 
366
                 mods= real_mods;
 
367
            else mods= 0;
 
368
            switch (interp->match&XkbSI_OpMask) {
 
369
                case XkbSI_NoneOf:
 
370
                    match= ((interp->mods&mods)==0);
 
371
                    break;
 
372
                case XkbSI_AnyOfOrNone:
 
373
                    match= ((mods==0)||((interp->mods&mods)!=0));
 
374
                    break;
 
375
                case XkbSI_AnyOf:
 
376
                    match= ((interp->mods&mods)!=0);
 
377
                    break;
 
378
                case XkbSI_AllOf:
 
379
                    match= ((interp->mods&mods)==interp->mods);
 
380
                    break;
 
381
                case XkbSI_Exactly:
 
382
                    match= (interp->mods==mods);
 
383
                    break;
 
384
                default:
 
385
                    match= 0;
 
386
                    break;
 
387
            }
 
388
            if (match) {
 
389
                if (interp->sym!=NoSymbol) {
 
390
                    return interp;
 
391
                }
 
392
                else if (rtrn==NULL) {
 
393
                    rtrn= interp;
 
394
                }
 
395
            }
 
396
        }
 
397
    }
 
398
    return rtrn;
 
399
}
 
400
 
 
401
static void
 
402
#if NeedFunctionPrototypes
 
403
_XkbAddKeyChange(KeyCode *pFirst,unsigned char *pNum,KeyCode newKey)
 
404
#else
 
405
_XkbAddKeyChange(pFirst,pNum,newKey)
 
406
    KeyCode *           pFirst;
 
407
    unsigned char *     pNum;
 
408
    KeyCode             newKey;
 
409
#endif
 
410
{
 
411
KeyCode last;
 
412
 
 
413
    last= (*pFirst)+(*pNum);
 
414
    if (newKey<*pFirst) {
 
415
        *pFirst= newKey;
 
416
        *pNum= (last-newKey)+1;
 
417
    }
 
418
    else if (newKey>last) {
 
419
        *pNum= (last-*pFirst)+1;
 
420
    }
 
421
    return;
 
422
}
 
423
 
 
424
static void
 
425
#if NeedFunctionPrototypes
 
426
_XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
 
427
#else
 
428
_XkbSetActionKeyMods(xkb,act,mods)
 
429
    XkbDescPtr  xkb;
 
430
    XkbAction * act;
 
431
    unsigned    mods;
 
432
#endif
 
433
{
 
434
unsigned        tmp;
 
435
 
 
436
    switch (act->type) {
 
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;
 
443
            }
 
444
            break;
 
445
        case XkbSA_ISOLock:
 
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);
 
450
                act->iso.mask|= tmp;
 
451
            }
 
452
            break;
 
453
    }
 
454
    return;
 
455
}
 
456
 
 
457
#define IBUF_SIZE       8
 
458
 
 
459
Bool
 
460
#if NeedFunctionPrototypes
 
461
XkbApplyCompatMapToKey(XkbDescPtr xkb,KeyCode key,XkbChangesPtr changes)
 
462
#else
 
463
XkbApplyCompatMapToKey(xkb,key,changes)
 
464
    XkbDescPtr          xkb;
 
465
    KeyCode             key;
 
466
    XkbChangesPtr       changes;
 
467
#endif
 
468
{
 
469
KeySym *                syms;
 
470
unsigned char           explicit,mods;
 
471
XkbSymInterpretPtr      *interps,ibuf[IBUF_SIZE]; 
 
472
int                     n,nSyms,found;
 
473
unsigned                changed,tmp;
 
474
 
 
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)) {
 
478
        return False;
 
479
    }
 
480
    if (((!xkb->server)||(!xkb->server->key_acts))&&
 
481
                (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success)) {
 
482
        return False;
 
483
    }
 
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 */
 
487
        return True;
 
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);
 
493
        if (interps==NULL) {
 
494
            interps= ibuf;
 
495
            nSyms= IBUF_SIZE;
 
496
        }
 
497
    }
 
498
    else {
 
499
        interps= ibuf;
 
500
    }
 
501
    found= 0;
 
502
    for (n=0;n<nSyms;n++) {
 
503
        unsigned level= (n%XkbKeyGroupsWidth(xkb,key));
 
504
        interps[n]= NULL;
 
505
        if (syms[n]!=NoSymbol) {
 
506
            interps[n]= _XkbFindMatchingInterp(xkb,syms[n],mods,level);
 
507
            if (interps[n]&&interps[n]->act.type!=XkbSA_NoAction)
 
508
                found++;
 
509
            else interps[n]= NULL;
 
510
        }
 
511
    }
 
512
    /* 1/28/96 (ef) -- XXX! WORKING HERE */
 
513
    if (!found) {
 
514
        if (xkb->server->key_acts[key]!=0) {
 
515
            xkb->server->key_acts[key]= 0;
 
516
            changed|= XkbKeyActionsMask;
 
517
        }
 
518
    }
 
519
    else {
 
520
        XkbAction *pActs;
 
521
        unsigned int    new_vmodmask;
 
522
        changed|= XkbKeyActionsMask;
 
523
        pActs= XkbResizeKeyActions(xkb,key,nSyms);
 
524
        if (!pActs)
 
525
            return False;
 
526
        new_vmodmask= 0;
 
527
        for (n=0;n<nSyms;n++) {
 
528
            if (interps[n]) {
 
529
                unsigned effMods;
 
530
 
 
531
                pActs[n]= *((XkbAction *)&interps[n]->act);
 
532
                if ((n==0)||((interps[n]->match&XkbSI_LevelOneOnly)==0)) {
 
533
                     effMods= mods;
 
534
                     if (interps[n]->virtual_mod!=XkbNoModifier)
 
535
                        new_vmodmask|= (1<<interps[n]->virtual_mod);
 
536
                }
 
537
                else effMods= 0;
 
538
                _XkbSetActionKeyMods(xkb,&pActs[n],effMods);
 
539
            }
 
540
            else pActs[n].type= XkbSA_NoAction;
 
541
        }
 
542
        if (((explicit&XkbExplicitVModMapMask)==0)&&
 
543
                                (xkb->server->vmodmap[key]!=new_vmodmask)) {
 
544
            changed|= XkbVirtualModMapMask;
 
545
            xkb->server->vmodmap[key]= new_vmodmask;
 
546
        }
 
547
        if (interps[0]) {
 
548
            if ((interps[0]->flags&XkbSI_LockingKey)&&
 
549
                                ((explicit&XkbExplicitBehaviorMask)==0)) {
 
550
                xkb->server->behaviors[key].type= XkbKB_Lock;
 
551
                changed|= XkbKeyBehaviorsMask;
 
552
            }
 
553
            if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
 
554
                CARD8 old;
 
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;
 
561
            }
 
562
        }
 
563
    }
 
564
    if ((!found)||(interps[0]==NULL)) {
 
565
        if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
 
566
            CARD8 old;
 
567
            old= xkb->ctrls->per_key_repeat[key/8];
 
568
#ifdef RETURN_SHOULD_REPEAT
 
569
            if (*XkbKeySymsPtr(xkb,key) != XK_Return)
 
570
#endif
 
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;
 
574
        }
 
575
        if (((explicit&XkbExplicitBehaviorMask)==0)&&
 
576
                (xkb->server->behaviors[key].type==XkbKB_Lock)) {
 
577
                xkb->server->behaviors[key].type= XkbKB_Default;
 
578
                changed|= XkbKeyBehaviorsMask;
 
579
        }
 
580
    }
 
581
    if (changes) {
 
582
        XkbMapChangesPtr        mc;
 
583
        mc= &changes->map;
 
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;
 
590
            mc->num_key_acts= 1;
 
591
        }
 
592
        if (tmp&XkbKeyBehaviorsMask) {
 
593
            _XkbAddKeyChange(&mc->first_key_behavior,&mc->num_key_behaviors,
 
594
                                                                        key);
 
595
        }
 
596
        else if (changed&XkbKeyBehaviorsMask) {
 
597
            mc->changed|= XkbKeyBehaviorsMask;
 
598
            mc->first_key_behavior= key;
 
599
            mc->num_key_behaviors= 1;
 
600
        }
 
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;
 
607
        }
 
608
        mc->changed|= changed;
 
609
    }
 
610
    if (interps!=ibuf)
 
611
        _XkbFree(interps);
 
612
    return True;
 
613
}
 
614
 
 
615
Bool
 
616
#if NeedFunctionPrototypes
 
617
XkbUpdateMapFromCore(   XkbDescPtr      xkb,
 
618
                        KeyCode         first_key,
 
619
                        int             num_keys,
 
620
                        int             map_width,
 
621
                        KeySym *        core_keysyms,
 
622
                        XkbChangesPtr   changes)
 
623
#else
 
624
XkbUpdateMapFromCore(xkb,first_key,num_keys,map_width,core_keysyms,changes)
 
625
    XkbDescPtr          xkb;
 
626
    KeyCode             first_key;
 
627
    int                 num_keys;
 
628
    int                 map_width;
 
629
    KeySym *            core_keysyms;
 
630
    XkbChangesPtr       changes;
 
631
#endif
 
632
{
 
633
register int    key,last_key;
 
634
KeySym *        syms;
 
635
 
 
636
    syms= &core_keysyms[(first_key-xkb->min_key_code)*map_width];
 
637
    if (changes) {
 
638
        if (changes->map.changed&XkbKeySymsMask) {
 
639
            _XkbAddKeyChange(&changes->map.first_key_sym,
 
640
                                &changes->map.num_key_syms,first_key);
 
641
            if (num_keys>1) {
 
642
                _XkbAddKeyChange(&changes->map.first_key_sym,
 
643
                                                &changes->map.num_key_syms,
 
644
                                                first_key+num_keys-1);
 
645
            }
 
646
        }
 
647
        else {
 
648
            changes->map.changed|= XkbKeySymsMask;
 
649
            changes->map.first_key_sym= first_key;
 
650
            changes->map.num_key_syms= num_keys;
 
651
        }
 
652
    }
 
653
    last_key= first_key+num_keys-1;
 
654
    for (key=first_key;key<=last_key;key++,syms+= map_width) {
 
655
        XkbMapChangesPtr        mc;
 
656
        unsigned                explicit;
 
657
        KeySym                  tsyms[XkbMaxSymsPerKey];
 
658
        int                     types[XkbNumKbdGroups];
 
659
        int                     nG;
 
660
 
 
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);
 
667
        if (changes)
 
668
             mc= &changes->map;
 
669
        else mc= NULL;
 
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);
 
674
    }
 
675
 
 
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;
 
680
        unsigned                present;
 
681
 
 
682
        bzero(newVMods,XkbNumVirtualMods);
 
683
        present= 0;
 
684
        for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
 
685
            if (xkb->server->vmodmap[key]==0)
 
686
                continue;
 
687
            for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
 
688
                if (bit&xkb->server->vmodmap[key]) {
 
689
                    present|= bit;
 
690
                    newVMods[i]|= xkb->map->modmap[key];
 
691
                }
 
692
            }
 
693
        }
 
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];
 
699
            }
 
700
        }
 
701
    }
 
702
    if (changes && (changes->map.changed&XkbVirtualModsMask))
 
703
        XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes);
 
704
    return True;
 
705
}
 
706
 
 
707
Status
 
708
#if NeedFunctionPrototypes
 
709
XkbChangeTypesOfKey(    XkbDescPtr               xkb,
 
710
                        int                      key,
 
711
                        int                      nGroups,
 
712
                        unsigned                 groups,
 
713
                        int     *                newTypesIn,
 
714
                        XkbMapChangesPtr         changes)
 
715
#else
 
716
XkbChangeTypesOfKey(xkb,key,nGroups,groups,newTypesIn,changes)
 
717
    XkbDescPtr           xkb;
 
718
    int                  key;
 
719
    int                  nGroups;
 
720
    unsigned             groups;
 
721
    int *                newTypesIn;
 
722
    XkbMapChangesPtr     changes;
 
723
#endif
 
724
{
 
725
XkbKeyTypePtr   pOldType,pNewType;
 
726
register int    i;
 
727
int             width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups];
 
728
 
 
729
    if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) ||
 
730
        (!xkb->map->types)||(!newTypes)||((groups&XkbAllGroupsMask)==0)||
 
731
        (nGroups>XkbNumKbdGroups)) {
 
732
        return BadMatch;
 
733
    }
 
734
    if (nGroups==0) {
 
735
        for (i=0;i<XkbNumKbdGroups;i++) {
 
736
            xkb->map->key_sym_map[key].kt_index[i]= XkbOneLevelIndex;
 
737
        }
 
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);
 
742
        return Success;
 
743
    }
 
744
 
 
745
    nOldGroups= XkbKeyNumGroups(xkb,key);
 
746
    oldWidth= XkbKeyGroupsWidth(xkb,key);
 
747
    for (width=i=0;i<nGroups;i++) {
 
748
        if (groups&(1<<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)
 
756
            return BadMatch;
 
757
        pNewType= &xkb->map->types[newTypes[i]];
 
758
        if (pNewType->num_levels>width)
 
759
            width= pNewType->num_levels;
 
760
    }
 
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;
 
765
        int             nCopy;
 
766
 
 
767
        if (nOldGroups==0) {
 
768
            pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
 
769
            if (pSyms!=NULL) {
 
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];
 
776
                }
 
777
                return Success;
 
778
            }
 
779
            return BadAlloc;
 
780
        }
 
781
        pSyms= XkbKeySymsPtr(xkb,key);
 
782
        memcpy(oldSyms,pSyms,XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
 
783
        pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
 
784
        if (pSyms==NULL)
 
785
            return BadAlloc;
 
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));
 
794
        }
 
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);
 
800
            if (pActs==NULL)
 
801
                return BadAlloc;
 
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));
 
811
            }
 
812
        }
 
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;
 
817
    }
 
818
    width= 0;
 
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;
 
823
    }
 
824
    xkb->map->key_sym_map[key].width= width;
 
825
    if (changes!=NULL) {
 
826
        if (changes->changed&XkbKeySymsMask) {
 
827
            _XkbAddKeyChange(&changes->first_key_sym,&changes->num_key_syms,
 
828
                                                                        key);
 
829
        }
 
830
        else {
 
831
            changes->changed|= XkbKeySymsMask;
 
832
            changes->first_key_sym= key;
 
833
            changes->num_key_syms= 1;
 
834
        }
 
835
    }
 
836
    return Success;
 
837
}
 
838
 
 
839
/***====================================================================***/
 
840
 
 
841
Bool
 
842
#if NeedFunctionPrototypes
 
843
XkbVirtualModsToReal(XkbDescPtr xkb,unsigned virtual_mask,unsigned *mask_rtrn)
 
844
#else
 
845
XkbVirtualModsToReal(xkb,virtual_mask,mask_rtrn)
 
846
    XkbDescPtr  xkb;
 
847
    unsigned    virtual_mask;
 
848
    unsigned *  mask_rtrn;
 
849
#endif
 
850
{
 
851
register int i,bit;
 
852
register unsigned mask;
 
853
 
 
854
    if (xkb==NULL)
 
855
        return False;
 
856
    if (virtual_mask==0) {
 
857
        *mask_rtrn= 0;
 
858
        return True;
 
859
    }
 
860
    if (xkb->server==NULL)
 
861
        return False;
 
862
    for (i=mask=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
 
863
        if (virtual_mask&bit)
 
864
            mask|= xkb->server->vmods[i];
 
865
    }
 
866
    *mask_rtrn= mask;
 
867
    return True;
 
868
}
 
869
 
 
870
/***====================================================================***/
 
871
 
 
872
Bool
 
873
#if NeedFunctionPrototypes
 
874
XkbUpdateActionVirtualMods(XkbDescPtr xkb,XkbAction *act,unsigned changed)
 
875
#else
 
876
XkbUpdateActionVirtualMods(xkb,act,changed)
 
877
    XkbDescPtr  xkb;
 
878
    XkbAction * act;
 
879
    unsigned    changed;
 
880
#endif
 
881
{
 
882
unsigned int    tmp;
 
883
 
 
884
    switch (act->type) {
 
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;
 
890
                return True;
 
891
            }
 
892
            break;
 
893
        case XkbSA_ISOLock:
 
894
            if ((((tmp= XkbModActionVMods(&act->iso))!=0)&changed)!=0) {
 
895
                XkbVirtualModsToReal(xkb,tmp,&tmp);
 
896
                act->iso.mask= act->iso.real_mods;
 
897
                act->iso.mask|= tmp;
 
898
                return True;
 
899
            }
 
900
            break;
 
901
    }
 
902
    return False;
 
903
}
 
904
 
 
905
void
 
906
#if NeedFunctionPrototypes
 
907
XkbUpdateKeyTypeVirtualMods(    XkbDescPtr      xkb,
 
908
                                XkbKeyTypePtr   type,
 
909
                                unsigned int    changed,
 
910
                                XkbChangesPtr   changes)
 
911
#else
 
912
XkbUpdateKeyTypeVirtualMods(xkb,type,changed,changes)
 
913
    XkbDescPtr          xkb;
 
914
    XkbKeyTypePtr       type;
 
915
    unsigned int        changed;
 
916
    XkbChangesPtr       changes;
 
917
#endif
 
918
{
 
919
register unsigned int   i;
 
920
unsigned int            mask;
 
921
 
 
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);
 
932
            }
 
933
            else entry->active= 1;
 
934
        }
 
935
    }
 
936
    if (changes) {
 
937
        int     type_ndx;
 
938
        type_ndx= type-xkb->map->types;
 
939
        if ((type_ndx<0)||(type_ndx>xkb->map->num_types))
 
940
            return;
 
941
        if (changes->map.changed&XkbKeyTypesMask) {
 
942
            int last;
 
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;
 
947
            }
 
948
            else if (type_ndx>last) {
 
949
                changes->map.num_types= (type_ndx-changes->map.first_type)+1;
 
950
            }
 
951
        }
 
952
        else {
 
953
            changes->map.changed|= XkbKeyTypesMask;
 
954
            changes->map.first_type= type_ndx;
 
955
            changes->map.num_types= 1;
 
956
        }
 
957
    }
 
958
    return;
 
959
}
 
960
 
 
961
Bool
 
962
#if NeedFunctionPrototypes
 
963
XkbApplyVirtualModChanges(XkbDescPtr xkb,unsigned changed,XkbChangesPtr changes)
 
964
#else
 
965
XkbApplyVirtualModChanges(xkb,changed,changes)
 
966
    XkbDescPtr          xkb;
 
967
    unsigned            changed;
 
968
    XkbChangesPtr       changes;
 
969
#endif
 
970
{
 
971
register int    i;
 
972
unsigned int    checkState = 0;
 
973
 
 
974
    if ((!xkb) || (!xkb->map) || (changed==0))
 
975
        return False;
 
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);
 
979
    }
 
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;
 
986
            if (changes) {
 
987
                changes->ctrls.changed_ctrls|= XkbInternalModsMask;
 
988
                checkState= True;
 
989
            }
 
990
        }
 
991
    }
 
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;
 
998
            if (changes) {
 
999
                changes->ctrls.changed_ctrls|= XkbIgnoreLockModsMask;
 
1000
                checkState= True;
 
1001
            }
 
1002
        }
 
1003
    }
 
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;
 
1014
                    if (changes) {
 
1015
                        changes->indicators.map_changes|= (1<<i);
 
1016
                        checkState= True;
 
1017
                    }
 
1018
                }
 
1019
            }
 
1020
        }
 
1021
    }
 
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;
 
1031
                if (changes) {
 
1032
                    changes->compat.changed_groups|= (1<<i);
 
1033
                    checkState= True;
 
1034
                }
 
1035
            }
 
1036
        }
 
1037
    }
 
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;
 
1043
                register int n;
 
1044
 
 
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)) {
 
1049
                        if (lowChange<0)
 
1050
                            lowChange= i;
 
1051
                        highChange= i;
 
1052
                    }
 
1053
                }
 
1054
            }
 
1055
        }
 
1056
        if (changes && (lowChange>0)) { /* something changed */
 
1057
            if (changes->map.changed&XkbKeyActionsMask) {
 
1058
                int last;
 
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)
 
1063
                    highChange= last;
 
1064
            }
 
1065
            changes->map.changed|=      XkbKeyActionsMask;
 
1066
            changes->map.first_key_act= lowChange;
 
1067
            changes->map.num_key_acts=  (highChange-lowChange)+1;
 
1068
        }
 
1069
    }
 
1070
    return checkState;
 
1071
}