[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