commit e91f3ae17b8994a92566413d0a8a0c19912957e9
parent a3764b4ccd67c4e0625e42917f0cbf159a51b746
Author: Luke Willis <lukejw@loquat.dev>
Date: Mon, 30 Mar 2026 00:37:24 -0400
Refactor a little and get a better mental grip on buffers
Diffstat:
| M | src/main.c | | | 68 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++------------- |
1 file changed, 55 insertions(+), 13 deletions(-)
diff --git a/src/main.c b/src/main.c
@@ -10,11 +10,21 @@
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
struct wig_window {
+ int configured;
+
char* label;
+ uint32_t width;
+ uint32_t height;
+
+ struct wl_shm* shm;
+
+ struct wl_buffer* wl_buffer;
+ int wl_buffer_released;
+
struct wl_surface* wl_surface;
struct zwlr_layer_surface_v1* wlr_layer_surface;
- struct wl_shm* shm;
+ uint32_t* data;
};
struct wig_state {
@@ -33,30 +43,35 @@ struct wig_state {
*/
static void wl_buffer_release(void* data, struct wl_buffer* wl_buffer) {
- wl_buffer_destroy(wl_buffer);
+ struct wig_window* window = data;
+ window->wl_buffer_released = 1;
}
static const struct wl_buffer_listener wl_buffer_listener = {
.release = wl_buffer_release,
};
-static struct wl_buffer* draw_frame(struct wig_window* state, int width,
- int height) {
+int reconfigure_window(struct wig_window* window, int width, int height) {
+ if (window->data != NULL) {
+ wl_buffer_destroy(window->wl_buffer);
+ munmap(window->data, window->width * window->height * 4);
+ }
+
int stride = width * 4;
int size = stride * height;
int fd = allocate_shm_file(size);
if (fd == -1) {
- return NULL;
+ return 0;
}
uint32_t* data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (data == MAP_FAILED) {
close(fd);
- return NULL;
+ return 0;
}
- struct wl_shm_pool* pool = wl_shm_create_pool(state->shm, fd, size);
+ struct wl_shm_pool* pool = wl_shm_create_pool(window->shm, fd, size);
struct wl_buffer* buffer = wl_shm_pool_create_buffer(
pool, 0, width, height, stride, WL_SHM_FORMAT_XRGB8888);
wl_shm_pool_destroy(pool);
@@ -71,10 +86,13 @@ static struct wl_buffer* draw_frame(struct wig_window* state, int width,
data[y * width + x] = 0xFFEEEEEE;
}
}
+ wl_buffer_add_listener(buffer, &wl_buffer_listener, window);
+
+ window->data = data;
+ window->wl_buffer = buffer;
+ window->configured = 1;
- munmap(data, size);
- wl_buffer_add_listener(buffer, &wl_buffer_listener, NULL);
- return buffer;
+ return 0;
}
/*
@@ -87,9 +105,22 @@ static void zwlr_layer_surface_configure(
struct wig_window* window = data;
zwlr_layer_surface_v1_ack_configure(zwlr_layer_surface_v1, serial);
- struct wl_buffer* buffer = draw_frame(window, width, height);
- wl_surface_attach(window->wl_surface, buffer, 0, 0);
+ /* Skip reconfiguration if the size hasn't changed */
+ if (width == window->width && height == window->height) return;
+
+ int result = reconfigure_window(window, width, height);
+
+ if (result) {
+ fprintf(stderr, "Failed to reconfigure \"%s\"", window->label);
+ return;
+ }
+
+ wl_surface_attach(window->wl_surface, window->wl_buffer, 0, 0);
wl_surface_commit(window->wl_surface);
+ window->wl_buffer_released = 0;
+
+ window->width = width;
+ window->height = height;
fprintf(stderr, "\"%s\" reconfigured\n", window->label);
fprintf(stderr, " %u x %u\n", width, height);
@@ -179,8 +210,12 @@ static void inner_main(void* data, int argc, char** argv) {
struct wig_window* window = &state->windows[i];
window->label = label;
+ window->width = width;
+ window->height = height;
+
window->shm = state->shm;
+ window->data = NULL;
window->wl_surface = wl_compositor_create_surface(state->compositor);
window->wlr_layer_surface = zwlr_layer_shell_v1_get_layer_surface(
state->layer_shell, window->wl_surface, NULL,
@@ -212,7 +247,14 @@ static void inner_main(void* data, int argc, char** argv) {
/* Loop */
while (wl_display_dispatch(state->display) != -1) {
- /* TODO */
+ for (size_t i = 0; i < num_windows; i++) {
+ state->windows[i].data[1] = 0xFFFF00FF;
+
+ wl_surface_attach(state->windows[i].wl_surface,
+ state->windows[i].wl_buffer, 0, 0);
+ wl_surface_damage_buffer(state->windows[i].wl_surface, 1, 0, 1, 1);
+ wl_surface_commit(state->windows[i].wl_surface);
+ }
}
/* Cleanup */