Instead of having different per-protocol cases, just obtain serial numbers equivelent to those you'd get from Protocol 5 and then use that serial to find a channel dynamically.
Signed-off-by: Jason Gerecke <killert...@gmail.com> --- src/wcmUSB.c | 178 +++++++++++++++++++++++++---------------------------------- 1 file changed, 75 insertions(+), 103 deletions(-) diff --git a/src/wcmUSB.c b/src/wcmUSB.c index 0669039..e8940da 100644 --- a/src/wcmUSB.c +++ b/src/wcmUSB.c @@ -720,121 +720,88 @@ static int usbParse(InputInfoPtr pInfo, const unsigned char* data, int len) return common->wcmPktLength; } -/* Up to MAX_CHANNEL tools can be tracked concurrently by driver. - * Chose a channel to use to track current batch of events. +/** + * Returns a serial number for the provided device_type and serial, as + * through it came from from a Protocol 5 device. + * + * Protocol 5 serial numbers will be returned unchanged. Otherwise, + * anonymous tools (from Protocol 4 and Generic Protocol) will have + * serial numbers of: -1 (pad), 1 (pen/1st finger), 2 (2nd finger), + * etc. + * + * @param[in] device_type Type of device (e.g. STYLUS_ID, TOUCH_ID, PAD_ID) + * @param[in] serial Serial number of device + * @return Serial number of device as through from Protocol 5 + */ +static int protocol5Serial(int device_type, unsigned int serial) { + if (!serial) { + /* Generic Protocol does not send serial numbers */ + return device_type == PAD_ID ? -1 : 1; + } + else if (serial == 0xf0) { + /* Protocol 4 uses the expected anonymous serial + * numbers, but has the wrong PAD serial number. + * This could cause problem if 0xf0 is ever used + * for a Protocol 5 serial number, but isn't a + * problem as yet. + */ + return -1; + } + else { + /* Protocol 5 FTW */ + return serial; + } +} + +/** + * Find an appropriate channel to track the specified tool's state in. + * If the tool is already in proximity, the channel currently being used + * to store its state will be returned. Otherwise, an arbitrary available + * channel will be returned. Up to MAX_CHANNEL tools can be tracked + * concurrently by driver. + * + * @param[in] common + * @return Channel number to track the tool's state */ static int usbChooseChannel(WacomCommonPtr common) { /* figure out the channel to use based on serial number */ int i, channel = -1; wcmUSBData* private = common->private; - unsigned int serial = private->wcmLastToolSerial; + unsigned int serial = protocol5Serial(private->wcmDeviceType, private->wcmLastToolSerial); - if (common->wcmProtocolLevel == WCM_PROTOCOL_GENERIC) - { - /* Generic Protocol devices do not use any form of - * serial #'s to multiplex events over a single input - * and so can always map to channel 0. This means - * only 1 tool can ever been in proximity at one time - * (MT events are special case handled elsewhere). - * It also means all buttons must be associated with - * a single tool and can not send tablet buttons - * as part of a pad tool. - */ - channel = 0; - serial = 1; + /* force events from PAD device to PAD_CHANNEL */ + if (serial == -1) + channel = PAD_CHANNEL; - /* Generic devices need to map stylus buttons to "channel" - * and all other button presses to PAD. Hardcode PAD - * channel here. - */ - private->wcmBTNChannel = PAD_CHANNEL; - } - else if (common->wcmProtocolLevel == WCM_PROTOCOL_4) - { - /* Protocol 4 devices support only 2 devices being - * in proximity at the same time. This includes - * the PAD device as well as 1 other tool - * (stylus, mouse, finger touch, etc). - * There is a special case of Tablet PC that also - * suport a 3rd tool (2nd finger touch) to also be - * in proximity at same time but this should eventually - * go away when its switched to MT events to fix loss of - * events. - * - * Protocol 4 send fixed serial numbers along with events. - * Events associated with PAD device - * will send serial number of 0xf0 always. - * Events associated with BTN_TOOL_TRIPLETAP (2nd finger - * touch) send a serial number of 0x02 always. - * Events associated with all other BTN_TOOL_*'s will - * either send a serial # of 0x01 or we can act as if - * they did send that value. - * - * Since its a fixed mapping, directly convert this to - * channels 0 to 2 with last channel always used for - * pad devices. - */ - if (serial == 0xf0) - channel = PAD_CHANNEL; - else if (serial) - channel = serial-1; - else - channel = 0; - /* All events go to same channel for Protocol 4 */ - private->wcmBTNChannel = channel; - } - else if (serial) /* serial number should never be 0 for V5 devices */ + /* find existing channel */ + if (channel < 0) { - /* Protocol 5 devices can support tracking 2 or 3 - * tools at once. One is the PAD device - * as well as a stylus and/or mouse. - * - * Events associated with PAD device - * will send serial number of -1 (0xffffffff) always. - * Events associated with all other BTN_TOOL_*'s will - * send a dynamic serial #. - * - * Logic here is related to dynamically mapping - * serial numbers to a fixed channel #. - */ - if (TabletHasFeature(common, WCM_DUALINPUT)) + for (i=0; i<MAX_CHANNELS; i++) { - /* find existing channel */ - for (i=0; i<MAX_CHANNELS; ++i) + if (common->wcmChannel[i].work.proximity && + common->wcmChannel[i].work.serial_num == serial) { - if (common->wcmChannel[i].work.proximity && - common->wcmChannel[i].work.serial_num == serial) - { - channel = i; - break; - } + channel = i; + break; } + } + } - /* find an empty channel */ - if (channel < 0) + /* find an empty channel */ + if (channel < 0) + { + for (i=0; i<MAX_CHANNELS; i++) + { + if (i == PAD_CHANNEL) + continue; + + if (!common->wcmChannel[i].work.proximity) { - for (i=0; i<MAX_CHANNELS; ++i) - { - if (!common->wcmChannel[i].work.proximity) - { - channel = i; - break; - } - } + channel = i; + break; } } - else /* one transducer plus expresskey (pad) is supported */ - { - if (serial == -1) /* pad */ - channel = 1; - else if ( (common->wcmChannel[0].work.proximity && /* existing transducer */ - (common->wcmChannel[0].work.serial_num == serial)) || - !common->wcmChannel[0].work.proximity ) /* new transducer */ - channel = 0; - } - /* All events go to same channel for Protocol 5 */ - private->wcmBTNChannel = channel; } /* fresh out of channels */ @@ -843,10 +810,13 @@ static int usbChooseChannel(WacomCommonPtr common) /* This should never happen in normal use. * Let's start over again. Force prox-out for all channels. */ - for (i=0; i<MAX_CHANNELS; ++i) + for (i=0; i<MAX_CHANNELS; i++) { + if (i == PAD_CHANNEL) + continue; + if (common->wcmChannel[i].work.proximity && - (common->wcmChannel[i].work.serial_num != -1)) + (common->wcmChannel[i].work.serial_num != -1)) { common->wcmChannel[i].work.proximity = 0; /* dispatch event */ @@ -854,11 +824,13 @@ static int usbChooseChannel(WacomCommonPtr common) } } DBG(1, common, "device with serial number: %u" - " at %d: Exceeded channel count; ignoring the events.\n", - serial, (int)GetTimeInMillis()); + " at %d: Exceeded channel count; ignoring the events.\n", + serial, (int)GetTimeInMillis()); } else + { private->wcmLastToolSerial = serial; + } return channel; } -- 1.7.12 ------------------------------------------------------------------------------ How fast is your code? 3 out of 4 devs don\\\'t know how their code performs in production. Find out how slow your code is with AppDynamics Lite. http://ad.doubleclick.net/clk;262219672;13503038;z? http://info.appdynamics.com/FreeJavaPerformanceDownload.html _______________________________________________ Linuxwacom-devel mailing list Linuxwacom-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel