This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch main
in repository ego.
View the commit online.
commit 3bb76f28bf1b87d6392e91523c28f6fc8f27080a
Author: [email protected] <[email protected]>
AuthorDate: Mon Mar 30 22:06:37 2026 -0600
feat(ego-gen): generate callback trampolines and closure-accepting methods
Generate per-typedef //export trampolines for EFL function pointer
callbacks, plus Go methods that accept closures and bridge them
to C via the CallbackRegister/free_cb pattern. Unlocks signal
callbacks, thread IO, and filter model methods.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---
cmd/ego-gen/generator.go | 45 +++++++++
cmd/ego-gen/main.go | 109 +++++++++++++++++----
cmd/ego-gen/templates/callback_trampolines.go.tmpl | 75 ++++++++++++++
cmd/ego-gen/templates/class.go.tmpl | 46 ++++++++-
efl/callback_trampolines_gen.go | 95 ++++++++++++++++++
efl/canvas/layout.go | 23 +++++
efl/eo/appthread.go | 16 +++
efl/eo/filter_model.go | 9 ++
efl/eo/thread.go | 16 +++
efl/eo/thread_io.go | 16 +++
efl/layout/signal.go | 23 +++++
efl/ui/image.go | 23 +++++
efl/ui/layout_base.go | 23 +++++
13 files changed, 501 insertions(+), 18 deletions(-)
diff --git a/cmd/ego-gen/generator.go b/cmd/ego-gen/generator.go
index 0b0c37d..610645b 100644
--- a/cmd/ego-gen/generator.go
+++ b/cmd/ego-gen/generator.go
@@ -221,6 +221,14 @@ type EventData struct {
PayloadCType string
}
+// PackageCallbackData holds all unique callback typedefs for a single generated
+// package. It is used to render the per-package callback_trampolines_gen.go file
+// that contains the //export trampoline functions.
+type PackageCallbackData struct {
+ PackageName string
+ CallbackTypes []CallbackTypeData
+}
+
// EnumData holds the information needed to render a Go file for one EFL enum.
type EnumData struct {
PackageName string
@@ -283,6 +291,43 @@ func (g *Generator) GenerateEnum(data EnumData) error {
return g.generate("enum.go.tmpl", data.PackageName, toSnake(data.GoTypeName), data)
}
+// GenerateCallbackTrampolines renders the callback trampolines template and
+// writes the result to outputDir/callback_trampolines_gen.go (in the root
+// output package). The generated file contains //export functions and must not
+// be in a file that also defines cgo preamble C code (CGO //export constraint).
+// All trampolines go into one file so that //export symbols are defined exactly
+// once across the entire binary (duplicate-symbol linker errors would otherwise
+// occur when multiple sub-packages forward the same mixin callback type).
+func (g *Generator) GenerateCallbackTrampolines(data PackageCallbackData) error {
+ // Write directly into g.outputDir (the base efl package), not a subdirectory.
+ return g.generateInDir("callback_trampolines.go.tmpl", g.outputDir, "callback_trampolines_gen", data)
+}
+
+// generateInDir is like generate but writes to an explicit directory instead of
+// computing it from outputDir + pkg.
+func (g *Generator) generateInDir(tmplName, dir, baseName string, data any) error {
+ if err := os.MkdirAll(dir, 0o755); err != nil {
+ return fmt.Errorf("generator: mkdir %s: %w", dir, err)
+ }
+
+ var buf bytes.Buffer
+ if err := g.tmpl.ExecuteTemplate(&buf, tmplName, data); err != nil {
+ return fmt.Errorf("generator: execute template %s: %w", tmplName, err)
+ }
+
+ src := buf.Bytes()
+ formatted, err := format.Source(src)
+ if err != nil {
+ formatted = src
+ }
+
+ outPath := filepath.Join(dir, baseName+".go")
+ if err := os.WriteFile(outPath, formatted, 0o644); err != nil {
+ return fmt.Errorf("generator: write %s: %w", outPath, err)
+ }
+ return nil
+}
+
// generate executes the named template with the given data, formats the
// output with go/format, and writes it to outputDir/pkg/filename.go.
// If go/format fails, the raw output is written so the file can be inspected.
diff --git a/cmd/ego-gen/main.go b/cmd/ego-gen/main.go
index 2d332ea..42d9761 100644
--- a/cmd/ego-gen/main.go
+++ b/cmd/ego-gen/main.go
@@ -36,9 +36,7 @@ var methodBlocklist = map[string]bool{
// efl.Layout.Calc — return struct by value; cannot be converted to unsafe.Pointer by cgo
"efl_layout_calc_size_min": true,
"efl_layout_calc_parts_extends": true,
- // efl.Layout.Signal — function has more params than Eolian reports
- "efl_layout_signal_callback_add": true,
- "efl_layout_signal_callback_del": true,
+ // efl.Layout.Signal — callback params handled via callback trampoline generation.
// efl.Layout.Signal — takes const Eina_Value by value; struct-valued parameter
"efl_layout_signal_message_send": true,
// efl.Access.Text — character_extents_get and range_extents_get take an extra Eina_Rect* out-param
@@ -60,8 +58,7 @@ var methodBlocklist = map[string]bool{
"efl_file_mmap_set": true,
// efl.File_Save — struct-by-value parameter incompatible with generated pointer wrapper
"efl_file_save": true,
- // efl.Filter_Model — callback parameter not reported by Eolian; wrong argument count
- "efl_filter_model_filter_set": true,
+ // efl.Filter_Model — callback param handled via callback trampoline generation.
// efl.Object — struct-by-pointer mismatch in event forwarder methods
"efl_event_callback_forwarder_priority_add": true,
"efl_event_callback_forwarder_del": true,
@@ -70,9 +67,7 @@ var methodBlocklist = map[string]bool{
// efl.Text_Formatter — wrong argument count reported by Eolian
"efl_text_formatter_attribute_insert": true,
"efl_text_formatter_attribute_clear": true,
- // efl.ThreadIO — callback struct parameters with extra data args not reported by Eolian
- "efl_threadio_call": true,
- "efl_threadio_call_sync": true,
+ // efl.ThreadIO — callback params handled via callback trampoline generation.
// efl.Input.Pointer — position setters now handled via known struct support.
// efl.Text_Cursor.Object — returns Eina_Rect by value (struct return not supported in indexed property)
"efl_text_cursor_object_lower_cursor_geometry_get": true,
@@ -162,7 +157,9 @@ var methodBlocklist = map[string]bool{
// efl.Net.Socket.Udp — more methods returning Eina_Error
"efl_net_socket_udp_multicast_join": true,
"efl_net_socket_udp_multicast_leave": true,
- // efl.Ui.Format — func_set takes callback+data+free_cb (3 extra params, not 1)
+ // efl.Ui.Format — func_set is a property setter that takes callback+data+free_cb
+ // (3 extra params not reflected in Eolian's property model). Keep blocked to prevent
+ // the property wrapper from generating a broken C shim with too few arguments.
"efl_ui_format_func_set": true,
// efl.Ui.Dnd — struct-by-value Eina_Content parameter
"efl_ui_dnd_drag_start": true,
@@ -180,9 +177,11 @@ var methodBlocklist = map[string]bool{
"efl_ui_property_bind": true,
// efl.Ui.Selection — struct-by-value Eina_Content parameter
"efl_ui_selection_set": true,
- // efl.Ui.ViewModel — returns Eina_Error; callback-style with extra params
+ // efl.Ui.ViewModel — returns Eina_Error; cannot be wrapped
"efl_ui_view_model_property_bind": true,
"efl_ui_view_model_factory_bind": true,
+ // efl.Ui.ViewModel — property_logic_add has complex multi-callback + iterator params
+ // that the generator cannot handle (Eolian reports fewer params than the C declaration).
"efl_ui_view_model_property_logic_add": true,
"efl_ui_view_model_property_logic_del": true,
// efl.Ui.ViewModel — more methods returning Eina_Error
@@ -331,6 +330,10 @@ func run(eoDirs, outputDir, templateDir string, useSystem bool) error {
// struct-typed properties from parent interfaces.
pkgOptionNames := make(map[string]map[string]bool)
+ // pkgCallbackTypes accumulates unique callback typedefs per package for the
+ // second-pass trampoline file generation.
+ pkgCallbackTypes := make(map[string]map[string]CallbackTypeData)
+
for _, c := range classes {
data, err := buildClassData(c, pkgOptionNames)
if err != nil {
@@ -345,9 +348,47 @@ func run(eoDirs, outputDir, templateDir string, useSystem bool) error {
continue
}
generated++
+
+ // Accumulate callback types for this package.
+ if len(data.CallbackTypes) > 0 {
+ if pkgCallbackTypes[data.PackageName] == nil {
+ pkgCallbackTypes[data.PackageName] = make(map[string]CallbackTypeData)
+ }
+ for _, ct := range data.CallbackTypes {
+ pkgCallbackTypes[data.PackageName][ct.EolianName] = ct
+ }
+ }
}
- // Step 7: Log statistics.
+ // Step 7: Generate a single callback trampolines file in the base "efl" package.
+ // All //export trampoline functions must be defined exactly once across the
+ // entire binary; placing them in the base package avoids duplicate-symbol
+ // linker errors when multiple sub-packages forward the same mixin callback.
+ allCallbackTypeMap := make(map[string]CallbackTypeData)
+ for _, typeMap := range pkgCallbackTypes {
+ for name, ct := range typeMap {
+ allCallbackTypeMap[name] = ct
+ }
+ }
+ if len(allCallbackTypeMap) > 0 {
+ var allTypes []CallbackTypeData
+ for _, ct := range allCallbackTypeMap {
+ allTypes = append(allTypes, ct)
+ }
+ sort.Slice(allTypes, func(i, j int) bool {
+ return allTypes[i].EolianName < allTypes[j].EolianName
+ })
+ cbData := PackageCallbackData{
+ PackageName: "efl",
+ CallbackTypes: allTypes,
+ }
+ if err := gen.GenerateCallbackTrampolines(cbData); err != nil {
+ log.Printf("ego-gen: generate callback trampolines: %v", err)
+ errCount++
+ }
+ }
+
+ // Step 8: Log statistics.
log.Printf("ego-gen: generated=%d skipped=%d errors=%d", generated, skipped, errCount)
if errCount > 0 {
@@ -832,6 +873,22 @@ func buildClassData(c *Class, pkgOptionNames map[string]map[string]bool) (ClassD
}
}
+ // Collect unique callback types for trampoline generation.
+ callbackTypeMap := make(map[string]CallbackTypeData)
+ for _, m := range methods {
+ for _, cp := range m.CallbackParams {
+ callbackTypeMap[cp.CallbackType.EolianName] = *cp.CallbackType
+ }
+ }
+ var callbackTypes []CallbackTypeData
+ for _, ct := range callbackTypeMap {
+ callbackTypes = append(callbackTypes, ct)
+ }
+ // Sort for deterministic output.
+ sort.Slice(callbackTypes, func(i, j int) bool {
+ return callbackTypes[i].EolianName < callbackTypes[j].EolianName
+ })
+
return ClassData{
PackageName: pkgName,
GoName: goName,
@@ -857,6 +914,8 @@ func buildClassData(c *Class, pkgOptionNames map[string]map[string]bool) (ClassD
HasIterators: len(iteratorMethods) > 0,
IteratorStructTypes: deduplicateIteratorStructTypes(iteratorMethods),
GlobalFunctions: globalFunctions,
+ CallbackTypes: callbackTypes,
+ HasCallbacks: len(callbackTypes) > 0,
}, nil
}
@@ -1105,7 +1164,22 @@ func buildMethodData(f *Function, cPrefix string) MethodData {
var params []ParamData
var outParams []OutParamData
+ var callbackParams []CallbackParamData
for _, p := range f.Parameters() {
+ // Check for callback function pointer parameter.
+ if p.Direction() == ParamIn && isCallbackParam(p) {
+ cbd, err := buildCallbackTypeData(p)
+ if err != nil {
+ log.Printf("ego-gen: skip callback param %s in %s: %v", p.Name(), methodName, err)
+ continue
+ }
+ callbackParams = append(callbackParams, CallbackParamData{
+ GoName: snakeToLowerCamel(p.Name()),
+ CallbackType: cbd,
+ })
+ continue
+ }
+
if p.Direction() != ParamIn {
if p.Direction() == ParamOut || p.Direction() == ParamInOut {
pt := p.Type()
@@ -1141,12 +1215,13 @@ func buildMethodData(f *Function, cPrefix string) MethodData {
}
return MethodData{
- GoName: goName,
- CName: cName,
- Params: params,
- ReturnType: returnType,
- ReturnCType: returnCType,
- OutParams: outParams,
+ GoName: goName,
+ CName: cName,
+ Params: params,
+ ReturnType: returnType,
+ ReturnCType: returnCType,
+ OutParams: outParams,
+ CallbackParams: callbackParams,
}
}
diff --git a/cmd/ego-gen/templates/callback_trampolines.go.tmpl b/cmd/ego-gen/templates/callback_trampolines.go.tmpl
new file mode 100644
index 0000000..0c080c6
--- /dev/null
+++ b/cmd/ego-gen/templates/callback_trampolines.go.tmpl
@@ -0,0 +1,75 @@
+// Code generated by ego-gen. DO NOT EDIT.
+
+package {{.PackageName}}
+
+/*
+#cgo pkg-config: elementary
+#define EFL_BETA_API_SUPPORT 1
+// Define all EFL_*_PROTECTED macros to expose @protected methods.
+#define EFL_ACCESS_ACTION_PROTECTED 1
+#define EFL_ACCESS_COMPONENT_PROTECTED 1
+#define EFL_ACCESS_EDITABLE_TEXT_PROTECTED 1
+#define EFL_ACCESS_OBJECT_PROTECTED 1
+#define EFL_ACCESS_SELECTION_PROTECTED 1
+#define EFL_ACCESS_TEXT_PROTECTED 1
+#define EFL_ACCESS_VALUE_PROTECTED 1
+#define EFL_ACCESS_WIDGET_ACTION_PROTECTED 1
+#define EFL_CONFIG_GLOBAL_PROTECTED 1
+#define EFL_GFX_HINT_PROTECTED 1
+#define EFL_IO_CLOSER_FD_PROTECTED 1
+#define EFL_IO_COPIER_PROTECTED 1
+#define EFL_IO_POSITIONER_FD_PROTECTED 1
+#define EFL_IO_READER_FD_PROTECTED 1
+#define EFL_IO_READER_PROTECTED 1
+#define EFL_IO_SIZER_FD_PROTECTED 1
+#define EFL_IO_WRITER_FD_PROTECTED 1
+#define EFL_IO_WRITER_PROTECTED 1
+#define EFL_LAYOUT_CALC_PROTECTED 1
+#define EFL_LOOP_PROTECTED 1
+#define EFL_PACK_LAYOUT_PROTECTED 1
+#define EFL_PART_PROTECTED 1
+#define EFL_UI_FACTORY_PROTECTED 1
+#define EFL_UI_FOCUS_COMPOSITION_PROTECTED 1
+#define EFL_UI_FOCUS_LAYER_PROTECTED 1
+#define EFL_UI_FOCUS_OBJECT_PROTECTED 1
+#define EFL_UI_FORMAT_PROTECTED 1
+#define EFL_UI_L10N_PROTECTED 1
+#define EFL_UI_SCROLLBAR_PROTECTED 1
+#define EFL_UI_SCROLL_MANAGER_PROTECTED 1
+#define EFL_UI_WIDGET_FOCUS_MANAGER_PROTECTED 1
+#define EFL_UI_WIDGET_PROTECTED 1
+#define EFL_UI_WIDGET_SCROLLABLE_CONTENT_PROTECTED 1
+#define EFL_CANVAS_GESTURE_PROTECTED 1
+#define EFL_CANVAS_GESTURE_CUSTOM_PROTECTED 1
+#define EFL_CANVAS_GROUP_PROTECTED 1
+#define EFL_CANVAS_OBJECT_PROTECTED 1
+#define EFL_INPUT_CLICKABLE_PROTECTED 1
+#include <Efl_Ui.h>
+*/
+import "C"
+
+import "unsafe"
+
+// Ensure unused imports are not flagged.
+var _ = unsafe.Pointer(nil)
+
+//export egoCallbackFree
+func egoCallbackFree(data unsafe.Pointer) {
+ CallbackRemove(uintptr(data))
+}
+
+{{- range .CallbackTypes}}
+
+//export {{.GoTrampolineName}}
+func {{.GoTrampolineName}}(data unsafe.Pointer{{range .Params}}, {{.GoName}} {{if .IsEo}}*C.Eo{{else if needsStringConversion .CType}}*C.char{{else if isBoolType .CType}}C.{{cTypeToCgo .CType}}{{else if isPointerType .GoType}}unsafe.Pointer{{else}}C.{{cTypeToCgo .CType}}{{end}}{{end}}) {{if .ReturnCType}}C.{{cTypeToCgo .ReturnCType}}{{end}} {
+ fn := CallbackLookup[{{.GoFuncType}}](uintptr(data))
+ if fn == nil {
+{{- if .ReturnCType}}
+ var _zero C.{{cTypeToCgo .ReturnCType}}
+ return _zero
+{{- end}}
+ return
+ }
+ {{if .ReturnCType}}_ = {{end}}fn({{range $i, $p := .Params}}{{if $i}}, {{end}}{{if $p.IsEo}}unsafe.Pointer({{$p.GoName}}){{else if needsStringConversion $p.CType}}C.GoString({{$p.GoName}}){{else if isBoolType $p.CType}}{{$p.GoName}} != 0{{else if isPointerType $p.GoType}}{{$p.GoName}}{{else}}{{$p.GoType}}({{$p.GoName}}){{end}}{{end}})
+}
+{{- end}}
diff --git a/cmd/ego-gen/templates/class.go.tmpl b/cmd/ego-gen/templates/class.go.tmpl
index 3dcdbf0..f773821 100644
--- a/cmd/ego-gen/templates/class.go.tmpl
+++ b/cmd/ego-gen/templates/class.go.tmpl
@@ -106,6 +106,18 @@ static {{index $im.StructCFieldTypes $i}} _ego_iter_{{$im.StructCType}}_{{$f}}(c
{{- end}}{{- end}}
{{- end}}
+{{- if .HasCallbacks}}
+// Callback trampoline forward declarations.
+extern void egoCallbackFree(void *data);
+{{- range .CallbackTypes}}
+{{- if .ReturnCType}}
+extern {{.ReturnCType}} {{.GoTrampolineName}}(void *data{{range .Params}}, {{.CType}} {{.GoName}}{{end}});
+{{- else}}
+extern void {{.GoTrampolineName}}(void *data{{range .Params}}, {{.CType}} {{.GoName}}{{end}});
+{{- end}}
+{{- end}}
+{{- end}}
+
{{- range .Properties}}
{{- if and .HasGet (isPointerType .GoType)}}
// _ego_get_{{.CGetName}} wraps the getter, casting the return value through
@@ -434,7 +446,39 @@ func (o *{{$.GoName}}) {{$prop.GoSetter}}(val {{if $prop.IsEo}}efl.Objecter{{els
{{- end}}
{{- range .Methods}}
-{{- if .OutParams}}
+{{- if .CallbackParams}}
+{{- $m := .}}
+
+// {{$m.GoName}} calls the {{$m.CName}} method on {{$.GoName}}.
+func (o *{{$.GoName}}) {{$m.GoName}}({{range $i, $p := $m.Params}}{{if $i}}, {{end}}{{$p.GoName}} {{if $p.IsEo}}efl.Objecter{{else}}{{$p.GoType}}{{end}}{{end}}{{if $m.Params}}, {{end}}{{range $i, $cp := $m.CallbackParams}}{{if $i}}, {{end}}{{$cp.GoName}} {{$cp.CallbackType.GoFuncType}}{{end}}) {{if $m.ReturnType}}{{$m.ReturnType}}{{end}} {
+{{- range $m.Params}}
+{{- if needsStringConversion .CType}}
+ c{{.GoName}} := C.CString({{.GoName}})
+ defer C.free(unsafe.Pointer(c{{.GoName}}))
+{{- else if isBoolType .CType}}
+ var c{{.GoName}} C.{{cTypeToCgo .CType}}
+ if {{.GoName}} { c{{.GoName}} = 1 }
+{{- end}}
+{{- end}}
+{{- range $m.CallbackParams}}
+ id{{.GoName}} := efl.CallbackRegister({{.GoName}})
+{{- end}}
+{{- if $m.ReturnType}}
+{{- if needsStringConversion $m.ReturnCType}}
+ cResult := C.{{$m.CName}}((*C.Eo)(o.Eo()){{range $m.Params}}, {{template "paramArg" .}}{{end}}{{range $m.CallbackParams}}, unsafe.Pointer(id{{.GoName}}), C.{{.CallbackType.CTypedef}}(C.{{.CallbackType.GoTrampolineName}}), C.Eina_Free_Cb(C.egoCallbackFree){{end}})
+ return C.GoString(cResult)
+{{- else if isBoolType $m.ReturnCType}}
+ return C.{{$m.CName}}((*C.Eo)(o.Eo()){{range $m.Params}}, {{template "paramArg" .}}{{end}}{{range $m.CallbackParams}}, unsafe.Pointer(id{{.GoName}}), C.{{.CallbackType.CTypedef}}(C.{{.CallbackType.GoTrampolineName}}), C.Eina_Free_Cb(C.egoCallbackFree){{end}}) != 0
+{{- else if isPointerType $m.ReturnType}}
+ return unsafe.Pointer(C.{{$m.CName}}((*C.Eo)(o.Eo()){{range $m.Params}}, {{template "paramArg" .}}{{end}}{{range $m.CallbackParams}}, unsafe.Pointer(id{{.GoName}}), C.{{.CallbackType.CTypedef}}(C.{{.CallbackType.GoTrampolineName}}), C.Eina_Free_Cb(C.egoCallbackFree){{end}}))
+{{- else}}
+ return {{$m.ReturnType}}(C.{{$m.CName}}((*C.Eo)(o.Eo()){{range $m.Params}}, {{template "paramArg" .}}{{end}}{{range $m.CallbackParams}}, unsafe.Pointer(id{{.GoName}}), C.{{.CallbackType.CTypedef}}(C.{{.CallbackType.GoTrampolineName}}), C.Eina_Free_Cb(C.egoCallbackFree){{end}}))
+{{- end}}
+{{- else}}
+ C.{{$m.CName}}((*C.Eo)(o.Eo()){{range $m.Params}}, {{template "paramArg" .}}{{end}}{{range $m.CallbackParams}}, unsafe.Pointer(id{{.GoName}}), C.{{.CallbackType.CTypedef}}(C.{{.CallbackType.GoTrampolineName}}), C.Eina_Free_Cb(C.egoCallbackFree){{end}})
+{{- end}}
+}
+{{- else if .OutParams}}
{{- $m := .}}
{{- range $op := .OutParams}}
{{- if $op.IsStruct}}
diff --git a/efl/callback_trampolines_gen.go b/efl/callback_trampolines_gen.go
new file mode 100644
index 0000000..85c273c
--- /dev/null
+++ b/efl/callback_trampolines_gen.go
@@ -0,0 +1,95 @@
+// Code generated by ego-gen. DO NOT EDIT.
+
+package efl
+
+/*
+#cgo pkg-config: elementary
+#define EFL_BETA_API_SUPPORT 1
+// Define all EFL_*_PROTECTED macros to expose @protected methods.
+#define EFL_ACCESS_ACTION_PROTECTED 1
+#define EFL_ACCESS_COMPONENT_PROTECTED 1
+#define EFL_ACCESS_EDITABLE_TEXT_PROTECTED 1
+#define EFL_ACCESS_OBJECT_PROTECTED 1
+#define EFL_ACCESS_SELECTION_PROTECTED 1
+#define EFL_ACCESS_TEXT_PROTECTED 1
+#define EFL_ACCESS_VALUE_PROTECTED 1
+#define EFL_ACCESS_WIDGET_ACTION_PROTECTED 1
+#define EFL_CONFIG_GLOBAL_PROTECTED 1
+#define EFL_GFX_HINT_PROTECTED 1
+#define EFL_IO_CLOSER_FD_PROTECTED 1
+#define EFL_IO_COPIER_PROTECTED 1
+#define EFL_IO_POSITIONER_FD_PROTECTED 1
+#define EFL_IO_READER_FD_PROTECTED 1
+#define EFL_IO_READER_PROTECTED 1
+#define EFL_IO_SIZER_FD_PROTECTED 1
+#define EFL_IO_WRITER_FD_PROTECTED 1
+#define EFL_IO_WRITER_PROTECTED 1
+#define EFL_LAYOUT_CALC_PROTECTED 1
+#define EFL_LOOP_PROTECTED 1
+#define EFL_PACK_LAYOUT_PROTECTED 1
+#define EFL_PART_PROTECTED 1
+#define EFL_UI_FACTORY_PROTECTED 1
+#define EFL_UI_FOCUS_COMPOSITION_PROTECTED 1
+#define EFL_UI_FOCUS_LAYER_PROTECTED 1
+#define EFL_UI_FOCUS_OBJECT_PROTECTED 1
+#define EFL_UI_FORMAT_PROTECTED 1
+#define EFL_UI_L10N_PROTECTED 1
+#define EFL_UI_SCROLLBAR_PROTECTED 1
+#define EFL_UI_SCROLL_MANAGER_PROTECTED 1
+#define EFL_UI_WIDGET_FOCUS_MANAGER_PROTECTED 1
+#define EFL_UI_WIDGET_PROTECTED 1
+#define EFL_UI_WIDGET_SCROLLABLE_CONTENT_PROTECTED 1
+#define EFL_CANVAS_GESTURE_PROTECTED 1
+#define EFL_CANVAS_GESTURE_CUSTOM_PROTECTED 1
+#define EFL_CANVAS_GROUP_PROTECTED 1
+#define EFL_CANVAS_OBJECT_PROTECTED 1
+#define EFL_INPUT_CLICKABLE_PROTECTED 1
+#include <Efl_Ui.h>
+*/
+import "C"
+
+import "unsafe"
+
+// Ensure unused imports are not flagged.
+var _ = unsafe.Pointer(nil)
+
+//export egoCallbackFree
+func egoCallbackFree(data unsafe.Pointer) {
+ CallbackRemove(uintptr(data))
+}
+
+//export egoCallback_EflFilterModel
+func egoCallback_EflFilterModel(data unsafe.Pointer, parent *C.Eo, child *C.Eo) {
+ fn := CallbackLookup[func(unsafe.Pointer, unsafe.Pointer)](uintptr(data))
+ if fn == nil {
+ return
+ }
+ fn(unsafe.Pointer(parent), unsafe.Pointer(child))
+}
+
+//export egoCallback_EflLayoutSignalCb
+func egoCallback_EflLayoutSignalCb(data unsafe.Pointer, object *C.Eo, emission *C.char, source *C.char) {
+ fn := CallbackLookup[func(unsafe.Pointer, string, string)](uintptr(data))
+ if fn == nil {
+ return
+ }
+ fn(unsafe.Pointer(object), C.GoString(emission), C.GoString(source))
+}
+
+//export egoCallback_EflThreadIOCall
+func egoCallback_EflThreadIOCall(data unsafe.Pointer, event unsafe.Pointer) {
+ fn := CallbackLookup[func(unsafe.Pointer)](uintptr(data))
+ if fn == nil {
+ return
+ }
+ fn(event)
+}
+
+//export egoCallback_EflThreadIOCallSync
+func egoCallback_EflThreadIOCallSync(data unsafe.Pointer, event unsafe.Pointer) {
+ fn := CallbackLookup[func(unsafe.Pointer)](uintptr(data))
+ if fn == nil {
+ return
+ }
+ fn(event)
+}
diff --git a/efl/canvas/layout.go b/efl/canvas/layout.go
index 61f410e..88103fc 100644
--- a/efl/canvas/layout.go
+++ b/efl/canvas/layout.go
@@ -131,6 +131,9 @@ static Eina_Bool _ego_iter_next(Eina_Iterator *iter, void **data) {
static void _ego_iter_free(Eina_Iterator *iter) {
eina_iterator_free(iter);
}
+// Callback trampoline forward declarations.
+extern void egoCallbackFree(void *data);
+extern void egoCallback_EflLayoutSignalCb(void *data, Efl_Layout_Signal * object, const char * emission, const char * source);
// _ego_get_efl_canvas_layout_load_error_get wraps the getter, casting the return value through
// uintptr_t so that both pointer and integer returns become void *.
// This prevents C type conflicts when Eolian's type differs from the header.
@@ -525,6 +528,26 @@ func (o *Layout) CalcForce() {
C.efl_layout_calc_force((*C.Eo)(o.Eo()))
}
+// SignalCallbackAdd calls the efl_layout_signal_callback_add method on Layout.
+func (o *Layout) SignalCallbackAdd(emission string, source string, func_ func(unsafe.Pointer, string, string)) bool {
+ cemission := C.CString(emission)
+ defer C.free(unsafe.Pointer(cemission))
+ csource := C.CString(source)
+ defer C.free(unsafe.Pointer(csource))
+ idfunc_ := efl.CallbackRegister(func_)
+ return C.efl_layout_signal_callback_add((*C.Eo)(o.Eo()), cemission, csource, unsafe.Pointer(idfunc_), C.EflLayoutSignalCb(C.egoCallback_EflLayoutSignalCb), C.Eina_Free_Cb(C.egoCallbackFree)) != 0
+}
+
+// SignalCallbackDel calls the efl_layout_signal_callback_del method on Layout.
+func (o *Layout) SignalCallbackDel(emission string, source string, func_ func(unsafe.Pointer, string, string)) bool {
+ cemission := C.CString(emission)
+ defer C.free(unsafe.Pointer(cemission))
+ csource := C.CString(source)
+ defer C.free(unsafe.Pointer(csource))
+ idfunc_ := efl.CallbackRegister(func_)
+ return C.efl_layout_signal_callback_del((*C.Eo)(o.Eo()), cemission, csource, unsafe.Pointer(idfunc_), C.EflLayoutSignalCb(C.egoCallback_EflLayoutSignalCb), C.Eina_Free_Cb(C.egoCallbackFree)) != 0
+}
+
// SignalEmit calls the efl_layout_signal_emit method on Layout.
func (o *Layout) SignalEmit(emission string, source string) {
cemission := C.CString(emission)
diff --git a/efl/eo/appthread.go b/efl/eo/appthread.go
index eede53a..6f75874 100644
--- a/efl/eo/appthread.go
+++ b/efl/eo/appthread.go
@@ -99,6 +99,10 @@ typedef Eo Efl_Ui_Widget;
// Declare the class_get function directly rather than including the full .eo.h
// header, which may reference types from other .eo files that are not included.
extern const Efl_Class *efl_appthread_class_get(void);
+// Callback trampoline forward declarations.
+extern void egoCallbackFree(void *data);
+extern void egoCallback_EflThreadIOCall(void *data, const Efl_Event * event);
+extern void egoCallback_EflThreadIOCallSync(void *data, const Efl_Event * event);
// _ego_get_efl_threadio_indata_get wraps the getter, casting the return value through
// uintptr_t so that both pointer and integer returns become void *.
// This prevents C type conflicts when Eolian's type differs from the header.
@@ -310,6 +314,18 @@ func (o *Appthread) SetCommandString(val string) {
C.efl_core_command_line_command_string_set((*C.Eo)(o.Eo()), cVal)
}
+// Call calls the efl_threadio_call method on Appthread.
+func (o *Appthread) Call(func_ func(unsafe.Pointer)) {
+ idfunc_ := efl.CallbackRegister(func_)
+ C.efl_threadio_call((*C.Eo)(o.Eo()), unsafe.Pointer(idfunc_), C.EflThreadIOCall(C.egoCallback_EflThreadIOCall), C.Eina_Free_Cb(C.egoCallbackFree))
+}
+
+// CallSync calls the efl_threadio_call_sync method on Appthread.
+func (o *Appthread) CallSync(func_ func(unsafe.Pointer)) unsafe.Pointer {
+ idfunc_ := efl.CallbackRegister(func_)
+ return unsafe.Pointer(C.efl_threadio_call_sync((*C.Eo)(o.Eo()), unsafe.Pointer(idfunc_), C.EflThreadIOCallSync(C.egoCallback_EflThreadIOCallSync), C.Eina_Free_Cb(C.egoCallbackFree)))
+}
+
// CommandAccess calls the efl_core_command_line_command_access method on Appthread.
func (o *Appthread) CommandAccess() unsafe.Pointer {
return unsafe.Pointer(C.efl_core_command_line_command_access((*C.Eo)(o.Eo())))
diff --git a/efl/eo/filter_model.go b/efl/eo/filter_model.go
index 857bcab..04585fb 100644
--- a/efl/eo/filter_model.go
+++ b/efl/eo/filter_model.go
@@ -84,6 +84,9 @@ typedef Eo Efl_Ui_Widget;
// Declare the class_get function directly rather than including the full .eo.h
// header, which may reference types from other .eo files that are not included.
extern const Efl_Class *efl_filter_model_class_get(void);
+// Callback trampoline forward declarations.
+extern void egoCallbackFree(void *data);
+extern void egoCallback_EflFilterModel(void *data, Efl_Filter_Model * parent, Efl_Model * child);
*/
import "C"
@@ -135,3 +138,9 @@ func NewFilterModel(parent efl.Objecter, opts ...efl.Option) *FilterModel {
}
return wrapFilterModel(result)
}
+
+// FilterSet calls the efl_filter_model_filter_set method on FilterModel.
+func (o *FilterModel) FilterSet(filter func(unsafe.Pointer, unsafe.Pointer)) {
+ idfilter := efl.CallbackRegister(filter)
+ C.efl_filter_model_filter_set((*C.Eo)(o.Eo()), unsafe.Pointer(idfilter), C.EflFilterModel(C.egoCallback_EflFilterModel), C.Eina_Free_Cb(C.egoCallbackFree))
+}
diff --git a/efl/eo/thread.go b/efl/eo/thread.go
index de8be32..89d4d80 100644
--- a/efl/eo/thread.go
+++ b/efl/eo/thread.go
@@ -99,6 +99,10 @@ typedef Eo Efl_Ui_Widget;
// Declare the class_get function directly rather than including the full .eo.h
// header, which may reference types from other .eo files that are not included.
extern const Efl_Class *efl_thread_class_get(void);
+// Callback trampoline forward declarations.
+extern void egoCallbackFree(void *data);
+extern void egoCallback_EflThreadIOCall(void *data, const Efl_Event * event);
+extern void egoCallback_EflThreadIOCallSync(void *data, const Efl_Event * event);
// _ego_get_efl_threadio_indata_get wraps the getter, casting the return value through
// uintptr_t so that both pointer and integer returns become void *.
// This prevents C type conflicts when Eolian's type differs from the header.
@@ -310,6 +314,18 @@ func (o *Thread) SetCommandString(val string) {
C.efl_core_command_line_command_string_set((*C.Eo)(o.Eo()), cVal)
}
+// Call calls the efl_threadio_call method on Thread.
+func (o *Thread) Call(func_ func(unsafe.Pointer)) {
+ idfunc_ := efl.CallbackRegister(func_)
+ C.efl_threadio_call((*C.Eo)(o.Eo()), unsafe.Pointer(idfunc_), C.EflThreadIOCall(C.egoCallback_EflThreadIOCall), C.Eina_Free_Cb(C.egoCallbackFree))
+}
+
+// CallSync calls the efl_threadio_call_sync method on Thread.
+func (o *Thread) CallSync(func_ func(unsafe.Pointer)) unsafe.Pointer {
+ idfunc_ := efl.CallbackRegister(func_)
+ return unsafe.Pointer(C.efl_threadio_call_sync((*C.Eo)(o.Eo()), unsafe.Pointer(idfunc_), C.EflThreadIOCallSync(C.egoCallback_EflThreadIOCallSync), C.Eina_Free_Cb(C.egoCallbackFree)))
+}
+
// CommandAccess calls the efl_core_command_line_command_access method on Thread.
func (o *Thread) CommandAccess() unsafe.Pointer {
return unsafe.Pointer(C.efl_core_command_line_command_access((*C.Eo)(o.Eo())))
diff --git a/efl/eo/thread_io.go b/efl/eo/thread_io.go
index 22b6941..dab5165 100644
--- a/efl/eo/thread_io.go
+++ b/efl/eo/thread_io.go
@@ -84,6 +84,10 @@ typedef Eo Efl_Ui_Widget;
// Declare the class_get function directly rather than including the full .eo.h
// header, which may reference types from other .eo files that are not included.
extern const Efl_Class *efl_threadio_mixin_get(void);
+// Callback trampoline forward declarations.
+extern void egoCallbackFree(void *data);
+extern void egoCallback_EflThreadIOCall(void *data, const Efl_Event * event);
+extern void egoCallback_EflThreadIOCallSync(void *data, const Efl_Event * event);
// _ego_get_efl_threadio_indata_get wraps the getter, casting the return value through
// uintptr_t so that both pointer and integer returns become void *.
// This prevents C type conflicts when Eolian's type differs from the header.
@@ -154,3 +158,15 @@ func (o *ThreadIO) Outdata() unsafe.Pointer {
func (o *ThreadIO) SetOutdata(val unsafe.Pointer) {
C._ego_set_efl_threadio_outdata_set((*C.Eo)(o.Eo()), val)
}
+
+// Call calls the efl_threadio_call method on ThreadIO.
+func (o *ThreadIO) Call(func_ func(unsafe.Pointer)) {
+ idfunc_ := efl.CallbackRegister(func_)
+ C.efl_threadio_call((*C.Eo)(o.Eo()), unsafe.Pointer(idfunc_), C.EflThreadIOCall(C.egoCallback_EflThreadIOCall), C.Eina_Free_Cb(C.egoCallbackFree))
+}
+
+// CallSync calls the efl_threadio_call_sync method on ThreadIO.
+func (o *ThreadIO) CallSync(func_ func(unsafe.Pointer)) unsafe.Pointer {
+ idfunc_ := efl.CallbackRegister(func_)
+ return unsafe.Pointer(C.efl_threadio_call_sync((*C.Eo)(o.Eo()), unsafe.Pointer(idfunc_), C.EflThreadIOCallSync(C.egoCallback_EflThreadIOCallSync), C.Eina_Free_Cb(C.egoCallbackFree)))
+}
diff --git a/efl/layout/signal.go b/efl/layout/signal.go
index 49c0b19..5b86a20 100644
--- a/efl/layout/signal.go
+++ b/efl/layout/signal.go
@@ -84,6 +84,9 @@ typedef Eo Efl_Ui_Widget;
// Declare the class_get function directly rather than including the full .eo.h
// header, which may reference types from other .eo files that are not included.
extern const Efl_Class *efl_layout_signal_interface_get(void);
+// Callback trampoline forward declarations.
+extern void egoCallbackFree(void *data);
+extern void egoCallback_EflLayoutSignalCb(void *data, Efl_Layout_Signal * object, const char * emission, const char * source);
*/
import "C"
@@ -109,6 +112,26 @@ func wrapSignal(ptr unsafe.Pointer) *Signal {
return o
}
+// SignalCallbackAdd calls the efl_layout_signal_callback_add method on Signal.
+func (o *Signal) SignalCallbackAdd(emission string, source string, func_ func(unsafe.Pointer, string, string)) bool {
+ cemission := C.CString(emission)
+ defer C.free(unsafe.Pointer(cemission))
+ csource := C.CString(source)
+ defer C.free(unsafe.Pointer(csource))
+ idfunc_ := efl.CallbackRegister(func_)
+ return C.efl_layout_signal_callback_add((*C.Eo)(o.Eo()), cemission, csource, unsafe.Pointer(idfunc_), C.EflLayoutSignalCb(C.egoCallback_EflLayoutSignalCb), C.Eina_Free_Cb(C.egoCallbackFree)) != 0
+}
+
+// SignalCallbackDel calls the efl_layout_signal_callback_del method on Signal.
+func (o *Signal) SignalCallbackDel(emission string, source string, func_ func(unsafe.Pointer, string, string)) bool {
+ cemission := C.CString(emission)
+ defer C.free(unsafe.Pointer(cemission))
+ csource := C.CString(source)
+ defer C.free(unsafe.Pointer(csource))
+ idfunc_ := efl.CallbackRegister(func_)
+ return C.efl_layout_signal_callback_del((*C.Eo)(o.Eo()), cemission, csource, unsafe.Pointer(idfunc_), C.EflLayoutSignalCb(C.egoCallback_EflLayoutSignalCb), C.Eina_Free_Cb(C.egoCallbackFree)) != 0
+}
+
// SignalEmit calls the efl_layout_signal_emit method on Signal.
func (o *Signal) SignalEmit(emission string, source string) {
cemission := C.CString(emission)
diff --git a/efl/ui/image.go b/efl/ui/image.go
index 258bd07..6f15653 100644
--- a/efl/ui/image.go
+++ b/efl/ui/image.go
@@ -141,6 +141,9 @@ typedef Eo Efl_Ui_Widget;
// Declare the class_get function directly rather than including the full .eo.h
// header, which may reference types from other .eo files that are not included.
extern const Efl_Class *efl_ui_image_class_get(void);
+// Callback trampoline forward declarations.
+extern void egoCallbackFree(void *data);
+extern void egoCallback_EflLayoutSignalCb(void *data, Efl_Layout_Signal * object, const char * emission, const char * source);
// _ego_get_efl_gfx_image_scale_method_get wraps the getter, casting the return value through
// uintptr_t so that both pointer and integer returns become void *.
// This prevents C type conflicts when Eolian's type differs from the header.
@@ -1183,6 +1186,26 @@ func (o *Image) CalcForce() {
C.efl_layout_calc_force((*C.Eo)(o.Eo()))
}
+// SignalCallbackAdd calls the efl_layout_signal_callback_add method on Image.
+func (o *Image) SignalCallbackAdd(emission string, source string, func_ func(unsafe.Pointer, string, string)) bool {
+ cemission := C.CString(emission)
+ defer C.free(unsafe.Pointer(cemission))
+ csource := C.CString(source)
+ defer C.free(unsafe.Pointer(csource))
+ idfunc_ := efl.CallbackRegister(func_)
+ return C.efl_layout_signal_callback_add((*C.Eo)(o.Eo()), cemission, csource, unsafe.Pointer(idfunc_), C.EflLayoutSignalCb(C.egoCallback_EflLayoutSignalCb), C.Eina_Free_Cb(C.egoCallbackFree)) != 0
+}
+
+// SignalCallbackDel calls the efl_layout_signal_callback_del method on Image.
+func (o *Image) SignalCallbackDel(emission string, source string, func_ func(unsafe.Pointer, string, string)) bool {
+ cemission := C.CString(emission)
+ defer C.free(unsafe.Pointer(cemission))
+ csource := C.CString(source)
+ defer C.free(unsafe.Pointer(csource))
+ idfunc_ := efl.CallbackRegister(func_)
+ return C.efl_layout_signal_callback_del((*C.Eo)(o.Eo()), cemission, csource, unsafe.Pointer(idfunc_), C.EflLayoutSignalCb(C.egoCallback_EflLayoutSignalCb), C.Eina_Free_Cb(C.egoCallbackFree)) != 0
+}
+
// SignalEmit calls the efl_layout_signal_emit method on Image.
func (o *Image) SignalEmit(emission string, source string) {
cemission := C.CString(emission)
diff --git a/efl/ui/layout_base.go b/efl/ui/layout_base.go
index dce39e7..ada9ad8 100644
--- a/efl/ui/layout_base.go
+++ b/efl/ui/layout_base.go
@@ -107,6 +107,9 @@ static Eina_Bool _ego_iter_next(Eina_Iterator *iter, void **data) {
static void _ego_iter_free(Eina_Iterator *iter) {
eina_iterator_free(iter);
}
+// Callback trampoline forward declarations.
+extern void egoCallbackFree(void *data);
+extern void egoCallback_EflLayoutSignalCb(void *data, Efl_Layout_Signal * object, const char * emission, const char * source);
// _ego_get_struct_efl_layout_group_size_min_get wraps the getter, decomposing the returned
// struct into individual out-params for safe cgo consumption.
static void _ego_get_struct_efl_layout_group_size_min_get(const Eo *obj, int *out_w, int *out_h) {
@@ -279,6 +282,26 @@ func (o *LayoutBase) CalcForce() {
C.efl_layout_calc_force((*C.Eo)(o.Eo()))
}
+// SignalCallbackAdd calls the efl_layout_signal_callback_add method on LayoutBase.
+func (o *LayoutBase) SignalCallbackAdd(emission string, source string, func_ func(unsafe.Pointer, string, string)) bool {
+ cemission := C.CString(emission)
+ defer C.free(unsafe.Pointer(cemission))
+ csource := C.CString(source)
+ defer C.free(unsafe.Pointer(csource))
+ idfunc_ := efl.CallbackRegister(func_)
+ return C.efl_layout_signal_callback_add((*C.Eo)(o.Eo()), cemission, csource, unsafe.Pointer(idfunc_), C.EflLayoutSignalCb(C.egoCallback_EflLayoutSignalCb), C.Eina_Free_Cb(C.egoCallbackFree)) != 0
+}
+
+// SignalCallbackDel calls the efl_layout_signal_callback_del method on LayoutBase.
+func (o *LayoutBase) SignalCallbackDel(emission string, source string, func_ func(unsafe.Pointer, string, string)) bool {
+ cemission := C.CString(emission)
+ defer C.free(unsafe.Pointer(cemission))
+ csource := C.CString(source)
+ defer C.free(unsafe.Pointer(csource))
+ idfunc_ := efl.CallbackRegister(func_)
+ return C.efl_layout_signal_callback_del((*C.Eo)(o.Eo()), cemission, csource, unsafe.Pointer(idfunc_), C.EflLayoutSignalCb(C.egoCallback_EflLayoutSignalCb), C.Eina_Free_Cb(C.egoCallbackFree)) != 0
+}
+
// SignalEmit calls the efl_layout_signal_emit method on LayoutBase.
func (o *LayoutBase) SignalEmit(emission string, source string) {
cemission := C.CString(emission)
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.