mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-03 10:00:27 +01:00
tablet: split out tip handling into a separate event
The tablet tip works like a button in the kernel but is otherwise not really a button. Split it into an explicit tip up/down event instead. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
30dbd6718a
commit
1318ffadb5
8 changed files with 154 additions and 1 deletions
|
|
@ -476,6 +476,13 @@ tablet_notify_proximity(struct libinput_device *device,
|
|||
unsigned char *changed_axes,
|
||||
double *axes);
|
||||
|
||||
void
|
||||
tablet_notify_tip(struct libinput_device *device,
|
||||
uint64_t time,
|
||||
struct libinput_tool *tool,
|
||||
enum libinput_tool_tip_state tip_state,
|
||||
double *axes);
|
||||
|
||||
void
|
||||
tablet_notify_button(struct libinput_device *device,
|
||||
uint64_t time,
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ struct libinput_event_tablet {
|
|||
unsigned char changed_axes[NCHARS(LIBINPUT_TABLET_AXIS_MAX + 1)];
|
||||
struct libinput_tool *tool;
|
||||
enum libinput_tool_proximity_state proximity_state;
|
||||
enum libinput_tool_tip_state tip_state;
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
@ -313,6 +314,7 @@ libinput_event_get_tablet_event(struct libinput_event *event)
|
|||
NULL,
|
||||
LIBINPUT_EVENT_TABLET_AXIS,
|
||||
LIBINPUT_EVENT_TABLET_PROXIMITY,
|
||||
LIBINPUT_EVENT_TABLET_TIP,
|
||||
LIBINPUT_EVENT_TABLET_BUTTON);
|
||||
|
||||
return (struct libinput_event_tablet *) event;
|
||||
|
|
@ -918,6 +920,7 @@ libinput_event_tablet_axis_has_changed(struct libinput_event_tablet *event,
|
|||
event->base.type,
|
||||
0,
|
||||
LIBINPUT_EVENT_TABLET_AXIS,
|
||||
LIBINPUT_EVENT_TABLET_TIP,
|
||||
LIBINPUT_EVENT_TABLET_PROXIMITY);
|
||||
|
||||
return (NCHARS(axis) <= sizeof(event->changed_axes)) ?
|
||||
|
|
@ -935,6 +938,7 @@ libinput_event_tablet_get_axis_value(struct libinput_event_tablet *event,
|
|||
event->base.type,
|
||||
0,
|
||||
LIBINPUT_EVENT_TABLET_AXIS,
|
||||
LIBINPUT_EVENT_TABLET_TIP,
|
||||
LIBINPUT_EVENT_TABLET_PROXIMITY);
|
||||
|
||||
switch(axis) {
|
||||
|
|
@ -968,6 +972,7 @@ libinput_event_tablet_get_axis_delta(struct libinput_event_tablet *event,
|
|||
event->base.type,
|
||||
0,
|
||||
LIBINPUT_EVENT_TABLET_AXIS,
|
||||
LIBINPUT_EVENT_TABLET_TIP,
|
||||
LIBINPUT_EVENT_TABLET_PROXIMITY);
|
||||
|
||||
switch(axis) {
|
||||
|
|
@ -999,6 +1004,7 @@ libinput_event_tablet_get_axis_delta_discrete(
|
|||
event->base.type,
|
||||
0,
|
||||
LIBINPUT_EVENT_TABLET_AXIS,
|
||||
LIBINPUT_EVENT_TABLET_TIP,
|
||||
LIBINPUT_EVENT_TABLET_PROXIMITY);
|
||||
|
||||
switch(axis) {
|
||||
|
|
@ -1028,6 +1034,7 @@ libinput_event_tablet_get_x_transformed(struct libinput_event_tablet *event,
|
|||
event->base.type,
|
||||
0,
|
||||
LIBINPUT_EVENT_TABLET_AXIS,
|
||||
LIBINPUT_EVENT_TABLET_TIP,
|
||||
LIBINPUT_EVENT_TABLET_PROXIMITY);
|
||||
|
||||
return evdev_device_transform_x(device,
|
||||
|
|
@ -1046,6 +1053,7 @@ libinput_event_tablet_get_y_transformed(struct libinput_event_tablet *event,
|
|||
event->base.type,
|
||||
0,
|
||||
LIBINPUT_EVENT_TABLET_AXIS,
|
||||
LIBINPUT_EVENT_TABLET_TIP,
|
||||
LIBINPUT_EVENT_TABLET_PROXIMITY);
|
||||
|
||||
return evdev_device_transform_y(device,
|
||||
|
|
@ -1065,6 +1073,12 @@ libinput_event_tablet_get_proximity_state(struct libinput_event_tablet *event)
|
|||
return event->proximity_state;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT enum libinput_tool_tip_state
|
||||
libinput_event_tablet_get_tip_state(struct libinput_event_tablet *event)
|
||||
{
|
||||
return event->tip_state;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT uint32_t
|
||||
libinput_event_tablet_get_time(struct libinput_event_tablet *event)
|
||||
{
|
||||
|
|
@ -1969,6 +1983,34 @@ tablet_notify_proximity(struct libinput_device *device,
|
|||
&proximity_event->base);
|
||||
}
|
||||
|
||||
void
|
||||
tablet_notify_tip(struct libinput_device *device,
|
||||
uint64_t time,
|
||||
struct libinput_tool *tool,
|
||||
enum libinput_tool_tip_state tip_state,
|
||||
double *axes)
|
||||
{
|
||||
struct libinput_event_tablet *tip_event;
|
||||
|
||||
tip_event = zalloc(sizeof *tip_event);
|
||||
if (!tip_event)
|
||||
return;
|
||||
|
||||
*tip_event = (struct libinput_event_tablet) {
|
||||
.time = time,
|
||||
.tool = tool,
|
||||
.tip_state = tip_state,
|
||||
};
|
||||
memcpy(tip_event->axes,
|
||||
axes,
|
||||
sizeof(tip_event->axes));
|
||||
|
||||
post_device_event(device,
|
||||
time,
|
||||
LIBINPUT_EVENT_TABLET_TIP,
|
||||
&tip_event->base);
|
||||
}
|
||||
|
||||
void
|
||||
tablet_notify_button(struct libinput_device *device,
|
||||
uint64_t time,
|
||||
|
|
|
|||
|
|
@ -216,6 +216,20 @@ enum libinput_tool_proximity_state {
|
|||
LIBINPUT_TOOL_PROXIMITY_IN = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
*
|
||||
* The tip contact state for a tool on a device. The device must have
|
||||
* the @ref LIBINPUT_DEVICE_CAP_TABLET capability.
|
||||
*
|
||||
* The tip contact state of a tool is a binary state signalling whether the tool is
|
||||
* touching the surface of the tablet device.
|
||||
*/
|
||||
enum libinput_tool_tip_state {
|
||||
LIBINPUT_TOOL_TIP_UP = 0,
|
||||
LIBINPUT_TOOL_TIP_DOWN = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup base
|
||||
*
|
||||
|
|
@ -301,6 +315,19 @@ enum libinput_event_type {
|
|||
* proximity out event.
|
||||
*/
|
||||
LIBINPUT_EVENT_TABLET_PROXIMITY,
|
||||
/**
|
||||
* Signals that a tool has come in contact with the surface of a
|
||||
* device with the @ref LIBINPUT_DEVICE_CAP_TABLET capability.
|
||||
*
|
||||
* On devices without distance proximity detection, the @ref
|
||||
* LIBINPUT_EVENT_TABLET_TIP is sent immediately after @ref
|
||||
* LIBINPUT_EVENT_TABLET_PROXIMITY for the tip down event, and
|
||||
* immediately before for the tip up event.
|
||||
*
|
||||
* If a button and/or axis state change occurs at the same time as a
|
||||
* tip state change, the order of events is device-dependent.
|
||||
*/
|
||||
LIBINPUT_EVENT_TABLET_TIP,
|
||||
LIBINPUT_EVENT_TABLET_BUTTON,
|
||||
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN = 800,
|
||||
|
|
@ -1499,6 +1526,20 @@ libinput_event_tablet_get_tool(struct libinput_event_tablet *event);
|
|||
enum libinput_tool_proximity_state
|
||||
libinput_event_tablet_get_proximity_state(struct libinput_event_tablet *event);
|
||||
|
||||
/**
|
||||
* @ingroup event_tablet
|
||||
*
|
||||
* Returns the new tip state of a tool from a tip event.
|
||||
* Used to check whether or not a tool came in contact with the tablet
|
||||
* surface or left contact with the tablet surface during an
|
||||
* event of type @ref LIBINPUT_EVENT_TABLET_TIP.
|
||||
*
|
||||
* @param event The libinput tablet event
|
||||
* @return The new tip state of the tool from the event.
|
||||
*/
|
||||
enum libinput_tool_tip_state
|
||||
libinput_event_tablet_get_tip_state(struct libinput_event_tablet *event);
|
||||
|
||||
/**
|
||||
* @ingroup event_tablet
|
||||
*
|
||||
|
|
|
|||
|
|
@ -195,6 +195,7 @@ LIBINPUT_TABLET_SUPPORT {
|
|||
libinput_event_tablet_get_proximity_state;
|
||||
libinput_event_tablet_get_seat_button_count;
|
||||
libinput_event_tablet_get_time;
|
||||
libinput_event_tablet_get_tip_state;
|
||||
libinput_event_tablet_get_tool;
|
||||
libinput_event_tablet_get_x_transformed;
|
||||
libinput_event_tablet_get_y_transformed;
|
||||
|
|
|
|||
|
|
@ -1887,6 +1887,9 @@ litest_event_type_str(struct libinput_event *event)
|
|||
case LIBINPUT_EVENT_TABLET_PROXIMITY:
|
||||
str = "TABLET PROX";
|
||||
break;
|
||||
case LIBINPUT_EVENT_TABLET_TIP:
|
||||
str = "TABLET TIP";
|
||||
break;
|
||||
case LIBINPUT_EVENT_TABLET_BUTTON:
|
||||
str = "TABLET BUTTON";
|
||||
break;
|
||||
|
|
@ -1949,6 +1952,11 @@ litest_print_event(struct libinput_event *event)
|
|||
fprintf(stderr, "proximity %d\n",
|
||||
libinput_event_tablet_get_proximity_state(t));
|
||||
break;
|
||||
case LIBINPUT_EVENT_TABLET_TIP:
|
||||
t = libinput_event_get_tablet_event(event);
|
||||
fprintf(stderr, "tip %d\n",
|
||||
libinput_event_tablet_get_tip_state(t));
|
||||
break;
|
||||
case LIBINPUT_EVENT_TABLET_BUTTON:
|
||||
t = libinput_event_get_tablet_event(event);
|
||||
fprintf(stderr, "button %d state %d\n",
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ START_TEST(proximity_out_clear_buttons)
|
|||
/* Test that proximity out events send button releases for any currently
|
||||
* pressed stylus buttons
|
||||
*/
|
||||
for (button = BTN_TOUCH; button <= BTN_STYLUS2; button++) {
|
||||
for (button = BTN_TOUCH + 1; button <= BTN_STYLUS2; button++) {
|
||||
bool button_released = false;
|
||||
uint32_t event_button;
|
||||
enum libinput_button_state state;
|
||||
|
|
@ -155,6 +155,8 @@ START_TEST(proximity_out_clear_buttons)
|
|||
libevdev_event_code_get_name(EV_KEY, button),
|
||||
event_button);
|
||||
}
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
|
|
|||
|
|
@ -115,6 +115,9 @@ print_event_header(struct libinput_event *ev)
|
|||
case LIBINPUT_EVENT_TABLET_PROXIMITY:
|
||||
type = "TABLET_PROXIMITY";
|
||||
break;
|
||||
case LIBINPUT_EVENT_TABLET_TIP:
|
||||
type = "TABLET_TIP";
|
||||
break;
|
||||
case LIBINPUT_EVENT_TABLET_BUTTON:
|
||||
type = "TABLET_BUTTON";
|
||||
break;
|
||||
|
|
@ -278,6 +281,18 @@ print_pointer_button_event(struct libinput_event *ev)
|
|||
libinput_event_pointer_get_seat_button_count(p));
|
||||
}
|
||||
|
||||
static void
|
||||
print_tablet_tip_event(struct libinput_event *ev)
|
||||
{
|
||||
struct libinput_event_tablet *p = libinput_event_get_tablet_event(ev);
|
||||
enum libinput_tool_tip_state state;
|
||||
|
||||
print_event_time(libinput_event_tablet_get_time(p));
|
||||
|
||||
state = libinput_event_tablet_get_tip_state(p);
|
||||
printf("%s\n", state == LIBINPUT_TOOL_TIP_DOWN ? "down" : "up");
|
||||
}
|
||||
|
||||
static void
|
||||
print_tablet_button_event(struct libinput_event *ev)
|
||||
{
|
||||
|
|
@ -667,6 +682,9 @@ handle_and_print_events(struct libinput *li)
|
|||
case LIBINPUT_EVENT_TABLET_PROXIMITY:
|
||||
print_proximity_event(ev);
|
||||
break;
|
||||
case LIBINPUT_EVENT_TABLET_TIP:
|
||||
print_tablet_tip_event(ev);
|
||||
break;
|
||||
case LIBINPUT_EVENT_TABLET_BUTTON:
|
||||
print_tablet_button_event(ev);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@ struct window {
|
|||
struct {
|
||||
double x, y;
|
||||
double x_in, y_in;
|
||||
double x_down, y_down;
|
||||
double x_up, y_up;
|
||||
double pressure;
|
||||
double distance;
|
||||
double tilt_x, tilt_y;
|
||||
|
|
@ -234,6 +236,20 @@ draw(GtkWidget *widget, cairo_t *cr, gpointer data)
|
|||
cairo_save(cr);
|
||||
}
|
||||
|
||||
if (w->tool.x_down && w->tool.y_down) {
|
||||
cairo_rectangle(cr, w->tool.x_down - 10, w->tool.y_down - 10, 20, 20);
|
||||
cairo_stroke(cr);
|
||||
cairo_restore(cr);
|
||||
cairo_save(cr);
|
||||
}
|
||||
|
||||
if (w->tool.x_up && w->tool.y_up) {
|
||||
cairo_rectangle(cr, w->tool.x_up - 10, w->tool.y_up - 10, 20, 20);
|
||||
cairo_stroke(cr);
|
||||
cairo_restore(cr);
|
||||
cairo_save(cr);
|
||||
}
|
||||
|
||||
if (w->tool.pressure)
|
||||
cairo_set_source_rgb(cr, .8, .8, .2);
|
||||
|
||||
|
|
@ -584,6 +600,7 @@ static void
|
|||
handle_event_tablet(struct libinput_event *ev, struct window *w)
|
||||
{
|
||||
struct libinput_event_tablet *t = libinput_event_get_tablet_event(ev);
|
||||
double x, y;
|
||||
|
||||
switch (libinput_event_get_type(ev)) {
|
||||
case LIBINPUT_EVENT_TABLET_PROXIMITY:
|
||||
|
|
@ -591,6 +608,10 @@ handle_event_tablet(struct libinput_event *ev, struct window *w)
|
|||
LIBINPUT_TOOL_PROXIMITY_OUT) {
|
||||
w->tool.x_in = 0;
|
||||
w->tool.y_in = 0;
|
||||
w->tool.x_down = 0;
|
||||
w->tool.y_down = 0;
|
||||
w->tool.x_up = 0;
|
||||
w->tool.y_up = 0;
|
||||
} else {
|
||||
w->tool.x_in = libinput_event_tablet_get_x_transformed(t,
|
||||
w->width);
|
||||
|
|
@ -612,6 +633,18 @@ handle_event_tablet(struct libinput_event *ev, struct window *w)
|
|||
w->tool.tilt_y = libinput_event_tablet_get_axis_value(t,
|
||||
LIBINPUT_TABLET_AXIS_TILT_Y);
|
||||
break;
|
||||
case LIBINPUT_EVENT_TABLET_TIP:
|
||||
x = libinput_event_tablet_get_x_transformed(t, w->width);
|
||||
y = libinput_event_tablet_get_y_transformed(t, w->height);
|
||||
if (libinput_event_tablet_get_tip_state(t) ==
|
||||
LIBINPUT_TOOL_TIP_DOWN) {
|
||||
w->tool.x_down = x;
|
||||
w->tool.y_down = y;
|
||||
} else {
|
||||
w->tool.x_up = x;
|
||||
w->tool.y_up = y;
|
||||
}
|
||||
break;
|
||||
case LIBINPUT_EVENT_TABLET_BUTTON:
|
||||
break;
|
||||
default:
|
||||
|
|
@ -676,6 +709,7 @@ handle_event_libinput(GIOChannel *source, GIOCondition condition, gpointer data)
|
|||
break;
|
||||
case LIBINPUT_EVENT_TABLET_AXIS:
|
||||
case LIBINPUT_EVENT_TABLET_PROXIMITY:
|
||||
case LIBINPUT_EVENT_TABLET_TIP:
|
||||
case LIBINPUT_EVENT_TABLET_BUTTON:
|
||||
handle_event_tablet(ev, w);
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue