Update to 2.0.22

- Drop backported patches included in this release
This commit is contained in:
Neal Gompa 2022-04-29 23:45:59 -04:00
parent adf5181d82
commit 2a9f848860
22 changed files with 27 additions and 1427 deletions

1
.gitignore vendored
View File

@ -14,3 +14,4 @@
/SDL2-2.0.16.tar.gz /SDL2-2.0.16.tar.gz
/SDL2-2.0.18.tar.gz /SDL2-2.0.18.tar.gz
/SDL2-2.0.20.tar.gz /SDL2-2.0.20.tar.gz
/SDL2-2.0.22.tar.gz

View File

@ -1,63 +0,0 @@
From b3984df1c61cfc28ea503bff62c7f9931ed6bcfb Mon Sep 17 00:00:00 2001
From: Frank Praznik <frank.praznik@gmail.com>
Date: Wed, 19 Jan 2022 13:14:54 -0500
Subject: [PATCH 1/7] audio: pipewire: Use client config files instead of
module names
Pipewire, as of 0.3.22, uses client config files to load modules instead of explicitly specifying them (PW_KEY_CONTEXT_PROFILE_MODULES is deprecated). Use the new method to load the realtime module to boost the audio thread priority.
---
src/audio/pipewire/SDL_pipewire.c | 31 +++++++++++++++++++++++++++----
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c
index 32d7d5a5a..6d436f992 100644
--- a/src/audio/pipewire/SDL_pipewire.c
+++ b/src/audio/pipewire/SDL_pipewire.c
@@ -31,8 +31,22 @@
#include <pipewire/extensions/metadata.h>
#include <spa/param/audio/format-utils.h>
-/* Older versions of Pipewire may not define this, but it's safe to pass at
- * runtime even if older installations don't recognize it.
+/*
+ * The following keys are defined for compatability when building against older versions of Pipewire
+ * prior to their introduction and can be removed if the minimum required Pipewire version is increased
+ * to or beyond their point of introduction.
+ */
+
+/*
+ * Introduced in 0.3.22
+ * Taken from /src/pipewire/keys.h
+ */
+#ifndef PW_KEY_CONFIG_NAME
+#define PW_KEY_CONFIG_NAME "config.name"
+#endif
+
+/*
+ * Introduced in 0.3.33
* Taken from src/pipewire/keys.h
*/
#ifndef PW_KEY_NODE_RATE
@@ -1099,8 +1113,17 @@ PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
return SDL_SetError("Pipewire: Failed to create stream loop (%i)", errno);
}
- /* Load the rtkit module so Pipewire can set the loop thread to the appropriate priority */
- props = PIPEWIRE_pw_properties_new(PW_KEY_CONTEXT_PROFILE_MODULES, "default,rtkit", NULL);
+ /*
+ * Load the realtime module so Pipewire can set the loop thread to the appropriate priority.
+ *
+ * NOTE: Pipewire versions 0.3.22 or higher require the PW_KEY_CONFIG_NAME property (with client-rt.conf),
+ * lower versions require explicitly specifying the 'rtkit' module.
+ *
+ * PW_KEY_CONTEXT_PROFILE_MODULES is deprecated and can be safely removed if the minimum required
+ * Pipewire version is increased to 0.3.22 or higher at some point.
+ */
+ props = PIPEWIRE_pw_properties_new(PW_KEY_CONFIG_NAME, "client-rt.conf",
+ PW_KEY_CONTEXT_PROFILE_MODULES, "default,rtkit", NULL);
if (props == NULL) {
return SDL_SetError("Pipewire: Failed to create stream context properties (%i)", errno);
}
--
2.34.1

View File

@ -1,182 +0,0 @@
From 9a2bbd8acbebcde56dd2f89ebca3b196c2b38914 Mon Sep 17 00:00:00 2001
From: Ethan Lee <flibitijibibo@gmail.com>
Date: Wed, 12 Jan 2022 13:01:05 -0500
Subject: [PATCH 01/11] wayland: Convert URI to local path for DropFile
---
src/video/wayland/SDL_waylandevents.c | 149 ++++++++++++++++++++++----
1 file changed, 129 insertions(+), 20 deletions(-)
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index dfa62ec69..bf2aeea5b 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -1312,36 +1312,145 @@ data_device_handle_motion(void *data, struct wl_data_device *wl_data_device,
{
}
+/* Decodes URI escape sequences in string buf of len bytes
+ (excluding the terminating NULL byte) in-place. Since
+ URI-encoded characters take three times the space of
+ normal characters, this should not be an issue.
+
+ Returns the number of decoded bytes that wound up in
+ the buffer, excluding the terminating NULL byte.
+
+ The buffer is guaranteed to be NULL-terminated but
+ may contain embedded NULL bytes.
+
+ On error, -1 is returned.
+
+ FIXME: This was shamelessly copied from SDL_x11events.c
+ */
+static int Wayland_URIDecode(char *buf, int len) {
+ int ri, wi, di;
+ char decode = '\0';
+ if (buf == NULL || len < 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (len == 0) {
+ len = SDL_strlen(buf);
+ }
+ for (ri = 0, wi = 0, di = 0; ri < len && wi < len; ri += 1) {
+ if (di == 0) {
+ /* start decoding */
+ if (buf[ri] == '%') {
+ decode = '\0';
+ di += 1;
+ continue;
+ }
+ /* normal write */
+ buf[wi] = buf[ri];
+ wi += 1;
+ continue;
+ } else if (di == 1 || di == 2) {
+ char off = '\0';
+ char isa = buf[ri] >= 'a' && buf[ri] <= 'f';
+ char isA = buf[ri] >= 'A' && buf[ri] <= 'F';
+ char isn = buf[ri] >= '0' && buf[ri] <= '9';
+ if (!(isa || isA || isn)) {
+ /* not a hexadecimal */
+ int sri;
+ for (sri = ri - di; sri <= ri; sri += 1) {
+ buf[wi] = buf[sri];
+ wi += 1;
+ }
+ di = 0;
+ continue;
+ }
+ /* itsy bitsy magicsy */
+ if (isn) {
+ off = 0 - '0';
+ } else if (isa) {
+ off = 10 - 'a';
+ } else if (isA) {
+ off = 10 - 'A';
+ }
+ decode |= (buf[ri] + off) << (2 - di) * 4;
+ if (di == 2) {
+ buf[wi] = decode;
+ wi += 1;
+ di = 0;
+ } else {
+ di += 1;
+ }
+ continue;
+ }
+ }
+ buf[wi] = '\0';
+ return wi;
+}
+
+/* Convert URI to local filename
+ return filename if possible, else NULL
+
+ FIXME: This was shamelessly copied from SDL_x11events.c
+*/
+static char* Wayland_URIToLocal(char* uri) {
+ char *file = NULL;
+ SDL_bool local;
+
+ if (SDL_memcmp(uri,"file:/",6) == 0) uri += 6; /* local file? */
+ else if (SDL_strstr(uri,":/") != NULL) return file; /* wrong scheme */
+
+ local = uri[0] != '/' || (uri[0] != '\0' && uri[1] == '/');
+
+ /* got a hostname? */
+ if (!local && uri[0] == '/' && uri[2] != '/') {
+ char* hostname_end = SDL_strchr(uri+1, '/');
+ if (hostname_end != NULL) {
+ char hostname[ 257 ];
+ if (gethostname(hostname, 255) == 0) {
+ hostname[ 256 ] = '\0';
+ if (SDL_memcmp(uri+1, hostname, hostname_end - (uri+1)) == 0) {
+ uri = hostname_end + 1;
+ local = SDL_TRUE;
+ }
+ }
+ }
+ }
+ if (local) {
+ file = uri;
+ /* Convert URI escape sequences to real characters */
+ Wayland_URIDecode(file, 0);
+ if (uri[1] == '/') {
+ file++;
+ } else {
+ file--;
+ }
+ }
+ return file;
+}
+
static void
data_device_handle_drop(void *data, struct wl_data_device *wl_data_device)
{
SDL_WaylandDataDevice *data_device = data;
- void *buffer = NULL;
- size_t length = 0;
-
- const char *current_uri = NULL;
- const char *last_char = NULL;
- char *current_char = NULL;
if (data_device->drag_offer != NULL) {
/* TODO: SDL Support more mime types */
- buffer = Wayland_data_offer_receive(data_device->drag_offer,
- &length, FILE_MIME, SDL_FALSE);
-
- /* uri-list */
- current_uri = (const char *)buffer;
- last_char = (const char *)buffer + length;
- for (current_char = buffer; current_char < last_char; ++current_char) {
- if (*current_char == '\n' || *current_char == 0) {
- if (*current_uri != 0 && *current_uri != '#') {
- *current_char = 0;
- SDL_SendDropFile(NULL, current_uri);
+ size_t length;
+ void *buffer = Wayland_data_offer_receive(data_device->drag_offer,
+ &length, FILE_MIME, SDL_FALSE);
+ if (buffer) {
+ char *saveptr = NULL;
+ char *token = SDL_strtokr((char *) buffer, "\r\n", &saveptr);
+ while (token != NULL) {
+ char *fn = Wayland_URIToLocal(token);
+ if (fn) {
+ SDL_SendDropFile(NULL, fn); /* FIXME: Window? */
}
- current_uri = (const char *)current_char + 1;
+ token = SDL_strtokr(NULL, "\r\n", &saveptr);
}
+ SDL_SendDropComplete(NULL); /* FIXME: Window? */
+ SDL_free(buffer);
}
-
- SDL_free(buffer);
}
}
--
2.34.1

View File

@ -1,59 +0,0 @@
From 0dda8a7f4cdbcdccc78979ec808777b027645ac6 Mon Sep 17 00:00:00 2001
From: pionere <pionere@freemail.hu>
Date: Mon, 17 Jan 2022 11:21:01 +0100
Subject: [PATCH 2/7] cleanup init functions of audio - use SDL_bool if
possible - assume NULL/SDL_FALSE filled impl - skip zfill of current_audio at
the beginning of SDL_AudioInit (done before the init() calls)
---
src/audio/pipewire/SDL_pipewire.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c
index 6d436f992..893d0c4ee 100644
--- a/src/audio/pipewire/SDL_pipewire.c
+++ b/src/audio/pipewire/SDL_pipewire.c
@@ -1223,19 +1223,19 @@ PIPEWIRE_Deinitialize()
}
}
-static int
+static SDL_bool
PIPEWIRE_Init(SDL_AudioDriverImpl *impl)
{
if (!pipewire_initialized) {
if (init_pipewire_library() < 0) {
- return 0;
+ return SDL_FALSE;
}
pipewire_initialized = SDL_TRUE;
if (hotplug_loop_init() < 0) {
PIPEWIRE_Deinitialize();
- return 0;
+ return SDL_FALSE;
}
}
@@ -1245,13 +1245,13 @@ PIPEWIRE_Init(SDL_AudioDriverImpl *impl)
impl->CloseDevice = PIPEWIRE_CloseDevice;
impl->Deinitialize = PIPEWIRE_Deinitialize;
- impl->HasCaptureSupport = 1;
- impl->ProvidesOwnCallbackThread = 1;
+ impl->HasCaptureSupport = SDL_TRUE;
+ impl->ProvidesOwnCallbackThread = SDL_TRUE;
- return 1;
+ return SDL_TRUE;
}
-AudioBootStrap PIPEWIRE_bootstrap = { "pipewire", "Pipewire", PIPEWIRE_Init, 0 };
+AudioBootStrap PIPEWIRE_bootstrap = { "pipewire", "Pipewire", PIPEWIRE_Init, SDL_FALSE };
#endif /* SDL_AUDIO_DRIVER_PIPEWIRE */
--
2.34.1

View File

@ -1,133 +0,0 @@
From d3952a8a2c8a32d4f6f521402427052a4b756f9f Mon Sep 17 00:00:00 2001
From: Cameron Gutman <aicommander@gmail.com>
Date: Sun, 16 Jan 2022 15:14:33 -0600
Subject: [PATCH 02/11] wayland: Avoid spurious resize events
---
src/video/wayland/SDL_waylandwindow.c | 42 +++++++++++++++++----------
src/video/wayland/SDL_waylandwindow.h | 1 +
2 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index 3eae22bf7..a4b5933eb 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -224,14 +224,16 @@ handle_configure_xdg_toplevel(void *data,
* us a completely stateless, sizeless configure, with which we have
* to enforce our own state anyway.
*/
- if (width != 0 && height != 0) {
+ if (width != 0 && height != 0 && (window->w != width || window->h != height)) {
window->w = width;
window->h = height;
+ wind->needs_resize_event = SDL_TRUE;
}
/* This part is good though. */
- if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+ if ((window->flags & SDL_WINDOW_ALLOW_HIGHDPI) && wind->scale_factor != driverdata->scale_factor) {
wind->scale_factor = driverdata->scale_factor;
+ wind->needs_resize_event = SDL_TRUE;
}
return;
@@ -284,8 +286,11 @@ handle_configure_xdg_toplevel(void *data,
}
/* Store this now so the xdg_surface configure knows what to resize to */
- window->w = width;
- window->h = height;
+ if (window->w != width || window->h != height) {
+ window->w = width;
+ window->h = height;
+ wind->needs_resize_event = SDL_TRUE;
+ }
} else {
/* For fullscreen, foolishly do what the compositor says. If it's wrong,
* don't blame us, we were explicitly instructed to do this.
@@ -293,14 +298,16 @@ handle_configure_xdg_toplevel(void *data,
* UPDATE: Nope, sure enough a compositor sends 0,0. This is a known bug:
* https://bugs.kde.org/show_bug.cgi?id=444962
*/
- if (width != 0 && height != 0) {
+ if (width != 0 && height != 0 && (window->w != width || window->h != height)) {
window->w = width;
window->h = height;
+ wind->needs_resize_event = SDL_TRUE;
}
/* This part is good though. */
- if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+ if ((window->flags & SDL_WINDOW_ALLOW_HIGHDPI) && wind->scale_factor != driverdata->scale_factor) {
wind->scale_factor = driverdata->scale_factor;
+ wind->needs_resize_event = SDL_TRUE;
}
}
}
@@ -330,6 +337,7 @@ decoration_frame_configure(struct libdecor_frame *frame,
enum libdecor_window_state window_state;
int width, height;
+ float scale_factor = wind->scale_factor;
SDL_bool focused = SDL_FALSE;
SDL_bool fullscreen = SDL_FALSE;
@@ -399,7 +407,7 @@ decoration_frame_configure(struct libdecor_frame *frame,
/* This part is good though. */
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
- wind->scale_factor = driverdata->scale_factor;
+ scale_factor = driverdata->scale_factor;
}
} else if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
width = window->windowed.w;
@@ -427,7 +435,7 @@ decoration_frame_configure(struct libdecor_frame *frame,
}
/* Do the resize on the SDL side (this will set window->w/h)... */
- Wayland_HandleResize(window, width, height, wind->scale_factor);
+ Wayland_HandleResize(window, width, height, scale_factor);
wind->shell_surface.libdecor.initial_configure_seen = SDL_TRUE;
/* ... then commit the changes on the libdecor side. */
@@ -1341,14 +1349,18 @@ Wayland_HandleResize(SDL_Window *window, int width, int height, float scale)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
SDL_VideoData *viddata = data->waylandData;
-
struct wl_region *region;
- window->w = 0;
- window->h = 0;
- SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, width, height);
- window->w = width;
- window->h = height;
- data->scale_factor = scale;
+
+ if (data->needs_resize_event || window->w != width || window->h != height || data->scale_factor != scale) {
+ /* We may have already updated window w/h (or only adjusted scale factor),
+ * so we must override the deduplication logic in the video core */
+ window->w = 0;
+ window->h = 0;
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, width, height);
+ window->w = width;
+ window->h = height;
+ data->needs_resize_event = SDL_FALSE;
+ }
wl_surface_set_buffer_scale(data->surface, data->scale_factor);
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
index 8ca090f0c..bce1d1855 100644
--- a/src/video/wayland/SDL_waylandwindow.h
+++ b/src/video/wayland/SDL_waylandwindow.h
@@ -84,6 +84,7 @@ typedef struct {
int num_outputs;
float scale_factor;
+ SDL_bool needs_resize_event;
} SDL_WindowData;
extern void Wayland_ShowWindow(_THIS, SDL_Window *window);
--
2.34.1

View File

@ -1,34 +0,0 @@
From 1043dd8c0d8a80a2df5b7003f84713af29749db2 Mon Sep 17 00:00:00 2001
From: pionere <pionere@freemail.hu>
Date: Wed, 19 Jan 2022 12:58:04 +0100
Subject: [PATCH 3/7] adjust handling of iscapture - drop iscapture parameter
of OpenDevice - use SDL_bool for iscapture
---
src/audio/pipewire/SDL_pipewire.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c
index 893d0c4ee..171c40849 100644
--- a/src/audio/pipewire/SDL_pipewire.c
+++ b/src/audio/pipewire/SDL_pipewire.c
@@ -1027,7 +1027,7 @@ static const struct pw_stream_events stream_input_events = { PW_VERSION_STREAM_
.process = input_callback };
static int
-PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
+PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname)
{
/*
* NOTE: The PW_STREAM_FLAG_RT_PROCESS flag can be set to call the stream
@@ -1048,6 +1048,7 @@ PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
const char * app_name, *stream_name, *stream_role, *error;
const Uint32 node_id = this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle);
enum pw_stream_state state;
+ SDL_bool iscapture = this->iscapture;
int res;
/* Clamp the period size to sane values */
--
2.34.1

View File

@ -1,96 +0,0 @@
From ed3442d7a5a79b3a7357c5bdf54b47ab985ca7f7 Mon Sep 17 00:00:00 2001
From: Ethan Lee <flibitijibibo@gmail.com>
Date: Wed, 19 Jan 2022 15:47:52 -0500
Subject: [PATCH 03/11] wayland: Fix building with SDL_OPENGL=OFF
---
src/video/wayland/SDL_waylandvideo.c | 2 ++
src/video/wayland/SDL_waylandwindow.c | 8 ++++++--
src/video/wayland/SDL_waylandwindow.h | 2 ++
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
index f009fb7c6..60d7403c7 100644
--- a/src/video/wayland/SDL_waylandvideo.c
+++ b/src/video/wayland/SDL_waylandvideo.c
@@ -230,6 +230,7 @@ Wayland_CreateDevice(int devindex)
device->WaitEventTimeout = Wayland_WaitEventTimeout;
device->SendWakeupEvent = Wayland_SendWakeupEvent;
+#if SDL_VIDEO_OPENGL_EGL
device->GL_SwapWindow = Wayland_GLES_SwapWindow;
device->GL_GetSwapInterval = Wayland_GLES_GetSwapInterval;
device->GL_SetSwapInterval = Wayland_GLES_SetSwapInterval;
@@ -240,6 +241,7 @@ Wayland_CreateDevice(int devindex)
device->GL_UnloadLibrary = Wayland_GLES_UnloadLibrary;
device->GL_GetProcAddress = Wayland_GLES_GetProcAddress;
device->GL_DeleteContext = Wayland_GLES_DeleteContext;
+#endif
device->CreateSDLWindow = Wayland_CreateWindow;
device->ShowWindow = Wayland_ShowWindow;
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index a4b5933eb..80bb66878 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -21,7 +21,7 @@
#include "../../SDL_internal.h"
-#if SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL
+#if SDL_VIDEO_DRIVER_WAYLAND
#include "../SDL_sysvideo.h"
#include "../../events/SDL_windowevents_c.h"
@@ -1309,12 +1309,14 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
data->egl_window = WAYLAND_wl_egl_window_create(data->surface,
window->w * data->scale_factor, window->h * data->scale_factor);
+#if SDL_VIDEO_OPENGL_EGL
/* Create the GLES window surface */
data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window);
if (data->egl_surface == EGL_NO_SURFACE) {
return SDL_SetError("failed to create an EGL window surface");
}
+#endif
}
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
@@ -1517,9 +1519,11 @@ void Wayland_DestroyWindow(_THIS, SDL_Window *window)
SDL_WindowData *wind = window->driverdata;
if (data) {
+#if SDL_VIDEO_OPENGL_EGL
if (wind->egl_surface) {
SDL_EGL_DestroySurface(_this, wind->egl_surface);
}
+#endif
if (wind->egl_window) {
WAYLAND_wl_egl_window_destroy(wind->egl_window);
}
@@ -1555,6 +1559,6 @@ void Wayland_DestroyWindow(_THIS, SDL_Window *window)
window->driverdata = NULL;
}
-#endif /* SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL */
+#endif /* SDL_VIDEO_DRIVER_WAYLAND */
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
index bce1d1855..e8d7d6299 100644
--- a/src/video/wayland/SDL_waylandwindow.h
+++ b/src/video/wayland/SDL_waylandwindow.h
@@ -63,7 +63,9 @@ typedef struct {
} shell_surface;
struct wl_egl_window *egl_window;
struct SDL_WaylandInput *keyboard_device;
+#if SDL_VIDEO_OPENGL_EGL
EGLSurface egl_surface;
+#endif
struct zwp_locked_pointer_v1 *locked_pointer;
struct zwp_confined_pointer_v1 *confined_pointer;
struct zxdg_toplevel_decoration_v1 *server_decoration;
--
2.34.1

View File

@ -1,34 +0,0 @@
From a70bb259c7a78ba5b802abadbffbc56228449b50 Mon Sep 17 00:00:00 2001
From: pionere <pionere@freemail.hu>
Date: Thu, 20 Jan 2022 13:16:03 +0100
Subject: [PATCH 4/7] drop handle parameter of OpenDevice
---
src/audio/pipewire/SDL_pipewire.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c
index 171c40849..5a10b28a8 100644
--- a/src/audio/pipewire/SDL_pipewire.c
+++ b/src/audio/pipewire/SDL_pipewire.c
@@ -1027,7 +1027,7 @@ static const struct pw_stream_events stream_input_events = { PW_VERSION_STREAM_
.process = input_callback };
static int
-PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname)
+PIPEWIRE_OpenDevice(_THIS, const char *devname)
{
/*
* NOTE: The PW_STREAM_FLAG_RT_PROCESS flag can be set to call the stream
@@ -1108,7 +1108,7 @@ PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname)
}
}
- SDL_snprintf(thread_name, sizeof(thread_name), "SDLAudio%c%ld", (iscapture) ? 'C' : 'P', (long)handle);
+ SDL_snprintf(thread_name, sizeof(thread_name), "SDLAudio%c%ld", (iscapture) ? 'C' : 'P', (long)this->handle);
priv->loop = PIPEWIRE_pw_thread_loop_new(thread_name, NULL);
if (priv->loop == NULL) {
return SDL_SetError("Pipewire: Failed to create stream loop (%i)", errno);
--
2.34.1

View File

@ -1,54 +0,0 @@
From e1b4761c621e9883c3f02971ea74cef14b1d6b87 Mon Sep 17 00:00:00 2001
From: Ethan Lee <flibitijibibo@gmail.com>
Date: Thu, 20 Jan 2022 14:10:56 -0500
Subject: [PATCH 04/11] wayland: Avoid calling SetFullscreen in libdecor
ShowWindow.
This caused some weird stuff to happen in the libdecor path, probably because
the window hasn't actually been mapped yet. It ends up calling stuff that
should not yet apply, and so fullscreen in particular would have a really
messed up titlebar.
The good news is, libdecor is good about tracking fullscreen state, so we can
let the callback do this for us. Keep this for xdg_shell because we actually
map the window ourselves, so we know this call is valid for that path.
---
src/video/wayland/SDL_waylandwindow.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index 80bb66878..3b21af7be 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -724,7 +724,6 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
{
SDL_VideoData *c = _this->driverdata;
SDL_WindowData *data = window->driverdata;
- SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
/* Detach any previous buffers before resetting everything, otherwise when
* calling this a second time you'll get an annoying protocol error
@@ -766,7 +765,6 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
if (window->flags & SDL_WINDOW_MINIMIZED) {
Wayland_MinimizeWindow(_this, window);
}
- Wayland_SetWindowFullscreen(_this, window, display, (window->flags & SDL_WINDOW_FULLSCREEN) != 0);
/* We have to wait until the surface gets a "configure" event, or use of
* this surface will fail. This is a new rule for xdg_shell.
@@ -782,6 +780,12 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
} else
#endif
if (c->shell.xdg) {
+ /* Unlike libdecor we need to call this explicitly to prevent a deadlock.
+ * libdecor will call this as part of their configure event!
+ * -flibit
+ */
+ Wayland_SetWindowFullscreen(_this, window, SDL_GetDisplayForWindow(window),
+ (window->flags & SDL_WINDOW_FULLSCREEN) != 0);
if (data->shell_surface.xdg.surface) {
while (!data->shell_surface.xdg.initial_configure_seen) {
WAYLAND_wl_display_flush(c->display);
--
2.34.1

View File

@ -1,63 +0,0 @@
From 0b34f18045a1ea89b06fc9c71dc828e8c257fb30 Mon Sep 17 00:00:00 2001
From: Frank Praznik <frank.praznik@gmail.com>
Date: Sun, 30 Jan 2022 12:00:55 -0500
Subject: [PATCH 5/7] audio: pipewire: Don't double free properties on init
failure
The context and stream creation functions will destroy the passed properties object on failure, so no need to do it manually.
The pw_properties_free() function pointer is no longer needed, so it can be removed.
---
src/audio/pipewire/SDL_pipewire.c | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c
index 5a10b28a8..5c6e10495 100644
--- a/src/audio/pipewire/SDL_pipewire.c
+++ b/src/audio/pipewire/SDL_pipewire.c
@@ -100,7 +100,6 @@ static enum pw_stream_state (*PIPEWIRE_pw_stream_get_state)(struct pw_stream *st
static struct pw_buffer *(*PIPEWIRE_pw_stream_dequeue_buffer)(struct pw_stream *);
static int (*PIPEWIRE_pw_stream_queue_buffer)(struct pw_stream *, struct pw_buffer *);
static struct pw_properties *(*PIPEWIRE_pw_properties_new)(const char *, ...)SPA_SENTINEL;
-static void (*PIPEWIRE_pw_properties_free)(struct pw_properties *);
static int (*PIPEWIRE_pw_properties_set)(struct pw_properties *, const char *, const char *);
static int (*PIPEWIRE_pw_properties_setf)(struct pw_properties *, const char *, const char *, ...) SPA_PRINTF_FUNC(3, 4);
@@ -190,7 +189,6 @@ load_pipewire_syms()
SDL_PIPEWIRE_SYM(pw_stream_dequeue_buffer);
SDL_PIPEWIRE_SYM(pw_stream_queue_buffer);
SDL_PIPEWIRE_SYM(pw_properties_new);
- SDL_PIPEWIRE_SYM(pw_properties_free);
SDL_PIPEWIRE_SYM(pw_properties_set);
SDL_PIPEWIRE_SYM(pw_properties_setf);
@@ -1129,10 +1127,8 @@ PIPEWIRE_OpenDevice(_THIS, const char *devname)
return SDL_SetError("Pipewire: Failed to create stream context properties (%i)", errno);
}
- /* On success, the context owns the properties object and will free it at destruction time. */
priv->context = PIPEWIRE_pw_context_new(PIPEWIRE_pw_thread_loop_get_loop(priv->loop), props, 0);
if (priv->context == NULL) {
- PIPEWIRE_pw_properties_free(props);
return SDL_SetError("Pipewire: Failed to create stream context (%i)", errno);
}
@@ -1151,14 +1147,10 @@ PIPEWIRE_OpenDevice(_THIS, const char *devname)
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%u", this->spec.freq);
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_ALWAYS_PROCESS, "true");
- /*
- * Create the new stream
- * On success, the stream owns the properties object and will free it at destruction time.
- */
+ /* Create the new stream */
priv->stream = PIPEWIRE_pw_stream_new_simple(PIPEWIRE_pw_thread_loop_get_loop(priv->loop), stream_name, props,
iscapture ? &stream_input_events : &stream_output_events, this);
if (priv->stream == NULL) {
- PIPEWIRE_pw_properties_free(props);
return SDL_SetError("Pipewire: Failed to create stream (%i)", errno);
}
--
2.34.1

View File

@ -1,41 +0,0 @@
From e2d74bcbe524960c17c852466130a6e0a30674a3 Mon Sep 17 00:00:00 2001
From: Ethan Lee <flibitijibibo@gmail.com>
Date: Tue, 25 Jan 2022 11:16:09 -0500
Subject: [PATCH 05/11] wayland: Detach hidden surfaces in HideWindow, not
ShowWindow
---
src/video/wayland/SDL_waylandwindow.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index 3b21af7be..2bf500a91 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -725,12 +725,6 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
SDL_VideoData *c = _this->driverdata;
SDL_WindowData *data = window->driverdata;
- /* Detach any previous buffers before resetting everything, otherwise when
- * calling this a second time you'll get an annoying protocol error
- */
- wl_surface_attach(data->surface, NULL, 0, 0);
- wl_surface_commit(data->surface);
-
/* Create the shell surface and map the toplevel */
#ifdef HAVE_LIBDECOR_H
if (c->shell.libdecor) {
@@ -862,6 +856,10 @@ void Wayland_HideWindow(_THIS, SDL_Window *window)
wind->shell_surface.xdg.surface = NULL;
}
}
+
+ /* Be sure to detach after this is done, otherwise ShowWindow crashes! */
+ wl_surface_attach(wind->surface, NULL, 0, 0);
+ wl_surface_commit(wind->surface);
}
static void
--
2.34.1

View File

@ -1,54 +0,0 @@
From 66866249a2699c46fb06d749f97bae2bc073c732 Mon Sep 17 00:00:00 2001
From: Frank Praznik <frank.praznik@gmail.com>
Date: Wed, 2 Feb 2022 11:09:02 -0500
Subject: [PATCH 6/7] audio: pipewire: Condition variable doesn't need to be
atomic
The condition variable is guarded by a mutex, so no need for it to be atomic.
---
src/audio/pipewire/SDL_pipewire.c | 4 ++--
src/audio/pipewire/SDL_pipewire.h | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c
index 5c6e10495..9c3d0b2cd 100644
--- a/src/audio/pipewire/SDL_pipewire.c
+++ b/src/audio/pipewire/SDL_pipewire.c
@@ -1012,7 +1012,7 @@ stream_state_changed_callback(void *data, enum pw_stream_state old, enum pw_stre
_THIS = data;
if (state == PW_STREAM_STATE_STREAMING || state == PW_STREAM_STATE_ERROR) {
- SDL_AtomicSet(&this->hidden->stream_initialized, 1);
+ this->hidden->stream_initialized = 1;
PIPEWIRE_pw_thread_loop_signal(this->hidden->loop, false);
}
}
@@ -1167,7 +1167,7 @@ PIPEWIRE_OpenDevice(_THIS, const char *devname)
/* Wait until the stream is either running or failed */
PIPEWIRE_pw_thread_loop_lock(priv->loop);
- if (!SDL_AtomicGet(&priv->stream_initialized)) {
+ if (!priv->stream_initialized) {
PIPEWIRE_pw_thread_loop_wait(priv->loop);
}
PIPEWIRE_pw_thread_loop_unlock(priv->loop);
diff --git a/src/audio/pipewire/SDL_pipewire.h b/src/audio/pipewire/SDL_pipewire.h
index 731a2027f..ba7d6fc30 100644
--- a/src/audio/pipewire/SDL_pipewire.h
+++ b/src/audio/pipewire/SDL_pipewire.h
@@ -37,9 +37,9 @@ struct SDL_PrivateAudioData
struct pw_context *context;
struct SDL_DataQueue *buffer;
- size_t buffer_period_size;
- Sint32 stride; /* Bytes-per-frame */
- SDL_atomic_t stream_initialized;
+ size_t buffer_period_size;
+ Sint32 stride; /* Bytes-per-frame */
+ int stream_initialized;
};
#endif /* SDL_pipewire_h_ */
--
2.34.1

View File

@ -1,28 +0,0 @@
From f0e768da43173cf62732fc20d1f80eb777d6d5c8 Mon Sep 17 00:00:00 2001
From: Ethan Lee <flibitijibibo@gmail.com>
Date: Tue, 25 Jan 2022 13:07:00 -0500
Subject: [PATCH 06/11] wayland: Call SetFullscreen directly in ShowWindow.
This cuts out an extra flush when getting the first configure event.
---
src/video/wayland/SDL_waylandwindow.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index 2bf500a91..d4b89de7a 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -778,8 +778,8 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
* libdecor will call this as part of their configure event!
* -flibit
*/
- Wayland_SetWindowFullscreen(_this, window, SDL_GetDisplayForWindow(window),
- (window->flags & SDL_WINDOW_FULLSCREEN) != 0);
+ SDL_WaylandOutputData *odata = SDL_GetDisplayForWindow(window)->driverdata;
+ SetFullscreen(window, (window->flags & SDL_WINDOW_FULLSCREEN) ? odata->output : NULL);
if (data->shell_surface.xdg.surface) {
while (!data->shell_surface.xdg.initial_configure_seen) {
WAYLAND_wl_display_flush(c->display);
--
2.34.1

View File

@ -1,217 +0,0 @@
From 53091e36a3b418e33133bae2f018954c006f86b8 Mon Sep 17 00:00:00 2001
From: Frank Praznik <frank.praznik@gmail.com>
Date: Wed, 2 Feb 2022 12:30:34 -0500
Subject: [PATCH 7/7] audio: pipewire: Remove the hard upper bound on rates and
buffer sizes
Remove the hard upper limit of 8192 samples and instead use the buffer sizes provided by Pipewire to determine the size of the intermediate input buffer and whether double buffering is required for output streams. This allows for higher latency streams to potentially avoid double-buffering in the output case, and we can guarantee that the intermediate input buffer will always be large enough to handle whatever Pipewire may deliver.
As the buffer size calculations occur in a callback in the Pipewire processing thread itself, the stream readiness check has been modified to wait on two distinct flags set when the buffers have been configured and when the stream is ready and running.
---
src/audio/pipewire/SDL_pipewire.c | 94 ++++++++++++++++++++-----------
src/audio/pipewire/SDL_pipewire.h | 4 +-
2 files changed, 64 insertions(+), 34 deletions(-)
diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c
index 9c3d0b2cd..637b90434 100644
--- a/src/audio/pipewire/SDL_pipewire.c
+++ b/src/audio/pipewire/SDL_pipewire.c
@@ -54,19 +54,22 @@
#endif
/*
- * These seem to be sane limits as Pipewire
- * uses them in several of it's own modules.
- *
- * NOTE: 8192 is a hard upper limit in Pipewire and
- * increasing this value can lead to buffer overflows.
+ * This seems to be a sane lower limit as Pipewire
+ * uses it in several of it's own modules.
*/
#define PW_MIN_SAMPLES 32 /* About 0.67ms at 48kHz */
-#define PW_MAX_SAMPLES 8192 /* About 170.6ms at 48kHz */
#define PW_BASE_CLOCK_RATE 48000
#define PW_POD_BUFFER_LENGTH 1024
#define PW_THREAD_NAME_BUFFER_LENGTH 128
+enum PW_READY_FLAGS
+{
+ PW_READY_FLAG_BUFFER_ADDED = 0x1,
+ PW_READY_FLAG_STREAM_READY = 0x2,
+ PW_READY_FLAG_ALL_BITS = 0x3
+};
+
#define PW_ID_TO_HANDLE(x) (void *)((uintptr_t)x)
#define PW_HANDLE_TO_ID(x) (uint32_t)((uintptr_t)x)
@@ -997,31 +1000,67 @@ input_callback(void *data)
this->callbackspec.callback(this->callbackspec.userdata, this->work_buffer, this->callbackspec.size);
SDL_UnlockMutex(this->mixer_lock);
}
- } else { /* Flush the buffer when paused */
+ } else if (this->hidden->buffer) { /* Flush the buffer when paused */
if (SDL_CountDataQueue(this->hidden->buffer) != 0) {
- SDL_ClearDataQueue(this->hidden->buffer, this->hidden->buffer_period_size * 2);
+ SDL_ClearDataQueue(this->hidden->buffer, this->hidden->input_buffer_packet_size);
}
}
PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf);
}
+static void
+stream_add_buffer_callback(void *data, struct pw_buffer *buffer)
+{
+ _THIS = data;
+
+ if (this->iscapture == SDL_FALSE) {
+ /*
+ * Clamp the output spec samples and size to the max size of the Pipewire buffer.
+ * If they exceed the maximum size of the Pipewire buffer, double buffering will be used.
+ */
+ if (this->spec.size > buffer->buffer->datas[0].maxsize) {
+ this->spec.samples = buffer->buffer->datas[0].maxsize / this->hidden->stride;
+ this->spec.size = buffer->buffer->datas[0].maxsize;
+ }
+ } else if (this->hidden->buffer == NULL) {
+ /*
+ * The latency of source nodes can change, so buffering is always required.
+ *
+ * Ensure that the intermediate input buffer is large enough to hold the requested
+ * application packet size or a full buffer of data from Pipewire, whichever is larger.
+ *
+ * A packet size of 2 periods should be more than is ever needed.
+ */
+ this->hidden->input_buffer_packet_size = SPA_MAX(this->spec.size, buffer->buffer->datas[0].maxsize) * 2;
+ this->hidden->buffer = SDL_NewDataQueue(this->hidden->input_buffer_packet_size, this->hidden->input_buffer_packet_size);
+ }
+
+ this->hidden->stream_init_status |= PW_READY_FLAG_BUFFER_ADDED;
+ PIPEWIRE_pw_thread_loop_signal(this->hidden->loop, false);
+}
+
static void
stream_state_changed_callback(void *data, enum pw_stream_state old, enum pw_stream_state state, const char *error)
{
_THIS = data;
+ if (state == PW_STREAM_STATE_STREAMING) {
+ this->hidden->stream_init_status |= PW_READY_FLAG_STREAM_READY;
+ }
+
if (state == PW_STREAM_STATE_STREAMING || state == PW_STREAM_STATE_ERROR) {
- this->hidden->stream_initialized = 1;
PIPEWIRE_pw_thread_loop_signal(this->hidden->loop, false);
}
}
static const struct pw_stream_events stream_output_events = { PW_VERSION_STREAM_EVENTS,
.state_changed = stream_state_changed_callback,
+ .add_buffer = stream_add_buffer_callback,
.process = output_callback };
static const struct pw_stream_events stream_input_events = { PW_VERSION_STREAM_EVENTS,
.state_changed = stream_state_changed_callback,
+ .add_buffer = stream_add_buffer_callback,
.process = input_callback };
static int
@@ -1044,14 +1083,12 @@ PIPEWIRE_OpenDevice(_THIS, const char *devname)
struct SDL_PrivateAudioData *priv;
struct pw_properties * props;
const char * app_name, *stream_name, *stream_role, *error;
- const Uint32 node_id = this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle);
- enum pw_stream_state state;
+ const Uint32 node_id = this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle);
SDL_bool iscapture = this->iscapture;
int res;
/* Clamp the period size to sane values */
- const int min_period = PW_MIN_SAMPLES * SPA_MAX(this->spec.freq / PW_BASE_CLOCK_RATE, 1);
- const int adjusted_samples = SPA_CLAMP(this->spec.samples, min_period, PW_MAX_SAMPLES);
+ const int min_period = PW_MIN_SAMPLES * SPA_MAX(this->spec.freq / PW_BASE_CLOCK_RATE, 1);
/* Get the hints for the application name, stream name and role */
app_name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME);
@@ -1090,22 +1127,11 @@ PIPEWIRE_OpenDevice(_THIS, const char *devname)
/* Size of a single audio frame in bytes */
priv->stride = (SDL_AUDIO_BITSIZE(this->spec.format) >> 3) * this->spec.channels;
- if (this->spec.samples != adjusted_samples && !iscapture) {
- this->spec.samples = adjusted_samples;
+ if (this->spec.samples < min_period) {
+ this->spec.samples = min_period;
this->spec.size = this->spec.samples * priv->stride;
}
- /* The latency of source nodes can change, so buffering is required. */
- if (iscapture) {
- priv->buffer_period_size = SPA_MAX(this->spec.samples, adjusted_samples) * priv->stride;
-
- /* A packet size of 4 periods should be more than is ever needed (no more than 2 should be queued in practice). */
- priv->buffer = SDL_NewDataQueue(priv->buffer_period_size * 4, priv->buffer_period_size * 2);
- if (priv->buffer == NULL) {
- return SDL_SetError("Pipewire: Failed to allocate source buffer");
- }
- }
-
SDL_snprintf(thread_name, sizeof(thread_name), "SDLAudio%c%ld", (iscapture) ? 'C' : 'P', (long)this->handle);
priv->loop = PIPEWIRE_pw_thread_loop_new(thread_name, NULL);
if (priv->loop == NULL) {
@@ -1143,7 +1169,7 @@ PIPEWIRE_OpenDevice(_THIS, const char *devname)
PIPEWIRE_pw_properties_set(props, PW_KEY_APP_NAME, app_name);
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_NAME, stream_name);
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, stream_name);
- PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%i", adjusted_samples, this->spec.freq);
+ PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%i", this->spec.samples, this->spec.freq);
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%u", this->spec.freq);
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_ALWAYS_PROCESS, "true");
@@ -1165,19 +1191,23 @@ PIPEWIRE_OpenDevice(_THIS, const char *devname)
return SDL_SetError("Pipewire: Failed to start stream loop");
}
- /* Wait until the stream is either running or failed */
+ /* Wait until all init flags are set or the stream has failed. */
PIPEWIRE_pw_thread_loop_lock(priv->loop);
- if (!priv->stream_initialized) {
+ while (priv->stream_init_status != PW_READY_FLAG_ALL_BITS &&
+ PIPEWIRE_pw_stream_get_state(priv->stream, NULL) != PW_STREAM_STATE_ERROR) {
PIPEWIRE_pw_thread_loop_wait(priv->loop);
}
PIPEWIRE_pw_thread_loop_unlock(priv->loop);
- state = PIPEWIRE_pw_stream_get_state(priv->stream, &error);
-
- if (state == PW_STREAM_STATE_ERROR) {
+ if (PIPEWIRE_pw_stream_get_state(priv->stream, &error) == PW_STREAM_STATE_ERROR) {
return SDL_SetError("Pipewire: Stream error: %s", error);
}
+ /* If this is a capture stream, make sure the intermediate buffer was successfully allocated. */
+ if (iscapture && priv->buffer == NULL) {
+ return SDL_SetError("Pipewire: Failed to allocate source buffer");
+ }
+
return 0;
}
diff --git a/src/audio/pipewire/SDL_pipewire.h b/src/audio/pipewire/SDL_pipewire.h
index ba7d6fc30..767b8f10c 100644
--- a/src/audio/pipewire/SDL_pipewire.h
+++ b/src/audio/pipewire/SDL_pipewire.h
@@ -37,9 +37,9 @@ struct SDL_PrivateAudioData
struct pw_context *context;
struct SDL_DataQueue *buffer;
- size_t buffer_period_size;
+ size_t input_buffer_packet_size;
Sint32 stride; /* Bytes-per-frame */
- int stream_initialized;
+ int stream_init_status;
};
#endif /* SDL_pipewire_h_ */
--
2.34.1

View File

@ -1,142 +0,0 @@
From 68a71f91c6cbb1458dc95e2d994d4522afd92c5e Mon Sep 17 00:00:00 2001
From: Ethan Lee <flibitijibibo@gmail.com>
Date: Tue, 25 Jan 2022 11:18:04 -0500
Subject: [PATCH 07/11] wayland: Try to avoid committing before the window is
shown
---
src/video/wayland/SDL_waylandwindow.c | 32 +++++++++++++++++----------
1 file changed, 20 insertions(+), 12 deletions(-)
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index d4b89de7a..4c3c60aac 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -42,7 +42,7 @@
#endif
static void
-CommitMinMaxDimensions(SDL_Window *window)
+SetMinMaxDimensions(SDL_Window *window, SDL_bool commit)
{
SDL_WindowData *wind = window->driverdata;
SDL_VideoData *viddata = wind->waylandData;
@@ -88,12 +88,14 @@ CommitMinMaxDimensions(SDL_Window *window)
xdg_toplevel_set_max_size(wind->shell_surface.xdg.roleobj.toplevel,
max_width,
max_height);
- wl_surface_commit(wind->surface);
+ if (commit) {
+ wl_surface_commit(wind->surface);
+ }
}
}
static void
-SetFullscreen(SDL_Window *window, struct wl_output *output)
+SetFullscreen(SDL_Window *window, struct wl_output *output, SDL_bool commit)
{
SDL_WindowData *wind = window->driverdata;
SDL_VideoData *viddata = wind->waylandData;
@@ -101,7 +103,7 @@ SetFullscreen(SDL_Window *window, struct wl_output *output)
/* The desktop may try to enforce min/max sizes here, so turn them off for
* fullscreen and on (if applicable) for windowed
*/
- CommitMinMaxDimensions(window);
+ SetMinMaxDimensions(window, SDL_FALSE);
#ifdef HAVE_LIBDECOR_H
if (viddata->shell.libdecor) {
@@ -134,6 +136,9 @@ SetFullscreen(SDL_Window *window, struct wl_output *output)
} else {
xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel);
}
+ if (commit) {
+ wl_surface_commit(wind->surface);
+ }
}
}
@@ -215,7 +220,7 @@ handle_configure_xdg_toplevel(void *data,
if (!fullscreen) {
if (window->flags & SDL_WINDOW_FULLSCREEN) {
/* We might need to re-enter fullscreen after being restored from minimized */
- SetFullscreen(window, driverdata->output);
+ SetFullscreen(window, driverdata->output, SDL_FALSE);
/* Foolishly do what the compositor says here. If it's wrong, don't
* blame us, we were explicitly instructed to do this.
@@ -364,7 +369,7 @@ decoration_frame_configure(struct libdecor_frame *frame,
if (!fullscreen) {
if (window->flags & SDL_WINDOW_FULLSCREEN) {
/* We might need to re-enter fullscreen after being restored from minimized */
- SetFullscreen(window, driverdata->output);
+ SetFullscreen(window, driverdata->output, SDL_FALSE);
fullscreen = SDL_TRUE;
floating = SDL_FALSE;
}
@@ -779,7 +784,7 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
* -flibit
*/
SDL_WaylandOutputData *odata = SDL_GetDisplayForWindow(window)->driverdata;
- SetFullscreen(window, (window->flags & SDL_WINDOW_FULLSCREEN) ? odata->output : NULL);
+ SetFullscreen(window, (window->flags & SDL_WINDOW_FULLSCREEN) ? odata->output : NULL, SDL_TRUE);
if (data->shell_surface.xdg.surface) {
while (!data->shell_surface.xdg.initial_configure_seen) {
WAYLAND_wl_display_flush(c->display);
@@ -791,6 +796,9 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
if (data->shell_surface.xdg.roleobj.toplevel && c->decoration_manager) {
data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel);
}
+ } else {
+ /* Nothing to see here, just commit. */
+ wl_surface_commit(data->surface);
}
/* Unlike the rest of window state we have to set this _after_ flushing the
@@ -1053,7 +1061,7 @@ Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
{
struct wl_output *output = ((SDL_WaylandOutputData*) _display->driverdata)->output;
SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
- SetFullscreen(window, fullscreen ? output : NULL);
+ SetFullscreen(window, fullscreen ? output : NULL, SDL_TRUE);
WAYLAND_wl_display_flush(viddata->display);
}
@@ -1125,7 +1133,7 @@ Wayland_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
} else
#endif
{
- CommitMinMaxDimensions(window);
+ SetMinMaxDimensions(window, SDL_TRUE);
}
}
@@ -1338,7 +1346,7 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
Wayland_input_lock_pointer(c->input);
}
- wl_surface_commit(data->surface);
+ /* Moved this call to ShowWindow: wl_surface_commit(data->surface); */
WAYLAND_wl_display_flush(c->display);
/* We may need to create an idle inhibitor for this new window */
@@ -1393,13 +1401,13 @@ Wayland_HandleResize(SDL_Window *window, int width, int height, float scale)
void
Wayland_SetWindowMinimumSize(_THIS, SDL_Window * window)
{
- CommitMinMaxDimensions(window);
+ SetMinMaxDimensions(window, SDL_TRUE);
}
void
Wayland_SetWindowMaximumSize(_THIS, SDL_Window * window)
{
- CommitMinMaxDimensions(window);
+ SetMinMaxDimensions(window, SDL_TRUE);
}
void Wayland_SetWindowSize(_THIS, SDL_Window * window)
--
2.34.1

View File

@ -1,57 +0,0 @@
From 77a9ca6ba0ae1973d7bc255a4d785e7f1ba3d111 Mon Sep 17 00:00:00 2001
From: Cameron Gutman <aicommander@gmail.com>
Date: Wed, 26 Jan 2022 18:26:07 -0600
Subject: [PATCH 08/11] wayland: Fix SDL_SetWindowSize() being dropped right
after exiting fullscreen
If we get a SDL_SetWindowSize() call right after SDL_SetWindowFullscreen() but
before we've gotten a new configure event from the compositor, the attempt to
set our window size will silently fail (when libdecor is enabled).
Fix this by remembering that we need to commit a new size, so we can do that
in decoration_frame_configure().
---
src/video/wayland/SDL_waylandwindow.c | 5 ++++-
src/video/wayland/SDL_waylandwindow.h | 1 +
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index 4c3c60aac..635546af4 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -414,9 +414,10 @@ decoration_frame_configure(struct libdecor_frame *frame,
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
scale_factor = driverdata->scale_factor;
}
- } else if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
+ } else if (!(window->flags & SDL_WINDOW_RESIZABLE) || (floating && wind->floating_resize_pending)) {
width = window->windowed.w;
height = window->windowed.h;
+ wind->floating_resize_pending = SDL_FALSE;
} else {
/* This will never set 0 for width/height unless the function returns false */
if (!libdecor_configuration_get_content_size(configuration, frame, &width, &height)) {
@@ -1424,6 +1425,8 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window)
if (data->shell.libdecor &&
wind->shell_surface.libdecor.frame &&
!libdecor_frame_is_floating(wind->shell_surface.libdecor.frame)) {
+ /* Commit the resize when we re-enter floating state */
+ wind->floating_resize_pending = SDL_TRUE;
return;
}
#endif
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
index e8d7d6299..90e4d8cf6 100644
--- a/src/video/wayland/SDL_waylandwindow.h
+++ b/src/video/wayland/SDL_waylandwindow.h
@@ -87,6 +87,7 @@ typedef struct {
float scale_factor;
SDL_bool needs_resize_event;
+ SDL_bool floating_resize_pending;
} SDL_WindowData;
extern void Wayland_ShowWindow(_THIS, SDL_Window *window);
--
2.34.1

View File

@ -1,36 +0,0 @@
From cc40f732f9482eb45a1938a23d4f34265e78a729 Mon Sep 17 00:00:00 2001
From: Cameron Gutman <aicommander@gmail.com>
Date: Wed, 26 Jan 2022 21:09:39 -0600
Subject: [PATCH 09/11] wayland: Round the refresh rate rather than truncating
it
A 59999 mHz monitor should be reported as 60 Hz, not 59 Hz.
---
src/video/wayland/SDL_waylandvideo.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
index 60d7403c7..61940cca4 100644
--- a/src/video/wayland/SDL_waylandvideo.c
+++ b/src/video/wayland/SDL_waylandvideo.c
@@ -393,7 +393,7 @@ display_handle_mode(void *data,
mode.w = width;
mode.h = height;
}
- mode.refresh_rate = refresh / 1000; /* mHz to Hz */
+ mode.refresh_rate = (int)SDL_round(refresh / 1000.0); /* mHz to Hz */
mode.driverdata = driverdata->output;
if (driverdata->index > -1) {
SDL_AddDisplayMode(SDL_GetDisplay(driverdata->index), &mode);
@@ -446,7 +446,7 @@ display_handle_done(void *data,
((float) driverdata->physical_width) / 25.4f,
((float) driverdata->physical_height) / 25.4f);
}
- mode.refresh_rate = driverdata->refresh / 1000; /* mHz to Hz */
+ mode.refresh_rate = (int)SDL_round(driverdata->refresh / 1000.0); /* mHz to Hz */
mode.driverdata = driverdata->output;
if (driverdata->index > -1) {
--
2.34.1

View File

@ -1,54 +0,0 @@
From a90a2e7582a73f7b69b14437287aa15945bf5989 Mon Sep 17 00:00:00 2001
From: Weng Xuetian <wengxt@gmail.com>
Date: Sun, 30 Jan 2022 16:44:44 -0800
Subject: [PATCH 10/11] Fix text_input_v3 preedit string
For every batch of text_input_v3 updates, if there is no preedit in this
batch, preedit should be cleared.
---
src/video/wayland/SDL_waylandevents.c | 8 +++++++-
src/video/wayland/SDL_waylandkeyboard.h | 1 +
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index bf2aeea5b..85d4edfc8 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -1505,7 +1505,9 @@ text_input_preedit_string(void *data,
int32_t cursor_begin,
int32_t cursor_end)
{
+ SDL_WaylandTextInput *text_input = data;
char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
+ text_input->has_preedit = SDL_TRUE;
if (text) {
size_t text_bytes = SDL_strlen(text), i = 0;
size_t cursor = 0;
@@ -1557,7 +1559,11 @@ text_input_done(void *data,
struct zwp_text_input_v3 *zwp_text_input_v3,
uint32_t serial)
{
- /* No-op */
+ SDL_WaylandTextInput *text_input = data;
+ if (!text_input->has_preedit) {
+ SDL_SendEditingText("", 0, 0);
+ }
+ text_input->has_preedit = SDL_FALSE;
}
static const struct zwp_text_input_v3_listener text_input_listener = {
diff --git a/src/video/wayland/SDL_waylandkeyboard.h b/src/video/wayland/SDL_waylandkeyboard.h
index dd8c146e6..604e0f37f 100644
--- a/src/video/wayland/SDL_waylandkeyboard.h
+++ b/src/video/wayland/SDL_waylandkeyboard.h
@@ -27,6 +27,7 @@ typedef struct SDL_WaylandTextInput
{
struct zwp_text_input_v3 *text_input;
SDL_Rect cursor_rect;
+ SDL_bool has_preedit;
} SDL_WaylandTextInput;
extern int Wayland_InitKeyboard(_THIS);
--
2.34.1

View File

@ -1,42 +0,0 @@
From b11dfd761181ab5005fe3f5527faa4faf6b56112 Mon Sep 17 00:00:00 2001
From: Weng Xuetian <wengxt@gmail.com>
Date: Tue, 1 Feb 2022 14:43:26 -0800
Subject: [PATCH 11/11] Only generate key repetition for keys that should
repeat on wayland.
This fix repetition on modifier keys, e.g. Control.
---
src/video/wayland/SDL_waylandevents.c | 4 +++-
src/video/wayland/SDL_waylandsym.h | 1 +
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index 85d4edfc8..55893201b 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -987,7 +987,9 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
SDL_SendKeyboardText(text);
}
}
- keyboard_repeat_set(&input->keyboard_repeat, time, scancode, has_text, text);
+ if (input->xkb.keymap && WAYLAND_xkb_keymap_key_repeats(input->xkb.keymap, key + 8)) {
+ keyboard_repeat_set(&input->keyboard_repeat, time, scancode, has_text, text);
+ }
}
}
diff --git a/src/video/wayland/SDL_waylandsym.h b/src/video/wayland/SDL_waylandsym.h
index 366ce9e94..fa29bedb1 100644
--- a/src/video/wayland/SDL_waylandsym.h
+++ b/src/video/wayland/SDL_waylandsym.h
@@ -122,6 +122,7 @@ SDL_WAYLAND_SYM(int, xkb_state_key_get_syms, (struct xkb_state *, xkb_keycode_t,
SDL_WAYLAND_SYM(int, xkb_keysym_to_utf8, (xkb_keysym_t, char *, size_t) )
SDL_WAYLAND_SYM(struct xkb_keymap *, xkb_keymap_new_from_string, (struct xkb_context *, const char *, enum xkb_keymap_format, enum xkb_keymap_compile_flags))
SDL_WAYLAND_SYM(struct xkb_state *, xkb_state_new, (struct xkb_keymap *) )
+SDL_WAYLAND_SYM(int, xkb_keymap_key_repeats, (struct xkb_keymap *keymap, xkb_keycode_t key) );
SDL_WAYLAND_SYM(void, xkb_keymap_unref, (struct xkb_keymap *) )
SDL_WAYLAND_SYM(void, xkb_state_unref, (struct xkb_state *) )
SDL_WAYLAND_SYM(void, xkb_context_unref, (struct xkb_context *) )
--
2.34.1

View File

@ -1,14 +1,23 @@
From 8ceba27d6291f1195e13608033ec439aec621fc6 Mon Sep 17 00:00:00 2001 From 68d8a2c6b4f732920df40bd79dc3c18b71a4a349 Mon Sep 17 00:00:00 2001
From: Ethan Lee <flibitijibibo@gmail.com> From: Neal Gompa <ngompa@fedoraproject.org>
Date: Sat, 17 Apr 2021 12:07:38 -0400 Date: Fri, 29 Apr 2022 23:39:39 -0400
Subject: [PATCH] video: Prefer Wayland over X11 Subject: [PATCH] Revert "Revert "video: Prefer Wayland over X11""
For Fedora/RHEL, we want to continue using Wayland by default.
The majority of issues around Wayland by default seem to center
around cases that are issues for the Steam Runtime's bundled
copy of SDL and proprietary games that depend on that runtime.
These issues do not apply to us.
This reverts commit 254fcc90eb22bb159ab365ad956222a9c5632841.
--- ---
src/video/SDL_video.c | 24 ++++++++++++------------ src/video/SDL_video.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-) 1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index dac8d1cc9..d3fe65502 100644 index 2b896c44b..6f31f4c9e 100644
--- a/src/video/SDL_video.c --- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c +++ b/src/video/SDL_video.c
@@ -61,12 +61,12 @@ static VideoBootStrap *bootstrap[] = { @@ -61,12 +61,12 @@ static VideoBootStrap *bootstrap[] = {
@ -27,7 +36,7 @@ index dac8d1cc9..d3fe65502 100644
#if SDL_VIDEO_DRIVER_VIVANTE #if SDL_VIDEO_DRIVER_VIVANTE
&VIVANTE_bootstrap, &VIVANTE_bootstrap,
#endif #endif
@@ -4249,12 +4249,12 @@ SDL_IsScreenKeyboardShown(SDL_Window *window) @@ -4275,12 +4275,12 @@ SDL_IsScreenKeyboardShown(SDL_Window *window)
#if SDL_VIDEO_DRIVER_UIKIT #if SDL_VIDEO_DRIVER_UIKIT
#include "uikit/SDL_uikitmessagebox.h" #include "uikit/SDL_uikitmessagebox.h"
#endif #endif
@ -43,7 +52,7 @@ index dac8d1cc9..d3fe65502 100644
#if SDL_VIDEO_DRIVER_HAIKU #if SDL_VIDEO_DRIVER_HAIKU
#include "haiku/SDL_bmessagebox.h" #include "haiku/SDL_bmessagebox.h"
#endif #endif
@@ -4362,17 +4362,17 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) @@ -4388,17 +4388,17 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
retval = 0; retval = 0;
} }
#endif #endif
@ -68,5 +77,5 @@ index dac8d1cc9..d3fe65502 100644
} }
#endif #endif
-- --
2.34.1 2.35.1

View File

@ -9,8 +9,8 @@
%global libdecor_majver 0 %global libdecor_majver 0
Name: SDL2 Name: SDL2
Version: 2.0.20 Version: 2.0.22
Release: 3%{?dist} Release: 1%{?dist}
Summary: Cross-platform multimedia library Summary: Cross-platform multimedia library
License: zlib and MIT License: zlib and MIT
URL: http://www.libsdl.org/ URL: http://www.libsdl.org/
@ -21,33 +21,8 @@ Source2: SDL_revision.h
Patch0: multilib.patch Patch0: multilib.patch
# ptrdiff_t is not the same as khronos defines on 32bit arches # ptrdiff_t is not the same as khronos defines on 32bit arches
Patch1: SDL2-2.0.9-khrplatform.patch Patch1: SDL2-2.0.9-khrplatform.patch
# Prefer Wayland by default
# Wayland backports Patch2: SDL2-2.0.22-prefer-wayland.patch
# From git format-patch release-2.0.20..68dd84f1de159b2e6ae1d5a23f842ee87f8a175a src/video/wayland/
Patch0101: 0001-wayland-Convert-URI-to-local-path-for-DropFile.patch
Patch0102: 0002-wayland-Avoid-spurious-resize-events.patch
Patch0103: 0003-wayland-Fix-building-with-SDL_OPENGL-OFF.patch
Patch0104: 0004-wayland-Avoid-calling-SetFullscreen-in-libdecor-Show.patch
Patch0105: 0005-wayland-Detach-hidden-surfaces-in-HideWindow-not-Sho.patch
Patch0106: 0006-wayland-Call-SetFullscreen-directly-in-ShowWindow.patch
Patch0107: 0007-wayland-Try-to-avoid-committing-before-the-window-is.patch
Patch0108: 0008-wayland-Fix-SDL_SetWindowSize-being-dropped-right-af.patch
Patch0109: 0009-wayland-Round-the-refresh-rate-rather-than-truncatin.patch
Patch0110: 0010-Fix-text_input_v3-preedit-string.patch
Patch0111: 0011-Only-generate-key-repetition-for-keys-that-should-re.patch
# From: https://github.com/libsdl-org/SDL/commit/8ceba27d6291f1195e13608033ec439aec621fc6
Patch0199: 0001-video-Prefer-Wayland-over-X11.patch
# PipeWire backports
# From git format-patch release-2.0.20..68dd84f1de159b2e6ae1d5a23f842ee87f8a175a src/audio/pipewire/
Patch0201: 0001-audio-pipewire-Use-client-config-files-instead-of-mo.patch
Patch0202: 0002-cleanup-init-functions-of-audio.patch
Patch0203: 0003-adjust-handling-of-iscapture.patch
Patch0204: 0004-drop-handle-parameter-of-OpenDevice.patch
Patch0205: 0005-audio-pipewire-Don-t-double-free-properties-on-init-.patch
Patch0206: 0006-audio-pipewire-Condition-variable-doesn-t-need-to-be.patch
Patch0207: 0007-audio-pipewire-Remove-the-hard-upper-bound-on-rates-.patch
BuildRequires: git-core BuildRequires: git-core
BuildRequires: cmake BuildRequires: cmake
@ -194,6 +169,10 @@ install -p -m 644 %{SOURCE2} %{buildroot}%{_includedir}/SDL2/SDL_revision.h
%{_libdir}/cmake/SDL2/SDL2staticTargets*.cmake %{_libdir}/cmake/SDL2/SDL2staticTargets*.cmake
%changelog %changelog
* Sat Apr 30 2022 Neal Gompa <ngompa@fedoraproject.org> - 2.0.22-1
- Update to 2.0.22
- Drop backported patches included in this release
* Tue Feb 08 2022 Neal Gompa <ngompa@fedoraproject.org> - 2.0.20-3 * Tue Feb 08 2022 Neal Gompa <ngompa@fedoraproject.org> - 2.0.20-3
- Backport Wayland and PipeWire fixes from upstream - Backport Wayland and PipeWire fixes from upstream

View File

@ -1 +1 @@
SHA512 (SDL2-2.0.20.tar.gz) = 4889949eaa674948bdb0a01bb2a842a0943b15b08ff27ec0079b0fd4f79d071ffb32488a5a51c12ad7c74ed5fe73b608cdf6336a44c95dae8a0fb3f47d0f01de SHA512 (SDL2-2.0.22.tar.gz) = ca4b690433cd4d9d73b797da98666317128e7e817ab60e874a49d94791ea41e8a6b4fc43649593120daa0702190c0f8a6ed326c908d87375c8da9f369d994f6a