Add debug message macros controlled by environment variable
[src/libhomescreen.git] / sample / simple-egl / src / simple-egl.cpp
1 /*
2  * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
3  * Copyright © 2011 Benjamin Franzke
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24
25 #include <mutex>
26 #include <chrono>
27
28 #include <iostream>
29 #include <string>
30 #include <stdarg.h>
31 #include <sys/types.h>
32 #include <thread>
33 #include <exception>
34 #include <vector>
35 #include <sstream>
36
37 #include <assert.h>
38 #include <signal.h>
39
40 #include <wayland-client.h>
41 #include <wayland-egl.h>
42
43 #include <GLES2/gl2.h>
44 #include <EGL/egl.h>
45 #include <EGL/eglext.h>
46
47 #include <unistd.h>
48 #include <time.h>
49
50 #include "libwindowmanager.h"
51 #include <libhomescreen.hpp>
52
53 #include <ilm/ivi-application-client-protocol.h>
54 #include "hmi-debug.h"
55
56 using namespace std;
57
58
59 uint32_t g_id_ivisurf = 9009;
60 long port = 1700;
61 string token = string("wm");
62
63 string app_name = string("Navigation");
64
65 LibHomeScreen* hs;
66 LibWindowmanager *wm;
67 bool gIsDraw = false;
68
69 static const struct wl_interface *types[] = {
70         NULL,
71         NULL,
72         NULL,
73         &wl_surface_interface,
74         &ivi_surface_interface,
75 };
76
77 static const struct wl_message ivi_surface_requests[] = {
78         { "destroy", "", types + 0 },
79 };
80
81 static const struct wl_message ivi_surface_events[] = {
82         { "configure", "ii", types + 0 },
83 };
84
85 const struct wl_interface ivi_surface_interface = {
86         "ivi_surface", 1,
87         1, ivi_surface_requests,
88         1, ivi_surface_events,
89 };
90
91 static const struct wl_message ivi_application_requests[] = {
92         { "surface_create", "uon", types + 2 },
93 };
94
95 const struct wl_interface ivi_application_interface = {
96         "ivi_application", 1,
97         1, ivi_application_requests,
98         0, NULL,
99 };
100
101 #include "platform.h"
102
103 #ifndef EGL_EXT_swap_buffers_with_damage
104 #define EGL_EXT_swap_buffers_with_damage 1
105 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC)(EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
106 #endif
107
108 #ifndef EGL_EXT_buffer_age
109 #define EGL_EXT_buffer_age 1
110 #define EGL_BUFFER_AGE_EXT                      0x313D
111 #endif
112
113 struct window;
114 struct seat;
115
116 struct display {
117         struct wl_display *display;
118         struct wl_registry *registry;
119         struct wl_compositor *compositor;
120         struct wl_seat *seat;
121         struct {
122                 EGLDisplay dpy;
123                 EGLContext ctx;
124                 EGLConfig conf;
125         } egl;
126         struct window *window;
127         struct ivi_application *ivi_application;
128
129         PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage;
130 };
131
132 struct geometry {
133         int width, height;
134 };
135
136 struct window {
137         struct display *display;
138         struct geometry geometry, window_size;
139         struct {
140                 GLuint rotation_uniform;
141                 GLuint pos;
142                 GLuint col;
143         } gl;
144
145         uint32_t benchmark_time, frames;
146         struct wl_egl_window *native;
147         struct wl_surface *surface;
148         struct ivi_surface *ivi_surface;
149         EGLSurface egl_surface;
150         struct wl_callback *callback;
151         int fullscreen, opaque, buffer_size, frame_sync;
152 } *gWindow;
153
154 static const char *vert_shader_text =
155         "uniform mat4 rotation;\n"
156         "attribute vec4 pos;\n"
157         "attribute vec4 color;\n"
158         "varying vec4 v_color;\n"
159         "void main() {\n"
160         "  gl_Position = rotation * pos;\n"
161         "  v_color = color;\n"
162         "}\n";
163
164 static const char *frag_shader_text =
165         "precision mediump float;\n"
166         "varying vec4 v_color;\n"
167         "void main() {\n"
168         "  gl_FragColor = v_color;\n"
169         "}\n";
170
171 static int running = 1;
172
173 static void
174 init_egl(struct display *display, struct window *window)
175 {
176         static const EGLint context_attribs[] = {
177                 EGL_CONTEXT_CLIENT_VERSION, 2,
178                 EGL_NONE
179         };
180         const char *extensions;
181
182         EGLint config_attribs[] = {
183                 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
184                 EGL_RED_SIZE, 1,
185                 EGL_GREEN_SIZE, 1,
186                 EGL_BLUE_SIZE, 1,
187                 EGL_ALPHA_SIZE, 1,
188                 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
189                 EGL_NONE
190         };
191
192         EGLint major, minor, n, count, i, size;
193         EGLConfig *configs;
194         EGLBoolean ret;
195
196         if (window->opaque || window->buffer_size == 16)
197                 config_attribs[9] = 0;
198         
199         display->egl.dpy = weston_platform_get_egl_display(EGL_PLATFORM_WAYLAND_KHR, display->display, NULL);
200         assert(display->egl.dpy);
201
202         ret = eglInitialize(display->egl.dpy, &major, &minor);
203         assert(ret == EGL_TRUE);
204         ret = eglBindAPI(EGL_OPENGL_ES_API);
205         assert(ret == EGL_TRUE);
206
207         if (!eglGetConfigs(display->egl.dpy, NULL, 0, &count) || count < 1)
208                 assert(0);
209
210         configs = calloc(count, sizeof *configs);
211         assert(configs);
212
213         ret = eglChooseConfig(display->egl.dpy, config_attribs,
214                               configs, count, &n);
215         assert(ret && n >= 1);
216
217         for (i = 0; i < n; i++) {
218                 eglGetConfigAttrib(display->egl.dpy,
219                                    configs[i], EGL_BUFFER_SIZE, &size);
220                 if (window->buffer_size == size) {
221                         display->egl.conf = configs[i];
222                         break;
223                 }
224         }
225         free(configs);
226         if (display->egl.conf == NULL) {
227                 HMI_DEBUG("simple-egl","did not find config with buffer size %d",
228                         window->buffer_size);
229                 exit(EXIT_FAILURE);
230         }
231
232         display->egl.ctx = eglCreateContext(display->egl.dpy,
233                                             display->egl.conf,
234                                             EGL_NO_CONTEXT, context_attribs);
235         assert(display->egl.ctx);
236
237         display->swap_buffers_with_damage = NULL;
238         extensions = eglQueryString(display->egl.dpy, EGL_EXTENSIONS);
239         if (extensions &&
240             strstr(extensions, "EGL_EXT_swap_buffers_with_damage") &&
241             strstr(extensions, "EGL_EXT_buffer_age"))
242                 display->swap_buffers_with_damage =
243                         (PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC)
244                         eglGetProcAddress("eglSwapBuffersWithDamageEXT");
245
246         if (display->swap_buffers_with_damage)
247                 HMI_DEBUG("simple-egl","has EGL_EXT_buffer_age and EGL_EXT_swap_buffers_with_damage");
248
249 }
250
251 static void
252 fini_egl(struct display *display)
253 {
254         eglTerminate(display->egl.dpy);
255         eglReleaseThread();
256 }
257
258 static GLuint
259 create_shader(struct window *window, const char *source, GLenum shader_type)
260 {
261         GLuint shader;
262         GLint status;
263
264         shader = glCreateShader(shader_type);
265         assert(shader != 0);
266
267         glShaderSource(shader, 1, (const char **) &source, NULL);
268         glCompileShader(shader);
269
270         glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
271         if (!status) {
272                 char log[1000];
273                 GLsizei len;
274                 glGetShaderInfoLog(shader, 1000, &len, log);
275                 HMI_DEBUG("simple-egl","Error: compiling %s: %*s",
276                         shader_type == GL_VERTEX_SHADER ? "vertex" : "fragment",
277                         len, log);
278                 exit(1);
279         }
280
281         return shader;
282 }
283
284 static void
285 init_gl(struct window *window)
286 {
287         GLuint frag, vert;
288         GLuint program;
289         GLint status;
290
291         frag = create_shader(window, frag_shader_text, GL_FRAGMENT_SHADER);
292         vert = create_shader(window, vert_shader_text, GL_VERTEX_SHADER);
293
294         program = glCreateProgram();
295         glAttachShader(program, frag);
296         glAttachShader(program, vert);
297         glLinkProgram(program);
298
299         glGetProgramiv(program, GL_LINK_STATUS, &status);
300         if (!status) {
301                 char log[1000];
302                 GLsizei len;
303                 glGetProgramInfoLog(program, 1000, &len, log);
304                 HMI_DEBUG("simple-egl","Error: linking:%*s", len, log);
305                 exit(1);
306         }
307
308         glUseProgram(program);
309
310         window->gl.pos = 0;
311         window->gl.col = 1;
312
313         glBindAttribLocation(program, window->gl.pos, "pos");
314         glBindAttribLocation(program, window->gl.col, "color");
315         glLinkProgram(program);
316
317         window->gl.rotation_uniform =
318                 glGetUniformLocation(program, "rotation");
319 }
320
321 static void
322 create_ivi_surface(struct window *window, struct display *display)
323 {
324         uint32_t id_ivisurf = g_id_ivisurf;
325         window->ivi_surface =
326                 ivi_application_surface_create(display->ivi_application,
327                                                id_ivisurf, window->surface);
328
329         if (window->ivi_surface == NULL) {
330                 HMI_DEBUG("simple-egl","Failed to create ivi_client_surface");
331                 abort();
332         }
333
334 }
335
336 static void
337 create_surface(struct window *window)
338 {
339         struct display *display = window->display;
340         EGLBoolean ret;
341
342         window->surface = wl_compositor_create_surface(display->compositor);
343
344         window->native =
345                 wl_egl_window_create(window->surface,
346                                      window->geometry.width,
347                                      window->geometry.height);
348         window->egl_surface =
349                 weston_platform_create_egl_surface(display->egl.dpy,
350                                                    display->egl.conf,
351                                                    window->native, NULL);
352
353
354         if (display->ivi_application ) {
355                 create_ivi_surface(window, display);
356         } else {
357                 assert(0);
358         }
359
360         ret = eglMakeCurrent(window->display->egl.dpy, window->egl_surface,
361                              window->egl_surface, window->display->egl.ctx);
362         assert(ret == EGL_TRUE);
363
364         if (!window->frame_sync)
365                 eglSwapInterval(display->egl.dpy, 0);
366
367 }
368
369 static void
370 destroy_surface(struct window *window)
371 {
372         /* Required, otherwise segfault in egl_dri2.c: dri2_make_current()
373          * on eglReleaseThread(). */
374         eglMakeCurrent(window->display->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE,
375                        EGL_NO_CONTEXT);
376
377         eglDestroySurface(window->display->egl.dpy, window->egl_surface);
378         wl_egl_window_destroy(window->native);
379
380         if (window->display->ivi_application)
381                 ivi_surface_destroy(window->ivi_surface);
382         wl_surface_destroy(window->surface);
383
384         if (window->callback)
385                 wl_callback_destroy(window->callback);
386 }
387
388 static void
389 redraw(void *data, struct wl_callback *callback, uint32_t time)
390 {
391         struct window *window = data;
392         struct display *display = window->display;
393         static const GLfloat verts[3][2] = {
394                 { -0.5, -0.5 },
395                 {  0.5, -0.5 },
396                 {  0,    0.5 }
397         };
398
399         static const GLfloat verts_sub[3][2] = {
400                 { -0.25, -0.5 },
401                 {  0.25, -0.5 },
402                 {  0,    0.5 }
403         };
404
405         static const GLfloat colors_H[3][3] = {
406                 { 1, 1, 1 },
407                 { 1, 1, 1 },
408                 { 1, 1, 1 }
409         };
410
411         static const GLfloat colors_N[3][3] = {
412                 { 1, 0, 0 },
413                 { 0, 1, 0 },
414                 { 0, 0, 1 }
415         };
416
417         GLfloat angle;
418         GLfloat rotation[4][4] = {
419                 { 1, 0, 0, 0 },
420                 { 0, 1, 0, 0 },
421                 { 0, 0, 1, 0 },
422                 { 0, 0, 0, 1 }
423         };
424         static const uint32_t speed_div = 5, benchmark_interval = 5;
425         struct wl_region *region;
426         EGLint rect[4];
427         EGLint buffer_age = 0;
428         struct timeval tv;
429
430         assert(window->callback == callback);
431         window->callback = NULL;
432
433         if (callback)
434                 wl_callback_destroy(callback);
435
436         gettimeofday(&tv, NULL);
437         time = tv.tv_sec * 1000 + tv.tv_usec / 1000;
438         if (window->frames == 0)
439                 window->benchmark_time = time;
440
441         if (time - window->benchmark_time > (benchmark_interval * 1000)) {
442                 HMI_DEBUG("simple-egl","%d frames in %d seconds: %f fps",
443                        window->frames,
444                        benchmark_interval,
445                        (float) window->frames / benchmark_interval);
446                 window->benchmark_time = time;
447                 window->frames = 0;
448         }
449
450         angle = (time / speed_div) % 360 * M_PI / 180.0;
451         rotation[0][0] =  cos(angle);
452         rotation[0][2] =  sin(angle);
453         rotation[2][0] = -sin(angle);
454         rotation[2][2] =  cos(angle);
455
456         if (display->swap_buffers_with_damage)
457                 eglQuerySurface(display->egl.dpy, window->egl_surface,
458                                 EGL_BUFFER_AGE_EXT, &buffer_age);
459
460         glViewport(0, 0, window->geometry.width, window->geometry.height);
461
462         glUniformMatrix4fv(window->gl.rotation_uniform, 1, GL_FALSE,
463                            (GLfloat *) rotation);
464
465         glClearColor(0.0, 0.0, 0.0, 0.5);
466         glClear(GL_COLOR_BUFFER_BIT);
467
468         if(window->geometry.height == 1488)
469         {
470                 glVertexAttribPointer(window->gl.pos, 2, GL_FLOAT, GL_FALSE, 0, verts);
471         }
472         else
473         {
474                 glVertexAttribPointer(window->gl.pos, 2, GL_FLOAT, GL_FALSE, 0, verts_sub);
475         }
476         if(app_name == string("HVAC")){
477                 glVertexAttribPointer(window->gl.col, 3, GL_FLOAT, GL_FALSE, 0, colors_H);
478         }
479         else{
480                 glVertexAttribPointer(window->gl.col, 3, GL_FLOAT, GL_FALSE, 0, colors_N);
481         }
482         glEnableVertexAttribArray(window->gl.pos);
483         glEnableVertexAttribArray(window->gl.col);
484
485         glDrawArrays(GL_TRIANGLES, 0, 3);
486
487         glDisableVertexAttribArray(window->gl.pos);
488         glDisableVertexAttribArray(window->gl.col);
489
490         if (window->opaque || window->fullscreen) {
491                 region = wl_compositor_create_region(window->display->compositor);
492                 wl_region_add(region, 0, 0,
493                               window->geometry.width,
494                               window->geometry.height);
495                 wl_surface_set_opaque_region(window->surface, region);
496                 wl_region_destroy(region);
497         } else {
498                 wl_surface_set_opaque_region(window->surface, NULL);
499         }
500
501         if (display->swap_buffers_with_damage && buffer_age > 0) {
502                 rect[0] = window->geometry.width / 4 - 1;
503                 rect[1] = window->geometry.height / 4 - 1;
504                 rect[2] = window->geometry.width / 2 + 2;
505                 rect[3] = window->geometry.height / 2 + 2;
506                 display->swap_buffers_with_damage(display->egl.dpy,
507                                                   window->egl_surface,
508                                                   rect, 1);
509         } else {
510                 eglSwapBuffers(display->egl.dpy, window->egl_surface);
511         }
512     
513         window->frames++;
514 }
515
516 static void
517 registry_handle_global(void *data, struct wl_registry *registry,
518                        uint32_t name, const char *interface, uint32_t version)
519 {
520         struct display *d = data;
521
522         if (strcmp(interface, "wl_compositor") == 0) {
523                 d->compositor =
524                         wl_registry_bind(registry, name,
525                                          &wl_compositor_interface, 1);
526         } else if (strcmp(interface, "ivi_application") == 0) {
527                 d->ivi_application =
528                         wl_registry_bind(registry, name,
529                                          &ivi_application_interface, 1);
530         }
531 }
532
533 static void
534 registry_handle_global_remove(void *data, struct wl_registry *registry,
535                               uint32_t name)
536 {
537 }
538
539 static const struct wl_registry_listener registry_listener = {
540         registry_handle_global,
541         registry_handle_global_remove
542 };
543
544 static void
545 signal_int(int signum)
546 {
547         running = 0;
548 }
549
550 int
551 init_wm(LibWindowmanager *wm)
552 {
553         HMI_DEBUG("simple-egl","called");
554         char* surfaceIdStr;
555
556         if (wm->init(port, token.c_str()) != 0) {
557                 HMI_DEBUG("simple-egl","wm init failed. ");
558                 return -1;
559         }
560
561         json_object *obj = json_object_new_object();
562         json_object_object_add(obj, wm->kKeyDrawingName, json_object_new_string(app_name.c_str()));
563         if (wm->requestSurface(obj) != 0) {
564                 HMI_DEBUG("simple-egl","wm request surface failed ");
565                 return -1;
566         }
567
568         wm->set_event_handler(LibWindowmanager::Event_Active, [wm](json_object *object) {
569                 const char *label = json_object_get_string(
570                         json_object_object_get(object, wm->kKeyDrawingName));
571                 HMI_DEBUG("simple-egl","Surface %s got activated! ", label);
572         });
573
574         wm->set_event_handler(LibWindowmanager::Event_Inactive, [wm](json_object *object) {
575                 const char *label = json_object_get_string(
576                         json_object_object_get(object, wm->kKeyDrawingName));
577                 HMI_DEBUG("simple-egl","Surface %s got inactivated!", label);
578         });
579
580         wm->set_event_handler(LibWindowmanager::Event_Visible, [wm](json_object *object) {
581                 const char *label = json_object_get_string(
582                         json_object_object_get(object, wm->kKeyDrawingName));
583                 HMI_DEBUG("simple-egl","Surface %s got visibled!", label);
584         });
585
586         wm->set_event_handler(LibWindowmanager::Event_Invisible, [wm](json_object *object) {
587                 const char *label = json_object_get_string(
588                         json_object_object_get(object, wm->kKeyDrawingName));
589                 HMI_DEBUG("simple-egl","Surface %s got invisibled!", label);
590                 gIsDraw = false;
591         });
592
593         wm->set_event_handler(LibWindowmanager::Event_SyncDraw, [wm](json_object *object) {
594                 const char *label = json_object_get_string(
595                         json_object_object_get(object, wm->kKeyDrawingName));
596                 const char *area = json_object_get_string(
597                         json_object_object_get(object, wm->kKeyDrawingArea));
598
599                 HMI_DEBUG("simple-egl","Surface %s got syncDraw! Area: %s. ", label, area);
600                 if ((wm->kStrLayoutNormal + "." + wm->kStrAreaFull) == std::string(area)) {
601                         HMI_DEBUG("simple-egl","Layout:%s x:%d y:%d w:%d h:%d ", area, 0, 0, 1080, 1488);
602                         wl_egl_window_resize(gWindow->native, 1080, 1488, 0, 0);
603                         gWindow->geometry.width = 1080;
604                         gWindow->geometry.height = 1488;
605                 }
606                 else if ((wm->kStrLayoutSplit + "." + wm->kStrAreaMain) == std::string(area) ||
607                                  (wm->kStrLayoutSplit + "." + wm->kStrAreaSub) == std::string(area)) {
608                         HMI_DEBUG("simple-egl","Layout:%s x:%d y:%d w:%d h:%d ", area, 0, 0, 1080, 744);
609                         wl_egl_window_resize(gWindow->native, 1080, 744, 0, 0);
610                         gWindow->geometry.width = 1080;
611                         gWindow->geometry.height = 744;
612                 }
613
614                 if (!gWindow->fullscreen)
615                         gWindow->window_size = gWindow->geometry;
616                 gIsDraw = true;
617                 json_object *obj = json_object_new_object();
618                 json_object_object_add(obj, wm->kKeyDrawingName, json_object_new_string(app_name.c_str()));
619
620         wm->endDraw(obj);
621     });
622
623         wm->set_event_handler(LibWindowmanager::Event_FlushDraw, [wm](json_object *object) {
624                 const char *label = json_object_get_string(
625                         json_object_object_get(object, wm->kKeyDrawingName));
626                 HMI_DEBUG("simple-egl","Surface %s got flushdraw! ", label);
627         });
628
629         do
630         {
631         surfaceIdStr = getenv("QT_IVI_SURFACE_ID");
632         } while (surfaceIdStr == NULL);
633
634         g_id_ivisurf = atoi(surfaceIdStr);
635         HMI_DEBUG("simple-egl","IVI_SURFACE_ID: %d ", g_id_ivisurf);
636
637         return 0;
638 }
639
640 int
641 init_hs(LibHomeScreen* hs){
642         if(hs->init(port, token)!=0)
643         {
644                 HMI_DEBUG("simple-egl","homescreen init failed. ");
645                 return -1;
646         }
647
648         hs->set_event_handler(LibHomeScreen::Event_TapShortcut, [](json_object *object){
649                 const char *application_name = json_object_get_string(
650                         json_object_object_get(object, "application_name"));
651                 HMI_DEBUG("simple-egl","Event_TapShortcut application_name = %s ", application_name);
652                 if(strcmp(application_name, app_name.c_str()) == 0)
653                 {
654                         HMI_DEBUG("simple-egl","try to activesurface %s ", app_name.c_str());
655                         json_object *obj = json_object_new_object();
656                         json_object_object_add(obj, wm->kKeyDrawingName, json_object_new_string(app_name.c_str()));
657                         json_object_object_add(obj, wm->kKeyDrawingArea, json_object_new_string("normal.full"));
658                         gIsDraw = false;
659                         wm->activateSurface(obj);
660                 }
661         });
662
663         hs->set_event_handler(LibHomeScreen::Event_OnScreenMessage, [](json_object *object){
664                 const char *display_message = json_object_get_string(
665                         json_object_object_get(object, "display_message"));
666         HMI_DEBUG("simple-egl","Event_OnScreenMessage display_message = %s ", display_message);
667         });
668
669         return 0;
670 }
671
672 int
673 main(int argc, char **argv)
674 {
675         struct sigaction sigint;
676         struct window  window  = { 0 };
677         struct display display = { 0 };
678
679         window.display = &display;
680         display.window = &window;
681         window.geometry.width  = 1080;
682         window.geometry.height = 1488;
683         window.window_size = window.geometry;
684         window.buffer_size = 32;
685         window.frame_sync = 1;
686         gWindow = &window;
687
688         if(argc > 2)
689         {
690                 if(string(argv[0]).find("hvac") != string::npos)
691                         app_name = string("HVAC");
692                 port = strtol(argv[1], NULL, 10);
693                 token = argv[2];
694         }
695
696         HMI_DEBUG("simple-egl","app_name: %s, port: %d, token: %s. ", app_name.c_str(), port, token.c_str());
697
698         display.display = wl_display_connect(NULL);
699         assert(display.display);
700
701         display.registry = wl_display_get_registry(display.display);
702         wl_registry_add_listener(display.registry,
703                                  &registry_listener, &display);
704
705         wl_display_roundtrip(display.display);
706
707         init_egl(&display, &window);
708
709         wm = new LibWindowmanager();
710         hs = new LibHomeScreen();
711         
712         if(init_wm(wm)!=0){
713                 fini_egl(&display);
714                 if (display.ivi_application)
715                         ivi_application_destroy(display.ivi_application);
716                 if (display.compositor)
717                         wl_compositor_destroy(display.compositor);
718                 wl_registry_destroy(display.registry);
719                 wl_display_flush(display.display);
720                 return -1;
721         }
722
723         if(init_hs(hs)!=0){
724                 fini_egl(&display);
725                 if (display.ivi_application)
726                         ivi_application_destroy(display.ivi_application);
727                 if (display.compositor)
728                         wl_compositor_destroy(display.compositor);
729                 wl_registry_destroy(display.registry);
730                 wl_display_flush(display.display);
731                 return -1;
732         }
733
734         create_surface(&window);
735         init_gl(&window);
736
737         //Ctrl+C
738         sigint.sa_handler = signal_int;
739         sigemptyset(&sigint.sa_mask);
740         sigint.sa_flags = SA_RESETHAND;
741         sigaction(SIGINT, &sigint, NULL);
742
743         wl_display_dispatch_pending(display.display);
744         redraw(&window, NULL, 0);
745         json_object *obj = json_object_new_object();
746         json_object_object_add(obj, wm->kKeyDrawingName, json_object_new_string(app_name.c_str()));
747         json_object_object_add(obj, wm->kKeyDrawingArea, json_object_new_string("normal.full"));
748         wm->activateSurface(obj);
749
750         /* The mainloop here is a little subtle.  Redrawing will cause
751          * EGL to read events so we can just call
752          * wl_display_dispatch_pending() to handle any events that got
753          * queued up as a side effect. */
754         while (running) {
755                 wl_display_dispatch_pending(display.display);
756                 if(!gIsDraw) {
757                         usleep(100000);
758                         continue;
759                 }
760                 else
761                 {
762                         redraw(&window, NULL, 0);
763                 }
764         }
765
766         HMI_DEBUG("simple-egl","simple-egl exiting! ");
767
768         destroy_surface(&window);
769         fini_egl(&display);
770
771         if (display.ivi_application)
772                 ivi_application_destroy(display.ivi_application);
773
774         if (display.compositor)
775                 wl_compositor_destroy(display.compositor);
776
777         wl_registry_destroy(display.registry);
778         wl_display_flush(display.display);
779         wl_display_disconnect(display.display);
780
781         return 0;
782 }