Pass resources to functions that take object references
diff --git a/compositor/compositor.c b/compositor/compositor.c
index 2cf0f2c..856eb29 100644
--- a/compositor/compositor.c
+++ b/compositor/compositor.c
@@ -1013,10 +1013,11 @@
 
 static void
 surface_attach(struct wl_client *client,
-	       struct wl_resource *resource, struct wl_buffer *buffer,
-	       int32_t x, int32_t y)
+	       struct wl_resource *resource,
+	       struct wl_resource *buffer_resource, int32_t x, int32_t y)
 {
 	struct wlsc_surface *es = resource->data;
+	struct wl_buffer *buffer = buffer_resource->data;
 
 	buffer->busy_count++;
 	wlsc_buffer_post_release(es->buffer);
@@ -1601,9 +1602,10 @@
 input_device_attach(struct wl_client *client,
 		    struct wl_resource *resource,
 		    uint32_t time,
-		    struct wl_buffer *buffer, int32_t x, int32_t y)
+		    struct wl_resource *buffer_resource, int32_t x, int32_t y)
 {
 	struct wlsc_input_device *device = resource->data;
+	struct wl_buffer *buffer = buffer_resource->data;
 
 	if (time < device->input_device.pointer_focus_time)
 		return;
@@ -1625,18 +1627,22 @@
 	input_device_attach,
 };
 
+static void
+bind_input_device(struct wl_client *client,
+		  void *data, uint32_t version, uint32_t id)
+{
+	wl_client_add_object(client, &wl_display_interface,
+			     &input_device_interface, id, data);
+}
+
 WL_EXPORT void
 wlsc_input_device_init(struct wlsc_input_device *device,
 		       struct wlsc_compositor *ec)
 {
 	wl_input_device_init(&device->input_device, &ec->compositor);
 
-	device->input_device.resource.object.interface = &wl_input_device_interface;
-	device->input_device.resource.object.implementation =
-		(void (**)(void)) &input_device_interface;
-	device->input_device.resource.data = device;
-	wl_display_add_global(ec->wl_display,
-			      &device->input_device.resource.object, NULL);
+	wl_display_add_global(ec->wl_display, &wl_input_device_interface,
+			      device, bind_input_device);
 
 	device->sprite = wlsc_surface_create(ec,
 					     device->input_device.x,
@@ -1655,11 +1661,10 @@
 }
 
 static void
-wlsc_output_post_geometry(struct wl_client *client, struct wl_object *global,
-			  uint32_t version, uint32_t id)
+bind_output(struct wl_client *client,
+	    void *data, uint32_t version, uint32_t id)
 {
-	struct wlsc_output *output =
-		container_of(global, struct wlsc_output, resource.object);
+	struct wlsc_output *output = data;
 	struct wlsc_mode *mode;
 
 	output->resource.client = client;
@@ -1860,8 +1865,8 @@
 	wl_list_init(&output->frame_callback_list);
 
 	output->resource.object.interface = &wl_output_interface;
-	wl_display_add_global(c->wl_display, &output->resource.object,
-			      wlsc_output_post_geometry);
+	wl_display_add_global(c->wl_display,
+			      &wl_output_interface, output, bind_output);
 }
 
 static void
diff --git a/compositor/meego-tablet-shell.c b/compositor/meego-tablet-shell.c
index f81abad..6a79704 100644
--- a/compositor/meego-tablet-shell.c
+++ b/compositor/meego-tablet-shell.c
@@ -251,10 +251,10 @@
 static void
 tablet_shell_set_lockscreen(struct wl_client *client,
 			    struct wl_resource *resource,
-			    struct wl_surface *surface)
+			    struct wl_resource *surface_resource)
 {
 	struct meego_tablet_shell *shell = resource->data;
-	struct wlsc_surface *es = (struct wlsc_surface *) surface;
+	struct wlsc_surface *es = surface_resource->data;
 	struct wlsc_input_device *device =
 		(struct wlsc_input_device *) shell->compositor->input_device;
 
@@ -284,12 +284,12 @@
 static void
 tablet_shell_set_switcher(struct wl_client *client,
 			  struct wl_resource *resource,
-			  struct wl_surface *surface)
+			  struct wl_resource *surface_resource)
 {
 	struct meego_tablet_shell *shell = resource->data;
 	struct wlsc_input_device *device =
 		(struct wlsc_input_device *) shell->compositor->input_device;
-	struct wlsc_surface *es = (struct wlsc_surface *) surface;
+	struct wlsc_surface *es = surface_resource->data;
 
 	/* FIXME: Switcher should be centered and the compositor
 	 * should do the tinting of the background.  With the cache
@@ -309,13 +309,13 @@
 static void
 tablet_shell_set_homescreen(struct wl_client *client,
 			    struct wl_resource *resource,
-			    struct wl_surface *surface)
+			    struct wl_resource *surface_resource)
 {
 	struct meego_tablet_shell *shell = resource->data;
 	struct wlsc_input_device *device =
 		(struct wlsc_input_device *) shell->compositor->input_device;
 
-	shell->home_surface = (struct wlsc_surface *) surface;
+	shell->home_surface = surface_resource->data;
 	shell->home_surface->x = 0;
 	shell->home_surface->y = 0;
 
@@ -370,21 +370,23 @@
 static void
 tablet_shell_show_grid(struct wl_client *client,
 		       struct wl_resource *resource,
-		       struct wl_surface *surface)
+		       struct wl_resource *surface_resource)
 {
 	struct meego_tablet_shell *shell = resource->data;
+	struct wlsc_surface *es = surface_resource->data;
 
-	meego_tablet_shell_switch_to(shell, (struct wlsc_surface *) surface);
+	meego_tablet_shell_switch_to(shell, es);
 }
 
 static void
 tablet_shell_show_panels(struct wl_client *client,
 			 struct wl_resource *resource,
-			 struct wl_surface *surface)
+			 struct wl_resource *surface_resource)
 {
 	struct meego_tablet_shell *shell = resource->data;
+	struct wlsc_surface *es = surface_resource->data;
 
-	meego_tablet_shell_switch_to(shell, (struct wlsc_surface *) surface);
+	meego_tablet_shell_switch_to(shell, es);
 }
 
 static void
@@ -398,7 +400,8 @@
 }
 
 static void
-tablet_client_destroy(struct wl_client *client, struct wl_resource *resource)
+tablet_client_destroy(struct wl_client *client,
+		      struct wl_resource *resource)
 {
 	wl_resource_destroy(resource, wlsc_compositor_get_time());
 }
@@ -622,12 +625,9 @@
 }
 
 static void
-bind_shell(struct wl_client *client,
-	   struct wl_object *global, uint32_t version, uint32_t id)
+bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
 {
-	struct meego_tablet_shell *shell =
-		container_of(global,
-			     struct meego_tablet_shell, resource.object);
+	struct meego_tablet_shell *shell = data;
 
 	if (shell->client != client)
 		/* Throw an error or just let the client fail when it
@@ -660,7 +660,7 @@
 
 	/* FIXME: This will make the object available to all clients. */
 	wl_display_add_global(compositor->wl_display,
-			      &shell->resource.object, bind_shell);
+			      &wl_shell_interface, shell, bind_shell);
 
 	loop = wl_display_get_event_loop(compositor->wl_display);
 	shell->long_press_source =
diff --git a/compositor/screenshooter.c b/compositor/screenshooter.c
index 9df13d7..4f6fee9 100644
--- a/compositor/screenshooter.c
+++ b/compositor/screenshooter.c
@@ -29,9 +29,11 @@
 static void
 screenshooter_shoot(struct wl_client *client,
 		    struct wl_resource *resource,
-		    struct wl_output *output_base, struct wl_buffer *buffer)
+		    struct wl_resource *output_resource,
+		    struct wl_resource *buffer_resource)
 {
-	struct wlsc_output *output = (struct wlsc_output *) output_base;
+	struct wlsc_output *output = output_resource->data;
+	struct wl_buffer *buffer = buffer_resource->data;
 
 	if (!wl_buffer_is_shm(buffer))
 		return;
@@ -50,6 +52,14 @@
 	screenshooter_shoot
 };
 
+static void
+bind_shooter(struct wl_client *client,
+	     void *data, uint32_t version, uint32_t id)
+{
+	wl_client_add_object(client, &screenshooter_interface,
+			     &screenshooter_implementation, id, data);
+}
+
 void
 screenshooter_create(struct wlsc_compositor *ec)
 {
@@ -64,5 +74,6 @@
 		(void(**)(void)) &screenshooter_implementation;
 	shooter->ec = ec;
 
-	wl_display_add_global(ec->wl_display, &shooter->base, NULL);
+	wl_display_add_global(ec->wl_display,
+			      &screenshooter_interface, shooter, bind_shooter);
 };
diff --git a/compositor/shell.c b/compositor/shell.c
index 2333ad6..f4942a2 100644
--- a/compositor/shell.c
+++ b/compositor/shell.c
@@ -29,7 +29,6 @@
 #include "compositor.h"
 
 struct wl_shell {
-	struct wl_object object;
 	struct wlsc_shell shell;
 };
 
@@ -76,22 +75,17 @@
 	move_grab_end
 };
 
-static void
-shell_move(struct wl_client *client, struct wl_resource *resource,
-	   struct wl_surface *surface,
-	   struct wl_input_device *device, uint32_t time)
+static int
+wlsc_surface_move(struct wlsc_surface *es,
+		  struct wlsc_input_device *wd, uint32_t time)
 {
-	struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
-	struct wlsc_surface *es = (struct wlsc_surface *) surface;
 	struct wlsc_move_grab *move;
 
 	/* FIXME: Reject if fullscreen */
 
 	move = malloc(sizeof *move);
-	if (!move) {
-		wl_client_post_no_memory(client);
-		return;
-	}
+	if (!move)
+		return -1;
 
 	move->grab.interface = &move_grab_interface;
 	move->dx = es->x - wd->input_device.grab_x;
@@ -99,11 +93,26 @@
 	move->surface = es;
 
 	if (wl_input_device_update_grab(&wd->input_device,
-					&move->grab, surface, time) < 0)
-		return;
+					&move->grab, &es->surface, time) < 0)
+		return 0;
 
 	wlsc_input_device_set_pointer_image(wd, WLSC_POINTER_DRAGGING);
-	wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0);
+	wl_input_device_set_pointer_focus(&wd->input_device,
+					  NULL, time, 0, 0, 0, 0);
+
+	return 0;
+}
+
+static void
+shell_move(struct wl_client *client, struct wl_resource *resource,
+	   struct wl_resource *surface_resource,
+	   struct wl_resource *input_resource, uint32_t time)
+{
+	struct wlsc_input_device *wd = input_resource->data;
+	struct wlsc_surface *es = surface_resource->data;
+
+	if (wlsc_surface_move(es, wd, time) < 0)
+		wl_client_post_no_memory(client);
 }
 
 struct wlsc_resize_grab {
@@ -111,8 +120,7 @@
 	uint32_t edges;
 	int32_t dx, dy, width, height;
 	struct wlsc_surface *surface;
-	struct wl_shell *shell;
-	struct wl_resource resource;
+	struct wl_resource *resource;
 };
 
 static void
@@ -140,7 +148,7 @@
 		height = resize->height;
 	}
 
-	wl_resource_post_event(&resize->resource,
+	wl_resource_post_event(resize->resource,
 			       WL_SHELL_CONFIGURE, time, resize->edges,
 			       surface, width, height);
 }
@@ -171,24 +179,20 @@
 	resize_grab_end
 };
 
-static void
-shell_resize(struct wl_client *client, struct wl_resource *resource,
-	     struct wl_surface *surface,
-	     struct wl_input_device *device, uint32_t time, uint32_t edges)
+static int
+wlsc_surface_resize(struct wlsc_surface *es,
+		    struct wlsc_input_device *wd,
+		    uint32_t time, uint32_t edges,
+		    struct wl_resource *resource)
 {
-	struct wl_shell *shell = resource->data;
-	struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
 	struct wlsc_resize_grab *resize;
 	enum wlsc_pointer_type pointer = WLSC_POINTER_LEFT_PTR;
-	struct wlsc_surface *es = (struct wlsc_surface *) surface;
 
 	/* FIXME: Reject if fullscreen */
 
 	resize = malloc(sizeof *resize);
-	if (!resize) {
-		wl_client_post_no_memory(client);
-		return;
-	}
+	if (!resize)
+		return -1;
 
 	resize->grab.interface = &resize_grab_interface;
 	resize->edges = edges;
@@ -197,14 +201,11 @@
 	resize->width = es->width;
 	resize->height = es->height;
 	resize->surface = es;
-	resize->shell = shell;
-
-	resize->resource.object = resource->object;
-	resize->resource.client = client;
+	resize->resource = resource;
 
 	if (edges == 0 || edges > 15 ||
 	    (edges & 3) == 3 || (edges & 12) == 12)
-		return;
+		return 0;
 
 	switch (edges) {
 	case WL_SHELL_RESIZE_TOP:
@@ -234,20 +235,37 @@
 	}
 
 	if (wl_input_device_update_grab(&wd->input_device,
-					&resize->grab, surface, time) < 0)
-		return;
+					&resize->grab, &es->surface, time) < 0)
+		return 0;
 
 	wlsc_input_device_set_pointer_image(wd, pointer);
-	wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0);
+	wl_input_device_set_pointer_focus(&wd->input_device,
+					  NULL, time, 0, 0, 0, 0);
+
+	return 0;
+}
+
+static void
+shell_resize(struct wl_client *client, struct wl_resource *resource,
+	     struct wl_resource *surface_resource,
+	     struct wl_resource *input_resource, uint32_t time, uint32_t edges)
+{
+	struct wlsc_input_device *wd = input_resource->data;
+	struct wlsc_surface *es = surface_resource->data;
+
+	/* FIXME: Reject if fullscreen */
+
+	if (wlsc_surface_resize(es, wd, time, edges, resource) < 0)
+		wl_client_post_no_memory(client);
 }
 
 static void
 shell_set_toplevel(struct wl_client *client,
 		   struct wl_resource *resource,
-		   struct wl_surface *surface)
+		   struct wl_resource *surface_resource)
 
 {
-	struct wlsc_surface *es = (struct wlsc_surface *) surface;
+	struct wlsc_surface *es = surface_resource->data;
 	struct wlsc_compositor *ec = es->compositor;
 
 	if (es->map_type == WLSC_SURFACE_MAP_FULLSCREEN) {
@@ -269,12 +287,12 @@
 static void
 shell_set_transient(struct wl_client *client,
 		    struct wl_resource *resource,
-		    struct wl_surface *surface,
-		    struct wl_surface *parent,
+		    struct wl_resource *surface_resource,
+		    struct wl_resource *parent_resource,
 		    int x, int y, uint32_t flags)
 {
-	struct wlsc_surface *es = (struct wlsc_surface *) surface;
-	struct wlsc_surface *pes = (struct wlsc_surface *) parent;
+	struct wlsc_surface *es = surface_resource->data;
+	struct wlsc_surface *pes = parent_resource->data;
 
 	/* assign to parents output  */
 	es->output = pes->output;
@@ -289,10 +307,10 @@
 static void
 shell_set_fullscreen(struct wl_client *client,
 		     struct wl_resource *resource,
-		     struct wl_surface *surface)
+		     struct wl_resource *surface_resource)
 
 {
-	struct wlsc_surface *es = (struct wlsc_surface *) surface;
+	struct wlsc_surface *es = surface_resource->data;
 	struct wlsc_output *output;
 
 	/* FIXME: Fullscreen on first output */
@@ -345,8 +363,6 @@
 	if (surface &&
 	    (!drag->drag_focus ||
 	     drag->drag_focus->resource.client != surface->resource.client)) {
-		wl_client_post_global(surface->resource.client,
-				      &drag->drag_offer.resource.object);
 		
 		drag->drag_offer.resource.client = surface->resource.client;
 		end = drag->types.data + drag->types.size;
@@ -490,10 +506,12 @@
 static void
 drag_activate(struct wl_client *client,
 	      struct wl_resource *resource,
-	      struct wl_surface *surface,
-	      struct wl_input_device *device, uint32_t time)
+	      struct wl_resource *surface_resource,
+	      struct wl_resource *device_resource, uint32_t time)
 {
 	struct wl_drag *drag = resource->data;
+	struct wl_surface *surface = surface_resource->data;
+	struct wl_input_device *device = device_resource->data;
 	struct wl_display *display = wl_client_get_display (client);
 	struct wlsc_surface *target;
 	int32_t sx, sy;
@@ -510,8 +528,7 @@
 	drag->drag_offer.resource.object.implementation =
 		(void (**)(void)) &drag_offer_interface;
 
-	wl_display_add_global(display,
-			      &drag->drag_offer.resource.object, NULL);
+	wl_display_add_global(display, &wl_drag_offer_interface, drag, NULL);
 
 	target = pick_surface(device, &sx, &sy);
 	wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0);
@@ -585,8 +602,6 @@
 				     NULL);
 
 	if (surface) {
-		wl_client_post_global(surface->resource.client,
-				      &selection->selection_offer.resource.object);
 
 		selection->selection_offer.resource.client = surface->resource.client;
 		end = selection->types.data + selection->types.size;
@@ -646,15 +661,15 @@
 static void
 selection_activate(struct wl_client *client,
 		   struct wl_resource *resource,
-		   struct wl_input_device *device, uint32_t time)
+		   struct wl_resource *input_resource, uint32_t time)
 {
 	struct wl_selection *selection = resource->data;
-	struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
+	struct wlsc_input_device *wd = input_resource->data;
 	struct wl_display *display = wl_client_get_display (client);
 	struct wlsc_compositor *compositor =
-		(struct wlsc_compositor *) device->compositor;
+		(struct wlsc_compositor *) wd->input_device.compositor;
 
-	selection->input_device = device;
+	selection->input_device = &wd->input_device;
 
 	selection->selection_offer.resource.object.interface =
 		&wl_selection_offer_interface;
@@ -662,8 +677,7 @@
 		(void (**)(void)) &selection_offer_interface;
 
 	wl_display_add_global(display,
-			      &selection->selection_offer.resource.object,
-			      NULL);
+			      &wl_selection_offer_interface, selection, NULL);
 
 	if (wd->selection) {
 		wl_resource_post_event(&wd->selection->resource,
@@ -671,8 +685,8 @@
 	}
 	wd->selection = selection;
 
-	wlsc_selection_set_focus(compositor->shell,
-				 selection, device->keyboard_focus, time);
+	wlsc_selection_set_focus(compositor->shell, selection,
+				 wd->input_device.keyboard_focus, time);
 }
 
 static void
@@ -763,7 +777,7 @@
 	if (surface == NULL)
 		return;
 
-	shell_move(NULL, NULL, &surface->surface, device, time);
+	wlsc_surface_move(surface, (struct wlsc_input_device *) device, time);
 }
 
 static void
@@ -772,6 +786,7 @@
 {
 	struct wlsc_surface *surface =
 		(struct wlsc_surface *) device->pointer_focus;
+	struct wl_resource *resource;
 	uint32_t edges = 0;
 	int32_t x, y;
 
@@ -795,7 +810,12 @@
 	else
 		edges |= WL_SHELL_RESIZE_BOTTOM;
 
-	shell_resize(NULL, NULL, &surface->surface, device, time, edges);
+	resource = /* Find shell resource for surface client */ 0;
+
+	/* ... or use wl_shell_surface */
+
+	wlsc_surface_resize(surface, (struct wlsc_input_device *) device,
+			    time, edges, resource);
 }
 
 static void
@@ -812,6 +832,15 @@
 	}
 }
 
+static void
+bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+	struct wl_shell *shell = data;
+
+	wl_client_add_object(client, &wl_shell_interface,
+			     &shell_interface, id, shell);
+}
+
 int
 shell_init(struct wlsc_compositor *ec);
 
@@ -828,9 +857,8 @@
 	shell->shell.attach = attach;
 	shell->shell.set_selection_focus = wlsc_selection_set_focus;
 
-	shell->object.interface = &wl_shell_interface;
-	shell->object.implementation = (void (**)(void)) &shell_interface;
-	if (wl_display_add_global(ec->wl_display, &shell->object, NULL))
+	if (wl_display_add_global(ec->wl_display, &wl_shell_interface,
+				  shell, bind_shell) == NULL)
 		return -1;
 
 	wlsc_compositor_add_binding(ec, 0, BTN_LEFT, MODIFIER_SUPER,
diff --git a/compositor/xserver-launcher.c b/compositor/xserver-launcher.c
index ba4669d..e0b2ec6 100644
--- a/compositor/xserver-launcher.c
+++ b/compositor/xserver-launcher.c
@@ -62,9 +62,8 @@
 	struct wl_event_source *unix_source;
 	int display;
 	struct wlsc_process process;
-
-	struct xserver xserver;
-
+	struct wl_resource *resource;
+	struct wl_client *client;
 	struct wlsc_wm *wm;
 };
 
@@ -407,8 +406,8 @@
 		return NULL;
 	}
 
-	wl_resource_post_event(&wxs->xserver.resource, XSERVER_CLIENT, sv[1]);
-	wl_client_flush(wxs->xserver.resource.client);
+	wl_resource_post_event(wxs->resource, XSERVER_CLIENT, sv[1]);
+	wl_client_flush(wxs->resource->client);
 	close(sv[1]);
 	
 	/* xcb_connect_to_fd takes ownership of the fd. */
@@ -458,32 +457,6 @@
 	free(wm);
 }
 
-static void
-wlsc_xserver_bind(struct wl_client *client,
-		  struct wl_object *global, uint32_t version, uint32_t id)
-{
-	struct wlsc_xserver *wxs =
-		container_of(global, struct wlsc_xserver,
-			     xserver.resource.object);
-
-	/* If it's a different client than the xserver we launched,
-	 * don't start the wm. */
-	if (client != wxs->xserver.resource.client)
-		return;
-
-	wxs->xserver.resource.object.id = id;
-	wxs->wm = wlsc_wm_create(wxs);
-	if (wxs == NULL) {
-		fprintf(stderr, "failed to create wm\n");
-	}
-
-	wl_resource_post_event(&wxs->xserver.resource,
-			       XSERVER_LISTEN_SOCKET, wxs->abstract_fd);
-
-	wl_resource_post_event(&wxs->xserver.resource,
-			       XSERVER_LISTEN_SOCKET, wxs->unix_fd);
-}
-
 static int
 wlsc_xserver_handle_event(int listen_fd, uint32_t mask, void *data)
 {
@@ -529,8 +502,7 @@
 		fprintf(stderr, "forked X server, pid %d\n", mxs->process.pid);
 
 		close(sv[1]);
-		mxs->xserver.resource.client =
-			wl_client_create(mxs->wl_display, sv[0]);
+		mxs->client = wl_client_create(mxs->wl_display, sv[0]);
 
 		wlsc_watch_process(&mxs->process);
 
@@ -569,7 +541,8 @@
 		container_of(process, struct wlsc_xserver, process);
 
 	mxs->process.pid = 0;
-	mxs->xserver.resource.client = NULL;
+	mxs->client = NULL;
+	mxs->resource = NULL;
 
 	mxs->abstract_source =
 		wl_event_loop_add_fd(mxs->loop, mxs->abstract_fd,
@@ -596,13 +569,14 @@
 
 static void
 xserver_set_window_id(struct wl_client *client, struct wl_resource *resource,
-		      struct wl_surface *surface, uint32_t id)
+		      struct wl_resource *surface_resource, uint32_t id)
 {
 	struct wlsc_xserver *wxs = resource->data;
 	struct wlsc_wm *wm = wxs->wm;
+	struct wl_surface *surface = surface_resource->data;
 	struct wlsc_wm_window *window;
 
-	if (client != wxs->xserver.resource.client)
+	if (client != wxs->client)
 		return;
 
 	window = wl_hash_table_lookup(wm->window_hash, id);
@@ -621,6 +595,33 @@
 	xserver_set_window_id
 };
 
+static void
+bind_xserver(struct wl_client *client,
+	     void *data, uint32_t version, uint32_t id)
+{
+	struct wlsc_xserver *wxs = data;
+
+	/* If it's a different client than the xserver we launched,
+	 * don't start the wm. */
+	if (client != wxs->client)
+		return;
+
+	wxs->resource = 
+		wl_client_add_object(client, &xserver_interface,
+				     &xserver_implementation, id, wxs);
+
+	wxs->wm = wlsc_wm_create(wxs);
+	if (wxs->wm == NULL) {
+		fprintf(stderr, "failed to create wm\n");
+	}
+
+	wl_resource_post_event(wxs->resource,
+			       XSERVER_LISTEN_SOCKET, wxs->abstract_fd);
+
+	wl_resource_post_event(wxs->resource,
+			       XSERVER_LISTEN_SOCKET, wxs->unix_fd);
+}
+
 static int
 bind_to_abstract_socket(int display)
 {
@@ -795,11 +796,7 @@
 				     WL_EVENT_READABLE,
 				     wlsc_xserver_handle_event, mxs);
 
-	mxs->xserver.resource.object.interface = &xserver_interface;
-	mxs->xserver.resource.object.implementation =
-		(void (**)(void)) &xserver_implementation;
-	wl_display_add_global(display, &mxs->xserver.resource.object,
-			      wlsc_xserver_bind);
+	wl_display_add_global(display, &xserver_interface, mxs, bind_xserver);
 
 	compositor->wxs = mxs;