summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/evdev.man12
-rw-r--r--src/evdev.c55
2 files changed, 44 insertions, 23 deletions
diff --git a/man/evdev.man b/man/evdev.man
index 4f15062..e322eb6 100644
--- a/man/evdev.man
+++ b/man/evdev.man
@@ -150,6 +150,14 @@ be set in the configuration.
Number of reopen attempts after a read error occurs on the device (e.g. after
waking up from suspend). In between each attempt is a 100ms wait. Default: 10.
.TP 7
+.BI "Option \*qCalibration\*q \*q" "min-x max-x min-y max-y" \*q
+Calibrates the X and Y axes for devices that need to scale to a different
+coordinate system than reported to the X server. This feature is required
+for devices that need to scale to a different coordinate system than
+originally reported by the kernel (e.g. touchscreens). The scaling to the
+custom coordinate system is done in-driver and the X server is unaware of
+the transformation. Property: "Evdev Axis Calibration".
+.TP 7
.BI "Option \*qSwapAxes\*q \*q" Bool \*q
Swap x/y axes. Default: off. Property: "Evdev Axes Swap".
.TP 7
@@ -178,9 +186,7 @@ driver.
.TP 7
.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.
+in-driver axis calibration.
.TP 7
.BI "Evdev Axis Inversion"
2 boolean values (8 bit, 0 or 1), order X, Y. 1 inverts the axis.
diff --git a/src/evdev.c b/src/evdev.c
index 2ffa412..ff69197 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1950,12 +1950,32 @@ EvdevProbe(InputInfoPtr pInfo)
return 0;
}
+static void
+EvdevSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4])
+{
+ EvdevPtr pEvdev = pInfo->private;
+
+ if (num_calibration == 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 (num_calibration == 4) {
+ pEvdev->flags |= EVDEV_CALIBRATED;
+ pEvdev->calibration.min_x = calibration[0];
+ pEvdev->calibration.max_x = calibration[1];
+ pEvdev->calibration.min_y = calibration[2];
+ pEvdev->calibration.max_y = calibration[3];
+ }
+}
static InputInfoPtr
EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
{
InputInfoPtr pInfo;
- const char *device;
+ const char *device, *str;
+ int num_calibration = 0, calibration[4] = { 0, 0, 0, 0 };
EvdevPtr pEvdev;
if (!(pInfo = xf86AllocateInput(drv, 0)))
@@ -2028,6 +2048,19 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
pEvdev->invert_y = xf86SetBoolOption(pInfo->options, "InvertY", FALSE);
pEvdev->swap_axes = xf86SetBoolOption(pInfo->options, "SwapAxes", FALSE);
+ str = xf86CheckStrOption(pInfo->options, "Calibration", NULL);
+ if (str) {
+ num_calibration = sscanf(str, "%d %d %d %d",
+ &calibration[0], &calibration[1],
+ &calibration[2], &calibration[3]);
+ if (num_calibration == 4)
+ EvdevSetCalibration(pInfo, num_calibration, calibration);
+ else
+ xf86Msg(X_ERROR,
+ "%s: Insufficient calibration factors (%d). Ignoring calibration\n",
+ pInfo->name, num_calibration);
+ }
+
/* Grabbing the event device stops in-kernel event forwarding. In other
words, it disables rfkill and the "Macintosh mouse button emulation".
Note that this needs a server that sets the console to RAW mode. */
@@ -2503,25 +2536,7 @@ EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
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];
- }
- }
+ EvdevSetCalibration(pInfo, val->size, val->data);
} else if (atom == prop_swap)
{
if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)