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