input: Don't test keyboard/pointer/touch pointers

Keyboards and pointers aren't freed when devices are removed, so we should
really be testing keyboard_device_count and pointer_device_count in most
cases, not the actual pointers. Otherwise we end up with different
behaviour after removing a device than we had before it was inserted.

This commit renames the touch/keyboard/pointer pointers and adds helper
functions to get them that hide this complexity and return NULL when
*_device_count is 0.

Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
Reviewed-by: Jonas Ådahl <jadahl@gmail.com>
dev
Derek Foreman 9 years ago committed by Bryce Harrington
parent b41b59e2fa
commit 1281a36e3b
  1. 34
      desktop-shell/exposay.c
  2. 7
      desktop-shell/input-panel.c
  3. 191
      desktop-shell/shell.c
  4. 18
      fullscreen-shell/fullscreen-shell.c
  5. 30
      ivi-shell/hmi-controller.c
  6. 7
      ivi-shell/input-panel-ivi.c
  7. 10
      src/compositor-drm.c
  8. 8
      src/compositor-wayland.c
  9. 18
      src/compositor-x11.c
  10. 27
      src/compositor.c
  11. 15
      src/compositor.h
  12. 41
      src/data-device.c
  13. 246
      src/input.c
  14. 15
      src/libinput-seat.c
  15. 7
      src/main.c
  16. 19
      src/text-backend.c
  17. 9
      src/zoom.c
  18. 7
      tests/surface-screenshot.c
  19. 9
      tests/weston-test.c
  20. 3
      xwayland/dnd.c
  21. 23
      xwayland/window-manager.c

@ -525,14 +525,16 @@ static enum exposay_layout_state
exposay_set_inactive(struct desktop_shell *shell) exposay_set_inactive(struct desktop_shell *shell)
{ {
struct weston_seat *seat = shell->exposay.seat; 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);
if (seat->pointer_device_count) if (pointer)
weston_pointer_end_grab(seat->pointer); weston_pointer_end_grab(pointer);
if (seat->keyboard_device_count) { if (keyboard) {
weston_keyboard_end_grab(seat->keyboard); weston_keyboard_end_grab(keyboard);
if (seat->keyboard->input_method_resource) if (keyboard->input_method_resource)
seat->keyboard->grab = &seat->keyboard->input_method_grab; keyboard->grab = &keyboard->input_method_grab;
} }
return EXPOSAY_LAYOUT_INACTIVE; return EXPOSAY_LAYOUT_INACTIVE;
@ -566,28 +568,30 @@ static enum exposay_layout_state
exposay_transition_active(struct desktop_shell *shell) exposay_transition_active(struct desktop_shell *shell)
{ {
struct weston_seat *seat = shell->exposay.seat; 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; struct shell_output *shell_output;
bool animate = false; bool animate = false;
shell->exposay.workspace = get_current_workspace(shell); shell->exposay.workspace = get_current_workspace(shell);
shell->exposay.focus_prev = get_default_view (seat->keyboard->focus); shell->exposay.focus_prev = get_default_view(keyboard->focus);
shell->exposay.focus_current = get_default_view (seat->keyboard->focus); shell->exposay.focus_current = get_default_view(keyboard->focus);
shell->exposay.clicked = NULL; shell->exposay.clicked = NULL;
wl_list_init(&shell->exposay.surface_list); wl_list_init(&shell->exposay.surface_list);
lower_fullscreen_layer(shell, NULL); lower_fullscreen_layer(shell, NULL);
shell->exposay.grab_kbd.interface = &exposay_kbd_grab; shell->exposay.grab_kbd.interface = &exposay_kbd_grab;
weston_keyboard_start_grab(seat->keyboard, weston_keyboard_start_grab(keyboard,
&shell->exposay.grab_kbd); &shell->exposay.grab_kbd);
weston_keyboard_set_focus(seat->keyboard, NULL); weston_keyboard_set_focus(keyboard, NULL);
shell->exposay.grab_ptr.interface = &exposay_ptr_grab; shell->exposay.grab_ptr.interface = &exposay_ptr_grab;
if (seat->pointer_device_count) { if (pointer) {
weston_pointer_start_grab(seat->pointer, weston_pointer_start_grab(pointer,
&shell->exposay.grab_ptr); &shell->exposay.grab_ptr);
weston_pointer_set_focus(seat->pointer, NULL, weston_pointer_set_focus(pointer, NULL,
seat->pointer->x, pointer->x,
seat->pointer->y); pointer->y);
} }
wl_list_for_each(shell_output, &shell->output_list, link) { wl_list_for_each(shell_output, &shell->output_list, link) {
enum exposay_layout_state state; enum exposay_layout_state state;

@ -68,9 +68,12 @@ show_input_panel_surface(struct input_panel_surface *ipsurf)
float x, y; float x, y;
wl_list_for_each(seat, &shell->compositor->seat_list, link) { 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; continue;
focus = weston_surface_get_main_surface(seat->keyboard->focus); focus = weston_surface_get_main_surface(keyboard->focus);
ipsurf->output = focus->output; ipsurf->output = focus->output;
x = ipsurf->output->x + (ipsurf->output->width - ipsurf->surface->width) / 2; x = ipsurf->output->x + (ipsurf->output->width - ipsurf->surface->width) / 2;
y = ipsurf->output->y + ipsurf->output->height - ipsurf->surface->height; y = ipsurf->output->y + ipsurf->output->height - ipsurf->surface->height;

@ -378,10 +378,11 @@ shell_grab_start(struct shell_grab *grab,
enum desktop_shell_cursor cursor) enum desktop_shell_cursor cursor)
{ {
struct desktop_shell *shell = shsurf->shell; struct desktop_shell *shell = shsurf->shell;
struct weston_touch *touch = weston_seat_get_touch(pointer->seat);
popup_grab_end(pointer); popup_grab_end(pointer);
if (pointer->seat->touch) if (touch)
touch_popup_grab_end(pointer->seat->touch); touch_popup_grab_end(touch);
grab->grab.interface = interface; grab->grab.interface = interface;
grab->shsurf = shsurf; grab->shsurf = shsurf;
@ -546,10 +547,11 @@ shell_touch_grab_start(struct shell_touch_grab *grab,
struct weston_touch *touch) struct weston_touch *touch)
{ {
struct desktop_shell *shell = shsurf->shell; struct desktop_shell *shell = shsurf->shell;
struct weston_pointer *pointer = weston_seat_get_pointer(touch->seat);
touch_popup_grab_end(touch); touch_popup_grab_end(touch);
if (touch->seat->pointer) if (pointer)
popup_grab_end(touch->seat->pointer); popup_grab_end(pointer);
grab->grab.interface = interface; grab->grab.interface = interface;
grab->shsurf = shsurf; grab->shsurf = shsurf;
@ -900,27 +902,33 @@ restore_focus_state(struct desktop_shell *shell, struct workspace *ws)
wl_list_init(&shell->compositor->seat_list); wl_list_init(&shell->compositor->seat_list);
wl_list_for_each_safe(state, next, &ws->focus_list, link) { 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_remove(&state->seat->link);
wl_list_insert(&shell->compositor->seat_list, wl_list_insert(&shell->compositor->seat_list,
&state->seat->link); &state->seat->link);
if (state->seat->keyboard == NULL) if (!keyboard)
continue; continue;
surface = state->keyboard_focus; 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 any remaining seats that we don't have a focus state
* for we'll reset the keyboard focus to NULL */ * for we'll reset the keyboard focus to NULL */
wl_list_for_each_safe(seat, next_seat, &pending_seat_list, link) { 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); wl_list_insert(&shell->compositor->seat_list, &seat->link);
if (seat->keyboard == NULL) if (!keyboard)
continue; continue;
weston_keyboard_set_focus(seat->keyboard, NULL); weston_keyboard_set_focus(keyboard, NULL);
} }
} }
@ -928,11 +936,12 @@ static void
replace_focus_state(struct desktop_shell *shell, struct workspace *ws, replace_focus_state(struct desktop_shell *shell, struct workspace *ws,
struct weston_seat *seat) struct weston_seat *seat)
{ {
struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
struct focus_state *state; struct focus_state *state;
wl_list_for_each(state, &ws->focus_list, link) { wl_list_for_each(state, &ws->focus_list, link) {
if (state->seat == seat) { if (state->seat == seat) {
focus_state_set_focus(state, seat->keyboard->focus); focus_state_set_focus(state, keyboard->focus);
return; return;
} }
} }
@ -1431,12 +1440,15 @@ move_surface_to_workspace(struct desktop_shell *shell,
drop_focus_state(shell, from, view->surface); drop_focus_state(shell, from, view->surface);
wl_list_for_each(seat, &shell->compositor->seat_list, link) { 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; continue;
focus = weston_surface_get_main_surface(seat->keyboard->focus); focus = weston_surface_get_main_surface(keyboard->focus);
if (focus == view->surface) if (focus == view->surface)
weston_keyboard_set_focus(seat->keyboard, NULL); weston_keyboard_set_focus(keyboard, NULL);
} }
weston_view_damage_below(view); weston_view_damage_below(view);
@ -1447,6 +1459,7 @@ take_surface_to_workspace_by_seat(struct desktop_shell *shell,
struct weston_seat *seat, struct weston_seat *seat,
unsigned int index) unsigned int index)
{ {
struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
struct weston_surface *surface; struct weston_surface *surface;
struct weston_view *view; struct weston_view *view;
struct shell_surface *shsurf; struct shell_surface *shsurf;
@ -1454,7 +1467,7 @@ take_surface_to_workspace_by_seat(struct desktop_shell *shell,
struct workspace *to; struct workspace *to;
struct focus_state *state; 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); view = get_default_view(surface);
if (view == NULL || if (view == NULL ||
index == shell->workspaces.current || index == shell->workspaces.current ||
@ -1782,23 +1795,25 @@ common_surface_move(struct wl_resource *resource,
struct wl_resource *seat_resource, uint32_t serial) struct wl_resource *seat_resource, uint32_t serial)
{ {
struct weston_seat *seat = wl_resource_get_user_data(seat_resource); 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 shell_surface *shsurf = wl_resource_get_user_data(resource);
struct weston_surface *surface; struct weston_surface *surface;
if (seat->pointer && if (pointer &&
seat->pointer->focus && pointer->focus &&
seat->pointer->button_count > 0 && pointer->button_count > 0 &&
seat->pointer->grab_serial == serial) { pointer->grab_serial == serial) {
surface = weston_surface_get_main_surface(seat->pointer->focus->surface); surface = weston_surface_get_main_surface(pointer->focus->surface);
if ((surface == shsurf->surface) && if ((surface == shsurf->surface) &&
(surface_move(shsurf, seat->pointer, true) < 0)) (surface_move(shsurf, pointer, true) < 0))
wl_resource_post_no_memory(resource); wl_resource_post_no_memory(resource);
} else if (seat->touch && } else if (touch &&
seat->touch->focus && touch->focus &&
seat->touch->grab_serial == serial) { touch->grab_serial == serial) {
surface = weston_surface_get_main_surface(seat->touch->focus->surface); surface = weston_surface_get_main_surface(touch->focus->surface);
if ((surface == shsurf->surface) && if ((surface == shsurf->surface) &&
(surface_touch_move(shsurf, seat->touch) < 0)) (surface_touch_move(shsurf, touch) < 0))
wl_resource_post_no_memory(resource); wl_resource_post_no_memory(resource);
} }
} }
@ -1986,20 +2001,21 @@ common_surface_resize(struct wl_resource *resource,
uint32_t edges) uint32_t edges)
{ {
struct weston_seat *seat = wl_resource_get_user_data(seat_resource); struct weston_seat *seat = wl_resource_get_user_data(seat_resource);
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
struct shell_surface *shsurf = wl_resource_get_user_data(resource); struct shell_surface *shsurf = wl_resource_get_user_data(resource);
struct weston_surface *surface; struct weston_surface *surface;
if (seat->pointer == NULL || if (!pointer ||
seat->pointer->button_count == 0 || pointer->button_count == 0 ||
seat->pointer->grab_serial != serial || pointer->grab_serial != serial ||
seat->pointer->focus == NULL) pointer->focus == NULL)
return; return;
surface = weston_surface_get_main_surface(seat->pointer->focus->surface); surface = weston_surface_get_main_surface(pointer->focus->surface);
if (surface != shsurf->surface) if (surface != shsurf->surface)
return; return;
if (surface_resize(shsurf, seat->pointer, edges) < 0) if (surface_resize(shsurf, pointer, edges) < 0)
wl_resource_post_no_memory(resource); wl_resource_post_no_memory(resource);
} }
@ -2096,10 +2112,12 @@ end_busy_cursor(struct weston_compositor *compositor, struct wl_client *client)
struct weston_seat *seat; struct weston_seat *seat;
wl_list_for_each(seat, &compositor->seat_list, link) { 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; continue;
grab = (struct shell_grab *) seat->pointer->grab; grab = (struct shell_grab *) pointer->grab;
if (grab->grab.interface == &busy_cursor_grab_interface && if (grab->grab.interface == &busy_cursor_grab_interface &&
wl_resource_get_client(grab->shsurf->resource) == client) { wl_resource_get_client(grab->shsurf->resource) == client) {
shell_grab_end(grab); shell_grab_end(grab);
@ -2121,15 +2139,17 @@ xdg_ping_timeout_handler(void *data)
/* Client is not responding */ /* Client is not responding */
sc->unresponsive = 1; sc->unresponsive = 1;
wl_list_for_each(seat, &sc->shell->compositor->seat_list, link) { 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);
continue;
if (seat->pointer->focus->surface->resource == NULL) if (!pointer ||
!pointer->focus ||
!pointer->focus->surface->resource)
continue; continue;
shsurf = get_shell_surface(seat->pointer->focus->surface); shsurf = get_shell_surface(pointer->focus->surface);
if (shsurf && if (shsurf &&
wl_resource_get_client(shsurf->resource) == sc->client) wl_resource_get_client(shsurf->resource) == sc->client)
set_busy_cursor(shsurf, seat->pointer); set_busy_cursor(shsurf, pointer);
} }
return 1; return 1;
@ -2684,11 +2704,14 @@ set_minimized(struct weston_surface *surface)
drop_focus_state(shsurf->shell, current_ws, view->surface); drop_focus_state(shsurf->shell, current_ws, view->surface);
wl_list_for_each(seat, &shsurf->shell->compositor->seat_list, link) { 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; continue;
focus = weston_surface_get_main_surface(seat->keyboard->focus); focus = weston_surface_get_main_surface(keyboard->focus);
if (focus == view->surface) if (focus == view->surface)
weston_keyboard_set_focus(seat->keyboard, NULL); weston_keyboard_set_focus(keyboard, NULL);
} }
shell_surface_update_child_surface_layers(shsurf); shell_surface_update_child_surface_layers(shsurf);
@ -3020,17 +3043,22 @@ get_focused_output(struct weston_compositor *compositor)
struct weston_output *output = NULL; struct weston_output *output = NULL;
wl_list_for_each(seat, &compositor->seat_list, link) { 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 /* Priority has touch focus, then pointer and
* then keyboard focus. We should probably have * then keyboard focus. We should probably have
* three for loops and check frist for touch, * three for loops and check frist for touch,
* then for pointer, etc. but unless somebody has some * then for pointer, etc. but unless somebody has some
* objections, I think this is sufficient. */ * objections, I think this is sufficient. */
if (seat->touch && seat->touch->focus) if (touch && touch->focus)
output = seat->touch->focus->output; output = touch->focus->output;
else if (seat->pointer && seat->pointer->focus) else if (pointer && pointer->focus)
output = seat->pointer->focus->output; output = pointer->focus->output;
else if (seat->keyboard && seat->keyboard->focus) else if (keyboard && keyboard->focus)
output = seat->keyboard->focus->output; output = keyboard->focus->output;
if (output) if (output)
break; break;
@ -3061,7 +3089,7 @@ shell_interface_set_maximized(struct shell_surface *shsurf)
static int static int
shell_interface_move(struct shell_surface *shsurf, struct weston_seat *ws) shell_interface_move(struct shell_surface *shsurf, struct weston_seat *ws)
{ {
return surface_move(shsurf, ws->pointer, true); return surface_move(shsurf, weston_seat_get_pointer(ws), true);
} }
static int static int
@ -3069,7 +3097,7 @@ shell_interface_resize(struct shell_surface *shsurf,
struct weston_seat *ws, struct weston_seat *ws,
uint32_t edges) uint32_t edges)
{ {
return surface_resize(shsurf, ws->pointer, edges); return surface_resize(shsurf, weston_seat_get_pointer(ws), edges);
} }
static const struct weston_pointer_grab_interface popup_grab_interface; static const struct weston_pointer_grab_interface popup_grab_interface;
@ -3101,24 +3129,28 @@ destroy_shell_seat(struct wl_listener *listener, void *data)
static void static void
shell_seat_caps_changed(struct wl_listener *listener, void *data) shell_seat_caps_changed(struct wl_listener *listener, void *data)
{ {
struct weston_keyboard *keyboard;
struct weston_pointer *pointer;
struct shell_seat *seat; struct shell_seat *seat;
seat = container_of(listener, struct shell_seat, caps_changed_listener); seat = container_of(listener, struct shell_seat, caps_changed_listener);
keyboard = weston_seat_get_keyboard(seat->seat);
pointer = weston_seat_get_pointer(seat->seat);
if (seat->seat->keyboard_device_count && if (keyboard &&
wl_list_empty(&seat->keyboard_focus_listener.link)) { wl_list_empty(&seat->keyboard_focus_listener.link)) {
wl_signal_add(&seat->seat->keyboard->focus_signal, wl_signal_add(&keyboard->focus_signal,
&seat->keyboard_focus_listener); &seat->keyboard_focus_listener);
} else if (!seat->seat->keyboard_device_count) { } else if (!keyboard) {
wl_list_remove(&seat->keyboard_focus_listener.link); wl_list_remove(&seat->keyboard_focus_listener.link);
wl_list_init(&seat->keyboard_focus_listener.link); wl_list_init(&seat->keyboard_focus_listener.link);
} }
if (seat->seat->pointer_device_count && if (pointer &&
wl_list_empty(&seat->pointer_focus_listener.link)) { wl_list_empty(&seat->pointer_focus_listener.link)) {
wl_signal_add(&seat->seat->pointer->focus_signal, wl_signal_add(&pointer->focus_signal,
&seat->pointer_focus_listener); &seat->pointer_focus_listener);
} else if (!seat->seat->pointer_device_count) { } else if (!pointer) {
wl_list_remove(&seat->pointer_focus_listener.link); wl_list_remove(&seat->pointer_focus_listener.link);
wl_list_init(&seat->pointer_focus_listener.link); wl_list_init(&seat->pointer_focus_listener.link);
} }
@ -3415,6 +3447,8 @@ add_popup_grab(struct shell_surface *shsurf,
{ {
struct weston_seat *seat = shseat->seat; struct weston_seat *seat = shseat->seat;
struct shell_surface *parent, *top_surface; struct shell_surface *parent, *top_surface;
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
struct weston_touch *touch = weston_seat_get_touch(seat);
parent = get_shell_surface(shsurf->parent); parent = get_shell_surface(shsurf->parent);
top_surface = get_top_popup(shseat); top_surface = get_top_popup(shseat);
@ -3441,7 +3475,7 @@ add_popup_grab(struct shell_surface *shsurf,
/* We must make sure here that this popup was opened /* We must make sure here that this popup was opened
* after a mouse press, and not just by moving around * after a mouse press, and not just by moving around
* with other popups already open. */ * with other popups already open. */
if (shseat->seat->pointer->button_count > 0) if (pointer->button_count > 0)
shseat->popup_grab.initial_up = 0; shseat->popup_grab.initial_up = 0;
} else if (type == TOUCH) { } else if (type == TOUCH) {
shseat->popup_grab.touch_grab.interface = shseat->popup_grab.touch_grab.interface =
@ -3452,10 +3486,10 @@ add_popup_grab(struct shell_surface *shsurf,
&shsurf->popup.grab_link); &shsurf->popup.grab_link);
if (type == POINTER) { if (type == POINTER) {
weston_pointer_start_grab(seat->pointer, weston_pointer_start_grab(pointer,
&shseat->popup_grab.grab); &shseat->popup_grab.grab);
} else if (type == TOUCH) { } else if (type == TOUCH) {
weston_touch_start_grab(seat->touch, weston_touch_start_grab(touch,
&shseat->popup_grab.touch_grab); &shseat->popup_grab.touch_grab);
} }
} else { } else {
@ -3498,6 +3532,8 @@ shell_map_popup(struct shell_surface *shsurf)
{ {
struct shell_seat *shseat = shsurf->popup.shseat; struct shell_seat *shseat = shsurf->popup.shseat;
struct weston_view *parent_view = get_default_view(shsurf->parent); 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->surface->output = parent_view->output;
shsurf->view->output = parent_view->output; shsurf->view->output = parent_view->output;
@ -3506,12 +3542,12 @@ shell_map_popup(struct shell_surface *shsurf)
weston_view_set_position(shsurf->view, shsurf->popup.x, shsurf->popup.y); weston_view_set_position(shsurf->view, shsurf->popup.x, shsurf->popup.y);
weston_view_update_transform(shsurf->view); weston_view_update_transform(shsurf->view);
if (shseat->seat->pointer && if (pointer &&
shseat->seat->pointer->grab_serial == shsurf->popup.serial) { pointer->grab_serial == shsurf->popup.serial) {
if (add_popup_grab(shsurf, shseat, POINTER) != 0) if (add_popup_grab(shsurf, shseat, POINTER) != 0)
return -1; return -1;
} else if (shseat->seat->touch && } else if (touch &&
shseat->seat->touch->grab_serial == shsurf->popup.serial) { touch->grab_serial == shsurf->popup.serial) {
if (add_popup_grab(shsurf, shseat, TOUCH) != 0) if (add_popup_grab(shsurf, shseat, TOUCH) != 0)
return -1; return -1;
} else { } else {
@ -4776,18 +4812,19 @@ do_zoom(struct weston_seat *seat, uint32_t time, uint32_t key, uint32_t axis,
wl_fixed_t value) wl_fixed_t value)
{ {
struct weston_compositor *compositor = seat->compositor; struct weston_compositor *compositor = seat->compositor;
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
struct weston_output *output; struct weston_output *output;
float increment; float increment;
if (!seat->pointer) { if (!pointer) {
weston_log("Zoom hotkey pressed but seat '%s' contains no pointer.\n", seat->seat_name); weston_log("Zoom hotkey pressed but seat '%s' contains no pointer.\n", seat->seat_name);
return; return;
} }
wl_list_for_each(output, &compositor->output_list, link) { wl_list_for_each(output, &compositor->output_list, link) {
if (pixman_region32_contains_point(&output->region, if (pixman_region32_contains_point(&output->region,
wl_fixed_to_double(seat->pointer->x), wl_fixed_to_double(pointer->x),
wl_fixed_to_double(seat->pointer->y), wl_fixed_to_double(pointer->y),
NULL)) { NULL)) {
if (key == KEY_PAGEUP) if (key == KEY_PAGEUP)
increment = output->zoom.increment; increment = output->zoom.increment;
@ -5168,10 +5205,13 @@ unfocus_all_seats(struct desktop_shell *shell)
struct weston_seat *seat, *next; struct weston_seat *seat, *next;
wl_list_for_each_safe(seat, next, &shell->compositor->seat_list, link) { 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; continue;
weston_keyboard_set_focus(seat->keyboard, NULL); weston_keyboard_set_focus(keyboard, NULL);
} }
} }
@ -5405,10 +5445,13 @@ idle_handler(struct wl_listener *listener, void *data)
struct weston_seat *seat; struct weston_seat *seat;
wl_list_for_each(seat, &shell->compositor->seat_list, link) { wl_list_for_each(seat, &shell->compositor->seat_list, link) {
if (seat->pointer) struct weston_touch *touch = weston_seat_get_touch(seat);
popup_grab_end(seat->pointer); struct weston_pointer *pointer = weston_seat_get_pointer(seat);
if (seat->touch)
touch_popup_grab_end(seat->touch); if (pointer)
popup_grab_end(pointer);
if (touch)
touch_popup_grab_end(touch);
} }
shell_fade(shell, FADE_OUT); shell_fade(shell, FADE_OUT);
@ -5456,9 +5499,11 @@ weston_view_set_initial_position(struct weston_view *view,
* TODO: Do something clever for touch too? * TODO: Do something clever for touch too?
*/ */
wl_list_for_each(seat, &compositor->seat_list, link) { wl_list_for_each(seat, &compositor->seat_list, link) {
if (seat->pointer) { struct weston_pointer *pointer = weston_seat_get_pointer(seat);
ix = wl_fixed_to_int(seat->pointer->x);
iy = wl_fixed_to_int(seat->pointer->y); if (pointer) {
ix = wl_fixed_to_int(pointer->x);
iy = wl_fixed_to_int(pointer->y);
break; break;
} }
} }

@ -96,15 +96,17 @@ static void
seat_caps_changed(struct wl_listener *l, void *data) seat_caps_changed(struct wl_listener *l, void *data)
{ {
struct weston_seat *seat = data; struct weston_seat *seat = data;
struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
struct pointer_focus_listener *listener; struct pointer_focus_listener *listener;
struct fs_output *fsout; struct fs_output *fsout;
listener = container_of(l, struct pointer_focus_listener, seat_caps); listener = container_of(l, struct pointer_focus_listener, seat_caps);
/* no pointer */ /* no pointer */
if (seat->pointer_device_count) { if (pointer) {
if (!listener->pointer_focus.link.prev) { if (!listener->pointer_focus.link.prev) {
wl_signal_add(&seat->pointer->focus_signal, wl_signal_add(&pointer->focus_signal,
&listener->pointer_focus); &listener->pointer_focus);
} }
} else { } else {
@ -113,7 +115,7 @@ seat_caps_changed(struct wl_listener *l, void *data)
} }
} }
if (seat->keyboard_device_count && seat->keyboard->focus != NULL) { if (keyboard && keyboard->focus != NULL) {
wl_list_for_each(fsout, &listener->shell->output_list, link) { wl_list_for_each(fsout, &listener->shell->output_list, link) {
if (fsout->surface) { if (fsout->surface) {
weston_surface_activate(fsout->surface, seat); weston_surface_activate(fsout->surface, seat);
@ -681,7 +683,10 @@ fullscreen_shell_present_surface(struct wl_client *client,
if (surface) { if (surface) {
wl_list_for_each(seat, &shell->compositor->seat_list, link) { 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)
weston_surface_activate(surface, seat); weston_surface_activate(surface, seat);
} }
} }
@ -729,7 +734,10 @@ fullscreen_shell_present_surface_for_mode(struct wl_client *client,
fsout, mode_feedback_destroyed); fsout, mode_feedback_destroyed);
wl_list_for_each(seat, &shell->compositor->seat_list, link) { 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)
weston_surface_activate(surface, seat); weston_surface_activate(surface, seat);
} }
} }

@ -1469,15 +1469,18 @@ enum HMI_GRAB_DEVICE {
static enum HMI_GRAB_DEVICE static enum HMI_GRAB_DEVICE
get_hmi_grab_device(struct weston_seat *seat, uint32_t serial) get_hmi_grab_device(struct weston_seat *seat, uint32_t serial)
{ {
if (seat->pointer && struct weston_pointer *pointer = weston_seat_get_pointer(seat);
seat->pointer->focus && struct weston_touch *touch = weston_seat_get_touch(seat);
seat->pointer->button_count &&
seat->pointer->grab_serial == serial) if (pointer &&
pointer->focus &&
pointer->button_count &&
pointer->grab_serial == serial)
return HMI_GRAB_DEVICE_POINTER; return HMI_GRAB_DEVICE_POINTER;
if (seat->touch && if (touch &&
seat->touch->focus && touch->focus &&
seat->touch->grab_serial == serial) touch->grab_serial == serial)
return HMI_GRAB_DEVICE_TOUCH; return HMI_GRAB_DEVICE_TOUCH;
return HMI_GRAB_DEVICE_NONE; return HMI_GRAB_DEVICE_NONE;
@ -1568,6 +1571,9 @@ ivi_hmi_controller_workspace_control(struct wl_client *client,
struct pointer_move_grab *pnt_move_grab = NULL; struct pointer_move_grab *pnt_move_grab = NULL;
struct touch_move_grab *tch_move_grab = NULL; struct touch_move_grab *tch_move_grab = NULL;
struct weston_seat *seat = NULL; struct weston_seat *seat = NULL;
struct weston_pointer *pointer;
struct weston_touch *touch;
enum HMI_GRAB_DEVICE device; enum HMI_GRAB_DEVICE device;
if (hmi_ctrl->workspace_count < 2) if (hmi_ctrl->workspace_count < 2)
@ -1586,21 +1592,23 @@ ivi_hmi_controller_workspace_control(struct wl_client *client,
switch (device) { switch (device) {
case HMI_GRAB_DEVICE_POINTER: case HMI_GRAB_DEVICE_POINTER:
pnt_move_grab = create_workspace_pointer_move(seat->pointer, pointer = weston_seat_get_pointer(seat);
pnt_move_grab = create_workspace_pointer_move(pointer,
resource); resource);
pointer_grab_start(&pnt_move_grab->base, layer, pointer_grab_start(&pnt_move_grab->base, layer,
&pointer_move_grab_workspace_interface, &pointer_move_grab_workspace_interface,
seat->pointer); pointer);
break; break;
case HMI_GRAB_DEVICE_TOUCH: case HMI_GRAB_DEVICE_TOUCH:
tch_move_grab = create_workspace_touch_move(seat->touch, touch = weston_seat_get_touch(seat);
tch_move_grab = create_workspace_touch_move(touch,
resource); resource);
touch_grab_start(&tch_move_grab->base, layer, touch_grab_start(&tch_move_grab->base, layer,
&touch_move_grab_workspace_interface, &touch_move_grab_workspace_interface,
seat->touch); touch);
break; break;
default: default:

@ -70,9 +70,12 @@ show_input_panel_surface(struct input_panel_surface *ipsurf)
float x, y; float x, y;
wl_list_for_each(seat, &shell->compositor->seat_list, link) { 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; continue;
focus = weston_surface_get_main_surface(seat->keyboard->focus); focus = weston_surface_get_main_surface(keyboard->focus);
ipsurf->output = focus->output; ipsurf->output = focus->output;
x = ipsurf->output->x + (ipsurf->output->width - ipsurf->surface->width) / 2; x = ipsurf->output->x + (ipsurf->output->width - ipsurf->surface->width) / 2;
y = ipsurf->output->y + ipsurf->output->height - ipsurf->surface->height; y = ipsurf->output->y + ipsurf->output->height - ipsurf->surface->height;

@ -2075,6 +2075,7 @@ setup_output_seat_constraint(struct drm_backend *b,
const char *s) const char *s)
{ {
if (strcmp(s, "") != 0) { if (strcmp(s, "") != 0) {
struct weston_pointer *pointer;
struct udev_seat *seat; struct udev_seat *seat;
seat = udev_seat_get_named(&b->input, s); seat = udev_seat_get_named(&b->input, s);
@ -2083,10 +2084,11 @@ setup_output_seat_constraint(struct drm_backend *b,
seat->base.output = output; seat->base.output = output;
if (seat->base.pointer) pointer = weston_seat_get_pointer(&seat->base);
weston_pointer_clamp(seat->base.pointer, if (pointer)
&seat->base.pointer->x, weston_pointer_clamp(pointer,
&seat->base.pointer->y); &pointer->x,
&pointer->y);
} }
} }

@ -1479,7 +1479,7 @@ input_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format,
close(fd); close(fd);
if (input->base.keyboard) if (weston_seat_get_keyboard(&input->base))
weston_seat_update_keymap(&input->base, keymap); weston_seat_update_keymap(&input->base, keymap);
else else
weston_seat_init_keyboard(&input->base, keymap); weston_seat_init_keyboard(&input->base, keymap);
@ -1569,11 +1569,12 @@ input_handle_key(void *data, struct wl_keyboard *keyboard,
} }
static void static void
input_handle_modifiers(void *data, struct wl_keyboard *keyboard, input_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,
uint32_t serial_in, uint32_t mods_depressed, uint32_t serial_in, uint32_t mods_depressed,
uint32_t mods_latched, uint32_t mods_locked, uint32_t mods_latched, uint32_t mods_locked,
uint32_t group) uint32_t group)
{ {
struct weston_keyboard *keyboard;
struct wayland_input *input = data; struct wayland_input *input = data;
struct wayland_backend *b = input->backend; struct wayland_backend *b = input->backend;
uint32_t serial_out; uint32_t serial_out;
@ -1586,7 +1587,8 @@ input_handle_modifiers(void *data, struct wl_keyboard *keyboard,
else else
serial_out = wl_display_next_serial(b->compositor->wl_display); serial_out = wl_display_next_serial(b->compositor->wl_display);
xkb_state_update_mask(input->base.keyboard->xkb_state.state, keyboard = weston_seat_get_keyboard(&input->base);
xkb_state_update_mask(keyboard->xkb_state.state,
mods_depressed, mods_latched, mods_depressed, mods_latched,
mods_locked, 0, 0, group); mods_locked, 0, 0, group);
notify_modifiers(&input->base, serial_out); notify_modifiers(&input->base, serial_out);

@ -174,7 +174,9 @@ x11_backend_get_keymap(struct x11_backend *b)
static uint32_t static uint32_t
get_xkb_mod_mask(struct x11_backend *b, uint32_t in) get_xkb_mod_mask(struct x11_backend *b, uint32_t in)
{ {
struct weston_xkb_info *info = b->core_seat.keyboard->xkb_info; struct weston_keyboard *keyboard =
weston_seat_get_keyboard(&b->core_seat);
struct weston_xkb_info *info = keyboard->xkb_info;
uint32_t ret = 0; uint32_t ret = 0;
if ((in & ShiftMask) && info->shift_mod != XKB_MOD_INVALID) if ((in & ShiftMask) && info->shift_mod != XKB_MOD_INVALID)
@ -206,6 +208,7 @@ x11_backend_setup_xkb(struct x11_backend *b)
b->xkb_event_base = 0; b->xkb_event_base = 0;
return; return;
#else #else
struct weston_keyboard *keyboard;
const xcb_query_extension_reply_t *ext; const xcb_query_extension_reply_t *ext;
xcb_generic_error_t *error; xcb_generic_error_t *error;
xcb_void_cookie_t select; xcb_void_cookie_t select;
@ -285,7 +288,8 @@ x11_backend_setup_xkb(struct x11_backend *b)
return; return;
} }
xkb_state_update_mask(b->core_seat.keyboard->xkb_state.state, keyboard = weston_seat_get_keyboard(&b->core_seat);
xkb_state_update_mask(keyboard->xkb_state.state,
get_xkb_mod_mask(b, state_reply->baseMods), get_xkb_mod_mask(b, state_reply->baseMods),
get_xkb_mod_mask(b, state_reply->latchedMods), get_xkb_mod_mask(b, state_reply->latchedMods),
get_xkb_mod_mask(b, state_reply->lockedMods), get_xkb_mod_mask(b, state_reply->lockedMods),
@ -975,7 +979,10 @@ static void delete_cb(void *data)
static void static void
update_xkb_state(struct x11_backend *b, xcb_xkb_state_notify_event_t *state) update_xkb_state(struct x11_backend *b, xcb_xkb_state_notify_event_t *state)
{ {
xkb_state_update_mask(b->core_seat.keyboard->xkb_state.state, struct weston_keyboard *keyboard =
weston_seat_get_keyboard(&b->core_seat);
xkb_state_update_mask(keyboard->xkb_state.state,
get_xkb_mod_mask(b, state->baseMods), get_xkb_mod_mask(b, state->baseMods),
get_xkb_mod_mask(b, state->latchedMods), get_xkb_mod_mask(b, state->latchedMods),
get_xkb_mod_mask(b, state->lockedMods), get_xkb_mod_mask(b, state->lockedMods),
@ -1003,9 +1010,10 @@ static void
update_xkb_state_from_core(struct x11_backend *b, uint16_t x11_mask) update_xkb_state_from_core(struct x11_backend *b, uint16_t x11_mask)
{ {
uint32_t mask = get_xkb_mod_mask(b, x11_mask); uint32_t mask = get_xkb_mod_mask(b, x11_mask);
struct weston_keyboard *keyboard = b->core_seat.keyboard; struct weston_keyboard *keyboard
= weston_seat_get_keyboard(&b->core_seat);
xkb_state_update_mask(b->core_seat.keyboard->xkb_state.state, xkb_state_update_mask(keyboard->xkb_state.state,
keyboard->modifiers.mods_depressed & mask, keyboard->modifiers.mods_depressed & mask,
keyboard->modifiers.mods_latched & mask, keyboard->modifiers.mods_latched & mask,
keyboard->modifiers.mods_locked & mask, keyboard->modifiers.mods_locked & mask,

@ -95,7 +95,7 @@ static void weston_mode_switch_finish(struct weston_output *output,
/* If a pointer falls outside the outputs new geometry, move it to its /* If a pointer falls outside the outputs new geometry, move it to its
* lower-right corner */ * lower-right corner */
wl_list_for_each(seat, &output->compositor->seat_list, link) { 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; int32_t x, y;
if (!pointer) if (!pointer)
@ -1752,15 +1752,20 @@ weston_view_unmap(struct weston_view *view)
return; return;
wl_list_for_each(seat, &view->surface->compositor->seat_list, link) { wl_list_for_each(seat, &view->surface->compositor->seat_list, link) {
if (seat->keyboard && seat->keyboard->focus == view->surface) struct weston_touch *touch = weston_seat_get_touch(seat);
weston_keyboard_set_focus(seat->keyboard, NULL); struct weston_pointer *pointer = weston_seat_get_pointer(seat);
if (seat->pointer && seat->pointer->focus == view) struct weston_keyboard *keyboard =
weston_pointer_set_focus(seat->pointer, 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, NULL,
wl_fixed_from_int(0), wl_fixed_from_int(0),
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->touch, NULL); weston_touch_set_focus(touch, NULL);
} }
} }
@ -4587,10 +4592,10 @@ weston_compositor_set_default_pointer_grab(struct weston_compositor *ec,
ec->default_pointer_grab = interface; ec->default_pointer_grab = interface;
wl_list_for_each(seat, &ec->seat_list, link) { wl_list_for_each(seat, &ec->seat_list, link) {
if (seat->pointer) { struct weston_pointer *pointer = weston_seat_get_pointer(seat);
weston_pointer_set_default_grab(seat->pointer,
interface); if (pointer)
} weston_pointer_set_default_grab(pointer, interface);
} }
} }

@ -503,9 +503,9 @@ struct weston_seat {
struct wl_list base_resource_list; struct wl_list base_resource_list;
struct wl_global *global; struct wl_global *global;
struct weston_pointer *pointer; struct weston_pointer *pointer_state;
struct weston_keyboard *keyboard; struct weston_keyboard *keyboard_state;
struct weston_touch *touch; struct weston_touch *touch_state;
int pointer_device_count; int pointer_device_count;
int keyboard_device_count; int keyboard_device_count;
int touch_device_count; int touch_device_count;
@ -1587,6 +1587,15 @@ weston_parse_transform(const char *transform, uint32_t *out);
const char * const char *
weston_transform_to_string(uint32_t output_transform); 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 #ifdef __cplusplus
} }
#endif #endif

@ -662,23 +662,25 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
struct wl_resource *icon_resource, uint32_t serial) struct wl_resource *icon_resource, uint32_t serial)
{ {
struct weston_seat *seat = wl_resource_get_user_data(resource); 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_surface *origin = wl_resource_get_user_data(origin_resource);
struct weston_data_source *source = NULL; struct weston_data_source *source = NULL;
struct weston_surface *icon = NULL; struct weston_surface *icon = NULL;
int is_pointer_grab, is_touch_grab; int is_pointer_grab, is_touch_grab;
int32_t ret = 0; int32_t ret = 0;
is_pointer_grab = seat->pointer && is_pointer_grab = pointer &&
seat->pointer->button_count == 1 && pointer->button_count == 1 &&
seat->pointer->grab_serial == serial && pointer->grab_serial == serial &&
seat->pointer->focus && pointer->focus &&
seat->pointer->focus->surface == origin; pointer->focus->surface == origin;
is_touch_grab = seat->touch && is_touch_grab = touch &&
seat->touch->num_tp == 1 && touch->num_tp == 1 &&
seat->touch->grab_serial == serial && touch->grab_serial == serial &&
seat->touch->focus && touch->focus &&
seat->touch->focus->surface == origin; touch->focus->surface == origin;
if (!is_pointer_grab && !is_touch_grab) if (!is_pointer_grab && !is_touch_grab)
return; return;
@ -698,9 +700,9 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
} }
if (is_pointer_grab) 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) 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) if (ret < 0)
wl_resource_post_no_memory(resource); wl_resource_post_no_memory(resource);
@ -711,13 +713,14 @@ destroy_selection_data_source(struct wl_listener *listener, void *data)
{ {
struct weston_seat *seat = container_of(listener, struct weston_seat, struct weston_seat *seat = container_of(listener, struct weston_seat,
selection_data_source_listener); selection_data_source_listener);
struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
struct wl_resource *data_device; struct wl_resource *data_device;
struct weston_surface *focus = NULL; struct weston_surface *focus = NULL;
seat->selection_data_source = NULL; seat->selection_data_source = NULL;
if (seat->keyboard) if (keyboard)
focus = seat->keyboard->focus; focus = keyboard->focus;
if (focus && focus->resource) { if (focus && focus->resource) {
data_device = wl_resource_find_for_client(&seat->drag_resource_list, data_device = wl_resource_find_for_client(&seat->drag_resource_list,
wl_resource_get_client(focus->resource)); wl_resource_get_client(focus->resource));
@ -766,6 +769,7 @@ weston_seat_set_selection(struct weston_seat *seat,
struct weston_data_source *source, uint32_t serial) struct weston_data_source *source, uint32_t serial)
{ {
struct weston_surface *focus = NULL; struct weston_surface *focus = NULL;
struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
if (seat->selection_data_source && if (seat->selection_data_source &&
seat->selection_serial - serial < UINT32_MAX / 2) seat->selection_serial - serial < UINT32_MAX / 2)
@ -780,8 +784,8 @@ weston_seat_set_selection(struct weston_seat *seat,
seat->selection_data_source = source; seat->selection_data_source = source;
seat->selection_serial = serial; seat->selection_serial = serial;
if (seat->keyboard) if (keyboard)
focus = seat->keyboard->focus; focus = keyboard->focus;
if (focus && focus->resource) { if (focus && focus->resource) {
weston_seat_send_selection(seat, wl_resource_get_client(focus->resource)); weston_seat_send_selection(seat, wl_resource_get_client(focus->resource));
} }
@ -939,11 +943,12 @@ WL_EXPORT void
wl_data_device_set_keyboard_focus(struct weston_seat *seat) wl_data_device_set_keyboard_focus(struct weston_seat *seat)
{ {
struct weston_surface *focus; struct weston_surface *focus;
struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
if (!seat->keyboard) if (!keyboard)
return; return;
focus = seat->keyboard->focus; focus = keyboard->focus;
if (!focus || !focus->resource) if (!focus || !focus->resource)
return; return;

@ -53,7 +53,7 @@ static void unbind_resource(struct wl_resource *resource)
WL_EXPORT void WL_EXPORT void
weston_seat_repick(struct weston_seat *seat) 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) if (!pointer)
return; return;
@ -391,7 +391,8 @@ default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
uint32_t mods_locked, uint32_t group) uint32_t mods_locked, uint32_t group)
{ {
struct weston_keyboard *keyboard = grab->keyboard; 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_resource *resource;
struct wl_list *resource_list; struct wl_list *resource_list;
@ -626,7 +627,7 @@ weston_pointer_set_focus(struct weston_pointer *pointer,
struct weston_view *view, struct weston_view *view,
wl_fixed_t sx, wl_fixed_t sy) 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_resource *resource;
struct wl_display *display = pointer->seat->compositor->wl_display; struct wl_display *display = pointer->seat->compositor->wl_display;
uint32_t serial; uint32_t serial;
@ -946,7 +947,7 @@ notify_motion(struct weston_seat *seat,
uint32_t time, wl_fixed_t dx, wl_fixed_t dy) uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
{ {
struct weston_compositor *ec = seat->compositor; 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); weston_compositor_wake(ec);
pointer->grab->interface->motion(pointer->grab, time, pointer->x + dx, pointer->y + dy); pointer->grab->interface->motion(pointer->grab, time, pointer->x + dx, pointer->y + dy);
@ -956,7 +957,7 @@ static void
run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new) run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new)
{ {
struct weston_compositor *compositor = seat->compositor; struct weston_compositor *compositor = seat->compositor;
struct weston_keyboard *keyboard = seat->keyboard; struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
uint32_t diff; uint32_t diff;
unsigned int i; unsigned int i;
struct { struct {
@ -993,7 +994,7 @@ notify_motion_absolute(struct weston_seat *seat,
uint32_t time, wl_fixed_t x, wl_fixed_t y) uint32_t time, wl_fixed_t x, wl_fixed_t y)
{ {
struct weston_compositor *ec = seat->compositor; 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); weston_compositor_wake(ec);
pointer->grab->interface->motion(pointer->grab, time, x, y); pointer->grab->interface->motion(pointer->grab, time, x, y);
@ -1004,9 +1005,10 @@ weston_surface_activate(struct weston_surface *surface,
struct weston_seat *seat) struct weston_seat *seat)
{ {
struct weston_compositor *compositor = seat->compositor; struct weston_compositor *compositor = seat->compositor;
struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
if (seat->keyboard) { if (keyboard) {
weston_keyboard_set_focus(seat->keyboard, surface); weston_keyboard_set_focus(keyboard, surface);
wl_data_device_set_keyboard_focus(seat); wl_data_device_set_keyboard_focus(seat);
} }
@ -1018,7 +1020,7 @@ notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
enum wl_pointer_button_state state) enum wl_pointer_button_state state)
{ {
struct weston_compositor *compositor = seat->compositor; 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) { if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
weston_compositor_idle_inhibit(compositor); weston_compositor_idle_inhibit(compositor);
@ -1049,7 +1051,7 @@ notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
wl_fixed_t value) wl_fixed_t value)
{ {
struct weston_compositor *compositor = seat->compositor; 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_resource *resource;
struct wl_list *resource_list; struct wl_list *resource_list;
@ -1124,7 +1126,7 @@ weston_keyboard_set_locks(struct weston_keyboard *keyboard,
WL_EXPORT void WL_EXPORT void
notify_modifiers(struct weston_seat *seat, uint32_t serial) 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; struct weston_keyboard_grab *grab = keyboard->grab;
uint32_t mods_depressed, mods_latched, mods_locked, group; uint32_t mods_depressed, mods_latched, mods_locked, group;
uint32_t mods_lookup; uint32_t mods_lookup;
@ -1196,7 +1198,7 @@ static void
update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key, update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
enum wl_keyboard_key_state state) 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; enum xkb_key_direction direction;
/* Keyboard modifiers don't exist in raw keyboard mode */ /* Keyboard modifiers don't exist in raw keyboard mode */
@ -1240,7 +1242,7 @@ weston_xkb_info_create(struct xkb_keymap *keymap);
static void static void
update_keymap(struct weston_seat *seat) 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 wl_resource *resource;
struct weston_xkb_info *xkb_info; struct weston_xkb_info *xkb_info;
struct xkb_state *state; struct xkb_state *state;
@ -1319,7 +1321,7 @@ notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
enum weston_key_state_update update_state) enum weston_key_state_update update_state)
{ {
struct weston_compositor *compositor = seat->compositor; 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; struct weston_keyboard_grab *grab = keyboard->grab;
uint32_t *k, *end; uint32_t *k, *end;
@ -1376,8 +1378,10 @@ WL_EXPORT void
notify_pointer_focus(struct weston_seat *seat, struct weston_output *output, notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
wl_fixed_t x, wl_fixed_t y) wl_fixed_t x, wl_fixed_t y)
{ {
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
if (output) { if (output) {
weston_pointer_move(seat->pointer, x, y); weston_pointer_move(pointer, x, y);
} else { } else {
/* FIXME: We should call weston_pointer_set_focus(seat, /* FIXME: We should call weston_pointer_set_focus(seat,
* NULL) here, but somehow that breaks re-entry... */ * NULL) here, but somehow that breaks re-entry... */
@ -1400,7 +1404,7 @@ notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
enum weston_key_state_update update_state) enum weston_key_state_update update_state)
{ {
struct weston_compositor *compositor = seat->compositor; 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; struct weston_surface *surface;
uint32_t *k, serial; uint32_t *k, serial;
@ -1426,7 +1430,8 @@ WL_EXPORT void
notify_keyboard_focus_out(struct weston_seat *seat) notify_keyboard_focus_out(struct weston_seat *seat)
{ {
struct weston_compositor *compositor = seat->compositor; 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; uint32_t *k, serial;
serial = wl_display_next_serial(compositor->wl_display); serial = wl_display_next_serial(compositor->wl_display);
@ -1448,8 +1453,8 @@ notify_keyboard_focus_out(struct weston_seat *seat)
weston_keyboard_set_focus(keyboard, NULL); weston_keyboard_set_focus(keyboard, NULL);
weston_keyboard_cancel_grab(keyboard); weston_keyboard_cancel_grab(keyboard);
if (seat->pointer) if (pointer)
weston_pointer_cancel_grab(seat->pointer); weston_pointer_cancel_grab(pointer);
} }
WL_EXPORT void WL_EXPORT void
@ -1507,7 +1512,7 @@ notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
wl_fixed_t x, wl_fixed_t y, int touch_type) wl_fixed_t x, wl_fixed_t y, int touch_type)
{ {
struct weston_compositor *ec = seat->compositor; 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_touch_grab *grab = touch->grab;
struct weston_view *ev; struct weston_view *ev;
wl_fixed_t sx, sy; wl_fixed_t sx, sy;
@ -1586,7 +1591,7 @@ notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
WL_EXPORT void WL_EXPORT void
notify_touch_frame(struct weston_seat *seat) 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; struct weston_touch_grab *grab = touch->grab;
grab->interface->frame(grab); grab->interface->frame(grab);
@ -1706,9 +1711,18 @@ seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
uint32_t id) uint32_t id)
{ {
struct weston_seat *seat = wl_resource_get_user_data(resource); struct weston_seat *seat = wl_resource_get_user_data(resource);
/* We use the pointer_state directly, which means we'll
* give a wl_pointer if the seat has ever had one - even though
* the spec explicitly states that this request only takes effect
* if the seat has the pointer capability.
*
* This prevents a race between the compositor sending new
* capabilities and the client trying to use the old ones.
*/
struct weston_pointer *pointer = seat->pointer_state;
struct wl_resource *cr; struct wl_resource *cr;
if (!seat->pointer) if (!pointer)
return; return;
cr = wl_resource_create(client, &wl_pointer_interface, cr = wl_resource_create(client, &wl_pointer_interface,
@ -1721,25 +1735,25 @@ seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
/* May be moved to focused list later by either /* May be moved to focused list later by either
* weston_pointer_set_focus or directly if this client is already * weston_pointer_set_focus or directly if this client is already
* focused */ * focused */
wl_list_insert(&seat->pointer->resource_list, wl_resource_get_link(cr)); wl_list_insert(&pointer->resource_list, wl_resource_get_link(cr));
wl_resource_set_implementation(cr, &pointer_interface, seat->pointer, wl_resource_set_implementation(cr, &pointer_interface, pointer,
unbind_resource); unbind_resource);
if (seat->pointer->focus && seat->pointer->focus->surface->resource && if (pointer->focus && pointer->focus->surface->resource &&
wl_resource_get_client(seat->pointer->focus->surface->resource) == client) { wl_resource_get_client(pointer->focus->surface->resource) == client) {
wl_fixed_t sx, sy; wl_fixed_t sx, sy;
weston_view_from_global_fixed(seat->pointer->focus, weston_view_from_global_fixed(pointer->focus,
seat->pointer->x, pointer->x,
seat->pointer->y, pointer->y,
&sx, &sy); &sx, &sy);
wl_list_remove(wl_resource_get_link(cr)); 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_resource_get_link(cr));
wl_pointer_send_enter(cr, wl_pointer_send_enter(cr,
seat->pointer->focus_serial, pointer->focus_serial,
seat->pointer->focus->surface->resource, pointer->focus->surface->resource,
sx, sy); sx, sy);
} }
} }
@ -1758,16 +1772,19 @@ static bool
should_send_modifiers_to_client(struct weston_seat *seat, should_send_modifiers_to_client(struct weston_seat *seat,
struct wl_client *client) struct wl_client *client)
{ {
if (seat->keyboard && struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
seat->keyboard->focus && struct weston_pointer *pointer = weston_seat_get_pointer(seat);
seat->keyboard->focus->resource &&
wl_resource_get_client(seat->keyboard->focus->resource) == client) if (keyboard &&
keyboard->focus &&
keyboard->focus->resource &&
wl_resource_get_client(keyboard->focus->resource) == client)
return true; return true;
if (seat->pointer && if (pointer &&
seat->pointer->focus && pointer->focus &&
seat->pointer->focus->surface->resource && pointer->focus->surface->resource &&
wl_resource_get_client(seat->pointer->focus->surface->resource) == client) wl_resource_get_client(pointer->focus->surface->resource) == client)
return true; return true;
return false; return false;
@ -1778,7 +1795,15 @@ seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
uint32_t id) uint32_t id)
{ {
struct weston_seat *seat = wl_resource_get_user_data(resource); struct weston_seat *seat = wl_resource_get_user_data(resource);
struct weston_keyboard *keyboard = seat->keyboard; /* We use the keyboard_state directly, which means we'll
* give a wl_keyboard if the seat has ever had one - even though
* the spec explicitly states that this request only takes effect
* if the seat has the keyboard capability.
*
* This prevents a race between the compositor sending new
* capabilities and the client trying to use the old ones.
*/
struct weston_keyboard *keyboard = seat->keyboard_state;
struct wl_resource *cr; struct wl_resource *cr;
if (!keyboard) if (!keyboard)
@ -1858,9 +1883,18 @@ seat_get_touch(struct wl_client *client, struct wl_resource *resource,
uint32_t id) uint32_t id)
{ {
struct weston_seat *seat = wl_resource_get_user_data(resource); struct weston_seat *seat = wl_resource_get_user_data(resource);
/* We use the touch_state directly, which means we'll
* give a wl_touch if the seat has ever had one - even though
* the spec explicitly states that this request only takes effect
* if the seat has the touch capability.
*
* This prevents a race between the compositor sending new
* capabilities and the client trying to use the old ones.
*/
struct weston_touch *touch = seat->touch_state;
struct wl_resource *cr; struct wl_resource *cr;
if (!seat->touch) if (!touch)
return; return;
cr = wl_resource_create(client, &wl_touch_interface, cr = wl_resource_create(client, &wl_touch_interface,
@ -1870,12 +1904,12 @@ seat_get_touch(struct wl_client *client, struct wl_resource *resource,
return; return;
} }
if (seat->touch->focus && if (touch->focus &&
wl_resource_get_client(seat->touch->focus->surface->resource) == client) { wl_resource_get_client(touch->focus->surface->resource) == client) {
wl_list_insert(&seat->touch->resource_list, wl_list_insert(&touch->resource_list,
wl_resource_get_link(cr)); wl_resource_get_link(cr));
} else { } else {
wl_list_insert(&seat->touch->focus_resource_list, wl_list_insert(&touch->focus_resource_list,
wl_resource_get_link(cr)); wl_resource_get_link(cr));
} }
wl_resource_set_implementation(cr, &touch_interface, wl_resource_set_implementation(cr, &touch_interface,
@ -1901,11 +1935,11 @@ bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
wl_resource_set_implementation(resource, &seat_interface, data, wl_resource_set_implementation(resource, &seat_interface, data,
unbind_resource); unbind_resource);
if (seat->pointer_device_count) if (weston_seat_get_pointer(seat))
caps |= WL_SEAT_CAPABILITY_POINTER; caps |= WL_SEAT_CAPABILITY_POINTER;
if (seat->keyboard_device_count) if (weston_seat_get_keyboard(seat))
caps |= WL_SEAT_CAPABILITY_KEYBOARD; caps |= WL_SEAT_CAPABILITY_KEYBOARD;
if (seat->touch_device_count) if (weston_seat_get_touch(seat))
caps |= WL_SEAT_CAPABILITY_TOUCH; caps |= WL_SEAT_CAPABILITY_TOUCH;
wl_seat_send_capabilities(resource, caps); wl_seat_send_capabilities(resource, caps);
@ -2095,17 +2129,19 @@ weston_compositor_xkb_destroy(struct weston_compositor *ec)
WL_EXPORT void WL_EXPORT void
weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap) 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; return;
#ifdef ENABLE_XKBCOMMON #ifdef ENABLE_XKBCOMMON
if (!seat->compositor->use_xkbcommon) if (!seat->compositor->use_xkbcommon)
return; return;
xkb_keymap_unref(seat->keyboard->pending_keymap); xkb_keymap_unref(keyboard->pending_keymap);
seat->keyboard->pending_keymap = xkb_keymap_ref(keymap); keyboard->pending_keymap = xkb_keymap_ref(keymap);
if (seat->keyboard->keys.size == 0) if (keyboard->keys.size == 0)
update_keymap(seat); update_keymap(seat);
#endif #endif
} }
@ -2115,7 +2151,7 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
{ {
struct weston_keyboard *keyboard; struct weston_keyboard *keyboard;
if (seat->keyboard) { if (seat->keyboard_state) {
seat->keyboard_device_count += 1; seat->keyboard_device_count += 1;
if (seat->keyboard_device_count == 1) if (seat->keyboard_device_count == 1)
seat_send_updated_caps(seat); seat_send_updated_caps(seat);
@ -2151,7 +2187,7 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
} }
#endif #endif
seat->keyboard = keyboard; seat->keyboard_state = keyboard;
seat->keyboard_device_count = 1; seat->keyboard_device_count = 1;
keyboard->seat = seat; keyboard->seat = seat;
@ -2196,9 +2232,9 @@ weston_seat_release_keyboard(struct weston_seat *seat)
seat->keyboard_device_count--; seat->keyboard_device_count--;
assert(seat->keyboard_device_count >= 0); assert(seat->keyboard_device_count >= 0);
if (seat->keyboard_device_count == 0) { if (seat->keyboard_device_count == 0) {
weston_keyboard_set_focus(seat->keyboard, NULL); weston_keyboard_set_focus(seat->keyboard_state, NULL);
weston_keyboard_cancel_grab(seat->keyboard); weston_keyboard_cancel_grab(seat->keyboard_state);
weston_keyboard_reset_state(seat->keyboard); weston_keyboard_reset_state(seat->keyboard_state);
seat_send_updated_caps(seat); seat_send_updated_caps(seat);
} }
} }
@ -2208,7 +2244,7 @@ weston_seat_init_pointer(struct weston_seat *seat)
{ {
struct weston_pointer *pointer; struct weston_pointer *pointer;
if (seat->pointer) { if (seat->pointer_state) {
seat->pointer_device_count += 1; seat->pointer_device_count += 1;
if (seat->pointer_device_count == 1) if (seat->pointer_device_count == 1)
seat_send_updated_caps(seat); seat_send_updated_caps(seat);
@ -2219,7 +2255,7 @@ weston_seat_init_pointer(struct weston_seat *seat)
if (pointer == NULL) if (pointer == NULL)
return; return;
seat->pointer = pointer; seat->pointer_state = pointer;
seat->pointer_device_count = 1; seat->pointer_device_count = 1;
pointer->seat = seat; pointer->seat = seat;
@ -2229,7 +2265,7 @@ weston_seat_init_pointer(struct weston_seat *seat)
WL_EXPORT void WL_EXPORT void
weston_seat_release_pointer(struct weston_seat *seat) weston_seat_release_pointer(struct weston_seat *seat)
{ {
struct weston_pointer *pointer = seat->pointer; struct weston_pointer *pointer = seat->pointer_state;
seat->pointer_device_count--; seat->pointer_device_count--;
if (seat->pointer_device_count == 0) { if (seat->pointer_device_count == 0) {
@ -2256,7 +2292,7 @@ weston_seat_init_touch(struct weston_seat *seat)
{ {
struct weston_touch *touch; struct weston_touch *touch;
if (seat->touch) { if (seat->touch_state) {
seat->touch_device_count += 1; seat->touch_device_count += 1;
if (seat->touch_device_count == 1) if (seat->touch_device_count == 1)
seat_send_updated_caps(seat); seat_send_updated_caps(seat);
@ -2267,7 +2303,7 @@ weston_seat_init_touch(struct weston_seat *seat)
if (touch == NULL) if (touch == NULL)
return; return;
seat->touch = touch; seat->touch_state = touch;
seat->touch_device_count = 1; seat->touch_device_count = 1;
touch->seat = seat; touch->seat = seat;
@ -2279,9 +2315,9 @@ weston_seat_release_touch(struct weston_seat *seat)
{ {
seat->touch_device_count--; seat->touch_device_count--;
if (seat->touch_device_count == 0) { if (seat->touch_device_count == 0) {
weston_touch_set_focus(seat->touch, NULL); weston_touch_set_focus(seat->touch_state, NULL);
weston_touch_cancel_grab(seat->touch); weston_touch_cancel_grab(seat->touch_state);
weston_touch_reset_state(seat->touch); weston_touch_reset_state(seat->touch_state);
seat_send_updated_caps(seat); seat_send_updated_caps(seat);
} }
} }
@ -2321,12 +2357,12 @@ weston_seat_release(struct weston_seat *seat)
if (seat->saved_kbd_focus) if (seat->saved_kbd_focus)
wl_list_remove(&seat->saved_kbd_focus_listener.link); wl_list_remove(&seat->saved_kbd_focus_listener.link);
if (seat->pointer) if (seat->pointer_state)
weston_pointer_destroy(seat->pointer); weston_pointer_destroy(seat->pointer_state);
if (seat->keyboard) if (seat->keyboard_state)
weston_keyboard_destroy(seat->keyboard); weston_keyboard_destroy(seat->keyboard_state);
if (seat->touch) if (seat->touch_state)
weston_touch_destroy(seat->touch); weston_touch_destroy(seat->touch_state);
free (seat->seat_name); free (seat->seat_name);
@ -2334,3 +2370,69 @@ weston_seat_release(struct weston_seat *seat)
wl_signal_emit(&seat->destroy_signal, seat); wl_signal_emit(&seat->destroy_signal, seat);
} }
/** Get a seat's keyboard pointer
*
* \param seat The seat to query
* \return The seat's keyboard pointer, or NULL if no keyboard is present
*
* The keyboard pointer for a seat isn't freed when all keyboards are removed,
* so it 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_state;
return NULL;
}
/** Get a seat's pointer pointer
*
* \param seat The seat to query
* \return The seat's pointer pointer, or NULL if no pointer device is present
*
* The pointer pointer for a seat isn't freed when all mice are removed,
* so it 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_state;
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 is present
*
* The touch pointer for a seat isn't freed when all touch devices are removed,
* so it 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_state;
return NULL;
}

@ -60,6 +60,7 @@ device_added(struct udev_input *input, struct libinput_device *libinput_device)
struct libinput_seat *libinput_seat; struct libinput_seat *libinput_seat;
struct weston_seat *seat; struct weston_seat *seat;
struct udev_seat *udev_seat; struct udev_seat *udev_seat;
struct weston_pointer *pointer;
c = input->compositor; c = input->compositor;
libinput_seat = libinput_device_get_seat(libinput_device); libinput_seat = libinput_device_get_seat(libinput_device);
@ -77,10 +78,11 @@ device_added(struct udev_input *input, struct libinput_device *libinput_device)
udev_seat = (struct udev_seat *) seat; udev_seat = (struct udev_seat *) seat;
wl_list_insert(udev_seat->devices_list.prev, &device->link); wl_list_insert(udev_seat->devices_list.prev, &device->link);
if (seat->output && seat->pointer) pointer = weston_seat_get_pointer(seat);
weston_pointer_clamp(seat->pointer, if (seat->output && pointer)
&seat->pointer->x, weston_pointer_clamp(pointer,
&seat->pointer->y); &pointer->x,
&pointer->y);
output_name = libinput_device_get_output_name(libinput_device); output_name = libinput_device_get_output_name(libinput_device);
if (output_name) { if (output_name) {
@ -378,8 +380,11 @@ udev_seat_create(struct udev_input *input, const char *seat_name)
static void static void
udev_seat_destroy(struct udev_seat *seat) udev_seat_destroy(struct udev_seat *seat)
{ {
struct weston_keyboard *keyboard =
weston_seat_get_keyboard(&seat->base);
udev_seat_remove_devices(seat); udev_seat_remove_devices(seat);
if (seat->base.keyboard) if (keyboard)
notify_keyboard_focus_out(&seat->base); notify_keyboard_focus_out(&seat->base);
weston_seat_release(&seat->base); weston_seat_release(&seat->base);
wl_list_remove(&seat->output_create_listener.link); wl_list_remove(&seat->output_create_listener.link);

@ -798,8 +798,11 @@ int main(int argc, char *argv[])
weston_config_section_get_bool(section, "numlock-on", &numlock_on, 0); weston_config_section_get_bool(section, "numlock-on", &numlock_on, 0);
if (numlock_on) { if (numlock_on) {
wl_list_for_each(seat, &ec->seat_list, link) { wl_list_for_each(seat, &ec->seat_list, link) {
if (seat->keyboard) struct weston_keyboard *keyboard =
weston_keyboard_set_locks(seat->keyboard, weston_seat_get_keyboard(seat);
if (keyboard)
weston_keyboard_set_locks(keyboard,
WESTON_NUM_LOCK, WESTON_NUM_LOCK,
WESTON_NUM_LOCK); WESTON_NUM_LOCK);
} }

@ -658,7 +658,7 @@ input_method_context_grab_keyboard(struct wl_client *client,
wl_resource_get_user_data(resource); wl_resource_get_user_data(resource);
struct wl_resource *cr; struct wl_resource *cr;
struct weston_seat *seat = context->input_method->seat; 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); cr = wl_resource_create(client, &wl_keyboard_interface, 1, id);
wl_resource_set_implementation(cr, NULL, context, unbind_keyboard); wl_resource_set_implementation(cr, NULL, context, unbind_keyboard);
@ -687,7 +687,7 @@ input_method_context_key(struct wl_client *client,
struct input_method_context *context = struct input_method_context *context =
wl_resource_get_user_data(resource); wl_resource_get_user_data(resource);
struct weston_seat *seat = context->input_method->seat; 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; struct weston_keyboard_grab *default_grab = &keyboard->default_grab;
default_grab->interface->key(default_grab, time, key, state_w); default_grab->interface->key(default_grab, time, key, state_w);
@ -706,7 +706,7 @@ input_method_context_modifiers(struct wl_client *client,
wl_resource_get_user_data(resource); wl_resource_get_user_data(resource);
struct weston_seat *seat = context->input_method->seat; 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; struct weston_keyboard_grab *default_grab = &keyboard->default_grab;
default_grab->interface->modifiers(default_grab, default_grab->interface->modifiers(default_grab,
@ -812,10 +812,11 @@ input_method_context_end_keyboard_grab(struct input_method_context *context)
struct weston_keyboard_grab *grab; struct weston_keyboard_grab *grab;
struct weston_keyboard *keyboard; struct weston_keyboard *keyboard;
if (!context->input_method->seat->keyboard) keyboard = weston_seat_get_keyboard(context->input_method->seat);
if (!keyboard)
return; return;
grab = &context->input_method->seat->keyboard->input_method_grab; grab = &keyboard->input_method_grab;
keyboard = grab->keyboard; keyboard = grab->keyboard;
if (!keyboard) if (!keyboard)
return; return;
@ -907,15 +908,17 @@ handle_keyboard_focus(struct wl_listener *listener, void *data)
static void static void
input_method_init_seat(struct weston_seat *seat) input_method_init_seat(struct weston_seat *seat)
{ {
struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
if (seat->input_method->focus_listener_initialized) if (seat->input_method->focus_listener_initialized)
return; return;
if (seat->keyboard) { if (keyboard) {
seat->input_method->keyboard_focus_listener.notify = seat->input_method->keyboard_focus_listener.notify =
handle_keyboard_focus; handle_keyboard_focus;
wl_signal_add(&seat->keyboard->focus_signal, wl_signal_add(&keyboard->focus_signal,
&seat->input_method->keyboard_focus_listener); &seat->input_method->keyboard_focus_listener);
seat->keyboard->input_method_grab.interface = keyboard->input_method_grab.interface =
&input_method_context_grab; &input_method_context_grab;
} }

@ -129,11 +129,12 @@ WL_EXPORT void
weston_output_update_zoom(struct weston_output *output) weston_output_update_zoom(struct weston_output *output)
{ {
struct weston_seat *seat = output->zoom.seat; struct weston_seat *seat = output->zoom.seat;
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
assert(output->zoom.active); assert(output->zoom.active);
output->zoom.current.x = seat->pointer->x; output->zoom.current.x = pointer->x;
output->zoom.current.y = seat->pointer->y; output->zoom.current.y = pointer->y;
weston_zoom_transition(output); weston_zoom_transition(output);
weston_output_update_zoom_transform(output); weston_output_update_zoom_transform(output);
@ -154,13 +155,15 @@ WL_EXPORT void
weston_output_activate_zoom(struct weston_output *output, weston_output_activate_zoom(struct weston_output *output,
struct weston_seat *seat) struct weston_seat *seat)
{ {
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
if (output->zoom.active) if (output->zoom.active)
return; return;
output->zoom.active = true; output->zoom.active = true;
output->zoom.seat = seat; output->zoom.seat = seat;
output->disable_planes++; output->disable_planes++;
wl_signal_add(&seat->pointer->motion_signal, wl_signal_add(&pointer->motion_signal,
&output->zoom.motion_listener); &output->zoom.motion_listener);
} }

@ -139,6 +139,7 @@ trigger_binding(struct weston_keyboard *keyboard, uint32_t time, uint32_t key,
char fname[1024]; char fname[1024];
struct weston_surface *surface; struct weston_surface *surface;
struct weston_seat *seat = keyboard->seat; struct weston_seat *seat = keyboard->seat;
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
int width, height; int width, height;
char desc[512]; char desc[512];
void *pixels; void *pixels;
@ -147,12 +148,10 @@ trigger_binding(struct weston_keyboard *keyboard, uint32_t time, uint32_t key,
int ret; int ret;
FILE *fp; FILE *fp;
if (seat->pointer_device_count == 0 || if (!pointer || !pointer->focus)
!seat->pointer ||
!seat->pointer->focus)
return; return;
surface = seat->pointer->focus->surface; surface = pointer->focus->surface;
weston_surface_get_content_size(surface, &width, &height); weston_surface_get_content_size(surface, &width, &height);

@ -83,7 +83,7 @@ static void
notify_pointer_position(struct weston_test *test, struct wl_resource *resource) notify_pointer_position(struct weston_test *test, struct wl_resource *resource)
{ {
struct weston_seat *seat = get_seat(test); struct weston_seat *seat = get_seat(test);
struct weston_pointer *pointer = seat->pointer; struct weston_pointer *pointer = weston_seat_get_pointer(seat);
weston_test_send_pointer_position(resource, pointer->x, pointer->y); weston_test_send_pointer_position(resource, pointer->x, pointer->y);
} }
@ -144,7 +144,7 @@ move_pointer(struct wl_client *client, struct wl_resource *resource,
{ {
struct weston_test *test = wl_resource_get_user_data(resource); struct weston_test *test = wl_resource_get_user_data(resource);
struct weston_seat *seat = get_seat(test); 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, notify_motion(seat, 100,
wl_fixed_from_int(x) - pointer->x, wl_fixed_from_int(x) - pointer->x,
@ -171,12 +171,13 @@ activate_surface(struct wl_client *client, struct wl_resource *resource,
wl_resource_get_user_data(surface_resource) : NULL; wl_resource_get_user_data(surface_resource) : NULL;
struct weston_test *test = wl_resource_get_user_data(resource); struct weston_test *test = wl_resource_get_user_data(resource);
struct weston_seat *seat; struct weston_seat *seat;
struct weston_keyboard *keyboard;
seat = get_seat(test); seat = get_seat(test);
keyboard = weston_seat_get_keyboard(seat);
if (surface) { if (surface) {
weston_surface_activate(surface, seat); weston_surface_activate(surface, seat);
notify_keyboard_focus_in(seat, &seat->keyboard->keys, notify_keyboard_focus_in(seat, &keyboard->keys,
STATE_UPDATE_AUTOMATIC); STATE_UPDATE_AUTOMATIC);
} }
else { else {

@ -154,6 +154,7 @@ handle_enter(struct weston_wm *wm, xcb_client_message_event_t *client_message)
{ {
struct dnd_data_source *source; struct dnd_data_source *source;
struct weston_seat *seat = weston_wm_pick_seat(wm); struct weston_seat *seat = weston_wm_pick_seat(wm);
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
char **p; char **p;
const char *name; const char *name;
uint32_t *types; uint32_t *types;
@ -213,7 +214,7 @@ handle_enter(struct weston_wm *wm, xcb_client_message_event_t *client_message)
} }
free(reply); free(reply);
weston_pointer_start_drag(seat->pointer, &source->base, NULL, NULL); weston_pointer_start_drag(pointer, &source->base, NULL, NULL);
} }
int int

@ -1316,12 +1316,16 @@ weston_wm_pick_seat_for_window(struct weston_wm_window *window)
seat = NULL; seat = NULL;
wl_list_for_each(s, &wm->server->compositor->seat_list, link) { wl_list_for_each(s, &wm->server->compositor->seat_list, link) {
if (s->pointer != NULL && s->pointer->focus && struct weston_pointer *pointer = weston_seat_get_pointer(s);
s->pointer->focus->surface == window->surface && struct weston_pointer *old_pointer =
s->pointer->button_count > 0 && weston_seat_get_pointer(seat);
(seat == NULL ||
s->pointer->grab_serial - if (pointer && pointer->focus &&
seat->pointer->grab_serial < (1 << 30))) pointer->focus->surface == window->surface &&
pointer->button_count > 0 &&
(!seat ||
pointer->grab_serial -
old_pointer->grab_serial < (1 << 30)))
seat = s; seat = s;
} }
@ -1345,13 +1349,14 @@ weston_wm_window_handle_moveresize(struct weston_wm_window *window,
struct weston_wm *wm = window->wm; struct weston_wm *wm = window->wm;
struct weston_seat *seat = weston_wm_pick_seat_for_window(window); struct weston_seat *seat = weston_wm_pick_seat_for_window(window);
struct weston_pointer *pointer = weston_seat_get_pointer(seat);
int detail; int detail;
struct weston_shell_interface *shell_interface = struct weston_shell_interface *shell_interface =
&wm->server->compositor->shell_interface; &wm->server->compositor->shell_interface;
if (seat == NULL || seat->pointer->button_count != 1 if (!pointer || pointer->button_count != 1
|| !seat->pointer->focus || !pointer->focus
|| seat->pointer->focus->surface != window->surface) || pointer->focus->surface != window->surface)
return; return;
detail = client_message->data.data32[2]; detail = client_message->data.data32[2];

Loading…
Cancel
Save