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