From 57b54ee3995f2f678ef359e7663cad517a8b2433 Mon Sep 17 00:00:00 2001 From: Oliver McFadden Date: Mon, 12 Oct 2009 16:32:51 +0300 Subject: evdev: Support the "Calibration" string option. Originally based on a patch from Daniel Stone, this commit allows for the calibration factors to be set either from Xorg.conf or via HAL. Previously the only way was via the properties interface. Signed-off-by: Peter Hutterer --- man/evdev.man | 12 +++++++++--- src/evdev.c | 55 +++++++++++++++++++++++++++++++++++-------------------- 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) -- cgit v1.2.3