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

Reply via email to