85 lines
2.3 KiB
Go
85 lines
2.3 KiB
Go
// +build !windows,!darwin,!plan9
|
|
|
|
// 16 february 2014
|
|
|
|
package ui
|
|
|
|
import (
|
|
"fmt"
|
|
"unsafe"
|
|
)
|
|
|
|
// #cgo pkg-config: gtk+-3.0
|
|
// #include "gtk_unix.h"
|
|
// /* unfortunately, there's no way to differentiate between the main thread and other threads; in fact, doing what we do on other platforms is discouraged by the GTK+ devs!
|
|
// but I can't avoid this any other way... so we have structures defined on the C side to skirt the garbage collector */
|
|
// struct uitaskParams {
|
|
// void *window; /* createWindow */
|
|
// void *control; /* createWindow */
|
|
// gboolean show; /* createWindow */
|
|
// };
|
|
// static struct uitaskParams *mkParams(void)
|
|
// {
|
|
// /* g_malloc0() will abort on not enough memory */
|
|
// return (struct uitaskParams *) g_malloc0(sizeof (struct uitaskParams));
|
|
// }
|
|
// static void freeParams(struct uitaskParams *p)
|
|
// {
|
|
// g_free(p);
|
|
// }
|
|
// extern gboolean our_createWindow_callback(gpointer);
|
|
// /* this is called when we're done */
|
|
// static inline gboolean our_quit_callback(gpointer data)
|
|
// {
|
|
// gtk_main_quit();
|
|
// return FALSE; /* remove from idle handler (not like it matters) */
|
|
// }
|
|
// /* I would call gdk_threads_add_idle() directly from ui() but cgo whines, so; trying to access our_quit_callback() in any way other than a call would cause _cgo_main.c to complain too */
|
|
// static inline void signalQuit(void)
|
|
// {
|
|
// gdk_threads_add_idle(our_quit_callback, NULL);
|
|
// }
|
|
import "C"
|
|
|
|
//export our_createWindow_callback
|
|
func our_createWindow_callback(what C.gpointer) C.gboolean {
|
|
uc := (*C.struct_uitaskParams)(unsafe.Pointer(what))
|
|
w := (*Window)(unsafe.Pointer(uc.window))
|
|
c := *(*Control)(unsafe.Pointer(uc.control))
|
|
s := fromgbool(uc.show)
|
|
w.create(c, s)
|
|
C.freeParams(uc)
|
|
return C.FALSE // remove this idle function; we're finished
|
|
}
|
|
|
|
func (_uitask) createWindow(w *Window, c Control, s bool) {
|
|
uc := C.mkParams()
|
|
uc.window = unsafe.Pointer(w)
|
|
uc.control = unsafe.Pointer(&c)
|
|
uc.show = togbool(s)
|
|
gdk_threads_add_idle(C.our_createWindow_callback, unsafe.Pointer(uc))
|
|
}
|
|
|
|
func gdk_threads_add_idle(f unsafe.Pointer, what unsafe.Pointer) {
|
|
C.gdk_threads_add_idle(C.GCallback(f), C.gpointer(what))
|
|
}
|
|
|
|
func uiinit() error {
|
|
err := gtk_init()
|
|
if err != nil {
|
|
return fmt.Errorf("gtk_init() failed: %v", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func ui() {
|
|
go func() {
|
|
<-Stop
|
|
C.signalQuit()
|
|
// TODO wait for it to return?
|
|
}()
|
|
|
|
C.gtk_main()
|
|
}
|