On Thu, Apr 10, 2014 at 04:48:52PM +1000, Peter Hutterer wrote: > On Thu, Apr 10, 2014 at 08:35:00AM +0200, Jonas Ådahl wrote: > > On Thu, Apr 10, 2014 at 04:07:34PM +1000, Peter Hutterer wrote: > > > 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. > > > > This is in the seat, and libinput separates pointers from keyboards, so > > shouldn't they be counted separately because of that? Will a pointer > > never press a "key" and a keyboard never a "button"? If they would then > > the keyboards button count should not effect the pointers button count > > and vice versa. > > are you suggesting we add keyboard_button or pointer_key events? because > that's a bridge we should burn when we have cross it, not before :)
No, what I mean is will a pointer_button code never be KEY_* and a keyboard_key code never be BTN_*? > > Cheers, > Peter > > > > > > > > > > }; > > > > > > > > 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 ;) > > > > Uhm, fixed locally. > > > > > > > > > + } > > > > + > > > > + 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". > > > > Sure, amended locally. > > > > > > > > Reviewed-by: Peter Hutterer <peter.hutte...@who-t.net> though, the test > > > too. > > > > Thanks > > > > > > > > > > > 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