desktop-shell: destroy data before exiting.

desktop-shell never returned from display_run() since it
was essentially killed when weston exited.  To fix this,
it is necessary to watch for EPOLLHUP in window.c so that
toytoolkit clients will return from display_run() when
weston quits.  This allows for clients to clean up
as needed.

Signed-off-by: U. Artie Eoff <ullysses.a.eoff@intel.com>
diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index 588dc1c..dc43652 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -372,6 +372,16 @@
 }
 
 static void
+panel_destroy_clock(struct panel_clock *clock)
+{
+	widget_destroy(clock->widget);
+
+	close(clock->clock_fd);
+
+	free(clock);
+}
+
+static void
 panel_add_clock(struct panel *panel)
 {
 	struct panel_clock *clock;
@@ -447,6 +457,39 @@
 	window_schedule_resize(panel->window, width, 32);
 }
 
+static void
+panel_destroy_launcher(struct panel_launcher *launcher)
+{
+	wl_array_release(&launcher->argv);
+	wl_array_release(&launcher->envp);
+
+	free(launcher->path);
+
+	cairo_surface_destroy(launcher->icon);
+
+	widget_destroy(launcher->widget);
+	wl_list_remove(&launcher->link);
+
+	free(launcher);
+}
+
+static void
+panel_destroy(struct panel *panel)
+{
+	struct panel_launcher *tmp;
+	struct panel_launcher *launcher;
+
+	panel_destroy_clock(panel->clock);
+
+	wl_list_for_each_safe(launcher, tmp, &panel->launcher_list, link)
+		panel_destroy_launcher(launcher);
+
+	widget_destroy(panel->widget);
+	window_destroy(panel->window);
+
+	free(panel);
+}
+
 static struct panel *
 panel_create(struct display *display)
 {
@@ -885,6 +928,15 @@
 	desktop_shell_grab_cursor
 };
 
+static void
+background_destroy(struct background *background)
+{
+	widget_destroy(background->widget);
+	window_destroy(background->window);
+
+	free(background);
+}
+
 static struct background *
 background_create(struct desktop *desktop)
 {
@@ -912,6 +964,13 @@
 }
 
 static void
+grab_surface_destroy(struct desktop *desktop)
+{
+	widget_destroy(desktop->grab_widget);
+	window_destroy(desktop->grab_window);
+}
+
+static void
 grab_surface_create(struct desktop *desktop)
 {
 	struct wl_surface *s;
@@ -933,6 +992,27 @@
 }
 
 static void
+output_destroy(struct output *output)
+{
+	background_destroy(output->background);
+	panel_destroy(output->panel);
+	wl_output_destroy(output->output);
+	wl_list_remove(&output->link);
+
+	free(output);
+}
+
+static void
+desktop_destroy_outputs(struct desktop *desktop)
+{
+	struct output *tmp;
+	struct output *output;
+
+	wl_list_for_each_safe(output, tmp, &desktop->outputs, link)
+		output_destroy(output);
+}
+
+static void
 create_output(struct desktop *desktop, uint32_t id)
 {
 	struct output *output;
@@ -1043,5 +1123,13 @@
 
 	display_run(desktop.display);
 
+	/* Cleanup */
+	grab_surface_destroy(&desktop);
+	desktop_destroy_outputs(&desktop);
+	if (desktop.unlock_dialog)
+		unlock_dialog_destroy(desktop.unlock_dialog);
+	desktop_shell_destroy(desktop.shell);
+	display_destroy(desktop.display);
+
 	return 0;
 }