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@xxxxxxxxx> 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@xxxxxxxxx> 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@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 > >