compositor: Add a destroy signal and turn weston_shell into signals
diff --git a/src/compositor.c b/src/compositor.c
index bb0cb35..1be1e10 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -229,7 +229,8 @@
 	pixman_region32_init(&surface->transform.opaque);
 	wl_list_init(&surface->frame_callback_list);
 
-	surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy;
+	surface->buffer_destroy_listener.notify =
+		surface_handle_buffer_destroy;
 
 	wl_list_init(&surface->geometry.transformation_list);
 	wl_list_insert(&surface->geometry.transformation_list,
@@ -908,7 +909,7 @@
 			compositor->fade.surface = NULL;
 		} else if (compositor->fade.spring.current > 0.999) {
 			compositor->state = WESTON_COMPOSITOR_SLEEPING;
-			compositor->shell->lock(compositor->shell);
+			wl_signal_emit(&compositor->lock_signal, compositor);
 		}
 	}
 }
@@ -1405,7 +1406,7 @@
 		weston_compositor_wake(compositor);
 	} else {
 		weston_compositor_dpms_on(compositor);
-		compositor->shell->unlock(compositor->shell);
+		wl_signal_emit(&compositor->unlock_signal, compositor);
 	}
 }
 
@@ -1513,9 +1514,13 @@
 weston_surface_activate(struct weston_surface *surface,
 			struct weston_input_device *device)
 {
+	struct weston_compositor *compositor = device->compositor;
+
 	wl_input_device_set_keyboard_focus(&device->input_device,
 					   &surface->surface);
 	wl_data_device_set_keyboard_focus(&device->input_device);
+
+	wl_signal_emit(&compositor->activate_signal, surface);
 }
 
 WL_EXPORT void
@@ -2332,6 +2337,10 @@
 	const char *extensions;
 
 	ec->wl_display = display;
+	wl_signal_init(&ec->destroy_signal);
+	wl_signal_init(&ec->activate_signal);
+	wl_signal_init(&ec->lock_signal);
+	wl_signal_init(&ec->unlock_signal);
 	ec->launcher_sock = weston_environment_get_fd("WESTON_LAUNCHER_SOCK");
 
 	if (!wl_display_add_global(display, &wl_compositor_interface,
@@ -2388,7 +2397,7 @@
 	weston_layer_init(&ec->fade_layer, &ec->layer_list);
 	weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
 
-	ec->screenshooter = screenshooter_create(ec);
+	screenshooter_create(ec);
 
 	wl_data_device_manager_init(ec->wl_display);
 
@@ -2421,9 +2430,6 @@
 	if (ec->input_loop_source)
 		wl_event_source_remove(ec->input_loop_source);
 
-	if (ec->screenshooter)
-		screenshooter_destroy(ec->screenshooter);
-
 	/* Destroy all outputs associated with this compositor */
 	wl_list_for_each_safe(output, next, &ec->output_list, link)
 		output->destroy(output);
@@ -2615,12 +2621,7 @@
 	/* prevent further rendering while shutting down */
 	ec->state = WESTON_COMPOSITOR_SLEEPING;
 
-#ifdef BUILD_XSERVER_LAUNCHER
-	if (xserver)
-		weston_xserver_destroy(ec);
-#endif
-
-	ec->shell->destroy(ec->shell);
+	wl_signal_emit(&ec->destroy_signal, ec);
 
 	if (ec->has_bind_display)
 		ec->unbind_display(ec->display, display);
diff --git a/src/compositor.h b/src/compositor.h
index 01e8d53..8fc5ab0 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -152,12 +152,6 @@
 	uint32_t timestamp;
 };
 
-struct weston_shell {
-	void (*lock)(struct weston_shell *shell);
-	void (*unlock)(struct weston_shell *shell);
-	void (*destroy)(struct weston_shell *shell);
-};
-
 enum {
 	WESTON_COMPOSITOR_ACTIVE,
 	WESTON_COMPOSITOR_IDLE,		/* shell->unlock called on activity */
@@ -173,7 +167,7 @@
 
 struct weston_compositor {
 	struct wl_shm *shm;
-	struct weston_xserver *wxs;
+	struct wl_signal destroy_signal;
 
 	EGLDisplay display;
 	EGLContext context;
@@ -184,7 +178,9 @@
 	struct weston_shader *current_shader;
 	struct wl_display *wl_display;
 
-	struct weston_shell *shell;
+	struct wl_signal activate_signal;
+	struct wl_signal lock_signal;
+	struct wl_signal unlock_signal;
 
 	struct wl_event_loop *input_loop;
 	struct wl_event_source *input_loop_source;
@@ -520,11 +516,8 @@
 int
 tty_activate_vt(struct tty *tty, int vt);
 
-struct screenshooter *
-screenshooter_create(struct weston_compositor *ec);
-
 void
-screenshooter_destroy(struct screenshooter *s);
+screenshooter_create(struct weston_compositor *ec);
 
 struct weston_process;
 typedef void (*weston_process_cleanup_func_t)(struct weston_process *process,
@@ -547,12 +540,6 @@
 
 int
 weston_xserver_init(struct weston_compositor *compositor);
-void
-weston_xserver_destroy(struct weston_compositor *compositor);
-void
-weston_xserver_surface_activate(struct weston_surface *surface);
-void
-weston_xserver_set_selection(struct weston_input_device *device);
 
 struct weston_zoom;
 typedef	void (*weston_zoom_done_func_t)(struct weston_zoom *zoom, void *data);
diff --git a/src/screenshooter.c b/src/screenshooter.c
index 414bcea..bd81351 100644
--- a/src/screenshooter.c
+++ b/src/screenshooter.c
@@ -33,6 +33,7 @@
 	struct wl_global *global;
 	struct wl_client *client;
 	struct weston_process process;
+	struct wl_listener destroy_listener;
 };
 
 static void
@@ -121,14 +122,24 @@
 					screenshooter_exe, screenshooter_sigchld);
 }
 
-struct screenshooter *
+static void
+screenshooter_destroy(struct wl_listener *listener, void *data)
+{
+	struct screenshooter *shooter =
+		container_of(listener, struct screenshooter, destroy_listener);
+
+	wl_display_remove_global(shooter->ec->wl_display, shooter->global);
+	free(shooter);
+}
+
+void
 screenshooter_create(struct weston_compositor *ec)
 {
 	struct screenshooter *shooter;
 
 	shooter = malloc(sizeof *shooter);
 	if (shooter == NULL)
-		return NULL;
+		return;
 
 	shooter->base.interface = &screenshooter_interface;
 	shooter->base.implementation =
@@ -142,12 +153,6 @@
 	weston_compositor_add_binding(ec, KEY_S, 0, 0, MODIFIER_SUPER,
 					screenshooter_binding, shooter);
 
-	return shooter;
-}
-
-void
-screenshooter_destroy(struct screenshooter *shooter)
-{
-	wl_display_remove_global(shooter->ec->wl_display, shooter->global);
-	free(shooter);
+	shooter->destroy_listener.notify = screenshooter_destroy;
+	wl_signal_add(&ec->destroy_signal, &shooter->destroy_listener);
 }
diff --git a/src/shell.c b/src/shell.c
index b7bd4be..6572ae3 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -40,7 +40,10 @@
 
 struct wl_shell {
 	struct weston_compositor *compositor;
-	struct weston_shell shell;
+
+	struct wl_listener lock_listener;
+	struct wl_listener unlock_listener;
+	struct wl_listener destroy_listener;
 
 	struct weston_layer fullscreen_layer;
 	struct weston_layer panel_layer;
@@ -98,6 +101,7 @@
 	struct weston_surface *surface;
 	struct wl_listener surface_destroy_listener;
 	struct shell_surface *parent;
+	struct wl_shell *shell;
 
 	enum shell_surface_type type;
 	int32_t saved_x, saved_y;
@@ -514,10 +518,7 @@
 static struct wl_shell *
 shell_surface_get_shell(struct shell_surface *shsurf)
 {
-	struct weston_surface *es = shsurf->surface;
-	struct weston_shell *shell = es->compositor->shell;
-
-	return (struct wl_shell *)container_of(shell, struct wl_shell, shell);
+	return shsurf->shell;
 }
 
 static int
@@ -916,6 +917,7 @@
 		(void (**)(void)) &shell_surface_implementation;
 	shsurf->resource.data = shsurf;
 
+	shsurf->shell = resource->data;
 	shsurf->saved_position_valid = false;
 	shsurf->surface = surface;
 	shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT;
@@ -1469,18 +1471,13 @@
 }
 
 static void
-activate(struct weston_shell *base, struct weston_surface *es,
+activate(struct wl_shell *shell, struct weston_surface *es,
 	 struct weston_input_device *device)
 {
-	struct wl_shell *shell = container_of(base, struct wl_shell, shell);
-	struct weston_compositor *compositor = shell->compositor;
 	struct weston_surface *surf, *prev;
 
 	weston_surface_activate(es, device);
 
-	if (compositor->wxs)
-		weston_xserver_surface_activate(es);
-
 	switch (get_shell_surface_type(es)) {
 	case SHELL_SURFACE_BACKGROUND:
 	case SHELL_SURFACE_PANEL:
@@ -1537,7 +1534,7 @@
 			  uint32_t button, uint32_t axis, int32_t state, void *data)
 {
 	struct weston_input_device *wd = (struct weston_input_device *) device;
-	struct weston_compositor *compositor = data;
+	struct wl_shell *shell = data;
 	struct weston_surface *focus;
 	struct weston_surface *upper;
 
@@ -1549,13 +1546,14 @@
 		focus = upper;
 
 	if (state && device->pointer_grab == &device->default_pointer_grab)
-		activate(compositor->shell, focus, wd);
+		activate(shell, focus, wd);
 }
 
 static void
-lock(struct weston_shell *base)
+lock(struct wl_listener *listener, void *data)
 {
-	struct wl_shell *shell = container_of(base, struct wl_shell, shell);
+	struct wl_shell *shell =
+		container_of(listener, struct wl_shell, lock_listener);
 	struct weston_input_device *device;
 	struct shell_surface *shsurf;
 	struct weston_output *output;
@@ -1606,9 +1604,10 @@
 }
 
 static void
-unlock(struct weston_shell *base)
+unlock(struct wl_listener *listener, void *data)
 {
-	struct wl_shell *shell = container_of(base, struct wl_shell, shell);
+	struct wl_shell *shell =
+		container_of(listener, struct wl_shell, unlock_listener);
 
 	if (!shell->locked || shell->lock_surface) {
 		weston_compositor_wake(shell->compositor);
@@ -1639,10 +1638,9 @@
 }
 
 static void
-map(struct weston_shell *base, struct weston_surface *surface,
+map(struct wl_shell *shell, struct weston_surface *surface,
     int32_t width, int32_t height, int32_t sx, int32_t sy)
 {
-	struct wl_shell *shell = container_of(base, struct wl_shell, shell);
 	struct weston_compositor *compositor = shell->compositor;
 	struct shell_surface *shsurf;
 	enum shell_surface_type surface_type = SHELL_SURFACE_NONE;
@@ -1743,7 +1741,7 @@
 	case SHELL_SURFACE_FULLSCREEN:
 	case SHELL_SURFACE_MAXIMIZED:
 		if (!shell->locked)
-			activate(base, surface,
+			activate(shell, surface,
 				 (struct weston_input_device *)
 				 compositor->input_device);
 		break;
@@ -1756,10 +1754,9 @@
 }
 
 static void
-configure(struct weston_shell *base, struct weston_surface *surface,
+configure(struct wl_shell *shell, struct weston_surface *surface,
 	  GLfloat x, GLfloat y, int32_t width, int32_t height)
 {
-	struct wl_shell *shell = container_of(base, struct wl_shell, shell);
 	enum shell_surface_type surface_type = SHELL_SURFACE_NONE;
 	enum shell_surface_type prev_surface_type = SHELL_SURFACE_NONE;
 	struct shell_surface *shsurf;
@@ -1809,8 +1806,8 @@
 static void
 shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
 {
-	struct weston_shell *shell = es->compositor->shell;
 	struct shell_surface *shsurf = get_shell_surface(es);
+	struct wl_shell *shell = shsurf->shell;
 
 	if (!weston_surface_is_mapped(es)) {
 		map(shell, es, es->buffer->width, es->buffer->height, sx, sy);
@@ -1974,7 +1971,7 @@
 }
 
 struct switcher {
-	struct weston_compositor *compositor;
+	struct wl_shell *shell;
 	struct weston_surface *current;
 	struct wl_listener listener;
 	struct wl_keyboard_grab grab;
@@ -1983,7 +1980,7 @@
 static void
 switcher_next(struct switcher *switcher)
 {
-	struct weston_compositor *compositor = switcher->compositor;
+	struct weston_compositor *compositor = switcher->shell->compositor;
 	struct weston_surface *surface;
 	struct weston_surface *first = NULL, *prev = NULL, *next = NULL;
 	struct shell_surface *shsurf;
@@ -2043,7 +2040,7 @@
 static void
 switcher_destroy(struct switcher *switcher, uint32_t time)
 {
-	struct weston_compositor *compositor = switcher->compositor;
+	struct weston_compositor *compositor = switcher->shell->compositor;
 	struct weston_surface *surface;
 	struct weston_input_device *device =
 		(struct weston_input_device *) switcher->grab.input_device;
@@ -2054,7 +2051,7 @@
 	}
 
 	if (switcher->current)
-		activate(compositor->shell, switcher->current, device);
+		activate(switcher->shell, switcher->current, device);
 	wl_list_remove(&switcher->listener.link);
 	wl_input_device_end_keyboard_grab(&device->input_device);
 	free(switcher);
@@ -2084,11 +2081,11 @@
 		 uint32_t key, uint32_t button, uint32_t axis,
 		 int32_t state, void *data)
 {
-	struct weston_compositor *compositor = data;
+	struct wl_shell *shell = data;
 	struct switcher *switcher;
 
 	switcher = malloc(sizeof *switcher);
-	switcher->compositor = compositor;
+	switcher->shell = shell;
 	switcher->current = NULL;
 	switcher->listener.notify = switcher_handle_surface_destroy;
 	wl_list_init(&switcher->listener.link);
@@ -2136,9 +2133,8 @@
 debug_repaint_binding(struct wl_input_device *device, uint32_t time,
 		      uint32_t key, uint32_t button, uint32_t axis, int32_t state, void *data)
 {
-	struct weston_compositor *compositor = data;
-	struct wl_shell *shell =
-		container_of(compositor->shell, struct wl_shell, shell);
+	struct wl_shell *shell = data;
+	struct weston_compositor *compositor = shell->compositor;
 	struct weston_surface *surface;
 
 	if (shell->debug_repaint_surface) {
@@ -2168,9 +2164,10 @@
 }
 
 static void
-shell_destroy(struct weston_shell *base)
+shell_destroy(struct wl_listener *listener, void *data)
 {
-	struct wl_shell *shell = container_of(base, struct wl_shell, shell);
+	struct wl_shell *shell =
+		container_of(listener, struct wl_shell, destroy_listener);
 
 	if (shell->child.client)
 		wl_client_destroy(shell->child.client);
@@ -2193,9 +2190,13 @@
 
 	memset(shell, 0, sizeof *shell);
 	shell->compositor = ec;
-	shell->shell.lock = lock;
-	shell->shell.unlock = unlock;
-	shell->shell.destroy = shell_destroy;
+
+	shell->destroy_listener.notify = shell_destroy;
+	wl_signal_add(&ec->destroy_signal, &shell->destroy_listener);
+	shell->lock_listener.notify = lock;
+	wl_signal_add(&ec->lock_signal, &shell->lock_listener);
+	shell->unlock_listener.notify = unlock;
+	wl_signal_add(&ec->unlock_signal, &shell->unlock_listener);
 
 	wl_list_init(&shell->backgrounds);
 	wl_list_init(&shell->panels);
@@ -2235,7 +2236,7 @@
 					MODIFIER_CTRL | MODIFIER_ALT,
 					terminate_binding, ec);
 	weston_compositor_add_binding(ec, 0, BTN_LEFT, 0, 0,
-					click_to_activate_binding, ec);
+					click_to_activate_binding, shell);
 	weston_compositor_add_binding(ec, 0, 0, WL_INPUT_DEVICE_AXIS_VERTICAL_SCROLL,
 					MODIFIER_SUPER | MODIFIER_ALT,
 					surface_opacity_binding, NULL);
@@ -2245,7 +2246,7 @@
 					MODIFIER_SUPER | MODIFIER_ALT,
 					rotate_binding, NULL);
 	weston_compositor_add_binding(ec, KEY_TAB, 0, 0, MODIFIER_SUPER,
-					switcher_binding, ec);
+					switcher_binding, shell);
 
 	/* brightness */
 	weston_compositor_add_binding(ec, KEY_F9, 0, 0, MODIFIER_CTRL,
@@ -2258,9 +2259,7 @@
 					backlight_binding, ec);
 
 	weston_compositor_add_binding(ec, KEY_SPACE, 0, 0, MODIFIER_SUPER,
-					debug_repaint_binding, ec);
-
-	ec->shell = &shell->shell;
+					debug_repaint_binding, shell);
 
 	return 0;
 }
diff --git a/src/tablet-shell.c b/src/tablet-shell.c
index 0ec31ea..1ead521 100644
--- a/src/tablet-shell.c
+++ b/src/tablet-shell.c
@@ -46,7 +46,9 @@
 struct tablet_shell {
 	struct wl_resource resource;
 
-	struct weston_shell shell;
+	struct wl_listener lock_listener;
+	struct wl_listener unlock_listener;
+	struct wl_listener destroy_listener;
 
 	struct weston_compositor *compositor;
 	struct weston_process process;
@@ -81,6 +83,21 @@
 };
 
 static void
+tablet_shell_destroy(struct wl_listener *listener, void *data);
+
+static struct tablet_shell *
+get_shell(struct weston_compositor *compositor)
+{
+	struct wl_listener *l;
+
+	l = wl_signal_get(&compositor->destroy_signal, tablet_shell_destroy);
+	if (l)
+		return container_of(l, struct tablet_shell, destroy_listener);
+
+	return NULL;
+}
+
+static void
 tablet_shell_sigchld(struct weston_process *process, int status)
 {
 	struct tablet_shell *shell =
@@ -109,9 +126,7 @@
 tablet_shell_surface_configure(struct weston_surface *surface,
 			       int32_t sx, int32_t sy)
 {
-	struct tablet_shell *shell =
-		container_of(surface->compositor->shell,
-			     struct tablet_shell, shell);
+	struct tablet_shell *shell = get_shell(surface->compositor);
 	int32_t width, height;
 
 	if (weston_surface_is_mapped(surface))
@@ -387,10 +402,10 @@
 }
 
 static void
-tablet_shell_lock(struct weston_shell *base)
+tablet_shell_lock(struct wl_listener *listener, void *data)
 {
 	struct tablet_shell *shell =
-		container_of(base, struct tablet_shell, shell);
+		container_of(listener, struct tablet_shell, lock_listener);
 
 	if (shell->state == STATE_LOCKED)
 		return;
@@ -402,10 +417,10 @@
 }
 
 static void
-tablet_shell_unlock(struct weston_shell *base)
+tablet_shell_unlock(struct wl_listener *listener, void *data)
 {
 	struct tablet_shell *shell =
-		container_of(base, struct tablet_shell, shell);
+		container_of(listener, struct tablet_shell, lock_listener);
 
 	weston_compositor_wake(shell->compositor);
 }
@@ -505,10 +520,10 @@
 }
 
 static void
-tablet_shell_destroy(struct weston_shell *base)
+tablet_shell_destroy(struct wl_listener *listener, void *data)
 {
 	struct tablet_shell *shell =
-		container_of(base, struct tablet_shell, shell);
+		container_of(listener, struct tablet_shell, destroy_listener);
 
 	if (shell->home_surface)
 		shell->home_surface->configure = NULL;
@@ -536,6 +551,13 @@
 	memset(shell, 0, sizeof *shell);
 	shell->compositor = compositor;
 
+	shell->destroy_listener.notify = tablet_shell_destroy;
+	wl_signal_add(&compositor->destroy_signal, &shell->destroy_listener);
+	shell->lock_listener.notify = tablet_shell_lock;
+	wl_signal_add(&compositor->lock_signal, &shell->lock_listener);
+	shell->unlock_listener.notify = tablet_shell_unlock;
+	wl_signal_add(&compositor->unlock_signal, &shell->unlock_listener);
+
 	/* FIXME: This will make the object available to all clients. */
 	wl_display_add_global(compositor->wl_display,
 			      &tablet_shell_interface, shell, bind_shell);
@@ -555,12 +577,6 @@
 	weston_compositor_add_binding(compositor, KEY_COMPOSE, 0, 0, 0,
 				    menu_key_binding, shell);
 
-	compositor->shell = &shell->shell;
-
-	shell->shell.lock = tablet_shell_lock;
-	shell->shell.unlock = tablet_shell_unlock;
-	shell->shell.destroy = tablet_shell_destroy;
-
 	weston_layer_init(&shell->homescreen_layer,
 			  &compositor->cursor_layer.link);
 	weston_layer_init(&shell->lockscreen_layer,
diff --git a/src/xserver-launcher.c b/src/xserver-launcher.c
index 36344ed..7038999 100644
--- a/src/xserver-launcher.c
+++ b/src/xserver-launcher.c
@@ -59,6 +59,8 @@
 	struct wl_client *client;
 	struct weston_compositor *compositor;
 	struct weston_wm *wm;
+	struct wl_listener activate_listener;
+	struct wl_listener destroy_listener;
 };
 
 struct weston_wm {
@@ -555,11 +557,14 @@
 			     XCB_INPUT_FOCUS_POINTER_ROOT, window->id, time);
 }
 
-WL_EXPORT void
-weston_xserver_surface_activate(struct weston_surface *surface)
+static void
+weston_xserver_surface_activate(struct wl_listener *listener, void *data)
 {
+	struct weston_surface *surface = data;
 	struct weston_wm_window *window = get_wm_window(surface);
-	struct weston_xserver *wxs = surface->compositor->wxs;
+	struct weston_xserver *wxs =
+		container_of(listener,
+			     struct weston_xserver, activate_listener);
 
 	if (window)
 		weston_wm_activate(wxs->wm, window, XCB_TIME_CURRENT_TIME);
@@ -1681,6 +1686,21 @@
 	return 0;
 }
 
+static void
+weston_xserver_destroy(struct wl_listener *l, void *data)
+{
+	struct weston_xserver *wxs =
+		container_of(l, struct weston_xserver, destroy_listener);
+
+	if (!wxs)
+		return;
+
+	if (wxs->loop)
+		weston_xserver_shutdown(wxs);
+
+	free(wxs);
+}
+
 int
 weston_xserver_init(struct weston_compositor *compositor)
 {
@@ -1741,21 +1761,12 @@
 
 	wl_display_add_global(display, &xserver_interface, mxs, bind_xserver);
 
-	compositor->wxs = mxs;
+	mxs->destroy_listener.notify = weston_xserver_destroy;
+	wl_signal_add(&compositor->destroy_signal, &mxs->destroy_listener);
+
+
+	mxs->activate_listener.notify = weston_xserver_surface_activate;
+	wl_signal_add(&compositor->activate_signal, &mxs->activate_listener);
 
 	return 0;
 }
-
-void
-weston_xserver_destroy(struct weston_compositor *compositor)
-{
-	struct weston_xserver *wxs = compositor->wxs;
-
-	if (!wxs)
-		return;
-
-	if (wxs->loop)
-		weston_xserver_shutdown(wxs);
-
-	free(wxs);
-}