mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-27 10:10:57 +00:00
Add zxdg_shell_v6 and wl_shell ad fallback interfaces
This commit is contained in:
parent
eda342262b
commit
9b0bad5d9f
@ -866,6 +866,7 @@ ifeq ($(HAVE_WAYLAND), 1)
|
||||
OBJ += gfx/drivers_context/wayland_ctx.o \
|
||||
input/drivers/wayland_input.o \
|
||||
gfx/common/wayland/xdg-shell.o \
|
||||
gfx/common/wayland/xdg-shell-unstable-v6.o \
|
||||
gfx/common/wayland/idle-inhibit-unstable-v1.o
|
||||
ifeq ($(HAVE_EGL), 1)
|
||||
LIBS += $(EGL_LIBS)
|
||||
|
@ -7,6 +7,10 @@ if [ ! -d $OUTPUT ]; then
|
||||
mkdir $OUTPUT
|
||||
fi
|
||||
|
||||
#Generate xdg-shell_v6 header and .c files
|
||||
$WAYSCAN client-header $WAYLAND_PROTOS/unstable/xdg-shell/xdg-shell-unstable-v6.xml $OUTPUT/xdg-shell-unstable-v6.h
|
||||
$WAYSCAN code $WAYLAND_PROTOS/unstable/xdg-shell/xdg-shell-unstable-v6.xml $OUTPUT/xdg-shell-unstable-v6.c
|
||||
|
||||
#Generate xdg-shell header and .c files
|
||||
$WAYSCAN client-header $WAYLAND_PROTOS/stable/xdg-shell/xdg-shell.xml $OUTPUT/xdg-shell.h
|
||||
$WAYSCAN code $WAYLAND_PROTOS/stable/xdg-shell/xdg-shell.xml $OUTPUT/xdg-shell.c
|
||||
|
@ -50,6 +50,9 @@
|
||||
/* Generated from idle-inhibit-unstable-v1.xml */
|
||||
#include "../common/wayland/idle-inhibit-unstable-v1.h"
|
||||
|
||||
/* Generated from xdg-shell-unstable-v6.xml */
|
||||
#include "../common/wayland/xdg-shell-unstable-v6.h"
|
||||
|
||||
/* Generated from xdg-shell.xml */
|
||||
#include "../common/wayland/xdg-shell.h"
|
||||
|
||||
@ -87,8 +90,13 @@ typedef struct gfx_ctx_wayland_data
|
||||
struct wl_registry *registry;
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_surface *surface;
|
||||
struct wl_shell_surface *shell_surf;
|
||||
struct wl_shell *shell;
|
||||
struct zxdg_surface_v6 *zxdg_surface;
|
||||
struct zxdg_shell_v6 *zxdg_shell;
|
||||
struct zxdg_toplevel_v6 *zxdg_toplevel;
|
||||
struct xdg_surface *xdg_surface;
|
||||
struct xdg_wm_base *shell;
|
||||
struct xdg_wm_base *xdg_shell;
|
||||
struct xdg_toplevel *xdg_toplevel;
|
||||
struct wl_keyboard *wl_keyboard;
|
||||
struct wl_pointer *wl_pointer;
|
||||
@ -314,8 +322,14 @@ static void pointer_handle_button(void *data,
|
||||
{
|
||||
wl->input.mouse.left = true;
|
||||
|
||||
if (BIT_GET(wl->input.key_state, KEY_LEFTALT) && wl->xdg_toplevel)
|
||||
xdg_toplevel_move(wl->xdg_toplevel, wl->seat, serial);
|
||||
if (BIT_GET(wl->input.key_state, KEY_LEFTALT) && wl->xdg_toplevel) {
|
||||
if (wl->xdg_toplevel)
|
||||
xdg_toplevel_move(wl->xdg_toplevel, wl->seat, serial);
|
||||
else if (wl->zxdg_toplevel)
|
||||
zxdg_toplevel_v6_move(wl->zxdg_toplevel, wl->seat, serial);
|
||||
else if (wl->shell)
|
||||
wl_shell_surface_move(wl->shell_surf, wl->seat, serial);
|
||||
}
|
||||
}
|
||||
else if (button == BTN_RIGHT)
|
||||
wl->input.mouse.right = true;
|
||||
@ -580,7 +594,7 @@ static void handle_toplevel_config(void *data, struct xdg_toplevel *toplevel,
|
||||
|
||||
wl->fullscreen = false;
|
||||
wl->maximized = false;
|
||||
enum xdg_toplevel_state *state;
|
||||
const uint32_t *state;
|
||||
wl_array_for_each(state, states) {
|
||||
switch (*state) {
|
||||
case XDG_TOPLEVEL_STATE_FULLSCREEN:
|
||||
@ -594,12 +608,7 @@ static void handle_toplevel_config(void *data, struct xdg_toplevel *toplevel,
|
||||
break;
|
||||
case XDG_TOPLEVEL_STATE_ACTIVATED:
|
||||
wl->activated = true;
|
||||
break;
|
||||
case XDG_TOPLEVEL_STATE_TILED_TOP:
|
||||
case XDG_TOPLEVEL_STATE_TILED_LEFT:
|
||||
case XDG_TOPLEVEL_STATE_TILED_RIGHT:
|
||||
case XDG_TOPLEVEL_STATE_TILED_BOTTOM:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (width > 0 && height > 0) {
|
||||
@ -627,6 +636,111 @@ static const struct xdg_toplevel_listener xdg_toplevel_listener = {
|
||||
handle_toplevel_close,
|
||||
};
|
||||
|
||||
static void zxdg_shell_ping(void *data, struct zxdg_shell_v6 *shell, uint32_t serial)
|
||||
{
|
||||
zxdg_shell_v6_pong(shell, serial);
|
||||
}
|
||||
|
||||
static const struct zxdg_shell_v6_listener zxdg_shell_v6_listener = {
|
||||
zxdg_shell_ping,
|
||||
};
|
||||
|
||||
static void handle_zxdg_surface_config(void *data, struct zxdg_surface_v6 *surface,
|
||||
uint32_t serial)
|
||||
{
|
||||
zxdg_surface_v6_ack_configure(surface, serial);
|
||||
}
|
||||
|
||||
static const struct zxdg_surface_v6_listener zxdg_surface_v6_listener = {
|
||||
handle_zxdg_surface_config,
|
||||
};
|
||||
|
||||
static void handle_zxdg_toplevel_config(void *data, struct zxdg_toplevel_v6 *toplevel,
|
||||
int32_t width, int32_t height, struct wl_array *states)
|
||||
{
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
|
||||
wl->fullscreen = false;
|
||||
wl->maximized = false;
|
||||
const uint32_t *state;
|
||||
wl_array_for_each(state, states) {
|
||||
switch (*state) {
|
||||
case XDG_TOPLEVEL_STATE_FULLSCREEN:
|
||||
wl->fullscreen = true;
|
||||
break;
|
||||
case XDG_TOPLEVEL_STATE_MAXIMIZED:
|
||||
wl->maximized = true;
|
||||
break;
|
||||
case XDG_TOPLEVEL_STATE_RESIZING:
|
||||
wl->resize = true;
|
||||
break;
|
||||
case XDG_TOPLEVEL_STATE_ACTIVATED:
|
||||
wl->activated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (width > 0 && height > 0) {
|
||||
wl->prev_width = width;
|
||||
wl->prev_height = height;
|
||||
wl->width = width;
|
||||
wl->height = height;
|
||||
}
|
||||
else {
|
||||
wl->width = wl->prev_width;
|
||||
wl->height = wl->prev_height;
|
||||
}
|
||||
|
||||
wl->configured = false;
|
||||
}
|
||||
|
||||
static void handle_zxdg_toplevel_close(void *data, struct zxdg_toplevel_v6 *zxdg_toplevel)
|
||||
{
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
BIT_SET(wl->input.key_state, KEY_ESC);
|
||||
}
|
||||
|
||||
static const struct zxdg_toplevel_v6_listener zxdg_toplevel_v6_listener = {
|
||||
handle_zxdg_toplevel_config,
|
||||
handle_zxdg_toplevel_close,
|
||||
};
|
||||
|
||||
static void shell_surface_handle_ping(void *data,
|
||||
struct wl_shell_surface *shell_surface,
|
||||
uint32_t serial)
|
||||
{
|
||||
(void)data;
|
||||
wl_shell_surface_pong(shell_surface, serial);
|
||||
}
|
||||
|
||||
static void shell_surface_handle_configure(void *data,
|
||||
struct wl_shell_surface *shell_surface,
|
||||
uint32_t edges, int32_t width, int32_t height)
|
||||
{
|
||||
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
|
||||
|
||||
(void)shell_surface;
|
||||
(void)edges;
|
||||
|
||||
wl->width = wl->buffer_scale * width;
|
||||
wl->height = wl->buffer_scale * height;
|
||||
|
||||
RARCH_LOG("[Wayland]: Surface configure: %u x %u.\n",
|
||||
wl->width, wl->height);
|
||||
}
|
||||
|
||||
static void shell_surface_handle_popup_done(void *data,
|
||||
struct wl_shell_surface *shell_surface)
|
||||
{
|
||||
(void)data;
|
||||
(void)shell_surface;
|
||||
}
|
||||
|
||||
static const struct wl_shell_surface_listener shell_surface_listener = {
|
||||
shell_surface_handle_ping,
|
||||
shell_surface_handle_configure,
|
||||
shell_surface_handle_popup_done,
|
||||
};
|
||||
|
||||
static void display_handle_geometry(void *data,
|
||||
struct wl_output *output,
|
||||
int x, int y,
|
||||
@ -718,8 +832,14 @@ static void registry_handle_global(void *data, struct wl_registry *reg,
|
||||
wl_display_roundtrip(wl->input.dpy);
|
||||
}
|
||||
else if (string_is_equal(interface, "xdg_wm_base"))
|
||||
wl->shell = (struct xdg_wm_base*)
|
||||
wl->xdg_shell = (struct xdg_wm_base*)
|
||||
wl_registry_bind(reg, id, &xdg_wm_base_interface, 1);
|
||||
else if (string_is_equal(interface, "zxdg_shell_v6"))
|
||||
wl->zxdg_shell = (struct zxdg_shell_v6*)
|
||||
wl_registry_bind(reg, id, &zxdg_shell_v6_interface, 1);
|
||||
else if (string_is_equal(interface, "wl_shell"))
|
||||
wl->shell = (struct wl_shell*)
|
||||
wl_registry_bind(reg, id, &wl_shell_interface, 1);
|
||||
else if (string_is_equal(interface, "wl_shm"))
|
||||
wl->shm = (struct wl_shm*)wl_registry_bind(reg, id, &wl_shm_interface, 1);
|
||||
else if (string_is_equal(interface, "wl_seat"))
|
||||
@ -802,16 +922,28 @@ static void gfx_ctx_wl_destroy_resources(gfx_ctx_wayland_data_t *wl)
|
||||
|
||||
if (wl->seat)
|
||||
wl_seat_destroy(wl->seat);
|
||||
if (wl->xdg_shell)
|
||||
xdg_wm_base_destroy(wl->xdg_shell);
|
||||
if (wl->zxdg_shell)
|
||||
zxdg_shell_v6_destroy(wl->zxdg_shell);
|
||||
if (wl->shell)
|
||||
xdg_wm_base_destroy(wl->shell);
|
||||
wl_shell_destroy(wl->shell);
|
||||
if (wl->compositor)
|
||||
wl_compositor_destroy(wl->compositor);
|
||||
if (wl->registry)
|
||||
wl_registry_destroy(wl->registry);
|
||||
if (wl->xdg_surface)
|
||||
xdg_surface_destroy(wl->xdg_surface);
|
||||
if (wl->zxdg_surface)
|
||||
zxdg_surface_v6_destroy(wl->zxdg_surface);
|
||||
if (wl->surface)
|
||||
wl_surface_destroy(wl->surface);
|
||||
if (wl->xdg_toplevel)
|
||||
xdg_toplevel_destroy(wl->xdg_toplevel);
|
||||
if (wl->zxdg_toplevel)
|
||||
zxdg_toplevel_v6_destroy(wl->zxdg_toplevel);
|
||||
if (wl->shell_surf)
|
||||
wl_shell_surface_destroy(wl->shell_surf);
|
||||
if (wl->idle_inhibit_manager)
|
||||
zwp_idle_inhibit_manager_v1_destroy(wl->idle_inhibit_manager);
|
||||
if (wl->idle_inhibitor)
|
||||
@ -826,12 +958,17 @@ static void gfx_ctx_wl_destroy_resources(gfx_ctx_wayland_data_t *wl)
|
||||
#ifdef HAVE_EGL
|
||||
wl->win = NULL;
|
||||
#endif
|
||||
wl->shell = NULL;
|
||||
wl->xdg_shell = NULL;
|
||||
wl->zxdg_shell = NULL;
|
||||
wl->shell = NULL;
|
||||
wl->compositor = NULL;
|
||||
wl->registry = NULL;
|
||||
wl->input.dpy = NULL;
|
||||
wl->xdg_surface = NULL;
|
||||
wl->surface = NULL;
|
||||
wl->xdg_toplevel = NULL;
|
||||
wl->zxdg_toplevel = NULL;
|
||||
wl->shell_surf = NULL;
|
||||
|
||||
wl->width = 0;
|
||||
wl->height = 0;
|
||||
@ -952,8 +1089,14 @@ static void gfx_ctx_wl_update_title(void *data, void *data2)
|
||||
|
||||
video_driver_get_window_title(title, sizeof(title));
|
||||
|
||||
if (wl && title[0])
|
||||
xdg_toplevel_set_title (wl->xdg_toplevel, title);
|
||||
if (wl && title[0]) {
|
||||
if (wl->xdg_toplevel)
|
||||
xdg_toplevel_set_title(wl->xdg_toplevel, title);
|
||||
else if (wl->zxdg_toplevel)
|
||||
zxdg_toplevel_v6_set_title(wl->zxdg_toplevel, title);
|
||||
else if (wl->shell_surf)
|
||||
wl_shell_surface_set_title(wl->shell_surf, title);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1113,10 +1256,20 @@ static void *gfx_ctx_wl_init(video_frame_info_t *video_info, void *video_driver)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!wl->shell)
|
||||
if (!wl->xdg_shell)
|
||||
{
|
||||
RARCH_ERR("[Wayland]: Failed to create shell.\n");
|
||||
goto error;
|
||||
RARCH_LOG("[Wayland]: Using zxdg_shell_v6 interface.\n");
|
||||
}
|
||||
|
||||
if (!wl->xdg_shell && !wl->zxdg_shell)
|
||||
{
|
||||
RARCH_WARN("[Wayland]: Fallback to deprecated wl_shell interface!.\n");
|
||||
}
|
||||
|
||||
if (!wl->xdg_shell && !wl->zxdg_shell && !wl->shell)
|
||||
{
|
||||
RARCH_ERR("[Wayland]: Failed to create shell.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!wl->idle_inhibit_manager)
|
||||
@ -1346,25 +1499,55 @@ static bool gfx_ctx_wl_set_video_mode(void *data,
|
||||
break;
|
||||
}
|
||||
|
||||
wl->xdg_surface = xdg_wm_base_get_xdg_surface(wl->shell, wl->surface);
|
||||
xdg_surface_add_listener(wl->xdg_surface, &xdg_surface_listener, wl);
|
||||
|
||||
wl->xdg_toplevel = xdg_surface_get_toplevel(wl->xdg_surface);
|
||||
xdg_toplevel_add_listener(wl->xdg_toplevel, &xdg_toplevel_listener, wl);
|
||||
|
||||
xdg_toplevel_set_app_id (wl->xdg_toplevel, "RetroArch");
|
||||
xdg_toplevel_set_title (wl->xdg_toplevel, "RetroArch");
|
||||
|
||||
/* Waiting for xdg_toplevel to be configured before starting to draw */
|
||||
wl_surface_commit(wl->surface);
|
||||
wl->configured = true;
|
||||
|
||||
while (wl->configured)
|
||||
wl_display_dispatch(wl->input.dpy);
|
||||
|
||||
/* Waiting for the "initial" set of globals to appear */
|
||||
wl_display_roundtrip(wl->input.dpy);
|
||||
xdg_wm_base_add_listener(wl->shell, &xdg_shell_listener, NULL);
|
||||
if (wl->xdg_shell) {
|
||||
wl->xdg_surface = xdg_wm_base_get_xdg_surface(wl->xdg_shell, wl->surface);
|
||||
xdg_surface_add_listener(wl->xdg_surface, &xdg_surface_listener, wl);
|
||||
|
||||
wl->xdg_toplevel = xdg_surface_get_toplevel(wl->xdg_surface);
|
||||
xdg_toplevel_add_listener(wl->xdg_toplevel, &xdg_toplevel_listener, wl);
|
||||
|
||||
xdg_toplevel_set_app_id(wl->xdg_toplevel, "RetroArch");
|
||||
xdg_toplevel_set_title(wl->xdg_toplevel, "RetroArch");
|
||||
|
||||
/* Waiting for xdg_toplevel to be configured before starting to draw */
|
||||
wl_surface_commit(wl->surface);
|
||||
wl->configured = true;
|
||||
|
||||
while (wl->configured) {
|
||||
wl_display_dispatch(wl->input.dpy);
|
||||
}
|
||||
/* Waiting for the "initial" set of globals to appear */
|
||||
wl_display_roundtrip(wl->input.dpy);
|
||||
xdg_wm_base_add_listener(wl->xdg_shell, &xdg_shell_listener, NULL);
|
||||
} else if (wl->zxdg_shell) {
|
||||
wl->zxdg_surface = zxdg_shell_v6_get_xdg_surface(wl->zxdg_shell, wl->surface);
|
||||
zxdg_surface_v6_add_listener(wl->zxdg_surface, &zxdg_surface_v6_listener, wl);
|
||||
|
||||
wl->zxdg_toplevel = zxdg_surface_v6_get_toplevel(wl->zxdg_surface);
|
||||
zxdg_toplevel_v6_add_listener(wl->zxdg_toplevel, &zxdg_toplevel_v6_listener, wl);
|
||||
|
||||
zxdg_toplevel_v6_set_app_id(wl->zxdg_toplevel, "RetroArch");
|
||||
zxdg_toplevel_v6_set_title(wl->zxdg_toplevel, "RetroArch");
|
||||
|
||||
/* Waiting for xdg_toplevel to be configured before starting to draw */
|
||||
wl_surface_commit(wl->surface);
|
||||
wl->configured = true;
|
||||
|
||||
while (wl->configured) {
|
||||
wl_display_dispatch(wl->input.dpy);
|
||||
}
|
||||
/* Waiting for the "initial" set of globals to appear */
|
||||
wl_display_roundtrip(wl->input.dpy);
|
||||
zxdg_shell_v6_add_listener(wl->zxdg_shell, &zxdg_shell_v6_listener, NULL);
|
||||
} else if (wl->shell) {
|
||||
wl->shell_surf = wl_shell_get_shell_surface(wl->shell, wl->surface);
|
||||
|
||||
wl_shell_surface_add_listener(wl->shell_surf, &shell_surface_listener, wl);
|
||||
wl_shell_surface_set_toplevel(wl->shell_surf);
|
||||
wl_shell_surface_set_class(wl->shell_surf, "RetroArch");
|
||||
wl_shell_surface_set_title(wl->shell_surf, "RetroArch");
|
||||
}
|
||||
|
||||
|
||||
switch (wl_api)
|
||||
{
|
||||
@ -1389,8 +1572,16 @@ static bool gfx_ctx_wl_set_video_mode(void *data,
|
||||
break;
|
||||
}
|
||||
|
||||
if (fullscreen)
|
||||
xdg_toplevel_set_fullscreen(wl->xdg_toplevel, NULL);
|
||||
if (fullscreen) {
|
||||
if (wl->xdg_toplevel) {
|
||||
xdg_toplevel_set_fullscreen(wl->xdg_toplevel, NULL);
|
||||
} else if (wl->zxdg_toplevel) {
|
||||
zxdg_toplevel_v6_set_fullscreen(wl->zxdg_toplevel, NULL);
|
||||
} else if (wl->shell) {
|
||||
wl_shell_surface_set_fullscreen(wl->shell_surf,
|
||||
WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
flush_wayland_fd(&wl->input);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user