[PATCH weston 1/3] Introduce pointer lock interface

Giulio Camuffo giuliocamuffo at gmail.com
Wed Sep 17 12:56:13 PDT 2014


I haven't looked at the implementation yet, just at the protocol, but
isn't _wl_pointer_lock.lock_pointer() returning a new wl_pointer a
problem? Objects should have a unique factory interface, or else the
version of the interface can't be determined.


--
Giulio


2014-09-17 22:39 GMT+03:00 Jonas Ådahl <jadahl at gmail.com>:
> Introduce a pointer lock interface and implementation. The interface
> consists of a global currently called _wl_pointer_lock. It is prefixed
> with an underscore (_) in order to not conflict with a potential
> official protocol in Wayland, and if moving it there, the prefixed
> should be removed.
>
> The protocol works by exposing the global _wl_pointer_lock to the
> client, and when the client wants to lock the pointer, it creates a new
> wl_pointer object using the 'lock_pointer' request. A more detailed
> description of the protocol seen in pointer-lock.xml file.
>
> The interface is based on the W3C pointer lock interface [0].
>
> [0] http://www.w3.org/TR/pointerlock/
>
> Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
> ---
>
> The part of the implementation I'm not very happy with is the internal
> API change: the extra argument in the pointer lock motion callback used
> to determine if the motion event was a result of a relative motion or an
> absolute motion. In this implementation absolute events are simply
> ignored as they don't tend to behave in any sensible way. One could
> generate relative motion events from absolute ones as done from a
> touchpad, but one would need some kind of threshold as there are no
> "touch down" or "touch up" events.
>
> With backends where relative and absolute events are indistinguishable
> (X11, Wayland) is tricker, as there is no way to know whether the event
> is suitable or not. One could also just let the client deal with it
> making "detached" absolute motions just result in very long vectors.
>
>
> Jonas
>
>  Makefile.am               |   7 +-
>  desktop-shell/exposay.c   |   2 +-
>  desktop-shell/shell.c     |  10 +-
>  protocol/pointer-lock.xml |  85 ++++++++++++++
>  src/compositor.c          |   4 +
>  src/compositor.h          |  21 +++-
>  src/input.c               | 277 +++++++++++++++++++++++++++++++++++++++++++++-
>  7 files changed, 394 insertions(+), 12 deletions(-)
>  create mode 100644 protocol/pointer-lock.xml
>
> diff --git a/Makefile.am b/Makefile.am
> index b2d6893..ed74983 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -79,7 +79,9 @@ nodist_weston_SOURCES =                                       \
>         protocol/workspaces-protocol.c                  \
>         protocol/workspaces-server-protocol.h           \
>         protocol/scaler-protocol.c                      \
> -       protocol/scaler-server-protocol.h
> +       protocol/scaler-server-protocol.h               \
> +       protocol/pointer-lock-protocol.c                \
> +       protocol/pointer-lock-server-protocol.h
>
>  BUILT_SOURCES += $(nodist_weston_SOURCES)
>
> @@ -987,7 +989,8 @@ EXTRA_DIST +=                                       \
>         protocol/wayland-test.xml               \
>         protocol/xdg-shell.xml                  \
>         protocol/fullscreen-shell.xml           \
> -       protocol/scaler.xml
> +       protocol/scaler.xml                     \
> +       protocol/pointer-lock.xml
>
>  man_MANS = weston.1 weston.ini.5
>
> diff --git a/desktop-shell/exposay.c b/desktop-shell/exposay.c
> index 4b65cbd..d6ec6a1 100644
> --- a/desktop-shell/exposay.c
> +++ b/desktop-shell/exposay.c
> @@ -340,7 +340,7 @@ exposay_focus(struct weston_pointer_grab *grab)
>
>  static void
>  exposay_motion(struct weston_pointer_grab *grab, uint32_t time,
> -              wl_fixed_t x, wl_fixed_t y)
> +              wl_fixed_t x, wl_fixed_t y, int rel)
>  {
>         struct desktop_shell *shell =
>                 container_of(grab, struct desktop_shell, exposay.grab_ptr);
> diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
> index 3a5a702..35b05d0 100644
> --- a/desktop-shell/shell.c
> +++ b/desktop-shell/shell.c
> @@ -1651,7 +1651,7 @@ constrain_position(struct weston_move_grab *move, int *cx, int *cy)
>
>  static void
>  move_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
> -                wl_fixed_t x, wl_fixed_t y)
> +                wl_fixed_t x, wl_fixed_t y, int rel)
>  {
>         struct weston_move_grab *move = (struct weston_move_grab *) grab;
>         struct weston_pointer *pointer = grab->pointer;
> @@ -1772,7 +1772,7 @@ struct weston_resize_grab {
>
>  static void
>  resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
> -                  wl_fixed_t x, wl_fixed_t y)
> +                  wl_fixed_t x, wl_fixed_t y, int rel)
>  {
>         struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
>         struct weston_pointer *pointer = grab->pointer;
> @@ -1981,7 +1981,7 @@ busy_cursor_grab_focus(struct weston_pointer_grab *base)
>
>  static void
>  busy_cursor_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
> -                       wl_fixed_t x, wl_fixed_t y)
> +                       wl_fixed_t x, wl_fixed_t y, int rel)
>  {
>         weston_pointer_move(grab->pointer, x, y);
>  }
> @@ -3063,7 +3063,7 @@ popup_grab_focus(struct weston_pointer_grab *grab)
>
>  static void
>  popup_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
> -                 wl_fixed_t x, wl_fixed_t y)
> +                 wl_fixed_t x, wl_fixed_t y, int rel)
>  {
>         struct weston_pointer *pointer = grab->pointer;
>         struct wl_resource *resource;
> @@ -4649,7 +4649,7 @@ terminate_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
>
>  static void
>  rotate_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
> -                  wl_fixed_t x, wl_fixed_t y)
> +                  wl_fixed_t x, wl_fixed_t y, int rel)
>  {
>         struct rotate_grab *rotate =
>                 container_of(grab, struct rotate_grab, base.grab);
> diff --git a/protocol/pointer-lock.xml b/protocol/pointer-lock.xml
> new file mode 100644
> index 0000000..e00ff80
> --- /dev/null
> +++ b/protocol/pointer-lock.xml
> @@ -0,0 +1,85 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<protocol name="pointer_lock">
> +
> +  <copyright>
> +    Copyright © 2013      Intel Corporation
> +    Copyright © 2014      Jonas Ådahl
> +
> +    Permission to use, copy, modify, distribute, and sell this
> +    software and its documentation for any purpose is hereby granted
> +    without fee, provided that the above copyright notice appear in
> +    all copies and that both that copyright notice and this permission
> +    notice appear in supporting documentation, and that the name of
> +    the copyright holders not be used in advertising or publicity
> +    pertaining to distribution of the software without specific,
> +    written prior permission.  The copyright holders make no
> +    representations about the suitability of this software for any
> +    purpose.  It is provided "as is" without express or implied
> +    warranty.
> +
> +    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
> +    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
> +    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
> +    SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> +    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
> +    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
> +    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
> +    THIS SOFTWARE.
> +  </copyright>
> +
> +  <interface name="_wl_pointer_lock" version="1">
> +    <description summary="lock pointer to a surface">
> +      This interface enables clients to lock pointers to a surface in order
> +      to only receive relative pointer motion events.
> +    </description>
> +
> +    <request name="lock_pointer">
> +      <description summary="return pointer object">
> +        The lock_pointer request lets the client disable pointer
> +        motion and request relative motion events.
> +
> +        Relative motion events have the same dimension as regular
> +        absolute motion events on a non-transformed surface, meaning that
> +        a relative motion event (dx, dy) is equivalent to the transition
> +        from the absolute coordinate (x y) to (x + dx, y + dy).
> +
> +        If the surface where the pointer is locked is transformed in
> +        any way (for example shown as a preview, rotated, etc), the
> +        motion events of the locked pointer object are sent as if the
> +        surface was not transformed.
> +
> +        This request initializes the pointer lock and activates it in
> +        case the surface is active. If the surface isn't active when
> +        the server receives the request, the compositor will activate
> +        the pointer_lock when the surface is eventually activated. It's
> +        up to the compositor and its shell to decide when a surface is
> +        active.
> +
> +        The lock_pointer request will create a new wl_pointer object.
> +        When the pointer_lock is activated, the original wl_pointer will
> +        send a leave event and the pointer_lock wl_pointer object
> +        will send an enter event. The enter event will contain the
> +        motion delta (0, 0). The wl_pointer object created with this
> +        request will always sends relative motion deltas, in contrast
> +        with a regular wl_pointer which sends surface local absolute
> +        coordinates.
> +
> +        The compositor can suspend the pointer_lock at any time, for
> +        example when switching to a different application (eg,
> +        alt-tab), if a notification pops up or when the screensaver
> +        starts.  When this happens the pointer lock wl_pointer will
> +        send a leave event. When or if the server activates the
> +        surface again, the client will receive an enter event again.
> +
> +        The client can break the pointer lock at any time by releasing
> +        the pointer lock wl_pointer using the wl_pointer.release request.
> +
> +        The interface version of the locked wl_pointer object is the same
> +        as the original wl_pointer object.
> +      </description>
> +      <arg name="id" type="new_id" interface="wl_pointer"/>
> +      <arg name="surface" type="object" interface="wl_surface"/>
> +      <arg name="pointer" type="object" interface="wl_pointer"/>
> +    </request>
> +  </interface>
> +</protocol>
> diff --git a/src/compositor.c b/src/compositor.c
> index a219766..43b4b95 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -3871,6 +3871,8 @@ weston_compositor_init(struct weston_compositor *ec,
>
>         wl_display_init_shm(display);
>
> +       init_pointer_lock(ec);
> +
>         loop = wl_display_get_event_loop(ec->wl_display);
>         ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
>         wl_event_source_timer_update(ec->idle_source, ec->idle_time * 1000);
> @@ -3890,6 +3892,8 @@ weston_compositor_shutdown(struct weston_compositor *ec)
>  {
>         struct weston_output *output, *next;
>
> +       destroy_pointer_lock(ec);
> +
>         wl_event_source_remove(ec->idle_source);
>         if (ec->input_loop_source)
>                 wl_event_source_remove(ec->input_loop_source);
> diff --git a/src/compositor.h b/src/compositor.h
> index 9611dea..e33e341 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -242,7 +242,8 @@ struct weston_pointer_grab;
>  struct weston_pointer_grab_interface {
>         void (*focus)(struct weston_pointer_grab *grab);
>         void (*motion)(struct weston_pointer_grab *grab, uint32_t time,
> -                      wl_fixed_t x, wl_fixed_t y);
> +                      wl_fixed_t x, wl_fixed_t y,
> +                      int is_relative);
>         void (*button)(struct weston_pointer_grab *grab,
>                        uint32_t time, uint32_t button, uint32_t state);
>         void (*cancel)(struct weston_pointer_grab *grab);
> @@ -321,6 +322,7 @@ struct weston_pointer {
>         struct wl_listener focus_resource_listener;
>         struct wl_signal focus_signal;
>         struct wl_signal motion_signal;
> +       struct wl_signal destroy_signal;
>
>         struct weston_view *sprite;
>         struct wl_listener sprite_destroy_listener;
> @@ -663,6 +665,8 @@ struct weston_compositor {
>
>         int32_t kb_repeat_rate;
>         int32_t kb_repeat_delay;
> +
> +       struct wl_global *pointer_lock;
>  };
>
>  struct weston_buffer {
> @@ -899,6 +903,15 @@ struct weston_surface {
>          */
>         struct wl_list subsurface_list; /* weston_subsurface::parent_link */
>         struct wl_list subsurface_list_pending; /* ...::parent_link_pending */
> +
> +       struct {
> +               struct wl_resource *pointer_resource;
> +               struct weston_pointer_grab grab;
> +               struct weston_pointer *pointer;
> +               struct wl_listener pointer_destroy_listener;
> +               struct wl_listener keyboard_focus_listener;
> +               struct wl_listener surface_destroy_listener;
> +       } pointer_lock;
>  };
>
>  struct weston_subsurface {
> @@ -1020,6 +1033,12 @@ void
>  notify_touch_frame(struct weston_seat *seat);
>
>  void
> +init_pointer_lock(struct weston_compositor *compositor);
> +
> +void
> +destroy_pointer_lock(struct weston_compositor *compositor);
> +
> +void
>  weston_layer_entry_insert(struct weston_layer_entry *list,
>                           struct weston_layer_entry *entry);
>  void
> diff --git a/src/input.c b/src/input.c
> index 530904d..ffdec49 100644
> --- a/src/input.c
> +++ b/src/input.c
> @@ -33,6 +33,7 @@
>
>  #include "../shared/os-compatibility.h"
>  #include "compositor.h"
> +#include "protocol/pointer-lock-server-protocol.h"
>
>  static void
>  empty_region(pixman_region32_t *region)
> @@ -163,7 +164,7 @@ default_grab_pointer_focus(struct weston_pointer_grab *grab)
>
>  static void
>  default_grab_pointer_motion(struct weston_pointer_grab *grab, uint32_t time,
> -                           wl_fixed_t x, wl_fixed_t y)
> +                           wl_fixed_t x, wl_fixed_t y, int rel)
>  {
>         struct weston_pointer *pointer = grab->pointer;
>         struct wl_list *resource_list;
> @@ -472,6 +473,7 @@ weston_pointer_create(struct weston_seat *seat)
>         wl_signal_init(&pointer->motion_signal);
>         wl_signal_init(&pointer->focus_signal);
>         wl_list_init(&pointer->focus_view_listener.link);
> +       wl_signal_init(&pointer->destroy_signal);
>
>         pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
>
> @@ -490,6 +492,8 @@ weston_pointer_create(struct weston_seat *seat)
>  WL_EXPORT void
>  weston_pointer_destroy(struct weston_pointer *pointer)
>  {
> +       wl_signal_emit(&pointer->destroy_signal, pointer);
> +
>         if (pointer->sprite)
>                 pointer_unmap_sprite(pointer);
>
> @@ -943,7 +947,8 @@ notify_motion(struct weston_seat *seat,
>         struct weston_pointer *pointer = seat->pointer;
>
>         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, 1);
>  }
>
>  static void
> @@ -990,7 +995,7 @@ notify_motion_absolute(struct weston_seat *seat,
>         struct weston_pointer *pointer = seat->pointer;
>
>         weston_compositor_wake(ec);
> -       pointer->grab->interface->motion(pointer->grab, time, x, y);
> +       pointer->grab->interface->motion(pointer->grab, time, x, y, 0);
>  }
>
>  WL_EXPORT void
> @@ -2309,3 +2314,269 @@ weston_seat_release(struct weston_seat *seat)
>
>         wl_signal_emit(&seat->destroy_signal, seat);
>  }
> +
> +static void
> +pointer_lock_grab_pointer_focus(struct weston_pointer_grab *grab)
> +{
> +}
> +
> +static void
> +pointer_lock_grab_pointer_motion(struct weston_pointer_grab *grab,
> +                                uint32_t time,
> +                                wl_fixed_t x, wl_fixed_t y, int rel)
> +{
> +       struct weston_surface *surface =
> +               container_of(grab, struct weston_surface, pointer_lock.grab);
> +       struct weston_pointer *pointer = surface->pointer_lock.grab.pointer;
> +       wl_fixed_t dx, dy;
> +
> +       /* Ignore motion events from non-relative sources. */
> +       if (!rel)
> +               return;
> +
> +       dx = x - pointer->x;
> +       dy = y - pointer->y;
> +       wl_pointer_send_motion(surface->pointer_lock.pointer_resource,
> +                              time, dx, dy);
> +}
> +
> +static void
> +pointer_lock_grab_pointer_button(struct weston_pointer_grab *grab,
> +                                uint32_t time, uint32_t button, uint32_t state)
> +{
> +       struct weston_surface *surface =
> +               container_of(grab, struct weston_surface, pointer_lock.grab);
> +       struct wl_resource *resource = surface->pointer_lock.pointer_resource;
> +       uint32_t serial;
> +
> +       serial = wl_display_next_serial(surface->compositor->wl_display);
> +       wl_pointer_send_button(resource, serial, time, button, state);
> +}
> +
> +static void
> +pointer_lock_grab_pointer_cancel(struct weston_pointer_grab *grab)
> +{
> +}
> +
> +static const struct weston_pointer_grab_interface
> +                               pointer_lock_grab_interface = {
> +       pointer_lock_grab_pointer_focus,
> +       pointer_lock_grab_pointer_motion,
> +       pointer_lock_grab_pointer_button,
> +       pointer_lock_grab_pointer_cancel,
> +};
> +
> +static void
> +pointer_lock_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)
> +{
> +}
> +
> +static void
> +pointer_lock_pointer_release(struct wl_client *client,
> +                            struct wl_resource *resource)
> +{
> +       wl_resource_destroy(resource);
> +}
> +
> +static const struct wl_pointer_interface pointer_lock_pointer_interface = {
> +       pointer_lock_pointer_set_cursor,
> +       pointer_lock_pointer_release
> +};
> +
> +static void
> +lock_pointer(struct weston_surface *surface, struct weston_pointer *pointer)
> +{
> +       struct weston_compositor *compositor = surface->compositor;
> +       uint32_t serial;
> +
> +       if (surface->pointer_lock.pointer->focus == surface)
> +               return;
> +
> +       weston_pointer_set_focus(pointer, NULL, 0, 0);
> +
> +       serial = wl_display_next_serial(compositor->wl_display);
> +       wl_pointer_send_enter(surface->pointer_lock.pointer_resource,
> +                             serial,
> +                             surface->resource,
> +                             0, 0);
> +
> +       if (pointer->sprite)
> +               pointer_unmap_sprite(pointer);
> +
> +       weston_pointer_start_grab(pointer, &surface->pointer_lock.grab);
> +}
> +
> +static void
> +unlock_pointer(struct weston_surface *surface)
> +{
> +       struct weston_compositor *compositor = surface->compositor;
> +       uint32_t serial;
> +
> +       if (surface->pointer_lock.pointer->focus != surface)
> +               return;
> +
> +       serial = wl_display_next_serial(compositor->wl_display);
> +       wl_pointer_send_leave(surface->pointer_lock.pointer_resource,
> +                             serial, surface->resource);
> +       weston_pointer_end_grab(surface->pointer_lock.grab.pointer);
> +}
> +
> +static void
> +start_pointer_lock(struct weston_surface *surface,
> +                  struct weston_pointer *pointer)
> +{
> +       struct weston_seat *seat = pointer->seat;
> +       struct wl_listener *keyboard_focus_listener =
> +               &surface->pointer_lock.keyboard_focus_listener;
> +
> +       surface->pointer_lock.pointer = pointer;
> +
> +       wl_signal_add(&seat->pointer->destroy_signal,
> +                     &surface->pointer_lock.pointer_destroy_listener);
> +       wl_signal_add(&surface->destroy_signal,
> +                     &surface->pointer_lock.surface_destroy_listener);
> +
> +       if (seat->keyboard) {
> +               wl_signal_add(&seat->keyboard->focus_signal,
> +                             keyboard_focus_listener);
> +       } else {
> +               wl_list_init(&keyboard_focus_listener->link);
> +       }
> +
> +       if (seat->keyboard->focus == surface)
> +               lock_pointer(surface, pointer);
> +}
> +
> +static void
> +end_pointer_lock(struct weston_surface *surface)
> +{
> +       unlock_pointer(surface);
> +       surface->pointer_lock.pointer_resource = NULL;
> +       surface->pointer_lock.pointer = NULL;
> +
> +       wl_list_remove(&surface->pointer_lock.pointer_destroy_listener.link);
> +       wl_list_remove(&surface->pointer_lock.keyboard_focus_listener.link);
> +       wl_list_remove(&surface->pointer_lock.surface_destroy_listener.link);
> +}
> +
> +static void
> +pointer_lock_resource_destroyed(struct wl_resource *resource)
> +{
> +       struct weston_surface *surface = wl_resource_get_user_data(resource);
> +
> +       end_pointer_lock(surface);
> +}
> +
> +static void
> +pointer_lock_keyboard_focused(struct wl_listener *listener, void *data)
> +{
> +       struct weston_keyboard *keyboard = data;
> +       struct weston_surface *surface =
> +               container_of(listener, struct weston_surface,
> +                            pointer_lock.keyboard_focus_listener);
> +       struct weston_pointer *pointer = surface->pointer_lock.pointer;
> +
> +       if (keyboard->focus == surface)
> +               lock_pointer(surface, pointer);
> +       else
> +               unlock_pointer(surface);
> +}
> +
> +static void
> +pointer_lock_pointer_destroyed(struct wl_listener *listener, void *data)
> +{
> +       struct weston_surface *surface =
> +               container_of(listener, struct weston_surface,
> +                            pointer_lock.pointer_destroy_listener);
> +
> +       end_pointer_lock(surface);
> +}
> +
> +static void
> +pointer_lock_surface_destroyed(struct wl_listener *listener, void *data)
> +{
> +       struct weston_surface *surface =
> +               container_of(listener, struct weston_surface,
> +                            pointer_lock.surface_destroy_listener);
> +
> +       end_pointer_lock(surface);
> +}
> +
> +static void
> +pointer_lock_lock_pointer(struct wl_client *client,
> +                         struct wl_resource *resource,
> +                         uint32_t id,
> +                         struct wl_resource *surface_resource,
> +                         struct wl_resource *pointer_resource)
> +{
> +       struct weston_pointer *pointer =
> +               wl_resource_get_user_data(pointer_resource);
> +       struct weston_surface *surface;
> +       struct wl_resource *cr;
> +
> +       surface = wl_resource_get_user_data(surface_resource);
> +       if (surface->pointer_lock.pointer_resource) {
> +               wl_resource_post_error(resource,
> +                                      WL_DISPLAY_ERROR_INVALID_OBJECT,
> +                                      "pointer already locked");
> +               return;
> +       }
> +
> +        cr = wl_resource_create(client, &wl_pointer_interface,
> +                               wl_resource_get_version(pointer_resource), id);
> +       if (cr == NULL) {
> +               wl_client_post_no_memory(client);
> +               return;
> +       }
> +
> +       wl_resource_set_implementation(cr, &pointer_lock_pointer_interface,
> +                                      surface,
> +                                      pointer_lock_resource_destroyed);
> +
> +       surface->pointer_lock.pointer_resource = cr;
> +       surface->pointer_lock.grab.interface = &pointer_lock_grab_interface;
> +       surface->pointer_lock.pointer_destroy_listener.notify =
> +               pointer_lock_pointer_destroyed;
> +       surface->pointer_lock.keyboard_focus_listener.notify =
> +               pointer_lock_keyboard_focused;
> +       surface->pointer_lock.surface_destroy_listener.notify =
> +               pointer_lock_surface_destroyed;
> +
> +       start_pointer_lock(surface, pointer);
> +}
> +
> +static const struct _wl_pointer_lock_interface pointer_lock_interface = {
> +       pointer_lock_lock_pointer
> +};
> +
> +static void
> +bind_pointer_lock(struct wl_client *client, void *data,
> +                 uint32_t version, uint32_t id)
> +{
> +       struct wl_resource *resource;
> +
> +       resource = wl_resource_create(client, &_wl_pointer_lock_interface,
> +                                     1, id);
> +       wl_resource_set_implementation(resource, &pointer_lock_interface,
> +                                      NULL, NULL);
> +}
> +
> +void
> +init_pointer_lock(struct weston_compositor *compositor)
> +{
> +       compositor->pointer_lock =
> +               wl_global_create(compositor->wl_display,
> +                                &_wl_pointer_lock_interface, 1,
> +                                NULL,
> +                                bind_pointer_lock);
> +}
> +
> +void
> +destroy_pointer_lock(struct weston_compositor *compositor)
> +{
> +       wl_global_destroy(compositor->pointer_lock);
> +}
> --
> 1.8.5.1
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list