[PATCH 24/42] dix: add helper functions to build up/verify the sprite trace

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


From: Daniel Stone <daniel at fooishbar.org>

Touch events' sprite trace stays the same for the duration of the touch
sequence.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 dix/touch.c     |   87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/input.h |    4 ++
 2 files changed, 91 insertions(+), 0 deletions(-)

diff --git a/dix/touch.c b/dix/touch.c
index 78c50cf..90349bd 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -500,3 +500,90 @@ TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource)
         /* FIXME: deliver the event */
     }
 }
+
+Bool
+TouchBuildSpriteTrace(DeviceIntPtr dev, SpritePtr sprite)
+{
+    int i;
+    TouchClassPtr t = dev->touch;
+    WindowPtr *trace;
+    SpritePtr srcsprite;
+
+    /* Find and reuse an existing touch's sprite if possible, else use the
+     * device's sprite. */
+    for (i = 0; i < t->num_touches; i++)
+        if (t->touches[i].sprite.spriteTraceGood > 0)
+            break;
+    if (i < t->num_touches)
+        srcsprite = &t->touches[i].sprite;
+    else if (dev->spriteInfo->sprite)
+        srcsprite = dev->spriteInfo->sprite;
+    else
+        return FALSE;
+
+    if (srcsprite->spriteTraceGood > sprite->spriteTraceSize)
+    {
+        trace = realloc(sprite->spriteTrace,
+                srcsprite->spriteTraceSize * sizeof(*trace));
+        if (!trace)
+        {
+            sprite->spriteTraceGood = 0;
+            return FALSE;
+        }
+        sprite->spriteTrace = trace;
+        sprite->spriteTraceSize = srcsprite->spriteTraceGood;
+    }
+    memcpy(sprite->spriteTrace, srcsprite->spriteTrace,
+            srcsprite->spriteTraceGood * sizeof(*trace));
+    sprite->spriteTraceGood = srcsprite->spriteTraceGood;
+
+    return TRUE;
+}
+
+/**
+ * Ensure a window trace is present in ti->sprite, constructing one for
+ * TouchBegin events.
+ */
+Bool
+TouchEnsureSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti,
+                  InternalEvent *ev)
+{
+    TouchClassPtr t = sourcedev->touch;
+    SpritePtr sprite = &ti->sprite;
+
+    /* We may not have a sprite if there are no applicable grabs or
+     * event selections, or if they've disappeared, or if all the grab
+     * owners have rejected the touch.  Don't bother delivering motion
+     * events if not, but TouchEnd events still need to be processed so
+     * we can call FinishTouchPoint and release it for later use. */
+    if (ev->any.type == ET_TouchEnd)
+        return TRUE;
+    else if (ev->any.type != ET_TouchBegin)
+        return (sprite->spriteTraceGood > 0);
+
+    if (t->mode == XIDirectTouch)
+    {
+        /* Focus immediately under the touchpoint in direct touch mode.
+         * XXX: Do we need to handle crossing screens here? */
+        sprite->spriteTrace[0] =
+            sourcedev->spriteInfo->sprite->hotPhys.pScreen->root;
+        XYToWindow(sprite, ev->device_event.root_x, ev->device_event.root_y);
+    }
+    else if (!TouchBuildSpriteTrace(sourcedev, sprite))
+        return FALSE;
+
+    if (sprite->spriteTraceGood <= 0)
+        return FALSE;
+
+    /* Mark which grabs/event selections we're delivering to: max one grab per
+     * window plus the bottom-most event selection. */
+    ti->listeners = calloc(sprite->spriteTraceGood + 1, sizeof(*ti->listeners));
+    if (!ti->listeners)
+    {
+        sprite->spriteTraceGood = 0;
+        return FALSE;
+    }
+    ti->num_listeners = 0;
+
+    return TRUE;
+}
diff --git a/include/input.h b/include/input.h
index 8ce5f2b..897f1d7 100644
--- a/include/input.h
+++ b/include/input.h
@@ -612,6 +612,10 @@ extern void TouchEventHistoryFree(TouchPointInfoPtr ti);
 extern void TouchEventHistoryPush(TouchPointInfoPtr ti, const DeviceEvent *ev);
 extern void TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource);
 
+extern Bool TouchEnsureSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti,
+                              InternalEvent *ev);
+extern Bool TouchBuildSpriteTrace(DeviceIntPtr dev, SpritePtr sprite);
+
 /* misc event helpers */
 extern Mask GetEventMask(DeviceIntPtr dev, xEvent* ev, InputClientsPtr clients);
 extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event);
-- 
1.7.7.1



More information about the xorg-devel mailing list