diff options
author | pingc <pingc> | 2009-12-01 22:52:45 +0000 |
---|---|---|
committer | pingc <pingc> | 2009-12-01 22:52:45 +0000 |
commit | 9f901a1c9645bfd5757d276c6bed0a21764e4950 (patch) | |
tree | 7f62b146c28e64aad7fe60137c5f2cc77021188f | |
parent | 3d03a8049d36644a55cda8ea4ed1203fa2343f19 (diff) | |
download | xf86-input-wacom-release-0.8.5-5.tar.gz |
Add new serial ISDv4 supportrelease-0.8.5-5
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | configure.in | 4 | ||||
-rwxr-xr-x | src/2.6.19/wacom_wac.c | 58 | ||||
-rwxr-xr-x | src/2.6.24/wacom.h | 4 | ||||
-rwxr-xr-x | src/2.6.24/wacom_sys.c | 154 | ||||
-rwxr-xr-x | src/2.6.26/wacom.h | 4 | ||||
-rwxr-xr-x | src/2.6.26/wacom_sys.c | 161 | ||||
-rwxr-xr-x | src/2.6.27/wacom.h | 4 | ||||
-rw-r--r-- | src/2.6.28/wacom_sys.c | 168 | ||||
-rwxr-xr-x | src/2.6.28/wacom_wac.c | 23 | ||||
-rwxr-xr-x | src/2.6.28/wacom_wac.h | 9 | ||||
-rw-r--r-- | src/util/10-linuxwacom.fdi | 4 | ||||
-rwxr-xr-x | src/xdrv/wcmCommon.c | 67 | ||||
-rwxr-xr-x | src/xdrv/wcmConfig.c | 45 | ||||
-rwxr-xr-x | src/xdrv/wcmISDV4.c | 268 | ||||
-rwxr-xr-x | src/xdrv/wcmSerial.c | 2 | ||||
-rw-r--r-- | src/xdrv/wcmTouchFilter.c | 7 | ||||
-rwxr-xr-x | src/xdrv/wcmUSB.c | 2 | ||||
-rwxr-xr-x | src/xdrv/wcmValidateDevice.c | 95 | ||||
-rwxr-xr-x | src/xdrv/xf86Wacom.c | 88 | ||||
-rwxr-xr-x | src/xdrv/xf86WacomDefs.h | 2 |
21 files changed, 694 insertions, 481 deletions
@@ -1,3 +1,9 @@ +2009-11-30 Ping Cheng <pingc@wacom.com> + * Fixed a kernel driver bug for E3 + * Updated serial ISDv4 support with newer protocol + * Support suspend/resume for kernel 2.6.26 and later + * Label 0.8.5-5 + 2009-11-13 Ping Cheng <pingc@wacom.com> * Allow multiple tools defined with one type * Label 0.8.5-4 diff --git a/configure.in b/configure.in index 1a22de0..c87b84f 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ AC_PREREQ(2.58) -AC_INIT(linuxwacom, 0.8.5-2) +AC_INIT(linuxwacom, 0.8.5) AM_INIT_AUTOMAKE AM_MAINTAINER_MODE @@ -600,7 +600,7 @@ if test "$WCM_XORG_XSERVER_1_6" == yes; then fi fi -if test "$WCM_XORG_XSERVER_1_4" == yes -a "$WCM_XORG_XSERVER_1_6" != yes; then +if test "$WCM_XORG_XSERVER_1_4" == yes -a "$WCM_XORG_XSERVER_1_5_2" != yes; then WCM_XDRIVER_QUIRKS="$WCM_XDRIVER_QUIRKS Uninit-called" fi diff --git a/src/2.6.19/wacom_wac.c b/src/2.6.19/wacom_wac.c index 8bf5b49..2faa652 100755 --- a/src/2.6.19/wacom_wac.c +++ b/src/2.6.19/wacom_wac.c @@ -609,15 +609,15 @@ int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) if (urb->actual_length == 5 || data[0] == 6) { /* Touch data */ if (urb->actual_length == 5) { /* with touch */ - prox = data[0] & 0x03; + prox = data[0] & 0x01; } else { /* with capacity */ - prox = data[1] & 0x03; + prox = data[1] & 0x01; } if (!stylusInProx) { /* stylus not in prox */ if (prox) { if (touchInProx) { - wacom->tool[1] = BTN_TOOL_DOUBLETAP; + wacom->tool[0] = BTN_TOOL_DOUBLETAP; wacom->id[0] = TOUCH_DEVICE_ID; if (urb->actual_length != 5) { wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); @@ -630,13 +630,13 @@ int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_key(wcombo, BTN_TOUCH, 1); } wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); + wacom_report_key(wcombo, wacom->tool[0], prox & 0x01); touchOut = 1; return 1; } } else { wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); + wacom_report_key(wcombo, wacom->tool[0], prox & 0x01); wacom_report_key(wcombo, BTN_TOUCH, 0); touchOut = 0; touchInProx = 1; @@ -644,7 +644,7 @@ int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) } } else if (touchOut || !prox) { /* force touch out-prox */ wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID); - wacom_report_key(wcombo, wacom->tool[1], 0); + wacom_report_key(wcombo, wacom->tool[0], 0); wacom_report_key(wcombo, BTN_TOUCH, 0); touchOut = 0; touchInProx = 1; @@ -655,38 +655,14 @@ int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) touchInProx = 0; - wacom->id[0] = ERASER_DEVICE_ID; - - /* - * if going from out of proximity into proximity select between the eraser - * and the pen based on the state of the stylus2 button, choose eraser if - * pressed else choose pen. if not a proximity change from out to in, send - * an out of proximity for previous tool then a in for new tool. - */ - if (prox) { /* in prox */ - if (!wacom->tool[0]) { - /* Going into proximity select tool */ - wacom->tool[1] = (data[1] & 0x08) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - if (wacom->tool[1] == BTN_TOOL_PEN) + if (prox) { /* pen in prox */ + if (!wacom->id[0]) { + wacom->tool[0] = (data[1] & 0x0c) ? + BTN_TOOL_RUBBER : BTN_TOOL_PEN; + if (wacom->tool[0] == BTN_TOOL_PEN) wacom->id[0] = STYLUS_DEVICE_ID; - } else if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[1] & 0x08)) { - /* - * was entered with stylus2 pressed - * report out proximity for previous tool - */ - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); - wacom_report_key(wcombo, wacom->tool[1], 0); - wacom_input_sync(wcombo); - - /* set new tool */ - wacom->tool[1] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - return 0; - } - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; + else + wacom->id[0] = ERASER_DEVICE_ID; } wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); @@ -698,15 +674,19 @@ int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_abs(wcombo, ABS_PRESSURE, pressure); wacom_report_key(wcombo, BTN_TOUCH, pressure); } else { + wacom_report_abs(wcombo, ABS_X, 0); + wacom_report_abs(wcombo, ABS_Y, 0); wacom_report_abs(wcombo, ABS_PRESSURE, 0); wacom_report_key(wcombo, BTN_TOUCH, 0); wacom_report_key(wcombo, BTN_STYLUS, 0); wacom_report_key(wcombo, BTN_STYLUS2, 0); + wacom->id[0] = 0; + /* pen is out so touch can be enabled now */ + touchInProx = 1; } - wacom_report_key(wcombo, wacom->tool[1], prox); + wacom_report_key(wcombo, wacom->tool[0], prox); wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); stylusInProx = prox; - wacom->tool[0] = prox; return 1; } return 0; diff --git a/src/2.6.24/wacom.h b/src/2.6.24/wacom.h index 468f2bc..f292cfc 100755 --- a/src/2.6.24/wacom.h +++ b/src/2.6.24/wacom.h @@ -84,9 +84,9 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.46-pc0.6" +#define DRIVER_VERSION "v1.46-pc0.7" #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" +#define DRIVER_DESC "USB Wacom tablet driver" #define DRIVER_LICENSE "GPL" MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/src/2.6.24/wacom_sys.c b/src/2.6.24/wacom_sys.c index bd6f83b..571d3dc 100755 --- a/src/2.6.24/wacom_sys.c +++ b/src/2.6.24/wacom_sys.c @@ -1,7 +1,7 @@ /* * drivers/input/tablet/wacom_sys.c * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code + * USB Wacom tablet support - system specific code */ /* @@ -270,7 +270,8 @@ void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) { + if ((wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) || + (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_RY, 0, wacom_wac->features->y_phy, 0, 0); input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); @@ -279,7 +280,7 @@ void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac) void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) { + if (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) { input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP); input_dev->evbit[0] |= BIT_MASK(EV_MSC); input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); @@ -287,10 +288,9 @@ void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac) } static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, - struct wacom_wac *wacom_wac) + struct wacom_features *features) { struct usb_device *dev = interface_to_usbdev(intf); - struct wacom_features *features = wacom_wac->features; char limit = 0; int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0, result = 0; unsigned char *report; @@ -335,6 +335,11 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi if (usage == WCM_DESKTOP) { if (finger) { features->device_type = BTN_TOOL_DOUBLETAP; + if (features->type == TABLETPC2FG) { + /* need to reset back */ + features->pktlen = WACOM_PKGLEN_TPC2FG; + features->device_type = BTN_TOOL_TRIPLETAP; + } features->x_max = wacom_le16_to_cpu(&report[i + 3]); features->x_phy = @@ -343,6 +348,9 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi features->unitExpo = report[i + 11]; i += 12; } else if (pen) { + /* penabled only accepts exact bytes of data */ + if (features->type == TABLETPC2FG) + features->pktlen = WACOM_PKGLEN_PENABLED; features->device_type = BTN_TOOL_PEN; features->x_max = (wacom_le16_to_cpu(&report[i+3])); @@ -361,7 +369,10 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi if (usage == WCM_DESKTOP) { if (finger) { features->device_type = BTN_TOOL_DOUBLETAP; - if (strstr(features->name, "Wacom ISDv4 E")) { + if (features->type == TABLETPC2FG) { + /* need to reset back */ + features->pktlen = WACOM_PKGLEN_TPC2FG; + features->device_type = BTN_TOOL_TRIPLETAP; features->y_max = wacom_le16_to_cpu(&report[i + 3]); features->y_phy = @@ -375,6 +386,9 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi i += 4; } } else if (pen) { + /* penabled only accepts exact bytes of data */ + if (features->type == TABLETPC2FG) + features->pktlen = WACOM_PKGLEN_PENABLED; features->device_type = BTN_TOOL_PEN; features->y_max = (wacom_le16_to_cpu(&report[i+3])); i += 4; @@ -412,17 +426,86 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi return result; } +static int wacom_reset_report(struct usb_interface *intf, struct wacom_features *features) +{ + char rep_data[4], limit = 0, report_id = 2; + int error = -ENOMEM; + /* + * Ask to report tablet data if it is 2FGT or not a Tablet PC. + * Repeat 3 times since on some systems the first 2 may fail. + */ + + if (features->device_type == BTN_TOOL_TRIPLETAP) { + do { + rep_data[0] = 3; + rep_data[1] = 4; + report_id = 3; + error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, + report_id, rep_data, 2); + if (error >= 0) + error = usb_get_report(intf, + WAC_HID_FEATURE_REPORT, report_id, + rep_data, 3); + } while ((error < 0 || rep_data[1] != 4) && limit++ < 3); + } else if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) { + do { + rep_data[0] = 2; + rep_data[1] = 2; + error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, + report_id, rep_data, 2); + if (error >= 0) + error = usb_get_report(intf, + WAC_HID_FEATURE_REPORT, report_id, + rep_data, 2); + } while ((error < 0 || rep_data[1] != 2) && limit++ < 3); + } + return error; +} + +static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, + struct wacom_features *features) +{ + int error = 0; + struct usb_host_interface *interface = intf->cur_altsetting; + struct hid_descriptor *hid_desc; + + /* default device to penabled */ + features->device_type = BTN_TOOL_PEN; + + /* only Tablet PCs need to retrieve the info */ + if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) + goto out; + + if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { + if (usb_get_extra_descriptor(&interface->endpoint[0], + HID_DEVICET_REPORT, &hid_desc)) { + printk("wacom: can not retrieve extra class descriptor\n"); + error = 1; + goto out; + } + } + error = wacom_parse_hid(intf, hid_desc, features); + if (error) + goto out; + + /* touch device found but size is not defined. use default */ + if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { + features->x_max = 1023; + features->y_max = 1023; + } + + out: + return error; +} + static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); - struct usb_host_interface *interface = intf->cur_altsetting; struct usb_endpoint_descriptor *endpoint; struct wacom *wacom; struct wacom_wac *wacom_wac; struct input_dev *input_dev; int error = -ENOMEM; - char rep_data[2], limit = 0, report_id = 2; - struct hid_descriptor *hid_desc; wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); @@ -446,10 +529,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i wacom_wac->features = get_wacom_feature(id); BUG_ON(wacom_wac->features->pktlen > WACOM_PKGLEN_MAX); - /* default device to penabled */ - if (wacom_wac->features->device_type) - wacom_wac->features->device_type = BTN_TOOL_PEN; - input_dev->name = wacom_wac->features->name; wacom->wacom_wac = wacom_wac; usb_to_input_id(dev, &input_dev->id); @@ -463,26 +542,9 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i endpoint = &intf->cur_altsetting->endpoint[0].desc; - if (wacom_wac->features->type == TABLETPC || wacom_wac->features->type == TABLETPC2FG) { - - /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ - if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { - if (usb_get_extra_descriptor(&interface->endpoint[0], - HID_DEVICET_REPORT, &hid_desc)) { - printk("wacom: can not retrive extra class descriptor\n"); - goto fail2; - } - } - error = wacom_parse_hid(intf, hid_desc, wacom_wac); - if (error) - goto fail2; - - /* touch device found but size is not defined. use default */ - if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP && !wacom_wac->features->x_max) { - wacom_wac->features->x_max = 1023; - wacom_wac->features->y_max = 1023; - } - } + error = wacom_retrieve_hid_descriptor(intf, wacom_wac->features); + if (error) + goto fail2; input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH); @@ -504,30 +566,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i if (error) goto fail3; - /* Ask the tablet to report tablet data if it is not a regular Tablet PC. - * Repeat 3 times since on some systems the first 2 may fail. - */ - if (wacom_wac->features->type == TABLETPC2FG) { - do { - rep_data[0] = 3; - rep_data[1] = 4; - report_id = 3; - error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, - report_id, rep_data, 2); - if (error >= 0) - error = usb_get_report(intf, - WAC_HID_FEATURE_REPORT, report_id, - rep_data, 3); - } while ((error < 0 || rep_data[1] != 4) && limit++ < 3); - } else if (wacom_wac->features->type != TABLETPC) { - do { - rep_data[0] = 2; - rep_data[1] = 2; - error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, report_id, rep_data, 2); - if(error >= 0) - error = usb_get_report(intf, WAC_HID_FEATURE_REPORT, report_id, rep_data, 2); - } while (((error <= 0) || (rep_data[1] != 2)) && limit++ < 3); - } + /* switch to wacom mode if needed */ + wacom_reset_report(intf, wacom_wac->features); usb_set_intfdata(intf, wacom); return 0; diff --git a/src/2.6.26/wacom.h b/src/2.6.26/wacom.h index b6762fe..f530c4c 100755 --- a/src/2.6.26/wacom.h +++ b/src/2.6.26/wacom.h @@ -87,9 +87,9 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.49-pc-2" +#define DRIVER_VERSION "v1.49-pc-3" #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" +#define DRIVER_DESC "USB Wacom tablet driver" #define DRIVER_LICENSE "GPL" MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/src/2.6.26/wacom_sys.c b/src/2.6.26/wacom_sys.c index af1102e..b6aa0b2 100755 --- a/src/2.6.26/wacom_sys.c +++ b/src/2.6.26/wacom_sys.c @@ -1,7 +1,7 @@ /* * drivers/input/tablet/wacom_sys.c * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code + * USB Wacom tablet support - system specific code */ /* @@ -287,7 +287,8 @@ void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) { + if ((wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) || + (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_RY, 0, wacom_wac->features->y_phy, 0, 0); input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); @@ -296,7 +297,7 @@ void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac) void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) { + if (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) { input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP); input_dev->evbit[0] |= BIT_MASK(EV_MSC); input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); @@ -304,10 +305,9 @@ void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac) } static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, - struct wacom_wac *wacom_wac) + struct wacom_features *features) { struct usb_device *dev = interface_to_usbdev(intf); - struct wacom_features *features = wacom_wac->features; char limit = 0; int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0, result = 0; unsigned char *report; @@ -352,6 +352,11 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi if (usage == WCM_DESKTOP) { if (finger) { features->device_type = BTN_TOOL_DOUBLETAP; + if (features->type == TABLETPC2FG) { + /* need to reset back */ + features->pktlen = WACOM_PKGLEN_TPC2FG; + features->device_type = BTN_TOOL_TRIPLETAP; + } features->x_max = wacom_le16_to_cpu(&report[i + 3]); features->x_phy = @@ -360,6 +365,9 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi features->unitExpo = report[i + 11]; i += 12; } else if (pen) { + /* penabled only accepts exact bytes of data */ + if (features->type == TABLETPC2FG) + features->pktlen = WACOM_PKGLEN_PENABLED; features->device_type = BTN_TOOL_PEN; features->x_max = (wacom_le16_to_cpu(&report[i+3])); i += 4; @@ -377,7 +385,10 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi if (usage == WCM_DESKTOP) { if (finger) { features->device_type = BTN_TOOL_DOUBLETAP; - if (strstr(features->name, "Wacom ISDv4 E")) { + if (features->type == TABLETPC2FG) { + /* need to reset back */ + features->pktlen = WACOM_PKGLEN_TPC2FG; + features->device_type = BTN_TOOL_TRIPLETAP; features->y_max = wacom_le16_to_cpu(&report[i + 3]); features->y_phy = @@ -391,6 +402,9 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi i += 4; } } else if (pen) { + /* penabled only accepts exact bytes of data */ + if (features->type == TABLETPC2FG) + features->pktlen = WACOM_PKGLEN_PENABLED; features->device_type = BTN_TOOL_PEN; features->y_max = (wacom_le16_to_cpu(&report[i+3])); i += 4; @@ -427,18 +441,86 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi kfree(report); return result; } +static int wacom_reset_report(struct usb_interface *intf, struct wacom_features *features) +{ + char rep_data[4], limit = 0, report_id = 2; + int error = -ENOMEM; + /* + * Ask to report tablet data if it is 2FGT or not a Tablet PC. + * Repeat 3 times since on some systems the first 2 may fail. + */ + + if (features->device_type == BTN_TOOL_TRIPLETAP) { + do { + rep_data[0] = 3; + rep_data[1] = 4; + report_id = 3; + error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, + report_id, rep_data, 2); + if (error >= 0) + error = usb_get_report(intf, + WAC_HID_FEATURE_REPORT, report_id, + rep_data, 3); + } while ((error < 0 || rep_data[1] != 4) && limit++ < 3); + } else if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) { + do { + rep_data[0] = 2; + rep_data[1] = 2; + error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, + report_id, rep_data, 2); + if (error >= 0) + error = usb_get_report(intf, + WAC_HID_FEATURE_REPORT, report_id, + rep_data, 2); + } while ((error < 0 || rep_data[1] != 2) && limit++ < 3); + } + return error; +} + +static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, + struct wacom_features *features) +{ + int error = 0; + struct usb_host_interface *interface = intf->cur_altsetting; + struct hid_descriptor *hid_desc; + + /* default device to penabled */ + features->device_type = BTN_TOOL_PEN; + + /* only Tablet PCs need to retrieve the info */ + if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) + goto out; + + if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { + if (usb_get_extra_descriptor(&interface->endpoint[0], + HID_DEVICET_REPORT, &hid_desc)) { + printk("wacom: can not retrieve extra class descriptor\n"); + error = 1; + goto out; + } + } + error = wacom_parse_hid(intf, hid_desc, features); + if (error) + goto out; + + /* touch device found but size is not defined. use default */ + if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { + features->x_max = 1023; + features->y_max = 1023; + } + + out: + return error; +} static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); - struct usb_host_interface *interface = intf->cur_altsetting; struct usb_endpoint_descriptor *endpoint; struct wacom *wacom; struct wacom_wac *wacom_wac; struct input_dev *input_dev; int error = -ENOMEM; - char rep_data[2], limit = 0, report_id = 2; - struct hid_descriptor *hid_desc; wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); @@ -464,10 +546,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i wacom_wac->features = get_wacom_feature(id); BUG_ON(wacom_wac->features->pktlen > WACOM_PKGLEN_MAX); - /* default device to penabled */ - if (features->device_type) - features->device_type = BTN_TOOL_PEN; - input_dev->name = wacom_wac->features->name; wacom->wacom_wac = wacom_wac; usb_to_input_id(dev, &input_dev->id); @@ -481,26 +559,9 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i endpoint = &intf->cur_altsetting->endpoint[0].desc; - if (wacom_wac->features->type == TABLETPC || wacom_wac->features->type == TABLETPC2FG) { - - /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ - if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { - if (usb_get_extra_descriptor(&interface->endpoint[0], - HID_DEVICET_REPORT, &hid_desc)) { - printk("wacom: can not retrive extra class descriptor\n"); - goto fail2; - } - } - error = wacom_parse_hid(intf, hid_desc, wacom_wac); - if (error) - goto fail2; - - /* touch device found but size is not defined. use default */ - if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP && !wacom_wac->features->x_max) { - wacom_wac->features->x_max = 1023; - wacom_wac->features->y_max = 1023; - } - } + error = wacom_retrieve_hid_descriptor(intf, wacom_wac->features); + if (error) + goto fail2; input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH); @@ -522,30 +583,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i if (error) goto fail3; - /* Ask the tablet to report tablet data if it is not a regular Tablet PC. - * Repeat 3 times since on some systems the first 2 may fail. - */ - if (wacom_wac->features->type == TABLETPC2FG) { - do { - rep_data[0] = 3; - rep_data[1] = 4; - report_id = 3; - error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, - report_id, rep_data, 2); - if (error >= 0) - error = usb_get_report(intf, - WAC_HID_FEATURE_REPORT, report_id, - rep_data, 3); - } while ((error < 0 || rep_data[1] != 4) && limit++ < 3); - } else if (wacom_wac->features->type != TABLETPC) { - do { - rep_data[0] = 2; - rep_data[1] = 2; - error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, report_id, rep_data, 2); - if(error >= 0) - error = usb_get_report(intf, WAC_HID_FEATURE_REPORT, report_id, rep_data, 2); - } while (((error <= 0) || (rep_data[1] != 2)) && limit++ < 3); - } + /* switch to wacom mode if needed */ + wacom_reset_report(intf, wacom_wac->features); usb_set_intfdata(intf, wacom); return 0; @@ -586,12 +625,16 @@ static int wacom_suspend(struct usb_interface *intf, pm_message_t message) static int wacom_resume(struct usb_interface *intf) { struct wacom *wacom = usb_get_intfdata(intf); + struct wacom_features *features = wacom->wacom_wac->features; int rv; mutex_lock(&wacom->lock); - if (wacom->open) + if (wacom->open) { rv = usb_submit_urb(wacom->irq, GFP_NOIO); - else + /* switch to wacom mode if needed */ + if (!wacom_retrieve_hid_descriptor(intf, features)) + wacom_reset_report(intf, features); + } else rv = 0; mutex_unlock(&wacom->lock); diff --git a/src/2.6.27/wacom.h b/src/2.6.27/wacom.h index da2ac83..83eacd9 100755 --- a/src/2.6.27/wacom.h +++ b/src/2.6.27/wacom.h @@ -87,9 +87,9 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.49-pc-2" +#define DRIVER_VERSION "v1.49-pc-3" #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" -#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" +#define DRIVER_DESC "USB Wacom tablet driver" #define DRIVER_LICENSE "GPL" MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/src/2.6.28/wacom_sys.c b/src/2.6.28/wacom_sys.c index e9c27f7..155f70e 100644 --- a/src/2.6.28/wacom_sys.c +++ b/src/2.6.28/wacom_sys.c @@ -1,7 +1,7 @@ /* * drivers/input/tablet/wacom_sys.c * - * USB Wacom Graphire and Wacom Intuos tablet support - system specific code + * USB Wacom tablet support - system specific code */ /* @@ -282,7 +282,8 @@ void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) { + if ((wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) || + (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_RY, 0, wacom_wac->features->y_phy, 0, 0); input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); @@ -291,7 +292,7 @@ void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac) void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) { + if (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) { input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP); input_dev->evbit[0] |= BIT_MASK(EV_MSC); input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); @@ -299,10 +300,9 @@ void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac) } static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, - struct wacom_wac *wacom_wac) + struct wacom_features *features) { struct usb_device *dev = interface_to_usbdev(intf); - struct wacom_features *features = wacom_wac->features; char limit = 0; int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0, result = 0; unsigned char *report; @@ -350,6 +350,11 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi if (usage == WCM_DESKTOP) { if (finger) { features->device_type = BTN_TOOL_DOUBLETAP; + if (features->type == TABLETPC2FG) { + /* need to reset back */ + features->pktlen = WACOM_PKGLEN_TPC2FG; + features->device_type = BTN_TOOL_TRIPLETAP; + } features->x_max = wacom_le16_to_cpu(&report[i + 3]); features->x_phy = @@ -358,6 +363,9 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi features->unitExpo = report[i + 11]; i += 12; } else if (pen) { + /* penabled only accepts exact bytes of data */ + if (features->type == TABLETPC2FG) + features->pktlen = WACOM_PKGLEN_PENABLED; features->device_type = BTN_TOOL_PEN; features->x_max = wacom_le16_to_cpu(&report[i + 3]); @@ -377,7 +385,10 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi if (usage == WCM_DESKTOP) { if (finger) { features->device_type = BTN_TOOL_DOUBLETAP; - if (strstr(features->name, "Wacom ISDv4 E")) { + if (features->type == TABLETPC2FG) { + /* need to reset back */ + features->pktlen = WACOM_PKGLEN_TPC2FG; + features->device_type = BTN_TOOL_TRIPLETAP; features->y_max = wacom_le16_to_cpu(&report[i + 3]); features->y_phy = @@ -391,6 +402,9 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi i += 4; } } else if (pen) { + /* penabled only accepts exact bytes of data */ + if (features->type == TABLETPC2FG) + features->pktlen = WACOM_PKGLEN_PENABLED; features->device_type = BTN_TOOL_PEN; features->y_max = wacom_le16_to_cpu(&report[i + 3]); @@ -431,18 +445,87 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi return result; } +static int wacom_reset_report(struct usb_interface *intf, struct wacom_features *features) +{ + char rep_data[4], limit = 0, report_id = 2; + int error = -ENOMEM; + /* + * Ask to report tablet data if it is 2FGT or not a Tablet PC. + * Repeat 3 times since on some systems the first 2 may fail. + */ + + if (features->device_type == BTN_TOOL_TRIPLETAP) { + do { + rep_data[0] = 3; + rep_data[1] = 4; + report_id = 3; + error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, + report_id, rep_data, 2); + if (error >= 0) + error = usb_get_report(intf, + WAC_HID_FEATURE_REPORT, report_id, + rep_data, 3); + } while ((error < 0 || rep_data[1] != 4) && limit++ < 3); + } else if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) { + do { + rep_data[0] = 2; + rep_data[1] = 2; + error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, + report_id, rep_data, 2); + if (error >= 0) + error = usb_get_report(intf, + WAC_HID_FEATURE_REPORT, report_id, + rep_data, 2); + } while ((error < 0 || rep_data[1] != 2) && limit++ < 3); + } + return error; +} + +static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, + struct wacom_features *features) +{ + int error = 0; + struct usb_host_interface *interface = intf->cur_altsetting; + struct hid_descriptor *hid_desc; + + /* default device to penabled */ + features->device_type = BTN_TOOL_PEN; + + /* only Tablet PCs need to retrieve the info */ + if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) + goto out; + + if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { + if (usb_get_extra_descriptor(&interface->endpoint[0], + HID_DEVICET_REPORT, &hid_desc)) { + printk("wacom: can not retrieve extra class descriptor\n"); + error = 1; + goto out; + } + } + error = wacom_parse_hid(intf, hid_desc, features); + if (error) + goto out; + + /* touch device found but size is not defined. use default */ + if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { + features->x_max = 1023; + features->y_max = 1023; + } + + out: + return error; +} + static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); - struct usb_host_interface *interface = intf->cur_altsetting; struct usb_endpoint_descriptor *endpoint; struct wacom *wacom; struct wacom_wac *wacom_wac; struct wacom_features *features; struct input_dev *input_dev; int error = -ENOMEM; - char rep_data[4], limit = 0, report_id = 2; - struct hid_descriptor *hid_desc; wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); @@ -468,10 +551,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i wacom_wac->features = features = get_wacom_feature(id); BUG_ON(features->pktlen > WACOM_PKGLEN_MAX); - /* default device to penabled */ - if (features->device_type) - features->device_type = BTN_TOOL_PEN; - input_dev->name = wacom_wac->features->name; wacom->wacom_wac = wacom_wac; usb_to_input_id(dev, &input_dev->id); @@ -485,26 +564,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i endpoint = &intf->cur_altsetting->endpoint[0].desc; - if (features->type == TABLETPC || features->type == TABLETPC2FG) { - - /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ - if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { - if (usb_get_extra_descriptor(&interface->endpoint[0], - HID_DEVICET_REPORT, &hid_desc)) { - printk("wacom: can not retrive extra class descriptor\n"); - goto fail2; - } - } - error = wacom_parse_hid(intf, hid_desc, wacom_wac); - if (error) - goto fail2; - - /* touch device found but size is not defined. use default */ - if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { - features->x_max = 1023; - features->y_max = 1023; - } - } + /* Retrieve the physical and logical size for OEM devices */ + error = wacom_retrieve_hid_descriptor(intf, features); + if (error) + goto fail2; input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH); @@ -528,35 +591,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i if (error) goto fail3; - /* - * Ask the tablet to report tablet data if it is not a regular Tablet PC. - * Repeat 3 times since on some systems the first 2 may fail. - */ - - if (features->type == TABLETPC2FG) { - do { - rep_data[0] = 3; - rep_data[1] = 4; - report_id = 3; - error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, - report_id, rep_data, 2); - if (error >= 0) - error = usb_get_report(intf, - WAC_HID_FEATURE_REPORT, report_id, - rep_data, 3); - } while ((error < 0 || rep_data[1] != 4) && limit++ < 3); - } else if (features->type != TABLETPC) { - do { - rep_data[0] = 2; - rep_data[1] = 2; - error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, - report_id, rep_data, 2); - if (error >= 0) - error = usb_get_report(intf, - WAC_HID_FEATURE_REPORT, report_id, - rep_data, 2); - } while ((error < 0 || rep_data[1] != 2) && limit++ < 3); - } + /* switch to wacom mode if needed */ + wacom_reset_report(intf, features); usb_set_intfdata(intf, wacom); return 0; @@ -598,12 +634,16 @@ static int wacom_suspend(struct usb_interface *intf, pm_message_t message) static int wacom_resume(struct usb_interface *intf) { struct wacom *wacom = usb_get_intfdata(intf); + struct wacom_features *features = wacom->wacom_wac->features; int rv; mutex_lock(&wacom->lock); - if (wacom->open) + if (wacom->open) { rv = usb_submit_urb(wacom->irq, GFP_NOIO); - else + /* switch to wacom mode if needed */ + if (!wacom_retrieve_hid_descriptor(intf, features)) + wacom_reset_report(intf, features); + } else rv = 0; mutex_unlock(&wacom->lock); diff --git a/src/2.6.28/wacom_wac.c b/src/2.6.28/wacom_wac.c index 39b5d68..20ab051 100755 --- a/src/2.6.28/wacom_wac.c +++ b/src/2.6.28/wacom_wac.c @@ -1,7 +1,7 @@ /* * drivers/input/tablet/wacom_wac.c * - * USB Wacom Graphire and Wacom Intuos tablet support - Wacom specific code + * USB Wacom tablet support - Wacom specific code * */ @@ -14,14 +14,6 @@ #include "wacom.h" #include "wacom_wac.h" -/* packet length for individual models */ -#define WACOM_PKGLEN_PENPRTN 7 -#define WACOM_PKGLEN_GRAPHIRE 8 -#define WACOM_PKGLEN_BBFUN 9 -#define WACOM_PKGLEN_INTUOS 10 -#define WACOM_PKGLEN_TPC1FG 5 -#define WACOM_PKGLEN_TPC2FG 14 - static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo) { unsigned char *data = wacom->data; @@ -846,7 +838,6 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) return wacom_intuos_irq(wacom_wac, wcombo); case TABLETPC: - case TABLETPC2FG: return wacom_tpc_irq(wacom_wac, wcombo); @@ -893,7 +884,7 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w /* fall through */ case TABLETPC: input_dev_tpc(input_dev, wacom_wac); - if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) + if (wacom_wac->features->device_type != BTN_TOOL_PEN) break; /* no need to process stylus stuff */ /* fall through */ @@ -964,11 +955,11 @@ static struct wacom_features wacom_features[] = { { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ }, { "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, 63, WACOM_BEE }, { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE }, - { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL }, - { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, - { "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, + { "Wacom DTU1931", WACOM_PKGLEN_PENABLED, 37832, 30305, 511, 0, PL }, + { "Wacom ISDv4 90", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC }, + { "Wacom ISDv4 93", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC }, + { "Wacom ISDv4 9A", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC }, + { "Wacom ISDv4 9F", WACOM_PKGLEN_PENABLED, 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 Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }, diff --git a/src/2.6.28/wacom_wac.h b/src/2.6.28/wacom_wac.h index 37e0eb3..39c2516 100755 --- a/src/2.6.28/wacom_wac.h +++ b/src/2.6.28/wacom_wac.h @@ -12,6 +12,15 @@ /* maximum packet length for USB devices */ #define WACOM_PKGLEN_MAX 32 +/* packet length for individual models */ +#define WACOM_PKGLEN_PENPRTN 7 +#define WACOM_PKGLEN_GRAPHIRE 8 +#define WACOM_PKGLEN_BBFUN 9 +#define WACOM_PKGLEN_INTUOS 10 +#define WACOM_PKGLEN_PENABLED 8 +#define WACOM_PKGLEN_TPC1FG 5 +#define WACOM_PKGLEN_TPC2FG 14 + /* device IDs */ #define STYLUS_DEVICE_ID 0x02 #define TOUCH_DEVICE_ID 0x03 diff --git a/src/util/10-linuxwacom.fdi b/src/util/10-linuxwacom.fdi index f0b6ab2..2d131cf 100644 --- a/src/util/10-linuxwacom.fdi +++ b/src/util/10-linuxwacom.fdi @@ -14,7 +14,7 @@ </match> </match> <match key="info.capabilities" contains="serial"> - <match key="@info.parent:pnp.id" contains_outof="WACf001;WACf002;WACf003;WACf004;WACf005;WACf006;WACf007;WACf008;WACf009;WACf00a;WACf00b;WACf00c;FUJ02e5"> + <match key="@info.parent:pnp.id" contains_outof="WACf;FUJ02e5;FUJ02e7"> <append key="info.capabilities" type="strlist">input</append> <merge key="input.x11_driver" type="string">wacom</merge> <merge key="input.x11_options.Type" type="string">stylus</merge> @@ -22,7 +22,7 @@ <merge key="input.device" type="copy_property">serial.device</merge> <append key="info.callouts.add" type="strlist">hal-setup-wacom</append> <append key="wacom.types" type="strlist">eraser</append> - <match key="@info.parent:pnp.id" contains_outof="WACf008;WACf009"> + <match key="@info.parent:pnp.id" contains_outof="WACf008;WACf009;WACf008A;WACf00B;WACf00C;WACf00D;WACf00E;WACf010;FUJ02e7"> <!-- Serial tablets with touch capabilities --> <append key="wacom.types" type="strlist">touch</append> </match> diff --git a/src/xdrv/wcmCommon.c b/src/xdrv/wcmCommon.c index a67e229..f80eab1 100755 --- a/src/xdrv/wcmCommon.c +++ b/src/xdrv/wcmCommon.c @@ -32,16 +32,6 @@ */ #define XF86_BUTTON1_BUG -WacomDeviceClass* wcmDeviceClasses[] = -{ -#ifdef WCM_ENABLE_LINUXINPUT - &gWacomUSBDevice, -#endif - &gWacomISDV4Device, - &gWacomSerialDevice, - NULL -}; - extern int xf86WcmDevSwitchModeCall(LocalDevicePtr local, int mode); extern void xf86WcmChangeScreen(LocalDevicePtr local, int value); extern void xf86WcmTilt2R(WacomDeviceStatePtr ds); @@ -736,7 +726,6 @@ void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds) v4 = ty; } v5 = wheel; - DBG(6, priv->debugLevel, ErrorF("[%s] %s prox=%d\tx=%d" "\ty=%d\tz=%d\tv3=%d\tv4=%d\tv5=%d\tid=%d" "\tserial=%u\tbutton=%s\tbuttons=%d\n", @@ -1018,49 +1007,6 @@ static int xf86WcmSuppress(WacomCommonPtr common, const WacomDeviceState* dsOrig return returnV; } -/***************************************************************************** - * xf86WcmOpen -- - ****************************************************************************/ - -Bool xf86WcmOpen(LocalDevicePtr local) -{ - WacomDevicePtr priv = (WacomDevicePtr)local->private; - WacomCommonPtr common = priv->common; - WacomDeviceClass** ppDevCls; - char id[BUFFER_SIZE]; - float version; - - DBG(1, priv->debugLevel, ErrorF("opening %s\n", common->wcmDevice)); - - local->fd = xf86OpenSerial(local->options); - if (local->fd < 0) - { - ErrorF("Error opening %s : %s\n", common->wcmDevice, - strerror(errno)); - return !Success; - } - - /* Detect device class; default is serial device */ - for (ppDevCls=wcmDeviceClasses; *ppDevCls!=NULL; ++ppDevCls) - { - if ((*ppDevCls)->Detect(local)) - { - common->wcmDevCls = *ppDevCls; - break; - } - } - - /* Initialize the tablet */ - if(common->wcmDevCls->Init(local, id, &version) != Success || - xf86WcmInitTablet(local, id, version) != Success) - { - xf86CloseSerial(local->fd); - local->fd = -1; - return !Success; - } - return Success; -} - /* reset raw data counters for filters */ static void resetSampleCounter(const WacomChannelPtr pChannel) { @@ -1196,8 +1142,12 @@ void xf86WcmEvent(WacomCommonPtr common, unsigned int channel, if (pChannel->nSamples < common->wcmRawSample) ++pChannel->nSamples; +/* gesture needs keystroke */ +#ifndef WCM_KEY_SENDING_SUPPORT + common->wcmGesture = 0; +#endif /* process second finger data if exists */ - if (ds.device_type == TOUCH_ID) + if ((ds.device_type == TOUCH_ID) && common->wcmTouch && common->wcmGesture) { WacomChannelPtr pOtherChannel; WacomDeviceState dsOther; @@ -1211,7 +1161,7 @@ void xf86WcmEvent(WacomCommonPtr common, unsigned int channel, /* This is the only place to reset gesture mode * once a gesture mode is entered */ - if (!ds.proximity && !dsOther.proximity && common->wcmGestureMode) + if (!ds.proximity && !dsOther.proximity) { common->wcmGestureMode = 0; @@ -1223,12 +1173,11 @@ void xf86WcmEvent(WacomCommonPtr common, unsigned int channel, { /* don't move the cursor if in gesture mode * wait for second finger data to process gestures */ - if (!channel && common->wcmTouch && - common->wcmGesture && common->wcmGestureMode) + if (!channel && common->wcmGestureMode) goto ret; /* process gesture when both touch and geature are enabled */ - if (channel && common->wcmTouch && common->wcmGesture) + if (channel) { xf86WcmFingerTapToClick(common); goto ret; diff --git a/src/xdrv/wcmConfig.c b/src/xdrv/wcmConfig.c index 7613fdf..ec99bf8 100755 --- a/src/xdrv/wcmConfig.c +++ b/src/xdrv/wcmConfig.c @@ -20,9 +20,10 @@ #include "xf86Wacom.h" #include "wcmFilter.h" #ifdef WCM_XORG_XSERVER_1_4 - extern Bool xf86WcmIsWacomDevice (char* fname, struct input_id* id); - extern Bool wcmIsAValidType(char* device, LocalDevicePtr local); + extern Bool xf86WcmIsWacomDevice (char* fname); + extern Bool wcmIsAValidType(const char *type, unsigned long* keys); extern int wcmIsDuplicate(char* device, LocalDevicePtr local); + extern int wcmDeviceTypeKeys(LocalDevicePtr local, unsigned long* keys); #endif /***************************************************************************** @@ -443,13 +444,11 @@ static LocalDevicePtr xf86WcmInit(InputDriverPtr drv, IDevPtr dev, int flags) LocalDevicePtr fakeLocal = NULL; WacomDevicePtr priv = NULL; WacomCommonPtr common = NULL; + const char* type; char *s, b[12]; int i, oldButton; LocalDevicePtr localDevices; -#ifdef WCM_XORG_XSERVER_1_4 char* device; - struct input_id id; -#endif WacomToolPtr tool = NULL; WacomToolAreaPtr area = NULL; @@ -466,37 +465,42 @@ static LocalDevicePtr xf86WcmInit(InputDriverPtr drv, IDevPtr dev, int flags) */ xf86CollectInputOptions(fakeLocal, default_options, NULL); -#ifdef WCM_XORG_XSERVER_1_4 device = xf86CheckStrOption(fakeLocal->options, "Device", NULL); fakeLocal->name = dev->identifier; + /* Type is mandatory */ + type = xf86FindOptionValue(fakeLocal->options, "Type"); + /* leave the undefined for auto-dev (if enabled) to deal with */ +#ifdef WCM_XORG_XSERVER_1_4 if(device) { - if (!xf86WcmIsWacomDevice(device, &id)) - goto SetupProc_fail; + unsigned long keys[NBITS(KEY_MAX)]; + if (!xf86WcmIsWacomDevice(device)) + goto SetupProc_fail; - /* check if the type is valid for the device */ - if(!wcmIsAValidType(device, fakeLocal)) - goto SetupProc_fail; + /* initialize supported keys */ + wcmDeviceTypeKeys(fakeLocal, keys); - /* check if the device has been added */ + /* check if the type is valid for the device */ + if(!wcmIsAValidType(type, keys)) + goto SetupProc_fail; + + /* check if the device has been added */ if (wcmIsDuplicate(device, fakeLocal)) goto SetupProc_fail; } #endif /* WCM_XORG_XSERVER_1_4 */ - /* Type is mandatory */ - s = xf86FindOptionValue(fakeLocal->options, "Type"); - if (s && (xf86NameCmp(s, "stylus") == 0)) + if (type && (xf86NameCmp(type, "stylus") == 0)) local = xf86WcmAllocateStylus(); - else if (s && (xf86NameCmp(s, "touch") == 0)) + else if (type && (xf86NameCmp(type, "touch") == 0)) local = xf86WcmAllocateTouch(); - else if (s && (xf86NameCmp(s, "cursor") == 0)) + else if (type && (xf86NameCmp(type, "cursor") == 0)) local = xf86WcmAllocateCursor(); - else if (s && (xf86NameCmp(s, "eraser") == 0)) + else if (type && (xf86NameCmp(type, "eraser") == 0)) local = xf86WcmAllocateEraser(); - else if (s && (xf86NameCmp(s, "pad") == 0)) + else if (type && (xf86NameCmp(type, "pad") == 0)) local = xf86WcmAllocatePad(); else { @@ -879,7 +883,8 @@ static LocalDevicePtr xf86WcmInit(InputDriverPtr drv, IDevPtr dev, int flags) xf86Msg(X_CONFIG, "%s: Touch is enabled \n", common->wcmDevice); /* Touch gesture applies to the whole tablet */ - common->wcmGesture = xf86SetBoolOption(local->options, "Touch", common->wcmGestureDefault); + common->wcmGesture = xf86SetBoolOption(local->options, "Gesture", + common->wcmGestureDefault); if ( common->wcmGesture ) xf86Msg(X_CONFIG, "%s: Touch gesture is enabled \n", common->wcmDevice); diff --git a/src/xdrv/wcmISDV4.c b/src/xdrv/wcmISDV4.c index da6d4ab..bf667db 100755 --- a/src/xdrv/wcmISDV4.c +++ b/src/xdrv/wcmISDV4.c @@ -102,7 +102,8 @@ static int isdv4Query(LocalDevicePtr local, const char* query, char* data) err = xf86WcmWrite(local->fd, WC_ISDV4_STOP, strlen(WC_ISDV4_STOP)); if (err == -1) { - ErrorF("Wacom xf86WcmWrite ISDV4_STOP error : %s\n", strerror(errno)); + xf86Msg(X_WARNING, "Wacom xf86WcmWrite ISDV4_STOP error : %s\n", + strerror(errno)); return !Success; } @@ -113,13 +114,13 @@ static int isdv4Query(LocalDevicePtr local, const char* query, char* data) /* Send query command to the tablet */ if (!xf86WcmWriteWait(local->fd, query)) { - ErrorF("Wacom unable to xf86WcmWrite request %s ISDV4 query command " - "after %d tries\n", query, MAXTRY); + xf86Msg(X_WARNING, "Wacom unable to xf86WcmWrite request %s ISDV4" + " query command after %d tries\n", query, MAXTRY); return !Success; } /* Read the control data */ - if (!xf86WcmWaitForTablet(local->fd, data, 11)) + if (!xf86WcmWaitForTablet(local->fd, data, WACOM_PKGLEN_TPCCTL)) { /* Try 19200 if it is not a touch query */ if (common->wcmISDV4Speed != 19200 && strcmp(query, WC_ISDV4_TOUCH_QUERY)) @@ -131,8 +132,8 @@ static int isdv4Query(LocalDevicePtr local, const char* query, char* data) } else { - ErrorF("Wacom unable to read ISDV4 %s data " - "after %d tries at (%d)\n", query, MAXTRY, common->wcmISDV4Speed); + xf86Msg(X_WARNING, "Wacom unable to read ISDV4 %s data after %d" + " tries at (%d)\n", query, MAXTRY, common->wcmISDV4Speed); return !Success; } } @@ -150,11 +151,12 @@ static int isdv4Query(LocalDevicePtr local, const char* query, char* data) } else { - /* Reread the control data since with some vendors it fails the first time */ - xf86WcmWaitForTablet(local->fd, data, 11); + /* Reread the control data since it may fail the first time */ + xf86WcmWaitForTablet(local->fd, data, WACOM_PKGLEN_TPCCTL); if ( !(data[0] & 0x40) ) { - ErrorF("Wacom ISDV4 control data (%x) error in %s query\n", data[0], query); + xf86Msg(X_WARNING, "Wacom ISDV4 control data (%x) error in %s" + " query\n", data[0], query); return !Success; } } @@ -171,11 +173,8 @@ static void isdv4InitISDV4(WacomCommonPtr common, const char* id, float version) { /* set parameters */ common->wcmProtocolLevel = 4; - common->wcmPktLength = WACOM_PKGLEN_TPC; /* length of a packet - * device packets are 9 bytes - * resistive touch is 5 bytes - * capacitive touch is 7 bytes - */ + /* length of a packet */ + common->wcmPktLength = WACOM_PKGLEN_TPC; /* digitizer X resolution in points/inch */ common->wcmResolX = 2540; @@ -198,12 +197,13 @@ static int isdv4GetRanges(LocalDevicePtr local) char data[BUFFER_SIZE]; WacomDevicePtr priv = (WacomDevicePtr)local->private; WacomCommonPtr common = priv->common; - char * s; + int ret = Success; DBG(2, priv->debugLevel, ErrorF("getting ISDV4 Ranges\n")); /* Send query command to the tablet */ - if (isdv4Query(local, WC_ISDV4_QUERY, data) == Success) + ret = isdv4Query(local, WC_ISDV4_QUERY, data); + if (ret == Success) { /* transducer data */ common->wcmMaxZ = ( data[5] | ((data[6] & 0x07) << 7) ); @@ -219,77 +219,117 @@ static int isdv4GetRanges(LocalDevicePtr local) } common->wcmVersion = ( data[10] | (data[9] << 7) ); + + /* default to no pen 2FGT if size is undefined */ + if (!common->wcmMaxX || !common->wcmMaxY) + common->tablet_id = 0xe2; + + DBG(2, priv->debugLevel, ErrorF("isdv4GetRanges Pen speed=%d " + "maxX=%d maxY=%d maxZ=%d TouchresX=%d TouchresY=%d \n", + common->wcmISDV4Speed, common->wcmMaxX, common->wcmMaxY, + common->wcmMaxZ, common->wcmResolX, common->wcmResolY)); } - else - return !Success; - if (common->wcmISDV4Speed != 19200) + /* Touch might be supported. Send a touch query command */ + common->wcmISDV4Speed = 38400; + if (isdv4Query(local, WC_ISDV4_TOUCH_QUERY, data) == Success) { - /* default to 0x93 (resistive touch) */ - common->wcmPktLength = WACOM_PKGLEN_TOUCH0; - common->tablet_id = 0x93; - - /* Touch might be supported. Send a touch query command */ - if (isdv4Query(local, WC_ISDV4_TOUCH_QUERY, data) == Success) + switch(data[2] & 0x07) { - /* (data[2] & 0x07) == 0 is for resistive touch */ - if (!(data[2] & 0x07) && data[1]) - { - common->wcmMaxTouchX = common->wcmMaxTouchY = (int)(1 << data[1]); - } + case 0x00: /* resistive touch & pen */ + common->wcmPktLength = WACOM_PKGLEN_TOUCH0; + common->tablet_id = 0x93; + break; + case 0x01: /* capacitive touch & pen */ + common->wcmPktLength = WACOM_PKGLEN_TOUCH; + common->tablet_id = 0x9a; + break; + case 0x02: /* resistive touch */ + common->wcmPktLength = WACOM_PKGLEN_TOUCH0; + common->tablet_id = 0x93; + break; + case 0x03: /* capacitive touch */ + common->wcmPktLength = WACOM_PKGLEN_TOUCH; + common->tablet_id = 0x9f; + break; + case 0x04: /* capacitive touch */ + common->wcmPktLength = WACOM_PKGLEN_TOUCH; + common->tablet_id = 0x9f; + break; + case 0x05: + common->wcmPktLength = WACOM_PKGLEN_TOUCH2FG; + /* a penabled */ + if (common->tablet_id == 0x90) + common->tablet_id = 0xe3; + break; + } - if ((data[0] & 0x41) && (data[2] & 0x07)) - { - /* tablet model */ - switch (data[2] & 0x07) + switch(data[0] & 0x3f) + { + /* single finger touch */ + case 0x01: + if ((common->tablet_id != 0x93) && + (common->tablet_id != 0x9A) && + (common->tablet_id != 0x9F)) { - case 0x01: - common->wcmPktLength = WACOM_PKGLEN_TOUCH; - common->tablet_id = 0x9A; - break; - case 0x02: - case 0x04: - common->wcmPktLength = WACOM_PKGLEN_TOUCH; - common->tablet_id = 0x9F; - break; + xf86Msg(X_WARNING, "WACOM: %s tablet id(0x%x)" + " mismatch with data id (0x01) \n", + local->name, common->tablet_id); + return ret; } - - /* touch logical size for tablet PC with touch */ - if (data[1]) + break; + /* 2FGT */ + case 0x03: + if ((common->tablet_id != 0xE2) && + (common->tablet_id != 0xE3)) { - common->wcmMaxTouchX = common->wcmMaxTouchY = (int)(1 << data[1]); + xf86Msg(X_WARNING, "WACOM: %s tablet id(0x%x)" + " mismatch with data id (0x03) \n", + local->name, common->tablet_id); + return ret; } + break; + } - /* Max capacity */ - common->wcmMaxCapacity = (int)(1 << data[7]); - - if (common->wcmMaxCapacity) - { - common->wcmTouchResolX = common->wcmMaxTouchX / ( 2540 * - ((data[3] << 9) | (data[4] << 2) | ((data[2] & 0x60) >> 5))); - common->wcmTouchResolX = common->wcmMaxTouchX / ( 2540 * - ((data[5] << 9) | (data[6] << 2) | ((data[2] & 0x18) >> 3))); - } - } + /* don't overwrite the default */ + if ((data[2] & 0x78) | data[3] | data[4] | data[5] | data[6]) + { + common->wcmMaxTouchX = ((data[3] << 9) | + (data[4] << 2) | ((data[2] & 0x60) >> 5)); + common->wcmMaxTouchY = ((data[5] << 9) | + (data[6] << 2) | ((data[2] & 0x18) >> 3)); } + else if (data[1]) + common->wcmMaxTouchX = common->wcmMaxTouchY = (int)(1 << data[1]); - s = xf86FindOptionValue(local->options, "Touch"); - if ( !s || (strstr(s, "on")) ) /* touch option is on */ + if (data[1]) { - common->wcmTouch = 1; + common->wcmTouchResolX = common->wcmTouchResolY = 10; + common->wcmTouchDefault = 1; } + else + common->wcmTouchDefault = 0; - /* TouchDefault was off for all devices - * defaults to enable when it is a touch device - */ - common->wcmTouchDefault = 1; - } + /* updated touch info */ + common->wcmTouch = xf86SetBoolOption(local->options, "Touch", + common->wcmTouchDefault); - DBG(2, priv->debugLevel, ErrorF("isdv4GetRanges speed=%d maxX=%d maxY=%d " - "maxZ=%d TouchresX=%d TouchresY=%d \n", common->wcmISDV4Speed, - common->wcmMaxX, common->wcmMaxY, common->wcmMaxZ, - common->wcmResolX, common->wcmResolY)); - return Success; + if ((common->tablet_id == 0xE2) || + (common->tablet_id == 0xE3)) + common->wcmGestureDefault = 1; + + common->wcmGesture = xf86SetBoolOption(local->options, "Gesture", + common->wcmGestureDefault); + + common->wcmVersion = ( data[10] | (data[9] << 7) ); + ret = Success; + + DBG(2, priv->debugLevel, ErrorF("isdv4GetRanges touch speed=%d " + "maxX=%d maxY=%d TouchresX=%d TouchresY=%d \n", + common->wcmISDV4Speed, common->wcmMaxTouchX, common->wcmMaxTouchY, + common->wcmTouchResolX, common->wcmTouchResolY)); + } + return ret; } static int isdv4StartTablet(LocalDevicePtr local) @@ -313,64 +353,28 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data) WacomDevicePtr priv = (WacomDevicePtr)local->private; WacomCommonPtr common = priv->common; WacomDeviceState* last = &common->wcmChannel[0].valid.state; + WacomDeviceState* lastTemp = &common->wcmChannel[1].valid.state; WacomDeviceState* ds; int n, cur_type, channel = 0; - static int touchInProx; DBG(10, common->debugLevel, ErrorF("isdv4Parse \n")); - channel = 0; /* determine the type of message (touch or stylus)*/ - if (data[0] & 0x18) /* not a pen */ + if (data[0] & 0x10) /* a touch data */ { - if ((last->device_id != TOUCH_DEVICE_ID && last->device_id && last->proximity ) || - !common->wcmTouch ) + if ((last->device_id != TOUCH_DEVICE_ID && last->device_id && + last->proximity) || !common->wcmTouch) { - if ((data[0] & 0x10) && (!(data[0] & 0x01))) /* a touch out-prox data */ - touchInProx = 0; - else - touchInProx = 1; - /* ignore touch event */ return common->wcmPktLength; } - else - { - if (data[0] & 0x10) /* a touch data */ - { - if (!touchInProx) - { - channel = 1; - } - else if (!(data[0] & 0x01)) /* touch out-prox */ - { - touchInProx = 0; - channel = 0; - } - else - { - /* ignore touch event */ - return common->wcmPktLength; - } - } - else - { - /* ignore touch event */ - return common->wcmPktLength; - } - } } else { /* touch was in control */ - if (common->wcmChannel[1].valid.state.proximity) - { + if (last->proximity && last->device_id == TOUCH_DEVICE_ID) /* let touch go */ - xf86WcmSoftOut(common, 1); - return 0; - } - common->wcmPktLength = WACOM_PKGLEN_TPC; - channel = 0; + xf86WcmSoftOut(common, channel); } if (common->buffer + common->bufpos - data < common->wcmPktLength) @@ -379,25 +383,18 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data) return common->wcmPktLength; } - if ((n = xf86WcmSerialValidate(common,data)) > 0) + /* Coordinate data bit check */ + if (data[0] & 0x40) /* control data */ + return common->wcmPktLength; + else if ((n = xf86WcmSerialValidate(common,data)) > 0) return n; - else - { - /* Coordinate data bit check */ - if (data[0] & 0x40) /* control data */ - return common->wcmPktLength; - } /* pick up where we left off, minus relative values */ ds = &common->wcmChannel[channel].work; RESET_RELATIVE(*ds); - if (common->wcmPktLength == WACOM_PKGLEN_TOUCH0 || - common->wcmPktLength == WACOM_PKGLEN_TOUCH) /* a touch */ + if (common->wcmPktLength != WACOM_PKGLEN_TPC) /* a touch */ { - /* touch without capacity has 5 bytes of data - * touch with capacity has 7 bytes of data - */ ds->x = (((int)data[1]) << 7) | ((int)data[2]); ds->y = (((int)data[3]) << 7) | ((int)data[4]); if (common->wcmPktLength == WACOM_PKGLEN_TOUCH) @@ -407,6 +404,27 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data) ds->buttons = ds->proximity = data[0] & 0x01; ds->device_type = TOUCH_ID; ds->device_id = TOUCH_DEVICE_ID; + + if (common->wcmPktLength == WACOM_PKGLEN_TOUCH2FG) + { + if ((data[0] & 0x02) || (!(data[0] & 0x02) && + lastTemp->proximity)) + { + /* Got 2FGT. Send the first one if received */ + if (ds->proximity || (!ds->proximity && + last->proximity)) + xf86WcmEvent(common, channel, ds); + + channel = 1; + ds = &common->wcmChannel[channel].work; + RESET_RELATIVE(*ds); + ds->x = (((int)data[7]) << 7) | ((int)data[8]); + ds->y = (((int)data[9]) << 7) | ((int)data[10]); + ds->device_type = TOUCH_ID; + ds->device_id = TOUCH_DEVICE_ID; + ds->proximity = data[0] & 0x02; + } + } DBG(8, priv->debugLevel, ErrorF("isdv4Parse MultiTouch " "%s proximity \n", ds->proximity ? "in" : "out of")); } diff --git a/src/xdrv/wcmSerial.c b/src/xdrv/wcmSerial.c index 9b9a1b7..a7fc2b3 100755 --- a/src/xdrv/wcmSerial.c +++ b/src/xdrv/wcmSerial.c @@ -1307,7 +1307,7 @@ int xf86WcmSerialValidate(WacomCommonPtr common, const unsigned char* data) { bad = 1; if (i!=0 && (data[i] & HEADER_BIT)) { - ErrorF("xf86WcmSerialValidate: bad magic at %d " + xf86Msg(X_WARNING, "xf86WcmSerialValidate: bad magic at %d " "v=%x l=%d\n", i, data[i], common->wcmPktLength); return i; } diff --git a/src/xdrv/wcmTouchFilter.c b/src/xdrv/wcmTouchFilter.c index 23971a3..7e8d52d 100644 --- a/src/xdrv/wcmTouchFilter.c +++ b/src/xdrv/wcmTouchFilter.c @@ -17,9 +17,10 @@ */ #include "xf86Wacom.h" +#ifdef WCM_KEY_SENDING_SUPPORT #include <math.h> -// Defines for 2FC Gesture +/* Defines for 2FC Gesture */ #define WACOM_DIST_IN_POINT 300 #define WACOM_APART_IN_POINT 350 #define WACOM_MOTION_IN_POINT 50 @@ -34,7 +35,7 @@ #define GESTURE_ZOOM_MODE 4 -// Defines for Tap Add-a-Finger to Click +/* Defines for Tap Add-a-Finger to Click */ #define WACOM_TAP_TIME_IN_MS 150 extern void xf86WcmRotateCoordinates(LocalDevicePtr local, int x, int y); @@ -389,4 +390,4 @@ static void xf86WcmFingerZoom(WacomDevicePtr priv) common->wcmGestureState[1] = ds[1]; } } - +#endif /* WCM_KEY_SENDING_SUPPORT */ diff --git a/src/xdrv/wcmUSB.c b/src/xdrv/wcmUSB.c index 2fc5f0c..bfb4c44 100755 --- a/src/xdrv/wcmUSB.c +++ b/src/xdrv/wcmUSB.c @@ -375,7 +375,7 @@ static Bool usbDetect(LocalDevicePtr local) if (err < 0) { - ErrorF("usbDetect: can not ioctl version\n"); + xf86Msg(X_WARNING, "usbDetect: can not ioctl version\n"); return 0; } #ifdef EVIOCGRAB diff --git a/src/xdrv/wcmValidateDevice.c b/src/xdrv/wcmValidateDevice.c index c079e73..a265286 100755 --- a/src/xdrv/wcmValidateDevice.c +++ b/src/xdrv/wcmValidateDevice.c @@ -23,6 +23,7 @@ #include <fcntl.h> #include <sys/stat.h> #endif + #include <linux/serial.h> /***************************************************************************** * xf86WcmCheckSource - Check if there is another source defined this device @@ -151,42 +152,106 @@ static struct { "pad", BTN_TOOL_FINGER } }; -static Bool checkValidType(char* type, unsigned long* keys) +/* validate tool type for device/product */ +Bool wcmIsAValidType(const char* type, unsigned long* keys) { int j, ret = FALSE; +ErrorF("wcmIsAValidType type %s \n", type); + if (!type) + return ret; /* walkthrough all types */ for (j = 0; j < sizeof (wcmType) / sizeof (wcmType [0]); j++) { if (!strcmp(wcmType[j].type, type)) if (ISBITSET (keys, wcmType[j].tool)) + { ret = TRUE; + break; + } } +ErrorF("wcmIsAValidType found type %s %d \n", type, ret); return ret; } -/* validate tool type for device/product */ -Bool wcmIsAValidType(char* device, LocalDevicePtr local) +/* Choose valid types according to device ID */ +int wcmDeviceTypeKeys(LocalDevicePtr local, unsigned long* keys) { - Bool ret = FALSE; - int fd = -1; - unsigned long keys[NBITS(KEY_MAX)]; - char* type = xf86FindOptionValue(local->options, "Type"); + int ret = 1, i, fd = -1; + unsigned int id = 0; + char* device, *stopstring; + char* str = strstr(local->name, "WACf"); + struct serial_struct tmp; + + device = xf86SetStrOption(local->options, "Device", NULL); SYSCALL(fd = open(device, O_RDONLY)); if (fd < 0) - return FALSE; - - /* test if the tool is defined in the kernel */ - if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keys)), keys) < 0) { - xf86Msg(X_ERROR, "WACOM: wcmIsAValidType unable to ioctl key bits.\n"); - return FALSE; + xf86Msg(X_WARNING, "%s: failed to open %s in " + "wcmDeviceTypeKeys.\n", local->name, device); + return 0; } - close(fd); - ret = checkValidType(type, keys); + /* we have tried memset. it doesn't work */ + for (i=0; i<NBITS(KEY_MAX); i++) + keys[i] = 0; + + /* serial ISDV4 devices */ + if (ioctl(fd, TIOCGSERIAL, &tmp) == 0) + { + if (str) /* id in name */ + { + str = str + 4; + if (str) + id = (int)strtol(str, &stopstring, 16); + + } + else /* id in file /sys/class/tty/%str/device/id */ + { + FILE *file; + char sysfs_id[256]; + str = strstr(device, "ttyS"); + snprintf(sysfs_id, sizeof(sysfs_id), + "/sys/class/tty/%s/device/id", str); + file = fopen(sysfs_id, "r"); + + if (file) + { + /* make sure we fall to default */ + if (fscanf(file, "WACf%x\n", &id) <= 0) + id = 0; + } + } + /* default to penabled */ + keys[LONG(BTN_TOOL_PEN)] |= BIT(BTN_TOOL_PEN); + keys[LONG(BTN_TOOL_RUBBER)] |= BIT(BTN_TOOL_RUBBER); + /* id < 0x008 are only penabled */ + if (id > 0x007) + { + keys[LONG(BTN_TOOL_DOUBLETAP)] |= BIT(BTN_TOOL_DOUBLETAP); + } + + /* no pen 2FGT */ + if (id == 0x010) + { + keys[LONG(BTN_TOOL_PEN)] &= ~BIT(BTN_TOOL_PEN); + keys[LONG(BTN_TOOL_RUBBER)] &= ~BIT(BTN_TOOL_RUBBER); + } + } + else /* USB devices */ + { + /* test if the tool is defined in the kernel */ + if (ioctl(fd, EVIOCGBIT(EV_KEY, (sizeof(unsigned long) + * NBITS(KEY_MAX))), keys) < 0) + { + xf86Msg(X_ERROR, "%s: wcmDeviceTypeKeys unable to " + "ioctl USB key bits.\n", local->name); + ret = 0; + } + } + close(fd); return ret; } #endif /* WCM_XORG_XSERVER_1_4 */ diff --git a/src/xdrv/xf86Wacom.c b/src/xdrv/xf86Wacom.c index 173fa8f..38c382d 100755 --- a/src/xdrv/xf86Wacom.c +++ b/src/xdrv/xf86Wacom.c @@ -85,11 +85,12 @@ * 2009-10-15 47-pc0.8.4-4 - added calibration-only wacomcpl * 2009-10-19 47-pc0.8.5 - Added support for TPC (0xE2, 0xE3 & 0x9F) * 2009-10-31 47-pc0.8.5-1 - Avoid duplicated devices for Xorg 1.4 and later - * 2009-11-6 47-pc0.8.5-2 - Validate tool type associated with device - * 2009-11-6 47-pc0.8.5-4 - Allow multiple tools to be defined for one type + * 2009-11-06 47-pc0.8.5-2 - Validate tool type associated with device + * 2009-11-11 47-pc0.8.5-4 - Allow multiple tools to be defined for one type + * 2009-11-24 47-pc0.8.5-5 - Support hotplugging for serial ISDV4 */ -static const char identification[] = "$Identification: 47-0.8.5-4 $"; +static const char identification[] = "$Identification: 47-0.8.5-5 $"; /****************************************************************************/ @@ -102,6 +103,16 @@ static const char identification[] = "$Identification: 47-0.8.5-4 $"; #endif #endif +WacomDeviceClass* wcmDeviceClasses[] = +{ +#ifdef WCM_ENABLE_LINUXINPUT + &gWacomUSBDevice, +#endif + &gWacomISDV4Device, + &gWacomSerialDevice, + NULL +}; + static int xf86WcmDevOpen(DeviceIntPtr pWcm); static void xf86WcmDevReadInput(LocalDevicePtr local); static void xf86WcmDevControlProc(DeviceIntPtr device, PtrCtrl* ctrl); @@ -554,18 +565,24 @@ static int xf86WcmRegisterX11Devices (LocalDevicePtr local) } #ifdef WCM_XORG_XSERVER_1_4 -Bool xf86WcmIsWacomDevice (char* fname, struct input_id* id) +Bool xf86WcmIsWacomDevice (char* fname) { int fd = -1; + struct input_id id; SYSCALL(fd = open(fname, O_RDONLY)); if (fd < 0) return FALSE; - ioctl(fd, EVIOCGID, id); - close(fd); + if (ioctl(fd, EVIOCGID, &id) < 0) + { + SYSCALL(close(fd)); + return FALSE; + } - if (id->vendor == 0x056a) + SYSCALL(close(fd)); + + if (id.vendor == 0x056a) return TRUE; else return FALSE; @@ -615,6 +632,49 @@ char *xf86WcmEventAutoDevProbe (LocalDevicePtr local) #endif /***************************************************************************** + * xf86WcmOpen -- + ****************************************************************************/ + +Bool xf86WcmOpen(LocalDevicePtr local) +{ + WacomDevicePtr priv = (WacomDevicePtr)local->private; + WacomCommonPtr common = priv->common; + WacomDeviceClass** ppDevCls; + char id[BUFFER_SIZE]; + float version; + + DBG(1, priv->debugLevel, ErrorF("opening %s\n", common->wcmDevice)); + + local->fd = xf86OpenSerial(local->options); + if (local->fd < 0) + { + ErrorF("Error opening %s : %s\n", common->wcmDevice, + strerror(errno)); + return !Success; + } + + /* Detect device class; default is serial device */ + for (ppDevCls=wcmDeviceClasses; *ppDevCls!=NULL; ++ppDevCls) + { + if ((*ppDevCls)->Detect(local)) + { + common->wcmDevCls = *ppDevCls; + break; + } + } + + /* Initialize the tablet */ + if(common->wcmDevCls->Init(local, id, &version) != Success || + xf86WcmInitTablet(local, id, version) != Success) + { + xf86CloseSerial(local->fd); + local->fd = -1; + return !Success; + } + return Success; +} + +/***************************************************************************** * xf86WcmDevOpen -- * Open the physical device and init information structs. ****************************************************************************/ @@ -777,14 +837,18 @@ void xf86WcmReadPacket(LocalDevicePtr local) */ if (common->wcmForceDevice == DEVICE_ISDV4 && common->wcmDevCls != &gWacomUSBDevice) { - common->wcmPktLength = WACOM_PKGLEN_TPC; data = common->buffer; - if ( data[0] & 0x18 ) + if (data[0]) + common->wcmPktLength = WACOM_PKGLEN_TPC; + + if ( data[0] & 0x10 ) { - if (common->wcmMaxCapacity) + /* set touch PktLength */ + common->wcmPktLength = WACOM_PKGLEN_TOUCH0; + if ((common->tablet_id == 0x9a) || (common->tablet_id == 0x9f)) common->wcmPktLength = WACOM_PKGLEN_TOUCH; - else - common->wcmPktLength = WACOM_PKGLEN_TOUCH0; + if ((common->tablet_id == 0xe2) || (common->tablet_id == 0xe3)) + common->wcmPktLength = WACOM_PKGLEN_TOUCH2FG; } } diff --git a/src/xdrv/xf86WacomDefs.h b/src/xdrv/xf86WacomDefs.h index b155b24..1a93749 100755 --- a/src/xdrv/xf86WacomDefs.h +++ b/src/xdrv/xf86WacomDefs.h @@ -56,6 +56,8 @@ #define WACOM_PKGLEN_TOUCH 7 #define WACOM_PKGLEN_GRAPHIRE 8 #define WACOM_PKGLEN_TPC 9 +#define WACOM_PKGLEN_TPCCTL 11 +#define WACOM_PKGLEN_TOUCH2FG 13 /* defines to discriminate second side button and the eraser */ #define ERASER_PROX 4 |