xkbActions.c revision 4642e01f
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#define NEED_EVENTS 1 3405b261ecSmrg#include <X11/X.h> 3505b261ecSmrg#include <X11/Xproto.h> 3605b261ecSmrg#include <X11/keysym.h> 3705b261ecSmrg#include "misc.h" 3805b261ecSmrg#include "inputstr.h" 3905b261ecSmrg#include "exevents.h" 4005b261ecSmrg#include <xkbsrv.h> 4105b261ecSmrg#include "xkb.h" 4205b261ecSmrg#include <ctype.h> 4305b261ecSmrg#define EXTENSION_EVENT_BASE 64 4405b261ecSmrg 454642e01fSmrgstatic int xkbDevicePrivateKeyIndex; 464642e01fSmrgDevPrivateKey xkbDevicePrivateKey = &xkbDevicePrivateKeyIndex; 4705b261ecSmrg 4805b261ecSmrgvoid 4905b261ecSmrgxkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, 5005b261ecSmrg pointer data) 5105b261ecSmrg{ 5205b261ecSmrg xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device); 5305b261ecSmrg ProcessInputProc backupproc; 5405b261ecSmrg if(xkbPrivPtr->unwrapProc) 5505b261ecSmrg xkbPrivPtr->unwrapProc = NULL; 5605b261ecSmrg 5705b261ecSmrg UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc); 5805b261ecSmrg proc(device,data); 5905b261ecSmrg COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, 6005b261ecSmrg backupproc,xkbUnwrapProc); 6105b261ecSmrg} 6205b261ecSmrg 6305b261ecSmrg 6405b261ecSmrgvoid 6505b261ecSmrgXkbSetExtension(DeviceIntPtr device, ProcessInputProc proc) 6605b261ecSmrg{ 6705b261ecSmrg xkbDeviceInfoPtr xkbPrivPtr; 6805b261ecSmrg 6905b261ecSmrg xkbPrivPtr = (xkbDeviceInfoPtr) xcalloc(1, sizeof(xkbDeviceInfoRec)); 7005b261ecSmrg if (!xkbPrivPtr) 7105b261ecSmrg return; 7205b261ecSmrg xkbPrivPtr->unwrapProc = NULL; 7305b261ecSmrg 744642e01fSmrg dixSetPrivate(&device->devPrivates, xkbDevicePrivateKey, xkbPrivPtr); 7505b261ecSmrg WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc); 7605b261ecSmrg} 7705b261ecSmrg 7805b261ecSmrgextern void ProcessOtherEvent( 7905b261ecSmrg xEvent * /* xE */, 8005b261ecSmrg DeviceIntPtr /* dev */, 8105b261ecSmrg int /* count */ 8205b261ecSmrg); 8305b261ecSmrg 8405b261ecSmrg/***====================================================================***/ 8505b261ecSmrg 8605b261ecSmrgstatic XkbAction 8705b261ecSmrg_FixUpAction(XkbDescPtr xkb,XkbAction *act) 8805b261ecSmrg{ 8905b261ecSmrgstatic XkbAction fake; 9005b261ecSmrg 9105b261ecSmrg if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) { 9205b261ecSmrg fake.type = XkbSA_NoAction; 9305b261ecSmrg return fake; 9405b261ecSmrg } 9505b261ecSmrg if (XkbDisableLockActions) { 9605b261ecSmrg switch (act->type) { 9705b261ecSmrg case XkbSA_LockMods: 9805b261ecSmrg fake.mods.type = XkbSA_SetMods; 9905b261ecSmrg fake.mods.flags = 0; 10005b261ecSmrg fake.mods.mask = act->mods.mask; 10105b261ecSmrg return fake; 10205b261ecSmrg case XkbSA_LatchMods: 10305b261ecSmrg fake.mods.type = XkbSA_SetMods; 10405b261ecSmrg fake.mods.flags = 0; 10505b261ecSmrg fake.mods.mask = act->mods.mask; 10605b261ecSmrg return fake; 10705b261ecSmrg case XkbSA_ISOLock: 10805b261ecSmrg if (act->iso.flags&XkbSA_ISODfltIsGroup) { 10905b261ecSmrg fake.group.type = XkbSA_SetGroup; 11005b261ecSmrg fake.group.flags = act->iso.flags&XkbSA_GroupAbsolute; 11105b261ecSmrg XkbSASetGroup(&fake.group,XkbSAGroup(&act->iso)); 11205b261ecSmrg } 11305b261ecSmrg else { 11405b261ecSmrg fake.mods.type = XkbSA_SetMods; 11505b261ecSmrg fake.mods.flags = 0; 11605b261ecSmrg fake.mods.mask = act->iso.mask; 11705b261ecSmrg } 11805b261ecSmrg return fake; 11905b261ecSmrg case XkbSA_LockGroup: 12005b261ecSmrg case XkbSA_LatchGroup: 12105b261ecSmrg /* We want everything from the latch/lock action except the 12205b261ecSmrg * type should be changed to set. 12305b261ecSmrg */ 12405b261ecSmrg fake = *act; 12505b261ecSmrg fake.group.type = XkbSA_SetGroup; 12605b261ecSmrg return fake; 12705b261ecSmrg } 12805b261ecSmrg } 12905b261ecSmrg else 13005b261ecSmrg if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) { 13105b261ecSmrg if (act->any.type==XkbSA_SetMods) { 13205b261ecSmrg fake.mods.type = XkbSA_LatchMods; 13305b261ecSmrg fake.mods.mask = act->mods.mask; 13405b261ecSmrg if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask)) 13505b261ecSmrg fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock; 13605b261ecSmrg else fake.mods.flags= XkbSA_ClearLocks; 13705b261ecSmrg return fake; 13805b261ecSmrg } 13905b261ecSmrg if (act->any.type==XkbSA_SetGroup) { 14005b261ecSmrg fake.group.type = XkbSA_LatchGroup; 14105b261ecSmrg if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask)) 14205b261ecSmrg fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock; 14305b261ecSmrg else fake.group.flags= XkbSA_ClearLocks; 14405b261ecSmrg XkbSASetGroup(&fake.group,XkbSAGroup(&act->group)); 14505b261ecSmrg return fake; 14605b261ecSmrg } 14705b261ecSmrg } 14805b261ecSmrg return *act; 14905b261ecSmrg} 15005b261ecSmrg 15105b261ecSmrgstatic XkbAction 15205b261ecSmrgXkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key) 15305b261ecSmrg{ 15405b261ecSmrgint effectiveGroup; 15505b261ecSmrgint col; 15605b261ecSmrgXkbDescPtr xkb; 15705b261ecSmrgXkbKeyTypePtr type; 15805b261ecSmrgXkbAction * pActs; 15905b261ecSmrgstatic XkbAction fake; 16005b261ecSmrg 16105b261ecSmrg xkb= xkbi->desc; 16205b261ecSmrg if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) { 16305b261ecSmrg fake.type = XkbSA_NoAction; 16405b261ecSmrg return fake; 16505b261ecSmrg } 16605b261ecSmrg pActs= XkbKeyActionsPtr(xkb,key); 16705b261ecSmrg col= 0; 16805b261ecSmrg effectiveGroup= xkbState->group; 16905b261ecSmrg if (effectiveGroup!=XkbGroup1Index) { 17005b261ecSmrg if (XkbKeyNumGroups(xkb,key)>(unsigned)1) { 17105b261ecSmrg if (effectiveGroup>=XkbKeyNumGroups(xkb,key)) { 17205b261ecSmrg unsigned gi= XkbKeyGroupInfo(xkb,key); 17305b261ecSmrg switch (XkbOutOfRangeGroupAction(gi)) { 17405b261ecSmrg default: 17505b261ecSmrg case XkbWrapIntoRange: 17605b261ecSmrg effectiveGroup %= XkbKeyNumGroups(xkb,key); 17705b261ecSmrg break; 17805b261ecSmrg case XkbClampIntoRange: 17905b261ecSmrg effectiveGroup = XkbKeyNumGroups(xkb,key)-1; 18005b261ecSmrg break; 18105b261ecSmrg case XkbRedirectIntoRange: 18205b261ecSmrg effectiveGroup= XkbOutOfRangeGroupInfo(gi); 18305b261ecSmrg if (effectiveGroup>=XkbKeyNumGroups(xkb,key)) 18405b261ecSmrg effectiveGroup= 0; 18505b261ecSmrg break; 18605b261ecSmrg } 18705b261ecSmrg } 18805b261ecSmrg } 18905b261ecSmrg else effectiveGroup= XkbGroup1Index; 19005b261ecSmrg col+= (effectiveGroup*XkbKeyGroupsWidth(xkb,key)); 19105b261ecSmrg } 19205b261ecSmrg type= XkbKeyKeyType(xkb,key,effectiveGroup); 19305b261ecSmrg if (type->map!=NULL) { 19405b261ecSmrg register unsigned i,mods; 19505b261ecSmrg register XkbKTMapEntryPtr entry; 19605b261ecSmrg mods= xkbState->mods&type->mods.mask; 19705b261ecSmrg for (entry= type->map,i=0;i<type->map_count;i++,entry++) { 19805b261ecSmrg if ((entry->active)&&(entry->mods.mask==mods)) { 19905b261ecSmrg col+= entry->level; 20005b261ecSmrg break; 20105b261ecSmrg } 20205b261ecSmrg } 20305b261ecSmrg } 20405b261ecSmrg if (pActs[col].any.type==XkbSA_NoAction) 20505b261ecSmrg return pActs[col]; 20605b261ecSmrg fake= _FixUpAction(xkb,&pActs[col]); 20705b261ecSmrg return fake; 20805b261ecSmrg} 20905b261ecSmrg 21005b261ecSmrgstatic XkbAction 21105b261ecSmrgXkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button) 21205b261ecSmrg{ 21305b261ecSmrgXkbAction fake; 21405b261ecSmrg if ((dev->button)&&(dev->button->xkb_acts)) { 21505b261ecSmrg if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) { 21605b261ecSmrg fake= _FixUpAction(kbd->key->xkbInfo->desc, 21705b261ecSmrg &dev->button->xkb_acts[button-1]); 21805b261ecSmrg return fake; 21905b261ecSmrg } 22005b261ecSmrg } 22105b261ecSmrg fake.any.type= XkbSA_NoAction; 22205b261ecSmrg return fake; 22305b261ecSmrg} 22405b261ecSmrg 22505b261ecSmrg/***====================================================================***/ 22605b261ecSmrg 22705b261ecSmrg#define SYNTHETIC_KEYCODE 1 22805b261ecSmrg#define BTN_ACT_FLAG 0x100 22905b261ecSmrg 23005b261ecSmrgstatic int 23105b261ecSmrg_XkbFilterSetState( XkbSrvInfoPtr xkbi, 23205b261ecSmrg XkbFilterPtr filter, 23305b261ecSmrg unsigned keycode, 23405b261ecSmrg XkbAction *pAction) 23505b261ecSmrg{ 23605b261ecSmrg if (filter->keycode==0) { /* initial press */ 23705b261ecSmrg filter->keycode = keycode; 23805b261ecSmrg filter->active = 1; 23905b261ecSmrg filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0); 24005b261ecSmrg filter->priv = 0; 24105b261ecSmrg filter->filter = _XkbFilterSetState; 24205b261ecSmrg if (pAction->type==XkbSA_SetMods) { 24305b261ecSmrg filter->upAction = *pAction; 24405b261ecSmrg xkbi->setMods= pAction->mods.mask; 24505b261ecSmrg } 24605b261ecSmrg else { 24705b261ecSmrg xkbi->groupChange = XkbSAGroup(&pAction->group); 24805b261ecSmrg if (pAction->group.flags&XkbSA_GroupAbsolute) 24905b261ecSmrg xkbi->groupChange-= xkbi->state.base_group; 25005b261ecSmrg filter->upAction= *pAction; 25105b261ecSmrg XkbSASetGroup(&filter->upAction.group,xkbi->groupChange); 25205b261ecSmrg } 25305b261ecSmrg } 25405b261ecSmrg else if (filter->keycode==keycode) { 25505b261ecSmrg if (filter->upAction.type==XkbSA_SetMods) { 25605b261ecSmrg xkbi->clearMods = filter->upAction.mods.mask; 25705b261ecSmrg if (filter->upAction.mods.flags&XkbSA_ClearLocks) { 25805b261ecSmrg xkbi->state.locked_mods&= ~filter->upAction.mods.mask; 25905b261ecSmrg } 26005b261ecSmrg } 26105b261ecSmrg else { 26205b261ecSmrg if (filter->upAction.group.flags&XkbSA_ClearLocks) { 26305b261ecSmrg xkbi->state.locked_group = 0; 26405b261ecSmrg } 26505b261ecSmrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); 26605b261ecSmrg } 26705b261ecSmrg filter->active = 0; 26805b261ecSmrg } 26905b261ecSmrg else { 27005b261ecSmrg filter->upAction.mods.flags&= ~XkbSA_ClearLocks; 27105b261ecSmrg filter->filterOthers = 0; 27205b261ecSmrg } 27305b261ecSmrg return 1; 27405b261ecSmrg} 27505b261ecSmrg 27605b261ecSmrg#define LATCH_KEY_DOWN 1 27705b261ecSmrg#define LATCH_PENDING 2 27805b261ecSmrg#define NO_LATCH 3 27905b261ecSmrg 28005b261ecSmrgstatic int 28105b261ecSmrg_XkbFilterLatchState( XkbSrvInfoPtr xkbi, 28205b261ecSmrg XkbFilterPtr filter, 28305b261ecSmrg unsigned keycode, 28405b261ecSmrg XkbAction * pAction) 28505b261ecSmrg{ 28605b261ecSmrg 28705b261ecSmrg if (filter->keycode==0) { /* initial press */ 28805b261ecSmrg filter->keycode = keycode; 28905b261ecSmrg filter->active = 1; 29005b261ecSmrg filter->filterOthers = 1; 29105b261ecSmrg filter->priv = LATCH_KEY_DOWN; 29205b261ecSmrg filter->filter = _XkbFilterLatchState; 29305b261ecSmrg if (pAction->type==XkbSA_LatchMods) { 29405b261ecSmrg filter->upAction = *pAction; 29505b261ecSmrg xkbi->setMods = pAction->mods.mask; 29605b261ecSmrg } 29705b261ecSmrg else { 29805b261ecSmrg xkbi->groupChange = XkbSAGroup(&pAction->group); 29905b261ecSmrg if (pAction->group.flags&XkbSA_GroupAbsolute) 30005b261ecSmrg xkbi->groupChange-= xkbi->state.base_group; 30105b261ecSmrg filter->upAction= *pAction; 30205b261ecSmrg XkbSASetGroup(&filter->upAction.group,xkbi->groupChange); 30305b261ecSmrg } 30405b261ecSmrg } 30505b261ecSmrg else if ( pAction && (filter->priv==LATCH_PENDING) ) { 30605b261ecSmrg if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) { 30705b261ecSmrg filter->active = 0; 30805b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) 30905b261ecSmrg xkbi->state.latched_mods&= ~filter->upAction.mods.mask; 31005b261ecSmrg else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group); 31105b261ecSmrg } 31205b261ecSmrg else if ((pAction->type==filter->upAction.type)&& 31305b261ecSmrg (pAction->mods.flags==filter->upAction.mods.flags)&& 31405b261ecSmrg (pAction->mods.mask==filter->upAction.mods.mask)) { 31505b261ecSmrg if (filter->upAction.mods.flags&XkbSA_LatchToLock) { 31605b261ecSmrg XkbControlsPtr ctrls= xkbi->desc->ctrls; 31705b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) 31805b261ecSmrg pAction->mods.type= XkbSA_LockMods; 31905b261ecSmrg else pAction->group.type= XkbSA_LockGroup; 32005b261ecSmrg if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&& 32105b261ecSmrg (ctrls->enabled_ctrls&XkbStickyKeysMask)) { 32205b261ecSmrg XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK, 32305b261ecSmrg XkbStickyKeysMask); 32405b261ecSmrg } 32505b261ecSmrg } 32605b261ecSmrg else { 32705b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) 32805b261ecSmrg pAction->mods.type= XkbSA_SetMods; 32905b261ecSmrg else pAction->group.type= XkbSA_SetGroup; 33005b261ecSmrg } 33105b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) 33205b261ecSmrg xkbi->state.latched_mods&= ~filter->upAction.mods.mask; 33305b261ecSmrg else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group); 33405b261ecSmrg filter->active = 0; 33505b261ecSmrg } 33605b261ecSmrg } 33705b261ecSmrg else if (filter->keycode==keycode) { /* release */ 33805b261ecSmrg XkbControlsPtr ctrls= xkbi->desc->ctrls; 33905b261ecSmrg int needBeep; 34005b261ecSmrg int beepType= _BEEP_NONE; 34105b261ecSmrg 34205b261ecSmrg needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&& 34305b261ecSmrg XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)); 34405b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) { 34505b261ecSmrg xkbi->clearMods = filter->upAction.mods.mask; 34605b261ecSmrg if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&& 34705b261ecSmrg (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) { 34805b261ecSmrg xkbi->state.locked_mods&= ~xkbi->clearMods; 34905b261ecSmrg filter->priv= NO_LATCH; 35005b261ecSmrg beepType= _BEEP_STICKY_UNLOCK; 35105b261ecSmrg } 35205b261ecSmrg } 35305b261ecSmrg else { 35405b261ecSmrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); 35505b261ecSmrg if ((filter->upAction.group.flags&XkbSA_ClearLocks)&& 35605b261ecSmrg (xkbi->state.locked_group)) { 35705b261ecSmrg xkbi->state.locked_group = 0; 35805b261ecSmrg filter->priv = NO_LATCH; 35905b261ecSmrg beepType= _BEEP_STICKY_UNLOCK; 36005b261ecSmrg } 36105b261ecSmrg } 36205b261ecSmrg if (filter->priv==NO_LATCH) { 36305b261ecSmrg filter->active= 0; 36405b261ecSmrg } 36505b261ecSmrg else { 36605b261ecSmrg filter->priv= LATCH_PENDING; 36705b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) { 36805b261ecSmrg xkbi->state.latched_mods |= filter->upAction.mods.mask; 36905b261ecSmrg needBeep = xkbi->state.latched_mods ? needBeep : 0; 37005b261ecSmrg xkbi->state.latched_mods |= filter->upAction.mods.mask; 37105b261ecSmrg } 37205b261ecSmrg else { 37305b261ecSmrg xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group); 37405b261ecSmrg } 37505b261ecSmrg if (needBeep && (beepType==_BEEP_NONE)) 37605b261ecSmrg beepType= _BEEP_STICKY_LATCH; 37705b261ecSmrg } 37805b261ecSmrg if (needBeep && (beepType!=_BEEP_NONE)) 37905b261ecSmrg XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask); 38005b261ecSmrg } 38105b261ecSmrg else if (filter->priv==LATCH_KEY_DOWN) { 38205b261ecSmrg filter->priv= NO_LATCH; 38305b261ecSmrg filter->filterOthers = 0; 38405b261ecSmrg } 38505b261ecSmrg return 1; 38605b261ecSmrg} 38705b261ecSmrg 38805b261ecSmrgstatic int 38905b261ecSmrg_XkbFilterLockState( XkbSrvInfoPtr xkbi, 39005b261ecSmrg XkbFilterPtr filter, 39105b261ecSmrg unsigned keycode, 39205b261ecSmrg XkbAction * pAction) 39305b261ecSmrg{ 39405b261ecSmrg if (pAction&&(pAction->type==XkbSA_LockGroup)) { 39505b261ecSmrg if (pAction->group.flags&XkbSA_GroupAbsolute) 39605b261ecSmrg xkbi->state.locked_group= XkbSAGroup(&pAction->group); 39705b261ecSmrg else xkbi->state.locked_group+= XkbSAGroup(&pAction->group); 39805b261ecSmrg return 1; 39905b261ecSmrg } 40005b261ecSmrg if (filter->keycode==0) { /* initial press */ 40105b261ecSmrg filter->keycode = keycode; 40205b261ecSmrg filter->active = 1; 40305b261ecSmrg filter->filterOthers = 0; 40405b261ecSmrg filter->priv = 0; 40505b261ecSmrg filter->filter = _XkbFilterLockState; 40605b261ecSmrg filter->upAction = *pAction; 40705b261ecSmrg xkbi->state.locked_mods^= pAction->mods.mask; 40805b261ecSmrg xkbi->setMods = pAction->mods.mask; 40905b261ecSmrg } 41005b261ecSmrg else if (filter->keycode==keycode) { 41105b261ecSmrg filter->active = 0; 41205b261ecSmrg xkbi->clearMods = filter->upAction.mods.mask; 41305b261ecSmrg } 41405b261ecSmrg return 1; 41505b261ecSmrg} 41605b261ecSmrg 41705b261ecSmrg#define ISO_KEY_DOWN 0 41805b261ecSmrg#define NO_ISO_LOCK 1 41905b261ecSmrg 42005b261ecSmrgstatic int 42105b261ecSmrg_XkbFilterISOLock( XkbSrvInfoPtr xkbi, 42205b261ecSmrg XkbFilterPtr filter, 42305b261ecSmrg unsigned keycode, 42405b261ecSmrg XkbAction * pAction) 42505b261ecSmrg{ 42605b261ecSmrg 42705b261ecSmrg if (filter->keycode==0) { /* initial press */ 42805b261ecSmrg CARD8 flags= pAction->iso.flags; 42905b261ecSmrg 43005b261ecSmrg filter->keycode = keycode; 43105b261ecSmrg filter->active = 1; 43205b261ecSmrg filter->filterOthers = 1; 43305b261ecSmrg filter->priv = ISO_KEY_DOWN; 43405b261ecSmrg filter->upAction = *pAction; 43505b261ecSmrg filter->filter = _XkbFilterISOLock; 43605b261ecSmrg if (flags&XkbSA_ISODfltIsGroup) { 43705b261ecSmrg xkbi->groupChange = XkbSAGroup(&pAction->iso); 43805b261ecSmrg xkbi->setMods = 0; 43905b261ecSmrg } 44005b261ecSmrg else { 44105b261ecSmrg xkbi->setMods = pAction->iso.mask; 44205b261ecSmrg xkbi->groupChange = 0; 44305b261ecSmrg } 44405b261ecSmrg if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) { 44505b261ecSmrg filter->priv= NO_ISO_LOCK; 44605b261ecSmrg xkbi->state.locked_mods^= xkbi->state.base_mods; 44705b261ecSmrg } 44805b261ecSmrg if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) { 44905b261ecSmrg/* 6/22/93 (ef) -- lock groups if group key is down first */ 45005b261ecSmrg } 45105b261ecSmrg if (!(flags&XkbSA_ISONoAffectPtr)) { 45205b261ecSmrg/* 6/22/93 (ef) -- lock mouse buttons if they're down */ 45305b261ecSmrg } 45405b261ecSmrg } 45505b261ecSmrg else if (filter->keycode==keycode) { 45605b261ecSmrg CARD8 flags= filter->upAction.iso.flags; 45705b261ecSmrg 45805b261ecSmrg if (flags&XkbSA_ISODfltIsGroup) { 45905b261ecSmrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso); 46005b261ecSmrg xkbi->clearMods = 0; 46105b261ecSmrg if (filter->priv==ISO_KEY_DOWN) 46205b261ecSmrg xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso); 46305b261ecSmrg } 46405b261ecSmrg else { 46505b261ecSmrg xkbi->clearMods= filter->upAction.iso.mask; 46605b261ecSmrg xkbi->groupChange= 0; 46705b261ecSmrg if (filter->priv==ISO_KEY_DOWN) 46805b261ecSmrg xkbi->state.locked_mods^= filter->upAction.iso.mask; 46905b261ecSmrg } 47005b261ecSmrg filter->active = 0; 47105b261ecSmrg } 47205b261ecSmrg else if (pAction) { 47305b261ecSmrg CARD8 flags= filter->upAction.iso.flags; 47405b261ecSmrg 47505b261ecSmrg switch (pAction->type) { 47605b261ecSmrg case XkbSA_SetMods: case XkbSA_LatchMods: 47705b261ecSmrg if (!(flags&XkbSA_ISONoAffectMods)) { 47805b261ecSmrg pAction->type= XkbSA_LockMods; 47905b261ecSmrg filter->priv= NO_ISO_LOCK; 48005b261ecSmrg } 48105b261ecSmrg break; 48205b261ecSmrg case XkbSA_SetGroup: case XkbSA_LatchGroup: 48305b261ecSmrg if (!(flags&XkbSA_ISONoAffectGroup)) { 48405b261ecSmrg pAction->type= XkbSA_LockGroup; 48505b261ecSmrg filter->priv= NO_ISO_LOCK; 48605b261ecSmrg } 48705b261ecSmrg break; 48805b261ecSmrg case XkbSA_PtrBtn: 48905b261ecSmrg if (!(flags&XkbSA_ISONoAffectPtr)) { 49005b261ecSmrg pAction->type= XkbSA_LockPtrBtn; 49105b261ecSmrg filter->priv= NO_ISO_LOCK; 49205b261ecSmrg } 49305b261ecSmrg break; 49405b261ecSmrg case XkbSA_SetControls: 49505b261ecSmrg if (!(flags&XkbSA_ISONoAffectCtrls)) { 49605b261ecSmrg pAction->type= XkbSA_LockControls; 49705b261ecSmrg filter->priv= NO_ISO_LOCK; 49805b261ecSmrg } 49905b261ecSmrg break; 50005b261ecSmrg } 50105b261ecSmrg } 50205b261ecSmrg return 1; 50305b261ecSmrg} 50405b261ecSmrg 50505b261ecSmrg 50605b261ecSmrgstatic CARD32 50705b261ecSmrg_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg) 50805b261ecSmrg{ 50905b261ecSmrgXkbSrvInfoPtr xkbi= (XkbSrvInfoPtr)arg; 51005b261ecSmrgXkbControlsPtr ctrls= xkbi->desc->ctrls; 51105b261ecSmrgint dx,dy; 51205b261ecSmrg 51305b261ecSmrg if (xkbi->mouseKey==0) 51405b261ecSmrg return 0; 51505b261ecSmrg 51605b261ecSmrg if (xkbi->mouseKeysAccel) { 51705b261ecSmrg if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) { 51805b261ecSmrg double step; 51905b261ecSmrg xkbi->mouseKeysCounter++; 52005b261ecSmrg step= xkbi->mouseKeysCurveFactor* 52105b261ecSmrg pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve); 52205b261ecSmrg if (xkbi->mouseKeysDX<0) 52305b261ecSmrg dx= floor( ((double)xkbi->mouseKeysDX)*step ); 52405b261ecSmrg else dx= ceil( ((double)xkbi->mouseKeysDX)*step ); 52505b261ecSmrg if (xkbi->mouseKeysDY<0) 52605b261ecSmrg dy= floor( ((double)xkbi->mouseKeysDY)*step ); 52705b261ecSmrg else dy= ceil( ((double)xkbi->mouseKeysDY)*step ); 52805b261ecSmrg } 52905b261ecSmrg else { 53005b261ecSmrg dx= xkbi->mouseKeysDX*ctrls->mk_max_speed; 53105b261ecSmrg dy= xkbi->mouseKeysDY*ctrls->mk_max_speed; 53205b261ecSmrg } 53305b261ecSmrg if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX) 53405b261ecSmrg dx= xkbi->mouseKeysDX; 53505b261ecSmrg if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY) 53605b261ecSmrg dy= xkbi->mouseKeysDY; 53705b261ecSmrg } 53805b261ecSmrg else { 53905b261ecSmrg dx= xkbi->mouseKeysDX; 54005b261ecSmrg dy= xkbi->mouseKeysDY; 54105b261ecSmrg } 54205b261ecSmrg XkbDDXFakePointerMotion(xkbi->mouseKeysFlags,dx,dy); 54305b261ecSmrg return xkbi->desc->ctrls->mk_interval; 54405b261ecSmrg} 54505b261ecSmrg 54605b261ecSmrgstatic int 54705b261ecSmrg_XkbFilterPointerMove( XkbSrvInfoPtr xkbi, 54805b261ecSmrg XkbFilterPtr filter, 54905b261ecSmrg unsigned keycode, 55005b261ecSmrg XkbAction * pAction) 55105b261ecSmrg{ 55205b261ecSmrgint x,y; 55305b261ecSmrgBool accel; 55405b261ecSmrg 55505b261ecSmrg if (xkbi->device == inputInfo.keyboard) 55605b261ecSmrg return 0; 55705b261ecSmrg 55805b261ecSmrg if (filter->keycode==0) { /* initial press */ 55905b261ecSmrg filter->keycode = keycode; 56005b261ecSmrg filter->active = 1; 56105b261ecSmrg filter->filterOthers = 0; 56205b261ecSmrg filter->priv=0; 56305b261ecSmrg filter->filter = _XkbFilterPointerMove; 56405b261ecSmrg filter->upAction= *pAction; 56505b261ecSmrg xkbi->mouseKeysCounter= 0; 56605b261ecSmrg xkbi->mouseKey= keycode; 56705b261ecSmrg accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0); 56805b261ecSmrg x= XkbPtrActionX(&pAction->ptr); 56905b261ecSmrg y= XkbPtrActionY(&pAction->ptr); 57005b261ecSmrg XkbDDXFakePointerMotion(pAction->ptr.flags,x,y); 57105b261ecSmrg AccessXCancelRepeatKey(xkbi,keycode); 57205b261ecSmrg xkbi->mouseKeysAccel= accel&& 57305b261ecSmrg (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask); 57405b261ecSmrg xkbi->mouseKeysFlags= pAction->ptr.flags; 57505b261ecSmrg xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr); 57605b261ecSmrg xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr); 57705b261ecSmrg xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 57805b261ecSmrg xkbi->desc->ctrls->mk_delay, 57905b261ecSmrg _XkbPtrAccelExpire,(pointer)xkbi); 58005b261ecSmrg } 58105b261ecSmrg else if (filter->keycode==keycode) { 58205b261ecSmrg filter->active = 0; 58305b261ecSmrg if (xkbi->mouseKey==keycode) { 58405b261ecSmrg xkbi->mouseKey= 0; 58505b261ecSmrg xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0, 58605b261ecSmrg NULL, NULL); 58705b261ecSmrg } 58805b261ecSmrg } 58905b261ecSmrg return 0; 59005b261ecSmrg} 59105b261ecSmrg 59205b261ecSmrgstatic int 59305b261ecSmrg_XkbFilterPointerBtn( XkbSrvInfoPtr xkbi, 59405b261ecSmrg XkbFilterPtr filter, 59505b261ecSmrg unsigned keycode, 59605b261ecSmrg XkbAction * pAction) 59705b261ecSmrg{ 59805b261ecSmrg if (filter->keycode==0) { /* initial press */ 59905b261ecSmrg int button= pAction->btn.button; 60005b261ecSmrg 60105b261ecSmrg if (button==XkbSA_UseDfltButton) 60205b261ecSmrg button = xkbi->desc->ctrls->mk_dflt_btn; 60305b261ecSmrg 60405b261ecSmrg filter->keycode = keycode; 60505b261ecSmrg filter->active = 1; 60605b261ecSmrg filter->filterOthers = 0; 60705b261ecSmrg filter->priv=0; 60805b261ecSmrg filter->filter = _XkbFilterPointerBtn; 60905b261ecSmrg filter->upAction= *pAction; 61005b261ecSmrg filter->upAction.btn.button= button; 61105b261ecSmrg switch (pAction->type) { 61205b261ecSmrg case XkbSA_LockPtrBtn: 61305b261ecSmrg if (((xkbi->lockedPtrButtons&(1<<button))==0)&& 61405b261ecSmrg ((pAction->btn.flags&XkbSA_LockNoLock)==0)) { 61505b261ecSmrg xkbi->lockedPtrButtons|= (1<<button); 61605b261ecSmrg AccessXCancelRepeatKey(xkbi,keycode); 6174642e01fSmrg XkbDDXFakeDeviceButton(xkbi->device, 1, button); 61805b261ecSmrg filter->upAction.type= XkbSA_NoAction; 61905b261ecSmrg } 62005b261ecSmrg break; 62105b261ecSmrg case XkbSA_PtrBtn: 62205b261ecSmrg { 62305b261ecSmrg register int i,nClicks; 62405b261ecSmrg AccessXCancelRepeatKey(xkbi,keycode); 62505b261ecSmrg if (pAction->btn.count>0) { 62605b261ecSmrg nClicks= pAction->btn.count; 62705b261ecSmrg for (i=0;i<nClicks;i++) { 6284642e01fSmrg XkbDDXFakeDeviceButton(xkbi->device, 1, button); 6294642e01fSmrg XkbDDXFakeDeviceButton(xkbi->device, 0, button); 63005b261ecSmrg } 63105b261ecSmrg filter->upAction.type= XkbSA_NoAction; 63205b261ecSmrg } 6334642e01fSmrg else XkbDDXFakeDeviceButton(xkbi->device, 1, button); 63405b261ecSmrg } 63505b261ecSmrg break; 63605b261ecSmrg case XkbSA_SetPtrDflt: 63705b261ecSmrg { 63805b261ecSmrg XkbControlsPtr ctrls= xkbi->desc->ctrls; 63905b261ecSmrg XkbControlsRec old; 64005b261ecSmrg xkbControlsNotify cn; 64105b261ecSmrg 64205b261ecSmrg old= *ctrls; 64305b261ecSmrg AccessXCancelRepeatKey(xkbi,keycode); 64405b261ecSmrg switch (pAction->dflt.affect) { 64505b261ecSmrg case XkbSA_AffectDfltBtn: 64605b261ecSmrg if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute) 64705b261ecSmrg ctrls->mk_dflt_btn= 64805b261ecSmrg XkbSAPtrDfltValue(&pAction->dflt); 64905b261ecSmrg else { 65005b261ecSmrg ctrls->mk_dflt_btn+= 65105b261ecSmrg XkbSAPtrDfltValue(&pAction->dflt); 65205b261ecSmrg if (ctrls->mk_dflt_btn>5) 65305b261ecSmrg ctrls->mk_dflt_btn= 5; 65405b261ecSmrg else if (ctrls->mk_dflt_btn<1) 65505b261ecSmrg ctrls->mk_dflt_btn= 1; 65605b261ecSmrg } 65705b261ecSmrg break; 65805b261ecSmrg default: 65905b261ecSmrg ErrorF( 66005b261ecSmrg "Attempt to change unknown pointer default (%d) ignored\n", 66105b261ecSmrg pAction->dflt.affect); 66205b261ecSmrg break; 66305b261ecSmrg } 66405b261ecSmrg if (XkbComputeControlsNotify(xkbi->device, 66505b261ecSmrg &old,xkbi->desc->ctrls, 66605b261ecSmrg &cn,False)) { 66705b261ecSmrg cn.keycode = keycode; 66805b261ecSmrg /* XXX: what about DeviceKeyPress? */ 66905b261ecSmrg cn.eventType = KeyPress; 67005b261ecSmrg cn.requestMajor = 0; 67105b261ecSmrg cn.requestMinor = 0; 67205b261ecSmrg XkbSendControlsNotify(xkbi->device,&cn); 67305b261ecSmrg } 67405b261ecSmrg } 67505b261ecSmrg break; 67605b261ecSmrg } 67705b261ecSmrg } 67805b261ecSmrg else if (filter->keycode==keycode) { 67905b261ecSmrg int button= filter->upAction.btn.button; 68005b261ecSmrg 68105b261ecSmrg switch (filter->upAction.type) { 68205b261ecSmrg case XkbSA_LockPtrBtn: 68305b261ecSmrg if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)|| 68405b261ecSmrg ((xkbi->lockedPtrButtons&(1<<button))==0)) { 68505b261ecSmrg break; 68605b261ecSmrg } 68705b261ecSmrg xkbi->lockedPtrButtons&= ~(1<<button); 68805b261ecSmrg case XkbSA_PtrBtn: 6894642e01fSmrg XkbDDXFakeDeviceButton(xkbi->device, 0, button); 69005b261ecSmrg break; 69105b261ecSmrg } 69205b261ecSmrg filter->active = 0; 69305b261ecSmrg } 69405b261ecSmrg return 0; 69505b261ecSmrg} 69605b261ecSmrg 69705b261ecSmrgstatic int 69805b261ecSmrg_XkbFilterControls( XkbSrvInfoPtr xkbi, 69905b261ecSmrg XkbFilterPtr filter, 70005b261ecSmrg unsigned keycode, 70105b261ecSmrg XkbAction * pAction) 70205b261ecSmrg{ 70305b261ecSmrgXkbControlsRec old; 70405b261ecSmrgXkbControlsPtr ctrls; 70505b261ecSmrgDeviceIntPtr kbd; 70605b261ecSmrgunsigned int change; 70705b261ecSmrgXkbEventCauseRec cause; 70805b261ecSmrg 70905b261ecSmrg kbd= xkbi->device; 71005b261ecSmrg ctrls= xkbi->desc->ctrls; 71105b261ecSmrg old= *ctrls; 71205b261ecSmrg if (filter->keycode==0) { /* initial press */ 71305b261ecSmrg filter->keycode = keycode; 71405b261ecSmrg filter->active = 1; 71505b261ecSmrg filter->filterOthers = 0; 71605b261ecSmrg change= XkbActionCtrls(&pAction->ctrls); 71705b261ecSmrg filter->priv = change; 71805b261ecSmrg filter->filter = _XkbFilterControls; 71905b261ecSmrg filter->upAction = *pAction; 72005b261ecSmrg 72105b261ecSmrg if (pAction->type==XkbSA_LockControls) { 72205b261ecSmrg filter->priv= (ctrls->enabled_ctrls&change); 72305b261ecSmrg change&= ~ctrls->enabled_ctrls; 72405b261ecSmrg } 72505b261ecSmrg 72605b261ecSmrg if (change) { 72705b261ecSmrg xkbControlsNotify cn; 72805b261ecSmrg XkbSrvLedInfoPtr sli; 72905b261ecSmrg 73005b261ecSmrg ctrls->enabled_ctrls|= change; 73105b261ecSmrg if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,False)) { 73205b261ecSmrg cn.keycode = keycode; 73305b261ecSmrg /* XXX: what about DeviceKeyPress? */ 73405b261ecSmrg cn.eventType = KeyPress; 73505b261ecSmrg cn.requestMajor = 0; 73605b261ecSmrg cn.requestMinor = 0; 73705b261ecSmrg XkbSendControlsNotify(kbd,&cn); 73805b261ecSmrg } 73905b261ecSmrg 74005b261ecSmrg XkbSetCauseKey(&cause,keycode,KeyPress); 74105b261ecSmrg 74205b261ecSmrg /* If sticky keys were disabled, clear all locks and latches */ 74305b261ecSmrg if ((old.enabled_ctrls&XkbStickyKeysMask)&& 74405b261ecSmrg (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) { 74505b261ecSmrg XkbClearAllLatchesAndLocks(kbd,xkbi,False,&cause); 74605b261ecSmrg } 74705b261ecSmrg sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); 74805b261ecSmrg XkbUpdateIndicators(kbd,sli->usesControls,True,NULL,&cause); 74905b261ecSmrg if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) 75005b261ecSmrg XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change); 75105b261ecSmrg } 75205b261ecSmrg } 75305b261ecSmrg else if (filter->keycode==keycode) { 75405b261ecSmrg change= filter->priv; 75505b261ecSmrg if (change) { 75605b261ecSmrg xkbControlsNotify cn; 75705b261ecSmrg XkbSrvLedInfoPtr sli; 75805b261ecSmrg 75905b261ecSmrg ctrls->enabled_ctrls&= ~change; 76005b261ecSmrg if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,False)) { 76105b261ecSmrg cn.keycode = keycode; 76205b261ecSmrg cn.eventType = KeyRelease; 76305b261ecSmrg cn.requestMajor = 0; 76405b261ecSmrg cn.requestMinor = 0; 76505b261ecSmrg XkbSendControlsNotify(kbd,&cn); 76605b261ecSmrg } 76705b261ecSmrg 76805b261ecSmrg XkbSetCauseKey(&cause,keycode,KeyRelease); 76905b261ecSmrg /* If sticky keys were disabled, clear all locks and latches */ 77005b261ecSmrg if ((old.enabled_ctrls&XkbStickyKeysMask)&& 77105b261ecSmrg (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) { 77205b261ecSmrg XkbClearAllLatchesAndLocks(kbd,xkbi,False,&cause); 77305b261ecSmrg } 77405b261ecSmrg sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); 77505b261ecSmrg XkbUpdateIndicators(kbd,sli->usesControls,True,NULL,&cause); 77605b261ecSmrg if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) 77705b261ecSmrg XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change); 77805b261ecSmrg } 77905b261ecSmrg filter->keycode= 0; 78005b261ecSmrg filter->active= 0; 78105b261ecSmrg } 78205b261ecSmrg return 1; 78305b261ecSmrg} 78405b261ecSmrg 78505b261ecSmrgstatic int 78605b261ecSmrg_XkbFilterActionMessage(XkbSrvInfoPtr xkbi, 78705b261ecSmrg XkbFilterPtr filter, 78805b261ecSmrg unsigned keycode, 78905b261ecSmrg XkbAction * pAction) 79005b261ecSmrg{ 79105b261ecSmrgXkbMessageAction * pMsg; 79205b261ecSmrgDeviceIntPtr kbd; 79305b261ecSmrg 79405b261ecSmrg kbd= xkbi->device; 79505b261ecSmrg if (filter->keycode==0) { /* initial press */ 79605b261ecSmrg pMsg= &pAction->msg; 79705b261ecSmrg if ((pMsg->flags&XkbSA_MessageOnRelease)|| 79805b261ecSmrg ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) { 79905b261ecSmrg filter->keycode = keycode; 80005b261ecSmrg filter->active = 1; 80105b261ecSmrg filter->filterOthers = 0; 80205b261ecSmrg filter->priv = 0; 80305b261ecSmrg filter->filter = _XkbFilterActionMessage; 80405b261ecSmrg filter->upAction = *pAction; 80505b261ecSmrg } 80605b261ecSmrg if (pMsg->flags&XkbSA_MessageOnPress) { 80705b261ecSmrg xkbActionMessage msg; 80805b261ecSmrg 80905b261ecSmrg msg.keycode= keycode; 81005b261ecSmrg msg.press= 1; 81105b261ecSmrg msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 81205b261ecSmrg memcpy((char *)msg.message, 81305b261ecSmrg (char *)pMsg->message,XkbActionMessageLength); 81405b261ecSmrg XkbSendActionMessage(kbd,&msg); 81505b261ecSmrg } 81605b261ecSmrg return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0); 81705b261ecSmrg } 81805b261ecSmrg else if (filter->keycode==keycode) { 81905b261ecSmrg pMsg= &filter->upAction.msg; 82005b261ecSmrg if (pMsg->flags&XkbSA_MessageOnRelease) { 82105b261ecSmrg xkbActionMessage msg; 82205b261ecSmrg 82305b261ecSmrg msg.keycode= keycode; 82405b261ecSmrg msg.press= 0; 82505b261ecSmrg msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 82605b261ecSmrg memcpy((char *)msg.message,(char *)pMsg->message, 82705b261ecSmrg XkbActionMessageLength); 82805b261ecSmrg XkbSendActionMessage(kbd,&msg); 82905b261ecSmrg } 83005b261ecSmrg filter->keycode= 0; 83105b261ecSmrg filter->active= 0; 83205b261ecSmrg return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 83305b261ecSmrg } 83405b261ecSmrg return 0; 83505b261ecSmrg} 83605b261ecSmrg 83705b261ecSmrgstatic int 83805b261ecSmrg_XkbFilterRedirectKey( XkbSrvInfoPtr xkbi, 83905b261ecSmrg XkbFilterPtr filter, 84005b261ecSmrg unsigned keycode, 84105b261ecSmrg XkbAction * pAction) 84205b261ecSmrg{ 8434642e01fSmrgunsigned realMods = 0; 84405b261ecSmrgxEvent ev; 84505b261ecSmrgint x,y; 84605b261ecSmrgXkbStateRec old; 84705b261ecSmrgunsigned mods,mask,oldCoreState = 0,oldCorePrevState = 0; 84805b261ecSmrgxkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device); 84905b261ecSmrgProcessInputProc backupproc; 85005b261ecSmrg 85105b261ecSmrg /* never actually used uninitialised, but gcc isn't smart enough 85205b261ecSmrg * to work that out. */ 85305b261ecSmrg memset(&old, 0, sizeof(old)); 85405b261ecSmrg 85505b261ecSmrg if ((filter->keycode!=0)&&(filter->keycode!=keycode)) 85605b261ecSmrg return 1; 85705b261ecSmrg 8584642e01fSmrg GetSpritePosition(inputInfo.pointer, &x,&y); 85905b261ecSmrg ev.u.keyButtonPointer.time = GetTimeInMillis(); 86005b261ecSmrg ev.u.keyButtonPointer.rootX = x; 86105b261ecSmrg ev.u.keyButtonPointer.rootY = y; 86205b261ecSmrg 86305b261ecSmrg if (filter->keycode==0) { /* initial press */ 86405b261ecSmrg if ((pAction->redirect.new_key<xkbi->desc->min_key_code)|| 86505b261ecSmrg (pAction->redirect.new_key>xkbi->desc->max_key_code)) { 86605b261ecSmrg return 1; 86705b261ecSmrg } 86805b261ecSmrg filter->keycode = keycode; 86905b261ecSmrg filter->active = 1; 87005b261ecSmrg filter->filterOthers = 0; 87105b261ecSmrg filter->priv = 0; 87205b261ecSmrg filter->filter = _XkbFilterRedirectKey; 87305b261ecSmrg filter->upAction = *pAction; 87405b261ecSmrg 87505b261ecSmrg /* XXX: what about DeviceKeyPress */ 87605b261ecSmrg ev.u.u.type = KeyPress; 87705b261ecSmrg ev.u.u.detail = pAction->redirect.new_key; 87805b261ecSmrg 87905b261ecSmrg mask= XkbSARedirectVModsMask(&pAction->redirect); 88005b261ecSmrg mods= XkbSARedirectVMods(&pAction->redirect); 88105b261ecSmrg if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask); 88205b261ecSmrg if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods); 88305b261ecSmrg mask|= pAction->redirect.mods_mask; 88405b261ecSmrg mods|= pAction->redirect.mods; 88505b261ecSmrg 88605b261ecSmrg if ( mask || mods ) { 88705b261ecSmrg old= xkbi->state; 88805b261ecSmrg oldCoreState= xkbi->device->key->state; 88905b261ecSmrg oldCorePrevState= xkbi->device->key->prev_state; 89005b261ecSmrg xkbi->state.base_mods&= ~mask; 89105b261ecSmrg xkbi->state.base_mods|= (mods&mask); 89205b261ecSmrg xkbi->state.latched_mods&= ~mask; 89305b261ecSmrg xkbi->state.latched_mods|= (mods&mask); 89405b261ecSmrg xkbi->state.locked_mods&= ~mask; 89505b261ecSmrg xkbi->state.locked_mods|= (mods&mask); 89605b261ecSmrg XkbComputeDerivedState(xkbi); 89705b261ecSmrg xkbi->device->key->state= xkbi->device->key->prev_state= 89805b261ecSmrg xkbi->state.mods; 89905b261ecSmrg } 90005b261ecSmrg 90105b261ecSmrg realMods = xkbi->device->key->modifierMap[ev.u.u.detail]; 90205b261ecSmrg xkbi->device->key->modifierMap[ev.u.u.detail] = 0; 90305b261ecSmrg UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc); 90405b261ecSmrg xkbi->device->public.processInputProc(&ev,xkbi->device,1); 90505b261ecSmrg COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, 90605b261ecSmrg backupproc,xkbUnwrapProc); 90705b261ecSmrg xkbi->device->key->modifierMap[ev.u.u.detail] = realMods; 90805b261ecSmrg 90905b261ecSmrg if ( mask || mods ) { 91005b261ecSmrg xkbi->device->key->state= oldCoreState; 91105b261ecSmrg xkbi->device->key->prev_state= oldCorePrevState; 91205b261ecSmrg xkbi->state= old; 91305b261ecSmrg } 91405b261ecSmrg } 91505b261ecSmrg else if (filter->keycode==keycode) { 91605b261ecSmrg 91705b261ecSmrg /* XXX: what about DeviceKeyRelease */ 91805b261ecSmrg ev.u.u.type = KeyRelease; 91905b261ecSmrg ev.u.u.detail = filter->upAction.redirect.new_key; 92005b261ecSmrg 92105b261ecSmrg mask= XkbSARedirectVModsMask(&filter->upAction.redirect); 92205b261ecSmrg mods= XkbSARedirectVMods(&filter->upAction.redirect); 92305b261ecSmrg if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask); 92405b261ecSmrg if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods); 92505b261ecSmrg mask|= filter->upAction.redirect.mods_mask; 92605b261ecSmrg mods|= filter->upAction.redirect.mods; 92705b261ecSmrg 92805b261ecSmrg if ( mask || mods ) { 92905b261ecSmrg old= xkbi->state; 93005b261ecSmrg oldCoreState= xkbi->device->key->state; 93105b261ecSmrg oldCorePrevState= xkbi->device->key->prev_state; 93205b261ecSmrg xkbi->state.base_mods&= ~mask; 93305b261ecSmrg xkbi->state.base_mods|= (mods&mask); 93405b261ecSmrg xkbi->state.latched_mods&= ~mask; 93505b261ecSmrg xkbi->state.latched_mods|= (mods&mask); 93605b261ecSmrg xkbi->state.locked_mods&= ~mask; 93705b261ecSmrg xkbi->state.locked_mods|= (mods&mask); 93805b261ecSmrg XkbComputeDerivedState(xkbi); 93905b261ecSmrg xkbi->device->key->state= xkbi->device->key->prev_state= 94005b261ecSmrg xkbi->state.mods; 94105b261ecSmrg } 94205b261ecSmrg 94305b261ecSmrg realMods = xkbi->device->key->modifierMap[ev.u.u.detail]; 94405b261ecSmrg xkbi->device->key->modifierMap[ev.u.u.detail] = 0; 94505b261ecSmrg UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc); 94605b261ecSmrg xkbi->device->public.processInputProc(&ev,xkbi->device,1); 94705b261ecSmrg COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, 94805b261ecSmrg backupproc,xkbUnwrapProc); 94905b261ecSmrg xkbi->device->key->modifierMap[ev.u.u.detail] = realMods; 95005b261ecSmrg 95105b261ecSmrg if ( mask || mods ) { 95205b261ecSmrg xkbi->device->key->state= oldCoreState; 95305b261ecSmrg xkbi->device->key->prev_state= oldCorePrevState; 95405b261ecSmrg xkbi->state= old; 95505b261ecSmrg } 95605b261ecSmrg 95705b261ecSmrg filter->keycode= 0; 95805b261ecSmrg filter->active= 0; 95905b261ecSmrg } 96005b261ecSmrg return 0; 96105b261ecSmrg} 96205b261ecSmrg 96305b261ecSmrgstatic int 96405b261ecSmrg_XkbFilterSwitchScreen( XkbSrvInfoPtr xkbi, 96505b261ecSmrg XkbFilterPtr filter, 96605b261ecSmrg unsigned keycode, 96705b261ecSmrg XkbAction * pAction) 96805b261ecSmrg{ 96905b261ecSmrg DeviceIntPtr dev = xkbi->device; 97005b261ecSmrg if (dev == inputInfo.keyboard) 97105b261ecSmrg return 0; 97205b261ecSmrg 97305b261ecSmrg if (filter->keycode==0) { /* initial press */ 97405b261ecSmrg filter->keycode = keycode; 97505b261ecSmrg filter->active = 1; 97605b261ecSmrg filter->filterOthers = 0; 97705b261ecSmrg filter->filter = _XkbFilterSwitchScreen; 97805b261ecSmrg AccessXCancelRepeatKey(xkbi, keycode); 97905b261ecSmrg XkbDDXSwitchScreen(dev,keycode,pAction); 98005b261ecSmrg return 0; 98105b261ecSmrg } 98205b261ecSmrg else if (filter->keycode==keycode) { 98305b261ecSmrg filter->active= 0; 98405b261ecSmrg return 0; 98505b261ecSmrg } 98605b261ecSmrg return 1; 98705b261ecSmrg} 98805b261ecSmrg 98905b261ecSmrgstatic int 99005b261ecSmrg_XkbFilterXF86Private( XkbSrvInfoPtr xkbi, 99105b261ecSmrg XkbFilterPtr filter, 99205b261ecSmrg unsigned keycode, 99305b261ecSmrg XkbAction * pAction) 99405b261ecSmrg{ 99505b261ecSmrg DeviceIntPtr dev = xkbi->device; 99605b261ecSmrg if (dev == inputInfo.keyboard) 99705b261ecSmrg return 0; 99805b261ecSmrg 99905b261ecSmrg if (filter->keycode==0) { /* initial press */ 100005b261ecSmrg filter->keycode = keycode; 100105b261ecSmrg filter->active = 1; 100205b261ecSmrg filter->filterOthers = 0; 100305b261ecSmrg filter->filter = _XkbFilterXF86Private; 100405b261ecSmrg XkbDDXPrivate(dev,keycode,pAction); 100505b261ecSmrg return 0; 100605b261ecSmrg } 100705b261ecSmrg else if (filter->keycode==keycode) { 100805b261ecSmrg filter->active= 0; 100905b261ecSmrg return 0; 101005b261ecSmrg } 101105b261ecSmrg return 1; 101205b261ecSmrg} 101305b261ecSmrg 101405b261ecSmrg 101505b261ecSmrgstatic int 101605b261ecSmrg_XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi, 101705b261ecSmrg XkbFilterPtr filter, 101805b261ecSmrg unsigned keycode, 101905b261ecSmrg XkbAction * pAction) 102005b261ecSmrg{ 102105b261ecSmrgDeviceIntPtr dev; 102205b261ecSmrgint button; 102305b261ecSmrg 10244642e01fSmrg if (xkbi->device == inputInfo.keyboard) 102505b261ecSmrg return 0; 102605b261ecSmrg 102705b261ecSmrg if (filter->keycode==0) { /* initial press */ 10284642e01fSmrg _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient, 10294642e01fSmrg DixUnknownAccess, &button); 10304642e01fSmrg if (!dev || !dev->public.on || dev == inputInfo.pointer) 103105b261ecSmrg return 1; 103205b261ecSmrg 103305b261ecSmrg button= pAction->devbtn.button; 103405b261ecSmrg if ((button<1)||(button>dev->button->numButtons)) 103505b261ecSmrg return 1; 103605b261ecSmrg 103705b261ecSmrg filter->keycode = keycode; 103805b261ecSmrg filter->active = 1; 103905b261ecSmrg filter->filterOthers = 0; 104005b261ecSmrg filter->priv=0; 104105b261ecSmrg filter->filter = _XkbFilterDeviceBtn; 104205b261ecSmrg filter->upAction= *pAction; 104305b261ecSmrg switch (pAction->type) { 104405b261ecSmrg case XkbSA_LockDeviceBtn: 104505b261ecSmrg if ((pAction->devbtn.flags&XkbSA_LockNoLock)|| 10464642e01fSmrg BitIsOn(dev->button->down, button)) 104705b261ecSmrg return 0; 104805b261ecSmrg XkbDDXFakeDeviceButton(dev,True,button); 104905b261ecSmrg filter->upAction.type= XkbSA_NoAction; 105005b261ecSmrg break; 105105b261ecSmrg case XkbSA_DeviceBtn: 105205b261ecSmrg if (pAction->devbtn.count>0) { 105305b261ecSmrg int nClicks,i; 105405b261ecSmrg nClicks= pAction->btn.count; 105505b261ecSmrg for (i=0;i<nClicks;i++) { 105605b261ecSmrg XkbDDXFakeDeviceButton(dev,True,button); 105705b261ecSmrg XkbDDXFakeDeviceButton(dev,False,button); 105805b261ecSmrg } 105905b261ecSmrg filter->upAction.type= XkbSA_NoAction; 106005b261ecSmrg } 106105b261ecSmrg else XkbDDXFakeDeviceButton(dev,True,button); 106205b261ecSmrg break; 106305b261ecSmrg } 106405b261ecSmrg } 106505b261ecSmrg else if (filter->keycode==keycode) { 106605b261ecSmrg int button; 106705b261ecSmrg 106805b261ecSmrg filter->active= 0; 10694642e01fSmrg _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device, 10704642e01fSmrg serverClient, DixUnknownAccess, &button); 10714642e01fSmrg if (!dev || !dev->public.on || dev == inputInfo.pointer) 107205b261ecSmrg return 1; 107305b261ecSmrg 107405b261ecSmrg button= filter->upAction.btn.button; 107505b261ecSmrg switch (filter->upAction.type) { 107605b261ecSmrg case XkbSA_LockDeviceBtn: 107705b261ecSmrg if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)|| 10784642e01fSmrg !BitIsOn(dev->button->down, button)) 107905b261ecSmrg return 0; 108005b261ecSmrg XkbDDXFakeDeviceButton(dev,False,button); 108105b261ecSmrg break; 108205b261ecSmrg case XkbSA_DeviceBtn: 108305b261ecSmrg XkbDDXFakeDeviceButton(dev,False,button); 108405b261ecSmrg break; 108505b261ecSmrg } 108605b261ecSmrg filter->active = 0; 108705b261ecSmrg } 108805b261ecSmrg return 0; 108905b261ecSmrg} 109005b261ecSmrg 109105b261ecSmrgstatic XkbFilterPtr 109205b261ecSmrg_XkbNextFreeFilter( 109305b261ecSmrg XkbSrvInfoPtr xkbi 109405b261ecSmrg) 109505b261ecSmrg{ 109605b261ecSmrgregister int i; 109705b261ecSmrg 109805b261ecSmrg if (xkbi->szFilters==0) { 109905b261ecSmrg xkbi->szFilters = 4; 110005b261ecSmrg xkbi->filters = _XkbTypedCalloc(xkbi->szFilters,XkbFilterRec); 110105b261ecSmrg /* 6/21/93 (ef) -- XXX! deal with allocation failure */ 110205b261ecSmrg } 110305b261ecSmrg for (i=0;i<xkbi->szFilters;i++) { 110405b261ecSmrg if (!xkbi->filters[i].active) { 110505b261ecSmrg xkbi->filters[i].keycode = 0; 110605b261ecSmrg return &xkbi->filters[i]; 110705b261ecSmrg } 110805b261ecSmrg } 110905b261ecSmrg xkbi->szFilters*=2; 111005b261ecSmrg xkbi->filters= _XkbTypedRealloc(xkbi->filters, 111105b261ecSmrg xkbi->szFilters, 111205b261ecSmrg XkbFilterRec); 111305b261ecSmrg /* 6/21/93 (ef) -- XXX! deal with allocation failure */ 111405b261ecSmrg bzero(&xkbi->filters[xkbi->szFilters/2], 111505b261ecSmrg (xkbi->szFilters/2)*sizeof(XkbFilterRec)); 111605b261ecSmrg return &xkbi->filters[xkbi->szFilters/2]; 111705b261ecSmrg} 111805b261ecSmrg 111905b261ecSmrgstatic int 112005b261ecSmrg_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction) 112105b261ecSmrg{ 112205b261ecSmrgregister int i,send; 112305b261ecSmrg 112405b261ecSmrg send= 1; 112505b261ecSmrg for (i=0;i<xkbi->szFilters;i++) { 112605b261ecSmrg if ((xkbi->filters[i].active)&&(xkbi->filters[i].filter)) 112705b261ecSmrg send= ((*xkbi->filters[i].filter)(xkbi,&xkbi->filters[i],kc,pAction) 112805b261ecSmrg && send); 112905b261ecSmrg } 113005b261ecSmrg return send; 113105b261ecSmrg} 113205b261ecSmrg 113305b261ecSmrgvoid 113405b261ecSmrgXkbHandleActions(DeviceIntPtr dev,DeviceIntPtr kbd,xEvent *xE,int count) 113505b261ecSmrg{ 113605b261ecSmrgint key,bit,i; 11374642e01fSmrgCARD8 realMods = 0; 113805b261ecSmrgXkbSrvInfoPtr xkbi; 113905b261ecSmrgKeyClassPtr keyc; 114005b261ecSmrgint changed,sendEvent; 114105b261ecSmrgBool genStateNotify; 114205b261ecSmrgXkbStateRec oldState; 114305b261ecSmrgXkbAction act; 114405b261ecSmrgXkbFilterPtr filter; 114505b261ecSmrgBool keyEvent; 114605b261ecSmrgBool pressEvent; 114705b261ecSmrgProcessInputProc backupproc; 114805b261ecSmrg 114905b261ecSmrgxkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev); 115005b261ecSmrg 115105b261ecSmrg keyc= kbd->key; 115205b261ecSmrg xkbi= keyc->xkbInfo; 115305b261ecSmrg key= xE->u.u.detail; 115405b261ecSmrg /* The state may change, so if we're not in the middle of sending a state 115505b261ecSmrg * notify, prepare for it */ 115605b261ecSmrg if ((xkbi->flags&_XkbStateNotifyInProgress)==0) { 115705b261ecSmrg oldState= xkbi->state; 115805b261ecSmrg xkbi->flags|= _XkbStateNotifyInProgress; 115905b261ecSmrg genStateNotify= True; 116005b261ecSmrg } 116105b261ecSmrg else genStateNotify= False; 116205b261ecSmrg 116305b261ecSmrg xkbi->clearMods = xkbi->setMods = 0; 116405b261ecSmrg xkbi->groupChange = 0; 116505b261ecSmrg 116605b261ecSmrg sendEvent = 1; 116705b261ecSmrg keyEvent= ((xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)|| 116805b261ecSmrg (xE->u.u.type==KeyRelease)||(xE->u.u.type==DeviceKeyRelease)); 116905b261ecSmrg pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)|| 117005b261ecSmrg (xE->u.u.type==ButtonPress)||(xE->u.u.type==DeviceButtonPress); 117105b261ecSmrg 117205b261ecSmrg if (pressEvent) { 117305b261ecSmrg if (keyEvent) 117405b261ecSmrg act = XkbGetKeyAction(xkbi,&xkbi->state,key); 117505b261ecSmrg else { 117605b261ecSmrg act = XkbGetButtonAction(kbd,dev,key); 117705b261ecSmrg key|= BTN_ACT_FLAG; 117805b261ecSmrg } 117905b261ecSmrg sendEvent = _XkbApplyFilters(xkbi,key,&act); 118005b261ecSmrg if (sendEvent) { 118105b261ecSmrg switch (act.type) { 118205b261ecSmrg case XkbSA_SetMods: 118305b261ecSmrg case XkbSA_SetGroup: 118405b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 118505b261ecSmrg sendEvent = _XkbFilterSetState(xkbi,filter,key,&act); 118605b261ecSmrg break; 118705b261ecSmrg case XkbSA_LatchMods: 118805b261ecSmrg case XkbSA_LatchGroup: 118905b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 119005b261ecSmrg sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act); 119105b261ecSmrg break; 119205b261ecSmrg case XkbSA_LockMods: 119305b261ecSmrg case XkbSA_LockGroup: 119405b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 119505b261ecSmrg sendEvent=_XkbFilterLockState(xkbi,filter,key,&act); 119605b261ecSmrg break; 119705b261ecSmrg case XkbSA_ISOLock: 119805b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 119905b261ecSmrg sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act); 120005b261ecSmrg break; 120105b261ecSmrg case XkbSA_MovePtr: 120205b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 120305b261ecSmrg sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act); 120405b261ecSmrg break; 120505b261ecSmrg case XkbSA_PtrBtn: 120605b261ecSmrg case XkbSA_LockPtrBtn: 120705b261ecSmrg case XkbSA_SetPtrDflt: 120805b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 120905b261ecSmrg sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act); 121005b261ecSmrg break; 121105b261ecSmrg case XkbSA_Terminate: 121205b261ecSmrg sendEvent= XkbDDXTerminateServer(dev,key,&act); 121305b261ecSmrg break; 121405b261ecSmrg case XkbSA_SwitchScreen: 121505b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 121605b261ecSmrg sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act); 121705b261ecSmrg break; 121805b261ecSmrg case XkbSA_SetControls: 121905b261ecSmrg case XkbSA_LockControls: 122005b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 122105b261ecSmrg sendEvent=_XkbFilterControls(xkbi,filter,key,&act); 122205b261ecSmrg break; 122305b261ecSmrg case XkbSA_ActionMessage: 122405b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 122505b261ecSmrg sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act); 122605b261ecSmrg break; 122705b261ecSmrg case XkbSA_RedirectKey: 122805b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 122905b261ecSmrg sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act); 123005b261ecSmrg break; 123105b261ecSmrg case XkbSA_DeviceBtn: 123205b261ecSmrg case XkbSA_LockDeviceBtn: 123305b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 123405b261ecSmrg sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act); 123505b261ecSmrg break; 123605b261ecSmrg case XkbSA_XFree86Private: 123705b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 123805b261ecSmrg sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act); 123905b261ecSmrg break; 124005b261ecSmrg } 124105b261ecSmrg } 124205b261ecSmrg } 124305b261ecSmrg else { 124405b261ecSmrg if (!keyEvent) 124505b261ecSmrg key|= BTN_ACT_FLAG; 124605b261ecSmrg sendEvent = _XkbApplyFilters(xkbi,key,NULL); 124705b261ecSmrg } 124805b261ecSmrg 124905b261ecSmrg if (xkbi->groupChange!=0) 125005b261ecSmrg xkbi->state.base_group+= xkbi->groupChange; 125105b261ecSmrg if (xkbi->setMods) { 125205b261ecSmrg for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) { 125305b261ecSmrg if (xkbi->setMods&bit) { 125405b261ecSmrg keyc->modifierKeyCount[i]++; 125505b261ecSmrg xkbi->state.base_mods|= bit; 125605b261ecSmrg xkbi->setMods&= ~bit; 125705b261ecSmrg } 125805b261ecSmrg } 125905b261ecSmrg } 126005b261ecSmrg if (xkbi->clearMods) { 126105b261ecSmrg for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) { 126205b261ecSmrg if (xkbi->clearMods&bit) { 126305b261ecSmrg keyc->modifierKeyCount[i]--; 126405b261ecSmrg if (keyc->modifierKeyCount[i]<=0) { 126505b261ecSmrg xkbi->state.base_mods&= ~bit; 126605b261ecSmrg keyc->modifierKeyCount[i] = 0; 126705b261ecSmrg } 126805b261ecSmrg xkbi->clearMods&= ~bit; 126905b261ecSmrg } 127005b261ecSmrg } 127105b261ecSmrg } 127205b261ecSmrg 127305b261ecSmrg if (sendEvent) { 12744642e01fSmrg DeviceIntPtr tmpdev; 127505b261ecSmrg if (keyEvent) { 127605b261ecSmrg realMods = keyc->modifierMap[key]; 127705b261ecSmrg keyc->modifierMap[key] = 0; 12784642e01fSmrg tmpdev = dev; 12794642e01fSmrg } else 12804642e01fSmrg tmpdev = GetPairedDevice(dev); 128105b261ecSmrg 12824642e01fSmrg UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc); 12834642e01fSmrg dev->public.processInputProc(xE,tmpdev,count); 12844642e01fSmrg COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, 128505b261ecSmrg backupproc,xkbUnwrapProc); 128605b261ecSmrg if (keyEvent) 128705b261ecSmrg keyc->modifierMap[key] = realMods; 128805b261ecSmrg } 128905b261ecSmrg else if (keyEvent) { 129005b261ecSmrg FixKeyState(xE,dev); 129105b261ecSmrg } 129205b261ecSmrg 129305b261ecSmrg xkbi->prev_state= oldState; 129405b261ecSmrg XkbComputeDerivedState(xkbi); 129505b261ecSmrg keyc->prev_state= keyc->state; 129605b261ecSmrg keyc->state= XkbStateFieldFromRec(&xkbi->state); 129705b261ecSmrg changed = XkbStateChangedFlags(&oldState,&xkbi->state); 129805b261ecSmrg if (genStateNotify) { 129905b261ecSmrg if (changed) { 130005b261ecSmrg xkbStateNotify sn; 130105b261ecSmrg sn.keycode= key; 130205b261ecSmrg sn.eventType= xE->u.u.type; 130305b261ecSmrg sn.requestMajor = sn.requestMinor = 0; 130405b261ecSmrg sn.changed= changed; 130505b261ecSmrg XkbSendStateNotify(dev,&sn); 130605b261ecSmrg } 130705b261ecSmrg xkbi->flags&= ~_XkbStateNotifyInProgress; 130805b261ecSmrg } 130905b261ecSmrg changed= XkbIndicatorsToUpdate(dev,changed,False); 131005b261ecSmrg if (changed) { 131105b261ecSmrg XkbEventCauseRec cause; 131205b261ecSmrg XkbSetCauseKey(&cause,key,xE->u.u.type); 131305b261ecSmrg XkbUpdateIndicators(dev,changed,False,NULL,&cause); 131405b261ecSmrg } 131505b261ecSmrg return; 131605b261ecSmrg} 131705b261ecSmrg 131805b261ecSmrgint 131905b261ecSmrgXkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches) 132005b261ecSmrg{ 132105b261ecSmrgXkbSrvInfoPtr xkbi; 132205b261ecSmrgXkbFilterPtr filter; 132305b261ecSmrgXkbAction act; 132405b261ecSmrgunsigned clear; 132505b261ecSmrg 132605b261ecSmrg if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) { 132705b261ecSmrg xkbi = pXDev->key->xkbInfo; 132805b261ecSmrg clear= (mask&(~latches)); 132905b261ecSmrg xkbi->state.latched_mods&= ~clear; 133005b261ecSmrg /* Clear any pending latch to locks. 133105b261ecSmrg */ 133205b261ecSmrg act.type = XkbSA_NoAction; 133305b261ecSmrg _XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act); 133405b261ecSmrg act.type = XkbSA_LatchMods; 133505b261ecSmrg act.mods.flags = 0; 133605b261ecSmrg act.mods.mask = mask&latches; 133705b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 133805b261ecSmrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act); 133905b261ecSmrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL); 134005b261ecSmrg return Success; 134105b261ecSmrg } 134205b261ecSmrg return BadValue; 134305b261ecSmrg} 134405b261ecSmrg 134505b261ecSmrgint 134605b261ecSmrgXkbLatchGroup(DeviceIntPtr pXDev,int group) 134705b261ecSmrg{ 134805b261ecSmrgXkbSrvInfoPtr xkbi; 134905b261ecSmrgXkbFilterPtr filter; 135005b261ecSmrgXkbAction act; 135105b261ecSmrg 135205b261ecSmrg if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) { 135305b261ecSmrg xkbi = pXDev->key->xkbInfo; 135405b261ecSmrg act.type = XkbSA_LatchGroup; 135505b261ecSmrg act.group.flags = 0; 135605b261ecSmrg XkbSASetGroup(&act.group,group); 135705b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 135805b261ecSmrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act); 135905b261ecSmrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL); 136005b261ecSmrg return Success; 136105b261ecSmrg } 136205b261ecSmrg return BadValue; 136305b261ecSmrg} 136405b261ecSmrg 136505b261ecSmrg/***====================================================================***/ 136605b261ecSmrg 136705b261ecSmrgvoid 136805b261ecSmrgXkbClearAllLatchesAndLocks( DeviceIntPtr dev, 136905b261ecSmrg XkbSrvInfoPtr xkbi, 137005b261ecSmrg Bool genEv, 137105b261ecSmrg XkbEventCausePtr cause) 137205b261ecSmrg{ 137305b261ecSmrgXkbStateRec os; 137405b261ecSmrgxkbStateNotify sn; 137505b261ecSmrg 137605b261ecSmrg sn.changed= 0; 137705b261ecSmrg os= xkbi->state; 137805b261ecSmrg if (os.latched_mods) { /* clear all latches */ 137905b261ecSmrg XkbLatchModifiers(dev,~0,0); 138005b261ecSmrg sn.changed|= XkbModifierLatchMask; 138105b261ecSmrg } 138205b261ecSmrg if (os.latched_group) { 138305b261ecSmrg XkbLatchGroup(dev,0); 138405b261ecSmrg sn.changed|= XkbGroupLatchMask; 138505b261ecSmrg } 138605b261ecSmrg if (os.locked_mods) { 138705b261ecSmrg xkbi->state.locked_mods= 0; 138805b261ecSmrg sn.changed|= XkbModifierLockMask; 138905b261ecSmrg } 139005b261ecSmrg if (os.locked_group) { 139105b261ecSmrg xkbi->state.locked_group= 0; 139205b261ecSmrg sn.changed|= XkbGroupLockMask; 139305b261ecSmrg } 139405b261ecSmrg if ( genEv && sn.changed) { 139505b261ecSmrg CARD32 changed; 139605b261ecSmrg 139705b261ecSmrg XkbComputeDerivedState(xkbi); 139805b261ecSmrg sn.keycode= cause->kc; 139905b261ecSmrg sn.eventType= cause->event; 140005b261ecSmrg sn.requestMajor= cause->mjr; 140105b261ecSmrg sn.requestMinor= cause->mnr; 140205b261ecSmrg sn.changed= XkbStateChangedFlags(&os,&xkbi->state); 140305b261ecSmrg XkbSendStateNotify(dev,&sn); 140405b261ecSmrg changed= XkbIndicatorsToUpdate(dev,sn.changed,False); 140505b261ecSmrg if (changed) { 140605b261ecSmrg XkbUpdateIndicators(dev,changed,True,NULL,cause); 140705b261ecSmrg } 140805b261ecSmrg } 140905b261ecSmrg return; 141005b261ecSmrg} 141105b261ecSmrg 1412