commit 1797ef5

uint  ·  2026-08-04 01:51:19 +0000 UTC
parent 52fb7f4
Wayland: handle shm buffer release
3 files changed,  +81, -28
M TODO
M TODO
+1, -0
1@@ -1,4 +1,5 @@
2 Maus:
3+[ ] Relative cursor
4 [ ] Rename mw->ctx internally
5 [ ] Move framebuffer creation out
6     of maus_init on platforms
+8, -3
 1@@ -47,15 +47,20 @@ typedef struct {
 2 	uint8_t  key_pressed;
 3 } MausEventPending;
 4 
 5+typedef struct {
 6+	struct wl_buffer* buffer;
 7+	void*             data;
 8+	size_t            size;
 9+	int8_t            busy;
10+} MausWLBuffer;
11+
12 typedef struct {
13 	struct wl_display*    display;
14-	struct wl_buffer*     buffer;
15 	struct wl_compositor* compositor;
16 	struct wl_surface*    surface;
17 
18 	struct wl_shm* shm;
19-	void*          shm_data;
20-	size_t         shm_size;
21+	MausWLBuffer   buffers[2];
22 
23 	struct wl_seat*     seat;
24 	struct wl_pointer*  pointer;
+72, -25
  1@@ -52,6 +52,7 @@ static void cursor_unlock(Maus* mw);
  2 static void cursor_show(Maus* mw);
  3 static MausKey keysym_to_mauskey(xkb_keysym_t sym);
  4 static MausMouseButton wl_button_to_maus(uint32_t button);
  5+static void wl_buffer_release(void* data, struct wl_buffer* buffer);
  6 
  7 static struct wl_registry_listener registry_listener = { registry_global, registry_global_remove };
  8 static struct xdg_surface_listener xdg_surface_listener = { xdg_surface_configure };
  9@@ -70,6 +71,16 @@ static struct wl_keyboard_listener keyboard_listener = {
 10 	keyboard_keymap, keyboard_enter, keyboard_leave, keyboard_key,
 11 	keyboard_modifiers, keyboard_repeat_info
 12 };
 13+static struct wl_buffer_listener wl_buffer_listener = { wl_buffer_release };
 14+
 15+static void wl_buffer_release(void* data, struct wl_buffer* buffer)
 16+{
 17+	MausWLBuffer* wb = data;
 18+
 19+	(void)buffer;
 20+
 21+	wb->busy = 0;
 22+}
 23 
 24 static void registry_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name)
 25 {
 26@@ -516,7 +527,7 @@ static void cursor_unlock(Maus* mw)
 27 	MausBackend* be = &mw->backend;
 28 
 29 	if (be->locked_pointer) {
 30-		zwp_pointer_constraints_v1_lock_pointer(be->locked_pointer);
 31+		zwp_confined_pointer_v1_destroy(be->locked_pointer);
 32 		be->locked_pointer = NULL;
 33 	}
 34 
 35@@ -548,11 +559,30 @@ static void cursor_show(Maus* mw)
 36 }
 37 
 38 static int8_t fb_create(Maus* mw);
 39+static int8_t fb_create_buffer(Maus* mw, MausWLBuffer* wb);
 40 static int8_t fb_create_shm(size_t size);
 41 static void fb_destroy(Maus* mw);
 42 static int8_t handle_event(Maus* mw, MausEvent* ev);
 43 
 44 static int8_t fb_create(Maus* mw)
 45+{
 46+	MausBackend* be = &mw->backend;
 47+
 48+	if (!fb_create_buffer(mw, &be->buffers[0])) {
 49+		fb_destroy(mw);
 50+		return 0;
 51+	}
 52+	if (!fb_create_buffer(mw, &be->buffers[1])) {
 53+		fb_destroy(mw);
 54+		return 0;
 55+	}
 56+
 57+	mw->fb = be->buffers[0].data;
 58+	mw->stride = mw->width;
 59+	return 1;
 60+}
 61+
 62+static int8_t fb_create_buffer(Maus* mw, MausWLBuffer* wb)
 63 {
 64 	MausBackend* be = &mw->backend;
 65 	struct wl_shm_pool* pool;
 66@@ -568,14 +598,15 @@ static int8_t fb_create(Maus* mw)
 67 	if (fd < 0)
 68 		return 0;
 69 
 70-	be->shm_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 71-	if (be->shm_data == MAP_FAILED) {
 72+	wb->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 73+	if (wb->data == MAP_FAILED) {
 74+		wb->data = NULL;
 75 		close(fd);
 76 		return 0;
 77 	}
 78 
 79 	pool = wl_shm_create_pool(be->shm, fd, size);
 80-	be->buffer = wl_shm_pool_create_buffer(
 81+	wb->buffer = wl_shm_pool_create_buffer(
 82 		pool, 0, mw->width, mw->height,
 83 		stride, WL_SHM_FORMAT_XRGB8888
 84 	);
 85@@ -583,9 +614,15 @@ static int8_t fb_create(Maus* mw)
 86 	wl_shm_pool_destroy(pool);
 87 	close(fd);
 88 
 89-	be->shm_size = size;
 90-	mw->fb = be->shm_data;
 91-	mw->stride = mw->width;
 92+	if (!wb->buffer) {
 93+		munmap(wb->data, size);
 94+		wb->data = NULL;
 95+		return 0;
 96+	}
 97+
 98+	wl_buffer_add_listener(wb->buffer, &wl_buffer_listener, wb);
 99+	wb->size = size;
100+	wb->busy = 0;
101 
102 	return 1;
103 }
104@@ -620,15 +657,20 @@ static void fb_destroy(Maus* mw)
105 {
106 	MausBackend* be = &mw->backend;
107 
108-	if (be->buffer)
109-		wl_buffer_destroy(be->buffer);
110+	uint32_t i;
111+
112+	for (i = 0; i < 2; i++) {
113+		if (be->buffers[i].buffer)
114+			wl_buffer_destroy(be->buffers[i].buffer);
115 
116-	if (be->shm_data && be->shm_size > 0)
117-		munmap(be->shm_data, be->shm_size);
118+		if (be->buffers[i].data && be->buffers[i].size > 0)
119+			munmap(be->buffers[i].data, be->buffers[i].size);
120 
121-	be->buffer = NULL;
122-	be->shm_data = NULL;
123-	be->shm_size = 0;
124+		be->buffers[i].buffer = NULL;
125+		be->buffers[i].data = NULL;
126+		be->buffers[i].size = 0;
127+		be->buffers[i].busy = 0;
128+	}
129 	mw->fb = NULL;
130 }
131 
132@@ -767,11 +809,7 @@ void maus_close(Maus* mw)
133 
134 	be = &mw->backend;
135 
136-	if (be->buffer)
137-		wl_buffer_destroy(be->buffer);
138-
139-	if (be->shm_data && be->shm_size > 0)
140-		munmap(be->shm_data, be->shm_size);
141+	fb_destroy(mw);
142 
143 	if (be->xdg_toplevel)
144 		xdg_toplevel_destroy(be->xdg_toplevel);
145@@ -842,9 +880,6 @@ int8_t maus_close_window(Maus* mw)
146 	if (be->surface)
147 		wl_surface_destroy(be->surface);
148 
149-	be->buffer = NULL;
150-	be->shm_data = NULL;
151-	be->shm_size = 0;
152 	be->xdg_toplevel = NULL;
153 	be->xdg_surface = NULL;
154 	be->surface = NULL;
155@@ -1000,15 +1035,27 @@ void maus_event_wait(Maus* mw, MausEvent* ev)
156 void maus_present(Maus* mw)
157 {
158 	MausBackend* be = &mw->backend;
159+	MausWLBuffer* wb = NULL;
160 	size_t bytes;
161 
162-	if (!be->buffer)
163+	uint32_t i;
164+
165+	for (i = 0; i < 2; i++) {
166+		if (be->buffers[i].buffer && !be->buffers[i].busy) {
167+			wb = &be->buffers[i];
168+			break;
169+		}
170+	}
171+
172+	if (!wb)
173 		return;
174 
175 	bytes = mw->stride * mw->height * sizeof(uint32_t);
176-	memcpy(be->shm_data, mw->bfb, bytes);
177+	memcpy(wb->data, mw->bfb, bytes);
178+	mw->fb = wb->data;
179+	wb->busy = 1;
180 
181-	wl_surface_attach(be->surface, be->buffer, 0, 0);
182+	wl_surface_attach(be->surface, wb->buffer, 0, 0);
183 	wl_surface_damage_buffer(be->surface, 0, 0, mw->width, mw->height);
184 	wl_surface_commit(be->surface);
185 	wl_display_flush(be->display);