From 1c5715fedfe8a67e55ee2138973563ca653256a9 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 6 Jun 2025 10:48:46 +1000 Subject: [PATCH] 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: --- src/evdev-fallback.c | 8 ++++++-- src/evdev-tablet-pad.c | 2 +- src/evdev-tablet.c | 2 +- src/evdev-totem.c | 4 ++-- src/evdev.c | 5 ++++- src/evdev.h | 22 ++++++++++++++++++++++ src/libinput-private.h | 24 ++++++++++++++++++++---- src/libinput.c | 29 ++++++++++++++++------------- 8 files changed, 72 insertions(+), 24 deletions(-) diff --git a/src/evdev-fallback.c b/src/evdev-fallback.c index f93539f4..d46e6d5a 100644 --- a/src/evdev-fallback.c +++ b/src/evdev-fallback.c @@ -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 diff --git a/src/evdev-tablet-pad.c b/src/evdev-tablet-pad.c index 03a76b69..f75c069e 100644 --- a/src/evdev-tablet-pad.c +++ b/src/evdev-tablet-pad.c @@ -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)) { diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c index c1811fac..248023de 100644 --- a/src/evdev-tablet.c +++ b/src/evdev-tablet.c @@ -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); diff --git a/src/evdev-totem.c b/src/evdev-totem.c index 9ea65432..b9597684 100644 --- a/src/evdev-totem.c +++ b/src/evdev-totem.c @@ -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); diff --git a/src/evdev.c b/src/evdev.c index a6aa28ca..a6d44c38 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -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) diff --git a/src/evdev.h b/src/evdev.h index 5f063275..d5e37086 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -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 */ diff --git a/src/libinput-private.h b/src/libinput-private.h index 479c0bf6..0a15f9ec 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -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, diff --git a/src/libinput.c b/src/libinput.c index cda843db..ca487954 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -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,