summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xext/geext.c18
-rw-r--r--Xext/geext.h27
-rw-r--r--Xi/extinit.c12
-rw-r--r--dix/events.c7
4 files changed, 52 insertions, 12 deletions
diff --git a/Xext/geext.c b/Xext/geext.c
index f0801cbf8..0add5e1fb 100644
--- a/Xext/geext.c
+++ b/Xext/geext.c
@@ -41,15 +41,8 @@ int GEErrorBase;
int GEClientPrivateIndex;
int GEEventType; /* The opcode for all GenericEvents will have. */
-/* Struct to keep information about registered extensions
- */
-typedef struct _GEExtension {
- /* event swap function */
- void (*evswap)(xGenericEvent* from, xGenericEvent* to);
-} GEExtension, *GEExtensionPtr;
-/* All registered extensions */
-static GEExtension GEExtensions[MAXEXTENSIONS];
+GEExtension GEExtensions[MAXEXTENSIONS];
/* Major available requests */
static const int version_requests[] = {
@@ -249,11 +242,15 @@ GEExtensionInit(void)
/* Register an extension with GE. The given swap function will be called each
* time an event is sent to a client with different byte order.
* @param extension The extensions major opcode
- * @param ev_swap the event swap function.
+ * @param ev_swap The event swap function.
+ * @param ev_fill Called for an event before delivery. The extension now has
+ * the chance to fill in necessary fields for the event.
*/
void GERegisterExtension(
int extension,
- void (*ev_swap)(xGenericEvent* from, xGenericEvent* to)
+ void (*ev_swap)(xGenericEvent* from, xGenericEvent* to),
+ void (*ev_fill)(xGenericEvent* ev, DeviceIntPtr pDev,
+ WindowPtr pWin, GrabPtr pGrab)
)
{
if ((extension & 0x7F) >= MAXEXTENSIONS)
@@ -261,6 +258,7 @@ void GERegisterExtension(
/* extension opcodes are > 128, might as well save some space here */
GEExtensions[extension & 0x7f].evswap = ev_swap;
+ GEExtensions[extension & 0x7f].evfill = ev_fill;
}
diff --git a/Xext/geext.h b/Xext/geext.h
index 7a73e81e6..bac472662 100644
--- a/Xext/geext.h
+++ b/Xext/geext.h
@@ -34,6 +34,23 @@ from the author.
#define _GEEXT_H_
#include <X11/extensions/geproto.h>
+/* Struct to keep information about registered extensions
+ *
+ * evswap ... use to swap event fields for different byte ordered clients.
+ * evfill ... use to fill various event fields from the given parameters.
+ */
+typedef struct _GEExtension {
+ void (*evswap)(xGenericEvent* from, xGenericEvent* to);
+ void (*evfill)(xGenericEvent* ev,
+ DeviceIntPtr pDev, /* device */
+ WindowPtr pWin, /* event window */
+ GrabPtr pGrab /* current grab, may be NULL */
+ );
+} GEExtension, *GEExtensionPtr;
+
+/* All registered extensions and their handling functions. */
+extern GEExtension GEExtensions[MAXEXTENSIONS];
+
/* Returns the extension offset from the event */
#define GEEXT(ev) (((xGenericEvent*)(ev))->extension)
@@ -50,11 +67,19 @@ from the author.
#define GECLIENT(pWin) \
(((pWin)->optional) ? (pWin)->optional->geMasks->geClients : NULL)
+/* Returns the event_fill for the given event */
+#define GEEventFill(ev) \
+ GEExtensions[GEEXTIDX(xE)].evfill
+
/* Interface for other extensions */
void GEWindowSetMask(ClientPtr pClient, WindowPtr pWin, int extension, Mask mask);
void GERegisterExtension(
int extension,
- void (*ev_dispatch)(xGenericEvent* from, xGenericEvent* to));
+ void (*ev_dispatch)(xGenericEvent* from, xGenericEvent* to),
+ void (*ev_fill)(xGenericEvent* ev, DeviceIntPtr pDev,
+ WindowPtr pWin, GrabPtr pGrab)
+ );
+
void GEInitEvent(xGenericEvent* ev, int extension);
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 99518e125..70253fe82 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -1151,6 +1151,16 @@ XIGEEventSwap(xGenericEvent* from, xGenericEvent* to)
}
}
+/**
+ * EventFill to fill various fields for events before they are delivered to
+ * the client.
+ */
+static void
+XIGEEventFill(xGenericEvent* ev, DeviceIntPtr pDev,
+ WindowPtr pWin, GrabPtr grab)
+{
+}
+
/**********************************************************************
*
* IExtensionInit - initialize the input extension.
@@ -1195,7 +1205,7 @@ XInputExtensionInit(void)
EventSwapVector[DeviceLeaveNotify] = SEventIDispatch;
/* init GE events */
- GERegisterExtension(IReqCode, XIGEEventSwap);
+ GERegisterExtension(IReqCode, XIGEEventSwap, XIGEEventFill);
SetGenericFilter(IReqCode, xi_filters);
} else {
FatalError("IExtensionInit: AddExtensions failed\n");
diff --git a/dix/events.c b/dix/events.c
index 77d62754f..d4af30731 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2129,6 +2129,9 @@ FixUpEventFromWindow(
{
SpritePtr pSprite = pDev->spriteInfo->sprite;
+ if (xE->u.u.type == GenericEvent) /* just a safety barrier */
+ return;
+
if (calcChild)
{
WindowPtr w= pSprite->spriteTrace[pSprite->spriteTraceGood-1];
@@ -2245,6 +2248,8 @@ DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab,
{
if (GEMaskIsSet(pWin, GEEXT(xE), filter))
{
+ if (GEExtensions[GEEXTIDX(xE)].evfill)
+ GEExtensions[GEEXTIDX(xE)].evfill(ge, dev, pWin, grab);
deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
filter, grab, 0);
if (deliveries > 0)
@@ -3270,6 +3275,8 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
if (!gemask)
return;
+ if (GEEventFill(xE))
+ GEEventFill(xE)(ge, thisDev, grab->window, grab);
deliveries = TryClientEvents(rClient(grab), xE, count,
gemask->mask,
generic_filters[GEEXTIDX(ge)][ge->evtype],