devices.c revision 65b04b38
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 /* Float all SDs before closing them. Note that at this point resources 986 * (e.g. cursors) have been freed already, so we can't just call 987 * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master 988 * to NULL and pretend nothing happened. 989 */ 990 for (dev = inputInfo.devices; dev; dev = dev->next) 991 { 992 if (!IsMaster(dev) && dev->u.master) 993 dev->u.master = NULL; 994 } 995 996 CloseDeviceList(&inputInfo.devices); 997 CloseDeviceList(&inputInfo.off_devices); 998 999 CloseDevice(inputInfo.pointer); 1000 CloseDevice(inputInfo.keyboard); 1001 1002 inputInfo.devices = NULL; 1003 inputInfo.off_devices = NULL; 1004 inputInfo.keyboard = NULL; 1005 inputInfo.pointer = NULL; 1006 XkbDeleteRulesDflts(); 1007} 1008 1009/** 1010 * Remove the cursor sprite for all devices. This needs to be done before any 1011 * resources are freed or any device is deleted. 1012 */ 1013void 1014UndisplayDevices(void) 1015{ 1016 DeviceIntPtr dev; 1017 ScreenPtr screen = screenInfo.screens[0]; 1018 1019 for (dev = inputInfo.devices; dev; dev = dev->next) 1020 screen->DisplayCursor(dev, screen, NullCursor); 1021} 1022 1023/** 1024 * Remove a device from the device list, closes it and thus frees all 1025 * resources. 1026 * Removes both enabled and disabled devices and notifies all devices about 1027 * the removal of the device. 1028 * 1029 * No PresenceNotify is sent for device that the client never saw. This can 1030 * happen if a malloc fails during the addition of master devices. If 1031 * dev->init is FALSE it means the client never received a DeviceAdded event, 1032 * so let's not send a DeviceRemoved event either. 1033 * 1034 * @param sendevent True if an XI2 event should be sent. 1035 */ 1036int 1037RemoveDevice(DeviceIntPtr dev, BOOL sendevent) 1038{ 1039 DeviceIntPtr prev,tmp,next; 1040 int ret = BadMatch; 1041 ScreenPtr screen = screenInfo.screens[0]; 1042 int deviceid; 1043 int initialized; 1044 int flags[MAXDEVICES] = {0}; 1045 1046 DebugF("(dix) removing device %d\n", dev->id); 1047 1048 if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer) 1049 return BadImplementation; 1050 1051 initialized = dev->inited; 1052 deviceid = dev->id; 1053 1054 if (initialized) 1055 { 1056 if (DevHasCursor(dev)) 1057 screen->DisplayCursor(dev, screen, NullCursor); 1058 1059 DisableDevice(dev, sendevent); 1060 flags[dev->id] = XIDeviceDisabled; 1061 } 1062 1063 prev = NULL; 1064 for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) { 1065 next = tmp->next; 1066 if (tmp == dev) { 1067 1068 if (prev==NULL) 1069 inputInfo.devices = next; 1070 else 1071 prev->next = next; 1072 1073 flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; 1074 CloseDevice(tmp); 1075 ret = Success; 1076 } 1077 } 1078 1079 prev = NULL; 1080 for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) { 1081 next = tmp->next; 1082 if (tmp == dev) { 1083 flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; 1084 CloseDevice(tmp); 1085 1086 if (prev == NULL) 1087 inputInfo.off_devices = next; 1088 else 1089 prev->next = next; 1090 1091 ret = Success; 1092 } 1093 } 1094 1095 if (ret == Success && initialized) { 1096 inputInfo.numDevices--; 1097 SendDevicePresenceEvent(deviceid, DeviceRemoved); 1098 if (sendevent) 1099 XISendDeviceHierarchyEvent(flags); 1100 } 1101 1102 return ret; 1103} 1104 1105int 1106NumMotionEvents(void) 1107{ 1108 /* only called to fill data in initial connection reply. 1109 * VCP is ok here, it is the only fixed device we have. */ 1110 return inputInfo.pointer->valuator->numMotionEvents; 1111} 1112 1113int 1114dixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode) 1115{ 1116 DeviceIntPtr dev; 1117 int rc; 1118 *pDev = NULL; 1119 1120 for (dev=inputInfo.devices; dev; dev=dev->next) { 1121 if (dev->id == id) 1122 goto found; 1123 } 1124 for (dev=inputInfo.off_devices; dev; dev=dev->next) { 1125 if (dev->id == id) 1126 goto found; 1127 } 1128 return BadDevice; 1129 1130found: 1131 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 1132 if (rc == Success) 1133 *pDev = dev; 1134 return rc; 1135} 1136 1137void 1138QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode) 1139{ 1140 if (inputInfo.keyboard) { 1141 *minCode = inputInfo.keyboard->key->xkbInfo->desc->min_key_code; 1142 *maxCode = inputInfo.keyboard->key->xkbInfo->desc->max_key_code; 1143 } 1144} 1145 1146/* Notably, this function does not expand the destination's keycode range, or 1147 * notify clients. */ 1148Bool 1149SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src) 1150{ 1151 int i, j; 1152 KeySym *tmp; 1153 int rowDif = src->minKeyCode - dst->minKeyCode; 1154 1155 /* if keysym map size changes, grow map first */ 1156 if (src->mapWidth < dst->mapWidth) { 1157 for (i = src->minKeyCode; i <= src->maxKeyCode; i++) { 1158#define SI(r, c) (((r - src->minKeyCode) * src->mapWidth) + (c)) 1159#define DI(r, c) (((r - dst->minKeyCode) * dst->mapWidth) + (c)) 1160 for (j = 0; j < src->mapWidth; j++) 1161 dst->map[DI(i, j)] = src->map[SI(i, j)]; 1162 for (j = src->mapWidth; j < dst->mapWidth; j++) 1163 dst->map[DI(i, j)] = NoSymbol; 1164#undef SI 1165#undef DI 1166 } 1167 return TRUE; 1168 } 1169 else if (src->mapWidth > dst->mapWidth) { 1170 i = sizeof(KeySym) * src->mapWidth * 1171 (dst->maxKeyCode - dst->minKeyCode + 1); 1172 tmp = calloc(sizeof(KeySym), i); 1173 if (!tmp) 1174 return FALSE; 1175 1176 if (dst->map) { 1177 for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++) 1178 memmove(&tmp[i * src->mapWidth], &dst->map[i * dst->mapWidth], 1179 dst->mapWidth * sizeof(KeySym)); 1180 free(dst->map); 1181 } 1182 dst->mapWidth = src->mapWidth; 1183 dst->map = tmp; 1184 } 1185 else if (!dst->map) { 1186 i = sizeof(KeySym) * src->mapWidth * 1187 (dst->maxKeyCode - dst->minKeyCode + 1); 1188 tmp = calloc(sizeof(KeySym), i); 1189 if (!tmp) 1190 return FALSE; 1191 1192 dst->map = tmp; 1193 dst->mapWidth = src->mapWidth; 1194 } 1195 1196 memmove(&dst->map[rowDif * dst->mapWidth], src->map, 1197 (src->maxKeyCode - src->minKeyCode + 1) * 1198 dst->mapWidth * sizeof(KeySym)); 1199 1200 return TRUE; 1201} 1202 1203Bool 1204InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom* labels, 1205 CARD8 *map) 1206{ 1207 ButtonClassPtr butc; 1208 int i; 1209 1210 butc = calloc(1, sizeof(ButtonClassRec)); 1211 if (!butc) 1212 return FALSE; 1213 butc->numButtons = numButtons; 1214 butc->sourceid = dev->id; 1215 for (i = 1; i <= numButtons; i++) 1216 butc->map[i] = map[i]; 1217 for (i = numButtons + 1; i < MAP_LENGTH; i++) 1218 butc->map[i] = i; 1219 memcpy(butc->labels, labels, numButtons * sizeof(Atom)); 1220 dev->button = butc; 1221 return TRUE; 1222} 1223 1224/** 1225 * Allocate a valuator class and set up the pointers for the axis values 1226 * appropriately. 1227 * 1228 * @param src If non-NULL, the memory is reallocated from src. If NULL, the 1229 * memory is calloc'd. 1230 * @parma numAxes Number of axes to allocate. 1231 * @return The allocated valuator struct. 1232 */ 1233ValuatorClassPtr 1234AllocValuatorClass(ValuatorClassPtr src, int numAxes) 1235{ 1236 ValuatorClassPtr v; 1237 /* force alignment with double */ 1238 union align_u { ValuatorClassRec valc; double d; } *align; 1239 int size; 1240 1241 size = sizeof(union align_u) + numAxes * (sizeof(double) + sizeof(AxisInfo)); 1242 align = (union align_u *) realloc(src, size); 1243 1244 if (!align) 1245 return NULL; 1246 1247 if (!src) 1248 memset(align, 0, size); 1249 1250 v = &align->valc; 1251 v->numAxes = numAxes; 1252 v->axisVal = (double*)(align + 1); 1253 v->axes = (AxisInfoPtr)(v->axisVal + numAxes); 1254 1255 return v; 1256} 1257 1258Bool 1259InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, 1260 int numMotionEvents, int mode) 1261{ 1262 int i; 1263 ValuatorClassPtr valc; 1264 1265 if (!dev) 1266 return FALSE; 1267 1268 if (numAxes > MAX_VALUATORS) 1269 { 1270 LogMessage(X_WARNING, 1271 "Device '%s' has %d axes, only using first %d.\n", 1272 dev->name, numAxes, MAX_VALUATORS); 1273 numAxes = MAX_VALUATORS; 1274 } 1275 1276 valc = AllocValuatorClass(NULL, numAxes); 1277 if (!valc) 1278 return FALSE; 1279 1280 valc->sourceid = dev->id; 1281 valc->motion = NULL; 1282 valc->first_motion = 0; 1283 valc->last_motion = 0; 1284 1285 valc->numMotionEvents = numMotionEvents; 1286 valc->motionHintWindow = NullWindow; 1287 1288 if (mode & OutOfProximity) 1289 InitProximityClassDeviceStruct(dev); 1290 1291 dev->valuator = valc; 1292 1293 AllocateMotionHistory(dev); 1294 1295 for (i=0; i<numAxes; i++) { 1296 InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1297 0, 0, 0, mode); 1298 valc->axisVal[i]=0; 1299 } 1300 1301 dev->last.numValuators = numAxes; 1302 1303 if (IsMaster(dev) || /* do not accelerate master or xtest devices */ 1304 IsXTestDevice(dev, NULL)) 1305 InitPointerAccelerationScheme(dev, PtrAccelNoOp); 1306 else 1307 InitPointerAccelerationScheme(dev, PtrAccelDefault); 1308 return TRUE; 1309} 1310 1311/* global list of acceleration schemes */ 1312ValuatorAccelerationRec pointerAccelerationScheme[] = { 1313 {PtrAccelNoOp, NULL, NULL, NULL}, 1314 {PtrAccelPredictable, acceleratePointerPredictable, NULL, AccelerationDefaultCleanup}, 1315 {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL}, 1316 {-1, NULL, NULL, NULL} /* terminator */ 1317}; 1318 1319/** 1320 * install an acceleration scheme. returns TRUE on success, and should not 1321 * change anything if unsuccessful. 1322 */ 1323Bool 1324InitPointerAccelerationScheme(DeviceIntPtr dev, 1325 int scheme) 1326{ 1327 int x, i = -1; 1328 void* data = NULL; 1329 ValuatorClassPtr val; 1330 1331 val = dev->valuator; 1332 1333 if(!val) 1334 return FALSE; 1335 1336 if(IsMaster(dev) && scheme != PtrAccelNoOp) 1337 return FALSE; 1338 1339 for(x = 0; pointerAccelerationScheme[x].number >= 0; x++) { 1340 if(pointerAccelerationScheme[x].number == scheme){ 1341 i = x; 1342 break; 1343 } 1344 } 1345 1346 if(-1 == i) 1347 return FALSE; 1348 1349 if (val->accelScheme.AccelCleanupProc) 1350 val->accelScheme.AccelCleanupProc(dev); 1351 1352 /* init scheme-specific data */ 1353 switch(scheme){ 1354 case PtrAccelPredictable: 1355 { 1356 DeviceVelocityPtr s; 1357 s = malloc(sizeof(DeviceVelocityRec)); 1358 if(!s) 1359 return FALSE; 1360 InitVelocityData(s); 1361 data = s; 1362 break; 1363 } 1364 default: 1365 break; 1366 } 1367 1368 val->accelScheme = pointerAccelerationScheme[i]; 1369 val->accelScheme.accelData = data; 1370 1371 /* post-init scheme */ 1372 switch(scheme){ 1373 case PtrAccelPredictable: 1374 InitializePredictableAccelerationProperties(dev); 1375 break; 1376 1377 default: 1378 break; 1379 } 1380 1381 return TRUE; 1382} 1383 1384Bool 1385InitAbsoluteClassDeviceStruct(DeviceIntPtr dev) 1386{ 1387 AbsoluteClassPtr abs; 1388 1389 abs = malloc(sizeof(AbsoluteClassRec)); 1390 if (!abs) 1391 return FALSE; 1392 1393 /* we don't do anything sensible with these, but should */ 1394 abs->min_x = NO_AXIS_LIMITS; 1395 abs->min_y = NO_AXIS_LIMITS; 1396 abs->max_x = NO_AXIS_LIMITS; 1397 abs->max_y = NO_AXIS_LIMITS; 1398 abs->flip_x = 0; 1399 abs->flip_y = 0; 1400 abs->rotation = 0; 1401 abs->button_threshold = 0; 1402 1403 abs->offset_x = 0; 1404 abs->offset_y = 0; 1405 abs->width = NO_AXIS_LIMITS; 1406 abs->height = NO_AXIS_LIMITS; 1407 abs->following = 0; 1408 abs->screen = 0; 1409 1410 abs->sourceid = dev->id; 1411 1412 dev->absolute = abs; 1413 1414 return TRUE; 1415} 1416 1417Bool 1418InitFocusClassDeviceStruct(DeviceIntPtr dev) 1419{ 1420 FocusClassPtr focc; 1421 1422 focc = malloc(sizeof(FocusClassRec)); 1423 if (!focc) 1424 return FALSE; 1425 focc->win = PointerRootWin; 1426 focc->revert = None; 1427 focc->time = currentTime; 1428 focc->trace = (WindowPtr *)NULL; 1429 focc->traceSize = 0; 1430 focc->traceGood = 0; 1431 focc->sourceid = dev->id; 1432 dev->focus = focc; 1433 return TRUE; 1434} 1435 1436Bool 1437InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc) 1438{ 1439 PtrFeedbackPtr feedc; 1440 1441 feedc = malloc(sizeof(PtrFeedbackClassRec)); 1442 if (!feedc) 1443 return FALSE; 1444 feedc->CtrlProc = controlProc; 1445 feedc->ctrl = defaultPointerControl; 1446 feedc->ctrl.id = 0; 1447 if ( (feedc->next = dev->ptrfeed) ) 1448 feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1; 1449 dev->ptrfeed = feedc; 1450 (*controlProc)(dev, &feedc->ctrl); 1451 return TRUE; 1452} 1453 1454 1455static LedCtrl defaultLedControl = { 1456 DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0}; 1457 1458static BellCtrl defaultBellControl = { 1459 DEFAULT_BELL, 1460 DEFAULT_BELL_PITCH, 1461 DEFAULT_BELL_DURATION, 1462 0}; 1463 1464static IntegerCtrl defaultIntegerControl = { 1465 DEFAULT_INT_RESOLUTION, 1466 DEFAULT_INT_MIN_VALUE, 1467 DEFAULT_INT_MAX_VALUE, 1468 DEFAULT_INT_DISPLAYED, 1469 0}; 1470 1471Bool 1472InitStringFeedbackClassDeviceStruct ( 1473 DeviceIntPtr dev, StringCtrlProcPtr controlProc, 1474 int max_symbols, int num_symbols_supported, KeySym *symbols) 1475{ 1476 int i; 1477 StringFeedbackPtr feedc; 1478 1479 feedc = malloc(sizeof(StringFeedbackClassRec)); 1480 if (!feedc) 1481 return FALSE; 1482 feedc->CtrlProc = controlProc; 1483 feedc->ctrl.num_symbols_supported = num_symbols_supported; 1484 feedc->ctrl.num_symbols_displayed = 0; 1485 feedc->ctrl.max_symbols = max_symbols; 1486 feedc->ctrl.symbols_supported = malloc(sizeof (KeySym) * num_symbols_supported); 1487 feedc->ctrl.symbols_displayed = malloc(sizeof (KeySym) * max_symbols); 1488 if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed) 1489 { 1490 free(feedc->ctrl.symbols_supported); 1491 free(feedc->ctrl.symbols_displayed); 1492 free(feedc); 1493 return FALSE; 1494 } 1495 for (i=0; i<num_symbols_supported; i++) 1496 *(feedc->ctrl.symbols_supported+i) = *symbols++; 1497 for (i=0; i<max_symbols; i++) 1498 *(feedc->ctrl.symbols_displayed+i) = (KeySym) 0; 1499 feedc->ctrl.id = 0; 1500 if ( (feedc->next = dev->stringfeed) ) 1501 feedc->ctrl.id = dev->stringfeed->ctrl.id + 1; 1502 dev->stringfeed = feedc; 1503 (*controlProc)(dev, &feedc->ctrl); 1504 return TRUE; 1505} 1506 1507Bool 1508InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc, 1509 BellCtrlProcPtr controlProc) 1510{ 1511 BellFeedbackPtr feedc; 1512 1513 feedc = malloc(sizeof(BellFeedbackClassRec)); 1514 if (!feedc) 1515 return FALSE; 1516 feedc->CtrlProc = controlProc; 1517 feedc->BellProc = bellProc; 1518 feedc->ctrl = defaultBellControl; 1519 feedc->ctrl.id = 0; 1520 if ( (feedc->next = dev->bell) ) 1521 feedc->ctrl.id = dev->bell->ctrl.id + 1; 1522 dev->bell = feedc; 1523 (*controlProc)(dev, &feedc->ctrl); 1524 return TRUE; 1525} 1526 1527Bool 1528InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc) 1529{ 1530 LedFeedbackPtr feedc; 1531 1532 feedc = malloc(sizeof(LedFeedbackClassRec)); 1533 if (!feedc) 1534 return FALSE; 1535 feedc->CtrlProc = controlProc; 1536 feedc->ctrl = defaultLedControl; 1537 feedc->ctrl.id = 0; 1538 if ( (feedc->next = dev->leds) ) 1539 feedc->ctrl.id = dev->leds->ctrl.id + 1; 1540 feedc->xkb_sli= NULL; 1541 dev->leds = feedc; 1542 (*controlProc)(dev, &feedc->ctrl); 1543 return TRUE; 1544} 1545 1546Bool 1547InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr controlProc) 1548{ 1549 IntegerFeedbackPtr feedc; 1550 1551 feedc = malloc(sizeof(IntegerFeedbackClassRec)); 1552 if (!feedc) 1553 return FALSE; 1554 feedc->CtrlProc = controlProc; 1555 feedc->ctrl = defaultIntegerControl; 1556 feedc->ctrl.id = 0; 1557 if ( (feedc->next = dev->intfeed) ) 1558 feedc->ctrl.id = dev->intfeed->ctrl.id + 1; 1559 dev->intfeed = feedc; 1560 (*controlProc)(dev, &feedc->ctrl); 1561 return TRUE; 1562} 1563 1564Bool 1565InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons, Atom* btn_labels, 1566 PtrCtrlProcPtr controlProc, int numMotionEvents, 1567 int numAxes, Atom *axes_labels) 1568{ 1569 DeviceIntPtr dev = (DeviceIntPtr)device; 1570 1571 return(InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) && 1572 InitValuatorClassDeviceStruct(dev, numAxes, axes_labels, 1573 numMotionEvents, Relative) && 1574 InitPtrFeedbackClassDeviceStruct(dev, controlProc)); 1575} 1576 1577/* 1578 * Check if the given buffer contains elements between low (inclusive) and 1579 * high (inclusive) only. 1580 * 1581 * @return TRUE if the device map is invalid, FALSE otherwise. 1582 */ 1583Bool 1584BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval) 1585{ 1586 int i; 1587 1588 for (i = 0; i < length; i++) 1589 if (buff[i]) /* only check non-zero elements */ 1590 { 1591 if ((low > buff[i]) || (high < buff[i])) 1592 { 1593 *errval = buff[i]; 1594 return TRUE; 1595 } 1596 } 1597 return FALSE; 1598} 1599 1600int 1601ProcSetModifierMapping(ClientPtr client) 1602{ 1603 xSetModifierMappingReply rep; 1604 int rc; 1605 REQUEST(xSetModifierMappingReq); 1606 REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq); 1607 1608 if (client->req_len != ((stuff->numKeyPerModifier << 1) + 1609 bytes_to_int32(sizeof(xSetModifierMappingReq)))) 1610 return BadLength; 1611 1612 rep.type = X_Reply; 1613 rep.length = 0; 1614 rep.sequenceNumber = client->sequence; 1615 1616 rc = change_modmap(client, PickKeyboard(client), (KeyCode *)&stuff[1], 1617 stuff->numKeyPerModifier); 1618 if (rc == MappingFailed || rc == -1) 1619 return BadValue; 1620 if (rc != Success && rc != MappingSuccess && rc != MappingFailed && 1621 rc != MappingBusy) 1622 return rc; 1623 1624 rep.success = rc; 1625 1626 WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep); 1627 return Success; 1628} 1629 1630int 1631ProcGetModifierMapping(ClientPtr client) 1632{ 1633 xGetModifierMappingReply rep; 1634 int max_keys_per_mod = 0; 1635 KeyCode *modkeymap = NULL; 1636 REQUEST_SIZE_MATCH(xReq); 1637 1638 generate_modkeymap(client, PickKeyboard(client), &modkeymap, 1639 &max_keys_per_mod); 1640 1641 memset(&rep, 0, sizeof(xGetModifierMappingReply)); 1642 rep.type = X_Reply; 1643 rep.numKeyPerModifier = max_keys_per_mod; 1644 rep.sequenceNumber = client->sequence; 1645 /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */ 1646 rep.length = max_keys_per_mod << 1; 1647 1648 WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep); 1649 (void)WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap); 1650 1651 free(modkeymap); 1652 1653 return Success; 1654} 1655 1656int 1657ProcChangeKeyboardMapping(ClientPtr client) 1658{ 1659 REQUEST(xChangeKeyboardMappingReq); 1660 unsigned len; 1661 KeySymsRec keysyms; 1662 DeviceIntPtr pDev, tmp; 1663 int rc; 1664 REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq); 1665 1666 len = client->req_len - bytes_to_int32(sizeof(xChangeKeyboardMappingReq)); 1667 if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode)) 1668 return BadLength; 1669 1670 pDev = PickKeyboard(client); 1671 1672 if ((stuff->firstKeyCode < pDev->key->xkbInfo->desc->min_key_code) || 1673 (stuff->firstKeyCode > pDev->key->xkbInfo->desc->max_key_code)) { 1674 client->errorValue = stuff->firstKeyCode; 1675 return BadValue; 1676 1677 } 1678 if (((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) > 1679 pDev->key->xkbInfo->desc->max_key_code) || 1680 (stuff->keySymsPerKeyCode == 0)) { 1681 client->errorValue = stuff->keySymsPerKeyCode; 1682 return BadValue; 1683 } 1684 1685 keysyms.minKeyCode = stuff->firstKeyCode; 1686 keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1; 1687 keysyms.mapWidth = stuff->keySymsPerKeyCode; 1688 keysyms.map = (KeySym *) &stuff[1]; 1689 1690 rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); 1691 if (rc != Success) 1692 return rc; 1693 1694 XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode, 1695 stuff->keyCodes, NULL, client); 1696 1697 for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { 1698 if (IsMaster(tmp) || tmp->u.master != pDev) 1699 continue; 1700 if (!tmp->key) 1701 continue; 1702 1703 rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); 1704 if (rc != Success) 1705 continue; 1706 1707 XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode, 1708 stuff->keyCodes, NULL, client); 1709 } 1710 1711 return Success; 1712} 1713 1714int 1715ProcSetPointerMapping(ClientPtr client) 1716{ 1717 BYTE *map; 1718 int ret; 1719 int i, j; 1720 DeviceIntPtr ptr = PickPointer(client); 1721 xSetPointerMappingReply rep; 1722 REQUEST(xSetPointerMappingReq); 1723 REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq); 1724 1725 if (client->req_len != 1726 bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts)) 1727 return BadLength; 1728 rep.type = X_Reply; 1729 rep.length = 0; 1730 rep.sequenceNumber = client->sequence; 1731 rep.success = MappingSuccess; 1732 map = (BYTE *)&stuff[1]; 1733 1734 /* So we're bounded here by the number of core buttons. This check 1735 * probably wants disabling through XFixes. */ 1736 /* MPX: With ClientPointer, we can return the right number of buttons. 1737 * Let's just hope nobody changed ClientPointer between GetPointerMapping 1738 * and SetPointerMapping 1739 */ 1740 if (stuff->nElts != ptr->button->numButtons) { 1741 client->errorValue = stuff->nElts; 1742 return BadValue; 1743 } 1744 1745 /* Core protocol specs don't allow for duplicate mappings; this check 1746 * almost certainly wants disabling through XFixes too. */ 1747 for (i = 0; i < stuff->nElts; i++) { 1748 for (j = i + 1; j < stuff->nElts; j++) { 1749 if (map[i] && map[i] == map[j]) { 1750 client->errorValue = map[i]; 1751 return BadValue; 1752 } 1753 } 1754 } 1755 1756 ret = ApplyPointerMapping(ptr, map, stuff->nElts, client); 1757 if (ret == MappingBusy) 1758 rep.success = ret; 1759 else if (ret == -1) 1760 return BadValue; 1761 else if (ret != Success) 1762 return ret; 1763 1764 WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep); 1765 return Success; 1766} 1767 1768int 1769ProcGetKeyboardMapping(ClientPtr client) 1770{ 1771 xGetKeyboardMappingReply rep; 1772 DeviceIntPtr kbd = PickKeyboard(client); 1773 XkbDescPtr xkb; 1774 KeySymsPtr syms; 1775 int rc; 1776 REQUEST(xGetKeyboardMappingReq); 1777 REQUEST_SIZE_MATCH(xGetKeyboardMappingReq); 1778 1779 rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess); 1780 if (rc != Success) 1781 return rc; 1782 1783 xkb = kbd->key->xkbInfo->desc; 1784 1785 if ((stuff->firstKeyCode < xkb->min_key_code) || 1786 (stuff->firstKeyCode > xkb->max_key_code)) { 1787 client->errorValue = stuff->firstKeyCode; 1788 return BadValue; 1789 } 1790 if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) { 1791 client->errorValue = stuff->count; 1792 return BadValue; 1793 } 1794 1795 syms = XkbGetCoreMap(kbd); 1796 if (!syms) 1797 return BadAlloc; 1798 1799 memset(&rep, 0, sizeof(xGetKeyboardMappingReply)); 1800 rep.type = X_Reply; 1801 rep.sequenceNumber = client->sequence; 1802 rep.keySymsPerKeyCode = syms->mapWidth; 1803 /* length is a count of 4 byte quantities and KeySyms are 4 bytes */ 1804 rep.length = syms->mapWidth * stuff->count; 1805 WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep); 1806 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write; 1807 WriteSwappedDataToClient(client, 1808 syms->mapWidth * stuff->count * sizeof(KeySym), 1809 &syms->map[syms->mapWidth * (stuff->firstKeyCode - 1810 syms->minKeyCode)]); 1811 free(syms->map); 1812 free(syms); 1813 1814 return Success; 1815} 1816 1817int 1818ProcGetPointerMapping(ClientPtr client) 1819{ 1820 xGetPointerMappingReply rep; 1821 /* Apps may get different values each time they call GetPointerMapping as 1822 * the ClientPointer could change. */ 1823 DeviceIntPtr ptr = PickPointer(client); 1824 ButtonClassPtr butc = ptr->button; 1825 int rc; 1826 REQUEST_SIZE_MATCH(xReq); 1827 1828 rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess); 1829 if (rc != Success) 1830 return rc; 1831 1832 rep.type = X_Reply; 1833 rep.sequenceNumber = client->sequence; 1834 rep.nElts = (butc) ? butc->numButtons : 0; 1835 rep.length = ((unsigned)rep.nElts + (4-1))/4; 1836 WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep); 1837 if (butc) 1838 WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]); 1839 return Success; 1840} 1841 1842void 1843NoteLedState(DeviceIntPtr keybd, int led, Bool on) 1844{ 1845 KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl; 1846 if (on) 1847 ctrl->leds |= ((Leds)1 << (led - 1)); 1848 else 1849 ctrl->leds &= ~((Leds)1 << (led - 1)); 1850} 1851 1852int 1853Ones(unsigned long mask) /* HACKMEM 169 */ 1854{ 1855 unsigned long y; 1856 1857 y = (mask >> 1) &033333333333; 1858 y = mask - y - ((y >>1) & 033333333333); 1859 return (((y + (y >> 3)) & 030707070707) % 077); 1860} 1861 1862static int 1863DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist, 1864 BITS32 vmask) 1865{ 1866#define DO_ALL (-1) 1867 KeybdCtrl ctrl; 1868 int t; 1869 int led = DO_ALL; 1870 int key = DO_ALL; 1871 BITS32 index2; 1872 int mask = vmask, i; 1873 XkbEventCauseRec cause; 1874 1875 ctrl = keybd->kbdfeed->ctrl; 1876 while (vmask) { 1877 index2 = (BITS32) lowbit (vmask); 1878 vmask &= ~index2; 1879 switch (index2) { 1880 case KBKeyClickPercent: 1881 t = (INT8)*vlist; 1882 vlist++; 1883 if (t == -1) { 1884 t = defaultKeyboardControl.click; 1885 } 1886 else if (t < 0 || t > 100) { 1887 client->errorValue = t; 1888 return BadValue; 1889 } 1890 ctrl.click = t; 1891 break; 1892 case KBBellPercent: 1893 t = (INT8)*vlist; 1894 vlist++; 1895 if (t == -1) { 1896 t = defaultKeyboardControl.bell; 1897 } 1898 else if (t < 0 || t > 100) { 1899 client->errorValue = t; 1900 return BadValue; 1901 } 1902 ctrl.bell = t; 1903 break; 1904 case KBBellPitch: 1905 t = (INT16)*vlist; 1906 vlist++; 1907 if (t == -1) { 1908 t = defaultKeyboardControl.bell_pitch; 1909 } 1910 else if (t < 0) { 1911 client->errorValue = t; 1912 return BadValue; 1913 } 1914 ctrl.bell_pitch = t; 1915 break; 1916 case KBBellDuration: 1917 t = (INT16)*vlist; 1918 vlist++; 1919 if (t == -1) 1920 t = defaultKeyboardControl.bell_duration; 1921 else if (t < 0) { 1922 client->errorValue = t; 1923 return BadValue; 1924 } 1925 ctrl.bell_duration = t; 1926 break; 1927 case KBLed: 1928 led = (CARD8)*vlist; 1929 vlist++; 1930 if (led < 1 || led > 32) { 1931 client->errorValue = led; 1932 return BadValue; 1933 } 1934 if (!(mask & KBLedMode)) 1935 return BadMatch; 1936 break; 1937 case KBLedMode: 1938 t = (CARD8)*vlist; 1939 vlist++; 1940 if (t == LedModeOff) { 1941 if (led == DO_ALL) 1942 ctrl.leds = 0x0; 1943 else 1944 ctrl.leds &= ~(((Leds)(1)) << (led - 1)); 1945 } 1946 else if (t == LedModeOn) { 1947 if (led == DO_ALL) 1948 ctrl.leds = ~0L; 1949 else 1950 ctrl.leds |= (((Leds)(1)) << (led - 1)); 1951 } 1952 else { 1953 client->errorValue = t; 1954 return BadValue; 1955 } 1956 1957 XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client); 1958 XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))), 1959 ctrl.leds, &cause); 1960 ctrl.leds = keybd->kbdfeed->ctrl.leds; 1961 1962 break; 1963 case KBKey: 1964 key = (KeyCode)*vlist; 1965 vlist++; 1966 if ((KeyCode)key < keybd->key->xkbInfo->desc->min_key_code || 1967 (KeyCode)key > keybd->key->xkbInfo->desc->max_key_code) { 1968 client->errorValue = key; 1969 return BadValue; 1970 } 1971 if (!(mask & KBAutoRepeatMode)) 1972 return BadMatch; 1973 break; 1974 case KBAutoRepeatMode: 1975 i = (key >> 3); 1976 mask = (1 << (key & 7)); 1977 t = (CARD8)*vlist; 1978 vlist++; 1979 if (key != DO_ALL) 1980 XkbDisableComputedAutoRepeats(keybd,key); 1981 if (t == AutoRepeatModeOff) { 1982 if (key == DO_ALL) 1983 ctrl.autoRepeat = FALSE; 1984 else 1985 ctrl.autoRepeats[i] &= ~mask; 1986 } 1987 else if (t == AutoRepeatModeOn) { 1988 if (key == DO_ALL) 1989 ctrl.autoRepeat = TRUE; 1990 else 1991 ctrl.autoRepeats[i] |= mask; 1992 } 1993 else if (t == AutoRepeatModeDefault) { 1994 if (key == DO_ALL) 1995 ctrl.autoRepeat = defaultKeyboardControl.autoRepeat; 1996 else 1997 ctrl.autoRepeats[i] = 1998 (ctrl.autoRepeats[i] & ~mask) | 1999 (defaultKeyboardControl.autoRepeats[i] & mask); 2000 } 2001 else { 2002 client->errorValue = t; 2003 return BadValue; 2004 } 2005 break; 2006 default: 2007 client->errorValue = mask; 2008 return BadValue; 2009 } 2010 } 2011 keybd->kbdfeed->ctrl = ctrl; 2012 2013 /* The XKB RepeatKeys control and core protocol global autorepeat */ 2014 /* value are linked */ 2015 XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat); 2016 2017 return Success; 2018 2019#undef DO_ALL 2020} 2021 2022/** 2023 * Changes kbd control on the ClientPointer and all attached SDs. 2024 */ 2025int 2026ProcChangeKeyboardControl (ClientPtr client) 2027{ 2028 XID *vlist; 2029 BITS32 vmask; 2030 int ret = Success, error = Success; 2031 DeviceIntPtr pDev = NULL, keyboard; 2032 REQUEST(xChangeKeyboardControlReq); 2033 2034 REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq); 2035 2036 vmask = stuff->mask; 2037 vlist = (XID *)&stuff[1]; 2038 2039 if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask)) 2040 return BadLength; 2041 2042 keyboard = PickKeyboard(client); 2043 2044 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 2045 if ((pDev == keyboard || 2046 (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard)) 2047 && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { 2048 ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); 2049 if (ret != Success) 2050 return ret; 2051 } 2052 } 2053 2054 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 2055 if ((pDev == keyboard || 2056 (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard)) 2057 && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { 2058 ret = DoChangeKeyboardControl(client, pDev, vlist, vmask); 2059 if (ret != Success) 2060 error = ret; 2061 } 2062 } 2063 2064 return error; 2065} 2066 2067int 2068ProcGetKeyboardControl (ClientPtr client) 2069{ 2070 int rc, i; 2071 DeviceIntPtr kbd = PickKeyboard(client); 2072 KeybdCtrl *ctrl = &kbd->kbdfeed->ctrl; 2073 xGetKeyboardControlReply rep; 2074 REQUEST_SIZE_MATCH(xReq); 2075 2076 rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess); 2077 if (rc != Success) 2078 return rc; 2079 2080 rep.type = X_Reply; 2081 rep.length = 5; 2082 rep.sequenceNumber = client->sequence; 2083 rep.globalAutoRepeat = ctrl->autoRepeat; 2084 rep.keyClickPercent = ctrl->click; 2085 rep.bellPercent = ctrl->bell; 2086 rep.bellPitch = ctrl->bell_pitch; 2087 rep.bellDuration = ctrl->bell_duration; 2088 rep.ledMask = ctrl->leds; 2089 for (i = 0; i < 32; i++) 2090 rep.map[i] = ctrl->autoRepeats[i]; 2091 WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep); 2092 return Success; 2093} 2094 2095int 2096ProcBell(ClientPtr client) 2097{ 2098 DeviceIntPtr dev, keybd = PickKeyboard(client); 2099 int base = keybd->kbdfeed->ctrl.bell; 2100 int newpercent; 2101 int rc; 2102 REQUEST(xBellReq); 2103 REQUEST_SIZE_MATCH(xBellReq); 2104 2105 if (stuff->percent < -100 || stuff->percent > 100) { 2106 client->errorValue = stuff->percent; 2107 return BadValue; 2108 } 2109 2110 newpercent = (base * stuff->percent) / 100; 2111 if (stuff->percent < 0) 2112 newpercent = base + newpercent; 2113 else 2114 newpercent = base - newpercent + stuff->percent; 2115 2116 for (dev = inputInfo.devices; dev; dev = dev->next) { 2117 if ((dev == keybd || 2118 (!IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == keybd)) && 2119 dev->kbdfeed && dev->kbdfeed->BellProc) { 2120 2121 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess); 2122 if (rc != Success) 2123 return rc; 2124 XkbHandleBell(FALSE, FALSE, dev, newpercent, 2125 &dev->kbdfeed->ctrl, 0, None, NULL, client); 2126 } 2127 } 2128 2129 return Success; 2130} 2131 2132int 2133ProcChangePointerControl(ClientPtr client) 2134{ 2135 DeviceIntPtr dev, mouse = PickPointer(client); 2136 PtrCtrl ctrl; /* might get BadValue part way through */ 2137 int rc; 2138 REQUEST(xChangePointerControlReq); 2139 REQUEST_SIZE_MATCH(xChangePointerControlReq); 2140 2141 ctrl = mouse->ptrfeed->ctrl; 2142 if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) { 2143 client->errorValue = stuff->doAccel; 2144 return BadValue; 2145 } 2146 if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) { 2147 client->errorValue = stuff->doThresh; 2148 return BadValue; 2149 } 2150 if (stuff->doAccel) { 2151 if (stuff->accelNum == -1) { 2152 ctrl.num = defaultPointerControl.num; 2153 } 2154 else if (stuff->accelNum < 0) { 2155 client->errorValue = stuff->accelNum; 2156 return BadValue; 2157 } 2158 else { 2159 ctrl.num = stuff->accelNum; 2160 } 2161 2162 if (stuff->accelDenum == -1) { 2163 ctrl.den = defaultPointerControl.den; 2164 } 2165 else if (stuff->accelDenum <= 0) { 2166 client->errorValue = stuff->accelDenum; 2167 return BadValue; 2168 } 2169 else { 2170 ctrl.den = stuff->accelDenum; 2171 } 2172 } 2173 if (stuff->doThresh) { 2174 if (stuff->threshold == -1) { 2175 ctrl.threshold = defaultPointerControl.threshold; 2176 } 2177 else if (stuff->threshold < 0) { 2178 client->errorValue = stuff->threshold; 2179 return BadValue; 2180 } 2181 else { 2182 ctrl.threshold = stuff->threshold; 2183 } 2184 } 2185 2186 for (dev = inputInfo.devices; dev; dev = dev->next) { 2187 if ((dev == mouse || 2188 (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) && 2189 dev->ptrfeed) { 2190 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess); 2191 if (rc != Success) 2192 return rc; 2193 } 2194 } 2195 2196 for (dev = inputInfo.devices; dev; dev = dev->next) { 2197 if ((dev == mouse || 2198 (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) && 2199 dev->ptrfeed) { 2200 dev->ptrfeed->ctrl = ctrl; 2201 } 2202 } 2203 2204 return Success; 2205} 2206 2207int 2208ProcGetPointerControl(ClientPtr client) 2209{ 2210 DeviceIntPtr ptr = PickPointer(client); 2211 PtrCtrl *ctrl = &ptr->ptrfeed->ctrl; 2212 xGetPointerControlReply rep; 2213 int rc; 2214 REQUEST_SIZE_MATCH(xReq); 2215 2216 rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess); 2217 if (rc != Success) 2218 return rc; 2219 2220 rep.type = X_Reply; 2221 rep.length = 0; 2222 rep.sequenceNumber = client->sequence; 2223 rep.threshold = ctrl->threshold; 2224 rep.accelNumerator = ctrl->num; 2225 rep.accelDenominator = ctrl->den; 2226 WriteReplyToClient(client, sizeof(xGenericReply), &rep); 2227 return Success; 2228} 2229 2230void 2231MaybeStopHint(DeviceIntPtr dev, ClientPtr client) 2232{ 2233 GrabPtr grab = dev->deviceGrab.grab; 2234 2235 if ((grab && SameClient(grab, client) && 2236 ((grab->eventMask & PointerMotionHintMask) || 2237 (grab->ownerEvents && 2238 (EventMaskForClient(dev->valuator->motionHintWindow, client) & 2239 PointerMotionHintMask)))) || 2240 (!grab && 2241 (EventMaskForClient(dev->valuator->motionHintWindow, client) & 2242 PointerMotionHintMask))) 2243 dev->valuator->motionHintWindow = NullWindow; 2244} 2245 2246int 2247ProcGetMotionEvents(ClientPtr client) 2248{ 2249 WindowPtr pWin; 2250 xTimecoord * coords = (xTimecoord *) NULL; 2251 xGetMotionEventsReply rep; 2252 int i, count, xmin, xmax, ymin, ymax, rc; 2253 unsigned long nEvents; 2254 DeviceIntPtr mouse = PickPointer(client); 2255 TimeStamp start, stop; 2256 REQUEST(xGetMotionEventsReq); 2257 REQUEST_SIZE_MATCH(xGetMotionEventsReq); 2258 2259 rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 2260 if (rc != Success) 2261 return rc; 2262 rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess); 2263 if (rc != Success) 2264 return rc; 2265 2266 if (mouse->valuator->motionHintWindow) 2267 MaybeStopHint(mouse, client); 2268 rep.type = X_Reply; 2269 rep.sequenceNumber = client->sequence; 2270 nEvents = 0; 2271 start = ClientTimeToServerTime(stuff->start); 2272 stop = ClientTimeToServerTime(stuff->stop); 2273 if ((CompareTimeStamps(start, stop) != LATER) && 2274 (CompareTimeStamps(start, currentTime) != LATER) && 2275 mouse->valuator->numMotionEvents) 2276 { 2277 if (CompareTimeStamps(stop, currentTime) == LATER) 2278 stop = currentTime; 2279 count = GetMotionHistory(mouse, &coords, start.milliseconds, 2280 stop.milliseconds, pWin->drawable.pScreen, 2281 TRUE); 2282 xmin = pWin->drawable.x - wBorderWidth (pWin); 2283 xmax = pWin->drawable.x + (int)pWin->drawable.width + 2284 wBorderWidth (pWin); 2285 ymin = pWin->drawable.y - wBorderWidth (pWin); 2286 ymax = pWin->drawable.y + (int)pWin->drawable.height + 2287 wBorderWidth (pWin); 2288 for (i = 0; i < count; i++) 2289 if ((xmin <= coords[i].x) && (coords[i].x < xmax) && 2290 (ymin <= coords[i].y) && (coords[i].y < ymax)) 2291 { 2292 coords[nEvents].time = coords[i].time; 2293 coords[nEvents].x = coords[i].x - pWin->drawable.x; 2294 coords[nEvents].y = coords[i].y - pWin->drawable.y; 2295 nEvents++; 2296 } 2297 } 2298 rep.length = nEvents * bytes_to_int32(sizeof(xTimecoord)); 2299 rep.nEvents = nEvents; 2300 WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep); 2301 if (nEvents) 2302 { 2303 client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite; 2304 WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord), 2305 (char *)coords); 2306 } 2307 free(coords); 2308 return Success; 2309} 2310 2311int 2312ProcQueryKeymap(ClientPtr client) 2313{ 2314 xQueryKeymapReply rep; 2315 int rc, i; 2316 DeviceIntPtr keybd = PickKeyboard(client); 2317 CARD8 *down = keybd->key->down; 2318 2319 REQUEST_SIZE_MATCH(xReq); 2320 rep.type = X_Reply; 2321 rep.sequenceNumber = client->sequence; 2322 rep.length = 2; 2323 2324 rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess); 2325 if (rc != Success && rc != BadAccess) 2326 return rc; 2327 2328 for (i = 0; i<32; i++) 2329 rep.map[i] = down[i]; 2330 2331 if (rc == BadAccess) 2332 memset(rep.map, 0, 32); 2333 2334 WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep); 2335 2336 return Success; 2337} 2338 2339 2340/** 2341 * Recalculate the number of buttons for the master device. The number of 2342 * buttons on the master device is equal to the number of buttons on the 2343 * slave device with the highest number of buttons. 2344 */ 2345static void 2346RecalculateMasterButtons(DeviceIntPtr slave) 2347{ 2348 DeviceIntPtr dev, master; 2349 int maxbuttons = 0; 2350 2351 if (!slave->button || IsMaster(slave)) 2352 return; 2353 2354 master = GetMaster(slave, MASTER_POINTER); 2355 if (!master) 2356 return; 2357 2358 for (dev = inputInfo.devices; dev; dev = dev->next) 2359 { 2360 if (IsMaster(dev) || 2361 dev->u.master != master || 2362 !dev->button) 2363 continue; 2364 2365 maxbuttons = max(maxbuttons, dev->button->numButtons); 2366 } 2367 2368 if (master->button && master->button->numButtons != maxbuttons) 2369 { 2370 int i; 2371 DeviceChangedEvent event; 2372 2373 memset(&event, 0, sizeof(event)); 2374 2375 master->button->numButtons = maxbuttons; 2376 2377 event.header = ET_Internal; 2378 event.type = ET_DeviceChanged; 2379 event.time = GetTimeInMillis(); 2380 event.deviceid = master->id; 2381 event.flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE; 2382 event.buttons.num_buttons = maxbuttons; 2383 memcpy(&event.buttons.names, master->button->labels, maxbuttons * 2384 sizeof(Atom)); 2385 2386 if (master->valuator) 2387 { 2388 event.num_valuators = master->valuator->numAxes; 2389 for (i = 0; i < event.num_valuators; i++) 2390 { 2391 event.valuators[i].min = master->valuator->axes[i].min_value; 2392 event.valuators[i].max = master->valuator->axes[i].max_value; 2393 event.valuators[i].resolution = master->valuator->axes[i].resolution; 2394 event.valuators[i].mode = master->valuator->axes[i].mode; 2395 event.valuators[i].name = master->valuator->axes[i].label; 2396 } 2397 } 2398 2399 if (master->key) 2400 { 2401 event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code; 2402 event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code; 2403 } 2404 2405 XISendDeviceChangedEvent(master, master, &event); 2406 } 2407} 2408 2409/** 2410 * Generate release events for all keys/button currently down on this 2411 * device. 2412 */ 2413void 2414ReleaseButtonsAndKeys(DeviceIntPtr dev) 2415{ 2416 EventListPtr eventlist = InitEventList(GetMaximumEventsNum()); 2417 ButtonClassPtr b = dev->button; 2418 KeyClassPtr k = dev->key; 2419 int i, j, nevents; 2420 2421 if (!eventlist) /* no release events for you */ 2422 return; 2423 2424 /* Release all buttons */ 2425 for (i = 0; b && i < b->numButtons; i++) 2426 { 2427 if (BitIsOn(b->down, i)) 2428 { 2429 nevents = GetPointerEvents(eventlist, dev, ButtonRelease, i, 0, NULL); 2430 for (j = 0; j < nevents; j++) 2431 mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL); 2432 } 2433 } 2434 2435 /* Release all keys */ 2436 for (i = 0; k && i < MAP_LENGTH; i++) 2437 { 2438 if (BitIsOn(k->down, i)) 2439 { 2440 nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i); 2441 for (j = 0; j < nevents; j++) 2442 mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL); 2443 } 2444 } 2445 2446 FreeEventList(eventlist, GetMaximumEventsNum()); 2447} 2448 2449/** 2450 * Attach device 'dev' to device 'master'. 2451 * Client is set to the client that issued the request, or NULL if it comes 2452 * from some internal automatic pairing. 2453 * 2454 * Master may be NULL to set the device floating. 2455 * 2456 * We don't allow multi-layer hierarchies right now. You can't attach a slave 2457 * to another slave. 2458 */ 2459int 2460AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) 2461{ 2462 ScreenPtr screen; 2463 DeviceIntPtr oldmaster; 2464 if (!dev || IsMaster(dev)) 2465 return BadDevice; 2466 2467 if (master && !IsMaster(master)) /* can't attach to slaves */ 2468 return BadDevice; 2469 2470 /* set from floating to floating? */ 2471 if (!dev->u.master && !master && dev->enabled) 2472 return Success; 2473 2474 /* free the existing sprite. */ 2475 if (!dev->u.master && dev->spriteInfo->paired == dev) 2476 { 2477 screen = miPointerGetScreen(dev); 2478 screen->DeviceCursorCleanup(dev, screen); 2479 free(dev->spriteInfo->sprite); 2480 } 2481 2482 oldmaster = dev->u.master; 2483 dev->u.master = master; 2484 2485 /* If device is set to floating, we need to create a sprite for it, 2486 * otherwise things go bad. However, we don't want to render the cursor, 2487 * so we reset spriteOwner. 2488 * Sprite has to be forced to NULL first, otherwise InitializeSprite won't 2489 * alloc new memory but overwrite the previous one. 2490 */ 2491 if (!master) 2492 { 2493 WindowPtr currentRoot; 2494 2495 if (dev->spriteInfo->sprite) 2496 currentRoot = GetCurrentRootWindow(dev); 2497 else /* new device auto-set to floating */ 2498 currentRoot = screenInfo.screens[0]->root; 2499 2500 /* we need to init a fake sprite */ 2501 screen = currentRoot->drawable.pScreen; 2502 screen->DeviceCursorInitialize(dev, screen); 2503 dev->spriteInfo->sprite = NULL; 2504 InitializeSprite(dev, currentRoot); 2505 dev->spriteInfo->spriteOwner = FALSE; 2506 dev->spriteInfo->paired = dev; 2507 } else 2508 { 2509 dev->spriteInfo->sprite = master->spriteInfo->sprite; 2510 dev->spriteInfo->paired = master; 2511 dev->spriteInfo->spriteOwner = FALSE; 2512 2513 RecalculateMasterButtons(master); 2514 } 2515 2516 /* XXX: in theory, the MD should change back to its old, original 2517 * classes when the last SD is detached. Thanks to the XTEST devices, 2518 * we'll always have an SD attached until the MD is removed. 2519 * So let's not worry about that. 2520 */ 2521 2522 return Success; 2523} 2524 2525/** 2526 * Return the device paired with the given device or NULL. 2527 * Returns the device paired with the parent master if the given device is a 2528 * slave device. 2529 */ 2530DeviceIntPtr 2531GetPairedDevice(DeviceIntPtr dev) 2532{ 2533 if (!IsMaster(dev) && dev->u.master) 2534 dev = dev->u.master; 2535 2536 return dev->spriteInfo->paired; 2537} 2538 2539 2540/** 2541 * Returns the right master for the type of event needed. If the event is a 2542 * keyboard event. 2543 * This function may be called with a master device as argument. If so, the 2544 * returned master is either the device itself or the paired master device. 2545 * If dev is a floating slave device, NULL is returned. 2546 * 2547 * @type ::MASTER_KEYBOARD or ::MASTER_POINTER 2548 */ 2549DeviceIntPtr 2550GetMaster(DeviceIntPtr dev, int which) 2551{ 2552 DeviceIntPtr master; 2553 2554 if (IsMaster(dev)) 2555 master = dev; 2556 else 2557 master = dev->u.master; 2558 2559 if (master) 2560 { 2561 if (which == MASTER_KEYBOARD) 2562 { 2563 if (master->type != MASTER_KEYBOARD) 2564 master = GetPairedDevice(master); 2565 } else 2566 { 2567 if (master->type != MASTER_POINTER) 2568 master = GetPairedDevice(master); 2569 } 2570 } 2571 2572 return master; 2573} 2574 2575/** 2576 * Create a new device pair (== one pointer, one keyboard device). 2577 * Only allocates the devices, you will need to call ActivateDevice() and 2578 * EnableDevice() manually. 2579 * Either a master or a slave device can be created depending on 2580 * the value for master. 2581 */ 2582int 2583AllocDevicePair (ClientPtr client, char* name, 2584 DeviceIntPtr* ptr, 2585 DeviceIntPtr* keybd, 2586 DeviceProc ptr_proc, 2587 DeviceProc keybd_proc, 2588 Bool master) 2589{ 2590 DeviceIntPtr pointer; 2591 DeviceIntPtr keyboard; 2592 *ptr = *keybd = NULL; 2593 2594 pointer = AddInputDevice(client, ptr_proc, TRUE); 2595 if (!pointer) 2596 return BadAlloc; 2597 2598 if (asprintf(&pointer->name, "%s pointer", name) == -1) { 2599 pointer->name = NULL; 2600 RemoveDevice(pointer, FALSE); 2601 return BadAlloc; 2602 } 2603 2604 pointer->public.processInputProc = ProcessOtherEvent; 2605 pointer->public.realInputProc = ProcessOtherEvent; 2606 XkbSetExtension(pointer, ProcessPointerEvent); 2607 pointer->deviceGrab.ActivateGrab = ActivatePointerGrab; 2608 pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab; 2609 pointer->coreEvents = TRUE; 2610 pointer->spriteInfo->spriteOwner = TRUE; 2611 2612 pointer->u.lastSlave = NULL; 2613 pointer->last.slave = NULL; 2614 pointer->type = (master) ? MASTER_POINTER : SLAVE; 2615 2616 keyboard = AddInputDevice(client, keybd_proc, TRUE); 2617 if (!keyboard) 2618 { 2619 RemoveDevice(pointer, FALSE); 2620 return BadAlloc; 2621 } 2622 2623 if (asprintf(&keyboard->name, "%s keyboard", name) == -1) { 2624 keyboard->name = NULL; 2625 RemoveDevice(keyboard, FALSE); 2626 RemoveDevice(pointer, FALSE); 2627 return BadAlloc; 2628 } 2629 2630 keyboard->public.processInputProc = ProcessOtherEvent; 2631 keyboard->public.realInputProc = ProcessOtherEvent; 2632 XkbSetExtension(keyboard, ProcessKeyboardEvent); 2633 keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab; 2634 keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; 2635 keyboard->coreEvents = TRUE; 2636 keyboard->spriteInfo->spriteOwner = FALSE; 2637 2638 keyboard->u.lastSlave = NULL; 2639 keyboard->last.slave = NULL; 2640 keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE; 2641 2642 /* The ClassesRec stores the device classes currently not used. */ 2643 pointer->unused_classes = calloc(1, sizeof(ClassesRec)); 2644 keyboard->unused_classes = calloc(1, sizeof(ClassesRec)); 2645 2646 *ptr = pointer; 2647 *keybd = keyboard; 2648 2649 return Success; 2650} 2651 2652/** 2653 * Return Relative or Absolute for the device. 2654 */ 2655int valuator_get_mode(DeviceIntPtr dev, int axis) 2656{ 2657 return (dev->valuator->axes[axis].mode & DeviceMode); 2658} 2659 2660/** 2661 * Set the given mode for the axis. If axis is VALUATOR_MODE_ALL_AXES, then 2662 * set the mode for all axes. 2663 */ 2664void valuator_set_mode(DeviceIntPtr dev, int axis, int mode) 2665{ 2666 if (axis != VALUATOR_MODE_ALL_AXES) 2667 dev->valuator->axes[axis].mode = mode; 2668 else { 2669 int i; 2670 for (i = 0; i < dev->valuator->numAxes; i++) 2671 dev->valuator->axes[i].mode = mode; 2672 } 2673} 2674