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) diff --git a/include/inputstr.h b/include/inputstr.h index 48a29bede..de96faeda 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -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;