diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 23:41:31 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 23:41:31 +0300 |
| commit | 76073fe5fad8799e5850805f2f090af2cb62c741 (patch) | |
| tree | 9658019babe4760a3634bdab4da0731a10e42e68 /include | |
| parent | dd1775a9927922c14f8679ccbc4d3ca8d5917e20 (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')
| -rw-r--r-- | include/yasl/app.h | 147 | ||||
| -rw-r--r-- | include/yasl/cpu.h | 15 | ||||
| -rw-r--r-- | include/yasl/desktop.h | 116 | ||||
| -rw-r--r-- | include/yasl/gl.h | 27 | ||||
| -rw-r--r-- | include/yasl/keycodes.h | 271 | ||||
| -rw-r--r-- | include/yasl/loop.h | 214 | ||||
| -rw-r--r-- | include/yasl/metal.h | 20 | ||||
| -rw-r--r-- | include/yasl/native.h | 90 | ||||
| -rw-r--r-- | include/yasl/native/cocoa.h | 48 | ||||
| -rw-r--r-- | include/yasl/native/wayland.h | 37 | ||||
| -rw-r--r-- | include/yasl/native/x11.h | 36 | ||||
| -rw-r--r-- | include/yasl/timing.h | 56 | ||||
| -rw-r--r-- | include/yasl/vulkan.h | 19 | ||||
| -rw-r--r-- | include/yasl/yasl.h | 1203 |
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 |
