The TouchRing on the MobileStudio Pro has a range of only 0-35 instead
of 0-17 like prior devices. Because we hardcode an assumed range, the
driver mistakenly believes the jump from 35 to 0 (or 0 to 35, depending
on direction) when the user completes a revolution is actually caused
by the user reversing their finger direction. By reading the range from
the kernel, we can avoid this situation.

Note that the ABS_WHEEL axis is also used by (legacy) combined pen/pad
devices with a range corresponding to the puck fingerwheel. We need to
be careful to not read the value in these cases since it would lead to
erroneous behavior in existing setups. Devices with a range range
different from 0-71 will hopefully not be widely used on kernels prior
to 3.17 where pen and pad were split into seperate devices since there
is no way (short of peeking at the VID:PID or name) to have them work
correctly in the combined case.

Signed-off-by: Jason Gerecke <jason.gere...@wacom.com>
---
 src/wcmCommon.c     |  5 +++--
 src/wcmUSB.c        | 10 ++++++++++
 src/xf86Wacom.c     |  8 ++++----
 src/xf86WacomDefs.h |  9 ++++-----
 4 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/src/wcmCommon.c b/src/wcmCommon.c
index 9408f42..0ba0304 100644
--- a/src/wcmCommon.c
+++ b/src/wcmCommon.c
@@ -361,6 +361,7 @@ static void sendWheelStripEvents(InputInfoPtr pInfo, const 
WacomDeviceState* ds,
                                 int first_val, int num_vals, int *valuators)
 {
        WacomDevicePtr priv = (WacomDevicePtr) pInfo->private;
+       WacomCommonPtr common = priv->common;
        int delta = 0, idx = 0;
 
        DBG(10, priv, "\n");
@@ -396,7 +397,7 @@ static void sendWheelStripEvents(InputInfoPtr pInfo, const 
WacomDeviceState* ds,
        }
 
        /* emulate events for left touch ring */
-       delta = getScrollDelta(ds->abswheel, priv->oldState.abswheel, 
MAX_PAD_RING, AXIS_INVERT);
+       delta = getScrollDelta(ds->abswheel, priv->oldState.abswheel, 
common->wcmMaxRing, AXIS_INVERT);
        idx = getWheelButton(delta, WHEEL_ABS_UP, WHEEL_ABS_DN);
        if (idx >= 0 && IsPad(priv) && priv->oldState.proximity == 
ds->proximity)
        {
@@ -406,7 +407,7 @@ static void sendWheelStripEvents(InputInfoPtr pInfo, const 
WacomDeviceState* ds,
        }
 
        /* emulate events for right touch ring */
-       delta = getScrollDelta(ds->abswheel2, priv->oldState.abswheel2, 
MAX_PAD_RING, AXIS_INVERT);
+       delta = getScrollDelta(ds->abswheel2, priv->oldState.abswheel2, 
common->wcmMaxRing, AXIS_INVERT);
        idx = getWheelButton(delta, WHEEL2_ABS_UP, WHEEL2_ABS_DN);
        if (idx >= 0 && IsPad(priv) && priv->oldState.proximity == 
ds->proximity)
        {
diff --git a/src/wcmUSB.c b/src/wcmUSB.c
index dcb1690..2f9d93f 100644
--- a/src/wcmUSB.c
+++ b/src/wcmUSB.c
@@ -652,6 +652,16 @@ int usbWcmGetRanges(InputInfoPtr pInfo)
                        common->wcmMaxStripX = absinfo.maximum;
        }
 
+       /* max touchring value for standalone pad tools */
+       common->wcmMinRing = 0;
+       common->wcmMaxRing = 71;
+       if (!ISBITSET(ev,EV_MSC) && ISBITSET(abs, ABS_WHEEL) &&
+                       !ioctl(pInfo->fd, EVIOCGABS(ABS_WHEEL), &absinfo))
+       {
+               common->wcmMinRing = absinfo.minimum;
+               common->wcmMaxRing = absinfo.maximum;
+       }
+
        /* X tilt range */
        if (ISBITSET(abs, ABS_TILT_X) &&
                        !ioctl(pInfo->fd, EVIOCGABS(ABS_TILT_X), &absinfo))
diff --git a/src/xf86Wacom.c b/src/xf86Wacom.c
index 40b5c3d..b4cf25b 100644
--- a/src/xf86Wacom.c
+++ b/src/xf86Wacom.c
@@ -282,8 +282,8 @@ static int wcmInitAxes(DeviceIntPtr pWcm)
        {
                /* Touch ring */
                label = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_WHEEL);
-               min = MIN_PAD_RING;
-               max = MAX_PAD_RING;
+               min = common->wcmMinRing;
+               max = common->wcmMaxRing;
        }
 
        wcmInitAxis(pInfo->dev, index, label, min, max, res, min_res, max_res, 
mode);
@@ -298,8 +298,8 @@ static int wcmInitAxes(DeviceIntPtr pWcm)
                mode = Absolute;
                min_res = max_res = res = 1;
 
-               min = MIN_PAD_RING;
-               max = MAX_PAD_RING;
+               min = common->wcmMinRing;
+               max = common->wcmMaxRing;
 
                wcmInitAxis(pInfo->dev, index, label, min, max, res, min_res, 
max_res, mode);
        }
diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h
index 9de9cab..3961545 100644
--- a/src/xf86WacomDefs.h
+++ b/src/xf86WacomDefs.h
@@ -48,9 +48,6 @@
 #define TILT_MIN -64           /* Minimum reported tilt value */
 #define TILT_MAX 63            /* Maximum reported tilt value */
 
-#define MIN_PAD_RING 0         /* I4 absolute scroll ring min value */
-#define MAX_PAD_RING 71                /* I4 absolute scroll ring max value */
-
 /* I4 cursor tool has a rotation offset of 175 degrees */
 #define INTUOS4_CURSOR_ROTATION_OFFSET 175
 
@@ -235,8 +232,8 @@ struct _WacomDeviceState
 };
 
 static const struct _WacomDeviceState OUTPROX_STATE = {
-  .abswheel = MAX_PAD_RING + 1,
-  .abswheel2 = MAX_PAD_RING + 1
+  .abswheel = INT_MAX,
+  .abswheel2 = INT_MAX
 };
 
 struct _WacomDeviceRec
@@ -436,6 +433,8 @@ struct _WacomCommonRec
 
        int wcmMaxStripX;            /* Maximum fingerstrip X */
        int wcmMaxStripY;            /* Maximum fingerstrip Y */
+       int wcmMinRing;              /* Minimum touchring value */
+       int wcmMaxRing;              /* Maximum touchring value */
 
        WacomDevicePtr wcmDevices;   /* list of devices sharing same port */
        int wcmPktLength;            /* length of a packet */
-- 
2.10.0


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to