[PATCH 11/12] compositor: Hot plug a output in clone mode
Xiong Zhang
xiong.y.zhang at intel.com
Fri Mar 7 00:27:29 PST 2014
If adding output is a clone output, first system will find its master,
then system will put this output into master->clone_output_list
If adding output is a master output, system will loop the output_list
to find its clone output. If this master has clone output, the clone
output will downgrade from master to clone.
Signed-off-by: Xiong Zhang <xiong.y.zhang at intel.com>
---
src/compositor-drm.c | 9 +++++++-
src/compositor.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++------
src/compositor.h | 2 ++
3 files changed, 64 insertions(+), 8 deletions(-)
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 58a0efa..a30f88d 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -2258,7 +2258,7 @@ update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
drmModeRes *resources;
struct drm_output *output, *next;
uint32_t connected = 0, disconnects = 0;
- int i;
+ int i, add_output = 0;
resources = drmModeGetResources(ec->drm.fd);
if (!resources) {
@@ -2287,11 +2287,18 @@ update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
drm_device);
weston_log("connector %d connected\n", connector_id);
+ add_output = 1;
+
}
drmModeFreeConnector(connector);
}
drmModeFreeResources(resources);
+ if (add_output) {
+ weston_compositor_add_clone_outputs(&ec->base);
+ weston_compositor_add_master_outputs(&ec->base);
+ }
+
disconnects = ec->connector_allocator & ~connected;
if (disconnects) {
wl_list_for_each_safe(output, next, &ec->base.output_list,
diff --git a/src/compositor.c b/src/compositor.c
index 72d29a0..39081bb 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -3139,11 +3139,9 @@ weston_compositor_remove_output(struct weston_compositor *compositor,
}
}
-WL_EXPORT void
-weston_output_destroy(struct weston_output *output)
+static void
+delete_output_from_list(struct weston_output *output)
{
- output->destroying = 1;
-
if (!output->is_clone)
weston_compositor_remove_output(output->compositor, output);
@@ -3155,12 +3153,10 @@ weston_output_destroy(struct weston_output *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);
if (!output->is_clone)
@@ -3168,6 +3164,57 @@ weston_output_destroy(struct weston_output *output)
}
static void
+migrate_clone_output(struct weston_output *clone, struct weston_output *master)
+{
+ delete_output_from_list(clone);
+
+ clone->master_output = master;
+ clone->is_clone = 1;
+
+ weston_output_init(clone, clone->compositor, clone->mm_width,
+ clone->mm_height, clone->transform,
+ clone->original_scale);
+}
+
+WL_EXPORT void
+weston_output_destroy(struct weston_output *output)
+{
+ output->destroying = 1;
+
+ delete_output_from_list(output);
+
+ free(output->name);
+ if (output->master_output_name)
+ free(output->master_output_name);
+}
+
+/* At first a clone output is discoveryed but associated master isn't found
+ * this clone output will be upgraded to master output;
+ * Then the master output is hot plugged, the original clone output
+ * should be downgraded to clone. */
+WL_EXPORT void
+weston_compositor_add_master_outputs(struct weston_compositor *compositor)
+{
+ struct weston_output *output, *master, *clone, *next1, *next2;
+
+ master = container_of(compositor->output_list.prev,
+ struct weston_output, link);
+
+ wl_list_for_each_safe(output, next1, &compositor->output_list, link) {
+ if (output->master_output_name == NULL ||
+ strncmp(output->master_output_name, master->name,
+ strlen(output->master_output_name)) != 0)
+ continue;
+
+ wl_list_for_each_safe(clone, next2, &output->clone_output_list,
+ link)
+ migrate_clone_output(clone, master);
+
+ migrate_clone_output(output, master);
+ }
+}
+
+static void
weston_output_compute_transform(struct weston_output *output)
{
struct weston_matrix transform;
diff --git a/src/compositor.h b/src/compositor.h
index ed7aa45..da63666 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -1222,6 +1222,8 @@ weston_output_init(struct weston_output *output, struct weston_compositor *c,
void
weston_compositor_add_clone_outputs(struct weston_compositor *compositor);
void
+weston_compositor_add_master_outputs(struct weston_compositor *compositor);
+void
weston_output_destroy(struct weston_output *output);
void
weston_output_transform_coordinate(struct weston_output *output,
--
1.8.3.2
More information about the wayland-devel
mailing list