Add the LIBINPUT_DEVICE_CAP_TABLET_PAD capability and matching interface

This interface handles the buttons on the physical tablet itself, including
the touch ring and the strip.

A notable difference to other libinput interfaces here is that we do not use
linux/input.h event codes for buttons. Instead, the buttons are merely
numbered sequentially, starting at button 1. This means:
* the API is different, instead of get_button() we have get_button_number() to
  drive the point home
* there is no seat button count. pads are inherently different devices and
  compositors should treat them as such. The seat button count makes sense
  when you want to know how many devices have BTN_LEFT down, but it makes no
  sense for buttons where all the semantics are handled by the compositor
  anyway.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Jason Gerecke <jason.gerecke@wacom.com>
Reviewed-by: Carlos Garnacho <carlosg@gnome.org>
This commit is contained in:
Peter Hutterer 2016-01-21 12:35:11 +10:00
parent 61e58a4c1f
commit b2a3706948
8 changed files with 740 additions and 7 deletions

View file

@ -8,15 +8,21 @@ Apple iPad.
@image html tablet.svg "Illustration of a graphics tablet"
@section tablet-tools Tablet buttons vs. tablet tools
@section tablet-tools Pad buttons vs. tablet tools
Most tablets provide two types of devices. The pysical tablet often provides
a number of buttons and a touch ring or strip. Interaction on the drawing
surface of the tablet requires a tool, usually in the shape of a stylus.
The libinput interface exposed by devices with the @ref
Most tablets provide two types of devices. The physical tablet often
provides a number of buttons and a touch ring or strip. Interaction on the
drawing surface of the tablet requires a tool, usually in the shape of a
stylus. The libinput interface exposed by devices with the @ref
LIBINPUT_DEVICE_CAP_TABLET_TOOL capability applies only to events generated
by tools.
Buttons, rings or strips on the physical tablet hardware (the "pad") are
exposed by devices with the @ref LIBINPUT_DEVICE_CAP_TABLET_PAD capability.
Pad events do not require a tool to be in proximity. Note that both
capabilities may exist on the same device though usually they are split
across multiple kernel devices.
Touch events on the tablet integrated into a screen itself are exposed
through the @ref LIBINPUT_DEVICE_CAP_TOUCH capability. Touch events on a
standalone tablet are exposed through the @ref LIBINPUT_DEVICE_CAP_POINTER
@ -25,7 +31,7 @@ node for the touch device, resulting in a separate libinput device.
See libinput_device_get_device_group() for information on how to associate
the touch part with other devices exposed by the same physical hardware.
@section tablet-tip Tool tip events vs. button events
@section tablet-tip Tool tip events vs. tool button events
The primary use of a tablet tool is to draw on the surface of the tablet.
When the tool tip comes into contact with the surface, libinput sends an
@ -113,6 +119,8 @@ tablets however extends further than the user may lift the mouse, i.e. the
tool may not be lifted out of physical proximity. For such tools, libinput
provides software-emulated proximity.
Events from the pad do not require proximity, they may be sent any time.
@section tablet-pressure-offset Pressure offset on worn-out tools
When a tool is used for an extended period it can wear down physically. A
@ -209,4 +217,30 @@ libinput_event_tablet_tool_get_y_transformed() the resulting value may be
less than 0 or larger than the upper range provided. It is up to the caller
to test for this and handle or ignore these events accordingly.
@section tablet-pad-buttons Tablet pad button numbers
Tablet Pad buttons are numbered sequentially, starting with button 0. Thus
button numbers returned by libinput_event_tablet_pad_get_button_number()
have no semantic meaning, a notable difference to the button codes returned
by other libinput interfaces (e.g. libinput_event_tablet_tool_get_button()).
The Linux kernel requires all input events to have semantic event codes,
but generic buttons like those on a pad cannot easily be assigned semantic
codes. The kernel supports generic codes in the form of BTN_0 through to
BTN_9 and additional unnamed space up until code 0x10f. Additional generic
buttons are available as BTN_A in the range dedicated for gamepads and
joysticks. Thus, tablet with a large number of buttons have to map across
two semantic ranges, have to use unnamed kernel button codes or risk leaking
into an unrelated range. libinput transparently maps the kernel event codes
into a sequential button range on the pad. Callers should use external
sources like libwacom to associate button numbers to their position on the
tablet.
Some buttons may have expected default behaviors. For example, on Wacom
Intuos Pro series tablets, the button inside the touch ring is expected to
switch between a mode switch. Mode switching is a feature implemented in the
caller and libinput does not provide specific handling. Callers should use
external sources like libwacom to identify which buttons have semantic
behaviors.
*/

View file

@ -544,6 +544,24 @@ tablet_notify_button(struct libinput_device *device,
int32_t button,
enum libinput_button_state state);
void
tablet_pad_notify_button(struct libinput_device *device,
uint64_t time,
int32_t button,
enum libinput_button_state state);
void
tablet_pad_notify_ring(struct libinput_device *device,
uint64_t time,
unsigned int number,
double value,
enum libinput_tablet_pad_ring_axis_source source);
void
tablet_pad_notify_strip(struct libinput_device *device,
uint64_t time,
unsigned int number,
double value,
enum libinput_tablet_pad_strip_axis_source source);
static inline uint64_t
libinput_now(struct libinput *libinput)
{

View file

@ -138,6 +138,23 @@ struct libinput_event_tablet_tool {
enum libinput_tablet_tool_tip_state tip_state;
};
struct libinput_event_tablet_pad {
struct libinput_event base;
uint32_t button;
enum libinput_button_state state;
uint64_t time;
struct {
enum libinput_tablet_pad_ring_axis_source source;
double position;
int number;
} ring;
struct {
enum libinput_tablet_pad_strip_axis_source source;
double position;
int number;
} strip;
};
static void
libinput_default_log_func(struct libinput *libinput,
enum libinput_log_priority priority,
@ -318,6 +335,19 @@ libinput_event_get_tablet_tool_event(struct libinput_event *event)
return (struct libinput_event_tablet_tool *) event;
}
LIBINPUT_EXPORT struct libinput_event_tablet_pad *
libinput_event_get_tablet_pad_event(struct libinput_event *event)
{
require_event_type(libinput_event_get_context(event),
event->type,
NULL,
LIBINPUT_EVENT_TABLET_PAD_RING,
LIBINPUT_EVENT_TABLET_PAD_STRIP,
LIBINPUT_EVENT_TABLET_PAD_BUTTON);
return (struct libinput_event_tablet_pad *) event;
}
LIBINPUT_EXPORT struct libinput_event_device_notify *
libinput_event_get_device_notify_event(struct libinput_event *event)
{
@ -1956,6 +1986,9 @@ device_has_cap(struct libinput_device *device,
case LIBINPUT_DEVICE_CAP_TABLET_TOOL:
capability = "CAP_TABLET_TOOL";
break;
case LIBINPUT_DEVICE_CAP_TABLET_PAD:
capability = "CAP_TABLET_PAD";
break;
}
log_bug_libinput(device->seat->libinput,
@ -2343,6 +2376,82 @@ tablet_notify_button(struct libinput_device *device,
&button_event->base);
}
void
tablet_pad_notify_button(struct libinput_device *device,
uint64_t time,
int32_t button,
enum libinput_button_state state)
{
struct libinput_event_tablet_pad *button_event;
button_event = zalloc(sizeof *button_event);
if (!button_event)
return;
*button_event = (struct libinput_event_tablet_pad) {
.time = time,
.button = button,
.state = state,
};
post_device_event(device,
time,
LIBINPUT_EVENT_TABLET_PAD_BUTTON,
&button_event->base);
}
void
tablet_pad_notify_ring(struct libinput_device *device,
uint64_t time,
unsigned int number,
double value,
enum libinput_tablet_pad_ring_axis_source source)
{
struct libinput_event_tablet_pad *ring_event;
ring_event = zalloc(sizeof *ring_event);
if (!ring_event)
return;
*ring_event = (struct libinput_event_tablet_pad) {
.time = time,
.ring.number = number,
.ring.position = value,
.ring.source = source,
};
post_device_event(device,
time,
LIBINPUT_EVENT_TABLET_PAD_RING,
&ring_event->base);
}
void
tablet_pad_notify_strip(struct libinput_device *device,
uint64_t time,
unsigned int number,
double value,
enum libinput_tablet_pad_strip_axis_source source)
{
struct libinput_event_tablet_pad *strip_event;
strip_event = zalloc(sizeof *strip_event);
if (!strip_event)
return;
*strip_event = (struct libinput_event_tablet_pad) {
.time = time,
.strip.number = number,
.strip.position = value,
.strip.source = source,
};
post_device_event(device,
time,
LIBINPUT_EVENT_TABLET_PAD_STRIP,
&strip_event->base);
}
static void
gesture_notify(struct libinput_device *device,
uint64_t time,
@ -2448,6 +2557,9 @@ event_type_to_str(enum libinput_event_type type)
CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_TIP);
CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_BUTTON);
CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_RING);
CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_STRIP);
CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN);
CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE);
CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_END);
@ -2679,6 +2791,24 @@ libinput_device_keyboard_has_key(struct libinput_device *device, uint32_t code)
return evdev_device_has_key((struct evdev_device *)device, code);
}
LIBINPUT_EXPORT int
libinput_device_tablet_pad_get_num_buttons(struct libinput_device *device)
{
return 0;
}
LIBINPUT_EXPORT int
libinput_device_tablet_pad_get_num_rings(struct libinput_device *device)
{
return 0;
}
LIBINPUT_EXPORT int
libinput_device_tablet_pad_get_num_strips(struct libinput_device *device)
{
return 0;
}
LIBINPUT_EXPORT struct libinput_event *
libinput_event_device_notify_get_base_event(struct libinput_event_device_notify *event)
{
@ -2751,6 +2881,133 @@ libinput_event_tablet_tool_get_base_event(struct libinput_event_tablet_tool *eve
return &event->base;
}
LIBINPUT_EXPORT double
libinput_event_tablet_pad_get_ring_position(struct libinput_event_tablet_pad *event)
{
require_event_type(libinput_event_get_context(&event->base),
event->base.type,
0.0,
LIBINPUT_EVENT_TABLET_PAD_RING);
return event->ring.position;
}
LIBINPUT_EXPORT unsigned int
libinput_event_tablet_pad_get_ring_number(struct libinput_event_tablet_pad *event)
{
require_event_type(libinput_event_get_context(&event->base),
event->base.type,
0,
LIBINPUT_EVENT_TABLET_PAD_RING);
return event->ring.number;
}
LIBINPUT_EXPORT enum libinput_tablet_pad_ring_axis_source
libinput_event_tablet_pad_get_ring_source(struct libinput_event_tablet_pad *event)
{
require_event_type(libinput_event_get_context(&event->base),
event->base.type,
LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN,
LIBINPUT_EVENT_TABLET_PAD_RING);
return event->ring.source;
}
LIBINPUT_EXPORT double
libinput_event_tablet_pad_get_strip_position(struct libinput_event_tablet_pad *event)
{
require_event_type(libinput_event_get_context(&event->base),
event->base.type,
0.0,
LIBINPUT_EVENT_TABLET_PAD_STRIP);
return event->strip.position;
}
LIBINPUT_EXPORT unsigned int
libinput_event_tablet_pad_get_strip_number(struct libinput_event_tablet_pad *event)
{
require_event_type(libinput_event_get_context(&event->base),
event->base.type,
0,
LIBINPUT_EVENT_TABLET_PAD_STRIP);
return event->strip.number;
}
LIBINPUT_EXPORT enum libinput_tablet_pad_strip_axis_source
libinput_event_tablet_pad_get_strip_source(struct libinput_event_tablet_pad *event)
{
require_event_type(libinput_event_get_context(&event->base),
event->base.type,
LIBINPUT_TABLET_PAD_STRIP_SOURCE_UNKNOWN,
LIBINPUT_EVENT_TABLET_PAD_STRIP);
return event->strip.source;
}
LIBINPUT_EXPORT uint32_t
libinput_event_tablet_pad_get_button_number(struct libinput_event_tablet_pad *event)
{
require_event_type(libinput_event_get_context(&event->base),
event->base.type,
0,
LIBINPUT_EVENT_TABLET_PAD_BUTTON);
return event->button;
}
LIBINPUT_EXPORT enum libinput_button_state
libinput_event_tablet_pad_get_button_state(struct libinput_event_tablet_pad *event)
{
require_event_type(libinput_event_get_context(&event->base),
event->base.type,
LIBINPUT_BUTTON_STATE_RELEASED,
LIBINPUT_EVENT_TABLET_PAD_BUTTON);
return event->state;
}
LIBINPUT_EXPORT uint32_t
libinput_event_tablet_pad_get_time(struct libinput_event_tablet_pad *event)
{
require_event_type(libinput_event_get_context(&event->base),
event->base.type,
0,
LIBINPUT_EVENT_TABLET_PAD_RING,
LIBINPUT_EVENT_TABLET_PAD_STRIP,
LIBINPUT_EVENT_TABLET_PAD_BUTTON);
return us2ms(event->time);
}
LIBINPUT_EXPORT uint64_t
libinput_event_tablet_pad_get_time_usec(struct libinput_event_tablet_pad *event)
{
require_event_type(libinput_event_get_context(&event->base),
event->base.type,
0,
LIBINPUT_EVENT_TABLET_PAD_RING,
LIBINPUT_EVENT_TABLET_PAD_STRIP,
LIBINPUT_EVENT_TABLET_PAD_BUTTON);
return event->time;
}
LIBINPUT_EXPORT struct libinput_event *
libinput_event_tablet_pad_get_base_event(struct libinput_event_tablet_pad *event)
{
require_event_type(libinput_event_get_context(&event->base),
event->base.type,
NULL,
LIBINPUT_EVENT_TABLET_PAD_RING,
LIBINPUT_EVENT_TABLET_PAD_STRIP,
LIBINPUT_EVENT_TABLET_PAD_BUTTON);
return &event->base;
}
LIBINPUT_EXPORT struct libinput_device_group *
libinput_device_group_ref(struct libinput_device_group *group)
{

View file

@ -59,6 +59,7 @@ enum libinput_device_capability {
LIBINPUT_DEVICE_CAP_POINTER = 1,
LIBINPUT_DEVICE_CAP_TOUCH = 2,
LIBINPUT_DEVICE_CAP_TABLET_TOOL = 3,
LIBINPUT_DEVICE_CAP_TABLET_PAD = 4,
LIBINPUT_DEVICE_CAP_GESTURE = 5,
};
@ -134,6 +135,36 @@ enum libinput_pointer_axis_source {
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
};
/**
* @ingroup event_tablet
*
* The source for a @ref LIBINPUT_EVENT_TABLET_PAD_RING event. See
* libinput_event_tablet_pad_get_ring_source() for details.
*/
enum libinput_tablet_pad_ring_axis_source {
LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN = 1,
/**
* The event is caused by the movement of one or more fingers on
* the ring.
*/
LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER,
};
/**
* @ingroup event_tablet
*
* The source for a @ref LIBINPUT_EVENT_TABLET_PAD_STRIP event. See
* libinput_event_tablet_pad_get_strip_source() for details.
*/
enum libinput_tablet_pad_strip_axis_source {
LIBINPUT_TABLET_PAD_STRIP_SOURCE_UNKNOWN = 1,
/**
* The event is caused by the movement of one or more fingers on
* the strip.
*/
LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER,
};
/**
* @ingroup device
* @struct libinput_tablet_tool
@ -336,9 +367,34 @@ enum libinput_event_type {
* same logical hardware event, the order of the @ref
* LIBINPUT_EVENT_TABLET_TOOL_BUTTON and @ref
* LIBINPUT_EVENT_TABLET_TOOL_AXIS event is device-specific.
*
* This event is not to be confused with the button events emitted
* by the tablet pad. See @ref LIBINPUT_EVENT_TABLET_PAD_BUTTON.
*
* @see LIBINPUT_EVENT_TABLET_BUTTON
*/
LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
/**
* A button pressed on a device with the @ref
* LIBINPUT_DEVICE_CAP_TABLET_PAD capability.
*
* This event is not to be confused with the button events emitted
* by tools on a tablet. See @ref LIBINPUT_EVENT_TABLET_TOOL_BUTTON.
*/
LIBINPUT_EVENT_TABLET_PAD_BUTTON = 700,
/**
* A status change on a tablet ring with the
* LIBINPUT_DEVICE_CAP_TABLET_PAD capability.
*/
LIBINPUT_EVENT_TABLET_PAD_RING,
/**
* A status change on a strip on a device with the @ref
* LIBINPUT_DEVICE_CAP_TABLET_PAD capability.
*/
LIBINPUT_EVENT_TABLET_PAD_STRIP,
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN = 800,
LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
LIBINPUT_EVENT_GESTURE_SWIPE_END,
@ -445,6 +501,17 @@ struct libinput_event_touch;
*/
struct libinput_event_tablet_tool;
/**
* @ingroup event_tablet
* @struct libinput_event_tablet_pad
*
* Tablet pad event representing a button press, or ring/strip update on
* the tablet pad itself. Valid event types for this event are @ref
* LIBINPUT_EVENT_TABLET_PAD_BUTTON, @ref LIBINPUT_EVENT_TABLET_PAD_RING and
* @ref LIBINPUT_EVENT_TABLET_PAD_STRIP.
*/
struct libinput_event_tablet_pad;
/**
* @defgroup event Accessing and destruction of events
*/
@ -566,6 +633,19 @@ libinput_event_get_gesture_event(struct libinput_event *event);
struct libinput_event_tablet_tool *
libinput_event_get_tablet_tool_event(struct libinput_event *event);
/**
* @ingroup event
*
* Return the tablet pad event that is this input event. If the event type does not
* match the tablet pad event types, this function returns NULL.
*
* The inverse of this function is libinput_event_tablet_pad_get_base_event().
*
* @return A tablet pad event, or NULL for other events
*/
struct libinput_event_tablet_pad *
libinput_event_get_tablet_pad_event(struct libinput_event *event);
/**
* @ingroup event
*
@ -1357,7 +1437,17 @@ libinput_event_gesture_get_angle_delta(struct libinput_event_gesture *event);
/**
* @defgroup event_tablet Tablet events
*
* Events that come from tools on tablet devices.
* Events that come from tools on or the pad of tablet devices.
*
* Events from tablet devices are exposed by two interfaces, tools and pads.
* Tool events originate (usually) from a stylus-like device, pad events
* reflect any events originating from the physical tablet itself.
*
* Note that many tablets support touch events. These are exposed through
* the @ref LIBINPUT_DEVICE_CAP_POINTER interface (for external touchpad-like
* devices such as the Wacom Intuos series) or @ref
* LIBINPUT_DEVICE_CAP_TOUCH interface (for built-in touchscreen-like
* devices such as the Wacom Cintiq series).
*/
/**
@ -2105,6 +2195,182 @@ void
libinput_tablet_tool_set_user_data(struct libinput_tablet_tool *tool,
void *user_data);
/**
* @ingroup event_tablet
*
* @return The generic libinput_event of this event
*/
struct libinput_event *
libinput_event_tablet_pad_get_base_event(struct libinput_event_tablet_pad *event);
/**
* @ingroup event_tablet
*
* Returns the current position of the ring, in degrees counterclockwise
* from the northern-most point of the ring in the tablet's current logical
* orientation.
*
* If the source is @ref LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER,
* libinput sends a terminating event with a ring value of -1 when the
* finger is lifted from the ring. A caller may use this information to e.g.
* determine if kinetic scrolling should be triggered.
*
* @note It is an application bug to call this function for events other than
* @ref LIBINPUT_EVENT_TABLET_PAD_RING. For other events, this function
* returns 0.
*
* @param event The libinput tablet pad event
* @return The current value of the the axis
* @retval -1 The finger was lifted
*/
double
libinput_event_tablet_pad_get_ring_position(struct libinput_event_tablet_pad *event);
/**
* @ingroup event_tablet
*
* Returns the number of the ring that has changed state, with 0 being the
* first ring. On tablets with only one ring, this function always returns
* 0.
*
* @note It is an application bug to call this function for events other than
* @ref LIBINPUT_EVENT_TABLET_PAD_RING. For other events, this function
* returns 0.
*
* @param event The libinput tablet pad event
* @return The index of the ring that changed state
*/
unsigned int
libinput_event_tablet_pad_get_ring_number(struct libinput_event_tablet_pad *event);
/**
* @ingroup event_tablet
*
* Returns the source of the interaction with the ring. If the source is
* @ref LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER, libinput sends a ring
* position value of -1 to terminate the current interaction.
*
* @note It is an application bug to call this function for events other than
* @ref LIBINPUT_EVENT_TABLET_PAD_RING. For other events, this function
* returns 0.
*
* @param event The libinput tablet pad event
* @return The source of the ring interaction
*/
enum libinput_tablet_pad_ring_axis_source
libinput_event_tablet_pad_get_ring_source(struct libinput_event_tablet_pad *event);
/**
* @ingroup event_tablet
*
* Returns the current position of the strip, normalized to the range
* [0, 1], with 0 being the top/left-most point in the tablet's current
* logical orientation.
*
* If the source is @ref LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER,
* libinput sends a terminating event with a ring value of -1 when the
* finger is lifted from the ring. A caller may use this information to e.g.
* determine if kinetic scrolling should be triggered.
*
* @note It is an application bug to call this function for events other than
* @ref LIBINPUT_EVENT_TABLET_PAD_STRIP. For other events, this function
* returns 0.
*
* @param event The libinput tablet pad event
* @return The current value of the the axis
* @retval -1 The finger was lifted
*/
double
libinput_event_tablet_pad_get_strip_position(struct libinput_event_tablet_pad *event);
/**
* @ingroup event_tablet
*
* Returns the number of the strip that has changed state, with 0 being the
* first strip. On tablets with only one strip, this function always returns
* 0.
*
* @note It is an application bug to call this function for events other than
* @ref LIBINPUT_EVENT_TABLET_PAD_STRIP. For other events, this function
* returns 0.
*
* @param event The libinput tablet pad event
* @return The index of the strip that changed state
*/
unsigned int
libinput_event_tablet_pad_get_strip_number(struct libinput_event_tablet_pad *event);
/**
* @ingroup event_tablet
*
* Returns the source of the interaction with the strip. If the source is
* @ref LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER, libinput sends a strip
* position value of -1 to terminate the current interaction.
*
* @note It is an application bug to call this function for events other than
* @ref LIBINPUT_EVENT_TABLET_PAD_STRIP. For other events, this function
* returns 0.
*
* @param event The libinput tablet pad event
* @return The source of the strip interaction
*/
enum libinput_tablet_pad_strip_axis_source
libinput_event_tablet_pad_get_strip_source(struct libinput_event_tablet_pad *event);
/**
* @ingroup event_tablet
*
* Return the button number that triggered this event, starting at 0.
* For events that are not of type @ref LIBINPUT_EVENT_TABLET_PAD_BUTTON,
* this function returns 0.
*
* Note that the number returned is a generic sequential button number and
* not a semantic button code as defined in linux/input.h.
* See @ref tablet-pad-buttons for more details.
*
* @note It is an application bug to call this function for events other than
* @ref LIBINPUT_EVENT_TABLET_PAD_BUTTON. For other events, this function
* returns 0.
*
* @param event The libinput tablet pad event
* @return the button triggering this event
*/
uint32_t
libinput_event_tablet_pad_get_button_number(struct libinput_event_tablet_pad *event);
/**
* @ingroup event_tablet
*
* Return the button state of the event.
*
* @note It is an application bug to call this function for events other than
* @ref LIBINPUT_EVENT_TABLET_PAD_BUTTON. For other events, this function
* returns 0.
*
* @param event The libinput tablet pad event
* @return the button state triggering this event
*/
enum libinput_button_state
libinput_event_tablet_pad_get_button_state(struct libinput_event_tablet_pad *event);
/**
* @ingroup event_tablet
*
* @param event The libinput tablet pad event
* @return The event time for this event
*/
uint32_t
libinput_event_tablet_pad_get_time(struct libinput_event_tablet_pad *event);
/**
* @ingroup event_tablet
*
* @param event The libinput tablet pad event
* @return The event time for this event in microseconds
*/
uint64_t
libinput_event_tablet_pad_get_time_usec(struct libinput_event_tablet_pad *event);
/**
* @defgroup base Initialization and manipulation of libinput contexts
*/
@ -2931,6 +3197,51 @@ int
libinput_device_keyboard_has_key(struct libinput_device *device,
uint32_t code);
/**
* @ingroup device
*
* Return the number of buttons on a device with the
* @ref LIBINPUT_DEVICE_CAP_TABLET_PAD capability.
* Buttons on a pad device are numbered sequentially, see @ref
* tablet-pad-buttons for details.
*
* @param device A current input device
*
* @return The number of buttons supported by the device.
*/
int
libinput_device_tablet_pad_get_num_buttons(struct libinput_device *device);
/**
* @ingroup device
*
* Return the number of rings a device with the @ref
* LIBINPUT_DEVICE_CAP_TABLET_PAD capability provides.
*
* @param device A current input device
*
* @return The number of rings or 0 if the device has no rings.
*
* @see libinput_event_tablet_pad_get_ring_number
*/
int
libinput_device_tablet_pad_get_num_rings(struct libinput_device *device);
/**
* @ingroup device
*
* Return the number of strips a device with the @ref
* LIBINPUT_DEVICE_CAP_TABLET_PAD capability provides.
*
* @param device A current input device
*
* @return The number of strips or 0 if the device has no strips.
*
* @see libinput_event_tablet_pad_get_strip_number
*/
int
libinput_device_tablet_pad_get_num_strips(struct libinput_device *device);
/**
* @ingroup device
*

View file

@ -234,3 +234,22 @@ LIBINPUT_1.2 {
libinput_tablet_tool_set_user_data;
libinput_tablet_tool_unref;
} LIBINPUT_1.1;
TABLET_PAD {
libinput_device_tablet_pad_get_num_buttons;
libinput_device_tablet_pad_get_num_rings;
libinput_device_tablet_pad_get_num_strips;
libinput_event_get_tablet_pad_event;
libinput_event_tablet_pad_get_base_event;
libinput_event_tablet_pad_get_button_number;
libinput_event_tablet_pad_get_button_state;
libinput_event_tablet_pad_get_ring_position;
libinput_event_tablet_pad_get_ring_number;
libinput_event_tablet_pad_get_ring_source;
libinput_event_tablet_pad_get_strip_position;
libinput_event_tablet_pad_get_strip_number;
libinput_event_tablet_pad_get_strip_source;
libinput_event_tablet_pad_get_time;
libinput_event_tablet_pad_get_time_usec;
} LIBINPUT_1.2;

View file

@ -1963,6 +1963,15 @@ litest_event_type_str(struct libinput_event *event)
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
str = "TABLET TOOL BUTTON";
break;
case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
str = "TABLET PAD BUTTON";
break;
case LIBINPUT_EVENT_TABLET_PAD_RING:
str = "TABLET PAD RING";
break;
case LIBINPUT_EVENT_TABLET_PAD_STRIP:
str = "TABLET PAD STRIP";
break;
}
return str;
}

View file

@ -121,6 +121,15 @@ print_event_header(struct libinput_event *ev)
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
type = "TABLET_TOOL_BUTTON";
break;
case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
type = "TABLET_PAD_BUTTON";
break;
case LIBINPUT_EVENT_TABLET_PAD_RING:
type = "TABLET_PAD_RING";
break;
case LIBINPUT_EVENT_TABLET_PAD_STRIP:
type = "TABLET_PAD_STRIP";
break;
}
printf("%-7s %-16s ", libinput_device_get_sysname(dev), type);
@ -172,6 +181,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_TABLET_PAD))
printf("P");
if (libinput_device_get_size(dev, &w, &h) == 0)
printf("\tsize %.2f/%.2fmm", w, h);
@ -574,6 +586,66 @@ print_gesture_event_with_coords(struct libinput_event *ev)
}
}
static void
print_tablet_pad_button_event(struct libinput_event *ev)
{
struct libinput_event_tablet_pad *p = libinput_event_get_tablet_pad_event(ev);
enum libinput_button_state state;
print_event_time(libinput_event_tablet_pad_get_time(p));
state = libinput_event_tablet_pad_get_button_state(p);
printf("%3d %s\n",
libinput_event_tablet_pad_get_button_number(p),
state == LIBINPUT_BUTTON_STATE_PRESSED ? "pressed" : "released");
}
static void
print_tablet_pad_ring_event(struct libinput_event *ev)
{
struct libinput_event_tablet_pad *p = libinput_event_get_tablet_pad_event(ev);
const char *source = "<invalid>";
print_event_time(libinput_event_tablet_pad_get_time(p));
switch (libinput_event_tablet_pad_get_ring_source(p)) {
case LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER:
source = "finger";
break;
case LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN:
source = "unknown";
break;
}
printf("ring %d position %.2f (source %s)\n",
libinput_event_tablet_pad_get_ring_number(p),
libinput_event_tablet_pad_get_ring_position(p),
source);
}
static void
print_tablet_pad_strip_event(struct libinput_event *ev)
{
struct libinput_event_tablet_pad *p = libinput_event_get_tablet_pad_event(ev);
const char *source = "<invalid>";
print_event_time(libinput_event_tablet_pad_get_time(p));
switch (libinput_event_tablet_pad_get_strip_source(p)) {
case LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER:
source = "finger";
break;
case LIBINPUT_TABLET_PAD_STRIP_SOURCE_UNKNOWN:
source = "unknown";
break;
}
printf("strip %d position %.2f (source %s)\n",
libinput_event_tablet_pad_get_strip_number(p),
libinput_event_tablet_pad_get_strip_position(p),
source);
}
static int
handle_and_print_events(struct libinput *li)
{
@ -653,6 +725,15 @@ handle_and_print_events(struct libinput *li)
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
print_tablet_button_event(ev);
break;
case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
print_tablet_pad_button_event(ev);
break;
case LIBINPUT_EVENT_TABLET_PAD_RING:
print_tablet_pad_ring_event(ev);
break;
case LIBINPUT_EVENT_TABLET_PAD_STRIP:
print_tablet_pad_strip_event(ev);
break;
}
libinput_event_destroy(ev);

View file

@ -798,6 +798,10 @@ handle_event_libinput(GIOChannel *source, GIOCondition condition, gpointer data)
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
handle_event_tablet(ev, w);
break;
case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
case LIBINPUT_EVENT_TABLET_PAD_RING:
case LIBINPUT_EVENT_TABLET_PAD_STRIP:
break;
}
libinput_event_destroy(ev);