Skip to content
This repository was archived by the owner on Aug 13, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions glib/glib_extra.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) 2014 Joan Garcia i Silano - https://github.com/joangs
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

package glib

import (
"errors"
)

// Gets the marshaller for a given type
func (t Type) GetMarshaller() (GValueMarshaler, error) {
if f, ok := gValueMarshalers[t]; ok {
return f, nil
}

return nil, errors.New("missing marshaler for type")
}
5 changes: 3 additions & 2 deletions gtk/gtk.go
Original file line number Diff line number Diff line change
Expand Up @@ -1300,6 +1300,7 @@ func (v *Bin) GetChild() (*Widget, error) {
// Builder is a representation of GTK's GtkBuilder.
type Builder struct {
*glib.Object
callbacks []interface{}
}

// native() returns a pointer to the underlying GtkBuilder.
Expand All @@ -1314,7 +1315,7 @@ func (b *Builder) native() *C.GtkBuilder {
func marshalBuilder(p uintptr) (interface{}, error) {
c := C.g_value_get_object((*C.GValue)(unsafe.Pointer(p)))
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
return &Builder{obj}, nil
return &Builder{obj, []interface{}{}}, nil
}

// BuilderNew is a wrapper around gtk_builder_new().
Expand All @@ -1324,7 +1325,7 @@ func BuilderNew() (*Builder, error) {
return nil, nilPtrErr
}
obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))}
b := &Builder{obj}
b := &Builder{obj, []interface{}{}}
obj.RefSink()
runtime.SetFinalizer(obj, (*glib.Object).Unref)
return b, nil
Expand Down
70 changes: 70 additions & 0 deletions gtk/gtkbuilder_bridge.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) 2014 Joan Garcia i Silano - https://github.com/joangs
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package gtk

/*
#cgo pkg-config: gtk+-3.0
#include <stdlib.h>
#include <gtk/gtk.h>

*/
import "C"
import (
"github.com/conformal/gotk3/glib"
"log"
"reflect"
"strings"
"unsafe"
)

//export dispatchEvent
func dispatchEvent(pbuilder unsafe.Pointer, csignal *C.char, rval *C.GValue, nparams C.guint, size C.int, params *C.GValue) {
b := (*Builder)(pbuilder)
signal := C.GoString(csignal)
signal = strings.ToUpper(signal[:1]) + signal[1:]

values := []reflect.Value{}

for c := uint64(0); c < (uint64)(nparams); c++ {
addr := uintptr(unsafe.Pointer(params)) + uintptr(c*uint64(size))
v := (*C.GValue)(unsafe.Pointer(addr))

t := glib.Type(v.g_type)
if m, err := t.GetMarshaller(); err != nil {
log.Printf("Error: %s", err.Error())
return
} else {
if gov, err := m(uintptr(unsafe.Pointer(v))); err != nil {
log.Printf("Error: %s", err.Error())
return
} else {
values = append(values, reflect.ValueOf(gov))
}
}
}

log.Printf("%s(%v) %d", signal, values, nparams)

for _, iface := range b.callbacks {
v := reflect.ValueOf(iface)
m := v.MethodByName(signal)

if m.IsValid() {
m.Call(values)
return
}
}

log.Printf("Warning: Signal '%s' not defined", signal)
}
91 changes: 91 additions & 0 deletions gtk/gtkbuilder_cgo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright (c) 2014 Joan Garcia i Silano - https://github.com/joangs
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package gtk

/*
#cgo pkg-config: gtk+-3.0
#include <stdlib.h>
#include <gtk/gtk.h>


typedef void (*callbackFunc) ();

#define BUILDER_DATA(ptr) ((struct gtkbuilder_data *)(ptr))

// TODO: Free data when GtkBuilder is freed.
struct gtkbuilder_data {
char *signal;
void *builder;
};


void gtkbuilder_handler(GClosure *closure,
GValue *return_value,
guint nparams,
const GValue *params,
gpointer invocation_hint,
gpointer marshal_data) {

const GValue **p;
int c;

p = (const GValue **)malloc(nparams * sizeof(GValue*));
for (c = 0; c < nparams; c++) {
p[c] = params+c;
}

dispatchEvent(BUILDER_DATA(marshal_data)->builder, BUILDER_DATA(marshal_data)->signal, return_value, nparams, sizeof(GValue), params);
free(p);
}

void gtkbuilder_connector(GtkBuilder *builder,
GObject *object,
const gchar *signal_name,
const gchar *handler_name,
GObject *connect_object,
GConnectFlags flags,
gpointer user_data)
{
struct gtkbuilder_data *data;
GClosure *c;

if (!(data = (struct gtkbuilder_data *)malloc(sizeof(struct gtkbuilder_data)))) {
fprintf(stderr, "ERROR: Not enough memory.\n");
return;
}

data->signal = g_strdup_printf("%s", handler_name);
data->builder = user_data;
printf("Connect '%s' w/ %s\n", signal_name, data->signal);

c = g_closure_new_simple(sizeof(GClosure), data);
g_closure_set_meta_marshal(c, data, gtkbuilder_handler);
g_signal_connect_closure(object, signal_name, c, FALSE);
}

*/
import "C"
import (
"unsafe"
)

// Bind callbacks methods using reflection. Callbacks must be exported (first letter in upper case)
func (b *Builder) BindCallbacks(ifaces ...interface{}) {
for _, v := range ifaces {
b.callbacks = append(b.callbacks, v)
}

C.gtk_builder_connect_signals_full(b.native(), C.callbackFunc(C.gtkbuilder_connector), C.gpointer(unsafe.Pointer(b)))

}