[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