[PATCH evdev] evdev: added property Evdev Axes Rotation. #27688

Oliver McFadden oliver.mcfadden at nokia.com
Thu Oct 28 23:45:36 PDT 2010


On Fri, 2010-10-29 at 15:37 +1000, ext Peter Hutterer wrote:
> On Sun, Oct 24, 2010 at 01:45:03PM +0200, Paolo D'Apice wrote:
> > The evdev driver does not allow to set a custom axes rotation
> > as the mousedrv driver does with the option "AngleOffset".
> > This option is necessary for some trackballs, for example the
> > Logitech Cordless Optical TrackMan which has the optical
> > sensor off-axes (in MS Windows, the Logitech proprietary driver
> > adjusts the offset).
> > 
> > X.Org Bug 27688 <http://bugs.freedesktop.org/show_bug.cgi?id=27688>
> > 
> > Signed-off-by: Paolo D'Apice <dapicester at gmail.com>
> 
> this patch seems simple enough that we could add it to the server as a
> standard property for pointer devices, isn't it?  I'd much prefer that so we
> don't have to re-implement it for the various drivers.
> 
> > ---
> >  include/evdev-properties.h |    4 ++++
> >  man/evdev.man              |   12 ++++++++++++
> >  src/evdev.c                |   25 +++++++++++++++++++++++++
> >  src/evdev.h                |    1 +
> >  4 files changed, 42 insertions(+), 0 deletions(-)
> > 
> > diff --git a/include/evdev-properties.h b/include/evdev-properties.h
> > index 7df2876..a658e2b 100644
> > --- a/include/evdev-properties.h
> > +++ b/include/evdev-properties.h
> > @@ -66,4 +66,8 @@
> >  /* BOOL */
> >  #define EVDEV_PROP_SWAP_AXES "Evdev Axes Swap"
> >  
> > +/* Axes Rotation */
> > +/* CARD16 */
> > +#define EVDEV_PROP_AXES_ROTATION "Evdev Axes Rotation"
> > +
> 
> note that CARD16 is unsigned, this should probably read INT16?
> 
> >  #endif
> > diff --git a/man/evdev.man b/man/evdev.man
> > index adb3f8d..f7c5e9f 100644
> > --- a/man/evdev.man
> > +++ b/man/evdev.man
> > @@ -177,6 +177,15 @@ This option has no effect on devices without absolute axes.
> >  .BI "Option \*qSwapAxes\*q \*q" Bool \*q
> >  Swap x/y axes. Default: off. Property: "Evdev Axes Swap".
> >  .TP 7
> > +.BI "Option \*qAxesRotation\*q \*q" integer \*q
> > +Clockwise axes rotation (in degrees) to apply to the pointer motion. 
> > +This transformation is applied before the 
> > +.BR SwapAxes , 
> > +.BR InvertX 
> > +and
> > +.B InvertY 
> > +transformations. Default: 0. Property: "Evdev Axes Rotation".
> > +.TP 7
> >  .BI "Option \*qXAxisMapping\*q \*q" "N1 N2" \*q
> >  Specifies which buttons are mapped to motion in the X direction in wheel
> >  emulation mode.  Button number
> > @@ -210,6 +219,9 @@ in-driver axis calibration.
> >  .BI "Evdev Axes Swap"
> >  1 boolean value (8 bit, 0 or 1). 1 swaps x/y axes.
> >  .TP 7
> > +.BI "Evdev Axes Rotation"
> > +1 16-bit positive and negative value. 0 disable rotation.
> 
> How about "1 16-bit signed value". hard to have a non-zero positive _and_
> negative value anyway :)
> 
> > +.TP 7
> >  .BI "Evdev Drag Lock Buttons"
> >  8-bit. Either 1 value or pairs of values. Value range 0-32, 0 disables a
> >  value.
> > diff --git a/src/evdev.c b/src/evdev.c
> > index 9e1fb10..fc8918e 100644
> > --- a/src/evdev.c
> > +++ b/src/evdev.c
> > @@ -47,6 +47,7 @@
> >  #include <exevents.h>
> >  #include <xorgVersion.h>
> >  #include <xkbsrv.h>
> > +#include <math.h>
> >  
> >  #ifdef HAVE_PROPERTIES
> >  #include <X11/Xatom.h>
> > @@ -114,6 +115,7 @@ static Atom prop_calibration = 0;
> >  static Atom prop_swap = 0;
> >  static Atom prop_axis_label = 0;
> >  static Atom prop_btn_label = 0;
> > +static Atom prop_axes_rotation = 0;
> >  #endif
> >  
> >  /* All devices the evdev driver has allocated and knows about.
> > @@ -383,6 +385,15 @@ EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v,
> >          int first = REL_CNT, last = 0;
> >          int i;
> >  
> > +        if (pEvdev->axes_rotation) {
> > +            float rotation = (pEvdev->axes_rotation % 360) * M_PI / 180.0; // degrees to radians 
> 
> see comment below about storing the radians.
> 
> > +            float rot_cos = cos(rotation), rot_sin = sin(rotation);
> 
> please split this line up, I read over it the first time and then got
> confused.

Perhaps also try using sincos (wrapped in ifdef _GNU_SOURCE) as the
valuators are processed quite often, so this might save a few cycles.

Although I'm only speculating about the real-world impact.

> 
> > +   
> > +            tmp = pEvdev->delta[REL_X];
> > +            pEvdev->delta[REL_X] = (int)(pEvdev->delta[REL_X] * rot_cos - pEvdev->delta[REL_Y] * rot_sin);
> > +            pEvdev->delta[REL_Y] = (int)(pEvdev->delta[REL_Y] * rot_cos + tmp * rot_sin);
> > +        }
> > +    
> >          if (pEvdev->swap_axes) {
> >              tmp = pEvdev->delta[REL_X];
> >              pEvdev->delta[REL_X] = pEvdev->delta[REL_Y];
> > @@ -2516,6 +2527,13 @@ EvdevInitProperty(DeviceIntPtr dev)
> >  
> >          XISetDevicePropertyDeletable(dev, prop_swap, FALSE);
> >  
> > +        prop_axes_rotation = MakeAtom(EVDEV_PROP_AXES_ROTATION,
> > +                strlen(EVDEV_PROP_AXES_ROTATION), TRUE);
> > +        rc = XIChangeDeviceProperty(dev, prop_axes_rotation, XA_INTEGER, 16,
> > +                PropModeReplace, 1, &pEvdev->axes_rotation, FALSE);
> > +        if (rc != Success) 
> > +            return;
> > +
> >  #ifdef HAVE_LABELS
> >          /* Axis labelling */
> >          if ((pEvdev->num_vals > 0) && (prop_axis_label = XIGetKnownProperty(AXIS_LABEL_PROP)))
> > @@ -2575,6 +2593,13 @@ EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
> >  
> >          if (!checkonly)
> >              pEvdev->swap_axes = *((BOOL*)val->data);
> > +    } else if (atom == prop_axes_rotation)
> > +    {
> > +        if (val->format != 16 || val->type != XA_INTEGER || val->size != 1)
> > +            return BadMatch;
> > +
> > +       if (!checkonly)
> > +	   pEvdev->axes_rotation = *((CARD16*)val->data);
> 
> The X server keeps track of the property value for us and thus the internal
> storage format can be arbitrary. I'd say it's better to calculate the
> radians here and store that so we only do it once per configuration, not
> once per event.
> 
> Cheers,
>   Peter
> 
> >      } else if (atom == prop_axis_label || atom == prop_btn_label)
> >          return BadAccess; /* Axis/Button labels can't be changed */
> >  
> > diff --git a/src/evdev.h b/src/evdev.h
> > index b382670..17d607a 100644
> > --- a/src/evdev.h
> > +++ b/src/evdev.h
> > @@ -129,6 +129,7 @@ typedef struct {
> >      BOOL swap_axes;
> >      BOOL invert_x;
> >      BOOL invert_y;
> > +    int axes_rotation;
> >  
> >      int delta[REL_CNT];
> >      unsigned int abs, rel;
> > -- 
> > 1.7.1
> > 
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel




More information about the xorg-devel mailing list