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