simple-shm: implement destructors

Implement proper destructors that call the wayland destroy functions.

With this and the "client: fix a strdup memory leak" patch in Wayland
core, simple-shm now runs Valgrind-clean (memcheck).

Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
diff --git a/clients/simple-shm.c b/clients/simple-shm.c
index 19dab94..7d4f177 100644
--- a/clients/simple-shm.c
+++ b/clients/simple-shm.c
@@ -48,7 +48,8 @@
 	struct wl_surface *surface;
 	struct wl_shell_surface *shell_surface;
 	struct wl_buffer *buffer;
-	void *data;
+	void *shm_data;
+	struct wl_callback *callback;
 };
 
 static struct wl_buffer *
@@ -98,6 +99,7 @@
 	struct window *window;
 	
 	window = malloc(sizeof *window);
+	window->callback = NULL;
 	window->display = display;
 	window->width = width;
 	window->height = height;
@@ -107,13 +109,25 @@
 	window->buffer = create_shm_buffer(display,
 					   width, height,
 					   WL_SHM_FORMAT_XRGB32,
-					   &window->data);
+					   &window->shm_data);
 
 	wl_shell_surface_set_toplevel(window->shell_surface);
 
 	return window;
 }
 
+static void
+destroy_window(struct window *window)
+{
+	if (window->callback)
+		wl_callback_destroy(window->callback);
+
+	wl_buffer_destroy(window->buffer);
+	wl_shell_surface_destroy(window->shell_surface);
+	wl_surface_destroy(window->surface);
+	free(window);
+}
+
 static const struct wl_callback_listener frame_listener;
 
 static void
@@ -123,7 +137,7 @@
 	uint32_t *p;
 	int i, end, offset;
 
-	p = window->data;
+	p = window->shm_data;
 	end = window->width * window->height;
 	offset = time >> 4;
 	for (i = 0; i < end; i++)
@@ -137,8 +151,8 @@
 	if (callback)
 		wl_callback_destroy(callback);
 
-	callback = wl_surface_frame(window->surface);
-	wl_callback_add_listener(callback, &frame_listener, window);
+	window->callback = wl_surface_frame(window->surface);
+	wl_callback_add_listener(window->callback, &frame_listener, window);
 }
 
 static const struct wl_callback_listener frame_listener = {
@@ -209,6 +223,22 @@
 	return display;
 }
 
+static void
+destroy_display(struct display *display)
+{
+	if (display->shm)
+		wl_shm_destroy(display->shm);
+
+	if (display->shell)
+		wl_shell_destroy(display->shell);
+
+	if (display->compositor)
+		wl_compositor_destroy(display->compositor);
+
+	wl_display_destroy(display->display);
+	free(display);
+}
+
 static int running = 1;
 
 static void
@@ -238,6 +268,8 @@
 		wl_display_iterate(display->display, display->mask);
 
 	fprintf(stderr, "simple-shm exiting\n");
+	destroy_window(window);
+	destroy_display(display);
 
 	return 0;
 }