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