Use tilt range and, optionally, resolution reported by the kernel for event
devices.

Add a constant for resolution currently expected by applications: TILT_RES,
1 point per degree in kernel units (points/radian). Scale values to this
resolution for compatibility and specify it for corresponding valuators
(instead of 1) for future use by applications.

Add constants for currently reported value limits: TILT_MIN and TILT_MAX,
-64 and 63 respectively. Continue clamping values to [TILT_MIN, TILT_MAX]
for compatibility.

Values and ranges reported by currently supported tablets should remain
unchanged.

Signed-off-by: Nikolai Kondrashov <spbn...@gmail.com>
---

Renamed wcmTilt[XY]<Noun> to wcmTilt<Noun>[XY] to better match the
conventions.
Clarified range-centering comments.
Replaced TODO items with a cleaner one in the header.

 src/wcmCommon.c     |    2 --
 src/wcmFilter.c     |   16 +++++-----
 src/wcmISDV4.c      |   14 +++++++--
 src/wcmUSB.c        |   82 +++++++++++++++++++++++++++++++++++++++++++++++++--
 src/xf86Wacom.c     |   10 ++++---
 src/xf86WacomDefs.h |   20 +++++++++++--
 6 files changed, 124 insertions(+), 20 deletions(-)

diff --git a/src/wcmCommon.c b/src/wcmCommon.c
index d10c1d1..650f8f5 100644
--- a/src/wcmCommon.c
+++ b/src/wcmCommon.c
@@ -1431,8 +1431,6 @@ WacomCommonPtr wcmNewCommon(void)
        common->wcmMaxTouchY = 1024;       /* max touch Y value */
        common->wcmMaxStripX = 4096;       /* Max fingerstrip X */
        common->wcmMaxStripY = 4096;       /* Max fingerstrip Y */
-       common->wcmMaxtiltX = 128;         /* Max tilt in X directory */
-       common->wcmMaxtiltY = 128;         /* Max tilt in Y directory */
        common->wcmCursorProxoutDistDefault = PROXOUT_INTUOS_DISTANCE;
                        /* default to Intuos */
        common->wcmSuppress = DEFAULT_SUPPRESS;
diff --git a/src/wcmFilter.c b/src/wcmFilter.c
index 47e958a..e55ef0f 100644
--- a/src/wcmFilter.c
+++ b/src/wcmFilter.c
@@ -298,16 +298,16 @@ int wcmFilterCoord(WacomCommonPtr common, WacomChannelPtr 
pChannel,
                                    ds->device_type == ERASER_ID))
        {
                ds->tiltx = tx / common->wcmRawSample;
-               if (ds->tiltx > common->wcmMaxtiltX/2-1)
-                       ds->tiltx = common->wcmMaxtiltX/2-1;
-               else if (ds->tiltx < -common->wcmMaxtiltX/2)
-                       ds->tiltx = -common->wcmMaxtiltX/2;
+               if (ds->tiltx > common->wcmTiltMaxX)
+                       ds->tiltx = common->wcmTiltMaxX;
+               else if (ds->tiltx < common->wcmTiltMinX)
+                       ds->tiltx = common->wcmTiltMinX;
 
                ds->tilty = ty / common->wcmRawSample;
-               if (ds->tilty > common->wcmMaxtiltY/2-1)
-                       ds->tilty = common->wcmMaxtiltY/2-1;
-               else if (ds->tilty < -common->wcmMaxtiltY/2)
-                       ds->tilty = -common->wcmMaxtiltY/2;
+               if (ds->tilty > common->wcmTiltMaxY)
+                       ds->tilty = common->wcmTiltMaxY;
+               else if (ds->tilty < common->wcmTiltMinY)
+                       ds->tilty = common->wcmTiltMinY;
        }
 
        return 0; /* lookin' good */
diff --git a/src/wcmISDV4.c b/src/wcmISDV4.c
index 37c8ee3..2528254 100644
--- a/src/wcmISDV4.c
+++ b/src/wcmISDV4.c
@@ -405,8 +405,18 @@ static int isdv4GetRanges(InputInfoPtr pInfo)
                common->wcmMaxY = reply.y_max;
                if (reply.tilt_x_max && reply.tilt_y_max)
                {
-                       common->wcmMaxtiltX = reply.tilt_x_max;
-                       common->wcmMaxtiltY = reply.tilt_y_max;
+                       common->wcmTiltOffX = 0 - reply.tilt_x_max / 2;
+                       common->wcmTiltFactX = 1.0;
+                       common->wcmTiltMinX = 0 + common->wcmTiltOffX;
+                       common->wcmTiltMaxX = reply.tilt_x_max +
+                                             common->wcmTiltOffX;
+
+                       common->wcmTiltOffY = 0 - reply.tilt_y_max / 2;
+                       common->wcmTiltFactY = 1.0;
+                       common->wcmTiltMinY = 0 + common->wcmTiltOffY;
+                       common->wcmTiltMaxY = reply.tilt_y_max +
+                                             common->wcmTiltOffY;
+
                        common->wcmFlags |= TILT_ENABLED_FLAG;
                }
 
diff --git a/src/wcmUSB.c b/src/wcmUSB.c
index 1a1951d..f25116b 100644
--- a/src/wcmUSB.c
+++ b/src/wcmUSB.c
@@ -572,6 +572,82 @@ int usbWcmGetRanges(InputInfoPtr pInfo)
                        common->wcmMaxStripX = absinfo.maximum;
        }
 
+       /* X tilt range */
+       if (ISBITSET(abs, ABS_TILT_X) &&
+                       !ioctl(pInfo->fd, EVIOCGABS(ABS_TILT_X), &absinfo))
+       {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
+               /* If resolution is specified */
+               if (absinfo.resolution > 0)
+               {
+                       /* Assume the range is centered on zero */
+                       common->wcmTiltOffX = 0;
+                       /* Convert to resolution expected by applications */
+                       common->wcmTiltFactX = TILT_RES /
+                                              (double)absinfo.resolution;
+               }
+               else
+#endif
+               {
+                       /*
+                        * Center the reported range on zero to support
+                        * kernel drivers still reporting non-zero-centered
+                        * values.
+                        */
+                       common->wcmTiltOffX = - (absinfo.minimum +
+                                                absinfo.maximum) / 2;
+                       /*
+                        * Assume reported resolution is the one expected by
+                        * applications
+                        */
+                       common->wcmTiltFactX = 1.0;
+               }
+               common->wcmTiltMinX = round((absinfo.minimum +
+                                            common->wcmTiltOffX) *
+                                           common->wcmTiltFactX);
+               common->wcmTiltMaxX = round((absinfo.maximum +
+                                            common->wcmTiltOffX) *
+                                           common->wcmTiltFactX);
+       }
+
+       /* Y tilt range */
+       if (ISBITSET(abs, ABS_TILT_Y) &&
+                       !ioctl(pInfo->fd, EVIOCGABS(ABS_TILT_Y), &absinfo))
+       {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
+               /* If resolution is specified */
+               if (absinfo.resolution > 0)
+               {
+                       /* Assume the range is centered on zero */
+                       common->wcmTiltOffY = 0;
+                       /* Convert to resolution expected by applications */
+                       common->wcmTiltFactY = TILT_RES /
+                                              (double)absinfo.resolution;
+               }
+               else
+#endif
+               {
+                       /*
+                        * Center the reported range on zero to support
+                        * kernel drivers still reporting non-zero-centered
+                        * values.
+                        */
+                       common->wcmTiltOffY = - (absinfo.minimum +
+                                                absinfo.maximum) / 2;
+                       /*
+                        * Assume reported resolution is the one expected by
+                        * applications
+                        */
+                       common->wcmTiltFactY = 1.0;
+               }
+               common->wcmTiltMinY = round((absinfo.minimum +
+                                            common->wcmTiltOffY) *
+                                           common->wcmTiltFactY);
+               common->wcmTiltMaxY = round((absinfo.maximum +
+                                            common->wcmTiltOffY) *
+                                           common->wcmTiltFactY);
+       }
+
        /* max finger strip Y for tablets with Expresskeys
         * or physical Y for touch devices in hundredths of a mm */
        if (ISBITSET(abs, ABS_RY) &&
@@ -1045,10 +1121,12 @@ static int usbParseAbsEvent(WacomCommonPtr common,
                        ds->rotation = event->value;
                        break;
                case ABS_TILT_X:
-                       ds->tiltx = event->value - common->wcmMaxtiltX/2;
+                       ds->tiltx = round((event->value + common->wcmTiltOffX) *
+                                         common->wcmTiltFactX);
                        break;
                case ABS_TILT_Y:
-                       ds->tilty = event->value - common->wcmMaxtiltY/2;
+                       ds->tilty = round((event->value + common->wcmTiltOffY) *
+                                         common->wcmTiltFactY);
                        break;
                case ABS_PRESSURE:
                        ds->pressure = event->value;
diff --git a/src/xf86Wacom.c b/src/xf86Wacom.c
index 6581ab5..c52db8d 100644
--- a/src/xf86Wacom.c
+++ b/src/xf86Wacom.c
@@ -223,8 +223,9 @@ static int wcmInitAxes(DeviceIntPtr pWcm)
        if (IsPen(priv))
        {
                label = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X),
-               min = -64;
-               max = 63;
+               min_res = max_res = res = round(TILT_RES);
+               min = TILT_MIN;
+               max = TILT_MAX;
        }
        else if (IsCursor(priv))
        {
@@ -251,8 +252,9 @@ static int wcmInitAxes(DeviceIntPtr pWcm)
        if (IsPen(priv))
        {
                label = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y);
-               min = -64;
-               max = 63;
+               min_res = max_res = res = round(TILT_RES);
+               min = TILT_MIN;
+               max = TILT_MAX;
        }
        else if (IsCursor(priv))
        {
diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h
index c978243..e6f8757 100644
--- a/src/xf86WacomDefs.h
+++ b/src/xf86WacomDefs.h
@@ -43,6 +43,11 @@
 #define MAX_ROTATION_RANGE 1800 /* the maximum range of the marker pen 
rotation */
 #define MAX_ABS_WHEEL 1023      /* the maximum value of absolute wheel */
 
+#define TILT_RES (180/M_PI)    /* Reported tilt resolution in points/radian
+                                  (1/degree) */
+#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 */
 
@@ -440,8 +445,19 @@ struct _WacomCommonRec
                                     /* tablet Z resolution is equivalent
                                      * to wcmMaxZ which is equal to 100% 
pressure */
        int wcmMaxDist;              /* tablet max distance value */
-       int wcmMaxtiltX;             /* styli max tilt in X directory */ 
-       int wcmMaxtiltY;             /* styli max tilt in Y directory */ 
+
+       /*
+        * TODO Remove wcmTiltOff*, once the kernel drivers reporting
+        *      non-zero-centered tilt values are no longer in use.
+        */
+       int wcmTiltOffX;             /* styli tilt offset in X direction */
+       int wcmTiltOffY;             /* styli tilt offset in Y direction */
+       double wcmTiltFactX;         /* styli tilt factor in X direction */
+       double wcmTiltFactY;         /* styli tilt factor in Y direction */
+       int wcmTiltMinX;             /* styli min reported tilt in X direction 
*/
+       int wcmTiltMinY;             /* styli min reported tilt in Y direction 
*/
+       int wcmTiltMaxX;             /* styli max reported tilt in X direction 
*/
+       int wcmTiltMaxY;             /* styli max reported tilt in Y direction 
*/
 
        int wcmMaxStripX;            /* Maximum fingerstrip X */
        int wcmMaxStripY;            /* Maximum fingerstrip Y */
-- 
1.7.10.4


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to