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 TODO
+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;