ark_wayland_server.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include "ark_wayland_server.h"
  2. #include <wayland-server.h>
  3. #include <wayland-server-protocol.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. static struct wl_display *display = NULL;
  8. static struct wl_event_loop *event_loop = NULL;
  9. static uint8_t* g_render_buffer = NULL;
  10. static int g_width = 1920;
  11. static int g_height = 1080;
  12. static int g_bpp = 4;
  13. struct ark_surface {
  14. struct wl_resource *resource;
  15. struct wl_resource *pending_buffer;
  16. };
  17. // Surface interface implementations
  18. static void surface_destroy(struct wl_client *client, struct wl_resource *resource) {
  19. wl_resource_destroy(resource);
  20. }
  21. static void surface_attach(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer, int32_t x, int32_t y) {
  22. struct ark_surface *surface = wl_resource_get_user_data(resource);
  23. surface->pending_buffer = buffer;
  24. }
  25. static void surface_damage(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) {
  26. // Basic implementation ignores partial damage and redraws all
  27. }
  28. static void surface_frame(struct wl_client *client, struct wl_resource *resource, uint32_t callback) {
  29. // Send frame event immediately for now (60fps limit handled by client or main loop)
  30. struct wl_resource *cb_resource = wl_resource_create(client, &wl_callback_interface, 1, callback);
  31. wl_callback_send_done(cb_resource, 0);
  32. wl_resource_destroy(cb_resource);
  33. }
  34. static void surface_set_opaque_region(struct wl_client *client, struct wl_resource *resource, struct wl_resource *region) {}
  35. static void surface_set_input_region(struct wl_client *client, struct wl_resource *resource, struct wl_resource *region) {}
  36. static void surface_commit(struct wl_client *client, struct wl_resource *resource) {
  37. struct ark_surface *surface = wl_resource_get_user_data(resource);
  38. if (surface->pending_buffer && g_render_buffer) {
  39. struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get(surface->pending_buffer);
  40. if (shm_buffer) {
  41. wl_shm_buffer_begin_access(shm_buffer);
  42. void *data = wl_shm_buffer_get_data(shm_buffer);
  43. int stride = wl_shm_buffer_get_stride(shm_buffer);
  44. int height = wl_shm_buffer_get_height(shm_buffer);
  45. int width = wl_shm_buffer_get_width(shm_buffer);
  46. // Copy buffer to global render buffer
  47. int max_y = (height < g_height) ? height : g_height;
  48. int max_bytes = (stride < g_width * g_bpp) ? stride : g_width * g_bpp;
  49. for (int y = 0; y < max_y; y++) {
  50. memcpy(g_render_buffer + (y * g_width * g_bpp),
  51. ((uint8_t*)data) + (y * stride),
  52. max_bytes);
  53. }
  54. wl_shm_buffer_end_access(shm_buffer);
  55. // Send release event to client
  56. wl_buffer_send_release(surface->pending_buffer);
  57. surface->pending_buffer = NULL;
  58. }
  59. }
  60. }
  61. static void surface_set_buffer_transform(struct wl_client *client, struct wl_resource *resource, int32_t transform) {}
  62. static void surface_set_buffer_scale(struct wl_client *client, struct wl_resource *resource, int32_t scale) {}
  63. 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) {}
  64. static const struct wl_surface_interface surface_implementation = {
  65. surface_destroy,
  66. surface_attach,
  67. surface_damage,
  68. surface_frame,
  69. surface_set_opaque_region,
  70. surface_set_input_region,
  71. surface_commit,
  72. surface_set_buffer_transform,
  73. surface_set_buffer_scale,
  74. surface_damage_buffer
  75. };
  76. static void destroy_surface(struct wl_resource *resource) {
  77. struct ark_surface *surface = wl_resource_get_user_data(resource);
  78. free(surface);
  79. }
  80. // Compositor interface implementations
  81. static void compositor_create_surface(struct wl_client *client, struct wl_resource *resource, uint32_t id) {
  82. struct ark_surface *surface = calloc(1, sizeof(struct ark_surface));
  83. surface->resource = wl_resource_create(client, &wl_surface_interface, 4, id);
  84. wl_resource_set_implementation(surface->resource, &surface_implementation, surface, destroy_surface);
  85. }
  86. static void compositor_create_region(struct wl_client *client, struct wl_resource *resource, uint32_t id) {
  87. // Regions are not fully supported yet in minimal server
  88. }
  89. static const struct wl_compositor_interface compositor_implementation = {
  90. compositor_create_surface,
  91. compositor_create_region
  92. };
  93. static void bind_compositor(struct wl_client *client, void *data, uint32_t version, uint32_t id) {
  94. struct wl_resource *resource = wl_resource_create(client, &wl_compositor_interface, version, id);
  95. wl_resource_set_implementation(resource, &compositor_implementation, NULL, NULL);
  96. }
  97. void ark_compositor_set_render_buffer(uint8_t* buffer, int width, int height, int bpp) {
  98. g_render_buffer = buffer;
  99. g_width = width;
  100. g_height = height;
  101. g_bpp = bpp;
  102. }
  103. bool ark_compositor_init(void) {
  104. display = wl_display_create();
  105. if (!display) {
  106. fprintf(stderr, "ArkCompositor: Failed to create Wayland display\n");
  107. return false;
  108. }
  109. event_loop = wl_display_get_event_loop(display);
  110. // Initialize SHM (shared memory)
  111. wl_display_init_shm(display);
  112. // Initialize Compositor
  113. wl_global_create(display, &wl_compositor_interface, 4, display, bind_compositor);
  114. // Add socket (this will usually bind to wayland-0)
  115. const char *socket = wl_display_add_socket_auto(display);
  116. if (!socket) {
  117. fprintf(stderr, "ArkCompositor: Failed to add socket\n");
  118. wl_display_destroy(display);
  119. display = NULL;
  120. return false;
  121. }
  122. printf("ArkCompositor: Wayland server listening on socket '%s'\n", socket);
  123. return true;
  124. }
  125. void ark_compositor_dispatch(void) {
  126. if (display && event_loop) {
  127. wl_display_flush_clients(display);
  128. wl_event_loop_dispatch(event_loop, 0); // Non-blocking dispatch
  129. }
  130. }
  131. void ark_compositor_shutdown(void) {
  132. if (display) {
  133. wl_display_destroy(display);
  134. display = NULL;
  135. event_loop = NULL;
  136. }
  137. }