Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,288 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matti=20Lehtim=C3=A4ki?= <matti.lehtimaki@jolla.com>
Date: Wed, 20 Apr 2022 18:03:42 +0300
Subject: [PATCH] wayland: Bring back wl_shell support
---
include/SDL_syswm.h | 2 +-
src/video/wayland/SDL_waylanddyn.h | 2 +
src/video/wayland/SDL_waylandevents.c | 8 +++
src/video/wayland/SDL_waylandsym.h | 2 +
src/video/wayland/SDL_waylandvideo.c | 7 ++
src/video/wayland/SDL_waylandvideo.h | 1 +
src/video/wayland/SDL_waylandwindow.c | 95 +++++++++++++++++++++++++++
src/video/wayland/SDL_waylandwindow.h | 1 +
8 files changed, 117 insertions(+), 1 deletion(-)
diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h
index 7b8bd6ef996571bbba2e5f1e139a0c9292c88146..671a26ee945bdac99de9f07b57aef9cc893f4cec 100644
--- a/include/SDL_syswm.h
+++ b/include/SDL_syswm.h
@@ -294,7 +294,7 @@ struct SDL_SysWMinfo
{
struct wl_display *display; /**< Wayland display */
struct wl_surface *surface; /**< Wayland surface */
- void *shell_surface; /**< DEPRECATED Wayland shell_surface (window manager handle) */
+ struct wl_shell_surface *shell_surface; /**< DEPRECATED Wayland shell_surface (window manager handle) */
struct wl_egl_window *egl_window; /**< Wayland EGL window (native window) */
struct xdg_surface *xdg_surface; /**< Wayland xdg surface (window manager handle) */
struct xdg_toplevel *xdg_toplevel; /**< Wayland xdg toplevel role */
diff --git a/src/video/wayland/SDL_waylanddyn.h b/src/video/wayland/SDL_waylanddyn.h
index 6feb343912b15a6a9360a11b66a08c0c4e36f882..2c93149cd2dcbff5a69c20606c028aa13905dced 100644
--- a/src/video/wayland/SDL_waylanddyn.h
+++ b/src/video/wayland/SDL_waylanddyn.h
@@ -111,11 +111,13 @@ void SDL_WAYLAND_UnloadSymbols(void);
#define wl_shm_pool_interface (*WAYLAND_wl_shm_pool_interface)
#define wl_buffer_interface (*WAYLAND_wl_buffer_interface)
#define wl_registry_interface (*WAYLAND_wl_registry_interface)
+#define wl_shell_surface_interface (*WAYLAND_wl_shell_surface_interface)
#define wl_region_interface (*WAYLAND_wl_region_interface)
#define wl_pointer_interface (*WAYLAND_wl_pointer_interface)
#define wl_keyboard_interface (*WAYLAND_wl_keyboard_interface)
#define wl_compositor_interface (*WAYLAND_wl_compositor_interface)
#define wl_output_interface (*WAYLAND_wl_output_interface)
+#define wl_shell_interface (*WAYLAND_wl_shell_interface)
#define wl_shm_interface (*WAYLAND_wl_shm_interface)
#define wl_data_device_interface (*WAYLAND_wl_data_device_interface)
#define wl_data_offer_interface (*WAYLAND_wl_data_offer_interface)
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index a8382812ab149c4377441d46a693f736f5430cad..45d679abdafb94708e478745d4f1db57922c37b7 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -518,6 +518,10 @@ static SDL_bool ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
input->seat,
serial);
}
+ } else {
+ if (window_data->shell_surface.wl) {
+ wl_shell_surface_move(window_data->shell_surface.wl, input->seat, serial);
+ }
}
return SDL_TRUE;
@@ -543,6 +547,10 @@ static SDL_bool ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
serial,
directions[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
}
+ } else {
+ if (window_data->shell_surface.wl) {
+ wl_shell_surface_resize(window_data->shell_surface.wl, input->seat, serial, directions[rc - SDL_HITTEST_RESIZE_TOPLEFT]);
+ }
}
return SDL_TRUE;
diff --git a/src/video/wayland/SDL_waylandsym.h b/src/video/wayland/SDL_waylandsym.h
index 1b02b01c6691bd2df30508ab88bbd990586594d0..27ff34a31a77c970300790697204594d24e11a1f 100644
--- a/src/video/wayland/SDL_waylandsym.h
+++ b/src/video/wayland/SDL_waylandsym.h
@@ -101,11 +101,13 @@ SDL_WAYLAND_INTERFACE(wl_surface_interface)
SDL_WAYLAND_INTERFACE(wl_shm_pool_interface)
SDL_WAYLAND_INTERFACE(wl_buffer_interface)
SDL_WAYLAND_INTERFACE(wl_registry_interface)
+SDL_WAYLAND_INTERFACE(wl_shell_surface_interface)
SDL_WAYLAND_INTERFACE(wl_region_interface)
SDL_WAYLAND_INTERFACE(wl_pointer_interface)
SDL_WAYLAND_INTERFACE(wl_keyboard_interface)
SDL_WAYLAND_INTERFACE(wl_compositor_interface)
SDL_WAYLAND_INTERFACE(wl_output_interface)
+SDL_WAYLAND_INTERFACE(wl_shell_interface)
SDL_WAYLAND_INTERFACE(wl_shm_interface)
SDL_WAYLAND_INTERFACE(wl_data_device_interface)
SDL_WAYLAND_INTERFACE(wl_data_source_interface)
diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
index 2cae471792cd692129f193fac2100d7d98ab6705..70e9d7306a8fcc60a4b8b1a9289c18f88a8de990 100644
--- a/src/video/wayland/SDL_waylandvideo.c
+++ b/src/video/wayland/SDL_waylandvideo.c
@@ -846,6 +846,8 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint
} else if (SDL_strcmp(interface, "xdg_wm_base") == 0) {
d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, SDL_min(version, 3));
xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL);
+ } else if (SDL_strcmp(interface, "wl_shell") == 0) {
+ d->shell.wl = wl_registry_bind(d->registry, id, &wl_shell_interface, 1);
} else if (SDL_strcmp(interface, "wl_shm") == 0) {
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
} else if (SDL_strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
@@ -1097,6 +1099,11 @@ static void Wayland_VideoCleanup(_THIS)
data->shm = NULL;
}
+ if (data->shell.wl) {
+ wl_shell_destroy(data->shell.wl);
+ data->shell.wl = NULL;
+ }
+
if (data->shell.xdg) {
xdg_wm_base_destroy(data->shell.xdg);
data->shell.xdg = NULL;
diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h
index b7b3348c6d4d9285971d5a2416f7d123f303c7f8..e57ab2bd21a3064c257d704b4912c22d5c49074e 100644
--- a/src/video/wayland/SDL_waylandvideo.h
+++ b/src/video/wayland/SDL_waylandvideo.h
@@ -64,6 +64,7 @@ typedef struct
struct
{
struct xdg_wm_base *xdg;
+ struct wl_shell *wl;
#ifdef HAVE_LIBDECOR_H
struct libdecor *libdecor;
#endif
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index 08df3638c2e795ecdf4cd5f4972bd5d4f866653d..4cb20afbda9aef1edad59b3cf2bd73a7f6e3d289 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -446,6 +446,20 @@ static void SetFullscreen(SDL_Window *window, struct wl_output *output)
} else {
xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel);
}
+ } else {
+ if (wind->shell_surface.wl == NULL) {
+ return; /* Can't do anything yet, wait for ShowWindow */
+ }
+
+ wl_surface_commit(wind->surface);
+
+ if (output) {
+ wl_shell_surface_set_fullscreen(wind->shell_surface.wl,
+ WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
+ 0, output);
+ } else {
+ wl_shell_surface_set_toplevel(wind->shell_surface.wl);
+ }
}
}
@@ -541,6 +555,62 @@ static const struct wl_callback_listener gles_swap_frame_listener = {
static void Wayland_HandleResize(SDL_Window *window, int width, int height, float scale);
+/* On modern desktops, we probably will use the xdg-shell protocol instead
+ of wl_shell, but wl_shell might be useful on older Wayland installs that
+ don't have the newer protocol, or embedded things that don't have a full
+ window manager. */
+
+static void
+handle_ping_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface,
+ uint32_t serial)
+{
+ wl_shell_surface_pong(shell_surface, serial);
+}
+
+static void
+handle_configure_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface,
+ uint32_t edges, int32_t width, int32_t height)
+{
+ SDL_WindowData *wind = (SDL_WindowData *)data;
+ SDL_Window *window = wind->sdlwindow;
+
+ /* wl_shell_surface spec states that this is a suggestion.
+ Ignore if less than or greater than max/min size. */
+
+ if (width == 0 || height == 0) {
+ return;
+ }
+
+ if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+ if ((window->flags & SDL_WINDOW_RESIZABLE)) {
+ if (window->max_w > 0) {
+ width = SDL_min(width, window->max_w);
+ }
+ width = SDL_max(width, window->min_w);
+
+ if (window->max_h > 0) {
+ height = SDL_min(height, window->max_h);
+ }
+ height = SDL_max(height, window->min_h);
+ } else {
+ return;
+ }
+ }
+
+ Wayland_HandleResize(window, width, height, wind->scale_factor);
+}
+
+static void
+handle_popup_done_wl_shell_surface(void *data, struct wl_shell_surface *shell_surface)
+{
+}
+
+static const struct wl_shell_surface_listener shell_surface_listener_wl = {
+ handle_ping_wl_shell_surface,
+ handle_configure_wl_shell_surface,
+ handle_popup_done_wl_shell_surface
+};
+
static void handle_configure_xdg_shell_surface(void *data, struct xdg_surface *xdg, uint32_t serial)
{
SDL_WindowData *wind = (SDL_WindowData *)data;
@@ -1374,6 +1444,11 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname);
xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data);
}
+ } else {
+ data->shell_surface.wl = wl_shell_get_shell_surface(c->shell.wl, data->surface);
+ wl_shell_surface_set_class(data->shell_surface.wl, c->classname);
+ wl_shell_surface_set_user_data(data->shell_surface.wl, data);
+ wl_shell_surface_add_listener(data->shell_surface.wl, &shell_surface_listener_wl, data);
}
/* Restore state that was set prior to this call */
@@ -1549,6 +1624,11 @@ void Wayland_HideWindow(_THIS, SDL_Window *window)
xdg_surface_destroy(wind->shell_surface.xdg.surface);
wind->shell_surface.xdg.surface = NULL;
}
+ } else {
+ if (wind->shell_surface.wl) {
+ wl_shell_surface_destroy(wind->shell_surface.wl);
+ wind->shell_surface.wl = NULL;
+ }
}
/*
@@ -1829,6 +1909,11 @@ void Wayland_RestoreWindow(_THIS, SDL_Window *window)
return; /* Can't do anything yet, wait for ShowWindow */
}
xdg_toplevel_unset_maximized(wind->shell_surface.xdg.roleobj.toplevel);
+ } else {
+ if (wind->shell_surface.wl == NULL) {
+ return; /* Can't do anything yet, wait for ShowWindow */
+ }
+ wl_shell_surface_set_toplevel(wind->shell_surface.wl);
}
WAYLAND_wl_display_roundtrip(viddata->display);
@@ -1908,6 +1993,11 @@ void Wayland_MaximizeWindow(_THIS, SDL_Window *window)
return; /* Can't do anything yet, wait for ShowWindow */
}
xdg_toplevel_set_maximized(wind->shell_surface.xdg.roleobj.toplevel);
+ } else {
+ if (wind->shell_surface.wl == NULL) {
+ return; /* Can't do anything yet, wait for ShowWindow */
+ }
+ wl_shell_surface_set_maximized(wind->shell_surface.wl, NULL);
}
WAYLAND_wl_display_roundtrip(viddata->display);
@@ -2209,6 +2299,11 @@ void Wayland_SetWindowTitle(_THIS, SDL_Window *window)
return; /* Can't do anything yet, wait for ShowWindow */
}
xdg_toplevel_set_title(wind->shell_surface.xdg.roleobj.toplevel, title);
+ } else {
+ if (wind->shell_surface.wl == NULL) {
+ return; /* Can'd do anything yet, wait for ShowWindow */
+ }
+ wl_shell_surface_set_title(wind->shell_surface.wl, title);
}
WAYLAND_wl_display_flush(viddata->display);
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
index 36600a4d2783e5205d0e1d2faf8422b54e1f7848..0951126949879d863cde175684a3605367428824 100644
--- a/src/video/wayland/SDL_waylandwindow.h
+++ b/src/video/wayland/SDL_waylandwindow.h
@@ -67,6 +67,7 @@ typedef struct
} roleobj;
SDL_bool initial_configure_seen;
} xdg;
+ struct wl_shell_surface *wl;
} shell_surface;
enum
{

View File

@@ -0,0 +1,49 @@
commit 7dd1cdd4656e0bdbf0f851392f644b2a05c32d64
Author: Vladimir Serbinenko <phcoder@gmail.com>
Date: Thu Sep 26 17:19:14 2024 +0300
Handle wayland touch cancel message
Suppose host has some three-finger gesture. Then we get the following sequence
of events:
DOWN-DOWN-DOWN-MOTION-CANCEL
Note that there is no UP in this sequence. So if we don't handle CANCEL then
we end up thinking that fingers are still touching the screen. Ideally we
should inform the application that cancel has happened as not to trigger
spurious taps but still this is way better than being stuck with phantom
finger touch.
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index 65838f480..236dc3232 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -932,6 +932,28 @@ static void touch_handler_frame(void *data, struct wl_touch *touch)
static void touch_handler_cancel(void *data, struct wl_touch *touch)
{
+ struct SDL_WaylandTouchPoint *tp;
+ while ((tp = touch_points.head)) {
+ wl_fixed_t fx = 0, fy = 0;
+ struct wl_surface *surface = NULL;
+ int id = tp->id;
+
+ touch_del(id, &fx, &fy, &surface);
+
+ if (surface) {
+ SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(surface);
+
+ if (window_data) {
+ const double dblx = wl_fixed_to_double(fx) * window_data->pointer_scale_x;
+ const double dbly = wl_fixed_to_double(fy) * window_data->pointer_scale_y;
+ const float x = dblx / window_data->sdlwindow->w;
+ const float y = dbly / window_data->sdlwindow->h;
+
+ SDL_SendTouch((SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id,
+ window_data->sdlwindow, SDL_FALSE, x, y, 1.0f);
+ }
+ }
+ }
}
static const struct wl_touch_listener touch_listener = {

View File

@@ -0,0 +1,12 @@
--- a/sdl2-config.in 2024-10-06 01:45:09.683556034 +0300
+++ b/sdl2-config.in 2024-10-06 01:56:47.497325450 +0300
@@ -53,8 +53,8 @@
@ENABLE_SHARED_TRUE@ ;;
@ENABLE_STATIC_TRUE@@ENABLE_SHARED_TRUE@ --static-libs)
@ENABLE_STATIC_TRUE@@ENABLE_SHARED_FALSE@ --libs|--static-libs)
-@ENABLE_STATIC_TRUE@ sdl_static_libs=$(echo "@SDL_LIBS@ @SDL_STATIC_LIBS@" | sed -E "s#-lSDL2[ $]#$libdir/libSDL2.a #g")
+@ENABLE_STATIC_TRUE@ sdl_static_libs=$(echo "@SDL_LIBS@ @SDL_STATIC_LIBS@" | sed "s#-lSDL2[ $]#$libdir/libSDL2.a #g")
@ENABLE_STATIC_TRUE@ echo -L@libdir@ $sdl_static_libs
@ENABLE_STATIC_TRUE@ ;;
*)
echo "${usage}" 1>&2