summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stone <daniel@fooishbar.org>2011-12-14 16:03:01 +1000
committerChase Douglas <chase.douglas@canonical.com>2011-12-21 10:34:11 -0800
commiteaaff49a0fe56e87a8b3e57d7742601fb8ca26c1 (patch)
tree1337e6360c736e610922c647cd26c155259ae06b
parentd877022c852976c8b0b072d8388ede068bd31998 (diff)
dix: add helper functions to build up/verify the sprite trace
Touch events' sprite trace stays the same for the duration of the touch sequence. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Chase Douglas <chase.douglas@canonical.com> Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
-rw-r--r--dix/touch.c87
-rw-r--r--include/input.h4
2 files changed, 91 insertions, 0 deletions
diff --git a/dix/touch.c b/dix/touch.c
index 792ebcdd7..0f2c0c335 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -506,3 +506,90 @@ TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource)
/* FIXME: deliver the event */
}
}
+
+Bool
+TouchBuildDependentSpriteTrace(DeviceIntPtr dev, SpritePtr sprite)
+{
+ int i;
+ TouchClassPtr t = dev->touch;
+ WindowPtr *trace;
+ SpritePtr srcsprite;
+
+ /* All touches should have the same sprite trace, so 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 (!TouchBuildDependentSpriteTrace(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 8ce5f2b9d..f1615cf44 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 TouchBuildDependentSpriteTrace(DeviceIntPtr dev, SpritePtr sprite);
+
/* misc event helpers */
extern Mask GetEventMask(DeviceIntPtr dev, xEvent* ev, InputClientsPtr clients);
extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event);