[PATCH 3/3] dix: support the transformation matrix for relative devices.

Simon Thum simon.thum at gmx.de
Thu Jun 2 06:44:15 PDT 2011


On 05/31/2011 05:57 AM, Peter Hutterer wrote:
> The transformation matrix we previously stored was a scaled matrix based on
> the axis ranges of the device. For relative movements, the scaling is not
> required (or desired).
Well, also any non-zero translating component will kill the mouse. That
also should be zeroed out in the relative transform matrix (which I'd
name after the purpose). In principle that matrix would be 2x2.

Now for scaling or rotation you'll need sub-pixel processing, or it will
only work properly with orthogonal angles and integer scale. Also I'd
say the transform should be applied after acceleration, but arguments
can be made for any order. My argument would be that acceleration has
been built on the assumption that the input "is" integer mickeys more or
less straight from the device, and the remainder is more or less private
stuff. Without descending into qualia considerations, there are three
solutions:

1 ) Base accel on float mickeys/deltas, and choose any order
2 ) First accel, then transform valuator + remainder (without setting
the latter again, i.e. you need one more row of remainders and base your
events on that)
3 ) Make the valuator masks double (or add FP val masks), and expose
them to drivers and accel and you-name-it.

OK, 3) is actually 1) on steroids, but it's unavoidable in the long run,
if you ask me. 2) is the fix for now.

So the most viable order would be 2-1-3 (too lazy to reshuffle). In any
case I'd feel better if you didn't push this patch. I think I'm
available enough these times to at least support that roadmap.

Cheers,

Simon


> 
> Store two separate matrices, one scaled, one unmodified. Depending on the
> type of movement, apply the respective matrix.
> 
> This breaks the DeviceIntRec ABI
> 
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
>  dix/devices.c      |    4 ++--
>  dix/getevents.c    |   26 +++++++++++++++++++++++++-
>  include/inputstr.h |    5 ++++-
>  3 files changed, 31 insertions(+), 4 deletions(-)
> 
> diff --git a/dix/devices.c b/dix/devices.c
> index 0ccf252..4e4b702 100644
> --- a/dix/devices.c
> +++ b/dix/devices.c
> @@ -125,14 +125,14 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform)
>          for (x=0; x<3; x++)
>              dev->transform.m[y][x] = *transform++;
>  
> -    pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform);
> +    pixman_f_transform_multiply(&dev->scale, &scale, &dev->transform);
>  
>      /* scale */
>      pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy);
>      scale.m[0][2] = -dev->valuator->axes[0].min_value / sx;
>      scale.m[1][2] = -dev->valuator->axes[1].min_value / sy;
>  
> -    pixman_f_transform_multiply(&dev->transform, &dev->transform, &scale);
> +    pixman_f_transform_multiply(&dev->scale, &dev->scale, &scale);
>  }
>  
>  /**
> diff --git a/dix/getevents.c b/dix/getevents.c
> index 1352a81..26c7f5d 100644
> --- a/dix/getevents.c
> +++ b/dix/getevents.c
> @@ -1066,6 +1066,28 @@ transform(struct pixman_f_transform *m, int *x, int *y)
>      *y = lround(p.v[1]);
>  }
>  
> +
> +static void
> +transformRelative(DeviceIntPtr dev, ValuatorMask *mask)
> +{
> +    int x, y;
> +
> +    x = valuator_mask_isset(mask, 0) ? valuator_mask_get(mask, 0) : 0;
> +    y = valuator_mask_isset(mask, 1) ? valuator_mask_get(mask, 1) : 0;
> +
> +    transform(&dev->transform, &x, &y);
> +
> +    if (x)
> +        valuator_mask_set(mask, 0, x);
> +    else
> +        valuator_mask_unset(mask, 0);
> +
> +    if (y)
> +        valuator_mask_set(mask, 1, y);
> +    else
> +        valuator_mask_unset(mask, 1);
> +}
> +
>  static void
>  transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
>  {
> @@ -1076,7 +1098,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
>      oy = y = valuator_mask_isset(mask, 1) ? valuator_mask_get(mask, 1) :
>                                              dev->last.valuators[1];
>  
> -    transform(&dev->transform, &x, &y);
> +    transform(&dev->scale, &x, &y);
>  
>      if (valuator_mask_isset(mask, 0) || ox != x)
>          valuator_mask_set(mask, 0, x);
> @@ -1200,6 +1222,8 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons
>          transformAbsolute(pDev, &mask);
>          moveAbsolute(pDev, &x, &y, &mask);
>      } else {
> +        transformRelative(pDev, &mask);
> +
>          if (flags & POINTER_ACCELERATE) {
>              accelPointer(pDev, &mask, ms);
>              /* The pointer acceleration code modifies the fractional part
> diff --git a/include/inputstr.h b/include/inputstr.h
> index 00f72c2..b917f6c 100644
> --- a/include/inputstr.h
> +++ b/include/inputstr.h
> @@ -530,8 +530,11 @@ typedef struct _DeviceIntRec {
>          XIPropertyHandlerPtr handlers; /* NULL-terminated */
>      } properties;
>  
> -    /* coordinate transformation matrix for absolute input devices */
> +    /* coordinate transformation matrix */
>      struct pixman_f_transform transform;
> +    /* scale matrix for absolute devices, this is the combined matrix of
> +       [1/scale] . [transform] . [scale]. See DeviceSetTransform */
> +    struct pixman_f_transform scale;
>  
>      /* XTest related master device id */
>      int xtest_master_id;



More information about the xorg-devel mailing list