mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-20 06:50:05 +01:00
tablet: add a the Totem tool type to the tablet interface
This is the public API only, not the internal bits, so nothing will work just yet. This interface addition is for the Dell Canvas Totem tool, so let's go with the same name because options like "Rotary" are too ambiguous. The totem is a knob that can be placed on the surface, it provides us with location and rotation data. The touch major/minor fields are filled in by the current totem, but they're always the same size. The totem exports BTN_0 as well, so let's add that to the debug-events output. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
52e86f4b2a
commit
17d792445e
7 changed files with 232 additions and 2 deletions
|
|
@ -200,6 +200,12 @@ axis_to_evcode(const enum libinput_tablet_tool_axis axis)
|
|||
case LIBINPUT_TABLET_TOOL_AXIS_SLIDER:
|
||||
evcode = ABS_WHEEL;
|
||||
break;
|
||||
case LIBINPUT_TABLET_TOOL_AXIS_SIZE_MAJOR:
|
||||
evcode = ABS_MT_TOUCH_MAJOR;
|
||||
break;
|
||||
case LIBINPUT_TABLET_TOOL_AXIS_SIZE_MINOR:
|
||||
evcode = ABS_MT_TOUCH_MINOR;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,12 @@ struct device_coord_rect {
|
|||
int w, h;
|
||||
};
|
||||
|
||||
/* A pair of major/minor in mm */
|
||||
struct phys_ellipsis {
|
||||
double major;
|
||||
double minor;
|
||||
};
|
||||
|
||||
/* A pair of tilt flags */
|
||||
struct wheel_tilt_flags {
|
||||
bool vertical, horizontal;
|
||||
|
|
@ -349,9 +355,11 @@ enum libinput_tablet_tool_axis {
|
|||
LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z = 7,
|
||||
LIBINPUT_TABLET_TOOL_AXIS_SLIDER = 8,
|
||||
LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL = 9,
|
||||
LIBINPUT_TABLET_TOOL_AXIS_SIZE_MAJOR = 10,
|
||||
LIBINPUT_TABLET_TOOL_AXIS_SIZE_MINOR = 11,
|
||||
};
|
||||
|
||||
#define LIBINPUT_TABLET_TOOL_AXIS_MAX LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL
|
||||
#define LIBINPUT_TABLET_TOOL_AXIS_MAX LIBINPUT_TABLET_TOOL_AXIS_SIZE_MINOR
|
||||
|
||||
struct tablet_axes {
|
||||
struct device_coords point;
|
||||
|
|
@ -363,6 +371,7 @@ struct tablet_axes {
|
|||
double slider;
|
||||
double wheel;
|
||||
int wheel_discrete;
|
||||
struct phys_ellipsis size;
|
||||
};
|
||||
|
||||
struct libinput_tablet_tool {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2013 Jonas Ådahl
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
* Copyright © 2013-2018 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -1153,6 +1153,38 @@ libinput_event_tablet_tool_slider_has_changed(
|
|||
LIBINPUT_TABLET_TOOL_AXIS_SLIDER);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT int
|
||||
libinput_event_tablet_tool_size_major_has_changed(
|
||||
struct libinput_event_tablet_tool *event)
|
||||
{
|
||||
require_event_type(libinput_event_get_context(&event->base),
|
||||
event->base.type,
|
||||
0,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_AXIS,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_TIP,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
|
||||
|
||||
return bit_is_set(event->changed_axes,
|
||||
LIBINPUT_TABLET_TOOL_AXIS_SIZE_MAJOR);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT int
|
||||
libinput_event_tablet_tool_size_minor_has_changed(
|
||||
struct libinput_event_tablet_tool *event)
|
||||
{
|
||||
require_event_type(libinput_event_get_context(&event->base),
|
||||
event->base.type,
|
||||
0,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_AXIS,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_TIP,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
|
||||
|
||||
return bit_is_set(event->changed_axes,
|
||||
LIBINPUT_TABLET_TOOL_AXIS_SIZE_MINOR);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT int
|
||||
libinput_event_tablet_tool_wheel_has_changed(
|
||||
struct libinput_event_tablet_tool *event)
|
||||
|
|
@ -1315,6 +1347,34 @@ libinput_event_tablet_tool_get_slider_position(struct libinput_event_tablet_tool
|
|||
return event->axes.slider;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT double
|
||||
libinput_event_tablet_tool_get_size_major(struct libinput_event_tablet_tool *event)
|
||||
{
|
||||
require_event_type(libinput_event_get_context(&event->base),
|
||||
event->base.type,
|
||||
0,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_AXIS,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_TIP,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
|
||||
|
||||
return event->axes.size.major;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT double
|
||||
libinput_event_tablet_tool_get_size_minor(struct libinput_event_tablet_tool *event)
|
||||
{
|
||||
require_event_type(libinput_event_get_context(&event->base),
|
||||
event->base.type,
|
||||
0,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_AXIS,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_TIP,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
|
||||
|
||||
return event->axes.size.minor;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT double
|
||||
libinput_event_tablet_tool_get_wheel_delta(struct libinput_event_tablet_tool *event)
|
||||
{
|
||||
|
|
@ -1551,6 +1611,13 @@ libinput_tablet_tool_has_wheel(struct libinput_tablet_tool *tool)
|
|||
LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT int
|
||||
libinput_tablet_tool_has_size(struct libinput_tablet_tool *tool)
|
||||
{
|
||||
return bit_is_set(tool->axis_caps,
|
||||
LIBINPUT_TABLET_TOOL_AXIS_SIZE_MAJOR);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT int
|
||||
libinput_tablet_tool_has_button(struct libinput_tablet_tool *tool,
|
||||
uint32_t code)
|
||||
|
|
|
|||
|
|
@ -341,6 +341,9 @@ enum libinput_tablet_tool_type {
|
|||
LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH, /**< An airbrush-like tool */
|
||||
LIBINPUT_TABLET_TOOL_TYPE_MOUSE, /**< A mouse bound to the tablet */
|
||||
LIBINPUT_TABLET_TOOL_TYPE_LENS, /**< A mouse tool with a lens */
|
||||
LIBINPUT_TABLET_TOOL_TYPE_TOTEM, /**< A rotary device with
|
||||
positional and rotation
|
||||
data */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2082,6 +2085,49 @@ libinput_event_tablet_tool_rotation_has_changed(
|
|||
int
|
||||
libinput_event_tablet_tool_slider_has_changed(
|
||||
struct libinput_event_tablet_tool *event);
|
||||
|
||||
/**
|
||||
* @ingroup event_tablet
|
||||
*
|
||||
* Check if the size major axis was updated in this event.
|
||||
* For events that are not of type @ref LIBINPUT_EVENT_TABLET_TOOL_AXIS,
|
||||
* @ref LIBINPUT_EVENT_TABLET_TOOL_TIP, or
|
||||
* @ref LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, this function returns 0.
|
||||
*
|
||||
* @note It is an application bug to call this function for events other
|
||||
* than @ref LIBINPUT_EVENT_TABLET_TOOL_AXIS, @ref
|
||||
* LIBINPUT_EVENT_TABLET_TOOL_TIP, or @ref
|
||||
* LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, or @ref
|
||||
* LIBINPUT_EVENT_TABLET_TOOL_BUTTON.
|
||||
*
|
||||
* @param event The libinput tablet tool event
|
||||
* @return 1 if the axis was updated or 0 otherwise
|
||||
*/
|
||||
int
|
||||
libinput_event_tablet_tool_size_major_has_changed(
|
||||
struct libinput_event_tablet_tool *event);
|
||||
|
||||
/**
|
||||
* @ingroup event_tablet
|
||||
*
|
||||
* Check if the size minor axis was updated in this event.
|
||||
* For events that are not of type @ref LIBINPUT_EVENT_TABLET_TOOL_AXIS,
|
||||
* @ref LIBINPUT_EVENT_TABLET_TOOL_TIP, or
|
||||
* @ref LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, this function returns 0.
|
||||
*
|
||||
* @note It is an application bug to call this function for events other
|
||||
* than @ref LIBINPUT_EVENT_TABLET_TOOL_AXIS, @ref
|
||||
* LIBINPUT_EVENT_TABLET_TOOL_TIP, or @ref
|
||||
* LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, or @ref
|
||||
* LIBINPUT_EVENT_TABLET_TOOL_BUTTON.
|
||||
*
|
||||
* @param event The libinput tablet tool event
|
||||
* @return 1 if the axis was updated or 0 otherwise
|
||||
*/
|
||||
int
|
||||
libinput_event_tablet_tool_size_minor_has_changed(
|
||||
struct libinput_event_tablet_tool *event);
|
||||
|
||||
/**
|
||||
* @ingroup event_tablet
|
||||
*
|
||||
|
|
@ -2293,6 +2339,42 @@ libinput_event_tablet_tool_get_rotation(struct libinput_event_tablet_tool *event
|
|||
double
|
||||
libinput_event_tablet_tool_get_slider_position(struct libinput_event_tablet_tool *event);
|
||||
|
||||
/**
|
||||
* @ingroup event_tablet
|
||||
*
|
||||
* Returns the current size in mm along the major axis of the touching
|
||||
* ellipse. This axis is not necessarily aligned with either x or y, the
|
||||
* rotation must be taken into account.
|
||||
*
|
||||
* Where no rotation is available on a tool, or where rotation is zero, the
|
||||
* major axis aligns with the y axis and the minor axis with the x axis.
|
||||
*
|
||||
* If this axis does not exist on the current tool, this function returns 0.
|
||||
*
|
||||
* @param event The libinput tablet tool event
|
||||
* @return The current value of the axis major in mm
|
||||
*/
|
||||
double
|
||||
libinput_event_tablet_tool_get_size_major(struct libinput_event_tablet_tool *event);
|
||||
|
||||
/**
|
||||
* @ingroup event_tablet
|
||||
*
|
||||
* Returns the current size in mm along the minor axis of the touching
|
||||
* ellipse. This axis is not necessarily aligned with either x or y, the
|
||||
* rotation must be taken into account.
|
||||
*
|
||||
* Where no rotation is available on a tool, or where rotation is zero, the
|
||||
* minor axis aligns with the y axis and the minor axis with the x axis.
|
||||
*
|
||||
* If this axis does not exist on the current tool, this function returns 0.
|
||||
*
|
||||
* @param event The libinput tablet tool event
|
||||
* @return The current value of the axis minor in mm
|
||||
*/
|
||||
double
|
||||
libinput_event_tablet_tool_get_size_minor(struct libinput_event_tablet_tool *event);
|
||||
|
||||
/**
|
||||
* @ingroup event_tablet
|
||||
*
|
||||
|
|
@ -2664,6 +2746,20 @@ libinput_tablet_tool_has_rotation(struct libinput_tablet_tool *tool);
|
|||
int
|
||||
libinput_tablet_tool_has_slider(struct libinput_tablet_tool *tool);
|
||||
|
||||
/**
|
||||
* @ingroup event_tablet
|
||||
*
|
||||
* Return whether the tablet tool has a ellipsis major and minor.
|
||||
* Where the underlying hardware only supports one of either major or minor,
|
||||
* libinput emulates the other axis as a circular contact, i.e. major ==
|
||||
* minor for all values of major.
|
||||
*
|
||||
* @param tool The tool to check the axis capabilities of
|
||||
* @return Nonzero if the axis is available, zero otherwise.
|
||||
*/
|
||||
int
|
||||
libinput_tablet_tool_has_size(struct libinput_tablet_tool *tool);
|
||||
|
||||
/**
|
||||
* @ingroup event_tablet
|
||||
*
|
||||
|
|
|
|||
|
|
@ -297,3 +297,11 @@ LIBINPUT_1.9 {
|
|||
LIBINPUT_1.11 {
|
||||
libinput_device_touch_get_touch_count;
|
||||
} LIBINPUT_1.9;
|
||||
|
||||
LIBINPUT_1.14 {
|
||||
libinput_tablet_tool_has_size;
|
||||
libinput_event_tablet_tool_get_size_major;
|
||||
libinput_event_tablet_tool_get_size_minor;
|
||||
libinput_event_tablet_tool_size_major_has_changed;
|
||||
libinput_event_tablet_tool_size_minor_has_changed;
|
||||
} LIBINPUT_1.11;
|
||||
|
|
|
|||
|
|
@ -366,6 +366,7 @@ print_tablet_axes(struct libinput_event_tablet_tool *t)
|
|||
double dist, pressure;
|
||||
double rotation, slider, wheel;
|
||||
double delta;
|
||||
double major, minor;
|
||||
|
||||
#define changed_sym(ev, ax) \
|
||||
(libinput_event_tablet_tool_##ax##_has_changed(ev) ? "*" : "")
|
||||
|
|
@ -415,6 +416,14 @@ print_tablet_axes(struct libinput_event_tablet_tool *t)
|
|||
wheel, changed_sym(t, wheel),
|
||||
(int)delta);
|
||||
}
|
||||
|
||||
if (libinput_tablet_tool_has_size(tool)) {
|
||||
major = libinput_event_tablet_tool_get_size_major(t);
|
||||
minor = libinput_event_tablet_tool_get_size_minor(t);
|
||||
printq("\tsize: %.2f%s/%.2f%s",
|
||||
major, changed_sym(t, size_major),
|
||||
minor, changed_sym(t, size_minor));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -548,6 +557,9 @@ print_proximity_event(struct libinput_event *ev)
|
|||
case LIBINPUT_TABLET_TOOL_TYPE_LENS:
|
||||
tool_str = "lens";
|
||||
break;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_TOTEM:
|
||||
tool_str = "totem";
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
|
@ -586,6 +598,8 @@ print_proximity_event(struct libinput_event *ev)
|
|||
printq("s");
|
||||
if (libinput_tablet_tool_has_wheel(tool))
|
||||
printq("w");
|
||||
if (libinput_tablet_tool_has_size(tool))
|
||||
printq("S");
|
||||
|
||||
printq("\tbtn:");
|
||||
if (libinput_tablet_tool_has_button(tool, BTN_TOUCH))
|
||||
|
|
@ -604,6 +618,8 @@ print_proximity_event(struct libinput_event *ev)
|
|||
printq("Sd");
|
||||
if (libinput_tablet_tool_has_button(tool, BTN_EXTRA))
|
||||
printq("Ex");
|
||||
if (libinput_tablet_tool_has_button(tool, BTN_0))
|
||||
printq("0");
|
||||
}
|
||||
|
||||
printq("\n");
|
||||
|
|
|
|||
|
|
@ -134,6 +134,8 @@ struct window {
|
|||
double pressure;
|
||||
double distance;
|
||||
double tilt_x, tilt_y;
|
||||
double rotation;
|
||||
double size_major, size_minor;
|
||||
|
||||
/* these are for the delta coordinates, but they're not
|
||||
* deltas, they are converted into abs positions */
|
||||
|
|
@ -473,13 +475,36 @@ draw_tablet(struct window *w, cairo_t *cr)
|
|||
cairo_set_source_rgb(cr, .2, .8, .8);
|
||||
|
||||
cairo_translate(cr, w->tool.x, w->tool.y);
|
||||
/* scale of 2.5 is large enough to make the marker visible around the
|
||||
physical totem */
|
||||
cairo_scale(cr,
|
||||
1.0 + w->tool.size_major * 2.5,
|
||||
1.0 + w->tool.size_minor * 2.5);
|
||||
cairo_scale(cr, 1.0 + w->tool.tilt_x/30.0, 1.0 + w->tool.tilt_y/30.0);
|
||||
if (w->tool.rotation)
|
||||
cairo_rotate(cr, w->tool.rotation * M_PI/180.0);
|
||||
if (w->tool.pressure)
|
||||
cairo_set_source_rgb(cr, .8, .8, .2);
|
||||
cairo_arc(cr, 0, 0,
|
||||
1 + 10 * max(w->tool.pressure, w->tool.distance),
|
||||
0, 2 * M_PI);
|
||||
cairo_fill(cr);
|
||||
cairo_restore(cr);
|
||||
|
||||
/* The line to indicate the origin */
|
||||
if (w->tool.size_major) {
|
||||
cairo_save(cr);
|
||||
cairo_scale(cr, 1.0, 1.0);
|
||||
cairo_translate(cr, w->tool.x, w->tool.y);
|
||||
if (w->tool.rotation)
|
||||
cairo_rotate(cr, w->tool.rotation * M_PI/180.0);
|
||||
cairo_set_source_rgb(cr, .0, .0, .0);
|
||||
cairo_move_to(cr, 0, 0);
|
||||
cairo_rel_line_to(cr, 0, -w->tool.size_major * 2.5);
|
||||
cairo_stroke(cr);
|
||||
cairo_restore(cr);
|
||||
}
|
||||
|
||||
/* tablet deltas */
|
||||
mask = ARRAY_LENGTH(w->tool.deltas);
|
||||
first = max(w->tool.ndeltas + 1, mask) - mask;
|
||||
|
|
@ -1207,6 +1232,9 @@ handle_event_tablet(struct libinput_event *ev, struct window *w)
|
|||
w->tool.distance = libinput_event_tablet_tool_get_distance(t);
|
||||
w->tool.tilt_x = libinput_event_tablet_tool_get_tilt_x(t);
|
||||
w->tool.tilt_y = libinput_event_tablet_tool_get_tilt_y(t);
|
||||
w->tool.rotation = libinput_event_tablet_tool_get_rotation(t);
|
||||
w->tool.size_major = libinput_event_tablet_tool_get_size_major(t);
|
||||
w->tool.size_minor = libinput_event_tablet_tool_get_size_minor(t);
|
||||
|
||||
/* Add the delta to the last position and store them as abs
|
||||
* coordinates */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue