| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- #include "ark_wayland_server.h"
- #include <wayland-server.h>
- #include <wayland-server-protocol.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- static struct wl_display *display = NULL;
- static struct wl_event_loop *event_loop = NULL;
- static uint8_t* g_render_buffer = NULL;
- static int g_width = 1920;
- static int g_height = 1080;
- static int g_bpp = 4;
- struct ark_surface {
- struct wl_resource *resource;
- struct wl_resource *pending_buffer;
- };
- // Surface interface implementations
- static void surface_destroy(struct wl_client *client, struct wl_resource *resource) {
- wl_resource_destroy(resource);
- }
- static void surface_attach(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer, int32_t x, int32_t y) {
- struct ark_surface *surface = wl_resource_get_user_data(resource);
- surface->pending_buffer = buffer;
- }
- static void surface_damage(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) {
- // Basic implementation ignores partial damage and redraws all
- }
- static void surface_frame(struct wl_client *client, struct wl_resource *resource, uint32_t callback) {
- // Send frame event immediately for now (60fps limit handled by client or main loop)
- struct wl_resource *cb_resource = wl_resource_create(client, &wl_callback_interface, 1, callback);
- wl_callback_send_done(cb_resource, 0);
- wl_resource_destroy(cb_resource);
- }
- static void surface_set_opaque_region(struct wl_client *client, struct wl_resource *resource, struct wl_resource *region) {}
- static void surface_set_input_region(struct wl_client *client, struct wl_resource *resource, struct wl_resource *region) {}
- static void surface_commit(struct wl_client *client, struct wl_resource *resource) {
- struct ark_surface *surface = wl_resource_get_user_data(resource);
-
- if (surface->pending_buffer && g_render_buffer) {
- struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get(surface->pending_buffer);
- if (shm_buffer) {
- wl_shm_buffer_begin_access(shm_buffer);
- void *data = wl_shm_buffer_get_data(shm_buffer);
- int stride = wl_shm_buffer_get_stride(shm_buffer);
- int height = wl_shm_buffer_get_height(shm_buffer);
- int width = wl_shm_buffer_get_width(shm_buffer);
-
- // Copy buffer to global render buffer
- int max_y = (height < g_height) ? height : g_height;
- int max_bytes = (stride < g_width * g_bpp) ? stride : g_width * g_bpp;
-
- for (int y = 0; y < max_y; y++) {
- memcpy(g_render_buffer + (y * g_width * g_bpp),
- ((uint8_t*)data) + (y * stride),
- max_bytes);
- }
-
- wl_shm_buffer_end_access(shm_buffer);
-
- // Send release event to client
- wl_buffer_send_release(surface->pending_buffer);
- surface->pending_buffer = NULL;
- }
- }
- }
- static void surface_set_buffer_transform(struct wl_client *client, struct wl_resource *resource, int32_t transform) {}
- static void surface_set_buffer_scale(struct wl_client *client, struct wl_resource *resource, int32_t scale) {}
- static void surface_damage_buffer(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) {}
- static const struct wl_surface_interface surface_implementation = {
- surface_destroy,
- surface_attach,
- surface_damage,
- surface_frame,
- surface_set_opaque_region,
- surface_set_input_region,
- surface_commit,
- surface_set_buffer_transform,
- surface_set_buffer_scale,
- surface_damage_buffer
- };
- static void destroy_surface(struct wl_resource *resource) {
- struct ark_surface *surface = wl_resource_get_user_data(resource);
- free(surface);
- }
- // Compositor interface implementations
- static void compositor_create_surface(struct wl_client *client, struct wl_resource *resource, uint32_t id) {
- struct ark_surface *surface = calloc(1, sizeof(struct ark_surface));
- surface->resource = wl_resource_create(client, &wl_surface_interface, 4, id);
- wl_resource_set_implementation(surface->resource, &surface_implementation, surface, destroy_surface);
- }
- static void compositor_create_region(struct wl_client *client, struct wl_resource *resource, uint32_t id) {
- // Regions are not fully supported yet in minimal server
- }
- static const struct wl_compositor_interface compositor_implementation = {
- compositor_create_surface,
- compositor_create_region
- };
- static void bind_compositor(struct wl_client *client, void *data, uint32_t version, uint32_t id) {
- struct wl_resource *resource = wl_resource_create(client, &wl_compositor_interface, version, id);
- wl_resource_set_implementation(resource, &compositor_implementation, NULL, NULL);
- }
- void ark_compositor_set_render_buffer(uint8_t* buffer, int width, int height, int bpp) {
- g_render_buffer = buffer;
- g_width = width;
- g_height = height;
- g_bpp = bpp;
- }
- bool ark_compositor_init(void) {
- display = wl_display_create();
- if (!display) {
- fprintf(stderr, "ArkCompositor: Failed to create Wayland display\n");
- return false;
- }
-
- event_loop = wl_display_get_event_loop(display);
-
- // Initialize SHM (shared memory)
- wl_display_init_shm(display);
-
- // Initialize Compositor
- wl_global_create(display, &wl_compositor_interface, 4, display, bind_compositor);
-
- // Add socket (this will usually bind to wayland-0)
- const char *socket = wl_display_add_socket_auto(display);
- if (!socket) {
- fprintf(stderr, "ArkCompositor: Failed to add socket\n");
- wl_display_destroy(display);
- display = NULL;
- return false;
- }
-
- printf("ArkCompositor: Wayland server listening on socket '%s'\n", socket);
- return true;
- }
- void ark_compositor_dispatch(void) {
- if (display && event_loop) {
- wl_display_flush_clients(display);
- wl_event_loop_dispatch(event_loop, 0); // Non-blocking dispatch
- }
- }
- void ark_compositor_shutdown(void) {
- if (display) {
- wl_display_destroy(display);
- display = NULL;
- event_loop = NULL;
- }
- }
|