[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