summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-12 22:12:02 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-12 22:12:02 +0300
commit94c5e361fbb229b0cd6853e2102a7d95f1f358b3 (patch)
tree3c0f11af9dcb84dac8067a31a6979acd6dd56fbf /include
parent08dc9047098d6d96791024ac7d8f5837633673ef (diff)
better public interface and doxygen
Diffstat (limited to 'include')
-rw-r--r--include/yasl/keycodes.h149
-rw-r--r--include/yasl/loop.h117
-rw-r--r--include/yasl/native.h49
-rw-r--r--include/yasl/native/cocoa.h33
-rw-r--r--include/yasl/native/wayland.h20
-rw-r--r--include/yasl/native/x11.h22
-rw-r--r--include/yasl/timing.h26
-rw-r--r--include/yasl/yasl.h614
8 files changed, 918 insertions, 112 deletions
diff --git a/include/yasl/keycodes.h b/include/yasl/keycodes.h
new file mode 100644
index 0000000..7586945
--- /dev/null
+++ b/include/yasl/keycodes.h
@@ -0,0 +1,149 @@
+/**
+ * @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_INPUT_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.
+ */
+#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. */
+};
+
+#endif /* YASL_KEYCODES_H */
diff --git a/include/yasl/loop.h b/include/yasl/loop.h
index a65fa12..9faa8f7 100644
--- a/include/yasl/loop.h
+++ b/include/yasl/loop.h
@@ -1,3 +1,14 @@
+/**
+ * @file
+ * Optional event loop, file watches, and timers.
+ *
+ * Use the loop's owning thread for all calls and callbacks, except
+ * yasl_loop_now_ns(). 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
@@ -10,33 +21,139 @@ extern "C" {
/* 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, and its timers.
+ * @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.
+ */
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);
+/**
+ * Signal the loop's wake pipe without dispatching callbacks.
+ * @param l Loop, or NULL for no action.
+ * Multiple signals may coalesce. This does not schedule a redraw or enqueue an
+ * event, and it does not provide a cross-thread application messaging contract.
+ */
YASL_API void yasl_loop_kick(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
diff --git a/include/yasl/native.h b/include/yasl/native.h
index f7e3020..d65f8d3 100644
--- a/include/yasl/native.h
+++ b/include/yasl/native.h
@@ -1,3 +1,12 @@
+/**
+ * @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
@@ -15,25 +24,61 @@ extern "C" {
* 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 toplevel options, with logical-pixel size.
+ * @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.
+ */
YASL_API struct yasl_surface *yasl_surface_create_native(struct yasl_display *d,
const struct yasl_surface_spec *spec, void *graphics_device);
+/** Borrowed native drawable for the current draw target, currently Cocoa/Metal. */
struct yasl_native_frame {
- void *drawable; /* id<CAMetalDrawable> on Cocoa */
- bool transaction; /* CAMetalLayer.presentsWithTransaction */
+ /** 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);
diff --git a/include/yasl/native/cocoa.h b/include/yasl/native/cocoa.h
index 9066a19..9b221cf 100644
--- a/include/yasl/native/cocoa.h
+++ b/include/yasl/native/cocoa.h
@@ -1,3 +1,7 @@
+/**
+ * @file
+ * Typed borrowed Cocoa handles; available on macOS. Use on the main thread.
+ */
#ifndef YASL_NATIVE_COCOA_H
#define YASL_NATIVE_COCOA_H
@@ -8,9 +12,9 @@
@class NSWindow;
@class NSView;
#else
-typedef struct objc_object NSApplication;
-typedef struct objc_object NSWindow;
-typedef struct objc_object NSView;
+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++. */
#endif
#ifdef __cplusplus
@@ -18,9 +22,30 @@ extern "C" {
#endif
/* Return borrowed Cocoa handles (expire on display/surface destruction).
- * Return NULL / nil if display/surface is not a Cocoa object or destroyed. */
+ * 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);
#ifdef __cplusplus
diff --git a/include/yasl/native/wayland.h b/include/yasl/native/wayland.h
index 4a759d4..b11e3b8 100644
--- a/include/yasl/native/wayland.h
+++ b/include/yasl/native/wayland.h
@@ -1,3 +1,7 @@
+/**
+ * @file
+ * Typed borrowed Wayland handles; available when built with Wayland support.
+ */
#ifndef YASL_NATIVE_WAYLAND_H
#define YASL_NATIVE_WAYLAND_H
@@ -11,8 +15,22 @@ 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 destroyed. */
+ * 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);
#ifdef __cplusplus
diff --git a/include/yasl/native/x11.h b/include/yasl/native/x11.h
index c0105cb..b719b4b 100644
--- a/include/yasl/native/x11.h
+++ b/include/yasl/native/x11.h
@@ -1,3 +1,7 @@
+/**
+ * @file
+ * Typed borrowed X11 handles; available when built with X11 support.
+ */
#ifndef YASL_NATIVE_X11_H
#define YASL_NATIVE_X11_H
@@ -8,11 +12,25 @@
extern "C" {
#endif
-typedef struct _XDisplay Display;
+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 destroyed. */
+ * 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);
#ifdef __cplusplus
diff --git a/include/yasl/timing.h b/include/yasl/timing.h
index d443bf6..7e4af9e 100644
--- a/include/yasl/timing.h
+++ b/include/yasl/timing.h
@@ -1,3 +1,8 @@
+/**
+ * @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
@@ -7,27 +12,40 @@
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,
- YASL_TIMING_SUBMISSION, /* CPU submission time; not scanout confirmation */
- YASL_TIMING_FRAME_CALLBACK, /* compositor pacing callback, not scanout */
- YASL_TIMING_PRESENTATION, /* compositor-confirmed presentation */
+ 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;
};
diff --git a/include/yasl/yasl.h b/include/yasl/yasl.h
index df94800..f40264e 100644
--- a/include/yasl/yasl.h
+++ b/include/yasl/yasl.h
@@ -1,3 +1,26 @@
+/**
+ * @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.
+ *
+ * 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 dispatch/poll/flush cycle and backend limits.
+ */
#ifndef YASL_H
#define YASL_H
@@ -9,11 +32,13 @@
#include <math.h>
#include "yasl/timing.h"
+#include "yasl/keycodes.h"
#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)
@@ -33,23 +58,46 @@ 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;
@@ -59,6 +107,11 @@ static inline int yasl_scale_to_device(double logical, uint32_t scale_120)
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;
@@ -73,219 +126,293 @@ static inline int yasl_scale_to_logical(int device, uint32_t scale_120)
}
/* Capabilities */
+/** Optional backend/server features, returned as a bitmask by yasl_display_caps(). */
enum yasl_display_cap : uint32_t {
- YASL_CAP_POPUPS = 1 << 0,
- YASL_CAP_DRAG = 1 << 1,
- YASL_CAP_DRAG_CARRY = 1 << 2,
- YASL_CAP_PLACE_WINDOW = 1 << 3,
- YASL_CAP_PRIMARY_SELECTION = 1 << 4,
- YASL_CAP_CSD = 1 << 5,
- YASL_CAP_NATIVE_GRAPHICS = 1 << 6,
- YASL_CAP_FRAME_PACING = 1 << 7, /* compositor/display-driven draws */
+ 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,
+ 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,
- YASL_PRIMARY,
+ 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,
- YASL_STATE_MAXIMIZED = 1 << 1,
- YASL_STATE_ACTIVATED = 1 << 2,
- YASL_STATE_SUSPENDED = 1 << 3,
- YASL_STATE_CSD = 1 << 4,
+ 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. */
};
+/** System cursor shapes. HIDDEN preserves pointer input; NONE is its compatibility alias. */
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, /* Hide the system cursor; pointer input is unchanged. */
- YASL_CURSOR_NONE = YASL_CURSOR_HIDDEN, /* Compatibility alias. */
-};
-
+ 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,
- 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,
+ 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
- * creation sizes use logical pixels. Damage is a hint: backends may upload
+ * 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 {
- int n; /* -1 means full repaint */
+ /** -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 {
- uint64_t generation; /* Opaque draw identity; preserve when copying target. */
+ /** 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;
};
+/** 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;
};
/* Drag and Drop */
+/** Target notifications for YASL surface drags, separate from external file drops. */
enum yasl_drag_event {
- YASL_DRAG_OVER,
- YASL_DRAG_LEAVE,
- YASL_DRAG_DROP,
+ 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,
- YASL_DROP_LEAVE,
+ 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,
- YASL_DRAG_CANCELLED,
+ 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,
- YASL_KEY_RELEASE,
- YASL_KEY_REPEAT,
+ 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,
- YASL_MOD_ALT = 1 << 1,
- YASL_MOD_CTRL = 1 << 2,
- YASL_MOD_SUPER = 1 << 3,
- YASL_MOD_CAPS = 1 << 4,
+ 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 transition or motion type; fields are meaningful according to this tag. */
enum yasl_pointer_kind {
- YASL_PTR_PRESS,
- YASL_PTR_RELEASE,
- YASL_PTR_MOTION,
- YASL_PTR_LEAVE,
- YASL_PTR_SCROLL,
+ YASL_PTR_PRESS, /**< Button/tip pressed. */
+ YASL_PTR_RELEASE, /**< Button/tip released. */
+ YASL_PTR_MOTION, /**< Position or tablet axes changed. */
+ YASL_PTR_LEAVE, /**< Pointer/tool left the surface. */
+ YASL_PTR_SCROLL, /**< Scroll sample. */
};
+/** Pointer source class; capability support does not imply an attached device. */
enum yasl_pointer_device {
- YASL_PTR_DEV_MOUSE,
- YASL_PTR_DEV_TOUCH,
- YASL_PTR_DEV_PEN,
- YASL_PTR_DEV_ERASER,
+ 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. */
};
+/** Normalized tablet axes; zero for unavailable axes and non-tablet devices. */
struct yasl_pointer_pen {
- uint16_t pressure; /* 0..65535, normalized to the device's pressure range. */
- int8_t tilt_x; /* Degrees, -90..90; positive toward the right. */
- int8_t tilt_y; /* Degrees, -90..90; positive toward the bottom. */
-};
-
+ /** 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;
+};
+
+/** 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. Native scancodes
+ * are backend-specific. Insert committed YASL_INPUT_TEXT into documents.
+ */
struct yasl_key_event {
- uint32_t key;
- uint32_t keypad;
+ /** 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;
- uint32_t base;
- uint32_t text;
+ /** Native code: Wayland evdev, X11 server keycode, Cocoa virtual keycode. */
+ uint32_t native_code;
};
+/** Pointer sample. Pen and eraser events share this structure with mouse input.
+Track contact with primary press/release, not pressure alone. Leave, focus loss,
+and YASL_INPUT_RESET must cancel held application input state. This is not a
+multi-contact touch API. Scroll offsets use fractional line units: positive x
+means right and positive y means down, after system scroll preferences. */
struct yasl_mouse_event {
+ /** Surface-relative device-pixel position. */
struct yasl_vector2i pos;
- int16_t button; /* Press/release: 0 = primary/tip, 1 = middle, 2 = secondary.
- * Motion/leave: informational; track presses and releases. */
- int16_t scroll_lines;
+ /** Press/release: 0 primary/tip, 1 middle, 2 secondary. Unused for scroll. */
+ int16_t button;
+ /** Sample type. */
enum yasl_pointer_kind kind;
+ /** Mouse, touch, pen, or eraser. */
enum yasl_pointer_device device;
+ /** yasl_mod bitmask at this event. */
uint32_t mods;
- float scroll_delta;
- /* Pen/eraser samples include the current axes, also on pressure-only
- * motion. Missing axes and non-tablet devices report zero. A primary
- * release or leave ends contact; zero pressure alone is not a release. */
+ /** Fractional line offsets, valid for SCROLL only; positive right/down. */
+ struct yasl_vector2d scroll;
+
+ /** Current tablet axes, including on pressure-only motion; missing axes are zero. */
struct yasl_pointer_pen pen;
};
+/** Input union tag. RESET has no payload and requires clearing held state. */
enum yasl_input_kind {
- YASL_INPUT_KEY,
- YASL_INPUT_MOUSE,
- YASL_INPUT_FOCUS,
- YASL_INPUT_PASTE,
- YASL_INPUT_DROP_FILES,
- YASL_INPUT_TEXT,
+ YASL_INPUT_KEY, /**< key member. */
+ YASL_INPUT_MOUSE, /**< mouse member. */
+ YASL_INPUT_FOCUS, /**< focus member. */
+ YASL_INPUT_PASTE, /**< paste member. */
+ YASL_INPUT_DROP_FILES, /**< drop_files member. */
+ YASL_INPUT_TEXT, /**< text member, containing committed UTF-8. */
/* The input stream was interrupted (e.g. allocation failure or device
* removal). Clear held keys/buttons and composition state. */
- YASL_INPUT_RESET,
+ YASL_INPUT_RESET, /**< No payload. Clear held keys/buttons and composition after an interruption. */
};
+/** Keyboard focus transition; cancel held state when focus is lost. */
struct yasl_focus_event {
+ /** true on focus gain, false on loss. */
bool focused;
};
+/** Committed UTF-8 text; insert this instead of deriving characters from key events. */
struct yasl_text_event {
+ /** Borrowed NUL-terminated UTF-8. */
const char *text;
+ /** Length in bytes excluding the terminating NUL. */
size_t len;
};
+/** UTF-8 text received from an explicit selection request. */
struct yasl_paste_event {
+ /** Borrowed NUL-terminated UTF-8. */
const char *text;
+ /** Length in bytes excluding the terminating NUL. */
size_t len;
};
+/** File URLs in text/uri-list form, separated by CRLF; not filesystem paths. */
struct yasl_drop_files_event {
+ /** Borrowed NUL-terminated text/uri-list; parse URLs and percent escapes. */
const char *files;
+ /** Length in bytes excluding the terminating NUL. */
size_t len;
};
+/** One tagged input event; read only the union member selected by kind.
+Payload strings follow yasl_surface_input_poll() lifetime rules. RESET carries
+no union payload; clear keys, buttons, strokes, and composition state. */
struct yasl_input_event {
+ /** Recipient; can differ from the polled surface for routed popup input. */
struct yasl_surface *surface;
+ /** Selects the valid union member. */
enum yasl_input_kind kind;
+ /** Reserved for YASL; applications must not interpret it. */
uint32_t reserved;
union {
- struct yasl_key_event key;
- struct yasl_mouse_event mouse;
- struct yasl_focus_event focus;
- struct yasl_text_event text;
- struct yasl_paste_event paste;
- struct yasl_drop_files_event drop_files;
+ struct yasl_key_event key; /**< Keyboard payload. */
+ struct yasl_mouse_event mouse; /**< Pointer payload. */
+ struct yasl_focus_event focus; /**< Focus payload. */
+ struct yasl_text_event text; /**< Committed text payload. */
+ struct yasl_paste_event paste; /**< Selection text payload. */
+ struct yasl_drop_files_event drop_files; /**< File URL list payload. */
};
};
@@ -300,128 +427,417 @@ struct yasl_input_event {
*/
/* 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 surface notifications, copied 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_surface_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. */
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,
- YASL_BACKEND_WAYLAND,
- YASL_BACKEND_X11,
- YASL_BACKEND_COCOA,
+ 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 selects the native backend. An explicit choice never falls back. */
+
+ /** 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);
/* 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_INPUT_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_surface_spec {
+ /** Copied UTF-8 title; NULL uses backend defaults. */
const char *title;
+ /** Requested logical-pixel width and height; both must be positive. */
struct yasl_vector2i size;
+ /** Request initial fullscreen; actual state is reported asynchronously. */
bool fullscreen;
+ /** Permit unpaced presentation where supported; a hint, not a guarantee. */
bool tearing;
};
+/** 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. Install callbacks and schedule a redraw.
+ */
YASL_API struct yasl_surface *yasl_surface_create_toplevel(struct yasl_display *d,
const struct yasl_surface_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, or NULL for no action.
+ * @param cbs Table copied by value; NULL removes all callbacks. NULL members are ignored.
+ * @param ud Borrowed userdata passed to the installed callbacks.
+ * Callbacks may run synchronously during this call; initialize userdata first.
+ * Use yasl_surface_geometry() to read current geometry; do not rely on receiving
+ * an initial configure callback when registering.
+ */
YASL_API void yasl_surface_set_callbacks(struct yasl_surface *s,
const struct yasl_surface_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);
/* Event payload strings are library-owned, NUL-terminated, and valid until
* the next SUCCESSFUL poll on this surface or surface destruction. Dispatch,
* flush and unsuccessful polls do not invalidate them. Copy to keep longer. */
+/**
+ * Remove one event from a surface's input queue without waiting.
+ * @param s Surface whose queue to drain.
+ * @param ev Required output event; unchanged when no event is available.
+ * @return true for an event, false for an empty queue or NULL arguments.
+ * Dispatch receives native input; polling only drains the queue. Read the union
+ * member selected by kind. Payload strings are borrowed, NUL-terminated, and
+ * valid until the next successful poll on this queue or its destruction; dispatch,
+ * flush, and unsuccessful polls do not invalidate them. On Wayland, popup pointer
+ * and keyboard input can be routed through the root parent's queue; inspect
+ * ev->surface to identify the receiving surface.
+ */
YASL_API bool yasl_surface_input_poll(struct yasl_surface *s, struct yasl_input_event *ev);
/* 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.
+ */
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_INPUT_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);
#ifdef __cplusplus