Signed-off-by: Jonas Ådahl <jad...@gmail.com>
Reviewed-by: Bryce Harrington <br...@osg.samsung.com>
---

Changes since v3:

Uses the XML file from wayland-protocols.

Updated implementation given interface renaming.

Updated implementation given protocol changes (see protocol patch).


 Makefile.am      |   6 +-
 clients/window.c | 326 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 clients/window.h |  62 +++++++++++
 3 files changed, 393 insertions(+), 1 deletion(-)

diff --git a/Makefile.am b/Makefile.am
index a640d74..42e91cb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -559,7 +559,11 @@ nodist_libtoytoolkit_la_SOURCES =                  \
        protocol/xdg-shell-unstable-v5-protocol.c                       \
        protocol/xdg-shell-unstable-v5-client-protocol.h                \
        protocol/ivi-application-protocol.c             \
-       protocol/ivi-application-client-protocol.h
+       protocol/ivi-application-client-protocol.h      \
+       protocol/pointer-constraints-unstable-v1-protocol.c             \
+       protocol/pointer-constraints-unstable-v1-client-protocol.h      \
+       protocol/relative-pointer-unstable-v1-protocol.c                \
+       protocol/relative-pointer-unstable-v1-client-protocol.h
 
 BUILT_SOURCES += $(nodist_libtoytoolkit_la_SOURCES)
 
diff --git a/clients/window.c b/clients/window.c
index f9797a2..6f5ca85 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -24,6 +24,7 @@
 
 #include "config.h"
 
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -70,6 +71,8 @@ typedef void *EGLContext;
 #include "shared/helpers.h"
 #include "xdg-shell-unstable-v5-client-protocol.h"
 #include "text-cursor-position-client-protocol.h"
+#include "pointer-constraints-unstable-v1-client-protocol.h"
+#include "relative-pointer-unstable-v1-client-protocol.h"
 #include "shared/os-compatibility.h"
 
 #include "window.h"
@@ -78,6 +81,9 @@ typedef void *EGLContext;
 #include "ivi-application-client-protocol.h"
 #define IVI_SURFACE_ID 9000
 
+#define ZWP_RELATIVE_POINTER_MANAGER_V1_VERSION 1
+#define ZWP_POINTER_CONSTRAINTS_V1_VERSION 1
+
 struct shm_pool;
 
 struct global {
@@ -97,6 +103,8 @@ struct display {
        struct text_cursor_position *text_cursor_position;
        struct xdg_shell *xdg_shell;
        struct ivi_application *ivi_application; /* ivi style shell */
+       struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
+       struct zwp_pointer_constraints_v1 *pointer_constraints;
        EGLDisplay dpy;
        EGLConfig argb_config;
        EGLContext argb_ctx;
@@ -245,6 +253,8 @@ struct window {
        window_output_handler_t output_handler;
        window_state_changed_handler_t state_changed_handler;
 
+       window_locked_pointer_motion_handler_t locked_pointer_motion_handler;
+
        struct surface *main_surface;
        struct xdg_surface *xdg_surface;
        struct xdg_popup *xdg_popup;
@@ -259,6 +269,19 @@ struct window {
        /* struct surface::link, contains also main_surface */
        struct wl_list subsurface_list;
 
+       struct zwp_relative_pointer_v1 *relative_pointer;
+       struct zwp_locked_pointer_v1 *locked_pointer;
+       struct input *locked_input;
+       bool pointer_locked;
+       locked_pointer_locked_handler_t pointer_locked_handler;
+       locked_pointer_unlocked_handler_t pointer_unlocked_handler;
+       confined_pointer_confined_handler_t pointer_confined_handler;
+       confined_pointer_unconfined_handler_t pointer_unconfined_handler;
+
+       struct zwp_confined_pointer_v1 *confined_pointer;
+       struct widget *confined_widget;
+       bool confined;
+
        void *user_data;
        struct wl_list link;
 };
@@ -3911,6 +3934,22 @@ window_do_resize(struct window *window)
 
        if (!window->fullscreen && !window->maximized)
                window->saved_allocation = window->pending_allocation;
+
+       if (window->confined && window->confined_widget) {
+               struct wl_compositor *compositor = window->display->compositor;
+               struct wl_region *region;
+               struct widget *widget = window->confined_widget;
+
+               region = wl_compositor_create_region(compositor);
+               wl_region_add(region,
+                             widget->allocation.x,
+                             widget->allocation.y,
+                             widget->allocation.width,
+                             widget->allocation.height);
+               zwp_confined_pointer_v1_set_region(window->confined_pointer,
+                                                  region);
+               wl_region_destroy(region);
+       }
 }
 
 static void
@@ -4440,6 +4479,43 @@ window_set_state_changed_handler(struct window *window,
 }
 
 void
+window_set_pointer_locked_handler(struct window *window,
+                                 locked_pointer_locked_handler_t locked)
+{
+       window->pointer_locked_handler = locked;
+}
+
+void
+window_set_pointer_unlocked_handler(struct window *window,
+                                   locked_pointer_unlocked_handler_t unlocked)
+{
+       window->pointer_unlocked_handler = unlocked;
+}
+
+void
+window_set_pointer_confined_handler(
+       struct window *window, confined_pointer_confined_handler_t confined)
+{
+       window->pointer_confined_handler = confined;
+}
+
+void
+window_set_pointer_unconfined_handler(
+       struct window *window,
+       confined_pointer_unconfined_handler_t unconfined)
+{
+       window->pointer_unconfined_handler = unconfined;
+}
+
+void
+window_set_locked_pointer_motion_handler(
+       struct window *window,
+       window_locked_pointer_motion_handler_t handler)
+{
+       window->locked_pointer_motion_handler = handler;
+}
+
+void
 window_set_title(struct window *window, const char *title)
 {
        free(window->title);
@@ -4481,6 +4557,244 @@ window_damage(struct window *window, int32_t x, int32_t 
y,
 }
 
 static void
+relative_pointer_handle_motion(void *data, struct zwp_relative_pointer_v1 
*pointer,
+                              uint32_t utime_most,
+                              uint32_t utime_least,
+                              wl_fixed_t dx,
+                              wl_fixed_t dy,
+                              wl_fixed_t dx_unaccel,
+                              wl_fixed_t dy_unaccel)
+{
+       struct input *input = data;
+       struct window *window = input->pointer_focus;
+       uint32_t time = (((uint64_t) utime_most) << 32 | utime_least) / 1000;
+
+       if (window->locked_pointer_motion_handler &&
+           window->pointer_locked) {
+               window->locked_pointer_motion_handler(
+                       window, input, time,
+                       wl_fixed_to_double(dx),
+                       wl_fixed_to_double(dy),
+                       window->user_data);
+       }
+}
+
+static const struct zwp_relative_pointer_v1_listener relative_pointer_listener 
= {
+       relative_pointer_handle_motion,
+};
+
+static void
+locked_pointer_locked(void *data,
+                     struct zwp_locked_pointer_v1 *locked_pointer)
+{
+       struct input *input = data;
+       struct window *window = input->pointer_focus;
+
+       window->pointer_locked = true;
+
+       if (window->pointer_locked_handler) {
+               window->pointer_locked_handler(window,
+                                              input,
+                                              window->user_data);
+       }
+}
+
+static void
+locked_pointer_unlocked(void *data,
+                       struct zwp_locked_pointer_v1 *locked_pointer)
+{
+       struct input *input = data;
+       struct window *window = input->pointer_focus;
+
+       window_unlock_pointer(window);
+
+       if (window->pointer_unlocked_handler) {
+               window->pointer_unlocked_handler(window,
+                                                input,
+                                                window->user_data);
+       }
+}
+
+static const struct zwp_locked_pointer_v1_listener locked_pointer_listener = {
+       locked_pointer_locked,
+       locked_pointer_unlocked,
+};
+
+int
+window_lock_pointer(struct window *window, struct input *input)
+{
+       struct zwp_relative_pointer_manager_v1 *relative_pointer_manager =
+               window->display->relative_pointer_manager;
+       struct zwp_pointer_constraints_v1 *pointer_constraints =
+               window->display->pointer_constraints;
+       struct zwp_relative_pointer_v1 *relative_pointer;
+       struct zwp_locked_pointer_v1 *locked_pointer;
+
+       if (!window->display->relative_pointer_manager)
+               return -1;
+
+       if (!window->display->pointer_constraints)
+               return -1;
+
+       if (window->locked_pointer)
+               return -1;
+
+       if (window->confined_pointer)
+               return -1;
+
+       if (!input->pointer)
+               return -1;
+
+       relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(
+               relative_pointer_manager, input->pointer);
+       zwp_relative_pointer_v1_add_listener(relative_pointer,
+                                            &relative_pointer_listener,
+                                            input);
+
+       locked_pointer =
+               zwp_pointer_constraints_v1_lock_pointer(pointer_constraints,
+                                                     
window->main_surface->surface,
+                                                     input->seat,
+                                                     NULL);
+       zwp_locked_pointer_v1_add_listener(locked_pointer,
+                                          &locked_pointer_listener,
+                                          input);
+
+       window->locked_input = input;
+       window->locked_pointer = locked_pointer;
+       window->relative_pointer = relative_pointer;
+
+       return 0;
+}
+
+void
+window_unlock_pointer(struct window *window)
+{
+       if (!window->locked_pointer)
+               return;
+
+       zwp_locked_pointer_v1_destroy(window->locked_pointer);
+       zwp_relative_pointer_v1_destroy(window->relative_pointer);
+       window->locked_pointer = NULL;
+       window->relative_pointer = NULL;
+       window->pointer_locked = false;
+       window->locked_input = NULL;
+}
+
+void
+widget_set_locked_pointer_cursor_hint(struct widget *widget,
+                                     float x, float y)
+{
+       struct window *window = widget->window;
+
+       if (!window->locked_pointer)
+               return;
+
+       zwp_locked_pointer_v1_set_cursor_position_hint(window->locked_pointer,
+                                                      wl_fixed_from_double(x),
+                                                      wl_fixed_from_double(y));
+       wl_surface_commit(window->main_surface->surface);
+}
+
+static void
+confined_pointer_confined(void *data,
+                         struct zwp_confined_pointer_v1 *confined_pointer)
+{
+       struct input *input = data;
+       struct window *window = input->pointer_focus;
+
+       if (window->pointer_confined_handler) {
+               window->pointer_confined_handler(window,
+                                                input,
+                                                window->user_data);
+       }
+       window->confined = true;
+}
+
+static void
+confined_pointer_unconfined(void *data,
+                           struct zwp_confined_pointer_v1 *confined_pointer)
+{
+       struct input *input = data;
+       struct window *window = input->pointer_focus;
+
+       window_unconfine_pointer(window);
+
+       if (window->pointer_unconfined_handler) {
+               window->pointer_unconfined_handler(window,
+                                                  input,
+                                                  window->user_data);
+       }
+       window->confined = false;
+}
+
+static const struct zwp_confined_pointer_v1_listener confined_pointer_listener 
= {
+       confined_pointer_confined,
+       confined_pointer_unconfined,
+};
+
+int
+window_confine_pointer_to_widget(struct window *window,
+                                struct widget *widget,
+                                struct input *input)
+{
+       struct zwp_pointer_constraints_v1 *pointer_constraints =
+               window->display->pointer_constraints;
+       struct zwp_confined_pointer_v1 *confined_pointer;
+       struct wl_compositor *compositor = window->display->compositor;
+       struct wl_region *region = NULL;
+
+       if (!window->display->pointer_constraints)
+               return -1;
+
+       if (window->locked_pointer)
+               return -1;
+
+       if (window->confined_pointer)
+               return -1;
+
+       if (!input->pointer)
+               return -1;
+
+       if (widget) {
+               region = wl_compositor_create_region(compositor);
+               wl_region_add(region,
+                             widget->allocation.x,
+                             widget->allocation.y,
+                             widget->allocation.width,
+                             widget->allocation.height);
+       }
+
+       confined_pointer =
+               zwp_pointer_constraints_v1_confine_pointer(pointer_constraints,
+                                                          
window->main_surface->surface,
+                                                          input->seat,
+                                                          region);
+       if (region)
+               wl_region_destroy(region);
+
+       zwp_confined_pointer_v1_add_listener(confined_pointer,
+                                            &confined_pointer_listener,
+                                            input);
+
+       window->confined_pointer = confined_pointer;
+       window->confined_widget = widget;
+
+       return 0;
+}
+
+void
+window_unconfine_pointer(struct window *window)
+{
+       if (!window->confined_pointer)
+               return;
+
+       zwp_confined_pointer_v1_destroy(window->confined_pointer);
+       window->confined_pointer = NULL;
+       window->confined = false;
+}
+
+static void
 surface_enter(void *data,
              struct wl_surface *wl_surface, struct wl_output *wl_output)
 {
@@ -5321,6 +5635,18 @@ registry_handle_global(void *data, struct wl_registry 
*registry, uint32_t id,
                display_add_output(d, id);
        } else if (strcmp(interface, "wl_seat") == 0) {
                display_add_input(d, id, version);
+       } else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0 &&
+                  version == ZWP_RELATIVE_POINTER_MANAGER_V1_VERSION) {
+               d->relative_pointer_manager =
+                       wl_registry_bind(registry, id,
+                                        
&zwp_relative_pointer_manager_v1_interface,
+                                        1);
+       } else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0 &&
+                  version == ZWP_POINTER_CONSTRAINTS_V1_VERSION)  {
+               d->pointer_constraints =
+                       wl_registry_bind(registry, id,
+                                        &zwp_pointer_constraints_v1_interface,
+                                        1);
        } else if (strcmp(interface, "wl_shm") == 0) {
                d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
                wl_shm_add_listener(d->shm, &shm_listener, d);
diff --git a/clients/window.h b/clients/window.h
index b61a62a..42cf492 100644
--- a/clients/window.h
+++ b/clients/window.h
@@ -218,6 +218,29 @@ typedef void (*window_output_handler_t)(struct window 
*window, struct output *ou
 typedef void (*window_state_changed_handler_t)(struct window *window,
                                               void *data);
 
+
+typedef void (*window_locked_pointer_motion_handler_t)(struct window *window,
+                                                      struct input *input,
+                                                      uint32_t time,
+                                                      float x, float y,
+                                                      void *data);
+
+typedef void (*locked_pointer_locked_handler_t)(struct window *window,
+                                               struct input *input,
+                                               void *data);
+
+typedef void (*locked_pointer_unlocked_handler_t)(struct window *window,
+                                                 struct input *input,
+                                                 void *data);
+
+typedef void (*confined_pointer_confined_handler_t)(struct window *window,
+                                                   struct input *input,
+                                                   void *data);
+
+typedef void (*confined_pointer_unconfined_handler_t)(struct window *window,
+                                                     struct input *input,
+                                                     void *data);
+
 typedef void (*widget_resize_handler_t)(struct widget *widget,
                                        int32_t width, int32_t height,
                                        void *data);
@@ -347,6 +370,24 @@ void
 window_damage(struct window *window, int32_t x, int32_t y,
              int32_t width, int32_t height);
 
+int
+window_lock_pointer(struct window *window, struct input *input);
+
+void
+window_unlock_pointer(struct window *window);
+
+void
+widget_set_locked_pointer_cursor_hint(struct widget *widget,
+                                     float x, float y);
+
+int
+window_confine_pointer_to_widget(struct window *window,
+                                struct widget *widget,
+                                struct input *input);
+
+void
+window_unconfine_pointer(struct window *window);
+
 cairo_surface_t *
 window_get_surface(struct window *window);
 
@@ -425,6 +466,27 @@ window_set_state_changed_handler(struct window *window,
                                 window_state_changed_handler_t handler);
 
 void
+window_set_pointer_locked_handler(struct window *window,
+                                 locked_pointer_locked_handler_t locked);
+
+void
+window_set_pointer_unlocked_handler(struct window *window,
+                                   locked_pointer_unlocked_handler_t unlocked);
+
+void
+window_set_pointer_confined_handler(
+       struct window *window, confined_pointer_confined_handler_t confined);
+
+void
+window_set_pointer_unconfined_handler(
+       struct window *window,
+       confined_pointer_unconfined_handler_t unconfined);
+
+void
+window_set_locked_pointer_motion_handler(
+       struct window *window, window_locked_pointer_motion_handler_t handler);
+
+void
 window_set_title(struct window *window, const char *title);
 
 const char *
-- 
2.4.3

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to