Use a newtype for the keycode, button code and pad button

This provides both some type-safety but also better readability of what
the integer we're passing around is supposed to be. In particular the
pad buttons are numeric buttons while the normal buttons are evdev
codes.

Future extension of this could be to also check for (or against) the
valid BTN_* ranges for a button code or keycode.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
This commit is contained in:
Peter Hutterer 2025-06-06 10:48:46 +10:00
parent c821bbd8e4
commit 1c5715fedf
8 changed files with 72 additions and 24 deletions

View file

@ -43,8 +43,12 @@ fallback_keyboard_notify_key(struct fallback_dispatch *dispatch,
down_count = evdev_update_key_down_count(device, usage, state);
if ((state == LIBINPUT_KEY_STATE_PRESSED && down_count == 1) ||
(state == LIBINPUT_KEY_STATE_RELEASED && down_count == 0))
keyboard_notify_key(&device->base, time, evdev_usage_code(usage), state);
(state == LIBINPUT_KEY_STATE_RELEASED && down_count == 0)) {
keyboard_notify_key(&device->base,
time,
keycode_from_usage(usage),
state);
}
}
static void

View file

@ -505,7 +505,7 @@ pad_notify_button_mask(struct pad_dispatch *pad,
pad_button_update_mode(group, button, state);
tablet_pad_notify_button(base,
time,
button,
pad_button_from_uint32_t(button),
state,
group);
} else if (map_is_key(map)) {

View file

@ -1386,7 +1386,7 @@ tablet_notify_button_mask(struct tablet_dispatch *tablet,
tool,
tip_state,
&tablet->axes,
i,
button_code_from_uint32_t(i),
state,
&tablet->area.x,
&tablet->area.y);

View file

@ -458,7 +458,7 @@ totem_handle_slot_state(struct totem_dispatch *totem,
slot->tool,
tip_state,
&axes,
BTN_0,
button_code_from_uint32_t(BTN_0),
btn_state,
device->abs.absinfo_x,
device->abs.absinfo_y);
@ -591,7 +591,7 @@ totem_interface_suspend(struct evdev_dispatch *dispatch,
slot->tool,
tip_state,
&axes,
BTN_0,
button_code_from_uint32_t(BTN_0),
LIBINPUT_BUTTON_STATE_RELEASED,
device->abs.absinfo_x,
device->abs.absinfo_y);

View file

@ -203,7 +203,10 @@ evdev_pointer_post_button(struct evdev_device *device,
if ((state == LIBINPUT_BUTTON_STATE_PRESSED && down_count == 1) ||
(state == LIBINPUT_BUTTON_STATE_RELEASED && down_count == 0)) {
pointer_notify_button(&device->base, time, evdev_usage_code(button), state);
pointer_notify_button(&device->base,
time,
button_code_from_usage(button),
state);
if (state == LIBINPUT_BUTTON_STATE_RELEASED) {
if (device->left_handed.change_to_enabled)

View file

@ -1054,4 +1054,26 @@ evdev_device_is_virtual(struct evdev_device *device)
return device->tags & EVDEV_TAG_VIRTUAL;
}
static inline keycode_t
keycode_from_usage(evdev_usage_t usage)
{
uint32_t type = evdev_usage_type(usage);
assert(type == EV_KEY);
uint32_t code = evdev_usage_code(usage);
return keycode_from_uint32_t(code);
}
static inline button_code_t
button_code_from_usage(evdev_usage_t usage)
{
uint32_t type = evdev_usage_type(usage);
assert(type == EV_KEY);
uint32_t code = evdev_usage_code(usage);
return button_code_from_uint32_t(code);
}
#endif /* EVDEV_H */

View file

@ -49,6 +49,21 @@ struct libinput_source;
/* The tablet tool pressure offset */
DECLARE_NEWTYPE(pressure_offset, double);
/**
* A numeric button such as used by the tablet pad
*/
DECLARE_NEWTYPE(pad_button, uint32_t);
/**
* An evdev button code
*/
DECLARE_NEWTYPE(button_code, uint32_t);
/**
* An evdev key code
*/
DECLARE_NEWTYPE(keycode, uint32_t);
static inline pressure_offset_t
pressure_offset_from_range(double min, double max, double value)
{
@ -671,7 +686,7 @@ notify_removed_device(struct libinput_device *device);
void
keyboard_notify_key(struct libinput_device *device,
uint64_t time,
uint32_t key,
keycode_t key,
enum libinput_key_state state);
void
@ -688,7 +703,7 @@ pointer_notify_motion_absolute(struct libinput_device *device,
void
pointer_notify_button(struct libinput_device *device,
uint64_t time,
int32_t button,
button_code_t button,
enum libinput_button_state state);
void
@ -824,7 +839,7 @@ tablet_notify_button(struct libinput_device *device,
struct libinput_tablet_tool *tool,
enum libinput_tablet_tool_tip_state tip_state,
const struct tablet_axes *axes,
int32_t button,
button_code_t button,
enum libinput_button_state state,
const struct input_absinfo *x,
const struct input_absinfo *y);
@ -832,9 +847,10 @@ tablet_notify_button(struct libinput_device *device,
void
tablet_pad_notify_button(struct libinput_device *device,
uint64_t time,
int32_t button,
pad_button_t button,
enum libinput_button_state state,
struct libinput_tablet_pad_mode_group *group);
void
tablet_pad_notify_dial(struct libinput_device *device,
uint64_t time,

View file

@ -2253,10 +2253,12 @@ libinput_device_remove_event_listener(struct libinput_event_listener *listener)
static uint32_t
update_seat_key_count(struct libinput_seat *seat,
int32_t key,
keycode_t keycode,
enum libinput_key_state state)
{
assert(key >= 0 && key <= KEY_MAX);
uint32_t key = keycode_as_uint32_t(keycode);
assert(key <= KEY_MAX);
switch (state) {
case LIBINPUT_KEY_STATE_PRESSED:
@ -2274,10 +2276,11 @@ update_seat_key_count(struct libinput_seat *seat,
static uint32_t
update_seat_button_count(struct libinput_seat *seat,
int32_t button,
button_code_t button_code,
enum libinput_button_state state)
{
assert(button >= 0 && button <= KEY_MAX);
uint32_t button = button_code_as_uint32_t(button_code);
assert(button <= KEY_MAX);
switch (state) {
case LIBINPUT_BUTTON_STATE_PRESSED:
@ -2419,7 +2422,7 @@ device_has_cap(struct libinput_device *device,
void
keyboard_notify_key(struct libinput_device *device,
uint64_t time,
uint32_t key,
keycode_t keycode,
enum libinput_key_state state)
{
struct libinput_event_keyboard *key_event;
@ -2430,11 +2433,11 @@ keyboard_notify_key(struct libinput_device *device,
key_event = zalloc(sizeof *key_event);
seat_key_count = update_seat_key_count(device->seat, key, state);
seat_key_count = update_seat_key_count(device->seat, keycode, state);
*key_event = (struct libinput_event_keyboard) {
.time = time,
.key = key,
.key = keycode_as_uint32_t(keycode),
.state = state,
.seat_key_count = seat_key_count,
};
@ -2493,7 +2496,7 @@ pointer_notify_motion_absolute(struct libinput_device *device,
void
pointer_notify_button(struct libinput_device *device,
uint64_t time,
int32_t button,
button_code_t button,
enum libinput_button_state state)
{
struct libinput_event_pointer *button_event;
@ -2510,7 +2513,7 @@ pointer_notify_button(struct libinput_device *device,
*button_event = (struct libinput_event_pointer) {
.time = time,
.button = button,
.button = button_code_as_uint32_t(button),
.state = state,
.seat_button_count = seat_button_count,
};
@ -2874,7 +2877,7 @@ tablet_notify_button(struct libinput_device *device,
struct libinput_tablet_tool *tool,
enum libinput_tablet_tool_tip_state tip_state,
const struct tablet_axes *axes,
int32_t button,
button_code_t button,
enum libinput_button_state state,
const struct input_absinfo *x,
const struct input_absinfo *y)
@ -2891,7 +2894,7 @@ tablet_notify_button(struct libinput_device *device,
*button_event = (struct libinput_event_tablet_tool) {
.time = time,
.tool = libinput_tablet_tool_ref(tool),
.button = button,
.button = button_code_as_uint32_t(button),
.state = state,
.seat_button_count = seat_button_count,
.proximity_state = LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN,
@ -2910,7 +2913,7 @@ tablet_notify_button(struct libinput_device *device,
void
tablet_pad_notify_button(struct libinput_device *device,
uint64_t time,
int32_t button,
pad_button_t button,
enum libinput_button_state state,
struct libinput_tablet_pad_mode_group *group)
{
@ -2923,7 +2926,7 @@ tablet_pad_notify_button(struct libinput_device *device,
*button_event = (struct libinput_event_tablet_pad) {
.time = time,
.button.number = button,
.button.number = pad_button_as_uint32_t(button),
.button.state = state,
.mode_group = libinput_tablet_pad_mode_group_ref(group),
.mode = mode,