summaryrefslogtreecommitdiff
path: root/include/yasl
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-13 23:41:31 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-13 23:41:31 +0300
commit76073fe5fad8799e5850805f2f090af2cb62c741 (patch)
tree9658019babe4760a3634bdab4da0731a10e42e68 /include/yasl
parentdd1775a9927922c14f8679ccbc4d3ca8d5917e20 (diff)
Simplify the public event and CPU API
Applications now need far less ceremony: hello.c is a 20-line loop that handles REFRESH, CLOSE and QUIT and draws into the surface's own pixels. - Fold GEOMETRY, STATE and FOCUS into one WINDOW event carrying size, scale and state; unchanged values send nothing. - Guarantee REFRESH once a window has a size and after every resize, never at size zero. - Merge DROP_HOVER into DROP with over/leave/data actions and give drag and drop actions enums. - Keep event strings valid until the next wait and drop yasl_event_release; empty or failed waits report NONE. - Replace copy-in presentation with a lent pixel buffer: yasl_cpu_pixels and yasl_cpu_present. - Remove yasl_poll_event, yasl_cpu_read_pixels, unused event fields and comments that restated names. - Wayland: resize floating windows in request_size instead of reporting it unsupported, and stop marking new GPU surfaces as Vulkan so yasl_vulkan_create_surface no longer fails with NATIVE_WINDOW_IN_USE. Also includes the in-progress public API refactor that was uncommitted in the tree (removal of the app/loop layer, new surface, GL and Vulkan entry points). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'include/yasl')
-rw-r--r--include/yasl/app.h147
-rw-r--r--include/yasl/cpu.h15
-rw-r--r--include/yasl/desktop.h116
-rw-r--r--include/yasl/gl.h27
-rw-r--r--include/yasl/keycodes.h271
-rw-r--r--include/yasl/loop.h214
-rw-r--r--include/yasl/metal.h20
-rw-r--r--include/yasl/native.h90
-rw-r--r--include/yasl/native/cocoa.h48
-rw-r--r--include/yasl/native/wayland.h37
-rw-r--r--include/yasl/native/x11.h36
-rw-r--r--include/yasl/timing.h56
-rw-r--r--include/yasl/vulkan.h19
-rw-r--r--include/yasl/yasl.h1203
14 files changed, 377 insertions, 1922 deletions
diff --git a/include/yasl/app.h b/include/yasl/app.h
deleted file mode 100644
index 78e62c4..0000000
--- a/include/yasl/app.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/**
- * @file
- * Unified application runner, event pipeline, and presentation context.
- *
- * Implements the inverted lifecycle architecture for modern cross-platform
- * applications (games, IDEs, and desktop tools). Instead of managing manual
- * dispatch/poll/flush pumps, the application provides event and frame callbacks
- * to yasl_run(), which drives platform runloops, display pacing, and live resizing.
- */
-#ifndef YASL_APP_H
-#define YASL_APP_H
-
-#include "yasl/yasl.h"
-#include "yasl/loop.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Application callback return status. */
-typedef enum yasl_app_result {
- YASL_APP_CONTINUE = 0, /**< Continue running the application. */
- YASL_APP_QUIT, /**< Request graceful termination of yasl_run(). */
- YASL_APP_ERROR, /**< Request orderly cleanup and a failing run result. */
-} yasl_app_result;
-
-/** Migration adapter; prefer yasl_frame_present() from yasl.h. */
-YASL_API bool yasl_frame_present_cpu(struct yasl_frame *frame,
- const struct yasl_rect2i *dirty_rects, int count);
-
-/**
- * Safely post a custom user event to the main event loop from ANY thread.
- * Wakes the display loop and delivers YASL_EVENT_USER to the event callback.
- * @param d Display.
- * @param s Optional target surface, or NULL.
- * @param code Application-defined message code (yasl_user_event.code).
- * @param payload Arbitrary pointer passed through to the event.
- * @param size Optional payload size.
- * @return true if queued; false if memory failed or d is not run by yasl_run().
- * Migration adapter: keep s alive through the call, and stop producers before
- * shutdown. Prefer yasl_display_post() with a captured ID and release callback
- * in either loop style; legacy payloads have no cancellation cleanup.
- */
-YASL_API bool yasl_post_event(struct yasl_display *d, struct yasl_surface *s,
- uint32_t code, void *payload, size_t size);
-
-/**
- * Watch an open file descriptor or socket for poll-style readiness in the main loop.
- * @param d Display.
- * @param fd Open file descriptor (e.g. LSP stdout pipe or socket).
- * @param poll_events Poll bitmask (e.g. POLLIN, POLLOUT).
- * @param cb Readiness callback run on the main thread.
- * @param ud Userdata.
- * @return Positive watch ID, or -1 on failure.
- */
-YASL_API int yasl_app_watch_fd(struct yasl_display *d, int fd, short poll_events,
- int (*cb)(int fd, short revents, void *ud), void *ud);
-
-/**
- * Unregister a file watch.
- * @param d Display.
- * @param watch_id Watch ID returned by yasl_app_watch_fd().
- */
-YASL_API void yasl_app_unwatch_fd(struct yasl_display *d, int watch_id);
-
-/**
- * Schedule a repeating or one-shot timer on the display's event loop.
- * @param d Display.
- * @param interval_ns Delay in monotonic nanoseconds.
- * @param cb Callback returning next interval in nanoseconds, or 0 to stop.
- * @param ud Userdata.
- * @return Positive timer ID, or 0 on failure.
- */
-YASL_API yasl_timer_id yasl_app_add_timer(struct yasl_display *d, uint64_t interval_ns,
- yasl_timer_cb cb, void *ud);
-
-/**
- * Cancel an active timer.
- * @param d Display.
- * @param id Timer ID returned by yasl_app_add_timer().
- */
-YASL_API void yasl_app_del_timer(struct yasl_display *d, yasl_timer_id id);
-
-/** Application callbacks descriptor passed to yasl_run(). */
-struct yasl_app_desc {
- /** Application identifier, e.g. "org.example.app". */
- const char *app_id;
- /** Desired backend; YASL_BACKEND_AUTO chooses native with fallback. */
- enum yasl_backend backend;
- /** User data passed to all callbacks. */
- void *userdata;
- /**
- * Optional toplevel created before init(), with its first frame requested.
- * Borrowed for the call; spec cbs and ud are ignored as for any runner window.
- * yasl_run() returns an error without calling init() if creation fails.
- */
- const struct yasl_window_spec *window;
-
- /**
- * Optional; called once after display and event machinery initialization.
- * Use this to create further windows and initialize application resources.
- * Return YASL_APP_CONTINUE, YASL_APP_QUIT, or YASL_APP_ERROR.
- */
- enum yasl_app_result (*init)(void *ud, struct yasl_display *d);
-
- /**
- * Unified event handler for input, window and user events, in display-wide enqueue order.
- * Event payloads and borrowed strings are valid for the duration of the callback.
- * INPUT_RESET has no payload and requires clearing held application input.
- * Return YASL_APP_CONTINUE, YASL_APP_QUIT, or YASL_APP_ERROR. Optional; without it, a
- * WINDOW_CLOSE request on any window stops yasl_run().
- */
- enum yasl_app_result (*event)(void *ud, const struct yasl_event *ev);
-
- /**
- * Invoked when a surface needs to present a frame.
- * Synchronized automatically with display pacing and live window resizing.
- */
- void (*frame)(void *ud, struct yasl_surface *s, struct yasl_frame *frame);
-
- /**
- * Called right before the display is closed and yasl_run() exits.
- * Destroy remaining surfaces and release application resources here.
- */
- void (*quit)(void *ud, struct yasl_display *d);
-};
-
-/** Request orderly exit from any display-thread callback; ERROR returns failure. */
-YASL_API void yasl_app_exit(struct yasl_display *d, enum yasl_app_result result);
-/** Borrow the optional desc.window surface during init or later; NULL if absent/destroyed. */
-YASL_API struct yasl_surface *yasl_app_window(struct yasl_display *d);
-
-/**
- * Run the application with the inverted lifecycle runner.
- * Handles the display event loop, live-resizing, pacing, and cleanup.
- * @param desc Application callbacks and options.
- * @return 0 on orderly exit, or non-zero on error.
- * Display quit notifications stop the runner; connection loss and dispatch
- * failures return an error after application cleanup.
- */
-YASL_API int yasl_run(const struct yasl_app_desc *desc);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* YASL_APP_H */
diff --git a/include/yasl/cpu.h b/include/yasl/cpu.h
new file mode 100644
index 0000000..d18f91f
--- /dev/null
+++ b/include/yasl/cpu.h
@@ -0,0 +1,15 @@
+/** @file CPU surfaces: draw into the lent pixel buffer, then present it. */
+#ifndef YASL_CPU_H
+#define YASL_CPU_H
+#include "yasl/yasl.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+/** width*height premultiplied 0xAARRGGBB pixels, rows tightly packed. Contents
+ * persist; a resize keeps the overlap and zeroes the rest. Valid until the next wait. */
+YASL_API uint32_t *yasl_cpu_pixels(yasl_surface *surface, int *width, int *height);
+YASL_API bool yasl_cpu_present(yasl_surface *surface);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/yasl/desktop.h b/include/yasl/desktop.h
index 3e72a50..2c2379e 100644
--- a/include/yasl/desktop.h
+++ b/include/yasl/desktop.h
@@ -1,113 +1,21 @@
-/**
- * @file
- * Desktop services next to windowing: opening URIs, notifications, the bell,
- * appearance preferences, and process paths.
- *
- * Display and surface functions use the display's opening thread (the main
- * thread on Cocoa). Path and locale functions may be called from any thread.
- * On Linux, notifications and appearance use the D-Bus session bus when YASL
- * is built with libdbus-1; without it they report unsupported.
- *
- * Functions that fill a buffer return the full string length in bytes,
- * excluding the NUL, or zero on failure. A result less than cap means out
- * holds the NUL-terminated string. Otherwise out is unchanged; call again with
- * a buffer of at least the result plus one.
- */
+/** @file Optional desktop services; window operations use the owning thread. */
#ifndef YASL_DESKTOP_H
#define YASL_DESKTOP_H
-
#include "yasl/yasl.h"
-
#ifdef __cplusplus
extern "C" {
#endif
-
-/** Appearance preference flags returned by yasl_display_appearance(). */
-enum yasl_appearance : uint32_t {
- YASL_APPEARANCE_DARK = 1 << 0, /**< The user prefers dark colors. */
- YASL_APPEARANCE_LIGHT = 1 << 1, /**< The user prefers light colors. */
- YASL_APPEARANCE_HIGH_CONTRAST = 1 << 2, /**< The user asks for higher contrast. */
-};
-
-/**
- * Open a URI with the user's default handler.
- * @param d Display, or NULL.
- * @param uri NUL-terminated absolute URI with a scheme, such as https: or file:.
- * @return true if the request was handed to the system; false for NULL
- * arguments, a missing scheme, or a failed launch.
- * YASL checks only the URI syntax. The application decides which schemes and
- * hosts it trusts. Success does not confirm that a handler opened the URI.
- * Linux runs xdg-open from PATH in a new session, with default signal
- * dispositions, an empty signal mask, stdin on /dev/null, and no descriptors
- * above stderr. It forks a short-lived helper first, which raises SIGCHLD;
- * YASL reaps it unless the application's reaper does. Cocoa uses NSWorkspace.
- */
-YASL_API bool yasl_display_open_uri(struct yasl_display *d, const char *uri);
-/**
- * Show a desktop notification.
- * @param d Display, or NULL.
- * @param title NUL-terminated UTF-8 summary.
- * @param body NUL-terminated UTF-8 body, or NULL for none.
- * @return true if the request was sent; false for NULL arguments or when no
- * notification service is available.
- * Linux sends org.freedesktop.Notifications.Notify with the display's app_id
- * as the application name and desktop-entry hint. Cocoa uses the user
- * notification center, which needs an app bundle with a bundle identifier,
- * and asks for permission on first use. Success does not confirm that the
- * notification was shown.
- */
-YASL_API bool yasl_display_notify(struct yasl_display *d, const char *title, const char *body);
-/**
- * Read the user's appearance preferences.
- * @param d Display, or NULL.
- * @return A yasl_appearance bitmask, or zero for NULL, no preference, or no
- * way to read it.
- * Linux reads color-scheme and contrast from the XDG Settings portal, which
- * waits briefly for a reply, then falls back to the GTK_THEME variable. Cocoa
- * reads the effective appearance and the increase-contrast setting. The
- * result is not cached and no change notification is sent; query again when
- * the window is focused.
- */
-YASL_API uint32_t yasl_display_appearance(struct yasl_display *d);
-/**
- * Ring the system bell for a surface.
- * @param s Surface, or NULL.
- * @return true if the request was sent; false for NULL or when unsupported.
- * The system decides whether the bell is audible, visual, or muted. Wayland
- * needs the xdg-system-bell protocol; X11 uses the XKB bell for the window
- * and Cocoa uses NSBeep.
- */
-YASL_API bool yasl_surface_bell(struct yasl_surface *s);
-/**
- * Get the absolute path of the running executable, with symbolic links resolved.
- * @param out Output buffer, or NULL when cap is zero.
- * @param cap Size of out in bytes.
- * @return Path length, or zero on failure. See the buffer rule in this file.
- */
-YASL_API size_t yasl_executable_path(char *out, size_t cap);
-/**
- * Get the resource directory of the app bundle that contains the executable.
- * @param out Output buffer, or NULL when cap is zero.
- * @param cap Size of out in bytes.
- * @return Path length, or zero when the executable is not in an app bundle.
- * Only Cocoa has app bundles; other platforms return zero.
- */
-YASL_API size_t yasl_resource_dir(char *out, size_t cap);
-/**
- * Get the user's preferred locale as a POSIX locale name, such as "en_US.UTF-8".
- * @param out Output buffer, or NULL when cap is zero.
- * @param cap Size of out in bytes.
- * @return Name length, or zero on failure.
- * Linux returns the first nonempty LC_ALL, LC_CTYPE, or LANG, and "C.UTF-8"
- * when none is set. Cocoa builds the name from the current locale's language
- * and region with a ".UTF-8" codeset, because apps started from Finder have no
- * locale variables. Use the result to set LANG for child processes; YASL does
- * not change the process locale.
- */
-YASL_API size_t yasl_default_locale(char *out, size_t cap);
-
+enum yasl_appearance { YASL_APPEARANCE_DARK=1u, YASL_APPEARANCE_LIGHT=2u, YASL_APPEARANCE_HIGH_CONTRAST=4u };
+YASL_API bool yasl_open_uri(const char *uri);
+YASL_API bool yasl_notify(const char *title, const char *body);
+YASL_API unsigned yasl_appearance(void);
+YASL_API bool yasl_surface_bell(yasl_surface *surface);
+/** Full byte length excluding NUL, zero on failure. Buffer unchanged unless cap
+ * exceeds returned length. NULL/zero queries size. These three are thread-safe. */
+YASL_API size_t yasl_executable_path(char *out, size_t capacity);
+YASL_API size_t yasl_resource_dir(char *out, size_t capacity);
+YASL_API size_t yasl_default_locale(char *out, size_t capacity);
#ifdef __cplusplus
}
#endif
-
-#endif /* YASL_DESKTOP_H */
+#endif
diff --git a/include/yasl/gl.h b/include/yasl/gl.h
new file mode 100644
index 0000000..66a245a
--- /dev/null
+++ b/include/yasl/gl.h
@@ -0,0 +1,27 @@
+/** @file Optional OpenGL/OpenGL ES contexts. Attribute lists are per-call. */
+#ifndef YASL_GL_H
+#define YASL_GL_H
+#include "yasl/yasl.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+enum yasl_gl_attribute { YASL_GL_END, YASL_GL_MAJOR, YASL_GL_MINOR, YASL_GL_PROFILE, YASL_GL_DEBUG,
+ YASL_GL_FORWARD_COMPAT, YASL_GL_RED_BITS, YASL_GL_GREEN_BITS, YASL_GL_BLUE_BITS, YASL_GL_ALPHA_BITS,
+ YASL_GL_DEPTH_BITS, YASL_GL_STENCIL_BITS, YASL_GL_SAMPLES, YASL_GL_SRGB, YASL_GL_API };
+enum yasl_gl_profile { YASL_GL_ANY, YASL_GL_CORE, YASL_GL_COMPATIBILITY };
+enum yasl_gl_api { YASL_GL_OPENGL, YASL_GL_OPENGL_ES };
+typedef void (*yasl_gl_proc)(void);
+/** key/value pairs terminated by END, NULL defaults to GL3.2 core RGBA8 D24 S8.
+ * share is a live GL surface or NULL. CPU flag is invalid. Context is owned by
+ * the returned surface. Detach it from all rendering threads before destruction. */
+YASL_API yasl_surface *yasl_gl_surface_create(const char *title, int width, int height,
+ unsigned flags, const int *attributes, yasl_surface *share);
+/** May run on a rendering thread. NULL detaches this thread's current context. */
+YASL_API bool yasl_gl_make_current(yasl_surface *surface);
+YASL_API yasl_gl_proc yasl_gl_get_proc_address(const char *name);
+YASL_API bool yasl_gl_swap_interval(yasl_surface *surface, int interval);
+YASL_API bool yasl_gl_swap_buffers(yasl_surface *surface);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/yasl/keycodes.h b/include/yasl/keycodes.h
index d34aeae..afa3eed 100644
--- a/include/yasl/keycodes.h
+++ b/include/yasl/keycodes.h
@@ -1,149 +1,142 @@
-/**
- * @file
- * Portable physical keyboard identities, included by yasl/yasl.h.
- * Letter/punctuation names describe positions on a US keyboard, regardless of
- * active layout or modifiers. Use YASL_EVENT_TEXT for text and codepoint/shifted
- * in yasl_key_event for layout labels. These values are neither Unicode nor
- * native scancodes; do not derive a character from a key enumerator.
- */
+/** @file Physical keys, named by their position on a US keyboard whatever the
+ * layout. Use TEXT events for typed text and key.codepoint for layout labels. */
#ifndef YASL_KEYCODES_H
#define YASL_KEYCODES_H
#include <stdint.h>
-/** Physical keys. Unrecognized native keys report YASL_KEY_UNKNOWN. */
enum yasl_key : uint32_t {
YASL_KEY_UNKNOWN = 0x000, /**< No portable identity; native_code may still identify the key. */
- YASL_KEY_SPACE = 0x020, /**< Space. */
- YASL_KEY_APOSTROPHE = 0x027, /**< Apostrophe. */
- YASL_KEY_COMMA = 0x02c, /**< Comma. */
- YASL_KEY_MINUS = 0x02d, /**< Minus. */
- YASL_KEY_PERIOD = 0x02e, /**< Period. */
- YASL_KEY_SLASH = 0x02f, /**< Slash. */
- YASL_KEY_0 = 0x030, /**< Physical 0 key. */
- YASL_KEY_1 = 0x031, /**< Physical 1 key. */
- YASL_KEY_2 = 0x032, /**< Physical 2 key. */
- YASL_KEY_3 = 0x033, /**< Physical 3 key. */
- YASL_KEY_4 = 0x034, /**< Physical 4 key. */
- YASL_KEY_5 = 0x035, /**< Physical 5 key. */
- YASL_KEY_6 = 0x036, /**< Physical 6 key. */
- YASL_KEY_7 = 0x037, /**< Physical 7 key. */
- YASL_KEY_8 = 0x038, /**< Physical 8 key. */
- YASL_KEY_9 = 0x039, /**< Physical 9 key. */
- YASL_KEY_SEMICOLON = 0x03b, /**< Semicolon. */
- YASL_KEY_EQUAL = 0x03d, /**< Equal. */
- YASL_KEY_A = 0x041, /**< Physical US A position; independent of layout and modifiers. */
- YASL_KEY_B = 0x042, /**< Physical US B position; independent of layout and modifiers. */
- YASL_KEY_C = 0x043, /**< Physical US C position; independent of layout and modifiers. */
- YASL_KEY_D = 0x044, /**< Physical US D position; independent of layout and modifiers. */
- YASL_KEY_E = 0x045, /**< Physical US E position; independent of layout and modifiers. */
- YASL_KEY_F = 0x046, /**< Physical US F position; independent of layout and modifiers. */
- YASL_KEY_G = 0x047, /**< Physical US G position; independent of layout and modifiers. */
- YASL_KEY_H = 0x048, /**< Physical US H position; independent of layout and modifiers. */
- YASL_KEY_I = 0x049, /**< Physical US I position; independent of layout and modifiers. */
- YASL_KEY_J = 0x04a, /**< Physical US J position; independent of layout and modifiers. */
- YASL_KEY_K = 0x04b, /**< Physical US K position; independent of layout and modifiers. */
- YASL_KEY_L = 0x04c, /**< Physical US L position; independent of layout and modifiers. */
- YASL_KEY_M = 0x04d, /**< Physical US M position; independent of layout and modifiers. */
- YASL_KEY_N = 0x04e, /**< Physical US N position; independent of layout and modifiers. */
- YASL_KEY_O = 0x04f, /**< Physical US O position; independent of layout and modifiers. */
- YASL_KEY_P = 0x050, /**< Physical US P position; independent of layout and modifiers. */
- YASL_KEY_Q = 0x051, /**< Physical US Q position; independent of layout and modifiers. */
- YASL_KEY_R = 0x052, /**< Physical US R position; independent of layout and modifiers. */
- YASL_KEY_S = 0x053, /**< Physical US S position; independent of layout and modifiers. */
- YASL_KEY_T = 0x054, /**< Physical US T position; independent of layout and modifiers. */
- YASL_KEY_U = 0x055, /**< Physical US U position; independent of layout and modifiers. */
- YASL_KEY_V = 0x056, /**< Physical US V position; independent of layout and modifiers. */
- YASL_KEY_W = 0x057, /**< Physical US W position; independent of layout and modifiers. */
- YASL_KEY_X = 0x058, /**< Physical US X position; independent of layout and modifiers. */
- YASL_KEY_Y = 0x059, /**< Physical US Y position; independent of layout and modifiers. */
- YASL_KEY_Z = 0x05a, /**< Physical US Z position; independent of layout and modifiers. */
- YASL_KEY_LEFT_BRACKET = 0x05b, /**< Left Bracket. */
- YASL_KEY_BACKSLASH = 0x05c, /**< Backslash. */
- YASL_KEY_RIGHT_BRACKET = 0x05d, /**< Right Bracket. */
- YASL_KEY_GRAVE = 0x060, /**< Grave. */
- YASL_KEY_ESCAPE = 0x100, /**< Escape. */
- YASL_KEY_ENTER = 0x101, /**< Enter. */
- YASL_KEY_TAB = 0x102, /**< Tab. */
- YASL_KEY_BACKSPACE = 0x103, /**< Backspace. */
- YASL_KEY_INSERT = 0x104, /**< Insert. */
- YASL_KEY_DELETE = 0x105, /**< Delete. */
- YASL_KEY_RIGHT = 0x106, /**< Right. */
- YASL_KEY_LEFT = 0x107, /**< Left. */
- YASL_KEY_DOWN = 0x108, /**< Down. */
- YASL_KEY_UP = 0x109, /**< Up. */
- YASL_KEY_PAGE_UP = 0x10a, /**< Page Up. */
- YASL_KEY_PAGE_DOWN = 0x10b, /**< Page Down. */
- YASL_KEY_HOME = 0x10c, /**< Home. */
- YASL_KEY_END = 0x10d, /**< End. */
- YASL_KEY_CAPS_LOCK = 0x10e, /**< Caps Lock. */
- YASL_KEY_SCROLL_LOCK = 0x10f, /**< Scroll Lock. */
- YASL_KEY_NUM_LOCK = 0x110, /**< Num Lock. */
- YASL_KEY_PRINT_SCREEN = 0x111, /**< Print Screen. */
- YASL_KEY_PAUSE = 0x112, /**< Pause. */
- YASL_KEY_ISO_BACKSLASH = 0x113, /**< Iso Backslash. */
- YASL_KEY_YEN = 0x114, /**< Yen. */
- YASL_KEY_RO = 0x115, /**< Ro. */
- YASL_KEY_KANA = 0x116, /**< Kana. */
- YASL_KEY_EISU = 0x117, /**< Eisu. */
- YASL_KEY_CONVERT = 0x118, /**< Convert. */
- YASL_KEY_NONCONVERT = 0x119, /**< Nonconvert. */
- YASL_KEY_F1 = 0x120, /**< Function key F1. */
- YASL_KEY_F2 = 0x121, /**< Function key F2. */
- YASL_KEY_F3 = 0x122, /**< Function key F3. */
- YASL_KEY_F4 = 0x123, /**< Function key F4. */
- YASL_KEY_F5 = 0x124, /**< Function key F5. */
- YASL_KEY_F6 = 0x125, /**< Function key F6. */
- YASL_KEY_F7 = 0x126, /**< Function key F7. */
- YASL_KEY_F8 = 0x127, /**< Function key F8. */
- YASL_KEY_F9 = 0x128, /**< Function key F9. */
- YASL_KEY_F10 = 0x129, /**< Function key F10. */
- YASL_KEY_F11 = 0x12a, /**< Function key F11. */
- YASL_KEY_F12 = 0x12b, /**< Function key F12. */
- YASL_KEY_F13 = 0x12c, /**< Function key F13. */
- YASL_KEY_F14 = 0x12d, /**< Function key F14. */
- YASL_KEY_F15 = 0x12e, /**< Function key F15. */
- YASL_KEY_F16 = 0x12f, /**< Function key F16. */
- YASL_KEY_F17 = 0x130, /**< Function key F17. */
- YASL_KEY_F18 = 0x131, /**< Function key F18. */
- YASL_KEY_F19 = 0x132, /**< Function key F19. */
- YASL_KEY_F20 = 0x133, /**< Function key F20. */
- YASL_KEY_F21 = 0x134, /**< Function key F21. */
- YASL_KEY_F22 = 0x135, /**< Function key F22. */
- YASL_KEY_F23 = 0x136, /**< Function key F23. */
- YASL_KEY_F24 = 0x137, /**< Function key F24. */
- YASL_KEY_F25 = 0x138, /**< Function key F25. */
- YASL_KEY_KP_0 = 0x140, /**< Numeric keypad 0. */
- YASL_KEY_KP_1 = 0x141, /**< Numeric keypad 1. */
- YASL_KEY_KP_2 = 0x142, /**< Numeric keypad 2. */
- YASL_KEY_KP_3 = 0x143, /**< Numeric keypad 3. */
- YASL_KEY_KP_4 = 0x144, /**< Numeric keypad 4. */
- YASL_KEY_KP_5 = 0x145, /**< Numeric keypad 5. */
- YASL_KEY_KP_6 = 0x146, /**< Numeric keypad 6. */
- YASL_KEY_KP_7 = 0x147, /**< Numeric keypad 7. */
- YASL_KEY_KP_8 = 0x148, /**< Numeric keypad 8. */
- YASL_KEY_KP_9 = 0x149, /**< Numeric keypad 9. */
- YASL_KEY_KP_DECIMAL = 0x14a, /**< Numeric keypad decimal. */
- YASL_KEY_KP_DIVIDE = 0x14b, /**< Numeric keypad divide. */
- YASL_KEY_KP_MULTIPLY = 0x14c, /**< Numeric keypad multiply. */
- YASL_KEY_KP_SUBTRACT = 0x14d, /**< Numeric keypad subtract. */
- YASL_KEY_KP_ADD = 0x14e, /**< Numeric keypad add. */
- YASL_KEY_KP_ENTER = 0x14f, /**< Numeric keypad enter. */
- YASL_KEY_KP_EQUAL = 0x150, /**< Numeric keypad equal. */
- YASL_KEY_KP_COMMA = 0x151, /**< Numeric keypad comma. */
- YASL_KEY_KP_CLEAR = 0x152, /**< Numeric keypad clear. */
- YASL_KEY_LEFT_SHIFT = 0x160, /**< Left Shift. */
- YASL_KEY_LEFT_CONTROL = 0x161, /**< Left Control. */
- YASL_KEY_LEFT_ALT = 0x162, /**< Left Alt. */
- YASL_KEY_LEFT_SUPER = 0x163, /**< Left Super. */
- YASL_KEY_RIGHT_SHIFT = 0x164, /**< Right Shift. */
- YASL_KEY_RIGHT_CONTROL = 0x165, /**< Right Control. */
- YASL_KEY_RIGHT_ALT = 0x166, /**< Right Alt. */
- YASL_KEY_RIGHT_SUPER = 0x167, /**< Right Super. */
- YASL_KEY_MENU = 0x168, /**< Menu. */
- YASL_KEY_VOLUME_UP = 0x169, /**< Volume Up. */
- YASL_KEY_VOLUME_DOWN = 0x16a, /**< Volume Down. */
- YASL_KEY_MUTE = 0x16b, /**< Mute. */
+ YASL_KEY_SPACE = 0x020,
+ YASL_KEY_APOSTROPHE = 0x027,
+ YASL_KEY_COMMA = 0x02c,
+ YASL_KEY_MINUS = 0x02d,
+ YASL_KEY_PERIOD = 0x02e,
+ YASL_KEY_SLASH = 0x02f,
+ YASL_KEY_0 = 0x030,
+ YASL_KEY_1 = 0x031,
+ YASL_KEY_2 = 0x032,
+ YASL_KEY_3 = 0x033,
+ YASL_KEY_4 = 0x034,
+ YASL_KEY_5 = 0x035,
+ YASL_KEY_6 = 0x036,
+ YASL_KEY_7 = 0x037,
+ YASL_KEY_8 = 0x038,
+ YASL_KEY_9 = 0x039,
+ YASL_KEY_SEMICOLON = 0x03b,
+ YASL_KEY_EQUAL = 0x03d,
+ YASL_KEY_A = 0x041,
+ YASL_KEY_B = 0x042,
+ YASL_KEY_C = 0x043,
+ YASL_KEY_D = 0x044,
+ YASL_KEY_E = 0x045,
+ YASL_KEY_F = 0x046,
+ YASL_KEY_G = 0x047,
+ YASL_KEY_H = 0x048,
+ YASL_KEY_I = 0x049,
+ YASL_KEY_J = 0x04a,
+ YASL_KEY_K = 0x04b,
+ YASL_KEY_L = 0x04c,
+ YASL_KEY_M = 0x04d,
+ YASL_KEY_N = 0x04e,
+ YASL_KEY_O = 0x04f,
+ YASL_KEY_P = 0x050,
+ YASL_KEY_Q = 0x051,
+ YASL_KEY_R = 0x052,
+ YASL_KEY_S = 0x053,
+ YASL_KEY_T = 0x054,
+ YASL_KEY_U = 0x055,
+ YASL_KEY_V = 0x056,
+ YASL_KEY_W = 0x057,
+ YASL_KEY_X = 0x058,
+ YASL_KEY_Y = 0x059,
+ YASL_KEY_Z = 0x05a,
+ YASL_KEY_LEFT_BRACKET = 0x05b,
+ YASL_KEY_BACKSLASH = 0x05c,
+ YASL_KEY_RIGHT_BRACKET = 0x05d,
+ YASL_KEY_GRAVE = 0x060,
+ YASL_KEY_ESCAPE = 0x100,
+ YASL_KEY_ENTER = 0x101,
+ YASL_KEY_TAB = 0x102,
+ YASL_KEY_BACKSPACE = 0x103,
+ YASL_KEY_INSERT = 0x104,
+ YASL_KEY_DELETE = 0x105,
+ YASL_KEY_RIGHT = 0x106,
+ YASL_KEY_LEFT = 0x107,
+ YASL_KEY_DOWN = 0x108,
+ YASL_KEY_UP = 0x109,
+ YASL_KEY_PAGE_UP = 0x10a,
+ YASL_KEY_PAGE_DOWN = 0x10b,
+ YASL_KEY_HOME = 0x10c,
+ YASL_KEY_END = 0x10d,
+ YASL_KEY_CAPS_LOCK = 0x10e,
+ YASL_KEY_SCROLL_LOCK = 0x10f,
+ YASL_KEY_NUM_LOCK = 0x110,
+ YASL_KEY_PRINT_SCREEN = 0x111,
+ YASL_KEY_PAUSE = 0x112,
+ YASL_KEY_ISO_BACKSLASH = 0x113,
+ YASL_KEY_YEN = 0x114,
+ YASL_KEY_RO = 0x115,
+ YASL_KEY_KANA = 0x116,
+ YASL_KEY_EISU = 0x117,
+ YASL_KEY_CONVERT = 0x118,
+ YASL_KEY_NONCONVERT = 0x119,
+ YASL_KEY_F1 = 0x120,
+ YASL_KEY_F2 = 0x121,
+ YASL_KEY_F3 = 0x122,
+ YASL_KEY_F4 = 0x123,
+ YASL_KEY_F5 = 0x124,
+ YASL_KEY_F6 = 0x125,
+ YASL_KEY_F7 = 0x126,
+ YASL_KEY_F8 = 0x127,
+ YASL_KEY_F9 = 0x128,
+ YASL_KEY_F10 = 0x129,
+ YASL_KEY_F11 = 0x12a,
+ YASL_KEY_F12 = 0x12b,
+ YASL_KEY_F13 = 0x12c,
+ YASL_KEY_F14 = 0x12d,
+ YASL_KEY_F15 = 0x12e,
+ YASL_KEY_F16 = 0x12f,
+ YASL_KEY_F17 = 0x130,
+ YASL_KEY_F18 = 0x131,
+ YASL_KEY_F19 = 0x132,
+ YASL_KEY_F20 = 0x133,
+ YASL_KEY_F21 = 0x134,
+ YASL_KEY_F22 = 0x135,
+ YASL_KEY_F23 = 0x136,
+ YASL_KEY_F24 = 0x137,
+ YASL_KEY_F25 = 0x138,
+ YASL_KEY_KP_0 = 0x140,
+ YASL_KEY_KP_1 = 0x141,
+ YASL_KEY_KP_2 = 0x142,
+ YASL_KEY_KP_3 = 0x143,
+ YASL_KEY_KP_4 = 0x144,
+ YASL_KEY_KP_5 = 0x145,
+ YASL_KEY_KP_6 = 0x146,
+ YASL_KEY_KP_7 = 0x147,
+ YASL_KEY_KP_8 = 0x148,
+ YASL_KEY_KP_9 = 0x149,
+ YASL_KEY_KP_DECIMAL = 0x14a,
+ YASL_KEY_KP_DIVIDE = 0x14b,
+ YASL_KEY_KP_MULTIPLY = 0x14c,
+ YASL_KEY_KP_SUBTRACT = 0x14d,
+ YASL_KEY_KP_ADD = 0x14e,
+ YASL_KEY_KP_ENTER = 0x14f,
+ YASL_KEY_KP_EQUAL = 0x150,
+ YASL_KEY_KP_COMMA = 0x151,
+ YASL_KEY_KP_CLEAR = 0x152,
+ YASL_KEY_LEFT_SHIFT = 0x160,
+ YASL_KEY_LEFT_CONTROL = 0x161,
+ YASL_KEY_LEFT_ALT = 0x162,
+ YASL_KEY_LEFT_SUPER = 0x163,
+ YASL_KEY_RIGHT_SHIFT = 0x164,
+ YASL_KEY_RIGHT_CONTROL = 0x165,
+ YASL_KEY_RIGHT_ALT = 0x166,
+ YASL_KEY_RIGHT_SUPER = 0x167,
+ YASL_KEY_MENU = 0x168,
+ YASL_KEY_VOLUME_UP = 0x169,
+ YASL_KEY_VOLUME_DOWN = 0x16a,
+ YASL_KEY_MUTE = 0x16b,
};
#endif /* YASL_KEYCODES_H */
diff --git a/include/yasl/loop.h b/include/yasl/loop.h
deleted file mode 100644
index a8e9974..0000000
--- a/include/yasl/loop.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/**
- * @file
- * Optional event loop, file watches, and timers.
- *
- * Use the loop's owning thread for all calls and callbacks, except
- * yasl_loop_now_ns(), yasl_loop_kick(), and yasl_loop_post(), which any thread
- * may call. A display borrows a supplied loop. For window applications,
- * drive yasl_display_dispatch(), drain input, then yasl_display_flush(); the
- * standalone loop_run() function does not replace this cycle. Timer intervals are
- * nanoseconds; timeout_ms arguments are milliseconds. Do not recursively step/run
- * or destroy a loop from a callback.
- */
-#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. */
-/**
- * Create an owned standalone file-descriptor and timer loop.
- * @return A loop to destroy with yasl_loop_destroy(), or NULL on allocation failure.
- * Use on one owning thread. Passing it to yasl_display_open() only lends it to
- * the display; the caller retains ownership.
- */
-YASL_API struct yasl_loop *yasl_loop_create(void);
-/**
- * Release a loop, its watches, its timers, and its signal watch.
- * @param l Loop, or NULL for no action.
- * Close displays borrowing this loop first. Must not run during a loop callback
- * or an active step/run. Watched file descriptors are not closed. Posted
- * functions that have not run are dropped; no thread may still post or kick.
- */
-YASL_API void yasl_loop_destroy(struct yasl_loop *l);
-/**
- * Step a standalone loop until yasl_loop_quit() is called.
- * @param l Loop.
- * @return Zero after quit, or -1 on failure.
- * For a window application, use a dispatch, input-poll, flush cycle instead;
- * loop_run alone does not perform that full cycle on every backend.
- */
-YASL_API int yasl_loop_run(struct yasl_loop *l);
-/**
- * Wait for file-descriptor readiness or a timer deadline and run callbacks.
- * @param l Loop.
- * @param timeout_ms Maximum wait: zero polls, negative waits indefinitely.
- * @return Number of callbacks handled, or -1 on failure.
- * Timer deadlines shorten the wait. Callbacks can add/delete sources, including
- * themselves. Do not recursively step/run this loop.
- */
-YASL_API int yasl_loop_step(struct yasl_loop *l, int timeout_ms);
-/**
- * Ask the currently running yasl_loop_run() to return after this step.
- * @param l Loop, or NULL for no action.
- * Call on the owning thread, usually from a callback.
- */
-YASL_API void yasl_loop_quit(struct yasl_loop *l);
-/**
- * Wake a loop that is waiting, without running any callback.
- * @param l Loop, or NULL for no action.
- * May be called from any thread and from a signal handler. The loop must stay
- * alive until the call returns. A waiting yasl_loop_step(), yasl_loop_run(), or
- * yasl_display_dispatch() on this loop returns early; a loop that is not
- * waiting returns early from its next wait instead. Kicks coalesce. This does
- * not schedule a redraw or enqueue an event; use yasl_loop_post() to run code
- * on the owning thread.
- */
-YASL_API void yasl_loop_kick(struct yasl_loop *l);
-/**
- * Run a function on the loop's owning thread.
- * @param l Loop.
- * @param fn Required function, called once with ud during a later step.
- * @param ud Borrowed userdata until fn runs.
- * @return true if queued; false for NULL arguments, a loop without a wake
- * pipe, or allocation failure.
- * May be called from any thread, but not from a signal handler. Wakes the loop
- * like yasl_loop_kick(). Functions run in posting order, during a
- * yasl_loop_step() or display dispatch on the owning thread. They may post
- * again; a function posted while posts are running waits for a later step.
- * Stop posting before yasl_loop_destroy(), which drops functions that have
- * not run.
- */
-YASL_API bool yasl_loop_post(struct yasl_loop *l, void (*fn)(void *ud), void *ud);
-/**
- * Deliver POSIX signals to a callback on the loop's owning thread.
- * @param l Loop.
- * @param signals Signal numbers to watch; the array is read during the call.
- * @param n Number of entries, at least one.
- * @param cb Required callback, given ud and one signal number per delivery.
- * @param ud Borrowed userdata until the watch is removed.
- * @return true if every signal is watched; false with errno set and no
- * dispositions changed. EINVAL means a NULL or invalid argument, including
- * SIGKILL and SIGSTOP. EBUSY means another loop watches one of the signals.
- * Replaces this loop's previous watch, if any. Installs one process-wide
- * handler per signal with SA_RESTART and an empty handler mask, and saves the
- * previous action. The handler only records the signal and wakes the loop,
- * so it may run on any thread. YASL does not change any thread's signal mask:
- * a signal blocked in every thread stays pending and is not delivered. Caught
- * signals reset to their default action across exec, so spawned programs
- * do not inherit the handler. Repeated deliveries of one signal before the
- * callback runs coalesce into one callback. SIGCHLD reports stopped and
- * continued children as well as exits. Callbacks run during yasl_loop_step()
- * or display dispatch, and may remove the watch.
- */
-YASL_API bool yasl_loop_watch_signals(struct yasl_loop *l, const int *signals, int n,
- void (*cb)(void *ud, int signo), void *ud);
-/**
- * Stop watching signals and restore their previous actions.
- * @param l Loop, or NULL for no action.
- * Does nothing if the loop watches no signals. Signals that arrived but have
- * not reached the callback are dropped. yasl_loop_destroy() also unwatches.
- */
-YASL_API void yasl_loop_unwatch_signals(struct yasl_loop *l);
-/**
- * Read the monotonic clock used by YASL timers and timing results.
- * @return Nanoseconds from CLOCK_MONOTONIC, unrelated to wall-clock time.
- * May be called from any thread.
- */
-YASL_API uint64_t yasl_loop_now_ns(void);
-/**
- * Get the loop used for a display's file watches and application timers.
- * @param d Display, or NULL.
- * @return Borrowed loop, or NULL. Do not destroy a display-owned loop yourself.
- */
-YASL_API struct yasl_loop *yasl_display_loop(struct yasl_display *d);
-/**
- * Register a borrowed file descriptor for poll-style readiness.
- * @param l Loop.
- * @param fd Open file descriptor; it remains owned by the caller.
- * @param events Bitmask from <poll.h>, for example POLLIN or POLLOUT.
- * @param fn Callback receiving poll revents (including errors/hangup); return value is ignored.
- * @param ud Borrowed userdata until watch removal or loop destruction.
- * @return Positive watch ID, or -1 on failure.
- * Delete the watch before closing fd. The callback must consume readiness or
- * change/remove its watch to avoid repeated immediate wakeups.
- */
-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);
-/**
- * Remove a file watch without closing its descriptor.
- * @param l Loop.
- * @param id Watch ID returned by yasl_loop_add_fd().
- * @return Zero if removed, or -1 for an invalid/missing watch.
- */
-YASL_API int yasl_loop_del_fd(struct yasl_loop *l, int id);
-/**
- * Replace a watch's poll event mask.
- * @param l Loop.
- * @param id Watch ID.
- * @param events New <poll.h> mask; zero disables requested readiness (errors may still arrive).
- * @return Zero if updated, or -1 for an invalid/missing watch.
- */
-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. */
-/** Timer identity scoped to its loop. Zero is invalid; do not reuse a retired ID. */
-typedef uint32_t yasl_timer_id;
-/** Timer callback. interval_ns is the last scheduled delay; return the next delay or zero to stop. */
-typedef uint64_t (*yasl_timer_cb)(void *ud, yasl_timer_id id, uint64_t interval_ns);
-
-/** Convert a nonnegative integer millisecond value to nanoseconds; avoid overflow. */
-#define YASL_MS_TO_NS(ms) ((uint64_t)(ms) * 1000000ull)
-
-/**
- * Schedule a timer on a loop.
- * @param l Loop.
- * @param interval_ns Nonzero delay in monotonic nanoseconds before first firing.
- * @param cb Required callback; returns a new nonzero interval to repeat, or zero to stop.
- * @param ud Borrowed userdata until the timer stops, is deleted, or the loop is destroyed.
- * @return Nonzero timer ID, or zero for invalid arguments or allocation failure.
- * Repeating timers coalesce missed deadlines; do not use them to count elapsed
- * wall time. The callback receives the last scheduled interval, not elapsed time.
- */
-YASL_API yasl_timer_id yasl_loop_add_timer(struct yasl_loop *l, uint64_t interval_ns,
- yasl_timer_cb cb, void *ud);
-/**
- * Cancel a loop timer, including from its own callback.
- * @param l Loop.
- * @param id Timer ID.
- * @return true if an armed timer was removed, false if invalid or already retired.
- */
-YASL_API bool yasl_loop_del_timer(struct yasl_loop *l, yasl_timer_id id);
-/**
- * Schedule a timer canceled automatically on surface destruction.
- * @param s Surface whose display loop will run the timer.
- * @param interval_ns Nonzero initial delay in nanoseconds.
- * @param cb Required timer callback, with the same rules as yasl_loop_add_timer().
- * @param ud Borrowed userdata until the timer ends or the surface is destroyed.
- * @return Nonzero timer ID, or zero on failure.
- * The surface does not own userdata. Cancel with yasl_surface_del_timer().
- */
-YASL_API yasl_timer_id yasl_surface_add_timer(struct yasl_surface *s, uint64_t interval_ns,
- yasl_timer_cb cb, void *ud);
-/**
- * Cancel a timer registered through yasl_surface_add_timer().
- * @param s Owning surface.
- * @param id Timer ID.
- * @return true if still armed and removed; false if unknown or already retired.
- */
-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/metal.h b/include/yasl/metal.h
new file mode 100644
index 0000000..695f80c
--- /dev/null
+++ b/include/yasl/metal.h
@@ -0,0 +1,20 @@
+/** @file Direct Metal layer; application configures its device/format and presents. */
+#ifndef YASL_METAL_H
+#define YASL_METAL_H
+#include "yasl/yasl.h"
+#ifdef __OBJC__
+@class CAMetalLayer;
+#else
+typedef struct objc_object CAMetalLayer;
+#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+/** Borrowed until surface destruction. YASL owns view/layer and drawableSize.
+ * No device, drawable acquisition, command submission, or implicit present.
+ * Returns NULL on unsupported backend, CPU/GL surface, or incompatible presenter. */
+YASL_API CAMetalLayer *yasl_metal_layer(yasl_surface *surface);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/yasl/native.h b/include/yasl/native.h
deleted file mode 100644
index 64bc161..0000000
--- a/include/yasl/native.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * @file
- * Optional native handles and application-managed rendering.
- *
- * These extensions follow the core thread and lifetime rules. Handles are borrowed;
- * never destroy them or dispatch their native connection independently. Typed
- * backend accessors live in the yasl/native headers and are installed only for built
- * backends. Application-managed drawing currently supports Cocoa/Metal only.
- */
-#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)
- */
-/**
- * Get a borrowed, backend-specific display handle.
- * @param d Display, or NULL.
- * @return Native handle, or NULL. Inspect yasl_display_backend() before casting.
- * Prefer a typed accessor from yasl/native/wayland.h, x11.h, or cocoa.h.
- * The handle expires on display close; do not close or dispatch it independently.
- */
-YASL_API void *yasl_display_get_native_handle(struct yasl_display *d);
-/**
- * Get a borrowed, backend-specific surface handle.
- * @param s Surface, or NULL.
- * @return Native handle, or NULL. X11 encodes a Window through uintptr_t.
- * Prefer typed accessors. The handle expires on surface destruction. Do not
- * change native ownership, event masks, buffer attachment, or surface roles.
- */
-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. */
-/**
- * Create a toplevel for application-managed native rendering.
- * @param d Display with YASL_CAP_NATIVE_GRAPHICS.
- * @param spec Copied window options, with logical-pixel size and optional callbacks.
- * @param graphics_device Required native graphics device; currently id<MTLDevice> on Cocoa.
- * @return Owned surface, or NULL with errno set: EINVAL for invalid arguments,
- * ENOTSUP for an unsupported backend, or a backend error.
- * Cocoa retains the device. Query the drawable during draw, submit/present it,
- * then call yasl_surface_present() to record submission.
- * Callback ownership and timing follow yasl_surface_create_toplevel().
- */
-YASL_API struct yasl_surface *yasl_surface_create_native(struct yasl_display *d,
- const struct yasl_window_spec *spec, void *graphics_device);
-
-/** Borrowed native drawable for the current draw target, currently Cocoa/Metal. */
-struct yasl_native_frame {
- /** Borrowed id<CAMetalDrawable> on Cocoa. */
- void *drawable;
- /** Cocoa CAMetalLayer presentsWithTransaction setting for this frame. */
- bool transaction;
-};
-
-/* 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. */
-/**
- * Get the current draw target's native drawable.
- * @param s Surface currently being drawn.
- * @param target Exact framebuffer identity supplied to this draw callback.
- * @param out Required output native frame.
- * @return true if available, false for NULL arguments, unsupported backends,
- * stale targets, or calls outside draw. The drawable is borrowed and expires on
- * successful present, callback return, or surface destruction. Currently Cocoa only.
- */
-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/native/cocoa.h b/include/yasl/native/cocoa.h
index 9b221cf..bd92c98 100644
--- a/include/yasl/native/cocoa.h
+++ b/include/yasl/native/cocoa.h
@@ -1,55 +1,23 @@
-/**
- * @file
- * Typed borrowed Cocoa handles; available on macOS. Use on the main thread.
- */
#ifndef YASL_NATIVE_COCOA_H
#define YASL_NATIVE_COCOA_H
-
#include "yasl/yasl.h"
-
#ifdef __OBJC__
@class NSApplication;
@class NSWindow;
@class NSView;
#else
-typedef struct objc_object NSApplication; /**< Opaque Cocoa application in plain C/C++. */
-typedef struct objc_object NSWindow; /**< Opaque Cocoa window in plain C/C++. */
-typedef struct objc_object NSView; /**< Opaque Cocoa view in plain C/C++. */
+typedef struct objc_object NSApplication;
+typedef struct objc_object NSWindow;
+typedef struct objc_object NSView;
#endif
-
#ifdef __cplusplus
extern "C" {
#endif
-
-/* Return borrowed Cocoa handles (expire on display/surface destruction).
- * Return NULL / nil if display/surface is not a Cocoa object or NULL. */
-/**
- * Get the borrowed NSApplication for an object of the matching backend.
- * @param d Live display, or NULL.
- * @return The handle, or zero/NULL for NULL or a different backend.
- * Expires on display destruction. Available only when this backend is built.
- * Never pass a pointer to a destroyed object.
- */
-YASL_API NSApplication *yasl_cocoa_display_get_application(struct yasl_display *d);
-/**
- * Get the borrowed NSWindow for an object of the matching backend.
- * @param s Live surface, or NULL.
- * @return The handle, or zero/NULL for NULL or a different backend.
- * Expires on surface destruction. Available only when this backend is built.
- * Never pass a pointer to a destroyed object.
- */
-YASL_API NSWindow *yasl_cocoa_surface_get_window(struct yasl_surface *s);
-/**
- * Get the borrowed NSView for an object of the matching backend.
- * @param s Live surface, or NULL.
- * @return The handle, or zero/NULL for NULL or a different backend.
- * Expires on surface destruction. Available only when this backend is built.
- * Never pass a pointer to a destroyed object.
- */
-YASL_API NSView *yasl_cocoa_surface_get_view(struct yasl_surface *s);
-
+/** Borrowed native objects. Use on main thread, never change native ownership. */
+YASL_API NSApplication *yasl_cocoa_application(void);
+YASL_API NSWindow *yasl_cocoa_window(const yasl_surface *surface);
+YASL_API NSView *yasl_cocoa_view(const yasl_surface *surface);
#ifdef __cplusplus
}
#endif
-
-#endif /* YASL_NATIVE_COCOA_H */
+#endif
diff --git a/include/yasl/native/wayland.h b/include/yasl/native/wayland.h
index b11e3b8..1b8881e 100644
--- a/include/yasl/native/wayland.h
+++ b/include/yasl/native/wayland.h
@@ -1,40 +1,15 @@
-/**
- * @file
- * Typed borrowed Wayland handles; available when built with Wayland support.
- */
#ifndef YASL_NATIVE_WAYLAND_H
#define YASL_NATIVE_WAYLAND_H
-
#include "yasl/yasl.h"
-
+struct wl_display;
+struct wl_surface;
#ifdef __cplusplus
extern "C" {
#endif
-
-struct wl_display;
-struct wl_surface;
-
-/* Return borrowed Wayland handles (expire on display/surface destruction).
- * Return NULL if display/surface is not a Wayland object or NULL. */
-/**
- * Get the borrowed Wayland connection for an object of the matching backend.
- * @param d Live display, or NULL.
- * @return The handle, or zero/NULL for NULL or a different backend.
- * Expires on display destruction. Available only when this backend is built.
- * Never pass a pointer to a destroyed object.
- */
-YASL_API struct wl_display *yasl_wayland_display_get_wl_display(struct yasl_display *d);
-/**
- * Get the borrowed Wayland surface for an object of the matching backend.
- * @param s Live surface, or NULL.
- * @return The handle, or zero/NULL for NULL or a different backend.
- * Expires on surface destruction. Available only when this backend is built.
- * Never pass a pointer to a destroyed object.
- */
-YASL_API struct wl_surface *yasl_wayland_surface_get_wl_surface(struct yasl_surface *s);
-
+/** Borrowed handles; never dispatch or close native connections independently. */
+YASL_API struct wl_display *yasl_wayland_display(const yasl_surface *surface);
+YASL_API struct wl_surface *yasl_wayland_surface(const yasl_surface *surface);
#ifdef __cplusplus
}
#endif
-
-#endif /* YASL_NATIVE_WAYLAND_H */
+#endif
diff --git a/include/yasl/native/x11.h b/include/yasl/native/x11.h
index b719b4b..f8c37ae 100644
--- a/include/yasl/native/x11.h
+++ b/include/yasl/native/x11.h
@@ -1,40 +1,14 @@
-/**
- * @file
- * Typed borrowed X11 handles; available when built with X11 support.
- */
#ifndef YASL_NATIVE_X11_H
#define YASL_NATIVE_X11_H
-
#include "yasl/yasl.h"
-#include <stdint.h>
-
+typedef struct _XDisplay Display;
#ifdef __cplusplus
extern "C" {
#endif
-
-typedef struct _XDisplay Display; /**< Opaque Xlib connection, compatible with Xlib.h. */
-
-/* Return borrowed X11 handles (expire on display/surface destruction).
- * Return NULL / 0 if display/surface is not an X11 object or NULL. */
-/**
- * Get the borrowed X11 Display for an object of the matching backend.
- * @param d Live display, or NULL.
- * @return The handle, or zero/NULL for NULL or a different backend.
- * Expires on display destruction. Available only when this backend is built.
- * Never pass a pointer to a destroyed object.
- */
-YASL_API Display *yasl_x11_display_get_display(struct yasl_display *d);
-/**
- * Get the borrowed X11 Window ID for an object of the matching backend.
- * @param s Live surface, or NULL.
- * @return The handle, or zero/NULL for NULL or a different backend.
- * Expires on surface destruction. Available only when this backend is built.
- * Never pass a pointer to a destroyed object.
- */
-YASL_API uintptr_t yasl_x11_surface_get_window(struct yasl_surface *s);
-
+/** Borrowed handles; surface/window lifetime and native connection stay in YASL. */
+YASL_API Display *yasl_x11_display(const yasl_surface *surface);
+YASL_API uintptr_t yasl_x11_window(const yasl_surface *surface);
#ifdef __cplusplus
}
#endif
-
-#endif /* YASL_NATIVE_X11_H */
+#endif
diff --git a/include/yasl/timing.h b/include/yasl/timing.h
deleted file mode 100644
index 7e4af9e..0000000
--- a/include/yasl/timing.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * @file
- * Timing provenance, refresh estimates, and buffer-resize statistics.
- * All timestamps are monotonic nanoseconds, not wall-clock dates.
- */
-#ifndef YASL_TIMING_H
-#define YASL_TIMING_H
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Cumulative backend buffer-resize measurements; unavailable counters are zero. */
-struct yasl_resize_stats {
- /** Number of measured buffer resizes. */
- uint64_t count;
- /** Mean measured resize duration in microseconds. */
- double avg_us;
- /** Maximum measured resize duration in microseconds. */
- double max_us;
- /** Backend minor page-fault counter, if collected. */
- long minflt;
-};
-
-/* Describes last_present_ns, not merely availability of an extension. */
-/** Provenance of last_present_ns; only PRESENTATION confirms compositor presentation. */
-enum yasl_timing_source {
- YASL_TIMING_UNKNOWN = 0, /**< No timing sample yet. */
- YASL_TIMING_SUBMISSION, /**< CPU submission time, not scanout confirmation. */
- YASL_TIMING_FRAME_CALLBACK, /**< Compositor pacing callback, not scanout confirmation. */
- YASL_TIMING_PRESENTATION, /**< Compositor-confirmed presentation. */
-};
-
-/** Snapshot of estimates and timing provenance. Zero timestamps mean no sample yet. */
-struct yasl_timing {
- /** Estimated refresh interval in nanoseconds; zero if unavailable. */
- double refresh_ns;
- /** Last timestamp, whose meaning is specified by source. */
- uint64_t last_present_ns;
- /** Estimated next presentation time, or zero without a prior sample. */
- uint64_t next_present_ns;
- /** Backend skipped-frame counter; not comparable across backends. */
- uint64_t frames_skipped;
- /** Provenance of last_present_ns. */
- enum yasl_timing_source source;
- /** Cumulative backend resize statistics. */
- struct yasl_resize_stats resize;
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* YASL_TIMING_H */
diff --git a/include/yasl/vulkan.h b/include/yasl/vulkan.h
new file mode 100644
index 0000000..afa1089
--- /dev/null
+++ b/include/yasl/vulkan.h
@@ -0,0 +1,19 @@
+/** @file Vulkan WSI only; application owns all Vulkan objects. */
+#ifndef YASL_VULKAN_H
+#define YASL_VULKAN_H
+#include "yasl/yasl.h"
+#include <vulkan/vulkan.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+YASL_API bool yasl_vulkan_init(PFN_vkGetInstanceProcAddr loader);
+/** Borrowed list through shutdown; merge with app extensions before instance creation. */
+YASL_API const char *const *yasl_vulkan_instance_extensions(const yasl_surface *surface, uint32_t *count);
+YASL_API VkInstanceCreateFlags yasl_vulkan_instance_flags(const yasl_surface *surface);
+/** Uses injected loader; destroy returned VkSurfaceKHR before YASL surface. */
+YASL_API VkResult yasl_vulkan_create_surface(yasl_surface *surface, VkInstance instance,
+ const VkAllocationCallbacks *allocator, VkSurfaceKHR *out);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/yasl/yasl.h b/include/yasl/yasl.h
index 889f70a..350339b 100644
--- a/include/yasl/yasl.h
+++ b/include/yasl/yasl.h
@@ -1,1089 +1,152 @@
-/**
- * @file
- * Portable desktop surfaces, CPU drawing, input, and display dispatch.
- *
- * All calls and callbacks use the display's opening thread (the main thread on
- * Cocoa), unless explicitly documented otherwise. Userdata is borrowed; callback
- * tables and creation specs are copied. Do not recursively dispatch/flush or
- * destroy a display/loop while dispatch or a callback is active. Destroy child
- * popups before parents, surfaces before displays, displays before borrowed loops.
- * Surface destruction from its own callback is supported; stop using it immediately.
- *
- * Zero-initialize option and callback structs before setting fields. Pointers to
- * destroyed objects are invalid, even for getters and destroy functions. NULL
- * handling is documented per function; it does not make freed pointers safe.
- * Only functions explicitly documenting errno guarantee a diagnostic there.
- * Other boolean results report success/availability; void setters are best effort.
- * New window requests, clipboard operations, frame presentation, and posting
- * document errno on failure. Event strings belong to the display queue.
- *
- * Toplevel creation sizes use logical pixels. Geometry, framebuffers, pointer
- * positions, damage, IME carets, popup specs, and drag offsets use device pixels.
- * Coordinates have their origin at the upper left; x grows right and y grows down.
- * Scale is an integer ratio with YASL_SCALE_UNIT (120) representing 1x.
- * See the application guide for the display-wide dispatch/poll/flush cycle
- * and backend limits. Legacy surface polling is an input-only filtered adapter.
- */
+/** @file Windows, input and events. The first surface starts the backend; use the
+ * creating thread (main on Cocoa) for every call except yasl_wake. Coordinates are
+ * logical units unless named pixel. */
#ifndef YASL_H
#define YASL_H
-
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
-#include <limits.h>
-#include <float.h>
-#include <math.h>
-
-#include "yasl/timing.h"
#include "yasl/keycodes.h"
-
+#if defined(__GNUC__)
+#define YASL_API __attribute__((visibility("default")))
+#else
+#define YASL_API
+#endif
#ifdef __cplusplus
extern "C" {
#endif
-
-/** Public shared-library symbol visibility annotation. */
-#if defined(_WIN32) || defined(__CYGWIN__)
- #if defined(YASL_BUILD_SHARED)
- #define YASL_API __declspec(dllexport)
- #elif defined(YASL_SHARED)
- #define YASL_API __declspec(dllimport)
- #else
- #define YASL_API
- #endif
-#elif defined(__GNUC__) && __GNUC__ >= 4
- #define YASL_API __attribute__((visibility("default")))
-#else
- #define YASL_API
-#endif
-
-struct yasl_display;
-struct yasl_surface;
-struct yasl_loop;
-
-/* Geometry */
-/** A two-dimensional integer size, position, or offset; units depend on the caller. */
-struct yasl_vector2i {
- /** Horizontal coordinate or width. */
- int x;
- /** Vertical coordinate or height. */
- int y;
-};
-
-/** Two-dimensional fractional offset; units depend on the containing structure. */
-struct yasl_vector2d {
- /** Horizontal component. */
- double x;
- /** Vertical component. */
- double y;
-};
-
-/** Integer rectangle; origin is upper left and extents must be nonnegative. */
-struct yasl_rect2i {
- /** Left coordinate. */
- int x;
- /** Top coordinate. */
- int y;
- /** Nonnegative horizontal extent. */
- int width;
- /** Nonnegative vertical extent. */
- int height;
-};
-
-/** Scale numerator representing 1x. */
-#define YASL_SCALE_UNIT 120
-/** Backend minimum logical dimension used when constraining toplevel sizes. */
-#define YASL_MIN_LOGICAL_PX 64
-
-/* Nearest integer, ties away from zero. Zero scale returns zero; finite
- * out-of-range results saturate. Non-finite logical coordinates return zero. */
-/** Convert a logical coordinate to device pixels, rounding ties away from zero.
- * @param logical Logical coordinate; non-finite values return zero.
- * @param scale_120 Scale numerator; zero returns zero.
- * @return Rounded device coordinate, saturated to the range of int.
- */
-static inline int yasl_scale_to_device(double logical, uint32_t scale_120)
-{
- if (!scale_120 || !(logical >= -DBL_MAX && logical <= DBL_MAX)) return 0;
- double px = (scale_120 == YASL_SCALE_UNIT) ? logical : (logical * ((double)scale_120 / YASL_SCALE_UNIT));
- if (px >= INT_MAX) return INT_MAX;
- if (px <= INT_MIN) return INT_MIN;
- return (int)(px + copysign(0.5, px));
-}
-
-/** Convert a device coordinate to logical pixels, rounding ties away from zero.
- * @param device Device coordinate.
- * @param scale_120 Scale numerator; zero returns zero.
- * @return Rounded logical coordinate, saturated to the range of int.
- */
-static inline int yasl_scale_to_logical(int device, uint32_t scale_120)
-{
- if (!scale_120) return 0;
- if (scale_120 == YASL_SCALE_UNIT) return device;
- int64_t px = (int64_t)device * YASL_SCALE_UNIT;
- int64_t half = (int64_t)(scale_120 / 2);
- int64_t bias = (px < 0) ? -half : half;
- px = (px + bias) / scale_120;
- if (px > INT_MAX) return INT_MAX;
- if (px < INT_MIN) return INT_MIN;
- return (int)px;
-}
-
-/* Capabilities */
-/** Optional backend/server features, returned as a bitmask by yasl_display_caps(). */
-enum yasl_display_cap : uint32_t {
- YASL_CAP_POPUPS = 1 << 0, /**< Popup creation and placement. */
- YASL_CAP_DRAG = 1 << 1, /**< Surface-drag source and target support. */
- YASL_CAP_DRAG_CARRY = 1 << 2, /**< Carry a toplevel during a drag. */
- YASL_CAP_PLACE_WINDOW = 1 << 3, /**< Place a window relative to the pointer. */
- YASL_CAP_PRIMARY_SELECTION = 1 << 4, /**< Separate primary selection. */
- YASL_CAP_CSD = 1 << 5, /**< Backend advertises client decoration support; check each action result. */
- YASL_CAP_NATIVE_GRAPHICS = 1 << 6, /**< Application-managed native rendering. */
- YASL_CAP_FRAME_PACING = 1 << 7, /**< Compositor/display-driven draws. */
- /* Backend/protocol supports tablet axes, independent of attached hardware. */
- YASL_CAP_TABLET = 1 << 8, /**< Tablet protocol support, independent of attached hardware. */
-};
-
-/** Independent selections. An unsupported selection never aliases the clipboard. */
-enum yasl_selection : uint8_t {
- YASL_CLIPBOARD, /**< Explicit copy/paste selection. */
- YASL_PRIMARY, /**< Independent primary selection, if supported. */
-};
-
-/** Reported surface state flags; absent flags may also mean unsupported state. */
-enum yasl_surface_state : uint32_t {
- YASL_STATE_FULLSCREEN = 1 << 0, /**< Fullscreen. */
- YASL_STATE_MAXIMIZED = 1 << 1, /**< Maximized. */
- YASL_STATE_ACTIVATED = 1 << 2, /**< Active window. */
- YASL_STATE_SUSPENDED = 1 << 3, /**< Compositor reports suspension. */
- YASL_STATE_CSD = 1 << 4, /**< Backend reports client-side decorations. */
- YASL_STATE_TILED = 1 << 5, /**< At least one edge is tiled; currently reported by Wayland. */
-};
-
-/** System cursor shapes. HIDDEN preserves pointer input; NONE is its compatibility alias. */
-enum yasl_cursor {
- YASL_CURSOR_ARROW, /**< Default arrow. */
- YASL_CURSOR_TEXT, /**< Text insertion. */
- YASL_CURSOR_LINK, /**< Link/pointer hand. */
- YASL_CURSOR_CROSSHAIR, /**< Crosshair. */
- YASL_CURSOR_MOVE, /**< Move in any direction. */
- YASL_CURSOR_RESIZE_NWSE, /**< Northwest/southeast resize. */
- YASL_CURSOR_RESIZE_NESW, /**< Northeast/southwest resize. */
- YASL_CURSOR_RESIZE_EW, /**< Horizontal resize. */
- YASL_CURSOR_RESIZE_NS, /**< Vertical resize. */
- YASL_CURSOR_HIDDEN, /**< Hidden system cursor; pointer input continues. */
- YASL_CURSOR_NONE = YASL_CURSOR_HIDDEN, /**< Compatibility alias for HIDDEN. */
-};
-
-/** Valid interactive resize edges; combinations are restricted to the named values. */
-enum yasl_resize_edge : uint32_t {
- YASL_EDGE_NONE = 0, /**< No resize edge; rejected by interactive resize. */
- YASL_EDGE_TOP = 1, /**< Top edge. */
- YASL_EDGE_BOTTOM = 2, /**< Bottom edge. */
- YASL_EDGE_LEFT = 4, /**< Left edge. */
- YASL_EDGE_TOP_LEFT = 5, /**< Top-left corner. */
- YASL_EDGE_BOTTOM_LEFT = 6, /**< Bottom-left corner. */
- YASL_EDGE_RIGHT = 8, /**< Right edge. */
- YASL_EDGE_TOP_RIGHT = 9, /**< Top-right corner. */
- YASL_EDGE_BOTTOM_RIGHT = 10, /**< Bottom-right corner. */
-};
-
-/* Damage & Framebuffer
- * CPU pixels are tightly packed premultiplied ARGB8888 (0xAARRGGBB).
- * Size, pointer positions, IME caret and damage use device pixels; surface
- * toplevel creation sizes use logical pixels. Damage is a hint: backends may upload
- * the whole frame. Every pixel must contain valid content on each draw.
- */
-/** Maximum number of damage rectangles in one presentation. */
-#define YASL_DAMAGE_MAX 64
-
-/** Damage hints for one presentation; every target still needs complete valid pixels. */
-struct yasl_damage_list {
- /** -1: full target; 0: no damaged rectangles; otherwise number of rects. */
- int n;
- /** Reserved hint; callers may leave zero. Core presentation uses rects. */
- struct yasl_rect2i bounds;
- /** First n rectangles, in device pixels; ignored for n == -1. */
- struct yasl_rect2i rects[YASL_DAMAGE_MAX];
-};
-
-/** Borrowed draw target, valid only for the current draw callback. Never free pixels. */
-struct yasl_framebuffer {
- /** Opaque draw identity. Preserve it and all target fields when copying. */
- uint64_t generation;
- /** Writable premultiplied ARGB8888, row stride size.x * sizeof(uint32_t); may be NULL for native rendering. */
- uint32_t *pixels;
- /** Target extent in device pixels. */
- struct yasl_vector2i size;
- /** Row stride in bytes, populated for the active draw callback. */
- int stride_bytes;
-};
-
-/** One draw invocation. Do not retain its pointer after the callback returns. */
-struct yasl_frame {
- /** Surface being drawn. */
- struct yasl_surface *surface;
- /** Target to initialize and present before returning. */
- struct yasl_framebuffer target;
- /** Zero-based index of this surface draw. */
- uint64_t frame_index;
- /** Estimated animation time; not confirmed presentation. */
- uint64_t target_time_ns;
- /** Device scale numerator, with 120 representing 1x. */
- uint32_t scale_120;
-};
-
-/** Coalesced redraw policy, valid with either loop style. */
-typedef enum yasl_pacing_mode {
- YASL_PACING_ON_DEMAND = 0, /**< Draw only when invalidated or exposed. */
- YASL_PACING_CONTINUOUS, /**< Draw continuously using native pacing or a timer. */
-} yasl_pacing_mode;
-
-/* Drag and Drop */
-/** Target notifications for YASL surface drags, separate from external file drops. */
-enum yasl_drag_event {
- YASL_DRAG_OVER, /**< Surface drag entered or moved over the target. */
- YASL_DRAG_LEAVE, /**< Surface drag left the target. */
- YASL_DRAG_DROP, /**< Surface drag dropped on the target. */
-};
-
-/** External text/file drag hover notifications; completed data arrives through input. */
-enum yasl_drop_event {
- YASL_DROP_OVER, /**< External data drag entered or moved over the target. */
- YASL_DROP_LEAVE, /**< External data drag left the target. */
-};
-
-/** Source-side drag completion; DROPPED does not prove application-level acceptance. */
-enum yasl_drag_end {
- YASL_DRAG_DROPPED, /**< Drag ended in a drop; not an application acceptance receipt. */
- YASL_DRAG_CANCELLED, /**< Drag canceled, including display close. */
-};
-
-/** Copied drag icon in tightly packed premultiplied 0xAARRGGBB device pixels. */
-struct yasl_drag_image {
- /** Copied pixel array; required when an image is supplied. */
- const uint32_t *pixels;
- /** Positive width and height in device pixels. */
- struct yasl_vector2i size;
- /** Pointer position within the image, in device pixels. */
- struct yasl_vector2i hotspot;
-};
-
-/** Copied drag completion listener; userdata remains owned by the application. */
-struct yasl_drag_listener {
- /** Called exactly once after a successful start, possibly synchronously on cancel/close. */
- void (*end)(void *ud, enum yasl_drag_end how);
-};
-
-/** Configured device-pixel content size and the corresponding display scale. */
-struct yasl_geometry {
- /** Current content extent in device pixels. */
- struct yasl_vector2i size;
- /** Positive scale numerator; 120 means 1x and 180 means 1.5x. */
- uint32_t scale_120;
-};
-
-/* Input Model */
-/** Keyboard press, release, or autorepeat; releases must not insert text. */
-enum yasl_key_action {
- YASL_KEY_PRESS, /**< Key pressed. */
- YASL_KEY_RELEASE, /**< Key released. */
- YASL_KEY_REPEAT, /**< Key autorepeat. */
-};
-
-/** Modifier bitmask. SUPER is Command on macOS. */
-enum yasl_mod : uint32_t {
- YASL_MOD_SHIFT = 1 << 0, /**< Shift modifier. */
- YASL_MOD_ALT = 1 << 1, /**< Alt/Option modifier. */
- YASL_MOD_CTRL = 1 << 2, /**< Control modifier. */
- YASL_MOD_SUPER = 1 << 3, /**< Super/Command modifier. */
- YASL_MOD_CAPS = 1 << 4, /**< Caps Lock modifier. */
-};
-
-/** Pointer source class; capability support does not imply an attached device. */
-enum yasl_pointer_device {
- YASL_PTR_DEV_MOUSE, /**< Mouse or trackpad pointer. */
- YASL_PTR_DEV_TOUCH, /**< Touch translated into pointer input. */
- YASL_PTR_DEV_PEN, /**< Tablet stylus. */
- YASL_PTR_DEV_ERASER, /**< Tablet eraser tool. */
-};
-
-/** Pointer button; meaningful only for POINTER_DOWN and POINTER_UP. */
-enum yasl_pointer_button {
- YASL_BUTTON_PRIMARY = 0, /**< Left button, pen tip, or touch contact. */
- YASL_BUTTON_MIDDLE = 1, /**< Middle button / wheel click. */
- YASL_BUTTON_SECONDARY = 2, /**< Right button or pen barrel button. */
- YASL_BUTTON_BACK = 3, /**< Side "back" button. */
- YASL_BUTTON_FORWARD = 4, /**< Side "forward" button. */
-};
-
-/** Bit for a yasl_pointer_button in yasl_pointer_event.buttons. */
+typedef struct yasl_surface yasl_surface;
+typedef struct yasl_event yasl_event;
+enum yasl_backend { YASL_BACKEND_AUTO, YASL_BACKEND_WAYLAND, YASL_BACKEND_X11, YASL_BACKEND_COCOA };
+enum yasl_surface_flags { YASL_SURFACE_CPU=1u, YASL_SURFACE_HIDDEN=2u, YASL_SURFACE_UNDECORATED=4u, YASL_SURFACE_FIXED_SIZE=8u };
+enum yasl_error { YASL_ERROR_NONE, YASL_ERROR_INVALID, YASL_ERROR_UNSUPPORTED, YASL_ERROR_NO_MEMORY,
+ YASL_ERROR_NOT_INITIALIZED, YASL_ERROR_BUSY, YASL_ERROR_WRONG_THREAD, YASL_ERROR_CONTEXT_EXPIRED, YASL_ERROR_IO };
+enum yasl_selection { YASL_CLIPBOARD, YASL_PRIMARY };
+enum yasl_key_action { YASL_KEY_PRESS, YASL_KEY_RELEASE, YASL_KEY_REPEAT };
+enum yasl_mod { YASL_MOD_SHIFT=1u, YASL_MOD_ALT=2u, YASL_MOD_CTRL=4u, YASL_MOD_SUPER=8u, YASL_MOD_CAPS=16u };
+enum yasl_pointer_action { YASL_POINTER_MOVE, YASL_POINTER_DOWN, YASL_POINTER_UP, YASL_POINTER_LEAVE };
+enum yasl_pointer_mode { YASL_POINTER_NORMAL, YASL_POINTER_RELATIVE };
+enum yasl_button { YASL_BUTTON_PRIMARY, YASL_BUTTON_MIDDLE, YASL_BUTTON_SECONDARY, YASL_BUTTON_BACK, YASL_BUTTON_FORWARD };
#define YASL_BUTTON_BIT(button) (1u << (button))
-
-/** Pointer capture mode for a surface. */
-enum yasl_pointer_mode {
- YASL_POINTER_NORMAL = 0, /**< Absolute positions; cursor per yasl_surface_set_cursor(). */
- /** Cursor hidden and locked in place while the surface has focus. POINTER_MOTION
- * reports unbounded relative motion in delta; pos stays at the lock position.
- * The lock is released on focus loss and re-acquired on focus gain. */
- YASL_POINTER_RELATIVE,
-};
-
-/** Normalized tablet axes; zero for unavailable axes and non-tablet devices. */
-struct yasl_pointer_pen {
- /** 0..65535 normalized to device range. Zero alone does not end contact. */
- uint16_t pressure;
- /** Degrees in -90..90; positive right. */
- int8_t tilt_x;
- /** Degrees in -90..90; positive down. */
- int8_t tilt_y;
-};
-
-/** Event tag. Each tag lists the union member it selects. */
-enum yasl_event_type {
- YASL_EVENT_NONE = 0,
-
- /* Input: produced by backends, returned by yasl_surface_poll_event(). */
- YASL_EVENT_KEY, /**< .key */
- YASL_EVENT_TEXT, /**< .text — committed UTF-8; insert this, not key codepoints. */
- YASL_EVENT_POINTER_DOWN, /**< .pointer — button/tip pressed; button valid. */
- YASL_EVENT_POINTER_UP, /**< .pointer — button/tip released; button valid. */
- YASL_EVENT_POINTER_MOTION, /**< .pointer — position, relative motion, or pen axes changed. */
- YASL_EVENT_POINTER_SCROLL, /**< .pointer — scroll valid. */
- YASL_EVENT_POINTER_LEAVE, /**< .pointer — last known pos/device; cancel hover state. */
- YASL_EVENT_FOCUS, /**< .focus — keyboard focus changed; cancel held state on loss. */
- YASL_EVENT_PASTE, /**< .text — UTF-8 from yasl_display_paste(). */
- YASL_EVENT_DROP, /**< .text — dropped text/uri-list: CRLF-separated file URLs, not paths. */
- YASL_EVENT_INPUT_RESET, /**< No payload. Input stream interrupted; clear held keys, buttons, strokes, IME. */
-
- /* Window and application: part of the display FIFO, as well as runner delivery.
- * Legacy window callbacks also receive matching native notifications. */
- YASL_EVENT_WINDOW_RESIZE, /**< .resize — size and/or scale changed; reallocate and redraw. */
- YASL_EVENT_WINDOW_CLOSE, /**< No payload. User asked to close the window. */
- YASL_EVENT_USER, /**< .user — posted application message. */
- YASL_EVENT_WINDOW_STATE, /**< .state — reported state changed. */
- YASL_EVENT_DRAG, /**< .drag — surface-drag target notification. */
- YASL_EVENT_DROP_HOVER, /**< .drop — external drag hover/leave. */
- YASL_EVENT_COMPOSITION, /**< .composition — preedit snapshot, including ending. */
- YASL_EVENT_DISPLAY_QUIT, /**< No payload; system requested application quit. */
- YASL_EVENT_DISPLAY_REOPEN, /**< No payload; system requested activation. */
- YASL_EVENT_DISPLAY_LOST, /**< No payload; display connection failed. */
-};
-
-/** Physical keyboard transition with optional layout labels.
- * key is independent of modifiers/layout and stable between press and release.
- * codepoint and shifted are optional single Unicode scalars for the current
- * layout at levels zero/one, not text input. Zero means unavailable, a control
- * key, or a layout mapping that produces multiple characters. Insert committed
- * YASL_EVENT_TEXT into documents instead. */
-struct yasl_key_event {
- /** Portable physical key; YASL_KEY_UNKNOWN when unmapped. */
- enum yasl_key key;
- /** Press, release, or autorepeat. */
- enum yasl_key_action action;
- /** yasl_mod bitmask at this event. */
- uint32_t mods;
- /** Optional unshifted layout Unicode scalar; zero if unavailable. */
- uint32_t codepoint;
- /** Optional shifted layout Unicode scalar; zero if unavailable. */
- uint32_t shifted;
- /** Native code: Wayland evdev, X11 server keycode, Cocoa virtual keycode. */
- uint32_t native_code;
-};
-
-/** Pointer sample shared by all POINTER_* events. Pen and eraser share it with
- * mouse input. Track contact with DOWN/UP of the primary button, not pressure.
- * This is not a multi-contact touch API. */
-struct yasl_pointer_event {
- /** Surface-relative device-pixel position. Frozen while YASL_POINTER_RELATIVE is locked. */
- struct yasl_vector2i pos;
- /** MOTION: device-pixel movement since the previous sample on this surface.
- * Unbounded under YASL_POINTER_RELATIVE; zero after enter, leave, or reset. */
- struct yasl_vector2d delta;
- /** SCROLL: fractional line offsets after system preferences; positive right/down. */
- struct yasl_vector2d scroll;
- /** DOWN/UP: which button changed. */
- enum yasl_pointer_button button;
- /** YASL_BUTTON_BIT() mask of buttons held after this event, on every
- * POINTER_* type. Tracked from this queue's DOWN and UP events for all
- * devices; INPUT_RESET clears it. On Wayland LEAVE clears it too, since the
- * compositor sends leave during a press only when it takes the pointer.
- * X11 and Cocoa keep sending motion and the release after LEAVE. */
- uint32_t buttons;
- /** Mouse, touch, pen, or eraser. */
- enum yasl_pointer_device device;
- /** yasl_mod bitmask at this event. */
- uint32_t mods;
- /** Current tablet axes, including on pressure-only motion; missing axes are zero. */
- struct yasl_pointer_pen pen;
-};
-
-/** Borrowed NUL-terminated UTF-8, shared by TEXT, PASTE and DROP. */
-struct yasl_text_event {
- /** Borrowed NUL-terminated bytes; see yasl_surface_poll_event() for lifetime. */
- const char *data;
- /** Length in bytes excluding the terminating NUL. */
- size_t len;
-};
-
-/** Clipboard transfer outcome. */
-enum yasl_transfer_status {
- YASL_TRANSFER_OK = 0, /**< Text received successfully, including empty text. */
- YASL_TRANSFER_UNAVAILABLE, /**< No text selection is available. */
- YASL_TRANSFER_FAILED, /**< Transfer or decoding failed. */
-};
-
-/** Clipboard completion; data/len alias the legacy text payload. */
-struct yasl_paste_event {
- const char *data; /**< Borrowed NUL-terminated UTF-8; empty on failure. */
- size_t len; /**< Byte length excluding NUL. */
- uint64_t request_id; /**< Zero for a legacy paste request. */
- enum yasl_transfer_status status; /**< Completion outcome. */
-};
-
-/** Borrowed UTF-8 preedit snapshot, valid until the next successful display poll. */
-struct yasl_composition_event {
- const char *data; /**< Borrowed NUL-terminated UTF-8 snapshot. */
- size_t len; /**< Byte length excluding NUL. */
- int begin; /**< UTF-8 byte offset, or -1 if unavailable. */
- int end; /**< UTF-8 byte offset, or -1 if unavailable. */
- bool active; /**< Whether composition text is present. */
-};
-
-/** Reported window-state change. */
-struct yasl_state_event { uint32_t flags; /**< Current YASL_STATE_* flags. */ };
-/** Surface-drag target notification; position is in device pixels. */
-struct yasl_drag_target_event {
- enum yasl_drag_event action; /**< Hover, leave, or drop. */
- struct yasl_vector2i pos; /**< Surface-relative device pixels. */
-};
-/** External drag hover notification; position is in device pixels. */
-struct yasl_drop_hover_event {
- enum yasl_drop_event action; /**< Hover or leave. */
- struct yasl_vector2i pos; /**< Surface-relative device pixels. */
-};
-
-/** Keyboard focus transition. */
-struct yasl_focus_event {
- /** true on focus gain, false on loss. */
- bool focused;
-};
-
-/** New configured geometry for a surface. */
-struct yasl_resize_event {
- /** Content size in device pixels and display scale. */
- struct yasl_geometry geometry;
- /** true when scale_120 differs from the previous resize of this surface. */
- bool scale_changed;
-};
-
-/** Application message posted with yasl_post_event(). */
-struct yasl_user_event {
- /** Application-defined message code. */
- uint32_t code;
- /** Pointer passed through unchanged; ownership stays with the application. */
- void *payload;
- /** Optional payload size, passed through unchanged. */
- size_t size;
-};
-
-/** One tagged event; read only the union member selected by type. */
+enum yasl_pen_tool { YASL_PEN_UNKNOWN, YASL_PEN_PEN, YASL_PEN_ERASER, YASL_PEN_BRUSH, YASL_PEN_AIRBRUSH, YASL_PEN_PENCIL };
+enum yasl_pen_action { YASL_PEN_ENTER, YASL_PEN_LEAVE, YASL_PEN_MOVE, YASL_PEN_DOWN, YASL_PEN_UP, YASL_PEN_BUTTON, YASL_PEN_CANCEL };
+enum yasl_pen_axis { YASL_PEN_PRESSURE=1u, YASL_PEN_TILT=2u, YASL_PEN_ROTATION=4u, YASL_PEN_DISTANCE=8u, YASL_PEN_TANGENTIAL=16u, YASL_PEN_WHEEL=32u };
+enum yasl_scroll_valid { YASL_SCROLL_LINES=1u, YASL_SCROLL_PIXELS=2u };
+enum yasl_scroll_source { YASL_SCROLL_UNKNOWN, YASL_SCROLL_WHEEL, YASL_SCROLL_FINGER, YASL_SCROLL_CONTINUOUS };
+enum yasl_scroll_phase { YASL_SCROLL_PHASE_UNKNOWN, YASL_SCROLL_BEGIN, YASL_SCROLL_UPDATE, YASL_SCROLL_END };
+enum yasl_transfer_status { YASL_TRANSFER_OK, YASL_TRANSFER_UNAVAILABLE, YASL_TRANSFER_FAILED };
+enum yasl_text_purpose { YASL_TEXT_NORMAL, YASL_TEXT_PASSWORD, YASL_TEXT_NUMBER, YASL_TEXT_TERMINAL };
+enum yasl_cursor { YASL_CURSOR_ARROW, YASL_CURSOR_TEXT, YASL_CURSOR_LINK, YASL_CURSOR_CROSSHAIR, YASL_CURSOR_MOVE,
+ YASL_CURSOR_RESIZE_NWSE, YASL_CURSOR_RESIZE_NESW, YASL_CURSOR_RESIZE_EW, YASL_CURSOR_RESIZE_NS, YASL_CURSOR_HIDDEN };
+enum yasl_surface_state { YASL_STATE_FULLSCREEN=1u, YASL_STATE_MAXIMIZED=2u, YASL_STATE_ACTIVATED=4u,
+ YASL_STATE_SUSPENDED=8u, YASL_STATE_CSD=16u, YASL_STATE_TILED=32u };
+enum yasl_feature { YASL_CAP_POPUPS=1u, YASL_CAP_DRAG=2u, YASL_CAP_DRAG_CARRY=4u, YASL_CAP_PLACE_WINDOW=8u,
+ YASL_CAP_PRIMARY_SELECTION=16u, YASL_CAP_CSD=32u, YASL_CAP_NATIVE_GRAPHICS=64u, YASL_CAP_FRAME_PACING=128u,
+ YASL_CAP_TABLET=256u, YASL_CAP_OPENGL=512u, YASL_CAP_VULKAN=1024u, YASL_CAP_TEXT_INPUT=2048u };
+enum yasl_popup_edge { YASL_POPUP_CENTER, YASL_POPUP_TOP, YASL_POPUP_BOTTOM, YASL_POPUP_LEFT,
+ YASL_POPUP_RIGHT, YASL_POPUP_TOP_LEFT, YASL_POPUP_BOTTOM_LEFT, YASL_POPUP_TOP_RIGHT, YASL_POPUP_BOTTOM_RIGHT };
+enum yasl_popup_constraint { YASL_POPUP_SLIDE_X=1u, YASL_POPUP_SLIDE_Y=2u, YASL_POPUP_FLIP_X=4u,
+ YASL_POPUP_FLIP_Y=8u, YASL_POPUP_RESIZE_X=16u, YASL_POPUP_RESIZE_Y=32u };
+enum yasl_resize_edge { YASL_EDGE_TOP=1, YASL_EDGE_BOTTOM=2, YASL_EDGE_LEFT=4, YASL_EDGE_TOP_LEFT=5,
+ YASL_EDGE_BOTTOM_LEFT=6, YASL_EDGE_RIGHT=8, YASL_EDGE_TOP_RIGHT=9, YASL_EDGE_BOTTOM_RIGHT=10 };
+enum yasl_event_type { YASL_EVENT_NONE, YASL_EVENT_CLOSE, YASL_EVENT_QUIT, YASL_EVENT_REOPEN, YASL_EVENT_WINDOW,
+ YASL_EVENT_REFRESH, YASL_EVENT_KEY, YASL_EVENT_TEXT, YASL_EVENT_POINTER, YASL_EVENT_SCROLL, YASL_EVENT_PEN,
+ YASL_EVENT_INPUT_RESET, YASL_EVENT_COMPOSITION, YASL_EVENT_TEXT_EDIT, YASL_EVENT_CLIPBOARD, YASL_EVENT_DROP,
+ YASL_EVENT_DRAG, YASL_EVENT_DISPLAY_LOST };
+enum yasl_drop_action { YASL_DROP_OVER, YASL_DROP_LEAVE, YASL_DROP_DATA };
+enum yasl_drag_action { YASL_DRAG_OVER, YASL_DRAG_LEAVE, YASL_DRAG_DROP };
+/** Read the union member named by type. Strings stay valid until the next wait.
+ * CLOSE: the user closed this window. QUIT: the system asked the app to quit.
+ * WINDOW: size, scale or state changed. REFRESH: draw now; sent once the window
+ * has a size, after every resize and when the system needs the contents again.
+ * INPUT_RESET: forget held keys, buttons and strokes. DROP: external data over
+ * the window, delivered as DATA. DRAG: another YASL surface dragged over. */
struct yasl_event {
- /** Selects the valid union member. */
enum yasl_event_type type;
- /** Recipient surface, or NULL for display-wide events. Can differ from the
- * polled surface for routed popup input. */
- struct yasl_surface *surface;
- /** Monotonic timestamp in nanoseconds, same clock as yasl_loop_now_ns(). */
+ yasl_surface *surface;
uint64_t time_ns;
- /** Increasing display-wide enqueue order; zero for standalone private queues. */
- uint64_t sequence;
- /** Stable recipient identity; zero for display-wide events. */
- uint64_t surface_id;
- union {
- struct yasl_key_event key; /**< KEY */
- struct yasl_pointer_event pointer; /**< POINTER_* */
- struct yasl_text_event text; /**< TEXT, legacy PASTE, DROP */
- struct yasl_paste_event paste; /**< PASTE */
- struct yasl_composition_event composition; /**< COMPOSITION */
- struct yasl_state_event state; /**< WINDOW_STATE */
- struct yasl_drag_target_event drag; /**< DRAG */
- struct yasl_drop_hover_event drop; /**< DROP_HOVER */
- struct yasl_focus_event focus; /**< FOCUS */
- struct yasl_resize_event resize; /**< WINDOW_RESIZE */
- struct yasl_user_event user; /**< USER */
- };
-};
-
-/* Ownership and threading
- * All calls and callbacks run on the display's opening thread (main thread on
- * Cocoa). Displays borrow supplied loops; destroy surfaces before displays,
- * 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.
- * Surface destruction is allowed from its callbacks; display/loop destruction
- * during dispatch or callbacks is not supported.
- */
-
-/* Callbacks */
-/** Optional display notifications. NULL callback members are ignored. */
-struct yasl_display_cbs {
- /** Application quit request; arrange orderly shutdown after dispatch returns. */
- void (*quit)(void *ud);
- /** Application reopen/activation request, currently Cocoa. */
- void (*reopen)(void *ud);
- /** Display connection lost; arrange cleanup after dispatch returns. */
- void (*lost)(void *ud);
-};
-
-/** Optional window/popup notifications, copied from yasl_window_spec.cbs or by
-yasl_surface_set_callbacks().
-Callbacks may destroy their surface. They must then return without further use
-of the surface or draw target. NULL members are ignored. */
-struct yasl_window_cbs {
- /** Initialize the entire target and optionally present. Requested through schedule_redraw/flush. */
- void (*draw)(struct yasl_surface *s, struct yasl_frame *frame, void *ud);
- /** Configured size/scale changed; reallocate application content and request a redraw. */
- void (*configure)(struct yasl_surface *s, struct yasl_geometry geometry, void *ud);
- /** Window/popup close request; application is responsible for destruction. */
- void (*close)(struct yasl_surface *s, void *ud);
- /** Reported yasl_surface_state bitmask changed; matches yasl_surface_state(s). */
- void (*state)(struct yasl_surface *s, uint32_t state, void *ud);
- /** YASL surface-drag target hover, leave, or drop; pos is in device pixels. */
- void (*drag)(struct yasl_surface *s, enum yasl_drag_event ev,
- struct yasl_vector2i pos, void *ud);
- /** External data-drag hover or leave; pos is in device pixels. */
- void (*drop)(struct yasl_surface *s, enum yasl_drop_event ev,
- struct yasl_vector2i pos, void *ud);
-};
-
-/* Display Lifecycle */
-/** Runtime backend choice. AUTO selects a native backend and allows fallback. */
-enum yasl_backend {
- YASL_BACKEND_AUTO = 0, /**< Choose native backend with fallback. */
- YASL_BACKEND_WAYLAND, /**< Require Wayland. */
- YASL_BACKEND_X11, /**< Require X11. */
- YASL_BACKEND_COCOA, /**< Require Cocoa. */
-};
-
-/** Display options. Zero-initialize for automatic backend selection. */
-struct yasl_display_spec {
- /** Copied application identifier, conventionally a reverse-domain UTF-8 string; NULL uses backend defaults. */
- const char *app_id;
- /** Copied optional display callbacks; NULL disables them. */
- const struct yasl_display_cbs *cbs;
- /** Borrowed display callback userdata. */
- void *ud;
-
- /** Zero/AUTO chooses native backend; explicit choices never fall back. */
- enum yasl_backend backend;
-};
-
-/* Return NULL and set errno if the requested backend cannot open. */
-/**
- * Open a desktop connection and its event machinery.
- * @param loop Borrowed loop, or NULL to create a display-owned loop.
- * @param spec Copied options, or NULL for automatic backend selection and defaults.
- * @return An owned display, or NULL with errno set. EINVAL means an invalid backend;
- * ENOSYS means the requested backend was not built; ENODEV is the fallback when
- * opening fails without a more specific platform error. Explicit choices never
- * fall back. Close with yasl_display_close() after destroying its surfaces.
- */
-YASL_API struct yasl_display *yasl_display_open(struct yasl_loop *loop,
- const struct yasl_display_spec *spec);
-/**
- * Read the selected backend.
- * @param d Display, or NULL.
- * @return The actual backend, or YASL_BACKEND_AUTO for NULL.
- */
-YASL_API enum yasl_backend yasl_display_backend(const struct yasl_display *d);
-/**
- * Close a display and release its owned loop, if any.
- * @param d Display to close, or NULL for no action.
- * Destroy all surfaces first. Cancels an active drag and may invoke its end
- * listener. Must not be called during dispatch or from a callback.
- */
-YASL_API void yasl_display_close(struct yasl_display *d);
-/**
- * Query currently available optional features.
- * @param d Display, or NULL.
- * @return A bitmask of yasl_display_cap values, or zero for NULL.
- * Capabilities describe backend/server support, not attached input hardware or
- * permission to perform an operation at any arbitrary moment.
- */
-YASL_API uint32_t yasl_display_caps(const struct yasl_display *d);
-/* Process events, waiting at most timeout_ms: zero polls, negative waits.
- * Pending input or redraw work returns immediately. Returns -1 on failure. */
-/**
- * Receive events and run ready loop sources.
- * @param d Display to dispatch.
- * @param timeout_ms Maximum wait in milliseconds: zero polls, negative waits indefinitely.
- * @return A nonnegative backend-specific work count on success, or -1 with errno
- * set on failure (EINVAL for NULL, EIO if no specific backend error is available).
- * Do not interpret the count as the number of queued input events. Pending input
- * or runnable redraw work prevents waiting. Drain input and call
- * yasl_display_flush() after updating application state. Do not dispatch recursively.
- */
-YASL_API int yasl_display_dispatch(struct yasl_display *d, int timeout_ms);
-/**
- * Draw scheduled surfaces and send pending display requests.
- * @param d Display, or NULL for no action.
- * May synchronously invoke draw and other callbacks. A paced surface may wait
- * for its next display/compositor signal. This is not a GPU completion wait.
- */
-YASL_API void yasl_display_flush(struct yasl_display *d);
-/**
- * Read the latest modifier state known to the backend.
- * @param d Display, or NULL.
- * @return A bitmask of yasl_mod values, or zero for NULL.
- * For an individual event use its own mods field instead.
- */
-YASL_API int yasl_display_modifiers(const struct yasl_display *d);
-/** Double-click interval used when the system reports none. */
-#define YASL_DOUBLE_CLICK_MS_DEFAULT 400
-/**
- * Read the system's double-click interval.
- * @param d Display, or NULL.
- * @return Maximum milliseconds between the clicks of a double click, or
- * YASL_DOUBLE_CLICK_MS_DEFAULT when d is NULL or the system reports none.
- * X11 reads the XSETTINGS Net/DoubleClickTime value. Wayland, and X11 without
- * XSETTINGS, read the KDE or GNOME setting through the XDG Settings portal,
- * which needs D-Bus and can wait briefly. Cocoa reads the system interval.
- * The user can change it at any time; read it again when a window gains focus
- * rather than on every click.
- */
-YASL_API int yasl_display_double_click_ms(const struct yasl_display *d);
-/* Unsupported/invalid selections are no-ops, never clipboard aliases. */
-/**
- * Offer a copy of a NUL-terminated UTF-8 string as a selection.
- * @param d Display, or NULL for no action.
- * @param sel YASL_CLIPBOARD or YASL_PRIMARY.
- * @param text Text copied during this call; NULL does nothing.
- * Unsupported selections do nothing. The void return does not confirm that the
- * system accepted the offer; Wayland may require a recent input serial.
- */
-YASL_API void yasl_display_copy(struct yasl_display *d, enum yasl_selection sel, const char *text);
-/**
- * Request text delivery to a particular surface.
- * @param d Display that owns target.
- * @param sel YASL_CLIPBOARD or YASL_PRIMARY.
- * @param target Destination surface; NULL or a surface on another display does nothing.
- * Results arrive as YASL_EVENT_PASTE, possibly during a later dispatch. No result
- * is promised for unavailable data or a failed transfer. Destroying target cancels
- * delivery. Unsupported selections do nothing.
- */
-YASL_API void yasl_display_paste(struct yasl_display *d, enum yasl_selection sel, struct yasl_surface *target);
-
-/* A successful drag invokes the copied listener's non-NULL end once, including
- * cancel and display close. Failed starts do not invoke it. */
-/**
- * Start a surface drag from a recent pointer press.
- * @param d Display that owns origin.
- * @param origin Origin surface.
- * @param image Optional copied premultiplied ARGB8888 drag image, or NULL.
- * @param l Optional copied completion listener, or NULL.
- * @param ud Borrowed listener userdata until completion.
- * @return true if started; false if unsupported, invalid, or not currently permitted.
- * A successful start invokes a non-NULL end callback exactly once, including
- * cancellation or display close. Failed starts do not invoke it. This API carries
- * surfaces, not arbitrary MIME payloads; use application state to identify the item.
- */
-YASL_API bool yasl_display_drag_start(struct yasl_display *d, struct yasl_surface *origin,
- const struct yasl_drag_image *image,
- const struct yasl_drag_listener *l, void *ud);
-/**
- * Cancel the active surface drag, if any.
- * @param d Display, or NULL for no action.
- * May invoke the end listener synchronously.
- */
-YASL_API void yasl_display_drag_cancel(struct yasl_display *d);
-
-/* Surface Lifecycle */
-/** Toplevel options. Zero-initialize, then supply a positive logical-pixel size. */
-struct yasl_window_spec {
- /** Copied UTF-8 title; NULL uses backend defaults. */
- const char *title;
- /** Requested logical-pixel width and height; both must be positive. */
union {
- struct yasl_vector2i size_logical; /**< Requested logical-pixel extent. */
- struct yasl_vector2i size; /**< Migration alias for size_logical. */
+ struct { int width,height,pixel_width,pixel_height; double scale; unsigned state; } window;
+ struct { enum yasl_key key; enum yasl_key_action action; unsigned mods;
+ uint32_t codepoint, shifted, native_code; } key;
+ struct { const char *data; size_t length; } text;
+ struct { double x,y,dx,dy; enum yasl_pointer_action action; unsigned button,buttons,mods; } pointer;
+ struct { double x,y,lines_x,lines_y,pixels_x,pixels_y; unsigned valid,source,phase,mods; bool momentum; } scroll;
+ struct { uint64_t device_id,tool_id; double x,y,pressure,tilt_x,tilt_y,rotation,distance,tangential,wheel_degrees;
+ unsigned axes_valid,axes_changed,buttons,changed_button,tool,action; bool in_contact; } pen;
+ struct { const char *data; size_t length; int begin,end; bool active; uint64_t revision,generation; } composition;
+ struct { const char *data; size_t length,begin,end; uint64_t revision,generation; } text_edit;
+ struct { const char *data; size_t length; uint64_t request_id; enum yasl_transfer_status status; } clipboard;
+ /** DATA carries a text/uri-list for yasl_drop_next_path; x/y are set for OVER. */
+ struct { enum yasl_drop_action action; double x,y; const char *data; size_t length; } drop;
+ struct { enum yasl_drag_action action; double x,y; } drag;
};
- /** Request initial fullscreen; actual state is reported asynchronously. */
- bool fullscreen;
- /** Permit unpaced presentation where supported; a hint, not a guarantee. */
- bool tearing;
- /** Copied optional window callbacks; NULL disables them. */
- const struct yasl_window_cbs *cbs;
- /** Borrowed window callback userdata; ignored by the runner. */
- void *ud;
- /** Borrowed application data, independent of callbacks and available in either loop style. */
- void *userdata;
};
-
-/** Popup options, entirely in device pixels, including size.
-The content rectangle excludes transparent margins/shadows used for placement.
-An axis of content_size equal to zero extends to that axis of size. The offset
-and resolved content size must fit in size. Anchor extents must be nonnegative.
-Dimensions must be positive, at most 32767, and fit an INT32_MAX-byte buffer;
-backends may impose further limits after scaling or resolving placement. */
-struct yasl_popup_spec {
- /** Full popup framebuffer extent in device pixels, including transparent margins. */
- struct yasl_vector2i size;
- /** Rectangle in parent framebuffer coordinates, in device pixels. */
- struct yasl_rect2i anchor;
- /** true prefers right of anchor; false prefers below. Placement may flip/slide. */
- bool beside;
- /** Top-left content offset within the popup, in device pixels. */
- struct yasl_vector2i content_offset;
- /** Content extent; zero per axis extends to the corresponding size edge. */
- struct yasl_vector2i content_size;
-};
-
-/**
- * Create a resizable desktop window with CPU drawing targets.
- * @param d Owning display.
- * @param spec Required copied options; size is in logical pixels.
- * @return An owned surface, or NULL with errno set. EINVAL means invalid options,
- * including a nonpositive dimension, a dimension above 32767, or a buffer above
- * INT32_MAX bytes. ENODEV is the fallback backend failure. Actual configured
- * size may differ from the request. The callback table in spec->cbs is copied;
- * spec->ud stays borrowed until callbacks are replaced or the surface is destroyed.
- * This window's callbacks cannot run before creation returns. Use
- * yasl_surface_geometry() for initial geometry; an initial configure callback
- * is not guaranteed. Schedule an initial redraw after setting up application state.
- * On a display owned by yasl_run(), the runner installs its own callbacks instead;
- * use yasl_app_desc.event and yasl_app_desc.frame for application notifications.
- */
-YASL_API struct yasl_surface *yasl_surface_create_toplevel(struct yasl_display *d,
- const struct yasl_window_spec *spec);
-/**
- * Create an owned popup attached to a parent surface.
- * @param parent Borrowed parent; destroy the popup before the parent.
- * @param spec Required copied options, entirely in device pixels.
- * @return A popup, or NULL with errno set: EINVAL for invalid options, ENOTSUP
- * for missing popup support, or a backend error (ENODEV if none was supplied).
- * Wayland requires a recent input serial for its popup grab. The backend may
- * flip or slide placement to fit the screen. See yasl_popup_spec.
- */
-YASL_API struct yasl_surface *yasl_surface_create_popup(struct yasl_surface *parent,
- const struct yasl_popup_spec *spec);
-/**
- * Update a popup's geometry and placement.
- * @param popup An existing popup.
- * @param spec Required copied replacement options, in device pixels.
- * @return true on success; false with errno set: EINVAL for invalid options,
- * ENOTSUP for missing popup support, or a backend error (ENODEV if unspecified).
- * Older Wayland popup protocol versions can reject repositioning.
- */
-YASL_API bool yasl_surface_popup_reposition(struct yasl_surface *popup,
- const struct yasl_popup_spec *spec);
-/**
- * Destroy a surface and cancel its surface timers and pending input.
- * @param s Surface, or NULL for no action.
- * Destroy child popups first. May be called from a surface callback; return from
- * that callback without further use of the surface or its draw target. Every
- * pointer or native handle obtained from this surface becomes invalid.
- */
-YASL_API void yasl_surface_destroy(struct yasl_surface *s);
-/**
- * Get the display that owns a surface.
- * @param s Surface, or NULL.
- * @return A borrowed display, or NULL.
- */
-YASL_API struct yasl_display *yasl_surface_display(const struct yasl_surface *s);
-
-/**
- * Replace the surface's callback table and userdata.
- * @param s Surface.
- * @param cbs Table copied by value; NULL removes all callbacks. NULL members are ignored.
- * @param ud Borrowed userdata passed to the installed callbacks.
- * @return true if replaced; false with EINVAL for NULL, EBUSY on a runner-owned surface.
- * This call only replaces callbacks; it does not invoke them.
- * Use yasl_surface_geometry() to read current geometry; do not rely on receiving
- * an initial configure callback when registering.
- */
-YASL_API bool yasl_surface_set_callbacks(struct yasl_surface *s,
- const struct yasl_window_cbs *cbs, void *ud);
-/**
- * Replace the window title with copied UTF-8 text.
- * @param s Surface.
- * @param title NUL-terminated UTF-8 title. Pass an empty string to clear it.
- * Backends may truncate the title.
- */
-YASL_API void yasl_surface_set_title(struct yasl_surface *s, const char *title);
-/**
- * Request a future draw callback, coalescing repeated requests.
- * @param s Surface, or NULL for no action.
- * Call yasl_display_flush() to service the request. Schedule again from draw to
- * animate. Without YASL_CAP_FRAME_PACING, throttle animation with a timer.
- */
-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 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. See yasl/native.h for native rendering. */
-/**
- * Submit the current draw target at most once.
- * @param s Surface currently being drawn.
- * @param fb Exact target from the current draw callback, including its generation.
- * @param damage Required damage hint: n is -1 for all pixels or 0..YASL_DAMAGE_MAX.
- * @return true if accepted; false for invalid, stale, already presented, or failed targets.
- * Rectangles must have nonnegative extents and are clipped to the target. Invalid
- * input does not consume the frame. All pixels must be initialized even with
- * partial damage. The backend may upload all pixels. Success records submission,
- * not confirmed scanout. The target expires when draw returns or s is destroyed.
- */
-YASL_API bool yasl_surface_present(struct yasl_surface *s, const struct yasl_framebuffer *fb,
- const struct yasl_damage_list *damage);
-/**
- * Migration adapter: consume one input event for a surface from the display FIFO.
- * Popup input can belong to the root queue; inspect ev->surface. Returns false
- * for empty/invalid arguments, leaving ev unchanged. Strings remain borrowed
- * until the next successful display or surface poll, or display close. Pending
- * recipient events are canceled on destruction. Prefer yasl_display_poll_event()
- * to receive window, composition, and display events as well as input. This
- * input-only adapter discards pending non-input events across the display
- * (legacy callbacks already delivered lifecycle changes). Do not mix
- * the two polling styles in one application. Use the display thread.
- */
-YASL_API bool yasl_surface_poll_event(struct yasl_surface *s, struct yasl_event *ev);
-/**
- * Decode the next local file path from a YASL_EVENT_DROP payload.
- * @param cursor Required in/out position in the NUL-terminated list. Start it
- * at event.text.data; a NULL *cursor returns zero.
- * @param out Output for the NUL-terminated path, or NULL when cap is zero.
- * @param cap Size of out in bytes.
- * @return Path length in bytes, excluding the NUL, or zero when no paths remain.
- * When the result is less than cap, out holds the path and *cursor moves past
- * it. Otherwise out and *cursor are unchanged; call again with a buffer of at
- * least the result plus one.
- * Accepts file:///path, file:/path, and file://host/path when host is
- * localhost or this machine's name. Percent escapes decode to raw bytes, and
- * a '?' or '#' ends the path. Skips blank lines, comments, other schemes,
- * other hosts, and lines with a malformed escape or an escaped NUL. May be
- * called from any thread.
- */
-YASL_API size_t yasl_drop_next_path(const char **cursor, char *out, size_t cap);
-/**
- * Copy the last frame presented from the surface's CPU target.
- * @param s Surface.
- * @param out Output for size->x * size->y premultiplied ARGB8888 pixels with
- * tightly packed rows, or NULL when cap is zero.
- * @param cap Capacity of out in pixels.
- * @param size Required output: the frame extent in device pixels, or zero when
- * no frame is available.
- * @return true if copied. false leaves out unchanged; when *size is nonzero,
- * out was too small, so allocate size->x * size->y pixels and call again.
- * A frame is available from a successful yasl_surface_present() until the
- * next draw callback starts, and again once that draw presents. After a draw
- * that does not present or a resize that replaces the target, no frame may be
- * available; native rendering never has one. Call outside draw callbacks. This copies YASL's frame, not
- * the composited screen: decorations, other windows, and color conversion are
- * not included.
- */
-YASL_API bool yasl_surface_read_pixels(struct yasl_surface *s, uint32_t *out, size_t cap,
- struct yasl_vector2i *size);
-/**
- * Select absolute or relative (locked) pointer input for a surface.
- * @param s Surface.
- * @param mode YASL_POINTER_NORMAL or YASL_POINTER_RELATIVE.
- * @return true if the mode is supported; false leaves the current mode.
- * RELATIVE hides the cursor and locks it while the surface is focused;
- * POINTER_MOTION then carries unbounded delta. Returning to NORMAL restores
- * the cursor selected with yasl_surface_set_cursor(). RELATIVE is supported on
- * Wayland compositors with the relative-pointer and pointer-constraints
- * protocols; X11 and Cocoa return false.
- */
-YASL_API bool yasl_surface_set_pointer_mode(struct yasl_surface *s, enum yasl_pointer_mode mode);
-
-/**
- * Consume one event from the display-wide FIFO without waiting.
- * Returns false for an empty queue or invalid arguments, leaving ev unchanged.
- * Strings remain valid until the next successful poll or display close.
- * Surface destruction cancels undelivered events, not the last polled payload.
- * Use the display thread. Do not mix display and surface polling in one app.
- */
-YASL_API bool yasl_display_poll_event(struct yasl_display *d, struct yasl_event *ev);
-
-/** Stable nonzero identity within a display; zero for NULL. Use on the display thread. */
-YASL_API uint64_t yasl_surface_id(const struct yasl_surface *s);
-/** Store borrowed application data independently of callback userdata. */
-YASL_API void yasl_surface_set_userdata(struct yasl_surface *s, void *userdata);
-/** Read borrowed application data, or NULL for NULL; use on the display thread. */
-YASL_API void *yasl_surface_userdata(const struct yasl_surface *s);
-
-/** Thread-safe message descriptor. Zero target_id means display-wide. */
-struct yasl_message {
- uint64_t target_id; /**< Surface identity, or zero for the display. */
- uint32_t code; /**< Application-defined message code. */
- void *payload; /**< Borrowed until release; passed through unchanged. */
- size_t size; /**< Application-defined payload length. */
- /** Optional cleanup on display thread after delivery/cancellation, exactly once.
- * May post messages, but must not dispatch, poll, or destroy YASL objects. */
- void (*release)(void *payload);
-};
-/**
- * Copy and enqueue a message from any thread; the display must stay alive.
- * Stop producer threads before closing the display. On success release runs
- * once after consumption or cancellation. On failure ownership stays with the
- * caller; errno is EINVAL, ENOENT (retired identity), ENOMEM, or EOVERFLOW.
- */
-YASL_API bool yasl_display_post(struct yasl_display *d, const struct yasl_message *message);
-
-/**
- * Present the active frame once. NULL/0 means full damage; non-NULL/0 means none.
- * Validate all rectangles; excess rectangles fall back to full damage.
- * Returns false with EINVAL for invalid/stale targets, EALREADY for a consumed
- * frame, or errno from the backend (EIO if unspecified).
- * Frame and pixels expire at callback return; use the display thread.
- */
-YASL_API bool yasl_frame_present(struct yasl_frame *frame,
- const struct yasl_rect2i *rects, size_t count);
-/** Coalesce a redraw request; use on the display thread. NULL is ignored. */
-YASL_API void yasl_surface_request_frame(struct yasl_surface *s);
-/** Set drawing policy for either loop style. Returns false with errno on failure. */
-YASL_API bool yasl_surface_set_pacing(struct yasl_surface *s, yasl_pacing_mode mode);
-
-/** Request a positive logical-pixel size. Success means issued, not configured. */
-YASL_API bool yasl_surface_set_size(struct yasl_surface *s, struct yasl_vector2i size_logical);
-/** Request fullscreen state; returns acceptance, not confirmation. */
-YASL_API bool yasl_surface_set_fullscreen(struct yasl_surface *s, bool enabled);
-/** Request maximized state; returns acceptance, not confirmation. */
-YASL_API bool yasl_surface_set_maximized(struct yasl_surface *s, bool enabled);
-/** Request minimization. Window requests set errno on failure; display thread only. */
-YASL_API bool yasl_surface_minimize(struct yasl_surface *s);
-
-/** Offer copied UTF-8 text. Returns false with errno if invalid/unsupported/failed. */
-YASL_API bool yasl_clipboard_set(struct yasl_display *d, enum yasl_selection selection,
- const char *text);
-/**
- * Request text; returns a nonzero ID or zero with errno. One PASTE completion
- * follows each accepted request unless its surface/display is destroyed.
- * Inspect paste.status even when data is empty. Use the display thread.
- */
-YASL_API uint64_t yasl_clipboard_request(struct yasl_surface *s, enum yasl_selection selection);
-
-/* Current device-pixel size and scale, matching the configure callback. */
-/**
- * Read current device-pixel size and scale together.
- * @param s Surface, or NULL.
- * @return Geometry matching configure callbacks; NULL gives zero size and unit scale.
- */
-YASL_API struct yasl_geometry yasl_surface_geometry(const struct yasl_surface *s);
-/**
- * Read current window state.
- * @param s Surface, or NULL.
- * @return A bitmask of yasl_surface_state values, or zero for NULL.
- * Flags are reported state, not requests; unsupported states are absent.
- * Flags may coexist. Windowed and floating have no separate flags. Suspension
- * does not imply minimization, and no minimized flag is reported.
- */
-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
- * YASL_CAP_FRAME_PACING, redraws run on flush without display synchronization.
- * Tearing may bypass pacing even when the capability is present. */
-/**
- * Read frame timing estimates and their provenance.
- * @param s Surface, or NULL.
- * @return Current timing, or a zero-initialized result for NULL.
- * Timestamps use monotonic nanoseconds. Inspect source before treating a timestamp
- * as confirmation of presentation. Refresh and next-present values are estimates.
- */
-YASL_API struct yasl_timing yasl_surface_timing(const struct yasl_surface *s);
-/**
- * Get a nondecreasing animation timestamp aligned to estimated refresh.
- * @param s Surface, or NULL.
- * @param now Current monotonic nanoseconds, usually from yasl_loop_now_ns().
- * @return Animation timestamp, or zero for NULL. Before timing is known, returns now.
- * Use this to advance animations; it is not presentation feedback.
- */
-YASL_API uint64_t yasl_surface_frame_time_ns(struct yasl_surface *s, uint64_t now);
-/* Set the mouse and tablet cursor for this surface, including future entries.
- * YASL_CURSOR_HIDDEN stays hidden until another cursor is selected. */
-/**
- * Select the surface's system mouse and tablet cursor.
- * @param s Surface.
- * @param cursor Cursor shape; YASL_CURSOR_HIDDEN hides the cursor without disabling input.
- * The choice persists across motion and re-entry until another shape is selected.
- */
-YASL_API void yasl_surface_set_cursor(struct yasl_surface *s, enum yasl_cursor cursor);
-/**
- * Set a backend window background hint.
- * @param s Surface.
- * @param bg Packed 0xAARRGGBB color; backends may ignore alpha or the entire hint.
- * Does not initialize framebuffer pixels or replace drawing.
- */
-YASL_API void yasl_surface_set_background_color(struct yasl_surface *s, uint32_t bg);
-
-/* IME Support: preedit is borrowed until the next dispatch or destruction. */
-/**
- * Read the current uncommitted UTF-8 composition text.
- * @param s Surface, or NULL.
- * @return Borrowed NUL-terminated text, or NULL if absent/unsupported.
- * Copy to retain across the next dispatch or surface destruction. Composition
- * changes can schedule a redraw. Insert committed YASL_EVENT_TEXT into documents,
- * not preedit text.
- */
-YASL_API const char *yasl_surface_ime_preedit(const struct yasl_surface *s);
-/**
- * Read the cursor/selection range in the preedit string.
- * @param s Surface.
- * @param begin Required output UTF-8 byte offset for the range start.
- * @param end Required output UTF-8 byte offset for the range end.
- * @return true if available; false without changing outputs otherwise.
- * Currently available on Wayland; Cocoa preedit text has no range result.
- */
-YASL_API bool yasl_surface_ime_preedit_cursor(const struct yasl_surface *s, int *begin, int *end);
-/**
- * Place the composition candidate window near the application caret.
- * @param s Surface.
- * @param caret Caret rectangle relative to the surface, in device pixels.
- * Update after caret motion or scale changes. Unsupported backends ignore it.
- */
-YASL_API void yasl_surface_set_ime_caret(struct yasl_surface *s, struct yasl_rect2i caret);
-
-/* Client-Side Decorations (CSD) Actions */
-/**
- * Ask the window system to begin an interactive move.
- * @param s Toplevel surface, normally during handling of a pointer press.
- * @return true if the request was issued; false if unsupported or not permitted.
- * A recent input serial may be required. Success does not confirm a final position.
- */
-YASL_API bool yasl_surface_start_interactive_move(struct yasl_surface *s);
-/**
- * Ask the window system to begin an interactive resize.
- * @param s Toplevel surface, normally during handling of a pointer press.
- * @param edge One nonzero yasl_resize_edge enumerator.
- * @return true if issued; false for an invalid edge, missing support, or rejected request.
- */
-YASL_API bool yasl_surface_start_interactive_resize(struct yasl_surface *s, enum yasl_resize_edge edge);
-/**
- * Ask the window system to display its window management menu.
- * @param s Toplevel surface.
- * @param pos Surface-relative position in device pixels.
- * @return true if issued; false if unsupported or not currently permitted.
- */
-YASL_API bool yasl_surface_show_window_menu(struct yasl_surface *s, struct yasl_vector2i pos);
-
-/* Drag Support */
-/**
- * Attach a toplevel surface to the current surface drag.
- * @param s Surface to carry; check YASL_CAP_DRAG_CARRY first.
- * @param offset Device-pixel offset of the pointer within the carried surface.
- * @return true if accepted; false if unsupported or no compatible drag is active.
- */
-YASL_API bool yasl_surface_drag_carry(struct yasl_surface *s, struct yasl_vector2i offset);
-/**
- * Place a toplevel surface relative to the current pointer.
- * @param s Surface; check YASL_CAP_PLACE_WINDOW first.
- * @param at Device-pixel position within the surface to place under the pointer.
- * @return true if issued; false if unsupported or unavailable.
- */
-YASL_API bool yasl_surface_place_under_pointer(struct yasl_surface *s, struct yasl_vector2i at);
-
+/** Last error on this thread; success does not clear it. */
+YASL_API enum yasl_error yasl_get_error(const char **description);
+YASL_API int yasl_get_native_error(void);
+/** Only before the first surface is created. */
+YASL_API bool yasl_set_app_id(const char *app_id);
+YASL_API bool yasl_set_backend(enum yasl_backend backend);
+/** Flags zero creates a surface for your own Vulkan or Metal renderer. */
+YASL_API yasl_surface *yasl_surface_create(const char *title, int width, int height, unsigned flags);
+/** Also destroys its popups. */
+YASL_API void yasl_surface_destroy(yasl_surface *surface);
+/** Destroys all surfaces. Release your GPU objects first. */
+YASL_API void yasl_shutdown(void);
+/** 1 event, 0 none (timeout or wake), -1 failure. timeout_ms zero polls, negative
+ * waits forever. Without an event, out->type is NONE. */
+YASL_API int yasl_wait_event(yasl_event *out, int timeout_ms);
+/** Makes a waiting yasl_wait_event return. Thread-safe. */
+YASL_API void yasl_wake(void);
+YASL_API uint64_t yasl_time_ns(void);
+YASL_API enum yasl_backend yasl_surface_backend(const yasl_surface *surface);
+YASL_API unsigned yasl_surface_features(const yasl_surface *surface);
+YASL_API void yasl_surface_get_size(const yasl_surface *surface, int *width, int *height);
+YASL_API void yasl_surface_get_framebuffer_size(const yasl_surface *surface, int *width, int *height);
+YASL_API double yasl_surface_get_scale(const yasl_surface *surface);
+YASL_API unsigned yasl_surface_state(const yasl_surface *surface);
+YASL_API void *yasl_surface_userdata(const yasl_surface *surface);
+YASL_API void yasl_surface_set_userdata(yasl_surface *surface, void *userdata);
+YASL_API bool yasl_surface_set_title(yasl_surface *surface, const char *title);
+/** Requests; the result arrives as a WINDOW event. */
+YASL_API bool yasl_surface_request_size(yasl_surface *surface, int width, int height);
+YASL_API bool yasl_surface_request_fullscreen(yasl_surface *surface, bool enabled);
+YASL_API bool yasl_surface_request_maximized(yasl_surface *surface, bool enabled);
+YASL_API bool yasl_surface_request_minimize(yasl_surface *surface);
+YASL_API bool yasl_surface_set_cursor(yasl_surface *surface, enum yasl_cursor cursor);
+YASL_API bool yasl_surface_set_pointer_mode(yasl_surface *surface, enum yasl_pointer_mode mode);
+/** Draws during native modal loops such as a live resize. The callback may render
+ * but must not wait, create or destroy surfaces, or shut down. */
+YASL_API void yasl_surface_set_refresh_callback(yasl_surface *surface, void (*refresh)(yasl_surface *,void *), void *userdata);
+YASL_API int yasl_double_click_ms(void);
+YASL_API bool yasl_clipboard_set(enum yasl_selection selection, const char *text);
+/** Returns a request ID; the text arrives as a CLIPBOARD event. Zero on failure. */
+YASL_API uint64_t yasl_clipboard_request(yasl_surface *target, enum yasl_selection selection);
+/** IME support for a text field. */
+YASL_API bool yasl_surface_set_text_input(yasl_surface *surface, bool active, enum yasl_text_purpose purpose);
+/** UTF-8; selection offsets are bytes. */
+YASL_API bool yasl_surface_set_surrounding_text(yasl_surface *surface, const char *text, size_t length,
+ size_t selection_begin, size_t selection_end, uint64_t revision);
+YASL_API bool yasl_surface_set_ime_caret(yasl_surface *surface, double x, double y, double width, double height);
+/** Anchor picks a point on the x/y/anchor rectangle of the parent; gravity is the
+ * direction the popup grows. Functions taking a trigger need a recent press event. */
+YASL_API yasl_surface *yasl_popup_create(yasl_surface *parent, int width, int height,
+ double x, double y, double anchor_width, double anchor_height, enum yasl_popup_edge anchor,
+ enum yasl_popup_edge gravity, unsigned constraints, const yasl_event *trigger);
+YASL_API bool yasl_popup_reposition(yasl_surface *popup, int width, int height,
+ double x, double y, double anchor_width, double anchor_height, enum yasl_popup_edge anchor,
+ enum yasl_popup_edge gravity, unsigned constraints);
+YASL_API bool yasl_surface_start_interactive_move(yasl_surface *surface, const yasl_event *trigger);
+YASL_API bool yasl_surface_start_interactive_resize(yasl_surface *surface, enum yasl_resize_edge edge, const yasl_event *trigger);
+YASL_API bool yasl_surface_show_window_menu(yasl_surface *surface, double x, double y, const yasl_event *trigger);
+YASL_API bool yasl_drag_start(yasl_surface *origin, const yasl_event *trigger,
+ const uint32_t *pixels, int width, int height, int hotspot_x, int hotspot_y);
+YASL_API void yasl_drag_cancel(void);
+YASL_API bool yasl_surface_drag_carry(yasl_surface *surface, double x, double y);
+YASL_API bool yasl_surface_place_under_pointer(yasl_surface *surface, double x, double y);
+YASL_API size_t yasl_drop_next_path(const char **cursor, char *out, size_t capacity);
#ifdef __cplusplus
}
#endif
-
-#endif /* YASL_H */
+#endif