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

Reply via email to