diff options
author | Peter Hutterer <peter@cs.unisa.edu.au> | 2006-12-01 15:56:52 +1030 |
---|---|---|
committer | Peter Hutterer <whot@hyena.localdomain> | 2006-12-01 15:56:52 +1030 |
commit | 416f1bb99a6d4557f2863ae941868e47e11bbb3b (patch) | |
tree | eeabb9e2f9496deb2e5c573878a4667e6bd29b29 | |
parent | afd6af65510b0147f16f08314045b3506bfa9d89 (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-- | Changelog | 46 | ||||
-rw-r--r-- | Xi/exevents.c | 4 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | dix/events.c | 14 | ||||
-rw-r--r-- | dix/getevents.c | 35 | ||||
-rw-r--r-- | include/mpxevents.h | 19 | ||||
-rw-r--r-- | include/mpxextinit.h | 72 | ||||
-rw-r--r-- | mpx/Makefile.am | 9 | ||||
-rw-r--r-- | mpx/extinit.c | 95 | ||||
-rw-r--r-- | mpx/getevbase.c | 55 | ||||
-rw-r--r-- | mpx/getevbase.h | 16 | ||||
-rw-r--r-- | mpx/getvers.c | 5 | ||||
-rw-r--r-- | mpx/listdev.c | 187 | ||||
-rw-r--r-- | mpx/listdev.h | 53 | ||||
-rw-r--r-- | mpx/mpxglobals.h | 16 | ||||
-rw-r--r-- | mpx/selectev.c | 132 | ||||
-rw-r--r-- | mpx/selectev.h | 17 |
17 files changed, 720 insertions, 57 deletions
@@ -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 */ |