[PATCH 40/42] dix: Remove touch grabs if the grab disappears

Peter Hutterer peter.hutterer at who-t.net
Wed Dec 14 19:02:17 PST 2011


From: Daniel Stone <daniel at fooishbar.org>

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 dix/grabs.c     |    3 +++
 dix/touch.c     |   41 +++++++++++++++++++++++++++++++++++++++++
 include/input.h |    1 +
 3 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/dix/grabs.c b/dix/grabs.c
index da014df..701470c 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -266,6 +266,9 @@ CreateGrab(
 void
 FreeGrab(GrabPtr pGrab)
 {
+    if (pGrab->grabtype == XI2 && pGrab->type == XI_TouchBegin)
+        TouchListenerGone(pGrab->resource);
+
     free(pGrab->modifiersDetail.pMask);
     free(pGrab->detail.pMask);
 
diff --git a/dix/touch.c b/dix/touch.c
index 85d0041..08dc960 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -37,6 +37,7 @@
 #include "inpututils.h"
 #include "eventconvert.h"
 #include "windowstr.h"
+#include "mi.h"
 
 #define TOUCH_HISTORY_SIZE 100
 
@@ -931,3 +932,43 @@ TouchRemovePointerGrab(DeviceIntPtr dev)
         return;
 }
 
+/* As touch grabs don't turn into active grabs with their own resources, we
+ * need to walk all the touches and remove this grab from any delivery
+ * lists. */
+void
+TouchListenerGone(XID resource)
+{
+    TouchPointInfoPtr ti;
+    DeviceIntPtr dev;
+    InternalEvent *events = InitEventList(GetMaximumEventsNum());
+    int i, j, k, nev;
+
+    if (!events)
+        FatalError("TouchListenerGone: couldn't allocate events\n");
+
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+        if (!dev->touch)
+            continue;
+
+        for (i = 0; i < dev->touch->num_touches; i++)
+        {
+            ti = &dev->touch->touches[i];
+            if (!ti->active)
+                continue;
+
+            for (j = 0; j < ti->num_listeners; j++)
+            {
+                if (ti->listeners[j].listener != resource)
+                    continue;
+
+                nev = GetTouchOwnershipEvents(events, dev, ti, XIRejectTouch,
+                                              resource, 0);
+                for (k = 0; k < nev; k++)
+                    mieqProcessDeviceEvent(dev, events + k, NULL);
+
+                break;
+            }
+        }
+    }
+}
diff --git a/include/input.h b/include/input.h
index d294398..f95956c 100644
--- a/include/input.h
+++ b/include/input.h
@@ -623,6 +623,7 @@ extern int TouchConvertToPointerEvent(const InternalEvent *ev,
                                       InternalEvent *motion, InternalEvent *button);
 extern int TouchGetPointerEventType(const InternalEvent *ev);
 extern void TouchRemovePointerGrab(DeviceIntPtr dev);
+extern void TouchListenerGone(XID resource);
 
 /* misc event helpers */
 extern Mask GetEventMask(DeviceIntPtr dev, xEvent* ev, InputClientsPtr clients);
-- 
1.7.7.1



More information about the xorg-devel mailing list