From 3b8af02be94a510e385f44d58c35c86bb89424a6 Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Mon, 12 Oct 2026 08:41:51 +0300 Subject: refactor: simplify public API and isolate native extensions Separate loop/timer and native interoperability APIs from the portable surface header. Unify dispatch, geometry queries, and timer callbacks; keep framebuffer bookkeeping and frame clocks private, and hide implementation symbols. Update backends, documentation, examples, and API/integration coverage. Verify exports, strict C/C++ installed consumers, and normal plus ASan/UBSan suites. --- src/wayland/api.h | 7 +++---- src/wayland/backend.c | 23 ++++++----------------- src/wayland/buffer.c | 8 +------- src/wayland/internal.h | 2 +- src/wayland/popup.c | 17 +++++++++++------ src/wayland/surface.c | 27 +++++++++------------------ 6 files changed, 31 insertions(+), 53 deletions(-) (limited to 'src/wayland') diff --git a/src/wayland/api.h b/src/wayland/api.h index 8252041..87e896d 100644 --- a/src/wayland/api.h +++ b/src/wayland/api.h @@ -9,7 +9,6 @@ struct wayland_surface; struct wayland_display *wayland_display_open(struct yasl_loop *loop, const struct yasl_display_spec *spec); void wayland_display_close(struct wayland_display *d); uint32_t wayland_display_caps(const struct wayland_display *d); -void wayland_display_dispatch(struct wayland_display *d); int wayland_display_dispatch_timeout(struct wayland_display *d, int timeout_ms); void wayland_display_flush(struct wayland_display *d); int wayland_display_modifiers(const struct wayland_display *d); @@ -17,7 +16,8 @@ void wayland_display_copy(struct wayland_display *d, enum yasl_selection sel, co void wayland_display_paste(struct wayland_display *d, enum yasl_selection sel, struct wayland_surface *target); bool wayland_display_drag_start(struct wayland_display *d, struct wayland_surface *origin, const struct yasl_drag_image *image, const struct yasl_drag_listener *l, void *ud); void wayland_display_drag_cancel(struct wayland_display *d); -struct wayland_surface *wayland_surface_create_toplevel(struct wayland_display *d, const struct yasl_surface_spec *spec); +struct wayland_surface *wayland_surface_create_toplevel(struct wayland_display *d, + const struct yasl_surface_spec *spec, void *graphics_device); struct wayland_surface *wayland_surface_create_popup(struct wayland_surface *parent, const struct yasl_popup_spec *spec); bool wayland_surface_popup_reposition(struct wayland_surface *popup, const struct yasl_popup_spec *spec); void wayland_surface_destroy(struct wayland_surface *s); @@ -27,8 +27,7 @@ void wayland_surface_set_title(struct wayland_surface *s, const char *title); void wayland_surface_schedule_redraw(struct wayland_surface *s); bool wayland_surface_present(struct wayland_surface *s, const struct yasl_framebuffer *fb, const struct yasl_damage_list *damage); bool wayland_surface_input_poll(struct wayland_surface *s, struct yasl_input_event *ev); -struct yasl_vector2i wayland_surface_size(const struct wayland_surface *s); -uint32_t wayland_surface_scale_120(const struct wayland_surface *s); +struct yasl_geometry wayland_surface_geometry(const struct wayland_surface *s); uint32_t wayland_surface_state(const struct wayland_surface *s); struct yasl_timing wayland_surface_timing(const struct wayland_surface *s); uint64_t wayland_surface_frame_time_ns(struct wayland_surface *s, uint64_t now); diff --git a/src/wayland/backend.c b/src/wayland/backend.c index 31e412f..5c34def 100644 --- a/src/wayland/backend.c +++ b/src/wayland/backend.c @@ -16,11 +16,6 @@ static uint32_t impl_display_caps(const struct yasl_display *d) return wayland_display_caps((const struct wayland_display *)d); } -static void impl_display_dispatch(struct yasl_display *d) -{ - wayland_display_dispatch((struct wayland_display *)d); -} - static int impl_display_dispatch_timeout(struct yasl_display *d, int timeout_ms) { return wayland_display_dispatch_timeout((struct wayland_display *)d, timeout_ms); @@ -56,9 +51,10 @@ static void impl_display_drag_cancel(struct yasl_display *d) wayland_display_drag_cancel((struct wayland_display *)d); } -static struct yasl_surface *impl_surface_create_toplevel(struct yasl_display *d, const struct yasl_surface_spec *spec) +static struct yasl_surface *impl_surface_create_toplevel(struct yasl_display *d, + const struct yasl_surface_spec *spec, void *graphics_device) { - struct wayland_surface *result = wayland_surface_create_toplevel((struct wayland_display *)d, spec); + struct wayland_surface *result = wayland_surface_create_toplevel((struct wayland_display *)d, spec, graphics_device); return result ? &result->base : NULL; } @@ -109,14 +105,9 @@ static bool impl_surface_input_poll(struct yasl_surface *s, struct yasl_input_ev return wayland_surface_input_poll((struct wayland_surface *)s, ev); } -static struct yasl_vector2i impl_surface_size(const struct yasl_surface *s) -{ - return wayland_surface_size((const struct wayland_surface *)s); -} - -static uint32_t impl_surface_scale_120(const struct yasl_surface *s) +static struct yasl_geometry impl_surface_geometry(const struct yasl_surface *s) { - return wayland_surface_scale_120((const struct wayland_surface *)s); + return wayland_surface_geometry((const struct wayland_surface *)s); } static uint32_t impl_surface_state(const struct yasl_surface *s) @@ -199,7 +190,6 @@ const struct yasl_backend_ops yasl_wayland_backend = { .display_open = impl_display_open, .display_close = impl_display_close, .display_caps = impl_display_caps, - .display_dispatch = impl_display_dispatch, .display_dispatch_timeout = impl_display_dispatch_timeout, .display_flush = impl_display_flush, .display_modifiers = impl_display_modifiers, @@ -217,8 +207,7 @@ const struct yasl_backend_ops yasl_wayland_backend = { .surface_schedule_redraw = impl_surface_schedule_redraw, .surface_present = impl_surface_present, .surface_input_poll = impl_surface_input_poll, - .surface_size = impl_surface_size, - .surface_scale_120 = impl_surface_scale_120, + .surface_geometry = impl_surface_geometry, .surface_state = impl_surface_state, .surface_timing = impl_surface_timing, .surface_frame_time_ns = impl_surface_frame_time_ns, diff --git a/src/wayland/buffer.c b/src/wayland/buffer.c index 3f9cf84..a1486fa 100644 --- a/src/wayland/buffer.c +++ b/src/wayland/buffer.c @@ -446,8 +446,7 @@ bool wayland_surface_present(struct wayland_surface *w, const struct yasl_frameb { if (!w || w->closed || !w->frame_active || w->frame_presented || !fb || !damage || fb->pixels != w->frame.target.pixels || - fb->size.x != w->width || fb->size.y != w->height || - fb->buffer != w->cur || fb->native_drawable || fb->transaction) + fb->size.x != w->width || fb->size.y != w->height) return false; w->damage = *damage; @@ -491,11 +490,6 @@ void surface_draw_frame(struct wayland_surface *w) .generation = yasl_frame_begin(&w->base), .pixels = w->buffers[idx].pixels, .size = { .x = w->width, .y = w->height }, - .buffer = idx, - .cleared = w->parent != NULL, - .damage = &w->damage, - .native_drawable = NULL, - .transaction = false, }, }; w->frame_active = true; diff --git a/src/wayland/internal.h b/src/wayland/internal.h index ccfd2dc..249fc8d 100644 --- a/src/wayland/internal.h +++ b/src/wayland/internal.h @@ -4,7 +4,7 @@ #define _GNU_SOURCE #include "api.h" -#include "yasl/timing.h" +#include "common/timing.h" #include "clipboard.h" #include diff --git a/src/wayland/popup.c b/src/wayland/popup.c index f0ef305..63bcba6 100644 --- a/src/wayland/popup.c +++ b/src/wayland/popup.c @@ -23,13 +23,18 @@ static const struct xdg_popup_listener popup_listener = { .repositioned = popup_repositioned, }; -static bool popup_spec_valid(const struct yasl_popup_spec *spec) +static bool popup_spec_valid(const struct wayland_surface *parent, + const struct yasl_popup_spec *spec) { - return spec && spec->size.x > 0 && spec->size.y > 0 && + if (!parent || !spec) return false; + int64_t x = (int64_t)spec->anchor.x - parent->content.x; + int64_t y = (int64_t)spec->anchor.y - parent->content.y; + return x >= INT_MIN && x <= INT_MAX && y >= INT_MIN && y <= INT_MAX && + spec->size.x > 0 && spec->size.y > 0 && spec->content_offset.x >= 0 && spec->content_offset.y >= 0 && spec->content_size.x >= 0 && spec->content_size.y >= 0 && - spec->content_offset.x + spec->content_size.x <= spec->size.x && - spec->content_offset.y + spec->content_size.y <= spec->size.y; + (int64_t)spec->content_offset.x + spec->content_size.x <= spec->size.x && + (int64_t)spec->content_offset.y + spec->content_size.y <= spec->size.y; } static bool popup_apply_spec(struct wayland_surface *w, const struct yasl_popup_spec *spec) @@ -125,7 +130,7 @@ struct wayland_surface *wayland_surface_create_popup(struct wayland_surface *par struct wayland_display *c = parent ? parent->conn : NULL; struct seat *seat = c ? conn_active_seat(c) : NULL; if (!c || c->lost || parent->closed || !parent->xdg_surface || !seat || - !seat->input_serial || !popup_spec_valid(spec)) + !seat->input_serial || !popup_spec_valid(parent, spec)) return NULL; struct wayland_surface *w = calloc(1, sizeof(*w)); @@ -170,7 +175,7 @@ err: bool wayland_surface_popup_reposition(struct wayland_surface *w, const struct yasl_popup_spec *spec) { if (!w || !w->popup || w->closed || !w->conn || w->conn->lost || - !popup_spec_valid(spec) || + !popup_spec_valid(w->parent, spec) || xdg_popup_get_version(w->popup) < XDG_POPUP_REPOSITION_SINCE_VERSION) return false; struct yasl_popup_spec old = { diff --git a/src/wayland/surface.c b/src/wayland/surface.c index 4f064e2..f291190 100644 --- a/src/wayland/surface.c +++ b/src/wayland/surface.c @@ -148,13 +148,13 @@ int wayland_display_dispatch_timeout(struct wayland_display *c, int timeout_ms) return -1; } - bool had_pending = display_arm(c); + display_arm(c); if (c->lost) { display_leave(c); return -1; } - if (had_pending && timeout_ms != 0 && display_has_immediate_work(c)) { + if (timeout_ms != 0 && display_has_immediate_work(c)) { timeout_ms = 0; } @@ -177,14 +177,6 @@ int wayland_display_dispatch_timeout(struct wayland_display *c, int timeout_ms) return n; } -void wayland_display_dispatch(struct wayland_display *c) -{ - if (unlikely(!c || c->lost)) - return; - int timeout = (display_has_immediate_work(c) || yasl_loop_is_running(c->loop)) ? 0 : -1; - wayland_display_dispatch_timeout(c, timeout); -} - void wayland_display_flush(struct wayland_display *c) { if (!c || c->lost) @@ -342,8 +334,9 @@ static bool spec_valid(const struct yasl_surface_spec *spec) } struct wayland_surface *wayland_surface_create_toplevel(struct wayland_display *c, - const struct yasl_surface_spec *spec) + const struct yasl_surface_spec *spec, void *graphics_device) { + (void)graphics_device; if (!c || c->lost || !spec_valid(spec)) return NULL; int width = spec->size.x, height = spec->size.y; @@ -457,14 +450,12 @@ void wayland_surface_schedule_redraw(struct wayland_surface *w) yasl_loop_kick(w->conn->loop); } -struct yasl_vector2i wayland_surface_size(const struct wayland_surface *w) +struct yasl_geometry wayland_surface_geometry(const struct wayland_surface *w) { - return w ? (struct yasl_vector2i){ .x = w->width, .y = w->height } : (struct yasl_vector2i){0}; -} - -uint32_t wayland_surface_scale_120(const struct wayland_surface *w) -{ - return w ? w->scale_120 : YASL_SCALE_UNIT; + return (struct yasl_geometry){ + .size = w ? (struct yasl_vector2i){w->width, w->height} : (struct yasl_vector2i){0}, + .scale_120 = w ? w->scale_120 : YASL_SCALE_UNIT, + }; } void wayland_surface_set_background_color(struct wayland_surface *w, uint32_t bg) -- cgit v1.2.3