summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2015-09-25 10:23:28 -0400
committerAdam Jackson <ajax@redhat.com>2015-09-25 10:23:28 -0400
commitdca5770af9e20bb1148374ebfd60931a81b148a2 (patch)
tree46e4aab10babe959d4204d9e4d38e5c7e87a56cb
parenta31bbc450a08622aadafc264b3efe57e465eaecb (diff)
parent21f384b7b8b571151805674c9d384e2ad7f8b7ea (diff)
Merge remote-tracking branch 'mchalupa/output-bugs'
-rw-r--r--hw/xwayland/xwayland-output.c44
-rw-r--r--hw/xwayland/xwayland.c11
-rw-r--r--hw/xwayland/xwayland.h1
3 files changed, 43 insertions, 13 deletions
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index dd169e806..1546eaa01 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
@@ -165,6 +183,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++);
@@ -184,6 +203,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);
}
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index f25bc006b..e31becf5e 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 53ca420cf..a7d71193d 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;