| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- #include "ark_wayland_client.h"
- #include <wayland-client.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/mman.h>
- static struct wl_display *display = NULL;
- static struct wl_registry *registry = NULL;
- static struct wl_compositor *compositor = NULL;
- static struct wl_shm *shm = NULL;
- static struct wl_surface *surface = NULL;
- static struct wl_buffer *buffer = NULL;
- static uint8_t *shm_data = NULL;
- static int shm_size = 0;
- static void registry_handler(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) {
- if (strcmp(interface, "wl_compositor") == 0) {
- compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 1);
- } else if (strcmp(interface, "wl_shm") == 0) {
- shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
- }
- }
- static void registry_remover(void *data, struct wl_registry *registry, uint32_t id) {
- // Handling removals not strictly needed for this simple client
- }
- static const struct wl_registry_listener registry_listener = {
- registry_handler,
- registry_remover
- };
- bool ark_wayland_client_init(void) {
- display = wl_display_connect(NULL);
- if (!display) {
- fprintf(stderr, "ArkGraphics (Client): Failed to connect to Wayland display\n");
- return false;
- }
-
- registry = wl_display_get_registry(display);
- wl_registry_add_listener(registry, ®istry_listener, NULL);
-
- // Wait for globals
- wl_display_roundtrip(display);
-
- if (!compositor || !shm) {
- fprintf(stderr, "ArkGraphics (Client): Compositor or SHM interface not found on Wayland server\n");
- return false;
- }
-
- printf("ArkGraphics (Client): Connected to Wayland Server\n");
- return true;
- }
- void ark_wayland_client_shutdown(void) {
- if (buffer) wl_buffer_destroy(buffer);
- if (surface) wl_surface_destroy(surface);
- if (shm_data) munmap(shm_data, shm_size);
-
- if (shm) wl_shm_destroy(shm);
- if (compositor) wl_compositor_destroy(compositor);
- if (registry) wl_registry_destroy(registry);
- if (display) wl_display_disconnect(display);
- }
- // OS helper for memfd create (if syscall not wrapped by libc, we can just use memfd_create)
- #include <sys/syscall.h>
- #include <linux/memfd.h>
- static int os_create_anonymous_file(off_t size) {
- int fd = syscall(SYS_memfd_create, "ark_wayland_shm", MFD_CLOEXEC);
- if (fd < 0) return -1;
- if (ftruncate(fd, size) < 0) {
- close(fd);
- return -1;
- }
- return fd;
- }
- uint8_t* ark_wayland_client_create_surface(int width, int height) {
- if (!compositor || !shm) return NULL;
-
- surface = wl_compositor_create_surface(compositor);
- if (!surface) return NULL;
-
- int stride = width * 4; // 4 bytes per pixel (ARGB8888)
- shm_size = stride * height;
-
- int fd = os_create_anonymous_file(shm_size);
- if (fd < 0) {
- fprintf(stderr, "ArkGraphics (Client): Failed to create SHM file\n");
- return NULL;
- }
-
- shm_data = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (shm_data == MAP_FAILED) {
- close(fd);
- return NULL;
- }
-
- struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, shm_size);
- buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888);
- wl_shm_pool_destroy(pool); // Pool object can be destroyed once buffer is created
-
- close(fd); // Wayland server keeps the fd open internally
-
- return shm_data;
- }
- void ark_wayland_client_commit(void) {
- if (!surface || !buffer) return;
-
- // Attach the buffer to the surface
- wl_surface_attach(surface, buffer, 0, 0);
- // Mark the entire surface as damaged so the compositor redraws it
- wl_surface_damage(surface, 0, 0, INT32_MAX, INT32_MAX);
- // Commit the surface state
- wl_surface_commit(surface);
-
- // Flush the display to ensure messages are sent
- wl_display_flush(display);
- }
|