From: Stephen Chandler Paul <thatsly...@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.hutte...@who-t.net>
Signed-off-by: Stephen Chandler Paul <thatsly...@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net>
---
 src/compositor.h      |  2 ++
 src/input.c           | 26 ++++++++++++++++++++++++++
 src/libinput-device.c | 27 +++++++++++++++++++++++----
 3 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/src/compositor.h b/src/compositor.h
index 8cc3cee..3f563f4 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -421,6 +421,7 @@ struct weston_tablet_tool {
        uint32_t focus_serial;
        uint32_t grab_serial;
 
+       struct wl_list tablet_list;
        struct wl_list link;
 
        uint64_t serial;
@@ -452,6 +453,7 @@ struct weston_tablet {
        struct wl_list resource_list;
 
        struct wl_list link;
+       struct wl_list tool_link;
 
        char *name;
        enum zwp_tablet1_type type;
diff --git a/src/input.c b/src/input.c
index b4e6c14..3761239 100644
--- a/src/input.c
+++ b/src/input.c
@@ -682,10 +682,30 @@ WL_EXPORT void
 weston_tablet_destroy(struct weston_tablet *tablet)
 {
        struct wl_resource *resource;
+       struct weston_tablet_tool *tool, *tmp;
 
        wl_resource_for_each(resource, &tablet->resource_list)
                zwp_tablet1_send_removed(resource);
 
+       /* Check all tools whether they're linked with this tablet and break
+        * that link. If the tool is left with no linked tablets after
+        * this, we can destroy it. */
+       wl_list_for_each_safe(tool, tmp, &tablet->seat->tablet_tool_list, link) 
{
+               struct weston_tablet *t, *tmpt;
+               bool remove_tool = false;
+
+               wl_list_for_each_safe(t, tmpt, &tool->tablet_list, tool_link) {
+                       if (t == tablet) {
+                               wl_list_remove(&t->tool_link);
+                               remove_tool = true;
+                               break;
+                       }
+               }
+
+               if (remove_tool && wl_list_empty(&tool->tablet_list))
+                       weston_tablet_tool_destroy(tool);
+       }
+
        wl_list_remove(&tablet->link);
        free(tablet->name);
        free(tablet);
@@ -978,6 +998,7 @@ weston_tablet_tool_create(void)
 
        wl_list_init(&tool->resource_list);
        wl_list_init(&tool->focus_resource_list);
+       wl_list_init(&tool->tablet_list);
 
        wl_list_init(&tool->sprite_destroy_listener.link);
        tool->sprite_destroy_listener.notify = 
tablet_tool_handle_sprite_destroy;
@@ -1003,6 +1024,11 @@ weston_tablet_tool_destroy(struct weston_tablet_tool 
*tool)
 {
        struct wl_resource *resource, *tmp;
 
+       if (!wl_list_empty(&tool->tablet_list)) {
+               weston_log("error: tool still linked to a tablet\n");
+               return;
+       }
+
        if (tool->sprite)
                tablet_tool_unmap_sprite(tool);
 
diff --git a/src/libinput-device.c b/src/libinput-device.c
index ba89410..d8643c8 100644
--- a/src/libinput-device.c
+++ b/src/libinput-device.c
@@ -334,10 +334,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;
+                       }
                }
        }
 
@@ -361,11 +363,28 @@ handle_tablet_proximity(struct libinput_device 
*libinput_device,
                    tool->capabilities |= 1 << ZWP_TABLET_TOOL1_CAPABILITY_TILT;
 
                wl_list_insert(&device->seat->tablet_tool_list, &tool->link);
+               wl_list_insert(&tool->tablet_list, &tablet->tool_link);
+
                notify_tablet_tool_added(tool);
 
                libinput_tool_set_user_data(libinput_tool, tool);
        }
 
+       if (serial && !create) {
+               struct weston_tablet *t;
+               bool add = true;
+
+               wl_list_for_each(t, &tool->tablet_list, tool_link) {
+                       if (t == tablet) {
+                               add = false;
+                               break;
+                       }
+               }
+
+               if (add)
+                       wl_list_insert(&tool->tablet_list, &tablet->tool_link);
+       }
+
        notify_tablet_tool_proximity_in(tool, time, tablet);
        /* FIXME: we should send axis updates  here */
        notify_tablet_tool_frame(tool, time);
-- 
2.4.3

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to