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