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

Peter Hutterer peter.hutterer at who-t.net
Tue Dec 20 15:32:29 PST 2011


On Mon, Dec 19, 2011 at 07:01:25PM -0800, Chase Douglas wrote:
> 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.

Daniel? This is still leftover code from your original patch. My suspicion
is that it's outdated from some point in the past when we sent all touches
to the same window. I'll just remove it.

> > +    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?

it's going to be either calloc or realloc if we re-use it unless we
pre-alloc with MAX_WINDOW_DEPTH (or whatever the define name is). This
alloc happens only on touch begin and the array itself is relatively small,
I doubt this is much of a performance issues.

Cheers,
  Peter

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


More information about the xorg-devel mailing list