7 #include <wayland-server.h>
9 #include <libds/backend.h>
10 #include <libds/output.h>
11 #include <libds/swapchain.h>
12 #include <libds/compositor.h>
13 #include <libds-tizen/allocator/tbm.h>
14 #include <libds-tizen/backend/tdm.h>
21 struct ds_backend *backend;
22 struct ds_output *output;
23 struct ds_allocator *allocator;
24 struct ds_swapchain *swapchain;
25 struct ds_buffer *front_buffer;
27 struct wl_display *display;
28 struct wl_event_source *stdin_source;
30 struct wl_listener new_output;
31 struct wl_listener output_destroy;
32 struct wl_listener output_frame;
37 struct server _server;
39 static void init_server(struct server *server, struct wl_display *display);
40 static void fini_server(struct server *server);
41 static void output_handle_destroy(struct wl_listener *listener, void *data);
42 static void output_handle_frame(struct wl_listener *listener, void *data);
43 static void draw_output(struct server *server);
44 static int stdin_dispatch(int fd, uint32_t mask, void *data);
49 struct server *server = &_server;
50 struct wl_display *display;
52 ds_log_init(DS_DBG, NULL);
54 display = wl_display_create();
57 server->width = WIDTH;
58 server->height = HEIGHT;
60 init_server(server, display);
62 ds_backend_start(server->backend);
66 struct wl_event_loop *loop = wl_display_get_event_loop(display);
67 server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO,
68 WL_EVENT_READABLE, stdin_dispatch, server);
70 wl_display_run(display);
73 wl_display_destroy(display);
78 backend_handle_new_output(struct wl_listener *listener, void *data)
80 struct server *server;
81 struct ds_output *output;
83 server = wl_container_of(listener, server, new_output);
85 ds_inf("New output(%p)", output);
91 server->output = output;
93 server->output_destroy.notify = output_handle_destroy;
94 ds_output_add_destroy_listener(server->output,
95 &server->output_destroy);
97 server->output_frame.notify = output_handle_frame;
98 ds_output_add_frame_listener(server->output,
99 &server->output_frame);
103 init_server(struct server *server, struct wl_display *display)
105 server->display = display;
106 server->front_buffer = NULL;
108 server->backend = ds_tdm_backend_create(display);
109 assert(server->backend);
111 server->new_output.notify = backend_handle_new_output;
112 ds_backend_add_new_output_listener(server->backend,
113 &server->new_output);
115 server->allocator = ds_tbm_allocator_create();
116 assert(server->allocator);
118 server->swapchain = ds_swapchain_create(server->allocator,
119 server->width, server->height, WL_SHM_FORMAT_XRGB8888);
120 assert(server->swapchain);
124 fini_server(struct server *server)
126 wl_list_remove(&server->new_output.link);
127 wl_list_remove(&server->output_destroy.link);
128 wl_list_remove(&server->output_frame.link);
129 if (server->front_buffer)
130 ds_buffer_unlock(server->front_buffer);
131 ds_swapchain_destroy(server->swapchain);
132 ds_allocator_destroy(server->allocator);
136 output_handle_destroy(struct wl_listener *listener,
137 void *data __attribute__((unused)))
139 struct server *server =
140 wl_container_of(listener, server, output_destroy);
141 wl_display_terminate(server->display);
145 paint_pixels(void *image, int padding, int width, int height, uint32_t time)
147 const int halfh = padding + (height - padding * 2) / 2;
148 const int halfw = padding + (width - padding * 2) / 2;
150 uint32_t *pixel = image;
153 /* squared radii thresholds */
154 or = (halfw < halfh ? halfw : halfh) - 8;
159 pixel += padding * width;
160 for (y = padding; y < height - padding; y++) {
162 int y2 = (y - halfh) * (y - halfh);
165 for (x = padding; x < width - padding; x++) {
168 /* squared distance from center */
169 int r2 = (x - halfw) * (x - halfw) + y2;
172 v = (r2 / 32 + time / 64) * 0x0080401;
174 v = (y + time / 32) * 0x0080401;
176 v = (x + time / 16) * 0x0080401;
179 /* cross if compositor uses X from XRGB as alpha */
180 if (abs(x - y) > 6 && abs(x + y - height) > 6)
190 static inline int64_t
191 timespec_to_msec(const struct timespec *a)
193 return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000;
197 output_handle_frame(struct wl_listener *listener,
198 void *data __attribute__((unused)))
200 struct server *server =
201 wl_container_of(listener, server, output_frame);
206 draw_output(struct server *server)
208 struct ds_buffer *buffer;
213 uint32_t frame_time_msec;
215 ds_dbg("Redraw output");
217 clock_gettime(CLOCK_MONOTONIC, &now);
218 frame_time_msec = timespec_to_msec(&now);
220 buffer = ds_swapchain_acquire(server->swapchain, NULL);
223 assert(ds_buffer_begin_data_ptr_access(buffer,
224 0, &data, &format, &stride) == true);
226 paint_pixels(data, 20, server->width, server->height, frame_time_msec);
228 ds_buffer_end_data_ptr_access(buffer);
230 ds_output_attach_buffer(server->output, buffer);
231 ds_output_commit(server->output);
233 if (server->front_buffer)
234 ds_buffer_unlock(server->front_buffer);
236 server->front_buffer = buffer;
240 stdin_dispatch(int fd, uint32_t mask, void *data)
242 struct server *server = data;
244 wl_display_terminate(server->display);