mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-03-27 01:10:40 +01:00
Emit LIBINPUT_TABLET_EVENT_TOOL_UPDATE events on tool changes
Signed-off-by: Stephen Chandler Paul <thatslyude@gmail.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
3a65184287
commit
e5212e2080
5 changed files with 183 additions and 3 deletions
|
|
@ -58,6 +58,19 @@ tablet_process_absolute(struct tablet_dispatch *tablet,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_update_tool(struct tablet_dispatch *tablet,
|
||||
enum libinput_tool_type tool,
|
||||
bool enabled)
|
||||
{
|
||||
assert(tool != LIBINPUT_TOOL_NONE);
|
||||
|
||||
if (enabled && tool != tablet->current_tool_type) {
|
||||
tablet->current_tool_type = tool;
|
||||
tablet_set_status(tablet, TABLET_TOOL_UPDATED);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_check_notify_axes(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *device,
|
||||
|
|
@ -95,11 +108,90 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_process_key(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *device,
|
||||
struct input_event *e,
|
||||
uint32_t time)
|
||||
{
|
||||
switch (e->code) {
|
||||
case BTN_TOOL_PEN:
|
||||
case BTN_TOOL_RUBBER:
|
||||
case BTN_TOOL_BRUSH:
|
||||
case BTN_TOOL_PENCIL:
|
||||
case BTN_TOOL_AIRBRUSH:
|
||||
case BTN_TOOL_FINGER:
|
||||
case BTN_TOOL_MOUSE:
|
||||
case BTN_TOOL_LENS:
|
||||
/* These codes have an equivalent libinput_tool value */
|
||||
tablet_update_tool(tablet, e->code, e->value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_process_misc(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *device,
|
||||
struct input_event *e,
|
||||
uint32_t time)
|
||||
{
|
||||
switch (e->code) {
|
||||
case MSC_SERIAL:
|
||||
if (e->value != (signed)tablet->current_tool_serial &&
|
||||
e->value != -1) {
|
||||
tablet->current_tool_serial = e->value;
|
||||
tablet_set_status(tablet, TABLET_TOOL_UPDATED);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
log_info("Unhandled MSC event code %#x\n", e->code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_notify_tool(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *device,
|
||||
uint32_t time)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
struct libinput_tool *tool;
|
||||
struct libinput_tool *new_tool = NULL;
|
||||
|
||||
/* Check if we already have the tool in our list of tools */
|
||||
list_for_each(tool, &base->seat->libinput->tool_list, link) {
|
||||
if (tablet->current_tool_type == tool->type &&
|
||||
tablet->current_tool_serial == tool->serial) {
|
||||
new_tool = tool;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we didn't already have the tool in our list of tools, add it */
|
||||
if (new_tool == NULL) {
|
||||
new_tool = zalloc(sizeof *new_tool);
|
||||
*new_tool = (struct libinput_tool) {
|
||||
.type = tablet->current_tool_type,
|
||||
.serial = tablet->current_tool_serial,
|
||||
.refcount = 1,
|
||||
};
|
||||
|
||||
list_insert(&base->seat->libinput->tool_list, &new_tool->link);
|
||||
}
|
||||
|
||||
tablet_notify_tool_update(base, time, new_tool);
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_flush(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *device,
|
||||
uint32_t time)
|
||||
{
|
||||
if (tablet_has_status(tablet, TABLET_TOOL_UPDATED))
|
||||
tablet_notify_tool(tablet, device, time);
|
||||
|
||||
if (tablet_has_status(tablet, TABLET_AXES_UPDATED)) {
|
||||
tablet_check_notify_axes(tablet, device, time);
|
||||
tablet_unset_status(tablet, TABLET_AXES_UPDATED);
|
||||
|
|
@ -119,6 +211,12 @@ tablet_process(struct evdev_dispatch *dispatch,
|
|||
case EV_ABS:
|
||||
tablet_process_absolute(tablet, device, e, time);
|
||||
break;
|
||||
case EV_KEY:
|
||||
tablet_process_key(tablet, device, e, time);
|
||||
break;
|
||||
case EV_MSC:
|
||||
tablet_process_misc(tablet, device, e, time);
|
||||
break;
|
||||
case EV_SYN:
|
||||
tablet_flush(tablet, device, time);
|
||||
break;
|
||||
|
|
@ -151,6 +249,7 @@ tablet_init(struct tablet_dispatch *tablet,
|
|||
tablet->base.interface = &tablet_interface;
|
||||
tablet->device = device;
|
||||
tablet->status = TABLET_NONE;
|
||||
tablet->current_tool_type = LIBINPUT_TOOL_NONE;
|
||||
|
||||
/* Mark any axes the tablet has as changed */
|
||||
for (a = 0; a < LIBINPUT_TABLET_AXIS_CNT; a++) {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@
|
|||
|
||||
enum tablet_status {
|
||||
TABLET_NONE = 0,
|
||||
TABLET_AXES_UPDATED = 1 << 0
|
||||
TABLET_AXES_UPDATED = 1 << 0,
|
||||
TABLET_TOOL_UPDATED = 1 << 1
|
||||
};
|
||||
|
||||
struct tablet_dispatch {
|
||||
|
|
@ -38,6 +39,9 @@ struct tablet_dispatch {
|
|||
unsigned char status;
|
||||
unsigned char changed_axes[NCHARS(LIBINPUT_TABLET_AXIS_CNT)];
|
||||
double axes[LIBINPUT_TABLET_AXIS_CNT];
|
||||
|
||||
enum libinput_tool_type current_tool_type;
|
||||
uint32_t current_tool_serial;
|
||||
};
|
||||
|
||||
static inline enum libinput_tablet_axis
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ struct libinput {
|
|||
size_t events_in;
|
||||
size_t events_out;
|
||||
|
||||
struct list tool_list;
|
||||
|
||||
const struct libinput_interface *interface;
|
||||
const struct libinput_interface_backend *interface_backend;
|
||||
void *user_data;
|
||||
|
|
@ -207,6 +209,11 @@ tablet_notify_axis(struct libinput_device *device,
|
|||
unsigned char *changed_axes,
|
||||
double *axes);
|
||||
|
||||
void
|
||||
tablet_notify_tool_update(struct libinput_device *device,
|
||||
uint32_t time,
|
||||
struct libinput_tool *tool);
|
||||
|
||||
void
|
||||
touch_notify_frame(struct libinput_device *device,
|
||||
uint32_t time);
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ struct libinput_event_tablet {
|
|||
uint32_t time;
|
||||
double *axes;
|
||||
unsigned char changed_axes[NCHARS(LIBINPUT_TABLET_AXIS_CNT)];
|
||||
struct libinput_tool *tool;
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
@ -199,6 +200,7 @@ libinput_event_get_pointer_event(struct libinput_event *event)
|
|||
case LIBINPUT_EVENT_TOUCH_CANCEL:
|
||||
case LIBINPUT_EVENT_TOUCH_FRAME:
|
||||
case LIBINPUT_EVENT_TABLET_AXIS:
|
||||
case LIBINPUT_EVENT_TABLET_TOOL_UPDATE:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -226,6 +228,7 @@ libinput_event_get_keyboard_event(struct libinput_event *event)
|
|||
case LIBINPUT_EVENT_TOUCH_CANCEL:
|
||||
case LIBINPUT_EVENT_TOUCH_FRAME:
|
||||
case LIBINPUT_EVENT_TABLET_AXIS:
|
||||
case LIBINPUT_EVENT_TABLET_TOOL_UPDATE:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -253,6 +256,7 @@ libinput_event_get_touch_event(struct libinput_event *event)
|
|||
case LIBINPUT_EVENT_TOUCH_FRAME:
|
||||
return (struct libinput_event_touch *) event;
|
||||
case LIBINPUT_EVENT_TABLET_AXIS:
|
||||
case LIBINPUT_EVENT_TABLET_TOOL_UPDATE:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -279,6 +283,7 @@ libinput_event_get_tablet_event(struct libinput_event *event)
|
|||
case LIBINPUT_EVENT_TOUCH_FRAME:
|
||||
break;
|
||||
case LIBINPUT_EVENT_TABLET_AXIS:
|
||||
case LIBINPUT_EVENT_TABLET_TOOL_UPDATE:
|
||||
return (struct libinput_event_tablet *) event;
|
||||
}
|
||||
|
||||
|
|
@ -305,6 +310,7 @@ libinput_event_get_device_notify_event(struct libinput_event *event)
|
|||
case LIBINPUT_EVENT_TOUCH_CANCEL:
|
||||
case LIBINPUT_EVENT_TOUCH_FRAME:
|
||||
case LIBINPUT_EVENT_TABLET_AXIS:
|
||||
case LIBINPUT_EVENT_TABLET_TOOL_UPDATE:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -509,6 +515,12 @@ libinput_event_tablet_get_y_transformed(struct libinput_event_tablet *event,
|
|||
height);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT struct libinput_tool *
|
||||
libinput_event_tablet_get_tool(struct libinput_event_tablet *event)
|
||||
{
|
||||
return event->tool;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT uint32_t
|
||||
libinput_event_tablet_get_time(struct libinput_event_tablet *event)
|
||||
{
|
||||
|
|
@ -605,6 +617,7 @@ libinput_init(struct libinput *libinput,
|
|||
libinput->user_data = user_data;
|
||||
list_init(&libinput->source_destroy_list);
|
||||
list_init(&libinput->seat_list);
|
||||
list_init(&libinput->tool_list);
|
||||
|
||||
if (libinput_timer_subsys_init(libinput) != 0) {
|
||||
free(libinput->events);
|
||||
|
|
@ -637,6 +650,7 @@ libinput_destroy(struct libinput *libinput)
|
|||
struct libinput_event *event;
|
||||
struct libinput_device *device, *next_device;
|
||||
struct libinput_seat *seat, *next_seat;
|
||||
struct libinput_tool *tool, *next_tool;
|
||||
|
||||
if (libinput == NULL)
|
||||
return;
|
||||
|
|
@ -659,6 +673,10 @@ libinput_destroy(struct libinput *libinput)
|
|||
libinput_seat_destroy(seat);
|
||||
}
|
||||
|
||||
list_for_each_safe(tool, next_tool, &libinput->tool_list, link) {
|
||||
libinput_tool_unref(tool);
|
||||
}
|
||||
|
||||
libinput_timer_subsys_destroy(libinput);
|
||||
libinput_drop_destroyed_sources(libinput);
|
||||
close(libinput->epoll_fd);
|
||||
|
|
@ -1160,6 +1178,27 @@ tablet_notify_axis(struct libinput_device *device,
|
|||
&axis_event->base);
|
||||
}
|
||||
|
||||
void
|
||||
tablet_notify_tool_update(struct libinput_device *device,
|
||||
uint32_t time,
|
||||
struct libinput_tool *tool)
|
||||
{
|
||||
struct libinput_event_tablet *tool_update_event;
|
||||
|
||||
tool_update_event = zalloc(sizeof *tool_update_event);
|
||||
if (!tool_update_event)
|
||||
return;
|
||||
|
||||
*tool_update_event = (struct libinput_event_tablet) {
|
||||
.time = time,
|
||||
.tool = tool,
|
||||
};
|
||||
|
||||
post_device_event(device,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_UPDATE,
|
||||
&tool_update_event->base);
|
||||
}
|
||||
|
||||
static void
|
||||
libinput_post_event(struct libinput *libinput,
|
||||
struct libinput_event *event)
|
||||
|
|
|
|||
|
|
@ -254,7 +254,12 @@ enum libinput_event_type {
|
|||
*/
|
||||
LIBINPUT_EVENT_TOUCH_FRAME,
|
||||
|
||||
LIBINPUT_EVENT_TABLET_AXIS = 600
|
||||
LIBINPUT_EVENT_TABLET_AXIS = 600,
|
||||
/**
|
||||
* Signals that a device with the @ref LIBINPUT_DEVICE_CAP_TABLET
|
||||
* capability has changed its tool.
|
||||
*/
|
||||
LIBINPUT_EVENT_TABLET_TOOL_UPDATE
|
||||
};
|
||||
|
||||
struct libinput;
|
||||
|
|
@ -283,7 +288,8 @@ struct libinput_event_touch;
|
|||
* @struct libinput_event_tablet
|
||||
*
|
||||
* Tablet event representing an axis update, button press, or tool update. Valid
|
||||
* event types for this event are @ref LIBINPUT_EVENT_TABLET_AXIS.
|
||||
* event types for this event are @ref LIBINPUT_EVENT_TABLET_AXIS, and
|
||||
* @ref LIBINPUT_EVENT_TABLET_TOOL_UPDATE.
|
||||
*/
|
||||
struct libinput_event_tablet;
|
||||
|
||||
|
|
@ -891,6 +897,31 @@ libinput_event_tablet_get_x_transformed(struct libinput_event_tablet *event,
|
|||
double
|
||||
libinput_event_tablet_get_y_transformed(struct libinput_event_tablet *event,
|
||||
uint32_t height);
|
||||
|
||||
/**
|
||||
* @ingroup event_tablet
|
||||
*
|
||||
* Return the new tool in use for this event.
|
||||
* For tablet events that are not of type @ref
|
||||
* LIBINPUT_EVENT_TABLET_TOOL_UPDATE, this function returns NULL. By default,
|
||||
* the lifetime of each tool is bound to the lifetime of the event, so the tool
|
||||
* will be destroyed when the event is destroyed. However, the lifetime of the
|
||||
* tool may be extended by using libinput_tool_ref() to increment the reference
|
||||
* count of the tool. Whenever libinput detects that the tool is in proximity of
|
||||
* any tablet that's connected, it will return the same libinput_tool object.
|
||||
*
|
||||
* @note It is an application bug to call this function for events other than
|
||||
* @ref LIBINPUT_EVENT_TABLET_TOOL_UPDATE.
|
||||
*
|
||||
* @note On tablets where the serial number of tools is not reported, each tool
|
||||
* cannot be guaranteed to be unique.
|
||||
*
|
||||
* @param event The libinput tablet event
|
||||
* @return The new tool triggering this event
|
||||
*/
|
||||
struct libinput_tool *
|
||||
libinput_event_tablet_get_tool(struct libinput_event_tablet *event);
|
||||
|
||||
/**
|
||||
* @ingroup event_tablet
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue