diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-14 13:56:48 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-14 13:56:48 +0300 |
| commit | 87279f6903343e621c0446b20d1e7d6a495f1125 (patch) | |
| tree | 999b5fb5fb76702efb02f856f082147304f0859b /tests | |
| parent | 1ab3e5a123109704789c2768e11a4f9af515821d (diff) | |
Simplify the public API into one dense header
yasl.h now holds everything except Vulkan: 45 functions instead of 62,
and three installed headers instead of ten.
- One constructor: yasl_surface_create takes CPU, GL or NATIVE, with
zero-initialized GL options meaning 3.2 core, RGBA8, D24S8.
- Events carry action, mods, x, y and text at the top level; pen
positions are now logical like pointer positions.
- yasl_cpu_pixels/yasl_cpu_present draw into one persistent canvas,
cutting three full-frame copies per frame.
- yasl_surface_get_info, yasl_surface_request, YASL_CURSOR_LOCKED,
yasl_surface_set_text_input, yasl_surface_begin_move_resize and
yasl_surface_get_native replace groups of narrower calls.
- Interactive calls drop the decorative trigger event argument.
- yasl_wait_event returns 0 only on timeout or yasl_wake, the refresh
callback runs only in native modal loops, focus loss sends
INPUT_RESET, and a lost event no longer fails every later wait.
- Unsupported operations and bad arguments report ENOTSUP and EINVAL
instead of EIO; the keycodes header no longer needs C23.
- The shared library gets a versioned SONAME and version macros.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/common/test_gl.c | 35 | ||||
| -rw-r--r-- | tests/common/test_surface_integration.c | 316 | ||||
| -rw-r--r-- | tests/common/test_vulkan.c | 17 | ||||
| -rw-r--r-- | tests/meson.build | 9 | ||||
| -rw-r--r-- | tests/test_api.cpp | 27 | ||||
| -rw-r--r-- | tests/test_lifecycle.c | 38 | ||||
| -rw-r--r-- | tests/wayland/test_reconnect.c | 41 | ||||
| -rw-r--r-- | tests/x11/test_tablet_native.c | 48 |
8 files changed, 253 insertions, 278 deletions
diff --git a/tests/common/test_gl.c b/tests/common/test_gl.c index 0e4597b..2bf3d8c 100644 --- a/tests/common/test_gl.c +++ b/tests/common/test_gl.c @@ -1,6 +1,6 @@ #define _POSIX_C_SOURCE 200809L -#include <yasl/gl.h> +#include <yasl/yasl.h> #include <math.h> #include <stdio.h> #include <stdlib.h> @@ -60,7 +60,9 @@ static void wait_for_size(yasl_surface *surface, int width, int height) double deadline = seconds_now() + 8.0; int actual_width = 0, actual_height = 0; while (seconds_now() < deadline) { - yasl_surface_get_size(surface, &actual_width, &actual_height); + struct yasl_surface_info info = yasl_surface_get_info(surface); + actual_width = info.width; + actual_height = info.height; if (actual_width == width && actual_height == height) return; yasl_event event = {0}; int result = yasl_wait_event(&event, 50); @@ -75,11 +77,12 @@ static void wait_for_size(yasl_surface *surface, int width, int height) int main(int argc, char **argv) { REQUIRE(argc == 2, "expected backend argument: wayland or x11"); - if (!strcmp(argv[1], "wayland")) REQUIRE((yasl_init(&(struct yasl_options){.backend=YASL_BACKEND_WAYLAND}) == 0), "select Wayland backend"); - else if (!strcmp(argv[1], "x11")) REQUIRE((yasl_init(&(struct yasl_options){.backend=YASL_BACKEND_X11}) == 0), "select X11 backend"); + if (!strcmp(argv[1], "wayland")) REQUIRE(yasl_init(YASL_BACKEND_WAYLAND, NULL) == 0, "select Wayland backend"); + else if (!strcmp(argv[1], "x11")) REQUIRE(yasl_init(YASL_BACKEND_X11, NULL) == 0, "select X11 backend"); else REQUIRE(false, "backend must be wayland or x11"); - primary = yasl_gl_surface_create(&(struct yasl_surface_options){.title="YASL GL test", .width=320, .height=240, .type=YASL_SURFACE_NATIVE, .flags=0}, NULL); + primary = yasl_surface_create(&(struct yasl_surface_options){.title="YASL GL test", .width=320, .height=240, .type=YASL_SURFACE_GL}); + REQUIRE(yasl_get_features() & YASL_FEATURE_OPENGL, "report OpenGL support"); REQUIRE(primary != NULL, "create default OpenGL 3.2 surface"); REQUIRE((yasl_gl_make_current(primary) == 0), "make first GL context current"); @@ -109,7 +112,8 @@ int main(int argc, char **argv) finish(); unsigned char pixel[4] = {0}; int pixel_width = 0, pixel_height = 0; - yasl_surface_get_framebuffer_size(primary, &pixel_width, &pixel_height); + pixel_width = yasl_surface_get_info(primary).pixel_width; + pixel_height = yasl_surface_get_info(primary).pixel_height; REQUIRE(pixel_width > 0 && pixel_height > 0, "query initial framebuffer size"); read_pixels(pixel_width / 2, pixel_height / 2, 1, 1, GL_RGBA_, GL_UNSIGNED_BYTE_, pixel); REQUIRE(abs((int)pixel[0] - 51) <= 3 && abs((int)pixel[1] - 102) <= 3 && @@ -123,9 +127,7 @@ int main(int argc, char **argv) bind_texture(GL_TEXTURE_2D_, texture); REQUIRE(is_texture(texture), "create a shareable GL texture"); - struct yasl_gl_options sharing = YASL_GL_OPTIONS_INIT; - sharing.share = primary; - shared = yasl_gl_surface_create(&(struct yasl_surface_options){.title="YASL GL shared context", .width=160, .height=120, .type=YASL_SURFACE_NATIVE, .flags=0}, &sharing); + shared = yasl_surface_create(&(struct yasl_surface_options){.title="YASL GL shared context", .width=160, .height=120, .type=YASL_SURFACE_GL, .gl = {.share = primary}}); REQUIRE(shared != NULL, "create shared GL context"); REQUIRE((yasl_gl_make_current(shared) == 0), "make shared context current"); REQUIRE(is_texture(texture), "verify context shares GL objects"); @@ -134,8 +136,9 @@ int main(int argc, char **argv) REQUIRE((yasl_surface_request_size(primary, 400, 300) == 0), "request surface resize"); wait_for_size(primary, 400, 300); - yasl_surface_get_framebuffer_size(primary, &pixel_width, &pixel_height); - double scale = yasl_surface_get_scale(primary); + pixel_width = yasl_surface_get_info(primary).pixel_width; + pixel_height = yasl_surface_get_info(primary).pixel_height; + double scale = yasl_surface_get_info(primary).scale; REQUIRE(abs(pixel_width - (int)lround(400 * scale)) <= 1 && abs(pixel_height - (int)lround(300 * scale)) <= 1, "query resized framebuffer dimensions"); @@ -143,13 +146,11 @@ int main(int argc, char **argv) clear(GL_COLOR_BUFFER_BIT_); REQUIRE((yasl_gl_present(primary) == 0), "swap resized GL surface"); - struct yasl_gl_options invalid_options = YASL_GL_OPTIONS_INIT; - invalid_options.major = -1; - REQUIRE(yasl_gl_surface_create(&(struct yasl_surface_options){.title="invalid attrs", .width=100, .height=100, .type=YASL_SURFACE_NATIVE, .flags=0}, &invalid_options) == NULL, + REQUIRE(yasl_surface_create(&(struct yasl_surface_options){.title="invalid attrs", .width=100, .height=100, .type=YASL_SURFACE_GL, .gl = {.major = -1}}) == NULL && errno == EINVAL, "reject invalid GL context options"); - REQUIRE(yasl_gl_surface_create(&(struct yasl_surface_options){.title="invalid CPU GL", .width=100, .height=100, .type=YASL_SURFACE_CPU, .flags=0}, NULL) == NULL, - "reject CPU flag on GL surface creation"); - cpu = yasl_surface_create(&(struct yasl_surface_options){.title="CPU surface", .width=100, .height=100, .type=YASL_SURFACE_CPU, .flags=0}); + cpu = yasl_surface_create(&(struct yasl_surface_options){.title="CPU surface", .width=100, .height=100}); + REQUIRE(yasl_surface_create(&(struct yasl_surface_options){.title="no CPU sharing", .width=100, .height=100, .type=YASL_SURFACE_GL, .gl = {.share = cpu}}) == NULL && errno == EINVAL, + "reject a non-GL share surface"); REQUIRE(cpu != NULL, "create CPU surface for incompatibility check"); REQUIRE((yasl_gl_make_current(cpu) < 0), "reject CPU surface as a GL context"); diff --git a/tests/common/test_surface_integration.c b/tests/common/test_surface_integration.c index 1f18f23..072a307 100644 --- a/tests/common/test_surface_integration.c +++ b/tests/common/test_surface_integration.c @@ -1,17 +1,5 @@ #define _POSIX_C_SOURCE 200809L #include <yasl/yasl.h> -#include <yasl/cpu.h> -#include <yasl/gl.h> -#include <yasl/metal.h> -#if YASL_HAS_WAYLAND -#include <yasl/native/wayland.h> -#endif -#if YASL_HAS_X11 -#include <yasl/native/x11.h> -#endif -#if YASL_HAS_COCOA -#include <yasl/native/cocoa.h> -#endif #include "common/backend.h" #include <assert.h> #include <pthread.h> @@ -40,18 +28,20 @@ static void *wake_thread(void *unused) static void *wrong_thread(void *data) { assert(yasl_surface_set_title(data, "wrong") == -EPERM); - struct yasl_cpu_buffer buffer; - assert(yasl_cpu_acquire(data, &buffer) == -EPERM && !buffer.pixels); -#if YASL_HAS_WAYLAND - struct yasl_wayland_handles native; - assert(yasl_wayland_get_native(data, &native) == -EPERM && !native.display && !native.surface); -#endif + int w = 1, h = 1; + assert(!yasl_cpu_pixels(data, &w, &h) && errno == EPERM && !w && !h); + struct yasl_native native; + assert(yasl_surface_get_native(data, &native) == -EPERM && !native.wl_display && !native.x11_display); return NULL; } +static void push(yasl_surface *s, struct yasl_private_event event) +{ + event.surface = s; + assert(yasl_private_events_push(s->display, s, &event)); +} static int refreshes; -static void refresh(yasl_surface *s, void *ud) +static void refresh(yasl_surface *s) { - (void)ud; refreshes++; yasl_event e; assert(yasl_wait_event(&e, 0) == -EBUSY); @@ -59,7 +49,10 @@ static void refresh(yasl_surface *s, void *ud) assert(yasl_surface_destroy(s) == -EBUSY); struct yasl_surface_options options = {.width = 32, .height = 32}; assert(!yasl_surface_create(&options) && errno == EBUSY); - assert(!yasl_gl_surface_create(&options, NULL) && errno == EBUSY); + options.type = YASL_SURFACE_GL; + assert(!yasl_surface_create(&options) && errno == EBUSY); + int w, h; + assert(yasl_cpu_pixels(s, &w, &h) && yasl_cpu_present(s) == 0); } int main(int argc, char **argv) { @@ -67,53 +60,32 @@ int main(int argc, char **argv) enum yasl_backend backend = !strcmp(argv[1], "wayland") ? YASL_BACKEND_WAYLAND : !strcmp(argv[1], "x11") ? YASL_BACKEND_X11 : YASL_BACKEND_COCOA; - assert(yasl_init( - &(struct yasl_options){.backend = backend, .app_id = "org.yasl.surface-test"}) == 0); - yasl_surface *s = yasl_surface_create(&(struct yasl_surface_options){ - .title = "CPU contract", .width = 96, .height = 80, .type = YASL_SURFACE_CPU, .flags = 0}); + assert(yasl_init(backend, "org.yasl.surface-test") == 0); + assert(yasl_init(backend, NULL) == -EALREADY); + assert(yasl_get_backend() == backend); + unsigned features = yasl_get_features(); + yasl_surface *s = yasl_surface_create( + &(struct yasl_surface_options){.title = "CPU contract", .width = 96, .height = 80}); if (!s) { - const char *why; - why = strerror(errno); - fprintf(stderr, "surface: %s native=%d\n", why, errno); + fprintf(stderr, "surface: %s\n", strerror(errno)); return 1; } - assert(yasl_surface_get_backend(s) == backend); assert(yasl_surface_set_userdata(s, &backend) == 0); assert(yasl_surface_get_userdata(s) == &backend); -#if YASL_HAS_WAYLAND - struct yasl_wayland_handles wl; - int wl_result = yasl_wayland_get_native(s, &wl); - assert(wl_result == (backend == YASL_BACKEND_WAYLAND ? 0 : -ENOTSUP)); - assert(backend == YASL_BACKEND_WAYLAND ? wl.display && wl.surface : !wl.display && !wl.surface); - assert(yasl_wayland_get_native(s, NULL) == -EINVAL); -#endif -#if YASL_HAS_X11 - struct yasl_x11_handles x; - int x_result = yasl_x11_get_native(s, &x); - assert(x_result == (backend == YASL_BACKEND_X11 ? 0 : -ENOTSUP)); - assert(backend == YASL_BACKEND_X11 ? x.display && x.window : !x.display && !x.window); -#endif -#if YASL_HAS_COCOA - struct yasl_cocoa_handles cocoa; - assert(yasl_cocoa_get_native(s, &cocoa) == 0 && cocoa.application && cocoa.window && - cocoa.view); -#endif - CAMetalLayer *layer = NULL; - assert(yasl_metal_get_layer(s, &layer) == -EBUSY && !layer); - assert(yasl_surface_set_ime_caret(s, 1e300, 0, 1, 1) == -EOVERFLOW); + struct yasl_native native; + assert(yasl_surface_get_native(s, &native) == 0); + assert(backend != YASL_BACKEND_WAYLAND || (native.wl_display && native.wl_surface)); + assert(backend != YASL_BACKEND_X11 || (native.x11_display && native.x11_window)); + assert(backend != YASL_BACKEND_COCOA || (native.ns_window && native.ns_view)); + assert(yasl_surface_get_native(s, NULL) == -EINVAL); + assert(!yasl_metal_get_layer(s) && errno == EBUSY); if (backend == YASL_BACKEND_COCOA) { - assert(!(yasl_surface_get_features(s) & YASL_CAP_OPENGL)); - assert(!yasl_gl_surface_create(&(struct yasl_surface_options){.title = "unsupported GL", - .width = 64, - .height = 64, - .type = YASL_SURFACE_NATIVE, - .flags = 0}, - NULL)); - assert(errno == ENOTSUP); - assert((yasl_gl_make_current(NULL) < 0)); - assert(errno == ENOTSUP); - assert(!yasl_gl_get_proc_address("glClear")); + assert(!(features & YASL_FEATURE_OPENGL)); + assert(!yasl_surface_create(&(struct yasl_surface_options){ + .title = "unsupported GL", .width = 64, .height = 64, .type = YASL_SURFACE_GL})); assert(errno == ENOTSUP); + assert(yasl_gl_make_current(NULL) == 0); + assert(!yasl_gl_get_proc_address("glClear") && errno == ENOTSUP); } /* The first events report the window size, then ask for a frame. */ yasl_event e; @@ -132,131 +104,155 @@ int main(int argc, char **argv) } } assert(e.type == YASL_EVENT_REFRESH); + struct yasl_surface_info info = yasl_surface_get_info(s); + assert(info.pixel_width == fw && info.pixel_height == fh && info.scale > 0); + + /* CPU pixels persist between frames and are the window's own buffer. */ int w, h; - yasl_surface_get_framebuffer_size(s, &w, &h); - assert(w == fw && h == fh); - assert((yasl_init(&(struct yasl_options){.backend = backend}) < 0)); - assert(errno == EALREADY); - struct yasl_cpu_buffer buffer, other; - assert(yasl_cpu_acquire(s, &buffer) == 0); - uint32_t *pixels = buffer.pixels; - assert(buffer.width == w && buffer.height == h && buffer.stride_bytes == (size_t)w * 4); + uint32_t *pixels = yasl_cpu_pixels(s, &w, &h); + assert(pixels && w == fw && h == fh); assert(pixels[0] == 0 && pixels[(size_t)w * h - 1] == 0); - assert(yasl_cpu_acquire(s, &other) == -EBUSY && !other.pixels); for (size_t i = 0; i < (size_t)w * h; i++) pixels[i] = 0xff102030u; pixels[(size_t)3 * w + 2] = 0xffaabbccu; - other = buffer; - other.stride_bytes++; - assert(yasl_cpu_present(s, &other) == -EINVAL); - assert(yasl_cpu_present(s, &buffer) == 0); - assert(yasl_cpu_present(s, &buffer) == -ESTALE); - assert(yasl_cpu_acquire(s, &buffer) == 0); - assert(buffer.pixels[0] == 0xff102030u && buffer.pixels[(size_t)3 * w + 2] == 0xffaabbccu); - buffer.pixels[0] = 0xffffffffu; - assert(s->committed_pixels[0] == 0xff102030u); - assert(yasl_cpu_discard(s, &buffer) == 0); - assert(yasl_cpu_discard(s, &buffer) == -ESTALE); - assert(yasl_cpu_acquire(s, &buffer) == 0 && buffer.pixels[0] == 0xff102030u); + assert(yasl_cpu_present(s) == 0); + drain(); + pixels = yasl_cpu_pixels(s, &w, &h); + assert(pixels[0] == 0xff102030u && pixels[(size_t)3 * w + 2] == 0xffaabbccu); + + /* Waiting ends only on an event, the timeout or yasl_wake, never early. */ + drain(); + uint64_t start = yasl_time_ns(); + int n = yasl_wait_event(&e, 200); + assert(n == 1 || yasl_time_ns() - start >= 190000000ull); drain(); - assert(yasl_cpu_present(s, &buffer) == -ESTALE); - yasl_surface *second = yasl_surface_create(&(struct yasl_surface_options){ - .width = 32, .height = 32, .type = YASL_SURFACE_CPU, .userdata = &backend}); - assert(second && yasl_surface_get_userdata(second) == &backend); - assert(yasl_cpu_acquire(s, &buffer) == 0); - assert(yasl_cpu_acquire(second, &other) == 0); - assert(yasl_cpu_present(second, &buffer) == -ESTALE); - assert(yasl_cpu_discard(second, &other) == 0); - assert(yasl_surface_destroy(second) == 0); - assert(yasl_cpu_discard(s, &buffer) == 0); pthread_t thread; - assert(!pthread_create(&thread, NULL, wrong_thread, s)); - pthread_join(thread, NULL); assert(!pthread_create(&thread, NULL, wake_thread, NULL)); - int n = yasl_wait_event(&e, 500); - assert(n >= 0); + start = yasl_time_ns(); + n = yasl_wait_event(&e, 5000); pthread_join(thread, NULL); - bool ime = (yasl_surface_set_text_input(s, true, YASL_TEXT_NORMAL) == 0); - if (!ime) - assert(errno == ENOTSUP); - bool snapshot = (yasl_surface_set_surrounding_text(s, "a\xc3\xa9z", 4, 1, 3, 7) == 0); - if (ime) - assert(snapshot); - else - assert(!snapshot && errno == ENOTSUP); - assert((yasl_surface_set_surrounding_text(s, "a\xc3\xa9z", 4, 2, 3, 8) < 0)); - assert((yasl_surface_set_surrounding_text(s, "\xc0\xaf", 2, 0, 2, 8) < 0)); + assert(n == 1 || (n == 0 && yasl_time_ns() - start < 4000000000ull)); + assert(!pthread_create(&thread, NULL, wrong_thread, s)); + pthread_join(thread, NULL); + + yasl_surface *second = yasl_surface_create( + &(struct yasl_surface_options){.width = 32, .height = 32, .userdata = &backend}); + assert(second && yasl_surface_get_userdata(second) == &backend); + assert(yasl_surface_destroy(second) == 0); + + /* Text input */ + int ime = yasl_surface_set_text_input(s, &(struct yasl_text_input){ + .text = "a\xc3\xa9z", .length = 4, .selection_begin = 1, .selection_end = 3, + .revision = 7, .caret_x = 1, .caret_y = 2, .caret_width = 1, .caret_height = 10}); + assert(ime == 0 || ime == -ENOTSUP); + assert(yasl_surface_set_text_input(s, &(struct yasl_text_input){ + .text = "a\xc3\xa9z", .length = 4, .selection_begin = 2, .selection_end = 3}) == -EILSEQ); + assert(yasl_surface_set_text_input(s, &(struct yasl_text_input){ + .text = "\xc0\xaf", .length = 2}) == -EILSEQ); + assert(yasl_surface_set_text_input(s, &(struct yasl_text_input){ + .text = "ab", .length = 2, .selection_end = 3}) == -EINVAL); + assert(yasl_surface_set_text_input(s, &(struct yasl_text_input){.caret_x = 1e300}) == -EOVERFLOW); + assert(yasl_surface_set_text_input(s, NULL) == 0 || ime == -ENOTSUP); + + /* Arguments are checked before the backend sees them. */ + assert(yasl_surface_begin_move_resize(s, YASL_EDGE_TOP | YASL_EDGE_BOTTOM) == -EINVAL); + assert(yasl_surface_begin_move_resize(s, 16) == -EINVAL); + assert(yasl_surface_request(s, (enum yasl_request)9) == -EINVAL); + assert(yasl_surface_request_size(s, 0, 10) == -EINVAL); + assert(yasl_surface_set_cursor(s, (enum yasl_cursor)99) == -EINVAL); + int locked = yasl_surface_set_cursor(s, YASL_CURSOR_LOCKED); + assert(locked == ((features & YASL_FEATURE_LOCKED_CURSOR) ? 0 : -ENOTSUP)); + assert(yasl_surface_set_cursor(s, YASL_CURSOR_ARROW) == 0); + assert(yasl_drag_start(s, &(struct yasl_drag_image){.pixel_width = 4, .pixel_height = 4}) == -EINVAL); + uint32_t icon[4] = {0}; + assert(yasl_drag_start(s, &(struct yasl_drag_image){ + .pixels = icon, .pixel_width = 2, .pixel_height = 2, .hotspot_x = 2}) == -EINVAL); + assert(!yasl_popup_create(s, &(struct yasl_popup_options){.width = 10, .height = 10, + .anchor = YASL_EDGE_LEFT | YASL_EDGE_RIGHT}) && + errno == EINVAL); + assert(yasl_clipboard_set((enum yasl_selection)5, "x") == -EINVAL); + assert(yasl_clipboard_set(YASL_CLIPBOARD, NULL) == -EINVAL); + assert(yasl_clipboard_set(YASL_CLIPBOARD, "\xff") == -EILSEQ); + assert(yasl_clipboard_set(YASL_PRIMARY, "x") == + ((features & YASL_FEATURE_PRIMARY_SELECTION) ? 0 : -ENOTSUP)); drain(); - struct yasl_private_event pen = {.type = YASL_PRIVATE_EVENT_PEN, - .surface = s, - .pen = {.device_id = 10, - .tool_id = 20, - .x = 12.5, - .y = 9.25, - .pressure = 0.3, - .axes_valid = YASL_PRIVATE_PEN_PRESSURE, - .action = YASL_PRIVATE_PEN_DOWN, - .in_contact = true}}; - assert(yasl_private_events_push(s->display, s, &pen)); - assert(yasl_wait_event(&e, 0) == 1 && e.type == YASL_EVENT_PEN && e.pen.device_id == 10 && - e.pen.pressure == 0.3 && e.pen.in_contact); - struct yasl_private_event text = { - .type = YASL_PRIVATE_EVENT_TEXT, .surface = s, .text = {.data = "owned", .len = 5}}; - assert(yasl_private_events_push(s->display, s, &text)); + + /* Event conversion: positions are logical, text is owned until the next wait. */ + uint32_t real_scale = s->scale_120; + s->scale_120 = 240; + push(s, (struct yasl_private_event){ + .type = YASL_PRIVATE_EVENT_PEN, + .pen = {.device_id = 10, .x = 25, .y = 18.5, .pressure = 0.3, + .axes_valid = YASL_PRIVATE_PEN_PRESSURE, .action = YASL_PRIVATE_PEN_DOWN, + .in_contact = true}}); + assert(yasl_wait_event(&e, 0) == 1 && e.type == YASL_EVENT_PEN && e.action == YASL_PEN_DOWN); + assert(e.x == 12.5 && e.y == 9.25 && e.pen.device_id == 10 && e.pen.pressure == 0.3 && + (e.pen.axes & YASL_PEN_PRESSURE) && e.pen.in_contact); + push(s, (struct yasl_private_event){ + .type = YASL_PRIVATE_EVENT_POINTER_DOWN, + .pointer = {.pos = {20, 10}, .button = YASL_PRIVATE_BUTTON_SECONDARY, + .buttons = 4, .mods = YASL_PRIVATE_MOD_CTRL}}); + assert(yasl_wait_event(&e, 0) == 1 && e.type == YASL_EVENT_POINTER && + e.action == YASL_POINTER_DOWN && e.x == 10 && e.y == 5 && e.mods == YASL_MOD_CTRL && + e.pointer.button == YASL_BUTTON_SECONDARY && e.pointer.buttons == 4); + s->scale_120 = real_scale; + push(s, (struct yasl_private_event){.type = YASL_PRIVATE_EVENT_TEXT, .text = {"owned", 5}}); assert(yasl_wait_event(&e, 0) == 1 && e.type == YASL_EVENT_TEXT); - assert(e.text.length == 5 && !strcmp(e.text.data, "owned")); - /* Unchanged focus folds into no event; a change reports the activated state. */ - unsigned active = yasl_surface_get_state(s) & YASL_STATE_ACTIVATED; - struct yasl_private_event focus = { - .type = YASL_PRIVATE_EVENT_FOCUS, .surface = s, .focus = {.focused = !active}}; - assert(yasl_private_events_push(s->display, s, &focus)); - assert(yasl_wait_event(&e, 0) == 1 && e.type == YASL_EVENT_WINDOW); - assert((e.window.state & YASL_STATE_ACTIVATED) == (active ? 0u : YASL_STATE_ACTIVATED) && - e.window.pixel_width == w); - assert(yasl_private_events_push(s->display, s, &focus)); + assert(e.length == 5 && !strcmp(e.text, "owned")); + push(s, (struct yasl_private_event){ + .type = YASL_PRIVATE_EVENT_PASTE, + .paste = {.data = "", .request_id = 1, .status = YASL_PRIVATE_TRANSFER_UNAVAILABLE}}); + assert(yasl_wait_event(&e, 0) == 1 && e.type == YASL_EVENT_CLIPBOARD && + e.action == YASL_TRANSFER_UNAVAILABLE && e.length == 0); + /* Losing focus releases held input; activation itself comes from the window state. */ + push(s, (struct yasl_private_event){.type = YASL_PRIVATE_EVENT_FOCUS, .focus = {.focused = false}}); + assert(yasl_wait_event(&e, 0) == 1 && e.type == YASL_EVENT_INPUT_RESET); + push(s, (struct yasl_private_event){.type = YASL_PRIVATE_EVENT_FOCUS, .focus = {.focused = true}}); assert(yasl_wait_event(&e, 0) == 0 && e.type == YASL_EVENT_NONE); - struct yasl_private_event hover = {.type = YASL_PRIVATE_EVENT_DROP_HOVER, - .surface = s, - .drop = {YASL_PRIVATE_DROP_LEAVE, {0, 0}}}; - assert(yasl_private_events_push(s->display, s, &hover)); - assert(yasl_wait_event(&e, 0) == 1 && e.type == YASL_EVENT_DROP && - e.drop.action == YASL_DROP_LEAVE); + push(s, (struct yasl_private_event){.type = YASL_PRIVATE_EVENT_DROP_HOVER, + .drop = {YASL_PRIVATE_DROP_LEAVE, {0, 0}}}); + assert(yasl_wait_event(&e, 0) == 1 && e.type == YASL_EVENT_DROP && e.action == YASL_DROP_LEAVE); + + /* A resize keeps the overlap of the pixels and zeroes the rest. */ assert(yasl_surface_request_size(s, 112, 96) == 0); uint64_t resize_deadline = yasl_time_ns() + 3000000000ull; - int logical_w = 0, logical_h = 0; do { assert(yasl_wait_event(&e, 20) >= 0); - yasl_surface_get_size(s, &logical_w, &logical_h); - } while ((logical_w != 112 || logical_h != 96) && yasl_time_ns() < resize_deadline); - assert(logical_w == 112 && logical_h == 96); - assert(yasl_cpu_acquire(s, &buffer) == 0); - assert(buffer.pixels[0] == 0xff102030u); - assert(buffer.pixels[(size_t)3 * buffer.width + 2] == 0xffaabbccu); - assert(buffer.pixels[(size_t)buffer.width * buffer.height - 1] == 0); - assert(yasl_cpu_present(s, &buffer) == 0); - yasl_surface_set_refresh_callback(s, refresh, NULL); - assert(yasl_cpu_acquire(s, &buffer) == 0); - assert(yasl_cpu_present(s, &buffer) == 0); + info = yasl_surface_get_info(s); + } while ((info.width != 112 || info.height != 96) && yasl_time_ns() < resize_deadline); + assert(info.width == 112 && info.height == 96); + pixels = yasl_cpu_pixels(s, &w, &h); + assert(pixels && w == info.pixel_width && h == info.pixel_height); + assert(pixels[0] == 0xff102030u && pixels[(size_t)3 * w + 2] == 0xffaabbccu); + assert(pixels[(size_t)w * h - 1] == 0); + assert(yasl_cpu_present(s) == 0); + + /* The refresh callback is reserved for modal loops; ordinary waits deliver REFRESH. */ + s->refresh = refresh; + for (int i = 0; i < 5; i++) { + assert(yasl_cpu_pixels(s, &w, &h) && yasl_cpu_present(s) == 0); + assert(yasl_wait_event(&e, 20) >= 0); + } + assert(refreshes == 0); #if YASL_HAS_COCOA + s->display->modal = true; yasl_test_frame_tick(s); -#endif uint64_t deadline = yasl_private_loop_now_ns() + 3000000000ull; while (!refreshes && yasl_private_loop_now_ns() < deadline) assert(yasl_wait_event(&e, 20) >= 0); assert(refreshes > 0); - yasl_surface_set_refresh_callback(s, NULL, NULL); + s->display->modal = false; +#endif + s->refresh = NULL; yasl_surface_destroy(s); - assert((yasl_init(&(struct yasl_options){.backend = backend}) < 0)); + assert(yasl_init(backend, NULL) == -EALREADY); s = yasl_surface_create(&(struct yasl_surface_options){.title = "shared backend remains", - .width = 64, - .height = 64, - .type = YASL_SURFACE_CPU, - .flags = 0}); + .width = 64, .height = 64}); assert(s); yasl_shutdown(); - assert((yasl_init(&(struct yasl_options){.backend = backend}) == 0)); - s = yasl_surface_create(&(struct yasl_surface_options){ - .title = "reinitialized", .width = 64, .height = 64, .type = YASL_SURFACE_CPU, .flags = 0}); + assert(yasl_init(backend, NULL) == 0); + s = yasl_surface_create( + &(struct yasl_surface_options){.title = "reinitialized", .width = 64, .height = 64}); assert(s); yasl_shutdown(); puts("public surface lifecycle, pixels, ownership, input, wake and refresh passed"); diff --git a/tests/common/test_vulkan.c b/tests/common/test_vulkan.c index b12256a..4633d55 100644 --- a/tests/common/test_vulkan.c +++ b/tests/common/test_vulkan.c @@ -41,30 +41,29 @@ static int run_test(enum yasl_backend backend) VkSemaphore acquired = VK_NULL_HANDLE, rendered = VK_NULL_HANDLE; VkCommandBuffer command = VK_NULL_HANDLE; - if ((yasl_init(&(struct yasl_options){.backend=backend}) < 0)) { + if (yasl_init(backend, NULL) < 0) { fprintf(stderr, "vulkan integration: cannot select requested backend %d (YASL error %d)\n", backend, errno); goto cleanup; } - if ((yasl_vulkan_init(vkGetInstanceProcAddr) < 0)) { + struct yasl_vulkan_requirements requirements; + if (yasl_vulkan_init(vkGetInstanceProcAddr, &requirements) < 0) { fprintf(stderr, "vulkan integration: loader initialization failed (YASL error %d)\n", errno); goto cleanup; } - surface = yasl_surface_create(&(struct yasl_surface_options){.title="yasl Vulkan WSI integration", .width=256, .height=192, .type=YASL_SURFACE_NATIVE, .flags=0}); + surface = yasl_surface_create(&(struct yasl_surface_options){.title="yasl Vulkan WSI integration", .width=256, .height=192, .type=YASL_SURFACE_NATIVE}); if (!surface) { fprintf(stderr, "vulkan integration: surface creation failed (YASL error %d)\n", errno); goto cleanup; } - if (!(yasl_surface_get_features(surface) & YASL_CAP_VULKAN)) { + if (!(yasl_get_features() & YASL_FEATURE_VULKAN)) { fprintf(stderr, "vulkan integration: requested backend does not advertise Vulkan WSI\n"); goto cleanup; } uint32_t extension_count = 0; - struct yasl_vulkan_requirements requirements; - if (yasl_vulkan_get_requirements(surface, &requirements) < 0) goto cleanup; extension_count = requirements.extension_count; const char *const *required = requirements.extensions; if (!required || !extension_count) { @@ -114,7 +113,7 @@ static int run_test(enum yasl_backend backend) VkSurfaceKHR duplicate = VK_NULL_HANDLE; if (yasl_vulkan_create_surface(surface, instance, NULL, &duplicate) != VK_ERROR_NATIVE_WINDOW_IN_USE_KHR || duplicate != VK_NULL_HANDLE || yasl_surface_destroy(surface) != -EBUSY || - yasl_shutdown() != -EBUSY || yasl_vulkan_init(vkGetInstanceProcAddr) != -EBUSY) { + yasl_shutdown() != -EBUSY || yasl_vulkan_init(vkGetInstanceProcAddr, &requirements) != -EBUSY) { fprintf(stderr, "vulkan integration: live WSI ownership was not enforced\n"); goto cleanup; } @@ -191,8 +190,8 @@ static int run_test(enum yasl_backend backend) VkExtent2D extent = capabilities.currentExtent; if (extent.width == UINT32_MAX) { - int width = 0, height = 0; - yasl_surface_get_framebuffer_size(surface, &width, &height); + int width = yasl_surface_get_info(surface).pixel_width; + int height = yasl_surface_get_info(surface).pixel_height; if (width <= 0 || height <= 0) { fprintf(stderr, "vulkan integration: surface has no drawable framebuffer extent\n"); goto cleanup; diff --git a/tests/meson.build b/tests/meson.build index e34f072..7e1940e 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -15,17 +15,10 @@ if add_languages('cpp', native: false, required: false) '-DYASL_HAS_COCOA=' + (has_cocoa ? '1' : '0')], override_options: ['cpp_std=c++11']) test('cpp-api', cpp_api) endif -headers = files('../include/yasl/yasl.h', '../include/yasl/cpu.h', '../include/yasl/gl.h', - '../include/yasl/metal.h', '../include/yasl/desktop.h') +headers = files('../include/yasl/yasl.h') if has_vulkan headers += files('../include/yasl/vulkan.h') endif -foreach backend : ['wayland', 'x11', 'cocoa'] - enabled = {'wayland': has_wayland, 'x11': has_x11, 'cocoa': has_cocoa}[backend] - if enabled - headers += files('../include/yasl/native/' + backend + '.h') - endif -endforeach nm = find_program('nm') export_args = ['--platform=' + system] if get_option('b_sanitize').contains('address') diff --git a/tests/test_api.cpp b/tests/test_api.cpp index acfbbb8..beec36d 100644 --- a/tests/test_api.cpp +++ b/tests/test_api.cpp @@ -1,35 +1,24 @@ #include <yasl/yasl.h> -#include <yasl/cpu.h> -#include <yasl/gl.h> -#include <yasl/metal.h> -#include <yasl/desktop.h> #if YASL_HAS_VULKAN #include <yasl/vulkan.h> #endif -#if YASL_HAS_WAYLAND -#include <yasl/native/wayland.h> -#endif -#if YASL_HAS_X11 -#include <yasl/native/x11.h> -#endif -#if YASL_HAS_COCOA -#include <yasl/native/cocoa.h> -#endif #include <cassert> int main() { yasl_event e{}; - e.pen.x = 1.5; + e.x = 1.5; e.pen.pressure = 0.25; - assert(e.pen.pressure == 0.25); + assert(e.pen.pressure == 0.25 && e.text == nullptr); yasl_surface_options options{}; options.width = -1; options.height = 10; assert(!yasl_surface_create(&options) && errno == EINVAL); - yasl_gl_options gl = YASL_GL_OPTIONS_INIT; - assert(gl.major == 3 && gl.minor == 2 && gl.share == nullptr); - yasl_cpu_buffer buffer{}; - assert(yasl_cpu_acquire(nullptr, &buffer) == -ENODEV); + yasl_gl_options gl{}; + assert(gl.major == 0 && gl.share == nullptr); + int w = 0, h = 0; + assert(!yasl_cpu_pixels(nullptr, &w, &h) && errno == ENODEV); + yasl_native native{}; + assert(yasl_surface_get_native(nullptr, &native) == -ENODEV); yasl_shutdown(); return 0; } diff --git a/tests/test_lifecycle.c b/tests/test_lifecycle.c index 08213b0..41dafe6 100644 --- a/tests/test_lifecycle.c +++ b/tests/test_lifecycle.c @@ -1,9 +1,6 @@ #include <yasl/yasl.h> -#include <yasl/cpu.h> -#include <yasl/gl.h> -#include <yasl/metal.h> -#include <yasl/desktop.h> #include <assert.h> +#include <string.h> int main(void) { assert(yasl_shutdown() == 0); @@ -11,27 +8,34 @@ int main(void) yasl_event event = {.type = YASL_EVENT_QUIT}; assert(yasl_wait_event(&event, 0) == -ENODEV && event.type == YASL_EVENT_NONE); assert(yasl_wait_event(NULL, 0) == -EINVAL); - assert(yasl_init(&(struct yasl_options){.backend = (enum yasl_backend)999}) == -EINVAL); + assert(yasl_init((enum yasl_backend)999, NULL) == -EINVAL); + assert(yasl_get_backend() == YASL_BACKEND_AUTO && yasl_get_features() == 0); assert(!yasl_surface_create(NULL) && errno == EINVAL); struct yasl_surface_options options = {.width = 0, .height = 64}; assert(!yasl_surface_create(&options) && errno == EINVAL); options.width = 64; - options.flags = 16; - assert(!yasl_surface_create(&options) && errno == EINVAL); - options.flags = 0; options.type = (enum yasl_surface_type)99; assert(!yasl_surface_create(&options) && errno == EINVAL); - struct yasl_cpu_buffer buffer = {.width = 9}; - assert(yasl_cpu_acquire(NULL, &buffer) == -ENODEV && !buffer.pixels && !buffer.width); - assert(yasl_cpu_acquire(NULL, NULL) == -EINVAL); - CAMetalLayer *layer = NULL; - assert(yasl_metal_get_layer(NULL, &layer) == -ENODEV && !layer); + options.type = YASL_SURFACE_GL; + options.gl.major = 9; + assert(!yasl_surface_create(&options) && errno == EINVAL); + int w = 9, h = 9; + assert(!yasl_cpu_pixels(NULL, &w, &h) && errno == ENODEV && w == 0 && h == 0); + assert(yasl_cpu_present(NULL) == -ENODEV); + assert(!yasl_metal_get_layer(NULL) && errno == ENODEV); + struct yasl_native native = {.x11_window = 7}; + assert(yasl_surface_get_native(NULL, &native) == -ENODEV && native.x11_window == 0); assert(yasl_surface_destroy(NULL) == 0); assert(yasl_time_ns() > 0); - int w = 9, h = 9; - yasl_surface_get_size(NULL, &w, &h); - assert(w == 0 && h == 0); - assert(yasl_get_executable_path(NULL, 0) > 0); + struct yasl_surface_info info = yasl_surface_get_info(NULL); + assert(info.width == 0 && info.pixel_height == 0 && info.scale == 1.0); + assert(yasl_gl_make_current(NULL) == 0); + assert(yasl_get_double_click_ms() == 400); + assert(yasl_get_system_string(YASL_EXECUTABLE_PATH, NULL, 0) > 0); + char locale[64]; + size_t n = yasl_get_system_string(YASL_LOCALE, locale, sizeof(locale)); + assert(n > 0 && n < sizeof(locale) && !strpbrk(locale, ".@")); + assert(yasl_get_system_string((enum yasl_system_string)9, locale, sizeof(locale)) == 0 && errno == EINVAL); assert(yasl_shutdown() == 0); return 0; } diff --git a/tests/wayland/test_reconnect.c b/tests/wayland/test_reconnect.c index 737afb2..891d98b 100644 --- a/tests/wayland/test_reconnect.c +++ b/tests/wayland/test_reconnect.c @@ -2,9 +2,6 @@ * after "ready" and starts a new one after "lost". Windows must survive, keep * their pixels, and accept new GL and Vulkan objects after DISPLAY_RESTORED. */ #include <yasl/yasl.h> -#include <yasl/cpu.h> -#include <yasl/gl.h> -#include <yasl/native/wayland.h> #if TEST_VULKAN #include <yasl/vulkan.h> #endif @@ -58,29 +55,25 @@ static VkSurfaceKHR vulkan_surface(void) int main(void) { - CHECK((yasl_init(&(struct yasl_options){.backend=YASL_BACKEND_WAYLAND}) == 0), "selecting Wayland"); - cpu = yasl_surface_create(&(struct yasl_surface_options){.title="reconnect CPU", .width=160, .height=120, .type=YASL_SURFACE_CPU, .flags=0}); + CHECK(yasl_init(YASL_BACKEND_WAYLAND, NULL) == 0, "selecting Wayland"); + cpu = yasl_surface_create(&(struct yasl_surface_options){.title="reconnect CPU", .width=160, .height=120}); CHECK(cpu, "creating CPU window"); - gl = yasl_gl_surface_create(&(struct yasl_surface_options){.title="reconnect GL", .width=160, .height=120, .type=YASL_SURFACE_NATIVE, .flags=0}, NULL); + gl = yasl_surface_create(&(struct yasl_surface_options){.title="reconnect GL", .width=160, .height=120, .type=YASL_SURFACE_GL}); CHECK(gl, "creating GL window"); expect(YASL_EVENT_REFRESH, cpu, 5000); int w, h; - struct yasl_cpu_buffer buffer; - CHECK(yasl_cpu_acquire(cpu, &buffer) == 0, "acquire CPU buffer"); - w=buffer.width; h=buffer.height; - uint32_t *pixels = buffer.pixels; + uint32_t *pixels = yasl_cpu_pixels(cpu, &w, &h); CHECK(pixels, "getting pixels"); for (size_t i = 0; i < (size_t)w * h; i++) pixels[i] = 0xff336699u; - CHECK((yasl_cpu_present(cpu, &buffer) == 0), "presenting"); + CHECK(yasl_cpu_present(cpu) == 0, "presenting"); draw_gl(0.8f); #if TEST_VULKAN - CHECK((yasl_vulkan_init(vkGetInstanceProcAddr) == 0), "loading Vulkan"); - vk = yasl_surface_create(&(struct yasl_surface_options){.title="reconnect Vulkan", .width=160, .height=120, .type=YASL_SURFACE_NATIVE, .flags=0}); - CHECK(vk, "creating Vulkan window"); struct yasl_vulkan_requirements requirements; - CHECK(yasl_vulkan_get_requirements(vk, &requirements) == 0, "Vulkan requirements"); + CHECK(yasl_vulkan_init(vkGetInstanceProcAddr, &requirements) == 0, "loading Vulkan"); + vk = yasl_surface_create(&(struct yasl_surface_options){.title="reconnect Vulkan", .width=160, .height=120, .type=YASL_SURFACE_NATIVE}); + CHECK(vk, "creating Vulkan window"); VkInstanceCreateInfo info = {.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .flags = requirements.flags, .enabledExtensionCount = requirements.extension_count, .ppEnabledExtensionNames = requirements.extensions}; @@ -92,29 +85,29 @@ int main(void) fflush(stdout); expect(YASL_EVENT_DISPLAY_LOST, NULL, 10000); - struct yasl_wayland_handles native; - CHECK(yasl_wayland_get_native(cpu, &native) == -ENOTCONN && !native.display && !native.surface, + struct yasl_native native; + CHECK(yasl_surface_get_native(cpu, &native) == -ENOTCONN && !native.wl_display && !native.wl_surface, "rejecting native handles while offline"); - CHECK(yasl_cpu_acquire(cpu, &buffer) == -ENOTCONN, "rejecting CPU acquisition while offline"); + CHECK(yasl_cpu_present(cpu) == -ENOTCONN, "rejecting CPU presentation while offline"); CHECK(yasl_gl_make_current(gl) == -ENOTCONN, "rejecting GL binding while offline"); + CHECK(yasl_gl_make_current(NULL) == 0, "detaching GL while offline"); #if TEST_VULKAN CHECK(yasl_vulkan_destroy_surface(vk) == 0, "destroying Vulkan surface"); #endif - CHECK(!yasl_surface_create(&(struct yasl_surface_options){.title="offline", .width=64, .height=64, .type=YASL_SURFACE_CPU, .flags=0}), "refusing windows while offline"); + CHECK(!yasl_surface_create(&(struct yasl_surface_options){.title="offline", .width=64, .height=64}), "refusing windows while offline"); CHECK(errno == ENOTCONN, "reporting the disconnect"); puts("lost"); fflush(stdout); expect(YASL_EVENT_DISPLAY_RESTORED, NULL, 15000); - CHECK(yasl_wayland_get_native(cpu, &native) == 0 && native.display && native.surface, + CHECK(yasl_surface_get_native(cpu, &native) == 0 && native.wl_display && native.wl_surface, "querying restored native handles"); expect(YASL_EVENT_REFRESH, cpu, 5000); int rw, rh; - CHECK(yasl_cpu_acquire(cpu, &buffer) == 0, "reacquire CPU buffer"); - rw=buffer.width; rh=buffer.height; pixels=buffer.pixels; + pixels = yasl_cpu_pixels(cpu, &rw, &rh); CHECK(pixels && rw == w && rh == h, "keeping the window size"); CHECK(pixels[0] == 0xff336699u && pixels[(size_t)w * h - 1] == 0xff336699u, "keeping the pixels"); - CHECK((yasl_cpu_present(cpu, &buffer) == 0), "presenting after reconnect"); + CHECK(yasl_cpu_present(cpu) == 0, "presenting after reconnect"); draw_gl(0.1f); #if TEST_VULKAN CHECK(vulkan_surface() != VK_NULL_HANDLE, "restored Vulkan handle"); @@ -123,7 +116,7 @@ int main(void) #endif /* A second window proves the new connection accepts creation. */ - CHECK(yasl_surface_create(&(struct yasl_surface_options){.title="after reconnect", .width=64, .height=64, .type=YASL_SURFACE_CPU, .flags=0}), "creating a window after reconnect"); + CHECK(yasl_surface_create(&(struct yasl_surface_options){.title="after reconnect", .width=64, .height=64}), "creating a window after reconnect"); yasl_gl_make_current(NULL); yasl_shutdown(); puts("restored"); diff --git a/tests/x11/test_tablet_native.c b/tests/x11/test_tablet_native.c index 66cdd93..bbe39f2 100644 --- a/tests/x11/test_tablet_native.c +++ b/tests/x11/test_tablet_native.c @@ -2,7 +2,6 @@ #define main tablet_example_main #include "../../examples/tablet.c" #undef main -#include <yasl/native/x11.h> #include <stdlib.h> #include <stdio.h> #include <time.h> @@ -59,7 +58,8 @@ static int connect_tool(const char *path) } struct canvas_state { - struct yasl_pen_payload pen; + struct yasl_pen_event pen; + double x, y; uint32_t *pixels; int width, height, painted_width, painted_height; bool down; @@ -69,24 +69,24 @@ static void render_event(yasl_surface *surface, struct canvas_state *state, cons { if (event->type == YASL_EVENT_PEN) { state->pen = event->pen; + state->x = event->x; + state->y = event->y; state->down = event->pen.in_contact; } - struct yasl_cpu_buffer buffer; free(state->pixels); - state->pixels = canvas(surface, &state->width, &state->height, - &state->painted_width, &state->painted_height, false, &buffer); - assert(state->pixels); + uint32_t *pixels = canvas(surface, &state->width, &state->height, + &state->painted_width, &state->painted_height, false); + assert(pixels); if (event->type == YASL_EVENT_PEN && state->down && - (event->pen.action == YASL_PEN_DOWN || event->pen.action == YASL_PEN_MOVE)) { - double scale = yasl_surface_get_scale(surface); - stamp(state->pixels, state->width, state->height, - event->pen.x * scale, event->pen.y * scale, + (event->action == YASL_PEN_DOWN || event->action == YASL_PEN_MOVE)) { + double scale = yasl_surface_get_info(surface).scale; + stamp(pixels, state->width, state->height, event->x * scale, event->y * scale, (1.5 + 12 * event->pen.pressure) * scale, event->pen.tool == YASL_PEN_ERASER); } uint32_t *snapshot = malloc((size_t)state->width * state->height * sizeof(*snapshot)); assert(snapshot); - memcpy(snapshot, buffer.pixels, (size_t)state->width * state->height * sizeof(*snapshot)); - assert(yasl_cpu_present(surface, &buffer) == 0); + memcpy(snapshot, pixels, (size_t)state->width * state->height * sizeof(*snapshot)); + assert(yasl_cpu_present(surface) == 0); state->pixels = snapshot; } @@ -107,12 +107,12 @@ static void pump(int fd, yasl_surface *surface, struct canvas_state *state) receive_all(fd, &response, sizeof(response)); assert(response.type == XF86IT_RESPONSE_SYNC_FINISHED && response.length == sizeof(response)); /* The driver acknowledgment guarantees XI2 processing has finished. */ - struct yasl_x11_handles native; - assert(yasl_x11_get_native(surface, &native) == 0); - XSync(native.display, False); + struct yasl_native native; + assert(yasl_surface_get_native(surface, &native) == 0); + XSync(native.x11_display, False); drain(surface, state); /* Public polling submits the CPU frame before the native readback. */ - XSync(native.display, False); + XSync(native.x11_display, False); } static void set_eraser_property(Display *display) @@ -140,13 +140,13 @@ int main(int argc, char **argv) { assert(argc == 3); /* pen socket, eraser socket */ struct canvas_state app = {0}; - assert((yasl_init(&(struct yasl_options){.backend=YASL_BACKEND_X11}) == 0)); - yasl_surface *surface = yasl_surface_create(&(struct yasl_surface_options){.title="YASL native pressure test", .width=500, .height=400, .type=YASL_SURFACE_CPU, .flags=0}); - assert(surface && (yasl_surface_get_features(surface) & YASL_CAP_TABLET)); - struct yasl_x11_handles native; - assert(yasl_x11_get_native(surface, &native) == 0); - Display *x = native.display; - Window window = (Window)native.window; + assert(yasl_init(YASL_BACKEND_X11, NULL) == 0); + yasl_surface *surface = yasl_surface_create(&(struct yasl_surface_options){.title="YASL native pressure test", .width=500, .height=400}); + assert(surface && (yasl_get_features() & YASL_FEATURE_TABLET)); + struct yasl_native native; + assert(yasl_surface_get_native(surface, &native) == 0); + Display *x = native.x11_display; + Window window = (Window)native.x11_window; XMoveWindow(x, window, 0, 0); XSetInputFocus(x, window, RevertToParent, CurrentTime); XSync(x, False); @@ -163,7 +163,7 @@ int main(int argc, char **argv) send_all(pen_fd, &motion, sizeof(motion)); pump(pen_fd, surface, &app); assert(!app.down && app.pen.tool == YASL_PEN_PEN); - assert(app.pen.x == 150 && app.pen.y == 200); + assert(app.x == 150 && app.y == 200); assert(app.pixels[(size_t)200 * app.width + 150] == PAPER); xf86ITEventButton button = {.header = {sizeof(button), XF86IT_EVENT_BUTTON}, .is_absolute = 1, .button = 1, .is_press = 1, .valuators = motion.valuators}; |
