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