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

Reply via email to