From 33eb36f26663c09c873acede1b35e91ef4c64479 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 30 Oct 2008 16:55:29 +1030 Subject: Add support for run-time calibration. Some devices require run-time axis calibration. We can't change the min/max ranges once we've initialised the valuator structs though, so in-driver run-time calibration is required. If the property is set, the driver scales from the calibrated range to the values reported to the X server (which then may scale to screen coordinates). If the property is not set (i.e. zero items) no scaling is performed. --- src/evdev.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/evdev.h | 7 +++++++ 2 files changed, 57 insertions(+) (limited to 'src') 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 */ -- cgit v1.2.3