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