On Mon, Mar 21, 2011 at 02:09:58PM -0700, Ping Cheng wrote:
> Serial ISDv4 kernel driver, wacom_w8001.ko, provides both pen and
> touch events on the same logical port. Filtering touch events when
> pen is in proximity while allowing pen events (ABS_X/Y, etc) pass.
> 
> Making this action configurable would make sense when XInput 2.1 is
> ready. At that point, we can post MT valuators while pen events are
> posted. Some code refactoring is needed to add a new channel to
> store the pen data as well as the 2FGT data.
> 
> Defering the code refactoring until we support XInput 2.1.
> 
> Signed-off-by: Ping Cheng <[email protected]>
> Reviewed-by: Peter Hutterer <[email protected]>
> Reviewed-by: Chris Bagwell <[email protected]>
> ---
> v3 changes: Incorporated Chris' comments. Added Reviewed-by.
> ---
>  src/wcmUSB.c |  108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
>  1 files changed, 102 insertions(+), 6 deletions(-)
> 
> diff --git a/src/wcmUSB.c b/src/wcmUSB.c
> index 9e0f310..82a0195 100644
> --- a/src/wcmUSB.c
> +++ b/src/wcmUSB.c
> @@ -33,6 +33,8 @@
>  typedef struct {
>       int wcmLastToolSerial;
>       int wcmBTNChannel;
> +     int wcmDeviceType;
> +     Bool wcmPenTouch;
>       Bool wcmUseMT;
>       int wcmMTChannel;
>       int wcmPrevChannel;
> @@ -571,8 +573,14 @@ int usbWcmGetRanges(InputInfoPtr pInfo)
>               common->wcmMaxDist = absinfo.maximum;
>  
>       if (ISBITSET(abs, ABS_MT_SLOT))
> +     {
>               private->wcmUseMT = 1;
>  
> +             /* pen and MT on the same logical port */
> +             if (ISBITSET(common->wcmKeys, BTN_TOOL_PEN))
> +                     private->wcmPenTouch = TRUE;
> +     }
> +
>       /* A generic protocol device does not report ABS_MISC event */
>       if (!ISBITSET(abs, ABS_MISC))
>               common->wcmProtocolLevel = WCM_PROTOCOL_GENERIC;
> @@ -865,12 +873,29 @@ static int usbFilterEvent(WacomCommonPtr common, struct 
> input_event *event)
>               }
>               else if (event->type == EV_ABS)
>               {
> -                     switch(event->code)
> +                     if (private->wcmDeviceType == TOUCH_ID)
>                       {
> -                             case ABS_X:
> -                             case ABS_Y:
> -                             case ABS_PRESSURE:
> -                                     return 1;
> +                             /* filter ST for MT */
> +                             switch(event->code)
> +                             {
> +                                     case ABS_X:
> +                                     case ABS_Y:
> +                                     case ABS_PRESSURE:
> +                                             return 1;
> +                             }
> +                     }
> +                     else
> +                     {
> +                             /* filter MT for pen */
> +                             switch(event->code)
> +                             {
> +                                     case ABS_MT_SLOT:
> +                                     case ABS_MT_TRACKING_ID:
> +                                     case ABS_MT_POSITION_X:
> +                                     case ABS_MT_POSITION_Y:
> +                                     case ABS_MT_PRESSURE:
> +                                             return 1;
> +                             }
>                       }
>               }
>       }
> @@ -1219,6 +1244,59 @@ static int usbParseBTNEvent(WacomCommonPtr common,
>       return 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 data A pointer to struct wcmUSBData to access device specific data.
> + */
> +static void usbInitToolType(wcmUSBData *data)

please make this a function of type
static int usbInitToolType(const struct input_event *events, int nevents)


> +{
> +     int i;
> +     struct input_event* event;
> +
> +     /* default to 0 if no pen/touch/eraser event code is in the packet */
> +     data->wcmDeviceType = 0;
> +
> +     for (i = 0; (i < data->wcmEventCnt) && !data->wcmDeviceType; ++i)
> +     {
> +             event = data->wcmEvents + i;
> +
> +             switch (event->code)
> +             {
> +                     case BTN_TOOL_PEN:
> +                     case BTN_TOOL_PENCIL:
> +                     case BTN_TOOL_BRUSH:
> +                     case BTN_TOOL_AIRBRUSH:
> +                             data->wcmDeviceType = STYLUS_ID;
> +                             break;
> +
> +                     case BTN_TOOL_FINGER:
> +                     case ABS_MT_SLOT:
> +                     case ABS_MT_TRACKING_ID:
> +                             data->wcmDeviceType = TOUCH_ID;
> +                             break;
> +
> +                     case BTN_TOOL_RUBBER:
> +                             data->wcmDeviceType = ERASER_ID;
> +                             break;
> +             }
> +     }
> +}
> +
> +/**
> + * Check if the tool is a stlys/eraser and in-prox or not.
> + *
> + * @param ds The tool state stored in wcmChannel
> + * @return True if stlys/eraser is in-prox; False otherwise.
> + */
> +static Bool usbIsPenInProx(WacomDeviceState ds)

please make this a function of type Bool (int, int)

Cheers,
  Peter

> +{
> +     Bool is_pen = (ds.device_type == STYLUS_ID) ||
> +                     (ds.device_type == ERASER_ID);
> +     return (is_pen && ds.proximity);
> +}
> +
>  static void usbDispatchEvents(InputInfoPtr pInfo)
>  {
>       int i;
> @@ -1228,11 +1306,29 @@ static void usbDispatchEvents(InputInfoPtr pInfo)
>       WacomCommonPtr common = priv->common;
>       int channel;
>       int channel_change = 0, btn_channel_change = 0, mt_channel_change = 0;
> -     WacomDeviceState dslast;
> +     WacomDeviceState dslast = common->wcmChannel[0].valid.state;
>       wcmUSBData* private = common->private;
>  
>       DBG(6, common, "%d events received\n", private->wcmEventCnt);
>  
> +     if (private->wcmPenTouch)
> +     {
> +             usbInitToolType(private);
> +
> +             /* We get both pen and touch data from the kernel when they
> +              * both are in/down. So, if we were (hence the need of dslast)
> +              * processing pen events, we should ignore touch events.
> +              *
> +              * MT events will be posted to the userland when XInput 2.1
> +              * is ready.
> +              */
> +             if ((private->wcmDeviceType == TOUCH_ID) && 
> usbIsPenInProx(dslast))
> +             {
> +                     private->wcmEventCnt = 0;
> +                     return;
> +             }
> +     }
> +
>       channel = usbChooseChannel(common);
>  
>       /* couldn't decide channel? invalid data */
> -- 
> 1.7.4


------------------------------------------------------------------------------
Enable your software for Intel(R) Active Management Technology to meet the
growing manageability and security demands of your customers. Businesses
are taking advantage of Intel(R) vPro (TM) technology - will your software 
be a part of the solution? Download the Intel(R) Manageability Checker 
today! http://p.sf.net/sfu/intel-dev2devmar
_______________________________________________
Linuxwacom-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to