Convert to wl_global_create/destroy()
diff --git a/clients/nested.c b/clients/nested.c
index 6aef9c8..a4e07f7 100644
--- a/clients/nested.c
+++ b/clients/nested.c
@@ -44,6 +44,8 @@
 
 #include "window.h"
 
+#define MIN(x,y) (((x) < (y)) ? (x) : (y))
+
 struct nested {
 	struct display *display;
 	struct window *window;
@@ -347,10 +349,10 @@
 		return;
 	}
 
-	callback->resource =
-		wl_client_add_object(client, &wl_callback_interface,
-				     NULL, id, callback);
-	wl_resource_set_destructor(callback->resource, destroy_frame_callback);
+	callback->resource = wl_resource_create(client,
+						&wl_callback_interface, 1, id);
+	wl_resource_set_implementation(callback->resource, NULL, callback,
+				       destroy_frame_callback);
 
 	wl_list_insert(nested->frame_callback_list.prev, &callback->link);
 }
@@ -423,9 +425,11 @@
 	display_release_window_surface(nested->display, nested->window);
 
 	surface->resource =
-		wl_client_add_object(client, &wl_surface_interface,
-				     &surface_interface, id, surface);
-	wl_resource_set_destructor(surface->resource, destroy_surface);
+		wl_resource_create(client, &wl_surface_interface, 1, id);
+
+	wl_resource_set_implementation(surface->resource,
+				       &surface_interface, surface,
+				       destroy_surface);
 
 	wl_list_insert(nested->surface_list.prev, &surface->link);
 }
@@ -488,23 +492,27 @@
 	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);
+		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 = {
 	compositor_create_surface,
 	compositor_create_region
 };
+
 static void
 compositor_bind(struct wl_client *client,
 		void *data, uint32_t version, uint32_t id)
 {
 	struct nested *nested = data;
+	struct wl_resource *resource;
 
-	wl_client_add_object(client, &wl_compositor_interface,
-			     &compositor_interface, id, nested);
+	resource = wl_resource_create(client, &wl_compositor_interface,
+				      MIN(version, 3), id);
+	wl_resource_set_implementation(resource, &compositor_interface,
+				       nested, NULL);
 }
 
 static int
@@ -523,9 +531,9 @@
 	display_watch_fd(nested->display, fd,
 			 EPOLLIN, &nested->child_task);
 
-	if (!wl_display_add_global(nested->child_display,
-				   &wl_compositor_interface,
-				   nested, compositor_bind))
+	if (!wl_global_create(nested->child_display,
+			      &wl_compositor_interface, 1,
+			      nested, compositor_bind))
 		return -1;
 
 	wl_display_init_shm(nested->child_display);
diff --git a/src/compositor.c b/src/compositor.c
index 92d89a7..e9e1166 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2571,8 +2571,6 @@
 WL_EXPORT void
 weston_output_destroy(struct weston_output *output)
 {
-	struct weston_compositor *c = output->compositor;
-
 	wl_signal_emit(&output->destroy_signal, output);
 
 	free(output->name);
@@ -2580,7 +2578,7 @@
 	pixman_region32_fini(&output->previous_damage);
 	output->compositor->output_id_pool &= ~(1 << output->id);
 
-	wl_display_remove_global(c->wl_display, output->global);
+	wl_global_destroy(output->global);
 }
 
 static void
@@ -2748,8 +2746,8 @@
 	output->compositor->output_id_pool |= 1 << output->id;
 
 	output->global =
-		wl_display_add_global(c->wl_display, &wl_output_interface,
-				      output, bind_output);
+		wl_global_create(c->wl_display, &wl_output_interface, 2,
+				 output, bind_output);
 	wl_signal_emit(&c->output_created_signal, output);
 }
 
@@ -2828,12 +2826,12 @@
 
 	ec->output_id_pool = 0;
 
-	if (!wl_display_add_global(display, &wl_compositor_interface,
-				   ec, compositor_bind))
+	if (!wl_global_create(display, &wl_compositor_interface, 3,
+			      ec, compositor_bind))
 		return -1;
 
-	if (!wl_display_add_global(display, &wl_subcompositor_interface,
-				   ec, bind_subcompositor))
+	if (!wl_global_create(display, &wl_subcompositor_interface, 1,
+			      ec, bind_subcompositor))
 		return -1;
 
 	wl_list_init(&ec->surface_list);
diff --git a/src/data-device.c b/src/data-device.c
index 205fe79..c89379c 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -620,9 +620,9 @@
 WL_EXPORT int
 wl_data_device_manager_init(struct wl_display *display)
 {
-	if (wl_display_add_global(display,
-				  &wl_data_device_manager_interface,
-				  NULL, bind_manager) == NULL)
+	if (wl_global_create(display,
+			     &wl_data_device_manager_interface, 1,
+			     NULL, bind_manager) == NULL)
 		return -1;
 
 	return 0;
diff --git a/src/input.c b/src/input.c
index 2519d9f..1887e7f 100644
--- a/src/input.c
+++ b/src/input.c
@@ -1531,9 +1531,8 @@
 	wl_list_init(&seat->drag_resource_list);
 	wl_signal_init(&seat->destroy_signal);
 
-	seat->global =
-		wl_display_add_global(ec->wl_display,
-				      &wl_seat_interface, seat, bind_seat);
+	seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 2,
+					seat, bind_seat);
 
 	seat->compositor = ec;
 	seat->modifier_state = 0;
@@ -1569,7 +1568,7 @@
 
 	free (seat->seat_name);
 
-	wl_display_remove_global(seat->compositor->wl_display, seat->global);
+	wl_global_destroy(seat->global);
 
 	wl_signal_emit(&seat->destroy_signal, seat);
 }
diff --git a/src/screenshooter.c b/src/screenshooter.c
index f236ca4..2b37071 100644
--- a/src/screenshooter.c
+++ b/src/screenshooter.c
@@ -559,7 +559,7 @@
 	struct screenshooter *shooter =
 		container_of(listener, struct screenshooter, destroy_listener);
 
-	wl_display_remove_global(shooter->ec->wl_display, shooter->global);
+	wl_global_destroy(shooter->global);
 	free(shooter);
 }
 
@@ -575,9 +575,9 @@
 	shooter->ec = ec;
 	shooter->client = NULL;
 
-	shooter->global = wl_display_add_global(ec->wl_display,
-						&screenshooter_interface,
-						shooter, bind_shooter);
+	shooter->global = wl_global_create(ec->wl_display,
+					   &screenshooter_interface, 1,
+					   shooter, bind_shooter);
 	weston_compositor_add_key_binding(ec, KEY_S, MODIFIER_SUPER,
 					  screenshooter_binding, shooter);
 	weston_compositor_add_key_binding(ec, KEY_R, MODIFIER_SUPER,
diff --git a/src/shell.c b/src/shell.c
index e20004f..69345b0 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -4507,25 +4507,25 @@
 	wl_list_init(&shell->workspaces.animation.link);
 	shell->workspaces.animation.frame = animate_workspace_change_frame;
 
-	if (wl_display_add_global(ec->wl_display, &wl_shell_interface,
+	if (wl_global_create(ec->wl_display, &wl_shell_interface, 1,
 				  shell, bind_shell) == NULL)
 		return -1;
 
-	if (wl_display_add_global(ec->wl_display,
-				  &desktop_shell_interface,
-				  shell, bind_desktop_shell) == NULL)
+	if (wl_global_create(ec->wl_display,
+			     &desktop_shell_interface, 2,
+			     shell, bind_desktop_shell) == NULL)
 		return -1;
 
-	if (wl_display_add_global(ec->wl_display, &screensaver_interface,
-				  shell, bind_screensaver) == NULL)
+	if (wl_global_create(ec->wl_display, &screensaver_interface, 1,
+			     shell, bind_screensaver) == NULL)
 		return -1;
 
-	if (wl_display_add_global(ec->wl_display, &wl_input_panel_interface,
+	if (wl_global_create(ec->wl_display, &wl_input_panel_interface, 1,
 				  shell, bind_input_panel) == NULL)
 		return -1;
 
-	if (wl_display_add_global(ec->wl_display, &workspace_manager_interface,
-				  shell, bind_workspace_manager) == NULL)
+	if (wl_global_create(ec->wl_display, &workspace_manager_interface, 1,
+			     shell, bind_workspace_manager) == NULL)
 		return -1;
 
 	shell->child.deathstamp = weston_compositor_get_time();
diff --git a/src/tablet-shell.c b/src/tablet-shell.c
index 76a4010..fdeb856 100644
--- a/src/tablet-shell.c
+++ b/src/tablet-shell.c
@@ -542,8 +542,8 @@
 	wl_signal_add(&compositor->wake_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_tablet_shell);
+	wl_global_create(compositor->wl_display, &tablet_shell_interface, 1,
+			 shell, bind_tablet_shell);
 
 	loop = wl_display_get_event_loop(compositor->wl_display);
 	shell->long_press_source =
diff --git a/src/text-backend.c b/src/text-backend.c
index b7a1a40..3a1d68c 100644
--- a/src/text-backend.c
+++ b/src/text-backend.c
@@ -398,8 +398,7 @@
 	struct text_input_manager *text_input_manager =
 		container_of(listener, struct text_input_manager, destroy_listener);
 
-	wl_display_remove_global(text_input_manager->ec->wl_display,
-				 text_input_manager->text_input_manager_global);
+	wl_global_destroy(text_input_manager->text_input_manager_global);
 
 	free(text_input_manager);
 }
@@ -414,9 +413,9 @@
 	text_input_manager->ec = ec;
 
 	text_input_manager->text_input_manager_global =
-		wl_display_add_global(ec->wl_display,
-				      &wl_text_input_manager_interface,
-				      text_input_manager, bind_text_input_manager);
+		wl_global_create(ec->wl_display,
+				 &wl_text_input_manager_interface, 1,
+				 text_input_manager, bind_text_input_manager);
 
 	text_input_manager->destroy_listener.notify = text_input_manager_notifier_destroy;
 	wl_signal_add(&ec->destroy_signal, &text_input_manager->destroy_listener);
@@ -792,8 +791,7 @@
 	if (input_method->model)
 		deactivate_text_input(input_method->model, input_method);
 
-	wl_display_remove_global(input_method->seat->compositor->wl_display,
-				 input_method->input_method_global);
+	wl_global_destroy(input_method->input_method_global);
 
 	free(input_method);
 }
@@ -899,9 +897,8 @@
 	input_method->text_backend = text_backend;
 
 	input_method->input_method_global =
-		wl_display_add_global(ec->wl_display,
-				      &wl_input_method_interface,
-				      input_method, bind_input_method);
+		wl_global_create(ec->wl_display, &wl_input_method_interface, 1,
+				 input_method, bind_input_method);
 
 	input_method->destroy_listener.notify = input_method_notifier_destroy;
 	wl_signal_add(&seat->destroy_signal, &input_method->destroy_listener);
diff --git a/src/xwayland/launcher.c b/src/xwayland/launcher.c
index 32ec1ae..3228b53 100644
--- a/src/xwayland/launcher.c
+++ b/src/xwayland/launcher.c
@@ -376,7 +376,7 @@
 				     WL_EVENT_READABLE,
 				     weston_xserver_handle_event, wxs);
 
-	wl_display_add_global(display, &xserver_interface, wxs, bind_xserver);
+	wl_global_create(display, &xserver_interface, 1, wxs, bind_xserver);
 
 	wxs->destroy_listener.notify = weston_xserver_destroy;
 	wl_signal_add(&compositor->destroy_signal, &wxs->destroy_listener);
diff --git a/src/zoom.c b/src/zoom.c
index 1dc8557..220b2b6 100644
--- a/src/zoom.c
+++ b/src/zoom.c
@@ -69,7 +69,7 @@
 	struct text_cursor_position *text_cursor_position =
 		container_of(listener, struct text_cursor_position, destroy_listener);
 
-	wl_display_remove_global(text_cursor_position->ec->wl_display, text_cursor_position->global);
+	wl_global_destroy(text_cursor_position->global);
 	free(text_cursor_position);
 }
 
@@ -84,11 +84,14 @@
 
 	text_cursor_position->ec = ec;
 
-	text_cursor_position->global = wl_display_add_global(ec->wl_display,
-						&text_cursor_position_interface,
-						text_cursor_position, bind_text_cursor_position);
+	text_cursor_position->global =
+		wl_global_create(ec->wl_display,
+				 &text_cursor_position_interface, 1,
+				 text_cursor_position,
+				 bind_text_cursor_position);
 
-	text_cursor_position->destroy_listener.notify = text_cursor_position_notifier_destroy;
+	text_cursor_position->destroy_listener.notify =
+		text_cursor_position_notifier_destroy;
 	wl_signal_add(&ec->destroy_signal, &text_cursor_position->destroy_listener);
 }
 
diff --git a/tests/weston-test.c b/tests/weston-test.c
index 486cd6a..b625f42 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -240,8 +240,8 @@
 	test->compositor = ec;
 	weston_layer_init(&test->layer, &ec->cursor_layer.link);
 
-	if (wl_display_add_global(ec->wl_display, &wl_test_interface,
-				  test, bind_test) == NULL)
+	if (wl_global_create(ec->wl_display, &wl_test_interface, 1,
+			     test, bind_test) == NULL)
 		return -1;
 
 	loop = wl_display_get_event_loop(ec->wl_display);