[PATCH weston v5] input: Don't test keyboard/pointer/touch pointers

Jonas Ã…dahl jadahl at gmail.com
Wed May 20 20:47:47 PDT 2015


On Mon, May 04, 2015 at 10:59:10AM -0500, Derek Foreman wrote:
> Keyboards and pointers aren't freed when devices are removed,
> so we should really be testing keyboard_device_count and
> pointer_device_count in most cases, not the actual pointers.
> Otherwise we end up with different behaviour after removing a
> device than we had before it was inserted.
> 
> This commit renames the touch/keyboard/pointer pointers and adds
> helper functions to get them that hide this complexity and return
> NULL when *_device_count is 0.
> 
> Signed-off-by: Derek Foreman <derekf at osg.samsung.com>
> ---
> 
> Fixed a few bugs that turned up while running devices-test - now
> seat_get_pointer, seat_get_touch and seat_get_keyboard use the resource
> pointers directly.
> 
> Added a couple of null pointer checks.
> 
> Moved the helper functions to input.c

Hey, some issues and nits inlined below. Another general comment is, in
various places, you use the helper and temporary variabes when it is
guaranteed that it'll always return for example seat->pointer (in grabs,
keybindings and the like). Are those changes really necessary? Being
able to go directly from seat to pointer is awfully convenient and very
often reliable (in grabs, keybindings etc).

> 
>  desktop-shell/exposay.c             |  27 ++--
>  desktop-shell/input-panel.c         |   7 +-
>  desktop-shell/shell.c               | 266 +++++++++++++++++++-------------
>  fullscreen-shell/fullscreen-shell.c |  21 ++-
>  ivi-shell/hmi-controller.c          |  35 +++--
>  ivi-shell/input-panel-ivi.c         |   7 +-
>  src/bindings.c                      |  28 ++--
>  src/compositor-drm.c                |  16 +-
>  src/compositor-wayland.c            |   8 +-
>  src/compositor-x11.c                |  20 ++-
>  src/compositor.c                    |  32 ++--
>  src/compositor.h                    |  15 +-
>  src/data-device.c                   |  41 ++---
>  src/input.c                         | 294 +++++++++++++++++++++++-------------
>  src/libinput-device.c               |   3 +-
>  src/libinput-seat.c                 |  15 +-
>  src/screen-share.c                  |   3 +-
>  src/screenshooter.c                 |   7 +-
>  src/text-backend.c                  |  19 ++-
>  src/zoom.c                          |   8 +-
>  tests/surface-screenshot.c          |   7 +-
>  tests/weston-test.c                 |  12 +-
>  xwayland/dnd.c                      |   3 +-
>  xwayland/window-manager.c           |  21 ++-
>  24 files changed, 583 insertions(+), 332 deletions(-)
> 
> diff --git a/desktop-shell/exposay.c b/desktop-shell/exposay.c
> index 4b65cbd..e3b1c78 100644
> --- a/desktop-shell/exposay.c
> +++ b/desktop-shell/exposay.c
> @@ -517,11 +517,13 @@ static enum exposay_layout_state
>  exposay_set_inactive(struct desktop_shell *shell)
>  {
>  	struct weston_seat *seat = shell->exposay.seat;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  
> -	weston_keyboard_end_grab(seat->keyboard);
> -	weston_pointer_end_grab(seat->pointer);
> -	if (seat->keyboard->input_method_resource)
> -		seat->keyboard->grab = &seat->keyboard->input_method_grab;
> +	weston_keyboard_end_grab(keyboard);
> +	weston_pointer_end_grab(pointer);
> +	if (keyboard->input_method_resource)
> +		keyboard->grab = &keyboard->input_method_grab;

This may introduce segfaults as seat->keyboard/seat->pointer would
previously always be non-NULL, even when the last keyboard/pointer was
disconnected.

>  
>  	return EXPOSAY_LAYOUT_INACTIVE;
>  }
> @@ -554,26 +556,27 @@ static enum exposay_layout_state
>  exposay_transition_active(struct desktop_shell *shell)
>  {
>  	struct weston_seat *seat = shell->exposay.seat;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	struct shell_output *shell_output;
>  	bool animate = false;
>  
>  	shell->exposay.workspace = get_current_workspace(shell);
> -	shell->exposay.focus_prev = get_default_view (seat->keyboard->focus);
> -	shell->exposay.focus_current = get_default_view (seat->keyboard->focus);
> +	shell->exposay.focus_prev = get_default_view(keyboard->focus);
> +	shell->exposay.focus_current = get_default_view(keyboard->focus);

Same issue here regarding pointe/keyboard can now be NULL when before
they couldn't.

>  	shell->exposay.clicked = NULL;
>  	wl_list_init(&shell->exposay.surface_list);
>  
>  	lower_fullscreen_layer(shell);
>  	shell->exposay.grab_kbd.interface = &exposay_kbd_grab;
> -	weston_keyboard_start_grab(seat->keyboard,
> -	                           &shell->exposay.grab_kbd);
> -	weston_keyboard_set_focus(seat->keyboard, NULL);
> +	weston_keyboard_start_grab(keyboard, &shell->exposay.grab_kbd);
> +	weston_keyboard_set_focus(keyboard, NULL);
>  
>  	shell->exposay.grab_ptr.interface = &exposay_ptr_grab;
> -	weston_pointer_start_grab(seat->pointer,
> +	weston_pointer_start_grab(pointer,
>  	                          &shell->exposay.grab_ptr);
> -	weston_pointer_set_focus(seat->pointer, NULL,
> -			         seat->pointer->x, seat->pointer->y);
> +	weston_pointer_set_focus(pointer, NULL,
> +			         pointer->x, pointer->y);
>  
>  	wl_list_for_each(shell_output, &shell->output_list, link) {
>  		enum exposay_layout_state state;
> diff --git a/desktop-shell/input-panel.c b/desktop-shell/input-panel.c
> index ffa3ade..1c2d08b 100644
> --- a/desktop-shell/input-panel.c
> +++ b/desktop-shell/input-panel.c
> @@ -66,9 +66,12 @@ show_input_panel_surface(struct input_panel_surface *ipsurf)
>  	float x, y;
>  
>  	wl_list_for_each(seat, &shell->compositor->seat_list, link) {
> -		if (!seat->keyboard || !seat->keyboard->focus)
> +		struct weston_keyboard *keyboard =
> +						weston_seat_get_keyboard(seat);

nit: Indentation wrong. The overwhelming way of indenting \n after = is
with one extra tab. Try "grep -r --include="*.c" -A1 -e ' =$' weston/".

nit2: What was the conclusion of the can-we-declare-in-sub-blocks? I
remember it was discussed not too long ago, but don't remember the
conclusion.

> +
> +		if (!keyboard || !keyboard->focus)
>  			continue;
> -		focus = weston_surface_get_main_surface(seat->keyboard->focus);
> +		focus = weston_surface_get_main_surface(keyboard->focus);
>  		ipsurf->output = focus->output;
>  		x = ipsurf->output->x + (ipsurf->output->width - ipsurf->surface->width) / 2;
>  		y = ipsurf->output->y + ipsurf->output->height - ipsurf->surface->height;
> diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
> index 5f54dea..07068a8 100644
> --- a/desktop-shell/shell.c
> +++ b/desktop-shell/shell.c
> @@ -360,10 +360,11 @@ shell_grab_start(struct shell_grab *grab,
>  		 enum desktop_shell_cursor cursor)
>  {
>  	struct desktop_shell *shell = shsurf->shell;
> +	struct weston_touch *touch = weston_seat_get_touch(pointer->seat);
>  
>  	popup_grab_end(pointer);
> -	if (pointer->seat->touch)
> -		touch_popup_grab_end(pointer->seat->touch);
> +	if (touch)
> +		touch_popup_grab_end(touch);
>  
>  	grab->grab.interface = interface;
>  	grab->shsurf = shsurf;
> @@ -527,10 +528,11 @@ shell_touch_grab_start(struct shell_touch_grab *grab,
>  		       struct weston_touch *touch)
>  {
>  	struct desktop_shell *shell = shsurf->shell;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(touch->seat);
>  
>  	touch_popup_grab_end(touch);
> -	if (touch->seat->pointer)
> -		popup_grab_end(touch->seat->pointer);
> +	if (pointer)
> +		popup_grab_end(pointer);
>  
>  	grab->grab.interface = interface;
>  	grab->shsurf = shsurf;
> @@ -889,27 +891,33 @@ restore_focus_state(struct desktop_shell *shell, struct workspace *ws)
>  	wl_list_init(&shell->compositor->seat_list);
>  
>  	wl_list_for_each_safe(state, next, &ws->focus_list, link) {
> +		struct weston_keyboard *keyboard =
> +					weston_seat_get_keyboard(state->seat);

nit: Same indentation inconsistency as above.

> +
>  		wl_list_remove(&state->seat->link);
>  		wl_list_insert(&shell->compositor->seat_list,
>  			       &state->seat->link);
>  
> -		if (state->seat->keyboard == NULL)
> +		if (!keyboard)
>  			continue;
>  
>  		surface = state->keyboard_focus;
>  
> -		weston_keyboard_set_focus(state->seat->keyboard, surface);
> +		weston_keyboard_set_focus(keyboard, surface);
>  	}
>  
>  	/* For any remaining seats that we don't have a focus state
>  	 * for we'll reset the keyboard focus to NULL */
>  	wl_list_for_each_safe(seat, next_seat, &pending_seat_list, link) {
> +		struct weston_keyboard *keyboard =
> +						weston_seat_get_keyboard(seat);

nit: Same indentation inconsistency as above.

> +
>  		wl_list_insert(&shell->compositor->seat_list, &seat->link);
>  
> -		if (seat->keyboard == NULL)
> +		if (!keyboard)
>  			continue;
>  
> -		weston_keyboard_set_focus(seat->keyboard, NULL);
> +		weston_keyboard_set_focus(keyboard, NULL);
>  	}
>  }
>  
> @@ -921,7 +929,10 @@ replace_focus_state(struct desktop_shell *shell, struct workspace *ws,
>  
>  	wl_list_for_each(state, &ws->focus_list, link) {
>  		if (state->seat == seat) {
> -			focus_state_set_focus(state, seat->keyboard->focus);
> +			struct weston_keyboard *keyboard =
> +						weston_seat_get_keyboard(seat);

nit: Same indentation inconsistency as above.

> +
> +			focus_state_set_focus(state, keyboard->focus);
>  			return;
>  		}
>  	}
> @@ -1420,12 +1431,15 @@ move_surface_to_workspace(struct desktop_shell *shell,
>  
>  	drop_focus_state(shell, from, view->surface);
>  	wl_list_for_each(seat, &shell->compositor->seat_list, link) {
> -		if (!seat->keyboard)
> +		struct weston_keyboard *keyboard =
> +						weston_seat_get_keyboard(seat);

nit: Same indentation inconsistency as above.

> +
> +		if (!keyboard)
>  			continue;
>  
> -		focus = weston_surface_get_main_surface(seat->keyboard->focus);
> +		focus = weston_surface_get_main_surface(keyboard->focus);
>  		if (focus == view->surface)
> -			weston_keyboard_set_focus(seat->keyboard, NULL);
> +			weston_keyboard_set_focus(keyboard, NULL);
>  	}
>  
>  	weston_view_damage_below(view);
> @@ -1436,6 +1450,7 @@ take_surface_to_workspace_by_seat(struct desktop_shell *shell,
>  				  struct weston_seat *seat,
>  				  unsigned int index)
>  {
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	struct weston_surface *surface;
>  	struct weston_view *view;
>  	struct shell_surface *shsurf;
> @@ -1443,7 +1458,7 @@ take_surface_to_workspace_by_seat(struct desktop_shell *shell,
>  	struct workspace *to;
>  	struct focus_state *state;
>  
> -	surface = weston_surface_get_main_surface(seat->keyboard->focus);
> +	surface = weston_surface_get_main_surface(keyboard->focus);
>  	view = get_default_view(surface);
>  	if (view == NULL ||
>  	    index == shell->workspaces.current ||
> @@ -1624,6 +1639,7 @@ static int
>  surface_touch_move(struct shell_surface *shsurf, struct weston_seat *seat)
>  {
>  	struct weston_touch_move_grab *move;
> +	struct weston_touch *touch = weston_seat_get_touch(seat);
>  
>  	if (!shsurf)
>  		return -1;
> @@ -1637,12 +1653,12 @@ surface_touch_move(struct shell_surface *shsurf, struct weston_seat *seat)
>  
>  	move->active = 1;
>  	move->dx = wl_fixed_from_double(shsurf->view->geometry.x) -
> -			seat->touch->grab_x;
> +					touch->grab_x;
>  	move->dy = wl_fixed_from_double(shsurf->view->geometry.y) -
> -			seat->touch->grab_y;
> +					touch->grab_y;
>  
>  	shell_touch_grab_start(&move->base, &touch_move_grab_interface, shsurf,
> -			       seat->touch);
> +			       touch);

Same issue regarding potential NULL pointer reference here.

>  
>  	return 0;
>  }
> @@ -1738,6 +1754,7 @@ static int
>  surface_move(struct shell_surface *shsurf, struct weston_seat *seat,
>  	     int client_initiated)
>  {
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  	struct weston_move_grab *move;
>  
>  	if (!shsurf)
> @@ -1752,13 +1769,13 @@ surface_move(struct shell_surface *shsurf, struct weston_seat *seat,
>  		return -1;
>  
>  	move->dx = wl_fixed_from_double(shsurf->view->geometry.x) -
> -			seat->pointer->grab_x;
> +					pointer->grab_x;
>  	move->dy = wl_fixed_from_double(shsurf->view->geometry.y) -
> -			seat->pointer->grab_y;
> +					pointer->grab_y;
>  	move->client_initiated = client_initiated;
>  
>  	shell_grab_start(&move->base, &move_grab_interface, shsurf,
> -			 seat->pointer, DESKTOP_SHELL_CURSOR_MOVE);
> +			 pointer, DESKTOP_SHELL_CURSOR_MOVE);

Potential NULL pointer dereference when the surface_move call originates
from the Xwayland window manager.

>  
>  	return 0;
>  }
> @@ -1768,21 +1785,23 @@ common_surface_move(struct wl_resource *resource,
>  		    struct wl_resource *seat_resource, uint32_t serial)
>  {
>  	struct weston_seat *seat = wl_resource_get_user_data(seat_resource);
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +	struct weston_touch *touch = weston_seat_get_touch(seat);
>  	struct shell_surface *shsurf = wl_resource_get_user_data(resource);
>  	struct weston_surface *surface;
>  
> -	if (seat->pointer &&
> -	    seat->pointer->focus &&
> -	    seat->pointer->button_count > 0 &&
> -	    seat->pointer->grab_serial == serial) {
> -		surface = weston_surface_get_main_surface(seat->pointer->focus->surface);
> +	if (pointer &&
> +	    pointer->focus &&
> +	    pointer->button_count > 0 &&
> +	    pointer->grab_serial == serial) {
> +		surface = weston_surface_get_main_surface(pointer->focus->surface);
>  		if ((surface == shsurf->surface) &&
>  		    (surface_move(shsurf, seat, 1) < 0))
>  			wl_resource_post_no_memory(resource);
> -	} else if (seat->touch &&
> -		   seat->touch->focus &&
> -		   seat->touch->grab_serial == serial) {
> -		surface = weston_surface_get_main_surface(seat->touch->focus->surface);
> +	} else if (touch &&
> +		   touch->focus &&
> +		   touch->grab_serial == serial) {
> +		surface = weston_surface_get_main_surface(touch->focus->surface);
>  		if ((surface == shsurf->surface) &&
>  		    (surface_touch_move(shsurf, seat) < 0))
>  			wl_resource_post_no_memory(resource);
> @@ -1932,6 +1951,7 @@ static int
>  surface_resize(struct shell_surface *shsurf,
>  	       struct weston_seat *seat, uint32_t edges)
>  {
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  	struct weston_resize_grab *resize;
>  	const unsigned resize_topbottom =
>  		WL_SHELL_SURFACE_RESIZE_TOP | WL_SHELL_SURFACE_RESIZE_BOTTOM;
> @@ -1961,7 +1981,7 @@ surface_resize(struct shell_surface *shsurf,
>  	shsurf->resize_edges = edges;
>  	shell_surface_state_changed(shsurf);
>  	shell_grab_start(&resize->base, &resize_grab_interface, shsurf,
> -			 seat->pointer, edges);
> +			 pointer, edges);

Potential NULL pointer dereference. Same as for surface_move.

>  
>  	return 0;
>  }
> @@ -1973,15 +1993,16 @@ common_surface_resize(struct wl_resource *resource,
>  {
>  	struct weston_seat *seat = wl_resource_get_user_data(seat_resource);
>  	struct shell_surface *shsurf = wl_resource_get_user_data(resource);
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  	struct weston_surface *surface;
>  
> -	if (seat->pointer == NULL ||
> -	    seat->pointer->button_count == 0 ||
> -	    seat->pointer->grab_serial != serial ||
> -	    seat->pointer->focus == NULL)
> +	if (!pointer ||
> +	    pointer->button_count == 0 ||
> +	    pointer->grab_serial != serial ||
> +	    pointer->focus == NULL)
>  		return;
>  
> -	surface = weston_surface_get_main_surface(seat->pointer->focus->surface);
> +	surface = weston_surface_get_main_surface(pointer->focus->surface);
>  	if (surface != shsurf->surface)
>  		return;
>  
> @@ -2081,10 +2102,12 @@ end_busy_cursor(struct weston_compositor *compositor, struct wl_client *client)
>  	struct weston_seat *seat;
>  
>  	wl_list_for_each(seat, &compositor->seat_list, link) {
> -		if (seat->pointer == NULL)
> +		struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +
> +		if (!pointer)
>  			continue;
>  
> -		grab = (struct shell_grab *) seat->pointer->grab;
> +		grab = (struct shell_grab *)pointer->grab;
>  		if (grab->grab.interface == &busy_cursor_grab_interface &&
>  		    wl_resource_get_client(grab->shsurf->resource) == client) {
>  			shell_grab_end(grab);
> @@ -2106,15 +2129,17 @@ xdg_ping_timeout_handler(void *data)
>  	/* Client is not responding */
>  	sc->unresponsive = 1;
>  	wl_list_for_each(seat, &sc->shell->compositor->seat_list, link) {
> -		if (seat->pointer == NULL || seat->pointer->focus == NULL)
> +		struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +
> +		if (!pointer || pointer->focus == NULL)
>  			continue;
> -		if (seat->pointer->focus->surface->resource == NULL)
> +		if (pointer->focus->surface->resource == NULL)
>  			continue;
> -		
> -		shsurf = get_shell_surface(seat->pointer->focus->surface);
> +
> +		shsurf = get_shell_surface(pointer->focus->surface);
>  		if (shsurf &&
>  		    wl_resource_get_client(shsurf->resource) == sc->client)
> -			set_busy_cursor(shsurf, seat->pointer);
> +			set_busy_cursor(shsurf, pointer);
>  	}
>  
>  	return 1;
> @@ -2669,11 +2694,14 @@ set_minimized(struct weston_surface *surface)
>  
>  	drop_focus_state(shsurf->shell, current_ws, view->surface);
>  	wl_list_for_each(seat, &shsurf->shell->compositor->seat_list, link) {
> -		if (!seat->keyboard)
> +		struct weston_keyboard *keyboard =
> +					weston_seat_get_keyboard(seat);

nit: Same indentation inconsistency as above.

> +
> +		if (!keyboard)
>  			continue;
> -		focus = weston_surface_get_main_surface(seat->keyboard->focus);
> +		focus = weston_surface_get_main_surface(keyboard->focus);
>  		if (focus == view->surface)
> -			weston_keyboard_set_focus(seat->keyboard, NULL);
> +			weston_keyboard_set_focus(keyboard, NULL);
>  	}
>  
>  	shell_surface_update_child_surface_layers(shsurf);
> @@ -3004,17 +3032,22 @@ get_focused_output(struct weston_compositor *compositor)
>  	struct weston_output *output = NULL;
>  
>  	wl_list_for_each(seat, &compositor->seat_list, link) {
> +		struct weston_touch *touch = weston_seat_get_touch(seat);
> +		struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +		struct weston_keyboard *keyboard =
> +						weston_seat_get_keyboard(seat);

nit: Same indentation inconsistency as above.

> +
>  		/* Priority has touch focus, then pointer and
>  		 * then keyboard focus. We should probably have
>  		 * three for loops and check frist for touch,
>  		 * then for pointer, etc. but unless somebody has some
>  		 * objections, I think this is sufficient. */
> -		if (seat->touch && seat->touch->focus)
> -			output = seat->touch->focus->output;
> -		else if (seat->pointer && seat->pointer->focus)
> -			output = seat->pointer->focus->output;
> -		else if (seat->keyboard && seat->keyboard->focus)
> -			output = seat->keyboard->focus->output;
> +		if (touch && touch->focus)
> +			output = touch->focus->output;
> +		else if (pointer && pointer->focus)
> +			output = pointer->focus->output;
> +		else if (keyboard && keyboard->focus)
> +			output = keyboard->focus->output;
>  
>  		if (output)
>  			break;
> @@ -3081,19 +3114,22 @@ shell_seat_caps_changed(struct wl_listener *listener, void *data)
>  
>  	seat = container_of(listener, struct shell_seat, caps_changed_listener);
>  
> -	if (seat->seat->keyboard &&
> +	/* this is one of the few places where seat->keyboard_resource and
> +	 * seat->pointer_resource should be tested directly, instead of
> +	 * through weston_seat_get_* */

Should these maybe be a separate patch?

> +	if (seat->seat->keyboard_resource &&
>  	    wl_list_empty(&seat->keyboard_focus_listener.link)) {
> -		wl_signal_add(&seat->seat->keyboard->focus_signal,
> +		wl_signal_add(&seat->seat->keyboard_resource->focus_signal,
>  			      &seat->keyboard_focus_listener);
> -	} else if (!seat->seat->keyboard) {
> +	} else if (!seat->seat->keyboard_resource) {
>  		wl_list_init(&seat->keyboard_focus_listener.link);
>  	}
>  
> -	if (seat->seat->pointer &&
> +	if (seat->seat->pointer_resource &&
>  	    wl_list_empty(&seat->pointer_focus_listener.link)) {
> -		wl_signal_add(&seat->seat->pointer->focus_signal,
> +		wl_signal_add(&seat->seat->pointer_resource->focus_signal,
>  			      &seat->pointer_focus_listener);
> -	} else if (!seat->seat->pointer) {
> +	} else if (!seat->seat->pointer_resource) {
>  		wl_list_init(&seat->pointer_focus_listener.link);
>  	}
>  }
> @@ -3197,6 +3233,7 @@ popup_grab_button(struct weston_pointer_grab *grab,
>  	struct shell_seat *shseat =
>  	    container_of(grab, struct shell_seat, popup_grab.grab);
>  	struct wl_display *display = shseat->seat->compositor->wl_display;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(shseat->seat);
>  	enum wl_pointer_button_state state = state_w;
>  	uint32_t serial;
>  	struct wl_list *resource_list;
> @@ -3210,7 +3247,7 @@ popup_grab_button(struct weston_pointer_grab *grab,
>  		}
>  	} else if (state == WL_POINTER_BUTTON_STATE_RELEASED &&
>  		   (shseat->popup_grab.initial_up ||
> -		    time - shseat->seat->pointer->grab_time > 500)) {
> +		    time - pointer->grab_time > 500)) {
>  		popup_grab_end(grab->pointer);
>  	}
>  
> @@ -3389,6 +3426,8 @@ add_popup_grab(struct shell_surface *shsurf,
>  {
>  	struct weston_seat *seat = shseat->seat;
>  	struct shell_surface *parent, *top_surface;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +	struct weston_touch *touch = weston_seat_get_touch(seat);
>  
>  	parent = get_shell_surface(shsurf->parent);
>  	top_surface = get_top_popup(shseat);
> @@ -3415,7 +3454,7 @@ add_popup_grab(struct shell_surface *shsurf,
>  			/* We must make sure here that this popup was opened
>  			 * after a mouse press, and not just by moving around
>  			 * with other popups already open. */
> -			if (shseat->seat->pointer->button_count > 0)
> +			if (pointer->button_count > 0)
>  				shseat->popup_grab.initial_up = 0;
>  		} else if (type == TOUCH) {
>  			shseat->popup_grab.touch_grab.interface =
> @@ -3426,10 +3465,10 @@ add_popup_grab(struct shell_surface *shsurf,
>  			       &shsurf->popup.grab_link);
>  
>  		if (type == POINTER) {
> -			weston_pointer_start_grab(seat->pointer,
> +			weston_pointer_start_grab(pointer,
>  						  &shseat->popup_grab.grab);
>  		} else if (type == TOUCH) {
> -			weston_touch_start_grab(seat->touch,
> +			weston_touch_start_grab(touch,
>  						&shseat->popup_grab.touch_grab);
>  		}
>  	} else {
> @@ -3472,6 +3511,8 @@ shell_map_popup(struct shell_surface *shsurf)
>  {
>  	struct shell_seat *shseat = shsurf->popup.shseat;
>  	struct weston_view *parent_view = get_default_view(shsurf->parent);
> +	struct weston_pointer *pointer = weston_seat_get_pointer(shseat->seat);
> +	struct weston_touch *touch = weston_seat_get_touch(shseat->seat);
>  
>  	shsurf->surface->output = parent_view->output;
>  	shsurf->view->output = parent_view->output;
> @@ -3480,12 +3521,10 @@ shell_map_popup(struct shell_surface *shsurf)
>  	weston_view_set_position(shsurf->view, shsurf->popup.x, shsurf->popup.y);
>  	weston_view_update_transform(shsurf->view);
>  
> -	if (shseat->seat->pointer &&
> -	    shseat->seat->pointer->grab_serial == shsurf->popup.serial) {
> +	if (pointer && pointer->grab_serial == shsurf->popup.serial) {
>  		if (add_popup_grab(shsurf, shseat, POINTER) != 0)
>  			return -1;
> -	} else if (shseat->seat->touch &&
> -	           shseat->seat->touch->grab_serial == shsurf->popup.serial) {
> +	} else if (touch && touch->grab_serial == shsurf->popup.serial) {
>  		if (add_popup_grab(shsurf, shseat, TOUCH) != 0)
>  			return -1;
>  	} else {
> @@ -4599,14 +4638,15 @@ get_shell_surface_type(struct weston_surface *surface)
>  static void
>  move_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
>  {
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  	struct weston_surface *focus;
>  	struct weston_surface *surface;
>  	struct shell_surface *shsurf;
>  
> -	if (seat->pointer->focus == NULL)
> +	if (pointer->focus == NULL)
>  		return;
>  
> -	focus = seat->pointer->focus->surface;
> +	focus = pointer->focus->surface;
>  
>  	surface = weston_surface_get_main_surface(focus);
>  	if (surface == NULL)
> @@ -4623,7 +4663,8 @@ move_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *dat
>  static void
>  maximize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
>  {
> -	struct weston_surface *focus = seat->keyboard->focus;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
> +	struct weston_surface *focus = keyboard->focus;
>  	struct weston_surface *surface;
>  	struct shell_surface *shsurf;
>  
> @@ -4646,7 +4687,8 @@ maximize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void
>  static void
>  fullscreen_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
>  {
> -	struct weston_surface *focus = seat->keyboard->focus;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
> +	struct weston_surface *focus = keyboard->focus;
>  	struct weston_surface *surface;
>  	struct shell_surface *shsurf;
>  
> @@ -4673,11 +4715,12 @@ touch_move_binding(struct weston_seat *seat, uint32_t time, void *data)
>  	struct weston_surface *focus;
>  	struct weston_surface *surface;
>  	struct shell_surface *shsurf;
> +	struct weston_touch *touch = weston_seat_get_touch(seat);
>  
> -	if (seat->touch->focus == NULL)
> +	if (touch->focus == NULL)
>  		return;
>  
> -	focus = seat->touch->focus->surface;
> +	focus = touch->focus->surface;
>  	surface = weston_surface_get_main_surface(focus);
>  	if (surface == NULL)
>  		return;
> @@ -4695,14 +4738,15 @@ resize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *d
>  {
>  	struct weston_surface *focus;
>  	struct weston_surface *surface;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  	uint32_t edges = 0;
>  	int32_t x, y;
>  	struct shell_surface *shsurf;
>  
> -	if (seat->pointer->focus == NULL)
> +	if (pointer->focus == NULL)
>  		return;
>  
> -	focus = seat->pointer->focus->surface;
> +	focus = pointer->focus->surface;
>  
>  	surface = weston_surface_get_main_surface(focus);
>  	if (surface == NULL)
> @@ -4714,8 +4758,8 @@ resize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *d
>  		return;
>  
>  	weston_view_from_global(shsurf->view,
> -				wl_fixed_to_int(seat->pointer->grab_x),
> -				wl_fixed_to_int(seat->pointer->grab_y),
> +				wl_fixed_to_int(pointer->grab_x),
> +				wl_fixed_to_int(pointer->grab_y),
>  				&x, &y);
>  
>  	if (x < shsurf->surface->width / 3)
> @@ -4741,7 +4785,8 @@ surface_opacity_binding(struct weston_seat *seat, uint32_t time, uint32_t axis,
>  {
>  	float step = 0.005;
>  	struct shell_surface *shsurf;
> -	struct weston_surface *focus = seat->pointer->focus->surface;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +	struct weston_surface *focus = pointer->focus->surface;
>  	struct weston_surface *surface;
>  
>  	/* XXX: broken for windows containing sub-surfaces */
> @@ -4769,18 +4814,19 @@ do_zoom(struct weston_seat *seat, uint32_t time, uint32_t key, uint32_t axis,
>  	wl_fixed_t value)
>  {
>  	struct weston_compositor *compositor = seat->compositor;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  	struct weston_output *output;
>  	float increment;
>  
> -	if (!seat->pointer) {
> +	if (!pointer) {
>  		weston_log("Zoom hotkey pressed but seat '%s' contains no pointer.\n", seat->seat_name);
>  		return;
>  	}
>  
>  	wl_list_for_each(output, &compositor->output_list, link) {
>  		if (pixman_region32_contains_point(&output->region,
> -						   wl_fixed_to_double(seat->pointer->x),
> -						   wl_fixed_to_double(seat->pointer->y),
> +						   wl_fixed_to_double(pointer->x),
> +						   wl_fixed_to_double(pointer->y),
>  						   NULL)) {
>  			if (key == KEY_PAGEUP)
>  				increment = output->zoom.increment;
> @@ -4938,6 +4984,7 @@ static const struct weston_pointer_grab_interface rotate_grab_interface = {
>  static void
>  surface_rotate(struct shell_surface *surface, struct weston_seat *seat)
>  {
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  	struct rotate_grab *rotate;
>  	float dx, dy;
>  	float r;
> @@ -4951,8 +4998,8 @@ surface_rotate(struct shell_surface *surface, struct weston_seat *seat)
>  				    surface->surface->height * 0.5f,
>  				    &rotate->center.x, &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;
> +	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);
>  	if (r > 20.0f) {
>  		struct weston_matrix inverse;
> @@ -4969,7 +5016,7 @@ surface_rotate(struct shell_surface *surface, struct weston_seat *seat)
>  	}
>  
>  	shell_grab_start(&rotate->base, &rotate_grab_interface, surface,
> -			 seat->pointer, DESKTOP_SHELL_CURSOR_ARROW);
> +			 pointer, DESKTOP_SHELL_CURSOR_ARROW);
>  }
>  
>  static void
> @@ -4979,11 +5026,12 @@ rotate_binding(struct weston_seat *seat, uint32_t time, uint32_t button,
>  	struct weston_surface *focus;
>  	struct weston_surface *base_surface;
>  	struct shell_surface *surface;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  
> -	if (seat->pointer->focus == NULL)
> +	if (pointer->focus == NULL)
>  		return;
>  
> -	focus = seat->pointer->focus->surface;
> +	focus = pointer->focus->surface;
>  
>  	base_surface = weston_surface_get_main_surface(focus);
>  	if (base_surface == NULL)
> @@ -5121,23 +5169,27 @@ static void
>  click_to_activate_binding(struct weston_seat *seat, uint32_t time, uint32_t button,
>  			  void *data)
>  {
> -	if (seat->pointer->grab != &seat->pointer->default_grab)
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +
> +	if (pointer->grab != &pointer->default_grab)
>  		return;
> -	if (seat->pointer->focus == NULL)
> +	if (pointer->focus == NULL)
>  		return;
>  
> -	activate_binding(seat, data, seat->pointer->focus->surface);
> +	activate_binding(seat, data, pointer->focus->surface);
>  }
>  
>  static void
>  touch_to_activate_binding(struct weston_seat *seat, uint32_t time, void *data)
>  {
> -	if (seat->touch->grab != &seat->touch->default_grab)
> +	struct weston_touch *touch = weston_seat_get_touch(seat);
> +
> +	if (touch->grab != &touch->default_grab)
>  		return;
> -	if (seat->touch->focus == NULL)
> +	if (touch->focus == NULL)
>  		return;
>  
> -	activate_binding(seat, data, seat->touch->focus->surface);
> +	activate_binding(seat, data, touch->focus->surface);
>  }
>  
>  static void
> @@ -5146,10 +5198,13 @@ unfocus_all_seats(struct desktop_shell *shell)
>  	struct weston_seat *seat, *next;
>  
>  	wl_list_for_each_safe(seat, next, &shell->compositor->seat_list, link) {
> -		if (seat->keyboard == NULL)
> +		struct weston_keyboard *keyboard =
> +						weston_seat_get_keyboard(seat);

nit: Same indentation inconsistency as above.

> +
> +		if (!keyboard)
>  			continue;
>  
> -		weston_keyboard_set_focus(seat->keyboard, NULL);
> +		weston_keyboard_set_focus(keyboard, NULL);
>  	}
>  }
>  
> @@ -5377,10 +5432,14 @@ idle_handler(struct wl_listener *listener, void *data)
>  	struct weston_seat *seat;
>  
>  	wl_list_for_each(seat, &shell->compositor->seat_list, link) {
> -		if (seat->pointer)
> -			popup_grab_end(seat->pointer);
> -		if (seat->touch)
> -			touch_popup_grab_end(seat->touch);
> +		struct weston_touch *touch = weston_seat_get_touch(seat);
> +		struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +
> +		if (pointer)
> +			popup_grab_end(pointer);
> +
> +		if (touch)
> +			touch_popup_grab_end(touch);
>  	}
>  
>  	shell_fade(shell, FADE_OUT);
> @@ -5428,9 +5487,11 @@ weston_view_set_initial_position(struct weston_view *view,
>  	 * TODO: Do something clever for touch too?
>  	 */
>  	wl_list_for_each(seat, &compositor->seat_list, link) {
> -		if (seat->pointer) {
> -			ix = wl_fixed_to_int(seat->pointer->x);
> -			iy = wl_fixed_to_int(seat->pointer->y);
> +		struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +
> +		if (pointer) {
> +			ix = wl_fixed_to_int(pointer->x);
> +			iy = wl_fixed_to_int(pointer->y);
>  			break;
>  		}
>  	}
> @@ -6112,6 +6173,7 @@ switcher_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
>  {
>  	struct desktop_shell *shell = data;
>  	struct switcher *switcher;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  
>  	switcher = malloc(sizeof *switcher);
>  	switcher->shell = shell;
> @@ -6123,8 +6185,8 @@ switcher_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
>  	restore_all_output_modes(shell->compositor);
>  	lower_fullscreen_layer(switcher->shell);
>  	switcher->grab.interface = &switcher_grab;
> -	weston_keyboard_start_grab(seat->keyboard, &switcher->grab);
> -	weston_keyboard_set_focus(seat->keyboard, NULL);
> +	weston_keyboard_start_grab(keyboard, &switcher->grab);
> +	weston_keyboard_set_focus(keyboard, NULL);
>  	switcher_next(switcher);
>  }
>  
> @@ -6165,13 +6227,13 @@ static void
>  force_kill_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
>  		   void *data)
>  {
> -	struct weston_surface *focus_surface;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
> +	struct weston_surface *focus_surface = keyboard->focus;
>  	struct wl_client *client;
>  	struct desktop_shell *shell = data;
>  	struct weston_compositor *compositor = shell->compositor;
>  	pid_t pid;
>  
> -	focus_surface = seat->keyboard->focus;
>  	if (!focus_surface)
>  		return;
>  
> diff --git a/fullscreen-shell/fullscreen-shell.c b/fullscreen-shell/fullscreen-shell.c
> index 35e6d8f..546daeb 100644
> --- a/fullscreen-shell/fullscreen-shell.c
> +++ b/fullscreen-shell/fullscreen-shell.c
> @@ -95,12 +95,16 @@ seat_caps_changed(struct wl_listener *l, void *data)
>  	struct pointer_focus_listener *listener;
>  	struct fs_output *fsout;
>  
> +	/* This function is one of the few places where seat->pointer_resource
> +	 * and seat->keyboard_resource should be tested directly instead of
> +	 * seat->*_device_count.
> +	 */
>  	listener = container_of(l, struct pointer_focus_listener, seat_caps);
>  
>  	/* no pointer */
> -	if (seat->pointer) {
> +	if (seat->pointer_resource) {
>  		if (!listener->pointer_focus.link.prev) {
> -			wl_signal_add(&seat->pointer->focus_signal,
> +			wl_signal_add(&seat->pointer_resource->focus_signal,
>  				      &listener->pointer_focus);
>  		}
>  	} else {
> @@ -109,7 +113,8 @@ seat_caps_changed(struct wl_listener *l, void *data)
>  		}
>  	}
>  
> -	if (seat->keyboard && seat->keyboard->focus != NULL) {
> +	if (seat->keyboard_resource &&
> +	    seat->keyboard_resource->focus != NULL) {
>  		wl_list_for_each(fsout, &listener->shell->output_list, link) {
>  			if (fsout->surface) {
>  				weston_surface_activate(fsout->surface, seat);
> @@ -677,7 +682,10 @@ fullscreen_shell_present_surface(struct wl_client *client,
>  
>  	if (surface) {
>  		wl_list_for_each(seat, &shell->compositor->seat_list, link) {
> -			if (seat->keyboard && seat->keyboard->focus == NULL)
> +			struct weston_keyboard *keyboard =
> +						weston_seat_get_keyboard(seat);

nit: Same indentation inconsistency as above.

> +
> +			if (keyboard && keyboard->focus == NULL)
>  				weston_surface_activate(surface, seat);
>  		}
>  	}
> @@ -725,7 +733,10 @@ fullscreen_shell_present_surface_for_mode(struct wl_client *client,
>  				       fsout, mode_feedback_destroyed);
>  
>  	wl_list_for_each(seat, &shell->compositor->seat_list, link) {
> -		if (seat->keyboard && seat->keyboard->focus == NULL)
> +		struct weston_keyboard *keyboard =
> +						weston_seat_get_keyboard(seat);

nit: Same indentation inconsistency as above.

> +
> +		if (keyboard && keyboard->focus == NULL)
>  			weston_surface_activate(surface, seat);
>  	}
>  }
> diff --git a/ivi-shell/hmi-controller.c b/ivi-shell/hmi-controller.c
> index cd79c38..1f02cbf 100644
> --- a/ivi-shell/hmi-controller.c
> +++ b/ivi-shell/hmi-controller.c
> @@ -1465,15 +1465,18 @@ enum HMI_GRAB_DEVICE {
>  static enum HMI_GRAB_DEVICE
>  get_hmi_grab_device(struct weston_seat *seat, uint32_t serial)
>  {
> -	if (seat->pointer &&
> -	    seat->pointer->focus &&
> -	    seat->pointer->button_count &&
> -	    seat->pointer->grab_serial == serial)
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +	struct weston_touch *touch = weston_seat_get_touch(seat);
> +
> +	if (pointer &&
> +	    pointer->focus &&
> +	    pointer->button_count &&
> +	    pointer->grab_serial == serial)
>  		return HMI_GRAB_DEVICE_POINTER;
>  
> -	if (seat->touch &&
> -	    seat->touch->focus &&
> -	    seat->touch->grab_serial == serial)
> +	if (touch &&
> +	    touch->focus &&
> +	    touch->grab_serial == serial)
>  		return HMI_GRAB_DEVICE_TOUCH;
>  
>  	return HMI_GRAB_DEVICE_NONE;
> @@ -1581,24 +1584,28 @@ ivi_hmi_controller_workspace_control(struct wl_client *client,
>  	ivi_controller_interface->transition_move_layer_cancel(layer);
>  
>  	switch (device) {
> -	case HMI_GRAB_DEVICE_POINTER:
> -		pnt_move_grab = create_workspace_pointer_move(seat->pointer,
> +	case HMI_GRAB_DEVICE_POINTER: {
> +		struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +
> +		pnt_move_grab = create_workspace_pointer_move(pointer,
>  							      resource);
>  
>  		pointer_grab_start(&pnt_move_grab->base, layer,
>  				   &pointer_move_grab_workspace_interface,
> -				   seat->pointer);
> +				   pointer);
>  		break;
> +	}
> +	case HMI_GRAB_DEVICE_TOUCH: {
> +		struct weston_touch *touch = weston_seat_get_touch(seat);
>  
> -	case HMI_GRAB_DEVICE_TOUCH:
> -		tch_move_grab = create_workspace_touch_move(seat->touch,
> +		tch_move_grab = create_workspace_touch_move(touch,
>  							    resource);
>  
>  		touch_grab_start(&tch_move_grab->base, layer,
>  				 &touch_move_grab_workspace_interface,
> -				 seat->touch);
> +				 touch);
>  		break;
> -
> +	}
>  	default:
>  		break;
>  	}
> diff --git a/ivi-shell/input-panel-ivi.c b/ivi-shell/input-panel-ivi.c
> index 6b89177..164408c 100644
> --- a/ivi-shell/input-panel-ivi.c
> +++ b/ivi-shell/input-panel-ivi.c
> @@ -66,9 +66,12 @@ show_input_panel_surface(struct input_panel_surface *ipsurf)
>  	float x, y;
>  
>  	wl_list_for_each(seat, &shell->compositor->seat_list, link) {
> -		if (!seat->keyboard || !seat->keyboard->focus)
> +		struct weston_keyboard *keyboard =
> +						weston_seat_get_keyboard(seat);

nit: Same indentation inconsistency as above.

> +
> +		if (!keyboard || !keyboard->focus)
>  			continue;
> -		focus = weston_surface_get_main_surface(seat->keyboard->focus);
> +		focus = weston_surface_get_main_surface(keyboard->focus);
>  		ipsurf->output = focus->output;
>  		x = ipsurf->output->x + (ipsurf->output->width - ipsurf->surface->width) / 2;
>  		y = ipsurf->output->y + ipsurf->output->height - ipsurf->surface->height;
> diff --git a/src/bindings.c b/src/bindings.c
> index 6aeed91..c0002fd 100644
> --- a/src/bindings.c
> +++ b/src/bindings.c
> @@ -254,11 +254,12 @@ install_binding_grab(struct weston_seat *seat, uint32_t time, uint32_t key,
>                       struct weston_surface *focus)
>  {
>  	struct binding_keyboard_grab *grab;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  
>  	grab = malloc(sizeof *grab);
>  	grab->key = key;
>  	grab->grab.interface = &binding_grab;
> -	weston_keyboard_start_grab(seat->keyboard, &grab->grab);
> +	weston_keyboard_start_grab(keyboard, &grab->grab);
>  
>  	/* Notify the surface which had the focus before this binding
>  	 * triggered that we stole a keypress from under it, by forcing
> @@ -268,9 +269,9 @@ install_binding_grab(struct weston_seat *seat, uint32_t time, uint32_t key,
>  	 * If the old focus surface is different than the new one it
>  	 * means it was changed in the binding handler, so it received
>  	 * the enter event already. */
> -	if (focus && seat->keyboard->focus == focus) {
> -		weston_keyboard_set_focus(seat->keyboard, NULL);
> -		weston_keyboard_set_focus(seat->keyboard, focus);
> +	if (focus && keyboard->focus == focus) {
> +		weston_keyboard_set_focus(keyboard, NULL);
> +		weston_keyboard_set_focus(keyboard, focus);
>  	}
>  }
>  
> @@ -280,6 +281,7 @@ weston_compositor_run_key_binding(struct weston_compositor *compositor,
>  				  uint32_t time, uint32_t key,
>  				  enum wl_keyboard_key_state state)
>  {
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	struct weston_binding *b, *tmp;
>  	struct weston_surface *focus;
>  
> @@ -293,14 +295,14 @@ weston_compositor_run_key_binding(struct weston_compositor *compositor,
>  	wl_list_for_each_safe(b, tmp, &compositor->key_binding_list, link) {
>  		if (b->key == key && b->modifier == seat->modifier_state) {
>  			weston_key_binding_handler_t handler = b->handler;
> -			focus = seat->keyboard->focus;
> +			focus = keyboard->focus;
>  			handler(seat, time, key, b->data);
>  
>  			/* If this was a key binding and it didn't
>  			 * install a keyboard grab, install one now to
>  			 * swallow the key press. */
> -			if (seat->keyboard->grab ==
> -			    &seat->keyboard->default_grab)
> +			if (keyboard->grab ==
> +			    &keyboard->default_grab)
>  				install_binding_grab(seat, time, key, focus);
>  		}
>  	}
> @@ -313,8 +315,9 @@ weston_compositor_run_modifier_binding(struct weston_compositor *compositor,
>  				       enum wl_keyboard_key_state state)
>  {
>  	struct weston_binding *b, *tmp;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  
> -	if (seat->keyboard->grab != &seat->keyboard->default_grab)
> +	if (keyboard->grab != &keyboard->default_grab)
>  		return;
>  
>  	wl_list_for_each_safe(b, tmp, &compositor->modifier_binding_list, link) {
> @@ -366,8 +369,9 @@ weston_compositor_run_touch_binding(struct weston_compositor *compositor,
>  				    int touch_type)
>  {
>  	struct weston_binding *b, *tmp;
> +	struct weston_touch *touch = weston_seat_get_touch(seat);
>  
> -	if (seat->touch->num_tp != 1 || touch_type != WL_TOUCH_DOWN)
> +	if (touch->num_tp != 1 || touch_type != WL_TOUCH_DOWN)
>  		return;
>  
>  	wl_list_for_each_safe(b, tmp, &compositor->touch_binding_list, link) {
> @@ -539,6 +543,10 @@ static void
>  debug_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
>  {
>  	struct debug_binding_grab *grab;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
> +
> +	if (!keyboard)
> +		return;

Why add this test here? We get here through a key binding, meaning we
just received a key. I assume we won't loose the keyboard before we have
already passed this path?

>  
>  	grab = calloc(1, sizeof *grab);
>  	if (!grab)
> @@ -547,7 +555,7 @@ debug_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
>  	grab->seat = seat;
>  	grab->key[0] = key;
>  	grab->grab.interface = &debug_binding_keyboard_grab;
> -	weston_keyboard_start_grab(seat->keyboard, &grab->grab);
> +	weston_keyboard_start_grab(keyboard, &grab->grab);
>  }
>  
>  /** Install the trigger binding for debug bindings.
> diff --git a/src/compositor-drm.c b/src/compositor-drm.c
> index 43197a8..7b1442d 100644
> --- a/src/compositor-drm.c
> +++ b/src/compositor-drm.c
> @@ -1893,16 +1893,20 @@ setup_output_seat_constraint(struct drm_compositor *ec,
>  			     const char *s)
>  {
>  	if (strcmp(s, "") != 0) {
> +		struct weston_pointer *pointer;
>  		struct udev_seat *seat;
>  
>  		seat = udev_seat_get_named(&ec->input, s);
> -		if (seat)
> -			seat->base.output = output;
> +		if (!seat)
> +			return;
> +
> +		seat->base.output = output;
>  
> -		if (seat && seat->base.pointer)
> -			weston_pointer_clamp(seat->base.pointer,
> -					     &seat->base.pointer->x,
> -					     &seat->base.pointer->y);
> +		pointer = weston_seat_get_pointer(&seat->base);
> +		if (pointer)
> +			weston_pointer_clamp(pointer,
> +					     &pointer->x,
> +					     &pointer->y);
>  	}
>  }
>  
> diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
> index 6c33361..6a86250 100644
> --- a/src/compositor-wayland.c
> +++ b/src/compositor-wayland.c
> @@ -1418,6 +1418,7 @@ input_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format,
>  		    int fd, uint32_t size)
>  {
>  	struct wayland_input *input = data;
> +	struct weston_keyboard *weston_keyboard;
>  	struct xkb_keymap *keymap;
>  	char *map_str;
>  
> @@ -1456,7 +1457,8 @@ input_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format,
>  
>  	close(fd);
>  
> -	if (input->base.keyboard)
> +	weston_keyboard = weston_seat_get_keyboard(&input->base);
> +	if (weston_keyboard)

This change will cause compositor-wayland not being able to update the
keymap when the parent compositor does so.

>  		weston_seat_update_keymap(&input->base, keymap);
>  	else
>  		weston_seat_init_keyboard(&input->base, keymap);
> @@ -1551,6 +1553,7 @@ input_handle_modifiers(void *data, struct wl_keyboard *keyboard,
>  		       uint32_t mods_latched, uint32_t mods_locked,
>  		       uint32_t group)
>  {
> +	struct weston_keyboard *weston_keyboard;
>  	struct wayland_input *input = data;
>  	struct wayland_compositor *c = input->compositor;
>  	uint32_t serial_out;
> @@ -1563,7 +1566,8 @@ input_handle_modifiers(void *data, struct wl_keyboard *keyboard,
>  	else
>  		serial_out = wl_display_next_serial(c->base.wl_display);
>  
> -	xkb_state_update_mask(input->base.keyboard->xkb_state.state,
> +	weston_keyboard = weston_seat_get_keyboard(&input->base);
> +	xkb_state_update_mask(weston_keyboard->xkb_state.state,
>  			      mods_depressed, mods_latched,
>  			      mods_locked, 0, 0, group);
>  	notify_modifiers(&input->base, serial_out);
> diff --git a/src/compositor-x11.c b/src/compositor-x11.c
> index 9792ac6..1cbdbc4 100644
> --- a/src/compositor-x11.c
> +++ b/src/compositor-x11.c
> @@ -169,9 +169,13 @@ x11_compositor_get_keymap(struct x11_compositor *c)
>  static uint32_t
>  get_xkb_mod_mask(struct x11_compositor *c, uint32_t in)
>  {
> -	struct weston_xkb_info *info = c->core_seat.keyboard->xkb_info;
> +	struct weston_keyboard *keyboard;
> +	struct weston_xkb_info *info;
>  	uint32_t ret = 0;
>  
> +	keyboard = weston_seat_get_keyboard(&c->core_seat);
> +	info = keyboard->xkb_info;
> +
>  	if ((in & ShiftMask) && info->shift_mod != XKB_MOD_INVALID)
>  		ret |= (1 << info->shift_mod);
>  	if ((in & LockMask) && info->caps_mod != XKB_MOD_INVALID)
> @@ -201,6 +205,7 @@ x11_compositor_setup_xkb(struct x11_compositor *c)
>  	c->xkb_event_base = 0;
>  	return;
>  #else
> +	struct weston_keyboard *keyboard;
>  	const xcb_query_extension_reply_t *ext;
>  	xcb_generic_error_t *error;
>  	xcb_void_cookie_t select;
> @@ -280,7 +285,8 @@ x11_compositor_setup_xkb(struct x11_compositor *c)
>  		return;
>  	}
>  
> -	xkb_state_update_mask(c->core_seat.keyboard->xkb_state.state,
> +	keyboard = weston_seat_get_keyboard(&c->core_seat);
> +	xkb_state_update_mask(keyboard->xkb_state.state,
>  			      get_xkb_mod_mask(c, state_reply->baseMods),
>  			      get_xkb_mod_mask(c, state_reply->latchedMods),
>  			      get_xkb_mod_mask(c, state_reply->lockedMods),
> @@ -963,7 +969,10 @@ static void delete_cb(void *data)
>  static void
>  update_xkb_state(struct x11_compositor *c, xcb_xkb_state_notify_event_t *state)
>  {
> -	xkb_state_update_mask(c->core_seat.keyboard->xkb_state.state,
> +	struct weston_keyboard *keyboard;
> +
> +	keyboard = weston_seat_get_keyboard(&c->core_seat);
> +	xkb_state_update_mask(keyboard->xkb_state.state,
>  			      get_xkb_mod_mask(c, state->baseMods),
>  			      get_xkb_mod_mask(c, state->latchedMods),
>  			      get_xkb_mod_mask(c, state->lockedMods),
> @@ -991,9 +1000,10 @@ static void
>  update_xkb_state_from_core(struct x11_compositor *c, uint16_t x11_mask)
>  {
>  	uint32_t mask = get_xkb_mod_mask(c, x11_mask);
> -	struct weston_keyboard *keyboard = c->core_seat.keyboard;
> +	struct weston_keyboard *keyboard;
>  
> -	xkb_state_update_mask(c->core_seat.keyboard->xkb_state.state,
> +	keyboard = weston_seat_get_keyboard(&c->core_seat);
> +	xkb_state_update_mask(keyboard->xkb_state.state,
>  			      keyboard->modifiers.mods_depressed & mask,
>  			      keyboard->modifiers.mods_latched & mask,
>  			      keyboard->modifiers.mods_locked & mask,
> diff --git a/src/compositor.c b/src/compositor.c
> index 698ee52..6b744c5 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -146,7 +146,7 @@ static void weston_mode_switch_finish(struct weston_output *output,
>  	/* If a pointer falls outside the outputs new geometry, move it to its
>  	 * lower-right corner */
>  	wl_list_for_each(seat, &output->compositor->seat_list, link) {
> -		struct weston_pointer *pointer = seat->pointer;
> +		struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  		int32_t x, y;
>  
>  		if (!pointer)
> @@ -1806,15 +1806,20 @@ weston_view_unmap(struct weston_view *view)
>  		return;
>  
>  	wl_list_for_each(seat, &view->surface->compositor->seat_list, link) {
> -		if (seat->keyboard && seat->keyboard->focus == view->surface)
> -			weston_keyboard_set_focus(seat->keyboard, NULL);
> -		if (seat->pointer && seat->pointer->focus == view)
> -			weston_pointer_set_focus(seat->pointer,
> +		struct weston_touch *touch = weston_seat_get_touch(seat);
> +		struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +		struct weston_keyboard *keyboard =
> +						weston_seat_get_keyboard(seat);

nit: Same indentation inconsistency as above.

> +
> +		if (keyboard && keyboard->focus == view->surface)
> +			weston_keyboard_set_focus(keyboard, NULL);
> +		if (pointer && pointer->focus == view)
> +			weston_pointer_set_focus(pointer,
>  						 NULL,
>  						 wl_fixed_from_int(0),
>  						 wl_fixed_from_int(0));
> -		if (seat->touch && seat->touch->focus == view)
> -			weston_touch_set_focus(seat->touch, NULL);
> +		if (touch && touch->focus == view)
> +			weston_touch_set_focus(touch, NULL);
>  	}
>  }
>  
> @@ -4646,8 +4651,10 @@ weston_compositor_set_default_pointer_grab(struct weston_compositor *ec,
>  
>  	ec->default_pointer_grab = interface;
>  	wl_list_for_each(seat, &ec->seat_list, link) {
> -		if (seat->pointer) {
> -			weston_pointer_set_default_grab(seat->pointer,
> +		struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +
> +		if (pointer) {
> +			weston_pointer_set_default_grab(pointer,
>  							interface);
>  		}
>  	}
> @@ -5414,8 +5421,11 @@ int main(int argc, char *argv[])
>  	weston_config_section_get_bool(section, "numlock-on", &numlock_on, 0);
>  	if (numlock_on) {
>  		wl_list_for_each(seat, &ec->seat_list, link) {
> -			if (seat->keyboard)
> -				weston_keyboard_set_locks(seat->keyboard,
> +			struct weston_keyboard *keyboard =
> +						weston_seat_get_keyboard(seat);

nit: Same indentation inconsistency as above.

> +
> +			if (keyboard)
> +				weston_keyboard_set_locks(keyboard,
>  							  WESTON_NUM_LOCK,
>  							  WESTON_NUM_LOCK);
>  		}
> diff --git a/src/compositor.h b/src/compositor.h
> index f9834ba..35c6a30 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -509,9 +509,9 @@ struct weston_seat {
>  	struct wl_list base_resource_list;
>  
>  	struct wl_global *global;
> -	struct weston_pointer *pointer;
> -	struct weston_keyboard *keyboard;
> -	struct weston_touch *touch;
> +	struct weston_pointer *pointer_resource;
> +	struct weston_keyboard *keyboard_resource;
> +	struct weston_touch *touch_resource;

These names are misleading. It's not a wl_resource (which usually
carries such names).

Maybe a better cleanup altogether would be to free the instances, set
seat->pointer to NULL, but keep some relevant state around, i.e. have
weston_pointer_state in weston_seat, that a weston_seat->pointer->state
is set to. We could keep pointer position etc there, while seat->pointer
would be NULL.

But before doing that we really need to check places which previously
relied on pointer/keyboard/touch never going away so they won't break.

>  	int pointer_device_count;
>  	int keyboard_device_count;
>  	int touch_device_count;
> @@ -1572,6 +1572,15 @@ weston_parse_transform(const char *transform, uint32_t *out);
>  const char *
>  weston_transform_to_string(uint32_t output_transform);
>  
> +struct weston_keyboard *
> +weston_seat_get_keyboard(struct weston_seat *seat);
> +
> +struct weston_pointer *
> +weston_seat_get_pointer(struct weston_seat *seat);
> +
> +struct weston_touch *
> +weston_seat_get_touch(struct weston_seat *seat);
> +
>  #ifdef  __cplusplus
>  }
>  #endif
> diff --git a/src/data-device.c b/src/data-device.c
> index 3e7baf9..d2699fd 100644
> --- a/src/data-device.c
> +++ b/src/data-device.c
> @@ -658,23 +658,25 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
>  		       struct wl_resource *icon_resource, uint32_t serial)
>  {
>  	struct weston_seat *seat = wl_resource_get_user_data(resource);
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +	struct weston_touch *touch = weston_seat_get_touch(seat);
>  	struct weston_surface *origin = wl_resource_get_user_data(origin_resource);
>  	struct weston_data_source *source = NULL;
>  	struct weston_surface *icon = NULL;
>  	int is_pointer_grab, is_touch_grab;
>  	int32_t ret = 0;
>  
> -	is_pointer_grab = seat->pointer &&
> -			  seat->pointer->button_count == 1 &&
> -			  seat->pointer->grab_serial == serial &&
> -			  seat->pointer->focus &&
> -			  seat->pointer->focus->surface == origin;
> +	is_pointer_grab = pointer &&
> +			  pointer->button_count == 1 &&
> +			  pointer->grab_serial == serial &&
> +			  pointer->focus &&
> +			  pointer->focus->surface == origin;
>  
> -	is_touch_grab = seat->touch &&
> -			seat->touch->num_tp == 1 &&
> -			seat->touch->grab_serial == serial &&
> -			seat->touch->focus &&
> -			seat->touch->focus->surface == origin;
> +	is_touch_grab = touch &&
> +			touch->num_tp == 1 &&
> +			touch->grab_serial == serial &&
> +			touch->focus &&
> +			touch->focus->surface == origin;
>  
>  	if (!is_pointer_grab && !is_touch_grab)
>  		return;
> @@ -694,9 +696,9 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
>  	}
>  
>  	if (is_pointer_grab)
> -		ret = weston_pointer_start_drag(seat->pointer, source, icon, client);
> +		ret = weston_pointer_start_drag(pointer, source, icon, client);
>  	else if (is_touch_grab)
> -		ret = weston_touch_start_drag(seat->touch, source, icon, client);
> +		ret = weston_touch_start_drag(touch, source, icon, client);
>  
>  	if (ret < 0)
>  		wl_resource_post_no_memory(resource);
> @@ -707,13 +709,14 @@ destroy_selection_data_source(struct wl_listener *listener, void *data)
>  {
>  	struct weston_seat *seat = container_of(listener, struct weston_seat,
>  						selection_data_source_listener);
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	struct wl_resource *data_device;
>  	struct weston_surface *focus = NULL;
>  
>  	seat->selection_data_source = NULL;
>  
> -	if (seat->keyboard)
> -		focus = seat->keyboard->focus;
> +	if (keyboard)
> +		focus = keyboard->focus;
>  	if (focus && focus->resource) {
>  		data_device = wl_resource_find_for_client(&seat->drag_resource_list,
>  							  wl_resource_get_client(focus->resource));
> @@ -761,6 +764,7 @@ WL_EXPORT void
>  weston_seat_set_selection(struct weston_seat *seat,
>  			  struct weston_data_source *source, uint32_t serial)
>  {
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	struct weston_surface *focus = NULL;
>  
>  	if (seat->selection_data_source &&
> @@ -776,8 +780,8 @@ weston_seat_set_selection(struct weston_seat *seat,
>  	seat->selection_data_source = source;
>  	seat->selection_serial = serial;
>  
> -	if (seat->keyboard)
> -		focus = seat->keyboard->focus;
> +	if (keyboard)
> +		focus = keyboard->focus;
>  	if (focus && focus->resource) {
>  		weston_seat_send_selection(seat, wl_resource_get_client(focus->resource));
>  	}
> @@ -935,11 +939,12 @@ WL_EXPORT void
>  wl_data_device_set_keyboard_focus(struct weston_seat *seat)
>  {
>  	struct weston_surface *focus;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  
> -	if (!seat->keyboard)
> +	if (!keyboard)
>  		return;
>  
> -	focus = seat->keyboard->focus;
> +	focus = keyboard->focus;
>  	if (!focus || !focus->resource)
>  		return;
>  
> diff --git a/src/input.c b/src/input.c
> index 6604c5d..3f9e267 100644
> --- a/src/input.c
> +++ b/src/input.c
> @@ -49,12 +49,12 @@ static void unbind_resource(struct wl_resource *resource)
>  WL_EXPORT void
>  weston_seat_repick(struct weston_seat *seat)
>  {
> -	const struct weston_pointer *pointer = seat->pointer;
> +	const struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  
> -	if (pointer == NULL)
> +	if (!pointer)
>  		return;
>  
> -	pointer->grab->interface->focus(seat->pointer->grab);
> +	pointer->grab->interface->focus(pointer->grab);
>  }
>  
>  static void
> @@ -387,7 +387,8 @@ default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
>  				uint32_t mods_locked, uint32_t group)
>  {
>  	struct weston_keyboard *keyboard = grab->keyboard;
> -	struct weston_pointer *pointer = grab->keyboard->seat->pointer;
> +	struct weston_pointer *pointer =
> +				weston_seat_get_pointer(grab->keyboard->seat);

nit: Same indentation inconsistency as above.

>  	struct wl_resource *resource;
>  	struct wl_list *resource_list;
>  
> @@ -622,7 +623,7 @@ weston_pointer_set_focus(struct weston_pointer *pointer,
>  			 struct weston_view *view,
>  			 wl_fixed_t sx, wl_fixed_t sy)
>  {
> -	struct weston_keyboard *kbd = pointer->seat->keyboard;
> +	struct weston_keyboard *kbd = weston_seat_get_keyboard(pointer->seat);
>  	struct wl_resource *resource;
>  	struct wl_display *display = pointer->seat->compositor->wl_display;
>  	uint32_t serial;
> @@ -942,7 +943,7 @@ notify_motion(struct weston_seat *seat,
>  	      uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
>  {
>  	struct weston_compositor *ec = seat->compositor;
> -	struct weston_pointer *pointer = seat->pointer;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  
>  	weston_compositor_wake(ec);
>  	pointer->grab->interface->motion(pointer->grab, time, pointer->x + dx, pointer->y + dy);
> @@ -952,7 +953,7 @@ static void
>  run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new)
>  {
>  	struct weston_compositor *compositor = seat->compositor;
> -	struct weston_keyboard *keyboard = seat->keyboard;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	uint32_t diff;
>  	unsigned int i;
>  	struct {
> @@ -989,7 +990,7 @@ notify_motion_absolute(struct weston_seat *seat,
>  		       uint32_t time, wl_fixed_t x, wl_fixed_t y)
>  {
>  	struct weston_compositor *ec = seat->compositor;
> -	struct weston_pointer *pointer = seat->pointer;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  
>  	weston_compositor_wake(ec);
>  	pointer->grab->interface->motion(pointer->grab, time, x, y);
> @@ -1000,9 +1001,10 @@ weston_surface_activate(struct weston_surface *surface,
>  			struct weston_seat *seat)
>  {
>  	struct weston_compositor *compositor = seat->compositor;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  
> -	if (seat->keyboard) {
> -		weston_keyboard_set_focus(seat->keyboard, surface);
> +	if (keyboard) {
> +		weston_keyboard_set_focus(keyboard, surface);
>  		wl_data_device_set_keyboard_focus(seat);
>  	}
>  
> @@ -1014,7 +1016,7 @@ notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
>  	      enum wl_pointer_button_state state)
>  {
>  	struct weston_compositor *compositor = seat->compositor;
> -	struct weston_pointer *pointer = seat->pointer;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  
>  	if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
>  		weston_compositor_idle_inhibit(compositor);
> @@ -1045,7 +1047,7 @@ notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
>  	    wl_fixed_t value)
>  {
>  	struct weston_compositor *compositor = seat->compositor;
> -	struct weston_pointer *pointer = seat->pointer;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  	struct wl_resource *resource;
>  	struct wl_list *resource_list;
>  
> @@ -1120,7 +1122,7 @@ weston_keyboard_set_locks(struct weston_keyboard *keyboard,
>  WL_EXPORT void
>  notify_modifiers(struct weston_seat *seat, uint32_t serial)
>  {
> -	struct weston_keyboard *keyboard = seat->keyboard;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	struct weston_keyboard_grab *grab = keyboard->grab;
>  	uint32_t mods_depressed, mods_latched, mods_locked, group;
>  	uint32_t mods_lookup;
> @@ -1138,19 +1140,19 @@ notify_modifiers(struct weston_seat *seat, uint32_t serial)
>  	group = xkb_state_serialize_layout(keyboard->xkb_state.state,
>  					   XKB_STATE_LAYOUT_EFFECTIVE);
>  
> -	if (mods_depressed != seat->keyboard->modifiers.mods_depressed ||
> -	    mods_latched != seat->keyboard->modifiers.mods_latched ||
> -	    mods_locked != seat->keyboard->modifiers.mods_locked ||
> -	    group != seat->keyboard->modifiers.group)
> +	if (mods_depressed != keyboard->modifiers.mods_depressed ||
> +	    mods_latched != keyboard->modifiers.mods_latched ||
> +	    mods_locked != keyboard->modifiers.mods_locked ||
> +	    group != keyboard->modifiers.group)
>  		changed = 1;
>  
> -	run_modifier_bindings(seat, seat->keyboard->modifiers.mods_depressed,
> +	run_modifier_bindings(seat, keyboard->modifiers.mods_depressed,
>  	                      mods_depressed);
>  
> -	seat->keyboard->modifiers.mods_depressed = mods_depressed;
> -	seat->keyboard->modifiers.mods_latched = mods_latched;
> -	seat->keyboard->modifiers.mods_locked = mods_locked;
> -	seat->keyboard->modifiers.group = group;
> +	keyboard->modifiers.mods_depressed = mods_depressed;
> +	keyboard->modifiers.mods_latched = mods_latched;
> +	keyboard->modifiers.mods_locked = mods_locked;
> +	keyboard->modifiers.group = group;
>  
>  	/* And update the modifier_state for bindings. */
>  	mods_lookup = mods_depressed | mods_latched;
> @@ -1192,7 +1194,7 @@ static void
>  update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
>  		      enum wl_keyboard_key_state state)
>  {
> -	struct weston_keyboard *keyboard = seat->keyboard;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	enum xkb_key_direction direction;
>  
>  	/* Keyboard modifiers don't exist in raw keyboard mode */
> @@ -1236,7 +1238,7 @@ weston_xkb_info_create(struct xkb_keymap *keymap);
>  static void
>  update_keymap(struct weston_seat *seat)
>  {
> -	struct weston_keyboard *keyboard = seat->keyboard;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	struct wl_resource *resource;
>  	struct weston_xkb_info *xkb_info;
>  	struct xkb_state *state;
> @@ -1276,9 +1278,9 @@ update_keymap(struct weston_seat *seat)
>  	xkb_state_unref(keyboard->xkb_state.state);
>  	keyboard->xkb_state.state = state;
>  
> -	wl_resource_for_each(resource, &seat->keyboard->resource_list)
> +	wl_resource_for_each(resource, &keyboard->resource_list)
>  		send_keymap(resource, xkb_info);
> -	wl_resource_for_each(resource, &seat->keyboard->focus_resource_list)
> +	wl_resource_for_each(resource, &keyboard->focus_resource_list)
>  		send_keymap(resource, xkb_info);
>  
>  	notify_modifiers(seat, wl_display_next_serial(seat->compositor->wl_display));
> @@ -1286,10 +1288,10 @@ update_keymap(struct weston_seat *seat)
>  	if (!latched_mods && !locked_mods)
>  		return;
>  
> -	wl_resource_for_each(resource, &seat->keyboard->resource_list)
> -		send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), seat->keyboard);
> -	wl_resource_for_each(resource, &seat->keyboard->focus_resource_list)
> -		send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), seat->keyboard);
> +	wl_resource_for_each(resource, &keyboard->resource_list)
> +		send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
> +	wl_resource_for_each(resource, &keyboard->focus_resource_list)
> +		send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
>  }
>  #else
>  WL_EXPORT void
> @@ -1315,7 +1317,7 @@ notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
>  	   enum weston_key_state_update update_state)
>  {
>  	struct weston_compositor *compositor = seat->compositor;
> -	struct weston_keyboard *keyboard = seat->keyboard;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	struct weston_keyboard_grab *grab = keyboard->grab;
>  	uint32_t *k, *end;
>  
> @@ -1372,8 +1374,10 @@ WL_EXPORT void
>  notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
>  		     wl_fixed_t x, wl_fixed_t y)
>  {
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +
>  	if (output) {
> -		weston_pointer_move(seat->pointer, x, y);
> +		weston_pointer_move(pointer, x, y);
>  	} else {
>  		/* FIXME: We should call weston_pointer_set_focus(seat,
>  		 * NULL) here, but somehow that breaks re-entry... */
> @@ -1396,7 +1400,7 @@ notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
>  			 enum weston_key_state_update update_state)
>  {
>  	struct weston_compositor *compositor = seat->compositor;
> -	struct weston_keyboard *keyboard = seat->keyboard;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	struct weston_surface *surface;
>  	uint32_t *k, serial;
>  
> @@ -1422,7 +1426,8 @@ WL_EXPORT void
>  notify_keyboard_focus_out(struct weston_seat *seat)
>  {
>  	struct weston_compositor *compositor = seat->compositor;
> -	struct weston_keyboard *keyboard = seat->keyboard;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  	uint32_t *k, serial;
>  
>  	serial = wl_display_next_serial(compositor->wl_display);
> @@ -1444,8 +1449,8 @@ notify_keyboard_focus_out(struct weston_seat *seat)
>  
>  	weston_keyboard_set_focus(keyboard, NULL);
>  	weston_keyboard_cancel_grab(keyboard);
> -	if (seat->pointer)
> -		weston_pointer_cancel_grab(seat->pointer);
> +	if (pointer)
> +		weston_pointer_cancel_grab(pointer);
>  }
>  
>  WL_EXPORT void
> @@ -1503,7 +1508,7 @@ notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
>               wl_fixed_t x, wl_fixed_t y, int touch_type)
>  {
>  	struct weston_compositor *ec = seat->compositor;
> -	struct weston_touch *touch = seat->touch;
> +	struct weston_touch *touch = weston_seat_get_touch(seat);
>  	struct weston_touch_grab *grab = touch->grab;
>  	struct weston_view *ev;
>  	wl_fixed_t sx, sy;
> @@ -1582,7 +1587,7 @@ notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
>  WL_EXPORT void
>  notify_touch_frame(struct weston_seat *seat)
>  {
> -	struct weston_touch *touch = seat->touch;
> +	struct weston_touch *touch = weston_seat_get_touch(seat);
>  	struct weston_touch_grab *grab = touch->grab;
>  
>  	grab->interface->frame(grab);
> @@ -1633,6 +1638,9 @@ pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
>  	struct weston_pointer *pointer = wl_resource_get_user_data(resource);
>  	struct weston_surface *surface = NULL;
>  
> +	if (!pointer)
> +		return;
> +
>  	if (surface_resource)
>  		surface = wl_resource_get_user_data(surface_resource);
>  
> @@ -1702,9 +1710,13 @@ seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
>  		 uint32_t id)
>  {
>  	struct weston_seat *seat = wl_resource_get_user_data(resource);
> +	/* We use the pointer_resource directly here because we only
> +	 * want to fail if the seat never contained a pointer.
> +	 */
> +	struct weston_pointer *pointer = seat->pointer_resource;
>  	struct wl_resource *cr;
>  
> -	if (!seat->pointer)
> +	if (!pointer)
>  		return;
>  
>          cr = wl_resource_create(client, &wl_pointer_interface,
> @@ -1717,25 +1729,25 @@ seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
>  	/* May be moved to focused list later by either
>  	 * weston_pointer_set_focus or directly if this client is already
>  	 * focused */
> -	wl_list_insert(&seat->pointer->resource_list, wl_resource_get_link(cr));
> -	wl_resource_set_implementation(cr, &pointer_interface, seat->pointer,
> +	wl_list_insert(&pointer->resource_list, wl_resource_get_link(cr));
> +	wl_resource_set_implementation(cr, &pointer_interface, pointer,
>  				       unbind_resource);
>  
> -	if (seat->pointer->focus && seat->pointer->focus->surface->resource &&
> -	    wl_resource_get_client(seat->pointer->focus->surface->resource) == client) {
> +	if (pointer->focus && pointer->focus->surface->resource &&
> +	    wl_resource_get_client(pointer->focus->surface->resource) == client) {
>  		wl_fixed_t sx, sy;
>  
> -		weston_view_from_global_fixed(seat->pointer->focus,
> -					      seat->pointer->x,
> -					      seat->pointer->y,
> +		weston_view_from_global_fixed(pointer->focus,
> +					      pointer->x,
> +					      pointer->y,
>  					      &sx, &sy);
>  
>  		wl_list_remove(wl_resource_get_link(cr));
> -		wl_list_insert(&seat->pointer->focus_resource_list,
> +		wl_list_insert(&pointer->focus_resource_list,
>  			       wl_resource_get_link(cr));
>  		wl_pointer_send_enter(cr,
> -				      seat->pointer->focus_serial,
> -				      seat->pointer->focus->surface->resource,
> +				      pointer->focus_serial,
> +				      pointer->focus->surface->resource,
>  				      sx, sy);
>  	}
>  }
> @@ -1754,16 +1766,19 @@ static bool
>  should_send_modifiers_to_client(struct weston_seat *seat,
>  				struct wl_client *client)
>  {
> -	if (seat->keyboard &&
> -	    seat->keyboard->focus &&
> -	    seat->keyboard->focus->resource &&
> -	    wl_resource_get_client(seat->keyboard->focus->resource) == client)
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +
> +	if (keyboard &&
> +	    keyboard->focus &&
> +	    keyboard->focus->resource &&
> +	    wl_resource_get_client(keyboard->focus->resource) == client)
>  		return true;
>  
> -	if (seat->pointer &&
> -	    seat->pointer->focus &&
> -	    seat->pointer->focus->surface->resource &&
> -	    wl_resource_get_client(seat->pointer->focus->surface->resource) == client)
> +	if (pointer &&
> +	    pointer->focus &&
> +	    pointer->focus->surface->resource &&
> +	    wl_resource_get_client(pointer->focus->surface->resource) == client)
>  		return true;
>  
>  	return false;
> @@ -1774,10 +1789,13 @@ seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
>  		  uint32_t id)
>  {
>  	struct weston_seat *seat = wl_resource_get_user_data(resource);
> -	struct weston_keyboard *keyboard = seat->keyboard;
> +	/* We use the keyboard_resource directly here because we only
> +	 * want to fail if the seat never contained a keyboard.
> +	 */
> +	struct weston_keyboard *keyboard = seat->keyboard_resource;
>  	struct wl_resource *cr;
>  
> -	if (!seat->keyboard)
> +	if (!keyboard)
>  		return;
>  
>          cr = wl_resource_create(client, &wl_keyboard_interface,
> @@ -1790,7 +1808,7 @@ seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
>  	/* May be moved to focused list later by either
>  	 * weston_keyboard_set_focus or directly if this client is already
>  	 * focused */
> -	wl_list_insert(&seat->keyboard->resource_list, wl_resource_get_link(cr));
> +	wl_list_insert(&keyboard->resource_list, wl_resource_get_link(cr));
>  	wl_resource_set_implementation(cr, &keyboard_interface,
>  				       seat, unbind_resource);
>  
> @@ -1813,27 +1831,26 @@ seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
>  	}
>  
>  	if (should_send_modifiers_to_client(seat, client)) {
> -		send_modifiers_to_resource(seat->keyboard,
> +		send_modifiers_to_resource(keyboard,
>  					   cr,
> -					   seat->keyboard->focus_serial);
> +					   keyboard->focus_serial);
>  	}
>  
> -	if (seat->keyboard->focus && seat->keyboard->focus->resource &&
> -	    wl_resource_get_client(seat->keyboard->focus->resource) == client) {
> -		struct weston_surface *surface =
> -			(struct weston_surface *) seat->keyboard->focus;
> +	if (keyboard->focus && keyboard->focus->resource &&
> +	    wl_resource_get_client(keyboard->focus->resource) == client) {
> +		struct weston_surface *surface = keyboard->focus;
>  
>  		wl_list_remove(wl_resource_get_link(cr));
> -		wl_list_insert(&seat->keyboard->focus_resource_list,
> +		wl_list_insert(&keyboard->focus_resource_list,
>  			       wl_resource_get_link(cr));
>  		wl_keyboard_send_enter(cr,
> -				       seat->keyboard->focus_serial,
> +				       keyboard->focus_serial,
>  				       surface->resource,
> -				       &seat->keyboard->keys);
> +				       &keyboard->keys);
>  
>  		/* If this is the first keyboard resource for this
>  		 * client... */
> -		if (seat->keyboard->focus_resource_list.prev ==
> +		if (keyboard->focus_resource_list.prev ==
>  		    wl_resource_get_link(cr))
>  			wl_data_device_set_keyboard_focus(seat);
>  	}
> @@ -1854,9 +1871,13 @@ seat_get_touch(struct wl_client *client, struct wl_resource *resource,
>  	       uint32_t id)
>  {
>  	struct weston_seat *seat = wl_resource_get_user_data(resource);
> +	/* We use the touch_resource directly here because we only
> +	 * want to fail if the seat never contained a touch device.
> +	 */
> +	struct weston_touch *touch = seat->touch_resource;
>  	struct wl_resource *cr;
>  
> -	if (!seat->touch)
> +	if (!touch)
>  		return;
>  
>          cr = wl_resource_create(client, &wl_touch_interface,
> @@ -1866,12 +1887,12 @@ seat_get_touch(struct wl_client *client, struct wl_resource *resource,
>  		return;
>  	}
>  
> -	if (seat->touch->focus &&
> -	    wl_resource_get_client(seat->touch->focus->surface->resource) == client) {
> -		wl_list_insert(&seat->touch->resource_list,
> +	if (touch->focus &&
> +	    wl_resource_get_client(touch->focus->surface->resource) == client) {
> +		wl_list_insert(&touch->resource_list,
>  			       wl_resource_get_link(cr));
>  	} else {
> -		wl_list_insert(&seat->touch->focus_resource_list,
> +		wl_list_insert(&touch->focus_resource_list,
>  			       wl_resource_get_link(cr));
>  	}
>  	wl_resource_set_implementation(cr, &touch_interface,
> @@ -1897,11 +1918,11 @@ bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
>  	wl_resource_set_implementation(resource, &seat_interface, data,
>  				       unbind_resource);
>  
> -	if (seat->pointer)
> +	if (seat->pointer_device_count)
>  		caps |= WL_SEAT_CAPABILITY_POINTER;
> -	if (seat->keyboard)
> +	if (seat->keyboard_device_count)
>  		caps |= WL_SEAT_CAPABILITY_KEYBOARD;
> -	if (seat->touch)
> +	if (seat->touch_device_count)
>  		caps |= WL_SEAT_CAPABILITY_TOUCH;
>  
>  	wl_seat_send_capabilities(resource, caps);
> @@ -2091,17 +2112,18 @@ weston_compositor_xkb_destroy(struct weston_compositor *ec)
>  WL_EXPORT void
>  weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap)
>  {
> -	if (!seat->keyboard || !keymap)
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
> +	if (!keyboard || !keymap)
>  		return;
>  
>  #ifdef ENABLE_XKBCOMMON
>  	if (!seat->compositor->use_xkbcommon)
>  		return;
>  
> -	xkb_keymap_unref(seat->keyboard->pending_keymap);
> -	seat->keyboard->pending_keymap = xkb_keymap_ref(keymap);
> +	xkb_keymap_unref(keyboard->pending_keymap);
> +	keyboard->pending_keymap = xkb_keymap_ref(keymap);
>  
> -	if (seat->keyboard->keys.size == 0)
> +	if (keyboard->keys.size == 0)
>  		update_keymap(seat);
>  #endif
>  }
> @@ -2111,7 +2133,7 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
>  {
>  	struct weston_keyboard *keyboard;
>  
> -	if (seat->keyboard) {
> +	if (seat->keyboard_resource) {
>  		seat->keyboard_device_count += 1;
>  		if (seat->keyboard_device_count == 1)
>  			seat_send_updated_caps(seat);
> @@ -2147,7 +2169,7 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
>  	}
>  #endif
>  
> -	seat->keyboard = keyboard;
> +	seat->keyboard_resource = keyboard;
>  	seat->keyboard_device_count = 1;
>  	keyboard->seat = seat;
>  
> @@ -2192,9 +2214,9 @@ weston_seat_release_keyboard(struct weston_seat *seat)
>  	seat->keyboard_device_count--;
>  	assert(seat->keyboard_device_count >= 0);
>  	if (seat->keyboard_device_count == 0) {
> -		weston_keyboard_set_focus(seat->keyboard, NULL);
> -		weston_keyboard_cancel_grab(seat->keyboard);
> -		weston_keyboard_reset_state(seat->keyboard);
> +		weston_keyboard_set_focus(seat->keyboard_resource, NULL);
> +		weston_keyboard_cancel_grab(seat->keyboard_resource);
> +		weston_keyboard_reset_state(seat->keyboard_resource);
>  		seat_send_updated_caps(seat);
>  	}
>  }
> @@ -2204,7 +2226,7 @@ weston_seat_init_pointer(struct weston_seat *seat)
>  {
>  	struct weston_pointer *pointer;
>  
> -	if (seat->pointer) {
> +	if (seat->pointer_resource) {
>  		seat->pointer_device_count += 1;
>  		if (seat->pointer_device_count == 1)
>  			seat_send_updated_caps(seat);
> @@ -2215,7 +2237,7 @@ weston_seat_init_pointer(struct weston_seat *seat)
>  	if (pointer == NULL)
>  		return;
>  
> -	seat->pointer = pointer;
> +	seat->pointer_resource = pointer;
>  	seat->pointer_device_count = 1;
>  	pointer->seat = seat;
>  
> @@ -2225,9 +2247,10 @@ weston_seat_init_pointer(struct weston_seat *seat)
>  WL_EXPORT void
>  weston_seat_release_pointer(struct weston_seat *seat)
>  {
> -	struct weston_pointer *pointer = seat->pointer;
> +	struct weston_pointer *pointer = seat->pointer_resource;
>  
>  	seat->pointer_device_count--;
> +	assert(seat->pointer_device_count >= 0);
>  	if (seat->pointer_device_count == 0) {
>  		weston_pointer_set_focus(pointer, NULL,
>  					 wl_fixed_from_int(0),
> @@ -2252,7 +2275,7 @@ weston_seat_init_touch(struct weston_seat *seat)
>  {
>  	struct weston_touch *touch;
>  
> -	if (seat->touch) {
> +	if (seat->touch_resource) {
>  		seat->touch_device_count += 1;
>  		if (seat->touch_device_count == 1)
>  			seat_send_updated_caps(seat);
> @@ -2263,7 +2286,7 @@ weston_seat_init_touch(struct weston_seat *seat)
>  	if (touch == NULL)
>  		return;
>  
> -	seat->touch = touch;
> +	seat->touch_resource = touch;
>  	seat->touch_device_count = 1;
>  	touch->seat = seat;
>  
> @@ -2274,10 +2297,11 @@ WL_EXPORT void
>  weston_seat_release_touch(struct weston_seat *seat)
>  {
>  	seat->touch_device_count--;
> +	assert(seat->touch_device_count >= 0);
>  	if (seat->touch_device_count == 0) {
> -		weston_touch_set_focus(seat->touch, NULL);
> -		weston_touch_cancel_grab(seat->touch);
> -		weston_touch_reset_state(seat->touch);
> +		weston_touch_set_focus(seat->touch_resource, NULL);
> +		weston_touch_cancel_grab(seat->touch_resource);
> +		weston_touch_reset_state(seat->touch_resource);
>  		seat_send_updated_caps(seat);
>  	}
>  }
> @@ -2317,16 +2341,82 @@ weston_seat_release(struct weston_seat *seat)
>  	if (seat->saved_kbd_focus)
>  		wl_list_remove(&seat->saved_kbd_focus_listener.link);
>  
> -	if (seat->pointer)
> -		weston_pointer_destroy(seat->pointer);
> -	if (seat->keyboard)
> -		weston_keyboard_destroy(seat->keyboard);
> -	if (seat->touch)
> -		weston_touch_destroy(seat->touch);
> +	if (seat->pointer_resource)
> +		weston_pointer_destroy(seat->pointer_resource);
> +	if (seat->keyboard_resource)
> +		weston_keyboard_destroy(seat->keyboard_resource);
> +	if (seat->touch_resource)
> +		weston_touch_destroy(seat->touch_resource);
>  
> -	free (seat->seat_name);
> +	free(seat->seat_name);
>  
>  	wl_global_destroy(seat->global);
>  
>  	wl_signal_emit(&seat->destroy_signal, seat);
>  }
> +
> +/** Get a seat's keyboard pointer
> + *
> + * \param seat The seat to query
> + * \return The seat's keyboard pointer, or NULL if no keyboard present
> + *
> + * The keyboard pointer for a seat isn't freed when all keyboards are removed,
> + * so should only be used when the seat's keyboard_device_count is greater
> + * than zero.  This function does that test and only returns a pointer
> + * when a keyboard is present.
> + */
> +WL_EXPORT struct weston_keyboard *
> +weston_seat_get_keyboard(struct weston_seat *seat)
> +{
> +	if (!seat)
> +		return NULL;
> +
> +	if (seat->keyboard_device_count)
> +		return seat->keyboard_resource;
> +
> +	return NULL;
> +}
> +
> +/** Get a seat's pointer pointer
> + *
> + * \param seat The seat to query
> + * \return The seat's pointer pointer, or NULL if no pointing device present
> + *
> + * The pointer pointer for a seat isn't freed when all mice are removed,
> + * so should only be used when the seat's pointer_device_count is greater
> + * than zero.  This function does that test and only returns a pointer
> + * when a pointing device is present.
> + */
> +WL_EXPORT struct weston_pointer *
> +weston_seat_get_pointer(struct weston_seat *seat)
> +{
> +	if (!seat)
> +		return NULL;
> +
> +	if (seat->pointer_device_count)
> +		return seat->pointer_resource;
> +
> +	return NULL;
> +}
> +
> +/** Get a seat's touch pointer
> + *
> + * \param seat The seat to query
> + * \return The seat's touch pointer, or NULL if no touch device present
> + *
> + * The touch pointer for a seat isn't freed when all touch devices are removed,
> + * so should only be used when the seat's touch_device_count is greater
> + * than zero.  This function does that test and only returns a pointer
> + * when a touch device is present.
> + */
> +WL_EXPORT struct weston_touch *
> +weston_seat_get_touch(struct weston_seat *seat)
> +{
> +	if (!seat)
> +		return NULL;
> +
> +	if (seat->touch_device_count)
> +		return seat->touch_resource;
> +
> +	return NULL;
> +}
> diff --git a/src/libinput-device.c b/src/libinput-device.c
> index 567e5ea..3fb507f 100644
> --- a/src/libinput-device.c
> +++ b/src/libinput-device.c
> @@ -541,9 +541,10 @@ void
>  evdev_notify_keyboard_focus(struct weston_seat *seat,
>  			    struct wl_list *evdev_devices)
>  {
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	struct wl_array keys;
>  
> -	if (seat->keyboard_device_count == 0)
> +	if (!keyboard)
>  		return;
>  
>  	wl_array_init(&keys);
> diff --git a/src/libinput-seat.c b/src/libinput-seat.c
> index c0a87ea..3ac0183 100644
> --- a/src/libinput-seat.c
> +++ b/src/libinput-seat.c
> @@ -56,6 +56,7 @@ device_added(struct udev_input *input, struct libinput_device *libinput_device)
>  	struct libinput_seat *libinput_seat;
>  	struct weston_seat *seat;
>  	struct udev_seat *udev_seat;
> +	struct weston_pointer *pointer;
>  
>  	c = input->compositor;
>  	libinput_seat = libinput_device_get_seat(libinput_device);
> @@ -73,10 +74,11 @@ device_added(struct udev_input *input, struct libinput_device *libinput_device)
>  	udev_seat = (struct udev_seat *) seat;
>  	wl_list_insert(udev_seat->devices_list.prev, &device->link);
>  
> -	if (seat->output && seat->pointer)
> -		weston_pointer_clamp(seat->pointer,
> -				     &seat->pointer->x,
> -				     &seat->pointer->y);
> +	pointer = weston_seat_get_pointer(seat);
> +	if (seat->output && pointer)
> +		weston_pointer_clamp(pointer,
> +				     &pointer->x,
> +				     &pointer->y);
>  
>  	output_name = libinput_device_get_output_name(libinput_device);
>  	if (output_name) {
> @@ -368,8 +370,11 @@ udev_seat_create(struct udev_input *input, const char *seat_name)
>  static void
>  udev_seat_destroy(struct udev_seat *seat)
>  {
> +	struct weston_keyboard *keyboard;
> +
>  	udev_seat_remove_devices(seat);
> -	if (seat->base.keyboard)
> +	keyboard = weston_seat_get_keyboard(&seat->base);
> +	if (keyboard)
>  		notify_keyboard_focus_out(&seat->base);
>  	weston_seat_release(&seat->base);
>  	wl_list_remove(&seat->output_create_listener.link);
> diff --git a/src/screen-share.c b/src/screen-share.c
> index 524a0ca..49b8416 100644
> --- a/src/screen-share.c
> +++ b/src/screen-share.c
> @@ -1067,8 +1067,9 @@ share_output_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
>  {
>  	struct weston_output *output;
>  	struct screen_share *ss = data;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  
> -	if (!seat->pointer) {
> +	if (!pointer) {
>  		weston_log("Cannot pick output: Seat does not have pointer\n");
>  		return;
>  	}
> diff --git a/src/screenshooter.c b/src/screenshooter.c
> index 4e32db5..af66af3 100644
> --- a/src/screenshooter.c
> +++ b/src/screenshooter.c
> @@ -559,6 +559,7 @@ static void
>  recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
>  {
>  	struct weston_compositor *ec = seat->compositor;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	struct weston_output *output;
>  	struct wl_listener *listener = NULL;
>  	struct weston_recorder *recorder;
> @@ -582,9 +583,9 @@ recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *da
>  		recorder->destroying = 1;
>  		weston_output_schedule_repaint(recorder->output);
>  	} else {
> -		if (seat->keyboard && seat->keyboard->focus &&
> -		    seat->keyboard->focus->output)
> -			output = seat->keyboard->focus->output;
> +		if (keyboard && keyboard->focus &&
> +		    keyboard->focus->output)
> +			output = keyboard->focus->output;
>  		else
>  			output = container_of(ec->output_list.next,
>  					      struct weston_output, link);
> diff --git a/src/text-backend.c b/src/text-backend.c
> index 4dc7179..e5a3acb 100644
> --- a/src/text-backend.c
> +++ b/src/text-backend.c
> @@ -611,7 +611,7 @@ input_method_context_grab_keyboard(struct wl_client *client,
>  	struct input_method_context *context = wl_resource_get_user_data(resource);
>  	struct wl_resource *cr;
>  	struct weston_seat *seat = context->input_method->seat;
> -	struct weston_keyboard *keyboard = seat->keyboard;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  
>  	cr = wl_resource_create(client, &wl_keyboard_interface, 1, id);
>  	wl_resource_set_implementation(cr, NULL, context, unbind_keyboard);
> @@ -639,7 +639,7 @@ input_method_context_key(struct wl_client *client,
>  {
>  	struct input_method_context *context = wl_resource_get_user_data(resource);
>  	struct weston_seat *seat = context->input_method->seat;
> -	struct weston_keyboard *keyboard = seat->keyboard;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	struct weston_keyboard_grab *default_grab = &keyboard->default_grab;
>  
>  	default_grab->interface->key(default_grab, time, key, state_w);
> @@ -657,7 +657,7 @@ input_method_context_modifiers(struct wl_client *client,
>  	struct input_method_context *context = wl_resource_get_user_data(resource);
>  
>  	struct weston_seat *seat = context->input_method->seat;
> -	struct weston_keyboard *keyboard = seat->keyboard;
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
>  	struct weston_keyboard_grab *default_grab = &keyboard->default_grab;
>  
>  	default_grab->interface->modifiers(default_grab,
> @@ -758,10 +758,11 @@ input_method_context_end_keyboard_grab(struct input_method_context *context)
>  	struct weston_keyboard_grab *grab;
>  	struct weston_keyboard *keyboard;
>  
> -	if (!context->input_method->seat->keyboard)
> +	keyboard = weston_seat_get_keyboard(context->input_method->seat);
> +	if (!keyboard)
>  		return;
>  
> -	grab = &context->input_method->seat->keyboard->input_method_grab;
> +	grab = &keyboard->input_method_grab;
>  	keyboard = grab->keyboard;
>  	if (!keyboard)
>  		return;
> @@ -850,13 +851,15 @@ handle_keyboard_focus(struct wl_listener *listener, void *data)
>  static void
>  input_method_init_seat(struct weston_seat *seat)
>  {
> +	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
> +
>  	if (seat->input_method->focus_listener_initialized)
>  		return;
>  
> -	if (seat->keyboard) {
> +	if (keyboard) {
>  		seat->input_method->keyboard_focus_listener.notify = handle_keyboard_focus;
> -		wl_signal_add(&seat->keyboard->focus_signal, &seat->input_method->keyboard_focus_listener);
> -		seat->keyboard->input_method_grab.interface = &input_method_context_grab;
> +		wl_signal_add(&keyboard->focus_signal, &seat->input_method->keyboard_focus_listener);
> +		keyboard->input_method_grab.interface = &input_method_context_grab;
>  	}
>  
>  	seat->input_method->focus_listener_initialized = 1;
> diff --git a/src/zoom.c b/src/zoom.c
> index bee038b..38624e0 100644
> --- a/src/zoom.c
> +++ b/src/zoom.c
> @@ -129,9 +129,10 @@ WL_EXPORT void
>  weston_output_update_zoom(struct weston_output *output)
>  {
>  	struct weston_seat *seat = weston_zoom_pick_seat(output->compositor);
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  
> -	output->zoom.current.x = seat->pointer->x;
> -	output->zoom.current.y = seat->pointer->y;
> +	output->zoom.current.x = pointer->x;
> +	output->zoom.current.y = pointer->y;
>  
>  	weston_zoom_transition(output);
>  	weston_output_update_zoom_transform(output);
> @@ -152,13 +153,14 @@ WL_EXPORT void
>  weston_output_activate_zoom(struct weston_output *output)
>  {
>  	struct weston_seat *seat = weston_zoom_pick_seat(output->compositor);
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  
>  	if (output->zoom.active)
>  		return;
>  
>  	output->zoom.active = 1;
>  	output->disable_planes++;
> -	wl_signal_add(&seat->pointer->motion_signal,
> +	wl_signal_add(&pointer->motion_signal,
>  		      &output->zoom.motion_listener);
>  }
>  
> diff --git a/tests/surface-screenshot.c b/tests/surface-screenshot.c
> index 57ec925..c0b4bd2 100644
> --- a/tests/surface-screenshot.c
> +++ b/tests/surface-screenshot.c
> @@ -131,6 +131,7 @@ static void
>  trigger_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
>  		void *data)
>  {
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  	const char *prefix = "surfaceshot-";
>  	const char *suffix = ".pam";
>  	char fname[1024];
> @@ -143,12 +144,10 @@ trigger_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
>  	int ret;
>  	FILE *fp;
>  
> -	if (seat->pointer_device_count == 0 ||
> -	    !seat->pointer ||
> -	    !seat->pointer->focus)
> +	if (!pointer || !pointer->focus)
>  		return;
>  
> -	surface = seat->pointer->focus->surface;
> +	surface = pointer->focus->surface;
>  
>  	weston_surface_get_content_size(surface, &width, &height);
>  
> diff --git a/tests/weston-test.c b/tests/weston-test.c
> index 9f1f49b..284705a 100644
> --- a/tests/weston-test.c
> +++ b/tests/weston-test.c
> @@ -78,7 +78,10 @@ static void
>  notify_pointer_position(struct weston_test *test, struct wl_resource *resource)
>  {
>  	struct weston_seat *seat = get_seat(test);
> -	struct weston_pointer *pointer = seat->pointer;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
> +
> +	if (!pointer)
> +		return;
>  
>  	weston_test_send_pointer_position(resource, pointer->x, pointer->y);
>  }
> @@ -139,7 +142,7 @@ move_pointer(struct wl_client *client, struct wl_resource *resource,
>  {
>  	struct weston_test *test = wl_resource_get_user_data(resource);
>  	struct weston_seat *seat = get_seat(test);
> -	struct weston_pointer *pointer = seat->pointer;
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  
>  	notify_motion(seat, 100,
>  		      wl_fixed_from_int(x) - pointer->x,
> @@ -166,12 +169,13 @@ activate_surface(struct wl_client *client, struct wl_resource *resource,
>  		wl_resource_get_user_data(surface_resource) : NULL;
>  	struct weston_test *test = wl_resource_get_user_data(resource);
>  	struct weston_seat *seat;
> +	struct weston_keyboard *keyboard;
>  
>  	seat = get_seat(test);
> -
> +	keyboard = weston_seat_get_keyboard(seat);
>  	if (surface) {
>  		weston_surface_activate(surface, seat);
> -		notify_keyboard_focus_in(seat, &seat->keyboard->keys,
> +		notify_keyboard_focus_in(seat, &keyboard->keys,
>  					 STATE_UPDATE_AUTOMATIC);
>  	}
>  	else {
> diff --git a/xwayland/dnd.c b/xwayland/dnd.c
> index f0f2457..944c220 100644
> --- a/xwayland/dnd.c
> +++ b/xwayland/dnd.c
> @@ -151,6 +151,7 @@ handle_enter(struct weston_wm *wm, xcb_client_message_event_t *client_message)
>  {
>  	struct dnd_data_source *source;
>  	struct weston_seat *seat = weston_wm_pick_seat(wm);
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  	char **p;
>  	const char *name;
>  	uint32_t *types;
> @@ -210,7 +211,7 @@ handle_enter(struct weston_wm *wm, xcb_client_message_event_t *client_message)
>  	}
>  
>  	free(reply);
> -	weston_pointer_start_drag(seat->pointer, &source->base, NULL, NULL);
> +	weston_pointer_start_drag(pointer, &source->base, NULL, NULL);
>  }
>  
>  int
> diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
> index cab7e20..44fe51d 100644
> --- a/xwayland/window-manager.c
> +++ b/xwayland/window-manager.c
> @@ -1302,12 +1302,16 @@ weston_wm_pick_seat_for_window(struct weston_wm_window *window)
>  
>  	seat = NULL;
>  	wl_list_for_each(s, &wm->server->compositor->seat_list, link) {
> -		if (s->pointer != NULL && s->pointer->focus &&
> -		    s->pointer->focus->surface == window->surface &&
> -		    s->pointer->button_count > 0 &&
> +		struct weston_pointer *pointer = weston_seat_get_pointer(s);
> +		struct weston_pointer *old_pointer =
> +						weston_seat_get_pointer(seat);

nit: Same indentation inconsistency as above.


Jonas

> +
> +		if (pointer && pointer->focus &&
> +		    pointer->focus->surface == window->surface &&
> +		    pointer->button_count > 0 &&
>  		    (seat == NULL ||
> -		     s->pointer->grab_serial -
> -		     seat->pointer->grab_serial < (1 << 30)))
> +		     pointer->grab_serial -
> +		     old_pointer->grab_serial < (1 << 30)))
>  			seat = s;
>  	}
>  
> @@ -1331,13 +1335,14 @@ weston_wm_window_handle_moveresize(struct weston_wm_window *window,
>  
>  	struct weston_wm *wm = window->wm;
>  	struct weston_seat *seat = weston_wm_pick_seat_for_window(window);
> +	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
>  	int detail;
>  	struct weston_shell_interface *shell_interface =
>  		&wm->server->compositor->shell_interface;
>  
> -	if (seat == NULL || seat->pointer->button_count != 1
> -	    || !seat->pointer->focus
> -	    || seat->pointer->focus->surface != window->surface)
> +	if (!pointer || pointer->button_count != 1
> +	    || !pointer->focus
> +	    || pointer->focus->surface != window->surface)
>  		return;
>  
>  	detail = client_message->data.data32[2];
> -- 
> 2.1.4
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list