diff options
Diffstat (limited to 'tests/x11/test_tablet_native.c')
| -rw-r--r-- | tests/x11/test_tablet_native.c | 126 |
1 files changed, 66 insertions, 60 deletions
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; } |
