commit 8d5ae2e
uint
·
2026-08-04 11:09:24 +0000 UTC
parent d433c89
Wayland: zwp_relative_pointer_v1: implemented
7 files changed,
+102,
-18
M
Makefile
+10,
-1
1@@ -41,7 +41,7 @@ build/maus_x11.o: source/maus_x11.c include/maus.h include/maus_x11.h config.mk
2 ${CC} ${CFLAGS} ${CPPFLAGS} -c source/maus_x11.c -o $@
3
4 # Wayland
5-build/maus_wayland.o: source/maus_wayland.c include/maus.h include/maus_wayland.h build/xdg-shell-client-protocol.h build/pointer-constraints-unstable-v1-client-protocol.h config.mk
6+build/maus_wayland.o: source/maus_wayland.c include/maus.h include/maus_wayland.h build/xdg-shell-client-protocol.h build/pointer-constraints-unstable-v1-client-protocol.h build/relative-pointer-unstable-v1-client-protocol.h config.mk
7 mkdir -p build
8 ${CC} ${WL_CFLAGS} ${CPPFLAGS} -c source/maus_wayland.c -o $@
9 build/xdg-shell-client-protocol.h:
10@@ -62,6 +62,15 @@ build/pointer-constraints-unstable-v1-protocol.c:
11 build/pointer-constraints-unstable-v1-protocol.o: build/pointer-constraints-unstable-v1-protocol.c build/pointer-constraints-unstable-v1-client-protocol.h
12 mkdir -p build
13 ${CC} ${WL_CFLAGS} ${CPPFLAGS} -c build/pointer-constraints-unstable-v1-protocol.c -o $@
14+build/relative-pointer-unstable-v1-client-protocol.h:
15+ mkdir -p build
16+ wayland-scanner client-header ${PROTOS}/unstable/relative-pointer/relative-pointer-unstable-v1.xml $@
17+build/relative-pointer-unstable-v1-protocol.c:
18+ mkdir -p build
19+ wayland-scanner private-code ${PROTOS}/unstable/relative-pointer/relative-pointer-unstable-v1.xml $@
20+build/relative-pointer-unstable-v1-protocol.o: build/relative-pointer-unstable-v1-protocol.c build/relative-pointer-unstable-v1-client-protocol.h
21+ mkdir -p build
22+ ${CC} ${WL_CFLAGS} ${CPPFLAGS} -c build/relative-pointer-unstable-v1-protocol.c -o $@
23
24 clean:
25 rm -rf build ${LIB_NAME} config.mk compile_flags.txt
M
TODO
+1,
-0
1@@ -1,5 +1,6 @@
2 Maus:
3 [ ] Relative cursor
4+ [ ] Fill deltas
5 [ ] Rename mw->ctx internally
6 [ ] Move framebuffer creation out
7 of maus_init on platforms
+2,
-2
1@@ -32,8 +32,8 @@ case "$backend" in
2 wayland)
3 echo "CONF_CPPFLAGS = -DBACKEND_WAY $(pkg-config --cflags wayland-client wayland-cursor xkbcommon)" >> config.mk
4 echo "CONF_LDFLAGS = $(pkg-config --libs wayland-client wayland-cursor xkbcommon)" >> config.mk
5- echo "CONF_SRC = source/maus_wayland.c build/xdg-shell-protocol.c build/pointer-constraints-unstable-v1-protocol.c" >> config.mk
6- echo "CONF_OBJS = build/maus_wayland.o build/xdg-shell-protocol.o build/pointer-constraints-unstable-v1-protocol.o" >> config.mk
7+ echo "CONF_SRC = source/maus_wayland.c build/xdg-shell-protocol.c build/pointer-constraints-unstable-v1-protocol.c build/relative-pointer-unstable-v1-protocol.c" >> config.mk
8+ echo "CONF_OBJS = build/maus_wayland.o build/xdg-shell-protocol.o build/pointer-constraints-unstable-v1-protocol.o build/relative-pointer-unstable-v1-protocol.o" >> config.mk
9 echo "CONF_LIB_NAME = libmaus_wayland.a" >> config.mk
10 echo "PROTOS = $(pkg-config --variable=pkgdatadir wayland-protocols)" >> config.mk
11 ;;
+2,
-2
1@@ -48,8 +48,8 @@ void handle_ev(Maus* mw, MausEvent* ev)
2 }
3 if (keys[MAUS_KEY_CONTROL_L] && keys[MAUS_KEY_R]) {
4 cur_relative ?
5- maus_cur_set_mode(mw, MAUS_CURSOR_STATE_RELATIVE) :
6- maus_cur_set_mode(mw, MAUS_CURSOR_STATE_ABSOLUTE);
7+ maus_cur_set_mode(mw, MAUS_CURSOR_STATE_ABSOLUTE) :
8+ maus_cur_set_mode(mw, MAUS_CURSOR_STATE_RELATIVE);
9
10 cur_relative = !cur_relative;
11 }
+2,
-0
1@@ -91,6 +91,8 @@ typedef struct {
2 struct {
3 int32_t x;
4 int32_t y;
5+ int32_t dx;
6+ int32_t dy;
7 } motion;
8 } mouse;
9
+8,
-5
1@@ -24,6 +24,8 @@ struct xdg_toplevel;
2
3 struct zwp_pointer_constraints_v1;
4 struct zwp_confined_pointer_v1;
5+struct zwp_relative_pointer_manager_v1;
6+struct zwp_relative_pointer_v1;
7
8 struct xkb_context;
9 struct xkb_keymap;
10@@ -36,8 +38,8 @@ typedef struct {
11 uint32_t width;
12 uint32_t height;
13
14- uint32_t mouse_x;
15- uint32_t mouse_y;
16+ int32_t mouse_x;
17+ int32_t mouse_y;
18 uint32_t mouse_button;
19 uint8_t mouse_pressed;
20
21@@ -72,8 +74,10 @@ typedef struct {
22 uint32_t pointer_enter_serial;
23 int8_t cursor_state;
24
25- struct zwp_pointer_constraints_v1* pointer_constraints;
26- struct zwp_confined_pointer_v1* locked_pointer;
27+ struct zwp_pointer_constraints_v1* pointer_constraints;
28+ struct zwp_confined_pointer_v1* locked_pointer;
29+ struct zwp_relative_pointer_manager_v1* relative_pointer_manager;
30+ struct zwp_relative_pointer_v1* relative_pointer;
31
32 struct xkb_context* xkb_context;
33 struct xkb_keymap* xkb_keymap;
34@@ -91,4 +95,3 @@ typedef struct {
35 } MausBackend;
36
37 #endif /* MAUS_WAYLAND_H */
38-
+77,
-8
1@@ -11,6 +11,7 @@
2 #include <wayland-cursor.h>
3 #include <xdg-shell-client-protocol.h>
4 #include <pointer-constraints-unstable-v1-client-protocol.h>
5+#include <relative-pointer-unstable-v1-client-protocol.h>
6 #include <xkbcommon/xkbcommon.h>
7
8 #include "maus.h"
9@@ -36,6 +37,7 @@ static void pointer_axis_stop(void* data, struct wl_pointer* pointer, uint32_t t
10 static void pointer_axis_discrete(void* data, struct wl_pointer* pointer, uint32_t axis, int32_t discrete);
11 static void pointer_axis_value120(void* data, struct wl_pointer* pointer, uint32_t axis, int32_t value120);
12 static void pointer_axis_relative_direction(void* data, struct wl_pointer* pointer, uint32_t axis, uint32_t direction);
13+static void relative_pointer_motion(void* data, struct zwp_relative_pointer_v1* relative_pointer, uint32_t utime_hi, uint32_t utime_lo, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_unaccel, wl_fixed_t dy_unaccel);
14 static void keyboard_keymap(void* data, struct wl_keyboard* keyboard, uint32_t format, int32_t fd, uint32_t size);
15 static void keyboard_enter(void* data, struct wl_keyboard* keyboard, uint32_t serial, struct wl_surface* surface, struct wl_array* keys);
16 static void keyboard_leave(void* data, struct wl_keyboard* keyboard, uint32_t serial, struct wl_surface* surface);
17@@ -44,12 +46,14 @@ static void keyboard_modifiers(void* data, struct wl_keyboard* keyboard, uint32_
18 static void keyboard_repeat_info(void* data, struct wl_keyboard* keyboard, int32_t rate, int32_t delay);
19 static void registry_global(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version);
20
21-static void cursor_destroy(Maus* mw);
22-static void cursor_hide(Maus* mw);
23 static int8_t cursor_init(Maus* mw);
24+static void cursor_destroy(Maus* mw);
25 static void cursor_lock(Maus* mw);
26 static void cursor_unlock(Maus* mw);
27 static void cursor_show(Maus* mw);
28+static void cursor_hide(Maus* mw);
29+static void cursor_relative(Maus* mw);
30+static void cursor_absolute(Maus* mw);
31 static MausKey keysym_to_mauskey(xkb_keysym_t sym);
32 static MausMouseButton wl_button_to_maus(uint32_t button);
33 static void wl_buffer_release(void* data, struct wl_buffer* buffer);
34@@ -71,6 +75,9 @@ static struct wl_keyboard_listener keyboard_listener = {
35 keyboard_keymap, keyboard_enter, keyboard_leave, keyboard_key,
36 keyboard_modifiers, keyboard_repeat_info
37 };
38+static struct zwp_relative_pointer_v1_listener relative_pointer_listener = {
39+ relative_pointer_motion
40+};
41 static struct wl_buffer_listener wl_buffer_listener = { wl_buffer_release };
42
43 static void wl_buffer_release(void* data, struct wl_buffer* buffer)
44@@ -172,9 +179,9 @@ static void registry_global(void* data, struct wl_registry* registry,
45 wl_seat_add_listener(be->seat, &seat_listener, mw);
46 }
47 else if (strcmp(interface, zwp_pointer_constraints_v1_interface.name) == 0)
48- be->pointer_constraints = wl_registry_bind(
49- registry, name, &zwp_pointer_constraints_v1_interface, 1
50- );
51+ be->pointer_constraints = wl_registry_bind(registry, name, &zwp_pointer_constraints_v1_interface, 1);
52+ else if (strcmp(interface, zwp_relative_pointer_manager_v1_interface.name) == 0)
53+ be->relative_pointer_manager = wl_registry_bind(registry, name, &zwp_relative_pointer_manager_v1_interface, 1);
54 }
55
56 static void seat_capabilities(void* data, struct wl_seat* seat, uint32_t capabilities)
57@@ -187,6 +194,7 @@ static void seat_capabilities(void* data, struct wl_seat* seat, uint32_t capabil
58 wl_pointer_add_listener(be->pointer, &pointer_listener, mw);
59 }
60 else if (!(capabilities & WL_SEAT_CAPABILITY_POINTER) && be->pointer) {
61+ cursor_absolute(mw);
62 wl_pointer_destroy(be->pointer);
63 be->pointer = NULL;
64 }
65@@ -242,6 +250,9 @@ static void pointer_motion(void* data, struct wl_pointer* pointer, uint32_t time
66 (void)pointer;
67 (void)time;
68
69+ if (mw->backend.relative_pointer)
70+ return;
71+
72 mw->backend.pending.pending = 1;
73 mw->backend.pending.type = MAUS_EV_MOUSE_MOTION;
74 mw->backend.pending.mouse_x = wl_fixed_to_int(sx);
75@@ -334,6 +345,25 @@ static void pointer_axis_relative_direction(void* data, struct wl_pointer* point
76 (void)direction;
77 }
78
79+static void relative_pointer_motion(void* data, struct zwp_relative_pointer_v1* relative_pointer,
80+ uint32_t utime_hi, uint32_t utime_lo,
81+ wl_fixed_t dx, wl_fixed_t dy,
82+ wl_fixed_t dx_unaccel, wl_fixed_t dy_unaccel)
83+{
84+ Maus* mw = data;
85+
86+ (void)relative_pointer;
87+ (void)utime_hi;
88+ (void)utime_lo;
89+ (void)dx_unaccel;
90+ (void)dy_unaccel;
91+
92+ mw->backend.pending.pending = 1;
93+ mw->backend.pending.type = MAUS_EV_MOUSE_MOTION;
94+ mw->backend.pending.mouse_x = wl_fixed_to_int(dx);
95+ mw->backend.pending.mouse_y = wl_fixed_to_int(dy);
96+}
97+
98 static void keyboard_keymap(void* data, struct wl_keyboard* keyboard, uint32_t format,
99 int32_t fd, uint32_t size)
100 {
101@@ -558,6 +588,35 @@ static void cursor_show(Maus* mw)
102 wl_surface_commit(be->cursor_surface);
103 }
104
105+static void cursor_relative(Maus* mw)
106+{
107+ MausBackend* be = &mw->backend;
108+ if (be->relative_pointer)
109+ return;
110+ if (!be->relative_pointer_manager || !be->pointer)
111+ return;
112+
113+ cursor_lock(mw);
114+ be->relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(
115+ be->relative_pointer_manager, be->pointer
116+ );
117+ zwp_relative_pointer_v1_add_listener(
118+ be->relative_pointer, &relative_pointer_listener, mw
119+ );
120+}
121+
122+static void cursor_absolute(Maus* mw)
123+{
124+ MausBackend* be = &mw->backend;
125+
126+ if (be->relative_pointer) {
127+ zwp_relative_pointer_v1_destroy(be->relative_pointer);
128+ be->relative_pointer = NULL;
129+ }
130+
131+ cursor_unlock(mw);
132+}
133+
134 static int8_t fb_create(Maus* mw);
135 static int8_t fb_create_buffer(Maus* mw, MausWLBuffer* wb);
136 static int8_t fb_create_shm(size_t size);
137@@ -810,6 +869,7 @@ void maus_close(Maus* mw)
138 be = &mw->backend;
139
140 fb_destroy(mw);
141+ cursor_absolute(mw);
142
143 if (be->xdg_toplevel)
144 xdg_toplevel_destroy(be->xdg_toplevel);
145@@ -820,8 +880,6 @@ void maus_close(Maus* mw)
146 if (be->surface)
147 wl_surface_destroy(be->surface);
148
149- cursor_unlock(mw);
150-
151 if (be->keyboard)
152 wl_keyboard_destroy(be->keyboard);
153
154@@ -834,6 +892,9 @@ void maus_close(Maus* mw)
155 if (be->pointer_constraints)
156 zwp_pointer_constraints_v1_destroy(be->pointer_constraints);
157
158+ if (be->relative_pointer_manager)
159+ zwp_relative_pointer_manager_v1_destroy(be->relative_pointer_manager);
160+
161 if (be->xkb_state)
162 xkb_state_unref(be->xkb_state);
163
164@@ -1106,7 +1167,15 @@ void maus_cur_set_mode(Maus* mw, MausCursorState state)
165 break;
166 case MAUS_CURSOR_STATE_FREE:
167 cursor_unlock(mw);
168- mw->backend.cursor_state = MAUS_CURSOR_STATE_VISIBLE;
169+ mw->backend.cursor_state = state;
170+ break;
171+ case MAUS_CURSOR_STATE_RELATIVE:
172+ cursor_relative(mw);
173+ mw->backend.cursor_state = state;
174+ break;
175+ case MAUS_CURSOR_STATE_ABSOLUTE:
176+ cursor_absolute(mw);
177+ mw->backend.cursor_state = state;
178 break;
179 default:
180 break;