diff options
author | Jason Gerecke <killertofu@gmail.com> | 2019-05-24 14:13:08 -0700 |
---|---|---|
committer | Jason Gerecke <killertofu@gmail.com> | 2019-05-24 15:00:08 -0700 |
commit | 33cdf63a0089bdd1e66e350cc621b80415a7c8ba (patch) | |
tree | c995c8e9530c5b13e2ff336321a9d7022a4d7e52 | |
parent | c091c9e295db9c271de60c87a1a9ce921d638159 (diff) | |
download | xf86-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.c | 73 |
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; } |