tizen 2.4 release
[framework/uifw/xorg/server/xorg-server.git] / xkb / xkbActions.c
1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be 
10 used in advertising or publicity pertaining to distribution 
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability 
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
15
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25 ********************************************************/
26
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
29 #endif
30
31 #include <stdio.h>
32 #include <math.h>
33 #include <X11/X.h>
34 #include <X11/Xproto.h>
35 #include <X11/keysym.h>
36 #include "misc.h"
37 #include "inputstr.h"
38 #include "exevents.h"
39 #include "eventstr.h"
40 #include <xkbsrv.h>
41 #include "xkb.h"
42 #include <ctype.h>
43 #include "mi.h"
44 #include "mipointer.h"
45 #include "inpututils.h"
46 #define EXTENSION_EVENT_BASE 64
47
48 DevPrivateKeyRec xkbDevicePrivateKeyRec;
49
50 static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x,
51                                  int y);
52
53 void
54 xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, void *data)
55 {
56     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
57     ProcessInputProc backupproc;
58
59     if (xkbPrivPtr->unwrapProc)
60         xkbPrivPtr->unwrapProc = NULL;
61
62     UNWRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, backupproc);
63     proc(device, data);
64     COND_WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, backupproc, xkbUnwrapProc);
65 }
66
67 Bool
68 XkbInitPrivates(void)
69 {
70     return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec, PRIVATE_DEVICE,
71                                  sizeof(xkbDeviceInfoRec));
72 }
73
74 void
75 XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
76 {
77     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
78
79     WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc);
80 }
81
82 /***====================================================================***/
83
84 static XkbAction
85 _FixUpAction(XkbDescPtr xkb, XkbAction *act)
86 {
87     static XkbAction fake;
88
89     if (XkbIsPtrAction(act) &&
90         (!(xkb->ctrls->enabled_ctrls & XkbMouseKeysMask))) {
91         fake.type = XkbSA_NoAction;
92         return fake;
93     }
94     if (xkb->ctrls->enabled_ctrls & XkbStickyKeysMask) {
95         if (act->any.type == XkbSA_SetMods) {
96             fake.mods.type = XkbSA_LatchMods;
97             fake.mods.mask = act->mods.mask;
98             if (XkbAX_NeedOption(xkb->ctrls, XkbAX_LatchToLockMask))
99                 fake.mods.flags = XkbSA_ClearLocks | XkbSA_LatchToLock;
100             else
101                 fake.mods.flags = XkbSA_ClearLocks;
102             return fake;
103         }
104         if (act->any.type == XkbSA_SetGroup) {
105             fake.group.type = XkbSA_LatchGroup;
106             if (XkbAX_NeedOption(xkb->ctrls, XkbAX_LatchToLockMask))
107                 fake.group.flags = XkbSA_ClearLocks | XkbSA_LatchToLock;
108             else
109                 fake.group.flags = XkbSA_ClearLocks;
110             XkbSASetGroup(&fake.group, XkbSAGroup(&act->group));
111             return fake;
112         }
113     }
114     return *act;
115 }
116
117 static XkbAction
118 XkbGetKeyAction(XkbSrvInfoPtr xkbi, XkbStatePtr xkbState, CARD8 key)
119 {
120     int effectiveGroup;
121     int col;
122     XkbDescPtr xkb;
123     XkbKeyTypePtr type;
124     XkbAction *pActs;
125     static XkbAction fake;
126
127     xkb = xkbi->desc;
128     if (!XkbKeyHasActions(xkb, key) || !XkbKeycodeInRange(xkb, key)) {
129         fake.type = XkbSA_NoAction;
130         return fake;
131     }
132     pActs = XkbKeyActionsPtr(xkb, key);
133     col = 0;
134
135     effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key);
136     if (effectiveGroup != XkbGroup1Index)
137         col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key));
138
139     type = XkbKeyKeyType(xkb, key, effectiveGroup);
140     if (type->map != NULL) {
141         register unsigned i, mods;
142         register XkbKTMapEntryPtr entry;
143
144         mods = xkbState->mods & type->mods.mask;
145         for (entry = type->map, i = 0; i < type->map_count; i++, entry++) {
146             if ((entry->active) && (entry->mods.mask == mods)) {
147                 col += entry->level;
148                 break;
149             }
150         }
151     }
152     if (pActs[col].any.type == XkbSA_NoAction)
153         return pActs[col];
154     fake = _FixUpAction(xkb, &pActs[col]);
155     return fake;
156 }
157
158 static XkbAction
159 XkbGetButtonAction(DeviceIntPtr kbd, DeviceIntPtr dev, int button)
160 {
161     XkbAction fake;
162
163     if ((dev->button) && (dev->button->xkb_acts)) {
164         if (dev->button->xkb_acts[button - 1].any.type != XkbSA_NoAction) {
165             fake = _FixUpAction(kbd->key->xkbInfo->desc,
166                                 &dev->button->xkb_acts[button - 1]);
167             return fake;
168         }
169     }
170     fake.any.type = XkbSA_NoAction;
171     return fake;
172 }
173
174 /***====================================================================***/
175
176 #define SYNTHETIC_KEYCODE       1
177 #define BTN_ACT_FLAG            0x100
178
179 static int
180 _XkbFilterSetState(XkbSrvInfoPtr xkbi,
181                    XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
182 {
183     if (filter->keycode == 0) { /* initial press */
184         filter->keycode = keycode;
185         filter->active = 1;
186         filter->filterOthers = ((pAction->mods.mask & XkbSA_ClearLocks) != 0);
187         filter->priv = 0;
188         filter->filter = _XkbFilterSetState;
189         if (pAction->type == XkbSA_SetMods) {
190             filter->upAction = *pAction;
191             xkbi->setMods = pAction->mods.mask;
192         }
193         else {
194             xkbi->groupChange = XkbSAGroup(&pAction->group);
195             if (pAction->group.flags & XkbSA_GroupAbsolute)
196                 xkbi->groupChange -= xkbi->state.base_group;
197             filter->upAction = *pAction;
198             XkbSASetGroup(&filter->upAction.group, xkbi->groupChange);
199         }
200     }
201     else if (filter->keycode == keycode) {
202         if (filter->upAction.type == XkbSA_SetMods) {
203             xkbi->clearMods = filter->upAction.mods.mask;
204             if (filter->upAction.mods.flags & XkbSA_ClearLocks) {
205                 xkbi->state.locked_mods &= ~filter->upAction.mods.mask;
206             }
207         }
208         else {
209             if (filter->upAction.group.flags & XkbSA_ClearLocks) {
210                 xkbi->state.locked_group = 0;
211             }
212             xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
213         }
214         filter->active = 0;
215     }
216     else {
217         filter->upAction.mods.flags &= ~XkbSA_ClearLocks;
218         filter->filterOthers = 0;
219     }
220     return 1;
221 }
222
223 #define LATCH_KEY_DOWN  1
224 #define LATCH_PENDING   2
225
226 static int
227 _XkbFilterLatchState(XkbSrvInfoPtr xkbi,
228                      XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
229 {
230
231     if (filter->keycode == 0) { /* initial press */
232         AccessXCancelRepeatKey(xkbi,keycode);
233         filter->keycode = keycode;
234         filter->active = 1;
235         filter->filterOthers = 1;
236         filter->priv = LATCH_KEY_DOWN;
237         filter->filter = _XkbFilterLatchState;
238         if (pAction->type == XkbSA_LatchMods) {
239             filter->upAction = *pAction;
240             xkbi->setMods = pAction->mods.mask;
241         }
242         else {
243             xkbi->groupChange = XkbSAGroup(&pAction->group);
244             if (pAction->group.flags & XkbSA_GroupAbsolute)
245                 xkbi->groupChange -= xkbi->state.base_group;
246             filter->upAction = *pAction;
247             XkbSASetGroup(&filter->upAction.group, xkbi->groupChange);
248         }
249     }
250     else if (pAction && (filter->priv == LATCH_PENDING)) {
251         if (((1 << pAction->type) & XkbSA_BreakLatch) != 0) {
252             filter->active = 0;
253             /* If one latch is broken, all latches are broken, so it's no use
254                to find out which particular latch this filter tracks. */
255             xkbi->state.latched_mods = 0;
256             xkbi->state.latched_group = 0;
257         }
258     }
259     else if (filter->keycode == keycode && filter->priv != LATCH_PENDING){
260         /* The test above for LATCH_PENDING skips subsequent releases of the
261            key after it has been released first time and the latch became
262            pending. */
263         XkbControlsPtr ctrls = xkbi->desc->ctrls;
264         int needBeep = ((ctrls->enabled_ctrls & XkbStickyKeysMask) &&
265                         XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask));
266
267         if (filter->upAction.type == XkbSA_LatchMods) {
268             unsigned char mask = filter->upAction.mods.mask;
269             unsigned char common;
270
271             xkbi->clearMods = mask;
272
273             /* ClearLocks */
274             common = mask & xkbi->state.locked_mods;
275             if ((filter->upAction.mods.flags & XkbSA_ClearLocks) && common) {
276                 mask &= ~common;
277                 xkbi->state.locked_mods &= ~common;
278                 if (needBeep)
279                     XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK,
280                                       XkbStickyKeysMask);
281             }
282             /* LatchToLock */
283             common = mask & xkbi->state.latched_mods;
284             if ((filter->upAction.mods.flags & XkbSA_LatchToLock) && common) {
285                 unsigned char newlocked;
286
287                 mask &= ~common;
288                 newlocked = common & ~xkbi->state.locked_mods;
289                 if(newlocked){
290                     xkbi->state.locked_mods |= newlocked;
291                     if (needBeep)
292                         XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK,
293                                           XkbStickyKeysMask);
294
295                 }
296                 xkbi->state.latched_mods &= ~common;
297             }
298             /* Latch remaining modifiers, if any. */
299             if (mask) {
300                 xkbi->state.latched_mods |= mask;
301                 filter->priv = LATCH_PENDING;
302                 if (needBeep)
303                     XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH,
304                                       XkbStickyKeysMask);
305             }
306         }
307         else {
308             xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
309             /* ClearLocks */
310             if ((filter->upAction.group.flags & XkbSA_ClearLocks) &&
311                 (xkbi->state.locked_group)) {
312                 xkbi->state.locked_group = 0;
313                 if (needBeep)
314                     XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK,
315                                       XkbStickyKeysMask);
316             }
317             /* LatchToLock */
318             else if ((filter->upAction.group.flags & XkbSA_LatchToLock)
319                      && (xkbi->state.latched_group)) {
320                 xkbi->state.locked_group  += XkbSAGroup(&filter->upAction.group);
321                 xkbi->state.latched_group -= XkbSAGroup(&filter->upAction.group);
322                 if(XkbSAGroup(&filter->upAction.group) && needBeep)
323                     XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK,
324                                       XkbStickyKeysMask);
325             }
326             /* Latch group */
327             else if(XkbSAGroup(&filter->upAction.group)){
328                 xkbi->state.latched_group += XkbSAGroup(&filter->upAction.group);
329                 filter->priv = LATCH_PENDING;
330                 if (needBeep)
331                     XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH,
332                                       XkbStickyKeysMask);
333             }
334         }
335
336         if (filter->priv != LATCH_PENDING)
337             filter->active = 0;
338     }
339     else if (pAction && (filter->priv == LATCH_KEY_DOWN)) {
340         /* Latch was broken before it became pending: degrade to a
341            SetMods/SetGroup. */
342         if (filter->upAction.type == XkbSA_LatchMods)
343             filter->upAction.type = XkbSA_SetMods;
344         else
345             filter->upAction.type = XkbSA_SetGroup;
346         filter->filter = _XkbFilterSetState;
347         filter->priv = 0;
348         return filter->filter(xkbi, filter, keycode, pAction);
349     }
350     return 1;
351 }
352
353 static int
354 _XkbFilterLockState(XkbSrvInfoPtr xkbi,
355                     XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
356 {
357     if (pAction && (pAction->type == XkbSA_LockGroup)) {
358         if (pAction->group.flags & XkbSA_GroupAbsolute)
359             xkbi->state.locked_group = XkbSAGroup(&pAction->group);
360         else
361             xkbi->state.locked_group += XkbSAGroup(&pAction->group);
362         return 1;
363     }
364     if (filter->keycode == 0) { /* initial press */
365         filter->keycode = keycode;
366         filter->active = 1;
367         filter->filterOthers = 0;
368         filter->priv = xkbi->state.locked_mods & pAction->mods.mask;
369         filter->filter = _XkbFilterLockState;
370         filter->upAction = *pAction;
371         if (!(filter->upAction.mods.flags & XkbSA_LockNoLock))
372             xkbi->state.locked_mods |= pAction->mods.mask;
373         xkbi->setMods = pAction->mods.mask;
374     }
375     else if (filter->keycode == keycode) {
376         filter->active = 0;
377         xkbi->clearMods = filter->upAction.mods.mask;
378         if (!(filter->upAction.mods.flags & XkbSA_LockNoUnlock))
379             xkbi->state.locked_mods &= ~filter->priv;
380     }
381     return 1;
382 }
383
384 #define ISO_KEY_DOWN            0
385 #define NO_ISO_LOCK             1
386
387 static int
388 _XkbFilterISOLock(XkbSrvInfoPtr xkbi,
389                   XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
390 {
391
392     if (filter->keycode == 0) { /* initial press */
393         CARD8 flags = pAction->iso.flags;
394
395         filter->keycode = keycode;
396         filter->active = 1;
397         filter->filterOthers = 1;
398         filter->priv = ISO_KEY_DOWN;
399         filter->upAction = *pAction;
400         filter->filter = _XkbFilterISOLock;
401         if (flags & XkbSA_ISODfltIsGroup) {
402             xkbi->groupChange = XkbSAGroup(&pAction->iso);
403             xkbi->setMods = 0;
404         }
405         else {
406             xkbi->setMods = pAction->iso.mask;
407             xkbi->groupChange = 0;
408         }
409         if ((!(flags & XkbSA_ISONoAffectMods)) && (xkbi->state.base_mods)) {
410             filter->priv = NO_ISO_LOCK;
411             xkbi->state.locked_mods ^= xkbi->state.base_mods;
412         }
413         if ((!(flags & XkbSA_ISONoAffectGroup)) && (xkbi->state.base_group)) {
414 /* 6/22/93 (ef) -- lock groups if group key is down first */
415         }
416         if (!(flags & XkbSA_ISONoAffectPtr)) {
417 /* 6/22/93 (ef) -- lock mouse buttons if they're down */
418         }
419     }
420     else if (filter->keycode == keycode) {
421         CARD8 flags = filter->upAction.iso.flags;
422
423         if (flags & XkbSA_ISODfltIsGroup) {
424             xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
425             xkbi->clearMods = 0;
426             if (filter->priv == ISO_KEY_DOWN)
427                 xkbi->state.locked_group += XkbSAGroup(&filter->upAction.iso);
428         }
429         else {
430             xkbi->clearMods = filter->upAction.iso.mask;
431             xkbi->groupChange = 0;
432             if (filter->priv == ISO_KEY_DOWN)
433                 xkbi->state.locked_mods ^= filter->upAction.iso.mask;
434         }
435         filter->active = 0;
436     }
437     else if (pAction) {
438         CARD8 flags = filter->upAction.iso.flags;
439
440         switch (pAction->type) {
441         case XkbSA_SetMods:
442         case XkbSA_LatchMods:
443             if (!(flags & XkbSA_ISONoAffectMods)) {
444                 pAction->type = XkbSA_LockMods;
445                 filter->priv = NO_ISO_LOCK;
446             }
447             break;
448         case XkbSA_SetGroup:
449         case XkbSA_LatchGroup:
450             if (!(flags & XkbSA_ISONoAffectGroup)) {
451                 pAction->type = XkbSA_LockGroup;
452                 filter->priv = NO_ISO_LOCK;
453             }
454             break;
455         case XkbSA_PtrBtn:
456             if (!(flags & XkbSA_ISONoAffectPtr)) {
457                 pAction->type = XkbSA_LockPtrBtn;
458                 filter->priv = NO_ISO_LOCK;
459             }
460             break;
461         case XkbSA_SetControls:
462             if (!(flags & XkbSA_ISONoAffectCtrls)) {
463                 pAction->type = XkbSA_LockControls;
464                 filter->priv = NO_ISO_LOCK;
465             }
466             break;
467         }
468     }
469     return 1;
470 }
471
472 static CARD32
473 _XkbPtrAccelExpire(OsTimerPtr timer, CARD32 now, void *arg)
474 {
475     XkbSrvInfoPtr xkbi = (XkbSrvInfoPtr) arg;
476     XkbControlsPtr ctrls = xkbi->desc->ctrls;
477     int dx, dy;
478
479     if (xkbi->mouseKey == 0)
480         return 0;
481
482     if (xkbi->mouseKeysAccel) {
483         if ((xkbi->mouseKeysCounter) < ctrls->mk_time_to_max) {
484             double step;
485
486             xkbi->mouseKeysCounter++;
487             step = xkbi->mouseKeysCurveFactor *
488                 pow((double) xkbi->mouseKeysCounter, xkbi->mouseKeysCurve);
489             if (xkbi->mouseKeysDX < 0)
490                 dx = floor(((double) xkbi->mouseKeysDX) * step);
491             else
492                 dx = ceil(((double) xkbi->mouseKeysDX) * step);
493             if (xkbi->mouseKeysDY < 0)
494                 dy = floor(((double) xkbi->mouseKeysDY) * step);
495             else
496                 dy = ceil(((double) xkbi->mouseKeysDY) * step);
497         }
498         else {
499             dx = xkbi->mouseKeysDX * ctrls->mk_max_speed;
500             dy = xkbi->mouseKeysDY * ctrls->mk_max_speed;
501         }
502         if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteX)
503             dx = xkbi->mouseKeysDX;
504         if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteY)
505             dy = xkbi->mouseKeysDY;
506     }
507     else {
508         dx = xkbi->mouseKeysDX;
509         dy = xkbi->mouseKeysDY;
510     }
511     XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags, dx, dy);
512     return xkbi->desc->ctrls->mk_interval;
513 }
514
515 static int
516 _XkbFilterPointerMove(XkbSrvInfoPtr xkbi,
517                       XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
518 {
519     int x, y;
520     Bool accel;
521
522     if (filter->keycode == 0) { /* initial press */
523         filter->keycode = keycode;
524         filter->active = 1;
525         filter->filterOthers = 0;
526         filter->priv = 0;
527         filter->filter = _XkbFilterPointerMove;
528         filter->upAction = *pAction;
529         xkbi->mouseKeysCounter = 0;
530         xkbi->mouseKey = keycode;
531         accel = ((pAction->ptr.flags & XkbSA_NoAcceleration) == 0);
532         x = XkbPtrActionX(&pAction->ptr);
533         y = XkbPtrActionY(&pAction->ptr);
534         XkbFakePointerMotion(xkbi->device, pAction->ptr.flags, x, y);
535         AccessXCancelRepeatKey(xkbi, keycode);
536         xkbi->mouseKeysAccel = accel &&
537             (xkbi->desc->ctrls->enabled_ctrls & XkbMouseKeysAccelMask);
538         xkbi->mouseKeysFlags = pAction->ptr.flags;
539         xkbi->mouseKeysDX = XkbPtrActionX(&pAction->ptr);
540         xkbi->mouseKeysDY = XkbPtrActionY(&pAction->ptr);
541         xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0,
542                                        xkbi->desc->ctrls->mk_delay,
543                                        _XkbPtrAccelExpire, (void *) xkbi);
544     }
545     else if (filter->keycode == keycode) {
546         filter->active = 0;
547         if (xkbi->mouseKey == keycode) {
548             xkbi->mouseKey = 0;
549             xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0, 0,
550                                            NULL, NULL);
551         }
552     }
553     return 0;
554 }
555
556 static int
557 _XkbFilterPointerBtn(XkbSrvInfoPtr xkbi,
558                      XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
559 {
560     if (filter->keycode == 0) { /* initial press */
561         int button = pAction->btn.button;
562
563         if (button == XkbSA_UseDfltButton)
564             button = xkbi->desc->ctrls->mk_dflt_btn;
565
566         filter->keycode = keycode;
567         filter->active = 1;
568         filter->filterOthers = 0;
569         filter->priv = 0;
570         filter->filter = _XkbFilterPointerBtn;
571         filter->upAction = *pAction;
572         filter->upAction.btn.button = button;
573         switch (pAction->type) {
574         case XkbSA_LockPtrBtn:
575             if (((xkbi->lockedPtrButtons & (1 << button)) == 0) &&
576                 ((pAction->btn.flags & XkbSA_LockNoLock) == 0)) {
577                 xkbi->lockedPtrButtons |= (1 << button);
578                 AccessXCancelRepeatKey(xkbi, keycode);
579                 XkbFakeDeviceButton(xkbi->device, 1, button);
580                 filter->upAction.type = XkbSA_NoAction;
581             }
582             break;
583         case XkbSA_PtrBtn:
584         {
585             register int i, nClicks;
586
587             AccessXCancelRepeatKey(xkbi, keycode);
588             if (pAction->btn.count > 0) {
589                 nClicks = pAction->btn.count;
590                 for (i = 0; i < nClicks; i++) {
591                     XkbFakeDeviceButton(xkbi->device, 1, button);
592                     XkbFakeDeviceButton(xkbi->device, 0, button);
593                 }
594                 filter->upAction.type = XkbSA_NoAction;
595             }
596             else
597                 XkbFakeDeviceButton(xkbi->device, 1, button);
598         }
599             break;
600         case XkbSA_SetPtrDflt:
601         {
602             XkbControlsPtr ctrls = xkbi->desc->ctrls;
603             XkbControlsRec old;
604             xkbControlsNotify cn;
605
606             old = *ctrls;
607             AccessXCancelRepeatKey(xkbi, keycode);
608             switch (pAction->dflt.affect) {
609             case XkbSA_AffectDfltBtn:
610                 if (pAction->dflt.flags & XkbSA_DfltBtnAbsolute)
611                     ctrls->mk_dflt_btn = XkbSAPtrDfltValue(&pAction->dflt);
612                 else {
613                     ctrls->mk_dflt_btn += XkbSAPtrDfltValue(&pAction->dflt);
614                     if (ctrls->mk_dflt_btn > 5)
615                         ctrls->mk_dflt_btn = 5;
616                     else if (ctrls->mk_dflt_btn < 1)
617                         ctrls->mk_dflt_btn = 1;
618                 }
619                 break;
620             default:
621                 ErrorF
622                     ("Attempt to change unknown pointer default (%d) ignored\n",
623                      pAction->dflt.affect);
624                 break;
625             }
626             if (XkbComputeControlsNotify(xkbi->device,
627                                          &old, xkbi->desc->ctrls, &cn, FALSE)) {
628                 cn.keycode = keycode;
629                 /* XXX: what about DeviceKeyPress? */
630                 cn.eventType = KeyPress;
631                 cn.requestMajor = 0;
632                 cn.requestMinor = 0;
633                 XkbSendControlsNotify(xkbi->device, &cn);
634             }
635         }
636             break;
637         }
638     }
639     else if (filter->keycode == keycode) {
640         int button = filter->upAction.btn.button;
641
642         switch (filter->upAction.type) {
643         case XkbSA_LockPtrBtn:
644             if (((filter->upAction.btn.flags & XkbSA_LockNoUnlock) != 0) ||
645                 ((xkbi->lockedPtrButtons & (1 << button)) == 0)) {
646                 break;
647             }
648             xkbi->lockedPtrButtons &= ~(1 << button);
649
650             if (IsMaster(xkbi->device)) {
651                 XkbMergeLockedPtrBtns(xkbi->device);
652                 /* One SD still has lock set, don't post event */
653                 if ((xkbi->lockedPtrButtons & (1 << button)) != 0)
654                     break;
655             }
656
657             /* fallthrough */
658         case XkbSA_PtrBtn:
659             XkbFakeDeviceButton(xkbi->device, 0, button);
660             break;
661         }
662         filter->active = 0;
663     }
664     return 0;
665 }
666
667 static int
668 _XkbFilterControls(XkbSrvInfoPtr xkbi,
669                    XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
670 {
671     XkbControlsRec old;
672     XkbControlsPtr ctrls;
673     DeviceIntPtr kbd;
674     unsigned int change;
675     XkbEventCauseRec cause;
676
677     kbd = xkbi->device;
678     ctrls = xkbi->desc->ctrls;
679     old = *ctrls;
680     if (filter->keycode == 0) { /* initial press */
681         filter->keycode = keycode;
682         filter->active = 1;
683         filter->filterOthers = 0;
684         change = XkbActionCtrls(&pAction->ctrls);
685         filter->priv = change;
686         filter->filter = _XkbFilterControls;
687         filter->upAction = *pAction;
688
689         if (pAction->type == XkbSA_LockControls) {
690             filter->priv = (ctrls->enabled_ctrls & change);
691             change &= ~ctrls->enabled_ctrls;
692         }
693
694         if (change) {
695             xkbControlsNotify cn;
696             XkbSrvLedInfoPtr sli;
697
698             ctrls->enabled_ctrls |= change;
699             if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE)) {
700                 cn.keycode = keycode;
701                 /* XXX: what about DeviceKeyPress? */
702                 cn.eventType = KeyPress;
703                 cn.requestMajor = 0;
704                 cn.requestMinor = 0;
705                 XkbSendControlsNotify(kbd, &cn);
706             }
707
708             XkbSetCauseKey(&cause, keycode, KeyPress);
709
710             /* If sticky keys were disabled, clear all locks and latches */
711             if ((old.enabled_ctrls & XkbStickyKeysMask) &&
712                 (!(ctrls->enabled_ctrls & XkbStickyKeysMask))) {
713                 XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE, &cause);
714             }
715             sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0);
716             XkbUpdateIndicators(kbd, sli->usesControls, TRUE, NULL, &cause);
717             if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask))
718                 XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_ON, change);
719         }
720     }
721     else if (filter->keycode == keycode) {
722         change = filter->priv;
723         if (change) {
724             xkbControlsNotify cn;
725             XkbSrvLedInfoPtr sli;
726
727             ctrls->enabled_ctrls &= ~change;
728             if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE)) {
729                 cn.keycode = keycode;
730                 cn.eventType = KeyRelease;
731                 cn.requestMajor = 0;
732                 cn.requestMinor = 0;
733                 XkbSendControlsNotify(kbd, &cn);
734             }
735
736             XkbSetCauseKey(&cause, keycode, KeyRelease);
737             /* If sticky keys were disabled, clear all locks and latches */
738             if ((old.enabled_ctrls & XkbStickyKeysMask) &&
739                 (!(ctrls->enabled_ctrls & XkbStickyKeysMask))) {
740                 XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE, &cause);
741             }
742             sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0);
743             XkbUpdateIndicators(kbd, sli->usesControls, TRUE, NULL, &cause);
744             if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask))
745                 XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_OFF, change);
746         }
747         filter->keycode = 0;
748         filter->active = 0;
749     }
750     return 1;
751 }
752
753 static int
754 _XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
755                         XkbFilterPtr filter,
756                         unsigned keycode, XkbAction *pAction)
757 {
758     XkbMessageAction *pMsg;
759     DeviceIntPtr kbd;
760
761     if ((filter->keycode != 0) && (filter->keycode != keycode))
762         return 1;
763
764     /* This can happen if the key repeats, and the state (modifiers or group)
765        changes meanwhile. */
766     if ((filter->keycode == keycode) && pAction &&
767         (pAction->type != XkbSA_ActionMessage))
768         return 1;
769
770     kbd = xkbi->device;
771     if (filter->keycode == 0) { /* initial press */
772         pMsg = &pAction->msg;
773         if ((pMsg->flags & XkbSA_MessageOnRelease) ||
774             ((pMsg->flags & XkbSA_MessageGenKeyEvent) == 0)) {
775             filter->keycode = keycode;
776             filter->active = 1;
777             filter->filterOthers = 0;
778             filter->priv = 0;
779             filter->filter = _XkbFilterActionMessage;
780             filter->upAction = *pAction;
781         }
782         if (pMsg->flags & XkbSA_MessageOnPress) {
783             xkbActionMessage msg;
784
785             msg.keycode = keycode;
786             msg.press = 1;
787             msg.keyEventFollows =
788                 ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
789             memcpy((char *) msg.message, (char *) pMsg->message,
790                    XkbActionMessageLength);
791             XkbSendActionMessage(kbd, &msg);
792         }
793         return ((pAction->msg.flags & XkbSA_MessageGenKeyEvent) != 0);
794     }
795     else if (filter->keycode == keycode) {
796         pMsg = &filter->upAction.msg;
797         if (pAction == NULL) {
798             if (pMsg->flags & XkbSA_MessageOnRelease) {
799                 xkbActionMessage msg;
800
801                 msg.keycode = keycode;
802                 msg.press = 0;
803                 msg.keyEventFollows =
804                     ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
805                 memcpy((char *) msg.message, (char *) pMsg->message,
806                        XkbActionMessageLength);
807                 XkbSendActionMessage(kbd, &msg);
808             }
809             filter->keycode = 0;
810             filter->active = 0;
811             return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
812         } else if (memcmp(pMsg, pAction, 8) == 0) {
813             /* Repeat: If we send the same message, avoid multiple messages
814                on release from piling up. */
815             filter->keycode = 0;
816             filter->active = 0;
817         }
818     }
819     return 1;
820 }
821
822 static int
823 _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
824                       XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
825 {
826     DeviceEvent ev;
827     int x, y;
828     XkbStateRec old, old_prev;
829     unsigned mods, mask;
830     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
831     ProcessInputProc backupproc;
832
833     if ((filter->keycode != 0) && (filter->keycode != keycode))
834         return 1;
835
836     /* This can happen if the key repeats, and the state (modifiers or group)
837        changes meanwhile. */
838     if ((filter->keycode == keycode) && pAction &&
839         (pAction->type != XkbSA_RedirectKey))
840         return 1;
841
842     /* never actually used uninitialised, but gcc isn't smart enough
843      * to work that out. */
844     memset(&old, 0, sizeof(old));
845     memset(&old_prev, 0, sizeof(old_prev));
846     memset(&ev, 0, sizeof(ev));
847
848     GetSpritePosition(xkbi->device, &x, &y);
849     ev.header = ET_Internal;
850     ev.length = sizeof(DeviceEvent);
851     ev.time = GetTimeInMillis();
852     ev.root_x = x;
853     ev.root_y = y;
854     /* redirect actions do not work across devices, therefore the following is
855      * correct: */
856     ev.deviceid = xkbi->device->id;
857     /* filter->priv must be set up by the caller for the initial press. */
858     ev.sourceid = filter->priv;
859
860     if (filter->keycode == 0) { /* initial press */
861         if ((pAction->redirect.new_key < xkbi->desc->min_key_code) ||
862             (pAction->redirect.new_key > xkbi->desc->max_key_code)) {
863             return 1;
864         }
865         filter->keycode = keycode;
866         filter->active = 1;
867         filter->filterOthers = 0;
868         filter->filter = _XkbFilterRedirectKey;
869         filter->upAction = *pAction;
870
871         ev.type = ET_KeyPress;
872         ev.detail.key = pAction->redirect.new_key;
873
874         mask = XkbSARedirectVModsMask(&pAction->redirect);
875         mods = XkbSARedirectVMods(&pAction->redirect);
876         if (mask)
877             XkbVirtualModsToReal(xkbi->desc, mask, &mask);
878         if (mods)
879             XkbVirtualModsToReal(xkbi->desc, mods, &mods);
880         mask |= pAction->redirect.mods_mask;
881         mods |= pAction->redirect.mods;
882
883         if (mask || mods) {
884             old = xkbi->state;
885             old_prev = xkbi->prev_state;
886             xkbi->state.base_mods &= ~mask;
887             xkbi->state.base_mods |= (mods & mask);
888             xkbi->state.latched_mods &= ~mask;
889             xkbi->state.latched_mods |= (mods & mask);
890             xkbi->state.locked_mods &= ~mask;
891             xkbi->state.locked_mods |= (mods & mask);
892             XkbComputeDerivedState(xkbi);
893             xkbi->prev_state = xkbi->state;
894         }
895
896         UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
897         xkbi->device->public.processInputProc((InternalEvent *) &ev,
898                                               xkbi->device);
899         COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
900                                      xkbUnwrapProc);
901
902         if (mask || mods) {
903             xkbi->state = old;
904             xkbi->prev_state = old_prev;
905         }
906         return 0;
907     }
908     else {
909         /* If it is a key release, or we redirect to another key, release the
910            previous new_key.  Otherwise, repeat. */
911         ev.detail.key = filter->upAction.redirect.new_key;
912         if (pAction == NULL ||  ev.detail.key != pAction->redirect.new_key) {
913             ev.type = ET_KeyRelease;
914             filter->active = 0;
915         }
916         else {
917             ev.type = ET_KeyPress;
918             ev.key_repeat = TRUE;
919         }
920
921         mask = XkbSARedirectVModsMask(&filter->upAction.redirect);
922         mods = XkbSARedirectVMods(&filter->upAction.redirect);
923         if (mask)
924             XkbVirtualModsToReal(xkbi->desc, mask, &mask);
925         if (mods)
926             XkbVirtualModsToReal(xkbi->desc, mods, &mods);
927         mask |= filter->upAction.redirect.mods_mask;
928         mods |= filter->upAction.redirect.mods;
929
930         if (mask || mods) {
931             old = xkbi->state;
932             old_prev = xkbi->prev_state;
933             xkbi->state.base_mods &= ~mask;
934             xkbi->state.base_mods |= (mods & mask);
935             xkbi->state.latched_mods &= ~mask;
936             xkbi->state.latched_mods |= (mods & mask);
937             xkbi->state.locked_mods &= ~mask;
938             xkbi->state.locked_mods |= (mods & mask);
939             XkbComputeDerivedState(xkbi);
940             xkbi->prev_state = xkbi->state;
941         }
942
943         UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
944         xkbi->device->public.processInputProc((InternalEvent *) &ev,
945                                               xkbi->device);
946         COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
947                                      xkbUnwrapProc);
948
949         if (mask || mods) {
950             xkbi->state = old;
951             xkbi->prev_state = old_prev;
952         }
953
954         /* We return 1 in case we have sent a release event because the new_key
955            has changed.  Then, subsequently, we will call this function again
956            with the same pAction, which will create the press for the new
957            new_key. */
958         return (pAction && ev.detail.key != pAction->redirect.new_key);
959     }
960 }
961
962 static int
963 _XkbFilterSwitchScreen(XkbSrvInfoPtr xkbi,
964                        XkbFilterPtr filter,
965                        unsigned keycode, XkbAction *pAction)
966 {
967     DeviceIntPtr dev = xkbi->device;
968
969     if (dev == inputInfo.keyboard)
970         return 0;
971
972     if (filter->keycode == 0) { /* initial press */
973         filter->keycode = keycode;
974         filter->active = 1;
975         filter->filterOthers = 0;
976         filter->filter = _XkbFilterSwitchScreen;
977         AccessXCancelRepeatKey(xkbi, keycode);
978         XkbDDXSwitchScreen(dev, keycode, pAction);
979         return 0;
980     }
981     else if (filter->keycode == keycode) {
982         filter->active = 0;
983         return 0;
984     }
985     return 1;
986 }
987
988 static int
989 _XkbFilterXF86Private(XkbSrvInfoPtr xkbi,
990                       XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
991 {
992     DeviceIntPtr dev = xkbi->device;
993
994     if (dev == inputInfo.keyboard)
995         return 0;
996
997     if (filter->keycode == 0) { /* initial press */
998         filter->keycode = keycode;
999         filter->active = 1;
1000         filter->filterOthers = 0;
1001         filter->filter = _XkbFilterXF86Private;
1002         XkbDDXPrivate(dev, keycode, pAction);
1003         return 0;
1004     }
1005     else if (filter->keycode == keycode) {
1006         filter->active = 0;
1007         return 0;
1008     }
1009     return 1;
1010 }
1011
1012 static int
1013 _XkbFilterDeviceBtn(XkbSrvInfoPtr xkbi,
1014                     XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
1015 {
1016     if (xkbi->device == inputInfo.keyboard)
1017         return 0;
1018
1019     if (filter->keycode == 0) { /* initial press */
1020         DeviceIntPtr dev;
1021         int button;
1022
1023         _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient,
1024                                DixUnknownAccess, &button);
1025         if (!dev || !dev->public.on)
1026             return 1;
1027
1028         button = pAction->devbtn.button;
1029         if ((button < 1) || (button > dev->button->numButtons))
1030             return 1;
1031
1032         filter->keycode = keycode;
1033         filter->active = 1;
1034         filter->filterOthers = 0;
1035         filter->priv = 0;
1036         filter->filter = _XkbFilterDeviceBtn;
1037         filter->upAction = *pAction;
1038         switch (pAction->type) {
1039         case XkbSA_LockDeviceBtn:
1040             if ((pAction->devbtn.flags & XkbSA_LockNoLock) ||
1041                 BitIsOn(dev->button->down, button))
1042                 return 0;
1043             XkbFakeDeviceButton(dev, TRUE, button);
1044             filter->upAction.type = XkbSA_NoAction;
1045             break;
1046         case XkbSA_DeviceBtn:
1047             if (pAction->devbtn.count > 0) {
1048                 int nClicks, i;
1049
1050                 nClicks = pAction->btn.count;
1051                 for (i = 0; i < nClicks; i++) {
1052                     XkbFakeDeviceButton(dev, TRUE, button);
1053                     XkbFakeDeviceButton(dev, FALSE, button);
1054                 }
1055                 filter->upAction.type = XkbSA_NoAction;
1056             }
1057             else
1058                 XkbFakeDeviceButton(dev, TRUE, button);
1059             break;
1060         }
1061     }
1062     else if (filter->keycode == keycode) {
1063         DeviceIntPtr dev;
1064         int button;
1065
1066         filter->active = 0;
1067         _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device,
1068                                serverClient, DixUnknownAccess, &button);
1069         if (!dev || !dev->public.on)
1070             return 1;
1071
1072         button = filter->upAction.btn.button;
1073         switch (filter->upAction.type) {
1074         case XkbSA_LockDeviceBtn:
1075             if ((filter->upAction.devbtn.flags & XkbSA_LockNoUnlock) ||
1076                 !BitIsOn(dev->button->down, button))
1077                 return 0;
1078             XkbFakeDeviceButton(dev, FALSE, button);
1079             break;
1080         case XkbSA_DeviceBtn:
1081             XkbFakeDeviceButton(dev, FALSE, button);
1082             break;
1083         }
1084         filter->active = 0;
1085     }
1086     return 0;
1087 }
1088
1089 static XkbFilterPtr
1090 _XkbNextFreeFilter(XkbSrvInfoPtr xkbi)
1091 {
1092     register int i;
1093
1094     if (xkbi->szFilters == 0) {
1095         xkbi->szFilters = 4;
1096         xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec));
1097         /* 6/21/93 (ef) -- XXX! deal with allocation failure */
1098     }
1099     for (i = 0; i < xkbi->szFilters; i++) {
1100         if (!xkbi->filters[i].active) {
1101             xkbi->filters[i].keycode = 0;
1102             return &xkbi->filters[i];
1103         }
1104     }
1105     xkbi->szFilters *= 2;
1106     xkbi->filters = realloc(xkbi->filters,
1107                             xkbi->szFilters * sizeof(XkbFilterRec));
1108     /* 6/21/93 (ef) -- XXX! deal with allocation failure */
1109     memset(&xkbi->filters[xkbi->szFilters / 2], 0,
1110            (xkbi->szFilters / 2) * sizeof(XkbFilterRec));
1111     return &xkbi->filters[xkbi->szFilters / 2];
1112 }
1113
1114 static int
1115 _XkbApplyFilters(XkbSrvInfoPtr xkbi, unsigned kc, XkbAction *pAction)
1116 {
1117     register int i, send;
1118
1119     send = 1;
1120     for (i = 0; i < xkbi->szFilters; i++) {
1121         if ((xkbi->filters[i].active) && (xkbi->filters[i].filter))
1122             send =
1123                 ((*xkbi->filters[i].filter) (xkbi, &xkbi->filters[i], kc,
1124                                              pAction)
1125                  && send);
1126     }
1127     return send;
1128 }
1129
1130 static int
1131 _XkbEnsureStateChange(XkbSrvInfoPtr xkbi)
1132 {
1133     Bool genStateNotify = FALSE;
1134
1135     /* The state may change, so if we're not in the middle of sending a state
1136      * notify, prepare for it */
1137     if ((xkbi->flags & _XkbStateNotifyInProgress) == 0) {
1138         xkbi->prev_state = xkbi->state;
1139         xkbi->flags |= _XkbStateNotifyInProgress;
1140         genStateNotify = TRUE;
1141     }
1142
1143     return genStateNotify;
1144 }
1145
1146 static void
1147 _XkbApplyState(DeviceIntPtr dev, Bool genStateNotify, int evtype, int key)
1148 {
1149     XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
1150     int changed;
1151
1152     XkbComputeDerivedState(xkbi);
1153
1154     changed = XkbStateChangedFlags(&xkbi->prev_state, &xkbi->state);
1155     if (genStateNotify) {
1156         if (changed) {
1157             xkbStateNotify sn;
1158
1159             sn.keycode = key;
1160             sn.eventType = evtype;
1161             sn.requestMajor = sn.requestMinor = 0;
1162             sn.changed = changed;
1163             XkbSendStateNotify(dev, &sn);
1164         }
1165         xkbi->flags &= ~_XkbStateNotifyInProgress;
1166     }
1167
1168     changed = XkbIndicatorsToUpdate(dev, changed, FALSE);
1169     if (changed) {
1170         XkbEventCauseRec cause;
1171         XkbSetCauseKey(&cause, key, evtype);
1172         XkbUpdateIndicators(dev, changed, FALSE, NULL, &cause);
1173     }
1174 }
1175
1176 void
1177 XkbPushLockedStateToSlaves(DeviceIntPtr master, int evtype, int key)
1178 {
1179     DeviceIntPtr dev;
1180     Bool genStateNotify;
1181
1182     nt_list_for_each_entry(dev, inputInfo.devices, next) {
1183         if (!dev->key || GetMaster(dev, MASTER_KEYBOARD) != master)
1184             continue;
1185
1186         genStateNotify = _XkbEnsureStateChange(dev->key->xkbInfo);
1187
1188         dev->key->xkbInfo->state.locked_mods =
1189             master->key->xkbInfo->state.locked_mods;
1190
1191         _XkbApplyState(dev, genStateNotify, evtype, key);
1192     }
1193 }
1194
1195 void
1196 XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
1197 {
1198     int key, bit, i;
1199     XkbSrvInfoPtr xkbi;
1200     KeyClassPtr keyc;
1201     int sendEvent;
1202     Bool genStateNotify;
1203     XkbAction act;
1204     XkbFilterPtr filter;
1205     Bool keyEvent;
1206     Bool pressEvent;
1207     ProcessInputProc backupproc;
1208
1209     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
1210
1211     keyc = kbd->key;
1212     xkbi = keyc->xkbInfo;
1213     key = event->detail.key;
1214
1215     genStateNotify = _XkbEnsureStateChange(xkbi);
1216
1217     xkbi->clearMods = xkbi->setMods = 0;
1218     xkbi->groupChange = 0;
1219
1220     sendEvent = 1;
1221     keyEvent = ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
1222     pressEvent = ((event->type == ET_KeyPress) ||
1223                   (event->type == ET_ButtonPress));
1224
1225     if (pressEvent) {
1226         if (keyEvent)
1227             act = XkbGetKeyAction(xkbi, &xkbi->state, key);
1228         else {
1229             act = XkbGetButtonAction(kbd, dev, key);
1230             key |= BTN_ACT_FLAG;
1231         }
1232         sendEvent = _XkbApplyFilters(xkbi, key, &act);
1233         if (sendEvent) {
1234             switch (act.type) {
1235             case XkbSA_SetMods:
1236             case XkbSA_SetGroup:
1237                 filter = _XkbNextFreeFilter(xkbi);
1238                 sendEvent = _XkbFilterSetState(xkbi, filter, key, &act);
1239                 break;
1240             case XkbSA_LatchMods:
1241             case XkbSA_LatchGroup:
1242                 filter = _XkbNextFreeFilter(xkbi);
1243                 sendEvent = _XkbFilterLatchState(xkbi, filter, key, &act);
1244                 break;
1245             case XkbSA_LockMods:
1246             case XkbSA_LockGroup:
1247                 filter = _XkbNextFreeFilter(xkbi);
1248                 sendEvent = _XkbFilterLockState(xkbi, filter, key, &act);
1249                 break;
1250             case XkbSA_ISOLock:
1251                 filter = _XkbNextFreeFilter(xkbi);
1252                 sendEvent = _XkbFilterISOLock(xkbi, filter, key, &act);
1253                 break;
1254             case XkbSA_MovePtr:
1255                 filter = _XkbNextFreeFilter(xkbi);
1256                 sendEvent = _XkbFilterPointerMove(xkbi, filter, key, &act);
1257                 break;
1258             case XkbSA_PtrBtn:
1259             case XkbSA_LockPtrBtn:
1260             case XkbSA_SetPtrDflt:
1261                 filter = _XkbNextFreeFilter(xkbi);
1262                 sendEvent = _XkbFilterPointerBtn(xkbi, filter, key, &act);
1263                 break;
1264             case XkbSA_Terminate:
1265                 sendEvent = XkbDDXTerminateServer(dev, key, &act);
1266                 break;
1267             case XkbSA_SwitchScreen:
1268                 filter = _XkbNextFreeFilter(xkbi);
1269                 sendEvent = _XkbFilterSwitchScreen(xkbi, filter, key, &act);
1270                 break;
1271             case XkbSA_SetControls:
1272             case XkbSA_LockControls:
1273                 filter = _XkbNextFreeFilter(xkbi);
1274                 sendEvent = _XkbFilterControls(xkbi, filter, key, &act);
1275                 break;
1276             case XkbSA_ActionMessage:
1277                 filter = _XkbNextFreeFilter(xkbi);
1278                 sendEvent = _XkbFilterActionMessage(xkbi, filter, key, &act);
1279                 break;
1280             case XkbSA_RedirectKey:
1281                 filter = _XkbNextFreeFilter(xkbi);
1282                 /* redirect actions must create a new DeviceEvent.  The
1283                  * source device id for this event cannot be obtained from
1284                  * xkbi, so we pass it here explicitly. The field deviceid
1285                  * equals to xkbi->device->id. */
1286                 filter->priv = event->sourceid;
1287                 sendEvent = _XkbFilterRedirectKey(xkbi, filter, key, &act);
1288                 break;
1289             case XkbSA_DeviceBtn:
1290             case XkbSA_LockDeviceBtn:
1291                 filter = _XkbNextFreeFilter(xkbi);
1292                 sendEvent = _XkbFilterDeviceBtn(xkbi, filter, key, &act);
1293                 break;
1294             case XkbSA_XFree86Private:
1295                 filter = _XkbNextFreeFilter(xkbi);
1296                 sendEvent = _XkbFilterXF86Private(xkbi, filter, key, &act);
1297                 break;
1298             }
1299         }
1300     }
1301     else {
1302         if (!keyEvent)
1303             key |= BTN_ACT_FLAG;
1304         sendEvent = _XkbApplyFilters(xkbi, key, NULL);
1305     }
1306
1307     if (xkbi->groupChange != 0)
1308         xkbi->state.base_group += xkbi->groupChange;
1309     if (xkbi->setMods) {
1310         for (i = 0, bit = 1; xkbi->setMods; i++, bit <<= 1) {
1311             if (xkbi->setMods & bit) {
1312                 keyc->modifierKeyCount[i]++;
1313                 xkbi->state.base_mods |= bit;
1314                 xkbi->setMods &= ~bit;
1315             }
1316         }
1317     }
1318     if (xkbi->clearMods) {
1319         for (i = 0, bit = 1; xkbi->clearMods; i++, bit <<= 1) {
1320             if (xkbi->clearMods & bit) {
1321                 keyc->modifierKeyCount[i]--;
1322                 if (keyc->modifierKeyCount[i] <= 0) {
1323                     xkbi->state.base_mods &= ~bit;
1324                     keyc->modifierKeyCount[i] = 0;
1325                 }
1326                 xkbi->clearMods &= ~bit;
1327             }
1328         }
1329     }
1330
1331     if (sendEvent) {
1332         DeviceIntPtr tmpdev;
1333
1334         if (keyEvent)
1335             tmpdev = dev;
1336         else
1337             tmpdev = GetMaster(dev, POINTER_OR_FLOAT);
1338
1339         UNWRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, backupproc);
1340         dev->public.processInputProc((InternalEvent *) event, tmpdev);
1341         COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
1342                                      backupproc, xkbUnwrapProc);
1343     }
1344     else if (keyEvent) {
1345         FixKeyState(event, dev);
1346     }
1347
1348     _XkbApplyState(dev, genStateNotify, event->type, key);
1349     XkbPushLockedStateToSlaves(dev, event->type, key);
1350 }
1351
1352 int
1353 XkbLatchModifiers(DeviceIntPtr pXDev, CARD8 mask, CARD8 latches)
1354 {
1355     XkbSrvInfoPtr xkbi;
1356     XkbFilterPtr filter;
1357     XkbAction act;
1358     unsigned clear;
1359
1360     if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
1361         xkbi = pXDev->key->xkbInfo;
1362         clear = (mask & (~latches));
1363         xkbi->state.latched_mods &= ~clear;
1364         /* Clear any pending latch to locks.
1365          */
1366         act.type = XkbSA_NoAction;
1367         _XkbApplyFilters(xkbi, SYNTHETIC_KEYCODE, &act);
1368         act.type = XkbSA_LatchMods;
1369         act.mods.flags = 0;
1370         act.mods.mask = mask & latches;
1371         filter = _XkbNextFreeFilter(xkbi);
1372         _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act);
1373         _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE,
1374                              (XkbAction *) NULL);
1375         return Success;
1376     }
1377     return BadValue;
1378 }
1379
1380 int
1381 XkbLatchGroup(DeviceIntPtr pXDev, int group)
1382 {
1383     XkbSrvInfoPtr xkbi;
1384     XkbFilterPtr filter;
1385     XkbAction act;
1386
1387     if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
1388         xkbi = pXDev->key->xkbInfo;
1389         act.type = XkbSA_LatchGroup;
1390         act.group.flags = 0;
1391         XkbSASetGroup(&act.group, group);
1392         filter = _XkbNextFreeFilter(xkbi);
1393         _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act);
1394         _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE,
1395                              (XkbAction *) NULL);
1396         return Success;
1397     }
1398     return BadValue;
1399 }
1400
1401 /***====================================================================***/
1402
1403 void
1404 XkbClearAllLatchesAndLocks(DeviceIntPtr dev,
1405                            XkbSrvInfoPtr xkbi,
1406                            Bool genEv, XkbEventCausePtr cause)
1407 {
1408     XkbStateRec os;
1409     xkbStateNotify sn;
1410
1411     sn.changed = 0;
1412     os = xkbi->state;
1413     if (os.latched_mods) {      /* clear all latches */
1414         XkbLatchModifiers(dev, ~0, 0);
1415         sn.changed |= XkbModifierLatchMask;
1416     }
1417     if (os.latched_group) {
1418         XkbLatchGroup(dev, 0);
1419         sn.changed |= XkbGroupLatchMask;
1420     }
1421     if (os.locked_mods) {
1422         xkbi->state.locked_mods = 0;
1423         sn.changed |= XkbModifierLockMask;
1424     }
1425     if (os.locked_group) {
1426         xkbi->state.locked_group = 0;
1427         sn.changed |= XkbGroupLockMask;
1428     }
1429     if (genEv && sn.changed) {
1430         CARD32 changed;
1431
1432         XkbComputeDerivedState(xkbi);
1433         sn.keycode = cause->kc;
1434         sn.eventType = cause->event;
1435         sn.requestMajor = cause->mjr;
1436         sn.requestMinor = cause->mnr;
1437         sn.changed = XkbStateChangedFlags(&os, &xkbi->state);
1438         XkbSendStateNotify(dev, &sn);
1439         changed = XkbIndicatorsToUpdate(dev, sn.changed, FALSE);
1440         if (changed) {
1441             XkbUpdateIndicators(dev, changed, TRUE, NULL, cause);
1442         }
1443     }
1444     return;
1445 }
1446
1447 /*
1448  * The event is injected into the event processing, not the EQ. Thus,
1449  * ensure that we restore the master after the event sequence to the
1450  * original set of classes. Otherwise, the master remains on the XTEST
1451  * classes and drops events that don't fit into the XTEST layout (e.g.
1452  * events with more than 2 valuators).
1453  *
1454  * FIXME: EQ injection in the processing stage is not designed for, so this
1455  * is a rather awkward hack. The event list returned by GetPointerEvents()
1456  * and friends is always prefixed with a DCE if the last _posted_ device was
1457  * different. For normal events, this sequence then resets the master during
1458  * the processing stage. Since we inject the PointerKey events in the
1459  * processing stage though, we need to manually reset to restore the
1460  * previous order, because the events already in the EQ must be sent for the
1461  * right device.
1462  * So we post-fix the event list we get from GPE with a DCE back to the
1463  * previous slave device.
1464  *
1465  * First one on drinking island wins!
1466  */
1467 static void
1468 InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags,
1469                        ValuatorMask *mask)
1470 {
1471     ScreenPtr pScreen;
1472     InternalEvent *events;
1473     int nevents, i;
1474     DeviceIntPtr ptr, mpointer, lastSlave = NULL;
1475     Bool saveWait;
1476
1477     if (IsMaster(dev)) {
1478         mpointer = GetMaster(dev, MASTER_POINTER);
1479         lastSlave = mpointer->lastSlave;
1480         ptr = GetXTestDevice(mpointer);
1481     }
1482     else if (IsFloating(dev))
1483         ptr = dev;
1484     else
1485         return;
1486
1487     events = InitEventList(GetMaximumEventsNum() + 1);
1488     OsBlockSignals();
1489     pScreen = miPointerGetScreen(ptr);
1490     saveWait = miPointerSetWaitForUpdate(pScreen, FALSE);
1491     nevents = GetPointerEvents(events, ptr, type, button, flags, mask);
1492     if (IsMaster(dev) && (lastSlave && lastSlave != ptr))
1493         UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT,
1494                          &nevents);
1495     miPointerSetWaitForUpdate(pScreen, saveWait);
1496     OsReleaseSignals();
1497
1498     for (i = 0; i < nevents; i++)
1499         mieqProcessDeviceEvent(ptr, &events[i], NULL);
1500
1501     FreeEventList(events, GetMaximumEventsNum());
1502
1503 }
1504
1505 static void
1506 XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x, int y)
1507 {
1508     ValuatorMask mask;
1509     int gpe_flags = 0;
1510
1511     /* ignore attached SDs */
1512     if (!IsMaster(dev) && !IsFloating(dev))
1513         return;
1514
1515     if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
1516         gpe_flags = POINTER_ABSOLUTE;
1517     else
1518         gpe_flags = POINTER_RELATIVE;
1519
1520     valuator_mask_set_range(&mask, 0, 2, (int[]) {
1521                             x, y});
1522
1523     InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, &mask);
1524 }
1525
1526 void
1527 XkbFakeDeviceButton(DeviceIntPtr dev, Bool press, int button)
1528 {
1529     DeviceIntPtr ptr;
1530     int down;
1531
1532     /* If dev is a slave device, and the SD is attached, do nothing. If we'd
1533      * post through the attached master pointer we'd get duplicate events.
1534      *
1535      * if dev is a master keyboard, post through the XTEST device
1536      *
1537      * if dev is a floating slave, post through the device itself.
1538      */
1539
1540     if (IsMaster(dev)) {
1541         DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER);
1542
1543         ptr = GetXTestDevice(mpointer);
1544     }
1545     else if (IsFloating(dev))
1546         ptr = dev;
1547     else
1548         return;
1549
1550 #ifdef _F_DO_NULL_CHECK_AT_XKBFAKEDEVICEBUTTON_
1551     if (!ptr)
1552         return;         
1553 #endif /* #ifdef _F_DO_NULL_CHECK_AT_XKBFAKEDEVICEBUTTON_ */
1554
1555     down = button_is_down(ptr, button, BUTTON_PROCESSED);
1556     if (press == down)
1557         return;
1558
1559     InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,
1560                            button, 0, NULL);
1561 }