aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/Xi/extinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/Xi/extinit.c')
-rw-r--r--xorg-server/Xi/extinit.c962
1 files changed, 962 insertions, 0 deletions
diff --git a/xorg-server/Xi/extinit.c b/xorg-server/Xi/extinit.c
new file mode 100644
index 000000000..2ffdafbc1
--- /dev/null
+++ b/xorg-server/Xi/extinit.c
@@ -0,0 +1,962 @@
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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
+OPEN GROUP 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 Open Group 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 Open Group.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/********************************************************************
+ *
+ * Dispatch routines and initialization routines for the X input extension.
+ *
+ */
+
+#define NUMTYPES 15
+
+#define NEED_EVENTS
+#define NEED_REPLIES
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "inputstr.h"
+#include "gcstruct.h" /* pointer for extnsionst.h */
+#include "extnsionst.h" /* extension entry */
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+
+#include "dixevents.h"
+#include "exevents.h"
+#include "extinit.h"
+#include "exglobals.h"
+#include "swaprep.h"
+#include "registry.h"
+
+/* modules local to Xi */
+#include "allowev.h"
+#include "chgdctl.h"
+#include "chgfctl.h"
+#include "chgkbd.h"
+#include "chgprop.h"
+#include "chgptr.h"
+#include "closedev.h"
+#include "devbell.h"
+#include "getbmap.h"
+#include "getbmap.h"
+#include "getdctl.h"
+#include "getfctl.h"
+#include "getfocus.h"
+#include "getkmap.h"
+#include "getmmap.h"
+#include "getprop.h"
+#include "getselev.h"
+#include "getvers.h"
+#include "getvers.h"
+#include "grabdev.h"
+#include "grabdevb.h"
+#include "grabdevk.h"
+#include "gtmotion.h"
+#include "listdev.h"
+#include "opendev.h"
+#include "queryst.h"
+#include "selectev.h"
+#include "sendexev.h"
+#include "chgkmap.h"
+#include "setbmap.h"
+#include "setdval.h"
+#include "setfocus.h"
+#include "setmmap.h"
+#include "setmode.h"
+#include "ungrdev.h"
+#include "ungrdevb.h"
+#include "ungrdevk.h"
+
+static Mask lastExtEventMask = 1;
+int ExtEventIndex;
+Mask ExtValidMasks[EMASKSIZE];
+Mask ExtExclusiveMasks[EMASKSIZE];
+
+static struct dev_type
+{
+ Atom type;
+ char *name;
+} dev_type[] = {
+ {
+ 0, XI_KEYBOARD}, {
+ 0, XI_MOUSE}, {
+ 0, XI_TABLET}, {
+ 0, XI_TOUCHSCREEN}, {
+ 0, XI_TOUCHPAD}, {
+ 0, XI_BARCODE}, {
+ 0, XI_BUTTONBOX}, {
+ 0, XI_KNOB_BOX}, {
+ 0, XI_ONE_KNOB}, {
+ 0, XI_NINE_KNOB}, {
+ 0, XI_TRACKBALL}, {
+ 0, XI_QUADRATURE}, {
+ 0, XI_ID_MODULE}, {
+ 0, XI_SPACEBALL}, {
+ 0, XI_DATAGLOVE}, {
+ 0, XI_EYETRACKER}, {
+ 0, XI_CURSORKEYS}, {
+0, XI_FOOTMOUSE}};
+
+CARD8 event_base[numInputClasses];
+XExtEventInfo EventInfo[32];
+
+/*****************************************************************
+ *
+ * Globals referenced elsewhere in the server.
+ *
+ */
+
+int IReqCode = 0;
+int BadDevice = 0;
+static int BadEvent = 1;
+int BadMode = 2;
+int DeviceBusy = 3;
+int BadClass = 4;
+
+Mask DevicePointerMotionMask;
+Mask DevicePointerMotionHintMask;
+Mask DeviceFocusChangeMask;
+Mask DeviceStateNotifyMask;
+static Mask ChangeDeviceNotifyMask;
+Mask DeviceMappingNotifyMask;
+Mask DeviceOwnerGrabButtonMask;
+Mask DeviceButtonGrabMask;
+Mask DeviceButtonMotionMask;
+Mask DevicePresenceNotifyMask;
+
+int DeviceValuator;
+int DeviceKeyPress;
+int DeviceKeyRelease;
+int DeviceButtonPress;
+int DeviceButtonRelease;
+int DeviceMotionNotify;
+int DeviceFocusIn;
+int DeviceFocusOut;
+int ProximityIn;
+int ProximityOut;
+int DeviceStateNotify;
+int DeviceKeyStateNotify;
+int DeviceButtonStateNotify;
+int DeviceMappingNotify;
+int ChangeDeviceNotify;
+int DevicePresenceNotify;
+
+int RT_INPUTCLIENT;
+
+/*****************************************************************
+ *
+ * Externs defined elsewhere in the X server.
+ *
+ */
+
+extern XExtensionVersion AllExtensionVersions[];
+
+Mask PropagateMask[MAX_DEVICES];
+
+/*****************************************************************
+ *
+ * Declarations of local routines.
+ *
+ */
+
+static XExtensionVersion thisversion = { XI_Present,
+ XI_Add_DevicePresenceNotify_Major,
+ XI_Add_DevicePresenceNotify_Minor
+};
+
+/*************************************************************************
+ *
+ * ProcIDispatch - main dispatch routine for requests to this extension.
+ * This routine is used if server and client have the same byte ordering.
+ *
+ */
+
+static int
+ProcIDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ if (stuff->data == X_GetExtensionVersion)
+ return (ProcXGetExtensionVersion(client));
+ if (stuff->data == X_ListInputDevices)
+ return (ProcXListInputDevices(client));
+ else if (stuff->data == X_OpenDevice)
+ return (ProcXOpenDevice(client));
+ else if (stuff->data == X_CloseDevice)
+ return (ProcXCloseDevice(client));
+ else if (stuff->data == X_SetDeviceMode)
+ return (ProcXSetDeviceMode(client));
+ else if (stuff->data == X_SelectExtensionEvent)
+ return (ProcXSelectExtensionEvent(client));
+ else if (stuff->data == X_GetSelectedExtensionEvents)
+ return (ProcXGetSelectedExtensionEvents(client));
+ else if (stuff->data == X_ChangeDeviceDontPropagateList)
+ return (ProcXChangeDeviceDontPropagateList(client));
+ else if (stuff->data == X_GetDeviceDontPropagateList)
+ return (ProcXGetDeviceDontPropagateList(client));
+ else if (stuff->data == X_GetDeviceMotionEvents)
+ return (ProcXGetDeviceMotionEvents(client));
+ else if (stuff->data == X_ChangeKeyboardDevice)
+ return (ProcXChangeKeyboardDevice(client));
+ else if (stuff->data == X_ChangePointerDevice)
+ return (ProcXChangePointerDevice(client));
+ else if (stuff->data == X_GrabDevice)
+ return (ProcXGrabDevice(client));
+ else if (stuff->data == X_UngrabDevice)
+ return (ProcXUngrabDevice(client));
+ else if (stuff->data == X_GrabDeviceKey)
+ return (ProcXGrabDeviceKey(client));
+ else if (stuff->data == X_UngrabDeviceKey)
+ return (ProcXUngrabDeviceKey(client));
+ else if (stuff->data == X_GrabDeviceButton)
+ return (ProcXGrabDeviceButton(client));
+ else if (stuff->data == X_UngrabDeviceButton)
+ return (ProcXUngrabDeviceButton(client));
+ else if (stuff->data == X_AllowDeviceEvents)
+ return (ProcXAllowDeviceEvents(client));
+ else if (stuff->data == X_GetDeviceFocus)
+ return (ProcXGetDeviceFocus(client));
+ else if (stuff->data == X_SetDeviceFocus)
+ return (ProcXSetDeviceFocus(client));
+ else if (stuff->data == X_GetFeedbackControl)
+ return (ProcXGetFeedbackControl(client));
+ else if (stuff->data == X_ChangeFeedbackControl)
+ return (ProcXChangeFeedbackControl(client));
+ else if (stuff->data == X_GetDeviceKeyMapping)
+ return (ProcXGetDeviceKeyMapping(client));
+ else if (stuff->data == X_ChangeDeviceKeyMapping)
+ return (ProcXChangeDeviceKeyMapping(client));
+ else if (stuff->data == X_GetDeviceModifierMapping)
+ return (ProcXGetDeviceModifierMapping(client));
+ else if (stuff->data == X_SetDeviceModifierMapping)
+ return (ProcXSetDeviceModifierMapping(client));
+ else if (stuff->data == X_GetDeviceButtonMapping)
+ return (ProcXGetDeviceButtonMapping(client));
+ else if (stuff->data == X_SetDeviceButtonMapping)
+ return (ProcXSetDeviceButtonMapping(client));
+ else if (stuff->data == X_QueryDeviceState)
+ return (ProcXQueryDeviceState(client));
+ else if (stuff->data == X_SendExtensionEvent)
+ return (ProcXSendExtensionEvent(client));
+ else if (stuff->data == X_DeviceBell)
+ return (ProcXDeviceBell(client));
+ else if (stuff->data == X_SetDeviceValuators)
+ return (ProcXSetDeviceValuators(client));
+ else if (stuff->data == X_GetDeviceControl)
+ return (ProcXGetDeviceControl(client));
+ else if (stuff->data == X_ChangeDeviceControl)
+ return (ProcXChangeDeviceControl(client));
+
+ return (BadRequest);
+}
+
+/*******************************************************************************
+ *
+ * SProcXDispatch
+ *
+ * Main swapped dispatch routine for requests to this extension.
+ * This routine is used if server and client do not have the same byte ordering.
+ *
+ */
+
+static int
+SProcIDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ if (stuff->data == X_GetExtensionVersion)
+ return (SProcXGetExtensionVersion(client));
+ if (stuff->data == X_ListInputDevices)
+ return (SProcXListInputDevices(client));
+ else if (stuff->data == X_OpenDevice)
+ return (SProcXOpenDevice(client));
+ else if (stuff->data == X_CloseDevice)
+ return (SProcXCloseDevice(client));
+ else if (stuff->data == X_SetDeviceMode)
+ return (SProcXSetDeviceMode(client));
+ else if (stuff->data == X_SelectExtensionEvent)
+ return (SProcXSelectExtensionEvent(client));
+ else if (stuff->data == X_GetSelectedExtensionEvents)
+ return (SProcXGetSelectedExtensionEvents(client));
+ else if (stuff->data == X_ChangeDeviceDontPropagateList)
+ return (SProcXChangeDeviceDontPropagateList(client));
+ else if (stuff->data == X_GetDeviceDontPropagateList)
+ return (SProcXGetDeviceDontPropagateList(client));
+ else if (stuff->data == X_GetDeviceMotionEvents)
+ return (SProcXGetDeviceMotionEvents(client));
+ else if (stuff->data == X_ChangeKeyboardDevice)
+ return (SProcXChangeKeyboardDevice(client));
+ else if (stuff->data == X_ChangePointerDevice)
+ return (SProcXChangePointerDevice(client));
+ else if (stuff->data == X_GrabDevice)
+ return (SProcXGrabDevice(client));
+ else if (stuff->data == X_UngrabDevice)
+ return (SProcXUngrabDevice(client));
+ else if (stuff->data == X_GrabDeviceKey)
+ return (SProcXGrabDeviceKey(client));
+ else if (stuff->data == X_UngrabDeviceKey)
+ return (SProcXUngrabDeviceKey(client));
+ else if (stuff->data == X_GrabDeviceButton)
+ return (SProcXGrabDeviceButton(client));
+ else if (stuff->data == X_UngrabDeviceButton)
+ return (SProcXUngrabDeviceButton(client));
+ else if (stuff->data == X_AllowDeviceEvents)
+ return (SProcXAllowDeviceEvents(client));
+ else if (stuff->data == X_GetDeviceFocus)
+ return (SProcXGetDeviceFocus(client));
+ else if (stuff->data == X_SetDeviceFocus)
+ return (SProcXSetDeviceFocus(client));
+ else if (stuff->data == X_GetFeedbackControl)
+ return (SProcXGetFeedbackControl(client));
+ else if (stuff->data == X_ChangeFeedbackControl)
+ return (SProcXChangeFeedbackControl(client));
+ else if (stuff->data == X_GetDeviceKeyMapping)
+ return (SProcXGetDeviceKeyMapping(client));
+ else if (stuff->data == X_ChangeDeviceKeyMapping)
+ return (SProcXChangeDeviceKeyMapping(client));
+ else if (stuff->data == X_GetDeviceModifierMapping)
+ return (SProcXGetDeviceModifierMapping(client));
+ else if (stuff->data == X_SetDeviceModifierMapping)
+ return (SProcXSetDeviceModifierMapping(client));
+ else if (stuff->data == X_GetDeviceButtonMapping)
+ return (SProcXGetDeviceButtonMapping(client));
+ else if (stuff->data == X_SetDeviceButtonMapping)
+ return (SProcXSetDeviceButtonMapping(client));
+ else if (stuff->data == X_QueryDeviceState)
+ return (SProcXQueryDeviceState(client));
+ else if (stuff->data == X_SendExtensionEvent)
+ return (SProcXSendExtensionEvent(client));
+ else if (stuff->data == X_DeviceBell)
+ return (SProcXDeviceBell(client));
+ else if (stuff->data == X_SetDeviceValuators)
+ return (SProcXSetDeviceValuators(client));
+ else if (stuff->data == X_GetDeviceControl)
+ return (SProcXGetDeviceControl(client));
+ else if (stuff->data == X_ChangeDeviceControl)
+ return (SProcXChangeDeviceControl(client));
+
+ return (BadRequest);
+}
+
+/**********************************************************************
+ *
+ * SReplyIDispatch
+ * Swap any replies defined in this extension.
+ *
+ */
+
+/* FIXME: this would be more concise and readable in ANSI C */
+#define DISPATCH(code) \
+ if (rep->RepType == X_##code) \
+ SRepX##code (client, len, (x##code##Reply *) rep)
+
+static void
+SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
+ /* All we look at is the type field */
+{ /* This is common to all replies */
+ if (rep->RepType == X_GetExtensionVersion)
+ SRepXGetExtensionVersion(client, len,
+ (xGetExtensionVersionReply *) rep);
+ else if (rep->RepType == X_ListInputDevices)
+ SRepXListInputDevices(client, len, (xListInputDevicesReply *) rep);
+ else if (rep->RepType == X_OpenDevice)
+ SRepXOpenDevice(client, len, (xOpenDeviceReply *) rep);
+ else if (rep->RepType == X_SetDeviceMode)
+ SRepXSetDeviceMode(client, len, (xSetDeviceModeReply *) rep);
+ else if (rep->RepType == X_GetSelectedExtensionEvents)
+ SRepXGetSelectedExtensionEvents(client, len,
+ (xGetSelectedExtensionEventsReply *)
+ rep);
+ else if (rep->RepType == X_GetDeviceDontPropagateList)
+ SRepXGetDeviceDontPropagateList(client, len,
+ (xGetDeviceDontPropagateListReply *)
+ rep);
+ else if (rep->RepType == X_GetDeviceMotionEvents)
+ SRepXGetDeviceMotionEvents(client, len,
+ (xGetDeviceMotionEventsReply *) rep);
+ else if (rep->RepType == X_GrabDevice)
+ SRepXGrabDevice(client, len, (xGrabDeviceReply *) rep);
+ else if (rep->RepType == X_GetDeviceFocus)
+ SRepXGetDeviceFocus(client, len, (xGetDeviceFocusReply *) rep);
+ else if (rep->RepType == X_GetFeedbackControl)
+ SRepXGetFeedbackControl(client, len, (xGetFeedbackControlReply *) rep);
+ else if (rep->RepType == X_GetDeviceKeyMapping)
+ SRepXGetDeviceKeyMapping(client, len,
+ (xGetDeviceKeyMappingReply *) rep);
+ else if (rep->RepType == X_GetDeviceModifierMapping)
+ SRepXGetDeviceModifierMapping(client, len,
+ (xGetDeviceModifierMappingReply *) rep);
+ else if (rep->RepType == X_SetDeviceModifierMapping)
+ SRepXSetDeviceModifierMapping(client, len,
+ (xSetDeviceModifierMappingReply *) rep);
+ else if (rep->RepType == X_GetDeviceButtonMapping)
+ SRepXGetDeviceButtonMapping(client, len,
+ (xGetDeviceButtonMappingReply *) rep);
+ else if (rep->RepType == X_SetDeviceButtonMapping)
+ SRepXSetDeviceButtonMapping(client, len,
+ (xSetDeviceButtonMappingReply *) rep);
+ else if (rep->RepType == X_QueryDeviceState)
+ SRepXQueryDeviceState(client, len, (xQueryDeviceStateReply *) rep);
+ else if (rep->RepType == X_SetDeviceValuators)
+ SRepXSetDeviceValuators(client, len, (xSetDeviceValuatorsReply *) rep);
+ else if (rep->RepType == X_GetDeviceControl)
+ SRepXGetDeviceControl(client, len, (xGetDeviceControlReply *) rep);
+ else if (rep->RepType == X_ChangeDeviceControl)
+ SRepXChangeDeviceControl(client, len,
+ (xChangeDeviceControlReply *) rep);
+ else {
+ FatalError("XINPUT confused sending swapped reply");
+ }
+}
+
+/************************************************************************
+ *
+ * This function swaps the DeviceValuator event.
+ *
+ */
+
+static void
+SEventDeviceValuator(deviceValuator * from, deviceValuator * to)
+{
+ char n;
+ int i;
+ INT32 *ip B32;
+
+ *to = *from;
+ swaps(&to->sequenceNumber, n);
+ swaps(&to->device_state, n);
+ ip = &to->valuator0;
+ for (i = 0; i < 6; i++) {
+ swapl((ip + i), n); /* macro - braces are required */
+ }
+}
+
+static void
+SEventFocus(deviceFocus * from, deviceFocus * to)
+{
+ char n;
+
+ *to = *from;
+ swaps(&to->sequenceNumber, n);
+ swapl(&to->time, n);
+ swapl(&to->window, n);
+}
+
+static void
+SDeviceStateNotifyEvent(deviceStateNotify * from, deviceStateNotify * to)
+{
+ int i;
+ char n;
+ INT32 *ip B32;
+
+ *to = *from;
+ swaps(&to->sequenceNumber, n);
+ swapl(&to->time, n);
+ ip = &to->valuator0;
+ for (i = 0; i < 3; i++) {
+ swapl((ip + i), n); /* macro - braces are required */
+ }
+}
+
+static void
+SDeviceKeyStateNotifyEvent(deviceKeyStateNotify * from,
+ deviceKeyStateNotify * to)
+{
+ char n;
+
+ *to = *from;
+ swaps(&to->sequenceNumber, n);
+}
+
+static void
+SDeviceButtonStateNotifyEvent(deviceButtonStateNotify * from,
+ deviceButtonStateNotify * to)
+{
+ char n;
+
+ *to = *from;
+ swaps(&to->sequenceNumber, n);
+}
+
+static void
+SChangeDeviceNotifyEvent(changeDeviceNotify * from, changeDeviceNotify * to)
+{
+ char n;
+
+ *to = *from;
+ swaps(&to->sequenceNumber, n);
+ swapl(&to->time, n);
+}
+
+static void
+SDeviceMappingNotifyEvent(deviceMappingNotify * from, deviceMappingNotify * to)
+{
+ char n;
+
+ *to = *from;
+ swaps(&to->sequenceNumber, n);
+ swapl(&to->time, n);
+}
+
+static void
+SDevicePresenceNotifyEvent (devicePresenceNotify *from, devicePresenceNotify *to)
+{
+ char n;
+
+ *to = *from;
+ swaps(&to->sequenceNumber,n);
+ swapl(&to->time, n);
+ swaps(&to->control, n);
+}
+
+/**************************************************************************
+ *
+ * Allow the specified event to have its propagation suppressed.
+ * The default is to not allow suppression of propagation.
+ *
+ */
+
+static void
+AllowPropagateSuppress(Mask mask)
+{
+ int i;
+
+ for (i = 0; i < MAX_DEVICES; i++)
+ PropagateMask[i] |= mask;
+}
+
+/**************************************************************************
+ *
+ * Return the next available extension event mask.
+ *
+ */
+
+static Mask
+GetNextExtEventMask(void)
+{
+ int i;
+ Mask mask = lastExtEventMask;
+
+ if (lastExtEventMask == 0) {
+ FatalError("GetNextExtEventMask: no more events are available.");
+ }
+ lastExtEventMask <<= 1;
+
+ for (i = 0; i < MAX_DEVICES; i++)
+ ExtValidMasks[i] |= mask;
+ return mask;
+}
+
+/**************************************************************************
+ *
+ * Record an event mask where there is no unique corresponding event type.
+ * We can't call SetMaskForEvent, since that would clobber the existing
+ * mask for that event. MotionHint and ButtonMotion are examples.
+ *
+ * Since extension event types will never be less than 64, we can use
+ * 0-63 in the EventInfo array as the "type" to be used to look up this
+ * mask. This means that the corresponding macros such as
+ * DevicePointerMotionHint must have access to the same constants.
+ *
+ */
+
+static void
+SetEventInfo(Mask mask, int constant)
+{
+ EventInfo[ExtEventIndex].mask = mask;
+ EventInfo[ExtEventIndex++].type = constant;
+}
+
+/**************************************************************************
+ *
+ * Allow the specified event to be restricted to being selected by one
+ * client at a time.
+ * The default is to allow more than one client to select the event.
+ *
+ */
+
+static void
+SetExclusiveAccess(Mask mask)
+{
+ int i;
+
+ for (i = 0; i < MAX_DEVICES; i++)
+ ExtExclusiveMasks[i] |= mask;
+}
+
+/**************************************************************************
+ *
+ * Assign the specified mask to the specified event.
+ *
+ */
+
+static void
+SetMaskForExtEvent(Mask mask, int event)
+{
+
+ EventInfo[ExtEventIndex].mask = mask;
+ EventInfo[ExtEventIndex++].type = event;
+
+ if ((event < LASTEvent) || (event >= 128))
+ FatalError("MaskForExtensionEvent: bogus event number");
+ SetMaskForEvent(mask, event);
+}
+
+/************************************************************************
+ *
+ * This function sets up extension event types and masks.
+ *
+ */
+
+static void
+FixExtensionEvents(ExtensionEntry * extEntry)
+{
+ Mask mask;
+
+ DeviceValuator = extEntry->eventBase;
+ DeviceKeyPress = DeviceValuator + 1;
+ DeviceKeyRelease = DeviceKeyPress + 1;
+ DeviceButtonPress = DeviceKeyRelease + 1;
+ DeviceButtonRelease = DeviceButtonPress + 1;
+ DeviceMotionNotify = DeviceButtonRelease + 1;
+ DeviceFocusIn = DeviceMotionNotify + 1;
+ DeviceFocusOut = DeviceFocusIn + 1;
+ ProximityIn = DeviceFocusOut + 1;
+ ProximityOut = ProximityIn + 1;
+ DeviceStateNotify = ProximityOut + 1;
+ DeviceMappingNotify = DeviceStateNotify + 1;
+ ChangeDeviceNotify = DeviceMappingNotify + 1;
+ DeviceKeyStateNotify = ChangeDeviceNotify + 1;
+ DeviceButtonStateNotify = DeviceKeyStateNotify + 1;
+ DevicePresenceNotify = DeviceButtonStateNotify + 1;
+
+ event_base[KeyClass] = DeviceKeyPress;
+ event_base[ButtonClass] = DeviceButtonPress;
+ event_base[ValuatorClass] = DeviceMotionNotify;
+ event_base[ProximityClass] = ProximityIn;
+ event_base[FocusClass] = DeviceFocusIn;
+ event_base[OtherClass] = DeviceStateNotify;
+
+ BadDevice += extEntry->errorBase;
+ BadEvent += extEntry->errorBase;
+ BadMode += extEntry->errorBase;
+ DeviceBusy += extEntry->errorBase;
+ BadClass += extEntry->errorBase;
+
+ mask = GetNextExtEventMask();
+ SetMaskForExtEvent(mask, DeviceKeyPress);
+ AllowPropagateSuppress(mask);
+
+ mask = GetNextExtEventMask();
+ SetMaskForExtEvent(mask, DeviceKeyRelease);
+ AllowPropagateSuppress(mask);
+
+ mask = GetNextExtEventMask();
+ SetMaskForExtEvent(mask, DeviceButtonPress);
+ AllowPropagateSuppress(mask);
+
+ mask = GetNextExtEventMask();
+ SetMaskForExtEvent(mask, DeviceButtonRelease);
+ AllowPropagateSuppress(mask);
+
+ mask = GetNextExtEventMask();
+ SetMaskForExtEvent(mask, ProximityIn);
+ SetMaskForExtEvent(mask, ProximityOut);
+ AllowPropagateSuppress(mask);
+
+ mask = GetNextExtEventMask();
+ DeviceStateNotifyMask = mask;
+ SetMaskForExtEvent(mask, DeviceStateNotify);
+
+ mask = GetNextExtEventMask();
+ DevicePointerMotionMask = mask;
+ SetMaskForExtEvent(mask, DeviceMotionNotify);
+ AllowPropagateSuppress(mask);
+
+ DevicePointerMotionHintMask = GetNextExtEventMask();
+ SetEventInfo(DevicePointerMotionHintMask, _devicePointerMotionHint);
+ SetEventInfo(GetNextExtEventMask(), _deviceButton1Motion);
+ SetEventInfo(GetNextExtEventMask(), _deviceButton2Motion);
+ SetEventInfo(GetNextExtEventMask(), _deviceButton3Motion);
+ SetEventInfo(GetNextExtEventMask(), _deviceButton4Motion);
+ SetEventInfo(GetNextExtEventMask(), _deviceButton5Motion);
+ DeviceButtonMotionMask = GetNextExtEventMask();
+ SetEventInfo(DeviceButtonMotionMask, _deviceButtonMotion);
+
+ DeviceFocusChangeMask = GetNextExtEventMask();
+ SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusIn);
+ SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusOut);
+
+ mask = GetNextExtEventMask();
+ SetMaskForExtEvent(mask, DeviceMappingNotify);
+ DeviceMappingNotifyMask = mask;
+
+ mask = GetNextExtEventMask();
+ SetMaskForExtEvent(mask, ChangeDeviceNotify);
+ ChangeDeviceNotifyMask = mask;
+
+ DeviceButtonGrabMask = GetNextExtEventMask();
+ SetEventInfo(DeviceButtonGrabMask, _deviceButtonGrab);
+ SetExclusiveAccess(DeviceButtonGrabMask);
+
+ DeviceOwnerGrabButtonMask = GetNextExtEventMask();
+ SetEventInfo(DeviceOwnerGrabButtonMask, _deviceOwnerGrabButton);
+
+ DevicePresenceNotifyMask = GetNextExtEventMask();
+ SetEventInfo(DevicePresenceNotifyMask, _devicePresence);
+ SetEventInfo(0, _noExtensionEvent);
+}
+
+/************************************************************************
+ *
+ * This function restores extension event types and masks to their
+ * initial state.
+ *
+ */
+
+static void
+RestoreExtensionEvents(void)
+{
+ int i;
+
+ IReqCode = 0;
+
+ for (i = 0; i < ExtEventIndex - 1; i++) {
+ if ((EventInfo[i].type >= LASTEvent) && (EventInfo[i].type < 128))
+ SetMaskForEvent(0, EventInfo[i].type);
+ EventInfo[i].mask = 0;
+ EventInfo[i].type = 0;
+ }
+ ExtEventIndex = 0;
+ lastExtEventMask = 1;
+ DeviceValuator = 0;
+ DeviceKeyPress = 1;
+ DeviceKeyRelease = 2;
+ DeviceButtonPress = 3;
+ DeviceButtonRelease = 4;
+ DeviceMotionNotify = 5;
+ DeviceFocusIn = 6;
+ DeviceFocusOut = 7;
+ ProximityIn = 8;
+ ProximityOut = 9;
+ DeviceStateNotify = 10;
+ DeviceMappingNotify = 11;
+ ChangeDeviceNotify = 12;
+ DeviceKeyStateNotify = 13;
+ DeviceButtonStateNotify = 13;
+ DevicePresenceNotify = 14;
+
+ BadDevice = 0;
+ BadEvent = 1;
+ BadMode = 2;
+ DeviceBusy = 3;
+ BadClass = 4;
+
+}
+
+/***********************************************************************
+ *
+ * IResetProc.
+ * Remove reply-swapping routine.
+ * Remove event-swapping routine.
+ *
+ */
+
+static void
+IResetProc(ExtensionEntry * unused)
+{
+
+ ReplySwapVector[IReqCode] = ReplyNotSwappd;
+ EventSwapVector[DeviceValuator] = NotImplemented;
+ EventSwapVector[DeviceKeyPress] = NotImplemented;
+ EventSwapVector[DeviceKeyRelease] = NotImplemented;
+ EventSwapVector[DeviceButtonPress] = NotImplemented;
+ EventSwapVector[DeviceButtonRelease] = NotImplemented;
+ EventSwapVector[DeviceMotionNotify] = NotImplemented;
+ EventSwapVector[DeviceFocusIn] = NotImplemented;
+ EventSwapVector[DeviceFocusOut] = NotImplemented;
+ EventSwapVector[ProximityIn] = NotImplemented;
+ EventSwapVector[ProximityOut] = NotImplemented;
+ EventSwapVector[DeviceStateNotify] = NotImplemented;
+ EventSwapVector[DeviceKeyStateNotify] = NotImplemented;
+ EventSwapVector[DeviceButtonStateNotify] = NotImplemented;
+ EventSwapVector[DeviceMappingNotify] = NotImplemented;
+ EventSwapVector[ChangeDeviceNotify] = NotImplemented;
+ EventSwapVector[DevicePresenceNotify] = NotImplemented;
+ RestoreExtensionEvents();
+}
+
+/***********************************************************************
+ *
+ * Assign an id and type to an input device.
+ *
+ */
+
+_X_EXPORT void
+AssignTypeAndName(DeviceIntPtr dev, Atom type, char *name)
+{
+ dev->type = type;
+ dev->name = (char *)xalloc(strlen(name) + 1);
+ strcpy(dev->name, name);
+}
+
+/***********************************************************************
+ *
+ * Make device type atoms.
+ *
+ */
+
+static void
+MakeDeviceTypeAtoms(void)
+{
+ int i;
+
+ for (i = 0; i < NUMTYPES; i++)
+ dev_type[i].type =
+ MakeAtom(dev_type[i].name, strlen(dev_type[i].name), 1);
+}
+
+/*****************************************************************************
+ *
+ * SEventIDispatch
+ *
+ * Swap any events defined in this extension.
+ */
+#define DO_SWAP(func,type) func ((type *)from, (type *)to)
+
+static void
+SEventIDispatch(xEvent * from, xEvent * to)
+{
+ int type = from->u.u.type & 0177;
+
+ if (type == DeviceValuator)
+ DO_SWAP(SEventDeviceValuator, deviceValuator);
+ else if (type == DeviceKeyPress) {
+ SKeyButtonPtrEvent(from, to);
+ to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
+ } else if (type == DeviceKeyRelease) {
+ SKeyButtonPtrEvent(from, to);
+ to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
+ } else if (type == DeviceButtonPress) {
+ SKeyButtonPtrEvent(from, to);
+ to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
+ } else if (type == DeviceButtonRelease) {
+ SKeyButtonPtrEvent(from, to);
+ to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
+ } else if (type == DeviceMotionNotify) {
+ SKeyButtonPtrEvent(from, to);
+ to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
+ } else if (type == DeviceFocusIn)
+ DO_SWAP(SEventFocus, deviceFocus);
+ else if (type == DeviceFocusOut)
+ DO_SWAP(SEventFocus, deviceFocus);
+ else if (type == ProximityIn) {
+ SKeyButtonPtrEvent(from, to);
+ to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
+ } else if (type == ProximityOut) {
+ SKeyButtonPtrEvent(from, to);
+ to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
+ } else if (type == DeviceStateNotify)
+ DO_SWAP(SDeviceStateNotifyEvent, deviceStateNotify);
+ else if (type == DeviceKeyStateNotify)
+ DO_SWAP(SDeviceKeyStateNotifyEvent, deviceKeyStateNotify);
+ else if (type == DeviceButtonStateNotify)
+ DO_SWAP(SDeviceButtonStateNotifyEvent, deviceButtonStateNotify);
+ else if (type == DeviceMappingNotify)
+ DO_SWAP(SDeviceMappingNotifyEvent, deviceMappingNotify);
+ else if (type == ChangeDeviceNotify)
+ DO_SWAP(SChangeDeviceNotifyEvent, changeDeviceNotify);
+ else if (type == DevicePresenceNotify)
+ DO_SWAP(SDevicePresenceNotifyEvent, devicePresenceNotify);
+ else {
+ FatalError("XInputExtension: Impossible event!\n");
+ }
+}
+
+/**********************************************************************
+ *
+ * IExtensionInit - initialize the input extension.
+ *
+ * Called from InitExtensions in main() or from QueryExtension() if the
+ * extension is dynamically loaded.
+ *
+ * This extension has several events and errors.
+ *
+ */
+
+void
+XInputExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+
+ extEntry = AddExtension(INAME, IEVENTS, IERRORS, ProcIDispatch,
+ SProcIDispatch, IResetProc, StandardMinorOpcode);
+ if (extEntry) {
+ IReqCode = extEntry->base;
+ AllExtensionVersions[IReqCode - 128] = thisversion;
+ MakeDeviceTypeAtoms();
+ RT_INPUTCLIENT = CreateNewResourceType((DeleteType) InputClientGone);
+ RegisterResourceName(RT_INPUTCLIENT, "INPUTCLIENT");
+ FixExtensionEvents(extEntry);
+ ReplySwapVector[IReqCode] = (ReplySwapPtr) SReplyIDispatch;
+ EventSwapVector[DeviceValuator] = SEventIDispatch;
+ EventSwapVector[DeviceKeyPress] = SEventIDispatch;
+ EventSwapVector[DeviceKeyRelease] = SEventIDispatch;
+ EventSwapVector[DeviceButtonPress] = SEventIDispatch;
+ EventSwapVector[DeviceButtonRelease] = SEventIDispatch;
+ EventSwapVector[DeviceMotionNotify] = SEventIDispatch;
+ EventSwapVector[DeviceFocusIn] = SEventIDispatch;
+ EventSwapVector[DeviceFocusOut] = SEventIDispatch;
+ EventSwapVector[ProximityIn] = SEventIDispatch;
+ EventSwapVector[ProximityOut] = SEventIDispatch;
+ EventSwapVector[DeviceStateNotify] = SEventIDispatch;
+ EventSwapVector[DeviceKeyStateNotify] = SEventIDispatch;
+ EventSwapVector[DeviceButtonStateNotify] = SEventIDispatch;
+ EventSwapVector[DeviceMappingNotify] = SEventIDispatch;
+ EventSwapVector[ChangeDeviceNotify] = SEventIDispatch;
+ EventSwapVector[DevicePresenceNotify] = SEventIDispatch;
+ } else {
+ FatalError("IExtensionInit: AddExtensions failed\n");
+ }
+}