|
@@ -34,6 +34,10 @@
|
|
|
*/
|
|
|
#define WACOM_CONTACT_AREA_SCALE 2607
|
|
|
|
|
|
+static bool touch_arbitration = 1;
|
|
|
+module_param(touch_arbitration, bool, 0644);
|
|
|
+MODULE_PARM_DESC(touch_arbitration, " on (Y) off (N)");
|
|
|
+
|
|
|
static void wacom_report_numbered_buttons(struct input_dev *input_dev,
|
|
|
int button_count, int mask);
|
|
|
|
|
@@ -882,6 +886,16 @@ static void wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len)
|
|
|
wacom_schedule_work(wacom_wac, WACOM_WORKER_REMOTE);
|
|
|
}
|
|
|
|
|
|
+static inline bool report_touch_events(struct wacom_wac *wacom)
|
|
|
+{
|
|
|
+ return (touch_arbitration ? !wacom->shared->stylus_in_proximity : 1);
|
|
|
+}
|
|
|
+
|
|
|
+static inline bool delay_pen_events(struct wacom_wac *wacom)
|
|
|
+{
|
|
|
+ return (wacom->shared->touch_down && touch_arbitration);
|
|
|
+}
|
|
|
+
|
|
|
static int wacom_intuos_general(struct wacom_wac *wacom)
|
|
|
{
|
|
|
struct wacom_features *features = &wacom->features;
|
|
@@ -895,7 +909,7 @@ static int wacom_intuos_general(struct wacom_wac *wacom)
|
|
|
data[0] != WACOM_REPORT_INTUOS_PEN)
|
|
|
return 0;
|
|
|
|
|
|
- if (wacom->shared->touch_down)
|
|
|
+ if (delay_pen_events(wacom))
|
|
|
return 1;
|
|
|
|
|
|
/* don't report events if we don't know the tool ID */
|
|
@@ -1155,7 +1169,7 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
|
|
|
|
|
|
if (touch_max == 1)
|
|
|
return test_bit(BTN_TOUCH, input->key) &&
|
|
|
- !wacom->shared->stylus_in_proximity;
|
|
|
+ report_touch_events(wacom);
|
|
|
|
|
|
for (i = 0; i < input->mt->num_slots; i++) {
|
|
|
struct input_mt_slot *ps = &input->mt->slots[i];
|
|
@@ -1196,7 +1210,7 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
|
|
|
|
|
|
for (i = 0; i < contacts_to_send; i++) {
|
|
|
int offset = (byte_per_packet * i) + 1;
|
|
|
- bool touch = (data[offset] & 0x1) && !wacom->shared->stylus_in_proximity;
|
|
|
+ bool touch = (data[offset] & 0x1) && report_touch_events(wacom);
|
|
|
int slot = input_mt_get_slot_by_key(input, data[offset + 1]);
|
|
|
|
|
|
if (slot < 0)
|
|
@@ -1260,7 +1274,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom)
|
|
|
|
|
|
for (i = 0; i < contacts_to_send; i++) {
|
|
|
int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3;
|
|
|
- bool touch = (data[offset] & 0x1) && !wacom->shared->stylus_in_proximity;
|
|
|
+ bool touch = (data[offset] & 0x1) && report_touch_events(wacom);
|
|
|
int id = get_unaligned_le16(&data[offset + 1]);
|
|
|
int slot = input_mt_get_slot_by_key(input, id);
|
|
|
|
|
@@ -1294,7 +1308,7 @@ static int wacom_tpc_mt_touch(struct wacom_wac *wacom)
|
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
int p = data[1] & (1 << i);
|
|
|
- bool touch = p && !wacom->shared->stylus_in_proximity;
|
|
|
+ bool touch = p && report_touch_events(wacom);
|
|
|
|
|
|
input_mt_slot(input, i);
|
|
|
input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
|
|
@@ -1318,7 +1332,7 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
|
|
|
{
|
|
|
unsigned char *data = wacom->data;
|
|
|
struct input_dev *input = wacom->touch_input;
|
|
|
- bool prox = !wacom->shared->stylus_in_proximity;
|
|
|
+ bool prox = report_touch_events(wacom);
|
|
|
int x = 0, y = 0;
|
|
|
|
|
|
if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG)
|
|
@@ -1363,8 +1377,10 @@ static int wacom_tpc_pen(struct wacom_wac *wacom)
|
|
|
/* keep pen state for touch events */
|
|
|
wacom->shared->stylus_in_proximity = prox;
|
|
|
|
|
|
- /* send pen events only when touch is up or forced out */
|
|
|
- if (!wacom->shared->touch_down) {
|
|
|
+ /* send pen events only when touch is up or forced out
|
|
|
+ * or touch arbitration is off
|
|
|
+ */
|
|
|
+ if (!delay_pen_events(wacom)) {
|
|
|
input_report_key(input, BTN_STYLUS, data[1] & 0x02);
|
|
|
input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
|
|
|
input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
|
|
@@ -1506,8 +1522,10 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- /* send pen events only when touch is up or forced out */
|
|
|
- if (!usage->type || wacom_wac->shared->touch_down)
|
|
|
+ /* send pen events only when touch is up or forced out
|
|
|
+ * or touch arbitration is off
|
|
|
+ */
|
|
|
+ if (!usage->type || delay_pen_events(wacom_wac))
|
|
|
return 0;
|
|
|
|
|
|
input_event(input, usage->type, usage->code, value);
|
|
@@ -1537,8 +1555,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
|
|
|
/* keep pen state for touch events */
|
|
|
wacom_wac->shared->stylus_in_proximity = prox;
|
|
|
|
|
|
- /* send pen events only when touch is up or forced out */
|
|
|
- if (!wacom_wac->shared->touch_down) {
|
|
|
+ if (!delay_pen_events(wacom_wac)) {
|
|
|
input_report_key(input, BTN_TOUCH,
|
|
|
wacom_wac->hid_data.tipswitch);
|
|
|
input_report_key(input, wacom_wac->tool[0], prox);
|
|
@@ -1609,7 +1626,7 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac,
|
|
|
struct hid_data *hid_data = &wacom_wac->hid_data;
|
|
|
bool mt = wacom_wac->features.touch_max > 1;
|
|
|
bool prox = hid_data->tipswitch &&
|
|
|
- !wacom_wac->shared->stylus_in_proximity;
|
|
|
+ report_touch_events(wacom_wac);
|
|
|
|
|
|
wacom_wac->hid_data.num_received++;
|
|
|
if (wacom_wac->hid_data.num_received > wacom_wac->hid_data.num_expected)
|
|
@@ -1835,15 +1852,8 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
|
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
int offset = (data[1] & 0x80) ? (8 * i) : (9 * i);
|
|
|
- bool touch = data[offset + 3] & 0x80;
|
|
|
-
|
|
|
- /*
|
|
|
- * Touch events need to be disabled while stylus is
|
|
|
- * in proximity because user's hand is resting on touchpad
|
|
|
- * and sending unwanted events. User expects tablet buttons
|
|
|
- * to continue working though.
|
|
|
- */
|
|
|
- touch = touch && !wacom->shared->stylus_in_proximity;
|
|
|
+ bool touch = report_touch_events(wacom)
|
|
|
+ && (data[offset + 3] & 0x80);
|
|
|
|
|
|
input_mt_slot(input, i);
|
|
|
input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
|
|
@@ -1880,7 +1890,7 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
|
|
|
if (slot < 0)
|
|
|
return;
|
|
|
|
|
|
- touch = touch && !wacom->shared->stylus_in_proximity;
|
|
|
+ touch = touch && report_touch_events(wacom);
|
|
|
|
|
|
input_mt_slot(input, slot);
|
|
|
input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
|
|
@@ -1993,7 +2003,7 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
|
|
|
}
|
|
|
|
|
|
wacom->shared->stylus_in_proximity = prox;
|
|
|
- if (wacom->shared->touch_down)
|
|
|
+ if (delay_pen_events(wacom))
|
|
|
return 0;
|
|
|
|
|
|
if (prox) {
|
|
@@ -2087,7 +2097,7 @@ static int wacom_bamboo_pad_touch_event(struct wacom_wac *wacom,
|
|
|
|
|
|
for (id = 0; id < wacom->features.touch_max; id++) {
|
|
|
valid = !!(prefix & BIT(id)) &&
|
|
|
- !wacom->shared->stylus_in_proximity;
|
|
|
+ report_touch_events(wacom);
|
|
|
|
|
|
input_mt_slot(input, id);
|
|
|
input_mt_report_slot_state(input, MT_TOOL_FINGER, valid);
|
|
@@ -2109,8 +2119,7 @@ static int wacom_bamboo_pad_touch_event(struct wacom_wac *wacom,
|
|
|
input_report_key(input, BTN_RIGHT, prefix & 0x80);
|
|
|
|
|
|
/* keep touch state for pen event */
|
|
|
- wacom->shared->touch_down = !!prefix &&
|
|
|
- !wacom->shared->stylus_in_proximity;
|
|
|
+ wacom->shared->touch_down = !!prefix && report_touch_events(wacom);
|
|
|
|
|
|
return 1;
|
|
|
}
|