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