xkbActions.c revision 6747b715
1/************************************************************ 2Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 3 4Permission to use, copy, modify, and distribute this 5software and its documentation for any purpose and without 6fee is hereby granted, provided that the above copyright 7notice appear in all copies and that both that copyright 8notice and this permission notice appear in supporting 9documentation, and that the name of Silicon Graphics not be 10used in advertising or publicity pertaining to distribution 11of the software without specific prior written permission. 12Silicon Graphics makes no representation about the suitability 13of this software for any purpose. It is provided "as is" 14without any express or implied warranty. 15 16SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 25********************************************************/ 26 27#ifdef HAVE_DIX_CONFIG_H 28#include <dix-config.h> 29#endif 30 31#include <stdio.h> 32#include <math.h> 33#include <X11/X.h> 34#include <X11/Xproto.h> 35#include <X11/keysym.h> 36#include "misc.h" 37#include "inputstr.h" 38#include "exevents.h" 39#include "eventstr.h" 40#include <xkbsrv.h> 41#include "xkb.h" 42#include <ctype.h> 43#include "mi.h" 44#include "mipointer.h" 45#define EXTENSION_EVENT_BASE 64 46 47DevPrivateKeyRec xkbDevicePrivateKeyRec; 48 49void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button); 50static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y); 51 52void 53xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, 54 pointer data) 55{ 56 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device); 57 ProcessInputProc backupproc; 58 if(xkbPrivPtr->unwrapProc) 59 xkbPrivPtr->unwrapProc = NULL; 60 61 UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc); 62 proc(device,data); 63 COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, 64 backupproc,xkbUnwrapProc); 65} 66 67Bool 68XkbInitPrivates(void) 69{ 70 return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec, PRIVATE_DEVICE, 0); 71} 72 73void 74XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc) 75{ 76 xkbDeviceInfoPtr xkbPrivPtr; 77 78 xkbPrivPtr = (xkbDeviceInfoPtr) calloc(1, sizeof(xkbDeviceInfoRec)); 79 if (!xkbPrivPtr) 80 return; 81 xkbPrivPtr->unwrapProc = NULL; 82 83 dixSetPrivate(&device->devPrivates, xkbDevicePrivateKey, xkbPrivPtr); 84 WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc); 85} 86 87/***====================================================================***/ 88 89static XkbAction 90_FixUpAction(XkbDescPtr xkb,XkbAction *act) 91{ 92static XkbAction fake; 93 94 if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) { 95 fake.type = XkbSA_NoAction; 96 return fake; 97 } 98 if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) { 99 if (act->any.type==XkbSA_SetMods) { 100 fake.mods.type = XkbSA_LatchMods; 101 fake.mods.mask = act->mods.mask; 102 if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask)) 103 fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock; 104 else fake.mods.flags= XkbSA_ClearLocks; 105 return fake; 106 } 107 if (act->any.type==XkbSA_SetGroup) { 108 fake.group.type = XkbSA_LatchGroup; 109 if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask)) 110 fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock; 111 else fake.group.flags= XkbSA_ClearLocks; 112 XkbSASetGroup(&fake.group,XkbSAGroup(&act->group)); 113 return fake; 114 } 115 } 116 return *act; 117} 118 119static XkbAction 120XkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key) 121{ 122int effectiveGroup; 123int col; 124XkbDescPtr xkb; 125XkbKeyTypePtr type; 126XkbAction * pActs; 127static XkbAction fake; 128 129 xkb= xkbi->desc; 130 if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) { 131 fake.type = XkbSA_NoAction; 132 return fake; 133 } 134 pActs= XkbKeyActionsPtr(xkb,key); 135 col= 0; 136 137 effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key); 138 if (effectiveGroup != XkbGroup1Index) 139 col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key)); 140 141 type= XkbKeyKeyType(xkb,key,effectiveGroup); 142 if (type->map!=NULL) { 143 register unsigned i,mods; 144 register XkbKTMapEntryPtr entry; 145 mods= xkbState->mods&type->mods.mask; 146 for (entry= type->map,i=0;i<type->map_count;i++,entry++) { 147 if ((entry->active)&&(entry->mods.mask==mods)) { 148 col+= entry->level; 149 break; 150 } 151 } 152 } 153 if (pActs[col].any.type==XkbSA_NoAction) 154 return pActs[col]; 155 fake= _FixUpAction(xkb,&pActs[col]); 156 return fake; 157} 158 159static XkbAction 160XkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button) 161{ 162XkbAction fake; 163 if ((dev->button)&&(dev->button->xkb_acts)) { 164 if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) { 165 fake= _FixUpAction(kbd->key->xkbInfo->desc, 166 &dev->button->xkb_acts[button-1]); 167 return fake; 168 } 169 } 170 fake.any.type= XkbSA_NoAction; 171 return fake; 172} 173 174/***====================================================================***/ 175 176#define SYNTHETIC_KEYCODE 1 177#define BTN_ACT_FLAG 0x100 178 179static int 180_XkbFilterSetState( XkbSrvInfoPtr xkbi, 181 XkbFilterPtr filter, 182 unsigned keycode, 183 XkbAction *pAction) 184{ 185 if (filter->keycode==0) { /* initial press */ 186 filter->keycode = keycode; 187 filter->active = 1; 188 filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0); 189 filter->priv = 0; 190 filter->filter = _XkbFilterSetState; 191 if (pAction->type==XkbSA_SetMods) { 192 filter->upAction = *pAction; 193 xkbi->setMods= pAction->mods.mask; 194 } 195 else { 196 xkbi->groupChange = XkbSAGroup(&pAction->group); 197 if (pAction->group.flags&XkbSA_GroupAbsolute) 198 xkbi->groupChange-= xkbi->state.base_group; 199 filter->upAction= *pAction; 200 XkbSASetGroup(&filter->upAction.group,xkbi->groupChange); 201 } 202 } 203 else if (filter->keycode==keycode) { 204 if (filter->upAction.type==XkbSA_SetMods) { 205 xkbi->clearMods = filter->upAction.mods.mask; 206 if (filter->upAction.mods.flags&XkbSA_ClearLocks) { 207 xkbi->state.locked_mods&= ~filter->upAction.mods.mask; 208 } 209 } 210 else { 211 if (filter->upAction.group.flags&XkbSA_ClearLocks) { 212 xkbi->state.locked_group = 0; 213 } 214 xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); 215 } 216 filter->active = 0; 217 } 218 else { 219 filter->upAction.mods.flags&= ~XkbSA_ClearLocks; 220 filter->filterOthers = 0; 221 } 222 return 1; 223} 224 225#define LATCH_KEY_DOWN 1 226#define LATCH_PENDING 2 227#define NO_LATCH 3 228 229static int 230_XkbFilterLatchState( XkbSrvInfoPtr xkbi, 231 XkbFilterPtr filter, 232 unsigned keycode, 233 XkbAction * pAction) 234{ 235 236 if (filter->keycode==0) { /* initial press */ 237 filter->keycode = keycode; 238 filter->active = 1; 239 filter->filterOthers = 1; 240 filter->priv = LATCH_KEY_DOWN; 241 filter->filter = _XkbFilterLatchState; 242 if (pAction->type==XkbSA_LatchMods) { 243 filter->upAction = *pAction; 244 xkbi->setMods = pAction->mods.mask; 245 } 246 else { 247 xkbi->groupChange = XkbSAGroup(&pAction->group); 248 if (pAction->group.flags&XkbSA_GroupAbsolute) 249 xkbi->groupChange-= xkbi->state.base_group; 250 filter->upAction= *pAction; 251 XkbSASetGroup(&filter->upAction.group,xkbi->groupChange); 252 } 253 } 254 else if ( pAction && (filter->priv==LATCH_PENDING) ) { 255 if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) { 256 filter->active = 0; 257 if (filter->upAction.type==XkbSA_LatchMods) 258 xkbi->state.latched_mods&= ~filter->upAction.mods.mask; 259 else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group); 260 } 261 else if ((pAction->type==filter->upAction.type)&& 262 (pAction->mods.flags==filter->upAction.mods.flags)&& 263 (pAction->mods.mask==filter->upAction.mods.mask)) { 264 if (filter->upAction.mods.flags&XkbSA_LatchToLock) { 265 XkbControlsPtr ctrls= xkbi->desc->ctrls; 266 if (filter->upAction.type==XkbSA_LatchMods) 267 pAction->mods.type= XkbSA_LockMods; 268 else pAction->group.type= XkbSA_LockGroup; 269 if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&& 270 (ctrls->enabled_ctrls&XkbStickyKeysMask)) { 271 XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK, 272 XkbStickyKeysMask); 273 } 274 } 275 else { 276 if (filter->upAction.type==XkbSA_LatchMods) 277 pAction->mods.type= XkbSA_SetMods; 278 else pAction->group.type= XkbSA_SetGroup; 279 } 280 if (filter->upAction.type==XkbSA_LatchMods) 281 xkbi->state.latched_mods&= ~filter->upAction.mods.mask; 282 else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group); 283 filter->active = 0; 284 } 285 } 286 else if (filter->keycode==keycode) { /* release */ 287 XkbControlsPtr ctrls= xkbi->desc->ctrls; 288 int needBeep; 289 int beepType= _BEEP_NONE; 290 291 needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&& 292 XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)); 293 if (filter->upAction.type==XkbSA_LatchMods) { 294 xkbi->clearMods = filter->upAction.mods.mask; 295 if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&& 296 (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) { 297 xkbi->state.locked_mods&= ~xkbi->clearMods; 298 filter->priv= NO_LATCH; 299 beepType= _BEEP_STICKY_UNLOCK; 300 } 301 } 302 else { 303 xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); 304 if ((filter->upAction.group.flags&XkbSA_ClearLocks)&& 305 (xkbi->state.locked_group)) { 306 xkbi->state.locked_group = 0; 307 filter->priv = NO_LATCH; 308 beepType= _BEEP_STICKY_UNLOCK; 309 } 310 } 311 if (filter->priv==NO_LATCH) { 312 filter->active= 0; 313 } 314 else { 315 filter->priv= LATCH_PENDING; 316 if (filter->upAction.type==XkbSA_LatchMods) { 317 xkbi->state.latched_mods |= filter->upAction.mods.mask; 318 needBeep = xkbi->state.latched_mods ? needBeep : 0; 319 xkbi->state.latched_mods |= filter->upAction.mods.mask; 320 } 321 else { 322 xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group); 323 } 324 if (needBeep && (beepType==_BEEP_NONE)) 325 beepType= _BEEP_STICKY_LATCH; 326 } 327 if (needBeep && (beepType!=_BEEP_NONE)) 328 XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask); 329 } 330 else if (filter->priv==LATCH_KEY_DOWN) { 331 filter->priv= NO_LATCH; 332 filter->filterOthers = 0; 333 } 334 return 1; 335} 336 337static int 338_XkbFilterLockState( XkbSrvInfoPtr xkbi, 339 XkbFilterPtr filter, 340 unsigned keycode, 341 XkbAction * pAction) 342{ 343 if (pAction&&(pAction->type==XkbSA_LockGroup)) { 344 if (pAction->group.flags&XkbSA_GroupAbsolute) 345 xkbi->state.locked_group= XkbSAGroup(&pAction->group); 346 else xkbi->state.locked_group+= XkbSAGroup(&pAction->group); 347 return 1; 348 } 349 if (filter->keycode==0) { /* initial press */ 350 filter->keycode = keycode; 351 filter->active = 1; 352 filter->filterOthers = 0; 353 filter->priv = 0; 354 filter->filter = _XkbFilterLockState; 355 filter->upAction = *pAction; 356 xkbi->state.locked_mods^= pAction->mods.mask; 357 xkbi->setMods = pAction->mods.mask; 358 } 359 else if (filter->keycode==keycode) { 360 filter->active = 0; 361 xkbi->clearMods = filter->upAction.mods.mask; 362 } 363 return 1; 364} 365 366#define ISO_KEY_DOWN 0 367#define NO_ISO_LOCK 1 368 369static int 370_XkbFilterISOLock( XkbSrvInfoPtr xkbi, 371 XkbFilterPtr filter, 372 unsigned keycode, 373 XkbAction * pAction) 374{ 375 376 if (filter->keycode==0) { /* initial press */ 377 CARD8 flags= pAction->iso.flags; 378 379 filter->keycode = keycode; 380 filter->active = 1; 381 filter->filterOthers = 1; 382 filter->priv = ISO_KEY_DOWN; 383 filter->upAction = *pAction; 384 filter->filter = _XkbFilterISOLock; 385 if (flags&XkbSA_ISODfltIsGroup) { 386 xkbi->groupChange = XkbSAGroup(&pAction->iso); 387 xkbi->setMods = 0; 388 } 389 else { 390 xkbi->setMods = pAction->iso.mask; 391 xkbi->groupChange = 0; 392 } 393 if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) { 394 filter->priv= NO_ISO_LOCK; 395 xkbi->state.locked_mods^= xkbi->state.base_mods; 396 } 397 if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) { 398/* 6/22/93 (ef) -- lock groups if group key is down first */ 399 } 400 if (!(flags&XkbSA_ISONoAffectPtr)) { 401/* 6/22/93 (ef) -- lock mouse buttons if they're down */ 402 } 403 } 404 else if (filter->keycode==keycode) { 405 CARD8 flags= filter->upAction.iso.flags; 406 407 if (flags&XkbSA_ISODfltIsGroup) { 408 xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso); 409 xkbi->clearMods = 0; 410 if (filter->priv==ISO_KEY_DOWN) 411 xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso); 412 } 413 else { 414 xkbi->clearMods= filter->upAction.iso.mask; 415 xkbi->groupChange= 0; 416 if (filter->priv==ISO_KEY_DOWN) 417 xkbi->state.locked_mods^= filter->upAction.iso.mask; 418 } 419 filter->active = 0; 420 } 421 else if (pAction) { 422 CARD8 flags= filter->upAction.iso.flags; 423 424 switch (pAction->type) { 425 case XkbSA_SetMods: case XkbSA_LatchMods: 426 if (!(flags&XkbSA_ISONoAffectMods)) { 427 pAction->type= XkbSA_LockMods; 428 filter->priv= NO_ISO_LOCK; 429 } 430 break; 431 case XkbSA_SetGroup: case XkbSA_LatchGroup: 432 if (!(flags&XkbSA_ISONoAffectGroup)) { 433 pAction->type= XkbSA_LockGroup; 434 filter->priv= NO_ISO_LOCK; 435 } 436 break; 437 case XkbSA_PtrBtn: 438 if (!(flags&XkbSA_ISONoAffectPtr)) { 439 pAction->type= XkbSA_LockPtrBtn; 440 filter->priv= NO_ISO_LOCK; 441 } 442 break; 443 case XkbSA_SetControls: 444 if (!(flags&XkbSA_ISONoAffectCtrls)) { 445 pAction->type= XkbSA_LockControls; 446 filter->priv= NO_ISO_LOCK; 447 } 448 break; 449 } 450 } 451 return 1; 452} 453 454 455static CARD32 456_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg) 457{ 458XkbSrvInfoPtr xkbi= (XkbSrvInfoPtr)arg; 459XkbControlsPtr ctrls= xkbi->desc->ctrls; 460int dx,dy; 461 462 if (xkbi->mouseKey==0) 463 return 0; 464 465 if (xkbi->mouseKeysAccel) { 466 if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) { 467 double step; 468 xkbi->mouseKeysCounter++; 469 step= xkbi->mouseKeysCurveFactor* 470 pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve); 471 if (xkbi->mouseKeysDX<0) 472 dx= floor( ((double)xkbi->mouseKeysDX)*step ); 473 else dx= ceil( ((double)xkbi->mouseKeysDX)*step ); 474 if (xkbi->mouseKeysDY<0) 475 dy= floor( ((double)xkbi->mouseKeysDY)*step ); 476 else dy= ceil( ((double)xkbi->mouseKeysDY)*step ); 477 } 478 else { 479 dx= xkbi->mouseKeysDX*ctrls->mk_max_speed; 480 dy= xkbi->mouseKeysDY*ctrls->mk_max_speed; 481 } 482 if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX) 483 dx= xkbi->mouseKeysDX; 484 if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY) 485 dy= xkbi->mouseKeysDY; 486 } 487 else { 488 dx= xkbi->mouseKeysDX; 489 dy= xkbi->mouseKeysDY; 490 } 491 XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy); 492 return xkbi->desc->ctrls->mk_interval; 493} 494 495static int 496_XkbFilterPointerMove( XkbSrvInfoPtr xkbi, 497 XkbFilterPtr filter, 498 unsigned keycode, 499 XkbAction * pAction) 500{ 501int x,y; 502Bool accel; 503 504 if (filter->keycode==0) { /* initial press */ 505 filter->keycode = keycode; 506 filter->active = 1; 507 filter->filterOthers = 0; 508 filter->priv=0; 509 filter->filter = _XkbFilterPointerMove; 510 filter->upAction= *pAction; 511 xkbi->mouseKeysCounter= 0; 512 xkbi->mouseKey= keycode; 513 accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0); 514 x= XkbPtrActionX(&pAction->ptr); 515 y= XkbPtrActionY(&pAction->ptr); 516 XkbFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y); 517 AccessXCancelRepeatKey(xkbi,keycode); 518 xkbi->mouseKeysAccel= accel&& 519 (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask); 520 xkbi->mouseKeysFlags= pAction->ptr.flags; 521 xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr); 522 xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr); 523 xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 524 xkbi->desc->ctrls->mk_delay, 525 _XkbPtrAccelExpire,(pointer)xkbi); 526 } 527 else if (filter->keycode==keycode) { 528 filter->active = 0; 529 if (xkbi->mouseKey==keycode) { 530 xkbi->mouseKey= 0; 531 xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0, 532 NULL, NULL); 533 } 534 } 535 return 0; 536} 537 538static int 539_XkbFilterPointerBtn( XkbSrvInfoPtr xkbi, 540 XkbFilterPtr filter, 541 unsigned keycode, 542 XkbAction * pAction) 543{ 544 if (filter->keycode==0) { /* initial press */ 545 int button= pAction->btn.button; 546 547 if (button==XkbSA_UseDfltButton) 548 button = xkbi->desc->ctrls->mk_dflt_btn; 549 550 filter->keycode = keycode; 551 filter->active = 1; 552 filter->filterOthers = 0; 553 filter->priv=0; 554 filter->filter = _XkbFilterPointerBtn; 555 filter->upAction= *pAction; 556 filter->upAction.btn.button= button; 557 switch (pAction->type) { 558 case XkbSA_LockPtrBtn: 559 if (((xkbi->lockedPtrButtons&(1<<button))==0)&& 560 ((pAction->btn.flags&XkbSA_LockNoLock)==0)) { 561 xkbi->lockedPtrButtons|= (1<<button); 562 AccessXCancelRepeatKey(xkbi,keycode); 563 XkbFakeDeviceButton(xkbi->device, 1, button); 564 filter->upAction.type= XkbSA_NoAction; 565 } 566 break; 567 case XkbSA_PtrBtn: 568 { 569 register int i,nClicks; 570 AccessXCancelRepeatKey(xkbi,keycode); 571 if (pAction->btn.count>0) { 572 nClicks= pAction->btn.count; 573 for (i=0;i<nClicks;i++) { 574 XkbFakeDeviceButton(xkbi->device, 1, button); 575 XkbFakeDeviceButton(xkbi->device, 0, button); 576 } 577 filter->upAction.type= XkbSA_NoAction; 578 } 579 else XkbFakeDeviceButton(xkbi->device, 1, button); 580 } 581 break; 582 case XkbSA_SetPtrDflt: 583 { 584 XkbControlsPtr ctrls= xkbi->desc->ctrls; 585 XkbControlsRec old; 586 xkbControlsNotify cn; 587 588 old= *ctrls; 589 AccessXCancelRepeatKey(xkbi,keycode); 590 switch (pAction->dflt.affect) { 591 case XkbSA_AffectDfltBtn: 592 if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute) 593 ctrls->mk_dflt_btn= 594 XkbSAPtrDfltValue(&pAction->dflt); 595 else { 596 ctrls->mk_dflt_btn+= 597 XkbSAPtrDfltValue(&pAction->dflt); 598 if (ctrls->mk_dflt_btn>5) 599 ctrls->mk_dflt_btn= 5; 600 else if (ctrls->mk_dflt_btn<1) 601 ctrls->mk_dflt_btn= 1; 602 } 603 break; 604 default: 605 ErrorF( 606 "Attempt to change unknown pointer default (%d) ignored\n", 607 pAction->dflt.affect); 608 break; 609 } 610 if (XkbComputeControlsNotify(xkbi->device, 611 &old,xkbi->desc->ctrls, 612 &cn,FALSE)) { 613 cn.keycode = keycode; 614 /* XXX: what about DeviceKeyPress? */ 615 cn.eventType = KeyPress; 616 cn.requestMajor = 0; 617 cn.requestMinor = 0; 618 XkbSendControlsNotify(xkbi->device,&cn); 619 } 620 } 621 break; 622 } 623 } 624 else if (filter->keycode==keycode) { 625 int button= filter->upAction.btn.button; 626 627 switch (filter->upAction.type) { 628 case XkbSA_LockPtrBtn: 629 if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)|| 630 ((xkbi->lockedPtrButtons&(1<<button))==0)) { 631 break; 632 } 633 xkbi->lockedPtrButtons&= ~(1<<button); 634 635 if (IsMaster(xkbi->device)) 636 { 637 XkbMergeLockedPtrBtns(xkbi->device); 638 /* One SD still has lock set, don't post event */ 639 if ((xkbi->lockedPtrButtons & (1 << button)) != 0) 640 break; 641 } 642 643 /* fallthrough */ 644 case XkbSA_PtrBtn: 645 XkbFakeDeviceButton(xkbi->device, 0, button); 646 break; 647 } 648 filter->active = 0; 649 } 650 return 0; 651} 652 653static int 654_XkbFilterControls( XkbSrvInfoPtr xkbi, 655 XkbFilterPtr filter, 656 unsigned keycode, 657 XkbAction * pAction) 658{ 659XkbControlsRec old; 660XkbControlsPtr ctrls; 661DeviceIntPtr kbd; 662unsigned int change; 663XkbEventCauseRec cause; 664 665 kbd= xkbi->device; 666 ctrls= xkbi->desc->ctrls; 667 old= *ctrls; 668 if (filter->keycode==0) { /* initial press */ 669 filter->keycode = keycode; 670 filter->active = 1; 671 filter->filterOthers = 0; 672 change= XkbActionCtrls(&pAction->ctrls); 673 filter->priv = change; 674 filter->filter = _XkbFilterControls; 675 filter->upAction = *pAction; 676 677 if (pAction->type==XkbSA_LockControls) { 678 filter->priv= (ctrls->enabled_ctrls&change); 679 change&= ~ctrls->enabled_ctrls; 680 } 681 682 if (change) { 683 xkbControlsNotify cn; 684 XkbSrvLedInfoPtr sli; 685 686 ctrls->enabled_ctrls|= change; 687 if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) { 688 cn.keycode = keycode; 689 /* XXX: what about DeviceKeyPress? */ 690 cn.eventType = KeyPress; 691 cn.requestMajor = 0; 692 cn.requestMinor = 0; 693 XkbSendControlsNotify(kbd,&cn); 694 } 695 696 XkbSetCauseKey(&cause,keycode,KeyPress); 697 698 /* If sticky keys were disabled, clear all locks and latches */ 699 if ((old.enabled_ctrls&XkbStickyKeysMask)&& 700 (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) { 701 XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause); 702 } 703 sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); 704 XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause); 705 if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) 706 XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change); 707 } 708 } 709 else if (filter->keycode==keycode) { 710 change= filter->priv; 711 if (change) { 712 xkbControlsNotify cn; 713 XkbSrvLedInfoPtr sli; 714 715 ctrls->enabled_ctrls&= ~change; 716 if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) { 717 cn.keycode = keycode; 718 cn.eventType = KeyRelease; 719 cn.requestMajor = 0; 720 cn.requestMinor = 0; 721 XkbSendControlsNotify(kbd,&cn); 722 } 723 724 XkbSetCauseKey(&cause,keycode,KeyRelease); 725 /* If sticky keys were disabled, clear all locks and latches */ 726 if ((old.enabled_ctrls&XkbStickyKeysMask)&& 727 (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) { 728 XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause); 729 } 730 sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); 731 XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause); 732 if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) 733 XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change); 734 } 735 filter->keycode= 0; 736 filter->active= 0; 737 } 738 return 1; 739} 740 741static int 742_XkbFilterActionMessage(XkbSrvInfoPtr xkbi, 743 XkbFilterPtr filter, 744 unsigned keycode, 745 XkbAction * pAction) 746{ 747XkbMessageAction * pMsg; 748DeviceIntPtr kbd; 749 750 kbd= xkbi->device; 751 if (filter->keycode==0) { /* initial press */ 752 pMsg= &pAction->msg; 753 if ((pMsg->flags&XkbSA_MessageOnRelease)|| 754 ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) { 755 filter->keycode = keycode; 756 filter->active = 1; 757 filter->filterOthers = 0; 758 filter->priv = 0; 759 filter->filter = _XkbFilterActionMessage; 760 filter->upAction = *pAction; 761 } 762 if (pMsg->flags&XkbSA_MessageOnPress) { 763 xkbActionMessage msg; 764 765 msg.keycode= keycode; 766 msg.press= 1; 767 msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 768 memcpy((char *)msg.message, 769 (char *)pMsg->message,XkbActionMessageLength); 770 XkbSendActionMessage(kbd,&msg); 771 } 772 return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0); 773 } 774 else if (filter->keycode==keycode) { 775 pMsg= &filter->upAction.msg; 776 if (pMsg->flags&XkbSA_MessageOnRelease) { 777 xkbActionMessage msg; 778 779 msg.keycode= keycode; 780 msg.press= 0; 781 msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 782 memcpy((char *)msg.message,(char *)pMsg->message, 783 XkbActionMessageLength); 784 XkbSendActionMessage(kbd,&msg); 785 } 786 filter->keycode= 0; 787 filter->active= 0; 788 return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); 789 } 790 return 0; 791} 792 793static int 794_XkbFilterRedirectKey( XkbSrvInfoPtr xkbi, 795 XkbFilterPtr filter, 796 unsigned keycode, 797 XkbAction * pAction) 798{ 799DeviceEvent ev; 800int x,y; 801XkbStateRec old; 802unsigned mods,mask; 803xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device); 804ProcessInputProc backupproc; 805 806 /* never actually used uninitialised, but gcc isn't smart enough 807 * to work that out. */ 808 memset(&old, 0, sizeof(old)); 809 memset(&ev, 0, sizeof(ev)); 810 811 if ((filter->keycode!=0)&&(filter->keycode!=keycode)) 812 return 1; 813 814 GetSpritePosition(xkbi->device, &x,&y); 815 ev.header = ET_Internal; 816 ev.length = sizeof(DeviceEvent); 817 ev.time = GetTimeInMillis(); 818 ev.root_x = x; 819 ev.root_y = y; 820 821 if (filter->keycode==0) { /* initial press */ 822 if ((pAction->redirect.new_key<xkbi->desc->min_key_code)|| 823 (pAction->redirect.new_key>xkbi->desc->max_key_code)) { 824 return 1; 825 } 826 filter->keycode = keycode; 827 filter->active = 1; 828 filter->filterOthers = 0; 829 filter->priv = 0; 830 filter->filter = _XkbFilterRedirectKey; 831 filter->upAction = *pAction; 832 833 ev.type = ET_KeyPress; 834 ev.detail.key = pAction->redirect.new_key; 835 836 mask= XkbSARedirectVModsMask(&pAction->redirect); 837 mods= XkbSARedirectVMods(&pAction->redirect); 838 if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask); 839 if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods); 840 mask|= pAction->redirect.mods_mask; 841 mods|= pAction->redirect.mods; 842 843 if ( mask || mods ) { 844 old= xkbi->state; 845 xkbi->state.base_mods&= ~mask; 846 xkbi->state.base_mods|= (mods&mask); 847 xkbi->state.latched_mods&= ~mask; 848 xkbi->state.latched_mods|= (mods&mask); 849 xkbi->state.locked_mods&= ~mask; 850 xkbi->state.locked_mods|= (mods&mask); 851 XkbComputeDerivedState(xkbi); 852 } 853 854 UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc); 855 xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device); 856 COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, 857 backupproc,xkbUnwrapProc); 858 859 if ( mask || mods ) 860 xkbi->state= old; 861 } 862 else if (filter->keycode==keycode) { 863 864 ev.type = ET_KeyRelease; 865 ev.detail.key = filter->upAction.redirect.new_key; 866 867 mask= XkbSARedirectVModsMask(&filter->upAction.redirect); 868 mods= XkbSARedirectVMods(&filter->upAction.redirect); 869 if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask); 870 if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods); 871 mask|= filter->upAction.redirect.mods_mask; 872 mods|= filter->upAction.redirect.mods; 873 874 if ( mask || mods ) { 875 old= xkbi->state; 876 xkbi->state.base_mods&= ~mask; 877 xkbi->state.base_mods|= (mods&mask); 878 xkbi->state.latched_mods&= ~mask; 879 xkbi->state.latched_mods|= (mods&mask); 880 xkbi->state.locked_mods&= ~mask; 881 xkbi->state.locked_mods|= (mods&mask); 882 XkbComputeDerivedState(xkbi); 883 } 884 885 UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc); 886 xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device); 887 COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, 888 backupproc,xkbUnwrapProc); 889 890 if ( mask || mods ) 891 xkbi->state= old; 892 893 filter->keycode= 0; 894 filter->active= 0; 895 } 896 return 0; 897} 898 899static int 900_XkbFilterSwitchScreen( XkbSrvInfoPtr xkbi, 901 XkbFilterPtr filter, 902 unsigned keycode, 903 XkbAction * pAction) 904{ 905 DeviceIntPtr dev = xkbi->device; 906 if (dev == inputInfo.keyboard) 907 return 0; 908 909 if (filter->keycode==0) { /* initial press */ 910 filter->keycode = keycode; 911 filter->active = 1; 912 filter->filterOthers = 0; 913 filter->filter = _XkbFilterSwitchScreen; 914 AccessXCancelRepeatKey(xkbi, keycode); 915 XkbDDXSwitchScreen(dev,keycode,pAction); 916 return 0; 917 } 918 else if (filter->keycode==keycode) { 919 filter->active= 0; 920 return 0; 921 } 922 return 1; 923} 924 925static int 926_XkbFilterXF86Private( XkbSrvInfoPtr xkbi, 927 XkbFilterPtr filter, 928 unsigned keycode, 929 XkbAction * pAction) 930{ 931 DeviceIntPtr dev = xkbi->device; 932 if (dev == inputInfo.keyboard) 933 return 0; 934 935 if (filter->keycode==0) { /* initial press */ 936 filter->keycode = keycode; 937 filter->active = 1; 938 filter->filterOthers = 0; 939 filter->filter = _XkbFilterXF86Private; 940 XkbDDXPrivate(dev,keycode,pAction); 941 return 0; 942 } 943 else if (filter->keycode==keycode) { 944 filter->active= 0; 945 return 0; 946 } 947 return 1; 948} 949 950 951static int 952_XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi, 953 XkbFilterPtr filter, 954 unsigned keycode, 955 XkbAction * pAction) 956{ 957DeviceIntPtr dev; 958int button; 959 960 if (xkbi->device == inputInfo.keyboard) 961 return 0; 962 963 if (filter->keycode==0) { /* initial press */ 964 _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient, 965 DixUnknownAccess, &button); 966 if (!dev || !dev->public.on) 967 return 1; 968 969 button= pAction->devbtn.button; 970 if ((button<1)||(button>dev->button->numButtons)) 971 return 1; 972 973 filter->keycode = keycode; 974 filter->active = 1; 975 filter->filterOthers = 0; 976 filter->priv=0; 977 filter->filter = _XkbFilterDeviceBtn; 978 filter->upAction= *pAction; 979 switch (pAction->type) { 980 case XkbSA_LockDeviceBtn: 981 if ((pAction->devbtn.flags&XkbSA_LockNoLock)|| 982 BitIsOn(dev->button->down, button)) 983 return 0; 984 XkbFakeDeviceButton(dev,TRUE,button); 985 filter->upAction.type= XkbSA_NoAction; 986 break; 987 case XkbSA_DeviceBtn: 988 if (pAction->devbtn.count>0) { 989 int nClicks,i; 990 nClicks= pAction->btn.count; 991 for (i=0;i<nClicks;i++) { 992 XkbFakeDeviceButton(dev,TRUE,button); 993 XkbFakeDeviceButton(dev,FALSE,button); 994 } 995 filter->upAction.type= XkbSA_NoAction; 996 } 997 else XkbFakeDeviceButton(dev,TRUE,button); 998 break; 999 } 1000 } 1001 else if (filter->keycode==keycode) { 1002 int button; 1003 1004 filter->active= 0; 1005 _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device, 1006 serverClient, DixUnknownAccess, &button); 1007 if (!dev || !dev->public.on) 1008 return 1; 1009 1010 button= filter->upAction.btn.button; 1011 switch (filter->upAction.type) { 1012 case XkbSA_LockDeviceBtn: 1013 if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)|| 1014 !BitIsOn(dev->button->down, button)) 1015 return 0; 1016 XkbFakeDeviceButton(dev,FALSE,button); 1017 break; 1018 case XkbSA_DeviceBtn: 1019 XkbFakeDeviceButton(dev,FALSE,button); 1020 break; 1021 } 1022 filter->active = 0; 1023 } 1024 return 0; 1025} 1026 1027static XkbFilterPtr 1028_XkbNextFreeFilter( 1029 XkbSrvInfoPtr xkbi 1030) 1031{ 1032register int i; 1033 1034 if (xkbi->szFilters==0) { 1035 xkbi->szFilters = 4; 1036 xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec)); 1037 /* 6/21/93 (ef) -- XXX! deal with allocation failure */ 1038 } 1039 for (i=0;i<xkbi->szFilters;i++) { 1040 if (!xkbi->filters[i].active) { 1041 xkbi->filters[i].keycode = 0; 1042 return &xkbi->filters[i]; 1043 } 1044 } 1045 xkbi->szFilters*=2; 1046 xkbi->filters= realloc(xkbi->filters, 1047 xkbi->szFilters * sizeof(XkbFilterRec)); 1048 /* 6/21/93 (ef) -- XXX! deal with allocation failure */ 1049 memset(&xkbi->filters[xkbi->szFilters/2], 0, 1050 (xkbi->szFilters/2)*sizeof(XkbFilterRec)); 1051 return &xkbi->filters[xkbi->szFilters/2]; 1052} 1053 1054static int 1055_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction) 1056{ 1057register int i,send; 1058 1059 send= 1; 1060 for (i=0;i<xkbi->szFilters;i++) { 1061 if ((xkbi->filters[i].active)&&(xkbi->filters[i].filter)) 1062 send= ((*xkbi->filters[i].filter)(xkbi,&xkbi->filters[i],kc,pAction) 1063 && send); 1064 } 1065 return send; 1066} 1067 1068void 1069XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent* event) 1070{ 1071int key,bit,i; 1072XkbSrvInfoPtr xkbi; 1073KeyClassPtr keyc; 1074int changed,sendEvent; 1075Bool genStateNotify; 1076XkbAction act; 1077XkbFilterPtr filter; 1078Bool keyEvent; 1079Bool pressEvent; 1080ProcessInputProc backupproc; 1081 1082xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev); 1083 1084 keyc= kbd->key; 1085 xkbi= keyc->xkbInfo; 1086 key= event->detail.key; 1087 /* The state may change, so if we're not in the middle of sending a state 1088 * notify, prepare for it */ 1089 if ((xkbi->flags&_XkbStateNotifyInProgress)==0) { 1090 xkbi->prev_state = xkbi->state; 1091 xkbi->flags|= _XkbStateNotifyInProgress; 1092 genStateNotify= TRUE; 1093 } 1094 else genStateNotify= FALSE; 1095 1096 xkbi->clearMods = xkbi->setMods = 0; 1097 xkbi->groupChange = 0; 1098 1099 sendEvent = 1; 1100 keyEvent= ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease)); 1101 pressEvent= ((event->type == ET_KeyPress)|| (event->type == ET_ButtonPress)); 1102 1103 if (pressEvent) { 1104 if (keyEvent) 1105 act = XkbGetKeyAction(xkbi,&xkbi->state,key); 1106 else { 1107 act = XkbGetButtonAction(kbd,dev,key); 1108 key|= BTN_ACT_FLAG; 1109 } 1110 sendEvent = _XkbApplyFilters(xkbi,key,&act); 1111 if (sendEvent) { 1112 switch (act.type) { 1113 case XkbSA_SetMods: 1114 case XkbSA_SetGroup: 1115 filter = _XkbNextFreeFilter(xkbi); 1116 sendEvent = _XkbFilterSetState(xkbi,filter,key,&act); 1117 break; 1118 case XkbSA_LatchMods: 1119 case XkbSA_LatchGroup: 1120 filter = _XkbNextFreeFilter(xkbi); 1121 sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act); 1122 break; 1123 case XkbSA_LockMods: 1124 case XkbSA_LockGroup: 1125 filter = _XkbNextFreeFilter(xkbi); 1126 sendEvent=_XkbFilterLockState(xkbi,filter,key,&act); 1127 break; 1128 case XkbSA_ISOLock: 1129 filter = _XkbNextFreeFilter(xkbi); 1130 sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act); 1131 break; 1132 case XkbSA_MovePtr: 1133 filter = _XkbNextFreeFilter(xkbi); 1134 sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act); 1135 break; 1136 case XkbSA_PtrBtn: 1137 case XkbSA_LockPtrBtn: 1138 case XkbSA_SetPtrDflt: 1139 filter = _XkbNextFreeFilter(xkbi); 1140 sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act); 1141 break; 1142 case XkbSA_Terminate: 1143 sendEvent= XkbDDXTerminateServer(dev,key,&act); 1144 break; 1145 case XkbSA_SwitchScreen: 1146 filter = _XkbNextFreeFilter(xkbi); 1147 sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act); 1148 break; 1149 case XkbSA_SetControls: 1150 case XkbSA_LockControls: 1151 filter = _XkbNextFreeFilter(xkbi); 1152 sendEvent=_XkbFilterControls(xkbi,filter,key,&act); 1153 break; 1154 case XkbSA_ActionMessage: 1155 filter = _XkbNextFreeFilter(xkbi); 1156 sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act); 1157 break; 1158 case XkbSA_RedirectKey: 1159 filter = _XkbNextFreeFilter(xkbi); 1160 sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act); 1161 break; 1162 case XkbSA_DeviceBtn: 1163 case XkbSA_LockDeviceBtn: 1164 filter = _XkbNextFreeFilter(xkbi); 1165 sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act); 1166 break; 1167 case XkbSA_XFree86Private: 1168 filter = _XkbNextFreeFilter(xkbi); 1169 sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act); 1170 break; 1171 } 1172 } 1173 } 1174 else { 1175 if (!keyEvent) 1176 key|= BTN_ACT_FLAG; 1177 sendEvent = _XkbApplyFilters(xkbi,key,NULL); 1178 } 1179 1180 if (xkbi->groupChange!=0) 1181 xkbi->state.base_group+= xkbi->groupChange; 1182 if (xkbi->setMods) { 1183 for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) { 1184 if (xkbi->setMods&bit) { 1185 keyc->modifierKeyCount[i]++; 1186 xkbi->state.base_mods|= bit; 1187 xkbi->setMods&= ~bit; 1188 } 1189 } 1190 } 1191 if (xkbi->clearMods) { 1192 for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) { 1193 if (xkbi->clearMods&bit) { 1194 keyc->modifierKeyCount[i]--; 1195 if (keyc->modifierKeyCount[i]<=0) { 1196 xkbi->state.base_mods&= ~bit; 1197 keyc->modifierKeyCount[i] = 0; 1198 } 1199 xkbi->clearMods&= ~bit; 1200 } 1201 } 1202 } 1203 1204 if (sendEvent) { 1205 DeviceIntPtr tmpdev; 1206 if (keyEvent) 1207 tmpdev = dev; 1208 else 1209 tmpdev = GetPairedDevice(dev); 1210 1211 UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc); 1212 dev->public.processInputProc((InternalEvent*)event, tmpdev); 1213 COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, 1214 backupproc,xkbUnwrapProc); 1215 } 1216 else if (keyEvent) { 1217 FixKeyState(event, dev); 1218 } 1219 1220 XkbComputeDerivedState(xkbi); 1221 changed = XkbStateChangedFlags(&xkbi->prev_state,&xkbi->state); 1222 if (genStateNotify) { 1223 if (changed) { 1224 xkbStateNotify sn; 1225 sn.keycode= key; 1226 sn.eventType= event->type; 1227 sn.requestMajor = sn.requestMinor = 0; 1228 sn.changed= changed; 1229 XkbSendStateNotify(dev,&sn); 1230 } 1231 xkbi->flags&= ~_XkbStateNotifyInProgress; 1232 } 1233 changed= XkbIndicatorsToUpdate(dev,changed,FALSE); 1234 if (changed) { 1235 XkbEventCauseRec cause; 1236 XkbSetCauseKey(&cause, key, event->type); 1237 XkbUpdateIndicators(dev,changed,FALSE,NULL,&cause); 1238 } 1239 return; 1240} 1241 1242int 1243XkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches) 1244{ 1245XkbSrvInfoPtr xkbi; 1246XkbFilterPtr filter; 1247XkbAction act; 1248unsigned clear; 1249 1250 if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) { 1251 xkbi = pXDev->key->xkbInfo; 1252 clear= (mask&(~latches)); 1253 xkbi->state.latched_mods&= ~clear; 1254 /* Clear any pending latch to locks. 1255 */ 1256 act.type = XkbSA_NoAction; 1257 _XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act); 1258 act.type = XkbSA_LatchMods; 1259 act.mods.flags = 0; 1260 act.mods.mask = mask&latches; 1261 filter = _XkbNextFreeFilter(xkbi); 1262 _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act); 1263 _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL); 1264 return Success; 1265 } 1266 return BadValue; 1267} 1268 1269int 1270XkbLatchGroup(DeviceIntPtr pXDev,int group) 1271{ 1272XkbSrvInfoPtr xkbi; 1273XkbFilterPtr filter; 1274XkbAction act; 1275 1276 if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) { 1277 xkbi = pXDev->key->xkbInfo; 1278 act.type = XkbSA_LatchGroup; 1279 act.group.flags = 0; 1280 XkbSASetGroup(&act.group,group); 1281 filter = _XkbNextFreeFilter(xkbi); 1282 _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act); 1283 _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL); 1284 return Success; 1285 } 1286 return BadValue; 1287} 1288 1289/***====================================================================***/ 1290 1291void 1292XkbClearAllLatchesAndLocks( DeviceIntPtr dev, 1293 XkbSrvInfoPtr xkbi, 1294 Bool genEv, 1295 XkbEventCausePtr cause) 1296{ 1297XkbStateRec os; 1298xkbStateNotify sn; 1299 1300 sn.changed= 0; 1301 os= xkbi->state; 1302 if (os.latched_mods) { /* clear all latches */ 1303 XkbLatchModifiers(dev,~0,0); 1304 sn.changed|= XkbModifierLatchMask; 1305 } 1306 if (os.latched_group) { 1307 XkbLatchGroup(dev,0); 1308 sn.changed|= XkbGroupLatchMask; 1309 } 1310 if (os.locked_mods) { 1311 xkbi->state.locked_mods= 0; 1312 sn.changed|= XkbModifierLockMask; 1313 } 1314 if (os.locked_group) { 1315 xkbi->state.locked_group= 0; 1316 sn.changed|= XkbGroupLockMask; 1317 } 1318 if ( genEv && sn.changed) { 1319 CARD32 changed; 1320 1321 XkbComputeDerivedState(xkbi); 1322 sn.keycode= cause->kc; 1323 sn.eventType= cause->event; 1324 sn.requestMajor= cause->mjr; 1325 sn.requestMinor= cause->mnr; 1326 sn.changed= XkbStateChangedFlags(&os,&xkbi->state); 1327 XkbSendStateNotify(dev,&sn); 1328 changed= XkbIndicatorsToUpdate(dev,sn.changed,FALSE); 1329 if (changed) { 1330 XkbUpdateIndicators(dev,changed,TRUE,NULL,cause); 1331 } 1332 } 1333 return; 1334} 1335 1336/* 1337 * The event is injected into the event processing, not the EQ. Thus, 1338 * ensure that we restore the master after the event sequence to the 1339 * original set of classes. Otherwise, the master remains on the XTEST 1340 * classes and drops events that don't fit into the XTEST layout (e.g. 1341 * events with more than 2 valuators). 1342 * 1343 * FIXME: EQ injection in the processing stage is not designed for, so this 1344 * is a rather awkward hack. The event list returned by GetPointerEvents() 1345 * and friends is always prefixed with a DCE if the last _posted_ device was 1346 * different. For normal events, this sequence then resets the master during 1347 * the processing stage. Since we inject the PointerKey events in the 1348 * processing stage though, we need to manually reset to restore the 1349 * previous order, because the events already in the EQ must be sent for the 1350 * right device. 1351 * So we post-fix the event list we get from GPE with a DCE back to the 1352 * previous slave device. 1353 * 1354 * First one on drinking island wins! 1355 */ 1356static void 1357InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, int num_valuators, int *valuators) 1358{ 1359 ScreenPtr pScreen; 1360 EventListPtr events; 1361 int nevents, i; 1362 DeviceIntPtr ptr, mpointer, lastSlave = NULL; 1363 Bool saveWait; 1364 1365 if (IsMaster(dev)) { 1366 mpointer = GetMaster(dev, MASTER_POINTER); 1367 lastSlave = mpointer->u.lastSlave; 1368 ptr = GetXTestDevice(mpointer); 1369 } else if (!dev->u.master) 1370 ptr = dev; 1371 else 1372 return; 1373 1374 1375 events = InitEventList(GetMaximumEventsNum() + 1); 1376 OsBlockSignals(); 1377 pScreen = miPointerGetScreen(ptr); 1378 saveWait = miPointerSetWaitForUpdate(pScreen, FALSE); 1379 nevents = GetPointerEvents(events, ptr, type, button, flags, 0, 1380 num_valuators, valuators); 1381 if (IsMaster(dev) && (lastSlave && lastSlave != ptr)) 1382 UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT, &nevents); 1383 miPointerSetWaitForUpdate(pScreen, saveWait); 1384 OsReleaseSignals(); 1385 1386 for (i = 0; i < nevents; i++) 1387 mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL); 1388 1389 FreeEventList(events, GetMaximumEventsNum()); 1390 1391} 1392 1393static void 1394XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y) 1395{ 1396 int gpe_flags = 0; 1397 1398 /* ignore attached SDs */ 1399 if (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) != NULL) 1400 return; 1401 1402 if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY) 1403 gpe_flags = POINTER_ABSOLUTE; 1404 else 1405 gpe_flags = POINTER_RELATIVE; 1406 1407 InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, 2, (int[]){x, y}); 1408} 1409 1410void 1411XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button) 1412{ 1413 DeviceIntPtr ptr; 1414 int down; 1415 1416 /* If dev is a slave device, and the SD is attached, do nothing. If we'd 1417 * post through the attached master pointer we'd get duplicate events. 1418 * 1419 * if dev is a master keyboard, post through the XTEST device 1420 * 1421 * if dev is a floating slave, post through the device itself. 1422 */ 1423 1424 if (IsMaster(dev)) { 1425 DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER); 1426 ptr = GetXTestDevice(mpointer); 1427 } else if (!dev->u.master) 1428 ptr = dev; 1429 else 1430 return; 1431 1432 down = button_is_down(ptr, button, BUTTON_PROCESSED); 1433 if (press == down) 1434 return; 1435 1436 InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease, 1437 button, 0, 0, NULL); 1438} 1439