mirror of
https://github.com/libretro/RetroArch
synced 2025-01-31 06:32:48 +00:00
[Wayland] Add mouse grab/lock functionality. (#15103)
* [Wayland] Add mouse grab functionality. Co-authored-by: Colin Kinloch <colin@kinlo.ch>
This commit is contained in:
parent
8d1e575ea6
commit
aaa53da148
@ -421,6 +421,34 @@ static void wl_touch_handle_motion(void *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_relative_motion(void *data,
|
||||||
|
struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1,
|
||||||
|
uint32_t utime_hi, uint32_t utime_lo,
|
||||||
|
wl_fixed_t dx, wl_fixed_t dy,
|
||||||
|
wl_fixed_t dx_unaccel, wl_fixed_t dy_unaccel)
|
||||||
|
{
|
||||||
|
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||||
|
|
||||||
|
wl->input.mouse.delta_x = wl_fixed_to_int(dx);
|
||||||
|
wl->input.mouse.delta_y = wl_fixed_to_int(dy);
|
||||||
|
|
||||||
|
if (wl->locked_pointer)
|
||||||
|
{
|
||||||
|
wl->input.mouse.x += wl->input.mouse.delta_x;
|
||||||
|
wl->input.mouse.y += wl->input.mouse.delta_y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 void wl_touch_handle_frame(void *data, struct wl_touch *wl_touch) { }
|
static void wl_touch_handle_frame(void *data, struct wl_touch *wl_touch) { }
|
||||||
|
|
||||||
static void wl_touch_handle_cancel(void *data, struct wl_touch *wl_touch)
|
static void wl_touch_handle_cancel(void *data, struct wl_touch *wl_touch)
|
||||||
@ -460,6 +488,11 @@ static void wl_seat_handle_capabilities(void *data,
|
|||||||
{
|
{
|
||||||
wl->wl_pointer = wl_seat_get_pointer(seat);
|
wl->wl_pointer = wl_seat_get_pointer(seat);
|
||||||
wl_pointer_add_listener(wl->wl_pointer, &pointer_listener, wl);
|
wl_pointer_add_listener(wl->wl_pointer, &pointer_listener, wl);
|
||||||
|
wl->wl_relative_pointer =
|
||||||
|
zwp_relative_pointer_manager_v1_get_relative_pointer(
|
||||||
|
wl->relative_pointer_manager, wl->wl_pointer);
|
||||||
|
zwp_relative_pointer_v1_add_listener(wl->wl_relative_pointer,
|
||||||
|
&relative_pointer_listener, wl);
|
||||||
}
|
}
|
||||||
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wl->wl_pointer)
|
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wl->wl_pointer)
|
||||||
{
|
{
|
||||||
@ -626,6 +659,17 @@ static void wl_registry_handle_global(void *data, struct wl_registry *reg,
|
|||||||
interface, zxdg_decoration_manager_v1_interface.name))
|
interface, zxdg_decoration_manager_v1_interface.name))
|
||||||
wl->deco_manager = (struct zxdg_decoration_manager_v1*)wl_registry_bind(
|
wl->deco_manager = (struct zxdg_decoration_manager_v1*)wl_registry_bind(
|
||||||
reg, id, &zxdg_decoration_manager_v1_interface, MIN(version, 1));
|
reg, id, &zxdg_decoration_manager_v1_interface, MIN(version, 1));
|
||||||
|
else if (string_is_equal(interface, zwp_pointer_constraints_v1_interface.name))
|
||||||
|
{
|
||||||
|
wl->pointer_constraints = (struct zwp_pointer_constraints_v1*)
|
||||||
|
wl_registry_bind(
|
||||||
|
reg, id, &zwp_pointer_constraints_v1_interface, MIN(version, 1));
|
||||||
|
wl->locked_pointer = NULL;
|
||||||
|
}
|
||||||
|
else if (string_is_equal(interface, zwp_relative_pointer_manager_v1_interface.name))
|
||||||
|
wl->relative_pointer_manager = (struct zwp_relative_pointer_manager_v1*)
|
||||||
|
wl_registry_bind(
|
||||||
|
reg, id, &zwp_relative_pointer_manager_v1_interface, MIN(version, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wl_registry_handle_global_remove(void *data,
|
static void wl_registry_handle_global_remove(void *data,
|
||||||
@ -951,6 +995,15 @@ const struct wl_data_offer_listener data_offer_listener = {
|
|||||||
wl_data_offer_handle_action
|
wl_data_offer_handle_action
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct zwp_relative_pointer_v1_listener relative_pointer_listener = {
|
||||||
|
.relative_motion = handle_relative_motion,
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct zwp_locked_pointer_v1_listener locked_pointer_listener = {
|
||||||
|
.locked = locked_pointer_locked,
|
||||||
|
.unlocked = locked_pointer_unlocked,
|
||||||
|
};
|
||||||
|
|
||||||
void flush_wayland_fd(void *data)
|
void flush_wayland_fd(void *data)
|
||||||
{
|
{
|
||||||
struct pollfd fd = {0};
|
struct pollfd fd = {0};
|
||||||
|
@ -41,6 +41,12 @@
|
|||||||
/* Generated from xdg-decoration-unstable-v1.h */
|
/* Generated from xdg-decoration-unstable-v1.h */
|
||||||
#include "../../gfx/common/wayland/xdg-decoration-unstable-v1.h"
|
#include "../../gfx/common/wayland/xdg-decoration-unstable-v1.h"
|
||||||
|
|
||||||
|
/* Generated from pointer-constraints-unstable-v1.h */
|
||||||
|
#include "../../gfx/common/wayland/pointer-constraints-unstable-v1.h"
|
||||||
|
|
||||||
|
/* Generated from relative-pointer-unstable-v1.h */
|
||||||
|
#include "../../gfx/common/wayland/relative-pointer-unstable-v1.h"
|
||||||
|
|
||||||
#define UDEV_KEY_MAX 0x2ff
|
#define UDEV_KEY_MAX 0x2ff
|
||||||
#define UDEV_MAX_KEYS (UDEV_KEY_MAX + 7) / 8
|
#define UDEV_MAX_KEYS (UDEV_KEY_MAX + 7) / 8
|
||||||
|
|
||||||
@ -138,6 +144,8 @@ typedef struct gfx_ctx_wayland_data
|
|||||||
struct xdg_toplevel *xdg_toplevel;
|
struct xdg_toplevel *xdg_toplevel;
|
||||||
struct wl_keyboard *wl_keyboard;
|
struct wl_keyboard *wl_keyboard;
|
||||||
struct wl_pointer *wl_pointer;
|
struct wl_pointer *wl_pointer;
|
||||||
|
struct zwp_relative_pointer_v1 *wl_relative_pointer;
|
||||||
|
struct zwp_locked_pointer_v1 *locked_pointer;
|
||||||
struct wl_touch *wl_touch;
|
struct wl_touch *wl_touch;
|
||||||
struct wl_seat *seat;
|
struct wl_seat *seat;
|
||||||
struct wl_shm *shm;
|
struct wl_shm *shm;
|
||||||
@ -157,6 +165,8 @@ typedef struct gfx_ctx_wayland_data
|
|||||||
struct zxdg_toplevel_decoration_v1 *deco;
|
struct zxdg_toplevel_decoration_v1 *deco;
|
||||||
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
|
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
|
||||||
struct zwp_idle_inhibitor_v1 *idle_inhibitor;
|
struct zwp_idle_inhibitor_v1 *idle_inhibitor;
|
||||||
|
struct zwp_pointer_constraints_v1 *pointer_constraints;
|
||||||
|
struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
|
||||||
output_info_t *current_output;
|
output_info_t *current_output;
|
||||||
#ifdef HAVE_VULKAN
|
#ifdef HAVE_VULKAN
|
||||||
gfx_ctx_vulkan_data_t vk;
|
gfx_ctx_vulkan_data_t vk;
|
||||||
@ -211,6 +221,10 @@ extern const struct wl_keyboard_listener keyboard_listener;
|
|||||||
|
|
||||||
extern const struct wl_pointer_listener pointer_listener;
|
extern const struct wl_pointer_listener pointer_listener;
|
||||||
|
|
||||||
|
extern const struct zwp_relative_pointer_v1_listener relative_pointer_listener;
|
||||||
|
|
||||||
|
extern const struct zwp_locked_pointer_v1_listener locked_pointer_listener;
|
||||||
|
|
||||||
extern const struct wl_touch_listener touch_listener;
|
extern const struct wl_touch_listener touch_listener;
|
||||||
|
|
||||||
extern const struct wl_seat_listener seat_listener;
|
extern const struct wl_seat_listener seat_listener;
|
||||||
|
@ -73,8 +73,6 @@ static void input_wl_poll(void *data)
|
|||||||
|
|
||||||
flush_wayland_fd(wl);
|
flush_wayland_fd(wl);
|
||||||
|
|
||||||
wl->mouse.delta_x = wl->mouse.x - wl->mouse.last_x;
|
|
||||||
wl->mouse.delta_y = wl->mouse.y - wl->mouse.last_y;
|
|
||||||
wl->mouse.last_x = wl->mouse.x;
|
wl->mouse.last_x = wl->mouse.x;
|
||||||
wl->mouse.last_y = wl->mouse.y;
|
wl->mouse.last_y = wl->mouse.y;
|
||||||
|
|
||||||
@ -84,6 +82,27 @@ static void input_wl_poll(void *data)
|
|||||||
wl->mouse.delta_y = 0;
|
wl->mouse.delta_y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wl->gfx->locked_pointer)
|
||||||
|
{
|
||||||
|
/* Get effective 'absolute' pointer location
|
||||||
|
* (last position + delta, bounded by current
|
||||||
|
* application window dimensions) */
|
||||||
|
wl->mouse.x += wl->mouse.delta_x;
|
||||||
|
wl->mouse.y += wl->mouse.delta_y;
|
||||||
|
|
||||||
|
/* Clamp X */
|
||||||
|
if (wl->mouse.x < 0)
|
||||||
|
wl->mouse.x = 0;
|
||||||
|
if (wl->mouse.x >= wl->gfx->buffer_width)
|
||||||
|
wl->mouse.x = (wl->gfx->buffer_width - 1);
|
||||||
|
|
||||||
|
/* Clamp Y */
|
||||||
|
if (wl->mouse.y < 0)
|
||||||
|
wl->mouse.y = 0;
|
||||||
|
if (wl->mouse.y >= wl->gfx->buffer_height)
|
||||||
|
wl->mouse.y = (wl->gfx->buffer_height - 1);
|
||||||
|
}
|
||||||
|
|
||||||
for (id = 0; id < MAX_TOUCHES; id++)
|
for (id = 0; id < MAX_TOUCHES; id++)
|
||||||
{
|
{
|
||||||
if (wayland_context_gettouchpos(wl->gfx, id, &touch_x, &touch_y))
|
if (wayland_context_gettouchpos(wl->gfx, id, &touch_x, &touch_y))
|
||||||
@ -154,6 +173,7 @@ static int16_t input_wl_state(
|
|||||||
unsigned id)
|
unsigned id)
|
||||||
{
|
{
|
||||||
input_ctx_wayland_data_t *wl = (input_ctx_wayland_data_t*)data;
|
input_ctx_wayland_data_t *wl = (input_ctx_wayland_data_t*)data;
|
||||||
|
int x, y = 0;
|
||||||
|
|
||||||
switch (device)
|
switch (device)
|
||||||
{
|
{
|
||||||
@ -267,10 +287,14 @@ static int16_t input_wl_state(
|
|||||||
wl->mouse.wd = false;
|
wl->mouse.wd = false;
|
||||||
return state;
|
return state;
|
||||||
case RETRO_DEVICE_ID_MOUSE_X:
|
case RETRO_DEVICE_ID_MOUSE_X:
|
||||||
return screen ? wl->mouse.x : wl->mouse.delta_x;
|
x = screen ? wl->mouse.x : wl->mouse.delta_x;
|
||||||
case RETRO_DEVICE_ID_MOUSE_Y:
|
wl->mouse.delta_x = 0;
|
||||||
return screen ? wl->mouse.y : wl->mouse.delta_y;
|
return x;
|
||||||
case RETRO_DEVICE_ID_MOUSE_LEFT:
|
case RETRO_DEVICE_ID_MOUSE_Y:
|
||||||
|
y = screen ? wl->mouse.y : wl->mouse.delta_y;
|
||||||
|
wl->mouse.delta_y = 0;
|
||||||
|
return y;
|
||||||
|
case RETRO_DEVICE_ID_MOUSE_LEFT:
|
||||||
return wl->mouse.left;
|
return wl->mouse.left;
|
||||||
case RETRO_DEVICE_ID_MOUSE_RIGHT:
|
case RETRO_DEVICE_ID_MOUSE_RIGHT:
|
||||||
return wl->mouse.right;
|
return wl->mouse.right;
|
||||||
@ -406,10 +430,25 @@ static uint64_t input_wl_get_capabilities(void *data)
|
|||||||
|
|
||||||
static void input_wl_grab_mouse(void *data, bool state)
|
static void input_wl_grab_mouse(void *data, bool state)
|
||||||
{
|
{
|
||||||
/* This function does nothing but registering it is necessary for allowing
|
input_ctx_wayland_data_t *wl = (input_ctx_wayland_data_t*)data;
|
||||||
* mouse-grab toggling. */
|
|
||||||
(void)data;
|
gfx_ctx_wayland_data_t *gfx = (gfx_ctx_wayland_data_t*)wl->gfx;
|
||||||
(void)state;
|
|
||||||
|
if (gfx->pointer_constraints)
|
||||||
|
{
|
||||||
|
if (state)
|
||||||
|
{
|
||||||
|
gfx->locked_pointer = zwp_pointer_constraints_v1_lock_pointer(gfx->pointer_constraints,
|
||||||
|
gfx->surface, gfx->wl_pointer, NULL, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
|
||||||
|
zwp_locked_pointer_v1_add_listener(gfx->locked_pointer,
|
||||||
|
&locked_pointer_listener, gfx);
|
||||||
|
}
|
||||||
|
else if (gfx->locked_pointer)
|
||||||
|
{
|
||||||
|
zwp_locked_pointer_v1_destroy(gfx->locked_pointer);
|
||||||
|
gfx->locked_pointer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input_driver_t input_wayland = {
|
input_driver_t input_wayland = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user