summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2006-12-01 15:56:52 +1030
committerPeter Hutterer <whot@hyena.localdomain>2006-12-01 15:56:52 +1030
commit416f1bb99a6d4557f2863ae941868e47e11bbb3b (patch)
treeeeabb9e2f9496deb2e5c573878a4667e6bd29b29
parentafd6af65510b0147f16f08314045b3506bfa9d89 (diff)
mpx: SelectEvents and GetEventBase requests.
Some renaming and cleaning up in extinit.c MPXLastEvent added Xi: ShouldFreeInputMask() from XI is not static any more, used in mpx dix: GetPointerEvents() allocates MPX event for MPX devices. DeliverDeviceEvents() caters for MPX devices.
-rw-r--r--Changelog46
-rw-r--r--Xi/exevents.c4
-rw-r--r--configure.ac2
-rw-r--r--dix/events.c14
-rw-r--r--dix/getevents.c35
-rw-r--r--include/mpxevents.h19
-rw-r--r--include/mpxextinit.h72
-rw-r--r--mpx/Makefile.am9
-rw-r--r--mpx/extinit.c95
-rw-r--r--mpx/getevbase.c55
-rw-r--r--mpx/getevbase.h16
-rw-r--r--mpx/getvers.c5
-rw-r--r--mpx/listdev.c187
-rw-r--r--mpx/listdev.h53
-rw-r--r--mpx/mpxglobals.h16
-rw-r--r--mpx/selectev.c132
-rw-r--r--mpx/selectev.h17
17 files changed, 720 insertions, 57 deletions
diff --git a/Changelog b/Changelog
index c818bce63..a63021c87 100644
--- a/Changelog
+++ b/Changelog
@@ -1,5 +1,49 @@
MPX Changelog file
-== 29.11.206 ==
+== 01.12.06 ==
+
+mpx: SelectEvents and GetEventBase requests.
+ Some renaming and cleaning up in extinit.c
+ MPXLastEvent added
+
+Xi: ShouldFreeInputMask() from XI is not static any more, used in mpx
+
+dix: GetPointerEvents() allocates MPX event for MPX devices.
+ DeliverDeviceEvents() caters for MPX devices.
+
+
+Files:
+ configure.ac
+ mpx/Makefile.am
+ mpx/extinit.c
+ mpx/getvers.c
+ mpx/getevbase.c
+ mpx/getevbase.h
+ mpx/listdev.c
+ mpx/listdev.h
+ mpx/mpxglobals.h
+ mpx/selectev.c
+ mpx/selectev.h
+ mpx/mpxevents.h
+ Xi/exevents.c
+ dix/events.c
+ dix/getevents.c
+ include/mpxevents.h
+ include/mpxextinit.h
+
+
+== 30.11.06
+mpx: Adding ListDevices request. Minor changes, using
+ MPXRestoreExtensionEvents() when resetting.
+
+Files:
+ mpx/Makefile.am
+ mpx/extinit.c
+ mpx/listdev.c
+ mpx/listdev.h
+ mpx/mpxextinit.h
+
+
+== 29.11.06 ==
mpx: Infrastructure for MPX extension, GetExtensionVersion request works.
Files:
diff --git a/Xi/exevents.c b/Xi/exevents.c
index ecbb1990a..26c3f4ba2 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -82,7 +82,7 @@ SOFTWARE.
#define Motion_Filter(class) (DevicePointerMotionMask | \
(class)->state | (class)->motionMask)
-static Bool ShouldFreeInputMasks(WindowPtr /* pWin */ ,
+Bool ShouldFreeInputMasks(WindowPtr /* pWin */ ,
Bool /* ignoreSelectedEvents */
);
static Bool MakeInputMasks(WindowPtr /* pWin */
@@ -1196,7 +1196,7 @@ DeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask,
return Success;
}
-static Bool
+Bool
ShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents)
{
int i;
diff --git a/configure.ac b/configure.ac
index e5d2f5ea2..fa1a5c859 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1003,7 +1003,7 @@ AC_EGREP_CPP([I_AM_SVR4],[
AC_DEFINE([SVR4],1,[Define to 1 on systems derived from System V Release 4])
AC_MSG_RESULT([yes])], AC_MSG_RESULT([no]))
-XSERVER_CFLAGS="$XSERVER_CFLAGS $CORE_INCS $XEXT_INC $COMPOSITE_INC $DAMAGE_INC $FIXES_INC $XI_INC $MI_INC $MIEXT_SHADOW_INC $MIEXT_LAYER_INC $MIEXT_DAMAGE_INC $RENDER_INC $RANDR_INC $FB_INC"
+XSERVER_CFLAGS="$XSERVER_CFLAGS $CORE_INCS $XEXT_INC $COMPOSITE_INC $DAMAGE_INC $FIXES_INC $XI_INC $MI_INC $MIEXT_SHADOW_INC $MIEXT_LAYER_INC $MIEXT_DAMAGE_INC $RENDER_INC $RANDR_INC $FB_INC $MPX_INC"
AC_DEFINE_UNQUOTED(X_BYTE_ORDER,[$ENDIAN],[Endian order])
AC_SUBST([XSERVER_LIBS])
diff --git a/dix/events.c b/dix/events.c
index 8ef318a22..c7d4df028 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -107,6 +107,12 @@ of the copyright holder.
******************************************************************/
+/*
+ * MPX additions
+ * Copyright 2006 by Peter Hutterer
+ * Author: Peter Hutterer <peter@cs.unisa.edu.au>
+ */
+
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
@@ -171,6 +177,10 @@ xEvent *xeviexE;
#include "dixgrabs.h"
#include "dispatch.h"
+#ifdef MPX
+#include "mpxglobals.h"
+#endif
+
#define EXTENSION_EVENT_BASE 64
#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
@@ -1924,6 +1934,10 @@ DeliverDeviceEvents(register WindowPtr pWin, register xEvent *xE, GrabPtr grab,
{
register OtherInputMasks *inputMasks;
int mskidx = dev->id;
+#ifdef MPX
+ if (IsMPXEvent(xE))
+ mskidx = MPXmskidx;
+#endif
inputMasks = wOtherInputMasks(pWin);
if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
diff --git a/dix/getevents.c b/dix/getevents.c
index 9c7b7230b..7c121a5ca 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -21,15 +21,12 @@
*
* Author: Daniel Stone <daniel@fooishbar.org>
*/
-#ifdef MPX
/*
* MPX additions:
* Copyright © 2006 Peter Hutterer
- * License see above.
* Author: Peter Hutterer <peter@cs.unisa.edu.au>
*
*/
-#endif
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
@@ -72,6 +69,11 @@ extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies);
#include "exglobals.h"
#include "extnsionst.h"
+#ifdef MPX
+#include <X11/extensions/MPXconst.h>
+#include <X11/extensions/MPXproto.h>
+#include "mpxglobals.h"
+#endif
/* Maximum number of valuators, divided by six, rounded up, to get number
* of events. */
@@ -511,7 +513,11 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
if ((type == ButtonPress || type == ButtonRelease) && !pDev->button)
return 0;
-
+#ifdef MPX
+ if (pDev->isMPDev)
+ num_events = 3;
+ else
+#endif
if (pDev->coreEvents)
num_events = 2;
else
@@ -603,7 +609,7 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
#ifdef MPX
if (flags & POINTER_MULTIPOINTER)
{
- // noop, just to fit MPX in easier with the following if
+ // noop, just less intrusive to fit MPX in like that
} else
#endif
if (pDev->coreEvents) {
@@ -637,6 +643,25 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
}
#ifdef MPX
+ if (pDev->isMPDev)
+ {
+ /* MPX events are the same as XI events but without valuators. */
+ memcpy(events, kbp, sizeof(deviceKeyButtonPointer));
+ switch(type)
+ {
+ case ButtonPress:
+ events->u.u.type = MPXButtonPress;
+ break;
+ case ButtonRelease:
+ events->u.u.type = MPXButtonRelease;
+ break;
+ case MotionNotify:
+ events->u.u.type = MPXMotionNotify;
+ break;
+ }
+ events++;
+ }
+
/* MPX devices always send core events */
if (pDev->coreEvents || pDev->isMPDev) {
#else
diff --git a/include/mpxevents.h b/include/mpxevents.h
new file mode 100644
index 000000000..99bf2b009
--- /dev/null
+++ b/include/mpxevents.h
@@ -0,0 +1,19 @@
+/* Copyright 2006 by Peter Hutterer <peter@cs.unisa.edu.au> */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef MPXEVENTS_H
+#define MPXEVENTS_H 1
+
+#include <X11/X.h> /* for inputstr.h */
+#include <X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+
+extern int MPXSelectForWindow(
+ WindowPtr /* pWin */,
+ ClientPtr /* client */,
+ int /* mask */);
+
+#endif
diff --git a/include/mpxextinit.h b/include/mpxextinit.h
new file mode 100644
index 000000000..7fbb4c432
--- /dev/null
+++ b/include/mpxextinit.h
@@ -0,0 +1,72 @@
+/* Copyright 2006 by Peter Hutterer <peter@cs.unisa.edu.au> */
+
+/********************************************************************
+ * Interface of mpx/extinit.c
+ */
+
+#ifndef MPXEXTINIT_H
+#define MPXEXTINIT_H
+
+#include "extnsionst.h"
+
+void
+MPXExtensionInit(
+ void
+ );
+
+int
+ProcMPXDispatch (
+ ClientPtr /* client */
+ );
+
+int
+SProcMPXDispatch(
+ ClientPtr /* client */
+ );
+
+void
+SReplyMPXDispatch (
+ ClientPtr /* client */,
+ int /* len */,
+ mpxGetExtensionVersionReply * /* rep */
+ );
+
+void
+SEventMPXDispatch (
+ xEvent * /* from */,
+ xEvent * /* to */
+ );
+
+void
+MPXFixExtensionEvents (
+ ExtensionEntry * /* extEntry */
+ );
+
+void
+MPXResetProc(
+ ExtensionEntry * /* unused */
+ );
+
+Mask
+MPXGetNextExtEventMask (
+ void
+);
+
+void
+MPXSetMaskForExtEvent(
+ Mask /* mask */,
+ int /* event */
+ );
+
+void
+MPXAllowPropagateSuppress (
+ Mask /* mask */
+ );
+
+void
+MPXRestoreExtensionEvents (
+ void
+ );
+#endif
+
+
diff --git a/mpx/Makefile.am b/mpx/Makefile.am
index db75eb53e..63c384fe2 100644
--- a/mpx/Makefile.am
+++ b/mpx/Makefile.am
@@ -5,5 +5,12 @@ AM_CFLAGS = $(DIX_CFLAGS)
libmpx_la_SOURCES = \
extinit.c \
getvers.c \
- getvers.h
+ getvers.h \
+ listdev.c \
+ listdev.h \
+ selectev.c \
+ selectev.h \
+ mpxglobals.h \
+ getevbase.c \
+ getevbase.h
diff --git a/mpx/extinit.c b/mpx/extinit.c
index 59bc49448..89a9dc713 100644
--- a/mpx/extinit.c
+++ b/mpx/extinit.c
@@ -11,17 +11,36 @@
#include "extnsionst.h" /* extension entry */
#include <X11/extensions/MPX.h>
#include <X11/extensions/MPXproto.h>
+#include <X11/extensions/MPXconst.h>
+#include "mpxglobals.h"
#include "mpxextinit.h"
#include "swaprep.h"
#include "getvers.h"
+#include "listdev.h"
+#include "selectev.h"
+#include "getevbase.h"
static Mask lastExtEventMask = 1;
-int ExtEventIndex;
-Mask ExtValidMasks[EMASKSIZE];
+int MPXEventIndex;
+MPXExtEventInfo EventInfo[32];
+
+/**
+ * MPX piggybacks on the X Input extension's event system. Each window has an
+ * array of event masks, from 0 to MAX_DEVICES. In XI, each device can have
+ * separate event masks. Before an event is delivered, the array at the index
+ * of the device is checked.
+ *
+ * Two things:
+ * -) core devices do not send input extension events
+ * -) MPX events are not device specific.
+ *
+ * Since the mask of the core pointer (index 1) is thus not used by XI, MPX
+ * can use it for the event mask. This also makes MPX less intrusive.
+ */
+int MPXmskidx = 1;
-XExtEventInfo EventInfo[32];
/*****************************************************************
*
@@ -29,7 +48,7 @@ XExtEventInfo EventInfo[32];
*
*/
-extern XExtensionVersion AllExtensionVersions[];
+extern MPXExtensionVersion AllExtensionVersions[];
Mask PropagateMask[MAX_DEVICES];
@@ -46,6 +65,7 @@ int MPXErrorBase = 0;
int MPXButtonPress;
int MPXButtonRelease;
int MPXMotionNotify;
+int MPXLastEvent;
/*****************************************************************
*
@@ -53,7 +73,8 @@ int MPXMotionNotify;
*
*/
-static XExtensionVersion thisversion = { MPX_Present,
+static MPXExtensionVersion thisversion = {
+ MPX_Present,
MPX_Major,
MPX_Minor
};
@@ -106,6 +127,12 @@ ProcMPXDispatch(register ClientPtr client)
REQUEST(xReq);
if (stuff->data == MPX_GetExtensionVersion)
return (ProcMPXGetExtensionVersion(client));
+ if (stuff->data == MPX_ListDevices)
+ return (ProcMPXListDevices(client));
+ if (stuff->data == MPX_SelectEvents)
+ return (ProcMPXSelectEvents(client));
+ if (stuff->data == MPX_GetEventBase)
+ return (ProcMPXGetEventBase(client));
else {
SendErrorToClient(client, MPXReqCode, stuff->data, 0, BadRequest);
}
@@ -128,6 +155,12 @@ SProcMPXDispatch(register ClientPtr client)
REQUEST(xReq);
if (stuff->data == MPX_GetExtensionVersion)
return (SProcMPXGetExtensionVersion(client));
+ if (stuff->data == MPX_ListDevices)
+ return (SProcMPXListDevices(client));
+ if (stuff->data == MPX_SelectEvents)
+ return (SProcMPXSelectEvents(client));
+ if (stuff->data == MPX_GetEventBase)
+ return (SProcMPXGetEventBase(client));
else {
SendErrorToClient(client, MPXReqCode, stuff->data, 0, BadRequest);
}
@@ -151,6 +184,8 @@ MPXResetProc(ExtensionEntry* unused)
EventSwapVector[MPXButtonRelease] = NotImplemented;
EventSwapVector[MPXMotionNotify] = NotImplemented;
+ MPXRestoreExtensionEvents();
+
}
void SReplyMPXDispatch(ClientPtr client, int len, mpxGetExtensionVersionReply* rep)
@@ -158,6 +193,9 @@ void SReplyMPXDispatch(ClientPtr client, int len, mpxGetExtensionVersionReply* r
if (rep->RepType == MPX_GetExtensionVersion)
SRepMPXGetExtensionVersion(client, len,
(mpxGetExtensionVersionReply*) rep);
+ if (rep->RepType == MPX_ListDevices)
+ SRepMPXListDevices(client, len,
+ (mpxListDevicesReply*) rep);
else {
FatalError("MPX confused sending swapped reply");
}
@@ -184,46 +222,16 @@ SEventMPXDispatch(xEvent* from, xEvent* to)
void
MPXFixExtensionEvents(ExtensionEntry* extEntry)
{
- Mask mask;
-
MPXButtonPress = extEntry->eventBase;
MPXButtonRelease = MPXButtonPress + 1;
MPXMotionNotify = MPXButtonRelease + 1;
+ MPXLastEvent = MPXMotionNotify + 1;
- mask = MPXGetNextExtEventMask();
- MPXSetMaskForExtEvent(mask, MPXButtonPress);
- MPXAllowPropagateSuppress(mask);
-
- mask = MPXGetNextExtEventMask();
- MPXSetMaskForExtEvent(mask, MPXButtonRelease);
- MPXAllowPropagateSuppress(mask);
-
- mask = MPXGetNextExtEventMask();
- MPXSetMaskForExtEvent(mask, MPXMotionNotify);
- MPXAllowPropagateSuppress(mask);
-
+ MPXSetMaskForExtEvent(MPXButtonPressMask, MPXButtonPress);
+ MPXSetMaskForExtEvent(MPXButtonReleaseMask, MPXButtonRelease);
+ MPXSetMaskForExtEvent(MPXPointerMotionMask, MPXMotionNotify);
}
-/**************************************************************************
- *
- * Return the next available extension event mask.
- *
- */
-Mask
-MPXGetNextExtEventMask(void)
-{
- int i;
- Mask mask = lastExtEventMask;
-
- if (lastExtEventMask == 0) {
- FatalError("MPXGetNextExtEventMask: no more events are available.");
- }
- lastExtEventMask <<= 1;
-
- for (i = 0; i < MAX_DEVICES; i++)
- ExtValidMasks[i] |= mask;
- return mask;
-}
/**************************************************************************
*
@@ -235,8 +243,8 @@ void
MPXSetMaskForExtEvent(Mask mask, int event)
{
- EventInfo[ExtEventIndex].mask = mask;
- EventInfo[ExtEventIndex++].type = event;
+ EventInfo[MPXEventIndex].mask = mask;
+ EventInfo[MPXEventIndex++].type = event;
if ((event < LASTEvent) || (event >= 128))
FatalError("MaskForExtensionEvent: bogus event number");
@@ -256,14 +264,14 @@ MPXRestoreExtensionEvents(void)
int i;
MPXReqCode = 0;
- for (i = 0; i < ExtEventIndex - 1; i++) {
+ for (i = 0; i < MPXEventIndex - 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;
+ MPXEventIndex = 0;
lastExtEventMask = 1;
MPXButtonPress = 0;
MPXButtonRelease = 1;
@@ -285,3 +293,4 @@ MPXAllowPropagateSuppress(Mask mask)
for (i = 0; i < MAX_DEVICES; i++)
PropagateMask[i] |= mask;
}
+
diff --git a/mpx/getevbase.c b/mpx/getevbase.c
new file mode 100644
index 000000000..7ec82f676
--- /dev/null
+++ b/mpx/getevbase.c
@@ -0,0 +1,55 @@
+/* Copyright 2006 by Peter Hutterer <peter@cs.unisa.edu.au> */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h> /* for inputstr.h */
+#include <X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <X11/extensions/MPX.h>
+#include <X11/extensions/MPXproto.h>
+
+#include "mpxglobals.h"
+#include "getevbase.h"
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the MPXGetEventBase function.
+ */
+int
+ProcMPXGetEventBase(register ClientPtr client)
+{
+ mpxGetEventBaseReply rep;
+
+ REQUEST(mpxGetEventBaseReq);
+ REQUEST_SIZE_MATCH(mpxGetEventBaseReq);
+
+ memset(&rep, 0, sizeof(mpxGetEventBaseReply));
+ rep.repType = X_Reply;
+ rep.RepType = MPX_GetEventBase;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rep.eventBase = MPXEventBase;
+
+ WriteReplyToClient(client, sizeof(mpxGetEventBaseReply), &rep);
+
+ return Success;
+}
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the MPXGetEventBase function.
+ */
+int
+SProcMPXGetEventBase(register ClientPtr client)
+{
+ register char n;
+
+ REQUEST(mpxGetEventBaseReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(mpxGetEventBaseReq);
+ return (ProcMPXGetEventBase(client));
+}
+
diff --git a/mpx/getevbase.h b/mpx/getevbase.h
new file mode 100644
index 000000000..5ff8284dc
--- /dev/null
+++ b/mpx/getevbase.h
@@ -0,0 +1,16 @@
+/* Copyright 2006 by Peter Hutterer <peter@cs.unisa.edu.au> */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GETEVBASE_H
+#define GETEVBASE_H 1
+
+int SProcMPXGetEventBase(ClientPtr /* client */
+ );
+
+int ProcMPXGetEventBase(ClientPtr /* client */
+ );
+
+#endif /* GETEVBASE_H */
diff --git a/mpx/getvers.c b/mpx/getvers.c
index 4663c5459..7297a1fb5 100644
--- a/mpx/getvers.c
+++ b/mpx/getvers.c
@@ -13,7 +13,7 @@
#include "mpxglobals.h"
#include "getvers.h"
-XExtensionVersion AllExtensionVersions[128];
+MPXExtensionVersion AllExtensionVersions[128];
/***********************************************************************
*
@@ -33,7 +33,6 @@ SProcMPXGetExtensionVersion(register ClientPtr client)
REQUEST_AT_LEAST_SIZE(mpxGetExtensionVersionReq);
return (ProcMPXGetExtensionVersion(client));
}
-
/***********************************************************************
*
* This procedure writes the reply for the XGetExtensionVersion function.
@@ -78,3 +77,5 @@ SRepMPXGetExtensionVersion(ClientPtr client, int size,
swaps(&rep->minor_version, n);
WriteToClient(client, size, (char *)rep);
}
+
+
diff --git a/mpx/listdev.c b/mpx/listdev.c
new file mode 100644
index 000000000..8bb27b30b
--- /dev/null
+++ b/mpx/listdev.c
@@ -0,0 +1,187 @@
+/* Copyright 2006 by Peter Hutterer <peter@cs.unisa.edu.au> */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "inputstr.h"
+
+#include <X11/extensions/MPX.h>
+#include <X11/extensions/MPXproto.h>
+
+#include "mpxextinit.h"
+#include "mpxglobals.h"
+
+#include "listdev.h"
+
+/***********************************************************************
+ *
+ * This procedure lists the MPX devices available to the server.
+ *
+ */
+int SProcMPXListDevices(register ClientPtr client)
+{
+ register char n;
+
+ REQUEST(mpxListDevicesReq);
+ swaps(&stuff->length, n);
+ return (ProcMPXListDevices(client));
+}
+
+/***********************************************************************
+ *
+ * This procedure lists the MPX devices available to the server.
+ *
+ * Strongly based on ProcXListInputDevices
+ */
+int ProcMPXListDevices(register ClientPtr client)
+{
+ mpxListDevicesReply rep;
+ int numdevs = 0;
+ int namesize = 1; /* need 1 extra byte for strcpy */
+ int size = 0;
+ int total_length;
+ char* devbuf;
+ char* namebuf;
+ char *savbuf;
+ mpxDeviceInfoPtr dev;
+ DeviceIntPtr d;
+
+ REQUEST_SIZE_MATCH(mpxListDevicesReq);
+ memset(&rep, 0, sizeof(mpxListDevicesReply));
+ rep.repType = X_Reply;
+ rep.RepType = MPX_ListDevices;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ for (d = inputInfo.devices; d; d = d->next) {
+ if (d->isMPDev)
+ {
+ SizeMPXDeviceInfo(d, &namesize, &size);
+ numdevs++;
+ }
+ }
+
+ for (d = inputInfo.off_devices; d; d = d->next) {
+ if (d->isMPDev)
+ {
+ SizeMPXDeviceInfo(d, &namesize, &size);
+ numdevs++;
+ }
+ }
+
+ total_length = numdevs * sizeof(mpxDeviceInfo) + size + namesize;
+ devbuf = (char *)xalloc(total_length);
+ namebuf = devbuf + (numdevs * sizeof(mpxDeviceInfo));
+ savbuf = devbuf;
+
+ dev = (mpxDeviceInfoPtr) devbuf;
+ for (d = inputInfo.devices; d; d = d->next, dev++)
+ if (d->isMPDev)
+ SetMPXDeviceInfo(client, d, dev, &devbuf, &namebuf);
+ for (d = inputInfo.off_devices; d; d = d->next, dev++)
+ if (d->isMPDev)
+ SetMPXDeviceInfo(client, d, dev, &devbuf, &namebuf);
+
+ rep.ndevices = numdevs;
+ rep.length = (total_length + 3) >> 2;
+ WriteReplyToClient(client, sizeof(mpxListDevicesReply), &rep);
+ WriteToClient(client, total_length, savbuf);
+ xfree(savbuf);
+ return Success;
+}
+
+/***********************************************************************
+ *
+ * This procedure calculates the size of the information to be returned
+ * for an input device.
+ *
+ */
+
+void
+SizeMPXDeviceInfo(DeviceIntPtr d, int *namesize, int *size)
+{
+ *namesize += 1;
+ if (d->name)
+ *namesize += strlen(d->name);
+}
+
+/***********************************************************************
+ *
+ * This procedure sets information to be returned for an input device.
+ *
+ */
+
+void
+SetMPXDeviceInfo(ClientPtr client, DeviceIntPtr d, mpxDeviceInfoPtr dev,
+ char **devbuf, char **namebuf)
+{
+ MPXCopyDeviceName(namebuf, d->name);
+ MPXCopySwapDevice(client, d, devbuf);
+}
+
+
+/***********************************************************************
+ *
+ * This procedure copies data to the DeviceInfo struct, swapping if necessary.
+ *
+ * We need the extra byte in the allocated buffer, because the trailing null
+ * hammers one extra byte, which is overwritten by the next name except for
+ * the last name copied.
+ *
+ */
+
+void
+MPXCopyDeviceName(char **namebuf, char *name)
+{
+ char *nameptr = (char *)*namebuf;
+
+ if (name) {
+ *nameptr++ = strlen(name);
+ strcpy(nameptr, name);
+ *namebuf += (strlen(name) + 1);
+ } else {
+ *nameptr++ = 0;
+ *namebuf += 1;
+ }
+}
+
+/***********************************************************************
+ *
+ * This procedure copies data to the DeviceInfo struct, swapping if necessary.
+ *
+ */
+void
+MPXCopySwapDevice(register ClientPtr client, DeviceIntPtr d, char **buf)
+{
+ register char n;
+ mpxDeviceInfoPtr dev;
+
+ dev = (mpxDeviceInfoPtr) * buf;
+ memset(dev, 0, sizeof(mpxDeviceInfo));
+
+ dev->id = d->id;
+ dev->type = d->type;
+ if (client->swapped) {
+ swapl(&dev->type, n); /* macro - braces are required */
+ }
+ *buf += sizeof(mpxDeviceInfo);
+}
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the MPXListDevices function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+void
+SRepMPXListDevices(ClientPtr client, int size, mpxListDevicesReply * rep)
+{
+ register char n;
+
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ WriteToClient(client, size, (char *)rep);
+}
diff --git a/mpx/listdev.h b/mpx/listdev.h
new file mode 100644
index 000000000..0d2e0dc22
--- /dev/null
+++ b/mpx/listdev.h
@@ -0,0 +1,53 @@
+/* Copyright 2006 by Peter Hutterer <peter@cs.unisa.edu.au> */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef LISTDEV_H
+#define LISTDEV_H 1
+
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "inputstr.h"
+
+#include <X11/extensions/MPX.h>
+#include <X11/extensions/MPXproto.h>
+
+#include "mpxextinit.h"
+#include "mpxglobals.h"
+
+int SProcMPXListDevices(ClientPtr /* client */
+ );
+
+int ProcMPXListDevices(ClientPtr /* client */
+ );
+
+void SizeMPXDeviceInfo(DeviceIntPtr /* d */ ,
+ int * /* namesize */ ,
+ int * /* size */
+ );
+
+void SetMPXDeviceInfo(ClientPtr /* client */ ,
+ DeviceIntPtr /* d */ ,
+ mpxDeviceInfoPtr /* dev */ ,
+ char ** /* devbuf */ ,
+ char ** /* namebuf */
+ );
+
+
+void MPXCopyDeviceName(char ** /* namebuf */ ,
+ char * /* name */
+ );
+
+void MPXCopySwapDevice(ClientPtr /* client */ ,
+ DeviceIntPtr /* d */ ,
+ char ** /* buf */
+ );
+
+void SRepMPXListDevices(ClientPtr /* client */ ,
+ int /* size */ ,
+ mpxListDevicesReply * /* rep */
+ );
+#endif
diff --git a/mpx/mpxglobals.h b/mpx/mpxglobals.h
index d74710c96..73f399032 100644
--- a/mpx/mpxglobals.h
+++ b/mpx/mpxglobals.h
@@ -4,12 +4,26 @@
#include <dix-config.h>
#endif
+#ifndef MPXGLOBALS_H
+#define MPXGLOBALS_H 1
+
extern int MPXReqCode;
extern int MPXEventBase;
extern int MPXErrorBase;
+extern Mask PropagateMask[];
+
+extern int MPXmskidx;
+
+/* events */
extern int MPXButtonPress;
extern int MPXButtonRelease;
extern int MPXMotionNotify;
+extern int MPXLastEvent;
-extern Mask PropagateMask[];
+#define IsMPXEvent(xE) \
+ ((xE)->u.u.type >= MPXEventBase \
+ && (xE)->u.u.type < MPXLastEvent)
+
+
+#endif
diff --git a/mpx/selectev.c b/mpx/selectev.c
index d29d3f15b..1e75a51b9 100644
--- a/mpx/selectev.c
+++ b/mpx/selectev.c
@@ -12,5 +12,135 @@
#include <X11/extensions/MPX.h>
#include <X11/extensions/MPXproto.h>
#include "extnsionst.h"
-#include "extinit.h" /* LookupDeviceIntRec */
+#include "mpxextinit.h" /* LookupDeviceIntRec */
+#include "mpxglobals.h"
+#include "mpxevents.h"
+
+#include "selectev.h"
+
+/* functions borrowed from XI */
+extern void RecalculateDeviceDeliverableEvents(
+ WindowPtr /* pWin */);
+
+extern int AddExtensionClient (
+ WindowPtr /* pWin */,
+ ClientPtr /* client */,
+ Mask /* mask */,
+ int /* mskidx */);
+extern Bool
+ShouldFreeInputMasks(WindowPtr /* pWin */,
+ Bool /* ignoreSelectedEvents */);
+
+/***********************************************************************
+ *
+ * Handle requests from clients with a different byte order.
+ *
+ */
+
+int
+SProcMPXSelectEvents(register ClientPtr client)
+{
+ register char n;
+
+ REQUEST(mpxSelectEventsReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(mpxSelectEventsReq);
+ swapl(&stuff->window, n);
+ return (ProcMPXSelectEvents(client));
+}
+
+/***********************************************************************
+ *
+ * This procedure selects input from an extension device.
+ *
+ */
+
+int
+ProcMPXSelectEvents(register ClientPtr client)
+{
+ int ret;
+ WindowPtr pWin;
+
+ REQUEST(mpxSelectEventsReq);
+ REQUEST_SIZE_MATCH(mpxSelectEventsReq);
+
+ if (stuff->length != (sizeof(mpxSelectEventsReq) >> 2))
+ {
+ SendErrorToClient(client, MPXReqCode, MPX_SelectEvents, 0,
+ BadLength);
+ return Success;
+ }
+
+ pWin = (WindowPtr) LookupWindow(stuff->window, client);
+ if (!pWin)
+ {
+ client->errorValue = stuff->window;
+ SendErrorToClient(client, MPXReqCode, MPX_SelectEvents, 0,
+ BadWindow);
+ return Success;
+ }
+
+ if (stuff->mask >= MPXHighestMask)
+ {
+ client->errorValue = stuff->mask;
+ SendErrorToClient(client, MPXReqCode, MPX_SelectEvents, 0,
+ BadValue);
+ }
+
+ if ((ret = MPXSelectForWindow(pWin, client, stuff->mask)) != Success)
+ {
+ SendErrorToClient(client, MPXReqCode, MPX_SelectEvents, 0, ret);
+ return Success;
+ }
+
+ return Success;
+}
+
+/**
+ * Selects a set of events for a given window.
+ * Different to XI, MPX is not device dependent. Either the client gets events
+ * from all devices or none.
+ *
+ * This method borrows some functions from XI, due to the piggyback on the
+ * core pointer (see comment in extinit.c)
+ */
+int
+MPXSelectForWindow(WindowPtr pWin, ClientPtr client, int mask)
+{
+ InputClientsPtr others;
+ int ret;
+
+ if (mask >= MPXHighestMask)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+
+ if (wOtherInputMasks(pWin))
+ {
+ for (others = wOtherInputMasks(pWin)->inputClients; others;
+ others = others->next)
+ {
+ if (SameClient(others, client)) {
+ others->mask[MPXmskidx] = mask;
+ if (mask == 0)
+ {
+ /* clean up stuff */
+ RecalculateDeviceDeliverableEvents(pWin);
+ if (ShouldFreeInputMasks(pWin, FALSE))
+ FreeResource(others->resource, RT_NONE);
+ return Success;
+ }
+ goto maskSet;
+ }
+ }
+ }
+ /* borrow from XI here */
+ if ((ret = AddExtensionClient(pWin, client, mask, MPXmskidx)) != Success)
+ return ret;
+maskSet:
+ RecalculateDeviceDeliverableEvents(pWin);
+ return Success;
+
+}
diff --git a/mpx/selectev.h b/mpx/selectev.h
new file mode 100644
index 000000000..702619987
--- /dev/null
+++ b/mpx/selectev.h
@@ -0,0 +1,17 @@
+/* Copyright 2006 by Peter Hutterer <peter@cs.unisa.edu.au> */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef SELECTEV_H
+#define SELECTEV_H 1
+
+int SProcMPXSelectEvents(ClientPtr /* client */
+ );
+
+int ProcMPXSelectEvents(ClientPtr /* client */
+ );
+
+#endif /* SELECTEV_H */