window, desktop-shell: deal with output unplug on client side

when output is removed, weston-desktop-shell should destroy panel
and background surface on destroyed output.

Signed-off-by: Xiong Zhang <xiong.y.zhang@intel.com>
diff --git a/clients/window.c b/clients/window.c
index 17d16ed..331569a 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -117,6 +117,7 @@
 
 	display_output_handler_t output_configure_handler;
 	display_global_handler_t global_handler;
+	display_global_handler_t global_handler_remove;
 
 	void *user_data;
 
@@ -339,6 +340,7 @@
 struct output {
 	struct display *display;
 	struct wl_output *output;
+	uint32_t server_output_id;
 	struct rectangle allocation;
 	struct wl_list link;
 	int transform;
@@ -4606,6 +4608,7 @@
 	output->scale = 1;
 	output->output =
 		wl_registry_bind(d->registry, id, &wl_output_interface, 2);
+	output->server_output_id = id;
 	wl_list_insert(d->output_list.prev, &output->link);
 
 	wl_output_add_listener(output->output, &output_listener, output);
@@ -4622,6 +4625,19 @@
 	free(output);
 }
 
+static void
+display_destroy_output(struct display *d, uint32_t id)
+{
+	struct output *output;
+
+	wl_list_for_each(output, &d->output_list, link) {
+		if (output->server_output_id == id) {
+			output_destroy(output);
+			break;
+		}
+	}
+}
+
 void
 display_set_global_handler(struct display *display,
 			   display_global_handler_t handler)
@@ -4639,6 +4655,15 @@
 }
 
 void
+display_set_global_handler_remove(struct display *display,
+			   display_global_handler_t remove_handler)
+{
+	display->global_handler_remove = remove_handler;
+	if (!remove_handler)
+		return;
+}
+
+void
 display_set_output_configure_handler(struct display *display,
 				     display_output_handler_t handler)
 {
@@ -4872,9 +4897,15 @@
 		if (global->name != name)
 			continue;
 
-		/* XXX: Should destroy bound globals, and call
-		 * the counterpart of display::global_handler
-		 */
+		if (strcmp(global->interface, "wl_output") == 0)
+			display_destroy_output(d, name);
+
+		/* XXX: Should destroy remaining bound globals */
+
+		if (d->global_handler_remove)
+			d->global_handler_remove(d, name, global->interface,
+					global->version, d->user_data);
+
 		wl_list_remove(&global->link);
 		free(global->interface);
 		free(global);