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