1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
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.
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.
25 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
34 #include <X11/Xproto.h>
35 #include <X11/keysym.h>
44 #include "mipointer.h"
45 #define EXTENSION_EVENT_BASE 64
47 DevPrivateKeyRec xkbDevicePrivateKeyRec;
49 void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button);
50 static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y);
53 xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc,
56 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
57 ProcessInputProc backupproc;
58 if(xkbPrivPtr->unwrapProc)
59 xkbPrivPtr->unwrapProc = NULL;
61 UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc);
63 COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr,
64 backupproc,xkbUnwrapProc);
70 return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec, PRIVATE_DEVICE, 0);
74 XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
76 xkbDeviceInfoPtr xkbPrivPtr;
78 xkbPrivPtr = (xkbDeviceInfoPtr) calloc(1, sizeof(xkbDeviceInfoRec));
81 xkbPrivPtr->unwrapProc = NULL;
83 dixSetPrivate(&device->devPrivates, xkbDevicePrivateKey, xkbPrivPtr);
84 WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc);
87 /***====================================================================***/
90 _FixUpAction(XkbDescPtr xkb,XkbAction *act)
92 static XkbAction fake;
94 if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) {
95 fake.type = XkbSA_NoAction;
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;
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));
120 XkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key)
127 static XkbAction fake;
130 if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) {
131 fake.type = XkbSA_NoAction;
134 pActs= XkbKeyActionsPtr(xkb,key);
137 effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key);
138 if (effectiveGroup != XkbGroup1Index)
139 col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key));
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)) {
153 if (pActs[col].any.type==XkbSA_NoAction)
155 fake= _FixUpAction(xkb,&pActs[col]);
160 XkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button)
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]);
170 fake.any.type= XkbSA_NoAction;
174 /***====================================================================***/
176 #define SYNTHETIC_KEYCODE 1
177 #define BTN_ACT_FLAG 0x100
180 _XkbFilterSetState( XkbSrvInfoPtr xkbi,
185 if (filter->keycode==0) { /* initial press */
186 filter->keycode = keycode;
188 filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0);
190 filter->filter = _XkbFilterSetState;
191 if (pAction->type==XkbSA_SetMods) {
192 filter->upAction = *pAction;
193 xkbi->setMods= pAction->mods.mask;
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);
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;
211 if (filter->upAction.group.flags&XkbSA_ClearLocks) {
212 xkbi->state.locked_group = 0;
214 xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
219 filter->upAction.mods.flags&= ~XkbSA_ClearLocks;
220 filter->filterOthers = 0;
225 #define LATCH_KEY_DOWN 1
226 #define LATCH_PENDING 2
230 _XkbFilterLatchState( XkbSrvInfoPtr xkbi,
236 if (filter->keycode==0) { /* initial press */
237 filter->keycode = keycode;
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;
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);
254 else if ( pAction && (filter->priv==LATCH_PENDING) ) {
255 if (((1<<pAction->type)&XkbSA_BreakLatch)!=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);
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,
276 if (filter->upAction.type==XkbSA_LatchMods)
277 pAction->mods.type= XkbSA_SetMods;
278 else pAction->group.type= XkbSA_SetGroup;
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);
286 else if (filter->keycode==keycode) { /* release */
287 XkbControlsPtr ctrls= xkbi->desc->ctrls;
289 int beepType= _BEEP_NONE;
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;
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;
311 if (filter->priv==NO_LATCH) {
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;
322 xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group);
324 if (needBeep && (beepType==_BEEP_NONE))
325 beepType= _BEEP_STICKY_LATCH;
327 if (needBeep && (beepType!=_BEEP_NONE))
328 XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask);
330 else if (filter->priv==LATCH_KEY_DOWN) {
331 filter->priv= NO_LATCH;
332 filter->filterOthers = 0;
338 _XkbFilterLockState( XkbSrvInfoPtr xkbi,
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);
349 if (filter->keycode==0) { /* initial press */
350 filter->keycode = keycode;
352 filter->filterOthers = 0;
354 filter->filter = _XkbFilterLockState;
355 filter->upAction = *pAction;
356 xkbi->state.locked_mods^= pAction->mods.mask;
357 xkbi->setMods = pAction->mods.mask;
359 else if (filter->keycode==keycode) {
361 xkbi->clearMods = filter->upAction.mods.mask;
366 #define ISO_KEY_DOWN 0
367 #define NO_ISO_LOCK 1
370 _XkbFilterISOLock( XkbSrvInfoPtr xkbi,
376 if (filter->keycode==0) { /* initial press */
377 CARD8 flags= pAction->iso.flags;
379 filter->keycode = keycode;
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);
390 xkbi->setMods = pAction->iso.mask;
391 xkbi->groupChange = 0;
393 if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) {
394 filter->priv= NO_ISO_LOCK;
395 xkbi->state.locked_mods^= xkbi->state.base_mods;
397 if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) {
398 /* 6/22/93 (ef) -- lock groups if group key is down first */
400 if (!(flags&XkbSA_ISONoAffectPtr)) {
401 /* 6/22/93 (ef) -- lock mouse buttons if they're down */
404 else if (filter->keycode==keycode) {
405 CARD8 flags= filter->upAction.iso.flags;
407 if (flags&XkbSA_ISODfltIsGroup) {
408 xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
410 if (filter->priv==ISO_KEY_DOWN)
411 xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso);
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;
422 CARD8 flags= filter->upAction.iso.flags;
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;
431 case XkbSA_SetGroup: case XkbSA_LatchGroup:
432 if (!(flags&XkbSA_ISONoAffectGroup)) {
433 pAction->type= XkbSA_LockGroup;
434 filter->priv= NO_ISO_LOCK;
438 if (!(flags&XkbSA_ISONoAffectPtr)) {
439 pAction->type= XkbSA_LockPtrBtn;
440 filter->priv= NO_ISO_LOCK;
443 case XkbSA_SetControls:
444 if (!(flags&XkbSA_ISONoAffectCtrls)) {
445 pAction->type= XkbSA_LockControls;
446 filter->priv= NO_ISO_LOCK;
456 _XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg)
458 XkbSrvInfoPtr xkbi= (XkbSrvInfoPtr)arg;
459 XkbControlsPtr ctrls= xkbi->desc->ctrls;
462 if (xkbi->mouseKey==0)
465 if (xkbi->mouseKeysAccel) {
466 if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) {
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 );
479 dx= xkbi->mouseKeysDX*ctrls->mk_max_speed;
480 dy= xkbi->mouseKeysDY*ctrls->mk_max_speed;
482 if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX)
483 dx= xkbi->mouseKeysDX;
484 if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY)
485 dy= xkbi->mouseKeysDY;
488 dx= xkbi->mouseKeysDX;
489 dy= xkbi->mouseKeysDY;
491 XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy);
492 return xkbi->desc->ctrls->mk_interval;
496 _XkbFilterPointerMove( XkbSrvInfoPtr xkbi,
504 if (filter->keycode==0) { /* initial press */
505 filter->keycode = keycode;
507 filter->filterOthers = 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);
527 else if (filter->keycode==keycode) {
529 if (xkbi->mouseKey==keycode) {
531 xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0,
539 _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
544 if (filter->keycode==0) { /* initial press */
545 int button= pAction->btn.button;
547 if (button==XkbSA_UseDfltButton)
548 button = xkbi->desc->ctrls->mk_dflt_btn;
550 filter->keycode = keycode;
552 filter->filterOthers = 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;
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);
577 filter->upAction.type= XkbSA_NoAction;
579 else XkbFakeDeviceButton(xkbi->device, 1, button);
582 case XkbSA_SetPtrDflt:
584 XkbControlsPtr ctrls= xkbi->desc->ctrls;
586 xkbControlsNotify cn;
589 AccessXCancelRepeatKey(xkbi,keycode);
590 switch (pAction->dflt.affect) {
591 case XkbSA_AffectDfltBtn:
592 if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute)
594 XkbSAPtrDfltValue(&pAction->dflt);
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;
606 "Attempt to change unknown pointer default (%d) ignored\n",
607 pAction->dflt.affect);
610 if (XkbComputeControlsNotify(xkbi->device,
611 &old,xkbi->desc->ctrls,
613 cn.keycode = keycode;
614 /* XXX: what about DeviceKeyPress? */
615 cn.eventType = KeyPress;
618 XkbSendControlsNotify(xkbi->device,&cn);
624 else if (filter->keycode==keycode) {
625 int button= filter->upAction.btn.button;
627 switch (filter->upAction.type) {
628 case XkbSA_LockPtrBtn:
629 if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)||
630 ((xkbi->lockedPtrButtons&(1<<button))==0)) {
633 xkbi->lockedPtrButtons&= ~(1<<button);
635 if (IsMaster(xkbi->device))
637 XkbMergeLockedPtrBtns(xkbi->device);
638 /* One SD still has lock set, don't post event */
639 if ((xkbi->lockedPtrButtons & (1 << button)) != 0)
645 XkbFakeDeviceButton(xkbi->device, 0, button);
654 _XkbFilterControls( XkbSrvInfoPtr xkbi,
660 XkbControlsPtr ctrls;
663 XkbEventCauseRec cause;
666 ctrls= xkbi->desc->ctrls;
668 if (filter->keycode==0) { /* initial press */
669 filter->keycode = keycode;
671 filter->filterOthers = 0;
672 change= XkbActionCtrls(&pAction->ctrls);
673 filter->priv = change;
674 filter->filter = _XkbFilterControls;
675 filter->upAction = *pAction;
677 if (pAction->type==XkbSA_LockControls) {
678 filter->priv= (ctrls->enabled_ctrls&change);
679 change&= ~ctrls->enabled_ctrls;
683 xkbControlsNotify cn;
684 XkbSrvLedInfoPtr sli;
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;
693 XkbSendControlsNotify(kbd,&cn);
696 XkbSetCauseKey(&cause,keycode,KeyPress);
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);
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);
709 else if (filter->keycode==keycode) {
710 change= filter->priv;
712 xkbControlsNotify cn;
713 XkbSrvLedInfoPtr sli;
715 ctrls->enabled_ctrls&= ~change;
716 if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) {
717 cn.keycode = keycode;
718 cn.eventType = KeyRelease;
721 XkbSendControlsNotify(kbd,&cn);
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);
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);
742 _XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
747 XkbMessageAction * pMsg;
751 if (filter->keycode==0) { /* initial press */
753 if ((pMsg->flags&XkbSA_MessageOnRelease)||
754 ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) {
755 filter->keycode = keycode;
757 filter->filterOthers = 0;
759 filter->filter = _XkbFilterActionMessage;
760 filter->upAction = *pAction;
762 if (pMsg->flags&XkbSA_MessageOnPress) {
763 xkbActionMessage msg;
765 msg.keycode= keycode;
767 msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
768 memcpy((char *)msg.message,
769 (char *)pMsg->message,XkbActionMessageLength);
770 XkbSendActionMessage(kbd,&msg);
772 return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0);
774 else if (filter->keycode==keycode) {
775 pMsg= &filter->upAction.msg;
776 if (pMsg->flags&XkbSA_MessageOnRelease) {
777 xkbActionMessage msg;
779 msg.keycode= keycode;
781 msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
782 memcpy((char *)msg.message,(char *)pMsg->message,
783 XkbActionMessageLength);
784 XkbSendActionMessage(kbd,&msg);
788 return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
794 _XkbFilterRedirectKey( XkbSrvInfoPtr xkbi,
803 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
804 ProcessInputProc backupproc;
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));
811 if ((filter->keycode!=0)&&(filter->keycode!=keycode))
814 GetSpritePosition(xkbi->device, &x,&y);
815 ev.header = ET_Internal;
816 ev.length = sizeof(DeviceEvent);
817 ev.time = GetTimeInMillis();
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)) {
826 filter->keycode = keycode;
828 filter->filterOthers = 0;
830 filter->filter = _XkbFilterRedirectKey;
831 filter->upAction = *pAction;
833 ev.type = ET_KeyPress;
834 ev.detail.key = pAction->redirect.new_key;
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;
843 if ( mask || mods ) {
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);
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);
862 else if (filter->keycode==keycode) {
864 ev.type = ET_KeyRelease;
865 ev.detail.key = filter->upAction.redirect.new_key;
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;
874 if ( mask || mods ) {
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);
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);
900 _XkbFilterSwitchScreen( XkbSrvInfoPtr xkbi,
905 DeviceIntPtr dev = xkbi->device;
906 if (dev == inputInfo.keyboard)
909 if (filter->keycode==0) { /* initial press */
910 filter->keycode = keycode;
912 filter->filterOthers = 0;
913 filter->filter = _XkbFilterSwitchScreen;
914 AccessXCancelRepeatKey(xkbi, keycode);
915 XkbDDXSwitchScreen(dev,keycode,pAction);
918 else if (filter->keycode==keycode) {
926 _XkbFilterXF86Private( XkbSrvInfoPtr xkbi,
931 DeviceIntPtr dev = xkbi->device;
932 if (dev == inputInfo.keyboard)
935 if (filter->keycode==0) { /* initial press */
936 filter->keycode = keycode;
938 filter->filterOthers = 0;
939 filter->filter = _XkbFilterXF86Private;
940 XkbDDXPrivate(dev,keycode,pAction);
943 else if (filter->keycode==keycode) {
952 _XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi,
960 if (xkbi->device == inputInfo.keyboard)
963 if (filter->keycode==0) { /* initial press */
964 _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient,
965 DixUnknownAccess, &button);
966 if (!dev || !dev->public.on)
969 button= pAction->devbtn.button;
970 if ((button<1)||(button>dev->button->numButtons))
973 filter->keycode = keycode;
975 filter->filterOthers = 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))
984 XkbFakeDeviceButton(dev,TRUE,button);
985 filter->upAction.type= XkbSA_NoAction;
987 case XkbSA_DeviceBtn:
988 if (pAction->devbtn.count>0) {
990 nClicks= pAction->btn.count;
991 for (i=0;i<nClicks;i++) {
992 XkbFakeDeviceButton(dev,TRUE,button);
993 XkbFakeDeviceButton(dev,FALSE,button);
995 filter->upAction.type= XkbSA_NoAction;
997 else XkbFakeDeviceButton(dev,TRUE,button);
1001 else if (filter->keycode==keycode) {
1005 _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device,
1006 serverClient, DixUnknownAccess, &button);
1007 if (!dev || !dev->public.on)
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))
1016 XkbFakeDeviceButton(dev,FALSE,button);
1018 case XkbSA_DeviceBtn:
1019 XkbFakeDeviceButton(dev,FALSE,button);
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 */
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];
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];
1055 _XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction)
1057 register int i,send;
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)
1069 XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent* event)
1074 int changed,sendEvent;
1075 Bool genStateNotify;
1077 XkbFilterPtr filter;
1080 ProcessInputProc backupproc;
1082 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
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;
1094 else genStateNotify= FALSE;
1096 xkbi->clearMods = xkbi->setMods = 0;
1097 xkbi->groupChange = 0;
1100 keyEvent= ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
1101 pressEvent= ((event->type == ET_KeyPress)|| (event->type == ET_ButtonPress));
1105 act = XkbGetKeyAction(xkbi,&xkbi->state,key);
1107 act = XkbGetButtonAction(kbd,dev,key);
1110 sendEvent = _XkbApplyFilters(xkbi,key,&act);
1114 case XkbSA_SetGroup:
1115 filter = _XkbNextFreeFilter(xkbi);
1116 sendEvent = _XkbFilterSetState(xkbi,filter,key,&act);
1118 case XkbSA_LatchMods:
1119 case XkbSA_LatchGroup:
1120 filter = _XkbNextFreeFilter(xkbi);
1121 sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act);
1123 case XkbSA_LockMods:
1124 case XkbSA_LockGroup:
1125 filter = _XkbNextFreeFilter(xkbi);
1126 sendEvent=_XkbFilterLockState(xkbi,filter,key,&act);
1129 filter = _XkbNextFreeFilter(xkbi);
1130 sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act);
1133 filter = _XkbNextFreeFilter(xkbi);
1134 sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act);
1137 case XkbSA_LockPtrBtn:
1138 case XkbSA_SetPtrDflt:
1139 filter = _XkbNextFreeFilter(xkbi);
1140 sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act);
1142 case XkbSA_Terminate:
1143 sendEvent= XkbDDXTerminateServer(dev,key,&act);
1145 case XkbSA_SwitchScreen:
1146 filter = _XkbNextFreeFilter(xkbi);
1147 sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act);
1149 case XkbSA_SetControls:
1150 case XkbSA_LockControls:
1151 filter = _XkbNextFreeFilter(xkbi);
1152 sendEvent=_XkbFilterControls(xkbi,filter,key,&act);
1154 case XkbSA_ActionMessage:
1155 filter = _XkbNextFreeFilter(xkbi);
1156 sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act);
1158 case XkbSA_RedirectKey:
1159 filter = _XkbNextFreeFilter(xkbi);
1160 sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act);
1162 case XkbSA_DeviceBtn:
1163 case XkbSA_LockDeviceBtn:
1164 filter = _XkbNextFreeFilter(xkbi);
1165 sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act);
1167 case XkbSA_XFree86Private:
1168 filter = _XkbNextFreeFilter(xkbi);
1169 sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act);
1177 sendEvent = _XkbApplyFilters(xkbi,key,NULL);
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;
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;
1199 xkbi->clearMods&= ~bit;
1205 DeviceIntPtr tmpdev;
1209 tmpdev = GetPairedDevice(dev);
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);
1216 else if (keyEvent) {
1217 FixKeyState(event, dev);
1220 XkbComputeDerivedState(xkbi);
1221 changed = XkbStateChangedFlags(&xkbi->prev_state,&xkbi->state);
1222 if (genStateNotify) {
1226 sn.eventType= event->type;
1227 sn.requestMajor = sn.requestMinor = 0;
1228 sn.changed= changed;
1229 XkbSendStateNotify(dev,&sn);
1231 xkbi->flags&= ~_XkbStateNotifyInProgress;
1233 changed= XkbIndicatorsToUpdate(dev,changed,FALSE);
1235 XkbEventCauseRec cause;
1236 XkbSetCauseKey(&cause, key, event->type);
1237 XkbUpdateIndicators(dev,changed,FALSE,NULL,&cause);
1243 XkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches)
1246 XkbFilterPtr filter;
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.
1256 act.type = XkbSA_NoAction;
1257 _XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act);
1258 act.type = XkbSA_LatchMods;
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);
1270 XkbLatchGroup(DeviceIntPtr pXDev,int group)
1273 XkbFilterPtr filter;
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);
1289 /***====================================================================***/
1292 XkbClearAllLatchesAndLocks( DeviceIntPtr dev,
1295 XkbEventCausePtr cause)
1302 if (os.latched_mods) { /* clear all latches */
1303 XkbLatchModifiers(dev,~0,0);
1304 sn.changed|= XkbModifierLatchMask;
1306 if (os.latched_group) {
1307 XkbLatchGroup(dev,0);
1308 sn.changed|= XkbGroupLatchMask;
1310 if (os.locked_mods) {
1311 xkbi->state.locked_mods= 0;
1312 sn.changed|= XkbModifierLockMask;
1314 if (os.locked_group) {
1315 xkbi->state.locked_group= 0;
1316 sn.changed|= XkbGroupLockMask;
1318 if ( genEv && sn.changed) {
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);
1330 XkbUpdateIndicators(dev,changed,TRUE,NULL,cause);
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).
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
1351 * So we post-fix the event list we get from GPE with a DCE back to the
1352 * previous slave device.
1354 * First one on drinking island wins!
1357 InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, int num_valuators, int *valuators)
1360 EventListPtr events;
1362 DeviceIntPtr ptr, mpointer, lastSlave = NULL;
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)
1375 events = InitEventList(GetMaximumEventsNum() + 1);
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);
1386 for (i = 0; i < nevents; i++)
1387 mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
1389 FreeEventList(events, GetMaximumEventsNum());
1394 XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
1398 /* ignore attached SDs */
1399 if (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) != NULL)
1402 if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
1403 gpe_flags = POINTER_ABSOLUTE;
1405 gpe_flags = POINTER_RELATIVE;
1407 InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, 2, (int[]){x, y});
1411 XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
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.
1419 * if dev is a master keyboard, post through the XTEST device
1421 * if dev is a floating slave, post through the device itself.
1424 if (IsMaster(dev)) {
1425 DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER);
1426 ptr = GetXTestDevice(mpointer);
1427 } else if (!dev->u.master)
1432 down = button_is_down(ptr, button, BUTTON_PROCESSED);
1436 InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,
1437 button, 0, 0, NULL);