Le 16/10/2015 11:53, David FORT a écrit : > This patch implements inert objects for wl_keyboard, wl_pointer and wl_touch. > The target case is when the server has just send a capability event about a > disappearing object, and the client binds the corresponding object. We bind an > inert object: an object does nothing when it is requested. If the client > behave > correctly, this object should be released when the capability event is > received > and treated (calling the corresponding release request). > As a consequence, we can rely on seat->[keyboard|pointer|touch]_state to know > if the seat has the corresponding object. > Weston doesn't really handle multiple mice for one wl_pointer, so I have > removed > the corresponding code and tests (it was quite a weston_test hack BTW). > Finally I have fixed a wrong behaviour: the capabilities event's > documentation states > that the capabilities should be sent when a new capability is set on the > seat. So > attaching a second mouse to an existing wl_pointer should not broadcast seat > capabilities (and the same for keyboard and touch). > --- > desktop-shell/exposay.c | 16 ++-- > desktop-shell/shell.c | 21 +++-- > src/compositor-wayland.c | 10 +- > src/compositor-x11.c | 12 ++- > src/compositor.h | 3 - > src/input.c | 235 > ++++++++++++++++++++++++++--------------------- > src/libinput-device.c | 2 +- > src/screen-share.c | 2 + > src/text-backend.c | 44 +++++---- > src/zoom.c | 7 +- > tests/devices-test.c | 20 ---- > tests/weston-test.c | 18 ++-- > xwayland/dnd.c | 3 +- > 13 files changed, 216 insertions(+), 177 deletions(-) > > diff --git a/desktop-shell/exposay.c b/desktop-shell/exposay.c > index 08b86a3..d6919b3 100644 > --- a/desktop-shell/exposay.c > +++ b/desktop-shell/exposay.c > @@ -574,21 +574,23 @@ exposay_transition_active(struct desktop_shell *shell) > bool animate = false; > > shell->exposay.workspace = get_current_workspace(shell); > - shell->exposay.focus_prev = get_default_view(keyboard->focus); > - shell->exposay.focus_current = get_default_view(keyboard->focus); > + if (keyboard) { > + 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, NULL); > shell->exposay.grab_kbd.interface = &exposay_kbd_grab; > - weston_keyboard_start_grab(keyboard, > - &shell->exposay.grab_kbd); > - weston_keyboard_set_focus(keyboard, NULL); > + if (keyboard) { > + weston_keyboard_start_grab(keyboard, &shell->exposay.grab_kbd); > + weston_keyboard_set_focus(keyboard, NULL); > + } > > shell->exposay.grab_ptr.interface = &exposay_ptr_grab; > if (pointer) { > - weston_pointer_start_grab(pointer, > - &shell->exposay.grab_ptr); > + weston_pointer_start_grab(pointer, &shell->exposay.grab_ptr); > weston_pointer_clear_focus(pointer); > } > wl_list_for_each(shell_output, &shell->output_list, link) { > diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c > index 3eb3f5c..cdddf09 100644 > --- a/desktop-shell/shell.c > +++ b/desktop-shell/shell.c > @@ -380,7 +380,8 @@ shell_grab_start(struct shell_grab *grab, > struct desktop_shell *shell = shsurf->shell; > struct weston_touch *touch = weston_seat_get_touch(pointer->seat); > > - popup_grab_end(pointer); > + if (pointer) > + popup_grab_end(pointer); > if (touch) > touch_popup_grab_end(touch); > > @@ -391,11 +392,13 @@ shell_grab_start(struct shell_grab *grab, > &grab->shsurf_destroy_listener); > > shsurf->grabbed = 1; > - weston_pointer_start_grab(pointer, &grab->grab); > + if (pointer) > + weston_pointer_start_grab(pointer, &grab->grab); > if (shell->child.desktop_shell) { > desktop_shell_send_grab_cursor(shell->child.desktop_shell, > cursor); > - weston_pointer_set_focus(pointer, > + if (pointer) > + weston_pointer_set_focus(pointer, > get_default_view(shell->grab_surface), > wl_fixed_from_int(0), > wl_fixed_from_int(0)); > @@ -925,12 +928,10 @@ restore_focus_state(struct desktop_shell *shell, struct > workspace *ws) > wl_list_insert(&shell->compositor->seat_list, > &state->seat->link); > > - if (!keyboard) > - continue; > - > surface = state->keyboard_focus; > > - weston_keyboard_set_focus(keyboard, surface); > + if (keyboard) > + weston_keyboard_set_focus(keyboard, surface); > } > > /* For any remaining seats that we don't have a focus state > @@ -955,6 +956,9 @@ replace_focus_state(struct desktop_shell *shell, struct > workspace *ws, > struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat); > struct focus_state *state; > > + if (!keyboard) > + return; > + > wl_list_for_each(state, &ws->focus_list, link) { > if (state->seat == seat) { > focus_state_set_focus(state, keyboard->focus); > @@ -1483,6 +1487,9 @@ take_surface_to_workspace_by_seat(struct desktop_shell > *shell, > struct workspace *to; > struct focus_state *state; > > + if (!keyboard) > + return; > + > surface = weston_surface_get_main_surface(keyboard->focus); > view = get_default_view(surface); > if (view == NULL || > diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c > index 7b11ae4..2cdf7a5 100644 > --- a/src/compositor-wayland.c > +++ b/src/compositor-wayland.c > @@ -1589,10 +1589,12 @@ input_handle_modifiers(void *data, struct wl_keyboard > *wl_keyboard, > serial_out = wl_display_next_serial(b->compositor->wl_display); > > keyboard = weston_seat_get_keyboard(&input->base); > - xkb_state_update_mask(keyboard->xkb_state.state, > - mods_depressed, mods_latched, > - mods_locked, 0, 0, group); > - notify_modifiers(&input->base, serial_out); > + if (keyboard) { > + xkb_state_update_mask(keyboard->xkb_state.state, > + mods_depressed, mods_latched, > + mods_locked, 0, 0, group); > + notify_modifiers(&input->base, serial_out); > + } > } > > static void > diff --git a/src/compositor-x11.c b/src/compositor-x11.c > index 9a23996..42356e6 100644 > --- a/src/compositor-x11.c > +++ b/src/compositor-x11.c > @@ -189,11 +189,15 @@ x11_backend_get_keymap(struct x11_backend *b) > static uint32_t > get_xkb_mod_mask(struct x11_backend *b, uint32_t in) > { > - struct weston_keyboard *keyboard = > - weston_seat_get_keyboard(&b->core_seat); > - struct weston_xkb_info *info = keyboard->xkb_info; > + struct weston_keyboard *keyboard = > weston_seat_get_keyboard(&b->core_seat); > + struct weston_xkb_info *info; > uint32_t ret = 0; > > + if (!keyboard) > + return 0; > + > + 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) > @@ -1028,6 +1032,8 @@ update_xkb_state_from_core(struct x11_backend *b, > uint16_t x11_mask) > struct weston_keyboard *keyboard > = weston_seat_get_keyboard(&b->core_seat); > > + if (!keyboard) > + return; > xkb_state_update_mask(keyboard->xkb_state.state, > keyboard->modifiers.mods_depressed & mask, > keyboard->modifiers.mods_latched & mask, > diff --git a/src/compositor.h b/src/compositor.h > index 2e2a185..de38514 100644 > --- a/src/compositor.h > +++ b/src/compositor.h > @@ -508,9 +508,6 @@ struct weston_seat { > struct weston_pointer *pointer_state; > struct weston_keyboard *keyboard_state; > struct weston_touch *touch_state; > - int pointer_device_count; > - int keyboard_device_count; > - int touch_device_count; > > struct weston_output *output; /* constraint */ > > diff --git a/src/input.c b/src/input.c > index 500c39a..6cd2650 100644 > --- a/src/input.c > +++ b/src/input.c > @@ -55,10 +55,8 @@ weston_seat_repick(struct weston_seat *seat) > { > const struct weston_pointer *pointer = weston_seat_get_pointer(seat); > > - if (!pointer) > - return; > - > - pointer->grab->interface->focus(pointer->grab); > + if (pointer) > + pointer->grab->interface->focus(pointer->grab); > } > > static void > @@ -618,11 +616,11 @@ seat_send_updated_caps(struct weston_seat *seat) > enum wl_seat_capability caps = 0; > struct wl_resource *resource; > > - if (seat->pointer_device_count > 0) > + if (seat->pointer_state) > caps |= WL_SEAT_CAPABILITY_POINTER; > - if (seat->keyboard_device_count > 0) > + if (seat->keyboard_state) > caps |= WL_SEAT_CAPABILITY_KEYBOARD; > - if (seat->touch_device_count > 0) > + if (seat->touch_state) > caps |= WL_SEAT_CAPABILITY_TOUCH; > > wl_resource_for_each(resource, &seat->base_resource_list) { > @@ -982,7 +980,8 @@ notify_motion(struct weston_seat *seat, > 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); > + if (pointer) > + pointer->grab->interface->motion(pointer->grab, time, > pointer->x + dx, pointer->y + dy); > } > > static void > @@ -1029,7 +1028,8 @@ notify_motion_absolute(struct weston_seat *seat, > struct weston_pointer *pointer = weston_seat_get_pointer(seat); > > weston_compositor_wake(ec); > - pointer->grab->interface->motion(pointer->grab, time, x, y); > + if (pointer) > + pointer->grab->interface->motion(pointer->grab, time, x, y); > } > > WL_EXPORT void > @@ -1054,6 +1054,9 @@ notify_button(struct weston_seat *seat, uint32_t time, > int32_t button, > struct weston_compositor *compositor = seat->compositor; > struct weston_pointer *pointer = weston_seat_get_pointer(seat); > > + if (!pointer) > + return; > + > if (state == WL_POINTER_BUTTON_STATE_PRESSED) { > weston_compositor_idle_inhibit(compositor); > if (pointer->button_count == 0) { > @@ -1092,7 +1095,7 @@ notify_axis(struct weston_seat *seat, uint32_t time, > uint32_t axis, > if (!value) > return; > > - if (weston_compositor_run_axis_binding(compositor, pointer, > + if (!pointer || weston_compositor_run_axis_binding(compositor, pointer, > time, axis, value)) > return; > > @@ -1159,12 +1162,16 @@ WL_EXPORT void > notify_modifiers(struct weston_seat *seat, uint32_t serial) > { > struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat); > - struct weston_keyboard_grab *grab = keyboard->grab; > + struct weston_keyboard_grab *grab; > uint32_t mods_depressed, mods_latched, mods_locked, group; > uint32_t mods_lookup; > enum weston_led leds = 0; > int changed = 0; > > + if (!keyboard) > + return; > + > + grab = keyboard->grab; > /* Serialize and update our internal state, checking to see if it's > * different to the previous state. */ > mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state, > @@ -1233,6 +1240,9 @@ update_modifier_state(struct weston_seat *seat, > uint32_t serial, uint32_t key, > struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat); > enum xkb_key_direction direction; > > + if (!keyboard) > + return; > + > /* Keyboard modifiers don't exist in raw keyboard mode */ > if (!seat->compositor->use_xkbcommon) > return; > @@ -1281,6 +1291,9 @@ update_keymap(struct weston_seat *seat) > xkb_mod_mask_t latched_mods; > xkb_mod_mask_t locked_mods; > > + if (!keyboard) > + return; > + > xkb_info = weston_xkb_info_create(keyboard->pending_keymap); > > xkb_keymap_unref(keyboard->pending_keymap); > @@ -1353,8 +1366,8 @@ 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 = weston_seat_get_keyboard(seat); > - struct weston_keyboard_grab *grab = keyboard->grab; > + struct weston_keyboard *keyboard; > + struct weston_keyboard_grab *grab; > uint32_t *k, *end; > > if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { > @@ -1363,6 +1376,11 @@ notify_key(struct weston_seat *seat, uint32_t time, > uint32_t key, > weston_compositor_idle_release(compositor); > } > > + keyboard = weston_seat_get_keyboard(seat); > + if (!keyboard) > + return; > + grab = keyboard->grab; > + > end = keyboard->keys.data + keyboard->keys.size; > for (k = keyboard->keys.data; k < end; k++) { > if (*k == key) { > @@ -1412,7 +1430,7 @@ notify_pointer_focus(struct weston_seat *seat, struct > weston_output *output, > { > struct weston_pointer *pointer = weston_seat_get_pointer(seat); > > - if (output) { > + if (output && pointer) { > weston_pointer_move(pointer, x, y); > } else { > /* FIXME: We should call weston_pointer_set_focus(seat, > @@ -1440,6 +1458,9 @@ notify_keyboard_focus_in(struct weston_seat *seat, > struct wl_array *keys, > struct weston_surface *surface; > uint32_t *k, serial; > > + if (!keyboard) > + return; > + > serial = wl_display_next_serial(compositor->wl_display); > wl_array_copy(&keyboard->keys, keys); > wl_array_for_each(k, &keyboard->keys) { > @@ -1466,25 +1487,30 @@ notify_keyboard_focus_out(struct weston_seat *seat) > struct weston_pointer *pointer = weston_seat_get_pointer(seat); > uint32_t *k, serial; > > - serial = wl_display_next_serial(compositor->wl_display); > - wl_array_for_each(k, &keyboard->keys) { > - weston_compositor_idle_release(compositor); > - update_modifier_state(seat, serial, *k, > - WL_KEYBOARD_KEY_STATE_RELEASED); > + if (keyboard) { > + serial = wl_display_next_serial(compositor->wl_display); > + wl_array_for_each(k, &keyboard->keys) { > + weston_compositor_idle_release(compositor); > + update_modifier_state(seat, serial, *k, > + > WL_KEYBOARD_KEY_STATE_RELEASED); > + } > } > > seat->modifier_state = 0; > > - if (keyboard->focus) { > - seat->saved_kbd_focus = keyboard->focus; > - seat->saved_kbd_focus_listener.notify = > - destroy_device_saved_kbd_focus; > - wl_signal_add(&keyboard->focus->destroy_signal, > - &seat->saved_kbd_focus_listener); > + if (keyboard) { > + if (keyboard->focus) { > + seat->saved_kbd_focus = keyboard->focus; > + seat->saved_kbd_focus_listener.notify = > + destroy_device_saved_kbd_focus; > + wl_signal_add(&keyboard->focus->destroy_signal, > + &seat->saved_kbd_focus_listener); > + } > + > + weston_keyboard_set_focus(keyboard, NULL); > + weston_keyboard_cancel_grab(keyboard); > } > > - weston_keyboard_set_focus(keyboard, NULL); > - weston_keyboard_cancel_grab(keyboard); > if (pointer) > weston_pointer_cancel_grab(pointer); > } > @@ -1545,10 +1571,15 @@ notify_touch(struct weston_seat *seat, uint32_t time, > int touch_id, > { > struct weston_compositor *ec = seat->compositor; > struct weston_touch *touch = weston_seat_get_touch(seat); > - struct weston_touch_grab *grab = touch->grab; > + struct weston_touch_grab *grab; > struct weston_view *ev; > wl_fixed_t sx, sy; > > + if (!touch) > + return; > + > + grab = touch->grab; > + > /* Update grab's global coordinates. */ > if (touch_id == touch->grab_touch_id && touch_type != WL_TOUCH_UP) { > touch->grab_x = x; > @@ -1620,9 +1651,12 @@ WL_EXPORT void > notify_touch_frame(struct weston_seat *seat) > { > struct weston_touch *touch = weston_seat_get_touch(seat); > - struct weston_touch_grab *grab = touch->grab; > + struct weston_touch_grab *grab; > > - grab->interface->frame(grab); > + if (touch) { > + grab = touch->grab; > + grab->interface->frame(grab); > + } > } > > static int > @@ -1735,34 +1769,46 @@ static const struct wl_pointer_interface > pointer_interface = { > }; > > static void > +inert_pointer_set_cursor(struct wl_client *client, struct wl_resource > *resource, > + uint32_t serial, struct wl_resource *surface_resource, > + int32_t x, int32_t y) > +{ > + /* in the "normal" pointer_set_cursor, we're setting a surface role only > + * if we have pointer focus. An inert pointer doesn't really have a > focus so > + * we don't do anything on the surface */ > +} > + > +static const struct wl_pointer_interface inert_pointer_interface = { > + inert_pointer_set_cursor, > + pointer_release > +}; > + > +static void > seat_get_pointer(struct wl_client *client, struct wl_resource *resource, > uint32_t id) > { > struct weston_seat *seat = wl_resource_get_user_data(resource); > - /* We use the pointer_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; > > - if (!pointer) > - return; > - > - cr = wl_resource_create(client, &wl_pointer_interface, > - wl_resource_get_version(resource), id); > + cr = wl_resource_create(client, &wl_pointer_interface, > + wl_resource_get_version(resource), id); > if (cr == NULL) { > wl_client_post_no_memory(client); > return; > } > > + if (!pointer) { > + /*weston_log("binding inert pointer for seat %p\n", seat);*/ > + wl_resource_set_implementation(cr, &inert_pointer_interface, > NULL, > + NULL); > + return; > + } > + > /* May be moved to focused list later by either > * weston_pointer_set_focus or directly if this client is already > * focused */ > + > wl_list_insert(&pointer->resource_list, wl_resource_get_link(cr)); > wl_resource_set_implementation(cr, &pointer_interface, pointer, > unbind_resource); > @@ -1796,6 +1842,10 @@ static const struct wl_keyboard_interface > keyboard_interface = { > keyboard_release > }; > > +static const struct wl_keyboard_interface inert_keyboard_interface = { > + keyboard_release > +}; > + > static bool > should_send_modifiers_to_client(struct weston_seat *seat, > struct wl_client *client) > @@ -1823,27 +1873,23 @@ seat_get_keyboard(struct wl_client *client, struct > wl_resource *resource, > uint32_t id) > { > struct weston_seat *seat = wl_resource_get_user_data(resource); > - /* 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; > > - if (!keyboard) > - return; > - > - cr = wl_resource_create(client, &wl_keyboard_interface, > - wl_resource_get_version(resource), id); > + cr = wl_resource_create(client, &wl_keyboard_interface, > + wl_resource_get_version(resource), id); > if (cr == NULL) { > wl_client_post_no_memory(client); > return; > } > > + if (!keyboard) { > + /*weston_log("binding inert keyboard for seat %p\n", seat);*/ > + wl_resource_set_implementation(cr, &inert_keyboard_interface, > NULL, > + NULL); > + return; > + } > + > /* May be moved to focused list later by either > * weston_keyboard_set_focus or directly if this client is already > * focused */ > @@ -1906,32 +1952,32 @@ static const struct wl_touch_interface > touch_interface = { > touch_release > }; > > +static const struct wl_touch_interface inert_touch_interface = { > + touch_release > +}; > + > static void > seat_get_touch(struct wl_client *client, struct wl_resource *resource, > uint32_t id) > { > struct weston_seat *seat = wl_resource_get_user_data(resource); > - /* We use the touch_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; > > - if (!touch) > - return; > - > - cr = wl_resource_create(client, &wl_touch_interface, > - wl_resource_get_version(resource), id); > + cr = wl_resource_create(client, &wl_touch_interface, > + wl_resource_get_version(resource), id); > if (cr == NULL) { > wl_client_post_no_memory(client); > return; > } > > + if (!touch) { > + /*weston_log("binding inert touch for seat %p\n", seat);*/ > + wl_resource_set_implementation(cr, &inert_touch_interface, > NULL, NULL); > + return; > + } > + > + > if (touch->focus && > wl_resource_get_client(touch->focus->surface->resource) == client) { > wl_list_insert(&touch->focus_resource_list, > @@ -2180,9 +2226,7 @@ weston_seat_init_keyboard(struct weston_seat *seat, > struct xkb_keymap *keymap) > struct weston_keyboard *keyboard; > > if (seat->keyboard_state) { > - seat->keyboard_device_count += 1; > - if (seat->keyboard_device_count == 1) > - seat_send_updated_caps(seat); > + weston_log("seat %p already has a keyboard device\n", seat); > return 0; > } > > @@ -2216,7 +2260,6 @@ weston_seat_init_keyboard(struct weston_seat *seat, > struct xkb_keymap *keymap) > #endif > > seat->keyboard_state = keyboard; > - seat->keyboard_device_count = 1; > keyboard->seat = seat; > > seat_send_updated_caps(seat); > @@ -2257,12 +2300,12 @@ weston_keyboard_reset_state(struct weston_keyboard > *keyboard) > WL_EXPORT void > weston_seat_release_keyboard(struct weston_seat *seat) > { > - seat->keyboard_device_count--; > - assert(seat->keyboard_device_count >= 0); > - if (seat->keyboard_device_count == 0) { > + if (seat->keyboard_state) { > weston_keyboard_set_focus(seat->keyboard_state, NULL); > weston_keyboard_cancel_grab(seat->keyboard_state); > weston_keyboard_reset_state(seat->keyboard_state); > + seat->keyboard_state = NULL; > + > seat_send_updated_caps(seat); > } > } > @@ -2273,9 +2316,7 @@ weston_seat_init_pointer(struct weston_seat *seat) > struct weston_pointer *pointer; > > if (seat->pointer_state) { > - seat->pointer_device_count += 1; > - if (seat->pointer_device_count == 1) > - seat_send_updated_caps(seat); > + weston_log("seat %p already has a pointer device\n", seat); > return; > } > > @@ -2284,7 +2325,6 @@ weston_seat_init_pointer(struct weston_seat *seat) > return; > > seat->pointer_state = pointer; > - seat->pointer_device_count = 1; > pointer->seat = seat; > > seat_send_updated_caps(seat); > @@ -2295,8 +2335,7 @@ weston_seat_release_pointer(struct weston_seat *seat) > { > struct weston_pointer *pointer = seat->pointer_state; > > - seat->pointer_device_count--; > - if (seat->pointer_device_count == 0) { > + if (seat->pointer_state) { > weston_pointer_clear_focus(pointer); > weston_pointer_cancel_grab(pointer); > > @@ -2304,12 +2343,9 @@ weston_seat_release_pointer(struct weston_seat *seat) > pointer_unmap_sprite(pointer); > > weston_pointer_reset_state(pointer); > - seat_send_updated_caps(seat); > + seat->pointer_state = NULL; > > - /* seat->pointer is intentionally not destroyed so that > - * a newly attached pointer on this seat will retain > - * the previous cursor co-ordinates. > - */ > + seat_send_updated_caps(seat); > } > } > > @@ -2319,9 +2355,7 @@ weston_seat_init_touch(struct weston_seat *seat) > struct weston_touch *touch; > > if (seat->touch_state) { > - seat->touch_device_count += 1; > - if (seat->touch_device_count == 1) > - seat_send_updated_caps(seat); > + weston_log("seat %p already has a touch device\n", seat); > return; > } > > @@ -2330,7 +2364,6 @@ weston_seat_init_touch(struct weston_seat *seat) > return; > > seat->touch_state = touch; > - seat->touch_device_count = 1; > touch->seat = seat; > > seat_send_updated_caps(seat); > @@ -2339,11 +2372,12 @@ weston_seat_init_touch(struct weston_seat *seat) > WL_EXPORT void > weston_seat_release_touch(struct weston_seat *seat) > { > - seat->touch_device_count--; > - if (seat->touch_device_count == 0) { > + if (seat->touch_state) { > weston_touch_set_focus(seat->touch_state, NULL); > weston_touch_cancel_grab(seat->touch_state); > weston_touch_reset_state(seat->touch_state); > + seat->touch_state = NULL; > + > seat_send_updated_caps(seat); > } > } > @@ -2413,10 +2447,7 @@ weston_seat_get_keyboard(struct weston_seat *seat) > if (!seat) > return NULL; > > - if (seat->keyboard_device_count) > - return seat->keyboard_state; > - > - return NULL; > + return seat->keyboard_state; > } > > /** Get a seat's pointer pointer > @@ -2435,10 +2466,7 @@ weston_seat_get_pointer(struct weston_seat *seat) > if (!seat) > return NULL; > > - if (seat->pointer_device_count) > - return seat->pointer_state; > - > - return NULL; > + return seat->pointer_state; > } > > /** Get a seat's touch pointer > @@ -2457,8 +2485,5 @@ weston_seat_get_touch(struct weston_seat *seat) > if (!seat) > return NULL; > > - if (seat->touch_device_count) > - return seat->touch_state; > - > - return NULL; > + return seat->touch_state; > } > diff --git a/src/libinput-device.c b/src/libinput-device.c > index 2cbfb88..ddd8e2c 100644 > --- a/src/libinput-device.c > +++ b/src/libinput-device.c > @@ -547,7 +547,7 @@ evdev_notify_keyboard_focus(struct weston_seat *seat, > { > struct wl_array keys; > > - if (seat->keyboard_device_count == 0) > + if (!seat->keyboard_state) > return; > > wl_array_init(&keys); > diff --git a/src/screen-share.c b/src/screen-share.c > index d961c89..e20aede 100644 > --- a/src/screen-share.c > +++ b/src/screen-share.c > @@ -283,6 +283,8 @@ ss_seat_handle_modifiers(void *data, struct wl_keyboard > *wl_keyboard, > serial_out = wl_display_next_serial(c->wl_display); > > keyboard = weston_seat_get_keyboard(&seat->base); > + if (!keyboard) > + return; > xkb_state_update_mask(keyboard->xkb_state.state, > mods_depressed, mods_latched, > mods_locked, 0, 0, group); > diff --git a/src/text-backend.c b/src/text-backend.c > index 8c9e30d..f3f30dc 100644 > --- a/src/text-backend.c > +++ b/src/text-backend.c > @@ -664,15 +664,17 @@ input_method_context_grab_keyboard(struct wl_client > *client, > > context->keyboard = cr; > > - wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, > - keyboard->xkb_info->keymap_fd, > - keyboard->xkb_info->keymap_size); > - > - if (keyboard->grab != &keyboard->default_grab) { > - weston_keyboard_end_grab(keyboard); > + if (keyboard) { > + wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, > + keyboard->xkb_info->keymap_fd, > + keyboard->xkb_info->keymap_size); > + > + if (keyboard->grab != &keyboard->default_grab) { > + weston_keyboard_end_grab(keyboard); > + } > + weston_keyboard_start_grab(keyboard, > &keyboard->input_method_grab); > + keyboard->input_method_resource = cr; > } > - weston_keyboard_start_grab(keyboard, &keyboard->input_method_grab); > - keyboard->input_method_resource = cr; > } > > static void > @@ -686,10 +688,14 @@ 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 = weston_seat_get_keyboard(seat); > - struct weston_keyboard_grab *default_grab = &keyboard->default_grab; > + struct weston_keyboard *keyboard; > + struct weston_keyboard_grab *default_grab; > > - default_grab->interface->key(default_grab, time, key, state_w); > + keyboard = weston_seat_get_keyboard(seat); > + if (keyboard) { > + default_grab = &keyboard->default_grab; > + default_grab->interface->key(default_grab, time, key, state_w); > + } > } > > static void > @@ -705,13 +711,17 @@ input_method_context_modifiers(struct wl_client *client, > wl_resource_get_user_data(resource); > > struct weston_seat *seat = context->input_method->seat; > - struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat); > - struct weston_keyboard_grab *default_grab = &keyboard->default_grab; > + struct weston_keyboard *keyboard; > + struct weston_keyboard_grab *default_grab; > > - default_grab->interface->modifiers(default_grab, > - serial, mods_depressed, > - mods_latched, mods_locked, > - group); > + keyboard = weston_seat_get_keyboard(seat); > + if (keyboard) { > + default_grab = &keyboard->default_grab; > + default_grab->interface->modifiers(default_grab, > + serial, mods_depressed, > + mods_latched, mods_locked, > + group); > + } > } > > static void > diff --git a/src/zoom.c b/src/zoom.c > index 08c0693..8658f08 100644 > --- a/src/zoom.c > +++ b/src/zoom.c > @@ -124,6 +124,8 @@ weston_output_update_zoom(struct weston_output *output) > struct weston_pointer *pointer = weston_seat_get_pointer(seat); > > assert(output->zoom.active); > + if (!pointer) > + return; > > output->zoom.current.x = wl_fixed_to_double(pointer->x); > output->zoom.current.y = wl_fixed_to_double(pointer->y); > @@ -155,8 +157,9 @@ weston_output_activate_zoom(struct weston_output *output, > output->zoom.active = true; > output->zoom.seat = seat; > output->disable_planes++; > - wl_signal_add(&pointer->motion_signal, > - &output->zoom.motion_listener); > + if (pointer) > + wl_signal_add(&pointer->motion_signal, > + &output->zoom.motion_listener); > } > > WL_EXPORT void > diff --git a/tests/devices-test.c b/tests/devices-test.c > index 8f9feec..8851c17 100644 > --- a/tests/devices-test.c > +++ b/tests/devices-test.c > @@ -74,26 +74,6 @@ TEST(seat_capabilities_test) > assert(cl->input->pointer); > assert(cl->input->keyboard); > assert(cl->input->touch); > - > - /* add extra devices */ > - weston_test_device_add(cl->test->weston_test, "keyboard"); > - weston_test_device_add(cl->test->weston_test, "pointer"); > - weston_test_device_add(cl->test->weston_test, "touch"); > - client_roundtrip(cl); > - > - /* remove extra devices */ > - weston_test_device_release(cl->test->weston_test, "keyboard"); > - weston_test_device_release(cl->test->weston_test, "pointer"); > - weston_test_device_release(cl->test->weston_test, "touch"); > - client_roundtrip(cl); > - > - /* we still should have all the capabilities, since the devices > - * were doubled */ > - assert(cl->input->caps == WL_SEAT_CAPABILITY_ALL); > - > - assert(cl->input->pointer); > - assert(cl->input->keyboard); > - assert(cl->input->touch); > } > > #define COUNT 15 > diff --git a/tests/weston-test.c b/tests/weston-test.c > index b593f1e..28aefad 100644 > --- a/tests/weston-test.c > +++ b/tests/weston-test.c > @@ -85,7 +85,8 @@ notify_pointer_position(struct weston_test *test, struct > wl_resource *resource) > struct weston_seat *seat = get_seat(test); > struct weston_pointer *pointer = weston_seat_get_pointer(seat); > > - weston_test_send_pointer_position(resource, pointer->x, pointer->y); > + if (pointer) > + weston_test_send_pointer_position(resource, pointer->x, > pointer->y); > } > > static void > @@ -146,9 +147,10 @@ move_pointer(struct wl_client *client, struct > wl_resource *resource, > struct weston_seat *seat = get_seat(test); > struct weston_pointer *pointer = weston_seat_get_pointer(seat); > > - notify_motion(seat, 100, > - wl_fixed_from_int(x) - pointer->x, > - wl_fixed_from_int(y) - pointer->y); > + if (pointer) > + notify_motion(seat, 100, > + wl_fixed_from_int(x) - pointer->x, > + wl_fixed_from_int(y) - pointer->y); > > notify_pointer_position(test, resource); > } > @@ -177,11 +179,13 @@ activate_surface(struct wl_client *client, struct > wl_resource *resource, > keyboard = weston_seat_get_keyboard(seat); > if (surface) { > weston_surface_activate(surface, seat); > - notify_keyboard_focus_in(seat, &keyboard->keys, > - STATE_UPDATE_AUTOMATIC); > + if (keyboard) > + notify_keyboard_focus_in(seat, &keyboard->keys, > + STATE_UPDATE_AUTOMATIC); > } > else { > - notify_keyboard_focus_out(seat); > + if (keyboard) > + notify_keyboard_focus_out(seat); > weston_surface_activate(surface, seat); > } > } > diff --git a/xwayland/dnd.c b/xwayland/dnd.c > index a036b30..94a9563 100644 > --- a/xwayland/dnd.c > +++ b/xwayland/dnd.c > @@ -214,7 +214,8 @@ handle_enter(struct weston_wm *wm, > xcb_client_message_event_t *client_message) > } > > free(reply); > - weston_pointer_start_drag(pointer, &source->base, NULL, NULL); > + if (pointer) > + weston_pointer_start_drag(pointer, &source->base, NULL, NULL); > } > > int >
Note: it's a first step, so that next we can treat seat removal correctly. -- David FORT website: http://www.hardening-consulting.com/ _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel