1
0
Fork 0
mirror of https://github.com/vbatts/freezing-octo-hipster.git synced 2024-11-24 07:55:39 +00:00
random-utils/vendor/github.com/mattn/go-gtk/glib/glib.go
Vincent Batts 4ab3be9bc6
go*: one go module for the repo, no more nested
Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
2024-04-26 19:34:55 +00:00

1052 lines
28 KiB
Go

// +build !cgocheck
package glib
// #include "glib.go.h"
// #cgo pkg-config: glib-2.0 gobject-2.0
import "C"
import (
"reflect"
"sync"
"unsafe"
)
type ContextStorage struct {
lastId int
m sync.Mutex
values map[int]interface{}
}
func NewContextStorage() *ContextStorage {
return &ContextStorage{values: make(map[int]interface{})}
}
func (c *ContextStorage) Add(value interface{}) int {
c.m.Lock()
newId := c.lastId
c.values[newId] = value
c.lastId++
c.m.Unlock()
return newId
}
func (c *ContextStorage) Get(id int) (value interface{}, found bool) {
c.m.Lock()
value, found = c.values[id]
c.m.Unlock()
return
}
func (c *ContextStorage) Remove(id int) {
c.m.Lock()
delete(c.values, id)
c.m.Unlock()
}
func (c *ContextStorage) Len() int {
c.m.Lock()
result := len(c.values)
c.m.Unlock()
return result
}
var (
sourcefunc_contexts = NewContextStorage()
callback_contexts = NewContextStorage()
)
func gbool(b bool) C.gboolean {
if b {
return C.gboolean(1)
}
return C.gboolean(0)
}
func gobool(b C.gboolean) bool {
if b != 0 {
return true
}
return false
}
// converts a C string array to a Go string slice
func toSlice(ar **C.gchar) []string {
result := make([]string, 0)
for i := 0; ; i++ {
str := C.GoString(C.to_charptr(*ar))
if str == "" {
break
}
result = append(result, str)
*ar = C.next_string(*ar)
}
return result
}
func GPtrToString(p interface{}) string {
pp := (C.gpointer)(p.(unsafe.Pointer))
return C.GoString(C.to_charptr_from_gpointer(pp))
}
//-----------------------------------------------------------------------
// Application
//-----------------------------------------------------------------------
func GetApplicationName() string {
return C.GoString(C.to_charptr(C.g_get_application_name()))
}
func SetApplicationName(name string) {
str := C.CString(name)
defer C.free_string(str)
C.g_set_application_name(C.to_gcharptr(str))
}
func GetPrgName() string {
return C.GoString(C.to_charptr(C.g_get_prgname()))
}
func SetPrgname(name string) {
str := C.CString(name)
defer C.free_string(str)
C.g_set_prgname(C.to_gcharptr(str))
}
//-----------------------------------------------------------------------
// User Information
//-----------------------------------------------------------------------
func GetUserName() string {
return C.GoString(C.to_charptr(C.g_get_user_name()))
}
func GetRealName() string {
return C.GoString(C.to_charptr(C.g_get_real_name()))
}
func GetUserCacheDir() string {
return C.GoString(C.to_charptr(C.g_get_user_cache_dir()))
}
func GetUserDataDir() string {
return C.GoString(C.to_charptr(C.g_get_user_data_dir()))
}
func GetUserConfigDir() string {
return C.GoString(C.to_charptr(C.g_get_user_config_dir()))
}
func GetUserRuntimeDir() string {
return C.GoString(C.to_charptr(C.g_get_user_runtime_dir()))
}
type ConnectFlags C.GConnectFlags
const (
ConnectAfter ConnectFlags = C.G_CONNECT_AFTER
ConnectSwapped ConnectFlags = C.G_CONNECT_SWAPPED
)
type UserDirectory C.GUserDirectory
const (
UserDirectoryDesktop UserDirectory = C.G_USER_DIRECTORY_DESKTOP
UserDirectoryDocuments UserDirectory = C.G_USER_DIRECTORY_DOCUMENTS
UserDirectoryDownload UserDirectory = C.G_USER_DIRECTORY_DOWNLOAD
UserDirectoryMusic UserDirectory = C.G_USER_DIRECTORY_MUSIC
UserDirectoryPictures UserDirectory = C.G_USER_DIRECTORY_PICTURES
UserDirectoryPublicShare UserDirectory = C.G_USER_DIRECTORY_PUBLIC_SHARE
UserDirectoryTemplates UserDirectory = C.G_USER_DIRECTORY_TEMPLATES
UserDirectoryVideos UserDirectory = C.G_USER_DIRECTORY_VIDEOS
)
func GetUserSpecialDir(directory UserDirectory) string {
result := C.g_get_user_special_dir(C.GUserDirectory(directory))
return C.GoString(C.to_charptr(result))
}
func ReloadUserSpecialDirsCache() {
C.g_reload_user_special_dirs_cache()
}
//-----------------------------------------------------------------------
// System Information
//-----------------------------------------------------------------------
func GetSystemDataDirs() []string {
return toSlice(C.g_get_system_data_dirs())
}
func GetSystemConfigDirs() []string {
return toSlice(C.g_get_system_config_dirs())
}
func GetHostName() string {
return C.GoString(C.to_charptr(C.g_get_host_name()))
}
func GetHomeDir() string {
return C.GoString(C.to_charptr(C.g_get_home_dir()))
}
func GetTmpDir() string {
return C.GoString(C.to_charptr(C.g_get_tmp_dir()))
}
func GetCurrentDir() string {
return C.GoString(C.to_charptr(C.g_get_current_dir()))
}
//-----------------------------------------------------------------------
// String Convert
//-----------------------------------------------------------------------
func Utf8Validate(str []byte, len int, bar **byte) bool {
return gobool(C._g_utf8_validate(unsafe.Pointer(&str[0]),
C.int(len), unsafe.Pointer(bar)))
}
func FilenameFromUri(uri string) (filename string, hostname string, err error) {
str := C.CString(uri)
defer C.free_string(str)
var gerror *C.GError
var ptr *C.gchar
filename = C.GoString(C.to_charptr(C.g_filename_from_uri(C.to_gcharptr(str), &ptr, &gerror)))
if unsafe.Pointer(gerror) != nil {
err = ErrorFromNative(unsafe.Pointer(gerror))
} else {
err = nil
}
hostname = ""
if ptr != nil {
hostname = C.GoString(C.to_charptr(ptr))
}
return
}
func FilenameToUri(filename string, hostname string) (uri string, err error) {
pfilename := C.CString(filename)
defer C.free_string(pfilename)
phostname := C.CString(hostname)
defer C.free_string(phostname)
var gerror *C.GError
uri = C.GoString(C.to_charptr(C.g_filename_to_uri(C.to_gcharptr(pfilename), C.to_gcharptr(phostname), &gerror)))
if unsafe.Pointer(gerror) != nil {
err = ErrorFromNative(unsafe.Pointer(gerror))
} else {
err = nil
}
return
}
func LocaleToUtf8(opsysstring []byte) (ret string, bytes_read int, bytes_written int, err *Error) {
var gerror *C.GError
var cbytes_read, cbytes_written C.int
str := C._g_locale_to_utf8(unsafe.Pointer(&opsysstring[0]), C.int(len(opsysstring)), &cbytes_read, &cbytes_written, &gerror)
if unsafe.Pointer(str) != nil {
defer C.free_string(C.to_charptr(str))
ret = C.GoString(C.to_charptr(str))
} else {
ret = ""
}
bytes_read = int(cbytes_read)
bytes_written = int(cbytes_written)
if unsafe.Pointer(gerror) != nil {
err = ErrorFromNative(unsafe.Pointer(gerror))
} else {
err = nil
}
return
}
func LocaleFromUtf8(utf8string string) (ret []byte, bytes_read int, bytes_written int, err *Error) {
var gerror *C.GError
var cbytes_read, cbytes_written C.int
src := C.CString(utf8string)
defer C.free_string(src)
str := C._g_locale_from_utf8(src, C.int(C.strlen(src)), &cbytes_read, &cbytes_written, &gerror)
if unsafe.Pointer(str) != nil {
defer C.free_string(C.to_charptr(str))
ret = ([]byte)(C.GoString(C.to_charptr(str)))
} else {
ret = ([]byte)("")
}
bytes_read = int(cbytes_read)
bytes_written = int(cbytes_written)
if unsafe.Pointer(gerror) != nil {
err = ErrorFromNative(unsafe.Pointer(gerror))
} else {
err = nil
}
return
}
//-----------------------------------------------------------------------
// List
//-----------------------------------------------------------------------
type List struct {
GList *C.GList
}
func ListFromNative(l unsafe.Pointer) *List {
return &List{
C.to_list(l)}
}
func (v List) Data() interface{} {
return v.GList.data
}
func (v List) Append(data unsafe.Pointer) *List {
return &List{C.g_list_append(v.GList, C.gpointer(data))}
}
func (v List) Prepend(data unsafe.Pointer) *List {
return &List{C.g_list_prepend(v.GList, C.gpointer(data))}
}
func (v List) Insert(data unsafe.Pointer, pos int) *List {
return &List{C.g_list_insert(v.GList, C.gpointer(data), C.gint(pos))}
}
func (v List) InsertBefore(sib List, data unsafe.Pointer) *List {
return &List{C.g_list_insert_before(v.GList, sib.GList, C.gpointer(data))}
}
//GList* g_list_insert_sorted (GList *list,
// gpointer data,
// GCompareFunc func);
func (v List) Remove(data unsafe.Pointer) *List {
return &List{C.g_list_remove(v.GList, C.gconstpointer(data))}
}
func (v List) RemoveLink(link List) *List {
return &List{C.g_list_remove_link(v.GList, link.GList)}
}
func (v List) DeleteLink(link List) *List {
return &List{C.g_list_delete_link(v.GList, link.GList)}
}
func (v List) RemoveAll(data unsafe.Pointer) *List {
return &List{C.g_list_remove_all(v.GList, C.gconstpointer(data))}
}
func (v List) Free() {
C.g_list_free(v.GList)
}
func GListAlloc() *List {
return &List{C.g_list_alloc()}
}
func (v List) Free1() {
C.g_list_free_1(v.GList)
}
func (v List) Length() uint {
return uint(C.g_list_length(v.GList))
}
func (v List) Copy() *List {
return &List{C.g_list_copy(v.GList)}
}
func (v List) Reverse() *List {
return &List{C.g_list_reverse(v.GList)}
}
//GList* g_list_sort (GList *list,
// GCompareFunc compare_func);
//gint (*GCompareFunc) (gconstpointer a,
// gconstpointer b);
//GList* g_list_insert_sorted_with_data (GList *list,
// gpointer data,
// GCompareDataFunc func,
// gpointer user_data);
//GList* g_list_sort_with_data (GList *list,
// GCompareDataFunc compare_func,
// gpointer user_data);
//gint (*GCompareDataFunc) (gconstpointer a,
// gconstpointer b,
// gpointer user_data);
func (v List) Concat(link List) *List {
return &List{C.g_list_concat(v.GList, link.GList)}
}
func (v List) ForEach(callback func(unsafe.Pointer, interface{}), user_datas ...interface{}) {
var user_data interface{}
if len(user_datas) > 0 {
user_data = user_datas[0]
}
l := v.First()
for n := uint(0); n < l.Length(); n++ {
callback(l.NthData(n), user_data)
}
}
func (v List) First() *List {
return &List{C.g_list_first(v.GList)}
}
func (v List) Last() *List {
return &List{C.g_list_last(v.GList)}
}
func (v List) Nth(n uint) *List {
return &List{C.g_list_nth(v.GList, C.guint(n))}
}
func (v List) NthData(n uint) unsafe.Pointer {
return unsafe.Pointer(C.g_list_nth_data(v.GList, C.guint(n)))
}
func (v List) NthPrev(n uint) *List {
return &List{C.g_list_nth_prev(v.GList, C.guint(n))}
}
func (v List) Find(data unsafe.Pointer) *List {
return &List{C.g_list_find(v.GList, C.gconstpointer(data))}
}
//GList* g_list_find_custom (GList *list,
// gconstpointer data,
// GCompareFunc func);
func (v List) Position(link List) int {
return int(C.g_list_position(v.GList, link.GList))
}
func (v List) Index(data unsafe.Pointer) int {
return int(C.g_list_index(v.GList, C.gconstpointer(data)))
}
//-----------------------------------------------------------------------
// g_slist
//-----------------------------------------------------------------------
type SList struct {
GSList *C.GSList
}
func SListFromNative(sl unsafe.Pointer) *SList {
return &SList{
C.to_slist(sl)}
}
func (v SList) ToSList() *C.GSList {
return v.GSList
}
func (v SList) Data() unsafe.Pointer {
return unsafe.Pointer(v.GSList.data)
}
func GSListAlloc() *SList {
return &SList{C.g_slist_alloc()}
}
func (v SList) Free() {
C.g_slist_free(v.GSList)
}
func (v SList) Free1() {
C.g_slist_free1(v.GSList)
}
func (v SList) Append(data unsafe.Pointer) *SList {
return &SList{C.g_slist_append(v.GSList, C.gpointer(data))}
}
func (v SList) Prepend(data unsafe.Pointer) *SList {
return &SList{C.g_slist_prepend(v.GSList, C.gpointer(data))}
}
// GSList* g_slist_insert (GSList *list, gpointer data, gint position) G_GNUC_WARN_UNUSED_RESULT;
// GSList* g_slist_insert_sorted (GSList *list, gpointer data, GCompareFunc func) G_GNUC_WARN_UNUSED_RESULT;
// GSList* g_slist_insert_sorted_with_data (GSList *list, gpointer data, GCompareDataFunc func, gpointer user_data) G_GNUC_WARN_UNUSED_RESULT;
func (v SList) InsertBefore(sibling SList, data unsafe.Pointer) *SList {
return &SList{C.g_slist_insert_before(v.GSList, sibling.GSList, C.gpointer(data))}
}
func (v SList) Concat(llink SList) *SList {
return &SList{C.g_slist_concat(v.GSList, llink.GSList)}
}
func (v SList) Remove(data unsafe.Pointer) *SList {
return &SList{C.g_slist_remove(v.GSList, C.gconstpointer(data))}
}
func (v SList) RemoveAll(data unsafe.Pointer) *SList {
return &SList{C.g_slist_remove_all(v.GSList, C.gconstpointer(data))}
}
func (v SList) RemoveLink(llink SList) *SList {
return &SList{C.g_slist_delete_link(v.GSList, llink.GSList)}
}
func (v SList) DeleteLink(llink SList) *SList {
return &SList{C.g_slist_delete_link(v.GSList, llink.GSList)}
}
func (v SList) Reverse() *SList {
return &SList{C.g_slist_reverse(v.GSList)}
}
func (v SList) Copy() *SList {
return &SList{C.g_slist_copy(v.GSList)}
}
func (v SList) Nth(n uint) *SList {
return &SList{C.g_slist_nth(v.GSList, C.guint(n))}
}
func (v SList) Find(data unsafe.Pointer) *SList {
return &SList{C.g_slist_find(v.GSList, C.gconstpointer(data))}
}
// GSList* g_slist_find_custom (GSList *list, gconstpointer data, GCompareFunc func);
func (v SList) Position(llink SList) int {
return int(C.g_slist_position(v.GSList, llink.GSList))
}
func (v SList) Index(data unsafe.Pointer) int {
return int(C.g_slist_index(v.GSList, C.gconstpointer(data)))
}
func (v SList) Last() *SList {
return &SList{C.g_slist_last(v.GSList)}
}
func (v SList) Length() uint {
return uint(C.g_slist_length(v.GSList))
}
func (v SList) ForEach(callback func(unsafe.Pointer, interface{}), user_datas ...interface{}) {
var user_data interface{}
if len(user_datas) > 0 {
user_data = user_datas[0]
}
for n := uint(0); n < v.Length(); n++ {
callback(v.Nth(n).Data(), user_data)
}
}
// GSList* g_slist_sort (GSList *list, GCompareFunc compare_func) G_GNUC_WARN_UNUSED_RESULT;
// GSList* g_slist_sort_with_data (GSList *list, GCompareDataFunc compare_func, gpointer user_data) G_GNUC_WARN_UNUSED_RESULT;
func (v SList) NthData(n uint) unsafe.Pointer {
return unsafe.Pointer(C.g_slist_nth_data(v.GSList, C.guint(n)))
}
//-----------------------------------------------------------------------
// g_error
//-----------------------------------------------------------------------
type Error struct {
GError *C.GError
}
func (v *Error) Error() string {
return v.Message()
}
func (v *Error) Message() string {
if unsafe.Pointer(v.GError) == nil || unsafe.Pointer(v.GError.message) == nil {
return ""
}
return C.GoString(C.to_charptr(v.GError.message))
}
func ErrorFromNative(err unsafe.Pointer) *Error {
return &Error{
C.to_error(err)}
}
//-----------------------------------------------------------------------
// GObject
//-----------------------------------------------------------------------
type ObjectLike interface {
Ref()
Unref()
Connect(s string, f interface{}, data ...interface{})
}
type GObject struct {
Object unsafe.Pointer
}
func ObjectFromNative(object unsafe.Pointer) *GObject {
// return &GObject {
// C.to_GObject(object) }
return &GObject{
object}
}
func (v *GObject) Ref() {
C.g_object_ref(C.gpointer(v.Object))
}
func (v *GObject) Unref() {
C.g_object_unref(C.gpointer(v.Object))
}
func (v *GObject) SetData(s string, p unsafe.Pointer) {
ptr := C.CString(s)
defer C.free_string(ptr)
C.g_object_set_data((*C.GObject)(v.Object), C.to_gcharptr(ptr), (C.gpointer)(p))
}
func (v *GObject) GetData(s string) unsafe.Pointer {
ptr := C.CString(s)
defer C.free_string(ptr)
p := C.g_object_get_data((*C.GObject)(v.Object), C.to_gcharptr(ptr))
return unsafe.Pointer(p)
}
func (v *GObject) Set(name string, value interface{}) {
ptr := C.CString(name)
defer C.free_string(ptr)
if _, ok := value.(WrappedObject); ok {
value = value.(WrappedObject).GetInternalValue()
}
if _, ok := value.(GObject); ok {
value = value.(GObject).Object
}
if _, ok := value.(GValue); ok {
value = value.(GValue).Value
}
switch value.(type) {
case bool:
bval := gbool(value.(bool))
C._g_object_set_addr(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(&bval))
case byte:
bval := C.gchar(value.(byte))
C._g_object_set_addr(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(&bval))
//C._g_object_set(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(reflect.ValueOf(C.gchar(value.(byte))).UnsafeAddr()))
case int:
ival := C.int(value.(int))
C._g_object_set_addr(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(&ival))
case uint:
uval := C.guint(value.(uint))
C._g_object_set_addr(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(&uval))
//C._g_object_set(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(reflect.ValueOf(C.guint(value.(uint))).UnsafeAddr()))
case float32:
f32val := C.gfloat(value.(float32))
C._g_object_set_addr(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(&f32val))
//C._g_object_set(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(reflect.ValueOf(C.gfloat(value.(float64))).UnsafeAddr()))
case float64:
f64val := C.gfloat(value.(float64))
C._g_object_set_addr(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(&f64val))
//C._g_object_set(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(reflect.ValueOf(C.gfloat(value.(float64))).UnsafeAddr()))
case string:
pval := C.CString(value.(string))
defer C.free_string(pval)
C._g_object_set_addr(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(&pval))
default:
if pv, ok := value.(*[0]uint8); ok {
C._g_object_set_ptr(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(pv))
} else {
av := reflect.ValueOf(value)
if av.Kind() == reflect.Ptr {
C._g_object_set_ptr(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(av.Pointer()))
} else if av.CanAddr() {
C._g_object_set_addr(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(av.UnsafeAddr()))
} else {
C._g_object_set_addr(C.gpointer(v.Object), C.to_gcharptr(ptr), unsafe.Pointer(&value))
}
}
}
}
func (v *GObject) SetProperty(name string, val *GValue) {
str := C.CString(name)
defer C.free_string(str)
C.g_object_set_property(C.to_GObject(v.Object), C.to_gcharptr(str), &val.Value)
}
//-----------------------------------------------------------------------
// GValue
//-----------------------------------------------------------------------
func GValueFromNative(value interface{}) *C.GValue {
var gv *C.GValue
if _, ok := value.(WrappedObject); ok {
value = value.(WrappedObject).GetInternalValue()
}
if _, ok := value.(GObject); ok {
value = value.(GObject).Object
}
if _, ok := value.(GValue); ok {
value = value.(GValue).Value
}
switch value.(type) {
case bool:
gv = C.init_gvalue_bool(gbool(value.(bool)))
break
case byte:
gv = C.init_gvalue_byte(C.guchar(value.(byte)))
break
case int:
gv = C.init_gvalue_int(C.gint(value.(int)))
break
case uint:
gv = C.init_gvalue_uint(C.guint(value.(uint)))
break
case int64:
gv = C.init_gvalue_int64(C.gint64(value.(int64)))
break
case float32:
gv = C.init_gvalue_double(C.gdouble(value.(float32)))
break
case float64:
gv = C.init_gvalue_double(C.gdouble(value.(float64)))
break
case string:
{
pval := C.CString(value.(string))
defer C.free_string(pval)
gv = C.init_gvalue_string(C.to_gcharptr(pval))
}
break
default:
//gv = C.init_gvalue_pointer(C.gpointer(unsafe.Pointer(&value)));
break
}
return gv
}
func ValueFromNative(val interface{}) *GValue {
return &GValue{*GValueFromNative(val)}
}
type GValue struct {
Value C.GValue
}
const (
G_TYPE_CHAR = 3 << 2
G_TYPE_UCHAR = 4 << 2
G_TYPE_BOOL = 5 << 2
G_TYPE_INT = 6 << 2
G_TYPE_UINT = 7 << 2
G_TYPE_LONG = 8 << 2
G_TYPE_ULONG = 9 << 2
G_TYPE_INT64 = 10 << 2
G_TYPE_UINT64 = 11 << 2
G_TYPE_ENUM = 12 << 2
G_TYPE_FLAGS = 13 << 2
G_TYPE_FLOAT = 14 << 2
G_TYPE_DOUBLE = 15 << 2
G_TYPE_STRING = 16 << 2
G_TYPE_POINTER = 17 << 2
G_TYPE_BOXED = 18 << 2
)
func (v *GValue) Init(t int) {
if t == G_TYPE_INT {
C.g_value_init_int(&v.Value)
} else if t == G_TYPE_STRING {
C.g_value_init_string(&v.Value)
}
}
func (v *GValue) GetString() string {
return C.GoString(C.to_charptr(C.g_value_get_string(&v.Value)))
}
func (v *GValue) GetInt() int {
return int(C.g_value_get_int(&v.Value))
}
func (v *GValue) GetBool() bool {
return gobool(C.g_value_get_boolean(&v.Value))
}
//-----------------------------------------------------------------------
// WrappedObject
//-----------------------------------------------------------------------
type WrappedObject interface {
GetInternalValue() unsafe.Pointer
}
//-----------------------------------------------------------------------
// Events
//-----------------------------------------------------------------------
// the go-gtk Callback is simpler than the one in C, because we have
// full closures, so there is never a need to pass additional data via
// a void * pointer. Where you might have wanted to do that, you can
// instead just use func () { ... using data } to pass the data in.
type CallbackContext struct {
f reflect.Value
cbi unsafe.Pointer
target reflect.Value
data reflect.Value
}
func (c *CallbackContext) Target() interface{} {
return c.target.Interface()
}
func (c *CallbackContext) Data() interface{} {
if !c.data.IsValid() {
return nil
}
return c.data.Interface()
}
func (c *CallbackContext) Args(n int) CallbackArg {
return CallbackArg(C.callback_info_get_arg((*C.callback_info)(c.cbi), C.int(n)))
}
type CallbackArg uintptr
func (c CallbackArg) ToString() string {
return C.GoString(C.to_charptr_voidp(unsafe.Pointer(uintptr(c))))
}
//export _go_glib_callback
func _go_glib_callback(cbi *C.callback_info) {
value, found := callback_contexts.Get(int(cbi.func_no))
if !found {
return
}
context := value.(*CallbackContext)
t := context.f.Type()
fargs := make([]reflect.Value, t.NumIn())
if len(fargs) > 0 {
fargs[0] = reflect.ValueOf(context)
}
ret := context.f.Call(fargs)
if len(ret) > 0 {
value := ret[0].Interface()
switch value.(type) {
case bool:
bval := gbool(value.(bool))
cbi.ret = unsafe.Pointer(&bval)
case byte:
bval := C.gchar(value.(byte))
cbi.ret = unsafe.Pointer(&bval)
case int:
ival := C.int(value.(int))
cbi.ret = unsafe.Pointer(&ival)
case uint:
uval := C.guint(value.(uint))
cbi.ret = unsafe.Pointer(&uval)
case float32:
f32val := C.gfloat(value.(float32))
cbi.ret = unsafe.Pointer(&f32val)
case float64:
f64val := C.gfloat(value.(float64))
cbi.ret = unsafe.Pointer(&f64val)
case string:
cbi.ret = unsafe.Pointer(C.CString(value.(string)))
default:
if pv, ok := value.(*[0]uint8); ok {
cbi.ret = unsafe.Pointer(pv)
} else {
av := reflect.ValueOf(value)
if av.Kind() == reflect.Ptr {
cbi.ret = unsafe.Pointer(av.Pointer())
} else if av.CanAddr() {
cbi.ret = unsafe.Pointer(av.UnsafeAddr())
} else {
cbi.ret = unsafe.Pointer(&value)
}
}
}
}
}
// Return the handler call_id to use with HandlerBlock, HandlerUnblock and
// HandlerDisconnect.
//
func (v *GObject) Connect(s string, f interface{}, datas ...interface{}) int {
var data interface{}
if len(datas) > 0 {
data = datas[0]
}
return v.SignalConnect(s, f, data, ConnectSwapped)
}
func (v *GObject) SignalConnect(s string, f interface{}, data interface{}, flags ConnectFlags) int {
ctx := &CallbackContext{reflect.ValueOf(f), nil, reflect.ValueOf(v), reflect.ValueOf(data)}
ptr := C.CString(s)
defer C.free_string(ptr)
id := callback_contexts.Add(ctx)
ctx.cbi = unsafe.Pointer(C._g_signal_connect(unsafe.Pointer(v.Object), C.to_gcharptr(ptr), C.int(id), C.int(flags)))
return id
}
func (v *GObject) SignalConnectAfter(s string, f interface{}, datas ...interface{}) int {
var data interface{}
if len(datas) > 0 {
data = datas[0]
}
return v.SignalConnect(s, f, data, ConnectAfter)
}
func (v *GObject) SignalConnectSwapped(s string, f interface{}, datas ...interface{}) int {
var data interface{}
if len(datas) > 0 {
data = datas[0]
}
return v.SignalConnect(s, f, data, ConnectSwapped)
}
func (v *GObject) StopEmission(s string) {
ptr := C.CString(s)
defer C.free_string(ptr)
C.g_signal_stop_emission_by_name((C.gpointer)(v.Object), C.to_gcharptr(ptr))
}
func (v *GObject) Emit(s string) {
ptr := C.CString(s)
defer C.free_string(ptr)
C._g_signal_emit_by_name((C.gpointer)(v.Object), C.to_gcharptr(ptr))
}
func (v *GObject) HandlerBlock(call_id int) {
value, found := callback_contexts.Get(call_id)
if !found {
return
}
context := value.(*CallbackContext)
c_call_id := C._g_signal_callback_id((*C.callback_info)(context.cbi))
C.g_signal_handler_block((C.gpointer)(v.Object), c_call_id)
}
func (v *GObject) HandlerUnblock(call_id int) {
value, found := callback_contexts.Get(call_id)
if !found {
return
}
context := value.(*CallbackContext)
c_call_id := C._g_signal_callback_id((*C.callback_info)(context.cbi))
C.g_signal_handler_unblock((C.gpointer)(v.Object), c_call_id)
}
func (v *GObject) HandlerDisconnect(call_id int) {
value, found := callback_contexts.Get(call_id)
if !found {
return
}
context := value.(*CallbackContext)
c_call_id := C._g_signal_callback_id((*C.callback_info)(context.cbi))
C.g_signal_handler_disconnect((C.gpointer)(v.Object), c_call_id)
callback_contexts.Remove(call_id)
}
//-----------------------------------------------------------------------
// Main Loop
//-----------------------------------------------------------------------
type GMainContext struct {
MainContext *C.GMainContext
}
type GMainLoop struct {
MainLoop *C.GMainLoop
}
func NewMainContext() *GMainContext {
return &GMainContext{C.g_main_context_new()}
}
func (v *GMainContext) Ref() *GMainContext {
return &GMainContext{C.g_main_context_ref(v.MainContext)}
}
func (v *GMainContext) Unref() {
C.g_main_context_unref(v.MainContext)
}
func MainContextDefault() *GMainContext {
return &GMainContext{C.g_main_context_default()}
}
func (v *GMainContext) Iteration(blocking bool) bool {
return gobool(C.g_main_context_iteration(v.MainContext, gbool(blocking)))
}
func (v *GMainContext) Pending() bool {
return gobool(C.g_main_context_pending(v.MainContext))
}
func NewMainLoop(context *GMainContext, is_running bool) *GMainLoop {
var ctx *C.GMainContext
if context != nil {
ctx = context.MainContext
}
return &GMainLoop{C.g_main_loop_new(ctx, gbool(is_running))}
}
func (v *GMainLoop) Ref() *GMainLoop {
return &GMainLoop{C.g_main_loop_ref(v.MainLoop)}
}
func (v *GMainLoop) Unref() {
C.g_main_loop_unref(v.MainLoop)
}
func (v *GMainLoop) Run() {
C.g_main_loop_run(v.MainLoop)
}
func (v *GMainLoop) Quit() {
C.g_main_loop_quit(v.MainLoop)
}
func (v *GMainLoop) IsRunning() bool {
return gobool(C.g_main_loop_is_running(v.MainLoop))
}
func (v *GMainLoop) GetContext() *GMainContext {
return &GMainContext{C.g_main_loop_get_context(v.MainLoop)}
}
type SourcefuncContext struct {
f reflect.Value
data reflect.Value
}
//export _go_glib_sourcefunc
func _go_glib_sourcefunc(sfi *C.sourcefunc_info) {
id := int(sfi.func_no)
value, found := sourcefunc_contexts.Get(id)
if !found {
return
}
context := value.(*SourcefuncContext)
t := context.f.Type()
fargs := make([]reflect.Value, t.NumIn())
if len(fargs) > 0 {
fargs[0] = reflect.ValueOf(context.data)
}
ret := context.f.Call(fargs)
if len(ret) > 0 {
bret, _ := ret[0].Interface().(bool)
sfi.ret = gbool(bret)
}
}
func IdleAdd(f interface{}, datas ...interface{}) {
var data interface{}
if len(datas) > 0 {
data = datas[0]
}
ctx := &SourcefuncContext{reflect.ValueOf(f), reflect.ValueOf(data)}
id := sourcefunc_contexts.Add(ctx)
C._g_idle_add(C.int(id))
}
func TimeoutAdd(interval uint, f interface{}, datas ...interface{}) {
var data interface{}
if len(datas) > 0 {
data = datas[0]
}
ctx := &SourcefuncContext{reflect.ValueOf(f), reflect.ValueOf(data)}
id := sourcefunc_contexts.Add(ctx)
C._g_timeout_add(C.guint(interval), C.int(id))
}
//-----------------------------------------------------------------------
// thread
//-----------------------------------------------------------------------
func ThreadInit(a ...interface{}) {
// TODO: define GThreadFunctions
C._g_thread_init(nil)
}