527519c34c778c1bd4c4ac9059623969eac2f951
[profile/ivi/ico-uxf-homescreen.git] / tool / ico_clear_screen.c
1 /*
2  * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
3  *
4  * This program is licensed under the terms and conditions of the
5  * Apache License, version 2.0.  The full text of the Apache License is at
6  * http://www.apache.org/licenses/LICENSE-2.0
7  *
8  */
9 /**
10  * @brief   Display screen clear tool
11  *
12  * @date    Sep-30-2013
13  */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18 #include <string.h>
19 #include <signal.h>
20 #include "ico_clear_screen.h"
21 #include <ico-uxf-weston-plugin/ico_window_mgr-client-protocol.h>
22
23 static struct display   *_display;
24 static int  signal_flag = 0;
25
26 static void
27 sigterm_catch(int signo)
28 {
29     signal_flag = 1;
30
31     if (_display->ico_window_mgr)   {
32         ico_window_mgr_set_visible(_display->ico_window_mgr, ICO_WINDOW_MGR_V_MAINSURFACE,
33                                    ICO_WINDOW_MGR_VISIBLE_HIDE, ICO_WINDOW_MGR_V_NOCHANGE,
34                                    ICO_WINDOW_MGR_FLAGS_ANIMATION |
35                                      ICO_WINDOW_MGR_FLAGS_NO_CONFIGURE);
36     }
37 }
38
39 void
40 wayland_dispatch_nonblock(struct wl_display *display)
41 {
42     int nread;
43
44     /* Check wayland input */
45     do {
46         /* Flush send data */
47         wl_display_flush(display);
48
49         nread = 0;
50         if (ioctl(wl_display_get_fd(display), FIONREAD, &nread) < 0) {
51             nread = 0;
52         }
53         if (nread >= 8) {
54             /* Read event from wayland */
55             wl_display_dispatch(display);
56         }
57     } while (nread > 0);
58 }
59
60 EGLDisplay
61 opengl_init(struct wl_display *display, EGLConfig *rconf, EGLContext *rctx)
62 {
63     EGLDisplay dpy; /* EGL dsplay id */
64     EGLint major, minor;
65     EGLint num_configs;
66     EGLConfig conf = 0;
67     EGLContext ctx;
68
69     static const EGLint config_attribs[] = {
70         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
71         EGL_RED_SIZE, 1,
72         EGL_GREEN_SIZE, 1,
73         EGL_BLUE_SIZE, 1,
74         EGL_ALPHA_SIZE, 1,
75         EGL_DEPTH_SIZE, 1,
76         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
77         EGL_NONE
78     };
79     static const EGLint context_attribs[] = {
80         EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE
81     };
82
83     dpy = eglGetDisplay((EGLNativeDisplayType)display);
84     if (! dpy) {
85         fprintf(stderr, "eglGetDisplay Error\n");
86         return NULL;
87     }
88
89     if (eglInitialize(dpy, &major, &minor) == EGL_FALSE) {
90         fprintf(stderr, "eglInitialize Error\n");
91         return NULL;
92     }
93
94     if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
95         fprintf(stderr, "eglBindAPI Error\n");
96         return NULL;
97     }
98
99     if (eglChooseConfig(dpy, config_attribs, &conf, 1, &num_configs) == EGL_FALSE) {
100         fprintf(stderr, "eglChooseConfig Error\n");
101         return NULL;
102     }
103
104     ctx = eglCreateContext(dpy, conf, EGL_NO_CONTEXT, context_attribs);
105     if (! ctx) {
106         fprintf(stderr, "eglCreateContext Error\n");
107         return NULL;
108     }
109     *rconf = conf;
110     *rctx = ctx;
111
112     wayland_dispatch_nonblock(display);
113
114     return(dpy);
115 }
116
117 EGLSurface
118 opengl_create_window(struct display *display, struct wl_surface *surface,
119                      EGLDisplay dpy, EGLConfig conf, EGLContext ctx,
120                      const int width, const int height, const unsigned int color,
121                      const int displayno, const int posx, const int posy)
122 {
123     struct wl_egl_window *egl_window;
124     EGLSurface egl_surface;
125
126     static const EGLint surface_attribs[] = {
127         EGL_ALPHA_FORMAT, EGL_ALPHA_FORMAT_PRE, EGL_NONE
128     };
129
130     egl_window = wl_egl_window_create(surface, width, height);
131     egl_surface = eglCreateWindowSurface(dpy, conf, (EGLNativeWindowType)egl_window,
132                                          surface_attribs);
133     eglMakeCurrent(dpy, egl_surface, egl_surface, ctx);
134     glViewport(0, 0, width, height);
135
136     wayland_dispatch_nonblock(display->display);
137
138     opengl_clear_window(color);
139
140     opengl_swap_buffer(display->display, dpy, egl_surface);
141
142     ico_window_mgr_set_animation(display->ico_window_mgr, ICO_WINDOW_MGR_V_MAINSURFACE,
143                                  ICO_WINDOW_MGR_ANIMATION_TYPE_HIDE|
144                                    ICO_WINDOW_MGR_ANIMATION_TYPE_SHOW,
145                                  display->animation, display->animatime);
146     ico_window_mgr_set_positionsize(display->ico_window_mgr, ICO_WINDOW_MGR_V_MAINSURFACE,
147                                     displayno, posx, posy,
148                                     ICO_WINDOW_MGR_V_NOCHANGE, ICO_WINDOW_MGR_V_NOCHANGE,
149                                     ICO_WINDOW_MGR_FLAGS_NO_CONFIGURE);
150     ico_window_mgr_set_window_layer(display->ico_window_mgr, ICO_WINDOW_MGR_V_MAINSURFACE,
151                                     display->init_layer);
152     ico_window_mgr_set_layer_visible(display->ico_window_mgr, display->init_layer, 1);
153     ico_window_mgr_set_visible(display->ico_window_mgr, ICO_WINDOW_MGR_V_MAINSURFACE,
154                                ICO_WINDOW_MGR_VISIBLE_SHOW, ICO_WINDOW_MGR_RAISE_RAISE,
155                                ICO_WINDOW_MGR_FLAGS_ANIMATION |
156                                  ICO_WINDOW_MGR_FLAGS_NO_CONFIGURE);
157     return(egl_surface);
158 }
159
160 void
161 opengl_clear_window(const unsigned int color)
162 {
163     double r, g, b, a;
164
165     r = (double)((color>>16) & 0x0ff);
166     r = r / 256.0;
167     g = (double)((color>>8) & 0x0ff);
168     g = g / 256.0;
169     b = (double)(color & 0x0ff);
170     b = b / 256.0;
171     a = (double)((color>>24) & 0x0ff);
172     a = (a + 1.0) / 256.0;
173
174     glClearColor(r, g, b, a);
175     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT| GL_STENCIL_BUFFER_BIT);
176 }
177
178 void
179 opengl_swap_buffer(struct wl_display *display, EGLDisplay dpy, EGLSurface egl_surface)
180 {
181     eglSwapBuffers(dpy, egl_surface);
182
183     wayland_dispatch_nonblock(display);
184 }
185
186 void
187 shell_surface_ping(void *data, struct wl_shell_surface *wl_shell_surface, uint32_t serial)
188 {
189 }
190
191 void
192 shell_surface_configure(void *data, struct wl_shell_surface *wl_shell_surface,
193 uint32_t edges, int32_t width, int32_t height)
194 {
195 }
196
197 void
198 shell_surface_popup_done(void *data, struct wl_shell_surface *wl_shell_surface)
199 {
200 }
201
202 void
203 output_handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
204                        int physical_width, int physical_height, int subpixel,
205                        const char *make, const char *model, int32_t transform)
206 {
207     struct output *output = (struct output*)data;
208
209     output->x = x;
210     output->y = y;
211 }
212
213 void
214 output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags,
215                    int width, int height, int refresh)
216 {
217     struct output *output = (struct output*)data;
218
219     if (flags & WL_OUTPUT_MODE_CURRENT) {
220         output->width = width;
221         output->height = height;
222     }
223 }
224
225 void
226 handle_global(void *data, struct wl_registry *registry, uint32_t id,
227               const char *interface, uint32_t version) {
228     struct display *display = (struct display*)data;
229     struct output *output;
230
231     if (strcmp(interface, "wl_compositor") == 0) {
232         display->compositor = (struct wl_compositor*)wl_registry_bind(display->registry, id,
233                                                                &wl_compositor_interface, 1);
234     }
235     else if (strcmp(interface, "wl_output") == 0) {
236         if (display->num_output < MAX_DISPLAY)  {
237             output = (struct output*)malloc(sizeof *output);
238             output->display = display;
239             output->output = (struct wl_output*)wl_registry_bind(display->registry, id, &wl_output_interface, 1);
240             wl_output_add_listener(output->output, &output_listener, output);
241             display->output[display->num_output++] = output;
242         }
243     }
244     else if (strcmp(interface, "wl_shell") == 0) {
245         display->shell = (struct wl_shell*)wl_registry_bind(display->registry, id, &wl_shell_interface, 1);
246     }
247     else if (strcmp(interface, "ico_window_mgr") == 0) {
248         display->ico_window_mgr = (struct ico_window_mgr *)wl_registry_bind(display->registry, id, &ico_window_mgr_interface, 1);
249     }
250 }
251
252 void
253 surface_enter(void *data, struct wl_surface *wl_surface, struct wl_output *output)
254 {
255     struct surface *surface = (struct surface *)data;
256
257     surface->output = (struct output*)wl_output_get_user_data(output);
258 }
259
260 void
261 surface_leave(void *data, struct wl_surface *wl_surface, struct wl_output *output)
262 {
263     struct surface *surface = (struct surface*)data;
264
265     surface->output = NULL;
266
267 }
268
269 void
270 sleep_with_wayland(struct wl_display *display, int msec)
271 {
272     int nread;
273     int fd;
274
275     fd = wl_display_get_fd(display);
276
277     do {
278         /* Flush send data */
279         wl_display_flush(display);
280
281         /* Check wayland input */
282         nread = 0;
283         if (ioctl(fd, FIONREAD, &nread) < 0) {
284             nread = 0;
285         }
286         if (nread >= 8) {
287             /* Read event from wayland */
288             wl_display_dispatch(display);
289         }
290         msec -= 20;
291         if (msec >= 0) usleep(20*1000);
292     } while (msec > 0);
293 }
294
295 void
296 create_surface(struct display *display, const char *title) {
297     struct surface *surface;
298
299     if (display->num_surface >= MAX_SURFACE)    {
300         exit(1);
301     }
302     surface = (struct surface *)malloc(sizeof(struct surface));
303     assert(surface);
304     memset(surface, 0, sizeof(struct surface));
305     surface->display = display;
306     display->surface[display->num_surface++] = surface;
307     surface->surface = wl_compositor_create_surface(display->compositor);
308     wl_surface_add_listener(surface->surface, &surface_listener, surface);
309
310     if (display->shell) {
311         surface->shell_surface = wl_shell_get_shell_surface(display->shell,
312                                                             surface->surface);
313         if (surface->shell_surface) {
314             wl_shell_surface_add_listener(surface->shell_surface,
315                                           &shell_surface_listener, display);
316             wl_shell_surface_set_toplevel(surface->shell_surface);
317             wl_shell_surface_set_title(surface->shell_surface, title);
318         }
319     }
320     wl_display_flush(display->display);
321     poll(NULL, 0, 100);
322
323     wl_display_roundtrip(display->display);
324
325     surface->dpy = opengl_init(display->display, &surface->conf, &surface->ctx);
326     if (surface->dpy) {
327         surface->egl_surface = opengl_create_window(display, 
328                                                     surface->surface,
329                                                     surface->dpy,
330                                                     surface->conf,
331                                                     surface->ctx,
332                                                     display->init_width,
333                                                     display->init_height,
334                                                     display->init_color,
335                                                     display->displayno,
336                                                     display->init_posx,
337                                                     display->init_posy);
338         clear_surface(surface);
339     }
340 }
341
342 void
343 clear_surface(struct surface *surface)
344 {
345     struct display *display = surface->display;
346
347     opengl_clear_window(display->init_color);
348     opengl_swap_buffer(display->display,
349                        surface->dpy, surface->egl_surface);
350 }
351
352 int main(int argc, char *argv[])
353 {
354     int         i;
355     char        sname[64];
356
357     _display = malloc(sizeof(struct display));
358     memset(_display, 0, sizeof(struct display));
359
360     _display->displayno = 0;
361     _display->init_color = 0xff000000;
362     _display->init_width = 1920;
363     _display->init_height = 1920;
364     _display->init_layer = 201;
365     strcpy(_display->animation, "fade");
366     _display->animatime = 600;
367
368     for (i = 1; i < (argc-1); i++)  {
369         if (strcasecmp(argv[i], "-display") == 0)   {
370             i++;
371             _display->displayno = strtol(argv[i], (char **)0, 0);
372         }
373         else if (strcasecmp(argv[i], "-width") == 0)    {
374             i++;
375             _display->init_width = strtol(argv[i], (char **)0, 0);
376         }
377         else if (strcasecmp(argv[i], "-height") == 0)   {
378             i++;
379             _display->init_height = strtol(argv[i], (char **)0, 0);
380         }
381         else if (strcasecmp(argv[i], "-color") == 0)   {
382             i++;
383             _display->init_color = strtoul(argv[i], (char **)0, 0);
384         }
385         else if (strcasecmp(argv[i], "-layer") == 0)   {
386             i++;
387             _display->init_layer = strtol(argv[i], (char **)0, 0);
388         }
389         else if (strcasecmp(argv[i], "-animation") == 0)   {
390             i++;
391             memset(_display->animation, 0, sizeof(_display->animation));
392             strncpy(_display->animation, argv[i], sizeof(_display->animation)-1);
393         }
394         else if (strcasecmp(argv[i], "-animatime") == 0)   {
395             i++;
396             _display->animatime = strtol(argv[i], (char **)0, 0);
397         }
398         else    {
399             fprintf(stderr,
400                     "usage: %s [-display no][-layer layer][-color aarrggbb][-width width]"
401                     "[-height height]\n", argv[0]);
402             exit(1);
403         }
404     }
405
406     _display->display = wl_display_connect(NULL);
407     if (! _display->display) {
408         fprintf(stderr, "can not connect to wayland\n");
409         return 1;
410     }
411     _display->registry = wl_display_get_registry(_display->display);
412     wl_registry_add_listener(_display->registry, &registry_listener, _display);
413
414     wl_display_dispatch(_display->display);
415     sleep_with_wayland(_display->display, 300);
416
417     sprintf(sname, "Clear-Screen-%d-%d", getpid(), _display->displayno);
418     create_surface(_display, sname);
419
420     signal_flag = 0;
421     signal(SIGTERM, sigterm_catch);
422
423     while (signal_flag == 0)   {
424         sleep_with_wayland(_display->display, 50);
425     }
426     for (i = 0; i < (450/50); i++)  {
427         sleep_with_wayland(_display->display, 50);
428     }
429     return 0;
430 }
431