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 <[email protected]>
---

Fixed a couple of bugs, responded to some of Bill's concerns

 desktop-shell/exposay.c             |  27 ++--
 desktop-shell/input-panel.c         |   7 +-
 desktop-shell/shell.c               | 271 ++++++++++++++++++++++--------------
 fullscreen-shell/fullscreen-shell.c |  21 ++-
 ivi-shell/hmi-controller.c          |  35 +++--
 ivi-shell/input-panel-ivi.c         |   7 +-
 src/bindings.c                      |  22 +--
 src/compositor-drm.c                |  16 ++-
 src/compositor-wayland.c            |   8 +-
 src/compositor-x11.c                |  20 ++-
 src/compositor.c                    |  95 +++++++++++--
 src/compositor.h                    |  15 +-
 src/data-device.c                   |  41 +++---
 src/input.c                         | 241 +++++++++++++++++---------------
 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                          |  18 ++-
 tests/weston-test.c                 |   9 +-
 xwayland/dnd.c                      |   3 +-
 xwayland/window-manager.c           |  21 +--
 23 files changed, 579 insertions(+), 345 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;
 
        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);
        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);
+
+               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 456763d..cee130b 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);
+
                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);
+
                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);
+
+                       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);
+
+               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);
 
        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);
 
        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);
@@ -1928,6 +1947,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;
@@ -1957,7 +1977,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);
 
        return 0;
 }
@@ -1969,15 +1989,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;
 
@@ -2077,10 +2098,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);
@@ -2102,15 +2125,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;
@@ -2661,18 +2686,21 @@ set_minimized(struct weston_surface *surface, uint32_t 
is_true)
 
                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);
+
+                       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);
                }
        }
        else {
                weston_layer_entry_insert(&current_ws->layer.view_list, 
&view->layer_link);
 
                wl_list_for_each(seat, &shsurf->shell->compositor->seat_list, 
link) {
-                       if (!seat->keyboard)
+                       if (!weston_seat_get_keyboard(seat))
                                continue;
                        activate(shsurf->shell, view->surface, seat, true);
                }
@@ -3041,19 +3069,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_* */
+       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);
        }
 }
@@ -3157,6 +3188,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;
@@ -3170,7 +3202,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);
        }
 
@@ -3336,6 +3368,8 @@ static void
 add_popup_grab(struct shell_surface *shsurf, struct shell_seat *shseat, 
int32_t type)
 {
        struct weston_seat *seat = shseat->seat;
+       struct weston_pointer *pointer = weston_seat_get_pointer(seat);
+       struct weston_touch *touch = weston_seat_get_touch(seat);
 
        if (wl_list_empty(&shseat->popup_grab.surfaces_list)) {
                shseat->popup_grab.type = type;
@@ -3346,7 +3380,7 @@ add_popup_grab(struct shell_surface *shsurf, struct 
shell_seat *shseat, int32_t
                        /* 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 = 
&touch_popup_grab_interface;
@@ -3355,9 +3389,9 @@ add_popup_grab(struct shell_surface *shsurf, struct 
shell_seat *shseat, int32_t
                wl_list_insert(&shseat->popup_grab.surfaces_list, 
&shsurf->popup.grab_link);
 
                if (type == POINTER)
-                       weston_pointer_start_grab(seat->pointer, 
&shseat->popup_grab.grab);
+                       weston_pointer_start_grab(pointer, 
&shseat->popup_grab.grab);
                else if (type == TOUCH)
-                       weston_touch_start_grab(seat->touch, 
&shseat->popup_grab.touch_grab);
+                       weston_touch_start_grab(touch, 
&shseat->popup_grab.touch_grab);
        } else {
                wl_list_insert(&shseat->popup_grab.surfaces_list, 
&shsurf->popup.grab_link);
        }
@@ -3386,6 +3420,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;
@@ -3394,11 +3430,9 @@ 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) {
                add_popup_grab(shsurf, shseat, POINTER);
-       } else if (shseat->seat->touch &&
-                  shseat->seat->touch->grab_serial == shsurf->popup.serial) {
+       } else if (touch && touch->grab_serial == shsurf->popup.serial) {
                add_popup_grab(shsurf, shseat, TOUCH);
        } else {
                shell_surface_send_popup_done(shsurf);
@@ -3612,17 +3646,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);
+
                /* 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;
@@ -4497,14 +4536,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)
@@ -4521,7 +4561,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;
 
@@ -4544,7 +4585,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;
 
@@ -4571,11 +4613,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;
@@ -4593,14 +4636,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)
@@ -4612,8 +4656,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)
@@ -4639,7 +4683,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 */
@@ -4668,18 +4713,19 @@ do_zoom(struct weston_seat *seat, uint32_t time, 
uint32_t key, uint32_t axis,
 {
        struct weston_seat *ws = (struct weston_seat *) seat;
        struct weston_compositor *compositor = ws->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;
@@ -4837,6 +4883,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;
@@ -4850,8 +4897,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;
@@ -4868,7 +4915,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
@@ -4878,11 +4925,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)
@@ -5020,23 +5068,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
@@ -5045,10 +5097,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);
+
+               if (!keyboard)
                        continue;
 
-               weston_keyboard_set_focus(seat->keyboard, NULL);
+               weston_keyboard_set_focus(keyboard, NULL);
        }
 }
 
@@ -5276,10 +5331,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);
@@ -5327,9 +5386,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;
                }
        }
@@ -6010,6 +6071,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;
@@ -6021,8 +6083,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);
 }
 
@@ -6175,6 +6237,7 @@ 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);
 
        grab = calloc(1, sizeof *grab);
        if (!grab)
@@ -6183,20 +6246,20 @@ debug_binding(struct weston_seat *seat, uint32_t time, 
uint32_t key, void *data)
        grab->seat = (struct weston_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);
 }
 
 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);
+
+                       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);
+
+               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 36a1b56..d573a6b 100644
--- a/ivi-shell/hmi-controller.c
+++ b/ivi-shell/hmi-controller.c
@@ -1420,15 +1420,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;
@@ -1536,24 +1539,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);
+
+               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 8d4c133..6448e6b 100644
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -253,11 +253,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
@@ -267,9 +268,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);
        }
 }
 
@@ -279,6 +280,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;
 
@@ -292,14 +294,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);
                }
        }
@@ -312,8 +314,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) 
{
@@ -365,8 +368,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) {
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 209f2ae..a3e9396 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -1886,16 +1886,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 04a2331..d5059a7 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -1410,6 +1410,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;
 
@@ -1448,7 +1449,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)
                weston_seat_update_keymap(&input->base, keymap);
        else
                weston_seat_init_keyboard(&input->base, keymap);
@@ -1543,6 +1545,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;
@@ -1555,7 +1558,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 5863446..56bb62d 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -164,9 +164,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)
@@ -196,6 +200,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;
@@ -275,7 +280,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),
@@ -945,7 +951,10 @@ x11_compositor_delete_window(struct x11_compositor *c, 
xcb_window_t window)
 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),
@@ -973,9 +982,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 c2c975d..55155bf 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -124,7 +124,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)
@@ -1568,14 +1568,19 @@ 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);
+
+               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)
+               if (touch && touch->focus == view)
                        weston_touch_set_focus(seat, NULL);
        }
 }
@@ -4249,8 +4254,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);
                }
        }
@@ -4786,6 +4793,71 @@ weston_transform_to_string(uint32_t output_transform)
        return "<illegal value>";
 }
 
+/** 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;
+}
 
 int main(int argc, char *argv[])
 {
@@ -4964,8 +5036,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);
+
+                       if (keyboard)
+                               weston_keyboard_set_locks(keyboard,
                                                          WESTON_NUM_LOCK,
                                                          WESTON_NUM_LOCK);
                }
diff --git a/src/compositor.h b/src/compositor.h
index aa87ec0..1d3d0f4 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -499,9 +499,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;
        int pointer_device_count;
        int keyboard_device_count;
        int touch_device_count;
@@ -1497,6 +1497,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 a0913a2..e11ed6e 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));
@@ -729,6 +732,7 @@ weston_seat_set_selection(struct weston_seat *seat,
                          struct weston_data_source *source, uint32_t serial)
 {
        struct wl_resource *data_device, *offer;
+       struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
        struct weston_surface *focus = NULL;
 
        if (seat->selection_data_source &&
@@ -744,8 +748,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) {
                data_device = 
wl_resource_find_for_client(&seat->drag_resource_list,
                                                          
wl_resource_get_client(focus->resource));
@@ -913,11 +917,12 @@ wl_data_device_set_keyboard_focus(struct weston_seat 
*seat)
        struct wl_resource *data_device, *offer;
        struct weston_data_source *source;
        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 c039af0..3cae150 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);
        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;
 
@@ -1367,8 +1369,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... */
@@ -1391,7 +1395,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;
 
@@ -1417,7 +1421,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);
@@ -1439,30 +1444,31 @@ 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
 weston_touch_set_focus(struct weston_seat *seat, struct weston_view *view)
 {
+       struct weston_touch *touch = weston_seat_get_touch(seat);
        struct wl_list *focus_resource_list;
 
-       focus_resource_list = &seat->touch->focus_resource_list;
+       focus_resource_list = &touch->focus_resource_list;
 
-       if (view && seat->touch->focus &&
-           seat->touch->focus->surface == view->surface) {
-               seat->touch->focus = view;
+       if (view && touch->focus &&
+           touch->focus->surface == view->surface) {
+               touch->focus = view;
                return;
        }
 
-       wl_list_remove(&seat->touch->focus_resource_listener.link);
-       wl_list_init(&seat->touch->focus_resource_listener.link);
-       wl_list_remove(&seat->touch->focus_view_listener.link);
-       wl_list_init(&seat->touch->focus_view_listener.link);
+       wl_list_remove(&touch->focus_resource_listener.link);
+       wl_list_init(&touch->focus_resource_listener.link);
+       wl_list_remove(&touch->focus_view_listener.link);
+       wl_list_init(&touch->focus_view_listener.link);
 
        if (!wl_list_empty(focus_resource_list)) {
-               move_resources(&seat->touch->resource_list,
+               move_resources(&touch->resource_list,
                               focus_resource_list);
        }
 
@@ -1470,19 +1476,19 @@ weston_touch_set_focus(struct weston_seat *seat, struct 
weston_view *view)
                struct wl_client *surface_client;
 
                if (!view->surface->resource) {
-                       seat->touch->focus = NULL;
+                       touch->focus = NULL;
                        return;
                }
 
                surface_client = 
wl_resource_get_client(view->surface->resource);
                move_resources_for_client(focus_resource_list,
-                                         &seat->touch->resource_list,
+                                         &touch->resource_list,
                                          surface_client);
                wl_resource_add_destroy_listener(view->surface->resource,
-                                                
&seat->touch->focus_resource_listener);
-               wl_signal_add(&view->destroy_signal, 
&seat->touch->focus_view_listener);
+                                                
&touch->focus_resource_listener);
+               wl_signal_add(&view->destroy_signal, 
&touch->focus_view_listener);
        }
-       seat->touch->focus = view;
+       touch->focus = view;
 }
 
 /**
@@ -1498,7 +1504,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;
@@ -1577,7 +1583,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);
@@ -1689,9 +1695,10 @@ seat_get_pointer(struct wl_client *client, struct 
wl_resource *resource,
                 uint32_t id)
 {
        struct weston_seat *seat = wl_resource_get_user_data(resource);
+       struct weston_pointer *pointer = weston_seat_get_pointer(seat);
        struct wl_resource *cr;
 
-       if (!seat->pointer)
+       if (!pointer)
                return;
 
         cr = wl_resource_create(client, &wl_pointer_interface,
@@ -1704,25 +1711,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);
        }
 }
@@ -1741,16 +1748,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;
@@ -1761,10 +1771,10 @@ 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;
+       struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
        struct wl_resource *cr;
 
-       if (!seat->keyboard)
+       if (!keyboard)
                return;
 
         cr = wl_resource_create(client, &wl_keyboard_interface,
@@ -1777,7 +1787,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);
 
@@ -1800,27 +1810,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);
        }
@@ -1841,9 +1850,10 @@ seat_get_touch(struct wl_client *client, struct 
wl_resource *resource,
               uint32_t id)
 {
        struct weston_seat *seat = wl_resource_get_user_data(resource);
+       struct weston_touch *touch = weston_seat_get_touch(seat);
        struct wl_resource *cr;
 
-       if (!seat->touch)
+       if (!touch)
                return;
 
         cr = wl_resource_create(client, &wl_touch_interface,
@@ -1853,12 +1863,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,
@@ -1884,11 +1894,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);
@@ -2078,17 +2088,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
 }
@@ -2098,7 +2109,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);
@@ -2134,7 +2145,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;
 
@@ -2179,9 +2190,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);
        }
 }
@@ -2191,7 +2202,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);
@@ -2202,7 +2213,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;
 
@@ -2212,7 +2223,7 @@ 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--;
        if (seat->pointer_device_count == 0) {
@@ -2239,7 +2250,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);
@@ -2250,7 +2261,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;
 
@@ -2263,8 +2274,8 @@ weston_seat_release_touch(struct weston_seat *seat)
        seat->touch_device_count--;
        if (seat->touch_device_count == 0) {
                weston_touch_set_focus(seat, NULL);
-               weston_touch_cancel_grab(seat->touch);
-               weston_touch_reset_state(seat->touch);
+               weston_touch_cancel_grab(seat->touch_resource);
+               weston_touch_reset_state(seat->touch_resource);
                seat_send_updated_caps(seat);
        }
 }
@@ -2304,14 +2315,14 @@ 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);
 
diff --git a/src/libinput-device.c b/src/libinput-device.c
index 3ce74b8..398e934 100644
--- a/src/libinput-device.c
+++ b/src/libinput-device.c
@@ -519,9 +519,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 ef2d804..ef2f1d6 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) {
@@ -367,8 +369,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 c98e2f9..fb8a14c 100644
--- a/src/screenshooter.c
+++ b/src/screenshooter.c
@@ -560,6 +560,7 @@ recorder_binding(struct weston_seat *seat, uint32_t time, 
uint32_t key, void *da
 {
        struct weston_seat *ws = (struct weston_seat *) seat;
        struct weston_compositor *ec = ws->compositor;
+       struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
        struct weston_output *output;
        struct wl_listener *listener = NULL;
        struct weston_recorder *recorder;
@@ -583,9 +584,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 f71d08c..af1bbac 100644
--- a/src/zoom.c
+++ b/src/zoom.c
@@ -69,6 +69,7 @@ weston_zoom_frame_xy(struct weston_animation *animation,
                struct weston_output *output, uint32_t msecs)
 {
        struct weston_seat *seat = weston_zoom_pick_seat(output->compositor);
+       struct weston_pointer *pointer = weston_seat_get_pointer(seat);
        wl_fixed_t x, y;
 
        if (animation->frame_counter <= 1)
@@ -86,8 +87,8 @@ weston_zoom_frame_xy(struct weston_animation *animation,
 
        if (weston_spring_done(&output->zoom.spring_xy)) {
                output->zoom.spring_xy.current = output->zoom.spring_xy.target;
-               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;
                wl_list_remove(&animation->link);
                wl_list_init(&animation->link);
        }
@@ -174,14 +175,16 @@ WL_EXPORT void
 weston_output_update_zoom(struct weston_output *output)
 {
        struct weston_seat *seat = weston_zoom_pick_seat(output->compositor);
-       wl_fixed_t x = seat->pointer->x;
-       wl_fixed_t y = seat->pointer->y;
+       struct weston_pointer *pointer = weston_seat_get_pointer(seat);
+
+       wl_fixed_t x = pointer->x;
+       wl_fixed_t y = pointer->y;
 
        zoom_area_center_from_pointer(output, &x, &y);
 
        if (wl_list_empty(&output->zoom.animation_xy.link)) {
-               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;
        } else {
                output->zoom.to.x = x;
                output->zoom.to.y = y;
@@ -206,13 +209,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/weston-test.c b/tests/weston-test.c
index 77eaa23..270f8a9 100644
--- a/tests/weston-test.c
+++ b/tests/weston-test.c
@@ -82,7 +82,7 @@ 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);
 
        wl_test_send_pointer_position(resource, pointer->x, pointer->y);
 }
@@ -143,7 +143,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,
@@ -170,12 +170,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 4d3611f..0bcc474 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -1241,12 +1241,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);
+
+               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;
        }
 
@@ -1270,13 +1274,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
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to