1 From 9e55f4f9c921782263b784e7f6e0e9b0fc9095ca Mon Sep 17 00:00:00 2001
2 From: Manuel Bachmann <manuel.bachmann@iot.bzh>
3 Date: Mon, 28 Sep 2015 04:45:19 +0200
4 Subject: [PATCH] Backport IVI-Shell from Weston 1.9.0 to 1.5.0
6 IVI-Shell is the alternative Weston shell implementing the
7 eponymous protocol, and supported in client toolkits such
10 We backport only the necessary, without touching the core
11 compositor if possible (was only necessary for surface
12 copying logic which had a patch in Tizen IVI).
14 Signed-off-by: Manuel Bachmann <manuel.bachmann@iot.bzh>
17 clients/ivi-shell-user-interface.c | 1312 ++++++++++++++++
18 clients/simple-egl.c | 78 +-
19 clients/simple-shm.c | 37 +
20 clients/window.c | 57 +-
22 data/background.png | Bin 0 -> 245579 bytes
23 data/fullscreen.png | Bin 0 -> 3406 bytes
24 data/home.png | Bin 0 -> 4629 bytes
25 data/icon_ivi_clickdot.png | Bin 0 -> 39523 bytes
26 data/icon_ivi_flower.png | Bin 0 -> 24475 bytes
27 data/icon_ivi_simple-egl.png | Bin 0 -> 29316 bytes
28 data/icon_ivi_simple-shm.png | Bin 0 -> 71120 bytes
29 data/icon_ivi_smoke.png | Bin 0 -> 46577 bytes
30 data/panel.png | Bin 0 -> 41955 bytes
31 data/random.png | Bin 0 -> 4891 bytes
32 data/sidebyside.png | Bin 0 -> 3929 bytes
33 data/tiling.png | Bin 0 -> 5620 bytes
34 ivi-shell/hmi-controller.c | 1814 ++++++++++++++++++++++
35 ivi-shell/input-panel-ivi.c | 397 +++++
36 ivi-shell/ivi-layout-export.h | 813 ++++++++++
37 ivi-shell/ivi-layout-private.h | 229 +++
38 ivi-shell/ivi-layout-transition.c | 871 +++++++++++
39 ivi-shell/ivi-layout.c | 3011 ++++++++++++++++++++++++++++++++++++
40 ivi-shell/ivi-shell.c | 469 ++++++
41 ivi-shell/ivi-shell.h | 67 +
42 ivi-shell/weston.ini.in | 98 ++
43 protocol/ivi-application.xml | 100 ++
44 protocol/ivi-hmi-controller.xml | 98 ++
45 shared/helpers.h | 96 ++
46 src/compositor.c | 48 +
47 src/compositor.h | 20 +
48 src/gl-renderer.c | 150 ++
49 src/pixman-renderer.c | 51 +
50 34 files changed, 9915 insertions(+), 23 deletions(-)
51 create mode 100644 clients/ivi-shell-user-interface.c
52 create mode 100644 data/background.png
53 create mode 100644 data/fullscreen.png
54 create mode 100644 data/home.png
55 create mode 100644 data/icon_ivi_clickdot.png
56 create mode 100644 data/icon_ivi_flower.png
57 create mode 100644 data/icon_ivi_simple-egl.png
58 create mode 100644 data/icon_ivi_simple-shm.png
59 create mode 100644 data/icon_ivi_smoke.png
60 create mode 100644 data/panel.png
61 create mode 100644 data/random.png
62 create mode 100644 data/sidebyside.png
63 create mode 100644 data/tiling.png
64 create mode 100644 ivi-shell/hmi-controller.c
65 create mode 100644 ivi-shell/input-panel-ivi.c
66 create mode 100644 ivi-shell/ivi-layout-export.h
67 create mode 100644 ivi-shell/ivi-layout-private.h
68 create mode 100644 ivi-shell/ivi-layout-transition.c
69 create mode 100644 ivi-shell/ivi-layout.c
70 create mode 100644 ivi-shell/ivi-shell.c
71 create mode 100644 ivi-shell/ivi-shell.h
72 create mode 100644 ivi-shell/weston.ini.in
73 create mode 100644 protocol/ivi-application.xml
74 create mode 100644 protocol/ivi-hmi-controller.xml
75 create mode 100644 shared/helpers.h
77 diff --git a/Makefile.am b/Makefile.am
78 index 343adc6..7649d7d 100644
81 @@ -8,7 +8,7 @@ BUILT_SOURCES =
83 DISTCHECK_CONFIGURE_FLAGS = --disable-setuid-install
85 -EXTRA_DIST = weston.ini.in
86 +EXTRA_DIST = weston.ini.in ivi-shell/weston.ini.in
88 weston.ini : $(srcdir)/weston.ini.in
90 @@ -17,7 +17,16 @@ weston.ini : $(srcdir)/weston.ini.in
91 -e 's|@libexecdir[@]|$(libexecdir)|g' \
94 -all-local : weston.ini
95 +ivi-shell/weston.ini : $(srcdir)/ivi-shell/weston.ini.in
97 + -e 's|@bindir[@]|$(bindir)|g' \
98 + -e 's|@abs_top_builddir[@]|$(abs_top_builddir)|g' \
99 + -e 's|@abs_top_srcdir[@]|$(abs_top_srcdir)|g' \
100 + -e 's|@libexecdir[@]|$(libexecdir)|g' \
101 + -e 's|@plugin_prefix[@]||g' \
104 +all-local : weston.ini ivi-shell/weston.ini
106 AM_CFLAGS = $(GCC_CFLAGS)
108 @@ -33,7 +42,7 @@ AM_CPPFLAGS = \
109 -DLIBEXECDIR='"$(libexecdir)"' \
110 -DBINDIR='"$(bindir)"'
112 -CLEANFILES = weston.ini $(BUILT_SOURCES)
113 +CLEANFILES = weston.ini ivi-shell/weston.ini $(BUILT_SOURCES)
115 bin_PROGRAMS += weston
117 @@ -361,6 +370,11 @@ libexec_PROGRAMS += \
122 +libexec_PROGRAMS += \
123 + weston-ivi-shell-user-interface
129 @@ -394,7 +408,9 @@ nodist_weston_simple_shm_SOURCES = \
130 protocol/xdg-shell-protocol.c \
131 protocol/xdg-shell-client-protocol.h \
132 protocol/fullscreen-shell-protocol.c \
133 - protocol/fullscreen-shell-client-protocol.h
134 + protocol/fullscreen-shell-client-protocol.h \
135 + protocol/ivi-application-protocol.c \
136 + protocol/ivi-application-client-protocol.h
137 weston_simple_shm_CFLAGS = $(AM_CFLAGS) $(SIMPLE_CLIENT_CFLAGS)
138 weston_simple_shm_LDADD = $(SIMPLE_CLIENT_LIBS) libshared.la
140 @@ -412,7 +428,9 @@ demo_clients += weston-simple-egl
141 weston_simple_egl_SOURCES = clients/simple-egl.c
142 nodist_weston_simple_egl_SOURCES = \
143 protocol/xdg-shell-protocol.c \
144 - protocol/xdg-shell-client-protocol.h
145 + protocol/xdg-shell-client-protocol.h \
146 + protocol/ivi-application-protocol.c \
147 + protocol/ivi-application-client-protocol.h
148 weston_simple_egl_CFLAGS = $(AM_CFLAGS) $(SIMPLE_EGL_CLIENT_CFLAGS)
149 weston_simple_egl_LDADD = $(SIMPLE_EGL_CLIENT_LIBS) -lm
151 @@ -431,7 +449,9 @@ nodist_libtoytoolkit_la_SOURCES = \
152 protocol/workspaces-protocol.c \
153 protocol/workspaces-client-protocol.h \
154 protocol/xdg-shell-protocol.c \
155 - protocol/xdg-shell-client-protocol.h
156 + protocol/xdg-shell-client-protocol.h \
157 + protocol/ivi-application-protocol.c \
158 + protocol/ivi-application-client-protocol.h
160 BUILT_SOURCES += $(nodist_libtoytoolkit_la_SOURCES)
162 @@ -570,6 +590,19 @@ nodist_weston_desktop_shell_SOURCES = \
163 weston_desktop_shell_LDADD = libtoytoolkit.la
164 weston_desktop_shell_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
167 +weston_ivi_shell_user_interface_SOURCES = \
168 + clients/ivi-shell-user-interface.c \
170 +nodist_weston_ivi_shell_user_interface_SOURCES = \
171 + protocol/ivi-hmi-controller-client-protocol.h \
172 + protocol/ivi-hmi-controller-protocol.c \
173 + protocol/ivi-application-client-protocol.h \
174 + protocol/ivi-application-protocol.c
175 +weston_ivi_shell_user_interface_LDADD = libtoytoolkit.la
176 +weston_ivi_shell_user_interface_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
179 if BUILD_FULL_GL_CLIENTS
180 demo_clients += weston-gears
181 weston_gears_SOURCES = clients/gears.c
182 @@ -616,8 +649,11 @@ BUILT_SOURCES += \
183 protocol/fullscreen-shell-protocol.c \
184 protocol/fullscreen-shell-client-protocol.h \
185 protocol/xdg-shell-protocol.c \
186 - protocol/xdg-shell-client-protocol.h
188 + protocol/xdg-shell-client-protocol.h \
189 + protocol/ivi-hmi-controller-protocol.c \
190 + protocol/ivi-hmi-controller-client-protocol.h \
191 + protocol/ivi-application-protocol.c \
192 + protocol/ivi-application-client-protocol.h
194 westondatadir = $(datadir)/weston
195 dist_westondata_DATA = \
196 @@ -631,6 +667,21 @@ dist_westondata_DATA = \
197 data/sign_maximize.png \
198 data/sign_minimize.png
201 +dist_westondata_DATA += \
202 + data/background.png \
204 + data/fullscreen.png \
207 + data/sidebyside.png \
209 + data/icon_ivi_clickdot.png \
210 + data/icon_ivi_flower.png \
211 + data/icon_ivi_simple-egl.png \
212 + data/icon_ivi_simple-shm.png \
213 + data/icon_ivi_smoke.png
217 bin_PROGRAMS += wcap-decode
218 @@ -700,6 +751,48 @@ nodist_fullscreen_shell_la_SOURCES = \
219 BUILT_SOURCES += $(nodist_fullscreen_shell_la_SOURCES)
224 +module_LTLIBRARIES += \
228 +ivi_shell = ivi-shell.la
229 +ivi_shell_la_LDFLAGS = -module -avoid-version
230 +ivi_shell_la_LIBADD = $(COMPOSITOR_LIBS) libshared.la
231 +ivi_shell_la_CFLAGS = $(AM_CFLAGS) $(COMPOSITOR_CFLAGS)
232 +ivi_shell_la_SOURCES = \
233 + ivi-shell/ivi-layout-export.h \
234 + ivi-shell/ivi-layout-private.h \
235 + ivi-shell/ivi-layout.c \
236 + ivi-shell/ivi-layout-transition.c \
237 + ivi-shell/ivi-shell.h \
238 + ivi-shell/ivi-shell.c \
239 + ivi-shell/input-panel-ivi.c \
241 +nodist_ivi_shell_la_SOURCES = \
242 + protocol/ivi-application-protocol.c \
243 + protocol/ivi-application-server-protocol.h
245 +BUILT_SOURCES += $(nodist_ivi_shell_la_SOURCES)
247 +hmi_controller = hmi-controller.la
248 +hmi_controller_la_LDFLAGS = -module -avoid-version
249 +hmi_controller_la_LIBADD = $(COMPOSITOR_LIBS) libshared.la
250 +hmi_controller_la_CFLAGS = $(AM_CFLAGS) $(COMPOSITOR_CFLAGS)
251 +hmi_controller_la_SOURCES = \
252 + ivi-shell/ivi-layout-export.h \
253 + ivi-shell/hmi-controller.c \
255 +nodist_hmi_controller_la_SOURCES = \
256 + protocol/ivi-hmi-controller-protocol.c \
257 + protocol/ivi-hmi-controller-server-protocol.h
259 +BUILT_SOURCES += $(nodist_hmi_controller_la_SOURCES)
264 if ENABLE_SCREEN_SHARING
266 module_LTLIBRARIES += screen-share.la
267 @@ -969,7 +1062,9 @@ EXTRA_DIST += \
268 protocol/wayland-test.xml \
269 protocol/xdg-shell.xml \
270 protocol/fullscreen-shell.xml \
271 - protocol/scaler.xml
272 + protocol/scaler.xml \
273 + protocol/ivi-application.xml \
274 + protocol/ivi-hmi-controller.xml
276 man_MANS = weston.1 weston.ini.5
278 diff --git a/clients/ivi-shell-user-interface.c b/clients/ivi-shell-user-interface.c
280 index 0000000..dbe7a88
282 +++ b/clients/ivi-shell-user-interface.c
285 + * Copyright (C) 2013 DENSO CORPORATION
287 + * Permission is hereby granted, free of charge, to any person obtaining a
288 + * copy of this software and associated documentation files (the "Software"),
289 + * to deal in the Software without restriction, including without limitation
290 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
291 + * and/or sell copies of the Software, and to permit persons to whom the
292 + * Software is furnished to do so, subject to the following conditions:
294 + * The above copyright notice and this permission notice (including the next
295 + * paragraph) shall be included in all copies or substantial portions of the
298 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
299 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
300 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
301 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
302 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
303 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
304 + * DEALINGS IN THE SOFTWARE.
307 +#include <sys/wait.h>
312 +#include <linux/input.h>
316 +#include <sys/mman.h>
318 +#include <wayland-cursor.h>
319 +#include <wayland-client-protocol.h>
320 +#include "shared/cairo-util.h"
321 +#include "shared/config-parser.h"
322 +#include "shared/helpers.h"
323 +#include "shared/os-compatibility.h"
324 +#include "ivi-application-client-protocol.h"
325 +#include "ivi-hmi-controller-client-protocol.h"
328 + * A reference implementation how to use ivi-hmi-controller interface to
329 + * interact with hmi-controller. This is launched from hmi-controller by using
330 + * hmi_client_start and create a pthread.
332 + * The basic flow is as followed,
333 + * 1/ read configuration from weston.ini.
334 + * 2/ draw png file to surface according to configuration of weston.ini
335 + * 3/ set up UI by using ivi-hmi-controller protocol
336 + * 4/ Enter event loop
337 + * 5/ If a surface receives touch/pointer event, followings are invoked
338 + * according to type of event and surface
339 + * 5-1/ If a surface to launch ivi_application receive touch up, it execs
340 + * ivi-application configured in weston.ini.
341 + * 5-2/ If a surface to switch layout mode receive touch up, it sends a request,
342 + * ivi_hmi_controller_switch_mode, to hmi-controller.
343 + * 5-3/ If a surface to show workspace having launchers, it sends a request,
344 + * ivi_hmi_controller_home, to hmi-controller.
345 + * 5-4/ If touch down events happens in workspace,
346 + * ivi_hmi_controller_workspace_control is sent to slide workspace.
347 + * When control finished, event: ivi_hmi_controller_workspace_end_control
351 +/*****************************************************************************
352 + * structure, globals
353 + ****************************************************************************/
355 + CURSOR_BOTTOM_LEFT,
356 + CURSOR_BOTTOM_RIGHT,
371 +struct wlContextCommon {
372 + struct wl_display *wlDisplay;
373 + struct wl_registry *wlRegistry;
374 + struct wl_compositor *wlCompositor;
375 + struct wl_shm *wlShm;
377 + struct wl_seat *wlSeat;
378 + struct wl_pointer *wlPointer;
379 + struct wl_touch *wlTouch;
380 + struct ivi_application *iviApplication;
381 + struct ivi_hmi_controller *hmiCtrl;
382 + struct hmi_homescreen_setting *hmi_setting;
383 + struct wl_list list_wlContextStruct;
384 + struct wl_surface *enterSurface;
385 + int32_t is_home_on;
386 + struct wl_cursor_theme *cursor_theme;
387 + struct wl_cursor **cursors;
388 + struct wl_surface *pointer_surface;
389 + enum cursor_type current_cursor;
390 + uint32_t enter_serial;
393 +struct wlContextStruct {
394 + struct wlContextCommon *cmm;
395 + struct wl_surface *wlSurface;
396 + struct wl_buffer *wlBuffer;
397 + cairo_surface_t *ctx_image;
399 + uint32_t id_surface;
400 + struct wl_list link;
404 +hmi_homescreen_srf {
411 +hmi_homescreen_workspace {
412 + struct wl_array launcher_id_array;
413 + struct wl_list link;
417 +hmi_homescreen_launcher {
418 + uint32_t icon_surface_id;
419 + uint32_t workspace_id;
422 + struct wl_list link;
426 +hmi_homescreen_setting {
427 + struct hmi_homescreen_srf background;
428 + struct hmi_homescreen_srf panel;
429 + struct hmi_homescreen_srf tiling;
430 + struct hmi_homescreen_srf sidebyside;
431 + struct hmi_homescreen_srf fullscreen;
432 + struct hmi_homescreen_srf random;
433 + struct hmi_homescreen_srf home;
434 + struct hmi_homescreen_srf workspace_background;
436 + struct wl_list workspace_list;
437 + struct wl_list launcher_list;
439 + char *cursor_theme;
440 + int32_t cursor_size;
441 + uint32_t transition_duration;
445 +fail_on_null(void *p, size_t size, char *file, int32_t line)
448 + fprintf(stderr, "%s(%d) %zd: out of memory\n",
450 + exit(EXIT_FAILURE);
457 +mem_alloc(size_t size, char *file, int32_t line)
459 + return fail_on_null(calloc(1, size), size, file, line);
462 +#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
464 +/*****************************************************************************
466 + ****************************************************************************/
469 +shm_format(void *data, struct wl_shm *pWlShm, uint32_t format)
471 + struct wlContextCommon *pCtx = data;
473 + pCtx->formats |= (1 << format);
476 +static struct wl_shm_listener shm_listenter = {
481 +getIdOfWlSurface(struct wlContextCommon *pCtx, struct wl_surface *wlSurface)
483 + struct wlContextStruct *pWlCtxSt = NULL;
485 + if (NULL == pCtx || NULL == wlSurface )
488 + wl_list_for_each(pWlCtxSt, &pCtx->list_wlContextStruct, link) {
489 + if (pWlCtxSt->wlSurface == wlSurface)
490 + return pWlCtxSt->id_surface;
497 +set_pointer_image(struct wlContextCommon *pCtx, uint32_t index)
499 + struct wl_cursor *cursor = NULL;
500 + struct wl_cursor_image *image = NULL;
501 + struct wl_buffer *buffer = NULL;
503 + if (!pCtx->wlPointer || !pCtx->cursors)
506 + if (CURSOR_BLANK == pCtx->current_cursor) {
507 + wl_pointer_set_cursor(pCtx->wlPointer, pCtx->enter_serial,
512 + cursor = pCtx->cursors[pCtx->current_cursor];
516 + if (cursor->image_count <= index) {
517 + fprintf(stderr, "cursor index out of range\n");
521 + image = cursor->images[index];
522 + buffer = wl_cursor_image_get_buffer(image);
527 + wl_pointer_set_cursor(pCtx->wlPointer, pCtx->enter_serial,
528 + pCtx->pointer_surface,
529 + image->hotspot_x, image->hotspot_y);
531 + wl_surface_attach(pCtx->pointer_surface, buffer, 0, 0);
533 + wl_surface_damage(pCtx->pointer_surface, 0, 0,
534 + image->width, image->height);
536 + wl_surface_commit(pCtx->pointer_surface);
540 +PointerHandleEnter(void *data, struct wl_pointer *wlPointer, uint32_t serial,
541 + struct wl_surface *wlSurface, wl_fixed_t sx, wl_fixed_t sy)
543 + struct wlContextCommon *pCtx = data;
545 + pCtx->enter_serial = serial;
546 + pCtx->enterSurface = wlSurface;
547 + set_pointer_image(pCtx, 0);
549 + printf("ENTER PointerHandleEnter: x(%d), y(%d)\n", sx, sy);
554 +PointerHandleLeave(void *data, struct wl_pointer *wlPointer, uint32_t serial,
555 + struct wl_surface *wlSurface)
557 + struct wlContextCommon *pCtx = data;
559 + pCtx->enterSurface = NULL;
562 + printf("ENTER PointerHandleLeave: serial(%d)\n", serial);
567 +PointerHandleMotion(void *data, struct wl_pointer *wlPointer, uint32_t time,
568 + wl_fixed_t sx, wl_fixed_t sy)
571 + printf("ENTER PointerHandleMotion: x(%d), y(%d)\n", sx, sy);
576 + * if a surface assigned as launcher receives touch-off event, invoking
577 + * ivi-application which configured in weston.ini with path to binary.
579 +extern char **environ; /*defied by libc */
582 +execute_process(char *path, char *argv[])
584 + pid_t pid = fork();
586 + fprintf(stderr, "Failed to fork\n");
591 + if (-1 == execve(path, argv, environ)) {
592 + fprintf(stderr, "Failed to execve %s\n", path);
600 +launcher_button(uint32_t surfaceId, struct wl_list *launcher_list)
602 + struct hmi_homescreen_launcher *launcher = NULL;
604 + wl_list_for_each(launcher, launcher_list, link) {
605 + char *argv[] = { NULL };
607 + if (surfaceId != launcher->icon_surface_id)
610 + execute_process(launcher->path, argv);
619 + * is-method to identify a surface set as launcher in workspace or workspace
620 + * itself. This is-method is used to decide whether request;
621 + * ivi_hmi_controller_workspace_control is sent or not.
624 +isWorkspaceSurface(uint32_t id, struct hmi_homescreen_setting *hmi_setting)
626 + struct hmi_homescreen_launcher *launcher = NULL;
628 + if (id == hmi_setting->workspace_background.id)
631 + wl_list_for_each(launcher, &hmi_setting->launcher_list, link) {
632 + if (id == launcher->icon_surface_id)
640 + * Decide which request is sent to hmi-controller
643 +touch_up(struct ivi_hmi_controller *hmi_ctrl, uint32_t id_surface,
644 + int32_t *is_home_on, struct hmi_homescreen_setting *hmi_setting)
646 + if (launcher_button(id_surface, &hmi_setting->launcher_list)) {
648 + ivi_hmi_controller_home(hmi_ctrl, IVI_HMI_CONTROLLER_HOME_OFF);
649 + } else if (id_surface == hmi_setting->tiling.id) {
650 + ivi_hmi_controller_switch_mode(hmi_ctrl,
651 + IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING);
652 + } else if (id_surface == hmi_setting->sidebyside.id) {
653 + ivi_hmi_controller_switch_mode(hmi_ctrl,
654 + IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE);
655 + } else if (id_surface == hmi_setting->fullscreen.id) {
656 + ivi_hmi_controller_switch_mode(hmi_ctrl,
657 + IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN);
658 + } else if (id_surface == hmi_setting->random.id) {
659 + ivi_hmi_controller_switch_mode(hmi_ctrl,
660 + IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM);
661 + } else if (id_surface == hmi_setting->home.id) {
662 + *is_home_on = !(*is_home_on);
664 + ivi_hmi_controller_home(hmi_ctrl,
665 + IVI_HMI_CONTROLLER_HOME_ON);
667 + ivi_hmi_controller_home(hmi_ctrl,
668 + IVI_HMI_CONTROLLER_HOME_OFF);
674 + * Even handler of Pointer event. IVI system is usually manipulated by touch
675 + * screen. However, some systems also have pointer device.
676 + * Release is the same behavior as touch off
677 + * Pressed is the same behavior as touch on
680 +PointerHandleButton(void *data, struct wl_pointer *wlPointer, uint32_t serial,
681 + uint32_t time, uint32_t button, uint32_t state)
683 + struct wlContextCommon *pCtx = data;
684 + struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl;
685 + const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface);
687 + if (BTN_RIGHT == button)
691 + case WL_POINTER_BUTTON_STATE_RELEASED:
692 + touch_up(hmi_ctrl, id_surface, &pCtx->is_home_on,
693 + pCtx->hmi_setting);
696 + case WL_POINTER_BUTTON_STATE_PRESSED:
698 + if (isWorkspaceSurface(id_surface, pCtx->hmi_setting)) {
699 + ivi_hmi_controller_workspace_control(hmi_ctrl,
707 + printf("ENTER PointerHandleButton: button(%d), state(%d)\n",
713 +PointerHandleAxis(void *data, struct wl_pointer *wlPointer, uint32_t time,
714 + uint32_t axis, wl_fixed_t value)
717 + printf("ENTER PointerHandleAxis: axis(%d), value(%d)\n", axis, value);
721 +static struct wl_pointer_listener pointer_listener = {
722 + PointerHandleEnter,
723 + PointerHandleLeave,
724 + PointerHandleMotion,
725 + PointerHandleButton,
730 + * Even handler of touch event
733 +TouchHandleDown(void *data, struct wl_touch *wlTouch, uint32_t serial,
734 + uint32_t time, struct wl_surface *surface, int32_t id,
735 + wl_fixed_t x_w, wl_fixed_t y_w)
737 + struct wlContextCommon *pCtx = data;
738 + struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl;
739 + uint32_t id_surface = 0;
742 + pCtx->enterSurface = surface;
744 + id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface);
747 + * When touch down happens on surfaces of workspace, ask
748 + * hmi-controller to start control workspace to select page of
749 + * workspace. After sending seat to hmi-controller by
750 + * ivi_hmi_controller_workspace_control,
751 + * hmi-controller-homescreen doesn't receive any event till
752 + * hmi-controller sends back it.
754 + if (isWorkspaceSurface(id_surface, pCtx->hmi_setting)) {
755 + ivi_hmi_controller_workspace_control(hmi_ctrl, pCtx->wlSeat,
761 +TouchHandleUp(void *data, struct wl_touch *wlTouch, uint32_t serial,
762 + uint32_t time, int32_t id)
764 + struct wlContextCommon *pCtx = data;
765 + struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl;
767 + const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface);
770 + * triggering event according to touch-up happening on which surface.
773 + touch_up(hmi_ctrl, id_surface, &pCtx->is_home_on,
774 + pCtx->hmi_setting);
779 +TouchHandleMotion(void *data, struct wl_touch *wlTouch, uint32_t time,
780 + int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
785 +TouchHandleFrame(void *data, struct wl_touch *wlTouch)
790 +TouchHandleCancel(void *data, struct wl_touch *wlTouch)
794 +static struct wl_touch_listener touch_listener = {
803 + * Handler of capabilities
806 +seat_handle_capabilities(void *data, struct wl_seat *seat, uint32_t caps)
808 + struct wlContextCommon *p_wlCtx = (struct wlContextCommon*)data;
809 + struct wl_seat *wlSeat = p_wlCtx->wlSeat;
810 + struct wl_pointer *wlPointer = p_wlCtx->wlPointer;
811 + struct wl_touch *wlTouch = p_wlCtx->wlTouch;
813 + if (p_wlCtx->hmi_setting->cursor_theme) {
814 + if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wlPointer){
815 + wlPointer = wl_seat_get_pointer(wlSeat);
816 + wl_pointer_add_listener(wlPointer,
817 + &pointer_listener, data);
819 + if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wlPointer){
820 + wl_pointer_destroy(wlPointer);
823 + p_wlCtx->wlPointer = wlPointer;
826 + if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !wlTouch){
827 + wlTouch = wl_seat_get_touch(wlSeat);
828 + wl_touch_add_listener(wlTouch, &touch_listener, data);
830 + if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && wlTouch){
831 + wl_touch_destroy(wlTouch);
834 + p_wlCtx->wlTouch = wlTouch;
837 +static struct wl_seat_listener seat_Listener = {
838 + seat_handle_capabilities,
842 + * Registration of event
843 + * This event is received when hmi-controller server finished controlling
847 +ivi_hmi_controller_workspace_end_control(void *data,
848 + struct ivi_hmi_controller *hmi_ctrl,
849 + int32_t is_controlled)
851 + struct wlContextCommon *pCtx = data;
852 + const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface);
858 + * During being controlled by hmi-controller, any input event is not
859 + * notified. So when control ends with touch up, it invokes launcher
860 + * if up event happens on a launcher surface.
863 + if (launcher_button(id_surface, &pCtx->hmi_setting->launcher_list)) {
864 + pCtx->is_home_on = 0;
865 + ivi_hmi_controller_home(hmi_ctrl, IVI_HMI_CONTROLLER_HOME_OFF);
869 +static const struct ivi_hmi_controller_listener hmi_controller_listener = {
870 + ivi_hmi_controller_workspace_end_control
874 + * Registration of interfaces
877 +registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
878 + const char *interface, uint32_t version)
880 + struct wlContextCommon *p_wlCtx = (struct wlContextCommon*)data;
882 + if (!strcmp(interface, "wl_compositor")) {
883 + p_wlCtx->wlCompositor =
884 + wl_registry_bind(registry, name,
885 + &wl_compositor_interface, 1);
886 + } else if (!strcmp(interface, "wl_shm")) {
888 + wl_registry_bind(registry, name, &wl_shm_interface, 1);
889 + wl_shm_add_listener(p_wlCtx->wlShm, &shm_listenter, p_wlCtx);
890 + } else if (!strcmp(interface, "wl_seat")) {
892 + wl_registry_bind(registry, name, &wl_seat_interface, 1);
893 + wl_seat_add_listener(p_wlCtx->wlSeat, &seat_Listener, data);
894 + } else if (!strcmp(interface, "ivi_application")) {
895 + p_wlCtx->iviApplication =
896 + wl_registry_bind(registry, name,
897 + &ivi_application_interface, 1);
898 + } else if (!strcmp(interface, "ivi_hmi_controller")) {
900 + wl_registry_bind(registry, name,
901 + &ivi_hmi_controller_interface, 1);
903 + ivi_hmi_controller_add_listener(p_wlCtx->hmiCtrl,
904 + &hmi_controller_listener, p_wlCtx);
909 +registry_handle_global_remove(void *data, struct wl_registry *registry,
914 +static const struct wl_registry_listener registry_listener = {
915 + registry_handle_global,
916 + registry_handle_global_remove
920 +frame_listener_func(void *data, struct wl_callback *callback, uint32_t time)
923 + wl_callback_destroy(callback);
926 +static const struct wl_callback_listener frame_listener = {
927 + frame_listener_func
931 + * The following correspondences between file names and cursors was copied
932 + * from: https://bugs.kde.org/attachment.cgi?id=67313
934 +static const char *bottom_left_corners[] = {
935 + "bottom_left_corner",
940 +static const char *bottom_right_corners[] = {
941 + "bottom_right_corner",
946 +static const char *bottom_sides[] = {
952 +static const char *grabbings[] = {
955 + "208530c400c041818281048008011002"
958 +static const char *left_ptrs[] = {
965 +static const char *left_sides[] = {
971 +static const char *right_sides[] = {
977 +static const char *top_left_corners[] = {
983 +static const char *top_right_corners[] = {
984 + "top_right_corner",
989 +static const char *top_sides[] = {
995 +static const char *xterms[] = {
1001 +static const char *hand1s[] = {
1005 + "e29285e634086352946a0e7090d73106"
1008 +static const char *watches[] = {
1011 + "0426c94ea35c87780ff01dc239897213"
1014 +struct cursor_alternatives {
1015 + const char **names;
1019 +static const struct cursor_alternatives cursors[] = {
1020 + { bottom_left_corners, ARRAY_LENGTH(bottom_left_corners) },
1021 + { bottom_right_corners, ARRAY_LENGTH(bottom_right_corners) },
1022 + { bottom_sides, ARRAY_LENGTH(bottom_sides) },
1023 + { grabbings, ARRAY_LENGTH(grabbings) },
1024 + { left_ptrs, ARRAY_LENGTH(left_ptrs) },
1025 + { left_sides, ARRAY_LENGTH(left_sides) },
1026 + { right_sides, ARRAY_LENGTH(right_sides) },
1027 + { top_left_corners, ARRAY_LENGTH(top_left_corners) },
1028 + { top_right_corners, ARRAY_LENGTH(top_right_corners) },
1029 + { top_sides, ARRAY_LENGTH(top_sides) },
1030 + { xterms, ARRAY_LENGTH(xterms) },
1031 + { hand1s, ARRAY_LENGTH(hand1s) },
1032 + { watches, ARRAY_LENGTH(watches) },
1036 +create_cursors(struct wlContextCommon *cmm)
1040 + struct wl_cursor *cursor = NULL;
1041 + char *cursor_theme = cmm->hmi_setting->cursor_theme;
1042 + int32_t cursor_size = cmm->hmi_setting->cursor_size;
1044 + cmm->cursor_theme = wl_cursor_theme_load(cursor_theme, cursor_size,
1048 + MEM_ALLOC(ARRAY_LENGTH(cursors) * sizeof(cmm->cursors[0]));
1050 + for (i = 0; i < ARRAY_LENGTH(cursors); i++) {
1053 + for (j = 0; !cursor && j < cursors[i].count; ++j) {
1054 + cursor = wl_cursor_theme_get_cursor(
1055 + cmm->cursor_theme, cursors[i].names[j]);
1059 + fprintf(stderr, "could not load cursor '%s'\n",
1060 + cursors[i].names[0]);
1063 + cmm->cursors[i] = cursor;
1068 +destroy_cursors(struct wlContextCommon *cmm)
1070 + if (cmm->cursor_theme)
1071 + wl_cursor_theme_destroy(cmm->cursor_theme);
1073 + free(cmm->cursors);
1077 + * Internal method to prepare parts of UI
1080 +createShmBuffer(struct wlContextStruct *p_wlCtx)
1082 + struct wl_shm_pool *pool;
1090 + width = cairo_image_surface_get_width(p_wlCtx->ctx_image);
1091 + height = cairo_image_surface_get_height(p_wlCtx->ctx_image);
1092 + stride = cairo_image_surface_get_stride(p_wlCtx->ctx_image);
1094 + size = stride * height;
1096 + fd = os_create_anonymous_file(size);
1098 + fprintf(stderr, "creating a buffer file for %d B failed: %m\n",
1104 + mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1106 + if (MAP_FAILED == p_wlCtx->data) {
1107 + fprintf(stderr, "mmap failed: %m\n");
1112 + pool = wl_shm_create_pool(p_wlCtx->cmm->wlShm, fd, size);
1113 + p_wlCtx->wlBuffer = wl_shm_pool_create_buffer(pool, 0,
1117 + WL_SHM_FORMAT_ARGB8888);
1119 + if (NULL == p_wlCtx->wlBuffer) {
1120 + fprintf(stderr, "wl_shm_create_buffer failed: %m\n");
1125 + wl_shm_pool_destroy(pool);
1130 +destroyWLContextCommon(struct wlContextCommon *p_wlCtx)
1132 + destroy_cursors(p_wlCtx);
1134 + if (p_wlCtx->pointer_surface)
1135 + wl_surface_destroy(p_wlCtx->pointer_surface);
1137 + if (p_wlCtx->wlCompositor)
1138 + wl_compositor_destroy(p_wlCtx->wlCompositor);
1142 +destroyWLContextStruct(struct wlContextStruct *p_wlCtx)
1144 + if (p_wlCtx->wlSurface)
1145 + wl_surface_destroy(p_wlCtx->wlSurface);
1147 + if (p_wlCtx->ctx_image) {
1148 + cairo_surface_destroy(p_wlCtx->ctx_image);
1149 + p_wlCtx->ctx_image = NULL;
1154 +createSurface(struct wlContextStruct *p_wlCtx)
1156 + p_wlCtx->wlSurface =
1157 + wl_compositor_create_surface(p_wlCtx->cmm->wlCompositor);
1158 + if (NULL == p_wlCtx->wlSurface) {
1159 + printf("Error: wl_compositor_create_surface failed.\n");
1160 + destroyWLContextCommon(p_wlCtx->cmm);
1168 +drawImage(struct wlContextStruct *p_wlCtx)
1170 + struct wl_callback *callback;
1175 + void *data = NULL;
1177 + width = cairo_image_surface_get_width(p_wlCtx->ctx_image);
1178 + height = cairo_image_surface_get_height(p_wlCtx->ctx_image);
1179 + stride = cairo_image_surface_get_stride(p_wlCtx->ctx_image);
1180 + data = cairo_image_surface_get_data(p_wlCtx->ctx_image);
1182 + memcpy(p_wlCtx->data, data, stride * height);
1184 + wl_surface_attach(p_wlCtx->wlSurface, p_wlCtx->wlBuffer, 0, 0);
1185 + wl_surface_damage(p_wlCtx->wlSurface, 0, 0, width, height);
1187 + callback = wl_surface_frame(p_wlCtx->wlSurface);
1188 + wl_callback_add_listener(callback, &frame_listener, NULL);
1190 + wl_surface_commit(p_wlCtx->wlSurface);
1194 +create_ivisurface(struct wlContextStruct *p_wlCtx,
1195 + uint32_t id_surface,
1196 + cairo_surface_t *surface)
1198 + struct ivi_surface *ivisurf = NULL;
1200 + p_wlCtx->ctx_image = surface;
1202 + p_wlCtx->id_surface = id_surface;
1203 + wl_list_init(&p_wlCtx->link);
1204 + wl_list_insert(&p_wlCtx->cmm->list_wlContextStruct, &p_wlCtx->link);
1206 + createSurface(p_wlCtx);
1207 + createShmBuffer(p_wlCtx);
1209 + ivisurf = ivi_application_surface_create(p_wlCtx->cmm->iviApplication,
1211 + p_wlCtx->wlSurface);
1212 + if (ivisurf == NULL) {
1213 + fprintf(stderr, "Failed to create ivi_client_surface\n");
1217 + drawImage(p_wlCtx);
1221 +create_ivisurfaceFromFile(struct wlContextStruct *p_wlCtx,
1222 + uint32_t id_surface,
1223 + const char *imageFile)
1225 + cairo_surface_t *surface = load_cairo_surface(imageFile);
1227 + if (NULL == surface) {
1228 + fprintf(stderr, "Failed to load_cairo_surface %s\n", imageFile);
1232 + create_ivisurface(p_wlCtx, id_surface, surface);
1236 +set_hex_color(cairo_t *cr, uint32_t color)
1238 + cairo_set_source_rgba(cr,
1239 + ((color >> 16) & 0xff) / 255.0,
1240 + ((color >> 8) & 0xff) / 255.0,
1241 + ((color >> 0) & 0xff) / 255.0,
1242 + ((color >> 24) & 0xff) / 255.0);
1246 +create_ivisurfaceFromColor(struct wlContextStruct *p_wlCtx,
1247 + uint32_t id_surface,
1248 + uint32_t width, uint32_t height,
1251 + cairo_surface_t *surface = NULL;
1252 + cairo_t *cr = NULL;
1254 + surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
1257 + cr = cairo_create(surface);
1258 + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
1259 + cairo_rectangle(cr, 0, 0, width, height);
1260 + set_hex_color(cr, color);
1262 + cairo_destroy(cr);
1264 + create_ivisurface(p_wlCtx, id_surface, surface);
1268 +UI_ready(struct ivi_hmi_controller *controller)
1270 + ivi_hmi_controller_UI_ready(controller);
1274 + * Internal method to set up UI by using ivi-hmi-controller
1277 +create_background(struct wlContextStruct *p_wlCtx, const uint32_t id_surface,
1278 + const char *imageFile)
1280 + create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
1284 +create_panel(struct wlContextStruct *p_wlCtx, const uint32_t id_surface,
1285 + const char *imageFile)
1287 + create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
1291 +create_button(struct wlContextStruct *p_wlCtx, const uint32_t id_surface,
1292 + const char *imageFile, uint32_t number)
1294 + create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
1298 +create_home_button(struct wlContextStruct *p_wlCtx, const uint32_t id_surface,
1299 + const char *imageFile)
1301 + create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
1305 +create_workspace_background(struct wlContextStruct *p_wlCtx,
1306 + struct hmi_homescreen_srf *srf)
1308 + create_ivisurfaceFromColor(p_wlCtx, srf->id, 1, 1, srf->color);
1312 +create_launchers(struct wlContextCommon *cmm, struct wl_list *launcher_list)
1314 + struct hmi_homescreen_launcher **launchers;
1315 + struct hmi_homescreen_launcher *launcher = NULL;
1317 + int launcher_count = wl_list_length(launcher_list);
1321 + if (0 == launcher_count)
1324 + launchers = MEM_ALLOC(launcher_count * sizeof(*launchers));
1326 + wl_list_for_each(launcher, launcher_list, link) {
1327 + launchers[ii] = launcher;
1331 + for (ii = 0; ii < launcher_count; ii++) {
1334 + if (ii != launcher_count - 1 &&
1335 + launchers[ii]->workspace_id ==
1336 + launchers[ii + 1]->workspace_id)
1339 + for (jj = start; jj <= ii; jj++) {
1340 + struct wlContextStruct *p_wlCtx;
1342 + p_wlCtx = MEM_ALLOC(sizeof(*p_wlCtx));
1343 + p_wlCtx->cmm = cmm;
1344 + create_ivisurfaceFromFile(p_wlCtx,
1345 + launchers[jj]->icon_surface_id,
1346 + launchers[jj]->icon);
1356 + * Internal method to read out weston.ini to get configuration
1358 +static struct hmi_homescreen_setting *
1359 +hmi_homescreen_setting_create(void)
1361 + struct weston_config *config = NULL;
1362 + struct weston_config_section *shellSection = NULL;
1363 + struct hmi_homescreen_setting *setting = MEM_ALLOC(sizeof(*setting));
1364 + struct weston_config_section *section = NULL;
1365 + const char *name = NULL;
1366 + uint32_t workspace_layer_id;
1367 + uint32_t icon_surface_id = 0;
1369 + wl_list_init(&setting->workspace_list);
1370 + wl_list_init(&setting->launcher_list);
1372 + config = weston_config_parse("weston.ini");
1375 + weston_config_get_section(config, "ivi-shell", NULL, NULL);
1377 + weston_config_section_get_string(
1378 + shellSection, "cursor-theme", &setting->cursor_theme, NULL);
1380 + weston_config_section_get_int(
1381 + shellSection, "cursor-size", &setting->cursor_size, 32);
1383 + weston_config_section_get_uint(
1384 + shellSection, "workspace-layer-id", &workspace_layer_id, 3000);
1386 + weston_config_section_get_string(
1387 + shellSection, "background-image", &setting->background.filePath,
1388 + DATADIR "/weston/background.png");
1390 + weston_config_section_get_uint(
1391 + shellSection, "background-id", &setting->background.id, 1001);
1393 + weston_config_section_get_string(
1394 + shellSection, "panel-image", &setting->panel.filePath,
1395 + DATADIR "/weston/panel.png");
1397 + weston_config_section_get_uint(
1398 + shellSection, "panel-id", &setting->panel.id, 1002);
1400 + weston_config_section_get_string(
1401 + shellSection, "tiling-image", &setting->tiling.filePath,
1402 + DATADIR "/weston/tiling.png");
1404 + weston_config_section_get_uint(
1405 + shellSection, "tiling-id", &setting->tiling.id, 1003);
1407 + weston_config_section_get_string(
1408 + shellSection, "sidebyside-image", &setting->sidebyside.filePath,
1409 + DATADIR "/weston/sidebyside.png");
1411 + weston_config_section_get_uint(
1412 + shellSection, "sidebyside-id", &setting->sidebyside.id, 1004);
1414 + weston_config_section_get_string(
1415 + shellSection, "fullscreen-image", &setting->fullscreen.filePath,
1416 + DATADIR "/weston/fullscreen.png");
1418 + weston_config_section_get_uint(
1419 + shellSection, "fullscreen-id", &setting->fullscreen.id, 1005);
1421 + weston_config_section_get_string(
1422 + shellSection, "random-image", &setting->random.filePath,
1423 + DATADIR "/weston/random.png");
1425 + weston_config_section_get_uint(
1426 + shellSection, "random-id", &setting->random.id, 1006);
1428 + weston_config_section_get_string(
1429 + shellSection, "home-image", &setting->home.filePath,
1430 + DATADIR "/weston/home.png");
1432 + weston_config_section_get_uint(
1433 + shellSection, "home-id", &setting->home.id, 1007);
1435 + weston_config_section_get_uint(
1436 + shellSection, "workspace-background-color",
1437 + &setting->workspace_background.color, 0x99000000);
1439 + weston_config_section_get_uint(
1440 + shellSection, "workspace-background-id",
1441 + &setting->workspace_background.id, 2001);
1443 + icon_surface_id = workspace_layer_id + 1;
1445 + while (weston_config_next_section(config, §ion, &name)) {
1446 + struct hmi_homescreen_launcher *launcher;
1448 + if (strcmp(name, "ivi-launcher") != 0)
1451 + launcher = MEM_ALLOC(sizeof(*launcher));
1452 + wl_list_init(&launcher->link);
1454 + weston_config_section_get_string(section, "icon",
1455 + &launcher->icon, NULL);
1456 + weston_config_section_get_string(section, "path",
1457 + &launcher->path, NULL);
1458 + weston_config_section_get_uint(section, "workspace-id",
1459 + &launcher->workspace_id, 0);
1460 + weston_config_section_get_uint(section, "icon-id",
1461 + &launcher->icon_surface_id,
1463 + icon_surface_id++;
1465 + wl_list_insert(setting->launcher_list.prev, &launcher->link);
1468 + weston_config_destroy(config);
1475 + * The basic flow are as followed,
1476 + * 1/ read configuration from weston.ini by hmi_homescreen_setting_create
1477 + * 2/ draw png file to surface according to configuration of weston.ini and
1478 + * set up UI by using ivi-hmi-controller protocol by each create_* method
1480 +int main(int argc, char **argv)
1482 + struct wlContextCommon wlCtxCommon;
1483 + struct wlContextStruct wlCtx_BackGround;
1484 + struct wlContextStruct wlCtx_Panel;
1485 + struct wlContextStruct wlCtx_Button_1;
1486 + struct wlContextStruct wlCtx_Button_2;
1487 + struct wlContextStruct wlCtx_Button_3;
1488 + struct wlContextStruct wlCtx_Button_4;
1489 + struct wlContextStruct wlCtx_HomeButton;
1490 + struct wlContextStruct wlCtx_WorkSpaceBackGround;
1491 + struct wl_list launcher_wlCtxList;
1493 + struct hmi_homescreen_setting *hmi_setting;
1494 + struct wlContextStruct *pWlCtxSt = NULL;
1496 + hmi_setting = hmi_homescreen_setting_create();
1498 + memset(&wlCtxCommon, 0x00, sizeof(wlCtxCommon));
1499 + memset(&wlCtx_BackGround, 0x00, sizeof(wlCtx_BackGround));
1500 + memset(&wlCtx_Panel, 0x00, sizeof(wlCtx_Panel));
1501 + memset(&wlCtx_Button_1, 0x00, sizeof(wlCtx_Button_1));
1502 + memset(&wlCtx_Button_2, 0x00, sizeof(wlCtx_Button_2));
1503 + memset(&wlCtx_Button_3, 0x00, sizeof(wlCtx_Button_3));
1504 + memset(&wlCtx_Button_4, 0x00, sizeof(wlCtx_Button_4));
1505 + memset(&wlCtx_HomeButton, 0x00, sizeof(wlCtx_HomeButton));
1506 + memset(&wlCtx_WorkSpaceBackGround, 0x00,
1507 + sizeof(wlCtx_WorkSpaceBackGround));
1508 + wl_list_init(&launcher_wlCtxList);
1509 + wl_list_init(&wlCtxCommon.list_wlContextStruct);
1511 + wlCtxCommon.hmi_setting = hmi_setting;
1513 + wlCtxCommon.wlDisplay = wl_display_connect(NULL);
1514 + if (NULL == wlCtxCommon.wlDisplay) {
1515 + printf("Error: wl_display_connect failed.\n");
1519 + /* get wl_registry */
1520 + wlCtxCommon.formats = 0;
1521 + wlCtxCommon.wlRegistry = wl_display_get_registry(wlCtxCommon.wlDisplay);
1522 + wl_registry_add_listener(wlCtxCommon.wlRegistry,
1523 + ®istry_listener, &wlCtxCommon);
1524 + wl_display_roundtrip(wlCtxCommon.wlDisplay);
1526 + if (wlCtxCommon.wlShm == NULL) {
1527 + fprintf(stderr, "No wl_shm global\n");
1531 + wl_display_roundtrip(wlCtxCommon.wlDisplay);
1533 + if (!(wlCtxCommon.formats & (1 << WL_SHM_FORMAT_XRGB8888))) {
1534 + fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n");
1538 + if (wlCtxCommon.hmi_setting->cursor_theme) {
1539 + create_cursors(&wlCtxCommon);
1541 + wlCtxCommon.pointer_surface =
1542 + wl_compositor_create_surface(wlCtxCommon.wlCompositor);
1544 + wlCtxCommon.current_cursor = CURSOR_LEFT_PTR;
1547 + wlCtx_BackGround.cmm = &wlCtxCommon;
1548 + wlCtx_Panel.cmm = &wlCtxCommon;
1549 + wlCtx_Button_1.cmm = &wlCtxCommon;
1550 + wlCtx_Button_2.cmm = &wlCtxCommon;
1551 + wlCtx_Button_3.cmm = &wlCtxCommon;
1552 + wlCtx_Button_4.cmm = &wlCtxCommon;
1553 + wlCtx_HomeButton.cmm = &wlCtxCommon;
1554 + wlCtx_WorkSpaceBackGround.cmm = &wlCtxCommon;
1556 + /* create desktop widgets */
1557 + create_background(&wlCtx_BackGround, hmi_setting->background.id,
1558 + hmi_setting->background.filePath);
1560 + create_panel(&wlCtx_Panel, hmi_setting->panel.id,
1561 + hmi_setting->panel.filePath);
1563 + create_button(&wlCtx_Button_1, hmi_setting->tiling.id,
1564 + hmi_setting->tiling.filePath, 0);
1566 + create_button(&wlCtx_Button_2, hmi_setting->sidebyside.id,
1567 + hmi_setting->sidebyside.filePath, 1);
1569 + create_button(&wlCtx_Button_3, hmi_setting->fullscreen.id,
1570 + hmi_setting->fullscreen.filePath, 2);
1572 + create_button(&wlCtx_Button_4, hmi_setting->random.id,
1573 + hmi_setting->random.filePath, 3);
1575 + create_workspace_background(&wlCtx_WorkSpaceBackGround,
1576 + &hmi_setting->workspace_background);
1578 + create_launchers(&wlCtxCommon, &hmi_setting->launcher_list);
1580 + create_home_button(&wlCtx_HomeButton, hmi_setting->home.id,
1581 + hmi_setting->home.filePath);
1583 + UI_ready(wlCtxCommon.hmiCtrl);
1586 + ret = wl_display_dispatch(wlCtxCommon.wlDisplay);
1588 + wl_list_for_each(pWlCtxSt, &wlCtxCommon.list_wlContextStruct, link) {
1589 + destroyWLContextStruct(pWlCtxSt);
1592 + destroyWLContextCommon(&wlCtxCommon);
1596 diff --git a/clients/simple-egl.c b/clients/simple-egl.c
1597 index 0d4673b..8634075 100644
1598 --- a/clients/simple-egl.c
1599 +++ b/clients/simple-egl.c
1601 #include <stdbool.h>
1604 +#include <unistd.h>
1607 #include <linux/input.h>
1609 #include <EGL/eglext.h>
1611 #include "xdg-shell-client-protocol.h"
1612 +#include "ivi-application-client-protocol.h"
1613 +#define IVI_SURFACE_ID 9000
1615 #ifndef EGL_EXT_swap_buffers_with_damage
1616 #define EGL_EXT_swap_buffers_with_damage 1
1617 @@ -74,6 +77,7 @@ struct display {
1620 struct window *window;
1621 + struct ivi_application *ivi_application;
1623 PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage;
1625 @@ -95,6 +99,7 @@ struct window {
1626 struct wl_egl_window *native;
1627 struct wl_surface *surface;
1628 struct xdg_surface *xdg_surface;
1629 + struct ivi_surface *ivi_surface;
1630 EGLSurface egl_surface;
1631 struct wl_callback *callback;
1632 int fullscreen, opaque, buffer_size, frame_sync;
1633 @@ -329,18 +334,61 @@ static const struct xdg_surface_listener xdg_surface_listener = {
1637 -create_surface(struct window *window)
1638 +handle_ivi_surface_configure(void *data, struct ivi_surface *ivi_surface,
1639 + int32_t width, int32_t height)
1641 + struct window *window = data;
1643 + wl_egl_window_resize(window->native, width, height, 0, 0);
1645 + window->geometry.width = width;
1646 + window->geometry.height = height;
1648 + if (!window->fullscreen)
1649 + window->window_size = window->geometry;
1652 +static const struct ivi_surface_listener ivi_surface_listener = {
1653 + handle_ivi_surface_configure,
1657 +create_xdg_surface(struct window *window, struct display *display)
1659 - struct display *display = window->display;
1662 - window->surface = wl_compositor_create_surface(display->compositor);
1663 window->xdg_surface = xdg_shell_get_xdg_surface(display->shell,
1666 xdg_surface_add_listener(window->xdg_surface,
1667 &xdg_surface_listener, window);
1669 + xdg_surface_set_title(window->xdg_surface, "simple-egl");
1673 +create_ivi_surface(struct window *window, struct display *display)
1675 + uint32_t id_ivisurf = IVI_SURFACE_ID + (uint32_t)getpid();
1676 + window->ivi_surface =
1677 + ivi_application_surface_create(display->ivi_application,
1678 + id_ivisurf, window->surface);
1680 + if (window->ivi_surface == NULL) {
1681 + fprintf(stderr, "Failed to create ivi_client_surface\n");
1685 + ivi_surface_add_listener(window->ivi_surface,
1686 + &ivi_surface_listener, window);
1690 +create_surface(struct window *window)
1692 + struct display *display = window->display;
1695 + window->surface = wl_compositor_create_surface(display->compositor);
1698 wl_egl_window_create(window->surface,
1699 window->window_size.width,
1700 @@ -350,7 +398,13 @@ create_surface(struct window *window)
1702 window->native, NULL);
1704 - xdg_surface_set_title(window->xdg_surface, "simple-egl");
1705 + if (display->shell) {
1706 + create_xdg_surface(window, display);
1707 + } else if (display->ivi_application) {
1708 + create_ivi_surface(window, display);
1713 ret = eglMakeCurrent(window->display->egl.dpy, window->egl_surface,
1714 window->egl_surface, window->display->egl.ctx);
1715 @@ -375,7 +429,10 @@ destroy_surface(struct window *window)
1716 eglDestroySurface(window->display->egl.dpy, window->egl_surface);
1717 wl_egl_window_destroy(window->native);
1719 - xdg_surface_destroy(window->xdg_surface);
1720 + if (window->xdg_surface)
1721 + xdg_surface_destroy(window->xdg_surface);
1722 + if (window->display->ivi_application)
1723 + ivi_surface_destroy(window->ivi_surface);
1724 wl_surface_destroy(window->surface);
1726 if (window->callback)
1727 @@ -729,6 +786,10 @@ registry_handle_global(void *data, struct wl_registry *registry,
1728 fprintf(stderr, "unable to load default left pointer\n");
1731 + } else if (strcmp(interface, "ivi_application") == 0) {
1732 + d->ivi_application =
1733 + wl_registry_bind(registry, name,
1734 + &ivi_application_interface, 1);
1738 @@ -834,6 +895,9 @@ main(int argc, char **argv)
1740 xdg_shell_destroy(display.shell);
1742 + if (display.ivi_application)
1743 + ivi_application_destroy(display.ivi_application);
1745 if (display.compositor)
1746 wl_compositor_destroy(display.compositor);
1748 diff --git a/clients/simple-shm.c b/clients/simple-shm.c
1749 index 2087a0e..97c2da5 100644
1750 --- a/clients/simple-shm.c
1751 +++ b/clients/simple-shm.c
1753 #include "../shared/os-compatibility.h"
1754 #include "xdg-shell-client-protocol.h"
1755 #include "fullscreen-shell-client-protocol.h"
1756 +#include "ivi-application-client-protocol.h"
1757 +#define IVI_SURFACE_ID 9000
1760 struct wl_display *display;
1761 @@ -45,6 +47,7 @@ struct display {
1762 struct _wl_fullscreen_shell *fshell;
1765 + struct ivi_application *ivi_application;
1769 @@ -58,6 +61,7 @@ struct window {
1771 struct wl_surface *surface;
1772 struct xdg_surface *xdg_surface;
1773 + struct ivi_surface *ivi_surface;
1774 struct buffer buffers[2];
1775 struct buffer *prev_buffer;
1776 struct wl_callback *callback;
1777 @@ -153,6 +157,17 @@ static const struct xdg_surface_listener xdg_surface_listener = {
1782 +handle_ivi_surface_configure(void *data, struct ivi_surface *ivi_surface,
1783 + int32_t width, int32_t height)
1785 + /* Simple-shm is resizable */
1788 +static const struct ivi_surface_listener ivi_surface_listener = {
1789 + handle_ivi_surface_configure,
1792 static struct window *
1793 create_window(struct display *display, int width, int height)
1795 @@ -184,6 +199,18 @@ create_window(struct display *display, int width, int height)
1797 _WL_FULLSCREEN_SHELL_PRESENT_METHOD_DEFAULT,
1799 + } else if (display->ivi_application) {
1800 + uint32_t id_ivisurf = IVI_SURFACE_ID + (uint32_t)getpid();
1801 + window->ivi_surface =
1802 + ivi_application_surface_create(display->ivi_application,
1803 + id_ivisurf, window->surface);
1804 + if (window->ivi_surface == NULL) {
1805 + fprintf(stderr, "Failed to create ivi_client_surface\n");
1809 + ivi_surface_add_listener(window->ivi_surface,
1810 + &ivi_surface_listener, window);
1814 @@ -368,6 +395,10 @@ registry_handle_global(void *data, struct wl_registry *registry,
1815 d->shm = wl_registry_bind(registry,
1816 id, &wl_shm_interface, 1);
1817 wl_shm_add_listener(d->shm, &shm_listener, d);
1818 + } else if (strcmp(interface, "ivi_application") == 0) {
1819 + d->ivi_application =
1820 + wl_registry_bind(registry, id,
1821 + &ivi_application_interface, 1);
1825 @@ -472,6 +503,12 @@ main(int argc, char **argv)
1826 ret = wl_display_dispatch(display->display);
1828 fprintf(stderr, "simple-shm exiting\n");
1830 + if (window->display->ivi_application) {
1831 + ivi_surface_destroy(window->ivi_surface);
1832 + ivi_application_destroy(window->display->ivi_application);
1835 destroy_window(window);
1836 destroy_display(display);
1838 diff --git a/clients/window.c b/clients/window.c
1839 index 4592ef9..049093d 100644
1840 --- a/clients/window.c
1841 +++ b/clients/window.c
1842 @@ -72,6 +72,9 @@ typedef void *EGLContext;
1846 +#include "ivi-application-client-protocol.h"
1847 +#define IVI_SURFACE_ID 9000
1852 @@ -91,6 +94,7 @@ struct display {
1853 struct text_cursor_position *text_cursor_position;
1854 struct workspace_manager *workspace_manager;
1855 struct xdg_shell *xdg_shell;
1856 + struct ivi_application *ivi_application; /* ivi style shell */
1858 EGLConfig argb_config;
1859 EGLContext argb_ctx;
1860 @@ -246,6 +250,8 @@ struct window {
1862 struct window *transient_for;
1864 + struct ivi_surface *ivi_surface;
1866 struct window_frame *frame;
1868 /* struct surface::link, contains also main_surface */
1869 @@ -1368,6 +1374,19 @@ window_get_display(struct window *window)
1873 +handle_ivi_surface_configure(void *data, struct ivi_surface *ivi_surface,
1874 + int32_t width, int32_t height)
1876 + struct window *window = data;
1878 + window_schedule_resize(window, width, height);
1881 +static const struct ivi_surface_listener ivi_surface_listener = {
1882 + handle_ivi_surface_configure,
1886 surface_create_surface(struct surface *surface, uint32_t flags)
1888 struct display *display = surface->window->display;
1889 @@ -1515,6 +1534,9 @@ window_destroy(struct window *window)
1890 if (window->xdg_popup)
1891 xdg_popup_destroy(window->xdg_popup);
1893 + if (window->ivi_surface)
1894 + ivi_surface_destroy(window->ivi_surface);
1896 surface_destroy(window->main_surface);
1898 wl_list_remove(&window->link);
1899 @@ -4386,7 +4408,7 @@ window_create_internal(struct display *display, int custom)
1900 surface = surface_create(window);
1901 window->main_surface = surface;
1903 - assert(custom || display->xdg_shell);
1904 + assert(custom || display->xdg_shell || display->ivi_application);
1906 window->custom = custom;
1907 window->preferred_format = WINDOW_PREFERRED_FORMAT_NONE;
1908 @@ -4406,17 +4428,31 @@ struct window *
1909 window_create(struct display *display)
1911 struct window *window;
1912 + uint32_t id_ivisurf;
1914 window = window_create_internal(display, 0);
1916 - window->xdg_surface =
1917 - xdg_shell_get_xdg_surface(window->display->xdg_shell,
1918 - window->main_surface->surface);
1919 - fail_on_null(window->xdg_surface);
1920 + if (window->display->xdg_shell) {
1921 + window->xdg_surface =
1922 + xdg_shell_get_xdg_surface(window->display->xdg_shell,
1923 + window->main_surface->surface);
1924 + fail_on_null(window->xdg_surface);
1926 - xdg_surface_set_user_data(window->xdg_surface, window);
1927 - xdg_surface_add_listener(window->xdg_surface,
1928 + xdg_surface_set_user_data(window->xdg_surface, window);
1929 + xdg_surface_add_listener(window->xdg_surface,
1930 &xdg_surface_listener, window);
1931 + } else if (display->ivi_application) {
1932 + /* auto generation of ivi_id based on process id + basement of id */
1933 + id_ivisurf = IVI_SURFACE_ID + (uint32_t)getpid();
1934 + window->ivi_surface =
1935 + ivi_application_surface_create(display->ivi_application,
1936 + id_ivisurf, window->main_surface->surface);
1938 + fail_on_null(window->ivi_surface);
1940 + ivi_surface_add_listener(window->ivi_surface,
1941 + &ivi_surface_listener, window);
1946 @@ -5090,6 +5126,10 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id,
1948 wl_registry_bind(registry, id,
1949 &wl_subcompositor_interface, 1);
1950 + } else if (strcmp(interface, "ivi_application") == 0) {
1951 + d->ivi_application =
1952 + wl_registry_bind(registry, id,
1953 + &ivi_application_interface, 1);
1956 if (d->global_handler)
1957 @@ -5389,6 +5429,9 @@ display_destroy(struct display *display)
1958 if (display->xdg_shell)
1959 xdg_shell_destroy(display->xdg_shell);
1961 + if (display->ivi_application)
1962 + ivi_application_destroy(display->ivi_application);
1965 wl_shm_destroy(display->shm);
1967 diff --git a/configure.ac b/configure.ac
1968 index f55cea8..edaba3c 100644
1971 @@ -433,6 +433,13 @@ if test "x$enable_dbus" != "xno"; then
1973 AM_CONDITIONAL(ENABLE_DBUS, test "x$enable_dbus" = "xyes")
1975 +# ivi-shell support
1976 +AC_ARG_ENABLE(ivi-shell,
1977 + AS_HELP_STRING([--disable-ivi-shell],
1978 + [do not build ivi-shell server plugin and client]),,
1979 + enable_ivi_shell=yes)
1980 +AM_CONDITIONAL(ENABLE_IVI_SHELL, test "x$enable_ivi_shell" = "xyes")
1982 AC_ARG_ENABLE(wcap-tools, [ --disable-wcap-tools],, enable_wcap_tools=yes)
1983 AM_CONDITIONAL(BUILD_WCAP_TOOLS, test x$enable_wcap_tools = xyes)
1984 if test x$enable_wcap_tools = xyes; then
1985 @@ -522,6 +529,8 @@ AC_MSG_RESULT([
1986 XWayland ${enable_xwayland}
1989 + ivi-shell ${enable_ivi_shell}
1991 Build wcap utility ${enable_wcap_tools}
1992 Build Fullscreen Shell ${enable_fullscreen_shell}
1995 diff --git a/ivi-shell/hmi-controller.c b/ivi-shell/hmi-controller.c
1996 new file mode 100644
1997 index 0000000..7f3d5bf
1999 +++ b/ivi-shell/hmi-controller.c
2002 + * Copyright (C) 2014 DENSO CORPORATION
2004 + * Permission is hereby granted, free of charge, to any person obtaining
2005 + * a copy of this software and associated documentation files (the
2006 + * "Software"), to deal in the Software without restriction, including
2007 + * without limitation the rights to use, copy, modify, merge, publish,
2008 + * distribute, sublicense, and/or sell copies of the Software, and to
2009 + * permit persons to whom the Software is furnished to do so, subject to
2010 + * the following conditions:
2012 + * The above copyright notice and this permission notice (including the
2013 + * next paragraph) shall be included in all copies or substantial
2014 + * portions of the Software.
2016 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2017 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2018 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2019 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2020 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
2021 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2022 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2027 + * A reference implementation how to use ivi-layout APIs in order to manage
2028 + * layout of ivi_surfaces/ivi_layers. Layout change is triggered by
2029 + * ivi-hmi-controller protocol, ivi-hmi-controller.xml. A reference how to
2030 + * use the protocol, see hmi-controller-homescreen.
2032 + * In-Vehicle Infotainment system usually manage properties of
2033 + * ivi_surfaces/ivi_layers by only a central component which decide where
2034 + * ivi_surfaces/ivi_layers shall be. This reference show examples to
2035 + * implement the central component as a module of weston.
2037 + * Default Scene graph of UI is defined in hmi_controller_create. It
2039 + * - In the bottom, a base ivi_layer to group ivi_surfaces of background,
2040 + * panel, and buttons
2041 + * - Next, a application ivi_layer to show application ivi_surfaces.
2042 + * - Workspace background ivi_layer to show a ivi_surface of background image.
2043 + * - Workspace ivi_layer to show launcher to launch application with icons.
2044 + * Paths to binary and icon are defined in weston.ini. The width of this
2045 + * ivi_layer is longer than the size of ivi_screen because a workspace has
2046 + * several pages and is controlled by motion of input.
2048 + * TODO: animation method shall be refined
2049 + * TODO: support fade-in when UI is ready
2052 +#include <sys/wait.h>
2053 +#include <unistd.h>
2054 +#include <stdlib.h>
2056 +#include <string.h>
2057 +#include <linux/input.h>
2058 +#include <assert.h>
2061 +#include "ivi-layout-export.h"
2062 +#include "ivi-hmi-controller-server-protocol.h"
2063 +#include "shared/helpers.h"
2065 +/*****************************************************************************
2066 + * structure, globals
2067 + ****************************************************************************/
2068 +struct hmi_controller_layer {
2069 + struct ivi_layout_layer *ivilayer;
2070 + uint32_t id_layer;
2077 +struct link_layer {
2078 + struct ivi_layout_layer *layout_layer;
2079 + struct wl_list link;
2082 +struct hmi_controller_fade {
2083 + uint32_t is_fade_in;
2084 + struct wl_list layer_list;
2087 +struct hmi_server_setting {
2088 + uint32_t base_layer_id;
2089 + uint32_t application_layer_id;
2090 + uint32_t workspace_background_layer_id;
2091 + uint32_t workspace_layer_id;
2092 + int32_t panel_height;
2093 + uint32_t transition_duration;
2094 + char *ivi_homescreen;
2097 +struct ui_setting {
2098 + uint32_t background_id;
2099 + uint32_t panel_id;
2100 + uint32_t tiling_id;
2101 + uint32_t sidebyside_id;
2102 + uint32_t fullscreen_id;
2103 + uint32_t random_id;
2105 + uint32_t workspace_background_id;
2108 +struct hmi_controller {
2109 + struct hmi_server_setting *hmi_setting;
2110 + struct hmi_controller_layer base_layer;
2111 + struct hmi_controller_layer application_layer;
2112 + struct hmi_controller_layer workspace_background_layer;
2113 + struct hmi_controller_layer workspace_layer;
2114 + enum ivi_hmi_controller_layout_mode layout_mode;
2116 + struct hmi_controller_fade workspace_fade;
2118 + int32_t workspace_count;
2119 + struct wl_array ui_widgets;
2120 + int32_t is_initialized;
2122 + struct weston_compositor *compositor;
2123 + struct weston_process process;
2124 + struct wl_listener destroy_listener;
2126 + struct wl_client *user_interface;
2127 + struct ui_setting ui_setting;
2130 +struct launcher_info {
2131 + uint32_t surface_id;
2132 + uint32_t workspace_id;
2136 +const struct ivi_controller_interface *ivi_controller_interface;
2139 +controller_module_init(struct weston_compositor *ec,
2140 + int *argc, char *argv[],
2141 + const struct ivi_controller_interface *interface,
2142 + size_t interface_version);
2144 +/*****************************************************************************
2146 + ****************************************************************************/
2148 +fail_on_null(void *p, size_t size, char *file, int32_t line)
2151 + weston_log("%s(%d) %zd: out of memory\n", file, line, size);
2152 + exit(EXIT_FAILURE);
2159 +mem_alloc(size_t size, char *file, int32_t line)
2161 + return fail_on_null(calloc(1, size), size, file, line);
2164 +#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
2167 +is_surf_in_ui_widget(struct hmi_controller *hmi_ctrl,
2168 + struct ivi_layout_surface *ivisurf)
2170 + uint32_t id = ivi_controller_interface->get_id_of_surface(ivisurf);
2172 + uint32_t *ui_widget_id = NULL;
2173 + wl_array_for_each(ui_widget_id, &hmi_ctrl->ui_widgets) {
2174 + if (*ui_widget_id == id)
2182 +compare_launcher_info(const void *lhs, const void *rhs)
2184 + const struct launcher_info *left = lhs;
2185 + const struct launcher_info *right = rhs;
2187 + if (left->workspace_id < right->workspace_id)
2190 + if (left->workspace_id > right->workspace_id)
2193 + if (left->index < right->index)
2196 + if (left->index > right->index)
2203 + * Internal methods called by mainly ivi_hmi_controller_switch_mode
2204 + * This reference shows 4 examples how to use ivi_layout APIs.
2207 +mode_divided_into_tiling(struct hmi_controller *hmi_ctrl,
2208 + struct ivi_layout_surface **pp_surface,
2209 + int32_t surface_length,
2210 + struct hmi_controller_layer *layer)
2212 + const float surface_width = (float)layer->width * 0.25;
2213 + const float surface_height = (float)layer->height * 0.5;
2214 + int32_t surface_x = 0;
2215 + int32_t surface_y = 0;
2216 + struct ivi_layout_surface *ivisurf = NULL;
2217 + struct ivi_layout_surface **surfaces;
2218 + struct ivi_layout_surface **new_order;
2219 + const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
2222 + int32_t surf_num = 0;
2225 + surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length);
2226 + new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length);
2228 + for (i = 0; i < surface_length; i++) {
2229 + ivisurf = pp_surface[i];
2231 + /* skip ui widgets */
2232 + if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
2235 + surfaces[surf_num++] = ivisurf;
2238 + for (i = 0; i < surf_num; i++) {
2239 + ivisurf = surfaces[i];
2240 + new_order[i] = ivisurf;
2244 + surface_x = (int32_t)((num - 1) * (surface_width));
2247 + surface_x = (int32_t)((num - 5) * (surface_width));
2248 + surface_y = (int32_t)surface_height;
2251 + ivi_controller_interface->surface_set_transition(ivisurf,
2252 + IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
2254 + ivi_controller_interface->surface_set_visibility(ivisurf, true);
2255 + ivi_controller_interface->surface_set_destination_rectangle(ivisurf,
2256 + surface_x, surface_y,
2257 + (int32_t)surface_width,
2258 + (int32_t)surface_height);
2263 + ivi_controller_interface->surface_set_visibility(ivisurf, false);
2266 + if (surf_num > 0) {
2267 + ivi_controller_interface->layer_set_transition(layer->ivilayer,
2268 + IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
2277 +mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl,
2278 + struct ivi_layout_surface **pp_surface,
2279 + int32_t surface_length,
2280 + struct hmi_controller_layer *layer)
2282 + int32_t surface_width = layer->width / 2;
2283 + int32_t surface_height = layer->height;
2284 + struct ivi_layout_surface *ivisurf = NULL;
2286 + const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
2290 + for (i = 0; i < surface_length; i++) {
2291 + ivisurf = pp_surface[i];
2293 + /* skip ui widgets */
2294 + if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
2298 + ivi_controller_interface->surface_set_transition(ivisurf,
2299 + IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
2301 + ivi_controller_interface->surface_set_visibility(ivisurf, true);
2302 + ivi_controller_interface->surface_set_destination_rectangle(ivisurf,
2309 + } else if (num == 2) {
2310 + ivi_controller_interface->surface_set_transition(ivisurf,
2311 + IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
2313 + ivi_controller_interface->surface_set_visibility(ivisurf, true);
2314 + ivi_controller_interface->surface_set_destination_rectangle(ivisurf,
2322 + ivi_controller_interface->surface_set_transition(ivisurf,
2323 + IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY,
2325 + ivi_controller_interface->surface_set_visibility(ivisurf, false);
2330 +mode_fullscreen_someone(struct hmi_controller *hmi_ctrl,
2331 + struct ivi_layout_surface **pp_surface,
2332 + int32_t surface_length,
2333 + struct hmi_controller_layer *layer)
2335 + const int32_t surface_width = layer->width;
2336 + const int32_t surface_height = layer->height;
2337 + struct ivi_layout_surface *ivisurf = NULL;
2339 + const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
2341 + for (i = 0; i < surface_length; i++) {
2342 + ivisurf = pp_surface[i];
2344 + /* skip ui widgets */
2345 + if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
2348 + ivi_controller_interface->surface_set_transition(ivisurf,
2349 + IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
2351 + ivi_controller_interface->surface_set_visibility(ivisurf, true);
2352 + ivi_controller_interface->surface_set_destination_rectangle(ivisurf, 0, 0,
2359 +mode_random_replace(struct hmi_controller *hmi_ctrl,
2360 + struct ivi_layout_surface **pp_surface,
2361 + int32_t surface_length,
2362 + struct hmi_controller_layer *layer)
2364 + const int32_t surface_width = (int32_t)(layer->width * 0.25f);
2365 + const int32_t surface_height = (int32_t)(layer->height * 0.25f);
2366 + int32_t surface_x = 0;
2367 + int32_t surface_y = 0;
2368 + struct ivi_layout_surface *ivisurf = NULL;
2369 + const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
2372 + for (i = 0; i < surface_length; i++) {
2373 + ivisurf = pp_surface[i];
2375 + /* skip ui widgets */
2376 + if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
2379 + ivi_controller_interface->surface_set_transition(ivisurf,
2380 + IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
2382 + ivi_controller_interface->surface_set_visibility(ivisurf, true);
2383 + surface_x = rand() % (layer->width - surface_width);
2384 + surface_y = rand() % (layer->height - surface_height);
2386 + ivi_controller_interface->surface_set_destination_rectangle(ivisurf,
2395 +has_application_surface(struct hmi_controller *hmi_ctrl,
2396 + struct ivi_layout_surface **pp_surface,
2397 + int32_t surface_length)
2399 + struct ivi_layout_surface *ivisurf = NULL;
2402 + for (i = 0; i < surface_length; i++) {
2403 + ivisurf = pp_surface[i];
2405 + /* skip ui widgets */
2406 + if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
2416 + * Supports 4 example to layout of application ivi_surfaces;
2417 + * tiling, side by side, fullscreen, and random.
2420 +switch_mode(struct hmi_controller *hmi_ctrl,
2421 + enum ivi_hmi_controller_layout_mode layout_mode)
2423 + struct hmi_controller_layer *layer = &hmi_ctrl->application_layer;
2424 + struct ivi_layout_surface **pp_surface = NULL;
2425 + int32_t surface_length = 0;
2428 + if (!hmi_ctrl->is_initialized)
2431 + hmi_ctrl->layout_mode = layout_mode;
2433 + ret = ivi_controller_interface->get_surfaces(&surface_length, &pp_surface);
2436 + if (!has_application_surface(hmi_ctrl, pp_surface, surface_length)) {
2438 + pp_surface = NULL;
2442 + switch (layout_mode) {
2443 + case IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING:
2444 + mode_divided_into_tiling(hmi_ctrl, pp_surface, surface_length,
2447 + case IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE:
2448 + mode_divided_into_sidebyside(hmi_ctrl, pp_surface,
2449 + surface_length, layer);
2451 + case IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN:
2452 + mode_fullscreen_someone(hmi_ctrl, pp_surface, surface_length,
2455 + case IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM:
2456 + mode_random_replace(hmi_ctrl, pp_surface, surface_length,
2461 + ivi_controller_interface->commit_changes();
2466 + * Internal method for transition
2469 +hmi_controller_fade_run(struct hmi_controller *hmi_ctrl, uint32_t is_fade_in,
2470 + struct hmi_controller_fade *fade)
2472 + double tint = is_fade_in ? 1.0 : 0.0;
2473 + struct link_layer *linklayer = NULL;
2474 + const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration;
2476 + fade->is_fade_in = is_fade_in;
2478 + wl_list_for_each(linklayer, &fade->layer_list, link) {
2479 + ivi_controller_interface->layer_set_transition(linklayer->layout_layer,
2480 + IVI_LAYOUT_TRANSITION_LAYER_FADE,
2482 + ivi_controller_interface->layer_set_fade_info(linklayer->layout_layer,
2483 + is_fade_in, 1.0 - tint, tint);
2488 + * Internal method to create ivi_layer with hmi_controller_layer and
2489 + * add to a ivi_screen
2492 +create_layer(struct ivi_layout_screen *iviscrn,
2493 + struct hmi_controller_layer *layer)
2498 + ivi_controller_interface->layer_create_with_dimension(layer->id_layer,
2501 + assert(layer->ivilayer != NULL);
2503 + ret = ivi_controller_interface->screen_add_layer(iviscrn, layer->ivilayer);
2506 + ret = ivi_controller_interface->layer_set_destination_rectangle(layer->ivilayer,
2507 + layer->x, layer->y,
2512 + ret = ivi_controller_interface->layer_set_visibility(layer->ivilayer, true);
2517 + * Internal set notification
2520 +set_notification_create_surface(struct ivi_layout_surface *ivisurf,
2523 + struct hmi_controller *hmi_ctrl = userdata;
2524 + struct ivi_layout_layer *application_layer =
2525 + hmi_ctrl->application_layer.ivilayer;
2528 + /* skip ui widgets */
2529 + if (is_surf_in_ui_widget(hmi_ctrl, ivisurf))
2532 + ret = ivi_controller_interface->layer_add_surface(application_layer, ivisurf);
2537 +set_notification_remove_surface(struct ivi_layout_surface *ivisurf,
2540 + struct hmi_controller *hmi_ctrl = userdata;
2542 + switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
2546 +set_notification_configure_surface(struct ivi_layout_surface *ivisurf,
2549 + struct hmi_controller *hmi_ctrl = userdata;
2550 + struct ivi_layout_layer *application_layer =
2551 + hmi_ctrl->application_layer.ivilayer;
2552 + struct weston_surface *surface;
2553 + struct ivi_layout_surface **ivisurfs;
2554 + int32_t length = 0;
2557 + /* return if the surface is not application content */
2558 + if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) {
2563 + * if application changes size of wl_buffer. The source rectangle shall be
2564 + * fit to the size.
2566 + surface = ivi_controller_interface->surface_get_weston_surface(ivisurf);
2568 + ivi_controller_interface->surface_set_source_rectangle(
2569 + ivisurf, 0, 0, surface->width,
2574 + * search if the surface is already added to layer.
2575 + * If not yet, it is newly invoded application to go to switch_mode.
2577 + ivi_controller_interface->get_surfaces_on_layer(application_layer,
2578 + &length, &ivisurfs);
2579 + for (i = 0; i < length; i++) {
2580 + if (ivisurf == ivisurfs[i]) {
2582 + * if it is non new invoked application, just call
2583 + * commit_changes to apply source_rectangle.
2585 + ivi_controller_interface->commit_changes();
2590 + switch_mode(hmi_ctrl, hmi_ctrl->layout_mode);
2594 + * A hmi_controller used 4 ivi_layers to manage ivi_surfaces. The IDs of
2595 + * corresponding ivi_layer are defined in weston.ini. Default scene graph
2596 + * of ivi_layers are initialized in hmi_controller_create
2598 +static struct hmi_server_setting *
2599 +hmi_server_setting_create(struct weston_compositor *ec)
2601 + struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
2602 + struct weston_config *config = ec->config;
2603 + struct weston_config_section *shell_section = NULL;
2605 + shell_section = weston_config_get_section(config, "ivi-shell",
2608 + weston_config_section_get_uint(shell_section, "base-layer-id",
2609 + &setting->base_layer_id, 1000);
2611 + weston_config_section_get_uint(shell_section,
2612 + "workspace-background-layer-id",
2613 + &setting->workspace_background_layer_id,
2616 + weston_config_section_get_uint(shell_section, "workspace-layer-id",
2617 + &setting->workspace_layer_id, 3000);
2619 + weston_config_section_get_uint(shell_section, "application-layer-id",
2620 + &setting->application_layer_id, 4000);
2622 + weston_config_section_get_uint(shell_section, "transition-duration",
2623 + &setting->transition_duration, 300);
2625 + setting->panel_height = 70;
2627 + weston_config_section_get_string(shell_section,
2628 + "ivi-shell-user-interface",
2629 + &setting->ivi_homescreen, NULL);
2635 +hmi_controller_destroy(struct wl_listener *listener, void *data)
2637 + struct link_layer *link = NULL;
2638 + struct link_layer *next = NULL;
2639 + struct hmi_controller *hmi_ctrl =
2640 + container_of(listener, struct hmi_controller, destroy_listener);
2642 + wl_list_for_each_safe(link, next,
2643 + &hmi_ctrl->workspace_fade.layer_list, link) {
2644 + wl_list_remove(&link->link);
2648 + wl_array_release(&hmi_ctrl->ui_widgets);
2649 + free(hmi_ctrl->hmi_setting);
2654 + * This is a starting method called from module_init.
2655 + * This sets up scene graph of ivi_layers; base, application, workspace
2656 + * background, and workspace. These ivi_layers are created/added to
2657 + * ivi_screen in create_layer
2659 + * base: to group ivi_surfaces of panel and background
2660 + * application: to group ivi_surfaces of ivi_applications
2661 + * workspace background: to group a ivi_surface of background in workspace
2662 + * workspace: to group ivi_surfaces for launching ivi_applications
2664 + * ivi_layers of workspace background and workspace is set to invisible at
2665 + * first. The properties of it is updated with animation when
2666 + * ivi_hmi_controller_home is requested.
2668 +static struct hmi_controller *
2669 +hmi_controller_create(struct weston_compositor *ec)
2671 + struct ivi_layout_screen **pp_screen = NULL;
2672 + struct ivi_layout_screen *iviscrn = NULL;
2673 + int32_t screen_length = 0;
2674 + int32_t screen_width = 0;
2675 + int32_t screen_height = 0;
2676 + struct link_layer *tmp_link_layer = NULL;
2677 + int32_t panel_height = 0;
2678 + struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
2680 + wl_array_init(&hmi_ctrl->ui_widgets);
2681 + hmi_ctrl->layout_mode = IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING;
2682 + hmi_ctrl->hmi_setting = hmi_server_setting_create(ec);
2683 + hmi_ctrl->compositor = ec;
2685 + ivi_controller_interface->get_screens(&screen_length, &pp_screen);
2687 + iviscrn = pp_screen[0];
2689 + ivi_controller_interface->get_screen_resolution(iviscrn, &screen_width,
2692 + /* init base ivi_layer*/
2693 + hmi_ctrl->base_layer.x = 0;
2694 + hmi_ctrl->base_layer.y = 0;
2695 + hmi_ctrl->base_layer.width = screen_width;
2696 + hmi_ctrl->base_layer.height = screen_height;
2697 + hmi_ctrl->base_layer.id_layer = hmi_ctrl->hmi_setting->base_layer_id;
2699 + create_layer(iviscrn, &hmi_ctrl->base_layer);
2701 + panel_height = hmi_ctrl->hmi_setting->panel_height;
2703 + /* init application ivi_layer */
2704 + hmi_ctrl->application_layer.x = 0;
2705 + hmi_ctrl->application_layer.y = 0;
2706 + hmi_ctrl->application_layer.width = screen_width;
2707 + hmi_ctrl->application_layer.height = screen_height - panel_height;
2708 + hmi_ctrl->application_layer.id_layer =
2709 + hmi_ctrl->hmi_setting->application_layer_id;
2711 + create_layer(iviscrn, &hmi_ctrl->application_layer);
2713 + /* init workspace background ivi_layer */
2714 + hmi_ctrl->workspace_background_layer.x = 0;
2715 + hmi_ctrl->workspace_background_layer.y = 0;
2716 + hmi_ctrl->workspace_background_layer.width = screen_width;
2717 + hmi_ctrl->workspace_background_layer.height =
2718 + screen_height - panel_height;
2720 + hmi_ctrl->workspace_background_layer.id_layer =
2721 + hmi_ctrl->hmi_setting->workspace_background_layer_id;
2723 + create_layer(iviscrn, &hmi_ctrl->workspace_background_layer);
2724 + ivi_controller_interface->layer_set_opacity(
2725 + hmi_ctrl->workspace_background_layer.ivilayer, 0);
2726 + ivi_controller_interface->layer_set_visibility(
2727 + hmi_ctrl->workspace_background_layer.ivilayer, false);
2730 + wl_list_init(&hmi_ctrl->workspace_fade.layer_list);
2731 + tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
2732 + tmp_link_layer->layout_layer =
2733 + hmi_ctrl->workspace_background_layer.ivilayer;
2734 + wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
2735 + &tmp_link_layer->link);
2737 + ivi_controller_interface->add_notification_create_surface(
2738 + set_notification_create_surface, hmi_ctrl);
2739 + ivi_controller_interface->add_notification_remove_surface(
2740 + set_notification_remove_surface, hmi_ctrl);
2741 + ivi_controller_interface->add_notification_configure_surface(
2742 + set_notification_configure_surface, hmi_ctrl);
2744 + hmi_ctrl->destroy_listener.notify = hmi_controller_destroy;
2745 + wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
2746 + &hmi_ctrl->destroy_listener);
2755 + * Implementations of ivi-hmi-controller.xml
2759 + * A ivi_surface drawing background is identified by id_surface.
2760 + * Properties of the ivi_surface is set by using ivi_layout APIs according to
2761 + * the scene graph of UI defined in hmi_controller_create.
2763 + * UI ivi_layer is used to add this ivi_surface.
2766 +ivi_hmi_controller_set_background(struct hmi_controller *hmi_ctrl,
2767 + uint32_t id_surface)
2769 + struct ivi_layout_surface *ivisurf = NULL;
2770 + struct ivi_layout_layer *ivilayer = hmi_ctrl->base_layer.ivilayer;
2771 + const int32_t dstx = hmi_ctrl->application_layer.x;
2772 + const int32_t dsty = hmi_ctrl->application_layer.y;
2773 + const int32_t width = hmi_ctrl->application_layer.width;
2774 + const int32_t height = hmi_ctrl->application_layer.height;
2777 + uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
2778 + sizeof(*add_surface_id));
2779 + *add_surface_id = id_surface;
2781 + ivisurf = ivi_controller_interface->get_surface_from_id(id_surface);
2782 + assert(ivisurf != NULL);
2784 + ret = ivi_controller_interface->layer_add_surface(ivilayer, ivisurf);
2787 + ret = ivi_controller_interface->surface_set_destination_rectangle(ivisurf,
2788 + dstx, dsty, width, height);
2791 + ret = ivi_controller_interface->surface_set_visibility(ivisurf, true);
2796 + * A ivi_surface drawing panel is identified by id_surface.
2797 + * Properties of the ivi_surface is set by using ivi_layout APIs according to
2798 + * the scene graph of UI defined in hmi_controller_create.
2800 + * UI ivi_layer is used to add this ivi_surface.
2803 +ivi_hmi_controller_set_panel(struct hmi_controller *hmi_ctrl,
2804 + uint32_t id_surface)
2806 + struct ivi_layout_surface *ivisurf = NULL;
2807 + struct ivi_layout_layer *ivilayer = hmi_ctrl->base_layer.ivilayer;
2808 + const int32_t width = hmi_ctrl->base_layer.width;
2810 + int32_t panel_height = 0;
2811 + const int32_t dstx = 0;
2814 + uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
2815 + sizeof(*add_surface_id));
2816 + *add_surface_id = id_surface;
2818 + ivisurf = ivi_controller_interface->get_surface_from_id(id_surface);
2819 + assert(ivisurf != NULL);
2821 + ret = ivi_controller_interface->layer_add_surface(ivilayer, ivisurf);
2824 + panel_height = hmi_ctrl->hmi_setting->panel_height;
2826 + dsty = hmi_ctrl->base_layer.height - panel_height;
2828 + ret = ivi_controller_interface->surface_set_destination_rectangle(
2829 + ivisurf, dstx, dsty, width, panel_height);
2832 + ret = ivi_controller_interface->surface_set_visibility(ivisurf, true);
2837 + * A ivi_surface drawing buttons in panel is identified by id_surface.
2838 + * It can set several buttons. Properties of the ivi_surface is set by
2839 + * using ivi_layout APIs according to the scene graph of UI defined in
2840 + * hmi_controller_create. Additionally, the position of it is shifted to
2841 + * right when new one is requested.
2843 + * UI ivi_layer is used to add these ivi_surfaces.
2846 +ivi_hmi_controller_set_button(struct hmi_controller *hmi_ctrl,
2847 + uint32_t id_surface, int32_t number)
2849 + struct ivi_layout_surface *ivisurf = NULL;
2850 + struct ivi_layout_layer *ivilayer = hmi_ctrl->base_layer.ivilayer;
2851 + const int32_t width = 48;
2852 + const int32_t height = 48;
2854 + int32_t panel_height = 0;
2857 + uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
2858 + sizeof(*add_surface_id));
2859 + *add_surface_id = id_surface;
2861 + ivisurf = ivi_controller_interface->get_surface_from_id(id_surface);
2862 + assert(ivisurf != NULL);
2864 + ret = ivi_controller_interface->layer_add_surface(ivilayer, ivisurf);
2867 + panel_height = hmi_ctrl->hmi_setting->panel_height;
2869 + dstx = (60 * number) + 15;
2870 + dsty = (hmi_ctrl->base_layer.height - panel_height) + 5;
2872 + ret = ivi_controller_interface->surface_set_destination_rectangle(
2873 + ivisurf,dstx, dsty, width, height);
2876 + ret = ivi_controller_interface->surface_set_visibility(ivisurf, true);
2881 + * A ivi_surface drawing home button in panel is identified by id_surface.
2882 + * Properties of the ivi_surface is set by using ivi_layout APIs according to
2883 + * the scene graph of UI defined in hmi_controller_create.
2885 + * UI ivi_layer is used to add these ivi_surfaces.
2888 +ivi_hmi_controller_set_home_button(struct hmi_controller *hmi_ctrl,
2889 + uint32_t id_surface)
2891 + struct ivi_layout_surface *ivisurf = NULL;
2892 + struct ivi_layout_layer *ivilayer = hmi_ctrl->base_layer.ivilayer;
2894 + int32_t size = 48;
2895 + int32_t panel_height = hmi_ctrl->hmi_setting->panel_height;
2896 + const int32_t dstx = (hmi_ctrl->base_layer.width - size) / 2;
2897 + const int32_t dsty = (hmi_ctrl->base_layer.height - panel_height) + 5;
2899 + uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
2900 + sizeof(*add_surface_id));
2901 + *add_surface_id = id_surface;
2903 + ivisurf = ivi_controller_interface->get_surface_from_id(id_surface);
2904 + assert(ivisurf != NULL);
2906 + ret = ivi_controller_interface->layer_add_surface(ivilayer, ivisurf);
2909 + ret = ivi_controller_interface->surface_set_destination_rectangle(
2910 + ivisurf, dstx, dsty, size, size);
2913 + ret = ivi_controller_interface->surface_set_visibility(ivisurf, true);
2918 + * A ivi_surface drawing background of workspace is identified by id_surface.
2919 + * Properties of the ivi_surface is set by using ivi_layout APIs according to
2920 + * the scene graph of UI defined in hmi_controller_create.
2922 + * A ivi_layer of workspace_background is used to add this ivi_surface.
2925 +ivi_hmi_controller_set_workspacebackground(struct hmi_controller *hmi_ctrl,
2926 + uint32_t id_surface)
2928 + struct ivi_layout_surface *ivisurf = NULL;
2929 + struct ivi_layout_layer *ivilayer = NULL;
2930 + const int32_t width = hmi_ctrl->workspace_background_layer.width;
2931 + const int32_t height = hmi_ctrl->workspace_background_layer.height;
2934 + uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
2935 + sizeof(*add_surface_id));
2936 + *add_surface_id = id_surface;
2937 + ivilayer = hmi_ctrl->workspace_background_layer.ivilayer;
2939 + ivisurf = ivi_controller_interface->get_surface_from_id(id_surface);
2940 + assert(ivisurf != NULL);
2942 + ret = ivi_controller_interface->layer_add_surface(ivilayer, ivisurf);
2945 + ret = ivi_controller_interface->surface_set_destination_rectangle(ivisurf,
2946 + 0, 0, width, height);
2949 + ret = ivi_controller_interface->surface_set_visibility(ivisurf, true);
2954 + * A list of ivi_surfaces drawing launchers in workspace is identified by
2955 + * id_surfaces. Properties of the ivi_surface is set by using ivi_layout
2956 + * APIs according to the scene graph of UI defined in hmi_controller_create.
2958 + * The workspace can have several pages to group ivi_surfaces of launcher.
2959 + * Each call of this interface increments a number of page to add a group
2963 +ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
2964 + int32_t icon_size)
2966 + int32_t minspace_x = 10;
2967 + int32_t minspace_y = minspace_x;
2969 + int32_t width = hmi_ctrl->workspace_background_layer.width;
2970 + int32_t height = hmi_ctrl->workspace_background_layer.height;
2972 + int32_t x_count = (width - minspace_x) / (minspace_x + icon_size);
2973 + int32_t space_x = (int32_t)((width - x_count * icon_size) / (1.0 + x_count));
2974 + float fcell_size_x = icon_size + space_x;
2976 + int32_t y_count = (height - minspace_y) / (minspace_y + icon_size);
2977 + int32_t space_y = (int32_t)((height - y_count * icon_size) / (1.0 + y_count));
2978 + float fcell_size_y = icon_size + space_y;
2980 + struct weston_config *config = NULL;
2981 + struct weston_config_section *section = NULL;
2982 + const char *name = NULL;
2983 + int launcher_count = 0;
2984 + struct wl_array launchers;
2987 + int32_t prev = -1;
2988 + struct launcher_info *data = NULL;
2990 + uint32_t surfaceid = 0;
2991 + uint32_t workspaceid = 0;
2992 + struct launcher_info *info = NULL;
2997 + struct ivi_layout_surface* layout_surface = NULL;
2998 + uint32_t *add_surface_id = NULL;
3000 + struct ivi_layout_screen *iviscrn = NULL;
3001 + struct link_layer *tmp_link_layer = NULL;
3002 + struct ivi_layout_screen **pp_screen = NULL;
3003 + int32_t screen_length = 0;
3011 + config = hmi_ctrl->compositor->config;
3015 + section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
3019 + wl_array_init(&launchers);
3021 + while (weston_config_next_section(config, §ion, &name)) {
3025 + if (0 != strcmp(name, "ivi-launcher"))
3028 + if (0 != weston_config_section_get_uint(section, "icon-id",
3032 + if (0 != weston_config_section_get_uint(section,
3037 + info = wl_array_add(&launchers, sizeof(*info));
3040 + info->surface_id = surfaceid;
3041 + info->workspace_id = workspaceid;
3042 + info->index = launcher_count;
3047 + qsort(launchers.data, launcher_count, sizeof(struct launcher_info),
3048 + compare_launcher_info);
3050 + wl_array_for_each(data, &launchers) {
3054 + layout_surface = NULL;
3055 + add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets,
3056 + sizeof(*add_surface_id));
3058 + *add_surface_id = data->surface_id;
3060 + if (0 > prev || (uint32_t)prev != data->workspace_id) {
3063 + prev = data->workspace_id;
3066 + hmi_ctrl->workspace_count++;
3069 + if (y_count == ny) {
3071 + hmi_ctrl->workspace_count++;
3074 + x = nx * fcell_size_x + (hmi_ctrl->workspace_count - 1) * width + space_x;
3075 + y = ny * fcell_size_y + space_y;
3078 + ivi_controller_interface->get_surface_from_id(data->surface_id);
3079 + assert(layout_surface);
3081 + ret = ivi_controller_interface->surface_set_destination_rectangle(
3082 + layout_surface, x, y, icon_size, icon_size);
3087 + if (x_count == nx) {
3093 + /* init workspace ivi_layer */
3094 + hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x;
3095 + hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y;
3096 + hmi_ctrl->workspace_layer.width =
3097 + hmi_ctrl->workspace_background_layer.width * hmi_ctrl->workspace_count;
3098 + hmi_ctrl->workspace_layer.height =
3099 + hmi_ctrl->workspace_background_layer.height;
3100 + hmi_ctrl->workspace_layer.id_layer =
3101 + hmi_ctrl->hmi_setting->workspace_layer_id;
3103 + ivi_controller_interface->get_screens(&screen_length, &pp_screen);
3104 + iviscrn = pp_screen[0];
3106 + create_layer(iviscrn, &hmi_ctrl->workspace_layer);
3107 + ivi_controller_interface->layer_set_opacity(hmi_ctrl->workspace_layer.ivilayer, 0);
3108 + ivi_controller_interface->layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer,
3111 + tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
3112 + tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer;
3113 + wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
3114 + &tmp_link_layer->link);
3116 + /* Add surface to layer */
3117 + wl_array_for_each(data, &launchers) {
3119 + ivi_controller_interface->get_surface_from_id(data->surface_id);
3120 + assert(layout_surface);
3122 + ret = ivi_controller_interface->layer_add_surface(hmi_ctrl->workspace_layer.ivilayer,
3126 + ret = ivi_controller_interface->surface_set_visibility(layout_surface, true);
3130 + wl_array_release(&launchers);
3131 + ivi_controller_interface->commit_changes();
3135 +ivi_hmi_controller_UI_ready(struct wl_client *client,
3136 + struct wl_resource *resource)
3138 + struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
3140 + ivi_hmi_controller_set_background(hmi_ctrl, hmi_ctrl->ui_setting.background_id);
3141 + ivi_hmi_controller_set_panel(hmi_ctrl, hmi_ctrl->ui_setting.panel_id);
3142 + ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.tiling_id, 0);
3143 + ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.sidebyside_id, 1);
3144 + ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.fullscreen_id, 2);
3145 + ivi_hmi_controller_set_button(hmi_ctrl, hmi_ctrl->ui_setting.random_id, 3);
3146 + ivi_hmi_controller_set_home_button(hmi_ctrl, hmi_ctrl->ui_setting.home_id);
3147 + ivi_hmi_controller_set_workspacebackground(hmi_ctrl, hmi_ctrl->ui_setting.workspace_background_id);
3148 + ivi_controller_interface->commit_changes();
3150 + ivi_hmi_controller_add_launchers(hmi_ctrl, 256);
3151 + hmi_ctrl->is_initialized = 1;
3155 + * Implementation of request and event of ivi_hmi_controller_workspace_control
3156 + * and controlling workspace.
3158 + * When motion of input is detected in a ivi_surface of workspace background,
3159 + * ivi_hmi_controller_workspace_control shall be invoked and to start
3160 + * controlling of workspace. The workspace has several pages to show several
3161 + * groups of applications.
3162 + * The workspace is slid by using ivi-layout to select a a page in layer_set_pos
3163 + * according to motion. When motion finished, e.g. touch up detected, control is
3164 + * terminated and event:ivi_hmi_controller_workspace_control is notified.
3166 +struct pointer_grab {
3167 + struct weston_pointer_grab grab;
3168 + struct ivi_layout_layer *layer;
3169 + struct wl_resource *resource;
3172 +struct touch_grab {
3173 + struct weston_touch_grab grab;
3174 + struct ivi_layout_layer *layer;
3175 + struct wl_resource *resource;
3179 + wl_fixed_t dst[2];
3180 + wl_fixed_t rgn[2][2];
3182 + struct timespec start_time;
3183 + struct timespec pre_time;
3184 + wl_fixed_t start_pos[2];
3185 + wl_fixed_t pos[2];
3189 +struct pointer_move_grab {
3190 + struct pointer_grab base;
3191 + struct move_grab move;
3194 +struct touch_move_grab {
3195 + struct touch_grab base;
3196 + struct move_grab move;
3197 + int32_t is_active;
3201 +pointer_grab_start(struct pointer_grab *grab,
3202 + struct ivi_layout_layer *layer,
3203 + const struct weston_pointer_grab_interface *interface,
3204 + struct weston_pointer *pointer)
3206 + grab->grab.interface = interface;
3207 + grab->layer = layer;
3208 + weston_pointer_start_grab(pointer, &grab->grab);
3212 +touch_grab_start(struct touch_grab *grab,
3213 + struct ivi_layout_layer *layer,
3214 + const struct weston_touch_grab_interface *interface,
3215 + struct weston_touch* touch)
3217 + grab->grab.interface = interface;
3218 + grab->layer = layer;
3219 + weston_touch_start_grab(touch, &grab->grab);
3223 +clamp(int32_t val, int32_t min, int32_t max)
3235 +move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource,
3236 + wl_fixed_t grab_x, struct ivi_layout_layer *layer)
3238 + struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
3239 + int32_t width = hmi_ctrl->workspace_background_layer.width;
3241 + struct timespec time = {0};
3242 + double grab_time = 0.0;
3243 + double from_motion_time = 0.0;
3244 + double pointer_v = 0.0;
3245 + int32_t is_flick = 0;
3246 + int32_t pos_x = 0;
3247 + int32_t pos_y = 0;
3249 + double end_pos = 0.0;
3250 + uint32_t duration = 0;
3252 + clock_gettime(CLOCK_MONOTONIC, &time);
3254 + grab_time = 1e+3 * (time.tv_sec - move->start_time.tv_sec) +
3255 + 1e-6 * (time.tv_nsec - move->start_time.tv_nsec);
3257 + from_motion_time = 1e+3 * (time.tv_sec - move->pre_time.tv_sec) +
3258 + 1e-6 * (time.tv_nsec - move->pre_time.tv_nsec);
3260 + pointer_v = move->v[0];
3262 + is_flick = grab_time < 400 && 0.4 < fabs(pointer_v);
3263 + if (200 < from_motion_time)
3266 + ivi_controller_interface->layer_get_position(layer, &pos_x, &pos_y);
3270 + int orgx = wl_fixed_to_int(move->dst[0] + grab_x);
3271 + page_no = (-orgx + width / 2) / width;
3273 + if (pointer_v < 0.0)
3278 + page_no = (-pos_x + width / 2) / width;
3281 + page_no = clamp(page_no, 0, hmi_ctrl->workspace_count - 1);
3282 + end_pos = -page_no * width;
3284 + duration = hmi_ctrl->hmi_setting->transition_duration;
3285 + ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved);
3286 + ivi_controller_interface->layer_set_transition(layer,
3287 + IVI_LAYOUT_TRANSITION_LAYER_MOVE,
3289 + ivi_controller_interface->layer_set_destination_rectangle(layer,
3291 + hmi_ctrl->workspace_layer.width,
3292 + hmi_ctrl->workspace_layer.height);
3293 + ivi_controller_interface->commit_changes();
3297 +pointer_move_workspace_grab_end(struct pointer_grab *grab)
3299 + struct pointer_move_grab *pnt_move_grab =
3300 + (struct pointer_move_grab *)grab;
3301 + struct ivi_layout_layer *layer = pnt_move_grab->base.layer;
3303 + move_workspace_grab_end(&pnt_move_grab->move, grab->resource,
3304 + grab->grab.pointer->grab_x, layer);
3306 + weston_pointer_end_grab(grab->grab.pointer);
3310 +touch_move_workspace_grab_end(struct touch_grab *grab)
3312 + struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
3313 + struct ivi_layout_layer *layer = tch_move_grab->base.layer;
3315 + move_workspace_grab_end(&tch_move_grab->move, grab->resource,
3316 + grab->grab.touch->grab_x, layer);
3318 + weston_touch_end_grab(grab->grab.touch);
3322 +pointer_noop_grab_focus(struct weston_pointer_grab *grab)
3327 +move_grab_update(struct move_grab *move, wl_fixed_t pointer[2])
3329 + struct timespec timestamp = {0};
3333 + clock_gettime(CLOCK_MONOTONIC, ×tamp); //FIXME
3334 + dt = (1e+3 * (timestamp.tv_sec - move->pre_time.tv_sec) +
3335 + 1e-6 * (timestamp.tv_nsec - move->pre_time.tv_nsec));
3340 + move->pre_time = timestamp;
3342 + for (ii = 0; ii < 2; ii++) {
3343 + wl_fixed_t prepos = move->pos[ii];
3344 + move->pos[ii] = pointer[ii] + move->dst[ii];
3346 + if (move->pos[ii] < move->rgn[0][ii]) {
3347 + move->pos[ii] = move->rgn[0][ii];
3348 + move->dst[ii] = move->pos[ii] - pointer[ii];
3349 + } else if (move->rgn[1][ii] < move->pos[ii]) {
3350 + move->pos[ii] = move->rgn[1][ii];
3351 + move->dst[ii] = move->pos[ii] - pointer[ii];
3354 + move->v[ii] = wl_fixed_to_double(move->pos[ii] - prepos) / dt;
3356 + if (!move->is_moved &&
3357 + 0 < wl_fixed_to_int(move->pos[ii] - move->start_pos[ii]))
3358 + move->is_moved = 1;
3363 +layer_set_pos(struct ivi_layout_layer *layer, wl_fixed_t pos_x,
3366 + int32_t layout_pos_x = 0;
3367 + int32_t layout_pos_y = 0;
3369 + layout_pos_x = wl_fixed_to_int(pos_x);
3370 + layout_pos_y = wl_fixed_to_int(pos_y);
3371 + ivi_controller_interface->layer_set_position(layer, layout_pos_x, layout_pos_y);
3372 + ivi_controller_interface->commit_changes();
3376 +pointer_move_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
3377 + wl_fixed_t x, wl_fixed_t y)
3379 + struct pointer_move_grab *pnt_move_grab =
3380 + (struct pointer_move_grab *)grab;
3381 + wl_fixed_t pointer_pos[2] = {x, y};
3383 + move_grab_update(&pnt_move_grab->move, pointer_pos);
3384 + layer_set_pos(pnt_move_grab->base.layer,
3385 + pnt_move_grab->move.pos[0], pnt_move_grab->move.pos[1]);
3386 + weston_pointer_move(pnt_move_grab->base.grab.pointer, x, y);
3390 +touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
3391 + int touch_id, wl_fixed_t x, wl_fixed_t y)
3393 + struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
3395 + if (!tch_move_grab->is_active)
3398 + wl_fixed_t pointer_pos[2] = {
3399 + grab->touch->grab_x,
3400 + grab->touch->grab_y
3403 + move_grab_update(&tch_move_grab->move, pointer_pos);
3404 + layer_set_pos(tch_move_grab->base.layer,
3405 + tch_move_grab->move.pos[0], tch_move_grab->move.pos[1]);
3409 +pointer_move_workspace_grab_button(struct weston_pointer_grab *grab,
3410 + uint32_t time, uint32_t button,
3413 + if (BTN_LEFT == button &&
3414 + WL_POINTER_BUTTON_STATE_RELEASED == state_w) {
3415 + struct pointer_grab *pg = (struct pointer_grab *)grab;
3417 + pointer_move_workspace_grab_end(pg);
3423 +touch_nope_grab_down(struct weston_touch_grab *grab, uint32_t time,
3424 + int touch_id, wl_fixed_t sx, wl_fixed_t sy)
3429 +touch_move_workspace_grab_up(struct weston_touch_grab *grab, uint32_t time,
3432 + struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab;
3434 + if (0 == touch_id)
3435 + tch_move_grab->is_active = 0;
3437 + if (0 == grab->touch->num_tp) {
3438 + touch_move_workspace_grab_end(&tch_move_grab->base);
3444 +pointer_move_workspace_grab_cancel(struct weston_pointer_grab *grab)
3446 + struct pointer_grab *pg = (struct pointer_grab *)grab;
3448 + pointer_move_workspace_grab_end(pg);
3453 +touch_move_workspace_grab_frame(struct weston_touch_grab *grab)
3458 +touch_move_workspace_grab_cancel(struct weston_touch_grab *grab)
3460 + struct touch_grab *tg = (struct touch_grab *)grab;
3462 + touch_move_workspace_grab_end(tg);
3466 +static const struct weston_pointer_grab_interface pointer_move_grab_workspace_interface = {
3467 + pointer_noop_grab_focus,
3468 + pointer_move_grab_motion,
3469 + pointer_move_workspace_grab_button,
3470 + pointer_move_workspace_grab_cancel
3473 +static const struct weston_touch_grab_interface touch_move_grab_workspace_interface = {
3474 + touch_nope_grab_down,
3475 + touch_move_workspace_grab_up,
3476 + touch_move_grab_motion,
3477 + touch_move_workspace_grab_frame,
3478 + touch_move_workspace_grab_cancel
3481 +enum HMI_GRAB_DEVICE {
3482 + HMI_GRAB_DEVICE_NONE,
3483 + HMI_GRAB_DEVICE_POINTER,
3484 + HMI_GRAB_DEVICE_TOUCH
3487 +static enum HMI_GRAB_DEVICE
3488 +get_hmi_grab_device(struct weston_seat *seat, uint32_t serial)
3490 + struct weston_pointer *pointer = seat->pointer;
3491 + struct weston_touch *touch = seat->touch;
3495 + pointer->button_count &&
3496 + pointer->grab_serial == serial)
3497 + return HMI_GRAB_DEVICE_POINTER;
3501 + touch->grab_serial == serial)
3502 + return HMI_GRAB_DEVICE_TOUCH;
3504 + return HMI_GRAB_DEVICE_NONE;
3508 +move_grab_init(struct move_grab* move, wl_fixed_t start_pos[2],
3509 + wl_fixed_t grab_pos[2], wl_fixed_t rgn[2][2],
3510 + struct wl_resource* resource)
3512 + clock_gettime(CLOCK_MONOTONIC, &move->start_time); //FIXME
3513 + move->pre_time = move->start_time;
3514 + move->pos[0] = start_pos[0];
3515 + move->pos[1] = start_pos[1];
3516 + move->start_pos[0] = start_pos[0];
3517 + move->start_pos[1] = start_pos[1];
3518 + move->dst[0] = start_pos[0] - grab_pos[0];
3519 + move->dst[1] = start_pos[1] - grab_pos[1];
3520 + memcpy(move->rgn, rgn, sizeof(move->rgn));
3524 +move_grab_init_workspace(struct move_grab* move,
3525 + wl_fixed_t grab_x, wl_fixed_t grab_y,
3526 + struct wl_resource *resource)
3528 + struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
3529 + struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer;
3530 + int32_t workspace_count = hmi_ctrl->workspace_count;
3531 + int32_t workspace_width = hmi_ctrl->workspace_background_layer.width;
3532 + int32_t layer_pos_x = 0;
3533 + int32_t layer_pos_y = 0;
3534 + wl_fixed_t start_pos[2] = {0};
3535 + wl_fixed_t rgn[2][2] = {{0}};
3536 + wl_fixed_t grab_pos[2] = { grab_x, grab_y };
3538 + ivi_controller_interface->layer_get_position(layer, &layer_pos_x, &layer_pos_y);
3540 + start_pos[0] = wl_fixed_from_int(layer_pos_x);
3541 + start_pos[1] = wl_fixed_from_int(layer_pos_y);
3543 + rgn[0][0] = wl_fixed_from_int(-workspace_width * (workspace_count - 1));
3545 + rgn[0][1] = wl_fixed_from_int(0);
3546 + rgn[1][0] = wl_fixed_from_int(0);
3547 + rgn[1][1] = wl_fixed_from_int(0);
3549 + move_grab_init(move, start_pos, grab_pos, rgn, resource);
3552 +static struct pointer_move_grab *
3553 +create_workspace_pointer_move(struct weston_pointer *pointer,
3554 + struct wl_resource* resource)
3556 + struct pointer_move_grab *pnt_move_grab =
3557 + MEM_ALLOC(sizeof(*pnt_move_grab));
3559 + pnt_move_grab->base.resource = resource;
3560 + move_grab_init_workspace(&pnt_move_grab->move, pointer->grab_x,
3561 + pointer->grab_y, resource);
3563 + return pnt_move_grab;
3566 +static struct touch_move_grab *
3567 +create_workspace_touch_move(struct weston_touch *touch,
3568 + struct wl_resource* resource)
3570 + struct touch_move_grab *tch_move_grab =
3571 + MEM_ALLOC(sizeof(*tch_move_grab));
3573 + tch_move_grab->base.resource = resource;
3574 + tch_move_grab->is_active = 1;
3575 + move_grab_init_workspace(&tch_move_grab->move, touch->grab_x,
3576 + touch->grab_y, resource);
3578 + return tch_move_grab;
3582 +ivi_hmi_controller_workspace_control(struct wl_client *client,
3583 + struct wl_resource *resource,
3584 + struct wl_resource *seat_resource,
3587 + struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
3588 + struct ivi_layout_layer *layer = NULL;
3589 + struct pointer_move_grab *pnt_move_grab = NULL;
3590 + struct touch_move_grab *tch_move_grab = NULL;
3591 + struct weston_seat *seat = NULL;
3592 + struct weston_pointer *pointer;
3593 + struct weston_touch *touch;
3595 + enum HMI_GRAB_DEVICE device;
3597 + if (hmi_ctrl->workspace_count < 2)
3600 + seat = wl_resource_get_user_data(seat_resource);
3601 + device = get_hmi_grab_device(seat, serial);
3603 + if (HMI_GRAB_DEVICE_POINTER != device &&
3604 + HMI_GRAB_DEVICE_TOUCH != device)
3607 + layer = hmi_ctrl->workspace_layer.ivilayer;
3609 + ivi_controller_interface->transition_move_layer_cancel(layer);
3612 + case HMI_GRAB_DEVICE_POINTER:
3613 + pointer = seat->pointer;
3614 + pnt_move_grab = create_workspace_pointer_move(pointer,
3617 + pointer_grab_start(&pnt_move_grab->base, layer,
3618 + &pointer_move_grab_workspace_interface,
3622 + case HMI_GRAB_DEVICE_TOUCH:
3623 + touch = seat->touch;
3624 + tch_move_grab = create_workspace_touch_move(touch,
3627 + touch_grab_start(&tch_move_grab->base, layer,
3628 + &touch_move_grab_workspace_interface,
3638 + * Implementation of switch_mode
3641 +ivi_hmi_controller_switch_mode(struct wl_client *client,
3642 + struct wl_resource *resource,
3643 + uint32_t layout_mode)
3645 + struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
3647 + switch_mode(hmi_ctrl, layout_mode);
3651 + * Implementation of on/off displaying workspace and workspace background
3655 +ivi_hmi_controller_home(struct wl_client *client,
3656 + struct wl_resource *resource,
3659 + struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource);
3660 + uint32_t is_fade_in;
3662 + if ((IVI_HMI_CONTROLLER_HOME_ON == home &&
3663 + !hmi_ctrl->workspace_fade.is_fade_in) ||
3664 + (IVI_HMI_CONTROLLER_HOME_OFF == home &&
3665 + hmi_ctrl->workspace_fade.is_fade_in)) {
3666 + is_fade_in = !hmi_ctrl->workspace_fade.is_fade_in;
3667 + hmi_controller_fade_run(hmi_ctrl, is_fade_in,
3668 + &hmi_ctrl->workspace_fade);
3671 + ivi_controller_interface->commit_changes();
3675 + * binding ivi-hmi-controller implementation
3677 +static const struct ivi_hmi_controller_interface ivi_hmi_controller_implementation = {
3678 + ivi_hmi_controller_UI_ready,
3679 + ivi_hmi_controller_workspace_control,
3680 + ivi_hmi_controller_switch_mode,
3681 + ivi_hmi_controller_home
3685 +unbind_hmi_controller(struct wl_resource *resource)
3690 +bind_hmi_controller(struct wl_client *client,
3691 + void *data, uint32_t version, uint32_t id)
3693 + struct wl_resource *resource = NULL;
3694 + struct hmi_controller *hmi_ctrl = data;
3696 + if (hmi_ctrl->user_interface != client) {
3697 + struct wl_resource *res = wl_client_get_object(client, 1);
3698 + wl_resource_post_error(res,
3699 + WL_DISPLAY_ERROR_INVALID_OBJECT,
3700 + "hmi-controller failed: permission denied");
3704 + resource = wl_resource_create(
3705 + client, &ivi_hmi_controller_interface, 1, id);
3707 + wl_resource_set_implementation(
3708 + resource, &ivi_hmi_controller_implementation,
3709 + hmi_ctrl, unbind_hmi_controller);
3713 +handle_hmi_client_process_sigchld(struct weston_process *proc, int status)
3719 +initialize(struct hmi_controller *hmi_ctrl)
3721 + struct config_command {
3726 + struct weston_config *config = hmi_ctrl->compositor->config;
3727 + struct weston_config_section *section = NULL;
3731 + const struct config_command uint_commands[] = {
3732 + { "background-id", &hmi_ctrl->ui_setting.background_id },
3733 + { "panel-id", &hmi_ctrl->ui_setting.panel_id },
3734 + { "tiling-id", &hmi_ctrl->ui_setting.tiling_id },
3735 + { "sidebyside-id", &hmi_ctrl->ui_setting.sidebyside_id },
3736 + { "fullscreen-id", &hmi_ctrl->ui_setting.fullscreen_id },
3737 + { "random-id", &hmi_ctrl->ui_setting.random_id },
3738 + { "home-id", &hmi_ctrl->ui_setting.home_id },
3739 + { "workspace-background-id", &hmi_ctrl->ui_setting.workspace_background_id },
3743 + section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
3745 + for (i = 0; -1 != result; ++i) {
3746 + const struct config_command *command = &uint_commands[i];
3748 + if (!command->key)
3751 + if (weston_config_section_get_uint(
3752 + section, command->key, command->dest, 0) != 0)
3756 + if (-1 == result) {
3757 + weston_log("Failed to initialize hmi-controller\n");
3765 +launch_hmi_client_process(void *data)
3767 + struct hmi_controller *hmi_ctrl =
3768 + (struct hmi_controller *)data;
3770 + hmi_ctrl->user_interface =
3771 + weston_client_launch(hmi_ctrl->compositor,
3772 + &hmi_ctrl->process,
3773 + hmi_ctrl->hmi_setting->ivi_homescreen,
3774 + handle_hmi_client_process_sigchld);
3776 + free(hmi_ctrl->hmi_setting->ivi_homescreen);
3779 +/*****************************************************************************
3780 + * exported functions
3781 + ****************************************************************************/
3783 +controller_module_init(struct weston_compositor *ec,
3784 + int *argc, char *argv[],
3785 + const struct ivi_controller_interface *interface,
3786 + size_t interface_version)
3788 + struct hmi_controller *hmi_ctrl = NULL;
3789 + struct wl_event_loop *loop = NULL;
3791 + if (interface_version < sizeof(struct ivi_controller_interface)) {
3792 + weston_log("ivi-shell: version mismatch of controller interface");
3796 + ivi_controller_interface = interface;
3798 + hmi_ctrl = hmi_controller_create(ec);
3800 + if (!initialize(hmi_ctrl)) {
3804 + if (wl_global_create(ec->wl_display,
3805 + &ivi_hmi_controller_interface, 1,
3806 + hmi_ctrl, bind_hmi_controller) == NULL) {
3810 + loop = wl_display_get_event_loop(ec->wl_display);
3811 + wl_event_loop_add_idle(loop, launch_hmi_client_process, hmi_ctrl);
3815 diff --git a/ivi-shell/input-panel-ivi.c b/ivi-shell/input-panel-ivi.c
3816 new file mode 100644
3817 index 0000000..51d2b8a
3819 +++ b/ivi-shell/input-panel-ivi.c
3822 + * Copyright © 2010-2012 Intel Corporation
3823 + * Copyright © 2011-2012 Collabora, Ltd.
3824 + * Copyright © 2013 Raspberry Pi Foundation
3826 + * Permission is hereby granted, free of charge, to any person obtaining
3827 + * a copy of this software and associated documentation files (the
3828 + * "Software"), to deal in the Software without restriction, including
3829 + * without limitation the rights to use, copy, modify, merge, publish,
3830 + * distribute, sublicense, and/or sell copies of the Software, and to
3831 + * permit persons to whom the Software is furnished to do so, subject to
3832 + * the following conditions:
3834 + * The above copyright notice and this permission notice (including the
3835 + * next paragraph) shall be included in all copies or substantial
3836 + * portions of the Software.
3838 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3839 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3840 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
3841 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
3842 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
3843 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
3844 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3848 +#include "config.h"
3850 +#include <stdlib.h>
3852 +#include <string.h>
3854 +#include "ivi-shell.h"
3855 +#include "input-method-server-protocol.h"
3856 +#include "ivi-layout-private.h"
3857 +#include "shared/helpers.h"
3859 +struct input_panel_surface {
3860 + struct wl_resource *resource;
3861 + struct wl_signal destroy_signal;
3863 + struct ivi_shell *shell;
3865 + struct wl_list link;
3866 + struct weston_surface *surface;
3867 + struct weston_view *view;
3868 + struct wl_listener surface_destroy_listener;
3870 + struct weston_view_animation *anim;
3872 + struct weston_output *output;
3877 +input_panel_slide_done(struct weston_view_animation *animation, void *data)
3879 + struct input_panel_surface *ipsurf = data;
3881 + ipsurf->anim = NULL;
3885 +show_input_panel_surface(struct input_panel_surface *ipsurf)
3887 + struct ivi_shell *shell = ipsurf->shell;
3888 + struct weston_seat *seat;
3889 + struct weston_surface *focus;
3892 + wl_list_for_each(seat, &shell->compositor->seat_list, link) {
3893 + struct weston_keyboard *keyboard = seat->keyboard;
3895 + if (!keyboard || !keyboard->focus)
3897 + focus = weston_surface_get_main_surface(keyboard->focus);
3898 + ipsurf->output = focus->output;
3899 + x = ipsurf->output->x + (ipsurf->output->width - ipsurf->surface->width) / 2;
3900 + y = ipsurf->output->y + ipsurf->output->height - ipsurf->surface->height;
3901 + weston_view_set_position(ipsurf->view, x, y);
3904 + wl_list_insert(&shell->input_panel_layer.view_list,
3905 + &ipsurf->view->layer_link);
3906 + weston_view_geometry_dirty(ipsurf->view);
3907 + weston_view_update_transform(ipsurf->view);
3908 + weston_surface_damage(ipsurf->surface);
3911 + weston_view_animation_destroy(ipsurf->anim);
3914 + weston_slide_run(ipsurf->view,
3915 + ipsurf->surface->height * 0.9, 0,
3916 + input_panel_slide_done, ipsurf);
3920 +show_input_panels(struct wl_listener *listener, void *data)
3922 + struct ivi_shell *shell =
3923 + container_of(listener, struct ivi_shell,
3924 + show_input_panel_listener);
3925 + struct input_panel_surface *ipsurf, *next;
3927 + shell->text_input.surface = (struct weston_surface*)data;
3929 + if (shell->showing_input_panels)
3932 + shell->showing_input_panels = true;
3934 + if (!shell->locked)
3935 + wl_list_insert(&shell->compositor->cursor_layer.link,
3936 + &shell->input_panel_layer.link);
3938 + wl_list_for_each_safe(ipsurf, next,
3939 + &shell->input_panel.surfaces, link) {
3940 + if (ipsurf->surface->width == 0)
3943 + show_input_panel_surface(ipsurf);
3948 +hide_input_panels(struct wl_listener *listener, void *data)
3950 + struct ivi_shell *shell =
3951 + container_of(listener, struct ivi_shell,
3952 + hide_input_panel_listener);
3953 + struct weston_view *view, *next;
3955 + if (!shell->showing_input_panels)
3958 + shell->showing_input_panels = false;
3960 + if (!shell->locked)
3961 + wl_list_remove(&shell->input_panel_layer.link);
3963 + wl_list_for_each_safe(view, next,
3964 + &shell->input_panel_layer.view_list,
3966 + weston_view_unmap(view);
3970 +update_input_panels(struct wl_listener *listener, void *data)
3972 + struct ivi_shell *shell =
3973 + container_of(listener, struct ivi_shell,
3974 + update_input_panel_listener);
3976 + memcpy(&shell->text_input.cursor_rectangle, data, sizeof(pixman_box32_t));
3980 +input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
3982 + struct input_panel_surface *ip_surface = surface->configure_private;
3983 + struct ivi_shell *shell = ip_surface->shell;
3984 + struct weston_view *view;
3987 + if (surface->width == 0)
3990 + if (ip_surface->panel) {
3991 + view = get_default_view(shell->text_input.surface);
3994 + x = view->geometry.x + shell->text_input.cursor_rectangle.x2;
3995 + y = view->geometry.y + shell->text_input.cursor_rectangle.y2;
3997 + x = ip_surface->output->x + (ip_surface->output->width - surface->width) / 2;
3998 + y = ip_surface->output->y + ip_surface->output->height - surface->height;
4001 + weston_view_set_position(ip_surface->view, x, y);
4003 + if (!weston_surface_is_mapped(surface) && shell->showing_input_panels)
4004 + show_input_panel_surface(ip_surface);
4008 +destroy_input_panel_surface(struct input_panel_surface *input_panel_surface)
4010 + wl_signal_emit(&input_panel_surface->destroy_signal, input_panel_surface);
4012 + wl_list_remove(&input_panel_surface->surface_destroy_listener.link);
4013 + wl_list_remove(&input_panel_surface->link);
4015 + input_panel_surface->surface->configure = NULL;
4016 + weston_view_destroy(input_panel_surface->view);
4018 + free(input_panel_surface);
4021 +static struct input_panel_surface *
4022 +get_input_panel_surface(struct weston_surface *surface)
4024 + if (surface->configure == input_panel_configure) {
4025 + return surface->configure_private;
4032 +input_panel_handle_surface_destroy(struct wl_listener *listener, void *data)
4034 + struct input_panel_surface *ipsurface = container_of(listener,
4035 + struct input_panel_surface,
4036 + surface_destroy_listener);
4038 + if (ipsurface->resource) {
4039 + wl_resource_destroy(ipsurface->resource);
4041 + destroy_input_panel_surface(ipsurface);
4045 +static struct input_panel_surface *
4046 +create_input_panel_surface(struct ivi_shell *shell,
4047 + struct weston_surface *surface)
4049 + struct input_panel_surface *input_panel_surface;
4051 + input_panel_surface = calloc(1, sizeof *input_panel_surface);
4052 + if (!input_panel_surface)
4055 + surface->configure = input_panel_configure;
4056 + surface->configure_private = input_panel_surface;
4058 + input_panel_surface->shell = shell;
4060 + input_panel_surface->surface = surface;
4061 + input_panel_surface->view = weston_view_create(surface);
4063 + wl_signal_init(&input_panel_surface->destroy_signal);
4064 + input_panel_surface->surface_destroy_listener.notify = input_panel_handle_surface_destroy;
4065 + wl_signal_add(&surface->destroy_signal,
4066 + &input_panel_surface->surface_destroy_listener);
4068 + wl_list_init(&input_panel_surface->link);
4070 + return input_panel_surface;
4074 +input_panel_surface_set_toplevel(struct wl_client *client,
4075 + struct wl_resource *resource,
4076 + struct wl_resource *output_resource,
4077 + uint32_t position)
4079 + struct input_panel_surface *input_panel_surface =
4080 + wl_resource_get_user_data(resource);
4081 + struct ivi_shell *shell = input_panel_surface->shell;
4083 + wl_list_insert(&shell->input_panel.surfaces,
4084 + &input_panel_surface->link);
4086 + input_panel_surface->output = wl_resource_get_user_data(output_resource);
4087 + input_panel_surface->panel = 0;
4091 +input_panel_surface_set_overlay_panel(struct wl_client *client,
4092 + struct wl_resource *resource)
4094 + struct input_panel_surface *input_panel_surface =
4095 + wl_resource_get_user_data(resource);
4096 + struct ivi_shell *shell = input_panel_surface->shell;
4098 + wl_list_insert(&shell->input_panel.surfaces,
4099 + &input_panel_surface->link);
4101 + input_panel_surface->panel = 1;
4104 +static const struct wl_input_panel_surface_interface input_panel_surface_implementation = {
4105 + input_panel_surface_set_toplevel,
4106 + input_panel_surface_set_overlay_panel
4110 +destroy_input_panel_surface_resource(struct wl_resource *resource)
4112 + struct input_panel_surface *ipsurf =
4113 + wl_resource_get_user_data(resource);
4115 + destroy_input_panel_surface(ipsurf);
4119 +input_panel_get_input_panel_surface(struct wl_client *client,
4120 + struct wl_resource *resource,
4122 + struct wl_resource *surface_resource)
4124 + struct weston_surface *surface =
4125 + wl_resource_get_user_data(surface_resource);
4126 + struct ivi_shell *shell = wl_resource_get_user_data(resource);
4127 + struct input_panel_surface *ipsurf;
4129 + if (get_input_panel_surface(surface)) {
4130 + wl_resource_post_error(surface_resource,
4131 + WL_DISPLAY_ERROR_INVALID_OBJECT,
4132 + "wl_input_panel::get_input_panel_surface already requested");
4136 + ipsurf = create_input_panel_surface(shell, surface);
4138 + wl_resource_post_error(surface_resource,
4139 + WL_DISPLAY_ERROR_INVALID_OBJECT,
4140 + "surface->configure already set");
4144 + ipsurf->resource =
4145 + wl_resource_create(client,
4146 + &wl_input_panel_surface_interface, 1, id);
4147 + wl_resource_set_implementation(ipsurf->resource,
4148 + &input_panel_surface_implementation,
4150 + destroy_input_panel_surface_resource);
4153 +static const struct wl_input_panel_interface input_panel_implementation = {
4154 + input_panel_get_input_panel_surface
4158 +unbind_input_panel(struct wl_resource *resource)
4160 + struct ivi_shell *shell = wl_resource_get_user_data(resource);
4162 + shell->input_panel.binding = NULL;
4166 +bind_input_panel(struct wl_client *client,
4167 + void *data, uint32_t version, uint32_t id)
4169 + struct ivi_shell *shell = data;
4170 + struct wl_resource *resource;
4172 + resource = wl_resource_create(client,
4173 + &wl_input_panel_interface, 1, id);
4175 + if (shell->input_panel.binding == NULL) {
4176 + wl_resource_set_implementation(resource,
4177 + &input_panel_implementation,
4178 + shell, unbind_input_panel);
4179 + shell->input_panel.binding = resource;
4183 + wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
4184 + "interface object already bound");
4188 +input_panel_destroy(struct ivi_shell *shell)
4190 + wl_list_remove(&shell->show_input_panel_listener.link);
4191 + wl_list_remove(&shell->hide_input_panel_listener.link);
4195 +input_panel_setup(struct ivi_shell *shell)
4197 + struct weston_compositor *ec = shell->compositor;
4199 + shell->show_input_panel_listener.notify = show_input_panels;
4200 + wl_signal_add(&ec->show_input_panel_signal,
4201 + &shell->show_input_panel_listener);
4202 + shell->hide_input_panel_listener.notify = hide_input_panels;
4203 + wl_signal_add(&ec->hide_input_panel_signal,
4204 + &shell->hide_input_panel_listener);
4205 + shell->update_input_panel_listener.notify = update_input_panels;
4206 + wl_signal_add(&ec->update_input_panel_signal,
4207 + &shell->update_input_panel_listener);
4209 + wl_list_init(&shell->input_panel.surfaces);
4211 + if (wl_global_create(shell->compositor->wl_display,
4212 + &wl_input_panel_interface, 1,
4213 + shell, bind_input_panel) == NULL)
4218 diff --git a/ivi-shell/ivi-layout-export.h b/ivi-shell/ivi-layout-export.h
4219 new file mode 100644
4220 index 0000000..8a92009
4222 +++ b/ivi-shell/ivi-layout-export.h
4225 + * Copyright (C) 2013 DENSO CORPORATION
4227 + * Permission is hereby granted, free of charge, to any person obtaining
4228 + * a copy of this software and associated documentation files (the
4229 + * "Software"), to deal in the Software without restriction, including
4230 + * without limitation the rights to use, copy, modify, merge, publish,
4231 + * distribute, sublicense, and/or sell copies of the Software, and to
4232 + * permit persons to whom the Software is furnished to do so, subject to
4233 + * the following conditions:
4235 + * The above copyright notice and this permission notice (including the
4236 + * next paragraph) shall be included in all copies or substantial
4237 + * portions of the Software.
4239 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
4240 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
4241 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
4242 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
4243 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
4244 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
4245 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
4250 + * The ivi-layout library supports API set of controlling properties of
4251 + * surface and layer which groups surfaces. An unique ID whose type is integer
4252 + * is required to create surface and layer. With the unique ID, surface and
4253 + * layer are identified to control them. The API set consists of APIs to control
4254 + * properties of surface and layers about followings,
4257 + * - clipping (x,y,width,height).
4258 + * - position and size of it to be displayed.
4259 + * - orientation per 90 degree.
4260 + * - add or remove surfaces to a layer.
4261 + * - order of surfaces/layers in layer/screen to be displayed.
4262 + * - commit to apply property changes.
4263 + * - notifications of property change.
4265 + * Management of surfaces and layers grouping these surfaces are common
4266 + * way in In-Vehicle Infotainment system, which integrate several domains
4267 + * in one system. A layer is allocated to a domain in order to control
4268 + * application surfaces grouped to the layer all together.
4270 + * This API and ABI follow following specifications.
4271 + * http://projects.genivi.org/wayland-ivi-extension/layer-manager-apis
4274 +#ifndef _IVI_LAYOUT_EXPORT_H_
4275 +#define _IVI_LAYOUT_EXPORT_H_
4279 +#endif /* __cplusplus */
4281 +#include "stdbool.h"
4282 +#include "compositor.h"
4284 +#define IVI_SUCCEEDED (0)
4285 +#define IVI_FAILED (-1)
4287 +struct ivi_layout_layer;
4288 +struct ivi_layout_screen;
4289 +struct ivi_layout_surface;
4291 +struct ivi_layout_surface_properties
4293 + wl_fixed_t opacity;
4296 + int32_t source_width;
4297 + int32_t source_height;
4300 + int32_t start_width;
4301 + int32_t start_height;
4304 + int32_t dest_width;
4305 + int32_t dest_height;
4306 + enum wl_output_transform orientation;
4308 + int32_t transition_type;
4309 + uint32_t transition_duration;
4312 +struct ivi_layout_layer_properties
4314 + wl_fixed_t opacity;
4317 + int32_t source_width;
4318 + int32_t source_height;
4321 + int32_t dest_width;
4322 + int32_t dest_height;
4323 + enum wl_output_transform orientation;
4324 + uint32_t visibility;
4325 + int32_t transition_type;
4326 + uint32_t transition_duration;
4327 + double start_alpha;
4329 + uint32_t is_fade_in;
4332 +enum ivi_layout_notification_mask {
4333 + IVI_NOTIFICATION_NONE = 0,
4334 + IVI_NOTIFICATION_OPACITY = (1 << 1),
4335 + IVI_NOTIFICATION_SOURCE_RECT = (1 << 2),
4336 + IVI_NOTIFICATION_DEST_RECT = (1 << 3),
4337 + IVI_NOTIFICATION_DIMENSION = (1 << 4),
4338 + IVI_NOTIFICATION_POSITION = (1 << 5),
4339 + IVI_NOTIFICATION_ORIENTATION = (1 << 6),
4340 + IVI_NOTIFICATION_VISIBILITY = (1 << 7),
4341 + IVI_NOTIFICATION_PIXELFORMAT = (1 << 8),
4342 + IVI_NOTIFICATION_ADD = (1 << 9),
4343 + IVI_NOTIFICATION_REMOVE = (1 << 10),
4344 + IVI_NOTIFICATION_CONFIGURE = (1 << 11),
4345 + IVI_NOTIFICATION_ALL = 0xFFFF
4348 +enum ivi_layout_transition_type{
4349 + IVI_LAYOUT_TRANSITION_NONE,
4350 + IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
4351 + IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY,
4352 + IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY,
4353 + IVI_LAYOUT_TRANSITION_LAYER_FADE,
4354 + IVI_LAYOUT_TRANSITION_LAYER_MOVE,
4355 + IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
4356 + IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
4357 + IVI_LAYOUT_TRANSITION_VIEW_RESIZE,
4358 + IVI_LAYOUT_TRANSITION_VIEW_FADE,
4359 + IVI_LAYOUT_TRANSITION_MAX,
4362 +typedef void (*layer_property_notification_func)(
4363 + struct ivi_layout_layer *ivilayer,
4364 + const struct ivi_layout_layer_properties *,
4365 + enum ivi_layout_notification_mask mask,
4368 +typedef void (*surface_property_notification_func)(
4369 + struct ivi_layout_surface *ivisurf,
4370 + const struct ivi_layout_surface_properties *,
4371 + enum ivi_layout_notification_mask mask,
4374 +typedef void (*layer_create_notification_func)(
4375 + struct ivi_layout_layer *ivilayer,
4378 +typedef void (*layer_remove_notification_func)(
4379 + struct ivi_layout_layer *ivilayer,
4382 +typedef void (*surface_create_notification_func)(
4383 + struct ivi_layout_surface *ivisurf,
4386 +typedef void (*surface_remove_notification_func)(
4387 + struct ivi_layout_surface *ivisurf,
4390 +typedef void (*surface_configure_notification_func)(
4391 + struct ivi_layout_surface *ivisurf,
4394 +typedef void (*ivi_controller_surface_content_callback)(
4395 + struct ivi_layout_surface *ivisurf,
4399 +struct ivi_controller_interface {
4402 + * \brief Commit all changes and execute all enqueued commands since
4405 + * \return IVI_SUCCEEDED if the method call was successful
4406 + * \return IVI_FAILED if the method call was failed
4408 + int32_t (*commit_changes)(void);
4411 + * surface controller interface
4415 + * \brief register/unregister for notification when ivi_surface is created
4417 + int32_t (*add_notification_create_surface)(
4418 + surface_create_notification_func callback,
4421 + void (*remove_notification_create_surface)(
4422 + surface_create_notification_func callback,
4426 + * \brief register/unregister for notification when ivi_surface is removed
4428 + int32_t (*add_notification_remove_surface)(
4429 + surface_remove_notification_func callback,
4432 + void (*remove_notification_remove_surface)(
4433 + surface_remove_notification_func callback,
4437 + * \brief register/unregister for notification when ivi_surface is configured
4439 + int32_t (*add_notification_configure_surface)(
4440 + surface_configure_notification_func callback,
4443 + void (*remove_notification_configure_surface)(
4444 + surface_configure_notification_func callback,
4448 + * \brief Get all ivi_surfaces which are currently registered and managed
4451 + * \return IVI_SUCCEEDED if the method call was successful
4452 + * \return IVI_FAILED if the method call was failed
4454 + int32_t (*get_surfaces)(int32_t *pLength, struct ivi_layout_surface ***ppArray);
4457 + * \brief get id of ivi_surface from ivi_layout_surface
4459 + * \return id of ivi_surface
4461 + uint32_t (*get_id_of_surface)(struct ivi_layout_surface *ivisurf);
4464 + * \brief get ivi_layout_surface from id of ivi_surface
4466 + * \return (struct ivi_layout_surface *)
4467 + * if the method call was successful
4468 + * \return NULL if the method call was failed
4470 + struct ivi_layout_surface *
4471 + (*get_surface_from_id)(uint32_t id_surface);
4474 + * \brief get ivi_layout_surface_properties from ivisurf
4476 + * \return (struct ivi_layout_surface_properties *)
4477 + * if the method call was successful
4478 + * \return NULL if the method call was failed
4480 + const struct ivi_layout_surface_properties *
4481 + (*get_properties_of_surface)(struct ivi_layout_surface *ivisurf);
4484 + * \brief Get all Surfaces which are currently registered to a given
4485 + * layer and are managed by the services
4487 + * \return IVI_SUCCEEDED if the method call was successful
4488 + * \return IVI_FAILED if the method call was failed
4490 + int32_t (*get_surfaces_on_layer)(struct ivi_layout_layer *ivilayer,
4492 + struct ivi_layout_surface ***ppArray);
4495 + * \brief Set the visibility of a ivi_surface.
4497 + * If a surface is not visible it will not be rendered.
4499 + * \return IVI_SUCCEEDED if the method call was successful
4500 + * \return IVI_FAILED if the method call was failed
4502 + int32_t (*surface_set_visibility)(struct ivi_layout_surface *ivisurf,
4503 + bool newVisibility);
4506 + * \brief Get the visibility of a surface.
4508 + * If a surface is not visible it will not be rendered.
4510 + * \return true if surface is visible
4511 + * \return false if surface is invisible or the method call was failed
4513 + bool (*surface_get_visibility)(struct ivi_layout_surface *ivisurf);
4516 + * \brief Set the opacity of a surface.
4518 + * \return IVI_SUCCEEDED if the method call was successful
4519 + * \return IVI_FAILED if the method call was failed
4521 + int32_t (*surface_set_opacity)(struct ivi_layout_surface *ivisurf,
4522 + wl_fixed_t opacity);
4525 + * \brief Get the opacity of a ivi_surface.
4527 + * \return opacity if the method call was successful
4528 + * \return wl_fixed_from_double(0.0) if the method call was failed
4530 + wl_fixed_t (*surface_get_opacity)(struct ivi_layout_surface *ivisurf);
4533 + * \brief Set the area of a ivi_surface which should be used for the rendering.
4535 + * \return IVI_SUCCEEDED if the method call was successful
4536 + * \return IVI_FAILED if the method call was failed
4538 + int32_t (*surface_set_source_rectangle)(struct ivi_layout_surface *ivisurf,
4539 + int32_t x, int32_t y,
4540 + int32_t width, int32_t height);
4543 + * \brief Set the destination area of a ivi_surface within a ivi_layer
4546 + * The surface will be scaled to this rectangle for rendering.
4548 + * \return IVI_SUCCEEDED if the method call was successful
4549 + * \return IVI_FAILED if the method call was failed
4551 + int32_t (*surface_set_destination_rectangle)(struct ivi_layout_surface *ivisurf,
4552 + int32_t x, int32_t y,
4553 + int32_t width, int32_t height);
4556 + * \brief Sets the horizontal and vertical position of the surface.
4558 + * \return IVI_SUCCEEDED if the method call was successful
4559 + * \return IVI_FAILED if the method call was failed
4561 + int32_t (*surface_set_position)(struct ivi_layout_surface *ivisurf,
4562 + int32_t dest_x, int32_t dest_y);
4565 + * \brief Get the horizontal and vertical position of the surface.
4567 + * \return IVI_SUCCEEDED if the method call was successful
4568 + * \return IVI_FAILED if the method call was failed
4570 + int32_t (*surface_get_position)(struct ivi_layout_surface *ivisurf,
4571 + int32_t *dest_x, int32_t *dest_y);
4574 + * \brief Set the horizontal and vertical dimension of the surface.
4576 + * \return IVI_SUCCEEDED if the method call was successful
4577 + * \return IVI_FAILED if the method call was failed
4579 + int32_t (*surface_set_dimension)(struct ivi_layout_surface *ivisurf,
4580 + int32_t dest_width, int32_t dest_height);
4583 + * \brief Get the horizontal and vertical dimension of the surface.
4585 + * \return IVI_SUCCEEDED if the method call was successful
4586 + * \return IVI_FAILED if the method call was failed
4588 + int32_t (*surface_get_dimension)(struct ivi_layout_surface *ivisurf,
4589 + int32_t *dest_width, int32_t *dest_height);
4592 + * \brief Sets the orientation of a ivi_surface.
4594 + * \return IVI_SUCCEEDED if the method call was successful
4595 + * \return IVI_FAILED if the method call was failed
4597 + int32_t (*surface_set_orientation)(struct ivi_layout_surface *ivisurf,
4598 + enum wl_output_transform orientation);
4601 + * \brief Gets the orientation of a surface.
4603 + * \return (enum wl_output_transform)
4604 + * if the method call was successful
4605 + * \return WL_OUTPUT_TRANSFORM_NORMAL if the method call was failed
4607 + enum wl_output_transform
4608 + (*surface_get_orientation)(struct ivi_layout_surface *ivisurf);
4611 + * \brief Set an observer callback for ivi_surface content status change.
4613 + * \return IVI_SUCCEEDED if the method call was successful
4614 + * \return IVI_FAILED if the method call was failed
4616 + int32_t (*surface_set_content_observer)(
4617 + struct ivi_layout_surface *ivisurf,
4618 + ivi_controller_surface_content_callback callback,
4622 + * \brief register for notification on property changes of ivi_surface
4624 + * \return IVI_SUCCEEDED if the method call was successful
4625 + * \return IVI_FAILED if the method call was failed
4627 + int32_t (*surface_add_notification)(struct ivi_layout_surface *ivisurf,
4628 + surface_property_notification_func callback,
4632 + * \brief remove notification on property changes of ivi_surface
4634 + void (*surface_remove_notification)(struct ivi_layout_surface *ivisurf);
4637 + * \brief get weston_surface of ivi_surface
4639 + struct weston_surface *
4640 + (*surface_get_weston_surface)(struct ivi_layout_surface *ivisurf);
4643 + * \brief set type of transition animation
4645 + int32_t (*surface_set_transition)(struct ivi_layout_surface *ivisurf,
4646 + enum ivi_layout_transition_type type,
4647 + uint32_t duration);
4650 + * \brief set duration of transition animation
4652 + int32_t (*surface_set_transition_duration)(
4653 + struct ivi_layout_surface *ivisurf,
4654 + uint32_t duration);
4657 + * layer controller interface
4661 + * \brief register/unregister for notification when ivi_layer is created
4663 + int32_t (*add_notification_create_layer)(
4664 + layer_create_notification_func callback,
4667 + void (*remove_notification_create_layer)(
4668 + layer_create_notification_func callback,
4672 + * \brief register/unregister for notification when ivi_layer is removed
4674 + int32_t (*add_notification_remove_layer)(
4675 + layer_remove_notification_func callback,
4678 + void (*remove_notification_remove_layer)(
4679 + layer_remove_notification_func callback,
4683 + * \brief Create a ivi_layer which should be managed by the service
4685 + * \return (struct ivi_layout_layer *)
4686 + * if the method call was successful
4687 + * \return NULL if the method call was failed
4689 + struct ivi_layout_layer *
4690 + (*layer_create_with_dimension)(uint32_t id_layer,
4691 + int32_t width, int32_t height);
4694 + * \brief Removes a ivi_layer which is currently managed by the service
4696 + void (*layer_destroy)(struct ivi_layout_layer *ivilayer);
4699 + * \brief Get all ivi_layers which are currently registered and managed
4702 + * \return IVI_SUCCEEDED if the method call was successful
4703 + * \return IVI_FAILED if the method call was failed
4705 + int32_t (*get_layers)(int32_t *pLength, struct ivi_layout_layer ***ppArray);
4708 + * \brief get id of ivi_layer from ivi_layout_layer
4711 + * \return id of ivi_layer
4713 + uint32_t (*get_id_of_layer)(struct ivi_layout_layer *ivilayer);
4716 + * \brief get ivi_layout_layer from id of layer
4718 + * \return (struct ivi_layout_layer *)
4719 + * if the method call was successful
4720 + * \return NULL if the method call was failed
4722 + struct ivi_layout_layer * (*get_layer_from_id)(uint32_t id_layer);
4725 + * \brief Get the ivi_layer properties
4727 + * \return (const struct ivi_layout_layer_properties *)
4728 + * if the method call was successful
4729 + * \return NULL if the method call was failed
4731 + const struct ivi_layout_layer_properties *
4732 + (*get_properties_of_layer)(struct ivi_layout_layer *ivilayer);
4735 + * \brief Get all ivi_ayers under the given ivi_surface
4737 + * \return IVI_SUCCEEDED if the method call was successful
4738 + * \return IVI_FAILED if the method call was failed
4740 + int32_t (*get_layers_under_surface)(struct ivi_layout_surface *ivisurf,
4742 + struct ivi_layout_layer ***ppArray);
4745 + * \brief Get all Layers of the given screen
4747 + * \return IVI_SUCCEEDED if the method call was successful
4748 + * \return IVI_FAILED if the method call was failed
4750 + int32_t (*get_layers_on_screen)(struct ivi_layout_screen *iviscrn,
4752 + struct ivi_layout_layer ***ppArray);
4755 + * \brief Set the visibility of a ivi_layer. If a ivi_layer is not visible,
4756 + * the ivi_layer and its ivi_surfaces will not be rendered.
4758 + * \return IVI_SUCCEEDED if the method call was successful
4759 + * \return IVI_FAILED if the method call was failed
4761 + int32_t (*layer_set_visibility)(struct ivi_layout_layer *ivilayer,
4762 + bool newVisibility);
4765 + * \brief Get the visibility of a layer. If a layer is not visible,
4766 + * the layer and its surfaces will not be rendered.
4768 + * \return true if layer is visible
4769 + * \return false if layer is invisible or the method call was failed
4771 + bool (*layer_get_visibility)(struct ivi_layout_layer *ivilayer);
4774 + * \brief Set the opacity of a ivi_layer.
4776 + * \return IVI_SUCCEEDED if the method call was successful
4777 + * \return IVI_FAILED if the method call was failed
4779 + int32_t (*layer_set_opacity)(struct ivi_layout_layer *ivilayer,
4780 + wl_fixed_t opacity);
4783 + * \brief Get the opacity of a ivi_layer.
4785 + * \return opacity if the method call was successful
4786 + * \return wl_fixed_from_double(0.0) if the method call was failed
4788 + wl_fixed_t (*layer_get_opacity)(struct ivi_layout_layer *ivilayer);
4791 + * \brief Set the area of a ivi_layer which should be used for the rendering.
4793 + * Only this part will be visible.
4795 + * \return IVI_SUCCEEDED if the method call was successful
4796 + * \return IVI_FAILED if the method call was failed
4798 + int32_t (*layer_set_source_rectangle)(struct ivi_layout_layer *ivilayer,
4799 + int32_t x, int32_t y,
4800 + int32_t width, int32_t height);
4803 + * \brief Set the destination area on the display for a ivi_layer.
4805 + * The ivi_layer will be scaled and positioned to this rectangle
4808 + * \return IVI_SUCCEEDED if the method call was successful
4809 + * \return IVI_FAILED if the method call was failed
4811 + int32_t (*layer_set_destination_rectangle)(struct ivi_layout_layer *ivilayer,
4812 + int32_t x, int32_t y,
4813 + int32_t width, int32_t height);
4816 + * \brief Sets the horizontal and vertical position of the ivi_layer.
4818 + * \return IVI_SUCCEEDED if the method call was successful
4819 + * \return IVI_FAILED if the method call was failed
4821 + int32_t (*layer_set_position)(struct ivi_layout_layer *ivilayer,
4822 + int32_t dest_x, int32_t dest_y);
4825 + * \brief Get the horizontal and vertical position of the ivi_layer.
4827 + * \return IVI_SUCCEEDED if the method call was successful
4828 + * \return IVI_FAILED if the method call was failed
4830 + int32_t (*layer_get_position)(struct ivi_layout_layer *ivilayer,
4831 + int32_t *dest_x, int32_t *dest_y);
4834 + * \brief Set the horizontal and vertical dimension of the layer.
4836 + * \return IVI_SUCCEEDED if the method call was successful
4837 + * \return IVI_FAILED if the method call was failed
4839 + int32_t (*layer_set_dimension)(struct ivi_layout_layer *ivilayer,
4840 + int32_t dest_width, int32_t dest_height);
4843 + * \brief Get the horizontal and vertical dimension of the layer.
4845 + * \return IVI_SUCCEEDED if the method call was successful
4846 + * \return IVI_FAILED if the method call was failed
4848 + int32_t (*layer_get_dimension)(struct ivi_layout_layer *ivilayer,
4849 + int32_t *dest_width, int32_t *dest_height);
4852 + * \brief Sets the orientation of a ivi_layer.
4854 + * \return IVI_SUCCEEDED if the method call was successful
4855 + * \return IVI_FAILED if the method call was failed
4857 + int32_t (*layer_set_orientation)(struct ivi_layout_layer *ivilayer,
4858 + enum wl_output_transform orientation);
4861 + * \brief Gets the orientation of a layer.
4863 + * \return (enum wl_output_transform)
4864 + * if the method call was successful
4865 + * \return WL_OUTPUT_TRANSFORM_NORMAL if the method call was failed
4867 + enum wl_output_transform
4868 + (*layer_get_orientation)(struct ivi_layout_layer *ivilayer);
4871 + * \brief Add a ivi_surface to a ivi_layer which is currently managed by the service
4873 + * \return IVI_SUCCEEDED if the method call was successful
4874 + * \return IVI_FAILED if the method call was failed
4876 + int32_t (*layer_add_surface)(struct ivi_layout_layer *ivilayer,
4877 + struct ivi_layout_surface *addsurf);
4880 + * \brief Removes a surface from a layer which is currently managed by the service
4882 + void (*layer_remove_surface)(struct ivi_layout_layer *ivilayer,
4883 + struct ivi_layout_surface *remsurf);
4886 + * \brief Sets render order of ivi_surfaces within a ivi_layer
4888 + * \return IVI_SUCCEEDED if the method call was successful
4889 + * \return IVI_FAILED if the method call was failed
4891 + int32_t (*layer_set_render_order)(struct ivi_layout_layer *ivilayer,
4892 + struct ivi_layout_surface **pSurface,
4896 + * \brief register for notification on property changes of ivi_layer
4898 + * \return IVI_SUCCEEDED if the method call was successful
4899 + * \return IVI_FAILED if the method call was failed
4901 + int32_t (*layer_add_notification)(struct ivi_layout_layer *ivilayer,
4902 + layer_property_notification_func callback,
4906 + * \brief remove notification on property changes of ivi_layer
4908 + void (*layer_remove_notification)(struct ivi_layout_layer *ivilayer);
4911 + * \brief set type of transition animation
4913 + int32_t (*layer_set_transition)(struct ivi_layout_layer *ivilayer,
4914 + enum ivi_layout_transition_type type,
4915 + uint32_t duration);
4918 + * screen controller interface
4922 + * \brief get ivi_layout_screen from id of ivi_screen
4924 + * \return (struct ivi_layout_screen *)
4925 + * if the method call was successful
4926 + * \return NULL if the method call was failed
4928 + struct ivi_layout_screen *
4929 + (*get_screen_from_id)(uint32_t id_screen);
4932 + * \brief Get the screen resolution of a specific ivi_screen
4934 + * \return IVI_SUCCEEDED if the method call was successful
4935 + * \return IVI_FAILED if the method call was failed
4937 + int32_t (*get_screen_resolution)(struct ivi_layout_screen *iviscrn,
4939 + int32_t *pHeight);
4942 + * \brief Get the ivi_screens
4944 + * \return IVI_SUCCEEDED if the method call was successful
4945 + * \return IVI_FAILED if the method call was failed
4947 + int32_t (*get_screens)(int32_t *pLength, struct ivi_layout_screen ***ppArray);
4950 + * \brief Get the ivi_screens under the given ivi_layer
4952 + * \return IVI_SUCCEEDED if the method call was successful
4953 + * \return IVI_FAILED if the method call was failed
4955 + int32_t (*get_screens_under_layer)(struct ivi_layout_layer *ivilayer,
4957 + struct ivi_layout_screen ***ppArray);
4960 + * \brief Add a ivi_layer to a ivi_screen which is currently managed
4963 + * \return IVI_SUCCEEDED if the method call was successful
4964 + * \return IVI_FAILED if the method call was failed
4966 + int32_t (*screen_add_layer)(struct ivi_layout_screen *iviscrn,
4967 + struct ivi_layout_layer *addlayer);
4970 + * \brief Sets render order of ivi_layers on a ivi_screen
4972 + * \return IVI_SUCCEEDED if the method call was successful
4973 + * \return IVI_FAILED if the method call was failed
4975 + int32_t (*screen_set_render_order)(struct ivi_layout_screen *iviscrn,
4976 + struct ivi_layout_layer **pLayer,
4977 + const int32_t number);
4980 + * \brief get weston_output from ivi_layout_screen.
4982 + * \return (struct weston_output *)
4983 + * if the method call was successful
4984 + * \return NULL if the method call was failed
4986 + struct weston_output *(*screen_get_output)(struct ivi_layout_screen *);
4990 + * transision animation for layer
4992 + void (*transition_move_layer_cancel)(struct ivi_layout_layer *layer);
4993 + int32_t (*layer_set_fade_info)(struct ivi_layout_layer* ivilayer,
4994 + uint32_t is_fade_in,
4995 + double start_alpha, double end_alpha);
4998 + * surface content dumping for debugging
5000 + int32_t (*surface_get_size)(struct ivi_layout_surface *ivisurf,
5001 + int32_t *width, int32_t *height,
5004 + int32_t (*surface_dump)(struct weston_surface *surface,
5005 + void *target, size_t size,
5006 + int32_t x, int32_t y,
5007 + int32_t width, int32_t height);
5010 + * remove notification by callback on property changes of ivi_surface
5012 + void (*surface_remove_notification_by_callback)(struct ivi_layout_surface *ivisurf,
5013 + surface_property_notification_func callback,
5017 + * \brief remove notification by callback on property changes of ivi_layer
5019 + void (*layer_remove_notification_by_callback)(struct ivi_layout_layer *ivilayer,
5020 + layer_property_notification_func callback,
5024 + * \brief get id of ivi_screen from ivi_layout_screen
5027 + * \return id of ivi_screen
5029 + uint32_t (*get_id_of_screen)(struct ivi_layout_screen *iviscrn);
5034 +#endif /* __cplusplus */
5036 +#endif /* _IVI_LAYOUT_EXPORT_H_ */
5037 diff --git a/ivi-shell/ivi-layout-private.h b/ivi-shell/ivi-layout-private.h
5038 new file mode 100644
5039 index 0000000..074d598
5041 +++ b/ivi-shell/ivi-layout-private.h
5044 + * Copyright (C) 2014 DENSO CORPORATION
5046 + * Permission is hereby granted, free of charge, to any person obtaining
5047 + * a copy of this software and associated documentation files (the
5048 + * "Software"), to deal in the Software without restriction, including
5049 + * without limitation the rights to use, copy, modify, merge, publish,
5050 + * distribute, sublicense, and/or sell copies of the Software, and to
5051 + * permit persons to whom the Software is furnished to do so, subject to
5052 + * the following conditions:
5054 + * The above copyright notice and this permission notice (including the
5055 + * next paragraph) shall be included in all copies or substantial
5056 + * portions of the Software.
5058 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
5059 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
5060 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
5061 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
5062 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
5063 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
5064 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5068 +#ifndef _ivi_layout_PRIVATE_H_
5069 +#define _ivi_layout_PRIVATE_H_
5071 +#include "compositor.h"
5072 +#include "ivi-layout-export.h"
5074 +struct ivi_layout_surface {
5075 + struct wl_list link;
5076 + struct wl_signal property_changed;
5077 + struct wl_list layer_list;
5078 + int32_t update_count;
5079 + uint32_t id_surface;
5081 + struct ivi_layout *layout;
5082 + struct weston_surface *surface;
5084 + struct weston_transform transform;
5086 + struct ivi_layout_surface_properties prop;
5087 + uint32_t event_mask;
5090 + struct ivi_layout_surface_properties prop;
5091 + struct wl_list link;
5095 + struct wl_list link;
5096 + struct wl_list layer_list;
5100 + ivi_controller_surface_content_callback callback;
5102 + } content_observer;
5104 + struct wl_signal configured;
5107 +struct ivi_layout_layer {
5108 + struct wl_list link;
5109 + struct wl_signal property_changed;
5110 + struct wl_list screen_list;
5111 + struct wl_list link_to_surface;
5112 + uint32_t id_layer;
5114 + struct ivi_layout *layout;
5116 + struct ivi_layout_layer_properties prop;
5117 + uint32_t event_mask;
5120 + struct ivi_layout_layer_properties prop;
5121 + struct wl_list surface_list;
5122 + struct wl_list link;
5127 + struct wl_list surface_list;
5128 + struct wl_list link;
5131 + int32_t ref_count;
5134 +struct ivi_layout {
5135 + struct weston_compositor *compositor;
5137 + struct wl_list surface_list;
5138 + struct wl_list layer_list;
5139 + struct wl_list screen_list;
5142 + struct wl_signal created;
5143 + struct wl_signal removed;
5144 + } layer_notification;
5147 + struct wl_signal created;
5148 + struct wl_signal removed;
5149 + struct wl_signal configure_changed;
5150 + } surface_notification;
5152 + struct weston_layer layout_layer;
5153 + struct wl_signal warning_signal;
5155 + struct ivi_layout_transition_set *transitions;
5156 + struct wl_list pending_transition_list;
5159 +struct ivi_layout *get_instance(void);
5161 +struct ivi_layout_transition;
5163 +struct ivi_layout_transition_set {
5164 + struct wl_event_source *event_source;
5165 + struct wl_list transition_list;
5168 +typedef void (*ivi_layout_transition_destroy_user_func)(void *user_data);
5170 +struct ivi_layout_transition_set *
5171 +ivi_layout_transition_set_create(struct weston_compositor *ec);
5174 +ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface,
5175 + int32_t dest_x, int32_t dest_y,
5176 + int32_t dest_width, int32_t dest_height,
5177 + uint32_t duration);
5180 +ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
5181 + uint32_t duration);
5184 +ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
5185 + uint32_t duration);
5189 +ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
5190 + int32_t dest_x, int32_t dest_y,
5191 + uint32_t duration);
5194 +ivi_layout_transition_fade_layer(struct ivi_layout_layer *layer,
5195 + uint32_t is_fade_in,
5196 + double start_alpha, double end_alpha,
5198 + ivi_layout_transition_destroy_user_func destroy_func,
5199 + uint32_t duration);
5202 +is_surface_transition(struct ivi_layout_surface *surface);
5205 + * methods of interaction between ivi-shell with ivi-layout
5207 +struct weston_view *
5208 +ivi_layout_get_weston_view(struct ivi_layout_surface *surface);
5210 +ivi_layout_surface_configure(struct ivi_layout_surface *ivisurf,
5211 + int32_t width, int32_t height);
5212 +struct ivi_layout_surface*
5213 +ivi_layout_surface_create(struct weston_surface *wl_surface,
5214 + uint32_t id_surface);
5216 +ivi_layout_init_with_compositor(struct weston_compositor *ec);
5218 +ivi_layout_surface_get_dimension(struct ivi_layout_surface *ivisurf,
5219 + int32_t *dest_width, int32_t *dest_height);
5221 +ivi_layout_surface_add_configured_listener(struct ivi_layout_surface* ivisurf,
5222 + struct wl_listener* listener);
5224 + * methods of interaction between transition animation with ivi-layout
5227 +ivi_layout_commit_changes(void);
5229 +ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf);
5231 +ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
5232 + int32_t x, int32_t y,
5233 + int32_t width, int32_t height);
5235 +ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
5236 + wl_fixed_t opacity);
5238 +ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf);
5240 +ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf,
5241 + bool newVisibility);
5243 +ivi_layout_surface_get_visibility(struct ivi_layout_surface *ivisurf);
5244 +struct ivi_layout_surface *
5245 +ivi_layout_get_surface_from_id(uint32_t id_surface);
5247 +ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
5248 + wl_fixed_t opacity);
5250 +ivi_layout_layer_get_opacity(struct ivi_layout_layer *ivilayer);
5252 +ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer,
5253 + bool newVisibility);
5255 +ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer,
5256 + int32_t dest_x, int32_t dest_y);
5258 +ivi_layout_layer_get_position(struct ivi_layout_layer *ivilayer,
5259 + int32_t *dest_x, int32_t *dest_y);
5261 +ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
5262 + struct ivi_layout_surface **pSurface,
5265 +ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer);
5267 +load_controller_modules(struct weston_compositor *compositor, const char *modules,
5268 + int *argc, char *argv[]);
5270 +ivi_layout_surface_destroy(struct ivi_layout_surface *ivisurf);
5272 diff --git a/ivi-shell/ivi-layout-transition.c b/ivi-shell/ivi-layout-transition.c
5273 new file mode 100644
5274 index 0000000..d12a8f4
5276 +++ b/ivi-shell/ivi-layout-transition.c
5279 + * Copyright (C) 2014 DENSO CORPORATION
5281 + * Permission is hereby granted, free of charge, to any person obtaining
5282 + * a copy of this software and associated documentation files (the
5283 + * "Software"), to deal in the Software without restriction, including
5284 + * without limitation the rights to use, copy, modify, merge, publish,
5285 + * distribute, sublicense, and/or sell copies of the Software, and to
5286 + * permit persons to whom the Software is furnished to do so, subject to
5287 + * the following conditions:
5289 + * The above copyright notice and this permission notice (including the
5290 + * next paragraph) shall be included in all copies or substantial
5291 + * portions of the Software.
5293 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
5294 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
5295 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
5296 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
5297 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
5298 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
5299 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5304 +#include <assert.h>
5305 +#include <stdlib.h>
5308 +#include "ivi-layout-export.h"
5309 +#include "ivi-layout-private.h"
5311 +struct ivi_layout_transition;
5313 +typedef void (*ivi_layout_transition_frame_func)(
5314 + struct ivi_layout_transition *transition);
5315 +typedef void (*ivi_layout_transition_destroy_func)(
5316 + struct ivi_layout_transition *transition);
5317 +typedef int32_t (*ivi_layout_is_transition_func)(void *private_data, void *id);
5319 +struct ivi_layout_transition {
5320 + enum ivi_layout_transition_type type;
5321 + void *private_data;
5324 + uint32_t time_start;
5325 + uint32_t time_duration;
5326 + uint32_t time_elapsed;
5328 + ivi_layout_is_transition_func is_transition_func;
5329 + ivi_layout_transition_frame_func frame_func;
5330 + ivi_layout_transition_destroy_func destroy_func;
5333 +struct transition_node {
5334 + struct ivi_layout_transition *transition;
5335 + struct wl_list link;
5338 +static void layout_transition_destroy(struct ivi_layout_transition *transition);
5340 +static struct ivi_layout_transition *
5341 +get_transition_from_type_and_id(enum ivi_layout_transition_type type,
5344 + struct ivi_layout *layout = get_instance();
5345 + struct transition_node *node;
5346 + struct ivi_layout_transition *tran;
5348 + wl_list_for_each(node, &layout->transitions->transition_list, link) {
5349 + tran = node->transition;
5351 + if (tran->type == type &&
5352 + tran->is_transition_func(tran->private_data, id_data))
5360 +is_surface_transition(struct ivi_layout_surface *surface)
5362 + struct ivi_layout *layout = get_instance();
5363 + struct transition_node *node;
5364 + struct ivi_layout_transition *tran;
5366 + wl_list_for_each(node, &layout->transitions->transition_list, link) {
5367 + tran = node->transition;
5369 + if ((tran->type == IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE ||
5370 + tran->type == IVI_LAYOUT_TRANSITION_VIEW_RESIZE) &&
5371 + tran->is_transition_func(tran->private_data, surface))
5379 +tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp)
5381 + const double t = timestamp - transition->time_start;
5383 + if (transition->time_duration <= t) {
5384 + transition->time_elapsed = transition->time_duration;
5385 + transition->is_done = 1;
5387 + transition->time_elapsed = t;
5391 +static float time_to_nowpos(struct ivi_layout_transition *transition)
5393 + return sin((float)transition->time_elapsed /
5394 + (float)transition->time_duration * M_PI_2);
5398 +do_transition_frame(struct ivi_layout_transition *transition,
5399 + uint32_t timestamp)
5401 + if (0 == transition->time_start)
5402 + transition->time_start = timestamp;
5404 + tick_transition(transition, timestamp);
5405 + transition->frame_func(transition);
5407 + if (transition->is_done)
5408 + layout_transition_destroy(transition);
5412 +layout_transition_frame(void *data)
5414 + struct ivi_layout_transition_set *transitions = data;
5415 + uint32_t fps = 30;
5416 + struct timespec timestamp = {};
5417 + uint32_t msec = 0;
5418 + struct transition_node *node = NULL;
5419 + struct transition_node *next = NULL;
5421 + if (wl_list_empty(&transitions->transition_list)) {
5422 + wl_event_source_timer_update(transitions->event_source, 0);
5426 + wl_event_source_timer_update(transitions->event_source, 1000 / fps);
5428 + clock_gettime(CLOCK_MONOTONIC, ×tamp);/* FIXME */
5429 + msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec);
5431 + wl_list_for_each_safe(node, next, &transitions->transition_list, link) {
5432 + do_transition_frame(node->transition, msec);
5435 + ivi_layout_commit_changes();
5439 +struct ivi_layout_transition_set *
5440 +ivi_layout_transition_set_create(struct weston_compositor *ec)
5442 + struct ivi_layout_transition_set *transitions;
5443 + struct wl_event_loop *loop;
5445 + transitions = malloc(sizeof(*transitions));
5446 + if (transitions == NULL) {
5447 + weston_log("%s: memory allocation fails\n", __func__);
5451 + wl_list_init(&transitions->transition_list);
5453 + loop = wl_display_get_event_loop(ec->wl_display);
5454 + transitions->event_source =
5455 + wl_event_loop_add_timer(loop, layout_transition_frame,
5458 + return transitions;
5462 +layout_transition_register(struct ivi_layout_transition *trans)
5464 + struct ivi_layout *layout = get_instance();
5465 + struct transition_node *node;
5467 + node = malloc(sizeof(*node));
5468 + if (node == NULL) {
5469 + weston_log("%s: memory allocation fails\n", __func__);
5473 + node->transition = trans;
5474 + wl_list_insert(&layout->pending_transition_list, &node->link);
5478 +remove_transition(struct ivi_layout *layout,
5479 + struct ivi_layout_transition *trans)
5481 + struct transition_node *node;
5482 + struct transition_node *next;
5484 + wl_list_for_each_safe(node, next,
5485 + &layout->transitions->transition_list, link) {
5486 + if (node->transition == trans) {
5487 + wl_list_remove(&node->link);
5493 + wl_list_for_each_safe(node, next,
5494 + &layout->pending_transition_list, link) {
5495 + if (node->transition == trans) {
5496 + wl_list_remove(&node->link);
5504 +layout_transition_destroy(struct ivi_layout_transition *transition)
5506 + struct ivi_layout *layout = get_instance();
5508 + remove_transition(layout, transition);
5509 + if (transition->destroy_func)
5510 + transition->destroy_func(transition);
5514 +static struct ivi_layout_transition *
5515 +create_layout_transition(void)
5517 + struct ivi_layout_transition *transition = malloc(sizeof(*transition));
5519 + if (transition == NULL) {
5520 + weston_log("%s: memory allocation fails\n", __func__);
5524 + transition->type = IVI_LAYOUT_TRANSITION_MAX;
5525 + transition->time_start = 0;
5526 + transition->time_duration = 300; /* 300ms */
5527 + transition->time_elapsed = 0;
5529 + transition->is_done = 0;
5531 + transition->private_data = NULL;
5532 + transition->user_data = NULL;
5534 + transition->frame_func = NULL;
5535 + transition->destroy_func = NULL;
5537 + return transition;
5540 +/* move and resize view transition */
5542 +struct move_resize_view_data {
5543 + struct ivi_layout_surface *surface;
5548 + int32_t start_width;
5549 + int32_t start_height;
5550 + int32_t end_width;
5551 + int32_t end_height;
5555 +transition_move_resize_view_destroy(struct ivi_layout_transition *transition)
5557 + struct move_resize_view_data *data =
5558 + (struct move_resize_view_data *)transition->private_data;
5559 + struct ivi_layout_surface *layout_surface = data->surface;
5561 + wl_signal_emit(&layout_surface->configured, layout_surface);
5563 + if (transition->private_data) {
5564 + free(transition->private_data);
5565 + transition->private_data = NULL;
5570 +transition_move_resize_view_user_frame(struct ivi_layout_transition *transition)
5572 + struct move_resize_view_data *mrv = transition->private_data;
5573 + const double current = time_to_nowpos(transition);
5575 + const int32_t destx = mrv->start_x +
5576 + (mrv->end_x - mrv->start_x) * current;
5578 + const int32_t desty = mrv->start_y +
5579 + (mrv->end_y - mrv->start_y) * current;
5581 + const int32_t dest_width = mrv->start_width +
5582 + (mrv->end_width - mrv->start_width) * current;
5584 + const int32_t dest_height = mrv->start_height +
5585 + (mrv->end_height - mrv->start_height) * current;
5587 + ivi_layout_surface_set_destination_rectangle(mrv->surface,
5589 + dest_width, dest_height);
5593 +is_transition_move_resize_view_func(struct move_resize_view_data *data,
5594 + struct ivi_layout_surface *view)
5596 + return data->surface == view;
5599 +static struct ivi_layout_transition *
5600 +create_move_resize_view_transition(
5601 + struct ivi_layout_surface *surface,
5602 + int32_t start_x, int32_t start_y,
5603 + int32_t end_x, int32_t end_y,
5604 + int32_t start_width, int32_t start_height,
5605 + int32_t end_width, int32_t end_height,
5606 + ivi_layout_transition_frame_func frame_func,
5607 + ivi_layout_transition_destroy_func destroy_func,
5608 + uint32_t duration)
5610 + struct ivi_layout_transition *transition;
5611 + struct move_resize_view_data *data;
5613 + transition = create_layout_transition();
5614 + if (transition == NULL)
5617 + data = malloc(sizeof(*data));
5618 + if (data == NULL) {
5619 + weston_log("%s: memory allocation fails\n", __func__);
5623 + transition->type = IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE;
5624 + transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_resize_view_func;
5626 + transition->frame_func = frame_func;
5627 + transition->destroy_func = destroy_func;
5628 + transition->private_data = data;
5630 + if (duration != 0)
5631 + transition->time_duration = duration;
5633 + data->surface = surface;
5634 + data->start_x = start_x;
5635 + data->start_y = start_y;
5636 + data->end_x = end_x;
5637 + data->end_y = end_y;
5639 + data->start_width = start_width;
5640 + data->start_height = start_height;
5641 + data->end_width = end_width;
5642 + data->end_height = end_height;
5644 + return transition;
5648 +ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface,
5649 + int32_t dest_x, int32_t dest_y,
5650 + int32_t dest_width, int32_t dest_height,
5651 + uint32_t duration)
5653 + struct ivi_layout_transition *transition;
5654 + int32_t start_pos[2] = {
5655 + surface->pending.prop.start_x,
5656 + surface->pending.prop.start_y
5659 + int32_t start_size[2] = {
5660 + surface->pending.prop.start_width,
5661 + surface->pending.prop.start_height
5664 + transition = get_transition_from_type_and_id(
5665 + IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
5668 + struct move_resize_view_data *data = transition->private_data;
5669 + transition->time_start = 0;
5670 + transition->time_duration = duration;
5672 + data->start_x = start_pos[0];
5673 + data->start_y = start_pos[1];
5674 + data->end_x = dest_x;
5675 + data->end_y = dest_y;
5677 + data->start_width = start_size[0];
5678 + data->start_height = start_size[1];
5679 + data->end_width = dest_width;
5680 + data->end_height = dest_height;
5684 + transition = create_move_resize_view_transition(
5686 + start_pos[0], start_pos[1],
5688 + start_size[0], start_size[1],
5689 + dest_width, dest_height,
5690 + transition_move_resize_view_user_frame,
5691 + transition_move_resize_view_destroy,
5694 + layout_transition_register(transition);
5697 +/* fade transition */
5698 +struct fade_view_data {
5699 + struct ivi_layout_surface *surface;
5700 + double start_alpha;
5704 +struct store_alpha{
5709 +fade_view_user_frame(struct ivi_layout_transition *transition)
5711 + struct fade_view_data *fade = transition->private_data;
5712 + struct ivi_layout_surface *surface = fade->surface;
5714 + const double current = time_to_nowpos(transition);
5715 + const double alpha = fade->start_alpha +
5716 + (fade->end_alpha - fade->start_alpha) * current;
5718 + ivi_layout_surface_set_opacity(surface, wl_fixed_from_double(alpha));
5719 + ivi_layout_surface_set_visibility(surface, true);
5723 +is_transition_fade_view_func(struct fade_view_data *data,
5724 + struct ivi_layout_surface *view)
5726 + return data->surface == view;
5729 +static struct ivi_layout_transition *
5730 +create_fade_view_transition(
5731 + struct ivi_layout_surface *surface,
5732 + double start_alpha, double end_alpha,
5733 + ivi_layout_transition_frame_func frame_func,
5735 + ivi_layout_transition_destroy_func destroy_func,
5736 + uint32_t duration)
5738 + struct ivi_layout_transition *transition;
5739 + struct fade_view_data *data;
5741 + transition = create_layout_transition();
5742 + if (transition == NULL)
5745 + data = malloc(sizeof(*data));
5746 + if (data == NULL) {
5747 + weston_log("%s: memory allocation fails\n", __func__);
5751 + transition->type = IVI_LAYOUT_TRANSITION_VIEW_FADE;
5752 + transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_view_func;
5754 + transition->user_data = user_data;
5755 + transition->private_data = data;
5756 + transition->frame_func = frame_func;
5757 + transition->destroy_func = destroy_func;
5759 + if (duration != 0)
5760 + transition->time_duration = duration;
5762 + data->surface = surface;
5763 + data->start_alpha = start_alpha;
5764 + data->end_alpha = end_alpha;
5766 + return transition;
5770 +create_visibility_transition(struct ivi_layout_surface *surface,
5771 + double start_alpha,
5772 + double dest_alpha,
5774 + ivi_layout_transition_destroy_func destroy_func,
5775 + uint32_t duration)
5777 + struct ivi_layout_transition *transition = NULL;
5779 + transition = create_fade_view_transition(
5781 + start_alpha, dest_alpha,
5782 + fade_view_user_frame,
5787 + layout_transition_register(transition);
5791 +visibility_on_transition_destroy(struct ivi_layout_transition *transition)
5793 + struct fade_view_data *data = transition->private_data;
5794 + struct store_alpha *user_data = transition->user_data;
5796 + ivi_layout_surface_set_visibility(data->surface, true);
5799 + transition->private_data = NULL;
5802 + transition->user_data = NULL;
5806 +ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
5807 + uint32_t duration)
5809 + struct ivi_layout_transition *transition;
5810 + bool is_visible = ivi_layout_surface_get_visibility(surface);
5811 + wl_fixed_t dest_alpha = ivi_layout_surface_get_opacity(surface);
5812 + struct store_alpha *user_data = NULL;
5813 + wl_fixed_t start_alpha = 0.0;
5814 + struct fade_view_data *data = NULL;
5816 + transition = get_transition_from_type_and_id(
5817 + IVI_LAYOUT_TRANSITION_VIEW_FADE,
5820 + start_alpha = ivi_layout_surface_get_opacity(surface);
5821 + user_data = transition->user_data;
5822 + data = transition->private_data;
5824 + transition->time_start = 0;
5825 + transition->time_duration = duration;
5826 + transition->destroy_func = visibility_on_transition_destroy;
5828 + data->start_alpha = wl_fixed_to_double(start_alpha);
5829 + data->end_alpha = user_data->alpha;
5836 + user_data = malloc(sizeof(*user_data));
5837 + if (user_data == NULL) {
5838 + weston_log("%s: memory allocation fails\n", __func__);
5842 + user_data->alpha = wl_fixed_to_double(dest_alpha);
5844 + create_visibility_transition(surface,
5845 + 0.0, // start_alpha
5846 + wl_fixed_to_double(dest_alpha),
5848 + visibility_on_transition_destroy,
5853 +visibility_off_transition_destroy(struct ivi_layout_transition *transition)
5855 + struct fade_view_data *data = transition->private_data;
5856 + struct store_alpha *user_data = transition->user_data;
5858 + ivi_layout_surface_set_visibility(data->surface, false);
5860 + ivi_layout_surface_set_opacity(data->surface,
5861 + wl_fixed_from_double(user_data->alpha));
5864 + transition->private_data = NULL;
5867 + transition->user_data= NULL;
5871 +ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
5872 + uint32_t duration)
5874 + struct ivi_layout_transition *transition;
5875 + wl_fixed_t start_alpha = ivi_layout_surface_get_opacity(surface);
5876 + struct store_alpha* user_data = NULL;
5877 + struct fade_view_data* data = NULL;
5880 + get_transition_from_type_and_id(IVI_LAYOUT_TRANSITION_VIEW_FADE,
5883 + data = transition->private_data;
5885 + transition->time_start = 0;
5886 + transition->time_duration = duration;
5887 + transition->destroy_func = visibility_off_transition_destroy;
5889 + data->start_alpha = wl_fixed_to_double(start_alpha);
5890 + data->end_alpha = 0;
5894 + user_data = malloc(sizeof(*user_data));
5895 + if (user_data == NULL) {
5896 + weston_log("%s: memory allocation fails\n", __func__);
5900 + user_data->alpha = wl_fixed_to_double(start_alpha);
5902 + create_visibility_transition(surface,
5903 + wl_fixed_to_double(start_alpha),
5904 + 0.0, // dest_alpha
5906 + visibility_off_transition_destroy,
5910 +/* move layer transition */
5912 +struct move_layer_data {
5913 + struct ivi_layout_layer *layer;
5918 + ivi_layout_transition_destroy_user_func destroy_func;
5922 +transition_move_layer_user_frame(struct ivi_layout_transition *transition)
5924 + struct move_layer_data *data = transition->private_data;
5925 + struct ivi_layout_layer *layer = data->layer;
5927 + const float current = time_to_nowpos(transition);
5929 + const int32_t dest_x = data->start_x +
5930 + (data->end_x - data->start_x) * current;
5932 + const int32_t dest_y = data->start_y +
5933 + (data->end_y - data->start_y) * current;
5935 + ivi_layout_layer_set_position(layer, dest_x, dest_y);
5939 +transition_move_layer_destroy(struct ivi_layout_transition *transition)
5941 + struct move_layer_data *data = transition->private_data;
5943 + if (data->destroy_func)
5944 + data->destroy_func(transition->user_data);
5947 + transition->private_data = NULL;
5951 +is_transition_move_layer_func(struct move_layer_data *data,
5952 + struct ivi_layout_layer *layer)
5954 + return data->layer == layer;
5958 +static struct ivi_layout_transition *
5959 +create_move_layer_transition(
5960 + struct ivi_layout_layer *layer,
5961 + int32_t start_x, int32_t start_y,
5962 + int32_t end_x, int32_t end_y,
5964 + ivi_layout_transition_destroy_user_func destroy_user_func,
5965 + uint32_t duration)
5967 + struct ivi_layout_transition *transition;
5968 + struct move_layer_data *data;
5970 + transition = create_layout_transition();
5971 + if (transition == NULL)
5974 + data = malloc(sizeof(*data));
5975 + if (data == NULL) {
5976 + weston_log("%s: memory allocation fails\n", __func__);
5980 + transition->type = IVI_LAYOUT_TRANSITION_LAYER_MOVE;
5981 + transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_layer_func;
5983 + transition->frame_func = transition_move_layer_user_frame;
5984 + transition->destroy_func = transition_move_layer_destroy;
5985 + transition->private_data = data;
5986 + transition->user_data = user_data;
5988 + if (duration != 0)
5989 + transition->time_duration = duration;
5991 + data->layer = layer;
5992 + data->start_x = start_x;
5993 + data->start_y = start_y;
5994 + data->end_x = end_x;
5995 + data->end_y = end_y;
5996 + data->destroy_func = destroy_user_func;
5998 + return transition;
6002 +ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
6003 + int32_t dest_x, int32_t dest_y,
6004 + uint32_t duration)
6006 + int32_t start_pos_x = 0;
6007 + int32_t start_pos_y = 0;
6008 + struct ivi_layout_transition *transition = NULL;
6010 + ivi_layout_layer_get_position(layer, &start_pos_x, &start_pos_y);
6012 + transition = create_move_layer_transition(
6014 + start_pos_x, start_pos_y,
6019 + layout_transition_register(transition);
6025 +ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer)
6027 + struct ivi_layout_transition *transition =
6028 + get_transition_from_type_and_id(
6029 + IVI_LAYOUT_TRANSITION_LAYER_MOVE,
6032 + layout_transition_destroy(transition);
6036 +/* fade layer transition */
6037 +struct fade_layer_data {
6038 + struct ivi_layout_layer *layer;
6039 + uint32_t is_fade_in;
6040 + double start_alpha;
6042 + ivi_layout_transition_destroy_user_func destroy_func;
6046 +transition_fade_layer_destroy(struct ivi_layout_transition *transition)
6048 + struct fade_layer_data *data = transition->private_data;
6049 + transition->private_data = NULL;
6055 +transition_fade_layer_user_frame(struct ivi_layout_transition *transition)
6057 + double current = time_to_nowpos(transition);
6058 + struct fade_layer_data *data = transition->private_data;
6059 + double alpha = data->start_alpha +
6060 + (data->end_alpha - data->start_alpha) * current;
6061 + wl_fixed_t fixed_alpha = wl_fixed_from_double(alpha);
6063 + int32_t is_done = transition->is_done;
6064 + bool is_visible = !is_done || data->is_fade_in;
6066 + ivi_layout_layer_set_opacity(data->layer, fixed_alpha);
6067 + ivi_layout_layer_set_visibility(data->layer, is_visible);
6071 +is_transition_fade_layer_func(struct fade_layer_data *data,
6072 + struct ivi_layout_layer *layer)
6074 + return data->layer == layer;
6078 +ivi_layout_transition_fade_layer(
6079 + struct ivi_layout_layer *layer,
6080 + uint32_t is_fade_in,
6081 + double start_alpha, double end_alpha,
6083 + ivi_layout_transition_destroy_user_func destroy_func,
6084 + uint32_t duration)
6086 + struct ivi_layout_transition *transition;
6087 + struct fade_layer_data *data = NULL;
6088 + wl_fixed_t fixed_opacity = 0.0;
6089 + double now_opacity = 0.0;
6090 + double remain = 0.0;
6092 + transition = get_transition_from_type_and_id(
6093 + IVI_LAYOUT_TRANSITION_LAYER_FADE,
6096 + /* transition update */
6097 + data = transition->private_data;
6100 + fixed_opacity = ivi_layout_layer_get_opacity(layer);
6101 + now_opacity = wl_fixed_to_double(fixed_opacity);
6104 + data->is_fade_in = is_fade_in;
6105 + data->start_alpha = now_opacity;
6106 + data->end_alpha = end_alpha;
6108 + remain = is_fade_in? 1.0 - now_opacity : now_opacity;
6109 + transition->time_start = 0;
6110 + transition->time_elapsed = 0;
6111 + transition->time_duration = duration * remain;
6116 + transition = create_layout_transition();
6117 + if (transition == NULL)
6120 + data = malloc(sizeof(*data));
6121 + if (data == NULL) {
6122 + weston_log("%s: memory allocation fails\n", __func__);
6126 + transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
6127 + transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
6129 + transition->private_data = data;
6130 + transition->user_data = user_data;
6132 + transition->frame_func = transition_fade_layer_user_frame;
6133 + transition->destroy_func = transition_fade_layer_destroy;
6135 + if (duration != 0)
6136 + transition->time_duration = duration;
6138 + data->layer = layer;
6139 + data->is_fade_in = is_fade_in;
6140 + data->start_alpha = start_alpha;
6141 + data->end_alpha = end_alpha;
6142 + data->destroy_func = destroy_func;
6144 + layout_transition_register(transition);
6149 diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c
6150 new file mode 100644
6151 index 0000000..51d0a8d
6153 +++ b/ivi-shell/ivi-layout.c
6156 + * Copyright (C) 2013 DENSO CORPORATION
6158 + * Permission is hereby granted, free of charge, to any person obtaining
6159 + * a copy of this software and associated documentation files (the
6160 + * "Software"), to deal in the Software without restriction, including
6161 + * without limitation the rights to use, copy, modify, merge, publish,
6162 + * distribute, sublicense, and/or sell copies of the Software, and to
6163 + * permit persons to whom the Software is furnished to do so, subject to
6164 + * the following conditions:
6166 + * The above copyright notice and this permission notice (including the
6167 + * next paragraph) shall be included in all copies or substantial
6168 + * portions of the Software.
6170 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
6171 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
6172 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
6173 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
6174 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
6175 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
6176 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
6181 + * Implementation of ivi-layout library. The actual view on ivi_screen is
6182 + * not updated till calling ivi_layout_commit_changes. A overview from
6183 + * calling API for updating properties of ivi_surface/ivi_layer to asking
6184 + * compositor to compose them by using weston_compositor_schedule_repaint,
6185 + * 0/ initialize this library by ivi_layout_init_with_compositor
6186 + * with (struct weston_compositor *ec) from ivi-shell.
6187 + * 1/ When a API for updating properties of ivi_surface/ivi_layer, it updates
6188 + * pending prop of ivi_surface/ivi_layer/ivi_screen which are structure to
6189 + * store properties.
6190 + * 2/ Before calling commitChanges, in case of calling a API to get a property,
6191 + * return current property, not pending property.
6192 + * 3/ At the timing of calling ivi_layout_commitChanges, pending properties
6193 + * are applied to properties.
6195 + * *) ivi_layout_commitChanges is also called by transition animation
6196 + * per each frame. See ivi-layout-transition.c in details. Transition
6197 + * animation interpolates frames between previous properties of ivi_surface
6199 + * For example, when a property of ivi_surface is changed from invisibility
6200 + * to visibility, it behaves like fade-in. When ivi_layout_commitChange is
6201 + * called during transition animation, it cancels the transition and
6202 + * re-start transition to new properties from current properties of final
6203 + * frame just before the the cancellation.
6205 + * 4/ According properties, set transformation by using weston_matrix and
6206 + * weston_view per ivi_surfaces and ivi_layers in while loop.
6207 + * 5/ Set damage and trigger transform by using weston_view_geometry_dirty.
6208 + * 6/ Notify update of properties.
6209 + * 7/ Trigger composition by weston_compositor_schedule_repaint.
6212 +#include "config.h"
6214 +#include <string.h>
6215 +#include <assert.h>
6217 +#include "compositor.h"
6218 +#include "ivi-layout-export.h"
6219 +#include "ivi-layout-private.h"
6221 +#include "shared/helpers.h"
6222 +#include "shared/os-compatibility.h"
6224 +#define max(a, b) ((a) > (b) ? (a) : (b))
6226 +struct link_layer {
6227 + struct ivi_layout_layer *ivilayer;
6228 + struct wl_list link;
6229 + struct wl_list link_to_layer;
6232 +struct link_screen {
6233 + struct ivi_layout_screen *iviscrn;
6234 + struct wl_list link;
6235 + struct wl_list link_to_screen;
6238 +struct listener_layout_notification {
6240 + struct wl_listener listener;
6245 +struct ivi_layout_screen {
6246 + struct wl_list link;
6247 + struct wl_list link_to_layer;
6248 + uint32_t id_screen;
6250 + struct ivi_layout *layout;
6251 + struct weston_output *output;
6254 + struct wl_list layer_list;
6255 + struct wl_list link;
6260 + struct wl_list layer_list;
6261 + struct wl_list link;
6265 +struct ivi_layout_notification_callback {
6270 +struct ivi_rectangle
6279 +remove_notification(struct wl_list *listener_list, void *callback, void *userdata);
6281 +static struct ivi_layout ivilayout = {0};
6283 +struct ivi_layout *
6286 + return &ivilayout;
6290 + * Internal API to add/remove a link to ivi_surface from ivi_layer.
6293 +add_link_to_surface(struct ivi_layout_layer *ivilayer,
6294 + struct link_layer *link_layer)
6296 + struct link_layer *link = NULL;
6298 + wl_list_for_each(link, &ivilayer->link_to_surface, link_to_layer) {
6299 + if (link == link_layer)
6303 + wl_list_insert(&ivilayer->link_to_surface, &link_layer->link_to_layer);
6307 +remove_link_to_surface(struct ivi_layout_layer *ivilayer)
6309 + struct link_layer *link = NULL;
6310 + struct link_layer *next = NULL;
6312 + wl_list_for_each_safe(link, next, &ivilayer->link_to_surface, link_to_layer) {
6313 + wl_list_remove(&link->link_to_layer);
6314 + wl_list_remove(&link->link);
6318 + wl_list_init(&ivilayer->link_to_surface);
6322 + * Internal API to add a link to ivi_layer from ivi_screen.
6325 +add_link_to_layer(struct ivi_layout_screen *iviscrn,
6326 + struct link_screen *link_screen)
6328 + wl_list_insert(&iviscrn->link_to_layer, &link_screen->link_to_screen);
6332 + * Internal API to add/remove a ivi_surface from ivi_layer.
6335 +add_ordersurface_to_layer(struct ivi_layout_surface *ivisurf,
6336 + struct ivi_layout_layer *ivilayer)
6338 + struct link_layer *link_layer = NULL;
6340 + link_layer = malloc(sizeof *link_layer);
6341 + if (link_layer == NULL) {
6342 + weston_log("fails to allocate memory\n");
6346 + link_layer->ivilayer = ivilayer;
6347 + wl_list_insert(&ivisurf->layer_list, &link_layer->link);
6348 + add_link_to_surface(ivilayer, link_layer);
6352 +remove_ordersurface_from_layer(struct ivi_layout_surface *ivisurf)
6354 + struct link_layer *link_layer = NULL;
6355 + struct link_layer *next = NULL;
6357 + wl_list_for_each_safe(link_layer, next, &ivisurf->layer_list, link) {
6358 + wl_list_remove(&link_layer->link);
6359 + wl_list_remove(&link_layer->link_to_layer);
6362 + wl_list_init(&ivisurf->layer_list);
6366 + * Internal API to add/remove a ivi_layer to/from ivi_screen.
6369 +add_orderlayer_to_screen(struct ivi_layout_layer *ivilayer,
6370 + struct ivi_layout_screen *iviscrn)
6372 + struct link_screen *link_scrn = NULL;
6374 + link_scrn = malloc(sizeof *link_scrn);
6375 + if (link_scrn == NULL) {
6376 + weston_log("fails to allocate memory\n");
6380 + link_scrn->iviscrn = iviscrn;
6381 + wl_list_insert(&ivilayer->screen_list, &link_scrn->link);
6382 + add_link_to_layer(iviscrn, link_scrn);
6386 +remove_orderlayer_from_screen(struct ivi_layout_layer *ivilayer)
6388 + struct link_screen *link_scrn = NULL;
6389 + struct link_screen *next = NULL;
6391 + wl_list_for_each_safe(link_scrn, next, &ivilayer->screen_list, link) {
6392 + wl_list_remove(&link_scrn->link);
6393 + wl_list_remove(&link_scrn->link_to_screen);
6396 + wl_list_init(&ivilayer->screen_list);
6400 + * Internal API to add/remove a ivi_layer to/from ivi_screen.
6402 +static struct ivi_layout_surface *
6403 +get_surface(struct wl_list *surf_list, uint32_t id_surface)
6405 + struct ivi_layout_surface *ivisurf;
6407 + wl_list_for_each(ivisurf, surf_list, link) {
6408 + if (ivisurf->id_surface == id_surface) {
6416 +static struct ivi_layout_layer *
6417 +get_layer(struct wl_list *layer_list, uint32_t id_layer)
6419 + struct ivi_layout_layer *ivilayer;
6421 + wl_list_for_each(ivilayer, layer_list, link) {
6422 + if (ivilayer->id_layer == id_layer) {
6431 +remove_configured_listener(struct ivi_layout_surface *ivisurf)
6433 + struct wl_listener *link = NULL;
6434 + struct wl_listener *next = NULL;
6436 + wl_list_for_each_safe(link, next, &ivisurf->configured.listener_list, link) {
6437 + wl_list_remove(&link->link);
6442 +remove_all_notification(struct wl_list *listener_list)
6444 + struct wl_listener *listener = NULL;
6445 + struct wl_listener *next = NULL;
6447 + wl_list_for_each_safe(listener, next, listener_list, link) {
6448 + struct listener_layout_notification *notification = NULL;
6449 + wl_list_remove(&listener->link);
6452 + container_of(listener,
6453 + struct listener_layout_notification,
6456 + free(notification->userdata);
6457 + free(notification);
6462 +ivi_layout_surface_remove_notification(struct ivi_layout_surface *ivisurf)
6464 + if (ivisurf == NULL) {
6465 + weston_log("ivi_layout_surface_remove_notification: invalid argument\n");
6469 + remove_all_notification(&ivisurf->property_changed.listener_list);
6473 +ivi_layout_surface_remove_notification_by_callback(struct ivi_layout_surface *ivisurf,
6474 + surface_property_notification_func callback,
6477 + if (ivisurf == NULL) {
6478 + weston_log("ivi_layout_surface_remove_notification_by_callback: invalid argument\n");
6482 + remove_notification(&ivisurf->property_changed.listener_list, callback, userdata);
6486 + * Called at destruction of wl_surface/ivi_surface
6489 +ivi_layout_surface_destroy(struct ivi_layout_surface *ivisurf)
6491 + struct ivi_layout *layout = get_instance();
6493 + if (ivisurf == NULL) {
6494 + weston_log("%s: invalid argument\n", __func__);
6498 + wl_list_remove(&ivisurf->transform.link);
6499 + wl_list_remove(&ivisurf->pending.link);
6500 + wl_list_remove(&ivisurf->order.link);
6501 + wl_list_remove(&ivisurf->link);
6502 + remove_ordersurface_from_layer(ivisurf);
6504 + wl_signal_emit(&layout->surface_notification.removed, ivisurf);
6506 + remove_configured_listener(ivisurf);
6508 + ivi_layout_surface_remove_notification(ivisurf);
6514 + * Internal API to check ivi_layer/ivi_surface already added in ivi_layer/ivi_screen.
6515 + * Called by ivi_layout_layer_add_surface/ivi_layout_screenAddLayer
6518 +is_surface_in_layer(struct ivi_layout_surface *ivisurf,
6519 + struct ivi_layout_layer *ivilayer)
6521 + struct ivi_layout_surface *surf = NULL;
6523 + wl_list_for_each(surf, &ivilayer->pending.surface_list, pending.link) {
6524 + if (surf->id_surface == ivisurf->id_surface) {
6533 +is_layer_in_screen(struct ivi_layout_layer *ivilayer,
6534 + struct ivi_layout_screen *iviscrn)
6536 + struct ivi_layout_layer *layer = NULL;
6538 + wl_list_for_each(layer, &iviscrn->pending.layer_list, pending.link) {
6539 + if (layer->id_layer == ivilayer->id_layer) {
6548 + * Internal API to initialize ivi_screens found from output_list of weston_compositor.
6549 + * Called by ivi_layout_init_with_compositor.
6552 +create_screen(struct weston_compositor *ec)
6554 + struct ivi_layout *layout = get_instance();
6555 + struct ivi_layout_screen *iviscrn = NULL;
6556 + struct weston_output *output = NULL;
6557 + int32_t count = 0;
6559 + wl_list_for_each(output, &ec->output_list, link) {
6560 + iviscrn = calloc(1, sizeof *iviscrn);
6561 + if (iviscrn == NULL) {
6562 + weston_log("fails to allocate memory\n");
6566 + iviscrn->layout = layout;
6568 + iviscrn->id_screen = count;
6571 + iviscrn->output = output;
6573 + wl_list_init(&iviscrn->pending.layer_list);
6574 + wl_list_init(&iviscrn->pending.link);
6576 + wl_list_init(&iviscrn->order.layer_list);
6577 + wl_list_init(&iviscrn->order.link);
6579 + wl_list_init(&iviscrn->link_to_layer);
6581 + wl_list_insert(&layout->screen_list, &iviscrn->link);
6586 + * Internal APIs to initialize properties of ivi_surface/ivi_layer when they are created.
6589 +init_layer_properties(struct ivi_layout_layer_properties *prop,
6590 + int32_t width, int32_t height)
6592 + memset(prop, 0, sizeof *prop);
6593 + prop->opacity = wl_fixed_from_double(1.0);
6594 + prop->source_width = width;
6595 + prop->source_height = height;
6596 + prop->dest_width = width;
6597 + prop->dest_height = height;
6601 +init_surface_properties(struct ivi_layout_surface_properties *prop)
6603 + memset(prop, 0, sizeof *prop);
6604 + prop->opacity = wl_fixed_from_double(1.0);
6606 + * FIXME: this shall be finxed by ivi-layout-transition.
6608 + prop->dest_width = 1;
6609 + prop->dest_height = 1;
6613 + * Internal APIs to be called from ivi_layout_commit_changes.
6616 +update_opacity(struct ivi_layout_layer *ivilayer,
6617 + struct ivi_layout_surface *ivisurf)
6619 + double layer_alpha = wl_fixed_to_double(ivilayer->prop.opacity);
6620 + double surf_alpha = wl_fixed_to_double(ivisurf->prop.opacity);
6622 + if ((ivilayer->event_mask & IVI_NOTIFICATION_OPACITY) ||
6623 + (ivisurf->event_mask & IVI_NOTIFICATION_OPACITY)) {
6624 + struct weston_view *tmpview = NULL;
6625 + wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
6626 + if (tmpview == NULL) {
6629 + tmpview->alpha = layer_alpha * surf_alpha;
6635 +get_rotate_values(enum wl_output_transform orientation,
6639 + switch (orientation) {
6640 + case WL_OUTPUT_TRANSFORM_90:
6644 + case WL_OUTPUT_TRANSFORM_180:
6648 + case WL_OUTPUT_TRANSFORM_270:
6652 + case WL_OUTPUT_TRANSFORM_NORMAL:
6661 +get_scale(enum wl_output_transform orientation,
6663 + float dest_height,
6664 + float source_width,
6665 + float source_height,
6669 + switch (orientation) {
6670 + case WL_OUTPUT_TRANSFORM_90:
6671 + *scale_x = dest_width / source_height;
6672 + *scale_y = dest_height / source_width;
6674 + case WL_OUTPUT_TRANSFORM_180:
6675 + *scale_x = dest_width / source_width;
6676 + *scale_y = dest_height / source_height;
6678 + case WL_OUTPUT_TRANSFORM_270:
6679 + *scale_x = dest_width / source_height;
6680 + *scale_y = dest_height / source_width;
6682 + case WL_OUTPUT_TRANSFORM_NORMAL:
6684 + *scale_x = dest_width / source_width;
6685 + *scale_y = dest_height / source_height;
6691 +calc_transformation_matrix(struct ivi_rectangle *source_rect,
6692 + struct ivi_rectangle *dest_rect,
6693 + enum wl_output_transform orientation,
6694 + struct weston_matrix *m)
6696 + float source_center_x;
6697 + float source_center_y;
6702 + float translate_x;
6703 + float translate_y;
6705 + source_center_x = source_rect->x + source_rect->width * 0.5f;
6706 + source_center_y = source_rect->y + source_rect->height * 0.5f;
6707 + weston_matrix_translate(m, -source_center_x, -source_center_y, 0.0f);
6709 + get_rotate_values(orientation, &vsin, &vcos);
6710 + weston_matrix_rotate_xy(m, vcos, vsin);
6712 + get_scale(orientation,
6714 + dest_rect->height,
6715 + source_rect->width,
6716 + source_rect->height,
6719 + weston_matrix_scale(m, scale_x, scale_y, 1.0f);
6721 + translate_x = dest_rect->width * 0.5f + dest_rect->x;
6722 + translate_y = dest_rect->height * 0.5f + dest_rect->y;
6723 + weston_matrix_translate(m, translate_x, translate_y, 0.0f);
6727 + * This computes intersected rect_output from two ivi_rectangles
6730 +ivi_rectangle_intersect(const struct ivi_rectangle *rect1,
6731 + const struct ivi_rectangle *rect2,
6732 + struct ivi_rectangle *rect_output)
6734 + int32_t rect1_right = rect1->x + rect1->width;
6735 + int32_t rect1_bottom = rect1->y + rect1->height;
6736 + int32_t rect2_right = rect2->x + rect2->width;
6737 + int32_t rect2_bottom = rect2->y + rect2->height;
6739 + rect_output->x = max(rect1->x, rect2->x);
6740 + rect_output->y = max(rect1->y, rect2->y);
6741 + rect_output->width = rect1_right < rect2_right ?
6742 + rect1_right - rect_output->x :
6743 + rect2_right - rect_output->x;
6744 + rect_output->height = rect1_bottom < rect2_bottom ?
6745 + rect1_bottom - rect_output->y :
6746 + rect2_bottom - rect_output->y;
6748 + if (rect_output->width < 0 || rect_output->height < 0) {
6749 + rect_output->width = 0;
6750 + rect_output->height = 0;
6755 + * Transform rect_input by the inverse of matrix, intersect with boundingbox,
6756 + * and store the result in rect_output.
6757 + * The boundingbox must be given in the same coordinate space as rect_output.
6758 + * Additionally, there are the following restrictions on the matrix:
6759 + * - no projective transformations
6761 + * - only multiples of 90-degree rotations supported
6763 + * In failure case of weston_matrix_invert, rect_output is set to boundingbox
6764 + * as a fail-safe with log.
6767 +calc_inverse_matrix_transform(const struct weston_matrix *matrix,
6768 + const struct ivi_rectangle *rect_input,
6769 + const struct ivi_rectangle *boundingbox,
6770 + struct ivi_rectangle *rect_output)
6772 + struct weston_matrix m;
6773 + struct weston_vector top_left;
6774 + struct weston_vector bottom_right;
6776 + assert(boundingbox != rect_output);
6778 + if (weston_matrix_invert(&m, matrix) < 0) {
6779 + weston_log("ivi-shell: calc_inverse_matrix_transform fails to invert a matrix.\n");
6780 + weston_log("ivi-shell: boundingbox is set to the rect_output.\n");
6781 + rect_output->x = boundingbox->x;
6782 + rect_output->y = boundingbox->y;
6783 + rect_output->width = boundingbox->width;
6784 + rect_output->height = boundingbox->height;
6787 + /* The vectors and matrices involved will always produce f[3] == 1.0. */
6788 + top_left.f[0] = rect_input->x;
6789 + top_left.f[1] = rect_input->y;
6790 + top_left.f[2] = 0.0f;
6791 + top_left.f[3] = 1.0f;
6793 + bottom_right.f[0] = rect_input->x + rect_input->width;
6794 + bottom_right.f[1] = rect_input->y + rect_input->height;
6795 + bottom_right.f[2] = 0.0f;
6796 + bottom_right.f[3] = 1.0f;
6798 + weston_matrix_transform(&m, &top_left);
6799 + weston_matrix_transform(&m, &bottom_right);
6801 + if (top_left.f[0] < bottom_right.f[0]) {
6802 + rect_output->x = top_left.f[0];
6803 + rect_output->width = bottom_right.f[0] - rect_output->x;
6805 + rect_output->x = bottom_right.f[0];
6806 + rect_output->width = top_left.f[0] - rect_output->x;
6809 + if (top_left.f[1] < bottom_right.f[1]) {
6810 + rect_output->y = top_left.f[1];
6811 + rect_output->height = bottom_right.f[1] - rect_output->y;
6813 + rect_output->y = bottom_right.f[1];
6814 + rect_output->height = top_left.f[1] - rect_output->y;
6817 + ivi_rectangle_intersect(rect_output, boundingbox, rect_output);
6821 + * This computes the whole transformation matrix:m from surface-local
6822 + * coordinates to global coordinates. It is assumed that
6823 + * weston_view::geometry.{x,y} are zero.
6825 + * Additionally, this computes the mask on surface-local coordinates as a
6826 + * ivi_rectangle. This can be set to weston_view_set_mask.
6828 + * The mask is computed by following steps
6829 + * - destination rectangle of layer is inversed to surface-local cooodinates
6830 + * by inversed matrix:m.
6831 + * - the area is intersected by intersected area between weston_surface and
6832 + * source rectangle of ivi_surface.
6835 +calc_surface_to_global_matrix_and_mask_to_weston_surface(
6836 + struct ivi_layout_layer *ivilayer,
6837 + struct ivi_layout_surface *ivisurf,
6838 + struct weston_matrix *m,
6839 + struct ivi_rectangle *result)
6841 + const struct ivi_layout_surface_properties *sp = &ivisurf->prop;
6842 + const struct ivi_layout_layer_properties *lp = &ivilayer->prop;
6843 + struct ivi_rectangle weston_surface_rect = { 0,
6845 + ivisurf->surface->width,
6846 + ivisurf->surface->height };
6847 + struct ivi_rectangle surface_source_rect = { sp->source_x,
6850 + sp->source_height };
6851 + struct ivi_rectangle surface_dest_rect = { sp->dest_x,
6854 + sp->dest_height };
6855 + struct ivi_rectangle layer_source_rect = { lp->source_x,
6858 + lp->source_height };
6859 + struct ivi_rectangle layer_dest_rect = { lp->dest_x,
6862 + lp->dest_height };
6863 + struct ivi_rectangle surface_result;
6866 + * the whole transformation matrix:m from surface-local
6867 + * coordinates to global coordinates, which is computed by
6869 + * - surface-local coordinates to layer-local coordinates
6870 + * - layer-local coordinates to global coordinates
6872 + calc_transformation_matrix(&surface_source_rect,
6873 + &surface_dest_rect,
6874 + sp->orientation, m);
6876 + calc_transformation_matrix(&layer_source_rect,
6878 + lp->orientation, m);
6880 + /* this intersected ivi_rectangle would be used for masking
6883 + ivi_rectangle_intersect(&surface_source_rect, &weston_surface_rect,
6886 + /* calc masking area of weston_surface from m */
6887 + calc_inverse_matrix_transform(m,
6894 +update_prop(struct ivi_layout_layer *ivilayer,
6895 + struct ivi_layout_surface *ivisurf)
6897 + struct weston_view *tmpview;
6898 + struct ivi_rectangle r;
6899 + bool can_calc = true;
6901 + if (!ivilayer->event_mask && !ivisurf->event_mask) {
6905 + update_opacity(ivilayer, ivisurf);
6907 + wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
6908 + if (tmpview != NULL) {
6913 + if (ivisurf->prop.source_width == 0 || ivisurf->prop.source_height == 0) {
6914 + weston_log("ivi-shell: source rectangle is not yet set by ivi_layout_surface_set_source_rectangle\n");
6918 + if (ivisurf->prop.dest_width == 0 || ivisurf->prop.dest_height == 0) {
6919 + weston_log("ivi-shell: destination rectangle is not yet set by ivi_layout_surface_set_destination_rectangle\n");
6924 + wl_list_remove(&ivisurf->transform.link);
6925 + weston_matrix_init(&ivisurf->transform.matrix);
6927 + calc_surface_to_global_matrix_and_mask_to_weston_surface(
6928 + ivilayer, ivisurf, &ivisurf->transform.matrix, &r);
6930 + if (tmpview != NULL) {
6931 + wl_list_insert(&tmpview->geometry.transformation_list,
6932 + &ivisurf->transform.link);
6934 + weston_view_set_transform_parent(tmpview, NULL);
6938 + ivisurf->update_count++;
6940 + if (tmpview != NULL) {
6941 + weston_view_geometry_dirty(tmpview);
6944 + if (ivisurf->surface != NULL) {
6945 + weston_surface_damage(ivisurf->surface);
6950 +commit_changes(struct ivi_layout *layout)
6952 + struct ivi_layout_screen *iviscrn = NULL;
6953 + struct ivi_layout_layer *ivilayer = NULL;
6954 + struct ivi_layout_surface *ivisurf = NULL;
6956 + wl_list_for_each(iviscrn, &layout->screen_list, link) {
6957 + wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
6958 + wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
6959 + update_prop(ivilayer, ivisurf);
6966 +commit_surface_list(struct ivi_layout *layout)
6968 + struct ivi_layout_surface *ivisurf = NULL;
6969 + int32_t dest_x = 0;
6970 + int32_t dest_y = 0;
6971 + int32_t dest_width = 0;
6972 + int32_t dest_height = 0;
6973 + int32_t configured = 0;
6975 + wl_list_for_each(ivisurf, &layout->surface_list, link) {
6976 + if (ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEFAULT) {
6977 + dest_x = ivisurf->prop.dest_x;
6978 + dest_y = ivisurf->prop.dest_y;
6979 + dest_width = ivisurf->prop.dest_width;
6980 + dest_height = ivisurf->prop.dest_height;
6982 + ivi_layout_transition_move_resize_view(ivisurf,
6983 + ivisurf->pending.prop.dest_x,
6984 + ivisurf->pending.prop.dest_y,
6985 + ivisurf->pending.prop.dest_width,
6986 + ivisurf->pending.prop.dest_height,
6987 + ivisurf->pending.prop.transition_duration);
6989 + if (ivisurf->pending.prop.visibility) {
6990 + ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
6992 + ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
6995 + ivisurf->prop = ivisurf->pending.prop;
6996 + ivisurf->prop.dest_x = dest_x;
6997 + ivisurf->prop.dest_y = dest_y;
6998 + ivisurf->prop.dest_width = dest_width;
6999 + ivisurf->prop.dest_height = dest_height;
7000 + ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
7001 + ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
7003 + } else if (ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY) {
7004 + dest_x = ivisurf->prop.dest_x;
7005 + dest_y = ivisurf->prop.dest_y;
7006 + dest_width = ivisurf->prop.dest_width;
7007 + dest_height = ivisurf->prop.dest_height;
7009 + ivi_layout_transition_move_resize_view(ivisurf,
7010 + ivisurf->pending.prop.dest_x,
7011 + ivisurf->pending.prop.dest_y,
7012 + ivisurf->pending.prop.dest_width,
7013 + ivisurf->pending.prop.dest_height,
7014 + ivisurf->pending.prop.transition_duration);
7016 + ivisurf->prop = ivisurf->pending.prop;
7017 + ivisurf->prop.dest_x = dest_x;
7018 + ivisurf->prop.dest_y = dest_y;
7019 + ivisurf->prop.dest_width = dest_width;
7020 + ivisurf->prop.dest_height = dest_height;
7022 + ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
7023 + ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
7025 + } else if (ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY) {
7027 + if (ivisurf->pending.prop.visibility) {
7028 + ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
7030 + ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
7033 + if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
7034 + ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
7038 + ivisurf->prop = ivisurf->pending.prop;
7039 + ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
7040 + ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
7042 + if (configured && !is_surface_transition(ivisurf))
7043 + wl_signal_emit(&ivisurf->configured, ivisurf);
7046 + if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
7047 + ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
7051 + ivisurf->prop = ivisurf->pending.prop;
7052 + ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
7053 + ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
7055 + if (configured && !is_surface_transition(ivisurf))
7056 + wl_signal_emit(&ivisurf->configured, ivisurf);
7062 +commit_layer_list(struct ivi_layout *layout)
7064 + struct ivi_layout_layer *ivilayer = NULL;
7065 + struct ivi_layout_surface *ivisurf = NULL;
7066 + struct ivi_layout_surface *next = NULL;
7068 + wl_list_for_each(ivilayer, &layout->layer_list, link) {
7069 + if (ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_MOVE) {
7070 + ivi_layout_transition_move_layer(ivilayer, ivilayer->pending.prop.dest_x, ivilayer->pending.prop.dest_y, ivilayer->pending.prop.transition_duration);
7071 + } else if (ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_FADE) {
7072 + ivi_layout_transition_fade_layer(ivilayer,ivilayer->pending.prop.is_fade_in,
7073 + ivilayer->pending.prop.start_alpha,ivilayer->pending.prop.end_alpha,
7075 + ivilayer->pending.prop.transition_duration);
7077 + ivilayer->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
7079 + ivilayer->prop = ivilayer->pending.prop;
7081 + if (!ivilayer->order.dirty) {
7085 + wl_list_for_each_safe(ivisurf, next, &ivilayer->order.surface_list,
7087 + remove_ordersurface_from_layer(ivisurf);
7088 + wl_list_remove(&ivisurf->order.link);
7089 + wl_list_init(&ivisurf->order.link);
7090 + ivisurf->event_mask |= IVI_NOTIFICATION_REMOVE;
7093 + assert(wl_list_empty(&ivilayer->order.surface_list));
7095 + wl_list_for_each(ivisurf, &ivilayer->pending.surface_list,
7097 + wl_list_remove(&ivisurf->order.link);
7098 + wl_list_insert(&ivilayer->order.surface_list,
7099 + &ivisurf->order.link);
7100 + add_ordersurface_to_layer(ivisurf, ivilayer);
7101 + ivisurf->event_mask |= IVI_NOTIFICATION_ADD;
7104 + ivilayer->order.dirty = 0;
7109 +commit_screen_list(struct ivi_layout *layout)
7111 + struct ivi_layout_screen *iviscrn = NULL;
7112 + struct ivi_layout_layer *ivilayer = NULL;
7113 + struct ivi_layout_layer *next = NULL;
7114 + struct ivi_layout_surface *ivisurf = NULL;
7116 + wl_list_for_each(iviscrn, &layout->screen_list, link) {
7117 + if (iviscrn->order.dirty) {
7118 + wl_list_for_each_safe(ivilayer, next,
7119 + &iviscrn->order.layer_list, order.link) {
7120 + remove_orderlayer_from_screen(ivilayer);
7121 + wl_list_remove(&ivilayer->order.link);
7122 + wl_list_init(&ivilayer->order.link);
7123 + ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
7126 + assert(wl_list_empty(&iviscrn->order.layer_list));
7128 + wl_list_for_each(ivilayer, &iviscrn->pending.layer_list,
7130 + wl_list_insert(&iviscrn->order.layer_list,
7131 + &ivilayer->order.link);
7132 + add_orderlayer_to_screen(ivilayer, iviscrn);
7133 + ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
7136 + iviscrn->order.dirty = 0;
7139 + /* Clear view list of layout ivi_layer */
7140 + wl_list_init(&layout->layout_layer.view_list);
7142 + wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
7143 + if (ivilayer->prop.visibility == false)
7146 + wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
7147 + struct weston_view *tmpview = NULL;
7148 + wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
7149 + if (tmpview != NULL) {
7154 + if (ivisurf->prop.visibility == false)
7156 + if (ivisurf->surface == NULL || tmpview == NULL)
7159 + wl_list_insert(&layout->layout_layer.view_list,
7160 + &tmpview->layer_link);
7162 + ivisurf->surface->output = iviscrn->output;
7171 +commit_transition(struct ivi_layout* layout)
7173 + if (wl_list_empty(&layout->pending_transition_list)) {
7177 + wl_list_insert_list(&layout->transitions->transition_list,
7178 + &layout->pending_transition_list);
7180 + wl_list_init(&layout->pending_transition_list);
7182 + wl_event_source_timer_update(layout->transitions->event_source, 1);
7186 +send_surface_prop(struct ivi_layout_surface *ivisurf)
7188 + wl_signal_emit(&ivisurf->property_changed, ivisurf);
7189 + ivisurf->event_mask = 0;
7193 +send_layer_prop(struct ivi_layout_layer *ivilayer)
7195 + wl_signal_emit(&ivilayer->property_changed, ivilayer);
7196 + ivilayer->event_mask = 0;
7200 +send_prop(struct ivi_layout *layout)
7202 + struct ivi_layout_layer *ivilayer = NULL;
7203 + struct ivi_layout_surface *ivisurf = NULL;
7205 + wl_list_for_each_reverse(ivilayer, &layout->layer_list, link) {
7206 + if (ivilayer->event_mask)
7207 + send_layer_prop(ivilayer);
7210 + wl_list_for_each_reverse(ivisurf, &layout->surface_list, link) {
7211 + if (ivisurf->event_mask)
7212 + send_surface_prop(ivisurf);
7217 +clear_surface_pending_list(struct ivi_layout_layer *ivilayer)
7219 + struct ivi_layout_surface *surface_link = NULL;
7220 + struct ivi_layout_surface *surface_next = NULL;
7222 + wl_list_for_each_safe(surface_link, surface_next,
7223 + &ivilayer->pending.surface_list, pending.link) {
7224 + wl_list_remove(&surface_link->pending.link);
7225 + wl_list_init(&surface_link->pending.link);
7230 +clear_surface_order_list(struct ivi_layout_layer *ivilayer)
7232 + struct ivi_layout_surface *surface_link = NULL;
7233 + struct ivi_layout_surface *surface_next = NULL;
7235 + wl_list_for_each_safe(surface_link, surface_next,
7236 + &ivilayer->order.surface_list, order.link) {
7237 + wl_list_remove(&surface_link->order.link);
7238 + wl_list_init(&surface_link->order.link);
7243 +layer_created(struct wl_listener *listener, void *data)
7245 + struct ivi_layout_layer *ivilayer = data;
7247 + struct listener_layout_notification *notification =
7248 + container_of(listener,
7249 + struct listener_layout_notification,
7252 + struct ivi_layout_notification_callback *created_callback =
7253 + notification->userdata;
7255 + ((layer_create_notification_func)created_callback->callback)
7256 + (ivilayer, created_callback->data);
7260 +layer_removed(struct wl_listener *listener, void *data)
7262 + struct ivi_layout_layer *ivilayer = data;
7264 + struct listener_layout_notification *notification =
7265 + container_of(listener,
7266 + struct listener_layout_notification,
7269 + struct ivi_layout_notification_callback *removed_callback =
7270 + notification->userdata;
7272 + ((layer_remove_notification_func)removed_callback->callback)
7273 + (ivilayer, removed_callback->data);
7277 +layer_prop_changed(struct wl_listener *listener, void *data)
7279 + struct ivi_layout_layer *ivilayer = data;
7281 + struct listener_layout_notification *layout_listener =
7282 + container_of(listener,
7283 + struct listener_layout_notification,
7286 + struct ivi_layout_notification_callback *prop_callback =
7287 + layout_listener->userdata;
7289 + ((layer_property_notification_func)prop_callback->callback)
7290 + (ivilayer, &ivilayer->prop, ivilayer->event_mask, prop_callback->data);
7294 +surface_created(struct wl_listener *listener, void *data)
7296 + struct ivi_layout_surface *ivisurface = data;
7298 + struct listener_layout_notification *notification =
7299 + container_of(listener,
7300 + struct listener_layout_notification,
7303 + struct ivi_layout_notification_callback *created_callback =
7304 + notification->userdata;
7306 + ((surface_create_notification_func)created_callback->callback)
7307 + (ivisurface, created_callback->data);
7311 +surface_removed(struct wl_listener *listener, void *data)
7313 + struct ivi_layout_surface *ivisurface = data;
7315 + struct listener_layout_notification *notification =
7316 + container_of(listener,
7317 + struct listener_layout_notification,
7320 + struct ivi_layout_notification_callback *removed_callback =
7321 + notification->userdata;
7323 + ((surface_remove_notification_func)removed_callback->callback)
7324 + (ivisurface, removed_callback->data);
7328 +surface_prop_changed(struct wl_listener *listener, void *data)
7330 + struct ivi_layout_surface *ivisurf = data;
7332 + struct listener_layout_notification *layout_listener =
7333 + container_of(listener,
7334 + struct listener_layout_notification,
7337 + struct ivi_layout_notification_callback *prop_callback =
7338 + layout_listener->userdata;
7340 + ((surface_property_notification_func)prop_callback->callback)
7341 + (ivisurf, &ivisurf->prop, ivisurf->event_mask, prop_callback->data);
7343 + ivisurf->event_mask = 0;
7347 +surface_configure_changed(struct wl_listener *listener,
7350 + struct ivi_layout_surface *ivisurface = data;
7352 + struct listener_layout_notification *notification =
7353 + container_of(listener,
7354 + struct listener_layout_notification,
7357 + struct ivi_layout_notification_callback *configure_changed_callback =
7358 + notification->userdata;
7360 + ((surface_configure_notification_func)configure_changed_callback->callback)
7361 + (ivisurface, configure_changed_callback->data);
7365 +add_notification(struct wl_signal *signal,
7366 + wl_notify_func_t callback,
7369 + struct listener_layout_notification *notification = NULL;
7371 + notification = malloc(sizeof *notification);
7372 + if (notification == NULL) {
7373 + weston_log("fails to allocate memory\n");
7375 + return IVI_FAILED;
7378 + notification->listener.notify = callback;
7379 + notification->userdata = userdata;
7381 + wl_signal_add(signal, ¬ification->listener);
7383 + return IVI_SUCCEEDED;
7387 +remove_notification(struct wl_list *listener_list, void *callback, void *userdata)
7389 + struct wl_listener *listener = NULL;
7390 + struct wl_listener *next = NULL;
7392 + wl_list_for_each_safe(listener, next, listener_list, link) {
7393 + struct listener_layout_notification *notification =
7394 + container_of(listener,
7395 + struct listener_layout_notification,
7398 + struct ivi_layout_notification_callback *notification_callback =
7399 + notification->userdata;
7401 + if ((notification_callback->callback != callback) ||
7402 + (notification_callback->data != userdata)) {
7406 + wl_list_remove(&listener->link);
7408 + free(notification->userdata);
7409 + free(notification);
7414 + * Exported APIs of ivi-layout library are implemented from here.
7415 + * Brief of APIs is described in ivi-layout-export.h.
7418 +ivi_layout_add_notification_create_layer(layer_create_notification_func callback,
7421 + struct ivi_layout *layout = get_instance();
7422 + struct ivi_layout_notification_callback *created_callback = NULL;
7424 + if (callback == NULL) {
7425 + weston_log("ivi_layout_add_notification_create_layer: invalid argument\n");
7426 + return IVI_FAILED;
7429 + created_callback = malloc(sizeof *created_callback);
7430 + if (created_callback == NULL) {
7431 + weston_log("fails to allocate memory\n");
7432 + return IVI_FAILED;
7435 + created_callback->callback = callback;
7436 + created_callback->data = userdata;
7438 + return add_notification(&layout->layer_notification.created,
7440 + created_callback);
7444 +ivi_layout_remove_notification_create_layer(layer_create_notification_func callback,
7447 + struct ivi_layout *layout = get_instance();
7448 + remove_notification(&layout->layer_notification.created.listener_list, callback, userdata);
7452 +ivi_layout_add_notification_remove_layer(layer_remove_notification_func callback,
7455 + struct ivi_layout *layout = get_instance();
7456 + struct ivi_layout_notification_callback *removed_callback = NULL;
7458 + if (callback == NULL) {
7459 + weston_log("ivi_layout_add_notification_remove_layer: invalid argument\n");
7460 + return IVI_FAILED;
7463 + removed_callback = malloc(sizeof *removed_callback);
7464 + if (removed_callback == NULL) {
7465 + weston_log("fails to allocate memory\n");
7466 + return IVI_FAILED;
7469 + removed_callback->callback = callback;
7470 + removed_callback->data = userdata;
7471 + return add_notification(&layout->layer_notification.removed,
7473 + removed_callback);
7477 +ivi_layout_remove_notification_remove_layer(layer_remove_notification_func callback,
7480 + struct ivi_layout *layout = get_instance();
7481 + remove_notification(&layout->layer_notification.removed.listener_list, callback, userdata);
7485 +ivi_layout_add_notification_create_surface(surface_create_notification_func callback,
7488 + struct ivi_layout *layout = get_instance();
7489 + struct ivi_layout_notification_callback *created_callback = NULL;
7491 + if (callback == NULL) {
7492 + weston_log("ivi_layout_add_notification_create_surface: invalid argument\n");
7493 + return IVI_FAILED;
7496 + created_callback = malloc(sizeof *created_callback);
7497 + if (created_callback == NULL) {
7498 + weston_log("fails to allocate memory\n");
7499 + return IVI_FAILED;
7502 + created_callback->callback = callback;
7503 + created_callback->data = userdata;
7505 + return add_notification(&layout->surface_notification.created,
7507 + created_callback);
7511 +ivi_layout_remove_notification_create_surface(surface_create_notification_func callback,
7514 + struct ivi_layout *layout = get_instance();
7515 + remove_notification(&layout->surface_notification.created.listener_list, callback, userdata);
7519 +ivi_layout_add_notification_remove_surface(surface_remove_notification_func callback,
7522 + struct ivi_layout *layout = get_instance();
7523 + struct ivi_layout_notification_callback *removed_callback = NULL;
7525 + if (callback == NULL) {
7526 + weston_log("ivi_layout_add_notification_remove_surface: invalid argument\n");
7527 + return IVI_FAILED;
7530 + removed_callback = malloc(sizeof *removed_callback);
7531 + if (removed_callback == NULL) {
7532 + weston_log("fails to allocate memory\n");
7533 + return IVI_FAILED;
7536 + removed_callback->callback = callback;
7537 + removed_callback->data = userdata;
7539 + return add_notification(&layout->surface_notification.removed,
7541 + removed_callback);
7545 +ivi_layout_remove_notification_remove_surface(surface_remove_notification_func callback,
7548 + struct ivi_layout *layout = get_instance();
7549 + remove_notification(&layout->surface_notification.removed.listener_list, callback, userdata);
7553 +ivi_layout_add_notification_configure_surface(surface_configure_notification_func callback,
7556 + struct ivi_layout *layout = get_instance();
7557 + struct ivi_layout_notification_callback *configure_changed_callback = NULL;
7558 + if (callback == NULL) {
7559 + weston_log("ivi_layout_add_notification_configure_surface: invalid argument\n");
7560 + return IVI_FAILED;
7563 + configure_changed_callback = malloc(sizeof *configure_changed_callback);
7564 + if (configure_changed_callback == NULL) {
7565 + weston_log("fails to allocate memory\n");
7566 + return IVI_FAILED;
7569 + configure_changed_callback->callback = callback;
7570 + configure_changed_callback->data = userdata;
7572 + return add_notification(&layout->surface_notification.configure_changed,
7573 + surface_configure_changed,
7574 + configure_changed_callback);
7578 +ivi_layout_remove_notification_configure_surface(surface_configure_notification_func callback,
7581 + struct ivi_layout *layout = get_instance();
7582 + remove_notification(&layout->surface_notification.configure_changed.listener_list, callback, userdata);
7586 +ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf)
7588 + return ivisurf->id_surface;
7592 +ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer)
7594 + return ivilayer->id_layer;
7598 +ivi_layout_get_id_of_screen(struct ivi_layout_screen *iviscrn)
7600 + return iviscrn->id_screen;
7603 +static struct ivi_layout_layer *
7604 +ivi_layout_get_layer_from_id(uint32_t id_layer)
7606 + struct ivi_layout *layout = get_instance();
7607 + struct ivi_layout_layer *ivilayer = NULL;
7609 + wl_list_for_each(ivilayer, &layout->layer_list, link) {
7610 + if (ivilayer->id_layer == id_layer) {
7618 +struct ivi_layout_surface *
7619 +ivi_layout_get_surface_from_id(uint32_t id_surface)
7621 + struct ivi_layout *layout = get_instance();
7622 + struct ivi_layout_surface *ivisurf = NULL;
7624 + wl_list_for_each(ivisurf, &layout->surface_list, link) {
7625 + if (ivisurf->id_surface == id_surface) {
7633 +static struct ivi_layout_screen *
7634 +ivi_layout_get_screen_from_id(uint32_t id_screen)
7636 + struct ivi_layout *layout = get_instance();
7637 + struct ivi_layout_screen *iviscrn = NULL;
7639 + wl_list_for_each(iviscrn, &layout->screen_list, link) {
7640 +/* FIXME : select iviscrn from screen_list by id_screen */
7649 +ivi_layout_get_screen_resolution(struct ivi_layout_screen *iviscrn,
7650 + int32_t *pWidth, int32_t *pHeight)
7652 + struct weston_output *output = NULL;
7654 + if (iviscrn == NULL || pWidth == NULL || pHeight == NULL) {
7655 + weston_log("ivi_layout_get_screen_resolution: invalid argument\n");
7656 + return IVI_FAILED;
7659 + output = iviscrn->output;
7660 + *pWidth = output->current_mode->width;
7661 + *pHeight = output->current_mode->height;
7663 + return IVI_SUCCEEDED;
7667 +ivi_layout_surface_add_notification(struct ivi_layout_surface *ivisurf,
7668 + surface_property_notification_func callback,
7671 + struct listener_layout_notification* notification = NULL;
7672 + struct ivi_layout_notification_callback *prop_callback = NULL;
7674 + if (ivisurf == NULL || callback == NULL) {
7675 + weston_log("ivi_layout_surface_add_notification: invalid argument\n");
7676 + return IVI_FAILED;
7679 + notification = malloc(sizeof *notification);
7680 + if (notification == NULL) {
7681 + weston_log("fails to allocate memory\n");
7682 + return IVI_FAILED;
7685 + prop_callback = malloc(sizeof *prop_callback);
7686 + if (prop_callback == NULL) {
7687 + weston_log("fails to allocate memory\n");
7688 + return IVI_FAILED;
7691 + prop_callback->callback = callback;
7692 + prop_callback->data = userdata;
7694 + notification->listener.notify = surface_prop_changed;
7695 + notification->userdata = prop_callback;
7697 + wl_signal_add(&ivisurf->property_changed, ¬ification->listener);
7699 + return IVI_SUCCEEDED;
7702 +static const struct ivi_layout_layer_properties *
7703 +ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer)
7705 + if (ivilayer == NULL) {
7706 + weston_log("ivi_layout_get_properties_of_layer: invalid argument\n");
7710 + return &ivilayer->prop;
7714 +ivi_layout_get_screens(int32_t *pLength, struct ivi_layout_screen ***ppArray)
7716 + struct ivi_layout *layout = get_instance();
7717 + struct ivi_layout_screen *iviscrn = NULL;
7718 + int32_t length = 0;
7721 + if (pLength == NULL || ppArray == NULL) {
7722 + weston_log("ivi_layout_get_screens: invalid argument\n");
7723 + return IVI_FAILED;
7726 + length = wl_list_length(&layout->screen_list);
7728 + if (length != 0) {
7729 + /* the Array must be free by module which called this function */
7730 + *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
7731 + if (*ppArray == NULL) {
7732 + weston_log("fails to allocate memory\n");
7733 + return IVI_FAILED;
7736 + wl_list_for_each(iviscrn, &layout->screen_list, link) {
7737 + (*ppArray)[n++] = iviscrn;
7741 + *pLength = length;
7743 + return IVI_SUCCEEDED;
7747 +ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer,
7749 + struct ivi_layout_screen ***ppArray)
7751 + struct link_screen *link_scrn = NULL;
7752 + int32_t length = 0;
7755 + if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
7756 + weston_log("ivi_layout_get_screens_under_layer: invalid argument\n");
7757 + return IVI_FAILED;
7760 + length = wl_list_length(&ivilayer->screen_list);
7762 + if (length != 0) {
7763 + /* the Array must be free by module which called this function */
7764 + *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
7765 + if (*ppArray == NULL) {
7766 + weston_log("fails to allocate memory\n");
7767 + return IVI_FAILED;
7770 + wl_list_for_each(link_scrn, &ivilayer->screen_list, link) {
7771 + (*ppArray)[n++] = link_scrn->iviscrn;
7775 + *pLength = length;
7777 + return IVI_SUCCEEDED;
7781 +ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray)
7783 + struct ivi_layout *layout = get_instance();
7784 + struct ivi_layout_layer *ivilayer = NULL;
7785 + int32_t length = 0;
7788 + if (pLength == NULL || ppArray == NULL) {
7789 + weston_log("ivi_layout_get_layers: invalid argument\n");
7790 + return IVI_FAILED;
7793 + length = wl_list_length(&layout->layer_list);
7795 + if (length != 0) {
7796 + /* the Array must be free by module which called this function */
7797 + *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
7798 + if (*ppArray == NULL) {
7799 + weston_log("fails to allocate memory\n");
7800 + return IVI_FAILED;
7803 + wl_list_for_each(ivilayer, &layout->layer_list, link) {
7804 + (*ppArray)[n++] = ivilayer;
7808 + *pLength = length;
7810 + return IVI_SUCCEEDED;
7814 +ivi_layout_get_layers_on_screen(struct ivi_layout_screen *iviscrn,
7816 + struct ivi_layout_layer ***ppArray)
7818 + struct ivi_layout_layer *ivilayer = NULL;
7819 + int32_t length = 0;
7822 + if (iviscrn == NULL || pLength == NULL || ppArray == NULL) {
7823 + weston_log("ivi_layout_get_layers_on_screen: invalid argument\n");
7824 + return IVI_FAILED;
7827 + length = wl_list_length(&iviscrn->order.layer_list);
7829 + if (length != 0) {
7830 + /* the Array must be free by module which called this function */
7831 + *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
7832 + if (*ppArray == NULL) {
7833 + weston_log("fails to allocate memory\n");
7834 + return IVI_FAILED;
7837 + wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
7838 + (*ppArray)[n++] = ivilayer;
7842 + *pLength = length;
7844 + return IVI_SUCCEEDED;
7848 +ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf,
7850 + struct ivi_layout_layer ***ppArray)
7852 + struct link_layer *link_layer = NULL;
7853 + int32_t length = 0;
7856 + if (ivisurf == NULL || pLength == NULL || ppArray == NULL) {
7857 + weston_log("ivi_layout_getLayers: invalid argument\n");
7858 + return IVI_FAILED;
7861 + length = wl_list_length(&ivisurf->layer_list);
7863 + if (length != 0) {
7864 + /* the Array must be free by module which called this function */
7865 + *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
7866 + if (*ppArray == NULL) {
7867 + weston_log("fails to allocate memory\n");
7868 + return IVI_FAILED;
7871 + wl_list_for_each(link_layer, &ivisurf->layer_list, link) {
7872 + (*ppArray)[n++] = link_layer->ivilayer;
7876 + *pLength = length;
7878 + return IVI_SUCCEEDED;
7883 +ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray)
7885 + struct ivi_layout *layout = get_instance();
7886 + struct ivi_layout_surface *ivisurf = NULL;
7887 + int32_t length = 0;
7890 + if (pLength == NULL || ppArray == NULL) {
7891 + weston_log("ivi_layout_get_surfaces: invalid argument\n");
7892 + return IVI_FAILED;
7895 + length = wl_list_length(&layout->surface_list);
7897 + if (length != 0) {
7898 + /* the Array must be free by module which called this function */
7899 + *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
7900 + if (*ppArray == NULL) {
7901 + weston_log("fails to allocate memory\n");
7902 + return IVI_FAILED;
7905 + wl_list_for_each(ivisurf, &layout->surface_list, link) {
7906 + (*ppArray)[n++] = ivisurf;
7910 + *pLength = length;
7912 + return IVI_SUCCEEDED;
7916 +ivi_layout_get_surfaces_on_layer(struct ivi_layout_layer *ivilayer,
7918 + struct ivi_layout_surface ***ppArray)
7920 + struct ivi_layout_surface *ivisurf = NULL;
7921 + int32_t length = 0;
7924 + if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
7925 + weston_log("ivi_layout_getSurfaceIDsOnLayer: invalid argument\n");
7926 + return IVI_FAILED;
7929 + length = wl_list_length(&ivilayer->order.surface_list);
7931 + if (length != 0) {
7932 + /* the Array must be free by module which called this function */
7933 + *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
7934 + if (*ppArray == NULL) {
7935 + weston_log("fails to allocate memory\n");
7936 + return IVI_FAILED;
7939 + wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
7940 + (*ppArray)[n++] = ivisurf;
7944 + *pLength = length;
7946 + return IVI_SUCCEEDED;
7949 +static struct ivi_layout_layer *
7950 +ivi_layout_layer_create_with_dimension(uint32_t id_layer,
7951 + int32_t width, int32_t height)
7953 + struct ivi_layout *layout = get_instance();
7954 + struct ivi_layout_layer *ivilayer = NULL;
7956 + ivilayer = get_layer(&layout->layer_list, id_layer);
7957 + if (ivilayer != NULL) {
7958 + weston_log("id_layer is already created\n");
7959 + ++ivilayer->ref_count;
7963 + ivilayer = calloc(1, sizeof *ivilayer);
7964 + if (ivilayer == NULL) {
7965 + weston_log("fails to allocate memory\n");
7969 + ivilayer->ref_count = 1;
7970 + wl_signal_init(&ivilayer->property_changed);
7971 + wl_list_init(&ivilayer->screen_list);
7972 + wl_list_init(&ivilayer->link_to_surface);
7973 + ivilayer->layout = layout;
7974 + ivilayer->id_layer = id_layer;
7976 + init_layer_properties(&ivilayer->prop, width, height);
7977 + ivilayer->event_mask = 0;
7979 + wl_list_init(&ivilayer->pending.surface_list);
7980 + wl_list_init(&ivilayer->pending.link);
7981 + ivilayer->pending.prop = ivilayer->prop;
7983 + wl_list_init(&ivilayer->order.surface_list);
7984 + wl_list_init(&ivilayer->order.link);
7986 + wl_list_insert(&layout->layer_list, &ivilayer->link);
7988 + wl_signal_emit(&layout->layer_notification.created, ivilayer);
7994 +ivi_layout_layer_remove_notification(struct ivi_layout_layer *ivilayer)
7996 + if (ivilayer == NULL) {
7997 + weston_log("ivi_layout_layer_remove_notification: invalid argument\n");
8001 + remove_all_notification(&ivilayer->property_changed.listener_list);
8005 +ivi_layout_layer_remove_notification_by_callback(struct ivi_layout_layer *ivilayer,
8006 + layer_property_notification_func callback,
8009 + if (ivilayer == NULL) {
8010 + weston_log("ivi_layout_layer_remove_notification_by_callback: invalid argument\n");
8014 + remove_notification(&ivilayer->property_changed.listener_list, callback, userdata);
8018 +ivi_layout_layer_destroy(struct ivi_layout_layer *ivilayer)
8020 + struct ivi_layout *layout = get_instance();
8022 + if (ivilayer == NULL) {
8023 + weston_log("ivi_layout_layer_remove: invalid argument\n");
8027 + if (--ivilayer->ref_count > 0)
8030 + wl_signal_emit(&layout->layer_notification.removed, ivilayer);
8032 + clear_surface_pending_list(ivilayer);
8033 + clear_surface_order_list(ivilayer);
8035 + wl_list_remove(&ivilayer->pending.link);
8036 + wl_list_remove(&ivilayer->order.link);
8037 + wl_list_remove(&ivilayer->link);
8039 + remove_orderlayer_from_screen(ivilayer);
8040 + remove_link_to_surface(ivilayer);
8041 + ivi_layout_layer_remove_notification(ivilayer);
8047 +ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer,
8048 + bool newVisibility)
8050 + struct ivi_layout_layer_properties *prop = NULL;
8052 + if (ivilayer == NULL) {
8053 + weston_log("ivi_layout_layer_set_visibility: invalid argument\n");
8054 + return IVI_FAILED;
8057 + prop = &ivilayer->pending.prop;
8058 + prop->visibility = newVisibility;
8060 + if (ivilayer->prop.visibility != newVisibility)
8061 + ivilayer->event_mask |= IVI_NOTIFICATION_VISIBILITY;
8063 + ivilayer->event_mask &= ~IVI_NOTIFICATION_VISIBILITY;
8065 + return IVI_SUCCEEDED;
8069 +ivi_layout_layer_get_visibility(struct ivi_layout_layer *ivilayer)
8071 + if (ivilayer == NULL) {
8072 + weston_log("ivi_layout_layer_get_visibility: invalid argument\n");
8076 + return ivilayer->prop.visibility;
8080 +ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
8081 + wl_fixed_t opacity)
8083 + struct ivi_layout_layer_properties *prop = NULL;
8085 + if (ivilayer == NULL ||
8086 + opacity < wl_fixed_from_double(0.0) ||
8087 + wl_fixed_from_double(1.0) < opacity) {
8088 + weston_log("ivi_layout_layer_set_opacity: invalid argument\n");
8089 + return IVI_FAILED;
8092 + prop = &ivilayer->pending.prop;
8093 + prop->opacity = opacity;
8095 + if (ivilayer->prop.opacity != opacity)
8096 + ivilayer->event_mask |= IVI_NOTIFICATION_OPACITY;
8098 + ivilayer->event_mask &= ~IVI_NOTIFICATION_OPACITY;
8100 + return IVI_SUCCEEDED;
8104 +ivi_layout_layer_get_opacity(struct ivi_layout_layer *ivilayer)
8106 + if (ivilayer == NULL) {
8107 + weston_log("ivi_layout_layer_get_opacity: invalid argument\n");
8108 + return wl_fixed_from_double(0.0);
8111 + return ivilayer->prop.opacity;
8115 +ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer,
8116 + int32_t x, int32_t y,
8117 + int32_t width, int32_t height)
8119 + struct ivi_layout_layer_properties *prop = NULL;
8121 + if (ivilayer == NULL) {
8122 + weston_log("ivi_layout_layer_set_source_rectangle: invalid argument\n");
8123 + return IVI_FAILED;
8126 + prop = &ivilayer->pending.prop;
8127 + prop->source_x = x;
8128 + prop->source_y = y;
8129 + prop->source_width = width;
8130 + prop->source_height = height;
8132 + if (ivilayer->prop.source_x != x || ivilayer->prop.source_y != y ||
8133 + ivilayer->prop.source_width != width ||
8134 + ivilayer->prop.source_height != height)
8135 + ivilayer->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
8137 + ivilayer->event_mask &= ~IVI_NOTIFICATION_SOURCE_RECT;
8139 + return IVI_SUCCEEDED;
8143 +ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer,
8144 + int32_t x, int32_t y,
8145 + int32_t width, int32_t height)
8147 + struct ivi_layout_layer_properties *prop = NULL;
8149 + if (ivilayer == NULL) {
8150 + weston_log("ivi_layout_layer_set_destination_rectangle: invalid argument\n");
8151 + return IVI_FAILED;
8154 + prop = &ivilayer->pending.prop;
8157 + prop->dest_width = width;
8158 + prop->dest_height = height;
8160 + if (ivilayer->prop.dest_x != x || ivilayer->prop.dest_y != y ||
8161 + ivilayer->prop.dest_width != width ||
8162 + ivilayer->prop.dest_height != height)
8163 + ivilayer->event_mask |= IVI_NOTIFICATION_DEST_RECT;
8165 + ivilayer->event_mask &= ~IVI_NOTIFICATION_DEST_RECT;
8167 + return IVI_SUCCEEDED;
8171 +ivi_layout_layer_get_dimension(struct ivi_layout_layer *ivilayer,
8172 + int32_t *dest_width, int32_t *dest_height)
8174 + if (ivilayer == NULL || dest_width == NULL || dest_height == NULL) {
8175 + weston_log("ivi_layout_layer_get_dimension: invalid argument\n");
8176 + return IVI_FAILED;
8179 + *dest_width = ivilayer->prop.dest_width;
8180 + *dest_height = ivilayer->prop.dest_height;
8182 + return IVI_SUCCEEDED;
8186 +ivi_layout_layer_set_dimension(struct ivi_layout_layer *ivilayer,
8187 + int32_t dest_width, int32_t dest_height)
8189 + struct ivi_layout_layer_properties *prop = NULL;
8191 + if (ivilayer == NULL) {
8192 + weston_log("ivi_layout_layer_set_dimension: invalid argument\n");
8193 + return IVI_FAILED;
8196 + prop = &ivilayer->pending.prop;
8198 + prop->dest_width = dest_width;
8199 + prop->dest_height = dest_height;
8201 + if (ivilayer->prop.dest_width != dest_width ||
8202 + ivilayer->prop.dest_height != dest_height)
8203 + ivilayer->event_mask |= IVI_NOTIFICATION_DIMENSION;
8205 + ivilayer->event_mask &= ~IVI_NOTIFICATION_DIMENSION;
8207 + return IVI_SUCCEEDED;
8211 +ivi_layout_layer_get_position(struct ivi_layout_layer *ivilayer,
8212 + int32_t *dest_x, int32_t *dest_y)
8214 + if (ivilayer == NULL || dest_x == NULL || dest_y == NULL) {
8215 + weston_log("ivi_layout_layer_get_position: invalid argument\n");
8216 + return IVI_FAILED;
8219 + *dest_x = ivilayer->prop.dest_x;
8220 + *dest_y = ivilayer->prop.dest_y;
8222 + return IVI_SUCCEEDED;
8226 +ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer,
8227 + int32_t dest_x, int32_t dest_y)
8229 + struct ivi_layout_layer_properties *prop = NULL;
8231 + if (ivilayer == NULL) {
8232 + weston_log("ivi_layout_layer_set_position: invalid argument\n");
8233 + return IVI_FAILED;
8236 + prop = &ivilayer->pending.prop;
8237 + prop->dest_x = dest_x;
8238 + prop->dest_y = dest_y;
8240 + if (ivilayer->prop.dest_x != dest_x || ivilayer->prop.dest_y != dest_y)
8241 + ivilayer->event_mask |= IVI_NOTIFICATION_POSITION;
8243 + ivilayer->event_mask &= ~IVI_NOTIFICATION_POSITION;
8245 + return IVI_SUCCEEDED;
8249 +ivi_layout_layer_set_orientation(struct ivi_layout_layer *ivilayer,
8250 + enum wl_output_transform orientation)
8252 + struct ivi_layout_layer_properties *prop = NULL;
8254 + if (ivilayer == NULL) {
8255 + weston_log("ivi_layout_layer_set_orientation: invalid argument\n");
8256 + return IVI_FAILED;
8259 + prop = &ivilayer->pending.prop;
8260 + prop->orientation = orientation;
8262 + if (ivilayer->prop.orientation != orientation)
8263 + ivilayer->event_mask |= IVI_NOTIFICATION_ORIENTATION;
8265 + ivilayer->event_mask &= ~IVI_NOTIFICATION_ORIENTATION;
8267 + return IVI_SUCCEEDED;
8270 +static enum wl_output_transform
8271 +ivi_layout_layer_get_orientation(struct ivi_layout_layer *ivilayer)
8273 + if (ivilayer == NULL) {
8274 + weston_log("ivi_layout_layer_get_orientation: invalid argument\n");
8278 + return ivilayer->prop.orientation;
8282 +ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
8283 + struct ivi_layout_surface **pSurface,
8286 + struct ivi_layout *layout = get_instance();
8287 + struct ivi_layout_surface *ivisurf = NULL;
8288 + struct ivi_layout_surface *next = NULL;
8289 + uint32_t *id_surface = NULL;
8292 + if (ivilayer == NULL) {
8293 + weston_log("ivi_layout_layer_set_render_order: invalid argument\n");
8294 + return IVI_FAILED;
8297 + clear_surface_pending_list(ivilayer);
8299 + for (i = 0; i < number; i++) {
8300 + id_surface = &pSurface[i]->id_surface;
8302 + wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
8303 + if (*id_surface != ivisurf->id_surface) {
8307 + wl_list_remove(&ivisurf->pending.link);
8308 + wl_list_insert(&ivilayer->pending.surface_list,
8309 + &ivisurf->pending.link);
8314 + ivilayer->order.dirty = 1;
8316 + return IVI_SUCCEEDED;
8320 +ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf,
8321 + bool newVisibility)
8323 + struct ivi_layout_surface_properties *prop = NULL;
8325 + if (ivisurf == NULL) {
8326 + weston_log("ivi_layout_surface_set_visibility: invalid argument\n");
8327 + return IVI_FAILED;
8330 + prop = &ivisurf->pending.prop;
8331 + prop->visibility = newVisibility;
8333 + if (ivisurf->prop.visibility != newVisibility)
8334 + ivisurf->event_mask |= IVI_NOTIFICATION_VISIBILITY;
8336 + ivisurf->event_mask &= ~IVI_NOTIFICATION_VISIBILITY;
8338 + return IVI_SUCCEEDED;
8342 +ivi_layout_surface_get_visibility(struct ivi_layout_surface *ivisurf)
8344 + if (ivisurf == NULL) {
8345 + weston_log("ivi_layout_surface_get_visibility: invalid argument\n");
8349 + return ivisurf->prop.visibility;
8353 +ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
8354 + wl_fixed_t opacity)
8356 + struct ivi_layout_surface_properties *prop = NULL;
8358 + if (ivisurf == NULL ||
8359 + opacity < wl_fixed_from_double(0.0) ||
8360 + wl_fixed_from_double(1.0) < opacity) {
8361 + weston_log("ivi_layout_surface_set_opacity: invalid argument\n");
8362 + return IVI_FAILED;
8365 + prop = &ivisurf->pending.prop;
8366 + prop->opacity = opacity;
8368 + if (ivisurf->prop.opacity != opacity)
8369 + ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY;
8371 + ivisurf->event_mask &= ~IVI_NOTIFICATION_OPACITY;
8373 + return IVI_SUCCEEDED;
8377 +ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf)
8379 + if (ivisurf == NULL) {
8380 + weston_log("ivi_layout_surface_get_opacity: invalid argument\n");
8381 + return wl_fixed_from_double(0.0);
8384 + return ivisurf->prop.opacity;
8388 +ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
8389 + int32_t x, int32_t y,
8390 + int32_t width, int32_t height)
8392 + struct ivi_layout_surface_properties *prop = NULL;
8394 + if (ivisurf == NULL) {
8395 + weston_log("ivi_layout_surface_set_destination_rectangle: invalid argument\n");
8396 + return IVI_FAILED;
8399 + prop = &ivisurf->pending.prop;
8400 + prop->start_x = prop->dest_x;
8401 + prop->start_y = prop->dest_y;
8404 + prop->start_width = prop->dest_width;
8405 + prop->start_height = prop->dest_height;
8406 + prop->dest_width = width;
8407 + prop->dest_height = height;
8409 + if (ivisurf->prop.dest_x != x || ivisurf->prop.dest_y != y ||
8410 + ivisurf->prop.dest_width != width ||
8411 + ivisurf->prop.dest_height != height)
8412 + ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT;
8414 + ivisurf->event_mask &= ~IVI_NOTIFICATION_DEST_RECT;
8416 + return IVI_SUCCEEDED;
8420 +ivi_layout_surface_set_dimension(struct ivi_layout_surface *ivisurf,
8421 + int32_t dest_width, int32_t dest_height)
8423 + struct ivi_layout_surface_properties *prop = NULL;
8425 + if (ivisurf == NULL) {
8426 + weston_log("ivi_layout_surface_set_dimension: invalid argument\n");
8427 + return IVI_FAILED;
8430 + prop = &ivisurf->pending.prop;
8431 + prop->dest_width = dest_width;
8432 + prop->dest_height = dest_height;
8434 + if (ivisurf->prop.dest_width != dest_width ||
8435 + ivisurf->prop.dest_height != dest_height)
8436 + ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION;
8438 + ivisurf->event_mask &= ~IVI_NOTIFICATION_DIMENSION;
8440 + return IVI_SUCCEEDED;
8444 +ivi_layout_surface_get_dimension(struct ivi_layout_surface *ivisurf,
8445 + int32_t *dest_width, int32_t *dest_height)
8447 + if (ivisurf == NULL || dest_width == NULL || dest_height == NULL) {
8448 + weston_log("ivi_layout_surface_get_dimension: invalid argument\n");
8449 + return IVI_FAILED;
8452 + *dest_width = ivisurf->prop.dest_width;
8453 + *dest_height = ivisurf->prop.dest_height;
8455 + return IVI_SUCCEEDED;
8459 +ivi_layout_surface_set_position(struct ivi_layout_surface *ivisurf,
8460 + int32_t dest_x, int32_t dest_y)
8462 + struct ivi_layout_surface_properties *prop = NULL;
8464 + if (ivisurf == NULL) {
8465 + weston_log("ivi_layout_surface_set_position: invalid argument\n");
8466 + return IVI_FAILED;
8469 + prop = &ivisurf->pending.prop;
8470 + prop->dest_x = dest_x;
8471 + prop->dest_y = dest_y;
8473 + if (ivisurf->prop.dest_x != dest_x || ivisurf->prop.dest_y != dest_y)
8474 + ivisurf->event_mask |= IVI_NOTIFICATION_POSITION;
8476 + ivisurf->event_mask &= ~IVI_NOTIFICATION_POSITION;
8478 + return IVI_SUCCEEDED;
8482 +ivi_layout_surface_get_position(struct ivi_layout_surface *ivisurf,
8483 + int32_t *dest_x, int32_t *dest_y)
8485 + if (ivisurf == NULL || dest_x == NULL || dest_y == NULL) {
8486 + weston_log("ivi_layout_surface_get_position: invalid argument\n");
8487 + return IVI_FAILED;
8490 + *dest_x = ivisurf->prop.dest_x;
8491 + *dest_y = ivisurf->prop.dest_y;
8493 + return IVI_SUCCEEDED;
8497 +ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf,
8498 + enum wl_output_transform orientation)
8500 + struct ivi_layout_surface_properties *prop = NULL;
8502 + if (ivisurf == NULL) {
8503 + weston_log("ivi_layout_surface_set_orientation: invalid argument\n");
8504 + return IVI_FAILED;
8507 + prop = &ivisurf->pending.prop;
8508 + prop->orientation = orientation;
8510 + if (ivisurf->prop.orientation != orientation)
8511 + ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION;
8513 + ivisurf->event_mask &= ~IVI_NOTIFICATION_ORIENTATION;
8515 + return IVI_SUCCEEDED;
8518 +static enum wl_output_transform
8519 +ivi_layout_surface_get_orientation(struct ivi_layout_surface *ivisurf)
8521 + if (ivisurf == NULL) {
8522 + weston_log("ivi_layout_surface_get_orientation: invalid argument\n");
8526 + return ivisurf->prop.orientation;
8530 +ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn,
8531 + struct ivi_layout_layer *addlayer)
8533 + struct ivi_layout *layout = get_instance();
8534 + struct ivi_layout_layer *ivilayer = NULL;
8535 + struct ivi_layout_layer *next = NULL;
8536 + int is_layer_in_scrn = 0;
8538 + if (iviscrn == NULL || addlayer == NULL) {
8539 + weston_log("ivi_layout_screen_add_layer: invalid argument\n");
8540 + return IVI_FAILED;
8543 + is_layer_in_scrn = is_layer_in_screen(addlayer, iviscrn);
8544 + if (is_layer_in_scrn == 1) {
8545 + weston_log("ivi_layout_screen_add_layer: addlayer is already available\n");
8546 + return IVI_SUCCEEDED;
8549 + wl_list_for_each_safe(ivilayer, next, &layout->layer_list, link) {
8550 + if (ivilayer->id_layer == addlayer->id_layer) {
8551 + wl_list_remove(&ivilayer->pending.link);
8552 + wl_list_insert(&iviscrn->pending.layer_list,
8553 + &ivilayer->pending.link);
8558 + iviscrn->order.dirty = 1;
8560 + return IVI_SUCCEEDED;
8564 +ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn,
8565 + struct ivi_layout_layer **pLayer,
8566 + const int32_t number)
8568 + struct ivi_layout *layout = get_instance();
8569 + struct ivi_layout_layer *ivilayer = NULL;
8570 + struct ivi_layout_layer *next = NULL;
8571 + uint32_t *id_layer = NULL;
8574 + if (iviscrn == NULL) {
8575 + weston_log("ivi_layout_screen_set_render_order: invalid argument\n");
8576 + return IVI_FAILED;
8579 + wl_list_for_each_safe(ivilayer, next,
8580 + &iviscrn->pending.layer_list, pending.link) {
8581 + wl_list_remove(&ivilayer->pending.link);
8582 + wl_list_init(&ivilayer->pending.link);
8585 + assert(wl_list_empty(&iviscrn->pending.layer_list));
8587 + for (i = 0; i < number; i++) {
8588 + id_layer = &pLayer[i]->id_layer;
8589 + wl_list_for_each(ivilayer, &layout->layer_list, link) {
8590 + if (*id_layer != ivilayer->id_layer) {
8594 + wl_list_remove(&ivilayer->pending.link);
8595 + wl_list_insert(&iviscrn->pending.layer_list,
8596 + &ivilayer->pending.link);
8601 + iviscrn->order.dirty = 1;
8603 + return IVI_SUCCEEDED;
8606 +static struct weston_output *
8607 +ivi_layout_screen_get_output(struct ivi_layout_screen *iviscrn)
8609 + return iviscrn->output;
8613 + * This function is used by the additional ivi-module because of dumping ivi_surface sceenshot.
8614 + * The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of Genivi's Layer Management.
8615 + * This function is used to get the result of drawing by clients.
8617 +static struct weston_surface *
8618 +ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf)
8620 + return ivisurf != NULL ? ivisurf->surface : NULL;
8624 +ivi_layout_surface_get_size(struct ivi_layout_surface *ivisurf,
8625 + int32_t *width, int32_t *height,
8630 + const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
8632 + if (ivisurf == NULL || ivisurf->surface == NULL) {
8633 + weston_log("%s: invalid argument\n", __func__);
8634 + return IVI_FAILED;
8637 + weston_surface_get_content_size(ivisurf->surface, &w, &h);
8639 + if (width != NULL)
8642 + if (height != NULL)
8645 + if (stride != NULL)
8646 + *stride = w * bytespp;
8648 + return IVI_SUCCEEDED;
8652 +ivi_layout_layer_add_notification(struct ivi_layout_layer *ivilayer,
8653 + layer_property_notification_func callback,
8656 + struct ivi_layout_notification_callback *prop_callback = NULL;
8658 + if (ivilayer == NULL || callback == NULL) {
8659 + weston_log("ivi_layout_layer_add_notification: invalid argument\n");
8660 + return IVI_FAILED;
8663 + prop_callback = malloc(sizeof *prop_callback);
8664 + if (prop_callback == NULL) {
8665 + weston_log("fails to allocate memory\n");
8666 + return IVI_FAILED;
8669 + prop_callback->callback = callback;
8670 + prop_callback->data = userdata;
8672 + return add_notification(&ivilayer->property_changed,
8673 + layer_prop_changed,
8677 +static const struct ivi_layout_surface_properties *
8678 +ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf)
8680 + if (ivisurf == NULL) {
8681 + weston_log("ivi_layout_get_properties_of_surface: invalid argument\n");
8685 + return &ivisurf->prop;
8689 +ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer,
8690 + struct ivi_layout_surface *addsurf)
8692 + struct ivi_layout *layout = get_instance();
8693 + struct ivi_layout_surface *ivisurf = NULL;
8694 + struct ivi_layout_surface *next = NULL;
8695 + int is_surf_in_layer = 0;
8697 + if (ivilayer == NULL || addsurf == NULL) {
8698 + weston_log("ivi_layout_layer_add_surface: invalid argument\n");
8699 + return IVI_FAILED;
8702 + is_surf_in_layer = is_surface_in_layer(addsurf, ivilayer);
8703 + if (is_surf_in_layer == 1) {
8704 + weston_log("ivi_layout_layer_add_surface: addsurf is already available\n");
8705 + return IVI_SUCCEEDED;
8708 + wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
8709 + if (ivisurf->id_surface == addsurf->id_surface) {
8710 + wl_list_remove(&ivisurf->pending.link);
8711 + wl_list_insert(&ivilayer->pending.surface_list,
8712 + &ivisurf->pending.link);
8717 + ivilayer->order.dirty = 1;
8719 + return IVI_SUCCEEDED;
8723 +ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer,
8724 + struct ivi_layout_surface *remsurf)
8726 + struct ivi_layout_surface *ivisurf = NULL;
8727 + struct ivi_layout_surface *next = NULL;
8729 + if (ivilayer == NULL || remsurf == NULL) {
8730 + weston_log("ivi_layout_layer_remove_surface: invalid argument\n");
8734 + wl_list_for_each_safe(ivisurf, next,
8735 + &ivilayer->pending.surface_list, pending.link) {
8736 + if (ivisurf->id_surface == remsurf->id_surface) {
8737 + wl_list_remove(&ivisurf->pending.link);
8738 + wl_list_init(&ivisurf->pending.link);
8743 + ivilayer->order.dirty = 1;
8747 +ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf,
8748 + int32_t x, int32_t y,
8749 + int32_t width, int32_t height)
8751 + struct ivi_layout_surface_properties *prop = NULL;
8753 + if (ivisurf == NULL) {
8754 + weston_log("ivi_layout_surface_set_source_rectangle: invalid argument\n");
8755 + return IVI_FAILED;
8758 + prop = &ivisurf->pending.prop;
8759 + prop->source_x = x;
8760 + prop->source_y = y;
8761 + prop->source_width = width;
8762 + prop->source_height = height;
8764 + if (ivisurf->prop.source_x != x || ivisurf->prop.source_y != y ||
8765 + ivisurf->prop.source_width != width ||
8766 + ivisurf->prop.source_height != height)
8767 + ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
8769 + ivisurf->event_mask &= ~IVI_NOTIFICATION_SOURCE_RECT;
8771 + return IVI_SUCCEEDED;
8775 +ivi_layout_commit_changes(void)
8777 + struct ivi_layout *layout = get_instance();
8779 + commit_surface_list(layout);
8780 + commit_layer_list(layout);
8781 + commit_screen_list(layout);
8783 + commit_transition(layout);
8785 + commit_changes(layout);
8786 + send_prop(layout);
8787 + weston_compositor_schedule_repaint(layout->compositor);
8789 + return IVI_SUCCEEDED;
8793 +ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer,
8794 + enum ivi_layout_transition_type type,
8795 + uint32_t duration)
8797 + if (ivilayer == NULL) {
8798 + weston_log("%s: invalid argument\n", __func__);
8802 + ivilayer->pending.prop.transition_type = type;
8803 + ivilayer->pending.prop.transition_duration = duration;
8809 +ivi_layout_layer_set_fade_info(struct ivi_layout_layer* ivilayer,
8810 + uint32_t is_fade_in,
8811 + double start_alpha, double end_alpha)
8813 + if (ivilayer == NULL) {
8814 + weston_log("%s: invalid argument\n", __func__);
8818 + ivilayer->pending.prop.is_fade_in = is_fade_in;
8819 + ivilayer->pending.prop.start_alpha = start_alpha;
8820 + ivilayer->pending.prop.end_alpha = end_alpha;
8826 +ivi_layout_surface_set_transition_duration(struct ivi_layout_surface *ivisurf,
8827 + uint32_t duration)
8829 + struct ivi_layout_surface_properties *prop;
8831 + if (ivisurf == NULL) {
8832 + weston_log("%s: invalid argument\n", __func__);
8836 + prop = &ivisurf->pending.prop;
8837 + prop->transition_duration = duration*10;
8842 +ivi_layout_surface_set_transition(struct ivi_layout_surface *ivisurf,
8843 + enum ivi_layout_transition_type type,
8844 + uint32_t duration)
8846 + struct ivi_layout_surface_properties *prop;
8848 + if (ivisurf == NULL) {
8849 + weston_log("%s: invalid argument\n", __func__);
8853 + prop = &ivisurf->pending.prop;
8854 + prop->transition_type = type;
8855 + prop->transition_duration = duration;
8860 +ivi_layout_surface_dump(struct weston_surface *surface,
8861 + void *target, size_t size,int32_t x, int32_t y,
8862 + int32_t width, int32_t height)
8866 + if (surface == NULL) {
8867 + weston_log("%s: invalid argument\n", __func__);
8868 + return IVI_FAILED;
8871 + result = weston_surface_copy_content(
8872 + surface, target, size,
8873 + x, y, width, height);
8875 + return result == 0 ? IVI_SUCCEEDED : IVI_FAILED;
8879 + * methods of interaction between ivi-shell with ivi-layout
8881 +struct weston_view *
8882 +ivi_layout_get_weston_view(struct ivi_layout_surface *surface)
8884 + struct weston_view *tmpview = NULL;
8886 + if (surface == NULL)
8889 + wl_list_for_each(tmpview, &surface->surface->views, surface_link)
8891 + if (tmpview != NULL) {
8899 +ivi_layout_surface_configure(struct ivi_layout_surface *ivisurf,
8900 + int32_t width, int32_t height)
8902 + struct ivi_layout *layout = get_instance();
8904 + /* emit callback which is set by ivi-layout api user */
8905 + wl_signal_emit(&layout->surface_notification.configure_changed,
8910 +ivi_layout_surface_set_content_observer(struct ivi_layout_surface *ivisurf,
8911 + ivi_controller_surface_content_callback callback,
8914 + int32_t ret = IVI_FAILED;
8916 + if (ivisurf != NULL) {
8917 + ivisurf->content_observer.callback = callback;
8918 + ivisurf->content_observer.userdata = userdata;
8919 + ret = IVI_SUCCEEDED;
8924 +struct ivi_layout_surface*
8925 +ivi_layout_surface_create(struct weston_surface *wl_surface,
8926 + uint32_t id_surface)
8928 + struct ivi_layout *layout = get_instance();
8929 + struct ivi_layout_surface *ivisurf = NULL;
8930 + struct weston_view *tmpview = NULL;
8932 + if (wl_surface == NULL) {
8933 + weston_log("ivi_layout_surface_create: invalid argument\n");
8937 + ivisurf = get_surface(&layout->surface_list, id_surface);
8938 + if (ivisurf != NULL) {
8939 + if (ivisurf->surface != NULL) {
8940 + weston_log("id_surface(%d) is already created\n", id_surface);
8945 + ivisurf = calloc(1, sizeof *ivisurf);
8946 + if (ivisurf == NULL) {
8947 + weston_log("fails to allocate memory\n");
8951 + wl_signal_init(&ivisurf->property_changed);
8952 + wl_signal_init(&ivisurf->configured);
8953 + wl_list_init(&ivisurf->layer_list);
8954 + ivisurf->id_surface = id_surface;
8955 + ivisurf->layout = layout;
8957 + ivisurf->surface = wl_surface;
8959 + tmpview = weston_view_create(wl_surface);
8960 + if (tmpview == NULL) {
8961 + weston_log("fails to allocate memory\n");
8964 + ivisurf->surface->width_from_buffer = 0;
8965 + ivisurf->surface->height_from_buffer = 0;
8967 + weston_matrix_init(&ivisurf->transform.matrix);
8968 + wl_list_init(&ivisurf->transform.link);
8970 + init_surface_properties(&ivisurf->prop);
8971 + ivisurf->event_mask = 0;
8973 + ivisurf->pending.prop = ivisurf->prop;
8974 + wl_list_init(&ivisurf->pending.link);
8976 + wl_list_init(&ivisurf->order.link);
8977 + wl_list_init(&ivisurf->order.layer_list);
8979 + wl_list_insert(&layout->surface_list, &ivisurf->link);
8981 + wl_signal_emit(&layout->surface_notification.created, ivisurf);
8987 +ivi_layout_init_with_compositor(struct weston_compositor *ec)
8989 + struct ivi_layout *layout = get_instance();
8991 + layout->compositor = ec;
8993 + wl_list_init(&layout->surface_list);
8994 + wl_list_init(&layout->layer_list);
8995 + wl_list_init(&layout->screen_list);
8997 + wl_signal_init(&layout->layer_notification.created);
8998 + wl_signal_init(&layout->layer_notification.removed);
9000 + wl_signal_init(&layout->surface_notification.created);
9001 + wl_signal_init(&layout->surface_notification.removed);
9002 + wl_signal_init(&layout->surface_notification.configure_changed);
9004 + /* Add layout_layer at the last of weston_compositor.layer_list */
9005 + weston_layer_init(&layout->layout_layer, ec->layer_list.prev);
9007 + create_screen(ec);
9009 + layout->transitions = ivi_layout_transition_set_create(ec);
9010 + wl_list_init(&layout->pending_transition_list);
9015 +ivi_layout_surface_add_configured_listener(struct ivi_layout_surface* ivisurf,
9016 + struct wl_listener* listener)
9018 + wl_signal_add(&ivisurf->configured, listener);
9021 +static struct ivi_controller_interface ivi_controller_interface = {
9023 + * commit all changes
9025 + .commit_changes = ivi_layout_commit_changes,
9028 + * surface controller interfaces
9030 + .add_notification_create_surface = ivi_layout_add_notification_create_surface,
9031 + .remove_notification_create_surface = ivi_layout_remove_notification_create_surface,
9032 + .add_notification_remove_surface = ivi_layout_add_notification_remove_surface,
9033 + .remove_notification_remove_surface = ivi_layout_remove_notification_remove_surface,
9034 + .add_notification_configure_surface = ivi_layout_add_notification_configure_surface,
9035 + .remove_notification_configure_surface = ivi_layout_remove_notification_configure_surface,
9036 + .get_surfaces = ivi_layout_get_surfaces,
9037 + .get_id_of_surface = ivi_layout_get_id_of_surface,
9038 + .get_surface_from_id = ivi_layout_get_surface_from_id,
9039 + .get_properties_of_surface = ivi_layout_get_properties_of_surface,
9040 + .get_surfaces_on_layer = ivi_layout_get_surfaces_on_layer,
9041 + .surface_set_visibility = ivi_layout_surface_set_visibility,
9042 + .surface_get_visibility = ivi_layout_surface_get_visibility,
9043 + .surface_set_opacity = ivi_layout_surface_set_opacity,
9044 + .surface_get_opacity = ivi_layout_surface_get_opacity,
9045 + .surface_set_source_rectangle = ivi_layout_surface_set_source_rectangle,
9046 + .surface_set_destination_rectangle = ivi_layout_surface_set_destination_rectangle,
9047 + .surface_set_position = ivi_layout_surface_set_position,
9048 + .surface_get_position = ivi_layout_surface_get_position,
9049 + .surface_set_dimension = ivi_layout_surface_set_dimension,
9050 + .surface_get_dimension = ivi_layout_surface_get_dimension,
9051 + .surface_set_orientation = ivi_layout_surface_set_orientation,
9052 + .surface_get_orientation = ivi_layout_surface_get_orientation,
9053 + .surface_set_content_observer = ivi_layout_surface_set_content_observer,
9054 + .surface_add_notification = ivi_layout_surface_add_notification,
9055 + .surface_remove_notification = ivi_layout_surface_remove_notification,
9056 + .surface_get_weston_surface = ivi_layout_surface_get_weston_surface,
9057 + .surface_set_transition = ivi_layout_surface_set_transition,
9058 + .surface_set_transition_duration = ivi_layout_surface_set_transition_duration,
9061 + * layer controller interfaces
9063 + .add_notification_create_layer = ivi_layout_add_notification_create_layer,
9064 + .remove_notification_create_layer = ivi_layout_remove_notification_create_layer,
9065 + .add_notification_remove_layer = ivi_layout_add_notification_remove_layer,
9066 + .remove_notification_remove_layer = ivi_layout_remove_notification_remove_layer,
9067 + .layer_create_with_dimension = ivi_layout_layer_create_with_dimension,
9068 + .layer_destroy = ivi_layout_layer_destroy,
9069 + .get_layers = ivi_layout_get_layers,
9070 + .get_id_of_layer = ivi_layout_get_id_of_layer,
9071 + .get_layer_from_id = ivi_layout_get_layer_from_id,
9072 + .get_properties_of_layer = ivi_layout_get_properties_of_layer,
9073 + .get_layers_under_surface = ivi_layout_get_layers_under_surface,
9074 + .get_layers_on_screen = ivi_layout_get_layers_on_screen,
9075 + .layer_set_visibility = ivi_layout_layer_set_visibility,
9076 + .layer_get_visibility = ivi_layout_layer_get_visibility,
9077 + .layer_set_opacity = ivi_layout_layer_set_opacity,
9078 + .layer_get_opacity = ivi_layout_layer_get_opacity,
9079 + .layer_set_source_rectangle = ivi_layout_layer_set_source_rectangle,
9080 + .layer_set_destination_rectangle = ivi_layout_layer_set_destination_rectangle,
9081 + .layer_set_position = ivi_layout_layer_set_position,
9082 + .layer_get_position = ivi_layout_layer_get_position,
9083 + .layer_set_dimension = ivi_layout_layer_set_dimension,
9084 + .layer_get_dimension = ivi_layout_layer_get_dimension,
9085 + .layer_set_orientation = ivi_layout_layer_set_orientation,
9086 + .layer_get_orientation = ivi_layout_layer_get_orientation,
9087 + .layer_add_surface = ivi_layout_layer_add_surface,
9088 + .layer_remove_surface = ivi_layout_layer_remove_surface,
9089 + .layer_set_render_order = ivi_layout_layer_set_render_order,
9090 + .layer_add_notification = ivi_layout_layer_add_notification,
9091 + .layer_remove_notification = ivi_layout_layer_remove_notification,
9092 + .layer_set_transition = ivi_layout_layer_set_transition,
9095 + * screen controller interfaces part1
9097 + .get_screen_from_id = ivi_layout_get_screen_from_id,
9098 + .get_screen_resolution = ivi_layout_get_screen_resolution,
9099 + .get_screens = ivi_layout_get_screens,
9100 + .get_screens_under_layer = ivi_layout_get_screens_under_layer,
9101 + .screen_add_layer = ivi_layout_screen_add_layer,
9102 + .screen_set_render_order = ivi_layout_screen_set_render_order,
9103 + .screen_get_output = ivi_layout_screen_get_output,
9108 + .transition_move_layer_cancel = ivi_layout_transition_move_layer_cancel,
9109 + .layer_set_fade_info = ivi_layout_layer_set_fade_info,
9112 + * surface content dumping for debugging
9114 + .surface_get_size = ivi_layout_surface_get_size,
9115 + .surface_dump = ivi_layout_surface_dump,
9118 + * remove notification by callback on property changes of ivi_surface/layer
9120 + .surface_remove_notification_by_callback = ivi_layout_surface_remove_notification_by_callback,
9121 + .layer_remove_notification_by_callback = ivi_layout_layer_remove_notification_by_callback,
9124 + * screen controller interfaces part2
9126 + .get_id_of_screen = ivi_layout_get_id_of_screen
9130 +load_controller_modules(struct weston_compositor *compositor, const char *modules,
9131 + int *argc, char *argv[])
9133 + const char *p, *end;
9135 + int (*controller_module_init)(struct weston_compositor *compositor,
9136 + int *argc, char *argv[],
9137 + const struct ivi_controller_interface *interface,
9138 + size_t interface_version);
9140 + if (modules == NULL)
9145 + end = strchrnul(p, ',');
9146 + snprintf(buffer, sizeof buffer, "%.*s", (int)(end - p), p);
9148 + controller_module_init = weston_load_module(buffer, "controller_module_init");
9149 + if (!controller_module_init)
9152 + if (controller_module_init(compositor, argc, argv,
9153 + &ivi_controller_interface,
9154 + sizeof(struct ivi_controller_interface)) != 0) {
9155 + weston_log("ivi-shell: Initialization of controller module fails");
9166 diff --git a/ivi-shell/ivi-shell.c b/ivi-shell/ivi-shell.c
9167 new file mode 100644
9168 index 0000000..220a508
9170 +++ b/ivi-shell/ivi-shell.c
9173 + * Copyright (C) 2013 DENSO CORPORATION
9175 + * Permission is hereby granted, free of charge, to any person obtaining
9176 + * a copy of this software and associated documentation files (the
9177 + * "Software"), to deal in the Software without restriction, including
9178 + * without limitation the rights to use, copy, modify, merge, publish,
9179 + * distribute, sublicense, and/or sell copies of the Software, and to
9180 + * permit persons to whom the Software is furnished to do so, subject to
9181 + * the following conditions:
9183 + * The above copyright notice and this permission notice (including the
9184 + * next paragraph) shall be included in all copies or substantial
9185 + * portions of the Software.
9187 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9188 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
9189 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
9190 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
9191 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
9192 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
9193 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
9198 + * ivi-shell supports a type of shell for In-Vehicle Infotainment system.
9199 + * In-Vehicle Infotainment system traditionally manages surfaces with global
9200 + * identification. A protocol, ivi_application, supports such a feature
9201 + * by implementing a request, ivi_application::surface_creation defined in
9202 + * ivi_application.xml.
9204 + * The ivi-shell explicitly loads a module to add business logic like how to
9205 + * layout surfaces by using internal ivi-layout APIs.
9207 +#include "config.h"
9209 +#include <string.h>
9211 +#include <limits.h>
9212 +#include <assert.h>
9213 +#include <linux/input.h>
9215 +#include "ivi-shell.h"
9216 +#include "ivi-application-server-protocol.h"
9217 +#include "ivi-layout-export.h"
9218 +#include "ivi-layout-private.h"
9219 +#include "shared/helpers.h"
9221 +/* Representation of ivi_surface protocol object. */
9222 +struct ivi_shell_surface
9224 + struct wl_resource* resource;
9225 + struct ivi_shell *shell;
9226 + struct ivi_layout_surface *layout_surface;
9228 + struct weston_surface *surface;
9229 + struct wl_listener surface_destroy_listener;
9231 + uint32_t id_surface;
9236 + struct wl_list link;
9238 + struct wl_listener configured_listener;
9241 +struct ivi_shell_setting
9244 + int developermode;
9248 + * Implementation of ivi_surface
9252 +surface_configure_notify(struct wl_listener *listener, void *data)
9254 + struct ivi_layout_surface *layout_surf =
9255 + (struct ivi_layout_surface *)data;
9257 + struct ivi_shell_surface *shell_surf =
9258 + container_of(listener,
9259 + struct ivi_shell_surface,
9260 + configured_listener);
9262 + int32_t dest_width = 0;
9263 + int32_t dest_height = 0;
9265 + ivi_layout_surface_get_dimension(layout_surf,
9266 + &dest_width, &dest_height);
9268 + if (shell_surf->resource)
9269 + ivi_surface_send_configure(shell_surf->resource,
9270 + dest_width, dest_height);
9274 +ivi_shell_surface_configure(struct weston_surface *, int32_t, int32_t);
9276 +static struct ivi_shell_surface *
9277 +get_ivi_shell_surface(struct weston_surface *surface)
9279 + if (surface->configure == ivi_shell_surface_configure)
9280 + return surface->configure_private;
9286 +ivi_shell_surface_configure(struct weston_surface *surface,
9287 + int32_t sx, int32_t sy)
9289 + struct ivi_shell_surface *ivisurf = get_ivi_shell_surface(surface);
9291 + if (surface->width == 0 || surface->height == 0 || ivisurf == NULL)
9294 + if (ivisurf->width != surface->width ||
9295 + ivisurf->height != surface->height) {
9296 + ivisurf->width = surface->width;
9297 + ivisurf->height = surface->height;
9299 + ivi_layout_surface_configure(ivisurf->layout_surface,
9300 + surface->width, surface->height);
9305 +layout_surface_cleanup(struct ivi_shell_surface *ivisurf)
9307 + assert(ivisurf->layout_surface != NULL);
9309 + ivi_layout_surface_destroy(ivisurf->layout_surface);
9310 + ivisurf->layout_surface = NULL;
9312 + ivisurf->surface->configure = NULL;
9313 + ivisurf->surface->configure_private = NULL;
9314 + ivisurf->surface = NULL;
9316 + // destroy weston_surface destroy signal.
9317 + wl_list_remove(&ivisurf->surface_destroy_listener.link);
9321 + * The ivi_surface wl_resource destructor.
9323 + * Gets called via ivi_surface.destroy request or automatic wl_client clean-up.
9326 +shell_destroy_shell_surface(struct wl_resource *resource)
9328 + struct ivi_shell_surface *ivisurf = wl_resource_get_user_data(resource);
9330 + if (ivisurf == NULL)
9333 + assert(ivisurf->resource == resource);
9335 + if (ivisurf->layout_surface != NULL)
9336 + layout_surface_cleanup(ivisurf);
9338 + wl_list_remove(&ivisurf->link);
9343 +/* Gets called through the weston_surface destroy signal. */
9345 +shell_handle_surface_destroy(struct wl_listener *listener, void *data)
9347 + struct ivi_shell_surface *ivisurf =
9348 + container_of(listener, struct ivi_shell_surface,
9349 + surface_destroy_listener);
9351 + assert(ivisurf != NULL);
9353 + if (ivisurf->layout_surface != NULL)
9354 + layout_surface_cleanup(ivisurf);
9357 +/* Gets called, when a client sends ivi_surface.destroy request. */
9359 +surface_destroy(struct wl_client *client, struct wl_resource *resource)
9362 + * Fires the wl_resource destroy signal, and then calls
9363 + * ivi_surface wl_resource destructor: shell_destroy_shell_surface()
9365 + wl_resource_destroy(resource);
9368 +static const struct ivi_surface_interface surface_implementation = {
9373 + * Request handler for ivi_application.surface_create.
9375 + * Creates an ivi_surface protocol object associated with the given wl_surface.
9376 + * ivi_surface protocol object is represented by struct ivi_shell_surface.
9378 + * \param client The client.
9379 + * \param resource The ivi_application protocol object.
9380 + * \param id_surface The IVI surface ID.
9381 + * \param surface_resource The wl_surface protocol object.
9382 + * \param id The protocol object id for the new ivi_surface protocol object.
9384 + * The wl_surface is given the ivi_surface role and associated with a unique
9385 + * IVI ID which is used to identify the surface in a controller
9386 + * (window manager).
9389 +application_surface_create(struct wl_client *client,
9390 + struct wl_resource *resource,
9391 + uint32_t id_surface,
9392 + struct wl_resource *surface_resource,
9395 + struct ivi_shell *shell = wl_resource_get_user_data(resource);
9396 + struct ivi_shell_surface *ivisurf;
9397 + struct ivi_layout_surface *layout_surface;
9398 + struct weston_surface *weston_surface =
9399 + wl_resource_get_user_data(surface_resource);
9400 + struct wl_resource *res;
9402 + /* check if a surface already has another role */
9403 + if (weston_surface->configure) {
9404 + wl_resource_post_error(weston_surface->resource,
9405 + WL_DISPLAY_ERROR_INVALID_OBJECT,
9406 + "surface->configure already "
9411 + layout_surface = ivi_layout_surface_create(weston_surface, id_surface);
9413 + /* check if id_ivi is already used for wl_surface*/
9414 + if (layout_surface == NULL) {
9415 + wl_resource_post_error(resource,
9416 + IVI_APPLICATION_ERROR_IVI_ID,
9417 + "surface_id is already assigned "
9418 + "by another app");
9422 + ivisurf = zalloc(sizeof *ivisurf);
9423 + if (ivisurf == NULL) {
9424 + wl_resource_post_no_memory(resource);
9428 + wl_list_init(&ivisurf->link);
9429 + wl_list_insert(&shell->ivi_surface_list, &ivisurf->link);
9431 + ivisurf->shell = shell;
9432 + ivisurf->id_surface = id_surface;
9434 + ivisurf->width = 0;
9435 + ivisurf->height = 0;
9436 + ivisurf->layout_surface = layout_surface;
9437 + ivisurf->configured_listener.notify = surface_configure_notify;
9438 + ivi_layout_surface_add_configured_listener(layout_surface,
9439 + &ivisurf->configured_listener);
9441 + * The following code relies on wl_surface destruction triggering
9442 + * immediateweston_surface destruction
9444 + ivisurf->surface_destroy_listener.notify = shell_handle_surface_destroy;
9445 + wl_signal_add(&weston_surface->destroy_signal,
9446 + &ivisurf->surface_destroy_listener);
9448 + ivisurf->surface = weston_surface;
9450 + weston_surface->configure = ivi_shell_surface_configure;
9451 + weston_surface->configure_private = ivisurf;
9453 + res = wl_resource_create(client, &ivi_surface_interface, 1, id);
9454 + if (res == NULL) {
9455 + wl_client_post_no_memory(client);
9459 + ivisurf->resource = res;
9461 + wl_resource_set_implementation(res, &surface_implementation,
9462 + ivisurf, shell_destroy_shell_surface);
9465 +static const struct ivi_application_interface application_implementation = {
9466 + application_surface_create
9470 + * Handle wl_registry.bind of ivi_application global singleton.
9473 +bind_ivi_application(struct wl_client *client,
9474 + void *data, uint32_t version, uint32_t id)
9476 + struct ivi_shell *shell = data;
9477 + struct wl_resource *resource;
9479 + resource = wl_resource_create(client, &ivi_application_interface,
9482 + wl_resource_set_implementation(resource,
9483 + &application_implementation,
9487 +struct weston_view *
9488 +get_default_view(struct weston_surface *surface)
9490 + struct ivi_shell_surface *shsurf;
9491 + struct weston_view *view;
9493 + if (!surface || wl_list_empty(&surface->views))
9496 + shsurf = get_ivi_shell_surface(surface);
9497 + if (shsurf && shsurf->layout_surface) {
9498 + view = ivi_layout_get_weston_view(shsurf->layout_surface);
9503 + wl_list_for_each(view, &surface->views, surface_link) {
9504 + if (weston_view_is_mapped(view))
9508 + return container_of(surface->views.next,
9509 + struct weston_view, surface_link);
9513 + * Called through the compositor's destroy signal.
9516 +shell_destroy(struct wl_listener *listener, void *data)
9518 + struct ivi_shell *shell =
9519 + container_of(listener, struct ivi_shell, destroy_listener);
9520 + struct ivi_shell_surface *ivisurf, *next;
9522 + input_panel_destroy(shell);
9524 + wl_list_for_each_safe(ivisurf, next, &shell->ivi_surface_list, link) {
9525 + wl_list_remove(&ivisurf->link);
9533 +terminate_binding(struct weston_seat *seat, uint32_t time,
9534 + uint32_t key, void *data)
9536 + struct weston_compositor *compositor = data;
9538 + wl_display_terminate(compositor->wl_display);
9542 +init_ivi_shell(struct weston_compositor *compositor, struct ivi_shell *shell,
9543 + const struct ivi_shell_setting *setting)
9545 + shell->compositor = compositor;
9547 + wl_list_init(&shell->ivi_surface_list);
9549 + weston_layer_init(&shell->input_panel_layer, NULL);
9551 + if (setting->developermode) {
9553 + weston_install_debug_key_binding(compositor, MODIFIER_SUPER);
9556 + weston_compositor_add_key_binding(compositor, KEY_BACKSPACE,
9557 + MODIFIER_CTRL | MODIFIER_ALT,
9558 + terminate_binding,
9564 +ivi_shell_setting_create(struct ivi_shell_setting *dest,
9565 + struct weston_compositor *compositor,
9566 + int *argc, char *argv[])
9569 + struct weston_config *config = compositor->config;
9570 + struct weston_config_section *section;
9572 + const struct weston_option ivi_shell_options[] = {
9573 + { WESTON_OPTION_STRING, "ivi-module", 0, &dest->ivi_module },
9576 + parse_options(ivi_shell_options, ARRAY_LENGTH(ivi_shell_options),
9579 + section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
9581 + if (!dest->ivi_module &&
9582 + weston_config_section_get_string(section, "ivi-module",
9583 + &dest->ivi_module, NULL) < 0) {
9584 + weston_log("Error: ivi-shell: No ivi-module set\n");
9588 + weston_config_section_get_bool(section, "developermode",
9589 + &dest->developermode, 0);
9595 + * Initialization of ivi-shell.
9598 +module_init(struct weston_compositor *compositor,
9599 + int *argc, char *argv[])
9601 + struct ivi_shell *shell;
9602 + struct ivi_shell_setting setting = { };
9605 + shell = zalloc(sizeof *shell);
9606 + if (shell == NULL)
9609 + if (ivi_shell_setting_create(&setting, compositor, argc, argv) != 0)
9612 + init_ivi_shell(compositor, shell, &setting);
9614 + shell->destroy_listener.notify = shell_destroy;
9615 + wl_signal_add(&compositor->destroy_signal, &shell->destroy_listener);
9617 + if (input_panel_setup(shell) < 0)
9618 + goto out_settings;
9620 + text_backend_init(compositor);
9622 + if (wl_global_create(compositor->wl_display,
9623 + &ivi_application_interface, 1,
9624 + shell, bind_ivi_application) == NULL)
9625 + goto out_settings;
9627 + ivi_layout_init_with_compositor(compositor);
9629 + /* Call module_init of ivi-modules which are defined in weston.ini */
9630 + if (load_controller_modules(compositor, setting.ivi_module,
9632 + goto out_settings;
9637 + free(setting.ivi_module);
9641 diff --git a/ivi-shell/ivi-shell.h b/ivi-shell/ivi-shell.h
9642 new file mode 100644
9643 index 0000000..9a05eb2
9645 +++ b/ivi-shell/ivi-shell.h
9648 + * Copyright (C) 2013 DENSO CORPORATION
9650 + * Permission is hereby granted, free of charge, to any person obtaining
9651 + * a copy of this software and associated documentation files (the
9652 + * "Software"), to deal in the Software without restriction, including
9653 + * without limitation the rights to use, copy, modify, merge, publish,
9654 + * distribute, sublicense, and/or sell copies of the Software, and to
9655 + * permit persons to whom the Software is furnished to do so, subject to
9656 + * the following conditions:
9658 + * The above copyright notice and this permission notice (including the
9659 + * next paragraph) shall be included in all copies or substantial
9660 + * portions of the Software.
9662 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9663 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
9664 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
9665 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
9666 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
9667 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
9668 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
9672 +#include <stdbool.h>
9674 +#include "compositor.h"
9678 + struct wl_listener destroy_listener;
9680 + struct weston_compositor *compositor;
9682 + struct wl_list ivi_surface_list; /* struct ivi_shell_surface::link */
9684 + struct text_backend *text_backend;
9686 + struct wl_listener show_input_panel_listener;
9687 + struct wl_listener hide_input_panel_listener;
9688 + struct wl_listener update_input_panel_listener;
9690 + struct weston_layer input_panel_layer;
9693 + bool showing_input_panels;
9696 + struct weston_surface *surface;
9697 + pixman_box32_t cursor_rectangle;
9701 + struct wl_resource *binding;
9702 + struct wl_list surfaces;
9706 +struct weston_view *
9707 +get_default_view(struct weston_surface *surface);
9710 +input_panel_setup(struct ivi_shell *shell);
9713 +input_panel_destroy(struct ivi_shell *shell);
9714 diff --git a/ivi-shell/weston.ini.in b/ivi-shell/weston.ini.in
9715 new file mode 100644
9716 index 0000000..6c22633
9718 +++ b/ivi-shell/weston.ini.in
9721 +shell=@plugin_prefix@ivi-shell.so
9724 +ivi-module=@plugin_prefix@hmi-controller.so
9725 +ivi-shell-user-interface=@abs_top_builddir@/weston-ivi-shell-user-interface
9727 +#developermode=true
9729 +cursor-theme=default
9733 +workspace-background-layer-id=2000
9734 +workspace-layer-id=3000
9735 +application-layer-id=4000
9737 +transition-duration=300
9739 +background-image=@abs_top_srcdir@/data/background.png
9741 +panel-image=@abs_top_srcdir@/data/panel.png
9743 +tiling-image=@abs_top_srcdir@/data/tiling.png
9745 +sidebyside-image=@abs_top_srcdir@/data/sidebyside.png
9747 +fullscreen-image=@abs_top_srcdir@/data/fullscreen.png
9749 +random-image=@abs_top_srcdir@/data/random.png
9751 +home-image=@abs_top_srcdir@/data/home.png
9753 +workspace-background-color=0x99000000
9754 +workspace-background-id=2001
9757 +path=@libexecdir@/weston-keyboard
9762 +icon=@abs_top_srcdir@/data/icon_ivi_flower.png
9763 +path=@abs_top_builddir@/weston-flower
9768 +icon=@abs_top_srcdir@/data/icon_ivi_clickdot.png
9769 +path=@abs_top_builddir@/weston-clickdot
9774 +icon=@abs_top_srcdir@/data/icon_ivi_simple-egl.png
9775 +path=@abs_top_builddir@/weston-simple-egl
9780 +icon=@abs_top_srcdir@/data/icon_ivi_simple-shm.png
9781 +path=@abs_top_builddir@/weston-simple-shm
9786 +icon=@abs_top_srcdir@/data/icon_ivi_smoke.png
9787 +path=@abs_top_builddir@/weston-smoke
9792 +icon=@abs_top_srcdir@/data/icon_ivi_flower.png
9793 +path=@abs_top_builddir@/weston-flower
9798 +icon=@abs_top_srcdir@/data/icon_ivi_clickdot.png
9799 +path=@abs_top_builddir@/weston-clickdot
9804 +icon=@abs_top_srcdir@/data/icon_ivi_simple-egl.png
9805 +path=@abs_top_builddir@/weston-simple-egl
9810 +icon=@abs_top_srcdir@/data/icon_ivi_simple-shm.png
9811 +path=@abs_top_builddir@/weston-simple-shm
9816 +icon=@abs_top_srcdir@/data/icon_ivi_smoke.png
9817 +path=@abs_top_builddir@/weston-smoke
9818 diff --git a/protocol/ivi-application.xml b/protocol/ivi-application.xml
9819 new file mode 100644
9820 index 0000000..8f24226
9822 +++ b/protocol/ivi-application.xml
9824 +<?xml version="1.0" encoding="UTF-8"?>
9825 +<protocol name="ivi_application">
9828 + Copyright (C) 2013 DENSO CORPORATION
9829 + Copyright (c) 2013 BMW Car IT GmbH
9831 + Permission is hereby granted, free of charge, to any person obtaining a
9832 + copy of this software and associated documentation files (the "Software"),
9833 + to deal in the Software without restriction, including without limitation
9834 + the rights to use, copy, modify, merge, publish, distribute, sublicense,
9835 + and/or sell copies of the Software, and to permit persons to whom the
9836 + Software is furnished to do so, subject to the following conditions:
9838 + The above copyright notice and this permission notice (including the next
9839 + paragraph) shall be included in all copies or substantial portions of the
9842 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9843 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9844 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
9845 + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9846 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
9847 + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
9848 + DEALINGS IN THE SOFTWARE.
9851 + <interface name="ivi_surface" version="1">
9852 + <description summary="application interface to surface in ivi compositor"/>
9854 + <request name="destroy" type="destructor">
9855 + <description summary="destroy ivi_surface">
9856 + This removes link from ivi_id to wl_surface and destroys ivi_surface.
9857 + The ID, ivi_id, is free and can be used for surface_create again.
9861 + <event name="configure">
9862 + <description summary="suggest resize">
9863 + The configure event asks the client to resize its surface.
9865 + The size is a hint, in the sense that the client is free to
9866 + ignore it if it doesn't resize, pick a smaller size (to
9867 + satisfy aspect ratio or resize in steps of NxM pixels).
9869 + The client is free to dismiss all but the last configure
9870 + event it received.
9872 + The width and height arguments specify the size of the window
9873 + in surface local coordinates.
9875 + <arg name="width" type="int"/>
9876 + <arg name="height" type="int"/>
9880 + <interface name="ivi_application" version="1">
9881 + <description summary="create ivi-style surfaces">
9882 + This interface is exposed as a global singleton.
9883 + This interface is implemented by servers that provide IVI-style user interfaces.
9884 + It allows clients to associate a ivi_surface with wl_surface.
9887 + <enum name="error">
9888 + <entry name="role" value="0" summary="given wl_surface has another role"/>
9889 + <entry name="ivi_id" value="1" summary="given ivi_id is assigned to another wl_surface"/>
9892 + <request name="surface_create">
9893 + <description summary="create ivi_surface with numeric ID in ivi compositor">
9894 + This request gives the wl_surface the role of an IVI Surface. Creating more than
9895 + one ivi_surface for a wl_surface is not allowed. Note, that this still allows the
9896 + following example:
9898 + 1. create a wl_surface
9899 + 2. create ivi_surface for the wl_surface
9900 + 3. destroy the ivi_surface
9901 + 4. create ivi_surface for the wl_surface (with the same or another ivi_id as before)
9903 + surface_create will create a interface:ivi_surface with numeric ID; ivi_id in
9904 + ivi compositor. These ivi_ids are defined as unique in the system to identify
9905 + it inside of ivi compositor. The ivi compositor implements business logic how to
9906 + set properties of the surface with ivi_id according to status of the system.
9907 + E.g. a unique ID for Car Navigation application is used for implementing special
9908 + logic of the application about where it shall be located.
9909 + The server regards following cases as protocol errors and disconnects the client.
9910 + - wl_surface already has an nother role.
9911 + - ivi_id is already assigned to an another wl_surface.
9913 + If client destroys ivi_surface or wl_surface which is assigne to the ivi_surface,
9914 + ivi_id which is assigned to the ivi_surface is free for reuse.
9916 + <arg name="ivi_id" type="uint"/>
9917 + <arg name="surface" type="object" interface="wl_surface"/>
9918 + <arg name="id" type="new_id" interface="ivi_surface"/>
9924 diff --git a/protocol/ivi-hmi-controller.xml b/protocol/ivi-hmi-controller.xml
9925 new file mode 100644
9926 index 0000000..826763c
9928 +++ b/protocol/ivi-hmi-controller.xml
9930 +<?xml version="1.0" encoding="UTF-8"?>
9931 +<protocol name="ivi_hmi_controller">
9934 + Copyright (C) 2013 DENSO CORPORATION
9935 + Copyright (c) 2013 BMW Car IT GmbH
9937 + Permission is hereby granted, free of charge, to any person obtaining a
9938 + copy of this software and associated documentation files (the "Software"),
9939 + to deal in the Software without restriction, including without limitation
9940 + the rights to use, copy, modify, merge, publish, distribute, sublicense,
9941 + and/or sell copies of the Software, and to permit persons to whom the
9942 + Software is furnished to do so, subject to the following conditions:
9944 + The above copyright notice and this permission notice (including the next
9945 + paragraph) shall be included in all copies or substantial portions of the
9948 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9949 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9950 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
9951 + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9952 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
9953 + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
9954 + DEALINGS IN THE SOFTWARE.
9957 + <interface name="ivi_hmi_controller" version="1">
9958 + <description summary="set up and control IVI style UI"/>
9960 + <request name="UI_ready">
9961 + <description summary="inform the ready for drawing desktop." />
9964 + <request name="workspace_control">
9965 + <description summary="start controlling a surface by server">
9966 + Reference protocol to control a surface by server.
9967 + To control a surface by server, it gives seat to the server
9968 + to e.g. control Home screen. Home screen has several workspaces
9969 + to group launchers of wayland application. These workspaces
9970 + are drawn on a horizontally long surface to be controlled
9971 + by motion of input device. E.g. A motion from right to left
9972 + happens, the viewport of surface is controlled in the ivi-shell
9973 + by using ivi-layout. client can recognizes the end of controlling
9974 + by event "workspace_end_control".
9976 + <arg name="seat" type="object" interface="wl_seat"/>
9977 + <arg name="serial" type="uint"/>
9980 + <enum name="layout_mode">
9981 + <entry name="tiling" value="0"/>
9982 + <entry name="side_by_side" value="1"/>
9983 + <entry name="full_screen" value="2"/>
9984 + <entry name="random" value="3" />
9987 + <request name="switch_mode">
9988 + <description summary="request mode switch of application layout">
9989 + hmi-controller loaded to ivi-shall implements 4 types of layout
9990 + as a reference; tiling, side by side, full_screen, and random.
9992 + <arg name="layout_mode" type="uint"/>
9995 + <enum name="home">
9996 + <entry name="off" value="0"/>
9997 + <entry name="on" value="1"/>
10000 + <request name="home">
10001 + <description summary="request displaying/undisplaying home screen">
10002 + home screen is a reference implementation of launcher to launch
10003 + wayland applications. The home screen has several workspaces to
10004 + group wayland applications. By defining the following keys in
10005 + weston.ini, user can add launcher icon to launch a wayland application
10009 + : id of workspace to add a launcher
10011 + : ivi id of ivi_surface to draw a icon
10012 + icon=/home/user/review/build-ivi-shell/data/icon_ivi_flower.png
10013 + : path to icon image
10014 + path=/home/user/review/build-ivi-shell/weston-dnd
10015 + : path to wayland application
10017 + <arg name="home" type="uint"/>
10020 + <event name="workspace_end_control">
10021 + <description summary="notify controlling workspace end"/>
10022 + <arg name="is_controlled" type="int"/>
10028 diff --git a/shared/helpers.h b/shared/helpers.h
10029 new file mode 100644
10030 index 0000000..1d1e458
10032 +++ b/shared/helpers.h
10035 + * Copyright © 2015 Samsung Electronics Co., Ltd
10037 + * Permission is hereby granted, free of charge, to any person obtaining
10038 + * a copy of this software and associated documentation files (the
10039 + * "Software"), to deal in the Software without restriction, including
10040 + * without limitation the rights to use, copy, modify, merge, publish,
10041 + * distribute, sublicense, and/or sell copies of the Software, and to
10042 + * permit persons to whom the Software is furnished to do so, subject to
10043 + * the following conditions:
10045 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10046 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10047 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
10048 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
10049 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
10050 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
10051 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
10055 +#ifndef WESTON_HELPERS_H
10056 +#define WESTON_HELPERS_H
10058 +#ifdef __cplusplus
10064 + * Simple misc helper macros.
10068 + * Compile-time computation of number of items in a hardcoded array.
10070 + * @param a the array being measured.
10071 + * @return the number of items hardcoded into the array.
10073 +#ifndef ARRAY_LENGTH
10074 +#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
10078 + * Returns the smaller of two values.
10080 + * @param x the first item to compare.
10081 + * @param y the second item to compare.
10082 + * @return the value that evaluates to lesser than the other.
10085 +#define MIN(x,y) (((x) < (y)) ? (x) : (y))
10089 + * Returns a pointer the the containing struct of a given member item.
10091 + * To demonstrate, the following example retrieves a pointer to
10092 + * `example_container` given only its `destroy_listener` member:
10095 + * struct example_container {
10096 + * struct wl_listener destroy_listener;
10097 + * // other members...
10100 + * void example_container_destroy(struct wl_listener *listener, void *data)
10102 + * struct example_container *ctr;
10104 + * ctr = wl_container_of(listener, ctr, destroy_listener);
10105 + * // destroy ctr...
10109 + * @param ptr A valid pointer to the contained item.
10111 + * @param type A pointer to the type of content that the list item
10112 + * stores. Type does not need be a valid pointer; a null or
10113 + * an uninitialised pointer will suffice.
10115 + * @param member The named location of ptr within the sample type.
10117 + * @return The container for the specified pointer.
10119 +#ifndef container_of
10120 +#define container_of(ptr, type, member) ({ \
10121 + const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
10122 + (type *)( (char *)__mptr - offsetof(type,member) );})
10125 +#ifdef __cplusplus
10129 +#endif /* WESTON_HELPERS_H */
10130 diff --git a/src/compositor.c b/src/compositor.c
10131 index 574db2d..e9c46a4 100644
10132 --- a/src/compositor.c
10133 +++ b/src/compositor.c
10134 @@ -2503,6 +2503,54 @@ weston_surface_get_main_surface(struct weston_surface *surface)
10138 +/** Get the size of surface contents */
10140 +weston_surface_get_content_size(struct weston_surface *surface,
10141 + int *width, int *height)
10143 + struct weston_renderer *rer = surface->compositor->renderer;
10145 + if (!rer->surface_get_content_size) {
10151 + rer->surface_get_content_size(surface, width, height);
10154 +/** Copy surface contents to system memory */
10156 +weston_surface_copy_content(struct weston_surface *surface,
10157 + void *target, size_t size,
10158 + int src_x, int src_y,
10159 + int width, int height)
10161 + struct weston_renderer *rer = surface->compositor->renderer;
10163 + const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
10165 + if (!rer->surface_copy_content)
10168 + weston_surface_get_content_size(surface, &cw, &ch);
10170 + if (src_x < 0 || src_y < 0)
10173 + if (width <= 0 || height <= 0)
10176 + if (src_x + width > cw || src_y + height > ch)
10179 + if (width * bytespp * height > size)
10182 + return rer->surface_copy_content(surface, target, size,
10183 + src_x, src_y, width, height);
10187 subsurface_set_position(struct wl_client *client,
10188 struct wl_resource *resource, int32_t x, int32_t y)
10189 diff --git a/src/compositor.h b/src/compositor.h
10190 index 057f8be..2a8da6b 100644
10191 --- a/src/compositor.h
10192 +++ b/src/compositor.h
10193 @@ -552,6 +552,16 @@ struct weston_renderer {
10194 float red, float green,
10195 float blue, float alpha);
10196 void (*destroy)(struct weston_compositor *ec);
10198 + /** See weston_surface_get_content_size() */
10199 + void (*surface_get_content_size)(struct weston_surface *surface,
10200 + int *width, int *height);
10202 + /** See weston_surface__copy_content() */
10203 + int (*surface_copy_content)(struct weston_surface *surface,
10204 + void *target, size_t size,
10205 + int src_x, int src_y,
10206 + int width, int height);
10209 enum weston_capability {
10210 @@ -1205,6 +1215,16 @@ weston_surface_unmap(struct weston_surface *surface);
10211 struct weston_surface *
10212 weston_surface_get_main_surface(struct weston_surface *surface);
10215 +weston_surface_get_content_size(struct weston_surface *surface,
10216 + int *width, int *height);
10219 +weston_surface_copy_content(struct weston_surface *surface,
10220 + void *target, size_t size,
10221 + int src_x, int src_y,
10222 + int width, int height);
10224 struct weston_buffer *
10225 weston_buffer_from_resource(struct wl_resource *resource);
10227 diff --git a/src/gl-renderer.c b/src/gl-renderer.c
10228 index 63af75d..55b612c 100644
10229 --- a/src/gl-renderer.c
10230 +++ b/src/gl-renderer.c
10231 @@ -77,6 +77,7 @@ struct gl_output_state {
10235 + BUFFER_TYPE_SOLID, /* internal solid color surfaces without a buffer */
10239 @@ -1297,11 +1298,157 @@ gl_renderer_surface_set_color(struct weston_surface *surface,
10240 gs->color[1] = green;
10241 gs->color[2] = blue;
10242 gs->color[3] = alpha;
10243 + gs->buffer_type = BUFFER_TYPE_SOLID;
10245 gs->shader = &gr->solid_shader;
10249 +gl_renderer_surface_get_content_size(struct weston_surface *surface,
10250 + int *width, int *height)
10252 + struct gl_surface_state *gs = get_surface_state(surface);
10254 + if (gs->buffer_type == BUFFER_TYPE_NULL) {
10258 + *width = gs->pitch;
10259 + *height = gs->height;
10264 +pack_color(pixman_format_code_t format, float *c)
10266 + uint8_t r = round(c[0] * 255.0f);
10267 + uint8_t g = round(c[1] * 255.0f);
10268 + uint8_t b = round(c[2] * 255.0f);
10269 + uint8_t a = round(c[3] * 255.0f);
10271 + switch (format) {
10272 + case PIXMAN_a8b8g8r8:
10273 + return (a << 24) | (b << 16) | (g << 8) | r;
10281 +gl_renderer_surface_copy_content(struct weston_surface *surface,
10282 + void *target, size_t size,
10283 + int src_x, int src_y,
10284 + int width, int height)
10286 + static const GLfloat verts[4 * 2] = {
10292 + static const GLfloat projmat_normal[16] = { /* transpose */
10293 + 2.0f, 0.0f, 0.0f, 0.0f,
10294 + 0.0f, 2.0f, 0.0f, 0.0f,
10295 + 0.0f, 0.0f, 1.0f, 0.0f,
10296 + -1.0f, -1.0f, 0.0f, 1.0f
10298 + static const GLfloat projmat_yinvert[16] = { /* transpose */
10299 + 2.0f, 0.0f, 0.0f, 0.0f,
10300 + 0.0f, -2.0f, 0.0f, 0.0f,
10301 + 0.0f, 0.0f, 1.0f, 0.0f,
10302 + -1.0f, 1.0f, 0.0f, 1.0f
10304 + const pixman_format_code_t format = PIXMAN_a8b8g8r8;
10305 + const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
10306 + const GLenum gl_format = GL_RGBA; /* PIXMAN_a8b8g8r8 little-endian */
10307 + struct gl_renderer *gr = get_renderer(surface->compositor);
10308 + struct gl_surface_state *gs = get_surface_state(surface);
10313 + const GLfloat *proj;
10316 + gl_renderer_surface_get_content_size(surface, &cw, &ch);
10318 + switch (gs->buffer_type) {
10319 + case BUFFER_TYPE_NULL:
10321 + case BUFFER_TYPE_SOLID:
10322 + *(uint32_t *)target = pack_color(format, gs->color);
10324 + case BUFFER_TYPE_SHM:
10325 + gl_renderer_flush_damage(surface);
10326 + /* fall through */
10327 + case BUFFER_TYPE_EGL:
10331 + glGenTextures(1, &tex);
10332 + glBindTexture(GL_TEXTURE_2D, tex);
10333 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cw, ch,
10334 + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
10335 + glBindTexture(GL_TEXTURE_2D, 0);
10337 + glGenFramebuffers(1, &fbo);
10338 + glBindFramebuffer(GL_FRAMEBUFFER, fbo);
10339 + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
10340 + GL_TEXTURE_2D, tex, 0);
10342 + status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
10343 + if (status != GL_FRAMEBUFFER_COMPLETE) {
10344 + weston_log("%s: fbo error: %#x\n", __func__, status);
10345 + glDeleteFramebuffers(1, &fbo);
10346 + glDeleteTextures(1, &tex);
10350 + glViewport(0, 0, cw, ch);
10351 + glDisable(GL_BLEND);
10352 + use_shader(gr, gs->shader);
10353 + if (gs->y_inverted)
10354 + proj = projmat_normal;
10356 + proj = projmat_yinvert;
10358 + glUniformMatrix4fv(gs->shader->proj_uniform, 1, GL_FALSE, proj);
10359 + glUniform1f(gs->shader->alpha_uniform, 1.0f);
10361 + for (i = 0; i < gs->num_textures; i++) {
10362 + glUniform1i(gs->shader->tex_uniforms[i], i);
10364 + glActiveTexture(GL_TEXTURE0 + i);
10365 + glBindTexture(gs->target, gs->textures[i]);
10366 + glTexParameteri(gs->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
10367 + glTexParameteri(gs->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
10371 + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, verts);
10372 + glEnableVertexAttribArray(0);
10375 + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, verts);
10376 + glEnableVertexAttribArray(1);
10378 + glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
10380 + glDisableVertexAttribArray(1);
10381 + glDisableVertexAttribArray(0);
10383 + glPixelStorei(GL_PACK_ALIGNMENT, bytespp);
10384 + glReadPixels(src_x, src_y, width, height, gl_format,
10385 + GL_UNSIGNED_BYTE, target);
10387 + glDeleteFramebuffers(1, &fbo);
10388 + glDeleteTextures(1, &tex);
10394 surface_state_destroy(struct gl_surface_state *gs, struct gl_renderer *gr)
10397 @@ -1932,6 +2079,9 @@ gl_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
10398 gr->base.attach = gl_renderer_attach;
10399 gr->base.surface_set_color = gl_renderer_surface_set_color;
10400 gr->base.destroy = gl_renderer_destroy;
10401 + gr->base.surface_get_content_size =
10402 + gl_renderer_surface_get_content_size;
10403 + gr->base.surface_copy_content = gl_renderer_surface_copy_content;
10405 gr->egl_display = eglGetDisplay(display);
10406 if (gr->egl_display == EGL_NO_DISPLAY) {
10407 diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c
10408 index 93be968..c9d5038 100644
10409 --- a/src/pixman-renderer.c
10410 +++ b/src/pixman-renderer.c
10411 @@ -674,6 +674,53 @@ pixman_renderer_destroy(struct weston_compositor *ec)
10415 +pixman_renderer_surface_get_content_size(struct weston_surface *surface,
10416 + int *width, int *height)
10418 + struct pixman_surface_state *ps = get_surface_state(surface);
10421 + *width = pixman_image_get_width(ps->image);
10422 + *height = pixman_image_get_height(ps->image);
10430 +pixman_renderer_surface_copy_content(struct weston_surface *surface,
10431 + void *target, size_t size,
10432 + int src_x, int src_y,
10433 + int width, int height)
10435 + const pixman_format_code_t format = PIXMAN_a8b8g8r8;
10436 + const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
10437 + struct pixman_surface_state *ps = get_surface_state(surface);
10438 + pixman_image_t *out_buf;
10443 + out_buf = pixman_image_create_bits(format, width, height,
10444 + target, width * bytespp);
10446 + pixman_image_set_transform(ps->image, NULL);
10447 + pixman_image_composite32(PIXMAN_OP_SRC,
10448 + ps->image, /* src */
10450 + out_buf, /* dest */
10451 + src_x, src_y, /* src_x, src_y */
10452 + 0, 0, /* mask_x, mask_y */
10453 + 0, 0, /* dest_x, dest_y */
10456 + pixman_image_unref(out_buf);
10462 debug_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
10465 @@ -711,6 +758,10 @@ pixman_renderer_init(struct weston_compositor *ec)
10466 renderer->base.attach = pixman_renderer_attach;
10467 renderer->base.surface_set_color = pixman_renderer_surface_set_color;
10468 renderer->base.destroy = pixman_renderer_destroy;
10469 + renderer->base.surface_get_content_size =
10470 + pixman_renderer_surface_get_content_size;
10471 + renderer->base.surface_copy_content =
10472 + pixman_renderer_surface_copy_content;
10473 ec->renderer = &renderer->base;
10474 ec->capabilities |= WESTON_CAP_ROTATION_ANY;
10475 ec->capabilities |= WESTON_CAP_CAPTURE_YFLIP;