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
