SDL: alsa: Use more hints for opening default devices.

From 35360ec4d7bf0eb46e089c58656146bda58e9468 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Sun, 15 Dec 2024 16:20:32 -0500
Subject: [PATCH] alsa: Use more hints for opening default devices.

---
 include/SDL3/SDL_hints.h        | 48 ++++++++++++++++++++++++++++++---
 src/audio/alsa/SDL_alsa_audio.c | 23 ++++++++--------
 2 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h
index a01e5abd86def..ebaea17e0c6a9 100644
--- a/include/SDL3/SDL_hints.h
+++ b/include/SDL3/SDL_hints.h
@@ -216,16 +216,58 @@ extern "C" {
  * Specify the default ALSA audio device name.
  *
  * This variable is a specific audio device to open when the "default" audio
- * device is used. By default if 4 channel audio is requested, the
- * "plug:surround40" device will be opened and if 6 channel audio is requested
- * the "plug:surround51" device will be opened.
+ * device is used.
+ *
+ * This hint will be ignored when opening the default playback device if
+ * SDL_HINT_AUDIO_ALSA_DEFAULT_PLAYBACK_DEVICE is set, or when opening the
+ * default recording device if SDL_HINT_AUDIO_ALSA_DEFAULT_RECORDING_DEVICE
+ * is set.
  *
  * This hint should be set before an audio device is opened.
  *
  * \since This hint is available since SDL 3.1.3.
+ *
+ * \sa SDL_HINT_AUDIO_ALSA_DEFAULT_PLAYBACK_DEVICE
+ * \sa SDL_HINT_AUDIO_ALSA_DEFAULT_RECORDING_DEVICE
  */
 #define SDL_HINT_AUDIO_ALSA_DEFAULT_DEVICE "SDL_AUDIO_ALSA_DEFAULT_DEVICE"
 
+/**
+ * Specify the default ALSA audio playback device name.
+ *
+ * This variable is a specific audio device to open for playback, when the
+ * "default" audio device is used.
+ *
+ * If this hint isn't set, SDL will check SDL_HINT_AUDIO_ALSA_DEFAULT_DEVICE
+ * before choosing a reasonable default.
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.1.7.
+ *
+ * \sa SDL_HINT_AUDIO_ALSA_DEFAULT_RECORDING_DEVICE
+ * \sa SDL_HINT_AUDIO_ALSA_DEFAULT_DEVICE
+ */
+#define SDL_HINT_AUDIO_ALSA_DEFAULT_PLAYBACK_DEVICE "SDL_AUDIO_ALSA_DEFAULT_PLAYBACK_DEVICE"
+
+/**
+ * Specify the default ALSA audio recording device name.
+ *
+ * This variable is a specific audio device to open for recording, when the
+ * "default" audio device is used.
+ *
+ * If this hint isn't set, SDL will check SDL_HINT_AUDIO_ALSA_DEFAULT_DEVICE
+ * before choosing a reasonable default.
+ *
+ * This hint should be set before an audio device is opened.
+ *
+ * \since This hint is available since SDL 3.1.7.
+ *
+ * \sa SDL_HINT_AUDIO_ALSA_DEFAULT_PLAYBACK_DEVICE
+ * \sa SDL_HINT_AUDIO_ALSA_DEFAULT_DEVICE
+ */
+#define SDL_HINT_AUDIO_ALSA_DEFAULT_RECORDING_DEVICE "SDL_AUDIO_ALSA_DEFAULT_RECORDING_DEVICE"
+
 /**
  * A variable controlling the audio category on iOS and macOS.
  *
diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c
index fe5c1a236f02f..1b635dbf38962 100644
--- a/src/audio/alsa/SDL_alsa_audio.c
+++ b/src/audio/alsa/SDL_alsa_audio.c
@@ -325,19 +325,20 @@ static char *get_pcm_str(void *handle)
 {
     SDL_assert(handle != NULL);  // SDL2 used NULL to mean "default" but that's not true in SDL3.
     ALSA_Device *dev = (ALSA_Device *)handle;
-
-    // If the user does not want to go thru the default PCM or the canonical default, the
-    // the configuration space being _massive_, give the user the ability to specify
-    // its own PCMs using environment variables. It will have to fit SDL constraints though.
-    // !!! FIXME: make these into SDL_Hints?
-    const char *env = SDL_getenv(dev->recording ? "SDL_AUDIO_ALSA_PCM_RECORDING" : "SDL_AUDIO_ALSA_PCM_PLAYBACK");
-    if (env) {
-        return SDL_strdup(env);
-    }
-
     char *pcm_str = NULL;
+
     if (SDL_strlen(dev->id) == 0) {
-        pcm_str = SDL_strdup("default");
+        // If the user does not want to go thru the default PCM or the canonical default, the
+        // the configuration space being _massive_, give the user the ability to specify
+        // its own PCMs using environment variables. It will have to fit SDL constraints though.
+        const char *devname = SDL_GetHint(dev->recording ? SDL_HINT_AUDIO_ALSA_DEFAULT_RECORDING_DEVICE : SDL_HINT_AUDIO_ALSA_DEFAULT_PLAYBACK_DEVICE);
+        if (!devname) {
+            devname = SDL_GetHint(SDL_HINT_AUDIO_ALSA_DEFAULT_DEVICE);
+            if (!devname) {
+                devname = "default";
+            }
+        }
+        pcm_str = SDL_strdup(devname);
     } else {
         SDL_asprintf(&pcm_str, "%sCARD=%s", ALSA_device_prefix, dev->id);
     }