window.c: Cache outputs
diff --git a/clients/window.c b/clients/window.c
index 32c546d..1c8b9ad 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -64,7 +64,6 @@
 	struct wl_shm *shm;
 	struct wl_output *output;
 	struct wl_data_device_manager *data_device_manager;
-	struct rectangle screen_allocation;
 	EGLDisplay dpy;
 	EGLConfig rgb_config;
 	EGLConfig premultiplied_argb_config;
@@ -82,6 +81,7 @@
 
 	struct wl_list window_list;
 	struct wl_list input_list;
+	struct wl_list output_list;
 	char *device_name;
 	cairo_surface_t *active_frame, *inactive_frame, *shadow;
 	struct xkb_desc *xkb;
@@ -162,6 +162,13 @@
 	struct data_offer *selection_offer;
 };
 
+struct output {
+	struct display *display;
+	struct wl_output *output;
+	struct rectangle allocation;
+	struct wl_list link;
+};
+
 enum {
 	POINTER_DEFAULT = 100,
 	POINTER_UNSET
@@ -1789,15 +1796,17 @@
 window_set_fullscreen(struct window *window, int fullscreen)
 {
 	int32_t width, height;
+	struct output *output;
 
 	if ((window->type == TYPE_FULLSCREEN) == fullscreen)
 		return;
 
 	if (fullscreen) {
+		output = display_get_output(window->display);
 		window->type = TYPE_FULLSCREEN;
 		window->saved_allocation = window->allocation;
-		width = window->display->screen_allocation.width;
-		height = window->display->screen_allocation.height;
+		width = output->allocation.width;
+		height = output->allocation.height;
 		window->decoration = 0;
 	} else {
 		window->type = TYPE_TOPLEVEL;
@@ -2026,10 +2035,10 @@
 			const char *make,
 			const char *model)
 {
-	struct display *display = data;
+	struct output *output = data;
 
-	display->screen_allocation.x = x;
-	display->screen_allocation.y = y;
+	output->allocation.x = x;
+	output->allocation.y = y;
 }
 
 static void
@@ -2040,10 +2049,12 @@
 		    int height,
 		    int refresh)
 {
-	struct display *display = data;
+	struct output *output = data;
 
-	display->screen_allocation.width = width;
-	display->screen_allocation.height = height;
+	if (flags & WL_OUTPUT_MODE_CURRENT) {
+		output->allocation.width = width;
+		output->allocation.height = height;
+	}
 }
 
 static const struct wl_output_listener output_listener = {
@@ -2052,6 +2063,30 @@
 };
 
 static void
+display_add_output(struct display *d, uint32_t id)
+{
+	struct output *output;
+
+	output = malloc(sizeof *output);
+	if (output == NULL)
+		return;
+
+	memset(output, 0, sizeof *output);
+	output->display = d;
+	output->output =
+		wl_display_bind(d->display, id, &wl_output_interface);
+	wl_list_insert(d->output_list.prev, &output->link);
+
+	wl_output_add_listener(output->output, &output_listener, output);
+}
+
+void
+output_get_allocation(struct output *output, struct rectangle *allocation)
+{
+	*allocation = output->allocation;
+}
+
+static void
 display_add_input(struct display *d, uint32_t id)
 {
 	struct input *input;
@@ -2089,8 +2124,7 @@
 		d->compositor =
 			wl_display_bind(display, id, &wl_compositor_interface);
 	} else if (strcmp(interface, "wl_output") == 0) {
-		d->output = wl_display_bind(display, id, &wl_output_interface);
-		wl_output_add_listener(d->output, &output_listener, d);
+		display_add_output(d, id);
 	} else if (strcmp(interface, "wl_input_device") == 0) {
 		display_add_input(d, id);
 	} else if (strcmp(interface, "wl_shell") == 0) {
@@ -2309,6 +2343,7 @@
 
 	wl_list_init(&d->deferred_list);
 	wl_list_init(&d->input_list);
+	wl_list_init(&d->output_list);
 
 	/* Set up listener so we'll catch all events. */
 	wl_display_add_global_listener(d->display,
@@ -2341,6 +2376,12 @@
 	return display->display;
 }
 
+struct output *
+display_get_output(struct display *display)
+{
+	return container_of(display->output_list.next, struct output, link);
+}
+
 struct wl_compositor *
 display_get_compositor(struct display *display)
 {