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