+++ /dev/null
-#include <assert.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-
-#include <wayland-server.h>
-#include <libds/log.h>
-#include <libds/backend.h>
-#include <libds/allocator/shm.h>
-#include <libds/backend/wayland.h>
-#include <libds/swapchain.h>
-#include <libds/compositor.h>
-
-#define WIDTH 700
-#define HEIGHT 400
-
-struct server
-{
- struct ds_backend *backend;
- struct ds_output *output;
- struct ds_allocator *allocator;
- struct ds_swapchain *swapchain;
- struct ds_buffer *front_buffer;
-
- struct wl_display *display;
-
- struct {
- struct wl_listener output_destroy;
- struct wl_listener output_frame;
- } listener;
-
- int width, height;
-};
-
-struct server _server;
-
-static void init_server(struct server *server, struct wl_display *display);
-static void fini_server(struct server *server);
-static void output_handle_destroy(struct wl_listener *listener, void *data);
-static void output_handle_frame(struct wl_listener *listener, void *data);
-static void draw_output(struct server *server);
-
-int
-main(void)
-{
- struct server *server = &_server;
- struct wl_display *display;
-
- ds_log_init(DS_DBG, NULL);
-
- display = wl_display_create();
- assert(display);
-
- server->width = WIDTH;
- server->height = HEIGHT;
-
- init_server(server, display);
-
- server->listener.output_destroy.notify = output_handle_destroy;
- ds_output_add_destroy_listener(server->output,
- &server->listener.output_destroy);
-
- server->listener.output_frame.notify = output_handle_frame;
- ds_output_add_frame_listener(server->output,
- &server->listener.output_frame);
-
- ds_backend_start(server->backend);
-
- draw_output(server);
-
- wl_display_run(server->display);
-
- fini_server(server);
- wl_display_destroy(display);
- return 0;
-}
-
-static struct ds_backend *
-create_backend_auto(struct wl_display *display)
-{
- struct ds_backend *backend = NULL;
- char name[512];
- int i;
-
- for (i = 0; i < 5; i++) {
- snprintf(name, sizeof name, "wayland-%d", i);
- backend = ds_wl_backend_create(display, name);
- if (backend)
- break;
- }
-
- return backend;
-}
-
-static void
-init_server(struct server *server, struct wl_display *display)
-{
- server->display = display;
-
- server->backend = create_backend_auto(display);
- assert(server->backend);
-
- server->allocator = ds_shm_allocator_create();
- assert(server->allocator);
-
- server->swapchain = ds_swapchain_create(server->allocator,
- server->width, server->height, WL_SHM_FORMAT_XRGB8888);
- assert(server->swapchain);
-
- server->output =
- ds_wl_backend_create_output(server->backend);
- assert(server->output);
-}
-
-static void
-fini_server(struct server *server)
-{
- ds_buffer_unlock(server->front_buffer);
- ds_swapchain_destroy(server->swapchain);
- ds_allocator_destroy(server->allocator);
-}
-
-static void
-paint_pixels(void *image, int padding, int width, int height, uint32_t time)
-{
- const int halfh = padding + (height - padding * 2) / 2;
- const int halfw = padding + (width - padding * 2) / 2;
- int ir, or;
- uint32_t *pixel = image;
- int y;
-
- /* squared radii thresholds */
- or = (halfw < halfh ? halfw : halfh) - 8;
- ir = or - 32;
- or *= or;
- ir *= ir;
-
- pixel += padding * width;
- for (y = padding; y < height - padding; y++) {
- int x;
- int y2 = (y - halfh) * (y - halfh);
-
- pixel += padding;
- for (x = padding; x < width - padding; x++) {
- uint32_t v;
-
- /* squared distance from center */
- int r2 = (x - halfw) * (x - halfw) + y2;
-
- if (r2 < ir)
- v = (r2 / 32 + time / 64) * 0x0080401;
- else if (r2 < or)
- v = (y + time / 32) * 0x0080401;
- else
- v = (x + time / 16) * 0x0080401;
- v &= 0x00ffffff;
-
- /* cross if compositor uses X from XRGB as alpha */
- if (abs(x - y) > 6 && abs(x + y - height) > 6)
- v |= 0xff000000;
-
- *pixel++ = v;
- }
-
- pixel += padding;
- }
-}
-
-static inline int64_t
-timespec_to_msec(const struct timespec *a)
-{
- return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000;
-}
-
-static void
-output_handle_destroy(struct wl_listener *listener,
- void *data __attribute__((unused)))
-{
- struct server *server =
- wl_container_of(listener, server, listener.output_destroy);
- wl_display_terminate(server->display);
-}
-
-static void
-output_handle_frame(struct wl_listener *listener,
- void *data __attribute__((unused)))
-{
- struct server *server =
- wl_container_of(listener, server, listener.output_frame);
- draw_output(server);
-}
-
-static void
-draw_output(struct server *server)
-{
- struct ds_buffer *buffer;
- void *data;
- uint32_t format;
- size_t stride;
- struct timespec now;
- uint32_t frame_time_msec;
-
- ds_dbg("Redraw output");
-
- clock_gettime(CLOCK_MONOTONIC, &now);
- frame_time_msec = timespec_to_msec(&now);
-
- buffer = ds_swapchain_acquire(server->swapchain, NULL);
- assert(buffer);
-
- assert(ds_buffer_begin_data_ptr_access(buffer,
- 0, &data, &format, &stride) == true);
-
- paint_pixels(data, 20, server->width, server->height, frame_time_msec);
-
- ds_buffer_end_data_ptr_access(buffer);
-
- ds_output_attach_buffer(server->output, buffer);
- ds_output_commit(server->output);
-
- if (server->front_buffer)
- ds_buffer_unlock(server->front_buffer);
-
- server->front_buffer = buffer;
-}