summaryrefslogtreecommitdiff
path: root/tests/x11
diff options
context:
space:
mode:
Diffstat (limited to 'tests/x11')
-rw-r--r--tests/x11/test_input.c24
-rw-r--r--tests/x11/test_state.c25
-rw-r--r--tests/x11/test_tablet.c79
-rw-r--r--tests/x11/test_tablet_native.c126
4 files changed, 146 insertions, 108 deletions
diff --git a/tests/x11/test_input.c b/tests/x11/test_input.c
index ccad859..a89812b 100644
--- a/tests/x11/test_input.c
+++ b/tests/x11/test_input.c
@@ -6,12 +6,14 @@
static void check_selection_encoding(struct x11_display *d, struct x11_surface *s)
{
+ struct yasl_private_event queued;
+ while (yasl_private_display_poll_event(&d->base, &queued)) {}
Window requestor = XCreateSimpleWindow(d->native, DefaultRootWindow(d->native),
0, 0, 1, 1, 0, 0, 0);
Atom property = XInternAtom(d->native, "YASL_PRIVATE_TEST_STRING", False);
XSelectionRequestEvent request = {.display = d->native, .requestor = requestor,
.selection = d->clipboard, .target = XA_STRING, .property = property};
- yasl_private_display_copy(&d->base, YASL_PRIVATE_CLIPBOARD, "café £");
+ yasl_private_clipboard_set(&d->base, YASL_PRIVATE_CLIPBOARD, "café £");
selection_request(d, &request);
Atom actual;
int format;
@@ -22,7 +24,7 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface *
assert(actual == XA_STRING && format == 8 && count == 6);
assert(memcmp(data, "caf\xe9 \xa3", count) == 0);
XFree(data);
- yasl_private_display_copy(&d->base, YASL_PRIVATE_CLIPBOARD, "字");
+ yasl_private_clipboard_set(&d->base, YASL_PRIVATE_CLIPBOARD, "字");
selection_request(d, &request);
assert(XGetWindowProperty(d->native, requestor, property, 0, 100, True,
AnyPropertyType, &actual, &format, &count, &left, &data) == Success);
@@ -72,7 +74,7 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface *
XSelectionEvent reply = {.requestor = pending->window, .property = property};
selection_notify(d, &reply);
struct yasl_private_event event;
- assert(yasl_private_surface_poll_event(&s->base, &event));
+ assert(yasl_private_display_poll_event(&d->base, &event));
assert(event.type == YASL_PRIVATE_EVENT_PASTE && event.paste.request_id == i + 1);
assert(event.paste.status == cases[i].status);
if (cases[i].status == YASL_PRIVATE_TRANSFER_OK) {
@@ -85,7 +87,7 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface *
pending->timeout = 0;
paste_timeout(pending, 0, PASTE_TIMEOUT_NS);
}
- assert(!yasl_private_surface_poll_event(&s->base, &event));
+ assert(!yasl_private_display_poll_event(&d->base, &event));
}
struct paste_request *rejected = calloc(1, sizeof(*rejected));
@@ -100,7 +102,7 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface *
XSelectionEvent no_property = {.requestor = rejected->window, .property = None};
selection_notify(d, &no_property);
struct yasl_private_event event;
- assert(yasl_private_surface_poll_event(&s->base, &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);
}
@@ -336,21 +338,21 @@ int main(void)
/* Native creation and keymap updates may already have queued focus or
* reset input on the shared display stream. Isolate this synthetic key. */
struct yasl_private_event event;
- while (yasl_private_surface_poll_event(surface, &event)) {}
+ while (yasl_private_display_poll_event(base, &event)) {}
XKeyEvent native = {.type = KeyPress, .display = d->native,
.window = s->window, .keycode = code};
key_event(s, &native, false);
- assert(yasl_private_surface_poll_event(surface, &event));
+ assert(yasl_private_display_poll_event(base, &event));
assert(event.type == YASL_PRIVATE_EVENT_KEY && event.key.key == YASL_KEY_A);
assert(event.key.codepoint == cases[i].label);
- assert(yasl_private_surface_poll_event(surface, &event));
+ assert(yasl_private_display_poll_event(base, &event));
assert(event.type == YASL_PRIVATE_EVENT_TEXT && event.text.len == strlen(cases[i].text));
assert(strcmp(event.text.data, cases[i].text) == 0);
- assert(!yasl_private_surface_poll_event(surface, &event));
+ assert(!yasl_private_display_poll_event(base, &event));
native.type = KeyRelease;
key_event(s, &native, false);
- assert(yasl_private_surface_poll_event(surface, &event) && event.type == YASL_PRIVATE_EVENT_KEY);
- assert(!yasl_private_surface_poll_event(surface, &event));
+ assert(yasl_private_display_poll_event(base, &event) && event.type == YASL_PRIVATE_EVENT_KEY);
+ assert(!yasl_private_display_poll_event(base, &event));
}
XChangeKeyboardMapping(d->native, code, width, saved, 1);
XSync(d->native, False);
diff --git a/tests/x11/test_state.c b/tests/x11/test_state.c
index 4696e60..0c36638 100644
--- a/tests/x11/test_state.c
+++ b/tests/x11/test_state.c
@@ -28,12 +28,15 @@ int state_property(Display *display, Window window, Atom property,
return Success;
}
-static void state_changed(struct yasl_surface *surface, uint32_t state, void *ud)
+static void collect(struct yasl_private_display *display)
{
- (void)ud;
- assert(yasl_private_surface_state(surface) == state);
- reported_state = state;
- notifications++;
+ struct yasl_private_event event;
+ while (yasl_private_display_poll_event(display, &event)) {
+ assert(event.type == YASL_PRIVATE_EVENT_WINDOW_STATE);
+ assert(yasl_private_surface_state(event.surface) == event.state.flags);
+ reported_state = event.state.flags;
+ notifications++;
+ }
}
/* Build an XSETTINGS blob in either byte order. */
@@ -98,35 +101,45 @@ int main(void)
display.native = (Display *)&display;
struct x11_surface surface = {.base = {.display = &display.base,
.state = YASL_PRIVATE_STATE_ACTIVATED}, .window = 42};
- set_callbacks(&surface.base, &(struct yasl_private_window_cbs){.state = state_changed}, NULL);
+ assert(yasl_private_events_open(&display.base));
+ assert(yasl_private_events_register(&surface.base));
properties[0] = display.fullscreen;
property_count = 1;
update_state(&surface);
+ collect(&display.base);
assert(notifications == 1);
assert(reported_state == (YASL_PRIVATE_STATE_FULLSCREEN | YASL_PRIVATE_STATE_ACTIVATED));
update_state(&surface);
+ collect(&display.base);
assert(notifications == 1);
/* Both maximized axes are required; activation survives property changes. */
properties[0] = display.maximized_h;
update_state(&surface);
+ collect(&display.base);
assert(notifications == 2 && reported_state == YASL_PRIVATE_STATE_ACTIVATED);
properties[1] = display.maximized_v;
property_count = 2;
update_state(&surface);
+ collect(&display.base);
assert(notifications == 3);
assert(reported_state == (YASL_PRIVATE_STATE_MAXIMIZED | YASL_PRIVATE_STATE_ACTIVATED));
properties[2] = display.fullscreen;
property_count = 3;
update_state(&surface);
+ collect(&display.base);
assert(notifications == 4);
assert(reported_state == (YASL_PRIVATE_STATE_FULLSCREEN | YASL_PRIVATE_STATE_MAXIMIZED | YASL_PRIVATE_STATE_ACTIVATED));
property_count = 0;
update_state(&surface);
+ collect(&display.base);
assert(notifications == 5 && reported_state == YASL_PRIVATE_STATE_ACTIVATED);
update_state(&surface);
+ collect(&display.base);
assert(notifications == 5);
+ yasl_private_events_unregister(&surface.base);
+ yasl_private_events_close(&display.base);
return 0;
}
diff --git a/tests/x11/test_tablet.c b/tests/x11/test_tablet.c
index be5da4c..8d9106e 100644
--- a/tests/x11/test_tablet.c
+++ b/tests/x11/test_tablet.c
@@ -24,31 +24,32 @@ struct drag_test_recorder {
struct yasl_private_vector2i last_pos;
};
-static void on_test_drag(struct yasl_surface *s, enum yasl_private_drag_event ev,
- struct yasl_private_vector2i pos, void *ud)
-{
- (void)s;
- struct drag_test_recorder *rec = ud;
- rec->last_pos = pos;
- if (ev == YASL_PRIVATE_DRAG_OVER) rec->over_count++;
- else if (ev == YASL_PRIVATE_DRAG_LEAVE) rec->leave_count++;
- else if (ev == YASL_PRIVATE_DRAG_DROP) rec->drop_count++;
-}
-
struct drop_test_recorder {
int over_count;
int leave_count;
struct yasl_private_vector2i last_pos;
};
-static void on_test_drop(struct yasl_surface *s, enum yasl_private_drop_event ev,
- struct yasl_private_vector2i pos, void *ud)
+static void collect(struct yasl_private_display *display, struct yasl_surface *first,
+ struct yasl_surface *second, struct drag_test_recorder *a,
+ struct drag_test_recorder *b, struct drop_test_recorder *drop)
{
- (void)s;
- struct drop_test_recorder *rec = ud;
- rec->last_pos = pos;
- if (ev == YASL_PRIVATE_DROP_OVER) rec->over_count++;
- else if (ev == YASL_PRIVATE_DROP_LEAVE) rec->leave_count++;
+ struct yasl_private_event event;
+ while (yasl_private_display_poll_event(display, &event)) {
+ if (event.type == YASL_PRIVATE_EVENT_DRAG) {
+ assert(event.surface == first || event.surface == second);
+ struct drag_test_recorder *rec = event.surface == first ? a : b;
+ rec->last_pos = event.drag.pos;
+ if (event.drag.action == YASL_PRIVATE_DRAG_OVER) rec->over_count++;
+ else if (event.drag.action == YASL_PRIVATE_DRAG_LEAVE) rec->leave_count++;
+ else if (event.drag.action == YASL_PRIVATE_DRAG_DROP) rec->drop_count++;
+ } else if (event.type == YASL_PRIVATE_EVENT_DROP_HOVER) {
+ assert(event.surface == first);
+ drop->last_pos = event.drop.pos;
+ if (event.drop.action == YASL_PRIVATE_DROP_OVER) drop->over_count++;
+ else if (event.drop.action == YASL_PRIVATE_DROP_LEAVE) drop->leave_count++;
+ }
+ }
}
static void on_test_drag_end(void *ud, enum yasl_private_drag_end how)
@@ -81,7 +82,7 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
struct yasl_private_popup_spec valid_spec = {
.size = {100, 120},
.anchor = {30, 40, 50, 60},
- .beside = false,
+ .anchor_edges = 6, .gravity = 8, .constraints = 15,
.content_offset = {5, 10},
};
assert(popup_spec_valid(s, &valid_spec));
@@ -93,7 +94,7 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
/* Explicit XDG-style anchor/gravity stays exact unless a constraint allows a fit. */
struct yasl_private_popup_spec positioned = {
- .positioner_explicit = true,
+
.anchor_edges = 2, /* bottom */
.gravity = 2, /* below */
.size = {100, 120}, .anchor = {100, 100, 40, 20},
@@ -118,7 +119,7 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
popup_calculate_position(d, s, &positioned, &x, &y, &actual_size);
assert(x == 1920 - actual_size.x && actual_size.x == 20);
- valid_spec.beside = true;
+ valid_spec.anchor_edges = 7;
popup_calculate_position(d, s, &valid_spec, &x, &y, &actual_size);
assert(x == 30 + 50 - 5);
assert(y == 40 - 10);
@@ -133,7 +134,7 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
struct yasl_private_popup_spec repo_spec = {
.size = {150, 180},
.anchor = {10, 20, 30, 40},
- .beside = false,
+ .anchor_edges = 6, .gravity = 8, .constraints = 15,
.content_offset = {0, 0},
};
assert(surface_popup_reposition(popup_base, &repo_spec));
@@ -149,10 +150,10 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
struct drag_test_recorder rec1 = {0};
struct drag_test_recorder rec2 = {0};
- struct yasl_private_window_cbs cbs1 = {.drag = on_test_drag};
- struct yasl_private_window_cbs cbs2 = {.drag = on_test_drag};
- set_callbacks(&s->base, &cbs1, &rec1);
- set_callbacks(&s2.base, &cbs2, &rec2);
+ struct drop_test_recorder drec = {0};
+ assert(yasl_private_events_open(&d->base));
+ assert(yasl_private_events_register(&s->base));
+ assert(yasl_private_events_register(&s2.base));
enum yasl_private_drag_end end_reason = (enum yasl_private_drag_end)-1;
struct yasl_private_drag_listener l = {.end = on_test_drag_end};
@@ -163,6 +164,7 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
XIDeviceEvent mev = {.evtype = XI_Motion, .sourceid = 8, .event = 42, .event_x = 12.0, .event_y = 34.0};
XGenericEventCookie cookie = {.evtype = XI_Motion, .data = &mev};
xi_event(d, &cookie);
+ collect(&d->base, &s->base, &s2.base, &rec1, &rec2, &drec);
assert(rec1.over_count == 1);
assert(rec1.last_pos.x == 12 && rec1.last_pos.y == 34);
@@ -171,6 +173,7 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
mev.event_x = 56.0;
mev.event_y = 78.0;
xi_event(d, &cookie);
+ collect(&d->base, &s->base, &s2.base, &rec1, &rec2, &drec);
assert(rec1.leave_count == 1);
assert(rec2.over_count == 1);
assert(rec2.last_pos.x == 56 && rec2.last_pos.y == 78);
@@ -179,6 +182,7 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
XIDeviceEvent rel = {.evtype = XI_ButtonRelease, .sourceid = 8, .event = 43, .detail = 1};
cookie = (XGenericEventCookie){.evtype = XI_ButtonRelease, .data = &rel};
xi_event(d, &cookie);
+ collect(&d->base, &s->base, &s2.base, &rec1, &rec2, &drec);
assert(rec2.drop_count == 1);
assert(end_reason == YASL_PRIVATE_DRAG_DROPPED);
assert(!d->drag.active);
@@ -188,8 +192,10 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
cookie = (XGenericEventCookie){.evtype = XI_Motion, .data = &mev};
mev.event = 42;
xi_event(d, &cookie);
+ collect(&d->base, &s->base, &s2.base, &rec1, &rec2, &drec);
assert(rec1.over_count == 2);
drag_cancel(&d->base);
+ collect(&d->base, &s->base, &s2.base, &rec1, &rec2, &drec);
assert(rec1.leave_count == 2);
assert(end_reason == YASL_PRIVATE_DRAG_CANCELLED);
assert(!d->drag.active);
@@ -203,9 +209,13 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
assert(end_reason == YASL_PRIVATE_DRAG_CANCELLED);
assert(!d->drag.active);
struct yasl_private_event reset_ev;
- assert(yasl_private_surface_poll_event(&s->base, &reset_ev));
+ /* The display stream also carries the reset of the second surface. */
+ do { assert(yasl_private_display_poll_event(&d->base, &reset_ev)); }
+ while (reset_ev.type != YASL_PRIVATE_EVENT_INPUT_RESET || reset_ev.surface != &s->base);
assert(reset_ev.type == YASL_PRIVATE_EVENT_INPUT_RESET);
+ collect(&d->base, &s->base, &s2.base, &rec1, &rec2, &drec);
+
/* 4. Drag image parameter */
uint32_t pixels[16] = {0xFF00FF00};
struct yasl_private_drag_image img = {.pixels = pixels, .size = {4, 4}, .hotspot = {2, 2}};
@@ -214,6 +224,8 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
assert(drag_carry(&s->base, (struct yasl_private_vector2i){10, 10}));
drag_cancel(&d->base);
+ collect(&d->base, &s->base, &s2.base, &rec1, &rec2, &drec);
+
/* 5. XDND drop-target events and URI parsing */
size_t out_len = 0;
char *parsed = parse_file_uris("file:///tmp/doc.txt\r\n", 21, &out_len);
@@ -236,9 +248,6 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
d->xdnd_drop = 13;
d->uri_list = 20;
- struct drop_test_recorder drec = {0};
- cbs1.drop = on_test_drop;
- set_callbacks(&s->base, &cbs1, &drec);
XClientMessageEvent enter_msg = {
.type = ClientMessage,
@@ -256,6 +265,7 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
.data.l = {99, 0, (100 << 16) | 200, 1000, 0},
};
handle_client_message(d, s, &pos_msg);
+ collect(&d->base, &s->base, &s2.base, &rec1, &rec2, &drec);
assert(drec.over_count == 1);
assert(drec.last_pos.x == 100 && drec.last_pos.y == 200);
@@ -266,10 +276,12 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
.data.l = {99, 0, 0, 0, 0},
};
handle_client_message(d, s, &leave_msg);
+ collect(&d->base, &s->base, &s2.base, &rec1, &rec2, &drec);
assert(drec.leave_count == 1);
handle_client_message(d, s, &enter_msg);
handle_client_message(d, s, &pos_msg);
+ collect(&d->base, &s->base, &s2.base, &rec1, &rec2, &drec);
assert(drec.over_count == 2);
XClientMessageEvent drop_msg = {
@@ -279,17 +291,22 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
.data.l = {99, 0, 1005, 0, 0},
};
handle_client_message(d, s, &drop_msg);
+ collect(&d->base, &s->base, &s2.base, &rec1, &rec2, &drec);
assert(drec.leave_count == 2);
assert(d->pending_drop.active);
/* Push YASL_PRIVATE_EVENT_DROP */
push(s, (struct yasl_private_event){.type = YASL_PRIVATE_EVENT_DROP}, "file:///sample.png\r\n", 20);
struct yasl_private_event drop_ev;
- assert(yasl_private_surface_poll_event(&s->base, &drop_ev));
+ assert(yasl_private_display_poll_event(&d->base, &drop_ev));
assert(drop_ev.type == YASL_PRIVATE_EVENT_DROP);
assert(drop_ev.text.len == 20);
assert(!strcmp(drop_ev.text.data, "file:///sample.png\r\n"));
+ yasl_private_events_unregister(&s->base);
+ yasl_private_events_unregister(&s2.base);
+ yasl_private_events_close(&d->base);
+
/* Clean up s2 */
s->next = NULL;
input_queue_clear(&s->input);
diff --git a/tests/x11/test_tablet_native.c b/tests/x11/test_tablet_native.c
index 828082c..f4f8014 100644
--- a/tests/x11/test_tablet_native.c
+++ b/tests/x11/test_tablet_native.c
@@ -2,7 +2,10 @@
#define main tablet_example_main
#include "../../examples/tablet.c"
#undef main
-#include <common/private_native.h>
+#include <yasl/native/x11.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@@ -55,41 +58,53 @@ static int connect_tool(const char *path)
return fd;
}
-static void native_draw(struct yasl_surface *surface, struct yasl_private_frame *frame, void *ud)
-{
- (void)surface;
- draw(ud, surface, frame);
-}
+struct canvas_state {
+ struct yasl_pen_payload pen;
+ uint32_t *pixels;
+ int width, height, painted_width, painted_height;
+ bool down;
+};
-static void native_configure(struct yasl_surface *surface, struct yasl_private_geometry geometry, void *ud)
+static void render_event(yasl_surface *surface, struct canvas_state *state, const yasl_event *event)
{
- input(ud, &(struct yasl_private_event){.surface = surface, .type = YASL_PRIVATE_EVENT_WINDOW_RESIZE,
- .resize = {.geometry = geometry}});
+ if (event->type == YASL_EVENT_PEN) {
+ state->pen = event->pen;
+ state->down = event->pen.in_contact;
+ }
+ state->pixels = canvas(surface, &state->width, &state->height,
+ &state->painted_width, &state->painted_height, false);
+ assert(state->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,
+ (1.5 + 12 * event->pen.pressure) * scale, event->pen.tool == YASL_PEN_ERASER);
+ }
+ assert(yasl_cpu_present(surface));
}
-static void native_input(struct app *app, const struct yasl_private_event *event)
+static void drain(yasl_surface *surface, struct canvas_state *state)
{
- input(app, event);
+ yasl_event event;
+ int result;
+ while ((result = yasl_wait_event(&event, 0)) > 0)
+ render_event(surface, state, &event);
+ assert(result == 0);
}
-static void pump(int fd, struct yasl_private_display *display, struct yasl_surface *surface, struct app *app)
+static void pump(int fd, yasl_surface *surface, struct canvas_state *state)
{
xf86ITEventWaitForSync sync = {{sizeof(sync), XF86IT_EVENT_WAIT_FOR_SYNC}};
send_all(fd, &sync, sizeof(sync));
xf86ITResponseHeader response;
receive_all(fd, &response, sizeof(response));
assert(response.type == XF86IT_RESPONSE_SYNC_FINISHED && response.length == sizeof(response));
- /* The driver acknowledgment guarantees input processing has finished.
- * Round-trip on YASL's X connection before draining its event queue. */
- XSync(yasl_private_display_get_native_handle(display), False);
- assert(yasl_private_display_dispatch(display, 0) == 0);
- struct yasl_private_event event;
- while (yasl_private_surface_poll_event(surface, &event)) {
- native_input(app, &event);
- yasl_private_surface_schedule_redraw(surface);
- }
- yasl_private_display_flush(display);
- assert(!app->failed);
+ /* The driver acknowledgment guarantees XI2 processing has finished. */
+ XSync(yasl_x11_display(surface), False);
+ drain(surface, state);
+ /* Public polling submits the CPU frame before the native readback. */
+ XSync(yasl_x11_display(surface), False);
}
static void set_eraser_property(Display *display)
@@ -116,23 +131,16 @@ static void set_eraser_property(Display *display)
int main(int argc, char **argv)
{
assert(argc == 3); /* pen socket, eraser socket */
- struct app app = {.tablet_supported = true, .backend = YASL_PRIVATE_BACKEND_X11};
- struct yasl_private_display_spec ds = {.backend = YASL_PRIVATE_BACKEND_X11};
- struct yasl_private_display *display = yasl_private_display_open(NULL, &ds);
- assert(display && (yasl_private_display_caps(display) & YASL_PRIVATE_CAP_TABLET));
- struct yasl_private_window_spec ss = {.title = "YASL native pressure test", .size = {500, 400}};
- struct yasl_surface *surface = yasl_private_surface_create_toplevel(display, &ss);
- assert(surface);
- struct yasl_private_window_cbs cbs = {.draw = native_draw, .configure = native_configure};
- yasl_private_surface_set_callbacks(surface, &cbs, &app);
- yasl_private_surface_schedule_redraw(surface);
- Display *x = yasl_private_display_get_native_handle(display);
- Window window = (Window)(uintptr_t)yasl_private_surface_get_native_handle(surface);
+ struct canvas_state app = {0};
+ assert(yasl_set_backend(YASL_BACKEND_X11));
+ yasl_surface *surface = yasl_surface_create("YASL native pressure test", 500, 400, YASL_SURFACE_CPU);
+ assert(surface && (yasl_surface_features(surface) & YASL_CAP_TABLET));
+ Display *x = yasl_x11_display(surface);
+ Window window = (Window)yasl_x11_window(surface);
XMoveWindow(x, window, 0, 0);
XSetInputFocus(x, window, RevertToParent, CurrentTime);
XSync(x, False);
- assert(yasl_private_display_dispatch(display, 0) == 0);
- yasl_private_display_flush(display);
+ drain(surface, &app);
set_eraser_property(x);
int pen_fd = connect_tool(argv[1]), eraser_fd = connect_tool(argv[2]);
xf86ITEventMotion motion = {.header = {sizeof(motion), XF86IT_EVENT_MOTION}, .is_absolute = 1};
@@ -143,52 +151,50 @@ int main(int argc, char **argv)
.is_prox_in = 1, .valuators = motion.valuators};
send_all(pen_fd, &proximity, sizeof(proximity));
send_all(pen_fd, &motion, sizeof(motion));
- pump(pen_fd, display, surface, &app);
- assert(app.visible && !app.down && app.pointer.device == YASL_PRIVATE_PTR_DEV_PEN);
- assert(app.pointer.pos.x == 150 && app.pointer.pos.y == 200);
- assert(app.canvas[(size_t)200 * app.geometry.size.x + 150] == PAPER);
+ 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.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};
button.valuators.valuators[4] = 250; /* Driver pressure range is 0..1000. */
send_all(pen_fd, &button, sizeof(button));
- pump(pen_fd, display, surface, &app);
- assert(app.down && app.pointer.pen.pressure == 16384);
- assert(app.canvas[(size_t)200 * app.geometry.size.x + 150] == INK &&
- app.canvas[(size_t)200 * app.geometry.size.x + 170] == PAPER);
+ pump(pen_fd, surface, &app);
+ assert(app.down && fabs(app.pen.pressure - 0.25) < 0.001);
+ assert(app.pixels[(size_t)200 * app.width + 150] == INK &&
+ app.pixels[(size_t)200 * app.width + 160] == PAPER);
motion.valuators.mask[0] = 1 << 4; /* No position change. */
motion.valuators.valuators[4] = 1000;
send_all(pen_fd, &motion, sizeof(motion));
- pump(pen_fd, display, surface, &app);
- assert(app.down && app.pointer.pen.pressure == 65535);
- assert(app.canvas[(size_t)200 * app.geometry.size.x + 170] == INK);
+ pump(pen_fd, surface, &app);
+ assert(app.down && app.pen.pressure == 1.0);
+ assert(app.pixels[(size_t)200 * app.width + 160] == INK);
/* Check the actual window's pixels too, after the example presents. */
- XImage *image = XGetImage(x, window, 170, 200, 1, 1, AllPlanes, ZPixmap);
+ XImage *image = XGetImage(x, window, 160, 200, 1, 1, AllPlanes, ZPixmap);
assert(image && (XGetPixel(image, 0, 0) & 0xffffff) == (INK & 0xffffff));
XDestroyImage(image);
button.is_press = 0;
button.valuators.mask[0] = 0; /* Release omits all valuators. */
send_all(pen_fd, &button, sizeof(button));
- pump(pen_fd, display, surface, &app);
- assert(!app.down && !app.pointer.pen.pressure);
+ pump(pen_fd, surface, &app);
+ assert(!app.down && !app.pen.pressure);
send_all(eraser_fd, &proximity, sizeof(proximity));
button.is_press = 1;
button.valuators = proximity.valuators;
button.valuators.valuators[4] = 1000;
send_all(eraser_fd, &button, sizeof(button));
- pump(eraser_fd, display, surface, &app);
- assert(app.down && app.pointer.device == YASL_PRIVATE_PTR_DEV_ERASER && app.pointer.pen.pressure == 65535);
- assert(app.canvas[(size_t)200 * app.geometry.size.x + 150] == PAPER &&
- app.canvas[(size_t)200 * app.geometry.size.x + 170] == PAPER);
+ pump(eraser_fd, surface, &app);
+ assert(app.down && app.pen.tool == YASL_PEN_ERASER && app.pen.pressure == 1.0);
+ assert(app.pixels[(size_t)200 * app.width + 150] == PAPER &&
+ app.pixels[(size_t)200 * app.width + 160] == PAPER);
button.is_press = 0;
send_all(eraser_fd, &button, sizeof(button));
- pump(eraser_fd, display, surface, &app);
- assert(!app.down && !app.pointer.pen.pressure);
+ pump(eraser_fd, surface, &app);
+ assert(!app.down && !app.pen.pressure);
close(pen_fd);
close(eraser_fd);
- free(app.canvas);
- yasl_private_surface_destroy(surface);
- yasl_private_display_close(display);
+ yasl_shutdown();
puts("Native Xorg pen pressure, stationary pressure, release, and eraser drawing passed.");
return 0;
}