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