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® 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