]> git.sesse.net Git - rdpsrv/blobdiff - Xserver/programs/Xserver/dix/devices.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / programs / Xserver / dix / devices.c
diff --git a/Xserver/programs/Xserver/dix/devices.c b/Xserver/programs/Xserver/dix/devices.c
new file mode 100644 (file)
index 0000000..90a2f61
--- /dev/null
@@ -0,0 +1,1753 @@
+/************************************************************
+
+Copyright (c) 1987  X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+********************************************************/
+
+
+/* $XFree86: xc/programs/Xserver/dix/devices.c,v 3.11 1996/12/24 02:23:43 dawes Exp $ */
+/* $XConsortium: devices.c /main/54 1996/09/25 00:45:00 dpw $ */
+
+#include "X.h"
+#include "misc.h"
+#include "resource.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include "Xproto.h"
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "site.h"
+#define        XKB_IN_SERVER
+#ifdef XKB
+#include "XKBsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "extensions/security.h"
+#endif
+
+#include "dispatch.h"
+#include "swaprep.h"
+#include "dixevents.h"
+
+DeviceIntPtr
+_AddInputDevice(deviceProc, autoStart)
+    DeviceProc deviceProc;
+    Bool autoStart;
+{
+    register DeviceIntPtr dev;
+
+    if (inputInfo.numDevices >= MAX_DEVICES)
+       return (DeviceIntPtr)NULL;
+    dev = (DeviceIntPtr) xalloc(sizeof(DeviceIntRec));
+    if (!dev)
+       return (DeviceIntPtr)NULL;
+    dev->name = (char *)NULL;
+    dev->type = 0;
+    dev->id = inputInfo.numDevices;
+    inputInfo.numDevices++;
+    dev->public.on = FALSE;
+    dev->public.processInputProc = (ProcessInputProc)NoopDDA;
+    dev->public.realInputProc = (ProcessInputProc)NoopDDA;
+    dev->public.enqueueInputProc = EnqueueEvent;
+    dev->deviceProc = deviceProc;
+    dev->startup = autoStart;
+    dev->sync.frozen = FALSE;
+    dev->sync.other = NullGrab;
+    dev->sync.state = NOT_GRABBED;
+    dev->sync.event = (xEvent *) NULL;
+    dev->sync.evcount = 0;
+    dev->grab = NullGrab;
+    dev->grabTime = currentTime;
+    dev->fromPassiveGrab = FALSE;
+    dev->key = (KeyClassPtr)NULL;
+    dev->valuator = (ValuatorClassPtr)NULL;
+    dev->button = (ButtonClassPtr)NULL;
+    dev->focus = (FocusClassPtr)NULL;
+    dev->proximity = (ProximityClassPtr)NULL;
+    dev->kbdfeed = (KbdFeedbackPtr)NULL;
+    dev->ptrfeed = (PtrFeedbackPtr)NULL;
+    dev->intfeed = (IntegerFeedbackPtr)NULL;
+    dev->stringfeed = (StringFeedbackPtr)NULL;
+    dev->bell = (BellFeedbackPtr)NULL;
+    dev->leds = (LedFeedbackPtr)NULL;
+    dev->next = inputInfo.off_devices;
+#ifdef XKB
+    dev->xkb_interest= NULL;
+#endif
+    inputInfo.off_devices = dev;
+    return dev;
+}
+
+Bool
+EnableDevice(dev)
+    register DeviceIntPtr dev;
+{
+    register DeviceIntPtr *prev;
+
+    for (prev = &inputInfo.off_devices;
+        *prev && (*prev != dev);
+        prev = &(*prev)->next)
+       ;
+    if ((*prev != dev) || !dev->inited ||
+       ((*dev->deviceProc)(dev, DEVICE_ON) != Success))
+       return FALSE;
+    *prev = dev->next;
+    dev->next = inputInfo.devices;
+    inputInfo.devices = dev;
+    return TRUE;
+}
+
+Bool
+DisableDevice(dev)
+    register DeviceIntPtr dev;
+{
+    register DeviceIntPtr *prev;
+
+    for (prev = &inputInfo.devices;
+        *prev && (*prev != dev);
+        prev = &(*prev)->next)
+       ;
+    if (*prev != dev)
+       return FALSE;
+    (void)(*dev->deviceProc)(dev, DEVICE_OFF);
+    *prev = dev->next;
+    dev->next = inputInfo.off_devices;
+    inputInfo.off_devices = dev;
+    return TRUE;
+}
+
+int
+InitAndStartDevices()
+{
+    register DeviceIntPtr dev, next;
+
+    for (dev = inputInfo.off_devices; dev; dev = dev->next)
+       dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success);
+    for (dev = inputInfo.off_devices; dev; dev = next)
+    {
+       next = dev->next;
+       if (dev->inited && dev->startup)
+           (void)EnableDevice(dev);
+    }
+    for (dev = inputInfo.devices;
+        dev && (dev != inputInfo.keyboard);
+        dev = dev->next)
+       ;
+    if (!dev || (dev != inputInfo.keyboard))
+       return BadImplementation;
+    for (dev = inputInfo.devices;
+        dev && (dev != inputInfo.pointer);
+        dev = dev->next)
+       ;
+    if (!dev || (dev != inputInfo.pointer))
+       return BadImplementation;
+    return Success;
+}
+
+static void
+#if NeedFunctionPrototypes
+CloseDevice(register DeviceIntPtr dev)
+#else
+CloseDevice(dev)
+    register DeviceIntPtr dev;
+#endif
+{
+    KbdFeedbackPtr k, knext;
+    PtrFeedbackPtr p, pnext;
+    IntegerFeedbackPtr i, inext;
+    StringFeedbackPtr s, snext;
+    BellFeedbackPtr b, bnext;
+    LedFeedbackPtr l, lnext;
+
+    if (dev->inited)
+       (void)(*dev->deviceProc)(dev, DEVICE_CLOSE);
+    xfree(dev->name);
+    if (dev->key)
+    {
+#ifdef XKB
+       if (dev->key->xkbInfo)
+           XkbFreeInfo(dev->key->xkbInfo);
+#endif
+       xfree(dev->key->curKeySyms.map);
+       xfree(dev->key->modifierKeyMap);
+       xfree(dev->key);
+    }
+    xfree(dev->valuator);
+#ifdef XKB
+    if ((dev->button)&&(dev->button->xkb_acts))
+       xfree(dev->button->xkb_acts);
+#endif
+    xfree(dev->button);
+    if (dev->focus)
+    {
+       xfree(dev->focus->trace);
+       xfree(dev->focus);
+    }
+    xfree(dev->proximity);
+    for (k=dev->kbdfeed; k; k=knext)
+    {
+       knext = k->next;
+#ifdef XKB
+       if (k->xkb_sli)
+           XkbFreeSrvLedInfo(k->xkb_sli);
+#endif
+       xfree(k);
+    }
+    for (p=dev->ptrfeed; p; p=pnext)
+    {
+       pnext = p->next;
+       xfree(p);
+    }
+    for (i=dev->intfeed; i; i=inext)
+    {
+       inext = i->next;
+       xfree(i);
+    }
+    for (s=dev->stringfeed; s; s=snext)
+    {
+       snext = s->next;
+       xfree(s->ctrl.symbols_supported);
+       xfree(s->ctrl.symbols_displayed);
+       xfree(s);
+    }
+    for (b=dev->bell; b; b=bnext)
+    {
+       bnext = b->next;
+       xfree(b);
+    }
+    for (l=dev->leds; l; l=lnext)
+    {
+       lnext = l->next;
+#ifdef XKB
+       if (l->xkb_sli)
+           XkbFreeSrvLedInfo(l->xkb_sli);
+#endif
+       xfree(l);
+    }
+#ifdef XKB
+    while (dev->xkb_interest) {
+       XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource);
+    }
+#endif
+    xfree(dev->sync.event);
+    xfree(dev);
+}
+
+void
+CloseDownDevices()
+{
+    register DeviceIntPtr dev, next;
+
+    for (dev = inputInfo.devices; dev; dev = next)
+    {
+       next = dev->next;
+       CloseDevice(dev);
+    }
+    for (dev = inputInfo.off_devices; dev; dev = next)
+    {
+       next = dev->next;
+       CloseDevice(dev);
+    }
+    inputInfo.keyboard = NULL;
+    inputInfo.pointer = NULL;
+}
+
+void
+RemoveDevice(dev)
+    register DeviceIntPtr dev;
+{
+    register DeviceIntPtr prev,tmp,next;
+
+    prev= NULL;
+    for (tmp= inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
+       next = tmp->next;
+       if (tmp==dev) {
+           CloseDevice(tmp);
+           if (prev==NULL)
+               inputInfo.devices = next;
+           else
+               prev->next = next;
+           inputInfo.numDevices--;
+           if (inputInfo.keyboard == tmp)
+               inputInfo.keyboard = NULL;
+           else if (inputInfo.pointer == tmp)
+               inputInfo.pointer = NULL;
+           return;
+       }
+    }
+
+    prev= NULL;
+    for (tmp= inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
+       next = tmp->next;
+       if (tmp==dev) {
+           CloseDevice(tmp);
+           if (prev==NULL)
+               inputInfo.off_devices = next;
+           else
+               prev->next = next;
+           inputInfo.numDevices--;
+           if (inputInfo.keyboard == tmp)
+               inputInfo.keyboard = NULL;
+           else if (inputInfo.pointer == tmp)
+               inputInfo.pointer = NULL;
+           return;
+       }
+    }
+    ErrorF("Internal Error! Attempt to remove a non-existent device\n");
+    return;
+}
+
+int
+NumMotionEvents()
+{
+    return inputInfo.pointer->valuator->numMotionEvents;
+}
+
+void
+_RegisterPointerDevice(device)
+    DeviceIntPtr device;
+{
+    inputInfo.pointer = device;
+#ifdef XKB
+    if (noXkbExtension) {
+       device->public.processInputProc = CoreProcessPointerEvent;
+       device->public.realInputProc = CoreProcessPointerEvent;
+    } else {
+       device->public.processInputProc = ProcessPointerEvent;
+       device->public.realInputProc = ProcessPointerEvent;
+    }
+#else
+    device->public.processInputProc = ProcessPointerEvent;
+    device->public.realInputProc = ProcessPointerEvent;
+#endif
+    device->ActivateGrab = ActivatePointerGrab;
+    device->DeactivateGrab = DeactivatePointerGrab;
+    if (!device->name)
+    {
+       char *p = "pointer";
+       device->name = (char *)xalloc(strlen(p) + 1);
+       strcpy(device->name, p);
+    }
+}
+
+void
+_RegisterKeyboardDevice(device)
+    DeviceIntPtr device;
+{
+    inputInfo.keyboard = device;
+#ifdef XKB
+    if (noXkbExtension) {
+       device->public.processInputProc = CoreProcessKeyboardEvent;
+       device->public.realInputProc = CoreProcessKeyboardEvent;
+    } else {
+       device->public.processInputProc = ProcessKeyboardEvent;
+       device->public.realInputProc = ProcessKeyboardEvent;
+    }
+#else
+    device->public.processInputProc = ProcessKeyboardEvent;
+    device->public.realInputProc = ProcessKeyboardEvent;
+#endif
+    device->ActivateGrab = ActivateKeyboardGrab;
+    device->DeactivateGrab = DeactivateKeyboardGrab;
+    if (!device->name)
+    {
+       char *k = "keyboard";
+       device->name = (char *)xalloc(strlen(k) + 1);
+       strcpy(device->name, k);
+    }
+}
+
+DevicePtr
+LookupKeyboardDevice()
+{
+    return inputInfo.keyboard ? &inputInfo.keyboard->public : NULL;
+}
+
+DevicePtr
+LookupPointerDevice()
+{
+    return inputInfo.pointer ? &inputInfo.pointer->public : NULL;
+}
+
+DevicePtr
+LookupDevice(id)
+    int id;
+{
+    DeviceIntPtr dev;
+
+    for (dev=inputInfo.devices; dev; dev=dev->next) {
+        if (dev->id == (CARD8)id)
+            return (DevicePtr)dev;
+    }
+    for (dev=inputInfo.off_devices; dev; dev=dev->next) {
+        if (dev->id == (CARD8)id)
+            return (DevicePtr)dev;
+    }
+    return NULL;
+}
+
+void
+QueryMinMaxKeyCodes(minCode, maxCode)
+    KeyCode *minCode, *maxCode;
+{
+    if (inputInfo.keyboard) {
+       *minCode = inputInfo.keyboard->key->curKeySyms.minKeyCode;
+       *maxCode = inputInfo.keyboard->key->curKeySyms.maxKeyCode;
+    }
+}
+
+Bool
+SetKeySymsMap(dst, src)
+    register KeySymsPtr dst, src;
+{
+    int i, j;
+    int rowDif = src->minKeyCode - dst->minKeyCode;
+           /* if keysym map size changes, grow map first */
+
+    if (src->mapWidth < dst->mapWidth)
+    {
+        for (i = src->minKeyCode; i <= src->maxKeyCode; i++)
+       {
+#define SI(r, c) (((r-src->minKeyCode)*src->mapWidth) + (c))
+#define DI(r, c) (((r - dst->minKeyCode)*dst->mapWidth) + (c))
+           for (j = 0; j < src->mapWidth; j++)
+               dst->map[DI(i, j)] = src->map[SI(i, j)];
+           for (j = src->mapWidth; j < dst->mapWidth; j++)
+               dst->map[DI(i, j)] = NoSymbol;
+#undef SI
+#undef DI
+       }
+       return TRUE;
+    }
+    else if (src->mapWidth > dst->mapWidth)
+    {
+        KeySym *map;
+       int bytes = sizeof(KeySym) * src->mapWidth *
+                   (dst->maxKeyCode - dst->minKeyCode + 1);
+        map = (KeySym *)xalloc(bytes);
+       if (!map)
+           return FALSE;
+       bzero((char *)map, bytes);
+        if (dst->map)
+       {
+            for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++)
+               memmove((char *)&map[i*src->mapWidth],
+                       (char *)&dst->map[i*dst->mapWidth],
+                     dst->mapWidth * sizeof(KeySym));
+           xfree(dst->map);
+       }
+       dst->mapWidth = src->mapWidth;
+       dst->map = map;
+    }
+    memmove((char *)&dst->map[rowDif * dst->mapWidth],
+           (char *)src->map,
+         (int)(src->maxKeyCode - src->minKeyCode + 1) *
+         dst->mapWidth * sizeof(KeySym));
+    return TRUE;
+}
+
+static Bool
+#if NeedFunctionPrototypes
+InitModMap(register KeyClassPtr keyc)
+#else
+InitModMap(keyc)
+    register KeyClassPtr keyc;
+#endif
+{
+    int i, j;
+    CARD8 keysPerModifier[8];
+    CARD8 mask;
+
+    keyc->maxKeysPerModifier = 0;
+    for (i = 0; i < 8; i++)
+       keysPerModifier[i] = 0;
+    for (i = 8; i < MAP_LENGTH; i++)
+    {
+       for (j = 0, mask = 1; j < 8; j++, mask <<= 1)
+       {
+           if (mask & keyc->modifierMap[i])
+           {
+               if (++keysPerModifier[j] > keyc->maxKeysPerModifier)
+                   keyc->maxKeysPerModifier = keysPerModifier[j];
+           }
+       }
+    }
+    keyc->modifierKeyMap = (KeyCode *)xalloc(8*keyc->maxKeysPerModifier);
+    if (!keyc->modifierKeyMap && keyc->maxKeysPerModifier)
+       return (FALSE);
+    bzero((char *)keyc->modifierKeyMap, 8*(int)keyc->maxKeysPerModifier);
+    for (i = 0; i < 8; i++)
+       keysPerModifier[i] = 0;
+    for (i = 8; i < MAP_LENGTH; i++)
+    {
+       for (j = 0, mask = 1; j < 8; j++, mask <<= 1)
+       {
+           if (mask & keyc->modifierMap[i])
+           {
+               keyc->modifierKeyMap[(j*keyc->maxKeysPerModifier) +
+                                    keysPerModifier[j]] = i;
+               keysPerModifier[j]++;
+           }
+       }
+    }
+    return TRUE;
+}
+
+Bool
+InitKeyClassDeviceStruct(dev, pKeySyms, pModifiers)
+    DeviceIntPtr dev;
+    KeySymsPtr pKeySyms;
+    CARD8 pModifiers[];
+{
+    int i;
+    register KeyClassPtr keyc;
+
+    keyc = (KeyClassPtr)xalloc(sizeof(KeyClassRec));
+    if (!keyc)
+       return FALSE;
+    keyc->curKeySyms.map = (KeySym *)NULL;
+    keyc->curKeySyms.mapWidth = 0;
+    keyc->curKeySyms.minKeyCode = pKeySyms->minKeyCode;
+    keyc->curKeySyms.maxKeyCode = pKeySyms->maxKeyCode;
+    keyc->modifierKeyMap = (KeyCode *)NULL;
+    keyc->state = 0;
+    keyc->prev_state = 0;
+    if (pModifiers)
+       memmove((char *)keyc->modifierMap, (char *)pModifiers, MAP_LENGTH);
+    else
+       bzero((char *)keyc->modifierMap, MAP_LENGTH);
+    bzero((char *)keyc->down, DOWN_LENGTH);
+    for (i = 0; i < 8; i++)
+       keyc->modifierKeyCount[i] = 0;
+    if (!SetKeySymsMap(&keyc->curKeySyms, pKeySyms) || !InitModMap(keyc))
+    {
+       xfree(keyc->curKeySyms.map);
+       xfree(keyc->modifierKeyMap);
+       xfree(keyc);
+       return FALSE;
+    }
+    dev->key = keyc;
+#ifdef XKB
+    dev->key->xkbInfo= NULL;
+    if (!noXkbExtension) XkbInitDevice(dev);
+#endif
+    return TRUE;
+}
+
+Bool
+InitButtonClassDeviceStruct(dev, numButtons, map)
+    register DeviceIntPtr dev;
+    int numButtons;
+    CARD8 *map;
+{
+    register ButtonClassPtr butc;
+    int i;
+
+    butc = (ButtonClassPtr)xalloc(sizeof(ButtonClassRec));
+    if (!butc)
+       return FALSE;
+    butc->numButtons = numButtons;
+    for (i = 1; i <= numButtons; i++)
+       butc->map[i] = map[i];
+    butc->buttonsDown = 0;
+    butc->state = 0;
+    butc->motionMask = 0;
+    bzero((char *)butc->down, DOWN_LENGTH);
+#ifdef XKB
+    butc->xkb_acts=    NULL;
+#endif
+    dev->button = butc;
+    return TRUE;
+}
+
+Bool
+InitValuatorClassDeviceStruct(dev, numAxes, motionProc, numMotionEvents, mode)
+    DeviceIntPtr dev;
+    ValuatorMotionProcPtr motionProc;
+    int numAxes;
+    int numMotionEvents;
+    int mode;
+{
+    int i;
+    register ValuatorClassPtr valc;
+
+    valc = (ValuatorClassPtr)xalloc(sizeof(ValuatorClassRec) +
+                                   numAxes * sizeof(AxisInfo) +
+                                   numAxes * sizeof(unsigned int));
+    if (!valc)
+       return FALSE;
+    valc->GetMotionProc = motionProc;
+    valc->numMotionEvents = numMotionEvents;
+    valc->motionHintWindow = NullWindow;
+    valc->numAxes = numAxes;
+    valc->mode = mode;
+    valc->axes = (AxisInfoPtr)(valc + 1);
+    valc->axisVal = (int *)(valc->axes + numAxes);
+    for (i=0; i<numAxes; i++)
+       valc->axisVal[i]=0;
+    dev->valuator = valc;
+    return TRUE;
+}
+
+Bool
+InitFocusClassDeviceStruct(dev)
+    DeviceIntPtr dev;
+{
+    register FocusClassPtr focc;
+
+    focc = (FocusClassPtr)xalloc(sizeof(FocusClassRec));
+    if (!focc)
+       return FALSE;
+    focc->win = PointerRootWin;
+    focc->revert = None;
+    focc->time = currentTime;
+    focc->trace = (WindowPtr *)NULL;
+    focc->traceSize = 0;
+    focc->traceGood = 0;
+    dev->focus = focc;
+    return TRUE;
+}
+
+Bool
+InitKbdFeedbackClassDeviceStruct(dev, bellProc, controlProc)
+    DeviceIntPtr dev;
+    BellProcPtr bellProc;
+    KbdCtrlProcPtr controlProc;
+{
+    register KbdFeedbackPtr feedc;
+
+    feedc = (KbdFeedbackPtr)xalloc(sizeof(KbdFeedbackClassRec));
+    if (!feedc)
+       return FALSE;
+    feedc->BellProc = bellProc;
+    feedc->CtrlProc = controlProc;
+#ifdef XKB
+    defaultKeyboardControl.autoRepeat = TRUE;
+#endif
+    feedc->ctrl = defaultKeyboardControl;
+    feedc->ctrl.id = 0;
+    if ((feedc->next = dev->kbdfeed) != 0)
+       feedc->ctrl.id = dev->kbdfeed->ctrl.id + 1;
+    dev->kbdfeed = feedc;
+#ifdef XKB
+    feedc->xkb_sli= NULL;
+    if (!noXkbExtension)
+       XkbFinishDeviceInit(dev);
+#endif
+    (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl);
+    return TRUE;
+}
+
+Bool
+InitPtrFeedbackClassDeviceStruct(dev, controlProc)
+    DeviceIntPtr dev;
+    PtrCtrlProcPtr controlProc;
+{
+    register PtrFeedbackPtr feedc;
+
+    feedc = (PtrFeedbackPtr)xalloc(sizeof(PtrFeedbackClassRec));
+    if (!feedc)
+       return FALSE;
+    feedc->CtrlProc = controlProc;
+#ifdef sgi
+    feedc->ctrl.num = 1;
+    feedc->ctrl.den = 1;
+    feedc->ctrl.threshold = 1;
+#else
+    feedc->ctrl = defaultPointerControl;
+#endif
+    feedc->ctrl.id = 0;
+    if ( (feedc->next = dev->ptrfeed) )
+        feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1;
+    dev->ptrfeed = feedc;
+    (*controlProc)(dev, &feedc->ctrl);
+    return TRUE;
+}
+
+
+LedCtrl defaultLedControl = {
+       DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0};
+
+BellCtrl defaultBellControl = {
+       DEFAULT_BELL,
+       DEFAULT_BELL_PITCH,
+       DEFAULT_BELL_DURATION,
+       0};
+
+IntegerCtrl defaultIntegerControl = {
+       DEFAULT_INT_RESOLUTION,
+       DEFAULT_INT_MIN_VALUE,
+       DEFAULT_INT_MAX_VALUE,
+       DEFAULT_INT_DISPLAYED,
+       0};
+
+Bool
+InitStringFeedbackClassDeviceStruct (dev, controlProc, max_symbols,
+                                    num_symbols_supported, symbols)
+    DeviceIntPtr dev;
+    StringCtrlProcPtr controlProc;
+    int max_symbols;
+    int num_symbols_supported;
+    KeySym *symbols;
+{
+    int i;
+    register StringFeedbackPtr feedc;
+
+    feedc = (StringFeedbackPtr)xalloc(sizeof(StringFeedbackClassRec));
+    if (!feedc)
+       return FALSE;
+    feedc->CtrlProc = controlProc;
+    feedc->ctrl.num_symbols_supported = num_symbols_supported;
+    feedc->ctrl.num_symbols_displayed = 0;
+    feedc->ctrl.max_symbols = max_symbols;
+    feedc->ctrl.symbols_supported = (KeySym *) 
+       xalloc (sizeof (KeySym) * num_symbols_supported);
+    feedc->ctrl.symbols_displayed = (KeySym *) 
+       xalloc (sizeof (KeySym) * max_symbols);
+    if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed)
+    {
+       if (feedc->ctrl.symbols_supported)
+           xfree(feedc->ctrl.symbols_supported);
+       if (feedc->ctrl.symbols_displayed)
+           xfree(feedc->ctrl.symbols_displayed);
+       xfree(feedc);
+       return FALSE;
+    }
+    for (i=0; i<num_symbols_supported; i++)
+       *(feedc->ctrl.symbols_supported+i) = *symbols++;
+    for (i=0; i<max_symbols; i++)
+       *(feedc->ctrl.symbols_displayed+i) = (KeySym) NULL;
+    feedc->ctrl.id = 0;
+    if ( (feedc->next = dev->stringfeed) )
+       feedc->ctrl.id = dev->stringfeed->ctrl.id + 1;
+    dev->stringfeed = feedc;
+    (*controlProc)(dev, &feedc->ctrl);
+    return TRUE;
+}
+
+Bool
+InitBellFeedbackClassDeviceStruct (dev, bellProc, controlProc)
+    DeviceIntPtr dev;
+    BellProcPtr bellProc;
+    BellCtrlProcPtr controlProc;
+{
+    register BellFeedbackPtr feedc;
+
+    feedc = (BellFeedbackPtr)xalloc(sizeof(BellFeedbackClassRec));
+    if (!feedc)
+       return FALSE;
+    feedc->CtrlProc = controlProc;
+    feedc->BellProc = bellProc;
+    feedc->ctrl = defaultBellControl;
+    feedc->ctrl.id = 0;
+    if ( (feedc->next = dev->bell) )
+       feedc->ctrl.id = dev->bell->ctrl.id + 1;
+    dev->bell = feedc;
+    (*controlProc)(dev, &feedc->ctrl);
+    return TRUE;
+}
+
+Bool
+InitLedFeedbackClassDeviceStruct (dev, controlProc)
+    DeviceIntPtr dev;
+    LedCtrlProcPtr controlProc;
+{
+    register LedFeedbackPtr feedc;
+
+    feedc = (LedFeedbackPtr)xalloc(sizeof(LedFeedbackClassRec));
+    if (!feedc)
+       return FALSE;
+    feedc->CtrlProc = controlProc;
+    feedc->ctrl = defaultLedControl;
+    feedc->ctrl.id = 0;
+    if ( (feedc->next = dev->leds) )
+       feedc->ctrl.id = dev->leds->ctrl.id + 1;
+#ifdef XKB
+    feedc->xkb_sli= NULL;
+#endif
+    dev->leds = feedc;
+    (*controlProc)(dev, &feedc->ctrl);
+    return TRUE;
+}
+
+Bool
+InitIntegerFeedbackClassDeviceStruct (dev, controlProc)
+    DeviceIntPtr dev;
+    IntegerCtrlProcPtr controlProc;
+{
+    register IntegerFeedbackPtr feedc;
+
+    feedc = (IntegerFeedbackPtr)xalloc(sizeof(IntegerFeedbackClassRec));
+    if (!feedc)
+       return FALSE;
+    feedc->CtrlProc = controlProc;
+    feedc->ctrl = defaultIntegerControl;
+    feedc->ctrl.id = 0;
+    if ( (feedc->next = dev->intfeed) )
+       feedc->ctrl.id = dev->intfeed->ctrl.id + 1;
+    dev->intfeed = feedc;
+    (*controlProc)(dev, &feedc->ctrl);
+    return TRUE;
+}
+
+Bool
+InitPointerDeviceStruct(device, map, numButtons, motionProc, controlProc,
+                       numMotionEvents)
+    DevicePtr device;
+    CARD8 *map;
+    int numButtons;
+    PtrCtrlProcPtr controlProc;
+    ValuatorMotionProcPtr motionProc;
+    int numMotionEvents;
+{
+    DeviceIntPtr dev = (DeviceIntPtr)device;
+
+    return(InitButtonClassDeviceStruct(dev, numButtons, map) &&
+          InitValuatorClassDeviceStruct(dev, 2, motionProc,
+                                        numMotionEvents, 0) &&
+          InitPtrFeedbackClassDeviceStruct(dev, controlProc));
+}
+
+Bool
+InitKeyboardDeviceStruct(device, pKeySyms, pModifiers, bellProc, controlProc)
+    DevicePtr device;
+    KeySymsPtr pKeySyms;
+    CARD8 pModifiers[];
+    BellProcPtr bellProc;
+    KbdCtrlProcPtr controlProc;
+{
+    DeviceIntPtr dev = (DeviceIntPtr)device;
+
+    return(InitKeyClassDeviceStruct(dev, pKeySyms, pModifiers) &&
+          InitFocusClassDeviceStruct(dev) &&
+          InitKbdFeedbackClassDeviceStruct(dev, bellProc, controlProc));
+}
+
+void
+SendMappingNotify(request, firstKeyCode, count, client)
+    unsigned int request, count;
+    unsigned int firstKeyCode;
+    ClientPtr  client;
+{
+    int i;
+    xEvent event;
+
+    event.u.u.type = MappingNotify;
+    event.u.mappingNotify.request = request;
+    if (request == MappingKeyboard)
+    {
+        event.u.mappingNotify.firstKeyCode = firstKeyCode;
+        event.u.mappingNotify.count = count;
+    }
+#ifdef XKB
+    if (!noXkbExtension &&
+       ((request == MappingKeyboard) || (request == MappingModifier))) {
+       XkbApplyMappingChange(inputInfo.keyboard,request,firstKeyCode,count,
+                                                                       client);
+    }
+#endif
+
+   /* 0 is the server client */
+    for (i=1; i<currentMaxClients; i++)
+    {
+       if (clients[i] && clients[i]->clientState == ClientStateRunning)
+       {
+#ifdef XKB
+           if (!noXkbExtension &&
+               (request == MappingKeyboard) &&
+               (clients[i]->xkbClientFlags != 0) &&
+               (clients[i]->mapNotifyMask&XkbKeySymsMask))
+               continue;
+#endif
+           event.u.u.sequenceNumber = clients[i]->sequence;
+           WriteEventsToClient(clients[i], 1, &event);
+       }
+    }
+}
+
+/*
+ * n-squared algorithm. n < 255 and don't want to copy the whole thing and
+ * sort it to do the checking. How often is it called? Just being lazy?
+ */
+Bool
+BadDeviceMap(buff, length, low, high, errval)
+    register BYTE *buff;
+    int length;
+    unsigned low, high;
+    XID *errval;
+{
+    register int     i, j;
+
+    for (i = 0; i < length; i++)
+       if (buff[i])                   /* only check non-zero elements */
+       {
+           if ((low > buff[i]) || (high < buff[i]))
+           {
+               *errval = buff[i];
+               return TRUE;
+           }
+           for (j = i + 1; j < length; j++)
+               if (buff[i] == buff[j])
+               {
+                   *errval = buff[i];
+                   return TRUE;
+               }
+       }
+    return FALSE;
+}
+
+Bool
+AllModifierKeysAreUp(dev, map1, per1, map2, per2)
+    register DeviceIntPtr dev;
+    register CARD8 *map1, *map2;
+    int per1, per2;
+{
+    register int i, j, k;
+    register CARD8 *down = dev->key->down;
+
+    for (i = 8; --i >= 0; map2 += per2)
+    {
+       for (j = per1; --j >= 0; map1++)
+       {
+           if (*map1 && BitIsOn(down, *map1))
+           {
+               for (k = per2; (--k >= 0) && (*map1 != map2[k]);)
+                 ;
+               if (k < 0)
+                   return FALSE;
+           }
+       }
+    }
+    return TRUE;
+}
+
+int 
+ProcSetModifierMapping(client)
+    ClientPtr client;
+{
+    xSetModifierMappingReply rep;
+    REQUEST(xSetModifierMappingReq);
+    KeyCode *inputMap;
+    int inputMapLen;
+    register int i;
+    DeviceIntPtr keybd = inputInfo.keyboard;
+    register KeyClassPtr keyc = keybd->key;
+    
+    REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
+
+    if (client->req_len != ((stuff->numKeyPerModifier<<1) +
+                           (sizeof (xSetModifierMappingReq)>>2)))
+       return BadLength;
+
+    inputMapLen = 8*stuff->numKeyPerModifier;
+    inputMap = (KeyCode *)&stuff[1];
+
+    /*
+     * Now enforce the restriction that "all of the non-zero keycodes must be
+     * in the range specified by min-keycode and max-keycode in the
+     * connection setup (else a Value error)"
+     */
+    i = inputMapLen;
+    while (i--)
+    {
+       if (inputMap[i]
+           && (inputMap[i] < keyc->curKeySyms.minKeyCode
+               || inputMap[i] > keyc->curKeySyms.maxKeyCode))
+       {
+           client->errorValue = inputMap[i];
+           return BadValue;
+       }
+    }
+
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, keybd, TRUE))
+       return BadAccess;
+#endif 
+
+#ifdef LBX
+    LbxFlushModifierMapTag();
+#endif
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.success = MappingSuccess;
+
+    /*
+     * Now enforce the restriction that none of the old or new
+     * modifier keys may be down while we change the mapping,  and
+     * that the DDX layer likes the choice.
+     */
+    if (!AllModifierKeysAreUp(keybd, keyc->modifierKeyMap,
+                             (int)keyc->maxKeysPerModifier,
+                             inputMap, (int)stuff->numKeyPerModifier)
+           ||
+       !AllModifierKeysAreUp(keybd, inputMap, (int)stuff->numKeyPerModifier,
+                             keyc->modifierKeyMap,
+                             (int)keyc->maxKeysPerModifier))
+    {
+       rep.success = MappingBusy;
+    }
+    else
+    {
+       for (i = 0; i < inputMapLen; i++)
+       {
+           if (inputMap[i] && !LegalModifier(inputMap[i], (DevicePtr)keybd))
+           {
+               rep.success = MappingFailed;
+               break;
+           }
+       }
+    }
+
+    if (rep.success == MappingSuccess)
+    {
+       KeyCode *map;
+       /*
+        *      Now build the keyboard's modifier bitmap from the
+        *      list of keycodes.
+        */
+       map = (KeyCode *)xalloc(inputMapLen);
+       if (!map && inputMapLen)
+           return BadAlloc;
+       if (keyc->modifierKeyMap)
+           xfree(keyc->modifierKeyMap);
+       keyc->modifierKeyMap = map;
+       memmove((char *)map, (char *)inputMap, inputMapLen);
+
+       keyc->maxKeysPerModifier = stuff->numKeyPerModifier;
+       for (i = 0; i < MAP_LENGTH; i++)
+           keyc->modifierMap[i] = 0;
+       for (i = 0; i < inputMapLen; i++)
+       {
+           if (inputMap[i])
+               keyc->modifierMap[inputMap[i]] |=
+                   (1<<(((unsigned int)i)/keyc->maxKeysPerModifier));
+       }
+    }
+
+    if (rep.success == MappingSuccess)
+        SendMappingNotify(MappingModifier, 0, 0, client);
+
+    WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
+
+    return(client->noClientException);
+}
+
+int
+ProcGetModifierMapping(client)
+    ClientPtr client;
+{
+    xGetModifierMappingReply rep;
+    register KeyClassPtr keyc = inputInfo.keyboard->key;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.numKeyPerModifier = keyc->maxKeysPerModifier;
+    rep.sequenceNumber = client->sequence;
+    /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
+    rep.length = keyc->maxKeysPerModifier << 1;
+
+    WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep);
+
+    /* Use the (modified by DDX) map that SetModifierMapping passed in */
+    (void)WriteToClient(client, (int)(keyc->maxKeysPerModifier << 3),
+                       (char *)keyc->modifierKeyMap);
+    return client->noClientException;
+}
+
+int
+ProcChangeKeyboardMapping(client)
+    ClientPtr client;
+{
+    REQUEST(xChangeKeyboardMappingReq);
+    unsigned len;
+    KeySymsRec keysyms;
+    register KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
+    REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
+
+    len = client->req_len - (sizeof(xChangeKeyboardMappingReq) >> 2);  
+    if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode))
+            return BadLength;
+    if ((stuff->firstKeyCode < curKeySyms->minKeyCode) ||
+       (stuff->firstKeyCode > curKeySyms->maxKeyCode))
+    {
+           client->errorValue = stuff->firstKeyCode;
+           return BadValue;
+    }
+    if ( ((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) >
+         curKeySyms->maxKeyCode) ||
+       (stuff->keySymsPerKeyCode == 0))
+    {
+           client->errorValue = stuff->keySymsPerKeyCode;
+           return BadValue;
+    }
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard,
+                                  TRUE))
+       return BadAccess;
+#endif 
+    keysyms.minKeyCode = stuff->firstKeyCode;
+    keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1;
+    keysyms.mapWidth = stuff->keySymsPerKeyCode;
+    keysyms.map = (KeySym *)&stuff[1];
+    if (!SetKeySymsMap(curKeySyms, &keysyms))
+       return BadAlloc;
+#ifdef LBX
+    LbxFlushKeyboardMapTag();
+#endif
+    SendMappingNotify(MappingKeyboard, stuff->firstKeyCode, stuff->keyCodes,
+                                                                       client);
+    return client->noClientException;
+
+}
+
+int
+ProcSetPointerMapping(client)
+    ClientPtr client;
+{
+    REQUEST(xSetPointerMappingReq);
+    BYTE *map;
+    xSetPointerMappingReply rep;
+    register unsigned int i;
+    DeviceIntPtr mouse = inputInfo.pointer;
+
+    REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq);
+    if (client->req_len != (sizeof(xSetPointerMappingReq)+stuff->nElts+3) >> 2)
+       return BadLength;
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.success = MappingSuccess;
+    map = (BYTE *)&stuff[1];
+    if (stuff->nElts != mouse->button->numButtons)
+    {
+       client->errorValue = stuff->nElts;
+       return BadValue;
+    }
+    if (BadDeviceMap(&map[0], (int)stuff->nElts, 1, 255, &client->errorValue))
+       return BadValue;
+    for (i=0; i < stuff->nElts; i++)
+       if ((mouse->button->map[i + 1] != map[i]) &&
+           BitIsOn(mouse->button->down, i + 1))
+       {
+           rep.success = MappingBusy;
+           WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
+            return Success;
+       }
+    for (i = 0; i < stuff->nElts; i++)
+       mouse->button->map[i + 1] = map[i];
+    SendMappingNotify(MappingPointer, 0, 0, client);
+    WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
+    return Success;
+}
+
+int
+ProcGetKeyboardMapping(client)
+    ClientPtr client;
+{
+    xGetKeyboardMappingReply rep;
+    REQUEST(xGetKeyboardMappingReq);
+    KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
+
+    REQUEST_SIZE_MATCH(xGetKeyboardMappingReq);
+
+    if ((stuff->firstKeyCode < curKeySyms->minKeyCode) ||
+        (stuff->firstKeyCode > curKeySyms->maxKeyCode))
+    {
+       client->errorValue = stuff->firstKeyCode;
+       return BadValue;
+    }
+    if (stuff->firstKeyCode + stuff->count >
+       (unsigned)(curKeySyms->maxKeyCode + 1))
+    {
+       client->errorValue = stuff->count;
+        return BadValue;
+    }
+
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.keySymsPerKeyCode = curKeySyms->mapWidth;
+    /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
+    rep.length = (curKeySyms->mapWidth * stuff->count);
+    WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep);
+    client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
+    WriteSwappedDataToClient(
+       client,
+       curKeySyms->mapWidth * stuff->count * sizeof(KeySym),
+       &curKeySyms->map[(stuff->firstKeyCode - curKeySyms->minKeyCode) *
+                        curKeySyms->mapWidth]);
+
+    return client->noClientException;
+}
+
+int
+ProcGetPointerMapping(client)
+    ClientPtr client;
+{
+    xGetPointerMappingReply rep;
+    ButtonClassPtr butc = inputInfo.pointer->button;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.nElts = butc->numButtons;
+    rep.length = ((unsigned)rep.nElts + (4-1))/4;
+    WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep);
+    (void)WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]);
+    return Success;    
+}
+
+void
+NoteLedState(keybd, led, on)
+    DeviceIntPtr keybd;
+    int                led;
+    Bool       on;
+{
+    KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl;
+    if (on)
+       ctrl->leds |= ((Leds)1 << (led - 1));
+    else
+       ctrl->leds &= ~((Leds)1 << (led - 1));
+}
+
+int
+Ones(mask)                /* HACKMEM 169 */
+    unsigned long mask;
+{
+    register unsigned long y;
+
+    y = (mask >> 1) &033333333333;
+    y = mask - y - ((y >>1) & 033333333333);
+    return (((y + (y >> 3)) & 030707070707) % 077);
+}
+
+int
+ProcChangeKeyboardControl (client)
+    ClientPtr client;
+{
+#define DO_ALL    (-1)
+    KeybdCtrl ctrl;
+    DeviceIntPtr keybd = inputInfo.keyboard;
+    XID *vlist;
+    int t;
+    int led = DO_ALL;
+    int key = DO_ALL;
+    BITS32 vmask, index2;
+    int mask, i;
+    REQUEST(xChangeKeyboardControlReq);
+
+    REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
+    vmask = stuff->mask;
+    if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask))
+       return BadLength;
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, keybd, TRUE))
+       return BadAccess;
+#endif 
+    vlist = (XID *)&stuff[1];          /* first word of values */
+    ctrl = keybd->kbdfeed->ctrl;
+    while (vmask)
+    {
+       index2 = (BITS32) lowbit (vmask);
+       vmask &= ~index2;
+       switch (index2)
+       {
+       case KBKeyClickPercent: 
+           t = (INT8)*vlist;
+           vlist++;
+           if (t == -1)
+               t = defaultKeyboardControl.click;
+           else if (t < 0 || t > 100)
+           {
+               client->errorValue = t;
+               return BadValue;
+           }
+           ctrl.click = t;
+           break;
+       case KBBellPercent:
+           t = (INT8)*vlist;
+           vlist++;
+           if (t == -1)
+               t = defaultKeyboardControl.bell;
+           else if (t < 0 || t > 100)
+           {
+               client->errorValue = t;
+               return BadValue;
+           }
+           ctrl.bell = t;
+           break;
+       case KBBellPitch:
+           t = (INT16)*vlist;
+           vlist++;
+           if (t == -1)
+               t = defaultKeyboardControl.bell_pitch;
+           else if (t < 0)
+           {
+               client->errorValue = t;
+               return BadValue;
+           }
+           ctrl.bell_pitch = t;
+           break;
+       case KBBellDuration:
+           t = (INT16)*vlist;
+           vlist++;
+           if (t == -1)
+               t = defaultKeyboardControl.bell_duration;
+           else if (t < 0)
+           {
+               client->errorValue = t;
+               return BadValue;
+           }
+           ctrl.bell_duration = t;
+           break;
+       case KBLed:
+           led = (CARD8)*vlist;
+           vlist++;
+           if (led < 1 || led > 32)
+           {
+               client->errorValue = led;
+               return BadValue;
+           }
+           if (!(stuff->mask & KBLedMode))
+               return BadMatch;
+           break;
+       case KBLedMode:
+           t = (CARD8)*vlist;
+           vlist++;
+           if (t == LedModeOff)
+           {
+               if (led == DO_ALL)
+                   ctrl.leds = 0x0;
+               else
+                   ctrl.leds &= ~(((Leds)(1)) << (led - 1));
+           }
+           else if (t == LedModeOn)
+           {
+               if (led == DO_ALL)
+                   ctrl.leds = ~0L;
+               else
+                   ctrl.leds |= (((Leds)(1)) << (led - 1));
+           }
+           else
+           {
+               client->errorValue = t;
+               return BadValue;
+           }
+#ifdef XKB
+           if (!noXkbExtension) {
+               XkbEventCauseRec        cause;
+               XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client);
+               keybd->kbdfeed->ctrl.leds = ctrl.leds;
+               XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))),
+                                                       ctrl.leds, &cause);
+           }
+#endif
+           break;
+       case KBKey:
+           key = (KeyCode)*vlist;
+           vlist++;
+           if ((KeyCode)key < inputInfo.keyboard->key->curKeySyms.minKeyCode ||
+               (KeyCode)key > inputInfo.keyboard->key->curKeySyms.maxKeyCode)
+           {
+               client->errorValue = key;
+               return BadValue;
+           }
+           if (!(stuff->mask & KBAutoRepeatMode))
+               return BadMatch;
+           break;
+       case KBAutoRepeatMode:
+           i = (key >> 3);
+           mask = (1 << (key & 7));
+           t = (CARD8)*vlist;
+           vlist++;
+#ifdef XKB
+           if (!noXkbExtension && key != DO_ALL)
+               XkbDisableComputedAutoRepeats(keybd,key);
+#endif
+           if (t == AutoRepeatModeOff)
+           {
+               if (key == DO_ALL)
+                   ctrl.autoRepeat = FALSE;
+               else
+                   ctrl.autoRepeats[i] &= ~mask;
+           }
+           else if (t == AutoRepeatModeOn)
+           {
+               if (key == DO_ALL)
+                   ctrl.autoRepeat = TRUE;
+               else
+                   ctrl.autoRepeats[i] |= mask;
+           }
+           else if (t == AutoRepeatModeDefault)
+           {
+               if (key == DO_ALL)
+                   ctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
+               else
+                   ctrl.autoRepeats[i] =
+                           (ctrl.autoRepeats[i] & ~mask) |
+                           (defaultKeyboardControl.autoRepeats[i] & mask);
+           }
+           else
+           {
+               client->errorValue = t;
+               return BadValue;
+           }
+           break;
+       default:
+           client->errorValue = stuff->mask;
+           return BadValue;
+       }
+    }
+    keybd->kbdfeed->ctrl = ctrl;
+#ifdef XKB
+    /* The XKB RepeatKeys control and core protocol global autorepeat */
+    /* value are linked        */
+    if (!noXkbExtension) {
+       XkbSetRepeatKeys(keybd,key,keybd->kbdfeed->ctrl.autoRepeat);
+    }
+    else
+#endif
+    (*keybd->kbdfeed->CtrlProc)(keybd, &keybd->kbdfeed->ctrl);
+    return Success;
+#undef DO_ALL
+} 
+
+int
+ProcGetKeyboardControl (client)
+    ClientPtr client;
+{
+    int i;
+    register KeybdCtrl *ctrl = &inputInfo.keyboard->kbdfeed->ctrl;
+    xGetKeyboardControlReply rep;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.length = 5;
+    rep.sequenceNumber = client->sequence;
+    rep.globalAutoRepeat = ctrl->autoRepeat;
+    rep.keyClickPercent = ctrl->click;
+    rep.bellPercent = ctrl->bell;
+    rep.bellPitch = ctrl->bell_pitch;
+    rep.bellDuration = ctrl->bell_duration;
+    rep.ledMask = ctrl->leds;
+    for (i = 0; i < 32; i++)
+       rep.map[i] = ctrl->autoRepeats[i];
+    WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep);
+    return Success;
+} 
+
+int
+ProcBell(client)
+    ClientPtr client;
+{
+    register DeviceIntPtr keybd = inputInfo.keyboard;
+    int base = keybd->kbdfeed->ctrl.bell;
+    int newpercent;
+    REQUEST(xBellReq);
+    REQUEST_SIZE_MATCH(xBellReq);
+    if (stuff->percent < -100 || stuff->percent > 100)
+    {
+       client->errorValue = stuff->percent;
+       return BadValue;
+    }
+    newpercent = (base * stuff->percent) / 100;
+    if (stuff->percent < 0)
+        newpercent = base + newpercent;
+    else
+       newpercent = base - newpercent + stuff->percent;
+#ifdef XKB
+    if (!noXkbExtension)
+       XkbHandleBell(FALSE,FALSE, keybd, newpercent, &keybd->kbdfeed->ctrl, 0, 
+                     None, NULL, client);
+       else
+#endif
+    (*keybd->kbdfeed->BellProc)(newpercent, keybd,
+                               (pointer) &keybd->kbdfeed->ctrl, 0);
+    return Success;
+} 
+
+int
+ProcChangePointerControl(client)
+    ClientPtr client;
+{
+    DeviceIntPtr mouse = inputInfo.pointer;
+    PtrCtrl ctrl;              /* might get BadValue part way through */
+    REQUEST(xChangePointerControlReq);
+
+    REQUEST_SIZE_MATCH(xChangePointerControlReq);
+    ctrl = mouse->ptrfeed->ctrl;
+    if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse))
+    {
+       client->errorValue = stuff->doAccel;
+       return(BadValue);
+    }
+    if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse))
+    {
+       client->errorValue = stuff->doThresh;
+       return(BadValue);
+    }
+    if (stuff->doAccel)
+    {
+       if (stuff->accelNum == -1)
+           ctrl.num = defaultPointerControl.num;
+       else if (stuff->accelNum < 0)
+       {
+           client->errorValue = stuff->accelNum;
+           return BadValue;
+       }
+       else ctrl.num = stuff->accelNum;
+       if (stuff->accelDenum == -1)
+           ctrl.den = defaultPointerControl.den;
+       else if (stuff->accelDenum <= 0)
+       {
+           client->errorValue = stuff->accelDenum;
+           return BadValue;
+       }
+       else ctrl.den = stuff->accelDenum;
+    }
+    if (stuff->doThresh)
+    {
+       if (stuff->threshold == -1)
+           ctrl.threshold = defaultPointerControl.threshold;
+       else if (stuff->threshold < 0)
+       {
+           client->errorValue = stuff->threshold;
+           return BadValue;
+       }
+       else ctrl.threshold = stuff->threshold;
+    }
+    mouse->ptrfeed->ctrl = ctrl;
+    (*mouse->ptrfeed->CtrlProc)(mouse, &mouse->ptrfeed->ctrl);
+    return Success;
+} 
+
+int
+ProcGetPointerControl(client)
+    ClientPtr client;
+{
+    register PtrCtrl *ctrl = &inputInfo.pointer->ptrfeed->ctrl;
+    xGetPointerControlReply rep;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.threshold = ctrl->threshold;
+    rep.accelNumerator = ctrl->num;
+    rep.accelDenominator = ctrl->den;
+    WriteReplyToClient(client, sizeof(xGenericReply), &rep);
+    return Success;
+}
+
+void
+MaybeStopHint(dev, client)
+    register DeviceIntPtr dev;
+    ClientPtr client;
+{
+    GrabPtr grab = dev->grab;
+
+    if ((grab && SameClient(grab, client) &&
+        ((grab->eventMask & PointerMotionHintMask) ||
+         (grab->ownerEvents &&
+          (EventMaskForClient(dev->valuator->motionHintWindow, client) &
+           PointerMotionHintMask)))) ||
+       (!grab &&
+        (EventMaskForClient(dev->valuator->motionHintWindow, client) &
+         PointerMotionHintMask)))
+       dev->valuator->motionHintWindow = NullWindow;
+}
+
+int
+ProcGetMotionEvents(client)
+    ClientPtr client;
+{
+    WindowPtr pWin;
+    xTimecoord * coords = (xTimecoord *) NULL;
+    xGetMotionEventsReply rep;
+    int     i, count, xmin, xmax, ymin, ymax;
+    unsigned long nEvents;
+    DeviceIntPtr mouse = inputInfo.pointer;
+    TimeStamp start, stop;
+    REQUEST(xGetMotionEventsReq);
+
+    REQUEST_SIZE_MATCH(xGetMotionEventsReq);
+    pWin = SecurityLookupWindow(stuff->window, client, TRUE);
+    if (!pWin)
+       return BadWindow;
+    if (mouse->valuator->motionHintWindow)
+       MaybeStopHint(mouse, client);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    nEvents = 0;
+    start = ClientTimeToServerTime(stuff->start);
+    stop = ClientTimeToServerTime(stuff->stop);
+    if ((CompareTimeStamps(start, stop) != LATER) &&
+       (CompareTimeStamps(start, currentTime) != LATER) &&
+       mouse->valuator->numMotionEvents)
+    {
+       if (CompareTimeStamps(stop, currentTime) == LATER)
+           stop = currentTime;
+       coords = (xTimecoord *)ALLOCATE_LOCAL(mouse->valuator->numMotionEvents
+                                             * sizeof(xTimecoord));
+       if (!coords)
+           return BadAlloc;
+       count = (*mouse->valuator->GetMotionProc) (mouse, coords,
+                                                  start.milliseconds,
+                                                  stop.milliseconds,
+                                                  pWin->drawable.pScreen);
+       xmin = pWin->drawable.x - wBorderWidth (pWin);
+       xmax = pWin->drawable.x + (int)pWin->drawable.width +
+               wBorderWidth (pWin);
+       ymin = pWin->drawable.y - wBorderWidth (pWin);
+       ymax = pWin->drawable.y + (int)pWin->drawable.height +
+               wBorderWidth (pWin);
+       for (i = 0; i < count; i++)
+           if ((xmin <= coords[i].x) && (coords[i].x < xmax) &&
+                   (ymin <= coords[i].y) && (coords[i].y < ymax))
+           {
+               coords[nEvents].time = coords[i].time;
+               coords[nEvents].x = coords[i].x - pWin->drawable.x;
+               coords[nEvents].y = coords[i].y - pWin->drawable.y;
+               nEvents++;
+           }
+    }
+    rep.length = nEvents * (sizeof(xTimecoord) >> 2);
+    rep.nEvents = nEvents;
+    WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep);
+    if (nEvents)
+    {
+       client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite;
+       WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord),
+                                (char *)coords);
+    }
+    if (coords)
+       DEALLOCATE_LOCAL(coords);
+    return Success;
+}
+
+int
+ProcQueryKeymap(client)
+    ClientPtr client;
+{
+    xQueryKeymapReply rep;
+    int i;
+    CARD8 *down = inputInfo.keyboard->key->down;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 2;
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+    {
+       bzero((char *)&rep.map[0], 32);
+    }
+    else
+#endif
+    for (i = 0; i<32; i++)
+       rep.map[i] = down[i];
+    WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
+    return Success;
+}
+
+/******************************************************************************
+ * The following entrypoints are provided for binary compatibility with
+ * previous versions (they make casts, where the current version changes types
+ * for more stringent prototype checking).
+ ******************************************************************************/
+#ifdef AddInputDevice
+#undef AddInputDevice
+
+#if NeedFunctionPrototypes
+DevicePtr
+AddInputDevice(
+    DeviceProc deviceProc,
+    Bool autoStart)
+#else
+DevicePtr
+AddInputDevice(deviceProc, autoStart)
+    DeviceProc deviceProc;
+    Bool autoStart;
+#endif
+{
+    return (DevicePtr)_AddInputDevice(deviceProc, autoStart);
+}
+#endif /* AddInputDevice */
+
+#ifdef RegisterPointerDevice
+#undef RegisterPointerDevice
+
+#if NeedFunctionPrototypes
+void
+RegisterPointerDevice(DevicePtr device)
+#else
+void
+RegisterPointerDevice(device)
+    DevicePtr device;
+#endif
+{
+    _RegisterPointerDevice((DeviceIntPtr)device);
+}
+#endif /* RegisterPointerDevice */
+
+#ifdef RegisterKeyboardDevice
+#undef RegisterKeyboardDevice
+
+#if NeedFunctionPrototypes
+void
+RegisterKeyboardDevice(DevicePtr device)
+#else
+void
+RegisterKeyboardDevice(device)
+    DevicePtr device;
+#endif
+{
+    _RegisterKeyboardDevice((DeviceIntPtr)device);
+}
+#endif /* RegisterKeyboardDevice */