[PATCH libinput 7/9] Introduce seat wide button and key count API

Jonas Ådahl jadahl at gmail.com
Wed Apr 9 23:35:00 PDT 2014


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 <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.

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.

> 
> >  };
> >  
> >  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.hutterer at who-t.net> though, the test too.

Thanks

> 
> 
> 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