summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPing Cheng <pinglinux@gmail.com>2019-06-12 13:11:10 -0700
committerGitHub <noreply@github.com>2019-06-12 13:11:10 -0700
commita3e880ec34e7e9ef01098a899a4b1eb113b82b51 (patch)
tree306606675599d4977fd6986100bde485eac7fc5a
parent5fc2d91ead58c8a5ae38f5cfe92de1d214aba5d7 (diff)
parent365739656df5361533a57494db327ecbc7cb4b8a (diff)
downloadxf86-input-wacom-a3e880ec34e7e9ef01098a899a4b1eb113b82b51.tar.gz
Merge pull request #62 from jigpu/issue-52
Fix issues with Microsoft Surface Go tablet
-rw-r--r--src/wcmUSB.c80
1 files changed, 68 insertions, 12 deletions
diff --git a/src/wcmUSB.c b/src/wcmUSB.c
index 2bb6b78..2bec7b4 100644
--- a/src/wcmUSB.c
+++ b/src/wcmUSB.c
@@ -796,8 +796,8 @@ int usbWcmGetRanges(InputInfoPtr pInfo)
private->wcmPenTouch = TRUE;
}
- /* A generic protocol device does not report ABS_MISC event */
- if (!ISBITSET(abs, ABS_MISC))
+ /* Non-wacom devices, and Wacom devices without an ABS_MISC should be treated as generic */
+ if (common->vendor_id != WACOM_VENDOR_ID || !ISBITSET(abs, ABS_MISC))
common->wcmProtocolLevel = WCM_PROTOCOL_GENERIC;
if (ioctl(pInfo->fd, EVIOCGBIT(EV_SW, sizeof(sw)), sw) < 0)
@@ -1210,7 +1210,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];
@@ -1225,12 +1233,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;
@@ -1251,6 +1253,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;
@@ -1259,8 +1294,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);
@@ -1271,6 +1304,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;
}
@@ -1608,7 +1663,8 @@ static int deviceTypeFromEvent(WacomCommonPtr common, int type, int code, int va
case ABS_MT_TRACKING_ID:
return TOUCH_ID;
case ABS_MISC:
- return usbFindDeviceTypeById(value);
+ if (common->wcmProtocolLevel != WCM_PROTOCOL_GENERIC)
+ return usbFindDeviceTypeById(value);
}
}