aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/dix/events.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/dix/events.c')
-rw-r--r--xorg-server/dix/events.c664
1 files changed, 401 insertions, 263 deletions
diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c
index d70d62fd8..14f6f909e 100644
--- a/xorg-server/dix/events.c
+++ b/xorg-server/dix/events.c
@@ -176,12 +176,23 @@ typedef const char *string;
#define AllEventMasks (LastEventMask|(LastEventMask-1))
-#define CORE_EVENT(event) \
- (!((event)->u.u.type & EXTENSION_EVENT_BASE) && \
- (event)->u.u.type != GenericEvent)
-#define XI2_EVENT(event) \
- (((event)->u.u.type == GenericEvent) && \
- ((xGenericEvent*)(event))->extension == IReqCode)
+/* @return the core event type or 0 if the event is not a core event */
+static inline int
+core_get_type(const xEvent *event)
+{
+ int type = event->u.u.type;
+
+ return ((type & EXTENSION_EVENT_BASE) || type == GenericEvent) ? 0 : type;
+}
+
+/* @return the XI2 event type or 0 if the event is not a XI2 event */
+static inline int
+xi2_get_type(const xEvent *event)
+{
+ xGenericEvent* e = (xGenericEvent*)event;
+
+ return (e->type != GenericEvent || e->extension != IReqCode) ? 0 : e->evtype;
+}
/**
* Used to indicate a implicit passive grab created by a ButtonPress event.
@@ -345,8 +356,8 @@ extern int DeviceMotionNotify;
/**
* Event masks for each event type.
*
- * One set of filters for each device, but only the first layer
- * is initialized. The rest is memcpy'd in InitEvents.
+ * One set of filters for each device, initialized by memcpy of
+ * default_filter in InitEvents.
*
* Filters are used whether a given event may be delivered to a client,
* usually in the form of if (window-event-mask & filter); then deliver event.
@@ -355,7 +366,9 @@ extern int DeviceMotionNotify;
* time a button is pressed, the filter is modified to also contain the
* matching ButtonXMotion mask.
*/
-static Mask filters[MAXDEVICES][128] = {
+static Mask filters[MAXDEVICES][128];
+
+static const Mask default_filter[128] =
{
NoSuchEvent, /* 0 */
NoSuchEvent, /* 1 */
@@ -392,7 +405,7 @@ static Mask filters[MAXDEVICES][128] = {
ColormapChangeMask, /* ColormapNotify */
CantBeFiltered, /* ClientMessage */
CantBeFiltered /* MappingNotify */
-}};
+};
/**
* For the given event, return the matching event filter. This filter may then
@@ -412,10 +425,12 @@ static Mask filters[MAXDEVICES][128] = {
Mask
GetEventFilter(DeviceIntPtr dev, xEvent *event)
{
+ int evtype = 0;
+
if (event->u.u.type != GenericEvent)
return filters[dev ? dev->id : 0][event->u.u.type];
- else if (XI2_EVENT(event))
- return (1 << (((xXIDeviceEvent*)event)->evtype % 8));
+ else if ((evtype = xi2_get_type(event)))
+ return (1 << (evtype % 8));
ErrorF("[dix] Unknown device type %d. No filter\n", event->u.u.type);
return 0;
}
@@ -430,7 +445,7 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
int filter;
int evtype;
- if (!inputMasks || !XI2_EVENT(ev))
+ if (!inputMasks || xi2_get_type(ev) == 0)
return 0;
evtype = ((xGenericEvent*)ev)->evtype;
@@ -444,14 +459,16 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
Mask
GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other)
{
+ int evtype;
+
/* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */
- if (XI2_EVENT(event))
+ if ((evtype = xi2_get_type(event)))
{
- int byte = ((xGenericEvent*)event)->evtype / 8;
+ int byte = evtype / 8;
return (other->xi2mask[dev->id][byte] |
other->xi2mask[XIAllDevices][byte] |
(IsMaster(dev)? other->xi2mask[XIAllMasterDevices][byte] : 0));
- } else if (CORE_EVENT(event))
+ } else if (core_get_type(event) != 0)
return other->mask[XIAllDevices];
else
return other->mask[dev->id];
@@ -1937,6 +1954,159 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents,
return 1;
}
+static BOOL
+ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
+ xEvent *event, Mask deliveryMask)
+{
+ GrabRec tempGrab;
+ OtherInputMasks *inputMasks;
+ CARD8 type = event->u.u.type;
+ GrabType grabtype;
+
+ if (type == ButtonPress)
+ grabtype = GRABTYPE_CORE;
+ else if (type == DeviceButtonPress)
+ grabtype = GRABTYPE_XI;
+ else if ((type = xi2_get_type(event)) == XI_ButtonPress)
+ grabtype = GRABTYPE_XI2;
+ else
+ return FALSE;
+
+ memset(&tempGrab, 0, sizeof(GrabRec));
+ tempGrab.next = NULL;
+ tempGrab.device = dev;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.window = win;
+ tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+ tempGrab.eventMask = deliveryMask;
+ tempGrab.keyboardMode = GrabModeAsync;
+ tempGrab.pointerMode = GrabModeAsync;
+ tempGrab.confineTo = NullWindow;
+ tempGrab.cursor = NullCursor;
+ tempGrab.type = type;
+ tempGrab.grabtype = grabtype;
+
+ /* get the XI and XI2 device mask */
+ inputMasks = wOtherInputMasks(win);
+ tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id]: 0;
+
+ if (inputMasks)
+ memcpy(tempGrab.xi2mask, inputMasks->xi2mask,
+ sizeof(tempGrab.xi2mask));
+
+ (*dev->deviceGrab.ActivateGrab)(dev, &tempGrab,
+ currentTime, TRUE | ImplicitGrabMask);
+ return TRUE;
+}
+
+enum EventDeliveryState {
+ EVENT_DELIVERED, /**< Event has been delivered to a client */
+ EVENT_NOT_DELIVERED, /**< Event was not delivered to any client */
+ EVENT_SKIP, /**< Event can be discarded by the caller */
+ EVENT_REJECTED, /**< Event was rejected for delivery to the client */
+};
+
+/**
+ * Attempt event delivery to the client owning the window.
+ */
+static enum EventDeliveryState
+DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win,
+ xEvent *events, int count, Mask filter,
+ GrabPtr grab)
+{
+ /* if nobody ever wants to see this event, skip some work */
+ if (filter != CantBeFiltered &&
+ !((wOtherEventMasks(win)|win->eventMask) & filter))
+ return EVENT_SKIP;
+
+ if (IsInterferingGrab(wClient(win), dev, events))
+ return EVENT_SKIP;
+
+ if (!XaceHook(XACE_RECEIVE_ACCESS, wClient(win), win, events, count))
+ {
+ int attempt = TryClientEvents(wClient(win), dev, events,
+ count, win->eventMask,
+ filter, grab);
+ if (attempt > 0)
+ return EVENT_DELIVERED;
+ if (attempt < 0)
+ return EVENT_REJECTED;
+ }
+
+ return EVENT_NOT_DELIVERED;
+}
+
+/**
+ * Deliver events to clients registered on the window.
+ *
+ * @param client_return On successful delivery, set to the recipient.
+ * @param mask_return On successful delivery, set to the recipient's event
+ * mask for this event.
+ */
+static enum EventDeliveryState
+DeliverEventToClients(DeviceIntPtr dev, WindowPtr win, xEvent *events,
+ int count, Mask filter, GrabPtr grab,
+ ClientPtr *client_return, Mask *mask_return)
+{
+ int attempt;
+ enum EventDeliveryState rc = EVENT_SKIP;
+ InputClients *other;
+
+ if (core_get_type(events) != 0)
+ other = (InputClients *)wOtherClients(win);
+ else if (xi2_get_type(events) != 0)
+ {
+ OtherInputMasks *inputMasks = wOtherInputMasks(win);
+ /* Has any client selected for the event? */
+ if (!GetWindowXI2Mask(dev, win, events))
+ goto out;
+ other = inputMasks->inputClients;
+ } else {
+ OtherInputMasks *inputMasks = wOtherInputMasks(win);
+ /* Has any client selected for the event? */
+ if (!inputMasks ||
+ !(inputMasks->inputEvents[dev->id] & filter))
+ goto out;
+
+ other = inputMasks->inputClients;
+ }
+
+ rc = EVENT_NOT_DELIVERED;
+
+ for (; other; other = other->next)
+ {
+ Mask mask;
+ ClientPtr client = rClient(other);
+
+ if (IsInterferingGrab(client, dev, events))
+ continue;
+
+ mask = GetEventMask(dev, events, other);
+
+ if (XaceHook(XACE_RECEIVE_ACCESS, client, win,
+ events, count))
+ /* do nothing */;
+ else if ( (attempt = TryClientEvents(client, dev,
+ events, count,
+ mask, filter, grab)) )
+ {
+ if (attempt > 0)
+ {
+ rc = EVENT_DELIVERED;
+ *client_return = client;
+ *mask_return = mask;
+ /* Success overrides non-success, so if we've been
+ * successful on one client, return that */
+ } else if (rc == EVENT_NOT_DELIVERED)
+ rc = EVENT_REJECTED;
+ }
+ }
+
+out:
+ return rc;
+}
+
+
/**
* Deliver events to a window. At this point, we do not yet know if the event
* actually needs to be delivered. May activate a grab if the event is a
@@ -1955,152 +2125,84 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents,
* @param filter Mask based on event type.
* @param grab Possible grab on the device that caused the event.
*
- * @return Number of events delivered to various clients.
+ * @return a positive number if at least one successful delivery has been
+ * made, 0 if no events were delivered, or a negative number if the event
+ * has not been delivered _and_ rejected by at least one client.
*/
int
DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
*pEvents, int count, Mask filter, GrabPtr grab)
{
int deliveries = 0, nondeliveries = 0;
- int attempt;
- InputClients *other;
ClientPtr client = NullClient;
Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
this mask is the mask of the grab. */
int type = pEvents->u.u.type;
-
/* Deliver to window owner */
- if ((filter == CantBeFiltered) || CORE_EVENT(pEvents))
+ if ((filter == CantBeFiltered) || core_get_type(pEvents) != 0)
{
- /* if nobody ever wants to see this event, skip some work */
- if (filter != CantBeFiltered &&
- !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
- return 0;
+ enum EventDeliveryState rc;
- if (IsInterferingGrab(wClient(pWin), pDev, pEvents))
- return 0;
+ rc = DeliverToWindowOwner(pDev, pWin, pEvents, count, filter, grab);
- if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count))
- /* do nothing */;
- else if ( (attempt = TryClientEvents(wClient(pWin), pDev, pEvents,
- count, pWin->eventMask,
- filter, grab)) )
- {
- if (attempt > 0)
- {
- deliveries++;
- client = wClient(pWin);
- deliveryMask = pWin->eventMask;
- } else
- nondeliveries--;
- }
+ switch(rc)
+ {
+ case EVENT_SKIP:
+ return 0;
+ case EVENT_REJECTED:
+ nondeliveries--;
+ break;
+ case EVENT_DELIVERED:
+ /* We delivered to the owner, with our event mask */
+ deliveries++;
+ client = wClient(pWin);
+ deliveryMask = pWin->eventMask;
+ break;
+ case EVENT_NOT_DELIVERED:
+ break;
+ }
}
/* CantBeFiltered means only window owner gets the event */
if (filter != CantBeFiltered)
{
- if (CORE_EVENT(pEvents))
- other = (InputClients *)wOtherClients(pWin);
- else if (XI2_EVENT(pEvents))
- {
- OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
- /* Has any client selected for the event? */
- if (!GetWindowXI2Mask(pDev, pWin, pEvents))
- return 0;
- other = inputMasks->inputClients;
- } else {
- OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
- /* Has any client selected for the event? */
- if (!inputMasks ||
- !(inputMasks->inputEvents[pDev->id] & filter))
- return 0;
+ enum EventDeliveryState rc;
- other = inputMasks->inputClients;
- }
+ rc = DeliverEventToClients(pDev, pWin, pEvents, count, filter, grab,
+ &client, &deliveryMask);
- for (; other; other = other->next)
+ switch(rc)
{
- Mask mask;
- if (IsInterferingGrab(rClient(other), pDev, pEvents))
- continue;
-
- mask = GetEventMask(pDev, pEvents, other);
-
- if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin,
- pEvents, count))
- /* do nothing */;
- else if ( (attempt = TryClientEvents(rClient(other), pDev,
- pEvents, count,
- mask, filter, grab)) )
- {
- if (attempt > 0)
- {
- deliveries++;
- client = rClient(other);
- deliveryMask = mask;
- } else
- nondeliveries--;
- }
+ case EVENT_SKIP:
+ return 0;
+ case EVENT_REJECTED:
+ nondeliveries--;
+ break;
+ case EVENT_DELIVERED:
+ deliveries++;
+ break;
+ case EVENT_NOT_DELIVERED:
+ break;
}
}
- /*
- * Note that since core events are delivered first, an implicit grab may
- * be activated on a core grab, stopping the XI events.
- */
- if ((type == DeviceButtonPress || type == ButtonPress ||
- ((XI2_EVENT(pEvents) && ((xGenericEvent*)pEvents)->evtype == XI_ButtonPress)))
- && deliveries
- && (!grab))
- {
- GrabRec tempGrab;
- OtherInputMasks *inputMasks;
- memset(&tempGrab, 0, sizeof(GrabRec));
- tempGrab.next = NULL;
- tempGrab.device = pDev;
- tempGrab.resource = client->clientAsMask;
- tempGrab.window = pWin;
- tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
- tempGrab.eventMask = deliveryMask;
- tempGrab.keyboardMode = GrabModeAsync;
- tempGrab.pointerMode = GrabModeAsync;
- tempGrab.confineTo = NullWindow;
- tempGrab.cursor = NullCursor;
- tempGrab.type = type;
- if (type == ButtonPress)
- tempGrab.grabtype = GRABTYPE_CORE;
- else if (type == DeviceButtonPress)
- tempGrab.grabtype = GRABTYPE_XI;
- else
- {
- tempGrab.type = ((xGenericEvent*)pEvents)->evtype;
- tempGrab.grabtype = GRABTYPE_XI2;
- }
-
- /* get the XI and XI2 device mask */
- inputMasks = wOtherInputMasks(pWin);
- tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[pDev->id]: 0;
-
- if (inputMasks)
- memcpy(tempGrab.xi2mask, inputMasks->xi2mask,
- sizeof(tempGrab.xi2mask));
-
- (*pDev->deviceGrab.ActivateGrab)(pDev, &tempGrab,
- currentTime, TRUE | ImplicitGrabMask);
- }
- else if ((type == MotionNotify) && deliveries)
- pDev->valuator->motionHintWindow = pWin;
- else
- {
- if ((type == DeviceMotionNotify || type == DeviceButtonPress) &&
- deliveries)
- CheckDeviceGrabAndHintWindow (pWin, type,
- (deviceKeyButtonPointer*) pEvents,
- grab, client, deliveryMask);
- }
if (deliveries)
+ {
+ /*
+ * Note that since core events are delivered first, an implicit grab may
+ * be activated on a core grab, stopping the XI events.
+ */
+ if (!grab && ActivateImplicitGrab(pDev, client, pWin, pEvents, deliveryMask))
+ /* grab activated */;
+ else if ((type == MotionNotify))
+ pDev->valuator->motionHintWindow = pWin;
+ else if (type == DeviceMotionNotify || type == DeviceButtonPress)
+ CheckDeviceGrabAndHintWindow (pWin, type,
+ (deviceKeyButtonPointer*) pEvents,
+ grab, client, deliveryMask);
return deliveries;
+ }
return nondeliveries;
}
@@ -2180,7 +2282,7 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
static Window FindChildForEvent(SpritePtr pSprite, WindowPtr event)
{
- WindowPtr w = pSprite->spriteTrace[pSprite->spriteTraceGood-1];
+ WindowPtr w = DeepestSpriteWin(pSprite);
Window child = None;
/* If the search ends up past the root should the child field be
@@ -2224,22 +2326,29 @@ FixUpEventFromWindow(
Window child,
Bool calcChild)
{
+ int evtype;
+
if (calcChild)
child = FindChildForEvent(pSprite, pWin);
- if (XI2_EVENT(xE))
+ if ((evtype = xi2_get_type(xE)))
{
xXIDeviceEvent* event = (xXIDeviceEvent*)xE;
- if (event->evtype == XI_RawKeyPress ||
- event->evtype == XI_RawKeyRelease ||
- event->evtype == XI_RawButtonPress ||
- event->evtype == XI_RawButtonRelease ||
- event->evtype == XI_RawMotion ||
- event->evtype == XI_DeviceChanged ||
- event->evtype == XI_HierarchyChanged ||
- event->evtype == XI_PropertyEvent)
- return;
+ switch (evtype)
+ {
+ case XI_RawKeyPress:
+ case XI_RawKeyRelease:
+ case XI_RawButtonPress:
+ case XI_RawButtonRelease:
+ case XI_RawMotion:
+ case XI_DeviceChanged:
+ case XI_HierarchyChanged:
+ case XI_PropertyEvent:
+ return;
+ default:
+ break;
+ }
event->root = RootWindow(pSprite)->drawable.id;
event->event = pWin->drawable.id;
@@ -2375,7 +2484,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
xEvent *xE = NULL, *core = NULL;
int rc, mask, count = 0;
- CHECKEVENT(event);
+ verify_internal_event(event);
while (pWin)
{
@@ -2623,7 +2732,7 @@ XYToWindow(SpritePtr pSprite, int x, int y)
else
pWin = pWin->nextSib;
}
- return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
+ return DeepestSpriteWin(pSprite);
}
/**
@@ -2661,7 +2770,8 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
event.deviceid = dev->id;
event.sourceid = dev->id;
event.detail.button = 0;
- rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE, TRUE) != NULL);
+ rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE,
+ TRUE) != NULL);
if (rc)
DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab);
return rc;
@@ -2698,7 +2808,8 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
event.deviceid = dev->id;
event.sourceid = dev->id;
event.detail.button = 0;
- rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE, TRUE) != NULL);
+ rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE,
+ TRUE) != NULL);
if (rc)
DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab);
return rc;
@@ -2721,7 +2832,7 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
WindowPtr prevSpriteWin, newSpriteWin;
SpritePtr pSprite = pDev->spriteInfo->sprite;
- CHECKEVENT(ev);
+ verify_internal_event(ev);
prevSpriteWin = pSprite->win;
@@ -3385,7 +3496,7 @@ GrabPtr
CheckPassiveGrabsOnWindow(
WindowPtr pWin,
DeviceIntPtr device,
- DeviceEvent *event,
+ InternalEvent *event,
BOOL checkCore,
BOOL activate)
{
@@ -3402,9 +3513,22 @@ CheckPassiveGrabsOnWindow(
return NULL;
/* Fill out the grab details, but leave the type for later before
* comparing */
+ switch (event->any.type)
+ {
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ tempGrab.detail.exact = event->device_event.detail.key;
+ break;
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ tempGrab.detail.exact = event->device_event.detail.button;
+ break;
+ default:
+ tempGrab.detail.exact = 0;
+ break;
+ }
tempGrab.window = pWin;
tempGrab.device = device;
- tempGrab.detail.exact = event->detail.key;
tempGrab.detail.pMask = NULL;
tempGrab.modifiersDetail.pMask = NULL;
tempGrab.next = NULL;
@@ -3412,6 +3536,8 @@ CheckPassiveGrabsOnWindow(
{
DeviceIntPtr gdev;
XkbSrvInfoPtr xkbi = NULL;
+ xEvent *xE = NULL;
+ int count, rc;
gdev= grab->modifierDevice;
if (grab->grabtype == GRABTYPE_CORE)
@@ -3437,16 +3563,15 @@ CheckPassiveGrabsOnWindow(
tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
/* Check for XI2 and XI grabs first */
- tempGrab.type = GetXI2Type((InternalEvent*)event);
+ tempGrab.type = GetXI2Type(event);
tempGrab.grabtype = GRABTYPE_XI2;
if (GrabMatchesSecond(&tempGrab, grab, FALSE))
match = XI2_MATCH;
- tempGrab.detail.exact = event->detail.key;
if (!match)
{
tempGrab.grabtype = GRABTYPE_XI;
- if ((tempGrab.type = GetXIType((InternalEvent*)event)) &&
+ if ((tempGrab.type = GetXIType(event)) &&
(GrabMatchesSecond(&tempGrab, grab, FALSE)))
match = XI_MATCH;
}
@@ -3455,122 +3580,134 @@ CheckPassiveGrabsOnWindow(
if (!match && checkCore)
{
tempGrab.grabtype = GRABTYPE_CORE;
- if ((tempGrab.type = GetCoreType((InternalEvent*)event)) &&
+ if ((tempGrab.type = GetCoreType(event)) &&
(GrabMatchesSecond(&tempGrab, grab, TRUE)))
match = CORE_MATCH;
}
- if (match && (!grab->confineTo ||
- (grab->confineTo->realized &&
- BorderSizeNotEmpty(device, grab->confineTo))))
- {
- int rc, count = 0;
- xEvent *xE = NULL;
-
- event->corestate &= 0x1f00;
- event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00);
- grabinfo = &device->deviceGrab;
- /* In some cases a passive core grab may exist, but the client
- * already has a core grab on some other device. In this case we
- * must not get the grab, otherwise we may never ungrab the
- * device.
- */
-
- if (grab->grabtype == GRABTYPE_CORE)
+ if (!match || (grab->confineTo &&
+ (!grab->confineTo->realized ||
+ !BorderSizeNotEmpty(device, grab->confineTo))))
+ continue;
+
+ grabinfo = &device->deviceGrab;
+ /* In some cases a passive core grab may exist, but the client
+ * already has a core grab on some other device. In this case we
+ * must not get the grab, otherwise we may never ungrab the
+ * device.
+ */
+
+ if (grab->grabtype == GRABTYPE_CORE)
+ {
+ DeviceIntPtr other;
+ BOOL interfering = FALSE;
+
+ /* A passive grab may have been created for a different device
+ than it is assigned to at this point in time.
+ Update the grab's device and modifier device to reflect the
+ current state.
+ Since XGrabDeviceButton requires to specify the
+ modifierDevice explicitly, we don't override this choice.
+ */
+ if (tempGrab.type < GenericEvent)
{
- DeviceIntPtr other;
- BOOL interfering = FALSE;
-
- /* A passive grab may have been created for a different device
- than it is assigned to at this point in time.
- Update the grab's device and modifier device to reflect the
- current state.
- Since XGrabDeviceButton requires to specify the
- modifierDevice explicitly, we don't override this choice.
- */
- if (tempGrab.type < GenericEvent)
- {
- grab->device = device;
- grab->modifierDevice = GetPairedDevice(device);
- }
+ grab->device = device;
+ grab->modifierDevice = GetPairedDevice(device);
+ }
- for (other = inputInfo.devices; other; other = other->next)
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ GrabPtr othergrab = other->deviceGrab.grab;
+ if (othergrab && othergrab->grabtype == GRABTYPE_CORE &&
+ SameClient(grab, rClient(othergrab)) &&
+ ((IsPointerDevice(grab->device) &&
+ IsPointerDevice(othergrab->device)) ||
+ (IsKeyboardDevice(grab->device) &&
+ IsKeyboardDevice(othergrab->device))))
{
- GrabPtr othergrab = other->deviceGrab.grab;
- if (othergrab && othergrab->grabtype == GRABTYPE_CORE &&
- SameClient(grab, rClient(othergrab)) &&
- ((IsPointerDevice(grab->device) &&
- IsPointerDevice(othergrab->device)) ||
- (IsKeyboardDevice(grab->device) &&
- IsKeyboardDevice(othergrab->device))))
- {
- interfering = TRUE;
- break;
- }
+ interfering = TRUE;
+ break;
}
- if (interfering)
- continue;
}
+ if (interfering)
+ continue;
+ }
- if (!activate)
- return grab;
+ if (!activate)
+ {
+ return grab;
+ }
+ else if (!GetXIType(event) && !GetCoreType(event))
+ {
+ ErrorF("Event type %d in CheckPassiveGrabsOnWindow is neither"
+ " XI 1.x nor core\n", event->any.type);
+ return NULL;
+ }
- if (match & CORE_MATCH)
+ /* The only consumers of corestate are Xi 1.x and core events, which
+ * are guaranteed to come from DeviceEvents. */
+ if (match & (XI_MATCH | CORE_MATCH))
+ {
+ event->device_event.corestate &= 0x1f00;
+ event->device_event.corestate |= tempGrab.modifiersDetail.exact &
+ (~0x1f00);
+ }
+
+ if (match & CORE_MATCH)
+ {
+ rc = EventToCore(event, &xE, &count);
+ if (rc != Success)
{
- rc = EventToCore((InternalEvent*)event, &xE, &count);
- if (rc != Success)
- {
- if (rc != BadMatch)
- ErrorF("[dix] %s: core conversion failed in CPGFW "
- "(%d, %d).\n", device->name, event->type, rc);
- continue;
- }
- } else if (match & XI2_MATCH)
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: core conversion failed in CPGFW "
+ "(%d, %d).\n", device->name, event->any.type, rc);
+ continue;
+ }
+ } else if (match & XI2_MATCH)
+ {
+ rc = EventToXI2(event, &xE);
+ if (rc != Success)
{
- rc = EventToXI2((InternalEvent*)event, &xE);
- if (rc != Success)
- {
- if (rc != BadMatch)
- ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
- "(%d, %d).\n", device->name, event->type, rc);
- continue;
- }
- count = 1;
- } else
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
+ "(%d, %d).\n", device->name, event->any.type, rc);
+ continue;
+ }
+ count = 1;
+ } else
+ {
+ rc = EventToXI(event, &xE, &count);
+ if (rc != Success)
{
- rc = EventToXI((InternalEvent*)event, &xE, &count);
- if (rc != Success)
- {
- if (rc != BadMatch)
- ErrorF("[dix] %s: XI conversion failed in CPGFW "
- "(%d, %d).\n", device->name, event->type, rc);
- continue;
- }
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: XI conversion failed in CPGFW "
+ "(%d, %d).\n", device->name, event->any.type, rc);
+ continue;
}
+ }
- (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
+ (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
- if (xE)
- {
- FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
+ if (xE)
+ {
+ FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
- /* XXX: XACE? */
- TryClientEvents(rClient(grab), device, xE, count,
- GetEventFilter(device, xE),
- GetEventFilter(device, xE), grab);
- }
+ /* XXX: XACE? */
+ TryClientEvents(rClient(grab), device, xE, count,
+ GetEventFilter(device, xE),
+ GetEventFilter(device, xE), grab);
+ }
- if (grabinfo->sync.state == FROZEN_NO_EVENT)
- {
- if (!grabinfo->sync.event)
- grabinfo->sync.event = calloc(1, sizeof(InternalEvent));
- *grabinfo->sync.event = *event;
- grabinfo->sync.state = FROZEN_WITH_EVENT;
- }
+ if (grabinfo->sync.state == FROZEN_NO_EVENT)
+ {
+ if (!grabinfo->sync.event)
+ grabinfo->sync.event = calloc(1, sizeof(DeviceEvent));
+ *grabinfo->sync.event = event->device_event;
+ grabinfo->sync.state = FROZEN_WITH_EVENT;
+ }
- free(xE);
- return grab;
- }
+ free(xE);
+ return grab;
}
return NULL;
#undef CORE_MATCH
@@ -3639,7 +3776,8 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor)
for (; i < focus->traceGood; i++)
{
pWin = focus->trace[i];
- if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore, TRUE))
+ if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event,
+ sendCore, TRUE))
{
ret = TRUE;
goto out;
@@ -3655,7 +3793,8 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor)
for (; i < device->spriteInfo->sprite->spriteTraceGood; i++)
{
pWin = device->spriteInfo->sprite->spriteTrace[i];
- if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore, TRUE))
+ if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event,
+ sendCore, TRUE))
{
ret = TRUE;
goto out;
@@ -3766,8 +3905,10 @@ unwind:
* grab. If not, TryClientEvents() is used.
*
* @param deactivateGrab True if the device's grab should be deactivated.
+ *
+ * @return The number of events delivered.
*/
-void
+int
DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
Bool deactivateGrab)
{
@@ -3935,6 +4076,8 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
free(core);
free(xi);
free(xi2);
+
+ return deliveries;
}
/* This function is used to set the key pressed or key released state -
@@ -4977,12 +5120,9 @@ InitEvents(void)
inputInfo.off_devices = (DeviceIntPtr)NULL;
inputInfo.keyboard = (DeviceIntPtr)NULL;
inputInfo.pointer = (DeviceIntPtr)NULL;
- /* The mask for pointer motion events may have changed in the last server
- * generation. See comment above definition of filters. */
- filters[0][PointerMotionMask] = MotionNotify;
- for (i = 1; i < MAXDEVICES; i++)
+ for (i = 0; i < MAXDEVICES; i++)
{
- memcpy(&filters[i], filters[0], sizeof(filters[0]));
+ memcpy(&filters[i], default_filter, sizeof(default_filter));
}
syncEvents.replayDev = (DeviceIntPtr)NULL;
@@ -5006,8 +5146,7 @@ InitEvents(void)
DontPropagateRefCnts[i] = 0;
}
- InputEventListLen = GetMaximumEventsNum();
- InputEventList = InitEventList(InputEventListLen);
+ InputEventList = InitEventList(GetMaximumEventsNum());
if (!InputEventList)
FatalError("[dix] Failed to allocate input event list.\n");
}
@@ -5015,8 +5154,7 @@ InitEvents(void)
void
CloseDownEvents(void)
{
- FreeEventList(InputEventList, InputEventListLen);
- InputEventListLen = 0;
+ FreeEventList(InputEventList, GetMaximumEventsNum());
InputEventList = NULL;
}