summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-13 15:05:06 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-13 15:05:06 +0300
commit98f0d51157fa2a2b8ccaae54ed4850a88d223d01 (patch)
tree90b03d0930986620d95eb0f45c07b96e1331783c /docs
parent339e1ad7adb8340732ee856d0f6f0d2c7f1455d1 (diff)
Simplify surface state, examples, and library installation
Diffstat (limited to 'docs')
-rw-r--r--docs/api-policy.md13
-rw-r--r--docs/getting-started.md81
-rw-r--r--docs/guide.md26
-rw-r--r--docs/migrating.md15
-rw-r--r--docs/testing.md12
5 files changed, 87 insertions, 60 deletions
diff --git a/docs/api-policy.md b/docs/api-policy.md
index 0c8f040..dd22ca7 100644
--- a/docs/api-policy.md
+++ b/docs/api-policy.md
@@ -1,16 +1,17 @@
# Public API policy
-YASL 0.1 is pre-release. The installed headers are the public API; implementation
+YASL 0.1 is pre-release. The headers under `include/yasl/` are the public API; implementation
headers under `src/` are private even when their symbols appear in a static
-archive. The shared library exports only declarations from installed headers.
-Native backend headers and accessors are available only for built backends.
+archive. The shared library exports only declarations from public headers.
+Native backend accessors are exported only for built backends. Installation
+copies only the shared and static libraries; use matching source-tree headers.
There is currently no stable ABI promise and no versioned shared-library SONAME.
Rebuild consumers against the exact headers/library pair they ship. Source and
binary compatibility can change before 1.0. Do not assume struct layout is stable
across releases, mix headers and binaries from different revisions, or persist
-public structs as a file/network format. The package version is available through
-`pkg-config --modversion yasl`.
+public structs as a file/network format. The release version is declared in
+`meson.build`.
See [migration notes](migrating.md) for window creation, portable keyboard, and
fractional scroll API changes.
@@ -28,7 +29,7 @@ Every public addition or behavior change needs:
- An update to the guide and its backend limits when observable behavior changes.
- A runnable example when the new workflow cannot be understood from an isolated
call, and meaningful regression coverage for ownership or behavior changes.
-- A check that shared exports and installed-package consumers still work.
+- A check that shared exports and consumers of the installed library still work.
Functions documenting errno set it on failure. Other booleans report acceptance
or availability without a guaranteed errno; void setters are best effort.
diff --git a/docs/getting-started.md b/docs/getting-started.md
index d21c9bd..caa25eb 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -39,79 +39,68 @@ CPU pixel targets are presented through the system's Metal device; applications
do not need to create or manage that device themselves.
The complete beginner example is [hello.c](../examples/hello.c). It checks
-construction failures, fills every pixel, presents inside `draw`, drains input,
-responds to quit/close/lost, and destroys resources in order. The
+construction failures, fills every pixel, and presents inside a frame callback.
+`yasl_run()` handles input delivery, display notifications, and cleanup. The
[interactive window](../examples/simple_window.c) adds pointer input; the
[tablet example](../examples/tablet.c) demonstrates retained application content,
pressure, erasers, resizing, and scale changes.
## Link an application
-Install the library and public headers into your chosen prefix:
+Install the shared and static libraries into your chosen prefix. Headers,
+examples, documentation, and pkg-config metadata remain in the source tree:
```sh
-meson setup build --prefix=/usr/local
+meson setup build --prefix=/usr/local --libdir=lib
meson compile -C build
meson install -C build
-cc -std=c23 examples/hello.c -o hello $(pkg-config --cflags --libs yasl)
+cc -std=c23 -Iinclude examples/hello.c -o hello -L/usr/local/lib -Wl,-rpath,/usr/local/lib -lyasl
./hello
```
-The prefix must be writable, and your compiler, pkg-config, and runtime loader
-must search it. For a custom prefix, set `PKG_CONFIG_PATH` to its pkg-config
-directory and configure the loader for its library directory. Static linking
-uses `pkg-config --static --libs yasl` to include backend dependencies.
+The prefix must be writable. Use matching headers from `include/`, and adjust
+the library search path and runtime path for your chosen prefix and `libdir`.
+Static consumers must also link the enabled backends' dependencies.
-A Meson consumer uses the installed dependency:
+A Meson application can instead vendor the source under `subprojects/yasl`:
```meson
project('my-app', 'c', default_options: ['c_std=c23'])
-yasl = dependency('yasl', version: '>=0.1.0')
+yasl = subproject('yasl').get_variable('yasl_dep')
executable('my-app', 'main.c', dependencies: yasl)
```
-YASL also declares `meson.override_dependency('yasl', ...)`, so the same consumer
-can use a vendored Meson subproject through a fallback dependency. Public headers
-can be included from C++11 or newer; the library itself builds as C23.
+The subproject dependency includes headers and backend link dependencies.
+Public headers can be included from C++11 or newer; the library itself builds
+as C23. Only the library artifacts are installed by `meson install`.
## The application cycle
-1. Open a display with `yasl_display_open(NULL, &spec)`. NULL creates a loop owned
- by the display. Supply your own loop only when you need shared loop ownership.
-2. Create a toplevel with `yasl_window_spec`: supply a positive **logical-pixel**
- size, a `yasl_window_cbs` table in `cbs`, and callback userdata in `ud`.
- Zero-initialize every option and callback struct. Callback tables are copied;
- userdata must remain alive. The new window's callbacks start after creation
- returns. Read initial geometry with `yasl_surface_geometry()`.
-3. Schedule the initial redraw. `draw` receives a borrowed target. Fill every
- pixel with premultiplied `0xAARRGGBB`, then present that exact target, once.
-4. Dispatch, drain input for every live surface queue, update application state,
- and flush. Flush runs scheduled drawing and sends native requests. Dispatch
- may also invoke callbacks, including drawing during native live resize.
-5. Destroy popups before parents, surfaces before displays, and displays before
- any supplied loop. NULL destroy/close calls do nothing; freed pointers are
- invalid for every operation.
+1. Include `<yasl/app.h>` and initialize a `yasl_app_desc` with your userdata and
+ `init`, `event`, and `frame` callbacks. Call `yasl_run(&desc)`.
+2. In `init`, create a toplevel with a positive **logical-pixel** size and call
+ `yasl_surface_request_frame(surface)` for the first redraw.
+3. In `event`, handle the union member selected by `event->type`. Return
+ `YASL_APP_QUIT` for a close request; otherwise return `YASL_APP_CONTINUE`.
+4. In `frame`, fill every pixel in `frame->cpu.pixels` with premultiplied
+ `0xAARRGGBB` and present once with `yasl_frame_present_cpu(frame, NULL, 0)`.
+5. Let the runner close remaining surfaces and the display. Release your own
+ resources in the optional `quit` callback or after `yasl_run()` returns.
```c
-while (running) {
- if (yasl_display_dispatch(display, -1) < 0) {
- perror("yasl_display_dispatch");
- break;
- }
- struct yasl_input_event event;
- while (yasl_surface_input_poll(surface, &event)) {
- /* Read the union member selected by event.kind. */
- }
- yasl_display_flush(display);
-}
+struct yasl_app_desc desc = {
+ .app_id = "org.example.app",
+ .userdata = &app,
+ .init = init,
+ .event = event,
+ .frame = draw,
+};
+return yasl_run(&desc);
```
-Zero timeout polls, positive timeout bounds the wait in milliseconds, and a
-negative timeout waits for work. Undrained input makes dispatch return without
-waiting. Use the return value only to detect failure, not to count input events.
-If callbacks destroy surfaces, update your application registry immediately and
-only poll surfaces that are still alive. Arrange display/loop cleanup after the
-cycle ends; destroying them inside a callback is unsupported.
+The default pacing mode sleeps until input, resize, or a requested redraw.
+Use `YASL_PACING_CONTINUOUS` for an animation or game. The core API still supports
+manual dispatch/poll/flush when an application owns its event loop; see the guide.
See the [application guide](guide.md) for drawing, input, popups, timers, and
platform limits, or the comments in the [public header](../include/yasl/yasl.h)
diff --git a/docs/guide.md b/docs/guide.md
index adcacc8..1bd1aef 100644
--- a/docs/guide.md
+++ b/docs/guide.md
@@ -39,6 +39,22 @@ it advertises CSD. Check each result and provide an application fallback.
## Window creation and callbacks
+All examples include `<yasl/app.h>` and call `yasl_run()` with a
+`yasl_app_desc`. Create surfaces in `init`, handle `YASL_EVENT_*` notifications
+in `event`, and render into `frame->cpu.pixels` in `frame`. Present with
+`yasl_frame_present_cpu(frame, NULL, 0)` and return `YASL_APP_QUIT` from an event
+handler to exit. The runner handles dispatch, input polling, resize redraws,
+and remaining surface/display cleanup. Display quit stops the runner; connection
+loss and dispatch failures return an error after cleanup.
+
+Unified pointer button and motion events retain `device` and `pen` axes,
+including erasers and pressure-only motion. Cancel held input or active strokes
+on `YASL_EVENT_INPUT_RESET`, pointer leave, or focus loss. Reset also starts the
+next motion delta from zero. [hello.c](../examples/hello.c) shows the minimal
+lifecycle; [tablet.c](../examples/tablet.c) demonstrates device-aware drawing.
+
+For applications managing their own event loop, use the core API below.
+
Open the display with application-wide options and notifications in
`yasl_display_spec`. Create each toplevel with `yasl_window_spec`, including its
title, logical size, optional `yasl_window_cbs` table in `cbs`, and userdata in
@@ -55,6 +71,14 @@ installs popup callbacks; the setter does not invoke the callbacks.
When using `yasl_run()`, its runner installs callbacks for windows on its display.
Use `yasl_app_desc.event` and `.frame` rather than `yasl_window_spec.cbs` and `.ud`.
+Read window state with `yasl_surface_state()`. Its `YASL_STATE_*` flags can
+coexist, and the `state` callback receives the same current bitmask. Wayland
+also reports `YASL_STATE_TILED` when any window edge is tiled; X11 and Cocoa
+currently leave that flag unset. Unsupported flags are absent. On Wayland, an
+ordinary floating toplevel has fullscreen, maximized, and tiled all absent.
+`YASL_STATE_SUSPENDED` describes repaint suspension rather than minimization;
+there is no portable minimized flag.
+
## Geometry and scaling
| Value | Units |
@@ -301,7 +325,7 @@ signals the loop pipe but is not a portable cross-thread event-posting API.
Portable CPU drawing needs no native headers. Opt into `<yasl/native.h>` and
`<yasl/native/wayland.h>`, `<yasl/native/x11.h>`, or `<yasl/native/cocoa.h>` when
-integrating a platform API. Typed headers and functions are installed only for
+integrating a platform API. Typed native functions are exported only for
built backends. Accessors return borrowed handles and zero/NULL for the wrong
backend. Do not pass freed objects, destroy borrowed handles, independently
dispatch native connections, or change surface roles and buffer ownership.
diff --git a/docs/migrating.md b/docs/migrating.md
index da4e591..395072e 100644
--- a/docs/migrating.md
+++ b/docs/migrating.md
@@ -1,9 +1,22 @@
# Migrating pre-release applications
YASL 0.1 has no stable source or binary compatibility promise. Rebuild all
-consumers against the matching installed headers and library after updating.
+consumers against matching public headers and the library after updating.
See the [application guide](guide.md) for the full window and input workflow.
+## Application callbacks
+
+All examples now use `<yasl/app.h>` and `yasl_run()`. Move window creation to
+`yasl_app_desc.init`, input handling to `.event`, and drawing to `.frame`.
+Replace manual dispatch/poll/flush loops with the runner and request redraws with
+`yasl_surface_request_frame()`. Present the frame context with
+`yasl_frame_present_cpu()`; the runner destroys remaining surfaces on exit.
+
+Unified pointer button and motion events retain `device` and tablet axes.
+Handle `YASL_EVENT_INPUT_RESET` by clearing held input and active strokes, just
+as for the core API's `YASL_INPUT_RESET`. Window state remains a `YASL_STATE_*`
+bitmask; `YASL_STATE_TILED` is reported for tiled Wayland toplevels.
+
## Window creation
Rename `struct yasl_surface_spec` to `struct yasl_window_spec` and
diff --git a/docs/testing.md b/docs/testing.md
index d01b82c..bd3f2f0 100644
--- a/docs/testing.md
+++ b/docs/testing.md
@@ -24,7 +24,7 @@ meson test -C build-sanitize --print-errorlogs
Default tests need no desktop connection. C++ header coverage is built when a
C++ compiler is available. On Linux and macOS, the shared-export test ensures
-only installed API declarations are exported. Test disabled-backend configurations separately with
+only public API declarations are exported. Test disabled-backend configurations separately with
`-Dwayland=disabled` or `-Dx11=disabled`; the combined integration harness needs
both backends.
@@ -94,13 +94,13 @@ serves as the drawing cursor. Mouse drawing uses a fixed width. Press C or
Space to clear and Escape to quit. Resizing and display scale changes preserve
the drawing. `--smoke-test` presents one frame and exits for automated checks.
-[`examples/tablet.c`](../examples/tablet.c) includes only `<yasl/yasl.h>` and the C
-standard library. It uses CPU framebuffers and `yasl_surface_input_poll()` on
-every backend. Tablet events arrive as `YASL_INPUT_MOUSE`, distinguished by
-`mouse.device == YASL_PTR_DEV_PEN` or `YASL_PTR_DEV_ERASER`; `mouse.pen` contains
+[`examples/tablet.c`](../examples/tablet.c) includes `<yasl/app.h>` and the C
+standard library. It uses `yasl_run()`, frame callbacks, and unified input events
+on every backend. Tablet button and motion events retain `device`, which is
+`YASL_PTR_DEV_PEN` or `YASL_PTR_DEV_ERASER`; their `pen` member contains
pressure and signed tilt. Button 0 is tip contact on every backend. Track tip
press/release events: zero pressure alone does not mean release. Hover and side
-buttons do not paint, and focus loss, leave, or `YASL_INPUT_RESET` cancels a stroke.
+buttons do not paint, and focus loss, leave, or `YASL_EVENT_INPUT_RESET` cancels a stroke.
Stationary pressure changes arrive as motion events and update the brush too.
The example uses portable physical keys: C and Space clear, Escape exits.