summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/evdev-properties.h4
-rw-r--r--man/evdev.man5
-rw-r--r--src/evdev.c50
-rw-r--r--src/evdev.h7
4 files changed, 66 insertions, 0 deletions
diff --git a/include/evdev-properties.h b/include/evdev-properties.h
index 89f25f1..be4307b 100644
--- a/include/evdev-properties.h
+++ b/include/evdev-properties.h
@@ -58,4 +58,8 @@
/* CARD8 */
#define EVDEV_PROP_REOPEN "Evdev Reopen Attempts"
+/* Run-time calibration */
+/* CARD32, 4 values [minx, maxx, miny, maxy], or no values for unset */
+#define EVDEV_PROP_CALIBRATION "Evdev Axis Calibration"
+
#endif
diff --git a/man/evdev.man b/man/evdev.man
index 9d336fc..fc8a96a 100644
--- a/man/evdev.man
+++ b/man/evdev.man
@@ -186,6 +186,11 @@ value.
.TP 7
.BI "Evdev Axis Inversion"
2 boolean values (8 bit, 0 or 1), order X, Y. 1 inverts the axis.
+.BI "Evdev Axis Calibration"
+4 32-bit values, order min-x, max-x, min-y, max-y or 0 values to disable
+run-time axis calibration. This feature is required for devices that need to
+scale to a different coordinate system than originally reported to the X
+server, such as touchscreens that require run-time calibration.
.SH AUTHORS
Kristian Høgsberg.
diff --git a/src/evdev.c b/src/evdev.c
index 9ef2829..aa8a10d 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -76,6 +76,7 @@
#define EVDEV_TOUCHPAD (1 << 4)
#define EVDEV_INITIALIZED (1 << 5) /* WheelInit etc. called already? */
#define EVDEV_TOUCHSCREEN (1 << 6)
+#define EVDEV_CALIBRATED (1 << 7) /* run-time calibrated? */
#define MIN_KEYCODE 8
#define GLYPHS_PER_KEY 2
@@ -107,6 +108,7 @@ static int EvdevSetProperty(DeviceIntPtr dev, Atom atom,
XIPropertyValuePtr val, BOOL checkonly);
static Atom prop_invert = 0;
static Atom prop_reopen = 0;
+static Atom prop_calibration = 0;
#endif
@@ -387,6 +389,17 @@ EvdevReadInput(InputInfoPtr pInfo)
int abs_x, abs_y;
abs_x = pEvdev->abs_x;
abs_y = pEvdev->abs_y;
+
+ if (pEvdev->flags & EVDEV_CALIBRATED)
+ {
+ abs_x = xf86ScaleAxis(abs_x,
+ pEvdev->max_x, pEvdev->min_x,
+ pEvdev->calibration.max_x, pEvdev->calibration.min_x);
+ abs_y = xf86ScaleAxis(abs_y,
+ pEvdev->max_y, pEvdev->min_y,
+ pEvdev->calibration.max_y, pEvdev->calibration.min_y);
+ }
+
if (pEvdev->invert_x)
abs_x = pEvdev->max_x - (abs_x - pEvdev->min_x);
if (pEvdev->invert_y)
@@ -1542,6 +1555,16 @@ EvdevInitProperty(DeviceIntPtr dev)
return;
XISetDevicePropertyDeletable(dev, prop_reopen, FALSE);
+
+
+ prop_calibration = MakeAtom(EVDEV_PROP_CALIBRATION,
+ strlen(EVDEV_PROP_CALIBRATION), TRUE);
+ rc = XIChangeDeviceProperty(dev, prop_calibration, XA_INTEGER, 32,
+ PropModeReplace, 0, NULL, FALSE);
+ if (rc != Success)
+ return;
+
+ XISetDevicePropertyDeletable(dev, prop_calibration, FALSE);
}
static int
@@ -1570,6 +1593,33 @@ EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
if (!checkonly)
pEvdev->reopen_attempts = *((CARD8*)val->data);
+ } else if (atom == prop_calibration)
+ {
+ if (val->format != 32 || val->type != XA_INTEGER)
+ return BadMatch;
+ if (val->size != 4 && val->size != 0)
+ return BadMatch;
+
+ if (!checkonly)
+ {
+ if (val->size == 0)
+ {
+ pEvdev->flags &= ~EVDEV_CALIBRATED;
+ pEvdev->calibration.min_x = 0;
+ pEvdev->calibration.max_x = 0;
+ pEvdev->calibration.min_y = 0;
+ pEvdev->calibration.max_y = 0;
+ } else if (val->size == 4)
+ {
+ CARD32 *vals = (CARD32*)val->data;
+
+ pEvdev->flags |= EVDEV_CALIBRATED;
+ pEvdev->calibration.min_x = vals[0];
+ pEvdev->calibration.max_x = vals[1];
+ pEvdev->calibration.min_y = vals[2];
+ pEvdev->calibration.max_y = vals[3];
+ }
+ }
}
return Success;
diff --git a/src/evdev.h b/src/evdev.h
index 5a97185..5696978 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -102,6 +102,13 @@ typedef struct {
Time expires; /* time of expiry */
Time timeout;
} emulateWheel;
+ /* run-time calibration */
+ struct {
+ int min_x;
+ int max_x;
+ int min_y;
+ int max_y;
+ } calibration;
unsigned char btnmap[32]; /* config-file specified button mapping */