mirror of https://github.com/libsdl-org/SDL
wayland: Add support for relative mouse mode, by Jonas ?dahl <jadahl@gmail.com>
Generate the C protocol files from the protocol XML files installed by wayland-protocols, and use them to implement support for relative pointer motions and pointer locking. Note that at the time, the protocol is unstable and may change in the future. Any future breaking changes will, however, fail gracefully and result in no regressions compared to before this patch.
This commit is contained in:
parent
19d3500ae1
commit
f11a440999
|
@ -18807,11 +18807,12 @@ $as_echo_n "checking for Wayland support... " >&6; }
|
|||
if test x$PKG_CONFIG != xno && \
|
||||
test x$video_opengl_egl = xyes && \
|
||||
test x$video_opengles_v2 = xyes; then
|
||||
if $PKG_CONFIG --exists wayland-client wayland-scanner wayland-egl wayland-cursor egl xkbcommon ; then
|
||||
if $PKG_CONFIG --exists wayland-client wayland-scanner wayland-protocols wayland-egl wayland-cursor egl xkbcommon ; then
|
||||
WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor xkbcommon`
|
||||
WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor xkbcommon`
|
||||
WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner`
|
||||
WAYLAND_CORE_PROTOCOL_DIR=`$PKG_CONFIG --variable=pkgdatadir wayland-client`
|
||||
WAYLAND_PROTOCOLS_DIR=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`
|
||||
video_wayland=yes
|
||||
fi
|
||||
fi
|
||||
|
@ -18827,6 +18828,9 @@ $as_echo "#define SDL_VIDEO_DRIVER_WAYLAND 1" >>confdefs.h
|
|||
$as_echo "#define SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
WAYLAND_PROTOCOLS_UNSTABLE="relative-pointer-unstable-v1 pointer-constraints-unstable-v1"
|
||||
|
||||
SOURCES="$SOURCES $srcdir/src/video/wayland/*.c"
|
||||
EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS -I\$(gen)"
|
||||
# Check whether --enable-wayland-shared was given.
|
||||
|
@ -23736,8 +23740,12 @@ SDLTEST_SOURCES="$srcdir/src/test/*.c"
|
|||
if test x$video_wayland = xyes; then
|
||||
WAYLAND_CORE_PROTOCOL_SOURCE='$(gen)/wayland-protocol.c'
|
||||
WAYLAND_CORE_PROTOCOL_HEADER='$(gen)/wayland-client-protocol.h'
|
||||
GEN_SOURCES="$GEN_SOURCES $WAYLAND_CORE_PROTOCOL_SOURCE"
|
||||
GEN_HEADERS="$GEN_HEADERS $WAYLAND_CORE_PROTOCOL_HEADER"
|
||||
WAYLAND_PROTOCOLS_UNSTABLE_SOURCES=`echo $WAYLAND_PROTOCOLS_UNSTABLE |\
|
||||
sed 's,[^ ]\+,\\$(gen)/&-protocol.c,g'`
|
||||
WAYLAND_PROTOCOLS_UNSTABLE_HEADERS=`echo $WAYLAND_PROTOCOLS_UNSTABLE |\
|
||||
sed 's,[^ ]\+,\\$(gen)/&-client-protocol.h,g'`
|
||||
GEN_SOURCES="$GEN_SOURCES $WAYLAND_CORE_PROTOCOL_SOURCE $WAYLAND_PROTOCOLS_UNSTABLE_SOURCES"
|
||||
GEN_HEADERS="$GEN_HEADERS $WAYLAND_CORE_PROTOCOL_HEADER $WAYLAND_PROTOCOLS_UNSTABLE_HEADERS"
|
||||
|
||||
WAYLAND_CORE_PROTOCOL_SOURCE_DEPENDS="
|
||||
$WAYLAND_CORE_PROTOCOL_SOURCE: $WAYLAND_CORE_PROTOCOL_DIR/wayland.xml
|
||||
|
@ -23753,10 +23761,30 @@ $WAYLAND_CORE_PROTOCOL_HEADER: $WAYLAND_CORE_PROTOCOL_DIR/wayland.xml
|
|||
\$(objects)/`echo $WAYLAND_CORE_PROTOCOL_SOURCE | sed 's/\$(gen)\/\(.*\).c$/\1.lo/'`: $WAYLAND_CORE_PROTOCOL_SOURCE
|
||||
\$(RUN_CMD_CC)\$(LIBTOOL) --tag=CC --mode=compile \$(CC) \$(CFLAGS) \$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \$< -o \$@"
|
||||
|
||||
WAYLAND_PROTOCOLS_CLIENT_HEADER_UNSTABLE_DEPENDS=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\
|
||||
do echo ; echo \$p | sed\
|
||||
"s,^\\([a-z\\-]\\+\\)-unstable-\\(v[0-9]\+\\)\$,\\$(gen)/&-client-protocol.h: $WAYLAND_PROTOCOLS_DIR/unstable/\1/&.xml\\\\
|
||||
\\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)\\\\
|
||||
\\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) client-header \\$< \\$@," ; done`
|
||||
|
||||
WAYLAND_PROTOCOLS_CODE_UNSTABLE_DEPENDS=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\
|
||||
do echo ; echo \$p | sed\
|
||||
"s,^\\([a-z\\-]\\+\\)-unstable-\\(v[0-9]\+\\)\$,\\$(gen)/&-protocol.c: $WAYLAND_PROTOCOLS_DIR/unstable/\1/&.xml\\\\
|
||||
\\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)\\\\
|
||||
\\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) code \\$< \\$@," ; done`
|
||||
|
||||
WAYLAND_PROTOCOLS_OBJECTS_UNSTABLE=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\
|
||||
do echo ; echo \$p | sed\
|
||||
"s,^\\([a-z\\-]\\+\\)-unstable-\\(v[0-9]\+\\)\$,\\\$(objects)/&-protocol.lo: \\$(gen)/&-protocol.c \\$(gen)/&-client-protocol.h\\\\
|
||||
\\$(RUN_CMD_CC)\\$(LIBTOOL) --tag=CC --mode=compile \\$(CC) \\$(CFLAGS) \\$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \\$< -o \\$@," ; done`
|
||||
|
||||
WAYLAND_PROTOCOLS_DEPENDS="
|
||||
$WAYLAND_CORE_PROTOCOL_SOURCE_DEPENDS
|
||||
$WAYLAND_CORE_PROTOCOL_HEADER_DEPENDS
|
||||
$WAYLAND_CORE_PROTOCOL_OBJECT
|
||||
$WAYLAND_PROTOCOLS_CLIENT_HEADER_UNSTABLE_DEPENDS
|
||||
$WAYLAND_PROTOCOLS_CODE_UNSTABLE_DEPENDS
|
||||
$WAYLAND_PROTOCOLS_OBJECTS_UNSTABLE
|
||||
"
|
||||
fi
|
||||
|
||||
|
|
34
configure.in
34
configure.in
|
@ -1201,11 +1201,12 @@ AC_HELP_STRING([--enable-video-wayland-qt-touch], [QtWayland server support for
|
|||
if test x$PKG_CONFIG != xno && \
|
||||
test x$video_opengl_egl = xyes && \
|
||||
test x$video_opengles_v2 = xyes; then
|
||||
if $PKG_CONFIG --exists wayland-client wayland-scanner wayland-egl wayland-cursor egl xkbcommon ; then
|
||||
if $PKG_CONFIG --exists wayland-client wayland-scanner wayland-protocols wayland-egl wayland-cursor egl xkbcommon ; then
|
||||
WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor xkbcommon`
|
||||
WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor xkbcommon`
|
||||
WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner`
|
||||
WAYLAND_CORE_PROTOCOL_DIR=`$PKG_CONFIG --variable=pkgdatadir wayland-client`
|
||||
WAYLAND_PROTOCOLS_DIR=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`
|
||||
video_wayland=yes
|
||||
fi
|
||||
fi
|
||||
|
@ -1216,6 +1217,9 @@ AC_HELP_STRING([--enable-video-wayland-qt-touch], [QtWayland server support for
|
|||
if test x$enable_video_wayland_qt_touch = xyes; then
|
||||
AC_DEFINE(SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH, 1, [ ])
|
||||
fi
|
||||
|
||||
WAYLAND_PROTOCOLS_UNSTABLE="relative-pointer-unstable-v1 pointer-constraints-unstable-v1"
|
||||
|
||||
SOURCES="$SOURCES $srcdir/src/video/wayland/*.c"
|
||||
EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS -I\$(gen)"
|
||||
AC_ARG_ENABLE(wayland-shared,
|
||||
|
@ -3486,8 +3490,12 @@ SDLTEST_SOURCES="$srcdir/src/test/*.c"
|
|||
if test x$video_wayland = xyes; then
|
||||
WAYLAND_CORE_PROTOCOL_SOURCE='$(gen)/wayland-protocol.c'
|
||||
WAYLAND_CORE_PROTOCOL_HEADER='$(gen)/wayland-client-protocol.h'
|
||||
GEN_SOURCES="$GEN_SOURCES $WAYLAND_CORE_PROTOCOL_SOURCE"
|
||||
GEN_HEADERS="$GEN_HEADERS $WAYLAND_CORE_PROTOCOL_HEADER"
|
||||
WAYLAND_PROTOCOLS_UNSTABLE_SOURCES=`echo $WAYLAND_PROTOCOLS_UNSTABLE |\
|
||||
sed 's,[[^ ]]\+,\\$(gen)/&-protocol.c,g'`
|
||||
WAYLAND_PROTOCOLS_UNSTABLE_HEADERS=`echo $WAYLAND_PROTOCOLS_UNSTABLE |\
|
||||
sed 's,[[^ ]]\+,\\$(gen)/&-client-protocol.h,g'`
|
||||
GEN_SOURCES="$GEN_SOURCES $WAYLAND_CORE_PROTOCOL_SOURCE $WAYLAND_PROTOCOLS_UNSTABLE_SOURCES"
|
||||
GEN_HEADERS="$GEN_HEADERS $WAYLAND_CORE_PROTOCOL_HEADER $WAYLAND_PROTOCOLS_UNSTABLE_HEADERS"
|
||||
|
||||
WAYLAND_CORE_PROTOCOL_SOURCE_DEPENDS="
|
||||
$WAYLAND_CORE_PROTOCOL_SOURCE: $WAYLAND_CORE_PROTOCOL_DIR/wayland.xml
|
||||
|
@ -3503,10 +3511,30 @@ $WAYLAND_CORE_PROTOCOL_HEADER: $WAYLAND_CORE_PROTOCOL_DIR/wayland.xml
|
|||
\$(objects)/`echo $WAYLAND_CORE_PROTOCOL_SOURCE | sed 's/\$(gen)\/\(.*\).c$/\1.lo/'`: $WAYLAND_CORE_PROTOCOL_SOURCE
|
||||
\$(RUN_CMD_CC)\$(LIBTOOL) --tag=CC --mode=compile \$(CC) \$(CFLAGS) \$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \$< -o \$@"
|
||||
|
||||
WAYLAND_PROTOCOLS_CLIENT_HEADER_UNSTABLE_DEPENDS=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\
|
||||
do echo ; echo \$p | sed\
|
||||
"s,^\\([[a-z\\-]]\\+\\)-unstable-\\(v[[0-9]]\+\\)\$,\\$(gen)/&-client-protocol.h: $WAYLAND_PROTOCOLS_DIR/unstable/\1/&.xml\\\\
|
||||
\\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)\\\\
|
||||
\\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) client-header \\$< \\$@," ; done`
|
||||
|
||||
WAYLAND_PROTOCOLS_CODE_UNSTABLE_DEPENDS=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\
|
||||
do echo ; echo \$p | sed\
|
||||
"s,^\\([[a-z\\-]]\\+\\)-unstable-\\(v[[0-9]]\+\\)\$,\\$(gen)/&-protocol.c: $WAYLAND_PROTOCOLS_DIR/unstable/\1/&.xml\\\\
|
||||
\\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)\\\\
|
||||
\\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) code \\$< \\$@," ; done`
|
||||
|
||||
WAYLAND_PROTOCOLS_OBJECTS_UNSTABLE=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\
|
||||
do echo ; echo \$p | sed\
|
||||
"s,^\\([[a-z\\-]]\\+\\)-unstable-\\(v[[0-9]]\+\\)\$,\\\$(objects)/&-protocol.lo: \\$(gen)/&-protocol.c \\$(gen)/&-client-protocol.h\\\\
|
||||
\\$(RUN_CMD_CC)\\$(LIBTOOL) --tag=CC --mode=compile \\$(CC) \\$(CFLAGS) \\$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \\$< -o \\$@," ; done`
|
||||
|
||||
WAYLAND_PROTOCOLS_DEPENDS="
|
||||
$WAYLAND_CORE_PROTOCOL_SOURCE_DEPENDS
|
||||
$WAYLAND_CORE_PROTOCOL_HEADER_DEPENDS
|
||||
$WAYLAND_CORE_PROTOCOL_OBJECT
|
||||
$WAYLAND_PROTOCOLS_CLIENT_HEADER_UNSTABLE_DEPENDS
|
||||
$WAYLAND_PROTOCOLS_CODE_UNSTABLE_DEPENDS
|
||||
$WAYLAND_PROTOCOLS_OBJECTS_UNSTABLE
|
||||
"
|
||||
fi
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "SDL_stdinc.h"
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_log.h"
|
||||
|
||||
#include "../../events/SDL_sysevents.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
|
@ -36,6 +37,9 @@
|
|||
|
||||
#include "SDL_waylanddyn.h"
|
||||
|
||||
#include "pointer-constraints-unstable-v1-client-protocol.h"
|
||||
#include "relative-pointer-unstable-v1-client-protocol.h"
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/mman.h>
|
||||
|
@ -48,13 +52,17 @@ struct SDL_WaylandInput {
|
|||
struct wl_seat *seat;
|
||||
struct wl_pointer *pointer;
|
||||
struct wl_keyboard *keyboard;
|
||||
struct zwp_relative_pointer_v1 *relative_pointer;
|
||||
SDL_WindowData *pointer_focus;
|
||||
SDL_WindowData *keyboard_focus;
|
||||
|
||||
/* Last motion location */
|
||||
wl_fixed_t sx_w;
|
||||
wl_fixed_t sy_w;
|
||||
|
||||
|
||||
double dx_frac;
|
||||
double dy_frac;
|
||||
|
||||
struct {
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_state *state;
|
||||
|
@ -170,10 +178,9 @@ ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
|
|||
}
|
||||
|
||||
static void
|
||||
pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
|
||||
uint32_t time, uint32_t button, uint32_t state_w)
|
||||
pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_t serial,
|
||||
uint32_t time, uint32_t button, uint32_t state_w)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
SDL_WindowData *window = input->pointer_focus;
|
||||
enum wl_pointer_button_state state = state_w;
|
||||
uint32_t sdl_button;
|
||||
|
@ -182,7 +189,7 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
|
|||
switch (button) {
|
||||
case BTN_LEFT:
|
||||
sdl_button = SDL_BUTTON_LEFT;
|
||||
if (ProcessHitTest(data, serial)) {
|
||||
if (ProcessHitTest(input, serial)) {
|
||||
return; /* don't pass this event on to app. */
|
||||
}
|
||||
break;
|
||||
|
@ -208,10 +215,18 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
|
|||
}
|
||||
|
||||
static void
|
||||
pointer_handle_axis(void *data, struct wl_pointer *pointer,
|
||||
uint32_t time, uint32_t axis, wl_fixed_t value)
|
||||
pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
|
||||
uint32_t time, uint32_t button, uint32_t state_w)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
|
||||
pointer_handle_button_common(input, serial, time, button, state_w);
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_handle_axis_common(struct SDL_WaylandInput *input,
|
||||
uint32_t time, uint32_t axis, wl_fixed_t value)
|
||||
{
|
||||
SDL_WindowData *window = input->pointer_focus;
|
||||
enum wl_pointer_axis a = axis;
|
||||
int x, y;
|
||||
|
@ -234,6 +249,15 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_handle_axis(void *data, struct wl_pointer *pointer,
|
||||
uint32_t time, uint32_t axis, wl_fixed_t value)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
|
||||
pointer_handle_axis_common(input, time, axis, value);
|
||||
}
|
||||
|
||||
static const struct wl_pointer_listener pointer_listener = {
|
||||
pointer_handle_enter,
|
||||
pointer_handle_leave,
|
||||
|
@ -453,6 +477,164 @@ void Wayland_display_destroy_input(SDL_VideoData *d)
|
|||
d->input = NULL;
|
||||
}
|
||||
|
||||
void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id)
|
||||
{
|
||||
d->relative_pointer_manager =
|
||||
wl_registry_bind(d->registry, id,
|
||||
&zwp_relative_pointer_manager_v1_interface, 1);
|
||||
}
|
||||
|
||||
void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d)
|
||||
{
|
||||
if (d->relative_pointer_manager)
|
||||
zwp_relative_pointer_manager_v1_destroy(d->relative_pointer_manager);
|
||||
}
|
||||
|
||||
void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id)
|
||||
{
|
||||
d->pointer_constraints =
|
||||
wl_registry_bind(d->registry, id,
|
||||
&zwp_pointer_constraints_v1_interface, 1);
|
||||
}
|
||||
|
||||
void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d)
|
||||
{
|
||||
if (d->pointer_constraints)
|
||||
zwp_pointer_constraints_v1_destroy(d->pointer_constraints);
|
||||
}
|
||||
|
||||
static void
|
||||
relative_pointer_handle_relative_motion(void *data,
|
||||
struct zwp_relative_pointer_v1 *pointer,
|
||||
uint32_t time_hi,
|
||||
uint32_t time_lo,
|
||||
wl_fixed_t dx_w,
|
||||
wl_fixed_t dy_w,
|
||||
wl_fixed_t dx_unaccel_w,
|
||||
wl_fixed_t dy_unaccel_w)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
SDL_VideoData *d = input->display;
|
||||
SDL_WindowData *window = input->pointer_focus;
|
||||
double dx_unaccel;
|
||||
double dy_unaccel;
|
||||
double dx;
|
||||
double dy;
|
||||
|
||||
dx_unaccel = wl_fixed_to_double(dx_unaccel_w);
|
||||
dy_unaccel = wl_fixed_to_double(dy_unaccel_w);
|
||||
|
||||
/* Add left over fraction from last event. */
|
||||
dx_unaccel += input->dx_frac;
|
||||
dy_unaccel += input->dy_frac;
|
||||
|
||||
input->dx_frac = modf(dx_unaccel, &dx);
|
||||
input->dy_frac = modf(dy_unaccel, &dy);
|
||||
|
||||
if (input->pointer_focus && d->relative_mouse_mode) {
|
||||
SDL_SendMouseMotion(window->sdlwindow, 0, 1, (int)dx, (int)dy);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = {
|
||||
relative_pointer_handle_relative_motion,
|
||||
};
|
||||
|
||||
static void
|
||||
locked_pointer_locked(void *data,
|
||||
struct zwp_locked_pointer_v1 *locked_pointer)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
locked_pointer_unlocked(void *data,
|
||||
struct zwp_locked_pointer_v1 *locked_pointer)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct zwp_locked_pointer_v1_listener locked_pointer_listener = {
|
||||
locked_pointer_locked,
|
||||
locked_pointer_unlocked,
|
||||
};
|
||||
|
||||
static void
|
||||
lock_pointer_to_window(SDL_Window *window,
|
||||
struct SDL_WaylandInput *input)
|
||||
{
|
||||
SDL_WindowData *w = window->driverdata;
|
||||
SDL_VideoData *d = input->display;
|
||||
struct zwp_locked_pointer_v1 *locked_pointer;
|
||||
|
||||
if (w->locked_pointer)
|
||||
return;
|
||||
|
||||
locked_pointer =
|
||||
zwp_pointer_constraints_v1_lock_pointer(d->pointer_constraints,
|
||||
w->surface,
|
||||
input->pointer,
|
||||
NULL,
|
||||
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
|
||||
zwp_locked_pointer_v1_add_listener(locked_pointer,
|
||||
&locked_pointer_listener,
|
||||
window);
|
||||
|
||||
w->locked_pointer = locked_pointer;
|
||||
}
|
||||
|
||||
int Wayland_input_lock_pointer(struct SDL_WaylandInput *input)
|
||||
{
|
||||
SDL_VideoDevice *vd = SDL_GetVideoDevice();
|
||||
SDL_VideoData *d = input->display;
|
||||
SDL_Window *window;
|
||||
struct zwp_relative_pointer_v1 *relative_pointer;
|
||||
|
||||
if (!d->relative_pointer_manager)
|
||||
return -1;
|
||||
|
||||
if (!d->pointer_constraints)
|
||||
return -1;
|
||||
|
||||
if (!input->relative_pointer) {
|
||||
relative_pointer =
|
||||
zwp_relative_pointer_manager_v1_get_relative_pointer(
|
||||
d->relative_pointer_manager,
|
||||
input->pointer);
|
||||
zwp_relative_pointer_v1_add_listener(relative_pointer,
|
||||
&relative_pointer_listener,
|
||||
input);
|
||||
input->relative_pointer = relative_pointer;
|
||||
}
|
||||
|
||||
for (window = vd->windows; window; window = window->next)
|
||||
lock_pointer_to_window(window, input);
|
||||
|
||||
d->relative_mouse_mode = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input)
|
||||
{
|
||||
SDL_VideoDevice *vd = SDL_GetVideoDevice();
|
||||
SDL_VideoData *d = input->display;
|
||||
SDL_Window *window;
|
||||
SDL_WindowData *w;
|
||||
|
||||
for (window = vd->windows; window; window = window->next) {
|
||||
w = window->driverdata;
|
||||
if (w->locked_pointer)
|
||||
zwp_locked_pointer_v1_destroy(w->locked_pointer);
|
||||
w->locked_pointer = NULL;
|
||||
}
|
||||
|
||||
zwp_relative_pointer_v1_destroy(input->relative_pointer);
|
||||
input->relative_pointer = NULL;
|
||||
|
||||
d->relative_mouse_mode = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_WAYLAND */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -32,6 +32,15 @@ extern void Wayland_PumpEvents(_THIS);
|
|||
extern void Wayland_display_add_input(SDL_VideoData *d, uint32_t id);
|
||||
extern void Wayland_display_destroy_input(SDL_VideoData *d);
|
||||
|
||||
extern void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id);
|
||||
extern void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d);
|
||||
|
||||
extern int Wayland_input_lock_pointer(struct SDL_WaylandInput *input);
|
||||
extern int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input);
|
||||
|
||||
extern void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id);
|
||||
extern void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d);
|
||||
|
||||
#endif /* _SDL_waylandevents_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -365,7 +365,13 @@ Wayland_WarpMouseGlobal(int x, int y)
|
|||
static int
|
||||
Wayland_SetRelativeMouseMode(SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
SDL_VideoDevice *vd = SDL_GetVideoDevice();
|
||||
SDL_VideoData *data = (SDL_VideoData *) vd->driverdata;
|
||||
|
||||
if (enabled)
|
||||
return Wayland_input_lock_pointer(data->input);
|
||||
else
|
||||
return Wayland_input_unlock_pointer(data->input);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -305,7 +305,10 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
|
|||
} else if (strcmp(interface, "wl_shm") == 0) {
|
||||
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
|
||||
d->cursor_theme = WAYLAND_wl_cursor_theme_load(NULL, 32, d->shm);
|
||||
|
||||
} else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
|
||||
Wayland_display_add_relative_pointer_manager(d, id);
|
||||
} else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) {
|
||||
Wayland_display_add_pointer_constraints(d, id);
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
} else if (strcmp(interface, "qt_touch_extension") == 0) {
|
||||
Wayland_touch_create(d, id);
|
||||
|
@ -395,6 +398,8 @@ Wayland_VideoQuit(_THIS)
|
|||
}
|
||||
|
||||
Wayland_display_destroy_input(data);
|
||||
Wayland_display_destroy_pointer_constraints(data);
|
||||
Wayland_display_destroy_relative_pointer_manager(data);
|
||||
|
||||
if (data->xkb_context) {
|
||||
WAYLAND_xkb_context_unref(data->xkb_context);
|
||||
|
|
|
@ -44,6 +44,8 @@ typedef struct {
|
|||
struct wl_cursor_theme *cursor_theme;
|
||||
struct wl_pointer *pointer;
|
||||
struct wl_shell *shell;
|
||||
struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
|
||||
struct zwp_pointer_constraints_v1 *pointer_constraints;
|
||||
|
||||
EGLDisplay edpy;
|
||||
EGLContext context;
|
||||
|
@ -59,6 +61,8 @@ typedef struct {
|
|||
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
|
||||
|
||||
char *classname;
|
||||
|
||||
int relative_mouse_mode;
|
||||
} SDL_VideoData;
|
||||
|
||||
#endif /* _SDL_waylandvideo_h */
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "../SDL_sysvideo.h"
|
||||
#include "../../events/SDL_windowevents_c.h"
|
||||
#include "../SDL_egl_c.h"
|
||||
#include "SDL_waylandevents_c.h"
|
||||
#include "SDL_waylandwindow.h"
|
||||
#include "SDL_waylandvideo.h"
|
||||
#include "SDL_waylandtouch.h"
|
||||
|
@ -215,6 +216,10 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
|
|||
wl_surface_set_opaque_region(data->surface, region);
|
||||
wl_region_destroy(region);
|
||||
|
||||
if (c->relative_mouse_mode) {
|
||||
Wayland_input_lock_pointer(c->input);
|
||||
}
|
||||
|
||||
WAYLAND_wl_display_flush(c->display);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -39,6 +39,7 @@ typedef struct {
|
|||
struct wl_egl_window *egl_window;
|
||||
struct SDL_WaylandInput *keyboard_device;
|
||||
EGLSurface egl_surface;
|
||||
struct zwp_locked_pointer_v1 *locked_pointer;
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
struct qt_extended_surface *extended_surface;
|
||||
|
|
Loading…
Reference in New Issue