summaryrefslogtreecommitdiff
path: root/tests/common/test_backends.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/common/test_backends.c')
-rw-r--r--tests/common/test_backends.c92
1 files changed, 87 insertions, 5 deletions
diff --git a/tests/common/test_backends.c b/tests/common/test_backends.c
index 48a6b68..3372290 100644
--- a/tests/common/test_backends.c
+++ b/tests/common/test_backends.c
@@ -67,7 +67,24 @@ static void draw(struct yasl_surface *s, struct yasl_frame *frame, void *ud)
assert(size.x == frame->target.size.x && size.y == frame->target.size.y);
assert(frame->target.pixels);
for (int i = 0; i < size.x * size.y; i++) frame->target.pixels[i] = 0xff4080c0;
- struct yasl_damage_list damage = {.n = -1};
+ struct yasl_damage_list damage = {.n = YASL_DAMAGE_MAX + 1};
+ assert(!yasl_surface_present(s, &frame->target, &damage));
+ damage.n = -2;
+ assert(!yasl_surface_present(s, &frame->target, &damage));
+ damage.n = 1;
+ damage.rects[0].width = -1;
+ assert(!yasl_surface_present(s, &frame->target, &damage));
+ damage.n = -1;
+ struct yasl_framebuffer invalid = frame->target;
+ invalid.buffer++;
+ assert(!yasl_surface_present(s, &invalid, &damage));
+ invalid = frame->target;
+ invalid.generation--;
+ assert(!yasl_surface_present(s, &invalid, &damage));
+ invalid = frame->target;
+ invalid.native_drawable = (void *)(uintptr_t)1;
+ assert(!yasl_surface_present(s, &invalid, &damage));
+ assert(!yasl_surface_present(s, &frame->target, NULL));
assert(yasl_surface_present(s, &frame->target, &damage));
assert(!yasl_surface_present(s, &frame->target, &damage));
w->draws++;
@@ -98,12 +115,22 @@ static const struct yasl_surface_cbs callbacks = {
.draw = draw, .configure = configure, .close = close_window,
};
+static void attach(struct window *w)
+{
+ struct yasl_surface_cbs temporary = callbacks;
+ yasl_surface_set_callbacks(w->surface, &temporary, w);
+ temporary.draw = NULL;
+ temporary.configure = NULL;
+ temporary.close = NULL;
+}
+
static struct window create(struct yasl_display *d)
{
struct yasl_surface_spec spec = {.title = "Backend test", .size = {160, 100}};
struct yasl_surface *s = yasl_surface_create_toplevel(d, &spec);
assert(s);
assert(yasl_surface_display(s) == d);
+ assert(yasl_surface_timing(s).source == YASL_TIMING_UNKNOWN);
return (struct window){.surface = s, .display = d};
}
@@ -153,6 +180,61 @@ static void x11_behavior(struct yasl_loop *loop, struct yasl_display *d, struct
}
}
assert(saw_key && saw_paste);
+ assert(yasl_surface_timing(w->surface).source == YASL_TIMING_SUBMISSION);
+ assert(!(yasl_display_caps(d) & YASL_CAP_FRAME_PACING));
+
+ /* Reuse caller storage, replace the selection, and exceed the old queue
+ * cap before polling: each paste must retain its own original contents. */
+ for (int i = 0; i < 300; i++) {
+ char text[32];
+ snprintf(text, sizeof(text), "owned-%d", i);
+ yasl_display_copy(d, YASL_CLIPBOARD, text);
+ yasl_display_paste(d, YASL_CLIPBOARD, w->surface);
+ memset(text, 'x', sizeof(text));
+ }
+ for (int i = 0; i < 300; i++) {
+ char text[32];
+ snprintf(text, sizeof(text), "owned-%d", i);
+ assert(yasl_surface_input_poll(w->surface, &event));
+ assert(event.kind == YASL_INPUT_PASTE && strcmp(event.paste.text, text) == 0);
+ }
+ const char *last = event.paste.text;
+ assert(!yasl_surface_input_poll(w->surface, &event));
+ yasl_display_copy(d, YASL_CLIPBOARD, "changed");
+ pump(loop, d, NULL);
+ assert(strcmp(last, "owned-299") == 0);
+ yasl_display_copy(d, YASL_CLIPBOARD, "");
+ yasl_display_paste(d, YASL_CLIPBOARD, w->surface);
+ assert(yasl_surface_input_poll(w->surface, &event));
+ assert(event.kind == YASL_INPUT_PASTE && !event.paste.len && !event.paste.text[0]);
+
+ /* Concurrent external conversions must not share a mutable target slot. */
+ struct yasl_display_spec ds = {.backend = YASL_BACKEND_X11};
+ struct yasl_display *owner = yasl_display_open(loop, &ds);
+ assert(owner);
+ yasl_display_copy(owner, YASL_CLIPBOARD, "external");
+ struct window other = create(d), cancelled = create(d);
+ yasl_display_paste(d, YASL_CLIPBOARD, w->surface);
+ yasl_display_paste(d, YASL_CLIPBOARD, other.surface);
+ yasl_display_paste(d, YASL_CLIPBOARD, cancelled.surface);
+ yasl_surface_destroy(cancelled.surface);
+ pump(loop, d, owner);
+ int first_pastes = 0, second_pastes = 0;
+ while (yasl_surface_input_poll(w->surface, &event)) {
+ if (event.kind == YASL_INPUT_PASTE) {
+ assert(strcmp(event.paste.text, "external") == 0);
+ first_pastes++;
+ }
+ }
+ while (yasl_surface_input_poll(other.surface, &event)) {
+ if (event.kind == YASL_INPUT_PASTE) {
+ assert(strcmp(event.paste.text, "external") == 0);
+ second_pastes++;
+ }
+ }
+ assert(first_pastes == 1 && second_pastes == 1);
+ yasl_surface_destroy(other.surface);
+ yasl_display_close(owner);
key.xclient = (XClientMessageEvent){.type = ClientMessage, .display = native,
.window = window, .message_type = XInternAtom(native, "WM_PROTOCOLS", False),
.format = 32, .data.l = {(long)XInternAtom(native, "WM_DELETE_WINDOW", False)}};
@@ -177,8 +259,8 @@ int main(int argc, char **argv)
struct yasl_display *b = yasl_display_open(loop, &spec);
assert(a && b);
struct window wa = create(a), wb = create(b);
- yasl_surface_set_callbacks(wa.surface, &callbacks, &wa);
- yasl_surface_set_callbacks(wb.surface, &callbacks, &wb);
+ attach(&wa);
+ attach(&wb);
pump(loop, a, b);
assert(wa.draws && wb.draws);
yasl_surface_destroy(wa.surface);
@@ -195,7 +277,7 @@ int main(int argc, char **argv)
struct window w = create(d);
pump(loop, d, NULL);
assert(w.draws == 0);
- yasl_surface_set_callbacks(w.surface, &callbacks, &w);
+ attach(&w);
yasl_surface_schedule_redraw(w.surface);
pump(loop, d, NULL);
assert(w.draws > 0);
@@ -204,7 +286,7 @@ int main(int argc, char **argv)
if (w.surface) yasl_surface_destroy(w.surface);
w = create(d);
w.destroy_on_draw = true;
- yasl_surface_set_callbacks(w.surface, &callbacks, &w);
+ attach(&w);
pump(loop, d, NULL);
assert(w.draws && !w.surface);
yasl_display_close(d);