Skip to content

Commit 8796f0a

Browse files
committed
SDL_gtk: Prevent loading GTK-3 if a different version of GTK is already loaded
- gtk_init_check claims it will not terminate the program on failure, however this is does not apply to the internal check it performs to see whether another GTK library is already loaded, the detection of which triggers a g_error which glib treats as fatal. - gtk_progress_get_type and gtk_misc_get_type are checked to match the checks done by _gtk_module_has_mixed_deps. - Clean up gtk/gdk loading. There are no library fallbacks so the one option available can be loaded rather than iterating through a list of one item.
1 parent f241e8e commit 8796f0a

File tree

1 file changed

+23
-25
lines changed

1 file changed

+23
-25
lines changed

src/core/unix/SDL_gtk.c

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include "SDL_internal.h"
2222
#include "SDL_gtk.h"
2323

24+
#include <dlfcn.h>
25+
2426
#define SDL_GTK_SYM2_OPTIONAL(ctx, lib, sub, fn, sym) \
2527
ctx.sub.fn = (void *)SDL_LoadFunction(lib, #sym)
2628

@@ -35,25 +37,19 @@
3537
#define SDL_GTK_SYM(ctx, lib, sub, fn) \
3638
SDL_GTK_SYM2(ctx, lib, sub, fn, sub##_##fn)
3739

38-
// we never link directly to gtk
39-
static const char *gdk_names[] = {
4040
#ifdef SDL_PLATFORM_OPENBSD
41-
"libgdk-3.so",
41+
#define GDK3_LIB "libgdk-3.so"
4242
#else
43-
"libgdk-3.so.0",
43+
#define GDK3_LIB "libgdk-3.so.0"
4444
#endif
45-
NULL
46-
};
4745

48-
static const char *gtk_names[] = {
4946
#ifdef SDL_PLATFORM_OPENBSD
50-
"libgtk-3.so",
47+
#define GTK3_LIB "libgtk-3.so"
5148
#else
52-
"libgtk-3.so.0",
49+
#define GTK3_LIB "libgtk-3.so.0"
5350
#endif
54-
NULL
55-
};
5651

52+
// we never link directly to gtk
5753
static void *libgdk = NULL;
5854
static void *libgtk = NULL;
5955

@@ -74,18 +70,6 @@ static void QuitGtk(void)
7470
libgtk = NULL;
7571
}
7672

77-
static void *FindLib(const char **names)
78-
{
79-
const char **name_ptr = names;
80-
void *handle = NULL;
81-
82-
do {
83-
handle = SDL_LoadObject(*name_ptr);
84-
} while (*++name_ptr && !handle);
85-
86-
return handle;
87-
}
88-
8973
static bool IsGtkInit()
9074
{
9175
return libgdk != NULL && libgtk != NULL;
@@ -101,8 +85,22 @@ static bool InitGtk(void)
10185
return true;
10286
}
10387

104-
libgdk = FindLib(gdk_names);
105-
libgtk = FindLib(gtk_names);
88+
// GTK only allows a single version to be loaded into a process at a time,
89+
// so if there is one already loaded ensure it is the version we use.
90+
void *progress_get_type = dlsym(RTLD_DEFAULT, "gtk_progress_get_type");
91+
void *misc_get_type = dlsym(RTLD_DEFAULT, "gtk_misc_get_type");
92+
if (progress_get_type || misc_get_type) {
93+
void *libgtk3 = dlopen(GTK3_LIB, RTLD_NOLOAD | RTLD_LAZY);
94+
if (!libgtk3) {
95+
QuitGtk();
96+
return SDL_SetError("Could not load GTK-3, another GTK version already present");
97+
}
98+
99+
dlclose(libgtk3);
100+
}
101+
102+
libgdk = SDL_LoadObject(GDK3_LIB);
103+
libgtk = SDL_LoadObject(GTK3_LIB);
106104

107105
if (!libgdk || !libgtk) {
108106
QuitGtk();

0 commit comments

Comments
 (0)