[PATCH libinput 16/26] tablet: add support for libinput_tool_has_button

Peter Hutterer peter.hutterer at who-t.net
Tue Feb 24 14:47:08 PST 2015


On Tue, Feb 24, 2015 at 12:46:10PM -0500, Benjamin Tissoires wrote:
> On Tue, Feb 24, 2015 at 1:21 AM, Peter Hutterer
> <peter.hutterer at who-t.net> wrote:
> > libwacom can tell us how many buttons we have per stylus, so we map those into
> > BTN_STYLUS and BTN_STYLUS2.
> > BTN_TOUCH is set on all styli.
> >
> > Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> > ---
> >  src/evdev-tablet.c     | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >  src/libinput-private.h |  1 +
> >  src/libinput.c         | 10 +++++++
> >  src/libinput.h         | 15 +++++++++++
> >  src/libinput.sym       |  1 +
> >  5 files changed, 100 insertions(+)
> >
> > diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
> > index 85bdcd7..ced9207 100644
> > --- a/src/evdev-tablet.c
> > +++ b/src/evdev-tablet.c
> > @@ -382,6 +382,51 @@ copy_axis_cap(const struct tablet_dispatch *tablet,
> >                 set_bit(tool->axis_caps, axis);
> >  }
> >
> > +static inline void
> > +copy_button_cap(const struct tablet_dispatch *tablet,
> > +               struct libinput_tool *tool,
> > +               uint32_t button)
> > +{
> > +       struct libevdev *evdev = tablet->device->evdev;
> > +       if (libevdev_has_event_code(evdev, EV_KEY, button))
> > +               set_bit(tool->buttons, button);
> > +}
> > +
> > +static void
> > +tool_set_bits_from_libwacom(const struct tablet_dispatch *tablet,
> > +                           struct libinput_tool *tool)
> > +{
> > +#if HAVE_LIBWACOM
> > +       WacomDeviceDatabase *db;
> > +       const WacomStylus *s = NULL;
> > +       int code;
> > +
> > +       db = libwacom_database_new();
> 
> Not sure this is related, but I noticed that hot plugging an Intuos
> pro takes a long time to be handled by libinput (several seconds,
> udevadm monitor shows the device in less than one second), while
> plugging the Bamboo tablet or the Bamboo PAD or any other device makes
> it quite immediate to get a libinput handle (less than a second at
> least).

that sounds like a libwacom bug, shouldn't take that long. probably best
fixed there, if you can trace it that'd be great. try
libwacom-list-local-devices, that should reproduce it.

> I believe there is n choice but to build the db at each tool too, right?

we could leave the libwacom handle around, but I figured it's not worth the 
cost. testing skews things somewhat by amplifying how often you actually
add a new tool. in the normal use-case 99% of users will have one tablet,
hotplugged once on startup and one pen + eraser. If they're fancy they use
the mouse so they have three tools. We keep the tool objects around once
initialized, so we only ever need libwacom when we see them first.

So there is a slight penalty is the first time you use each tool but I think
that's better than keeping the libwacom handle and the database in memory
for the lifetime of the session when it's not needed anymore.
 
Cheers,
   Peter

> > +       if (!db)
> > +               goto out;
> > +       s = libwacom_stylus_get_for_id(db, tool->tool_id);
> > +       if (!s)
> > +               goto out;
> > +
> > +       if (libwacom_stylus_get_type(s) == WSTYLUS_PUCK) {
> > +               for (code = BTN_LEFT;
> > +                    code < BTN_LEFT + libwacom_stylus_get_num_buttons(s);
> > +                    code++)
> > +                       copy_button_cap(tablet, tool, code);
> > +       } else {
> > +               if (libwacom_stylus_get_num_buttons(s) >= 2)
> > +                       copy_button_cap(tablet, tool, BTN_STYLUS2);
> > +               if (libwacom_stylus_get_num_buttons(s) >= 1)
> > +                       copy_button_cap(tablet, tool, BTN_STYLUS);
> > +               copy_button_cap(tablet, tool, BTN_TOUCH);
> > +       }
> > +
> > +out:
> > +       if (db)
> > +               libwacom_database_destroy(db);
> > +#endif
> > +}
> > +
> >  static void
> >  tool_set_bits(const struct tablet_dispatch *tablet,
> >               struct libinput_tool *tool)
> > @@ -413,6 +458,34 @@ tool_set_bits(const struct tablet_dispatch *tablet,
> >         default:
> >                 break;
> >         }
> > +
> > +#if HAVE_LIBWACOM
> > +       tool_set_bits_from_libwacom(tablet, tool);
> > +#else
> > +       /* If we don't have libwacom, copy all pen-related ones from the
> > +          tablet vs all mouse-related ones */
> > +       switch (type) {
> > +       case LIBINPUT_TOOL_PEN:
> > +       case LIBINPUT_TOOL_BRUSH:
> > +       case LIBINPUT_TOOL_AIRBRUSH:
> > +       case LIBINPUT_TOOL_PENCIL:
> > +       case LIBINPUT_TOOL_ERASER:
> > +               copy_button_cap(tablet, tool, BTN_STYLUS);
> > +               copy_button_cap(tablet, tool, BTN_STYLUS2);
> > +               copy_button_cap(tablet, tool, BTN_TOUCH);
> > +               break;
> > +       case LIBINPUT_TOOL_MOUSE:
> > +       case LIBINPUT_TOOL_LENS:
> > +               copy_button_cap(tablet, tool, BTN_LEFT);
> > +               copy_button_cap(tablet, tool, BTN_MIDDLE);
> > +               copy_button_cap(tablet, tool, BTN_RIGHT);
> > +               copy_button_cap(tablet, tool, BTN_SIDE);
> > +               copy_button_cap(tablet, tool, BTN_EXTRA);
> > +               break;
> > +       default:
> > +               break;
> > +       }
> > +#endif
> >  }
> >
> >  static struct libinput_tool *
> > diff --git a/src/libinput-private.h b/src/libinput-private.h
> > index b2dc406..9f32655 100644
> > --- a/src/libinput-private.h
> > +++ b/src/libinput-private.h
> > @@ -191,6 +191,7 @@ struct libinput_tool {
> >         uint32_t tool_id;
> >         enum libinput_tool_type type;
> >         unsigned char axis_caps[NCHARS(LIBINPUT_TABLET_AXIS_MAX + 1)];
> > +       unsigned char buttons[NCHARS(KEY_MAX) + 1];
> >         int refcount;
> >         void *user_data;
> >  };
> > diff --git a/src/libinput.c b/src/libinput.c
> > index b165c59..5ed3ffc 100644
> > --- a/src/libinput.c
> > +++ b/src/libinput.c
> > @@ -681,6 +681,16 @@ libinput_tool_has_axis(struct libinput_tool *tool,
> >         return bit_is_set(tool->axis_caps, axis);
> >  }
> >
> > +LIBINPUT_EXPORT int
> > +libinput_tool_has_button(struct libinput_tool *tool,
> > +                        uint32_t code)
> > +{
> > +       if (NCHARS(code) > sizeof(tool->buttons))
> > +               return 0;
> > +
> > +       return bit_is_set(tool->buttons, code);
> > +}
> > +
> >  LIBINPUT_EXPORT void
> >  libinput_tool_set_user_data(struct libinput_tool *tool,
> >                             void *user_data)
> > diff --git a/src/libinput.h b/src/libinput.h
> > index f746671..02b2c11 100644
> > --- a/src/libinput.h
> > +++ b/src/libinput.h
> > @@ -1244,6 +1244,21 @@ libinput_tool_has_axis(struct libinput_tool *tool,
> >  /**
> >   * @ingroup event_tablet
> >   *
> > + * Check if a tablet tool has a button with the
> > + * passed-in code (see linux/input.h).
> > + *
> > + * @param tool A tablet tool
> > + * @param code button code to check for
> > + *
> > + * @return 1 if the tool supports this button code, 0 if it does not
> > + */
> > +int
> > +libinput_tool_has_button(struct libinput_tool *tool,
> > +                        uint32_t code);
> > +
> > +/**
> > + * @ingroup event_tablet
> > + *
> >   * Decrement the ref count of tool by one. When the ref count of tool reaches 0,
> >   * the memory allocated for tool will be freed.
> >   *
> > diff --git a/src/libinput.sym b/src/libinput.sym
> > index 5561478..e674226 100644
> > --- a/src/libinput.sym
> > +++ b/src/libinput.sym
> > @@ -159,6 +159,7 @@ LIBINPUT_TABLET_SUPPORT {
> >         libinput_tool_get_tool_id;
> >         libinput_tool_get_type;
> >         libinput_tool_get_user_data;
> > +       libinput_tool_has_button;
> >         libinput_tool_has_axis;
> >         libinput_tool_ref;
> >         libinput_tool_set_user_data;
> > --
> > 2.1.0
> >
> > _______________________________________________
> > 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