commit e33c1df

uint  ·  2026-08-03 18:24:41 +0000 UTC
parent 2f8879e
Wayland: created window, dispatch MAUS_EV_NONE events, create framebuffer
2 files changed,  +157, -9
+17, -1
 1@@ -1,19 +1,35 @@
 2 #ifndef MAUS_WAYLAND_H
 3 #define MAUS_WAYLAND_H
 4 
 5+#include <stddef.h>
 6+#include <stdint.h>
 7+
 8 /* must forward declare so that other
 9    ANSI abiding files arent affected */
10 struct wl_display;
11+struct wl_buffer;
12 struct wl_registry;
13 struct wl_compositor;
14+struct wl_surface;
15 struct wl_shm;
16+
17 struct xdg_wm_base;
18+struct xdg_surface;
19+struct xdg_toplevel;
20 
21 typedef struct {
22 	struct wl_display*    display;
23+	struct wl_buffer*     buffer;
24 	struct wl_compositor* compositor;
25+	struct wl_surface*    surface;
26 	struct wl_shm*        shm;
27-	struct xdg_wm_base*   wm_base;
28+	void*                 shm_data;
29+	size_t                shm_size;
30+
31+	struct xdg_wm_base*  wm_base;
32+	struct xdg_surface*  xdg_surface;
33+	struct xdg_toplevel* xdg_toplevel;
34+	int8_t               configured;
35 
36 	struct wl_registry*          registry;
37 } MausBackend;
+140, -8
  1@@ -1,5 +1,8 @@
  2+#include <fcntl.h>
  3 #include <stdlib.h>
  4 #include <string.h>
  5+#include <sys/mman.h>
  6+#include <unistd.h>
  7 
  8 #include <wayland-client.h>
  9 #include <xdg-shell-client-protocol.h>
 10@@ -7,15 +10,33 @@
 11 #include "maus.h"
 12 #include "maus_wayland.h"
 13 
 14+static void registry_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name);
 15+static void xdg_surface_configure(void* data, struct xdg_surface* xdg_surface, uint32_t serial);
 16+static void wm_base_ping(void* data, struct xdg_wm_base* wm_base, uint32_t serial);
 17 static void registry_global(void* data, struct wl_registry* registry,
 18                             uint32_t name, const char* interface,
 19                             uint32_t version);
 20-static void registry_global_remove(void *data, struct wl_registry *wl_registry,
 21-                          uint32_t name);
 22+static struct wl_registry_listener registry_listener = { registry_global, registry_global_remove };
 23+static struct xdg_surface_listener xdg_surface_listener = { xdg_surface_configure };
 24+static struct xdg_wm_base_listener xdg_wm_base_listener = { wm_base_ping };
 25 
 26-static struct wl_registry_listener registry_listener = {
 27-	registry_global, registry_global_remove
 28-};
 29+static void registry_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name)
 30+{
 31+
 32+}
 33+
 34+static void xdg_surface_configure(void* data, struct xdg_surface* xdg_surface, uint32_t serial)
 35+{
 36+	Maus* mw = data;
 37+	xdg_surface_ack_configure(xdg_surface, serial);
 38+	mw->backend.configured = 1;
 39+}
 40+
 41+static void wm_base_ping(void* data, struct xdg_wm_base* wm_base, uint32_t serial)
 42+{
 43+	(void)data;
 44+	xdg_wm_base_pong(wm_base, serial);
 45+}
 46 
 47 static void registry_global(void* data, struct wl_registry* registry,
 48                             uint32_t name, const char* interface,
 49@@ -32,12 +53,80 @@ static void registry_global(void* data, struct wl_registry* registry,
 50 		be->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
 51 	else if (strcmp(interface, xdg_wm_base_interface.name) == 0)
 52 		be->wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
 53+	else if (strcmp(interface, xdg_wm_base_interface.name) == 0) {
 54+		be->wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
 55+		xdg_wm_base_add_listener(be->wm_base, &xdg_wm_base_listener, mw);
 56+	}
 57 }
 58 
 59-static void registry_global_remove(void *data, struct wl_registry *wl_registry,
 60-                          uint32_t name)
 61+
 62+
 63+
 64+static int8_t fb_create(Maus* mw);
 65+static int8_t fb_create_shm(size_t size);
 66+
 67+static int8_t fb_create(Maus* mw)
 68 {
 69+	MausBackend* be = &mw->backend;
 70+	struct wl_shm_pool* pool;
 71+
 72+	int fd;
 73+	int stride;
 74+	int size;
 75+
 76+	stride = mw->width * 4;
 77+	size = stride * mw->height;
 78+
 79+	fd = fb_create_shm(size);
 80+	if (fd < 0)
 81+		return 0;
 82+
 83+	be->shm_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 84+	if (be->shm_data == MAP_FAILED) {
 85+		close(fd);
 86+		return 0;
 87+	}
 88+
 89+	pool = wl_shm_create_pool(be->shm, fd, size);
 90+	be->buffer = wl_shm_pool_create_buffer(
 91+		pool, 0, mw->width, mw->height,
 92+		stride, WL_SHM_FORMAT_XRGB8888
 93+	);
 94+
 95+	wl_shm_pool_destroy(pool);
 96+	close(fd);
 97+
 98+	be->shm_size = size;
 99+	mw->fb = be->shm_data;
100+	mw->stride = mw->width;
101 
102+	return 1;
103+}
104+
105+static int8_t fb_create_shm(size_t size)
106+{
107+	char name[64];
108+	int fd;
109+
110+	int i;
111+
112+	for (i = 0; i < 100; i++) {
113+		snprintf(name, sizeof(name), "/maus-%ld-%d", (long)getpid(), i);
114+
115+		fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
116+		if (fd >= 0) {
117+			shm_unlink(name);
118+
119+			if (ftruncate(fd, size) < 0) {
120+				close(fd);
121+				return -1;
122+			}
123+
124+			return fd;
125+		}
126+	}
127+
128+	return -1;
129 }
130 
131 void maus_clear(Maus* mw, MausColor col)
132@@ -67,7 +156,35 @@ int8_t maus_close_window(Maus* mw)
133 
134 int8_t maus_create_window(Maus* mw)
135 {
136+	MausBackend* be = &mw->backend;
137+
138+	be->surface = wl_compositor_create_surface(be->compositor);
139+	if (!be->surface)
140+		return 0;
141 
142+	be->xdg_surface = xdg_wm_base_get_xdg_surface(be->wm_base, be->surface);
143+	if (!be->xdg_surface)
144+		return 0;
145+
146+	xdg_surface_add_listener(be->xdg_surface, &xdg_surface_listener, mw);
147+
148+	be->xdg_toplevel = xdg_surface_get_toplevel(be->xdg_surface);
149+	if (!be->xdg_toplevel)
150+		return 0;
151+
152+	xdg_toplevel_set_title(be->xdg_toplevel, mw->title);
153+
154+	if (!fb_create(mw))
155+		return 0;
156+
157+	wl_surface_commit(be->surface);
158+
159+	while (!be->configured) {
160+		if (wl_display_dispatch(be->display) == -1)
161+			return 0;
162+	}
163+
164+	return 1;
165 }
166 
167 Maus* maus_init(const char* title, int x, int y, int width, int height)
168@@ -114,7 +231,10 @@ Maus* maus_init(const char* title, int x, int y, int width, int height)
169 
170 int8_t maus_event_poll(Maus* mw, MausEvent* ev)
171 {
172-
173+	ev->type = MAUS_EV_NONE;
174+	wl_display_dispatch_pending(mw->backend.display);
175+	wl_display_flush(mw->backend.display);
176+	return 0;
177 }
178 
179 void maus_event_wait(Maus* mw, MausEvent* ev)
180@@ -124,7 +244,19 @@ void maus_event_wait(Maus* mw, MausEvent* ev)
181 
182 void maus_present(Maus* mw)
183 {
184+	MausBackend* be = &mw->backend;
185+	size_t bytes;
186+
187+	if (!be->buffer)
188+		return;
189+
190+	bytes = mw->stride * mw->height * sizeof(uint32_t);
191+	memcpy(be->shm_data, mw->bfb, bytes);
192 
193+	wl_surface_attach(be->surface, be->buffer, 0, 0);
194+	wl_surface_damage_buffer(be->surface, 0, 0, mw->width, mw->height);
195+	wl_surface_commit(be->surface);
196+	wl_display_flush(be->display);
197 }
198 
199 int8_t maus_resize(Maus* mw, uint32_t width, uint32_t height)