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