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