xkbActions.c revision 9ace9065
105b261ecSmrg/************************************************************ 205b261ecSmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 305b261ecSmrg 405b261ecSmrgPermission to use, copy, modify, and distribute this 505b261ecSmrgsoftware and its documentation for any purpose and without 605b261ecSmrgfee is hereby granted, provided that the above copyright 705b261ecSmrgnotice appear in all copies and that both that copyright 805b261ecSmrgnotice and this permission notice appear in supporting 905b261ecSmrgdocumentation, and that the name of Silicon Graphics not be 1005b261ecSmrgused in advertising or publicity pertaining to distribution 1105b261ecSmrgof the software without specific prior written permission. 1205b261ecSmrgSilicon Graphics makes no representation about the suitability 1305b261ecSmrgof this software for any purpose. It is provided "as is" 1405b261ecSmrgwithout any express or implied warranty. 1505b261ecSmrg 1605b261ecSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1705b261ecSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1805b261ecSmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 1905b261ecSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2005b261ecSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2105b261ecSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 2205b261ecSmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 2305b261ecSmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 2405b261ecSmrg 2505b261ecSmrg********************************************************/ 2605b261ecSmrg 2705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2805b261ecSmrg#include <dix-config.h> 2905b261ecSmrg#endif 3005b261ecSmrg 3105b261ecSmrg#include <stdio.h> 3205b261ecSmrg#include <math.h> 3305b261ecSmrg#include <X11/X.h> 3405b261ecSmrg#include <X11/Xproto.h> 3505b261ecSmrg#include <X11/keysym.h> 3605b261ecSmrg#include "misc.h" 3705b261ecSmrg#include "inputstr.h" 3805b261ecSmrg#include "exevents.h" 396747b715Smrg#include "eventstr.h" 4005b261ecSmrg#include <xkbsrv.h> 4105b261ecSmrg#include "xkb.h" 4205b261ecSmrg#include <ctype.h> 436747b715Smrg#include "mi.h" 446747b715Smrg#include "mipointer.h" 459ace9065Smrg#include "inpututils.h" 4605b261ecSmrg#define EXTENSION_EVENT_BASE 64 4705b261ecSmrg 486747b715SmrgDevPrivateKeyRec xkbDevicePrivateKeyRec; 496747b715Smrg 506747b715Smrgvoid XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button); 516747b715Smrgstatic void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y); 5205b261ecSmrg 5305b261ecSmrgvoid 5405b261ecSmrgxkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, 5505b261ecSmrg pointer data) 5605b261ecSmrg{ 5705b261ecSmrg xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device); 5805b261ecSmrg ProcessInputProc backupproc; 5905b261ecSmrg if(xkbPrivPtr->unwrapProc) 6005b261ecSmrg xkbPrivPtr->unwrapProc = NULL; 6105b261ecSmrg 6205b261ecSmrg UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc); 6305b261ecSmrg proc(device,data); 6405b261ecSmrg COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, 6505b261ecSmrg backupproc,xkbUnwrapProc); 6605b261ecSmrg} 6705b261ecSmrg 686747b715SmrgBool 696747b715SmrgXkbInitPrivates(void) 706747b715Smrg{ 719ace9065Smrg return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec, PRIVATE_DEVICE, sizeof(xkbDeviceInfoRec)); 726747b715Smrg} 7305b261ecSmrg 7405b261ecSmrgvoid 7505b261ecSmrgXkbSetExtension(DeviceIntPtr device, ProcessInputProc proc) 7605b261ecSmrg{ 779ace9065Smrg xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device); 7805b261ecSmrg WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc); 7905b261ecSmrg} 8005b261ecSmrg 8105b261ecSmrg/***====================================================================***/ 8205b261ecSmrg 8305b261ecSmrgstatic XkbAction 8405b261ecSmrg_FixUpAction(XkbDescPtr xkb,XkbAction *act) 8505b261ecSmrg{ 8605b261ecSmrgstatic XkbAction fake; 8705b261ecSmrg 8805b261ecSmrg if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) { 8905b261ecSmrg fake.type = XkbSA_NoAction; 9005b261ecSmrg return fake; 9105b261ecSmrg } 9205b261ecSmrg if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) { 9305b261ecSmrg if (act->any.type==XkbSA_SetMods) { 9405b261ecSmrg fake.mods.type = XkbSA_LatchMods; 9505b261ecSmrg fake.mods.mask = act->mods.mask; 9605b261ecSmrg if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask)) 9705b261ecSmrg fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock; 9805b261ecSmrg else fake.mods.flags= XkbSA_ClearLocks; 9905b261ecSmrg return fake; 10005b261ecSmrg } 10105b261ecSmrg if (act->any.type==XkbSA_SetGroup) { 10205b261ecSmrg fake.group.type = XkbSA_LatchGroup; 10305b261ecSmrg if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask)) 10405b261ecSmrg fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock; 10505b261ecSmrg else fake.group.flags= XkbSA_ClearLocks; 10605b261ecSmrg XkbSASetGroup(&fake.group,XkbSAGroup(&act->group)); 10705b261ecSmrg return fake; 10805b261ecSmrg } 10905b261ecSmrg } 11005b261ecSmrg return *act; 11105b261ecSmrg} 11205b261ecSmrg 11305b261ecSmrgstatic XkbAction 11405b261ecSmrgXkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key) 11505b261ecSmrg{ 11605b261ecSmrgint effectiveGroup; 11705b261ecSmrgint col; 11805b261ecSmrgXkbDescPtr xkb; 11905b261ecSmrgXkbKeyTypePtr type; 12005b261ecSmrgXkbAction * pActs; 12105b261ecSmrgstatic XkbAction fake; 12205b261ecSmrg 12305b261ecSmrg xkb= xkbi->desc; 12405b261ecSmrg if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) { 12505b261ecSmrg fake.type = XkbSA_NoAction; 12605b261ecSmrg return fake; 12705b261ecSmrg } 12805b261ecSmrg pActs= XkbKeyActionsPtr(xkb,key); 12905b261ecSmrg col= 0; 1306747b715Smrg 1316747b715Smrg effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key); 1326747b715Smrg if (effectiveGroup != XkbGroup1Index) 1336747b715Smrg col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key)); 1346747b715Smrg 13505b261ecSmrg type= XkbKeyKeyType(xkb,key,effectiveGroup); 13605b261ecSmrg if (type->map!=NULL) { 13705b261ecSmrg register unsigned i,mods; 13805b261ecSmrg register XkbKTMapEntryPtr entry; 13905b261ecSmrg mods= xkbState->mods&type->mods.mask; 14005b261ecSmrg for (entry= type->map,i=0;i<type->map_count;i++,entry++) { 14105b261ecSmrg if ((entry->active)&&(entry->mods.mask==mods)) { 14205b261ecSmrg col+= entry->level; 14305b261ecSmrg break; 14405b261ecSmrg } 14505b261ecSmrg } 14605b261ecSmrg } 14705b261ecSmrg if (pActs[col].any.type==XkbSA_NoAction) 14805b261ecSmrg return pActs[col]; 14905b261ecSmrg fake= _FixUpAction(xkb,&pActs[col]); 15005b261ecSmrg return fake; 15105b261ecSmrg} 15205b261ecSmrg 15305b261ecSmrgstatic XkbAction 15405b261ecSmrgXkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button) 15505b261ecSmrg{ 15605b261ecSmrgXkbAction fake; 15705b261ecSmrg if ((dev->button)&&(dev->button->xkb_acts)) { 15805b261ecSmrg if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) { 15905b261ecSmrg fake= _FixUpAction(kbd->key->xkbInfo->desc, 16005b261ecSmrg &dev->button->xkb_acts[button-1]); 16105b261ecSmrg return fake; 16205b261ecSmrg } 16305b261ecSmrg } 16405b261ecSmrg fake.any.type= XkbSA_NoAction; 16505b261ecSmrg return fake; 16605b261ecSmrg} 16705b261ecSmrg 16805b261ecSmrg/***====================================================================***/ 16905b261ecSmrg 17005b261ecSmrg#define SYNTHETIC_KEYCODE 1 17105b261ecSmrg#define BTN_ACT_FLAG 0x100 17205b261ecSmrg 17305b261ecSmrgstatic int 17405b261ecSmrg_XkbFilterSetState( XkbSrvInfoPtr xkbi, 17505b261ecSmrg XkbFilterPtr filter, 17605b261ecSmrg unsigned keycode, 17705b261ecSmrg XkbAction *pAction) 17805b261ecSmrg{ 17905b261ecSmrg if (filter->keycode==0) { /* initial press */ 18005b261ecSmrg filter->keycode = keycode; 18105b261ecSmrg filter->active = 1; 18205b261ecSmrg filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0); 18305b261ecSmrg filter->priv = 0; 18405b261ecSmrg filter->filter = _XkbFilterSetState; 18505b261ecSmrg if (pAction->type==XkbSA_SetMods) { 18605b261ecSmrg filter->upAction = *pAction; 18705b261ecSmrg xkbi->setMods= pAction->mods.mask; 18805b261ecSmrg } 18905b261ecSmrg else { 19005b261ecSmrg xkbi->groupChange = XkbSAGroup(&pAction->group); 19105b261ecSmrg if (pAction->group.flags&XkbSA_GroupAbsolute) 19205b261ecSmrg xkbi->groupChange-= xkbi->state.base_group; 19305b261ecSmrg filter->upAction= *pAction; 19405b261ecSmrg XkbSASetGroup(&filter->upAction.group,xkbi->groupChange); 19505b261ecSmrg } 19605b261ecSmrg } 19705b261ecSmrg else if (filter->keycode==keycode) { 19805b261ecSmrg if (filter->upAction.type==XkbSA_SetMods) { 19905b261ecSmrg xkbi->clearMods = filter->upAction.mods.mask; 20005b261ecSmrg if (filter->upAction.mods.flags&XkbSA_ClearLocks) { 20105b261ecSmrg xkbi->state.locked_mods&= ~filter->upAction.mods.mask; 20205b261ecSmrg } 20305b261ecSmrg } 20405b261ecSmrg else { 20505b261ecSmrg if (filter->upAction.group.flags&XkbSA_ClearLocks) { 20605b261ecSmrg xkbi->state.locked_group = 0; 20705b261ecSmrg } 20805b261ecSmrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); 20905b261ecSmrg } 21005b261ecSmrg filter->active = 0; 21105b261ecSmrg } 21205b261ecSmrg else { 21305b261ecSmrg filter->upAction.mods.flags&= ~XkbSA_ClearLocks; 21405b261ecSmrg filter->filterOthers = 0; 21505b261ecSmrg } 21605b261ecSmrg return 1; 21705b261ecSmrg} 21805b261ecSmrg 21905b261ecSmrg#define LATCH_KEY_DOWN 1 22005b261ecSmrg#define LATCH_PENDING 2 22105b261ecSmrg#define NO_LATCH 3 22205b261ecSmrg 22305b261ecSmrgstatic int 22405b261ecSmrg_XkbFilterLatchState( XkbSrvInfoPtr xkbi, 22505b261ecSmrg XkbFilterPtr filter, 22605b261ecSmrg unsigned keycode, 22705b261ecSmrg XkbAction * pAction) 22805b261ecSmrg{ 22905b261ecSmrg 23005b261ecSmrg if (filter->keycode==0) { /* initial press */ 23105b261ecSmrg filter->keycode = keycode; 23205b261ecSmrg filter->active = 1; 23305b261ecSmrg filter->filterOthers = 1; 23405b261ecSmrg filter->priv = LATCH_KEY_DOWN; 23505b261ecSmrg filter->filter = _XkbFilterLatchState; 23605b261ecSmrg if (pAction->type==XkbSA_LatchMods) { 23705b261ecSmrg filter->upAction = *pAction; 23805b261ecSmrg xkbi->setMods = pAction->mods.mask; 23905b261ecSmrg } 24005b261ecSmrg else { 24105b261ecSmrg xkbi->groupChange = XkbSAGroup(&pAction->group); 24205b261ecSmrg if (pAction->group.flags&XkbSA_GroupAbsolute) 24305b261ecSmrg xkbi->groupChange-= xkbi->state.base_group; 24405b261ecSmrg filter->upAction= *pAction; 24505b261ecSmrg XkbSASetGroup(&filter->upAction.group,xkbi->groupChange); 24605b261ecSmrg } 24705b261ecSmrg } 24805b261ecSmrg else if ( pAction && (filter->priv==LATCH_PENDING) ) { 24905b261ecSmrg if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) { 25005b261ecSmrg filter->active = 0; 25105b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) 25205b261ecSmrg xkbi->state.latched_mods&= ~filter->upAction.mods.mask; 25305b261ecSmrg else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group); 25405b261ecSmrg } 25505b261ecSmrg else if ((pAction->type==filter->upAction.type)&& 25605b261ecSmrg (pAction->mods.flags==filter->upAction.mods.flags)&& 25705b261ecSmrg (pAction->mods.mask==filter->upAction.mods.mask)) { 25805b261ecSmrg if (filter->upAction.mods.flags&XkbSA_LatchToLock) { 25905b261ecSmrg XkbControlsPtr ctrls= xkbi->desc->ctrls; 26005b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) 26105b261ecSmrg pAction->mods.type= XkbSA_LockMods; 26205b261ecSmrg else pAction->group.type= XkbSA_LockGroup; 26305b261ecSmrg if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&& 26405b261ecSmrg (ctrls->enabled_ctrls&XkbStickyKeysMask)) { 26505b261ecSmrg XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK, 26605b261ecSmrg XkbStickyKeysMask); 26705b261ecSmrg } 26805b261ecSmrg } 26905b261ecSmrg else { 27005b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) 27105b261ecSmrg pAction->mods.type= XkbSA_SetMods; 27205b261ecSmrg else pAction->group.type= XkbSA_SetGroup; 27305b261ecSmrg } 27405b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) 27505b261ecSmrg xkbi->state.latched_mods&= ~filter->upAction.mods.mask; 27605b261ecSmrg else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group); 27705b261ecSmrg filter->active = 0; 27805b261ecSmrg } 27905b261ecSmrg } 28005b261ecSmrg else if (filter->keycode==keycode) { /* release */ 28105b261ecSmrg XkbControlsPtr ctrls= xkbi->desc->ctrls; 28205b261ecSmrg int needBeep; 28305b261ecSmrg int beepType= _BEEP_NONE; 28405b261ecSmrg 28505b261ecSmrg needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&& 28605b261ecSmrg XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)); 28705b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) { 28805b261ecSmrg xkbi->clearMods = filter->upAction.mods.mask; 28905b261ecSmrg if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&& 29005b261ecSmrg (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) { 29105b261ecSmrg xkbi->state.locked_mods&= ~xkbi->clearMods; 29205b261ecSmrg filter->priv= NO_LATCH; 29305b261ecSmrg beepType= _BEEP_STICKY_UNLOCK; 29405b261ecSmrg } 29505b261ecSmrg } 29605b261ecSmrg else { 29705b261ecSmrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); 29805b261ecSmrg if ((filter->upAction.group.flags&XkbSA_ClearLocks)&& 29905b261ecSmrg (xkbi->state.locked_group)) { 30005b261ecSmrg xkbi->state.locked_group = 0; 30105b261ecSmrg filter->priv = NO_LATCH; 30205b261ecSmrg beepType= _BEEP_STICKY_UNLOCK; 30305b261ecSmrg } 30405b261ecSmrg } 30505b261ecSmrg if (filter->priv==NO_LATCH) { 30605b261ecSmrg filter->active= 0; 30705b261ecSmrg } 30805b261ecSmrg else { 30905b261ecSmrg filter->priv= LATCH_PENDING; 31005b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) { 31105b261ecSmrg xkbi->state.latched_mods |= filter->upAction.mods.mask; 31205b261ecSmrg needBeep = xkbi->state.latched_mods ? needBeep : 0; 31305b261ecSmrg xkbi->state.latched_mods |= filter->upAction.mods.mask; 31405b261ecSmrg } 31505b261ecSmrg else { 31605b261ecSmrg xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group); 31705b261ecSmrg } 31805b261ecSmrg if (needBeep && (beepType==_BEEP_NONE)) 31905b261ecSmrg beepType= _BEEP_STICKY_LATCH; 32005b261ecSmrg } 32105b261ecSmrg if (needBeep && (beepType!=_BEEP_NONE)) 32205b261ecSmrg XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask); 32305b261ecSmrg } 32405b261ecSmrg else if (filter->priv==LATCH_KEY_DOWN) { 32505b261ecSmrg filter->priv= NO_LATCH; 32605b261ecSmrg filter->filterOthers = 0; 32705b261ecSmrg } 32805b261ecSmrg return 1; 32905b261ecSmrg} 33005b261ecSmrg 33105b261ecSmrgstatic int 33205b261ecSmrg_XkbFilterLockState( XkbSrvInfoPtr xkbi, 33305b261ecSmrg XkbFilterPtr filter, 33405b261ecSmrg unsigned keycode, 33505b261ecSmrg XkbAction * pAction) 33605b261ecSmrg{ 33705b261ecSmrg if (pAction&&(pAction->type==XkbSA_LockGroup)) { 33805b261ecSmrg if (pAction->group.flags&XkbSA_GroupAbsolute) 33905b261ecSmrg xkbi->state.locked_group= XkbSAGroup(&pAction->group); 34005b261ecSmrg else xkbi->state.locked_group+= XkbSAGroup(&pAction->group); 34105b261ecSmrg return 1; 34205b261ecSmrg } 34305b261ecSmrg if (filter->keycode==0) { /* initial press */ 34405b261ecSmrg filter->keycode = keycode; 34505b261ecSmrg filter->active = 1; 34605b261ecSmrg filter->filterOthers = 0; 34705b261ecSmrg filter->priv = 0; 34805b261ecSmrg filter->filter = _XkbFilterLockState; 34905b261ecSmrg filter->upAction = *pAction; 35005b261ecSmrg xkbi->state.locked_mods^= pAction->mods.mask; 35105b261ecSmrg xkbi->setMods = pAction->mods.mask; 35205b261ecSmrg } 35305b261ecSmrg else if (filter->keycode==keycode) { 35405b261ecSmrg filter->active = 0; 35505b261ecSmrg xkbi->clearMods = filter->upAction.mods.mask; 35605b261ecSmrg } 35705b261ecSmrg return 1; 35805b261ecSmrg} 35905b261ecSmrg 36005b261ecSmrg#define ISO_KEY_DOWN 0 36105b261ecSmrg#define NO_ISO_LOCK 1 36205b261ecSmrg 36305b261ecSmrgstatic int 36405b261ecSmrg_XkbFilterISOLock( XkbSrvInfoPtr xkbi, 36505b261ecSmrg XkbFilterPtr filter, 36605b261ecSmrg unsigned keycode, 36705b261ecSmrg XkbAction * pAction) 36805b261ecSmrg{ 36905b261ecSmrg 37005b261ecSmrg if (filter->keycode==0) { /* initial press */ 37105b261ecSmrg CARD8 flags= pAction->iso.flags; 37205b261ecSmrg 37305b261ecSmrg filter->keycode = keycode; 37405b261ecSmrg filter->active = 1; 37505b261ecSmrg filter->filterOthers = 1; 37605b261ecSmrg filter->priv = ISO_KEY_DOWN; 37705b261ecSmrg filter->upAction = *pAction; 37805b261ecSmrg filter->filter = _XkbFilterISOLock; 37905b261ecSmrg if (flags&XkbSA_ISODfltIsGroup) { 38005b261ecSmrg xkbi->groupChange = XkbSAGroup(&pAction->iso); 38105b261ecSmrg xkbi->setMods = 0; 38205b261ecSmrg } 38305b261ecSmrg else { 38405b261ecSmrg xkbi->setMods = pAction->iso.mask; 38505b261ecSmrg xkbi->groupChange = 0; 38605b261ecSmrg } 38705b261ecSmrg if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) { 38805b261ecSmrg filter->priv= NO_ISO_LOCK; 38905b261ecSmrg xkbi->state.locked_mods^= xkbi->state.base_mods; 39005b261ecSmrg } 39105b261ecSmrg if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) { 39205b261ecSmrg/* 6/22/93 (ef) -- lock groups if group key is down first */ 39305b261ecSmrg } 39405b261ecSmrg if (!(flags&XkbSA_ISONoAffectPtr)) { 39505b261ecSmrg/* 6/22/93 (ef) -- lock mouse buttons if they're down */ 39605b261ecSmrg } 39705b261ecSmrg } 39805b261ecSmrg else if (filter->keycode==keycode) { 39905b261ecSmrg CARD8 flags= filter->upAction.iso.flags; 40005b261ecSmrg 40105b261ecSmrg if (flags&XkbSA_ISODfltIsGroup) { 40205b261ecSmrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso); 40305b261ecSmrg xkbi->clearMods = 0; 40405b261ecSmrg if (filter->priv==ISO_KEY_DOWN) 40505b261ecSmrg xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso); 40605b261ecSmrg } 40705b261ecSmrg else { 40805b261ecSmrg xkbi->clearMods= filter->upAction.iso.mask; 40905b261ecSmrg xkbi->groupChange= 0; 41005b261ecSmrg if (filter->priv==ISO_KEY_DOWN) 41105b261ecSmrg xkbi->state.locked_mods^= filter->upAction.iso.mask; 41205b261ecSmrg } 41305b261ecSmrg filter->active = 0; 41405b261ecSmrg } 41505b261ecSmrg else if (pAction) { 41605b261ecSmrg CARD8 flags= filter->upAction.iso.flags; 41705b261ecSmrg 41805b261ecSmrg switch (pAction->type) { 41905b261ecSmrg case XkbSA_SetMods: case XkbSA_LatchMods: 42005b261ecSmrg if (!(flags&XkbSA_ISONoAffectMods)) { 42105b261ecSmrg pAction->type= XkbSA_LockMods; 42205b261ecSmrg filter->priv= NO_ISO_LOCK; 42305b261ecSmrg } 42405b261ecSmrg break; 42505b261ecSmrg case XkbSA_SetGroup: case XkbSA_LatchGroup: 42605b261ecSmrg if (!(flags&XkbSA_ISONoAffectGroup)) { 42705b261ecSmrg pAction->type= XkbSA_LockGroup; 42805b261ecSmrg filter->priv= NO_ISO_LOCK; 42905b261ecSmrg } 43005b261ecSmrg break; 43105b261ecSmrg case XkbSA_PtrBtn: 43205b261ecSmrg if (!(flags&XkbSA_ISONoAffectPtr)) { 43305b261ecSmrg pAction->type= XkbSA_LockPtrBtn; 43405b261ecSmrg filter->priv= NO_ISO_LOCK; 43505b261ecSmrg } 43605b261ecSmrg break; 43705b261ecSmrg case XkbSA_SetControls: 43805b261ecSmrg if (!(flags&XkbSA_ISONoAffectCtrls)) { 43905b261ecSmrg pAction->type= XkbSA_LockControls; 44005b261ecSmrg filter->priv= NO_ISO_LOCK; 44105b261ecSmrg } 44205b261ecSmrg break; 44305b261ecSmrg } 44405b261ecSmrg } 44505b261ecSmrg return 1; 44605b261ecSmrg} 44705b261ecSmrg 44805b261ecSmrg 44905b261ecSmrgstatic CARD32 45005b261ecSmrg_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg) 45105b261ecSmrg{ 45205b261ecSmrgXkbSrvInfoPtr xkbi= (XkbSrvInfoPtr)arg; 45305b261ecSmrgXkbControlsPtr ctrls= xkbi->desc->ctrls; 45405b261ecSmrgint dx,dy; 45505b261ecSmrg 45605b261ecSmrg if (xkbi->mouseKey==0) 45705b261ecSmrg return 0; 45805b261ecSmrg 45905b261ecSmrg if (xkbi->mouseKeysAccel) { 46005b261ecSmrg if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) { 46105b261ecSmrg double step; 46205b261ecSmrg xkbi->mouseKeysCounter++; 46305b261ecSmrg step= xkbi->mouseKeysCurveFactor* 46405b261ecSmrg pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve); 46505b261ecSmrg if (xkbi->mouseKeysDX<0) 46605b261ecSmrg dx= floor( ((double)xkbi->mouseKeysDX)*step ); 46705b261ecSmrg else dx= ceil( ((double)xkbi->mouseKeysDX)*step ); 46805b261ecSmrg if (xkbi->mouseKeysDY<0) 46905b261ecSmrg dy= floor( ((double)xkbi->mouseKeysDY)*step ); 47005b261ecSmrg else dy= ceil( ((double)xkbi->mouseKeysDY)*step ); 47105b261ecSmrg } 47205b261ecSmrg else { 47305b261ecSmrg dx= xkbi->mouseKeysDX*ctrls->mk_max_speed; 47405b261ecSmrg dy= xkbi->mouseKeysDY*ctrls->mk_max_speed; 47505b261ecSmrg } 47605b261ecSmrg if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX) 47705b261ecSmrg dx= xkbi->mouseKeysDX; 47805b261ecSmrg if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY) 47905b261ecSmrg dy= xkbi->mouseKeysDY; 48005b261ecSmrg } 48105b261ecSmrg else { 48205b261ecSmrg dx= xkbi->mouseKeysDX; 48305b261ecSmrg dy= xkbi->mouseKeysDY; 48405b261ecSmrg } 4856747b715Smrg XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy); 48605b261ecSmrg return xkbi->desc->ctrls->mk_interval; 48705b261ecSmrg} 48805b261ecSmrg 48905b261ecSmrgstatic int 49005b261ecSmrg_XkbFilterPointerMove( XkbSrvInfoPtr xkbi, 49105b261ecSmrg XkbFilterPtr filter, 49205b261ecSmrg unsigned keycode, 49305b261ecSmrg XkbAction * pAction) 49405b261ecSmrg{ 49505b261ecSmrgint x,y; 49605b261ecSmrgBool accel; 49705b261ecSmrg 49805b261ecSmrg if (filter->keycode==0) { /* initial press */ 49905b261ecSmrg filter->keycode = keycode; 50005b261ecSmrg filter->active = 1; 50105b261ecSmrg filter->filterOthers = 0; 50205b261ecSmrg filter->priv=0; 50305b261ecSmrg filter->filter = _XkbFilterPointerMove; 50405b261ecSmrg filter->upAction= *pAction; 50505b261ecSmrg xkbi->mouseKeysCounter= 0; 50605b261ecSmrg xkbi->mouseKey= keycode; 50705b261ecSmrg accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0); 50805b261ecSmrg x= XkbPtrActionX(&pAction->ptr); 50905b261ecSmrg y= XkbPtrActionY(&pAction->ptr); 5106747b715Smrg XkbFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y); 51105b261ecSmrg AccessXCancelRepeatKey(xkbi,keycode); 51205b261ecSmrg xkbi->mouseKeysAccel= accel&& 51305b261ecSmrg (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask); 51405b261ecSmrg xkbi->mouseKeysFlags= pAction->ptr.flags; 51505b261ecSmrg xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr); 51605b261ecSmrg xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr); 51705b261ecSmrg xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 51805b261ecSmrg xkbi->desc->ctrls->mk_delay, 51905b261ecSmrg _XkbPtrAccelExpire,(pointer)xkbi); 52005b261ecSmrg } 52105b261ecSmrg else if (filter->keycode==keycode) { 52205b261ecSmrg filter->active = 0; 52305b261ecSmrg if (xkbi->mouseKey==keycode) { 52405b261ecSmrg xkbi->mouseKey= 0; 52505b261ecSmrg xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0, 52605b261ecSmrg NULL, NULL); 52705b261ecSmrg } 52805b261ecSmrg } 52905b261ecSmrg return 0; 53005b261ecSmrg} 53105b261ecSmrg 53205b261ecSmrgstatic int 53305b261ecSmrg_XkbFilterPointerBtn( XkbSrvInfoPtr xkbi, 53405b261ecSmrg XkbFilterPtr filter, 53505b261ecSmrg unsigned keycode, 53605b261ecSmrg XkbAction * pAction) 53705b261ecSmrg{ 53805b261ecSmrg if (filter->keycode==0) { /* initial press */ 53905b261ecSmrg int button= pAction->btn.button; 54005b261ecSmrg 54105b261ecSmrg if (button==XkbSA_UseDfltButton) 54205b261ecSmrg button = xkbi->desc->ctrls->mk_dflt_btn; 54305b261ecSmrg 54405b261ecSmrg filter->keycode = keycode; 54505b261ecSmrg filter->active = 1; 54605b261ecSmrg filter->filterOthers = 0; 54705b261ecSmrg filter->priv=0; 54805b261ecSmrg filter->filter = _XkbFilterPointerBtn; 54905b261ecSmrg filter->upAction= *pAction; 55005b261ecSmrg filter->upAction.btn.button= button; 55105b261ecSmrg switch (pAction->type) { 55205b261ecSmrg case XkbSA_LockPtrBtn: 55305b261ecSmrg if (((xkbi->lockedPtrButtons&(1<<button))==0)&& 55405b261ecSmrg ((pAction->btn.flags&XkbSA_LockNoLock)==0)) { 55505b261ecSmrg xkbi->lockedPtrButtons|= (1<<button); 55605b261ecSmrg AccessXCancelRepeatKey(xkbi,keycode); 5576747b715Smrg XkbFakeDeviceButton(xkbi->device, 1, button); 55805b261ecSmrg filter->upAction.type= XkbSA_NoAction; 55905b261ecSmrg } 56005b261ecSmrg break; 56105b261ecSmrg case XkbSA_PtrBtn: 56205b261ecSmrg { 56305b261ecSmrg register int i,nClicks; 56405b261ecSmrg AccessXCancelRepeatKey(xkbi,keycode); 56505b261ecSmrg if (pAction->btn.count>0) { 56605b261ecSmrg nClicks= pAction->btn.count; 56705b261ecSmrg for (i=0;i<nClicks;i++) { 5686747b715Smrg XkbFakeDeviceButton(xkbi->device, 1, button); 5696747b715Smrg XkbFakeDeviceButton(xkbi->device, 0, button); 57005b261ecSmrg } 57105b261ecSmrg filter->upAction.type= XkbSA_NoAction; 57205b261ecSmrg } 5736747b715Smrg else XkbFakeDeviceButton(xkbi->device, 1, button); 57405b261ecSmrg } 57505b261ecSmrg break; 57605b261ecSmrg case XkbSA_SetPtrDflt: 57705b261ecSmrg { 57805b261ecSmrg XkbControlsPtr ctrls= xkbi->desc->ctrls; 57905b261ecSmrg XkbControlsRec old; 58005b261ecSmrg xkbControlsNotify cn; 58105b261ecSmrg 58205b261ecSmrg old= *ctrls; 58305b261ecSmrg AccessXCancelRepeatKey(xkbi,keycode); 58405b261ecSmrg switch (pAction->dflt.affect) { 58505b261ecSmrg case XkbSA_AffectDfltBtn: 58605b261ecSmrg if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute) 58705b261ecSmrg ctrls->mk_dflt_btn= 58805b261ecSmrg XkbSAPtrDfltValue(&pAction->dflt); 58905b261ecSmrg else { 59005b261ecSmrg ctrls->mk_dflt_btn+= 59105b261ecSmrg XkbSAPtrDfltValue(&pAction->dflt); 59205b261ecSmrg if (ctrls->mk_dflt_btn>5) 59305b261ecSmrg ctrls->mk_dflt_btn= 5; 59405b261ecSmrg else if (ctrls->mk_dflt_btn<1) 59505b261ecSmrg ctrls->mk_dflt_btn= 1; 59605b261ecSmrg } 59705b261ecSmrg break; 59805b261ecSmrg default: 59905b261ecSmrg ErrorF( 60005b261ecSmrg "Attempt to change unknown pointer default (%d) ignored\n", 60105b261ecSmrg pAction->dflt.affect); 60205b261ecSmrg break; 60305b261ecSmrg } 60405b261ecSmrg if (XkbComputeControlsNotify(xkbi->device, 60505b261ecSmrg &old,xkbi->desc->ctrls, 6066747b715Smrg &cn,FALSE)) { 60705b261ecSmrg cn.keycode = keycode; 60805b261ecSmrg /* XXX: what about DeviceKeyPress? */ 60905b261ecSmrg cn.eventType = KeyPress; 61005b261ecSmrg cn.requestMajor = 0; 61105b261ecSmrg cn.requestMinor = 0; 61205b261ecSmrg XkbSendControlsNotify(xkbi->device,&cn); 61305b261ecSmrg } 61405b261ecSmrg } 61505b261ecSmrg break; 61605b261ecSmrg } 61705b261ecSmrg } 61805b261ecSmrg else if (filter->keycode==keycode) { 61905b261ecSmrg int button= filter->upAction.btn.button; 62005b261ecSmrg 62105b261ecSmrg switch (filter->upAction.type) { 62205b261ecSmrg case XkbSA_LockPtrBtn: 62305b261ecSmrg if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)|| 62405b261ecSmrg ((xkbi->lockedPtrButtons&(1<<button))==0)) { 62505b261ecSmrg break; 62605b261ecSmrg } 62705b261ecSmrg xkbi->lockedPtrButtons&= ~(1<<button); 6286747b715Smrg 6296747b715Smrg if (IsMaster(xkbi->device)) 6306747b715Smrg { 6316747b715Smrg XkbMergeLockedPtrBtns(xkbi->device); 6326747b715Smrg /* One SD still has lock set, don't post event */ 6336747b715Smrg if ((xkbi->lockedPtrButtons & (1 << button)) != 0) 6346747b715Smrg break; 6356747b715Smrg } 6366747b715Smrg 6376747b715Smrg /* fallthrough */ 63805b261ecSmrg case XkbSA_PtrBtn: 6396747b715Smrg XkbFakeDeviceButton(xkbi->device, 0, button); 64005b261ecSmrg break; 64105b261ecSmrg } 64205b261ecSmrg filter->active = 0; 64305b261ecSmrg } 64405b261ecSmrg return 0; 64505b261ecSmrg} 64605b261ecSmrg 64705b261ecSmrgstatic int 64805b261ecSmrg_XkbFilterControls( XkbSrvInfoPtr xkbi, 64905b261ecSmrg XkbFilterPtr filter, 65005b261ecSmrg unsigned keycode, 65105b261ecSmrg XkbAction * pAction) 65205b261ecSmrg{ 65305b261ecSmrgXkbControlsRec old; 65405b261ecSmrgXkbControlsPtr ctrls; 65505b261ecSmrgDeviceIntPtr kbd; 65605b261ecSmrgunsigned int change; 65705b261ecSmrgXkbEventCauseRec cause; 65805b261ecSmrg 65905b261ecSmrg kbd= xkbi->device; 66005b261ecSmrg ctrls= xkbi->desc->ctrls; 66105b261ecSmrg old= *ctrls; 66205b261ecSmrg if (filter->keycode==0) { /* initial press */ 66305b261ecSmrg filter->keycode = keycode; 66405b261ecSmrg filter->active = 1; 66505b261ecSmrg filter->filterOthers = 0; 66605b261ecSmrg change= XkbActionCtrls(&pAction->ctrls); 66705b261ecSmrg filter->priv = change; 66805b261ecSmrg filter->filter = _XkbFilterControls; 66905b261ecSmrg filter->upAction = *pAction; 67005b261ecSmrg 67105b261ecSmrg if (pAction->type==XkbSA_LockControls) { 67205b261ecSmrg filter->priv= (ctrls->enabled_ctrls&change); 67305b261ecSmrg change&= ~ctrls->enabled_ctrls; 67405b261ecSmrg } 67505b261ecSmrg 67605b261ecSmrg if (change) { 67705b261ecSmrg xkbControlsNotify cn; 67805b261ecSmrg XkbSrvLedInfoPtr sli; 67905b261ecSmrg 68005b261ecSmrg ctrls->enabled_ctrls|= change; 6816747b715Smrg if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) { 68205b261ecSmrg cn.keycode = keycode; 68305b261ecSmrg /* XXX: what about DeviceKeyPress? */ 68405b261ecSmrg cn.eventType = KeyPress; 68505b261ecSmrg cn.requestMajor = 0; 68605b261ecSmrg cn.requestMinor = 0; 68705b261ecSmrg XkbSendControlsNotify(kbd,&cn); 68805b261ecSmrg } 68905b261ecSmrg 69005b261ecSmrg XkbSetCauseKey(&cause,keycode,KeyPress); 69105b261ecSmrg 69205b261ecSmrg /* If sticky keys were disabled, clear all locks and latches */ 69305b261ecSmrg if ((old.enabled_ctrls&XkbStickyKeysMask)&& 69405b261ecSmrg (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) { 6956747b715Smrg XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause); 69605b261ecSmrg } 69705b261ecSmrg sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); 6986747b715Smrg XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause); 69905b261ecSmrg if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) 70005b261ecSmrg XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change); 70105b261ecSmrg } 70205b261ecSmrg } 70305b261ecSmrg else if (filter->keycode==keycode) { 70405b261ecSmrg change= filter->priv; 70505b261ecSmrg if (change) { 70605b261ecSmrg xkbControlsNotify cn; 70705b261ecSmrg XkbSrvLedInfoPtr sli; 70805b261ecSmrg 70905b261ecSmrg ctrls->enabled_ctrls&= ~change; 7106747b715Smrg if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) { 71105b261ecSmrg cn.keycode = keycode; 71205b261ecSmrg cn.eventType = KeyRelease; 71305b261ecSmrg cn.requestMajor = 0; 71405b261ecSmrg cn.requestMinor = 0; 71505b261ecSmrg XkbSendControlsNotify(kbd,&cn); 71605b261ecSmrg } 71705b261ecSmrg 71805b261ecSmrg XkbSetCauseKey(&cause,keycode,KeyRelease); 71905b261ecSmrg /* If sticky keys were disabled, clear all locks and latches */ 72005b261ecSmrg if ((old.enabled_ctrls&XkbStickyKeysMask)&& 72105b261ecSmrg (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) { 7226747b715Smrg XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause); 72305b261ecSmrg } 72405b261ecSmrg sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); 7256747b715Smrg XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause); 72605b261ecSmrg if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) 72705b261ecSmrg XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change); 72805b261ecSmrg } 72905b261ecSmrg filter->keycode= 0; 73005b261ecSmrg filter->active= 0; 73105b261ecSmrg } 73205b261ecSmrg return 1; 73305b261ecSmrg} 73405b261ecSmrg 73505b261ecSmrgstatic int 73605b261ecSmrg_XkbFilterActionMessage(XkbSrvInfoPtr xkbi, 73705b261ecSmrg XkbFilterPtr filter, 73805b261ecSmrg unsigned keycode, 73905b261ecSmrg XkbAction * pAction) 74005b261ecSmrg{ 74105b261ecSmrgXkbMessageAction * pMsg; 74205b261ecSmrgDeviceIntPtr kbd; 74305b261ecSmrg 74405b261ecSmrg kbd= xkbi->device; 74505b261ecSmrg if (filter->keycode==0) { /* initial press */ 74605b261ecSmrg pMsg= &pAction->msg; 74705b261ecSmrg if ((pMsg->flags&XkbSA_MessageOnRelease)|| 74805b261ecSmrg ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) { 74905b261ecSmrg filter->keycode = keycode; 75005b261ecSmrg filter->active = 1; 75105b261ecSmrg filter->filterOthers = 0; 75205b261ecSmrg filter->priv = 0; 75305b261ecSmrg filter->filter = _XkbFilterActionMessage; 75405b261ecSmrg filter->upAction = *pAction; 75505b261ecSmrg } 75605b261ecSmrg if (pMsg->flags&XkbSA_MessageOnPress) { 75705b261ecSmrg xkbActionMessage msg; 75805b261ecSmrg 75905b261ecSmrg msg.keycode= keycode; 76005b261ecSmrg msg.press= 1; 76105b261ecSmrg msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 76205b261ecSmrg memcpy((char *)msg.message, 76305b261ecSmrg (char *)pMsg->message,XkbActionMessageLength); 76405b261ecSmrg XkbSendActionMessage(kbd,&msg); 76505b261ecSmrg } 76605b261ecSmrg return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0); 76705b261ecSmrg } 76805b261ecSmrg else if (filter->keycode==keycode) { 76905b261ecSmrg pMsg= &filter->upAction.msg; 77005b261ecSmrg if (pMsg->flags&XkbSA_MessageOnRelease) { 77105b261ecSmrg xkbActionMessage msg; 77205b261ecSmrg 77305b261ecSmrg msg.keycode= keycode; 77405b261ecSmrg msg.press= 0; 77505b261ecSmrg msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 77605b261ecSmrg memcpy((char *)msg.message,(char *)pMsg->message, 77705b261ecSmrg XkbActionMessageLength); 77805b261ecSmrg XkbSendActionMessage(kbd,&msg); 77905b261ecSmrg } 78005b261ecSmrg filter->keycode= 0; 78105b261ecSmrg filter->active= 0; 78205b261ecSmrg return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 78305b261ecSmrg } 78405b261ecSmrg return 0; 78505b261ecSmrg} 78605b261ecSmrg 78705b261ecSmrgstatic int 78805b261ecSmrg_XkbFilterRedirectKey( XkbSrvInfoPtr xkbi, 78905b261ecSmrg XkbFilterPtr filter, 79005b261ecSmrg unsigned keycode, 79105b261ecSmrg XkbAction * pAction) 79205b261ecSmrg{ 7936747b715SmrgDeviceEvent ev; 79405b261ecSmrgint x,y; 79505b261ecSmrgXkbStateRec old; 7966747b715Smrgunsigned mods,mask; 79705b261ecSmrgxkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device); 79805b261ecSmrgProcessInputProc backupproc; 79905b261ecSmrg 80005b261ecSmrg /* never actually used uninitialised, but gcc isn't smart enough 80105b261ecSmrg * to work that out. */ 80205b261ecSmrg memset(&old, 0, sizeof(old)); 8036747b715Smrg memset(&ev, 0, sizeof(ev)); 80405b261ecSmrg 80505b261ecSmrg if ((filter->keycode!=0)&&(filter->keycode!=keycode)) 80605b261ecSmrg return 1; 80705b261ecSmrg 8086747b715Smrg GetSpritePosition(xkbi->device, &x,&y); 8096747b715Smrg ev.header = ET_Internal; 8106747b715Smrg ev.length = sizeof(DeviceEvent); 8116747b715Smrg ev.time = GetTimeInMillis(); 8126747b715Smrg ev.root_x = x; 8136747b715Smrg ev.root_y = y; 81405b261ecSmrg 81505b261ecSmrg if (filter->keycode==0) { /* initial press */ 81605b261ecSmrg if ((pAction->redirect.new_key<xkbi->desc->min_key_code)|| 81705b261ecSmrg (pAction->redirect.new_key>xkbi->desc->max_key_code)) { 81805b261ecSmrg return 1; 81905b261ecSmrg } 82005b261ecSmrg filter->keycode = keycode; 82105b261ecSmrg filter->active = 1; 82205b261ecSmrg filter->filterOthers = 0; 82305b261ecSmrg filter->priv = 0; 82405b261ecSmrg filter->filter = _XkbFilterRedirectKey; 82505b261ecSmrg filter->upAction = *pAction; 82605b261ecSmrg 8276747b715Smrg ev.type = ET_KeyPress; 8286747b715Smrg ev.detail.key = pAction->redirect.new_key; 82905b261ecSmrg 83005b261ecSmrg mask= XkbSARedirectVModsMask(&pAction->redirect); 83105b261ecSmrg mods= XkbSARedirectVMods(&pAction->redirect); 83205b261ecSmrg if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask); 83305b261ecSmrg if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods); 83405b261ecSmrg mask|= pAction->redirect.mods_mask; 83505b261ecSmrg mods|= pAction->redirect.mods; 83605b261ecSmrg 83705b261ecSmrg if ( mask || mods ) { 83805b261ecSmrg old= xkbi->state; 83905b261ecSmrg xkbi->state.base_mods&= ~mask; 84005b261ecSmrg xkbi->state.base_mods|= (mods&mask); 84105b261ecSmrg xkbi->state.latched_mods&= ~mask; 84205b261ecSmrg xkbi->state.latched_mods|= (mods&mask); 84305b261ecSmrg xkbi->state.locked_mods&= ~mask; 84405b261ecSmrg xkbi->state.locked_mods|= (mods&mask); 84505b261ecSmrg XkbComputeDerivedState(xkbi); 84605b261ecSmrg } 84705b261ecSmrg 84805b261ecSmrg UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc); 8496747b715Smrg xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device); 85005b261ecSmrg COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, 85105b261ecSmrg backupproc,xkbUnwrapProc); 85205b261ecSmrg 8536747b715Smrg if ( mask || mods ) 85405b261ecSmrg xkbi->state= old; 85505b261ecSmrg } 85605b261ecSmrg else if (filter->keycode==keycode) { 85705b261ecSmrg 8586747b715Smrg ev.type = ET_KeyRelease; 8596747b715Smrg ev.detail.key = filter->upAction.redirect.new_key; 86005b261ecSmrg 86105b261ecSmrg mask= XkbSARedirectVModsMask(&filter->upAction.redirect); 86205b261ecSmrg mods= XkbSARedirectVMods(&filter->upAction.redirect); 86305b261ecSmrg if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask); 86405b261ecSmrg if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods); 86505b261ecSmrg mask|= filter->upAction.redirect.mods_mask; 86605b261ecSmrg mods|= filter->upAction.redirect.mods; 86705b261ecSmrg 86805b261ecSmrg if ( mask || mods ) { 86905b261ecSmrg old= xkbi->state; 87005b261ecSmrg xkbi->state.base_mods&= ~mask; 87105b261ecSmrg xkbi->state.base_mods|= (mods&mask); 87205b261ecSmrg xkbi->state.latched_mods&= ~mask; 87305b261ecSmrg xkbi->state.latched_mods|= (mods&mask); 87405b261ecSmrg xkbi->state.locked_mods&= ~mask; 87505b261ecSmrg xkbi->state.locked_mods|= (mods&mask); 87605b261ecSmrg XkbComputeDerivedState(xkbi); 87705b261ecSmrg } 87805b261ecSmrg 87905b261ecSmrg UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc); 8806747b715Smrg xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device); 88105b261ecSmrg COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, 88205b261ecSmrg backupproc,xkbUnwrapProc); 88305b261ecSmrg 8846747b715Smrg if ( mask || mods ) 88505b261ecSmrg xkbi->state= old; 88605b261ecSmrg 88705b261ecSmrg filter->keycode= 0; 88805b261ecSmrg filter->active= 0; 88905b261ecSmrg } 89005b261ecSmrg return 0; 89105b261ecSmrg} 89205b261ecSmrg 89305b261ecSmrgstatic int 89405b261ecSmrg_XkbFilterSwitchScreen( XkbSrvInfoPtr xkbi, 89505b261ecSmrg XkbFilterPtr filter, 89605b261ecSmrg unsigned keycode, 89705b261ecSmrg XkbAction * pAction) 89805b261ecSmrg{ 89905b261ecSmrg DeviceIntPtr dev = xkbi->device; 90005b261ecSmrg if (dev == inputInfo.keyboard) 90105b261ecSmrg return 0; 90205b261ecSmrg 90305b261ecSmrg if (filter->keycode==0) { /* initial press */ 90405b261ecSmrg filter->keycode = keycode; 90505b261ecSmrg filter->active = 1; 90605b261ecSmrg filter->filterOthers = 0; 90705b261ecSmrg filter->filter = _XkbFilterSwitchScreen; 90805b261ecSmrg AccessXCancelRepeatKey(xkbi, keycode); 90905b261ecSmrg XkbDDXSwitchScreen(dev,keycode,pAction); 91005b261ecSmrg return 0; 91105b261ecSmrg } 91205b261ecSmrg else if (filter->keycode==keycode) { 91305b261ecSmrg filter->active= 0; 91405b261ecSmrg return 0; 91505b261ecSmrg } 91605b261ecSmrg return 1; 91705b261ecSmrg} 91805b261ecSmrg 91905b261ecSmrgstatic int 92005b261ecSmrg_XkbFilterXF86Private( XkbSrvInfoPtr xkbi, 92105b261ecSmrg XkbFilterPtr filter, 92205b261ecSmrg unsigned keycode, 92305b261ecSmrg XkbAction * pAction) 92405b261ecSmrg{ 92505b261ecSmrg DeviceIntPtr dev = xkbi->device; 92605b261ecSmrg if (dev == inputInfo.keyboard) 92705b261ecSmrg return 0; 92805b261ecSmrg 92905b261ecSmrg if (filter->keycode==0) { /* initial press */ 93005b261ecSmrg filter->keycode = keycode; 93105b261ecSmrg filter->active = 1; 93205b261ecSmrg filter->filterOthers = 0; 93305b261ecSmrg filter->filter = _XkbFilterXF86Private; 93405b261ecSmrg XkbDDXPrivate(dev,keycode,pAction); 93505b261ecSmrg return 0; 93605b261ecSmrg } 93705b261ecSmrg else if (filter->keycode==keycode) { 93805b261ecSmrg filter->active= 0; 93905b261ecSmrg return 0; 94005b261ecSmrg } 94105b261ecSmrg return 1; 94205b261ecSmrg} 94305b261ecSmrg 94405b261ecSmrg 94505b261ecSmrgstatic int 94605b261ecSmrg_XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi, 94705b261ecSmrg XkbFilterPtr filter, 94805b261ecSmrg unsigned keycode, 94905b261ecSmrg XkbAction * pAction) 95005b261ecSmrg{ 95105b261ecSmrgDeviceIntPtr dev; 95205b261ecSmrgint button; 95305b261ecSmrg 9544642e01fSmrg if (xkbi->device == inputInfo.keyboard) 95505b261ecSmrg return 0; 95605b261ecSmrg 95705b261ecSmrg if (filter->keycode==0) { /* initial press */ 9584642e01fSmrg _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient, 9594642e01fSmrg DixUnknownAccess, &button); 9606747b715Smrg if (!dev || !dev->public.on) 96105b261ecSmrg return 1; 96205b261ecSmrg 96305b261ecSmrg button= pAction->devbtn.button; 96405b261ecSmrg if ((button<1)||(button>dev->button->numButtons)) 96505b261ecSmrg return 1; 96605b261ecSmrg 96705b261ecSmrg filter->keycode = keycode; 96805b261ecSmrg filter->active = 1; 96905b261ecSmrg filter->filterOthers = 0; 97005b261ecSmrg filter->priv=0; 97105b261ecSmrg filter->filter = _XkbFilterDeviceBtn; 97205b261ecSmrg filter->upAction= *pAction; 97305b261ecSmrg switch (pAction->type) { 97405b261ecSmrg case XkbSA_LockDeviceBtn: 97505b261ecSmrg if ((pAction->devbtn.flags&XkbSA_LockNoLock)|| 9764642e01fSmrg BitIsOn(dev->button->down, button)) 97705b261ecSmrg return 0; 9786747b715Smrg XkbFakeDeviceButton(dev,TRUE,button); 97905b261ecSmrg filter->upAction.type= XkbSA_NoAction; 98005b261ecSmrg break; 98105b261ecSmrg case XkbSA_DeviceBtn: 98205b261ecSmrg if (pAction->devbtn.count>0) { 98305b261ecSmrg int nClicks,i; 98405b261ecSmrg nClicks= pAction->btn.count; 98505b261ecSmrg for (i=0;i<nClicks;i++) { 9866747b715Smrg XkbFakeDeviceButton(dev,TRUE,button); 9876747b715Smrg XkbFakeDeviceButton(dev,FALSE,button); 98805b261ecSmrg } 98905b261ecSmrg filter->upAction.type= XkbSA_NoAction; 99005b261ecSmrg } 9916747b715Smrg else XkbFakeDeviceButton(dev,TRUE,button); 99205b261ecSmrg break; 99305b261ecSmrg } 99405b261ecSmrg } 99505b261ecSmrg else if (filter->keycode==keycode) { 99605b261ecSmrg int button; 99705b261ecSmrg 99805b261ecSmrg filter->active= 0; 9994642e01fSmrg _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device, 10004642e01fSmrg serverClient, DixUnknownAccess, &button); 10016747b715Smrg if (!dev || !dev->public.on) 100205b261ecSmrg return 1; 100305b261ecSmrg 100405b261ecSmrg button= filter->upAction.btn.button; 100505b261ecSmrg switch (filter->upAction.type) { 100605b261ecSmrg case XkbSA_LockDeviceBtn: 100705b261ecSmrg if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)|| 10084642e01fSmrg !BitIsOn(dev->button->down, button)) 100905b261ecSmrg return 0; 10106747b715Smrg XkbFakeDeviceButton(dev,FALSE,button); 101105b261ecSmrg break; 101205b261ecSmrg case XkbSA_DeviceBtn: 10136747b715Smrg XkbFakeDeviceButton(dev,FALSE,button); 101405b261ecSmrg break; 101505b261ecSmrg } 101605b261ecSmrg filter->active = 0; 101705b261ecSmrg } 101805b261ecSmrg return 0; 101905b261ecSmrg} 102005b261ecSmrg 102105b261ecSmrgstatic XkbFilterPtr 102205b261ecSmrg_XkbNextFreeFilter( 102305b261ecSmrg XkbSrvInfoPtr xkbi 102405b261ecSmrg) 102505b261ecSmrg{ 102605b261ecSmrgregister int i; 102705b261ecSmrg 102805b261ecSmrg if (xkbi->szFilters==0) { 102905b261ecSmrg xkbi->szFilters = 4; 10306747b715Smrg xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec)); 103105b261ecSmrg /* 6/21/93 (ef) -- XXX! deal with allocation failure */ 103205b261ecSmrg } 103305b261ecSmrg for (i=0;i<xkbi->szFilters;i++) { 103405b261ecSmrg if (!xkbi->filters[i].active) { 103505b261ecSmrg xkbi->filters[i].keycode = 0; 103605b261ecSmrg return &xkbi->filters[i]; 103705b261ecSmrg } 103805b261ecSmrg } 103905b261ecSmrg xkbi->szFilters*=2; 10406747b715Smrg xkbi->filters= realloc(xkbi->filters, 10416747b715Smrg xkbi->szFilters * sizeof(XkbFilterRec)); 104205b261ecSmrg /* 6/21/93 (ef) -- XXX! deal with allocation failure */ 10436747b715Smrg memset(&xkbi->filters[xkbi->szFilters/2], 0, 104405b261ecSmrg (xkbi->szFilters/2)*sizeof(XkbFilterRec)); 104505b261ecSmrg return &xkbi->filters[xkbi->szFilters/2]; 104605b261ecSmrg} 104705b261ecSmrg 104805b261ecSmrgstatic int 104905b261ecSmrg_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction) 105005b261ecSmrg{ 105105b261ecSmrgregister int i,send; 105205b261ecSmrg 105305b261ecSmrg send= 1; 105405b261ecSmrg for (i=0;i<xkbi->szFilters;i++) { 105505b261ecSmrg if ((xkbi->filters[i].active)&&(xkbi->filters[i].filter)) 105605b261ecSmrg send= ((*xkbi->filters[i].filter)(xkbi,&xkbi->filters[i],kc,pAction) 105705b261ecSmrg && send); 105805b261ecSmrg } 105905b261ecSmrg return send; 106005b261ecSmrg} 106105b261ecSmrg 106205b261ecSmrgvoid 10636747b715SmrgXkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent* event) 106405b261ecSmrg{ 106505b261ecSmrgint key,bit,i; 106605b261ecSmrgXkbSrvInfoPtr xkbi; 106705b261ecSmrgKeyClassPtr keyc; 106805b261ecSmrgint changed,sendEvent; 106905b261ecSmrgBool genStateNotify; 107005b261ecSmrgXkbAction act; 107105b261ecSmrgXkbFilterPtr filter; 107205b261ecSmrgBool keyEvent; 107305b261ecSmrgBool pressEvent; 107405b261ecSmrgProcessInputProc backupproc; 107505b261ecSmrg 107605b261ecSmrgxkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev); 107705b261ecSmrg 107805b261ecSmrg keyc= kbd->key; 107905b261ecSmrg xkbi= keyc->xkbInfo; 10806747b715Smrg key= event->detail.key; 108105b261ecSmrg /* The state may change, so if we're not in the middle of sending a state 108205b261ecSmrg * notify, prepare for it */ 108305b261ecSmrg if ((xkbi->flags&_XkbStateNotifyInProgress)==0) { 10846747b715Smrg xkbi->prev_state = xkbi->state; 108505b261ecSmrg xkbi->flags|= _XkbStateNotifyInProgress; 10866747b715Smrg genStateNotify= TRUE; 108705b261ecSmrg } 10886747b715Smrg else genStateNotify= FALSE; 108905b261ecSmrg 109005b261ecSmrg xkbi->clearMods = xkbi->setMods = 0; 109105b261ecSmrg xkbi->groupChange = 0; 109205b261ecSmrg 109305b261ecSmrg sendEvent = 1; 10946747b715Smrg keyEvent= ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease)); 10956747b715Smrg pressEvent= ((event->type == ET_KeyPress)|| (event->type == ET_ButtonPress)); 109605b261ecSmrg 109705b261ecSmrg if (pressEvent) { 109805b261ecSmrg if (keyEvent) 109905b261ecSmrg act = XkbGetKeyAction(xkbi,&xkbi->state,key); 110005b261ecSmrg else { 110105b261ecSmrg act = XkbGetButtonAction(kbd,dev,key); 110205b261ecSmrg key|= BTN_ACT_FLAG; 110305b261ecSmrg } 110405b261ecSmrg sendEvent = _XkbApplyFilters(xkbi,key,&act); 110505b261ecSmrg if (sendEvent) { 110605b261ecSmrg switch (act.type) { 110705b261ecSmrg case XkbSA_SetMods: 110805b261ecSmrg case XkbSA_SetGroup: 110905b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 111005b261ecSmrg sendEvent = _XkbFilterSetState(xkbi,filter,key,&act); 111105b261ecSmrg break; 111205b261ecSmrg case XkbSA_LatchMods: 111305b261ecSmrg case XkbSA_LatchGroup: 111405b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 111505b261ecSmrg sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act); 111605b261ecSmrg break; 111705b261ecSmrg case XkbSA_LockMods: 111805b261ecSmrg case XkbSA_LockGroup: 111905b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 112005b261ecSmrg sendEvent=_XkbFilterLockState(xkbi,filter,key,&act); 112105b261ecSmrg break; 112205b261ecSmrg case XkbSA_ISOLock: 112305b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 112405b261ecSmrg sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act); 112505b261ecSmrg break; 112605b261ecSmrg case XkbSA_MovePtr: 112705b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 112805b261ecSmrg sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act); 112905b261ecSmrg break; 113005b261ecSmrg case XkbSA_PtrBtn: 113105b261ecSmrg case XkbSA_LockPtrBtn: 113205b261ecSmrg case XkbSA_SetPtrDflt: 113305b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 113405b261ecSmrg sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act); 113505b261ecSmrg break; 113605b261ecSmrg case XkbSA_Terminate: 113705b261ecSmrg sendEvent= XkbDDXTerminateServer(dev,key,&act); 113805b261ecSmrg break; 113905b261ecSmrg case XkbSA_SwitchScreen: 114005b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 114105b261ecSmrg sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act); 114205b261ecSmrg break; 114305b261ecSmrg case XkbSA_SetControls: 114405b261ecSmrg case XkbSA_LockControls: 114505b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 114605b261ecSmrg sendEvent=_XkbFilterControls(xkbi,filter,key,&act); 114705b261ecSmrg break; 114805b261ecSmrg case XkbSA_ActionMessage: 114905b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 115005b261ecSmrg sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act); 115105b261ecSmrg break; 115205b261ecSmrg case XkbSA_RedirectKey: 115305b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 115405b261ecSmrg sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act); 115505b261ecSmrg break; 115605b261ecSmrg case XkbSA_DeviceBtn: 115705b261ecSmrg case XkbSA_LockDeviceBtn: 115805b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 115905b261ecSmrg sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act); 116005b261ecSmrg break; 116105b261ecSmrg case XkbSA_XFree86Private: 116205b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 116305b261ecSmrg sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act); 116405b261ecSmrg break; 116505b261ecSmrg } 116605b261ecSmrg } 116705b261ecSmrg } 116805b261ecSmrg else { 116905b261ecSmrg if (!keyEvent) 117005b261ecSmrg key|= BTN_ACT_FLAG; 117105b261ecSmrg sendEvent = _XkbApplyFilters(xkbi,key,NULL); 117205b261ecSmrg } 117305b261ecSmrg 117405b261ecSmrg if (xkbi->groupChange!=0) 117505b261ecSmrg xkbi->state.base_group+= xkbi->groupChange; 117605b261ecSmrg if (xkbi->setMods) { 117705b261ecSmrg for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) { 117805b261ecSmrg if (xkbi->setMods&bit) { 117905b261ecSmrg keyc->modifierKeyCount[i]++; 118005b261ecSmrg xkbi->state.base_mods|= bit; 118105b261ecSmrg xkbi->setMods&= ~bit; 118205b261ecSmrg } 118305b261ecSmrg } 118405b261ecSmrg } 118505b261ecSmrg if (xkbi->clearMods) { 118605b261ecSmrg for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) { 118705b261ecSmrg if (xkbi->clearMods&bit) { 118805b261ecSmrg keyc->modifierKeyCount[i]--; 118905b261ecSmrg if (keyc->modifierKeyCount[i]<=0) { 119005b261ecSmrg xkbi->state.base_mods&= ~bit; 119105b261ecSmrg keyc->modifierKeyCount[i] = 0; 119205b261ecSmrg } 119305b261ecSmrg xkbi->clearMods&= ~bit; 119405b261ecSmrg } 119505b261ecSmrg } 119605b261ecSmrg } 119705b261ecSmrg 119805b261ecSmrg if (sendEvent) { 11994642e01fSmrg DeviceIntPtr tmpdev; 12006747b715Smrg if (keyEvent) 12014642e01fSmrg tmpdev = dev; 12026747b715Smrg else 12034642e01fSmrg tmpdev = GetPairedDevice(dev); 120405b261ecSmrg 12054642e01fSmrg UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc); 12066747b715Smrg dev->public.processInputProc((InternalEvent*)event, tmpdev); 12074642e01fSmrg COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, 120805b261ecSmrg backupproc,xkbUnwrapProc); 120905b261ecSmrg } 121005b261ecSmrg else if (keyEvent) { 12116747b715Smrg FixKeyState(event, dev); 121205b261ecSmrg } 121305b261ecSmrg 121405b261ecSmrg XkbComputeDerivedState(xkbi); 12156747b715Smrg changed = XkbStateChangedFlags(&xkbi->prev_state,&xkbi->state); 121605b261ecSmrg if (genStateNotify) { 121705b261ecSmrg if (changed) { 121805b261ecSmrg xkbStateNotify sn; 121905b261ecSmrg sn.keycode= key; 12206747b715Smrg sn.eventType= event->type; 122105b261ecSmrg sn.requestMajor = sn.requestMinor = 0; 122205b261ecSmrg sn.changed= changed; 122305b261ecSmrg XkbSendStateNotify(dev,&sn); 122405b261ecSmrg } 122505b261ecSmrg xkbi->flags&= ~_XkbStateNotifyInProgress; 122605b261ecSmrg } 12276747b715Smrg changed= XkbIndicatorsToUpdate(dev,changed,FALSE); 122805b261ecSmrg if (changed) { 122905b261ecSmrg XkbEventCauseRec cause; 12306747b715Smrg XkbSetCauseKey(&cause, key, event->type); 12316747b715Smrg XkbUpdateIndicators(dev,changed,FALSE,NULL,&cause); 123205b261ecSmrg } 123305b261ecSmrg return; 123405b261ecSmrg} 123505b261ecSmrg 123605b261ecSmrgint 123705b261ecSmrgXkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches) 123805b261ecSmrg{ 123905b261ecSmrgXkbSrvInfoPtr xkbi; 124005b261ecSmrgXkbFilterPtr filter; 124105b261ecSmrgXkbAction act; 124205b261ecSmrgunsigned clear; 124305b261ecSmrg 124405b261ecSmrg if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) { 124505b261ecSmrg xkbi = pXDev->key->xkbInfo; 124605b261ecSmrg clear= (mask&(~latches)); 124705b261ecSmrg xkbi->state.latched_mods&= ~clear; 124805b261ecSmrg /* Clear any pending latch to locks. 124905b261ecSmrg */ 125005b261ecSmrg act.type = XkbSA_NoAction; 125105b261ecSmrg _XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act); 125205b261ecSmrg act.type = XkbSA_LatchMods; 125305b261ecSmrg act.mods.flags = 0; 125405b261ecSmrg act.mods.mask = mask&latches; 125505b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 125605b261ecSmrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act); 125705b261ecSmrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL); 125805b261ecSmrg return Success; 125905b261ecSmrg } 126005b261ecSmrg return BadValue; 126105b261ecSmrg} 126205b261ecSmrg 126305b261ecSmrgint 126405b261ecSmrgXkbLatchGroup(DeviceIntPtr pXDev,int group) 126505b261ecSmrg{ 126605b261ecSmrgXkbSrvInfoPtr xkbi; 126705b261ecSmrgXkbFilterPtr filter; 126805b261ecSmrgXkbAction act; 126905b261ecSmrg 127005b261ecSmrg if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) { 127105b261ecSmrg xkbi = pXDev->key->xkbInfo; 127205b261ecSmrg act.type = XkbSA_LatchGroup; 127305b261ecSmrg act.group.flags = 0; 127405b261ecSmrg XkbSASetGroup(&act.group,group); 127505b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 127605b261ecSmrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act); 127705b261ecSmrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL); 127805b261ecSmrg return Success; 127905b261ecSmrg } 128005b261ecSmrg return BadValue; 128105b261ecSmrg} 128205b261ecSmrg 128305b261ecSmrg/***====================================================================***/ 128405b261ecSmrg 128505b261ecSmrgvoid 128605b261ecSmrgXkbClearAllLatchesAndLocks( DeviceIntPtr dev, 128705b261ecSmrg XkbSrvInfoPtr xkbi, 128805b261ecSmrg Bool genEv, 128905b261ecSmrg XkbEventCausePtr cause) 129005b261ecSmrg{ 129105b261ecSmrgXkbStateRec os; 129205b261ecSmrgxkbStateNotify sn; 129305b261ecSmrg 129405b261ecSmrg sn.changed= 0; 129505b261ecSmrg os= xkbi->state; 129605b261ecSmrg if (os.latched_mods) { /* clear all latches */ 129705b261ecSmrg XkbLatchModifiers(dev,~0,0); 129805b261ecSmrg sn.changed|= XkbModifierLatchMask; 129905b261ecSmrg } 130005b261ecSmrg if (os.latched_group) { 130105b261ecSmrg XkbLatchGroup(dev,0); 130205b261ecSmrg sn.changed|= XkbGroupLatchMask; 130305b261ecSmrg } 130405b261ecSmrg if (os.locked_mods) { 130505b261ecSmrg xkbi->state.locked_mods= 0; 130605b261ecSmrg sn.changed|= XkbModifierLockMask; 130705b261ecSmrg } 130805b261ecSmrg if (os.locked_group) { 130905b261ecSmrg xkbi->state.locked_group= 0; 131005b261ecSmrg sn.changed|= XkbGroupLockMask; 131105b261ecSmrg } 131205b261ecSmrg if ( genEv && sn.changed) { 131305b261ecSmrg CARD32 changed; 131405b261ecSmrg 131505b261ecSmrg XkbComputeDerivedState(xkbi); 131605b261ecSmrg sn.keycode= cause->kc; 131705b261ecSmrg sn.eventType= cause->event; 131805b261ecSmrg sn.requestMajor= cause->mjr; 131905b261ecSmrg sn.requestMinor= cause->mnr; 132005b261ecSmrg sn.changed= XkbStateChangedFlags(&os,&xkbi->state); 132105b261ecSmrg XkbSendStateNotify(dev,&sn); 13226747b715Smrg changed= XkbIndicatorsToUpdate(dev,sn.changed,FALSE); 132305b261ecSmrg if (changed) { 13246747b715Smrg XkbUpdateIndicators(dev,changed,TRUE,NULL,cause); 132505b261ecSmrg } 132605b261ecSmrg } 132705b261ecSmrg return; 132805b261ecSmrg} 132905b261ecSmrg 13306747b715Smrg/* 13316747b715Smrg * The event is injected into the event processing, not the EQ. Thus, 13326747b715Smrg * ensure that we restore the master after the event sequence to the 13336747b715Smrg * original set of classes. Otherwise, the master remains on the XTEST 13346747b715Smrg * classes and drops events that don't fit into the XTEST layout (e.g. 13356747b715Smrg * events with more than 2 valuators). 13366747b715Smrg * 13376747b715Smrg * FIXME: EQ injection in the processing stage is not designed for, so this 13386747b715Smrg * is a rather awkward hack. The event list returned by GetPointerEvents() 13396747b715Smrg * and friends is always prefixed with a DCE if the last _posted_ device was 13406747b715Smrg * different. For normal events, this sequence then resets the master during 13416747b715Smrg * the processing stage. Since we inject the PointerKey events in the 13426747b715Smrg * processing stage though, we need to manually reset to restore the 13436747b715Smrg * previous order, because the events already in the EQ must be sent for the 13446747b715Smrg * right device. 13456747b715Smrg * So we post-fix the event list we get from GPE with a DCE back to the 13466747b715Smrg * previous slave device. 13476747b715Smrg * 13486747b715Smrg * First one on drinking island wins! 13496747b715Smrg */ 13506747b715Smrgstatic void 13519ace9065SmrgInjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, ValuatorMask *mask) 13526747b715Smrg{ 13536747b715Smrg ScreenPtr pScreen; 13546747b715Smrg EventListPtr events; 13556747b715Smrg int nevents, i; 13566747b715Smrg DeviceIntPtr ptr, mpointer, lastSlave = NULL; 13576747b715Smrg Bool saveWait; 13586747b715Smrg 13596747b715Smrg if (IsMaster(dev)) { 13606747b715Smrg mpointer = GetMaster(dev, MASTER_POINTER); 13616747b715Smrg lastSlave = mpointer->u.lastSlave; 13626747b715Smrg ptr = GetXTestDevice(mpointer); 13636747b715Smrg } else if (!dev->u.master) 13646747b715Smrg ptr = dev; 13656747b715Smrg else 13666747b715Smrg return; 13676747b715Smrg 13686747b715Smrg 13696747b715Smrg events = InitEventList(GetMaximumEventsNum() + 1); 13706747b715Smrg OsBlockSignals(); 13716747b715Smrg pScreen = miPointerGetScreen(ptr); 13726747b715Smrg saveWait = miPointerSetWaitForUpdate(pScreen, FALSE); 13739ace9065Smrg nevents = GetPointerEvents(events, ptr, type, button, flags, mask); 13746747b715Smrg if (IsMaster(dev) && (lastSlave && lastSlave != ptr)) 13756747b715Smrg UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT, &nevents); 13766747b715Smrg miPointerSetWaitForUpdate(pScreen, saveWait); 13776747b715Smrg OsReleaseSignals(); 13786747b715Smrg 13796747b715Smrg for (i = 0; i < nevents; i++) 13806747b715Smrg mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL); 13816747b715Smrg 13826747b715Smrg FreeEventList(events, GetMaximumEventsNum()); 13836747b715Smrg 13846747b715Smrg} 13856747b715Smrg 13866747b715Smrgstatic void 13876747b715SmrgXkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y) 13886747b715Smrg{ 13899ace9065Smrg ValuatorMask mask; 13906747b715Smrg int gpe_flags = 0; 13916747b715Smrg 13926747b715Smrg /* ignore attached SDs */ 13936747b715Smrg if (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) != NULL) 13946747b715Smrg return; 13956747b715Smrg 13966747b715Smrg if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY) 13976747b715Smrg gpe_flags = POINTER_ABSOLUTE; 13986747b715Smrg else 13996747b715Smrg gpe_flags = POINTER_RELATIVE; 14006747b715Smrg 14019ace9065Smrg valuator_mask_set_range(&mask, 0, 2, (int[]){x, y}); 14029ace9065Smrg 14039ace9065Smrg InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, &mask); 14046747b715Smrg} 14056747b715Smrg 14066747b715Smrgvoid 14076747b715SmrgXkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button) 14086747b715Smrg{ 14096747b715Smrg DeviceIntPtr ptr; 14106747b715Smrg int down; 14116747b715Smrg 14126747b715Smrg /* If dev is a slave device, and the SD is attached, do nothing. If we'd 14136747b715Smrg * post through the attached master pointer we'd get duplicate events. 14146747b715Smrg * 14156747b715Smrg * if dev is a master keyboard, post through the XTEST device 14166747b715Smrg * 14176747b715Smrg * if dev is a floating slave, post through the device itself. 14186747b715Smrg */ 14196747b715Smrg 14206747b715Smrg if (IsMaster(dev)) { 14216747b715Smrg DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER); 14226747b715Smrg ptr = GetXTestDevice(mpointer); 14236747b715Smrg } else if (!dev->u.master) 14246747b715Smrg ptr = dev; 14256747b715Smrg else 14266747b715Smrg return; 14276747b715Smrg 14286747b715Smrg down = button_is_down(ptr, button, BUTTON_PROCESSED); 14296747b715Smrg if (press == down) 14306747b715Smrg return; 14316747b715Smrg 14326747b715Smrg InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease, 14339ace9065Smrg button, 0, NULL); 14346747b715Smrg} 1435