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> --- In this version I tried accomodating everything we've discussed before. However, it was a long time ago and it is hard to force myself to re-read and remember everything, so I may have overlooked something. This was tested with kernel 3.5 and Waltop Sirius Battery Free Tablet. src/wcmCommon.c | 2 -- src/wcmFilter.c | 16 +++++----- src/wcmISDV4.c | 14 +++++++-- src/wcmUSB.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/xf86Wacom.c | 10 ++++--- src/xf86WacomDefs.h | 17 +++++++++-- 6 files changed, 121 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..3802857 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->wcmTiltXMax) + ds->tiltx = common->wcmTiltXMax; + else if (ds->tiltx < common->wcmTiltXMin) + ds->tiltx = common->wcmTiltXMin; 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->wcmTiltYMax) + ds->tilty = common->wcmTiltYMax; + else if (ds->tilty < common->wcmTiltYMin) + ds->tilty = common->wcmTiltYMin; } return 0; /* lookin' good */ diff --git a/src/wcmISDV4.c b/src/wcmISDV4.c index 37c8ee3..f6a861e 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->wcmTiltXOff = 0 - reply.tilt_x_max / 2; + common->wcmTiltXFact = 1.0; + common->wcmTiltXMin = 0 + common->wcmTiltXOff; + common->wcmTiltXMax = reply.tilt_x_max + + common->wcmTiltXOff; + + common->wcmTiltYOff = 0 - reply.tilt_y_max / 2; + common->wcmTiltYFact = 1.0; + common->wcmTiltYMin = 0 + common->wcmTiltYOff; + common->wcmTiltYMax = reply.tilt_y_max + + common->wcmTiltYOff; + common->wcmFlags |= TILT_ENABLED_FLAG; } diff --git a/src/wcmUSB.c b/src/wcmUSB.c index 1a1951d..154f6cf 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->wcmTiltXOff = 0; + /* Convert to resolution expected by applications */ + common->wcmTiltXFact = TILT_RES / + (double)absinfo.resolution; + } + else +#endif + { + /* + * TODO: set to 0 once Wacom kernel driver is + * updated to report zero-centered values. + */ + /* Center the reported range on zero */ + common->wcmTiltXOff = - (absinfo.minimum + + absinfo.maximum) / 2; + /* + * Assume reported resolution is the one expected by + * applications + */ + common->wcmTiltXFact = 1.0; + } + common->wcmTiltXMin = round((absinfo.minimum + + common->wcmTiltXOff) * + common->wcmTiltXFact); + common->wcmTiltXMax = round((absinfo.maximum + + common->wcmTiltXOff) * + common->wcmTiltXFact); + } + + /* 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->wcmTiltYOff = 0; + /* Convert to resolution expected by applications */ + common->wcmTiltYFact = TILT_RES / + (double)absinfo.resolution; + } + else +#endif + { + /* + * TODO: set to 0 once Wacom kernel driver is + * updated to report zero-centered values. + */ + /* Center the reported range on zero */ + common->wcmTiltYOff = - (absinfo.minimum + + absinfo.maximum) / 2; + /* + * Assume reported resolution is the one expected by + * applications + */ + common->wcmTiltYFact = 1.0; + } + common->wcmTiltYMin = round((absinfo.minimum + + common->wcmTiltYOff) * + common->wcmTiltYFact); + common->wcmTiltYMax = round((absinfo.maximum + + common->wcmTiltYOff) * + common->wcmTiltYFact); + } + /* 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->wcmTiltXOff) * + common->wcmTiltXFact); break; case ABS_TILT_Y: - ds->tilty = event->value - common->wcmMaxtiltY/2; + ds->tilty = round((event->value + common->wcmTiltYOff) * + common->wcmTiltYFact); 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..2f46e15 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,16 @@ 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 */ + + int wcmTiltXOff; /* styli tilt offset in X direction */ + double wcmTiltXFact; /* styli tilt factor in X direction */ + int wcmTiltXMin; /* styli min reported tilt in X direction */ + int wcmTiltXMax; /* styli max reported tilt in X direction */ + + int wcmTiltYOff; /* styli tilt offset in Y direction */ + double wcmTiltYFact; /* styli tilt factor in Y direction */ + int wcmTiltYMin; /* styli min reported tilt in Y direction */ + int wcmTiltYMax; /* 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