mirror of
https://github.com/vbatts/freezing-octo-hipster.git
synced 2024-11-24 07:55:39 +00:00
1052 lines
28 KiB
Go
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)
|
|
}
|