On Thu, Oct 21, 2010 at 12:38 PM, Ping Cheng <pingli...@gmail.com> wrote: > On Wed, Oct 20, 2010 at 6:16 PM, <ch...@cnpbagwell.com> wrote: >> From: Chris Bagwell <ch...@cnpbagwell.com> >> >> The core of xf86-input-wacom strictly enforces buttons >> on tools that are out-of-proximity must be cleared except >> for the special case of the PAD device that is always >> considered in proximity. >> >> Simple/Generic tablets (non-wacom) and touchpads will send >> button presses associated with tablet itself even though no >> tools are reported as in proximity. >> >> Work around this by forcing all non-styus button presses >> to be routed to hard coded PAD channel and post multiple >> channel events per sync window. >> >> MT packets could be implemented using same concept and >> routing to hard coded channel 0 or 1 based on finger #. >> >> Signed-off-by: Chris Bagwell <ch...@cnpbagwell.com> >> Reviewed-by: Peter Hutterer <peter.hutte...@who-t.net> >> --- >> src/wcmUSB.c | 110 >> +++++++++++++++++++++++++++++++++++++++++++++++----------- >> 1 files changed, 89 insertions(+), 21 deletions(-) >> >> diff --git a/src/wcmUSB.c b/src/wcmUSB.c >> index eed755e..973e358 100644 >> --- a/src/wcmUSB.c >> +++ b/src/wcmUSB.c >> @@ -35,6 +35,7 @@ >> >> typedef struct { >> int wcmLastToolSerial; >> + int wcmPadChannel; >> int wcmEventCnt; >> struct input_event wcmEvents[MAX_USB_EVENTS]; >> } wcmUSBData; >> @@ -752,6 +753,13 @@ static int usbChooseChannel(WacomCommonPtr common) >> */ >> channel = 0; >> serial = 1; >> + >> + /* Generic devices are only ones that will send >> + * pad buttons without a PAD serial # so hardcode >> + * the reserved channel here. The rest can protocols >> + * can rely on normal channel logic. >> + */ >> + private->wcmPadChannel = MAX_CHANNELS-1; >> } >> else if (common->wcmProtocolLevel == WCM_PROTOCOL_4) >> { >> @@ -784,6 +792,7 @@ static int usbChooseChannel(WacomCommonPtr common) >> channel = serial-1; >> else >> channel = 0; >> + private->wcmPadChannel = channel; >> } >> else if (serial) /* serial number should never be 0 for V5 devices */ >> { >> @@ -834,6 +843,7 @@ static int usbChooseChannel(WacomCommonPtr common) >> !common->wcmChannel[0].work.proximity >> ) /* new transducer */ >> channel = 0; >> } >> + private->wcmPadChannel = channel; >> } >> >> /* fresh out of channels */ >> @@ -950,9 +960,11 @@ skipEvent: >> private->wcmEventCnt = 0; >> } >> >> -static void usbParseAbsEvent(WacomCommonPtr common, >> - struct input_event *event, WacomDeviceState *ds) >> +static int usbParseAbsEvent(WacomCommonPtr common, >> + struct input_event *event, WacomDeviceState *ds) >> { >> + int change = 1; >> + >> switch(event->code) >> { >> case ABS_X: >> @@ -1003,7 +1015,10 @@ static void usbParseAbsEvent(WacomCommonPtr common, >> if (event->value) >> ds->device_id = event->value; >> break; >> + default: >> + change = 0; >> } >> + return change; >> } >> >> static struct >> @@ -1024,16 +1039,18 @@ static struct >> { PAD_ID, BTN_TOOL_FINGER } >> }; >> >> -static void usbParseKeyEvent(WacomCommonPtr common, >> - struct input_event *event, WacomDeviceState *ds, >> - WacomDeviceState *dslast) >> +#define MOD_BUTTONS(bit, value) do { \ >> + shift = 1<<bit; \ >> + ds->buttons = (((value) != 0) ? \ >> + (ds->buttons | (shift)) : (ds->buttons & ~(shift))); \ >> + } while (0) >> + >> +static int usbParseKeyEvent(WacomCommonPtr common, >> + struct input_event *event, WacomDeviceState *ds, >> + WacomDeviceState *dslast) >> { >> - int shift, nkeys; >> - #define MOD_BUTTONS(bit, value) do { \ >> - shift = 1<<bit; \ >> - ds->buttons = (((value) != 0) ? \ >> - (ds->buttons | (shift)) : (ds->buttons & ~(shift))); \ >> - } while (0) >> + int shift; >> + int change = 1; >> >> /* BTN_TOOL_* are sent to indicate when a specific tool is going >> * in our out of proximity. When going out of proximity, ds >> @@ -1046,8 +1063,9 @@ static void usbParseKeyEvent(WacomCommonPtr common, >> * that map to different channels can be in proximity at same >> * time with no confusion. >> * >> - * Remaining part of case state (after BTN_TOOL_*) handle normal >> - * button presses. >> + * Remaining part of case state (after BTN_TOOL_*) handle buttons >> + * on stylus that validaty depends on its tool being in >> + * proximity. >> */ >> switch (event->code) >> { >> @@ -1165,16 +1183,38 @@ static void usbParseKeyEvent(WacomCommonPtr common, >> * combination with the first finger data */ >> break; >> >> + case BTN_STYLUS: >> + MOD_BUTTONS(1, event->value); >> + break; >> + >> + case BTN_STYLUS2: >> + MOD_BUTTONS(2, event->value); >> + break; >> + default: >> + change = 0; >> + } >> + return change; >> +} >> + >> +/* Track buttons associated with always in proximity PAD device. These >> + * are buttons located on tablet itself. >> + */ > > BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, BTN_SIDE, and BTN_EXTRA are the > buttons for CURSOR (mouse/puck, whichever name you use ;-) device. > They are reported through BTN_TOOL_MOUSE. So, PAD should not use them. > That is why BTN_0...9, BTX_A..Z, BTN_BASE... are used for PAD and > those five BTN_* have never been reused for PAD. > > Bamboo doesn't come with a mouse. So, this isn't an issue for you. > But, I have to care about those users who have pucks. Otherwise they > are going to cry ;). > > There are two options for us, I think. > > 1. We don't support BTN_LEFT, etc as default values for PAD, as > we are doing it now, except the freshly baked Bamboo MT patchset. That > is, we'll need to update the Bamboo MT patch to BTN_0 or something. > > The drawback for this option is: we lose the chance to set meaningful > defaults for the buttons in the kernel. The benefit for us is it is > easy to implement. > > 2. We support BTN_LEFT, etc. for PAD as well so we can have good > default settings in the kernel. Then we need something to distinguish > PAD from CURSOR so we could reroute the buttons here. > > Putting an Acked-by tag is easy. Making all the users happy is not so easy... > > Ping
Great comments. I think I can somehow wrap this stuff with WCM_PROTOCOL_GENERIC and resolve the issue. I mean put these "CURSOR" and "PAD" overlapping buttons in both usbParsePadKeyEvent() and usbParseKeyEvent() but only support them in later when wcmProtocolLevel != WCM_PROTOCOL_GENERIC... or maybe only when device_type == CURSOR_ID. Anyways, I'll make a list of the overlapping values and see what patterns emerge. Somehow I had convinced myself there were no overlapping buttons. Stay tuned for v3 of patch #5 and patch #1. Chris > >> +static int usbParsePadKeyEvent(WacomCommonPtr common, >> + struct input_event *event, WacomDeviceState >> *ds) >> +{ >> + int shift, nkeys; >> + int change = 1; >> + >> + switch (event->code) >> + { >> case BTN_LEFT: >> MOD_BUTTONS(0, event->value); >> break; >> >> - case BTN_STYLUS: >> case BTN_MIDDLE: >> MOD_BUTTONS(1, event->value); >> break; >> >> - case BTN_STYLUS2: >> case BTN_RIGHT: >> MOD_BUTTONS(2, event->value); >> break; >> @@ -1196,17 +1236,21 @@ static void usbParseKeyEvent(WacomCommonPtr common, >> break; >> } >> } >> + if (nkeys >= common->npadkeys) >> + change = 0; >> } >> + return change; >> } >> >> static void usbDispatchEvents(InputInfoPtr pInfo) >> { >> int i; >> - WacomDeviceState* ds; >> + WacomDeviceState *ds, *pad_ds; >> struct input_event* event; >> WacomDevicePtr priv = (WacomDevicePtr)pInfo->private; >> WacomCommonPtr common = priv->common; >> int channel; >> + int channel_change = 0, pad_channel_change = 0; >> WacomChannelPtr pChannel; >> WacomDeviceState dslast; >> wcmUSBData* private = common->private; >> @@ -1280,6 +1324,7 @@ static void usbDispatchEvents(InputInfoPtr pInfo) >> ds = &common->wcmChannel[channel].work; >> ds->relwheel = 0; >> ds->serial_num = private->wcmLastToolSerial; >> + pad_ds = &common->wcmChannel[private->wcmPadChannel].work; >> >> /* loop through all events in group */ >> for (i=0; i<private->wcmEventCnt; ++i) >> @@ -1292,19 +1337,28 @@ static void usbDispatchEvents(InputInfoPtr pInfo) >> /* absolute events */ >> if (event->type == EV_ABS) >> { >> - usbParseAbsEvent(common, event, ds); >> + channel_change |= usbParseAbsEvent(common, event, >> ds); >> } >> else if (event->type == EV_REL) >> { >> if (event->code == REL_WHEEL) >> + { >> ds->relwheel = -event->value; >> + channel_change |= 1; >> + } >> else >> xf86Msg(X_ERROR, "%s: rel event recv'd >> (%d)!\n", >> pInfo->name, event->code); >> } >> - >> else if (event->type == EV_KEY) >> - usbParseKeyEvent(common, event, ds, &dslast); >> + { >> + if (usbParseKeyEvent(common, event, ds, &dslast)) >> + channel_change |= 1; >> + else >> + pad_channel_change |= >> + usbParsePadKeyEvent(common, event, >> + pad_ds); >> + } >> } /* next event */ >> >> /* device type unknown? Tool may be on the tablet when X starts. */ >> @@ -1342,8 +1396,22 @@ static void usbDispatchEvents(InputInfoPtr pInfo) >> if (!ds->proximity) >> private->wcmLastToolSerial = 0; >> >> - /* dispatch event */ >> - wcmEvent(common, channel, ds); >> + /* dispatch tool event */ >> + if (channel_change) >> + wcmEvent(common, channel, ds); >> + /* dispatch pad event */ >> + if (pad_channel_change) >> + { >> + /* Force to in proximity for special case */ >> + if (common->wcmProtocolLevel == WCM_PROTOCOL_GENERIC) >> + { >> + pad_ds->proximity = 1; >> + pad_ds->device_type = PAD_ID; >> + pad_ds->device_id = PAD_DEVICE_ID; >> + pad_ds->serial_num = 0xf0; >> + } >> + wcmEvent(common, private->wcmPadChannel, pad_ds); >> + } >> } >> >> /** >> -- >> 1.7.3.1 >> >> >> ------------------------------------------------------------------------------ >> Nokia and AT&T present the 2010 Calling All Innovators-North America contest >> Create new apps & games for the Nokia N8 for consumers in U.S. and Canada >> $10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing >> Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store >> http://p.sf.net/sfu/nokia-dev2dev >> _______________________________________________ >> Linuxwacom-devel mailing list >> Linuxwacom-devel@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel >> > ------------------------------------------------------------------------------ Nokia and AT&T present the 2010 Calling All Innovators-North America contest Create new apps & games for the Nokia N8 for consumers in U.S. and Canada $10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store http://p.sf.net/sfu/nokia-dev2dev _______________________________________________ Linuxwacom-devel mailing list Linuxwacom-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel