[mutter] wayland: Implement support for wp_relative_pointer
- From: Jonas Ã…dahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] wayland: Implement support for wp_relative_pointer
- Date: Tue, 16 Feb 2016 11:03:26 +0000 (UTC)
commit 5b0eabec51cbb08e2ded9133740cd1418afa75b7
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Tue Jun 2 16:26:34 2015 +0800
wayland: Implement support for wp_relative_pointer
Add support for sending relative pointer motion deltas to clients who
request such events by creating wp_relative_pointer objects via
wp_relative_pointer_manager.
This currently implements the unstable version 1 from wayland-protocols.
https://bugzilla.gnome.org/show_bug.cgi?id=744104
.gitignore | 2 +
configure.ac | 2 +-
src/Makefile.am | 2 +
src/backends/meta-backend-private.h | 14 +++
src/backends/meta-backend.c | 27 +++++
src/backends/native/meta-backend-native.c | 14 +++
src/wayland/meta-wayland-pointer.c | 155 ++++++++++++++++++++++++++++-
src/wayland/meta-wayland-pointer.h | 3 +
src/wayland/meta-wayland.c | 1 +
9 files changed, 218 insertions(+), 2 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 7a3d9d3..62a2743 100644
--- a/.gitignore
+++ b/.gitignore
@@ -68,6 +68,8 @@ src/xdg-shell-unstable-v*-protocol.c
src/xdg-shell-unstable-v*-server-protocol.h
src/pointer-gestures-unstable-v*-protocol.c
src/pointer-gestures-unstable-v*-server-protocol.h
+src/relative-pointer-unstable-v*-protocol.c
+src/relative-pointer-unstable-v*-server-protocol.h
src/meta/meta-version.h
doc/reference/*.args
doc/reference/*.bak
diff --git a/configure.ac b/configure.ac
index 8731079..412bb85 100644
--- a/configure.ac
+++ b/configure.ac
@@ -221,7 +221,7 @@ AS_IF([test "$have_wayland" = "yes"], [
AC_SUBST([WAYLAND_SCANNER])
AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
- PKG_CHECK_MODULES(WAYLAND_PROTOCOLS, [wayland-protocols >= 1.0],
+ PKG_CHECK_MODULES(WAYLAND_PROTOCOLS, [wayland-protocols >= 1.1],
[ac_wayland_protocols_pkgdatadir=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`])
AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, $ac_wayland_protocols_pkgdatadir)
])
diff --git a/src/Makefile.am b/src/Makefile.am
index 5468d47..71aa026 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -51,6 +51,8 @@ mutter_built_sources += \
gtk-shell-server-protocol.h \
xdg-shell-unstable-v5-protocol.c \
xdg-shell-unstable-v5-server-protocol.h \
+ relative-pointer-unstable-v1-protocol.c \
+ relative-pointer-unstable-v1-server-protocol.h \
$(NULL)
endif
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
index d2c6276..6fa468d 100644
--- a/src/backends/meta-backend-private.h
+++ b/src/backends/meta-backend-private.h
@@ -87,6 +87,13 @@ struct _MetaBackendClass
void (* update_screen_size) (MetaBackend *backend, int width, int height);
void (* select_stage_events) (MetaBackend *backend);
+
+ gboolean (* get_relative_motion_deltas) (MetaBackend *backend,
+ const ClutterEvent *event,
+ double *dx,
+ double *dy,
+ double *dx_unaccel,
+ double *dy_unaccel);
};
MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend,
@@ -110,4 +117,11 @@ struct xkb_keymap * meta_backend_get_keymap (MetaBackend *backend);
void meta_backend_update_last_device (MetaBackend *backend,
int device_id);
+gboolean meta_backend_get_relative_motion_deltas (MetaBackend *backend,
+ const ClutterEvent *event,
+ double *dx,
+ double *dy,
+ double *dx_unaccel,
+ double *dy_unaccel);
+
#endif /* META_BACKEND_PRIVATE_H */
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 8197478..05d160d 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -353,6 +353,17 @@ meta_backend_real_select_stage_events (MetaBackend *backend)
/* Do nothing */
}
+static gboolean
+meta_backend_real_get_relative_motion_deltas (MetaBackend *backend,
+ const ClutterEvent *event,
+ double *dx,
+ double *dy,
+ double *dx_unaccel,
+ double *dy_unaccel)
+{
+ return FALSE;
+}
+
static void
meta_backend_class_init (MetaBackendClass *klass)
{
@@ -366,6 +377,7 @@ meta_backend_class_init (MetaBackendClass *klass)
klass->ungrab_device = meta_backend_real_ungrab_device;
klass->update_screen_size = meta_backend_real_update_screen_size;
klass->select_stage_events = meta_backend_real_select_stage_events;
+ klass->get_relative_motion_deltas = meta_backend_real_get_relative_motion_deltas;
g_signal_new ("keymap-changed",
G_TYPE_FROM_CLASS (object_class),
@@ -544,6 +556,21 @@ meta_backend_update_last_device (MetaBackend *backend,
}
}
+gboolean
+meta_backend_get_relative_motion_deltas (MetaBackend *backend,
+ const ClutterEvent *event,
+ double *dx,
+ double *dy,
+ double *dx_unaccel,
+ double *dy_unaccel)
+{
+ MetaBackendClass *klass = META_BACKEND_GET_CLASS (backend);
+ return klass->get_relative_motion_deltas (backend,
+ event,
+ dx, dy,
+ dx_unaccel, dy_unaccel);
+}
+
static GType
get_backend_type (void)
{
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
index d22bed1..5a1c1b4 100644
--- a/src/backends/native/meta-backend-native.c
+++ b/src/backends/native/meta-backend-native.c
@@ -306,6 +306,19 @@ meta_backend_native_lock_layout_group (MetaBackend *backend,
g_signal_emit_by_name (backend, "keymap-layout-group-changed", idx, 0);
}
+static gboolean
+meta_backend_native_get_relative_motion_deltas (MetaBackend *backend,
+ const ClutterEvent *event,
+ double *dx,
+ double *dy,
+ double *dx_unaccel,
+ double *dy_unaccel)
+{
+ return clutter_evdev_event_get_relative_motion (event,
+ dx, dy,
+ dx_unaccel, dy_unaccel);
+}
+
static void
meta_backend_native_class_init (MetaBackendNativeClass *klass)
{
@@ -323,6 +336,7 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
backend_class->set_keymap = meta_backend_native_set_keymap;
backend_class->get_keymap = meta_backend_native_get_keymap;
backend_class->lock_layout_group = meta_backend_native_lock_layout_group;
+ backend_class->get_relative_motion_deltas = meta_backend_native_get_relative_motion_deltas;
}
static void
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
index 92acffa..ef3228e 100644
--- a/src/wayland/meta-wayland-pointer.c
+++ b/src/wayland/meta-wayland-pointer.c
@@ -63,6 +63,8 @@
#include "backends/meta-cursor-tracker-private.h"
#include "backends/meta-cursor-renderer.h"
+#include "relative-pointer-unstable-v1-server-protocol.h"
+
#ifdef HAVE_NATIVE_BACKEND
#include "backends/native/meta-backend-native.h"
#endif
@@ -96,6 +98,7 @@ meta_wayland_pointer_client_new (void)
wl_list_init (&pointer_client->pointer_resources);
wl_list_init (&pointer_client->swipe_gesture_resources);
wl_list_init (&pointer_client->pinch_gesture_resources);
+ wl_list_init (&pointer_client->relative_pointer_resources);
return pointer_client;
}
@@ -124,6 +127,11 @@ meta_wayland_pointer_client_free (MetaWaylandPointerClient *pointer_client)
wl_list_remove (wl_resource_get_link (resource));
wl_list_init (wl_resource_get_link (resource));
}
+ wl_resource_for_each_safe (resource, next, &pointer_client->relative_pointer_resources)
+ {
+ wl_list_remove (wl_resource_get_link (resource));
+ wl_list_init (wl_resource_get_link (resource));
+ }
g_slice_free (MetaWaylandPointerClient, pointer_client);
}
@@ -133,7 +141,8 @@ meta_wayland_pointer_client_is_empty (MetaWaylandPointerClient *pointer_client)
{
return (wl_list_empty (&pointer_client->pointer_resources) &&
wl_list_empty (&pointer_client->swipe_gesture_resources) &&
- wl_list_empty (&pointer_client->pinch_gesture_resources));
+ wl_list_empty (&pointer_client->pinch_gesture_resources) &&
+ wl_list_empty (&pointer_client->relative_pointer_resources));
}
MetaWaylandPointerClient *
@@ -264,6 +273,53 @@ meta_wayland_pointer_broadcast_frame (MetaWaylandPointer *pointer)
}
}
+static void
+meta_wayland_pointer_send_relative_motion (MetaWaylandPointer *pointer,
+ const ClutterEvent *event)
+{
+ struct wl_resource *resource;
+ double dx, dy;
+ double dx_unaccel, dy_unaccel;
+ uint64_t time_us;
+ uint32_t time_us_hi;
+ uint32_t time_us_lo;
+ wl_fixed_t dxf, dyf;
+ wl_fixed_t dx_unaccelf, dy_unaccelf;
+
+ if (!pointer->focus_client)
+ return;
+
+ if (!meta_backend_get_relative_motion_deltas (meta_get_backend (),
+ event,
+ &dx, &dy,
+ &dx_unaccel, &dy_unaccel))
+ return;
+
+#ifdef HAVE_NATIVE_BACKEND
+ time_us = clutter_evdev_event_get_time_usec (event);
+ if (time_us == 0)
+#endif
+ time_us = clutter_event_get_time (event) * 1000ULL;
+ time_us_hi = (uint32_t) (time_us >> 32);
+ time_us_lo = (uint32_t) time_us;
+ dxf = wl_fixed_from_double (dx);
+ dyf = wl_fixed_from_double (dy);
+ dx_unaccelf = wl_fixed_from_double (dx_unaccel);
+ dy_unaccelf = wl_fixed_from_double (dy_unaccel);
+
+ wl_resource_for_each (resource,
+ &pointer->focus_client->relative_pointer_resources)
+ {
+ zwp_relative_pointer_v1_send_relative_motion (resource,
+ time_us_hi,
+ time_us_lo,
+ dxf,
+ dyf,
+ dx_unaccelf,
+ dy_unaccelf);
+ }
+}
+
void
meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer,
const ClutterEvent *event)
@@ -285,6 +341,8 @@ meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer,
wl_pointer_send_motion (resource, time, sx, sy);
}
+ meta_wayland_pointer_send_relative_motion (pointer, event);
+
meta_wayland_pointer_broadcast_frame (pointer);
}
@@ -1098,6 +1156,101 @@ meta_wayland_pointer_get_top_popup (MetaWaylandPointer *pointer)
}
static void
+relative_pointer_destroy (struct wl_client *client,
+ struct wl_resource *resource)
+{
+ wl_resource_destroy (resource);
+}
+
+static const struct zwp_relative_pointer_v1_interface relative_pointer_interface = {
+ relative_pointer_destroy
+};
+
+static void
+relative_pointer_manager_destroy (struct wl_client *client,
+ struct wl_resource *resource)
+{
+ wl_resource_destroy (resource);
+}
+
+static void
+relative_pointer_manager_get_relative_pointer (struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id,
+ struct wl_resource *pointer_resource)
+{
+ MetaWaylandPointer *pointer = wl_resource_get_user_data (pointer_resource);
+ struct wl_resource *cr;
+ MetaWaylandPointerClient *pointer_client;
+
+ cr = wl_resource_create (client, &zwp_relative_pointer_v1_interface,
+ wl_resource_get_version (resource), id);
+ if (cr == NULL)
+ {
+ wl_client_post_no_memory (client);
+ return;
+ }
+
+ wl_resource_set_implementation (cr, &relative_pointer_interface,
+ pointer,
+ meta_wayland_pointer_unbind_pointer_client_resource);
+
+ pointer_client = meta_wayland_pointer_ensure_pointer_client (pointer, client);
+
+ wl_list_insert (&pointer_client->relative_pointer_resources,
+ wl_resource_get_link (cr));
+}
+
+static const struct zwp_relative_pointer_manager_v1_interface relative_pointer_manager = {
+ relative_pointer_manager_destroy,
+ relative_pointer_manager_get_relative_pointer,
+};
+
+static void
+bind_relative_pointer_manager (struct wl_client *client,
+ void *data,
+ uint32_t version,
+ uint32_t id)
+{
+ MetaWaylandCompositor *compositor = data;
+ struct wl_resource *resource;
+
+ resource = wl_resource_create (client,
+ &zwp_relative_pointer_manager_v1_interface,
+ 1, id);
+
+ if (version != 1)
+ wl_resource_post_error (resource,
+ WL_DISPLAY_ERROR_INVALID_OBJECT,
+ "bound invalid version %u of "
+ "wp_relative_pointer_manager",
+ version);
+
+ wl_resource_set_implementation (resource, &relative_pointer_manager,
+ compositor,
+ NULL);
+}
+
+void
+meta_wayland_relative_pointer_init (MetaWaylandCompositor *compositor)
+{
+ /* Relative pointer events are currently only supported by the native backend
+ * so lets just advertise the extension when the native backend is used.
+ */
+#ifdef HAVE_NATIVE_BACKEND
+ if (!META_IS_BACKEND_NATIVE (meta_get_backend ()))
+ return;
+#else
+ return;
+#endif
+
+ if (!wl_global_create (compositor->wayland_display,
+ &zwp_relative_pointer_manager_v1_interface, 1,
+ compositor, bind_relative_pointer_manager))
+ g_error ("Could not create relative pointer manager global");
+}
+
+static void
cursor_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
{
MetaWaylandSurface *surface =
diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h
index 7e31da9..cfe1b46 100644
--- a/src/wayland/meta-wayland-pointer.h
+++ b/src/wayland/meta-wayland-pointer.h
@@ -58,6 +58,7 @@ struct _MetaWaylandPointerClient
struct wl_list pointer_resources;
struct wl_list swipe_gesture_resources;
struct wl_list pinch_gesture_resources;
+ struct wl_list relative_pointer_resources;
};
struct _MetaWaylandPointer
@@ -142,4 +143,6 @@ MetaWaylandPointerClient * meta_wayland_pointer_get_pointer_client (MetaWaylandP
struct wl_client *client);
void meta_wayland_pointer_unbind_pointer_client_resource (struct wl_resource *resource);
+void meta_wayland_relative_pointer_init (MetaWaylandCompositor *compositor);
+
#endif /* META_WAYLAND_POINTER_H */
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index 523fbce..a878f32 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -328,6 +328,7 @@ meta_wayland_init (void)
meta_wayland_shell_init (compositor);
meta_wayland_pointer_gestures_init (compositor);
meta_wayland_seat_init (compositor);
+ meta_wayland_relative_pointer_init (compositor);
if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display))
g_error ("Failed to start X Wayland");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]