From: Chris Bagwell <ch...@cnpbagwell.com>

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 map ST-style events to channel 0 and then MT packets will
write to either channel 0 or 1 or both.

For MT case of 1st finger, we will updated X/Y/PRESSURE values 2 times
but left it this way for simplicity (we only dispatch 1 time correctly).

Signed-off-by: Chris Bagwell <ch...@cnpbagwell.com>
---
 src/wcmUSB.c |   75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/src/wcmUSB.c b/src/wcmUSB.c
index 6427adf..517ca04 100644
--- a/src/wcmUSB.c
+++ b/src/wcmUSB.c
@@ -36,6 +36,7 @@
 typedef struct {
        int wcmLastToolSerial;
        int wcmBTNChannel;
+       int wcmMTChannel;
        int wcmEventCnt;
        struct input_event wcmEvents[MAX_USB_EVENTS];
 } wcmUSBData;
@@ -831,6 +832,57 @@ static int usbParseAbsEvent(WacomCommonPtr common,
        return change;
 }
 
+static int usbParseAbsMTEvent(WacomCommonPtr common, struct input_event *event)
+{
+#ifndef ABS_MT_SLOT
+       /* requires Linux 2.6.36 or newer */
+       return 0;
+#else
+       int change = 1;
+       wcmUSBData* private = common->private;
+       WacomDeviceState *ds, *dslast;
+
+       ds = &common->wcmChannel[private->wcmMTChannel].work;
+       dslast = &common->wcmChannel[private->wcmMTChannel].valid.state;
+
+       switch(event->code)
+       {
+               case ABS_MT_SLOT:
+                       if (event->value >= 0 && event->value < MAX_FINGERS)
+                       {
+                               private->wcmMTChannel = event->value;
+                               ds = &common->
+                                       wcmChannel[private->wcmMTChannel].work;
+                               ds->device_type = TOUCH_ID;
+                               ds->device_id = TOUCH_DEVICE_ID;
+                               ds->serial_num = event->value+1;
+                       }
+                       break;
+
+               case ABS_MT_TRACKING_ID:
+                       ds->proximity = (event->value != -1);
+
+                       /* time stamp of proximity change for gestures */
+                       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;
+               default:
+                       change = 0;
+       }
+       return change;
+#endif
+}
+
 static struct
 {
        unsigned long device_type;
@@ -1063,7 +1115,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, mt1_channel_change = 0;
        WacomChannelPtr pChannel;
        WacomDeviceState dslast;
        wcmUSBData* private = common->private;
@@ -1151,7 +1203,15 @@ static void usbDispatchEvents(InputInfoPtr pInfo)
                /* 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)
+                                       mt1_channel_change |= 1;
+                       }
                }
                else if (event->type == EV_REL)
                {
@@ -1225,6 +1285,17 @@ static void usbDispatchEvents(InputInfoPtr pInfo)
                btn_ds->serial_num = 0xf0;
                wcmEvent(common, private->wcmBTNChannel, btn_ds);
        }
+
+       /* dispatch for second finger.  first finger is handled above. */
+       if (mt1_channel_change)
+       {
+               WacomDeviceState *mt1_ds;
+
+               mt1_ds = &common->wcmChannel[private->wcmMTChannel].work;
+               wcmEvent(common, 1, mt1_ds);
+       }
+
+
 }
 
 /**
-- 
1.7.3.2


------------------------------------------------------------------------------
The Next 800 Companies to Lead America's Growth: New Video Whitepaper
David G. Thomson, author of the best-selling book "Blueprint to a 
Billion" shares his insights and actions to help propel your 
business during the next growth cycle. Listen Now!
http://p.sf.net/sfu/SAP-dev2dev
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to