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