|
@@ -581,9 +581,13 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
|
|
|
(features->type == CINTIQ && !(data[1] & 0x40)))
|
|
|
return 1;
|
|
|
|
|
|
- if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
|
|
|
+ if (wacom->shared) {
|
|
|
wacom->shared->stylus_in_proximity = true;
|
|
|
|
|
|
+ if (wacom->shared->touch_down)
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
/* in Range while exiting */
|
|
|
if (((data[1] & 0xfe) == 0x20) && wacom->reporting_data) {
|
|
|
input_report_key(input, BTN_TOUCH, 0);
|
|
@@ -811,6 +815,11 @@ static int wacom_intuos_irq(struct wacom_wac *wacom)
|
|
|
input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4]));
|
|
|
input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6]));
|
|
|
input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8]));
|
|
|
+ if ((data[2] & 0x07) | data[4] | data[5] | data[6] | data[7] | data[8] | data[9]) {
|
|
|
+ input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
|
|
|
+ } else {
|
|
|
+ input_report_abs(input, ABS_MISC, 0);
|
|
|
+ }
|
|
|
} else if (features->type == CINTIQ_HYBRID) {
|
|
|
/*
|
|
|
* Do not send hardware buttons under Android. They
|
|
@@ -1065,27 +1074,28 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
|
|
|
struct input_dev *input = wacom->input;
|
|
|
unsigned char *data = wacom->data;
|
|
|
int i;
|
|
|
- int current_num_contacts = 0;
|
|
|
+ int current_num_contacts = data[61];
|
|
|
int contacts_to_send = 0;
|
|
|
int num_contacts_left = 4; /* maximum contacts per packet */
|
|
|
int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET;
|
|
|
int y_offset = 2;
|
|
|
+ static int contact_with_no_pen_down_count = 0;
|
|
|
|
|
|
if (wacom->features.type == WACOM_27QHDT) {
|
|
|
current_num_contacts = data[63];
|
|
|
num_contacts_left = 10;
|
|
|
byte_per_packet = WACOM_BYTES_PER_QHDTHID_PACKET;
|
|
|
y_offset = 0;
|
|
|
- } else {
|
|
|
- current_num_contacts = data[61];
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* First packet resets the counter since only the first
|
|
|
* packet in series will have non-zero current_num_contacts.
|
|
|
*/
|
|
|
- if (current_num_contacts)
|
|
|
+ if (current_num_contacts) {
|
|
|
wacom->num_contacts_left = current_num_contacts;
|
|
|
+ contact_with_no_pen_down_count = 0;
|
|
|
+ }
|
|
|
|
|
|
contacts_to_send = min(num_contacts_left, wacom->num_contacts_left);
|
|
|
|
|
@@ -1118,15 +1128,16 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
|
|
|
input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h));
|
|
|
input_report_abs(input, ABS_MT_ORIENTATION, w > h);
|
|
|
}
|
|
|
+ contact_with_no_pen_down_count++;
|
|
|
}
|
|
|
}
|
|
|
input_mt_sync_frame(input);
|
|
|
|
|
|
wacom->num_contacts_left -= contacts_to_send;
|
|
|
- if (wacom->num_contacts_left <= 0)
|
|
|
+ if (wacom->num_contacts_left <= 0) {
|
|
|
wacom->num_contacts_left = 0;
|
|
|
-
|
|
|
- wacom->shared->touch_down = (wacom->num_contacts_left > 0);
|
|
|
+ wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
|
|
|
+ }
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
@@ -1138,6 +1149,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom)
|
|
|
int current_num_contacts = data[2];
|
|
|
int contacts_to_send = 0;
|
|
|
int x_offset = 0;
|
|
|
+ static int contact_with_no_pen_down_count = 0;
|
|
|
|
|
|
/* MTTPC does not support Height and Width */
|
|
|
if (wacom->features.type == MTTPC || wacom->features.type == MTTPC_B)
|
|
@@ -1147,8 +1159,10 @@ static int wacom_mt_touch(struct wacom_wac *wacom)
|
|
|
* First packet resets the counter since only the first
|
|
|
* packet in series will have non-zero current_num_contacts.
|
|
|
*/
|
|
|
- if (current_num_contacts)
|
|
|
+ if (current_num_contacts) {
|
|
|
wacom->num_contacts_left = current_num_contacts;
|
|
|
+ contact_with_no_pen_down_count = 0;
|
|
|
+ }
|
|
|
|
|
|
/* There are at most 5 contacts per packet */
|
|
|
contacts_to_send = min(5, wacom->num_contacts_left);
|
|
@@ -1169,15 +1183,16 @@ static int wacom_mt_touch(struct wacom_wac *wacom)
|
|
|
int y = get_unaligned_le16(&data[offset + x_offset + 9]);
|
|
|
input_report_abs(input, ABS_MT_POSITION_X, x);
|
|
|
input_report_abs(input, ABS_MT_POSITION_Y, y);
|
|
|
+ contact_with_no_pen_down_count++;
|
|
|
}
|
|
|
}
|
|
|
input_mt_sync_frame(input);
|
|
|
|
|
|
wacom->num_contacts_left -= contacts_to_send;
|
|
|
- if (wacom->num_contacts_left < 0)
|
|
|
+ if (wacom->num_contacts_left <= 0) {
|
|
|
wacom->num_contacts_left = 0;
|
|
|
-
|
|
|
- wacom->shared->touch_down = (wacom->num_contacts_left > 0);
|
|
|
+ wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
|
|
|
+ }
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
@@ -1215,29 +1230,25 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
|
|
|
{
|
|
|
unsigned char *data = wacom->data;
|
|
|
struct input_dev *input = wacom->input;
|
|
|
- bool prox;
|
|
|
+ bool prox = !wacom->shared->stylus_in_proximity;
|
|
|
int x = 0, y = 0;
|
|
|
|
|
|
if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG)
|
|
|
return 0;
|
|
|
|
|
|
- if (!wacom->shared->stylus_in_proximity) {
|
|
|
- if (len == WACOM_PKGLEN_TPC1FG) {
|
|
|
- prox = data[0] & 0x01;
|
|
|
- x = get_unaligned_le16(&data[1]);
|
|
|
- y = get_unaligned_le16(&data[3]);
|
|
|
- } else if (len == WACOM_PKGLEN_TPC1FG_B) {
|
|
|
- prox = data[2] & 0x01;
|
|
|
- x = get_unaligned_le16(&data[3]);
|
|
|
- y = get_unaligned_le16(&data[5]);
|
|
|
- } else {
|
|
|
- prox = data[1] & 0x01;
|
|
|
- x = le16_to_cpup((__le16 *)&data[2]);
|
|
|
- y = le16_to_cpup((__le16 *)&data[4]);
|
|
|
- }
|
|
|
- } else
|
|
|
- /* force touch out when pen is in prox */
|
|
|
- prox = 0;
|
|
|
+ if (len == WACOM_PKGLEN_TPC1FG) {
|
|
|
+ prox = prox && (data[0] & 0x01);
|
|
|
+ x = get_unaligned_le16(&data[1]);
|
|
|
+ y = get_unaligned_le16(&data[3]);
|
|
|
+ } else if (len == WACOM_PKGLEN_TPC1FG_B) {
|
|
|
+ prox = prox && (data[2] & 0x01);
|
|
|
+ x = get_unaligned_le16(&data[3]);
|
|
|
+ y = get_unaligned_le16(&data[5]);
|
|
|
+ } else {
|
|
|
+ prox = prox && (data[1] & 0x01);
|
|
|
+ x = le16_to_cpup((__le16 *)&data[2]);
|
|
|
+ y = le16_to_cpup((__le16 *)&data[4]);
|
|
|
+ }
|
|
|
|
|
|
if (prox) {
|
|
|
input_report_abs(input, ABS_X, x);
|
|
@@ -1635,6 +1646,7 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
|
|
|
struct input_dev *pad_input = wacom->pad_input;
|
|
|
unsigned char *data = wacom->data;
|
|
|
int i;
|
|
|
+ int contact_with_no_pen_down_count = 0;
|
|
|
|
|
|
if (data[0] != 0x02)
|
|
|
return 0;
|
|
@@ -1662,6 +1674,7 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
|
|
|
}
|
|
|
input_report_abs(input, ABS_MT_POSITION_X, x);
|
|
|
input_report_abs(input, ABS_MT_POSITION_Y, y);
|
|
|
+ contact_with_no_pen_down_count++;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1671,11 +1684,12 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
|
|
|
input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0);
|
|
|
input_report_key(pad_input, BTN_BACK, (data[1] & 0x02) != 0);
|
|
|
input_report_key(pad_input, BTN_RIGHT, (data[1] & 0x01) != 0);
|
|
|
+ wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
|
|
|
+static int wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data, int last_touch_count)
|
|
|
{
|
|
|
struct wacom_features *features = &wacom->features;
|
|
|
struct input_dev *input = wacom->input;
|
|
@@ -1683,7 +1697,7 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
|
|
|
int slot = input_mt_get_slot_by_key(input, data[0]);
|
|
|
|
|
|
if (slot < 0)
|
|
|
- return;
|
|
|
+ return 0;
|
|
|
|
|
|
touch = touch && !wacom->shared->stylus_in_proximity;
|
|
|
|
|
@@ -1715,7 +1729,9 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
|
|
|
input_report_abs(input, ABS_MT_POSITION_Y, y);
|
|
|
input_report_abs(input, ABS_MT_TOUCH_MAJOR, width);
|
|
|
input_report_abs(input, ABS_MT_TOUCH_MINOR, height);
|
|
|
+ last_touch_count++;
|
|
|
}
|
|
|
+ return last_touch_count;
|
|
|
}
|
|
|
|
|
|
static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
|
|
@@ -1740,6 +1756,7 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom)
|
|
|
unsigned char *data = wacom->data;
|
|
|
int count = data[1] & 0x07;
|
|
|
int i;
|
|
|
+ int contact_with_no_pen_down_count = 0;
|
|
|
|
|
|
if (data[0] != 0x02)
|
|
|
return 0;
|
|
@@ -1750,12 +1767,15 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom)
|
|
|
int msg_id = data[offset];
|
|
|
|
|
|
if (msg_id >= 2 && msg_id <= 17)
|
|
|
- wacom_bpt3_touch_msg(wacom, data + offset);
|
|
|
+ contact_with_no_pen_down_count =
|
|
|
+ wacom_bpt3_touch_msg(wacom, data + offset,
|
|
|
+ contact_with_no_pen_down_count);
|
|
|
else if (msg_id == 128)
|
|
|
wacom_bpt3_button_msg(wacom, data + offset);
|
|
|
|
|
|
}
|
|
|
input_mt_sync_frame(input);
|
|
|
+ wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
@@ -1770,6 +1790,9 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
|
|
|
if (data[0] != WACOM_REPORT_PENABLED)
|
|
|
return 0;
|
|
|
|
|
|
+ if (wacom->shared->touch_down)
|
|
|
+ return 0;
|
|
|
+
|
|
|
prox = (data[1] & 0x20) == 0x20;
|
|
|
|
|
|
/*
|
|
@@ -2875,9 +2898,9 @@ static const struct wacom_features wacom_features_0xF6 =
|
|
|
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10,
|
|
|
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
|
|
|
static const struct wacom_features wacom_features_0x32A =
|
|
|
- { "Wacom Cintiq 27QHD", 119740, 67520, 2047,
|
|
|
- 63, WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
|
|
|
- WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
|
|
|
+ { "Wacom Cintiq 27QHD", 119740, 67520, 2047, 63,
|
|
|
+ WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
|
|
|
+ WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
|
|
|
static const struct wacom_features wacom_features_0x32B =
|
|
|
{ "Wacom Cintiq 27QHD touch", 119740, 67520, 2047, 63,
|
|
|
WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
|