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