Thread (3 messages) 3 messages, 1 author, 2021-10-30
STALE1795d REVIEWED: 2 (0M)

2 review trailers.

[PATCH] HID: input: fix the incorrectly reported BTN_TOOL_RUBBER/PEN tools

From: Ping Cheng <hidden>
Date: 2021-10-22 23:29:20
Also in: stable
Subsystem: hid core layer, the rest · Maintainers: Jiri Kosina, Benjamin Tissoires, Linus Torvalds

The HID_QUIRK_INVERT caused BTN_TOOL_RUBBER events were reported at the
same time as events for BTN_TOOL_PEN/PENCIL/etc, if HID_QUIRK_INVERT
was set by a stylus' sideswitch. The reality is that a pen can only be
a stylus (writing/drawing) or an eraser, but not both at the same time.
This patch makes that logic correct.

CC: stable@vger.kernel.org # 2.4+
Signed-off-by: Ping Cheng <ping.cheng@wacom.com>
Reviewed-by: Jason Gerecke <redacted>
Tested-by: Tatsunosuke Tobita <redacted>
---
 drivers/hid/hid-input.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 4b5ebeacd283..85741a2d828d 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1344,12 +1344,28 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
 	}
 
 	if (usage->hid == HID_DG_INRANGE) {
+		/* when HID_QUIRK_INVERT is set by a stylus sideswitch, HID_DG_INRANGE could be
+		 * for stylus or eraser. Make sure events are only posted to the current valid tool:
+		 * BTN_TOOL_RUBBER vs BTN_TOOL_PEN/BTN_TOOL_PENCIL/BTN_TOOL_BRUSH/etc since a pen
+		 * can not be used as a stylus (to draw/write) and an erasaer at the same time
+		 */
+		static unsigned int last_code = 0;
+		unsigned int code = (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code;
 		if (value) {
-			input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1);
-			return;
+			if (code != last_code) {
+				/* send the last tool out before allow the new one in */
+				if (last_code)
+					input_event(input, usage->type, last_code, 0);
+				input_event(input, usage->type, code, 1);
+			}
+			last_code = code;
+		} else {
+			/* only send the last valid tool out */
+			if (last_code)
+				input_event(input, usage->type, last_code, 0);
+			/* reset tool for next cycle */
+			last_code = 0;
 		}
-		input_event(input, usage->type, usage->code, 0);
-		input_event(input, usage->type, BTN_TOOL_RUBBER, 0);
 		return;
 	}
 
-- 
2.25.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help