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