diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/yasl/loop.h | 46 | ||||
| -rw-r--r-- | include/yasl/native.h | 44 | ||||
| -rw-r--r-- | include/yasl/timing.h | 23 | ||||
| -rw-r--r-- | include/yasl/yasl.h | 110 |
4 files changed, 120 insertions, 103 deletions
diff --git a/include/yasl/loop.h b/include/yasl/loop.h new file mode 100644 index 0000000..a65fa12 --- /dev/null +++ b/include/yasl/loop.h @@ -0,0 +1,46 @@ +#ifndef YASL_LOOP_H +#define YASL_LOOP_H + +#include "yasl/yasl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Optional event loop. Use the display's loop when adding application timers. + * A step waits at most timeout_ms: zero polls, a negative value waits indefinitely. + * Calls and callbacks use the loop's owning thread. */ +YASL_API struct yasl_loop *yasl_loop_create(void); +YASL_API void yasl_loop_destroy(struct yasl_loop *l); +YASL_API int yasl_loop_run(struct yasl_loop *l); +YASL_API int yasl_loop_step(struct yasl_loop *l, int timeout_ms); +YASL_API void yasl_loop_quit(struct yasl_loop *l); +YASL_API void yasl_loop_kick(struct yasl_loop *l); +YASL_API uint64_t yasl_loop_now_ns(void); +YASL_API struct yasl_loop *yasl_display_loop(struct yasl_display *d); +YASL_API int yasl_loop_add_fd(struct yasl_loop *l, int fd, short events, + int (*fn)(int fd, short revents, void *ud), void *ud); +YASL_API int yasl_loop_del_fd(struct yasl_loop *l, int id); +YASL_API int yasl_loop_set_fd_events(struct yasl_loop *l, int id, short events); + +/* Timers use nanoseconds. Return the next interval to repeat/reschedule, or zero + * to remove the timer. A zero ID indicates failure. Loop timers live until they + * stop, are deleted, or the loop is destroyed. Surface timers are also canceled + * when their surface is destroyed. */ +typedef uint32_t yasl_timer_id; +typedef uint64_t (*yasl_timer_cb)(void *ud, yasl_timer_id id, uint64_t interval_ns); + +#define YASL_MS_TO_NS(ms) ((uint64_t)(ms) * 1000000ull) + +YASL_API yasl_timer_id yasl_loop_add_timer(struct yasl_loop *l, uint64_t interval_ns, + yasl_timer_cb cb, void *ud); +YASL_API bool yasl_loop_del_timer(struct yasl_loop *l, yasl_timer_id id); +YASL_API yasl_timer_id yasl_surface_add_timer(struct yasl_surface *s, uint64_t interval_ns, + yasl_timer_cb cb, void *ud); +YASL_API bool yasl_surface_del_timer(struct yasl_surface *s, yasl_timer_id id); + +#ifdef __cplusplus +} +#endif + +#endif /* YASL_LOOP_H */ diff --git a/include/yasl/native.h b/include/yasl/native.h new file mode 100644 index 0000000..f7e3020 --- /dev/null +++ b/include/yasl/native.h @@ -0,0 +1,44 @@ +#ifndef YASL_NATIVE_H +#define YASL_NATIVE_H + +#include "yasl/yasl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Optional platform interoperability. All handles are borrowed and expire on + * object destruction. Check yasl_display_backend() before casting: + * + * display surface + * Wayland struct wl_display * struct wl_surface * + * X11 Display * Window (cast through uintptr_t) + * Cocoa NSApplication * NSWindow * (view: window.contentView) + */ +YASL_API void *yasl_display_get_native_handle(struct yasl_display *d); +YASL_API void *yasl_surface_get_native_handle(struct yasl_surface *s); + +/* Create a surface for application-managed native rendering. graphics_device + * must be non-NULL; currently an id<MTLDevice> on Cocoa, retained by the surface. + * Other backends return NULL with errno=ENOTSUP. CPU rendering uses the ordinary + * yasl_surface_create_toplevel() and requires no native device. */ +YASL_API struct yasl_surface *yasl_surface_create_native(struct yasl_display *d, + const struct yasl_surface_spec *spec, void *graphics_device); + +struct yasl_native_frame { + void *drawable; /* id<CAMetalDrawable> on Cocoa */ + bool transaction; /* CAMetalLayer.presentsWithTransaction */ +}; + +/* Query the current draw target's native drawable. Returns false for unsupported + * backends, stale targets, or outside the draw callback. The result expires on + * successful present, callback return, or surface destruction. Native renderers + * submit/present the drawable, then call yasl_surface_present() to record it. */ +YASL_API bool yasl_surface_get_native_frame(struct yasl_surface *s, + const struct yasl_framebuffer *target, struct yasl_native_frame *out); + +#ifdef __cplusplus +} +#endif + +#endif /* YASL_NATIVE_H */ diff --git a/include/yasl/timing.h b/include/yasl/timing.h index 85f305d..d443bf6 100644 --- a/include/yasl/timing.h +++ b/include/yasl/timing.h @@ -1,7 +1,6 @@ #ifndef YASL_TIMING_H #define YASL_TIMING_H -#include <stdbool.h> #include <stdint.h> #ifdef __cplusplus @@ -32,28 +31,6 @@ struct yasl_timing { struct yasl_resize_stats resize; }; -#define YASL_REFRESH_DEFAULT_NS 16666666.0 - -struct yasl_frame_clock { - uint64_t last_present_ns; - uint64_t resize_count; - uint64_t resize_sum_ns; - uint64_t resize_max_ns; - long resize_minflt; - uint64_t frame_time_ns; - double refresh_ns; - enum yasl_timing_source source; -}; - -uint64_t yasl_clock_extend_ms(uint32_t ms, uint64_t now_ns); -void yasl_clock_presented(struct yasl_frame_clock *c, uint64_t now, bool sample); -void yasl_clock_note_resize(struct yasl_frame_clock *c, uint64_t dt_ns); -void yasl_clock_resize_stats(const struct yasl_frame_clock *c, - struct yasl_resize_stats *out); -double yasl_clock_refresh_ms(const struct yasl_frame_clock *c); -uint64_t yasl_clock_next_present_ns(const struct yasl_frame_clock *c); -uint64_t yasl_clock_frame_timestamp_ns(struct yasl_frame_clock *c, uint64_t now); - #ifdef __cplusplus } #endif diff --git a/include/yasl/yasl.h b/include/yasl/yasl.h index cde7f34..30bf591 100644 --- a/include/yasl/yasl.h +++ b/include/yasl/yasl.h @@ -136,11 +136,6 @@ struct yasl_framebuffer { uint64_t generation; /* Opaque draw identity; preserve when copying target. */ uint32_t *pixels; struct yasl_vector2i size; - int buffer; - bool cleared; - struct yasl_damage_list *damage; - void *native_drawable; - bool transaction; }; struct yasl_frame { @@ -250,6 +245,25 @@ enum yasl_input_kind { YASL_INPUT_RESET, }; +struct yasl_focus_event { + bool focused; +}; + +struct yasl_text_event { + const char *text; + size_t len; +}; + +struct yasl_paste_event { + const char *text; + size_t len; +}; + +struct yasl_drop_files_event { + const char *files; + size_t len; +}; + struct yasl_input_event { struct yasl_surface *surface; enum yasl_input_kind kind; @@ -257,10 +271,10 @@ struct yasl_input_event { union { struct yasl_key_event key; struct yasl_mouse_event mouse; - struct { bool focused; } focus; - struct { const char *text; size_t len; } text; - struct { const char *text; size_t len; } paste; - struct { const char *files; size_t len; } drop_files; + struct yasl_focus_event focus; + struct yasl_text_event text; + struct yasl_paste_event paste; + struct yasl_drop_files_event drop_files; }; }; @@ -270,7 +284,6 @@ struct yasl_input_event { * popups before parents, and displays before their supplied loop. * Specs, strings, callback tables and drag listeners are copied during calls. * Userdata is borrowed until callbacks are removed or the object/drag ends. - * Native handles are borrowed and expire when their owning object is destroyed. * Surface destruction is allowed from its callbacks; display/loop destruction * during dispatch or callbacks is not supported. */ @@ -315,8 +328,9 @@ YASL_API struct yasl_display *yasl_display_open(struct yasl_loop *loop, YASL_API enum yasl_backend yasl_display_backend(const struct yasl_display *d); YASL_API void yasl_display_close(struct yasl_display *d); YASL_API uint32_t yasl_display_caps(const struct yasl_display *d); -YASL_API void yasl_display_dispatch(struct yasl_display *d); -YASL_API int yasl_display_dispatch_timeout(struct yasl_display *d, int timeout_ms); +/* Process events, waiting at most timeout_ms: zero polls, negative waits. + * Pending input or redraw work returns immediately. Returns -1 on failure. */ +YASL_API int yasl_display_dispatch(struct yasl_display *d, int timeout_ms); YASL_API void yasl_display_flush(struct yasl_display *d); YASL_API int yasl_display_modifiers(const struct yasl_display *d); /* Unsupported/invalid selections are no-ops, never clipboard aliases. */ @@ -336,10 +350,6 @@ struct yasl_surface_spec { struct yasl_vector2i size; bool fullscreen; bool tearing; - /* Optional native graphics device (retained on Cocoa). Requires - * YASL_CAP_NATIVE_GRAPHICS; other backends reject it with ENOTSUP. - * NULL selects CPU pixel presentation. */ - void *graphics_device; }; struct yasl_popup_spec { @@ -364,12 +374,10 @@ YASL_API void yasl_surface_set_callbacks(struct yasl_surface *s, YASL_API void yasl_surface_set_title(struct yasl_surface *s, const char *title); YASL_API void yasl_surface_schedule_redraw(struct yasl_surface *s); /* Present exactly the target supplied to the current draw callback, at most - * once. Targets and native drawables expire when that callback returns or - * the surface is destroyed. + * once. Targets expire when that callback returns or the surface is destroyed. * damage is required: n must be -1 or 0..YASL_DAMAGE_MAX. Rectangles must have * nonnegative extents; they are clipped to the target. Invalid input returns - * false without consuming the frame. Native renderers submit/present their - * drawable themselves, then call this function to record the submission. */ + * false without consuming the frame. See yasl/native.h for native rendering. */ YASL_API bool yasl_surface_present(struct yasl_surface *s, const struct yasl_framebuffer *fb, const struct yasl_damage_list *damage); /* Event payload strings are library-owned, NUL-terminated, and valid until @@ -377,8 +385,8 @@ YASL_API bool yasl_surface_present(struct yasl_surface *s, const struct yasl_fra * flush and unsuccessful polls do not invalidate them. Copy to keep longer. */ YASL_API bool yasl_surface_input_poll(struct yasl_surface *s, struct yasl_input_event *ev); -YASL_API struct yasl_vector2i yasl_surface_size(const struct yasl_surface *s); -YASL_API uint32_t yasl_surface_scale_120(const struct yasl_surface *s); +/* Current device-pixel size and scale, matching the configure callback. */ +YASL_API struct yasl_geometry yasl_surface_geometry(const struct yasl_surface *s); YASL_API uint32_t yasl_surface_state(const struct yasl_surface *s); /* Timing uses monotonic nanoseconds. Check source before treating timestamps * as presentation confirmation. refresh/next_present are estimates. Without @@ -403,64 +411,6 @@ YASL_API bool yasl_surface_show_window_menu(struct yasl_surface *s, struct yasl_ YASL_API bool yasl_surface_drag_carry(struct yasl_surface *s, struct yasl_vector2i offset); YASL_API bool yasl_surface_place_under_pointer(struct yasl_surface *s, struct yasl_vector2i at); -/* Native Interoperability Handles */ -YASL_API void *yasl_display_get_native_handle(struct yasl_display *d); -YASL_API void *yasl_surface_get_native_handle(struct yasl_surface *s); - -/* Integrated Event Loop */ -YASL_API struct yasl_loop *yasl_loop_create(void); -YASL_API void yasl_loop_destroy(struct yasl_loop *l); -YASL_API int yasl_loop_run(struct yasl_loop *l); -YASL_API int yasl_loop_step(struct yasl_loop *l, int timeout_ms); -YASL_API void yasl_loop_quit(struct yasl_loop *l); -YASL_API bool yasl_loop_is_running(const struct yasl_loop *l); -YASL_API void yasl_loop_kick(struct yasl_loop *l); -YASL_API uint64_t yasl_loop_now_ns(void); -YASL_API int yasl_loop_add_fd(struct yasl_loop *l, int fd, short events, - int (*fn)(int fd, short revents, void *ud), void *ud); -YASL_API int yasl_loop_del_fd(struct yasl_loop *l, int id); -YASL_API int yasl_loop_set_fd_events(struct yasl_loop *l, int id, short events); -YASL_API int yasl_loop_next_timeout_ms(const struct yasl_loop *l); - -/* Timers (SDL3-compatible callback model) - * Timer callbacks return the next interval in nanoseconds (or milliseconds for _ms), - * or 0 to disarm and remove the timer. Returning the same interval repeats the timer; - * returning a different non-zero interval reschedules it with the new interval. - * - * All timers fire on the display's opening thread during event dispatch/step. - * Surface timers are bound to a specific surface and are automatically canceled - * if that surface is destroyed. */ -typedef uint32_t yasl_timer_id; - -typedef uint64_t (*yasl_timer_cb)(void *ud, yasl_timer_id id, uint64_t interval_ns); -typedef uint32_t (*yasl_timer_ms_cb)(void *ud, yasl_timer_id id, uint32_t interval_ms); - -#define YASL_MS_TO_NS(ms) ((uint64_t)(ms) * 1000000ull) -#define YASL_NS_TO_MS(ns) ((uint64_t)(ns) / 1000000ull) - -/* Surface-bound Timers */ -YASL_API yasl_timer_id yasl_surface_add_timer(struct yasl_surface *s, uint64_t interval_ns, - yasl_timer_cb cb, void *ud); -YASL_API yasl_timer_id yasl_surface_add_timer_ms(struct yasl_surface *s, uint32_t interval_ms, - yasl_timer_ms_cb cb, void *ud); -YASL_API bool yasl_surface_del_timer(struct yasl_surface *s, yasl_timer_id id); - -/* Display-bound Timers */ -YASL_API yasl_timer_id yasl_display_add_timer(struct yasl_display *d, uint64_t interval_ns, - yasl_timer_cb cb, void *ud); -YASL_API yasl_timer_id yasl_display_add_timer_ms(struct yasl_display *d, uint32_t interval_ms, - yasl_timer_ms_cb cb, void *ud); -YASL_API bool yasl_display_del_timer(struct yasl_display *d, yasl_timer_id id); -YASL_API struct yasl_loop *yasl_display_loop(struct yasl_display *d); -YASL_API struct yasl_loop *yasl_surface_loop(struct yasl_surface *s); - -/* Loop Timers */ -YASL_API yasl_timer_id yasl_loop_add_timer(struct yasl_loop *l, uint64_t interval_ns, - yasl_timer_cb cb, void *ud); -YASL_API yasl_timer_id yasl_loop_add_timer_ms(struct yasl_loop *l, uint32_t interval_ms, - yasl_timer_ms_cb cb, void *ud); -YASL_API bool yasl_loop_del_timer(struct yasl_loop *l, yasl_timer_id id); - #ifdef __cplusplus } #endif |
