Skip to content

Commit 88cbe85

Browse files
committed
Added missing files
1 parent 26c41f3 commit 88cbe85

File tree

2 files changed

+352
-0
lines changed

2 files changed

+352
-0
lines changed

src/core/unix/SDL_gtk.c

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
/*
2+
Simple DirectMedia Layer
3+
Copyright (C) 1997-2025 Sam Lantinga <[email protected]>
4+
5+
This software is provided 'as-is', without any express or implied
6+
warranty. In no event will the authors be held liable for any damages
7+
arising from the use of this software.
8+
9+
Permission is granted to anyone to use this software for any purpose,
10+
including commercial applications, and to alter it and redistribute it
11+
freely, subject to the following restrictions:
12+
13+
1. The origin of this software must not be misrepresented; you must not
14+
claim that you wrote the original software. If you use this software
15+
in a product, an acknowledgment in the product documentation would be
16+
appreciated but is not required.
17+
2. Altered source versions must be plainly marked as such, and must not be
18+
misrepresented as being the original software.
19+
3. This notice may not be removed or altered from any source distribution.
20+
*/
21+
#include "SDL_internal.h"
22+
#include "SDL_gtk.h"
23+
24+
#define SDL_GTK_SYM2_OPTIONAL(ctx, lib, sub, fn, sym) \
25+
ctx.sub.fn = (void *)SDL_LoadFunction(lib, #sym)
26+
27+
#define SDL_GTK_SYM2(ctx, lib, sub, fn, sym) \
28+
if (!(ctx.sub.fn = (void *)SDL_LoadFunction(lib, #sym))) { \
29+
return SDL_SetError("Could not load GTK functions"); \
30+
}
31+
32+
#define SDL_GTK_SYM_OPTIONAL(ctx, lib, sub, fn) \
33+
SDL_GTK_SYM2_OPTIONAL(ctx, lib, sub, fn, sub##_##fn)
34+
35+
#define SDL_GTK_SYM(ctx, lib, sub, fn) \
36+
SDL_GTK_SYM2(ctx, lib, sub, fn, sub##_##fn)
37+
38+
// we never link directly to gtk
39+
static const char *gdk_names[] = {
40+
#ifdef SDL_PLATFORM_OPENBSD
41+
"libgdk-3.so",
42+
#else
43+
"libgdk-3.so.0",
44+
#endif
45+
NULL
46+
};
47+
48+
static const char *gtk_names[] = {
49+
#ifdef SDL_PLATFORM_OPENBSD
50+
"libgtk-3.so",
51+
#else
52+
"libgtk-3.so.0",
53+
#endif
54+
NULL
55+
};
56+
57+
static void *libgdk = NULL;
58+
static void *libgtk = NULL;
59+
60+
static SDL_GtkContext gtk;
61+
static GMainContext *sdl_main_context;
62+
63+
gulong signal_connect(gpointer instance, const gchar *detailed_signal, void *c_handler, gpointer data)
64+
{
65+
return gtk.g.signal_connect_data(instance, detailed_signal, SDL_G_CALLBACK(c_handler), data, NULL, (SDL_GConnectFlags)0);
66+
}
67+
68+
static void QuitGtk(void)
69+
{
70+
SDL_UnloadObject(libgdk);
71+
SDL_UnloadObject(libgtk);
72+
73+
libgdk = NULL;
74+
libgtk = NULL;
75+
}
76+
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+
89+
static bool IsGtkInit()
90+
{
91+
return libgdk != NULL && libgtk != NULL;
92+
}
93+
94+
static bool InitGtk(void)
95+
{
96+
if (!SDL_GetHintBoolean("SDL_ENABLE_GTK", true)) {
97+
return false;
98+
}
99+
100+
if (IsGtkInit()) {
101+
return true;
102+
}
103+
104+
libgdk = FindLib(gdk_names);
105+
libgtk = FindLib(gtk_names);
106+
107+
if (!libgdk || !libgtk) {
108+
QuitGtk();
109+
return SDL_SetError("Could not load GTK libraries");
110+
}
111+
112+
SDL_GTK_SYM(gtk, libgtk, gtk, init_check);
113+
SDL_GTK_SYM(gtk, libgtk, gtk, menu_new);
114+
SDL_GTK_SYM(gtk, libgtk, gtk, separator_menu_item_new);
115+
SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_new_with_label);
116+
SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_set_submenu);
117+
SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_get_label);
118+
SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_set_label);
119+
SDL_GTK_SYM(gtk, libgtk, gtk, menu_shell_append);
120+
SDL_GTK_SYM(gtk, libgtk, gtk, menu_shell_insert);
121+
SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_new_with_label);
122+
SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_get_active);
123+
SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_set_active);
124+
SDL_GTK_SYM(gtk, libgtk, gtk, widget_show);
125+
SDL_GTK_SYM(gtk, libgtk, gtk, widget_destroy);
126+
SDL_GTK_SYM(gtk, libgtk, gtk, widget_get_sensitive);
127+
SDL_GTK_SYM(gtk, libgtk, gtk, widget_set_sensitive);
128+
SDL_GTK_SYM(gtk, libgtk, gtk, settings_get_default);
129+
130+
SDL_GTK_SYM(gtk, libgdk, g, signal_connect_data);
131+
SDL_GTK_SYM(gtk, libgdk, g, mkdtemp);
132+
SDL_GTK_SYM(gtk, libgdk, g, object_ref);
133+
SDL_GTK_SYM(gtk, libgdk, g, object_ref_sink);
134+
SDL_GTK_SYM(gtk, libgdk, g, object_unref);
135+
SDL_GTK_SYM(gtk, libgdk, g, object_get);
136+
SDL_GTK_SYM(gtk, libgdk, g, signal_handler_disconnect);
137+
SDL_GTK_SYM(gtk, libgdk, g, main_context_push_thread_default);
138+
SDL_GTK_SYM(gtk, libgdk, g, main_context_pop_thread_default);
139+
SDL_GTK_SYM(gtk, libgdk, g, main_context_new);
140+
SDL_GTK_SYM(gtk, libgdk, g, main_context_acquire);
141+
SDL_GTK_SYM(gtk, libgdk, g, main_context_iteration);
142+
143+
gtk.g.signal_connect = signal_connect;
144+
145+
if (gtk.gtk.init_check(0, NULL) == GTK_FALSE) {
146+
QuitGtk();
147+
return SDL_SetError("Could not init GTK");
148+
}
149+
150+
sdl_main_context = gtk.g.main_context_new();
151+
if (!sdl_main_context) {
152+
QuitGtk();
153+
return SDL_SetError("Could not create GTK context");
154+
}
155+
156+
if (!gtk.g.main_context_acquire(sdl_main_context)) {
157+
QuitGtk();
158+
return SDL_SetError("Could not acquire GTK context");
159+
}
160+
161+
return true;
162+
}
163+
164+
static SDL_InitState gtk_init;
165+
166+
bool SDL_Gtk_Init(void)
167+
{
168+
static bool is_gtk_available = true;
169+
170+
if (!is_gtk_available) {
171+
return false; // don't keep trying if this fails.
172+
}
173+
174+
if (SDL_ShouldInit(&gtk_init)) {
175+
if (InitGtk()) {
176+
SDL_SetInitialized(&gtk_init, true);
177+
} else {
178+
is_gtk_available = false;
179+
SDL_SetInitialized(&gtk_init, true);
180+
SDL_Gtk_Quit();
181+
}
182+
}
183+
184+
return IsGtkInit();
185+
}
186+
187+
void SDL_Gtk_Quit(void)
188+
{
189+
if (!SDL_ShouldQuit(&gtk_init)) {
190+
return;
191+
}
192+
193+
QuitGtk();
194+
SDL_zero(gtk);
195+
sdl_main_context = NULL;
196+
197+
SDL_SetInitialized(&gtk_init, false);
198+
}
199+
200+
SDL_GtkContext *SDL_Gtk_GetContext(void)
201+
{
202+
return IsGtkInit() ? &gtk : NULL;
203+
}
204+
205+
SDL_GtkContext *SDL_Gtk_EnterContext(void)
206+
{
207+
SDL_Gtk_Init();
208+
209+
if (IsGtkInit()) {
210+
gtk.g.main_context_push_thread_default(sdl_main_context);
211+
return &gtk;
212+
}
213+
214+
return NULL;
215+
}
216+
217+
void SDL_Gtk_ExitContext(SDL_GtkContext *ctx)
218+
{
219+
if (ctx) {
220+
ctx->g.main_context_pop_thread_default(sdl_main_context);
221+
}
222+
}
223+
224+
void SDL_UpdateGtk(void)
225+
{
226+
if (IsGtkInit()) {
227+
gtk.g.main_context_iteration(sdl_main_context, GTK_FALSE);
228+
}
229+
}

src/core/unix/SDL_gtk.h

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
Simple DirectMedia Layer
3+
Copyright (C) 1997-2025 Sam Lantinga <[email protected]>
4+
5+
This software is provided 'as-is', without any express or implied
6+
warranty. In no event will the authors be held liable for any damages
7+
arising from the use of this software.
8+
9+
Permission is granted to anyone to use this software for any purpose,
10+
including commercial applications, and to alter it and redistribute it
11+
freely, subject to the following restrictions:
12+
13+
1. The origin of this software must not be misrepresented; you must not
14+
claim that you wrote the original software. If you use this software
15+
in a product, an acknowledgment in the product documentation would be
16+
appreciated but is not required.
17+
2. Altered source versions must be plainly marked as such, and must not be
18+
misrepresented as being the original software.
19+
3. This notice may not be removed or altered from any source distribution.
20+
*/
21+
22+
#include "SDL_internal.h"
23+
24+
#ifndef SDL_gtk_h_
25+
#define SDL_gtk_h_
26+
27+
/* Glib 2.0 */
28+
29+
typedef unsigned long gulong;
30+
typedef void *gpointer;
31+
typedef char gchar;
32+
typedef int gint;
33+
typedef unsigned int guint;
34+
typedef double gdouble;
35+
typedef gint gboolean;
36+
typedef void (*GCallback)(void);
37+
typedef struct _GClosure GClosure;
38+
typedef void (*GClosureNotify) (gpointer data, GClosure *closure);
39+
typedef gboolean (*GSourceFunc) (gpointer user_data);
40+
41+
typedef struct _GParamSpec GParamSpec;
42+
typedef struct _GMainContext GMainContext;
43+
44+
typedef enum SDL_GConnectFlags
45+
{
46+
SDL_G_CONNECT_DEFAULT = 0,
47+
SDL_G_CONNECT_AFTER = 1 << 0,
48+
SDL_G_CONNECT_SWAPPED = 1 << 1
49+
} SDL_GConnectFlags;
50+
51+
#define SDL_G_CALLBACK(f) ((GCallback) (f))
52+
#define SDL_G_TYPE_CIC(ip, gt, ct) ((ct*) ip)
53+
#define SDL_G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (SDL_G_TYPE_CIC ((instance), (g_type), c_type))
54+
55+
#define GTK_FALSE 0
56+
#define GTK_TRUE 1
57+
58+
59+
/* GTK 3.0 */
60+
61+
typedef struct _GtkMenu GtkMenu;
62+
typedef struct _GtkMenuItem GtkMenuItem;
63+
typedef struct _GtkMenuShell GtkMenuShell;
64+
typedef struct _GtkWidget GtkWidget;
65+
typedef struct _GtkCheckMenuItem GtkCheckMenuItem;
66+
typedef struct _GtkSettings GtkSettings;
67+
68+
#define GTK_MENU_ITEM(obj) (SDL_G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_ITEM, GtkMenuItem))
69+
#define GTK_WIDGET(widget) (SDL_G_TYPE_CHECK_INSTANCE_CAST ((widget), GTK_TYPE_WIDGET, GtkWidget))
70+
#define GTK_CHECK_MENU_ITEM(obj) (SDL_G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CHECK_MENU_ITEM, GtkCheckMenuItem))
71+
#define GTK_MENU(obj) (SDL_G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU, GtkMenu))
72+
73+
74+
typedef struct SDL_GtkContext
75+
{
76+
/* Glib 2.0 */
77+
struct
78+
{
79+
gulong (*signal_connect)(gpointer instance, const gchar *detailed_signal, void *c_handler, gpointer data);
80+
gulong (*signal_connect_data)(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, SDL_GConnectFlags connect_flags);
81+
void (*object_unref)(gpointer object);
82+
gchar *(*mkdtemp)(gchar *template);
83+
gpointer (*object_ref_sink)(gpointer object);
84+
gpointer (*object_ref)(gpointer object);
85+
void (*object_get)(gpointer object, const gchar *first_property_name, ...);
86+
void (*signal_handler_disconnect)(gpointer instance, gulong handler_id);
87+
void (*main_context_push_thread_default)(GMainContext *context);
88+
void (*main_context_pop_thread_default)(GMainContext *context);
89+
GMainContext *(*main_context_new)(void);
90+
gboolean (*main_context_acquire)(GMainContext *context);
91+
gboolean (*main_context_iteration)(GMainContext *context, gboolean may_block);
92+
} g;
93+
94+
/* GTK 3.0 */
95+
struct
96+
{
97+
gboolean (*init_check)(int *argc, char ***argv);
98+
GtkWidget *(*menu_new)(void);
99+
GtkWidget *(*separator_menu_item_new)(void);
100+
GtkWidget *(*menu_item_new_with_label)(const gchar *label);
101+
void (*menu_item_set_submenu)(GtkMenuItem *menu_item, GtkWidget *submenu);
102+
GtkWidget *(*check_menu_item_new_with_label)(const gchar *label);
103+
void (*check_menu_item_set_active)(GtkCheckMenuItem *check_menu_item, gboolean is_active);
104+
void (*widget_set_sensitive)(GtkWidget *widget, gboolean sensitive);
105+
void (*widget_show)(GtkWidget *widget);
106+
void (*menu_shell_append)(GtkMenuShell *menu_shell, GtkWidget *child);
107+
void (*menu_shell_insert)(GtkMenuShell *menu_shell, GtkWidget *child, gint position);
108+
void (*widget_destroy)(GtkWidget *widget);
109+
const gchar *(*menu_item_get_label)(GtkMenuItem *menu_item);
110+
void (*menu_item_set_label)(GtkMenuItem *menu_item, const gchar *label);
111+
gboolean (*check_menu_item_get_active)(GtkCheckMenuItem *check_menu_item);
112+
gboolean (*widget_get_sensitive)(GtkWidget *widget);
113+
GtkSettings *(*settings_get_default)(void);
114+
} gtk;
115+
} SDL_GtkContext;
116+
117+
extern bool SDL_Gtk_Init(void);
118+
extern void SDL_Gtk_Quit(void);
119+
extern SDL_GtkContext *SDL_Gtk_EnterContext(void);
120+
extern void SDL_Gtk_ExitContext(SDL_GtkContext *gtk);
121+
extern void SDL_UpdateGtk(void);
122+
123+
#endif // SDL_gtk_h_

0 commit comments

Comments
 (0)