[RFC v3 libinput 1/2] buttonset: Add a "buttonset" interface for button-only devices

Peter Hutterer peter.hutterer at who-t.net
Wed Jan 20 16:30:18 PST 2016


On Wed, Jan 20, 2016 at 08:58:09PM +0100, Benjamin Tissoires wrote:
[...]
> > @@ -138,6 +139,50 @@ enum libinput_pointer_axis_source {
> >   * @ingroup device
> >   * @struct libinput_tablet_tool
> >   *
> > + * Available axis types for a buttonset device. It must have the @ref
> > + * LIBINPUT_DEVICE_CAP_BUTTONSET capability. A device may have more than one
> > + * axis of the same type, e.g. a Wacom Cintiq 24HD has two ring axes.
> > + */
> > +enum libinput_buttonset_axis_type {
> > +       LIBINPUT_BUTTONSET_AXIS_X = 1, /**< Absolute X axis */
> > +       LIBINPUT_BUTTONSET_AXIS_Y, /**< Absolute Y axis */
> > +       LIBINPUT_BUTTONSET_AXIS_Z, /**< Absolute Z axis */
> > +       LIBINPUT_BUTTONSET_AXIS_REL_X, /**< Relative X axis */
> > +       LIBINPUT_BUTTONSET_AXIS_REL_Y, /**< Relative Y axis */
> > +       LIBINPUT_BUTTONSET_AXIS_REL_Z, /**< Relative Z axis */
> > +       LIBINPUT_BUTTONSET_AXIS_ROTATION_X,
> > +       LIBINPUT_BUTTONSET_AXIS_ROTATION_Y,
> > +       LIBINPUT_BUTTONSET_AXIS_ROTATION_Z,
> > +       /**
> > +        * A ring-like axis with absolute axis values, e.g. the ring on the
> > +        * Wacom Intuos4.
> > +        */
> > +       LIBINPUT_BUTTONSET_AXIS_RING,
> > +       /**
> > +        * A strip-like axis with absolute axis values, e.g. the strip on
> > +        * the Wacom Intuos3.
> > +        */
> > +       LIBINPUT_BUTTONSET_AXIS_STRIP,
> > +};
> 
> Given the latest API and the quirks needed for Wacom pads support, I
> wonder if those names are not too generic.
> I believe X|Y|Z|REL_X|REL_Y|REL_Z|ROT_X|ROT_Y|ROT_Z are primary meant
> for 3D mice and/or tools like the SpacePilot).
> On the other hand, we have STRIP, which, by its documentation later
> on, seems to be the exact same thing as a Y axis.
> 
> Comparing STRIP and Y makes me wonder whether we do not already
> implies that STRIP will only be used by Pads on Wacom devices, while
> the rest of the world will use Y.
> The other explanation would be that STRIP has an actual input source
> (a finger), and is only meant for capacitive touch strip. In this
> case, why do we need to specify whether we have an input source.
> 
> I wonder, if we should not use a clear unambiguous name (which would
> contain TABLET or 3D_MOUSEin it), and be really precise in the
> definitions we are using.
> This also means that the buttonset will end up being just a bag of
> special usages, but I am not sure we will be able to avoid the quirks
> here and there if we keep having generic axis.
> 
> Regarding the RING axis, the same thing applies. A more generic term
> would be rotary encoder, with overrolling (0.8 + 0.3 = 0.1) or not.
> The fact that the ring is an actual ring does not help if one decides
> to use a different design.

first: yes, the x/y/z axes are meant to be physical axes for 3d devices,
they won't apply to any current tablet.

the strip can be a y axis, but doesn't have to be. it is just a capacitative
strip that can be aligned in any direction. all the hw I can think of right
now has it vertically, but that shouldn't matter.

for the ring, I thought it may also be useful for things like the griffin
powermate, or any other rotary device (though you could say this is
rotation).

the input source is important because we may not be able to detect a finger
lift. on the wacom tablets we can, which means that you can implement
kinetic scrolling on a ring. but that's not guaranteed to work in the future
- the input source is the out-of-band information for this.

I think I'd be happy with designating both ring and strip as capacitative
strips as on the wacom tablet and accepting that they won't be used for
anything else. as to:

> This also means that the buttonset will end up being just a bag of
> special usages, but I am not sure we will be able to avoid the quirks
> here and there if we keep having generic axis.

yeah, this is partially the plan of the buttonset interface though. it may
be custom axes, but at least we can define how the work and work around
kernel quirks in libinput, even if there is only few devices that support
the respective axis. libinput will require a caller to know the device and
how to interpret/map an axis, but at least the value coming out of libinput
will be useful.

[...]
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * Return the y coordinate of the buttonset event, transformed to
> > + * screen coordinates. The axis must be of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_Y.
> > + *
> > + * @param event The event
> > + * @param axis An index for an axis of type @ref LIBINPUT_BUTTONSET_AXIS_Y
> > + * @param height The screen height
> > + * @return The x coordinate transformed to screen coordinates, or 0 if the
> > + * axis is not of type @ref LIBINPUT_BUTTONSET_AXIS_Y.
> > + */
> > +double
> > +libinput_event_buttonset_get_y_transformed(struct libinput_event_buttonset *event,
> > +                                          unsigned int axis,
> > +                                          uint32_t height);
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * Get the z coordinate in mm for the given axis from the top edge of the
> > + * device in its current logical rotation. The axis must be of type
> 
> I am not sure what "axis from the top edge of thedevice in its current
> logical rotation" means.
> I think we should be very cautious in describing those axis, or some
> will give ascending Z, and other descending ones.
> 
> I recently had the issue with the HID protocol. See "4.2 Axis Usages"
> in http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (the HID usage
> table).
> " Z – A linear translation in the Z direction. Report values should
> increase as the control’s position is moved from high to low (Z). "
> This makes sense given the righthand rule taking into account x (left
> to right) and y (top to bottom).
> 
> Maybe we should state that Z is generally negative from the surface to
> the point tracked instead of positive, to follow the righthand rule.
> Or we should explicitely say that we break this rule.

for the archives: Benjamin and I agreed on following the HUT for axis
orientations and re-using + linking to the HUT.

> > + * @ref LIBINPUT_BUTTONSET_AXIS_Z.
> > + *
> > + * @param event The event
> > + * @param axis An index for an axis of type @ref LIBINPUT_BUTTONSET_AXIS_Z
> > + * @return The z coordinate in mm, or 0 if the axis is not of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_Z.
> > + */
> > +double
> > +libinput_event_buttonset_get_z(struct libinput_event_buttonset *event,
> > +                              unsigned int axis);
> > +
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * Get the delta coordinates for a relative x axis of type
> > + * @ref LIBINPUT_BUTTONSET_AXIS_REL_X.
> > + *
> > + * The interpretation of a delta is device-specific. Buttonset devices are
> 
> device specific, but should increase along the X axis and decrease on
> the opposite side (same comment for REL_Y and REL_Z).
> 
> > + * not usually supposed to control the cursor position, a caller should not
> > + * assume that delta coordinates are directly applicable to pointer
> > + * movement.
> > + *
> > + * @param event The event
> > + * @param axis An index for an axis of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_REL_X
> > + * @return The delta x coordinate, or 0 if the axis is not of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_REL_X.
> > + */
> > +double
> > +libinput_event_buttonset_get_dx(struct libinput_event_buttonset *event,
> > +                               unsigned int axis);
> > +
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * Get the delta coordinates for a relative x axis of type
> > + * @ref LIBINPUT_BUTTONSET_AXIS_REL_Y.
> > + *
> > + * The interpretation of a delta is device-specific. Buttonset devices are
> > + * not usually supposed to control the cursor position, a caller should not
> > + * assume that delta coordinates are directly applicable to pointer
> > + * movement.
> > + *
> > + * @param event The event
> > + * @param axis An index for an axis of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_REL_Y
> > + * @return The delta y coordinate, or 0 if the axis is not of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_REL_Y.
> > + */
> > +double
> > +libinput_event_buttonset_get_dy(struct libinput_event_buttonset *event,
> > +                               unsigned int axis);
> > +
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * Get the delta coordinates for a relative x axis of type
> > + * @ref LIBINPUT_BUTTONSET_AXIS_REL_Z.
> > + *
> > + * @param event The event
> > + * @param axis An index for an axis of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_REL_Z
> > + * @return The delta z coordinate, or 0 if the axis is not of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_REL_Z.
> > + */
> > +double
> > +libinput_event_buttonset_get_dz(struct libinput_event_buttonset *event,
> > +                               unsigned int axis);
> > +
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * Get the rotational position in degrees off the logical neutral position
> > + * in the current logical orientation for an axis of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_ROTATION_X.
> > + *
> > + * @param event The event
> > + * @param axis An index for an axis of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_ROTATION_X
> > + * @return The rotational x value in degrees, or 0 if the axis is not of type @ref
> 
> we should mention whether the angle is direct or not here (see the HUT
> for a better formulation: "angular position report values follow the
> righthand rule").
> 
> > + * LIBINPUT_BUTTONSET_AXIS_REL_Z.
> 
> REL_Z? shouldn't it be ROTATION_X?

sorry, copy/paste errors

> 
> > + */
> > +double
> > +libinput_event_buttonset_get_rotation_x(struct libinput_event_buttonset *event,
> > +                                       unsigned int axis);
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * Get the rotational position in degrees off the logical neutral position
> > + * in the current logical orientation for an axis of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_ROTATION_Y.
> > + *
> > + * @param event The event
> > + * @param axis An index for an axis of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_ROTATION_Y
> > + * @return The rotational y value in degrees, or 0 if the axis is not of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_REL_Y.
> 
> REL_Y?
> 
> > + */
> > +double
> > +libinput_event_buttonset_get_rotation_y(struct libinput_event_buttonset *event,
> > +                                       unsigned int axis);
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * Get the rotational position in degrees off the logical neutral position
> > + * in the current logical orientation for an axis of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_ROTATION_Z.
> > + *
> > + * @param event The event
> > + * @param axis An index for an axis of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_ROTATION_Z
> > + * @return The rotational z value in degrees, or 0 if the axis is not of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_REL_Z.
> 
> REL_Z?
> 
> > + */
> > +double
> > +libinput_event_buttonset_get_rotation_z(struct libinput_event_buttonset *event,
> > +                                       unsigned int axis);
> > +
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * Get the absolute position for an axis of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_RING in degrees clockwise in the
> > + * device's current logical rotation.
> > + *
> > + * If the libinput_event_buttonset_get_ring_source() returns @ref
> > + * LIBINPUT_BUTTONSET_AXIS_SOURCE_FINGER for this event and this axis,
> > + * libinput will send an event with a value of -1 when the finger is
> > + * lifted.
> > + *
> > + * @param event The event
> > + * @param axis An index for an axis of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_RING
> > + * @return The ring's position in degrees, or 0 if the axis is not of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_RING.
> > + */
> > +double
> > +libinput_event_buttonset_get_ring_position(struct libinput_event_buttonset *event,
> > +                                          unsigned int axis);
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * Return the source for an axis of type @ref LIBINPUT_BUTTONSET_AXIS_RING.
> > + *
> > + * If the source is @ref LIBINPUT_BUTTONSET_AXIS_SOURCE_FINGER, libinput
> > + * guarantees that a sequence is terminated with an out-of-range value (see
> > + * libinput_event_buttonset_get_ring_value() for details).
> > + * A caller may use this information to decide on whether kinetic motion
> > + * should be triggered on this event sequence.
> > + *
> > + * If the source is @ref LIBINPUT_BUTTONSET_AXIS_SOURCE_UNKNOWN, libinput
> > + * does not send a terminating value to indicate release.
> > + *
> > + */
> > +enum libinput_buttonset_axis_source
> > +libinput_event_buttonset_get_ring_source(struct libinput_event_buttonset *event,
> > +                                        unsigned int axis);
> > +
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * Get the absolute position for an axis of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_STRIP normalized to the axis range [0, 1], where
> > + * 0 is the strip's top or left-most point in the device's current logical
> > + * rotation.
> > + *
> > + * If the libinput_event_buttonset_get_strip_source() returns @ref
> > + * LIBINPUT_BUTTONSET_AXIS_SOURCE_FINGER for this event and this axis,
> > + * libinput will send an event with a value of -1 when the finger is
> > + * lifted.
> 
> Could be interesting to have this also for buttons. Wacom Intuos Pros
> report the capacitive information for each button, and it would be
> interesting to send those to the userspace. Currently the kernel
> strips those events but we should be able to change that if we have
> the requirements and uses.
> 
> Thinking about the PS3 controller (ok, buttonset is not for gamepads,
> but still), I wonder if this is actually just wrong (sending out of
> range values when the finger is lifted).
> For each button on the PS3 controller, we have 2 different
> informations: whether the user pressed it or not (the "click"), and if
> not, an absolute value of the pressure used against each button.
> 
> Here, we also have 2 sensors combined into one physical tool of
> interaction: a capacitive sensor which gives the finger on/off
> information, and the buttons, rotary position, etc...
> 
> Could we imagine a way where we have the buttonset which is a set of
> composite objects (I think the term could be actuator, or instrument).
> Each composite object has one or more valuator/button/whatever so that
> the client of libinput knows what is the topology of the device.
> Agree, this might be overkill, but I really dislike the "out of bound
> value means the finger is up" because in the kernel, we will mostly
> send this information on a different channel than the out of bound
> value (maybe not).

for the archives: we discussed this in a meeting and the conclusion was that
for buttons with extra abilities such as capacity or pressure we can add
exta events later. for a capacitative button, a proximity-like event that
brackets the button press/release events and for pressure a button axis
event. the button state could be a logical state, taking a pressure
threshold into account where needed.

Cheers,
   Peter

> 
> I think I'll stop here. Thanks for reading :)
> 
> Cheers,
> Benjamin
> 
> > + *
> > + * @param event The event
> > + * @param axis An index for an axis of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_STRIP
> > + * @return The normalized position on the strip, or 0 if the axis is not of type @ref
> > + * LIBINPUT_BUTTONSET_AXIS_STRIP.
> > + */
> > +double
> > +libinput_event_buttonset_get_strip_position(struct libinput_event_buttonset *event,
> > +                                           unsigned int axis);
> > +
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * Return the source for an axis of type @ref LIBINPUT_BUTTONSET_AXIS_STRIP.
> > + *
> > + * If the source is @ref LIBINPUT_BUTTONSET_AXIS_SOURCE_FINGER, libinput
> > + * guarantees that a sequence is terminated with an out-of-range value (see
> > + * libinput_event_buttonset_get_strip_value() for details).
> > + * A caller may use this information to decide on whether kinetic motion
> > + * should be triggered on this event sequence.
> > + *
> > + * If the source is @ref LIBINPUT_BUTTONSET_AXIS_SOURCE_UNKNOWN, libinput
> > + * does not send a terminating value to indicate release.
> > + */
> > +enum libinput_buttonset_axis_source
> > +libinput_event_buttonset_get_strip_source(struct libinput_event_buttonset *event,
> > +                                        unsigned int axis);
> > +
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * Return the button that triggered this event.
> > + * For buttonset events that are not of type @ref LIBINPUT_EVENT_BUTTONSET_BUTTON, this
> > + * function returns 0.
> > + *
> > + * @note It is an application bug to call this function for events other than
> > + * @ref LIBINPUT_EVENT_BUTTONSET_BUTTON.
> > + *
> > + * @param event The libinput buttonset event
> > + * @return the button triggering this event
> > + */
> > +uint32_t
> > +libinput_event_buttonset_get_button(struct libinput_event_buttonset *event);
> > +
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * Return the button state of the event.
> > + *
> > + * @note It is an application bug to call this function for events other than
> > + * @ref LIBINPUT_EVENT_BUTTONSET_BUTTON.
> > + *
> > + * @param event The libinput buttonset event
> > + * @return the button state triggering this event
> > + */
> > +enum libinput_button_state
> > +libinput_event_buttonset_get_button_state(struct libinput_event_buttonset *event);
> > +
> > +/**
> > + * @ingroup event_buttonset
> > + *
> > + * For the button of a @ref LIBINPUT_EVENT_BUTTONSET_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
> > + * @ref LIBINPUT_EVENT_BUTTONSET_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_buttonset_get_seat_button_count(struct libinput_event_buttonset *event);
> > +
> > +/**
> >   * @defgroup base Initialization and manipulation of libinput contexts
> >   */
> >
> > @@ -2874,6 +3320,68 @@ libinput_device_keyboard_has_key(struct libinput_device *device,
> >                                  uint32_t code);
> >
> >  /**
> > + * Check if a @ref LIBINPUT_DEVICE_CAP_BUTTONSET device has a button with
> > + * the given code (see linux/input.h).
> > + *
> > + * @param device A current input device
> > + * @param code button code to check for
> > + *
> > + * @return 1 if the device supports this button code, 0 if it does not, -1
> > + * on error.
> > + *
> > + * @see @ref buttonset_buttons
> > + */
> > +int
> > +libinput_device_buttonset_has_button(struct libinput_device *device,
> > +                                    uint32_t code);
> > +
> > +/**
> > + * @ingroup device
> > + *
> > + * Return the number of axes on this @ref LIBINPUT_DEVICE_CAP_BUTTONSET
> > + * device.
> > + *
> > + * If the device does not have the @ref LIBINPUT_DEVICE_CAP_BUTTONSET
> > + * capability, this function returns zero.
> > + *
> > + * @note: axis numbers are not stable, see @ref buttonset_axes for details.
> > + *
> > + * @note It is an application bug to call this function on a device
> > + * without the @ref LIBINPUT_DEVICE_CAP_BUTTONSET capability.
> > + *
> > + * @param device A current input device
> > + *
> > + * @return The number of axes on this device or zero.
> > + */
> > +unsigned int
> > +libinput_device_buttonset_get_num_axes(struct libinput_device *device);
> > +
> > +/**
> > + * @ingroup device
> > + *
> > + * Return the axis type for the given axis on this @ref
> > + * LIBINPUT_DEVICE_CAP_BUTTONSET device.
> > + *
> > + * If the device does not have the @ref LIBINPUT_DEVICE_CAP_BUTTONSET
> > + * capability or the axis does not exist on this device, this function
> > + * returns zero.
> > + *
> > + * @note It is an application bug to call this function on a device
> > + * without the @ref LIBINPUT_DEVICE_CAP_BUTTONSET capability or for an axis
> > + * that does not exist.
> > + *
> > + * @param device A current input device
> > + * @param axis The axis to retrieve the type of
> > + *
> > + * @return The axis type for the given axis or 0 if the axis does not exist
> > + *
> > + * @see libinput_device_buttonset_get_num_axes
> > + */
> > +enum libinput_buttonset_axis_type
> > +libinput_device_buttonset_get_axis_type(struct libinput_device *device,
> > +                                       unsigned int axis);
> > +
> > +/**
> >   * @ingroup device
> >   *
> >   * Increase the refcount of the device group. A device group will be freed
> > diff --git a/src/libinput.sym b/src/libinput.sym
> > index 22a8dd8..07073b2 100644
> > --- a/src/libinput.sym
> > +++ b/src/libinput.sym
> > @@ -231,3 +231,37 @@ LIBINPUT_TABLET_SUPPORT {
> >         libinput_tablet_tool_set_user_data;
> >         libinput_tablet_tool_unref;
> >  } LIBINPUT_1.1;
> > +
> > +BUTTONSET_INTERFACE {
> > +       libinput_device_buttonset_has_button;
> > +       libinput_device_buttonset_get_axis_type;
> > +       libinput_device_buttonset_get_num_axes;
> > +       libinput_event_buttonset_get_base_event;
> > +       libinput_event_buttonset_get_button;
> > +       libinput_event_buttonset_get_button_state;
> > +       libinput_event_buttonset_get_seat_button_count;
> > +       libinput_event_buttonset_get_time;
> > +       libinput_event_buttonset_get_time_usec;
> > +       libinput_event_buttonset_axis_has_changed;
> > +       libinput_event_get_buttonset_event;
> > +       libinput_event_buttonset_get_x;
> > +       libinput_event_buttonset_get_x_transformed;
> > +       libinput_event_buttonset_get_y;
> > +       libinput_event_buttonset_get_y_transformed;
> > +       libinput_event_buttonset_get_z;
> > +       libinput_event_buttonset_get_dx;
> > +       libinput_event_buttonset_get_dy;
> > +       libinput_event_buttonset_get_dz;
> > +       libinput_event_buttonset_get_rotation_x;
> > +       libinput_event_buttonset_get_rotation_y;
> > +       libinput_event_buttonset_get_rotation_z;
> > +       libinput_event_buttonset_get_ring_position;
> > +       libinput_event_buttonset_get_ring_source;
> > +       libinput_event_buttonset_get_strip_position;
> > +       libinput_event_buttonset_get_strip_source;
> > +       libinput_event_buttonset_get_dx;
> > +       libinput_event_buttonset_get_dy;
> > +       libinput_event_buttonset_get_dz;
> > +       libinput_event_buttonset_get_ring_position;
> > +       libinput_event_buttonset_get_strip_position;
> > +} LIBINPUT_TABLET_SUPPORT;
> > diff --git a/test/litest.c b/test/litest.c
> > index 3da187c..0d93ab4 100644
> > --- a/test/litest.c
> > +++ b/test/litest.c
> > @@ -1934,6 +1934,12 @@ litest_event_type_str(struct libinput_event *event)
> >         case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
> >                 str = "TABLET BUTTON";
> >                 break;
> > +       case LIBINPUT_EVENT_BUTTONSET_AXIS:
> > +               str = "BUTTONSET AXIS";
> > +               break;
> > +       case LIBINPUT_EVENT_BUTTONSET_BUTTON:
> > +               str = "BUTTONSET BUTTON";
> > +               break;
> >         }
> >         return str;
> >  }
> > diff --git a/tools/event-debug.c b/tools/event-debug.c
> > index 648111e..359b437 100644
> > --- a/tools/event-debug.c
> > +++ b/tools/event-debug.c
> > @@ -121,6 +121,12 @@ print_event_header(struct libinput_event *ev)
> >         case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
> >                 type = "TABLET_BUTTON";
> >                 break;
> > +       case LIBINPUT_EVENT_BUTTONSET_AXIS:
> > +               type = "BUTTONSET_AXIS";
> > +               break;
> > +       case LIBINPUT_EVENT_BUTTONSET_BUTTON:
> > +               type = "BUTTONSET_BUTTON";
> > +               break;
> >         }
> >
> >         printf("%-7s    %-16s ", libinput_device_get_sysname(dev), type);
> > @@ -172,6 +178,9 @@ print_device_notify(struct libinput_event *ev)
> >         if (libinput_device_has_capability(dev,
> >                                            LIBINPUT_DEVICE_CAP_TABLET_TOOL))
> >                 printf("T");
> > +       if (libinput_device_has_capability(dev,
> > +                                          LIBINPUT_DEVICE_CAP_BUTTONSET))
> > +               printf("b");
> >
> >         if (libinput_device_get_size(dev, &w, &h) == 0)
> >                 printf("\tsize %.2f/%.2fmm", w, h);
> > @@ -315,6 +324,57 @@ print_tablet_button_event(struct libinput_event *ev)
> >  }
> >
> >  static void
> > +print_buttonset_button_event(struct libinput_event *ev)
> > +{
> > +       struct libinput_event_buttonset *b = libinput_event_get_buttonset_event(ev);
> > +       enum libinput_button_state state;
> > +
> > +       print_event_time(libinput_event_buttonset_get_time(b));
> > +
> > +       state = libinput_event_buttonset_get_button_state(b);
> > +       printf("%3d %s, seat count: %u\n",
> > +              libinput_event_buttonset_get_button(b),
> > +              state == LIBINPUT_BUTTON_STATE_PRESSED ? "pressed" : "released",
> > +              libinput_event_buttonset_get_seat_button_count(b));
> > +}
> > +
> > +static void
> > +print_buttonset_axis_event(struct libinput_event *ev)
> > +{
> > +       struct libinput_event_buttonset *b = libinput_event_get_buttonset_event(ev);
> > +       const char *axis_name;
> > +       double val;
> > +       unsigned int axis;
> > +       struct libinput_device *device = libinput_event_get_device(ev);
> > +
> > +       print_event_time(libinput_event_buttonset_get_time(b));
> > +
> > +       for (axis = 0;
> > +            axis < libinput_device_buttonset_get_num_axes(device);
> > +            axis++) {
> > +               if (!libinput_event_buttonset_axis_has_changed(b, axis))
> > +                       continue;
> > +
> > +               switch(libinput_device_buttonset_get_axis_type(device, axis)) {
> > +               case LIBINPUT_BUTTONSET_AXIS_RING:
> > +                       axis_name = "ring";
> > +                       val = libinput_event_buttonset_get_ring_position(b, axis);
> > +                       break;
> > +               case LIBINPUT_BUTTONSET_AXIS_STRIP:
> > +                       axis_name = "strip";
> > +                       val = libinput_event_buttonset_get_strip_position(b, axis);
> > +                       break;
> > +               default:
> > +                       axis_name = "UNKNOWN";
> > +                       break;
> > +               }
> > +               printf("\t%s: %.2f", axis_name, val);
> > +       }
> > +
> > +       printf("\n");
> > +}
> > +
> > +static void
> >  print_pointer_axis_event(struct libinput_event *ev)
> >  {
> >         struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
> > @@ -647,6 +707,12 @@ handle_and_print_events(struct libinput *li)
> >                 case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
> >                         print_tablet_button_event(ev);
> >                         break;
> > +               case LIBINPUT_EVENT_BUTTONSET_BUTTON:
> > +                       print_buttonset_button_event(ev);
> > +                       break;
> > +               case LIBINPUT_EVENT_BUTTONSET_AXIS:
> > +                       print_buttonset_axis_event(ev);
> > +                       break;
> >                 }
> >
> >                 libinput_event_destroy(ev);
> > diff --git a/tools/event-gui.c b/tools/event-gui.c
> > index fa0e1a0..e258d69 100644
> > --- a/tools/event-gui.c
> > +++ b/tools/event-gui.c
> > @@ -710,6 +710,9 @@ handle_event_libinput(GIOChannel *source, GIOCondition condition, gpointer data)
> >                 case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
> >                         handle_event_tablet(ev, w);
> >                         break;
> > +               case LIBINPUT_EVENT_BUTTONSET_AXIS:
> > +               case LIBINPUT_EVENT_BUTTONSET_BUTTON:
> > +                       break;
> >                 }
> >
> >                 libinput_event_destroy(ev);
> > --
> > 2.5.0
> >
> 


More information about the wayland-devel mailing list