mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
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
This commit is contained in:
parent
50099c4c10
commit
5b0eabec51
2
.gitignore
vendored
2
.gitignore
vendored
@ -68,6 +68,8 @@ src/xdg-shell-unstable-v*-protocol.c
|
|||||||
src/xdg-shell-unstable-v*-server-protocol.h
|
src/xdg-shell-unstable-v*-server-protocol.h
|
||||||
src/pointer-gestures-unstable-v*-protocol.c
|
src/pointer-gestures-unstable-v*-protocol.c
|
||||||
src/pointer-gestures-unstable-v*-server-protocol.h
|
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
|
src/meta/meta-version.h
|
||||||
doc/reference/*.args
|
doc/reference/*.args
|
||||||
doc/reference/*.bak
|
doc/reference/*.bak
|
||||||
|
@ -221,7 +221,7 @@ AS_IF([test "$have_wayland" = "yes"], [
|
|||||||
AC_SUBST([WAYLAND_SCANNER])
|
AC_SUBST([WAYLAND_SCANNER])
|
||||||
AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
|
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_wayland_protocols_pkgdatadir=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`])
|
||||||
AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, $ac_wayland_protocols_pkgdatadir)
|
AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, $ac_wayland_protocols_pkgdatadir)
|
||||||
])
|
])
|
||||||
|
@ -51,6 +51,8 @@ mutter_built_sources += \
|
|||||||
gtk-shell-server-protocol.h \
|
gtk-shell-server-protocol.h \
|
||||||
xdg-shell-unstable-v5-protocol.c \
|
xdg-shell-unstable-v5-protocol.c \
|
||||||
xdg-shell-unstable-v5-server-protocol.h \
|
xdg-shell-unstable-v5-server-protocol.h \
|
||||||
|
relative-pointer-unstable-v1-protocol.c \
|
||||||
|
relative-pointer-unstable-v1-server-protocol.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -87,6 +87,13 @@ struct _MetaBackendClass
|
|||||||
|
|
||||||
void (* update_screen_size) (MetaBackend *backend, int width, int height);
|
void (* update_screen_size) (MetaBackend *backend, int width, int height);
|
||||||
void (* select_stage_events) (MetaBackend *backend);
|
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,
|
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,
|
void meta_backend_update_last_device (MetaBackend *backend,
|
||||||
int device_id);
|
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 */
|
#endif /* META_BACKEND_PRIVATE_H */
|
||||||
|
@ -353,6 +353,17 @@ meta_backend_real_select_stage_events (MetaBackend *backend)
|
|||||||
/* Do nothing */
|
/* 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
|
static void
|
||||||
meta_backend_class_init (MetaBackendClass *klass)
|
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->ungrab_device = meta_backend_real_ungrab_device;
|
||||||
klass->update_screen_size = meta_backend_real_update_screen_size;
|
klass->update_screen_size = meta_backend_real_update_screen_size;
|
||||||
klass->select_stage_events = meta_backend_real_select_stage_events;
|
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_signal_new ("keymap-changed",
|
||||||
G_TYPE_FROM_CLASS (object_class),
|
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
|
static GType
|
||||||
get_backend_type (void)
|
get_backend_type (void)
|
||||||
{
|
{
|
||||||
|
@ -306,6 +306,19 @@ meta_backend_native_lock_layout_group (MetaBackend *backend,
|
|||||||
g_signal_emit_by_name (backend, "keymap-layout-group-changed", idx, 0);
|
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
|
static void
|
||||||
meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
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->set_keymap = meta_backend_native_set_keymap;
|
||||||
backend_class->get_keymap = meta_backend_native_get_keymap;
|
backend_class->get_keymap = meta_backend_native_get_keymap;
|
||||||
backend_class->lock_layout_group = meta_backend_native_lock_layout_group;
|
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
|
static void
|
||||||
|
@ -63,6 +63,8 @@
|
|||||||
#include "backends/meta-cursor-tracker-private.h"
|
#include "backends/meta-cursor-tracker-private.h"
|
||||||
#include "backends/meta-cursor-renderer.h"
|
#include "backends/meta-cursor-renderer.h"
|
||||||
|
|
||||||
|
#include "relative-pointer-unstable-v1-server-protocol.h"
|
||||||
|
|
||||||
#ifdef HAVE_NATIVE_BACKEND
|
#ifdef HAVE_NATIVE_BACKEND
|
||||||
#include "backends/native/meta-backend-native.h"
|
#include "backends/native/meta-backend-native.h"
|
||||||
#endif
|
#endif
|
||||||
@ -96,6 +98,7 @@ meta_wayland_pointer_client_new (void)
|
|||||||
wl_list_init (&pointer_client->pointer_resources);
|
wl_list_init (&pointer_client->pointer_resources);
|
||||||
wl_list_init (&pointer_client->swipe_gesture_resources);
|
wl_list_init (&pointer_client->swipe_gesture_resources);
|
||||||
wl_list_init (&pointer_client->pinch_gesture_resources);
|
wl_list_init (&pointer_client->pinch_gesture_resources);
|
||||||
|
wl_list_init (&pointer_client->relative_pointer_resources);
|
||||||
|
|
||||||
return pointer_client;
|
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_remove (wl_resource_get_link (resource));
|
||||||
wl_list_init (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);
|
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) &&
|
return (wl_list_empty (&pointer_client->pointer_resources) &&
|
||||||
wl_list_empty (&pointer_client->swipe_gesture_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 *
|
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
|
void
|
||||||
meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer,
|
meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer,
|
||||||
const ClutterEvent *event)
|
const ClutterEvent *event)
|
||||||
@ -285,6 +341,8 @@ meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer,
|
|||||||
wl_pointer_send_motion (resource, time, sx, sy);
|
wl_pointer_send_motion (resource, time, sx, sy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meta_wayland_pointer_send_relative_motion (pointer, event);
|
||||||
|
|
||||||
meta_wayland_pointer_broadcast_frame (pointer);
|
meta_wayland_pointer_broadcast_frame (pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1097,6 +1155,101 @@ meta_wayland_pointer_get_top_popup (MetaWaylandPointer *pointer)
|
|||||||
return meta_wayland_popup_grab_get_top_popup(grab);
|
return meta_wayland_popup_grab_get_top_popup(grab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static void
|
||||||
cursor_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
|
cursor_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
|
||||||
{
|
{
|
||||||
|
@ -58,6 +58,7 @@ struct _MetaWaylandPointerClient
|
|||||||
struct wl_list pointer_resources;
|
struct wl_list pointer_resources;
|
||||||
struct wl_list swipe_gesture_resources;
|
struct wl_list swipe_gesture_resources;
|
||||||
struct wl_list pinch_gesture_resources;
|
struct wl_list pinch_gesture_resources;
|
||||||
|
struct wl_list relative_pointer_resources;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaWaylandPointer
|
struct _MetaWaylandPointer
|
||||||
@ -142,4 +143,6 @@ MetaWaylandPointerClient * meta_wayland_pointer_get_pointer_client (MetaWaylandP
|
|||||||
struct wl_client *client);
|
struct wl_client *client);
|
||||||
void meta_wayland_pointer_unbind_pointer_client_resource (struct wl_resource *resource);
|
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 */
|
#endif /* META_WAYLAND_POINTER_H */
|
||||||
|
@ -328,6 +328,7 @@ meta_wayland_init (void)
|
|||||||
meta_wayland_shell_init (compositor);
|
meta_wayland_shell_init (compositor);
|
||||||
meta_wayland_pointer_gestures_init (compositor);
|
meta_wayland_pointer_gestures_init (compositor);
|
||||||
meta_wayland_seat_init (compositor);
|
meta_wayland_seat_init (compositor);
|
||||||
|
meta_wayland_relative_pointer_init (compositor);
|
||||||
|
|
||||||
if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display))
|
if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display))
|
||||||
g_error ("Failed to start X Wayland");
|
g_error ("Failed to start X Wayland");
|
||||||
|
Loading…
Reference in New Issue
Block a user