func (self *GObjectObject) Connect(signal string, fun func()) { cgo_signal := C.CString(signal) defer C.free(unsafe.Pointer(cgo_signal)) callback := &Callback{uintptr(unsafe.Pointer(&fun)), &fun} _callbacks[callback.id] = callback C._signal_connect(self.GetGObject(), cgo_signal, unsafe.Pointer(callback)) }
func (o *Object) connect(noi bool, sid SignalId, detail Quark, cb_func, param0 interface{}) { cb := reflect.ValueOf(cb_func) if cb.Kind() != reflect.Func { panic("cb_func isn't a function") } // Check that function parameters and return value match to signal var sq C.GSignalQuery C.g_signal_query(C.guint(sid), &sq) ft := cb.Type() if ft.NumOut() > 1 || ft.NumOut() == 1 && Type(sq.return_type) == TYPE_NONE { panic("Number of function return values doesn't match signal spec.") } poffset := 2 if param0 == nil { // There is no param0 poffset-- } if noi { // There is no instance on which signal was emited as first parameter poffset-- } else if !o.Type().Match(ft.In(poffset - 1)) { panic(fmt.Sprintf( "Callback #%d param. type %s doesn't match signal source: %s", poffset-1, ft.In(poffset-1), o.Type(), )) } n_params := int(sq.n_params) if ft.NumIn() != n_params+poffset { panic(fmt.Sprintf( "Number of function parameters #%d isn't equal to signal spec: #%d", ft.NumIn(), n_params+poffset, )) } if ft.NumOut() != 0 && !Type(sq.return_type).Match(ft.Out(0)) { panic("Type of function return value doesn't match signal spec.") } if n_params > 0 { pt := (*[1 << 16]Type)(unsafe.Pointer(sq.param_types))[:int(sq.n_params)] for i := 0; i < n_params; i++ { if !pt[i].Match(ft.In(i + poffset)) { panic(fmt.Sprintf( "Callback #%d param. type %s doesn't match signal spec %s", i+poffset, ft.In(i+poffset), pt[i], )) } } } // Setup closure and connect it to signal var gocl *C.GoClosure p0 := reflect.ValueOf(param0) // Check type of #0 parameter which is set by Connect method switch p0.Kind() { case reflect.Invalid: gocl = C._object_closure_new(gBoolean(noi), nil) case reflect.Ptr: if !p0.Type().AssignableTo(ft.In(0)) { panic(fmt.Sprintf( "Callback #0 parameter type: %s doesn't match signal spec: %s", ft.In(0), p0.Type(), )) } gocl = C._object_closure_new(gBoolean(noi), C.gpointer(p0.Pointer())) default: panic("Callback parameter #0 isn't a pointer nor nil") } gocl.h_id = C._signal_connect(o.g(), C.guint(sid), C.GQuark(detail), gocl) oh := obj_handlers[uintptr(o.p)] if oh == nil { oh = make(map[SigHandlerId]*sigHandler) obj_handlers[uintptr(o.p)] = oh } oh[SigHandlerId(gocl.h_id)] = &sigHandler{cb, p0} // p0 for prevent GC }