On Thu, Oct 21, 2010 at 12:38 PM, Ping Cheng <[email protected]> wrote:
> On Wed, Oct 20, 2010 at 6:16 PM, <[email protected]> wrote:
>> From: Chris Bagwell <[email protected]>
>>
>> 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 <[email protected]>
>> Reviewed-by: Peter Hutterer <[email protected]>
>> ---
>> 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
>> [email protected]
>> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel