[PATCH v3] evdev: Support the "Calibration" string option.

Peter Hutterer peter.hutterer at who-t.net
Mon Oct 12 15:40:49 PDT 2009


On Mon, Oct 12, 2009 at 04:32:51PM +0300, Oliver McFadden wrote:
> 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.
> ---
>  man/evdev.man |    5 +++++
>  src/evdev.c   |   56 ++++++++++++++++++++++++++++++++++++--------------------
>  2 files changed, 41 insertions(+), 20 deletions(-)
> 
> diff --git a/man/evdev.man b/man/evdev.man
> index 4f15062..05626b5 100644
> --- a/man/evdev.man
> +++ b/man/evdev.man
> @@ -150,6 +150,11 @@ 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.
> +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
> diff --git a/src/evdev.c b/src/evdev.c
> index 59cdd0d..d8d0f72 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -1949,12 +1949,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)))
> @@ -2027,6 +2047,20 @@ 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: Unsupported number of calibration factors: %d\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. */
> @@ -2502,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)
> -- 
> 1.6.1

ack, but I'd like to squash the following diff in before pushing, it's just
more verbosity in the man page, the error message and one minor style fix
(no {} for single-line ifs)

Cheers,
  Peter

diff --git a/man/evdev.man b/man/evdev.man
index 05626b5..e322eb6 100644
--- a/man/evdev.man
+++ b/man/evdev.man
@@ -152,8 +152,11 @@ 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.
-Property: "Evdev Axis Calibration".
+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".
@@ -183,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 70a700a..c50f1df 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -2053,13 +2053,12 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
         num_calibration = sscanf(str, "%d %d %d %d",
                                  &calibration[0], &calibration[1],
                                  &calibration[2], &calibration[3]);
-        if (num_calibration == 4) {
+        if (num_calibration == 4)
             EvdevSetCalibration(pInfo, num_calibration, calibration);
-        } else {
+        else
             xf86Msg(X_ERROR,
-                    "%s: Unsupported number of calibration factors: %d\n",
+                    "%s: Unsufficient calibration factors (%d). Ignoring calibration.\n",
                     pInfo->name, num_calibration);
-        }
     }
 
     /* Grabbing the event device stops in-kernel event forwarding. In other



More information about the xorg-devel mailing list