From 6449456d5fd4932c9cc246d9c158b5cf2341a118 Mon Sep 17 00:00:00 2001 From: Paolo D'Apice Date: Mon, 14 Feb 2011 16:33:13 +0800 Subject: [PATCH] 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 Signed-off-by: Paolo D'Apice --- include/evdev-properties.h | 4 ++++ man/evdev.man | 12 ++++++++++++ src/evdev.c | 28 ++++++++++++++++++++++++++++ src/evdev.h | 3 ++- 4 files changed, 46 insertions(+), 1 deletions(-) diff --git a/include/evdev-properties.h b/include/evdev-properties.h index 16f2af7..9457706 100644 --- a/include/evdev-properties.h +++ b/include/evdev-properties.h @@ -66,6 +66,10 @@ /* BOOL */ #define EVDEV_PROP_SWAP_AXES "Evdev Axes Swap" +/* Axes Rotation */ +/* INT16 */ +#define EVDEV_PROP_AXES_ROTATION "Evdev Axes Rotation" + /* BOOL */ #define EVDEV_PROP_THIRDBUTTON "Evdev Third Button Emulation" /* CARD32 */ diff --git a/man/evdev.man b/man/evdev.man index 931e1a1..c5cfe9d 100644 --- a/man/evdev.man +++ b/man/evdev.man @@ -202,6 +202,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 @@ -235,6 +244,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 signed value. 0 disable rotation. +.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 bb30655..84a5970 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -113,6 +114,7 @@ static Atom prop_calibration; static Atom prop_swap; static Atom prop_axis_label; static Atom prop_btn_label; +static Atom prop_axes_rotation; /* All devices the evdev driver has allocated and knows about. * MAXDEVICES is safe as null-terminated array, as two devices (VCP and VCK) @@ -386,6 +388,14 @@ EvdevProcessValuators(InputInfoPtr pInfo) if (pEvdev->rel_queued) { int i; + if (pEvdev->axes_rotation) { + float cosine = cos(pEvdev->axes_rotation); + float sine = sin(pEvdev->axes_rotation); + + tmp = pEvdev->delta[REL_X]; + pEvdev->delta[REL_X] = (int)(pEvdev->delta[REL_X] * cosine - pEvdev->delta[REL_Y] * sine); + pEvdev->delta[REL_Y] = (int)(pEvdev->delta[REL_Y] * cosine + tmp * sine); + } if (pEvdev->swap_axes) { tmp = pEvdev->delta[REL_X]; pEvdev->delta[REL_X] = pEvdev->delta[REL_Y]; @@ -2267,6 +2277,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; + /* Axis labelling */ if ((pEvdev->num_vals > 0) && (prop_axis_label = XIGetKnownProperty(AXIS_LABEL_PROP))) { @@ -2324,6 +2341,17 @@ 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) + { + // cache radians + int degrees = *((INT16*)val->data); + pEvdev->axes_rotation = (degrees % 360) * M_PI / 180.0; + } } 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 5df7d3e..6b47520 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -120,7 +120,8 @@ typedef struct { BOOL swap_axes; BOOL invert_x; BOOL invert_y; - + float axes_rotation; /* radians */ + int delta[REL_CNT]; unsigned int abs_queued, rel_queued, prox_queued; -- 1.7.2.3