summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/yasl/loop.h46
-rw-r--r--include/yasl/native.h44
-rw-r--r--include/yasl/timing.h23
-rw-r--r--include/yasl/yasl.h110
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