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)