[PATCH 5/5] Implement touch early accept

Chase Douglas chase.douglas at canonical.com
Thu Feb 2 16:57:58 PST 2012


From: Chase Douglas <chase.douglas at ubuntu.com>

This doesn't really implement early accept as it should. Ideally, the
server should send end events to all subsequent touch clients as soon as
an early accept comes in. However, this implementation is still protocol
compliant. We can always improve it later.

Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
---
 Xi/exevents.c   |   29 +++++++++++++++++++++++++----
 dix/touch.c     |    9 ++++-----
 include/input.h |    2 ++
 3 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 6b2db4b..d0e0a5e 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1088,6 +1088,26 @@ DeliverOneTouchEvent(ClientPtr client, DeviceIntPtr dev, TouchPointInfoPtr ti,
     return TRUE;
 }
 
+static void
+ActivateEarlyAccept(DeviceIntPtr dev, TouchPointInfoPtr ti)
+{
+    int rc;
+    ClientPtr client;
+    XID error;
+
+    rc = dixLookupClient(&client, ti->listeners[0].listener, serverClient,
+                         DixSendAccess);
+    if (rc != Success)
+    {
+        ErrorF("[Xi] Failed to lookup early accepting client.\n");
+        return;
+    }
+
+    if (AllowTouch(client, dev, XIAcceptTouch, ti->client_id,
+        ti->listeners[0].window->drawable.id, &error) != Success)
+        ErrorF("[Xi] Failed to accept touch grab after early acceptance.\n");
+}
+
 /**
  * If the current owner has rejected the event, deliver the
  * TouchOwnership/TouchBegin to the next item in the sprite stack.
@@ -1101,7 +1121,8 @@ TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
     int i, nev;
 
     /* Deliver the ownership */
-    if (ti->listeners[0].state == LISTENER_AWAITING_OWNER)
+    if (ti->listeners[0].state == LISTENER_AWAITING_OWNER ||
+        ti->listeners[0].state == LISTENER_EARLY_ACCEPT)
         DeliverTouchEvents(dev, ti, (InternalEvent*)ev, ti->listeners[0].listener);
     else if (ti->listeners[0].state == LISTENER_AWAITING_BEGIN)
         TouchEventHistoryReplay(ti, dev, ti->listeners[0].listener);
@@ -1128,6 +1149,9 @@ TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
 
     valuator_mask_free(&mask);
     FreeEventList(tel, GetMaximumEventsNum());
+
+    if (ti->listeners[0].state == LISTENER_EARLY_ACCEPT)
+        ActivateEarlyAccept(dev, ti);
 }
 
 static void
@@ -1213,9 +1237,6 @@ ProcessTouchOwnershipEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
         valuator_mask_set_double(mask, 1,
                                  valuator_mask_get_double(ti->valuators, 1));
 
-        /* FIXME: what about early acceptance? a client may accept before it
-         * owns the touch. */
-
         /* The touch owner has accepted the touch.  Send TouchEnd events to
          * everyone else, and truncate the list of listeners. */
         flags = TOUCH_ACCEPT|TOUCH_CLIENT_ID;
diff --git a/dix/touch.c b/dix/touch.c
index 1faeb7c..d7af508 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -1022,12 +1022,11 @@ AllowTouch(ClientPtr client, DeviceIntPtr dev, int mode, uint32_t touchid,
     if (i > 0)
     {
         if (mode == XIRejectTouch)
-        {
             TouchRemoveListener(ti, ti->listeners[i].listener);
-            return Success;
-        }
-        /* FIXME: Implement early accept */
-        return BadAccess;
+        else
+            ti->listeners[i].state = LISTENER_EARLY_ACCEPT;
+
+        return Success;
     }
 
     nev = GetTouchOwnershipEvents(events, dev, ti, mode,
diff --git a/include/input.h b/include/input.h
index 18119bc..c15e74a 100644
--- a/include/input.h
+++ b/include/input.h
@@ -583,6 +583,8 @@ extern _X_EXPORT void FreeInputAttributes(InputAttributes *attrs);
 enum TouchListenerState{
     LISTENER_AWAITING_BEGIN = 0,   /**< Waiting for a TouchBegin event */
     LISTENER_AWAITING_OWNER,       /**< Waiting for a TouchOwnership event */
+    LISTENER_EARLY_ACCEPT,         /**< Waiting for ownership, has already
+                                        accepted */
     LISTENER_IS_OWNER,             /**< Is the current owner */
     LISTENER_HAS_END,              /**< Has already received the end event */
 };
-- 
1.7.8.3



More information about the xorg-devel mailing list