xkbEvents.c revision 05b261ec
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#define NEED_EVENTS 1 33#include <X11/X.h> 34#include <X11/Xproto.h> 35#include <X11/keysym.h> 36#include <X11/extensions/XI.h> 37#include <X11/extensions/XIproto.h> 38#include "inputstr.h" 39#include "windowstr.h" 40#include <xkbsrv.h> 41#include "xkb.h" 42 43/***====================================================================***/ 44 45void 46XkbSendNewKeyboardNotify(DeviceIntPtr kbd,xkbNewKeyboardNotify *pNKN) 47{ 48register int i; 49Time time; 50CARD16 changed; 51 52 pNKN->type = XkbEventCode + XkbEventBase; 53 pNKN->xkbType = XkbNewKeyboardNotify; 54 pNKN->time = time = GetTimeInMillis(); 55 changed = pNKN->changed; 56 57 for (i=1; i<currentMaxClients; i++) { 58 if ((!clients[i]) || clients[i]->clientGone || 59 (clients[i]->requestVector==InitialVector)) { 60 continue; 61 } 62 63 if (clients[i]->xkbClientFlags&_XkbClientInitialized) { 64 if (clients[i]->newKeyboardNotifyMask&changed) { 65 pNKN->sequenceNumber = clients[i]->sequence; 66 pNKN->time = time; 67 pNKN->changed = changed; 68 if ( clients[i]->swapped ) { 69 register int n; 70 swaps(&pNKN->sequenceNumber,n); 71 swapl(&pNKN->time,n); 72 swaps(&pNKN->changed,n); 73 } 74 WriteToClient(clients[i],sizeof(xEvent),(char *)pNKN); 75 if (changed&XkbNKN_KeycodesMask) { 76 clients[i]->minKC= pNKN->minKeyCode; 77 clients[i]->maxKC= pNKN->maxKeyCode; 78 } 79 } 80 } 81 else if (changed&XkbNKN_KeycodesMask) { 82 xEvent event; 83 event.u.u.type= MappingNotify; 84 event.u.mappingNotify.request= MappingKeyboard; 85 event.u.mappingNotify.firstKeyCode= clients[i]->minKC; 86 event.u.mappingNotify.count= clients[i]->maxKC-clients[i]->minKC+1; 87 event.u.u.sequenceNumber= clients[i]->sequence; 88 if (clients[i]->swapped) { 89 int n; 90 swaps(&event.u.u.sequenceNumber,n); 91 } 92 WriteToClient(clients[i],SIZEOF(xEvent), (char *)&event); 93 event.u.mappingNotify.request= MappingModifier; 94 WriteToClient(clients[i],SIZEOF(xEvent), (char *)&event); 95 } 96 } 97 return; 98} 99 100/***====================================================================***/ 101 102void 103XkbSendStateNotify(DeviceIntPtr kbd,xkbStateNotify *pSN) 104{ 105XkbSrvInfoPtr xkbi; 106XkbStatePtr state; 107XkbInterestPtr interest; 108Time time; 109register CARD16 changed,bState; 110 111 interest = kbd->xkb_interest; 112 if (!interest) 113 return; 114 xkbi = kbd->key->xkbInfo; 115 state= &xkbi->state; 116 117 pSN->type = XkbEventCode + XkbEventBase; 118 pSN->xkbType = XkbStateNotify; 119 pSN->deviceID = kbd->id; 120 pSN->time = time = GetTimeInMillis(); 121 pSN->mods = state->mods; 122 pSN->baseMods = state->base_mods; 123 pSN->latchedMods = state->latched_mods; 124 pSN->lockedMods = state->locked_mods; 125 pSN->group = state->group; 126 pSN->baseGroup = state->base_group; 127 pSN->latchedGroup = state->latched_group; 128 pSN->lockedGroup = state->locked_group; 129 pSN->compatState = state->compat_state; 130 pSN->grabMods = state->grab_mods; 131 pSN->compatGrabMods = state->compat_grab_mods; 132 pSN->lookupMods = state->lookup_mods; 133 pSN->compatLookupMods = state->compat_lookup_mods; 134 pSN->ptrBtnState = state->ptr_buttons; 135 changed = pSN->changed; 136 bState= pSN->ptrBtnState; 137 138 while (interest) { 139 if ((!interest->client->clientGone) && 140 (interest->client->requestVector != InitialVector) && 141 (interest->client->xkbClientFlags&_XkbClientInitialized) && 142 (interest->stateNotifyMask&changed)) { 143 pSN->sequenceNumber = interest->client->sequence; 144 pSN->time = time; 145 pSN->changed = changed; 146 pSN->ptrBtnState = bState; 147 if ( interest->client->swapped ) { 148 register int n; 149 swaps(&pSN->sequenceNumber,n); 150 swapl(&pSN->time,n); 151 swaps(&pSN->changed,n); 152 swaps(&pSN->ptrBtnState,n); 153 } 154 WriteToClient(interest->client, sizeof(xEvent), (char *)pSN); 155 } 156 interest= interest->next; 157 } 158 return; 159} 160 161/***====================================================================***/ 162 163void 164XkbSendMapNotify(DeviceIntPtr kbd,xkbMapNotify *pMN) 165{ 166int i; 167XkbSrvInfoPtr xkbi; 168unsigned time = 0,initialized; 169CARD16 changed; 170 171 xkbi = kbd->key->xkbInfo; 172 initialized= 0; 173 174 changed = pMN->changed; 175 pMN->minKeyCode= xkbi->desc->min_key_code; 176 pMN->maxKeyCode= xkbi->desc->max_key_code; 177 for (i=1; i<currentMaxClients; i++) { 178 if (clients[i] && ! clients[i]->clientGone && 179 (clients[i]->requestVector != InitialVector) && 180 (clients[i]->xkbClientFlags&_XkbClientInitialized) && 181 (clients[i]->mapNotifyMask&changed)) 182 { 183 if (!initialized) { 184 pMN->type = XkbEventCode + XkbEventBase; 185 pMN->xkbType = XkbMapNotify; 186 pMN->deviceID = kbd->id; 187 time = GetTimeInMillis(); 188 initialized= 1; 189 } 190 pMN->time= time; 191 pMN->sequenceNumber = clients[i]->sequence; 192 pMN->changed = changed; 193 if ( clients[i]->swapped ) { 194 register int n; 195 swaps(&pMN->sequenceNumber,n); 196 swapl(&pMN->time,n); 197 swaps(&pMN->changed,n); 198 } 199 WriteToClient(clients[i],sizeof(xEvent),(char *)pMN); 200 } 201 } 202 return; 203} 204 205int 206XkbComputeControlsNotify( DeviceIntPtr kbd, 207 XkbControlsPtr old, 208 XkbControlsPtr new, 209 xkbControlsNotify * pCN, 210 Bool forceCtrlProc) 211{ 212int i; 213CARD32 changedControls; 214 215 changedControls= 0; 216 217 if (!kbd || !kbd->kbdfeed) 218 return 0; 219 220 if (old->enabled_ctrls!=new->enabled_ctrls) 221 changedControls|= XkbControlsEnabledMask; 222 if ((old->repeat_delay!=new->repeat_delay)|| 223 (old->repeat_interval!=new->repeat_interval)) 224 changedControls|= XkbRepeatKeysMask; 225 for (i = 0; i < XkbPerKeyBitArraySize; i++) 226 if (old->per_key_repeat[i] != new->per_key_repeat[i]) 227 changedControls|= XkbPerKeyRepeatMask; 228 if (old->slow_keys_delay!=new->slow_keys_delay) 229 changedControls|= XkbSlowKeysMask; 230 if (old->debounce_delay!=new->debounce_delay) 231 changedControls|= XkbBounceKeysMask; 232 if ((old->mk_delay!=new->mk_delay)|| 233 (old->mk_interval!=new->mk_interval)|| 234 (old->mk_dflt_btn!=new->mk_dflt_btn)) 235 changedControls|= XkbMouseKeysMask; 236 if ((old->mk_time_to_max!=new->mk_time_to_max)|| 237 (old->mk_curve!=new->mk_curve)|| 238 (old->mk_max_speed!=new->mk_max_speed)) 239 changedControls|= XkbMouseKeysAccelMask; 240 if (old->ax_options!=new->ax_options) 241 changedControls|= XkbAccessXKeysMask; 242 if ((old->ax_options^new->ax_options) & XkbAX_SKOptionsMask) 243 changedControls|= XkbStickyKeysMask; 244 if ((old->ax_options^new->ax_options) & XkbAX_FBOptionsMask) 245 changedControls|= XkbAccessXFeedbackMask; 246 if ((old->ax_timeout!=new->ax_timeout)|| 247 (old->axt_ctrls_mask!=new->axt_ctrls_mask)|| 248 (old->axt_ctrls_values!=new->axt_ctrls_values)|| 249 (old->axt_opts_mask!=new->axt_opts_mask)|| 250 (old->axt_opts_values!= new->axt_opts_values)) { 251 changedControls|= XkbAccessXTimeoutMask; 252 } 253 if ((old->internal.mask!=new->internal.mask)|| 254 (old->internal.real_mods!=new->internal.real_mods)|| 255 (old->internal.vmods!=new->internal.vmods)) 256 changedControls|= XkbInternalModsMask; 257 if ((old->ignore_lock.mask!=new->ignore_lock.mask)|| 258 (old->ignore_lock.real_mods!=new->ignore_lock.real_mods)|| 259 (old->ignore_lock.vmods!=new->ignore_lock.vmods)) 260 changedControls|= XkbIgnoreLockModsMask; 261 262 if (new->enabled_ctrls&XkbRepeatKeysMask) 263 kbd->kbdfeed->ctrl.autoRepeat=TRUE; 264 else kbd->kbdfeed->ctrl.autoRepeat=FALSE; 265 266 if (kbd->kbdfeed && kbd->kbdfeed->CtrlProc && 267 (changedControls || forceCtrlProc)) 268 (*kbd->kbdfeed->CtrlProc)(kbd, &kbd->kbdfeed->ctrl); 269 270 if ((!changedControls)&&(old->num_groups==new->num_groups)) 271 return 0; 272 273 if (!kbd->xkb_interest) 274 return 0; 275 276 pCN->changedControls = changedControls; 277 pCN->enabledControls = new->enabled_ctrls; 278 pCN->enabledControlChanges = (new->enabled_ctrls^old->enabled_ctrls); 279 pCN->numGroups = new->num_groups; 280 281 return 1; 282} 283 284void 285XkbSendControlsNotify(DeviceIntPtr kbd,xkbControlsNotify *pCN) 286{ 287int initialized; 288CARD32 changedControls, enabledControls, enabledChanges = 0; 289XkbSrvInfoPtr xkbi; 290XkbInterestPtr interest; 291Time time = 0; 292 293 interest = kbd->xkb_interest; 294 if (!interest) 295 return; 296 xkbi = kbd->key->xkbInfo; 297 298 initialized = 0; 299 enabledControls = xkbi->desc->ctrls->enabled_ctrls; 300 changedControls = pCN->changedControls; 301 pCN->numGroups= xkbi->desc->ctrls->num_groups; 302 while (interest) { 303 if ((!interest->client->clientGone) && 304 (interest->client->requestVector != InitialVector) && 305 (interest->client->xkbClientFlags&_XkbClientInitialized) && 306 (interest->ctrlsNotifyMask&changedControls)) { 307 if (!initialized) { 308 pCN->type = XkbEventCode + XkbEventBase; 309 pCN->xkbType = XkbControlsNotify; 310 pCN->deviceID = kbd->id; 311 pCN->time = time = GetTimeInMillis(); 312 enabledChanges = pCN->enabledControlChanges; 313 initialized= 1; 314 } 315 pCN->changedControls = changedControls; 316 pCN->enabledControls = enabledControls; 317 pCN->enabledControlChanges = enabledChanges; 318 pCN->sequenceNumber = interest->client->sequence; 319 pCN->time = time; 320 if ( interest->client->swapped ) { 321 register int n; 322 swaps(&pCN->sequenceNumber,n); 323 swapl(&pCN->changedControls,n); 324 swapl(&pCN->enabledControls,n); 325 swapl(&pCN->enabledControlChanges,n); 326 swapl(&pCN->time,n); 327 } 328 WriteToClient(interest->client, sizeof(xEvent), (char *)pCN); 329 } 330 interest= interest->next; 331 } 332 return; 333} 334 335static void 336XkbSendIndicatorNotify(DeviceIntPtr kbd,int xkbType,xkbIndicatorNotify *pEv) 337{ 338int initialized; 339XkbInterestPtr interest; 340Time time = 0; 341CARD32 state,changed; 342 343 interest = kbd->xkb_interest; 344 if (!interest) 345 return; 346 347 initialized = 0; 348 state = pEv->state; 349 changed = pEv->changed; 350 while (interest) { 351 if ((!interest->client->clientGone) && 352 (interest->client->requestVector != InitialVector) && 353 (interest->client->xkbClientFlags&_XkbClientInitialized) && 354 (((xkbType==XkbIndicatorStateNotify)&& 355 (interest->iStateNotifyMask&changed))|| 356 ((xkbType==XkbIndicatorMapNotify)&& 357 (interest->iMapNotifyMask&changed)))) { 358 if (!initialized) { 359 pEv->type = XkbEventCode + XkbEventBase; 360 pEv->xkbType = xkbType; 361 pEv->deviceID = kbd->id; 362 pEv->time = time = GetTimeInMillis(); 363 initialized= 1; 364 } 365 pEv->sequenceNumber = interest->client->sequence; 366 pEv->time = time; 367 pEv->changed = changed; 368 pEv->state = state; 369 if ( interest->client->swapped ) { 370 register int n; 371 swaps(&pEv->sequenceNumber,n); 372 swapl(&pEv->time,n); 373 swapl(&pEv->changed,n); 374 swapl(&pEv->state,n); 375 } 376 WriteToClient(interest->client, sizeof(xEvent), (char *)pEv); 377 } 378 interest= interest->next; 379 } 380 return; 381} 382 383 384void 385XkbHandleBell( BOOL force, 386 BOOL eventOnly, 387 DeviceIntPtr kbd, 388 CARD8 percent, 389 pointer pCtrl, 390 CARD8 class, 391 Atom name, 392 WindowPtr pWin, 393 ClientPtr pClient) 394{ 395xkbBellNotify bn; 396int initialized; 397XkbSrvInfoPtr xkbi; 398XkbInterestPtr interest; 399CARD8 id; 400CARD16 pitch,duration; 401Time time = 0; 402XID winID = 0; 403 404 xkbi = kbd->key->xkbInfo; 405 406 if ((force||(xkbi->desc->ctrls->enabled_ctrls&XkbAudibleBellMask))&& 407 (!eventOnly)) { 408 if (kbd->kbdfeed->BellProc) 409 (*kbd->kbdfeed->BellProc)(percent,kbd,(pointer)pCtrl,class); 410 } 411 interest = kbd->xkb_interest; 412 if ((!interest)||(force)) 413 return; 414 415 if ((class==0)||(class==KbdFeedbackClass)) { 416 KeybdCtrl *pKeyCtrl= (KeybdCtrl *)pCtrl; 417 id= pKeyCtrl->id; 418 pitch= pKeyCtrl->bell_pitch; 419 duration= pKeyCtrl->bell_duration; 420 } 421 else if (class==BellFeedbackClass) { 422 BellCtrl *pBellCtrl= (BellCtrl *)pCtrl; 423 id= pBellCtrl->id; 424 pitch= pBellCtrl->pitch; 425 duration= pBellCtrl->duration; 426 } 427 else return; 428 429 initialized = 0; 430 while (interest) { 431 if ((!interest->client->clientGone) && 432 (interest->client->requestVector != InitialVector) && 433 (interest->client->xkbClientFlags&_XkbClientInitialized) && 434 (interest->bellNotifyMask)) { 435 if (!initialized) { 436 time = GetTimeInMillis(); 437 bn.type = XkbEventCode + XkbEventBase; 438 bn.xkbType = XkbBellNotify; 439 bn.deviceID = kbd->id; 440 bn.bellClass = class; 441 bn.bellID = id; 442 bn.percent= percent; 443 bn.eventOnly = (eventOnly!=0); 444 winID= (pWin?pWin->drawable.id:None); 445 initialized= 1; 446 } 447 bn.sequenceNumber = interest->client->sequence; 448 bn.time = time; 449 bn.pitch = pitch; 450 bn.duration = duration; 451 bn.name = name; 452 bn.window= winID; 453 if ( interest->client->swapped ) { 454 register int n; 455 swaps(&bn.sequenceNumber,n); 456 swapl(&bn.time,n); 457 swaps(&bn.pitch,n); 458 swaps(&bn.duration,n); 459 swapl(&bn.name,n); 460 swapl(&bn.window,n); 461 } 462 WriteToClient(interest->client, sizeof(xEvent), (char *)&bn); 463 } 464 interest= interest->next; 465 } 466 return; 467} 468 469void 470XkbSendAccessXNotify(DeviceIntPtr kbd,xkbAccessXNotify *pEv) 471{ 472int initialized; 473XkbInterestPtr interest; 474Time time = 0; 475CARD16 sk_delay,db_delay; 476 477 interest = kbd->xkb_interest; 478 if (!interest) 479 return; 480 481 initialized = 0; 482 sk_delay= pEv->slowKeysDelay; 483 db_delay= pEv->debounceDelay; 484 while (interest) { 485 if ((!interest->client->clientGone) && 486 (interest->client->requestVector != InitialVector) && 487 (interest->client->xkbClientFlags&_XkbClientInitialized) && 488 (interest->accessXNotifyMask&(1<<pEv->detail))) { 489 if (!initialized) { 490 pEv->type = XkbEventCode + XkbEventBase; 491 pEv->xkbType = XkbAccessXNotify; 492 pEv->deviceID = kbd->id; 493 pEv->time = time = GetTimeInMillis(); 494 initialized= 1; 495 } 496 pEv->sequenceNumber = interest->client->sequence; 497 pEv->time = time; 498 pEv->slowKeysDelay = sk_delay; 499 pEv->debounceDelay = db_delay; 500 if ( interest->client->swapped ) { 501 register int n; 502 swaps(&pEv->sequenceNumber,n); 503 swapl(&pEv->time,n); 504 swaps(&pEv->slowKeysDelay,n); 505 swaps(&pEv->debounceDelay,n); 506 } 507 WriteToClient(interest->client, sizeof(xEvent), (char *)pEv); 508 } 509 interest= interest->next; 510 } 511 return; 512} 513 514void 515XkbSendNamesNotify(DeviceIntPtr kbd,xkbNamesNotify *pEv) 516{ 517int initialized; 518XkbInterestPtr interest; 519Time time = 0; 520CARD16 changed,changedVirtualMods; 521CARD32 changedIndicators; 522 523 interest = kbd->xkb_interest; 524 if (!interest) 525 return; 526 527 initialized = 0; 528 changed= pEv->changed; 529 changedIndicators= pEv->changedIndicators; 530 changedVirtualMods= pEv->changedVirtualMods; 531 while (interest) { 532 if ((!interest->client->clientGone) && 533 (interest->client->requestVector != InitialVector) && 534 (interest->client->xkbClientFlags&_XkbClientInitialized) && 535 (interest->namesNotifyMask&pEv->changed)) { 536 if (!initialized) { 537 pEv->type = XkbEventCode + XkbEventBase; 538 pEv->xkbType = XkbNamesNotify; 539 pEv->deviceID = kbd->id; 540 pEv->time = time = GetTimeInMillis(); 541 initialized= 1; 542 } 543 pEv->sequenceNumber = interest->client->sequence; 544 pEv->time = time; 545 pEv->changed = changed; 546 pEv->changedIndicators = changedIndicators; 547 pEv->changedVirtualMods= changedVirtualMods; 548 if ( interest->client->swapped ) { 549 register int n; 550 swaps(&pEv->sequenceNumber,n); 551 swapl(&pEv->time,n); 552 swaps(&pEv->changed,n); 553 swapl(&pEv->changedIndicators,n); 554 swaps(&pEv->changedVirtualMods,n); 555 } 556 WriteToClient(interest->client, sizeof(xEvent), (char *)pEv); 557 } 558 interest= interest->next; 559 } 560 return; 561} 562 563void 564XkbSendCompatMapNotify(DeviceIntPtr kbd,xkbCompatMapNotify *pEv) 565{ 566int initialized; 567XkbInterestPtr interest; 568Time time = 0; 569CARD16 firstSI = 0, nSI = 0, nTotalSI = 0; 570 571 interest = kbd->xkb_interest; 572 if (!interest) 573 return; 574 575 initialized = 0; 576 while (interest) { 577 if ((!interest->client->clientGone) && 578 (interest->client->requestVector != InitialVector) && 579 (interest->client->xkbClientFlags&_XkbClientInitialized) && 580 (interest->compatNotifyMask)) { 581 if (!initialized) { 582 pEv->type = XkbEventCode + XkbEventBase; 583 pEv->xkbType = XkbCompatMapNotify; 584 pEv->deviceID = kbd->id; 585 pEv->time = time = GetTimeInMillis(); 586 firstSI= pEv->firstSI; 587 nSI= pEv->nSI; 588 nTotalSI= pEv->nTotalSI; 589 initialized= 1; 590 } 591 pEv->sequenceNumber = interest->client->sequence; 592 pEv->time = time; 593 pEv->firstSI = firstSI; 594 pEv->nSI = nSI; 595 pEv->nTotalSI = nTotalSI; 596 if ( interest->client->swapped ) { 597 register int n; 598 swaps(&pEv->sequenceNumber,n); 599 swapl(&pEv->time,n); 600 swaps(&pEv->firstSI,n); 601 swaps(&pEv->nSI,n); 602 swaps(&pEv->nTotalSI,n); 603 } 604 WriteToClient(interest->client, sizeof(xEvent), (char *)pEv); 605 } 606 interest= interest->next; 607 } 608 return; 609} 610 611void 612XkbSendActionMessage(DeviceIntPtr kbd,xkbActionMessage *pEv) 613{ 614int initialized; 615XkbSrvInfoPtr xkbi; 616XkbInterestPtr interest; 617Time time = 0; 618 619 xkbi = kbd->key->xkbInfo; 620 interest = kbd->xkb_interest; 621 if (!interest) 622 return; 623 624 initialized = 0; 625 pEv->mods= xkbi->state.mods; 626 pEv->group= xkbi->state.group; 627 while (interest) { 628 if ((!interest->client->clientGone) && 629 (interest->client->requestVector != InitialVector) && 630 (interest->client->xkbClientFlags&_XkbClientInitialized) && 631 (interest->actionMessageMask)) { 632 if (!initialized) { 633 pEv->type = XkbEventCode + XkbEventBase; 634 pEv->xkbType = XkbActionMessage; 635 pEv->deviceID = kbd->id; 636 pEv->sequenceNumber = interest->client->sequence; 637 pEv->time = time = GetTimeInMillis(); 638 initialized= 1; 639 } 640 pEv->sequenceNumber = interest->client->sequence; 641 pEv->time = time; 642 if ( interest->client->swapped ) { 643 register int n; 644 swaps(&pEv->sequenceNumber,n); 645 swapl(&pEv->time,n); 646 } 647 WriteToClient(interest->client, sizeof(xEvent), (char *)pEv); 648 } 649 interest= interest->next; 650 } 651 return; 652} 653 654void 655XkbSendExtensionDeviceNotify( DeviceIntPtr dev, 656 ClientPtr client, 657 xkbExtensionDeviceNotify * pEv) 658{ 659int initialized; 660XkbInterestPtr interest; 661Time time = 0; 662CARD32 defined, state; 663CARD16 reason, supported = 0; 664 665 interest = dev->xkb_interest; 666 if (!interest) 667 return; 668 669 initialized = 0; 670 reason= pEv->reason; 671 defined= pEv->ledsDefined; 672 state= pEv->ledState; 673 while (interest) { 674 if ((!interest->client->clientGone) && 675 (interest->client->requestVector != InitialVector) && 676 (interest->client->xkbClientFlags&_XkbClientInitialized) && 677 (interest->extDevNotifyMask&reason)) { 678 if (!initialized) { 679 pEv->type = XkbEventCode + XkbEventBase; 680 pEv->xkbType = XkbExtensionDeviceNotify; 681 pEv->deviceID = dev->id; 682 pEv->sequenceNumber = interest->client->sequence; 683 pEv->time = time = GetTimeInMillis(); 684 supported= pEv->supported; 685 initialized= 1; 686 } 687 else { 688 pEv->sequenceNumber = interest->client->sequence; 689 pEv->time = time; 690 pEv->ledsDefined= defined; 691 pEv->ledState= state; 692 pEv->reason= reason; 693 pEv->supported= supported; 694 } 695 if (client!=interest->client) { 696 /* only report UnsupportedFeature to the client that */ 697 /* issued the failing request */ 698 pEv->reason&= ~XkbXI_UnsupportedFeatureMask; 699 if ((interest->extDevNotifyMask&reason)==0) 700 continue; 701 } 702 if ( interest->client->swapped ) { 703 register int n; 704 swaps(&pEv->sequenceNumber,n); 705 swapl(&pEv->time,n); 706 swapl(&pEv->ledsDefined,n); 707 swapl(&pEv->ledState,n); 708 swaps(&pEv->reason,n); 709 swaps(&pEv->supported,n); 710 } 711 WriteToClient(interest->client, sizeof(xEvent), (char *)pEv); 712 } 713 interest= interest->next; 714 } 715 return; 716} 717 718void 719XkbSendNotification( DeviceIntPtr kbd, 720 XkbChangesPtr pChanges, 721 XkbEventCausePtr cause) 722{ 723XkbSrvLedInfoPtr sli; 724 725 sli= NULL; 726 if (pChanges->state_changes) { 727 xkbStateNotify sn; 728 sn.changed= pChanges->state_changes; 729 sn.keycode= cause->kc; 730 sn.eventType= cause->event; 731 sn.requestMajor= cause->mjr; 732 sn.requestMinor= cause->mnr; 733 XkbSendStateNotify(kbd,&sn); 734 } 735 if (pChanges->map.changed) { 736 xkbMapNotify mn; 737 mn.changed= pChanges->map.changed; 738 mn.firstType= pChanges->map.first_type; 739 mn.nTypes= pChanges->map.num_types; 740 mn.firstKeySym= pChanges->map.first_key_sym; 741 mn.nKeySyms= pChanges->map.num_key_syms; 742 mn.firstKeyAct= pChanges->map.first_key_act; 743 mn.nKeyActs= pChanges->map.num_key_acts; 744 mn.firstKeyBehavior= pChanges->map.first_key_behavior; 745 mn.nKeyBehaviors= pChanges->map.num_key_behaviors; 746 mn.virtualMods= pChanges->map.vmods; 747 mn.firstKeyExplicit= pChanges->map.first_key_explicit; 748 mn.nKeyExplicit= pChanges->map.num_key_explicit; 749 mn.firstModMapKey= pChanges->map.first_modmap_key; 750 mn.nModMapKeys= pChanges->map.num_modmap_keys; 751 mn.firstVModMapKey= pChanges->map.first_vmodmap_key; 752 mn.nVModMapKeys= pChanges->map.num_vmodmap_keys; 753 XkbSendMapNotify(kbd,&mn); 754 } 755 if ((pChanges->ctrls.changed_ctrls)|| 756 (pChanges->ctrls.enabled_ctrls_changes)) { 757 xkbControlsNotify cn; 758 cn.changedControls= pChanges->ctrls.changed_ctrls; 759 cn.enabledControlChanges= pChanges->ctrls.enabled_ctrls_changes; 760 cn.keycode= cause->kc; 761 cn.eventType= cause->event; 762 cn.requestMajor= cause->mjr; 763 cn.requestMinor= cause->mnr; 764 XkbSendControlsNotify(kbd,&cn); 765 } 766 if (pChanges->indicators.map_changes) { 767 xkbIndicatorNotify in; 768 if (sli==NULL) 769 sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); 770 in.state= sli->effectiveState; 771 in.changed= pChanges->indicators.map_changes; 772 XkbSendIndicatorNotify(kbd,XkbIndicatorMapNotify,&in); 773 } 774 if (pChanges->indicators.state_changes) { 775 xkbIndicatorNotify in; 776 if (sli==NULL) 777 sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); 778 in.state= sli->effectiveState; 779 in.changed= pChanges->indicators.state_changes; 780 XkbSendIndicatorNotify(kbd,XkbIndicatorStateNotify,&in); 781 } 782 if (pChanges->names.changed) { 783 xkbNamesNotify nn; 784 nn.changed= pChanges->names.changed; 785 nn.firstType= pChanges->names.first_type; 786 nn.nTypes= pChanges->names.num_types; 787 nn.firstLevelName= pChanges->names.first_lvl; 788 nn.nLevelNames= pChanges->names.num_lvls; 789 nn.nRadioGroups= pChanges->names.num_rg; 790 nn.changedVirtualMods= pChanges->names.changed_vmods; 791 nn.changedIndicators= pChanges->names.changed_indicators; 792 XkbSendNamesNotify(kbd,&nn); 793 } 794 if ((pChanges->compat.changed_groups)||(pChanges->compat.num_si>0)) { 795 xkbCompatMapNotify cmn; 796 cmn.changedGroups= pChanges->compat.changed_groups; 797 cmn.firstSI= pChanges->compat.first_si; 798 cmn.nSI= pChanges->compat.num_si; 799 cmn.nTotalSI= kbd->key->xkbInfo->desc->compat->num_si; 800 XkbSendCompatMapNotify(kbd,&cmn); 801 } 802 return; 803} 804 805/***====================================================================***/ 806 807Bool 808XkbFilterEvents(ClientPtr pClient,int nEvents,xEvent *xE) 809{ 810int i, button_mask; 811DeviceIntPtr pXDev = (DeviceIntPtr)LookupKeyboardDevice(); 812XkbSrvInfoPtr xkbi; 813 814 xkbi= pXDev->key->xkbInfo; 815 if ( pClient->xkbClientFlags & _XkbClientInitialized ) { 816#ifdef DEBUG 817 if ((xkbDebugFlags&0x10)&& 818 ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease)|| 819 (xE[0].u.u.type==DeviceKeyPress)|| 820 (xE[0].u.u.type == DeviceKeyRelease))) { 821 ErrorF("XKbFilterWriteEvents:\n"); 822 ErrorF(" Event state= 0x%04x\n",xE[0].u.keyButtonPointer.state); 823 ErrorF(" XkbLastRepeatEvent!=xE (0x%p!=0x%p) %s\n", 824 XkbLastRepeatEvent,xE, 825 ((XkbLastRepeatEvent!=(pointer)xE)?"True":"False")); 826 ErrorF(" (xkbClientEventsFlags&XWDA)==0 (0x%x) %s\n", 827 pClient->xkbClientFlags, 828 (_XkbWantsDetectableAutoRepeat(pClient)?"True":"False")); 829 ErrorF(" !IsRelease(%d) %s\n",xE[0].u.u.type, 830 (!_XkbIsReleaseEvent(xE[0].u.u.type))?"True":"False"); 831 } 832#endif /* DEBUG */ 833 if ( (XkbLastRepeatEvent==(pointer)xE) && 834 (_XkbWantsDetectableAutoRepeat(pClient)) && 835 (_XkbIsReleaseEvent(xE[0].u.u.type)) ) { 836 return False; 837 } 838 if ((pXDev->grab != NullGrab) && pXDev->fromPassiveGrab && 839 ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease)|| 840 (xE[0].u.u.type==DeviceKeyPress)|| 841 (xE[0].u.u.type == DeviceKeyRelease))) { 842 register unsigned state,flags; 843 844 flags= pClient->xkbClientFlags; 845 state= xkbi->state.compat_grab_mods; 846 if (flags & XkbPCF_GrabsUseXKBStateMask) { 847 int group; 848 if (flags&XkbPCF_LookupStateWhenGrabbed) { 849 group= xkbi->state.group; 850 state= xkbi->state.lookup_mods; 851 } 852 else { 853 state= xkbi->state.grab_mods; 854 group= xkbi->state.base_group+xkbi->state.latched_group; 855 if ((group<0)||(group>=xkbi->desc->ctrls->num_groups)) { 856 group= XkbAdjustGroup(group,xkbi->desc->ctrls); 857 } 858 } 859 state = XkbBuildCoreState(state, group); 860 } 861 else if (flags&XkbPCF_LookupStateWhenGrabbed) 862 state= xkbi->state.compat_lookup_mods; 863 xE[0].u.keyButtonPointer.state= state; 864 } 865 button_mask = 1 << xE[0].u.u.detail; 866 if (xE[0].u.u.type == ButtonPress && 867 ((xE[0].u.keyButtonPointer.state >> 7) & button_mask) == button_mask && 868 (xkbi->lockedPtrButtons & button_mask) == button_mask) { 869#ifdef DEBUG 870 /* If the MouseKeys is pressed, and the "real" mouse is also pressed 871 * when the mouse is released, the server does not behave properly. 872 * Faking a release of the button here solves the problem. 873 */ 874 ErrorF("Faking release of button %d\n", xE[0].u.u.detail); 875#endif 876 XkbDDXFakePointerButton(ButtonRelease, xE[0].u.u.detail); 877 } 878 } 879 else { 880 register CARD8 type; 881 882 for (i=0;i<nEvents;i++) { 883 type= xE[i].u.u.type; 884#ifdef DEBUG 885 if ((xkbDebugFlags&0x4)&& 886 ((xE[i].u.u.type==KeyPress)||(xE[i].u.u.type==KeyRelease)|| 887 (xE[i].u.u.type==DeviceKeyPress)|| 888 (xE[i].u.u.type == DeviceKeyRelease))) { 889 XkbStatePtr s= &xkbi->state; 890 ErrorF("XKbFilterWriteEvents (non-XKB):\n"); 891 ErrorF("event= 0x%04x\n",xE[i].u.keyButtonPointer.state); 892 ErrorF("lookup= 0x%02x, grab= 0x%02x\n",s->lookup_mods, 893 s->grab_mods); 894 ErrorF("compat lookup= 0x%02x, grab= 0x%02x\n", 895 s->compat_lookup_mods, 896 s->compat_grab_mods); 897 } 898#endif 899 if ( (type>=KeyPress)&&(type<=MotionNotify) ) { 900 CARD16 old,new; 901 902 old= xE[i].u.keyButtonPointer.state&(~0x1f00); 903 new= xE[i].u.keyButtonPointer.state&0x1F00; 904 905 if (old==XkbStateFieldFromRec(&xkbi->state)) 906 new|= xkbi->state.compat_lookup_mods; 907 else new|= xkbi->state.compat_grab_mods; 908 xE[i].u.keyButtonPointer.state= new; 909 } 910 else if ((type==EnterNotify)||(type==LeaveNotify)) { 911 xE[i].u.enterLeave.state&= 0x1F00; 912 xE[i].u.enterLeave.state|= xkbi->state.compat_grab_mods; 913 } else if ((type>=DeviceKeyPress)&&(type<=DeviceMotionNotify)) { 914 CARD16 old, new; 915 deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer*)&xE[i]; 916 old= kbp->state&(~0x1F00); 917 new= kbp->state&0x1F00; 918 if (old==XkbStateFieldFromRec(&xkbi->state)) 919 new|= xkbi->state.compat_lookup_mods; 920 else new|= xkbi->state.compat_grab_mods; 921 kbp->state= new; 922 } 923 button_mask = 1 << xE[i].u.u.detail; 924 if (type == ButtonPress && 925 ((xE[i].u.keyButtonPointer.state >> 7) & button_mask) == button_mask && 926 (xkbi->lockedPtrButtons & button_mask) == button_mask) { 927#ifdef DEBUG 928 ErrorF("Faking release of button %d\n", xE[i].u.u.detail); 929#endif 930 XkbDDXFakePointerButton(ButtonRelease, xE[i].u.u.detail); 931 } else if (type == DeviceButtonPress && 932 ((((deviceKeyButtonPointer*)&xE[i])->state >> 7) & button_mask) == button_mask && 933 (xkbi->lockedPtrButtons & button_mask) == button_mask) { 934#ifdef DEBUG 935 ErrorF("Faking release of button %d\n", ((deviceKeyButtonPointer*)&xE[i])->state); 936#endif 937 XkbDDXFakePointerButton(DeviceButtonRelease, ((deviceKeyButtonPointer*)&xE[i])->state); 938 } 939 } 940 } 941 return True; 942} 943 944/***====================================================================***/ 945 946XkbInterestPtr 947XkbFindClientResource(DevicePtr inDev,ClientPtr client) 948{ 949DeviceIntPtr dev = (DeviceIntPtr)inDev; 950XkbInterestPtr interest; 951 952 if ( dev->xkb_interest ) { 953 interest = dev->xkb_interest; 954 while (interest){ 955 if (interest->client==client) { 956 return interest; 957 } 958 interest = interest->next; 959 } 960 } 961 return NULL; 962} 963 964XkbInterestPtr 965XkbAddClientResource(DevicePtr inDev,ClientPtr client,XID id) 966{ 967DeviceIntPtr dev = (DeviceIntPtr)inDev; 968XkbInterestPtr interest; 969 970 interest = dev->xkb_interest; 971 while (interest) { 972 if (interest->client==client) 973 return ((interest->resource==id)?interest:NULL); 974 interest = interest->next; 975 } 976 interest = _XkbTypedAlloc(XkbInterestRec); 977 bzero(interest,sizeof(XkbInterestRec)); 978 if (interest) { 979 interest->dev = dev; 980 interest->client = client; 981 interest->resource = id; 982 interest->stateNotifyMask= 0; 983 interest->ctrlsNotifyMask= 0; 984 interest->namesNotifyMask= 0; 985 interest->compatNotifyMask= 0; 986 interest->bellNotifyMask= FALSE; 987 interest->accessXNotifyMask= 0; 988 interest->iStateNotifyMask= 0; 989 interest->iMapNotifyMask= 0; 990 interest->altSymsNotifyMask= 0; 991 interest->next = dev->xkb_interest; 992 dev->xkb_interest= interest; 993 return interest; 994 } 995 return NULL; 996} 997 998int 999XkbRemoveResourceClient(DevicePtr inDev,XID id) 1000{ 1001XkbSrvInfoPtr xkbi; 1002DeviceIntPtr dev = (DeviceIntPtr)inDev; 1003XkbInterestPtr interest; 1004Bool found; 1005unsigned long autoCtrls,autoValues; 1006ClientPtr client = NULL; 1007 1008 found= False; 1009 autoCtrls= autoValues= 0; 1010 if ( dev->xkb_interest ) { 1011 interest = dev->xkb_interest; 1012 if (interest && (interest->resource==id)){ 1013 dev->xkb_interest = interest->next; 1014 autoCtrls= interest->autoCtrls; 1015 autoValues= interest->autoCtrlValues; 1016 client= interest->client; 1017 _XkbFree(interest); 1018 found= True; 1019 } 1020 while ((!found)&&(interest->next)) { 1021 if (interest->next->resource==id) { 1022 XkbInterestPtr victim = interest->next; 1023 interest->next = victim->next; 1024 autoCtrls= victim->autoCtrls; 1025 autoValues= victim->autoCtrlValues; 1026 client= victim->client; 1027 _XkbFree(victim); 1028 found= True; 1029 } 1030 interest = interest->next; 1031 } 1032 } 1033 if (found && autoCtrls && dev->key && dev->key->xkbInfo ) { 1034 XkbEventCauseRec cause; 1035 1036 xkbi= dev->key->xkbInfo; 1037 XkbSetCauseXkbReq(&cause,X_kbPerClientFlags,client); 1038 XkbEnableDisableControls(xkbi,autoCtrls,autoValues,NULL,&cause); 1039 } 1040 return found; 1041} 1042