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.
master
Peter Hutterer 18 years ago
parent d5cf24d3f0
commit 33eb36f266
  1. 4
      include/evdev-properties.h
  2. 5
      man/evdev.man
  3. 50
      src/evdev.c
  4. 7
      src/evdev.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

@ -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.

@ -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;

@ -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 */

Loading…
Cancel
Save