[PATCH] input: deliver raw events unconditionally for XI 2.1 clients.
Peter Hutterer
peter.hutterer at who-t.net
Tue May 10 21:59:35 PDT 2011
Deliver raw events regardless whether there is a grab on or not for clients
supporting 2.1 or later.
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
Xi/exevents.c | 42 ++++++++++++++++++++++++------------------
dix/events.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 72 insertions(+), 19 deletions(-)
diff --git a/Xi/exevents.c b/Xi/exevents.c
index c6f9d46..2392ff1 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -876,30 +876,36 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
return DEFAULT;
}
+
+/**
+ * Raw event delivery differs between XI 2.0 and XI 2.1.
+ * XI 2.0: events delivered to the grabbing client only (if any) OR to all
+ * root windows
+ * XI 2.1: events delivered to all root windows, regardless of grabbing
+ * state
+ *
+ */
static void
ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
{
GrabPtr grab = device->deviceGrab.grab;
+ xEvent *xi;
+ int i;
- if (grab)
- DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE);
- else { /* deliver to all root windows */
- xEvent *xi;
- int i;
-
- i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi);
- if (i != Success)
- {
- ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n",
- device->name, i);
- return;
- }
-
- for (i = 0; i < screenInfo.numScreens; i++)
- DeliverEventsToWindow(device, screenInfo.screens[i]->root, xi, 1,
- GetEventFilter(device, xi), NULL);
- free(xi);
+ /* deliver to all root windows. For XI 2.0 clients,
+ * grabbed raw events will be filtered later */
+ i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi);
+ if (i != Success)
+ {
+ ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n",
+ device->name, i);
+ return;
}
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ DeliverEventsToWindow(device, screenInfo.screens[i]->root, xi, 1,
+ GetEventFilter(device, xi), NULL);
+ free(xi);
}
/**
diff --git a/dix/events.c b/dix/events.c
index f3af5ee..ee05be3 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1992,6 +1992,52 @@ out:
}
/**
+ * Filter out raw events for XI 2.0 clients.
+ *
+ * If there is a grab on the device, 2.0 clients only get raw events if they
+ * have the grab. 2.1+ clients get raw events in all cases.
+ *
+ * For raw events, this function may be called from DeliverEventsToWindow()
+ * or through DeliverGrabbedEvent(). For 2.0 we need to filter when a grab
+ * is on and we're coming from DeliverEventsToWindow(), for 2.1 we need to
+ * filter whenever we come from DeliverGrabbedEvent().
+ *
+ * grab is non-NULL when coming from DeliverGrabbedEvent(), otherwise NULL.
+ *
+ * @return TRUE if the event should be discarded, FALSE otherwise.
+ */
+static BOOL
+FilterRawEvents(const DeviceIntPtr dev, const xEvent *event,
+ const GrabPtr grab, const ClientPtr client)
+{
+ int rc = FALSE;
+ XIClientPtr client_xi_version;
+
+ if (!is_xi2_event_of_type(event, XI_RawMotion) &&
+ !is_xi2_event_of_type(event, XI_RawButtonPress) &&
+ !is_xi2_event_of_type(event, XI_RawButtonRelease) &&
+ !is_xi2_event_of_type(event, XI_RawKeyPress) &&
+ !is_xi2_event_of_type(event, XI_RawKeyRelease))
+ goto out;
+
+ client_xi_version = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
+
+ /* If the client is XI 2.0, there is a grab on the device and it's not
+ * our grab, filter the raw event. */
+ if (version_compare(client_xi_version->major_version,
+ client_xi_version->minor_version, 2, 0) == 0)
+ {
+ GrabPtr devgrab = dev->deviceGrab.grab;
+
+ if (devgrab && rClient(devgrab) != client)
+ rc = TRUE;
+ }
+
+out:
+ return rc;
+}
+
+/**
* Deliver events to clients registered on the window.
*
* @param client_return On successful delivery, set to the recipient.
@@ -2039,7 +2085,8 @@ DeliverEventToClients(DeviceIntPtr dev, WindowPtr win, xEvent *events,
mask = GetEventMask(dev, events, other);
if (XaceHook(XACE_RECEIVE_ACCESS, client, win,
- events, count))
+ events, count) ||
+ FilterRawEvents(dev, events, grab, client))
/* do nothing */;
else if ( (attempt = TryClientEvents(client, dev,
events, count,
--
1.7.4.4
More information about the xorg-devel
mailing list