From c1a16bdcfe7aa907fe78f27dc606a8e5a2699952 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 27 Jun 2007 18:08:03 +0930 Subject: [PATCH] Add 'evfill' field to GEExtensions. We need this to allow extensions to fill in extra data for an event before it is sent to the client. This is probably to be used like FillUpEventsFromWindow(). --- Xext/geext.c | 18 ++++++++---------- Xext/geext.h | 27 ++++++++++++++++++++++++++- Xi/extinit.c | 12 +++++++++++- dix/events.c | 7 +++++++ 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 +/* 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],