Use wl_resource_create() for creating resources

This commit sets the version numbers for all added/created objects.  The
wl_compositor.create_surface implementation was altered to create a surface
with the same version as the underlying wl_compositor.  Since no other
"child interfaces" have version greater than 1, they were all hard-coded to
version 1.

Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
diff --git a/src/compositor.c b/src/compositor.c
index 30b14fe..8e74dbc 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1489,9 +1489,11 @@
 		return;
 	}
 
-	cb->resource = wl_client_add_object(client, &wl_callback_interface,
-					    NULL, callback, cb);
-	wl_resource_set_destructor(cb->resource, destroy_frame_callback);
+	cb->resource = wl_resource_create(client,
+						      &wl_callback_interface,
+						      1, callback);
+	wl_resource_set_implementation(cb->resource, NULL, cb,
+				       destroy_frame_callback);
 
 	wl_list_insert(surface->pending.frame_callback_list.prev, &cb->link);
 }
@@ -1688,10 +1690,11 @@
 		return;
 	}
 
-	surface->resource = wl_client_add_object(client, &wl_surface_interface,
-						 &surface_interface,
-						 id, surface);
-	wl_resource_set_destructor(surface->resource, destroy_surface);
+	surface->resource =
+		wl_resource_create(client, &wl_surface_interface,
+				   wl_resource_get_version(resource), id);
+	wl_resource_set_implementation(surface->resource, &surface_interface,
+				       surface, destroy_surface);
 }
 
 static void
@@ -1751,9 +1754,10 @@
 
 	pixman_region32_init(&region->region);
 
-	region->resource = wl_client_add_object(client, &wl_region_interface,
-						&region_interface, id, region);
-	wl_resource_set_destructor(region->resource, destroy_region);
+	region->resource =
+		wl_resource_create(client, &wl_region_interface, 1, id);
+	wl_resource_set_implementation(region->resource, &region_interface,
+				       region, destroy_region);
 }
 
 static const struct wl_compositor_interface compositor_interface = {
@@ -2288,16 +2292,16 @@
 	if (!sub)
 		return NULL;
 
-	sub->resource = wl_client_add_object(client,
-					     &wl_subsurface_interface,
-					     &subsurface_implementation,
-					     id, sub);
+	sub->resource =
+		wl_resource_create(client, &wl_subsurface_interface, 1, id);
 	if (!sub->resource) {
 		free(sub);
 		return NULL;
 	}
 
-	wl_resource_set_destructor(sub->resource, subsurface_resource_destroy);
+	wl_resource_set_implementation(sub->resource,
+				       &subsurface_implementation,
+				       sub, subsurface_resource_destroy);
 	weston_subsurface_link_surface(sub, surface);
 	weston_subsurface_link_parent(sub, parent);
 	weston_subsurface_cache_init(sub);
@@ -2408,9 +2412,14 @@
 		   void *data, uint32_t version, uint32_t id)
 {
 	struct weston_compositor *compositor = data;
+	struct wl_resource *resource;
 
-	wl_client_add_object(client, &wl_subcompositor_interface,
-			     &subcompositor_interface, id, compositor);
+	resource =
+		wl_resource_create(client, &wl_subcompositor_interface, 1, id);
+	if (resource)
+		wl_resource_set_implementation(resource,
+					       &subcompositor_interface, 
+					       compositor, NULL);
 }
 
 static void
@@ -2522,11 +2531,11 @@
 	struct weston_mode *mode;
 	struct wl_resource *resource;
 
-	resource = wl_client_add_object(client,
-					&wl_output_interface, NULL, id, data);
+	resource = wl_resource_create(client, &wl_output_interface,
+				      MIN(version, 2), id);
 
 	wl_list_insert(&output->resource_list, wl_resource_get_link(resource));
-	wl_resource_set_destructor(resource, unbind_resource);
+	wl_resource_set_implementation(resource, NULL, data, unbind_resource);
 
 	wl_output_send_geometry(resource,
 				output->x,
@@ -2742,9 +2751,13 @@
 		void *data, uint32_t version, uint32_t id)
 {
 	struct weston_compositor *compositor = data;
+	struct wl_resource *resource;
 
-	wl_client_add_object(client, &wl_compositor_interface,
-			     &compositor_interface, id, compositor);
+	resource = wl_resource_create(client, &wl_compositor_interface,
+				      MIN(version, 3), id);
+	if (resource)
+		wl_resource_set_implementation(resource, &compositor_interface,
+					       compositor, NULL);
 }
 
 static void
diff --git a/src/compositor.h b/src/compositor.h
index 6d2c683..8070409 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -594,7 +594,7 @@
 
 	union {
 		struct wl_shm_buffer *shm_buffer;
-		struct wl_buffer *legacy_buffer;
+		void *legacy_buffer;
 	};
 	int32_t width, height;
 	uint32_t busy_count;
diff --git a/src/data-device.c b/src/data-device.c
index 5627884..205fe79 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -117,10 +117,11 @@
 	if (offer == NULL)
 		return NULL;
 
-	offer->resource = wl_client_new_object(wl_resource_get_client(target),
-					       &wl_data_offer_interface,
-					       &data_offer_interface, offer);
-	wl_resource_set_destructor(offer->resource, destroy_data_offer);
+	offer->resource =
+		wl_resource_create(wl_resource_get_client(target),
+				   &wl_data_offer_interface, 1, 0);
+	wl_resource_set_implementation(offer->resource, &data_offer_interface,
+				       offer, destroy_data_offer);
 
 	offer->source = source;
 	offer->source_destroy_listener.notify = destroy_offer_data_source;
@@ -545,11 +546,10 @@
 
 	wl_array_init(&source->mime_types);
 
-	source->resource = wl_client_add_object(client,
-						&wl_data_source_interface,
-						&data_source_interface,
-						id, source);
-	wl_resource_set_destructor(source->resource, destroy_data_source);
+	source->resource =
+		wl_resource_create(client, &wl_data_source_interface, 1, id);
+	wl_resource_set_implementation(source->resource, &data_source_interface,
+				       source, destroy_data_source);
 }
 
 static void unbind_data_device(struct wl_resource *resource)
@@ -565,12 +565,12 @@
 	struct weston_seat *seat = wl_resource_get_user_data(seat_resource);
 	struct wl_resource *resource;
 
-	resource = wl_client_add_object(client, &wl_data_device_interface,
-					&data_device_interface, id,
-					seat);
+	resource = wl_resource_create(client,
+				      &wl_data_device_interface, 1, id);
 
 	wl_list_insert(&seat->drag_resource_list, wl_resource_get_link(resource));
-	wl_resource_set_destructor(resource, unbind_data_device);
+	wl_resource_set_implementation(resource, &data_device_interface,
+				       seat, unbind_data_device);
 }
 
 static const struct wl_data_device_manager_interface manager_interface = {
@@ -582,8 +582,14 @@
 bind_manager(struct wl_client *client,
 	     void *data, uint32_t version, uint32_t id)
 {
-	wl_client_add_object(client, &wl_data_device_manager_interface,
-			     &manager_interface, id, NULL);
+	struct wl_resource *resource;
+
+	resource =
+		wl_resource_create(client,
+				   &wl_data_device_manager_interface, 1, id);
+	if (resource)
+		wl_resource_set_implementation(resource, &manager_interface,
+					       NULL, NULL);
 }
 
 WL_EXPORT void
diff --git a/src/input.c b/src/input.c
index 88fd64c..0f42ed6 100644
--- a/src/input.c
+++ b/src/input.c
@@ -1186,10 +1186,11 @@
 	if (!seat->pointer)
 		return;
 
-        cr = wl_client_add_object(client, &wl_pointer_interface,
-				  &pointer_interface, id, seat->pointer);
+        cr = wl_resource_create(client, &wl_pointer_interface,
+				wl_resource_get_version(resource), id);
 	wl_list_insert(&seat->pointer->resource_list, wl_resource_get_link(cr));
-	wl_resource_set_destructor(cr, unbind_resource);
+	wl_resource_set_implementation(cr, &pointer_interface, seat->pointer,
+				       unbind_resource);
 
 	if (seat->pointer->focus &&
 	    wl_resource_get_client(seat->pointer->focus->resource) == client) {
@@ -1219,10 +1220,10 @@
 	if (!seat->keyboard)
 		return;
 
-        cr = wl_client_add_object(client, &wl_keyboard_interface, NULL, id,
-				  seat);
+        cr = wl_resource_create(client, &wl_keyboard_interface,
+				wl_resource_get_version(resource), id);
 	wl_list_insert(&seat->keyboard->resource_list, wl_resource_get_link(cr));
-	wl_resource_set_destructor(cr, unbind_resource);
+	wl_resource_set_implementation(cr, NULL, seat, unbind_resource);
 
 	if (seat->compositor->use_xkbcommon) {
 		wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
@@ -1254,9 +1255,10 @@
 	if (!seat->touch)
 		return;
 
-        cr = wl_client_add_object(client, &wl_touch_interface, NULL, id, seat);
+        cr = wl_resource_create(client, &wl_touch_interface,
+				wl_resource_get_version(resource), id);
 	wl_list_insert(&seat->touch->resource_list, wl_resource_get_link(cr));
-	wl_resource_set_destructor(cr, unbind_resource);
+	wl_resource_set_implementation(cr, NULL, seat, unbind_resource);
 }
 
 static const struct wl_seat_interface seat_interface = {
@@ -1272,10 +1274,11 @@
 	struct wl_resource *resource;
 	enum wl_seat_capability caps = 0;
 
-	resource = wl_client_add_object(client, &wl_seat_interface,
-					&seat_interface, id, data);
+	resource = wl_resource_create(client,
+				      &wl_seat_interface, MIN(version, 2), id);
 	wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
-	wl_resource_set_destructor(resource, unbind_resource);
+	wl_resource_set_implementation(resource, &seat_interface, data,
+				       unbind_resource);
 
 	if (seat->pointer)
 		caps |= WL_SEAT_CAPABILITY_POINTER;
diff --git a/src/screenshooter.c b/src/screenshooter.c
index 8143202..f236ca4 100644
--- a/src/screenshooter.c
+++ b/src/screenshooter.c
@@ -217,14 +217,17 @@
 	struct screenshooter *shooter = data;
 	struct wl_resource *resource;
 
-	resource = wl_client_add_object(client, &screenshooter_interface,
-			     &screenshooter_implementation, id, data);
+	resource = wl_resource_create(client,
+				      &screenshooter_interface, 1, id);
 
 	if (client != shooter->client) {
 		wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
 				       "screenshooter failed: permission denied");
 		wl_resource_destroy(resource);
 	}
+
+	wl_resource_set_implementation(resource, &screenshooter_implementation,
+				       data, NULL);
 }
 
 static void
diff --git a/src/shell.c b/src/shell.c
index 9869db5..aa2db3d 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -1015,16 +1015,17 @@
 	struct desktop_shell *shell = data;
 	struct wl_resource *resource;
 
-	resource = wl_client_add_object(client, &workspace_manager_interface,
-					&workspace_manager_implementation,
-					id, shell);
+	resource = wl_resource_create(client,
+				      &workspace_manager_interface, 1, id);
 
 	if (resource == NULL) {
 		weston_log("couldn't add workspace manager object");
 		return;
 	}
 
-	wl_resource_set_destructor(resource, unbind_resource);
+	wl_resource_set_implementation(resource,
+				       &workspace_manager_implementation,
+				       shell, unbind_resource);
 	wl_list_insert(&shell->workspaces.client_list,
 		       wl_resource_get_link(resource));
 
@@ -2332,12 +2333,12 @@
 		return;
 	}
 
-	shsurf->resource = wl_client_add_object(client,
-						&wl_shell_surface_interface,
-						&shell_surface_implementation,
-						id, shsurf);
-	wl_resource_set_destructor(shsurf->resource,
-				   shell_destroy_shell_surface);
+	shsurf->resource =
+		wl_resource_create(client,
+				   &wl_shell_surface_interface, 1, id);
+	wl_resource_set_implementation(shsurf->resource,
+				       &shell_surface_implementation,
+				       shsurf, shell_destroy_shell_surface);
 }
 
 static const struct wl_shell_interface shell_implementation = {
@@ -3598,9 +3599,12 @@
 bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
 {
 	struct desktop_shell *shell = data;
+	struct wl_resource *resource;
 
-	wl_client_add_object(client, &wl_shell_interface,
-			     &shell_implementation, id, shell);
+	resource = wl_resource_create(client, &wl_shell_interface, 1, id);
+	if (resource)
+		wl_resource_set_implementation(resource, &shell_implementation,
+					       shell, NULL);
 }
 
 static void
@@ -3622,12 +3626,13 @@
 	struct desktop_shell *shell = data;
 	struct wl_resource *resource;
 
-	resource = wl_client_add_object(client, &desktop_shell_interface,
-					&desktop_shell_implementation,
-					id, shell);
+	resource = wl_resource_create(client, &desktop_shell_interface,
+				      MIN(version, 2), id);
 
 	if (client == shell->child.client) {
-		wl_resource_set_destructor(resource, unbind_desktop_shell);
+		wl_resource_set_implementation(resource,
+					       &desktop_shell_implementation,
+					       shell, unbind_desktop_shell);
 		shell->child.desktop_shell = resource;
 
 		if (version < 2)
@@ -3700,12 +3705,12 @@
 	struct desktop_shell *shell = data;
 	struct wl_resource *resource;
 
-	resource = wl_client_add_object(client, &screensaver_interface,
-					&screensaver_implementation,
-					id, shell);
+	resource = wl_resource_create(client, &screensaver_interface, 1, id);
 
 	if (shell->screensaver.binding == NULL) {
-		wl_resource_set_destructor(resource, unbind_screensaver);
+		wl_resource_set_implementation(resource,
+					       &screensaver_implementation,
+					       shell, unbind_screensaver);
 		shell->screensaver.binding = resource;
 		return;
 	}
@@ -3894,13 +3899,13 @@
 		return;
 	}
 
-	ipsurf->resource = wl_client_add_object(client,
-						&wl_input_panel_surface_interface,
-						&input_panel_surface_implementation,
-						id, ipsurf);
-
-	wl_resource_set_destructor(ipsurf->resource,
-				   destroy_input_panel_surface_resource);
+	ipsurf->resource =
+		wl_resource_create(client,
+				   &wl_input_panel_surface_interface, 1, id);
+	wl_resource_set_implementation(ipsurf->resource,
+				       &input_panel_surface_implementation,
+				       ipsurf,
+				       destroy_input_panel_surface_resource);
 }
 
 static const struct wl_input_panel_interface input_panel_implementation = {
@@ -3922,12 +3927,13 @@
 	struct desktop_shell *shell = data;
 	struct wl_resource *resource;
 
-	resource = wl_client_add_object(client, &wl_input_panel_interface,
-					&input_panel_implementation,
-					id, shell);
+	resource = wl_resource_create(client,
+				      &wl_input_panel_interface, 1, id);
 
 	if (shell->input_panel.binding == NULL) {
-		wl_resource_set_destructor(resource, unbind_input_panel);
+		wl_resource_set_implementation(resource,
+					       &input_panel_implementation,
+					       shell, unbind_input_panel);
 		shell->input_panel.binding = resource;
 		return;
 	}
diff --git a/src/tablet-shell.c b/src/tablet-shell.c
index 91e5110..76a4010 100644
--- a/src/tablet-shell.c
+++ b/src/tablet-shell.c
@@ -350,12 +350,11 @@
 	tablet_client->shell = shell;
 	tablet_client->name = strdup(name);
 
-	tablet_client->resource = wl_client_add_object(client,
-						       &tablet_client_interface,
-						       &tablet_client_implementation,
-						       id, tablet_client);
-	wl_resource_set_destructor(tablet_client->resource,
-				   destroy_tablet_client);
+	tablet_client->resource =
+		wl_resource_create(client, &tablet_client_interface, 1, id);
+	wl_resource_set_implementation(tablet_client->resource,
+				       &tablet_client_implementation,
+				       tablet_client, destroy_tablet_client);
 
 	tablet_client->surface = NULL;
 	shell->current_client = tablet_client;
@@ -498,11 +497,11 @@
 		 * tries to access the object?. */
 		return;
 
-	shell->resource = wl_client_add_object(client,
-					       &tablet_shell_interface,
-					       &tablet_shell_implementation,
-					       id, shell);
-	wl_resource_set_destructor(shell->resource, destroy_tablet_shell);
+	shell->resource =
+		wl_resource_create(client, &tablet_shell_interface, 1, id);
+	wl_resource_set_implementation(shell->resource,
+				       &tablet_shell_implementation,
+				       shell, destroy_tablet_shell);
 }
 
 static void
diff --git a/src/text-backend.c b/src/text-backend.c
index 38728e9..b7a1a40 100644
--- a/src/text-backend.c
+++ b/src/text-backend.c
@@ -358,11 +358,11 @@
 
 	text_input = calloc(1, sizeof *text_input);
 
-	text_input->resource = wl_client_add_object(client,
-						    &wl_text_input_interface,
-						    &text_input_implementation,
-						    id, text_input);
-	wl_resource_set_destructor(text_input->resource, destroy_text_input);
+	text_input->resource =
+		wl_resource_create(client, &wl_text_input_interface, 1, id);
+	wl_resource_set_implementation(text_input->resource,
+				       &text_input_implementation,
+				       text_input, destroy_text_input);
 
 	text_input->ec = text_input_manager->ec;
 
@@ -380,12 +380,16 @@
 			uint32_t id)
 {
 	struct text_input_manager *text_input_manager = data;
+	struct wl_resource *resource;
 
-	/* No checking for duplicate binding necessary.
-	 * No events have to be sent, so we don't need the return value. */
-	wl_client_add_object(client, &wl_text_input_manager_interface,
-			     &text_input_manager_implementation,
-			     id, text_input_manager);
+	/* No checking for duplicate binding necessary.  */
+	resource =
+		wl_resource_create(client,
+				   &wl_text_input_manager_interface, 1, id);
+	if (resource)
+		wl_resource_set_implementation(resource,
+					       &text_input_manager_implementation,
+					       text_input_manager, NULL);
 }
 
 static void
@@ -582,9 +586,8 @@
 	struct weston_seat *seat = context->input_method->seat;
 	struct weston_keyboard *keyboard = seat->keyboard;
 
-	cr = wl_client_add_object(client, &wl_keyboard_interface,
-				  NULL, id, context);
-	wl_resource_set_destructor(cr, unbind_keyboard);
+	cr = wl_resource_create(client, &wl_keyboard_interface, 1, id);
+	wl_resource_set_implementation(cr, NULL, context, unbind_keyboard);
 
 	context->keyboard = cr;
 
@@ -703,12 +706,12 @@
 		return;
 
 	binding = input_method->input_method_binding;
-	context->resource = wl_client_new_object(wl_resource_get_client(binding),
-						 &wl_input_method_context_interface,
-						 &input_method_context_implementation,
-						 context);
-	wl_resource_set_destructor(context->resource,
-				   destroy_input_method_context);
+	context->resource =
+		wl_resource_create(wl_resource_get_client(binding),
+				   &wl_input_method_context_interface, 1, 0);
+	wl_resource_set_implementation(context->resource,
+				       &input_method_context_implementation,
+				       context, destroy_input_method_context);
 
 	context->model = model;
 	context->input_method = input_method;
@@ -756,9 +759,8 @@
 	struct text_backend *text_backend = input_method->text_backend;
 	struct wl_resource *resource;
 
-	resource = wl_client_add_object(client, &wl_input_method_interface,
-					NULL,
-					id, input_method);
+	resource =
+		wl_resource_create(client, &wl_input_method_interface, 1, id);
 
 	if (input_method->input_method_binding != NULL) {
 		wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
@@ -774,7 +776,8 @@
 		return;
 	}
 
-	wl_resource_set_destructor(resource, unbind_input_method);
+	wl_resource_set_implementation(resource, NULL, input_method,
+				       unbind_input_method);
 	input_method->input_method_binding = resource;
 
 	text_backend->input_method.binding = resource;
diff --git a/src/xwayland/launcher.c b/src/xwayland/launcher.c
index 7048131..32ec1ae 100644
--- a/src/xwayland/launcher.c
+++ b/src/xwayland/launcher.c
@@ -159,8 +159,10 @@
 		return;
 
 	wxs->resource = 
-		wl_client_add_object(client, &xserver_interface,
-				     &xserver_implementation, id, wxs);
+		wl_resource_create(client, &xserver_interface,
+					       1, id);
+	wl_resource_set_implementation(wxs->resource, &xserver_implementation,
+				       wxs, NULL);
 
 	wxs->wm = weston_wm_create(wxs);
 	if (wxs->wm == NULL) {
diff --git a/src/zoom.c b/src/zoom.c
index 267ff31..1dc8557 100644
--- a/src/zoom.c
+++ b/src/zoom.c
@@ -53,8 +53,14 @@
 bind_text_cursor_position(struct wl_client *client,
 	     void *data, uint32_t version, uint32_t id)
 {
-	wl_client_add_object(client, &text_cursor_position_interface,
-			     &text_cursor_position_implementation, id, data);
+	struct wl_resource *resource;
+
+	resource = wl_resource_create(client,
+				      &text_cursor_position_interface, 1, id);
+	if (resource)
+		wl_resource_set_implementation(resource,
+					       &text_cursor_position_implementation,
+					       data, NULL);
 }
 
 static void
diff --git a/tests/weston-test.c b/tests/weston-test.c
index 214296e..3b5e7cb 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -191,8 +191,10 @@
 	struct weston_test *test = data;
 	struct wl_resource *resource;
 
-	resource = wl_client_add_object(client, &wl_test_interface,
-					&test_implementation, id, test);
+	resource = wl_client_add_versioned_object(client, &wl_test_interface,
+						  1, id);
+	wl_resource_set_implementation(resource, &test_implementation,
+				       test, NULL);
 
 	notify_pointer_position(test, resource);
 }