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>
---
Updating my patch so it applies against current git for people
playing around with 2.6.37 kernels.  It doesn't need to be 
commited yet.

There is still FIXME in this to resolve and Ping is working out
long term MT plans still.

 src/wcmUSB.c |   76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/src/wcmUSB.c b/src/wcmUSB.c
index 90e8cf6..f54994f 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;
@@ -839,6 +840,60 @@ static int usbParseAbsEvent(WacomCommonPtr common,
        return change;
 }
 
+/* FIXME: I'm compiling against 2.6.35 header files in /usr/include/linux */
+#define ABS_MT_SLOT 0x2f
+
+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;
@@ -1078,7 +1133,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;
@@ -1166,7 +1221,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)
                {
@@ -1230,6 +1293,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 (mt1_channel_change)
+       {
+               WacomDeviceState *mt1_ds;
+
+               mt1_ds = &common->wcmChannel[private->wcmMTChannel].work;
+               wcmEvent(common, 1, mt1_ds);
+       }
+
        /* dispatch butten events when re-routed */
        if (private->wcmBTNChannel != channel && btn_channel_change)
        {
-- 
1.7.3.2


------------------------------------------------------------------------------
Increase Visibility of Your 3D Game App & Earn a Chance To Win $500!
Tap into the largest installed PC base & get more eyes on your game by
optimizing for Intel(R) Graphics Technology. Get started today with the
Intel(R) Software Partner Program. Five $500 cash prizes are up for grabs.
http://p.sf.net/sfu/intelisp-dev2dev
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to