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