summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Gerecke <killertofu@gmail.com>2019-05-24 14:13:08 -0700
committerJason Gerecke <killertofu@gmail.com>2019-05-24 15:00:08 -0700
commit33cdf63a0089bdd1e66e350cc621b80415a7c8ba (patch)
treec995c8e9530c5b13e2ff336321a9d7022a4d7e52
parentc091c9e295db9c271de60c87a1a9ce921d638159 (diff)
downloadxf86-input-wacom-33cdf63a0089bdd1e66e350cc621b80415a7c8ba.tar.gz
USB: Split handling of generic and protocol 5 ABS events
Many Wacom devices use a non-standard meaning for several axes and we should be careful not to apply those meaning when receiving events from a generic device. Incorrectly using the non-standard meanings can cause the driver or userspace to become confused. Ref: https://github.com/linuxwacom/xf86-input-wacom/issues/52 Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
-rw-r--r--src/wcmUSB.c73
1 files changed, 64 insertions, 9 deletions
diff --git a/src/wcmUSB.c b/src/wcmUSB.c
index 8ded958..3515563 100644
--- a/src/wcmUSB.c
+++ b/src/wcmUSB.c
@@ -1187,7 +1187,15 @@ static int usbFindDeviceTypeById(int device_id)
}
}
-static void usbParseAbsEvent(WacomCommonPtr common,
+/**
+ * Handle ABS events strictly according to their definition as documented
+ * in the Linux kernel.
+ *
+ * @param common
+ * @param event
+ * @param channel_number
+ */
+static int usbParseGenericAbsEvent(WacomCommonPtr common,
struct input_event *event, int channel_number)
{
WacomChannel *channel = &common->wcmChannel[channel_number];
@@ -1202,12 +1210,6 @@ static void usbParseAbsEvent(WacomCommonPtr common,
case ABS_Y:
ds->y = event->value;
break;
- case ABS_RX:
- ds->stripx = event->value;
- break;
- case ABS_RY:
- ds->stripy = event->value;
- break;
case ABS_RZ:
ds->rotation = event->value;
break;
@@ -1228,6 +1230,39 @@ static void usbParseAbsEvent(WacomCommonPtr common,
case ABS_WHEEL:
ds->abswheel = event->value;
break;
+ case ABS_THROTTLE:
+ ds->throttle = event->value;
+ break;
+ default:
+ change = 0;
+ }
+
+ return change;
+}
+
+/**
+ * Handle ABS events according to Wacom (protocol 4/5) conventions. Only
+ * those events which are not interpreted in the generic manner need to be
+ * handled here.
+ *
+ * @param common
+ * @param event
+ * @param channel_number
+ */
+static int usbParseWacomAbsEvent(WacomCommonPtr common,
+ struct input_event *event, int channel_number)
+{
+ WacomChannel *channel = &common->wcmChannel[channel_number];
+ WacomDeviceState *ds = &channel->work;
+ int change = 1;
+
+ switch(event->code) {
+ case ABS_RX:
+ ds->stripx = event->value;
+ break;
+ case ABS_RY:
+ ds->stripy = event->value;
+ break;
case ABS_Z:
ds->abswheel = event->value;
break;
@@ -1236,8 +1271,6 @@ static void usbParseAbsEvent(WacomCommonPtr common,
if ((common->vendor_id == WACOM_VENDOR_ID) &&
(common->tablet_id == 0xF4 || common->tablet_id == 0xF8))
ds->abswheel2 = event->value;
- else
- ds->throttle = event->value;
break;
case ABS_MISC:
ds->proximity = (event->value != 0);
@@ -1248,6 +1281,28 @@ static void usbParseAbsEvent(WacomCommonPtr common,
change = 0;
}
+ return change;
+}
+
+/**
+ * Handle an incoming ABS event.
+ *
+ * @param common
+ * @param event
+ * @param channel_number
+ */
+static void usbParseAbsEvent(WacomCommonPtr common,
+ struct input_event *event, int channel_number)
+{
+ WacomChannel *channel = &common->wcmChannel[channel_number];
+ WacomDeviceState *ds = &channel->work;
+ Bool change;
+
+ change = usbParseGenericAbsEvent(common, event, channel_number);
+ if (common->wcmProtocolLevel != WCM_PROTOCOL_GENERIC) {
+ change |= usbParseWacomAbsEvent(common, event, channel_number);
+ }
+
ds->time = (int)GetTimeInMillis();
channel->dirty |= change;
}