[PATCH 3/3] dix: support the transformation matrix for relative devices.
Peter Hutterer
peter.hutterer at who-t.net
Thu Jun 2 18:27:22 PDT 2011
On Thu, Jun 02, 2011 at 03:44:15PM +0200, Simon Thum wrote:
> 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.
Then we need to zero it out on-the-fly since a device may have the same
transformation matrix (for rotation for example) but the coordinates it
sends may be either abs or relative.
> 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.
I think having the acceleration apply after transformation ensures
consistency - the acceleration of the "left" movement of the pointer is
always the same. I can be convinced otherwise though.
also, aiui, if the transformation applies before accel, we can merge this
patch - the issues pointed out below apply to "accel before transform"
only.
> 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:
correct me if I'm wrong here but the current accel code seems to also assume
a unified resolution. the higher the device's resolution, the higher the
mickeys (and thus the acceleration) but I didn't see anything in the accel
code that takes this into account. this may be something worth looking into
as well.
> 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.
I believe Daniel has a set of patches to do exactly that but they haven't
been on the list yet.
> 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.
The big advantage we have with properties is that we are not locked into a
single format. We can switch the matrix to support float format in the
future while still supporting an integer matrix as well.
Cheers,
Peter
> > 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