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

Bamboo P&T code supports multi-touch but is using the
standard input driver's ABS_X/Y/PRESSURE which filters
duplicate events since it does not know they are unrelated.
Its also using Wacom-specific "serial channels" concept
to inform X driver which finger is currently being
sent.

Starting with kernel 2.6.30, a multi-touch interface was
added to the kernel input layer to address this issue for all
modern multi-touch input devices.

This patch converts the 2 finger touch events over to this
multi-touch interface.  It is backwards compatible in that
pre-existing wacom X drivers will see the first finger's
events using standard ABS_X/Y/PRESSURE interface.

Additional updates are needed to xdrv to support processing
these new MT events.

Signed-off-by: Chris Bagwell <ch...@cnpbagwell.com>
---
 src/2.6.27/wacom.h     |    1 +
 src/2.6.27/wacom_sys.c |   23 ++++++++--
 src/2.6.27/wacom_wac.c |  120 +++++++++++++++++-------------------------------
 3 files changed, 62 insertions(+), 82 deletions(-)

diff --git a/src/2.6.27/wacom.h b/src/2.6.27/wacom.h
index 5ec8abf..60a5fa2 100755
--- a/src/2.6.27/wacom.h
+++ b/src/2.6.27/wacom.h
@@ -134,6 +134,7 @@ extern void wacom_report_rel(void *wcombo, unsigned int 
rel_type, int rel_data);
 extern void wacom_report_key(void *wcombo, unsigned int key_type, int 
key_data);
 extern void wacom_input_event(void *wcombo, unsigned int type, unsigned int 
code, int value);
 extern void wacom_input_sync(void *wcombo);
+extern void wacom_input_mt_sync(void *wcombo);
 extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac 
*wacom_wac);
 extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac 
*wacom_wac);
 extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac 
*wacom_wac);
diff --git a/src/2.6.27/wacom_sys.c b/src/2.6.27/wacom_sys.c
index 93947b0..14ca963 100755
--- a/src/2.6.27/wacom_sys.c
+++ b/src/2.6.27/wacom_sys.c
@@ -160,6 +160,12 @@ void wacom_input_sync(void *wcombo)
        input_sync(get_input_dev((struct wacom_combo *)wcombo));
 }
 
+void wacom_input_mt_sync(void *wcombo)
+{
+       input_mt_sync(get_input_dev((struct wacom_combo *)wcombo));
+}
+
+
 static int wacom_open(struct input_dev *dev)
 {
        struct wacom *wacom = input_get_drvdata(dev);
@@ -201,12 +207,21 @@ void input_dev_bpt(struct input_dev *input_dev, struct 
wacom_wac *wacom_wac)
 {
        /* 2FGT */
        if (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) {
-               input_set_abs_params(input_dev, ABS_RX, 0,
-                       wacom_wac->features->x_phy, 0, 0);
+               input_set_abs_params(input_dev, ABS_RX, 0, 
+                                    wacom_wac->features->x_phy, 0, 0);
                input_set_abs_params(input_dev, ABS_RY, 0,
-                       wacom_wac->features->y_phy, 0, 0);
-               input_dev->keybit[BIT_WORD(BTN_DIGI)] |= 
BIT_MASK(BTN_TOOL_DOUBLETAP);
+                                    wacom_wac->features->y_phy, 0, 0);
+
+               /* finger position */
+               input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,
+                                    wacom_wac->features->x_max, 0, 0);
+               input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,
+                                    wacom_wac->features->y_max, 0, 0);
+               input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0,
+                                    wacom_wac->features->pressure_max, 0, 0);
+
                input_dev->keybit[BIT_WORD(BTN_DIGI)] |= 
BIT_MASK(BTN_TOOL_TRIPLETAP);
+               input_dev->keybit[BIT_WORD(BTN_DIGI)] |= 
BIT_MASK(BTN_TOOL_DOUBLETAP);
                input_dev->keybit[BIT_WORD(BTN_DIGI)] |= 
BIT_MASK(BTN_TOOL_FINGER);
                input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) |
                        BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3);
diff --git a/src/2.6.27/wacom_wac.c b/src/2.6.27/wacom_wac.c
index 13d441b..eb14cd0 100755
--- a/src/2.6.27/wacom_wac.c
+++ b/src/2.6.27/wacom_wac.c
@@ -150,80 +150,54 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void 
*wcombo)
        return 1;
 }
 
-static void wacom_bpt_finger_in(struct wacom_wac *wacom, void *wcombo, char 
*data, int idx)
+static void wacom_bpt_touch(struct wacom_wac *wacom, void *wcombo,
+                           int force_out)
 {
-       int x = 0, y = 0, pressure;
-       int finger = idx + 1;
+       char *data = wacom->data;
+       int pressure1 = 0, x1 = 0, y1 = 0, pressure2 = 0, x2 = 0, y2 = 0;
+       int prox1 = 0, prox2 = 0;
+
+       if (!force_out)
+       {
+           prox1 = data[3] & 0x80;
+           if (prox1)
+           {
+               pressure1 = (data[2] & 0xff);
+               x1 = wacom_be16_to_cpu ((unsigned char *)&data[3]) & 0x7ff;
+               y1 = wacom_be16_to_cpu ((unsigned char *)&data[5]) & 0x7ff;
+           }
+
+           prox2 = data[12] & 0x80;
+           if (prox2)
+           {
+               pressure2 = (data[11] & 0xff);
+               x2 = wacom_be16_to_cpu ((unsigned char *)&data[12]) & 0x7ff;
+               y2 = wacom_be16_to_cpu ((unsigned char *)&data[14]) & 0x7ff;
+           }
+       }
 
-       pressure = (data[2 + (idx * 9)] & 0xff);
-       x = wacom_be16_to_cpu ((unsigned char *)&data[3 + (idx * 9)]) & 0x7ff;
-       y = wacom_be16_to_cpu ((unsigned char *)&data[5 + (idx * 9)]) & 0x7ff;
+       wacom_report_abs(wcombo, ABS_MT_TOUCH_MAJOR, prox1 != 0);
+       wacom_report_abs(wcombo, ABS_MT_POSITION_X, x1);
+       wacom_report_abs(wcombo, ABS_MT_POSITION_Y, y1);
 
-       wacom_report_abs(wcombo, ABS_X, x + idx);
-       wacom_report_abs(wcombo, ABS_Y, y + idx);
-       wacom_report_abs(wcombo, ABS_PRESSURE, pressure + idx);
-       wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
-       wacom_report_key(wcombo, wacom->tool[idx], 1);
+       wacom_input_mt_sync(wcombo);
 
-       if (!idx)
-               wacom_report_key(wcombo, BTN_TOUCH, 1);
-       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, finger);
-}
+       wacom_report_abs(wcombo, ABS_MT_TOUCH_MAJOR, prox2 != 0);
+       wacom_report_abs(wcombo, ABS_MT_POSITION_X, x2);
+       wacom_report_abs(wcombo, ABS_MT_POSITION_Y, y2);
 
-static void wacom_bpt_touch_out(struct wacom_wac *wacom, void *wcombo, int idx)
-{
-       int finger = idx + 1;
+       wacom_input_mt_sync(wcombo);
 
-       wacom_report_abs(wcombo, ABS_X, 0);
-       wacom_report_abs(wcombo, ABS_Y, 0);
-       wacom_report_abs(wcombo, ABS_PRESSURE, 0);
-       wacom_report_abs(wcombo, ABS_MISC, 0);
-       wacom_report_key(wcombo, wacom->tool[idx], 0);
+       wacom_report_key(wcombo, BTN_TOOL_DOUBLETAP, prox1);
 
-       if (!idx)
-               wacom_report_key(wcombo, BTN_TOUCH, 0);
-       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, finger);
-}
+       wacom_report_abs(wcombo, ABS_PRESSURE, pressure1);
+       wacom_report_abs(wcombo, ABS_X, x1);
+       wacom_report_abs(wcombo, ABS_Y, y1);
 
-static void wacom_bpt_touch_in(struct wacom_wac *wacom, void *wcombo)
-{
-       char *data = wacom->data;
-       static int firstFinger = 0;
-       static int secondFinger = 0;
-
-       wacom->tool[0] = BTN_TOOL_DOUBLETAP; 
-       wacom->id[0] = TOUCH_DEVICE_ID; 
-       wacom->tool[1] = BTN_TOOL_TRIPLETAP;
-       wacom->id[1] = (((data[3] & 0x80) >> 7) & 0x1) |
-                      (((data[12] & 0x80) >> 6) & 0x2);
-
-       /* First finger down */
-       if (data[3] & 0x80) {
-               wacom_bpt_finger_in(wacom, wcombo, data, 0);
-               firstFinger = 1;
-       } else if (firstFinger) {
-               wacom_bpt_touch_out(wacom, wcombo, 0);
-       }
-
-       /* Second finger down */
-       if (data[12] & 0x80) {
-               /* sync first finger data */
-               if (firstFinger)
-                       wacom_input_sync(wcombo);
+       wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID);
+       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 1);
+       wacom_input_sync(wcombo);
 
-               wacom_bpt_finger_in(wacom, wcombo, data, 1);
-               secondFinger = 1;
-       } else if (secondFinger) {
-               /* sync first finger data */
-               if (firstFinger)
-                       wacom_input_sync(wcombo);
-
-               wacom_bpt_touch_out(wacom, wcombo, 1);
-               secondFinger = 0;
-       }
-
-       if (!(data[3] & 0x80))
-               firstFinger = 0;
 }
 
 static int wacom_bpt_irq(struct wacom_wac *wacom, void *wcombo)
@@ -265,28 +239,18 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, void 
*wcombo)
                if (!stylusInProx) {
                        if (prox) {
                                if (touchInProx) {
-                                       wacom_bpt_touch_in(wacom, wcombo);
+                                       wacom_bpt_touch(wacom, wcombo, 0);
                                        touchOut = 1;
                                        retval = 1;
                                }
                        } else {
-                               if (wacom->id[1] & 0x1) {
-                                       wacom_bpt_touch_out(wacom, wcombo, 0);
-                                       /* sync first finger event */
-                                       if (wacom->id[1] & 0x2) {
-                                               wacom_input_sync(wcombo);
-                                       }
-                               }
-                               if (wacom->id[1] & 0x2) {
-                                       wacom_bpt_touch_out(wacom, wcombo, 1);
-                               }
+                               wacom_bpt_touch(wacom, wcombo, 1);
                                touchOut = 0;
                                touchInProx = 1;
                                retval = 1;
                        }
                } else if (touchOut || !prox) { /* force touch out-prox */
-                       wacom_bpt_touch_out(wacom, wcombo, 0);
-                       wacom_bpt_touch_out(wacom, wcombo, 1);
+                       wacom_bpt_touch(wacom, wcombo, 1);
 
                        touchOut = 0;
                        touchInProx = 1;
-- 
1.6.6.1


------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to