diff options
-rw-r--r-- | Xext/Makefile.am | 6 | ||||
-rw-r--r-- | Xext/geext.c | 384 | ||||
-rw-r--r-- | Xext/geext.h | 64 | ||||
-rw-r--r-- | Xext/geint.h | 60 | ||||
-rw-r--r-- | dix/events.c | 145 | ||||
-rw-r--r-- | dix/window.c | 17 | ||||
-rw-r--r-- | include/windowstr.h | 13 | ||||
-rw-r--r-- | mi/miinitext.c | 6 | ||||
-rw-r--r-- | os/utils.c | 2 |
9 files changed, 660 insertions, 37 deletions
diff --git a/Xext/Makefile.am b/Xext/Makefile.am index 6ea3d7445..29a01ee99 100644 --- a/Xext/Makefile.am +++ b/Xext/Makefile.am @@ -23,7 +23,8 @@ BUILTIN_SRCS = \ shape.c \ sleepuntil.c \ sleepuntil.h \ - xtest.c + xtest.c \ + geext.c # Sources always included in libXextmodule.la & libXext.la MODULE_SRCS = \ @@ -178,5 +179,6 @@ EXTRA_DIST = \ $(EXTRA_MULTIBUFFER_SRCS) \ $(FONTCACHE_SRCS) \ $(BIGFONT_SRCS) \ - $(DPMS_SRCS) + $(DPMS_SRCS) \ + $(GE_SRCS) diff --git a/Xext/geext.c b/Xext/geext.c new file mode 100644 index 000000000..7c4573e8c --- /dev/null +++ b/Xext/geext.c @@ -0,0 +1,384 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +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 AUTHOR 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 author 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 author. + +*/ + + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif +#include "windowstr.h" +#include <X11/extensions/ge.h> + +#include "geint.h" +#include "geext.h" + +int GEEventBase; +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]; + +/* Major available requests */ +static const int version_requests[] = { + X_GEQueryVersion, /* before client sends QueryVersion */ + X_GEQueryVersion, /* must be set to last request in version 1 */ +}; + +/* Forward declarations */ +static void SGEGenericEvent(xEvent* from, xEvent* to); + +#define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0])) + +/************************************************************/ +/* request handlers */ +/************************************************************/ + +static int ProcGEQueryVersion(ClientPtr client) +{ + int n; + GEClientInfoPtr pGEClient = GEGetClient(client); + xGEQueryVersionReply rep; + REQUEST(xGEQueryVersionReq); + + REQUEST_SIZE_MATCH(xGEQueryVersionReq); + + rep.repType = X_Reply; + rep.RepType = X_GEQueryVersion; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + if (stuff->majorVersion < GE_MAJOR) { + rep.majorVersion = stuff->majorVersion; + rep.minorVersion = stuff->minorVersion; + } else { + rep.majorVersion = GE_MAJOR; + if (stuff->majorVersion == GE_MAJOR && + stuff->minorVersion < GE_MINOR) + rep.minorVersion = stuff->minorVersion; + else + rep.minorVersion = GE_MINOR; + } + + pGEClient->major_version = rep.majorVersion; + pGEClient->minor_version = rep.minorVersion; + + if (client->swapped) + { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.majorVersion, n); + swaps(&rep.minorVersion, n); + } + + + WriteToClient(client, sizeof(xGEQueryVersionReply), (char*)&rep); + return(client->noClientException); +} + +int (*ProcGEVector[GENumberRequests])(ClientPtr) = { + /* Version 1.0 */ + ProcGEQueryVersion +}; + +/************************************************************/ +/* swapped request handlers */ +/************************************************************/ +static int +SProcGEQueryVersion(ClientPtr client) +{ + int n; + REQUEST(xGEQueryVersionReq); + + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xGEQueryVersionReq); + swaps(&stuff->majorVersion, n); + swaps(&stuff->minorVersion, n); + return(*ProcGEVector[stuff->ReqType])(client); +} + +int (*SProcGEVector[GENumberRequests])(ClientPtr) = { + /* Version 1.0 */ + SProcGEQueryVersion +}; + + +/************************************************************/ +/* callbacks */ +/************************************************************/ + +/* dispatch requests */ +static int +ProcGEDispatch(ClientPtr client) +{ + GEClientInfoPtr pGEClient = GEGetClient(client); + REQUEST(xGEReq); + + if (pGEClient->major_version >= NUM_VERSION_REQUESTS) + return BadRequest; + if (stuff->ReqType > version_requests[pGEClient->major_version]) + return BadRequest; + + return (ProcGEVector[stuff->ReqType])(client); +} + +/* dispatch swapped requests */ +static int +SProcGEDispatch(ClientPtr client) +{ + REQUEST(xGEReq); + if (stuff->ReqType >= GENumberRequests) + return BadRequest; + return (*SProcGEVector[stuff->ReqType])(client); +} + +/* new client callback */ +static void GEClientCallback(CallbackListPtr *list, + pointer closure, + pointer data) +{ + NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; + ClientPtr pClient = clientinfo->client; + GEClientInfoPtr pGEClient = GEGetClient(pClient); + + pGEClient->major_version = 0; + pGEClient->minor_version = 0; +} + +/* reset extension */ +static void +GEResetProc(ExtensionEntry *extEntry) +{ + DeleteCallback(&ClientStateCallback, GEClientCallback, 0); + EventSwapVector[GenericEvent] = NotImplemented; + + GEEventBase = 0; + GEErrorBase = 0; + GEEventType = 0; +} + +/* Calls the registered event swap function for the extension. */ +static void +SGEGenericEvent(xEvent* from, xEvent* to) +{ + xGenericEvent* gefrom = (xGenericEvent*)from; + xGenericEvent* geto = (xGenericEvent*)to; + + if (gefrom->extension > MAXEXTENSIONS) + { + ErrorF("GE: Invalid extension offset for event.\n"); + return; + } + + if (GEExtensions[gefrom->extension & 0x7F].evswap) + GEExtensions[gefrom->extension & 0x7F].evswap(gefrom, geto); +} + +/* init extension, register at server */ +void +GEExtensionInit(void) +{ + ExtensionEntry *extEntry; + + GEClientPrivateIndex = AllocateClientPrivateIndex(); + if (!AllocateClientPrivate(GEClientPrivateIndex, + sizeof(GEClientRec))) + { + FatalError("GEExtensionInit: Alloc client private failed.\n"); + } + + if(!AddCallback(&ClientStateCallback, GEClientCallback, 0)) + { + FatalError("GEExtensionInit: register client callback failed.\n"); + } + + if((extEntry = AddExtension(GE_NAME, + GENumberEvents, GENumberErrors, + ProcGEDispatch, SProcGEDispatch, + GEResetProc, StandardMinorOpcode)) != 0) + { + GEEventBase = extEntry->eventBase; + GEErrorBase = extEntry->errorBase; + GEEventType = GEEventBase; + + memset(GEExtensions, 0, sizeof(GEExtensions)); + + EventSwapVector[GEEventBase + X_GenericEvent] = + (EventSwapPtr) SGEGenericEvent; + } else { + FatalError("GEInit: AddExtensions failed.\n"); + } + +} + +/************************************************************/ +/* interface for extensions */ +/************************************************************/ + +/* Register extension with GE. + * Requires the event swap function as parameter. The function will be called + * each time an event is sent to a client with different byte order. + * Returns extension offset. This offset is to be used in all generic events + * sent to the client. + */ +void GERegisterExtension( + int extension, + void (*ev_swap)(xGenericEvent* from, xGenericEvent* to) + ) +{ + if ((extension & 0x7F) >= MAXEXTENSIONS) + FatalError("GE: extension > MAXEXTENSIONS. This should not happen.\n"); + + /* extension opcodes are > 128, might as well save some space here */ + GEExtensions[extension & 0x7f].evswap = ev_swap; +} + + +/* Sets type and extension field for a generic event. This is just an + * auxiliary function, extensions could do it manually too. */ +void GEInitEvent(xGenericEvent* ev, int extension) +{ + ev->type = GenericEvent; + ev->extension = extension; + ev->length = 0; +} + +/* Recalculates the summary mask for the window. */ +static void +GERecalculateWinMask(WindowPtr pWin) +{ + int i; + GEClientPtr it; + GEEventMasksPtr evmasks; + + if (!pWin->optional) + return; + + evmasks = pWin->optional->geMasks; + + for (i = 0; i < MAXEXTENSIONS; i++) + { + evmasks->eventMasks[i] = 0; + } + + it = pWin->optional->geMasks->geClients; + while(it) + { + for (i = 0; i < MAXEXTENSIONS; i++) + { + evmasks->eventMasks[i] |= it->eventMask[i]; + } + it = it->next; + } +} + +/* Set generic event mask for given window. */ +void GEWindowSetMask(ClientPtr pClient, WindowPtr pWin, int extension, Mask mask) +{ + GEClientPtr cli; + + extension = (extension & 0x7F); + + if (extension > MAXEXTENSIONS) + { + ErrorF("Invalid extension number.\n"); + return; + } + + if (!pWin->optional && !MakeWindowOptional(pWin)) + { + ErrorF("GE: Could not make window optional.\n"); + return; + } + + if (mask) + { + GEEventMasksPtr evmasks = pWin->optional->geMasks; + + /* check for existing client */ + cli = evmasks->geClients; + while(cli) + { + if (cli->client == pClient) + break; + cli = cli->next; + } + if (!cli) + { + /* new client */ + cli = (GEClientPtr)xcalloc(1, sizeof(GEClientRec)); + if (!cli) + { + ErrorF("GE: Insufficient memory to alloc client.\n"); + return; + } + cli->next = evmasks->geClients; + cli->client = pClient; + evmasks->geClients = cli; + } + cli->eventMask[extension] = mask; + } else + { + /* remove client. */ + cli = pWin->optional->geMasks->geClients; + if (cli->client == pClient) + { + pWin->optional->geMasks->geClients = cli->next; + xfree(cli); + } else + { + GEClientPtr prev = cli; + cli = cli->next; + + while(cli) + { + if (cli->client == pClient) + { + prev->next = cli->next; + xfree(cli); + break; + } + prev = cli; + cli = cli->next; + } + } + if (!cli) + return; + } + + GERecalculateWinMask(pWin); +} + + diff --git a/Xext/geext.h b/Xext/geext.h new file mode 100644 index 000000000..53aa21c8b --- /dev/null +++ b/Xext/geext.h @@ -0,0 +1,64 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +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 AUTHOR 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 author 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 author. + +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _GEEXT_H_ +#define _GEEXT_H_ +#include <X11/extensions/geproto.h> + +/* Returns the extension offset from the event */ +#define GEEXT(ev) (((xGenericEvent*)(ev))->extension) + +#define GEEXTIDX(ev) (GEEXT(ev) & 0x7F) +/* Typecast to generic event */ +#define GEV(ev) ((xGenericEvent*)(ev)) +/* True if mask is set for extension on window */ +#define GEMaskIsSet(pWin, extension, mask) \ + ((pWin)->optional && \ + (pWin)->optional->geMasks && \ + ((pWin)->optional->geMasks->eventMasks[(extension) & 0x7F] & (mask))) + +/* Returns first client */ +#define GECLIENT(pWin) \ + (((pWin)->optional) ? (pWin)->optional->geMasks->geClients : NULL) + +/* Interface for other extensions */ +Mask GENextMask(int extension); +void GEWindowSetMask(ClientPtr pClient, WindowPtr pWin, int extension, Mask mask); +void GERegisterExtension( + int extension, + void (*ev_dispatch)(xGenericEvent* from, xGenericEvent* to)); +void GEInitEvent(xGenericEvent* ev, int extension); + + +void GEExtensionInit(void); + +#endif /* _GEEXT_H_ */ diff --git a/Xext/geint.h b/Xext/geint.h new file mode 100644 index 000000000..9e131d3b3 --- /dev/null +++ b/Xext/geint.h @@ -0,0 +1,60 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +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 AUTHOR 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 author 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 author. + +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _GEINT_H_ +#define _GEINT_H_ + +#define NEED_EVENTS +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "os.h" +#include "dixstruct.h" +#include "extnsionst.h" +#include <X11/extensions/geproto.h> + +extern int GEEventType; +extern int GEEventBase; +extern int GEErrorBase; +extern int GEClientPrivateIndex; + +typedef struct _GEClientInfo { + CARD32 major_version; + CARD32 minor_version; +} GEClientInfoRec, *GEClientInfoPtr; + +#define GEGetClient(pClient) ((GEClientInfoPtr) (pClient)->devPrivates[GEClientPrivateIndex].ptr) + +extern int (*ProcGEVector[/*GENumRequests*/])(ClientPtr); +extern int (*SProcGEVector[/*GENumRequests*/])(ClientPtr); + +#endif /* _GEINT_H_ */ diff --git a/dix/events.c b/dix/events.c index deb2da104..836d755f6 100644 --- a/dix/events.c +++ b/dix/events.c @@ -178,6 +178,11 @@ static xEvent *xeviexE; #include "dixevents.h" #include "dixgrabs.h" #include "dispatch.h" + +#include <X11/extensions/ge.h> +#include "geext.h" +#include "geint.h" + /** * Extension events type numbering starts at EXTENSION_EVENT_BASE. */ @@ -260,6 +265,9 @@ static struct { #define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0] +static xEvent* swapEvent = NULL; +static int swapEventLen = 0; + /** * True if device owns a cursor, false if device shares a cursor sprite with * another device. @@ -1850,7 +1858,8 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent return 0; /* CantBeFiltered means only window owner gets the event */ - if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE)) + if ((filter == CantBeFiltered) || + (!(type & EXTENSION_EVENT_BASE) && type != GenericEvent)) { /* if nobody ever wants to see this event, skip some work */ if (filter != CantBeFiltered && @@ -1875,37 +1884,70 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent } if (filter != CantBeFiltered) { - if (type & EXTENSION_EVENT_BASE) - { - OtherInputMasks *inputMasks; + /* Handle generic events */ + if (type == GenericEvent) + { + GEClientPtr pClient; + /* FIXME: We don't do more than one GenericEvent at a time yet. */ + if (count > 1) + { + ErrorF("Do not send more than one GenericEvent at a time!\n"); + return 0; + } - inputMasks = wOtherInputMasks(pWin); - if (!inputMasks || - !(inputMasks->inputEvents[mskidx] & filter)) - return 0; - other = inputMasks->inputClients; - } - else - other = (InputClients *)wOtherClients(pWin); - for (; other; other = other->next) - { - /* core event? check for grab interference */ - if (!(type & EXTENSION_EVENT_BASE) && - IsInterferingGrab(rClient(other), pWin, pDev, pEvents)) - continue; + /* if we get here, filter should be set to the GE specific mask. + check if any client wants it */ + if (!GEMaskIsSet(pWin, GEEXT(pEvents), filter)) + return 0; - if ( (attempt = TryClientEvents(rClient(other), pEvents, count, - other->mask[mskidx], filter, grab)) ) - { - if (attempt > 0) - { - deliveries++; - client = rClient(other); - deliveryMask = other->mask[mskidx]; - } else - nondeliveries--; - } - } + /* run through all clients, deliver event */ + for (pClient = GECLIENT(pWin); pClient; pClient = pClient->next) + { + if (pClient->eventMask[GEEXTIDX(pEvents)] & filter) + { + if (TryClientEvents(pClient->client, pEvents, count, + pClient->eventMask[GEEXTIDX(pEvents)], filter, grab) > 0) + { + deliveries++; + } else + nondeliveries--; + } + } + } + else { + /* Traditional event */ + if (type & EXTENSION_EVENT_BASE) + { + OtherInputMasks *inputMasks; + + inputMasks = wOtherInputMasks(pWin); + if (!inputMasks || + !(inputMasks->inputEvents[mskidx] & filter)) + return 0; + other = inputMasks->inputClients; + } + else + other = (InputClients *)wOtherClients(pWin); + for (; other; other = other->next) + { + /* core event? check for grab interference */ + if (!(type & EXTENSION_EVENT_BASE) && + IsInterferingGrab(rClient(other), pWin, pDev, pEvents)) + continue; + + if ( (attempt = TryClientEvents(rClient(other), pEvents, count, + other->mask[mskidx], filter, grab)) ) + { + if (attempt > 0) + { + deliveries++; + client = rClient(other); + deliveryMask = other->mask[mskidx]; + } else + nondeliveries--; + } + } + } } if ((type == ButtonPress) && deliveries && (!grab)) { @@ -5378,8 +5420,9 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) #ifdef PANORAMIX xEvent eventCopy; #endif - xEvent eventTo, *eventFrom; - int i; + xEvent *eventTo, *eventFrom; + int i, + eventlength = sizeof(xEvent); #ifdef XKB if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events))) @@ -5436,21 +5479,53 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) } } #endif + /* Just a safety check to make sure we only have one GenericEvent, it just + * makes things easier for me right now. (whot) */ + for (i = 1; i < count; i++) + { + if (events[i].u.u.type == GenericEvent) + { + ErrorF("TryClientEvents: Only one GenericEvent at a time."); + return; + } + } + + if (events->u.u.type == GenericEvent) + { + eventlength += ((xGenericEvent*)events)->length * 4; + if (eventlength > swapEventLen) + { + swapEventLen = eventlength; + swapEvent = Xrealloc(swapEvent, swapEventLen); + if (!swapEvent) + { + FatalError("WriteEventsToClient: Out of memory.\n"); + return; + } + } + } + if(pClient->swapped) { for(i = 0; i < count; i++) { eventFrom = &events[i]; + eventTo = swapEvent; + /* Remember to strip off the leading bit of type in case this event was sent with "SendEvent." */ (*EventSwapVector[eventFrom->u.u.type & 0177]) - (eventFrom, &eventTo); - (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo); + (eventFrom, eventTo); + + (void)WriteToClient(pClient, eventlength, (char *)&eventTo); } } else { - (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events); + /* only one GenericEvent, remember? that means either count is 1 and + * eventlength is arbitrary or eventlength is 32 and count doesn't + * matter. And we're all set. Woohoo. */ + (void)WriteToClient(pClient, count * eventlength, (char *) events); } } diff --git a/dix/window.c b/dix/window.c index 484693906..b49abdfe5 100644 --- a/dix/window.c +++ b/dix/window.c @@ -455,6 +455,7 @@ CreateRootWindow(ScreenPtr pScreen) #ifdef XINPUT pWin->optional->inputMasks = NULL; pWin->optional->deviceCursors = NULL; + pWin->optional->geMasks = NULL; #endif pWin->optional->access.perm = NULL; @@ -3700,6 +3701,9 @@ CheckWindowOptionalNeed (WindowPtr w) optional->access.ndeny != 0) return; + if (optional->geMasks != NULL) + return; + parentOptional = FindWindowWithOptional(w)->optional; if (optional->visual != parentOptional->visual) return; @@ -3746,6 +3750,19 @@ MakeWindowOptional (WindowPtr pWin) optional->inputMasks = NULL; #endif optional->deviceCursors = NULL; + + optional->geMasks = (GEEventMasksPtr)xalloc(sizeof(GEEventMasksRec)); + if (!optional->geMasks) + { + xfree(optional); + return FALSE; + } else { + int i; + optional->geMasks->geClients = 0; + for (i = 0; i < MAXEXTENSIONS; i++) + optional->geMasks->eventMasks[i] = 0; + } + optional->access.nperm = 0; optional->access.ndeny = 0; optional->access.perm = NULL; diff --git a/include/windowstr.h b/include/windowstr.h index 87158b263..a1d501d37 100644 --- a/include/windowstr.h +++ b/include/windowstr.h @@ -77,6 +77,18 @@ typedef struct _DevCursorNode { struct _DevCursorNode* next; } DevCursNodeRec, *DevCursNodePtr, *DevCursorList; +typedef struct _GEClientRec { + Mask eventMask[MAXEXTENSIONS]; + ClientPtr client; + struct _GEClientRec* next; +} GEClientRec, *GEClientPtr; + +/* Mask structure for GE extension. Allows one mask per extension. */ +typedef struct _GEEventMasks { + Mask eventMasks[MAXEXTENSIONS]; + struct _GEClientRec* geClients; +} GEEventMasksRec, *GEEventMasksPtr; + typedef struct _WindowAccessRec { int defaultRule; /* WindowAccessDenyAll */ DeviceIntPtr* perm; @@ -105,6 +117,7 @@ typedef struct _WindowOpt { struct _OtherInputMasks *inputMasks; /* default: NULL */ #endif DevCursorList deviceCursors; /* default: NULL */ + struct _GEEventMasks* geMasks; /* default: NULL */ WindowAccessRec access; } WindowOptRec, *WindowOptPtr; diff --git a/mi/miinitext.c b/mi/miinitext.c index 0fc6d1521..cad978d3b 100644 --- a/mi/miinitext.c +++ b/mi/miinitext.c @@ -215,6 +215,7 @@ extern Bool noXIdleExtension; #ifdef XV extern Bool noXvExtension; #endif +extern Bool noGEExtension; #ifndef XFree86LOADER #define INITARGS void @@ -386,6 +387,7 @@ extern void DamageExtensionInit(INITARGS); #ifdef COMPOSITE extern void CompositeExtensionInit(INITARGS); #endif +extern void GEExtensionInit(INITARGS); /* The following is only a small first step towards run-time * configurable extensions. @@ -398,6 +400,7 @@ typedef struct { static ExtensionToggle ExtensionToggleList[] = { /* sort order is extension name string as shown in xdpyinfo */ + { "Generic Events", &noGEExtension }, #ifdef BIGREQS { "BIG-REQUESTS", &noBigReqExtension }, #endif @@ -531,6 +534,8 @@ InitExtensions(argc, argv) int argc; char *argv[]; { + if (!noGEExtension) GEExtensionInit(); + #ifdef XCSECURITY SecurityExtensionSetup(); #endif @@ -684,6 +689,7 @@ InitVisualWrap() #else /* XFree86LOADER */ /* List of built-in (statically linked) extensions */ static ExtensionModule staticExtensions[] = { + { GEExtensionInit, "Generic Event Extension", &noGEExtension, NULL, NULL}, #ifdef MITSHM { ShmExtensionInit, SHMNAME, &noMITShmExtension, NULL, NULL }, #endif diff --git a/os/utils.c b/os/utils.c index 5058285e8..e45edd17f 100644 --- a/os/utils.c +++ b/os/utils.c @@ -236,6 +236,8 @@ _X_EXPORT Bool noXIdleExtension = FALSE; _X_EXPORT Bool noXvExtension = FALSE; #endif +_X_EXPORT Bool noGEExtension = FALSE; + #define X_INCLUDE_NETDB_H #include <X11/Xos_r.h> |