Commit b58221f9 authored by Peter Hutterer's avatar Peter Hutterer Committed by Keith Packard
Browse files

dix: support the transformation matrix for relative devices.



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).

Store two separate matrices, one as requested by the client, one as the
product of [scale . matrix . inv_scale]. Depending on the type of movement,
apply the respective matrix.

For relative movements, also drop the translation component since it doesn't
really make sense to use that bit.

Input ABI 19
Signed-off-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard's avatarKeith Packard <keithp@keithp.com>
Signed-off-by: Keith Packard's avatarKeith Packard <keithp@keithp.com>
parent b173eb2a
......@@ -93,9 +93,10 @@ SOFTWARE.
static void RecalculateMasterButtons(DeviceIntPtr slave);
static void
DeviceSetTransform(DeviceIntPtr dev, float *transform)
DeviceSetTransform(DeviceIntPtr dev, float *transform_data)
{
struct pixman_f_transform scale;
struct pixman_f_transform transform;
double sx, sy;
int x, y;
......@@ -122,16 +123,21 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform)
/* transform */
for (y = 0; y < 3; y++)
for (x = 0; x < 3; x++)
dev->transform.m[y][x] = *transform++;
transform.m[y][x] = *transform_data++;
pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform);
pixman_f_transform_multiply(&dev->scale_and_transform, &scale, &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_and_transform, &dev->scale_and_transform, &scale);
/* remove translation component for relative movements */
dev->relative_transform = transform;
dev->relative_transform.m[0][2] = 0;
dev->relative_transform.m[1][2] = 0;
}
/**
......@@ -308,9 +314,10 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
/* unity matrix */
memset(transform, 0, sizeof(transform));
transform[0] = transform[4] = transform[8] = 1.0f;
dev->transform.m[0][0] = 1.0;
dev->transform.m[1][1] = 1.0;
dev->transform.m[2][2] = 1.0;
dev->relative_transform.m[0][0] = 1.0;
dev->relative_transform.m[1][1] = 1.0;
dev->relative_transform.m[2][2] = 1.0;
dev->scale_and_transform = dev->relative_transform;
XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
XIGetKnownProperty(XATOM_FLOAT), 32,
......
......@@ -1202,6 +1202,27 @@ transform(struct pixman_f_transform *m, double *x, double *y)
*y = p.v[1];
}
static void
transformRelative(DeviceIntPtr dev, ValuatorMask *mask)
{
double x = 0, y = 0;
valuator_mask_fetch_double(mask, 0, &x);
valuator_mask_fetch_double(mask, 1, &y);
transform(&dev->relative_transform, &x, &y);
if (x)
valuator_mask_set_double(mask, 0, x);
else
valuator_mask_unset(mask, 0);
if (y)
valuator_mask_set_double(mask, 1, y);
else
valuator_mask_unset(mask, 1);
}
/**
* Apply the device's transformation matrix to the valuator mask and replace
* the scaled values in mask. This transformation only applies to valuators
......@@ -1229,7 +1250,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
ox = dev->last.valuators[0];
oy = dev->last.valuators[1];
pixman_f_transform_invert(&invert, &dev->transform);
pixman_f_transform_invert(&invert, &dev->scale_and_transform);
transform(&invert, &ox, &oy);
x = ox;
......@@ -1242,7 +1263,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
if (valuator_mask_isset(mask, 1))
oy = y = valuator_mask_get_double(mask, 1);
transform(&dev->transform, &x, &y);
transform(&dev->scale_and_transform, &x, &y);
if (valuator_mask_isset(mask, 0) || ox != x)
valuator_mask_set_double(mask, 0, x);
......@@ -1403,6 +1424,8 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
set_raw_valuators(raw, &mask, raw->valuators.data);
}
else {
transformRelative(pDev, &mask);
if (flags & POINTER_ACCELERATE)
accelPointer(pDev, &mask, ms);
if ((flags & POINTER_NORAW) == 0)
......
......@@ -588,8 +588,12 @@ typedef struct _DeviceIntRec {
XIPropertyHandlerPtr handlers; /* NULL-terminated */
} properties;
/* coordinate transformation matrix for absolute input devices */
struct pixman_f_transform transform;
/* coordinate transformation matrix for relative movement. Matrix with
* the translation component dropped */
struct pixman_f_transform relative_transform;
/* scale matrix for absolute devices, this is the combined matrix of
[1/scale] . [transform] . [scale]. See DeviceSetTransform */
struct pixman_f_transform scale_and_transform;
/* XTest related master device id */
int xtest_master_id;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment