diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-12 10:53:22 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-12 10:53:22 +0300 |
| commit | 5206933399775e5ff46baefbbb3a776c2a9bb84c (patch) | |
| tree | e7549216ac626c1f3ac22345f79fbf80cc5a90fb /tests/wayland/test_cursor.c | |
| parent | 881fb6cb1d64868132287bd9637f4ae1cbc3504c (diff) | |
feat: add type-safe native platform headers and portable drag support
- Add include/yasl/native/{wayland,cocoa,x11}.h with type-safe handle accessors.
- Unify drag-and-drop and window carry support across Wayland, X11, and Cocoa.
- Preserve full ABI compatibility for capability flags.
- Install native headers conditionally based on enabled backend.
- Include missing tablet example and backend test suites.
Diffstat (limited to 'tests/wayland/test_cursor.c')
| -rw-r--r-- | tests/wayland/test_cursor.c | 118 |
1 files changed, 118 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; +} |
