[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