Skip to content

Commit 8947b0c

Browse files
jigpuJiri Kosina
authored andcommitted
HID: wacom: Support "in range" for Intuos/Bamboo tablets where possible
The 1st-generation Intuos tablets (CTL-X80) include an "in range" flag like some professional tablets. To ensure the pen remains usable at as large as distance as possible (and to preemptively disable touch when it is nearby) we need to ensure that we handle these "in range" events. Handling of tool type identification has been moved to occur only when the pen is fully in prox rather than any time the "stylus_in_proximity" flag changes (which is controlled by the further-out "in range" flag). Link: https://sourceforge.net/p/linuxwacom/bugs/358/ Link: linuxwacom/xf86-input-wacom#14 Link: linuxwacom/xf86-input-wacom#17 Signed-off-by: Jason Gerecke <[email protected]> Tested-by: Ping Cheng <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 008464a commit 8947b0c

File tree

1 file changed

+39
-35
lines changed

1 file changed

+39
-35
lines changed

drivers/hid/wacom_wac.c

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2894,41 +2894,41 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
28942894
struct wacom_features *features = &wacom->features;
28952895
struct input_dev *input = wacom->pen_input;
28962896
unsigned char *data = wacom->data;
2897-
int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0;
2897+
int x = 0, y = 0, p = 0, d = 0;
2898+
bool pen = false, btn1 = false, btn2 = false;
2899+
bool range, prox, rdy;
28982900

28992901
if (data[0] != WACOM_REPORT_PENABLED)
29002902
return 0;
29012903

2902-
prox = (data[1] & 0x20) == 0x20;
2904+
range = (data[1] & 0x80) == 0x80;
2905+
prox = (data[1] & 0x40) == 0x40;
2906+
rdy = (data[1] & 0x20) == 0x20;
2907+
2908+
wacom->shared->stylus_in_proximity = range;
2909+
if (delay_pen_events(wacom))
2910+
return 0;
2911+
2912+
if (rdy) {
2913+
p = le16_to_cpup((__le16 *)&data[6]);
2914+
pen = data[1] & 0x01;
2915+
btn1 = data[1] & 0x02;
2916+
btn2 = data[1] & 0x04;
2917+
}
2918+
if (prox) {
2919+
x = le16_to_cpup((__le16 *)&data[2]);
2920+
y = le16_to_cpup((__le16 *)&data[4]);
29032921

2904-
/*
2905-
* All reports shared between PEN and RUBBER tool must be
2906-
* forced to a known starting value (zero) when transitioning to
2907-
* out-of-prox.
2908-
*
2909-
* If not reset then, to userspace, it will look like lost events
2910-
* if new tool comes in-prox with same values as previous tool sent.
2911-
*
2912-
* Hardware does report zero in most out-of-prox cases but not all.
2913-
*/
2914-
if (!wacom->shared->stylus_in_proximity) {
29152922
if (data[1] & 0x08) {
29162923
wacom->tool[0] = BTN_TOOL_RUBBER;
29172924
wacom->id[0] = ERASER_DEVICE_ID;
29182925
} else {
29192926
wacom->tool[0] = BTN_TOOL_PEN;
29202927
wacom->id[0] = STYLUS_DEVICE_ID;
29212928
}
2929+
wacom->reporting_data = true;
29222930
}
2923-
2924-
wacom->shared->stylus_in_proximity = prox;
2925-
if (delay_pen_events(wacom))
2926-
return 0;
2927-
2928-
if (prox) {
2929-
x = le16_to_cpup((__le16 *)&data[2]);
2930-
y = le16_to_cpup((__le16 *)&data[4]);
2931-
p = le16_to_cpup((__le16 *)&data[6]);
2931+
if (range) {
29322932
/*
29332933
* Convert distance from out prox to distance from tablet.
29342934
* distance will be greater than distance_max once
@@ -2937,25 +2937,29 @@ static int wacom_bpt_pen(struct wacom_wac *wacom)
29372937
*/
29382938
if (data[8] <= features->distance_max)
29392939
d = features->distance_max - data[8];
2940-
2941-
pen = data[1] & 0x01;
2942-
btn1 = data[1] & 0x02;
2943-
btn2 = data[1] & 0x04;
29442940
} else {
29452941
wacom->id[0] = 0;
29462942
}
29472943

2948-
input_report_key(input, BTN_TOUCH, pen);
2949-
input_report_key(input, BTN_STYLUS, btn1);
2950-
input_report_key(input, BTN_STYLUS2, btn2);
2944+
if (wacom->reporting_data) {
2945+
input_report_key(input, BTN_TOUCH, pen);
2946+
input_report_key(input, BTN_STYLUS, btn1);
2947+
input_report_key(input, BTN_STYLUS2, btn2);
29512948

2952-
input_report_abs(input, ABS_X, x);
2953-
input_report_abs(input, ABS_Y, y);
2954-
input_report_abs(input, ABS_PRESSURE, p);
2955-
input_report_abs(input, ABS_DISTANCE, d);
2949+
if (prox || !range) {
2950+
input_report_abs(input, ABS_X, x);
2951+
input_report_abs(input, ABS_Y, y);
2952+
}
2953+
input_report_abs(input, ABS_PRESSURE, p);
2954+
input_report_abs(input, ABS_DISTANCE, d);
29562955

2957-
input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */
2958-
input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */
2956+
input_report_key(input, wacom->tool[0], range); /* PEN or RUBBER */
2957+
input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */
2958+
}
2959+
2960+
if (!range) {
2961+
wacom->reporting_data = false;
2962+
}
29592963

29602964
return 1;
29612965
}

0 commit comments

Comments
 (0)