keyrouter: Fix wrong validity check
[platform/core/uifw/libds-tizen.git] / src / examples / wl-backend.c
1 #include <assert.h>
2 #include <stdbool.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <signal.h>
6
7 #include <wayland-server.h>
8 #include <libds/log.h>
9 #include <libds/backend.h>
10 #include <libds/allocator/shm.h>
11 #include <libds/backend/wayland.h>
12 #include <libds/swapchain.h>
13 #include <libds/compositor.h>
14
15 #define WIDTH   700
16 #define HEIGHT  400
17
18 struct server
19 {
20     struct ds_backend *backend;
21     struct ds_output *output;
22     struct ds_allocator *allocator;
23     struct ds_swapchain *swapchain;
24     struct ds_buffer *front_buffer;
25
26     struct wl_display *display;
27
28     struct {
29         struct wl_listener output_destroy;
30         struct wl_listener output_frame;
31     } listener;
32
33     int width, height;
34 };
35
36 struct server _server;
37
38 static void init_server(struct server *server, struct wl_display *display);
39 static void fini_server(struct server *server);
40 static void output_handle_destroy(struct wl_listener *listener, void *data);
41 static void output_handle_frame(struct wl_listener *listener, void *data);
42 static void draw_output(struct server *server);
43
44 int
45 main(void)
46 {
47     struct server *server = &_server;
48     struct wl_display *display;
49
50     ds_log_init(DS_DBG, NULL);
51
52     display = wl_display_create();
53     assert(display);
54
55     server->width = WIDTH;
56     server->height = HEIGHT;
57
58     init_server(server, display);
59
60     server->listener.output_destroy.notify = output_handle_destroy;
61     ds_output_add_destroy_listener(server->output,
62             &server->listener.output_destroy);
63
64     server->listener.output_frame.notify = output_handle_frame;
65     ds_output_add_frame_listener(server->output,
66             &server->listener.output_frame);
67
68     ds_backend_start(server->backend);
69
70     draw_output(server);
71
72     wl_display_run(server->display);
73
74     fini_server(server);
75     wl_display_destroy(display);
76     return 0;
77 }
78
79 static struct ds_backend *
80 create_backend_auto(struct wl_display *display)
81 {
82     struct ds_backend *backend = NULL;
83     char name[512];
84     int i;
85
86     for (i = 0; i < 5; i++) {
87         snprintf(name, sizeof name, "wayland-%d", i);
88         backend = ds_wl_backend_create(display, name);
89         if (backend)
90             break;
91     }
92
93     return backend;
94 }
95
96 static void
97 init_server(struct server *server, struct wl_display *display)
98 {
99     server->display = display;
100
101     server->backend = create_backend_auto(display);
102     assert(server->backend);
103
104     server->allocator = ds_shm_allocator_create();
105     assert(server->allocator);
106
107     server->swapchain = ds_swapchain_create(server->allocator,
108             server->width, server->height, WL_SHM_FORMAT_XRGB8888);
109     assert(server->swapchain);
110
111     server->output =
112         ds_wl_backend_create_output(server->backend);
113     assert(server->output);
114 }
115
116 static void
117 fini_server(struct server *server)
118 {
119     ds_buffer_unlock(server->front_buffer);
120     ds_swapchain_destroy(server->swapchain);
121     ds_allocator_destroy(server->allocator);
122 }
123
124 static void
125 paint_pixels(void *image, int padding, int width, int height, uint32_t time)
126 {
127         const int halfh = padding + (height - padding * 2) / 2;
128         const int halfw = padding + (width - padding * 2) / 2;
129         int ir, or;
130         uint32_t *pixel = image;
131         int y;
132
133         /* squared radii thresholds */
134         or = (halfw < halfh ? halfw : halfh) - 8;
135         ir = or - 32;
136         or *= or;
137         ir *= ir;
138
139         pixel += padding * width;
140         for (y = padding; y < height - padding; y++) {
141                 int x;
142                 int y2 = (y - halfh) * (y - halfh);
143
144                 pixel += padding;
145                 for (x = padding; x < width - padding; x++) {
146                         uint32_t v;
147
148                         /* squared distance from center */
149                         int r2 = (x - halfw) * (x - halfw) + y2;
150
151                         if (r2 < ir)
152                                 v = (r2 / 32 + time / 64) * 0x0080401;
153                         else if (r2 < or)
154                                 v = (y + time / 32) * 0x0080401;
155                         else
156                                 v = (x + time / 16) * 0x0080401;
157                         v &= 0x00ffffff;
158
159                         /* cross if compositor uses X from XRGB as alpha */
160                         if (abs(x - y) > 6 && abs(x + y - height) > 6)
161                                 v |= 0xff000000;
162
163                         *pixel++ = v;
164                 }
165
166                 pixel += padding;
167         }
168 }
169
170 static inline int64_t                                       
171 timespec_to_msec(const struct timespec *a)                  
172 {                                                           
173     return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000;
174 }                                                           
175
176 static void
177 output_handle_destroy(struct wl_listener *listener,
178         void *data __attribute__((unused)))
179 {
180     struct server *server =
181         wl_container_of(listener, server, listener.output_destroy);
182     wl_display_terminate(server->display);
183 }
184
185 static void
186 output_handle_frame(struct wl_listener *listener,
187         void *data __attribute__((unused)))
188 {
189     struct server *server =
190         wl_container_of(listener, server, listener.output_frame);
191     draw_output(server);
192 }
193
194 static void
195 draw_output(struct server *server)
196 {
197     struct ds_buffer *buffer;
198     void *data;
199     uint32_t format;
200     size_t stride;
201     struct timespec now;                 
202     uint32_t frame_time_msec;
203
204     ds_dbg("Redraw output");
205
206     clock_gettime(CLOCK_MONOTONIC, &now);
207     frame_time_msec = timespec_to_msec(&now);
208
209     buffer = ds_swapchain_acquire(server->swapchain, NULL);
210     assert(buffer);
211
212     assert(ds_buffer_begin_data_ptr_access(buffer,
213                 0, &data, &format, &stride) == true);
214
215     paint_pixels(data, 20, server->width, server->height, frame_time_msec);
216
217     ds_buffer_end_data_ptr_access(buffer);
218
219     ds_output_attach_buffer(server->output, buffer);
220     ds_output_commit(server->output);
221
222     if (server->front_buffer)
223         ds_buffer_unlock(server->front_buffer);
224
225     server->front_buffer = buffer;
226 }