Workaround older libpulse that fails in pa_context_new() with a NULL appname.
authorRyan C. Gordon <icculus@icculus.org>
Tue, 30 Jul 2013 01:32:26 -0400
changeset 7545 adb619b0af9c
parent 7544 0508756e7886
child 7546 f9ff5e066e49
Workaround older libpulse that fails in pa_context_new() with a NULL appname. Newer libpulses do sane defaults if you pass a NULL there. In lieu of a proper way to specify this in SDL at the moment, this will do. Fixes Bugzilla #1119.
src/audio/pulseaudio/SDL_pulseaudio.c
--- a/src/audio/pulseaudio/SDL_pulseaudio.c	Tue Jul 30 01:30:32 2013 -0400
+++ b/src/audio/pulseaudio/SDL_pulseaudio.c	Tue Jul 30 01:32:26 2013 -0400
@@ -65,6 +65,7 @@
 #endif /* pulseaudio <= 0.9.10 */
 
 
+static const char *(*PULSEAUDIO_pa_get_library_version) (void);
 static pa_simple *(*PULSEAUDIO_pa_simple_new) (const char *, const char *,
     pa_stream_direction_t, const char *, const char *, const pa_sample_spec *,
     const pa_channel_map *, const pa_buffer_attr *, int *);
@@ -177,6 +178,7 @@
 static int
 load_pulseaudio_syms(void)
 {
+    SDL_PULSEAUDIO_SYM(pa_get_library_version);
     SDL_PULSEAUDIO_SYM(pa_simple_new);
     SDL_PULSEAUDIO_SYM(pa_simple_free);
     SDL_PULSEAUDIO_SYM(pa_mainloop_new);
@@ -322,6 +324,28 @@
 }
 
 
+static __inline__ int
+squashVersion(const int major, const int minor, const int patch)
+{
+    return ((major & 0xFF) << 16) | ((minor & 0xFF) << 8) | (patch & 0xFF);
+}
+
+/* Workaround for older pulse: pa_context_new() must have non-NULL appname */
+static const char *
+getAppName(void)
+{
+    const char *verstr = PULSEAUDIO_pa_get_library_version();
+    if (verstr != NULL) {
+        int maj, min, patch;
+        if (SDL_sscanf(verstr, "%d.%d.%d", &maj, &min, &patch) == 3) {
+            if (squashVersion(maj, min, patch) >= squashVersion(0, 9, 15)) {
+                return NULL;  /* 0.9.15+ handles NULL correctly. */
+            }
+        }
+    }
+    return "SDL Application";  /* oh well. */
+}
+
 static int
 PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
 {
@@ -432,7 +456,7 @@
     }
 
     h->mainloop_api = PULSEAUDIO_pa_mainloop_get_api(h->mainloop);
-    h->context = PULSEAUDIO_pa_context_new(h->mainloop_api, NULL);
+    h->context = PULSEAUDIO_pa_context_new(h->mainloop_api, getAppName());
     if (!h->context) {
         PULSEAUDIO_CloseDevice(this);
         return SDL_SetError("pa_context_new() failed");