diff options
Diffstat (limited to 'src/libui_sdl/libui/unix/main.c')
| -rw-r--r-- | src/libui_sdl/libui/unix/main.c | 108 | 
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); +} |