[PATCH libinput 7/9] Introduce seat wide button and key count API
Peter Hutterer
peter.hutterer at who-t.net
Wed Apr 9 23:07:34 PDT 2014
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 <jadahl at 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.hutterer at who-t.net> though, the test too.
Cheers,
Peter
> }
>
> static void
> --
> 1.8.3.2
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
More information about the wayland-devel
mailing list