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 killertofu@gmail.com Tested-by: Tatsunosuke Tobita junkpainting@gmail.com --- 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; }
Hi @Dmitry Torokhov and @Benjamin Tissoires,
Do you have any comments about this patch? The issue and the logic behind the fix has been explained in the commit comment and in the code. Jiri is probably waiting for an acknowledgment from one of you...
Thank you, Ping
On Fri, Oct 22, 2021 at 4:29 PM Ping Cheng pinglinux@gmail.com wrote:
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 killertofu@gmail.com Tested-by: Tatsunosuke Tobita junkpainting@gmail.com
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
Ok, I know why no one follow-up with my patch. Life wasn't as simple as I wished for :).
The patch missed one important fact: repeated events don't go into userland. They are filtered! We need to initiate another input_dev to hold all the past events for the coming tool, whether it is PEN or RUBBER. So, it is more like a simplified multi-pen case, right? What's your suggestions? Do we claim two tools for this particular use case?
On Wed, Oct 27, 2021 at 12:06 PM Ping Cheng pinglinux@gmail.com wrote:
Hi @Dmitry Torokhov and @Benjamin Tissoires,
Do you have any comments about this patch? The issue and the logic behind the fix has been explained in the commit comment and in the code. Jiri is probably waiting for an acknowledgment from one of you...
Thank you, Ping
On Fri, Oct 22, 2021 at 4:29 PM Ping Cheng pinglinux@gmail.com wrote:
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 killertofu@gmail.com Tested-by: Tatsunosuke Tobita junkpainting@gmail.com
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
linux-stable-mirror@lists.linaro.org