Master output will be in compositor->output_list. Clone output won't be in compositor->output_list, while it is in master->clone_output_list.
The group of master output and associated clone outputs will be treated as one output, client can't get any information about clone output. Signed-off-by: Xiong Zhang <[email protected]> --- src/compositor-drm.c | 9 ++++ src/compositor.c | 114 ++++++++++++++++++++++++++++++++++++++++++--------- src/compositor.h | 9 ++++ weston.ini.in | 2 + 4 files changed, 115 insertions(+), 19 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index dd1c251..de777b3 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -1951,6 +1951,13 @@ create_output_for_connector(struct drm_compositor *ec, setup_output_seat_constraint(ec, &output->base, s); free(s); + weston_config_section_get_string(section, "clone", &s, ""); + if (strcmp(s, "") != 0) { + output->base.is_clone = 1; + output->base.master_output_name = strdup(s); + } + free(s); + output->crtc_id = resources->crtcs[i]; output->pipe = i; ec->crtc_allocator |= (1 << output->crtc_id); @@ -2231,6 +2238,8 @@ create_outputs(struct drm_compositor *ec, uint32_t option_connector, drmModeFreeConnector(connector); } + weston_compositor_add_clone_outputs(&ec->base); + if (wl_list_empty(&ec->base.output_list)) { weston_log("No currently active connector found.\n"); drmModeFreeResources(resources); diff --git a/src/compositor.c b/src/compositor.c index 6aff7ab..402ac75 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -3066,6 +3066,47 @@ bind_output(struct wl_client *client, wl_output_send_done(resource); } +static void +add_clone_output(struct weston_output *clone_output) +{ + struct weston_compositor *compositor = clone_output->compositor; + struct weston_output *master_output; + uint32_t found = 0; + + wl_list_for_each(master_output, &compositor->output_list, link) { + if (clone_output->master_output_name == NULL || + strncmp(clone_output->master_output_name, + master_output->name, + strlen(clone_output->master_output_name) != 0)) + continue; + + clone_output->master_output = master_output; + found = 1; + } + + if (found == 0) + clone_output->is_clone = 0; + + weston_output_init(clone_output, compositor, + clone_output->mm_width, + clone_output->mm_height, + clone_output->transform, + clone_output->original_scale); +} + +WL_EXPORT void +weston_compositor_add_clone_outputs(struct weston_compositor *compositor) +{ + struct weston_output *clone_output, *next; + + wl_list_for_each_safe(clone_output, next, + &compositor->temp_clone_list, link) { + wl_list_remove(&clone_output->link); + + add_clone_output(clone_output); + } +} + /* Move other outputs when one is removed so the space remains contiguos. */ static void weston_compositor_remove_output(struct weston_compositor *compositor, @@ -3093,19 +3134,27 @@ weston_output_destroy(struct weston_output *output) { output->destroying = 1; - weston_compositor_remove_output(output->compositor, output); + if (!output->is_clone) + weston_compositor_remove_output(output->compositor, output); + wl_list_remove(&output->link); - wl_signal_emit(&output->compositor->output_destroyed_signal, output); - wl_signal_emit(&output->destroy_signal, output); + if (!output->is_clone) { + wl_signal_emit(&output->compositor->output_destroyed_signal, + output); + wl_signal_emit(&output->destroy_signal, output); + } free(output->name); + if (output->master_output_name) + free(output->master_output_name); pixman_region32_fini(&output->region); pixman_region32_fini(&output->previous_damage); pixman_region32_fini(&output->damage); output->compositor->output_id_pool &= ~(1 << output->id); - wl_global_destroy(output->global); + if (!output->is_clone) + wl_global_destroy(output->global); } static void @@ -3284,8 +3333,28 @@ weston_output_init(struct weston_output *output, struct weston_compositor *c, { struct weston_output *last; + output->compositor = c; + output->mm_width = mm_width; + output->mm_height = mm_height; + output->dirty = 1; + output->original_scale = scale; + + weston_output_transform_scale_init(output, transform, scale); + weston_output_init_zoom(output); + + /* If clone ouptut haven't found master output yet, then put this + * clone output to c->temp_clone_list and delay the init until found + * its master. */ + if (output->is_clone && output->master_output == NULL) { + wl_list_insert(c->temp_clone_list.prev, &output->link); + return; + } + /* Find the position for this output */ - if (!wl_list_empty(&c->output_list)) { + if (output->is_clone) { + output->x = output->master_output->x; + output->y = output->master_output->y; + } else if (!wl_list_empty(&c->output_list)) { last = container_of(c->output_list.prev, struct weston_output, link); @@ -3296,15 +3365,6 @@ weston_output_init(struct weston_output *output, struct weston_compositor *c, output->y = 0; } - output->compositor = c; - output->mm_width = mm_width; - output->mm_height = mm_height; - output->dirty = 1; - output->original_scale = scale; - - weston_output_transform_scale_init(output, transform, scale); - weston_output_init_zoom(output); - weston_output_init_geometry(output, output->x, output->y); weston_output_damage(output); @@ -3316,12 +3376,18 @@ weston_output_init(struct weston_output *output, struct weston_compositor *c, output->id = ffs(~output->compositor->output_id_pool) - 1; output->compositor->output_id_pool |= 1 << output->id; - wl_list_insert(c->output_list.prev, &output->link); + wl_list_init(&output->clone_output_list); + + if (!output->is_clone) { + wl_list_insert(c->output_list.prev, &output->link); - output->global = - wl_global_create(c->wl_display, &wl_output_interface, 2, + output->global = + wl_global_create(c->wl_display, &wl_output_interface, 2, output, bind_output); - wl_signal_emit(&c->output_created_signal, output); + wl_signal_emit(&c->output_created_signal, output); + } else + wl_list_insert(output->master_output->clone_output_list.prev, + &output->link); } WL_EXPORT void @@ -3604,6 +3670,8 @@ weston_compositor_init(struct weston_compositor *ec, wl_list_init(&ec->axis_binding_list); wl_list_init(&ec->debug_binding_list); + wl_list_init(&ec->temp_clone_list); + weston_plane_init(&ec->primary_plane, ec, 0, 0); weston_compositor_stack_plane(ec, &ec->primary_plane, NULL); @@ -3647,14 +3715,22 @@ WL_EXPORT void weston_compositor_shutdown(struct weston_compositor *ec) { struct weston_output *output, *next; + struct weston_output *clone_output, *tmp; wl_event_source_remove(ec->idle_source); if (ec->input_loop_source) wl_event_source_remove(ec->input_loop_source); /* Destroy all outputs associated with this compositor */ - wl_list_for_each_safe(output, next, &ec->output_list, link) + wl_list_for_each_safe(output, next, &ec->output_list, link) { + /* Destroy all clone outputs associated with this output. */ + wl_list_for_each_safe(clone_output, tmp, + &output->clone_output_list, + link) + clone_output->destroy(clone_output); + output->destroy(output); + } if (ec->renderer) ec->renderer->destroy(ec); diff --git a/src/compositor.h b/src/compositor.h index 6cfd09c..ed7aa45 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -213,6 +213,11 @@ struct weston_output { struct weston_mode *original_mode; struct wl_list mode_list; + uint32_t is_clone; + char *master_output_name; + struct weston_output *master_output; + struct wl_list clone_output_list; + void (*start_repaint_loop)(struct weston_output *output); int (*repaint)(struct weston_output *output, pixman_region32_t *damage); @@ -605,6 +610,8 @@ struct weston_compositor { struct wl_list axis_binding_list; struct wl_list debug_binding_list; + struct wl_list temp_clone_list; + uint32_t state; struct wl_event_source *idle_source; uint32_t idle_inhibit; @@ -1213,6 +1220,8 @@ void weston_output_init(struct weston_output *output, struct weston_compositor *c, int width, int height, uint32_t transform, int32_t scale); void +weston_compositor_add_clone_outputs(struct weston_compositor *compositor); +void weston_output_destroy(struct weston_output *output); void weston_output_transform_coordinate(struct weston_output *output, diff --git a/weston.ini.in b/weston.ini.in index 2c39177..94de52c 100644 --- a/weston.ini.in +++ b/weston.ini.in @@ -49,12 +49,14 @@ path=@libexecdir@/weston-keyboard #name=LVDS1 #mode=1680x1050 #transform=90 +#clone=VGA1 #icc_profile=/usr/share/color/icc/colord/Bluish.icc #[output] #name=VGA1 #mode=173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync #transform=flipped +#clone=LVDS1 #[output] #name=X1 -- 1.8.3.2 _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
