Skip to content

Commit

Permalink
HID: wacom: Ignore contacts in excess of declared contact count
Browse files Browse the repository at this point in the history
The reports sent from some touch devices (e.g. the Cintiq 24HDT) contain
junk data in the contact slots which follow the final "valid" contact.
To avoid forwarding it to usrspace, we store the reported contact count
during the pre-process phase and then only process that many contacts.
If a device sends its contacts across multiple reports (what Microsoft
refers to as "hybrid" mode) then the contact count will be zero for
reports other than the first.

Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
  • Loading branch information
Jason Gerecke authored and Jiri Kosina committed Jul 23, 2015
1 parent 06324e0 commit 1b5d514
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
30 changes: 29 additions & 1 deletion drivers/hid/wacom_wac.c
Original file line number Diff line number Diff line change
Expand Up @@ -1510,6 +1510,10 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev,
features->last_slot_field = usage->hid;
wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0);
break;
case HID_DG_CONTACTCOUNT:
wacom_wac->hid_data.cc_index = field->index;
wacom_wac->hid_data.cc_value_index = usage->usage_index;
break;
}
}

Expand All @@ -1521,6 +1525,10 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac,
bool prox = hid_data->tipswitch &&
!wacom_wac->shared->stylus_in_proximity;

wacom_wac->hid_data.num_received++;
if (wacom_wac->hid_data.num_received > wacom_wac->hid_data.num_expected)
return;

if (mt) {
int slot;

Expand Down Expand Up @@ -1573,7 +1581,19 @@ static int wacom_wac_finger_event(struct hid_device *hdev,
static void wacom_wac_finger_pre_report(struct hid_device *hdev,
struct hid_report *report)
{
return;
struct wacom *wacom = hid_get_drvdata(hdev);
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
struct hid_data* hid_data = &wacom_wac->hid_data;

if (hid_data->cc_index >= 0) {
struct hid_field *field = report->field[hid_data->cc_index];
int value = field->value[hid_data->cc_value_index];
if (value)
hid_data->num_expected = value;
}
else {
hid_data->num_expected = wacom_wac->features.touch_max;
}
}

static void wacom_wac_finger_report(struct hid_device *hdev,
Expand All @@ -1584,10 +1604,18 @@ static void wacom_wac_finger_report(struct hid_device *hdev,
struct input_dev *input = wacom_wac->touch_input;
unsigned touch_max = wacom_wac->features.touch_max;

/* If more packets of data are expected, give us a chance to
* process them rather than immediately syncing a partial
* update.
*/
if (wacom_wac->hid_data.num_received < wacom_wac->hid_data.num_expected)
return;

if (touch_max > 1)
input_mt_sync_frame(input);

input_sync(input);
wacom_wac->hid_data.num_received = 0;

/* keep touch state for pen event */
wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac);
Expand Down
4 changes: 4 additions & 0 deletions drivers/hid/wacom_wac.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ struct hid_data {
int width;
int height;
int id;
int cc_index;
int cc_value_index;
int num_expected;
int num_received;
};

struct wacom_wac {
Expand Down

0 comments on commit 1b5d514

Please sign in to comment.