summaryrefslogtreecommitdiff
path: root/tests/x11/test_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/x11/test_input.c')
-rw-r--r--tests/x11/test_input.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/tests/x11/test_input.c b/tests/x11/test_input.c
index a89812b..f82dc82 100644
--- a/tests/x11/test_input.c
+++ b/tests/x11/test_input.c
@@ -34,12 +34,14 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface *
selection_request(d, &request);
assert(XGetWindowProperty(d->native, requestor, property, 0, 100, True,
AnyPropertyType, &actual, &format, &count, &left, &data) == Success);
- assert(actual == XA_ATOM && format == 32 && count == 2);
- assert(((Atom *)data)[0] == d->targets && ((Atom *)data)[1] == d->utf8);
+ /* Text outside Latin-1 offers no STRING target. */
+ assert(actual == XA_ATOM && format == 32 && count == 4);
+ assert(((Atom *)data)[0] == d->targets && ((Atom *)data)[1] == d->utf8 &&
+ ((Atom *)data)[2] == d->timestamp && ((Atom *)data)[3] == d->multiple);
XFree(data);
XDestroyWindow(d->native, requestor);
- /* Simulate legacy STRING, empty UTF-8, malformed UTF-8, and rejected INCR. */
+ /* Simulate legacy STRING, empty UTF-8 and malformed UTF-8. */
const struct {
Atom type;
const void *bytes;
@@ -51,7 +53,6 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface *
{XA_STRING, "caf\xe9 \xa3", 6, 8, "café £", YASL_PRIVATE_TRANSFER_OK},
{d->utf8, "", 0, 8, "", YASL_PRIVATE_TRANSFER_OK},
{d->utf8, "\xff", 1, 8, NULL, YASL_PRIVATE_TRANSFER_FAILED},
- {d->incr, NULL, 1, 32, NULL, YASL_PRIVATE_TRANSFER_FAILED},
};
for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
struct paste_request *pending = calloc(1, sizeof(*pending));
@@ -66,11 +67,8 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface *
assert(pending->timeout);
pending->next = d->pastes;
d->pastes = pending;
- unsigned long incr_bytes = 4096;
- const void *bytes = cases[i].bytes;
- if (cases[i].type == d->incr) bytes = &incr_bytes;
XChangeProperty(d->native, pending->window, property, cases[i].type,
- cases[i].format, PropModeReplace, bytes, (int)cases[i].len);
+ cases[i].format, PropModeReplace, cases[i].bytes, (int)cases[i].len);
XSelectionEvent reply = {.requestor = pending->window, .property = property};
selection_notify(d, &reply);
struct yasl_private_event event;
@@ -81,15 +79,37 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface *
assert(event.text.len == strlen(cases[i].expected));
assert(strcmp(event.text.data, cases[i].expected) == 0);
}
- if (cases[i].type == d->incr) {
- assert(d->pastes == pending && !pending->target);
- assert(yasl_private_loop_del_timer(d->loop, pending->timeout));
- pending->timeout = 0;
- paste_timeout(pending, 0, PASTE_TIMEOUT_NS);
- }
assert(!yasl_private_display_poll_event(&d->base, &event));
}
+ /* INCR: the owner announces a size, then writes chunks until an empty one. */
+ struct paste_request *incr = calloc(1, sizeof(*incr));
+ assert(incr);
+ incr->display = d;
+ incr->window = XCreateSimpleWindow(d->native, DefaultRootWindow(d->native), 0, 0, 1, 1, 0, 0, 0);
+ incr->target = s;
+ incr->id = 9;
+ incr->timeout = yasl_private_loop_add_timer(d->loop, PASTE_TIMEOUT_NS, paste_timeout, incr);
+ assert(incr->timeout);
+ incr->next = d->pastes;
+ d->pastes = incr;
+ unsigned long incr_bytes = 5;
+ XChangeProperty(d->native, incr->window, d->paste_property, d->incr, 32, PropModeReplace,
+ (const unsigned char *)&incr_bytes, 1);
+ selection_notify(d, &(XSelectionEvent){.requestor = incr->window, .property = d->paste_property});
+ struct yasl_private_event event;
+ assert(incr->incr && !yasl_private_display_poll_event(&d->base, &event));
+ const char *chunks[] = {"inc", "r\xc3\xa9", ""};
+ for (size_t i = 0; i < sizeof(chunks) / sizeof(chunks[0]); i++) {
+ XChangeProperty(d->native, incr->window, d->paste_property, d->utf8, 8, PropModeReplace,
+ (const unsigned char *)chunks[i], (int)strlen(chunks[i]));
+ assert(paste_incr_property(d, &(XPropertyEvent){.window = incr->window,
+ .atom = d->paste_property, .state = PropertyNewValue}));
+ }
+ assert(yasl_private_display_poll_event(&d->base, &event));
+ assert(event.type == YASL_PRIVATE_EVENT_PASTE && event.paste.request_id == 9 &&
+ event.paste.status == YASL_PRIVATE_TRANSFER_OK && !strcmp(event.paste.data, "incr\xc3\xa9"));
+
struct paste_request *rejected = calloc(1, sizeof(*rejected));
assert(rejected);
rejected->window = XCreateSimpleWindow(d->native, DefaultRootWindow(d->native),
@@ -101,7 +121,6 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface *
d->pastes = rejected;
XSelectionEvent no_property = {.requestor = rejected->window, .property = None};
selection_notify(d, &no_property);
- struct yasl_private_event event;
assert(yasl_private_display_poll_event(&d->base, &event));
assert(event.type == YASL_PRIVATE_EVENT_PASTE && event.paste.request_id == 99);
assert(event.paste.status == YASL_PRIVATE_TRANSFER_FAILED);