xserver: Branch 'master' - 4 commits

Adam Jackson ajax at kemper.freedesktop.org
Fri Sep 25 07:23:41 PDT 2015


 hw/xwayland/xwayland-output.c |   44 ++++++++++++++++++++++++++++++------------
 hw/xwayland/xwayland.c        |   11 +++++++++-
 hw/xwayland/xwayland.h        |    1 
 3 files changed, 43 insertions(+), 13 deletions(-)

New commits:
commit dca5770af9e20bb1148374ebfd60931a81b148a2
Merge: a31bbc4 21f384b
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri Sep 25 10:23:28 2015 -0400

    Merge remote-tracking branch 'mchalupa/output-bugs'

commit 21f384b7b8b571151805674c9d384e2ad7f8b7ea
Author: Marek Chalupa <mchqwerty at gmail.com>
Date:   Thu May 21 15:43:43 2015 +0200

    xwayland: do not add output into output_list multiple times
    
    output.done event can be sent even on some property change, not only
    when announcing the output. Therefore we must check if we already have it
    otherwise we may corrupt the list by adding it multiple times.
    
    This fixes bug when xwayland looped indefinitely in output.done handler
    and that can be reproduced following these steps (under X without
    multi-monitor setup):
     1) run weston --output-count=2
     2) run xterm, move it so that half is on one output
        and half on the other
     3) close second output, try run weston-terminal
    
    weston sends updated outputs which trigger this bug.
    
    v2. factor out common code into function
        move expecting_events into right branch
    
    Signed-off-by: Marek Chalupa <mchqwerty at gmail.com>

diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 28aec8e..1546eaa 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -113,29 +113,47 @@ output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
                  xwl_output->rotation, NULL, 1, &xwl_output->randr_output);
 }
 
+static inline void
+output_get_new_size(struct xwl_output *xwl_output,
+		    int *height, int *width)
+{
+    if (*width < xwl_output->x + xwl_output->width)
+        *width = xwl_output->x + xwl_output->width;
+
+    if (*height < xwl_output->y + xwl_output->height)
+        *height = xwl_output->y + xwl_output->height;
+}
+
 static void
 output_handle_done(void *data, struct wl_output *wl_output)
 {
-    struct xwl_output *xwl_output = data;
+    struct xwl_output *it, *xwl_output = data;
     struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
-    int width, height;
+    int width = 0, height = 0, has_this_output = 0;
 
-    xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
+    xorg_list_for_each_entry(it, &xwl_screen->output_list, link) {
+        /* output done event is sent even when some property
+         * of output is changed. That means that we may already
+         * have this output. If it is true, we must not add it
+         * into the output_list otherwise we'll corrupt it */
+        if (it == xwl_output)
+            has_this_output = 1;
 
-    width = 0;
-    height = 0;
-    xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
-        if (width < xwl_output->x + xwl_output->width)
-            width = xwl_output->x + xwl_output->width;
-        if (height < xwl_output->y + xwl_output->height)
-            height = xwl_output->y + xwl_output->height;
+        output_get_new_size(it, &height, &width);
+    }
+
+    if (!has_this_output) {
+        xorg_list_append(&xwl_output->link, &xwl_screen->output_list);
+
+        /* we did not check this output for new screen size, do it now */
+        output_get_new_size(xwl_output, &height, &width);
+
+	--xwl_screen->expecting_event;
     }
 
     xwl_screen->width = width;
     xwl_screen->height = height;
     RRScreenSizeNotify(xwl_screen->screen);
-
-    xwl_screen->expecting_event--;
 }
 
 static void
commit 95014ad2a7815282efdecc895bf14742b4b3ccb3
Author: Dima Ryazanov <dima at gmail.com>
Date:   Tue May 12 10:21:18 2015 -0700

    xwayland: Remove the output from the list after destroying it
    
    [Marek Chalupa]: rebased to master
    
    Signed-off-by: Dima Ryazanov <dima at gmail.com>

diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 927224a..28aec8e 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -185,6 +185,7 @@ void
 xwl_output_destroy(struct xwl_output *xwl_output)
 {
     wl_output_destroy(xwl_output->output);
+    xorg_list_del(&xwl_output->link);
     free(xwl_output);
 }
 
commit 550984c95ef0bee1886dbb54e35edc0852772e2f
Author: Dima Ryazanov <dima at gmail.com>
Date:   Fri May 15 22:38:28 2015 -0700

    xwayland: Destroy xwl_output when wl_output gets removed
    
    This makes Xwayland correctly handle a monitor getting unplugged.
    
    [Marek]: use xorg_list_for_each_entry_safe
    
    Signed-off-by: Dima Ryazanov <dima at gmail.com>
    Signed-off-by: Marek Chalupa <mchqwerty at gmail.com>

diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index dd169e8..927224a 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -165,6 +165,7 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)
 
     xwl_output->output = wl_registry_bind(xwl_screen->registry, id,
                                           &wl_output_interface, 2);
+    xwl_output->server_output_id = id;
     wl_output_add_listener(xwl_output->output, &output_listener, xwl_output);
 
     snprintf(name, sizeof name, "XWAYLAND%d", serial++);
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index f25bc00..e31becf 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -410,7 +410,16 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,
 static void
 global_remove(void *data, struct wl_registry *registry, uint32_t name)
 {
-    /* Nothing to do here, wl_compositor and wl_shm should not be removed */
+    struct xwl_screen *xwl_screen = data;
+    struct xwl_output *xwl_output, *tmp_xwl_output;
+
+    xorg_list_for_each_entry_safe(xwl_output, tmp_xwl_output,
+                                  &xwl_screen->output_list, link) {
+        if (xwl_output->server_output_id == name) {
+            xwl_output_destroy(xwl_output);
+            break;
+        }
+    }
 }
 
 static const struct wl_registry_listener registry_listener = {
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 53ca420..a7d7119 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -142,6 +142,7 @@ struct xwl_seat {
 struct xwl_output {
     struct xorg_list link;
     struct wl_output *output;
+    uint32_t server_output_id;
     struct xwl_screen *xwl_screen;
     RROutputPtr randr_output;
     RRCrtcPtr randr_crtc;


More information about the xorg-commit mailing list