summaryrefslogtreecommitdiff
path: root/dix
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2013-02-08 14:52:02 +1000
committerKeith Packard <keithp@keithp.com>2013-02-08 09:02:57 -0800
commitb58221f9da8c549d979215271359c6cd88b5568a (patch)
tree116d142be89e85ab53422b41aabfcefa1fc18311 /dix
parentb173eb2ae3349c557db1ff9e424fa540b8289bb2 (diff)
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 <peter.hutterer@who-t.net> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'dix')
-rw-r--r--dix/devices.c21
-rw-r--r--dix/getevents.c27
2 files changed, 39 insertions, 9 deletions
diff --git a/dix/devices.c b/dix/devices.c
index 172fc0460..530f15d66 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -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,
diff --git a/dix/getevents.c b/dix/getevents.c
index 7cc8d8cb5..a4f192cf0 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -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)