diff options
-rw-r--r-- | Xi/Makefile.am | 2 | ||||
-rw-r--r-- | Xi/extgrbdev.c | 238 | ||||
-rw-r--r-- | Xi/extgrbdev.h | 46 | ||||
-rw-r--r-- | Xi/extinit.c | 7 | ||||
-rw-r--r-- | Xi/grabdev.c | 7 | ||||
-rw-r--r-- | dix/devices.c | 2 | ||||
-rw-r--r-- | dix/events.c | 223 | ||||
-rw-r--r-- | include/dix.h | 17 | ||||
-rw-r--r-- | include/inputstr.h | 17 | ||||
-rw-r--r-- | include/misc.h | 1 |
10 files changed, 539 insertions, 21 deletions
diff --git a/Xi/Makefile.am b/Xi/Makefile.am index d020210df..2cf11a042 100644 --- a/Xi/Makefile.am +++ b/Xi/Makefile.am @@ -29,6 +29,8 @@ libXi_la_SOURCES = \ devbell.h \ exevents.c \ exglobals.h \ + extgrbdev.c \ + extgrbdev.h \ extinit.c \ fakedevdata.c \ fakedevdata.h \ diff --git a/Xi/extgrbdev.c b/Xi/extgrbdev.c new file mode 100644 index 000000000..0f0fd30f0 --- /dev/null +++ b/Xi/extgrbdev.c @@ -0,0 +1,238 @@ +/* + +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. + +*/ + +/*********************************************************************** + * + * Request to fake data for a given device. + * + */ + +#define NEED_EVENTS +#define NEED_REPLIES +#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 "windowstr.h" /* window structure */ +#include "scrnintstr.h" /* screen structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "gestr.h" +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#include "exevents.h" +#include "exglobals.h" + +#include "extgrbdev.h" + +int +SProcXExtendedGrabDevice(ClientPtr client) +{ + char n; + int i; + long* p; + + REQUEST(xExtendedGrabDeviceReq); + swaps(&stuff->length, n); + REQUEST_AT_LEAST_SIZE(xExtendedGrabDeviceReq); + + swapl(&stuff->grab_window, n); + swapl(&stuff->time, n); + swapl(&stuff->confine_to, n); + swapl(&stuff->cursor, n); + swaps(&stuff->event_mask, n); + swaps(&stuff->event_count, n); + swaps(&stuff->ge_event_count, n); + + p = (long *)&stuff[1]; + for (i = 0; i < stuff->event_count; i++) { + swapl(p, n); + p++; + } + + for (i = 0; i < stuff->ge_event_count; i++) { + p++; /* first 4 bytes are extension type and padding */ + swapl(p, n); + p++; + } + + return ProcXExtendedGrabDevice(client); +} + + +int +ProcXExtendedGrabDevice(ClientPtr client) +{ + xExtendedGrabDeviceReply rep; + DeviceIntPtr dev; + int err, + errval = 0, + i; + WindowPtr grab_window, + confineTo = 0; + CursorPtr cursor = NULL; + struct tmask tmp[EMASKSIZE]; + TimeStamp time; + XgeEventMask* xgeMask; + GenericMaskPtr gemasks = NULL; + + REQUEST(xExtendedGrabDeviceReq); + REQUEST_AT_LEAST_SIZE(xExtendedGrabDeviceReq); + + if (stuff->length != (sizeof(xExtendedGrabDeviceReq) >> 2) + + stuff->event_count + 2 * stuff->ge_event_count) + { + errval = 0; + err = BadLength; + goto cleanup; + } + + dev = LookupDeviceIntRec(stuff->deviceid); + if (dev == NULL) { + errval = stuff->deviceid; + err = BadDevice; + goto cleanup; + } + + err = dixLookupWindow(&grab_window, + stuff->grab_window, + client, + DixReadAccess); + if (err != Success) + { + errval = stuff->grab_window; + goto cleanup; + } + + if (stuff->confine_to) + { + err = dixLookupWindow(&confineTo, + stuff->confine_to, + client, + DixReadAccess); + if (err != Success) + { + errval = stuff->confine_to; + goto cleanup; + } + } + + if (stuff->cursor) + { + cursor = (CursorPtr)SecurityLookupIDByType(client, + stuff->cursor, + RT_CURSOR, + DixReadAccess); + if (!cursor) + { + errval = stuff->cursor; + err = BadCursor; + goto cleanup; + } + } + + rep.repType = X_Reply; + rep.RepType = X_ExtendedGrabDevice; + rep.sequenceNumber = client->sequence; + rep.length = 0; + + if (CreateMaskFromList(client, + (XEventClass*)&stuff[1], + stuff->event_count, + tmp, + dev, + X_GrabDevice) != Success) + return Success; + + time = ClientTimeToServerTime(stuff->time); + + if (stuff->ge_event_count) + { + xgeMask = + (XgeEventMask*)(((XEventClass*)&stuff[1]) + stuff->event_count); + + gemasks = xcalloc(1, sizeof(GenericMaskRec)); + gemasks->extension = xgeMask->extension; + gemasks->mask = xgeMask->evmask; + gemasks->next = NULL; + xgeMask++; + + for (i = 1; i < stuff->ge_event_count; i++, xgeMask++) + { + gemasks->next = xcalloc(1, sizeof(GenericMaskRec)); + gemasks = gemasks->next; + gemasks->extension = xgeMask->extension; + gemasks->mask = xgeMask->evmask; + gemasks->next = NULL; + } + } + + ExtGrabDevice(client, dev, stuff->grabmode, stuff->device_mode, + grab_window, confineTo, time, stuff->owner_events, + cursor, stuff->event_mask, tmp[stuff->deviceid].mask, + gemasks); + + if (err != Success) { + errval = 0; + goto cleanup; + } + +cleanup: + + while(gemasks) + { + GenericMaskPtr prev = gemasks; + gemasks = gemasks->next; + xfree(prev); + } + + if (err == Success) + { + WriteReplyToClient(client, sizeof(xGrabDeviceReply), &rep); + } + else + { + SendErrorToClient(client, IReqCode, + X_ExtendedGrabDevice, + errval, err); + } + return Success; +} + +void +SRepXExtendedGrabDevice(ClientPtr client, int size, + xExtendedGrabDeviceReply* rep) +{ + char n; + swaps(&rep->sequenceNumber, n); + swaps(&rep->length, n); + WriteToClient(client, size, (char*)rep); +} diff --git a/Xi/extgrbdev.h b/Xi/extgrbdev.h new file mode 100644 index 000000000..93075b177 --- /dev/null +++ b/Xi/extgrbdev.h @@ -0,0 +1,46 @@ +/* + +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 EXTGRBDEV_H +#define EXTGRBDEV_H 1 + +int SProcXExtendedGrabDevice(ClientPtr /* client */ + ); + +int ProcXExtendedGrabDevice(ClientPtr /* client */ + ); + +void SRepXExtendedGrabDevice(ClientPtr client, + int size, + xExtendedGrabDeviceReply* rep); + +#endif /* EXTGRBDEV_H */ diff --git a/Xi/extinit.c b/Xi/extinit.c index bfb2bc78b..088873062 100644 --- a/Xi/extinit.c +++ b/Xi/extinit.c @@ -85,6 +85,7 @@ SOFTWARE. #include "chgptr.h" #include "chpkpair.h" #include "closedev.h" +#include "extgrbdev.h" #include "devbell.h" #include "fakedevdata.h" #include "getbmap.h" @@ -346,6 +347,8 @@ ProcIDispatch(ClientPtr client) return ProcXGetPairedPointer(client); else if (stuff->data == X_FakeDeviceData) return ProcXFakeDeviceData(client); + else if (stuff->data == X_ExtendedGrabDevice) + return ProcXExtendedGrabDevice(client); else { SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest); } @@ -461,6 +464,8 @@ SProcIDispatch(ClientPtr client) return SProcXGetPairedPointer(client); else if (stuff->data == X_FakeDeviceData) return SProcXFakeDeviceData(client); + else if (stuff->data == X_ExtendedGrabDevice) + return SProcXExtendedGrabDevice(client); else { SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest); } @@ -549,6 +554,8 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep) SRepXGetClientPointer(client, len, (xGetClientPointerReply*) rep); else if (rep->RepType == X_GetPairedPointer) SRepXGetPairedPointer(client, len, (xGetPairedPointerReply*) rep); + else if (rep->RepType == X_ExtendedGrabDevice) + SRepXExtendedGrabDevice(client, len, (xExtendedGrabDeviceReply*) rep); else { FatalError("XINPUT confused sending swapped reply"); } diff --git a/Xi/grabdev.c b/Xi/grabdev.c index 143b98c73..f3349ba8c 100644 --- a/Xi/grabdev.c +++ b/Xi/grabdev.c @@ -155,6 +155,13 @@ ProcXGrabDevice(ClientPtr client) * * This procedure creates an event mask from a list of XEventClasses. * + * Procedure is as follows: + * An XEventClass is (deviceid << 8 | eventtype). For each entry in the list, + * get the device. Then run through all available event indices (those are + * set when XI starts up) and binary OR's the device's mask to whatever the + * event mask for the given event type was. + * + * mask has to be size EMASKSIZE and pre-allocated. */ int diff --git a/dix/devices.c b/dix/devices.c index bd145a085..d66364909 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -653,7 +653,7 @@ CloseDevice(DeviceIntPtr dev) /* a client may have the device set as client pointer */ for (j = 0; j < currentMaxClients; j++) { - if (clients[j]->clientPtr == dev) + if (clients[j] && clients[j]->clientPtr == dev) { clients[j]->clientPtr = NULL; clients[j]->clientPtr = PickPointer(clients[j]); diff --git a/dix/events.c b/dix/events.c index c8b0eb235..415db6e3e 100644 --- a/dix/events.c +++ b/dix/events.c @@ -170,6 +170,7 @@ static xEvent *xeviexE; #endif #include <X11/extensions/XIproto.h> +#include <X11/extensions/XI.h> #include "exglobals.h" #include "exevents.h" #include "exglobals.h" @@ -1401,8 +1402,10 @@ void ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab, TimeStamp time, Bool autoGrab) { - WindowPtr oldWin = (mouse->coreGrab.grab) ? - mouse->coreGrab.grab->window + GrabInfoPtr grabinfo = + (grab->coreGrab) ? &mouse->coreGrab : &mouse->deviceGrab; + WindowPtr oldWin = (grabinfo->grab) ? + grabinfo->grab->window : mouse->spriteInfo->sprite->win; if (grab->confineTo) @@ -1416,14 +1419,14 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab, DoEnterLeaveEvents(mouse, oldWin, grab->window, NotifyGrab); mouse->valuator->motionHintWindow = NullWindow; if (syncEvents.playingEvents) - mouse->coreGrab.grabTime = syncEvents.time; + grabinfo->grabTime = syncEvents.time; else - mouse->coreGrab.grabTime = time; + grabinfo->grabTime = time; if (grab->cursor) grab->cursor->refcnt++; - mouse->coreGrab.activeGrab = *grab; - mouse->coreGrab.grab = &mouse->coreGrab.activeGrab; - mouse->coreGrab.fromPassiveGrab = autoGrab; + grabinfo->activeGrab = *grab; + grabinfo->grab = &grabinfo->activeGrab; + grabinfo->fromPassiveGrab = autoGrab; PostNewCursor(mouse); CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode); } @@ -1467,10 +1470,12 @@ DeactivatePointerGrab(DeviceIntPtr mouse) void ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive) { + GrabInfoPtr grabinfo = + (grab->coreGrab) ? &keybd->coreGrab : &keybd->deviceGrab; WindowPtr oldWin; - if (keybd->coreGrab.grab) - oldWin = keybd->coreGrab.grab->window; + if (grabinfo->grab) + oldWin = grabinfo->grab->window; else if (keybd->focus) oldWin = keybd->focus->win; else @@ -1481,12 +1486,12 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool pass keybd->valuator->motionHintWindow = NullWindow; DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab); if (syncEvents.playingEvents) - keybd->coreGrab.grabTime = syncEvents.time; + grabinfo->grabTime = syncEvents.time; else - keybd->coreGrab.grabTime = time; - keybd->coreGrab.activeGrab = *grab; - keybd->coreGrab.grab = &keybd->coreGrab.activeGrab; - keybd->coreGrab.fromPassiveGrab = passive; + grabinfo->grabTime = time; + grabinfo->activeGrab = *grab; + grabinfo->grab = &grabinfo->activeGrab; + grabinfo->fromPassiveGrab = passive; CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode); } @@ -1501,6 +1506,9 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd) WindowPtr focusWin = keybd->focus ? keybd->focus->win : keybd->spriteInfo->sprite->win; + if (!grab) + grab = keybd->deviceGrab.grab; + if (focusWin == FollowKeyboardWin) focusWin = inputInfo.keyboard->focus->win; if (keybd->valuator) @@ -3154,7 +3162,7 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev, xEvent *dxE; SpritePtr pSprite = thisDev->spriteInfo->sprite; - if (xE->u.u.type & EXTENSION_EVENT_BASE) + if (xE->u.u.type & EXTENSION_EVENT_BASE || xE->u.u.type == GenericEvent) grabinfo = &thisDev->deviceGrab; else grabinfo = &thisDev->coreGrab; @@ -3188,11 +3196,32 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev, { if (ACDeviceAllowed(grab->window, thisDev)) { + if (xE->u.u.type == GenericEvent) + { + /* find evmask for event's extension */ + xGenericEvent* ge = ((xGenericEvent*)xE); + GenericMaskPtr gemask = grab->genericMasks; + while(gemask) + { + if (gemask->extension == ge->extension) + break; + gemask = gemask->next; + } + + if (!gemask) + return; - FixUpEventFromWindow(thisDev, xE, grab->window, None, TRUE); - deliveries = TryClientEvents(rClient(grab), xE, count, - (Mask)grab->eventMask, - filters[xE->u.u.type], grab); + deliveries = TryClientEvents(rClient(grab), xE, count, + gemask->mask, + generic_filters[GEEXTIDX(ge)][ge->evtype], + grab); + } else + { + FixUpEventFromWindow(thisDev, xE, grab->window, None, TRUE); + deliveries = TryClientEvents(rClient(grab), xE, count, + (Mask)grab->eventMask, + filters[xE->u.u.type], grab); + } if (deliveries && (xE->u.u.type == MotionNotify #ifdef XINPUT || xE->u.u.type == DeviceMotionNotify @@ -4726,6 +4755,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev, tempGrab.eventMask = mask; tempGrab.device = dev; tempGrab.cursor = NULL; + tempGrab.coreGrab = coreGrab; (*grabInfo->ActivateGrab)(dev, &tempGrab, time, FALSE); *status = GrabSuccess; @@ -5709,3 +5739,158 @@ SetGenericFilter(int extension, Mask* filters) { generic_filters[extension & 0x7f] = filters; } + + +/** + * Grab a device properly. + * + * grabmode decides if the grab should be for core events and/or XI device + * events. The latter also applies to generic events. + * grabmode is also used to ungrab a device. + * + * + */ +_X_EXPORT int +ExtGrabDevice(ClientPtr client, + DeviceIntPtr dev, + int grabmode, + int device_mode, + WindowPtr grabWindow, + WindowPtr confineTo, + TimeStamp ctime, + Bool ownerEvents, + CursorPtr cursor, + Mask core_mask, + Mask xi_mask, + GenericMaskPtr ge_masks) +{ + GrabInfoPtr grabinfo; + GrabRec newGrab; + + UpdateCurrentTime(); + if (grabmode & CoreOnlyGrab) + { + CursorPtr oldCursor = NullCursor; + + grabinfo = &dev->coreGrab; + + if (grabinfo->grab && !SameClient(grabinfo->grab, client)) + return AlreadyGrabbed; + + if ((!grabWindow->realized) || + (confineTo && !(confineTo->realized && + BorderSizeNotEmpty(dev, confineTo)))) + return GrabNotViewable; + + if (grabinfo->sync.frozen && grabinfo->sync.other && + !SameClient(grabinfo->sync.other, client)) + return GrabFrozen; + + if ((CompareTimeStamps(ctime, currentTime) == LATER) || + (CompareTimeStamps(ctime, grabinfo->grabTime) == EARLIER)) + return GrabInvalidTime; + + if (grabinfo->grab) + { + if (grabinfo->grab->confineTo) + ConfineCursorToWindow(dev, RootWindow(dev), FALSE, FALSE); + oldCursor = dev->coreGrab.grab->cursor; + } + + memset(&newGrab, 0, sizeof(GrabRec)); + newGrab.cursor = cursor; + newGrab.resource = client->clientAsMask; + newGrab.ownerEvents = ownerEvents; + newGrab.confineTo = confineTo; + newGrab.window = grabWindow; + newGrab.coreGrab = True; + newGrab.device = dev; + newGrab.eventMask = core_mask; + if (IsPointerDevice(dev)) + { + newGrab.keyboardMode = GrabModeAsync; + newGrab.pointerMode = device_mode; + } else + { + newGrab.keyboardMode = device_mode; + newGrab.pointerMode = GrabModeAsync; + } + + (*grabinfo->ActivateGrab)(dev, &newGrab, ctime, FALSE); + + if (oldCursor) + FreeCursor(oldCursor, 0); + } + + if (grabmode & DeviceOnlyGrab) + { + grabinfo = &dev->deviceGrab; + + if (grabinfo->grab && !SameClient(grabinfo->grab, client)) + return AlreadyGrabbed; + + if (!grabWindow->realized) + return GrabNotViewable; + + if ((CompareTimeStamps(ctime, currentTime) == LATER) || + (CompareTimeStamps(ctime, grabinfo->grabTime) == EARLIER)) + return GrabInvalidTime; + + if (grabinfo->sync.frozen && grabinfo->sync.other && + !SameClient(grabinfo->sync.other, client)) + return GrabFrozen; + + memset(&newGrab, 0, sizeof(GrabRec)); + newGrab.window = grabWindow; + newGrab.resource = client->clientAsMask; + newGrab.ownerEvents = ownerEvents; + newGrab.device = dev; + newGrab.cursor = cursor; + newGrab.confineTo = confineTo; + newGrab.eventMask = xi_mask; + newGrab.genericMasks = NULL; + + if (ge_masks) + { + GenericMaskPtr last; + newGrab.genericMasks = xcalloc(1, sizeof(GenericMaskRec)); + *newGrab.genericMasks = *ge_masks; + newGrab.genericMasks->next = NULL; + ge_masks = ge_masks->next; + last = newGrab.genericMasks; + + while(ge_masks) + { + last->next = xcalloc(1, sizeof(GenericMaskRec)); + last = last->next; + *last = *ge_masks; + ge_masks = ge_masks->next; + } + } + + if (IsPointerDevice(dev)) + { + newGrab.keyboardMode = GrabModeAsync; + newGrab.pointerMode = device_mode; + } else + { + newGrab.keyboardMode = device_mode; + newGrab.pointerMode = GrabModeAsync; + } + + (*grabinfo->ActivateGrab)(dev, &newGrab, ctime, FALSE); + } + + if (grabmode & UngrabAll) + { + if (grabmode & UngrabCoreOnly) + grabinfo = &dev->coreGrab; + else + grabinfo = &dev->deviceGrab; + if (grabinfo->grab && SameClient(grabinfo->grab, client)) + (*grabinfo->DeactivateGrab)(dev); + } + + return GrabSuccess; +} + diff --git a/include/dix.h b/include/dix.h index 1828f43f6..60a68eea9 100644 --- a/include/dix.h +++ b/include/dix.h @@ -51,6 +51,8 @@ SOFTWARE. #include "gc.h" #include "window.h" #include "input.h" +#include "cursor.h" +#include <X11/extensions/XI.h> #define EARLIER -1 #define SAMETIME 0 @@ -693,6 +695,19 @@ extern Bool IsKeyboardDevice(DeviceIntPtr dev); /* GE stuff */ -void SetGenericFilter(int extension, Mask* filters); +extern void SetGenericFilter(int extension, Mask* filters); + +extern int ExtGrabDevice(ClientPtr client, + DeviceIntPtr dev, + int grabmode, + int device_mode, + WindowPtr grabWindow, + WindowPtr confineTo, + TimeStamp ctime, + Bool ownerEvents, + CursorPtr cursor, + Mask core_mask, + Mask xi_mask, + GenericMaskPtr ge_masks); #endif /* DIX_H */ diff --git a/include/inputstr.h b/include/inputstr.h index 4924cb1cc..837afaa44 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -102,6 +102,22 @@ typedef struct _DetailRec { /* Grab details may be bit masks */ Mask *pMask; } DetailRec; +typedef struct _GenericMaskRec { + int extension; + Mask mask; + struct _GenericMaskRec* next; +} GenericMaskRec; + +/** + * Central struct for device grabs. + * The same struct is used for both core grabs and device grabs, with + * different fields being set. + * If the grab is a core grab (GrabPointer/GrabKeyboard), then the eventMask + * is a combination of standard event masks (i.e. PointerMotionMask | + * ButtonPressMask). + * If the grab is a device grab (GrabDevice), then the eventMask is a + * combination of event masks for a given XI event type (see SetEventInfo). + */ typedef struct _GrabRec { GrabPtr next; /* for chain of passive grabs */ XID resource; @@ -119,6 +135,7 @@ typedef struct _GrabRec { WindowPtr confineTo; /* always NULL for keyboards */ CursorPtr cursor; /* always NULL for keyboards */ Mask eventMask; + GenericMaskPtr genericMasks; /* null terminated list */ } GrabRec; typedef struct _KeyClassRec { diff --git a/include/misc.h b/include/misc.h index 2be1d66a6..05c3dff45 100644 --- a/include/misc.h +++ b/include/misc.h @@ -243,6 +243,7 @@ typedef struct _Box *BoxPtr; typedef struct _xEvent *xEventPtr; typedef struct _xRectangle *xRectanglePtr; typedef struct _GrabRec *GrabPtr; +typedef struct _GenericMaskRec *GenericMaskPtr; /* typedefs from other places - duplicated here to minimize the amount * of unnecessary junk that one would normally have to include to get |