devices.c (82602B)
1 /************************************************************ 2 3 Copyright 1987, 1998 The Open Group 4 5 Permission to use, copy, modify, distribute, and sell this software and its 6 documentation for any purpose is hereby granted without fee, provided that 7 the above copyright notice appear in all copies and that both that 8 copyright notice and this permission notice appear in supporting 9 documentation. 10 11 The above copyright notice and this permission notice shall be included in 12 all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21 Except as contained in this notice, the name of The Open Group shall not be 22 used in advertising or otherwise to promote the sale, use or other dealings 23 in this Software without prior written authorization from The Open Group. 24 25 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 26 27 All Rights Reserved 28 29 Permission to use, copy, modify, and distribute this software and its 30 documentation for any purpose and without fee is hereby granted, 31 provided that the above copyright notice appear in all copies and that 32 both that copyright notice and this permission notice appear in 33 supporting documentation, and that the name of Digital not be 34 used in advertising or publicity pertaining to distribution of the 35 software without specific, written prior permission. 36 37 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 38 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 39 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 40 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 41 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 42 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 43 SOFTWARE. 44 45 ********************************************************/ 46 47 #ifdef HAVE_DIX_CONFIG_H 48 #include <dix-config.h> 49 #endif 50 51 #include <X11/X.h> 52 #include "misc.h" 53 #include "resource.h" 54 #include <X11/Xproto.h> 55 #include <X11/Xatom.h> 56 #include "windowstr.h" 57 #include "inputstr.h" 58 #include "scrnintstr.h" 59 #include "cursorstr.h" 60 #include "dixstruct.h" 61 #include "ptrveloc.h" 62 #include "xkbsrv.h" 63 #include "privates.h" 64 #include "xace.h" 65 #include "mi.h" 66 67 #include "dispatch.h" 68 #include "swaprep.h" 69 #include "dixevents.h" 70 #include "mipointer.h" 71 #include "eventstr.h" 72 #include "dixgrabs.h" 73 74 #include <X11/extensions/XI.h> 75 #include <X11/extensions/XI2.h> 76 #include <X11/extensions/XIproto.h> 77 #include <math.h> 78 #include <pixman.h> 79 #include "exglobals.h" 80 #include "exevents.h" 81 #include "xiquerydevice.h" /* for SizeDeviceClasses */ 82 #include "xiproperty.h" 83 #include "enterleave.h" /* for EnterWindow() */ 84 #include "xserver-properties.h" 85 #include "xichangehierarchy.h" /* For XISendDeviceHierarchyEvent */ 86 #include "syncsrv.h" 87 88 /** @file 89 * This file handles input device-related stuff. 90 */ 91 92 static void RecalculateMasterButtons(DeviceIntPtr slave); 93 94 static void 95 DeviceSetTransform(DeviceIntPtr dev, float *transform_data) 96 { 97 struct pixman_f_transform scale; 98 struct pixman_f_transform transform; 99 double sx, sy; 100 int x, y; 101 102 /** 103 * calculate combined transformation matrix: 104 * 105 * M = InvScale * Transform * Scale 106 * 107 * So we can later transform points using M * p 108 * 109 * Where: 110 * Scale scales coordinates into 0..1 range 111 * Transform is the user supplied (affine) transform 112 * InvScale scales coordinates back up into their native range 113 */ 114 sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value + 1; 115 sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value + 1; 116 117 /* invscale */ 118 pixman_f_transform_init_scale(&scale, sx, sy); 119 scale.m[0][2] = dev->valuator->axes[0].min_value; 120 scale.m[1][2] = dev->valuator->axes[1].min_value; 121 122 /* transform */ 123 for (y = 0; y < 3; y++) 124 for (x = 0; x < 3; x++) 125 transform.m[y][x] = *transform_data++; 126 127 pixman_f_transform_multiply(&dev->scale_and_transform, &scale, &transform); 128 129 /* scale */ 130 pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy); 131 scale.m[0][2] = -dev->valuator->axes[0].min_value / sx; 132 scale.m[1][2] = -dev->valuator->axes[1].min_value / sy; 133 134 pixman_f_transform_multiply(&dev->scale_and_transform, &dev->scale_and_transform, &scale); 135 136 /* remove translation component for relative movements */ 137 dev->relative_transform = transform; 138 dev->relative_transform.m[0][2] = 0; 139 dev->relative_transform.m[1][2] = 0; 140 } 141 142 /** 143 * DIX property handler. 144 */ 145 static int 146 DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, 147 BOOL checkonly) 148 { 149 if (property == XIGetKnownProperty(XI_PROP_ENABLED)) { 150 if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1) 151 return BadValue; 152 153 /* Don't allow disabling of VCP/VCK or XTest devices */ 154 if ((dev == inputInfo.pointer || 155 dev == inputInfo.keyboard || 156 IsXTestDevice(dev, NULL)) 157 &&!(*(CARD8 *) prop->data)) 158 return BadAccess; 159 160 if (!checkonly) { 161 if ((*((CARD8 *) prop->data)) && !dev->enabled) 162 EnableDevice(dev, TRUE); 163 else if (!(*((CARD8 *) prop->data)) && dev->enabled) 164 DisableDevice(dev, TRUE); 165 } 166 } 167 else if (property == XIGetKnownProperty(XI_PROP_TRANSFORM)) { 168 float *f = (float *) prop->data; 169 int i; 170 171 if (prop->format != 32 || prop->size != 9 || 172 prop->type != XIGetKnownProperty(XATOM_FLOAT)) 173 return BadValue; 174 175 for (i = 0; i < 9; i++) 176 if (!isfinite(f[i])) 177 return BadValue; 178 179 if (!dev->valuator) 180 return BadMatch; 181 182 if (!checkonly) 183 DeviceSetTransform(dev, f); 184 } 185 186 return Success; 187 } 188 189 /* Pair the keyboard to the pointer device. Keyboard events will follow the 190 * pointer sprite. Only applicable for master devices. 191 */ 192 static int 193 PairDevices(DeviceIntPtr ptr, DeviceIntPtr kbd) 194 { 195 if (!ptr) 196 return BadDevice; 197 198 /* Don't allow pairing for slave devices */ 199 if (!IsMaster(ptr) || !IsMaster(kbd)) 200 return BadDevice; 201 202 if (ptr->spriteInfo->paired) 203 return BadDevice; 204 205 if (kbd->spriteInfo->spriteOwner) { 206 free(kbd->spriteInfo->sprite); 207 kbd->spriteInfo->sprite = NULL; 208 kbd->spriteInfo->spriteOwner = FALSE; 209 } 210 211 kbd->spriteInfo->sprite = ptr->spriteInfo->sprite; 212 kbd->spriteInfo->paired = ptr; 213 ptr->spriteInfo->paired = kbd; 214 return Success; 215 } 216 217 /** 218 * Find and return the next unpaired MD pointer device. 219 */ 220 static DeviceIntPtr 221 NextFreePointerDevice(void) 222 { 223 DeviceIntPtr dev; 224 225 for (dev = inputInfo.devices; dev; dev = dev->next) 226 if (IsMaster(dev) && 227 dev->spriteInfo->spriteOwner && !dev->spriteInfo->paired) 228 return dev; 229 return NULL; 230 } 231 232 /** 233 * Create a new input device and init it to sane values. The device is added 234 * to the server's off_devices list. 235 * 236 * @param deviceProc Callback for device control function (switch dev on/off). 237 * @return The newly created device. 238 */ 239 DeviceIntPtr 240 AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) 241 { 242 DeviceIntPtr dev, *prev; /* not a typo */ 243 DeviceIntPtr devtmp; 244 int devid; 245 char devind[MAXDEVICES]; 246 BOOL enabled; 247 float transform[9]; 248 249 /* Find next available id, 0 and 1 are reserved */ 250 memset(devind, 0, sizeof(char) * MAXDEVICES); 251 for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next) 252 devind[devtmp->id]++; 253 for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next) 254 devind[devtmp->id]++; 255 for (devid = 2; devid < MAXDEVICES && devind[devid]; devid++); 256 257 if (devid >= MAXDEVICES) 258 return (DeviceIntPtr) NULL; 259 dev = calloc(1, 260 sizeof(DeviceIntRec) + 261 sizeof(SpriteInfoRec)); 262 if (!dev) 263 return (DeviceIntPtr) NULL; 264 265 if (!dixAllocatePrivates(&dev->devPrivates, PRIVATE_DEVICE)) { 266 free(dev); 267 return NULL; 268 } 269 270 dev->last.scroll = NULL; 271 dev->last.touches = NULL; 272 dev->id = devid; 273 dev->public.processInputProc = ProcessOtherEvent; 274 dev->public.realInputProc = ProcessOtherEvent; 275 dev->public.enqueueInputProc = EnqueueEvent; 276 dev->deviceProc = deviceProc; 277 dev->startup = autoStart; 278 279 /* device grab defaults */ 280 UpdateCurrentTimeIf(); 281 dev->deviceGrab.grabTime = currentTime; 282 dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab; 283 dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; 284 dev->deviceGrab.sync.event = calloc(1, sizeof(InternalEvent)); 285 286 XkbSetExtension(dev, ProcessKeyboardEvent); 287 288 dev->coreEvents = TRUE; 289 290 /* sprite defaults */ 291 dev->spriteInfo = (SpriteInfoPtr) &dev[1]; 292 293 /* security creation/labeling check 294 */ 295 if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) { 296 dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE); 297 free(dev); 298 return NULL; 299 } 300 301 inputInfo.numDevices++; 302 303 for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next); 304 *prev = dev; 305 dev->next = NULL; 306 307 enabled = FALSE; 308 XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED), 309 XA_INTEGER, 8, PropModeReplace, 1, &enabled, FALSE); 310 XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_ENABLED), 311 FALSE); 312 313 /* unity matrix */ 314 memset(transform, 0, sizeof(transform)); 315 transform[0] = transform[4] = transform[8] = 1.0f; 316 dev->relative_transform.m[0][0] = 1.0; 317 dev->relative_transform.m[1][1] = 1.0; 318 dev->relative_transform.m[2][2] = 1.0; 319 dev->scale_and_transform = dev->relative_transform; 320 321 XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM), 322 XIGetKnownProperty(XATOM_FLOAT), 32, 323 PropModeReplace, 9, transform, FALSE); 324 XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_TRANSFORM), 325 FALSE); 326 327 XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL, NULL); 328 329 return dev; 330 } 331 332 void 333 SendDevicePresenceEvent(int deviceid, int type) 334 { 335 DeviceIntRec dummyDev = { .id = XIAllDevices }; 336 devicePresenceNotify ev; 337 338 UpdateCurrentTimeIf(); 339 ev.type = DevicePresenceNotify; 340 ev.time = currentTime.milliseconds; 341 ev.devchange = type; 342 ev.deviceid = deviceid; 343 344 SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, 345 (xEvent *) &ev, 1); 346 } 347 348 /** 349 * Enable the device through the driver, add the device to the device list. 350 * Switch device ON through the driver and push it onto the global device 351 * list. Initialize the DIX sprite or pair the device. All clients are 352 * notified about the device being enabled. 353 * 354 * A master pointer device needs to be enabled before a master keyboard 355 * device. 356 * 357 * @param The device to be enabled. 358 * @param sendevent True if an XI2 event should be sent. 359 * @return TRUE on success or FALSE otherwise. 360 */ 361 Bool 362 EnableDevice(DeviceIntPtr dev, BOOL sendevent) 363 { 364 DeviceIntPtr *prev; 365 int ret; 366 DeviceIntPtr other; 367 BOOL enabled; 368 int flags[MAXDEVICES] = { 0 }; 369 370 for (prev = &inputInfo.off_devices; 371 *prev && (*prev != dev); prev = &(*prev)->next); 372 373 if (!dev->spriteInfo->sprite) { 374 if (IsMaster(dev)) { 375 /* Sprites appear on first root window, so we can hardcode it */ 376 if (dev->spriteInfo->spriteOwner) { 377 InitializeSprite(dev, screenInfo.screens[0]->root); 378 /* mode doesn't matter */ 379 EnterWindow(dev, screenInfo.screens[0]->root, NotifyAncestor); 380 } 381 else { 382 other = NextFreePointerDevice(); 383 BUG_RETURN_VAL_MSG(other == NULL, FALSE, 384 "[dix] cannot find pointer to pair with.\n"); 385 PairDevices(other, dev); 386 } 387 } 388 else { 389 if (dev->coreEvents) 390 other = (IsPointerDevice(dev)) ? inputInfo.pointer: 391 inputInfo.keyboard; 392 else 393 other = NULL; /* auto-float non-core devices */ 394 AttachDevice(NULL, dev, other); 395 } 396 } 397 398 input_lock(); 399 if ((*prev != dev) || !dev->inited || 400 ((ret = (*dev->deviceProc) (dev, DEVICE_ON)) != Success)) { 401 ErrorF("[dix] couldn't enable device %d\n", dev->id); 402 input_unlock(); 403 return FALSE; 404 } 405 dev->enabled = TRUE; 406 *prev = dev->next; 407 408 for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next); 409 *prev = dev; 410 dev->next = NULL; 411 input_unlock(); 412 413 enabled = TRUE; 414 XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED), 415 XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE); 416 417 SendDevicePresenceEvent(dev->id, DeviceEnabled); 418 if (sendevent) { 419 flags[dev->id] |= XIDeviceEnabled; 420 XISendDeviceHierarchyEvent(flags); 421 } 422 423 if (!IsMaster(dev) && !IsFloating(dev)) 424 XkbPushLockedStateToSlaves(GetMaster(dev, MASTER_KEYBOARD), 0, 0); 425 RecalculateMasterButtons(dev); 426 427 /* initialise an idle timer for this device*/ 428 dev->idle_counter = SyncInitDeviceIdleTime(dev); 429 430 return TRUE; 431 } 432 433 434 /** 435 * Switch a device off through the driver and push it onto the off_devices 436 * list. A device will not send events while disabled. All clients are 437 * notified about the device being disabled. 438 * 439 * Master keyboard devices have to be disabled before master pointer devices 440 * otherwise things turn bad. 441 * 442 * @param sendevent True if an XI2 event should be sent. 443 * @return TRUE on success or FALSE otherwise. 444 */ 445 Bool 446 DisableDevice(DeviceIntPtr dev, BOOL sendevent) 447 { 448 DeviceIntPtr *prev, other; 449 BOOL enabled; 450 int flags[MAXDEVICES] = { 0 }; 451 452 if (!dev->enabled) 453 return TRUE; 454 455 for (prev = &inputInfo.devices; 456 *prev && (*prev != dev); prev = &(*prev)->next); 457 if (*prev != dev) 458 return FALSE; 459 460 TouchEndPhysicallyActiveTouches(dev); 461 GestureEndActiveGestures(dev); 462 ReleaseButtonsAndKeys(dev); 463 SyncRemoveDeviceIdleTime(dev->idle_counter); 464 dev->idle_counter = NULL; 465 466 /* float attached devices */ 467 if (IsMaster(dev)) { 468 for (other = inputInfo.devices; other; other = other->next) { 469 if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev) { 470 AttachDevice(NULL, other, NULL); 471 flags[other->id] |= XISlaveDetached; 472 } 473 } 474 } 475 else { 476 for (other = inputInfo.devices; other; other = other->next) { 477 if (IsMaster(other) && other->lastSlave == dev) 478 other->lastSlave = NULL; 479 } 480 } 481 482 if (IsMaster(dev) && dev->spriteInfo->sprite) { 483 for (other = inputInfo.devices; other; other = other->next) 484 if (other->spriteInfo->paired == dev && !other->spriteInfo->spriteOwner) 485 DisableDevice(other, sendevent); 486 } 487 488 if (dev->spriteInfo->paired) 489 dev->spriteInfo->paired = NULL; 490 491 input_lock(); 492 (void) (*dev->deviceProc) (dev, DEVICE_OFF); 493 dev->enabled = FALSE; 494 495 /* now that the device is disabled, we can reset the event reader's 496 * last.slave */ 497 for (other = inputInfo.devices; other; other = other->next) { 498 if (other->last.slave == dev) 499 other->last.slave = NULL; 500 } 501 input_unlock(); 502 503 FreeSprite(dev); 504 505 LeaveWindow(dev); 506 SetFocusOut(dev); 507 508 *prev = dev->next; 509 dev->next = inputInfo.off_devices; 510 inputInfo.off_devices = dev; 511 512 enabled = FALSE; 513 XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED), 514 XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE); 515 516 SendDevicePresenceEvent(dev->id, DeviceDisabled); 517 if (sendevent) { 518 flags[dev->id] = XIDeviceDisabled; 519 XISendDeviceHierarchyEvent(flags); 520 } 521 522 RecalculateMasterButtons(dev); 523 524 return TRUE; 525 } 526 527 void 528 DisableAllDevices(void) 529 { 530 DeviceIntPtr dev, tmp; 531 532 /* Disable slave devices first, excluding XTest devices */ 533 nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { 534 if (!IsXTestDevice(dev, NULL) && !IsMaster(dev)) 535 DisableDevice(dev, FALSE); 536 } 537 /* Disable XTest devices */ 538 nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { 539 if (!IsMaster(dev)) 540 DisableDevice(dev, FALSE); 541 } 542 /* master keyboards need to be disabled first */ 543 nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { 544 if (dev->enabled && IsMaster(dev) && IsKeyboardDevice(dev)) 545 DisableDevice(dev, FALSE); 546 } 547 nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) { 548 if (dev->enabled) 549 DisableDevice(dev, FALSE); 550 } 551 } 552 553 /** 554 * Initialise a new device through the driver and tell all clients about the 555 * new device. 556 * 557 * Must be called before EnableDevice. 558 * The device will NOT send events until it is enabled! 559 * 560 * @param sendevent True if an XI2 event should be sent. 561 * @return Success or an error code on failure. 562 */ 563 int 564 ActivateDevice(DeviceIntPtr dev, BOOL sendevent) 565 { 566 int ret = Success; 567 ScreenPtr pScreen = screenInfo.screens[0]; 568 569 if (!dev || !dev->deviceProc) 570 return BadImplementation; 571 572 input_lock(); 573 ret = (*dev->deviceProc) (dev, DEVICE_INIT); 574 input_unlock(); 575 dev->inited = (ret == Success); 576 if (!dev->inited) 577 return ret; 578 579 /* Initialize memory for sprites. */ 580 if (IsMaster(dev) && dev->spriteInfo->spriteOwner) 581 if (!pScreen->DeviceCursorInitialize(dev, pScreen)) 582 ret = BadAlloc; 583 584 SendDevicePresenceEvent(dev->id, DeviceAdded); 585 if (sendevent) { 586 int flags[MAXDEVICES] = { 0 }; 587 flags[dev->id] = XISlaveAdded; 588 XISendDeviceHierarchyEvent(flags); 589 } 590 return ret; 591 } 592 593 /** 594 * Ring the bell. 595 * The actual task of ringing the bell is the job of the DDX. 596 */ 597 static void 598 CoreKeyboardBell(int volume, DeviceIntPtr pDev, void *arg, int something) 599 { 600 KeybdCtrl *ctrl = arg; 601 602 DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration); 603 } 604 605 static void 606 CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl * ctrl) 607 { 608 return; 609 } 610 611 /** 612 * Device control function for the Virtual Core Keyboard. 613 */ 614 int 615 CoreKeyboardProc(DeviceIntPtr pDev, int what) 616 { 617 618 switch (what) { 619 case DEVICE_INIT: 620 if (!InitKeyboardDeviceStruct(pDev, NULL, CoreKeyboardBell, 621 CoreKeyboardCtl)) { 622 ErrorF("Keyboard initialization failed. This could be a missing " 623 "or incorrect setup of xkeyboard-config.\n"); 624 return BadValue; 625 } 626 return Success; 627 628 case DEVICE_ON: 629 case DEVICE_OFF: 630 return Success; 631 632 case DEVICE_CLOSE: 633 return Success; 634 } 635 636 return BadMatch; 637 } 638 639 /** 640 * Device control function for the Virtual Core Pointer. 641 */ 642 int 643 CorePointerProc(DeviceIntPtr pDev, int what) 644 { 645 #define NBUTTONS 10 646 #define NAXES 2 647 BYTE map[NBUTTONS + 1]; 648 int i = 0; 649 Atom btn_labels[NBUTTONS] = { 0 }; 650 Atom axes_labels[NAXES] = { 0 }; 651 ScreenPtr scr = screenInfo.screens[0]; 652 653 switch (what) { 654 case DEVICE_INIT: 655 for (i = 1; i <= NBUTTONS; i++) 656 map[i] = i; 657 658 btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); 659 btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); 660 btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); 661 btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); 662 btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); 663 btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); 664 btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); 665 /* don't know about the rest */ 666 667 axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); 668 axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); 669 670 if (!InitPointerDeviceStruct 671 ((DevicePtr) pDev, map, NBUTTONS, btn_labels, 672 (PtrCtrlProcPtr) NoopDDA, GetMotionHistorySize(), NAXES, 673 axes_labels)) { 674 ErrorF("Could not initialize device '%s'. Out of memory.\n", 675 pDev->name); 676 return BadAlloc; /* IPDS only fails on allocs */ 677 } 678 /* axisVal is per-screen, last.valuators is desktop-wide */ 679 pDev->valuator->axisVal[0] = scr->width / 2; 680 pDev->last.valuators[0] = pDev->valuator->axisVal[0] + scr->x; 681 pDev->valuator->axisVal[1] = scr->height / 2; 682 pDev->last.valuators[1] = pDev->valuator->axisVal[1] + scr->y; 683 break; 684 685 case DEVICE_CLOSE: 686 break; 687 688 default: 689 break; 690 } 691 692 return Success; 693 694 #undef NBUTTONS 695 #undef NAXES 696 } 697 698 /** 699 * Initialise the two core devices, VCP and VCK (see events.c). 700 * Both devices are not tied to physical devices, but guarantee that there is 701 * always a keyboard and a pointer present and keep the protocol semantics. 702 * 703 * Note that the server MUST have two core devices at all times, even if there 704 * is no physical device connected. 705 */ 706 void 707 InitCoreDevices(void) 708 { 709 int result; 710 711 result = AllocDevicePair(serverClient, "Virtual core", 712 &inputInfo.pointer, &inputInfo.keyboard, 713 CorePointerProc, CoreKeyboardProc, TRUE); 714 if (result != Success) { 715 FatalError("Failed to allocate virtual core devices: %d", result); 716 } 717 718 result = ActivateDevice(inputInfo.pointer, TRUE); 719 if (result != Success) { 720 FatalError("Failed to activate virtual core pointer: %d", result); 721 } 722 723 result = ActivateDevice(inputInfo.keyboard, TRUE); 724 if (result != Success) { 725 FatalError("Failed to activate virtual core keyboard: %d", result); 726 } 727 728 if (!EnableDevice(inputInfo.pointer, TRUE)) { 729 FatalError("Failed to enable virtual core pointer."); 730 } 731 732 if (!EnableDevice(inputInfo.keyboard, TRUE)) { 733 FatalError("Failed to enable virtual core keyboard."); 734 } 735 736 InitXTestDevices(); 737 } 738 739 /** 740 * Activate all switched-off devices and then enable all those devices. 741 * 742 * Will return an error if no core keyboard or core pointer is present. 743 * In theory this should never happen if you call InitCoreDevices() first. 744 * 745 * InitAndStartDevices needs to be called AFTER the windows are initialized. 746 * Devices will start sending events after InitAndStartDevices() has 747 * completed. 748 * 749 * @return Success or error code on failure. 750 */ 751 int 752 InitAndStartDevices(void) 753 { 754 DeviceIntPtr dev, next; 755 756 for (dev = inputInfo.off_devices; dev; dev = dev->next) { 757 DebugF("(dix) initialising device %d\n", dev->id); 758 if (!dev->inited) 759 ActivateDevice(dev, TRUE); 760 } 761 762 /* enable real devices */ 763 for (dev = inputInfo.off_devices; dev; dev = next) { 764 DebugF("(dix) enabling device %d\n", dev->id); 765 next = dev->next; 766 if (dev->inited && dev->startup) 767 EnableDevice(dev, TRUE); 768 } 769 770 return Success; 771 } 772 773 /** 774 * Free the given device class and reset the pointer to NULL. 775 */ 776 static void 777 FreeDeviceClass(int type, void **class) 778 { 779 if (!(*class)) 780 return; 781 782 switch (type) { 783 case KeyClass: 784 { 785 KeyClassPtr *k = (KeyClassPtr *) class; 786 787 if ((*k)->xkbInfo) { 788 XkbFreeInfo((*k)->xkbInfo); 789 (*k)->xkbInfo = NULL; 790 } 791 free((*k)); 792 break; 793 } 794 case ButtonClass: 795 { 796 ButtonClassPtr *b = (ButtonClassPtr *) class; 797 798 free((*b)->xkb_acts); 799 free((*b)); 800 break; 801 } 802 case ValuatorClass: 803 { 804 ValuatorClassPtr *v = (ValuatorClassPtr *) class; 805 806 free((*v)->motion); 807 free((*v)); 808 break; 809 } 810 case XITouchClass: 811 { 812 TouchClassPtr *t = (TouchClassPtr *) class; 813 int i; 814 815 for (i = 0; i < (*t)->num_touches; i++) { 816 free((*t)->touches[i].sprite.spriteTrace); 817 free((*t)->touches[i].listeners); 818 free((*t)->touches[i].valuators); 819 } 820 821 free((*t)->touches); 822 free((*t)); 823 break; 824 } 825 case FocusClass: 826 { 827 FocusClassPtr *f = (FocusClassPtr *) class; 828 829 free((*f)->trace); 830 free((*f)); 831 break; 832 } 833 case ProximityClass: 834 { 835 ProximityClassPtr *p = (ProximityClassPtr *) class; 836 837 free((*p)); 838 break; 839 } 840 } 841 *class = NULL; 842 } 843 844 static void 845 FreeFeedbackClass(int type, void **class) 846 { 847 if (!(*class)) 848 return; 849 850 switch (type) { 851 case KbdFeedbackClass: 852 { 853 KbdFeedbackPtr *kbdfeed = (KbdFeedbackPtr *) class; 854 KbdFeedbackPtr k, knext; 855 856 for (k = (*kbdfeed); k; k = knext) { 857 knext = k->next; 858 if (k->xkb_sli) 859 XkbFreeSrvLedInfo(k->xkb_sli); 860 free(k); 861 } 862 break; 863 } 864 case PtrFeedbackClass: 865 { 866 PtrFeedbackPtr *ptrfeed = (PtrFeedbackPtr *) class; 867 PtrFeedbackPtr p, pnext; 868 869 for (p = (*ptrfeed); p; p = pnext) { 870 pnext = p->next; 871 free(p); 872 } 873 break; 874 } 875 case IntegerFeedbackClass: 876 { 877 IntegerFeedbackPtr *intfeed = (IntegerFeedbackPtr *) class; 878 IntegerFeedbackPtr i, inext; 879 880 for (i = (*intfeed); i; i = inext) { 881 inext = i->next; 882 free(i); 883 } 884 break; 885 } 886 case StringFeedbackClass: 887 { 888 StringFeedbackPtr *stringfeed = (StringFeedbackPtr *) class; 889 StringFeedbackPtr s, snext; 890 891 for (s = (*stringfeed); s; s = snext) { 892 snext = s->next; 893 free(s->ctrl.symbols_supported); 894 free(s->ctrl.symbols_displayed); 895 free(s); 896 } 897 break; 898 } 899 case BellFeedbackClass: 900 { 901 BellFeedbackPtr *bell = (BellFeedbackPtr *) class; 902 BellFeedbackPtr b, bnext; 903 904 for (b = (*bell); b; b = bnext) { 905 bnext = b->next; 906 free(b); 907 } 908 break; 909 } 910 case LedFeedbackClass: 911 { 912 LedFeedbackPtr *leds = (LedFeedbackPtr *) class; 913 LedFeedbackPtr l, lnext; 914 915 for (l = (*leds); l; l = lnext) { 916 lnext = l->next; 917 if (l->xkb_sli) 918 XkbFreeSrvLedInfo(l->xkb_sli); 919 free(l); 920 } 921 break; 922 } 923 } 924 *class = NULL; 925 } 926 927 static void 928 FreeAllDeviceClasses(ClassesPtr classes) 929 { 930 if (!classes) 931 return; 932 933 FreeDeviceClass(KeyClass, (void *) &classes->key); 934 FreeDeviceClass(ValuatorClass, (void *) &classes->valuator); 935 FreeDeviceClass(XITouchClass, (void *) &classes->touch); 936 FreeDeviceClass(ButtonClass, (void *) &classes->button); 937 FreeDeviceClass(FocusClass, (void *) &classes->focus); 938 FreeDeviceClass(ProximityClass, (void *) &classes->proximity); 939 940 FreeFeedbackClass(KbdFeedbackClass, (void *) &classes->kbdfeed); 941 FreeFeedbackClass(PtrFeedbackClass, (void *) &classes->ptrfeed); 942 FreeFeedbackClass(IntegerFeedbackClass, (void *) &classes->intfeed); 943 FreeFeedbackClass(StringFeedbackClass, (void *) &classes->stringfeed); 944 FreeFeedbackClass(BellFeedbackClass, (void *) &classes->bell); 945 FreeFeedbackClass(LedFeedbackClass, (void *) &classes->leds); 946 947 } 948 949 /** 950 * Close down a device and free all resources. 951 * Once closed down, the driver will probably not expect you that you'll ever 952 * enable it again and free associated structs. If you want the device to just 953 * be disabled, DisableDevice(). 954 * Don't call this function directly, use RemoveDevice() instead. 955 * 956 * Called with input lock held. 957 */ 958 static void 959 CloseDevice(DeviceIntPtr dev) 960 { 961 ScreenPtr screen = screenInfo.screens[0]; 962 ClassesPtr classes; 963 int j; 964 965 if (!dev) 966 return; 967 968 XIDeleteAllDeviceProperties(dev); 969 970 if (dev->inited) 971 (void) (*dev->deviceProc) (dev, DEVICE_CLOSE); 972 973 FreeSprite(dev); 974 975 if (IsMaster(dev)) 976 screen->DeviceCursorCleanup(dev, screen); 977 978 /* free acceleration info */ 979 if (dev->valuator && dev->valuator->accelScheme.AccelCleanupProc) 980 dev->valuator->accelScheme.AccelCleanupProc(dev); 981 982 while (dev->xkb_interest) 983 XkbRemoveResourceClient((DevicePtr) dev, dev->xkb_interest->resource); 984 985 free(dev->name); 986 987 classes = (ClassesPtr) &dev->key; 988 FreeAllDeviceClasses(classes); 989 990 if (IsMaster(dev)) { 991 classes = dev->unused_classes; 992 FreeAllDeviceClasses(classes); 993 free(classes); 994 } 995 996 /* a client may have the device set as client pointer */ 997 for (j = 0; j < currentMaxClients; j++) { 998 if (clients[j] && clients[j]->clientPtr == dev) { 999 clients[j]->clientPtr = NULL; 1000 clients[j]->clientPtr = PickPointer(clients[j]); 1001 } 1002 } 1003 1004 if (dev->deviceGrab.grab) 1005 FreeGrab(dev->deviceGrab.grab); 1006 free(dev->deviceGrab.sync.event); 1007 free(dev->config_info); /* Allocated in xf86ActivateDevice. */ 1008 free(dev->last.scroll); 1009 for (j = 0; j < dev->last.num_touches; j++) 1010 free(dev->last.touches[j].valuators); 1011 free(dev->last.touches); 1012 dev->config_info = NULL; 1013 dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE); 1014 free(dev); 1015 } 1016 1017 /** 1018 * Shut down all devices of one list and free all resources. 1019 */ 1020 static 1021 void 1022 CloseDeviceList(DeviceIntPtr *listHead) 1023 { 1024 /* Used to mark devices that we tried to free */ 1025 Bool freedIds[MAXDEVICES]; 1026 DeviceIntPtr dev; 1027 int i; 1028 1029 if (listHead == NULL) 1030 return; 1031 1032 for (i = 0; i < MAXDEVICES; i++) 1033 freedIds[i] = FALSE; 1034 1035 dev = *listHead; 1036 while (dev != NULL) { 1037 freedIds[dev->id] = TRUE; 1038 DeleteInputDeviceRequest(dev); 1039 1040 dev = *listHead; 1041 while (dev != NULL && freedIds[dev->id]) 1042 dev = dev->next; 1043 } 1044 } 1045 1046 /** 1047 * Shut down all devices, free all resources, etc. 1048 * Only useful if you're shutting down the server! 1049 */ 1050 void 1051 CloseDownDevices(void) 1052 { 1053 DeviceIntPtr dev; 1054 1055 input_lock(); 1056 1057 /* Float all SDs before closing them. Note that at this point resources 1058 * (e.g. cursors) have been freed already, so we can't just call 1059 * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master 1060 * to NULL and pretend nothing happened. 1061 */ 1062 for (dev = inputInfo.devices; dev; dev = dev->next) { 1063 if (!IsMaster(dev) && !IsFloating(dev)) 1064 dev->master = NULL; 1065 } 1066 1067 CloseDeviceList(&inputInfo.devices); 1068 CloseDeviceList(&inputInfo.off_devices); 1069 1070 CloseDevice(inputInfo.pointer); 1071 1072 CloseDevice(inputInfo.keyboard); 1073 1074 inputInfo.devices = NULL; 1075 inputInfo.off_devices = NULL; 1076 inputInfo.keyboard = NULL; 1077 inputInfo.pointer = NULL; 1078 1079 XkbDeleteRulesDflts(); 1080 XkbDeleteRulesUsed(); 1081 1082 input_unlock(); 1083 } 1084 1085 /** 1086 * Signal all devices that we're in the process of aborting. 1087 * This function is called from a signal handler. 1088 */ 1089 void 1090 AbortDevices(void) 1091 { 1092 DeviceIntPtr dev; 1093 1094 /* Do not call input_lock as we don't know what 1095 * state the input thread might be in, and that could 1096 * cause a dead-lock. 1097 */ 1098 nt_list_for_each_entry(dev, inputInfo.devices, next) { 1099 if (!IsMaster(dev)) 1100 (*dev->deviceProc) (dev, DEVICE_ABORT); 1101 } 1102 1103 nt_list_for_each_entry(dev, inputInfo.off_devices, next) { 1104 if (!IsMaster(dev)) 1105 (*dev->deviceProc) (dev, DEVICE_ABORT); 1106 } 1107 } 1108 1109 /** 1110 * Remove the cursor sprite for all devices. This needs to be done before any 1111 * resources are freed or any device is deleted. 1112 */ 1113 void 1114 UndisplayDevices(void) 1115 { 1116 DeviceIntPtr dev; 1117 ScreenPtr screen = screenInfo.screens[0]; 1118 1119 for (dev = inputInfo.devices; dev; dev = dev->next) 1120 screen->DisplayCursor(dev, screen, NullCursor); 1121 } 1122 1123 /** 1124 * Remove a device from the device list, closes it and thus frees all 1125 * resources. 1126 * Removes both enabled and disabled devices and notifies all devices about 1127 * the removal of the device. 1128 * 1129 * No PresenceNotify is sent for device that the client never saw. This can 1130 * happen if a malloc fails during the addition of master devices. If 1131 * dev->init is FALSE it means the client never received a DeviceAdded event, 1132 * so let's not send a DeviceRemoved event either. 1133 * 1134 * @param sendevent True if an XI2 event should be sent. 1135 */ 1136 int 1137 RemoveDevice(DeviceIntPtr dev, BOOL sendevent) 1138 { 1139 DeviceIntPtr prev, tmp, next; 1140 int ret = BadMatch; 1141 ScreenPtr screen = screenInfo.screens[0]; 1142 int deviceid; 1143 int initialized; 1144 int flags[MAXDEVICES] = { 0 }; 1145 1146 DebugF("(dix) removing device %d\n", dev->id); 1147 1148 if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer) 1149 return BadImplementation; 1150 1151 initialized = dev->inited; 1152 deviceid = dev->id; 1153 1154 if (initialized) { 1155 if (DevHasCursor(dev)) 1156 screen->DisplayCursor(dev, screen, NullCursor); 1157 1158 DisableDevice(dev, sendevent); 1159 flags[dev->id] = XIDeviceDisabled; 1160 } 1161 1162 input_lock(); 1163 1164 prev = NULL; 1165 for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) { 1166 next = tmp->next; 1167 if (tmp == dev) { 1168 1169 if (prev == NULL) 1170 inputInfo.devices = next; 1171 else 1172 prev->next = next; 1173 1174 flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; 1175 CloseDevice(tmp); 1176 ret = Success; 1177 break; 1178 } 1179 } 1180 1181 prev = NULL; 1182 for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) { 1183 next = tmp->next; 1184 if (tmp == dev) { 1185 flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; 1186 CloseDevice(tmp); 1187 1188 if (prev == NULL) 1189 inputInfo.off_devices = next; 1190 else 1191 prev->next = next; 1192 1193 ret = Success; 1194 break; 1195 } 1196 } 1197 1198 input_unlock(); 1199 1200 if (ret == Success && initialized) { 1201 inputInfo.numDevices--; 1202 SendDevicePresenceEvent(deviceid, DeviceRemoved); 1203 if (sendevent) 1204 XISendDeviceHierarchyEvent(flags); 1205 } 1206 1207 return ret; 1208 } 1209 1210 int 1211 NumMotionEvents(void) 1212 { 1213 /* only called to fill data in initial connection reply. 1214 * VCP is ok here, it is the only fixed device we have. */ 1215 return inputInfo.pointer->valuator->numMotionEvents; 1216 } 1217 1218 int 1219 dixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode) 1220 { 1221 DeviceIntPtr dev; 1222 int rc; 1223 1224 *pDev = NULL; 1225 1226 for (dev = inputInfo.devices; dev; dev = dev->next) { 1227 if (dev->id == id) 1228 goto found; 1229 } 1230 for (dev = inputInfo.off_devices; dev; dev = dev->next) { 1231 if (dev->id == id) 1232 goto found; 1233 } 1234 return BadDevice; 1235 1236 found: 1237 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 1238 if (rc == Success) 1239 *pDev = dev; 1240 return rc; 1241 } 1242 1243 void 1244 QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode) 1245 { 1246 if (inputInfo.keyboard) { 1247 *minCode = inputInfo.keyboard->key->xkbInfo->desc->min_key_code; 1248 *maxCode = inputInfo.keyboard->key->xkbInfo->desc->max_key_code; 1249 } 1250 } 1251 1252 Bool 1253 InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom *labels, 1254 CARD8 *map) 1255 { 1256 ButtonClassPtr butc; 1257 int i; 1258 1259 BUG_RETURN_VAL(dev == NULL, FALSE); 1260 BUG_RETURN_VAL(dev->button != NULL, FALSE); 1261 BUG_RETURN_VAL(numButtons >= MAX_BUTTONS, FALSE); 1262 1263 butc = calloc(1, sizeof(ButtonClassRec)); 1264 if (!butc) 1265 return FALSE; 1266 butc->numButtons = numButtons; 1267 butc->sourceid = dev->id; 1268 for (i = 1; i <= numButtons; i++) 1269 butc->map[i] = map[i]; 1270 for (i = numButtons + 1; i < MAP_LENGTH; i++) 1271 butc->map[i] = i; 1272 memcpy(butc->labels, labels, numButtons * sizeof(Atom)); 1273 dev->button = butc; 1274 return TRUE; 1275 } 1276 1277 /** 1278 * Allocate a valuator class and set up the pointers for the axis values 1279 * appropriately. 1280 * 1281 * @param src If non-NULL, the memory is reallocated from src. If NULL, the 1282 * memory is calloc'd. 1283 * @parma numAxes Number of axes to allocate. 1284 * @return The allocated valuator struct. 1285 */ 1286 ValuatorClassPtr 1287 AllocValuatorClass(ValuatorClassPtr src, int numAxes) 1288 { 1289 ValuatorClassPtr v; 1290 1291 /* force alignment with double */ 1292 union align_u { 1293 ValuatorClassRec valc; 1294 double d; 1295 } *align; 1296 int size; 1297 1298 size = 1299 sizeof(union align_u) + numAxes * (sizeof(double) + sizeof(AxisInfo)); 1300 align = (union align_u *) realloc(src, size); 1301 1302 if (!align) 1303 return NULL; 1304 1305 if (!src) 1306 memset(align, 0, size); 1307 1308 v = &align->valc; 1309 v->numAxes = numAxes; 1310 v->axisVal = (double *) (align + 1); 1311 v->axes = (AxisInfoPtr) (v->axisVal + numAxes); 1312 1313 return v; 1314 } 1315 1316 Bool 1317 InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, 1318 int numMotionEvents, int mode) 1319 { 1320 int i; 1321 ValuatorClassPtr valc; 1322 1323 BUG_RETURN_VAL(dev == NULL, FALSE); 1324 1325 if (numAxes > MAX_VALUATORS) { 1326 LogMessage(X_WARNING, 1327 "Device '%s' has %d axes, only using first %d.\n", 1328 dev->name, numAxes, MAX_VALUATORS); 1329 numAxes = MAX_VALUATORS; 1330 } 1331 1332 valc = AllocValuatorClass(NULL, numAxes); 1333 if (!valc) 1334 return FALSE; 1335 1336 dev->last.scroll = valuator_mask_new(numAxes); 1337 if (!dev->last.scroll) { 1338 free(valc); 1339 return FALSE; 1340 } 1341 1342 valc->sourceid = dev->id; 1343 valc->motion = NULL; 1344 valc->first_motion = 0; 1345 valc->last_motion = 0; 1346 valc->h_scroll_axis = -1; 1347 valc->v_scroll_axis = -1; 1348 1349 valc->numMotionEvents = numMotionEvents; 1350 valc->motionHintWindow = NullWindow; 1351 1352 if ((mode & OutOfProximity) && !dev->proximity) 1353 InitProximityClassDeviceStruct(dev); 1354 1355 dev->valuator = valc; 1356 1357 AllocateMotionHistory(dev); 1358 1359 for (i = 0; i < numAxes; i++) { 1360 InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, 1361 NO_AXIS_LIMITS, 0, 0, 0, mode); 1362 valc->axisVal[i] = 0; 1363 } 1364 1365 dev->last.numValuators = numAxes; 1366 1367 if (IsMaster(dev) || /* do not accelerate master or xtest devices */ 1368 IsXTestDevice(dev, NULL)) 1369 InitPointerAccelerationScheme(dev, PtrAccelNoOp); 1370 else 1371 InitPointerAccelerationScheme(dev, PtrAccelDefault); 1372 return TRUE; 1373 } 1374 1375 /* global list of acceleration schemes */ 1376 ValuatorAccelerationRec pointerAccelerationScheme[] = { 1377 {PtrAccelNoOp, NULL, NULL, NULL, NULL}, 1378 {PtrAccelPredictable, acceleratePointerPredictable, NULL, 1379 InitPredictableAccelerationScheme, AccelerationDefaultCleanup}, 1380 {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL, NULL}, 1381 {-1, NULL, NULL, NULL, NULL} /* terminator */ 1382 }; 1383 1384 /** 1385 * install an acceleration scheme. returns TRUE on success, and should not 1386 * change anything if unsuccessful. 1387 */ 1388 Bool 1389 InitPointerAccelerationScheme(DeviceIntPtr dev, int scheme) 1390 { 1391 int x, i = -1; 1392 ValuatorClassPtr val; 1393 1394 val = dev->valuator; 1395 1396 if (!val) 1397 return FALSE; 1398 1399 if (IsMaster(dev) && scheme != PtrAccelNoOp) 1400 return FALSE; 1401 1402 for (x = 0; pointerAccelerationScheme[x].number >= 0; x++) { 1403 if (pointerAccelerationScheme[x].number == scheme) { 1404 i = x; 1405 break; 1406 } 1407 } 1408 1409 if (-1 == i) 1410 return FALSE; 1411 1412 if (val->accelScheme.AccelCleanupProc) 1413 val->accelScheme.AccelCleanupProc(dev); 1414 1415 if (pointerAccelerationScheme[i].AccelInitProc) { 1416 if (!pointerAccelerationScheme[i].AccelInitProc(dev, 1417 &pointerAccelerationScheme[i])) { 1418 return FALSE; 1419 } 1420 } 1421 else { 1422 val->accelScheme = pointerAccelerationScheme[i]; 1423 } 1424 return TRUE; 1425 } 1426 1427 Bool 1428 InitFocusClassDeviceStruct(DeviceIntPtr dev) 1429 { 1430 FocusClassPtr focc; 1431 1432 BUG_RETURN_VAL(dev == NULL, FALSE); 1433 BUG_RETURN_VAL(dev->focus != NULL, FALSE); 1434 1435 focc = malloc(sizeof(FocusClassRec)); 1436 if (!focc) 1437 return FALSE; 1438 UpdateCurrentTimeIf(); 1439 focc->win = PointerRootWin; 1440 focc->revert = None; 1441 focc->time = currentTime; 1442 focc->trace = (WindowPtr *) NULL; 1443 focc->traceSize = 0; 1444 focc->traceGood = 0; 1445 focc->sourceid = dev->id; 1446 dev->focus = focc; 1447 return TRUE; 1448 } 1449 1450 Bool 1451 InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc) 1452 { 1453 PtrFeedbackPtr feedc; 1454 1455 BUG_RETURN_VAL(dev == NULL, FALSE); 1456 1457 feedc = malloc(sizeof(PtrFeedbackClassRec)); 1458 if (!feedc) 1459 return FALSE; 1460 feedc->CtrlProc = controlProc; 1461 feedc->ctrl = defaultPointerControl; 1462 feedc->ctrl.id = 0; 1463 if ((feedc->next = dev->ptrfeed)) 1464 feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1; 1465 dev->ptrfeed = feedc; 1466 (*controlProc) (dev, &feedc->ctrl); 1467 return TRUE; 1468 } 1469 1470 static LedCtrl defaultLedControl = { 1471 DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0 1472 }; 1473 1474 static BellCtrl defaultBellControl = { 1475 DEFAULT_BELL, 1476 DEFAULT_BELL_PITCH, 1477 DEFAULT_BELL_DURATION, 1478 0 1479 }; 1480 1481 static IntegerCtrl defaultIntegerControl = { 1482 DEFAULT_INT_RESOLUTION, 1483 DEFAULT_INT_MIN_VALUE, 1484 DEFAULT_INT_MAX_VALUE, 1485 DEFAULT_INT_DISPLAYED, 1486 0 1487 }; 1488 1489 Bool 1490 InitStringFeedbackClassDeviceStruct(DeviceIntPtr dev, 1491 StringCtrlProcPtr controlProc, 1492 int max_symbols, int num_symbols_supported, 1493 KeySym * symbols) 1494 { 1495 int i; 1496 StringFeedbackPtr feedc; 1497 1498 BUG_RETURN_VAL(dev == NULL, FALSE); 1499 1500 feedc = malloc(sizeof(StringFeedbackClassRec)); 1501 if (!feedc) 1502 return FALSE; 1503 feedc->CtrlProc = controlProc; 1504 feedc->ctrl.num_symbols_supported = num_symbols_supported; 1505 feedc->ctrl.num_symbols_displayed = 0; 1506 feedc->ctrl.max_symbols = max_symbols; 1507 feedc->ctrl.symbols_supported = 1508 xallocarray(num_symbols_supported, sizeof(KeySym)); 1509 feedc->ctrl.symbols_displayed = xallocarray(max_symbols, sizeof(KeySym)); 1510 if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed) { 1511 free(feedc->ctrl.symbols_supported); 1512 free(feedc->ctrl.symbols_displayed); 1513 free(feedc); 1514 return FALSE; 1515 } 1516 for (i = 0; i < num_symbols_supported; i++) 1517 *(feedc->ctrl.symbols_supported + i) = *symbols++; 1518 for (i = 0; i < max_symbols; i++) 1519 *(feedc->ctrl.symbols_displayed + i) = (KeySym) 0; 1520 feedc->ctrl.id = 0; 1521 if ((feedc->next = dev->stringfeed)) 1522 feedc->ctrl.id = dev->stringfeed->ctrl.id + 1; 1523 dev->stringfeed = feedc; 1524 (*controlProc) (dev, &feedc->ctrl); 1525 return TRUE; 1526 } 1527 1528 Bool 1529 InitBellFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc, 1530 BellCtrlProcPtr controlProc) 1531 { 1532 BellFeedbackPtr feedc; 1533 1534 BUG_RETURN_VAL(dev == NULL, FALSE); 1535 1536 feedc = malloc(sizeof(BellFeedbackClassRec)); 1537 if (!feedc) 1538 return FALSE; 1539 feedc->CtrlProc = controlProc; 1540 feedc->BellProc = bellProc; 1541 feedc->ctrl = defaultBellControl; 1542 feedc->ctrl.id = 0; 1543 if ((feedc->next = dev->bell)) 1544 feedc->ctrl.id = dev->bell->ctrl.id + 1; 1545 dev->bell = feedc; 1546 (*controlProc) (dev, &feedc->ctrl); 1547 return TRUE; 1548 } 1549 1550 Bool 1551 InitLedFeedbackClassDeviceStruct(DeviceIntPtr dev, LedCtrlProcPtr controlProc) 1552 { 1553 LedFeedbackPtr feedc; 1554 1555 BUG_RETURN_VAL(dev == NULL, FALSE); 1556 1557 feedc = malloc(sizeof(LedFeedbackClassRec)); 1558 if (!feedc) 1559 return FALSE; 1560 feedc->CtrlProc = controlProc; 1561 feedc->ctrl = defaultLedControl; 1562 feedc->ctrl.id = 0; 1563 if ((feedc->next = dev->leds)) 1564 feedc->ctrl.id = dev->leds->ctrl.id + 1; 1565 feedc->xkb_sli = NULL; 1566 dev->leds = feedc; 1567 (*controlProc) (dev, &feedc->ctrl); 1568 return TRUE; 1569 } 1570 1571 Bool 1572 InitIntegerFeedbackClassDeviceStruct(DeviceIntPtr dev, 1573 IntegerCtrlProcPtr controlProc) 1574 { 1575 IntegerFeedbackPtr feedc; 1576 1577 BUG_RETURN_VAL(dev == NULL, FALSE); 1578 1579 feedc = malloc(sizeof(IntegerFeedbackClassRec)); 1580 if (!feedc) 1581 return FALSE; 1582 feedc->CtrlProc = controlProc; 1583 feedc->ctrl = defaultIntegerControl; 1584 feedc->ctrl.id = 0; 1585 if ((feedc->next = dev->intfeed)) 1586 feedc->ctrl.id = dev->intfeed->ctrl.id + 1; 1587 dev->intfeed = feedc; 1588 (*controlProc) (dev, &feedc->ctrl); 1589 return TRUE; 1590 } 1591 1592 Bool 1593 InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons, 1594 Atom *btn_labels, PtrCtrlProcPtr controlProc, 1595 int numMotionEvents, int numAxes, Atom *axes_labels) 1596 { 1597 DeviceIntPtr dev = (DeviceIntPtr) device; 1598 1599 BUG_RETURN_VAL(dev == NULL, FALSE); 1600 BUG_RETURN_VAL(dev->button != NULL, FALSE); 1601 BUG_RETURN_VAL(dev->valuator != NULL, FALSE); 1602 BUG_RETURN_VAL(dev->ptrfeed != NULL, FALSE); 1603 1604 return (InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) && 1605 InitValuatorClassDeviceStruct(dev, numAxes, axes_labels, 1606 numMotionEvents, Relative) && 1607 InitPtrFeedbackClassDeviceStruct(dev, controlProc)); 1608 } 1609 1610 /** 1611 * Sets up multitouch capabilities on @device. 1612 * 1613 * @max_touches The maximum number of simultaneous touches, or 0 for unlimited. 1614 * @mode The mode of the touch device (XIDirectTouch or XIDependentTouch). 1615 * @num_axes The number of touch valuator axes. 1616 */ 1617 Bool 1618 InitTouchClassDeviceStruct(DeviceIntPtr device, unsigned int max_touches, 1619 unsigned int mode, unsigned int num_axes) 1620 { 1621 TouchClassPtr touch; 1622 int i; 1623 1624 BUG_RETURN_VAL(device == NULL, FALSE); 1625 BUG_RETURN_VAL(device->touch != NULL, FALSE); 1626 BUG_RETURN_VAL(device->valuator == NULL, FALSE); 1627 1628 /* Check the mode is valid, and at least X and Y axes. */ 1629 BUG_RETURN_VAL(mode != XIDirectTouch && mode != XIDependentTouch, FALSE); 1630 BUG_RETURN_VAL(num_axes < 2, FALSE); 1631 1632 if (num_axes > MAX_VALUATORS) { 1633 LogMessage(X_WARNING, 1634 "Device '%s' has %d touch axes, only using first %d.\n", 1635 device->name, num_axes, MAX_VALUATORS); 1636 num_axes = MAX_VALUATORS; 1637 } 1638 1639 touch = calloc(1, sizeof(*touch)); 1640 if (!touch) 1641 return FALSE; 1642 1643 touch->max_touches = max_touches; 1644 if (max_touches == 0) 1645 max_touches = 5; /* arbitrary number plucked out of the air */ 1646 touch->touches = calloc(max_touches, sizeof(*touch->touches)); 1647 if (!touch->touches) 1648 goto err; 1649 touch->num_touches = max_touches; 1650 for (i = 0; i < max_touches; i++) 1651 TouchInitTouchPoint(touch, device->valuator, i); 1652 1653 touch->mode = mode; 1654 touch->sourceid = device->id; 1655 1656 device->touch = touch; 1657 device->last.touches = calloc(max_touches, sizeof(*device->last.touches)); 1658 device->last.num_touches = touch->num_touches; 1659 for (i = 0; i < touch->num_touches; i++) 1660 TouchInitDDXTouchPoint(device, &device->last.touches[i]); 1661 1662 return TRUE; 1663 1664 err: 1665 for (i = 0; i < touch->num_touches; i++) 1666 TouchFreeTouchPoint(device, i); 1667 1668 free(touch->touches); 1669 free(touch); 1670 1671 return FALSE; 1672 } 1673 1674 /** 1675 * Sets up gesture capabilities on @device. 1676 * 1677 * @max_touches The maximum number of simultaneous touches, or 0 for unlimited. 1678 */ 1679 Bool 1680 InitGestureClassDeviceStruct(DeviceIntPtr device, unsigned int max_touches) 1681 { 1682 GestureClassPtr g; 1683 1684 BUG_RETURN_VAL(device == NULL, FALSE); 1685 BUG_RETURN_VAL(device->gesture != NULL, FALSE); 1686 1687 g = calloc(1, sizeof(*g)); 1688 if (!g) 1689 return FALSE; 1690 1691 g->sourceid = device->id; 1692 g->max_touches = max_touches; 1693 GestureInitGestureInfo(&g->gesture); 1694 1695 device->gesture = g; 1696 1697 return TRUE; 1698 } 1699 1700 /* 1701 * Check if the given buffer contains elements between low (inclusive) and 1702 * high (inclusive) only. 1703 * 1704 * @return TRUE if the device map is invalid, FALSE otherwise. 1705 */ 1706 Bool 1707 BadDeviceMap(BYTE * buff, int length, unsigned low, unsigned high, XID *errval) 1708 { 1709 int i; 1710 1711 for (i = 0; i < length; i++) 1712 if (buff[i]) { /* only check non-zero elements */ 1713 if ((low > buff[i]) || (high < buff[i])) { 1714 *errval = buff[i]; 1715 return TRUE; 1716 } 1717 } 1718 return FALSE; 1719 } 1720 1721 int 1722 ProcSetModifierMapping(ClientPtr client) 1723 { 1724 xSetModifierMappingReply rep; 1725 int rc; 1726 1727 REQUEST(xSetModifierMappingReq); 1728 REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq); 1729 1730 if (client->req_len != ((stuff->numKeyPerModifier << 1) + 1731 bytes_to_int32(sizeof(xSetModifierMappingReq)))) 1732 return BadLength; 1733 1734 rep = (xSetModifierMappingReply) { 1735 .type = X_Reply, 1736 .sequenceNumber = client->sequence, 1737 .length = 0 1738 }; 1739 1740 rc = change_modmap(client, PickKeyboard(client), (KeyCode *) &stuff[1], 1741 stuff->numKeyPerModifier); 1742 if (rc == MappingFailed || rc == -1) 1743 return BadValue; 1744 if (rc != MappingSuccess && rc != MappingFailed && rc != MappingBusy) 1745 return rc; 1746 1747 rep.success = rc; 1748 1749 WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep); 1750 return Success; 1751 } 1752 1753 int 1754 ProcGetModifierMapping(ClientPtr client) 1755 { 1756 xGetModifierMappingReply rep; 1757 int max_keys_per_mod = 0; 1758 KeyCode *modkeymap = NULL; 1759 1760 REQUEST_SIZE_MATCH(xReq); 1761 1762 generate_modkeymap(client, PickKeyboard(client), &modkeymap, 1763 &max_keys_per_mod); 1764 1765 rep = (xGetModifierMappingReply) { 1766 .type = X_Reply, 1767 .numKeyPerModifier = max_keys_per_mod, 1768 .sequenceNumber = client->sequence, 1769 /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */ 1770 .length = max_keys_per_mod << 1 1771 }; 1772 1773 WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep); 1774 WriteToClient(client, max_keys_per_mod * 8, modkeymap); 1775 1776 free(modkeymap); 1777 1778 return Success; 1779 } 1780 1781 int 1782 ProcChangeKeyboardMapping(ClientPtr client) 1783 { 1784 REQUEST(xChangeKeyboardMappingReq); 1785 unsigned len; 1786 KeySymsRec keysyms; 1787 DeviceIntPtr pDev, tmp; 1788 int rc; 1789 1790 REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq); 1791 1792 len = client->req_len - bytes_to_int32(sizeof(xChangeKeyboardMappingReq)); 1793 if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode)) 1794 return BadLength; 1795 1796 pDev = PickKeyboard(client); 1797 1798 if ((stuff->firstKeyCode < pDev->key->xkbInfo->desc->min_key_code) || 1799 (stuff->firstKeyCode > pDev->key->xkbInfo->desc->max_key_code)) { 1800 client->errorValue = stuff->firstKeyCode; 1801 return BadValue; 1802 1803 } 1804 if (((unsigned) (stuff->firstKeyCode + stuff->keyCodes - 1) > 1805 pDev->key->xkbInfo->desc->max_key_code) || 1806 (stuff->keySymsPerKeyCode == 0)) { 1807 client->errorValue = stuff->keySymsPerKeyCode; 1808 return BadValue; 1809 } 1810 1811 keysyms.minKeyCode = stuff->firstKeyCode; 1812 keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1; 1813 keysyms.mapWidth = stuff->keySymsPerKeyCode; 1814 keysyms.map = (KeySym *) &stuff[1]; 1815 1816 rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); 1817 if (rc != Success) 1818 return rc; 1819 1820 XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode, 1821 stuff->keyCodes, NULL, client); 1822 1823 for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { 1824 if (IsMaster(tmp) || GetMaster(tmp, MASTER_KEYBOARD) != pDev) 1825 continue; 1826 if (!tmp->key) 1827 continue; 1828 1829 rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); 1830 if (rc != Success) 1831 continue; 1832 1833 XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode, 1834 stuff->keyCodes, NULL, client); 1835 } 1836 1837 return Success; 1838 } 1839 1840 int 1841 ProcSetPointerMapping(ClientPtr client) 1842 { 1843 BYTE *map; 1844 int ret; 1845 int i, j; 1846 DeviceIntPtr ptr = PickPointer(client); 1847 xSetPointerMappingReply rep; 1848 1849 REQUEST(xSetPointerMappingReq); 1850 REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq); 1851 1852 if (client->req_len != 1853 bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts)) 1854 return BadLength; 1855 1856 rep = (xSetPointerMappingReply) { 1857 .type = X_Reply, 1858 .success = MappingSuccess, 1859 .sequenceNumber = client->sequence, 1860 .length = 0 1861 }; 1862 map = (BYTE *) &stuff[1]; 1863 1864 /* So we're bounded here by the number of core buttons. This check 1865 * probably wants disabling through XFixes. */ 1866 /* MPX: With ClientPointer, we can return the right number of buttons. 1867 * Let's just hope nobody changed ClientPointer between GetPointerMapping 1868 * and SetPointerMapping 1869 */ 1870 if (stuff->nElts != ptr->button->numButtons) { 1871 client->errorValue = stuff->nElts; 1872 return BadValue; 1873 } 1874 1875 /* Core protocol specs don't allow for duplicate mappings; this check 1876 * almost certainly wants disabling through XFixes too. */ 1877 for (i = 0; i < stuff->nElts; i++) { 1878 for (j = i + 1; j < stuff->nElts; j++) { 1879 if (map[i] && map[i] == map[j]) { 1880 client->errorValue = map[i]; 1881 return BadValue; 1882 } 1883 } 1884 } 1885 1886 ret = ApplyPointerMapping(ptr, map, stuff->nElts, client); 1887 if (ret == MappingBusy) 1888 rep.success = ret; 1889 else if (ret == -1) 1890 return BadValue; 1891 else if (ret != Success) 1892 return ret; 1893 1894 WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep); 1895 return Success; 1896 } 1897 1898 int 1899 ProcGetKeyboardMapping(ClientPtr client) 1900 { 1901 xGetKeyboardMappingReply rep; 1902 DeviceIntPtr kbd = PickKeyboard(client); 1903 XkbDescPtr xkb; 1904 KeySymsPtr syms; 1905 int rc; 1906 1907 REQUEST(xGetKeyboardMappingReq); 1908 REQUEST_SIZE_MATCH(xGetKeyboardMappingReq); 1909 1910 rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess); 1911 if (rc != Success) 1912 return rc; 1913 1914 xkb = kbd->key->xkbInfo->desc; 1915 1916 if ((stuff->firstKeyCode < xkb->min_key_code) || 1917 (stuff->firstKeyCode > xkb->max_key_code)) { 1918 client->errorValue = stuff->firstKeyCode; 1919 return BadValue; 1920 } 1921 if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) { 1922 client->errorValue = stuff->count; 1923 return BadValue; 1924 } 1925 1926 syms = XkbGetCoreMap(kbd); 1927 if (!syms) 1928 return BadAlloc; 1929 1930 rep = (xGetKeyboardMappingReply) { 1931 .type = X_Reply, 1932 .keySymsPerKeyCode = syms->mapWidth, 1933 .sequenceNumber = client->sequence, 1934 /* length is a count of 4 byte quantities and KeySyms are 4 bytes */ 1935 .length = syms->mapWidth * stuff->count 1936 }; 1937 WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep); 1938 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write; 1939 WriteSwappedDataToClient(client, 1940 syms->mapWidth * stuff->count * sizeof(KeySym), 1941 &syms->map[syms->mapWidth * (stuff->firstKeyCode - 1942 syms->minKeyCode)]); 1943 free(syms->map); 1944 free(syms); 1945 1946 return Success; 1947 } 1948 1949 int 1950 ProcGetPointerMapping(ClientPtr client) 1951 { 1952 xGetPointerMappingReply rep; 1953 1954 /* Apps may get different values each time they call GetPointerMapping as 1955 * the ClientPointer could change. */ 1956 DeviceIntPtr ptr = PickPointer(client); 1957 ButtonClassPtr butc = ptr->button; 1958 int nElts; 1959 int rc; 1960 1961 REQUEST_SIZE_MATCH(xReq); 1962 1963 rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess); 1964 if (rc != Success) 1965 return rc; 1966 1967 nElts = (butc) ? butc->numButtons : 0; 1968 rep = (xGetPointerMappingReply) { 1969 .type = X_Reply, 1970 .nElts = nElts, 1971 .sequenceNumber = client->sequence, 1972 .length = ((unsigned) nElts + (4 - 1)) / 4 1973 }; 1974 WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep); 1975 if (butc) 1976 WriteToClient(client, nElts, &butc->map[1]); 1977 return Success; 1978 } 1979 1980 void 1981 NoteLedState(DeviceIntPtr keybd, int led, Bool on) 1982 { 1983 KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl; 1984 1985 if (on) 1986 ctrl->leds |= ((Leds) 1 << (led - 1)); 1987 else 1988 ctrl->leds &= ~((Leds) 1 << (led - 1)); 1989 } 1990 1991 int 1992 Ones(unsigned long mask) 1993 { /* HACKMEM 169 */ 1994 unsigned long y; 1995 1996 y = (mask >> 1) & 033333333333; 1997 y = mask - y - ((y >> 1) & 033333333333); 1998 return (((y + (y >> 3)) & 030707070707) % 077); 1999 } 2000 2001 static int 2002 DoChangeKeyboardControl(ClientPtr client, DeviceIntPtr keybd, XID *vlist, 2003 BITS32 vmask) 2004 { 2005 #define DO_ALL (-1) 2006 KeybdCtrl ctrl; 2007 int t; 2008 int led = DO_ALL; 2009 int key = DO_ALL; 2010 BITS32 index2; 2011 int mask = vmask, i; 2012 XkbEventCauseRec cause; 2013 2014 ctrl = keybd->kbdfeed->ctrl; 2015 while (vmask) { 2016 index2 = (BITS32) lowbit(vmask); 2017 vmask &= ~index2; 2018 switch (index2) { 2019 case KBKeyClickPercent: 2020 t = (INT8) *vlist; 2021 vlist++; 2022 if (t == -1) { 2023 t = defaultKeyboardControl.click; 2024 } 2025 else if (t < 0 || t > 100) { 2026 client->errorValue = t; 2027 return BadValue; 2028 } 2029 ctrl.click = t; 2030 break; 2031 case KBBellPercent: 2032 t = (INT8) *vlist; 2033 vlist++; 2034 if (t == -1) { 2035 t = defaultKeyboardControl.bell; 2036 } 2037 else if (t < 0 || t > 100) { 2038 client->errorValue = t; 2039 return BadValue; 2040 } 2041 ctrl.bell = t; 2042 break; 2043 case KBBellPitch: 2044 t = (INT16) *vlist; 2045 vlist++; 2046 if (t == -1) { 2047 t = defaultKeyboardControl.bell_pitch; 2048 } 2049 else if (t < 0) { 2050 client->errorValue = t; 2051 return BadValue; 2052 } 2053 ctrl.bell_pitch = t; 2054 break; 2055 case KBBellDuration: 2056 t = (INT16) *vlist; 2057 vlist++; 2058 if (t == -1) 2059 t = defaultKeyboardControl.bell_duration; 2060 else if (t < 0) { 2061 client->errorValue = t; 2062 return BadValue; 2063 } 2064 ctrl.bell_duration = t; 2065 break; 2066 case KBLed: 2067 led = (CARD8) *vlist; 2068 vlist++; 2069 if (led < 1 || led > 32) { 2070 client->errorValue = led; 2071 return BadValue; 2072 } 2073 if (!(mask & KBLedMode)) 2074 return BadMatch; 2075 break; 2076 case KBLedMode: 2077 t = (CARD8) *vlist; 2078 vlist++; 2079 if (t == LedModeOff) { 2080 if (led == DO_ALL) 2081 ctrl.leds = 0x0; 2082 else 2083 ctrl.leds &= ~(((Leds) (1)) << (led - 1)); 2084 } 2085 else if (t == LedModeOn) { 2086 if (led == DO_ALL) 2087 ctrl.leds = ~0L; 2088 else 2089 ctrl.leds |= (((Leds) (1)) << (led - 1)); 2090 } 2091 else { 2092 client->errorValue = t; 2093 return BadValue; 2094 } 2095 2096 XkbSetCauseCoreReq(&cause, X_ChangeKeyboardControl, client); 2097 XkbSetIndicators(keybd, ((led == DO_ALL) ? ~0L : (1L << (led - 1))), 2098 ctrl.leds, &cause); 2099 ctrl.leds = keybd->kbdfeed->ctrl.leds; 2100 2101 break; 2102 case KBKey: 2103 key = (KeyCode) *vlist; 2104 vlist++; 2105 if ((KeyCode) key < keybd->key->xkbInfo->desc->min_key_code || 2106 (KeyCode) key > keybd->key->xkbInfo->desc->max_key_code) { 2107 client->errorValue = key; 2108 return BadValue; 2109 } 2110 if (!(mask & KBAutoRepeatMode)) 2111 return BadMatch; 2112 break; 2113 case KBAutoRepeatMode: 2114 i = (key >> 3); 2115 mask = (1 << (key & 7)); 2116 t = (CARD8) *vlist; 2117 vlist++; 2118 if (key != DO_ALL) 2119 XkbDisableComputedAutoRepeats(keybd, key); 2120 if (t == AutoRepeatModeOff) { 2121 if (key == DO_ALL) 2122 ctrl.autoRepeat = FALSE; 2123 else 2124 ctrl.autoRepeats[i] &= ~mask; 2125 } 2126 else if (t == AutoRepeatModeOn) { 2127 if (key == DO_ALL) 2128 ctrl.autoRepeat = TRUE; 2129 else 2130 ctrl.autoRepeats[i] |= mask; 2131 } 2132 else if (t == AutoRepeatModeDefault) { 2133 if (key == DO_ALL) 2134 ctrl.autoRepeat = defaultKeyboardControl.autoRepeat; 2135 else 2136 ctrl.autoRepeats[i] = 2137 (ctrl.autoRepeats[i] & ~mask) | 2138 (defaultKeyboardControl.autoRepeats[i] & mask); 2139 } 2140 else { 2141 client->errorValue = t; 2142 return BadValue; 2143 } 2144 break; 2145 default: 2146 client->errorValue = mask; 2147 return BadValue; 2148 } 2149 } 2150 keybd->kbdfeed->ctrl = ctrl; 2151 2152 /* The XKB RepeatKeys control and core protocol global autorepeat */ 2153 /* value are linked */ 2154 XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat); 2155 2156 return Success; 2157 2158 #undef DO_ALL 2159 } 2160 2161 /** 2162 * Changes kbd control on the ClientPointer and all attached SDs. 2163 */ 2164 int 2165 ProcChangeKeyboardControl(ClientPtr client) 2166 { 2167 XID *vlist; 2168 BITS32 vmask; 2169 int ret = Success, error = Success; 2170 DeviceIntPtr pDev = NULL, keyboard; 2171 2172 REQUEST(xChangeKeyboardControlReq); 2173 2174 REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq); 2175 2176 vmask = stuff->mask; 2177 vlist = (XID *) &stuff[1]; 2178 2179 if (client->req_len != 2180 (sizeof(xChangeKeyboardControlReq) >> 2) + Ones(vmask)) 2181 return BadLength; 2182 2183 keyboard = PickKeyboard(client); 2184 2185 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 2186 if ((pDev == keyboard || 2187 (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard)) 2188 && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { 2189 ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); 2190 if (ret != Success) 2191 return ret; 2192 } 2193 } 2194 2195 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 2196 if ((pDev == keyboard || 2197 (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard)) 2198 && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { 2199 ret = DoChangeKeyboardControl(client, pDev, vlist, vmask); 2200 if (ret != Success) 2201 error = ret; 2202 } 2203 } 2204 2205 return error; 2206 } 2207 2208 int 2209 ProcGetKeyboardControl(ClientPtr client) 2210 { 2211 int rc, i; 2212 DeviceIntPtr kbd = PickKeyboard(client); 2213 KeybdCtrl *ctrl = &kbd->kbdfeed->ctrl; 2214 xGetKeyboardControlReply rep; 2215 2216 REQUEST_SIZE_MATCH(xReq); 2217 2218 rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess); 2219 if (rc != Success) 2220 return rc; 2221 2222 rep = (xGetKeyboardControlReply) { 2223 .type = X_Reply, 2224 .globalAutoRepeat = ctrl->autoRepeat, 2225 .sequenceNumber = client->sequence, 2226 .length = 5, 2227 .ledMask = ctrl->leds, 2228 .keyClickPercent = ctrl->click, 2229 .bellPercent = ctrl->bell, 2230 .bellPitch = ctrl->bell_pitch, 2231 .bellDuration = ctrl->bell_duration 2232 }; 2233 for (i = 0; i < 32; i++) 2234 rep.map[i] = ctrl->autoRepeats[i]; 2235 WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep); 2236 return Success; 2237 } 2238 2239 int 2240 ProcBell(ClientPtr client) 2241 { 2242 DeviceIntPtr dev, keybd = PickKeyboard(client); 2243 int base = keybd->kbdfeed->ctrl.bell; 2244 int newpercent; 2245 int rc; 2246 2247 REQUEST(xBellReq); 2248 REQUEST_SIZE_MATCH(xBellReq); 2249 2250 if (stuff->percent < -100 || stuff->percent > 100) { 2251 client->errorValue = stuff->percent; 2252 return BadValue; 2253 } 2254 2255 newpercent = (base * stuff->percent) / 100; 2256 if (stuff->percent < 0) 2257 newpercent = base + newpercent; 2258 else 2259 newpercent = base - newpercent + stuff->percent; 2260 2261 for (dev = inputInfo.devices; dev; dev = dev->next) { 2262 if ((dev == keybd || 2263 (!IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == keybd)) && 2264 ((dev->kbdfeed && dev->kbdfeed->BellProc) || dev->xkb_interest)) { 2265 2266 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess); 2267 if (rc != Success) 2268 return rc; 2269 XkbHandleBell(FALSE, FALSE, dev, newpercent, 2270 &dev->kbdfeed->ctrl, 0, None, NULL, client); 2271 } 2272 } 2273 2274 return Success; 2275 } 2276 2277 int 2278 ProcChangePointerControl(ClientPtr client) 2279 { 2280 DeviceIntPtr dev, mouse = PickPointer(client); 2281 PtrCtrl ctrl; /* might get BadValue part way through */ 2282 int rc; 2283 2284 REQUEST(xChangePointerControlReq); 2285 REQUEST_SIZE_MATCH(xChangePointerControlReq); 2286 2287 /* If the device has no PtrFeedbackPtr, the xserver has a bug */ 2288 BUG_RETURN_VAL (!mouse->ptrfeed, BadImplementation); 2289 2290 ctrl = mouse->ptrfeed->ctrl; 2291 if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) { 2292 client->errorValue = stuff->doAccel; 2293 return BadValue; 2294 } 2295 if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) { 2296 client->errorValue = stuff->doThresh; 2297 return BadValue; 2298 } 2299 if (stuff->doAccel) { 2300 if (stuff->accelNum == -1) { 2301 ctrl.num = defaultPointerControl.num; 2302 } 2303 else if (stuff->accelNum < 0) { 2304 client->errorValue = stuff->accelNum; 2305 return BadValue; 2306 } 2307 else { 2308 ctrl.num = stuff->accelNum; 2309 } 2310 2311 if (stuff->accelDenum == -1) { 2312 ctrl.den = defaultPointerControl.den; 2313 } 2314 else if (stuff->accelDenum <= 0) { 2315 client->errorValue = stuff->accelDenum; 2316 return BadValue; 2317 } 2318 else { 2319 ctrl.den = stuff->accelDenum; 2320 } 2321 } 2322 if (stuff->doThresh) { 2323 if (stuff->threshold == -1) { 2324 ctrl.threshold = defaultPointerControl.threshold; 2325 } 2326 else if (stuff->threshold < 0) { 2327 client->errorValue = stuff->threshold; 2328 return BadValue; 2329 } 2330 else { 2331 ctrl.threshold = stuff->threshold; 2332 } 2333 } 2334 2335 for (dev = inputInfo.devices; dev; dev = dev->next) { 2336 if ((dev == mouse || 2337 (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) && 2338 dev->ptrfeed) { 2339 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess); 2340 if (rc != Success) 2341 return rc; 2342 } 2343 } 2344 2345 for (dev = inputInfo.devices; dev; dev = dev->next) { 2346 if ((dev == mouse || 2347 (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) && 2348 dev->ptrfeed) { 2349 dev->ptrfeed->ctrl = ctrl; 2350 } 2351 } 2352 2353 return Success; 2354 } 2355 2356 int 2357 ProcGetPointerControl(ClientPtr client) 2358 { 2359 DeviceIntPtr ptr = PickPointer(client); 2360 PtrCtrl *ctrl; 2361 xGetPointerControlReply rep; 2362 int rc; 2363 2364 if (ptr->ptrfeed) 2365 ctrl = &ptr->ptrfeed->ctrl; 2366 else 2367 ctrl = &defaultPointerControl; 2368 2369 REQUEST_SIZE_MATCH(xReq); 2370 2371 rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess); 2372 if (rc != Success) 2373 return rc; 2374 2375 rep = (xGetPointerControlReply) { 2376 .type = X_Reply, 2377 .sequenceNumber = client->sequence, 2378 .length = 0, 2379 .accelNumerator = ctrl->num, 2380 .accelDenominator = ctrl->den, 2381 .threshold = ctrl->threshold 2382 }; 2383 WriteReplyToClient(client, sizeof(xGenericReply), &rep); 2384 return Success; 2385 } 2386 2387 void 2388 MaybeStopHint(DeviceIntPtr dev, ClientPtr client) 2389 { 2390 GrabPtr grab = dev->deviceGrab.grab; 2391 2392 if ((grab && SameClient(grab, client) && 2393 ((grab->eventMask & PointerMotionHintMask) || 2394 (grab->ownerEvents && 2395 (EventMaskForClient(dev->valuator->motionHintWindow, client) & 2396 PointerMotionHintMask)))) || 2397 (!grab && 2398 (EventMaskForClient(dev->valuator->motionHintWindow, client) & 2399 PointerMotionHintMask))) 2400 dev->valuator->motionHintWindow = NullWindow; 2401 } 2402 2403 int 2404 ProcGetMotionEvents(ClientPtr client) 2405 { 2406 WindowPtr pWin; 2407 xTimecoord *coords = (xTimecoord *) NULL; 2408 xGetMotionEventsReply rep; 2409 int i, count, xmin, xmax, ymin, ymax, rc; 2410 unsigned long nEvents; 2411 DeviceIntPtr mouse = PickPointer(client); 2412 TimeStamp start, stop; 2413 2414 REQUEST(xGetMotionEventsReq); 2415 REQUEST_SIZE_MATCH(xGetMotionEventsReq); 2416 2417 rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 2418 if (rc != Success) 2419 return rc; 2420 rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess); 2421 if (rc != Success) 2422 return rc; 2423 2424 UpdateCurrentTimeIf(); 2425 if (mouse->valuator->motionHintWindow) 2426 MaybeStopHint(mouse, client); 2427 rep = (xGetMotionEventsReply) { 2428 .type = X_Reply, 2429 .sequenceNumber = client->sequence 2430 }; 2431 nEvents = 0; 2432 start = ClientTimeToServerTime(stuff->start); 2433 stop = ClientTimeToServerTime(stuff->stop); 2434 if ((CompareTimeStamps(start, stop) != LATER) && 2435 (CompareTimeStamps(start, currentTime) != LATER) && 2436 mouse->valuator->numMotionEvents) { 2437 if (CompareTimeStamps(stop, currentTime) == LATER) 2438 stop = currentTime; 2439 count = GetMotionHistory(mouse, &coords, start.milliseconds, 2440 stop.milliseconds, pWin->drawable.pScreen, 2441 TRUE); 2442 xmin = pWin->drawable.x - wBorderWidth(pWin); 2443 xmax = pWin->drawable.x + (int) pWin->drawable.width + 2444 wBorderWidth(pWin); 2445 ymin = pWin->drawable.y - wBorderWidth(pWin); 2446 ymax = pWin->drawable.y + (int) pWin->drawable.height + 2447 wBorderWidth(pWin); 2448 for (i = 0; i < count; i++) 2449 if ((xmin <= coords[i].x) && (coords[i].x < xmax) && 2450 (ymin <= coords[i].y) && (coords[i].y < ymax)) { 2451 coords[nEvents].time = coords[i].time; 2452 coords[nEvents].x = coords[i].x - pWin->drawable.x; 2453 coords[nEvents].y = coords[i].y - pWin->drawable.y; 2454 nEvents++; 2455 } 2456 } 2457 rep.length = nEvents * bytes_to_int32(sizeof(xTimecoord)); 2458 rep.nEvents = nEvents; 2459 WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep); 2460 if (nEvents) { 2461 client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite; 2462 WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord), 2463 (char *) coords); 2464 } 2465 free(coords); 2466 return Success; 2467 } 2468 2469 int 2470 ProcQueryKeymap(ClientPtr client) 2471 { 2472 xQueryKeymapReply rep; 2473 int rc, i; 2474 DeviceIntPtr keybd = PickKeyboard(client); 2475 CARD8 *down = keybd->key->down; 2476 2477 REQUEST_SIZE_MATCH(xReq); 2478 rep = (xQueryKeymapReply) { 2479 .type = X_Reply, 2480 .sequenceNumber = client->sequence, 2481 .length = 2 2482 }; 2483 2484 rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess); 2485 /* If rc is Success, we're allowed to copy out the keymap. 2486 * If it's BadAccess, we leave it empty & lie to the client. 2487 */ 2488 if (rc == Success) { 2489 for (i = 0; i < 32; i++) 2490 rep.map[i] = down[i]; 2491 } 2492 else if (rc != BadAccess) 2493 return rc; 2494 2495 WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep); 2496 2497 return Success; 2498 } 2499 2500 /** 2501 * Recalculate the number of buttons for the master device. The number of 2502 * buttons on the master device is equal to the number of buttons on the 2503 * slave device with the highest number of buttons. 2504 */ 2505 static void 2506 RecalculateMasterButtons(DeviceIntPtr slave) 2507 { 2508 DeviceIntPtr dev, master; 2509 int maxbuttons = 0; 2510 2511 if (!slave->button || IsMaster(slave)) 2512 return; 2513 2514 master = GetMaster(slave, MASTER_POINTER); 2515 if (!master) 2516 return; 2517 2518 for (dev = inputInfo.devices; dev; dev = dev->next) { 2519 if (IsMaster(dev) || 2520 GetMaster(dev, MASTER_ATTACHED) != master || !dev->button) 2521 continue; 2522 2523 maxbuttons = max(maxbuttons, dev->button->numButtons); 2524 } 2525 2526 if (master->button && master->button->numButtons != maxbuttons) { 2527 int i; 2528 DeviceChangedEvent event = { 2529 .header = ET_Internal, 2530 .type = ET_DeviceChanged, 2531 .time = GetTimeInMillis(), 2532 .deviceid = master->id, 2533 .flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE, 2534 .buttons.num_buttons = maxbuttons 2535 }; 2536 2537 master->button->numButtons = maxbuttons; 2538 2539 memcpy(&event.buttons.names, master->button->labels, maxbuttons * 2540 sizeof(Atom)); 2541 2542 if (master->valuator) { 2543 event.num_valuators = master->valuator->numAxes; 2544 for (i = 0; i < event.num_valuators; i++) { 2545 event.valuators[i].min = master->valuator->axes[i].min_value; 2546 event.valuators[i].max = master->valuator->axes[i].max_value; 2547 event.valuators[i].resolution = 2548 master->valuator->axes[i].resolution; 2549 event.valuators[i].mode = master->valuator->axes[i].mode; 2550 event.valuators[i].name = master->valuator->axes[i].label; 2551 } 2552 } 2553 2554 if (master->key) { 2555 event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code; 2556 event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code; 2557 } 2558 2559 XISendDeviceChangedEvent(master, &event); 2560 } 2561 } 2562 2563 /** 2564 * Generate release events for all keys/button currently down on this 2565 * device. 2566 */ 2567 void 2568 ReleaseButtonsAndKeys(DeviceIntPtr dev) 2569 { 2570 InternalEvent *eventlist = InitEventList(GetMaximumEventsNum()); 2571 ButtonClassPtr b = dev->button; 2572 KeyClassPtr k = dev->key; 2573 int i, j, nevents; 2574 2575 if (!eventlist) /* no release events for you */ 2576 return; 2577 2578 /* Release all buttons */ 2579 for (i = 0; b && i < b->numButtons; i++) { 2580 if (BitIsOn(b->down, i)) { 2581 nevents = 2582 GetPointerEvents(eventlist, dev, ButtonRelease, i, 0, NULL); 2583 for (j = 0; j < nevents; j++) 2584 mieqProcessDeviceEvent(dev, &eventlist[j], NULL); 2585 } 2586 } 2587 2588 /* Release all keys */ 2589 for (i = 0; k && i < MAP_LENGTH; i++) { 2590 if (BitIsOn(k->down, i)) { 2591 nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i); 2592 for (j = 0; j < nevents; j++) 2593 mieqProcessDeviceEvent(dev, &eventlist[j], NULL); 2594 } 2595 } 2596 2597 FreeEventList(eventlist, GetMaximumEventsNum()); 2598 } 2599 2600 /** 2601 * Attach device 'dev' to device 'master'. 2602 * Client is set to the client that issued the request, or NULL if it comes 2603 * from some internal automatic pairing. 2604 * 2605 * Master may be NULL to set the device floating. 2606 * 2607 * We don't allow multi-layer hierarchies right now. You can't attach a slave 2608 * to another slave. 2609 */ 2610 int 2611 AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) 2612 { 2613 ScreenPtr screen; 2614 2615 if (!dev || IsMaster(dev)) 2616 return BadDevice; 2617 2618 if (master && !IsMaster(master)) /* can't attach to slaves */ 2619 return BadDevice; 2620 2621 /* set from floating to floating? */ 2622 if (IsFloating(dev) && !master && dev->enabled) 2623 return Success; 2624 2625 /* free the existing sprite. */ 2626 if (IsFloating(dev) && dev->spriteInfo->paired == dev) { 2627 screen = miPointerGetScreen(dev); 2628 screen->DeviceCursorCleanup(dev, screen); 2629 free(dev->spriteInfo->sprite); 2630 } 2631 2632 dev->master = master; 2633 2634 /* If device is set to floating, we need to create a sprite for it, 2635 * otherwise things go bad. However, we don't want to render the cursor, 2636 * so we reset spriteOwner. 2637 * Sprite has to be forced to NULL first, otherwise InitializeSprite won't 2638 * alloc new memory but overwrite the previous one. 2639 */ 2640 if (!master) { 2641 WindowPtr currentRoot; 2642 2643 if (dev->spriteInfo->sprite) 2644 currentRoot = GetCurrentRootWindow(dev); 2645 else /* new device auto-set to floating */ 2646 currentRoot = screenInfo.screens[0]->root; 2647 2648 /* we need to init a fake sprite */ 2649 screen = currentRoot->drawable.pScreen; 2650 screen->DeviceCursorInitialize(dev, screen); 2651 dev->spriteInfo->sprite = NULL; 2652 InitializeSprite(dev, currentRoot); 2653 dev->spriteInfo->spriteOwner = FALSE; 2654 dev->spriteInfo->paired = dev; 2655 } 2656 else { 2657 dev->spriteInfo->sprite = master->spriteInfo->sprite; 2658 dev->spriteInfo->paired = master; 2659 dev->spriteInfo->spriteOwner = FALSE; 2660 2661 XkbPushLockedStateToSlaves(GetMaster(dev, MASTER_KEYBOARD), 0, 0); 2662 RecalculateMasterButtons(master); 2663 } 2664 2665 /* XXX: in theory, the MD should change back to its old, original 2666 * classes when the last SD is detached. Thanks to the XTEST devices, 2667 * we'll always have an SD attached until the MD is removed. 2668 * So let's not worry about that. 2669 */ 2670 2671 return Success; 2672 } 2673 2674 /** 2675 * Return the device paired with the given device or NULL. 2676 * Returns the device paired with the parent master if the given device is a 2677 * slave device. 2678 */ 2679 DeviceIntPtr 2680 GetPairedDevice(DeviceIntPtr dev) 2681 { 2682 if (!IsMaster(dev) && !IsFloating(dev)) 2683 dev = GetMaster(dev, MASTER_ATTACHED); 2684 2685 return dev->spriteInfo? dev->spriteInfo->paired: NULL; 2686 } 2687 2688 /** 2689 * Returns the requested master for this device. 2690 * The return values are: 2691 * - MASTER_ATTACHED: the master for this device or NULL for a floating 2692 * slave. 2693 * - MASTER_KEYBOARD: the master keyboard for this device or NULL for a 2694 * floating slave 2695 * - MASTER_POINTER: the master pointer for this device or NULL for a 2696 * floating slave 2697 * - POINTER_OR_FLOAT: the master pointer for this device or the device for 2698 * a floating slave 2699 * - KEYBOARD_OR_FLOAT: the master keyboard for this device or the device for 2700 * a floating slave 2701 * 2702 * @param which ::MASTER_KEYBOARD or ::MASTER_POINTER, ::MASTER_ATTACHED, 2703 * ::POINTER_OR_FLOAT or ::KEYBOARD_OR_FLOAT. 2704 * @return The requested master device 2705 */ 2706 DeviceIntPtr 2707 GetMaster(DeviceIntPtr dev, int which) 2708 { 2709 DeviceIntPtr master; 2710 2711 if (IsMaster(dev)) 2712 master = dev; 2713 else { 2714 master = dev->master; 2715 if (!master && 2716 (which == POINTER_OR_FLOAT || which == KEYBOARD_OR_FLOAT)) 2717 return dev; 2718 } 2719 2720 if (master && which != MASTER_ATTACHED) { 2721 if (which == MASTER_KEYBOARD || which == KEYBOARD_OR_FLOAT) { 2722 if (master->type != MASTER_KEYBOARD) 2723 master = GetPairedDevice(master); 2724 } 2725 else { 2726 if (master->type != MASTER_POINTER) 2727 master = GetPairedDevice(master); 2728 } 2729 } 2730 2731 return master; 2732 } 2733 2734 /** 2735 * Create a new device pair (== one pointer, one keyboard device). 2736 * Only allocates the devices, you will need to call ActivateDevice() and 2737 * EnableDevice() manually. 2738 * Either a master or a slave device can be created depending on 2739 * the value for master. 2740 */ 2741 int 2742 AllocDevicePair(ClientPtr client, const char *name, 2743 DeviceIntPtr *ptr, 2744 DeviceIntPtr *keybd, 2745 DeviceProc ptr_proc, DeviceProc keybd_proc, Bool master) 2746 { 2747 DeviceIntPtr pointer; 2748 DeviceIntPtr keyboard; 2749 char *dev_name; 2750 2751 *ptr = *keybd = NULL; 2752 2753 XkbInitPrivates(); 2754 2755 pointer = AddInputDevice(client, ptr_proc, TRUE); 2756 2757 if (!pointer) 2758 return BadAlloc; 2759 2760 if (asprintf(&dev_name, "%s pointer", name) == -1) { 2761 RemoveDevice(pointer, FALSE); 2762 2763 return BadAlloc; 2764 } 2765 pointer->name = dev_name; 2766 2767 pointer->public.processInputProc = ProcessOtherEvent; 2768 pointer->public.realInputProc = ProcessOtherEvent; 2769 XkbSetExtension(pointer, ProcessPointerEvent); 2770 pointer->deviceGrab.ActivateGrab = ActivatePointerGrab; 2771 pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab; 2772 pointer->coreEvents = TRUE; 2773 pointer->spriteInfo->spriteOwner = TRUE; 2774 2775 pointer->lastSlave = NULL; 2776 pointer->last.slave = NULL; 2777 pointer->type = (master) ? MASTER_POINTER : SLAVE; 2778 2779 keyboard = AddInputDevice(client, keybd_proc, TRUE); 2780 if (!keyboard) { 2781 RemoveDevice(pointer, FALSE); 2782 2783 return BadAlloc; 2784 } 2785 2786 if (asprintf(&dev_name, "%s keyboard", name) == -1) { 2787 RemoveDevice(keyboard, FALSE); 2788 RemoveDevice(pointer, FALSE); 2789 2790 return BadAlloc; 2791 } 2792 keyboard->name = dev_name; 2793 2794 keyboard->public.processInputProc = ProcessOtherEvent; 2795 keyboard->public.realInputProc = ProcessOtherEvent; 2796 XkbSetExtension(keyboard, ProcessKeyboardEvent); 2797 keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab; 2798 keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; 2799 keyboard->coreEvents = TRUE; 2800 keyboard->spriteInfo->spriteOwner = FALSE; 2801 2802 keyboard->lastSlave = NULL; 2803 keyboard->last.slave = NULL; 2804 keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE; 2805 2806 /* The ClassesRec stores the device classes currently not used. */ 2807 if (IsMaster(pointer)) { 2808 pointer->unused_classes = calloc(1, sizeof(ClassesRec)); 2809 keyboard->unused_classes = calloc(1, sizeof(ClassesRec)); 2810 } 2811 2812 *ptr = pointer; 2813 2814 *keybd = keyboard; 2815 2816 return Success; 2817 } 2818 2819 /** 2820 * Return Relative or Absolute for the device. 2821 */ 2822 int 2823 valuator_get_mode(DeviceIntPtr dev, int axis) 2824 { 2825 return (dev->valuator->axes[axis].mode & DeviceMode); 2826 } 2827 2828 /** 2829 * Set the given mode for the axis. If axis is VALUATOR_MODE_ALL_AXES, then 2830 * set the mode for all axes. 2831 */ 2832 void 2833 valuator_set_mode(DeviceIntPtr dev, int axis, int mode) 2834 { 2835 if (axis != VALUATOR_MODE_ALL_AXES) 2836 dev->valuator->axes[axis].mode = mode; 2837 else { 2838 int i; 2839 2840 for (i = 0; i < dev->valuator->numAxes; i++) 2841 dev->valuator->axes[i].mode = mode; 2842 } 2843 } 2844 2845 void 2846 DeliverDeviceClassesChangedEvent(int sourceid, Time time) 2847 { 2848 DeviceIntPtr dev; 2849 int num_events = 0; 2850 InternalEvent dcce; 2851 2852 dixLookupDevice(&dev, sourceid, serverClient, DixWriteAccess); 2853 2854 if (!dev) 2855 return; 2856 2857 /* UpdateFromMaster generates at most one event */ 2858 UpdateFromMaster(&dcce, dev, DEVCHANGE_POINTER_EVENT, &num_events); 2859 BUG_WARN(num_events > 1); 2860 2861 if (num_events) { 2862 dcce.any.time = time; 2863 /* FIXME: This doesn't do anything */ 2864 dev->public.processInputProc(&dcce, dev); 2865 } 2866 }