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