SDL: audio/video: Skip preferred drivers when loading a driver on demand

From 706de78a9ec2abace956e3c24e61877629648bdb Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Tue, 11 Feb 2025 10:33:54 -0500
Subject: [PATCH] audio/video: Skip preferred drivers when loading a driver on
 demand

Preferred driver entries have special conditions for initializing, which aren't relevant when a specific driver was explicitly requested.
---
 src/audio/SDL_audio.c                | 2 +-
 src/audio/SDL_sysaudio.h             | 1 +
 src/audio/pipewire/SDL_pipewire.c    | 2 +-
 src/video/SDL_sysvideo.h             | 1 +
 src/video/SDL_video.c                | 3 ++-
 src/video/wayland/SDL_waylandvideo.c | 3 ++-
 6 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index db4c55f3fde3a..a503a4e170665 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -964,7 +964,7 @@ bool SDL_InitAudio(const char *driver_name)
             }
 
             for (int i = 0; bootstrap[i]; ++i) {
-                if (SDL_strcasecmp(bootstrap[i]->name, driver_attempt) == 0) {
+                if (!bootstrap[i]->is_preferred && SDL_strcasecmp(bootstrap[i]->name, driver_attempt) == 0) {
                     tried_to_init = true;
                     SDL_zero(current_audio);
                     current_audio.pending_events_tail = &current_audio.pending_events;
diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h
index c8af24412a810..4a88bd2302410 100644
--- a/src/audio/SDL_sysaudio.h
+++ b/src/audio/SDL_sysaudio.h
@@ -360,6 +360,7 @@ typedef struct AudioBootStrap
     const char *desc;
     bool (*init)(SDL_AudioDriverImpl *impl);
     bool demand_only; // if true: request explicitly, or it won't be available.
+    bool is_preferred;
 } AudioBootStrap;
 
 // Not all of these are available in a given build. Use #ifdefs, etc.
diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c
index dfb5d6cf3eebb..72e90db1c2711 100644
--- a/src/audio/pipewire/SDL_pipewire.c
+++ b/src/audio/pipewire/SDL_pipewire.c
@@ -1337,7 +1337,7 @@ static bool PIPEWIRE_Init(SDL_AudioDriverImpl *impl)
 }
 
 AudioBootStrap PIPEWIRE_PREFERRED_bootstrap = {
-    "pipewire", "Pipewire", PIPEWIRE_PREFERRED_Init, false
+    "pipewire", "Pipewire", PIPEWIRE_PREFERRED_Init, false, true
 };
 AudioBootStrap PIPEWIRE_bootstrap = {
     "pipewire", "Pipewire", PIPEWIRE_Init, false
diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h
index e043305aa06b8..6951d456424ae 100644
--- a/src/video/SDL_sysvideo.h
+++ b/src/video/SDL_sysvideo.h
@@ -504,6 +504,7 @@ typedef struct VideoBootStrap
     const char *desc;
     SDL_VideoDevice *(*create)(void);
     bool (*ShowMessageBox)(const SDL_MessageBoxData *messageboxdata, int *buttonID);  // can be done without initializing backend!
+    bool is_preferred;
 } VideoBootStrap;
 
 // Not all of these are available in a given build. Use #ifdefs, etc.
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index e773969183f01..d2f0800b364fe 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -654,7 +654,8 @@ bool SDL_VideoInit(const char *driver_name)
                                                                      : SDL_strlen(driver_attempt);
 
             for (i = 0; bootstrap[i]; ++i) {
-                if ((driver_attempt_len == SDL_strlen(bootstrap[i]->name)) &&
+                if (!bootstrap[i]->is_preferred &&
+                    (driver_attempt_len == SDL_strlen(bootstrap[i]->name)) &&
                     (SDL_strncasecmp(bootstrap[i]->name, driver_attempt, driver_attempt_len) == 0)) {
                     video = bootstrap[i]->create();
                     if (video) {
diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
index 944d0d91494d8..7ec0d5c2b5b6a 100644
--- a/src/video/wayland/SDL_waylandvideo.c
+++ b/src/video/wayland/SDL_waylandvideo.c
@@ -685,7 +685,8 @@ static SDL_VideoDevice *Wayland_Fallback_CreateDevice(void)
 VideoBootStrap Wayland_preferred_bootstrap = {
     WAYLANDVID_DRIVER_NAME, "SDL Wayland video driver",
     Wayland_Preferred_CreateDevice,
-    Wayland_ShowMessageBox
+    Wayland_ShowMessageBox,
+    true
 };
 
 VideoBootStrap Wayland_bootstrap = {