exevents.c revision 4642e01f
1/************************************************************ 2 3Copyright 1989, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25Copyright 1989 by Hewlett-Packard Company, Palo Alto, California. 26 27 All Rights Reserved 28 29Permission to use, copy, modify, and distribute this software and its 30documentation for any purpose and without fee is hereby granted, 31provided that the above copyright notice appear in all copies and that 32both that copyright notice and this permission notice appear in 33supporting documentation, and that the name of Hewlett-Packard not be 34used in advertising or publicity pertaining to distribution of the 35software without specific, written prior permission. 36 37HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 38ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 39HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 40ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 41WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 42ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 43SOFTWARE. 44 45********************************************************/ 46 47/******************************************************************** 48 * 49 * Routines to register and initialize extension input devices. 50 * This also contains ProcessOtherEvent, the routine called from DDX 51 * to route extension events. 52 * 53 */ 54 55#define NEED_EVENTS 56#ifdef HAVE_DIX_CONFIG_H 57#include <dix-config.h> 58#endif 59 60#include <X11/X.h> 61#include <X11/Xproto.h> 62#include <X11/extensions/XI.h> 63#include <X11/extensions/XIproto.h> 64#include <X11/extensions/geproto.h> 65#include "inputstr.h" 66#include "windowstr.h" 67#include "miscstruct.h" 68#include "region.h" 69#include "exevents.h" 70#include "extnsionst.h" 71#include "exglobals.h" 72#include "dixevents.h" /* DeliverFocusedEvent */ 73#include "dixgrabs.h" /* CreateGrab() */ 74#include "scrnintstr.h" 75#include "listdev.h" /* for CopySwapXXXClass */ 76#include "xace.h" 77 78#ifdef XKB 79#include <X11/extensions/XKBproto.h> 80#include "xkbsrv.h" 81extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies); 82#endif 83 84#define WID(w) ((w) ? ((w)->drawable.id) : 0) 85#define AllModifiersMask ( \ 86 ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \ 87 Mod3Mask | Mod4Mask | Mod5Mask ) 88#define AllButtonsMask ( \ 89 Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) 90#define Motion_Filter(class) (DevicePointerMotionMask | \ 91 (class)->state | (class)->motionMask) 92 93Bool ShouldFreeInputMasks(WindowPtr /* pWin */ , 94 Bool /* ignoreSelectedEvents */ 95 ); 96static Bool MakeInputMasks(WindowPtr /* pWin */ 97 ); 98 99/* Used to sture classes currently not in use by an MD */ 100extern DevPrivateKey UnusedClassesPrivateKey; 101 102 103void 104RegisterOtherDevice(DeviceIntPtr device) 105{ 106 device->public.processInputProc = ProcessOtherEvent; 107 device->public.realInputProc = ProcessOtherEvent; 108} 109 110Bool 111IsPointerEvent(xEvent* xE) 112{ 113 switch(xE->u.u.type) 114 { 115 case ButtonPress: 116 case ButtonRelease: 117 case MotionNotify: 118 case EnterNotify: 119 case LeaveNotify: 120 return TRUE; 121 default: 122 if (xE->u.u.type == DeviceButtonPress || 123 xE->u.u.type == DeviceButtonRelease || 124 xE->u.u.type == DeviceMotionNotify || 125 xE->u.u.type == ProximityIn || 126 xE->u.u.type == ProximityOut) 127 { 128 return TRUE; 129 } 130 } 131 return FALSE; 132} 133 134/** 135 * @return the device matching the deviceid of the device set in the event, or 136 * NULL if the event is not an XInput event. 137 */ 138DeviceIntPtr 139XIGetDevice(xEvent* xE) 140{ 141 DeviceIntPtr pDev = NULL; 142 143 if (xE->u.u.type == DeviceButtonPress || 144 xE->u.u.type == DeviceButtonRelease || 145 xE->u.u.type == DeviceMotionNotify || 146 xE->u.u.type == ProximityIn || 147 xE->u.u.type == ProximityOut || 148 xE->u.u.type == DevicePropertyNotify) 149 { 150 int rc; 151 int id; 152 153 id = ((deviceKeyButtonPointer*)xE)->deviceid & ~MORE_EVENTS; 154 155 rc = dixLookupDevice(&pDev, id, serverClient, DixUnknownAccess); 156 if (rc != Success) 157 ErrorF("[dix] XIGetDevice failed on XACE restrictions (%d)\n", rc); 158 } 159 return pDev; 160} 161 162 163/** 164 * Copy the device->key into master->key and send a mapping notify to the 165 * clients if appropriate. 166 * master->key needs to be allocated by the caller. 167 * 168 * Device is the slave device. If it is attached to a master device, we may 169 * need to send a mapping notify to the client because it causes the MD 170 * to change state. 171 * 172 * Mapping notify needs to be sent in the following cases: 173 * - different slave device on same master 174 * - different master 175 * 176 * XXX: They way how the code is we also send a map notify if the slave device 177 * stays the same, but the master changes. This isn't really necessary though. 178 * 179 * XXX: this gives you funny behaviour with the ClientPointer. When a 180 * MappingNotify is sent to the client, the client usually responds with a 181 * GetKeyboardMapping. This will retrieve the ClientPointer's keyboard 182 * mapping, regardless of which keyboard sent the last mapping notify request. 183 * So depending on the CP setting, your keyboard may change layout in each 184 * app... 185 * 186 * This code is basically the old SwitchCoreKeyboard. 187 */ 188 189void 190CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master) 191{ 192 static DeviceIntPtr lastMapNotifyDevice = NULL; 193 KeyClassPtr mk, dk; /* master, device */ 194 BOOL sendNotify = FALSE; 195 int i; 196 197 if (device == master) 198 return; 199 200 dk = device->key; 201 mk = master->key; 202 203 if (device != dixLookupPrivate(&master->devPrivates, 204 CoreDevicePrivateKey)) { 205 memcpy(mk->modifierMap, dk->modifierMap, MAP_LENGTH); 206 207 if (dk->maxKeysPerModifier) 208 { 209 mk->modifierKeyMap = xrealloc(mk->modifierKeyMap, 210 8 * dk->maxKeysPerModifier); 211 if (!mk->modifierKeyMap) 212 FatalError("[Xi] no memory for class shift.\n"); 213 memcpy(mk->modifierKeyMap, dk->modifierKeyMap, 214 (8 * dk->maxKeysPerModifier)); 215 } else 216 { 217 xfree(mk->modifierKeyMap); 218 mk->modifierKeyMap = NULL; 219 } 220 221 mk->maxKeysPerModifier = dk->maxKeysPerModifier; 222 mk->curKeySyms.minKeyCode = dk->curKeySyms.minKeyCode; 223 mk->curKeySyms.maxKeyCode = dk->curKeySyms.maxKeyCode; 224 SetKeySymsMap(&mk->curKeySyms, &dk->curKeySyms); 225 226 /* 227 * Copy state from the extended keyboard to core. If you omit this, 228 * holding Ctrl on keyboard one, and pressing Q on keyboard two, will 229 * cause your app to quit. This feels wrong to me, hence the below 230 * code. 231 * 232 * XXX: If you synthesise core modifier events, the state will get 233 * clobbered here. You'll have to work out something sensible 234 * to fix that. Good luck. 235 */ 236 237#define KEYBOARD_MASK (ShiftMask | LockMask | ControlMask | Mod1Mask | \ 238 Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask) 239 mk->state &= ~(KEYBOARD_MASK); 240 mk->state |= (dk->state & KEYBOARD_MASK); 241#undef KEYBOARD_MASK 242 for (i = 0; i < 8; i++) 243 mk->modifierKeyCount[i] = dk->modifierKeyCount[i]; 244 245#ifdef XKB 246 if (!noXkbExtension && dk->xkbInfo && dk->xkbInfo->desc) { 247 if (!mk->xkbInfo || !mk->xkbInfo->desc) 248 { 249 XkbInitDevice(master); 250 XkbFinishDeviceInit(master); 251 } 252 if (!XkbCopyKeymap(dk->xkbInfo->desc, mk->xkbInfo->desc, True)) 253 FatalError("Couldn't pivot keymap from device to core!\n"); 254 } 255#endif 256 257 dixSetPrivate(&master->devPrivates, CoreDevicePrivateKey, device); 258 sendNotify = TRUE; 259 } else if (lastMapNotifyDevice != master) 260 sendNotify = TRUE; 261 262 if (sendNotify) 263 { 264 SendMappingNotify(master, MappingKeyboard, 265 mk->curKeySyms.minKeyCode, 266 (mk->curKeySyms.maxKeyCode - 267 mk->curKeySyms.minKeyCode), 268 serverClient); 269 lastMapNotifyDevice = master; 270 } 271} 272 273/** 274 * Copies the feedback classes from device "from" into device "to". Classes 275 * are duplicated (not just flipping the pointers). All feedback classes are 276 * linked lists, the full list is duplicated. 277 */ 278static void 279DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) 280{ 281 ClassesPtr classes; 282 283 if (from->kbdfeed) 284 { 285 KbdFeedbackPtr *k, it; 286 287 if (!to->kbdfeed) 288 { 289 classes = dixLookupPrivate(&to->devPrivates, 290 UnusedClassesPrivateKey); 291 to->kbdfeed = classes->kbdfeed; 292 } 293 294 k = &to->kbdfeed; 295 for(it = from->kbdfeed; it; it = it->next) 296 { 297 if (!(*k)) 298 { 299 *k = xcalloc(1, sizeof(KbdFeedbackClassRec)); 300 if (!*k) 301 { 302 ErrorF("[Xi] Cannot alloc memory for class copy."); 303 return; 304 } 305 } 306 (*k)->BellProc = it->BellProc; 307 (*k)->CtrlProc = it->CtrlProc; 308 (*k)->ctrl = it->ctrl; 309#ifdef XKB 310 if ((*k)->xkb_sli) 311 XkbFreeSrvLedInfo((*k)->xkb_sli); 312 (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL); 313#endif 314 315 k = &(*k)->next; 316 } 317 } else if (to->kbdfeed && !from->kbdfeed) 318 { 319 ClassesPtr classes; 320 classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 321 classes->kbdfeed = to->kbdfeed; 322 to->kbdfeed = NULL; 323 } 324 325 if (from->ptrfeed) 326 { 327 PtrFeedbackPtr *p, it; 328 if (!to->ptrfeed) 329 { 330 classes = dixLookupPrivate(&to->devPrivates, 331 UnusedClassesPrivateKey); 332 to->ptrfeed = classes->ptrfeed; 333 } 334 335 p = &to->ptrfeed; 336 for (it = from->ptrfeed; it; it = it->next) 337 { 338 if (!(*p)) 339 { 340 *p = xcalloc(1, sizeof(PtrFeedbackClassRec)); 341 if (!*p) 342 { 343 ErrorF("[Xi] Cannot alloc memory for class copy."); 344 return; 345 } 346 } 347 (*p)->CtrlProc = it->CtrlProc; 348 (*p)->ctrl = it->ctrl; 349 350 p = &(*p)->next; 351 } 352 } else if (to->ptrfeed && !from->ptrfeed) 353 { 354 ClassesPtr classes; 355 classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 356 classes->ptrfeed = to->ptrfeed; 357 to->ptrfeed = NULL; 358 } 359 360 if (from->intfeed) 361 { 362 IntegerFeedbackPtr *i, it; 363 364 if (!to->intfeed) 365 { 366 classes = dixLookupPrivate(&to->devPrivates, 367 UnusedClassesPrivateKey); 368 to->intfeed = classes->intfeed; 369 } 370 371 i = &to->intfeed; 372 for (it = from->intfeed; it; it = it->next) 373 { 374 if (!(*i)) 375 { 376 *i = xcalloc(1, sizeof(IntegerFeedbackClassRec)); 377 if (!(*i)) 378 { 379 ErrorF("[Xi] Cannot alloc memory for class copy."); 380 return; 381 } 382 } 383 (*i)->CtrlProc = it->CtrlProc; 384 (*i)->ctrl = it->ctrl; 385 386 i = &(*i)->next; 387 } 388 } else if (to->intfeed && !from->intfeed) 389 { 390 ClassesPtr classes; 391 classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 392 classes->intfeed = to->intfeed; 393 to->intfeed = NULL; 394 } 395 396 if (from->stringfeed) 397 { 398 StringFeedbackPtr *s, it; 399 400 if (!to->stringfeed) 401 { 402 classes = dixLookupPrivate(&to->devPrivates, 403 UnusedClassesPrivateKey); 404 to->stringfeed = classes->stringfeed; 405 } 406 407 s = &to->stringfeed; 408 for (it = from->stringfeed; it; it = it->next) 409 { 410 if (!(*s)) 411 { 412 *s = xcalloc(1, sizeof(StringFeedbackClassRec)); 413 if (!(*s)) 414 { 415 ErrorF("[Xi] Cannot alloc memory for class copy."); 416 return; 417 } 418 } 419 (*s)->CtrlProc = it->CtrlProc; 420 (*s)->ctrl = it->ctrl; 421 422 s = &(*s)->next; 423 } 424 } else if (to->stringfeed && !from->stringfeed) 425 { 426 ClassesPtr classes; 427 classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 428 classes->stringfeed = to->stringfeed; 429 to->stringfeed = NULL; 430 } 431 432 if (from->bell) 433 { 434 BellFeedbackPtr *b, it; 435 436 if (!to->bell) 437 { 438 classes = dixLookupPrivate(&to->devPrivates, 439 UnusedClassesPrivateKey); 440 to->bell = classes->bell; 441 } 442 443 b = &to->bell; 444 for (it = from->bell; it; it = it->next) 445 { 446 if (!(*b)) 447 { 448 *b = xcalloc(1, sizeof(BellFeedbackClassRec)); 449 if (!(*b)) 450 { 451 ErrorF("[Xi] Cannot alloc memory for class copy."); 452 return; 453 } 454 } 455 (*b)->BellProc = it->BellProc; 456 (*b)->CtrlProc = it->CtrlProc; 457 (*b)->ctrl = it->ctrl; 458 459 b = &(*b)->next; 460 } 461 } else if (to->bell && !from->bell) 462 { 463 ClassesPtr classes; 464 classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 465 classes->bell = to->bell; 466 to->bell = NULL; 467 } 468 469 if (from->leds) 470 { 471 LedFeedbackPtr *l, it; 472 473 if (!to->leds) 474 { 475 classes = dixLookupPrivate(&to->devPrivates, 476 UnusedClassesPrivateKey); 477 to->leds = classes->leds; 478 } 479 480 l = &to->leds; 481 for (it = from->leds; it; it = it->next) 482 { 483 if (!(*l)) 484 { 485 *l = xcalloc(1, sizeof(LedFeedbackClassRec)); 486 if (!(*l)) 487 { 488 ErrorF("[Xi] Cannot alloc memory for class copy."); 489 return; 490 } 491 } 492 (*l)->CtrlProc = it->CtrlProc; 493 (*l)->ctrl = it->ctrl; 494#ifdef XKB 495 if ((*l)->xkb_sli) 496 XkbFreeSrvLedInfo((*l)->xkb_sli); 497 (*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l); 498#endif 499 500 l = &(*l)->next; 501 } 502 } else if (to->leds && !from->leds) 503 { 504 ClassesPtr classes; 505 classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 506 classes->leds = to->leds; 507 to->leds = NULL; 508 } 509} 510 511/** 512 * Copies the CONTENT of the classes of device from into the classes in device 513 * to. From and to are identical after finishing. 514 * 515 * If to does not have classes from currenly has, the classes are stored in 516 * to's devPrivates system. Later, we recover it again from there if needed. 517 * Saves a few memory allocations. 518 */ 519 520void 521DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) 522{ 523 ClassesPtr classes; 524 525 /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the 526 * kbdfeed to be set up properly, so let's do the feedback classes first. 527 */ 528 DeepCopyFeedbackClasses(from, to); 529 530 if (from->key) 531 { 532 KeyCode *oldModKeyMap; 533 KeySym *oldMap; 534#ifdef XKB 535 struct _XkbSrvInfo *oldXkbInfo; 536#endif 537 if (!to->key) 538 { 539 classes = dixLookupPrivate(&to->devPrivates, 540 UnusedClassesPrivateKey); 541 to->key = classes->key; 542 if (!to->key) 543 { 544 to->key = xcalloc(1, sizeof(KeyClassRec)); 545 if (!to->key) 546 FatalError("[Xi] no memory for class shift.\n"); 547 } else 548 classes->key = NULL; 549 } 550 551 oldModKeyMap = to->key->modifierKeyMap; 552 oldMap = to->key->curKeySyms.map; 553#ifdef XKB 554 oldXkbInfo = to->key->xkbInfo; 555#endif 556 557 if (!oldMap) /* newly created key struct */ 558 { 559 int bytes = (to->key->curKeySyms.maxKeyCode - 560 to->key->curKeySyms.minKeyCode + 1) * 561 to->key->curKeySyms.mapWidth; 562 oldMap = (KeySym *)xcalloc(sizeof(KeySym), bytes); 563 memcpy(oldMap, from->key->curKeySyms.map, bytes); 564 } 565 566 to->key->modifierKeyMap = oldModKeyMap; 567 to->key->curKeySyms.map = oldMap; 568#ifdef XKB 569 to->key->xkbInfo = oldXkbInfo; 570#endif 571 572 CopyKeyClass(from, to); 573 } else if (to->key && !from->key) 574 { 575 ClassesPtr classes; 576 classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 577 classes->key = to->key; 578 to->key = NULL; 579 } 580 581 if (from->valuator) 582 { 583 ValuatorClassPtr v; 584 if (!to->valuator) 585 { 586 classes = dixLookupPrivate(&to->devPrivates, 587 UnusedClassesPrivateKey); 588 to->valuator = classes->valuator; 589 if (to->valuator) 590 classes->valuator = NULL; 591 } 592 593 to->valuator = xrealloc(to->valuator, sizeof(ValuatorClassRec) + 594 from->valuator->numAxes * sizeof(AxisInfo) + 595 from->valuator->numAxes * sizeof(unsigned int)); 596 v = to->valuator; 597 if (!v) 598 FatalError("[Xi] no memory for class shift.\n"); 599 600 v->numAxes = from->valuator->numAxes; 601 v->axes = (AxisInfoPtr)&v[1]; 602 memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo)); 603 604 v->axisVal = (int*)(v->axes + from->valuator->numAxes); 605 } else if (to->valuator && !from->valuator) 606 { 607 ClassesPtr classes; 608 classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 609 classes->valuator = to->valuator; 610 to->valuator = NULL; 611 } 612 613 if (from->button) 614 { 615 if (!to->button) 616 { 617 classes = dixLookupPrivate(&to->devPrivates, 618 UnusedClassesPrivateKey); 619 to->button = classes->button; 620 if (!to->button) 621 { 622 to->button = xcalloc(1, sizeof(ButtonClassRec)); 623 if (!to->button) 624 FatalError("[Xi] no memory for class shift.\n"); 625 } else 626 classes->button = NULL; 627 } 628 629#ifdef XKB 630 if (from->button->xkb_acts) 631 { 632 if (!to->button->xkb_acts) 633 { 634 to->button->xkb_acts = xcalloc(1, sizeof(XkbAction)); 635 if (!to->button->xkb_acts) 636 FatalError("[Xi] not enough memory for xkb_acts.\n"); 637 } 638 memcpy(to->button->xkb_acts, from->button->xkb_acts, 639 sizeof(XkbAction)); 640 } else 641 xfree(to->button->xkb_acts); 642#endif 643 } else if (to->button && !from->button) 644 { 645 ClassesPtr classes; 646 classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 647 classes->button = to->button; 648 to->button = NULL; 649 } 650 651 652 /* We can't just copy over the focus class. When an app sets the focus, 653 * it'll do so on the master device. Copying the SDs focus means losing 654 * the focus. 655 * So we only copy the focus class if the device didn't have one, 656 * otherwise we leave it as it is. 657 */ 658 if (from->focus) 659 { 660 if (!to->focus) 661 { 662 WindowPtr *oldTrace; 663 664 classes = dixLookupPrivate(&to->devPrivates, 665 UnusedClassesPrivateKey); 666 to->focus = classes->focus; 667 if (!to->focus) 668 { 669 to->focus = xcalloc(1, sizeof(FocusClassRec)); 670 if (!to->focus) 671 FatalError("[Xi] no memory for class shift.\n"); 672 } else 673 classes->focus = NULL; 674 675 oldTrace = to->focus->trace; 676 memcpy(to->focus, from->focus, sizeof(FocusClassRec)); 677 to->focus->trace = xrealloc(oldTrace, 678 to->focus->traceSize * sizeof(WindowPtr)); 679 if (!to->focus->trace && to->focus->traceSize) 680 FatalError("[Xi] no memory for trace.\n"); 681 memcpy(to->focus->trace, from->focus->trace, 682 from->focus->traceSize * sizeof(WindowPtr)); 683 } 684 } else if (to->focus) 685 { 686 ClassesPtr classes; 687 classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 688 classes->focus = to->focus; 689 to->focus = NULL; 690 } 691 692 if (from->proximity) 693 { 694 if (!to->proximity) 695 { 696 classes = dixLookupPrivate(&to->devPrivates, 697 UnusedClassesPrivateKey); 698 to->proximity = classes->proximity; 699 if (!to->proximity) 700 { 701 to->proximity = xcalloc(1, sizeof(ProximityClassRec)); 702 if (!to->proximity) 703 FatalError("[Xi] no memory for class shift.\n"); 704 } else 705 classes->proximity = NULL; 706 } 707 memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec)); 708 } else if (to->proximity) 709 { 710 ClassesPtr classes; 711 classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 712 classes->proximity = to->proximity; 713 to->proximity = NULL; 714 } 715 716 if (from->absolute) 717 { 718 if (!to->absolute) 719 { 720 classes = dixLookupPrivate(&to->devPrivates, 721 UnusedClassesPrivateKey); 722 to->absolute = classes->absolute; 723 if (!to->absolute) 724 { 725 to->absolute = xcalloc(1, sizeof(AbsoluteClassRec)); 726 if (!to->absolute) 727 FatalError("[Xi] no memory for class shift.\n"); 728 } else 729 classes->absolute = NULL; 730 } 731 memcpy(to->absolute, from->absolute, sizeof(AbsoluteClassRec)); 732 } else if (to->absolute) 733 { 734 ClassesPtr classes; 735 classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 736 classes->absolute = to->absolute; 737 to->absolute = NULL; 738 } 739} 740 741 742/** 743 * Update the device state according to the data in the event. 744 * 745 * return values are 746 * DEFAULT ... process as normal 747 * DONT_PROCESS ... return immediately from caller 748 * IS_REPEAT .. event is a repeat event. 749 */ 750#define DEFAULT 0 751#define DONT_PROCESS 1 752#define IS_REPEAT 2 753int 754UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count) 755{ 756 int i; 757 int key = 0, 758 bit = 0; 759 760 KeyClassPtr k = NULL; 761 ButtonClassPtr b = NULL; 762 ValuatorClassPtr v = NULL; 763 deviceValuator *xV = (deviceValuator *) xE; 764 BYTE *kptr = NULL; 765 CARD16 modifiers = 0, 766 mask = 0; 767 768 /* currently no other generic event modifies the device */ 769 if (xE->u.u.type == GenericEvent) 770 return DEFAULT; 771 772 k = device->key; 773 v = device->valuator; 774 b = device->button; 775 776 777 if (xE->u.u.type != DeviceValuator) 778 { 779 key = xE->u.u.detail; 780 bit = 1 << (key & 7); 781 } 782 783 /* Update device axis */ 784 /* Don't update valuators for the VCP, it never sends XI events anyway */ 785 for (i = 1; !device->isMaster && i < count; i++) { 786 if ((++xV)->type == DeviceValuator) { 787 int *axisvals; 788 int first = xV->first_valuator; 789 BOOL change = FALSE; 790 791 792 if (xV->num_valuators && 793 (!v || (xV->num_valuators && 794 (first + xV->num_valuators > v->numAxes)))) 795 FatalError("Bad valuators reported for device %s\n", 796 device->name); 797 if (v && v->axisVal) { 798 /* v->axisVal is always in absolute coordinates. Only the 799 * delivery mode changes. 800 * If device is mode Absolute 801 * dev = event 802 * If device is mode Relative 803 * swap = (event - device) 804 * dev = event 805 * event = delta 806 */ 807 int delta; 808 axisvals = v->axisVal; 809 if (v->mode == Relative) /* device reports relative */ 810 change = TRUE; 811 812 switch (xV->num_valuators) { 813 case 6: 814 if (change) delta = xV->valuator5 - *(axisvals + first + 5); 815 *(axisvals + first + 5) = xV->valuator5; 816 if (change) xV->valuator5 = delta; 817 case 5: 818 if (change) delta = xV->valuator4 - *(axisvals + first + 4); 819 *(axisvals + first + 4) = xV->valuator4; 820 if (change) xV->valuator4 = delta; 821 case 4: 822 if (change) delta = xV->valuator3 - *(axisvals + first + 3); 823 *(axisvals + first + 3) = xV->valuator3; 824 if (change) xV->valuator3 = delta; 825 case 3: 826 if (change) delta = xV->valuator2 - *(axisvals + first + 2); 827 *(axisvals + first + 2) = xV->valuator2; 828 if (change) xV->valuator2 = delta; 829 case 2: 830 if (change) delta = xV->valuator1 - *(axisvals + first + 1); 831 *(axisvals + first + 1) = xV->valuator1; 832 if (change) xV->valuator1 = delta; 833 case 1: 834 if (change) delta = xV->valuator0 - *(axisvals + first); 835 *(axisvals + first) = xV->valuator0; 836 if (change) xV->valuator0 = delta; 837 case 0: 838 default: 839 break; 840 } 841 } 842 } 843 } 844 845 if (xE->u.u.type == DeviceKeyPress) { 846 if (!k) 847 return DONT_PROCESS; 848 849 modifiers = k->modifierMap[key]; 850 kptr = &k->down[key >> 3]; 851 if (*kptr & bit) { /* allow ddx to generate multiple downs */ 852 return IS_REPEAT; 853 } 854 if (device->valuator) 855 device->valuator->motionHintWindow = NullWindow; 856 *kptr |= bit; 857 k->prev_state = k->state; 858 for (i = 0, mask = 1; modifiers; i++, mask <<= 1) { 859 if (mask & modifiers) { 860 /* This key affects modifier "i" */ 861 k->modifierKeyCount[i]++; 862 k->state |= mask; 863 modifiers &= ~mask; 864 } 865 } 866 } else if (xE->u.u.type == DeviceKeyRelease) { 867 if (!k) 868 return DONT_PROCESS; 869 870 kptr = &k->down[key >> 3]; 871 if (!(*kptr & bit)) /* guard against duplicates */ 872 return DONT_PROCESS; 873 modifiers = k->modifierMap[key]; 874 if (device->valuator) 875 device->valuator->motionHintWindow = NullWindow; 876 *kptr &= ~bit; 877 k->prev_state = k->state; 878 for (i = 0, mask = 1; modifiers; i++, mask <<= 1) { 879 if (mask & modifiers) { 880 /* This key affects modifier "i" */ 881 if (--k->modifierKeyCount[i] <= 0) { 882 k->modifierKeyCount[i] = 0; 883 k->state &= ~mask; 884 } 885 modifiers &= ~mask; 886 } 887 } 888 } else if (xE->u.u.type == DeviceButtonPress) { 889 if (!b) 890 return DONT_PROCESS; 891 892 kptr = &b->down[key >> 3]; 893 if ((*kptr & bit) != 0) 894 return DONT_PROCESS; 895 *kptr |= bit; 896 if (device->valuator) 897 device->valuator->motionHintWindow = NullWindow; 898 if (!b->map[key]) 899 return DONT_PROCESS; 900 b->buttonsDown++; 901 b->motionMask = DeviceButtonMotionMask; 902 if (b->map[key] <= 5) 903 b->state |= (Button1Mask >> 1) << b->map[key]; 904 SetMaskForEvent(device->id, Motion_Filter(b), DeviceMotionNotify); 905 } else if (xE->u.u.type == DeviceButtonRelease) { 906 if (!b) 907 return DONT_PROCESS; 908 909 kptr = &b->down[key>>3]; 910 if (!(*kptr & bit)) 911 return DONT_PROCESS; 912 if (device->isMaster) { 913 DeviceIntPtr sd; 914 915 /* 916 * Leave the button down if any slave has the 917 * button still down. Note that this depends on the 918 * event being delivered through the slave first 919 */ 920 for (sd = inputInfo.devices; sd; sd = sd->next) { 921 if (sd->isMaster || sd->u.master != device) 922 continue; 923 if ((sd->button->down[key>>3] & bit) != 0) 924 return DONT_PROCESS; 925 } 926 } 927 *kptr &= ~bit; 928 if (device->valuator) 929 device->valuator->motionHintWindow = NullWindow; 930 if (!b->map[key]) 931 return DONT_PROCESS; 932 if (b->buttonsDown >= 1 && !--b->buttonsDown) 933 b->motionMask = 0; 934 if (b->map[key] <= 5) 935 b->state &= ~((Button1Mask >> 1) << b->map[key]); 936 SetMaskForEvent(device->id, Motion_Filter(b), DeviceMotionNotify); 937 } else if (xE->u.u.type == ProximityIn) 938 device->valuator->mode &= ~OutOfProximity; 939 else if (xE->u.u.type == ProximityOut) 940 device->valuator->mode |= OutOfProximity; 941 942 return DEFAULT; 943} 944 945/** 946 * Main device event processing function. 947 * Called from when processing the events from the event queue. 948 * 949 */ 950void 951ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count) 952{ 953 int i; 954 CARD16 modifiers; 955 GrabPtr grab = device->deviceGrab.grab; 956 Bool deactivateDeviceGrab = FALSE; 957 int key = 0, rootX, rootY; 958 ButtonClassPtr b; 959 KeyClassPtr k; 960 ValuatorClassPtr v; 961 deviceValuator *xV = (deviceValuator *) xE; 962 int ret = 0; 963 int state; 964 DeviceIntPtr mouse = NULL, kbd = NULL; 965 966 if (IsPointerDevice(device)) 967 { 968 kbd = GetPairedDevice(device); 969 mouse = device; 970 if (!kbd->key) /* can happen with floating SDs */ 971 kbd = NULL; 972 } else 973 { 974 mouse = GetPairedDevice(device); 975 kbd = device; 976 if (!mouse->valuator || !mouse->button) /* may be float. SDs */ 977 mouse = NULL; 978 } 979 980 /* State needs to be assembled BEFORE the device is updated. */ 981 state = (kbd) ? kbd->key->state : 0; 982 state |= (mouse) ? (mouse->button->state) : 0; 983 984 ret = UpdateDeviceState(device, xE, count); 985 if (ret == DONT_PROCESS) 986 return; 987 988 v = device->valuator; 989 b = device->button; 990 k = device->key; 991 992 if (device->isMaster) 993 CheckMotion(xE, device); 994 995 if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) { 996 GetSpritePosition(device, &rootX, &rootY); 997 xE->u.keyButtonPointer.rootX = rootX; 998 xE->u.keyButtonPointer.rootY = rootY; 999 NoticeEventTime(xE); 1000 1001 xE->u.keyButtonPointer.state = state; 1002 1003 key = xE->u.u.detail; 1004 } 1005 if (DeviceEventCallback) { 1006 DeviceEventInfoRec eventinfo; 1007 1008 eventinfo.events = (xEventPtr) xE; 1009 eventinfo.count = count; 1010 CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); 1011 } 1012 1013 /* Valuator event handling */ 1014 /* Don't care about valuators for the VCP, it never sends XI events */ 1015 1016 for (i = 1; !device->isMaster && i < count; i++) { 1017 if ((++xV)->type == DeviceValuator) { 1018 int first = xV->first_valuator; 1019 if (xV->num_valuators 1020 && (!v 1021 || (xV->num_valuators 1022 && (first + xV->num_valuators > v->numAxes)))) 1023 FatalError("Bad valuators reported for device %s\n", 1024 device->name); 1025 xV->device_state = 0; 1026 if (k) 1027 xV->device_state |= k->state; 1028 if (b) 1029 xV->device_state |= b->state; 1030 } 1031 } 1032 1033 if (xE->u.u.type == DeviceKeyPress) { 1034 if (ret == IS_REPEAT) { /* allow ddx to generate multiple downs */ 1035 modifiers = k->modifierMap[key]; 1036 if (!modifiers) { 1037 xE->u.u.type = DeviceKeyRelease; 1038 ProcessOtherEvent(xE, device, count); 1039 xE->u.u.type = DeviceKeyPress; 1040 /* release can have side effects, don't fall through */ 1041 ProcessOtherEvent(xE, device, count); 1042 } 1043 return; 1044 } 1045 if (!grab && CheckDeviceGrabs(device, xE, 0, count)) { 1046 device->deviceGrab.activatingKey = key; 1047 return; 1048 } 1049 } else if (xE->u.u.type == DeviceKeyRelease) { 1050 if (device->deviceGrab.fromPassiveGrab && 1051 (key == device->deviceGrab.activatingKey)) 1052 deactivateDeviceGrab = TRUE; 1053 } else if (xE->u.u.type == DeviceButtonPress) { 1054 xE->u.u.detail = b->map[key]; 1055 if (xE->u.u.detail == 0) { 1056 xE->u.u.detail = key; 1057 return; 1058 } 1059 if (!grab && CheckDeviceGrabs(device, xE, 0, count)) 1060 { 1061 /* if a passive grab was activated, the event has been sent 1062 * already */ 1063 return; 1064 } 1065 1066 } else if (xE->u.u.type == DeviceButtonRelease) { 1067 xE->u.u.detail = b->map[key]; 1068 if (xE->u.u.detail == 0) { 1069 xE->u.u.detail = key; 1070 return; 1071 } 1072 if (!b->buttonsDown && device->deviceGrab.fromPassiveGrab) 1073 deactivateDeviceGrab = TRUE; 1074 } 1075 1076 if (grab) 1077 DeliverGrabbedEvent(xE, device, deactivateDeviceGrab, count); 1078 else if (device->focus && !IsPointerEvent(xE)) 1079 DeliverFocusedEvent(device, xE, GetSpriteWindow(device), count); 1080 else 1081 DeliverDeviceEvents(GetSpriteWindow(device), xE, NullGrab, NullWindow, 1082 device, count); 1083 1084 if (deactivateDeviceGrab == TRUE) 1085 (*device->deviceGrab.DeactivateGrab) (device); 1086 xE->u.u.detail = key; 1087} 1088 1089_X_EXPORT int 1090InitProximityClassDeviceStruct(DeviceIntPtr dev) 1091{ 1092 ProximityClassPtr proxc; 1093 1094 proxc = (ProximityClassPtr) xalloc(sizeof(ProximityClassRec)); 1095 if (!proxc) 1096 return FALSE; 1097 dev->proximity = proxc; 1098 return TRUE; 1099} 1100 1101/** 1102 * Initialise the device's valuators. The memory must already be allocated, 1103 * this function merely inits the matching axis (specified through axnum) to 1104 * sane values. 1105 * 1106 * It is a condition that (minval < maxval). 1107 * 1108 * @see InitValuatorClassDeviceStruct 1109 */ 1110_X_EXPORT void 1111InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, int minval, int maxval, 1112 int resolution, int min_res, int max_res) 1113{ 1114 AxisInfoPtr ax; 1115 1116 if (!dev || !dev->valuator || minval > maxval) 1117 return; 1118 1119 ax = dev->valuator->axes + axnum; 1120 1121 ax->min_value = minval; 1122 ax->max_value = maxval; 1123 ax->resolution = resolution; 1124 ax->min_resolution = min_res; 1125 ax->max_resolution = max_res; 1126} 1127 1128static void 1129FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, 1130 ButtonClassPtr b, ValuatorClassPtr v, int first) 1131{ 1132 ev->type = DeviceStateNotify; 1133 ev->deviceid = dev->id; 1134 ev->time = currentTime.milliseconds; 1135 ev->classes_reported = 0; 1136 ev->num_keys = 0; 1137 ev->num_buttons = 0; 1138 ev->num_valuators = 0; 1139 1140 if (b) { 1141 ev->classes_reported |= (1 << ButtonClass); 1142 ev->num_buttons = b->numButtons; 1143 memcpy((char*)ev->buttons, (char*)b->down, 4); 1144 } else if (k) { 1145 ev->classes_reported |= (1 << KeyClass); 1146 ev->num_keys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode; 1147 memmove((char *)&ev->keys[0], (char *)k->down, 4); 1148 } 1149 if (v) { 1150 int nval = v->numAxes - first; 1151 1152 ev->classes_reported |= (1 << ValuatorClass); 1153 ev->classes_reported |= (dev->valuator->mode << ModeBitsShift); 1154 ev->num_valuators = nval < 3 ? nval : 3; 1155 switch (ev->num_valuators) { 1156 case 3: 1157 ev->valuator2 = v->axisVal[first + 2]; 1158 case 2: 1159 ev->valuator1 = v->axisVal[first + 1]; 1160 case 1: 1161 ev->valuator0 = v->axisVal[first]; 1162 break; 1163 } 1164 } 1165} 1166 1167static void 1168FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, 1169 int first) 1170{ 1171 int nval = v->numAxes - first; 1172 1173 ev->type = DeviceValuator; 1174 ev->deviceid = dev->id; 1175 ev->num_valuators = nval < 3 ? nval : 3; 1176 ev->first_valuator = first; 1177 switch (ev->num_valuators) { 1178 case 3: 1179 ev->valuator2 = v->axisVal[first + 2]; 1180 case 2: 1181 ev->valuator1 = v->axisVal[first + 1]; 1182 case 1: 1183 ev->valuator0 = v->axisVal[first]; 1184 break; 1185 } 1186 first += ev->num_valuators; 1187} 1188 1189void 1190DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, 1191 WindowPtr pWin) 1192{ 1193 deviceFocus event; 1194 1195 if (type == FocusIn) 1196 type = DeviceFocusIn; 1197 else 1198 type = DeviceFocusOut; 1199 1200 event.deviceid = dev->id; 1201 event.mode = mode; 1202 event.type = type; 1203 event.detail = detail; 1204 event.window = pWin->drawable.id; 1205 event.time = currentTime.milliseconds; 1206 1207 (void)DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, 1208 DeviceFocusChangeMask, NullGrab, dev->id); 1209 1210 if ((type == DeviceFocusIn) && 1211 (wOtherInputMasks(pWin)) && 1212 (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) 1213 { 1214 int evcount = 1; 1215 deviceStateNotify *ev, *sev; 1216 deviceKeyStateNotify *kev; 1217 deviceButtonStateNotify *bev; 1218 1219 KeyClassPtr k; 1220 ButtonClassPtr b; 1221 ValuatorClassPtr v; 1222 int nval = 0, nkeys = 0, nbuttons = 0, first = 0; 1223 1224 if ((b = dev->button) != NULL) { 1225 nbuttons = b->numButtons; 1226 if (nbuttons > 32) 1227 evcount++; 1228 } 1229 if ((k = dev->key) != NULL) { 1230 nkeys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode; 1231 if (nkeys > 32) 1232 evcount++; 1233 if (nbuttons > 0) { 1234 evcount++; 1235 } 1236 } 1237 if ((v = dev->valuator) != NULL) { 1238 nval = v->numAxes; 1239 1240 if (nval > 3) 1241 evcount++; 1242 if (nval > 6) { 1243 if (!(k && b)) 1244 evcount++; 1245 if (nval > 9) 1246 evcount += ((nval - 7) / 3); 1247 } 1248 } 1249 1250 sev = ev = (deviceStateNotify *) xalloc(evcount * sizeof(xEvent)); 1251 FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); 1252 1253 if (b != NULL) { 1254 FixDeviceStateNotify(dev, ev++, NULL, b, v, first); 1255 first += 3; 1256 nval -= 3; 1257 if (nbuttons > 32) { 1258 (ev - 1)->deviceid |= MORE_EVENTS; 1259 bev = (deviceButtonStateNotify *) ev++; 1260 bev->type = DeviceButtonStateNotify; 1261 bev->deviceid = dev->id; 1262 memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); 1263 } 1264 if (nval > 0) { 1265 (ev - 1)->deviceid |= MORE_EVENTS; 1266 FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 1267 first += 3; 1268 nval -= 3; 1269 } 1270 } 1271 1272 if (k != NULL) { 1273 FixDeviceStateNotify(dev, ev++, k, NULL, v, first); 1274 first += 3; 1275 nval -= 3; 1276 if (nkeys > 32) { 1277 (ev - 1)->deviceid |= MORE_EVENTS; 1278 kev = (deviceKeyStateNotify *) ev++; 1279 kev->type = DeviceKeyStateNotify; 1280 kev->deviceid = dev->id; 1281 memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); 1282 } 1283 if (nval > 0) { 1284 (ev - 1)->deviceid |= MORE_EVENTS; 1285 FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 1286 first += 3; 1287 nval -= 3; 1288 } 1289 } 1290 1291 while (nval > 0) { 1292 FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); 1293 first += 3; 1294 nval -= 3; 1295 if (nval > 0) { 1296 (ev - 1)->deviceid |= MORE_EVENTS; 1297 FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 1298 first += 3; 1299 nval -= 3; 1300 } 1301 } 1302 1303 (void)DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount, 1304 DeviceStateNotifyMask, NullGrab, dev->id); 1305 xfree(sev); 1306 } 1307} 1308 1309int 1310GrabButton(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode, 1311 BYTE other_devices_mode, CARD16 modifiers, 1312 DeviceIntPtr modifier_device, CARD8 button, Window grabWindow, 1313 BOOL ownerEvents, Cursor rcursor, Window rconfineTo, Mask eventMask) 1314{ 1315 WindowPtr pWin, confineTo; 1316 CursorPtr cursor; 1317 GrabPtr grab; 1318 Mask access_mode = DixGrabAccess; 1319 int rc; 1320 1321 if ((this_device_mode != GrabModeSync) && 1322 (this_device_mode != GrabModeAsync)) { 1323 client->errorValue = this_device_mode; 1324 return BadValue; 1325 } 1326 if ((other_devices_mode != GrabModeSync) && 1327 (other_devices_mode != GrabModeAsync)) { 1328 client->errorValue = other_devices_mode; 1329 return BadValue; 1330 } 1331 if ((modifiers != AnyModifier) && (modifiers & ~AllModifiersMask)) { 1332 client->errorValue = modifiers; 1333 return BadValue; 1334 } 1335 if ((ownerEvents != xFalse) && (ownerEvents != xTrue)) { 1336 client->errorValue = ownerEvents; 1337 return BadValue; 1338 } 1339 rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess); 1340 if (rc != Success) 1341 return rc; 1342 if (rconfineTo == None) 1343 confineTo = NullWindow; 1344 else { 1345 rc = dixLookupWindow(&confineTo, rconfineTo, client, DixSetAttrAccess); 1346 if (rc != Success) 1347 return rc; 1348 } 1349 if (rcursor == None) 1350 cursor = NullCursor; 1351 else { 1352 rc = dixLookupResource((pointer *)&cursor, rcursor, RT_CURSOR, 1353 client, DixUseAccess); 1354 if (rc != Success) 1355 { 1356 client->errorValue = rcursor; 1357 return (rc == BadValue) ? BadCursor : rc; 1358 } 1359 access_mode |= DixForceAccess; 1360 } 1361 if (this_device_mode == GrabModeSync || other_devices_mode == GrabModeSync) 1362 access_mode |= DixFreezeAccess; 1363 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 1364 if (rc != Success) 1365 return rc; 1366 1367 grab = CreateGrab(client->index, dev, pWin, eventMask, 1368 (Bool) ownerEvents, (Bool) this_device_mode, 1369 (Bool) other_devices_mode, modifier_device, modifiers, 1370 DeviceButtonPress, button, confineTo, cursor); 1371 if (!grab) 1372 return BadAlloc; 1373 return AddPassiveGrabToList(client, grab); 1374} 1375 1376int 1377GrabKey(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode, 1378 BYTE other_devices_mode, CARD16 modifiers, 1379 DeviceIntPtr modifier_device, CARD8 key, Window grabWindow, 1380 BOOL ownerEvents, Mask mask) 1381{ 1382 WindowPtr pWin; 1383 GrabPtr grab; 1384 KeyClassPtr k = dev->key; 1385 Mask access_mode = DixGrabAccess; 1386 int rc; 1387 1388 if (k == NULL) 1389 return BadMatch; 1390 if ((other_devices_mode != GrabModeSync) && 1391 (other_devices_mode != GrabModeAsync)) { 1392 client->errorValue = other_devices_mode; 1393 return BadValue; 1394 } 1395 if ((this_device_mode != GrabModeSync) && 1396 (this_device_mode != GrabModeAsync)) { 1397 client->errorValue = this_device_mode; 1398 return BadValue; 1399 } 1400 if (((key > k->curKeySyms.maxKeyCode) || (key < k->curKeySyms.minKeyCode)) 1401 && (key != AnyKey)) { 1402 client->errorValue = key; 1403 return BadValue; 1404 } 1405 if ((modifiers != AnyModifier) && (modifiers & ~AllModifiersMask)) { 1406 client->errorValue = modifiers; 1407 return BadValue; 1408 } 1409 if ((ownerEvents != xTrue) && (ownerEvents != xFalse)) { 1410 client->errorValue = ownerEvents; 1411 return BadValue; 1412 } 1413 rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess); 1414 if (rc != Success) 1415 return rc; 1416 if (this_device_mode == GrabModeSync || other_devices_mode == GrabModeSync) 1417 access_mode |= DixFreezeAccess; 1418 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 1419 if (rc != Success) 1420 return rc; 1421 1422 grab = CreateGrab(client->index, dev, pWin, 1423 mask, ownerEvents, this_device_mode, other_devices_mode, 1424 modifier_device, modifiers, DeviceKeyPress, key, 1425 NullWindow, NullCursor); 1426 if (!grab) 1427 return BadAlloc; 1428 return AddPassiveGrabToList(client, grab); 1429} 1430 1431int 1432SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client, 1433 Mask mask, Mask exclusivemasks, Mask validmasks) 1434{ 1435 int mskidx = dev->id; 1436 int i, ret; 1437 Mask check; 1438 InputClientsPtr others; 1439 1440 if (mask & ~validmasks) { 1441 client->errorValue = mask; 1442 return BadValue; 1443 } 1444 check = (mask & exclusivemasks); 1445 if (wOtherInputMasks(pWin)) { 1446 if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different 1447 * clients to select on any of the 1448 * events for maskcheck. However, 1449 * it is OK, for some client to 1450 * continue selecting on one of those 1451 * events. */ 1452 for (others = wOtherInputMasks(pWin)->inputClients; others; 1453 others = others->next) { 1454 if (!SameClient(others, client) && (check & 1455 others->mask[mskidx])) 1456 return BadAccess; 1457 } 1458 } 1459 for (others = wOtherInputMasks(pWin)->inputClients; others; 1460 others = others->next) { 1461 if (SameClient(others, client)) { 1462 check = others->mask[mskidx]; 1463 others->mask[mskidx] = mask; 1464 if (mask == 0) { 1465 for (i = 0; i < EMASKSIZE; i++) 1466 if (i != mskidx && others->mask[i] != 0) 1467 break; 1468 if (i == EMASKSIZE) { 1469 RecalculateDeviceDeliverableEvents(pWin); 1470 if (ShouldFreeInputMasks(pWin, FALSE)) 1471 FreeResource(others->resource, RT_NONE); 1472 return Success; 1473 } 1474 } 1475 goto maskSet; 1476 } 1477 } 1478 } 1479 check = 0; 1480 if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success) 1481 return ret; 1482 maskSet: 1483 if (dev->valuator) 1484 if ((dev->valuator->motionHintWindow == pWin) && 1485 (mask & DevicePointerMotionHintMask) && 1486 !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab) 1487 dev->valuator->motionHintWindow = NullWindow; 1488 RecalculateDeviceDeliverableEvents(pWin); 1489 return Success; 1490} 1491 1492int 1493AddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx) 1494{ 1495 InputClientsPtr others; 1496 1497 if (!pWin->optional && !MakeWindowOptional(pWin)) 1498 return BadAlloc; 1499 others = xcalloc(1, sizeof(InputClients)); 1500 if (!others) 1501 return BadAlloc; 1502 if (!pWin->optional->inputMasks && !MakeInputMasks(pWin)) 1503 return BadAlloc; 1504 others->mask[mskidx] = mask; 1505 others->resource = FakeClientID(client->index); 1506 others->next = pWin->optional->inputMasks->inputClients; 1507 pWin->optional->inputMasks->inputClients = others; 1508 if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin)) 1509 return BadAlloc; 1510 return Success; 1511} 1512 1513static Bool 1514MakeInputMasks(WindowPtr pWin) 1515{ 1516 struct _OtherInputMasks *imasks; 1517 1518 imasks = xcalloc(1, sizeof(struct _OtherInputMasks)); 1519 if (!imasks) 1520 return FALSE; 1521 pWin->optional->inputMasks = imasks; 1522 return TRUE; 1523} 1524 1525void 1526RecalculateDeviceDeliverableEvents(WindowPtr pWin) 1527{ 1528 InputClientsPtr others; 1529 struct _OtherInputMasks *inputMasks; /* default: NULL */ 1530 WindowPtr pChild, tmp; 1531 int i; 1532 1533 pChild = pWin; 1534 while (1) { 1535 if ((inputMasks = wOtherInputMasks(pChild)) != 0) { 1536 for (others = inputMasks->inputClients; others; 1537 others = others->next) { 1538 for (i = 0; i < EMASKSIZE; i++) 1539 inputMasks->inputEvents[i] |= others->mask[i]; 1540 } 1541 for (i = 0; i < EMASKSIZE; i++) 1542 inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i]; 1543 for (tmp = pChild->parent; tmp; tmp = tmp->parent) 1544 if (wOtherInputMasks(tmp)) 1545 for (i = 0; i < EMASKSIZE; i++) 1546 inputMasks->deliverableEvents[i] |= 1547 (wOtherInputMasks(tmp)->deliverableEvents[i] 1548 & ~inputMasks-> 1549 dontPropagateMask[i] & PropagateMask[i]); 1550 } 1551 if (pChild->firstChild) { 1552 pChild = pChild->firstChild; 1553 continue; 1554 } 1555 while (!pChild->nextSib && (pChild != pWin)) 1556 pChild = pChild->parent; 1557 if (pChild == pWin) 1558 break; 1559 pChild = pChild->nextSib; 1560 } 1561} 1562 1563int 1564InputClientGone(WindowPtr pWin, XID id) 1565{ 1566 InputClientsPtr other, prev; 1567 1568 if (!wOtherInputMasks(pWin)) 1569 return (Success); 1570 prev = 0; 1571 for (other = wOtherInputMasks(pWin)->inputClients; other; 1572 other = other->next) { 1573 if (other->resource == id) { 1574 if (prev) { 1575 prev->next = other->next; 1576 xfree(other); 1577 } else if (!(other->next)) { 1578 if (ShouldFreeInputMasks(pWin, TRUE)) { 1579 wOtherInputMasks(pWin)->inputClients = other->next; 1580 xfree(wOtherInputMasks(pWin)); 1581 pWin->optional->inputMasks = (OtherInputMasks *) NULL; 1582 CheckWindowOptionalNeed(pWin); 1583 xfree(other); 1584 } else { 1585 other->resource = FakeClientID(0); 1586 if (!AddResource(other->resource, RT_INPUTCLIENT, 1587 (pointer) pWin)) 1588 return BadAlloc; 1589 } 1590 } else { 1591 wOtherInputMasks(pWin)->inputClients = other->next; 1592 xfree(other); 1593 } 1594 RecalculateDeviceDeliverableEvents(pWin); 1595 return (Success); 1596 } 1597 prev = other; 1598 } 1599 FatalError("client not on device event list"); 1600} 1601 1602int 1603SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, 1604 xEvent * ev, Mask mask, int count) 1605{ 1606 WindowPtr pWin; 1607 WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ 1608 WindowPtr spriteWin = GetSpriteWindow(d); 1609 1610 if (dest == PointerWindow) 1611 pWin = spriteWin; 1612 else if (dest == InputFocus) { 1613 WindowPtr inputFocus; 1614 1615 if (!d->focus) 1616 inputFocus = spriteWin; 1617 else 1618 inputFocus = d->focus->win; 1619 1620 if (inputFocus == FollowKeyboardWin) 1621 inputFocus = inputInfo.keyboard->focus->win; 1622 1623 if (inputFocus == NoneWin) 1624 return Success; 1625 1626 /* If the input focus is PointerRootWin, send the event to where 1627 * the pointer is if possible, then perhaps propogate up to root. */ 1628 if (inputFocus == PointerRootWin) 1629 inputFocus = GetCurrentRootWindow(d); 1630 1631 if (IsParent(inputFocus, spriteWin)) { 1632 effectiveFocus = inputFocus; 1633 pWin = spriteWin; 1634 } else 1635 effectiveFocus = pWin = inputFocus; 1636 } else 1637 dixLookupWindow(&pWin, dest, client, DixSendAccess); 1638 if (!pWin) 1639 return BadWindow; 1640 if ((propagate != xFalse) && (propagate != xTrue)) { 1641 client->errorValue = propagate; 1642 return BadValue; 1643 } 1644 ev->u.u.type |= 0x80; 1645 if (propagate) { 1646 for (; pWin; pWin = pWin->parent) { 1647 if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab, d->id)) 1648 return Success; 1649 if (pWin == effectiveFocus) 1650 return Success; 1651 if (wOtherInputMasks(pWin)) 1652 mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id]; 1653 if (!mask) 1654 break; 1655 } 1656 } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count)) 1657 (void)(DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab, d->id)); 1658 return Success; 1659} 1660 1661int 1662SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map) 1663{ 1664 int i; 1665 ButtonClassPtr b = dev->button; 1666 1667 if (b == NULL) 1668 return BadMatch; 1669 1670 if (nElts != b->numButtons) { 1671 client->errorValue = nElts; 1672 return BadValue; 1673 } 1674 if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue)) 1675 return BadValue; 1676 for (i = 0; i < nElts; i++) 1677 if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1)) 1678 return MappingBusy; 1679 for (i = 0; i < nElts; i++) 1680 b->map[i + 1] = map[i]; 1681 return Success; 1682} 1683 1684int 1685SetModifierMapping(ClientPtr client, DeviceIntPtr dev, int len, int rlen, 1686 int numKeyPerModifier, KeyCode * inputMap, KeyClassPtr * k) 1687{ 1688 KeyCode *map = NULL; 1689 int inputMapLen; 1690 int i; 1691 1692 *k = dev->key; 1693 if (*k == NULL) 1694 return BadMatch; 1695 if (len != ((numKeyPerModifier << 1) + rlen)) 1696 return BadLength; 1697 1698 inputMapLen = 8 * numKeyPerModifier; 1699 1700 /* 1701 * Now enforce the restriction that "all of the non-zero keycodes must be 1702 * in the range specified by min-keycode and max-keycode in the 1703 * connection setup (else a Value error)" 1704 */ 1705 i = inputMapLen; 1706 while (i--) { 1707 if (inputMap[i] 1708 && (inputMap[i] < (*k)->curKeySyms.minKeyCode 1709 || inputMap[i] > (*k)->curKeySyms.maxKeyCode)) { 1710 client->errorValue = inputMap[i]; 1711 return -1; /* BadValue collides with MappingFailed */ 1712 } 1713 } 1714 1715 /* 1716 * Now enforce the restriction that none of the old or new 1717 * modifier keys may be down while we change the mapping, and 1718 * that the DDX layer likes the choice. 1719 */ 1720 if (!AllModifierKeysAreUp(dev, (*k)->modifierKeyMap, 1721 (int)(*k)->maxKeysPerModifier, inputMap, 1722 (int)numKeyPerModifier) 1723 || !AllModifierKeysAreUp(dev, inputMap, (int)numKeyPerModifier, 1724 (*k)->modifierKeyMap, 1725 (int)(*k)->maxKeysPerModifier)) { 1726 return MappingBusy; 1727 } else { 1728 for (i = 0; i < inputMapLen; i++) { 1729 if (inputMap[i] && !LegalModifier(inputMap[i], dev)) { 1730 return MappingFailed; 1731 } 1732 } 1733 } 1734 1735 /* 1736 * Now build the keyboard's modifier bitmap from the 1737 * list of keycodes. 1738 */ 1739 if (inputMapLen) { 1740 map = (KeyCode *) xalloc(inputMapLen); 1741 if (!map) 1742 return BadAlloc; 1743 } 1744 if ((*k)->modifierKeyMap) 1745 xfree((*k)->modifierKeyMap); 1746 if (inputMapLen) { 1747 (*k)->modifierKeyMap = map; 1748 memmove((char *)(*k)->modifierKeyMap, (char *)inputMap, inputMapLen); 1749 } else 1750 (*k)->modifierKeyMap = NULL; 1751 1752 (*k)->maxKeysPerModifier = numKeyPerModifier; 1753 for (i = 0; i < MAP_LENGTH; i++) 1754 (*k)->modifierMap[i] = 0; 1755 for (i = 0; i < inputMapLen; i++) 1756 if (inputMap[i]) { 1757 (*k)->modifierMap[inputMap[i]] 1758 |= (1 << (i / (*k)->maxKeysPerModifier)); 1759 } 1760 1761 return (MappingSuccess); 1762} 1763 1764void 1765SendDeviceMappingNotify(ClientPtr client, CARD8 request, 1766 KeyCode firstKeyCode, CARD8 count, DeviceIntPtr dev) 1767{ 1768 xEvent event; 1769 deviceMappingNotify *ev = (deviceMappingNotify *) & event; 1770 1771 ev->type = DeviceMappingNotify; 1772 ev->request = request; 1773 ev->deviceid = dev->id; 1774 ev->time = currentTime.milliseconds; 1775 if (request == MappingKeyboard) { 1776 ev->firstKeyCode = firstKeyCode; 1777 ev->count = count; 1778 } 1779 1780#ifdef XKB 1781 if (!noXkbExtension && (request == MappingKeyboard || 1782 request == MappingModifier)) 1783 XkbApplyMappingChange(dev, request, firstKeyCode, count, client); 1784#endif 1785 1786 SendEventToAllWindows(dev, DeviceMappingNotifyMask, (xEvent *) ev, 1); 1787} 1788 1789int 1790ChangeKeyMapping(ClientPtr client, 1791 DeviceIntPtr dev, 1792 unsigned len, 1793 int type, 1794 KeyCode firstKeyCode, 1795 CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map) 1796{ 1797 KeySymsRec keysyms; 1798 KeyClassPtr k = dev->key; 1799 1800 if (k == NULL) 1801 return (BadMatch); 1802 1803 if (len != (keyCodes * keySymsPerKeyCode)) 1804 return BadLength; 1805 1806 if ((firstKeyCode < k->curKeySyms.minKeyCode) || 1807 (firstKeyCode + keyCodes - 1 > k->curKeySyms.maxKeyCode)) { 1808 client->errorValue = firstKeyCode; 1809 return BadValue; 1810 } 1811 if (keySymsPerKeyCode == 0) { 1812 client->errorValue = 0; 1813 return BadValue; 1814 } 1815 keysyms.minKeyCode = firstKeyCode; 1816 keysyms.maxKeyCode = firstKeyCode + keyCodes - 1; 1817 keysyms.mapWidth = keySymsPerKeyCode; 1818 keysyms.map = map; 1819 if (!SetKeySymsMap(&k->curKeySyms, &keysyms)) 1820 return BadAlloc; 1821 SendDeviceMappingNotify(client, MappingKeyboard, firstKeyCode, keyCodes, dev); 1822 return client->noClientException; 1823} 1824 1825static void 1826DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) 1827{ 1828 WindowPtr parent; 1829 1830 /* Deactivate any grabs performed on this window, before making 1831 * any input focus changes. 1832 * Deactivating a device grab should cause focus events. */ 1833 1834 if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin)) 1835 (*dev->deviceGrab.DeactivateGrab) (dev); 1836 1837 /* If the focus window is a root window (ie. has no parent) 1838 * then don't delete the focus from it. */ 1839 1840 if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) { 1841 int focusEventMode = NotifyNormal; 1842 1843 /* If a grab is in progress, then alter the mode of focus events. */ 1844 1845 if (dev->deviceGrab.grab) 1846 focusEventMode = NotifyWhileGrabbed; 1847 1848 switch (dev->focus->revert) { 1849 case RevertToNone: 1850 DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 1851 dev->focus->win = NoneWin; 1852 dev->focus->traceGood = 0; 1853 break; 1854 case RevertToParent: 1855 parent = pWin; 1856 do { 1857 parent = parent->parent; 1858 dev->focus->traceGood--; 1859 } 1860 while (!parent->realized); 1861 DoFocusEvents(dev, pWin, parent, focusEventMode); 1862 dev->focus->win = parent; 1863 dev->focus->revert = RevertToNone; 1864 break; 1865 case RevertToPointerRoot: 1866 DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); 1867 dev->focus->win = PointerRootWin; 1868 dev->focus->traceGood = 0; 1869 break; 1870 case RevertToFollowKeyboard: 1871 if (inputInfo.keyboard->focus->win) { 1872 DoFocusEvents(dev, pWin, inputInfo.keyboard->focus->win, 1873 focusEventMode); 1874 dev->focus->win = FollowKeyboardWin; 1875 dev->focus->traceGood = 0; 1876 } else { 1877 DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 1878 dev->focus->win = NoneWin; 1879 dev->focus->traceGood = 0; 1880 } 1881 break; 1882 } 1883 } 1884 1885 if (dev->valuator) 1886 if (dev->valuator->motionHintWindow == pWin) 1887 dev->valuator->motionHintWindow = NullWindow; 1888} 1889 1890void 1891DeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources) 1892{ 1893 int i; 1894 DeviceIntPtr dev; 1895 InputClientsPtr ic; 1896 struct _OtherInputMasks *inputMasks; 1897 1898 for (dev = inputInfo.devices; dev; dev = dev->next) { 1899 if (dev == inputInfo.pointer || dev == inputInfo.keyboard) 1900 continue; 1901 DeleteDeviceFromAnyExtEvents(pWin, dev); 1902 } 1903 1904 for (dev = inputInfo.off_devices; dev; dev = dev->next) 1905 DeleteDeviceFromAnyExtEvents(pWin, dev); 1906 1907 if (freeResources) 1908 while ((inputMasks = wOtherInputMasks(pWin)) != 0) { 1909 ic = inputMasks->inputClients; 1910 for (i = 0; i < EMASKSIZE; i++) 1911 inputMasks->dontPropagateMask[i] = 0; 1912 FreeResource(ic->resource, RT_NONE); 1913 } 1914} 1915 1916int 1917MaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask) 1918{ 1919 DeviceIntPtr dev; 1920 1921 dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient, 1922 DixReadAccess); 1923 if (!dev) 1924 return 0; 1925 1926 if (pEvents->type == DeviceMotionNotify) { 1927 if (mask & DevicePointerMotionHintMask) { 1928 if (WID(dev->valuator->motionHintWindow) == pEvents->event) { 1929 return 1; /* don't send, but pretend we did */ 1930 } 1931 pEvents->detail = NotifyHint; 1932 } else { 1933 pEvents->detail = NotifyNormal; 1934 } 1935 } 1936 return (0); 1937} 1938 1939void 1940CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, 1941 deviceKeyButtonPointer * xE, GrabPtr grab, 1942 ClientPtr client, Mask deliveryMask) 1943{ 1944 DeviceIntPtr dev; 1945 1946 dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient, 1947 DixReadAccess); 1948 if (!dev) 1949 return; 1950 1951 if (type == DeviceMotionNotify) 1952 dev->valuator->motionHintWindow = pWin; 1953 else if ((type == DeviceButtonPress) && (!grab) && 1954 (deliveryMask & DeviceButtonGrabMask)) { 1955 GrabRec tempGrab; 1956 1957 tempGrab.device = dev; 1958 tempGrab.resource = client->clientAsMask; 1959 tempGrab.window = pWin; 1960 tempGrab.ownerEvents = 1961 (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE; 1962 tempGrab.eventMask = deliveryMask; 1963 tempGrab.keyboardMode = GrabModeAsync; 1964 tempGrab.pointerMode = GrabModeAsync; 1965 tempGrab.confineTo = NullWindow; 1966 tempGrab.cursor = NullCursor; 1967 tempGrab.genericMasks = NULL; 1968 tempGrab.next = NULL; 1969 (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE); 1970 } 1971} 1972 1973static Mask 1974DeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client) 1975{ 1976 InputClientsPtr other; 1977 1978 if (!wOtherInputMasks(pWin)) 1979 return 0; 1980 for (other = wOtherInputMasks(pWin)->inputClients; other; 1981 other = other->next) { 1982 if (SameClient(other, client)) 1983 return other->mask[dev->id]; 1984 } 1985 return 0; 1986} 1987 1988void 1989MaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client) 1990{ 1991 WindowPtr pWin; 1992 GrabPtr grab = dev->deviceGrab.grab; 1993 1994 pWin = dev->valuator->motionHintWindow; 1995 1996 if ((grab && SameClient(grab, client) && 1997 ((grab->eventMask & DevicePointerMotionHintMask) || 1998 (grab->ownerEvents && 1999 (DeviceEventMaskForClient(dev, pWin, client) & 2000 DevicePointerMotionHintMask)))) || 2001 (!grab && 2002 (DeviceEventMaskForClient(dev, pWin, client) & 2003 DevicePointerMotionHintMask))) 2004 dev->valuator->motionHintWindow = NullWindow; 2005} 2006 2007int 2008DeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, 2009 int maskndx) 2010{ 2011 struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 2012 2013 if (mask & ~PropagateMask[maskndx]) { 2014 client->errorValue = mask; 2015 return BadValue; 2016 } 2017 2018 if (mask == 0) { 2019 if (inputMasks) 2020 inputMasks->dontPropagateMask[maskndx] = mask; 2021 } else { 2022 if (!inputMasks) 2023 AddExtensionClient(pWin, client, 0, 0); 2024 inputMasks = wOtherInputMasks(pWin); 2025 inputMasks->dontPropagateMask[maskndx] = mask; 2026 } 2027 RecalculateDeviceDeliverableEvents(pWin); 2028 if (ShouldFreeInputMasks(pWin, FALSE)) 2029 FreeResource(inputMasks->inputClients->resource, RT_NONE); 2030 return Success; 2031} 2032 2033Bool 2034ShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents) 2035{ 2036 int i; 2037 Mask allInputEventMasks = 0; 2038 struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 2039 2040 for (i = 0; i < EMASKSIZE; i++) 2041 allInputEventMasks |= inputMasks->dontPropagateMask[i]; 2042 if (!ignoreSelectedEvents) 2043 for (i = 0; i < EMASKSIZE; i++) 2044 allInputEventMasks |= inputMasks->inputEvents[i]; 2045 if (allInputEventMasks == 0) 2046 return TRUE; 2047 else 2048 return FALSE; 2049} 2050 2051/*********************************************************************** 2052 * 2053 * Walk through the window tree, finding all clients that want to know 2054 * about the Event. 2055 * 2056 */ 2057 2058static void 2059FindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask, 2060 xEvent * ev, int count) 2061{ 2062 WindowPtr p2; 2063 2064 while (p1) { 2065 p2 = p1->firstChild; 2066 (void)DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab, dev->id); 2067 FindInterestedChildren(dev, p2, mask, ev, count); 2068 p1 = p1->nextSib; 2069 } 2070} 2071 2072/*********************************************************************** 2073 * 2074 * Send an event to interested clients in all windows on all screens. 2075 * 2076 */ 2077 2078void 2079SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count) 2080{ 2081 int i; 2082 WindowPtr pWin, p1; 2083 2084 for (i = 0; i < screenInfo.numScreens; i++) { 2085 pWin = WindowTable[i]; 2086 if (!pWin) 2087 continue; 2088 (void)DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab, dev->id); 2089 p1 = pWin->firstChild; 2090 FindInterestedChildren(dev, p1, mask, ev, count); 2091 } 2092} 2093 2094