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 /examples/simple_window.c | |
| 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 'examples/simple_window.c')
| -rw-r--r-- | examples/simple_window.c | 232 |
1 files changed, 42 insertions, 190 deletions
diff --git a/examples/simple_window.c b/examples/simple_window.c index 5a8b314..114bfbf 100644 --- a/examples/simple_window.c +++ b/examples/simple_window.c @@ -1,198 +1,50 @@ -#include <yasl/app.h> -#include <stdio.h> +/* Mouse and pen input on a CPU surface. */ +#include <yasl/yasl.h> +#include <yasl/cpu.h> #include <string.h> -static bool failed, smoke_test; -static int mouse_x = -1; -static int mouse_y = -1; -static bool mouse_down = false; -static int color_theme = 0; -static uint16_t pen_pressure = 0; -static int8_t pen_tilt_x = 0; -static int8_t pen_tilt_y = 0; -static enum yasl_pointer_device pointer_device = YASL_PTR_DEV_MOUSE; - -static const char *device_name(enum yasl_pointer_device dev) -{ - switch (dev) { - case YASL_PTR_DEV_PEN: return "Pen/Stylus"; - case YASL_PTR_DEV_ERASER: return "Eraser"; - case YASL_PTR_DEV_TOUCH: return "Touch"; - default: return "Mouse"; - } -} - -static void on_draw(void *ud, struct yasl_surface *s, struct yasl_frame *frame) +int main(int argc, char **argv) { - (void)ud; - int w = frame->target.size.x; - int h = frame->target.size.y; - uint32_t *pixels = frame->target.pixels; - if (!pixels || w <= 0 || h <= 0) - return; - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - uint8_t r, g, b; - uint8_t u = (uint8_t)((x * 255) / (w > 0 ? w : 1)); - uint8_t v = (uint8_t)((y * 255) / (h > 0 ? h : 1)); - - switch (color_theme % 3) { - case 0: - r = u; - g = v; - b = 160; - break; - case 1: - r = 40; - g = u; - b = v; - break; - default: - r = v; - g = 60; - b = u; - break; - } - - /* Draw interactive pointer / stylus indicator */ - if (mouse_x >= 0 && mouse_y >= 0) { - int dx = x - mouse_x; - int dy = y - mouse_y; - int dist_sq = dx * dx + dy * dy; - - /* Pressure-sensitive radius: scales dynamically from 8px to 64px */ - int radius; - if (pen_pressure > 0) { - radius = 8 + (int)(((uint32_t)pen_pressure * 56) / 65535); - } else { - radius = mouse_down ? 36 : 18; - } - - if (dist_sq < radius * radius) { - r = (uint8_t)(255 - r / 2); - g = (uint8_t)(255 - g / 2); - b = (uint8_t)(255 - b / 2); + bool smoke = argc == 2 && !strcmp(argv[1], "--smoke-test"); + yasl_surface *s = yasl_surface_create("YASL input", 640, 480, YASL_SURFACE_CPU); + if (!s) return 1; + double px = -100, py = -100, pressure = 0; + bool dirty = false; + int frames = 0, result = 1; + yasl_event e; + for (;;) { + int n = yasl_wait_event(&e, smoke ? 20 : -1); + if (n < 0 || e.type == YASL_EVENT_DISPLAY_LOST) break; + if (e.type == YASL_EVENT_CLOSE || e.type == YASL_EVENT_QUIT || + (e.type == YASL_EVENT_KEY && e.key.key == YASL_KEY_ESCAPE)) { result = 0; break; } + if (e.type == YASL_EVENT_POINTER) { + px = e.pointer.x; py = e.pointer.y; + pressure = (e.pointer.buttons & YASL_BUTTON_BIT(YASL_BUTTON_PRIMARY)) ? 0.5 : 0; + dirty = true; + } + if (e.type == YASL_EVENT_PEN) { + px = e.pen.x; py = e.pen.y; + pressure = (e.pen.axes_valid & YASL_PEN_PRESSURE) ? e.pen.pressure : 0; + dirty = true; + } + if (e.type == YASL_EVENT_REFRESH) dirty = true; + if (dirty) { + int w, h; + uint32_t *pixels = yasl_cpu_pixels(s, &w, &h); + if (!pixels) break; + double scale = yasl_surface_get_scale(s), radius = (8 + pressure * 48) * scale; + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + double dx = x - px * scale, dy = y - py * scale; + pixels[(size_t)y * w + x] = dx * dx + dy * dy < radius * radius ? 0xffffc060u : 0xff203040u; } } - - pixels[y * w + x] = (255u << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b; - } - } - - if (!yasl_frame_present(frame, NULL, 0)) { - fprintf(stderr, "Failed to present frame\n"); - failed = true; - } - if (failed) yasl_app_exit(yasl_surface_display(s), YASL_APP_ERROR); - else if (smoke_test) yasl_surface_destroy(s); -} - -static enum yasl_app_result on_init(void *ud, struct yasl_display *display) -{ - (void)ud; - struct yasl_window_spec window_spec = { - .title = "YASL Interactive Window (Pen & Touch Enabled)", - .size_logical = { .x = 640, .y = 480 }, - }; - struct yasl_surface *s = yasl_surface_create_toplevel(display, &window_spec); - if (!s) { - fprintf(stderr, "Failed to create surface\n"); - failed = true; - return YASL_APP_ERROR; - } - - yasl_surface_request_frame(s); - - printf("=== YASL Demo Running ===\n"); - printf(" - Stylus/Pen: full pressure (0..65535) and tilt detection\n"); - printf(" - Mouse/Touch: interactive click/motion highlights\n"); - printf(" - Space: cycle background themes\n"); - printf(" - Escape: exit\n\n"); - - return YASL_APP_CONTINUE; -} - -static void pointer_sample(struct yasl_vector2i pos, enum yasl_pointer_device device, - struct yasl_pointer_pen pen) -{ - mouse_x = pos.x; - mouse_y = pos.y; - pointer_device = device; - pen_pressure = pen.pressure; - pen_tilt_x = pen.tilt_x; - pen_tilt_y = pen.tilt_y; -} - -static enum yasl_app_result on_event(void *ud, const struct yasl_event *ev) -{ - (void)ud; - switch (ev->type) { - case YASL_EVENT_WINDOW_CLOSE: - return YASL_APP_QUIT; - case YASL_EVENT_WINDOW_RESIZE: { - uint32_t flags = yasl_surface_state(ev->surface); - const char *mode = flags & YASL_STATE_FULLSCREEN ? "fullscreen" : - flags & YASL_STATE_MAXIMIZED ? "maximized" : - flags & YASL_STATE_TILED ? "tiled" : "windowed"; - printf("[YASL] Resized to %dx%d (scale: %.2fx, %s)\n", ev->resize.geometry.size.x, - ev->resize.geometry.size.y, (double)ev->resize.geometry.scale_120 / YASL_SCALE_UNIT, mode); - break; - } - case YASL_EVENT_KEY: - if (ev->key.action != YASL_KEY_PRESS) return YASL_APP_CONTINUE; - if (ev->key.key == YASL_KEY_ESCAPE) return YASL_APP_QUIT; - if (ev->key.key == YASL_KEY_SPACE || ev->key.key == YASL_KEY_ENTER) - color_theme++; - break; - case YASL_EVENT_POINTER_DOWN: - case YASL_EVENT_POINTER_UP: - case YASL_EVENT_POINTER_MOTION: - pointer_sample(ev->pointer.pos, ev->pointer.device, ev->pointer.pen); - if (ev->type == YASL_EVENT_POINTER_DOWN && ev->pointer.button == YASL_BUTTON_PRIMARY) { - mouse_down = true; - } else if (ev->type == YASL_EVENT_POINTER_UP && ev->pointer.button == YASL_BUTTON_PRIMARY) { - mouse_down = false; - pen_pressure = 0; + if (!yasl_cpu_present(s)) break; + dirty = false; + frames++; } - break; - case YASL_EVENT_FOCUS: - if (ev->focus.focused) return YASL_APP_CONTINUE; - /* Fall through to cancel held input on focus loss. */ - [[fallthrough]]; - case YASL_EVENT_INPUT_RESET: - case YASL_EVENT_POINTER_LEAVE: - mouse_x = mouse_y = -1; - mouse_down = false; - pen_pressure = 0; - break; - default: - return YASL_APP_CONTINUE; - } - if (pen_pressure > 0) { - printf("[Pen] Pressure: %5u/65535 (%.1f%%) | Tilt: (%+3d°, %+3d°) | Device: %s\n", - pen_pressure, pen_pressure * 100.0 / 65535.0, - pen_tilt_x, pen_tilt_y, device_name(pointer_device)); - } - yasl_surface_request_frame(ev->surface); - return YASL_APP_CONTINUE; -} - -int main(int argc, char **argv) -{ - if (argc == 2 && strcmp(argv[1], "--smoke-test") == 0) - smoke_test = true; - else if (argc != 1) { - fprintf(stderr, "Usage: %s [--smoke-test]\n", argv[0]); - return 1; + if (smoke && frames && n == 0) { result = 0; break; } } - struct yasl_app_desc desc = { - .app_id = "org.yasl.example", - .init = on_init, - .event = on_event, - .frame = on_draw, - }; - int result = yasl_run(&desc); - if (result) perror("yasl_run"); - return result || failed ? 1 : 0; + yasl_shutdown(); + return result; } |
