#include #include #include #include #include #include #include "xdg-shell-client-protocol.h" static struct wl_display *display; static struct wl_registry *registry; static struct wl_compositor *compositor; static struct wl_shm *shm; static struct xdg_wm_base *xdg_wm_base; static struct wl_surface *surface; static struct xdg_surface *xdg_surface; static struct xdg_toplevel *xdg_toplevel; static volatile int running = 1; static int width = 800, height = 600; static void registry_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { if (strcmp(interface, "wl_compositor") == 0) { compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1); } else if (strcmp(interface, "wl_shm") == 0) { shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); } else if (strcmp(interface, "xdg_wm_base") == 0) { xdg_wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1); } } static void registry_global_remove(void *data, struct wl_registry *registry, uint32_t name) {} static const struct wl_registry_listener registry_listener = { .global = registry_global, .global_remove = registry_global_remove, }; static void create_buffer(); static void xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial) { xdg_surface_ack_configure(xdg_surface, serial); create_buffer(); } static const struct xdg_surface_listener xdg_surface_listener = { .configure = xdg_surface_configure, }; static void xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, int32_t w, int32_t h, struct wl_array *states) { if (w > 0) width = w; if (h > 0) height = h; } static void xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel) { running = 0; } static const struct xdg_toplevel_listener xdg_toplevel_listener = { .configure = xdg_toplevel_configure, .close = xdg_toplevel_close, }; static void create_buffer() { char name[32]; sprintf(name, "/wayland-shm-%d", getpid()); int stride = width * 4; int size = stride * height; int fd = shm_open(name, O_RDWR | O_CREAT, 0600); if (fd == -1) return; ftruncate(fd, size); void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); memset(data, 0xFF, size); // white struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size); struct wl_buffer *buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); wl_surface_attach(surface, buffer, 0, 0); wl_surface_damage(surface, 0, 0, width, height); wl_surface_commit(surface); wl_buffer_destroy(buffer); wl_shm_pool_destroy(pool); close(fd); shm_unlink(name); munmap(data, size); } void run_wayland() { display = wl_display_connect(NULL); if (!display) return; registry = wl_display_get_registry(display); wl_registry_add_listener(registry, ®istry_listener, NULL); wl_display_dispatch(display); wl_display_roundtrip(display); if (!compositor || !shm || !xdg_wm_base) return; surface = wl_compositor_create_surface(compositor); xdg_surface = xdg_wm_base_get_xdg_surface(xdg_wm_base, surface); xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, NULL); xdg_toplevel = xdg_surface_get_toplevel(xdg_surface); xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL); wl_surface_commit(surface); while (running && wl_display_dispatch(display) != -1) {} wl_display_disconnect(display); }