Add ExtendedGrabDevice handling.
Add XGE handling in DeliverGrabbedEvent. We can now grab something selecting XGE events, but the current code is a bit messy and doesn't work too well yet.
This commit is contained in:
parent
cb22bdbe67
commit
4dc973f08c
|
@ -29,6 +29,8 @@ libXi_la_SOURCES = \
|
|||
devbell.h \
|
||||
exevents.c \
|
||||
exglobals.h \
|
||||
extgrbdev.c \
|
||||
extgrbdev.h \
|
||||
extinit.c \
|
||||
fakedevdata.c \
|
||||
fakedevdata.h \
|
||||
|
|
238
Xi/extgrbdev.c
Normal file
238
Xi/extgrbdev.c
Normal file
|
@ -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);
|
||||
}
|
46
Xi/extgrbdev.h
Normal file
46
Xi/extgrbdev.h
Normal file
|
@ -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 */
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
|
|
223
dix/events.c
223
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;
|
||||
}
|
||||
|
||||
FixUpEventFromWindow(thisDev, xE, grab->window, None, TRUE);
|
||||
deliveries = TryClientEvents(rClient(grab), xE, count,
|
||||
(Mask)grab->eventMask,
|
||||
filters[xE->u.u.type], grab);
|
||||
if (!gemask)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user