[PATCH v2 weston 13/13] tablet: Remove tablet-specific tools on disconnect
Peter Hutterer
peter.hutterer at who-t.net
Wed Feb 3 05:28:17 UTC 2016
From: Stephen Chandler Paul <thatslyude at gmail.com>
Store all tablets that a tool was used on in a list. When the tablet
is removed, remove all tools only seen on this tablet.
Tools without a serial number are only ever bound to one tablet.
Co-authored-by: Peter Hutterer <peter.hutterer at who-t.net>
Signed-off-by: Stephen Chandler Paul <thatslyude at gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
src/compositor.h | 8 ++++++++
src/input.c | 33 +++++++++++++++++++++++++++++++--
src/libinput-device.c | 41 +++++++++++++++++++++++++++++++++++++----
3 files changed, 76 insertions(+), 6 deletions(-)
diff --git a/src/compositor.h b/src/compositor.h
index bd6af4d..c6f5f07 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -483,6 +483,13 @@ struct weston_tablet_tool {
wl_fixed_t grab_x, grab_y;
};
+struct weston_tablet_tool_id {
+ struct wl_list link;
+
+ enum zwp_tablet_tool_v1_type type;
+ uint64_t serial;
+};
+
struct weston_tablet {
struct weston_seat *seat;
struct evdev_device *device;
@@ -490,6 +497,7 @@ struct weston_tablet {
struct wl_list resource_list;
struct wl_list link;
+ struct wl_list tool_id_list;
char *name;
uint32_t vid;
diff --git a/src/input.c b/src/input.c
index 11ed0c4..03b5a9f 100644
--- a/src/input.c
+++ b/src/input.c
@@ -869,6 +869,7 @@ weston_tablet_create(void)
return NULL;
wl_list_init(&tablet->resource_list);
+ wl_list_init(&tablet->tool_id_list);
return tablet;
}
@@ -877,11 +878,41 @@ WL_EXPORT void
weston_tablet_destroy(struct weston_tablet *tablet)
{
struct wl_resource *resource;
+ struct weston_tablet *t;
+ struct weston_tablet_tool *tool, *tmptool;
+ struct weston_tablet_tool_id *id, *tmpid;
wl_resource_for_each(resource, &tablet->resource_list)
zwp_tablet_v1_send_removed(resource);
+ /* First drop all tool ids from this tablet */
+ wl_list_for_each_safe(id, tmpid, &tablet->tool_id_list, link) {
+ wl_list_remove(&id->link);
+ free(id);
+ }
+
+ /* Remove the tablet from the list */
wl_list_remove(&tablet->link);
+
+ /* For each tool, check remaining tablets for the stored ID list. If we
+ * can't find this tool anywhere, we can drop it */
+ wl_list_for_each_safe(tool, tmptool,
+ &tablet->seat->tablet_tool_list, link) {
+ bool remove_tool = true;
+
+ wl_list_for_each(t, &tablet->seat->tablet_list, link) {
+ wl_list_for_each(id, &t->tool_id_list, link) {
+ if (tool->type == id->type &&
+ tool->serial == id->serial) {
+ remove_tool = false;
+ break;
+ }
+ }
+ }
+
+ if (remove_tool)
+ weston_seat_release_tablet_tool(tool);
+ }
}
WL_EXPORT void
@@ -3394,8 +3425,6 @@ weston_seat_release_pointer(struct weston_seat *seat)
WL_EXPORT void
weston_seat_release_tablet_tool(struct weston_tablet_tool *tool)
{
- /* FIXME: nothing is calling this function yet, tools are only
- released on shutdown when the seat goes away */
wl_signal_emit(&tool->removed_signal, tool);
weston_tablet_tool_destroy(tool);
diff --git a/src/libinput-device.c b/src/libinput-device.c
index 31ce786..729825b 100644
--- a/src/libinput-device.c
+++ b/src/libinput-device.c
@@ -363,6 +363,7 @@ handle_tablet_proximity(struct libinput_device *libinput_device,
struct evdev_device *device;
struct weston_tablet *tablet;
struct weston_tablet_tool *tool;
+ struct weston_tablet_tool_id *id;
struct libinput_tablet_tool *libinput_tool;
enum libinput_tablet_tool_type libinput_tool_type;
uint32_t serial, type;
@@ -397,10 +398,12 @@ handle_tablet_proximity(struct libinput_device *libinput_device,
return;
}
- wl_list_for_each(tool, &device->seat->tablet_tool_list, link) {
- if (tool->serial == serial && tool->type == type) {
- create = false;
- break;
+ if (serial) {
+ wl_list_for_each(tool, &device->seat->tablet_tool_list, link) {
+ if (tool->serial == serial && tool->type == type) {
+ create = false;
+ break;
+ }
}
}
@@ -419,11 +422,41 @@ handle_tablet_proximity(struct libinput_device *libinput_device,
tool->capabilities |= 1 << ZWP_TABLET_TOOL_V1_CAPABILITY_TILT;
wl_list_insert(&device->seat->tablet_tool_list, &tool->link);
+
+ id = zalloc(sizeof *id);
+ if (id) {
+ id->type = tool->type;
+ id->serial = serial;
+ wl_list_insert(&tablet->tool_id_list, &id->link);
+ }
+
notify_tablet_tool_added(tool);
libinput_tablet_tool_set_user_data(libinput_tool, tool);
}
+ if (serial && !create) {
+ struct weston_tablet_tool_id *id;
+ bool add = true;
+
+ wl_list_for_each(id, &tablet->tool_id_list, link) {
+ if (id->type == tool->type &&
+ id->serial == tool->serial) {
+ add = false;
+ break;
+ }
+ }
+
+ if (add) {
+ id = zalloc(sizeof *id);
+ if (id) {
+ id->type = tool->type;
+ id->serial = tool->serial;
+ wl_list_insert(&tablet->tool_id_list, &id->link);
+ }
+ }
+ }
+
notify_tablet_tool_proximity_in(tool, time, tablet);
/* FIXME: we should send axis updates here */
notify_tablet_tool_frame(tool, time);
--
2.5.0
More information about the wayland-devel
mailing list