From: Lyude 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: Lyude Paul <thatsly...@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net>
Signed-off-by: Bastian Farkas <bfar...@de.adit-jv.com>
---
 libweston/compositor.h      |  8 ++++++++
 libweston/input.c           | 33 +++++++++++++++++++++++++++++++--
 libweston/libinput-device.c | 41 +++++++++++++++++++++++++++++++++++++----
 3 files changed, 76 insertions(+), 6 deletions(-)

diff --git a/libweston/compositor.h b/libweston/compositor.h
index 90800a7..fb59615 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -477,6 +477,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;
@@ -484,6 +491,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/libweston/input.c b/libweston/input.c
index ecd4c58..d8251b1 100644
--- a/libweston/input.c
+++ b/libweston/input.c
@@ -1217,6 +1217,7 @@ weston_tablet_create(void)
                return NULL;
 
        wl_list_init(&tablet->resource_list);
+       wl_list_init(&tablet->tool_id_list);
 
        return tablet;
 }
@@ -1225,11 +1226,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
@@ -3821,8 +3852,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/libweston/libinput-device.c b/libweston/libinput-device.c
index 49ee444..82c528d 100644
--- a/libweston/libinput-device.c
+++ b/libweston/libinput-device.c
@@ -370,6 +370,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;
@@ -404,10 +405,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;
+                       }
                }
        }
 
@@ -426,11 +429,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.7.4

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

Reply via email to