From eae3c06c23af59f192ab0c409a56d80f6bc34ce4 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Tue, 17 May 2022 18:40:11 +0200
Subject: [PATCH] xwayland: make the output serials belong to the screen

Xwayland uses an output serial number it increments each time a new
Wayland output is added.

On server regeneration, that static value is not cleared, and therfore
the output numbers keep increasing each time the Xserver restarts.

To avoid that issue, make the output serial part of the xwl_screen,
which gets recreated on server regeneration, so that index is reset to 0
automatically on server regeneration.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
---
 hw/xwayland/xwayland-drm-lease.c | 12 +++++++-----
 hw/xwayland/xwayland-output.c    | 10 ++--------
 hw/xwayland/xwayland-output.h    |  2 --
 hw/xwayland/xwayland-screen.c    |  7 +++++++
 hw/xwayland/xwayland-screen.h    |  2 ++
 5 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/hw/xwayland/xwayland-drm-lease.c b/hw/xwayland/xwayland-drm-lease.c
index 8bbb27e70f..d623b4b797 100644
--- a/hw/xwayland/xwayland-drm-lease.c
+++ b/hw/xwayland/xwayland-drm-lease.c
@@ -336,6 +336,7 @@ drm_lease_device_handle_connector(void *data,
                                   struct wp_drm_lease_connector_v1 *connector)
 {
     struct xwl_drm_lease_device *lease_device = data;
+    struct xwl_screen *xwl_screen = lease_device->xwl_screen;
     struct xwl_output *xwl_output;
     char name[256];
 
@@ -345,18 +346,19 @@ drm_lease_device_handle_connector(void *data,
         return;
     }
 
-    snprintf(name, sizeof name, "XWAYLAND%d", xwl_get_next_output_serial());
+    snprintf(name, sizeof name, "XWAYLAND%d",
+             xwl_screen_get_next_output_serial(xwl_screen));
 
     xwl_output->lease_device = lease_device;
-    xwl_output->xwl_screen = lease_device->xwl_screen;
+    xwl_output->xwl_screen = xwl_screen;
     xwl_output->lease_connector = connector;
-    xwl_output->randr_crtc = RRCrtcCreate(lease_device->xwl_screen->screen, xwl_output);
+    xwl_output->randr_crtc = RRCrtcCreate(xwl_screen->screen, xwl_output);
     if (!xwl_output->randr_crtc) {
         ErrorF("Failed creating RandR CRTC\n");
         goto err;
     }
     RRCrtcSetRotations(xwl_output->randr_crtc, ALL_ROTATIONS);
-    xwl_output->randr_output = RROutputCreate(lease_device->xwl_screen->screen,
+    xwl_output->randr_output = RROutputCreate(xwl_screen->screen,
                                               name, strlen(name), xwl_output);
     if (!xwl_output->randr_output) {
         ErrorF("Failed creating RandR Output\n");
@@ -373,7 +375,7 @@ drm_lease_device_handle_connector(void *data,
                                             &lease_connector_listener,
                                             xwl_output);
 
-    xorg_list_append(&xwl_output->link, &lease_device->xwl_screen->output_list);
+    xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
     return;
 
 err:
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 1dd5a5f896..4a6a98f520 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -768,7 +768,8 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)
     xwl_output->server_output_id = id;
     wl_output_add_listener(xwl_output->output, &output_listener, xwl_output);
 
-    snprintf(name, sizeof name, "XWAYLAND%d", xwl_get_next_output_serial());
+    snprintf(name, sizeof name, "XWAYLAND%d",
+             xwl_screen_get_next_output_serial(xwl_screen));
 
     xwl_output->xwl_screen = xwl_screen;
     xwl_output->randr_crtc = RRCrtcCreate(xwl_screen->screen, xwl_output);
@@ -1011,10 +1012,3 @@ xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen)
     xorg_list_for_each_entry(it, &xwl_screen->output_list, link)
         xwl_output_get_xdg_output(it);
 }
-
-int
-xwl_get_next_output_serial(void)
-{
-    static int output_name_serial = 0;
-    return output_name_serial++;
-}
diff --git a/hw/xwayland/xwayland-output.h b/hw/xwayland/xwayland-output.h
index 74a46994fe..10a353ddc9 100644
--- a/hw/xwayland/xwayland-output.h
+++ b/hw/xwayland/xwayland-output.h
@@ -94,6 +94,4 @@ void xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen,
 
 void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen);
 
-int xwl_get_next_output_serial(void);
-
 #endif /* XWAYLAND_OUTPUT_H */
diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
index dd520819ba..c9b93a2da0 100644
--- a/hw/xwayland/xwayland-screen.c
+++ b/hw/xwayland/xwayland-screen.c
@@ -580,6 +580,13 @@ xwl_screen_roundtrip(struct xwl_screen *xwl_screen)
         xwl_give_up("could not connect to wayland server\n");
 }
 
+
+int
+xwl_screen_get_next_output_serial(struct xwl_screen *xwl_screen)
+{
+    return xwl_screen->output_name_serial++;
+}
+
 Bool
 xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
 {
diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
index f8aee2bdc5..a4738882a4 100644
--- a/hw/xwayland/xwayland-screen.h
+++ b/hw/xwayland/xwayland-screen.h
@@ -48,6 +48,7 @@ struct xwl_screen {
     int width;
     int height;
     int depth;
+    int output_name_serial;
     ScreenPtr screen;
     int wm_client_id;
     int expecting_event;
@@ -140,5 +141,6 @@ void xwl_screen_roundtrip (struct xwl_screen *xwl_screen);
 void xwl_surface_damage(struct xwl_screen *xwl_screen,
                         struct wl_surface *surface,
                         int32_t x, int32_t y, int32_t width, int32_t height);
+int xwl_screen_get_next_output_serial(struct xwl_screen * xwl_screen);
 
 #endif /* XWAYLAND_SCREEN_H */
-- 
GitLab