Convert wl_input_device to wl_seat (and friends)

wl_input_device has been both renamed and split.  wl_seat is now a
virtual object representing a group of logically related input devices
with related focus.

It now only generates one event: to let clients know that it has new
capabilities.  It takes requests which hand back objects for the
wl_pointer, wl_keyboard and wl_touch interfaces it exposes which all
provide the old input interface, just under different names.

This commit tracks these changes in weston and the clients, as well as
similar renames (e.g. weston_input_device -> weston_seat).  Some other
changes were necessary, e.g. renaming the name for the visible mouse
sprite from 'pointer' to 'cursor' so as to not conflict.

For simplicity, every seat is always exposed with all three interfaces,
although this will change as time goes on.

Signed-off-by: Daniel Stone <daniel@fooishbar.org>
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index d588dbf..ce024dd 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -625,22 +625,22 @@
 
 static int
 drm_output_set_cursor(struct weston_output *output_base,
-		      struct weston_input_device *eid);
+		      struct weston_seat *es);
 
 static void
 weston_output_set_cursor(struct weston_output *output,
-			 struct weston_input_device *device,
+			 struct weston_seat *seat,
 			 pixman_region32_t *overlap)
 {
 	pixman_region32_t cursor_region;
 	int prior_was_hardware;
 
-	if (device->sprite == NULL)
+	if (seat->sprite == NULL)
 		return;
 
 	pixman_region32_init(&cursor_region);
 	pixman_region32_intersect(&cursor_region,
-				  &device->sprite->transform.boundingbox,
+				  &seat->sprite->transform.boundingbox,
 				  &output->region);
 
 	if (!pixman_region32_not_empty(&cursor_region)) {
@@ -648,19 +648,19 @@
 		goto out;
 	}
 
-	prior_was_hardware = device->hw_cursor;
+	prior_was_hardware = seat->hw_cursor;
 	if (pixman_region32_not_empty(overlap) ||
-	    drm_output_set_cursor(output, device) < 0) {
+	    drm_output_set_cursor(output, seat) < 0) {
 		if (prior_was_hardware) {
-			weston_surface_damage(device->sprite);
+			weston_surface_damage(seat->sprite);
 			drm_output_set_cursor(output, NULL);
 		}
-		device->hw_cursor = 0;
+		seat->hw_cursor = 0;
 	} else {
 		if (!prior_was_hardware)
-			weston_surface_damage_below(device->sprite);
-		wl_list_remove(&device->sprite->link);
-		device->hw_cursor = 1;
+			weston_surface_damage_below(seat->sprite);
+		wl_list_remove(&seat->sprite->link);
+		seat->hw_cursor = 1;
 	}
 
 out:
@@ -673,7 +673,7 @@
 	struct weston_compositor *ec = output->compositor;
 	struct weston_surface *es, *next;
 	pixman_region32_t overlap, surface_overlap;
-	struct weston_input_device *device;
+	struct weston_seat *seat;
 
 	/*
 	 * Find a surface for each sprite in the output using some heuristics:
@@ -698,12 +698,12 @@
 		pixman_region32_intersect(&surface_overlap, &overlap,
 					  &es->transform.boundingbox);
 
-		device = (struct weston_input_device *) ec->input_device;
-		if (es == device->sprite) {
-			weston_output_set_cursor(output, device,
+		seat = (struct weston_seat *) ec->seat;
+		if (es == seat->sprite) {
+			weston_output_set_cursor(output, seat,
 						 &surface_overlap);
 
-			if (!device->hw_cursor)
+			if (!seat->hw_cursor)
 				pixman_region32_union(&overlap, &overlap,
 						      &es->transform.boundingbox);
 		} else if (!drm_output_prepare_overlay_surface(output, es,
@@ -723,7 +723,7 @@
 
 static int
 drm_output_set_cursor(struct weston_output *output_base,
-		      struct weston_input_device *eid)
+		      struct weston_seat *es)
 {
 	struct drm_output *output = (struct drm_output *) output_base;
 	struct drm_compositor *c =
@@ -734,17 +734,17 @@
 	uint32_t buf[64 * 64];
 	unsigned char *d, *s, *end;
 
-	if (eid == NULL) {
+	if (es == NULL) {
 		drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0);
 		return 0;
 	}
 
-	if (eid->sprite->buffer == NULL ||
-	    !wl_buffer_is_shm(eid->sprite->buffer))
+	if (es->sprite->buffer == NULL ||
+	    !wl_buffer_is_shm(es->sprite->buffer))
 		goto out;
 
-	if (eid->sprite->geometry.width > 64 ||
-	    eid->sprite->geometry.height > 64)
+	if (es->sprite->geometry.width > 64 ||
+	    es->sprite->geometry.height > 64)
 		goto out;
 
 	output->current_cursor ^= 1;
@@ -754,11 +754,11 @@
 
 	memset(buf, 0, sizeof buf);
 	d = (unsigned char *) buf;
-	stride = wl_shm_buffer_get_stride(eid->sprite->buffer);
-	s = wl_shm_buffer_get_data(eid->sprite->buffer);
-	end = s + stride * eid->sprite->geometry.height;
+	stride = wl_shm_buffer_get_stride(es->sprite->buffer);
+	s = wl_shm_buffer_get_data(es->sprite->buffer);
+	end = s + stride * es->sprite->geometry.height;
 	while (s < end) {
-		memcpy(d, s, eid->sprite->geometry.width * 4);
+		memcpy(d, s, es->sprite->geometry.width * 4);
 		s += stride;
 		d += 64 * 4;
 	}
@@ -774,8 +774,8 @@
 	}
 
 	ret = drmModeMoveCursor(c->drm.fd, output->crtc_id,
-				eid->sprite->geometry.x - output->base.x,
-				eid->sprite->geometry.y - output->base.y);
+				es->sprite->geometry.x - output->base.x,
+				es->sprite->geometry.y - output->base.y);
 	if (ret) {
 		fprintf(stderr, "failed to move cursor: %s\n", strerror(-ret));
 		goto out;
@@ -1616,10 +1616,10 @@
 drm_destroy(struct weston_compositor *ec)
 {
 	struct drm_compositor *d = (struct drm_compositor *) ec;
-	struct weston_input_device *input, *next;
+	struct weston_seat *seat, *next;
 
-	wl_list_for_each_safe(input, next, &ec->input_device_list, link)
-		evdev_input_destroy(input);
+	wl_list_for_each_safe(seat, next, &ec->seat_list, link)
+		evdev_input_destroy(seat);
 
 	wl_event_source_remove(d->udev_drm_source);
 	wl_event_source_remove(d->drm_source);
@@ -1668,7 +1668,7 @@
 {
 	struct drm_compositor *ec = (struct drm_compositor *) compositor;
 	struct weston_output *output;
-	struct weston_input_device *input;
+	struct weston_seat *seat;
 	struct drm_sprite *sprite;
 	struct drm_output *drm_output;
 
@@ -1682,15 +1682,15 @@
 		compositor->state = ec->prev_state;
 		drm_compositor_set_modes(ec);
 		weston_compositor_damage_all(compositor);
-		wl_list_for_each(input, &compositor->input_device_list, link) {
-			evdev_add_devices(ec->udev, input);
-			evdev_enable_udev_monitor(ec->udev, input);
+		wl_list_for_each(seat, &compositor->seat_list, link) {
+			evdev_add_devices(ec->udev, seat);
+			evdev_enable_udev_monitor(ec->udev, seat);
 		}
 		break;
 	case TTY_LEAVE_VT:
-		wl_list_for_each(input, &compositor->input_device_list, link) {
-			evdev_disable_udev_monitor(input);
-			evdev_remove_devices(input);
+		wl_list_for_each(seat, &compositor->seat_list, link) {
+			evdev_disable_udev_monitor(seat);
+			evdev_remove_devices(seat);
 		}
 
 		compositor->focus = 0;
@@ -1727,7 +1727,7 @@
 }
 
 static void
-switch_vt_binding(struct wl_input_device *device, uint32_t time,
+switch_vt_binding(struct wl_seat *seat, uint32_t time,
 		  uint32_t key, uint32_t button, uint32_t axis, int32_t state, void *data)
 {
 	struct drm_compositor *ec = data;
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 96fedbc..bbacea4 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -85,7 +85,10 @@
 
 struct wayland_input {
 	struct wayland_compositor *compositor;
-	struct wl_input_device *input_device;
+	struct wl_seat *seat;
+	struct wl_pointer *pointer;
+	struct wl_keyboard *keyboard;
+	struct wl_touch *touch;
 	struct wl_list link;
 };
 
@@ -244,16 +247,16 @@
 static int
 wayland_input_create(struct wayland_compositor *c)
 {
-	struct weston_input_device *input;
+	struct weston_seat *seat;
 
-	input = malloc(sizeof *input);
-	if (input == NULL)
+	seat = malloc(sizeof *seat);
+	if (seat == NULL)
 		return -1;
 
-	memset(input, 0, sizeof *input);
-	weston_input_device_init(input, &c->base);
+	memset(seat, 0, sizeof *seat);
+	weston_seat_init(seat, &c->base);
 
-	c->base.input_device = &input->input_device;
+	c->base.seat = seat;
 
 	return 0;
 }
@@ -507,52 +510,8 @@
 
 /* parent input interface */
 static void
-input_handle_motion(void *data, struct wl_input_device *input_device,
-		    uint32_t time, wl_fixed_t x, wl_fixed_t y)
-{
-	struct wayland_input *input = data;
-	struct wayland_compositor *c = input->compositor;
-
-	notify_motion(c->base.input_device, time,
-		      x - wl_fixed_from_int(c->border.left),
-		      y - wl_fixed_from_int(c->border.top));
-}
-
-static void
-input_handle_button(void *data,
-		    struct wl_input_device *input_device,
-		    uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
-{
-	struct wayland_input *input = data;
-	struct wayland_compositor *c = input->compositor;
-
-	notify_button(c->base.input_device, time, button, state);
-}
-
-static void
-input_handle_axis(void *data, struct wl_input_device *input_device,
-		  uint32_t time, uint32_t axis, int32_t value)
-{
-	struct wayland_input *input = data;
-	struct wayland_compositor *c = input->compositor;
-
-	notify_axis(c->base.input_device, time, axis, value);
-}
-
-static void
-input_handle_key(void *data, struct wl_input_device *input_device,
-		 uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
-{
-	struct wayland_input *input = data;
-	struct wayland_compositor *c = input->compositor;
-
-	notify_key(c->base.input_device, time, key, state);
-}
-
-static void
-input_handle_pointer_enter(void *data,
-			   struct wl_input_device *input_device,
-			   uint32_t time, struct wl_surface *surface,
+input_handle_pointer_enter(void *data, struct wl_pointer *pointer,
+			   uint32_t serial, struct wl_surface *surface,
 			   wl_fixed_t x, wl_fixed_t y)
 {
 	struct wayland_input *input = data;
@@ -560,59 +519,134 @@
 	struct wayland_compositor *c = input->compositor;
 
 	output = wl_surface_get_user_data(surface);
-	notify_pointer_focus(c->base.input_device, &output->base, x, y);
-	wl_input_device_attach(input->input_device, time, NULL, 0, 0);
+	notify_pointer_focus(&c->base.seat->seat, &output->base, x, y);
+	wl_pointer_attach(input->pointer, serial, NULL, 0, 0);
 }
 
 static void
-input_handle_pointer_leave(void *data,
-			   struct wl_input_device *input_device,
-			   uint32_t time, struct wl_surface *surface)
+input_handle_pointer_leave(void *data, struct wl_pointer *pointer,
+			   uint32_t serial, struct wl_surface *surface)
 {
 	struct wayland_input *input = data;
 	struct wayland_compositor *c = input->compositor;
 
-	notify_pointer_focus(c->base.input_device, NULL, 0, 0);
+	notify_pointer_focus(&c->base.seat->seat, NULL, 0, 0);
 }
 
 static void
+input_handle_motion(void *data, struct wl_pointer *pointer,
+		    uint32_t time, wl_fixed_t x, wl_fixed_t y)
+{
+	struct wayland_input *input = data;
+	struct wayland_compositor *c = input->compositor;
+
+	notify_motion(&c->base.seat->seat, time,
+		      x - wl_fixed_from_int(c->border.left),
+		      y - wl_fixed_from_int(c->border.top));
+}
+
+static void
+input_handle_button(void *data, struct wl_pointer *pointer,
+		    uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
+{
+	struct wayland_input *input = data;
+	struct wayland_compositor *c = input->compositor;
+
+	notify_button(&c->base.seat->seat, time, button, state);
+}
+
+static void
+input_handle_axis(void *data, struct wl_pointer *pointer,
+		  uint32_t time, uint32_t axis, int32_t value)
+{
+	struct wayland_input *input = data;
+	struct wayland_compositor *c = input->compositor;
+
+	notify_axis(&c->base.seat->seat, time, axis, value);
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+	input_handle_pointer_enter,
+	input_handle_pointer_leave,
+	input_handle_motion,
+	input_handle_button,
+	input_handle_axis,
+};
+
+static void
 input_handle_keyboard_enter(void *data,
-			    struct wl_input_device *input_device,
-			    uint32_t time,
+			    struct wl_keyboard *keyboard,
+			    uint32_t serial,
 			    struct wl_surface *surface,
 			    struct wl_array *keys)
 {
 	struct wayland_input *input = data;
 	struct wayland_compositor *c = input->compositor;
 
-	notify_keyboard_focus(c->base.input_device, keys);
+	notify_keyboard_focus(&c->base.seat->seat, keys);
 }
 
 static void
 input_handle_keyboard_leave(void *data,
-			    struct wl_input_device *input_device,
-			    uint32_t time,
+			    struct wl_keyboard *keyboard,
+			    uint32_t serial,
 			    struct wl_surface *surface)
 {
 	struct wayland_input *input = data;
 	struct wayland_compositor *c = input->compositor;
 
-	notify_keyboard_focus(c->base.input_device, NULL);
+	notify_keyboard_focus(&c->base.seat->seat, NULL);
 }
 
-static const struct wl_input_device_listener input_device_listener = {
-	input_handle_motion,
-	input_handle_button,
-	input_handle_axis,
-	input_handle_key,
-	input_handle_pointer_enter,
-	input_handle_pointer_leave,
+static void
+input_handle_key(void *data, struct wl_keyboard *keyboard,
+		 uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
+{
+	struct wayland_input *input = data;
+	struct wayland_compositor *c = input->compositor;
+
+	notify_key(&c->base.seat->seat, time, key, state);
+}
+
+static const struct wl_keyboard_listener keyboard_listener = {
 	input_handle_keyboard_enter,
 	input_handle_keyboard_leave,
+	input_handle_key,
 };
 
 static void
-display_add_input(struct wayland_compositor *c, uint32_t id)
+input_handle_capabilities(void *data, struct wl_seat *seat,
+		          enum wl_seat_capability caps)
+{
+	struct wayland_input *input = data;
+
+	if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
+		input->pointer = wl_seat_get_pointer(seat);
+		wl_pointer_set_user_data(input->pointer, input);
+		wl_pointer_add_listener(input->pointer, &pointer_listener,
+					input);
+	} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
+		wl_pointer_destroy(input->pointer);
+		input->pointer = NULL;
+	}
+
+	if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) {
+		input->keyboard = wl_seat_get_keyboard(seat);
+		wl_keyboard_set_user_data(input->keyboard, input);
+		wl_keyboard_add_listener(input->keyboard, &keyboard_listener,
+					 input);
+	} else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) {
+		wl_keyboard_destroy(input->keyboard);
+		input->keyboard = NULL;
+	}
+}
+
+static const struct wl_seat_listener seat_listener = {
+	input_handle_capabilities,
+};
+
+static void
+display_add_seat(struct wayland_compositor *c, uint32_t id)
 {
 	struct wayland_input *input;
 
@@ -623,13 +657,12 @@
 	memset(input, 0, sizeof *input);
 
 	input->compositor = c;
-	input->input_device = wl_display_bind(c->parent.display,
-					      id, &wl_input_device_interface);
+	input->seat = wl_display_bind(c->parent.display, id,
+				      &wl_seat_interface);
 	wl_list_insert(c->input_list.prev, &input->link);
 
-	wl_input_device_add_listener(input->input_device,
-				     &input_device_listener, input);
-	wl_input_device_set_user_data(input->input_device, input);
+	wl_seat_add_listener(input->seat, &seat_listener, input);
+	wl_seat_set_user_data(input->seat, input);
 }
 
 static void
@@ -645,8 +678,8 @@
 		c->parent.output =
 			wl_display_bind(display, id, &wl_output_interface);
 		wl_output_add_listener(c->parent.output, &output_listener, c);
-	} else if (strcmp(interface, "wl_input_device") == 0) {
-		display_add_input(c, id);
+	} else if (strcmp(interface, "wl_seat") == 0) {
+		display_add_seat(c, id);
 	} else if (strcmp(interface, "wl_shell") == 0) {
 		c->parent.shell =
 			wl_display_bind(display, id, &wl_shell_interface);
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 0777d77..3a4709c 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -83,7 +83,7 @@
 };
 
 struct x11_input {
-	struct weston_input_device base;
+	struct weston_seat base;
 };
 
 
@@ -97,9 +97,9 @@
 		return -1;
 
 	memset(input, 0, sizeof *input);
-	weston_input_device_init(&input->base, &c->base);
+	weston_seat_init(&input->base, &c->base);
 
-	c->base.input_device = &input->base.input_device;
+	c->base.seat = &input->base;
 
 	return 0;
 }
@@ -107,11 +107,11 @@
 static void
 x11_input_destroy(struct x11_compositor *compositor)
 {
-	struct x11_input *input = container_of(compositor->base.input_device,
+	struct x11_input *input = container_of(compositor->base.seat,
 					       struct x11_input,
-					       base.input_device);
+					       base);
 
-	weston_input_device_release(&input->base);
+	weston_seat_release(&input->base);
 	free(input);
 }
 
@@ -500,31 +500,31 @@
 		break;
 	case 4:
 		if (state)
-			notify_axis(c->base.input_device,
+			notify_axis(&c->base.seat->seat,
 				      weston_compositor_get_time(),
-				      WL_INPUT_DEVICE_AXIS_VERTICAL_SCROLL, 1);
+				      WL_POINTER_AXIS_VERTICAL_SCROLL, 1);
 		return;
 	case 5:
 		if (state)
-			notify_axis(c->base.input_device,
+			notify_axis(&c->base.seat->seat,
 				      weston_compositor_get_time(),
-				      WL_INPUT_DEVICE_AXIS_VERTICAL_SCROLL, -1);
+				      WL_POINTER_AXIS_VERTICAL_SCROLL, -1);
 		return;
 	case 6:
 		if (state)
-			notify_axis(c->base.input_device,
+			notify_axis(&c->base.seat->seat,
 				      weston_compositor_get_time(),
-				      WL_INPUT_DEVICE_AXIS_HORIZONTAL_SCROLL, 1);
+				      WL_POINTER_AXIS_HORIZONTAL_SCROLL, 1);
 		return;
 	case 7:
 		if (state)
-			notify_axis(c->base.input_device,
+			notify_axis(&c->base.seat->seat,
 				      weston_compositor_get_time(),
-				      WL_INPUT_DEVICE_AXIS_HORIZONTAL_SCROLL, -1);
+				      WL_POINTER_AXIS_HORIZONTAL_SCROLL, -1);
 		return;
 	}
 
-	notify_button(c->base.input_device,
+	notify_button(&c->base.seat->seat,
 		      weston_compositor_get_time(), button, state);
 }
 
@@ -581,7 +581,7 @@
 				/* Deliver the held key release now
 				 * and fall through and handle the new
 				 * event below. */
-				notify_key(c->base.input_device,
+				notify_key(&c->base.seat->seat,
 					   weston_compositor_get_time(),
 					   key_release->detail - 8, 0);
 				free(prev);
@@ -604,7 +604,7 @@
 			}
 
 			output = x11_compositor_find_output(c, focus_in->event);
-			notify_keyboard_focus(c->base.input_device, &c->keys);
+			notify_keyboard_focus(&c->base.seat->seat, &c->keys);
 
 			free(prev);
 			prev = NULL;
@@ -618,7 +618,7 @@
 		switch (event->response_type & ~0x80) {
 		case XCB_KEY_PRESS:
 			key_press = (xcb_key_press_event_t *) event;
-			notify_key(c->base.input_device,
+			notify_key(&c->base.seat->seat,
 				   weston_compositor_get_time(),
 				   key_press->detail - 8, 1);
 			break;
@@ -636,7 +636,7 @@
 			output = x11_compositor_find_output(c, motion_notify->event);
 			x = wl_fixed_from_int(output->base.x + motion_notify->event_x);
 			y = wl_fixed_from_int(output->base.y + motion_notify->event_y);
-			notify_motion(c->base.input_device,
+			notify_motion(&c->base.seat->seat,
 				      weston_compositor_get_time(), x, y);
 			break;
 
@@ -655,7 +655,7 @@
 			x = wl_fixed_from_int(output->base.x + enter_notify->event_x);
 			y = wl_fixed_from_int(output->base.y + enter_notify->event_y);
 
-			notify_pointer_focus(c->base.input_device,
+			notify_pointer_focus(&c->base.seat->seat,
 					     &output->base, x, y);
 			break;
 
@@ -664,7 +664,7 @@
 			if (enter_notify->state >= Button1Mask)
 				break;
 			output = x11_compositor_find_output(c, enter_notify->event);
-			notify_pointer_focus(c->base.input_device, NULL, 0, 0);
+			notify_pointer_focus(&c->base.seat->seat, NULL, 0, 0);
 			break;
 
 		case XCB_CLIENT_MESSAGE:
@@ -687,7 +687,7 @@
 			if (focus_in->mode == XCB_NOTIFY_MODE_WHILE_GRABBED ||
 			    focus_in->mode == XCB_NOTIFY_MODE_UNGRAB)
 				break;
-			notify_keyboard_focus(c->base.input_device, NULL);
+			notify_keyboard_focus(&c->base.seat->seat, NULL);
 			break;
 
 		default:
@@ -701,7 +701,7 @@
 	switch (prev ? prev->response_type & ~0x80 : 0x80) {
 	case XCB_KEY_RELEASE:
 		key_release = (xcb_key_press_event_t *) prev;
-		notify_key(c->base.input_device,
+		notify_key(&c->base.seat->seat,
 			   weston_compositor_get_time(),
 			   key_release->detail - 8, 0);
 		free(prev);
diff --git a/src/compositor.c b/src/compositor.c
index f0d405d..622db58 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -608,59 +608,64 @@
 }
 
 static void
-weston_device_repick(struct wl_input_device *device)
+weston_device_repick(struct wl_seat *seat)
 {
-	struct weston_input_device *wd = (struct weston_input_device *) device;
+	struct weston_seat *ws = (struct weston_seat *) seat;
 	const struct wl_pointer_grab_interface *interface;
 	struct weston_surface *surface, *focus;
 
-	surface = weston_compositor_pick_surface(wd->compositor,
-						 device->x, device->y,
-						 &device->current_x,
-						 &device->current_y);
+	surface = weston_compositor_pick_surface(ws->compositor,
+						 seat->pointer->x,
+						 seat->pointer->y,
+						 &seat->pointer->current_x,
+						 &seat->pointer->current_y);
 
-	if (&surface->surface != device->current) {
-		interface = device->pointer_grab->interface;
-		interface->focus(device->pointer_grab, &surface->surface,
-				 device->current_x, device->current_y);
-		device->current = &surface->surface;
+	if (&surface->surface != seat->pointer->current) {
+		interface = seat->pointer->grab->interface;
+		interface->focus(seat->pointer->grab, &surface->surface,
+				 seat->pointer->current_x,
+				 seat->pointer->current_y);
+		seat->pointer->current = &surface->surface;
 	}
 
-	focus = (struct weston_surface *) device->pointer_grab->focus;
+	focus = (struct weston_surface *) seat->pointer->grab->focus;
 	if (focus)
-		weston_surface_from_global_fixed(focus, device->x, device->y,
-					         &device->pointer_grab->x,
-					         &device->pointer_grab->y);
+		weston_surface_from_global_fixed(focus,
+						 seat->pointer->x,
+						 seat->pointer->y,
+					         &seat->pointer->grab->x,
+					         &seat->pointer->grab->y);
 }
 
 WL_EXPORT void
 weston_compositor_repick(struct weston_compositor *compositor)
 {
-	struct weston_input_device *device;
+	struct weston_seat *seat;
 
 	if (!compositor->focus)
 		return;
 
-	wl_list_for_each(device, &compositor->input_device_list, link)
-		weston_device_repick(&device->input_device);
+	wl_list_for_each(seat, &compositor->seat_list, link)
+		weston_device_repick(&seat->seat);
 }
 
 static void
 weston_surface_unmap(struct weston_surface *surface)
 {
-	struct wl_input_device *device = surface->compositor->input_device;
+	struct wl_seat *seat = &surface->compositor->seat->seat;
 
 	weston_surface_damage_below(surface);
 	surface->output = NULL;
 	wl_list_remove(&surface->link);
 	wl_list_remove(&surface->layer_link);
 
-	if (device->keyboard_focus == &surface->surface)
-		wl_input_device_set_keyboard_focus(device, NULL);
-	if (device->pointer_focus == &surface->surface)
-		wl_input_device_set_pointer_focus(device, NULL,
-		                                  wl_fixed_from_int(0),
-						  wl_fixed_from_int(0));
+	if (seat->keyboard->focus == &surface->surface)
+		wl_keyboard_set_focus(seat->keyboard, NULL);
+	if (seat->pointer->focus == &surface->surface)
+		wl_pointer_set_focus(seat->pointer,
+				     NULL,
+		                     wl_fixed_from_int(0),
+				     wl_fixed_from_int(0));
 
 	weston_compositor_schedule_repaint(surface->compositor);
 }
@@ -1543,21 +1548,19 @@
 }
 
 static  void
-weston_input_update_drag_surface(struct wl_input_device *input_device,
-				 int dx, int dy);
+weston_seat_update_drag_surface(struct wl_seat *seat, int dx, int dy);
 
 static void
-clip_pointer_motion(struct weston_input_device *device,
-		    wl_fixed_t *fx, wl_fixed_t *fy)
+clip_pointer_motion(struct weston_seat *seat, wl_fixed_t *fx, wl_fixed_t *fy)
 {
-	struct weston_compositor *ec = device->compositor;
+	struct weston_compositor *ec = seat->compositor;
 	struct weston_output *output, *prev = NULL;
 	int x, y, old_x, old_y, valid = 0;
 
 	x = wl_fixed_to_int(*fx);
 	y = wl_fixed_to_int(*fy);
-	old_x = wl_fixed_to_int(device->input_device.x);
-	old_y = wl_fixed_to_int(device->input_device.y);
+	old_x = wl_fixed_to_int(seat->seat.pointer->x);
+	old_y = wl_fixed_to_int(seat->seat.pointer->y);
 
 	wl_list_for_each(output, &ec->output_list, link) {
 		if (pixman_region32_contains_point(&output->region,
@@ -1567,7 +1570,7 @@
 						   old_x, old_y, NULL))
 			prev = output;
 	}
-	
+
 	if (!valid) {
 		if (x < prev->x)
 			*fx = wl_fixed_from_int(prev->x);
@@ -1583,24 +1586,24 @@
 }
 
 WL_EXPORT void
-notify_motion(struct wl_input_device *device,
-	      uint32_t time, wl_fixed_t x, wl_fixed_t y)
+notify_motion(struct wl_seat *seat, uint32_t time, wl_fixed_t x, wl_fixed_t y)
 {
 	const struct wl_pointer_grab_interface *interface;
-	struct weston_input_device *wd = (struct weston_input_device *) device;
-	struct weston_compositor *ec = wd->compositor;
+	struct weston_seat *ws = (struct weston_seat *) seat;
+	struct weston_compositor *ec = ws->compositor;
 	struct weston_output *output;
 	int32_t ix, iy;
 
 	weston_compositor_activity(ec);
 
-	clip_pointer_motion(wd, &x, &y);
+	clip_pointer_motion(ws, &x, &y);
 
-	weston_input_update_drag_surface(device,
-					 x - device->x, y - device->y);
+	weston_seat_update_drag_surface(seat,
+					x - seat->pointer->x,
+					y - seat->pointer->y);
 
-	device->x = x;
-	device->y = y;
+	seat->pointer->x = x;
+	seat->pointer->y = y;
 
 	ix = wl_fixed_to_int(x);
 	iy = wl_fixed_to_int(y);
@@ -1611,73 +1614,75 @@
 						   ix, iy, NULL))
 			weston_output_update_zoom(output, x, y);
 
-	weston_device_repick(device);
-	interface = device->pointer_grab->interface;
-	interface->motion(device->pointer_grab, time,
-			  device->pointer_grab->x, device->pointer_grab->y);
+	weston_device_repick(seat);
+	interface = seat->pointer->grab->interface;
+	interface->motion(seat->pointer->grab, time,
+			  seat->pointer->grab->x, seat->pointer->grab->y);
 
-	if (wd->sprite) {
-		weston_surface_set_position(wd->sprite,
-					    ix - wd->hotspot_x,
-					    iy - wd->hotspot_y);
+	if (ws->sprite) {
+		weston_surface_set_position(ws->sprite,
+					    ix - ws->hotspot_x,
+					    iy - ws->hotspot_y);
 		weston_compositor_schedule_repaint(ec);
 	}
 }
 
 WL_EXPORT void
 weston_surface_activate(struct weston_surface *surface,
-			struct weston_input_device *device)
+			struct weston_seat *seat)
 {
-	struct weston_compositor *compositor = device->compositor;
+	struct weston_compositor *compositor = seat->compositor;
 
-	wl_input_device_set_keyboard_focus(&device->input_device,
-					   &surface->surface);
-	wl_data_device_set_keyboard_focus(&device->input_device);
+	wl_keyboard_set_focus(seat->seat.keyboard, &surface->surface);
+	wl_data_device_set_keyboard_focus(&seat->seat);
 
 	wl_signal_emit(&compositor->activate_signal, surface);
 }
 
 WL_EXPORT void
-notify_button(struct wl_input_device *device,
-	      uint32_t time, int32_t button, uint32_t state)
+notify_button(struct wl_seat *seat, uint32_t time, int32_t button,
+	      uint32_t state)
 {
-	struct weston_input_device *wd = (struct weston_input_device *) device;
-	struct weston_compositor *compositor = wd->compositor;
-	struct weston_surface *focus = (struct weston_surface *) device->pointer_focus;
+	struct weston_seat *ws = (struct weston_seat *) seat;
+	struct weston_compositor *compositor = ws->compositor;
+	struct weston_surface *focus =
+		(struct weston_surface *) seat->pointer->focus;
 	uint32_t serial = wl_display_next_serial(compositor->wl_display);
 
 	if (state) {
 		if (compositor->ping_handler && focus)
 			compositor->ping_handler(focus, serial);
 		weston_compositor_idle_inhibit(compositor);
-		if (device->button_count == 0) {
-			device->grab_button = button;
-			device->grab_time = time;
-			device->grab_x = device->x;
-			device->grab_y = device->y;
+		if (seat->pointer->button_count == 0) {
+			seat->pointer->grab_button = button;
+			seat->pointer->grab_time = time;
+			seat->pointer->grab_x = seat->pointer->x;
+			seat->pointer->grab_y = seat->pointer->y;
 		}
-		device->button_count++;
+		seat->pointer->button_count++;
 	} else {
 		weston_compositor_idle_release(compositor);
-		device->button_count--;
+		seat->pointer->button_count--;
 	}
 
-	weston_compositor_run_binding(compositor, wd, time, 0, button, 0, state);
+	weston_compositor_run_binding(compositor, ws, time, 0, button, 0,
+				      state);
 
-	device->pointer_grab->interface->button(device->pointer_grab, time, button, state);
+	seat->pointer->grab->interface->button(seat->pointer->grab, time,
+					       button, state);
 
-	if (device->button_count == 1)
-		device->grab_serial =
+	if (seat->pointer->button_count == 1)
+		seat->pointer->grab_serial =
 			wl_display_get_serial(compositor->wl_display);
 }
 
 WL_EXPORT void
-notify_axis(struct wl_input_device *device,
-	      uint32_t time, uint32_t axis, int32_t value)
+notify_axis(struct wl_seat *seat, uint32_t time, uint32_t axis, int32_t value)
 {
-	struct weston_input_device *wd = (struct weston_input_device *) device;
-	struct weston_compositor *compositor = wd->compositor;
-	struct weston_surface *focus = (struct weston_surface *) device->pointer_focus;
+	struct weston_seat *ws = (struct weston_seat *) seat;
+	struct weston_compositor *compositor = ws->compositor;
+	struct weston_surface *focus =
+		(struct weston_surface *) seat->pointer->focus;
 	uint32_t serial = wl_display_next_serial(compositor->wl_display);
 
 	if (compositor->ping_handler && focus)
@@ -1686,19 +1691,18 @@
 	weston_compositor_activity(compositor);
 
 	if (value)
-		weston_compositor_run_binding(compositor, wd,
-						time, 0, 0, axis, value);
+		weston_compositor_run_binding(compositor, ws,
+					      time, 0, 0, axis, value);
 	else
 		return;
 
-	if (device->pointer_focus_resource)
-		wl_resource_post_event(device->pointer_focus_resource,
-				WL_INPUT_DEVICE_AXIS, time, axis, value);
+	if (seat->pointer->focus_resource)
+		wl_resource_post_event(seat->pointer->focus_resource,
+				       WL_POINTER_AXIS, time, axis, value);
 }
 
 static void
-update_modifier_state(struct weston_input_device *device,
-		      uint32_t key, uint32_t state)
+update_modifier_state(struct weston_seat *seat, uint32_t key, uint32_t state)
 {
 	uint32_t modifier;
 
@@ -1724,18 +1728,18 @@
 	}
 
 	if (state)
-		device->modifier_state |= modifier;
+		seat->modifier_state |= modifier;
 	else
-		device->modifier_state &= ~modifier;
+		seat->modifier_state &= ~modifier;
 }
 
 WL_EXPORT void
-notify_key(struct wl_input_device *device,
-	   uint32_t time, uint32_t key, uint32_t state)
+notify_key(struct wl_seat *seat, uint32_t time, uint32_t key, uint32_t state)
 {
-	struct weston_input_device *wd = (struct weston_input_device *) device;
-	struct weston_compositor *compositor = wd->compositor;
-	struct weston_surface *focus = (struct weston_surface *) device->pointer_focus;
+	struct weston_seat *ws = (struct weston_seat *) seat;
+	struct weston_compositor *compositor = ws->compositor;
+	struct weston_surface *focus =
+		(struct weston_surface *) seat->pointer->focus;
 	uint32_t serial = wl_display_next_serial(compositor->wl_display);
 	uint32_t *k, *end;
 
@@ -1744,45 +1748,46 @@
 			compositor->ping_handler(focus, serial);
 
 		weston_compositor_idle_inhibit(compositor);
-		device->grab_key = key;
-		device->grab_time = time;
+		seat->keyboard->grab_key = key;
+		seat->keyboard->grab_time = time;
 	} else {
 		weston_compositor_idle_release(compositor);
 	}
 
-	update_modifier_state(wd, key, state);
-	end = device->keys.data + device->keys.size;
-	for (k = device->keys.data; k < end; k++) {
+	update_modifier_state(ws, key, state);
+	end = seat->keyboard->keys.data + seat->keyboard->keys.size;
+	for (k = seat->keyboard->keys.data; k < end; k++) {
 		if (*k == key)
 			*k = *--end;
 	}
-	device->keys.size = (void *) end - device->keys.data;
+	seat->keyboard->keys.size = (void *) end - seat->keyboard->keys.data;
 	if (state) {
-		k = wl_array_add(&device->keys, sizeof *k);
+		k = wl_array_add(&seat->keyboard->keys, sizeof *k);
 		*k = key;
 	}
 
-	if (device->keyboard_grab == &device->default_keyboard_grab)
-		weston_compositor_run_binding(compositor, wd,
+	if (seat->keyboard->grab == &seat->keyboard->default_grab)
+		weston_compositor_run_binding(compositor, ws,
 					      time, key, 0, 0, state);
 
-	device->keyboard_grab->interface->key(device->keyboard_grab,
-					      time, key, state);
+	seat->keyboard->grab->interface->key(seat->keyboard->grab,
+					     time, key, state);
 }
 
 WL_EXPORT void
-notify_pointer_focus(struct wl_input_device *device,
-		     struct weston_output *output, wl_fixed_t x, wl_fixed_t y)
+notify_pointer_focus(struct wl_seat *seat, struct weston_output *output,
+		     wl_fixed_t x, wl_fixed_t y)
 {
-	struct weston_input_device *wd = (struct weston_input_device *) device;
-	struct weston_compositor *compositor = wd->compositor;
+	struct weston_seat *ws = (struct weston_seat *) seat;
+	struct weston_compositor *compositor = ws->compositor;
 
 	if (output) {
-		weston_input_update_drag_surface(device,
-		                                 x - device->x, y - device->y);
+		weston_seat_update_drag_surface(seat,
+						x - seat->pointer->x,
+						y - seat->pointer->y);
 
-		device->x = x;
-		device->y = y;
+		seat->pointer->x = x;
+		seat->pointer->y = y;
 		compositor->focus = 1;
 		weston_compositor_repick(compositor);
 	} else {
@@ -1794,119 +1799,114 @@
 static void
 destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
 {
-	struct weston_input_device *wd;
+	struct weston_seat *ws;
 
-	wd = container_of(listener, struct weston_input_device,
+	ws = container_of(listener, struct weston_seat,
 			  saved_kbd_focus_listener);
 
-	wd->saved_kbd_focus = NULL;
+	ws->saved_kbd_focus = NULL;
 }
 
 WL_EXPORT void
-notify_keyboard_focus(struct wl_input_device *device, struct wl_array *keys)
+notify_keyboard_focus(struct wl_seat *seat, struct wl_array *keys)
 {
-	struct weston_input_device *wd =
-		(struct weston_input_device *) device;
-	struct weston_compositor *compositor = wd->compositor;
+	struct weston_seat *ws = (struct weston_seat *) seat;
+	struct weston_compositor *compositor = ws->compositor;
 	struct wl_surface *surface;
 	uint32_t *k;
 
 	if (keys) {
-		wl_array_copy(&wd->input_device.keys, keys);
-		wd->modifier_state = 0;
-		wl_array_for_each(k, &device->keys) {
+		wl_array_copy(&seat->keyboard->keys, keys);
+		ws->modifier_state = 0;
+		wl_array_for_each(k, &seat->keyboard->keys) {
 			weston_compositor_idle_inhibit(compositor);
-			update_modifier_state(wd, *k, 1);
+			update_modifier_state(ws, *k, 1);
 		}
 
-		surface = wd->saved_kbd_focus;
+		surface = ws->saved_kbd_focus;
 
 		if (surface) {
-			wl_list_remove(&wd->saved_kbd_focus_listener.link);
-			wl_input_device_set_keyboard_focus(&wd->input_device,
-							   surface);
-			wd->saved_kbd_focus = NULL;
+			wl_list_remove(&ws->saved_kbd_focus_listener.link);
+			wl_keyboard_set_focus(ws->seat.keyboard, surface);
+			ws->saved_kbd_focus = NULL;
 		}
 	} else {
-		wl_array_for_each(k, &device->keys)
+		wl_array_for_each(k, &seat->keyboard->keys)
 			weston_compositor_idle_release(compositor);
 
-		wd->modifier_state = 0;
+		ws->modifier_state = 0;
 
-		surface = wd->input_device.keyboard_focus;
+		surface = ws->seat.keyboard->focus;
 
 		if (surface) {
-			wd->saved_kbd_focus = surface;
-			wd->saved_kbd_focus_listener.notify =
+			ws->saved_kbd_focus = surface;
+			ws->saved_kbd_focus_listener.notify =
 				destroy_device_saved_kbd_focus;
 			wl_signal_add(&surface->resource.destroy_signal,
-				      &wd->saved_kbd_focus_listener);
+				      &ws->saved_kbd_focus_listener);
 		}
 
-		wl_input_device_set_keyboard_focus(&wd->input_device, NULL);
+		wl_keyboard_set_focus(ws->seat.keyboard, NULL);
 		/* FIXME: We really need keyboard grab cancel here to
 		 * let the grab shut down properly.  As it is we leak
 		 * the grab data. */
-		wl_input_device_end_keyboard_grab(&wd->input_device);
+		wl_keyboard_end_grab(ws->seat.keyboard);
 	}
 }
 
 static void
 lose_touch_focus_resource(struct wl_listener *listener, void *data)
 {
-	struct weston_input_device *device =
-		container_of(listener, struct weston_input_device,
-			     touch_focus_resource_listener);
+	struct weston_seat *seat = container_of(listener, struct weston_seat,
+						touch_focus_resource_listener);
 
-	device->touch_focus_resource = NULL;
+	seat->touch_focus_resource = NULL;
 }
 
 static void
 lose_touch_focus(struct wl_listener *listener, void *data)
 {
-	struct weston_input_device *device =
-		container_of(listener, struct weston_input_device,
-			     touch_focus_listener);
+	struct weston_seat *seat = container_of(listener, struct weston_seat,
+						touch_focus_listener);
 
-	device->touch_focus = NULL;
+	seat->touch_focus = NULL;
 }
 
 static void
-touch_set_focus(struct weston_input_device *device,
-		struct wl_surface *surface)
+touch_set_focus(struct weston_seat *ws, struct wl_surface *surface)
 {
-	struct wl_input_device *input_device = &device->input_device;
+	struct wl_seat *seat = &ws->seat;
 	struct wl_resource *resource;
 
-	if (device->touch_focus == surface)
+	if (ws->touch_focus == surface)
 		return;
 
 	if (surface) {
 		resource =
-			find_resource_for_client(&input_device->resource_list,
+			find_resource_for_client(&seat->touch->resource_list,
 						 surface->resource.client);
 		if (!resource) {
 			fprintf(stderr, "couldn't find resource\n");
 			return;
 		}
 
-		device->touch_focus_resource_listener.notify =
+		ws->touch_focus_resource_listener.notify =
 			lose_touch_focus_resource;
 		wl_signal_add(&resource->destroy_signal,
-			      &device->touch_focus_resource_listener);
-		device->touch_focus_listener.notify = lose_touch_focus;
+			      &ws->touch_focus_resource_listener);
+		ws->touch_focus_listener.notify = lose_touch_focus;
 		wl_signal_add(&surface->resource.destroy_signal,
-			       &device->touch_focus_listener);
+			       &ws->touch_focus_listener);
 
-		device->touch_focus = surface;
-		device->touch_focus_resource = resource;
+		seat->touch->focus = surface;
+		seat->touch->focus_resource = resource;
 	} else {
-		if (device->touch_focus)
-			wl_list_remove(&device->touch_focus_listener.link);
-		if (device->touch_focus_resource)
-			wl_list_remove(&device->touch_focus_resource_listener.link);
-		device->touch_focus = NULL;
-		device->touch_focus_resource = NULL;
+		if (seat->touch->focus)
+			wl_list_remove(&ws->touch_focus_listener.link);
+		if (seat->touch->focus_resource)
+			wl_list_remove(&ws->touch_focus_resource_listener.link);
+		seat->touch->focus = NULL;
+		seat->touch->focus_resource = NULL;
 	}
 }
 
@@ -1919,118 +1919,117 @@
  *
  */
 WL_EXPORT void
-notify_touch(struct wl_input_device *device, uint32_t time, int touch_id,
+notify_touch(struct wl_seat *seat, uint32_t time, int touch_id,
              wl_fixed_t x, wl_fixed_t y, int touch_type)
 {
-	struct weston_input_device *wd = (struct weston_input_device *) device;
-	struct weston_compositor *ec = wd->compositor;
+	struct weston_seat *ws = (struct weston_seat *) seat;
+	struct weston_compositor *ec = ws->compositor;
 	struct weston_surface *es;
 	wl_fixed_t sx, sy;
 	uint32_t serial = 0;
 
 	switch (touch_type) {
-	case WL_INPUT_DEVICE_TOUCH_DOWN:
+	case WL_TOUCH_DOWN:
 		weston_compositor_idle_inhibit(ec);
 
-		wd->num_tp++;
+		ws->num_tp++;
 
 		/* the first finger down picks the surface, and all further go
 		 * to that surface for the remainder of the touch session i.e.
 		 * until all touch points are up again. */
-		if (wd->num_tp == 1) {
+		if (ws->num_tp == 1) {
 			es = weston_compositor_pick_surface(ec, x, y, &sx, &sy);
-			touch_set_focus(wd, &es->surface);
-		} else if (wd->touch_focus) {
-			es = (struct weston_surface *) wd->touch_focus;
+			touch_set_focus(ws, &es->surface);
+		} else if (ws->touch_focus) {
+			es = (struct weston_surface *) ws->touch_focus;
 			weston_surface_from_global_fixed(es, x, y, &sx, &sy);
 		}
 
-		if (wd->touch_focus_resource && wd->touch_focus)
-			wl_input_device_send_touch_down(wd->touch_focus_resource,
-							serial, time,
-							&wd->touch_focus->resource,
-							touch_id, sx, sy);
+		if (ws->touch_focus_resource && ws->touch_focus)
+			wl_touch_send_down(ws->touch_focus_resource,
+					   serial, time,
+					   &ws->touch_focus->resource,
+					   touch_id, sx, sy);
 		break;
-	case WL_INPUT_DEVICE_TOUCH_MOTION:
-		es = (struct weston_surface *) wd->touch_focus;
+	case WL_TOUCH_MOTION:
+		es = (struct weston_surface *) ws->touch_focus;
 		if (!es)
 			break;
 
 		weston_surface_from_global_fixed(es, x, y, &sx, &sy);
-		if (wd->touch_focus_resource)
-			wl_input_device_send_touch_motion(wd->touch_focus_resource,
-							  time, touch_id, sx, sy);
+		if (ws->touch_focus_resource)
+			wl_touch_send_motion(ws->touch_focus_resource,
+					     time, touch_id, sx, sy);
 		break;
-	case WL_INPUT_DEVICE_TOUCH_UP:
+	case WL_TOUCH_UP:
 		weston_compositor_idle_release(ec);
-		wd->num_tp--;
+		ws->num_tp--;
 
-		if (wd->touch_focus_resource)
-			wl_input_device_send_touch_up(wd->touch_focus_resource,
-						      serial, time, touch_id);
-		if (wd->num_tp == 0)
-			touch_set_focus(wd, NULL);
+		if (ws->touch_focus_resource)
+			wl_touch_send_up(ws->touch_focus_resource,
+					 serial, time, touch_id);
+		if (ws->num_tp == 0)
+			touch_set_focus(ws, NULL);
 		break;
 	}
 }
 
 static void
-input_device_attach(struct wl_client *client,
-		    struct wl_resource *resource,
-		    uint32_t serial,
-		    struct wl_resource *buffer_resource, int32_t x, int32_t y)
+pointer_attach(struct wl_client *client, struct wl_resource *resource,
+	       uint32_t serial, struct wl_resource *buffer_resource,
+	       int32_t x, int32_t y)
 {
-	struct weston_input_device *device = resource->data;
-	struct weston_compositor *compositor = device->compositor;
+	struct weston_seat *seat = resource->data;
+	struct weston_compositor *compositor = seat->compositor;
 	struct wl_buffer *buffer = NULL;
 
-	if (serial < device->input_device.pointer_focus_serial)
+	if (serial < seat->seat.pointer->focus_serial)
 		return;
-	if (device->input_device.pointer_focus == NULL)
+	if (seat->seat.pointer->focus == NULL)
 		return;
-	if (device->input_device.pointer_focus->resource.client != client)
+	if (seat->seat.pointer->focus->resource.client != client)
 		return;
 
 	if (buffer_resource)
 		buffer = buffer_resource->data;
 
-	weston_surface_attach(&device->sprite->surface, buffer);
-	empty_region(&device->sprite->input);
+	weston_surface_attach(&seat->sprite->surface, buffer);
+	empty_region(&seat->sprite->input);
 
 	if (!buffer)
 		return;
 
-	if (!weston_surface_is_mapped(device->sprite)) {
+	if (!weston_surface_is_mapped(seat->sprite)) {
 		wl_list_insert(&compositor->cursor_layer.surface_list,
-			       &device->sprite->layer_link);
-		weston_surface_assign_output(device->sprite);
+			       &seat->sprite->layer_link);
+		weston_surface_assign_output(seat->sprite);
 	}
 
 
-	device->hotspot_x = x;
-	device->hotspot_y = y;
-	weston_surface_configure(device->sprite,
-				 wl_fixed_to_int(device->input_device.x) - x,
-				 wl_fixed_to_int(device->input_device.y) - y,
+	seat->hotspot_x = x;
+	seat->hotspot_y = y;
+	weston_surface_configure(seat->sprite,
+				 wl_fixed_to_int(seat->seat.pointer->x) - x,
+				 wl_fixed_to_int(seat->seat.pointer->y) - y,
 				 buffer->width, buffer->height);
 
-	surface_damage(NULL, &device->sprite->surface.resource,
+	surface_damage(NULL, &seat->sprite->surface.resource,
 		       0, 0, buffer->width, buffer->height);
 }
 
-static const struct wl_input_device_interface input_device_interface = {
-	input_device_attach,
+static const struct wl_pointer_interface pointer_interface = {
+	pointer_attach,
 };
 
 static void
 handle_drag_surface_destroy(struct wl_listener *listener, void *data)
 {
-	struct weston_input_device *device;
+	struct weston_seat *seat;
 
-	device = container_of(listener, struct weston_input_device,
-			      drag_surface_destroy_listener);
+	seat = container_of(listener, struct weston_seat,
+			    drag_surface_destroy_listener);
 
-	device->drag_surface = NULL;
+	seat->drag_surface = NULL;
 }
 
 static void unbind_resource(struct wl_resource *resource)
@@ -2040,67 +2039,131 @@
 }
 
 static void
-bind_input_device(struct wl_client *client,
-		  void *data, uint32_t version, uint32_t id)
+seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
+		 uint32_t id)
 {
-	struct wl_input_device *device = data;
-	struct wl_resource *resource;
+	struct weston_seat *seat = resource->data;
+	struct wl_resource *cr;
 
-	resource = wl_client_add_object(client, &wl_input_device_interface,
-					&input_device_interface, id, data);
-	wl_list_insert(&device->resource_list, &resource->link);
+	if (!seat->seat.pointer)
+		return;
+
+        cr = wl_client_add_object(client, &wl_pointer_interface,
+				  &pointer_interface, id, seat);
+	wl_list_insert(&seat->seat.pointer->resource_list, &cr->link);
+}
+
+static void
+seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
+		  uint32_t id)
+{
+	struct weston_seat *seat = resource->data;
+	struct wl_resource *cr;
+
+	if (!seat->seat.keyboard)
+		return;
+
+        cr = wl_client_add_object(client, &wl_keyboard_interface, NULL, id,
+				  seat);
+	wl_list_insert(&seat->seat.keyboard->resource_list, &cr->link);
+}
+
+static void
+seat_get_touch(struct wl_client *client, struct wl_resource *resource,
+	       uint32_t id)
+{
+	struct weston_seat *seat = resource->data;
+	struct wl_resource *cr;
+
+	if (!seat->seat.touch)
+		return;
+
+        cr = wl_client_add_object(client, &wl_touch_interface, NULL, id, seat);
+	wl_list_insert(&seat->seat.touch->resource_list, &cr->link);
+}
+
+static const struct wl_seat_interface seat_interface = {
+	seat_get_pointer,
+	seat_get_keyboard,
+	seat_get_touch,
+};
+
+static void
+bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+	struct wl_seat *seat = data;
+	struct wl_resource *resource;
+	enum wl_seat_capability caps = 0;
+
+	resource = wl_client_add_object(client, &wl_seat_interface,
+					&seat_interface, id, data);
+	wl_list_insert(&seat->base_resource_list, &resource->link);
 	resource->destroy = unbind_resource;
+
+	if (seat->pointer)
+		caps |= WL_SEAT_CAPABILITY_POINTER;
+	if (seat->keyboard)
+		caps |= WL_SEAT_CAPABILITY_KEYBOARD;
+	if (seat->touch)
+		caps |= WL_SEAT_CAPABILITY_TOUCH;
+
+	wl_seat_send_capabilities(resource, caps);
 }
 
 static void
 device_handle_new_drag_icon(struct wl_listener *listener, void *data)
 {
-	struct weston_input_device *device;
+	struct weston_seat *seat;
 
-	device = container_of(listener, struct weston_input_device,
-			      new_drag_icon_listener);
+	seat = container_of(listener, struct weston_seat,
+			    new_drag_icon_listener);
 
-	weston_input_update_drag_surface(&device->input_device, 0, 0);
+	weston_seat_update_drag_surface(&seat->seat, 0, 0);
 }
 
 WL_EXPORT void
-weston_input_device_init(struct weston_input_device *device,
-			 struct weston_compositor *ec)
+weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec)
 {
-	wl_input_device_init(&device->input_device);
+	wl_seat_init(&seat->seat);
+	wl_pointer_init(&seat->pointer);
+	wl_seat_set_pointer(&seat->seat, &seat->pointer);
+	wl_keyboard_init(&seat->keyboard);
+	wl_seat_set_keyboard(&seat->seat, &seat->keyboard);
+	wl_touch_init(&seat->touch);
+	wl_seat_set_touch(&seat->seat, &seat->touch);
 
-	wl_display_add_global(ec->wl_display, &wl_input_device_interface,
-			      device, bind_input_device);
+	wl_display_add_global(ec->wl_display, &wl_seat_interface, seat,
+			      bind_seat);
 
-	device->sprite = weston_surface_create(ec);
-	device->sprite->surface.resource.data = device->sprite;
+	seat->sprite = weston_surface_create(ec);
+	seat->sprite->surface.resource.data = seat->sprite;
 
-	device->compositor = ec;
-	device->hotspot_x = 16;
-	device->hotspot_y = 16;
-	device->modifier_state = 0;
-	device->num_tp = 0;
+	seat->compositor = ec;
+	seat->hotspot_x = 16;
+	seat->hotspot_y = 16;
+	seat->modifier_state = 0;
+	seat->num_tp = 0;
 
-	device->drag_surface_destroy_listener.notify =
+	seat->drag_surface_destroy_listener.notify =
 		handle_drag_surface_destroy;
 
-	wl_list_insert(ec->input_device_list.prev, &device->link);
+	wl_list_insert(ec->seat_list.prev, &seat->link);
 
-	device->new_drag_icon_listener.notify = device_handle_new_drag_icon;
-	wl_signal_add(&device->input_device.drag_icon_signal,
-		      &device->new_drag_icon_listener);
+	seat->new_drag_icon_listener.notify = device_handle_new_drag_icon;
+	wl_signal_add(&seat->seat.drag_icon_signal,
+		      &seat->new_drag_icon_listener);
 }
 
 WL_EXPORT void
-weston_input_device_release(struct weston_input_device *device)
+weston_seat_release(struct weston_seat *seat)
 {
-	wl_list_remove(&device->link);
+	wl_list_remove(&seat->link);
 	/* The global object is destroyed at wl_display_destroy() time. */
 
-	if (device->sprite)
-		destroy_surface(&device->sprite->surface.resource);
+	if (seat->sprite)
+		destroy_surface(&seat->sprite->surface.resource);
 
-	wl_input_device_release(&device->input_device);
+	wl_seat_release(&seat->seat);
 }
 
 static void
@@ -2112,10 +2175,10 @@
 }
 
 static int
-device_setup_new_drag_surface(struct weston_input_device *device,
+device_setup_new_drag_surface(struct weston_seat *ws,
 			      struct weston_surface *surface)
 {
-	struct wl_input_device *input_device = &device->input_device;
+	struct wl_seat *seat = &ws->seat;
 
 	if (surface->configure) {
 		wl_resource_post_error(&surface->surface.resource,
@@ -2124,93 +2187,92 @@
 		return 0;
 	}
 
-	device->drag_surface = surface;
+	ws->drag_surface = surface;
 
-	weston_surface_set_position(device->drag_surface,
-				    wl_fixed_to_double(input_device->x),
-				    wl_fixed_to_double(input_device->y));
+	weston_surface_set_position(ws->drag_surface,
+				    wl_fixed_to_double(seat->pointer->x),
+				    wl_fixed_to_double(seat->pointer->y));
 
 	surface->configure = drag_surface_configure;
 
 	wl_signal_add(&surface->surface.resource.destroy_signal,
-		       &device->drag_surface_destroy_listener);
+		       &ws->drag_surface_destroy_listener);
 
 	return 1;
 }
 
 static void
-device_release_drag_surface(struct weston_input_device *device)
+device_release_drag_surface(struct weston_seat *seat)
 {
-	device->drag_surface->configure = NULL;
-	undef_region(&device->drag_surface->input);
-	wl_list_remove(&device->drag_surface_destroy_listener.link);
-	device->drag_surface = NULL;
+	seat->drag_surface->configure = NULL;
+	undef_region(&seat->drag_surface->input);
+	wl_list_remove(&seat->drag_surface_destroy_listener.link);
+	seat->drag_surface = NULL;
 }
 
 static void
-device_map_drag_surface(struct weston_input_device *device)
+device_map_drag_surface(struct weston_seat *seat)
 {
-	if (weston_surface_is_mapped(device->drag_surface) ||
-	    !device->drag_surface->buffer)
+	if (weston_surface_is_mapped(seat->drag_surface) ||
+	    !seat->drag_surface->buffer)
 		return;
 
-	wl_list_insert(&device->sprite->layer_link,
-		       &device->drag_surface->layer_link);
-	weston_surface_assign_output(device->drag_surface);
-	empty_region(&device->drag_surface->input);
+	wl_list_insert(&seat->sprite->layer_link,
+		       &seat->drag_surface->layer_link);
+	weston_surface_assign_output(seat->drag_surface);
+	empty_region(&seat->drag_surface->input);
 }
 
 static  void
-weston_input_update_drag_surface(struct wl_input_device *input_device,
-				 int dx, int dy)
+weston_seat_update_drag_surface(struct wl_seat *seat,
+				int dx, int dy)
 {
 	int surface_changed = 0;
-	struct weston_input_device *device = (struct weston_input_device *)
-		input_device;
+	struct weston_seat *ws = (struct weston_seat *) seat;
 
-	if (!device->drag_surface && !input_device->drag_surface)
+	if (!ws->drag_surface && !seat->drag_surface)
 		return;
 
-	if (device->drag_surface && input_device->drag_surface &&
-	    (&device->drag_surface->surface.resource !=
-	     &input_device->drag_surface->resource))
+	if (ws->drag_surface && seat->drag_surface &&
+	    (&ws->drag_surface->surface.resource !=
+	     &seat->drag_surface->resource))
 		/* between calls to this funcion we got a new drag_surface */
 		surface_changed = 1;
 
-	if (!input_device->drag_surface || surface_changed) {
-		device_release_drag_surface(device);
+	if (!seat->drag_surface || surface_changed) {
+		device_release_drag_surface(ws);
 		if (!surface_changed)
 			return;
 	}
 
-	if (!device->drag_surface || surface_changed) {
+	if (!ws->drag_surface || surface_changed) {
 		struct weston_surface *surface = (struct weston_surface *)
-			input_device->drag_surface;
-		if (!device_setup_new_drag_surface(device, surface))
+			seat->drag_surface;
+		if (!device_setup_new_drag_surface(ws, surface))
 			return;
 	}
 
 	/* the client may not have attached a buffer to the drag surface
 	 * when we setup it up, so check if map is needed on every update */
-	device_map_drag_surface(device);
+	device_map_drag_surface(ws);
 
 	/* the client may have attached a buffer with a different size to
 	 * the drag surface, causing the input region to be reset */
-	if (region_is_undefined(&device->drag_surface->input))
-		empty_region(&device->drag_surface->input);
+	if (region_is_undefined(&ws->drag_surface->input))
+		empty_region(&ws->drag_surface->input);
 
 	if (!dx && !dy)
 		return;
 
-	weston_surface_set_position(device->drag_surface,
-				    device->drag_surface->geometry.x + wl_fixed_to_double(dx),
-				    device->drag_surface->geometry.y + wl_fixed_to_double(dy));
+	weston_surface_set_position(ws->drag_surface,
+				    ws->drag_surface->geometry.x + wl_fixed_to_double(dx),
+				    ws->drag_surface->geometry.y + wl_fixed_to_double(dy));
 }
 
 WL_EXPORT void
 weston_compositor_update_drag_surfaces(struct weston_compositor *compositor)
 {
-	weston_input_update_drag_surface(compositor->input_device, 0, 0);
+	weston_seat_update_drag_surface(&compositor->seat->seat, 0, 0);
 }
 
 static void
@@ -2545,7 +2607,7 @@
 
 	wl_list_init(&ec->surface_list);
 	wl_list_init(&ec->layer_list);
-	wl_list_init(&ec->input_device_list);
+	wl_list_init(&ec->seat_list);
 	wl_list_init(&ec->output_list);
 	wl_list_init(&ec->binding_list);
 	wl_list_init(&ec->animation_list);
diff --git a/src/compositor.h b/src/compositor.h
index 6fe0f49..2e66f22 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -45,7 +45,7 @@
 
 struct weston_surface;
 struct shell_surface;
-struct weston_input_device;
+struct weston_seat;
 struct weston_output;
 
 struct weston_mode {
@@ -131,8 +131,11 @@
 	void (*set_dpms)(struct weston_output *output, enum dpms_enum level);
 };
 
-struct weston_input_device {
-	struct wl_input_device input_device;
+struct weston_seat {
+	struct wl_seat seat;
+	struct wl_pointer pointer;
+	struct wl_keyboard keyboard;
+	struct wl_touch touch;
 	struct weston_compositor *compositor;
 	struct weston_surface *sprite;
 	struct weston_surface *drag_surface;
@@ -213,13 +216,13 @@
 	struct wl_event_source *input_loop_source;
 
 	/* There can be more than one, but not right now... */
-	struct wl_input_device *input_device;
+	struct weston_seat *seat;
 
 	struct weston_layer fade_layer;
 	struct weston_layer cursor_layer;
 
 	struct wl_list output_list;
-	struct wl_list input_device_list;
+	struct wl_list seat_list;
 	struct wl_list layer_list;
 	struct wl_list surface_list;
 	struct wl_list binding_list;
@@ -419,34 +422,33 @@
 
 void
 weston_surface_activate(struct weston_surface *surface,
-			struct weston_input_device *device);
+			struct weston_seat *seat);
 void
 weston_surface_draw(struct weston_surface *es,
 		    struct weston_output *output, pixman_region32_t *damage);
 
 void
-notify_motion(struct wl_input_device *device,
-	      uint32_t time, wl_fixed_t x, wl_fixed_t y);
+notify_motion(struct wl_seat *seat, uint32_t time,
+	      wl_fixed_t x, wl_fixed_t y);
 void
-notify_button(struct wl_input_device *device,
-	      uint32_t time, int32_t button, uint32_t state);
+notify_button(struct wl_seat *seat, uint32_t time, int32_t button,
+	      uint32_t state);
 void
-notify_axis(struct wl_input_device *device,
-	      uint32_t time, uint32_t axis, int32_t value);
+notify_axis(struct wl_seat *seat, uint32_t time, uint32_t axis,
+	    int32_t value);
 void
-notify_key(struct wl_input_device *device,
-	   uint32_t time, uint32_t key, uint32_t state);
+notify_key(struct wl_seat *seat, uint32_t time, uint32_t key,
+	   uint32_t state);
 
 void
-notify_pointer_focus(struct wl_input_device *device,
-		     struct weston_output *output,
+notify_pointer_focus(struct wl_seat *seat, struct weston_output *output,
 		     wl_fixed_t x, wl_fixed_t y);
 
 void
-notify_keyboard_focus(struct wl_input_device *device, struct wl_array *keys);
+notify_keyboard_focus(struct wl_seat *seat, struct wl_array *keys);
 
 void
-notify_touch(struct wl_input_device *device, uint32_t time, int touch_id,
+notify_touch(struct wl_seat *seat, uint32_t time, int touch_id,
 	     wl_fixed_t x, wl_fixed_t y, int touch_type);
 
 void
@@ -477,7 +479,7 @@
 
 
 struct weston_binding;
-typedef void (*weston_binding_handler_t)(struct wl_input_device *device,
+typedef void (*weston_binding_handler_t)(struct wl_seat *seat,
 					 uint32_t time, uint32_t key,
 					 uint32_t button,
 					 uint32_t axis,
@@ -495,7 +497,7 @@
 
 void
 weston_compositor_run_binding(struct weston_compositor *compositor,
-			      struct weston_input_device *device,
+			      struct weston_seat *seat,
 			      uint32_t time,
 			      uint32_t key, uint32_t button, uint32_t axis,
 			      int32_t value);
@@ -554,11 +556,10 @@
 weston_output_destroy(struct weston_output *output);
 
 void
-weston_input_device_init(struct weston_input_device *device,
-			 struct weston_compositor *ec);
+weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec);
 
 void
-weston_input_device_release(struct weston_input_device *device);
+weston_seat_release(struct weston_seat *seat);
 
 enum {
 	TTY_ENTER_VT,
diff --git a/src/evdev.c b/src/evdev.c
index 22634aa..26002b4 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -32,8 +32,8 @@
 #include "evdev.h"
 #include "launcher-util.h"
 
-struct evdev_input {
-	struct weston_input_device base;
+struct evdev_seat {
+	struct weston_seat base;
 	struct wl_list devices_list;
 	struct udev_monitor *udev_monitor;
 	struct wl_event_source *udev_monitor_source;
@@ -43,7 +43,7 @@
 #define MAX_SLOTS 16
 
 struct evdev_input_device {
-	struct evdev_input *master;
+	struct evdev_seat *master;
 	struct wl_list link;
 	struct wl_event_source *source;
 	struct weston_output *output;
@@ -120,12 +120,12 @@
 	case BTN_FORWARD:
 	case BTN_BACK:
 	case BTN_TASK:
-		notify_button(&device->master->base.input_device,
+		notify_button(&device->master->base.seat,
 			      time, e->code, e->value);
 		break;
 
 	default:
-		notify_key(&device->master->base.input_device,
+		notify_key(&device->master->base.seat,
 			   time, e->code, e->value);
 		break;
 	}
@@ -245,14 +245,14 @@
 		device->type |= EVDEV_RELATIVE_MOTION;
 		break;
 	case REL_WHEEL:
-		notify_axis(&device->master->base.input_device,
+		notify_axis(&device->master->base.seat,
 			      time,
-			      WL_INPUT_DEVICE_AXIS_VERTICAL_SCROLL, e->value);
+			      WL_POINTER_AXIS_VERTICAL_SCROLL, e->value);
 		break;
 	case REL_HWHEEL:
-		notify_axis(&device->master->base.input_device,
+		notify_axis(&device->master->base.seat,
 			      time,
-			      WL_INPUT_DEVICE_AXIS_HORIZONTAL_SCROLL, e->value);
+			      WL_POINTER_AXIS_HORIZONTAL_SCROLL, e->value);
 		break;
 	}
 }
@@ -296,44 +296,44 @@
 static void
 evdev_flush_motion(struct evdev_input_device *device, uint32_t time)
 {
-	struct wl_input_device *master = &device->master->base.input_device;
+	struct weston_seat *master = &device->master->base;
 
 	if (!device->type)
 		return;
 
 	if (device->type & EVDEV_RELATIVE_MOTION) {
-		notify_motion(master, time,
-			      master->x + device->rel.dx,
-			      master->y + device->rel.dy);
+		notify_motion(&master->seat, time,
+			      master->seat.pointer->x + device->rel.dx,
+			      master->seat.pointer->y + device->rel.dy);
 		device->type &= ~EVDEV_RELATIVE_MOTION;
 		device->rel.dx = 0;
 		device->rel.dy = 0;
 	}
 	if (device->type & EVDEV_ABSOLUTE_MT_DOWN) {
-		notify_touch(master, time,
+		notify_touch(&master->seat, time,
 			     device->mt.slot,
 			     wl_fixed_from_int(device->mt.x[device->mt.slot]),
 			     wl_fixed_from_int(device->mt.y[device->mt.slot]),
-			     WL_INPUT_DEVICE_TOUCH_DOWN);
+			     WL_TOUCH_DOWN);
 		device->type &= ~EVDEV_ABSOLUTE_MT_DOWN;
 		device->type &= ~EVDEV_ABSOLUTE_MT_MOTION;
 	}
 	if (device->type & EVDEV_ABSOLUTE_MT_MOTION) {
-		notify_touch(master, time,
+		notify_touch(&master->seat, time,
 			     device->mt.slot,
 			     wl_fixed_from_int(device->mt.x[device->mt.slot]),
 			     wl_fixed_from_int(device->mt.y[device->mt.slot]),
-			     WL_INPUT_DEVICE_TOUCH_MOTION);
+			     WL_TOUCH_MOTION);
 		device->type &= ~EVDEV_ABSOLUTE_MT_DOWN;
 		device->type &= ~EVDEV_ABSOLUTE_MT_MOTION;
 	}
 	if (device->type & EVDEV_ABSOLUTE_MT_UP) {
-		notify_touch(master, time, device->mt.slot, 0, 0,
-			     WL_INPUT_DEVICE_TOUCH_UP);
+		notify_touch(&master->seat, time, device->mt.slot, 0, 0,
+			     WL_TOUCH_UP);
 		device->type &= ~EVDEV_ABSOLUTE_MT_UP;
 	}
 	if (device->type & EVDEV_ABSOLUTE_MOTION) {
-		notify_motion(master, time,
+		notify_motion(&master->seat, time,
 			      wl_fixed_from_int(device->abs.x),
 			      wl_fixed_from_int(device->abs.y));
 		device->type &= ~EVDEV_ABSOLUTE_MOTION;
@@ -472,7 +472,7 @@
 }
 
 static struct evdev_input_device *
-evdev_input_device_create(struct evdev_input *master,
+evdev_input_device_create(struct evdev_seat *master,
 			  struct wl_display *display, const char *path)
 {
 	struct evdev_input_device *device;
@@ -532,7 +532,7 @@
 static const char default_seat[] = "seat0";
 
 static void
-device_added(struct udev_device *udev_device, struct evdev_input *master)
+device_added(struct udev_device *udev_device, struct evdev_seat *master)
 {
 	struct weston_compositor *c;
 	const char *devnode;
@@ -563,7 +563,7 @@
 }
 
 static void
-evdev_notify_keyboard_focus(struct evdev_input *input)
+evdev_notify_keyboard_focus(struct evdev_seat *seat)
 {
 	struct evdev_input_device *device;
 	struct wl_array keys;
@@ -573,7 +573,7 @@
 	int ret;
 
 	memset(all_keys, 0, sizeof all_keys);
-	wl_list_for_each(device, &input->devices_list, link) {
+	wl_list_for_each(device, &seat->devices_list, link) {
 		memset(evdev_keys, 0, sizeof evdev_keys);
 		ret = ioctl(device->fd,
 			    EVIOCGKEY(sizeof evdev_keys), evdev_keys);
@@ -595,15 +595,15 @@
 		}
 	}
 
-	notify_keyboard_focus(&input->base.input_device, &keys);
+	notify_keyboard_focus(&seat->base.seat, &keys);
 
 	wl_array_release(&keys);
 }
 
 void
-evdev_add_devices(struct udev *udev, struct weston_input_device *input_base)
+evdev_add_devices(struct udev *udev, struct weston_seat *seat_base)
 {
-	struct evdev_input *input = (struct evdev_input *) input_base;
+	struct evdev_seat *seat = (struct evdev_seat *) seat_base;
 	struct udev_enumerate *e;
 	struct udev_list_entry *entry;
 	struct udev_device *device;
@@ -622,15 +622,15 @@
 			continue;
 		}
 
-		device_added(device, input);
+		device_added(device, seat);
 
 		udev_device_unref(device);
 	}
 	udev_enumerate_unref(e);
 
-	evdev_notify_keyboard_focus(input);
+	evdev_notify_keyboard_focus(seat);
 
-	if (wl_list_empty(&input->devices_list)) {
+	if (wl_list_empty(&seat->devices_list)) {
 		fprintf(stderr,
 			"warning: no input devices on entering Weston. "
 			"Possible causes:\n"
@@ -644,7 +644,7 @@
 static int
 evdev_udev_handler(int fd, uint32_t mask, void *data)
 {
-	struct evdev_input *master = data;
+	struct evdev_seat *master = data;
 	struct udev_device *udev_device;
 	struct evdev_input_device *device, *next;
 	const char *action;
@@ -678,9 +678,9 @@
 }
 
 int
-evdev_enable_udev_monitor(struct udev *udev, struct weston_input_device *input_base)
+evdev_enable_udev_monitor(struct udev *udev, struct weston_seat *seat_base)
 {
-	struct evdev_input *master = (struct evdev_input *) input_base;
+	struct evdev_seat *master = (struct evdev_seat *) seat_base;
 	struct wl_event_loop *loop;
 	struct weston_compositor *c = master->base.compositor;
 	int fd;
@@ -714,66 +714,66 @@
 }
 
 void
-evdev_disable_udev_monitor(struct weston_input_device *input_base)
+evdev_disable_udev_monitor(struct weston_seat *seat_base)
 {
-	struct evdev_input *input = (struct evdev_input *) input_base;
+	struct evdev_seat *seat = (struct evdev_seat *) seat_base;
 
-	if (!input->udev_monitor)
+	if (!seat->udev_monitor)
 		return;
 
-	udev_monitor_unref(input->udev_monitor);
-	input->udev_monitor = NULL;
-	wl_event_source_remove(input->udev_monitor_source);
-	input->udev_monitor_source = NULL;
+	udev_monitor_unref(seat->udev_monitor);
+	seat->udev_monitor = NULL;
+	wl_event_source_remove(seat->udev_monitor_source);
+	seat->udev_monitor_source = NULL;
 }
 
 void
 evdev_input_create(struct weston_compositor *c, struct udev *udev,
-		   const char *seat)
+		   const char *seat_id)
 {
-	struct evdev_input *input;
+	struct evdev_seat *seat;
 
-	input = malloc(sizeof *input);
-	if (input == NULL)
+	seat = malloc(sizeof *seat);
+	if (seat == NULL)
 		return;
 
-	memset(input, 0, sizeof *input);
-	weston_input_device_init(&input->base, c);
+	memset(seat, 0, sizeof *seat);
+	weston_seat_init(&seat->base, c);
 
-	wl_list_init(&input->devices_list);
-	input->seat_id = strdup(seat);
-	if (!evdev_enable_udev_monitor(udev, &input->base)) {
-		free(input->seat_id);
-		free(input);
+	wl_list_init(&seat->devices_list);
+	seat->seat_id = strdup(seat_id);
+	if (!evdev_enable_udev_monitor(udev, &seat->base)) {
+		free(seat->seat_id);
+		free(seat);
 		return;
 	}
 
-	evdev_add_devices(udev, &input->base);
+	evdev_add_devices(udev, &seat->base);
 
-	c->input_device = &input->base.input_device;
+	c->seat = &seat->base;
 }
 
 void
-evdev_remove_devices(struct weston_input_device *input_base)
+evdev_remove_devices(struct weston_seat *seat_base)
 {
-	struct evdev_input *input = (struct evdev_input *) input_base;
+	struct evdev_seat *seat = (struct evdev_seat *) seat_base;
 	struct evdev_input_device *device, *next;
 
-	wl_list_for_each_safe(device, next, &input->devices_list, link)
+	wl_list_for_each_safe(device, next, &seat->devices_list, link)
 		device_removed(device);
 
-	notify_keyboard_focus(&input->base.input_device, NULL);
+	notify_keyboard_focus(&seat->base.seat, NULL);
 }
 
 void
-evdev_input_destroy(struct weston_input_device *input_base)
+evdev_input_destroy(struct weston_seat *seat_base)
 {
-	struct evdev_input *input = (struct evdev_input *) input_base;
+	struct evdev_seat *seat = (struct evdev_seat *) seat_base;
 
-	evdev_remove_devices(input_base);
-	evdev_disable_udev_monitor(&input->base);
+	evdev_remove_devices(seat_base);
+	evdev_disable_udev_monitor(&seat->base);
 
-	wl_list_remove(&input->base.link);
-	free(input->seat_id);
-	free(input);
+	wl_list_remove(&seat->base.link);
+	free(seat->seat_id);
+	free(seat);
 }
diff --git a/src/evdev.h b/src/evdev.h
index b05c855..8e3214d 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -23,21 +23,20 @@
 #include <libudev.h>
 
 void
-evdev_add_devices(struct udev *udev, struct weston_input_device
-		  *input_base);
+evdev_add_devices(struct udev *udev, struct weston_seat *seat_base);
 
 void
-evdev_remove_devices(struct weston_input_device *input_base);
+evdev_remove_devices(struct weston_seat *seat_base);
 
 void
 evdev_input_create(struct weston_compositor *c, struct udev *udev,
 		   const char *seat);
 
 void
-evdev_input_destroy(struct weston_input_device *input_base);
+evdev_input_destroy(struct weston_seat *seat);
 
 int
-evdev_enable_udev_monitor(struct udev *udev, struct weston_input_device *input_base);
+evdev_enable_udev_monitor(struct udev *udev, struct weston_seat *seat_base);
 
 void
-evdev_disable_udev_monitor(struct weston_input_device *input_base);
+evdev_disable_udev_monitor(struct weston_seat *seat_base);
diff --git a/src/screenshooter.c b/src/screenshooter.c
index 90dd497..fcf85e9 100644
--- a/src/screenshooter.c
+++ b/src/screenshooter.c
@@ -193,7 +193,7 @@
 }
 
 static void
-screenshooter_binding(struct wl_input_device *device, uint32_t time,
+screenshooter_binding(struct wl_seat *seat, uint32_t time,
 		 uint32_t key, uint32_t button, uint32_t axis,
 		 int32_t state, void *data)
 {
diff --git a/src/shell.c b/src/shell.c
index 95d08c6..f11f573 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -132,7 +132,7 @@
 		int32_t x, y;
 		struct weston_transform parent_transform;
 		int32_t initial_up;
-		struct wl_input_device *device;
+		struct wl_seat *seat;
 		uint32_t serial;
 	} popup;
 
@@ -314,11 +314,11 @@
 		 uint32_t time, wl_fixed_t x, wl_fixed_t y)
 {
 	struct weston_move_grab *move = (struct weston_move_grab *) grab;
-	struct wl_input_device *device = grab->input_device;
+	struct wl_pointer *pointer = grab->pointer;
 	struct shell_surface *shsurf = move->base.shsurf;
 	struct weston_surface *es;
-	int dx = wl_fixed_to_int(device->x + move->dx);
-	int dy = wl_fixed_to_int(device->y + move->dy);
+	int dx = wl_fixed_to_int(pointer->x + move->dx);
+	int dy = wl_fixed_to_int(pointer->y + move->dy);
 
 	if (!shsurf)
 		return;
@@ -335,11 +335,11 @@
 {
 	struct shell_grab *shell_grab = container_of(grab, struct shell_grab,
 						    grab);
-	struct wl_input_device *device = grab->input_device;
+	struct wl_pointer *pointer = grab->pointer;
 
-	if (device->button_count == 0 && state == 0) {
+	if (pointer->button_count == 0 && state == 0) {
 		shell_grab_finish(shell_grab);
-		wl_input_device_end_pointer_grab(device);
+		wl_pointer_end_grab(pointer);
 		free(grab);
 	}
 }
@@ -502,7 +502,7 @@
 
 static int
 weston_surface_move(struct weston_surface *es,
-		    struct weston_input_device *wd)
+		    struct weston_seat *ws)
 {
 	struct weston_move_grab *move;
 	struct shell_surface *shsurf = get_shell_surface(es);
@@ -516,32 +516,33 @@
 
 	shell_grab_init(&move->base, &move_grab_interface, shsurf);
 
-	move->dx = wl_fixed_from_double(es->geometry.x) - wd->input_device.grab_x;
-	move->dy = wl_fixed_from_double(es->geometry.y) - wd->input_device.grab_y;
+	move->dx = wl_fixed_from_double(es->geometry.x) -
+			ws->seat.pointer->grab_x;
+	move->dy = wl_fixed_from_double(es->geometry.y) -
+			ws->seat.pointer->grab_y;
 
-	wl_input_device_start_pointer_grab(&wd->input_device,
-					   &move->base.grab);
+	wl_pointer_start_grab(ws->seat.pointer, &move->base.grab);
 
-	wl_input_device_set_pointer_focus(&wd->input_device, NULL,
-	                                  wl_fixed_from_int(0),
-					  wl_fixed_from_int(0));
+	wl_pointer_set_focus(ws->seat.pointer, NULL,
+	                     wl_fixed_from_int(0),
+			     wl_fixed_from_int(0));
 
 	return 0;
 }
 
 static void
 shell_surface_move(struct wl_client *client, struct wl_resource *resource,
-		   struct wl_resource *input_resource, uint32_t serial)
+		   struct wl_resource *seat_resource, uint32_t serial)
 {
-	struct weston_input_device *wd = input_resource->data;
+	struct weston_seat *ws = seat_resource->data;
 	struct shell_surface *shsurf = resource->data;
 
-	if (wd->input_device.button_count == 0 ||
-	    wd->input_device.grab_serial != serial ||
-	    wd->input_device.pointer_focus != &shsurf->surface->surface)
+	if (ws->seat.pointer->button_count == 0 ||
+	    ws->seat.pointer->grab_serial != serial ||
+	    ws->seat.pointer->focus != &shsurf->surface->surface)
 		return;
 
-	if (weston_surface_move(shsurf->surface, wd) < 0)
+	if (weston_surface_move(shsurf->surface, ws) < 0)
 		wl_resource_post_no_memory(resource);
 }
 
@@ -556,7 +557,7 @@
 		   uint32_t time, wl_fixed_t x, wl_fixed_t y)
 {
 	struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
-	struct wl_input_device *device = grab->input_device;
+	struct wl_pointer *pointer = grab->pointer;
 	int32_t width, height;
 	wl_fixed_t from_x, from_y;
 	wl_fixed_t to_x, to_y;
@@ -565,10 +566,10 @@
 		return;
 
 	weston_surface_from_global_fixed(resize->base.shsurf->surface,
-				         device->grab_x, device->grab_y,
+				         pointer->grab_x, pointer->grab_y,
 				         &from_x, &from_y);
 	weston_surface_from_global_fixed(resize->base.shsurf->surface,
-				         device->x, device->y, &to_x, &to_y);
+				         pointer->x, pointer->y, &to_x, &to_y);
 
 	width = resize->width;
 	if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) {
@@ -593,11 +594,11 @@
 		   uint32_t time, uint32_t button, uint32_t state)
 {
 	struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
-	struct wl_input_device *device = grab->input_device;
+	struct wl_pointer *pointer = grab->pointer;
 
-	if (device->button_count == 0 && state == 0) {
+	if (pointer->button_count == 0 && state == 0) {
 		shell_grab_finish(&resize->base);
-		wl_input_device_end_pointer_grab(device);
+		wl_pointer_end_grab(pointer);
 		free(grab);
 	}
 }
@@ -610,7 +611,7 @@
 
 static int
 weston_surface_resize(struct shell_surface *shsurf,
-		      struct weston_input_device *wd, uint32_t edges)
+		      struct weston_seat *ws, uint32_t edges)
 {
 	struct weston_resize_grab *resize;
 
@@ -631,33 +632,32 @@
 	resize->width = shsurf->surface->geometry.width;
 	resize->height = shsurf->surface->geometry.height;
 
-	wl_input_device_start_pointer_grab(&wd->input_device,
-					   &resize->base.grab);
+	wl_pointer_start_grab(ws->seat.pointer, &resize->base.grab);
 
-	wl_input_device_set_pointer_focus(&wd->input_device, NULL,
-	                                  wl_fixed_from_int(0),
-					  wl_fixed_from_int(0));
+	wl_pointer_set_focus(ws->seat.pointer, NULL,
+			     wl_fixed_from_int(0),
+			     wl_fixed_from_int(0));
 
 	return 0;
 }
 
 static void
 shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
-		     struct wl_resource *input_resource, uint32_t serial,
+		     struct wl_resource *seat_resource, uint32_t serial,
 		     uint32_t edges)
 {
-	struct weston_input_device *wd = input_resource->data;
+	struct weston_seat *ws = seat_resource->data;
 	struct shell_surface *shsurf = resource->data;
 
 	if (shsurf->type == SHELL_SURFACE_FULLSCREEN)
 		return;
 
-	if (wd->input_device.button_count == 0 ||
-	    wd->input_device.grab_serial != serial ||
-	    wd->input_device.pointer_focus != &shsurf->surface->surface)
+	if (ws->seat.pointer->button_count == 0 ||
+	    ws->seat.pointer->grab_serial != serial ||
+	    ws->seat.pointer->focus != &shsurf->surface->surface)
 		return;
 
-	if (weston_surface_resize(shsurf, wd, edges) < 0)
+	if (weston_surface_resize(shsurf, ws, edges) < 0)
 		wl_resource_post_no_memory(resource);
 }
 
@@ -1042,18 +1042,18 @@
 		 wl_fixed_t x,
 		 wl_fixed_t y)
 {
-	struct wl_input_device *device = grab->input_device;
+	struct wl_pointer *pointer = grab->pointer;
 	struct shell_surface *priv =
 		container_of(grab, struct shell_surface, popup.grab);
 	struct wl_client *client = priv->surface->surface.resource.client;
 
 	if (surface && surface->resource.client == client) {
-		wl_input_device_set_pointer_focus(device, surface, x, y);
+		wl_pointer_set_focus(pointer, surface, x, y);
 		grab->focus = surface;
 	} else {
-		wl_input_device_set_pointer_focus(device, NULL,
-		                                  wl_fixed_from_int(0),
-						  wl_fixed_from_int(0));
+		wl_pointer_set_focus(pointer, NULL,
+				     wl_fixed_from_int(0),
+				     wl_fixed_from_int(0));
 		grab->focus = NULL;
 	}
 }
@@ -1064,9 +1064,9 @@
 {
 	struct wl_resource *resource;
 
-	resource = grab->input_device->pointer_focus_resource;
+	resource = grab->pointer->focus_resource;
 	if (resource)
-		wl_input_device_send_motion(resource, time, sx, sy);
+		wl_pointer_send_motion(resource, time, sx, sy);
 }
 
 static void
@@ -1079,18 +1079,17 @@
 	struct wl_display *display;
 	uint32_t serial;
 
-	resource = grab->input_device->pointer_focus_resource;
+	resource = grab->pointer->focus_resource;
 	if (resource) {
 		display = wl_client_get_display(resource->client);
 		serial = wl_display_get_serial(display);
-		wl_input_device_send_button(resource, serial,
-					    time, button, state);
+		wl_pointer_send_button(resource, serial, time, button, state);
 	} else if (state == 0 &&
 		   (shsurf->popup.initial_up ||
-		    time - shsurf->popup.device->grab_time > 500)) {
+		    time - shsurf->popup.seat->pointer->grab_time > 500)) {
 		wl_shell_surface_send_popup_done(&shsurf->resource);
-		wl_input_device_end_pointer_grab(grab->input_device);
-		shsurf->popup.grab.input_device = NULL;
+		wl_pointer_end_grab(grab->pointer);
+		shsurf->popup.grab.pointer = NULL;
 	}
 
 	if (state == 0)
@@ -1106,7 +1105,7 @@
 static void
 shell_map_popup(struct shell_surface *shsurf)
 {
-	struct wl_input_device *device = shsurf->popup.device;
+	struct wl_seat *seat = shsurf->popup.seat;
 	struct weston_surface *es = shsurf->surface;
 	struct weston_surface *parent = shsurf->parent->surface;
 
@@ -1133,9 +1132,8 @@
 
 	/* We don't require the grab to still be active, but if another
 	 * grab has started in the meantime, we end the popup now. */
-	if (device->grab_serial == shsurf->popup.serial) {
-		wl_input_device_start_pointer_grab(device,
-						   &shsurf->popup.grab);
+	if (seat->pointer->grab_serial == shsurf->popup.serial) {
+		wl_pointer_start_grab(seat->pointer, &shsurf->popup.grab);
 	} else {
 		wl_shell_surface_send_popup_done(&shsurf->resource);
 	}
@@ -1144,7 +1142,7 @@
 static void
 shell_surface_set_popup(struct wl_client *client,
 			struct wl_resource *resource,
-			struct wl_resource *input_device_resource,
+			struct wl_resource *seat_resource,
 			uint32_t serial,
 			struct wl_resource *parent_resource,
 			int32_t x, int32_t y, uint32_t flags)
@@ -1153,7 +1151,7 @@
 
 	shsurf->type = SHELL_SURFACE_POPUP;
 	shsurf->parent = parent_resource->data;
-	shsurf->popup.device = input_device_resource->data;
+	shsurf->popup.seat = seat_resource->data;
 	shsurf->popup.serial = serial;
 	shsurf->popup.x = x;
 	shsurf->popup.y = y;
@@ -1175,8 +1173,8 @@
 static void
 destroy_shell_surface(struct shell_surface *shsurf)
 {
-	if (shsurf->popup.grab.input_device)
-		wl_input_device_end_pointer_grab(shsurf->popup.grab.input_device);
+	if (shsurf->popup.grab.pointer)
+		wl_pointer_end_grab(shsurf->popup.grab.pointer);
 
 	if (shsurf->fullscreen.type == WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER &&
 	    shell_surface_is_top_fullscreen(shsurf)) {
@@ -1507,12 +1505,12 @@
 }
 
 static void
-move_binding(struct wl_input_device *device, uint32_t time,
+move_binding(struct wl_seat *seat, uint32_t time,
 	     uint32_t key, uint32_t button, uint32_t axis, int32_t value,
 	     void *data)
 {
 	struct weston_surface *surface =
-		(struct weston_surface *) device->pointer_focus;
+		(struct weston_surface *) seat->pointer->focus;
 
 	if (surface == NULL)
 		return;
@@ -1527,16 +1525,16 @@
 			break;
 	}
 
-	weston_surface_move(surface, (struct weston_input_device *) device);
+	weston_surface_move(surface, (struct weston_seat *) seat);
 }
 
 static void
-resize_binding(struct wl_input_device *device, uint32_t time,
+resize_binding(struct wl_seat *seat, uint32_t time,
 	       uint32_t key, uint32_t button, uint32_t axis, int32_t value,
 	       void *data)
 {
 	struct weston_surface *surface =
-		(struct weston_surface *) device->pointer_focus;
+		(struct weston_surface *) seat->pointer->focus;
 	uint32_t edges = 0;
 	int32_t x, y;
 	struct shell_surface *shsurf;
@@ -1559,8 +1557,8 @@
 	}
 
 	weston_surface_from_global(surface,
-				   wl_fixed_to_int(device->grab_x),
-				   wl_fixed_to_int(device->grab_y),
+				   wl_fixed_to_int(seat->pointer->grab_x),
+				   wl_fixed_to_int(seat->pointer->grab_y),
 				   &x, &y);
 
 	if (x < surface->geometry.width / 3)
@@ -1577,19 +1575,18 @@
 	else
 		edges |= WL_SHELL_SURFACE_RESIZE_BOTTOM;
 
-	weston_surface_resize(shsurf, (struct weston_input_device *) device,
-			      edges);
+	weston_surface_resize(shsurf, (struct weston_seat *) seat, edges);
 }
 
 static void
-surface_opacity_binding(struct wl_input_device *device, uint32_t time,
+surface_opacity_binding(struct wl_seat *seat, uint32_t time,
 			uint32_t key, uint32_t button, uint32_t axis,
 			int32_t value, void *data)
 {
 	uint32_t step = 15;
 	struct shell_surface *shsurf;
 	struct weston_surface *surface =
-		(struct weston_surface *) device->pointer_focus;
+		(struct weston_surface *) seat->pointer->focus;
 
 	if (surface == NULL)
 		return;
@@ -1618,18 +1615,18 @@
 }
 
 static void
-zoom_binding(struct wl_input_device *device, uint32_t time,
+zoom_binding(struct wl_seat *seat, uint32_t time,
 	     uint32_t key, uint32_t button, uint32_t axis, int32_t value,
 	     void *data)
 {
-	struct weston_input_device *wd = (struct weston_input_device *) device;
-	struct weston_compositor *compositor = wd->compositor;
+	struct weston_seat *ws = (struct weston_seat *) seat;
+	struct weston_compositor *compositor = ws->compositor;
 	struct weston_output *output;
 
 	wl_list_for_each(output, &compositor->output_list, link) {
 		if (pixman_region32_contains_point(&output->region,
-						   wl_fixed_to_double(device->x),
-						   wl_fixed_to_double(device->y),
+						   wl_fixed_to_double(seat->pointer->x),
+						   wl_fixed_to_double(seat->pointer->y),
 						   NULL)) {
 			output->zoom.active = 1;
 			output->zoom.level += output->zoom.increment * -value;
@@ -1642,13 +1639,15 @@
 			if (output->zoom.level < output->zoom.increment)
 				output->zoom.level = output->zoom.increment;
 
-			weston_output_update_zoom(output, device->x, device->y);
+			weston_output_update_zoom(output,
+			                          seat->pointer->x,
+						  seat->pointer->y);
 		}
 	}
 }
 
 static void
-terminate_binding(struct wl_input_device *device, uint32_t time,
+terminate_binding(struct wl_seat *seat, uint32_t time,
 		  uint32_t key, uint32_t button, uint32_t axis, int32_t state, void *data)
 {
 	struct weston_compositor *compositor = data;
@@ -1663,7 +1662,7 @@
 {
 	struct rotate_grab *rotate =
 		container_of(grab, struct rotate_grab, base.grab);
-	struct wl_input_device *device = grab->input_device;
+	struct wl_pointer *pointer = grab->pointer;
 	struct shell_surface *shsurf = rotate->base.shsurf;
 	struct weston_surface *surface;
 	GLfloat cx, cy, dx, dy, cposx, cposy, dposx, dposy, r;
@@ -1676,8 +1675,8 @@
 	cx = 0.5f * surface->geometry.width;
 	cy = 0.5f * surface->geometry.height;
 
-	dx = wl_fixed_to_double(device->x) - rotate->center.x;
-	dy = wl_fixed_to_double(device->y) - rotate->center.y;
+	dx = wl_fixed_to_double(pointer->x) - rotate->center.x;
+	dy = wl_fixed_to_double(pointer->y) - rotate->center.y;
 	r = sqrtf(dx * dx + dy * dy);
 
 	wl_list_remove(&shsurf->rotation.transform.link);
@@ -1732,15 +1731,15 @@
 {
 	struct rotate_grab *rotate =
 		container_of(grab, struct rotate_grab, base.grab);
-	struct wl_input_device *device = grab->input_device;
+	struct wl_pointer *pointer = grab->pointer;
 	struct shell_surface *shsurf = rotate->base.shsurf;
 
-	if (device->button_count == 0 && state == 0) {
+	if (pointer->button_count == 0 && state == 0) {
 		if (shsurf)
 			weston_matrix_multiply(&shsurf->rotation.rotation,
 					       &rotate->rotation);
 		shell_grab_finish(&rotate->base);
-		wl_input_device_end_pointer_grab(device);
+		wl_pointer_end_grab(pointer);
 		free(rotate);
 	}
 }
@@ -1752,12 +1751,12 @@
 };
 
 static void
-rotate_binding(struct wl_input_device *device, uint32_t time,
+rotate_binding(struct wl_seat *seat, uint32_t time,
 	       uint32_t key, uint32_t button, uint32_t axis, int32_t value,
 	       void *data)
 {
 	struct weston_surface *base_surface =
-		(struct weston_surface *) device->pointer_focus;
+		(struct weston_surface *) seat->pointer->focus;
 	struct shell_surface *surface;
 	struct rotate_grab *rotate;
 	GLfloat dx, dy;
@@ -1791,10 +1790,10 @@
 				 surface->surface->geometry.height / 2,
 				 &rotate->center.x, &rotate->center.y);
 
-	wl_input_device_start_pointer_grab(device, &rotate->base.grab);
+	wl_pointer_start_grab(seat->pointer, &rotate->base.grab);
 
-	dx = wl_fixed_to_double(device->x) - rotate->center.x;
-	dy = wl_fixed_to_double(device->y) - rotate->center.y;
+	dx = wl_fixed_to_double(seat->pointer->x) - rotate->center.x;
+	dy = wl_fixed_to_double(seat->pointer->y) - rotate->center.y;
 	r = sqrtf(dx * dx + dy * dy);
 	if (r > 20.0f) {
 		struct weston_matrix inverse;
@@ -1816,18 +1815,18 @@
 		weston_matrix_init(&rotate->rotation);
 	}
 
-	wl_input_device_set_pointer_focus(device, NULL,
-	                                  wl_fixed_from_int(0),
-					  wl_fixed_from_int(0));
+	wl_pointer_set_focus(seat->pointer, NULL,
+			     wl_fixed_from_int(0),
+			     wl_fixed_from_int(0));
 }
 
 static void
 activate(struct desktop_shell *shell, struct weston_surface *es,
-	 struct weston_input_device *device)
+	 struct weston_seat *seat)
 {
 	struct weston_surface *surf, *prev;
 
-	weston_surface_activate(es, device);
+	weston_surface_activate(es, seat);
 
 	switch (get_shell_surface_type(es)) {
 	case SHELL_SURFACE_BACKGROUND:
@@ -1881,24 +1880,24 @@
 }
 
 static void
-click_to_activate_binding(struct wl_input_device *device,
+click_to_activate_binding(struct wl_seat *seat,
 			  uint32_t time, uint32_t key,
 			  uint32_t button, uint32_t axis, int32_t state, void *data)
 {
-	struct weston_input_device *wd = (struct weston_input_device *) device;
+	struct weston_seat *ws = (struct weston_seat *) seat;
 	struct desktop_shell *shell = data;
 	struct weston_surface *focus;
 	struct weston_surface *upper;
 
-	focus = (struct weston_surface *) device->pointer_focus;
+	focus = (struct weston_surface *) seat->pointer->focus;
 	if (!focus)
 		return;
 
 	if (is_black_surface(focus, &upper))
 		focus = upper;
 
-	if (state && device->pointer_grab == &device->default_pointer_grab)
-		activate(shell, focus, wd);
+	if (state && seat->pointer->grab == &seat->pointer->default_grab)
+		activate(shell, focus, ws);
 }
 
 static void
@@ -1906,7 +1905,7 @@
 {
 	struct desktop_shell *shell =
 		container_of(listener, struct desktop_shell, lock_listener);
-	struct weston_input_device *device;
+	struct weston_seat *seat;
 	struct shell_surface *shsurf;
 	struct weston_output *output;
 
@@ -1945,9 +1944,8 @@
 	weston_compositor_schedule_repaint(shell->compositor);
 
 	/* reset keyboard foci */
-	wl_list_for_each(device, &shell->compositor->input_device_list, link) {
-		wl_input_device_set_keyboard_focus(&device->input_device,
-						   NULL);
+	wl_list_for_each(seat, &shell->compositor->seat_list, link) {
+		wl_keyboard_set_focus(seat->seat.keyboard, NULL);
 	}
 
 	/* TODO: disable bindings that should not work while locked. */
@@ -2094,8 +2092,7 @@
 	case SHELL_SURFACE_MAXIMIZED:
 		if (!shell->locked)
 			activate(shell, surface,
-				 (struct weston_input_device *)
-				 compositor->input_device);
+				 (struct weston_seat *) compositor->seat);
 		break;
 	default:
 		break;
@@ -2406,8 +2403,7 @@
 {
 	struct weston_compositor *compositor = switcher->shell->compositor;
 	struct weston_surface *surface;
-	struct weston_input_device *device =
-		(struct weston_input_device *) switcher->grab.input_device;
+	struct wl_keyboard *keyboard = switcher->grab.keyboard;
 
 	wl_list_for_each(surface, &compositor->surface_list, link) {
 		surface->alpha = 255;
@@ -2415,9 +2411,10 @@
 	}
 
 	if (switcher->current)
-		activate(switcher->shell, switcher->current, device);
+		activate(switcher->shell, switcher->current,
+			 (struct weston_seat *) keyboard->seat);
 	wl_list_remove(&switcher->listener.link);
-	wl_input_device_end_keyboard_grab(&device->input_device);
+	wl_keyboard_end_grab(keyboard);
 	free(switcher);
 }
 
@@ -2426,10 +2423,9 @@
 	     uint32_t time, uint32_t key, uint32_t state)
 {
 	struct switcher *switcher = container_of(grab, struct switcher, grab);
-	struct weston_input_device *device =
-		(struct weston_input_device *) grab->input_device;
+	struct weston_seat *seat = (struct weston_seat *) grab->keyboard->seat;
 
-	if ((device->modifier_state & switcher->shell->binding_modifier) == 0) {
+	if ((seat->modifier_state & switcher->shell->binding_modifier) == 0) {
 		switcher_destroy(switcher, time);
 	} else if (key == KEY_TAB && state) {
 		switcher_next(switcher);
@@ -2441,7 +2437,7 @@
 };
 
 static void
-switcher_binding(struct wl_input_device *device, uint32_t time,
+switcher_binding(struct wl_seat *seat, uint32_t time,
 		 uint32_t key, uint32_t button, uint32_t axis,
 		 int32_t value, void *data)
 {
@@ -2455,13 +2451,13 @@
 	wl_list_init(&switcher->listener.link);
 
 	switcher->grab.interface = &switcher_grab;
-	wl_input_device_start_keyboard_grab(device, &switcher->grab);
-	wl_input_device_set_keyboard_focus(device, NULL);
+	wl_keyboard_start_grab(seat->keyboard, &switcher->grab);
+	wl_keyboard_set_focus(seat->keyboard, NULL);
 	switcher_next(switcher);
 }
 
 static void
-backlight_binding(struct wl_input_device *device, uint32_t time,
+backlight_binding(struct wl_seat *seat, uint32_t time,
 		  uint32_t key, uint32_t button, uint32_t axis, int32_t state, void *data)
 {
 	struct weston_compositor *compositor = data;
@@ -2494,7 +2490,7 @@
 }
 
 static void
-debug_repaint_binding(struct wl_input_device *device, uint32_t time,
+debug_repaint_binding(struct wl_seat *seat, uint32_t time,
 		      uint32_t key, uint32_t button, uint32_t axis,
 		      int32_t value, void *data)
 {
@@ -2556,11 +2552,11 @@
 	weston_compositor_add_binding(ec, 0, BTN_LEFT, 0, 0,
 				      click_to_activate_binding, shell);
 	weston_compositor_add_binding(ec, 0, 0,
-				      WL_INPUT_DEVICE_AXIS_VERTICAL_SCROLL,
+				      WL_POINTER_AXIS_VERTICAL_SCROLL,
 				      MODIFIER_SUPER | MODIFIER_ALT,
 				      surface_opacity_binding, NULL);
 	weston_compositor_add_binding(ec, 0, 0,
-				      WL_INPUT_DEVICE_AXIS_VERTICAL_SCROLL,
+				      WL_POINTER_AXIS_VERTICAL_SCROLL,
 				      MODIFIER_SUPER, zoom_binding, NULL);
 
 	/* configurable bindings */
diff --git a/src/tablet-shell.c b/src/tablet-shell.c
index 633c08f..cf9ddf6 100644
--- a/src/tablet-shell.c
+++ b/src/tablet-shell.c
@@ -52,7 +52,7 @@
 
 	struct weston_compositor *compositor;
 	struct weston_process process;
-	struct weston_input_device *device;
+	struct weston_seat *seat;
 	struct wl_client *client;
 
 	struct weston_surface *surface;
@@ -241,10 +241,9 @@
 {
 	struct tablet_shell *shell = data;
 	struct weston_compositor *compositor = shell->compositor;
-	struct weston_input_device *device =
-		(struct weston_input_device *) compositor->input_device;
+	struct weston_seat *seat = (struct weston_seat *) compositor->seat;
 
-	weston_surface_activate(shell->home_surface, device);
+	weston_surface_activate(shell->home_surface, seat);
 }
 
 static void
@@ -252,8 +251,7 @@
 			     struct weston_surface *surface)
 {
 	struct weston_compositor *compositor = shell->compositor;
-	struct weston_input_device *device =
-		(struct weston_input_device *) compositor->input_device;
+	struct weston_seat *seat = (struct weston_seat *) compositor->seat;
 	struct weston_surface *current;
 
 	if (shell->state == STATE_SWITCHER) {
@@ -271,7 +269,7 @@
 		}
 	} else {
 		fprintf(stderr, "switch to %p\n", surface);
-		weston_surface_activate(surface, device);
+		weston_surface_activate(surface, seat);
 		tablet_shell_set_state(shell, STATE_TASK);
 		weston_zoom_run(surface, 0.3, 1.0, NULL, NULL);
 	}
@@ -428,13 +426,13 @@
 static void
 go_home(struct tablet_shell *shell)
 {
-	struct weston_input_device *device =
-		(struct weston_input_device *) shell->compositor->input_device;
+	struct weston_seat *seat =
+		(struct weston_seat *) shell->compositor->seat;
 
 	if (shell->state == STATE_SWITCHER)
 		tablet_shell_send_hide_switcher(&shell->resource);
 
-	weston_surface_activate(shell->home_surface, device);
+	weston_surface_activate(shell->home_surface, seat);
 
 	tablet_shell_set_state(shell, STATE_HOME);
 }
@@ -451,7 +449,7 @@
 }
 
 static void
-menu_key_binding(struct wl_input_device *device, uint32_t time,
+menu_key_binding(struct wl_seat *seat, uint32_t time,
 		 uint32_t key, uint32_t button, uint32_t axis, int32_t state, void *data)
 {
 	struct tablet_shell *shell = data;
@@ -464,7 +462,7 @@
 }
 
 static void
-home_key_binding(struct wl_input_device *device, uint32_t time,
+home_key_binding(struct wl_seat *seat, uint32_t time,
 		 uint32_t key, uint32_t button, uint32_t axis, int32_t state, void *data)
 {
 	struct tablet_shell *shell = data;
@@ -472,7 +470,7 @@
 	if (shell->state == STATE_LOCKED)
 		return;
 
-	shell->device = (struct weston_input_device *) device;
+	shell->seat = (struct weston_seat *) seat;
 
 	if (state) {
 		wl_event_source_timer_update(shell->long_press_source, 500);
diff --git a/src/util.c b/src/util.c
index c789d29..b06efd0 100644
--- a/src/util.c
+++ b/src/util.c
@@ -257,16 +257,16 @@
 	struct wl_display *display;
 	uint32_t serial;
 
-	resource = grab->input_device->keyboard_focus_resource;
+	resource = grab->keyboard->focus_resource;
 	if (key == b->key) {
 		if (!state) {
-			wl_input_device_end_keyboard_grab(grab->input_device);
+			wl_keyboard_end_grab(grab->keyboard);
 			free(b);
 		}
 	} else if (resource) {
 		display = wl_client_get_display(resource->client);
 		serial = wl_display_next_serial(display);
-		wl_input_device_send_key(resource, serial, time, key, state);
+		wl_keyboard_send_key(resource, serial, time, key, state);
 	}
 }
 
@@ -275,7 +275,7 @@
 };
 
 static void
-install_binding_grab(struct wl_input_device *device,
+install_binding_grab(struct wl_seat *seat,
 		     uint32_t time, uint32_t key)
 {
 	struct binding_keyboard_grab *grab;
@@ -283,12 +283,12 @@
 	grab = malloc(sizeof *grab);
 	grab->key = key;
 	grab->grab.interface = &binding_grab;
-	wl_input_device_start_keyboard_grab(device, &grab->grab);
+	wl_keyboard_start_grab(seat->keyboard, &grab->grab);
 }
 
 WL_EXPORT void
 weston_compositor_run_binding(struct weston_compositor *compositor,
-			      struct weston_input_device *device,
+			      struct weston_seat *seat,
 			      uint32_t time, uint32_t key,
 			      uint32_t button, uint32_t axis, int32_t value)
 {
@@ -296,18 +296,17 @@
 
 	wl_list_for_each(b, &compositor->binding_list, link) {
 		if (b->key == key && b->button == button && b->axis == axis &&
-		    b->modifier == device->modifier_state && value) {
-			b->handler(&device->input_device,
+		    b->modifier == seat->modifier_state && value) {
+			b->handler(&seat->seat,
 				   time, key, button, axis, value, b->data);
 
 			/* If this was a key binding and it didn't
 			 * install a keyboard grab, install one now to
 			 * swallow the key release. */
 			if (b->key &&
-			    device->input_device.keyboard_grab ==
-			    &device->input_device.default_keyboard_grab)
-				install_binding_grab(&device->input_device,
-						     time, key);
+			    seat->seat.keyboard->grab ==
+			    &seat->seat.keyboard->default_grab)
+				install_binding_grab(&seat->seat, time, key);
 		}
 	}
 }
diff --git a/src/xserver-launcher.c b/src/xserver-launcher.c
index d553703..ad854df 100644
--- a/src/xserver-launcher.c
+++ b/src/xserver-launcher.c
@@ -427,8 +427,8 @@
 	}
 
 	compositor = wm->server->compositor;
-	wl_input_device_set_selection(compositor->input_device, source,
-				      wl_display_next_serial(compositor->wl_display));
+	wl_seat_set_selection(&compositor->seat->seat, source,
+			      wl_display_next_serial(compositor->wl_display));
 
 	free(reply);
 }
@@ -546,10 +546,10 @@
 static void
 weston_wm_set_selection(struct wl_listener *listener, void *data)
 {
-	struct wl_input_device *device = data;
+	struct wl_seat *seat = data;
 	struct weston_wm *wm =
 		container_of(listener, struct weston_wm, selection_listener);
-	struct wl_data_source *source = device->selection_data_source;
+	struct wl_data_source *source = seat->selection_data_source;
 	const char **p, **end;
 	int has_text_plain = 0;
 
@@ -1060,7 +1060,7 @@
 static void
 weston_wm_send_data(struct weston_wm *wm, xcb_atom_t target, const char *mime_type)
 {
-	struct wl_input_device *device = wm->server->compositor->input_device;
+	struct wl_seat *seat = &wm->server->compositor->seat->seat;
 	int p[2];
 
 	if (pipe2(p, O_CLOEXEC | O_NONBLOCK) == -1) {
@@ -1078,7 +1078,7 @@
 						   weston_wm_read_data_source,
 						   wm);
 
-	wl_data_source_send_send(&device->selection_data_source->resource,
+	wl_data_source_send_send(&seat->selection_data_source->resource,
 				 mime_type, p[1]);
 	close(p[1]);
 }
@@ -1505,7 +1505,7 @@
 static struct weston_wm *
 weston_wm_create(struct weston_xserver *wxs)
 {
-	struct wl_input_device *device;
+	struct wl_seat *seat;
 	struct weston_wm *wm;
 	struct wl_event_loop *loop;
 	xcb_screen_iterator_t s;
@@ -1604,9 +1604,9 @@
 
 	xcb_flush(wm->conn);
 
-	device = wxs->compositor->input_device;
+	seat = &wxs->compositor->seat->seat;
 	wm->selection_listener.notify = weston_wm_set_selection;
-	wl_signal_add(&device->selection_signal, &wm->selection_listener);
+	wl_signal_add(&seat->selection_signal, &wm->selection_listener);
 
 	fprintf(stderr, "created wm\n");