1706f2543Smrg/************************************************************ 2706f2543SmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 3706f2543Smrg 4706f2543SmrgPermission to use, copy, modify, and distribute this 5706f2543Smrgsoftware and its documentation for any purpose and without 6706f2543Smrgfee is hereby granted, provided that the above copyright 7706f2543Smrgnotice appear in all copies and that both that copyright 8706f2543Smrgnotice and this permission notice appear in supporting 9706f2543Smrgdocumentation, and that the name of Silicon Graphics not be 10706f2543Smrgused in advertising or publicity pertaining to distribution 11706f2543Smrgof the software without specific prior written permission. 12706f2543SmrgSilicon Graphics makes no representation about the suitability 13706f2543Smrgof this software for any purpose. It is provided "as is" 14706f2543Smrgwithout any express or implied warranty. 15706f2543Smrg 16706f2543SmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17706f2543SmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18706f2543SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19706f2543SmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20706f2543SmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21706f2543SmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22706f2543SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23706f2543SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 24706f2543Smrg 25706f2543Smrg********************************************************/ 26706f2543Smrg 27706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 28706f2543Smrg#include <dix-config.h> 29706f2543Smrg#endif 30706f2543Smrg 31706f2543Smrg#include <stdio.h> 32706f2543Smrg#include <math.h> 33706f2543Smrg#include <X11/X.h> 34706f2543Smrg#include <X11/Xproto.h> 35706f2543Smrg#include <X11/keysym.h> 36706f2543Smrg#include "misc.h" 37706f2543Smrg#include "inputstr.h" 38706f2543Smrg#include "exevents.h" 39706f2543Smrg#include "eventstr.h" 40706f2543Smrg#include <xkbsrv.h> 41706f2543Smrg#include "xkb.h" 42706f2543Smrg#include <ctype.h> 43706f2543Smrg#include "mi.h" 44706f2543Smrg#include "mipointer.h" 45706f2543Smrg#include "inpututils.h" 46706f2543Smrg#define EXTENSION_EVENT_BASE 64 47706f2543Smrg 48706f2543SmrgDevPrivateKeyRec xkbDevicePrivateKeyRec; 49706f2543Smrg 50706f2543Smrgvoid XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button); 51706f2543Smrgstatic void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y); 52706f2543Smrg 53706f2543Smrgvoid 54706f2543SmrgxkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, 55706f2543Smrg pointer data) 56706f2543Smrg{ 57706f2543Smrg xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device); 58706f2543Smrg ProcessInputProc backupproc; 59706f2543Smrg if(xkbPrivPtr->unwrapProc) 60706f2543Smrg xkbPrivPtr->unwrapProc = NULL; 61706f2543Smrg 62706f2543Smrg UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc); 63706f2543Smrg proc(device,data); 64706f2543Smrg COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, 65706f2543Smrg backupproc,xkbUnwrapProc); 66706f2543Smrg} 67706f2543Smrg 68706f2543SmrgBool 69706f2543SmrgXkbInitPrivates(void) 70706f2543Smrg{ 71706f2543Smrg return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec, PRIVATE_DEVICE, sizeof(xkbDeviceInfoRec)); 72706f2543Smrg} 73706f2543Smrg 74706f2543Smrgvoid 75706f2543SmrgXkbSetExtension(DeviceIntPtr device, ProcessInputProc proc) 76706f2543Smrg{ 77706f2543Smrg xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device); 78706f2543Smrg WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc); 79706f2543Smrg} 80706f2543Smrg 81706f2543Smrg/***====================================================================***/ 82706f2543Smrg 83706f2543Smrgstatic XkbAction 84706f2543Smrg_FixUpAction(XkbDescPtr xkb,XkbAction *act) 85706f2543Smrg{ 86706f2543Smrgstatic XkbAction fake; 87706f2543Smrg 88706f2543Smrg if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) { 89706f2543Smrg fake.type = XkbSA_NoAction; 90706f2543Smrg return fake; 91706f2543Smrg } 92706f2543Smrg if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) { 93706f2543Smrg if (act->any.type==XkbSA_SetMods) { 94706f2543Smrg fake.mods.type = XkbSA_LatchMods; 95706f2543Smrg fake.mods.mask = act->mods.mask; 96706f2543Smrg if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask)) 97706f2543Smrg fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock; 98706f2543Smrg else fake.mods.flags= XkbSA_ClearLocks; 99706f2543Smrg return fake; 100706f2543Smrg } 101706f2543Smrg if (act->any.type==XkbSA_SetGroup) { 102706f2543Smrg fake.group.type = XkbSA_LatchGroup; 103706f2543Smrg if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask)) 104706f2543Smrg fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock; 105706f2543Smrg else fake.group.flags= XkbSA_ClearLocks; 106706f2543Smrg XkbSASetGroup(&fake.group,XkbSAGroup(&act->group)); 107706f2543Smrg return fake; 108706f2543Smrg } 109706f2543Smrg } 110706f2543Smrg return *act; 111706f2543Smrg} 112706f2543Smrg 113706f2543Smrgstatic XkbAction 114706f2543SmrgXkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key) 115706f2543Smrg{ 116706f2543Smrgint effectiveGroup; 117706f2543Smrgint col; 118706f2543SmrgXkbDescPtr xkb; 119706f2543SmrgXkbKeyTypePtr type; 120706f2543SmrgXkbAction * pActs; 121706f2543Smrgstatic XkbAction fake; 122706f2543Smrg 123706f2543Smrg xkb= xkbi->desc; 124706f2543Smrg if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) { 125706f2543Smrg fake.type = XkbSA_NoAction; 126706f2543Smrg return fake; 127706f2543Smrg } 128706f2543Smrg pActs= XkbKeyActionsPtr(xkb,key); 129706f2543Smrg col= 0; 130706f2543Smrg 131706f2543Smrg effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key); 132706f2543Smrg if (effectiveGroup != XkbGroup1Index) 133706f2543Smrg col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key)); 134706f2543Smrg 135706f2543Smrg type= XkbKeyKeyType(xkb,key,effectiveGroup); 136706f2543Smrg if (type->map!=NULL) { 137706f2543Smrg register unsigned i,mods; 138706f2543Smrg register XkbKTMapEntryPtr entry; 139706f2543Smrg mods= xkbState->mods&type->mods.mask; 140706f2543Smrg for (entry= type->map,i=0;i<type->map_count;i++,entry++) { 141706f2543Smrg if ((entry->active)&&(entry->mods.mask==mods)) { 142706f2543Smrg col+= entry->level; 143706f2543Smrg break; 144706f2543Smrg } 145706f2543Smrg } 146706f2543Smrg } 147706f2543Smrg if (pActs[col].any.type==XkbSA_NoAction) 148706f2543Smrg return pActs[col]; 149706f2543Smrg fake= _FixUpAction(xkb,&pActs[col]); 150706f2543Smrg return fake; 151706f2543Smrg} 152706f2543Smrg 153706f2543Smrgstatic XkbAction 154706f2543SmrgXkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button) 155706f2543Smrg{ 156706f2543SmrgXkbAction fake; 157706f2543Smrg if ((dev->button)&&(dev->button->xkb_acts)) { 158706f2543Smrg if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) { 159706f2543Smrg fake= _FixUpAction(kbd->key->xkbInfo->desc, 160706f2543Smrg &dev->button->xkb_acts[button-1]); 161706f2543Smrg return fake; 162706f2543Smrg } 163706f2543Smrg } 164706f2543Smrg fake.any.type= XkbSA_NoAction; 165706f2543Smrg return fake; 166706f2543Smrg} 167706f2543Smrg 168706f2543Smrg/***====================================================================***/ 169706f2543Smrg 170706f2543Smrg#define SYNTHETIC_KEYCODE 1 171706f2543Smrg#define BTN_ACT_FLAG 0x100 172706f2543Smrg 173706f2543Smrgstatic int 174706f2543Smrg_XkbFilterSetState( XkbSrvInfoPtr xkbi, 175706f2543Smrg XkbFilterPtr filter, 176706f2543Smrg unsigned keycode, 177706f2543Smrg XkbAction *pAction) 178706f2543Smrg{ 179706f2543Smrg if (filter->keycode==0) { /* initial press */ 180706f2543Smrg filter->keycode = keycode; 181706f2543Smrg filter->active = 1; 182706f2543Smrg filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0); 183706f2543Smrg filter->priv = 0; 184706f2543Smrg filter->filter = _XkbFilterSetState; 185706f2543Smrg if (pAction->type==XkbSA_SetMods) { 186706f2543Smrg filter->upAction = *pAction; 187706f2543Smrg xkbi->setMods= pAction->mods.mask; 188706f2543Smrg } 189706f2543Smrg else { 190706f2543Smrg xkbi->groupChange = XkbSAGroup(&pAction->group); 191706f2543Smrg if (pAction->group.flags&XkbSA_GroupAbsolute) 192706f2543Smrg xkbi->groupChange-= xkbi->state.base_group; 193706f2543Smrg filter->upAction= *pAction; 194706f2543Smrg XkbSASetGroup(&filter->upAction.group,xkbi->groupChange); 195706f2543Smrg } 196706f2543Smrg } 197706f2543Smrg else if (filter->keycode==keycode) { 198706f2543Smrg if (filter->upAction.type==XkbSA_SetMods) { 199706f2543Smrg xkbi->clearMods = filter->upAction.mods.mask; 200706f2543Smrg if (filter->upAction.mods.flags&XkbSA_ClearLocks) { 201706f2543Smrg xkbi->state.locked_mods&= ~filter->upAction.mods.mask; 202706f2543Smrg } 203706f2543Smrg } 204706f2543Smrg else { 205706f2543Smrg if (filter->upAction.group.flags&XkbSA_ClearLocks) { 206706f2543Smrg xkbi->state.locked_group = 0; 207706f2543Smrg } 208706f2543Smrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); 209706f2543Smrg } 210706f2543Smrg filter->active = 0; 211706f2543Smrg } 212706f2543Smrg else { 213706f2543Smrg filter->upAction.mods.flags&= ~XkbSA_ClearLocks; 214706f2543Smrg filter->filterOthers = 0; 215706f2543Smrg } 216706f2543Smrg return 1; 217706f2543Smrg} 218706f2543Smrg 219706f2543Smrg#define LATCH_KEY_DOWN 1 220706f2543Smrg#define LATCH_PENDING 2 221706f2543Smrg#define NO_LATCH 3 222706f2543Smrg 223706f2543Smrgstatic int 224706f2543Smrg_XkbFilterLatchState( XkbSrvInfoPtr xkbi, 225706f2543Smrg XkbFilterPtr filter, 226706f2543Smrg unsigned keycode, 227706f2543Smrg XkbAction * pAction) 228706f2543Smrg{ 229706f2543Smrg 230706f2543Smrg if (filter->keycode==0) { /* initial press */ 231706f2543Smrg filter->keycode = keycode; 232706f2543Smrg filter->active = 1; 233706f2543Smrg filter->filterOthers = 1; 234706f2543Smrg filter->priv = LATCH_KEY_DOWN; 235706f2543Smrg filter->filter = _XkbFilterLatchState; 236706f2543Smrg if (pAction->type==XkbSA_LatchMods) { 237706f2543Smrg filter->upAction = *pAction; 238706f2543Smrg xkbi->setMods = pAction->mods.mask; 239706f2543Smrg } 240706f2543Smrg else { 241706f2543Smrg xkbi->groupChange = XkbSAGroup(&pAction->group); 242706f2543Smrg if (pAction->group.flags&XkbSA_GroupAbsolute) 243706f2543Smrg xkbi->groupChange-= xkbi->state.base_group; 244706f2543Smrg filter->upAction= *pAction; 245706f2543Smrg XkbSASetGroup(&filter->upAction.group,xkbi->groupChange); 246706f2543Smrg } 247706f2543Smrg } 248706f2543Smrg else if ( pAction && (filter->priv==LATCH_PENDING) ) { 249706f2543Smrg if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) { 250706f2543Smrg filter->active = 0; 251706f2543Smrg if (filter->upAction.type==XkbSA_LatchMods) 252706f2543Smrg xkbi->state.latched_mods&= ~filter->upAction.mods.mask; 253706f2543Smrg else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group); 254706f2543Smrg } 255706f2543Smrg else if ((pAction->type==filter->upAction.type)&& 256706f2543Smrg (pAction->mods.flags==filter->upAction.mods.flags)&& 257706f2543Smrg (pAction->mods.mask==filter->upAction.mods.mask)) { 258706f2543Smrg if (filter->upAction.mods.flags&XkbSA_LatchToLock) { 259706f2543Smrg XkbControlsPtr ctrls= xkbi->desc->ctrls; 260706f2543Smrg if (filter->upAction.type==XkbSA_LatchMods) 261706f2543Smrg pAction->mods.type= XkbSA_LockMods; 262706f2543Smrg else pAction->group.type= XkbSA_LockGroup; 263706f2543Smrg if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&& 264706f2543Smrg (ctrls->enabled_ctrls&XkbStickyKeysMask)) { 265706f2543Smrg XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK, 266706f2543Smrg XkbStickyKeysMask); 267706f2543Smrg } 268706f2543Smrg } 269706f2543Smrg else { 270706f2543Smrg if (filter->upAction.type==XkbSA_LatchMods) 271706f2543Smrg pAction->mods.type= XkbSA_SetMods; 272706f2543Smrg else pAction->group.type= XkbSA_SetGroup; 273706f2543Smrg } 274706f2543Smrg if (filter->upAction.type==XkbSA_LatchMods) 275706f2543Smrg xkbi->state.latched_mods&= ~filter->upAction.mods.mask; 276706f2543Smrg else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group); 277706f2543Smrg filter->active = 0; 278706f2543Smrg } 279706f2543Smrg } 280706f2543Smrg else if (filter->keycode==keycode) { /* release */ 281706f2543Smrg XkbControlsPtr ctrls= xkbi->desc->ctrls; 282706f2543Smrg int needBeep; 283706f2543Smrg int beepType= _BEEP_NONE; 284706f2543Smrg 285706f2543Smrg needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&& 286706f2543Smrg XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)); 287706f2543Smrg if (filter->upAction.type==XkbSA_LatchMods) { 288706f2543Smrg xkbi->clearMods = filter->upAction.mods.mask; 289706f2543Smrg if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&& 290706f2543Smrg (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) { 291706f2543Smrg xkbi->state.locked_mods&= ~xkbi->clearMods; 292706f2543Smrg filter->priv= NO_LATCH; 293706f2543Smrg beepType= _BEEP_STICKY_UNLOCK; 294706f2543Smrg } 295706f2543Smrg } 296706f2543Smrg else { 297706f2543Smrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); 298706f2543Smrg if ((filter->upAction.group.flags&XkbSA_ClearLocks)&& 299706f2543Smrg (xkbi->state.locked_group)) { 300706f2543Smrg xkbi->state.locked_group = 0; 301706f2543Smrg filter->priv = NO_LATCH; 302706f2543Smrg beepType= _BEEP_STICKY_UNLOCK; 303706f2543Smrg } 304706f2543Smrg } 305706f2543Smrg if (filter->priv==NO_LATCH) { 306706f2543Smrg filter->active= 0; 307706f2543Smrg } 308706f2543Smrg else { 309706f2543Smrg filter->priv= LATCH_PENDING; 310706f2543Smrg if (filter->upAction.type==XkbSA_LatchMods) { 311706f2543Smrg xkbi->state.latched_mods |= filter->upAction.mods.mask; 312706f2543Smrg needBeep = xkbi->state.latched_mods ? needBeep : 0; 313706f2543Smrg xkbi->state.latched_mods |= filter->upAction.mods.mask; 314706f2543Smrg } 315706f2543Smrg else { 316706f2543Smrg xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group); 317706f2543Smrg } 318706f2543Smrg if (needBeep && (beepType==_BEEP_NONE)) 319706f2543Smrg beepType= _BEEP_STICKY_LATCH; 320706f2543Smrg } 321706f2543Smrg if (needBeep && (beepType!=_BEEP_NONE)) 322706f2543Smrg XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask); 323706f2543Smrg } 324706f2543Smrg else if (filter->priv==LATCH_KEY_DOWN) { 325706f2543Smrg filter->priv= NO_LATCH; 326706f2543Smrg filter->filterOthers = 0; 327706f2543Smrg } 328706f2543Smrg return 1; 329706f2543Smrg} 330706f2543Smrg 331706f2543Smrgstatic int 332706f2543Smrg_XkbFilterLockState( XkbSrvInfoPtr xkbi, 333706f2543Smrg XkbFilterPtr filter, 334706f2543Smrg unsigned keycode, 335706f2543Smrg XkbAction * pAction) 336706f2543Smrg{ 337706f2543Smrg if (pAction&&(pAction->type==XkbSA_LockGroup)) { 338706f2543Smrg if (pAction->group.flags&XkbSA_GroupAbsolute) 339706f2543Smrg xkbi->state.locked_group= XkbSAGroup(&pAction->group); 340706f2543Smrg else xkbi->state.locked_group+= XkbSAGroup(&pAction->group); 341706f2543Smrg return 1; 342706f2543Smrg } 343706f2543Smrg if (filter->keycode==0) { /* initial press */ 344706f2543Smrg filter->keycode = keycode; 345706f2543Smrg filter->active = 1; 346706f2543Smrg filter->filterOthers = 0; 347706f2543Smrg filter->priv = 0; 348706f2543Smrg filter->filter = _XkbFilterLockState; 349706f2543Smrg filter->upAction = *pAction; 350706f2543Smrg xkbi->state.locked_mods^= pAction->mods.mask; 351706f2543Smrg xkbi->setMods = pAction->mods.mask; 352706f2543Smrg } 353706f2543Smrg else if (filter->keycode==keycode) { 354706f2543Smrg filter->active = 0; 355706f2543Smrg xkbi->clearMods = filter->upAction.mods.mask; 356706f2543Smrg } 357706f2543Smrg return 1; 358706f2543Smrg} 359706f2543Smrg 360706f2543Smrg#define ISO_KEY_DOWN 0 361706f2543Smrg#define NO_ISO_LOCK 1 362706f2543Smrg 363706f2543Smrgstatic int 364706f2543Smrg_XkbFilterISOLock( XkbSrvInfoPtr xkbi, 365706f2543Smrg XkbFilterPtr filter, 366706f2543Smrg unsigned keycode, 367706f2543Smrg XkbAction * pAction) 368706f2543Smrg{ 369706f2543Smrg 370706f2543Smrg if (filter->keycode==0) { /* initial press */ 371706f2543Smrg CARD8 flags= pAction->iso.flags; 372706f2543Smrg 373706f2543Smrg filter->keycode = keycode; 374706f2543Smrg filter->active = 1; 375706f2543Smrg filter->filterOthers = 1; 376706f2543Smrg filter->priv = ISO_KEY_DOWN; 377706f2543Smrg filter->upAction = *pAction; 378706f2543Smrg filter->filter = _XkbFilterISOLock; 379706f2543Smrg if (flags&XkbSA_ISODfltIsGroup) { 380706f2543Smrg xkbi->groupChange = XkbSAGroup(&pAction->iso); 381706f2543Smrg xkbi->setMods = 0; 382706f2543Smrg } 383706f2543Smrg else { 384706f2543Smrg xkbi->setMods = pAction->iso.mask; 385706f2543Smrg xkbi->groupChange = 0; 386706f2543Smrg } 387706f2543Smrg if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) { 388706f2543Smrg filter->priv= NO_ISO_LOCK; 389706f2543Smrg xkbi->state.locked_mods^= xkbi->state.base_mods; 390706f2543Smrg } 391706f2543Smrg if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) { 392706f2543Smrg/* 6/22/93 (ef) -- lock groups if group key is down first */ 393706f2543Smrg } 394706f2543Smrg if (!(flags&XkbSA_ISONoAffectPtr)) { 395706f2543Smrg/* 6/22/93 (ef) -- lock mouse buttons if they're down */ 396706f2543Smrg } 397706f2543Smrg } 398706f2543Smrg else if (filter->keycode==keycode) { 399706f2543Smrg CARD8 flags= filter->upAction.iso.flags; 400706f2543Smrg 401706f2543Smrg if (flags&XkbSA_ISODfltIsGroup) { 402706f2543Smrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso); 403706f2543Smrg xkbi->clearMods = 0; 404706f2543Smrg if (filter->priv==ISO_KEY_DOWN) 405706f2543Smrg xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso); 406706f2543Smrg } 407706f2543Smrg else { 408706f2543Smrg xkbi->clearMods= filter->upAction.iso.mask; 409706f2543Smrg xkbi->groupChange= 0; 410706f2543Smrg if (filter->priv==ISO_KEY_DOWN) 411706f2543Smrg xkbi->state.locked_mods^= filter->upAction.iso.mask; 412706f2543Smrg } 413706f2543Smrg filter->active = 0; 414706f2543Smrg } 415706f2543Smrg else if (pAction) { 416706f2543Smrg CARD8 flags= filter->upAction.iso.flags; 417706f2543Smrg 418706f2543Smrg switch (pAction->type) { 419706f2543Smrg case XkbSA_SetMods: case XkbSA_LatchMods: 420706f2543Smrg if (!(flags&XkbSA_ISONoAffectMods)) { 421706f2543Smrg pAction->type= XkbSA_LockMods; 422706f2543Smrg filter->priv= NO_ISO_LOCK; 423706f2543Smrg } 424706f2543Smrg break; 425706f2543Smrg case XkbSA_SetGroup: case XkbSA_LatchGroup: 426706f2543Smrg if (!(flags&XkbSA_ISONoAffectGroup)) { 427706f2543Smrg pAction->type= XkbSA_LockGroup; 428706f2543Smrg filter->priv= NO_ISO_LOCK; 429706f2543Smrg } 430706f2543Smrg break; 431706f2543Smrg case XkbSA_PtrBtn: 432706f2543Smrg if (!(flags&XkbSA_ISONoAffectPtr)) { 433706f2543Smrg pAction->type= XkbSA_LockPtrBtn; 434706f2543Smrg filter->priv= NO_ISO_LOCK; 435706f2543Smrg } 436706f2543Smrg break; 437706f2543Smrg case XkbSA_SetControls: 438706f2543Smrg if (!(flags&XkbSA_ISONoAffectCtrls)) { 439706f2543Smrg pAction->type= XkbSA_LockControls; 440706f2543Smrg filter->priv= NO_ISO_LOCK; 441706f2543Smrg } 442706f2543Smrg break; 443706f2543Smrg } 444706f2543Smrg } 445706f2543Smrg return 1; 446706f2543Smrg} 447706f2543Smrg 448706f2543Smrg 449706f2543Smrgstatic CARD32 450706f2543Smrg_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg) 451706f2543Smrg{ 452706f2543SmrgXkbSrvInfoPtr xkbi= (XkbSrvInfoPtr)arg; 453706f2543SmrgXkbControlsPtr ctrls= xkbi->desc->ctrls; 454706f2543Smrgint dx,dy; 455706f2543Smrg 456706f2543Smrg if (xkbi->mouseKey==0) 457706f2543Smrg return 0; 458706f2543Smrg 459706f2543Smrg if (xkbi->mouseKeysAccel) { 460706f2543Smrg if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) { 461706f2543Smrg double step; 462706f2543Smrg xkbi->mouseKeysCounter++; 463706f2543Smrg step= xkbi->mouseKeysCurveFactor* 464706f2543Smrg pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve); 465706f2543Smrg if (xkbi->mouseKeysDX<0) 466706f2543Smrg dx= floor( ((double)xkbi->mouseKeysDX)*step ); 467706f2543Smrg else dx= ceil( ((double)xkbi->mouseKeysDX)*step ); 468706f2543Smrg if (xkbi->mouseKeysDY<0) 469706f2543Smrg dy= floor( ((double)xkbi->mouseKeysDY)*step ); 470706f2543Smrg else dy= ceil( ((double)xkbi->mouseKeysDY)*step ); 471706f2543Smrg } 472706f2543Smrg else { 473706f2543Smrg dx= xkbi->mouseKeysDX*ctrls->mk_max_speed; 474706f2543Smrg dy= xkbi->mouseKeysDY*ctrls->mk_max_speed; 475706f2543Smrg } 476706f2543Smrg if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX) 477706f2543Smrg dx= xkbi->mouseKeysDX; 478706f2543Smrg if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY) 479706f2543Smrg dy= xkbi->mouseKeysDY; 480706f2543Smrg } 481706f2543Smrg else { 482706f2543Smrg dx= xkbi->mouseKeysDX; 483706f2543Smrg dy= xkbi->mouseKeysDY; 484706f2543Smrg } 485706f2543Smrg XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy); 486706f2543Smrg return xkbi->desc->ctrls->mk_interval; 487706f2543Smrg} 488706f2543Smrg 489706f2543Smrgstatic int 490706f2543Smrg_XkbFilterPointerMove( XkbSrvInfoPtr xkbi, 491706f2543Smrg XkbFilterPtr filter, 492706f2543Smrg unsigned keycode, 493706f2543Smrg XkbAction * pAction) 494706f2543Smrg{ 495706f2543Smrgint x,y; 496706f2543SmrgBool accel; 497706f2543Smrg 498706f2543Smrg if (filter->keycode==0) { /* initial press */ 499706f2543Smrg filter->keycode = keycode; 500706f2543Smrg filter->active = 1; 501706f2543Smrg filter->filterOthers = 0; 502706f2543Smrg filter->priv=0; 503706f2543Smrg filter->filter = _XkbFilterPointerMove; 504706f2543Smrg filter->upAction= *pAction; 505706f2543Smrg xkbi->mouseKeysCounter= 0; 506706f2543Smrg xkbi->mouseKey= keycode; 507706f2543Smrg accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0); 508706f2543Smrg x= XkbPtrActionX(&pAction->ptr); 509706f2543Smrg y= XkbPtrActionY(&pAction->ptr); 510706f2543Smrg XkbFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y); 511706f2543Smrg AccessXCancelRepeatKey(xkbi,keycode); 512706f2543Smrg xkbi->mouseKeysAccel= accel&& 513706f2543Smrg (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask); 514706f2543Smrg xkbi->mouseKeysFlags= pAction->ptr.flags; 515706f2543Smrg xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr); 516706f2543Smrg xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr); 517706f2543Smrg xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 518706f2543Smrg xkbi->desc->ctrls->mk_delay, 519706f2543Smrg _XkbPtrAccelExpire,(pointer)xkbi); 520706f2543Smrg } 521706f2543Smrg else if (filter->keycode==keycode) { 522706f2543Smrg filter->active = 0; 523706f2543Smrg if (xkbi->mouseKey==keycode) { 524706f2543Smrg xkbi->mouseKey= 0; 525706f2543Smrg xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0, 526706f2543Smrg NULL, NULL); 527706f2543Smrg } 528706f2543Smrg } 529706f2543Smrg return 0; 530706f2543Smrg} 531706f2543Smrg 532706f2543Smrgstatic int 533706f2543Smrg_XkbFilterPointerBtn( XkbSrvInfoPtr xkbi, 534706f2543Smrg XkbFilterPtr filter, 535706f2543Smrg unsigned keycode, 536706f2543Smrg XkbAction * pAction) 537706f2543Smrg{ 538706f2543Smrg if (filter->keycode==0) { /* initial press */ 539706f2543Smrg int button= pAction->btn.button; 540706f2543Smrg 541706f2543Smrg if (button==XkbSA_UseDfltButton) 542706f2543Smrg button = xkbi->desc->ctrls->mk_dflt_btn; 543706f2543Smrg 544706f2543Smrg filter->keycode = keycode; 545706f2543Smrg filter->active = 1; 546706f2543Smrg filter->filterOthers = 0; 547706f2543Smrg filter->priv=0; 548706f2543Smrg filter->filter = _XkbFilterPointerBtn; 549706f2543Smrg filter->upAction= *pAction; 550706f2543Smrg filter->upAction.btn.button= button; 551706f2543Smrg switch (pAction->type) { 552706f2543Smrg case XkbSA_LockPtrBtn: 553706f2543Smrg if (((xkbi->lockedPtrButtons&(1<<button))==0)&& 554706f2543Smrg ((pAction->btn.flags&XkbSA_LockNoLock)==0)) { 555706f2543Smrg xkbi->lockedPtrButtons|= (1<<button); 556706f2543Smrg AccessXCancelRepeatKey(xkbi,keycode); 557706f2543Smrg XkbFakeDeviceButton(xkbi->device, 1, button); 558706f2543Smrg filter->upAction.type= XkbSA_NoAction; 559706f2543Smrg } 560706f2543Smrg break; 561706f2543Smrg case XkbSA_PtrBtn: 562706f2543Smrg { 563706f2543Smrg register int i,nClicks; 564706f2543Smrg AccessXCancelRepeatKey(xkbi,keycode); 565706f2543Smrg if (pAction->btn.count>0) { 566706f2543Smrg nClicks= pAction->btn.count; 567706f2543Smrg for (i=0;i<nClicks;i++) { 568706f2543Smrg XkbFakeDeviceButton(xkbi->device, 1, button); 569706f2543Smrg XkbFakeDeviceButton(xkbi->device, 0, button); 570706f2543Smrg } 571706f2543Smrg filter->upAction.type= XkbSA_NoAction; 572706f2543Smrg } 573706f2543Smrg else XkbFakeDeviceButton(xkbi->device, 1, button); 574706f2543Smrg } 575706f2543Smrg break; 576706f2543Smrg case XkbSA_SetPtrDflt: 577706f2543Smrg { 578706f2543Smrg XkbControlsPtr ctrls= xkbi->desc->ctrls; 579706f2543Smrg XkbControlsRec old; 580706f2543Smrg xkbControlsNotify cn; 581706f2543Smrg 582706f2543Smrg old= *ctrls; 583706f2543Smrg AccessXCancelRepeatKey(xkbi,keycode); 584706f2543Smrg switch (pAction->dflt.affect) { 585706f2543Smrg case XkbSA_AffectDfltBtn: 586706f2543Smrg if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute) 587706f2543Smrg ctrls->mk_dflt_btn= 588706f2543Smrg XkbSAPtrDfltValue(&pAction->dflt); 589706f2543Smrg else { 590706f2543Smrg ctrls->mk_dflt_btn+= 591706f2543Smrg XkbSAPtrDfltValue(&pAction->dflt); 592706f2543Smrg if (ctrls->mk_dflt_btn>5) 593706f2543Smrg ctrls->mk_dflt_btn= 5; 594706f2543Smrg else if (ctrls->mk_dflt_btn<1) 595706f2543Smrg ctrls->mk_dflt_btn= 1; 596706f2543Smrg } 597706f2543Smrg break; 598706f2543Smrg default: 599706f2543Smrg ErrorF( 600706f2543Smrg "Attempt to change unknown pointer default (%d) ignored\n", 601706f2543Smrg pAction->dflt.affect); 602706f2543Smrg break; 603706f2543Smrg } 604706f2543Smrg if (XkbComputeControlsNotify(xkbi->device, 605706f2543Smrg &old,xkbi->desc->ctrls, 606706f2543Smrg &cn,FALSE)) { 607706f2543Smrg cn.keycode = keycode; 608706f2543Smrg /* XXX: what about DeviceKeyPress? */ 609706f2543Smrg cn.eventType = KeyPress; 610706f2543Smrg cn.requestMajor = 0; 611706f2543Smrg cn.requestMinor = 0; 612706f2543Smrg XkbSendControlsNotify(xkbi->device,&cn); 613706f2543Smrg } 614706f2543Smrg } 615706f2543Smrg break; 616706f2543Smrg } 617706f2543Smrg } 618706f2543Smrg else if (filter->keycode==keycode) { 619706f2543Smrg int button= filter->upAction.btn.button; 620706f2543Smrg 621706f2543Smrg switch (filter->upAction.type) { 622706f2543Smrg case XkbSA_LockPtrBtn: 623706f2543Smrg if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)|| 624706f2543Smrg ((xkbi->lockedPtrButtons&(1<<button))==0)) { 625706f2543Smrg break; 626706f2543Smrg } 627706f2543Smrg xkbi->lockedPtrButtons&= ~(1<<button); 628706f2543Smrg 629706f2543Smrg if (IsMaster(xkbi->device)) 630706f2543Smrg { 631706f2543Smrg XkbMergeLockedPtrBtns(xkbi->device); 632706f2543Smrg /* One SD still has lock set, don't post event */ 633706f2543Smrg if ((xkbi->lockedPtrButtons & (1 << button)) != 0) 634706f2543Smrg break; 635706f2543Smrg } 636706f2543Smrg 637706f2543Smrg /* fallthrough */ 638706f2543Smrg case XkbSA_PtrBtn: 639706f2543Smrg XkbFakeDeviceButton(xkbi->device, 0, button); 640706f2543Smrg break; 641706f2543Smrg } 642706f2543Smrg filter->active = 0; 643706f2543Smrg } 644706f2543Smrg return 0; 645706f2543Smrg} 646706f2543Smrg 647706f2543Smrgstatic int 648706f2543Smrg_XkbFilterControls( XkbSrvInfoPtr xkbi, 649706f2543Smrg XkbFilterPtr filter, 650706f2543Smrg unsigned keycode, 651706f2543Smrg XkbAction * pAction) 652706f2543Smrg{ 653706f2543SmrgXkbControlsRec old; 654706f2543SmrgXkbControlsPtr ctrls; 655706f2543SmrgDeviceIntPtr kbd; 656706f2543Smrgunsigned int change; 657706f2543SmrgXkbEventCauseRec cause; 658706f2543Smrg 659706f2543Smrg kbd= xkbi->device; 660706f2543Smrg ctrls= xkbi->desc->ctrls; 661706f2543Smrg old= *ctrls; 662706f2543Smrg if (filter->keycode==0) { /* initial press */ 663706f2543Smrg filter->keycode = keycode; 664706f2543Smrg filter->active = 1; 665706f2543Smrg filter->filterOthers = 0; 666706f2543Smrg change= XkbActionCtrls(&pAction->ctrls); 667706f2543Smrg filter->priv = change; 668706f2543Smrg filter->filter = _XkbFilterControls; 669706f2543Smrg filter->upAction = *pAction; 670706f2543Smrg 671706f2543Smrg if (pAction->type==XkbSA_LockControls) { 672706f2543Smrg filter->priv= (ctrls->enabled_ctrls&change); 673706f2543Smrg change&= ~ctrls->enabled_ctrls; 674706f2543Smrg } 675706f2543Smrg 676706f2543Smrg if (change) { 677706f2543Smrg xkbControlsNotify cn; 678706f2543Smrg XkbSrvLedInfoPtr sli; 679706f2543Smrg 680706f2543Smrg ctrls->enabled_ctrls|= change; 681706f2543Smrg if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) { 682706f2543Smrg cn.keycode = keycode; 683706f2543Smrg /* XXX: what about DeviceKeyPress? */ 684706f2543Smrg cn.eventType = KeyPress; 685706f2543Smrg cn.requestMajor = 0; 686706f2543Smrg cn.requestMinor = 0; 687706f2543Smrg XkbSendControlsNotify(kbd,&cn); 688706f2543Smrg } 689706f2543Smrg 690706f2543Smrg XkbSetCauseKey(&cause,keycode,KeyPress); 691706f2543Smrg 692706f2543Smrg /* If sticky keys were disabled, clear all locks and latches */ 693706f2543Smrg if ((old.enabled_ctrls&XkbStickyKeysMask)&& 694706f2543Smrg (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) { 695706f2543Smrg XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause); 696706f2543Smrg } 697706f2543Smrg sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); 698706f2543Smrg XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause); 699706f2543Smrg if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) 700706f2543Smrg XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change); 701706f2543Smrg } 702706f2543Smrg } 703706f2543Smrg else if (filter->keycode==keycode) { 704706f2543Smrg change= filter->priv; 705706f2543Smrg if (change) { 706706f2543Smrg xkbControlsNotify cn; 707706f2543Smrg XkbSrvLedInfoPtr sli; 708706f2543Smrg 709706f2543Smrg ctrls->enabled_ctrls&= ~change; 710706f2543Smrg if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) { 711706f2543Smrg cn.keycode = keycode; 712706f2543Smrg cn.eventType = KeyRelease; 713706f2543Smrg cn.requestMajor = 0; 714706f2543Smrg cn.requestMinor = 0; 715706f2543Smrg XkbSendControlsNotify(kbd,&cn); 716706f2543Smrg } 717706f2543Smrg 718706f2543Smrg XkbSetCauseKey(&cause,keycode,KeyRelease); 719706f2543Smrg /* If sticky keys were disabled, clear all locks and latches */ 720706f2543Smrg if ((old.enabled_ctrls&XkbStickyKeysMask)&& 721706f2543Smrg (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) { 722706f2543Smrg XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause); 723706f2543Smrg } 724706f2543Smrg sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); 725706f2543Smrg XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause); 726706f2543Smrg if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) 727706f2543Smrg XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change); 728706f2543Smrg } 729706f2543Smrg filter->keycode= 0; 730706f2543Smrg filter->active= 0; 731706f2543Smrg } 732706f2543Smrg return 1; 733706f2543Smrg} 734706f2543Smrg 735706f2543Smrgstatic int 736706f2543Smrg_XkbFilterActionMessage(XkbSrvInfoPtr xkbi, 737706f2543Smrg XkbFilterPtr filter, 738706f2543Smrg unsigned keycode, 739706f2543Smrg XkbAction * pAction) 740706f2543Smrg{ 741706f2543SmrgXkbMessageAction * pMsg; 742706f2543SmrgDeviceIntPtr kbd; 743706f2543Smrg 744706f2543Smrg kbd= xkbi->device; 745706f2543Smrg if (filter->keycode==0) { /* initial press */ 746706f2543Smrg pMsg= &pAction->msg; 747706f2543Smrg if ((pMsg->flags&XkbSA_MessageOnRelease)|| 748706f2543Smrg ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) { 749706f2543Smrg filter->keycode = keycode; 750706f2543Smrg filter->active = 1; 751706f2543Smrg filter->filterOthers = 0; 752706f2543Smrg filter->priv = 0; 753706f2543Smrg filter->filter = _XkbFilterActionMessage; 754706f2543Smrg filter->upAction = *pAction; 755706f2543Smrg } 756706f2543Smrg if (pMsg->flags&XkbSA_MessageOnPress) { 757706f2543Smrg xkbActionMessage msg; 758706f2543Smrg 759706f2543Smrg msg.keycode= keycode; 760706f2543Smrg msg.press= 1; 761706f2543Smrg msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 762706f2543Smrg memcpy((char *)msg.message, 763706f2543Smrg (char *)pMsg->message,XkbActionMessageLength); 764706f2543Smrg XkbSendActionMessage(kbd,&msg); 765706f2543Smrg } 766706f2543Smrg return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0); 767706f2543Smrg } 768706f2543Smrg else if (filter->keycode==keycode) { 769706f2543Smrg pMsg= &filter->upAction.msg; 770706f2543Smrg if (pMsg->flags&XkbSA_MessageOnRelease) { 771706f2543Smrg xkbActionMessage msg; 772706f2543Smrg 773706f2543Smrg msg.keycode= keycode; 774706f2543Smrg msg.press= 0; 775706f2543Smrg msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 776706f2543Smrg memcpy((char *)msg.message,(char *)pMsg->message, 777706f2543Smrg XkbActionMessageLength); 778706f2543Smrg XkbSendActionMessage(kbd,&msg); 779706f2543Smrg } 780706f2543Smrg filter->keycode= 0; 781706f2543Smrg filter->active= 0; 782706f2543Smrg return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 783706f2543Smrg } 784706f2543Smrg return 0; 785706f2543Smrg} 786706f2543Smrg 787706f2543Smrgstatic int 788706f2543Smrg_XkbFilterRedirectKey( XkbSrvInfoPtr xkbi, 789706f2543Smrg XkbFilterPtr filter, 790706f2543Smrg unsigned keycode, 791706f2543Smrg XkbAction * pAction) 792706f2543Smrg{ 793706f2543SmrgDeviceEvent ev; 794706f2543Smrgint x,y; 795706f2543SmrgXkbStateRec old; 796706f2543Smrgunsigned mods,mask; 797706f2543SmrgxkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device); 798706f2543SmrgProcessInputProc backupproc; 799706f2543Smrg 800706f2543Smrg /* never actually used uninitialised, but gcc isn't smart enough 801706f2543Smrg * to work that out. */ 802706f2543Smrg memset(&old, 0, sizeof(old)); 803706f2543Smrg memset(&ev, 0, sizeof(ev)); 804706f2543Smrg 805706f2543Smrg if ((filter->keycode!=0)&&(filter->keycode!=keycode)) 806706f2543Smrg return 1; 807706f2543Smrg 808706f2543Smrg GetSpritePosition(xkbi->device, &x,&y); 809706f2543Smrg ev.header = ET_Internal; 810706f2543Smrg ev.length = sizeof(DeviceEvent); 811706f2543Smrg ev.time = GetTimeInMillis(); 812706f2543Smrg ev.root_x = x; 813706f2543Smrg ev.root_y = y; 814706f2543Smrg 815706f2543Smrg if (filter->keycode==0) { /* initial press */ 816706f2543Smrg if ((pAction->redirect.new_key<xkbi->desc->min_key_code)|| 817706f2543Smrg (pAction->redirect.new_key>xkbi->desc->max_key_code)) { 818706f2543Smrg return 1; 819706f2543Smrg } 820706f2543Smrg filter->keycode = keycode; 821706f2543Smrg filter->active = 1; 822706f2543Smrg filter->filterOthers = 0; 823706f2543Smrg filter->priv = 0; 824706f2543Smrg filter->filter = _XkbFilterRedirectKey; 825706f2543Smrg filter->upAction = *pAction; 826706f2543Smrg 827706f2543Smrg ev.type = ET_KeyPress; 828706f2543Smrg ev.detail.key = pAction->redirect.new_key; 829706f2543Smrg 830706f2543Smrg mask= XkbSARedirectVModsMask(&pAction->redirect); 831706f2543Smrg mods= XkbSARedirectVMods(&pAction->redirect); 832706f2543Smrg if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask); 833706f2543Smrg if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods); 834706f2543Smrg mask|= pAction->redirect.mods_mask; 835706f2543Smrg mods|= pAction->redirect.mods; 836706f2543Smrg 837706f2543Smrg if ( mask || mods ) { 838706f2543Smrg old= xkbi->state; 839706f2543Smrg xkbi->state.base_mods&= ~mask; 840706f2543Smrg xkbi->state.base_mods|= (mods&mask); 841706f2543Smrg xkbi->state.latched_mods&= ~mask; 842706f2543Smrg xkbi->state.latched_mods|= (mods&mask); 843706f2543Smrg xkbi->state.locked_mods&= ~mask; 844706f2543Smrg xkbi->state.locked_mods|= (mods&mask); 845706f2543Smrg XkbComputeDerivedState(xkbi); 846706f2543Smrg } 847706f2543Smrg 848706f2543Smrg UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc); 849706f2543Smrg xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device); 850706f2543Smrg COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, 851706f2543Smrg backupproc,xkbUnwrapProc); 852706f2543Smrg 853706f2543Smrg if ( mask || mods ) 854706f2543Smrg xkbi->state= old; 855706f2543Smrg } 856706f2543Smrg else if (filter->keycode==keycode) { 857706f2543Smrg 858706f2543Smrg ev.type = ET_KeyRelease; 859706f2543Smrg ev.detail.key = filter->upAction.redirect.new_key; 860706f2543Smrg 861706f2543Smrg mask= XkbSARedirectVModsMask(&filter->upAction.redirect); 862706f2543Smrg mods= XkbSARedirectVMods(&filter->upAction.redirect); 863706f2543Smrg if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask); 864706f2543Smrg if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods); 865706f2543Smrg mask|= filter->upAction.redirect.mods_mask; 866706f2543Smrg mods|= filter->upAction.redirect.mods; 867706f2543Smrg 868706f2543Smrg if ( mask || mods ) { 869706f2543Smrg old= xkbi->state; 870706f2543Smrg xkbi->state.base_mods&= ~mask; 871706f2543Smrg xkbi->state.base_mods|= (mods&mask); 872706f2543Smrg xkbi->state.latched_mods&= ~mask; 873706f2543Smrg xkbi->state.latched_mods|= (mods&mask); 874706f2543Smrg xkbi->state.locked_mods&= ~mask; 875706f2543Smrg xkbi->state.locked_mods|= (mods&mask); 876706f2543Smrg XkbComputeDerivedState(xkbi); 877706f2543Smrg } 878706f2543Smrg 879706f2543Smrg UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc); 880706f2543Smrg xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device); 881706f2543Smrg COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, 882706f2543Smrg backupproc,xkbUnwrapProc); 883706f2543Smrg 884706f2543Smrg if ( mask || mods ) 885706f2543Smrg xkbi->state= old; 886706f2543Smrg 887706f2543Smrg filter->keycode= 0; 888706f2543Smrg filter->active= 0; 889706f2543Smrg } 890706f2543Smrg return 0; 891706f2543Smrg} 892706f2543Smrg 893706f2543Smrgstatic int 894706f2543Smrg_XkbFilterSwitchScreen( XkbSrvInfoPtr xkbi, 895706f2543Smrg XkbFilterPtr filter, 896706f2543Smrg unsigned keycode, 897706f2543Smrg XkbAction * pAction) 898706f2543Smrg{ 899706f2543Smrg DeviceIntPtr dev = xkbi->device; 900706f2543Smrg if (dev == inputInfo.keyboard) 901706f2543Smrg return 0; 902706f2543Smrg 903706f2543Smrg if (filter->keycode==0) { /* initial press */ 904706f2543Smrg filter->keycode = keycode; 905706f2543Smrg filter->active = 1; 906706f2543Smrg filter->filterOthers = 0; 907706f2543Smrg filter->filter = _XkbFilterSwitchScreen; 908706f2543Smrg AccessXCancelRepeatKey(xkbi, keycode); 909706f2543Smrg XkbDDXSwitchScreen(dev,keycode,pAction); 910706f2543Smrg return 0; 911706f2543Smrg } 912706f2543Smrg else if (filter->keycode==keycode) { 913706f2543Smrg filter->active= 0; 914706f2543Smrg return 0; 915706f2543Smrg } 916706f2543Smrg return 1; 917706f2543Smrg} 918706f2543Smrg 919706f2543Smrgstatic int 920706f2543Smrg_XkbFilterXF86Private( XkbSrvInfoPtr xkbi, 921706f2543Smrg XkbFilterPtr filter, 922706f2543Smrg unsigned keycode, 923706f2543Smrg XkbAction * pAction) 924706f2543Smrg{ 925706f2543Smrg DeviceIntPtr dev = xkbi->device; 926706f2543Smrg if (dev == inputInfo.keyboard) 927706f2543Smrg return 0; 928706f2543Smrg 929706f2543Smrg if (filter->keycode==0) { /* initial press */ 930706f2543Smrg filter->keycode = keycode; 931706f2543Smrg filter->active = 1; 932706f2543Smrg filter->filterOthers = 0; 933706f2543Smrg filter->filter = _XkbFilterXF86Private; 934706f2543Smrg XkbDDXPrivate(dev,keycode,pAction); 935706f2543Smrg return 0; 936706f2543Smrg } 937706f2543Smrg else if (filter->keycode==keycode) { 938706f2543Smrg filter->active= 0; 939706f2543Smrg return 0; 940706f2543Smrg } 941706f2543Smrg return 1; 942706f2543Smrg} 943706f2543Smrg 944706f2543Smrg 945706f2543Smrgstatic int 946706f2543Smrg_XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi, 947706f2543Smrg XkbFilterPtr filter, 948706f2543Smrg unsigned keycode, 949706f2543Smrg XkbAction * pAction) 950706f2543Smrg{ 951706f2543SmrgDeviceIntPtr dev; 952706f2543Smrgint button; 953706f2543Smrg 954706f2543Smrg if (xkbi->device == inputInfo.keyboard) 955706f2543Smrg return 0; 956706f2543Smrg 957706f2543Smrg if (filter->keycode==0) { /* initial press */ 958706f2543Smrg _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient, 959706f2543Smrg DixUnknownAccess, &button); 960706f2543Smrg if (!dev || !dev->public.on) 961706f2543Smrg return 1; 962706f2543Smrg 963706f2543Smrg button= pAction->devbtn.button; 964706f2543Smrg if ((button<1)||(button>dev->button->numButtons)) 965706f2543Smrg return 1; 966706f2543Smrg 967706f2543Smrg filter->keycode = keycode; 968706f2543Smrg filter->active = 1; 969706f2543Smrg filter->filterOthers = 0; 970706f2543Smrg filter->priv=0; 971706f2543Smrg filter->filter = _XkbFilterDeviceBtn; 972706f2543Smrg filter->upAction= *pAction; 973706f2543Smrg switch (pAction->type) { 974706f2543Smrg case XkbSA_LockDeviceBtn: 975706f2543Smrg if ((pAction->devbtn.flags&XkbSA_LockNoLock)|| 976706f2543Smrg BitIsOn(dev->button->down, button)) 977706f2543Smrg return 0; 978706f2543Smrg XkbFakeDeviceButton(dev,TRUE,button); 979706f2543Smrg filter->upAction.type= XkbSA_NoAction; 980706f2543Smrg break; 981706f2543Smrg case XkbSA_DeviceBtn: 982706f2543Smrg if (pAction->devbtn.count>0) { 983706f2543Smrg int nClicks,i; 984706f2543Smrg nClicks= pAction->btn.count; 985706f2543Smrg for (i=0;i<nClicks;i++) { 986706f2543Smrg XkbFakeDeviceButton(dev,TRUE,button); 987706f2543Smrg XkbFakeDeviceButton(dev,FALSE,button); 988706f2543Smrg } 989706f2543Smrg filter->upAction.type= XkbSA_NoAction; 990706f2543Smrg } 991706f2543Smrg else XkbFakeDeviceButton(dev,TRUE,button); 992706f2543Smrg break; 993706f2543Smrg } 994706f2543Smrg } 995706f2543Smrg else if (filter->keycode==keycode) { 996706f2543Smrg int button; 997706f2543Smrg 998706f2543Smrg filter->active= 0; 999706f2543Smrg _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device, 1000706f2543Smrg serverClient, DixUnknownAccess, &button); 1001706f2543Smrg if (!dev || !dev->public.on) 1002706f2543Smrg return 1; 1003706f2543Smrg 1004706f2543Smrg button= filter->upAction.btn.button; 1005706f2543Smrg switch (filter->upAction.type) { 1006706f2543Smrg case XkbSA_LockDeviceBtn: 1007706f2543Smrg if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)|| 1008706f2543Smrg !BitIsOn(dev->button->down, button)) 1009706f2543Smrg return 0; 1010706f2543Smrg XkbFakeDeviceButton(dev,FALSE,button); 1011706f2543Smrg break; 1012706f2543Smrg case XkbSA_DeviceBtn: 1013706f2543Smrg XkbFakeDeviceButton(dev,FALSE,button); 1014706f2543Smrg break; 1015706f2543Smrg } 1016706f2543Smrg filter->active = 0; 1017706f2543Smrg } 1018706f2543Smrg return 0; 1019706f2543Smrg} 1020706f2543Smrg 1021706f2543Smrgstatic XkbFilterPtr 1022706f2543Smrg_XkbNextFreeFilter( 1023706f2543Smrg XkbSrvInfoPtr xkbi 1024706f2543Smrg) 1025706f2543Smrg{ 1026706f2543Smrgregister int i; 1027706f2543Smrg 1028706f2543Smrg if (xkbi->szFilters==0) { 1029706f2543Smrg xkbi->szFilters = 4; 1030706f2543Smrg xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec)); 1031706f2543Smrg /* 6/21/93 (ef) -- XXX! deal with allocation failure */ 1032706f2543Smrg } 1033706f2543Smrg for (i=0;i<xkbi->szFilters;i++) { 1034706f2543Smrg if (!xkbi->filters[i].active) { 1035706f2543Smrg xkbi->filters[i].keycode = 0; 1036706f2543Smrg return &xkbi->filters[i]; 1037706f2543Smrg } 1038706f2543Smrg } 1039706f2543Smrg xkbi->szFilters*=2; 1040706f2543Smrg xkbi->filters= realloc(xkbi->filters, 1041706f2543Smrg xkbi->szFilters * sizeof(XkbFilterRec)); 1042706f2543Smrg /* 6/21/93 (ef) -- XXX! deal with allocation failure */ 1043706f2543Smrg memset(&xkbi->filters[xkbi->szFilters/2], 0, 1044706f2543Smrg (xkbi->szFilters/2)*sizeof(XkbFilterRec)); 1045706f2543Smrg return &xkbi->filters[xkbi->szFilters/2]; 1046706f2543Smrg} 1047706f2543Smrg 1048706f2543Smrgstatic int 1049706f2543Smrg_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction) 1050706f2543Smrg{ 1051706f2543Smrgregister int i,send; 1052706f2543Smrg 1053706f2543Smrg send= 1; 1054706f2543Smrg for (i=0;i<xkbi->szFilters;i++) { 1055706f2543Smrg if ((xkbi->filters[i].active)&&(xkbi->filters[i].filter)) 1056706f2543Smrg send= ((*xkbi->filters[i].filter)(xkbi,&xkbi->filters[i],kc,pAction) 1057706f2543Smrg && send); 1058706f2543Smrg } 1059706f2543Smrg return send; 1060706f2543Smrg} 1061706f2543Smrg 1062706f2543Smrgvoid 1063706f2543SmrgXkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent* event) 1064706f2543Smrg{ 1065706f2543Smrgint key,bit,i; 1066706f2543SmrgXkbSrvInfoPtr xkbi; 1067706f2543SmrgKeyClassPtr keyc; 1068706f2543Smrgint changed,sendEvent; 1069706f2543SmrgBool genStateNotify; 1070706f2543SmrgXkbAction act; 1071706f2543SmrgXkbFilterPtr filter; 1072706f2543SmrgBool keyEvent; 1073706f2543SmrgBool pressEvent; 1074706f2543SmrgProcessInputProc backupproc; 1075706f2543Smrg 1076706f2543SmrgxkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev); 1077706f2543Smrg 1078706f2543Smrg keyc= kbd->key; 1079706f2543Smrg xkbi= keyc->xkbInfo; 1080706f2543Smrg key= event->detail.key; 1081706f2543Smrg /* The state may change, so if we're not in the middle of sending a state 1082706f2543Smrg * notify, prepare for it */ 1083706f2543Smrg if ((xkbi->flags&_XkbStateNotifyInProgress)==0) { 1084706f2543Smrg xkbi->prev_state = xkbi->state; 1085706f2543Smrg xkbi->flags|= _XkbStateNotifyInProgress; 1086706f2543Smrg genStateNotify= TRUE; 1087706f2543Smrg } 1088706f2543Smrg else genStateNotify= FALSE; 1089706f2543Smrg 1090706f2543Smrg xkbi->clearMods = xkbi->setMods = 0; 1091706f2543Smrg xkbi->groupChange = 0; 1092706f2543Smrg 1093706f2543Smrg sendEvent = 1; 1094706f2543Smrg keyEvent= ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease)); 1095706f2543Smrg pressEvent= ((event->type == ET_KeyPress)|| (event->type == ET_ButtonPress)); 1096706f2543Smrg 1097706f2543Smrg if (pressEvent) { 1098706f2543Smrg if (keyEvent) 1099706f2543Smrg act = XkbGetKeyAction(xkbi,&xkbi->state,key); 1100706f2543Smrg else { 1101706f2543Smrg act = XkbGetButtonAction(kbd,dev,key); 1102706f2543Smrg key|= BTN_ACT_FLAG; 1103706f2543Smrg } 1104706f2543Smrg sendEvent = _XkbApplyFilters(xkbi,key,&act); 1105706f2543Smrg if (sendEvent) { 1106706f2543Smrg switch (act.type) { 1107706f2543Smrg case XkbSA_SetMods: 1108706f2543Smrg case XkbSA_SetGroup: 1109706f2543Smrg filter = _XkbNextFreeFilter(xkbi); 1110706f2543Smrg sendEvent = _XkbFilterSetState(xkbi,filter,key,&act); 1111706f2543Smrg break; 1112706f2543Smrg case XkbSA_LatchMods: 1113706f2543Smrg case XkbSA_LatchGroup: 1114706f2543Smrg filter = _XkbNextFreeFilter(xkbi); 1115706f2543Smrg sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act); 1116706f2543Smrg break; 1117706f2543Smrg case XkbSA_LockMods: 1118706f2543Smrg case XkbSA_LockGroup: 1119706f2543Smrg filter = _XkbNextFreeFilter(xkbi); 1120706f2543Smrg sendEvent=_XkbFilterLockState(xkbi,filter,key,&act); 1121706f2543Smrg break; 1122706f2543Smrg case XkbSA_ISOLock: 1123706f2543Smrg filter = _XkbNextFreeFilter(xkbi); 1124706f2543Smrg sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act); 1125706f2543Smrg break; 1126706f2543Smrg case XkbSA_MovePtr: 1127706f2543Smrg filter = _XkbNextFreeFilter(xkbi); 1128706f2543Smrg sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act); 1129706f2543Smrg break; 1130706f2543Smrg case XkbSA_PtrBtn: 1131706f2543Smrg case XkbSA_LockPtrBtn: 1132706f2543Smrg case XkbSA_SetPtrDflt: 1133706f2543Smrg filter = _XkbNextFreeFilter(xkbi); 1134706f2543Smrg sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act); 1135706f2543Smrg break; 1136706f2543Smrg case XkbSA_Terminate: 1137706f2543Smrg sendEvent= XkbDDXTerminateServer(dev,key,&act); 1138706f2543Smrg break; 1139706f2543Smrg case XkbSA_SwitchScreen: 1140706f2543Smrg filter = _XkbNextFreeFilter(xkbi); 1141706f2543Smrg sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act); 1142706f2543Smrg break; 1143706f2543Smrg case XkbSA_SetControls: 1144706f2543Smrg case XkbSA_LockControls: 1145706f2543Smrg filter = _XkbNextFreeFilter(xkbi); 1146706f2543Smrg sendEvent=_XkbFilterControls(xkbi,filter,key,&act); 1147706f2543Smrg break; 1148706f2543Smrg case XkbSA_ActionMessage: 1149706f2543Smrg filter = _XkbNextFreeFilter(xkbi); 1150706f2543Smrg sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act); 1151706f2543Smrg break; 1152706f2543Smrg case XkbSA_RedirectKey: 1153706f2543Smrg filter = _XkbNextFreeFilter(xkbi); 1154706f2543Smrg sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act); 1155706f2543Smrg break; 1156706f2543Smrg case XkbSA_DeviceBtn: 1157706f2543Smrg case XkbSA_LockDeviceBtn: 1158706f2543Smrg filter = _XkbNextFreeFilter(xkbi); 1159706f2543Smrg sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act); 1160706f2543Smrg break; 1161706f2543Smrg case XkbSA_XFree86Private: 1162706f2543Smrg filter = _XkbNextFreeFilter(xkbi); 1163706f2543Smrg sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act); 1164706f2543Smrg break; 1165706f2543Smrg } 1166706f2543Smrg } 1167706f2543Smrg } 1168706f2543Smrg else { 1169706f2543Smrg if (!keyEvent) 1170706f2543Smrg key|= BTN_ACT_FLAG; 1171706f2543Smrg sendEvent = _XkbApplyFilters(xkbi,key,NULL); 1172706f2543Smrg } 1173706f2543Smrg 1174706f2543Smrg if (xkbi->groupChange!=0) 1175706f2543Smrg xkbi->state.base_group+= xkbi->groupChange; 1176706f2543Smrg if (xkbi->setMods) { 1177706f2543Smrg for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) { 1178706f2543Smrg if (xkbi->setMods&bit) { 1179706f2543Smrg keyc->modifierKeyCount[i]++; 1180706f2543Smrg xkbi->state.base_mods|= bit; 1181706f2543Smrg xkbi->setMods&= ~bit; 1182706f2543Smrg } 1183706f2543Smrg } 1184706f2543Smrg } 1185706f2543Smrg if (xkbi->clearMods) { 1186706f2543Smrg for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) { 1187706f2543Smrg if (xkbi->clearMods&bit) { 1188706f2543Smrg keyc->modifierKeyCount[i]--; 1189706f2543Smrg if (keyc->modifierKeyCount[i]<=0) { 1190706f2543Smrg xkbi->state.base_mods&= ~bit; 1191706f2543Smrg keyc->modifierKeyCount[i] = 0; 1192706f2543Smrg } 1193706f2543Smrg xkbi->clearMods&= ~bit; 1194706f2543Smrg } 1195706f2543Smrg } 1196706f2543Smrg } 1197706f2543Smrg 1198706f2543Smrg if (sendEvent) { 1199706f2543Smrg DeviceIntPtr tmpdev; 1200706f2543Smrg if (keyEvent) 1201706f2543Smrg tmpdev = dev; 1202706f2543Smrg else 1203706f2543Smrg tmpdev = GetPairedDevice(dev); 1204706f2543Smrg 1205706f2543Smrg UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc); 1206706f2543Smrg dev->public.processInputProc((InternalEvent*)event, tmpdev); 1207706f2543Smrg COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, 1208706f2543Smrg backupproc,xkbUnwrapProc); 1209706f2543Smrg } 1210706f2543Smrg else if (keyEvent) { 1211706f2543Smrg FixKeyState(event, dev); 1212706f2543Smrg } 1213706f2543Smrg 1214706f2543Smrg XkbComputeDerivedState(xkbi); 1215706f2543Smrg changed = XkbStateChangedFlags(&xkbi->prev_state,&xkbi->state); 1216706f2543Smrg if (genStateNotify) { 1217706f2543Smrg if (changed) { 1218706f2543Smrg xkbStateNotify sn; 1219706f2543Smrg sn.keycode= key; 1220706f2543Smrg sn.eventType= event->type; 1221706f2543Smrg sn.requestMajor = sn.requestMinor = 0; 1222706f2543Smrg sn.changed= changed; 1223706f2543Smrg XkbSendStateNotify(dev,&sn); 1224706f2543Smrg } 1225706f2543Smrg xkbi->flags&= ~_XkbStateNotifyInProgress; 1226706f2543Smrg } 1227706f2543Smrg changed= XkbIndicatorsToUpdate(dev,changed,FALSE); 1228706f2543Smrg if (changed) { 1229706f2543Smrg XkbEventCauseRec cause; 1230706f2543Smrg XkbSetCauseKey(&cause, key, event->type); 1231706f2543Smrg XkbUpdateIndicators(dev,changed,FALSE,NULL,&cause); 1232706f2543Smrg } 1233706f2543Smrg return; 1234706f2543Smrg} 1235706f2543Smrg 1236706f2543Smrgint 1237706f2543SmrgXkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches) 1238706f2543Smrg{ 1239706f2543SmrgXkbSrvInfoPtr xkbi; 1240706f2543SmrgXkbFilterPtr filter; 1241706f2543SmrgXkbAction act; 1242706f2543Smrgunsigned clear; 1243706f2543Smrg 1244706f2543Smrg if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) { 1245706f2543Smrg xkbi = pXDev->key->xkbInfo; 1246706f2543Smrg clear= (mask&(~latches)); 1247706f2543Smrg xkbi->state.latched_mods&= ~clear; 1248706f2543Smrg /* Clear any pending latch to locks. 1249706f2543Smrg */ 1250706f2543Smrg act.type = XkbSA_NoAction; 1251706f2543Smrg _XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act); 1252706f2543Smrg act.type = XkbSA_LatchMods; 1253706f2543Smrg act.mods.flags = 0; 1254706f2543Smrg act.mods.mask = mask&latches; 1255706f2543Smrg filter = _XkbNextFreeFilter(xkbi); 1256706f2543Smrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act); 1257706f2543Smrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL); 1258706f2543Smrg return Success; 1259706f2543Smrg } 1260706f2543Smrg return BadValue; 1261706f2543Smrg} 1262706f2543Smrg 1263706f2543Smrgint 1264706f2543SmrgXkbLatchGroup(DeviceIntPtr pXDev,int group) 1265706f2543Smrg{ 1266706f2543SmrgXkbSrvInfoPtr xkbi; 1267706f2543SmrgXkbFilterPtr filter; 1268706f2543SmrgXkbAction act; 1269706f2543Smrg 1270706f2543Smrg if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) { 1271706f2543Smrg xkbi = pXDev->key->xkbInfo; 1272706f2543Smrg act.type = XkbSA_LatchGroup; 1273706f2543Smrg act.group.flags = 0; 1274706f2543Smrg XkbSASetGroup(&act.group,group); 1275706f2543Smrg filter = _XkbNextFreeFilter(xkbi); 1276706f2543Smrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act); 1277706f2543Smrg _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL); 1278706f2543Smrg return Success; 1279706f2543Smrg } 1280706f2543Smrg return BadValue; 1281706f2543Smrg} 1282706f2543Smrg 1283706f2543Smrg/***====================================================================***/ 1284706f2543Smrg 1285706f2543Smrgvoid 1286706f2543SmrgXkbClearAllLatchesAndLocks( DeviceIntPtr dev, 1287706f2543Smrg XkbSrvInfoPtr xkbi, 1288706f2543Smrg Bool genEv, 1289706f2543Smrg XkbEventCausePtr cause) 1290706f2543Smrg{ 1291706f2543SmrgXkbStateRec os; 1292706f2543SmrgxkbStateNotify sn; 1293706f2543Smrg 1294706f2543Smrg sn.changed= 0; 1295706f2543Smrg os= xkbi->state; 1296706f2543Smrg if (os.latched_mods) { /* clear all latches */ 1297706f2543Smrg XkbLatchModifiers(dev,~0,0); 1298706f2543Smrg sn.changed|= XkbModifierLatchMask; 1299706f2543Smrg } 1300706f2543Smrg if (os.latched_group) { 1301706f2543Smrg XkbLatchGroup(dev,0); 1302706f2543Smrg sn.changed|= XkbGroupLatchMask; 1303706f2543Smrg } 1304706f2543Smrg if (os.locked_mods) { 1305706f2543Smrg xkbi->state.locked_mods= 0; 1306706f2543Smrg sn.changed|= XkbModifierLockMask; 1307706f2543Smrg } 1308706f2543Smrg if (os.locked_group) { 1309706f2543Smrg xkbi->state.locked_group= 0; 1310706f2543Smrg sn.changed|= XkbGroupLockMask; 1311706f2543Smrg } 1312706f2543Smrg if ( genEv && sn.changed) { 1313706f2543Smrg CARD32 changed; 1314706f2543Smrg 1315706f2543Smrg XkbComputeDerivedState(xkbi); 1316706f2543Smrg sn.keycode= cause->kc; 1317706f2543Smrg sn.eventType= cause->event; 1318706f2543Smrg sn.requestMajor= cause->mjr; 1319706f2543Smrg sn.requestMinor= cause->mnr; 1320706f2543Smrg sn.changed= XkbStateChangedFlags(&os,&xkbi->state); 1321706f2543Smrg XkbSendStateNotify(dev,&sn); 1322706f2543Smrg changed= XkbIndicatorsToUpdate(dev,sn.changed,FALSE); 1323706f2543Smrg if (changed) { 1324706f2543Smrg XkbUpdateIndicators(dev,changed,TRUE,NULL,cause); 1325706f2543Smrg } 1326706f2543Smrg } 1327706f2543Smrg return; 1328706f2543Smrg} 1329706f2543Smrg 1330706f2543Smrg/* 1331706f2543Smrg * The event is injected into the event processing, not the EQ. Thus, 1332706f2543Smrg * ensure that we restore the master after the event sequence to the 1333706f2543Smrg * original set of classes. Otherwise, the master remains on the XTEST 1334706f2543Smrg * classes and drops events that don't fit into the XTEST layout (e.g. 1335706f2543Smrg * events with more than 2 valuators). 1336706f2543Smrg * 1337706f2543Smrg * FIXME: EQ injection in the processing stage is not designed for, so this 1338706f2543Smrg * is a rather awkward hack. The event list returned by GetPointerEvents() 1339706f2543Smrg * and friends is always prefixed with a DCE if the last _posted_ device was 1340706f2543Smrg * different. For normal events, this sequence then resets the master during 1341706f2543Smrg * the processing stage. Since we inject the PointerKey events in the 1342706f2543Smrg * processing stage though, we need to manually reset to restore the 1343706f2543Smrg * previous order, because the events already in the EQ must be sent for the 1344706f2543Smrg * right device. 1345706f2543Smrg * So we post-fix the event list we get from GPE with a DCE back to the 1346706f2543Smrg * previous slave device. 1347706f2543Smrg * 1348706f2543Smrg * First one on drinking island wins! 1349706f2543Smrg */ 1350706f2543Smrgstatic void 1351706f2543SmrgInjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, ValuatorMask *mask) 1352706f2543Smrg{ 1353706f2543Smrg ScreenPtr pScreen; 1354706f2543Smrg EventListPtr events; 1355706f2543Smrg int nevents, i; 1356706f2543Smrg DeviceIntPtr ptr, mpointer, lastSlave = NULL; 1357706f2543Smrg Bool saveWait; 1358706f2543Smrg 1359706f2543Smrg if (IsMaster(dev)) { 1360706f2543Smrg mpointer = GetMaster(dev, MASTER_POINTER); 1361706f2543Smrg lastSlave = mpointer->u.lastSlave; 1362706f2543Smrg ptr = GetXTestDevice(mpointer); 1363706f2543Smrg } else if (!dev->u.master) 1364706f2543Smrg ptr = dev; 1365706f2543Smrg else 1366706f2543Smrg return; 1367706f2543Smrg 1368706f2543Smrg 1369706f2543Smrg events = InitEventList(GetMaximumEventsNum() + 1); 1370706f2543Smrg OsBlockSignals(); 1371706f2543Smrg pScreen = miPointerGetScreen(ptr); 1372706f2543Smrg saveWait = miPointerSetWaitForUpdate(pScreen, FALSE); 1373706f2543Smrg nevents = GetPointerEvents(events, ptr, type, button, flags, mask); 1374706f2543Smrg if (IsMaster(dev) && (lastSlave && lastSlave != ptr)) 1375706f2543Smrg UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT, &nevents); 1376706f2543Smrg miPointerSetWaitForUpdate(pScreen, saveWait); 1377706f2543Smrg OsReleaseSignals(); 1378706f2543Smrg 1379706f2543Smrg for (i = 0; i < nevents; i++) 1380706f2543Smrg mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL); 1381706f2543Smrg 1382706f2543Smrg FreeEventList(events, GetMaximumEventsNum()); 1383706f2543Smrg 1384706f2543Smrg} 1385706f2543Smrg 1386706f2543Smrgstatic void 1387706f2543SmrgXkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y) 1388706f2543Smrg{ 1389706f2543Smrg ValuatorMask mask; 1390706f2543Smrg int gpe_flags = 0; 1391706f2543Smrg 1392706f2543Smrg /* ignore attached SDs */ 1393706f2543Smrg if (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) != NULL) 1394706f2543Smrg return; 1395706f2543Smrg 1396706f2543Smrg if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY) 1397706f2543Smrg gpe_flags = POINTER_ABSOLUTE; 1398706f2543Smrg else 1399706f2543Smrg gpe_flags = POINTER_RELATIVE; 1400706f2543Smrg 1401706f2543Smrg valuator_mask_set_range(&mask, 0, 2, (int[]){x, y}); 1402706f2543Smrg 1403706f2543Smrg InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, &mask); 1404706f2543Smrg} 1405706f2543Smrg 1406706f2543Smrgvoid 1407706f2543SmrgXkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button) 1408706f2543Smrg{ 1409706f2543Smrg DeviceIntPtr ptr; 1410706f2543Smrg int down; 1411706f2543Smrg 1412706f2543Smrg /* If dev is a slave device, and the SD is attached, do nothing. If we'd 1413706f2543Smrg * post through the attached master pointer we'd get duplicate events. 1414706f2543Smrg * 1415706f2543Smrg * if dev is a master keyboard, post through the XTEST device 1416706f2543Smrg * 1417706f2543Smrg * if dev is a floating slave, post through the device itself. 1418706f2543Smrg */ 1419706f2543Smrg 1420706f2543Smrg if (IsMaster(dev)) { 1421706f2543Smrg DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER); 1422706f2543Smrg ptr = GetXTestDevice(mpointer); 1423706f2543Smrg } else if (!dev->u.master) 1424706f2543Smrg ptr = dev; 1425706f2543Smrg else 1426706f2543Smrg return; 1427706f2543Smrg 1428706f2543Smrg down = button_is_down(ptr, button, BUTTON_PROCESSED); 1429706f2543Smrg if (press == down) 1430706f2543Smrg return; 1431706f2543Smrg 1432706f2543Smrg InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease, 1433706f2543Smrg button, 0, NULL); 1434706f2543Smrg} 1435