1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
#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;
wl_surface_set_user_data(surface.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;
}
|