On Wed, Apr 09, 2014 at 09:02:14PM +0200, Jonas Ådahl wrote: > Compositors will need to keep provide virtual devices of supported > generic device types (pointer, keyboard, touch etc). Events from each > device capable of a certain device type abstraction should be combined > as if it was only one device. > > For key and button events this means counting presses of every key or > button. With this patch, libinput provides two new API for doing just > this; libinput_event_pointer_get_seat_button_count() and > libinput_event_keyboard_get_seat_key_count(). > > With these functions, a compositor can sort out what key or button events > that should be ignored for a virtual device. This could for example > look like: > > event = libinput_get_event(libinput); > switch (libinput_event_get_type(event)) { > ... > case LIBINPUT_EVENT_POINTER_BUTTON: > device = libinput_event_get_device(event); > seat = libinput_event_get_seat(device); > pevent = libinput_event_get_pointer_event(event); > > if (libinput_event_pointer_get_button_state(pevent) && > libinput_event_pointer_get_seat_button_count(pevent) == 1) > notify_pointer_button_press(seat); > else if (libinput_event_pointer_get_button_state(pevent) && > libinput_event_pointer_get_seat_button_count(pevent) == 0) > notify_pointer_button_release(seat); > break; > ... > } > > Signed-off-by: Jonas Ådahl <jad...@gmail.com> > --- > src/evdev.c | 3 +++ > src/libinput-private.h | 5 ++++ > src/libinput.c | 72 > ++++++++++++++++++++++++++++++++++++++++++++++++++ > src/libinput.h | 32 ++++++++++++++++++++++ > tools/event-debug.c | 5 ++-- > 5 files changed, 115 insertions(+), 2 deletions(-) > > diff --git a/src/evdev.c b/src/evdev.c > index b6aaf57..4020496 100644 > --- a/src/evdev.c > +++ b/src/evdev.c > @@ -252,6 +252,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); > diff --git a/src/libinput-private.h b/src/libinput-private.h > index 21627b0..39d6445 100644 > --- a/src/libinput-private.h > +++ b/src/libinput-private.h > @@ -23,6 +23,8 @@ > #ifndef LIBINPUT_PRIVATE_H > #define LIBINPUT_PRIVATE_H > > +#include <linux/input.h> > + > #include "libinput.h" > #include "libinput-util.h" > > @@ -63,6 +65,9 @@ struct libinput_seat { > char *logical_name; > > uint32_t slot_map; > + > + uint32_t button_count[KEY_CNT]; > + uint32_t key_count[KEY_CNT];
the ranges are mutually exclusive, we don't really need two arrays here. > }; > > struct libinput_device { > diff --git a/src/libinput.c b/src/libinput.c > index 182c401..799b309 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; > @@ -282,6 +284,13 @@ libinput_event_keyboard_get_key_state(struct > libinput_event_keyboard *event) > } > > 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) > { > return event->time; > @@ -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,52 @@ 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->key_count[key]; > + break; > + case LIBINPUT_KEYBOARD_KEY_STATE_RELEASED: > + /* We might not have received the first PRESSED event. */ > + if (seat->key_count[key] == 0) > + return 0; > + > + return --seat->key_count[key]; > + break; return and break seems excessive ;) > + } > + > + 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]; > + break; > + 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]; > + break; > + } > + > + return 0; > +} > + > static void > init_event_base(struct libinput_event *event, > struct libinput_device *device, > @@ -735,15 +797,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 +870,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 5599a6a..e21cd28 100644 > --- a/src/libinput.h > +++ b/src/libinput.h > @@ -345,6 +345,22 @@ enum libinput_keyboard_key_state > libinput_event_keyboard_get_key_state(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 > * > * Pointer events reflect motion, button and scroll events, as well as > @@ -506,6 +522,22 @@ 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 > + * > * Return the axis that triggered this event. > * For pointer events that are not of type LIBINPUT_EVENT_POINTER_AXIS, > * this function returns 0. > diff --git a/tools/event-debug.c b/tools/event-debug.c > index 12a2df8..e466e09 100644 > --- a/tools/event-debug.c > +++ b/tools/event-debug.c > @@ -281,9 +281,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 (%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)); might as well make it easy to understand and have ", seat cound %u". Reviewed-by: Peter Hutterer <peter.hutte...@who-t.net> though, the test too. Cheers, Peter > } > > static void > -- > 1.8.3.2 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel > _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel