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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxx # 2.4+
Signed-off-by: Ping Cheng <ping.cheng@xxxxxxxxx>
Reviewed-by: Jason Gerecke <killertofu@xxxxxxxxx>
Tested-by: Tatsunosuke Tobita <junkpainting@xxxxxxxxx>
---
 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




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux