sdl12-compat: quirks: Force X11 on Linux if certain symbols are in the process.

From 2a96bb35d7562f75c710e5824a49eb14c13c1bac Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Sun, 16 Oct 2022 07:49:36 -0400
Subject: [PATCH] quirks: Force X11 on Linux if certain symbols are in the
 process.

So if we see the process references GLEW or Nvidia Cg, we assume the
app will fail if it can't talk to glX.

This automates the process in many cases instead of having to list these
specific titles in the quirks table.

This patch in its initial form, and the idea, are from @smvc (thanks!).

Fixes #249.
Fixes #252.
Fixes #258.
Fixes #262.
Fixes #263.
---
 src/SDL12_compat.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c
index d502c00d1..cb97408e5 100644
--- a/src/SDL12_compat.c
+++ b/src/SDL12_compat.c
@@ -1189,11 +1189,9 @@ static QuirkEntryType quirks[] = {
 #if defined(__unix__)
     /* Awesomenauts uses Cg, and does weird things with the GL context. */
     {"Awesomenauts.bin.x86", "SDL12COMPAT_OPENGL_SCALING", "0"},
-    {"Awesomenauts.bin.x86", "SDL_VIDEODRIVER", "x11"},
     {"Awesomenauts.bin.x86", "SDL12COMPAT_FORCE_GL_SWAPBUFFER_CONTEXT", "1"},
 
     /* Braid uses Cg, which uses glXGetProcAddress(). */
-    {"braid", "SDL_VIDEODRIVER", "x11"},
     {"braid", "SDL12COMPAT_OPENGL_SCALING", "0"},
 
     /* GOG's DOSBox builds have architecture-specific filenames. */
@@ -1329,6 +1327,30 @@ SDL12Compat_ApplyQuirks(void)
             }
         }
     }
+
+    #ifdef __linux__
+    {
+        void *global_symbols = dlopen(NULL, RTLD_LOCAL|RTLD_NOW);
+        SDL_bool force_x11 = SDL_FALSE;
+
+        /* Use linked libraries to detect what quirks we are likely to need */
+        if (global_symbols != NULL) {
+            /* GLEW (e.g. Frogatto, SLUDGE) */
+            if (dlsym(global_symbols, "glxewInit") != NULL) { force_x11 = SDL_TRUE; }
+            /* NVIDIA Cg (e.g. Awesomenauts, Braid) */
+            else if (dlsym(global_symbols, "cgGLEnableProgramProfiles") != NULL) { force_x11 = SDL_TRUE; }
+        }
+
+        dlclose(global_symbols);
+
+        if (force_x11) {
+            SDL20_Log("sdl12-compat: We are forcing this app to use X11, because it probably");
+            SDL20_Log("sdl12-compat: talks to an X server directly, outside of SDL. If possible,");
+            SDL20_Log("sdl12-compat: this app should be fixed, to be compatible with Wayland, etc.");
+            SDL20_setenv("SDL_VIDEODRIVER", "x11", 1);
+        }
+    }
+    #endif
 }
 
 static int