[PATCH] window: Store the outputs that the window is on

Rob Bradford rob at robster.org.uk
Tue May 15 09:55:34 PDT 2012


From: Rob Bradford <rob at linux.intel.com>

Using the surface enter/leave events track which outputs the window is on and
store those in a "window_output_list" on the window.

To create this list we define a struct window_output that is the list
relationship between the window and the output.
---
 clients/window.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/clients/window.c b/clients/window.c
index e14edb0..e532c68 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -124,10 +124,16 @@ enum {
 	TYPE_MENU,
 	TYPE_CUSTOM
 };
-       
+
+struct window_output {
+	struct output *output;
+	struct wl_list link;
+};
+
 struct window {
 	struct display *display;
 	struct window *parent;
+	struct wl_list window_output_list;
 	struct wl_surface *surface;
 	struct wl_shell_surface *shell_surface;
 	struct wl_region *input_region;
@@ -948,6 +954,8 @@ window_destroy(struct window *window)
 {
 	struct display *display = window->display;
 	struct input *input;
+	struct window_output *window_output;
+	struct window_output *window_output_tmp;
 
 	if (window->redraw_scheduled)
 		wl_list_remove(&window->redraw_task.link);
@@ -962,6 +970,11 @@ window_destroy(struct window *window)
 			input->focus_widget = NULL;
 	}
 
+	wl_list_for_each_safe(window_output, window_output_tmp,
+			      &window->window_output_list, link) {
+		free (window_output);
+	}
+
 	if (window->input_region)
 		wl_region_destroy(window->input_region);
 	if (window->opaque_region)
@@ -2620,14 +2633,48 @@ window_damage(struct window *window, int32_t x, int32_t y,
 
 static void
 surface_enter(void *data,
-	      struct wl_surface *wl_surface, struct wl_output *output)
+	      struct wl_surface *wl_surface, struct wl_output *wl_output)
 {
+	struct window *window = data;
+	struct output *output;
+	struct output *output_found = NULL;
+	struct window_output *window_output;
+
+	wl_list_for_each(output, &window->display->output_list, link) {
+		if (output->output == wl_output) {
+			output_found = output;
+			break;
+		}
+	}
+
+	if (!output_found)
+		return;
+
+	window_output = malloc (sizeof *window_output);
+	window_output->output = output_found;
+
+	wl_list_insert (&window->window_output_list, &window_output->link);
 }
 
 static void
 surface_leave(void *data,
 	      struct wl_surface *wl_surface, struct wl_output *output)
 {
+	struct window *window = data;
+	struct window_output *window_output;
+	struct window_output *window_output_found = NULL;
+
+	wl_list_for_each(window_output, &window->window_output_list, link) {
+		if (window_output->output->output == output) {
+			window_output_found = window_output;
+			break;
+		}
+	}
+
+	if (window_output_found) {
+		wl_list_remove(&window_output_found->link);
+		free(window_output_found);
+	}
 }
 
 static const struct wl_surface_listener surface_listener = {
@@ -2686,6 +2733,8 @@ window_create_internal(struct display *display, struct window *parent)
 					      &shell_surface_listener, window);
 	}
 
+	wl_list_init (&window->window_output_list);
+
 	return window;
 }
 
-- 
1.7.7.6



More information about the wayland-devel mailing list