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