On Mon, Dec 20, 2010 at 02:07:14PM -0600, ch...@cnpbagwell.com wrote: > From: Chris Bagwell <ch...@cnpbagwell.com> > > This patch adds support for processing multi-touch (MT) kernel events. > To do this, it must filter out older style single touch (ST) events > to prevent conflicts. > > For Bamboo's/Tablet PC, channel 0 == 1st finger and channel 1 == 2nd finger. > > In older Bamboo kernel driver, serial #1 == 1st finger and serial #2 == > 2nd finger. Mapping to channel was serial # - 1 and events had to > come in isolated by separate BTN_TOOL_DOUBLETAP/TRIPLETAP messages. > > With newer MT kernel driver, MT slot 0 == 1st finger and MT slot 1 == > 2nd finger. Take advantage of this straight mapping to channel. > Code will ignore ST-style events then MT packets will write to > either channel 0 or 1 or both. > > Signed-off-by: Chris Bagwell <ch...@cnpbagwell.com> > --- > > Updated based on Peter's comments.
just for the future: please replace PATCH with PATCH v2, v3, etc. depending on the version. it makes it a lot easier to go back through email archives to figure out which patch is the latest. especially since comments on patches don't always come in-order of the patches sent (more of a problem on other lists,but it's a good habit to get into) merged, thanks Cheers, Peter > src/wcmUSB.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++---- > src/xf86WacomDefs.h | 28 ++++++++++ > 2 files changed, 154 insertions(+), 11 deletions(-) > > diff --git a/src/wcmUSB.c b/src/wcmUSB.c > index 1d54b3f..655d59a 100644 > --- a/src/wcmUSB.c > +++ b/src/wcmUSB.c > @@ -33,6 +33,8 @@ > typedef struct { > int wcmLastToolSerial; > int wcmBTNChannel; > + Bool wcmUseMT; > + int wcmMTChannel; > int wcmEventCnt; > struct input_event wcmEvents[MAX_USB_EVENTS]; > } wcmUSBData; > @@ -410,6 +412,7 @@ int usbWcmGetRanges(InputInfoPtr pInfo) > unsigned long abs[NBITS(ABS_MAX)] = {0}; > WacomDevicePtr priv = (WacomDevicePtr)pInfo->private; > WacomCommonPtr common = priv->common; > + wcmUSBData* private = common->private; > int is_touch = IsTouch(priv); > > /* Devices such as Bamboo P&T may have Pad data reported in the same > @@ -509,6 +512,8 @@ int usbWcmGetRanges(InputInfoPtr pInfo) > if (ioctl(pInfo->fd, EVIOCGABS(ABS_DISTANCE), &absinfo) == 0) > common->wcmMaxDist = absinfo.maximum; > > + if (ISBITSET(common->wcmKeys, ABS_MT_SLOT)) > + private->wcmUseMT = 1; > if ((common->tablet_id >= 0xd0) && (common->tablet_id <= 0xd3)) > { > @@ -788,6 +793,55 @@ skipEvent: > private->wcmEventCnt = 0; > } > > +static int usbFilterEvent(WacomCommonPtr common, struct input_event *event) > +{ > + wcmUSBData* private = common->private; > + > + /* For devices that report multitouch, the following list is a set of > + * duplicate data from one slot and needs to be filtered out. > + */ > + if (private->wcmUseMT) > + { > + if (event->type == EV_KEY) > + { > + switch(event->code) > + { > + case BTN_TOUCH: > + case BTN_TOOL_FINGER: > + return 1; > + } > + } > + else if (event->type == EV_ABS) > + { > + switch(event->code) > + { > + case ABS_X: > + case ABS_Y: > + case ABS_PRESSURE: > + return 1; > + } > + } > + } > + > + /* For generic devices, filter out doubletap/tripletap that > + * can be confused with older protocol. > + */ > + if (common->wcmProtocolLevel == WCM_PROTOCOL_GENERIC) > + { > + if (event->type == EV_ABS) > + { > + switch(event->code) > + { > + case BTN_TOOL_DOUBLETAP: > + case BTN_TOOL_TRIPLETAP: > + return 1; > + } > + } > + } > + > + return 0; > +} > + > static int usbParseAbsEvent(WacomCommonPtr common, > struct input_event *event, WacomDeviceState *ds) > { > @@ -844,6 +898,55 @@ static int usbParseAbsEvent(WacomCommonPtr common, > return change; > } > > +static int usbParseAbsMTEvent(WacomCommonPtr common, struct input_event > *event) > +{ > + int change = 1; > + wcmUSBData* private = common->private; > + WacomDeviceState *ds; > + > + ds = &common->wcmChannel[private->wcmMTChannel].work; > + > + switch(event->code) > + { > + case ABS_MT_SLOT: > + if (event->value >= 0 && event->value < MAX_FINGERS) > + { > + WacomDeviceState *dsnew; > + > + private->wcmMTChannel = event->value; > + dsnew = &common-> > + wcmChannel[private->wcmMTChannel].work; > + > + dsnew->device_type = TOUCH_ID; > + dsnew->device_id = TOUCH_DEVICE_ID; > + dsnew->serial_num = event->value+1; > + } > + break; > + > + case ABS_MT_TRACKING_ID: > + ds->proximity = (event->value != -1); > + > + ds->sample = (int)GetTimeInMillis(); > + break; > + > + case ABS_MT_POSITION_X: > + ds->x = event->value; > + break; > + > + case ABS_MT_POSITION_Y: > + ds->y = event->value; > + break; > + > + case ABS_MT_PRESSURE: > + ds->capacity = event->value; > + break; > + > + default: > + change = 0; > + } > + return change; > +} > + > static struct > { > unsigned long device_type; > @@ -947,11 +1050,6 @@ static int usbParseKeyEvent(WacomCommonPtr common, > > /* fall through */ > case BTN_TOOL_DOUBLETAP: > - /* If a real double tap report, ignore. */ > - if (common->wcmProtocolLevel == WCM_PROTOCOL_GENERIC && > - event->code == BTN_TOOL_DOUBLETAP) > - break; > - > DBG(6, common, > "USB Touch detected %x (value=%d)\n", > event->code, event->value); > @@ -977,10 +1075,6 @@ static int usbParseKeyEvent(WacomCommonPtr common, > break; > > case BTN_TOOL_TRIPLETAP: > - /* If a real triple tap report, ignore. */ > - if (common->wcmProtocolLevel == WCM_PROTOCOL_GENERIC) > - break; > - > DBG(6, common, > "USB Touch second finger detected %x (value=%d)\n", > event->code, event->value); > @@ -1080,7 +1174,7 @@ static void usbDispatchEvents(InputInfoPtr pInfo) > WacomDevicePtr priv = (WacomDevicePtr)pInfo->private; > WacomCommonPtr common = priv->common; > int channel; > - int channel_change = 0, btn_channel_change = 0; > + int channel_change = 0, btn_channel_change = 0, mt_channel_change = 0; > WacomChannelPtr pChannel; > WacomDeviceState dslast; > wcmUSBData* private = common->private; > @@ -1165,10 +1259,22 @@ static void usbDispatchEvents(InputInfoPtr pInfo) > "event[%d]->type=%d code=%d value=%d\n", > i, event->type, event->code, event->value); > > + /* Check for events to be ignored and skip them up front. */ > + if (usbFilterEvent(common, event)) > + continue; > + > /* absolute events */ > if (event->type == EV_ABS) > { > - channel_change |= usbParseAbsEvent(common, event, ds); > + if (usbParseAbsEvent(common, event, ds)) > + channel_change |= 1; > + else if (usbParseAbsMTEvent(common, event)) > + { > + if (private->wcmMTChannel == 0) > + channel_change |= 1; > + else if (private->wcmMTChannel == 1) > + mt_channel_change |= 1; > + } > } > else if (event->type == EV_REL) > { > @@ -1232,6 +1338,15 @@ static void usbDispatchEvents(InputInfoPtr pInfo) > (private->wcmBTNChannel == channel && btn_channel_change)) > wcmEvent(common, channel, ds); > > + /* dispatch for second finger. first finger is handled above. */ > + if (mt_channel_change) > + { > + WacomDeviceState *mt_ds; > + > + mt_ds = &common->wcmChannel[1].work; > + wcmEvent(common, 1, mt_ds); > + } > + > /* dispatch butten events when re-routed */ > if (private->wcmBTNChannel != channel && btn_channel_change) > { > diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h > index 87d75d5..b8c94b3 100644 > --- a/src/xf86WacomDefs.h > +++ b/src/xf86WacomDefs.h > @@ -47,6 +47,8 @@ > #define PROXOUT_INTUOS_DISTANCE 10 > #define PROXOUT_GRAPHIRE_DISTANCE 42 > > +/* 2.6.28 */ > + > #ifndef BTN_TOOL_DOUBLETAP > #define BTN_TOOL_DOUBLETAP 0x14d > #endif > @@ -55,6 +57,32 @@ > #define BTN_TOOL_TRIPLETAP 0x14e > #endif > > +/* 2.6.30 */ > + > +#ifndef ABS_MT_POSITION_X > +#define ABS_MT_POSITION_X 0x35 > +#endif > + > +#ifndef ABS_MT_POSITION_Y > +#define ABS_MT_POSITION_Y 0x36 > +#endif > + > +#ifndef ABS_MT_TRACKING_ID > +#define ABS_MT_TRACKING_ID 0x39 > +#endif > + > +/* 2.6.33 */ > + > +#ifndef ABS_MT_PRESSURE > +#define ABS_MT_PRESSURE 0x3a > +#endif > + > +/* 2.6.36 */ > + > +#ifndef ABS_MT_SLOT > +#define ABS_MT_SLOT 0x2f > +#endif > + > /* defines to discriminate second side button and the eraser */ > #define ERASER_PROX 4 > #define OTHER_PROX 1 > -- > 1.7.3.3 ------------------------------------------------------------------------------ Lotusphere 2011 Register now for Lotusphere 2011 and learn how to connect the dots, take your collaborative environment to the next level, and enter the era of Social Business. http://p.sf.net/sfu/lotusphere-d2d _______________________________________________ Linuxwacom-devel mailing list Linuxwacom-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel