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