/* * el_native_target.h — Native widget declarations for el programs targeting * native desktop UI (AppKit / GTK4 / Win32). * * This header is designed to be included AFTER el_runtime.h without conflict: * - It does NOT redefine el_to_float, el_from_float, or any el_runtime.h * static inlines. * - It does NOT redeclare __println, __print, or other functions whose * return types differ between el_seed.h and el_runtime.h. * - It adds: native widget builtins + float arithmetic helpers that the * current el_runtime.h omits but elc still emits calls to. * * Usage: * Inject via -include at compile time, OR #include it after el_runtime.h. * * clang -DEL_TARGET_MACOS -include el_native_target.h -c my_app.c ... */ #pragma once #include #include /* el_val_t must already be defined by el_runtime.h or el_seed.h. */ #ifndef EL_VAL_T_DEFINED typedef int64_t el_val_t; #endif /* ── Float arithmetic helpers ─────────────────────────────────────────────── * elc emits calls to float_div / float_mul etc. for Float-typed expressions. * These were in el_runtime.c through v1.0.0-20260501 but are missing from the * current el_runtime.h. Redeclared here as static inline to avoid link deps. * Only defined if not already declared (old runtimes that still have them). */ #ifndef EL_FLOAT_OPS_DEFINED #define EL_FLOAT_OPS_DEFINED /* el_to_float / el_from_float — bit-cast between el_val_t and double. * Defined as static inline in both el_runtime.h and el_seed.h; we do NOT * redefine them here. We rely on one of those headers being included first. */ static inline el_val_t float_div(el_val_t a, el_val_t b) { union { double d; int64_t i; } ua, ub, ur; ua.i = a; ub.i = b; ur.d = (ub.d != 0.0) ? (ua.d / ub.d) : 0.0; return ur.i; } static inline el_val_t float_mul(el_val_t a, el_val_t b) { union { double d; int64_t i; } ua, ub, ur; ua.i = a; ub.i = b; ur.d = ua.d * ub.d; return ur.i; } static inline el_val_t float_add(el_val_t a, el_val_t b) { union { double d; int64_t i; } ua, ub, ur; ua.i = a; ub.i = b; ur.d = ua.d + ub.d; return ur.i; } static inline el_val_t float_sub(el_val_t a, el_val_t b) { union { double d; int64_t i; } ua, ub, ur; ua.i = a; ub.i = b; ur.d = ua.d - ub.d; return ur.i; } static inline el_val_t float_lt(el_val_t a, el_val_t b) { union { double d; int64_t i; } ua, ub; ua.i = a; ub.i = b; return (el_val_t)(ua.d < ub.d); } static inline el_val_t float_gt(el_val_t a, el_val_t b) { union { double d; int64_t i; } ua, ub; ua.i = a; ub.i = b; return (el_val_t)(ua.d > ub.d); } static inline el_val_t float_lte(el_val_t a, el_val_t b) { union { double d; int64_t i; } ua, ub; ua.i = a; ub.i = b; return (el_val_t)(ua.d <= ub.d); } static inline el_val_t float_gte(el_val_t a, el_val_t b) { union { double d; int64_t i; } ua, ub; ua.i = a; ub.i = b; return (el_val_t)(ua.d >= ub.d); } static inline el_val_t float_eq(el_val_t a, el_val_t b) { union { double d; int64_t i; } ua, ub; ua.i = a; ub.i = b; return (el_val_t)(ua.d == ub.d); } #endif /* EL_FLOAT_OPS_DEFINED */ /* ── Native widget system (macOS AppKit) ──────────────────────────────────── * Available when compiled with -DEL_TARGET_MACOS and linked with el_appkit.m. * Widget handles are opaque int64_t slot indices; -1 = invalid. */ #ifdef EL_TARGET_MACOS /* Initialisation */ void __native_init(void); void __native_run_loop(void); /* Window */ el_val_t __window_create(el_val_t title, el_val_t width, el_val_t height, el_val_t min_width, el_val_t min_height); void __window_show(el_val_t handle); void __window_set_title(el_val_t handle, el_val_t title); /* Layout containers */ el_val_t __vstack_create(el_val_t spacing); el_val_t __hstack_create(el_val_t spacing); el_val_t __zstack_create(void); el_val_t __scroll_create(void); /* Widgets */ el_val_t __label_create(el_val_t text); el_val_t __button_create(el_val_t label); el_val_t __text_field_create(el_val_t placeholder); el_val_t __text_area_create(el_val_t placeholder); el_val_t __image_create(el_val_t path_or_name); /* Widget properties */ void __widget_set_text(el_val_t handle, el_val_t text); el_val_t __widget_get_text(el_val_t handle); void __widget_set_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a); void __widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a); void __widget_set_font(el_val_t handle, el_val_t family, el_val_t size, el_val_t bold); void __widget_set_padding(el_val_t handle, el_val_t top, el_val_t right, el_val_t bottom, el_val_t left); void __widget_set_width(el_val_t handle, el_val_t width); void __widget_set_height(el_val_t handle, el_val_t height); void __widget_set_flex(el_val_t handle, el_val_t flex); void __widget_set_corner_radius(el_val_t handle, el_val_t radius); void __widget_set_disabled(el_val_t handle, el_val_t disabled); void __widget_set_hidden(el_val_t handle, el_val_t hidden); /* Layout / tree */ void __widget_add_child(el_val_t parent, el_val_t child); void __widget_remove_child(el_val_t parent, el_val_t child); void __widget_destroy(el_val_t handle); /* Events */ void __widget_on_click(el_val_t handle, el_val_t fn_name); void __widget_on_change(el_val_t handle, el_val_t fn_name); void __widget_on_submit(el_val_t handle, el_val_t fn_name); /* Manifest reader */ el_val_t __manifest_read(el_val_t path); #endif /* EL_TARGET_MACOS */ /* ── Native widget system (Linux GTK4) ────────────────────────────────────── * Available when compiled with -DEL_TARGET_LINUX and linked with el_gtk4.c. * Widget handles are opaque int64_t slot indices; -1 = invalid. * All functions have the same signatures as EL_TARGET_MACOS above. */ #ifdef EL_TARGET_LINUX /* Initialisation */ void __native_init(void); void __native_run_loop(void); /* Window */ el_val_t __window_create(el_val_t title, el_val_t width, el_val_t height, el_val_t min_width, el_val_t min_height); void __window_show(el_val_t handle); void __window_set_title(el_val_t handle, el_val_t title); /* Layout containers */ el_val_t __vstack_create(el_val_t spacing); el_val_t __hstack_create(el_val_t spacing); el_val_t __zstack_create(void); el_val_t __scroll_create(void); /* Widgets */ el_val_t __label_create(el_val_t text); el_val_t __button_create(el_val_t label); el_val_t __text_field_create(el_val_t placeholder); el_val_t __text_area_create(el_val_t placeholder); el_val_t __image_create(el_val_t path_or_name); /* Widget properties */ void __widget_set_text(el_val_t handle, el_val_t text); el_val_t __widget_get_text(el_val_t handle); void __widget_set_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a); void __widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a); void __widget_set_font(el_val_t handle, el_val_t family, el_val_t size, el_val_t bold); void __widget_set_padding(el_val_t handle, el_val_t top, el_val_t right, el_val_t bottom, el_val_t left); void __widget_set_width(el_val_t handle, el_val_t width); void __widget_set_height(el_val_t handle, el_val_t height); void __widget_set_flex(el_val_t handle, el_val_t flex); void __widget_set_corner_radius(el_val_t handle, el_val_t radius); void __widget_set_disabled(el_val_t handle, el_val_t disabled); void __widget_set_hidden(el_val_t handle, el_val_t hidden); /* Layout / tree */ void __widget_add_child(el_val_t parent, el_val_t child); void __widget_remove_child(el_val_t parent, el_val_t child); void __widget_destroy(el_val_t handle); /* Events */ void __widget_on_click(el_val_t handle, el_val_t fn_name); void __widget_on_change(el_val_t handle, el_val_t fn_name); void __widget_on_submit(el_val_t handle, el_val_t fn_name); /* Manifest reader — same JSON output as EL_TARGET_MACOS */ el_val_t __manifest_read(el_val_t path); #endif /* EL_TARGET_LINUX */ /* ── Native widget system (Windows Win32) ─────────────────────────────────── * Available when compiled with -DEL_TARGET_WIN32 and linked with el_win32.c. * Widget handles are opaque int64_t slot indices; -1 = invalid. * Link: el_win32.obj comctl32.lib user32.lib gdi32.lib */ #ifdef EL_TARGET_WIN32 /* Initialisation */ void __native_init(void); void __native_run_loop(void); /* Window */ el_val_t __window_create(el_val_t title, el_val_t width, el_val_t height, el_val_t min_width, el_val_t min_height); void __window_show(el_val_t handle); void __window_set_title(el_val_t handle, el_val_t title); /* Layout containers */ el_val_t __vstack_create(el_val_t spacing); el_val_t __hstack_create(el_val_t spacing); el_val_t __zstack_create(void); el_val_t __scroll_create(void); /* Widgets */ el_val_t __label_create(el_val_t text); el_val_t __button_create(el_val_t label); el_val_t __text_field_create(el_val_t placeholder); el_val_t __text_area_create(el_val_t placeholder); el_val_t __image_create(el_val_t path_or_name); /* Widget properties */ void __widget_set_text(el_val_t handle, el_val_t text); el_val_t __widget_get_text(el_val_t handle); void __widget_set_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a); void __widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a); void __widget_set_font(el_val_t handle, el_val_t family, el_val_t size, el_val_t bold); void __widget_set_padding(el_val_t handle, el_val_t top, el_val_t right, el_val_t bottom, el_val_t left); void __widget_set_width(el_val_t handle, el_val_t width); void __widget_set_height(el_val_t handle, el_val_t height); void __widget_set_flex(el_val_t handle, el_val_t flex); void __widget_set_corner_radius(el_val_t handle, el_val_t radius); void __widget_set_disabled(el_val_t handle, el_val_t disabled); void __widget_set_hidden(el_val_t handle, el_val_t hidden); /* Layout / tree */ void __widget_add_child(el_val_t parent, el_val_t child); void __widget_remove_child(el_val_t parent, el_val_t child); void __widget_destroy(el_val_t handle); /* Events */ void __widget_on_click(el_val_t handle, el_val_t fn_name); void __widget_on_change(el_val_t handle, el_val_t fn_name); void __widget_on_submit(el_val_t handle, el_val_t fn_name); /* Manifest reader */ el_val_t __manifest_read(el_val_t path); #endif /* EL_TARGET_WIN32 */ /* ── Native widget system (iOS UIKit) ─────────────────────────────────────── * Available when compiled with -DEL_TARGET_IOS and linked with el_uikit.m. * Widget handles are opaque int64_t slot indices; -1 = invalid. * * iOS lifecycle note: UIApplicationMain never returns. The el program must * store its UI-build logic in a void(*)(void) function pointer, assign it to * el_main_entry_fn, then call __native_run_loop. ElAppDelegate invokes * el_main_entry_fn inside didFinishLaunchingWithOptions. * Call el_uikit_set_args(argc, argv) from main() before __native_run_loop. */ #ifdef EL_TARGET_IOS /* Lifecycle entry-function hook — set before calling __native_run_loop. */ extern void (*el_main_entry_fn)(void); /* Forward argc/argv from main() to UIApplicationMain. */ void el_uikit_set_args(int argc, char** argv); /* Initialisation */ void __native_init(void); void __native_run_loop(void); /* Window */ el_val_t __window_create(el_val_t title, el_val_t width, el_val_t height, el_val_t min_width, el_val_t min_height); void __window_show(el_val_t handle); void __window_set_title(el_val_t handle, el_val_t title); /* Layout containers */ el_val_t __vstack_create(el_val_t spacing); el_val_t __hstack_create(el_val_t spacing); el_val_t __zstack_create(void); el_val_t __scroll_create(void); /* Widgets */ el_val_t __label_create(el_val_t text); el_val_t __button_create(el_val_t label); el_val_t __text_field_create(el_val_t placeholder); el_val_t __text_area_create(el_val_t placeholder); el_val_t __image_create(el_val_t path_or_name); /* Widget properties */ void __widget_set_text(el_val_t handle, el_val_t text); el_val_t __widget_get_text(el_val_t handle); void __widget_set_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a); void __widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a); void __widget_set_font(el_val_t handle, el_val_t family, el_val_t size, el_val_t bold); void __widget_set_padding(el_val_t handle, el_val_t top, el_val_t right, el_val_t bottom, el_val_t left); void __widget_set_width(el_val_t handle, el_val_t width); void __widget_set_height(el_val_t handle, el_val_t height); void __widget_set_flex(el_val_t handle, el_val_t flex); void __widget_set_corner_radius(el_val_t handle, el_val_t radius); void __widget_set_disabled(el_val_t handle, el_val_t disabled); void __widget_set_hidden(el_val_t handle, el_val_t hidden); /* Layout / tree */ void __widget_add_child(el_val_t parent, el_val_t child); void __widget_remove_child(el_val_t parent, el_val_t child); void __widget_destroy(el_val_t handle); /* Events */ void __widget_on_click(el_val_t handle, el_val_t fn_name); void __widget_on_change(el_val_t handle, el_val_t fn_name); void __widget_on_submit(el_val_t handle, el_val_t fn_name); /* Manifest reader */ el_val_t __manifest_read(el_val_t path); #endif /* EL_TARGET_IOS */ /* ── Native widget system (Android JNI) ───────────────────────────────────── * Available when compiled with -DEL_TARGET_ANDROID and linked with * libelruntime.so (which includes el_android.c compiled by the NDK build). * Widget handles are opaque int64_t slot indices; -1 = invalid. * * Java companion: ElBridge.java (package com.neuron.el) must be compiled into * the APK. The Activity must call ElBridge.init(this) before any widget ops. * * Link flags (in Android.mk or CMakeLists.txt): * -landroid -llog -ldl */ #ifdef EL_TARGET_ANDROID /* Initialisation */ void __native_init(void); void __native_run_loop(void); /* no-op on Android */ /* Window */ el_val_t __window_create(el_val_t title, el_val_t width, el_val_t height, el_val_t min_width, el_val_t min_height); void __window_show(el_val_t handle); void __window_set_title(el_val_t handle, el_val_t title); /* Layout containers */ el_val_t __vstack_create(el_val_t spacing); el_val_t __hstack_create(el_val_t spacing); el_val_t __zstack_create(void); el_val_t __scroll_create(void); /* Widgets */ el_val_t __label_create(el_val_t text); el_val_t __button_create(el_val_t label); el_val_t __text_field_create(el_val_t placeholder); el_val_t __text_area_create(el_val_t placeholder); el_val_t __image_create(el_val_t path_or_name); /* Widget properties */ void __widget_set_text(el_val_t handle, el_val_t text); el_val_t __widget_get_text(el_val_t handle); void __widget_set_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a); void __widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a); void __widget_set_font(el_val_t handle, el_val_t family, el_val_t size, el_val_t bold); void __widget_set_padding(el_val_t handle, el_val_t top, el_val_t right, el_val_t bottom, el_val_t left); void __widget_set_width(el_val_t handle, el_val_t width); void __widget_set_height(el_val_t handle, el_val_t height); void __widget_set_flex(el_val_t handle, el_val_t flex); void __widget_set_corner_radius(el_val_t handle, el_val_t radius); void __widget_set_disabled(el_val_t handle, el_val_t disabled); void __widget_set_hidden(el_val_t handle, el_val_t hidden); /* Layout / tree */ void __widget_add_child(el_val_t parent, el_val_t child); void __widget_remove_child(el_val_t parent, el_val_t child); void __widget_destroy(el_val_t handle); /* Events */ void __widget_on_click(el_val_t handle, el_val_t fn_name); void __widget_on_change(el_val_t handle, el_val_t fn_name); void __widget_on_submit(el_val_t handle, el_val_t fn_name); /* Manifest reader */ el_val_t __manifest_read(el_val_t path); #endif /* EL_TARGET_ANDROID */ /* ── Native widget system (LVGL v9 — embedded / microcontroller) ───────────── * Available when compiled with -DEL_TARGET_LVGL and linked with el_lvgl.c * and the LVGL library (lvgl.a or lvgl source tree). * * Target platforms: ESP32, STM32, industrial panels. Any system with 256KB+ * RAM and an LVGL-compatible display driver. No OS required. * * Widget handles are opaque int64_t slot indices; -1 = invalid. * * Bare-metal / no dynamic linker: * Compile with -DEL_LVGL_NO_DLSYM and provide: * el_val_t el_lvgl_dispatch(const char *fn, el_val_t a, el_val_t b); * * Compile: * gcc -DEL_TARGET_LVGL -I./lvgl el_lvgl.c -c -o el_lvgl.o * # Then link with lvgl.a. */ #ifdef EL_TARGET_LVGL /* Initialisation */ void __native_init(void); void __native_run_loop(void); /* Window */ el_val_t __window_create(el_val_t title, el_val_t width, el_val_t height, el_val_t min_width, el_val_t min_height); void __window_show(el_val_t handle); void __window_set_title(el_val_t handle, el_val_t title); /* Layout containers */ el_val_t __vstack_create(el_val_t spacing); el_val_t __hstack_create(el_val_t spacing); el_val_t __zstack_create(void); el_val_t __scroll_create(void); /* Widgets */ el_val_t __label_create(el_val_t text); el_val_t __button_create(el_val_t label); el_val_t __text_field_create(el_val_t placeholder); el_val_t __text_area_create(el_val_t placeholder); el_val_t __image_create(el_val_t path_or_name); /* Widget properties */ void __widget_set_text(el_val_t handle, el_val_t text); el_val_t __widget_get_text(el_val_t handle); void __widget_set_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a); void __widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a); void __widget_set_font(el_val_t handle, el_val_t family, el_val_t size, el_val_t bold); void __widget_set_padding(el_val_t handle, el_val_t top, el_val_t right, el_val_t bottom, el_val_t left); void __widget_set_width(el_val_t handle, el_val_t width); void __widget_set_height(el_val_t handle, el_val_t height); void __widget_set_flex(el_val_t handle, el_val_t flex); void __widget_set_corner_radius(el_val_t handle, el_val_t radius); void __widget_set_disabled(el_val_t handle, el_val_t disabled); void __widget_set_hidden(el_val_t handle, el_val_t hidden); /* Layout / tree */ void __widget_add_child(el_val_t parent, el_val_t child); void __widget_remove_child(el_val_t parent, el_val_t child); void __widget_destroy(el_val_t handle); /* Events */ void __widget_on_click(el_val_t handle, el_val_t fn_name); void __widget_on_change(el_val_t handle, el_val_t fn_name); void __widget_on_submit(el_val_t handle, el_val_t fn_name); /* Manifest reader — same JSON output as all other native targets */ el_val_t __manifest_read(el_val_t path); #endif /* EL_TARGET_LVGL */ /* ── Native widget system (SDL2 — embedded / Pi) ──────────────────────────── * Available when compiled with -DEL_TARGET_SDL2 and linked with el_sdl2.c. * Widget handles are opaque int64_t slot indices; -1 = invalid. * * Target: Raspberry Pi Zero, embedded Linux, any system with a framebuffer * and SDL2 available. No GTK, no desktop environment required. * * Compile: * gcc -DEL_TARGET_SDL2 $(sdl2-config --cflags) -c el_sdl2.c -o el_sdl2.o * Link: * $(sdl2-config --libs) -lSDL2_ttf -lSDL2_image -ldl */ #ifdef EL_TARGET_SDL2 /* Initialisation */ void __native_init(void); void __native_run_loop(void); /* Window */ el_val_t __window_create(el_val_t title, el_val_t width, el_val_t height, el_val_t min_width, el_val_t min_height); void __window_show(el_val_t handle); void __window_set_title(el_val_t handle, el_val_t title); /* Layout containers */ el_val_t __vstack_create(el_val_t spacing); el_val_t __hstack_create(el_val_t spacing); el_val_t __zstack_create(void); el_val_t __scroll_create(void); /* Widgets */ el_val_t __label_create(el_val_t text); el_val_t __button_create(el_val_t label); el_val_t __text_field_create(el_val_t placeholder); el_val_t __text_area_create(el_val_t placeholder); el_val_t __image_create(el_val_t path_or_name); /* Widget properties */ void __widget_set_text(el_val_t handle, el_val_t text); el_val_t __widget_get_text(el_val_t handle); void __widget_set_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a); void __widget_set_bg_color(el_val_t handle, el_val_t r, el_val_t g, el_val_t b, el_val_t a); void __widget_set_font(el_val_t handle, el_val_t family, el_val_t size, el_val_t bold); void __widget_set_padding(el_val_t handle, el_val_t top, el_val_t right, el_val_t bottom, el_val_t left); void __widget_set_width(el_val_t handle, el_val_t width); void __widget_set_height(el_val_t handle, el_val_t height); void __widget_set_flex(el_val_t handle, el_val_t flex); void __widget_set_corner_radius(el_val_t handle, el_val_t radius); void __widget_set_disabled(el_val_t handle, el_val_t disabled); void __widget_set_hidden(el_val_t handle, el_val_t hidden); /* Layout / tree */ void __widget_add_child(el_val_t parent, el_val_t child); void __widget_remove_child(el_val_t parent, el_val_t child); void __widget_destroy(el_val_t handle); /* Events */ void __widget_on_click(el_val_t handle, el_val_t fn_name); void __widget_on_change(el_val_t handle, el_val_t fn_name); void __widget_on_submit(el_val_t handle, el_val_t fn_name); /* Manifest reader */ el_val_t __manifest_read(el_val_t path); #endif /* EL_TARGET_SDL2 */