commit: 01765eace2b83bc543e23044352c92db39680f5a
parent 9c1752c94d7d19b5ddab770e29d7163ff1b2a731
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Mon, 22 Feb 2021 07:00:04 +0100
C/wayland: handle resizing and closing
Diffstat:
M | C/wayland.c | 105 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------ |
1 file changed, 73 insertions(+), 32 deletions(-)
diff --git a/C/wayland.c b/C/wayland.c
@@ -11,11 +11,6 @@
#include <unistd.h>
#include <wayland-client.h>
-#define WIDTH 800
-#define HEIGHT 800
-#define STRIDE WIDTH * 4
-#define SIZE STRIDE *HEIGHT
-
/* Shared memory support code */
static void
randname(char *buf)
@@ -75,8 +70,8 @@ struct client_state
struct wl_registry *wl_registry;
struct wl_compositor *wl_compositor;
struct xdg_wm_base *xdg_wm_base;
+ struct wl_shm *wl_shm;
struct wl_buffer *wl_buffer;
- int shm_fd;
uint32_t *shm_data;
/* Objects */
struct wl_surface *wl_surface;
@@ -85,6 +80,8 @@ struct client_state
/* State */
float offset;
uint32_t last_frame;
+ int width, height;
+ bool closed;
};
static void
@@ -92,9 +89,9 @@ draw_frame(struct client_state *state)
{
int t = (int)state->offset;
/* Let the fun begin! */
- for(int y = 0; y < HEIGHT; ++y)
+ for(int y = 0; y < state->height; ++y)
{
- for(int x = 0; x < WIDTH; ++x)
+ for(int x = 0; x < state->width; ++x)
{
//if (((x + offset) + (y + offset) / 8 * 8) % 16 < 8)
// data[y * WIDTH + x] = 0xFF666666;
@@ -102,10 +99,10 @@ draw_frame(struct client_state *state)
// data[y * WIDTH + x] = 0xFFEEEEEE;
// munching squares
- state->shm_data[y * WIDTH + x] = (x - t | y - t) + t << t % 16;
+ //state->shm_data[y * WIDTH + x] = (x - t | y - t) + t << t % 16;
//glichy munching squares
- //data[y * WIDTH + x] = (x|y)*t;
+ state->shm_data[y * state->width + x] = (x | y) * t;
// color enumeration
//data[y * WIDTH + x] = t*2|t*4<<8|t*8<<16;
@@ -114,6 +111,63 @@ draw_frame(struct client_state *state)
}
static void
+allocate_wl_shm_buffer(struct client_state *state)
+{
+ struct wl_shm_pool *pool;
+
+ int stride = state->width * 4;
+ int size = stride * state->height;
+
+ int shm_fd = allocate_shm_file(size);
+ if(shm_fd == -1)
+ {
+ return;
+ }
+
+ state->shm_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
+ if(state->shm_data == MAP_FAILED)
+ {
+ close(shm_fd);
+ return;
+ }
+
+ pool = wl_shm_create_pool(state->wl_shm, shm_fd, size);
+ state->wl_buffer = wl_shm_pool_create_buffer(
+ pool, 0, state->width, state->height, stride, WL_SHM_FORMAT_XRGB8888);
+ wl_shm_pool_destroy(pool);
+ close(shm_fd);
+}
+
+static void
+xdg_toplevel_configure(void *data,
+ struct xdg_toplevel *xdg_toplevel,
+ int32_t width,
+ int32_t height,
+ struct wl_array *states)
+{
+ struct client_state *state = data;
+ if(width != 0 && height != 0)
+ {
+ munmap(state->shm_data, state->width * state->height * 4);
+ state->width = width;
+ state->height = height;
+ allocate_wl_shm_buffer(state);
+ }
+}
+
+static void
+xdg_toplevel_close(void *data, struct xdg_toplevel *toplevel)
+{
+ struct client_state *state = data;
+ state->closed = true;
+}
+
+static const struct xdg_toplevel_listener xdg_toplevel_listener = {
+ .configure = xdg_toplevel_configure,
+ .close = xdg_toplevel_close,
+};
+
+static void
xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial)
{
struct client_state *state = data;
@@ -181,12 +235,8 @@ registry_global(void *data,
struct client_state *state = data;
if(strcmp(interface, wl_shm_interface.name) == 0)
{
- struct wl_shm *wl_shm = wl_registry_bind(wl_registry, name, &wl_shm_interface, 1);
- struct wl_shm_pool *pool = wl_shm_create_pool(wl_shm, state->shm_fd, SIZE);
- state->wl_buffer =
- wl_shm_pool_create_buffer(pool, 0, WIDTH, HEIGHT, STRIDE, WL_SHM_FORMAT_XRGB8888);
- wl_shm_pool_destroy(pool);
- close(state->shm_fd);
+ state->wl_shm = wl_registry_bind(wl_registry, name, &wl_shm_interface, 1);
+ allocate_wl_shm_buffer(state);
}
else if(strcmp(interface, wl_compositor_interface.name) == 0)
{
@@ -216,19 +266,9 @@ main(int argc, char *argv[])
struct client_state state = {0};
state.wl_display = wl_display_connect(NULL);
state.wl_registry = wl_display_get_registry(state.wl_display);
-
- state.shm_fd = allocate_shm_file(SIZE);
- if(state.shm_fd == -1)
- {
- return 1;
- }
-
- state.shm_data = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, state.shm_fd, 0);
- if(state.shm_data == MAP_FAILED)
- {
- close(state.shm_fd);
- return 1;
- }
+ state.width = 800;
+ state.height = 600;
+ state.closed = false;
wl_registry_add_listener(state.wl_registry, &wl_registry_listener, &state);
wl_display_roundtrip(state.wl_display);
@@ -237,18 +277,19 @@ main(int argc, char *argv[])
state.xdg_surface = xdg_wm_base_get_xdg_surface(state.xdg_wm_base, state.wl_surface);
xdg_surface_add_listener(state.xdg_surface, &xdg_surface_listener, &state);
state.xdg_toplevel = xdg_surface_get_toplevel(state.xdg_surface);
- xdg_toplevel_set_title(state.xdg_toplevel, "Example client");
+ xdg_toplevel_add_listener(state.xdg_toplevel, &xdg_toplevel_listener, &state);
+ xdg_toplevel_set_title(state.xdg_toplevel, "Bytemedia wayland");
wl_surface_commit(state.wl_surface);
struct wl_callback *cb = wl_surface_frame(state.wl_surface);
wl_callback_add_listener(cb, &wl_surface_frame_listener, &state);
- while(wl_display_dispatch(state.wl_display))
+ while(wl_display_dispatch(state.wl_display) && !state.closed)
{
/* This space deliberately left blank */
}
- munmap(state.shm_data, SIZE);
+ munmap(state.shm_data, state.width * state.height * 4);
return 0;
}