exevents.c revision 6747b715
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 if (button_is_down(sd, key, BUTTON_PROCESSED)) 882 return DONT_PROCESS; 883 } 884 } 885 set_button_up(device, key, BUTTON_PROCESSED); 886 if (device->valuator) 887 device->valuator->motionHintWindow = NullWindow; 888 if (!b->map[key]) 889 return DONT_PROCESS; 890 if (b->buttonsDown >= 1 && !--b->buttonsDown) 891 b->motionMask = 0; 892 if (b->map[key] <= 5) 893 b->state &= ~((Button1Mask >> 1) << b->map[key]); 894 895 /* Add state and motionMask to the filter for this event */ 896 mask = DevicePointerMotionMask | b->state | b->motionMask; 897 SetMaskForEvent(device->id, mask, DeviceMotionNotify); 898 mask = PointerMotionMask | b->state | b->motionMask; 899 SetMaskForEvent(device->id, mask, MotionNotify); 900 } else if (event->type == ET_ProximityIn) 901 device->valuator->mode &= ~OutOfProximity; 902 else if (event->type == ET_ProximityOut) 903 device->valuator->mode |= OutOfProximity; 904 905 return DEFAULT; 906} 907 908static void 909ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) 910{ 911 GrabPtr grab = device->deviceGrab.grab; 912 913 if (grab) 914 DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE); 915 else { /* deliver to all root windows */ 916 xEvent *xi; 917 int i; 918 919 i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); 920 if (i != Success) 921 { 922 ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n", 923 device->name, i); 924 return; 925 } 926 927 for (i = 0; i < screenInfo.numScreens; i++) 928 DeliverEventsToWindow(device, screenInfo.screens[i]->root, xi, 1, 929 GetEventFilter(device, xi), NULL); 930 free(xi); 931 } 932} 933 934/** 935 * Main device event processing function. 936 * Called from when processing the events from the event queue. 937 * 938 */ 939void 940ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) 941{ 942 GrabPtr grab; 943 Bool deactivateDeviceGrab = FALSE; 944 int key = 0, rootX, rootY; 945 ButtonClassPtr b; 946 KeyClassPtr k; 947 ValuatorClassPtr v; 948 int ret = 0; 949 int state, i; 950 DeviceIntPtr mouse = NULL, kbd = NULL; 951 DeviceEvent *event = &ev->device_event; 952 953 CHECKEVENT(ev); 954 955 if (ev->any.type == ET_RawKeyPress || 956 ev->any.type == ET_RawKeyRelease || 957 ev->any.type == ET_RawButtonPress || 958 ev->any.type == ET_RawButtonRelease || 959 ev->any.type == ET_RawMotion) 960 { 961 ProcessRawEvent(&ev->raw_event, device); 962 return; 963 } 964 965 if (IsPointerDevice(device)) 966 { 967 kbd = GetPairedDevice(device); 968 mouse = device; 969 if (!kbd->key) /* can happen with floating SDs */ 970 kbd = NULL; 971 } else 972 { 973 mouse = GetPairedDevice(device); 974 kbd = device; 975 if (!mouse->valuator || !mouse->button) /* may be float. SDs */ 976 mouse = NULL; 977 } 978 979 /* State needs to be assembled BEFORE the device is updated. */ 980 state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0; 981 state |= (mouse && mouse->button) ? (mouse->button->state) : 0; 982 983 for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) 984 if (BitIsOn(mouse->button->down, i)) 985 SetBit(event->buttons, i); 986 987 if (kbd && kbd->key) 988 { 989 XkbStatePtr state; 990 /* we need the state before the event happens */ 991 if (event->type == ET_KeyPress || event->type == ET_KeyRelease) 992 state = &kbd->key->xkbInfo->prev_state; 993 else 994 state = &kbd->key->xkbInfo->state; 995 996 event->mods.base = state->base_mods; 997 event->mods.latched = state->latched_mods; 998 event->mods.locked = state->locked_mods; 999 event->mods.effective = state->mods; 1000 1001 event->group.base = state->base_group; 1002 event->group.latched = state->latched_group; 1003 event->group.locked = state->locked_group; 1004 event->group.effective = state->group; 1005 } 1006 1007 ret = UpdateDeviceState(device, event); 1008 if (ret == DONT_PROCESS) 1009 return; 1010 1011 v = device->valuator; 1012 b = device->button; 1013 k = device->key; 1014 1015 if (IsMaster(device) || !device->u.master) 1016 CheckMotion(event, device); 1017 1018 switch (event->type) 1019 { 1020 case ET_Motion: 1021 case ET_ButtonPress: 1022 case ET_ButtonRelease: 1023 case ET_KeyPress: 1024 case ET_KeyRelease: 1025 case ET_ProximityIn: 1026 case ET_ProximityOut: 1027 GetSpritePosition(device, &rootX, &rootY); 1028 event->root_x = rootX; 1029 event->root_y = rootY; 1030 NoticeEventTime((InternalEvent*)event); 1031 event->corestate = state; 1032 key = event->detail.key; 1033 break; 1034 default: 1035 break; 1036 } 1037 1038 if (DeviceEventCallback && !syncEvents.playingEvents) { 1039 DeviceEventInfoRec eventinfo; 1040 SpritePtr pSprite = device->spriteInfo->sprite; 1041 1042 /* see comment in EnqueueEvents regarding the next three lines */ 1043 if (ev->any.type == ET_Motion) 1044 ev->device_event.root = pSprite->hotPhys.pScreen->root->drawable.id; 1045 1046 eventinfo.device = device; 1047 eventinfo.event = ev; 1048 CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); 1049 } 1050 1051 grab = device->deviceGrab.grab; 1052 1053 switch(event->type) 1054 { 1055 case ET_KeyPress: 1056 if (!grab && CheckDeviceGrabs(device, event, 0)) { 1057 device->deviceGrab.activatingKey = key; 1058 return; 1059 } 1060 break; 1061 case ET_KeyRelease: 1062 if (grab && device->deviceGrab.fromPassiveGrab && 1063 (key == device->deviceGrab.activatingKey) && 1064 (device->deviceGrab.grab->type == KeyPress || 1065 device->deviceGrab.grab->type == DeviceKeyPress || 1066 device->deviceGrab.grab->type == XI_KeyPress)) 1067 deactivateDeviceGrab = TRUE; 1068 break; 1069 case ET_ButtonPress: 1070 event->detail.button = b->map[key]; 1071 if (!event->detail.button) { /* there's no button 0 */ 1072 event->detail.button = key; 1073 return; 1074 } 1075 if (!grab && CheckDeviceGrabs(device, event, 0)) 1076 { 1077 /* if a passive grab was activated, the event has been sent 1078 * already */ 1079 return; 1080 } 1081 break; 1082 case ET_ButtonRelease: 1083 event->detail.button = b->map[key]; 1084 if (!event->detail.button) { /* there's no button 0 */ 1085 event->detail.button = key; 1086 return; 1087 } 1088 if (grab && !b->buttonsDown && 1089 device->deviceGrab.fromPassiveGrab && 1090 (device->deviceGrab.grab->type == ButtonPress || 1091 device->deviceGrab.grab->type == DeviceButtonPress || 1092 device->deviceGrab.grab->type == XI_ButtonPress)) 1093 deactivateDeviceGrab = TRUE; 1094 default: 1095 break; 1096 } 1097 1098 1099 if (grab) 1100 DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab); 1101 else if (device->focus && !IsPointerEvent((InternalEvent*)ev)) 1102 DeliverFocusedEvent(device, (InternalEvent*)event, 1103 GetSpriteWindow(device)); 1104 else 1105 DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent*)event, 1106 NullGrab, NullWindow, device); 1107 1108 if (deactivateDeviceGrab == TRUE) 1109 (*device->deviceGrab.DeactivateGrab) (device); 1110 event->detail.key = key; 1111} 1112 1113int 1114InitProximityClassDeviceStruct(DeviceIntPtr dev) 1115{ 1116 ProximityClassPtr proxc; 1117 1118 proxc = (ProximityClassPtr) malloc(sizeof(ProximityClassRec)); 1119 if (!proxc) 1120 return FALSE; 1121 proxc->sourceid = dev->id; 1122 dev->proximity = proxc; 1123 return TRUE; 1124} 1125 1126/** 1127 * Initialise the device's valuators. The memory must already be allocated, 1128 * this function merely inits the matching axis (specified through axnum) to 1129 * sane values. 1130 * 1131 * It is a condition that (minval < maxval). 1132 * 1133 * @see InitValuatorClassDeviceStruct 1134 */ 1135void 1136InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval, 1137 int resolution, int min_res, int max_res) 1138{ 1139 AxisInfoPtr ax; 1140 1141 if (!dev || !dev->valuator || minval > maxval) 1142 return; 1143 if (axnum >= dev->valuator->numAxes) 1144 return; 1145 1146 ax = dev->valuator->axes + axnum; 1147 1148 ax->min_value = minval; 1149 ax->max_value = maxval; 1150 ax->resolution = resolution; 1151 ax->min_resolution = min_res; 1152 ax->max_resolution = max_res; 1153 ax->label = label; 1154} 1155 1156static void 1157FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, 1158 ButtonClassPtr b, ValuatorClassPtr v, int first) 1159{ 1160 ev->type = DeviceStateNotify; 1161 ev->deviceid = dev->id; 1162 ev->time = currentTime.milliseconds; 1163 ev->classes_reported = 0; 1164 ev->num_keys = 0; 1165 ev->num_buttons = 0; 1166 ev->num_valuators = 0; 1167 1168 if (b) { 1169 ev->classes_reported |= (1 << ButtonClass); 1170 ev->num_buttons = b->numButtons; 1171 memcpy((char*)ev->buttons, (char*)b->down, 4); 1172 } else if (k) { 1173 ev->classes_reported |= (1 << KeyClass); 1174 ev->num_keys = k->xkbInfo->desc->max_key_code - 1175 k->xkbInfo->desc->min_key_code; 1176 memmove((char *)&ev->keys[0], (char *)k->down, 4); 1177 } 1178 if (v) { 1179 int nval = v->numAxes - first; 1180 1181 ev->classes_reported |= (1 << ValuatorClass); 1182 ev->classes_reported |= (dev->valuator->mode << ModeBitsShift); 1183 ev->num_valuators = nval < 3 ? nval : 3; 1184 switch (ev->num_valuators) { 1185 case 3: 1186 ev->valuator2 = v->axisVal[first + 2]; 1187 case 2: 1188 ev->valuator1 = v->axisVal[first + 1]; 1189 case 1: 1190 ev->valuator0 = v->axisVal[first]; 1191 break; 1192 } 1193 } 1194} 1195 1196static void 1197FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, 1198 int first) 1199{ 1200 int nval = v->numAxes - first; 1201 1202 ev->type = DeviceValuator; 1203 ev->deviceid = dev->id; 1204 ev->num_valuators = nval < 3 ? nval : 3; 1205 ev->first_valuator = first; 1206 switch (ev->num_valuators) { 1207 case 3: 1208 ev->valuator2 = v->axisVal[first + 2]; 1209 case 2: 1210 ev->valuator1 = v->axisVal[first + 1]; 1211 case 1: 1212 ev->valuator0 = v->axisVal[first]; 1213 break; 1214 } 1215 first += ev->num_valuators; 1216} 1217 1218void 1219DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, 1220 WindowPtr pWin) 1221{ 1222 deviceFocus event; 1223 xXIFocusInEvent *xi2event; 1224 DeviceIntPtr mouse; 1225 int btlen, len, i; 1226 1227 mouse = (IsMaster(dev) || dev->u.master) ? GetMaster(dev, MASTER_POINTER) : dev; 1228 1229 /* XI 2 event */ 1230 btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; 1231 btlen = bytes_to_int32(btlen); 1232 len = sizeof(xXIFocusInEvent) + btlen * 4; 1233 1234 xi2event = calloc(1, len); 1235 xi2event->type = GenericEvent; 1236 xi2event->extension = IReqCode; 1237 xi2event->evtype = type; 1238 xi2event->length = bytes_to_int32(len - sizeof(xEvent)); 1239 xi2event->buttons_len = btlen; 1240 xi2event->detail = detail; 1241 xi2event->time = currentTime.milliseconds; 1242 xi2event->deviceid = dev->id; 1243 xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */ 1244 xi2event->mode = mode; 1245 xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0); 1246 xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0); 1247 1248 for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) 1249 if (BitIsOn(mouse->button->down, i)) 1250 SetBit(&xi2event[1], i); 1251 1252 if (dev->key) 1253 { 1254 xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods; 1255 xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods; 1256 xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods; 1257 xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods; 1258 1259 xi2event->group.base_group = dev->key->xkbInfo->state.base_group; 1260 xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group; 1261 xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group; 1262 xi2event->group.effective_group = dev->key->xkbInfo->state.group; 1263 } 1264 1265 FixUpEventFromWindow(dev, (xEvent*)xi2event, pWin, None, FALSE); 1266 1267 DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1, 1268 GetEventFilter(dev, (xEvent*)xi2event), NullGrab); 1269 1270 free(xi2event); 1271 1272 /* XI 1.x event */ 1273 event.deviceid = dev->id; 1274 event.mode = mode; 1275 event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut; 1276 event.detail = detail; 1277 event.window = pWin->drawable.id; 1278 event.time = currentTime.milliseconds; 1279 1280 DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, 1281 DeviceFocusChangeMask, NullGrab); 1282 1283 if ((type == DeviceFocusIn) && 1284 (wOtherInputMasks(pWin)) && 1285 (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) 1286 { 1287 int evcount = 1; 1288 deviceStateNotify *ev, *sev; 1289 deviceKeyStateNotify *kev; 1290 deviceButtonStateNotify *bev; 1291 1292 KeyClassPtr k; 1293 ButtonClassPtr b; 1294 ValuatorClassPtr v; 1295 int nval = 0, nkeys = 0, nbuttons = 0, first = 0; 1296 1297 if ((b = dev->button) != NULL) { 1298 nbuttons = b->numButtons; 1299 if (nbuttons > 32) 1300 evcount++; 1301 } 1302 if ((k = dev->key) != NULL) { 1303 nkeys = k->xkbInfo->desc->max_key_code - 1304 k->xkbInfo->desc->min_key_code; 1305 if (nkeys > 32) 1306 evcount++; 1307 if (nbuttons > 0) { 1308 evcount++; 1309 } 1310 } 1311 if ((v = dev->valuator) != NULL) { 1312 nval = v->numAxes; 1313 1314 if (nval > 3) 1315 evcount++; 1316 if (nval > 6) { 1317 if (!(k && b)) 1318 evcount++; 1319 if (nval > 9) 1320 evcount += ((nval - 7) / 3); 1321 } 1322 } 1323 1324 sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); 1325 FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); 1326 1327 if (b != NULL) { 1328 FixDeviceStateNotify(dev, ev++, NULL, b, v, first); 1329 first += 3; 1330 nval -= 3; 1331 if (nbuttons > 32) { 1332 (ev - 1)->deviceid |= MORE_EVENTS; 1333 bev = (deviceButtonStateNotify *) ev++; 1334 bev->type = DeviceButtonStateNotify; 1335 bev->deviceid = dev->id; 1336 memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); 1337 } 1338 if (nval > 0) { 1339 (ev - 1)->deviceid |= MORE_EVENTS; 1340 FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 1341 first += 3; 1342 nval -= 3; 1343 } 1344 } 1345 1346 if (k != NULL) { 1347 FixDeviceStateNotify(dev, ev++, k, NULL, v, first); 1348 first += 3; 1349 nval -= 3; 1350 if (nkeys > 32) { 1351 (ev - 1)->deviceid |= MORE_EVENTS; 1352 kev = (deviceKeyStateNotify *) ev++; 1353 kev->type = DeviceKeyStateNotify; 1354 kev->deviceid = dev->id; 1355 memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); 1356 } 1357 if (nval > 0) { 1358 (ev - 1)->deviceid |= MORE_EVENTS; 1359 FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 1360 first += 3; 1361 nval -= 3; 1362 } 1363 } 1364 1365 while (nval > 0) { 1366 FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); 1367 first += 3; 1368 nval -= 3; 1369 if (nval > 0) { 1370 (ev - 1)->deviceid |= MORE_EVENTS; 1371 FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 1372 first += 3; 1373 nval -= 3; 1374 } 1375 } 1376 1377 DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount, 1378 DeviceStateNotifyMask, NullGrab); 1379 free(sev); 1380 } 1381} 1382 1383int 1384CheckGrabValues(ClientPtr client, GrabParameters* param) 1385{ 1386 if (param->grabtype != GRABTYPE_CORE && 1387 param->grabtype != GRABTYPE_XI && 1388 param->grabtype != GRABTYPE_XI2) 1389 { 1390 ErrorF("[Xi] grabtype is invalid. This is a bug.\n"); 1391 return BadImplementation; 1392 } 1393 1394 if ((param->this_device_mode != GrabModeSync) && 1395 (param->this_device_mode != GrabModeAsync)) { 1396 client->errorValue = param->this_device_mode; 1397 return BadValue; 1398 } 1399 if ((param->other_devices_mode != GrabModeSync) && 1400 (param->other_devices_mode != GrabModeAsync)) { 1401 client->errorValue = param->other_devices_mode; 1402 return BadValue; 1403 } 1404 1405 if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) && 1406 (param->modifiers & ~AllModifiersMask)) { 1407 client->errorValue = param->modifiers; 1408 return BadValue; 1409 } 1410 1411 if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) { 1412 client->errorValue = param->ownerEvents; 1413 return BadValue; 1414 } 1415 return Success; 1416} 1417 1418int 1419GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, 1420 int button, GrabParameters *param, GrabType grabtype, 1421 GrabMask *mask) 1422{ 1423 WindowPtr pWin, confineTo; 1424 CursorPtr cursor; 1425 GrabPtr grab; 1426 int rc, type = -1; 1427 Mask access_mode = DixGrabAccess; 1428 1429 rc = CheckGrabValues(client, param); 1430 if (rc != Success) 1431 return rc; 1432 if (param->confineTo == None) 1433 confineTo = NullWindow; 1434 else { 1435 rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess); 1436 if (rc != Success) 1437 return rc; 1438 } 1439 if (param->cursor == None) 1440 cursor = NullCursor; 1441 else { 1442 rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, 1443 RT_CURSOR, client, DixUseAccess); 1444 if (rc != Success) 1445 { 1446 client->errorValue = param->cursor; 1447 return rc; 1448 } 1449 access_mode |= DixForceAccess; 1450 } 1451 if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 1452 access_mode |= DixFreezeAccess; 1453 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 1454 if (rc != Success) 1455 return rc; 1456 rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 1457 if (rc != Success) 1458 return rc; 1459 1460 if (grabtype == GRABTYPE_XI) 1461 type = DeviceButtonPress; 1462 else if (grabtype == GRABTYPE_XI2) 1463 type = XI_ButtonPress; 1464 1465 grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, 1466 mask, param, type, button, confineTo, cursor); 1467 if (!grab) 1468 return BadAlloc; 1469 return AddPassiveGrabToList(client, grab); 1470} 1471 1472/** 1473 * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If 1474 * grabtype is GRABTYPE_XI2, the key is a keysym. 1475 */ 1476int 1477GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, 1478 int key, GrabParameters *param, GrabType grabtype, GrabMask *mask) 1479{ 1480 WindowPtr pWin; 1481 GrabPtr grab; 1482 KeyClassPtr k = dev->key; 1483 Mask access_mode = DixGrabAccess; 1484 int rc, type = -1; 1485 1486 rc = CheckGrabValues(client, param); 1487 if (rc != Success) 1488 return rc; 1489 if (k == NULL) 1490 return BadMatch; 1491 if (grabtype == GRABTYPE_XI) 1492 { 1493 if ((key > k->xkbInfo->desc->max_key_code || 1494 key < k->xkbInfo->desc->min_key_code) 1495 && (key != AnyKey)) { 1496 client->errorValue = key; 1497 return BadValue; 1498 } 1499 type = DeviceKeyPress; 1500 } else if (grabtype == GRABTYPE_XI2) 1501 type = XI_KeyPress; 1502 1503 rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 1504 if (rc != Success) 1505 return rc; 1506 if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 1507 access_mode |= DixFreezeAccess; 1508 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 1509 if (rc != Success) 1510 return rc; 1511 1512 grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, 1513 mask, param, type, key, NULL, NULL); 1514 if (!grab) 1515 return BadAlloc; 1516 return AddPassiveGrabToList(client, grab); 1517} 1518 1519/* Enter/FocusIn grab */ 1520int 1521GrabWindow(ClientPtr client, DeviceIntPtr dev, int type, 1522 GrabParameters *param, GrabMask *mask) 1523{ 1524 WindowPtr pWin; 1525 CursorPtr cursor; 1526 GrabPtr grab; 1527 Mask access_mode = DixGrabAccess; 1528 int rc; 1529 1530 rc = CheckGrabValues(client, param); 1531 if (rc != Success) 1532 return rc; 1533 1534 rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 1535 if (rc != Success) 1536 return rc; 1537 if (param->cursor == None) 1538 cursor = NullCursor; 1539 else { 1540 rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, 1541 RT_CURSOR, client, DixUseAccess); 1542 if (rc != Success) 1543 { 1544 client->errorValue = param->cursor; 1545 return rc; 1546 } 1547 access_mode |= DixForceAccess; 1548 } 1549 if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 1550 access_mode |= DixFreezeAccess; 1551 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 1552 if (rc != Success) 1553 return rc; 1554 1555 grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2, 1556 mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn, 1557 0, NULL, cursor); 1558 1559 if (!grab) 1560 return BadAlloc; 1561 1562 return AddPassiveGrabToList(client, grab); 1563} 1564 1565int 1566SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client, 1567 Mask mask, Mask exclusivemasks) 1568{ 1569 int mskidx = dev->id; 1570 int i, ret; 1571 Mask check; 1572 InputClientsPtr others; 1573 1574 check = (mask & exclusivemasks); 1575 if (wOtherInputMasks(pWin)) { 1576 if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different 1577 * clients to select on any of the 1578 * events for maskcheck. However, 1579 * it is OK, for some client to 1580 * continue selecting on one of those 1581 * events. */ 1582 for (others = wOtherInputMasks(pWin)->inputClients; others; 1583 others = others->next) { 1584 if (!SameClient(others, client) && (check & 1585 others->mask[mskidx])) 1586 return BadAccess; 1587 } 1588 } 1589 for (others = wOtherInputMasks(pWin)->inputClients; others; 1590 others = others->next) { 1591 if (SameClient(others, client)) { 1592 check = others->mask[mskidx]; 1593 others->mask[mskidx] = mask; 1594 if (mask == 0) { 1595 for (i = 0; i < EMASKSIZE; i++) 1596 if (i != mskidx && others->mask[i] != 0) 1597 break; 1598 if (i == EMASKSIZE) { 1599 RecalculateDeviceDeliverableEvents(pWin); 1600 if (ShouldFreeInputMasks(pWin, FALSE)) 1601 FreeResource(others->resource, RT_NONE); 1602 return Success; 1603 } 1604 } 1605 goto maskSet; 1606 } 1607 } 1608 } 1609 check = 0; 1610 if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success) 1611 return ret; 1612 maskSet: 1613 if (dev->valuator) 1614 if ((dev->valuator->motionHintWindow == pWin) && 1615 (mask & DevicePointerMotionHintMask) && 1616 !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab) 1617 dev->valuator->motionHintWindow = NullWindow; 1618 RecalculateDeviceDeliverableEvents(pWin); 1619 return Success; 1620} 1621 1622int 1623AddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx) 1624{ 1625 InputClientsPtr others; 1626 1627 if (!pWin->optional && !MakeWindowOptional(pWin)) 1628 return BadAlloc; 1629 others = calloc(1, sizeof(InputClients)); 1630 if (!others) 1631 return BadAlloc; 1632 if (!pWin->optional->inputMasks && !MakeInputMasks(pWin)) 1633 return BadAlloc; 1634 others->mask[mskidx] = mask; 1635 others->resource = FakeClientID(client->index); 1636 others->next = pWin->optional->inputMasks->inputClients; 1637 pWin->optional->inputMasks->inputClients = others; 1638 if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin)) 1639 return BadAlloc; 1640 return Success; 1641} 1642 1643static Bool 1644MakeInputMasks(WindowPtr pWin) 1645{ 1646 struct _OtherInputMasks *imasks; 1647 1648 imasks = calloc(1, sizeof(struct _OtherInputMasks)); 1649 if (!imasks) 1650 return FALSE; 1651 pWin->optional->inputMasks = imasks; 1652 return TRUE; 1653} 1654 1655void 1656RecalculateDeviceDeliverableEvents(WindowPtr pWin) 1657{ 1658 InputClientsPtr others; 1659 struct _OtherInputMasks *inputMasks; /* default: NULL */ 1660 WindowPtr pChild, tmp; 1661 int i, j; 1662 1663 pChild = pWin; 1664 while (1) { 1665 if ((inputMasks = wOtherInputMasks(pChild)) != 0) { 1666 for (i = 0; i < EMASKSIZE; i++) 1667 memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i])); 1668 for (others = inputMasks->inputClients; others; 1669 others = others->next) { 1670 for (i = 0; i < EMASKSIZE; i++) 1671 inputMasks->inputEvents[i] |= others->mask[i]; 1672 for (i = 0; i < EMASKSIZE; i++) 1673 for (j = 0; j < XI2MASKSIZE; j++) 1674 inputMasks->xi2mask[i][j] |= others->xi2mask[i][j]; 1675 } 1676 for (i = 0; i < EMASKSIZE; i++) 1677 inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i]; 1678 for (tmp = pChild->parent; tmp; tmp = tmp->parent) 1679 if (wOtherInputMasks(tmp)) 1680 for (i = 0; i < EMASKSIZE; i++) 1681 inputMasks->deliverableEvents[i] |= 1682 (wOtherInputMasks(tmp)->deliverableEvents[i] 1683 & ~inputMasks-> 1684 dontPropagateMask[i] & PropagateMask[i]); 1685 } 1686 if (pChild->firstChild) { 1687 pChild = pChild->firstChild; 1688 continue; 1689 } 1690 while (!pChild->nextSib && (pChild != pWin)) 1691 pChild = pChild->parent; 1692 if (pChild == pWin) 1693 break; 1694 pChild = pChild->nextSib; 1695 } 1696} 1697 1698int 1699InputClientGone(WindowPtr pWin, XID id) 1700{ 1701 InputClientsPtr other, prev; 1702 1703 if (!wOtherInputMasks(pWin)) 1704 return Success; 1705 prev = 0; 1706 for (other = wOtherInputMasks(pWin)->inputClients; other; 1707 other = other->next) { 1708 if (other->resource == id) { 1709 if (prev) { 1710 prev->next = other->next; 1711 free(other); 1712 } else if (!(other->next)) { 1713 if (ShouldFreeInputMasks(pWin, TRUE)) { 1714 wOtherInputMasks(pWin)->inputClients = other->next; 1715 free(wOtherInputMasks(pWin)); 1716 pWin->optional->inputMasks = (OtherInputMasks *) NULL; 1717 CheckWindowOptionalNeed(pWin); 1718 free(other); 1719 } else { 1720 other->resource = FakeClientID(0); 1721 if (!AddResource(other->resource, RT_INPUTCLIENT, 1722 (pointer) pWin)) 1723 return BadAlloc; 1724 } 1725 } else { 1726 wOtherInputMasks(pWin)->inputClients = other->next; 1727 free(other); 1728 } 1729 RecalculateDeviceDeliverableEvents(pWin); 1730 return Success; 1731 } 1732 prev = other; 1733 } 1734 FatalError("client not on device event list"); 1735} 1736 1737int 1738SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, 1739 xEvent * ev, Mask mask, int count) 1740{ 1741 WindowPtr pWin; 1742 WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ 1743 WindowPtr spriteWin = GetSpriteWindow(d); 1744 1745 if (dest == PointerWindow) 1746 pWin = spriteWin; 1747 else if (dest == InputFocus) { 1748 WindowPtr inputFocus; 1749 1750 if (!d->focus) 1751 inputFocus = spriteWin; 1752 else 1753 inputFocus = d->focus->win; 1754 1755 if (inputFocus == FollowKeyboardWin) 1756 inputFocus = inputInfo.keyboard->focus->win; 1757 1758 if (inputFocus == NoneWin) 1759 return Success; 1760 1761 /* If the input focus is PointerRootWin, send the event to where 1762 * the pointer is if possible, then perhaps propogate up to root. */ 1763 if (inputFocus == PointerRootWin) 1764 inputFocus = GetCurrentRootWindow(d); 1765 1766 if (IsParent(inputFocus, spriteWin)) { 1767 effectiveFocus = inputFocus; 1768 pWin = spriteWin; 1769 } else 1770 effectiveFocus = pWin = inputFocus; 1771 } else 1772 dixLookupWindow(&pWin, dest, client, DixSendAccess); 1773 if (!pWin) 1774 return BadWindow; 1775 if ((propagate != xFalse) && (propagate != xTrue)) { 1776 client->errorValue = propagate; 1777 return BadValue; 1778 } 1779 ev->u.u.type |= 0x80; 1780 if (propagate) { 1781 for (; pWin; pWin = pWin->parent) { 1782 if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab)) 1783 return Success; 1784 if (pWin == effectiveFocus) 1785 return Success; 1786 if (wOtherInputMasks(pWin)) 1787 mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id]; 1788 if (!mask) 1789 break; 1790 } 1791 } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count)) 1792 DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab); 1793 return Success; 1794} 1795 1796int 1797SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map) 1798{ 1799 int i; 1800 ButtonClassPtr b = dev->button; 1801 1802 if (b == NULL) 1803 return BadMatch; 1804 1805 if (nElts != b->numButtons) { 1806 client->errorValue = nElts; 1807 return BadValue; 1808 } 1809 if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue)) 1810 return BadValue; 1811 for (i = 0; i < nElts; i++) 1812 if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1)) 1813 return MappingBusy; 1814 for (i = 0; i < nElts; i++) 1815 b->map[i + 1] = map[i]; 1816 return Success; 1817} 1818 1819int 1820ChangeKeyMapping(ClientPtr client, 1821 DeviceIntPtr dev, 1822 unsigned len, 1823 int type, 1824 KeyCode firstKeyCode, 1825 CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map) 1826{ 1827 KeySymsRec keysyms; 1828 KeyClassPtr k = dev->key; 1829 1830 if (k == NULL) 1831 return BadMatch; 1832 1833 if (len != (keyCodes * keySymsPerKeyCode)) 1834 return BadLength; 1835 1836 if ((firstKeyCode < k->xkbInfo->desc->min_key_code) || 1837 (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) { 1838 client->errorValue = firstKeyCode; 1839 return BadValue; 1840 } 1841 if (keySymsPerKeyCode == 0) { 1842 client->errorValue = 0; 1843 return BadValue; 1844 } 1845 keysyms.minKeyCode = firstKeyCode; 1846 keysyms.maxKeyCode = firstKeyCode + keyCodes - 1; 1847 keysyms.mapWidth = keySymsPerKeyCode; 1848 keysyms.map = map; 1849 1850 XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL, 1851 serverClient); 1852 1853 return Success; 1854} 1855 1856static void 1857DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) 1858{ 1859 WindowPtr parent; 1860 1861 /* Deactivate any grabs performed on this window, before making 1862 * any input focus changes. 1863 * Deactivating a device grab should cause focus events. */ 1864 1865 if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin)) 1866 (*dev->deviceGrab.DeactivateGrab) (dev); 1867 1868 /* If the focus window is a root window (ie. has no parent) 1869 * then don't delete the focus from it. */ 1870 1871 if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) { 1872 int focusEventMode = NotifyNormal; 1873 1874 /* If a grab is in progress, then alter the mode of focus events. */ 1875 1876 if (dev->deviceGrab.grab) 1877 focusEventMode = NotifyWhileGrabbed; 1878 1879 switch (dev->focus->revert) { 1880 case RevertToNone: 1881 if (!ActivateFocusInGrab(dev, pWin, NoneWin)) 1882 DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 1883 dev->focus->win = NoneWin; 1884 dev->focus->traceGood = 0; 1885 break; 1886 case RevertToParent: 1887 parent = pWin; 1888 do { 1889 parent = parent->parent; 1890 dev->focus->traceGood--; 1891 } 1892 while (!parent->realized); 1893 if (!ActivateFocusInGrab(dev, pWin, parent)) 1894 DoFocusEvents(dev, pWin, parent, focusEventMode); 1895 dev->focus->win = parent; 1896 dev->focus->revert = RevertToNone; 1897 break; 1898 case RevertToPointerRoot: 1899 if (!ActivateFocusInGrab(dev, pWin, PointerRootWin)) 1900 DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); 1901 dev->focus->win = PointerRootWin; 1902 dev->focus->traceGood = 0; 1903 break; 1904 case RevertToFollowKeyboard: 1905 { 1906 DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD); 1907 if (!kbd || (kbd == dev && kbd != inputInfo.keyboard)) 1908 kbd = inputInfo.keyboard; 1909 if (kbd->focus->win) { 1910 if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win)) 1911 DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode); 1912 dev->focus->win = FollowKeyboardWin; 1913 dev->focus->traceGood = 0; 1914 } else { 1915 if (!ActivateFocusInGrab(dev, pWin, NoneWin)) 1916 DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 1917 dev->focus->win = NoneWin; 1918 dev->focus->traceGood = 0; 1919 } 1920 } 1921 break; 1922 } 1923 } 1924 1925 if (dev->valuator) 1926 if (dev->valuator->motionHintWindow == pWin) 1927 dev->valuator->motionHintWindow = NullWindow; 1928} 1929 1930void 1931DeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources) 1932{ 1933 int i; 1934 DeviceIntPtr dev; 1935 InputClientsPtr ic; 1936 struct _OtherInputMasks *inputMasks; 1937 1938 for (dev = inputInfo.devices; dev; dev = dev->next) { 1939 DeleteDeviceFromAnyExtEvents(pWin, dev); 1940 } 1941 1942 for (dev = inputInfo.off_devices; dev; dev = dev->next) 1943 DeleteDeviceFromAnyExtEvents(pWin, dev); 1944 1945 if (freeResources) 1946 while ((inputMasks = wOtherInputMasks(pWin)) != 0) { 1947 ic = inputMasks->inputClients; 1948 for (i = 0; i < EMASKSIZE; i++) 1949 inputMasks->dontPropagateMask[i] = 0; 1950 FreeResource(ic->resource, RT_NONE); 1951 } 1952} 1953 1954int 1955MaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask) 1956{ 1957 DeviceIntPtr dev; 1958 1959 dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient, 1960 DixReadAccess); 1961 if (!dev) 1962 return 0; 1963 1964 if (pEvents->type == DeviceMotionNotify) { 1965 if (mask & DevicePointerMotionHintMask) { 1966 if (WID(dev->valuator->motionHintWindow) == pEvents->event) { 1967 return 1; /* don't send, but pretend we did */ 1968 } 1969 pEvents->detail = NotifyHint; 1970 } else { 1971 pEvents->detail = NotifyNormal; 1972 } 1973 } 1974 return 0; 1975} 1976 1977void 1978CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, 1979 deviceKeyButtonPointer * xE, GrabPtr grab, 1980 ClientPtr client, Mask deliveryMask) 1981{ 1982 DeviceIntPtr dev; 1983 1984 dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient, 1985 DixGrabAccess); 1986 if (!dev) 1987 return; 1988 1989 if (type == DeviceMotionNotify) 1990 dev->valuator->motionHintWindow = pWin; 1991 else if ((type == DeviceButtonPress) && (!grab) && 1992 (deliveryMask & DeviceButtonGrabMask)) { 1993 GrabRec tempGrab; 1994 1995 tempGrab.device = dev; 1996 tempGrab.resource = client->clientAsMask; 1997 tempGrab.window = pWin; 1998 tempGrab.ownerEvents = 1999 (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE; 2000 tempGrab.eventMask = deliveryMask; 2001 tempGrab.keyboardMode = GrabModeAsync; 2002 tempGrab.pointerMode = GrabModeAsync; 2003 tempGrab.confineTo = NullWindow; 2004 tempGrab.cursor = NullCursor; 2005 tempGrab.next = NULL; 2006 (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE); 2007 } 2008} 2009 2010static Mask 2011DeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client) 2012{ 2013 InputClientsPtr other; 2014 2015 if (!wOtherInputMasks(pWin)) 2016 return 0; 2017 for (other = wOtherInputMasks(pWin)->inputClients; other; 2018 other = other->next) { 2019 if (SameClient(other, client)) 2020 return other->mask[dev->id]; 2021 } 2022 return 0; 2023} 2024 2025void 2026MaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client) 2027{ 2028 WindowPtr pWin; 2029 GrabPtr grab = dev->deviceGrab.grab; 2030 2031 pWin = dev->valuator->motionHintWindow; 2032 2033 if ((grab && SameClient(grab, client) && 2034 ((grab->eventMask & DevicePointerMotionHintMask) || 2035 (grab->ownerEvents && 2036 (DeviceEventMaskForClient(dev, pWin, client) & 2037 DevicePointerMotionHintMask)))) || 2038 (!grab && 2039 (DeviceEventMaskForClient(dev, pWin, client) & 2040 DevicePointerMotionHintMask))) 2041 dev->valuator->motionHintWindow = NullWindow; 2042} 2043 2044int 2045DeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, 2046 int maskndx) 2047{ 2048 struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 2049 2050 if (mask & ~PropagateMask[maskndx]) { 2051 client->errorValue = mask; 2052 return BadValue; 2053 } 2054 2055 if (mask == 0) { 2056 if (inputMasks) 2057 inputMasks->dontPropagateMask[maskndx] = mask; 2058 } else { 2059 if (!inputMasks) 2060 AddExtensionClient(pWin, client, 0, 0); 2061 inputMasks = wOtherInputMasks(pWin); 2062 inputMasks->dontPropagateMask[maskndx] = mask; 2063 } 2064 RecalculateDeviceDeliverableEvents(pWin); 2065 if (ShouldFreeInputMasks(pWin, FALSE)) 2066 FreeResource(inputMasks->inputClients->resource, RT_NONE); 2067 return Success; 2068} 2069 2070Bool 2071ShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents) 2072{ 2073 int i; 2074 Mask allInputEventMasks = 0; 2075 struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 2076 2077 for (i = 0; i < EMASKSIZE; i++) 2078 allInputEventMasks |= inputMasks->dontPropagateMask[i]; 2079 if (!ignoreSelectedEvents) 2080 for (i = 0; i < EMASKSIZE; i++) 2081 allInputEventMasks |= inputMasks->inputEvents[i]; 2082 if (allInputEventMasks == 0) 2083 return TRUE; 2084 else 2085 return FALSE; 2086} 2087 2088/*********************************************************************** 2089 * 2090 * Walk through the window tree, finding all clients that want to know 2091 * about the Event. 2092 * 2093 */ 2094 2095static void 2096FindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask, 2097 xEvent * ev, int count) 2098{ 2099 WindowPtr p2; 2100 2101 while (p1) { 2102 p2 = p1->firstChild; 2103 DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab); 2104 FindInterestedChildren(dev, p2, mask, ev, count); 2105 p1 = p1->nextSib; 2106 } 2107} 2108 2109/*********************************************************************** 2110 * 2111 * Send an event to interested clients in all windows on all screens. 2112 * 2113 */ 2114 2115void 2116SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count) 2117{ 2118 int i; 2119 WindowPtr pWin, p1; 2120 2121 for (i = 0; i < screenInfo.numScreens; i++) { 2122 pWin = screenInfo.screens[i]->root; 2123 if (!pWin) 2124 continue; 2125 DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab); 2126 p1 = pWin->firstChild; 2127 FindInterestedChildren(dev, p1, mask, ev, count); 2128 } 2129} 2130 2131/** 2132 * Set the XI2 mask for the given client on the given window. 2133 * @param dev The device to set the mask for. 2134 * @param win The window to set the mask on. 2135 * @param client The client setting the mask. 2136 * @param len Number of bytes in mask. 2137 * @param mask Event mask in the form of (1 << eventtype) 2138 */ 2139int 2140XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client, 2141 unsigned int len, unsigned char* mask) 2142{ 2143 OtherInputMasks *masks; 2144 InputClientsPtr others = NULL; 2145 2146 masks = wOtherInputMasks(win); 2147 if (masks) 2148 { 2149 for (others = wOtherInputMasks(win)->inputClients; others; 2150 others = others->next) { 2151 if (SameClient(others, client)) { 2152 memset(others->xi2mask[dev->id], 0, 2153 sizeof(others->xi2mask[dev->id])); 2154 break; 2155 } 2156 } 2157 } 2158 2159 len = min(len, sizeof(others->xi2mask[dev->id])); 2160 2161 if (len && !others) 2162 { 2163 if (AddExtensionClient(win, client, 0, 0) != Success) 2164 return BadAlloc; 2165 others= wOtherInputMasks(win)->inputClients; 2166 } 2167 2168 if (others) 2169 memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id])); 2170 2171 if (len) 2172 memcpy(others->xi2mask[dev->id], mask, len); 2173 2174 RecalculateDeviceDeliverableEvents(win); 2175 2176 return Success; 2177} 2178