xkbActions.c revision 6747b715
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" 4505b261ecSmrg#define EXTENSION_EVENT_BASE 64 4605b261ecSmrg 476747b715SmrgDevPrivateKeyRec xkbDevicePrivateKeyRec; 486747b715Smrg 496747b715Smrgvoid XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button); 506747b715Smrgstatic void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y); 5105b261ecSmrg 5205b261ecSmrgvoid 5305b261ecSmrgxkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, 5405b261ecSmrg pointer data) 5505b261ecSmrg{ 5605b261ecSmrg xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device); 5705b261ecSmrg ProcessInputProc backupproc; 5805b261ecSmrg if(xkbPrivPtr->unwrapProc) 5905b261ecSmrg xkbPrivPtr->unwrapProc = NULL; 6005b261ecSmrg 6105b261ecSmrg UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc); 6205b261ecSmrg proc(device,data); 6305b261ecSmrg COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, 6405b261ecSmrg backupproc,xkbUnwrapProc); 6505b261ecSmrg} 6605b261ecSmrg 676747b715SmrgBool 686747b715SmrgXkbInitPrivates(void) 696747b715Smrg{ 706747b715Smrg return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec, PRIVATE_DEVICE, 0); 716747b715Smrg} 7205b261ecSmrg 7305b261ecSmrgvoid 7405b261ecSmrgXkbSetExtension(DeviceIntPtr device, ProcessInputProc proc) 7505b261ecSmrg{ 7605b261ecSmrg xkbDeviceInfoPtr xkbPrivPtr; 7705b261ecSmrg 786747b715Smrg xkbPrivPtr = (xkbDeviceInfoPtr) calloc(1, sizeof(xkbDeviceInfoRec)); 7905b261ecSmrg if (!xkbPrivPtr) 8005b261ecSmrg return; 8105b261ecSmrg xkbPrivPtr->unwrapProc = NULL; 8205b261ecSmrg 834642e01fSmrg dixSetPrivate(&device->devPrivates, xkbDevicePrivateKey, xkbPrivPtr); 8405b261ecSmrg WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc); 8505b261ecSmrg} 8605b261ecSmrg 8705b261ecSmrg/***====================================================================***/ 8805b261ecSmrg 8905b261ecSmrgstatic XkbAction 9005b261ecSmrg_FixUpAction(XkbDescPtr xkb,XkbAction *act) 9105b261ecSmrg{ 9205b261ecSmrgstatic XkbAction fake; 9305b261ecSmrg 9405b261ecSmrg if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) { 9505b261ecSmrg fake.type = XkbSA_NoAction; 9605b261ecSmrg return fake; 9705b261ecSmrg } 9805b261ecSmrg if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) { 9905b261ecSmrg if (act->any.type==XkbSA_SetMods) { 10005b261ecSmrg fake.mods.type = XkbSA_LatchMods; 10105b261ecSmrg fake.mods.mask = act->mods.mask; 10205b261ecSmrg if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask)) 10305b261ecSmrg fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock; 10405b261ecSmrg else fake.mods.flags= XkbSA_ClearLocks; 10505b261ecSmrg return fake; 10605b261ecSmrg } 10705b261ecSmrg if (act->any.type==XkbSA_SetGroup) { 10805b261ecSmrg fake.group.type = XkbSA_LatchGroup; 10905b261ecSmrg if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask)) 11005b261ecSmrg fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock; 11105b261ecSmrg else fake.group.flags= XkbSA_ClearLocks; 11205b261ecSmrg XkbSASetGroup(&fake.group,XkbSAGroup(&act->group)); 11305b261ecSmrg return fake; 11405b261ecSmrg } 11505b261ecSmrg } 11605b261ecSmrg return *act; 11705b261ecSmrg} 11805b261ecSmrg 11905b261ecSmrgstatic XkbAction 12005b261ecSmrgXkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key) 12105b261ecSmrg{ 12205b261ecSmrgint effectiveGroup; 12305b261ecSmrgint col; 12405b261ecSmrgXkbDescPtr xkb; 12505b261ecSmrgXkbKeyTypePtr type; 12605b261ecSmrgXkbAction * pActs; 12705b261ecSmrgstatic XkbAction fake; 12805b261ecSmrg 12905b261ecSmrg xkb= xkbi->desc; 13005b261ecSmrg if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) { 13105b261ecSmrg fake.type = XkbSA_NoAction; 13205b261ecSmrg return fake; 13305b261ecSmrg } 13405b261ecSmrg pActs= XkbKeyActionsPtr(xkb,key); 13505b261ecSmrg col= 0; 1366747b715Smrg 1376747b715Smrg effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key); 1386747b715Smrg if (effectiveGroup != XkbGroup1Index) 1396747b715Smrg col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key)); 1406747b715Smrg 14105b261ecSmrg type= XkbKeyKeyType(xkb,key,effectiveGroup); 14205b261ecSmrg if (type->map!=NULL) { 14305b261ecSmrg register unsigned i,mods; 14405b261ecSmrg register XkbKTMapEntryPtr entry; 14505b261ecSmrg mods= xkbState->mods&type->mods.mask; 14605b261ecSmrg for (entry= type->map,i=0;i<type->map_count;i++,entry++) { 14705b261ecSmrg if ((entry->active)&&(entry->mods.mask==mods)) { 14805b261ecSmrg col+= entry->level; 14905b261ecSmrg break; 15005b261ecSmrg } 15105b261ecSmrg } 15205b261ecSmrg } 15305b261ecSmrg if (pActs[col].any.type==XkbSA_NoAction) 15405b261ecSmrg return pActs[col]; 15505b261ecSmrg fake= _FixUpAction(xkb,&pActs[col]); 15605b261ecSmrg return fake; 15705b261ecSmrg} 15805b261ecSmrg 15905b261ecSmrgstatic XkbAction 16005b261ecSmrgXkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button) 16105b261ecSmrg{ 16205b261ecSmrgXkbAction fake; 16305b261ecSmrg if ((dev->button)&&(dev->button->xkb_acts)) { 16405b261ecSmrg if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) { 16505b261ecSmrg fake= _FixUpAction(kbd->key->xkbInfo->desc, 16605b261ecSmrg &dev->button->xkb_acts[button-1]); 16705b261ecSmrg return fake; 16805b261ecSmrg } 16905b261ecSmrg } 17005b261ecSmrg fake.any.type= XkbSA_NoAction; 17105b261ecSmrg return fake; 17205b261ecSmrg} 17305b261ecSmrg 17405b261ecSmrg/***====================================================================***/ 17505b261ecSmrg 17605b261ecSmrg#define SYNTHETIC_KEYCODE 1 17705b261ecSmrg#define BTN_ACT_FLAG 0x100 17805b261ecSmrg 17905b261ecSmrgstatic int 18005b261ecSmrg_XkbFilterSetState( XkbSrvInfoPtr xkbi, 18105b261ecSmrg XkbFilterPtr filter, 18205b261ecSmrg unsigned keycode, 18305b261ecSmrg XkbAction *pAction) 18405b261ecSmrg{ 18505b261ecSmrg if (filter->keycode==0) { /* initial press */ 18605b261ecSmrg filter->keycode = keycode; 18705b261ecSmrg filter->active = 1; 18805b261ecSmrg filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0); 18905b261ecSmrg filter->priv = 0; 19005b261ecSmrg filter->filter = _XkbFilterSetState; 19105b261ecSmrg if (pAction->type==XkbSA_SetMods) { 19205b261ecSmrg filter->upAction = *pAction; 19305b261ecSmrg xkbi->setMods= pAction->mods.mask; 19405b261ecSmrg } 19505b261ecSmrg else { 19605b261ecSmrg xkbi->groupChange = XkbSAGroup(&pAction->group); 19705b261ecSmrg if (pAction->group.flags&XkbSA_GroupAbsolute) 19805b261ecSmrg xkbi->groupChange-= xkbi->state.base_group; 19905b261ecSmrg filter->upAction= *pAction; 20005b261ecSmrg XkbSASetGroup(&filter->upAction.group,xkbi->groupChange); 20105b261ecSmrg } 20205b261ecSmrg } 20305b261ecSmrg else if (filter->keycode==keycode) { 20405b261ecSmrg if (filter->upAction.type==XkbSA_SetMods) { 20505b261ecSmrg xkbi->clearMods = filter->upAction.mods.mask; 20605b261ecSmrg if (filter->upAction.mods.flags&XkbSA_ClearLocks) { 20705b261ecSmrg xkbi->state.locked_mods&= ~filter->upAction.mods.mask; 20805b261ecSmrg } 20905b261ecSmrg } 21005b261ecSmrg else { 21105b261ecSmrg if (filter->upAction.group.flags&XkbSA_ClearLocks) { 21205b261ecSmrg xkbi->state.locked_group = 0; 21305b261ecSmrg } 21405b261ecSmrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); 21505b261ecSmrg } 21605b261ecSmrg filter->active = 0; 21705b261ecSmrg } 21805b261ecSmrg else { 21905b261ecSmrg filter->upAction.mods.flags&= ~XkbSA_ClearLocks; 22005b261ecSmrg filter->filterOthers = 0; 22105b261ecSmrg } 22205b261ecSmrg return 1; 22305b261ecSmrg} 22405b261ecSmrg 22505b261ecSmrg#define LATCH_KEY_DOWN 1 22605b261ecSmrg#define LATCH_PENDING 2 22705b261ecSmrg#define NO_LATCH 3 22805b261ecSmrg 22905b261ecSmrgstatic int 23005b261ecSmrg_XkbFilterLatchState( XkbSrvInfoPtr xkbi, 23105b261ecSmrg XkbFilterPtr filter, 23205b261ecSmrg unsigned keycode, 23305b261ecSmrg XkbAction * pAction) 23405b261ecSmrg{ 23505b261ecSmrg 23605b261ecSmrg if (filter->keycode==0) { /* initial press */ 23705b261ecSmrg filter->keycode = keycode; 23805b261ecSmrg filter->active = 1; 23905b261ecSmrg filter->filterOthers = 1; 24005b261ecSmrg filter->priv = LATCH_KEY_DOWN; 24105b261ecSmrg filter->filter = _XkbFilterLatchState; 24205b261ecSmrg if (pAction->type==XkbSA_LatchMods) { 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 ( pAction && (filter->priv==LATCH_PENDING) ) { 25505b261ecSmrg if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) { 25605b261ecSmrg filter->active = 0; 25705b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) 25805b261ecSmrg xkbi->state.latched_mods&= ~filter->upAction.mods.mask; 25905b261ecSmrg else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group); 26005b261ecSmrg } 26105b261ecSmrg else if ((pAction->type==filter->upAction.type)&& 26205b261ecSmrg (pAction->mods.flags==filter->upAction.mods.flags)&& 26305b261ecSmrg (pAction->mods.mask==filter->upAction.mods.mask)) { 26405b261ecSmrg if (filter->upAction.mods.flags&XkbSA_LatchToLock) { 26505b261ecSmrg XkbControlsPtr ctrls= xkbi->desc->ctrls; 26605b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) 26705b261ecSmrg pAction->mods.type= XkbSA_LockMods; 26805b261ecSmrg else pAction->group.type= XkbSA_LockGroup; 26905b261ecSmrg if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&& 27005b261ecSmrg (ctrls->enabled_ctrls&XkbStickyKeysMask)) { 27105b261ecSmrg XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK, 27205b261ecSmrg XkbStickyKeysMask); 27305b261ecSmrg } 27405b261ecSmrg } 27505b261ecSmrg else { 27605b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) 27705b261ecSmrg pAction->mods.type= XkbSA_SetMods; 27805b261ecSmrg else pAction->group.type= XkbSA_SetGroup; 27905b261ecSmrg } 28005b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) 28105b261ecSmrg xkbi->state.latched_mods&= ~filter->upAction.mods.mask; 28205b261ecSmrg else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group); 28305b261ecSmrg filter->active = 0; 28405b261ecSmrg } 28505b261ecSmrg } 28605b261ecSmrg else if (filter->keycode==keycode) { /* release */ 28705b261ecSmrg XkbControlsPtr ctrls= xkbi->desc->ctrls; 28805b261ecSmrg int needBeep; 28905b261ecSmrg int beepType= _BEEP_NONE; 29005b261ecSmrg 29105b261ecSmrg needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&& 29205b261ecSmrg XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)); 29305b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) { 29405b261ecSmrg xkbi->clearMods = filter->upAction.mods.mask; 29505b261ecSmrg if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&& 29605b261ecSmrg (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) { 29705b261ecSmrg xkbi->state.locked_mods&= ~xkbi->clearMods; 29805b261ecSmrg filter->priv= NO_LATCH; 29905b261ecSmrg beepType= _BEEP_STICKY_UNLOCK; 30005b261ecSmrg } 30105b261ecSmrg } 30205b261ecSmrg else { 30305b261ecSmrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); 30405b261ecSmrg if ((filter->upAction.group.flags&XkbSA_ClearLocks)&& 30505b261ecSmrg (xkbi->state.locked_group)) { 30605b261ecSmrg xkbi->state.locked_group = 0; 30705b261ecSmrg filter->priv = NO_LATCH; 30805b261ecSmrg beepType= _BEEP_STICKY_UNLOCK; 30905b261ecSmrg } 31005b261ecSmrg } 31105b261ecSmrg if (filter->priv==NO_LATCH) { 31205b261ecSmrg filter->active= 0; 31305b261ecSmrg } 31405b261ecSmrg else { 31505b261ecSmrg filter->priv= LATCH_PENDING; 31605b261ecSmrg if (filter->upAction.type==XkbSA_LatchMods) { 31705b261ecSmrg xkbi->state.latched_mods |= filter->upAction.mods.mask; 31805b261ecSmrg needBeep = xkbi->state.latched_mods ? needBeep : 0; 31905b261ecSmrg xkbi->state.latched_mods |= filter->upAction.mods.mask; 32005b261ecSmrg } 32105b261ecSmrg else { 32205b261ecSmrg xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group); 32305b261ecSmrg } 32405b261ecSmrg if (needBeep && (beepType==_BEEP_NONE)) 32505b261ecSmrg beepType= _BEEP_STICKY_LATCH; 32605b261ecSmrg } 32705b261ecSmrg if (needBeep && (beepType!=_BEEP_NONE)) 32805b261ecSmrg XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask); 32905b261ecSmrg } 33005b261ecSmrg else if (filter->priv==LATCH_KEY_DOWN) { 33105b261ecSmrg filter->priv= NO_LATCH; 33205b261ecSmrg filter->filterOthers = 0; 33305b261ecSmrg } 33405b261ecSmrg return 1; 33505b261ecSmrg} 33605b261ecSmrg 33705b261ecSmrgstatic int 33805b261ecSmrg_XkbFilterLockState( XkbSrvInfoPtr xkbi, 33905b261ecSmrg XkbFilterPtr filter, 34005b261ecSmrg unsigned keycode, 34105b261ecSmrg XkbAction * pAction) 34205b261ecSmrg{ 34305b261ecSmrg if (pAction&&(pAction->type==XkbSA_LockGroup)) { 34405b261ecSmrg if (pAction->group.flags&XkbSA_GroupAbsolute) 34505b261ecSmrg xkbi->state.locked_group= XkbSAGroup(&pAction->group); 34605b261ecSmrg else xkbi->state.locked_group+= XkbSAGroup(&pAction->group); 34705b261ecSmrg return 1; 34805b261ecSmrg } 34905b261ecSmrg if (filter->keycode==0) { /* initial press */ 35005b261ecSmrg filter->keycode = keycode; 35105b261ecSmrg filter->active = 1; 35205b261ecSmrg filter->filterOthers = 0; 35305b261ecSmrg filter->priv = 0; 35405b261ecSmrg filter->filter = _XkbFilterLockState; 35505b261ecSmrg filter->upAction = *pAction; 35605b261ecSmrg xkbi->state.locked_mods^= pAction->mods.mask; 35705b261ecSmrg xkbi->setMods = pAction->mods.mask; 35805b261ecSmrg } 35905b261ecSmrg else if (filter->keycode==keycode) { 36005b261ecSmrg filter->active = 0; 36105b261ecSmrg xkbi->clearMods = filter->upAction.mods.mask; 36205b261ecSmrg } 36305b261ecSmrg return 1; 36405b261ecSmrg} 36505b261ecSmrg 36605b261ecSmrg#define ISO_KEY_DOWN 0 36705b261ecSmrg#define NO_ISO_LOCK 1 36805b261ecSmrg 36905b261ecSmrgstatic int 37005b261ecSmrg_XkbFilterISOLock( XkbSrvInfoPtr xkbi, 37105b261ecSmrg XkbFilterPtr filter, 37205b261ecSmrg unsigned keycode, 37305b261ecSmrg XkbAction * pAction) 37405b261ecSmrg{ 37505b261ecSmrg 37605b261ecSmrg if (filter->keycode==0) { /* initial press */ 37705b261ecSmrg CARD8 flags= pAction->iso.flags; 37805b261ecSmrg 37905b261ecSmrg filter->keycode = keycode; 38005b261ecSmrg filter->active = 1; 38105b261ecSmrg filter->filterOthers = 1; 38205b261ecSmrg filter->priv = ISO_KEY_DOWN; 38305b261ecSmrg filter->upAction = *pAction; 38405b261ecSmrg filter->filter = _XkbFilterISOLock; 38505b261ecSmrg if (flags&XkbSA_ISODfltIsGroup) { 38605b261ecSmrg xkbi->groupChange = XkbSAGroup(&pAction->iso); 38705b261ecSmrg xkbi->setMods = 0; 38805b261ecSmrg } 38905b261ecSmrg else { 39005b261ecSmrg xkbi->setMods = pAction->iso.mask; 39105b261ecSmrg xkbi->groupChange = 0; 39205b261ecSmrg } 39305b261ecSmrg if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) { 39405b261ecSmrg filter->priv= NO_ISO_LOCK; 39505b261ecSmrg xkbi->state.locked_mods^= xkbi->state.base_mods; 39605b261ecSmrg } 39705b261ecSmrg if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) { 39805b261ecSmrg/* 6/22/93 (ef) -- lock groups if group key is down first */ 39905b261ecSmrg } 40005b261ecSmrg if (!(flags&XkbSA_ISONoAffectPtr)) { 40105b261ecSmrg/* 6/22/93 (ef) -- lock mouse buttons if they're down */ 40205b261ecSmrg } 40305b261ecSmrg } 40405b261ecSmrg else if (filter->keycode==keycode) { 40505b261ecSmrg CARD8 flags= filter->upAction.iso.flags; 40605b261ecSmrg 40705b261ecSmrg if (flags&XkbSA_ISODfltIsGroup) { 40805b261ecSmrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso); 40905b261ecSmrg xkbi->clearMods = 0; 41005b261ecSmrg if (filter->priv==ISO_KEY_DOWN) 41105b261ecSmrg xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso); 41205b261ecSmrg } 41305b261ecSmrg else { 41405b261ecSmrg xkbi->clearMods= filter->upAction.iso.mask; 41505b261ecSmrg xkbi->groupChange= 0; 41605b261ecSmrg if (filter->priv==ISO_KEY_DOWN) 41705b261ecSmrg xkbi->state.locked_mods^= filter->upAction.iso.mask; 41805b261ecSmrg } 41905b261ecSmrg filter->active = 0; 42005b261ecSmrg } 42105b261ecSmrg else if (pAction) { 42205b261ecSmrg CARD8 flags= filter->upAction.iso.flags; 42305b261ecSmrg 42405b261ecSmrg switch (pAction->type) { 42505b261ecSmrg case XkbSA_SetMods: case XkbSA_LatchMods: 42605b261ecSmrg if (!(flags&XkbSA_ISONoAffectMods)) { 42705b261ecSmrg pAction->type= XkbSA_LockMods; 42805b261ecSmrg filter->priv= NO_ISO_LOCK; 42905b261ecSmrg } 43005b261ecSmrg break; 43105b261ecSmrg case XkbSA_SetGroup: case XkbSA_LatchGroup: 43205b261ecSmrg if (!(flags&XkbSA_ISONoAffectGroup)) { 43305b261ecSmrg pAction->type= XkbSA_LockGroup; 43405b261ecSmrg filter->priv= NO_ISO_LOCK; 43505b261ecSmrg } 43605b261ecSmrg break; 43705b261ecSmrg case XkbSA_PtrBtn: 43805b261ecSmrg if (!(flags&XkbSA_ISONoAffectPtr)) { 43905b261ecSmrg pAction->type= XkbSA_LockPtrBtn; 44005b261ecSmrg filter->priv= NO_ISO_LOCK; 44105b261ecSmrg } 44205b261ecSmrg break; 44305b261ecSmrg case XkbSA_SetControls: 44405b261ecSmrg if (!(flags&XkbSA_ISONoAffectCtrls)) { 44505b261ecSmrg pAction->type= XkbSA_LockControls; 44605b261ecSmrg filter->priv= NO_ISO_LOCK; 44705b261ecSmrg } 44805b261ecSmrg break; 44905b261ecSmrg } 45005b261ecSmrg } 45105b261ecSmrg return 1; 45205b261ecSmrg} 45305b261ecSmrg 45405b261ecSmrg 45505b261ecSmrgstatic CARD32 45605b261ecSmrg_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg) 45705b261ecSmrg{ 45805b261ecSmrgXkbSrvInfoPtr xkbi= (XkbSrvInfoPtr)arg; 45905b261ecSmrgXkbControlsPtr ctrls= xkbi->desc->ctrls; 46005b261ecSmrgint dx,dy; 46105b261ecSmrg 46205b261ecSmrg if (xkbi->mouseKey==0) 46305b261ecSmrg return 0; 46405b261ecSmrg 46505b261ecSmrg if (xkbi->mouseKeysAccel) { 46605b261ecSmrg if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) { 46705b261ecSmrg double step; 46805b261ecSmrg xkbi->mouseKeysCounter++; 46905b261ecSmrg step= xkbi->mouseKeysCurveFactor* 47005b261ecSmrg pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve); 47105b261ecSmrg if (xkbi->mouseKeysDX<0) 47205b261ecSmrg dx= floor( ((double)xkbi->mouseKeysDX)*step ); 47305b261ecSmrg else dx= ceil( ((double)xkbi->mouseKeysDX)*step ); 47405b261ecSmrg if (xkbi->mouseKeysDY<0) 47505b261ecSmrg dy= floor( ((double)xkbi->mouseKeysDY)*step ); 47605b261ecSmrg else dy= ceil( ((double)xkbi->mouseKeysDY)*step ); 47705b261ecSmrg } 47805b261ecSmrg else { 47905b261ecSmrg dx= xkbi->mouseKeysDX*ctrls->mk_max_speed; 48005b261ecSmrg dy= xkbi->mouseKeysDY*ctrls->mk_max_speed; 48105b261ecSmrg } 48205b261ecSmrg if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX) 48305b261ecSmrg dx= xkbi->mouseKeysDX; 48405b261ecSmrg if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY) 48505b261ecSmrg dy= xkbi->mouseKeysDY; 48605b261ecSmrg } 48705b261ecSmrg else { 48805b261ecSmrg dx= xkbi->mouseKeysDX; 48905b261ecSmrg dy= xkbi->mouseKeysDY; 49005b261ecSmrg } 4916747b715Smrg XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy); 49205b261ecSmrg return xkbi->desc->ctrls->mk_interval; 49305b261ecSmrg} 49405b261ecSmrg 49505b261ecSmrgstatic int 49605b261ecSmrg_XkbFilterPointerMove( XkbSrvInfoPtr xkbi, 49705b261ecSmrg XkbFilterPtr filter, 49805b261ecSmrg unsigned keycode, 49905b261ecSmrg XkbAction * pAction) 50005b261ecSmrg{ 50105b261ecSmrgint x,y; 50205b261ecSmrgBool accel; 50305b261ecSmrg 50405b261ecSmrg if (filter->keycode==0) { /* initial press */ 50505b261ecSmrg filter->keycode = keycode; 50605b261ecSmrg filter->active = 1; 50705b261ecSmrg filter->filterOthers = 0; 50805b261ecSmrg filter->priv=0; 50905b261ecSmrg filter->filter = _XkbFilterPointerMove; 51005b261ecSmrg filter->upAction= *pAction; 51105b261ecSmrg xkbi->mouseKeysCounter= 0; 51205b261ecSmrg xkbi->mouseKey= keycode; 51305b261ecSmrg accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0); 51405b261ecSmrg x= XkbPtrActionX(&pAction->ptr); 51505b261ecSmrg y= XkbPtrActionY(&pAction->ptr); 5166747b715Smrg XkbFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y); 51705b261ecSmrg AccessXCancelRepeatKey(xkbi,keycode); 51805b261ecSmrg xkbi->mouseKeysAccel= accel&& 51905b261ecSmrg (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask); 52005b261ecSmrg xkbi->mouseKeysFlags= pAction->ptr.flags; 52105b261ecSmrg xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr); 52205b261ecSmrg xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr); 52305b261ecSmrg xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 52405b261ecSmrg xkbi->desc->ctrls->mk_delay, 52505b261ecSmrg _XkbPtrAccelExpire,(pointer)xkbi); 52605b261ecSmrg } 52705b261ecSmrg else if (filter->keycode==keycode) { 52805b261ecSmrg filter->active = 0; 52905b261ecSmrg if (xkbi->mouseKey==keycode) { 53005b261ecSmrg xkbi->mouseKey= 0; 53105b261ecSmrg xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0, 53205b261ecSmrg NULL, NULL); 53305b261ecSmrg } 53405b261ecSmrg } 53505b261ecSmrg return 0; 53605b261ecSmrg} 53705b261ecSmrg 53805b261ecSmrgstatic int 53905b261ecSmrg_XkbFilterPointerBtn( XkbSrvInfoPtr xkbi, 54005b261ecSmrg XkbFilterPtr filter, 54105b261ecSmrg unsigned keycode, 54205b261ecSmrg XkbAction * pAction) 54305b261ecSmrg{ 54405b261ecSmrg if (filter->keycode==0) { /* initial press */ 54505b261ecSmrg int button= pAction->btn.button; 54605b261ecSmrg 54705b261ecSmrg if (button==XkbSA_UseDfltButton) 54805b261ecSmrg button = xkbi->desc->ctrls->mk_dflt_btn; 54905b261ecSmrg 55005b261ecSmrg filter->keycode = keycode; 55105b261ecSmrg filter->active = 1; 55205b261ecSmrg filter->filterOthers = 0; 55305b261ecSmrg filter->priv=0; 55405b261ecSmrg filter->filter = _XkbFilterPointerBtn; 55505b261ecSmrg filter->upAction= *pAction; 55605b261ecSmrg filter->upAction.btn.button= button; 55705b261ecSmrg switch (pAction->type) { 55805b261ecSmrg case XkbSA_LockPtrBtn: 55905b261ecSmrg if (((xkbi->lockedPtrButtons&(1<<button))==0)&& 56005b261ecSmrg ((pAction->btn.flags&XkbSA_LockNoLock)==0)) { 56105b261ecSmrg xkbi->lockedPtrButtons|= (1<<button); 56205b261ecSmrg AccessXCancelRepeatKey(xkbi,keycode); 5636747b715Smrg XkbFakeDeviceButton(xkbi->device, 1, button); 56405b261ecSmrg filter->upAction.type= XkbSA_NoAction; 56505b261ecSmrg } 56605b261ecSmrg break; 56705b261ecSmrg case XkbSA_PtrBtn: 56805b261ecSmrg { 56905b261ecSmrg register int i,nClicks; 57005b261ecSmrg AccessXCancelRepeatKey(xkbi,keycode); 57105b261ecSmrg if (pAction->btn.count>0) { 57205b261ecSmrg nClicks= pAction->btn.count; 57305b261ecSmrg for (i=0;i<nClicks;i++) { 5746747b715Smrg XkbFakeDeviceButton(xkbi->device, 1, button); 5756747b715Smrg XkbFakeDeviceButton(xkbi->device, 0, button); 57605b261ecSmrg } 57705b261ecSmrg filter->upAction.type= XkbSA_NoAction; 57805b261ecSmrg } 5796747b715Smrg else XkbFakeDeviceButton(xkbi->device, 1, button); 58005b261ecSmrg } 58105b261ecSmrg break; 58205b261ecSmrg case XkbSA_SetPtrDflt: 58305b261ecSmrg { 58405b261ecSmrg XkbControlsPtr ctrls= xkbi->desc->ctrls; 58505b261ecSmrg XkbControlsRec old; 58605b261ecSmrg xkbControlsNotify cn; 58705b261ecSmrg 58805b261ecSmrg old= *ctrls; 58905b261ecSmrg AccessXCancelRepeatKey(xkbi,keycode); 59005b261ecSmrg switch (pAction->dflt.affect) { 59105b261ecSmrg case XkbSA_AffectDfltBtn: 59205b261ecSmrg if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute) 59305b261ecSmrg ctrls->mk_dflt_btn= 59405b261ecSmrg XkbSAPtrDfltValue(&pAction->dflt); 59505b261ecSmrg else { 59605b261ecSmrg ctrls->mk_dflt_btn+= 59705b261ecSmrg XkbSAPtrDfltValue(&pAction->dflt); 59805b261ecSmrg if (ctrls->mk_dflt_btn>5) 59905b261ecSmrg ctrls->mk_dflt_btn= 5; 60005b261ecSmrg else if (ctrls->mk_dflt_btn<1) 60105b261ecSmrg ctrls->mk_dflt_btn= 1; 60205b261ecSmrg } 60305b261ecSmrg break; 60405b261ecSmrg default: 60505b261ecSmrg ErrorF( 60605b261ecSmrg "Attempt to change unknown pointer default (%d) ignored\n", 60705b261ecSmrg pAction->dflt.affect); 60805b261ecSmrg break; 60905b261ecSmrg } 61005b261ecSmrg if (XkbComputeControlsNotify(xkbi->device, 61105b261ecSmrg &old,xkbi->desc->ctrls, 6126747b715Smrg &cn,FALSE)) { 61305b261ecSmrg cn.keycode = keycode; 61405b261ecSmrg /* XXX: what about DeviceKeyPress? */ 61505b261ecSmrg cn.eventType = KeyPress; 61605b261ecSmrg cn.requestMajor = 0; 61705b261ecSmrg cn.requestMinor = 0; 61805b261ecSmrg XkbSendControlsNotify(xkbi->device,&cn); 61905b261ecSmrg } 62005b261ecSmrg } 62105b261ecSmrg break; 62205b261ecSmrg } 62305b261ecSmrg } 62405b261ecSmrg else if (filter->keycode==keycode) { 62505b261ecSmrg int button= filter->upAction.btn.button; 62605b261ecSmrg 62705b261ecSmrg switch (filter->upAction.type) { 62805b261ecSmrg case XkbSA_LockPtrBtn: 62905b261ecSmrg if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)|| 63005b261ecSmrg ((xkbi->lockedPtrButtons&(1<<button))==0)) { 63105b261ecSmrg break; 63205b261ecSmrg } 63305b261ecSmrg xkbi->lockedPtrButtons&= ~(1<<button); 6346747b715Smrg 6356747b715Smrg if (IsMaster(xkbi->device)) 6366747b715Smrg { 6376747b715Smrg XkbMergeLockedPtrBtns(xkbi->device); 6386747b715Smrg /* One SD still has lock set, don't post event */ 6396747b715Smrg if ((xkbi->lockedPtrButtons & (1 << button)) != 0) 6406747b715Smrg break; 6416747b715Smrg } 6426747b715Smrg 6436747b715Smrg /* fallthrough */ 64405b261ecSmrg case XkbSA_PtrBtn: 6456747b715Smrg XkbFakeDeviceButton(xkbi->device, 0, button); 64605b261ecSmrg break; 64705b261ecSmrg } 64805b261ecSmrg filter->active = 0; 64905b261ecSmrg } 65005b261ecSmrg return 0; 65105b261ecSmrg} 65205b261ecSmrg 65305b261ecSmrgstatic int 65405b261ecSmrg_XkbFilterControls( XkbSrvInfoPtr xkbi, 65505b261ecSmrg XkbFilterPtr filter, 65605b261ecSmrg unsigned keycode, 65705b261ecSmrg XkbAction * pAction) 65805b261ecSmrg{ 65905b261ecSmrgXkbControlsRec old; 66005b261ecSmrgXkbControlsPtr ctrls; 66105b261ecSmrgDeviceIntPtr kbd; 66205b261ecSmrgunsigned int change; 66305b261ecSmrgXkbEventCauseRec cause; 66405b261ecSmrg 66505b261ecSmrg kbd= xkbi->device; 66605b261ecSmrg ctrls= xkbi->desc->ctrls; 66705b261ecSmrg old= *ctrls; 66805b261ecSmrg if (filter->keycode==0) { /* initial press */ 66905b261ecSmrg filter->keycode = keycode; 67005b261ecSmrg filter->active = 1; 67105b261ecSmrg filter->filterOthers = 0; 67205b261ecSmrg change= XkbActionCtrls(&pAction->ctrls); 67305b261ecSmrg filter->priv = change; 67405b261ecSmrg filter->filter = _XkbFilterControls; 67505b261ecSmrg filter->upAction = *pAction; 67605b261ecSmrg 67705b261ecSmrg if (pAction->type==XkbSA_LockControls) { 67805b261ecSmrg filter->priv= (ctrls->enabled_ctrls&change); 67905b261ecSmrg change&= ~ctrls->enabled_ctrls; 68005b261ecSmrg } 68105b261ecSmrg 68205b261ecSmrg if (change) { 68305b261ecSmrg xkbControlsNotify cn; 68405b261ecSmrg XkbSrvLedInfoPtr sli; 68505b261ecSmrg 68605b261ecSmrg ctrls->enabled_ctrls|= change; 6876747b715Smrg if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) { 68805b261ecSmrg cn.keycode = keycode; 68905b261ecSmrg /* XXX: what about DeviceKeyPress? */ 69005b261ecSmrg cn.eventType = KeyPress; 69105b261ecSmrg cn.requestMajor = 0; 69205b261ecSmrg cn.requestMinor = 0; 69305b261ecSmrg XkbSendControlsNotify(kbd,&cn); 69405b261ecSmrg } 69505b261ecSmrg 69605b261ecSmrg XkbSetCauseKey(&cause,keycode,KeyPress); 69705b261ecSmrg 69805b261ecSmrg /* If sticky keys were disabled, clear all locks and latches */ 69905b261ecSmrg if ((old.enabled_ctrls&XkbStickyKeysMask)&& 70005b261ecSmrg (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) { 7016747b715Smrg XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause); 70205b261ecSmrg } 70305b261ecSmrg sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); 7046747b715Smrg XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause); 70505b261ecSmrg if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) 70605b261ecSmrg XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change); 70705b261ecSmrg } 70805b261ecSmrg } 70905b261ecSmrg else if (filter->keycode==keycode) { 71005b261ecSmrg change= filter->priv; 71105b261ecSmrg if (change) { 71205b261ecSmrg xkbControlsNotify cn; 71305b261ecSmrg XkbSrvLedInfoPtr sli; 71405b261ecSmrg 71505b261ecSmrg ctrls->enabled_ctrls&= ~change; 7166747b715Smrg if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) { 71705b261ecSmrg cn.keycode = keycode; 71805b261ecSmrg cn.eventType = KeyRelease; 71905b261ecSmrg cn.requestMajor = 0; 72005b261ecSmrg cn.requestMinor = 0; 72105b261ecSmrg XkbSendControlsNotify(kbd,&cn); 72205b261ecSmrg } 72305b261ecSmrg 72405b261ecSmrg XkbSetCauseKey(&cause,keycode,KeyRelease); 72505b261ecSmrg /* If sticky keys were disabled, clear all locks and latches */ 72605b261ecSmrg if ((old.enabled_ctrls&XkbStickyKeysMask)&& 72705b261ecSmrg (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) { 7286747b715Smrg XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause); 72905b261ecSmrg } 73005b261ecSmrg sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); 7316747b715Smrg XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause); 73205b261ecSmrg if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) 73305b261ecSmrg XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change); 73405b261ecSmrg } 73505b261ecSmrg filter->keycode= 0; 73605b261ecSmrg filter->active= 0; 73705b261ecSmrg } 73805b261ecSmrg return 1; 73905b261ecSmrg} 74005b261ecSmrg 74105b261ecSmrgstatic int 74205b261ecSmrg_XkbFilterActionMessage(XkbSrvInfoPtr xkbi, 74305b261ecSmrg XkbFilterPtr filter, 74405b261ecSmrg unsigned keycode, 74505b261ecSmrg XkbAction * pAction) 74605b261ecSmrg{ 74705b261ecSmrgXkbMessageAction * pMsg; 74805b261ecSmrgDeviceIntPtr kbd; 74905b261ecSmrg 75005b261ecSmrg kbd= xkbi->device; 75105b261ecSmrg if (filter->keycode==0) { /* initial press */ 75205b261ecSmrg pMsg= &pAction->msg; 75305b261ecSmrg if ((pMsg->flags&XkbSA_MessageOnRelease)|| 75405b261ecSmrg ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) { 75505b261ecSmrg filter->keycode = keycode; 75605b261ecSmrg filter->active = 1; 75705b261ecSmrg filter->filterOthers = 0; 75805b261ecSmrg filter->priv = 0; 75905b261ecSmrg filter->filter = _XkbFilterActionMessage; 76005b261ecSmrg filter->upAction = *pAction; 76105b261ecSmrg } 76205b261ecSmrg if (pMsg->flags&XkbSA_MessageOnPress) { 76305b261ecSmrg xkbActionMessage msg; 76405b261ecSmrg 76505b261ecSmrg msg.keycode= keycode; 76605b261ecSmrg msg.press= 1; 76705b261ecSmrg msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 76805b261ecSmrg memcpy((char *)msg.message, 76905b261ecSmrg (char *)pMsg->message,XkbActionMessageLength); 77005b261ecSmrg XkbSendActionMessage(kbd,&msg); 77105b261ecSmrg } 77205b261ecSmrg return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0); 77305b261ecSmrg } 77405b261ecSmrg else if (filter->keycode==keycode) { 77505b261ecSmrg pMsg= &filter->upAction.msg; 77605b261ecSmrg if (pMsg->flags&XkbSA_MessageOnRelease) { 77705b261ecSmrg xkbActionMessage msg; 77805b261ecSmrg 77905b261ecSmrg msg.keycode= keycode; 78005b261ecSmrg msg.press= 0; 78105b261ecSmrg msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 78205b261ecSmrg memcpy((char *)msg.message,(char *)pMsg->message, 78305b261ecSmrg XkbActionMessageLength); 78405b261ecSmrg XkbSendActionMessage(kbd,&msg); 78505b261ecSmrg } 78605b261ecSmrg filter->keycode= 0; 78705b261ecSmrg filter->active= 0; 78805b261ecSmrg return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 78905b261ecSmrg } 79005b261ecSmrg return 0; 79105b261ecSmrg} 79205b261ecSmrg 79305b261ecSmrgstatic int 79405b261ecSmrg_XkbFilterRedirectKey( XkbSrvInfoPtr xkbi, 79505b261ecSmrg XkbFilterPtr filter, 79605b261ecSmrg unsigned keycode, 79705b261ecSmrg XkbAction * pAction) 79805b261ecSmrg{ 7996747b715SmrgDeviceEvent ev; 80005b261ecSmrgint x,y; 80105b261ecSmrgXkbStateRec old; 8026747b715Smrgunsigned mods,mask; 80305b261ecSmrgxkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device); 80405b261ecSmrgProcessInputProc backupproc; 80505b261ecSmrg 80605b261ecSmrg /* never actually used uninitialised, but gcc isn't smart enough 80705b261ecSmrg * to work that out. */ 80805b261ecSmrg memset(&old, 0, sizeof(old)); 8096747b715Smrg memset(&ev, 0, sizeof(ev)); 81005b261ecSmrg 81105b261ecSmrg if ((filter->keycode!=0)&&(filter->keycode!=keycode)) 81205b261ecSmrg return 1; 81305b261ecSmrg 8146747b715Smrg GetSpritePosition(xkbi->device, &x,&y); 8156747b715Smrg ev.header = ET_Internal; 8166747b715Smrg ev.length = sizeof(DeviceEvent); 8176747b715Smrg ev.time = GetTimeInMillis(); 8186747b715Smrg ev.root_x = x; 8196747b715Smrg ev.root_y = y; 82005b261ecSmrg 82105b261ecSmrg if (filter->keycode==0) { /* initial press */ 82205b261ecSmrg if ((pAction->redirect.new_key<xkbi->desc->min_key_code)|| 82305b261ecSmrg (pAction->redirect.new_key>xkbi->desc->max_key_code)) { 82405b261ecSmrg return 1; 82505b261ecSmrg } 82605b261ecSmrg filter->keycode = keycode; 82705b261ecSmrg filter->active = 1; 82805b261ecSmrg filter->filterOthers = 0; 82905b261ecSmrg filter->priv = 0; 83005b261ecSmrg filter->filter = _XkbFilterRedirectKey; 83105b261ecSmrg filter->upAction = *pAction; 83205b261ecSmrg 8336747b715Smrg ev.type = ET_KeyPress; 8346747b715Smrg ev.detail.key = pAction->redirect.new_key; 83505b261ecSmrg 83605b261ecSmrg mask= XkbSARedirectVModsMask(&pAction->redirect); 83705b261ecSmrg mods= XkbSARedirectVMods(&pAction->redirect); 83805b261ecSmrg if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask); 83905b261ecSmrg if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods); 84005b261ecSmrg mask|= pAction->redirect.mods_mask; 84105b261ecSmrg mods|= pAction->redirect.mods; 84205b261ecSmrg 84305b261ecSmrg if ( mask || mods ) { 84405b261ecSmrg old= xkbi->state; 84505b261ecSmrg xkbi->state.base_mods&= ~mask; 84605b261ecSmrg xkbi->state.base_mods|= (mods&mask); 84705b261ecSmrg xkbi->state.latched_mods&= ~mask; 84805b261ecSmrg xkbi->state.latched_mods|= (mods&mask); 84905b261ecSmrg xkbi->state.locked_mods&= ~mask; 85005b261ecSmrg xkbi->state.locked_mods|= (mods&mask); 85105b261ecSmrg XkbComputeDerivedState(xkbi); 85205b261ecSmrg } 85305b261ecSmrg 85405b261ecSmrg UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc); 8556747b715Smrg xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device); 85605b261ecSmrg COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, 85705b261ecSmrg backupproc,xkbUnwrapProc); 85805b261ecSmrg 8596747b715Smrg if ( mask || mods ) 86005b261ecSmrg xkbi->state= old; 86105b261ecSmrg } 86205b261ecSmrg else if (filter->keycode==keycode) { 86305b261ecSmrg 8646747b715Smrg ev.type = ET_KeyRelease; 8656747b715Smrg ev.detail.key = filter->upAction.redirect.new_key; 86605b261ecSmrg 86705b261ecSmrg mask= XkbSARedirectVModsMask(&filter->upAction.redirect); 86805b261ecSmrg mods= XkbSARedirectVMods(&filter->upAction.redirect); 86905b261ecSmrg if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask); 87005b261ecSmrg if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods); 87105b261ecSmrg mask|= filter->upAction.redirect.mods_mask; 87205b261ecSmrg mods|= filter->upAction.redirect.mods; 87305b261ecSmrg 87405b261ecSmrg if ( mask || mods ) { 87505b261ecSmrg old= xkbi->state; 87605b261ecSmrg xkbi->state.base_mods&= ~mask; 87705b261ecSmrg xkbi->state.base_mods|= (mods&mask); 87805b261ecSmrg xkbi->state.latched_mods&= ~mask; 87905b261ecSmrg xkbi->state.latched_mods|= (mods&mask); 88005b261ecSmrg xkbi->state.locked_mods&= ~mask; 88105b261ecSmrg xkbi->state.locked_mods|= (mods&mask); 88205b261ecSmrg XkbComputeDerivedState(xkbi); 88305b261ecSmrg } 88405b261ecSmrg 88505b261ecSmrg UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc); 8866747b715Smrg xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device); 88705b261ecSmrg COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, 88805b261ecSmrg backupproc,xkbUnwrapProc); 88905b261ecSmrg 8906747b715Smrg if ( mask || mods ) 89105b261ecSmrg xkbi->state= old; 89205b261ecSmrg 89305b261ecSmrg filter->keycode= 0; 89405b261ecSmrg filter->active= 0; 89505b261ecSmrg } 89605b261ecSmrg return 0; 89705b261ecSmrg} 89805b261ecSmrg 89905b261ecSmrgstatic int 90005b261ecSmrg_XkbFilterSwitchScreen( XkbSrvInfoPtr xkbi, 90105b261ecSmrg XkbFilterPtr filter, 90205b261ecSmrg unsigned keycode, 90305b261ecSmrg XkbAction * pAction) 90405b261ecSmrg{ 90505b261ecSmrg DeviceIntPtr dev = xkbi->device; 90605b261ecSmrg if (dev == inputInfo.keyboard) 90705b261ecSmrg return 0; 90805b261ecSmrg 90905b261ecSmrg if (filter->keycode==0) { /* initial press */ 91005b261ecSmrg filter->keycode = keycode; 91105b261ecSmrg filter->active = 1; 91205b261ecSmrg filter->filterOthers = 0; 91305b261ecSmrg filter->filter = _XkbFilterSwitchScreen; 91405b261ecSmrg AccessXCancelRepeatKey(xkbi, keycode); 91505b261ecSmrg XkbDDXSwitchScreen(dev,keycode,pAction); 91605b261ecSmrg return 0; 91705b261ecSmrg } 91805b261ecSmrg else if (filter->keycode==keycode) { 91905b261ecSmrg filter->active= 0; 92005b261ecSmrg return 0; 92105b261ecSmrg } 92205b261ecSmrg return 1; 92305b261ecSmrg} 92405b261ecSmrg 92505b261ecSmrgstatic int 92605b261ecSmrg_XkbFilterXF86Private( XkbSrvInfoPtr xkbi, 92705b261ecSmrg XkbFilterPtr filter, 92805b261ecSmrg unsigned keycode, 92905b261ecSmrg XkbAction * pAction) 93005b261ecSmrg{ 93105b261ecSmrg DeviceIntPtr dev = xkbi->device; 93205b261ecSmrg if (dev == inputInfo.keyboard) 93305b261ecSmrg return 0; 93405b261ecSmrg 93505b261ecSmrg if (filter->keycode==0) { /* initial press */ 93605b261ecSmrg filter->keycode = keycode; 93705b261ecSmrg filter->active = 1; 93805b261ecSmrg filter->filterOthers = 0; 93905b261ecSmrg filter->filter = _XkbFilterXF86Private; 94005b261ecSmrg XkbDDXPrivate(dev,keycode,pAction); 94105b261ecSmrg return 0; 94205b261ecSmrg } 94305b261ecSmrg else if (filter->keycode==keycode) { 94405b261ecSmrg filter->active= 0; 94505b261ecSmrg return 0; 94605b261ecSmrg } 94705b261ecSmrg return 1; 94805b261ecSmrg} 94905b261ecSmrg 95005b261ecSmrg 95105b261ecSmrgstatic int 95205b261ecSmrg_XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi, 95305b261ecSmrg XkbFilterPtr filter, 95405b261ecSmrg unsigned keycode, 95505b261ecSmrg XkbAction * pAction) 95605b261ecSmrg{ 95705b261ecSmrgDeviceIntPtr dev; 95805b261ecSmrgint button; 95905b261ecSmrg 9604642e01fSmrg if (xkbi->device == inputInfo.keyboard) 96105b261ecSmrg return 0; 96205b261ecSmrg 96305b261ecSmrg if (filter->keycode==0) { /* initial press */ 9644642e01fSmrg _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient, 9654642e01fSmrg DixUnknownAccess, &button); 9666747b715Smrg if (!dev || !dev->public.on) 96705b261ecSmrg return 1; 96805b261ecSmrg 96905b261ecSmrg button= pAction->devbtn.button; 97005b261ecSmrg if ((button<1)||(button>dev->button->numButtons)) 97105b261ecSmrg return 1; 97205b261ecSmrg 97305b261ecSmrg filter->keycode = keycode; 97405b261ecSmrg filter->active = 1; 97505b261ecSmrg filter->filterOthers = 0; 97605b261ecSmrg filter->priv=0; 97705b261ecSmrg filter->filter = _XkbFilterDeviceBtn; 97805b261ecSmrg filter->upAction= *pAction; 97905b261ecSmrg switch (pAction->type) { 98005b261ecSmrg case XkbSA_LockDeviceBtn: 98105b261ecSmrg if ((pAction->devbtn.flags&XkbSA_LockNoLock)|| 9824642e01fSmrg BitIsOn(dev->button->down, button)) 98305b261ecSmrg return 0; 9846747b715Smrg XkbFakeDeviceButton(dev,TRUE,button); 98505b261ecSmrg filter->upAction.type= XkbSA_NoAction; 98605b261ecSmrg break; 98705b261ecSmrg case XkbSA_DeviceBtn: 98805b261ecSmrg if (pAction->devbtn.count>0) { 98905b261ecSmrg int nClicks,i; 99005b261ecSmrg nClicks= pAction->btn.count; 99105b261ecSmrg for (i=0;i<nClicks;i++) { 9926747b715Smrg XkbFakeDeviceButton(dev,TRUE,button); 9936747b715Smrg XkbFakeDeviceButton(dev,FALSE,button); 99405b261ecSmrg } 99505b261ecSmrg filter->upAction.type= XkbSA_NoAction; 99605b261ecSmrg } 9976747b715Smrg else XkbFakeDeviceButton(dev,TRUE,button); 99805b261ecSmrg break; 99905b261ecSmrg } 100005b261ecSmrg } 100105b261ecSmrg else if (filter->keycode==keycode) { 100205b261ecSmrg int button; 100305b261ecSmrg 100405b261ecSmrg filter->active= 0; 10054642e01fSmrg _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device, 10064642e01fSmrg serverClient, DixUnknownAccess, &button); 10076747b715Smrg if (!dev || !dev->public.on) 100805b261ecSmrg return 1; 100905b261ecSmrg 101005b261ecSmrg button= filter->upAction.btn.button; 101105b261ecSmrg switch (filter->upAction.type) { 101205b261ecSmrg case XkbSA_LockDeviceBtn: 101305b261ecSmrg if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)|| 10144642e01fSmrg !BitIsOn(dev->button->down, button)) 101505b261ecSmrg return 0; 10166747b715Smrg XkbFakeDeviceButton(dev,FALSE,button); 101705b261ecSmrg break; 101805b261ecSmrg case XkbSA_DeviceBtn: 10196747b715Smrg XkbFakeDeviceButton(dev,FALSE,button); 102005b261ecSmrg break; 102105b261ecSmrg } 102205b261ecSmrg filter->active = 0; 102305b261ecSmrg } 102405b261ecSmrg return 0; 102505b261ecSmrg} 102605b261ecSmrg 102705b261ecSmrgstatic XkbFilterPtr 102805b261ecSmrg_XkbNextFreeFilter( 102905b261ecSmrg XkbSrvInfoPtr xkbi 103005b261ecSmrg) 103105b261ecSmrg{ 103205b261ecSmrgregister int i; 103305b261ecSmrg 103405b261ecSmrg if (xkbi->szFilters==0) { 103505b261ecSmrg xkbi->szFilters = 4; 10366747b715Smrg xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec)); 103705b261ecSmrg /* 6/21/93 (ef) -- XXX! deal with allocation failure */ 103805b261ecSmrg } 103905b261ecSmrg for (i=0;i<xkbi->szFilters;i++) { 104005b261ecSmrg if (!xkbi->filters[i].active) { 104105b261ecSmrg xkbi->filters[i].keycode = 0; 104205b261ecSmrg return &xkbi->filters[i]; 104305b261ecSmrg } 104405b261ecSmrg } 104505b261ecSmrg xkbi->szFilters*=2; 10466747b715Smrg xkbi->filters= realloc(xkbi->filters, 10476747b715Smrg xkbi->szFilters * sizeof(XkbFilterRec)); 104805b261ecSmrg /* 6/21/93 (ef) -- XXX! deal with allocation failure */ 10496747b715Smrg memset(&xkbi->filters[xkbi->szFilters/2], 0, 105005b261ecSmrg (xkbi->szFilters/2)*sizeof(XkbFilterRec)); 105105b261ecSmrg return &xkbi->filters[xkbi->szFilters/2]; 105205b261ecSmrg} 105305b261ecSmrg 105405b261ecSmrgstatic int 105505b261ecSmrg_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction) 105605b261ecSmrg{ 105705b261ecSmrgregister int i,send; 105805b261ecSmrg 105905b261ecSmrg send= 1; 106005b261ecSmrg for (i=0;i<xkbi->szFilters;i++) { 106105b261ecSmrg if ((xkbi->filters[i].active)&&(xkbi->filters[i].filter)) 106205b261ecSmrg send= ((*xkbi->filters[i].filter)(xkbi,&xkbi->filters[i],kc,pAction) 106305b261ecSmrg && send); 106405b261ecSmrg } 106505b261ecSmrg return send; 106605b261ecSmrg} 106705b261ecSmrg 106805b261ecSmrgvoid 10696747b715SmrgXkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent* event) 107005b261ecSmrg{ 107105b261ecSmrgint key,bit,i; 107205b261ecSmrgXkbSrvInfoPtr xkbi; 107305b261ecSmrgKeyClassPtr keyc; 107405b261ecSmrgint changed,sendEvent; 107505b261ecSmrgBool genStateNotify; 107605b261ecSmrgXkbAction act; 107705b261ecSmrgXkbFilterPtr filter; 107805b261ecSmrgBool keyEvent; 107905b261ecSmrgBool pressEvent; 108005b261ecSmrgProcessInputProc backupproc; 108105b261ecSmrg 108205b261ecSmrgxkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev); 108305b261ecSmrg 108405b261ecSmrg keyc= kbd->key; 108505b261ecSmrg xkbi= keyc->xkbInfo; 10866747b715Smrg key= event->detail.key; 108705b261ecSmrg /* The state may change, so if we're not in the middle of sending a state 108805b261ecSmrg * notify, prepare for it */ 108905b261ecSmrg if ((xkbi->flags&_XkbStateNotifyInProgress)==0) { 10906747b715Smrg xkbi->prev_state = xkbi->state; 109105b261ecSmrg xkbi->flags|= _XkbStateNotifyInProgress; 10926747b715Smrg genStateNotify= TRUE; 109305b261ecSmrg } 10946747b715Smrg else genStateNotify= FALSE; 109505b261ecSmrg 109605b261ecSmrg xkbi->clearMods = xkbi->setMods = 0; 109705b261ecSmrg xkbi->groupChange = 0; 109805b261ecSmrg 109905b261ecSmrg sendEvent = 1; 11006747b715Smrg keyEvent= ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease)); 11016747b715Smrg pressEvent= ((event->type == ET_KeyPress)|| (event->type == ET_ButtonPress)); 110205b261ecSmrg 110305b261ecSmrg if (pressEvent) { 110405b261ecSmrg if (keyEvent) 110505b261ecSmrg act = XkbGetKeyAction(xkbi,&xkbi->state,key); 110605b261ecSmrg else { 110705b261ecSmrg act = XkbGetButtonAction(kbd,dev,key); 110805b261ecSmrg key|= BTN_ACT_FLAG; 110905b261ecSmrg } 111005b261ecSmrg sendEvent = _XkbApplyFilters(xkbi,key,&act); 111105b261ecSmrg if (sendEvent) { 111205b261ecSmrg switch (act.type) { 111305b261ecSmrg case XkbSA_SetMods: 111405b261ecSmrg case XkbSA_SetGroup: 111505b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 111605b261ecSmrg sendEvent = _XkbFilterSetState(xkbi,filter,key,&act); 111705b261ecSmrg break; 111805b261ecSmrg case XkbSA_LatchMods: 111905b261ecSmrg case XkbSA_LatchGroup: 112005b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 112105b261ecSmrg sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act); 112205b261ecSmrg break; 112305b261ecSmrg case XkbSA_LockMods: 112405b261ecSmrg case XkbSA_LockGroup: 112505b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 112605b261ecSmrg sendEvent=_XkbFilterLockState(xkbi,filter,key,&act); 112705b261ecSmrg break; 112805b261ecSmrg case XkbSA_ISOLock: 112905b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 113005b261ecSmrg sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act); 113105b261ecSmrg break; 113205b261ecSmrg case XkbSA_MovePtr: 113305b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 113405b261ecSmrg sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act); 113505b261ecSmrg break; 113605b261ecSmrg case XkbSA_PtrBtn: 113705b261ecSmrg case XkbSA_LockPtrBtn: 113805b261ecSmrg case XkbSA_SetPtrDflt: 113905b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 114005b261ecSmrg sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act); 114105b261ecSmrg break; 114205b261ecSmrg case XkbSA_Terminate: 114305b261ecSmrg sendEvent= XkbDDXTerminateServer(dev,key,&act); 114405b261ecSmrg break; 114505b261ecSmrg case XkbSA_SwitchScreen: 114605b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 114705b261ecSmrg sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act); 114805b261ecSmrg break; 114905b261ecSmrg case XkbSA_SetControls: 115005b261ecSmrg case XkbSA_LockControls: 115105b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 115205b261ecSmrg sendEvent=_XkbFilterControls(xkbi,filter,key,&act); 115305b261ecSmrg break; 115405b261ecSmrg case XkbSA_ActionMessage: 115505b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 115605b261ecSmrg sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act); 115705b261ecSmrg break; 115805b261ecSmrg case XkbSA_RedirectKey: 115905b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 116005b261ecSmrg sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act); 116105b261ecSmrg break; 116205b261ecSmrg case XkbSA_DeviceBtn: 116305b261ecSmrg case XkbSA_LockDeviceBtn: 116405b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 116505b261ecSmrg sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act); 116605b261ecSmrg break; 116705b261ecSmrg case XkbSA_XFree86Private: 116805b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 116905b261ecSmrg sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act); 117005b261ecSmrg break; 117105b261ecSmrg } 117205b261ecSmrg } 117305b261ecSmrg } 117405b261ecSmrg else { 117505b261ecSmrg if (!keyEvent) 117605b261ecSmrg key|= BTN_ACT_FLAG; 117705b261ecSmrg sendEvent = _XkbApplyFilters(xkbi,key,NULL); 117805b261ecSmrg } 117905b261ecSmrg 118005b261ecSmrg if (xkbi->groupChange!=0) 118105b261ecSmrg xkbi->state.base_group+= xkbi->groupChange; 118205b261ecSmrg if (xkbi->setMods) { 118305b261ecSmrg for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) { 118405b261ecSmrg if (xkbi->setMods&bit) { 118505b261ecSmrg keyc->modifierKeyCount[i]++; 118605b261ecSmrg xkbi->state.base_mods|= bit; 118705b261ecSmrg xkbi->setMods&= ~bit; 118805b261ecSmrg } 118905b261ecSmrg } 119005b261ecSmrg } 119105b261ecSmrg if (xkbi->clearMods) { 119205b261ecSmrg for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) { 119305b261ecSmrg if (xkbi->clearMods&bit) { 119405b261ecSmrg keyc->modifierKeyCount[i]--; 119505b261ecSmrg if (keyc->modifierKeyCount[i]<=0) { 119605b261ecSmrg xkbi->state.base_mods&= ~bit; 119705b261ecSmrg keyc->modifierKeyCount[i] = 0; 119805b261ecSmrg } 119905b261ecSmrg xkbi->clearMods&= ~bit; 120005b261ecSmrg } 120105b261ecSmrg } 120205b261ecSmrg } 120305b261ecSmrg 120405b261ecSmrg if (sendEvent) { 12054642e01fSmrg DeviceIntPtr tmpdev; 12066747b715Smrg if (keyEvent) 12074642e01fSmrg tmpdev = dev; 12086747b715Smrg else 12094642e01fSmrg tmpdev = GetPairedDevice(dev); 121005b261ecSmrg 12114642e01fSmrg UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc); 12126747b715Smrg dev->public.processInputProc((InternalEvent*)event, tmpdev); 12134642e01fSmrg COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, 121405b261ecSmrg backupproc,xkbUnwrapProc); 121505b261ecSmrg } 121605b261ecSmrg else if (keyEvent) { 12176747b715Smrg FixKeyState(event, dev); 121805b261ecSmrg } 121905b261ecSmrg 122005b261ecSmrg XkbComputeDerivedState(xkbi); 12216747b715Smrg changed = XkbStateChangedFlags(&xkbi->prev_state,&xkbi->state); 122205b261ecSmrg if (genStateNotify) { 122305b261ecSmrg if (changed) { 122405b261ecSmrg xkbStateNotify sn; 122505b261ecSmrg sn.keycode= key; 12266747b715Smrg sn.eventType= event->type; 122705b261ecSmrg sn.requestMajor = sn.requestMinor = 0; 122805b261ecSmrg sn.changed= changed; 122905b261ecSmrg XkbSendStateNotify(dev,&sn); 123005b261ecSmrg } 123105b261ecSmrg xkbi->flags&= ~_XkbStateNotifyInProgress; 123205b261ecSmrg } 12336747b715Smrg changed= XkbIndicatorsToUpdate(dev,changed,FALSE); 123405b261ecSmrg if (changed) { 123505b261ecSmrg XkbEventCauseRec cause; 12366747b715Smrg XkbSetCauseKey(&cause, key, event->type); 12376747b715Smrg XkbUpdateIndicators(dev,changed,FALSE,NULL,&cause); 123805b261ecSmrg } 123905b261ecSmrg return; 124005b261ecSmrg} 124105b261ecSmrg 124205b261ecSmrgint 124305b261ecSmrgXkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches) 124405b261ecSmrg{ 124505b261ecSmrgXkbSrvInfoPtr xkbi; 124605b261ecSmrgXkbFilterPtr filter; 124705b261ecSmrgXkbAction act; 124805b261ecSmrgunsigned clear; 124905b261ecSmrg 125005b261ecSmrg if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) { 125105b261ecSmrg xkbi = pXDev->key->xkbInfo; 125205b261ecSmrg clear= (mask&(~latches)); 125305b261ecSmrg xkbi->state.latched_mods&= ~clear; 125405b261ecSmrg /* Clear any pending latch to locks. 125505b261ecSmrg */ 125605b261ecSmrg act.type = XkbSA_NoAction; 125705b261ecSmrg _XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act); 125805b261ecSmrg act.type = XkbSA_LatchMods; 125905b261ecSmrg act.mods.flags = 0; 126005b261ecSmrg act.mods.mask = mask&latches; 126105b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 126205b261ecSmrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act); 126305b261ecSmrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL); 126405b261ecSmrg return Success; 126505b261ecSmrg } 126605b261ecSmrg return BadValue; 126705b261ecSmrg} 126805b261ecSmrg 126905b261ecSmrgint 127005b261ecSmrgXkbLatchGroup(DeviceIntPtr pXDev,int group) 127105b261ecSmrg{ 127205b261ecSmrgXkbSrvInfoPtr xkbi; 127305b261ecSmrgXkbFilterPtr filter; 127405b261ecSmrgXkbAction act; 127505b261ecSmrg 127605b261ecSmrg if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) { 127705b261ecSmrg xkbi = pXDev->key->xkbInfo; 127805b261ecSmrg act.type = XkbSA_LatchGroup; 127905b261ecSmrg act.group.flags = 0; 128005b261ecSmrg XkbSASetGroup(&act.group,group); 128105b261ecSmrg filter = _XkbNextFreeFilter(xkbi); 128205b261ecSmrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act); 128305b261ecSmrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL); 128405b261ecSmrg return Success; 128505b261ecSmrg } 128605b261ecSmrg return BadValue; 128705b261ecSmrg} 128805b261ecSmrg 128905b261ecSmrg/***====================================================================***/ 129005b261ecSmrg 129105b261ecSmrgvoid 129205b261ecSmrgXkbClearAllLatchesAndLocks( DeviceIntPtr dev, 129305b261ecSmrg XkbSrvInfoPtr xkbi, 129405b261ecSmrg Bool genEv, 129505b261ecSmrg XkbEventCausePtr cause) 129605b261ecSmrg{ 129705b261ecSmrgXkbStateRec os; 129805b261ecSmrgxkbStateNotify sn; 129905b261ecSmrg 130005b261ecSmrg sn.changed= 0; 130105b261ecSmrg os= xkbi->state; 130205b261ecSmrg if (os.latched_mods) { /* clear all latches */ 130305b261ecSmrg XkbLatchModifiers(dev,~0,0); 130405b261ecSmrg sn.changed|= XkbModifierLatchMask; 130505b261ecSmrg } 130605b261ecSmrg if (os.latched_group) { 130705b261ecSmrg XkbLatchGroup(dev,0); 130805b261ecSmrg sn.changed|= XkbGroupLatchMask; 130905b261ecSmrg } 131005b261ecSmrg if (os.locked_mods) { 131105b261ecSmrg xkbi->state.locked_mods= 0; 131205b261ecSmrg sn.changed|= XkbModifierLockMask; 131305b261ecSmrg } 131405b261ecSmrg if (os.locked_group) { 131505b261ecSmrg xkbi->state.locked_group= 0; 131605b261ecSmrg sn.changed|= XkbGroupLockMask; 131705b261ecSmrg } 131805b261ecSmrg if ( genEv && sn.changed) { 131905b261ecSmrg CARD32 changed; 132005b261ecSmrg 132105b261ecSmrg XkbComputeDerivedState(xkbi); 132205b261ecSmrg sn.keycode= cause->kc; 132305b261ecSmrg sn.eventType= cause->event; 132405b261ecSmrg sn.requestMajor= cause->mjr; 132505b261ecSmrg sn.requestMinor= cause->mnr; 132605b261ecSmrg sn.changed= XkbStateChangedFlags(&os,&xkbi->state); 132705b261ecSmrg XkbSendStateNotify(dev,&sn); 13286747b715Smrg changed= XkbIndicatorsToUpdate(dev,sn.changed,FALSE); 132905b261ecSmrg if (changed) { 13306747b715Smrg XkbUpdateIndicators(dev,changed,TRUE,NULL,cause); 133105b261ecSmrg } 133205b261ecSmrg } 133305b261ecSmrg return; 133405b261ecSmrg} 133505b261ecSmrg 13366747b715Smrg/* 13376747b715Smrg * The event is injected into the event processing, not the EQ. Thus, 13386747b715Smrg * ensure that we restore the master after the event sequence to the 13396747b715Smrg * original set of classes. Otherwise, the master remains on the XTEST 13406747b715Smrg * classes and drops events that don't fit into the XTEST layout (e.g. 13416747b715Smrg * events with more than 2 valuators). 13426747b715Smrg * 13436747b715Smrg * FIXME: EQ injection in the processing stage is not designed for, so this 13446747b715Smrg * is a rather awkward hack. The event list returned by GetPointerEvents() 13456747b715Smrg * and friends is always prefixed with a DCE if the last _posted_ device was 13466747b715Smrg * different. For normal events, this sequence then resets the master during 13476747b715Smrg * the processing stage. Since we inject the PointerKey events in the 13486747b715Smrg * processing stage though, we need to manually reset to restore the 13496747b715Smrg * previous order, because the events already in the EQ must be sent for the 13506747b715Smrg * right device. 13516747b715Smrg * So we post-fix the event list we get from GPE with a DCE back to the 13526747b715Smrg * previous slave device. 13536747b715Smrg * 13546747b715Smrg * First one on drinking island wins! 13556747b715Smrg */ 13566747b715Smrgstatic void 13576747b715SmrgInjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, int num_valuators, int *valuators) 13586747b715Smrg{ 13596747b715Smrg ScreenPtr pScreen; 13606747b715Smrg EventListPtr events; 13616747b715Smrg int nevents, i; 13626747b715Smrg DeviceIntPtr ptr, mpointer, lastSlave = NULL; 13636747b715Smrg Bool saveWait; 13646747b715Smrg 13656747b715Smrg if (IsMaster(dev)) { 13666747b715Smrg mpointer = GetMaster(dev, MASTER_POINTER); 13676747b715Smrg lastSlave = mpointer->u.lastSlave; 13686747b715Smrg ptr = GetXTestDevice(mpointer); 13696747b715Smrg } else if (!dev->u.master) 13706747b715Smrg ptr = dev; 13716747b715Smrg else 13726747b715Smrg return; 13736747b715Smrg 13746747b715Smrg 13756747b715Smrg events = InitEventList(GetMaximumEventsNum() + 1); 13766747b715Smrg OsBlockSignals(); 13776747b715Smrg pScreen = miPointerGetScreen(ptr); 13786747b715Smrg saveWait = miPointerSetWaitForUpdate(pScreen, FALSE); 13796747b715Smrg nevents = GetPointerEvents(events, ptr, type, button, flags, 0, 13806747b715Smrg num_valuators, valuators); 13816747b715Smrg if (IsMaster(dev) && (lastSlave && lastSlave != ptr)) 13826747b715Smrg UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT, &nevents); 13836747b715Smrg miPointerSetWaitForUpdate(pScreen, saveWait); 13846747b715Smrg OsReleaseSignals(); 13856747b715Smrg 13866747b715Smrg for (i = 0; i < nevents; i++) 13876747b715Smrg mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL); 13886747b715Smrg 13896747b715Smrg FreeEventList(events, GetMaximumEventsNum()); 13906747b715Smrg 13916747b715Smrg} 13926747b715Smrg 13936747b715Smrgstatic void 13946747b715SmrgXkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y) 13956747b715Smrg{ 13966747b715Smrg int gpe_flags = 0; 13976747b715Smrg 13986747b715Smrg /* ignore attached SDs */ 13996747b715Smrg if (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) != NULL) 14006747b715Smrg return; 14016747b715Smrg 14026747b715Smrg if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY) 14036747b715Smrg gpe_flags = POINTER_ABSOLUTE; 14046747b715Smrg else 14056747b715Smrg gpe_flags = POINTER_RELATIVE; 14066747b715Smrg 14076747b715Smrg InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, 2, (int[]){x, y}); 14086747b715Smrg} 14096747b715Smrg 14106747b715Smrgvoid 14116747b715SmrgXkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button) 14126747b715Smrg{ 14136747b715Smrg DeviceIntPtr ptr; 14146747b715Smrg int down; 14156747b715Smrg 14166747b715Smrg /* If dev is a slave device, and the SD is attached, do nothing. If we'd 14176747b715Smrg * post through the attached master pointer we'd get duplicate events. 14186747b715Smrg * 14196747b715Smrg * if dev is a master keyboard, post through the XTEST device 14206747b715Smrg * 14216747b715Smrg * if dev is a floating slave, post through the device itself. 14226747b715Smrg */ 14236747b715Smrg 14246747b715Smrg if (IsMaster(dev)) { 14256747b715Smrg DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER); 14266747b715Smrg ptr = GetXTestDevice(mpointer); 14276747b715Smrg } else if (!dev->u.master) 14286747b715Smrg ptr = dev; 14296747b715Smrg else 14306747b715Smrg return; 14316747b715Smrg 14326747b715Smrg down = button_is_down(ptr, button, BUTTON_PROCESSED); 14336747b715Smrg if (press == down) 14346747b715Smrg return; 14356747b715Smrg 14366747b715Smrg InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease, 14376747b715Smrg button, 0, 0, NULL); 14386747b715Smrg} 1439