[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