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