compositor: Make all exported objects wl_resources
diff --git a/compositor/compositor.c b/compositor/compositor.c
index 34bd366..9c01468 100644
--- a/compositor/compositor.c
+++ b/compositor/compositor.c
@@ -241,7 +241,7 @@
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
-	surface->surface.client = NULL;
+	surface->surface.resource.client = NULL;
 
 	surface->compositor = compositor;
 	surface->visual = NULL;
@@ -339,7 +339,7 @@
 }
 
 static void
-destroy_surface(struct wl_resource *resource, struct wl_client *client)
+destroy_surface(struct wl_resource *resource)
 {
 	struct wlsc_surface *surface =
 		container_of(resource, struct wlsc_surface, surface.resource);
@@ -704,10 +704,8 @@
 	if (buffer == NULL || --buffer->busy_count > 0)
 		return;
 
-	assert(buffer->client != NULL);
-	wl_client_post_event(buffer->client,
-			     &buffer->resource.object,
-			     WL_BUFFER_RELEASE);
+	assert(buffer->resource.client != NULL);
+	wl_resource_post_event(&buffer->resource, WL_BUFFER_RELEASE);
 }
 
 WL_EXPORT void
@@ -899,7 +897,6 @@
 
 struct wlsc_frame_callback {
 	struct wl_resource resource;
-	struct wl_client *client;
 	struct wl_list link;
 };
 
@@ -917,11 +914,9 @@
 	output->present(output);
 
 	wl_list_for_each_safe(cb, cnext, &output->frame_callback_list, link) {
-		wl_client_post_event(cb->client, &cb->resource.object, 
-				     WL_CALLBACK_DONE, msecs);
-		wl_resource_destroy(&cb->resource, cb->client, 0);
+		wl_resource_post_event(&cb->resource, WL_CALLBACK_DONE, msecs);
+		wl_resource_destroy(&cb->resource, 0);
 	}
-	wl_list_init(&output->frame_callback_list);
 
 	wl_list_for_each_safe(animation, next,
 			      &compositor->animation_list, link)
@@ -986,11 +981,9 @@
 }
 
 static void
-surface_destroy(struct wl_client *client,
-		struct wl_surface *surface)
+surface_destroy(struct wl_client *client, struct wl_resource *resource)
 {
-	wl_resource_destroy(&surface->resource, client,
-			    wlsc_compositor_get_time());
+	wl_resource_destroy(resource, wlsc_compositor_get_time());
 }
 
 WL_EXPORT void
@@ -1020,10 +1013,10 @@
 
 static void
 surface_attach(struct wl_client *client,
-	       struct wl_surface *surface, struct wl_buffer *buffer,
+	       struct wl_resource *resource, struct wl_buffer *buffer,
 	       int32_t x, int32_t y)
 {
-	struct wlsc_surface *es = (struct wlsc_surface *) surface;
+	struct wlsc_surface *es = resource->data;
 
 	buffer->busy_count++;
 	wlsc_buffer_post_release(es->buffer);
@@ -1042,33 +1035,36 @@
 		wlsc_surface_configure(es, es->x + x, es->y + y,
 				       buffer->width, buffer->height);
 
-	wlsc_buffer_attach(buffer, surface);
+	wlsc_buffer_attach(buffer, &es->surface);
 
 	es->compositor->shell->attach(es->compositor->shell, es);
 }
 
 static void
 surface_damage(struct wl_client *client,
-	       struct wl_surface *surface,
+	       struct wl_resource *resource,
 	       int32_t x, int32_t y, int32_t width, int32_t height)
 {
-	struct wlsc_surface *es = (struct wlsc_surface *) surface;
+	struct wlsc_surface *es = resource->data;
 
 	wlsc_surface_damage_rectangle(es, x, y, width, height);
 }
 
 static void
-destroy_frame_callback(struct wl_resource *resource, struct wl_client *client)
+destroy_frame_callback(struct wl_resource *resource)
 {
+	struct wlsc_frame_callback *cb = resource->data;
+
+	wl_list_remove(&cb->link);
 	free(resource);
 }
 
 static void
 surface_frame(struct wl_client *client,
-	      struct wl_surface *surface, uint32_t callback)
+	      struct wl_resource *resource, uint32_t callback)
 {
 	struct wlsc_frame_callback *cb;
-	struct wlsc_surface *es = (struct wlsc_surface *) surface;
+	struct wlsc_surface *es = resource->data;
 
 	cb = malloc(sizeof *cb);
 	if (cb == NULL) {
@@ -1079,8 +1075,9 @@
 	cb->resource.object.interface = &wl_callback_interface;
 	cb->resource.object.id = callback;
 	cb->resource.destroy = destroy_frame_callback;
+	cb->resource.client = client;
+	cb->resource.data = cb;
 	wl_list_insert(es->output->frame_callback_list.prev, &cb->link);
-	cb->client = client;
 
 	wl_client_add_resource(client, &cb->resource);
 }
@@ -1140,9 +1137,9 @@
 
 static void
 compositor_create_surface(struct wl_client *client,
-			  struct wl_compositor *compositor, uint32_t id)
+			  struct wl_resource *resource, uint32_t id)
 {
-	struct wlsc_compositor *ec = (struct wlsc_compositor *) compositor;
+	struct wlsc_compositor *ec = resource->data;
 	struct wlsc_surface *surface;
 
 	surface = wlsc_surface_create(ec, 0, 0, 0, 0);
@@ -1157,7 +1154,7 @@
 	surface->surface.resource.object.interface = &wl_surface_interface;
 	surface->surface.resource.object.implementation =
 		(void (**)(void)) &surface_interface;
-	surface->surface.client = client;
+	surface->surface.resource.data = surface;
 
 	wl_client_add_resource(client, &surface->surface.resource);
 }
@@ -1182,7 +1179,7 @@
 	struct wlsc_surface *es;
 
 	wl_list_for_each(es, &ec->surface_list, link) {
-		if (es->surface.client == NULL)
+		if (es->surface.resource.client == NULL)
 			continue;
 		wlsc_surface_transform(es, device->x, device->y, sx, sy);
 		if (0 <= *sx && *sx < es->width &&
@@ -1203,22 +1200,26 @@
 	struct wlsc_surface *es =
 		(struct wlsc_surface *) device->input_device.pointer_focus;
 	int32_t sx, sy;
+	struct wl_resource *resource;
 
-	wlsc_surface_transform(es, x, y, &sx, &sy);
-	wl_client_post_event(es->surface.client,
-			     &device->input_device.object,
-			     WL_INPUT_DEVICE_MOTION,
-			     time, x, y, sx, sy);
+	resource = grab->input_device->pointer_focus_resource;
+	if (resource) {
+		wlsc_surface_transform(es, x, y, &sx, &sy);
+		wl_resource_post_event(resource, WL_INPUT_DEVICE_MOTION,
+				       time, x, y, sx, sy);
+	}
 }
 
 static void
 motion_grab_button(struct wl_grab *grab,
 		   uint32_t time, int32_t button, int32_t state)
 {
-	wl_client_post_event(grab->input_device->pointer_focus->client,
-			     &grab->input_device->object,
-			     WL_INPUT_DEVICE_BUTTON,
-			     time, button, state);
+	struct wl_resource *resource;
+
+	resource = grab->input_device->pointer_focus_resource;
+	if (resource)
+		wl_resource_post_event(resource, WL_INPUT_DEVICE_BUTTON,
+				       time, button, state);
 }
 
 static void
@@ -1330,11 +1331,10 @@
 		wl_input_device_set_pointer_focus(device,
 						  &es->surface,
 						  time, x, y, sx, sy);
-		if (es)
-			wl_client_post_event(es->surface.client,
-					     &device->object,
-					     WL_INPUT_DEVICE_MOTION,
-					     time, x, y, sx, sy);
+		if (device->pointer_focus_resource)
+			wl_resource_post_event(device->pointer_focus_resource,
+					       WL_INPUT_DEVICE_MOTION,
+					       time, x, y, sx, sy);
 	}
 
 	wlsc_surface_damage_below(wd->sprite);
@@ -1518,10 +1518,9 @@
 		*k = key;
 	}
 
-	if (device->keyboard_focus != NULL)
-		wl_client_post_event(device->keyboard_focus->client,
-				     &device->object,
-				     WL_INPUT_DEVICE_KEY, time, key, state);
+	if (device->keyboard_focus_resource)
+		wl_resource_post_event(device->keyboard_focus_resource,
+				       WL_INPUT_DEVICE_KEY, time, key, state);
 }
 
 WL_EXPORT void
@@ -1583,7 +1582,7 @@
 			update_modifier_state(wd, *k, 1);
 		}
 
-		if (es->surface.client)
+		if (es->surface.resource.client)
 			wl_input_device_set_keyboard_focus(&wd->input_device,
 							   &es->surface, time);
 	} else {
@@ -1600,18 +1599,17 @@
 
 static void
 input_device_attach(struct wl_client *client,
-		    struct wl_input_device *device_base,
+		    struct wl_resource *resource,
 		    uint32_t time,
 		    struct wl_buffer *buffer, int32_t x, int32_t y)
 {
-	struct wlsc_input_device *device =
-		(struct wlsc_input_device *) device_base;
+	struct wlsc_input_device *device = resource->data;
 
 	if (time < device->input_device.pointer_focus_time)
 		return;
 	if (device->input_device.pointer_focus == NULL)
 		return;
-	if (device->input_device.pointer_focus->client != client)
+	if (device->input_device.pointer_focus->resource.client != client)
 		return;
 
 	if (buffer == NULL) {
@@ -1633,11 +1631,14 @@
 {
 	wl_input_device_init(&device->input_device, &ec->compositor);
 
-	device->input_device.object.interface = &wl_input_device_interface;
-	device->input_device.object.implementation =
+	device->input_device.resource.object.interface = &wl_input_device_interface;
+	device->input_device.resource.object.implementation =
 		(void (**)(void)) &input_device_interface;
-	wl_display_add_object(ec->wl_display, &device->input_device.object);
-	wl_display_add_global(ec->wl_display, &device->input_device.object, NULL);
+	device->input_device.resource.data = device;
+	wl_display_add_object(ec->wl_display,
+			      &device->input_device.resource.object);
+	wl_display_add_global(ec->wl_display,
+			      &device->input_device.resource.object, NULL);
 
 	device->sprite = wlsc_surface_create(ec,
 					     device->input_device.x,
@@ -1660,23 +1661,26 @@
 			  struct wl_object *global, uint32_t version)
 {
 	struct wlsc_output *output =
-		container_of(global, struct wlsc_output, object);
+		container_of(global, struct wlsc_output, resource.object);
 	struct wlsc_mode *mode;
 
-	wl_client_post_event(client, global,
-			     WL_OUTPUT_GEOMETRY,
-			     output->x,
-			     output->y,
-			     output->mm_width,
-			     output->mm_height,
-			     output->subpixel,
-			     output->make, output->model);
+	output->resource.client = client;
+	wl_resource_post_event(&output->resource,
+			       WL_OUTPUT_GEOMETRY,
+			       output->x,
+			       output->y,
+			       output->mm_width,
+			       output->mm_height,
+			       output->subpixel,
+			       output->make, output->model);
 
 	wl_list_for_each (mode, &output->mode_list, link) {
-		wl_client_post_event(client, global,
-				     WL_OUTPUT_MODE,
-				     mode->flags,
-				     mode->width, mode->height, mode->refresh);
+		wl_resource_post_event(&output->resource,
+				       WL_OUTPUT_MODE,
+				       mode->flags,
+				       mode->width,
+				       mode->height,
+				       mode->refresh);
 	}
 }
 
@@ -1796,7 +1800,7 @@
 {
 	pixman_region32_fini(&output->region);
 	pixman_region32_fini(&output->previous_damage);
-	destroy_surface(&output->background->surface.resource, NULL);
+	destroy_surface(&output->background->surface.resource);
 }
 
 WL_EXPORT void
@@ -1856,9 +1860,9 @@
 	wl_list_init(&output->scanout_buffer_destroy_listener.link);
 	wl_list_init(&output->frame_callback_list);
 
-	output->object.interface = &wl_output_interface;
-	wl_display_add_object(c->wl_display, &output->object);
-	wl_display_add_global(c->wl_display, &output->object,
+	output->resource.object.interface = &wl_output_interface;
+	wl_display_add_object(c->wl_display, &output->resource.object);
+	wl_display_add_global(c->wl_display, &output->resource.object,
 			      wlsc_output_post_geometry);
 }
 
diff --git a/compositor/compositor.h b/compositor/compositor.h
index 5896463..38e3583 100644
--- a/compositor/compositor.h
+++ b/compositor/compositor.h
@@ -61,7 +61,7 @@
 };
 
 struct wlsc_output {
-	struct wl_object object;
+	struct wl_resource resource;
 	struct wl_list link;
 	struct wlsc_compositor *compositor;
 	struct wlsc_surface *background;
diff --git a/compositor/meego-tablet-shell.c b/compositor/meego-tablet-shell.c
index 75216f3..8d7dfe0 100644
--- a/compositor/meego-tablet-shell.c
+++ b/compositor/meego-tablet-shell.c
@@ -47,7 +47,7 @@
 };
 
 struct meego_tablet_shell {
-	struct wl_object object;
+	struct wl_resource resource;
 
 	struct wlsc_shell shell;
 
@@ -224,12 +224,12 @@
 		if (shell->state == STATE_STARTING) {
 			meego_tablet_shell_set_state(shell, STATE_LOCKED);
 			shell->previous_state = STATE_HOME;
-			wl_client_post_event(shell->client, &shell->object,
-					     MEEGO_TABLET_SHELL_SHOW_LOCKSCREEN);
+			wl_resource_post_event(&shell->resource,
+					       MEEGO_TABLET_SHELL_SHOW_LOCKSCREEN);
 		}
 	} else if (shell->current_client &&
 		   shell->current_client->surface != surface &&
-		   shell->current_client->client == surface->surface.client) {
+		   shell->current_client->client == surface->surface.resource.client) {
 		meego_tablet_shell_set_state(shell, STATE_TASK);
 		shell->current_client->surface = surface;
 		meego_tablet_zoom_run(shell, surface, 0.3, 1.0);
@@ -250,9 +250,10 @@
 
 static void
 tablet_shell_set_lockscreen(struct wl_client *client,
-			    struct meego_tablet_shell *shell,
+			    struct wl_resource *resource,
 			    struct wl_surface *surface)
 {
+	struct meego_tablet_shell *shell = resource->data;
 	struct wlsc_surface *es = (struct wlsc_surface *) surface;
 	struct wlsc_input_device *device =
 		(struct wlsc_input_device *) shell->compositor->input_device;
@@ -282,9 +283,10 @@
 
 static void
 tablet_shell_set_switcher(struct wl_client *client,
-			  struct meego_tablet_shell *shell,
+			  struct wl_resource *resource,
 			  struct wl_surface *surface)
 {
+	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;
@@ -306,9 +308,10 @@
 
 static void
 tablet_shell_set_homescreen(struct wl_client *client,
-			    struct meego_tablet_shell *shell,
+			    struct wl_resource *resource,
 			    struct wl_surface *surface)
 {
+	struct meego_tablet_shell *shell = resource->data;
 	struct wlsc_input_device *device =
 		(struct wlsc_input_device *) shell->compositor->input_device;
 
@@ -366,22 +369,26 @@
 
 static void
 tablet_shell_show_grid(struct wl_client *client,
-		       struct meego_tablet_shell *shell,
+		       struct wl_resource *resource,
 		       struct wl_surface *surface)
 {
+	struct meego_tablet_shell *shell = resource->data;
+
 	meego_tablet_shell_switch_to(shell, (struct wlsc_surface *) surface);
 }
 
 static void
 tablet_shell_show_panels(struct wl_client *client,
-			 struct meego_tablet_shell *shell,
+			 struct wl_resource *resource,
 			 struct wl_surface *surface)
 {
+	struct meego_tablet_shell *shell = resource->data;
+
 	meego_tablet_shell_switch_to(shell, (struct wlsc_surface *) surface);
 }
 
 static void
-destroy_tablet_client(struct wl_resource *resource, struct wl_client *client)
+destroy_tablet_client(struct wl_resource *resource)
 {
 	struct meego_tablet_client *tablet_client =
 		container_of(resource, struct meego_tablet_client, resource);
@@ -391,17 +398,15 @@
 }
 
 static void
-tablet_client_destroy(struct wl_client *client,
-		      struct meego_tablet_client *tablet_client)
+tablet_client_destroy(struct wl_client *client, struct wl_resource *resource)
 {
-	wl_resource_destroy(&tablet_client->resource,
-			    client, wlsc_compositor_get_time());
+	wl_resource_destroy(resource, wlsc_compositor_get_time());
 }
 
 static void
-tablet_client_activate(struct wl_client *client,
-		       struct meego_tablet_client *tablet_client)
+tablet_client_activate(struct wl_client *client, struct wl_resource *resource)
 {
+	struct meego_tablet_client *tablet_client = resource->data;
 	struct meego_tablet_shell *shell = tablet_client->shell;
 
 	shell->current_client = tablet_client;
@@ -418,9 +423,10 @@
 
 static void
 tablet_shell_create_client(struct wl_client *client,
-			   struct meego_tablet_shell *shell,
+			   struct wl_resource *resource,
 			   uint32_t id, const char *name, int fd)
 {
+	struct meego_tablet_shell *shell = resource->data;
 	struct wlsc_compositor *compositor = shell->compositor;
 	struct meego_tablet_client *tablet_client;
 
@@ -508,12 +514,12 @@
 {
 	switch (shell->state) {
 	case STATE_SWITCHER:
-		wl_client_post_event(shell->client, &shell->object,
+		wl_resource_post_event(&shell->resource,
 				     MEEGO_TABLET_SHELL_HIDE_SWITCHER);
 		break;
 	default:
-		wl_client_post_event(shell->client, &shell->object,
-				     MEEGO_TABLET_SHELL_SHOW_SWITCHER);
+		wl_resource_post_event(&shell->resource,
+				       MEEGO_TABLET_SHELL_SHOW_SWITCHER);
 		meego_tablet_shell_set_state(shell, STATE_SWITCHER);
 		break;
 	}
@@ -528,11 +534,11 @@
 	if (shell->state == STATE_LOCKED)
 		return;
 	if (shell->state == STATE_SWITCHER)
-		wl_client_post_event(shell->client, &shell->object,
-				     MEEGO_TABLET_SHELL_HIDE_SWITCHER);
+		wl_resource_post_event(&shell->resource,
+				       MEEGO_TABLET_SHELL_HIDE_SWITCHER);
 
-	wl_client_post_event(shell->client, &shell->object,
-			     MEEGO_TABLET_SHELL_SHOW_LOCKSCREEN);
+	wl_resource_post_event(&shell->resource,
+			       MEEGO_TABLET_SHELL_SHOW_LOCKSCREEN);
 	
 	meego_tablet_shell_set_state(shell, STATE_LOCKED);
 }
@@ -544,8 +550,8 @@
 		(struct wlsc_input_device *) shell->compositor->input_device;
 
 	if (shell->state == STATE_SWITCHER)
-		wl_client_post_event(shell->client, &shell->object,
-				     MEEGO_TABLET_SHELL_HIDE_SWITCHER);
+		wl_resource_post_event(&shell->resource,
+				       MEEGO_TABLET_SHELL_HIDE_SWITCHER);
 
 	wlsc_surface_activate(shell->home_surface, device,
 			      wlsc_compositor_get_time());
@@ -615,6 +621,22 @@
 {
 }
 
+static void
+bind_shell(struct wl_client *client,
+	   struct wl_object *global, uint32_t version)
+{
+	struct meego_tablet_shell *shell =
+		container_of(global,
+			     struct meego_tablet_shell, resource.object);
+
+	if (shell->client != client)
+		/* Throw an error or just let the client fail when it
+		 * tries to access the object?. */
+		return;
+
+	shell->resource.client = client;
+}
+
 void
 shell_init(struct wlsc_compositor *compositor);
 
@@ -631,13 +653,14 @@
 	memset(shell, 0, sizeof *shell);
 	shell->compositor = compositor;
 
-	shell->object.interface = &meego_tablet_shell_interface;
-	shell->object.implementation =
+	shell->resource.object.interface = &meego_tablet_shell_interface;
+	shell->resource.object.implementation =
 		(void (**)(void)) &tablet_shell_interface;
-	wl_display_add_object(compositor->wl_display, &shell->object);
+	wl_display_add_object(compositor->wl_display, &shell->resource.object);
 
 	/* FIXME: This will make the object available to all clients. */
-	wl_display_add_global(compositor->wl_display, &shell->object, NULL);
+	wl_display_add_global(compositor->wl_display,
+			      &shell->resource.object, 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 4d7660d..2cf1be6 100644
--- a/compositor/screenshooter.c
+++ b/compositor/screenshooter.c
@@ -28,7 +28,7 @@
 
 static void
 screenshooter_shoot(struct wl_client *client,
-		    struct screenshooter *shooter,
+		    struct wl_resource *resource,
 		    struct wl_output *output_base, struct wl_buffer *buffer)
 {
 	struct wlsc_output *output = (struct wlsc_output *) output_base;
diff --git a/compositor/shell.c b/compositor/shell.c
index 91af256..251d17a 100644
--- a/compositor/shell.c
+++ b/compositor/shell.c
@@ -77,7 +77,7 @@
 };
 
 static void
-shell_move(struct wl_client *client, struct wl_shell *shell,
+shell_move(struct wl_client *client, struct wl_resource *resource,
 	   struct wl_surface *surface,
 	   struct wl_input_device *device, uint32_t time)
 {
@@ -112,6 +112,7 @@
 	int32_t dx, dy, width, height;
 	struct wlsc_surface *surface;
 	struct wl_shell *shell;
+	struct wl_resource resource;
 };
 
 static void
@@ -139,9 +140,9 @@
 		height = resize->height;
 	}
 
-	wl_client_post_event(surface->client, &resize->shell->object,
-			     WL_SHELL_CONFIGURE, time, resize->edges,
-			     surface, width, height);
+	wl_resource_post_event(&resize->resource,
+			       WL_SHELL_CONFIGURE, time, resize->edges,
+			       surface, width, height);
 }
 
 static void
@@ -171,10 +172,11 @@
 };
 
 static void
-shell_resize(struct wl_client *client, struct wl_shell *shell,
+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)
 {
+	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;
@@ -197,6 +199,9 @@
 	resize->surface = es;
 	resize->shell = shell;
 
+	resize->resource.object = resource->object;
+	resize->resource.client = client;
+
 	if (edges == 0 || edges > 15 ||
 	    (edges & 3) == 3 || (edges & 12) == 12)
 		return;
@@ -238,7 +243,7 @@
 
 static void
 shell_set_toplevel(struct wl_client *client,
-		   struct wl_shell *wl_shell,
+		   struct wl_resource *resource,
 		   struct wl_surface *surface)
 
 {
@@ -263,7 +268,7 @@
 
 static void
 shell_set_transient(struct wl_client *client,
-		    struct wl_shell *wl_shell,
+		    struct wl_resource *resource,
 		    struct wl_surface *surface,
 		    struct wl_surface *parent,
 		    int x, int y, uint32_t flags)
@@ -283,7 +288,7 @@
 
 static void
 shell_set_fullscreen(struct wl_client *client,
-		     struct wl_shell *wl_shell,
+		     struct wl_resource *resource,
 		     struct wl_surface *surface)
 
 {
@@ -306,7 +311,7 @@
 }
 
 static void
-destroy_drag(struct wl_resource *resource, struct wl_client *client)
+destroy_drag(struct wl_resource *resource)
 {
 	struct wl_drag *drag =
 		container_of(resource, struct wl_drag, resource);
@@ -331,31 +336,30 @@
 		return;
 
 	if (drag->drag_focus &&
-	    (!surface || drag->drag_focus->client != surface->client))
-		wl_client_post_event(drag->drag_focus->client,
-				      &drag->drag_offer.object,
+	    (!surface ||
+	     drag->drag_focus->resource.client != surface->resource.client))
+		wl_resource_post_event(&drag->drag_offer.resource,
 				      WL_DRAG_OFFER_POINTER_FOCUS,
 				      time, NULL, 0, 0, 0, 0);
 
 	if (surface &&
 	    (!drag->drag_focus ||
-	     drag->drag_focus->client != surface->client)) {
-		wl_client_post_global(surface->client,
-				      &drag->drag_offer.object);
-
+	     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;
 		for (p = drag->types.data; p < end; p++)
-			wl_client_post_event(surface->client,
-					      &drag->drag_offer.object,
-					      WL_DRAG_OFFER_OFFER, *p);
+			wl_resource_post_event(&drag->drag_offer.resource,
+					       WL_DRAG_OFFER_OFFER, *p);
 	}
 
 	if (surface) {
-		wl_client_post_event(surface->client,
-				     &drag->drag_offer.object,
-				     WL_DRAG_OFFER_POINTER_FOCUS,
-				     time, surface,
-				     x, y, sx, sy);
+		wl_resource_post_event(&drag->drag_offer.resource,
+				       WL_DRAG_OFFER_POINTER_FOCUS,
+				       time, surface,
+				       x, y, sx, sy);
 
 	}
 
@@ -370,9 +374,10 @@
 }
 
 static void
-drag_offer_accept(struct wl_client *client,
-		  struct wl_drag_offer *offer, uint32_t time, const char *type)
+drag_offer_accept(struct wl_client *client, struct wl_resource *resource,
+		  uint32_t time, const char *type)
 {
+	struct wl_drag_offer *offer = resource->data;
 	struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
 	char **p, **end;
 
@@ -391,28 +396,27 @@
 		if (type && strcmp(*p, type) == 0)
 			drag->type = *p;
 
-	wl_client_post_event(drag->source->client, &drag->resource.object,
-			     WL_DRAG_TARGET, drag->type);
+	wl_resource_post_event(&drag->resource, WL_DRAG_TARGET, drag->type);
 }
 
 static void
 drag_offer_receive(struct wl_client *client,
-		   struct wl_drag_offer *offer, int fd)
+		   struct wl_resource *resource, int fd)
 {
+	struct wl_drag_offer *offer = resource->data;
 	struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
 
-	wl_client_post_event(drag->source->client, &drag->resource.object,
-			     WL_DRAG_FINISH, fd);
+	wl_resource_post_event(&drag->resource, WL_DRAG_FINISH, fd);
 	close(fd);
 }
 
 static void
-drag_offer_reject(struct wl_client *client, struct wl_drag_offer *offer)
+drag_offer_reject(struct wl_client *client, struct wl_resource *resource)
 {
+	struct wl_drag_offer *offer = resource->data;
 	struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
 
-	wl_client_post_event(drag->source->client, &drag->resource.object,
-			     WL_DRAG_REJECT);
+	wl_resource_post_event(&drag->resource, WL_DRAG_REJECT);
 }
 
 static const struct wl_drag_offer_interface drag_offer_interface = {
@@ -422,8 +426,10 @@
 };
 
 static void
-drag_offer(struct wl_client *client, struct wl_drag *drag, const char *type)
+drag_offer(struct wl_client *client,
+	   struct wl_resource *resource, const char *type)
 {
+	struct wl_drag *drag = resource->data;
 	char **p;
 
 	p = wl_array_add(&drag->types, sizeof *p);
@@ -444,10 +450,9 @@
 	es = pick_surface(grab->input_device, &sx, &sy);
 	wl_drag_set_pointer_focus(drag, &es->surface, time, x, y, sx, sy);
 	if (es)
-		wl_client_post_event(es->surface.client,
-				     &drag->drag_offer.object,
-				     WL_DRAG_OFFER_MOTION,
-				     time, x, y, sx, sy);
+		wl_resource_post_event(&drag->drag_offer.resource,
+				       WL_DRAG_OFFER_MOTION,
+				       time, x, y, sx, sy);
 }
 
 static void
@@ -465,9 +470,8 @@
 	int32_t sx, sy;
 
 	if (drag->target)
-		wl_client_post_event(drag->target,
-				     &drag->drag_offer.object,
-				     WL_DRAG_OFFER_DROP);
+		wl_resource_post_event(&drag->drag_offer.resource,
+				       WL_DRAG_OFFER_DROP);
 
 	wl_drag_set_pointer_focus(drag, NULL, time, 0, 0, 0, 0);
 
@@ -485,10 +489,11 @@
 
 static void
 drag_activate(struct wl_client *client,
-	      struct wl_drag *drag,
+	      struct wl_resource *resource,
 	      struct wl_surface *surface,
 	      struct wl_input_device *device, uint32_t time)
 {
+	struct wl_drag *drag = resource->data;
 	struct wl_display *display = wl_client_get_display (client);
 	struct wlsc_surface *target;
 	int32_t sx, sy;
@@ -501,11 +506,11 @@
 
 	drag->source = surface;
 
-	drag->drag_offer.object.interface = &wl_drag_offer_interface;
-	drag->drag_offer.object.implementation =
+	drag->drag_offer.resource.object.interface = &wl_drag_offer_interface;
+	drag->drag_offer.resource.object.implementation =
 		(void (**)(void)) &drag_offer_interface;
 
-	wl_display_add_object(display, &drag->drag_offer.object);
+	wl_display_add_object(display, &drag->drag_offer.resource.object);
 
 	target = pick_surface(device, &sx, &sy);
 	wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0);
@@ -514,10 +519,9 @@
 }
 
 static void
-drag_destroy(struct wl_client *client, struct wl_drag *drag)
+drag_destroy(struct wl_client *client, struct wl_resource *resource)
 {
-	wl_resource_destroy(&drag->resource, client,
-			    wlsc_compositor_get_time());
+	wl_resource_destroy(resource, wlsc_compositor_get_time());
 }
 
 static const struct wl_drag_interface drag_interface = {
@@ -540,7 +544,7 @@
 
 static void
 shell_create_drag(struct wl_client *client,
-		  struct wl_shell *shell, uint32_t id)
+		  struct wl_resource *resource, uint32_t id)
 {
 	struct wl_drag *drag;
 
@@ -575,29 +579,27 @@
 		return;
 
 	if (selection->selection_focus != NULL)
-		wl_client_post_event(selection->selection_focus->client,
-				     &selection->selection_offer.object,
+		wl_resource_post_event(&selection->selection_offer.resource,
 				     WL_SELECTION_OFFER_KEYBOARD_FOCUS,
 				     NULL);
 
 	if (surface) {
-		wl_client_post_global(surface->client,
-				      &selection->selection_offer.object);
+		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;
 		for (p = selection->types.data; p < end; p++)
-			wl_client_post_event(surface->client,
-					     &selection->selection_offer.object,
-					     WL_SELECTION_OFFER_OFFER, *p);
+			wl_resource_post_event(&selection->selection_offer.resource,
+					       WL_SELECTION_OFFER_OFFER, *p);
 
 		wl_list_remove(&selection->selection_focus_listener.link);
 		wl_list_insert(surface->resource.destroy_listener_list.prev,
 			       &selection->selection_focus_listener.link);
 
-		wl_client_post_event(surface->client,
-				     &selection->selection_offer.object,
-				     WL_SELECTION_OFFER_KEYBOARD_FOCUS,
-				     selection->input_device);
+		wl_resource_post_event(&selection->selection_offer.resource,
+				       WL_SELECTION_OFFER_KEYBOARD_FOCUS,
+				       selection->input_device);
 	}
 
 	selection->selection_focus = surface;
@@ -610,15 +612,15 @@
 
 static void
 selection_offer_receive(struct wl_client *client,
-			struct wl_selection_offer *offer,
+			struct wl_resource *resource,
 			const char *mime_type, int fd)
 {
+	struct wl_selection_offer *offer = resource->data;
 	struct wl_selection *selection =
 		container_of(offer, struct wl_selection, selection_offer);
 
-	wl_client_post_event(selection->client,
-			     &selection->resource.object,
-			     WL_SELECTION_SEND, mime_type, fd);
+	wl_resource_post_event(&selection->resource,
+			       WL_SELECTION_SEND, mime_type, fd);
 	close(fd);
 }
 
@@ -628,8 +630,9 @@
 
 static void
 selection_offer(struct wl_client *client,
-		struct wl_selection *selection, const char *type)
+		struct wl_resource *resource, const char *type)
 {
+	struct wl_selection *selection = resource->data;
 	char **p;
 
 	p = wl_array_add(&selection->types, sizeof *p);
@@ -641,9 +644,10 @@
 
 static void
 selection_activate(struct wl_client *client,
-		   struct wl_selection *selection,
+		   struct wl_resource *resource,
 		   struct wl_input_device *device, uint32_t time)
 {
+	struct wl_selection *selection = resource->data;
 	struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
 	struct wl_display *display = wl_client_get_display (client);
 	struct wlsc_compositor *compositor =
@@ -651,17 +655,17 @@
 
 	selection->input_device = device;
 
-	selection->selection_offer.object.interface =
+	selection->selection_offer.resource.object.interface =
 		&wl_selection_offer_interface;
-	selection->selection_offer.object.implementation =
+	selection->selection_offer.resource.object.implementation =
 		(void (**)(void)) &selection_offer_interface;
 
-	wl_display_add_object(display, &selection->selection_offer.object);
+	wl_display_add_object(display,
+			      &selection->selection_offer.resource.object);
 
 	if (wd->selection) {
-		wl_client_post_event(wd->selection->client,
-				     &wd->selection->resource.object,
-				     WL_SELECTION_CANCELLED);
+		wl_resource_post_event(&wd->selection->resource,
+				       WL_SELECTION_CANCELLED);
 	}
 	wd->selection = selection;
 
@@ -670,10 +674,9 @@
 }
 
 static void
-selection_destroy(struct wl_client *client, struct wl_selection *selection)
+selection_destroy(struct wl_client *client, struct wl_resource *resource)
 {
-	wl_resource_destroy(&selection->resource, client,
-			    wlsc_compositor_get_time());
+	wl_resource_destroy(resource, wlsc_compositor_get_time());
 }
 
 static const struct wl_selection_interface selection_interface = {
@@ -683,7 +686,7 @@
 };
 
 static void
-destroy_selection(struct wl_resource *resource, struct wl_client *client)
+destroy_selection(struct wl_resource *resource)
 {
 	struct wl_selection *selection =
 		container_of(resource, struct wl_selection, resource);
@@ -711,7 +714,7 @@
 
 static void
 shell_create_selection(struct wl_client *client,
-		       struct wl_shell *shell, uint32_t id)
+		       struct wl_resource *resource, uint32_t id)
 {
 	struct wl_selection *selection;
 
@@ -752,21 +755,19 @@
 move_binding(struct wl_input_device *device, uint32_t time,
 	     uint32_t key, uint32_t button, uint32_t state, void *data)
 {
-	struct wl_shell *shell = data;
 	struct wlsc_surface *surface =
 		(struct wlsc_surface *) device->pointer_focus;
 
 	if (surface == NULL)
 		return;
 
-	shell_move(NULL, shell, &surface->surface, device, time);
+	shell_move(NULL, NULL, &surface->surface, device, time);
 }
 
 static void
 resize_binding(struct wl_input_device *device, uint32_t time,
 	       uint32_t key, uint32_t button, uint32_t state, void *data)
 {
-	struct wl_shell *shell = data;
 	struct wlsc_surface *surface =
 		(struct wlsc_surface *) device->pointer_focus;
 	uint32_t edges = 0;
@@ -792,7 +793,7 @@
 	else
 		edges |= WL_SHELL_RESIZE_BOTTOM;
 
-	shell_resize(NULL, shell, &surface->surface, device, time, edges);
+	shell_resize(NULL, NULL, &surface->surface, device, time, edges);
 }
 
 static void
diff --git a/compositor/xserver-launcher.c b/compositor/xserver-launcher.c
index 254f7c5..72b02dd 100644
--- a/compositor/xserver-launcher.c
+++ b/compositor/xserver-launcher.c
@@ -49,14 +49,13 @@
  */
 
 struct xserver {
-	struct wl_object object;
+	struct wl_resource resource;
 };
 
 struct wlsc_xserver {
 	struct wl_display *wl_display;
 	struct wl_event_loop *loop;
 	struct wl_event_source *sigchld_source;
-	struct wl_client *client;
 	int abstract_fd;
 	struct wl_event_source *abstract_source;
 	int unix_fd;
@@ -408,10 +407,8 @@
 		return NULL;
 	}
 
-	wl_client_post_event(wxs->client,
-			     &wxs->xserver.object,
-			     XSERVER_CLIENT, sv[1]);
-	wl_client_flush(wxs->client);
+	wl_resource_post_event(&wxs->xserver.resource, XSERVER_CLIENT, sv[1]);
+	wl_client_flush(wxs->xserver.resource.client);
 	close(sv[1]);
 	
 	/* xcb_connect_to_fd takes ownership of the fd. */
@@ -463,15 +460,15 @@
 
 static void
 wlsc_xserver_bind(struct wl_client *client,
-		  struct wl_object *global,
-		  uint32_t version)
+		  struct wl_object *global, uint32_t version)
 {
 	struct wlsc_xserver *wxs =
-		container_of(global, struct wlsc_xserver, xserver.object);
+		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->client)
+	if (client != wxs->xserver.resource.client)
 		return;
 
 	wxs->wm = wlsc_wm_create(wxs);
@@ -479,13 +476,11 @@
 		fprintf(stderr, "failed to create wm\n");
 	}
 
-	wl_client_post_event(wxs->client,
-			     &wxs->xserver.object,
-			     XSERVER_LISTEN_SOCKET, wxs->abstract_fd);
+	wl_resource_post_event(&wxs->xserver.resource,
+			       XSERVER_LISTEN_SOCKET, wxs->abstract_fd);
 
-	wl_client_post_event(wxs->client,
-			     &wxs->xserver.object,
-			     XSERVER_LISTEN_SOCKET, wxs->unix_fd);
+	wl_resource_post_event(&wxs->xserver.resource,
+			       XSERVER_LISTEN_SOCKET, wxs->unix_fd);
 }
 
 static int
@@ -533,7 +528,8 @@
 		fprintf(stderr, "forked X server, pid %d\n", mxs->process.pid);
 
 		close(sv[1]);
-		mxs->client = wl_client_create(mxs->wl_display, sv[0]);
+		mxs->xserver.resource.client =
+			wl_client_create(mxs->wl_display, sv[0]);
 
 		wlsc_watch_process(&mxs->process);
 
@@ -572,6 +568,7 @@
 		container_of(process, struct wlsc_xserver, process);
 
 	mxs->process.pid = 0;
+	mxs->xserver.resource.client = NULL;
 
 	mxs->abstract_source =
 		wl_event_loop_add_fd(mxs->loop, mxs->abstract_fd,
@@ -597,15 +594,14 @@
 }
 
 static void
-xserver_set_window_id(struct wl_client *client, struct xserver *xserver,
+xserver_set_window_id(struct wl_client *client, struct wl_resource *resource,
 		      struct wl_surface *surface, uint32_t id)
 {
-	struct wlsc_xserver *wxs =
-		container_of(xserver, struct wlsc_xserver, xserver);
+	struct wlsc_xserver *wxs = resource->data;
 	struct wlsc_wm *wm = wxs->wm;
 	struct wlsc_wm_window *window;
 
-	if (client != wxs->client)
+	if (client != wxs->xserver.resource.client)
 		return;
 
 	window = wl_hash_table_lookup(wm->window_hash, id);
@@ -798,12 +794,12 @@
 				     WL_EVENT_READABLE,
 				     wlsc_xserver_handle_event, mxs);
 
-	mxs->xserver.object.interface = &xserver_interface;
-	mxs->xserver.object.implementation =
+	mxs->xserver.resource.object.interface = &xserver_interface;
+	mxs->xserver.resource.object.implementation =
 		(void (**)(void)) &xserver_implementation;
-	wl_display_add_object(display, &mxs->xserver.object);
-	wl_display_add_global(display,
-			      &mxs->xserver.object, wlsc_xserver_bind);
+	wl_display_add_object(display, &mxs->xserver.resource.object);
+	wl_display_add_global(display, &mxs->xserver.resource.object,
+			      wlsc_xserver_bind);
 
 	compositor->wxs = mxs;