Resolution uses different units in the kernel (point/mm), XInput
(point/m), and the hardware protocol (point/cm/1000 for touch and
point/inch for pen).

We have a resolution table for pen in the X driver. But we get the
touch resolution directly from the kernel through HID descriptor.

For kernels older than 2.6.30, resolution is not part of absinfo.
For kernels older than 2.6.35, kernel does not pass resolution to
the userland.

This patch addresses those issues and correct a conversion bug
introduced by the RX/RY workaround.

Signed-off-by: Ping Cheng <[email protected]>
Reviewed-by: Chris Bagwell <[email protected]>
---
 src/wcmUSB.c |   49 +++++++++++++++++++++++++++++++++++--------------
 1 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/src/wcmUSB.c b/src/wcmUSB.c
index cfaf920..38a191b 100644
--- a/src/wcmUSB.c
+++ b/src/wcmUSB.c
@@ -27,6 +27,9 @@
 #include <asm/types.h>
 #include <linux/input.h>
 #include <sys/utsname.h>
+# ifndef LINUX_VERSION_CODE
+# include <linux/version.h>
+# endif
 
 #define MAX_USB_EVENTS 32
 
@@ -463,8 +466,19 @@ int usbWcmGetRanges(InputInfoPtr pInfo)
        if (!is_touch)
                common->wcmMaxX = absinfo.maximum;
        else
+       {
                common->wcmMaxTouchX = absinfo.maximum;
 
+               /* reset touch resolution since we retrieve it from the kernel 
+                * through absinfo (on kenrels 2.6.35 or later) or 
+                * RX (on kenrels older than 2.6.35) below
+                */
+               common->wcmTouchResolX = 0;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
+               common->wcmTouchResolX = absinfo.resolution * 1000;
+#endif
+       }
+
        /* max y */
        if (ioctl(pInfo->fd, EVIOCGABS(ABS_Y), &absinfo) < 0)
        {
@@ -480,36 +494,43 @@ int usbWcmGetRanges(InputInfoPtr pInfo)
        if (!is_touch)
                common->wcmMaxY = absinfo.maximum;
        else
+       {
                common->wcmMaxTouchY = absinfo.maximum;
 
+               /* reset touch resolution since we retrieve it from the kernel 
+                * through absinfo (on kenrels 2.6.35 or later) or 
+                * RY (on kenrels older than 2.6.35) below
+                */
+               common->wcmTouchResolY = 0;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
+               common->wcmTouchResolY = absinfo.resolution * 1000;
+#endif
+       }
+
        /* max finger strip X for tablets with Expresskeys
-        * or touch physical X for TabletPCs with touch */
+        * or physical X for touch device in thousandth of a cm */
        if (ioctl(pInfo->fd, EVIOCGABS(ABS_RX), &absinfo) == 0)
        {
-               if (is_touch)
-                       common->wcmTouchResolX = absinfo.maximum;
+               if (is_touch && !common->wcmTouchResolX)
+                       common->wcmTouchResolX =
+                               (int)(((double)common->wcmMaxTouchX * 10.0
+                                / (double)absinfo.maximum) + 0.5);
                else
                        common->wcmMaxStripX = absinfo.maximum;
        }
 
        /* max finger strip Y for tablets with Expresskeys
-        * or touch physical Y for TabletPCs with touch */
+        * or physical Y for touch device in thousandth of a cm */
        if (ioctl(pInfo->fd, EVIOCGABS(ABS_RY), &absinfo) == 0)
        {
-               if (is_touch)
-                       common->wcmTouchResolY = absinfo.maximum;
+               if (is_touch && !common->wcmTouchResolY)
+                       common->wcmTouchResolY =
+                                (int)(((double)common->wcmMaxTouchY * 10.0
+                                / (double)absinfo.maximum) + 0.5);
                else
                        common->wcmMaxStripY = absinfo.maximum;
        }
 
-       if (is_touch && common->wcmTouchResolX && common->wcmMaxTouchX)
-       {
-               common->wcmTouchResolX = (int)(((double)common->wcmTouchResolX)
-                        / ((double)common->wcmMaxTouchX) + 0.5);
-               common->wcmTouchResolY = (int)(((double)common->wcmTouchResolY)
-                        / ((double)common->wcmMaxTouchY) + 0.5);
-       }
-
        /* max z cannot be configured */
        if (ioctl(pInfo->fd, EVIOCGABS(ABS_PRESSURE), &absinfo) == 0)
                common->wcmMaxZ = absinfo.maximum;
-- 
1.7.3.4


------------------------------------------------------------------------------
Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)!
Finally, a world-class log management solution at an even better price-free!
Download using promo code Free_Logger_4_Dev2Dev. Offer expires 
February 28th, so secure your free ArcSight Logger TODAY! 
http://p.sf.net/sfu/arcsight-sfd2d
_______________________________________________
Linuxwacom-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to