aboutsummaryrefslogtreecommitdiff
path: root/src/libui_sdl/libui/unix/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libui_sdl/libui/unix/main.c')
-rw-r--r--src/libui_sdl/libui/unix/main.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/libui_sdl/libui/unix/main.c b/src/libui_sdl/libui/unix/main.c
new file mode 100644
index 0000000..2998bf3
--- /dev/null
+++ b/src/libui_sdl/libui/unix/main.c
@@ -0,0 +1,108 @@
+// 6 april 2015
+#include "uipriv_unix.h"
+
+uiInitOptions options;
+
+const char *uiInit(uiInitOptions *o)
+{
+ GError *err = NULL;
+ const char *msg;
+
+ options = *o;
+ if (gtk_init_with_args(NULL, NULL, NULL, NULL, NULL, &err) == FALSE) {
+ msg = g_strdup(err->message);
+ g_error_free(err);
+ return msg;
+ }
+ initAlloc();
+ loadFutures();
+ return NULL;
+}
+
+void uiUninit(void)
+{
+ uninitMenus();
+ uninitAlloc();
+}
+
+void uiFreeInitError(const char *err)
+{
+ g_free((gpointer) err);
+}
+
+static gboolean (*iteration)(gboolean) = NULL;
+
+void uiMain(void)
+{
+ iteration = gtk_main_iteration_do;
+ gtk_main();
+}
+
+static gboolean stepsQuit = FALSE;
+
+// the only difference is we ignore the return value from gtk_main_iteration_do(), since it will always be TRUE if gtk_main() was never called
+// gtk_main_iteration_do() will still run the main loop regardless
+static gboolean stepsIteration(gboolean block)
+{
+ gtk_main_iteration_do(block);
+ return stepsQuit;
+}
+
+void uiMainSteps(void)
+{
+ iteration = stepsIteration;
+}
+
+int uiMainStep(int wait)
+{
+ gboolean block;
+
+ block = FALSE;
+ if (wait)
+ block = TRUE;
+ return (*iteration)(block) == FALSE;
+}
+
+// gtk_main_quit() may run immediately, or it may wait for other pending events; "it depends" (thanks mclasen in irc.gimp.net/#gtk+)
+// PostQuitMessage() on Windows always waits, so we must do so too
+// we'll do it by using an idle callback
+static gboolean quit(gpointer data)
+{
+ if (iteration == stepsIteration)
+ stepsQuit = TRUE;
+ // TODO run a gtk_main() here just to do the cleanup steps of syncing the clipboard and other stuff gtk_main() does before it returns
+ else
+ gtk_main_quit();
+ return FALSE;
+}
+
+void uiQuit(void)
+{
+ gdk_threads_add_idle(quit, NULL);
+}
+
+struct queued {
+ void (*f)(void *);
+ void *data;
+};
+
+static gboolean doqueued(gpointer data)
+{
+ struct queued *q = (struct queued *) data;
+
+ (*(q->f))(q->data);
+ g_free(q);
+ return FALSE;
+}
+
+void uiQueueMain(void (*f)(void *data), void *data)
+{
+ struct queued *q;
+
+ // we have to use g_new0()/g_free() because uiAlloc() is only safe to call on the main thread
+ // for some reason it didn't affect me, but it did affect krakjoe
+ q = g_new0(struct queued, 1);
+ q->f = f;
+ q->data = data;
+ gdk_threads_add_idle(doqueued, q);
+}