exevents.c revision d931189f
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 */ 1228 btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; 1229 btlen = bytes_to_int32(btlen); 1230 len = sizeof(xXIFocusInEvent) + btlen * 4; 1231 1232 xi2event = calloc(1, len); 1233 xi2event->type = GenericEvent; 1234 xi2event->extension = IReqCode; 1235 xi2event->evtype = type; 1236 xi2event->length = bytes_to_int32(len - sizeof(xEvent)); 1237 xi2event->buttons_len = btlen; 1238 xi2event->detail = detail; 1239 xi2event->time = currentTime.milliseconds; 1240 xi2event->deviceid = dev->id; 1241 xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */ 1242 xi2event->mode = mode; 1243 xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0); 1244 xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0); 1245 1246 for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) 1247 if (BitIsOn(mouse->button->down, i)) 1248 SetBit(&xi2event[1], i); 1249 1250 if (dev->key) 1251 { 1252 xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods; 1253 xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods; 1254 xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods; 1255 xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods; 1256 1257 xi2event->group.base_group = dev->key->xkbInfo->state.base_group; 1258 xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group; 1259 xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group; 1260 xi2event->group.effective_group = dev->key->xkbInfo->state.group; 1261 } 1262 1263 FixUpEventFromWindow(dev->spriteInfo->sprite, (xEvent*)xi2event, pWin, 1264 None, FALSE); 1265 1266 DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1, 1267 GetEventFilter(dev, (xEvent*)xi2event), NullGrab); 1268 1269 free(xi2event); 1270 1271 /* XI 1.x event */ 1272 event.deviceid = dev->id; 1273 event.mode = mode; 1274 event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut; 1275 event.detail = detail; 1276 event.window = pWin->drawable.id; 1277 event.time = currentTime.milliseconds; 1278 1279 DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, 1280 DeviceFocusChangeMask, NullGrab); 1281 1282 if ((event.type == DeviceFocusIn) && 1283 (wOtherInputMasks(pWin)) && 1284 (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) 1285 { 1286 int evcount = 1; 1287 deviceStateNotify *ev, *sev; 1288 deviceKeyStateNotify *kev; 1289 deviceButtonStateNotify *bev; 1290 1291 KeyClassPtr k; 1292 ButtonClassPtr b; 1293 ValuatorClassPtr v; 1294 int nval = 0, nkeys = 0, nbuttons = 0, first = 0; 1295 1296 if ((b = dev->button) != NULL) { 1297 nbuttons = b->numButtons; 1298 if (nbuttons > 32) 1299 evcount++; 1300 } 1301 if ((k = dev->key) != NULL) { 1302 nkeys = k->xkbInfo->desc->max_key_code - 1303 k->xkbInfo->desc->min_key_code; 1304 if (nkeys > 32) 1305 evcount++; 1306 if (nbuttons > 0) { 1307 evcount++; 1308 } 1309 } 1310 if ((v = dev->valuator) != NULL) { 1311 nval = v->numAxes; 1312 1313 if (nval > 3) 1314 evcount++; 1315 if (nval > 6) { 1316 if (!(k && b)) 1317 evcount++; 1318 if (nval > 9) 1319 evcount += ((nval - 7) / 3); 1320 } 1321 } 1322 1323 sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); 1324 FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); 1325 1326 if (b != NULL) { 1327 FixDeviceStateNotify(dev, ev++, NULL, b, v, first); 1328 first += 3; 1329 nval -= 3; 1330 if (nbuttons > 32) { 1331 (ev - 1)->deviceid |= MORE_EVENTS; 1332 bev = (deviceButtonStateNotify *) ev++; 1333 bev->type = DeviceButtonStateNotify; 1334 bev->deviceid = dev->id; 1335 memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); 1336 } 1337 if (nval > 0) { 1338 (ev - 1)->deviceid |= MORE_EVENTS; 1339 FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 1340 first += 3; 1341 nval -= 3; 1342 } 1343 } 1344 1345 if (k != NULL) { 1346 FixDeviceStateNotify(dev, ev++, k, NULL, v, first); 1347 first += 3; 1348 nval -= 3; 1349 if (nkeys > 32) { 1350 (ev - 1)->deviceid |= MORE_EVENTS; 1351 kev = (deviceKeyStateNotify *) ev++; 1352 kev->type = DeviceKeyStateNotify; 1353 kev->deviceid = dev->id; 1354 memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); 1355 } 1356 if (nval > 0) { 1357 (ev - 1)->deviceid |= MORE_EVENTS; 1358 FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 1359 first += 3; 1360 nval -= 3; 1361 } 1362 } 1363 1364 while (nval > 0) { 1365 FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); 1366 first += 3; 1367 nval -= 3; 1368 if (nval > 0) { 1369 (ev - 1)->deviceid |= MORE_EVENTS; 1370 FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 1371 first += 3; 1372 nval -= 3; 1373 } 1374 } 1375 1376 DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount, 1377 DeviceStateNotifyMask, NullGrab); 1378 free(sev); 1379 } 1380} 1381 1382int 1383CheckGrabValues(ClientPtr client, GrabParameters* param) 1384{ 1385 if (param->grabtype != GRABTYPE_CORE && 1386 param->grabtype != GRABTYPE_XI && 1387 param->grabtype != GRABTYPE_XI2) 1388 { 1389 ErrorF("[Xi] grabtype is invalid. This is a bug.\n"); 1390 return BadImplementation; 1391 } 1392 1393 if ((param->this_device_mode != GrabModeSync) && 1394 (param->this_device_mode != GrabModeAsync)) { 1395 client->errorValue = param->this_device_mode; 1396 return BadValue; 1397 } 1398 if ((param->other_devices_mode != GrabModeSync) && 1399 (param->other_devices_mode != GrabModeAsync)) { 1400 client->errorValue = param->other_devices_mode; 1401 return BadValue; 1402 } 1403 1404 if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) && 1405 (param->modifiers & ~AllModifiersMask)) { 1406 client->errorValue = param->modifiers; 1407 return BadValue; 1408 } 1409 1410 if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) { 1411 client->errorValue = param->ownerEvents; 1412 return BadValue; 1413 } 1414 return Success; 1415} 1416 1417int 1418GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, 1419 int button, GrabParameters *param, GrabType grabtype, 1420 GrabMask *mask) 1421{ 1422 WindowPtr pWin, confineTo; 1423 CursorPtr cursor; 1424 GrabPtr grab; 1425 int rc, type = -1; 1426 Mask access_mode = DixGrabAccess; 1427 1428 rc = CheckGrabValues(client, param); 1429 if (rc != Success) 1430 return rc; 1431 if (param->confineTo == None) 1432 confineTo = NullWindow; 1433 else { 1434 rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess); 1435 if (rc != Success) 1436 return rc; 1437 } 1438 if (param->cursor == None) 1439 cursor = NullCursor; 1440 else { 1441 rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, 1442 RT_CURSOR, client, DixUseAccess); 1443 if (rc != Success) 1444 { 1445 client->errorValue = param->cursor; 1446 return rc; 1447 } 1448 access_mode |= DixForceAccess; 1449 } 1450 if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 1451 access_mode |= DixFreezeAccess; 1452 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 1453 if (rc != Success) 1454 return rc; 1455 rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 1456 if (rc != Success) 1457 return rc; 1458 1459 if (grabtype == GRABTYPE_XI) 1460 type = DeviceButtonPress; 1461 else if (grabtype == GRABTYPE_XI2) 1462 type = XI_ButtonPress; 1463 1464 grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, 1465 mask, param, type, button, confineTo, cursor); 1466 if (!grab) 1467 return BadAlloc; 1468 return AddPassiveGrabToList(client, grab); 1469} 1470 1471/** 1472 * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If 1473 * grabtype is GRABTYPE_XI2, the key is a keysym. 1474 */ 1475int 1476GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, 1477 int key, GrabParameters *param, GrabType grabtype, GrabMask *mask) 1478{ 1479 WindowPtr pWin; 1480 GrabPtr grab; 1481 KeyClassPtr k = dev->key; 1482 Mask access_mode = DixGrabAccess; 1483 int rc, type = -1; 1484 1485 rc = CheckGrabValues(client, param); 1486 if (rc != Success) 1487 return rc; 1488 if ((dev->id != XIAllDevices && dev->id != XIAllMasterDevices) && k == NULL) 1489 return BadMatch; 1490 if (grabtype == GRABTYPE_XI) 1491 { 1492 if ((key > k->xkbInfo->desc->max_key_code || 1493 key < k->xkbInfo->desc->min_key_code) 1494 && (key != AnyKey)) { 1495 client->errorValue = key; 1496 return BadValue; 1497 } 1498 type = DeviceKeyPress; 1499 } else if (grabtype == GRABTYPE_XI2) 1500 type = XI_KeyPress; 1501 1502 rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 1503 if (rc != Success) 1504 return rc; 1505 if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 1506 access_mode |= DixFreezeAccess; 1507 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 1508 if (rc != Success) 1509 return rc; 1510 1511 grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, 1512 mask, param, type, key, NULL, NULL); 1513 if (!grab) 1514 return BadAlloc; 1515 return AddPassiveGrabToList(client, grab); 1516} 1517 1518/* Enter/FocusIn grab */ 1519int 1520GrabWindow(ClientPtr client, DeviceIntPtr dev, int type, 1521 GrabParameters *param, GrabMask *mask) 1522{ 1523 WindowPtr pWin; 1524 CursorPtr cursor; 1525 GrabPtr grab; 1526 Mask access_mode = DixGrabAccess; 1527 int rc; 1528 1529 rc = CheckGrabValues(client, param); 1530 if (rc != Success) 1531 return rc; 1532 1533 rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 1534 if (rc != Success) 1535 return rc; 1536 if (param->cursor == None) 1537 cursor = NullCursor; 1538 else { 1539 rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, 1540 RT_CURSOR, client, DixUseAccess); 1541 if (rc != Success) 1542 { 1543 client->errorValue = param->cursor; 1544 return rc; 1545 } 1546 access_mode |= DixForceAccess; 1547 } 1548 if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 1549 access_mode |= DixFreezeAccess; 1550 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 1551 if (rc != Success) 1552 return rc; 1553 1554 grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2, 1555 mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn, 1556 0, NULL, cursor); 1557 1558 if (!grab) 1559 return BadAlloc; 1560 1561 return AddPassiveGrabToList(client, grab); 1562} 1563 1564int 1565SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client, 1566 Mask mask, Mask exclusivemasks) 1567{ 1568 int mskidx = dev->id; 1569 int i, ret; 1570 Mask check; 1571 InputClientsPtr others; 1572 1573 check = (mask & exclusivemasks); 1574 if (wOtherInputMasks(pWin)) { 1575 if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different 1576 * clients to select on any of the 1577 * events for maskcheck. However, 1578 * it is OK, for some client to 1579 * continue selecting on one of those 1580 * events. */ 1581 for (others = wOtherInputMasks(pWin)->inputClients; others; 1582 others = others->next) { 1583 if (!SameClient(others, client) && (check & 1584 others->mask[mskidx])) 1585 return BadAccess; 1586 } 1587 } 1588 for (others = wOtherInputMasks(pWin)->inputClients; others; 1589 others = others->next) { 1590 if (SameClient(others, client)) { 1591 check = others->mask[mskidx]; 1592 others->mask[mskidx] = mask; 1593 if (mask == 0) { 1594 for (i = 0; i < EMASKSIZE; i++) 1595 if (i != mskidx && others->mask[i] != 0) 1596 break; 1597 if (i == EMASKSIZE) { 1598 RecalculateDeviceDeliverableEvents(pWin); 1599 if (ShouldFreeInputMasks(pWin, FALSE)) 1600 FreeResource(others->resource, RT_NONE); 1601 return Success; 1602 } 1603 } 1604 goto maskSet; 1605 } 1606 } 1607 } 1608 check = 0; 1609 if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success) 1610 return ret; 1611 maskSet: 1612 if (dev->valuator) 1613 if ((dev->valuator->motionHintWindow == pWin) && 1614 (mask & DevicePointerMotionHintMask) && 1615 !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab) 1616 dev->valuator->motionHintWindow = NullWindow; 1617 RecalculateDeviceDeliverableEvents(pWin); 1618 return Success; 1619} 1620 1621int 1622AddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx) 1623{ 1624 InputClientsPtr others; 1625 1626 if (!pWin->optional && !MakeWindowOptional(pWin)) 1627 return BadAlloc; 1628 others = calloc(1, sizeof(InputClients)); 1629 if (!others) 1630 return BadAlloc; 1631 if (!pWin->optional->inputMasks && !MakeInputMasks(pWin)) 1632 goto bail; 1633 others->mask[mskidx] = mask; 1634 others->resource = FakeClientID(client->index); 1635 others->next = pWin->optional->inputMasks->inputClients; 1636 pWin->optional->inputMasks->inputClients = others; 1637 if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin)) 1638 goto bail; 1639 return Success; 1640 1641bail: 1642 free(others); 1643 return BadAlloc; 1644} 1645 1646static Bool 1647MakeInputMasks(WindowPtr pWin) 1648{ 1649 struct _OtherInputMasks *imasks; 1650 1651 imasks = calloc(1, sizeof(struct _OtherInputMasks)); 1652 if (!imasks) 1653 return FALSE; 1654 pWin->optional->inputMasks = imasks; 1655 return TRUE; 1656} 1657 1658void 1659RecalculateDeviceDeliverableEvents(WindowPtr pWin) 1660{ 1661 InputClientsPtr others; 1662 struct _OtherInputMasks *inputMasks; /* default: NULL */ 1663 WindowPtr pChild, tmp; 1664 int i, j; 1665 1666 pChild = pWin; 1667 while (1) { 1668 if ((inputMasks = wOtherInputMasks(pChild)) != 0) { 1669 for (i = 0; i < EMASKSIZE; i++) 1670 memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i])); 1671 for (others = inputMasks->inputClients; others; 1672 others = others->next) { 1673 for (i = 0; i < EMASKSIZE; i++) 1674 inputMasks->inputEvents[i] |= others->mask[i]; 1675 for (i = 0; i < EMASKSIZE; i++) 1676 for (j = 0; j < XI2MASKSIZE; j++) 1677 inputMasks->xi2mask[i][j] |= others->xi2mask[i][j]; 1678 } 1679 for (i = 0; i < EMASKSIZE; i++) 1680 inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i]; 1681 for (tmp = pChild->parent; tmp; tmp = tmp->parent) 1682 if (wOtherInputMasks(tmp)) 1683 for (i = 0; i < EMASKSIZE; i++) 1684 inputMasks->deliverableEvents[i] |= 1685 (wOtherInputMasks(tmp)->deliverableEvents[i] 1686 & ~inputMasks-> 1687 dontPropagateMask[i] & PropagateMask[i]); 1688 } 1689 if (pChild->firstChild) { 1690 pChild = pChild->firstChild; 1691 continue; 1692 } 1693 while (!pChild->nextSib && (pChild != pWin)) 1694 pChild = pChild->parent; 1695 if (pChild == pWin) 1696 break; 1697 pChild = pChild->nextSib; 1698 } 1699} 1700 1701int 1702InputClientGone(WindowPtr pWin, XID id) 1703{ 1704 InputClientsPtr other, prev; 1705 1706 if (!wOtherInputMasks(pWin)) 1707 return Success; 1708 prev = 0; 1709 for (other = wOtherInputMasks(pWin)->inputClients; other; 1710 other = other->next) { 1711 if (other->resource == id) { 1712 if (prev) { 1713 prev->next = other->next; 1714 free(other); 1715 } else if (!(other->next)) { 1716 if (ShouldFreeInputMasks(pWin, TRUE)) { 1717 wOtherInputMasks(pWin)->inputClients = other->next; 1718 free(wOtherInputMasks(pWin)); 1719 pWin->optional->inputMasks = (OtherInputMasks *) NULL; 1720 CheckWindowOptionalNeed(pWin); 1721 free(other); 1722 } else { 1723 other->resource = FakeClientID(0); 1724 if (!AddResource(other->resource, RT_INPUTCLIENT, 1725 (pointer) pWin)) 1726 return BadAlloc; 1727 } 1728 } else { 1729 wOtherInputMasks(pWin)->inputClients = other->next; 1730 free(other); 1731 } 1732 RecalculateDeviceDeliverableEvents(pWin); 1733 return Success; 1734 } 1735 prev = other; 1736 } 1737 FatalError("client not on device event list"); 1738} 1739 1740int 1741SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, 1742 xEvent * ev, Mask mask, int count) 1743{ 1744 WindowPtr pWin; 1745 WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ 1746 WindowPtr spriteWin = GetSpriteWindow(d); 1747 1748 if (dest == PointerWindow) 1749 pWin = spriteWin; 1750 else if (dest == InputFocus) { 1751 WindowPtr inputFocus; 1752 1753 if (!d->focus) 1754 inputFocus = spriteWin; 1755 else 1756 inputFocus = d->focus->win; 1757 1758 if (inputFocus == FollowKeyboardWin) 1759 inputFocus = inputInfo.keyboard->focus->win; 1760 1761 if (inputFocus == NoneWin) 1762 return Success; 1763 1764 /* If the input focus is PointerRootWin, send the event to where 1765 * the pointer is if possible, then perhaps propogate up to root. */ 1766 if (inputFocus == PointerRootWin) 1767 inputFocus = GetCurrentRootWindow(d); 1768 1769 if (IsParent(inputFocus, spriteWin)) { 1770 effectiveFocus = inputFocus; 1771 pWin = spriteWin; 1772 } else 1773 effectiveFocus = pWin = inputFocus; 1774 } else 1775 dixLookupWindow(&pWin, dest, client, DixSendAccess); 1776 if (!pWin) 1777 return BadWindow; 1778 if ((propagate != xFalse) && (propagate != xTrue)) { 1779 client->errorValue = propagate; 1780 return BadValue; 1781 } 1782 ev->u.u.type |= 0x80; 1783 if (propagate) { 1784 for (; pWin; pWin = pWin->parent) { 1785 if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab)) 1786 return Success; 1787 if (pWin == effectiveFocus) 1788 return Success; 1789 if (wOtherInputMasks(pWin)) 1790 mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id]; 1791 if (!mask) 1792 break; 1793 } 1794 } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count)) 1795 DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab); 1796 return Success; 1797} 1798 1799int 1800SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map) 1801{ 1802 int i; 1803 ButtonClassPtr b = dev->button; 1804 1805 if (b == NULL) 1806 return BadMatch; 1807 1808 if (nElts != b->numButtons) { 1809 client->errorValue = nElts; 1810 return BadValue; 1811 } 1812 if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue)) 1813 return BadValue; 1814 for (i = 0; i < nElts; i++) 1815 if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1)) 1816 return MappingBusy; 1817 for (i = 0; i < nElts; i++) 1818 b->map[i + 1] = map[i]; 1819 return Success; 1820} 1821 1822int 1823ChangeKeyMapping(ClientPtr client, 1824 DeviceIntPtr dev, 1825 unsigned len, 1826 int type, 1827 KeyCode firstKeyCode, 1828 CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map) 1829{ 1830 KeySymsRec keysyms; 1831 KeyClassPtr k = dev->key; 1832 1833 if (k == NULL) 1834 return BadMatch; 1835 1836 if (len != (keyCodes * keySymsPerKeyCode)) 1837 return BadLength; 1838 1839 if ((firstKeyCode < k->xkbInfo->desc->min_key_code) || 1840 (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) { 1841 client->errorValue = firstKeyCode; 1842 return BadValue; 1843 } 1844 if (keySymsPerKeyCode == 0) { 1845 client->errorValue = 0; 1846 return BadValue; 1847 } 1848 keysyms.minKeyCode = firstKeyCode; 1849 keysyms.maxKeyCode = firstKeyCode + keyCodes - 1; 1850 keysyms.mapWidth = keySymsPerKeyCode; 1851 keysyms.map = map; 1852 1853 XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL, 1854 serverClient); 1855 1856 return Success; 1857} 1858 1859static void 1860DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) 1861{ 1862 WindowPtr parent; 1863 1864 /* Deactivate any grabs performed on this window, before making 1865 * any input focus changes. 1866 * Deactivating a device grab should cause focus events. */ 1867 1868 if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin)) 1869 (*dev->deviceGrab.DeactivateGrab) (dev); 1870 1871 /* If the focus window is a root window (ie. has no parent) 1872 * then don't delete the focus from it. */ 1873 1874 if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) { 1875 int focusEventMode = NotifyNormal; 1876 1877 /* If a grab is in progress, then alter the mode of focus events. */ 1878 1879 if (dev->deviceGrab.grab) 1880 focusEventMode = NotifyWhileGrabbed; 1881 1882 switch (dev->focus->revert) { 1883 case RevertToNone: 1884 if (!ActivateFocusInGrab(dev, pWin, NoneWin)) 1885 DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 1886 dev->focus->win = NoneWin; 1887 dev->focus->traceGood = 0; 1888 break; 1889 case RevertToParent: 1890 parent = pWin; 1891 do { 1892 parent = parent->parent; 1893 dev->focus->traceGood--; 1894 } 1895 while (!parent->realized); 1896 if (!ActivateFocusInGrab(dev, pWin, parent)) 1897 DoFocusEvents(dev, pWin, parent, focusEventMode); 1898 dev->focus->win = parent; 1899 dev->focus->revert = RevertToNone; 1900 break; 1901 case RevertToPointerRoot: 1902 if (!ActivateFocusInGrab(dev, pWin, PointerRootWin)) 1903 DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); 1904 dev->focus->win = PointerRootWin; 1905 dev->focus->traceGood = 0; 1906 break; 1907 case RevertToFollowKeyboard: 1908 { 1909 DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD); 1910 if (!kbd || (kbd == dev && kbd != inputInfo.keyboard)) 1911 kbd = inputInfo.keyboard; 1912 if (kbd->focus->win) { 1913 if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win)) 1914 DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode); 1915 dev->focus->win = FollowKeyboardWin; 1916 dev->focus->traceGood = 0; 1917 } else { 1918 if (!ActivateFocusInGrab(dev, pWin, NoneWin)) 1919 DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 1920 dev->focus->win = NoneWin; 1921 dev->focus->traceGood = 0; 1922 } 1923 } 1924 break; 1925 } 1926 } 1927 1928 if (dev->valuator) 1929 if (dev->valuator->motionHintWindow == pWin) 1930 dev->valuator->motionHintWindow = NullWindow; 1931} 1932 1933void 1934DeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources) 1935{ 1936 int i; 1937 DeviceIntPtr dev; 1938 InputClientsPtr ic; 1939 struct _OtherInputMasks *inputMasks; 1940 1941 for (dev = inputInfo.devices; dev; dev = dev->next) { 1942 DeleteDeviceFromAnyExtEvents(pWin, dev); 1943 } 1944 1945 for (dev = inputInfo.off_devices; dev; dev = dev->next) 1946 DeleteDeviceFromAnyExtEvents(pWin, dev); 1947 1948 if (freeResources) 1949 while ((inputMasks = wOtherInputMasks(pWin)) != 0) { 1950 ic = inputMasks->inputClients; 1951 for (i = 0; i < EMASKSIZE; i++) 1952 inputMasks->dontPropagateMask[i] = 0; 1953 FreeResource(ic->resource, RT_NONE); 1954 } 1955} 1956 1957int 1958MaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask) 1959{ 1960 DeviceIntPtr dev; 1961 1962 dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient, 1963 DixReadAccess); 1964 if (!dev) 1965 return 0; 1966 1967 if (pEvents->type == DeviceMotionNotify) { 1968 if (mask & DevicePointerMotionHintMask) { 1969 if (WID(dev->valuator->motionHintWindow) == pEvents->event) { 1970 return 1; /* don't send, but pretend we did */ 1971 } 1972 pEvents->detail = NotifyHint; 1973 } else { 1974 pEvents->detail = NotifyNormal; 1975 } 1976 } 1977 return 0; 1978} 1979 1980void 1981CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, 1982 deviceKeyButtonPointer * xE, GrabPtr grab, 1983 ClientPtr client, Mask deliveryMask) 1984{ 1985 DeviceIntPtr dev; 1986 1987 dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient, 1988 DixGrabAccess); 1989 if (!dev) 1990 return; 1991 1992 if (type == DeviceMotionNotify) 1993 dev->valuator->motionHintWindow = pWin; 1994 else if ((type == DeviceButtonPress) && (!grab) && 1995 (deliveryMask & DeviceButtonGrabMask)) { 1996 GrabRec tempGrab; 1997 1998 tempGrab.device = dev; 1999 tempGrab.resource = client->clientAsMask; 2000 tempGrab.window = pWin; 2001 tempGrab.ownerEvents = 2002 (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE; 2003 tempGrab.eventMask = deliveryMask; 2004 tempGrab.keyboardMode = GrabModeAsync; 2005 tempGrab.pointerMode = GrabModeAsync; 2006 tempGrab.confineTo = NullWindow; 2007 tempGrab.cursor = NullCursor; 2008 tempGrab.next = NULL; 2009 (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE); 2010 } 2011} 2012 2013static Mask 2014DeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client) 2015{ 2016 InputClientsPtr other; 2017 2018 if (!wOtherInputMasks(pWin)) 2019 return 0; 2020 for (other = wOtherInputMasks(pWin)->inputClients; other; 2021 other = other->next) { 2022 if (SameClient(other, client)) 2023 return other->mask[dev->id]; 2024 } 2025 return 0; 2026} 2027 2028void 2029MaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client) 2030{ 2031 WindowPtr pWin; 2032 GrabPtr grab = dev->deviceGrab.grab; 2033 2034 pWin = dev->valuator->motionHintWindow; 2035 2036 if ((grab && SameClient(grab, client) && 2037 ((grab->eventMask & DevicePointerMotionHintMask) || 2038 (grab->ownerEvents && 2039 (DeviceEventMaskForClient(dev, pWin, client) & 2040 DevicePointerMotionHintMask)))) || 2041 (!grab && 2042 (DeviceEventMaskForClient(dev, pWin, client) & 2043 DevicePointerMotionHintMask))) 2044 dev->valuator->motionHintWindow = NullWindow; 2045} 2046 2047int 2048DeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, 2049 int maskndx) 2050{ 2051 struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 2052 2053 if (mask & ~PropagateMask[maskndx]) { 2054 client->errorValue = mask; 2055 return BadValue; 2056 } 2057 2058 if (mask == 0) { 2059 if (inputMasks) 2060 inputMasks->dontPropagateMask[maskndx] = mask; 2061 } else { 2062 if (!inputMasks) 2063 AddExtensionClient(pWin, client, 0, 0); 2064 inputMasks = wOtherInputMasks(pWin); 2065 inputMasks->dontPropagateMask[maskndx] = mask; 2066 } 2067 RecalculateDeviceDeliverableEvents(pWin); 2068 if (ShouldFreeInputMasks(pWin, FALSE)) 2069 FreeResource(inputMasks->inputClients->resource, RT_NONE); 2070 return Success; 2071} 2072 2073Bool 2074ShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents) 2075{ 2076 int i; 2077 Mask allInputEventMasks = 0; 2078 struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 2079 2080 for (i = 0; i < EMASKSIZE; i++) 2081 allInputEventMasks |= inputMasks->dontPropagateMask[i]; 2082 if (!ignoreSelectedEvents) 2083 for (i = 0; i < EMASKSIZE; i++) 2084 allInputEventMasks |= inputMasks->inputEvents[i]; 2085 if (allInputEventMasks == 0) 2086 return TRUE; 2087 else 2088 return FALSE; 2089} 2090 2091/*********************************************************************** 2092 * 2093 * Walk through the window tree, finding all clients that want to know 2094 * about the Event. 2095 * 2096 */ 2097 2098static void 2099FindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask, 2100 xEvent * ev, int count) 2101{ 2102 WindowPtr p2; 2103 2104 while (p1) { 2105 p2 = p1->firstChild; 2106 DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab); 2107 FindInterestedChildren(dev, p2, mask, ev, count); 2108 p1 = p1->nextSib; 2109 } 2110} 2111 2112/*********************************************************************** 2113 * 2114 * Send an event to interested clients in all windows on all screens. 2115 * 2116 */ 2117 2118void 2119SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count) 2120{ 2121 int i; 2122 WindowPtr pWin, p1; 2123 2124 for (i = 0; i < screenInfo.numScreens; i++) { 2125 pWin = screenInfo.screens[i]->root; 2126 if (!pWin) 2127 continue; 2128 DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab); 2129 p1 = pWin->firstChild; 2130 FindInterestedChildren(dev, p1, mask, ev, count); 2131 } 2132} 2133 2134/** 2135 * Set the XI2 mask for the given client on the given window. 2136 * @param dev The device to set the mask for. 2137 * @param win The window to set the mask on. 2138 * @param client The client setting the mask. 2139 * @param len Number of bytes in mask. 2140 * @param mask Event mask in the form of (1 << eventtype) 2141 */ 2142int 2143XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client, 2144 unsigned int len, unsigned char* mask) 2145{ 2146 OtherInputMasks *masks; 2147 InputClientsPtr others = NULL; 2148 2149 masks = wOtherInputMasks(win); 2150 if (masks) 2151 { 2152 for (others = wOtherInputMasks(win)->inputClients; others; 2153 others = others->next) { 2154 if (SameClient(others, client)) { 2155 memset(others->xi2mask[dev->id], 0, 2156 sizeof(others->xi2mask[dev->id])); 2157 break; 2158 } 2159 } 2160 } 2161 2162 len = min(len, sizeof(others->xi2mask[dev->id])); 2163 2164 if (len && !others) 2165 { 2166 if (AddExtensionClient(win, client, 0, 0) != Success) 2167 return BadAlloc; 2168 others= wOtherInputMasks(win)->inputClients; 2169 } 2170 2171 if (others) 2172 memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id])); 2173 2174 if (len) 2175 memcpy(others->xi2mask[dev->id], mask, len); 2176 2177 RecalculateDeviceDeliverableEvents(win); 2178 2179 return Success; 2180} 2181