summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-09-29 14:18:35 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-09-29 14:18:35 +1000
commit057cc92ebfeebe81b7d01ff2c6aa2c066c8d1a64 (patch)
tree9d2d821c8b9c011c35b440552c34246c7822fea7
parentafb1fe695d197187a301c19863a128a65389b15c (diff)
parent52c9b59a9fed6abfeca775a7a04133cee18eac0b (diff)
Merge branch 'raw-events' into next
Conflicts: configure.ac dix/events.c
-rw-r--r--configure.ac2
-rw-r--r--dix/events.c92
-rw-r--r--include/protocol-versions.h2
3 files changed, 78 insertions, 18 deletions
diff --git a/configure.ac b/configure.ac
index b0d26435a..58ec3fb5b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -778,7 +778,7 @@ WINDOWSWMPROTO="windowswmproto"
APPLEWMPROTO="applewmproto >= 1.4"
dnl Core modules for most extensions, et al.
-SDK_REQUIRED_MODULES="[xproto >= 7.0.22] [randrproto >= 1.2.99.3] [renderproto >= 0.11] [xextproto >= 7.1.99] [inputproto >= 1.9.99.902] [kbproto >= 1.0.3] fontsproto"
+SDK_REQUIRED_MODULES="[xproto >= 7.0.22] [randrproto >= 1.2.99.3] [renderproto >= 0.11] [xextproto >= 7.1.99] [inputproto >= 2.0.99.1] [kbproto >= 1.0.3] fontsproto"
# Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc
AC_SUBST(SDK_REQUIRED_MODULES)
diff --git a/dix/events.c b/dix/events.c
index fbe4fc953..4e21c2df2 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2268,33 +2268,93 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
return nondeliveries;
}
+/**
+ * Filter out raw events for XI 2.0 and XI 2.1 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.
+ *
+ * @return TRUE if the event should be discarded, FALSE otherwise.
+ */
+static BOOL
+FilterRawEvents(const ClientPtr client, const GrabPtr grab)
+{
+ XIClientPtr client_xi_version;
+ int cmp;
+
+ /* device not grabbed -> don't filter */
+ if (!grab)
+ return FALSE;
+
+ client_xi_version = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
+
+ cmp = version_compare(client_xi_version->major_version,
+ client_xi_version->minor_version, 2, 0);
+ /* XI 2.0: if device is grabbed, skip
+ XI 2.1: if device is grabbed by us, skip, we've already delivered */
+ return (cmp == 0) ? TRUE : SameClient(grab, client);
+}
+
+/**
+ * Deliver a raw event to the grab owner (if any) and to all root windows.
+ *
+ * Raw event delivery differs between XI 2.0 and XI 2.1.
+ * XI 2.0: events delivered to the grabbing client (if any) OR to all root
+ * windows
+ * XI 2.1: events delivered to all root windows, regardless of grabbing
+ * state.
+ */
void
DeliverRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
{
GrabPtr grab = device->deviceGrab.grab;
+ xEvent *xi;
+ int i, rc;
+ int filter;
+
+ rc = EventToXI2((InternalEvent*)ev, (xEvent**)&xi);
+ if (rc != Success)
+ {
+ ErrorF("[Xi] %s: XI2 conversion failed in %s (%d)\n",
+ __func__, device->name, rc);
+ return;
+ }
if (grab)
DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE);
- else { /* deliver to all root windows */
- xEvent *xi;
- int i;
- int filter;
- i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi);
- if (i != Success)
- {
- ErrorF("[Xi] %s: XI2 conversion failed in %s (%d)\n",
- __func__, device->name, i);
- return;
- }
+ filter = GetEventFilter(device, xi);
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ WindowPtr root;
+ InputClients *inputclients;
- filter = GetEventFilter(device, xi);
+ root = screenInfo.screens[i]->root;
+ if (!GetClientsForDelivery(device, root, xi, filter, &inputclients))
+ continue;
- for (i = 0; i < screenInfo.numScreens; i++)
- DeliverEventsToWindow(device, screenInfo.screens[i]->root, xi, 1,
- filter, NullGrab);
- free(xi);
+ for (; inputclients; inputclients = inputclients->next)
+ {
+ ClientPtr c; /* unused */
+ Mask m; /* unused */
+ InputClients ic = *inputclients;
+
+ /* Because we run through the list manually, copy the actual
+ * list, shorten the copy to only have one client and then pass
+ * that down to DeliverEventToInputClients. This way we avoid
+ * double events on XI 2.1 clients that have a grab on the
+ * device.
+ */
+ ic.next = NULL;
+
+ if (!FilterRawEvents(rClient(&ic), grab))
+ DeliverEventToInputClients(device, &ic, root, xi, 1,
+ filter, NULL, &c, &m);
+ }
}
+
+ free(xi);
}
/* If the event goes to dontClient, don't send it and return 0. if
diff --git a/include/protocol-versions.h b/include/protocol-versions.h
index 7b7a9f53c..832bcf756 100644
--- a/include/protocol-versions.h
+++ b/include/protocol-versions.h
@@ -127,7 +127,7 @@
/* X Input */
#define SERVER_XI_MAJOR_VERSION 2
-#define SERVER_XI_MINOR_VERSION 0
+#define SERVER_XI_MINOR_VERSION 1
/* XKB */
#define SERVER_XKB_MAJOR_VERSION 1