logo

bytemedia

Home to byte-level sounds, images, videos, … git clone https://hacktivis.me/git/bytemedia.git
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:

MC/wayland.c105+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
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; }