[DIGImend-devel] [PATCH v2] Use kernel-reported tilt range and resolution
Brought to you by:
spb_nick
|
From: Nikolai K. <sp...@gm...> - 2012-08-27 19:24:27
|
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 <sp...@gm...>
---
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
|