summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xi/xiproperty.c4
-rw-r--r--dix/devices.c71
-rw-r--r--dix/getevents.c19
-rw-r--r--include/inputstr.h4
-rw-r--r--include/xserver-properties.h7
5 files changed, 104 insertions, 1 deletions
diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index 8bb19624c..b4d939f99 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -177,7 +177,9 @@ static struct dev_properties
{0, BTN_LABEL_PROP_BTN_TOOL_TRIPLETAP},
{0, BTN_LABEL_PROP_BTN_GEAR_DOWN},
- {0, BTN_LABEL_PROP_BTN_GEAR_UP}
+ {0, BTN_LABEL_PROP_BTN_GEAR_UP},
+
+ {0, XI_PROP_TRANSFORM}
};
static long XIPropHandlerID = 1;
diff --git a/dix/devices.c b/dix/devices.c
index cf23bc6d0..b0b465326 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -77,6 +77,8 @@ SOFTWARE.
#include <X11/extensions/XI.h>
#include <X11/extensions/XI2.h>
#include <X11/extensions/XIproto.h>
+#include <math.h>
+#include <pixman.h>
#include "exglobals.h"
#include "exevents.h"
#include "xiquerydevice.h" /* for SizeDeviceClasses */
@@ -91,6 +93,48 @@ SOFTWARE.
static void RecalculateMasterButtons(DeviceIntPtr slave);
+static void
+DeviceSetTransform(DeviceIntPtr dev, float *transform)
+{
+ struct pixman_f_transform scale;
+ double sx, sy;
+ int x, y;
+
+ /**
+ * calculate combined transformation matrix:
+ *
+ * M = InvScale * Transform * Scale
+ *
+ * So we can later transform points using M * p
+ *
+ * Where:
+ * Scale scales coordinates into 0..1 range
+ * Transform is the user supplied (affine) transform
+ * InvScale scales coordinates back up into their native range
+ */
+ sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value;
+ sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value;
+
+ /* invscale */
+ pixman_f_transform_init_scale(&scale, sx, sy);
+ scale.m[0][2] = dev->valuator->axes[0].min_value;
+ scale.m[1][2] = dev->valuator->axes[1].min_value;
+
+ /* transform */
+ for (y=0; y<3; y++)
+ for (x=0; x<3; x++)
+ dev->transform.m[y][x] = *transform++;
+
+ pixman_f_transform_multiply(&dev->transform, &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);
+}
+
/**
* DIX property handler.
*/
@@ -115,6 +159,21 @@ DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
else if (!(*((CARD8*)prop->data)) && dev->enabled)
DisableDevice(dev, TRUE);
}
+ } else if (property == XIGetKnownProperty(XI_PROP_TRANSFORM))
+ {
+ float *f = (float*)prop->data;
+ int i;
+
+ if (prop->format != 32 || prop->size != 9 ||
+ prop->type != XIGetKnownProperty(XATOM_FLOAT))
+ return BadValue;
+
+ for (i=0; i<9; i++)
+ if (!isfinite(f[i]))
+ return BadValue;
+
+ if (!checkonly)
+ DeviceSetTransform(dev, f);
}
return Success;
@@ -183,6 +242,7 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
int devid;
char devind[MAXDEVICES];
BOOL enabled;
+ float transform[9];
/* Find next available id, 0 and 1 are reserved */
memset(devind, 0, sizeof(char)*MAXDEVICES);
@@ -234,6 +294,17 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
XA_INTEGER, 8, PropModeReplace, 1, &enabled,
FALSE);
XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_ENABLED), FALSE);
+
+ /* unity matrix */
+ memset(transform, 0, sizeof(transform));
+ transform[0] = transform[4] = transform[8] = 1.0f;
+
+ XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
+ XIGetKnownProperty(XATOM_FLOAT), 32,
+ PropModeReplace, 9, transform, FALSE);
+ XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
+ FALSE);
+
XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL, NULL);
return dev;
diff --git a/dix/getevents.c b/dix/getevents.c
index 62aaff981..eeef41448 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -33,6 +33,7 @@
#include <X11/X.h>
#include <X11/keysym.h>
#include <X11/Xproto.h>
+#include <math.h>
#include "misc.h"
#include "resource.h"
@@ -56,6 +57,7 @@
#include <X11/extensions/XI.h>
#include <X11/extensions/XIproto.h>
+#include <pixman.h>
#include "exglobals.h"
#include "exevents.h"
#include "exglobals.h"
@@ -997,6 +999,22 @@ FreeEventList(EventListPtr list, int num_events)
free(list);
}
+static void
+transformAbsolute(DeviceIntPtr dev, int v[MAX_VALUATORS])
+{
+ struct pixman_f_vector p;
+
+ /* p' = M * p in homogeneous coordinates */
+ p.v[0] = v[0];
+ p.v[1] = v[1];
+ p.v[2] = 1.0;
+
+ pixman_f_transform_point(&dev->transform, &p);
+
+ v[0] = lround(p.v[0]);
+ v[1] = lround(p.v[1]);
+}
+
/**
* Generate a series of xEvents (filled into the EventList) representing
* pointer motion, or button presses. Xi and XKB-aware.
@@ -1068,6 +1086,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
scr->height);
}
+ transformAbsolute(pDev, valuators);
moveAbsolute(pDev, &x, &y, first_valuator, num_valuators, valuators);
} else {
if (flags & POINTER_ACCELERATE) {
diff --git a/include/inputstr.h b/include/inputstr.h
index c5b9ff71a..a83e863be 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -49,6 +49,7 @@ SOFTWARE.
#ifndef INPUTSTRUCT_H
#define INPUTSTRUCT_H
+#include <pixman.h>
#include "input.h"
#include "window.h"
#include "dixstruct.h"
@@ -550,6 +551,9 @@ typedef struct _DeviceIntRec {
XIPropertyPtr properties;
XIPropertyHandlerPtr handlers; /* NULL-terminated */
} properties;
+
+ /* coordinate transformation matrix for absolute input devices */
+ struct pixman_f_transform transform;
} DeviceIntRec;
typedef struct {
diff --git a/include/xserver-properties.h b/include/xserver-properties.h
index 30e8efb68..c6259aee1 100644
--- a/include/xserver-properties.h
+++ b/include/xserver-properties.h
@@ -35,6 +35,13 @@
/* BOOL. If present, device is a virtual XTEST device */
#define XI_PROP_XTEST_DEVICE "XTEST Device"
+/* Coordinate transformation matrix for absolute input devices
+ * FLOAT, 9 values in row-major order, coordinates in 0..1 range:
+ * [c0 c1 c2] [x]
+ * [c3 c4 c5] * [y]
+ * [c6 c7 c8] [1] */
+#define XI_PROP_TRANSFORM "Coordinate Transformation Matrix"
+
/* Pointer acceleration properties */
/* INTEGER of any format */
#define ACCEL_PROP_PROFILE_NUMBER "Device Accel Profile"