From 76073fe5fad8799e5850805f2f090af2cb62c741 Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Tue, 13 Oct 2026 23:41:31 +0300 Subject: 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 --- src/platform/posix/loop.c | 156 ++++++++++++++++---------------- src/platform/posix/yasl_platform_sync.h | 14 +-- 2 files changed, 85 insertions(+), 85 deletions(-) (limited to 'src/platform/posix') diff --git a/src/platform/posix/loop.c b/src/platform/posix/loop.c index 3c3d730..49132f8 100644 --- a/src/platform/posix/loop.c +++ b/src/platform/posix/loop.c @@ -14,35 +14,35 @@ #include #include -#define YASL_LOOP_INIT_CAP 32 +#define YASL_PRIVATE_LOOP_INIT_CAP 32 -typedef int (*yasl_loop_fd_fn)(int fd, short revents, void *ud); +typedef int (*yasl_private_loop_fd_fn)(int fd, short revents, void *ud); -struct yasl_fd_source { - yasl_loop_fd_fn fn; +struct yasl_private_fd_source { + yasl_private_loop_fd_fn fn; void *ud; int id; int fd; short events; }; -struct yasl_timer_source { - yasl_timer_cb fn; +struct yasl_private_timer_source { + yasl_private_timer_cb fn; void *ud; uint64_t interval_ns; uint64_t deadline_ns; - yasl_timer_id id; + yasl_private_timer_id id; bool deleted; }; -struct yasl_post { +struct yasl_private_post { void (*fn)(void *ud); void *ud; - struct yasl_post *next; + struct yasl_private_post *next; }; /* Signals this loop watches; the previous actions are restored on unwatch. */ -struct yasl_signal_watch { +struct yasl_private_signal_watch { void (*cb)(void *ud, int signo); void *ud; int count; @@ -50,8 +50,8 @@ struct yasl_signal_watch { struct sigaction old[NSIG]; }; -struct yasl_loop { - struct yasl_fd_source *fds; +struct yasl_private_loop { + struct yasl_private_fd_source *fds; struct pollfd *pollfds; int count; int capacity; @@ -61,17 +61,17 @@ struct yasl_loop { int wake_wfd; int wake_watch; - struct yasl_timer_source *timers; + struct yasl_private_timer_source *timers; int timer_count; int timer_capacity; uint32_t next_timer_id; int timer_firing_depth; - yasl_mutex post_mutex; - struct yasl_post *post_head; - struct yasl_post *post_tail; + yasl_private_mutex post_mutex; + struct yasl_private_post *post_head; + struct yasl_private_post *post_tail; - struct yasl_signal_watch *signals; + struct yasl_private_signal_watch *signals; }; /* Handlers run on any thread, so they only touch lock-free atomics: they mark @@ -79,34 +79,34 @@ struct yasl_loop { * stored as fd + 1 so that the zero initializer means no pipe. */ static atomic_int signal_wake_fd[NSIG]; static atomic_bool signal_pending[NSIG]; -static struct yasl_loop *signal_owner[NSIG]; +static struct yasl_private_loop *signal_owner[NSIG]; -uint64_t yasl_loop_now_ns(void) +uint64_t yasl_private_loop_now_ns(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (uint64_t)ts.tv_sec * 1000000000ull + (uint64_t)ts.tv_nsec; } -static void run_posts(struct yasl_loop *l) +static void run_posts(struct yasl_private_loop *l) { - yasl_mutex_lock(&l->post_mutex); - struct yasl_post *p = l->post_head; + yasl_private_mutex_lock(&l->post_mutex); + struct yasl_private_post *p = l->post_head; l->post_head = l->post_tail = NULL; - yasl_mutex_unlock(&l->post_mutex); + yasl_private_mutex_unlock(&l->post_mutex); while (p) { - struct yasl_post *next = p->next; + struct yasl_private_post *next = p->next; p->fn(p->ud); free(p); p = next; } } -static void run_signals(struct yasl_loop *l) +static void run_signals(struct yasl_private_loop *l) { /* A callback may unwatch, so re-check the watch before each delivery. */ for (int signo = 1; signo < NSIG; signo++) { - struct yasl_signal_watch *w = l->signals; + struct yasl_private_signal_watch *w = l->signals; if (!w) return; if (signal_owner[signo] != l || !atomic_exchange(&signal_pending[signo], false)) continue; @@ -120,18 +120,18 @@ static int loop_wake_cb(int fd, short revents, void *ud) char buf[128]; ssize_t n; while ((n = read(fd, buf, sizeof(buf))) > 0 || (n < 0 && errno == EINTR)) {} - struct yasl_loop *l = ud; + struct yasl_private_loop *l = ud; run_posts(l); run_signals(l); return 0; } -struct yasl_loop *yasl_loop_create(void) +struct yasl_private_loop *yasl_private_loop_create(void) { - struct yasl_loop *l = calloc(1, sizeof(*l)); + struct yasl_private_loop *l = calloc(1, sizeof(*l)); if (!l) return NULL; - l->capacity = YASL_LOOP_INIT_CAP; + l->capacity = YASL_PRIVATE_LOOP_INIT_CAP; l->fds = malloc((size_t)l->capacity * sizeof(*l->fds)); l->pollfds = malloc((size_t)l->capacity * sizeof(*l->pollfds)); if (!l->fds || !l->pollfds) { @@ -141,7 +141,7 @@ struct yasl_loop *yasl_loop_create(void) return NULL; } - if (yasl_mutex_init(&l->post_mutex) != 0) { + if (yasl_private_mutex_init(&l->post_mutex) != 0) { free(l->fds); free(l->pollfds); free(l); @@ -173,23 +173,23 @@ struct yasl_loop *yasl_loop_create(void) #endif if (l->wake_rfd >= 0) { - l->wake_watch = yasl_loop_add_fd(l, l->wake_rfd, POLLIN, loop_wake_cb, l); + l->wake_watch = yasl_private_loop_add_fd(l, l->wake_rfd, POLLIN, loop_wake_cb, l); } return l; } -void yasl_loop_destroy(struct yasl_loop *l) +void yasl_private_loop_destroy(struct yasl_private_loop *l) { if (!l) return; - yasl_loop_unwatch_signals(l); - for (struct yasl_post *p = l->post_head; p;) { - struct yasl_post *next = p->next; + yasl_private_loop_unwatch_signals(l); + for (struct yasl_private_post *p = l->post_head; p;) { + struct yasl_private_post *next = p->next; free(p); p = next; } - yasl_mutex_destroy(&l->post_mutex); + yasl_private_mutex_destroy(&l->post_mutex); if (l->wake_watch > 0) - yasl_loop_del_fd(l, l->wake_watch); + yasl_private_loop_del_fd(l, l->wake_watch); if (l->wake_rfd >= 0) close(l->wake_rfd); if (l->wake_wfd >= 0) @@ -200,15 +200,15 @@ void yasl_loop_destroy(struct yasl_loop *l) free(l); } -int yasl_loop_add_fd(struct yasl_loop *l, int fd, short events, +int yasl_private_loop_add_fd(struct yasl_private_loop *l, int fd, short events, int (*fn)(int fd, short revents, void *ud), void *ud) { if (!l || fd < 0) return -1; if (l->count >= l->capacity) { - int new_cap = l->capacity ? l->capacity * 2 : YASL_LOOP_INIT_CAP; - struct yasl_fd_source *new_fds = realloc(l->fds, (size_t)new_cap * sizeof(*new_fds)); + int new_cap = l->capacity ? l->capacity * 2 : YASL_PRIVATE_LOOP_INIT_CAP; + struct yasl_private_fd_source *new_fds = realloc(l->fds, (size_t)new_cap * sizeof(*new_fds)); if (!new_fds) return -1; l->fds = new_fds; @@ -221,7 +221,7 @@ int yasl_loop_add_fd(struct yasl_loop *l, int fd, short events, int id = l->next_id++; if (l->next_id <= 0) l->next_id = 1; - l->fds[l->count] = (struct yasl_fd_source){ + l->fds[l->count] = (struct yasl_private_fd_source){ .fn = fn, .ud = ud, .id = id, .fd = fd, .events = events, }; l->pollfds[l->count] = (struct pollfd){ @@ -231,7 +231,7 @@ int yasl_loop_add_fd(struct yasl_loop *l, int fd, short events, return id; } -int yasl_loop_del_fd(struct yasl_loop *l, int id) +int yasl_private_loop_del_fd(struct yasl_private_loop *l, int id) { if (!l || id <= 0) return -1; for (int i = 0; i < l->count; i++) { @@ -245,7 +245,7 @@ int yasl_loop_del_fd(struct yasl_loop *l, int id) return -1; } -int yasl_loop_set_fd_events(struct yasl_loop *l, int id, short events) +int yasl_private_loop_set_fd_events(struct yasl_private_loop *l, int id, short events) { if (!l || id <= 0) return -1; for (int i = 0; i < l->count; i++) { @@ -270,25 +270,25 @@ static void wake_write(int fd) errno = saved; } -void yasl_loop_kick(struct yasl_loop *l) +void yasl_private_loop_kick(struct yasl_private_loop *l) { if (!l || l->wake_wfd < 0) return; wake_write(l->wake_wfd); } -bool yasl_loop_post(struct yasl_loop *l, void (*fn)(void *ud), void *ud) +bool yasl_private_loop_post(struct yasl_private_loop *l, void (*fn)(void *ud), void *ud) { if (!l || !fn || l->wake_wfd < 0) return false; - struct yasl_post *p = malloc(sizeof(*p)); + struct yasl_private_post *p = malloc(sizeof(*p)); if (!p) return false; - *p = (struct yasl_post){.fn = fn, .ud = ud}; - yasl_mutex_lock(&l->post_mutex); + *p = (struct yasl_private_post){.fn = fn, .ud = ud}; + yasl_private_mutex_lock(&l->post_mutex); if (l->post_tail) l->post_tail->next = p; else l->post_head = p; l->post_tail = p; - yasl_mutex_unlock(&l->post_mutex); + yasl_private_mutex_unlock(&l->post_mutex); wake_write(l->wake_wfd); return true; } @@ -305,7 +305,7 @@ static bool signal_valid(int signo) return signo > 0 && signo < NSIG && signo != SIGKILL && signo != SIGSTOP; } -bool yasl_loop_watch_signals(struct yasl_loop *l, const int *signals, int n, +bool yasl_private_loop_watch_signals(struct yasl_private_loop *l, const int *signals, int n, void (*cb)(void *ud, int signo), void *ud) { if (!l || !signals || n <= 0 || !cb || l->wake_wfd < 0) { @@ -324,14 +324,14 @@ bool yasl_loop_watch_signals(struct yasl_loop *l, const int *signals, int n, } wanted[signals[i]] = true; } - struct yasl_signal_watch *w = calloc(1, sizeof(*w)); + struct yasl_private_signal_watch *w = calloc(1, sizeof(*w)); if (!w) return false; w->cb = cb; w->ud = ud; /* Keep the old watch's saved actions for signals that stay watched, so * that unwatch restores what the application had before any watch. */ - struct yasl_signal_watch *old = l->signals; + struct yasl_private_signal_watch *old = l->signals; struct sigaction sa = {.sa_handler = signal_handler, .sa_flags = SA_RESTART}; sigemptyset(&sa.sa_mask); for (int signo = 1; signo < NSIG; signo++) { @@ -380,10 +380,10 @@ bool yasl_loop_watch_signals(struct yasl_loop *l, const int *signals, int n, return true; } -void yasl_loop_unwatch_signals(struct yasl_loop *l) +void yasl_private_loop_unwatch_signals(struct yasl_private_loop *l) { if (!l || !l->signals) return; - struct yasl_signal_watch *w = l->signals; + struct yasl_private_signal_watch *w = l->signals; l->signals = NULL; for (int i = 0; i < w->count; i++) { int signo = w->signals[i]; @@ -395,19 +395,19 @@ void yasl_loop_unwatch_signals(struct yasl_loop *l) free(w); } -static void timer_cleanup_deleted(struct yasl_loop *l) +static void timer_cleanup_deleted(struct yasl_private_loop *l) { if (!l || l->timer_firing_depth > 0) return; int dest = 0; for (int src = 0; src < l->timer_count; src++) { - struct yasl_timer_source t = l->timers[src]; + struct yasl_private_timer_source t = l->timers[src]; l->timers[dest] = t; dest += !t.deleted; } l->timer_count = dest; } -bool yasl_loop_timer_armed(const struct yasl_loop *l, yasl_timer_id id) +bool yasl_private_loop_timer_armed(const struct yasl_private_loop *l, yasl_private_timer_id id) { if (!l || id == 0) return false; for (int i = 0; i < l->timer_count; i++) @@ -416,7 +416,7 @@ bool yasl_loop_timer_armed(const struct yasl_loop *l, yasl_timer_id id) return false; } -int yasl_loop_poll_set(const struct yasl_loop *l, const struct pollfd **fds) +int yasl_private_loop_poll_set(const struct yasl_private_loop *l, const struct pollfd **fds) { if (!l) { *fds = NULL; @@ -426,10 +426,10 @@ int yasl_loop_poll_set(const struct yasl_loop *l, const struct pollfd **fds) return l->count; } -int yasl_loop_next_timeout_ms(const struct yasl_loop *l) +int yasl_private_loop_next_timeout_ms(const struct yasl_private_loop *l) { if (!l || l->timer_count <= 0) return -1; - uint64_t now = yasl_loop_now_ns(); + uint64_t now = yasl_private_loop_now_ns(); uint64_t min_deadline = UINT64_MAX; bool has_active = false; for (int i = 0; i < l->timer_count; i++) { @@ -446,14 +446,14 @@ int yasl_loop_next_timeout_ms(const struct yasl_loop *l) return (ms > (uint64_t)INT_MAX) ? INT_MAX : (int)ms; } -yasl_timer_id yasl_loop_add_timer(struct yasl_loop *l, uint64_t interval_ns, - yasl_timer_cb cb, void *ud) +yasl_private_timer_id yasl_private_loop_add_timer(struct yasl_private_loop *l, uint64_t interval_ns, + yasl_private_timer_cb cb, void *ud) { if (!l || !cb || interval_ns == 0) return 0; if (l->timer_count >= l->timer_capacity) { int new_cap = l->timer_capacity ? l->timer_capacity * 2 : 16; - struct yasl_timer_source *new_timers = realloc(l->timers, (size_t)new_cap * sizeof(*new_timers)); + struct yasl_private_timer_source *new_timers = realloc(l->timers, (size_t)new_cap * sizeof(*new_timers)); if (!new_timers) return 0; l->timers = new_timers; l->timer_capacity = new_cap; @@ -462,8 +462,8 @@ yasl_timer_id yasl_loop_add_timer(struct yasl_loop *l, uint64_t interval_ns, uint32_t id = l->next_timer_id++; if (l->next_timer_id == 0) l->next_timer_id = 1; - uint64_t now = yasl_loop_now_ns(); - l->timers[l->timer_count++] = (struct yasl_timer_source){ + uint64_t now = yasl_private_loop_now_ns(); + l->timers[l->timer_count++] = (struct yasl_private_timer_source){ .fn = cb, .ud = ud, .id = id, @@ -472,11 +472,11 @@ yasl_timer_id yasl_loop_add_timer(struct yasl_loop *l, uint64_t interval_ns, .deleted = false, }; - yasl_loop_kick(l); + yasl_private_loop_kick(l); return id; } -bool yasl_loop_del_timer(struct yasl_loop *l, yasl_timer_id id) +bool yasl_private_loop_del_timer(struct yasl_private_loop *l, yasl_private_timer_id id) { if (!l || id == 0) return false; for (int i = l->timer_count - 1; i >= 0; i--) { @@ -496,11 +496,11 @@ bool yasl_loop_del_timer(struct yasl_loop *l, yasl_timer_id id) return false; } -int yasl_loop_step(struct yasl_loop *l, int timeout_ms) +int yasl_private_loop_step(struct yasl_private_loop *l, int timeout_ms) { if (!l) return -1; - int timer_to = yasl_loop_next_timeout_ms(l); + int timer_to = yasl_private_loop_next_timeout_ms(l); int effective_timeout = timeout_ms; if (timer_to >= 0) { if (effective_timeout < 0 || timer_to < effective_timeout) @@ -528,9 +528,9 @@ int yasl_loop_step(struct yasl_loop *l, int timeout_ms) if (l->count > 0) { int count = l->count; - struct yasl_fd_source sstack[32]; + struct yasl_private_fd_source sstack[32]; struct pollfd pstack[32]; - struct yasl_fd_source *scopy = (count <= 32) ? sstack : malloc((size_t)count * sizeof(*scopy)); + struct yasl_private_fd_source *scopy = (count <= 32) ? sstack : malloc((size_t)count * sizeof(*scopy)); struct pollfd *pcopy = (count <= 32) ? pstack : malloc((size_t)count * sizeof(*pcopy)); if (!scopy || !pcopy) { if (scopy && scopy != sstack) free(scopy); @@ -570,7 +570,7 @@ int yasl_loop_step(struct yasl_loop *l, int timeout_ms) } if (l->timer_count > 0) { - uint64_t now = yasl_loop_now_ns(); + uint64_t now = yasl_private_loop_now_ns(); l->timer_firing_depth++; int initial_count = l->timer_count; for (int i = 0; i < initial_count; i++) { @@ -578,10 +578,10 @@ int yasl_loop_step(struct yasl_loop *l, int timeout_ms) if (l->timers[i].deleted || l->timers[i].deadline_ns > now) continue; - yasl_timer_id tid = l->timers[i].id; + yasl_private_timer_id tid = l->timers[i].id; uint64_t interval = l->timers[i].interval_ns; void *ud = l->timers[i].ud; - struct yasl_timer_source timer_src = l->timers[i]; + struct yasl_private_timer_source timer_src = l->timers[i]; uint64_t next_interval = timer_src.fn(ud, tid, interval); handled++; @@ -623,18 +623,18 @@ int yasl_loop_step(struct yasl_loop *l, int timeout_ms) return handled; } -int yasl_loop_run(struct yasl_loop *l) +int yasl_private_loop_run(struct yasl_private_loop *l) { if (!l) return -1; l->running = true; while (l->running) { - if (yasl_loop_step(l, -1) < 0) + if (yasl_private_loop_step(l, -1) < 0) return -1; } return 0; } -void yasl_loop_quit(struct yasl_loop *l) +void yasl_private_loop_quit(struct yasl_private_loop *l) { if (l) l->running = false; } diff --git a/src/platform/posix/yasl_platform_sync.h b/src/platform/posix/yasl_platform_sync.h index f94a25d..972eef2 100644 --- a/src/platform/posix/yasl_platform_sync.h +++ b/src/platform/posix/yasl_platform_sync.h @@ -1,26 +1,26 @@ -#ifndef YASL_POSIX_SYNC_H -#define YASL_POSIX_SYNC_H +#ifndef YASL_PRIVATE_POSIX_SYNC_H +#define YASL_PRIVATE_POSIX_SYNC_H #include -typedef pthread_mutex_t yasl_mutex; +typedef pthread_mutex_t yasl_private_mutex; -static inline int yasl_mutex_init(yasl_mutex *mutex) +static inline int yasl_private_mutex_init(yasl_private_mutex *mutex) { return pthread_mutex_init(mutex, NULL); } -static inline void yasl_mutex_destroy(yasl_mutex *mutex) +static inline void yasl_private_mutex_destroy(yasl_private_mutex *mutex) { pthread_mutex_destroy(mutex); } -static inline void yasl_mutex_lock(yasl_mutex *mutex) +static inline void yasl_private_mutex_lock(yasl_private_mutex *mutex) { pthread_mutex_lock(mutex); } -static inline void yasl_mutex_unlock(yasl_mutex *mutex) +static inline void yasl_private_mutex_unlock(yasl_private_mutex *mutex) { pthread_mutex_unlock(mutex); } -- cgit v1.2.3