devices.c revision 05b261ec
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#define NEED_EVENTS
58#define NEED_REPLIES
59#include <X11/Xproto.h>
60#include "windowstr.h"
61#include "inputstr.h"
62#include "scrnintstr.h"
63#include "cursorstr.h"
64#include "dixstruct.h"
65#include "site.h"
66#ifndef XKB_IN_SERVER
67#define	XKB_IN_SERVER
68#endif
69#ifdef XKB
70#include <xkbsrv.h>
71#endif
72#include "xace.h"
73
74#include "dispatch.h"
75#include "swaprep.h"
76#include "dixevents.h"
77
78#include <X11/extensions/XI.h>
79#include <X11/extensions/XIproto.h>
80#include "exglobals.h"
81#include "exevents.h"
82
83/** @file
84 * This file handles input device-related stuff.
85 */
86
87int CoreDevicePrivatesIndex = 0;
88static int CoreDevicePrivatesGeneration = -1;
89
90/**
91 * Create a new input device and init it to sane values. The device is added
92 * to the server's off_devices list.
93 *
94 * @param deviceProc Callback for device control function (switch dev on/off).
95 * @return The newly created device.
96 */
97DeviceIntPtr
98AddInputDevice(DeviceProc deviceProc, Bool autoStart)
99{
100    DeviceIntPtr dev, *prev; /* not a typo */
101    DeviceIntPtr devtmp;
102    int devid;
103    char devind[MAX_DEVICES];
104
105    /* Find next available id */
106    memset(devind, 0, sizeof(char)*MAX_DEVICES);
107    for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next)
108	devind[devtmp->id]++;
109    for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next)
110	devind[devtmp->id]++;
111    for (devid = 0; devid < MAX_DEVICES && devind[devid]; devid++)
112	;
113
114    if (devid >= MAX_DEVICES)
115	return (DeviceIntPtr)NULL;
116    dev = (DeviceIntPtr) xcalloc(sizeof(DeviceIntRec), 1);
117    if (!dev)
118	return (DeviceIntPtr)NULL;
119    dev->name = (char *)NULL;
120    dev->type = 0;
121    dev->id = devid;
122    inputInfo.numDevices++;
123    dev->public.on = FALSE;
124    dev->public.processInputProc = (ProcessInputProc)NoopDDA;
125    dev->public.realInputProc = (ProcessInputProc)NoopDDA;
126    dev->public.enqueueInputProc = EnqueueEvent;
127    dev->deviceProc = deviceProc;
128    dev->startup = autoStart;
129    dev->sync.frozen = FALSE;
130    dev->sync.other = NullGrab;
131    dev->sync.state = NOT_GRABBED;
132    dev->sync.event = (xEvent *) NULL;
133    dev->sync.evcount = 0;
134    dev->grab = NullGrab;
135    dev->grabTime = currentTime;
136    dev->fromPassiveGrab = FALSE;
137    dev->key = (KeyClassPtr)NULL;
138    dev->valuator = (ValuatorClassPtr)NULL;
139    dev->button = (ButtonClassPtr)NULL;
140    dev->focus = (FocusClassPtr)NULL;
141    dev->proximity = (ProximityClassPtr)NULL;
142    dev->absolute = (AbsoluteClassPtr)NULL;
143    dev->kbdfeed = (KbdFeedbackPtr)NULL;
144    dev->ptrfeed = (PtrFeedbackPtr)NULL;
145    dev->intfeed = (IntegerFeedbackPtr)NULL;
146    dev->stringfeed = (StringFeedbackPtr)NULL;
147    dev->bell = (BellFeedbackPtr)NULL;
148    dev->leds = (LedFeedbackPtr)NULL;
149#ifdef XKB
150    dev->xkb_interest = NULL;
151#endif
152    dev->config_info = NULL;
153    dev->nPrivates = 0;
154    dev->devPrivates = NULL;
155    dev->unwrapProc = NULL;
156    dev->coreEvents = TRUE;
157    dev->inited = FALSE;
158    dev->enabled = FALSE;
159
160    for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next)
161        ;
162    *prev = dev;
163    dev->next = NULL;
164
165    return dev;
166}
167
168/**
169 * Switch device ON through the driver and push it onto the global device
170 * list. All clients are notified about the device being enabled.
171 *
172 * A device will send events once enabled.
173 *
174 * @param The device to be enabled.
175 * @return TRUE on success or FALSE otherwise.
176 */
177Bool
178EnableDevice(DeviceIntPtr dev)
179{
180    DeviceIntPtr *prev;
181    int ret;
182    DeviceIntRec dummyDev;
183    devicePresenceNotify ev;
184
185    for (prev = &inputInfo.off_devices;
186	 *prev && (*prev != dev);
187	 prev = &(*prev)->next)
188	;
189    if ((*prev != dev) || !dev->inited ||
190	((ret = (*dev->deviceProc)(dev, DEVICE_ON)) != Success)) {
191        ErrorF("couldn't enable device %d\n", dev->id);
192	return FALSE;
193    }
194    dev->enabled = TRUE;
195    *prev = dev->next;
196
197    for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next)
198        ;
199    *prev = dev;
200    dev->next = NULL;
201
202    ev.type = DevicePresenceNotify;
203    ev.time = currentTime.milliseconds;
204    ev.devchange = DeviceEnabled;
205    ev.deviceid = dev->id;
206    dummyDev.id = 0;
207    SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
208                          (xEvent *) &ev, 1);
209
210    return TRUE;
211}
212
213/**
214 * Switch a device off through the driver and push it onto the off_devices
215 * list. A device will not send events while disabled. All clients are
216 * notified about the device being disabled.
217 *
218 * @return TRUE on success or FALSE otherwise.
219 */
220Bool
221DisableDevice(DeviceIntPtr dev)
222{
223    DeviceIntPtr *prev;
224    DeviceIntRec dummyDev;
225    devicePresenceNotify ev;
226
227    for (prev = &inputInfo.devices;
228	 *prev && (*prev != dev);
229	 prev = &(*prev)->next)
230	;
231    if (*prev != dev)
232	return FALSE;
233    (void)(*dev->deviceProc)(dev, DEVICE_OFF);
234    dev->enabled = FALSE;
235    *prev = dev->next;
236    dev->next = inputInfo.off_devices;
237    inputInfo.off_devices = dev;
238
239    ev.type = DevicePresenceNotify;
240    ev.time = currentTime.milliseconds;
241    ev.devchange = DeviceDisabled;
242    ev.deviceid = dev->id;
243    dummyDev.id = 0;
244    SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
245                          (xEvent *) &ev, 1);
246
247    return TRUE;
248}
249
250/**
251 * Initialise a new device through the driver and tell all clients about the
252 * new device.
253 *
254 * The device will NOT send events until it is enabled!
255 *
256 * @return Success or an error code on failure.
257 */
258int
259ActivateDevice(DeviceIntPtr dev)
260{
261    int ret = Success;
262    devicePresenceNotify ev;
263    DeviceIntRec dummyDev;
264
265    if (!dev || !dev->deviceProc)
266        return BadImplementation;
267
268    ret = (*dev->deviceProc) (dev, DEVICE_INIT);
269    dev->inited = (ret == Success);
270
271    ev.type = DevicePresenceNotify;
272    ev.time = currentTime.milliseconds;
273    ev.devchange = DeviceAdded;
274    ev.deviceid = dev->id;
275    dummyDev.id = 0;
276    SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
277                          (xEvent *) &ev, 1);
278
279    return ret;
280}
281
282/**
283 * Ring the bell.
284 * The actual task of ringing the bell is the job of the DDX.
285 */
286static void
287CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
288{
289    KeybdCtrl *ctrl = arg;
290
291    DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration);
292}
293
294static void
295CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
296{
297    return;
298}
299
300/**
301 * Device control function for the Virtual Core Keyboard.
302 */
303static int
304CoreKeyboardProc(DeviceIntPtr pDev, int what)
305{
306    CARD8 *modMap;
307    KeySymsRec keySyms;
308#ifdef XKB
309    XkbComponentNamesRec names;
310#endif
311
312    switch (what) {
313    case DEVICE_INIT:
314        keySyms.minKeyCode = 8;
315        keySyms.maxKeyCode = 255;
316        keySyms.mapWidth = 4;
317        keySyms.map = (KeySym *)xcalloc(sizeof(KeySym),
318                                        (keySyms.maxKeyCode -
319                                         keySyms.minKeyCode + 1) *
320                                        keySyms.mapWidth);
321        if (!keySyms.map) {
322            ErrorF("Couldn't allocate core keymap\n");
323            return BadAlloc;
324        }
325
326        modMap = (CARD8 *)xalloc(MAP_LENGTH);
327        if (!modMap) {
328            ErrorF("Couldn't allocate core modifier map\n");
329            return BadAlloc;
330        }
331        bzero((char *)modMap, MAP_LENGTH);
332
333#ifdef XKB
334        if (!noXkbExtension) {
335            bzero(&names, sizeof(names));
336            XkbSetRulesDflts("base", "pc105", "us", NULL, NULL);
337            XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, modMap,
338                                        CoreKeyboardBell, CoreKeyboardCtl);
339        }
340        else
341#endif
342        {
343            /* FIXME Our keymap here isn't exactly useful. */
344            InitKeyboardDeviceStruct((DevicePtr)pDev, &keySyms, modMap,
345                                     CoreKeyboardBell, CoreKeyboardCtl);
346        }
347
348        xfree(keySyms.map);
349        xfree(modMap);
350
351        break;
352
353    case DEVICE_CLOSE:
354        pDev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
355        break;
356
357    default:
358        break;
359    }
360    return Success;
361}
362
363/**
364 * Device control function for the Virtual Core Pointer.
365 */
366static int
367CorePointerProc(DeviceIntPtr pDev, int what)
368{
369    BYTE map[33];
370    int i = 0;
371
372    switch (what) {
373    case DEVICE_INIT:
374        for (i = 1; i <= 32; i++)
375            map[i] = i;
376        InitPointerDeviceStruct((DevicePtr)pDev, map, 32,
377                                GetMotionHistory, (PtrCtrlProcPtr)NoopDDA,
378                                GetMotionHistorySize(), 2);
379        pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
380        pDev->valuator->lastx = pDev->valuator->axisVal[0];
381        pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
382        pDev->valuator->lasty = pDev->valuator->axisVal[1];
383        break;
384
385    case DEVICE_CLOSE:
386        pDev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
387        break;
388
389    default:
390        break;
391    }
392
393    return Success;
394}
395
396/**
397 * Initialise the two core devices, VCP and VCK (see events.c).
398 * The devices are activated but not enabled.
399 * Note that the server MUST have two core devices at all times, even if there
400 * is no physical device connected.
401 */
402void
403InitCoreDevices(void)
404{
405    DeviceIntPtr dev;
406
407    if (CoreDevicePrivatesGeneration != serverGeneration) {
408        CoreDevicePrivatesIndex = AllocateDevicePrivateIndex();
409        CoreDevicePrivatesGeneration = serverGeneration;
410    }
411
412    if (!inputInfo.keyboard) {
413        dev = AddInputDevice(CoreKeyboardProc, TRUE);
414        if (!dev)
415            FatalError("Failed to allocate core keyboard");
416        dev->name = strdup("Virtual core keyboard");
417#ifdef XKB
418        dev->public.processInputProc = CoreProcessKeyboardEvent;
419        dev->public.realInputProc = CoreProcessKeyboardEvent;
420        if (!noXkbExtension)
421           XkbSetExtension(dev, ProcessKeyboardEvent);
422#else
423        dev->public.processInputProc = ProcessKeyboardEvent;
424        dev->public.realInputProc = ProcessKeyboardEvent;
425#endif
426        dev->ActivateGrab = ActivateKeyboardGrab;
427        dev->DeactivateGrab = DeactivateKeyboardGrab;
428        dev->coreEvents = FALSE;
429        if (!AllocateDevicePrivate(dev, CoreDevicePrivatesIndex))
430            FatalError("Couldn't allocate keyboard devPrivates\n");
431        dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
432        (void)ActivateDevice(dev);
433        inputInfo.keyboard = dev;
434    }
435
436    if (!inputInfo.pointer) {
437        dev = AddInputDevice(CorePointerProc, TRUE);
438        if (!dev)
439            FatalError("Failed to allocate core pointer");
440        dev->name = strdup("Virtual core pointer");
441#ifdef XKB
442        dev->public.processInputProc = CoreProcessPointerEvent;
443        dev->public.realInputProc = CoreProcessPointerEvent;
444        if (!noXkbExtension)
445           XkbSetExtension(dev, ProcessPointerEvent);
446#else
447        dev->public.processInputProc = ProcessPointerEvent;
448        dev->public.realInputProc = ProcessPointerEvent;
449#endif
450        dev->ActivateGrab = ActivatePointerGrab;
451        dev->DeactivateGrab = DeactivatePointerGrab;
452        dev->coreEvents = FALSE;
453        if (!AllocateDevicePrivate(dev, CoreDevicePrivatesIndex))
454            FatalError("Couldn't allocate pointer devPrivates\n");
455        dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
456        (void)ActivateDevice(dev);
457        inputInfo.pointer = dev;
458    }
459}
460
461/**
462 * Activate all switched-off devices and then enable all those devices.
463 *
464 * Will return an error if no core keyboard or core pointer is present.
465 * In theory this should never happen if you call InitCoreDevices() first.
466 *
467 * @return Success or error code on failure.
468 */
469int
470InitAndStartDevices(void)
471{
472    DeviceIntPtr dev, next;
473
474    for (dev = inputInfo.off_devices; dev; dev = dev->next) {
475        DebugF("(dix) initialising device %d\n", dev->id);
476        if (!dev->inited)
477            ActivateDevice(dev);
478    }
479    for (dev = inputInfo.off_devices; dev; dev = next)
480    {
481        DebugF("(dix) enabling device %d\n", dev->id);
482	next = dev->next;
483	if (dev->inited && dev->startup)
484	    (void)EnableDevice(dev);
485    }
486    for (dev = inputInfo.devices;
487	 dev && (dev != inputInfo.keyboard);
488	 dev = dev->next)
489	;
490    if (!dev || (dev != inputInfo.keyboard)) {
491	ErrorF("No core keyboard\n");
492	return BadImplementation;
493    }
494    for (dev = inputInfo.devices;
495	 dev && (dev != inputInfo.pointer);
496	 dev = dev->next)
497	;
498    if (!dev || (dev != inputInfo.pointer)) {
499	ErrorF("No core pointer\n");
500	return BadImplementation;
501    }
502    return Success;
503}
504
505/**
506 * Close down a device and free all resources.
507 * Once closed down, the driver will probably not expect you that you'll ever
508 * enable it again and free associated structs. If you want the device to just
509 * be disabled, DisableDevice().
510 * Don't call this function directly, use RemoveDevice() instead.
511 */
512static void
513CloseDevice(DeviceIntPtr dev)
514{
515    KbdFeedbackPtr k, knext;
516    PtrFeedbackPtr p, pnext;
517    IntegerFeedbackPtr i, inext;
518    StringFeedbackPtr s, snext;
519    BellFeedbackPtr b, bnext;
520    LedFeedbackPtr l, lnext;
521
522    if (dev->inited)
523	(void)(*dev->deviceProc)(dev, DEVICE_CLOSE);
524
525    xfree(dev->name);
526
527    if (dev->key) {
528#ifdef XKB
529	if (dev->key->xkbInfo)
530	    XkbFreeInfo(dev->key->xkbInfo);
531#endif
532        dev->key->xkbInfo = NULL;
533	xfree(dev->key->curKeySyms.map);
534	xfree(dev->key->modifierKeyMap);
535	xfree(dev->key);
536    }
537
538    if (dev->valuator) {
539        /* Counterpart to 'biggest hack ever' in init. */
540        if (dev->valuator->motion &&
541            dev->valuator->GetMotionProc == GetMotionHistory)
542            xfree(dev->valuator->motion);
543        xfree(dev->valuator);
544    }
545
546    if (dev->button) {
547#ifdef XKB
548        if (dev->button->xkb_acts)
549            xfree(dev->button->xkb_acts);
550#endif
551        xfree(dev->button);
552    }
553
554    if (dev->focus) {
555	xfree(dev->focus->trace);
556	xfree(dev->focus);
557    }
558
559    if (dev->proximity)
560        xfree(dev->proximity);
561
562    for (k = dev->kbdfeed; k; k = knext) {
563	knext = k->next;
564#ifdef XKB
565	if (k->xkb_sli)
566	    XkbFreeSrvLedInfo(k->xkb_sli);
567#endif
568	xfree(k);
569    }
570
571    for (p = dev->ptrfeed; p; p = pnext) {
572	pnext = p->next;
573	xfree(p);
574    }
575
576    for (i = dev->intfeed; i; i = inext) {
577	inext = i->next;
578	xfree(i);
579    }
580
581    for (s = dev->stringfeed; s; s = snext) {
582	snext = s->next;
583	xfree(s->ctrl.symbols_supported);
584	xfree(s->ctrl.symbols_displayed);
585	xfree(s);
586    }
587
588    for (b = dev->bell; b; b = bnext) {
589	bnext = b->next;
590	xfree(b);
591    }
592
593    for (l = dev->leds; l; l = lnext) {
594	lnext = l->next;
595#ifdef XKB
596	if (l->xkb_sli)
597	    XkbFreeSrvLedInfo(l->xkb_sli);
598#endif
599	xfree(l);
600    }
601
602#ifdef XKB
603    while (dev->xkb_interest)
604	XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource);
605#endif
606
607    if (dev->devPrivates)
608	xfree(dev->devPrivates);
609
610    xfree(dev->sync.event);
611    xfree(dev);
612}
613
614/**
615 * Shut down all devices, free all resources, etc.
616 * Only useful if you're shutting down the server!
617 */
618void
619CloseDownDevices(void)
620{
621    DeviceIntPtr dev, next;
622
623    for (dev = inputInfo.devices; dev; dev = next)
624    {
625	next = dev->next;
626	CloseDevice(dev);
627    }
628    for (dev = inputInfo.off_devices; dev; dev = next)
629    {
630	next = dev->next;
631	CloseDevice(dev);
632    }
633    inputInfo.devices = NULL;
634    inputInfo.off_devices = NULL;
635    inputInfo.keyboard = NULL;
636    inputInfo.pointer = NULL;
637}
638
639/**
640 * Remove a device from the device list, closes it and thus frees all
641 * resources.
642 * Removes both enabled and disabled devices and notifies all devices about
643 * the removal of the device.
644 */
645int
646RemoveDevice(DeviceIntPtr dev)
647{
648    DeviceIntPtr prev,tmp,next;
649    int ret = BadMatch;
650    devicePresenceNotify ev;
651    DeviceIntRec dummyDev;
652    int deviceid;
653
654    DebugF("(dix) removing device %d\n", dev->id);
655
656    if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
657        return BadImplementation;
658
659    deviceid = dev->id;
660    DisableDevice(dev);
661
662    prev = NULL;
663    for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
664	next = tmp->next;
665	if (tmp == dev) {
666	    CloseDevice(tmp);
667
668	    if (prev==NULL)
669		inputInfo.devices = next;
670	    else
671		prev->next = next;
672
673	    ret = Success;
674	}
675    }
676
677    prev = NULL;
678    for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
679	next = tmp->next;
680	if (tmp == dev) {
681	    CloseDevice(tmp);
682
683	    if (prev == NULL)
684		inputInfo.off_devices = next;
685	    else
686		prev->next = next;
687
688            ret = Success;
689	}
690    }
691
692    if (ret == Success) {
693        inputInfo.numDevices--;
694        ev.type = DevicePresenceNotify;
695        ev.time = currentTime.milliseconds;
696        ev.devchange = DeviceRemoved;
697        ev.deviceid = deviceid;
698        dummyDev.id = 0;
699        SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
700                              (xEvent *) &ev, 1);
701    }
702
703    return ret;
704}
705
706int
707NumMotionEvents(void)
708{
709    return inputInfo.pointer->valuator->numMotionEvents;
710}
711
712void
713RegisterPointerDevice(DeviceIntPtr device)
714{
715    RegisterOtherDevice(device);
716}
717
718void
719RegisterKeyboardDevice(DeviceIntPtr device)
720{
721    RegisterOtherDevice(device);
722}
723
724_X_EXPORT DevicePtr
725LookupKeyboardDevice(void)
726{
727    return inputInfo.keyboard ? &inputInfo.keyboard->public : NULL;
728}
729
730_X_EXPORT DevicePtr
731LookupPointerDevice(void)
732{
733    return inputInfo.pointer ? &inputInfo.pointer->public : NULL;
734}
735
736DevicePtr
737LookupDevice(int id)
738{
739    DeviceIntPtr dev;
740
741    for (dev=inputInfo.devices; dev; dev=dev->next) {
742        if (dev->id == (CARD8)id)
743            return (DevicePtr)dev;
744    }
745    for (dev=inputInfo.off_devices; dev; dev=dev->next) {
746        if (dev->id == (CARD8)id)
747            return (DevicePtr)dev;
748    }
749    return NULL;
750}
751
752void
753QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode)
754{
755    if (inputInfo.keyboard) {
756	*minCode = inputInfo.keyboard->key->curKeySyms.minKeyCode;
757	*maxCode = inputInfo.keyboard->key->curKeySyms.maxKeyCode;
758    }
759}
760
761Bool
762SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src)
763{
764    int i, j;
765    int rowDif = src->minKeyCode - dst->minKeyCode;
766
767    /* if keysym map size changes, grow map first */
768    if (src->mapWidth < dst->mapWidth)
769    {
770        for (i = src->minKeyCode; i <= src->maxKeyCode; i++)
771	{
772#define SI(r, c) (((r-src->minKeyCode)*src->mapWidth) + (c))
773#define DI(r, c) (((r - dst->minKeyCode)*dst->mapWidth) + (c))
774	    for (j = 0; j < src->mapWidth; j++)
775		dst->map[DI(i, j)] = src->map[SI(i, j)];
776	    for (j = src->mapWidth; j < dst->mapWidth; j++)
777		dst->map[DI(i, j)] = NoSymbol;
778#undef SI
779#undef DI
780	}
781	return TRUE;
782    }
783    else if (src->mapWidth > dst->mapWidth)
784    {
785        KeySym *map;
786	int bytes = sizeof(KeySym) * src->mapWidth *
787		    (dst->maxKeyCode - dst->minKeyCode + 1);
788        map = (KeySym *)xalloc(bytes);
789	if (!map)
790	    return FALSE;
791	bzero((char *)map, bytes);
792        if (dst->map)
793	{
794            for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++)
795		memmove((char *)&map[i*src->mapWidth],
796			(char *)&dst->map[i*dst->mapWidth],
797		      dst->mapWidth * sizeof(KeySym));
798	    xfree(dst->map);
799	}
800	dst->mapWidth = src->mapWidth;
801	dst->map = map;
802    }
803    memmove((char *)&dst->map[rowDif * dst->mapWidth],
804	    (char *)src->map,
805	  (int)(src->maxKeyCode - src->minKeyCode + 1) *
806	  dst->mapWidth * sizeof(KeySym));
807    return TRUE;
808}
809
810static Bool
811InitModMap(KeyClassPtr keyc)
812{
813    int i, j;
814    CARD8 keysPerModifier[8];
815    CARD8 mask;
816
817    keyc->maxKeysPerModifier = 0;
818    for (i = 0; i < 8; i++)
819	keysPerModifier[i] = 0;
820    for (i = 8; i < MAP_LENGTH; i++)
821    {
822	for (j = 0, mask = 1; j < 8; j++, mask <<= 1)
823	{
824	    if (mask & keyc->modifierMap[i])
825	    {
826		if (++keysPerModifier[j] > keyc->maxKeysPerModifier)
827		    keyc->maxKeysPerModifier = keysPerModifier[j];
828	    }
829	}
830    }
831    keyc->modifierKeyMap = (KeyCode *)xalloc(8*keyc->maxKeysPerModifier);
832    if (!keyc->modifierKeyMap && keyc->maxKeysPerModifier)
833	return (FALSE);
834    bzero((char *)keyc->modifierKeyMap, 8*(int)keyc->maxKeysPerModifier);
835    for (i = 0; i < 8; i++)
836	keysPerModifier[i] = 0;
837    for (i = 8; i < MAP_LENGTH; i++)
838    {
839	for (j = 0, mask = 1; j < 8; j++, mask <<= 1)
840	{
841	    if (mask & keyc->modifierMap[i])
842	    {
843		keyc->modifierKeyMap[(j*keyc->maxKeysPerModifier) +
844				     keysPerModifier[j]] = i;
845		keysPerModifier[j]++;
846	    }
847	}
848    }
849    return TRUE;
850}
851
852_X_EXPORT Bool
853InitKeyClassDeviceStruct(DeviceIntPtr dev, KeySymsPtr pKeySyms, CARD8 pModifiers[])
854{
855    int i;
856    KeyClassPtr keyc;
857
858    keyc = (KeyClassPtr)xalloc(sizeof(KeyClassRec));
859    if (!keyc)
860	return FALSE;
861    keyc->curKeySyms.map = (KeySym *)NULL;
862    keyc->curKeySyms.mapWidth = 0;
863    keyc->curKeySyms.minKeyCode = pKeySyms->minKeyCode;
864    keyc->curKeySyms.maxKeyCode = pKeySyms->maxKeyCode;
865    keyc->modifierKeyMap = (KeyCode *)NULL;
866    keyc->state = 0;
867    keyc->prev_state = 0;
868    if (pModifiers)
869	memmove((char *)keyc->modifierMap, (char *)pModifiers, MAP_LENGTH);
870    else
871	bzero((char *)keyc->modifierMap, MAP_LENGTH);
872    bzero((char *)keyc->down, DOWN_LENGTH);
873    bzero((char *)keyc->postdown, DOWN_LENGTH);
874    for (i = 0; i < 8; i++)
875	keyc->modifierKeyCount[i] = 0;
876    if (!SetKeySymsMap(&keyc->curKeySyms, pKeySyms) || !InitModMap(keyc))
877    {
878	xfree(keyc->curKeySyms.map);
879	xfree(keyc->modifierKeyMap);
880	xfree(keyc);
881	return FALSE;
882    }
883    dev->key = keyc;
884#ifdef XKB
885    dev->key->xkbInfo= NULL;
886    if (!noXkbExtension) XkbInitDevice(dev);
887#endif
888    return TRUE;
889}
890
891_X_EXPORT Bool
892InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons,
893                            CARD8 *map)
894{
895    ButtonClassPtr butc;
896    int i;
897
898    butc = (ButtonClassPtr)xalloc(sizeof(ButtonClassRec));
899    if (!butc)
900	return FALSE;
901    butc->numButtons = numButtons;
902    for (i = 1; i <= numButtons; i++)
903	butc->map[i] = map[i];
904    butc->buttonsDown = 0;
905    butc->state = 0;
906    butc->motionMask = 0;
907    bzero((char *)butc->down, DOWN_LENGTH);
908#ifdef XKB
909    butc->xkb_acts=	NULL;
910#endif
911    dev->button = butc;
912    return TRUE;
913}
914
915_X_EXPORT Bool
916InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes,
917                              ValuatorMotionProcPtr motionProc,
918                              int numMotionEvents, int mode)
919{
920    int i;
921    ValuatorClassPtr valc;
922
923    if (!dev)
924        return FALSE;
925
926    valc = (ValuatorClassPtr)xalloc(sizeof(ValuatorClassRec) +
927				    numAxes * sizeof(AxisInfo) +
928				    numAxes * sizeof(unsigned int));
929    if (!valc)
930	return FALSE;
931
932    valc->motion = NULL;
933    valc->first_motion = 0;
934    valc->last_motion = 0;
935    valc->GetMotionProc = motionProc;
936
937    valc->numMotionEvents = numMotionEvents;
938    valc->motionHintWindow = NullWindow;
939    valc->numAxes = numAxes;
940    valc->mode = mode;
941    valc->axes = (AxisInfoPtr)(valc + 1);
942    valc->axisVal = (int *)(valc->axes + numAxes);
943    valc->lastx = 0;
944    valc->lasty = 0;
945    valc->dxremaind = 0;
946    valc->dyremaind = 0;
947    dev->valuator = valc;
948
949    /* biggest hack ever. */
950    if (motionProc == GetMotionHistory)
951        AllocateMotionHistory(dev);
952
953    for (i=0; i<numAxes; i++) {
954        InitValuatorAxisStruct(dev, i, 0, -1, 0, 0, 0);
955	valc->axisVal[i]=0;
956    }
957    return TRUE;
958}
959
960_X_EXPORT Bool
961InitAbsoluteClassDeviceStruct(DeviceIntPtr dev)
962{
963    AbsoluteClassPtr abs;
964
965    abs = (AbsoluteClassPtr)xalloc(sizeof(AbsoluteClassRec));
966    if (!abs)
967        return FALSE;
968
969    /* we don't do anything sensible with these, but should */
970    abs->min_x = -1;
971    abs->min_y = -1;
972    abs->max_x = -1;
973    abs->max_y = -1;
974    abs->flip_x = 0;
975    abs->flip_y = 0;
976    abs->rotation = 0;
977    abs->button_threshold = 0;
978
979    abs->offset_x = 0;
980    abs->offset_y = 0;
981    abs->width = -1;
982    abs->height = -1;
983    abs->following = 0;
984    abs->screen = 0;
985
986    dev->absolute = abs;
987
988    return TRUE;
989}
990
991_X_EXPORT Bool
992InitFocusClassDeviceStruct(DeviceIntPtr dev)
993{
994    FocusClassPtr focc;
995
996    focc = (FocusClassPtr)xalloc(sizeof(FocusClassRec));
997    if (!focc)
998	return FALSE;
999    focc->win = PointerRootWin;
1000    focc->revert = None;
1001    focc->time = currentTime;
1002    focc->trace = (WindowPtr *)NULL;
1003    focc->traceSize = 0;
1004    focc->traceGood = 0;
1005    dev->focus = focc;
1006    return TRUE;
1007}
1008
1009_X_EXPORT Bool
1010InitKbdFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc,
1011                                 KbdCtrlProcPtr controlProc)
1012{
1013    KbdFeedbackPtr feedc;
1014
1015    feedc = (KbdFeedbackPtr)xalloc(sizeof(KbdFeedbackClassRec));
1016    if (!feedc)
1017	return FALSE;
1018    feedc->BellProc = bellProc;
1019    feedc->CtrlProc = controlProc;
1020#ifdef XKB
1021    defaultKeyboardControl.autoRepeat = TRUE;
1022#endif
1023    feedc->ctrl = defaultKeyboardControl;
1024    feedc->ctrl.id = 0;
1025    if ((feedc->next = dev->kbdfeed) != 0)
1026	feedc->ctrl.id = dev->kbdfeed->ctrl.id + 1;
1027    dev->kbdfeed = feedc;
1028#ifdef XKB
1029    feedc->xkb_sli= NULL;
1030    if (!noXkbExtension)
1031	XkbFinishDeviceInit(dev);
1032#endif
1033    (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl);
1034    return TRUE;
1035}
1036
1037_X_EXPORT Bool
1038InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc)
1039{
1040    PtrFeedbackPtr feedc;
1041
1042    feedc = (PtrFeedbackPtr)xalloc(sizeof(PtrFeedbackClassRec));
1043    if (!feedc)
1044	return FALSE;
1045    feedc->CtrlProc = controlProc;
1046    feedc->ctrl = defaultPointerControl;
1047    feedc->ctrl.id = 0;
1048    if ( (feedc->next = dev->ptrfeed) )
1049        feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1;
1050    dev->ptrfeed = feedc;
1051    (*controlProc)(dev, &feedc->ctrl);
1052    return TRUE;
1053}
1054
1055
1056static LedCtrl defaultLedControl = {
1057	DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0};
1058
1059static BellCtrl defaultBellControl = {
1060	DEFAULT_BELL,
1061	DEFAULT_BELL_PITCH,
1062	DEFAULT_BELL_DURATION,
1063	0};
1064
1065static IntegerCtrl defaultIntegerControl = {
1066	DEFAULT_INT_RESOLUTION,
1067	DEFAULT_INT_MIN_VALUE,
1068	DEFAULT_INT_MAX_VALUE,
1069	DEFAULT_INT_DISPLAYED,
1070	0};
1071
1072_X_EXPORT Bool
1073InitStringFeedbackClassDeviceStruct (
1074      DeviceIntPtr dev, StringCtrlProcPtr controlProc,
1075      int max_symbols, int num_symbols_supported, KeySym *symbols)
1076{
1077    int i;
1078    StringFeedbackPtr feedc;
1079
1080    feedc = (StringFeedbackPtr)xalloc(sizeof(StringFeedbackClassRec));
1081    if (!feedc)
1082	return FALSE;
1083    feedc->CtrlProc = controlProc;
1084    feedc->ctrl.num_symbols_supported = num_symbols_supported;
1085    feedc->ctrl.num_symbols_displayed = 0;
1086    feedc->ctrl.max_symbols = max_symbols;
1087    feedc->ctrl.symbols_supported = (KeySym *)
1088	xalloc (sizeof (KeySym) * num_symbols_supported);
1089    feedc->ctrl.symbols_displayed = (KeySym *)
1090	xalloc (sizeof (KeySym) * max_symbols);
1091    if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed)
1092    {
1093	if (feedc->ctrl.symbols_supported)
1094	    xfree(feedc->ctrl.symbols_supported);
1095	if (feedc->ctrl.symbols_displayed)
1096	    xfree(feedc->ctrl.symbols_displayed);
1097	xfree(feedc);
1098	return FALSE;
1099    }
1100    for (i=0; i<num_symbols_supported; i++)
1101	*(feedc->ctrl.symbols_supported+i) = *symbols++;
1102    for (i=0; i<max_symbols; i++)
1103	*(feedc->ctrl.symbols_displayed+i) = (KeySym) NULL;
1104    feedc->ctrl.id = 0;
1105    if ( (feedc->next = dev->stringfeed) )
1106	feedc->ctrl.id = dev->stringfeed->ctrl.id + 1;
1107    dev->stringfeed = feedc;
1108    (*controlProc)(dev, &feedc->ctrl);
1109    return TRUE;
1110}
1111
1112_X_EXPORT Bool
1113InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc,
1114                                   BellCtrlProcPtr controlProc)
1115{
1116    BellFeedbackPtr feedc;
1117
1118    feedc = (BellFeedbackPtr)xalloc(sizeof(BellFeedbackClassRec));
1119    if (!feedc)
1120	return FALSE;
1121    feedc->CtrlProc = controlProc;
1122    feedc->BellProc = bellProc;
1123    feedc->ctrl = defaultBellControl;
1124    feedc->ctrl.id = 0;
1125    if ( (feedc->next = dev->bell) )
1126	feedc->ctrl.id = dev->bell->ctrl.id + 1;
1127    dev->bell = feedc;
1128    (*controlProc)(dev, &feedc->ctrl);
1129    return TRUE;
1130}
1131
1132_X_EXPORT Bool
1133InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc)
1134{
1135    LedFeedbackPtr feedc;
1136
1137    feedc = (LedFeedbackPtr)xalloc(sizeof(LedFeedbackClassRec));
1138    if (!feedc)
1139	return FALSE;
1140    feedc->CtrlProc = controlProc;
1141    feedc->ctrl = defaultLedControl;
1142    feedc->ctrl.id = 0;
1143    if ( (feedc->next = dev->leds) )
1144	feedc->ctrl.id = dev->leds->ctrl.id + 1;
1145#ifdef XKB
1146    feedc->xkb_sli= NULL;
1147#endif
1148    dev->leds = feedc;
1149    (*controlProc)(dev, &feedc->ctrl);
1150    return TRUE;
1151}
1152
1153_X_EXPORT Bool
1154InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr controlProc)
1155{
1156    IntegerFeedbackPtr feedc;
1157
1158    feedc = (IntegerFeedbackPtr)xalloc(sizeof(IntegerFeedbackClassRec));
1159    if (!feedc)
1160	return FALSE;
1161    feedc->CtrlProc = controlProc;
1162    feedc->ctrl = defaultIntegerControl;
1163    feedc->ctrl.id = 0;
1164    if ( (feedc->next = dev->intfeed) )
1165	feedc->ctrl.id = dev->intfeed->ctrl.id + 1;
1166    dev->intfeed = feedc;
1167    (*controlProc)(dev, &feedc->ctrl);
1168    return TRUE;
1169}
1170
1171_X_EXPORT Bool
1172InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons,
1173                        ValuatorMotionProcPtr motionProc,
1174                        PtrCtrlProcPtr controlProc, int numMotionEvents,
1175                        int numAxes)
1176{
1177    DeviceIntPtr dev = (DeviceIntPtr)device;
1178
1179    return(InitButtonClassDeviceStruct(dev, numButtons, map) &&
1180	   InitValuatorClassDeviceStruct(dev, numAxes, motionProc,
1181					 numMotionEvents, 0) &&
1182	   InitPtrFeedbackClassDeviceStruct(dev, controlProc));
1183}
1184
1185_X_EXPORT Bool
1186InitKeyboardDeviceStruct(DevicePtr device, KeySymsPtr pKeySyms,
1187                         CARD8 pModifiers[], BellProcPtr bellProc,
1188                         KbdCtrlProcPtr controlProc)
1189{
1190    DeviceIntPtr dev = (DeviceIntPtr)device;
1191
1192    return(InitKeyClassDeviceStruct(dev, pKeySyms, pModifiers) &&
1193	   InitFocusClassDeviceStruct(dev) &&
1194	   InitKbdFeedbackClassDeviceStruct(dev, bellProc, controlProc));
1195}
1196
1197_X_EXPORT void
1198SendMappingNotify(unsigned request, unsigned firstKeyCode, unsigned count,
1199                  ClientPtr client)
1200{
1201    int i;
1202    xEvent event;
1203
1204    event.u.u.type = MappingNotify;
1205    event.u.mappingNotify.request = request;
1206    if (request == MappingKeyboard)
1207    {
1208        event.u.mappingNotify.firstKeyCode = firstKeyCode;
1209        event.u.mappingNotify.count = count;
1210    }
1211#ifdef XKB
1212    if (!noXkbExtension &&
1213	((request == MappingKeyboard) || (request == MappingModifier)))
1214        XkbApplyMappingChange(inputInfo.keyboard, request, firstKeyCode, count,
1215                              client);
1216#endif
1217
1218   /* 0 is the server client */
1219    for (i=1; i<currentMaxClients; i++)
1220    {
1221	if (clients[i] && clients[i]->clientState == ClientStateRunning)
1222	{
1223#ifdef XKB
1224	    if (!noXkbExtension &&
1225		(request == MappingKeyboard) &&
1226		(clients[i]->xkbClientFlags != 0) &&
1227		(clients[i]->mapNotifyMask&XkbKeySymsMask))
1228		continue;
1229#endif
1230	    event.u.u.sequenceNumber = clients[i]->sequence;
1231	    WriteEventsToClient(clients[i], 1, &event);
1232	}
1233    }
1234}
1235
1236/*
1237 * n-squared algorithm. n < 255 and don't want to copy the whole thing and
1238 * sort it to do the checking. How often is it called? Just being lazy?
1239 */
1240Bool
1241BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval)
1242{
1243    int i, j;
1244
1245    for (i = 0; i < length; i++)
1246	if (buff[i])		       /* only check non-zero elements */
1247	{
1248	    if ((low > buff[i]) || (high < buff[i]))
1249	    {
1250		*errval = buff[i];
1251		return TRUE;
1252	    }
1253	    for (j = i + 1; j < length; j++)
1254		if (buff[i] == buff[j])
1255		{
1256		    *errval = buff[i];
1257		    return TRUE;
1258		}
1259	}
1260    return FALSE;
1261}
1262
1263Bool
1264AllModifierKeysAreUp(dev, map1, per1, map2, per2)
1265    DeviceIntPtr dev;
1266    CARD8 *map1, *map2;
1267    int per1, per2;
1268{
1269    int i, j, k;
1270    CARD8 *down = dev->key->down;
1271
1272    for (i = 8; --i >= 0; map2 += per2)
1273    {
1274	for (j = per1; --j >= 0; map1++)
1275	{
1276	    if (*map1 && BitIsOn(down, *map1))
1277	    {
1278		for (k = per2; (--k >= 0) && (*map1 != map2[k]);)
1279		  ;
1280		if (k < 0)
1281		    return FALSE;
1282	    }
1283	}
1284    }
1285    return TRUE;
1286}
1287
1288static int
1289DoSetModifierMapping(ClientPtr client, KeyCode *inputMap,
1290                     int numKeyPerModifier)
1291{
1292    DeviceIntPtr pDev = NULL;
1293    int i = 0, inputMapLen = numKeyPerModifier * 8;
1294
1295    for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
1296        if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
1297            for (i = 0; i < inputMapLen; i++) {
1298                /* Check that all the new modifiers fall within the advertised
1299                 * keycode range, and are okay with the DDX. */
1300                if (inputMap[i] && ((inputMap[i] < pDev->key->curKeySyms.minKeyCode ||
1301                                    inputMap[i] > pDev->key->curKeySyms.maxKeyCode) ||
1302                                    !LegalModifier(inputMap[i], pDev))) {
1303                    client->errorValue = inputMap[i];
1304                    return BadValue;
1305                }
1306            }
1307
1308            if (!XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE))
1309                return BadAccess;
1310
1311            /* None of the modifiers (old or new) may be down while we change
1312             * the map. */
1313            if (!AllModifierKeysAreUp(pDev, pDev->key->modifierKeyMap,
1314                                      pDev->key->maxKeysPerModifier,
1315                                      inputMap, numKeyPerModifier) ||
1316                !AllModifierKeysAreUp(pDev, inputMap, numKeyPerModifier,
1317                                      pDev->key->modifierKeyMap,
1318                                      pDev->key->maxKeysPerModifier)) {
1319                return MappingBusy;
1320            }
1321        }
1322    }
1323
1324    for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
1325
1326        if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
1327            bzero(pDev->key->modifierMap, MAP_LENGTH);
1328
1329            /* Annoyingly, we lack a modifierKeyMap size, so we have to just free
1330             * and re-alloc it every time. */
1331            if (pDev->key->modifierKeyMap)
1332                xfree(pDev->key->modifierKeyMap);
1333
1334            if (inputMapLen) {
1335                pDev->key->modifierKeyMap = (KeyCode *) xalloc(inputMapLen);
1336                if (!pDev->key->modifierKeyMap)
1337                    return BadAlloc;
1338
1339                memcpy(pDev->key->modifierKeyMap, inputMap, inputMapLen);
1340                pDev->key->maxKeysPerModifier = numKeyPerModifier;
1341
1342                for (i = 0; i < inputMapLen; i++) {
1343                    if (inputMap[i]) {
1344                        pDev->key->modifierMap[inputMap[i]] |=
1345                            (1 << (((unsigned int)i) / numKeyPerModifier));
1346                    }
1347                }
1348            }
1349            else {
1350                pDev->key->modifierKeyMap = NULL;
1351                pDev->key->maxKeysPerModifier = 0;
1352            }
1353        }
1354    }
1355
1356    return Success;
1357}
1358
1359int
1360ProcSetModifierMapping(ClientPtr client)
1361{
1362    xSetModifierMappingReply rep;
1363    DeviceIntPtr dev;
1364    REQUEST(xSetModifierMappingReq);
1365
1366    REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
1367
1368    if (client->req_len != ((stuff->numKeyPerModifier << 1) +
1369			    (sizeof (xSetModifierMappingReq) >> 2)))
1370	return BadLength;
1371
1372    rep.type = X_Reply;
1373    rep.length = 0;
1374    rep.sequenceNumber = client->sequence;
1375
1376    rep.success = DoSetModifierMapping(client, (KeyCode *)&stuff[1],
1377                                       stuff->numKeyPerModifier);
1378
1379    SendMappingNotify(MappingModifier, 0, 0, client);
1380    for (dev = inputInfo.devices; dev; dev = dev->next)
1381        if (dev->key && dev->coreEvents)
1382            SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev);
1383    WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
1384    return client->noClientException;
1385}
1386
1387int
1388ProcGetModifierMapping(ClientPtr client)
1389{
1390    xGetModifierMappingReply rep;
1391    KeyClassPtr keyc = inputInfo.keyboard->key;
1392
1393    REQUEST_SIZE_MATCH(xReq);
1394    rep.type = X_Reply;
1395    rep.numKeyPerModifier = keyc->maxKeysPerModifier;
1396    rep.sequenceNumber = client->sequence;
1397    /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
1398    rep.length = keyc->maxKeysPerModifier << 1;
1399
1400    WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep);
1401
1402    /* Use the (modified by DDX) map that SetModifierMapping passed in */
1403    (void)WriteToClient(client, (int)(keyc->maxKeysPerModifier << 3),
1404			(char *)keyc->modifierKeyMap);
1405    return client->noClientException;
1406}
1407
1408int
1409ProcChangeKeyboardMapping(ClientPtr client)
1410{
1411    REQUEST(xChangeKeyboardMappingReq);
1412    unsigned len;
1413    KeySymsRec keysyms;
1414    KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
1415    DeviceIntPtr pDev = NULL;
1416    REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
1417
1418    len = client->req_len - (sizeof(xChangeKeyboardMappingReq) >> 2);
1419    if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode))
1420            return BadLength;
1421
1422    if ((stuff->firstKeyCode < curKeySyms->minKeyCode) ||
1423	(stuff->firstKeyCode > curKeySyms->maxKeyCode)) {
1424	    client->errorValue = stuff->firstKeyCode;
1425	    return BadValue;
1426
1427    }
1428    if (((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) >
1429        curKeySyms->maxKeyCode) || (stuff->keySymsPerKeyCode == 0)) {
1430	    client->errorValue = stuff->keySymsPerKeyCode;
1431	    return BadValue;
1432    }
1433
1434    for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
1435        if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
1436            if (!XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE))
1437                return BadAccess;
1438        }
1439    }
1440
1441    keysyms.minKeyCode = stuff->firstKeyCode;
1442    keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1;
1443    keysyms.mapWidth = stuff->keySymsPerKeyCode;
1444    keysyms.map = (KeySym *)&stuff[1];
1445    for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
1446        if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key)
1447            if (!SetKeySymsMap(&pDev->key->curKeySyms, &keysyms))
1448                return BadAlloc;
1449
1450    SendMappingNotify(MappingKeyboard, stuff->firstKeyCode, stuff->keyCodes,
1451                      client);
1452    for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
1453        if (pDev->key && pDev->coreEvents)
1454            SendDeviceMappingNotify(client, MappingKeyboard,
1455                                    stuff->firstKeyCode, stuff->keyCodes,
1456                                    pDev);
1457
1458    return client->noClientException;
1459}
1460
1461static int
1462DoSetPointerMapping(DeviceIntPtr device, BYTE *map, int n)
1463{
1464    int i = 0;
1465    DeviceIntPtr dev = NULL;
1466
1467    if (!device || !device->button)
1468        return BadDevice;
1469
1470    for (dev = inputInfo.devices; dev; dev = dev->next) {
1471        if ((dev->coreEvents || dev == inputInfo.pointer) && dev->button) {
1472            for (i = 0; i < n; i++) {
1473                if ((device->button->map[i + 1] != map[i]) &&
1474                    BitIsOn(device->button->down, i + 1)) {
1475                    return MappingBusy;
1476                }
1477            }
1478        }
1479    }
1480
1481    for (dev = inputInfo.devices; dev; dev = dev->next) {
1482        if ((dev->coreEvents || dev == inputInfo.pointer) && dev->button) {
1483            for (i = 0; i < n; i++)
1484                dev->button->map[i + 1] = map[i];
1485        }
1486    }
1487
1488    return Success;
1489}
1490
1491int
1492ProcSetPointerMapping(ClientPtr client)
1493{
1494    REQUEST(xSetPointerMappingReq);
1495    BYTE *map;
1496    int ret;
1497    xSetPointerMappingReply rep;
1498
1499    REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq);
1500    if (client->req_len != (sizeof(xSetPointerMappingReq)+stuff->nElts+3) >> 2)
1501	return BadLength;
1502    rep.type = X_Reply;
1503    rep.length = 0;
1504    rep.sequenceNumber = client->sequence;
1505    rep.success = MappingSuccess;
1506    map = (BYTE *)&stuff[1];
1507
1508    /* So we're bounded here by the number of core buttons.  This check
1509     * probably wants disabling through XFixes. */
1510    if (stuff->nElts != inputInfo.pointer->button->numButtons) {
1511	client->errorValue = stuff->nElts;
1512	return BadValue;
1513    }
1514    if (BadDeviceMap(&map[0], (int)stuff->nElts, 1, 255, &client->errorValue))
1515	return BadValue;
1516
1517    ret = DoSetPointerMapping(inputInfo.pointer, map, stuff->nElts);
1518    if (ret != Success) {
1519        rep.success = ret;
1520        WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
1521        return Success;
1522    }
1523
1524    /* FIXME: Send mapping notifies for all the extended devices as well. */
1525    SendMappingNotify(MappingPointer, 0, 0, client);
1526    WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
1527    return Success;
1528}
1529
1530int
1531ProcGetKeyboardMapping(ClientPtr client)
1532{
1533    xGetKeyboardMappingReply rep;
1534    REQUEST(xGetKeyboardMappingReq);
1535    KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
1536
1537    REQUEST_SIZE_MATCH(xGetKeyboardMappingReq);
1538
1539    if ((stuff->firstKeyCode < curKeySyms->minKeyCode) ||
1540        (stuff->firstKeyCode > curKeySyms->maxKeyCode)) {
1541	client->errorValue = stuff->firstKeyCode;
1542	return BadValue;
1543    }
1544    if (stuff->firstKeyCode + stuff->count >
1545	(unsigned)(curKeySyms->maxKeyCode + 1)) {
1546	client->errorValue = stuff->count;
1547        return BadValue;
1548    }
1549
1550    rep.type = X_Reply;
1551    rep.sequenceNumber = client->sequence;
1552    rep.keySymsPerKeyCode = curKeySyms->mapWidth;
1553    /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
1554    rep.length = (curKeySyms->mapWidth * stuff->count);
1555    WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep);
1556    client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
1557    WriteSwappedDataToClient(
1558	client,
1559	curKeySyms->mapWidth * stuff->count * sizeof(KeySym),
1560	&curKeySyms->map[(stuff->firstKeyCode - curKeySyms->minKeyCode) *
1561			 curKeySyms->mapWidth]);
1562
1563    return client->noClientException;
1564}
1565
1566int
1567ProcGetPointerMapping(ClientPtr client)
1568{
1569    xGetPointerMappingReply rep;
1570    ButtonClassPtr butc = inputInfo.pointer->button;
1571
1572    REQUEST_SIZE_MATCH(xReq);
1573    rep.type = X_Reply;
1574    rep.sequenceNumber = client->sequence;
1575    rep.nElts = butc->numButtons;
1576    rep.length = ((unsigned)rep.nElts + (4-1))/4;
1577    WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep);
1578    (void)WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]);
1579    return Success;
1580}
1581
1582void
1583NoteLedState(DeviceIntPtr keybd, int led, Bool on)
1584{
1585    KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl;
1586    if (on)
1587	ctrl->leds |= ((Leds)1 << (led - 1));
1588    else
1589	ctrl->leds &= ~((Leds)1 << (led - 1));
1590}
1591
1592_X_EXPORT int
1593Ones(unsigned long mask)             /* HACKMEM 169 */
1594{
1595    unsigned long y;
1596
1597    y = (mask >> 1) &033333333333;
1598    y = mask - y - ((y >>1) & 033333333333);
1599    return (((y + (y >> 3)) & 030707070707) % 077);
1600}
1601
1602static int
1603DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist,
1604                         BITS32 vmask)
1605{
1606#define DO_ALL    (-1)
1607    KeybdCtrl ctrl;
1608    int t;
1609    int led = DO_ALL;
1610    int key = DO_ALL;
1611    BITS32 index2;
1612    int mask = vmask, i;
1613
1614    ctrl = keybd->kbdfeed->ctrl;
1615    while (vmask) {
1616	index2 = (BITS32) lowbit (vmask);
1617	vmask &= ~index2;
1618	switch (index2) {
1619	case KBKeyClickPercent:
1620	    t = (INT8)*vlist;
1621	    vlist++;
1622	    if (t == -1) {
1623		t = defaultKeyboardControl.click;
1624            }
1625	    else if (t < 0 || t > 100) {
1626		client->errorValue = t;
1627		return BadValue;
1628	    }
1629	    ctrl.click = t;
1630	    break;
1631	case KBBellPercent:
1632	    t = (INT8)*vlist;
1633	    vlist++;
1634	    if (t == -1) {
1635		t = defaultKeyboardControl.bell;
1636            }
1637	    else if (t < 0 || t > 100) {
1638		client->errorValue = t;
1639		return BadValue;
1640	    }
1641	    ctrl.bell = t;
1642	    break;
1643	case KBBellPitch:
1644	    t = (INT16)*vlist;
1645	    vlist++;
1646	    if (t == -1) {
1647		t = defaultKeyboardControl.bell_pitch;
1648            }
1649	    else if (t < 0) {
1650		client->errorValue = t;
1651		return BadValue;
1652	    }
1653	    ctrl.bell_pitch = t;
1654	    break;
1655	case KBBellDuration:
1656	    t = (INT16)*vlist;
1657	    vlist++;
1658	    if (t == -1)
1659		t = defaultKeyboardControl.bell_duration;
1660	    else if (t < 0) {
1661		client->errorValue = t;
1662		return BadValue;
1663	    }
1664	    ctrl.bell_duration = t;
1665	    break;
1666	case KBLed:
1667	    led = (CARD8)*vlist;
1668	    vlist++;
1669	    if (led < 1 || led > 32) {
1670		client->errorValue = led;
1671		return BadValue;
1672	    }
1673	    if (!(mask & KBLedMode))
1674		return BadMatch;
1675	    break;
1676	case KBLedMode:
1677	    t = (CARD8)*vlist;
1678	    vlist++;
1679	    if (t == LedModeOff) {
1680		if (led == DO_ALL)
1681		    ctrl.leds = 0x0;
1682		else
1683		    ctrl.leds &= ~(((Leds)(1)) << (led - 1));
1684	    }
1685	    else if (t == LedModeOn) {
1686		if (led == DO_ALL)
1687		    ctrl.leds = ~0L;
1688		else
1689		    ctrl.leds |= (((Leds)(1)) << (led - 1));
1690	    }
1691	    else {
1692		client->errorValue = t;
1693		return BadValue;
1694	    }
1695#ifdef XKB
1696            if (!noXkbExtension) {
1697                XkbEventCauseRec cause;
1698                XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client);
1699                XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))),
1700				 			ctrl.leds, &cause);
1701                ctrl.leds = keybd->kbdfeed->ctrl.leds;
1702            }
1703#endif
1704	    break;
1705	case KBKey:
1706	    key = (KeyCode)*vlist;
1707	    vlist++;
1708	    if ((KeyCode)key < inputInfo.keyboard->key->curKeySyms.minKeyCode ||
1709		(KeyCode)key > inputInfo.keyboard->key->curKeySyms.maxKeyCode) {
1710		client->errorValue = key;
1711		return BadValue;
1712	    }
1713	    if (!(mask & KBAutoRepeatMode))
1714		return BadMatch;
1715	    break;
1716	case KBAutoRepeatMode:
1717	    i = (key >> 3);
1718	    mask = (1 << (key & 7));
1719	    t = (CARD8)*vlist;
1720	    vlist++;
1721#ifdef XKB
1722            if (!noXkbExtension && key != DO_ALL)
1723                XkbDisableComputedAutoRepeats(keybd,key);
1724#endif
1725	    if (t == AutoRepeatModeOff) {
1726		if (key == DO_ALL)
1727		    ctrl.autoRepeat = FALSE;
1728		else
1729		    ctrl.autoRepeats[i] &= ~mask;
1730	    }
1731	    else if (t == AutoRepeatModeOn) {
1732		if (key == DO_ALL)
1733		    ctrl.autoRepeat = TRUE;
1734		else
1735		    ctrl.autoRepeats[i] |= mask;
1736	    }
1737	    else if (t == AutoRepeatModeDefault) {
1738		if (key == DO_ALL)
1739		    ctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
1740		else
1741		    ctrl.autoRepeats[i] =
1742			    (ctrl.autoRepeats[i] & ~mask) |
1743			    (defaultKeyboardControl.autoRepeats[i] & mask);
1744	    }
1745	    else {
1746		client->errorValue = t;
1747		return BadValue;
1748	    }
1749	    break;
1750	default:
1751	    client->errorValue = mask;
1752	    return BadValue;
1753	}
1754    }
1755    keybd->kbdfeed->ctrl = ctrl;
1756
1757#ifdef XKB
1758    /* The XKB RepeatKeys control and core protocol global autorepeat */
1759    /* value are linked	*/
1760    if (!noXkbExtension)
1761        XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat);
1762    else
1763#endif
1764        (*keybd->kbdfeed->CtrlProc)(keybd, &keybd->kbdfeed->ctrl);
1765
1766    return Success;
1767
1768#undef DO_ALL
1769}
1770
1771int
1772ProcChangeKeyboardControl (ClientPtr client)
1773{
1774    XID *vlist;
1775    BITS32 vmask;
1776    int ret = Success, error = Success;
1777    DeviceIntPtr pDev = NULL;
1778    REQUEST(xChangeKeyboardControlReq);
1779
1780    REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
1781
1782    vmask = stuff->mask;
1783    vlist = (XID *)&stuff[1];
1784
1785    if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask))
1786	return BadLength;
1787
1788    for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
1789        if ((pDev->coreEvents || pDev == inputInfo.keyboard) &&
1790            pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
1791            if (!XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE))
1792                return BadAccess;
1793        }
1794    }
1795
1796    for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
1797        if ((pDev->coreEvents || pDev == inputInfo.keyboard) &&
1798            pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
1799            ret = DoChangeKeyboardControl(client, pDev, vlist, vmask);
1800            if (ret != Success)
1801                error = ret;
1802        }
1803    }
1804
1805    return error;
1806}
1807
1808int
1809ProcGetKeyboardControl (ClientPtr client)
1810{
1811    int i;
1812    KeybdCtrl *ctrl = &inputInfo.keyboard->kbdfeed->ctrl;
1813    xGetKeyboardControlReply rep;
1814
1815    REQUEST_SIZE_MATCH(xReq);
1816    rep.type = X_Reply;
1817    rep.length = 5;
1818    rep.sequenceNumber = client->sequence;
1819    rep.globalAutoRepeat = ctrl->autoRepeat;
1820    rep.keyClickPercent = ctrl->click;
1821    rep.bellPercent = ctrl->bell;
1822    rep.bellPitch = ctrl->bell_pitch;
1823    rep.bellDuration = ctrl->bell_duration;
1824    rep.ledMask = ctrl->leds;
1825    for (i = 0; i < 32; i++)
1826	rep.map[i] = ctrl->autoRepeats[i];
1827    WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep);
1828    return Success;
1829}
1830
1831int
1832ProcBell(ClientPtr client)
1833{
1834    DeviceIntPtr keybd = inputInfo.keyboard;
1835    int base = keybd->kbdfeed->ctrl.bell;
1836    int newpercent;
1837    REQUEST(xBellReq);
1838    REQUEST_SIZE_MATCH(xBellReq);
1839
1840    if (!keybd->kbdfeed->BellProc)
1841        return BadDevice;
1842
1843    if (stuff->percent < -100 || stuff->percent > 100) {
1844	client->errorValue = stuff->percent;
1845	return BadValue;
1846    }
1847
1848    newpercent = (base * stuff->percent) / 100;
1849    if (stuff->percent < 0)
1850        newpercent = base + newpercent;
1851    else
1852    	newpercent = base - newpercent + stuff->percent;
1853
1854    for (keybd = inputInfo.devices; keybd; keybd = keybd->next) {
1855        if ((keybd->coreEvents || keybd == inputInfo.keyboard) &&
1856            keybd->kbdfeed && keybd->kbdfeed->BellProc) {
1857#ifdef XKB
1858            if (!noXkbExtension)
1859                XkbHandleBell(FALSE, FALSE, keybd, newpercent,
1860                              &keybd->kbdfeed->ctrl, 0, None, NULL, client);
1861            else
1862#endif
1863                (*keybd->kbdfeed->BellProc)(newpercent, keybd,
1864                                            &keybd->kbdfeed->ctrl, 0);
1865        }
1866    }
1867
1868    return Success;
1869}
1870
1871int
1872ProcChangePointerControl(ClientPtr client)
1873{
1874    DeviceIntPtr mouse = inputInfo.pointer;
1875    PtrCtrl ctrl;		/* might get BadValue part way through */
1876    REQUEST(xChangePointerControlReq);
1877
1878    REQUEST_SIZE_MATCH(xChangePointerControlReq);
1879
1880    if (!mouse->ptrfeed->CtrlProc)
1881        return BadDevice;
1882
1883    ctrl = mouse->ptrfeed->ctrl;
1884    if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) {
1885	client->errorValue = stuff->doAccel;
1886	return(BadValue);
1887    }
1888    if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) {
1889	client->errorValue = stuff->doThresh;
1890	return(BadValue);
1891    }
1892    if (stuff->doAccel) {
1893	if (stuff->accelNum == -1) {
1894	    ctrl.num = defaultPointerControl.num;
1895        }
1896	else if (stuff->accelNum < 0) {
1897	    client->errorValue = stuff->accelNum;
1898	    return BadValue;
1899	}
1900	else {
1901            ctrl.num = stuff->accelNum;
1902        }
1903
1904	if (stuff->accelDenum == -1) {
1905	    ctrl.den = defaultPointerControl.den;
1906        }
1907	else if (stuff->accelDenum <= 0) {
1908	    client->errorValue = stuff->accelDenum;
1909	    return BadValue;
1910	}
1911	else {
1912            ctrl.den = stuff->accelDenum;
1913        }
1914    }
1915    if (stuff->doThresh) {
1916	if (stuff->threshold == -1) {
1917	    ctrl.threshold = defaultPointerControl.threshold;
1918        }
1919	else if (stuff->threshold < 0) {
1920	    client->errorValue = stuff->threshold;
1921	    return BadValue;
1922	}
1923	else {
1924            ctrl.threshold = stuff->threshold;
1925        }
1926    }
1927
1928
1929    for (mouse = inputInfo.devices; mouse; mouse = mouse->next) {
1930        if ((mouse->coreEvents || mouse == inputInfo.pointer) &&
1931            mouse->ptrfeed && mouse->ptrfeed->CtrlProc) {
1932            mouse->ptrfeed->ctrl = ctrl;
1933            (*mouse->ptrfeed->CtrlProc)(mouse, &mouse->ptrfeed->ctrl);
1934        }
1935    }
1936
1937    return Success;
1938}
1939
1940int
1941ProcGetPointerControl(ClientPtr client)
1942{
1943    PtrCtrl *ctrl = &inputInfo.pointer->ptrfeed->ctrl;
1944    xGetPointerControlReply rep;
1945
1946    REQUEST_SIZE_MATCH(xReq);
1947    rep.type = X_Reply;
1948    rep.length = 0;
1949    rep.sequenceNumber = client->sequence;
1950    rep.threshold = ctrl->threshold;
1951    rep.accelNumerator = ctrl->num;
1952    rep.accelDenominator = ctrl->den;
1953    WriteReplyToClient(client, sizeof(xGenericReply), &rep);
1954    return Success;
1955}
1956
1957void
1958MaybeStopHint(DeviceIntPtr dev, ClientPtr client)
1959{
1960    GrabPtr grab = dev->grab;
1961
1962    if ((grab && SameClient(grab, client) &&
1963	 ((grab->eventMask & PointerMotionHintMask) ||
1964	  (grab->ownerEvents &&
1965	   (EventMaskForClient(dev->valuator->motionHintWindow, client) &
1966	    PointerMotionHintMask)))) ||
1967	(!grab &&
1968	 (EventMaskForClient(dev->valuator->motionHintWindow, client) &
1969	  PointerMotionHintMask)))
1970	dev->valuator->motionHintWindow = NullWindow;
1971}
1972
1973int
1974ProcGetMotionEvents(ClientPtr client)
1975{
1976    WindowPtr pWin;
1977    xTimecoord * coords = (xTimecoord *) NULL;
1978    xGetMotionEventsReply rep;
1979    int i, count, xmin, xmax, ymin, ymax, rc;
1980    unsigned long nEvents;
1981    DeviceIntPtr mouse = inputInfo.pointer;
1982    TimeStamp start, stop;
1983    REQUEST(xGetMotionEventsReq);
1984
1985    REQUEST_SIZE_MATCH(xGetMotionEventsReq);
1986    rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess);
1987    if (rc != Success)
1988	return rc;
1989    if (mouse->valuator->motionHintWindow)
1990	MaybeStopHint(mouse, client);
1991    rep.type = X_Reply;
1992    rep.sequenceNumber = client->sequence;
1993    nEvents = 0;
1994    start = ClientTimeToServerTime(stuff->start);
1995    stop = ClientTimeToServerTime(stuff->stop);
1996    if ((CompareTimeStamps(start, stop) != LATER) &&
1997	(CompareTimeStamps(start, currentTime) != LATER) &&
1998	mouse->valuator->numMotionEvents)
1999    {
2000	if (CompareTimeStamps(stop, currentTime) == LATER)
2001	    stop = currentTime;
2002	coords = (xTimecoord *)ALLOCATE_LOCAL(mouse->valuator->numMotionEvents
2003					      * sizeof(xTimecoord));
2004	if (!coords)
2005	    return BadAlloc;
2006	count = (*mouse->valuator->GetMotionProc) (mouse, coords,
2007						   start.milliseconds,
2008						   stop.milliseconds,
2009						   pWin->drawable.pScreen);
2010	xmin = pWin->drawable.x - wBorderWidth (pWin);
2011	xmax = pWin->drawable.x + (int)pWin->drawable.width +
2012		wBorderWidth (pWin);
2013	ymin = pWin->drawable.y - wBorderWidth (pWin);
2014	ymax = pWin->drawable.y + (int)pWin->drawable.height +
2015		wBorderWidth (pWin);
2016	for (i = 0; i < count; i++)
2017	    if ((xmin <= coords[i].x) && (coords[i].x < xmax) &&
2018		    (ymin <= coords[i].y) && (coords[i].y < ymax))
2019	    {
2020		coords[nEvents].time = coords[i].time;
2021		coords[nEvents].x = coords[i].x - pWin->drawable.x;
2022		coords[nEvents].y = coords[i].y - pWin->drawable.y;
2023		nEvents++;
2024	    }
2025    }
2026    rep.length = nEvents * (sizeof(xTimecoord) >> 2);
2027    rep.nEvents = nEvents;
2028    WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep);
2029    if (nEvents)
2030    {
2031	client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite;
2032	WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord),
2033				 (char *)coords);
2034    }
2035    if (coords)
2036	DEALLOCATE_LOCAL(coords);
2037    return Success;
2038}
2039
2040int
2041ProcQueryKeymap(ClientPtr client)
2042{
2043    xQueryKeymapReply rep;
2044    int i;
2045    CARD8 *down = inputInfo.keyboard->key->down;
2046
2047    REQUEST_SIZE_MATCH(xReq);
2048    rep.type = X_Reply;
2049    rep.sequenceNumber = client->sequence;
2050    rep.length = 2;
2051
2052    if (XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE))
2053	for (i = 0; i<32; i++)
2054	    rep.map[i] = down[i];
2055    else
2056	bzero((char *)&rep.map[0], 32);
2057
2058    WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
2059    return Success;
2060}
2061