2014-02-16 14:55:51 -06:00
// +build !windows,!darwin,!plan9
// 16 february 2014
2014-03-12 20:55:45 -05:00
2014-02-19 10:41:10 -06:00
package ui
2014-02-16 14:55:51 -06:00
import (
"fmt"
2014-07-01 11:09:31 -05:00
"unsafe"
2014-02-16 14:55:51 -06:00
)
2014-05-19 21:18:53 -05:00
// #cgo pkg-config: gtk+-3.0
// #include "gtk_unix.h"
2014-07-01 11:09:31 -05:00
// /* 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);
2014-05-19 21:18:53 -05:00
import "C"
2014-07-01 11:09:31 -05:00
//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 ) )
}
2014-02-16 14:55:51 -06:00
2014-06-30 21:48:12 -05:00
func uiinit ( ) error {
2014-04-27 11:43:15 -05:00
err := gtk_init ( )
if err != nil {
return fmt . Errorf ( "gtk_init() failed: %v" , err )
2014-02-16 14:55:51 -06:00
}
2014-06-30 21:48:12 -05:00
return nil
}
func ui ( ) {
2014-03-12 19:00:29 -05:00
// thanks to tristan and Daniel_S in irc.gimp.net/#gtk
// see our_idle_callback in callbacks_unix.go for details
go func ( ) {
2014-07-01 11:09:31 -05:00
// TODO do differently
<- Stop
// using gdk_threads_add_idle() will make sure it gets run when any events currently being handled finish running
f := func ( ) {
C . gtk_main_quit ( )
2014-02-16 16:09:58 -06:00
}
2014-07-01 11:09:31 -05:00
done := make ( chan struct { } )
gdk_threads_add_idle_op ( & gtkIdleOp {
what : f ,
done : done ,
} )
<- done
close ( done )
2014-03-12 19:00:29 -05:00
} ( )
2014-03-01 14:18:29 -06:00
2014-05-19 21:18:53 -05:00
C . gtk_main ( )
2014-02-16 14:55:51 -06:00
}