eafton пре 1 дан
родитељ
комит
e4f75bac45
5 измењених фајлова са 64 додато и 438 уклоњено
  1. 0 8
      src/SDL.c
  2. 0 300
      src/core/unix/SDL_gtk.c
  3. 0 126
      src/core/unix/SDL_gtk.h
  4. 64 2
      src/video/wayland/SDL_waylandvideo.c
  5. 0 2
      src/video/x11/SDL_x11modes.c

+ 0 - 8
src/SDL.c

@@ -30,10 +30,6 @@
 // this checks for HAVE_DBUS_DBUS_H internally.
 #include "core/linux/SDL_dbus.h"
 
-#if defined(SDL_PLATFORM_UNIX) && !defined(SDL_PLATFORM_ANDROID)
-#include "core/unix/SDL_gtk.h"
-#endif
-
 #ifdef SDL_PLATFORM_EMSCRIPTEN
 #include <emscripten.h>
 #endif
@@ -714,10 +710,6 @@ void SDL_Quit(void)
     SDL_DBus_Quit();
 #endif
 
-#if defined(SDL_PLATFORM_UNIX) && !defined(SDL_PLATFORM_ANDROID) && !defined(SDL_PLATFORM_EMSCRIPTEN) && !defined(SDL_PLATFORM_PRIVATE)
-    SDL_Gtk_Quit();
-#endif
-
     SDL_QuitTimers();
     SDL_QuitAsyncIO();
 

+ 0 - 300
src/core/unix/SDL_gtk.c

@@ -1,300 +0,0 @@
-/*
-  Simple DirectMedia Layer
-  Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-*/
-#include "SDL_internal.h"
-#include "SDL_gtk.h"
-
-#include <dlfcn.h>
-#include <errno.h>
-#include <unistd.h>
-
-#define SDL_GTK_SYM2_OPTIONAL(ctx, lib, sub, fn, sym)                     \
-    ctx.sub.fn = (void *)SDL_LoadFunction(lib, #sym)
-
-#define SDL_GTK_SYM2(ctx, lib, sub, fn, sym)                              \
-    SDL_GTK_SYM2_OPTIONAL(ctx, lib, sub, fn, sym);                        \
-    if (!ctx.sub.fn) {                                                    \
-        return SDL_SetError("Could not load GTK functions");              \
-    }
-
-#define SDL_GTK_SYM_OPTIONAL(ctx, lib, sub, fn) \
-    SDL_GTK_SYM2_OPTIONAL(ctx, lib, sub, fn, sub##_##fn)
-
-#define SDL_GTK_SYM(ctx, lib, sub, fn) \
-    SDL_GTK_SYM2(ctx, lib, sub, fn, sub##_##fn)
-
-#ifdef SDL_PLATFORM_OPENBSD
-#define GDK3_LIB "libgdk-3.so"
-#else
-#define GDK3_LIB "libgdk-3.so.0"
-#endif
-
-#ifdef SDL_PLATFORM_OPENBSD
-#define GTK3_LIB "libgtk-3.so"
-#else
-#define GTK3_LIB "libgtk-3.so.0"
-#endif
-
-// we never link directly to gtk
-static void *libgdk = NULL;
-static void *libgtk = NULL;
-
-static SDL_GtkContext gtk;
-static GMainContext *sdl_main_context;
-
-static gulong signal_connect(gpointer instance, const gchar *detailed_signal, void *c_handler, gpointer data)
-{
-    return gtk.g.signal_connect_data(instance, detailed_signal, SDL_G_CALLBACK(c_handler), data, NULL, (SDL_GConnectFlags)0);
-}
-
-static void QuitGtk(void)
-{
-    if (sdl_main_context) {
-        gtk.g.main_context_unref(sdl_main_context);
-        sdl_main_context = NULL;
-    }
-
-    SDL_UnloadObject(libgdk);
-    SDL_UnloadObject(libgtk);
-
-    libgdk = NULL;
-    libgtk = NULL;
-}
-
-static bool IsGtkInit(void)
-{
-    return libgdk != NULL && libgtk != NULL;
-}
-
-#ifndef HAVE_GETRESUID
-// Non-POSIX, but Linux and some BSDs have it.
-// To reduce the number of code paths, if getresuid() isn't available at
-// compile-time, we behave as though it existed but failed at runtime.
-static inline int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) {
-    errno = ENOSYS;
-    return -1;
-}
-#endif
-
-#ifndef HAVE_GETRESGID
-// Same as getresuid() but for the primary group
-static inline int getresgid(uid_t *ruid, uid_t *euid, uid_t *suid) {
-    errno = ENOSYS;
-    return -1;
-}
-#endif
-
-bool SDL_CanUseGtk(void)
-{
-    // "Real", "effective" and "saved" IDs: see e.g. Linux credentials(7)
-    uid_t ruid = -1, euid = -1, suid = -1;
-    gid_t rgid = -1, egid = -1, sgid = -1;
-
-    if (!SDL_GetHintBoolean("SDL_ENABLE_GTK", true)) {
-        SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Not using GTK due to hint");
-        return false;
-    }
-
-    // This is intended to match the check in gtkmain.c, rather than being
-    // an exhaustive check for having elevated privileges: as a result
-    // we don't use Linux getauxval() or prctl PR_GET_DUMPABLE,
-    // BSD issetugid(), or similar OS-specific detection
-
-    if (getresuid(&ruid, &euid, &suid) != 0) {
-        ruid = suid = getuid();
-        euid = geteuid();
-    }
-
-    if (getresgid(&rgid, &egid, &sgid) != 0) {
-        rgid = sgid = getgid();
-        egid = getegid();
-    }
-
-    // Real ID != effective ID means we are setuid or setgid:
-    // GTK will refuse to initialize, and instead will call exit().
-    if (ruid != euid || rgid != egid) {
-        SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Not using GTK due to setuid/setgid");
-        return false;
-    }
-
-    // Real ID != saved ID means we are setuid or setgid, we previously
-    // dropped privileges, but we can regain them; this protects against
-    // accidents but does not protect against arbitrary code execution.
-    // Again, GTK will refuse to initialize if this is the case.
-    if (ruid != suid || rgid != sgid) {
-        SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Not using GTK due to saved uid/gid");
-        return false;
-    }
-
-    return true;
-}
-
-static bool InitGtk(void)
-{
-    if (!SDL_CanUseGtk()) {
-        return false;
-    }
-
-    if (IsGtkInit()) {
-        return true;
-    }
-
-    // GTK only allows a single version to be loaded into a process at a time,
-    // so if there is one already loaded ensure it is the version we use.
-    void *progress_get_type = dlsym(RTLD_DEFAULT, "gtk_progress_get_type");
-    void *misc_get_type = dlsym(RTLD_DEFAULT, "gtk_misc_get_type");
-    if (progress_get_type || misc_get_type) {
-        void *libgtk3 = dlopen(GTK3_LIB, RTLD_NOLOAD | RTLD_LAZY);
-        if (!libgtk3) {
-            QuitGtk();
-            return SDL_SetError("Could not load GTK-3, another GTK version already present");
-        }
-
-        dlclose(libgtk3);
-    }
-
-    libgdk = SDL_LoadObject(GDK3_LIB);
-    libgtk = SDL_LoadObject(GTK3_LIB);
-
-    if (!libgdk || !libgtk) {
-        QuitGtk();
-        return SDL_SetError("Could not load GTK libraries");
-    }
-
-    SDL_GTK_SYM(gtk, libgtk, gtk, init_check);
-    SDL_GTK_SYM(gtk, libgtk, gtk, menu_new);
-    SDL_GTK_SYM(gtk, libgtk, gtk, separator_menu_item_new);
-    SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_new_with_label);
-    SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_set_submenu);
-    SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_get_label);
-    SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_set_label);
-    SDL_GTK_SYM(gtk, libgtk, gtk, menu_shell_append);
-    SDL_GTK_SYM(gtk, libgtk, gtk, menu_shell_insert);
-    SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_new_with_label);
-    SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_get_active);
-    SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_set_active);
-    SDL_GTK_SYM(gtk, libgtk, gtk, widget_show);
-    SDL_GTK_SYM(gtk, libgtk, gtk, widget_destroy);
-    SDL_GTK_SYM(gtk, libgtk, gtk, widget_get_sensitive);
-    SDL_GTK_SYM(gtk, libgtk, gtk, widget_set_sensitive);
-    SDL_GTK_SYM(gtk, libgtk, gtk, settings_get_default);
-
-    SDL_GTK_SYM(gtk, libgdk, g, signal_connect_data);
-    SDL_GTK_SYM(gtk, libgdk, g, mkdtemp);
-    SDL_GTK_SYM(gtk, libgdk, g, get_user_cache_dir);
-    SDL_GTK_SYM(gtk, libgdk, g, object_ref);
-    SDL_GTK_SYM(gtk, libgdk, g, object_ref_sink);
-    SDL_GTK_SYM(gtk, libgdk, g, object_unref);
-    SDL_GTK_SYM(gtk, libgdk, g, object_get);
-    SDL_GTK_SYM(gtk, libgdk, g, signal_handler_disconnect);
-    SDL_GTK_SYM(gtk, libgdk, g, main_context_push_thread_default);
-    SDL_GTK_SYM(gtk, libgdk, g, main_context_pop_thread_default);
-    SDL_GTK_SYM(gtk, libgdk, g, main_context_new);
-    SDL_GTK_SYM(gtk, libgdk, g, main_context_unref);
-    SDL_GTK_SYM(gtk, libgdk, g, main_context_acquire);
-    SDL_GTK_SYM(gtk, libgdk, g, main_context_iteration);
-
-    gtk.g.signal_connect = signal_connect;
-
-    if (gtk.gtk.init_check(NULL, NULL) == GTK_FALSE) {
-        QuitGtk();
-        return SDL_SetError("Could not init GTK");
-    }
-
-    sdl_main_context = gtk.g.main_context_new();
-    if (!sdl_main_context) {
-        QuitGtk();
-        return SDL_SetError("Could not create GTK context");
-    }
-
-    if (!gtk.g.main_context_acquire(sdl_main_context)) {
-        QuitGtk();
-        return SDL_SetError("Could not acquire GTK context");
-    }
-
-    return true;
-}
-
-static SDL_InitState gtk_init;
-
-bool SDL_Gtk_Init(void)
-{
-    static bool is_gtk_available = true;
-
-    if (!is_gtk_available) {
-        return false; // don't keep trying if this fails.
-    }
-
-    if (SDL_ShouldInit(&gtk_init)) {
-        if (InitGtk()) {
-            SDL_SetInitialized(&gtk_init, true);
-        } else {
-            is_gtk_available = false;
-            SDL_SetInitialized(&gtk_init, true);
-            SDL_Gtk_Quit();
-        }
-    }
-
-    return IsGtkInit();
-}
-
-void SDL_Gtk_Quit(void)
-{
-    if (!SDL_ShouldQuit(&gtk_init)) {
-        return;
-    }
-
-    QuitGtk();
-    SDL_zero(gtk);
-
-    SDL_SetInitialized(&gtk_init, false);
-}
-
-SDL_GtkContext *SDL_Gtk_GetContext(void)
-{
-    return IsGtkInit() ? &gtk : NULL;
-}
-
-SDL_GtkContext *SDL_Gtk_EnterContext(void)
-{
-    SDL_Gtk_Init();
-
-    if (IsGtkInit()) {
-        gtk.g.main_context_push_thread_default(sdl_main_context);
-        return &gtk;
-    }
-
-    return NULL;
-}
-
-void SDL_Gtk_ExitContext(SDL_GtkContext *ctx)
-{
-    if (ctx) {
-        ctx->g.main_context_pop_thread_default(sdl_main_context);
-    }
-}
-
-void SDL_UpdateGtk(void)
-{
-    if (IsGtkInit()) {
-        gtk.g.main_context_iteration(sdl_main_context, GTK_FALSE);
-        gtk.g.main_context_iteration(NULL, GTK_FALSE);
-    }
-}

+ 0 - 126
src/core/unix/SDL_gtk.h

@@ -1,126 +0,0 @@
-/*
-  Simple DirectMedia Layer
-  Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include "SDL_internal.h"
-
-#ifndef SDL_gtk_h_
-#define SDL_gtk_h_
-
-/* Glib 2.0 */
-
-typedef unsigned long gulong;
-typedef void *gpointer;
-typedef char gchar;
-typedef int gint;
-typedef unsigned int guint;
-typedef double gdouble;
-typedef gint gboolean;
-typedef void (*GCallback)(void);
-typedef struct _GClosure GClosure;
-typedef void (*GClosureNotify) (gpointer data, GClosure *closure);
-typedef gboolean (*GSourceFunc) (gpointer user_data);
-
-typedef struct _GParamSpec GParamSpec;
-typedef struct _GMainContext GMainContext;
-
-typedef enum SDL_GConnectFlags
-{
-    SDL_G_CONNECT_DEFAULT = 0,
-    SDL_G_CONNECT_AFTER = 1 << 0,
-    SDL_G_CONNECT_SWAPPED = 1 << 1
-} SDL_GConnectFlags;
-
-#define SDL_G_CALLBACK(f) ((GCallback) (f))
-#define SDL_G_TYPE_CIC(ip, gt, ct) ((ct*) ip)
-#define SDL_G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (SDL_G_TYPE_CIC ((instance), (g_type), c_type))
-
-#define GTK_FALSE 0
-#define GTK_TRUE 1
-
-
-/* GTK 3.0 */
-
-typedef struct _GtkMenu GtkMenu;
-typedef struct _GtkMenuItem GtkMenuItem;
-typedef struct _GtkMenuShell GtkMenuShell;
-typedef struct _GtkWidget GtkWidget;
-typedef struct _GtkCheckMenuItem GtkCheckMenuItem;
-typedef struct _GtkSettings GtkSettings;
-
-#define GTK_MENU_ITEM(obj) (SDL_G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_ITEM, GtkMenuItem))
-#define GTK_WIDGET(widget) (SDL_G_TYPE_CHECK_INSTANCE_CAST ((widget), GTK_TYPE_WIDGET, GtkWidget))
-#define GTK_CHECK_MENU_ITEM(obj) (SDL_G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CHECK_MENU_ITEM, GtkCheckMenuItem))
-#define GTK_MENU(obj) (SDL_G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU, GtkMenu))
-
-
-typedef struct SDL_GtkContext
-{
-	/* Glib 2.0 */
-	struct
-	{
-		gulong (*signal_connect)(gpointer instance, const gchar *detailed_signal, void *c_handler, gpointer data);
-		gulong (*signal_connect_data)(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, SDL_GConnectFlags connect_flags);
-		void (*object_unref)(gpointer object);
-		gchar *(*mkdtemp)(gchar *template);
-		gchar *(*get_user_cache_dir)(void);
-		gpointer (*object_ref_sink)(gpointer object);
-		gpointer (*object_ref)(gpointer object);
-		void (*object_get)(gpointer object, const gchar *first_property_name, ...);
-		void (*signal_handler_disconnect)(gpointer instance, gulong handler_id);
-		void (*main_context_push_thread_default)(GMainContext *context);
-		void (*main_context_pop_thread_default)(GMainContext *context);
-		GMainContext *(*main_context_new)(void);
-		void (*main_context_unref)(GMainContext *context);
-		gboolean (*main_context_acquire)(GMainContext *context);
-		gboolean (*main_context_iteration)(GMainContext *context, gboolean may_block);
-	} g;
-
-	/* GTK 3.0 */
-	struct
-	{
-		gboolean (*init_check)(int *argc, char ***argv);
-		GtkWidget *(*menu_new)(void);
-		GtkWidget *(*separator_menu_item_new)(void);
-		GtkWidget *(*menu_item_new_with_label)(const gchar *label);
-		void (*menu_item_set_submenu)(GtkMenuItem *menu_item, GtkWidget *submenu);
-		GtkWidget *(*check_menu_item_new_with_label)(const gchar *label);
-		void (*check_menu_item_set_active)(GtkCheckMenuItem *check_menu_item, gboolean is_active);
-		void (*widget_set_sensitive)(GtkWidget *widget, gboolean sensitive);
-		void (*widget_show)(GtkWidget *widget);
-		void (*menu_shell_append)(GtkMenuShell *menu_shell, GtkWidget *child);
-		void (*menu_shell_insert)(GtkMenuShell *menu_shell, GtkWidget *child, gint position);
-		void (*widget_destroy)(GtkWidget *widget);
-		const gchar *(*menu_item_get_label)(GtkMenuItem *menu_item);
-		void (*menu_item_set_label)(GtkMenuItem *menu_item, const gchar *label);
-		gboolean (*check_menu_item_get_active)(GtkCheckMenuItem *check_menu_item);
-		gboolean (*widget_get_sensitive)(GtkWidget *widget);
-		GtkSettings *(*settings_get_default)(void);
-	} gtk;
-} SDL_GtkContext;
-
-extern bool SDL_CanUseGtk(void);
-extern bool SDL_Gtk_Init(void);
-extern void SDL_Gtk_Quit(void);
-extern SDL_GtkContext *SDL_Gtk_EnterContext(void);
-extern void SDL_Gtk_ExitContext(SDL_GtkContext *ctx);
-extern void SDL_UpdateGtk(void);
-
-#endif // SDL_gtk_h_

+ 64 - 2
src/video/wayland/SDL_waylandvideo.c

@@ -25,7 +25,6 @@
 
 #include "../../core/linux/SDL_system_theme.h"
 #include "../../core/linux/SDL_progressbar.h"
-#include "../../core/unix/SDL_gtk.h"
 #include "../../events/SDL_events_c.h"
 
 #include "SDL_waylandclipboard.h"
@@ -1503,6 +1502,69 @@ static int SDLCALL LibdecorNewInThread(void *data)
 }
 #endif
 
+#ifndef HAVE_GETRESUID
+// Non-POSIX, but Linux and some BSDs have it.
+// To reduce the number of code paths, if getresuid() isn't available at
+// compile-time, we behave as though it existed but failed at runtime.
+static inline int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) {
+    errno = ENOSYS;
+    return -1;
+}
+#endif
+
+#ifndef HAVE_GETRESGID
+// Same as getresuid() but for the primary group
+static inline int getresgid(uid_t *ruid, uid_t *euid, uid_t *suid) {
+    errno = ENOSYS;
+    return -1;
+}
+#endif
+
+bool CanUseGtk(void)
+{
+    // "Real", "effective" and "saved" IDs: see e.g. Linux credentials(7)
+    uid_t ruid = -1, euid = -1, suid = -1;
+    gid_t rgid = -1, egid = -1, sgid = -1;
+
+    if (!SDL_GetHintBoolean("SDL_ENABLE_GTK", true)) {
+        SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Not using GTK due to hint");
+        return false;
+    }
+
+    // This is intended to match the check in gtkmain.c, rather than being
+    // an exhaustive check for having elevated privileges: as a result
+    // we don't use Linux getauxval() or prctl PR_GET_DUMPABLE,
+    // BSD issetugid(), or similar OS-specific detection
+
+    if (getresuid(&ruid, &euid, &suid) != 0) {
+        ruid = suid = getuid();
+        euid = geteuid();
+    }
+
+    if (getresgid(&rgid, &egid, &sgid) != 0) {
+        rgid = sgid = getgid();
+        egid = getegid();
+    }
+
+    // Real ID != effective ID means we are setuid or setgid:
+    // GTK will refuse to initialize, and instead will call exit().
+    if (ruid != euid || rgid != egid) {
+        SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Not using GTK due to setuid/setgid");
+        return false;
+    }
+
+    // Real ID != saved ID means we are setuid or setgid, we previously
+    // dropped privileges, but we can regain them; this protects against
+    // accidents but does not protect against arbitrary code execution.
+    // Again, GTK will refuse to initialize if this is the case.
+    if (ruid != suid || rgid != sgid) {
+        SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "Not using GTK due to saved uid/gid");
+        return false;
+    }
+
+    return true;
+}
+
 bool Wayland_LoadLibdecor(SDL_VideoData *data, bool ignore_xdg)
 {
 #ifdef HAVE_LIBDECOR_H
@@ -1510,7 +1572,7 @@ bool Wayland_LoadLibdecor(SDL_VideoData *data, bool ignore_xdg)
         return true; // Already loaded!
     }
     if (should_use_libdecor(data, ignore_xdg)) {
-        if (SDL_CanUseGtk()) {
+        if (CanUseGtk()) {
             LibdecorNew(data);
         } else {
             // Intentionally initialize libdecor in a non-main thread

+ 0 - 2
src/video/x11/SDL_x11modes.c

@@ -27,8 +27,6 @@
 #include "edid.h"
 #include "../../events/SDL_displayevents_c.h"
 
-#include "../../core/unix/SDL_gtk.h"
-
 // #define X11MODES_DEBUG
 
 /* Timeout and revert mode switches if the timespan has elapsed without the window becoming fullscreen.