summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpingc <pingc>2009-11-10 01:40:04 +0000
committerpingc <pingc>2009-11-10 01:40:04 +0000
commit336c6d03d3a36145508fc449b2b15a70671d4f48 (patch)
treea24d52eb9ef5653de8b7c1fea7a76b162d8c5b4b
parent9fd91ce680abaa07303d9be62df30b27801a4e06 (diff)
downloadxf86-input-wacom-336c6d03d3a36145508fc449b2b15a70671d4f48.tar.gz
Support two finger touchrelease-0.8.5-2
-rw-r--r--ChangeLog8
-rw-r--r--configure.in18
-rwxr-xr-xsrc/2.6.24/wacom_sys.c58
-rwxr-xr-xsrc/2.6.26/wacom_sys.c58
-rw-r--r--src/2.6.28/wacom_sys.c62
-rwxr-xr-xsrc/2.6.28/wacom_wac.c229
-rwxr-xr-xsrc/2.6.28/wacom_wac.h8
-rw-r--r--src/include/xdrv-config.h.in3
-rwxr-xr-xsrc/util/wacomcfg.c4
-rwxr-xr-xsrc/util/xsetwacom.c16
-rwxr-xr-xsrc/xdrv/Makefile.am8
-rwxr-xr-xsrc/xdrv/wcmCommon.c726
-rwxr-xr-xsrc/xdrv/wcmConfig.c340
-rwxr-xr-xsrc/xdrv/wcmISDV4.c34
-rwxr-xr-xsrc/xdrv/wcmMapping.c874
-rwxr-xr-xsrc/xdrv/wcmSerial.c8
-rw-r--r--src/xdrv/wcmTouchFilter.c392
-rwxr-xr-xsrc/xdrv/wcmUSB.c261
-rwxr-xr-xsrc/xdrv/wcmValidateDevice.c306
-rw-r--r--src/xdrv/wcmXCommand.c31
-rwxr-xr-xsrc/xdrv/xf86Wacom.c286
-rwxr-xr-xsrc/xdrv/xf86Wacom.h6
-rwxr-xr-xsrc/xdrv/xf86WacomDefs.h69
23 files changed, 2211 insertions, 1594 deletions
diff --git a/ChangeLog b/ChangeLog
index bcac61b..18b2352 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-11-09 Ping Cheng <pingc@wacom.com>
+ * Added right click, scroll, and zoom for two finger touch
+ * Updated kernel driver
+ * Validating tool by retriving device type from kernel driver
+ * Fixed a bug in xsetwacom TWINVIEW option
+ * Fixed a device id issue in xsetwacom TOOLID option
+ * Label 0.8.5-2
+
2009-10-31 Ping Cheng <pingc@wacom.com>
* Avoid duplicated devices
* Validate tool type before adding it
diff --git a/configure.in b/configure.in
index 6ee6f6a..1a22de0 100644
--- a/configure.in
+++ b/configure.in
@@ -1,5 +1,5 @@
AC_PREREQ(2.58)
-AC_INIT(linuxwacom, 0.8.5)
+AC_INIT(linuxwacom, 0.8.5-2)
AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE
@@ -456,6 +456,22 @@ if test "$WCM_ENV_XFREE86" != yes; then
], , [WCM_XORG_XORG=yes], [WCM_XORG_XORG=no])
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($WCM_XORG_XORG)
+ AC_MSG_CHECKING([if Xorg server is version 1.5.2 or later])
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="-I$WCM_XORGSDK_DIR $CFLAGS"
+ AC_TRY_COMPILE([
+#include <xorg-server.h>
+#include <xorgVersion.h>
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 5, 2, 0, 0)
+# error "X.org < 1.5.2 "
+#endif
+], , [WCM_XORG_XSERVER_1_5_2=yes], [WCM_XORG_XSERVER_1_5_2=no])
+ CFLAGS="$save_CFLAGS"
+ AC_MSG_RESULT($WCM_XORG_XSERVER_1_5_2)
+ if test "$WCM_XORG_XSERVER_1_5_2" = "yes"; then
+ AC_DEFINE(WCM_XORG_XSERVER_1_5_2, 1,
+ [Using version 1.5.2 or later of X.org])
+ fi
AC_MSG_CHECKING([if Xorg server is version 1.6 or later])
save_CFLAGS="$CFLAGS"
CFLAGS="-I$WCM_XORGSDK_DIR $CFLAGS"
diff --git a/src/2.6.24/wacom_sys.c b/src/2.6.24/wacom_sys.c
index 5273942..bd6f83b 100755
--- a/src/2.6.24/wacom_sys.c
+++ b/src/2.6.24/wacom_sys.c
@@ -197,6 +197,7 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) |
BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
+ BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) |
BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2);
input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
}
@@ -244,6 +245,7 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) |
BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
+ BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) |
BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) |
BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) |
BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2);
@@ -257,7 +259,8 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2);
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
+ BIT_MASK(BTN_STYLUS) | BIT_MASK(BTN_STYLUS2);
}
void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
@@ -267,16 +270,20 @@ 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)
{
- input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->touch_x_max, 4, 0);
- input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->touch_y_max, 4, 0);
- input_set_abs_params(input_dev, ABS_Z, 0, wacom_wac->features->touch_x_res, 0, 0);
- input_set_abs_params(input_dev, ABS_RZ, 0, wacom_wac->features->touch_y_res, 0, 0);
- input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP);
+ 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);
+ }
}
void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP);
+ if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) {
+ 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);
+ }
}
static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc,
@@ -327,14 +334,16 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
case HID_USAGE_X:
if (usage == WCM_DESKTOP) {
if (finger) {
- features->touch_x_max =
+ features->device_type = BTN_TOOL_DOUBLETAP;
+ features->x_max =
wacom_le16_to_cpu(&report[i + 3]);
- features->touch_x_res =
+ features->x_phy =
wacom_le16_to_cpu(&report[i + 6]);
features->unit = report[i + 9];
features->unitExpo = report[i + 11];
i += 12;
} else if (pen) {
+ features->device_type = BTN_TOOL_PEN;
features->x_max =
(wacom_le16_to_cpu(&report[i+3]));
i += 4;
@@ -351,20 +360,22 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
case HID_USAGE_Y:
if (usage == WCM_DESKTOP) {
if (finger) {
+ features->device_type = BTN_TOOL_DOUBLETAP;
if (strstr(features->name, "Wacom ISDv4 E")) {
- features->touch_y_max =
+ features->y_max =
wacom_le16_to_cpu(&report[i + 3]);
- features->touch_y_res =
+ features->y_phy =
wacom_le16_to_cpu(&report[i + 6]);
i += 7;
} else {
- features->touch_y_max =
- features->touch_x_max;
- features->touch_y_res =
+ features->y_max =
+ features->x_max;
+ features->y_phy =
wacom_le16_to_cpu(&report[i + 3]);
i += 4;
}
} else if (pen) {
+ features->device_type = BTN_TOOL_PEN;
features->y_max = (wacom_le16_to_cpu(&report[i+3]));
i += 4;
}
@@ -435,6 +446,10 @@ 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);
@@ -448,10 +463,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
endpoint = &intf->cur_altsetting->endpoint[0].desc;
- /* Initialize touch_x_max and touch_y_max in case it is not defined */
if (wacom_wac->features->type == TABLETPC || wacom_wac->features->type == TABLETPC2FG) {
- wacom_wac->features->touch_x_max = 1023;
- wacom_wac->features->touch_y_max = 1023;
/* TabletPC need to retrieve the physical and logical maximum from report descriptor */
if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
@@ -464,14 +476,16 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
error = wacom_parse_hid(intf, hid_desc, wacom_wac);
if (error)
goto fail2;
- } else {
- wacom_wac->features->touch_x_max = 0;
- wacom_wac->features->touch_y_max = 0;
+
+ /* 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;
+ }
}
input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) |
- BIT_MASK(BTN_TOUCH);
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH);
input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0);
input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0);
diff --git a/src/2.6.26/wacom_sys.c b/src/2.6.26/wacom_sys.c
index d797b73..af1102e 100755
--- a/src/2.6.26/wacom_sys.c
+++ b/src/2.6.26/wacom_sys.c
@@ -214,6 +214,7 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) |
BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
+ BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) |
BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2);
input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
}
@@ -261,6 +262,7 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) |
BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
+ BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) |
BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) |
BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) |
BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2);
@@ -274,7 +276,8 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2);
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
+ BIT_MASK(BTN_STYLUS) | BIT_MASK(BTN_STYLUS2);
}
void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
@@ -284,16 +287,20 @@ 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)
{
- input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->touch_x_max, 4, 0);
- input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->touch_y_max, 4, 0);
- input_set_abs_params(input_dev, ABS_Z, 0, wacom_wac->features->touch_x_res, 0, 0);
- input_set_abs_params(input_dev, ABS_RZ, 0, wacom_wac->features->touch_y_res, 0, 0);
- input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP);
+ 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);
+ }
}
void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP);
+ if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) {
+ 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);
+ }
}
static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc,
@@ -344,14 +351,16 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
case HID_USAGE_X:
if (usage == WCM_DESKTOP) {
if (finger) {
- features->touch_x_max =
+ features->device_type = BTN_TOOL_DOUBLETAP;
+ features->x_max =
wacom_le16_to_cpu(&report[i + 3]);
- features->touch_x_res =
+ features->x_phy =
wacom_le16_to_cpu(&report[i + 6]);
features->unit = report[i + 9];
features->unitExpo = report[i + 11];
i += 12;
} else if (pen) {
+ features->device_type = BTN_TOOL_PEN;
features->x_max = (wacom_le16_to_cpu(&report[i+3]));
i += 4;
}
@@ -367,20 +376,22 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
case HID_USAGE_Y:
if (usage == WCM_DESKTOP) {
if (finger) {
+ features->device_type = BTN_TOOL_DOUBLETAP;
if (strstr(features->name, "Wacom ISDv4 E")) {
- features->touch_y_max =
+ features->y_max =
wacom_le16_to_cpu(&report[i + 3]);
- features->touch_y_res =
+ features->y_phy =
wacom_le16_to_cpu(&report[i + 6]);
i += 7;
} else {
- features->touch_y_max =
- features->touch_x_max;
- features->touch_y_res =
+ features->y_max =
+ features->x_max;
+ features->y_phy =
wacom_le16_to_cpu(&report[i + 3]);
i += 4;
}
} else if (pen) {
+ features->device_type = BTN_TOOL_PEN;
features->y_max = (wacom_le16_to_cpu(&report[i+3]));
i += 4;
}
@@ -453,6 +464,10 @@ 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);
@@ -466,10 +481,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
endpoint = &intf->cur_altsetting->endpoint[0].desc;
- /* Initialize touch_x_max and touch_y_max in case it is not defined */
if (wacom_wac->features->type == TABLETPC || wacom_wac->features->type == TABLETPC2FG) {
- wacom_wac->features->touch_x_max = 1023;
- wacom_wac->features->touch_y_max = 1023;
/* TabletPC need to retrieve the physical and logical maximum from report descriptor */
if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
@@ -482,14 +494,16 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
error = wacom_parse_hid(intf, hid_desc, wacom_wac);
if (error)
goto fail2;
- } else {
- wacom_wac->features->touch_x_max = 0;
- wacom_wac->features->touch_y_max = 0;
+
+ /* 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;
+ }
}
input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) |
- BIT_MASK(BTN_TOUCH);
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH);
input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0);
input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0);
diff --git a/src/2.6.28/wacom_sys.c b/src/2.6.28/wacom_sys.c
index b3113b0..e9c27f7 100644
--- a/src/2.6.28/wacom_sys.c
+++ b/src/2.6.28/wacom_sys.c
@@ -209,6 +209,7 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) |
BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
+ BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) |
BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2);
input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
}
@@ -256,6 +257,7 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) |
BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
+ BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) |
BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) |
BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) |
BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2);
@@ -269,7 +271,8 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2);
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
+ BIT_MASK(BTN_STYLUS) | BIT_MASK(BTN_STYLUS2);
}
void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
@@ -279,16 +282,20 @@ 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)
{
- input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->touch_x_max, 4, 0);
- input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->touch_y_max, 4, 0);
- input_set_abs_params(input_dev, ABS_Z, 0, wacom_wac->features->touch_x_res, 0, 0);
- input_set_abs_params(input_dev, ABS_RZ, 0, wacom_wac->features->touch_y_res, 0, 0);
- input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP);
+ 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);
+ }
}
void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP);
+ if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP) {
+ 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);
+ }
}
static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc,
@@ -342,14 +349,16 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
case HID_USAGE_X:
if (usage == WCM_DESKTOP) {
if (finger) {
- features->touch_x_max =
+ features->device_type = BTN_TOOL_DOUBLETAP;
+ features->x_max =
wacom_le16_to_cpu(&report[i + 3]);
- features->touch_x_res =
+ features->x_phy =
wacom_le16_to_cpu(&report[i + 6]);
features->unit = report[i + 9];
features->unitExpo = report[i + 11];
i += 12;
} else if (pen) {
+ features->device_type = BTN_TOOL_PEN;
features->x_max =
wacom_le16_to_cpu(&report[i + 3]);
i += 4;
@@ -367,20 +376,22 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
case HID_USAGE_Y:
if (usage == WCM_DESKTOP) {
if (finger) {
+ features->device_type = BTN_TOOL_DOUBLETAP;
if (strstr(features->name, "Wacom ISDv4 E")) {
- features->touch_y_max =
+ features->y_max =
wacom_le16_to_cpu(&report[i + 3]);
- features->touch_y_res =
+ features->y_phy =
wacom_le16_to_cpu(&report[i + 6]);
i += 7;
} else {
- features->touch_y_max =
- features->touch_x_max;
- features->touch_y_res =
+ features->y_max =
+ features->x_max;
+ features->y_phy =
wacom_le16_to_cpu(&report[i + 3]);
i += 4;
}
} else if (pen) {
+ features->device_type = BTN_TOOL_PEN;
features->y_max =
wacom_le16_to_cpu(&report[i + 3]);
i += 4;
@@ -457,6 +468,10 @@ 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);
@@ -470,10 +485,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
endpoint = &intf->cur_altsetting->endpoint[0].desc;
- /* Initialize touch_x_max and touch_y_max in case it is not defined in HID descriptor */
if (features->type == TABLETPC || features->type == TABLETPC2FG) {
- features->touch_x_max = 1023;
- features->touch_y_max = 1023;
/* TabletPC need to retrieve the physical and logical maximum from report descriptor */
if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
@@ -486,20 +498,20 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
error = wacom_parse_hid(intf, hid_desc, wacom_wac);
if (error)
goto fail2;
- } else {
- features->touch_x_max = 0;
- features->touch_y_max = 0;
- }
+ /* 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;
+ }
+ }
input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
- BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS);
+ 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);
-
+
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);
diff --git a/src/2.6.28/wacom_wac.c b/src/2.6.28/wacom_wac.c
index 1fb3c62..39b5d68 100755
--- a/src/2.6.28/wacom_wac.c
+++ b/src/2.6.28/wacom_wac.c
@@ -73,9 +73,9 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
prox = data[1] & 0x40;
- wacom->id[0] = ERASER_DEVICE_ID;
if (prox) {
+ wacom->id[0] = ERASER_DEVICE_ID;
pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
if (wacom->features->pressure_max > 255)
pressure = (pressure << 1) | ((data[4] >> 6) & 1);
@@ -163,6 +163,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
{
unsigned char *data = wacom->data;
int x, y, rw;
+ static int penData = 0;
if ((data[0] & 0xff) != 2) {
dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
@@ -171,7 +172,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
if (data[1] & 0x80) {
/* in prox and not a pad data */
-
+ penData = 1;
switch ((data[1] >> 5) & 3) {
case 0: /* Pen */
@@ -187,8 +188,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
case 2: /* Mouse with wheel */
wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04);
if (wacom->features->type == WACOM_G4 ||
- wacom->features->type == WACOM_MO ||
- wacom->features->type == WACOM_GB ) {
+ wacom->features->type == WACOM_MO ) {
rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
wacom_report_rel(wcombo, REL_WHEEL, -rw);
} else
@@ -201,8 +201,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
if (wacom->features->type == WACOM_G4 ||
- wacom->features->type == WACOM_MO ||
- wacom->features->type == WACOM_GB )
+ wacom->features->type == WACOM_MO )
wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
else
wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
@@ -242,7 +241,11 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
switch (wacom->features->type) {
case WACOM_G4:
if (data[7] & 0xf8) {
- wacom_input_sync(wcombo); /* sync last event */
+ if (penData) {
+ wacom_input_sync(wcombo); /* sync last event */
+ if (!wacom->id[0])
+ penData = 0;
+ }
wacom->id[1] = PAD_DEVICE_ID;
wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
@@ -252,10 +255,15 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
} else if (wacom->id[1]) {
- wacom_input_sync(wcombo); /* sync last event */
+ if (penData) {
+ wacom_input_sync(wcombo); /* sync last event */
+ if (!wacom->id[0])
+ penData = 0;
+ }
wacom->id[1] = 0;
wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
+ wacom_report_rel(wcombo, REL_WHEEL, 0);
wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
wacom_report_abs(wcombo, ABS_MISC, 0);
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
@@ -263,7 +271,11 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
break;
case WACOM_MO:
if ((data[7] & 0xf8) || (data[8] & 0xff)) {
- wacom_input_sync(wcombo); /* sync last event */
+ if (penData) {
+ wacom_input_sync(wcombo); /* sync last event */
+ if (!wacom->id[0])
+ penData = 0;
+ }
wacom->id[1] = PAD_DEVICE_ID;
wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
@@ -274,7 +286,11 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
} else if (wacom->id[1]) {
- wacom_input_sync(wcombo); /* sync last event */
+ if (penData) {
+ wacom_input_sync(wcombo); /* sync last event */
+ if (!wacom->id[0])
+ penData = 0;
+ }
wacom->id[1] = 0;
wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
@@ -286,24 +302,6 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
}
break;
- case WACOM_GB:
- if (data [7] & 0x03) {
- wacom_input_sync(wcombo); /* sync last event */
- wacom->id[1] = PAD_DEVICE_ID;
- wacom_report_key(wcombo, BTN_0, (data[7] & 0x02));
- wacom_report_key(wcombo, BTN_1, (data[7] & 0x01));
- wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
- wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
- wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
- } else if (wacom->id[1]) {
- wacom_input_sync(wcombo); /* sync last event */
- wacom->id[1] = 0;
- wacom_report_key(wcombo, BTN_0, (data[7] & 0x02));
- wacom_report_key(wcombo, BTN_1, (data[7] & 0x01));
- wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
- wacom_report_abs(wcombo, ABS_MISC, 0);
- wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
- }
}
return 1;
}
@@ -634,13 +632,45 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
return 1;
}
+
+static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx)
+{
+ wacom_report_abs(wcombo, ABS_X,
+ (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8));
+ wacom_report_abs(wcombo, ABS_Y,
+ (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8));
+ wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
+ wacom_report_key(wcombo, wacom->tool[idx], 1);
+ if (idx)
+ wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+ else
+ wacom_report_key(wcombo, BTN_TOUCH, 1);
+}
+
+static void wacom_tpc_touch_out(struct wacom_wac *wacom, void *wcombo, int idx)
+{
+ wacom_report_abs(wcombo, ABS_X, 0);
+ wacom_report_abs(wcombo, ABS_Y, 0);
+ wacom_report_abs(wcombo, ABS_MISC, 0);
+ wacom_report_key(wcombo, wacom->tool[idx], 0);
+ if (idx)
+ wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+ else
+ wacom_report_key(wcombo, BTN_TOUCH, 0);
+ return;
+}
+
static void wacom_tpc_touch_in(struct wacom_wac *wacom, void *wcombo)
{
char *data = wacom->data;
struct urb *urb = ((struct wacom_combo *)wcombo)->urb;
+ 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;
+
if (urb->actual_length != WACOM_PKGLEN_TPC1FG) {
switch (data[0] & 0xff) {
case 6:
@@ -648,80 +678,72 @@ static void wacom_tpc_touch_in(struct wacom_wac *wacom, void *wcombo)
wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6]));
wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6]));
+ wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
+ wacom_report_key(wcombo, wacom->tool[0], 1);
break;
case 13:
+ /* keep this byte to send proper out-prox event */
+ wacom->id[1] = data[1] & 0x03;
+
if (data[1] & 0x01) {
- if (data[1] & 0x02) {
- wacom->tool[1] = BTN_TOOL_TRIPLETAP;
- wacom_report_abs(wcombo, ABS_X, (data[4] & 0xff) | ((data[5] & 0x7f) << 8));
- wacom_report_abs(wcombo, ABS_Y, (data[8] & 0xff) | ((data[9] & 0x7f) << 8));
- wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
- wacom_report_key(wcombo, wacom->tool[1], 1);
- wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
- wacom_input_sync(wcombo); /* sync second finger data */
- }
- wacom_report_abs(wcombo, ABS_X, (data[2] & 0xff) | ((data[3] & 0x7f) << 8));
- wacom_report_abs(wcombo, ABS_Y, (data[6] & 0xff) | ((data[7] & 0x7f) << 8));
+ wacom_tpc_finger_in(wacom, wcombo, data, 0);
+ firstFinger = 1;
+ } else if (firstFinger) {
+ wacom_tpc_touch_out(wacom, wcombo, 0);
+ }
+
+ if (data[1] & 0x02) {
+ /* sync first finger data */
+ if (firstFinger)
+ wacom_input_sync(wcombo);
+
+ wacom_tpc_finger_in(wacom, wcombo, data, 1);
+ secondFinger = 1;
+ } else if (secondFinger) {
+ /* sync first finger data */
+ if (firstFinger)
+ wacom_input_sync(wcombo);
+
+ wacom_tpc_touch_out(wacom, wcombo, 1);
+ secondFinger = 0;
}
- wacom_report_key(wcombo, BTN_TOUCH, 1);
+ if (!(data[1] & 0x01))
+ firstFinger = 0;
break;
}
} else {
wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1]));
wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3]));
wacom_report_key(wcombo, BTN_TOUCH, 1);
+ wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
+ wacom_report_key(wcombo, wacom->tool[0], 1);
}
- wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
- wacom_report_key(wcombo, wacom->tool[0], 1);
-
- return;
-}
-
-static void wacom_tpc_touch_out(struct wacom_wac *wacom, void *wcombo)
-{
- wacom_report_abs(wcombo, ABS_X, 0);
- wacom_report_abs(wcombo, ABS_Y, 0);
- wacom_report_abs(wcombo, ABS_MISC, 0);
- wacom_report_key(wcombo, wacom->tool[0], 0);
- wacom_report_key(wcombo, BTN_TOUCH, 0);
return;
}
static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
{
char *data = wacom->data;
- int prox = 0, pressure;
+ int prox = 0, pressure, idx = -1;
static int stylusInProx, touchInProx = 1, touchOut;
struct urb *urb = ((struct wacom_combo *)wcombo)->urb;
- static int secondFingerIn = 0;
dbg("wacom_tpc_irq: received report #%d", data[0]);
if (urb->actual_length == WACOM_PKGLEN_TPC1FG || ((data[0] & 0xff) == 6) /* single touch */
|| (data[0] & 0xff) == 13 ) { /* 2FG touch */
if (urb->actual_length == WACOM_PKGLEN_TPC1FG) { /* with touch */
- prox = data[0] & 0x03;
+ prox = data[0] & 0x01;
} else { /* with capacity */
- if ((data[0] & 0xff) == 6) /* single touch */
+ if ((data[0] & 0xff) == 6)
+ /* single touch */
prox = data[1] & 0x01;
- else /* 2FG touch data */
+ else
+ /* 2FG touch data */
prox = data[1] & 0x03;
}
if (!stylusInProx) { /* stylus not in prox */
- if ((data[0] & 0xff) == 13) {
- if (data[1] & 0x02)
- secondFingerIn = 1;
- else if (secondFingerIn == 1) {
- wacom_report_abs(wcombo, ABS_X, 0);
- wacom_report_abs(wcombo, ABS_Y, 0);
- wacom_report_abs(wcombo, ABS_MISC, 0);
- wacom_report_key(wcombo, wacom->tool[1], 0);
- wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
- wacom_input_sync(wcombo); /* sync second finger data */
- secondFingerIn = 0;
- }
- }
if (prox) {
if (touchInProx) {
wacom_tpc_touch_in(wacom, wcombo);
@@ -729,13 +751,26 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
return 1;
}
} else {
- wacom_tpc_touch_out(wacom, wcombo);
+ /* 2FGT out-prox */
+ if ((data[0] & 0xff) == 13) {
+ idx = (wacom->id[1] & 0x01) - 1;
+ if (idx == 0) {
+ wacom_tpc_touch_out(wacom, wcombo, idx);
+ /* sync first finger event */
+ if (wacom->id[1] & 0x02)
+ wacom_input_sync(wcombo);
+ }
+ idx = (wacom->id[1] & 0x02) - 1;
+ if (idx == 1)
+ wacom_tpc_touch_out(wacom, wcombo, idx);
+ } else /* one finger touch */
+ wacom_tpc_touch_out(wacom, wcombo, 0);
touchOut = 0;
touchInProx = 1;
return 1;
}
} else if (touchOut || !prox) { /* force touch out-prox */
- wacom_tpc_touch_out(wacom, wcombo);
+ wacom_tpc_touch_out(wacom, wcombo, 0);
touchOut = 0;
touchInProx = 1;
return 1;
@@ -745,38 +780,14 @@ static 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->id[1]) {
- /* Going into proximity select tool */
- wacom->tool[0] = (data[1] & 0x08) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+ 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[0] == 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[0], 0);
- wacom_input_sync(wcombo);
-
- /* set new tool */
- wacom->tool[0] = 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[0] = 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);
@@ -786,7 +797,7 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
if (pressure < 0)
pressure = wacom->features->pressure_max + pressure + 1;
wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
- wacom_report_key(wcombo, BTN_TOUCH, pressure);
+ wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
} else {
wacom_report_abs(wcombo, ABS_X, 0);
wacom_report_abs(wcombo, ABS_Y, 0);
@@ -794,12 +805,13 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_key(wcombo, BTN_STYLUS, 0);
wacom_report_key(wcombo, BTN_STYLUS2, 0);
wacom_report_key(wcombo, BTN_TOUCH, 0);
- touchInProx = 1; /* pen is out so touch can be enabled now */
+ wacom->id[0] = 0;
+ /* pen is out so touch can be enabled now */
+ touchInProx = 1;
}
wacom_report_key(wcombo, wacom->tool[0], prox);
wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
stylusInProx = prox;
- wacom->id[1] = prox; /* use the prox info to distinguish up-side switch from eraser */
return 1;
}
return 0;
@@ -817,7 +829,6 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
case WACOM_G4:
case GRAPHIRE:
case WACOM_MO:
- case WACOM_GB:
return wacom_graphire_irq(wacom_wac, wcombo);
case PTU:
@@ -851,7 +862,6 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w
case WACOM_MO:
input_dev_mo(input_dev, wacom_wac);
case WACOM_G4:
- case WACOM_GB:
input_dev_g4(input_dev, wacom_wac);
/* fall through */
case GRAPHIRE:
@@ -883,6 +893,9 @@ 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)
+ break; /* no need to process stylus stuff */
+
/* fall through */
case PL:
case PTU:
@@ -952,7 +965,6 @@ static struct wacom_features wacom_features[] = {
{ "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 Graphire Bluetooth", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, WACOM_GB },
{ "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 },
@@ -1020,7 +1032,6 @@ static struct usb_device_id wacom_ids[] = {
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC7) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x81) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) },
diff --git a/src/2.6.28/wacom_wac.h b/src/2.6.28/wacom_wac.h
index 7d207fd..37e0eb3 100755
--- a/src/2.6.28/wacom_wac.h
+++ b/src/2.6.28/wacom_wac.h
@@ -37,7 +37,6 @@ enum {
WACOM_MO,
TABLETPC,
TABLETPC2FG,
- WACOM_GB,
MAX_TYPE
};
@@ -49,10 +48,9 @@ struct wacom_features {
int pressure_max;
int distance_max;
int type;
- int touch_x_res;
- int touch_y_res;
- int touch_x_max;
- int touch_y_max;
+ int device_type;
+ int x_phy;
+ int y_phy;
unsigned char unit;
unsigned char unitExpo;
};
diff --git a/src/include/xdrv-config.h.in b/src/include/xdrv-config.h.in
index fade638..165d960 100644
--- a/src/include/xdrv-config.h.in
+++ b/src/include/xdrv-config.h.in
@@ -35,6 +35,9 @@
/* Xserver versions 1.4 and later call Uninit before closing a device. */
#undef WCM_XORG_XSERVER_1_4
+/* Xserver versions earlier than 1.5.2 call Uninit before closing a device. */
+#undef WCM_XORG_XSERVER_1_5_2
+
/* Xserver versions 1.6 and later changed a few interfaces. */
#undef WCM_XORG_XSERVER_1_6
diff --git a/src/util/wacomcfg.c b/src/util/wacomcfg.c
index f9eb7cd..7da42cc 100755
--- a/src/util/wacomcfg.c
+++ b/src/util/wacomcfg.c
@@ -281,8 +281,8 @@ WACOMDEVICETYPE mapStringToType (const char* name)
return WACOMDEVICETYPE_TOUCH;
else if (strstr(name,"pad") != NULL)
return WACOMDEVICETYPE_PAD;
- else
- return WACOMDEVICETYPE_UNKNOWN;
+ else /* HAL eliminated stylus in the name for stylus */
+ return WACOMDEVICETYPE_STYLUS;
}
diff --git a/src/util/xsetwacom.c b/src/util/xsetwacom.c
index cbb06cc..de9c5b3 100755
--- a/src/util/xsetwacom.c
+++ b/src/util/xsetwacom.c
@@ -109,11 +109,11 @@ struct _PARAMINFO
static const char* tv_char[] =
{
"none",
- "xinerama"
+ "xinerama",
"vertical",
"horizontal",
- "aboveof"
- "leftof"
+ "aboveof",
+ "leftof",
"NULL"
};
@@ -692,7 +692,7 @@ static int ListDev(WACOMCONFIG *hConfig, char** argv)
const char* pszType;
WACOMDEVICEINFO* pInfo;
unsigned int i, j, uCount;
- char nameOut[60];
+ char nameOut[60] = "";
static TYPEXLAT xTypes[] =
{
@@ -712,13 +712,14 @@ static int ListDev(WACOMCONFIG *hConfig, char** argv)
for (i=0; i<uCount; ++i)
{
pszType = "unknown";
+ nameOut[0] = 0; /* end of string */
for (j=0; j<sizeof(xTypes)/sizeof(*xTypes); ++j)
if (xTypes[j].type == pInfo[i].type)
pszType = xTypes[j].pszText;
/* tcl/tk (wacomcpl) has problem to process spaced names
- * so we make the name into one string */
- for(j=0; j<strlen(pInfo[i].pszName); j++)
+ * so we make them into the one string */
+ for (j=0; j<strlen(pInfo[i].pszName); j++)
{
if(pInfo[i].pszName[j] == ' ')
nameOut[j] = '_';
@@ -898,11 +899,14 @@ static int ParseValues(int nCount, const char* pszValues, int* nValues,
if (p->nParamID == XWACOM_PARAM_TWINVIEW)
option_char = tv_char;
for (j = p->nMin; j <= p->nMax; j++)
+ {
if (!strcasecmp(pszValues, option_char[j]))
{
check = 1;
*nValue = j;
+ break;
}
+ }
if (!check)
{
fprintf(stderr,"ParseValues: Value '%s' is "
diff --git a/src/xdrv/Makefile.am b/src/xdrv/Makefile.am
index 0d451b1..4ed4291 100755
--- a/src/xdrv/Makefile.am
+++ b/src/xdrv/Makefile.am
@@ -12,7 +12,9 @@ EXTRA_DIST = xf86Wacom.c wcmXCommand.c xf86Wacom.h \
wcmSerial.c wcmISDV4.c wcmUSB.c \
wcmCommon.c wcmCompat.c wcmConfig.c \
wcmFilter.c wcmFilter.h wcmSerial.h \
- ../include/Xwacom.h wcmTilt2Rotation.c
+ ../include/Xwacom.h wcmTilt2Rotation.c \
+ wcmTouchFilter.c wcmValidateDevice.c \
+ wcmMapping.c
if WCM_ENV_XORGSDK
DRIVER_INCLUDES = -I../include -I$(WCM_XORGSDK_DIR) $(X_CFLAGS) @XORG_CFLAGS@
@@ -42,8 +44,8 @@ endif
XF86OBJS = xf86Wacom.o wcmSerial.o wcmUSB.o wcmISDV4.o \
wcmXCommand.o wcmCommon.o wcmCompat.o wcmConfig.o \
- wcmFilter.o wcmTilt2Rotation.o
-
+ wcmFilter.o wcmTilt2Rotation.o wcmTouchFilter.o \
+ wcmValidateDevice.o wcmMapping.o
$(XF86OBJS):
$(CC) $(CFLAGS) $(WCM_DEPFLAGS) $(DLLOADER) -pipe $(WCM_CLEVEL) \
-pedantic -Wall -Wpointer-arith $(NO_MERGE_CONSTANTS) \
diff --git a/src/xdrv/wcmCommon.c b/src/xdrv/wcmCommon.c
index 7f6fb86..696e4f9 100755
--- a/src/xdrv/wcmCommon.c
+++ b/src/xdrv/wcmCommon.c
@@ -44,9 +44,9 @@ WacomDeviceClass* wcmDeviceClasses[] =
extern int xf86WcmDevSwitchModeCall(LocalDevicePtr local, int mode);
extern void xf86WcmChangeScreen(LocalDevicePtr local, int value);
-extern void xf86WcmInitialCoordinates(LocalDevicePtr local, int axes);
-extern void xf86WcmVirtaulTabletSize(LocalDevicePtr local);
extern void xf86WcmTilt2R(WacomDeviceStatePtr ds);
+extern void xf86WcmFingerTapToClick(WacomCommonPtr common);
+extern void xf86WcmSetScreen(LocalDevicePtr local, int v0, int v1);
/*****************************************************************************
* Static functions
@@ -60,192 +60,6 @@ static void sendAButton(LocalDevicePtr local, int button, int mask,
int rx, int ry, int rz, int v3, int v4, int v5);
/*****************************************************************************
- * xf86WcmMappingFactor --
- * calculate the proper tablet to screen mapping factor according to the
- * screen/desktop size and the tablet size
- ****************************************************************************/
-
-void xf86WcmMappingFactor(LocalDevicePtr local)
-{
- WacomDevicePtr priv = (WacomDevicePtr) local->private;
- int screenX, screenY;
-
- DBG(10, priv->debugLevel, ErrorF("xf86WcmMappingFactor \n"));
-
- xf86WcmVirtaulTabletSize(local);
-
- if (!(priv->flags & ABSOLUTE_FLAG) || !priv->wcmMMonitor)
- {
- /* Get the current screen that the cursor is in */
-#if WCM_XINPUTABI_MAJOR == 0
- if (miPointerCurrentScreen())
- priv->currentScreen = miPointerCurrentScreen()->myNum;
-#else
- if (miPointerGetScreen(local->dev))
- priv->currentScreen = miPointerGetScreen(local->dev)->myNum;
-#endif
- }
- else
- {
- if (priv->screen_no != -1)
- priv->currentScreen = priv->screen_no;
- else if (priv->currentScreen == -1)
- {
- /* Get the current screen that the cursor is in */
-#if WCM_XINPUTABI_MAJOR == 0
- if (miPointerCurrentScreen())
- priv->currentScreen = miPointerCurrentScreen()->myNum;
-#else
- if (miPointerGetScreen(local->dev))
- priv->currentScreen = miPointerGetScreen(local->dev)->myNum;
-#endif
- }
- }
- if (priv->currentScreen == -1) /* tool on the tablet */
- priv->currentScreen = 0;
-
- screenX = priv->maxWidth;
- screenY = priv->maxHeight;
- if (priv->screen_no != -1 || (priv->twinview > TV_XINERAMA) || (!priv->wcmMMonitor) )
- {
- screenX = priv->screenBottomX[priv->currentScreen] - priv->screenTopX[priv->currentScreen];
- screenY = priv->screenBottomY[priv->currentScreen] - priv->screenTopY[priv->currentScreen];
- }
- DBG(10, priv->debugLevel, ErrorF("xf86WcmMappingFactor"
- " Active tablet area x=%d y=%d (virtual tablet area x=%d y=%d) map"
- " to maxWidth =%d maxHeight =%d\n",
- priv->bottomX, priv->bottomY, priv->sizeX, priv->sizeY,
- screenX, screenY));
-
- priv->factorX = (double)screenX / (double)priv->sizeX;
- priv->factorY = (double)screenY / (double)priv->sizeY;
- DBG(2, priv->debugLevel, ErrorF("X factor = %.3g, Y factor = %.3g\n",
- priv->factorX, priv->factorY));
-}
-
-/*****************************************************************************
- * xf86WcmSetScreen --
- * set to the proper screen according to the converted (x,y).
- * this only supports for horizontal setup now.
- * need to know screen's origin (x,y) to support
- * combined horizontal and vertical setups
- ****************************************************************************/
-
-static void xf86WcmSetScreen(LocalDevicePtr local, int v0, int v1)
-{
- WacomDevicePtr priv = (WacomDevicePtr) local->private;
- int screenToSet = -1, i, j, x, y, tabletSize = 0;
-
- DBG(6, priv->debugLevel, ErrorF("xf86WcmSetScreen v0=%d v1=%d "
- "currentScreen=%d\n", v0, v1, priv->currentScreen));
-
- if (priv->screen_no != -1 && priv->screen_no >= priv->numScreen)
- {
- ErrorF("xf86WcmSetScreen Screen%d is larger than number of available screens (%d)\n",
- priv->screen_no, priv->numScreen);
- priv->screen_no = -1;
- }
-
- if (!(local->flags & (XI86_ALWAYS_CORE | XI86_CORE_POINTER))) return;
-
- if (priv->twinview > TV_XINERAMA && priv->screen_no == -1 && (priv->flags & ABSOLUTE_FLAG))
- {
- if (priv->twinview == TV_LEFT_RIGHT)
- {
- tabletSize = priv->bottomX - priv->tvoffsetX;
- if (v0 > tabletSize && v0 <= priv->bottomX)
- priv->currentScreen = 1;
- if (v0 > priv->topX && v0 <= priv->topX + priv->tvoffsetX)
- priv->currentScreen = 0;
- }
- if (priv->twinview == TV_ABOVE_BELOW)
- {
- tabletSize = priv->bottomY - priv->tvoffsetY;
- if (v0 > tabletSize && v0 <= priv->bottomY)
- priv->currentScreen = 1;
- if (v0 > priv->topY && v0 <= priv->topY + priv->tvoffsetY)
- priv->currentScreen = 0;
- }
- if (priv->twinview == TV_RIGHT_LEFT)
- {
- tabletSize = priv->bottomX - priv->tvoffsetX;
- if (v0 > tabletSize && v0 <= priv->bottomX)
- priv->currentScreen = 0;
- if (v0 > priv->topX && v0 <= priv->topX + priv->tvoffsetX)
- priv->currentScreen = 1;
- }
- if (priv->twinview == TV_BELOW_ABOVE)
- {
- tabletSize = priv->bottomY - priv->tvoffsetY;
- if (v0 > tabletSize && v0 <= priv->bottomY)
- priv->currentScreen = 0;
- if (v0 > priv->topY && v0 <= priv->topY + priv->tvoffsetY)
- priv->currentScreen = 1;
- }
- DBG(10, priv->debugLevel, ErrorF("xf86WcmSetScreen TwinView setup screenToSet=%d\n",
- priv->currentScreen));
- }
-
- xf86WcmMappingFactor(local);
- if (!(priv->flags & ABSOLUTE_FLAG) || screenInfo.numScreens == 1 || !priv->wcmMMonitor)
- return;
-
- v0 = v0 - priv->topX;
- v1 = v1 - priv->topY;
-
- if (priv->screen_no == -1)
- {
- for (i = 0; i < priv->numScreen; i++)
- {
- if (v0 * priv->factorX >= priv->screenTopX[i] &&
- v0 * priv->factorX < priv->screenBottomX[i] - 0.5)
- {
-
- for (j = 0; j < priv->numScreen; j++)
- {
- if (v1 * priv->factorY >= priv->screenTopY[j] &&
- v1 * priv->factorY <= priv->screenBottomY[j] - 0.5)
- {
- if (j == i)
- {
- screenToSet = i;
- break;
- }
- }
- }
-
- if (screenToSet != -1)
- break;
- }
- }
- }
- else
- screenToSet = priv->screen_no;
-
- if (screenToSet == -1)
- {
- DBG(3, priv->debugLevel, ErrorF("xf86WcmSetScreen Error: "
- "Can not find valid screen (currentScreen=%d)\n",
- priv->currentScreen));
- return;
- }
-
- priv->currentScreen = screenToSet;
- xf86WcmMappingFactor(local);
- x = ((double)v0 * priv->factorX) - priv->screenTopX[screenToSet] + 0.5;
- y = ((double)v1 * priv->factorY) - priv->screenTopY[screenToSet] + 0.5;
-
- if (x >= screenInfo.screens[screenToSet]->width)
- x = screenInfo.screens[screenToSet]->width - 1;
- if (y >= screenInfo.screens[screenToSet]->height)
- y = screenInfo.screens[screenToSet]->height - 1;
-
- xf86XInputSetScreen(local, screenToSet, x, y);
- DBG(10, priv->debugLevel, ErrorF("xf86WcmSetScreen current=%d ToSet=%d\n",
- priv->currentScreen, screenToSet));
-}
-
-/*****************************************************************************
* xf86WcmSendButtons --
* Send button events by comparing the current button mask with the
* previous one.
@@ -395,7 +209,7 @@ static int ODDKEYSYM [][2] =
{ 0, 0}
};
-static void emitKeysym (DeviceIntPtr keydev, int keysym, int state)
+void emitKeysym (DeviceIntPtr keydev, int keysym, int state)
{
int i, j, alt_keysym = 0;
@@ -552,7 +366,9 @@ static void sendAButton(LocalDevicePtr local, int button, int mask,
case AC_DISPLAYTOGGLE:
if (mask && priv->numScreen > 1)
{
- if (IsPad(priv)) /* toggle display (individual screens plus the whole desktop) for all tools except pad */
+ /* toggle display (individual screens plus the whole desktop)
+ * for all tools except pad */
+ if (IsPad(priv))
{
WacomDevicePtr tmppriv;
for (tmppriv = common->wcmDevices; tmppriv; tmppriv = tmppriv->next)
@@ -566,7 +382,7 @@ static void sendAButton(LocalDevicePtr local, int button, int mask,
}
}
}
- else /* toggle display (individual screens plus the whole desktop) only for the selected tool */
+ else
{
int screen = priv->screen_no;
if (++screen >= priv->numScreen)
@@ -579,7 +395,8 @@ static void sendAButton(LocalDevicePtr local, int button, int mask,
case AC_SCREENTOGGLE:
if (mask && priv->numScreen > 1)
{
- if (IsPad(priv)) /* toggle screens for all tools except pad */
+ /* toggle screens for all tools except pad */
+ if (IsPad(priv))
{
WacomDevicePtr tmppriv;
for (tmppriv = common->wcmDevices; tmppriv; tmppriv = tmppriv->next)
@@ -804,6 +621,33 @@ static void sendCommonEvents(LocalDevicePtr local, const WacomDeviceState* ds, i
sendWheelStripEvents(local, ds, x, y, z, v3, v4, v5);
}
+/* rotate the raw coordinates */
+void xf86WcmRotateCoordinates(LocalDevicePtr local, int x, int y)
+{
+ WacomDevicePtr priv = (WacomDevicePtr) local->private;
+ WacomCommonPtr common = priv->common;
+ int tmp_coord;
+
+ /* rotation mixes x and y up a bit */
+ if (common->wcmRotate == ROTATE_CW)
+ {
+ tmp_coord = x;
+ x = y;
+ y = common->wcmMaxY - tmp_coord;
+ }
+ else if (common->wcmRotate == ROTATE_CCW)
+ {
+ tmp_coord = y;
+ y = x;
+ x = common->wcmMaxX - tmp_coord;
+ }
+ else if (common->wcmRotate == ROTATE_HALF)
+ {
+ x = common->wcmMaxX - x;
+ y = common->wcmMaxY - y;
+ }
+}
+
/*****************************************************************************
* xf86WcmSendEvents --
* Send events according to the device state.
@@ -825,9 +669,7 @@ void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds)
int rot = ds->rotation;
int throttle = ds->throttle;
int wheel = ds->abswheel;
- int tmp_coord;
WacomDevicePtr priv = (WacomDevicePtr) local->private;
- WacomCommonPtr common = priv->common;
int naxes = priv->naxes;
int is_absolute = priv->flags & ABSOLUTE_FLAG;
int v3, v4, v5;
@@ -866,24 +708,7 @@ void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds)
x, y, z, is_button ? "true" : "false", buttons,
tx, ty, wheel, rot, throttle));
- /* rotation mixes x and y up a bit */
- if (common->wcmRotate == ROTATE_CW)
- {
- tmp_coord = x;
- x = y;
- y = priv->wcmMaxY - tmp_coord;
- }
- else if (common->wcmRotate == ROTATE_CCW)
- {
- tmp_coord = y;
- y = x;
- x = priv->wcmMaxX - tmp_coord;
- }
- else if (common->wcmRotate == ROTATE_HALF)
- {
- x = priv->wcmMaxX - x;
- y = priv->wcmMaxY - y;
- }
+ xf86WcmRotateCoordinates(local, x, y);
if (IsCursor(priv))
{
@@ -1261,9 +1086,6 @@ void xf86WcmEvent(WacomCommonPtr common, unsigned int channel,
* will need to change the values (ie. for error correction) */
ds = *pState;
- /* timestamp to track the last event sent */
- ds.sample = (int)GetTimeInMillis();
-
DBG(10, common->debugLevel, ErrorF("xf86WcmEvent: "
"c=%d i=%d t=%d s=%u x=%d y=%d b=%d "
"p=%d rz=%d tx=%d ty=%d aw=%d rw=%d "
@@ -1336,17 +1158,13 @@ void xf86WcmEvent(WacomCommonPtr common, unsigned int channel,
{
DBG(10, common->debugLevel, ErrorF(
"Raw filtering discarded data.\n"));
- resetSampleCounter(pChannel);
- return; /* discard */
+ goto ret; /* discard */
}
}
/* Discard unwanted data */
suppress = xf86WcmSuppress(common, pLast, &ds);
if (!suppress)
- {
- resetSampleCounter(pChannel);
- return;
- }
+ goto ret;
}
/* JEJ - Do not move this code without discussing it with me.
@@ -1359,10 +1177,52 @@ void xf86WcmEvent(WacomCommonPtr common, unsigned int channel,
memmove(pChannel->valid.states + 1,
pChannel->valid.states,
sizeof(WacomDeviceState) * (common->wcmRawSample - 1));
- pChannel->valid.state = ds; /*save last raw sample */
+ pChannel->valid.state = ds; /* save last raw sample */
if (pChannel->nSamples < common->wcmRawSample) ++pChannel->nSamples;
+
+ /* process second finger data if exists */
+ if (ds.device_type == TOUCH_ID)
+ {
+ 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)
+ {
+ 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->wcmTouch &&
+ common->wcmGesture && common->wcmGestureMode)
+ goto ret;
+
+ /* process gesture when both touch and geature are enabled */
+ if (channel && common->wcmTouch && common->wcmGesture)
+ {
+ xf86WcmFingerTapToClick(common);
+ goto ret;
+ }
+ }
+ }
+ /* everything else falls here */
commonDispatchDevice(common,channel,pChannel, suppress);
+ret:
resetSampleCounter(pChannel);
}
@@ -1504,12 +1364,7 @@ static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel,
if (tool->current)
{
/* Send soft prox-out for the old area */
- LocalDevicePtr oDev = outprox->device;
- WacomDeviceState out = { 0 };
- out.device_type = DEVICE_ID(((WacomDevicePtr)(oDev->private))->flags);
- DBG(2, common->debugLevel, ErrorF("Soft prox-out for %s\n",
- outprox->device->name));
- xf86WcmSendEvents(oDev, &out);
+ xf86WcmSoftOutEvent(outprox->device);
}
else
tool->current = outprox;
@@ -1571,6 +1426,9 @@ static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel,
/* Lookup to see if associated touch was enabled */
for (; localDevices != NULL; localDevices = localDevices->next)
{
+ /* we need to go through all enabled Wacom devices
+ * since USB pen and touch don't share the same logical port
+ */
if (strstr(localDevices->drv->driverName, "wacom"))
{
temppriv = (WacomDevicePtr) localDevices->private;
@@ -1582,12 +1440,7 @@ static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel,
IsTouch(temppriv) && temppriv->oldProximity)
{
/* Send soft prox-out for touch first */
- WacomDeviceState out = { 0 };
- out.device_type = DEVICE_ID(temppriv->flags);
- DBG(2, common->debugLevel, ErrorF(
- "Send soft prox-out for %s first\n",
- localDevices->name));
- xf86WcmSendEvents(localDevices, &out);
+ xf86WcmSoftOutEvent(localDevices);
}
}
}
@@ -1772,90 +1625,30 @@ static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel,
}
}
-/*****************************************************************************
- * xf86WcmInitTablet -- common initialization for all tablets
- ****************************************************************************/
-
-int xf86WcmInitTablet(LocalDevicePtr local, const char* id, float version)
+void xf86WcmSoftOutEvent(LocalDevicePtr local)
{
- WacomDevicePtr priv = (WacomDevicePtr)local->private;
+ /* Send a soft prox-out event for the device */
+ WacomDeviceState out = { 0 };
+ WacomDevicePtr priv = (WacomDevicePtr) local->private;
WacomCommonPtr common = priv->common;
- WacomModelPtr model = common->wcmModel;
-
- /* Initialize the tablet */
- model->Initialize(common,id,version);
-
- /* Get tablet resolution */
- if (model->GetResolution)
- model->GetResolution(local);
-
- /* Get tablet range */
- if (model->GetRanges && (model->GetRanges(local) != Success))
- return !Success;
-
- /* Default threshold value if not set */
- if (common->wcmThreshold <= 0)
- {
- /* Threshold for counting pressure as a button */
- if (strstr(common->wcmModel->name, "Intuos4"))
- common->wcmThreshold = common->wcmMaxZ * 3 / 25;
- else
- common->wcmThreshold = common->wcmMaxZ * 3 / 50;
- ErrorF("%s Wacom using pressure threshold of %d for button 1\n",
- XCONFIG_PROBED, common->wcmThreshold);
- }
-
- /* Reset tablet to known state */
- if (model->Reset && (model->Reset(local) != Success))
- {
- ErrorF("Wacom xf86WcmWrite error : %s\n", strerror(errno));
- return !Success;
- }
- /* Enable tilt mode, if requested and available */
- if ((common->wcmFlags & TILT_REQUEST_FLAG) && model->EnableTilt)
- {
- if (model->EnableTilt(local) != Success)
- return !Success;
- }
-
- /* Enable hardware suppress, if requested and available */
- if (model->EnableSuppress)
- {
- if (model->EnableSuppress(local) != Success)
- return !Success;
- }
-
- /* change the serial speed, if requested */
- if (model->SetLinkSpeed)
- {
- if (common->wcmLinkSpeed != 9600)
- {
- if (model->SetLinkSpeed(local) != Success)
- return !Success;
- }
- }
- else
- {
- DBG(2, common->debugLevel, ErrorF("Tablet does not support setting link "
- "speed, or not yet implemented\n"));
- }
-
- /* output tablet state as probed */
- if (xf86Verbose)
- ErrorF("%s Wacom %s tablet speed=%d (%d) maxX=%d maxY=%d maxZ=%d "
- "resX=%d resY=%d tilt=%s\n",
- XCONFIG_PROBED,
- model->name, common->wcmLinkSpeed, common->wcmISDV4Speed,
- common->wcmMaxX, common->wcmMaxY, common->wcmMaxZ,
- common->wcmResolX, common->wcmResolY,
- HANDLE_TILT(common) ? "enabled" : "disabled");
-
- /* start the tablet data */
- if (model->Start && (model->Start(local) != Success))
- return !Success;
+ out.device_type = DEVICE_ID(priv->flags);
+ DBG(2, common->debugLevel, ErrorF("Send soft prox-out for"
+ " %s first\n", local->name));
+ xf86WcmSendEvents(local, &out);
+}
- return Success;
+void xf86WcmSoftOut(WacomCommonPtr common, int channel)
+{
+ /* Send a soft prox-out for the device */
+ WacomDeviceState out = { 0 };
+ WacomChannelPtr pChannel = common->wcmChannel + channel;
+ WacomDeviceState ds = pChannel->valid.state;
+
+ out.device_type = ds.device_type;
+ DBG(2, common->debugLevel, ErrorF("Send soft prox-out for"
+ " %s at channel %d \n", common->wcmModel->name, channel));
+ xf86WcmEvent(common, channel, &out);
}
/*****************************************************************************
@@ -1884,308 +1677,3 @@ static void transPressureCurve(WacomDevicePtr pDev, WacomDeviceStatePtr pState)
}
}
-/*****************************************************************************
- * xf86WcmInitialTVScreens
- ****************************************************************************/
-
-static void xf86WcmInitialTVScreens(LocalDevicePtr local)
-{
- WacomDevicePtr priv = (WacomDevicePtr)local->private;
-
- if (priv->twinview <= TV_XINERAMA)
- return;
-
- priv->numScreen = 2;
-
- if ((priv->twinview == TV_LEFT_RIGHT) || (priv->twinview == TV_RIGHT_LEFT))
- {
- /* it does not need the offset if always map to a specific screen */
- if (priv->screen_no == -1)
- {
- priv->tvoffsetX = 60;
- priv->tvoffsetY = 0;
- }
-
- /* default resolution */
- if(!priv->tvResolution[0])
- {
- priv->tvResolution[0] = screenInfo.screens[0]->width/2;
- priv->tvResolution[1] = screenInfo.screens[0]->height;
- priv->tvResolution[2] = priv->tvResolution[0];
- priv->tvResolution[3] = priv->tvResolution[1];
- }
- }
- else if ((priv->twinview == TV_ABOVE_BELOW) || (priv->twinview == TV_BELOW_ABOVE))
- {
- /* it does not need the offset if always map to a specific screen */
- if (priv->screen_no == -1)
- {
- priv->tvoffsetX = 0;
- priv->tvoffsetY = 60;
- }
-
- /* default resolution */
- if(!priv->tvResolution[0])
- {
- priv->tvResolution[0] = screenInfo.screens[0]->width;
- priv->tvResolution[1] = screenInfo.screens[0]->height/2;
- priv->tvResolution[2] = priv->tvResolution[0];
- priv->tvResolution[3] = priv->tvResolution[1];
- }
- }
-
- /* initial screen info */
- if (priv->twinview == TV_ABOVE_BELOW)
- {
- priv->screenTopX[0] = 0;
- priv->screenTopY[0] = 0;
- priv->screenBottomX[0] = priv->tvResolution[0];
- priv->screenBottomY[0] = priv->tvResolution[1];
- priv->screenTopX[1] = 0;
- priv->screenTopY[1] = priv->tvResolution[1];
- priv->screenBottomX[1] = priv->tvResolution[2];
- priv->screenBottomY[1] = priv->tvResolution[1] + priv->tvResolution[3];
- }
- if (priv->twinview == TV_LEFT_RIGHT)
- {
- priv->screenTopX[0] = 0;
- priv->screenTopY[0] = 0;
- priv->screenBottomX[0] = priv->tvResolution[0];
- priv->screenBottomY[0] = priv->tvResolution[1];
- priv->screenTopX[1] = priv->tvResolution[0];
- priv->screenTopY[1] = 0;
- priv->screenBottomX[1] = priv->tvResolution[0] + priv->tvResolution[2];
- priv->screenBottomY[1] = priv->tvResolution[3];
- }
- if (priv->twinview == TV_BELOW_ABOVE)
- {
- priv->screenTopX[0] = 0;
- priv->screenTopY[0] = priv->tvResolution[1];
- priv->screenBottomX[0] = priv->tvResolution[2];
- priv->screenBottomY[0] = priv->tvResolution[1] + priv->tvResolution[3];
- priv->screenTopX[1] = 0;
- priv->screenTopY[1] = 0;
- priv->screenBottomX[1] = priv->tvResolution[0];
- priv->screenBottomY[1] = priv->tvResolution[1];
- }
- if (priv->twinview == TV_RIGHT_LEFT)
- {
- priv->screenTopX[0] = priv->tvResolution[0];
- priv->screenTopY[0] = 0;
- priv->screenBottomX[0] = priv->tvResolution[0] + priv->tvResolution[2];
- priv->screenBottomY[0] = priv->tvResolution[3];
- priv->screenTopX[1] = 0;
- priv->screenTopY[1] = 0;
- priv->screenBottomX[1] = priv->tvResolution[0];
- priv->screenBottomY[1] = priv->tvResolution[1];
- }
-
- DBG(10, priv->debugLevel, ErrorF("xf86WcmInitialTVScreens for \"%s\" "
- "topX0=%d topY0=%d bottomX0=%d bottomY0=%d "
- "topX1=%d topY1=%d bottomX1=%d bottomY1=%d \n",
- local->name, priv->screenTopX[0], priv->screenTopY[0],
- priv->screenBottomX[0], priv->screenBottomY[0],
- priv->screenTopX[1], priv->screenTopY[1],
- priv->screenBottomX[1], priv->screenBottomY[1]));
-}
-
-/*****************************************************************************
- * xf86WcmInitialScreens
- ****************************************************************************/
-
-void xf86WcmInitialScreens(LocalDevicePtr local)
-{
- WacomDevicePtr priv = (WacomDevicePtr)local->private;
- int i;
-
- DBG(2, priv->debugLevel, ErrorF("xf86WcmInitialScreens for \"%s\" "
- "number of screen=%d \n", local->name, screenInfo.numScreens));
- priv->tvoffsetX = 0;
- priv->tvoffsetY = 0;
- if (priv->twinview > TV_XINERAMA)
- {
- xf86WcmInitialTVScreens(local);
- return;
- }
-
- /* initial screen info */
- priv->numScreen = screenInfo.numScreens;
- priv->screenTopX[0] = 0;
- priv->screenTopY[0] = 0;
- priv->screenBottomX[0] = 0;
- priv->screenBottomY[0] = 0;
- for (i=0; i<screenInfo.numScreens; i++)
- {
-#ifdef WCM_HAVE_DIXSCREENORIGINS
- if (screenInfo.numScreens > 1)
- {
- priv->screenTopX[i] = dixScreenOrigins[i].x;
- priv->screenTopY[i] = dixScreenOrigins[i].y;
- priv->screenBottomX[i] = dixScreenOrigins[i].x;
- priv->screenBottomY[i] = dixScreenOrigins[i].y;
-
- DBG(10, priv->debugLevel, ErrorF("xf86WcmInitialScreens from dix for \"%s\" "
- "ScreenOrigins[%d].x=%d ScreenOrigins[%d].y=%d \n",
- local->name, i, priv->screenTopX[i], i, priv->screenTopY[i]));
- }
-#else /* WCM_HAVE_DIXSCREENORIGINS */
- if (i > 0)
- {
- /* only support left to right in this case */
- priv->screenTopX[i] = priv->screenBottomX[i-1];
- priv->screenTopY[i] = 0;
- priv->screenBottomX[i] = priv->screenTopX[i];
- priv->screenBottomY[i] = 0;
- }
-#endif /* WCM_HAVE_DIXSCREENORIGINS */
- priv->screenBottomX[i] += screenInfo.screens[i]->width;
- priv->screenBottomY[i] += screenInfo.screens[i]->height;
-
- DBG(10, priv->debugLevel, ErrorF("xf86WcmInitialScreens for \"%s\" "
- "topX[%d]=%d topY[%d]=%d bottomX[%d]=%d bottomY[%d]=%d \n",
- local->name, i, priv->screenTopX[i], i, priv->screenTopY[i],
- i, priv->screenBottomX[i], i, priv->screenBottomY[i]));
- }
-}
-
-/*****************************************************************************
- * rotateOneTool
- ****************************************************************************/
-
-static void rotateOneTool(WacomDevicePtr priv)
-{
- WacomCommonPtr common = priv->common;
- WacomToolAreaPtr area = priv->toolarea;
- int tmpTopX, tmpTopY, tmpBottomX, tmpBottomY, oldMaxX, oldMaxY;
-
- DBG(10, priv->debugLevel, ErrorF("rotateOneTool for \"%s\" \n", priv->local->name));
-
- oldMaxX = priv->wcmMaxX;
- oldMaxY = priv->wcmMaxY;
-
- tmpTopX = priv->topX;
- tmpBottomX = priv->bottomX;
- tmpTopY = priv->topY;
- tmpBottomY = priv->bottomY;
-
- if (common->wcmRotate == ROTATE_CW || common->wcmRotate == ROTATE_CCW)
- {
- priv->wcmMaxX = oldMaxY;
- priv->wcmMaxY = oldMaxX;
- }
-
- switch (common->wcmRotate) {
- case ROTATE_CW:
- area->topX = priv->topX = tmpTopY;
- area->bottomX = priv->bottomX = tmpBottomY;
- area->topY = priv->topY = oldMaxX - tmpBottomX;
- area->bottomY = priv->bottomY =oldMaxX - tmpTopX;
- break;
- case ROTATE_CCW:
- area->topX = priv->topX = oldMaxY - tmpBottomY;
- area->bottomX = priv->bottomX = oldMaxY - tmpTopY;
- area->topY = priv->topY = tmpTopX;
- area->bottomY = priv->bottomY = tmpBottomX;
- break;
- case ROTATE_HALF:
- area->topX = priv->topX = oldMaxX - tmpBottomX;
- area->bottomX = priv->bottomX = oldMaxX - tmpTopX;
- area->topY = priv->topY= oldMaxY - tmpBottomY;
- area->bottomY = priv->bottomY = oldMaxY - tmpTopY;
- break;
- }
- xf86WcmInitialCoordinates(priv->local, 0);
- xf86WcmInitialCoordinates(priv->local, 1);
-
- if (tmpTopX != priv->topX)
- xf86ReplaceIntOption(priv->local->options, "TopX", priv->topX);
- if (tmpTopY != priv->topY)
- xf86ReplaceIntOption(priv->local->options, "TopY", priv->topY);
- if (tmpBottomX != priv->bottomX)
- xf86ReplaceIntOption(priv->local->options, "BottomX", priv->bottomX);
- if (tmpBottomY != priv->bottomY)
- xf86ReplaceIntOption(priv->local->options, "BottomY", priv->bottomY);
-}
-
-/*****************************************************************************
- * xf86WcmRotateTablet
- ****************************************************************************/
-
-void xf86WcmRotateTablet(LocalDevicePtr local, int value)
-{
- WacomDevicePtr priv = (WacomDevicePtr)local->private;
- WacomCommonPtr common = priv->common;
- WacomDevicePtr tmppriv;
- int oldRotation;
- int tmpTopX, tmpTopY, tmpBottomX, tmpBottomY, oldMaxX, oldMaxY;
-
- DBG(10, priv->debugLevel, ErrorF("xf86WcmRotateTablet for \"%s\" \n", local->name));
-
- if (common->wcmRotate == value) /* initialization */
- {
- rotateOneTool(priv);
- }
- else
- {
- oldRotation = common->wcmRotate;
- common->wcmRotate = value;
-
- /* rotate all devices at once! else they get misaligned */
- for (tmppriv = common->wcmDevices; tmppriv; tmppriv = tmppriv->next)
- {
- oldMaxX = tmppriv->wcmMaxX;
- oldMaxY = tmppriv->wcmMaxY;
-
- if (oldRotation == ROTATE_CW || oldRotation == ROTATE_CCW)
- {
- tmppriv->wcmMaxX = oldMaxY;
- tmppriv->wcmMaxY = oldMaxX;
- }
-
- tmpTopX = tmppriv->topX;
- tmpBottomX = tmppriv->bottomX;
- tmpTopY = tmppriv->topY;
- tmpBottomY = tmppriv->bottomY;
-
- /* recover to the unrotated xy-rectangles */
- switch (oldRotation) {
- case ROTATE_CW:
- tmppriv->topX = oldMaxY - tmpBottomY;
- tmppriv->bottomX = oldMaxY - tmpTopY;
- tmppriv->topY = tmpTopX;
- tmppriv->bottomY = tmpBottomX;
- break;
- case ROTATE_CCW:
- tmppriv->topX = tmpTopY;
- tmppriv->bottomX = tmpBottomY;
- tmppriv->topY = oldMaxX - tmpBottomX;
- tmppriv->bottomY = oldMaxX - tmpTopX;
- break;
- case ROTATE_HALF:
- tmppriv->topX = oldMaxX - tmpBottomX;
- tmppriv->bottomX = oldMaxX - tmpTopX;
- tmppriv->topY = oldMaxY - tmpBottomY;
- tmppriv->bottomY = oldMaxY - tmpTopY;
- break;
- }
-
- /* and rotate them to the new value */
- rotateOneTool(tmppriv);
-
- switch(value) {
- case ROTATE_NONE:
- xf86ReplaceStrOption(local->options, "Rotate", "NONE");
- break;
- case ROTATE_CW:
- xf86ReplaceStrOption(local->options, "Rotate", "CW");
- break;
- case ROTATE_CCW:
- xf86ReplaceStrOption(local->options, "Rotate", "CCW");
- break;
- case ROTATE_HALF:
- xf86ReplaceStrOption(local->options, "Rotate", "HALF");
- break;
- }
- }
- }
-}
diff --git a/src/xdrv/wcmConfig.c b/src/xdrv/wcmConfig.c
index 4447f24..61a4410 100755
--- a/src/xdrv/wcmConfig.c
+++ b/src/xdrv/wcmConfig.c
@@ -20,11 +20,9 @@
#include "xf86Wacom.h"
#include "wcmFilter.h"
#ifdef WCM_XORG_XSERVER_1_4
- #include <fcntl.h>
- #ifndef _XF86_ANSIC_H
- #include <sys/stat.h>
- #endif
extern Bool xf86WcmIsWacomDevice (char* fname, struct input_id* id);
+ extern Bool wcmIsAValidType(char* device, LocalDevicePtr local, unsigned short id);
+ extern int wcmIsDuplicate(char* device, LocalDevicePtr local);
#endif
/*****************************************************************************
@@ -108,24 +106,20 @@ LocalDevicePtr xf86WcmAllocate(char* name, int flag)
priv->oldTiltY = 0; /* previous tilt in y direction */
priv->oldStripX = 0; /* previous left strip value */
priv->oldStripY = 0; /* previous right strip value */
- priv->oldButtons = 0; /* previous buttons state */
- priv->oldWheel = 0; /* previous wheel */
- priv->topX = 0; /* X top */
- priv->topY = 0; /* Y top */
- priv->bottomX = 0; /* X bottom */
- priv->bottomY = 0; /* Y bottom */
- priv->wcmMaxX = 0; /* max tool logical X value */
- priv->wcmMaxY = 0; /* max tool logical Y value */
- priv->wcmResolX = 0; /* tool X resolution in points/inch */
- priv->wcmResolY = 0; /* tool Y resolution in points/inch */
- priv->sizeX = 0; /* active X size */
- priv->sizeY = 0; /* active Y size */
- priv->factorX = 0.0; /* X factor */
- priv->factorY = 0.0; /* Y factor */
- priv->common = common; /* common info pointer */
- priv->oldProximity = 0; /* previous proximity */
- priv->hardProx = 1; /* previous hardware proximity */
- priv->old_serial = 0; /* last active tool's serial */
+ priv->oldButtons = 0; /* previous buttons state */
+ priv->oldWheel = 0; /* previous wheel */
+ priv->topX = 0; /* X top */
+ priv->topY = 0; /* Y top */
+ priv->bottomX = 0; /* X bottom */
+ priv->bottomY = 0; /* Y bottom */
+ priv->sizeX = 0; /* active X size */
+ priv->sizeY = 0; /* active Y size */
+ priv->factorX = 0.0; /* X factor */
+ priv->factorY = 0.0; /* Y factor */
+ priv->common = common; /* common info pointer */
+ priv->oldProximity = 0; /* previous proximity */
+ priv->hardProx = 1; /* previous hardware proximity */
+ priv->old_serial = 0; /* last active tool's serial */
priv->old_device_id = IsStylus(priv) ? STYLUS_DEVICE_ID :
(IsEraser(priv) ? ERASER_DEVICE_ID :
(IsCursor(priv) ? CURSOR_DEVICE_ID :
@@ -151,15 +145,15 @@ LocalDevicePtr xf86WcmAllocate(char* name, int flag)
priv->keys[i][j] = 0;
priv->nbuttons = MAX_BUTTONS; /* Default number of buttons */
- priv->relup = 5; /* Default relative wheel up event */
- priv->reldn = 4; /* Default relative wheel down event */
+ priv->relup = SCROLL_UP; /* Default relative wheel up event */
+ priv->reldn = SCROLL_DOWN; /* Default relative wheel down event */
- priv->wheelup = IsPad (priv) ? 4 : 0; /* Default absolute wheel up event */
- priv->wheeldn = IsPad (priv) ? 5 : 0; /* Default absolute wheel down event */
- priv->striplup = 4; /* Default left strip up event */
- priv->stripldn = 5; /* Default left strip down event */
- priv->striprup = 4; /* Default right strip up event */
- priv->striprdn = 5; /* Default right strip down event */
+ priv->wheelup = IsPad (priv) ? SCROLL_DOWN : 0; /* Default absolute wheel up event */
+ priv->wheeldn = IsPad (priv) ? SCROLL_UP : 0; /* Default absolute wheel down event */
+ priv->striplup = SCROLL_DOWN; /* Default left strip up event */
+ priv->stripldn = SCROLL_UP; /* Default left strip down event */
+ priv->striprup = SCROLL_DOWN; /* Default right strip up event */
+ priv->striprdn = SCROLL_UP; /* Default right strip down event */
priv->naxes = 6; /* Default number of axes */
priv->debugLevel = 0; /* debug level */
priv->numScreen = screenInfo.numScreens; /* configured screens count */
@@ -182,9 +176,7 @@ LocalDevicePtr xf86WcmAllocate(char* name, int flag)
priv->throttleLimit = -1;
common->wcmDevice = ""; /* device file name */
-#ifdef WCM_XORG_XSERVER_1_6
common->min_maj = 0; /* device major and minor */
-#endif
common->wcmFlags = RAW_FILTERING_FLAG; /* various flags */
common->wcmDevices = priv;
common->npadkeys = 0; /* Default number of pad keys */
@@ -203,23 +195,24 @@ LocalDevicePtr xf86WcmAllocate(char* name, int flag)
common->wcmTPCButtonDefault; /* set Tablet PC button on/off */
common->wcmTouch = 0; /* touch is disabled */
common->wcmTouchDefault = 0; /* default to disable when touch isn't supported */
+ common->wcmGestureMode = 0; /* touch is not in Gesture mode */
common->wcmGesture = 0; /* touch Gesture is disabled */
common->wcmGestureDefault = 0; /* default to disable when touch Gesture isn't supported */
common->wcmCapacity = -1; /* Capacity is disabled */
- common->wcmCapacityDefault = -1; /* default to -1 when capacity isn't supported */
+ common->wcmCapacityDefault = -1; /* default to -1 when capacity isn't supported */
/* 3 when capacity is supported */
common->wcmRotate = ROTATE_NONE; /* default tablet rotation to off */
- common->wcmMaxX = 0; /* max digitizer logical X value */
- common->wcmMaxY = 0; /* max digitizer logical Y value */
- common->wcmMaxTouchX = 1024; /* max touch X value */
- common->wcmMaxTouchY = 1024; /* max touch Y value */
+ common->wcmMaxX = 0; /* max tool logical X value */
+ common->wcmMaxY = 0; /* max tool logical Y value */
common->wcmMaxZ = 0; /* max Z value */
+ common->wcmResolX = 0; /* tool X resolution in
+ * points/inch for penabled
+ * points/mm for touch */
+ common->wcmResolY = 0; /* tool Y resolution in
+ * points/inch for penabled
+ * points/mm for touch */
common->wcmMaxCapacity = 0; /* max capacity value */
common->wcmMaxDist = 0; /* max distance value */
- common->wcmResolX = 0; /* digitizer X resolution in points/inch */
- common->wcmResolY = 0; /* digitizer Y resolution in points/inch */
- common->wcmTouchResolX = 0; /* touch X resolution in points/mm */
- common->wcmTouchResolY = 0; /* touch Y resolution in points/mm */
common->wcmMaxStripX = 4096; /* Max fingerstrip X */
common->wcmMaxStripY = 4096; /* Max fingerstrip Y */
common->wcmMaxtiltX = 128; /* Max tilt in X directory */
@@ -233,6 +226,10 @@ LocalDevicePtr xf86WcmAllocate(char* name, int flag)
/* transmit position if increment is superior */
common->wcmRawSample = DEFAULT_SAMPLES;
/* number of raw data to be used to for filtering */
+#ifdef WCM_ENABLE_LINUXINPUT
+ common->wcmLastToolSerial = 0;
+ common->wcmEventCnt = 0;
+#endif
/* tool */
priv->tool = tool;
@@ -379,9 +376,9 @@ static void xf86WcmUninit(InputDriverPtr drv, LocalDevicePtr local, int flags)
DBG(1, priv->debugLevel, ErrorF("xf86WcmUninit\n"));
- /* Xservers 1.4 and later but earlier than 1.6 need this call */
+ /* Xservers 1.4 and later but earlier than 1.5.2 need this call */
#ifdef WCM_XORG_XSERVER_1_4
- #ifndef WCM_XORG_XSERVER_1_6
+ #ifndef WCM_XORG_XSERVER_1_5_2
gWacomModule.DevProc(local->dev, DEVICE_OFF);
#endif
#endif
@@ -427,6 +424,8 @@ static Bool xf86WcmMatchDevice(LocalDevicePtr pMatch, LocalDevicePtr pLocal)
}
xfree(common);
common = priv->common = privMatch->common;
+
+ /* insert the device to the front of the wcmDevices list */
priv->next = common->wcmDevices;
common->wcmDevices = priv;
return 1;
@@ -434,235 +433,6 @@ static Bool xf86WcmMatchDevice(LocalDevicePtr pMatch, LocalDevicePtr pLocal)
return 0;
}
-#ifdef WCM_XORG_XSERVER_1_4
-
-/* xf86WcmCheckTypeAndSource - Check if both devices have the same type OR
- * the device has been used in xorg.conf: don't add the tool by hal/udev
- * if user has defined at least one tool for the device in xorg.conf */
-
-static Bool xf86WcmCheckTypeAndSource(LocalDevicePtr fakeLocal, LocalDevicePtr pLocal)
-{
- int match = 1;
- char* fsource = xf86CheckStrOption(fakeLocal->options, "_source", "");
- char* psource = xf86CheckStrOption(pLocal->options, "_source", "");
- char* type = xf86FindOptionValue(fakeLocal->options, "Type");
- WacomDevicePtr priv = (WacomDevicePtr) pLocal->private;
-
- /* only add the new tool if the matching major/minor
- * was from the same source */
- if (!strcmp(fsource, psource))
- {
- /* and the tools have different types */
- if (strcmp(type, xf86FindOptionValue(pLocal->options, "Type")))
- match = 0;
- }
- DBG(2, priv->debugLevel, xf86Msg(X_INFO, "xf86WcmCheckTypeAndSource "
- "device %s from %s %s \n", fakeLocal->name, fsource,
- match ? "will be added" : "will be ignored"));
- return match;
-}
-
-/* check if the device has been added */
-static int wcmIsDuplicate(char* device, LocalDevicePtr local)
-{
-#ifdef _XF86_ANSIC_H
- struct xf86stat st;
-#else
- struct stat st;
-#endif
- int isInUse = 0;
- LocalDevicePtr localDevices = NULL;
- WacomCommonPtr common = NULL;
-
- /* open the port */
- do {
- local->fd = open(device, O_RDONLY, 0);
- } while (local->fd < 0 && errno == EINTR);
-
- if (local->fd < 0)
- {
- /* can not open the device */
- xf86Msg(X_ERROR, "Unable to open Wacom device \"%s\".\n", device);
- isInUse = 2;
- goto ret;
- }
-
-#ifdef _XF86_ANSIC_H
- if (xf86fstat(local->fd, &st) == -1)
-#else
- if (fstat(local->fd, &st) == -1)
-#endif
- {
- /* can not access major/minor to check device duplication */
- xf86Msg(X_ERROR, "%s: stat failed (%s). cannot check for duplicates.\n",
- local->name, strerror(errno));
-
- /* older systems don't support the required ioctl. let it pass */
- goto ret;
- }
-
- if ((int)st.st_rdev)
- {
- localDevices = xf86FirstLocalDevice();
-
- for (; localDevices != NULL; localDevices = localDevices->next)
- {
- device = xf86CheckStrOption(localDevices->options, "Device", NULL);
-
- /* device can be NULL on some distros */
- if (!device || !strstr(localDevices->drv->driverName, "wacom"))
- continue;
-
- common = ((WacomDevicePtr)localDevices->private)->common;
- if (local != localDevices &&
- common->min_maj &&
- common->min_maj == st.st_rdev)
- {
- /* device matches with another added port */
- if (xf86WcmCheckTypeAndSource(local, localDevices))
- {
- xf86Msg(X_WARNING, "%s: device file already in use by %s. "
- "Ignoring.\n", local->name, localDevices->name);
- isInUse = 4;
- goto ret;
- }
- }
- }
- }
- else
- {
- /* major/minor can never be 0, right? */
- xf86Msg(X_ERROR, "%s: device opened with a major/minor of 0. "
- "Something was wrong.\n", local->name);
- isInUse = 5;
- }
-ret:
- if (local->fd >= 0)
- {
- close(local->fd);
- local->fd = -1;
- }
- return isInUse;
-}
-
-static struct
-{
- __u16 productID;
- __u16 flags;
-} validType [] =
-{
- { 0x00, STYLUS_ID }, /* PenPartner */
- { 0x10, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Graphire */
- { 0x11, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Graphire2 4x5 */
- { 0x12, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Graphire2 5x7 */
-
- { 0x13, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Graphire3 4x5 */
- { 0x14, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Graphire3 6x8 */
-
- { 0x15, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Graphire4 4x5 */
- { 0x16, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Graphire4 6x8 */
- { 0x17, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* BambooFun 4x5 */
- { 0x18, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* BambooFun 6x8 */
- { 0x19, STYLUS_ID | ERASER_ID }, /* Bamboo1 Medium*/
- { 0x81, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Graphire4 6x8 BlueTooth */
-
- { 0x20, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos 4x5 */
- { 0x21, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos 6x8 */
- { 0x22, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos 9x12 */
- { 0x23, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos 12x12 */
- { 0x24, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos 12x18 */
-
- { 0x03, STYLUS_ID | ERASER_ID }, /* PTU600 */
- { 0x30, STYLUS_ID | ERASER_ID }, /* PL400 */
- { 0x31, STYLUS_ID | ERASER_ID }, /* PL500 */
- { 0x32, STYLUS_ID | ERASER_ID }, /* PL600 */
- { 0x33, STYLUS_ID | ERASER_ID }, /* PL600SX */
- { 0x34, STYLUS_ID | ERASER_ID }, /* PL550 */
- { 0x35, STYLUS_ID | ERASER_ID }, /* PL800 */
- { 0x37, STYLUS_ID | ERASER_ID }, /* PL700 */
- { 0x38, STYLUS_ID | ERASER_ID }, /* PL510 */
- { 0x39, STYLUS_ID | ERASER_ID }, /* PL710 */
- { 0xC0, STYLUS_ID | ERASER_ID }, /* DTF720 */
- { 0xC2, STYLUS_ID | ERASER_ID }, /* DTF720a */
- { 0xC4, STYLUS_ID | ERASER_ID }, /* DTF521 */
- { 0xC7, STYLUS_ID | ERASER_ID }, /* DTU1931 */
-
- { 0x41, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos2 4x5 */
- { 0x42, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos2 6x8 */
- { 0x43, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos2 9x12 */
- { 0x44, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos2 12x12 */
- { 0x45, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos2 12x18 */
- { 0x47, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos2 6x8 */
-
- { 0x60, STYLUS_ID }, /* Volito */
- { 0x61, STYLUS_ID }, /* PenStation */
- { 0x62, STYLUS_ID }, /* Volito2 4x5 */
- { 0x63, STYLUS_ID }, /* Volito2 2x3 */
- { 0x64, STYLUS_ID }, /* PenPartner2 */
-
- { 0x65, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Bamboo */
- { 0x69, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Bamboo1 */
-
- { 0xB0, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos3 4x5 */
- { 0xB1, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos3 6x8 */
- { 0xB2, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos3 9x12 */
- { 0xB3, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos3 12x12 */
- { 0xB4, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos3 12x19 */
- { 0xB5, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos3 6x11 */
- { 0xB7, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos3 4x6 */
-
- { 0xB8, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Intuos4 4x6 */
- { 0xB9, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Intuos4 6x9 */
- { 0xBA, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Intuos4 8x13 */
- { 0xBB, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Intuos4 12x19*/
-
- { 0x3F, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Cintiq 21UX */
- { 0xC5, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Cintiq 20WSX */
- { 0xC6, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Cintiq 12WX */
-
- { 0x90, STYLUS_ID | ERASER_ID }, /* TabletPC 0x90 */
- { 0x93, STYLUS_ID | ERASER_ID | TOUCH_ID }, /* TabletPC 0x93 */
- { 0x9A, STYLUS_ID | ERASER_ID | TOUCH_ID }, /* TabletPC 0x9A */
- { 0x9F, TOUCH_ID }, /* CapPlus 0x9F */
- { 0xE2, TOUCH_ID }, /* TabletPC 0xE2 */
- { 0xE3, STYLUS_ID | ERASER_ID | TOUCH_ID } /* TabletPC 0xE3 */
-};
-
-static struct
-{
- const char* type;
- __u16 id;
-} wcmTypeAndID [] =
-{
- { "stylus", STYLUS_ID },
- { "eraser", ERASER_ID },
- { "cursor", CURSOR_ID },
- { "touch", TOUCH_ID },
- { "pad", PAD_ID }
-};
-
-/* validate tool type for device/product */
-static int wcmIsAValidType(char* device, LocalDevicePtr local, unsigned short id)
-{
- int i, j, ret = 0;
- char* type = xf86FindOptionValue(local->options, "Type");
-
- /* walkthrough all supported models */
- for (i = 0; i < sizeof (validType) / sizeof (validType [0]); i++)
- {
- if (validType[i].productID == id)
- {
-
- /* walkthrough all types */
- for (j = 0; j < sizeof (wcmTypeAndID) / sizeof (wcmTypeAndID [0]); j++)
- if (!strcmp(wcmTypeAndID[j].type, type))
- if (wcmTypeAndID[j].id & validType[i].flags)
- ret = 1;
- }
- }
- return ret;
-}
-#endif /* WCM_XORG_XSERVER_1_4 */
/* xf86WcmInit - called when the module subsection is found in XF86Config */
static LocalDevicePtr xf86WcmInit(InputDriverPtr drv, IDevPtr dev, int flags)
@@ -704,11 +474,11 @@ static LocalDevicePtr xf86WcmInit(InputDriverPtr drv, IDevPtr dev, int flags)
if (!xf86WcmIsWacomDevice(device, &id))
goto SetupProc_fail;
- /* check if the type is valid for the device */
+ /* check if the type is valid for the device */
if(!wcmIsAValidType(device, fakeLocal, id.product))
goto SetupProc_fail;
- /* check if the device has been added */
+ /* check if the device has been added */
if (wcmIsDuplicate(device, fakeLocal))
goto SetupProc_fail;
}
@@ -1046,26 +816,20 @@ static LocalDevicePtr xf86WcmInit(InputDriverPtr drv, IDevPtr dev, int flags)
xf86Msg(X_CONFIG, "%s: threshold = %d\n", dev->identifier,
common->wcmThreshold);
- priv->wcmMaxX = xf86SetIntOption(local->options, "MaxX",
+ common->wcmMaxX = xf86SetIntOption(local->options, "MaxX",
common->wcmMaxX);
- if (priv->wcmMaxX > 0)
+ if (common->wcmMaxX > 0)
{
- xf86Msg(X_CONFIG, "%s: max x set to %d by xorg.conf\n", dev->identifier,
- priv->wcmMaxX);
-
- /* Update tablet logical max X */
- if (!IsTouch(priv)) common->wcmMaxX = priv->wcmMaxX;
+ xf86Msg(X_CONFIG, "%s: max x set to %d \n", dev->identifier,
+ common->wcmMaxX);
}
- priv->wcmMaxY = xf86SetIntOption(local->options, "MaxY",
+ common->wcmMaxY = xf86SetIntOption(local->options, "MaxY",
common->wcmMaxY);
- if (priv->wcmMaxY > 0)
+ if (common->wcmMaxY > 0)
{
- xf86Msg(X_CONFIG, "%s: max y set to %d by xorg.conf\n", dev->identifier,
- priv->wcmMaxY);
-
- /* Update tablet logical max Y */
- if (!IsTouch(priv)) common->wcmMaxY = priv->wcmMaxY;
+ xf86Msg(X_CONFIG, "%s: max y set to %d \n", dev->identifier,
+ common->wcmMaxY);
}
common->wcmMaxZ = xf86SetIntOption(local->options, "MaxZ",
diff --git a/src/xdrv/wcmISDV4.c b/src/xdrv/wcmISDV4.c
index 6f05393..1f7aa87 100755
--- a/src/xdrv/wcmISDV4.c
+++ b/src/xdrv/wcmISDV4.c
@@ -23,7 +23,7 @@
static Bool isdv4Detect(LocalDevicePtr);
static Bool isdv4Init(LocalDevicePtr, char* id, float *version);
-static void isdv4InitISDV4(WacomCommonPtr, const char* id, float version);
+static void isdv4InitISDV4(WacomCommonPtr common, const char* id, float version);
static int isdv4GetRanges(LocalDevicePtr);
static int isdv4StartTablet(LocalDevicePtr);
static int isdv4Parse(LocalDevicePtr, const unsigned char* data);
@@ -235,7 +235,7 @@ static int isdv4GetRanges(LocalDevicePtr local)
/* (data[2] & 0x07) == 0 is for resistive touch */
if (!(data[2] & 0x07) && data[1])
{
- common->wcmMaxTouchX = common->wcmMaxTouchY = (int)(1 << data[1]);
+ common->wcmMaxX = common->wcmMaxY = (int)(1 << data[1]);
}
if ((data[0] & 0x41) && (data[2] & 0x07))
@@ -257,7 +257,7 @@ static int isdv4GetRanges(LocalDevicePtr local)
/* touch logical size for tablet PC with touch */
if (data[1])
{
- common->wcmMaxTouchX = common->wcmMaxTouchY = (int)(1 << data[1]);
+ common->wcmMaxX = common->wcmMaxY = (int)(1 << data[1]);
}
/* Max capacity */
@@ -265,9 +265,9 @@ static int isdv4GetRanges(LocalDevicePtr local)
if (common->wcmMaxCapacity)
{
- common->wcmTouchResolX = common->wcmMaxTouchX / ( 2540 *
+ common->wcmResolX = common->wcmMaxX / ( 2540 *
((data[3] << 9) | (data[4] << 2) | ((data[2] & 0x60) >> 5)));
- common->wcmTouchResolX = common->wcmMaxTouchX / ( 2540 *
+ common->wcmResolX = common->wcmMaxX / ( 2540 *
((data[5] << 9) | (data[6] << 2) | ((data[2] & 0x18) >> 3)));
}
}
@@ -283,21 +283,12 @@ static int isdv4GetRanges(LocalDevicePtr local)
* defaults to enable when it is a touch device
*/
common->wcmTouchDefault = 1;
-
- if (common->wcmMaxX && common->wcmMaxY && !common->wcmTouchResolX)
- {
- /* Some touch tablet don't report physical size */
- common->wcmTouchResolX = (int)((double)(common->wcmMaxTouchX *
- common->wcmResolX) / (double)common->wcmMaxX + 0.5);
- common->wcmTouchResolY = (int)((double)(common->wcmMaxTouchY *
- common->wcmResolY) / (double)common->wcmMaxY + 0.5);
- }
}
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->wcmTouchResolX, common->wcmTouchResolY));
+ common->wcmResolX, common->wcmResolY));
return Success;
}
@@ -328,6 +319,7 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data)
DBG(10, common->debugLevel, ErrorF("isdv4Parse \n"));
+ channel = 0;
/* determine the type of message (touch or stylus)*/
if (data[0] & 0x18) /* not a pen */
{
@@ -353,7 +345,7 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data)
else if (!(data[0] & 0x01)) /* touch out-prox */
{
touchInProx = 0;
- channel = 1;
+ channel = 0;
}
else
{
@@ -374,9 +366,7 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data)
if (common->wcmChannel[1].valid.state.proximity)
{
/* let touch go */
- WacomDeviceState out = { 0 };
- out.device_type = TOUCH_ID;
- xf86WcmEvent(common, 1, &out);
+ xf86WcmSoftOut(common, 1);
return 0;
}
common->wcmPktLength = WACOM_PKGLEN_TPC;
@@ -402,7 +392,8 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data)
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_TOUCH0 ||
+ common->wcmPktLength == WACOM_PKGLEN_TOUCH) /* a touch */
{
/* touch without capacity has 5 bytes of data
* touch with capacity has 7 bytes of data
@@ -450,8 +441,7 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data)
(ds->device_type == ERASER_ID))
{
/* send a prox-out for old device */
- WacomDeviceState out = { 0 };
- xf86WcmEvent(common, 0, &out);
+ xf86WcmSoftOut(common, 0);
ds->device_type = cur_type;
}
}
diff --git a/src/xdrv/wcmMapping.c b/src/xdrv/wcmMapping.c
new file mode 100755
index 0000000..7b1caed
--- /dev/null
+++ b/src/xdrv/wcmMapping.c
@@ -0,0 +1,874 @@
+/*
+ * Copyright 2009 by Ping Cheng, Wacom Technology. <pingc@wacom.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "xf86Wacom.h"
+#include "../include/Xwacom.h"
+
+static void xf86WcmInitialScreens(LocalDevicePtr local);
+
+
+/*****************************************************************************
+ * xf86WcmDesktopSize --
+ * calculate the whole desktop size
+ ****************************************************************************/
+static void xf86WcmDesktopSize(LocalDevicePtr local)
+{
+ WacomDevicePtr priv = (WacomDevicePtr) local->private;
+ int i = 0, minX = 0, minY = 0, maxX = 0, maxY = 0;
+
+ xf86WcmInitialScreens(local);
+
+ minX = priv->screenTopX[0];
+ minY = priv->screenTopY[0];
+ maxX = priv->screenBottomX[0];
+ maxY = priv->screenBottomY[0];
+
+ if (priv->numScreen != 1)
+ {
+ for (i = 1; i < priv->numScreen; i++)
+ {
+ if (priv->screenTopX[i] < minX)
+ minX = priv->screenTopX[i];
+ if (priv->screenTopY[i] < minY)
+ minY = priv->screenTopY[i];
+ if (priv->screenBottomX[i] > maxX)
+ maxX = priv->screenBottomX[i];
+ if (priv->screenBottomY[i] > maxY)
+ maxY = priv->screenBottomY[i];
+ }
+ }
+
+ priv->maxWidth = maxX - minX;
+ priv->maxHeight = maxY - minY;
+}
+
+int xf86WcmInitArea(LocalDevicePtr local)
+{
+ WacomDevicePtr priv = (WacomDevicePtr)local->private;
+ WacomToolAreaPtr area = priv->toolarea, inlist;
+ WacomCommonPtr common = priv->common;
+ double screenRatio, tabletRatio;
+
+ DBG(10, priv->debugLevel, ErrorF("xf86WcmInitArea\n"));
+
+ /* Verify Box */
+ if (priv->topX > common->wcmMaxX)
+ {
+ area->topX = priv->topX = 0;
+ }
+
+ if (priv->topY > common->wcmMaxY)
+ {
+ area->topY = priv->topY = 0;
+ }
+
+ /* set unconfigured bottom to max */
+ priv->bottomX = xf86SetIntOption(local->options, "BottomX", 0);
+ if (priv->bottomX < priv->topX || !priv->bottomX)
+ {
+ area->bottomX = priv->bottomX = common->wcmMaxX;
+ }
+
+ /* set unconfigured bottom to max */
+ priv->bottomY = xf86SetIntOption(local->options, "BottomY", 0);
+ if (priv->bottomY < priv->topY || !priv->bottomY)
+ {
+ area->bottomY = priv->bottomY = common->wcmMaxY;
+ }
+
+ if (priv->twinview > TV_XINERAMA)
+ priv->numScreen = 2;
+
+ if (priv->screen_no != -1 &&
+ (priv->screen_no >= priv->numScreen || priv->screen_no < 0))
+ {
+ if (priv->twinview <= TV_XINERAMA)
+ {
+ ErrorF("%s: invalid screen number %d, resetting to default (-1) \n",
+ local->name, priv->screen_no);
+ priv->screen_no = -1;
+ }
+ else if (priv->screen_no > 1)
+ {
+ ErrorF("%s: invalid screen number %d, resetting to default (-1) \n",
+ local->name, priv->screen_no);
+ priv->screen_no = -1;
+ }
+ }
+
+ /* need maxWidth and maxHeight for keepshape */
+ xf86WcmDesktopSize(local);
+
+ /* Maintain aspect ratio to the whole desktop
+ * May need to consider a specific screen in multimonitor settings
+ */
+ if (priv->flags & KEEP_SHAPE_FLAG)
+ {
+
+ screenRatio = ((double)priv->maxWidth / (double)priv->maxHeight);
+ tabletRatio = ((double)(common->wcmMaxX - priv->topX) /
+ (double)(common->wcmMaxY - priv->topY));
+
+ DBG(2, priv->debugLevel, ErrorF("screenRatio = %.3g, "
+ "tabletRatio = %.3g\n", screenRatio, tabletRatio));
+
+ if (screenRatio > tabletRatio)
+ {
+ area->bottomX = priv->bottomX = common->wcmMaxX;
+ area->bottomY = priv->bottomY = (common->wcmMaxY - priv->topY) *
+ tabletRatio / screenRatio + priv->topY;
+ }
+ else
+ {
+ area->bottomX = priv->bottomX = (common->wcmMaxX - priv->topX) *
+ screenRatio / tabletRatio + priv->topX;
+ area->bottomY = priv->bottomY = common->wcmMaxY;
+ }
+ }
+ /* end keep shape */
+
+ inlist = priv->tool->arealist;
+
+ /* The first one in the list is always valid */
+ if (area != inlist && xf86WcmAreaListOverlap(area, inlist))
+ {
+ inlist = priv->tool->arealist;
+
+ /* remove this overlapped area from the list */
+ for (; inlist; inlist=inlist->next)
+ {
+ if (inlist->next == area)
+ {
+ inlist->next = area->next;
+ xfree(area);
+ priv->toolarea = NULL;
+ break;
+ }
+ }
+
+ /* Remove this device from the common struct */
+ if (common->wcmDevices == priv)
+ common->wcmDevices = priv->next;
+ else
+ {
+ WacomDevicePtr tmp = common->wcmDevices;
+ while(tmp->next && tmp->next != priv)
+ tmp = tmp->next;
+ if(tmp)
+ tmp->next = priv->next;
+ }
+ xf86Msg(X_ERROR, "%s: Top/Bottom area overlaps with another devices.\n",
+ local->conf_idev->identifier);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*****************************************************************************
+ * xf86WcmVirtaulTabletSize(LocalDevicePtr local)
+ ****************************************************************************/
+
+void xf86WcmVirtaulTabletSize(LocalDevicePtr local)
+{
+ WacomDevicePtr priv = (WacomDevicePtr)local->private;
+
+ if (!(priv->flags & ABSOLUTE_FLAG))
+ {
+ priv->sizeX = priv->bottomX - priv->topX;
+ priv->sizeY = priv->bottomY - priv->topY;
+ return;
+ }
+
+ priv->sizeX = priv->bottomX - priv->topX - priv->tvoffsetX;
+ priv->sizeY = priv->bottomY - priv->topY - priv->tvoffsetY;
+
+ DBG(10, priv->debugLevel, ErrorF("xf86WcmVirtaulTabletSize for \"%s\" "
+ "x=%d y=%d \n", local->name, priv->sizeX, priv->sizeY));
+ return;
+}
+
+/*****************************************************************************
+ * xf86WcmInitialCoordinates
+ ****************************************************************************/
+
+void xf86WcmInitialCoordinates(LocalDevicePtr local, int axes)
+{
+ WacomDevicePtr priv = (WacomDevicePtr)local->private;
+ int topx = 0, topy = 0, resolution;
+ WacomCommonPtr common = priv->common;
+ int bottomx = common->wcmMaxX, bottomy = common->wcmMaxY;
+
+ xf86WcmMappingFactor(local);
+
+ /* x ax */
+ if ( !axes )
+ {
+ if (priv->flags & ABSOLUTE_FLAG)
+ {
+ topx = priv->topX;
+ bottomx = priv->sizeX + priv->topX;
+ if ((priv->currentScreen == 1) && (priv->twinview > TV_XINERAMA))
+ topx += priv->tvoffsetX;
+ if ((priv->currentScreen == 0) && (priv->twinview > TV_XINERAMA))
+ bottomx -= priv->tvoffsetX;
+ }
+
+ resolution = common->wcmResolX;
+#ifdef WCM_XORG_TABLET_SCALING
+ /* Ugly hack for Xorg 7.3, which doesn't call xf86WcmDevConvert
+ * for coordinate conversion at the moment */
+ topx = 0;
+ bottomx = priv->sizeX;
+ if ((priv->twinview == TV_LEFT_RIGHT) || (priv->twinview == TV_RIGHT_LEFT))
+ bottomx *= 2;
+ bottomx = (int)((double)bottomx * priv->factorX + 0.5);
+ resolution = (int)((double)resolution * priv->factorX + 0.5);
+#endif
+
+ InitValuatorAxisStruct(local->dev, 0, topx, bottomx,
+ resolution, 0, resolution);
+ }
+ else /* y ax */
+ {
+ if (priv->flags & ABSOLUTE_FLAG)
+ {
+ topy = priv->topY;
+ bottomy = priv->sizeY + priv->topY;
+ if ((priv->currentScreen == 1) && (priv->twinview > TV_XINERAMA))
+ topy += priv->tvoffsetY;
+ if ((priv->currentScreen == 0) && (priv->twinview > TV_XINERAMA))
+ bottomy -= priv->tvoffsetY;
+ }
+
+ resolution = common->wcmResolY;
+#ifdef WCM_XORG_TABLET_SCALING
+ /* Ugly hack for Xorg 7.3, which doesn't call xf86WcmDevConvert
+ * for coordinate conversion at the moment */
+ topy = 0;
+ bottomy = priv->sizeY;
+ if ((priv->twinview == TV_ABOVE_BELOW) || (priv->twinview == TV_BELOW_ABOVE))
+ bottomy *= 2;
+ bottomy = (int)((double)bottomy * priv->factorY + 0.5);
+ resolution = (int)((double)resolution * priv->factorY + 0.5);
+#endif
+
+ InitValuatorAxisStruct(local->dev, 1, topy, bottomy,
+ resolution, 0, resolution);
+ }
+ return;
+}
+
+/*****************************************************************************
+ * xf86WcmMappingFactor --
+ * calculate the proper tablet to screen mapping factor according to the
+ * screen/desktop size and the tablet size
+ ****************************************************************************/
+
+void xf86WcmMappingFactor(LocalDevicePtr local)
+{
+ WacomDevicePtr priv = (WacomDevicePtr) local->private;
+ int screenX, screenY;
+
+ DBG(10, priv->debugLevel, ErrorF("xf86WcmMappingFactor \n"));
+
+ xf86WcmVirtaulTabletSize(local);
+
+ if (!(priv->flags & ABSOLUTE_FLAG) || !priv->wcmMMonitor)
+ {
+ /* Get the current screen that the cursor is in */
+#if WCM_XINPUTABI_MAJOR == 0
+ if (miPointerCurrentScreen())
+ priv->currentScreen = miPointerCurrentScreen()->myNum;
+#else
+ if (miPointerGetScreen(local->dev))
+ priv->currentScreen = miPointerGetScreen(local->dev)->myNum;
+#endif
+ }
+ else
+ {
+ if (priv->screen_no != -1)
+ priv->currentScreen = priv->screen_no;
+ else if (priv->currentScreen == -1)
+ {
+ /* Get the current screen that the cursor is in */
+#if WCM_XINPUTABI_MAJOR == 0
+ if (miPointerCurrentScreen())
+ priv->currentScreen = miPointerCurrentScreen()->myNum;
+#else
+ if (miPointerGetScreen(local->dev))
+ priv->currentScreen = miPointerGetScreen(local->dev)->myNum;
+#endif
+ }
+ }
+ if (priv->currentScreen == -1) /* tool on the tablet */
+ priv->currentScreen = 0;
+
+ screenX = priv->maxWidth;
+ screenY = priv->maxHeight;
+ if (priv->screen_no != -1 || (priv->twinview > TV_XINERAMA) || (!priv->wcmMMonitor) )
+ {
+ screenX = priv->screenBottomX[priv->currentScreen] - priv->screenTopX[priv->currentScreen];
+ screenY = priv->screenBottomY[priv->currentScreen] - priv->screenTopY[priv->currentScreen];
+ }
+ DBG(10, priv->debugLevel, ErrorF("xf86WcmMappingFactor"
+ " Active tablet area x=%d y=%d (virtual tablet area x=%d y=%d) map"
+ " to maxWidth =%d maxHeight =%d\n",
+ priv->bottomX, priv->bottomY, priv->sizeX, priv->sizeY,
+ screenX, screenY));
+
+ priv->factorX = (double)screenX / (double)priv->sizeX;
+ priv->factorY = (double)screenY / (double)priv->sizeY;
+ DBG(2, priv->debugLevel, ErrorF("X factor = %.3g, Y factor = %.3g\n",
+ priv->factorX, priv->factorY));
+}
+
+/*****************************************************************************
+ * xf86WcmSetScreen --
+ * set to the proper screen according to the converted (x,y).
+ * this only supports for horizontal setup now.
+ * need to know screen's origin (x,y) to support
+ * combined horizontal and vertical setups
+ ****************************************************************************/
+
+void xf86WcmSetScreen(LocalDevicePtr local, int v0, int v1)
+{
+ WacomDevicePtr priv = (WacomDevicePtr) local->private;
+ int screenToSet = -1, i, j, x, y, tabletSize = 0;
+
+ DBG(6, priv->debugLevel, ErrorF("xf86WcmSetScreen v0=%d v1=%d "
+ "currentScreen=%d\n", v0, v1, priv->currentScreen));
+
+ if (priv->screen_no != -1 && priv->screen_no >= priv->numScreen)
+ {
+ ErrorF("xf86WcmSetScreen Screen%d is larger than number of available screens (%d)\n",
+ priv->screen_no, priv->numScreen);
+ priv->screen_no = -1;
+ }
+
+ if (!(local->flags & (XI86_ALWAYS_CORE | XI86_CORE_POINTER))) return;
+
+ if (priv->twinview > TV_XINERAMA && priv->screen_no == -1 && (priv->flags & ABSOLUTE_FLAG))
+ {
+ if (priv->twinview == TV_LEFT_RIGHT)
+ {
+ tabletSize = priv->bottomX - priv->tvoffsetX;
+ if (v0 > tabletSize && v0 <= priv->bottomX)
+ priv->currentScreen = 1;
+ if (v0 > priv->topX && v0 <= priv->topX + priv->tvoffsetX)
+ priv->currentScreen = 0;
+ }
+ if (priv->twinview == TV_ABOVE_BELOW)
+ {
+ tabletSize = priv->bottomY - priv->tvoffsetY;
+ if (v0 > tabletSize && v0 <= priv->bottomY)
+ priv->currentScreen = 1;
+ if (v0 > priv->topY && v0 <= priv->topY + priv->tvoffsetY)
+ priv->currentScreen = 0;
+ }
+ if (priv->twinview == TV_RIGHT_LEFT)
+ {
+ tabletSize = priv->bottomX - priv->tvoffsetX;
+ if (v0 > tabletSize && v0 <= priv->bottomX)
+ priv->currentScreen = 0;
+ if (v0 > priv->topX && v0 <= priv->topX + priv->tvoffsetX)
+ priv->currentScreen = 1;
+ }
+ if (priv->twinview == TV_BELOW_ABOVE)
+ {
+ tabletSize = priv->bottomY - priv->tvoffsetY;
+ if (v0 > tabletSize && v0 <= priv->bottomY)
+ priv->currentScreen = 0;
+ if (v0 > priv->topY && v0 <= priv->topY + priv->tvoffsetY)
+ priv->currentScreen = 1;
+ }
+ DBG(10, priv->debugLevel, ErrorF("xf86WcmSetScreen TwinView setup screenToSet=%d\n",
+ priv->currentScreen));
+ }
+
+ xf86WcmMappingFactor(local);
+ if (!(priv->flags & ABSOLUTE_FLAG) || screenInfo.numScreens == 1 || !priv->wcmMMonitor)
+ return;
+
+ v0 = v0 - priv->topX;
+ v1 = v1 - priv->topY;
+
+ if (priv->screen_no == -1)
+ {
+ for (i = 0; i < priv->numScreen; i++)
+ {
+ if (v0 * priv->factorX >= priv->screenTopX[i] &&
+ v0 * priv->factorX < priv->screenBottomX[i] - 0.5)
+ {
+
+ for (j = 0; j < priv->numScreen; j++)
+ {
+ if (v1 * priv->factorY >= priv->screenTopY[j] &&
+ v1 * priv->factorY <= priv->screenBottomY[j] - 0.5)
+ {
+ if (j == i)
+ {
+ screenToSet = i;
+ break;
+ }
+ }
+ }
+
+ if (screenToSet != -1)
+ break;
+ }
+ }
+ }
+ else
+ screenToSet = priv->screen_no;
+
+ if (screenToSet == -1)
+ {
+ DBG(3, priv->debugLevel, ErrorF("xf86WcmSetScreen Error: "
+ "Can not find valid screen (currentScreen=%d)\n",
+ priv->currentScreen));
+ return;
+ }
+
+ priv->currentScreen = screenToSet;
+ xf86WcmMappingFactor(local);
+ x = ((double)v0 * priv->factorX) - priv->screenTopX[screenToSet] + 0.5;
+ y = ((double)v1 * priv->factorY) - priv->screenTopY[screenToSet] + 0.5;
+
+ if (x >= screenInfo.screens[screenToSet]->width)
+ x = screenInfo.screens[screenToSet]->width - 1;
+ if (y >= screenInfo.screens[screenToSet]->height)
+ y = screenInfo.screens[screenToSet]->height - 1;
+
+ xf86XInputSetScreen(local, screenToSet, x, y);
+ DBG(10, priv->debugLevel, ErrorF("xf86WcmSetScreen current=%d ToSet=%d\n",
+ priv->currentScreen, screenToSet));
+}
+
+/*****************************************************************************
+ * xf86WcmInitTablet -- common initialization for all tablets
+ ****************************************************************************/
+
+int xf86WcmInitTablet(LocalDevicePtr local, const char* id, float version)
+{
+ WacomDevicePtr priv = (WacomDevicePtr)local->private;
+ WacomCommonPtr common = priv->common;
+ WacomModelPtr model = common->wcmModel;
+
+ /* Initialize the tablet */
+ model->Initialize(common,id,version);
+
+ /* Get tablet resolution */
+ if (model->GetResolution)
+ model->GetResolution(local);
+
+ /* Get tablet range */
+ if (model->GetRanges && (model->GetRanges(local) != Success))
+ return !Success;
+
+ /* Default threshold value if not set */
+ if (common->wcmThreshold <= 0)
+ {
+ /* Threshold for counting pressure as a button */
+ if (strstr(common->wcmModel->name, "Intuos4"))
+ common->wcmThreshold = common->wcmMaxZ * 3 / 25;
+ else
+ common->wcmThreshold = common->wcmMaxZ * 3 / 50;
+ ErrorF("%s Wacom using pressure threshold of %d for button 1\n",
+ XCONFIG_PROBED, common->wcmThreshold);
+ }
+
+ /* Reset tablet to known state */
+ if (model->Reset && (model->Reset(local) != Success))
+ {
+ ErrorF("Wacom xf86WcmWrite error : %s\n", strerror(errno));
+ return !Success;
+ }
+
+ /* Enable tilt mode, if requested and available */
+ if ((common->wcmFlags & TILT_REQUEST_FLAG) && model->EnableTilt)
+ {
+ if (model->EnableTilt(local) != Success)
+ return !Success;
+ }
+
+ /* Enable hardware suppress, if requested and available */
+ if (model->EnableSuppress)
+ {
+ if (model->EnableSuppress(local) != Success)
+ return !Success;
+ }
+
+ /* change the serial speed, if requested */
+ if (model->SetLinkSpeed)
+ {
+ if (common->wcmLinkSpeed != 9600)
+ {
+ if (model->SetLinkSpeed(local) != Success)
+ return !Success;
+ }
+ }
+ else
+ {
+ DBG(2, common->debugLevel, ErrorF("Tablet does not support setting link "
+ "speed, or not yet implemented\n"));
+ }
+
+ /* output tablet state as probed */
+ if (xf86Verbose)
+ ErrorF("%s Wacom %s tablet speed=%d (%d) maxX=%d maxY=%d maxZ=%d "
+ "resX=%d resY=%d tilt=%s\n",
+ XCONFIG_PROBED,
+ model->name, common->wcmLinkSpeed, common->wcmISDV4Speed,
+ common->wcmMaxX, common->wcmMaxY, common->wcmMaxZ,
+ common->wcmResolX, common->wcmResolY,
+ HANDLE_TILT(common) ? "enabled" : "disabled");
+
+ /* start the tablet data */
+ if (model->Start && (model->Start(local) != Success))
+ return !Success;
+
+ return Success;
+}
+
+/*****************************************************************************
+ * xf86WcmInitialTVScreens
+ ****************************************************************************/
+
+static void xf86WcmInitialTVScreens(LocalDevicePtr local)
+{
+ WacomDevicePtr priv = (WacomDevicePtr)local->private;
+
+ if (priv->twinview <= TV_XINERAMA)
+ return;
+
+ priv->numScreen = 2;
+
+ if ((priv->twinview == TV_LEFT_RIGHT) || (priv->twinview == TV_RIGHT_LEFT))
+ {
+ /* it does not need the offset if always map to a specific screen */
+ if (priv->screen_no == -1)
+ {
+ priv->tvoffsetX = 60;
+ priv->tvoffsetY = 0;
+ }
+
+ /* default resolution */
+ if(!priv->tvResolution[0])
+ {
+ priv->tvResolution[0] = screenInfo.screens[0]->width/2;
+ priv->tvResolution[1] = screenInfo.screens[0]->height;
+ priv->tvResolution[2] = priv->tvResolution[0];
+ priv->tvResolution[3] = priv->tvResolution[1];
+ }
+ }
+ else if ((priv->twinview == TV_ABOVE_BELOW) || (priv->twinview == TV_BELOW_ABOVE))
+ {
+ /* it does not need the offset if always map to a specific screen */
+ if (priv->screen_no == -1)
+ {
+ priv->tvoffsetX = 0;
+ priv->tvoffsetY = 60;
+ }
+
+ /* default resolution */
+ if(!priv->tvResolution[0])
+ {
+ priv->tvResolution[0] = screenInfo.screens[0]->width;
+ priv->tvResolution[1] = screenInfo.screens[0]->height/2;
+ priv->tvResolution[2] = priv->tvResolution[0];
+ priv->tvResolution[3] = priv->tvResolution[1];
+ }
+ }
+
+ /* initial screen info */
+ if (priv->twinview == TV_ABOVE_BELOW)
+ {
+ priv->screenTopX[0] = 0;
+ priv->screenTopY[0] = 0;
+ priv->screenBottomX[0] = priv->tvResolution[0];
+ priv->screenBottomY[0] = priv->tvResolution[1];
+ priv->screenTopX[1] = 0;
+ priv->screenTopY[1] = priv->tvResolution[1];
+ priv->screenBottomX[1] = priv->tvResolution[2];
+ priv->screenBottomY[1] = priv->tvResolution[1] + priv->tvResolution[3];
+ }
+ if (priv->twinview == TV_LEFT_RIGHT)
+ {
+ priv->screenTopX[0] = 0;
+ priv->screenTopY[0] = 0;
+ priv->screenBottomX[0] = priv->tvResolution[0];
+ priv->screenBottomY[0] = priv->tvResolution[1];
+ priv->screenTopX[1] = priv->tvResolution[0];
+ priv->screenTopY[1] = 0;
+ priv->screenBottomX[1] = priv->tvResolution[0] + priv->tvResolution[2];
+ priv->screenBottomY[1] = priv->tvResolution[3];
+ }
+ if (priv->twinview == TV_BELOW_ABOVE)
+ {
+ priv->screenTopX[0] = 0;
+ priv->screenTopY[0] = priv->tvResolution[1];
+ priv->screenBottomX[0] = priv->tvResolution[2];
+ priv->screenBottomY[0] = priv->tvResolution[1] + priv->tvResolution[3];
+ priv->screenTopX[1] = 0;
+ priv->screenTopY[1] = 0;
+ priv->screenBottomX[1] = priv->tvResolution[0];
+ priv->screenBottomY[1] = priv->tvResolution[1];
+ }
+ if (priv->twinview == TV_RIGHT_LEFT)
+ {
+ priv->screenTopX[0] = priv->tvResolution[0];
+ priv->screenTopY[0] = 0;
+ priv->screenBottomX[0] = priv->tvResolution[0] + priv->tvResolution[2];
+ priv->screenBottomY[0] = priv->tvResolution[3];
+ priv->screenTopX[1] = 0;
+ priv->screenTopY[1] = 0;
+ priv->screenBottomX[1] = priv->tvResolution[0];
+ priv->screenBottomY[1] = priv->tvResolution[1];
+ }
+
+ DBG(10, priv->debugLevel, ErrorF("xf86WcmInitialTVScreens for \"%s\" "
+ "topX0=%d topY0=%d bottomX0=%d bottomY0=%d "
+ "topX1=%d topY1=%d bottomX1=%d bottomY1=%d \n",
+ local->name, priv->screenTopX[0], priv->screenTopY[0],
+ priv->screenBottomX[0], priv->screenBottomY[0],
+ priv->screenTopX[1], priv->screenTopY[1],
+ priv->screenBottomX[1], priv->screenBottomY[1]));
+}
+
+/*****************************************************************************
+ * xf86WcmInitialScreens
+ ****************************************************************************/
+
+static void xf86WcmInitialScreens(LocalDevicePtr local)
+{
+ WacomDevicePtr priv = (WacomDevicePtr)local->private;
+ int i;
+
+ DBG(2, priv->debugLevel, ErrorF("xf86WcmInitialScreens for \"%s\" "
+ "number of screen=%d \n", local->name, screenInfo.numScreens));
+ priv->tvoffsetX = 0;
+ priv->tvoffsetY = 0;
+ if (priv->twinview > TV_XINERAMA)
+ {
+ xf86WcmInitialTVScreens(local);
+ return;
+ }
+
+ /* initial screen info */
+ priv->numScreen = screenInfo.numScreens;
+ priv->screenTopX[0] = 0;
+ priv->screenTopY[0] = 0;
+ priv->screenBottomX[0] = 0;
+ priv->screenBottomY[0] = 0;
+ for (i=0; i<screenInfo.numScreens; i++)
+ {
+#ifdef WCM_HAVE_DIXSCREENORIGINS
+ if (screenInfo.numScreens > 1)
+ {
+ priv->screenTopX[i] = dixScreenOrigins[i].x;
+ priv->screenTopY[i] = dixScreenOrigins[i].y;
+ priv->screenBottomX[i] = dixScreenOrigins[i].x;
+ priv->screenBottomY[i] = dixScreenOrigins[i].y;
+
+ DBG(10, priv->debugLevel, ErrorF("xf86WcmInitialScreens from dix for \"%s\" "
+ "ScreenOrigins[%d].x=%d ScreenOrigins[%d].y=%d \n",
+ local->name, i, priv->screenTopX[i], i, priv->screenTopY[i]));
+ }
+#else /* WCM_HAVE_DIXSCREENORIGINS */
+ if (i > 0)
+ {
+ /* only support left to right in this case */
+ priv->screenTopX[i] = priv->screenBottomX[i-1];
+ priv->screenTopY[i] = 0;
+ priv->screenBottomX[i] = priv->screenTopX[i];
+ priv->screenBottomY[i] = 0;
+ }
+#endif /* WCM_HAVE_DIXSCREENORIGINS */
+ priv->screenBottomX[i] += screenInfo.screens[i]->width;
+ priv->screenBottomY[i] += screenInfo.screens[i]->height;
+
+ DBG(10, priv->debugLevel, ErrorF("xf86WcmInitialScreens for \"%s\" "
+ "topX[%d]=%d topY[%d]=%d bottomX[%d]=%d bottomY[%d]=%d \n",
+ local->name, i, priv->screenTopX[i], i, priv->screenTopY[i],
+ i, priv->screenBottomX[i], i, priv->screenBottomY[i]));
+ }
+}
+
+/*****************************************************************************
+ * xf86WcmChangeScreen
+ ****************************************************************************/
+
+void xf86WcmChangeScreen(LocalDevicePtr local, int value)
+{
+ WacomDevicePtr priv = (WacomDevicePtr)local->private;
+
+ if (priv->screen_no != value)
+ {
+ priv->screen_no = value;
+ xf86ReplaceIntOption(local->options, "ScreenNo", value);
+ }
+
+ if (priv->screen_no != -1)
+ priv->currentScreen = priv->screen_no;
+ xf86WcmInitialScreens(local);
+ xf86WcmInitialCoordinates(local, 0);
+ xf86WcmInitialCoordinates(local, 1);
+}
+
+/*****************************************************************************
+ * rotateOneTool
+ ****************************************************************************/
+
+static void rotateOneTool(WacomDevicePtr priv)
+{
+ WacomCommonPtr common = priv->common;
+ WacomToolAreaPtr area = priv->toolarea;
+ int tmpTopX, tmpTopY, tmpBottomX, tmpBottomY, oldMaxX, oldMaxY;
+
+ DBG(10, priv->debugLevel, ErrorF("rotateOneTool for \"%s\" \n", priv->local->name));
+
+ oldMaxX = common->wcmMaxX;
+ oldMaxY = common->wcmMaxY;
+
+ tmpTopX = priv->topX;
+ tmpBottomX = priv->bottomX;
+ tmpTopY = priv->topY;
+ tmpBottomY = priv->bottomY;
+
+ if (common->wcmRotate == ROTATE_CW || common->wcmRotate == ROTATE_CCW)
+ {
+ common->wcmMaxX = oldMaxY;
+ common->wcmMaxY = oldMaxX;
+ }
+
+ switch (common->wcmRotate) {
+ case ROTATE_CW:
+ area->topX = priv->topX = tmpTopY;
+ area->bottomX = priv->bottomX = tmpBottomY;
+ area->topY = priv->topY = oldMaxX - tmpBottomX;
+ area->bottomY = priv->bottomY =oldMaxX - tmpTopX;
+ break;
+ case ROTATE_CCW:
+ area->topX = priv->topX = oldMaxY - tmpBottomY;
+ area->bottomX = priv->bottomX = oldMaxY - tmpTopY;
+ area->topY = priv->topY = tmpTopX;
+ area->bottomY = priv->bottomY = tmpBottomX;
+ break;
+ case ROTATE_HALF:
+ area->topX = priv->topX = oldMaxX - tmpBottomX;
+ area->bottomX = priv->bottomX = oldMaxX - tmpTopX;
+ area->topY = priv->topY= oldMaxY - tmpBottomY;
+ area->bottomY = priv->bottomY = oldMaxY - tmpTopY;
+ break;
+ }
+ xf86WcmInitialCoordinates(priv->local, 0);
+ xf86WcmInitialCoordinates(priv->local, 1);
+
+ if (tmpTopX != priv->topX)
+ xf86ReplaceIntOption(priv->local->options, "TopX", priv->topX);
+ if (tmpTopY != priv->topY)
+ xf86ReplaceIntOption(priv->local->options, "TopY", priv->topY);
+ if (tmpBottomX != priv->bottomX)
+ xf86ReplaceIntOption(priv->local->options, "BottomX", priv->bottomX);
+ if (tmpBottomY != priv->bottomY)
+ xf86ReplaceIntOption(priv->local->options, "BottomY", priv->bottomY);
+}
+
+/*****************************************************************************
+ * xf86WcmRotateTablet
+ ****************************************************************************/
+
+void xf86WcmRotateTablet(LocalDevicePtr local, int value)
+{
+ WacomDevicePtr priv = (WacomDevicePtr)local->private;
+ WacomCommonPtr common = priv->common;
+ WacomDevicePtr tmppriv;
+ int oldRotation;
+ int tmpTopX, tmpTopY, tmpBottomX, tmpBottomY, oldMaxX, oldMaxY;
+
+ DBG(10, priv->debugLevel, ErrorF("xf86WcmRotateTablet for \"%s\" \n", local->name));
+
+ if (common->wcmRotate == value) /* initialization */
+ {
+ rotateOneTool(priv);
+ }
+ else
+ {
+ oldRotation = common->wcmRotate;
+ common->wcmRotate = value;
+
+ /* rotate all devices at once! else they get misaligned */
+ for (tmppriv = common->wcmDevices; tmppriv; tmppriv = tmppriv->next)
+ {
+ oldMaxX = common->wcmMaxX;
+ oldMaxY = common->wcmMaxY;
+
+ if (oldRotation == ROTATE_CW || oldRotation == ROTATE_CCW)
+ {
+ common->wcmMaxX = oldMaxY;
+ common->wcmMaxY = oldMaxX;
+ }
+
+ tmpTopX = tmppriv->topX;
+ tmpBottomX = tmppriv->bottomX;
+ tmpTopY = tmppriv->topY;
+ tmpBottomY = tmppriv->bottomY;
+
+ /* recover to the unrotated xy-rectangles */
+ switch (oldRotation) {
+ case ROTATE_CW:
+ tmppriv->topX = oldMaxY - tmpBottomY;
+ tmppriv->bottomX = oldMaxY - tmpTopY;
+ tmppriv->topY = tmpTopX;
+ tmppriv->bottomY = tmpBottomX;
+ break;
+ case ROTATE_CCW:
+ tmppriv->topX = tmpTopY;
+ tmppriv->bottomX = tmpBottomY;
+ tmppriv->topY = oldMaxX - tmpBottomX;
+ tmppriv->bottomY = oldMaxX - tmpTopX;
+ break;
+ case ROTATE_HALF:
+ tmppriv->topX = oldMaxX - tmpBottomX;
+ tmppriv->bottomX = oldMaxX - tmpTopX;
+ tmppriv->topY = oldMaxY - tmpBottomY;
+ tmppriv->bottomY = oldMaxY - tmpTopY;
+ break;
+ }
+
+ /* and rotate them to the new value */
+ rotateOneTool(tmppriv);
+
+ switch(value) {
+ case ROTATE_NONE:
+ xf86ReplaceStrOption(local->options, "Rotate", "NONE");
+ break;
+ case ROTATE_CW:
+ xf86ReplaceStrOption(local->options, "Rotate", "CW");
+ break;
+ case ROTATE_CCW:
+ xf86ReplaceStrOption(local->options, "Rotate", "CCW");
+ break;
+ case ROTATE_HALF:
+ xf86ReplaceStrOption(local->options, "Rotate", "HALF");
+ break;
+ }
+ }
+ }
+}
+
diff --git a/src/xdrv/wcmSerial.c b/src/xdrv/wcmSerial.c
index 0307614..9b9a1b7 100755
--- a/src/xdrv/wcmSerial.c
+++ b/src/xdrv/wcmSerial.c
@@ -25,7 +25,7 @@
static Bool serialDetect(LocalDevicePtr pDev);
static Bool serialInit(LocalDevicePtr pDev, char* id, float *version);
-static int serialInitTablet(LocalDevicePtr local, char* id, float *version);
+static int serialInitTablet(LocalDevicePtr pDev, char* id, float *version);
static void serialInitIntuos(WacomCommonPtr common, const char* id, float version);
static void serialInitIntuos2(WacomCommonPtr common, const char* id, float version);
static void serialInitCintiq(WacomCommonPtr common, const char* id, float version);
@@ -700,7 +700,7 @@ static int serialParseProtocol5(LocalDevicePtr local, const unsigned char* data)
/* Protocol 5 devices support 2 data channels */
channel = data[0] & 0x01;
- /* pick up where we left off, minus relative values */
+ /* pick up where we left off, minus relative values */
ds = &common->wcmChannel[channel].work;
RESET_RELATIVE(*ds);
@@ -1269,9 +1269,7 @@ static void serialParseP4Common(LocalDevicePtr local,
(ds->device_type == ERASER_ID))
{
/* send a prox-out for old device */
- WacomDeviceState out = { 0 };
- out.device_type = ERASER_ID;
- xf86WcmEvent(common, 0, &out);
+ xf86WcmSoftOut(common, 0);
ds->device_type = cur_type;
}
}
diff --git a/src/xdrv/wcmTouchFilter.c b/src/xdrv/wcmTouchFilter.c
new file mode 100644
index 0000000..23971a3
--- /dev/null
+++ b/src/xdrv/wcmTouchFilter.c
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2009 by Ping Cheng, Wacom Technology. <pingc@wacom.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "xf86Wacom.h"
+#include <math.h>
+
+// Defines for 2FC Gesture
+#define WACOM_DIST_IN_POINT 300
+#define WACOM_APART_IN_POINT 350
+#define WACOM_MOTION_IN_POINT 50
+#define WACOM_PARA_MOTION_IN_POINT 50
+#define WACOM_DOWN_TIME_IN_MS 800
+#define WACOM_TIME_BETWEEN_IN_MS 400
+#define WACOM_HORIZ_ALLOWED 1
+#define WACOM_VERT_ALLOWED 2
+
+#define GESTURE_TAP_MODE 1
+#define GESTURE_SCROLL_MODE 2
+#define GESTURE_ZOOM_MODE 4
+
+
+// Defines for Tap Add-a-Finger to Click
+#define WACOM_TAP_TIME_IN_MS 150
+
+extern void xf86WcmRotateCoordinates(LocalDevicePtr local, int x, int y);
+extern void emitKeysym (DeviceIntPtr keydev, int keysym, int state);
+
+static void xf86WcmFingerScroll(WacomDevicePtr priv);
+static void xf86WcmFingerZoom(WacomDevicePtr priv);
+
+static double touchDistance(WacomDeviceState ds0, WacomDeviceState ds1)
+{
+ int xDelta = ds0.x - ds1.x;
+ int yDelta = ds0.y - ds1.y;
+ double distance = sqrt((double)(xDelta*xDelta + yDelta*yDelta));
+ return distance;
+}
+
+static Bool pointsInLine(WacomDeviceState ds0, WacomDeviceState ds1, int *direction)
+{
+ Bool ret = FALSE;
+
+ if (*direction == 0)
+ {
+ if ( abs(ds0.x - ds1.x) < WACOM_PARA_MOTION_IN_POINT)
+ {
+ *direction = WACOM_VERT_ALLOWED;
+ ret = TRUE;
+ }
+ else if (abs(ds0.y - ds1.y) < WACOM_PARA_MOTION_IN_POINT)
+ {
+ *direction = WACOM_HORIZ_ALLOWED;
+ ret = TRUE;
+ }
+ }
+ else if (*direction == WACOM_HORIZ_ALLOWED)
+ {
+ if ( abs(ds0.y - ds1.y) < WACOM_PARA_MOTION_IN_POINT)
+ ret = TRUE;
+ }
+ else if (*direction == WACOM_VERT_ALLOWED)
+ {
+ if ( abs(ds0.x - ds1.x) < WACOM_PARA_MOTION_IN_POINT)
+ ret = TRUE;
+ }
+ return ret;
+}
+
+static Bool pointsInLineAfter(int p1, int p2)
+{
+ Bool ret = FALSE;
+
+ if ( abs(p1 - p2) < WACOM_PARA_MOTION_IN_POINT)
+ ret = TRUE;
+
+ return ret;
+}
+
+static void xf86WcmSwitchLeftClick(WacomDevicePtr priv)
+{
+ WacomCommonPtr common = priv->common;
+
+ if (common->wcmGestureMode)
+ {
+ /* send button one up */
+ xf86PostButtonEvent(priv->local->dev,
+ priv->flags & ABSOLUTE_FLAG,
+ 1,0,0,priv->naxes, priv->oldX,
+ priv->oldY,0,0,0,0);
+ priv->oldButtons = 0;
+ }
+}
+
+/*****************************************************************************
+ * xf86WcmFingerTapToClick --
+ * translate second finger tap to right click
+ ****************************************************************************/
+
+void xf86WcmFingerTapToClick(WacomCommonPtr common)
+{
+ WacomDevicePtr priv = common->wcmDevices;
+ WacomChannelPtr firstChannel = common->wcmChannel;
+ WacomChannelPtr secondChannel = common->wcmChannel + 1;
+ WacomDeviceState ds[2] = { firstChannel->valid.states[0],
+ secondChannel->valid.states[0] };
+ WacomDeviceState dsLast[2] = { firstChannel->valid.states[1],
+ secondChannel->valid.states[1] };
+ int direction = 0;
+
+ DBG(10, priv->debugLevel, ErrorF("xf86WcmFingerTapToClick \n"));
+
+ /* skip initial second finger event */
+ if (!dsLast[1].proximity) goto skipGesture;
+
+ if (!IsTouch(priv))
+ {
+ /* go through the shared port */
+ for (; priv; priv = priv->next)
+ {
+ if (IsTouch(priv))
+ break;
+ }
+ }
+
+ if (priv) /* found the first finger */
+ {
+ /* allow only second finger tap */
+ if ((dsLast[0].sample < dsLast[1].sample) && ((GetTimeInMillis() -
+ dsLast[1].sample) <= WACOM_TAP_TIME_IN_MS))
+ {
+ /* send right click when second finger taps within WACOM_TAP_TIMEms
+ * and both fingers stay within WACOM_DIST */
+ if (!ds[1].proximity && dsLast[1].proximity)
+ {
+ if (touchDistance(ds[0], dsLast[1]) <= WACOM_DIST_IN_POINT)
+ {
+ /* send left up before sending right down */
+ if (!common->wcmGestureMode)
+ xf86WcmSwitchLeftClick(priv);
+ common->wcmGestureMode = GESTURE_TAP_MODE;
+
+ /* right button down */
+ xf86PostButtonEvent(priv->local->dev,
+ priv->flags & ABSOLUTE_FLAG,
+ 3,1,0,priv->naxes, priv->oldX,
+ priv->oldY,0,0,0,0);
+ /* right button up */
+ xf86PostButtonEvent(priv->local->dev,
+ priv->flags & ABSOLUTE_FLAG,
+ 3,0,0,priv->naxes, priv->oldX,
+ priv->oldY,0,0,0,0);
+ }
+ }
+ }
+ else if ((WACOM_TAP_TIME_IN_MS < (GetTimeInMillis() - dsLast[0].sample)) &&
+ (WACOM_TAP_TIME_IN_MS < (GetTimeInMillis() - dsLast[1].sample))
+ && ds[0].proximity && ds[1].proximity)
+ {
+ if (abs(touchDistance(ds[0], ds[1])) >= WACOM_APART_IN_POINT &&
+ common->wcmGestureMode != GESTURE_TAP_MODE &&
+ common->wcmGestureMode != GESTURE_SCROLL_MODE)
+ {
+ /* fingers moved apart more than WACOM_APART_IN_POINT
+ * zoom mode is entered */
+ if (!common->wcmGestureMode)
+ xf86WcmSwitchLeftClick(priv);
+ common->wcmGestureMode = GESTURE_ZOOM_MODE;
+ xf86WcmFingerZoom(priv);
+ }
+
+ if ( pointsInLine(ds[0], dsLast[0], &direction) &&
+ pointsInLine(ds[1], dsLast[1], &direction) &&
+ common->wcmGestureMode != GESTURE_ZOOM_MODE &&
+ common->wcmGestureMode != GESTURE_TAP_MODE)
+ {
+ /* send scroll event when both fingers move in
+ * the same direction */
+ if (!common->wcmGestureMode)
+ xf86WcmSwitchLeftClick(priv);
+ common->wcmGestureMode = GESTURE_SCROLL_MODE;
+ xf86WcmFingerScroll(priv);
+ }
+ }
+ }
+ else
+ /* this should never happen */
+ xf86Msg(X_ERROR, "WACOM: No touch device found for %s \n", common->wcmDevice);
+skipGesture:
+ /* keep the initial in-prox time */
+ ds[0].sample = dsLast[0].sample;
+ ds[1].sample = dsLast[1].sample;
+
+ /* keep the initial states for both fingers */
+ if ( !(common->wcmGestureMode && (GESTURE_SCROLL_MODE | GESTURE_ZOOM_MODE))
+ && ds[0].proximity && ds[1].proximity)
+ {
+ common->wcmGestureState[0] = ds[0];
+ common->wcmGestureState[1] = ds[1];
+ }
+}
+
+static void xf86WcmSendVerticalScrollEvent(WacomDevicePtr priv, int dist,
+ int buttonUp, int buttonDn)
+{
+ int i = 0;
+
+ for (i=0; i<(int)(((double)abs(dist)/
+ (double)WACOM_MOTION_IN_POINT) + 0.5); i++)
+ {
+ if (dist > 0)
+ {
+ /* button down */
+ xf86PostButtonEvent(priv->local->dev,
+ priv->flags & ABSOLUTE_FLAG,
+ buttonUp,1,0,priv->naxes, priv->oldX,
+ priv->oldY,0,0,0,0);
+ /* button up */
+ xf86PostButtonEvent(priv->local->dev,
+ priv->flags & ABSOLUTE_FLAG,
+ buttonUp,0,0,priv->naxes, priv->oldX,
+ priv->oldY,0,0,0,0);
+ }
+ else
+ {
+ /* button down */
+ xf86PostButtonEvent(priv->local->dev,
+ priv->flags & ABSOLUTE_FLAG,
+ buttonDn,1,0,priv->naxes, priv->oldX,
+ priv->oldY,0,0,0,0);
+ /* button up */
+ xf86PostButtonEvent(priv->local->dev,
+ priv->flags & ABSOLUTE_FLAG,
+ buttonDn,0,0,priv->naxes, priv->oldX,
+ priv->oldY,0,0,0,0);
+ }
+ }
+}
+
+static void xf86WcmSendHorizontalScrollEvent(WacomDevicePtr priv, int dist,
+ int buttonUp, int buttonDn)
+{
+ int i = 0;
+
+ for (i=0; i<(int)(((double)abs(dist)/
+ (double)WACOM_MOTION_IN_POINT) + 0.5); i++)
+ {
+ if (dist > 0)
+ {
+ emitKeysym (priv->local->dev, XK_Left, 1);
+ emitKeysym (priv->local->dev, XK_Left, 0);
+ }
+ else
+ {
+ emitKeysym (priv->local->dev, XK_Right, 1);
+ emitKeysym (priv->local->dev, XK_Right, 0);
+ }
+ }
+}
+
+static void xf86WcmFingerScroll(WacomDevicePtr priv)
+{
+ WacomCommonPtr common = priv->common;
+ WacomChannelPtr firstChannel = common->wcmChannel;
+ WacomChannelPtr secondChannel = common->wcmChannel + 1;
+ WacomDeviceState ds[2] = { firstChannel->valid.states[0],
+ secondChannel->valid.states[0] };
+ WacomDeviceState dsLast[2] = { firstChannel->valid.states[1],
+ secondChannel->valid.states[1] };
+ int midPoint_new = 0;
+ int midPoint_old = 0;
+ int i = 0, dist =0;
+ int gesture = 0;
+ WacomFilterState filterd; /* borrow this struct */
+
+ DBG(10, priv->debugLevel, ErrorF("xf86WcmFingerScroll \n"));
+
+ /* initialize the points so we can rotate them */
+ filterd.x[0] = ds[0].x;
+ filterd.y[0] = ds[0].y;
+ filterd.x[1] = ds[1].x;
+ filterd.y[1] = ds[1].y;
+ filterd.x[2] = common->wcmGestureState[0].x;
+ filterd.y[2] = common->wcmGestureState[0].y;
+ filterd.x[3] = common->wcmGestureState[1].x;
+ filterd.y[3] = common->wcmGestureState[1].y;
+ filterd.x[4] = dsLast[0].x;
+ filterd.y[4] = dsLast[0].y;
+ filterd.x[5] = dsLast[1].x;
+ filterd.y[5] = dsLast[1].y;
+
+ /* rotate the coordinates first */
+ for (i=0; i<6; i++)
+ xf86WcmRotateCoordinates(priv->local, filterd.x[i], filterd.y[i]);
+
+ /* check vertical direction */
+ midPoint_old = (((double)filterd.x[4] + (double)filterd.x[5]) / 2.);
+ midPoint_new = (((double)filterd.x[0] + (double)filterd.x[1]) / 2.);
+ if (pointsInLineAfter(midPoint_old, midPoint_new))
+ {
+ midPoint_old = (((double)filterd.y[2] + (double)filterd.y[3]) / 2.);
+ midPoint_new = (((double)filterd.y[0] + (double)filterd.y[1]) / 2.);
+ dist = midPoint_old - midPoint_new;
+
+ if (abs(dist) > WACOM_PARA_MOTION_IN_POINT)
+ {
+ gesture = 1;
+ xf86WcmSendVerticalScrollEvent(priv, dist, SCROLL_UP, SCROLL_DOWN);
+ }
+
+ /* check horizontal direction */
+ if (!gesture)
+ {
+ midPoint_old = (((double)filterd.y[4] + (double)filterd.y[5]) / 2.);
+ midPoint_new = (((double)filterd.y[0] + (double)filterd.y[1]) / 2.);
+ if (pointsInLineAfter(midPoint_old, midPoint_new))
+ {
+ midPoint_old = (((double)filterd.x[2] + (double)filterd.x[3]) / 2.);
+ midPoint_new = (((double)filterd.x[0] + (double)filterd.x[1]) / 2.);
+ dist = midPoint_old - midPoint_new;
+
+ if (abs(dist) > WACOM_PARA_MOTION_IN_POINT)
+ {
+ gesture = 1;
+ xf86WcmSendHorizontalScrollEvent(priv, dist, SCROLL_RIGHT, SCROLL_LEFT);
+ }
+ }
+ }
+ if (gesture)
+ {
+ /* reset initial states */
+ common->wcmGestureState[0] = ds[0];
+ common->wcmGestureState[1] = ds[1];
+ }
+ }
+}
+
+static void xf86WcmFingerZoom(WacomDevicePtr priv)
+{
+ WacomCommonPtr common = priv->common;
+ WacomChannelPtr firstChannel = common->wcmChannel;
+ WacomChannelPtr secondChannel = common->wcmChannel + 1;
+ WacomDeviceState ds[2] = { firstChannel->valid.states[0],
+ secondChannel->valid.states[0] };
+ int i = 0;
+ int dist = touchDistance(common->wcmGestureState[0], common->wcmGestureState[1]);
+
+ DBG(10, priv->debugLevel, ErrorF("xf86WcmFingerZoom \n"));
+
+ dist = touchDistance(ds[0], ds[1]) - dist;
+
+ /* zooming? */
+ if (abs(dist) > WACOM_MOTION_IN_POINT)
+ {
+ for (i=0; i<(int)(((double)abs(dist)/
+ (double)WACOM_MOTION_IN_POINT) + 0.5); i++)
+ {
+ emitKeysym (priv->local->dev, XK_Control_L, 1);
+ /* zooming in */
+ if (dist > 0)
+ {
+ emitKeysym (priv->local->dev, XK_plus, 1);
+ emitKeysym (priv->local->dev, XK_plus, 0);
+ }
+ else /* zooming out */
+ {
+ emitKeysym (priv->local->dev, XK_minus, 1);
+ emitKeysym (priv->local->dev, XK_minus, 0);
+ }
+ emitKeysym (priv->local->dev, XK_Control_L, 0);
+ }
+
+ /* reset initial states */
+ common->wcmGestureState[0] = ds[0];
+ common->wcmGestureState[1] = ds[1];
+ }
+}
+
diff --git a/src/xdrv/wcmUSB.c b/src/xdrv/wcmUSB.c
index 904aa64..cb0a81d 100755
--- a/src/xdrv/wcmUSB.c
+++ b/src/xdrv/wcmUSB.c
@@ -49,7 +49,7 @@ static int usbParse(LocalDevicePtr local, const unsigned char* data);
static int usbDetectConfig(LocalDevicePtr local);
static void usbParseEvent(LocalDevicePtr local,
const struct input_event* event);
-static void usbParseChannel(LocalDevicePtr local, int channel, int serial);
+static void usbParseChannel(LocalDevicePtr local, int channel);
WacomDeviceClass gWacomUSBDevice =
{
@@ -398,12 +398,6 @@ static Bool usbDetect(LocalDevicePtr local)
/*****************************************************************************
* wcmusbInit --
****************************************************************************/
-#define BIT(x) (1<<((x) & (BITS_PER_LONG - 1)))
-#define BITS_PER_LONG (sizeof(long) * 8)
-#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
-#define ISBITSET(x,y) ((x)[LONG(y)] & BIT(y))
-#define OFF(x) ((x)%BITS_PER_LONG)
-#define LONG(x) ((x)/BITS_PER_LONG)
/* Key codes used to mark tablet buttons -- must be in sync
* with the keycode array in wacom.c kernel driver.
@@ -548,13 +542,14 @@ Bool usbWcmInit(LocalDevicePtr local, char* id, float *version)
{
/* GestureDefault was off for all devices */
/* except when multi-touch is supported */
- common->wcmGestureDefault = 0;
+ common->wcmGestureDefault = 1;
/* check if gesture was turned off in xorg.conf */
common->wcmGesture = xf86SetBoolOption(local->options,
"Gesture", common->wcmGestureDefault);
if ( common->wcmTouch && common->wcmGesture )
- xf86Msg(X_CONFIG, "%s: Touch Gesture is enabled \n", common->wcmDevice);
+ xf86Msg(X_CONFIG, "%s: "
+ "Touch Gesture is enabled \n", common->wcmDevice);
}
}
@@ -686,11 +681,11 @@ int usbWcmGetRanges(LocalDevicePtr local)
common->wcmMaxY = absinfo.maximum;
/* max finger strip X for tablets with Expresskeys
- * or touch logical X for TabletPCs with touch */
+ * or touch physical X for TabletPCs with touch */
if (ioctl(local->fd, EVIOCGABS(ABS_RX), &absinfo) == 0)
{
if (common->wcmTouchDefault)
- common->wcmMaxTouchX = absinfo.maximum;
+ common->wcmResolX = absinfo.maximum;
else
common->wcmMaxStripX = absinfo.maximum;
@@ -698,45 +693,22 @@ int usbWcmGetRanges(LocalDevicePtr local)
local->name, absinfo.maximum));
}
- /* max finger strip y for tablets with Expresskeys
- * or touch logical Y for TabletPCs with touch */
+ /* max finger strip y for tablets with Expresskeys
+ * or touch physical Y for TabletPCs with touch */
if (ioctl(local->fd, EVIOCGABS(ABS_RY), &absinfo) == 0)
{
if (common->wcmTouchDefault)
- common->wcmMaxTouchY = absinfo.maximum;
+ common->wcmResolY = absinfo.maximum;
else
common->wcmMaxStripY = absinfo.maximum;
}
- /* touch physical X for TabletPCs with touch */
- if (ioctl(local->fd, EVIOCGABS(ABS_Z), &absinfo) == 0)
+ if (common->wcmTouchDefault && common->wcmMaxX && common->wcmResolX)
{
- if (common->wcmTouchDefault)
- common->wcmTouchResolX = absinfo.maximum;
- }
-
- /* touch physical Y for TabletPCs with touch */
- if (ioctl(local->fd, EVIOCGABS(ABS_RZ), &absinfo) == 0)
- {
- if (common->wcmTouchDefault)
- common->wcmTouchResolY = absinfo.maximum;
- }
-
- if (common->wcmTouchDefault && common->wcmTouchResolX)
- {
- common->wcmTouchResolX = (int)(((double)common->wcmTouchResolX)
- / ((double)common->wcmMaxTouchX) + 0.5);
- common->wcmTouchResolY = (int)(((double)common->wcmTouchResolY)
- / ((double)common->wcmMaxTouchY) + 0.5);
-
- if (!common->wcmTouchResolX || !common->wcmTouchResolY)
- {
- ErrorF("WACOM: touch resolution value(s) was wrong resX"
- " = %d resY = %d.\n", common->wcmTouchResolX,
- common->wcmTouchResolY);
- return !Success;
- }
-
+ common->wcmResolX = (int)(((double)common->wcmResolX)
+ / ((double)common->wcmMaxX) + 0.5);
+ common->wcmResolY = (int)(((double)common->wcmResolY)
+ / ((double)common->wcmMaxY) + 0.5);
}
/* max z cannot be configured */
@@ -795,10 +767,89 @@ static int usbParse(LocalDevicePtr local, const unsigned char* data)
return common->wcmPktLength;
}
-static void usbParseEvent(LocalDevicePtr local,
- const struct input_event* event)
+
+static int usbChooseChannel(WacomCommonPtr common, int serial)
{
- int i, channel;
+ /* figure out the channel to use based on serial number */
+ int i, channel = -1;
+ if (common->wcmProtocolLevel == 4)
+ {
+ /* Protocol 4 doesn't support tool serial numbers */
+ if (serial == 0xf0)
+ channel = 1;
+ else
+ channel = 0;
+ }
+ else if (serial) /* serial number should never be 0 for V5 devices */
+ {
+ /* dual input is supported */
+ if ( strstr(common->wcmModel->name, "Intuos1") || strstr(common->wcmModel->name, "Intuos2") )
+ {
+ /* find existing channel */
+ for (i=0; i<MAX_CHANNELS; ++i)
+ {
+ if (common->wcmChannel[i].work.proximity &&
+ common->wcmChannel[i].work.serial_num == serial)
+ {
+ channel = i;
+ break;
+ }
+ }
+
+ /* find an empty channel */
+ if (channel < 0)
+ {
+ for (i=0; i<MAX_CHANNELS; ++i)
+ {
+ if (!common->wcmChannel[i].work.proximity)
+ {
+ channel = i;
+ break;
+ }
+ }
+ }
+ }
+ else /* one transducer plus expresskey (pad) is supported */
+ {
+ if (serial == -1) /* pad */
+ channel = 1;
+ else if ( (common->wcmChannel[0].work.proximity && /* existing transducer */
+ (common->wcmChannel[0].work.serial_num == serial)) ||
+ !common->wcmChannel[0].work.proximity ) /* new transducer */
+ channel = 0;
+ }
+ }
+
+ /* fresh out of channels */
+ if (channel < 0)
+ {
+ /* This should never happen in normal use.
+ * Let's start over again. Force prox-out for all channels.
+ */
+ for (i=0; i<MAX_CHANNELS; ++i)
+ {
+ if (common->wcmChannel[i].work.proximity &&
+ (common->wcmChannel[i].work.serial_num != -1))
+ {
+ common->wcmChannel[i].work.proximity = 0;
+ /* dispatch event */
+ xf86WcmEvent(common, i, &common->wcmChannel[i].work);
+ }
+ }
+ DBG(1, common->debugLevel, ErrorF("usbParse (device with serial number: %u)"
+ " at %d: Exceeded channel count; ignoring the events.\n",
+ serial, (int)GetTimeInMillis()));
+ }
+ else
+ common->wcmLastToolSerial = serial;
+
+ return channel;
+}
+
+static void usbParseEvent(LocalDevicePtr local,
+ const struct input_event* event)
+{
+ int channel;
WacomDevicePtr priv = (WacomDevicePtr)local->private;
WacomCommonPtr common = priv->common;
@@ -829,8 +880,7 @@ static void usbParseEvent(LocalDevicePtr local,
goto skipEvent;
}
- /* save the serial number so we can look up the channel number later */
- common->wcmLastToolSerial = event->value;
+ common->wcmLastToolSerial = event->value;
/* if SYN_REPORT is end of record indicator, we are done */
if (USE_SYN_REPORTS(common))
@@ -858,86 +908,18 @@ static void usbParseEvent(LocalDevicePtr local,
return;
}
- /* figure out the channel to use based on serial number */
- channel = -1;
- if (common->wcmProtocolLevel == 4)
+ /* ignore events without information */
+ if (common->wcmEventCnt <= 2)
{
- /* Protocol 4 doesn't support tool serial numbers */
- if (common->wcmLastToolSerial == 0xf0)
- channel = 1;
- else
- channel = 0;
+ DBG(3, common->debugLevel, ErrorF("%s - usbParse: dropping empty event for serial %d\n",
+ local->name, common->wcmLastToolSerial));
+ goto skipEvent;
}
- else if (common->wcmLastToolSerial) /* serial number should never be 0 */
- {
- /* ignore events without information */
- if (common->wcmEventCnt <= 2)
- {
- DBG(3, common->debugLevel, ErrorF("%s - usbParse: dropping empty event for serial %d\n",
- local->name, common->wcmLastToolSerial));
- goto skipEvent;
- }
- /* dual input is supported */
- if ( strstr(common->wcmModel->name, "Intuos1") || strstr(common->wcmModel->name, "Intuos2") )
- {
- /* find existing channel */
- for (i=0; i<MAX_CHANNELS; ++i)
- {
- if (common->wcmChannel[i].work.proximity &&
- common->wcmChannel[i].work.serial_num == common->wcmLastToolSerial)
- {
- channel = i;
- break;
- }
- }
-
- /* find an empty channel */
- if (channel < 0)
- {
- for (i=0; i<MAX_CHANNELS; ++i)
- {
- if (!common->wcmChannel[i].work.proximity)
- {
- channel = i;
- break;
- }
- }
- }
- }
- else /* one transducer plus expresskey (pad) is supported */
- {
- if (common->wcmLastToolSerial == -1) /* pad */
- channel = 1;
- else if ( (common->wcmChannel[0].work.proximity && /* existing transducer */
- (common->wcmChannel[0].work.serial_num == common->wcmLastToolSerial)) ||
- !common->wcmChannel[0].work.proximity ) /* new transducer */
- channel = 0;
- }
- }
- else
- goto skipEvent;
+ channel = usbChooseChannel(common, common->wcmLastToolSerial);
- /* fresh out of channels */
- if (channel < 0)
- {
- /* This should never happen in normal use.
- * Let's start over again. Force prox-out for all channels.
- */
- for (i=0; i<MAX_CHANNELS; ++i)
- {
- if (common->wcmChannel[i].work.proximity && (common->wcmChannel[i].work.serial_num != -1))
- {
- common->wcmChannel[i].work.proximity = 0;
- /* dispatch event */
- xf86WcmEvent(common, i, &common->wcmChannel[i].work);
- }
- }
- DBG(1, common->debugLevel, ErrorF("usbParse (%s with serial number: %u) at %d: Exceeded channel count; "
- "ignoring the events.\n", local->name, common->wcmLastToolSerial,
- (int)GetTimeInMillis()));
- goto skipEvent;
- }
+ /* couldn't decide channel? invalid data */
+ if (channel == -1) goto skipEvent;
if (!common->wcmChannel[channel].work.proximity)
{
@@ -947,14 +929,14 @@ static void usbParseEvent(LocalDevicePtr local,
}
/* dispatch event */
- usbParseChannel(local,channel,common->wcmLastToolSerial);
+ usbParseChannel(local, channel);
skipEvent:
common->wcmLastToolSerial = 0;
common->wcmEventCnt = 0;
}
-static void usbParseChannel(LocalDevicePtr local, int channel, int serial)
+static void usbParseChannel(LocalDevicePtr local, int channel)
{
int i, shift, nkeys;
WacomDeviceState* ds;
@@ -977,7 +959,7 @@ static void usbParseChannel(LocalDevicePtr local, int channel, int serial)
/* all USB data operates from previous context except relative values*/
ds = &common->wcmChannel[channel].work;
ds->relwheel = 0;
- ds->serial_num = serial;
+ ds->serial_num = common->wcmLastToolSerial;
/* loop through all events in group */
for (i=0; i<common->wcmEventCnt; ++i)
@@ -1035,7 +1017,9 @@ static void usbParseChannel(LocalDevicePtr local, int channel, int serial)
(event->code == BTN_TOOL_AIRBRUSH))
{
ds->device_type = STYLUS_ID;
- ds->device_id = STYLUS_DEVICE_ID;
+ /* V5 tools use ABS_MISC to report device_id */
+ if (common->wcmProtocolLevel == 4)
+ ds->device_id = STYLUS_DEVICE_ID;
ds->proximity = (event->value != 0);
DBG(6, common->debugLevel, ErrorF(
"USB stylus detected %x\n",
@@ -1044,7 +1028,9 @@ static void usbParseChannel(LocalDevicePtr local, int channel, int serial)
else if (event->code == BTN_TOOL_RUBBER)
{
ds->device_type = ERASER_ID;
- ds->device_id = ERASER_DEVICE_ID;
+ /* V5 tools use ABS_MISC to report device_id */
+ if (common->wcmProtocolLevel == 4)
+ ds->device_id = ERASER_DEVICE_ID;
ds->proximity = (event->value != 0);
if (ds->proximity)
ds->proximity = ERASER_PROX;
@@ -1059,7 +1045,9 @@ static void usbParseChannel(LocalDevicePtr local, int channel, int serial)
"USB mouse detected %x (value=%d)\n",
event->code, event->value));
ds->device_type = CURSOR_ID;
- ds->device_id = CURSOR_DEVICE_ID;
+ /* V5 tools use ABS_MISC to report device_id */
+ if (common->wcmProtocolLevel == 4)
+ ds->device_id = CURSOR_DEVICE_ID;
ds->proximity = (event->value != 0);
}
else if (event->code == BTN_TOOL_FINGER)
@@ -1073,12 +1061,18 @@ static void usbParseChannel(LocalDevicePtr local, int channel, int serial)
}
else if (event->code == BTN_TOOL_DOUBLETAP)
{
+ WacomChannelPtr pChannel = common->wcmChannel + channel;
+ WacomDeviceState dslast = pChannel->valid.state;
DBG(6, common->debugLevel, ErrorF(
"USB Touch detected %x (value=%d)\n",
event->code, event->value));
ds->device_type = TOUCH_ID;
ds->device_id = TOUCH_DEVICE_ID;
ds->proximity = event->value;
+ /* time stamp for 2GT gesture events */
+ if ((ds->proximity && !dslast.proximity) ||
+ (!ds->proximity && dslast.proximity))
+ ds->sample = (int)GetTimeInMillis();
/* Left button is always pressed for touch without capacity
* when the first finger touch event received.
* For touch with capacity enabled, left button event will be decided
@@ -1089,13 +1083,20 @@ static void usbParseChannel(LocalDevicePtr local, int channel, int serial)
}
else if (event->code == BTN_TOOL_TRIPLETAP)
{
+ WacomChannelPtr pChannel = common->wcmChannel + channel;
+ WacomDeviceState dslast = pChannel->valid.state;
DBG(6, common->debugLevel, ErrorF(
"USB Touch second finger detected %x (value=%d)\n",
event->code, event->value));
ds->device_type = TOUCH_ID;
ds->device_id = TOUCH_DEVICE_ID;
ds->proximity = event->value;
- /* Second finger events will be combined with the first finger data */
+ /* time stamp for 2GT gesture events */
+ if ((ds->proximity && !dslast.proximity) ||
+ (!ds->proximity && dslast.proximity))
+ ds->sample = (int)GetTimeInMillis();
+ /* Second finger events will be considered in
+ * combination with the first finger data */
}
else if ((event->code == BTN_STYLUS) ||
(event->code == BTN_MIDDLE))
diff --git a/src/xdrv/wcmValidateDevice.c b/src/xdrv/wcmValidateDevice.c
new file mode 100755
index 0000000..34114f2
--- /dev/null
+++ b/src/xdrv/wcmValidateDevice.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2009 by Ping Cheng, Wacom. <pingc@wacom.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "xf86Wacom.h"
+#include "wcmFilter.h"
+#ifdef WCM_XORG_XSERVER_1_4
+ #ifndef _XF86_ANSIC_H
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #endif
+
+/*****************************************************************************
+ * xf86WcmCheckTypeAndSource - Check if both devices have the same type OR
+ * the device has been used in xorg.conf: don't add the tool by hal/udev
+ * if user has defined at least one tool for the device in xorg.conf
+ ****************************************************************************/
+static Bool xf86WcmCheckTypeAndSource(LocalDevicePtr fakeLocal, LocalDevicePtr pLocal)
+{
+ int match = 1;
+ char* fsource = xf86CheckStrOption(fakeLocal->options, "_source", "");
+ char* psource = xf86CheckStrOption(pLocal->options, "_source", "");
+ char* type = xf86FindOptionValue(fakeLocal->options, "Type");
+ WacomDevicePtr priv = (WacomDevicePtr) pLocal->private;
+
+ /* only add the new tool if the matching major/minor
+ * was from the same source */
+ if (!strcmp(fsource, psource))
+ {
+ /* and the tools have different types */
+ if (strcmp(type, xf86FindOptionValue(pLocal->options, "Type")))
+ match = 0;
+ }
+ DBG(2, priv->debugLevel, xf86Msg(X_INFO, "xf86WcmCheckTypeAndSource "
+ "device %s from %s %s \n", fakeLocal->name, fsource,
+ match ? "will be added" : "will be ignored"));
+ return match;
+}
+
+/* check if the device has been added */
+int wcmIsDuplicate(char* device, LocalDevicePtr local)
+{
+#ifdef _XF86_ANSIC_H
+ struct xf86stat st;
+#else
+ struct stat st;
+#endif
+ int isInUse = 0;
+ LocalDevicePtr localDevices = NULL;
+ WacomCommonPtr common = NULL;
+
+ /* open the port */
+ do {
+ SYSCALL(local->fd = open(device, O_RDONLY, 0));
+ } while (local->fd < 0 && errno == EINTR);
+
+ if (local->fd < 0)
+ {
+ /* can not open the device */
+ xf86Msg(X_ERROR, "Unable to open Wacom device \"%s\".\n", device);
+ isInUse = 2;
+ goto ret;
+ }
+
+#ifdef _XF86_ANSIC_H
+ if (xf86fstat(local->fd, &st) == -1)
+#else
+ if (fstat(local->fd, &st) == -1)
+#endif
+ {
+ /* can not access major/minor to check device duplication */
+ xf86Msg(X_ERROR, "%s: stat failed (%s). cannot check for duplicates.\n",
+ local->name, strerror(errno));
+
+ /* older systems don't support the required ioctl. let it pass */
+ goto ret;
+ }
+
+ if ((int)st.st_rdev)
+ {
+ localDevices = xf86FirstLocalDevice();
+
+ for (; localDevices != NULL; localDevices = localDevices->next)
+ {
+ device = xf86CheckStrOption(localDevices->options, "Device", NULL);
+
+ /* device can be NULL on some distros */
+ if (!device || !strstr(localDevices->drv->driverName, "wacom"))
+ continue;
+
+ common = ((WacomDevicePtr)localDevices->private)->common;
+ if (local != localDevices &&
+ common->min_maj &&
+ common->min_maj == st.st_rdev)
+ {
+ /* device matches with another added port */
+ if (xf86WcmCheckTypeAndSource(local, localDevices))
+ {
+ xf86Msg(X_WARNING, "%s: device file already in use by %s. "
+ "Ignoring.\n", local->name, localDevices->name);
+ isInUse = 4;
+ goto ret;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* major/minor can never be 0, right? */
+ xf86Msg(X_ERROR, "%s: device opened with a major/minor of 0. "
+ "Something was wrong.\n", local->name);
+ isInUse = 5;
+ }
+ret:
+ if (local->fd >= 0)
+ {
+ close(local->fd);
+ local->fd = -1;
+ }
+ return isInUse;
+}
+
+static struct
+{
+ __u16 productID;
+ __u16 flags;
+} validType [] =
+{
+ { 0x00, STYLUS_ID }, /* PenPartner */
+ { 0x10, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Graphire */
+ { 0x11, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Graphire2 4x5 */
+ { 0x12, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Graphire2 5x7 */
+
+ { 0x13, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Graphire3 4x5 */
+ { 0x14, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Graphire3 6x8 */
+
+ { 0x15, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Graphire4 4x5 */
+ { 0x16, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Graphire4 6x8 */
+ { 0x17, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* BambooFun 4x5 */
+ { 0x18, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* BambooFun 6x8 */
+ { 0x19, STYLUS_ID | ERASER_ID }, /* Bamboo1 Medium*/
+ { 0x81, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Graphire4 6x8 BlueTooth */
+
+ { 0x20, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos 4x5 */
+ { 0x21, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos 6x8 */
+ { 0x22, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos 9x12 */
+ { 0x23, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos 12x12 */
+ { 0x24, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos 12x18 */
+
+ { 0x03, STYLUS_ID | ERASER_ID }, /* PTU600 */
+ { 0x30, STYLUS_ID | ERASER_ID }, /* PL400 */
+ { 0x31, STYLUS_ID | ERASER_ID }, /* PL500 */
+ { 0x32, STYLUS_ID | ERASER_ID }, /* PL600 */
+ { 0x33, STYLUS_ID | ERASER_ID }, /* PL600SX */
+ { 0x34, STYLUS_ID | ERASER_ID }, /* PL550 */
+ { 0x35, STYLUS_ID | ERASER_ID }, /* PL800 */
+ { 0x37, STYLUS_ID | ERASER_ID }, /* PL700 */
+ { 0x38, STYLUS_ID | ERASER_ID }, /* PL510 */
+ { 0x39, STYLUS_ID | ERASER_ID }, /* PL710 */
+ { 0xC0, STYLUS_ID }, /* DTF720 */
+ { 0xC2, STYLUS_ID }, /* DTF720a */
+ { 0xC4, STYLUS_ID | ERASER_ID }, /* DTF521 */
+ { 0xC7, STYLUS_ID | ERASER_ID }, /* DTU1931 */
+
+ { 0x41, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos2 4x5 */
+ { 0x42, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos2 6x8 */
+ { 0x43, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos2 9x12 */
+ { 0x44, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos2 12x12 */
+ { 0x45, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos2 12x18 */
+ { 0x47, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos2 6x8 */
+
+ { 0x60, STYLUS_ID }, /* Volito */
+ { 0x61, STYLUS_ID }, /* PenStation */
+ { 0x62, STYLUS_ID }, /* Volito2 4x5 */
+ { 0x63, STYLUS_ID }, /* Volito2 2x3 */
+ { 0x64, STYLUS_ID }, /* PenPartner2 */
+
+ { 0x65, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Bamboo */
+ { 0x69, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Bamboo1 */
+
+ { 0xB0, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos3 4x5 */
+ { 0xB1, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos3 6x8 */
+ { 0xB2, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos3 9x12 */
+ { 0xB3, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos3 12x12 */
+ { 0xB4, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos3 12x19 */
+ { 0xB5, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos3 6x11 */
+ { 0xB7, STYLUS_ID | ERASER_ID | CURSOR_ID }, /* Intuos3 4x6 */
+
+ { 0xB8, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Intuos4 4x6 */
+ { 0xB9, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Intuos4 6x9 */
+ { 0xBA, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Intuos4 8x13 */
+ { 0xBB, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Intuos4 12x19*/
+
+ { 0x3F, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Cintiq 21UX */
+ { 0xC5, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Cintiq 20WSX */
+ { 0xC6, STYLUS_ID | ERASER_ID | CURSOR_ID | PAD_ID }, /* Cintiq 12WX */
+
+ { 0x90, STYLUS_ID | ERASER_ID }, /* TabletPC 0x90 */
+ { 0x93, STYLUS_ID | ERASER_ID | TOUCH_ID }, /* TabletPC 0x93 */
+ { 0x9A, STYLUS_ID | ERASER_ID | TOUCH_ID }, /* TabletPC 0x9A */
+ { 0x9F, TOUCH_ID }, /* CapPlus 0x9F */
+ { 0xE2, TOUCH_ID }, /* TabletPC 0xE2 */
+ { 0xE3, STYLUS_ID | ERASER_ID | TOUCH_ID } /* TabletPC 0xE3 */
+};
+
+static struct
+{
+ const char* type;
+ __u16 id;
+} wcmTypeAndID [] =
+{
+ { "stylus", STYLUS_ID },
+ { "eraser", ERASER_ID },
+ { "cursor", CURSOR_ID },
+ { "touch", TOUCH_ID },
+ { "pad", PAD_ID }
+};
+
+static Bool checkValidType(char* type, unsigned short id)
+{
+ int i, j, ret = FALSE;
+
+ /* walkthrough all supported models */
+ for (i = 0; i < sizeof (validType) / sizeof (validType [0]); i++)
+ {
+ if (validType[i].productID == id)
+ {
+ /* walkthrough all types */
+ for (j = 0; j < sizeof (wcmTypeAndID) / sizeof (wcmTypeAndID [0]); j++)
+ if (!strcmp(wcmTypeAndID[j].type, type))
+ if (wcmTypeAndID[j].id & validType[i].flags)
+ ret = TRUE;
+ }
+ }
+ return ret;
+}
+
+static Bool aTouchPort(char* device)
+{
+ int fd = -1;
+ unsigned long keys[NBITS(KEY_MAX)];
+
+ SYSCALL(fd = open(device, O_RDONLY));
+ if (fd < 0)
+ return FALSE;
+
+ /* test if BTN_TOOL_DOUBLETAP set or not for touch device */
+ if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keys)), keys) < 0)
+ {
+ xf86Msg(X_ERROR, "WACOM: aTouchPort unable to ioctl key bits.\n");
+ return FALSE;
+ }
+ close(fd);
+
+ /* BTN_TOOL_DOUBLETAP is used to define touch tools */
+ if (ISBITSET (keys, BTN_TOOL_DOUBLETAP))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/* validate tool type for device/product */
+Bool wcmIsAValidType(char* device, LocalDevicePtr local, unsigned short id)
+{
+ Bool ret = FALSE;
+ char* type = xf86FindOptionValue(local->options, "Type");
+
+ /* touch tool has its own port.
+ * we need to distinguish it from the others first */
+ if (checkValidType("touch", id))
+ {
+ if (aTouchPort(device))
+ {
+ if (strstr(type, "touch"))
+ return TRUE;
+ else
+ return FALSE;
+ }
+ else
+ {
+ if (strstr(type, "touch"))
+ return FALSE;
+ }
+ }
+
+ /* not a touch tool or touch is not support forthe id */
+ ret = checkValidType(type, id);
+
+ return ret;
+}
+#endif /* WCM_XORG_XSERVER_1_4 */
+
diff --git a/src/xdrv/wcmXCommand.c b/src/xdrv/wcmXCommand.c
index 96e98a7..54fa4ce 100644
--- a/src/xdrv/wcmXCommand.c
+++ b/src/xdrv/wcmXCommand.c
@@ -33,9 +33,9 @@
#include "xf86Wacom.h"
#include "wcmFilter.h"
+extern void xf86WcmChangeScreen(LocalDevicePtr local, int value);
extern void xf86WcmInitialCoordinates(LocalDevicePtr local, int axes);
extern void xf86WcmRotateTablet(LocalDevicePtr local, int value);
-extern void xf86WcmInitialScreens(LocalDevicePtr local);
/*****************************************************************************
* xf86WcmSetPadCoreMode
@@ -122,27 +122,6 @@ int xf86WcmDevSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode)
}
/*****************************************************************************
- * xf86WcmChangeScreen
- ****************************************************************************/
-
-void xf86WcmChangeScreen(LocalDevicePtr local, int value)
-{
- WacomDevicePtr priv = (WacomDevicePtr)local->private;
-
- if (priv->screen_no != value)
- {
- priv->screen_no = value;
- xf86ReplaceIntOption(local->options, "ScreenNo", value);
- }
-
- if (priv->screen_no != -1)
- priv->currentScreen = priv->screen_no;
- xf86WcmInitialScreens(local);
- xf86WcmInitialCoordinates(local, 0);
- xf86WcmInitialCoordinates(local, 1);
-}
-
-/*****************************************************************************
* xf86WcmSetParam
****************************************************************************/
@@ -345,8 +324,8 @@ static int xf86WcmSetParam(LocalDevicePtr local, int param, int value)
case XWACOM_PARAM_XYDEFAULT:
xf86WcmSetParam (local, XWACOM_PARAM_TOPX, 0);
xf86WcmSetParam (local, XWACOM_PARAM_TOPY, 0);
- xf86WcmSetParam (local, XWACOM_PARAM_BOTTOMX, priv->wcmMaxX);
- xf86WcmSetParam (local, XWACOM_PARAM_BOTTOMY, priv->wcmMaxY);
+ xf86WcmSetParam (local, XWACOM_PARAM_BOTTOMX, common->wcmMaxX);
+ xf86WcmSetParam (local, XWACOM_PARAM_BOTTOMY, common->wcmMaxY);
break;
case XWACOM_PARAM_MMT:
if ((value != 0) && (value != 1))
@@ -979,9 +958,9 @@ static int xf86WcmGetDefaultParam(LocalDevicePtr local, int param)
case XWACOM_PARAM_TOPY:
return 0;
case XWACOM_PARAM_BOTTOMX:
- return priv->wcmMaxX;
+ return common->wcmMaxX;
case XWACOM_PARAM_BOTTOMY:
- return priv->wcmMaxY;
+ return common->wcmMaxY;
case XWACOM_PARAM_BUTTON1:
case XWACOM_PARAM_BUTTON2:
case XWACOM_PARAM_BUTTON3:
diff --git a/src/xdrv/xf86Wacom.c b/src/xdrv/xf86Wacom.c
index 10e6c09..e930ecf 100755
--- a/src/xdrv/xf86Wacom.c
+++ b/src/xdrv/xf86Wacom.c
@@ -85,17 +85,18 @@
* 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
*/
-static const char identification[] = "$Identification: 47-0.8.5-1 $";
+static const char identification[] = "$Identification: 47-0.8.5-2 $";
/****************************************************************************/
#include "xf86Wacom.h"
#include "wcmFilter.h"
#ifdef WCM_XORG_XSERVER_1_4
- #include <fcntl.h>
#ifndef _XF86_ANSIC_H
+ #include <fcntl.h>
#include <sys/stat.h>
#endif
#endif
@@ -114,7 +115,7 @@ extern int usbWcmGetRanges(LocalDevicePtr local);
extern int xf86WcmDevChangeControl(LocalDevicePtr local, xDeviceCtl* control);
extern int xf86WcmDevSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode);
extern void xf86WcmRotateTablet(LocalDevicePtr local, int value);
-extern void xf86WcmInitialScreens(LocalDevicePtr local);
+extern int xf86WcmInitArea(LocalDevicePtr local);
WacomModule gWacomModule =
{
@@ -143,259 +144,7 @@ static void xf86WcmBellCallback(int pct, DeviceIntPtr di, pointer ctrl, int x)
static void xf86WcmKbdCtrlCallback(DeviceIntPtr di, KeybdCtrl* ctrl)
{
}
-#endif /* WCM_KEY_SENDING_SUPPORT */
-
-/*****************************************************************************
- * xf86WcmDesktopSize --
- * calculate the whole desktop size
- ****************************************************************************/
-static void xf86WcmDesktopSize(LocalDevicePtr local)
-{
- WacomDevicePtr priv = (WacomDevicePtr) local->private;
- int i = 0, minX = 0, minY = 0, maxX = 0, maxY = 0;
-
- xf86WcmInitialScreens(local);
-
- minX = priv->screenTopX[0];
- minY = priv->screenTopY[0];
- maxX = priv->screenBottomX[0];
- maxY = priv->screenBottomY[0];
-
- if (priv->numScreen != 1)
- {
- for (i = 1; i < priv->numScreen; i++)
- {
- if (priv->screenTopX[i] < minX)
- minX = priv->screenTopX[i];
- if (priv->screenTopY[i] < minY)
- minY = priv->screenTopY[i];
- if (priv->screenBottomX[i] > maxX)
- maxX = priv->screenBottomX[i];
- if (priv->screenBottomY[i] > maxY)
- maxY = priv->screenBottomY[i];
- }
- }
-
- priv->maxWidth = maxX - minX;
- priv->maxHeight = maxY - minY;
-}
-
-static int xf86WcmInitArea(LocalDevicePtr local)
-{
- WacomDevicePtr priv = (WacomDevicePtr)local->private;
- WacomToolAreaPtr area = priv->toolarea, inlist;
- WacomCommonPtr common = priv->common;
- double screenRatio, tabletRatio;
-
- DBG(10, priv->debugLevel, ErrorF("xf86WcmInitArea\n"));
-
- /* Verify Box */
- if (priv->topX > priv->wcmMaxX)
- {
- area->topX = priv->topX = 0;
- }
-
- if (priv->topY > priv->wcmMaxY)
- {
- area->topY = priv->topY = 0;
- }
-
- /* set unconfigured bottom to max */
- priv->bottomX = xf86SetIntOption(local->options, "BottomX", 0);
- if (priv->bottomX < priv->topX || !priv->bottomX)
- {
- area->bottomX = priv->bottomX = priv->wcmMaxX;
- }
-
- /* set unconfigured bottom to max */
- priv->bottomY = xf86SetIntOption(local->options, "BottomY", 0);
- if (priv->bottomY < priv->topY || !priv->bottomY)
- {
- area->bottomY = priv->bottomY = priv->wcmMaxY;
- }
-
- if (priv->twinview > TV_XINERAMA)
- priv->numScreen = 2;
-
- if (priv->screen_no != -1 &&
- (priv->screen_no >= priv->numScreen || priv->screen_no < 0))
- {
- if (priv->twinview <= TV_XINERAMA)
- {
- ErrorF("%s: invalid screen number %d, resetting to default (-1) \n",
- local->name, priv->screen_no);
- priv->screen_no = -1;
- }
- else if (priv->screen_no > 1)
- {
- ErrorF("%s: invalid screen number %d, resetting to default (-1) \n",
- local->name, priv->screen_no);
- priv->screen_no = -1;
- }
- }
-
- /* need maxWidth and maxHeight for keepshape */
- xf86WcmDesktopSize(local);
-
- /* Maintain aspect ratio to the whole desktop
- * May need to consider a specific screen in multimonitor settings
- */
- if (priv->flags & KEEP_SHAPE_FLAG)
- {
-
- screenRatio = ((double)priv->maxWidth / (double)priv->maxHeight);
- tabletRatio = ((double)(priv->wcmMaxX - priv->topX) /
- (double)(priv->wcmMaxY - priv->topY));
-
- DBG(2, priv->debugLevel, ErrorF("screenRatio = %.3g, "
- "tabletRatio = %.3g\n", screenRatio, tabletRatio));
-
- if (screenRatio > tabletRatio)
- {
- area->bottomX = priv->bottomX = priv->wcmMaxX;
- area->bottomY = priv->bottomY = (priv->wcmMaxY - priv->topY) *
- tabletRatio / screenRatio + priv->topY;
- }
- else
- {
- area->bottomX = priv->bottomX = (priv->wcmMaxX - priv->topX) *
- screenRatio / tabletRatio + priv->topX;
- area->bottomY = priv->bottomY = priv->wcmMaxY;
- }
- }
- /* end keep shape */
-
- inlist = priv->tool->arealist;
-
- /* The first one in the list is always valid */
- if (area != inlist && xf86WcmAreaListOverlap(area, inlist))
- {
- inlist = priv->tool->arealist;
-
- /* remove this overlapped area from the list */
- for (; inlist; inlist=inlist->next)
- {
- if (inlist->next == area)
- {
- inlist->next = area->next;
- xfree(area);
- priv->toolarea = NULL;
- break;
- }
- }
-
- /* Remove this device from the common struct */
- if (common->wcmDevices == priv)
- common->wcmDevices = priv->next;
- else
- {
- WacomDevicePtr tmp = common->wcmDevices;
- while(tmp->next && tmp->next != priv)
- tmp = tmp->next;
- if(tmp)
- tmp->next = priv->next;
- }
- xf86Msg(X_ERROR, "%s: Top/Bottom area overlaps with another devices.\n",
- local->conf_idev->identifier);
- return FALSE;
- }
- return TRUE;
-}
-
-/*****************************************************************************
- * xf86WcmVirtaulTabletSize(LocalDevicePtr local)
- ****************************************************************************/
-
-void xf86WcmVirtaulTabletSize(LocalDevicePtr local)
-{
- WacomDevicePtr priv = (WacomDevicePtr)local->private;
-
- if (!(priv->flags & ABSOLUTE_FLAG))
- {
- priv->sizeX = priv->bottomX - priv->topX;
- priv->sizeY = priv->bottomY - priv->topY;
- return;
- }
-
- priv->sizeX = priv->bottomX - priv->topX - priv->tvoffsetX;
- priv->sizeY = priv->bottomY - priv->topY - priv->tvoffsetY;
-
- DBG(10, priv->debugLevel, ErrorF("xf86WcmVirtaulTabletSize for \"%s\" "
- "x=%d y=%d \n", local->name, priv->sizeX, priv->sizeY));
- return;
-}
-
-/*****************************************************************************
- * xf86WcmInitialCoordinates
- ****************************************************************************/
-void xf86WcmInitialCoordinates(LocalDevicePtr local, int axes)
-{
- WacomDevicePtr priv = (WacomDevicePtr)local->private;
- int topx = 0, topy = 0, resolution;
- int bottomx = priv->wcmMaxX, bottomy = priv->wcmMaxY;
-
- xf86WcmMappingFactor(local);
-
- /* x ax */
- if ( !axes )
- {
- if (priv->flags & ABSOLUTE_FLAG)
- {
- topx = priv->topX;
- bottomx = priv->sizeX + priv->topX;
- if ((priv->currentScreen == 1) && (priv->twinview > TV_XINERAMA))
- topx += priv->tvoffsetX;
- if ((priv->currentScreen == 0) && (priv->twinview > TV_XINERAMA))
- bottomx -= priv->tvoffsetX;
- }
-
- resolution = priv->wcmResolX;
-#ifdef WCM_XORG_TABLET_SCALING
- /* Ugly hack for Xorg 7.3, which doesn't call xf86WcmDevConvert
- * for coordinate conversion at the moment */
- topx = 0;
- bottomx = priv->sizeX;
- if ((priv->twinview == TV_LEFT_RIGHT) || (priv->twinview == TV_RIGHT_LEFT))
- bottomx *= 2;
- bottomx = (int)((double)bottomx * priv->factorX + 0.5);
- resolution = (int)((double)resolution * priv->factorX + 0.5);
-#endif
-
- InitValuatorAxisStruct(local->dev, 0, topx, bottomx,
- resolution, 0, resolution);
- }
- else /* y ax */
- {
- if (priv->flags & ABSOLUTE_FLAG)
- {
- topy = priv->topY;
- bottomy = priv->sizeY + priv->topY;
- if ((priv->currentScreen == 1) && (priv->twinview > TV_XINERAMA))
- topy += priv->tvoffsetY;
- if ((priv->currentScreen == 0) && (priv->twinview > TV_XINERAMA))
- bottomy -= priv->tvoffsetY;
- }
-
- resolution = priv->wcmResolY;
-#ifdef WCM_XORG_TABLET_SCALING
- /* Ugly hack for Xorg 7.3, which doesn't call xf86WcmDevConvert
- * for coordinate conversion at the moment */
- topy = 0;
- bottomy = priv->sizeY;
- if ((priv->twinview == TV_ABOVE_BELOW) || (priv->twinview == TV_BELOW_ABOVE))
- bottomy *= 2;
- bottomy = (int)((double)bottomy * priv->factorY + 0.5);
- resolution = (int)((double)resolution * priv->factorY + 0.5);
-#endif
-
- InitValuatorAxisStruct(local->dev, 1, topy, bottomy,
- resolution, 0, resolution);
- }
- return;
-}
-
-#ifdef WCM_KEY_SENDING_SUPPORT
/*****************************************************************************
* xf86WcmRegisterX11Devices --
* Register the X11 input devices with X11 core.
@@ -557,25 +306,10 @@ static void xf86WcmInitialToolSize(LocalDevicePtr local)
WacomToolPtr toollist = common->wcmTool;
WacomToolAreaPtr arealist;
- if (IsTouch(priv))
- {
- priv->wcmMaxX = common->wcmMaxTouchX;
- priv->wcmMaxY = common->wcmMaxTouchY;
- priv->wcmResolX = common->wcmTouchResolX;
- priv->wcmResolY = common->wcmTouchResolY;
- }
- else
- {
- priv->wcmMaxX = common->wcmMaxX;
- priv->wcmMaxY = common->wcmMaxY;
- priv->wcmResolX = common->wcmResolX;
- priv->wcmResolY = common->wcmResolY;
- }
-
- DBG(2, common->debugLevel, ErrorF("Wacom \"%s\" "
+ DBG(2, priv->debugLevel, ErrorF("Wacom \"%s\" "
"max X=%d max Y=%d resol X=%d resol Y=%d\n",
local->name, common->wcmMaxX, common->wcmMaxY,
- priv->wcmResolX, priv->wcmResolY));
+ common->wcmResolX, common->wcmResolY));
for (; toollist; toollist=toollist->next)
@@ -584,13 +318,13 @@ static void xf86WcmInitialToolSize(LocalDevicePtr local)
for (; arealist; arealist=arealist->next)
{
if (!arealist->bottomX)
- arealist->bottomX = priv->wcmMaxX;
+ arealist->bottomX = common->wcmMaxX;
if (!arealist->bottomY)
- arealist->bottomY = priv->wcmMaxY;
+ arealist->bottomY = common->wcmMaxY;
}
}
- DBG(2, common->debugLevel, ErrorF("Wacom device \"%s\" "
+ DBG(2, priv->debugLevel, ErrorF("Wacom device \"%s\" "
"top X=%d top Y=%d bottom X=%d bottom Y=%d \n",
local->name, priv->topX, priv->topY,
priv->bottomX, priv->bottomY));
@@ -813,7 +547,7 @@ Bool xf86WcmIsWacomDevice (char* fname, struct input_id* id)
{
int fd = -1;
- fd = open(fname, O_RDONLY);
+ SYSCALL(fd = open(fname, O_RDONLY));
if (fd < 0)
return FALSE;
diff --git a/src/xdrv/xf86Wacom.h b/src/xdrv/xf86Wacom.h
index 742f638..7d03a3a 100755
--- a/src/xdrv/xf86Wacom.h
+++ b/src/xdrv/xf86Wacom.h
@@ -233,5 +233,11 @@ int xf86WcmSetPadCoreMode(LocalDevicePtr local);
/* calculate the proper tablet to screen mapping factor */
void xf86WcmMappingFactor(LocalDevicePtr local);
+/* send a soft prox-out event for local */
+void xf86WcmSoftOutEvent(LocalDevicePtr local);
+
+/* send a soft prox-out event for device at the channel */
+void xf86WcmSoftOut(WacomCommonPtr common, int channel);
+
/****************************************************************************/
#endif /* __XF86WACOM_H */
diff --git a/src/xdrv/xf86WacomDefs.h b/src/xdrv/xf86WacomDefs.h
index 833bf70..f2c26a3 100755
--- a/src/xdrv/xf86WacomDefs.h
+++ b/src/xdrv/xf86WacomDefs.h
@@ -24,9 +24,17 @@
* General Defines
****************************************************************************/
#ifdef WCM_ENABLE_LINUXINPUT
-#include <asm/types.h>
-#include <linux/input.h>
-#define MAX_USB_EVENTS 32
+ #include <asm/types.h>
+ #include <linux/input.h>
+ #define MAX_USB_EVENTS 32
+
+ /* for access TOOL, BTN, and key codes of USB tablets */
+ #define BIT(x) (1<<((x) & (BITS_PER_LONG - 1)))
+ #define BITS_PER_LONG (sizeof(long) * 8)
+ #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
+ #define ISBITSET(x,y) ((x)[LONG(y)] & BIT(y))
+ #define OFF(x) ((x)%BITS_PER_LONG)
+ #define LONG(x) ((x)/BITS_PER_LONG)
#endif /* WCM_ENABLE_LINUXINPUT */
#define DEFAULT_SPEED 1.0 /* default relative cursor speed */
@@ -140,6 +148,11 @@ struct _WacomModel
* tablet buttons besides the strips are
* treated as buttons */
+#define SCROLL_UP 5 /* absolute/relative wheel/strip up event */
+#define SCROLL_DOWN 4 /* absolute/relative wheel/strip down event */
+#define SCROLL_LEFT 7 /* scroll left event for gesture */
+#define SCROLL_RIGHT 6 /* scroll right event for gesture */
+
struct _WacomDeviceRec
{
/* configuration fields */
@@ -154,10 +167,6 @@ struct _WacomDeviceRec
int bottomY; /* Y bottom */
int sizeX; /* active X size */
int sizeY; /* active Y size */
- int wcmMaxX; /* max tool logical X value */
- int wcmMaxY; /* max tool logical Y value */
- int wcmResolX; /* tool X resolution in points/inch */
- int wcmResolY; /* tool Y resolution in points/inch */
double factorX; /* X factor */
double factorY; /* Y factor */
unsigned int serial; /* device serial number */
@@ -306,10 +315,6 @@ struct _WacomChannel
/* the following struct contains the current known state of the
* device channel, as well as the previous MAX_SAMPLES states
* for use in detecting hardware defects, jitter, trends, etc. */
-
- /* the following union contains the current known state of the
- * device channel, as well as the previous MAX_SAMPLES states
- * for use in detecting hardware defects, jitter, trends, etc. */
union
{
WacomDeviceState state; /* current state */
@@ -355,6 +360,7 @@ struct _WacomDeviceClass
#define DEVICE_ISDV4 0x000C
#define MAX_CHANNELS 2
+#define MAX_FINGERS 2
struct _WacomCommonRec
{
@@ -366,16 +372,11 @@ struct _WacomCommonRec
int fd_refs; /* number of references to fd; if =0, fd is invalid */
dev_t min_maj; /* minor/major number */
- /* These values are in tablet coordinates */
- int wcmMaxX; /* tablet logical max X value */
- int wcmMaxY; /* tablet logical max Y value */
+ int wcmMaxX; /* max tool logical X value */
+ int wcmMaxY; /* max tool logical Y value */
+ int wcmResolX; /* tool X resolution in points/inch */
+ int wcmResolY; /* tool Y resolution in points/inch */
int wcmMaxZ; /* tablet max Z value */
- int wcmMaxTouchX; /* touch panel logical max X value */
- int wcmMaxTouchY; /* touch panel logical max Y value */
- int wcmResolX; /* pen tool X resolution in points/inch */
- int wcmResolY; /* pen tool Y resolution in points/inch */
- int wcmTouchResolX; /* touch X resolution in points/mm */
- int wcmTouchResolY; /* touch Y resolution in points/mm */
/* tablet Z resolution is equivalent
* to wcmMaxZ which is equal to 100% pressure */
int wcmMaxCapacity; /* max capacity value */
@@ -409,21 +410,23 @@ struct _WacomCommonRec
WacomDeviceClassPtr wcmDevCls; /* device class functions */
WacomModelPtr wcmModel; /* model-specific functions */
- char * wcmEraserID; /* eraser associated with the stylus */
- int wcmTPCButton; /* set Tablet PC button on/off */
- int wcmTouch; /* disable/enable touch event */
- int wcmTPCButtonDefault; /* Tablet PC button default */
- int wcmTouchDefault; /* default touch to disable when not supported */
- int wcmGesture; /* disable/enable touch gesture */
- int wcmGestureDefault; /* default touch gesture to disable when not supported */
- int wcmCapacity; /* disable/enable capacity */
- int wcmCapacityDefault; /* default to -1 when capacity isn't supported/disabled */
- /* 3 when capacity is supported */
- int wcmMaxCursorDist; /* Max mouse distance reported so far */
- int wcmCursorProxoutDist; /* Max mouse distance for proxy-out max/256 units */
+ char * wcmEraserID; /* eraser associated with the stylus */
+ int wcmTPCButton; /* set Tablet PC button on/off */
+ int wcmTouch; /* disable/enable touch event */
+ int wcmTPCButtonDefault; /* Tablet PC button default */
+ int wcmTouchDefault; /* default touch to disable when not supported */
+ int wcmGestureMode; /* data is in Gesture Mode? */
+ WacomDeviceState wcmGestureState[MAX_FINGERS]; /* inital state when in gesture mode */
+ int wcmGesture; /* disable/enable touch gesture */
+ int wcmGestureDefault; /* default touch gesture to disable when not supported */
+ int wcmCapacity; /* disable/enable capacity */
+ int wcmCapacityDefault; /* default to -1 when capacity isn't supported/disabled */
+ /* 3 when capacity is supported */
+ int wcmMaxCursorDist; /* Max mouse distance reported so far */
+ int wcmCursorProxoutDist; /* Max mouse distance for proxy-out max/256 units */
int wcmCursorProxoutDistDefault; /* Default max mouse distance for proxy-out */
int wcmSuppress; /* transmit position on delta > supress */
- int wcmRawSample; /* Number of raw data used to filter an event */
+ int wcmRawSample; /* Number of raw data used to filter an event */
int bufpos; /* position with buffer */
unsigned char buffer[BUFFER_SIZE]; /* data read from device */