diff options
author | Adam Jackson <ajax@redhat.com> | 2015-09-25 10:23:28 -0400 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2015-09-25 10:23:28 -0400 |
commit | dca5770af9e20bb1148374ebfd60931a81b148a2 (patch) | |
tree | 46e4aab10babe959d4204d9e4d38e5c7e87a56cb | |
parent | a31bbc450a08622aadafc264b3efe57e465eaecb (diff) | |
parent | 21f384b7b8b571151805674c9d384e2ad7f8b7ea (diff) |
Merge remote-tracking branch 'mchalupa/output-bugs'
-rw-r--r-- | hw/xwayland/xwayland-output.c | 44 | ||||
-rw-r--r-- | hw/xwayland/xwayland.c | 11 | ||||
-rw-r--r-- | hw/xwayland/xwayland.h | 1 |
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; |