diff options
-rw-r--r-- | include/evdev-properties.h | 4 | ||||
-rw-r--r-- | man/evdev.man | 5 | ||||
-rw-r--r-- | src/evdev.c | 50 | ||||
-rw-r--r-- | src/evdev.h | 7 |
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 */ |