diff options
author | Jason Gerecke <killertofu@gmail.com> | 2012-08-01 17:10:27 -0700 |
---|---|---|
committer | Jason Gerecke <killertofu@gmail.com> | 2012-10-08 10:17:38 -0700 |
commit | afb25836e6350b5aaea76ccc68b2e16d382e1398 (patch) | |
tree | 64e214527798128c3476834e1edb6fa8b66f22f1 | |
parent | 63cf3c5a2a04559838ec6fd6b9e7e808818072b1 (diff) | |
download | xf86-input-wacom-afb25836e6350b5aaea76ccc68b2e16d382e1398.tar.gz |
Make usbInitToolType more generic, and always use
Tweaks the usbInitToolType function to be always useful. This is
needed so that we can use it to get the tool type for all event
frames, allowing us to properly fill in the tool type for devices
that we otherwise don't figure out until later on (which causes
problems with the proper operation of usbChooseChannel).
Signed-off-by: Jason Gerecke <killertofu@gmail.com>
Tested-by: Chris Bagwell <chris@cnpbagwell.com>
-rw-r--r-- | src/wcmUSB.c | 122 |
1 files changed, 87 insertions, 35 deletions
diff --git a/src/wcmUSB.c b/src/wcmUSB.c index 627cf96..0669039 100644 --- a/src/wcmUSB.c +++ b/src/wcmUSB.c @@ -1454,55 +1454,107 @@ static void usbParseBTNEvent(WacomCommonPtr common, channel->dirty |= change; } -/*** - * Retrieve the tool type from an USB data packet by looking at the event - * codes. Refer to linux/input.h for event codes that define tool types. - * - * @param event_ptr A pointer to the USB data packet that contains the - * events to be processed. - * @param nevents Number of events in the packet. - * @param last_device_type The device type for the last event +/** + * Translates a tool code from the kernel (e.g. BTN_TOOL_PEN) into the + * corresponding device type for the driver (e.g. STYLUS_ID). * - * @return The tool type. last_device_type if no pen/touch/eraser event code - * in the event, or TOUCH_ID if last_device_type is not a tool. + * @param[in] type Linux input tool type (e.g. EV_KEY) + * @param[in] code Linux input tool code (e.g. BTN_STYLUS_PEN) + * @param[in] protocol Wacom protocol type (e.g. WCM_PROTOCOL_GENERIC) + * @return Wacom device ID (e.g. STYLUS_ID) or 0 if no match. */ -static int usbInitToolType(const struct input_event *event_ptr, int nevents, int last_device_type) +static int toolTypeToDeviceType(int type, int code, int protocol) { - int i, device_type = 0; - - for (i = 0; (i < nevents) && !device_type; ++i) - { - switch (event_ptr->code) - { + if (type == EV_KEY) { + switch(code) { case BTN_TOOL_PEN: case BTN_TOOL_PENCIL: case BTN_TOOL_BRUSH: case BTN_TOOL_AIRBRUSH: - device_type = STYLUS_ID; - break; + return STYLUS_ID; case BTN_TOOL_FINGER: - case ABS_MT_SLOT: - case ABS_MT_TRACKING_ID: - device_type = TOUCH_ID; - break; + if (protocol != WCM_PROTOCOL_GENERIC) + return PAD_ID; + else + return TOUCH_ID; case BTN_TOOL_RUBBER: - device_type = ERASER_ID; - break; + return ERASER_ID; } + } + else if (type == EV_ABS) { + switch (code) { + case ABS_MT_SLOT: + case ABS_MT_TRACKING_ID: + return TOUCH_ID; + } + } + + return 0; +} + +/** + * Queries the kernel through EVIOCGKEY for the latest device type + * information. The result is the first tool type (e.g. STYLUS_ID) + * found associated with the in-prox tool. + * + * @param[in] common + * @return A tool type (e.g. STYLUS_ID) associated with the in-prox tool + */ +static int refreshDeviceType(WacomCommonPtr common) +{ + int device_type = 0; + unsigned long keys[NBITS(KEY_MAX)] = { 0 }; + int rc = ioctl(common->fd, EVIOCGKEY(sizeof(keys)), keys); + int i; - event_ptr++; + if (rc == -1) + xf86Msg(X_ERROR, "%s: failed to retrieve key bits\n", common->device_path); + return 0; + + for (i = 0; i < KEY_MAX; i++) + { + if (ISBITSET(keys, i)) + device_type = toolTypeToDeviceType(EV_KEY, i, common->wcmProtocolLevel); + if (device_type) + return device_type; } - if (!device_type) + return 0; +} + +/*** + * Retrieve the tool type from an USB data packet by looking at the event + * codes. Refer to linux/input.h for event codes that define tool types. + * + * @param[in] common + * @param[in] event_ptr A pointer to the USB data packet that contains the + * events to be processed. + * @param[in] nevents Number of events in the packet. + * @param[in] last_device_type The device type for the last event + * + * @return The tool type. This falls back on last_device_type if no + * pen/touch/eraser event code in the event, and on EVIOCGKEY + * if last_device_type is not a tool. If all else fails, '0' + * is returned. + */ +static int usbInitToolType(WacomCommonPtr common, const struct input_event *event_ptr, + int nevents, int last_device_type) +{ + int i, device_type = 0; + + for (i = 0; (i < nevents) && !device_type; ++i, event_ptr++) { - if (last_device_type) - device_type = last_device_type; - else - device_type = TOUCH_ID; + device_type = toolTypeToDeviceType(event_ptr->type, event_ptr->code, common->wcmProtocolLevel); } + if (!device_type) + device_type = last_device_type; + + if (!device_type) + device_type = refreshDeviceType(common); + return device_type; } @@ -1534,10 +1586,10 @@ static void usbDispatchEvents(InputInfoPtr pInfo) DBG(6, common, "%d events received\n", private->wcmEventCnt); - if (private->wcmUseMT) - private->wcmDeviceType = usbInitToolType(private->wcmEvents, - private->wcmEventCnt, - dslast.device_type); + private->wcmDeviceType = usbInitToolType(common, + private->wcmEvents, + private->wcmEventCnt, + dslast.device_type); if (private->wcmPenTouch) { |