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

Chase Douglas chase.douglas at canonical.com
Mon Dec 19 19:01:25 PST 2011


On Dec 14, 2011, at 7:02 PM, Peter Hutterer <peter.hutterer at who-t.net> wrote:
> 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. */

Why? I can't remember why we would want to prefer a touch sprite, in which case we can simplify the next dozen lines.

> +    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));

Calling calloc on every touch begin seems inefficient, perhaps we should add a FIXME: reuse touch point listeners array note for the future?

> +    if (!ti->listeners)
> +    {
> +        sprite->spriteTraceGood = 0;
> +        return FALSE;
> +    }
> +    ti->num_listeners = 0;
> +
> +    return TRUE;
> +}

-- Chase


More information about the xorg-devel mailing list