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-03 10:13:48 -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 18:42:55 -05:00
// /* this is called when we're done */
// static inline gboolean our_quit_callback(gpointer data)
// {
// gtk_main_quit();
2014-07-03 10:13:48 -05:00
// return FALSE; /* remove from idle handler queue (not like it matters) */
2014-07-01 18:42:55 -05:00
// }
// /* 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);
// }
2014-07-03 10:13:48 -05:00
// extern gboolean our_post_callback(gpointer);
2014-05-19 21:18:53 -05:00
import "C"
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
go func ( ) {
2014-07-01 11:09:31 -05:00
<- Stop
2014-07-01 18:42:55 -05:00
C . signalQuit ( )
// TODO wait for it to return?
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
}
2014-07-03 10:13:48 -05:00
// we DO need to worry about keeping data alive here
// so we do the posting in a new goroutine that waits instead
type uipostmsg struct {
w * Window
data interface { }
done chan struct { }
}
//export our_post_callback
func our_post_callback ( xmsg C . gpointer ) C . gboolean {
msg := ( * uipostmsg ) ( unsafe . Pointer ( xmsg ) )
msg . w . sysData . post ( msg . data )
msg . done <- struct { } { }
return C . FALSE // remove from idle handler queue
}
func uipost ( w * Window , data interface { } ) {
go func ( ) {
msg := & uipostmsg {
w : w ,
data : data ,
done : make ( chan struct { } ) ,
}
C . gdk_threads_add_idle ( C . GSourceFunc ( C . our_post_callback ) ,
C . gpointer ( unsafe . Pointer ( msg ) ) )
<- msg . done
close ( msg . done )
} ( )
}