summaryrefslogtreecommitdiff
path: root/examples/simple_window.c
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-13 23:41:31 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-13 23:41:31 +0300
commit76073fe5fad8799e5850805f2f090af2cb62c741 (patch)
tree9658019babe4760a3634bdab4da0731a10e42e68 /examples/simple_window.c
parentdd1775a9927922c14f8679ccbc4d3ca8d5917e20 (diff)
Simplify the public event and CPU API
Applications now need far less ceremony: hello.c is a 20-line loop that handles REFRESH, CLOSE and QUIT and draws into the surface's own pixels. - Fold GEOMETRY, STATE and FOCUS into one WINDOW event carrying size, scale and state; unchanged values send nothing. - Guarantee REFRESH once a window has a size and after every resize, never at size zero. - Merge DROP_HOVER into DROP with over/leave/data actions and give drag and drop actions enums. - Keep event strings valid until the next wait and drop yasl_event_release; empty or failed waits report NONE. - Replace copy-in presentation with a lent pixel buffer: yasl_cpu_pixels and yasl_cpu_present. - Remove yasl_poll_event, yasl_cpu_read_pixels, unused event fields and comments that restated names. - Wayland: resize floating windows in request_size instead of reporting it unsupported, and stop marking new GPU surfaces as Vulkan so yasl_vulkan_create_surface no longer fails with NATIVE_WINDOW_IN_USE. Also includes the in-progress public API refactor that was uncommitted in the tree (removal of the app/loop layer, new surface, GL and Vulkan entry points). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'examples/simple_window.c')
-rw-r--r--examples/simple_window.c232
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;
}