[PATCH 8/9] hot plug remove a output in clone mode

Xiong Zhang xiong.y.zhang at intel.com
Tue Sep 17 20:51:03 PDT 2013


if removed output is clone output, just delete this output
if removed output is primary output, find a new primary output and adjust
clone output's mode necessary

Signed-off-by: Xiong Zhang <xiong.y.zhang at intel.com>
---
 src/compositor-drm.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 0aa105a..3594a1d 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -1298,6 +1298,58 @@ clone_mode_add_output(struct drm_output *output)
 }
 
 static void
+adjust_all_clone_outputs_mode(struct weston_compositor *c)
+{
+	struct drm_output *output;
+	struct drm_output *primary_output;
+
+	primary_output = (struct drm_output *)c->primary_output;
+	wl_list_for_each(output, &c->output_list, base.link) {
+		if (output != primary_output && clone_output_need_adjust_mode(output)) {
+			adjust_clone_output_mode(output);
+		}
+	}
+}
+
+static void
+clone_mode_remove_output(struct drm_output *output)
+{
+	struct drm_output *primary_output, *tmp_output;
+	struct weston_compositor *compositor;
+
+	compositor = output->base.compositor;
+	if (wl_list_empty(&compositor->output_list))
+		return;
+
+	primary_output = (struct drm_output *)compositor->primary_output;
+	/*if origin primary output will be remove, find a new primary output */
+	/* and reorder output_llist */
+	if (primary_output == output) {
+		primary_output = NULL;
+		wl_list_for_each(tmp_output, &compositor->output_list, base.link) {
+			if (!primary_output ||
+				(choose_output(primary_output, tmp_output) != primary_output))
+				primary_output = tmp_output;
+		}
+
+		if (primary_output) {
+			/*make sure primary output is the first in output_list when clone mode is enabled */
+			wl_list_remove(&primary_output->base.link);
+			wl_list_insert(&compositor->output_list, &primary_output->base.link);
+			compositor->primary_output = &primary_output->base;
+
+			primary_output->base.repaint_scheduled = 0;
+			primary_output->base.repaint_needed = 0;
+			/*find new primary output, clone output's mode may be need to adjust*/
+			adjust_all_clone_outputs_mode(compositor);
+			/*dirty all surface, so that app can get frame calllback and repaint*/
+			weston_compositor_dirty_all_surface(compositor);
+			weston_output_damage(&primary_output->base);
+		}
+	}
+}
+
+static void
 drm_output_destroy(struct weston_output *output_base)
 {
 	struct drm_output *output = (struct drm_output *) output_base;
@@ -1334,6 +1386,8 @@ drm_output_destroy(struct weston_output *output_base)
 
 	weston_output_destroy(&output->base);
 	wl_list_remove(&output->base.link);
+	if (c->base.multiscreen_mode == WESTON_MULTISCREEN_CLONE)
+		clone_mode_remove_output(output);
 
 	free(output);
 }
@@ -2427,7 +2481,8 @@ update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
 	if (disconnects) {
 		wl_list_for_each_safe(output, next, &ec->base.output_list,
 				      base.link) {
-			if (x_offset != 0 || y_offset != 0) {
+			if ((ec->base.multiscreen_mode == WESTON_MULTISCREEN_EXTEND) &&
+				(x_offset != 0 || y_offset != 0)) {
 				weston_output_move(&output->base,
 						 output->base.x - x_offset,
 						 output->base.y - y_offset);
-- 
1.8.3.2



More information about the wayland-devel mailing list