diff --git a/src/evdev.c b/src/evdev.c index 2e0d1d73..08ee0b26 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -258,6 +258,9 @@ evdev_process_key(struct evdev_device *device, struct input_event *e, int time) if (e->value == 2) return; + if (e->code > KEY_MAX) + return; + if (e->code == BTN_TOUCH) { if (!device->is_mt) evdev_process_touch_button(device, time, e->value); @@ -284,6 +287,11 @@ evdev_process_key(struct evdev_device *device, struct input_event *e, int time) break; default: + /* Only let KEY_* codes pass through. */ + if (!(e->code <= KEY_MICMUTE || + (e->code >= KEY_OK && e->code <= KEY_LIGHTS_TOGGLE))) + break; + keyboard_notify_key( &device->base, time, diff --git a/src/libinput-private.h b/src/libinput-private.h index f778f6ea..dc1d5905 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -23,6 +23,8 @@ #ifndef LIBINPUT_PRIVATE_H #define LIBINPUT_PRIVATE_H +#include + #include "libinput.h" #include "libinput-util.h" @@ -63,6 +65,8 @@ struct libinput_seat { char *logical_name; uint32_t slot_map; + + uint32_t button_count[KEY_CNT]; }; struct libinput_device { diff --git a/src/libinput.c b/src/libinput.c index 1e31be30..6b7e8b88 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -54,6 +54,7 @@ struct libinput_event_keyboard { struct libinput_event base; uint32_t time; uint32_t key; + uint32_t seat_key_count; enum libinput_keyboard_key_state state; }; @@ -63,6 +64,7 @@ struct libinput_event_pointer { li_fixed_t x; li_fixed_t y; uint32_t button; + uint32_t seat_button_count; enum libinput_pointer_button_state state; enum libinput_pointer_axis axis; li_fixed_t value; @@ -281,6 +283,13 @@ libinput_event_keyboard_get_key_state(struct libinput_event_keyboard *event) return event->state; } +LIBINPUT_EXPORT uint32_t +libinput_event_keyboard_get_seat_key_count( + struct libinput_event_keyboard *event) +{ + return event->seat_key_count; +} + LIBINPUT_EXPORT uint32_t libinput_event_pointer_get_time(struct libinput_event_pointer *event) { @@ -345,6 +354,13 @@ libinput_event_pointer_get_button_state(struct libinput_event_pointer *event) return event->state; } +LIBINPUT_EXPORT uint32_t +libinput_event_pointer_get_seat_button_count( + struct libinput_event_pointer *event) +{ + return event->seat_button_count; +} + LIBINPUT_EXPORT enum libinput_pointer_axis libinput_event_pointer_get_axis(struct libinput_event_pointer *event) { @@ -672,6 +688,48 @@ libinput_dispatch(struct libinput *libinput) return 0; } +static uint32_t +update_seat_key_count(struct libinput_seat *seat, + int32_t key, + enum libinput_keyboard_key_state state) +{ + assert(key >= 0 && key <= KEY_MAX); + + switch (state) { + case LIBINPUT_KEYBOARD_KEY_STATE_PRESSED: + return ++seat->button_count[key]; + case LIBINPUT_KEYBOARD_KEY_STATE_RELEASED: + /* We might not have received the first PRESSED event. */ + if (seat->button_count[key] == 0) + return 0; + + return --seat->button_count[key]; + } + + return 0; +} + +static uint32_t +update_seat_button_count(struct libinput_seat *seat, + int32_t button, + enum libinput_pointer_button_state state) +{ + assert(button >= 0 && button <= KEY_MAX); + + switch (state) { + case LIBINPUT_POINTER_BUTTON_STATE_PRESSED: + return ++seat->button_count[button]; + case LIBINPUT_POINTER_BUTTON_STATE_RELEASED: + /* We might not have received the first PRESSED event. */ + if (seat->button_count[button] == 0) + return 0; + + return --seat->button_count[button]; + } + + return 0; +} + static void init_event_base(struct libinput_event *event, struct libinput_device *device, @@ -735,15 +793,19 @@ keyboard_notify_key(struct libinput_device *device, enum libinput_keyboard_key_state state) { struct libinput_event_keyboard *key_event; + uint32_t seat_key_count; key_event = zalloc(sizeof *key_event); if (!key_event) return; + seat_key_count = update_seat_key_count(device->seat, key, state); + *key_event = (struct libinput_event_keyboard) { .time = time, .key = key, .state = state, + .seat_key_count = seat_key_count, }; post_device_event(device, @@ -804,15 +866,21 @@ pointer_notify_button(struct libinput_device *device, enum libinput_pointer_button_state state) { struct libinput_event_pointer *button_event; + int32_t seat_button_count; button_event = zalloc(sizeof *button_event); if (!button_event) return; + seat_button_count = update_seat_button_count(device->seat, + button, + state); + *button_event = (struct libinput_event_pointer) { .time = time, .button = button, .state = state, + .seat_button_count = seat_button_count, }; post_device_event(device, diff --git a/src/libinput.h b/src/libinput.h index 810a66c2..fb297e3a 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -370,6 +370,22 @@ libinput_event_keyboard_get_key_state(struct libinput_event_keyboard *event); struct libinput_event * libinput_event_keyboard_get_base_event(struct libinput_event_keyboard *event); +/** + * @ingroup event_keyboard + * + * For the key of a LIBINPUT_EVENT_KEYBOARD_KEY event, return the total number + * of keys pressed on all devices on the associated seat after the event was + * triggered. + * + " @note It is an application bug to call this function for events other than + * LIBINPUT_EVENT_KEYBOARD_KEY. For other events, this function returns 0. + * + * @return the seat wide pressed key count for the key of this event + */ +uint32_t +libinput_event_keyboard_get_seat_key_count( + struct libinput_event_keyboard *event); + /** * @defgroup event_pointer Pointer events * @@ -529,6 +545,22 @@ libinput_event_pointer_get_button(struct libinput_event_pointer *event); enum libinput_pointer_button_state libinput_event_pointer_get_button_state(struct libinput_event_pointer *event); +/** + * @ingroup event_pointer + * + * For the button of a LIBINPUT_EVENT_POINTER_BUTTON event, return the total + * number of buttons pressed on all devices on the associated seat after the + * the event was triggered. + * + " @note It is an application bug to call this function for events other than + * LIBINPUT_EVENT_POINTER_BUTTON. For other events, this function returns 0. + * + * @return the seat wide pressed button count for the key of this event + */ +uint32_t +libinput_event_pointer_get_seat_button_count( + struct libinput_event_pointer *event); + /** * @ingroup event_pointer * diff --git a/tools/event-debug.c b/tools/event-debug.c index c0a08a7a..6cb57ff2 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -287,9 +287,10 @@ print_button_event(struct libinput_event *ev) print_event_time(libinput_event_pointer_get_time(p)); state = libinput_event_pointer_get_button_state(p); - printf("%3d %s\n", + printf("%3d %s, seat count: %u\n", libinput_event_pointer_get_button(p), - state == LIBINPUT_POINTER_BUTTON_STATE_PRESSED ? "pressed" : "released"); + state == LIBINPUT_POINTER_BUTTON_STATE_PRESSED ? "pressed" : "released", + libinput_event_pointer_get_seat_button_count(p)); } static void