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