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

Reply via email to