blob: 1349c733dcaa907e292a5aa3f356928ce7f0c6a2 [file] [log] [blame]
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +09001/*
2 * Copyright (C) 2013 DENSO CORPORATION
3 *
Bryce Harrington1f6b0d12015-06-10 22:48:59 -07004 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +090010 *
Bryce Harrington1f6b0d12015-06-10 22:48:59 -070011 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +090022 */
23
Yong-iL Johcd9bb712015-11-17 16:28:11 +090024#include "config.h"
25
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +090026#include <sys/wait.h>
27#include <unistd.h>
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31#include <linux/input.h>
32#include <assert.h>
33#include <fcntl.h>
34#include <signal.h>
35#include <sys/mman.h>
36#include <getopt.h>
37#include <wayland-cursor.h>
Bill Spitzak2ccd9a22015-08-06 16:24:59 +010038#include <wayland-client-protocol.h>
Jon Cruz4678bab2015-06-15 15:37:07 -070039#include "shared/cairo-util.h"
40#include "shared/config-parser.h"
Jon Cruz35b2eaa2015-06-15 15:37:08 -070041#include "shared/helpers.h"
Jon Cruz4678bab2015-06-15 15:37:07 -070042#include "shared/os-compatibility.h"
Bryce Harrington0d1a6222016-02-11 16:42:49 -080043#include "shared/zalloc.h"
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +090044#include "ivi-application-client-protocol.h"
45#include "ivi-hmi-controller-client-protocol.h"
46
47/**
48 * A reference implementation how to use ivi-hmi-controller interface to
49 * interact with hmi-controller. This is launched from hmi-controller by using
50 * hmi_client_start and create a pthread.
51 *
52 * The basic flow is as followed,
53 * 1/ read configuration from weston.ini.
54 * 2/ draw png file to surface according to configuration of weston.ini
55 * 3/ set up UI by using ivi-hmi-controller protocol
56 * 4/ Enter event loop
57 * 5/ If a surface receives touch/pointer event, followings are invoked
58 * according to type of event and surface
59 * 5-1/ If a surface to launch ivi_application receive touch up, it execs
60 * ivi-application configured in weston.ini.
61 * 5-2/ If a surface to switch layout mode receive touch up, it sends a request,
62 * ivi_hmi_controller_switch_mode, to hmi-controller.
63 * 5-3/ If a surface to show workspace having launchers, it sends a request,
64 * ivi_hmi_controller_home, to hmi-controller.
65 * 5-4/ If touch down events happens in workspace,
66 * ivi_hmi_controller_workspace_control is sent to slide workspace.
67 * When control finished, event: ivi_hmi_controller_workspace_end_control
68 * is received.
69 */
70
71/*****************************************************************************
72 * structure, globals
73 ****************************************************************************/
74enum cursor_type {
75 CURSOR_BOTTOM_LEFT,
76 CURSOR_BOTTOM_RIGHT,
77 CURSOR_BOTTOM,
78 CURSOR_DRAGGING,
79 CURSOR_LEFT_PTR,
80 CURSOR_LEFT,
81 CURSOR_RIGHT,
82 CURSOR_TOP_LEFT,
83 CURSOR_TOP_RIGHT,
84 CURSOR_TOP,
85 CURSOR_IBEAM,
86 CURSOR_HAND1,
87 CURSOR_WATCH,
88
89 CURSOR_BLANK
90};
91struct wlContextCommon {
92 struct wl_display *wlDisplay;
93 struct wl_registry *wlRegistry;
94 struct wl_compositor *wlCompositor;
95 struct wl_shm *wlShm;
96 uint32_t formats;
97 struct wl_seat *wlSeat;
98 struct wl_pointer *wlPointer;
99 struct wl_touch *wlTouch;
100 struct ivi_application *iviApplication;
101 struct ivi_hmi_controller *hmiCtrl;
102 struct hmi_homescreen_setting *hmi_setting;
103 struct wl_list list_wlContextStruct;
104 struct wl_surface *enterSurface;
105 int32_t is_home_on;
106 struct wl_cursor_theme *cursor_theme;
107 struct wl_cursor **cursors;
108 struct wl_surface *pointer_surface;
109 enum cursor_type current_cursor;
110 uint32_t enter_serial;
111};
112
113struct wlContextStruct {
114 struct wlContextCommon *cmm;
115 struct wl_surface *wlSurface;
116 struct wl_buffer *wlBuffer;
117 cairo_surface_t *ctx_image;
118 void *data;
119 uint32_t id_surface;
120 struct wl_list link;
121};
122
123struct
124hmi_homescreen_srf {
125 uint32_t id;
126 char *filePath;
127 uint32_t color;
128};
129
130struct
131hmi_homescreen_workspace {
132 struct wl_array launcher_id_array;
133 struct wl_list link;
134};
135
136struct
137hmi_homescreen_launcher {
138 uint32_t icon_surface_id;
139 uint32_t workspace_id;
140 char *icon;
141 char *path;
142 struct wl_list link;
143};
144
145struct
146hmi_homescreen_setting {
147 struct hmi_homescreen_srf background;
148 struct hmi_homescreen_srf panel;
149 struct hmi_homescreen_srf tiling;
150 struct hmi_homescreen_srf sidebyside;
151 struct hmi_homescreen_srf fullscreen;
152 struct hmi_homescreen_srf random;
153 struct hmi_homescreen_srf home;
154 struct hmi_homescreen_srf workspace_background;
155
156 struct wl_list workspace_list;
157 struct wl_list launcher_list;
158
159 char *cursor_theme;
160 int32_t cursor_size;
161 uint32_t transition_duration;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900162 uint32_t surface_id_offset;
163 int32_t screen_num;
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +0900164};
165
166static void *
167fail_on_null(void *p, size_t size, char *file, int32_t line)
168{
169 if (size && !p) {
170 fprintf(stderr, "%s(%d) %zd: out of memory\n",
171 file, line, size);
172 exit(EXIT_FAILURE);
173 }
174
175 return p;
176}
177
178static void *
179mem_alloc(size_t size, char *file, int32_t line)
180{
Bryce Harrington0d1a6222016-02-11 16:42:49 -0800181 return fail_on_null(zalloc(size), size, file, line);
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +0900182}
183
184#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +0900185
186/*****************************************************************************
187 * Event Handler
188 ****************************************************************************/
189
190static void
191shm_format(void *data, struct wl_shm *pWlShm, uint32_t format)
192{
193 struct wlContextCommon *pCtx = data;
194
195 pCtx->formats |= (1 << format);
196}
197
198static struct wl_shm_listener shm_listenter = {
199 shm_format
200};
201
202static int32_t
203getIdOfWlSurface(struct wlContextCommon *pCtx, struct wl_surface *wlSurface)
204{
205 struct wlContextStruct *pWlCtxSt = NULL;
206
207 if (NULL == pCtx || NULL == wlSurface )
208 return 0;
209
210 wl_list_for_each(pWlCtxSt, &pCtx->list_wlContextStruct, link) {
211 if (pWlCtxSt->wlSurface == wlSurface)
212 return pWlCtxSt->id_surface;
213 }
214
215 return -1;
216}
217
218static void
219set_pointer_image(struct wlContextCommon *pCtx, uint32_t index)
220{
221 struct wl_cursor *cursor = NULL;
222 struct wl_cursor_image *image = NULL;
223 struct wl_buffer *buffer = NULL;
224
225 if (!pCtx->wlPointer || !pCtx->cursors)
226 return;
227
228 if (CURSOR_BLANK == pCtx->current_cursor) {
229 wl_pointer_set_cursor(pCtx->wlPointer, pCtx->enter_serial,
230 NULL, 0, 0);
231 return;
232 }
233
234 cursor = pCtx->cursors[pCtx->current_cursor];
235 if (!cursor)
236 return;
237
238 if (cursor->image_count <= index) {
239 fprintf(stderr, "cursor index out of range\n");
240 return;
241 }
242
243 image = cursor->images[index];
244 buffer = wl_cursor_image_get_buffer(image);
245
246 if (!buffer)
247 return;
248
249 wl_pointer_set_cursor(pCtx->wlPointer, pCtx->enter_serial,
250 pCtx->pointer_surface,
251 image->hotspot_x, image->hotspot_y);
252
253 wl_surface_attach(pCtx->pointer_surface, buffer, 0, 0);
254
255 wl_surface_damage(pCtx->pointer_surface, 0, 0,
256 image->width, image->height);
257
258 wl_surface_commit(pCtx->pointer_surface);
259}
260
261static void
262PointerHandleEnter(void *data, struct wl_pointer *wlPointer, uint32_t serial,
263 struct wl_surface *wlSurface, wl_fixed_t sx, wl_fixed_t sy)
264{
265 struct wlContextCommon *pCtx = data;
266
267 pCtx->enter_serial = serial;
268 pCtx->enterSurface = wlSurface;
269 set_pointer_image(pCtx, 0);
270#ifdef _DEBUG
271 printf("ENTER PointerHandleEnter: x(%d), y(%d)\n", sx, sy);
272#endif
273}
274
275static void
276PointerHandleLeave(void *data, struct wl_pointer *wlPointer, uint32_t serial,
277 struct wl_surface *wlSurface)
278{
279 struct wlContextCommon *pCtx = data;
280
281 pCtx->enterSurface = NULL;
282
283#ifdef _DEBUG
284 printf("ENTER PointerHandleLeave: serial(%d)\n", serial);
285#endif
286}
287
288static void
289PointerHandleMotion(void *data, struct wl_pointer *wlPointer, uint32_t time,
290 wl_fixed_t sx, wl_fixed_t sy)
291{
292#ifdef _DEBUG
293 printf("ENTER PointerHandleMotion: x(%d), y(%d)\n", sx, sy);
294#endif
295}
296
297/**
298 * if a surface assigned as launcher receives touch-off event, invoking
299 * ivi-application which configured in weston.ini with path to binary.
300 */
301extern char **environ; /*defied by libc */
302
303static pid_t
304execute_process(char *path, char *argv[])
305{
306 pid_t pid = fork();
307 if (pid < 0)
308 fprintf(stderr, "Failed to fork\n");
309
310 if (pid)
311 return pid;
312
313 if (-1 == execve(path, argv, environ)) {
314 fprintf(stderr, "Failed to execve %s\n", path);
315 exit(1);
316 }
317
318 return pid;
319}
320
321static int32_t
322launcher_button(uint32_t surfaceId, struct wl_list *launcher_list)
323{
324 struct hmi_homescreen_launcher *launcher = NULL;
325
326 wl_list_for_each(launcher, launcher_list, link) {
327 char *argv[] = { NULL };
328
329 if (surfaceId != launcher->icon_surface_id)
330 continue;
331
332 execute_process(launcher->path, argv);
333
334 return 1;
335 }
336
337 return 0;
338}
339
340/**
341 * is-method to identify a surface set as launcher in workspace or workspace
342 * itself. This is-method is used to decide whether request;
343 * ivi_hmi_controller_workspace_control is sent or not.
344 */
345static int32_t
346isWorkspaceSurface(uint32_t id, struct hmi_homescreen_setting *hmi_setting)
347{
348 struct hmi_homescreen_launcher *launcher = NULL;
349
350 if (id == hmi_setting->workspace_background.id)
351 return 1;
352
353 wl_list_for_each(launcher, &hmi_setting->launcher_list, link) {
354 if (id == launcher->icon_surface_id)
355 return 1;
356 }
357
358 return 0;
359}
360
361/**
362 * Decide which request is sent to hmi-controller
363 */
364static void
365touch_up(struct ivi_hmi_controller *hmi_ctrl, uint32_t id_surface,
366 int32_t *is_home_on, struct hmi_homescreen_setting *hmi_setting)
367{
368 if (launcher_button(id_surface, &hmi_setting->launcher_list)) {
369 *is_home_on = 0;
370 ivi_hmi_controller_home(hmi_ctrl, IVI_HMI_CONTROLLER_HOME_OFF);
371 } else if (id_surface == hmi_setting->tiling.id) {
372 ivi_hmi_controller_switch_mode(hmi_ctrl,
373 IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING);
374 } else if (id_surface == hmi_setting->sidebyside.id) {
375 ivi_hmi_controller_switch_mode(hmi_ctrl,
376 IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE);
377 } else if (id_surface == hmi_setting->fullscreen.id) {
378 ivi_hmi_controller_switch_mode(hmi_ctrl,
379 IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN);
380 } else if (id_surface == hmi_setting->random.id) {
381 ivi_hmi_controller_switch_mode(hmi_ctrl,
382 IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM);
383 } else if (id_surface == hmi_setting->home.id) {
384 *is_home_on = !(*is_home_on);
385 if (*is_home_on) {
386 ivi_hmi_controller_home(hmi_ctrl,
387 IVI_HMI_CONTROLLER_HOME_ON);
388 } else {
389 ivi_hmi_controller_home(hmi_ctrl,
390 IVI_HMI_CONTROLLER_HOME_OFF);
391 }
392 }
393}
394
395/**
396 * Even handler of Pointer event. IVI system is usually manipulated by touch
397 * screen. However, some systems also have pointer device.
398 * Release is the same behavior as touch off
399 * Pressed is the same behavior as touch on
400 */
401static void
402PointerHandleButton(void *data, struct wl_pointer *wlPointer, uint32_t serial,
403 uint32_t time, uint32_t button, uint32_t state)
404{
405 struct wlContextCommon *pCtx = data;
406 struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl;
407 const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface);
408
409 if (BTN_RIGHT == button)
410 return;
411
412 switch (state) {
413 case WL_POINTER_BUTTON_STATE_RELEASED:
414 touch_up(hmi_ctrl, id_surface, &pCtx->is_home_on,
415 pCtx->hmi_setting);
416 break;
417
418 case WL_POINTER_BUTTON_STATE_PRESSED:
419
420 if (isWorkspaceSurface(id_surface, pCtx->hmi_setting)) {
421 ivi_hmi_controller_workspace_control(hmi_ctrl,
422 pCtx->wlSeat,
423 serial);
424 }
425
426 break;
427 }
428#ifdef _DEBUG
429 printf("ENTER PointerHandleButton: button(%d), state(%d)\n",
430 button, state);
431#endif
432}
433
434static void
435PointerHandleAxis(void *data, struct wl_pointer *wlPointer, uint32_t time,
436 uint32_t axis, wl_fixed_t value)
437{
438#ifdef _DEBUG
439 printf("ENTER PointerHandleAxis: axis(%d), value(%d)\n", axis, value);
440#endif
441}
442
443static struct wl_pointer_listener pointer_listener = {
444 PointerHandleEnter,
445 PointerHandleLeave,
446 PointerHandleMotion,
447 PointerHandleButton,
448 PointerHandleAxis
449};
450
451/**
452 * Even handler of touch event
453 */
454static void
455TouchHandleDown(void *data, struct wl_touch *wlTouch, uint32_t serial,
456 uint32_t time, struct wl_surface *surface, int32_t id,
457 wl_fixed_t x_w, wl_fixed_t y_w)
458{
459 struct wlContextCommon *pCtx = data;
460 struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl;
461 uint32_t id_surface = 0;
462
463 if (0 == id)
464 pCtx->enterSurface = surface;
465
466 id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface);
467
468 /**
469 * When touch down happens on surfaces of workspace, ask
470 * hmi-controller to start control workspace to select page of
471 * workspace. After sending seat to hmi-controller by
472 * ivi_hmi_controller_workspace_control,
473 * hmi-controller-homescreen doesn't receive any event till
474 * hmi-controller sends back it.
475 */
476 if (isWorkspaceSurface(id_surface, pCtx->hmi_setting)) {
477 ivi_hmi_controller_workspace_control(hmi_ctrl, pCtx->wlSeat,
478 serial);
479 }
480}
481
482static void
483TouchHandleUp(void *data, struct wl_touch *wlTouch, uint32_t serial,
484 uint32_t time, int32_t id)
485{
486 struct wlContextCommon *pCtx = data;
487 struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl;
488
489 const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface);
490
491 /**
492 * triggering event according to touch-up happening on which surface.
493 */
494 if (id == 0){
495 touch_up(hmi_ctrl, id_surface, &pCtx->is_home_on,
496 pCtx->hmi_setting);
497 }
498}
499
500static void
501TouchHandleMotion(void *data, struct wl_touch *wlTouch, uint32_t time,
502 int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
503{
504}
505
506static void
507TouchHandleFrame(void *data, struct wl_touch *wlTouch)
508{
509}
510
511static void
512TouchHandleCancel(void *data, struct wl_touch *wlTouch)
513{
514}
515
516static struct wl_touch_listener touch_listener = {
517 TouchHandleDown,
518 TouchHandleUp,
519 TouchHandleMotion,
520 TouchHandleFrame,
521 TouchHandleCancel,
522};
523
524/**
525 * Handler of capabilities
526 */
527static void
528seat_handle_capabilities(void *data, struct wl_seat *seat, uint32_t caps)
529{
530 struct wlContextCommon *p_wlCtx = (struct wlContextCommon*)data;
531 struct wl_seat *wlSeat = p_wlCtx->wlSeat;
532 struct wl_pointer *wlPointer = p_wlCtx->wlPointer;
533 struct wl_touch *wlTouch = p_wlCtx->wlTouch;
534
535 if (p_wlCtx->hmi_setting->cursor_theme) {
536 if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wlPointer){
537 wlPointer = wl_seat_get_pointer(wlSeat);
538 wl_pointer_add_listener(wlPointer,
539 &pointer_listener, data);
540 } else
541 if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wlPointer){
542 wl_pointer_destroy(wlPointer);
543 wlPointer = NULL;
544 }
545 p_wlCtx->wlPointer = wlPointer;
546 }
547
548 if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !wlTouch){
549 wlTouch = wl_seat_get_touch(wlSeat);
550 wl_touch_add_listener(wlTouch, &touch_listener, data);
551 } else
552 if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && wlTouch){
553 wl_touch_destroy(wlTouch);
554 wlTouch = NULL;
555 }
556 p_wlCtx->wlTouch = wlTouch;
557}
558
559static struct wl_seat_listener seat_Listener = {
560 seat_handle_capabilities,
561};
562
563/**
564 * Registration of event
565 * This event is received when hmi-controller server finished controlling
566 * workspace.
567 */
568static void
569ivi_hmi_controller_workspace_end_control(void *data,
570 struct ivi_hmi_controller *hmi_ctrl,
571 int32_t is_controlled)
572{
573 struct wlContextCommon *pCtx = data;
574 const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface);
575
576 if (is_controlled)
577 return;
578
579 /**
580 * During being controlled by hmi-controller, any input event is not
581 * notified. So when control ends with touch up, it invokes launcher
582 * if up event happens on a launcher surface.
583 *
584 */
585 if (launcher_button(id_surface, &pCtx->hmi_setting->launcher_list)) {
586 pCtx->is_home_on = 0;
587 ivi_hmi_controller_home(hmi_ctrl, IVI_HMI_CONTROLLER_HOME_OFF);
588 }
589}
590
591static const struct ivi_hmi_controller_listener hmi_controller_listener = {
592 ivi_hmi_controller_workspace_end_control
593};
594
595/**
596 * Registration of interfaces
597 */
598static void
599registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
600 const char *interface, uint32_t version)
601{
602 struct wlContextCommon *p_wlCtx = (struct wlContextCommon*)data;
603
604 if (!strcmp(interface, "wl_compositor")) {
605 p_wlCtx->wlCompositor =
606 wl_registry_bind(registry, name,
607 &wl_compositor_interface, 1);
608 } else if (!strcmp(interface, "wl_shm")) {
609 p_wlCtx->wlShm =
610 wl_registry_bind(registry, name, &wl_shm_interface, 1);
611 wl_shm_add_listener(p_wlCtx->wlShm, &shm_listenter, p_wlCtx);
612 } else if (!strcmp(interface, "wl_seat")) {
613 p_wlCtx->wlSeat =
614 wl_registry_bind(registry, name, &wl_seat_interface, 1);
615 wl_seat_add_listener(p_wlCtx->wlSeat, &seat_Listener, data);
616 } else if (!strcmp(interface, "ivi_application")) {
617 p_wlCtx->iviApplication =
618 wl_registry_bind(registry, name,
619 &ivi_application_interface, 1);
620 } else if (!strcmp(interface, "ivi_hmi_controller")) {
621 p_wlCtx->hmiCtrl =
622 wl_registry_bind(registry, name,
623 &ivi_hmi_controller_interface, 1);
624
625 ivi_hmi_controller_add_listener(p_wlCtx->hmiCtrl,
626 &hmi_controller_listener, p_wlCtx);
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +0900627 } else if (!strcmp(interface, "wl_output")) {
628 p_wlCtx->hmi_setting->screen_num++;
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +0900629 }
630}
631
632static void
633registry_handle_global_remove(void *data, struct wl_registry *registry,
634 uint32_t name)
635{
636}
637
638static const struct wl_registry_listener registry_listener = {
639 registry_handle_global,
640 registry_handle_global_remove
641};
642
643static void
644frame_listener_func(void *data, struct wl_callback *callback, uint32_t time)
645{
646 if (callback)
647 wl_callback_destroy(callback);
648}
649
650static const struct wl_callback_listener frame_listener = {
651 frame_listener_func
652};
653
654/*
655 * The following correspondences between file names and cursors was copied
656 * from: https://bugs.kde.org/attachment.cgi?id=67313
657 */
658static const char *bottom_left_corners[] = {
659 "bottom_left_corner",
660 "sw-resize",
661 "size_bdiag"
662};
663
664static const char *bottom_right_corners[] = {
665 "bottom_right_corner",
666 "se-resize",
667 "size_fdiag"
668};
669
670static const char *bottom_sides[] = {
671 "bottom_side",
672 "s-resize",
673 "size_ver"
674};
675
676static const char *grabbings[] = {
677 "grabbing",
678 "closedhand",
679 "208530c400c041818281048008011002"
680};
681
682static const char *left_ptrs[] = {
683 "left_ptr",
684 "default",
685 "top_left_arrow",
686 "left-arrow"
687};
688
689static const char *left_sides[] = {
690 "left_side",
691 "w-resize",
692 "size_hor"
693};
694
695static const char *right_sides[] = {
696 "right_side",
697 "e-resize",
698 "size_hor"
699};
700
701static const char *top_left_corners[] = {
702 "top_left_corner",
703 "nw-resize",
704 "size_fdiag"
705};
706
707static const char *top_right_corners[] = {
708 "top_right_corner",
709 "ne-resize",
710 "size_bdiag"
711};
712
713static const char *top_sides[] = {
714 "top_side",
715 "n-resize",
716 "size_ver"
717};
718
719static const char *xterms[] = {
720 "xterm",
721 "ibeam",
722 "text"
723};
724
725static const char *hand1s[] = {
726 "hand1",
727 "pointer",
728 "pointing_hand",
729 "e29285e634086352946a0e7090d73106"
730};
731
732static const char *watches[] = {
733 "watch",
734 "wait",
735 "0426c94ea35c87780ff01dc239897213"
736};
737
738struct cursor_alternatives {
739 const char **names;
740 size_t count;
741};
742
743static const struct cursor_alternatives cursors[] = {
744 { bottom_left_corners, ARRAY_LENGTH(bottom_left_corners) },
745 { bottom_right_corners, ARRAY_LENGTH(bottom_right_corners) },
746 { bottom_sides, ARRAY_LENGTH(bottom_sides) },
747 { grabbings, ARRAY_LENGTH(grabbings) },
748 { left_ptrs, ARRAY_LENGTH(left_ptrs) },
749 { left_sides, ARRAY_LENGTH(left_sides) },
750 { right_sides, ARRAY_LENGTH(right_sides) },
751 { top_left_corners, ARRAY_LENGTH(top_left_corners) },
752 { top_right_corners, ARRAY_LENGTH(top_right_corners) },
753 { top_sides, ARRAY_LENGTH(top_sides) },
754 { xterms, ARRAY_LENGTH(xterms) },
755 { hand1s, ARRAY_LENGTH(hand1s) },
756 { watches, ARRAY_LENGTH(watches) },
757};
758
759static void
760create_cursors(struct wlContextCommon *cmm)
761{
762 uint32_t i = 0;
763 uint32_t j = 0;
764 struct wl_cursor *cursor = NULL;
765 char *cursor_theme = cmm->hmi_setting->cursor_theme;
766 int32_t cursor_size = cmm->hmi_setting->cursor_size;
767
768 cmm->cursor_theme = wl_cursor_theme_load(cursor_theme, cursor_size,
769 cmm->wlShm);
770
771 cmm->cursors =
772 MEM_ALLOC(ARRAY_LENGTH(cursors) * sizeof(cmm->cursors[0]));
773
774 for (i = 0; i < ARRAY_LENGTH(cursors); i++) {
775 cursor = NULL;
776
777 for (j = 0; !cursor && j < cursors[i].count; ++j) {
778 cursor = wl_cursor_theme_get_cursor(
779 cmm->cursor_theme, cursors[i].names[j]);
780 }
781
782 if (!cursor) {
783 fprintf(stderr, "could not load cursor '%s'\n",
784 cursors[i].names[0]);
785 }
786
787 cmm->cursors[i] = cursor;
788 }
789}
790
791static void
792destroy_cursors(struct wlContextCommon *cmm)
793{
794 if (cmm->cursor_theme)
795 wl_cursor_theme_destroy(cmm->cursor_theme);
796
797 free(cmm->cursors);
798}
799
800/**
801 * Internal method to prepare parts of UI
802 */
803static void
804createShmBuffer(struct wlContextStruct *p_wlCtx)
805{
806 struct wl_shm_pool *pool;
807
808 int fd = -1;
809 int size = 0;
810 int width = 0;
811 int height = 0;
812 int stride = 0;
813
814 width = cairo_image_surface_get_width(p_wlCtx->ctx_image);
815 height = cairo_image_surface_get_height(p_wlCtx->ctx_image);
816 stride = cairo_image_surface_get_stride(p_wlCtx->ctx_image);
817
818 size = stride * height;
819
820 fd = os_create_anonymous_file(size);
821 if (fd < 0) {
822 fprintf(stderr, "creating a buffer file for %d B failed: %m\n",
823 size);
824 return ;
825 }
826
827 p_wlCtx->data =
828 mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
829
830 if (MAP_FAILED == p_wlCtx->data) {
831 fprintf(stderr, "mmap failed: %m\n");
832 close(fd);
833 return;
834 }
835
836 pool = wl_shm_create_pool(p_wlCtx->cmm->wlShm, fd, size);
837 p_wlCtx->wlBuffer = wl_shm_pool_create_buffer(pool, 0,
838 width,
839 height,
840 stride,
841 WL_SHM_FORMAT_ARGB8888);
842
843 if (NULL == p_wlCtx->wlBuffer) {
844 fprintf(stderr, "wl_shm_create_buffer failed: %m\n");
845 close(fd);
846 return;
847 }
848
849 wl_shm_pool_destroy(pool);
850 close(fd);
851}
852
853static void
854destroyWLContextCommon(struct wlContextCommon *p_wlCtx)
855{
856 destroy_cursors(p_wlCtx);
857
858 if (p_wlCtx->pointer_surface)
859 wl_surface_destroy(p_wlCtx->pointer_surface);
860
861 if (p_wlCtx->wlCompositor)
862 wl_compositor_destroy(p_wlCtx->wlCompositor);
863}
864
865static void
866destroyWLContextStruct(struct wlContextStruct *p_wlCtx)
867{
868 if (p_wlCtx->wlSurface)
869 wl_surface_destroy(p_wlCtx->wlSurface);
870
871 if (p_wlCtx->ctx_image) {
872 cairo_surface_destroy(p_wlCtx->ctx_image);
873 p_wlCtx->ctx_image = NULL;
874 }
875}
876
877static int
878createSurface(struct wlContextStruct *p_wlCtx)
879{
880 p_wlCtx->wlSurface =
881 wl_compositor_create_surface(p_wlCtx->cmm->wlCompositor);
882 if (NULL == p_wlCtx->wlSurface) {
883 printf("Error: wl_compositor_create_surface failed.\n");
884 destroyWLContextCommon(p_wlCtx->cmm);
885 abort();
886 }
887
888 return 0;
889}
890
891static void
892drawImage(struct wlContextStruct *p_wlCtx)
893{
894 struct wl_callback *callback;
895
896 int width = 0;
897 int height = 0;
898 int stride = 0;
899 void *data = NULL;
900
901 width = cairo_image_surface_get_width(p_wlCtx->ctx_image);
902 height = cairo_image_surface_get_height(p_wlCtx->ctx_image);
903 stride = cairo_image_surface_get_stride(p_wlCtx->ctx_image);
904 data = cairo_image_surface_get_data(p_wlCtx->ctx_image);
905
906 memcpy(p_wlCtx->data, data, stride * height);
907
908 wl_surface_attach(p_wlCtx->wlSurface, p_wlCtx->wlBuffer, 0, 0);
909 wl_surface_damage(p_wlCtx->wlSurface, 0, 0, width, height);
910
911 callback = wl_surface_frame(p_wlCtx->wlSurface);
912 wl_callback_add_listener(callback, &frame_listener, NULL);
913
914 wl_surface_commit(p_wlCtx->wlSurface);
915}
916
917static void
918create_ivisurface(struct wlContextStruct *p_wlCtx,
919 uint32_t id_surface,
920 cairo_surface_t *surface)
921{
922 struct ivi_surface *ivisurf = NULL;
923
924 p_wlCtx->ctx_image = surface;
925
926 p_wlCtx->id_surface = id_surface;
927 wl_list_init(&p_wlCtx->link);
928 wl_list_insert(&p_wlCtx->cmm->list_wlContextStruct, &p_wlCtx->link);
929
930 createSurface(p_wlCtx);
931 createShmBuffer(p_wlCtx);
932
933 ivisurf = ivi_application_surface_create(p_wlCtx->cmm->iviApplication,
934 id_surface,
935 p_wlCtx->wlSurface);
936 if (ivisurf == NULL) {
937 fprintf(stderr, "Failed to create ivi_client_surface\n");
938 return;
939 }
940
941 drawImage(p_wlCtx);
942}
943
944static void
945create_ivisurfaceFromFile(struct wlContextStruct *p_wlCtx,
946 uint32_t id_surface,
947 const char *imageFile)
948{
949 cairo_surface_t *surface = load_cairo_surface(imageFile);
950
951 if (NULL == surface) {
952 fprintf(stderr, "Failed to load_cairo_surface %s\n", imageFile);
953 return;
954 }
955
956 create_ivisurface(p_wlCtx, id_surface, surface);
957}
958
959static void
960set_hex_color(cairo_t *cr, uint32_t color)
961{
962 cairo_set_source_rgba(cr,
963 ((color >> 16) & 0xff) / 255.0,
964 ((color >> 8) & 0xff) / 255.0,
965 ((color >> 0) & 0xff) / 255.0,
966 ((color >> 24) & 0xff) / 255.0);
967}
968
969static void
970create_ivisurfaceFromColor(struct wlContextStruct *p_wlCtx,
971 uint32_t id_surface,
972 uint32_t width, uint32_t height,
973 uint32_t color)
974{
975 cairo_surface_t *surface = NULL;
976 cairo_t *cr = NULL;
977
978 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
979 width, height);
980
981 cr = cairo_create(surface);
982 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
983 cairo_rectangle(cr, 0, 0, width, height);
984 set_hex_color(cr, color);
985 cairo_fill(cr);
986 cairo_destroy(cr);
987
988 create_ivisurface(p_wlCtx, id_surface, surface);
989}
990
991static void
992UI_ready(struct ivi_hmi_controller *controller)
993{
994 ivi_hmi_controller_UI_ready(controller);
995}
996
997/**
998 * Internal method to set up UI by using ivi-hmi-controller
999 */
1000static void
1001create_background(struct wlContextStruct *p_wlCtx, const uint32_t id_surface,
1002 const char *imageFile)
1003{
1004 create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
1005}
1006
1007static void
1008create_panel(struct wlContextStruct *p_wlCtx, const uint32_t id_surface,
1009 const char *imageFile)
1010{
1011 create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
1012}
1013
1014static void
1015create_button(struct wlContextStruct *p_wlCtx, const uint32_t id_surface,
1016 const char *imageFile, uint32_t number)
1017{
1018 create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
1019}
1020
1021static void
1022create_home_button(struct wlContextStruct *p_wlCtx, const uint32_t id_surface,
1023 const char *imageFile)
1024{
1025 create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
1026}
1027
1028static void
1029create_workspace_background(struct wlContextStruct *p_wlCtx,
1030 struct hmi_homescreen_srf *srf)
1031{
1032 create_ivisurfaceFromColor(p_wlCtx, srf->id, 1, 1, srf->color);
1033}
1034
1035static void
1036create_launchers(struct wlContextCommon *cmm, struct wl_list *launcher_list)
1037{
1038 struct hmi_homescreen_launcher **launchers;
1039 struct hmi_homescreen_launcher *launcher = NULL;
1040
1041 int launcher_count = wl_list_length(launcher_list);
1042 int ii = 0;
1043 int start = 0;
1044
1045 if (0 == launcher_count)
1046 return;
1047
1048 launchers = MEM_ALLOC(launcher_count * sizeof(*launchers));
1049
1050 wl_list_for_each(launcher, launcher_list, link) {
1051 launchers[ii] = launcher;
1052 ii++;
1053 }
1054
1055 for (ii = 0; ii < launcher_count; ii++) {
1056 int jj = 0;
1057
1058 if (ii != launcher_count - 1 &&
1059 launchers[ii]->workspace_id ==
1060 launchers[ii + 1]->workspace_id)
1061 continue;
1062
1063 for (jj = start; jj <= ii; jj++) {
1064 struct wlContextStruct *p_wlCtx;
1065
1066 p_wlCtx = MEM_ALLOC(sizeof(*p_wlCtx));
1067 p_wlCtx->cmm = cmm;
1068 create_ivisurfaceFromFile(p_wlCtx,
1069 launchers[jj]->icon_surface_id,
1070 launchers[jj]->icon);
1071 }
1072
1073 start = ii + 1;
1074 }
1075
1076 free(launchers);
1077}
1078
1079/**
1080 * Internal method to read out weston.ini to get configuration
1081 */
1082static struct hmi_homescreen_setting *
1083hmi_homescreen_setting_create(void)
1084{
Pekka Paalanen6c71aae2015-03-24 15:56:19 +02001085 const char *config_file;
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +09001086 struct weston_config *config = NULL;
1087 struct weston_config_section *shellSection = NULL;
1088 struct hmi_homescreen_setting *setting = MEM_ALLOC(sizeof(*setting));
1089 struct weston_config_section *section = NULL;
1090 const char *name = NULL;
1091 uint32_t workspace_layer_id;
1092 uint32_t icon_surface_id = 0;
1093
1094 wl_list_init(&setting->workspace_list);
1095 wl_list_init(&setting->launcher_list);
1096
Pekka Paalanen6c71aae2015-03-24 15:56:19 +02001097 config_file = weston_config_get_name_from_env();
1098 config = weston_config_parse(config_file);
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +09001099
1100 shellSection =
1101 weston_config_get_section(config, "ivi-shell", NULL, NULL);
1102
1103 weston_config_section_get_string(
1104 shellSection, "cursor-theme", &setting->cursor_theme, NULL);
1105
1106 weston_config_section_get_int(
1107 shellSection, "cursor-size", &setting->cursor_size, 32);
1108
1109 weston_config_section_get_uint(
1110 shellSection, "workspace-layer-id", &workspace_layer_id, 3000);
1111
1112 weston_config_section_get_string(
1113 shellSection, "background-image", &setting->background.filePath,
1114 DATADIR "/weston/background.png");
1115
1116 weston_config_section_get_uint(
1117 shellSection, "background-id", &setting->background.id, 1001);
1118
1119 weston_config_section_get_string(
1120 shellSection, "panel-image", &setting->panel.filePath,
1121 DATADIR "/weston/panel.png");
1122
1123 weston_config_section_get_uint(
1124 shellSection, "panel-id", &setting->panel.id, 1002);
1125
1126 weston_config_section_get_string(
1127 shellSection, "tiling-image", &setting->tiling.filePath,
1128 DATADIR "/weston/tiling.png");
1129
1130 weston_config_section_get_uint(
1131 shellSection, "tiling-id", &setting->tiling.id, 1003);
1132
1133 weston_config_section_get_string(
1134 shellSection, "sidebyside-image", &setting->sidebyside.filePath,
1135 DATADIR "/weston/sidebyside.png");
1136
1137 weston_config_section_get_uint(
1138 shellSection, "sidebyside-id", &setting->sidebyside.id, 1004);
1139
1140 weston_config_section_get_string(
1141 shellSection, "fullscreen-image", &setting->fullscreen.filePath,
1142 DATADIR "/weston/fullscreen.png");
1143
1144 weston_config_section_get_uint(
1145 shellSection, "fullscreen-id", &setting->fullscreen.id, 1005);
1146
1147 weston_config_section_get_string(
1148 shellSection, "random-image", &setting->random.filePath,
1149 DATADIR "/weston/random.png");
1150
1151 weston_config_section_get_uint(
1152 shellSection, "random-id", &setting->random.id, 1006);
1153
1154 weston_config_section_get_string(
1155 shellSection, "home-image", &setting->home.filePath,
1156 DATADIR "/weston/home.png");
1157
1158 weston_config_section_get_uint(
1159 shellSection, "home-id", &setting->home.id, 1007);
1160
1161 weston_config_section_get_uint(
1162 shellSection, "workspace-background-color",
1163 &setting->workspace_background.color, 0x99000000);
1164
1165 weston_config_section_get_uint(
1166 shellSection, "workspace-background-id",
1167 &setting->workspace_background.id, 2001);
1168
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001169 weston_config_section_get_uint(
1170 shellSection, "surface-id-offset", &setting->surface_id_offset, 10);
1171
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +09001172 icon_surface_id = workspace_layer_id + 1;
1173
1174 while (weston_config_next_section(config, &section, &name)) {
1175 struct hmi_homescreen_launcher *launcher;
1176
1177 if (strcmp(name, "ivi-launcher") != 0)
1178 continue;
1179
1180 launcher = MEM_ALLOC(sizeof(*launcher));
1181 wl_list_init(&launcher->link);
1182
1183 weston_config_section_get_string(section, "icon",
1184 &launcher->icon, NULL);
1185 weston_config_section_get_string(section, "path",
1186 &launcher->path, NULL);
1187 weston_config_section_get_uint(section, "workspace-id",
1188 &launcher->workspace_id, 0);
1189 weston_config_section_get_uint(section, "icon-id",
1190 &launcher->icon_surface_id,
1191 icon_surface_id);
1192 icon_surface_id++;
1193
1194 wl_list_insert(setting->launcher_list.prev, &launcher->link);
1195 }
1196
1197 weston_config_destroy(config);
1198 return setting;
1199}
1200
1201/**
1202 * Main thread
1203 *
1204 * The basic flow are as followed,
1205 * 1/ read configuration from weston.ini by hmi_homescreen_setting_create
1206 * 2/ draw png file to surface according to configuration of weston.ini and
1207 * set up UI by using ivi-hmi-controller protocol by each create_* method
1208 */
1209int main(int argc, char **argv)
1210{
1211 struct wlContextCommon wlCtxCommon;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001212 struct wlContextStruct *wlCtx_BackGround;
1213 struct wlContextStruct *wlCtx_Panel;
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +09001214 struct wlContextStruct wlCtx_Button_1;
1215 struct wlContextStruct wlCtx_Button_2;
1216 struct wlContextStruct wlCtx_Button_3;
1217 struct wlContextStruct wlCtx_Button_4;
1218 struct wlContextStruct wlCtx_HomeButton;
1219 struct wlContextStruct wlCtx_WorkSpaceBackGround;
1220 struct wl_list launcher_wlCtxList;
1221 int ret = 0;
1222 struct hmi_homescreen_setting *hmi_setting;
1223 struct wlContextStruct *pWlCtxSt = NULL;
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001224 int i = 0;
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +09001225
1226 hmi_setting = hmi_homescreen_setting_create();
1227
1228 memset(&wlCtxCommon, 0x00, sizeof(wlCtxCommon));
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +09001229 memset(&wlCtx_Button_1, 0x00, sizeof(wlCtx_Button_1));
1230 memset(&wlCtx_Button_2, 0x00, sizeof(wlCtx_Button_2));
1231 memset(&wlCtx_Button_3, 0x00, sizeof(wlCtx_Button_3));
1232 memset(&wlCtx_Button_4, 0x00, sizeof(wlCtx_Button_4));
1233 memset(&wlCtx_HomeButton, 0x00, sizeof(wlCtx_HomeButton));
1234 memset(&wlCtx_WorkSpaceBackGround, 0x00,
1235 sizeof(wlCtx_WorkSpaceBackGround));
1236 wl_list_init(&launcher_wlCtxList);
1237 wl_list_init(&wlCtxCommon.list_wlContextStruct);
1238
1239 wlCtxCommon.hmi_setting = hmi_setting;
1240
1241 wlCtxCommon.wlDisplay = wl_display_connect(NULL);
1242 if (NULL == wlCtxCommon.wlDisplay) {
1243 printf("Error: wl_display_connect failed.\n");
1244 return -1;
1245 }
1246
1247 /* get wl_registry */
1248 wlCtxCommon.formats = 0;
1249 wlCtxCommon.wlRegistry = wl_display_get_registry(wlCtxCommon.wlDisplay);
1250 wl_registry_add_listener(wlCtxCommon.wlRegistry,
1251 &registry_listener, &wlCtxCommon);
1252 wl_display_roundtrip(wlCtxCommon.wlDisplay);
1253
1254 if (wlCtxCommon.wlShm == NULL) {
1255 fprintf(stderr, "No wl_shm global\n");
1256 exit(1);
1257 }
1258
1259 wl_display_roundtrip(wlCtxCommon.wlDisplay);
1260
1261 if (!(wlCtxCommon.formats & (1 << WL_SHM_FORMAT_XRGB8888))) {
1262 fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n");
1263 exit(1);
1264 }
1265
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001266 wlCtx_BackGround = MEM_ALLOC(hmi_setting->screen_num * sizeof(struct wlContextStruct));
1267 wlCtx_Panel= MEM_ALLOC(hmi_setting->screen_num * sizeof(struct wlContextStruct));
1268
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +09001269 if (wlCtxCommon.hmi_setting->cursor_theme) {
1270 create_cursors(&wlCtxCommon);
1271
1272 wlCtxCommon.pointer_surface =
1273 wl_compositor_create_surface(wlCtxCommon.wlCompositor);
1274
1275 wlCtxCommon.current_cursor = CURSOR_LEFT_PTR;
1276 }
1277
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +09001278 wlCtx_Button_1.cmm = &wlCtxCommon;
1279 wlCtx_Button_2.cmm = &wlCtxCommon;
1280 wlCtx_Button_3.cmm = &wlCtxCommon;
1281 wlCtx_Button_4.cmm = &wlCtxCommon;
1282 wlCtx_HomeButton.cmm = &wlCtxCommon;
1283 wlCtx_WorkSpaceBackGround.cmm = &wlCtxCommon;
1284
1285 /* create desktop widgets */
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001286 for (i = 0; i < hmi_setting->screen_num; i++) {
1287 wlCtx_BackGround[i].cmm = &wlCtxCommon;
1288 create_background(&wlCtx_BackGround[i],
1289 hmi_setting->background.id +
1290 (i * hmi_setting->surface_id_offset),
1291 hmi_setting->background.filePath);
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +09001292
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001293 wlCtx_Panel[i].cmm = &wlCtxCommon;
1294 create_panel(&wlCtx_Panel[i],
1295 hmi_setting->panel.id + (i * hmi_setting->surface_id_offset),
1296 hmi_setting->panel.filePath);
1297 }
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +09001298
1299 create_button(&wlCtx_Button_1, hmi_setting->tiling.id,
1300 hmi_setting->tiling.filePath, 0);
1301
1302 create_button(&wlCtx_Button_2, hmi_setting->sidebyside.id,
1303 hmi_setting->sidebyside.filePath, 1);
1304
1305 create_button(&wlCtx_Button_3, hmi_setting->fullscreen.id,
1306 hmi_setting->fullscreen.filePath, 2);
1307
1308 create_button(&wlCtx_Button_4, hmi_setting->random.id,
1309 hmi_setting->random.filePath, 3);
1310
1311 create_workspace_background(&wlCtx_WorkSpaceBackGround,
1312 &hmi_setting->workspace_background);
1313
1314 create_launchers(&wlCtxCommon, &hmi_setting->launcher_list);
1315
1316 create_home_button(&wlCtx_HomeButton, hmi_setting->home.id,
1317 hmi_setting->home.filePath);
1318
1319 UI_ready(wlCtxCommon.hmiCtrl);
1320
Dawid Gajownik74a635b2015-08-06 17:12:19 -03001321 while (ret != -1)
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +09001322 ret = wl_display_dispatch(wlCtxCommon.wlDisplay);
1323
1324 wl_list_for_each(pWlCtxSt, &wlCtxCommon.list_wlContextStruct, link) {
1325 destroyWLContextStruct(pWlCtxSt);
1326 }
1327
Nobuhiko Tanibata2e656762015-12-09 15:41:46 +09001328 free(wlCtx_BackGround);
1329 free(wlCtx_Panel);
1330
Nobuhiko Tanibata923bc142014-11-27 13:23:32 +09001331 destroyWLContextCommon(&wlCtxCommon);
1332
1333 return 0;
1334}