[RFC PATCH 3/6] Input: Fire EV_BTN if found in ev_bit

Tomasz Pakuła posted 6 patches 1 month ago
[RFC PATCH 3/6] Input: Fire EV_BTN if found in ev_bit
Posted by Tomasz Pakuła 1 month ago
Passes EV_BTN through to handlers and allows reacting to this event by
clients.

Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>
---
 drivers/hid/hid-input.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 2bbb645c2ff4..900a6fc9813e 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1673,7 +1673,8 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
 
 	switch (usage->type) {
 	case EV_KEY:
-		if (usage->code == 0) /* Key 0 is "unassigned", not KEY_UNKNOWN */
+		/* Key 0 is "unassigned", not KEY_UNKNOWN */
+		if (usage->code == 0 && !test_bit(EV_BTN, input->evbit))
 			return;
 		break;
 
@@ -1723,10 +1724,19 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
 	    value == field->value[usage->usage_index])
 		return;
 
-	/* report the usage code as scancode if the key status has changed */
-	if (usage->type == EV_KEY &&
-	    (!test_bit(usage->code, input->key)) == value)
-		input_event(input, EV_MSC, MSC_SCAN, usage->hid);
+
+	if (usage->type == EV_KEY) {
+		/* Send out EV_BTN with button number (starts at 1) */
+		if (test_bit(EV_BTN, input->evbit))
+			input_event(input, EV_BTN, usage->hid & HID_USAGE, value);
+
+		if (usage->code == 0)
+			return;
+
+		/* report usage code as scancode if the status has changed */
+		if ((!test_bit(usage->code, input->key)) == value)
+			input_event(input, EV_MSC, MSC_SCAN, usage->hid);
+	}
 
 	input_event(input, usage->type, usage->code, value);
 
-- 
2.52.0

Re: [RFC PATCH 3/6] Input: Fire EV_BTN if found in ev_bit
Posted by Benjamin Tissoires 1 month ago
On Jan 04 2026, Tomasz Pakuła wrote:
> Passes EV_BTN through to handlers and allows reacting to this event by
> clients.
> 
> Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>
> ---
>  drivers/hid/hid-input.c | 20 +++++++++++++++-----
>  1 file changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
> index 2bbb645c2ff4..900a6fc9813e 100644
> --- a/drivers/hid/hid-input.c
> +++ b/drivers/hid/hid-input.c
> @@ -1673,7 +1673,8 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
>  
>  	switch (usage->type) {
>  	case EV_KEY:
> -		if (usage->code == 0) /* Key 0 is "unassigned", not KEY_UNKNOWN */
> +		/* Key 0 is "unassigned", not KEY_UNKNOWN */
> +		if (usage->code == 0 && !test_bit(EV_BTN, input->evbit))
>  			return;
>  		break;
>  
> @@ -1723,10 +1724,19 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
>  	    value == field->value[usage->usage_index])
>  		return;
>  
> -	/* report the usage code as scancode if the key status has changed */
> -	if (usage->type == EV_KEY &&
> -	    (!test_bit(usage->code, input->key)) == value)
> -		input_event(input, EV_MSC, MSC_SCAN, usage->hid);
> +
> +	if (usage->type == EV_KEY) {
> +		/* Send out EV_BTN with button number (starts at 1) */
> +		if (test_bit(EV_BTN, input->evbit))
> +			input_event(input, EV_BTN, usage->hid & HID_USAGE, value);

In addition to what Peter said, this seems to be a lot more convoluted
than what it needs to be.

The one nice thing about the EV_BTN is that is transfers the intend of
"this is a buttons with no particular meaning". And that's exactly what
the HID usage page "button" is.

So why not:
- whenever there are buttons from the HID usage page button -> map them
	to EV_BTN
- only map EV_BTN to usage page Button (to prevent weird things
	happening with keyboards)
- keep doing the weird mapping in HID we do but do not upper bound the
	EV_KEY like we do (first hunk in this patch), and store the mapping
	EV_BTN/EV_KEY in the input/evdev subsystem, not in HID
- on the HID side, we fire just the EV_BTN for button usage page, and
	input does the backward compatibility.
- the backward compatibility needs to be in the input side of things so
	we can add the new ioctls Peter was mentioning.

Cheers,
Benjamin

> +
> +		if (usage->code == 0)
> +			return;
> +
> +		/* report usage code as scancode if the status has changed */
> +		if ((!test_bit(usage->code, input->key)) == value)
> +			input_event(input, EV_MSC, MSC_SCAN, usage->hid);
> +	}
>  
>  	input_event(input, usage->type, usage->code, value);
>  
> -- 
> 2.52.0
>