[PATCH weston 02/19] tablet: Add initial tablet support to weston
Stephen Chandler Paul
thatslyude at gmail.com
Wed Aug 6 16:07:52 PDT 2014
This only adds support for reporting motion events, proximity_in events
(without the tool object information), proximity_out events and frame
events.
Signed-off-by: Stephen Chandler Paul <thatslyude at gmail.com>
---
src/compositor.h | 97 ++++++++++++++++
src/input.c | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/libinput-device.c | 160 ++++++++++++++++++++++++++
src/libinput-device.h | 4 +-
4 files changed, 572 insertions(+), 1 deletion(-)
diff --git a/src/compositor.h b/src/compositor.h
index 102cfa7..f0f4e90 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -33,6 +33,7 @@ extern "C" {
#define WL_HIDE_DEPRECATED
#include <wayland-server.h>
+#include <wayland-tablet-server-protocol.h>
#include "version.h"
#include "matrix.h"
@@ -288,6 +289,45 @@ struct weston_touch_grab {
struct weston_touch *touch;
};
+struct weston_tablet_tool;
+struct weston_tablet_grab;
+struct weston_tablet_grab_interface {
+ void (*proximity_in)(struct weston_tablet_grab *grab,
+ uint32_t time,
+ struct weston_tablet_tool *tool);
+ void (*proximity_out)(struct weston_tablet_grab *grab,
+ uint32_t time);
+ void (*motion)(struct weston_tablet_grab *grab,
+ uint32_t time,
+ wl_fixed_t x,
+ wl_fixed_t y);
+ void (*down)(struct weston_tablet_grab *grab,
+ uint32_t time);
+ void (*up)(struct weston_tablet_grab *grab,
+ uint32_t time);
+ void (*pressure)(struct weston_tablet_grab *grab,
+ uint32_t time,
+ wl_fixed_t pressure);
+ void (*distance)(struct weston_tablet_grab *grab,
+ uint32_t time,
+ wl_fixed_t distance);
+ void (*tilt)(struct weston_tablet_grab *grab,
+ uint32_t time,
+ wl_fixed_t tilt_x,
+ wl_fixed_t tilt_y);
+ void (*button)(struct weston_tablet_grab *grab,
+ uint32_t time,
+ uint32_t button,
+ enum wl_tablet_button_state state);
+ void (*frame)(struct weston_tablet_grab *grab);
+ void (*cancel)(struct weston_tablet_grab *grab);
+};
+
+struct weston_tablet_grab {
+ const struct weston_tablet_grab_interface *interface;
+ struct weston_tablet *tablet;
+};
+
struct weston_data_offer {
struct wl_resource *resource;
struct weston_data_source *source;
@@ -358,6 +398,31 @@ struct weston_touch {
uint32_t grab_time;
};
+struct weston_tablet {
+ struct weston_seat *seat;
+ struct evdev_device *device;
+
+ struct wl_list resource_list;
+ struct wl_list focus_resource_list;
+ struct weston_view *focus;
+ struct wl_listener focus_view_listener;
+ struct wl_listener focus_resource_listener;
+ uint32_t focus_serial;
+
+ wl_fixed_t x, y;
+
+ struct weston_tablet_grab *grab;
+ struct weston_tablet_grab default_grab;
+
+ struct wl_list link;
+
+ char *name;
+ enum wl_tablet_manager_tablet_type type;
+ uint32_t vid;
+ uint32_t pid;
+ struct weston_output *output;
+};
+
struct weston_pointer *
weston_pointer_create(struct weston_seat *seat);
void
@@ -407,6 +472,19 @@ weston_touch_start_grab(struct weston_touch *device,
void
weston_touch_end_grab(struct weston_touch *touch);
+struct weston_tablet *
+weston_tablet_create(void);
+void
+weston_tablet_destroy(struct weston_tablet *tablet);
+void
+weston_tablet_set_focus(struct weston_tablet *tablet, struct weston_view *view,
+ uint32_t time);
+void
+weston_tablet_start_grab(struct weston_tablet *device,
+ struct weston_tablet_grab *grab);
+void
+weston_tablet_end_grab(struct weston_tablet *tablet);
+
void
wl_data_device_set_keyboard_focus(struct weston_seat *seat);
@@ -490,9 +568,11 @@ struct weston_seat {
struct weston_pointer *pointer;
struct weston_keyboard *keyboard;
struct weston_touch *touch;
+ struct wl_list tablet_list;
int pointer_device_count;
int keyboard_device_count;
int touch_device_count;
+ int tablet_device_count;
struct weston_output *output; /* constraint */
@@ -511,6 +591,9 @@ struct weston_seat {
struct wl_listener selection_data_source_listener;
struct wl_signal selection_signal;
+ struct wl_global *tablet_manager;
+ struct wl_list tablet_manager_resource_list;
+
void (*led_update)(struct weston_seat *ws, enum weston_led leds);
uint32_t slot_map;
@@ -1006,6 +1089,16 @@ void
notify_touch_frame(struct weston_seat *seat);
void
+notify_tablet_added(struct weston_tablet *tablet);
+void
+notify_tablet_proximity_out(struct weston_tablet *tablet, uint32_t time);
+void
+notify_tablet_motion(struct weston_tablet *tablet, uint32_t time,
+ wl_fixed_t x, wl_fixed_t y);
+void
+notify_tablet_frame(struct weston_tablet *tablet);
+
+void
weston_layer_entry_insert(struct weston_layer_entry *list,
struct weston_layer_entry *entry);
void
@@ -1257,6 +1350,10 @@ void
weston_seat_init_touch(struct weston_seat *seat);
void
weston_seat_release_touch(struct weston_seat *seat);
+struct weston_tablet *
+weston_seat_add_tablet(struct weston_seat *seat);
+void
+weston_seat_release_tablet(struct weston_tablet *tablet);
void
weston_seat_repick(struct weston_seat *seat);
void
diff --git a/src/input.c b/src/input.c
index aaa2223..8a97632 100644
--- a/src/input.c
+++ b/src/input.c
@@ -122,6 +122,26 @@ touch_focus_resource_destroyed(struct wl_listener *listener, void *data)
}
static void
+tablet_focus_view_destroyed(struct wl_listener *listener, void *data)
+{
+ struct weston_tablet *tablet =
+ container_of(listener, struct weston_tablet,
+ focus_view_listener);
+
+ weston_tablet_set_focus(tablet, NULL, 0);
+}
+
+static void
+tablet_focus_resource_destroyed(struct wl_listener *listener, void *data)
+{
+ struct weston_tablet *tablet =
+ container_of(listener, struct weston_tablet,
+ focus_resource_listener);
+
+ weston_tablet_set_focus(tablet, NULL, 0);
+}
+
+static void
move_resources(struct wl_list *destination, struct wl_list *source)
{
wl_list_insert_list(destination, source);
@@ -421,6 +441,66 @@ static const struct weston_keyboard_grab_interface
};
static void
+default_grab_tablet_proximity_out(struct weston_tablet_grab *grab,
+ uint32_t time)
+{
+ weston_tablet_set_focus(grab->tablet, NULL, time);
+}
+
+static void
+default_grab_tablet_motion(struct weston_tablet_grab *grab,
+ uint32_t time, wl_fixed_t x, wl_fixed_t y)
+{
+ struct weston_tablet *tablet = grab->tablet;
+ struct weston_view *current_view;
+ wl_fixed_t sx, sy;
+ struct wl_resource *resource;
+ struct wl_list *resource_list = &tablet->focus_resource_list;
+
+ current_view = weston_compositor_pick_view(tablet->seat->compositor,
+ x, y, &sx, &sy);
+ if (current_view != tablet->focus)
+ weston_tablet_set_focus(tablet, current_view, time);
+
+ if (!wl_list_empty(resource_list)) {
+ wl_resource_for_each(resource, resource_list)
+ wl_tablet_send_motion(resource, time, sx, sy);
+ }
+}
+
+static void
+default_grab_tablet_frame(struct weston_tablet_grab *grab)
+{
+ struct wl_resource *resource;
+ struct wl_list *resource_list = &grab->tablet->focus_resource_list;
+
+ if (!wl_list_empty(resource_list)) {
+ wl_resource_for_each(resource, resource_list)
+ wl_tablet_send_frame(resource);
+ }
+}
+
+static void
+default_grab_tablet_cancel(struct weston_tablet_grab *grab)
+{
+
+}
+
+static struct weston_tablet_grab_interface default_tablet_grab_interface = {
+ NULL,
+ default_grab_tablet_proximity_out,
+ default_grab_tablet_motion,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ default_grab_tablet_frame,
+ default_grab_tablet_cancel,
+};
+
+static void
pointer_unmap_sprite(struct weston_pointer *pointer)
{
if (weston_surface_is_mapped(pointer->sprite->surface))
@@ -597,6 +677,90 @@ weston_touch_destroy(struct weston_touch *touch)
free(touch);
}
+WL_EXPORT struct weston_tablet *
+weston_tablet_create(void)
+{
+ struct weston_tablet *tablet;
+
+ tablet = zalloc(sizeof *tablet);
+ if (tablet == NULL)
+ return NULL;
+
+ wl_list_init(&tablet->resource_list);
+ wl_list_init(&tablet->focus_resource_list);
+ wl_list_init(&tablet->focus_view_listener.link);
+ tablet->focus_view_listener.notify = tablet_focus_view_destroyed;
+ wl_list_init(&tablet->focus_resource_listener.link);
+ tablet->focus_resource_listener.notify = tablet_focus_resource_destroyed;
+ tablet->default_grab.interface = &default_tablet_grab_interface;
+ tablet->default_grab.tablet = tablet;
+ tablet->grab = &tablet->default_grab;
+
+ return tablet;
+}
+
+WL_EXPORT void
+weston_tablet_destroy(struct weston_tablet *tablet)
+{
+ free(tablet->name);
+
+ wl_list_remove(&tablet->focus_view_listener.link);
+ wl_list_remove(&tablet->focus_resource_listener.link);
+
+ free(tablet);
+}
+
+WL_EXPORT void
+weston_tablet_set_focus(struct weston_tablet *tablet, struct weston_view *view,
+ uint32_t time)
+{
+ struct wl_list *focus_resource_list;
+ struct wl_resource *resource;
+ struct weston_seat *seat = tablet->seat;
+
+ focus_resource_list = &tablet->focus_resource_list;
+
+ if (tablet->focus && !wl_list_empty(focus_resource_list)) {
+ wl_resource_for_each(resource, focus_resource_list) {
+ wl_tablet_send_proximity_out(resource, time);
+ wl_tablet_send_frame(resource);
+ }
+
+ move_resources(&tablet->resource_list, focus_resource_list);
+ }
+
+ if (find_resource_for_view(&tablet->resource_list, view)) {
+ struct wl_client *surface_client =
+ wl_resource_get_client(view->surface->resource);
+
+ move_resources_for_client(focus_resource_list,
+ &tablet->resource_list,
+ surface_client);
+ tablet->focus_serial =
+ wl_display_next_serial(seat->compositor->wl_display);
+
+ wl_resource_for_each(resource, focus_resource_list)
+ wl_tablet_send_proximity_in(resource,
+ tablet->focus_serial,
+ time, NULL,
+ view->surface->resource);
+ }
+
+ wl_list_remove(&tablet->focus_view_listener.link);
+ wl_list_init(&tablet->focus_view_listener.link);
+ wl_list_remove(&tablet->focus_resource_listener.link);
+ wl_list_init(&tablet->focus_resource_listener.link);
+ if (view)
+ wl_signal_add(&view->destroy_signal,
+ &tablet->focus_view_listener);
+ if (view && view->surface->resource)
+ wl_resource_add_destroy_listener(view->surface->resource,
+ &tablet->focus_resource_listener);
+
+ tablet->focus = view;
+ tablet->focus_view_listener.notify = tablet_focus_view_destroyed;
+}
+
static void
seat_send_updated_caps(struct weston_seat *seat)
{
@@ -1531,6 +1695,60 @@ notify_touch_frame(struct weston_seat *seat)
grab->interface->frame(grab);
}
+static const struct wl_tablet_interface tablet_interface;
+
+WL_EXPORT void
+notify_tablet_added(struct weston_tablet *tablet)
+{
+ struct wl_resource *resource;
+ struct weston_seat *seat = tablet->seat;
+
+ wl_resource_for_each(resource, &seat->tablet_manager_resource_list) {
+ struct wl_resource *tablet_resource =
+ wl_resource_create(wl_resource_get_client(resource),
+ &wl_tablet_interface,
+ 1, 0);
+
+ wl_list_insert(&tablet->resource_list,
+ wl_resource_get_link(tablet_resource));
+ wl_resource_set_implementation(tablet_resource,
+ &tablet_interface,
+ tablet,
+ unbind_resource);
+
+ wl_resource_set_user_data(tablet_resource, tablet);
+ wl_tablet_manager_send_device_added(resource, tablet_resource,
+ tablet->name, tablet->vid,
+ tablet->pid, 0, 0);
+ }
+}
+
+WL_EXPORT void
+notify_tablet_proximity_out(struct weston_tablet *tablet, uint32_t time)
+{
+ struct weston_tablet_grab *grab = tablet->grab;
+
+ grab->interface->proximity_out(grab, time);
+}
+
+WL_EXPORT void
+notify_tablet_motion(struct weston_tablet *tablet, uint32_t time,
+ wl_fixed_t x, wl_fixed_t y)
+{
+ struct weston_tablet_grab *grab = tablet->grab;
+
+ weston_compositor_wake(tablet->seat->compositor);
+ grab->interface->motion(grab, time, x, y);
+}
+
+WL_EXPORT void
+notify_tablet_frame(struct weston_tablet *tablet)
+{
+ struct weston_tablet_grab *grab = tablet->grab;
+
+ grab->interface->frame(grab);
+}
+
static void
pointer_cursor_surface_configure(struct weston_surface *es,
int32_t dx, int32_t dy)
@@ -1809,6 +2027,16 @@ static const struct wl_seat_interface seat_interface = {
};
static void
+tablet_release(struct wl_client *client, struct wl_resource *resource)
+{
+ wl_resource_destroy(resource);
+}
+
+static const struct wl_tablet_interface tablet_interface = {
+ tablet_release,
+};
+
+static void
bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
{
struct weston_seat *seat = data;
@@ -1833,6 +2061,44 @@ bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
wl_seat_send_name(resource, seat->seat_name);
}
+static void
+bind_tablet_manager(struct wl_client *client, void *data, uint32_t version,
+ uint32_t id)
+{
+ struct weston_seat *seat = data;
+ struct wl_resource *seat_resource =
+ wl_resource_find_for_client(&seat->base_resource_list, client);
+ struct wl_resource *resource;
+ struct weston_tablet *tablet;
+
+ resource = wl_resource_create(client, &wl_tablet_manager_interface,
+ MIN(version, 1), id);
+ wl_resource_set_implementation(resource, NULL, data, unbind_resource);
+ wl_list_insert(&seat->tablet_manager_resource_list,
+ wl_resource_get_link(resource));
+
+ /* Notify the client of the wl_seat object we're associated with */
+ wl_tablet_manager_send_seat(resource, seat_resource);
+
+ /* Notify the client of all tablets currently connected to the system */
+ wl_list_for_each(tablet, &seat->tablet_list, link) {
+ struct wl_resource *tablet_resource =
+ wl_resource_create(client, &wl_tablet_interface, 1, 0);
+
+ wl_resource_set_implementation(tablet_resource,
+ &tablet_interface, tablet,
+ unbind_resource);
+ wl_resource_set_user_data(tablet_resource, tablet);
+
+ wl_list_insert(&tablet->resource_list,
+ wl_resource_get_link(tablet_resource));
+
+ wl_tablet_manager_send_device_added(resource, tablet_resource,
+ tablet->name, tablet->vid,
+ tablet->pid, 0, 0);
+ }
+}
+
#ifdef ENABLE_XKBCOMMON
int
weston_compositor_xkb_init(struct weston_compositor *ec,
@@ -2185,6 +2451,42 @@ weston_seat_init_touch(struct weston_seat *seat)
seat_send_updated_caps(seat);
}
+WL_EXPORT struct weston_tablet *
+weston_seat_add_tablet(struct weston_seat *seat)
+{
+ struct weston_tablet *tablet;
+
+ seat->tablet_device_count++;
+ if (seat->tablet_device_count == 1)
+ seat_send_updated_caps(seat);
+
+ tablet = weston_tablet_create();
+ if (tablet == NULL)
+ return NULL;
+
+ tablet->seat = seat;
+
+ return tablet;
+}
+
+WL_EXPORT void
+weston_seat_release_tablet(struct weston_tablet *tablet)
+{
+ struct wl_resource *resource;
+
+ weston_tablet_set_focus(tablet, NULL, 0);
+ wl_resource_for_each(resource, &tablet->resource_list)
+ wl_tablet_send_removed(resource);
+
+ tablet->seat->tablet_device_count--;
+ wl_list_remove(&tablet->link);
+
+ if (tablet->seat->tablet_device_count == 0)
+ seat_send_updated_caps(tablet->seat);
+
+ weston_tablet_destroy(tablet);
+}
+
WL_EXPORT void
weston_seat_release_touch(struct weston_seat *seat)
{
@@ -2209,9 +2511,14 @@ weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
wl_list_init(&seat->drag_resource_list);
wl_signal_init(&seat->destroy_signal);
wl_signal_init(&seat->updated_caps_signal);
+ wl_list_init(&seat->tablet_list);
+ wl_list_init(&seat->tablet_manager_resource_list);
seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 4,
seat, bind_seat);
+ seat->tablet_manager = wl_global_create(ec->wl_display,
+ &wl_tablet_manager_interface,
+ 1, seat, bind_tablet_manager);
seat->compositor = ec;
seat->modifier_state = 0;
@@ -2227,6 +2534,8 @@ weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
WL_EXPORT void
weston_seat_release(struct weston_seat *seat)
{
+ struct weston_tablet *tablet;
+
wl_list_remove(&seat->link);
if (seat->saved_kbd_focus)
@@ -2238,10 +2547,13 @@ weston_seat_release(struct weston_seat *seat)
weston_keyboard_destroy(seat->keyboard);
if (seat->touch)
weston_touch_destroy(seat->touch);
+ wl_list_for_each(tablet, &seat->tablet_list, link)
+ weston_tablet_destroy(tablet);
free (seat->seat_name);
wl_global_destroy(seat->global);
+ wl_global_destroy(seat->tablet_manager);
wl_signal_emit(&seat->destroy_signal, seat);
}
diff --git a/src/libinput-device.c b/src/libinput-device.c
index 2ba4ec3..f5ed2a0 100644
--- a/src/libinput-device.c
+++ b/src/libinput-device.c
@@ -38,6 +38,14 @@
#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int(10)
+struct tablet_output_listener {
+ struct wl_listener base;
+ struct wl_list tablet_list;
+};
+
+static int
+tablet_bind_output(struct weston_tablet *tablet, struct weston_output *output);
+
void
evdev_led_update(struct evdev_device *device, enum weston_led weston_leds)
{
@@ -210,6 +218,51 @@ handle_touch_frame(struct libinput_device *libinput_device,
notify_touch_frame(seat);
}
+static void
+handle_tablet_axis(struct libinput_device *libinput_device,
+ struct libinput_event_tablet *axis_event)
+{
+ struct evdev_device *device =
+ libinput_device_get_user_data(libinput_device);
+ struct weston_tablet *tablet = device->tablet;
+
+ if (libinput_event_tablet_axis_has_changed(axis_event,
+ LIBINPUT_TABLET_AXIS_X) ||
+ libinput_event_tablet_axis_has_changed(axis_event,
+ LIBINPUT_TABLET_AXIS_Y)) {
+ double x, y;
+ uint32_t width, height,
+ time;
+
+ time = libinput_event_tablet_get_time(axis_event);
+
+ width = tablet->output->current_mode->width;
+ height = tablet->output->current_mode->height;
+ x = libinput_event_tablet_get_x_transformed(axis_event, width);
+ y = libinput_event_tablet_get_y_transformed(axis_event, height);
+
+ notify_tablet_motion(tablet, time,
+ wl_fixed_from_double(x),
+ wl_fixed_from_double(y));
+ }
+
+ notify_tablet_frame(tablet);
+}
+
+static void
+handle_tablet_proximity_out(struct libinput_device *libinput_device,
+ struct libinput_event_tablet *proximity_out_event)
+{
+ struct evdev_device *device =
+ libinput_device_get_user_data(libinput_device);
+ struct weston_tablet *tablet = device->tablet;
+ uint32_t time;
+
+ time = libinput_event_tablet_get_time(proximity_out_event);
+
+ notify_tablet_proximity_out(tablet, time);
+}
+
int
evdev_device_process_event(struct libinput_event *event)
{
@@ -255,6 +308,15 @@ evdev_device_process_event(struct libinput_event *event)
handle_touch_frame(libinput_device,
libinput_event_get_touch_event(event));
break;
+ case LIBINPUT_EVENT_TABLET_AXIS:
+ handle_tablet_axis(libinput_device,
+ libinput_event_get_tablet_event(event));
+ break;
+ case LIBINPUT_EVENT_TABLET_PROXIMITY_OUT:
+ handle_tablet_proximity_out(
+ libinput_device,
+ libinput_event_get_tablet_event(event));
+ break;
default:
handled = 0;
weston_log("unknown libinput event %d\n",
@@ -297,6 +359,81 @@ evdev_device_set_output(struct evdev_device *device,
&device->output_destroy_listener);
}
+static void
+bind_unbound_tablets(struct wl_listener *listener_base, void *data)
+{
+ struct tablet_output_listener *listener =
+ wl_container_of(listener_base, listener, base);
+ struct weston_tablet *tablet, *tmp;
+
+ wl_list_for_each_safe(tablet, tmp, &listener->tablet_list, link) {
+ if (tablet_bind_output(tablet, data)) {
+ wl_list_remove(&tablet->link);
+ wl_list_insert(&tablet->seat->tablet_list,
+ &tablet->link);
+ tablet->device->seat_caps |= EVDEV_SEAT_TABLET;
+ notify_tablet_added(tablet);
+ }
+ }
+
+ if (wl_list_empty(&listener->tablet_list)) {
+ wl_list_remove(&listener_base->link);
+ free(listener);
+ }
+}
+
+static int
+tablet_bind_output(struct weston_tablet *tablet, struct weston_output *output)
+{
+ struct wl_list *output_list = &tablet->seat->compositor->output_list;
+ struct weston_compositor *compositor = tablet->seat->compositor;
+
+ /* TODO: Properly bind tablets with built-in displays */
+ switch (tablet->type) {
+ case WL_TABLET_MANAGER_TABLET_TYPE_EXTERNAL:
+ case WL_TABLET_MANAGER_TABLET_TYPE_INTERNAL:
+ case WL_TABLET_MANAGER_TABLET_TYPE_DISPLAY:
+ if (output)
+ tablet->output = output;
+ else {
+ if (wl_list_empty(output_list))
+ break;
+
+ /* Find the first available display */
+ wl_list_for_each(output, output_list, link)
+ break;
+ tablet->output = output;
+ }
+ }
+
+ if (!tablet->output) {
+ struct tablet_output_listener *listener;
+ struct wl_listener *listener_base;
+
+ listener_base =
+ wl_signal_get(&compositor->output_created_signal,
+ bind_unbound_tablets);
+ if (listener_base == NULL) {
+ listener = zalloc(sizeof(*listener));
+
+ wl_list_init(&listener->tablet_list);
+
+ listener_base = &listener->base;
+ listener_base->notify = bind_unbound_tablets;
+
+ wl_signal_add(&compositor->output_created_signal,
+ listener_base);
+ } else
+ listener = wl_container_of(listener_base, listener,
+ base);
+
+ wl_list_insert(&listener->tablet_list, &tablet->link);
+ return 0;
+ }
+
+ return 1;
+}
+
struct evdev_device *
evdev_device_create(struct libinput_device *libinput_device,
struct weston_seat *seat)
@@ -326,6 +463,27 @@ evdev_device_create(struct libinput_device *libinput_device,
weston_seat_init_touch(seat);
device->seat_caps |= EVDEV_SEAT_TOUCH;
}
+ if (libinput_device_has_capability(libinput_device,
+ LIBINPUT_DEVICE_CAP_TABLET)) {
+ struct weston_tablet *tablet = weston_seat_add_tablet(seat);
+
+ tablet->name = strdup(libinput_device_get_name(libinput_device));
+ tablet->vid = libinput_device_get_id_vendor(libinput_device);
+ tablet->pid = libinput_device_get_id_product(libinput_device);
+
+ /* If we can successfully bind the tablet to an output, then
+ * it's ready to get added to the seat's tablet list, otherwise
+ * it will get added when an appropriate output is available */
+ if (tablet_bind_output(tablet, NULL)) {
+ wl_list_insert(&seat->tablet_list, &tablet->link);
+ device->seat_caps |= EVDEV_SEAT_TABLET;
+
+ notify_tablet_added(tablet);
+ }
+
+ device->tablet = tablet;
+ tablet->device = device;
+ }
libinput_device_set_user_data(libinput_device, device);
libinput_device_ref(libinput_device);
@@ -342,6 +500,8 @@ evdev_device_destroy(struct evdev_device *device)
weston_seat_release_keyboard(device->seat);
if (device->seat_caps & EVDEV_SEAT_TOUCH)
weston_seat_release_touch(device->seat);
+ if (device->seat_caps & EVDEV_SEAT_TABLET)
+ weston_seat_release_tablet(device->tablet);
if (device->output)
wl_list_remove(&device->output_destroy_listener.link);
diff --git a/src/libinput-device.h b/src/libinput-device.h
index 0775743..02a2095 100644
--- a/src/libinput-device.h
+++ b/src/libinput-device.h
@@ -34,7 +34,8 @@
enum evdev_device_seat_capability {
EVDEV_SEAT_POINTER = (1 << 0),
EVDEV_SEAT_KEYBOARD = (1 << 1),
- EVDEV_SEAT_TOUCH = (1 << 2)
+ EVDEV_SEAT_TOUCH = (1 << 2),
+ EVDEV_SEAT_TABLET = (1 << 3)
};
struct evdev_device {
@@ -44,6 +45,7 @@ struct evdev_device {
struct wl_list link;
struct weston_output *output;
struct wl_listener output_destroy_listener;
+ struct weston_tablet *tablet;
char *devnode;
char *output_name;
int fd;
--
1.8.5.5
More information about the wayland-devel
mailing list