summaryrefslogtreecommitdiff
path: root/tests/wayland
diff options
context:
space:
mode:
Diffstat (limited to 'tests/wayland')
-rw-r--r--tests/wayland/test_cursor.c118
-rw-r--r--tests/wayland/test_tablet.c62
2 files changed, 180 insertions, 0 deletions
diff --git a/tests/wayland/test_cursor.c b/tests/wayland/test_cursor.c
new file mode 100644
index 0000000..e43bff4
--- /dev/null
+++ b/tests/wayland/test_cursor.c
@@ -0,0 +1,118 @@
+#include "wayland/internal.h"
+#include <assert.h>
+
+/* Record cursor requests without a compositor or tablet hardware. */
+static int pointer_hides, tool_hides, pointer_shapes, tool_shapes;
+static uint32_t pointer_serial, tool_serial, pointer_shape, tool_shape;
+static struct wp_cursor_shape_device_v1 *pointer_device;
+
+static void pointer_cursor(struct wl_pointer *pointer, uint32_t serial,
+ struct wl_surface *surface, int32_t x, int32_t y)
+{
+ assert(pointer && !surface && !x && !y);
+ pointer_hides++;
+ pointer_serial = serial;
+}
+
+static void tool_cursor(struct zwp_tablet_tool_v2 *tool, uint32_t serial,
+ struct wl_surface *surface, int32_t x, int32_t y)
+{
+ assert(tool && !surface && !x && !y);
+ tool_hides++;
+ tool_serial = serial;
+}
+
+static void cursor_shape(struct wp_cursor_shape_device_v1 *device,
+ uint32_t serial, uint32_t shape)
+{
+ if (device == pointer_device) {
+ pointer_shapes++;
+ pointer_serial = serial;
+ pointer_shape = shape;
+ } else {
+ assert(device);
+ tool_shapes++;
+ tool_serial = serial;
+ tool_shape = shape;
+ }
+}
+
+static uint32_t pointer_version(struct wl_pointer *pointer)
+{
+ assert(pointer);
+ return WL_POINTER_FRAME_SINCE_VERSION;
+}
+
+#define wl_pointer_set_cursor pointer_cursor
+#define zwp_tablet_tool_v2_set_cursor tool_cursor
+#define wp_cursor_shape_device_v1_set_shape cursor_shape
+#define wl_pointer_get_version pointer_version
+#include "../../src/wayland/pointer.c"
+
+int main(void)
+{
+ struct wayland_display display = {.base.ops = &yasl_wayland_backend};
+ struct wayland_surface surface = {.base.display = &display.base, .conn = &display,
+ .scale_factor = 1, .cursor = YASL_CURSOR_TEXT};
+ surface.surface = (struct wl_surface *)&surface;
+ display.surfaces = &surface;
+ struct seat seat = {.conn = &display};
+ seat.pointer = (struct wl_pointer *)&seat;
+ display.seats = &seat;
+ struct tablet_tool tool = {.seat = &seat};
+ tool.proxy = (struct zwp_tablet_tool_v2 *)&tool;
+
+ /* The example selects hidden before either input device has entered. */
+ yasl_surface_set_cursor(&surface.base, YASL_CURSOR_HIDDEN);
+ assert(!pointer_hides && !tool_hides);
+ pointer_enter(&seat, seat.pointer, 10, surface.surface, 0, 0);
+ assert(pointer_hides == 1 && pointer_serial == 10);
+ tablet_tool_proximity_in(&tool, tool.proxy, 11, NULL, surface.surface);
+ assert(tool_hides == 1 && tool_serial == 11);
+
+ /* Hiding also works with no cursor-shape protocol, and preserves input. */
+ pointer_motion(&seat, seat.pointer, 0, wl_fixed_from_int(12), wl_fixed_from_int(34));
+ pointer_frame(&seat, seat.pointer);
+ tablet_tool_motion(&tool, tool.proxy, wl_fixed_from_int(56), wl_fixed_from_int(78));
+ tool_frame(&tool, tool.proxy, 0);
+ struct yasl_input_event event;
+ assert(yasl_surface_input_poll(&surface.base, &event));
+ assert(event.kind == YASL_INPUT_MOUSE && event.mouse.device == YASL_PTR_DEV_MOUSE);
+ assert(event.mouse.pos.x == 12 && event.mouse.pos.y == 34);
+ assert(yasl_surface_input_poll(&surface.base, &event));
+ assert(event.kind == YASL_INPUT_MOUSE && event.mouse.device == YASL_PTR_DEV_PEN);
+ assert(event.mouse.pos.x == 56 && event.mouse.pos.y == 78);
+ assert(!yasl_surface_input_poll(&surface.base, &event));
+
+ /* Each new entry needs a request with its own serial. */
+ pointer_leave(&seat, seat.pointer, 12, surface.surface);
+ pointer_frame(&seat, seat.pointer);
+ tablet_tool_proximity_out(&tool, tool.proxy);
+ pointer_enter(&seat, seat.pointer, 13, surface.surface, 0, 0);
+ tool.eraser = true;
+ tablet_tool_proximity_in(&tool, tool.proxy, 14, NULL, surface.surface);
+ assert(pointer_hides == 2 && pointer_serial == 13);
+ assert(tool_hides == 2 && tool_serial == 14);
+
+ /* Restore a visible shape on both currently focused devices. */
+ pointer_device = seat.cursor_shape_dev = (struct wp_cursor_shape_device_v1 *)&seat;
+ tool.shape_dev = (struct wp_cursor_shape_device_v1 *)&tool;
+ yasl_surface_set_cursor(&surface.base, YASL_CURSOR_ARROW);
+ assert(pointer_shapes == 1 && tool_shapes == 1);
+ assert(pointer_shape == WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT);
+ assert(tool_shape == WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT);
+ yasl_surface_set_cursor(&surface.base, YASL_CURSOR_HIDDEN);
+ assert(pointer_hides == 3 && tool_hides == 3);
+ assert(pointer_shapes == 1 && tool_shapes == 1);
+
+ /* Updating an unfocused surface must not alter the active cursor. */
+ struct wayland_surface other = {.base.display = &display.base, .conn = &display};
+ yasl_surface_set_cursor(&other.base, YASL_CURSOR_CROSSHAIR);
+ assert(pointer_shapes == 1 && tool_shapes == 1);
+ yasl_surface_set_cursor(&surface.base, (enum yasl_cursor)-1);
+ yasl_surface_set_cursor(&surface.base, (enum yasl_cursor)(YASL_CURSOR_HIDDEN + 1));
+ assert(pointer_hides == 3 && tool_hides == 3);
+ assert(pointer_shapes == 1 && tool_shapes == 1);
+ input_queue_clear(&surface.input);
+ return 0;
+}
diff --git a/tests/wayland/test_tablet.c b/tests/wayland/test_tablet.c
new file mode 100644
index 0000000..449c446
--- /dev/null
+++ b/tests/wayland/test_tablet.c
@@ -0,0 +1,62 @@
+#include "../../src/wayland/pointer.c"
+#include <assert.h>
+
+static struct yasl_mouse_event next(struct wayland_surface *surface)
+{
+ struct yasl_input_event event;
+ assert(yasl_surface_input_poll(&surface->base, &event));
+ assert(event.surface == &surface->base && event.kind == YASL_INPUT_MOUSE);
+ return event.mouse;
+}
+
+int main(void)
+{
+ struct wayland_display display = {.base.ops = &yasl_wayland_backend};
+ struct wayland_surface surface = {.base.display = &display.base, .conn = &display,
+ .scale_factor = 1.5};
+ struct seat seat = {.conn = &display, .tablet_focus = &surface};
+ struct tablet_tool tool = {.seat = &seat};
+ seat.tool = &tool;
+ tablet_tool_motion(&tool, NULL, wl_fixed_from_int(100), wl_fixed_from_int(120));
+ tool_pressure(&tool, NULL, 32768);
+ tool_tilt(&tool, NULL, wl_fixed_from_int(-35), wl_fixed_from_int(42));
+ tablet_tool_down(&tool, NULL, 1);
+ tool_frame(&tool, NULL, 0);
+ struct yasl_mouse_event ev = next(&surface);
+ assert(ev.kind == YASL_PTR_MOTION && ev.device == YASL_PTR_DEV_PEN);
+ assert(ev.pos.x == 150 && ev.pos.y == 180 && ev.pen.pressure == 32768);
+ assert(ev.pen.tilt_x == -35 && ev.pen.tilt_y == 42);
+ ev = next(&surface);
+ assert(ev.kind == YASL_PTR_PRESS && ev.button == 0 && ev.pen.pressure == 32768);
+
+ /* Stationary pressure and tilt changes are still motion samples. */
+ tool_pressure(&tool, NULL, 100000);
+ tool_tilt(&tool, NULL, wl_fixed_from_int(-120), wl_fixed_from_int(120));
+ tool_frame(&tool, NULL, 0);
+ ev = next(&surface);
+ assert(ev.kind == YASL_PTR_MOTION && ev.pen.pressure == 65535);
+ assert(ev.pos.x == 150 && ev.pos.y == 180);
+ assert(ev.pen.tilt_x == -90 && ev.pen.tilt_y == 90);
+ tablet_tool_up(&tool, NULL);
+ tool_frame(&tool, NULL, 0);
+ ev = next(&surface);
+ assert(ev.kind == YASL_PTR_RELEASE && ev.button == 0 && !ev.pen.pressure);
+
+ tool_type(&tool, NULL, ZWP_TABLET_TOOL_V2_TYPE_ERASER);
+ tool_pressure(&tool, NULL, 22000);
+ tool_frame(&tool, NULL, 0);
+ assert(next(&surface).device == YASL_PTR_DEV_ERASER);
+ tool_wheel(&tool, NULL, 0, 1);
+ tool_frame(&tool, NULL, 0);
+ ev = next(&surface);
+ assert(ev.kind == YASL_PTR_SCROLL && ev.device == YASL_PTR_DEV_ERASER);
+ tablet_tool_proximity_out(&tool, NULL);
+ ev = next(&surface);
+ assert(ev.kind == YASL_PTR_LEAVE && ev.device == YASL_PTR_DEV_ERASER && !ev.pen.pressure);
+ assert(!seat.tool && !seat.tablet_focus && !seat.tool_buttons);
+ assert(!(yasl_display_caps(&display.base) & YASL_CAP_TABLET));
+ display.tablet_mgr = (void *)&display; /* Capability depends on protocol availability. */
+ assert(yasl_display_caps(&display.base) & YASL_CAP_TABLET);
+ input_queue_clear(&surface.input);
+ return 0;
+}