upgrade for xorg-server 1.12.99.905 (for 1.13 RC)
[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, pointer 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 #define NO_LATCH        3
226
227 static int
228 _XkbFilterLatchState(XkbSrvInfoPtr xkbi,
229                      XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
230 {
231
232     if (filter->keycode == 0) { /* initial press */
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 (filter->upAction.type == XkbSA_LatchMods)
254                 xkbi->state.latched_mods &= ~filter->upAction.mods.mask;
255             else
256                 xkbi->state.latched_group -=
257                     XkbSAGroup(&filter->upAction.group);
258         }
259         else if ((pAction->type == filter->upAction.type) &&
260                  (pAction->mods.flags == filter->upAction.mods.flags) &&
261                  (pAction->mods.mask == filter->upAction.mods.mask)) {
262             if (filter->upAction.mods.flags & XkbSA_LatchToLock) {
263                 XkbControlsPtr ctrls = xkbi->desc->ctrls;
264
265                 if (filter->upAction.type == XkbSA_LatchMods)
266                     pAction->mods.type = XkbSA_LockMods;
267                 else
268                     pAction->group.type = XkbSA_LockGroup;
269                 if (XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask) &&
270                     (ctrls->enabled_ctrls & XkbStickyKeysMask)) {
271                     XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK,
272                                       XkbStickyKeysMask);
273                 }
274             }
275             else {
276                 if (filter->upAction.type == XkbSA_LatchMods)
277                     pAction->mods.type = XkbSA_SetMods;
278                 else
279                     pAction->group.type = XkbSA_SetGroup;
280             }
281             if (filter->upAction.type == XkbSA_LatchMods)
282                 xkbi->state.latched_mods &= ~filter->upAction.mods.mask;
283             else
284                 xkbi->state.latched_group -=
285                     XkbSAGroup(&filter->upAction.group);
286             filter->active = 0;
287         }
288     }
289     else if (filter->keycode == keycode) {      /* release */
290         XkbControlsPtr ctrls = xkbi->desc->ctrls;
291         int needBeep;
292         int beepType = _BEEP_NONE;
293
294         needBeep = ((ctrls->enabled_ctrls & XkbStickyKeysMask) &&
295                     XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask));
296         if (filter->upAction.type == XkbSA_LatchMods) {
297             xkbi->clearMods = filter->upAction.mods.mask;
298             if ((filter->upAction.mods.flags & XkbSA_ClearLocks) &&
299                 (xkbi->clearMods & xkbi->state.locked_mods) ==
300                 xkbi->clearMods) {
301                 xkbi->state.locked_mods &= ~xkbi->clearMods;
302                 filter->priv = NO_LATCH;
303                 beepType = _BEEP_STICKY_UNLOCK;
304             }
305         }
306         else {
307             xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
308             if ((filter->upAction.group.flags & XkbSA_ClearLocks) &&
309                 (xkbi->state.locked_group)) {
310                 xkbi->state.locked_group = 0;
311                 filter->priv = NO_LATCH;
312                 beepType = _BEEP_STICKY_UNLOCK;
313             }
314         }
315         if (filter->priv == NO_LATCH) {
316             filter->active = 0;
317         }
318         else {
319             filter->priv = LATCH_PENDING;
320             if (filter->upAction.type == XkbSA_LatchMods) {
321                 xkbi->state.latched_mods |= filter->upAction.mods.mask;
322                 needBeep = xkbi->state.latched_mods ? needBeep : 0;
323                 xkbi->state.latched_mods |= filter->upAction.mods.mask;
324             }
325             else {
326                 xkbi->state.latched_group +=
327                     XkbSAGroup(&filter->upAction.group);
328             }
329             if (needBeep && (beepType == _BEEP_NONE))
330                 beepType = _BEEP_STICKY_LATCH;
331         }
332         if (needBeep && (beepType != _BEEP_NONE))
333             XkbDDXAccessXBeep(xkbi->device, beepType, XkbStickyKeysMask);
334     }
335     else if (filter->priv == LATCH_KEY_DOWN) {
336         filter->priv = NO_LATCH;
337         filter->filterOthers = 0;
338     }
339     return 1;
340 }
341
342 static int
343 _XkbFilterLockState(XkbSrvInfoPtr xkbi,
344                     XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
345 {
346     if (pAction && (pAction->type == XkbSA_LockGroup)) {
347         if (pAction->group.flags & XkbSA_GroupAbsolute)
348             xkbi->state.locked_group = XkbSAGroup(&pAction->group);
349         else
350             xkbi->state.locked_group += XkbSAGroup(&pAction->group);
351         return 1;
352     }
353     if (filter->keycode == 0) { /* initial press */
354         filter->keycode = keycode;
355         filter->active = 1;
356         filter->filterOthers = 0;
357         filter->priv = xkbi->state.locked_mods & pAction->mods.mask;
358         filter->filter = _XkbFilterLockState;
359         filter->upAction = *pAction;
360         if (!(filter->upAction.mods.flags & XkbSA_LockNoLock))
361             xkbi->state.locked_mods |= pAction->mods.mask;
362         xkbi->setMods = pAction->mods.mask;
363     }
364     else if (filter->keycode == keycode) {
365         filter->active = 0;
366         xkbi->clearMods = filter->upAction.mods.mask;
367         if (!(filter->upAction.mods.flags & XkbSA_LockNoUnlock))
368             xkbi->state.locked_mods &= ~filter->priv;
369     }
370     return 1;
371 }
372
373 #define ISO_KEY_DOWN            0
374 #define NO_ISO_LOCK             1
375
376 static int
377 _XkbFilterISOLock(XkbSrvInfoPtr xkbi,
378                   XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
379 {
380
381     if (filter->keycode == 0) { /* initial press */
382         CARD8 flags = pAction->iso.flags;
383
384         filter->keycode = keycode;
385         filter->active = 1;
386         filter->filterOthers = 1;
387         filter->priv = ISO_KEY_DOWN;
388         filter->upAction = *pAction;
389         filter->filter = _XkbFilterISOLock;
390         if (flags & XkbSA_ISODfltIsGroup) {
391             xkbi->groupChange = XkbSAGroup(&pAction->iso);
392             xkbi->setMods = 0;
393         }
394         else {
395             xkbi->setMods = pAction->iso.mask;
396             xkbi->groupChange = 0;
397         }
398         if ((!(flags & XkbSA_ISONoAffectMods)) && (xkbi->state.base_mods)) {
399             filter->priv = NO_ISO_LOCK;
400             xkbi->state.locked_mods ^= xkbi->state.base_mods;
401         }
402         if ((!(flags & XkbSA_ISONoAffectGroup)) && (xkbi->state.base_group)) {
403 /* 6/22/93 (ef) -- lock groups if group key is down first */
404         }
405         if (!(flags & XkbSA_ISONoAffectPtr)) {
406 /* 6/22/93 (ef) -- lock mouse buttons if they're down */
407         }
408     }
409     else if (filter->keycode == keycode) {
410         CARD8 flags = filter->upAction.iso.flags;
411
412         if (flags & XkbSA_ISODfltIsGroup) {
413             xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
414             xkbi->clearMods = 0;
415             if (filter->priv == ISO_KEY_DOWN)
416                 xkbi->state.locked_group += XkbSAGroup(&filter->upAction.iso);
417         }
418         else {
419             xkbi->clearMods = filter->upAction.iso.mask;
420             xkbi->groupChange = 0;
421             if (filter->priv == ISO_KEY_DOWN)
422                 xkbi->state.locked_mods ^= filter->upAction.iso.mask;
423         }
424         filter->active = 0;
425     }
426     else if (pAction) {
427         CARD8 flags = filter->upAction.iso.flags;
428
429         switch (pAction->type) {
430         case XkbSA_SetMods:
431         case XkbSA_LatchMods:
432             if (!(flags & XkbSA_ISONoAffectMods)) {
433                 pAction->type = XkbSA_LockMods;
434                 filter->priv = NO_ISO_LOCK;
435             }
436             break;
437         case XkbSA_SetGroup:
438         case XkbSA_LatchGroup:
439             if (!(flags & XkbSA_ISONoAffectGroup)) {
440                 pAction->type = XkbSA_LockGroup;
441                 filter->priv = NO_ISO_LOCK;
442             }
443             break;
444         case XkbSA_PtrBtn:
445             if (!(flags & XkbSA_ISONoAffectPtr)) {
446                 pAction->type = XkbSA_LockPtrBtn;
447                 filter->priv = NO_ISO_LOCK;
448             }
449             break;
450         case XkbSA_SetControls:
451             if (!(flags & XkbSA_ISONoAffectCtrls)) {
452                 pAction->type = XkbSA_LockControls;
453                 filter->priv = NO_ISO_LOCK;
454             }
455             break;
456         }
457     }
458     return 1;
459 }
460
461 static CARD32
462 _XkbPtrAccelExpire(OsTimerPtr timer, CARD32 now, pointer arg)
463 {
464     XkbSrvInfoPtr xkbi = (XkbSrvInfoPtr) arg;
465     XkbControlsPtr ctrls = xkbi->desc->ctrls;
466     int dx, dy;
467
468     if (xkbi->mouseKey == 0)
469         return 0;
470
471     if (xkbi->mouseKeysAccel) {
472         if ((xkbi->mouseKeysCounter) < ctrls->mk_time_to_max) {
473             double step;
474
475             xkbi->mouseKeysCounter++;
476             step = xkbi->mouseKeysCurveFactor *
477                 pow((double) xkbi->mouseKeysCounter, xkbi->mouseKeysCurve);
478             if (xkbi->mouseKeysDX < 0)
479                 dx = floor(((double) xkbi->mouseKeysDX) * step);
480             else
481                 dx = ceil(((double) xkbi->mouseKeysDX) * step);
482             if (xkbi->mouseKeysDY < 0)
483                 dy = floor(((double) xkbi->mouseKeysDY) * step);
484             else
485                 dy = ceil(((double) xkbi->mouseKeysDY) * step);
486         }
487         else {
488             dx = xkbi->mouseKeysDX * ctrls->mk_max_speed;
489             dy = xkbi->mouseKeysDY * ctrls->mk_max_speed;
490         }
491         if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteX)
492             dx = xkbi->mouseKeysDX;
493         if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteY)
494             dy = xkbi->mouseKeysDY;
495     }
496     else {
497         dx = xkbi->mouseKeysDX;
498         dy = xkbi->mouseKeysDY;
499     }
500     XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags, dx, dy);
501     return xkbi->desc->ctrls->mk_interval;
502 }
503
504 static int
505 _XkbFilterPointerMove(XkbSrvInfoPtr xkbi,
506                       XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
507 {
508     int x, y;
509     Bool accel;
510
511     if (filter->keycode == 0) { /* initial press */
512         filter->keycode = keycode;
513         filter->active = 1;
514         filter->filterOthers = 0;
515         filter->priv = 0;
516         filter->filter = _XkbFilterPointerMove;
517         filter->upAction = *pAction;
518         xkbi->mouseKeysCounter = 0;
519         xkbi->mouseKey = keycode;
520         accel = ((pAction->ptr.flags & XkbSA_NoAcceleration) == 0);
521         x = XkbPtrActionX(&pAction->ptr);
522         y = XkbPtrActionY(&pAction->ptr);
523         XkbFakePointerMotion(xkbi->device, pAction->ptr.flags, x, y);
524         AccessXCancelRepeatKey(xkbi, keycode);
525         xkbi->mouseKeysAccel = accel &&
526             (xkbi->desc->ctrls->enabled_ctrls & XkbMouseKeysAccelMask);
527         xkbi->mouseKeysFlags = pAction->ptr.flags;
528         xkbi->mouseKeysDX = XkbPtrActionX(&pAction->ptr);
529         xkbi->mouseKeysDY = XkbPtrActionY(&pAction->ptr);
530         xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0,
531                                        xkbi->desc->ctrls->mk_delay,
532                                        _XkbPtrAccelExpire, (pointer) xkbi);
533     }
534     else if (filter->keycode == keycode) {
535         filter->active = 0;
536         if (xkbi->mouseKey == keycode) {
537             xkbi->mouseKey = 0;
538             xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0, 0,
539                                            NULL, NULL);
540         }
541     }
542     return 0;
543 }
544
545 static int
546 _XkbFilterPointerBtn(XkbSrvInfoPtr xkbi,
547                      XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
548 {
549     if (filter->keycode == 0) { /* initial press */
550         int button = pAction->btn.button;
551
552         if (button == XkbSA_UseDfltButton)
553             button = xkbi->desc->ctrls->mk_dflt_btn;
554
555         filter->keycode = keycode;
556         filter->active = 1;
557         filter->filterOthers = 0;
558         filter->priv = 0;
559         filter->filter = _XkbFilterPointerBtn;
560         filter->upAction = *pAction;
561         filter->upAction.btn.button = button;
562         switch (pAction->type) {
563         case XkbSA_LockPtrBtn:
564             if (((xkbi->lockedPtrButtons & (1 << button)) == 0) &&
565                 ((pAction->btn.flags & XkbSA_LockNoLock) == 0)) {
566                 xkbi->lockedPtrButtons |= (1 << button);
567                 AccessXCancelRepeatKey(xkbi, keycode);
568                 XkbFakeDeviceButton(xkbi->device, 1, button);
569                 filter->upAction.type = XkbSA_NoAction;
570             }
571             break;
572         case XkbSA_PtrBtn:
573         {
574             register int i, nClicks;
575
576             AccessXCancelRepeatKey(xkbi, keycode);
577             if (pAction->btn.count > 0) {
578                 nClicks = pAction->btn.count;
579                 for (i = 0; i < nClicks; i++) {
580                     XkbFakeDeviceButton(xkbi->device, 1, button);
581                     XkbFakeDeviceButton(xkbi->device, 0, button);
582                 }
583                 filter->upAction.type = XkbSA_NoAction;
584             }
585             else
586                 XkbFakeDeviceButton(xkbi->device, 1, button);
587         }
588             break;
589         case XkbSA_SetPtrDflt:
590         {
591             XkbControlsPtr ctrls = xkbi->desc->ctrls;
592             XkbControlsRec old;
593             xkbControlsNotify cn;
594
595             old = *ctrls;
596             AccessXCancelRepeatKey(xkbi, keycode);
597             switch (pAction->dflt.affect) {
598             case XkbSA_AffectDfltBtn:
599                 if (pAction->dflt.flags & XkbSA_DfltBtnAbsolute)
600                     ctrls->mk_dflt_btn = XkbSAPtrDfltValue(&pAction->dflt);
601                 else {
602                     ctrls->mk_dflt_btn += XkbSAPtrDfltValue(&pAction->dflt);
603                     if (ctrls->mk_dflt_btn > 5)
604                         ctrls->mk_dflt_btn = 5;
605                     else if (ctrls->mk_dflt_btn < 1)
606                         ctrls->mk_dflt_btn = 1;
607                 }
608                 break;
609             default:
610                 ErrorF
611                     ("Attempt to change unknown pointer default (%d) ignored\n",
612                      pAction->dflt.affect);
613                 break;
614             }
615             if (XkbComputeControlsNotify(xkbi->device,
616                                          &old, xkbi->desc->ctrls, &cn, FALSE)) {
617                 cn.keycode = keycode;
618                 /* XXX: what about DeviceKeyPress? */
619                 cn.eventType = KeyPress;
620                 cn.requestMajor = 0;
621                 cn.requestMinor = 0;
622                 XkbSendControlsNotify(xkbi->device, &cn);
623             }
624         }
625             break;
626         }
627     }
628     else if (filter->keycode == keycode) {
629         int button = filter->upAction.btn.button;
630
631         switch (filter->upAction.type) {
632         case XkbSA_LockPtrBtn:
633             if (((filter->upAction.btn.flags & XkbSA_LockNoUnlock) != 0) ||
634                 ((xkbi->lockedPtrButtons & (1 << button)) == 0)) {
635                 break;
636             }
637             xkbi->lockedPtrButtons &= ~(1 << button);
638
639             if (IsMaster(xkbi->device)) {
640                 XkbMergeLockedPtrBtns(xkbi->device);
641                 /* One SD still has lock set, don't post event */
642                 if ((xkbi->lockedPtrButtons & (1 << button)) != 0)
643                     break;
644             }
645
646             /* fallthrough */
647         case XkbSA_PtrBtn:
648             XkbFakeDeviceButton(xkbi->device, 0, button);
649             break;
650         }
651         filter->active = 0;
652     }
653     return 0;
654 }
655
656 static int
657 _XkbFilterControls(XkbSrvInfoPtr xkbi,
658                    XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
659 {
660     XkbControlsRec old;
661     XkbControlsPtr ctrls;
662     DeviceIntPtr kbd;
663     unsigned int change;
664     XkbEventCauseRec cause;
665
666     kbd = xkbi->device;
667     ctrls = xkbi->desc->ctrls;
668     old = *ctrls;
669     if (filter->keycode == 0) { /* initial press */
670         filter->keycode = keycode;
671         filter->active = 1;
672         filter->filterOthers = 0;
673         change = XkbActionCtrls(&pAction->ctrls);
674         filter->priv = change;
675         filter->filter = _XkbFilterControls;
676         filter->upAction = *pAction;
677
678         if (pAction->type == XkbSA_LockControls) {
679             filter->priv = (ctrls->enabled_ctrls & change);
680             change &= ~ctrls->enabled_ctrls;
681         }
682
683         if (change) {
684             xkbControlsNotify cn;
685             XkbSrvLedInfoPtr sli;
686
687             ctrls->enabled_ctrls |= change;
688             if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE)) {
689                 cn.keycode = keycode;
690                 /* XXX: what about DeviceKeyPress? */
691                 cn.eventType = KeyPress;
692                 cn.requestMajor = 0;
693                 cn.requestMinor = 0;
694                 XkbSendControlsNotify(kbd, &cn);
695             }
696
697             XkbSetCauseKey(&cause, keycode, KeyPress);
698
699             /* If sticky keys were disabled, clear all locks and latches */
700             if ((old.enabled_ctrls & XkbStickyKeysMask) &&
701                 (!(ctrls->enabled_ctrls & XkbStickyKeysMask))) {
702                 XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE, &cause);
703             }
704             sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0);
705             XkbUpdateIndicators(kbd, sli->usesControls, TRUE, NULL, &cause);
706             if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask))
707                 XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_ON, change);
708         }
709     }
710     else if (filter->keycode == keycode) {
711         change = filter->priv;
712         if (change) {
713             xkbControlsNotify cn;
714             XkbSrvLedInfoPtr sli;
715
716             ctrls->enabled_ctrls &= ~change;
717             if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE)) {
718                 cn.keycode = keycode;
719                 cn.eventType = KeyRelease;
720                 cn.requestMajor = 0;
721                 cn.requestMinor = 0;
722                 XkbSendControlsNotify(kbd, &cn);
723             }
724
725             XkbSetCauseKey(&cause, keycode, KeyRelease);
726             /* If sticky keys were disabled, clear all locks and latches */
727             if ((old.enabled_ctrls & XkbStickyKeysMask) &&
728                 (!(ctrls->enabled_ctrls & XkbStickyKeysMask))) {
729                 XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE, &cause);
730             }
731             sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0);
732             XkbUpdateIndicators(kbd, sli->usesControls, TRUE, NULL, &cause);
733             if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask))
734                 XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_OFF, change);
735         }
736         filter->keycode = 0;
737         filter->active = 0;
738     }
739     return 1;
740 }
741
742 static int
743 _XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
744                         XkbFilterPtr filter,
745                         unsigned keycode, XkbAction *pAction)
746 {
747     XkbMessageAction *pMsg;
748     DeviceIntPtr kbd;
749
750     kbd = xkbi->device;
751     if (filter->keycode == 0) { /* initial press */
752         pMsg = &pAction->msg;
753         if ((pMsg->flags & XkbSA_MessageOnRelease) ||
754             ((pMsg->flags & XkbSA_MessageGenKeyEvent) == 0)) {
755             filter->keycode = keycode;
756             filter->active = 1;
757             filter->filterOthers = 0;
758             filter->priv = 0;
759             filter->filter = _XkbFilterActionMessage;
760             filter->upAction = *pAction;
761         }
762         if (pMsg->flags & XkbSA_MessageOnPress) {
763             xkbActionMessage msg;
764
765             msg.keycode = keycode;
766             msg.press = 1;
767             msg.keyEventFollows =
768                 ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
769             memcpy((char *) msg.message, (char *) pMsg->message,
770                    XkbActionMessageLength);
771             XkbSendActionMessage(kbd, &msg);
772         }
773         return ((pAction->msg.flags & XkbSA_MessageGenKeyEvent) != 0);
774     }
775     else if (filter->keycode == keycode) {
776         pMsg = &filter->upAction.msg;
777         if (pMsg->flags & XkbSA_MessageOnRelease) {
778             xkbActionMessage msg;
779
780             msg.keycode = keycode;
781             msg.press = 0;
782             msg.keyEventFollows =
783                 ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
784             memcpy((char *) msg.message, (char *) pMsg->message,
785                    XkbActionMessageLength);
786             XkbSendActionMessage(kbd, &msg);
787         }
788         filter->keycode = 0;
789         filter->active = 0;
790         return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
791     }
792     return 1;
793 }
794
795 static int
796 _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
797                       XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
798 {
799     DeviceEvent ev;
800     int x, y;
801     XkbStateRec old, old_prev;
802     unsigned mods, mask;
803     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
804     ProcessInputProc backupproc;
805
806     /* never actually used uninitialised, but gcc isn't smart enough
807      * to work that out. */
808     memset(&old, 0, sizeof(old));
809     memset(&old_prev, 0, sizeof(old_prev));
810     memset(&ev, 0, sizeof(ev));
811
812     if ((filter->keycode != 0) && (filter->keycode != keycode))
813         return 1;
814
815     GetSpritePosition(xkbi->device, &x, &y);
816     ev.header = ET_Internal;
817     ev.length = sizeof(DeviceEvent);
818     ev.time = GetTimeInMillis();
819     ev.root_x = x;
820     ev.root_y = y;
821     /* redirect actions do not work across devices, therefore the following is
822      * correct: */
823     ev.deviceid = xkbi->device->id;
824     /* filter->priv must be set up by the caller for the initial press. */
825     ev.sourceid = filter->priv;
826
827     if (filter->keycode == 0) { /* initial press */
828         if ((pAction->redirect.new_key < xkbi->desc->min_key_code) ||
829             (pAction->redirect.new_key > xkbi->desc->max_key_code)) {
830             return 1;
831         }
832         filter->keycode = keycode;
833         filter->active = 1;
834         filter->filterOthers = 0;
835         filter->filter = _XkbFilterRedirectKey;
836         filter->upAction = *pAction;
837
838         ev.type = ET_KeyPress;
839         ev.detail.key = pAction->redirect.new_key;
840
841         mask = XkbSARedirectVModsMask(&pAction->redirect);
842         mods = XkbSARedirectVMods(&pAction->redirect);
843         if (mask)
844             XkbVirtualModsToReal(xkbi->desc, mask, &mask);
845         if (mods)
846             XkbVirtualModsToReal(xkbi->desc, mods, &mods);
847         mask |= pAction->redirect.mods_mask;
848         mods |= pAction->redirect.mods;
849
850         if (mask || mods) {
851             old = xkbi->state;
852             old_prev = xkbi->prev_state;
853             xkbi->state.base_mods &= ~mask;
854             xkbi->state.base_mods |= (mods & mask);
855             xkbi->state.latched_mods &= ~mask;
856             xkbi->state.latched_mods |= (mods & mask);
857             xkbi->state.locked_mods &= ~mask;
858             xkbi->state.locked_mods |= (mods & mask);
859             XkbComputeDerivedState(xkbi);
860             xkbi->prev_state = xkbi->state;
861         }
862
863         UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
864         xkbi->device->public.processInputProc((InternalEvent *) &ev,
865                                               xkbi->device);
866         COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
867                                      xkbUnwrapProc);
868
869         if (mask || mods) {
870             xkbi->state = old;
871             xkbi->prev_state = old_prev;
872         }
873     }
874     else if (filter->keycode == keycode) {
875
876         ev.type = ET_KeyRelease;
877         ev.detail.key = filter->upAction.redirect.new_key;
878
879         mask = XkbSARedirectVModsMask(&filter->upAction.redirect);
880         mods = XkbSARedirectVMods(&filter->upAction.redirect);
881         if (mask)
882             XkbVirtualModsToReal(xkbi->desc, mask, &mask);
883         if (mods)
884             XkbVirtualModsToReal(xkbi->desc, mods, &mods);
885         mask |= filter->upAction.redirect.mods_mask;
886         mods |= filter->upAction.redirect.mods;
887
888         if (mask || mods) {
889             old = xkbi->state;
890             old_prev = xkbi->prev_state;
891             xkbi->state.base_mods &= ~mask;
892             xkbi->state.base_mods |= (mods & mask);
893             xkbi->state.latched_mods &= ~mask;
894             xkbi->state.latched_mods |= (mods & mask);
895             xkbi->state.locked_mods &= ~mask;
896             xkbi->state.locked_mods |= (mods & mask);
897             XkbComputeDerivedState(xkbi);
898             xkbi->prev_state = xkbi->state;
899         }
900
901         UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
902         xkbi->device->public.processInputProc((InternalEvent *) &ev,
903                                               xkbi->device);
904         COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
905                                      xkbUnwrapProc);
906
907         if (mask || mods) {
908             xkbi->state = old;
909             xkbi->prev_state = old_prev;
910         }
911
912         filter->keycode = 0;
913         filter->active = 0;
914     }
915     return 0;
916 }
917
918 static int
919 _XkbFilterSwitchScreen(XkbSrvInfoPtr xkbi,
920                        XkbFilterPtr filter,
921                        unsigned keycode, XkbAction *pAction)
922 {
923     DeviceIntPtr dev = xkbi->device;
924
925     if (dev == inputInfo.keyboard)
926         return 0;
927
928     if (filter->keycode == 0) { /* initial press */
929         filter->keycode = keycode;
930         filter->active = 1;
931         filter->filterOthers = 0;
932         filter->filter = _XkbFilterSwitchScreen;
933         AccessXCancelRepeatKey(xkbi, keycode);
934         XkbDDXSwitchScreen(dev, keycode, pAction);
935         return 0;
936     }
937     else if (filter->keycode == keycode) {
938         filter->active = 0;
939         return 0;
940     }
941     return 1;
942 }
943
944 static int
945 _XkbFilterXF86Private(XkbSrvInfoPtr xkbi,
946                       XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
947 {
948     DeviceIntPtr dev = xkbi->device;
949
950     if (dev == inputInfo.keyboard)
951         return 0;
952
953     if (filter->keycode == 0) { /* initial press */
954         filter->keycode = keycode;
955         filter->active = 1;
956         filter->filterOthers = 0;
957         filter->filter = _XkbFilterXF86Private;
958         XkbDDXPrivate(dev, keycode, pAction);
959         return 0;
960     }
961     else if (filter->keycode == keycode) {
962         filter->active = 0;
963         return 0;
964     }
965     return 1;
966 }
967
968 static int
969 _XkbFilterDeviceBtn(XkbSrvInfoPtr xkbi,
970                     XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
971 {
972     if (xkbi->device == inputInfo.keyboard)
973         return 0;
974
975     if (filter->keycode == 0) { /* initial press */
976         DeviceIntPtr dev;
977         int button;
978
979         _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient,
980                                DixUnknownAccess, &button);
981         if (!dev || !dev->public.on)
982             return 1;
983
984         button = pAction->devbtn.button;
985         if ((button < 1) || (button > dev->button->numButtons))
986             return 1;
987
988         filter->keycode = keycode;
989         filter->active = 1;
990         filter->filterOthers = 0;
991         filter->priv = 0;
992         filter->filter = _XkbFilterDeviceBtn;
993         filter->upAction = *pAction;
994         switch (pAction->type) {
995         case XkbSA_LockDeviceBtn:
996             if ((pAction->devbtn.flags & XkbSA_LockNoLock) ||
997                 BitIsOn(dev->button->down, button))
998                 return 0;
999             XkbFakeDeviceButton(dev, TRUE, button);
1000             filter->upAction.type = XkbSA_NoAction;
1001             break;
1002         case XkbSA_DeviceBtn:
1003             if (pAction->devbtn.count > 0) {
1004                 int nClicks, i;
1005
1006                 nClicks = pAction->btn.count;
1007                 for (i = 0; i < nClicks; i++) {
1008                     XkbFakeDeviceButton(dev, TRUE, button);
1009                     XkbFakeDeviceButton(dev, FALSE, button);
1010                 }
1011                 filter->upAction.type = XkbSA_NoAction;
1012             }
1013             else
1014                 XkbFakeDeviceButton(dev, TRUE, button);
1015             break;
1016         }
1017     }
1018     else if (filter->keycode == keycode) {
1019         DeviceIntPtr dev;
1020         int button;
1021
1022         filter->active = 0;
1023         _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device,
1024                                serverClient, DixUnknownAccess, &button);
1025         if (!dev || !dev->public.on)
1026             return 1;
1027
1028         button = filter->upAction.btn.button;
1029         switch (filter->upAction.type) {
1030         case XkbSA_LockDeviceBtn:
1031             if ((filter->upAction.devbtn.flags & XkbSA_LockNoUnlock) ||
1032                 !BitIsOn(dev->button->down, button))
1033                 return 0;
1034             XkbFakeDeviceButton(dev, FALSE, button);
1035             break;
1036         case XkbSA_DeviceBtn:
1037             XkbFakeDeviceButton(dev, FALSE, button);
1038             break;
1039         }
1040         filter->active = 0;
1041     }
1042     return 0;
1043 }
1044
1045 static XkbFilterPtr
1046 _XkbNextFreeFilter(XkbSrvInfoPtr xkbi)
1047 {
1048     register int i;
1049
1050     if (xkbi->szFilters == 0) {
1051         xkbi->szFilters = 4;
1052         xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec));
1053         /* 6/21/93 (ef) -- XXX! deal with allocation failure */
1054     }
1055     for (i = 0; i < xkbi->szFilters; i++) {
1056         if (!xkbi->filters[i].active) {
1057             xkbi->filters[i].keycode = 0;
1058             return &xkbi->filters[i];
1059         }
1060     }
1061     xkbi->szFilters *= 2;
1062     xkbi->filters = realloc(xkbi->filters,
1063                             xkbi->szFilters * sizeof(XkbFilterRec));
1064     /* 6/21/93 (ef) -- XXX! deal with allocation failure */
1065     memset(&xkbi->filters[xkbi->szFilters / 2], 0,
1066            (xkbi->szFilters / 2) * sizeof(XkbFilterRec));
1067     return &xkbi->filters[xkbi->szFilters / 2];
1068 }
1069
1070 static int
1071 _XkbApplyFilters(XkbSrvInfoPtr xkbi, unsigned kc, XkbAction *pAction)
1072 {
1073     register int i, send;
1074
1075     send = 1;
1076     for (i = 0; i < xkbi->szFilters; i++) {
1077         if ((xkbi->filters[i].active) && (xkbi->filters[i].filter))
1078             send =
1079                 ((*xkbi->filters[i].filter) (xkbi, &xkbi->filters[i], kc,
1080                                              pAction)
1081                  && send);
1082     }
1083     return send;
1084 }
1085
1086 void
1087 XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
1088 {
1089     int key, bit, i;
1090     XkbSrvInfoPtr xkbi;
1091     KeyClassPtr keyc;
1092     int changed, sendEvent;
1093     Bool genStateNotify;
1094     XkbAction act;
1095     XkbFilterPtr filter;
1096     Bool keyEvent;
1097     Bool pressEvent;
1098     ProcessInputProc backupproc;
1099
1100     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
1101
1102     keyc = kbd->key;
1103     xkbi = keyc->xkbInfo;
1104     key = event->detail.key;
1105     /* The state may change, so if we're not in the middle of sending a state
1106      * notify, prepare for it */
1107     if ((xkbi->flags & _XkbStateNotifyInProgress) == 0) {
1108         xkbi->prev_state = xkbi->state;
1109         xkbi->flags |= _XkbStateNotifyInProgress;
1110         genStateNotify = TRUE;
1111     }
1112     else
1113         genStateNotify = FALSE;
1114
1115     xkbi->clearMods = xkbi->setMods = 0;
1116     xkbi->groupChange = 0;
1117
1118     sendEvent = 1;
1119     keyEvent = ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
1120     pressEvent = ((event->type == ET_KeyPress) ||
1121                   (event->type == ET_ButtonPress));
1122
1123     if (pressEvent) {
1124         if (keyEvent)
1125             act = XkbGetKeyAction(xkbi, &xkbi->state, key);
1126         else {
1127             act = XkbGetButtonAction(kbd, dev, key);
1128             key |= BTN_ACT_FLAG;
1129         }
1130         sendEvent = _XkbApplyFilters(xkbi, key, &act);
1131         if (sendEvent) {
1132             switch (act.type) {
1133             case XkbSA_SetMods:
1134             case XkbSA_SetGroup:
1135                 filter = _XkbNextFreeFilter(xkbi);
1136                 sendEvent = _XkbFilterSetState(xkbi, filter, key, &act);
1137                 break;
1138             case XkbSA_LatchMods:
1139             case XkbSA_LatchGroup:
1140                 filter = _XkbNextFreeFilter(xkbi);
1141                 sendEvent = _XkbFilterLatchState(xkbi, filter, key, &act);
1142                 break;
1143             case XkbSA_LockMods:
1144             case XkbSA_LockGroup:
1145                 filter = _XkbNextFreeFilter(xkbi);
1146                 sendEvent = _XkbFilterLockState(xkbi, filter, key, &act);
1147                 break;
1148             case XkbSA_ISOLock:
1149                 filter = _XkbNextFreeFilter(xkbi);
1150                 sendEvent = _XkbFilterISOLock(xkbi, filter, key, &act);
1151                 break;
1152             case XkbSA_MovePtr:
1153                 filter = _XkbNextFreeFilter(xkbi);
1154                 sendEvent = _XkbFilterPointerMove(xkbi, filter, key, &act);
1155                 break;
1156             case XkbSA_PtrBtn:
1157             case XkbSA_LockPtrBtn:
1158             case XkbSA_SetPtrDflt:
1159                 filter = _XkbNextFreeFilter(xkbi);
1160                 sendEvent = _XkbFilterPointerBtn(xkbi, filter, key, &act);
1161                 break;
1162             case XkbSA_Terminate:
1163                 sendEvent = XkbDDXTerminateServer(dev, key, &act);
1164                 break;
1165             case XkbSA_SwitchScreen:
1166                 filter = _XkbNextFreeFilter(xkbi);
1167                 sendEvent = _XkbFilterSwitchScreen(xkbi, filter, key, &act);
1168                 break;
1169             case XkbSA_SetControls:
1170             case XkbSA_LockControls:
1171                 filter = _XkbNextFreeFilter(xkbi);
1172                 sendEvent = _XkbFilterControls(xkbi, filter, key, &act);
1173                 break;
1174             case XkbSA_ActionMessage:
1175                 filter = _XkbNextFreeFilter(xkbi);
1176                 sendEvent = _XkbFilterActionMessage(xkbi, filter, key, &act);
1177                 break;
1178             case XkbSA_RedirectKey:
1179                 filter = _XkbNextFreeFilter(xkbi);
1180                 /* redirect actions must create a new DeviceEvent.  The
1181                  * source device id for this event cannot be obtained from
1182                  * xkbi, so we pass it here explicitly. The field deviceid
1183                  * equals to xkbi->device->id. */
1184                 filter->priv = event->sourceid;
1185                 sendEvent = _XkbFilterRedirectKey(xkbi, filter, key, &act);
1186                 break;
1187             case XkbSA_DeviceBtn:
1188             case XkbSA_LockDeviceBtn:
1189                 filter = _XkbNextFreeFilter(xkbi);
1190                 sendEvent = _XkbFilterDeviceBtn(xkbi, filter, key, &act);
1191                 break;
1192             case XkbSA_XFree86Private:
1193                 filter = _XkbNextFreeFilter(xkbi);
1194                 sendEvent = _XkbFilterXF86Private(xkbi, filter, key, &act);
1195                 break;
1196             }
1197         }
1198     }
1199     else {
1200         if (!keyEvent)
1201             key |= BTN_ACT_FLAG;
1202         sendEvent = _XkbApplyFilters(xkbi, key, NULL);
1203     }
1204
1205     if (xkbi->groupChange != 0)
1206         xkbi->state.base_group += xkbi->groupChange;
1207     if (xkbi->setMods) {
1208         for (i = 0, bit = 1; xkbi->setMods; i++, bit <<= 1) {
1209             if (xkbi->setMods & bit) {
1210                 keyc->modifierKeyCount[i]++;
1211                 xkbi->state.base_mods |= bit;
1212                 xkbi->setMods &= ~bit;
1213             }
1214         }
1215     }
1216     if (xkbi->clearMods) {
1217         for (i = 0, bit = 1; xkbi->clearMods; i++, bit <<= 1) {
1218             if (xkbi->clearMods & bit) {
1219                 keyc->modifierKeyCount[i]--;
1220                 if (keyc->modifierKeyCount[i] <= 0) {
1221                     xkbi->state.base_mods &= ~bit;
1222                     keyc->modifierKeyCount[i] = 0;
1223                 }
1224                 xkbi->clearMods &= ~bit;
1225             }
1226         }
1227     }
1228
1229     if (sendEvent) {
1230         DeviceIntPtr tmpdev;
1231
1232         if (keyEvent)
1233             tmpdev = dev;
1234         else
1235             tmpdev = GetMaster(dev, POINTER_OR_FLOAT);
1236
1237         UNWRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, backupproc);
1238         dev->public.processInputProc((InternalEvent *) event, tmpdev);
1239         COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
1240                                      backupproc, xkbUnwrapProc);
1241     }
1242     else if (keyEvent) {
1243         FixKeyState(event, dev);
1244     }
1245
1246     XkbComputeDerivedState(xkbi);
1247     changed = XkbStateChangedFlags(&xkbi->prev_state, &xkbi->state);
1248     if (genStateNotify) {
1249         if (changed) {
1250             xkbStateNotify sn;
1251
1252             sn.keycode = key;
1253             sn.eventType = event->type;
1254             sn.requestMajor = sn.requestMinor = 0;
1255             sn.changed = changed;
1256             XkbSendStateNotify(dev, &sn);
1257         }
1258         xkbi->flags &= ~_XkbStateNotifyInProgress;
1259     }
1260     changed = XkbIndicatorsToUpdate(dev, changed, FALSE);
1261     if (changed) {
1262         XkbEventCauseRec cause;
1263
1264         XkbSetCauseKey(&cause, key, event->type);
1265         XkbUpdateIndicators(dev, changed, FALSE, NULL, &cause);
1266     }
1267     return;
1268 }
1269
1270 int
1271 XkbLatchModifiers(DeviceIntPtr pXDev, CARD8 mask, CARD8 latches)
1272 {
1273     XkbSrvInfoPtr xkbi;
1274     XkbFilterPtr filter;
1275     XkbAction act;
1276     unsigned clear;
1277
1278     if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
1279         xkbi = pXDev->key->xkbInfo;
1280         clear = (mask & (~latches));
1281         xkbi->state.latched_mods &= ~clear;
1282         /* Clear any pending latch to locks.
1283          */
1284         act.type = XkbSA_NoAction;
1285         _XkbApplyFilters(xkbi, SYNTHETIC_KEYCODE, &act);
1286         act.type = XkbSA_LatchMods;
1287         act.mods.flags = 0;
1288         act.mods.mask = mask & latches;
1289         filter = _XkbNextFreeFilter(xkbi);
1290         _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act);
1291         _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE,
1292                              (XkbAction *) NULL);
1293         return Success;
1294     }
1295     return BadValue;
1296 }
1297
1298 int
1299 XkbLatchGroup(DeviceIntPtr pXDev, int group)
1300 {
1301     XkbSrvInfoPtr xkbi;
1302     XkbFilterPtr filter;
1303     XkbAction act;
1304
1305     if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
1306         xkbi = pXDev->key->xkbInfo;
1307         act.type = XkbSA_LatchGroup;
1308         act.group.flags = 0;
1309         XkbSASetGroup(&act.group, group);
1310         filter = _XkbNextFreeFilter(xkbi);
1311         _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act);
1312         _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE,
1313                              (XkbAction *) NULL);
1314         return Success;
1315     }
1316     return BadValue;
1317 }
1318
1319 /***====================================================================***/
1320
1321 void
1322 XkbClearAllLatchesAndLocks(DeviceIntPtr dev,
1323                            XkbSrvInfoPtr xkbi,
1324                            Bool genEv, XkbEventCausePtr cause)
1325 {
1326     XkbStateRec os;
1327     xkbStateNotify sn;
1328
1329     sn.changed = 0;
1330     os = xkbi->state;
1331     if (os.latched_mods) {      /* clear all latches */
1332         XkbLatchModifiers(dev, ~0, 0);
1333         sn.changed |= XkbModifierLatchMask;
1334     }
1335     if (os.latched_group) {
1336         XkbLatchGroup(dev, 0);
1337         sn.changed |= XkbGroupLatchMask;
1338     }
1339     if (os.locked_mods) {
1340         xkbi->state.locked_mods = 0;
1341         sn.changed |= XkbModifierLockMask;
1342     }
1343     if (os.locked_group) {
1344         xkbi->state.locked_group = 0;
1345         sn.changed |= XkbGroupLockMask;
1346     }
1347     if (genEv && sn.changed) {
1348         CARD32 changed;
1349
1350         XkbComputeDerivedState(xkbi);
1351         sn.keycode = cause->kc;
1352         sn.eventType = cause->event;
1353         sn.requestMajor = cause->mjr;
1354         sn.requestMinor = cause->mnr;
1355         sn.changed = XkbStateChangedFlags(&os, &xkbi->state);
1356         XkbSendStateNotify(dev, &sn);
1357         changed = XkbIndicatorsToUpdate(dev, sn.changed, FALSE);
1358         if (changed) {
1359             XkbUpdateIndicators(dev, changed, TRUE, NULL, cause);
1360         }
1361     }
1362     return;
1363 }
1364
1365 /*
1366  * The event is injected into the event processing, not the EQ. Thus,
1367  * ensure that we restore the master after the event sequence to the
1368  * original set of classes. Otherwise, the master remains on the XTEST
1369  * classes and drops events that don't fit into the XTEST layout (e.g.
1370  * events with more than 2 valuators).
1371  *
1372  * FIXME: EQ injection in the processing stage is not designed for, so this
1373  * is a rather awkward hack. The event list returned by GetPointerEvents()
1374  * and friends is always prefixed with a DCE if the last _posted_ device was
1375  * different. For normal events, this sequence then resets the master during
1376  * the processing stage. Since we inject the PointerKey events in the
1377  * processing stage though, we need to manually reset to restore the
1378  * previous order, because the events already in the EQ must be sent for the
1379  * right device.
1380  * So we post-fix the event list we get from GPE with a DCE back to the
1381  * previous slave device.
1382  *
1383  * First one on drinking island wins!
1384  */
1385 static void
1386 InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags,
1387                        ValuatorMask *mask)
1388 {
1389     ScreenPtr pScreen;
1390     InternalEvent *events;
1391     int nevents, i;
1392     DeviceIntPtr ptr, mpointer, lastSlave = NULL;
1393     Bool saveWait;
1394
1395     if (IsMaster(dev)) {
1396         mpointer = GetMaster(dev, MASTER_POINTER);
1397         lastSlave = mpointer->lastSlave;
1398         ptr = GetXTestDevice(mpointer);
1399     }
1400     else if (IsFloating(dev))
1401         ptr = dev;
1402     else
1403         return;
1404
1405     events = InitEventList(GetMaximumEventsNum() + 1);
1406     OsBlockSignals();
1407     pScreen = miPointerGetScreen(ptr);
1408     saveWait = miPointerSetWaitForUpdate(pScreen, FALSE);
1409     nevents = GetPointerEvents(events, ptr, type, button, flags, mask);
1410     if (IsMaster(dev) && (lastSlave && lastSlave != ptr))
1411         UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT,
1412                          &nevents);
1413     miPointerSetWaitForUpdate(pScreen, saveWait);
1414     OsReleaseSignals();
1415
1416     for (i = 0; i < nevents; i++)
1417         mieqProcessDeviceEvent(ptr, &events[i], NULL);
1418
1419     FreeEventList(events, GetMaximumEventsNum());
1420
1421 }
1422
1423 static void
1424 XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x, int y)
1425 {
1426     ValuatorMask mask;
1427     int gpe_flags = 0;
1428
1429     /* ignore attached SDs */
1430     if (!IsMaster(dev) && !IsFloating(dev))
1431         return;
1432
1433     if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
1434         gpe_flags = POINTER_ABSOLUTE;
1435     else
1436         gpe_flags = POINTER_RELATIVE;
1437
1438     valuator_mask_set_range(&mask, 0, 2, (int[]) {
1439                             x, y});
1440
1441     InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, &mask);
1442 }
1443
1444 void
1445 XkbFakeDeviceButton(DeviceIntPtr dev, Bool press, int button)
1446 {
1447     DeviceIntPtr ptr;
1448     int down;
1449
1450     /* If dev is a slave device, and the SD is attached, do nothing. If we'd
1451      * post through the attached master pointer we'd get duplicate events.
1452      *
1453      * if dev is a master keyboard, post through the XTEST device
1454      *
1455      * if dev is a floating slave, post through the device itself.
1456      */
1457
1458     if (IsMaster(dev)) {
1459         DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER);
1460
1461         ptr = GetXTestDevice(mpointer);
1462     }
1463     else if (IsFloating(dev))
1464         ptr = dev;
1465     else
1466         return;
1467
1468     down = button_is_down(ptr, button, BUTTON_PROCESSED);
1469     if (press == down)
1470         return;
1471
1472     InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,
1473                            button, 0, NULL);
1474 }