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

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/xkb/xkbActions.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: xkbActions.c,v 1.3 2000/08/17 19:53:47 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/programs/Xserver/xkb/xkbActions.c,v 3.11 2003/02/13 15:36:48 dawes Exp $ */
 
28
 
 
29
#include <stdio.h>
 
30
#include <math.h>
 
31
#define NEED_EVENTS 1
 
32
#include <X11/X.h>
 
33
#include <X11/Xproto.h>
 
34
#include <X11/keysym.h>
 
35
#include "misc.h"
 
36
#include "inputstr.h"
 
37
#include "XKBsrv.h"
 
38
#include <ctype.h>
 
39
 
 
40
#ifdef XINPUT
 
41
extern  void    ProcessOtherEvent(
 
42
#if NeedFunctionPrototypes
 
43
    xEvent *            /* xE */,
 
44
    DeviceIntPtr        /* dev */,
 
45
    int                 /* count */
 
46
#endif
 
47
);
 
48
#endif
 
49
 
 
50
/***====================================================================***/
 
51
 
 
52
static XkbAction
 
53
#if NeedFunctionPrototypes
 
54
_FixUpAction(XkbDescPtr xkb,XkbAction *act)
 
55
#else
 
56
_FixUpAction(xkb,act)
 
57
    XkbDescPtr          xkb;
 
58
    XkbAction *         act;
 
59
#endif
 
60
{
 
61
static XkbAction        fake;
 
62
 
 
63
    if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) {
 
64
        fake.type = XkbSA_NoAction;
 
65
        return fake;
 
66
    }
 
67
    if (XkbDisableLockActions) {
 
68
        switch (act->type) {
 
69
            case XkbSA_LockMods:
 
70
                fake.mods.type  = XkbSA_SetMods;
 
71
                fake.mods.flags = 0;
 
72
                fake.mods.mask  = act->mods.mask;
 
73
                return fake;
 
74
            case XkbSA_LatchMods:
 
75
                fake.mods.type  = XkbSA_SetMods;
 
76
                fake.mods.flags = 0;
 
77
                fake.mods.mask  = act->mods.mask;
 
78
                return fake;
 
79
            case XkbSA_ISOLock:
 
80
                if (act->iso.flags&XkbSA_ISODfltIsGroup) {
 
81
                     fake.group.type = XkbSA_SetGroup;
 
82
                     fake.group.flags = act->iso.flags&XkbSA_GroupAbsolute;
 
83
                     XkbSASetGroup(&fake.group,XkbSAGroup(&act->iso));
 
84
                }
 
85
                else {
 
86
                     fake.mods.type  = XkbSA_SetMods;
 
87
                     fake.mods.flags = 0;
 
88
                     fake.mods.mask  = act->iso.mask;
 
89
                }
 
90
                return fake;
 
91
            case XkbSA_LockGroup:
 
92
            case XkbSA_LatchGroup:
 
93
                /* We want everything from the latch/lock action except the
 
94
                 * type should be changed to set.
 
95
                 */
 
96
                fake = *act;
 
97
                fake.group.type = XkbSA_SetGroup;
 
98
                return fake;
 
99
        }
 
100
    }
 
101
    else 
 
102
    if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) {
 
103
        if (act->any.type==XkbSA_SetMods) {
 
104
            fake.mods.type = XkbSA_LatchMods;
 
105
            fake.mods.mask = act->mods.mask;
 
106
            if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
 
107
                 fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
 
108
            else fake.mods.flags= XkbSA_ClearLocks;
 
109
            return fake;
 
110
        }
 
111
        if (act->any.type==XkbSA_SetGroup) {
 
112
            fake.group.type = XkbSA_LatchGroup;
 
113
            if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
 
114
                 fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
 
115
            else fake.group.flags= XkbSA_ClearLocks;
 
116
            XkbSASetGroup(&fake.group,XkbSAGroup(&act->group));
 
117
            return fake;
 
118
        }
 
119
    }
 
120
    return *act;
 
121
}
 
122
 
 
123
static XkbAction
 
124
#if NeedFunctionPrototypes
 
125
XkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key)
 
126
#else
 
127
XkbGetKeyAction(xkbi,xkbState,key)
 
128
    XkbSrvInfoPtr       xkbi;
 
129
    XkbStatePtr         xkbState;
 
130
    CARD8               key;
 
131
#endif
 
132
{
 
133
int                     effectiveGroup;
 
134
int                     col;
 
135
XkbDescPtr              xkb;
 
136
XkbKeyTypePtr           type;
 
137
XkbAction *             pActs;
 
138
static XkbAction        fake;
 
139
 
 
140
    xkb= xkbi->desc;
 
141
    if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) {
 
142
        fake.type = XkbSA_NoAction;
 
143
        return fake;
 
144
    }
 
145
    pActs= XkbKeyActionsPtr(xkb,key);
 
146
    col= 0;
 
147
    effectiveGroup= xkbState->group;
 
148
    if (effectiveGroup!=XkbGroup1Index) {
 
149
        if (XkbKeyNumGroups(xkb,key)>(unsigned)1) {
 
150
            if (effectiveGroup>=XkbKeyNumGroups(xkb,key)) {
 
151
                unsigned gi= XkbKeyGroupInfo(xkb,key);
 
152
                switch (XkbOutOfRangeGroupAction(gi)) {
 
153
                    default:
 
154
                    case XkbWrapIntoRange:
 
155
                        effectiveGroup %= XkbKeyNumGroups(xkb,key);
 
156
                        break;
 
157
                    case XkbClampIntoRange:
 
158
                        effectiveGroup = XkbKeyNumGroups(xkb,key)-1;
 
159
                        break;
 
160
                    case XkbRedirectIntoRange:
 
161
                        effectiveGroup= XkbOutOfRangeGroupInfo(gi);
 
162
                        if (effectiveGroup>=XkbKeyNumGroups(xkb,key))
 
163
                            effectiveGroup= 0;
 
164
                        break;
 
165
                }
 
166
            }
 
167
        }
 
168
        else effectiveGroup= XkbGroup1Index;
 
169
        col+= (effectiveGroup*XkbKeyGroupsWidth(xkb,key));
 
170
    }
 
171
    type= XkbKeyKeyType(xkb,key,effectiveGroup);
 
172
    if (type->map!=NULL) {
 
173
        register unsigned               i,mods;
 
174
        register XkbKTMapEntryPtr       entry;
 
175
        mods= xkbState->mods&type->mods.mask;
 
176
        for (entry= type->map,i=0;i<type->map_count;i++,entry++) {
 
177
            if ((entry->active)&&(entry->mods.mask==mods)) {
 
178
                col+= entry->level;
 
179
                break;
 
180
            }
 
181
        }
 
182
    }
 
183
    if (pActs[col].any.type==XkbSA_NoAction)
 
184
        return pActs[col];
 
185
    fake= _FixUpAction(xkb,&pActs[col]);
 
186
    return fake;
 
187
}
 
188
 
 
189
XkbAction
 
190
#if NeedFunctionPrototypes
 
191
XkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button)
 
192
#else
 
193
XkbGetButtonAction(kbd,dev,button)
 
194
    DeviceIntPtr        kbd;
 
195
    DeviceIntPtr        dev;
 
196
    int                 button;
 
197
#endif
 
198
{
 
199
XkbAction fake;
 
200
   if ((dev->button)&&(dev->button->xkb_acts)) {
 
201
        if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) {
 
202
            fake= _FixUpAction(kbd->key->xkbInfo->desc,
 
203
                                        &dev->button->xkb_acts[button-1]);
 
204
            return fake;
 
205
        }
 
206
   }
 
207
   fake.any.type= XkbSA_NoAction;
 
208
   return fake;
 
209
}
 
210
 
 
211
/***====================================================================***/
 
212
 
 
213
#define SYNTHETIC_KEYCODE       1
 
214
#define BTN_ACT_FLAG            0x100
 
215
 
 
216
typedef struct _XkbFilter {
 
217
        CARD16                    keycode;
 
218
        CARD8                     what;
 
219
        CARD8                     active;
 
220
        CARD8                     filterOthers;
 
221
        CARD32                    priv;
 
222
        XkbAction                 upAction;
 
223
        int                     (*filter)(
 
224
#if NeedFunctionPrototypes
 
225
                                        XkbSrvInfoPtr           /* xkbi */,
 
226
                                        struct _XkbFilter *     /* filter */,
 
227
                                        unsigned                /* keycode */,
 
228
                                        XkbAction *             /* action */
 
229
#endif
 
230
                                  );
 
231
        struct _XkbFilter        *next;
 
232
} XkbFilterRec,*XkbFilterPtr;
 
233
 
 
234
static int
 
235
#if NeedFunctionPrototypes
 
236
_XkbFilterSetState(     XkbSrvInfoPtr   xkbi,
 
237
                        XkbFilterPtr    filter,
 
238
                        unsigned        keycode,
 
239
                        XkbAction *pAction)
 
240
#else
 
241
_XkbFilterSetState(xkbi,filter,keycode,pAction)
 
242
    XkbSrvInfoPtr       xkbi;
 
243
    XkbFilterPtr        filter;
 
244
    unsigned            keycode;
 
245
    XkbAction *         pAction;
 
246
#endif
 
247
{
 
248
    if (filter->keycode==0) {           /* initial press */
 
249
        filter->keycode = keycode;
 
250
        filter->active = 1;
 
251
        filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0);
 
252
        filter->priv = 0;
 
253
        filter->filter = _XkbFilterSetState;
 
254
        if (pAction->type==XkbSA_SetMods) {
 
255
            filter->upAction = *pAction;
 
256
            xkbi->setMods= pAction->mods.mask;
 
257
        }
 
258
        else {
 
259
            xkbi->groupChange = XkbSAGroup(&pAction->group);
 
260
            if (pAction->group.flags&XkbSA_GroupAbsolute)
 
261
                xkbi->groupChange-= xkbi->state.base_group;
 
262
            filter->upAction= *pAction;
 
263
            XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
 
264
        }
 
265
    }
 
266
    else if (filter->keycode==keycode) {
 
267
        if (filter->upAction.type==XkbSA_SetMods) {
 
268
            xkbi->clearMods = filter->upAction.mods.mask;
 
269
            if (filter->upAction.mods.flags&XkbSA_ClearLocks) {
 
270
                xkbi->state.locked_mods&= ~filter->upAction.mods.mask;
 
271
            }
 
272
        }
 
273
        else {
 
274
            if (filter->upAction.group.flags&XkbSA_ClearLocks) {
 
275
                xkbi->state.locked_group = 0;
 
276
            }
 
277
            xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
 
278
        }
 
279
        filter->active = 0;
 
280
    }
 
281
    else {
 
282
        filter->upAction.mods.flags&= ~XkbSA_ClearLocks;
 
283
        filter->filterOthers = 0;
 
284
    }
 
285
    return 1;
 
286
}
 
287
 
 
288
#define LATCH_KEY_DOWN  1
 
289
#define LATCH_PENDING   2
 
290
#define NO_LATCH        3
 
291
 
 
292
static int
 
293
#if NeedFunctionPrototypes
 
294
_XkbFilterLatchState(   XkbSrvInfoPtr   xkbi,
 
295
                        XkbFilterPtr    filter,
 
296
                        unsigned        keycode,
 
297
                        XkbAction *     pAction)
 
298
#else
 
299
_XkbFilterLatchState(xkbi,filter,keycode,pAction)
 
300
    XkbSrvInfoPtr       xkbi;
 
301
    XkbFilterPtr        filter;
 
302
    unsigned            keycode;
 
303
    XkbAction *         pAction;
 
304
#endif
 
305
{
 
306
 
 
307
    if (filter->keycode==0) {                   /* initial press */
 
308
        filter->keycode = keycode;
 
309
        filter->active = 1;
 
310
        filter->filterOthers = 1;
 
311
        filter->priv = LATCH_KEY_DOWN;
 
312
        filter->filter = _XkbFilterLatchState;
 
313
        if (pAction->type==XkbSA_LatchMods) {
 
314
            filter->upAction = *pAction;
 
315
            xkbi->setMods = pAction->mods.mask;
 
316
        }
 
317
        else {
 
318
            xkbi->groupChange = XkbSAGroup(&pAction->group);
 
319
            if (pAction->group.flags&XkbSA_GroupAbsolute)
 
320
                 xkbi->groupChange-= xkbi->state.base_group;
 
321
            filter->upAction= *pAction;
 
322
            XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
 
323
        }
 
324
    }
 
325
    else if ( pAction && (filter->priv==LATCH_PENDING) ) {
 
326
        if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) {
 
327
            filter->active = 0;
 
328
            if (filter->upAction.type==XkbSA_LatchMods)
 
329
                 xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
 
330
            else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
 
331
        }
 
332
        else if ((pAction->type==filter->upAction.type)&&
 
333
                 (pAction->mods.flags==filter->upAction.mods.flags)&&
 
334
                 (pAction->mods.mask==filter->upAction.mods.mask)) {
 
335
            if (filter->upAction.mods.flags&XkbSA_LatchToLock) {
 
336
                XkbControlsPtr ctrls= xkbi->desc->ctrls;
 
337
                if (filter->upAction.type==XkbSA_LatchMods)
 
338
                     pAction->mods.type= XkbSA_LockMods;
 
339
                else pAction->group.type= XkbSA_LockGroup;
 
340
                if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&&
 
341
                                (ctrls->enabled_ctrls&XkbStickyKeysMask)) {
 
342
                    XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK,
 
343
                                                XkbStickyKeysMask);
 
344
                }
 
345
            }
 
346
            else {
 
347
                if (filter->upAction.type==XkbSA_LatchMods)
 
348
                     pAction->mods.type= XkbSA_SetMods;
 
349
                else pAction->group.type= XkbSA_SetGroup;
 
350
            }
 
351
            if (filter->upAction.type==XkbSA_LatchMods)
 
352
                 xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
 
353
            else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
 
354
            filter->active = 0;
 
355
        }
 
356
    }
 
357
    else if (filter->keycode==keycode) {        /* release */
 
358
        XkbControlsPtr  ctrls= xkbi->desc->ctrls;
 
359
        int             needBeep;
 
360
        int             beepType= _BEEP_NONE;
 
361
 
 
362
        needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&&
 
363
                        XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask));
 
364
        if (filter->upAction.type==XkbSA_LatchMods) {
 
365
            xkbi->clearMods = filter->upAction.mods.mask;
 
366
            if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&&
 
367
                 (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) {
 
368
                xkbi->state.locked_mods&= ~xkbi->clearMods;
 
369
                filter->priv= NO_LATCH;
 
370
                beepType= _BEEP_STICKY_UNLOCK;
 
371
            }
 
372
        }
 
373
        else {
 
374
            xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
 
375
            if ((filter->upAction.group.flags&XkbSA_ClearLocks)&&
 
376
                                                (xkbi->state.locked_group)) {
 
377
                xkbi->state.locked_group = 0;
 
378
                filter->priv = NO_LATCH;
 
379
                beepType= _BEEP_STICKY_UNLOCK;
 
380
            }
 
381
        }
 
382
        if (filter->priv==NO_LATCH) {
 
383
            filter->active= 0;
 
384
        }
 
385
        else {
 
386
            filter->priv= LATCH_PENDING;
 
387
            if (filter->upAction.type==XkbSA_LatchMods) {
 
388
                xkbi->state.latched_mods |= filter->upAction.mods.mask;
 
389
                needBeep = xkbi->state.latched_mods ? needBeep : 0;
 
390
                xkbi->state.latched_mods |= filter->upAction.mods.mask;
 
391
            }
 
392
            else {
 
393
                xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group);
 
394
            }
 
395
            if (needBeep && (beepType==_BEEP_NONE))
 
396
                beepType= _BEEP_STICKY_LATCH;
 
397
        }
 
398
        if (needBeep && (beepType!=_BEEP_NONE))
 
399
            XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask);
 
400
    }
 
401
    else if (filter->priv==LATCH_KEY_DOWN) {
 
402
        filter->priv= NO_LATCH;
 
403
        filter->filterOthers = 0;
 
404
    }
 
405
    return 1;
 
406
}
 
407
 
 
408
static int
 
409
#if NeedFunctionPrototypes
 
410
_XkbFilterLockState(    XkbSrvInfoPtr   xkbi,
 
411
                        XkbFilterPtr    filter,
 
412
                        unsigned        keycode,
 
413
                        XkbAction *     pAction)
 
414
#else
 
415
_XkbFilterLockState(xkbi,filter,keycode,pAction)
 
416
    XkbSrvInfoPtr       xkbi;
 
417
    XkbFilterPtr        filter;
 
418
    unsigned            keycode;
 
419
    XkbAction *         pAction;
 
420
#endif
 
421
{
 
422
 
 
423
    if (pAction&&(pAction->type==XkbSA_LockGroup)) {
 
424
        if (pAction->group.flags&XkbSA_GroupAbsolute)
 
425
             xkbi->state.locked_group= XkbSAGroup(&pAction->group);
 
426
        else xkbi->state.locked_group+= XkbSAGroup(&pAction->group);
 
427
        return 1;
 
428
    }
 
429
    if (filter->keycode==0) {           /* initial press */
 
430
        filter->keycode = keycode;
 
431
        filter->active = 1;
 
432
        filter->filterOthers = 0;
 
433
        filter->priv = 0;
 
434
        filter->filter = _XkbFilterLockState;
 
435
        filter->upAction = *pAction;
 
436
        xkbi->state.locked_mods^= pAction->mods.mask;
 
437
        xkbi->setMods = pAction->mods.mask;
 
438
    }
 
439
    else if (filter->keycode==keycode) {
 
440
        filter->active = 0;
 
441
        xkbi->clearMods = filter->upAction.mods.mask;
 
442
    }
 
443
    return 1;
 
444
}
 
445
 
 
446
#define ISO_KEY_DOWN            0
 
447
#define NO_ISO_LOCK             1
 
448
 
 
449
static int
 
450
#if NeedFunctionPrototypes
 
451
_XkbFilterISOLock(      XkbSrvInfoPtr   xkbi,
 
452
                        XkbFilterPtr    filter,
 
453
                        unsigned        keycode,
 
454
                        XkbAction *     pAction)
 
455
#else
 
456
_XkbFilterISOLock(xkbi,filter,keycode,pAction)
 
457
    XkbSrvInfoPtr       xkbi;
 
458
    XkbFilterPtr        filter;
 
459
    unsigned            keycode;
 
460
    XkbAction *         pAction;
 
461
#endif
 
462
{
 
463
 
 
464
    if (filter->keycode==0) {           /* initial press */
 
465
        CARD8   flags= pAction->iso.flags;
 
466
 
 
467
        filter->keycode = keycode;
 
468
        filter->active = 1;
 
469
        filter->filterOthers = 1;
 
470
        filter->priv = ISO_KEY_DOWN;
 
471
        filter->upAction = *pAction;
 
472
        filter->filter = _XkbFilterISOLock;
 
473
        if (flags&XkbSA_ISODfltIsGroup) {
 
474
            xkbi->groupChange = XkbSAGroup(&pAction->iso);
 
475
            xkbi->setMods = 0;
 
476
        }
 
477
        else {
 
478
            xkbi->setMods = pAction->iso.mask;
 
479
            xkbi->groupChange = 0;
 
480
        }
 
481
        if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) {
 
482
            filter->priv= NO_ISO_LOCK;
 
483
            xkbi->state.locked_mods^= xkbi->state.base_mods;
 
484
        }
 
485
        if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) {
 
486
/* 6/22/93 (ef) -- lock groups if group key is down first */
 
487
        }
 
488
        if (!(flags&XkbSA_ISONoAffectPtr)) {
 
489
/* 6/22/93 (ef) -- lock mouse buttons if they're down */
 
490
        }
 
491
    }
 
492
    else if (filter->keycode==keycode) {
 
493
        CARD8   flags= filter->upAction.iso.flags;
 
494
 
 
495
        if (flags&XkbSA_ISODfltIsGroup) {
 
496
            xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
 
497
            xkbi->clearMods = 0;
 
498
            if (filter->priv==ISO_KEY_DOWN)
 
499
                xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso);
 
500
        }
 
501
        else {
 
502
            xkbi->clearMods= filter->upAction.iso.mask;
 
503
            xkbi->groupChange= 0;
 
504
            if (filter->priv==ISO_KEY_DOWN)
 
505
                xkbi->state.locked_mods^= filter->upAction.iso.mask;
 
506
        }
 
507
        filter->active = 0;
 
508
    }
 
509
    else if (pAction) {
 
510
        CARD8   flags= filter->upAction.iso.flags;
 
511
 
 
512
        switch (pAction->type) {
 
513
            case XkbSA_SetMods: case XkbSA_LatchMods:
 
514
                if (!(flags&XkbSA_ISONoAffectMods)) {
 
515
                    pAction->type= XkbSA_LockMods;
 
516
                    filter->priv= NO_ISO_LOCK;
 
517
                }
 
518
                break;
 
519
            case XkbSA_SetGroup: case XkbSA_LatchGroup:
 
520
                if (!(flags&XkbSA_ISONoAffectGroup)) {
 
521
                    pAction->type= XkbSA_LockGroup;
 
522
                    filter->priv= NO_ISO_LOCK;
 
523
                }
 
524
                break;
 
525
            case XkbSA_PtrBtn:
 
526
                if (!(flags&XkbSA_ISONoAffectPtr)) {
 
527
                     pAction->type= XkbSA_LockPtrBtn;
 
528
                     filter->priv= NO_ISO_LOCK;
 
529
                }
 
530
                break;
 
531
            case XkbSA_SetControls:
 
532
                if (!(flags&XkbSA_ISONoAffectCtrls)) {
 
533
                    pAction->type= XkbSA_LockControls;
 
534
                    filter->priv= NO_ISO_LOCK;
 
535
                }
 
536
                break;
 
537
        }
 
538
    }
 
539
    return 1;
 
540
}
 
541
 
 
542
 
 
543
static CARD32
 
544
#if NeedFunctionPrototypes
 
545
_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg)
 
546
#else
 
547
_XkbPtrAccelExpire(timer,now,arg)
 
548
    OsTimerPtr   timer;
 
549
    CARD32       now;
 
550
    pointer      arg;
 
551
#endif
 
552
{
 
553
XkbSrvInfoPtr   xkbi= (XkbSrvInfoPtr)arg;
 
554
XkbControlsPtr  ctrls= xkbi->desc->ctrls;
 
555
int             dx,dy;
 
556
 
 
557
    if (xkbi->mouseKey==0)
 
558
        return 0;
 
559
 
 
560
    if (xkbi->mouseKeysAccel) {
 
561
        if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) {
 
562
            double step;
 
563
            xkbi->mouseKeysCounter++;
 
564
            step= xkbi->mouseKeysCurveFactor*
 
565
                 pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve);
 
566
            if (xkbi->mouseKeysDX<0)
 
567
                 dx= floor( ((double)xkbi->mouseKeysDX)*step );
 
568
            else dx=  ceil( ((double)xkbi->mouseKeysDX)*step );
 
569
            if (xkbi->mouseKeysDY<0)
 
570
                 dy= floor( ((double)xkbi->mouseKeysDY)*step );
 
571
            else dy=  ceil( ((double)xkbi->mouseKeysDY)*step );
 
572
        }
 
573
        else {
 
574
            dx= xkbi->mouseKeysDX*ctrls->mk_max_speed;
 
575
            dy= xkbi->mouseKeysDY*ctrls->mk_max_speed;
 
576
        }
 
577
        if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX)
 
578
            dx= xkbi->mouseKeysDX;
 
579
        if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY)
 
580
            dy= xkbi->mouseKeysDY;
 
581
    }
 
582
    else {
 
583
        dx= xkbi->mouseKeysDX;
 
584
        dy= xkbi->mouseKeysDY;
 
585
    }
 
586
    XkbDDXFakePointerMotion(xkbi->mouseKeysFlags,dx,dy);
 
587
    return xkbi->desc->ctrls->mk_interval;
 
588
}
 
589
 
 
590
static int
 
591
#if NeedFunctionPrototypes
 
592
_XkbFilterPointerMove(  XkbSrvInfoPtr   xkbi,
 
593
                        XkbFilterPtr    filter,
 
594
                        unsigned        keycode,
 
595
                        XkbAction *     pAction)
 
596
#else
 
597
_XkbFilterPointerMove(xkbi,filter,keycode,pAction)
 
598
    XkbSrvInfoPtr       xkbi;
 
599
    XkbFilterPtr        filter;
 
600
    unsigned            keycode;
 
601
    XkbAction *         pAction;
 
602
#endif
 
603
{
 
604
int     x,y;
 
605
Bool    accel;
 
606
 
 
607
    if (filter->keycode==0) {           /* initial press */
 
608
        filter->keycode = keycode;
 
609
        filter->active = 1;
 
610
        filter->filterOthers = 0;
 
611
        filter->priv=0;
 
612
        filter->filter = _XkbFilterPointerMove;
 
613
        filter->upAction= *pAction;
 
614
        xkbi->mouseKeysCounter= 0;
 
615
        xkbi->mouseKey= keycode;
 
616
        accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0);
 
617
        x= XkbPtrActionX(&pAction->ptr);
 
618
        y= XkbPtrActionY(&pAction->ptr);
 
619
        XkbDDXFakePointerMotion(pAction->ptr.flags,x,y);
 
620
        AccessXCancelRepeatKey(xkbi,keycode);
 
621
        xkbi->mouseKeysAccel= accel&&
 
622
                (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask);
 
623
        xkbi->mouseKeysFlags= pAction->ptr.flags;
 
624
        xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr);
 
625
        xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr);
 
626
        xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0,
 
627
                                xkbi->desc->ctrls->mk_delay,
 
628
                                _XkbPtrAccelExpire,(pointer)xkbi);
 
629
    }
 
630
    else if (filter->keycode==keycode) {
 
631
        filter->active = 0;
 
632
        if (xkbi->mouseKey==keycode) {
 
633
            xkbi->mouseKey= 0;
 
634
            xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0,
 
635
                                                        NULL, NULL);
 
636
        }
 
637
    }
 
638
    return 0;
 
639
}
 
640
 
 
641
static int
 
642
#if NeedFunctionPrototypes
 
643
_XkbFilterPointerBtn(   XkbSrvInfoPtr   xkbi,
 
644
                        XkbFilterPtr    filter,
 
645
                        unsigned        keycode,
 
646
                        XkbAction *     pAction)
 
647
#else
 
648
_XkbFilterPointerBtn(xkbi,filter,keycode,pAction)
 
649
    XkbSrvInfoPtr       xkbi;
 
650
    XkbFilterPtr        filter;
 
651
    unsigned            keycode;
 
652
    XkbAction *         pAction;
 
653
#endif
 
654
{
 
655
    if (filter->keycode==0) {           /* initial press */
 
656
        int     button= pAction->btn.button;
 
657
 
 
658
        if (button==XkbSA_UseDfltButton)
 
659
            button = xkbi->desc->ctrls->mk_dflt_btn;
 
660
 
 
661
        filter->keycode = keycode;
 
662
        filter->active = 1;
 
663
        filter->filterOthers = 0;
 
664
        filter->priv=0;
 
665
        filter->filter = _XkbFilterPointerBtn;
 
666
        filter->upAction= *pAction;
 
667
        filter->upAction.btn.button= button;
 
668
        switch (pAction->type) {
 
669
            case XkbSA_LockPtrBtn:
 
670
                if (((xkbi->lockedPtrButtons&(1<<button))==0)&&
 
671
                        ((pAction->btn.flags&XkbSA_LockNoLock)==0)) {
 
672
                    xkbi->lockedPtrButtons|= (1<<button);
 
673
                    AccessXCancelRepeatKey(xkbi,keycode);
 
674
                    XkbDDXFakePointerButton(ButtonPress,button);
 
675
                    filter->upAction.type= XkbSA_NoAction;
 
676
                }
 
677
                break;
 
678
            case XkbSA_PtrBtn:
 
679
                {
 
680
                    register int i,nClicks;
 
681
                    AccessXCancelRepeatKey(xkbi,keycode);
 
682
                    if (pAction->btn.count>0) {
 
683
                        nClicks= pAction->btn.count;
 
684
                        for (i=0;i<nClicks;i++) {
 
685
                            XkbDDXFakePointerButton(ButtonPress,button);
 
686
                            XkbDDXFakePointerButton(ButtonRelease,button);
 
687
                        }
 
688
                        filter->upAction.type= XkbSA_NoAction;
 
689
                    }
 
690
                    else XkbDDXFakePointerButton(ButtonPress,button);
 
691
                }
 
692
                break;
 
693
            case XkbSA_SetPtrDflt:
 
694
                {
 
695
                    XkbControlsPtr      ctrls= xkbi->desc->ctrls;
 
696
                    XkbControlsRec      old;
 
697
                    xkbControlsNotify   cn;
 
698
 
 
699
                    old= *ctrls;
 
700
                    AccessXCancelRepeatKey(xkbi,keycode);
 
701
                    switch (pAction->dflt.affect) {
 
702
                        case XkbSA_AffectDfltBtn:
 
703
                            if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute)
 
704
                                ctrls->mk_dflt_btn= 
 
705
                                        XkbSAPtrDfltValue(&pAction->dflt);
 
706
                            else {
 
707
                                ctrls->mk_dflt_btn+=
 
708
                                        XkbSAPtrDfltValue(&pAction->dflt);
 
709
                                if (ctrls->mk_dflt_btn>5)
 
710
                                    ctrls->mk_dflt_btn= 5;
 
711
                                else if (ctrls->mk_dflt_btn<1)
 
712
                                    ctrls->mk_dflt_btn= 1;
 
713
                            }
 
714
                            break;
 
715
                        default:
 
716
                            ErrorF(
 
717
                "Attempt to change unknown pointer default (%d) ignored\n",
 
718
                                                        pAction->dflt.affect);
 
719
                            break;
 
720
                    }
 
721
                    if (XkbComputeControlsNotify(xkbi->device,
 
722
                                                &old,xkbi->desc->ctrls,
 
723
                                                &cn,False)) {
 
724
                        cn.keycode = keycode;
 
725
                        cn.eventType = KeyPress;
 
726
                        cn.requestMajor = 0;
 
727
                        cn.requestMinor = 0;
 
728
                        XkbSendControlsNotify(xkbi->device,&cn);
 
729
                    }
 
730
                }
 
731
                break;
 
732
        }
 
733
    }
 
734
    else if (filter->keycode==keycode) {
 
735
        int     button= filter->upAction.btn.button;
 
736
 
 
737
        switch (filter->upAction.type) {
 
738
            case XkbSA_LockPtrBtn:
 
739
                if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)||
 
740
                                ((xkbi->lockedPtrButtons&(1<<button))==0)) {
 
741
                    break;
 
742
                }
 
743
                xkbi->lockedPtrButtons&= ~(1<<button);
 
744
            case XkbSA_PtrBtn:
 
745
                XkbDDXFakePointerButton(ButtonRelease,button);
 
746
                break;
 
747
        }
 
748
        filter->active = 0;
 
749
    }
 
750
    return 0;
 
751
}
 
752
 
 
753
static int
 
754
#if NeedFunctionPrototypes
 
755
_XkbFilterControls(     XkbSrvInfoPtr   xkbi,
 
756
                        XkbFilterPtr    filter,
 
757
                        unsigned        keycode,
 
758
                        XkbAction *     pAction)
 
759
#else
 
760
_XkbFilterControls(xkbi,filter,keycode,pAction)
 
761
    XkbSrvInfoPtr       xkbi;
 
762
    XkbFilterPtr        filter;
 
763
    unsigned            keycode;
 
764
    XkbAction *         pAction;
 
765
#endif
 
766
{
 
767
XkbControlsRec          old;
 
768
XkbControlsPtr          ctrls;
 
769
DeviceIntPtr            kbd;
 
770
unsigned int            change;
 
771
XkbEventCauseRec        cause;
 
772
 
 
773
    kbd= xkbi->device;
 
774
    ctrls= xkbi->desc->ctrls;
 
775
    old= *ctrls;
 
776
    if (filter->keycode==0) {           /* initial press */
 
777
        filter->keycode = keycode;
 
778
        filter->active = 1;
 
779
        filter->filterOthers = 0;
 
780
        change= XkbActionCtrls(&pAction->ctrls);
 
781
        filter->priv = change;
 
782
        filter->filter = _XkbFilterControls;
 
783
        filter->upAction = *pAction;
 
784
 
 
785
        if (pAction->type==XkbSA_LockControls) {
 
786
            filter->priv= (ctrls->enabled_ctrls&change);
 
787
            change&= ~ctrls->enabled_ctrls;
 
788
        }
 
789
 
 
790
        if (change) {
 
791
            xkbControlsNotify   cn;
 
792
            XkbSrvLedInfoPtr    sli;
 
793
 
 
794
            ctrls->enabled_ctrls|= change;
 
795
            if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,False)) {
 
796
                cn.keycode = keycode;
 
797
                cn.eventType = KeyPress;
 
798
                cn.requestMajor = 0;
 
799
                cn.requestMinor = 0;
 
800
                XkbSendControlsNotify(kbd,&cn);
 
801
            }
 
802
 
 
803
            XkbSetCauseKey(&cause,keycode,KeyPress);
 
804
 
 
805
            /* If sticky keys were disabled, clear all locks and latches */
 
806
            if ((old.enabled_ctrls&XkbStickyKeysMask)&&
 
807
                (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
 
808
                XkbClearAllLatchesAndLocks(kbd,xkbi,False,&cause);
 
809
            }
 
810
            sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
 
811
            XkbUpdateIndicators(kbd,sli->usesControls,True,NULL,&cause);
 
812
            if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
 
813
                XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change);
 
814
        }
 
815
    }
 
816
    else if (filter->keycode==keycode) {
 
817
        change= filter->priv;
 
818
        if (change) {
 
819
            xkbControlsNotify   cn;
 
820
            XkbSrvLedInfoPtr    sli;
 
821
 
 
822
            ctrls->enabled_ctrls&= ~change;
 
823
            if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,False)) {
 
824
                cn.keycode = keycode;
 
825
                cn.eventType = KeyRelease;
 
826
                cn.requestMajor = 0;
 
827
                cn.requestMinor = 0;
 
828
                XkbSendControlsNotify(kbd,&cn);
 
829
            }
 
830
 
 
831
            XkbSetCauseKey(&cause,keycode,KeyRelease);
 
832
            /* If sticky keys were disabled, clear all locks and latches */
 
833
            if ((old.enabled_ctrls&XkbStickyKeysMask)&&
 
834
                (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
 
835
                XkbClearAllLatchesAndLocks(kbd,xkbi,False,&cause);
 
836
            }
 
837
            sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
 
838
            XkbUpdateIndicators(kbd,sli->usesControls,True,NULL,&cause);
 
839
            if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
 
840
                XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change);
 
841
        }
 
842
        filter->keycode= 0;
 
843
        filter->active= 0;
 
844
    }
 
845
    return 1;
 
846
}
 
847
 
 
848
static int
 
849
#if NeedFunctionPrototypes
 
850
_XkbFilterActionMessage(XkbSrvInfoPtr   xkbi,
 
851
                        XkbFilterPtr    filter,
 
852
                        unsigned        keycode,
 
853
                        XkbAction *     pAction)
 
854
#else
 
855
_XkbFilterActionMessage(xkbi,filter,keycode,pAction)
 
856
    XkbSrvInfoPtr       xkbi;
 
857
    XkbFilterPtr        filter;
 
858
    unsigned            keycode;
 
859
    XkbAction *         pAction;
 
860
#endif
 
861
{
 
862
XkbMessageAction *      pMsg;
 
863
DeviceIntPtr            kbd;
 
864
 
 
865
    kbd= xkbi->device;
 
866
    if (filter->keycode==0) {           /* initial press */
 
867
        pMsg= &pAction->msg;
 
868
        if ((pMsg->flags&XkbSA_MessageOnRelease)||
 
869
            ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) {
 
870
            filter->keycode = keycode;
 
871
            filter->active = 1;
 
872
            filter->filterOthers = 0;
 
873
            filter->priv = 0;
 
874
            filter->filter = _XkbFilterActionMessage;
 
875
            filter->upAction = *pAction;
 
876
        }
 
877
        if (pMsg->flags&XkbSA_MessageOnPress)  {
 
878
            xkbActionMessage    msg;
 
879
 
 
880
            msg.keycode= keycode;
 
881
            msg.press= 1;
 
882
            msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
 
883
            memcpy((char *)msg.message,
 
884
                                (char *)pMsg->message,XkbActionMessageLength);
 
885
            XkbSendActionMessage(kbd,&msg);
 
886
        }
 
887
        return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0);
 
888
    }
 
889
    else if (filter->keycode==keycode) {
 
890
        pMsg= &filter->upAction.msg;
 
891
        if (pMsg->flags&XkbSA_MessageOnRelease) {
 
892
            xkbActionMessage    msg;
 
893
 
 
894
            msg.keycode= keycode;
 
895
            msg.press= 0;
 
896
            msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
 
897
            memcpy((char *)msg.message,(char *)pMsg->message,
 
898
                                                XkbActionMessageLength);
 
899
            XkbSendActionMessage(kbd,&msg);
 
900
        }
 
901
        filter->keycode= 0;
 
902
        filter->active= 0;
 
903
        return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
 
904
    }
 
905
    return 0;
 
906
}
 
907
 
 
908
static int
 
909
#if NeedFunctionPrototypes
 
910
_XkbFilterRedirectKey(  XkbSrvInfoPtr   xkbi,
 
911
                        XkbFilterPtr    filter,
 
912
                        unsigned        keycode,
 
913
                        XkbAction *     pAction)
 
914
#else
 
915
_XkbFilterRedirectKey(xkbi,filter,keycode,pAction)
 
916
    XkbSrvInfoPtr       xkbi;
 
917
    XkbFilterPtr        filter;
 
918
    unsigned            keycode;
 
919
    XkbAction *         pAction;
 
920
#endif
 
921
{
 
922
unsigned        realMods;
 
923
xEvent          ev;
 
924
int             x,y;
 
925
XkbStateRec     old;
 
926
unsigned        mods,mask,oldCoreState = 0,oldCorePrevState = 0;
 
927
 
 
928
    if ((filter->keycode!=0)&&(filter->keycode!=keycode))
 
929
        return 1;
 
930
 
 
931
    GetSpritePosition(&x,&y);
 
932
    ev.u.keyButtonPointer.time = GetTimeInMillis();
 
933
    ev.u.keyButtonPointer.rootX = x;
 
934
    ev.u.keyButtonPointer.rootY = y;
 
935
 
 
936
    mask= XkbSARedirectVModsMask(&pAction->redirect);
 
937
    mods= XkbSARedirectVMods(&pAction->redirect);
 
938
    if (mask)   XkbVirtualModsToReal(xkbi->desc,mask,&mask);
 
939
    if (mods)   XkbVirtualModsToReal(xkbi->desc,mods,&mods);
 
940
    mask|= pAction->redirect.mods_mask;
 
941
    mods|= pAction->redirect.mods;
 
942
 
 
943
    if (filter->keycode==0) {           /* initial press */
 
944
        if ((pAction->redirect.new_key<xkbi->desc->min_key_code)||
 
945
            (pAction->redirect.new_key>xkbi->desc->max_key_code)) {
 
946
            return 1;
 
947
        }
 
948
        filter->keycode = keycode;
 
949
        filter->active = 1;
 
950
        filter->filterOthers = 0;
 
951
        filter->priv = 0;
 
952
        filter->filter = _XkbFilterRedirectKey;
 
953
        filter->upAction = *pAction;
 
954
 
 
955
        ev.u.u.type = KeyPress;
 
956
        ev.u.u.detail = pAction->redirect.new_key;
 
957
 
 
958
        if ( mask || mods ) {
 
959
            old= xkbi->state;
 
960
            oldCoreState= xkbi->device->key->state;
 
961
            oldCorePrevState= xkbi->device->key->prev_state;
 
962
            xkbi->state.base_mods&= ~mask;
 
963
            xkbi->state.base_mods|= (mods&mask);
 
964
            xkbi->state.latched_mods&= ~mask;
 
965
            xkbi->state.latched_mods|= (mods&mask);
 
966
            xkbi->state.locked_mods&= ~mask;
 
967
            xkbi->state.locked_mods|= (mods&mask);
 
968
            XkbComputeDerivedState(xkbi);
 
969
            xkbi->device->key->state= xkbi->device->key->prev_state= 
 
970
                                                        xkbi->state.mods;
 
971
        }
 
972
 
 
973
        realMods = xkbi->device->key->modifierMap[ev.u.u.detail];
 
974
        xkbi->device->key->modifierMap[ev.u.u.detail] = 0;
 
975
        CoreProcessKeyboardEvent(&ev,xkbi->device,1);
 
976
        xkbi->device->key->modifierMap[ev.u.u.detail] = realMods;
 
977
        
 
978
        if ( mask || mods ) {
 
979
            xkbi->device->key->state= oldCoreState;
 
980
            xkbi->device->key->prev_state= oldCorePrevState;
 
981
            xkbi->state= old;
 
982
        }
 
983
    }
 
984
    else if (filter->keycode==keycode) {
 
985
 
 
986
        ev.u.u.type = KeyRelease;
 
987
        ev.u.u.detail = filter->upAction.redirect.new_key;
 
988
 
 
989
        if ( mask || mods ) {
 
990
            old= xkbi->state;
 
991
            oldCoreState= xkbi->device->key->state;
 
992
            oldCorePrevState= xkbi->device->key->prev_state;
 
993
            xkbi->state.base_mods&= ~mask;
 
994
            xkbi->state.base_mods|= (mods&mask);
 
995
            xkbi->state.latched_mods&= ~mask;
 
996
            xkbi->state.latched_mods|= (mods&mask);
 
997
            xkbi->state.locked_mods&= ~mask;
 
998
            xkbi->state.locked_mods|= (mods&mask);
 
999
            XkbComputeDerivedState(xkbi);
 
1000
            xkbi->device->key->state= xkbi->device->key->prev_state= 
 
1001
                                                        xkbi->state.mods;
 
1002
        }
 
1003
 
 
1004
        realMods = xkbi->device->key->modifierMap[ev.u.u.detail];
 
1005
        xkbi->device->key->modifierMap[ev.u.u.detail] = 0;
 
1006
        CoreProcessKeyboardEvent(&ev,xkbi->device,1);
 
1007
        xkbi->device->key->modifierMap[ev.u.u.detail] = realMods;
 
1008
 
 
1009
        if ( mask || mods ) {
 
1010
            xkbi->device->key->state= oldCoreState;
 
1011
            xkbi->device->key->prev_state= oldCorePrevState;
 
1012
            xkbi->state= old;
 
1013
        }
 
1014
 
 
1015
        filter->keycode= 0;
 
1016
        filter->active= 0;
 
1017
    }
 
1018
    return 1;
 
1019
}
 
1020
 
 
1021
static int
 
1022
#if NeedFunctionPrototypes
 
1023
_XkbFilterSwitchScreen( XkbSrvInfoPtr   xkbi,
 
1024
                        XkbFilterPtr    filter,
 
1025
                        unsigned        keycode,
 
1026
                        XkbAction *     pAction)
 
1027
#else
 
1028
_XkbFilterSwitchScreen(xkbi,filter,keycode,pAction)
 
1029
    XkbSrvInfoPtr       xkbi;
 
1030
    XkbFilterPtr        filter;
 
1031
    unsigned            keycode;
 
1032
    XkbAction *         pAction;
 
1033
#endif
 
1034
{
 
1035
    if (filter->keycode==0) {           /* initial press */
 
1036
        DeviceIntPtr    dev = xkbi->device;
 
1037
        filter->keycode = keycode;
 
1038
        filter->active = 1;
 
1039
        filter->filterOthers = 0;
 
1040
        filter->filter = _XkbFilterSwitchScreen;
 
1041
        AccessXCancelRepeatKey(xkbi, keycode);
 
1042
        XkbDDXSwitchScreen(dev,keycode,pAction);
 
1043
        return 0; 
 
1044
    }
 
1045
    else if (filter->keycode==keycode) {
 
1046
        filter->active= 0;
 
1047
        return 0; 
 
1048
    }
 
1049
    return 1;
 
1050
}
 
1051
 
 
1052
#ifdef XFree86Server
 
1053
static int
 
1054
#if NeedFunctionPrototypes
 
1055
_XkbFilterXF86Private(  XkbSrvInfoPtr   xkbi,
 
1056
                        XkbFilterPtr    filter,
 
1057
                        unsigned        keycode,
 
1058
                        XkbAction *     pAction)
 
1059
#else
 
1060
_XkbFilterXF86Private(xkbi,filter,keycode,pAction)
 
1061
    XkbSrvInfoPtr       xkbi;
 
1062
    XkbFilterPtr        filter;
 
1063
    unsigned            keycode;
 
1064
    XkbAction *         pAction;
 
1065
#endif
 
1066
{
 
1067
    if (filter->keycode==0) {           /* initial press */
 
1068
        DeviceIntPtr    dev = xkbi->device;
 
1069
        filter->keycode = keycode;
 
1070
        filter->active = 1;
 
1071
        filter->filterOthers = 0;
 
1072
        filter->filter = _XkbFilterXF86Private;
 
1073
        XkbDDXPrivate(dev,keycode,pAction);
 
1074
        return 0; 
 
1075
    }
 
1076
    else if (filter->keycode==keycode) {
 
1077
        filter->active= 0;
 
1078
        return 0; 
 
1079
    }
 
1080
    return 1;
 
1081
}
 
1082
#endif
 
1083
 
 
1084
#ifdef XINPUT
 
1085
 
 
1086
static int
 
1087
#if NeedFunctionPrototypes
 
1088
_XkbFilterDeviceBtn(    XkbSrvInfoPtr   xkbi,
 
1089
                        XkbFilterPtr    filter,
 
1090
                        unsigned        keycode,
 
1091
                        XkbAction *     pAction)
 
1092
#else
 
1093
_XkbFilterDeviceBtn(xkbi,filter,keycode,pAction)
 
1094
    XkbSrvInfoPtr       xkbi;
 
1095
    XkbFilterPtr        filter;
 
1096
    unsigned            keycode;
 
1097
    XkbAction *         pAction;
 
1098
#endif
 
1099
{
 
1100
DeviceIntPtr    dev;
 
1101
int             button;
 
1102
 
 
1103
    if (filter->keycode==0) {           /* initial press */
 
1104
        dev= _XkbLookupButtonDevice(pAction->devbtn.device,NULL);
 
1105
        if ((!dev)||(!dev->public.on)||(&dev->public==LookupPointerDevice()))
 
1106
            return 1;
 
1107
 
 
1108
        button= pAction->devbtn.button;
 
1109
        if ((button<1)||(button>dev->button->numButtons))
 
1110
            return 1;
 
1111
 
 
1112
        filter->keycode = keycode;
 
1113
        filter->active = 1;
 
1114
        filter->filterOthers = 0;
 
1115
        filter->priv=0;
 
1116
        filter->filter = _XkbFilterDeviceBtn;
 
1117
        filter->upAction= *pAction;
 
1118
        switch (pAction->type) {
 
1119
            case XkbSA_LockDeviceBtn:
 
1120
                if ((pAction->devbtn.flags&XkbSA_LockNoLock)||
 
1121
                    (dev->button->down[button/8]&(1L<<(button%8))))
 
1122
                    return 0;
 
1123
                XkbDDXFakeDeviceButton(dev,True,button);
 
1124
                filter->upAction.type= XkbSA_NoAction;
 
1125
                break;
 
1126
            case XkbSA_DeviceBtn:
 
1127
                if (pAction->devbtn.count>0) {
 
1128
                    int nClicks,i;
 
1129
                    nClicks= pAction->btn.count;
 
1130
                    for (i=0;i<nClicks;i++) {
 
1131
                        XkbDDXFakeDeviceButton(dev,True,button);
 
1132
                        XkbDDXFakeDeviceButton(dev,False,button);
 
1133
                    }
 
1134
                    filter->upAction.type= XkbSA_NoAction;
 
1135
                }
 
1136
                else XkbDDXFakeDeviceButton(dev,True,button);
 
1137
                break;
 
1138
        }
 
1139
    }
 
1140
    else if (filter->keycode==keycode) {
 
1141
        int     button;
 
1142
 
 
1143
        filter->active= 0;
 
1144
        dev= _XkbLookupButtonDevice(filter->upAction.devbtn.device,NULL);
 
1145
        if ((!dev)||(!dev->public.on)||(&dev->public==LookupPointerDevice()))
 
1146
            return 1;
 
1147
 
 
1148
        button= filter->upAction.btn.button;
 
1149
        switch (filter->upAction.type) {
 
1150
            case XkbSA_LockDeviceBtn:
 
1151
                if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)||
 
1152
                    ((dev->button->down[button/8]&(1L<<(button%8)))==0))
 
1153
                    return 0;
 
1154
                XkbDDXFakeDeviceButton(dev,False,button);
 
1155
                break;
 
1156
            case XkbSA_DeviceBtn:
 
1157
                XkbDDXFakeDeviceButton(dev,False,button);
 
1158
                break;
 
1159
        }
 
1160
        filter->active = 0;
 
1161
    }
 
1162
    return 0;
 
1163
}
 
1164
#endif
 
1165
 
 
1166
static  int             szFilters = 0;
 
1167
static  XkbFilterPtr    filters = NULL;
 
1168
 
 
1169
static XkbFilterPtr
 
1170
_XkbNextFreeFilter(
 
1171
#if NeedFunctionPrototypes
 
1172
        void
 
1173
#endif
 
1174
)
 
1175
{
 
1176
register int    i;
 
1177
 
 
1178
    if (szFilters==0) {
 
1179
        szFilters = 4;
 
1180
        filters = _XkbTypedCalloc(szFilters,XkbFilterRec);
 
1181
        /* 6/21/93 (ef) -- XXX! deal with allocation failure */
 
1182
    }
 
1183
    for (i=0;i<szFilters;i++) {
 
1184
        if (!filters[i].active) {
 
1185
            filters[i].keycode = 0;
 
1186
            return &filters[i];
 
1187
        }
 
1188
    }
 
1189
    szFilters*=2;
 
1190
    filters= _XkbTypedRealloc(filters,szFilters,XkbFilterRec);
 
1191
    /* 6/21/93 (ef) -- XXX! deal with allocation failure */
 
1192
    bzero(&filters[szFilters/2],(szFilters/2)*sizeof(XkbFilterRec));
 
1193
    return &filters[szFilters/2];
 
1194
}
 
1195
 
 
1196
static int
 
1197
#if NeedFunctionPrototypes
 
1198
_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction)
 
1199
#else
 
1200
_XkbApplyFilters(xkbi,kc,pAction)
 
1201
    XkbSrvInfoPtr       xkbi;
 
1202
    unsigned            kc;
 
1203
    XkbAction *         pAction;
 
1204
#endif
 
1205
{
 
1206
register int    i,send;
 
1207
 
 
1208
    send= 1;
 
1209
    for (i=0;i<szFilters;i++) {
 
1210
        if ((filters[i].active)&&(filters[i].filter))
 
1211
            send= ((*filters[i].filter)(xkbi,&filters[i],kc,pAction)&&send);
 
1212
    }
 
1213
    return send;
 
1214
}
 
1215
 
 
1216
void
 
1217
#if NeedFunctionPrototypes
 
1218
XkbHandleActions(DeviceIntPtr dev,DeviceIntPtr kbd,xEvent *xE,int count)
 
1219
#else
 
1220
XkbHandleActions(dev,kbd,xE,count)
 
1221
    DeviceIntPtr        dev;
 
1222
    DeviceIntPtr        kbd;
 
1223
    xEvent *            xE;
 
1224
    int                 count;
 
1225
#endif
 
1226
{
 
1227
int             key,bit,i;
 
1228
CARD8           realMods;
 
1229
XkbSrvInfoPtr   xkbi;
 
1230
KeyClassPtr     keyc;
 
1231
int             changed,sendEvent;
 
1232
Bool            genStateNotify;
 
1233
XkbStateRec     oldState;
 
1234
XkbAction       act;
 
1235
XkbFilterPtr    filter;
 
1236
Bool            keyEvent;
 
1237
Bool            pressEvent;
 
1238
#ifdef XINPUT
 
1239
Bool            xiEvent;
 
1240
#endif
 
1241
 
 
1242
    keyc= kbd->key;
 
1243
    xkbi= keyc->xkbInfo;
 
1244
    key= xE->u.u.detail;
 
1245
    if ((xkbi->flags&_XkbStateNotifyInProgress)==0) {
 
1246
        oldState= xkbi->state;
 
1247
        xkbi->flags|= _XkbStateNotifyInProgress;
 
1248
        genStateNotify= True;
 
1249
    }
 
1250
    else genStateNotify= False;
 
1251
 
 
1252
    xkbi->clearMods = xkbi->setMods = 0;
 
1253
    xkbi->groupChange = 0;
 
1254
 
 
1255
    sendEvent = 1;
 
1256
#ifdef XINPUT
 
1257
    keyEvent= ((xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)||
 
1258
                (xE->u.u.type==KeyRelease)||(xE->u.u.type==DeviceKeyRelease));
 
1259
    pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)||
 
1260
                 (xE->u.u.type==ButtonPress)||(xE->u.u.type==DeviceButtonPress);
 
1261
    xiEvent= (xE->u.u.type==DeviceKeyPress)||(xE->u.u.type==DeviceKeyRelease)||
 
1262
             (xE->u.u.type==DeviceButtonPress)||
 
1263
             (xE->u.u.type==DeviceButtonRelease);
 
1264
#else
 
1265
    keyEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease);
 
1266
    pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==ButtonPress);
 
1267
#endif
 
1268
 
 
1269
    if (pressEvent) {
 
1270
        if (keyEvent)   
 
1271
            act = XkbGetKeyAction(xkbi,&xkbi->state,key);
 
1272
        else {
 
1273
            act = XkbGetButtonAction(kbd,dev,key);
 
1274
            key|= BTN_ACT_FLAG;
 
1275
        }
 
1276
        sendEvent = _XkbApplyFilters(xkbi,key,&act);
 
1277
        if (sendEvent) {
 
1278
            switch (act.type) {
 
1279
                case XkbSA_SetMods:
 
1280
                case XkbSA_SetGroup:
 
1281
                    filter = _XkbNextFreeFilter();
 
1282
                    sendEvent = _XkbFilterSetState(xkbi,filter,key,&act);
 
1283
                    break;
 
1284
                case XkbSA_LatchMods:
 
1285
                case XkbSA_LatchGroup:
 
1286
                    filter = _XkbNextFreeFilter();
 
1287
                    sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act);
 
1288
                    break;
 
1289
                case XkbSA_LockMods:
 
1290
                case XkbSA_LockGroup:
 
1291
                    filter = _XkbNextFreeFilter();
 
1292
                    sendEvent=_XkbFilterLockState(xkbi,filter,key,&act);
 
1293
                    break;
 
1294
                case XkbSA_ISOLock:
 
1295
                    filter = _XkbNextFreeFilter();
 
1296
                    sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act);
 
1297
                    break;
 
1298
                case XkbSA_MovePtr:
 
1299
                    filter = _XkbNextFreeFilter();
 
1300
                    sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act);
 
1301
                    break;
 
1302
                case XkbSA_PtrBtn:
 
1303
                case XkbSA_LockPtrBtn:
 
1304
                case XkbSA_SetPtrDflt:
 
1305
                    filter = _XkbNextFreeFilter();
 
1306
                    sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act);
 
1307
                    break;
 
1308
                case XkbSA_Terminate:
 
1309
                    sendEvent= XkbDDXTerminateServer(dev,key,&act);
 
1310
                    break;
 
1311
                case XkbSA_SwitchScreen:
 
1312
                    filter = _XkbNextFreeFilter();
 
1313
                    sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act);
 
1314
                    break;
 
1315
                case XkbSA_SetControls:
 
1316
                case XkbSA_LockControls:
 
1317
                    filter = _XkbNextFreeFilter();
 
1318
                    sendEvent=_XkbFilterControls(xkbi,filter,key,&act);
 
1319
                    break;
 
1320
                case XkbSA_ActionMessage:
 
1321
                    filter = _XkbNextFreeFilter();
 
1322
                    sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act);
 
1323
                    break;
 
1324
                case XkbSA_RedirectKey:
 
1325
                    filter = _XkbNextFreeFilter();
 
1326
                    sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act);
 
1327
                    break;
 
1328
#ifdef XINPUT
 
1329
                case XkbSA_DeviceBtn:
 
1330
                case XkbSA_LockDeviceBtn:
 
1331
                    filter = _XkbNextFreeFilter();
 
1332
                    sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act);
 
1333
                    break;
 
1334
#endif
 
1335
#ifdef XFree86Server
 
1336
                case XkbSA_XFree86Private:
 
1337
                    filter = _XkbNextFreeFilter();
 
1338
                    sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act);
 
1339
                    break;
 
1340
#endif
 
1341
            }
 
1342
        }
 
1343
    }
 
1344
    else {
 
1345
        if (!keyEvent)
 
1346
            key|= BTN_ACT_FLAG;
 
1347
        sendEvent = _XkbApplyFilters(xkbi,key,NULL);
 
1348
    }
 
1349
 
 
1350
    if (xkbi->groupChange!=0)
 
1351
        xkbi->state.base_group+= xkbi->groupChange;
 
1352
    if (xkbi->setMods) {
 
1353
        for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) {
 
1354
            if (xkbi->setMods&bit) {
 
1355
                keyc->modifierKeyCount[i]++;
 
1356
                xkbi->state.base_mods|= bit;
 
1357
                xkbi->setMods&= ~bit;
 
1358
            }
 
1359
        }
 
1360
    }
 
1361
    if (xkbi->clearMods) {
 
1362
        for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) {
 
1363
            if (xkbi->clearMods&bit) {
 
1364
                keyc->modifierKeyCount[i]--;
 
1365
                if (keyc->modifierKeyCount[i]<=0) {
 
1366
                    xkbi->state.base_mods&= ~bit;
 
1367
                    keyc->modifierKeyCount[i] = 0;
 
1368
                }
 
1369
                xkbi->clearMods&= ~bit;
 
1370
            }
 
1371
        }
 
1372
    }
 
1373
 
 
1374
    if (sendEvent) {
 
1375
#ifdef XINPUT
 
1376
        if (xiEvent)
 
1377
            ProcessOtherEvent(xE,dev,count);
 
1378
        else 
 
1379
#endif
 
1380
        if (keyEvent) {
 
1381
            realMods = keyc->modifierMap[key];
 
1382
            keyc->modifierMap[key] = 0;
 
1383
            CoreProcessKeyboardEvent(xE,dev,count);
 
1384
            keyc->modifierMap[key] = realMods;
 
1385
        }
 
1386
        else CoreProcessPointerEvent(xE,dev,count);
 
1387
    }
 
1388
    else if (keyEvent)
 
1389
        FixKeyState(xE,dev);
 
1390
 
 
1391
    xkbi->prev_state= oldState;
 
1392
    XkbComputeDerivedState(xkbi);
 
1393
    keyc->prev_state= keyc->state;
 
1394
    keyc->state= XkbStateFieldFromRec(&xkbi->state);
 
1395
    changed = XkbStateChangedFlags(&oldState,&xkbi->state);
 
1396
    if (genStateNotify) {
 
1397
        if (changed) {
 
1398
            xkbStateNotify      sn;
 
1399
            sn.keycode= key;
 
1400
            sn.eventType= xE->u.u.type;
 
1401
            sn.requestMajor = sn.requestMinor = 0;
 
1402
            sn.changed= changed;
 
1403
            XkbSendStateNotify(dev,&sn);
 
1404
        }
 
1405
        xkbi->flags&= ~_XkbStateNotifyInProgress;
 
1406
    }
 
1407
    changed= XkbIndicatorsToUpdate(dev,changed,False);
 
1408
    if (changed) {
 
1409
        XkbEventCauseRec        cause;
 
1410
        XkbSetCauseKey(&cause,key,xE->u.u.type);
 
1411
        XkbUpdateIndicators(dev,changed,True,NULL,&cause);
 
1412
    }
 
1413
    return;
 
1414
}
 
1415
 
 
1416
int
 
1417
#if NeedFunctionPrototypes
 
1418
XkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches)
 
1419
#else
 
1420
XkbLatchModifiers(pXDev,mask,latches)
 
1421
    DeviceIntPtr        pXDev;
 
1422
    CARD8               mask;
 
1423
    CARD8               latches;
 
1424
#endif
 
1425
{
 
1426
XkbSrvInfoPtr   xkbi;
 
1427
XkbFilterPtr    filter;
 
1428
XkbAction       act;
 
1429
unsigned        clear;
 
1430
 
 
1431
    if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
 
1432
        xkbi = pXDev->key->xkbInfo;
 
1433
        clear= (mask&(~latches));
 
1434
        xkbi->state.latched_mods&= ~clear;
 
1435
        /* Clear any pending latch to locks.
 
1436
         */
 
1437
        act.type = XkbSA_NoAction;
 
1438
        _XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act);
 
1439
        act.type = XkbSA_LatchMods;
 
1440
        act.mods.flags = 0;
 
1441
        act.mods.mask  = mask&latches;
 
1442
        filter = _XkbNextFreeFilter();
 
1443
        _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
 
1444
        _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
 
1445
        return Success;
 
1446
    }
 
1447
    return BadValue;
 
1448
}
 
1449
 
 
1450
int
 
1451
#if NeedFunctionPrototypes
 
1452
XkbLatchGroup(DeviceIntPtr pXDev,int group)
 
1453
#else
 
1454
XkbLatchGroup(pXDev,group)
 
1455
    DeviceIntPtr  pXDev;
 
1456
    int           group;
 
1457
#endif
 
1458
{
 
1459
XkbSrvInfoPtr   xkbi;
 
1460
XkbFilterPtr    filter;
 
1461
XkbAction       act;
 
1462
 
 
1463
    if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
 
1464
        xkbi = pXDev->key->xkbInfo;
 
1465
        act.type = XkbSA_LatchGroup;
 
1466
        act.group.flags = 0;
 
1467
        XkbSASetGroup(&act.group,group);
 
1468
        filter = _XkbNextFreeFilter();
 
1469
        _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
 
1470
        _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
 
1471
        return Success;
 
1472
    }
 
1473
    return BadValue;
 
1474
}
 
1475
 
 
1476
/***====================================================================***/
 
1477
 
 
1478
void
 
1479
#if NeedFunctionPrototypes
 
1480
XkbClearAllLatchesAndLocks(     DeviceIntPtr            dev,
 
1481
                                XkbSrvInfoPtr           xkbi,
 
1482
                                Bool                    genEv,
 
1483
                                XkbEventCausePtr        cause)
 
1484
#else
 
1485
XkbClearAllLatchesAndLocks(dev,xkbi,genEv,cause)
 
1486
    DeviceIntPtr        dev;
 
1487
    XkbSrvInfoPtr       xkbi;
 
1488
    Bool                genEv;
 
1489
    XkbEventCausePtr    cause;
 
1490
#endif
 
1491
{
 
1492
XkbStateRec     os;
 
1493
xkbStateNotify  sn;
 
1494
 
 
1495
    sn.changed= 0;
 
1496
    os= xkbi->state;
 
1497
    if (os.latched_mods) { /* clear all latches */
 
1498
        XkbLatchModifiers(dev,~0,0);
 
1499
        sn.changed|= XkbModifierLatchMask;
 
1500
    }
 
1501
    if (os.latched_group) {
 
1502
        XkbLatchGroup(dev,0);
 
1503
        sn.changed|= XkbGroupLatchMask;
 
1504
    }
 
1505
    if (os.locked_mods) {
 
1506
        xkbi->state.locked_mods= 0;
 
1507
        sn.changed|= XkbModifierLockMask;
 
1508
    }
 
1509
    if (os.locked_group) {
 
1510
        xkbi->state.locked_group= 0;
 
1511
        sn.changed|= XkbGroupLockMask;
 
1512
    }
 
1513
    if ( genEv && sn.changed) {
 
1514
        CARD32  changed;
 
1515
 
 
1516
        XkbComputeDerivedState(xkbi);
 
1517
        sn.keycode=             cause->kc;
 
1518
        sn.eventType=           cause->event;
 
1519
        sn.requestMajor=        cause->mjr;
 
1520
        sn.requestMinor=        cause->mnr;
 
1521
        sn.changed= XkbStateChangedFlags(&os,&xkbi->state);
 
1522
        XkbSendStateNotify(dev,&sn);
 
1523
        changed= XkbIndicatorsToUpdate(dev,sn.changed,False);
 
1524
        if (changed) {
 
1525
            XkbUpdateIndicators(dev,changed,True,NULL,cause);
 
1526
        }
 
1527
    }
 
1528
    return;
 
1529
}
 
1530