Hello all,
I've been over on the Ubuntu list, and I was asked to put the latest
patch over here. I figured the devel list was the best place to send
this. I just got done testing a second revision of the patch. The
other patch I'm attaching (linuxwacom-0.8.5-9-spelling.patch) is a
spelling correction of the function xf86WcmVirtualTabletSize (spelled
virtaul in the code). The patch gets pen working again on the Bamboo
P&T tablets 0xd0-0xd4 and fixes the touch scaling for 0xd0-0xd3
tablets with touch.
As far a bugs, the gesture scrolling and zooming is still not working
reliably. I think there is more work that needs to be done on the
kernel side to clean up the finger up events since it is
differentiating between which finger was released and the X driver may
see the first finger lift while the second is still down, which gets
the cursor locked in gesture mode. Also if the tablet is plugged in
after X is already running (even gdm), HAL will send the pad and touch
devices out of order and pad gets all the good data about what the
size of the tablet should be. Seems like there is no good place to
try and copy the pad data over to the touch subdevice to alleviate
this problem and with HAL going away, it might not be worth it to fix
it.
I've tried to describe the changes clearly below, but please let me
know if you have any questions.
Thanks,
Jason
A summary of the changes in linuxwacom-0.8.5-9-2.patch is below:
src/2.6.27/wacom_sys.c:
* input_set_abs_params for input_dev_bpt now sends
wacom_wac->features->x_max/y_max for both pen and touch interfaces.
* changed pktlen for BAMBOO_PT to WACOM_PKGLEN_BBFUN since
the 0xd0-0xd4 devices have a pen packet length of 9.
* send features->x_phy/y_phy for ABS_X and ABS_X since tablet size is
480x320 and those numbers appear in the phy variables, max variables
are 12000x8000 for the touch interface.
* added spin_lock_init back in to support spin_locks in the wacom_bpt_irq
interrupt handler.
src/2.6.27/wacom_wac.c
* added a debug printout of the data from the tablet
* added spin_lock/spin_unlock calls around static data access.
(note: without these major crashes happen when you have your hand
resting on the tablet while using the pen, since both packets are being
sent from the tablet simultaneously in that case).
* change all references of pen length from WACOM_PKGLEN_GRAPHIRE
to WACOM_PKGLEN_BBFUN since the pen packet length is 9 for devices
0xd0-0xd4.
src/2.6.27/wacom_wac.h
* added extern reference to bpt_lock spinlock_t variable for use in
wacom_sys.c
src/xdrv/wcmCommon.c
* reordered the one/two finger touch routines in wcmEvent since the
common->wcmGesture variable was being used to determine if single
finger events should be processed. This never changes once the tablet has
been initialised and one finger touch never worked. (This was masked by the
capacity issue below).
* common->wcmCapacityDefault was used in some places rather than the
configurable common->wcmCapacity.
src/xdrv/wcmConfig.c
* added capacity check for tablet_id 0xd0 to 0xd3. it will set the
common->wcmCapacityDefault = 3 (as stated in comments for it in
xf86WcmAllocate). This keeps the left click from always being pressed
when a single finger touches the tablet.
src/xdrv/wcmUSB.c
* changed a check of common->wcmCapacityDefault to check
common->wcmCapacity instead.
--- a/linuxwacom/src/2.6.27/wacom_sys.c 2009-12-30 19:05:15.000000000 -0500
+++ b/linuxwacom/src/2.6.27/wacom_sys.c 2010-01-04 20:24:00.627276231 -0500
@@ -197,9 +197,9 @@
void input_dev_bpt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
+ input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->x_max, 0, 0);
+ input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->y_max, 0, 0);
if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) {
- 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);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP);
input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_2) |
@@ -399,9 +399,10 @@
}
} else if (pen) {
/* penabled only accepts exact bytes of data */
- if ((features->type == TABLETPC2FG) ||
- (features->type == BAMBOO_PT))
+ if (features->type == TABLETPC2FG)
features->pktlen = WACOM_PKGLEN_GRAPHIRE;
+ else if (features->type == BAMBOO_PT)
+ features->pktlen = WACOM_PKGLEN_BBFUN;
features->device_type = BTN_TOOL_PEN;
features->x_max =
wacom_le16_to_cpu(&report[i + 3]);
@@ -447,6 +448,8 @@
/* penabled only accepts exact bytes of data */
if (features->type == TABLETPC2FG)
features->pktlen = WACOM_PKGLEN_GRAPHIRE;
+ else if (features->type == BAMBOO_PT)
+ features->pktlen = WACOM_PKGLEN_BBFUN;
features->device_type = BTN_TOOL_PEN;
features->y_max =
wacom_le16_to_cpu(&report[i + 3]);
@@ -622,8 +625,13 @@
input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH);
- input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0);
- input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0);
+ if (features->type == BAMBOO_PT && features->device_type == BTN_TOOL_DOUBLETAP) {
+ input_set_abs_params(input_dev, ABS_X, 0, features->x_phy, 4, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, features->y_phy, 4, 0);
+ } else {
+ input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0);
+ }
input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0);
input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
@@ -718,6 +726,9 @@
static int __init wacom_init(void)
{
int result;
+
+ spin_lock_init (&bpt_lock);
+
wacom_driver.id_table = get_device_table();
result = usb_register(&wacom_driver);
if (result == 0)
--- a/linuxwacom/src/2.6.27/wacom_wac.c 2009-12-30 19:05:15.000000000 -0500
+++ b/linuxwacom/src/2.6.27/wacom_wac.c 2010-01-04 19:23:05.553536072 -0500
@@ -14,6 +14,8 @@
#include "wacom.h"
#include "wacom_wac.h"
+spinlock_t bpt_lock;
+
static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo)
{
unsigned char *data = wacom->data;
@@ -253,6 +255,18 @@
int prox = 0, retval = 0;
static int stylusInProx = 0, touchInProx = 1, touchOut = 0;
struct urb *urb = ((struct wacom_combo *)wcombo)->urb;
+ unsigned long flags;
+
+#ifdef DEBUG
+ {
+ int idx;
+ printk("wacom_bpt_irq: data:");
+ for (idx = 0; idx < urb->actual_length; idx++) {
+ printk("%02x ", (unsigned char)data[idx]);
+ }
+ printk("\n");
+ }
+#endif
if (data[0] != WACOM_REPORT_PENABLED) {
dbg("wacom_bpt_irq: received unknown report #%d", data[0]);
@@ -283,11 +297,18 @@
}
prox = (data[17] & 0x30 >> 4);
+ spin_lock_irqsave(&bpt_lock, flags);
if (!stylusInProx) {
+ spin_unlock_irqrestore(&bpt_lock, flags);
if (prox) {
+ spin_lock_irqsave(&bpt_lock, flags);
if (touchInProx) {
+ spin_unlock_irqrestore(&bpt_lock, flags);
wacom_bpt_touch_in(wacom, wcombo);
+
+ spin_lock_irqsave(&bpt_lock, flags);
touchOut = 1;
+ spin_unlock_irqrestore(&bpt_lock, flags);
retval = 1;
goto exit;
}
@@ -305,20 +326,26 @@
if (wacom->id[1] & 0x4) {
wacom_bpt_touch_out(wacom, wcombo, 2);
}
+ spin_lock_irqsave(&bpt_lock, flags);
touchOut = 0;
touchInProx = 1;
+ spin_unlock_irqrestore(&bpt_lock, flags);
retval = 1;
goto exit;
}
} else if (touchOut || !prox) { /* force touch out-prox */
+ spin_unlock_irqrestore(&bpt_lock, flags);
wacom_bpt_touch_out(wacom, wcombo, 0);
+ spin_lock_irqsave(&bpt_lock, flags);
touchOut = 0;
touchInProx = 1;
+ spin_unlock_irqrestore(&bpt_lock, flags);
retval = 1;
goto exit;
}
- } else if (urb->actual_length == WACOM_PKGLEN_GRAPHIRE) { /* Penabled */
+ spin_unlock_irqrestore(&bpt_lock, flags);
+ } else if (urb->actual_length == WACOM_PKGLEN_BBFUN) { /* Penabled */
int x, y, pressure, distance;
int tip, button_1, button_2;
int in_box, has_data, moving;
@@ -329,11 +356,14 @@
button_2 = (data[1] & 0x04) >> 2;
eraser = (data[1] & 0x08) >> 3;
in_box = (data[1] & 0x10) >> 4;
- has_data = (data[1] & 0x20) >> 5;
+ has_data = (data[1] & 0x20) >> 5;
moving = (data[1] & 0x40) >> 6;
prox = (data[1] & 0x80) >> 7;
+
+ spin_lock_irqsave(&bpt_lock, flags);
touchInProx = ~prox;
stylusInProx = prox;
+ spin_unlock_irqrestore(&bpt_lock, flags);
x = wacom_le16_to_cpu(&data[2]);
y = wacom_le16_to_cpu(&data[4]);
@@ -368,7 +398,9 @@
wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
wacom_report_key(wcombo, wacom->tool[0], 0);
+ spin_lock_irqsave(&bpt_lock, flags);
touchInProx = 1;
+ spin_unlock_irqrestore(&bpt_lock, flags);
}
wacom_report_key(wcombo, wacom->tool[0], in_box);
wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
@@ -1199,11 +1231,11 @@
{ "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC },
{ "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG },
{ "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG },
- { "Wacom Bamboo P&T 4x5", WACOM_PKGLEN_GRAPHIRE, 14720, 9200, 1023, 63, BAMBOO_PT },
- { "Wacom Bamboo Pen 4x5", WACOM_PKGLEN_GRAPHIRE, 14720, 9200, 1023, 63, BAMBOO_PT },
- { "Wacom Bamboo Craft", WACOM_PKGLEN_GRAPHIRE, 14720, 9200, 1023, 63, BAMBOO_PT },
- { "Wacom Bamboo P&T 6x8", WACOM_PKGLEN_GRAPHIRE, 21648, 13530, 1023, 63, BAMBOO_PT },
- { "Wacom Bamboo Touch", WACOM_PKGLEN_GRAPHIRE, 14720, 9200, 1023, 63, BAMBOO_PT },
+ { "Wacom Bamboo P&T 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT },
+ { "Wacom Bamboo Pen 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT },
+ { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT },
+ { "Wacom Bamboo P&T 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT },
+ { "Wacom Bamboo Touch", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT },
{ "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS },
{ }
};
--- a/linuxwacom/src/2.6.27/wacom_wac.h 2009-12-30 19:05:15.000000000 -0500
+++ b/linuxwacom/src/2.6.27/wacom_wac.h 2010-01-04 19:24:10.543536461 -0500
@@ -116,4 +116,6 @@
#define WACOM_SET_LEFT_HANDED _IOW(0x00, 0x01, struct wacom_handedness)
#define WACOM_SET_LED_MODE _IOW(0x00, 0x02, struct wacom_led_mode)
+extern spinlock_t bpt_lock;
+
#endif
--- a/linuxwacom/src/xdrv/wcmCommon.c 2009-12-30 19:05:15.000000000 -0500
+++ b/linuxwacom/src/xdrv/wcmCommon.c 2010-01-04 00:31:13.546021076 -0500
@@ -1132,52 +1132,50 @@
#ifndef WCM_KEY_SENDING_SUPPORT
common->wcmGesture = 0;
#endif
- /* process second finger data if exists */
- if ((ds.device_type == TOUCH_ID) && common->wcmTouch && common->wcmGesture)
+ if ((ds.device_type == TOUCH_ID) && common->wcmTouch)
{
- WacomChannelPtr pOtherChannel;
- WacomDeviceState dsOther;
-
- /* exit gesture mode when both fingers are out */
- if (channel)
- pOtherChannel = common->wcmChannel;
- else
- pOtherChannel = common->wcmChannel + 1;
- dsOther = pOtherChannel->valid.state;
-
- /* This is the only place to reset gesture mode
- * once a gesture mode is entered */
- if (!ds.proximity && !dsOther.proximity)
- {
- common->wcmGestureMode = 0;
-
- /* send a touch out-prox event here
- * in case the FF was out before the SF */
- channel = 0;
- }
- else
- {
- /* don't move the cursor if in gesture mode
- * wait for second finger data to process gestures */
- if (!channel && common->wcmGestureMode)
- goto ret;
+ WacomDeviceState* pds = &common->wcmTouchpadState;
+ WacomDevicePtr priv = common->wcmDevices;
- /* process gesture when both touch and geature are enabled */
+ /* process second finger data if exists */
+ if (common->wcmGesture) {
+ WacomChannelPtr pOtherChannel;
+ WacomDeviceState dsOther;
+ /* exit gesture mode when both fingers are out */
if (channel)
+ pOtherChannel = common->wcmChannel;
+ else
+ pOtherChannel = common->wcmChannel + 1;
+ dsOther = pOtherChannel->valid.state;
+
+ /* This is the only place to reset gesture mode
+ * once a gesture mode is entered */
+ if (!ds.proximity && !dsOther.proximity)
+ {
+ common->wcmGestureMode = 0;
+
+ /* send a touch out-prox event here
+ * in case the FF was out before the SF */
+ channel = 0;
+ }
+ else
{
- xf86WcmFingerTapToClick(common);
- goto ret;
+ /* don't move the cursor if in gesture mode
+ * wait for second finger data to process gestures */
+ if (!channel && common->wcmGestureMode)
+ goto ret;
+
+ /* process gesture when both touch and gesture are enabled */
+ if (channel)
+ {
+ xf86WcmFingerTapToClick(common);
+ goto ret;
+ }
}
}
- }
-
- /* process single finger events */
- if (ds.device_type == TOUCH_ID && common->wcmTouch && !common->wcmGesture)
- {
- WacomDeviceState* pds = &common->wcmTouchpadState;
- WacomDevicePtr priv = common->wcmDevices;
- if (ds.proximity)
+ /* process single finger events if no gestures were processed */
+ if (ds.proximity) {
switch (common->wcmTouchpadMode)
{
case 0:
@@ -1202,7 +1200,7 @@
}
break;
}
- else {
+ } else {
switch (common->wcmTouchpadMode)
{
case 1:
@@ -1479,7 +1477,7 @@
}
/* touch capacity is supported */
- if (IsTouch(priv) && (common->wcmCapacityDefault >= 0) && !priv->hardProx)
+ if (IsTouch(priv) && (common->wcmCapacity >= 0) && !priv->hardProx)
{
if (((double)(filtered.capacity * 5) /
(double)common->wcmMaxZ) >
--- a/linuxwacom/src/xdrv/wcmConfig.c 2009-12-30 19:05:15.000000000 -0500
+++ b/linuxwacom/src/xdrv/wcmConfig.c 2010-01-04 19:59:43.243532406 -0500
@@ -459,6 +459,15 @@
common->wcmGestureDefault = 1;
}
+ /* Bamboo P&T Capacity defaults to 3 */
+ if ((common->tablet_id >= 0xd0) && (common->tablet_id <= 0xd3)) {
+
+ /* Capacity is off for all devices except on
+ * Bamboo Pen & Touch devices
+ */
+ common->wcmCapacityDefault = 3;
+ }
+
/* check if touch was turned off in xorg.conf */
common->wcmTouch = xf86SetBoolOption(local->options, "Touch",
common->wcmTouchDefault);
--- a/linuxwacom/src/xdrv/wcmUSB.c 2009-12-30 19:05:15.000000000 -0500
+++ b/linuxwacom/src/xdrv/wcmUSB.c 2010-01-04 00:25:52.373523617 -0500
@@ -1055,7 +1055,7 @@
* For touch with capacity enabled, left button event will be decided
* in wcmCommon.c by capacity threshold.
*/
- if (common->wcmCapacityDefault < 0)
+ if (common->wcmCapacity < 0)
MOD_BUTTONS (0, event->value);
}
else if (event->code == BTN_TOOL_TRIPLETAP)
--- a/linuxwacom/src/xdrv/wcmMapping.c 2009-12-30 19:05:15.000000000 -0500
+++ b/linuxwacom/src/xdrv/wcmMapping.c 2010-01-03 20:58:54.435479499 -0500
@@ -182,10 +182,10 @@
}
/*****************************************************************************
- * xf86WcmVirtaulTabletSize(LocalDevicePtr local)
+ * xf86WcmVirtualTabletSize(LocalDevicePtr local)
****************************************************************************/
-void xf86WcmVirtaulTabletSize(LocalDevicePtr local)
+void xf86WcmVirtualTabletSize(LocalDevicePtr local)
{
WacomDevicePtr priv = (WacomDevicePtr)local->private;
@@ -199,7 +199,7 @@
priv->sizeX = priv->bottomX - priv->topX - priv->tvoffsetX;
priv->sizeY = priv->bottomY - priv->topY - priv->tvoffsetY;
- DBG(10, priv->debugLevel, ErrorF("xf86WcmVirtaulTabletSize for \"%s\" "
+ DBG(10, priv->debugLevel, ErrorF("xf86WcmVirtualTabletSize for \"%s\" "
"x=%d y=%d \n", local->name, priv->sizeX, priv->sizeY));
return;
}
@@ -287,7 +287,7 @@
DBG(10, priv->debugLevel, ErrorF("xf86WcmMappingFactor \n"));
- xf86WcmVirtaulTabletSize(local);
+ xf86WcmVirtualTabletSize(local);
if (!(priv->flags & ABSOLUTE_FLAG) || !priv->wcmMMonitor)
{
------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev
_______________________________________________
Linuxwacom-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel