summaryrefslogtreecommitdiffstats
path: root/meta-ivi-common/recipes-graphics/wayland/weston-ivi-shell/0001-IVI-Shell-Backport-from-Weston-1.9.0-to-1.8.0.patch
diff options
context:
space:
mode:
authorManuel Bachmann <mbc@iot.bzh>2016-01-13 18:36:55 +0000
committerGerrit Code Review <gerrit@172.30.200.200>2016-01-18 22:28:01 +0000
commit59fb43fa95a212af20009247332b4c5c34302b1f (patch)
tree056f68cd25c2feedd4dbce5b251a82acf5a70fec /meta-ivi-common/recipes-graphics/wayland/weston-ivi-shell/0001-IVI-Shell-Backport-from-Weston-1.9.0-to-1.8.0.patch
parent91f7784cfd26ca7d26e1006d78c067e74c7dc92a (diff)
Migrate IVI-Shell backport to Weston 1.8.0 (Yocto 2.0)
(NOTICE : this is the last patch necessary to fully migrate to Yocto 2.0) As newer Poky "Jethro" is now providing Weston 1.8.0, adapt IVI-Shell 1.9.0 backport to it. Remove unnecessary patches (touchscreen support for Qt, panel toggle) which are now upstreamed. Make the systemd service recipe name more generic. Change-Id: Icaad3f40b29617bcb33ac235bbe3c65f7f4bdbd7 Signed-off-by: Manuel Bachmann <mbc@iot.bzh>
Diffstat (limited to 'meta-ivi-common/recipes-graphics/wayland/weston-ivi-shell/0001-IVI-Shell-Backport-from-Weston-1.9.0-to-1.8.0.patch')
-rw-r--r--meta-ivi-common/recipes-graphics/wayland/weston-ivi-shell/0001-IVI-Shell-Backport-from-Weston-1.9.0-to-1.8.0.patch2392
1 files changed, 2392 insertions, 0 deletions
diff --git a/meta-ivi-common/recipes-graphics/wayland/weston-ivi-shell/0001-IVI-Shell-Backport-from-Weston-1.9.0-to-1.8.0.patch b/meta-ivi-common/recipes-graphics/wayland/weston-ivi-shell/0001-IVI-Shell-Backport-from-Weston-1.9.0-to-1.8.0.patch
new file mode 100644
index 000000000..33476a8f3
--- /dev/null
+++ b/meta-ivi-common/recipes-graphics/wayland/weston-ivi-shell/0001-IVI-Shell-Backport-from-Weston-1.9.0-to-1.8.0.patch
@@ -0,0 +1,2392 @@
+From fb20221f0c0068a4a75fe62f2873d9d3c5566e73 Mon Sep 17 00:00:00 2001
+From: Manuel Bachmann <manuel.bachmann@iot.bzh>
+Date: Wed, 13 Jan 2016 18:42:26 +0100
+Subject: [PATCH] [PATCH] Backport IVI-Shell from Weston 1.9.0 to 1.8.0
+
+IVI-Shell is the alternative Weston shell implementing the
+eponymous protocol, and supported in client toolkits such
+as EFL, Qt...
+
+We backport only what is necessary, without modifying core
+compositor code.
+
+Signed-off-by: Manuel Bachmann <manuel.bachmann@iot.bzh>
+---
+ ivi-shell/hmi-controller.c | 140 +++---
+ ivi-shell/input-panel-ivi.c | 41 +-
+ ivi-shell/ivi-layout-export.h | 58 ++-
+ ivi-shell/ivi-layout-private.h | 47 +-
+ ivi-shell/ivi-layout-transition.c | 39 +-
+ ivi-shell/ivi-layout.c | 983 +++++++++++++++++++-------------------
+ ivi-shell/ivi-shell.c | 91 ++--
+ ivi-shell/ivi-shell.h | 37 +-
+ 8 files changed, 758 insertions(+), 678 deletions(-)
+
+diff --git a/ivi-shell/hmi-controller.c b/ivi-shell/hmi-controller.c
+index 88e9333..2f18217 100644
+--- a/ivi-shell/hmi-controller.c
++++ b/ivi-shell/hmi-controller.c
+@@ -1,23 +1,26 @@
+ /*
+ * Copyright (C) 2014 DENSO CORPORATION
+ *
+- * Permission to use, copy, modify, distribute, and sell this software and
+- * its documentation for any purpose is hereby granted without fee, provided
+- * that the above copyright notice appear in all copies and that both that
+- * copyright notice and this permission notice appear in supporting
+- * documentation, and that the name of the copyright holders not be used in
+- * advertising or publicity pertaining to distribution of the software
+- * without specific, written prior permission. The copyright holders make
+- * no representations about the suitability of this software for any
+- * purpose. It is provided "as is" without express or implied warranty.
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
+ *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial
++ * portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
+ */
+
+ /**
+@@ -721,27 +724,9 @@ hmi_controller_create(struct weston_compositor *ec)
+ ivi_controller_interface->layer_set_visibility(
+ hmi_ctrl->workspace_background_layer.ivilayer, false);
+
+- /* init workspace ivi_layer */
+- hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x;
+- hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y;
+- hmi_ctrl->workspace_layer.width =
+- hmi_ctrl->workspace_background_layer.width;
+- hmi_ctrl->workspace_layer.height =
+- hmi_ctrl->workspace_background_layer.height;
+- hmi_ctrl->workspace_layer.id_layer =
+- hmi_ctrl->hmi_setting->workspace_layer_id;
+-
+- create_layer(iviscrn, &hmi_ctrl->workspace_layer);
+- ivi_controller_interface->layer_set_opacity(hmi_ctrl->workspace_layer.ivilayer, 0);
+- ivi_controller_interface->layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer,
+- false);
+
+ wl_list_init(&hmi_ctrl->workspace_fade.layer_list);
+ tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
+- tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer;
+- wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
+- &tmp_link_layer->link);
+- tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
+ tmp_link_layer->layout_layer =
+ hmi_ctrl->workspace_background_layer.ivilayer;
+ wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
+@@ -976,12 +961,11 @@ static void
+ ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
+ int32_t icon_size)
+ {
+- struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer;
+ int32_t minspace_x = 10;
+ int32_t minspace_y = minspace_x;
+
+- int32_t width = hmi_ctrl->workspace_layer.width;
+- int32_t height = hmi_ctrl->workspace_layer.height;
++ int32_t width = hmi_ctrl->workspace_background_layer.width;
++ int32_t height = hmi_ctrl->workspace_background_layer.height;
+
+ int32_t x_count = (width - minspace_x) / (minspace_x + icon_size);
+ int32_t space_x = (int32_t)((width - x_count * icon_size) / (1.0 + x_count));
+@@ -1011,6 +995,11 @@ ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
+ struct ivi_layout_surface* layout_surface = NULL;
+ uint32_t *add_surface_id = NULL;
+
++ struct ivi_layout_screen *iviscrn = NULL;
++ struct link_layer *tmp_link_layer = NULL;
++ struct ivi_layout_screen **pp_screen = NULL;
++ int32_t screen_length = 0;
++
+ if (0 == x_count)
+ x_count = 1;
+
+@@ -1087,16 +1076,10 @@ ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
+ ivi_controller_interface->get_surface_from_id(data->surface_id);
+ assert(layout_surface);
+
+- ret = ivi_controller_interface->layer_add_surface(layer, layout_surface);
+- assert(!ret);
+-
+ ret = ivi_controller_interface->surface_set_destination_rectangle(
+ layout_surface, x, y, icon_size, icon_size);
+ assert(!ret);
+
+- ret = ivi_controller_interface->surface_set_visibility(layout_surface, true);
+- assert(!ret);
+-
+ nx++;
+
+ if (x_count == nx) {
+@@ -1105,6 +1088,43 @@ ivi_hmi_controller_add_launchers(struct hmi_controller *hmi_ctrl,
+ }
+ }
+
++ /* init workspace ivi_layer */
++ hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x;
++ hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y;
++ hmi_ctrl->workspace_layer.width =
++ hmi_ctrl->workspace_background_layer.width * hmi_ctrl->workspace_count;
++ hmi_ctrl->workspace_layer.height =
++ hmi_ctrl->workspace_background_layer.height;
++ hmi_ctrl->workspace_layer.id_layer =
++ hmi_ctrl->hmi_setting->workspace_layer_id;
++
++ ivi_controller_interface->get_screens(&screen_length, &pp_screen);
++ iviscrn = pp_screen[0];
++ free(pp_screen);
++ create_layer(iviscrn, &hmi_ctrl->workspace_layer);
++ ivi_controller_interface->layer_set_opacity(hmi_ctrl->workspace_layer.ivilayer, 0);
++ ivi_controller_interface->layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer,
++ false);
++
++ tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer));
++ tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer;
++ wl_list_insert(&hmi_ctrl->workspace_fade.layer_list,
++ &tmp_link_layer->link);
++
++ /* Add surface to layer */
++ wl_array_for_each(data, &launchers) {
++ layout_surface =
++ ivi_controller_interface->get_surface_from_id(data->surface_id);
++ assert(layout_surface);
++
++ ret = ivi_controller_interface->layer_add_surface(hmi_ctrl->workspace_layer.ivilayer,
++ layout_surface);
++ assert(!ret);
++
++ ret = ivi_controller_interface->surface_set_visibility(layout_surface, true);
++ assert(!ret);
++ }
++
+ wl_array_release(&launchers);
+ ivi_controller_interface->commit_changes();
+ }
+@@ -1266,8 +1286,8 @@ move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource,
+ duration);
+ ivi_controller_interface->layer_set_destination_rectangle(layer,
+ end_pos, pos_y,
+- hmi_ctrl->workspace_background_layer.width,
+- hmi_ctrl->workspace_background_layer.height);
++ hmi_ctrl->workspace_layer.width,
++ hmi_ctrl->workspace_layer.height);
+ ivi_controller_interface->commit_changes();
+ }
+
+@@ -1465,15 +1485,18 @@ enum HMI_GRAB_DEVICE {
+ static enum HMI_GRAB_DEVICE
+ get_hmi_grab_device(struct weston_seat *seat, uint32_t serial)
+ {
+- if (seat->pointer &&
+- seat->pointer->focus &&
+- seat->pointer->button_count &&
+- seat->pointer->grab_serial == serial)
++ struct weston_pointer *pointer = seat->pointer;
++ struct weston_touch *touch = seat->touch;
++
++ if (pointer &&
++ pointer->focus &&
++ pointer->button_count &&
++ pointer->grab_serial == serial)
+ return HMI_GRAB_DEVICE_POINTER;
+
+- if (seat->touch &&
+- seat->touch->focus &&
+- seat->touch->grab_serial == serial)
++ if (touch &&
++ touch->focus &&
++ touch->grab_serial == serial)
+ return HMI_GRAB_DEVICE_TOUCH;
+
+ return HMI_GRAB_DEVICE_NONE;
+@@ -1564,6 +1587,9 @@ ivi_hmi_controller_workspace_control(struct wl_client *client,
+ struct pointer_move_grab *pnt_move_grab = NULL;
+ struct touch_move_grab *tch_move_grab = NULL;
+ struct weston_seat *seat = NULL;
++ struct weston_pointer *pointer;
++ struct weston_touch *touch;
++
+ enum HMI_GRAB_DEVICE device;
+
+ if (hmi_ctrl->workspace_count < 2)
+@@ -1582,21 +1608,23 @@ ivi_hmi_controller_workspace_control(struct wl_client *client,
+
+ switch (device) {
+ case HMI_GRAB_DEVICE_POINTER:
+- pnt_move_grab = create_workspace_pointer_move(seat->pointer,
++ pointer = seat->pointer;
++ pnt_move_grab = create_workspace_pointer_move(pointer,
+ resource);
+
+ pointer_grab_start(&pnt_move_grab->base, layer,
+ &pointer_move_grab_workspace_interface,
+- seat->pointer);
++ pointer);
+ break;
+
+ case HMI_GRAB_DEVICE_TOUCH:
+- tch_move_grab = create_workspace_touch_move(seat->touch,
++ touch = seat->touch;
++ tch_move_grab = create_workspace_touch_move(touch,
+ resource);
+
+ touch_grab_start(&tch_move_grab->base, layer,
+ &touch_move_grab_workspace_interface,
+- seat->touch);
++ touch);
+ break;
+
+ default:
+diff --git a/ivi-shell/input-panel-ivi.c b/ivi-shell/input-panel-ivi.c
+index 6b89177..3eefb68 100644
+--- a/ivi-shell/input-panel-ivi.c
++++ b/ivi-shell/input-panel-ivi.c
+@@ -3,23 +3,26 @@
+ * Copyright © 2011-2012 Collabora, Ltd.
+ * Copyright © 2013 Raspberry Pi Foundation
+ *
+- * Permission to use, copy, modify, distribute, and sell this software and
+- * its documentation for any purpose is hereby granted without fee, provided
+- * that the above copyright notice appear in all copies and that both that
+- * copyright notice and this permission notice appear in supporting
+- * documentation, and that the name of the copyright holders not be used in
+- * advertising or publicity pertaining to distribution of the software
+- * without specific, written prior permission. The copyright holders make
+- * no representations about the suitability of this software for any
+- * purpose. It is provided "as is" without express or implied warranty.
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
+ *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial
++ * portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
+ */
+
+ #include "config.h"
+@@ -66,9 +69,11 @@ show_input_panel_surface(struct input_panel_surface *ipsurf)
+ float x, y;
+
+ wl_list_for_each(seat, &shell->compositor->seat_list, link) {
+- if (!seat->keyboard || !seat->keyboard->focus)
++ struct weston_keyboard *keyboard = seat->keyboard;
++
++ if (!keyboard || !keyboard->focus)
+ continue;
+- focus = weston_surface_get_main_surface(seat->keyboard->focus);
++ focus = weston_surface_get_main_surface(keyboard->focus);
+ ipsurf->output = focus->output;
+ x = ipsurf->output->x + (ipsurf->output->width - ipsurf->surface->width) / 2;
+ y = ipsurf->output->y + ipsurf->output->height - ipsurf->surface->height;
+diff --git a/ivi-shell/ivi-layout-export.h b/ivi-shell/ivi-layout-export.h
+index 4b4328c..8a92009 100644
+--- a/ivi-shell/ivi-layout-export.h
++++ b/ivi-shell/ivi-layout-export.h
+@@ -1,23 +1,26 @@
+ /*
+ * Copyright (C) 2013 DENSO CORPORATION
+ *
+- * Permission to use, copy, modify, distribute, and sell this software and
+- * its documentation for any purpose is hereby granted without fee, provided
+- * that the above copyright notice appear in all copies and that both that
+- * copyright notice and this permission notice appear in supporting
+- * documentation, and that the name of the copyright holders not be used in
+- * advertising or publicity pertaining to distribution of the software
+- * without specific, written prior permission. The copyright holders make
+- * no representations about the suitability of this software for any
+- * purpose. It is provided "as is" without express or implied warranty.
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
+ *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial
++ * portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
+ */
+
+ /**
+@@ -467,7 +470,7 @@ struct ivi_controller_interface {
+ /**
+ * \brief Removes a ivi_layer which is currently managed by the service
+ */
+- void (*layer_remove)(struct ivi_layout_layer *ivilayer);
++ void (*layer_destroy)(struct ivi_layout_layer *ivilayer);
+
+ /**
+ * \brief Get all ivi_layers which are currently registered and managed
+@@ -780,6 +783,27 @@ struct ivi_controller_interface {
+ int32_t x, int32_t y,
+ int32_t width, int32_t height);
+
++ /**
++ * remove notification by callback on property changes of ivi_surface
++ */
++ void (*surface_remove_notification_by_callback)(struct ivi_layout_surface *ivisurf,
++ surface_property_notification_func callback,
++ void *userdata);
++
++ /**
++ * \brief remove notification by callback on property changes of ivi_layer
++ */
++ void (*layer_remove_notification_by_callback)(struct ivi_layout_layer *ivilayer,
++ layer_property_notification_func callback,
++ void *userdata);
++
++ /**
++ * \brief get id of ivi_screen from ivi_layout_screen
++ *
++ *
++ * \return id of ivi_screen
++ */
++ uint32_t (*get_id_of_screen)(struct ivi_layout_screen *iviscrn);
+ };
+
+ #ifdef __cplusplus
+diff --git a/ivi-shell/ivi-layout-private.h b/ivi-shell/ivi-layout-private.h
+index 4531748..074d598 100644
+--- a/ivi-shell/ivi-layout-private.h
++++ b/ivi-shell/ivi-layout-private.h
+@@ -1,23 +1,26 @@
+ /*
+ * Copyright (C) 2014 DENSO CORPORATION
+ *
+- * Permission to use, copy, modify, distribute, and sell this software and
+- * its documentation for any purpose is hereby granted without fee, provided
+- * that the above copyright notice appear in all copies and that both that
+- * copyright notice and this permission notice appear in supporting
+- * documentation, and that the name of the copyright holders not be used in
+- * advertising or publicity pertaining to distribution of the software
+- * without specific, written prior permission. The copyright holders make
+- * no representations about the suitability of this software for any
+- * purpose. It is provided "as is" without express or implied warranty.
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
+ *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial
++ * portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
+ */
+
+ #ifndef _ivi_layout_PRIVATE_H_
+@@ -36,12 +39,7 @@ struct ivi_layout_surface {
+ struct ivi_layout *layout;
+ struct weston_surface *surface;
+
+- struct wl_listener surface_destroy_listener;
+- struct weston_transform surface_rotation;
+- struct weston_transform layer_rotation;
+- struct weston_transform surface_pos;
+- struct weston_transform layer_pos;
+- struct weston_transform scaling;
++ struct weston_transform transform;
+
+ struct ivi_layout_surface_properties prop;
+ uint32_t event_mask;
+@@ -83,9 +81,12 @@ struct ivi_layout_layer {
+ } pending;
+
+ struct {
++ int dirty;
+ struct wl_list surface_list;
+ struct wl_list link;
+ } order;
++
++ int32_t ref_count;
+ };
+
+ struct ivi_layout {
+@@ -223,4 +224,6 @@ ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer);
+ int
+ load_controller_modules(struct weston_compositor *compositor, const char *modules,
+ int *argc, char *argv[]);
++void
++ivi_layout_surface_destroy(struct ivi_layout_surface *ivisurf);
+ #endif
+diff --git a/ivi-shell/ivi-layout-transition.c b/ivi-shell/ivi-layout-transition.c
+index f691d35..d12a8f4 100644
+--- a/ivi-shell/ivi-layout-transition.c
++++ b/ivi-shell/ivi-layout-transition.c
+@@ -1,23 +1,26 @@
+ /*
+ * Copyright (C) 2014 DENSO CORPORATION
+ *
+- * Permission to use, copy, modify, distribute, and sell this software and
+- * its documentation for any purpose is hereby granted without fee, provided
+- * that the above copyright notice appear in all copies and that both that
+- * copyright notice and this permission notice appear in supporting
+- * documentation, and that the name of the copyright holders not be used in
+- * advertising or publicity pertaining to distribution of the software
+- * without specific, written prior permission. The copyright holders make
+- * no representations about the suitability of this software for any
+- * purpose. It is provided "as is" without express or implied warranty.
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
+ *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial
++ * portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
+ */
+
+ #include <time.h>
+@@ -226,7 +229,7 @@ layout_transition_destroy(struct ivi_layout_transition *transition)
+ struct ivi_layout *layout = get_instance();
+
+ remove_transition(layout, transition);
+- if(transition->destroy_func)
++ if (transition->destroy_func)
+ transition->destroy_func(transition);
+ free(transition);
+ }
+@@ -660,7 +663,7 @@ transition_move_layer_destroy(struct ivi_layout_transition *transition)
+ {
+ struct move_layer_data *data = transition->private_data;
+
+- if(data->destroy_func)
++ if (data->destroy_func)
+ data->destroy_func(transition->user_data);
+
+ free(data);
+diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c
+index abfba70..c153884 100644
+--- a/ivi-shell/ivi-layout.c
++++ b/ivi-shell/ivi-layout.c
+@@ -1,23 +1,26 @@
+ /*
+ * Copyright (C) 2013 DENSO CORPORATION
+ *
+- * Permission to use, copy, modify, distribute, and sell this software and
+- * its documentation for any purpose is hereby granted without fee, provided
+- * that the above copyright notice appear in all copies and that both that
+- * copyright notice and this permission notice appear in supporting
+- * documentation, and that the name of the copyright holders not be used in
+- * advertising or publicity pertaining to distribution of the software
+- * without specific, written prior permission. The copyright holders make
+- * no representations about the suitability of this software for any
+- * purpose. It is provided "as is" without express or implied warranty.
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
+ *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial
++ * portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
+ */
+
+ /**
+@@ -55,12 +58,15 @@
+ #include "config.h"
+
+ #include <string.h>
++#include <assert.h>
+
+ #include "compositor.h"
+ #include "ivi-layout-export.h"
+ #include "ivi-layout-private.h"
+
+-#include "../shared/os-compatibility.h"
++#include "shared/os-compatibility.h"
++
++#define max(a, b) ((a) > (b) ? (a) : (b))
+
+ struct link_layer {
+ struct ivi_layout_layer *ivilayer;
+@@ -89,14 +95,13 @@ struct ivi_layout_screen {
+ struct ivi_layout *layout;
+ struct weston_output *output;
+
+- uint32_t event_mask;
+-
+ struct {
+ struct wl_list layer_list;
+ struct wl_list link;
+ } pending;
+
+ struct {
++ int dirty;
+ struct wl_list layer_list;
+ struct wl_list link;
+ } order;
+@@ -107,6 +112,17 @@ struct ivi_layout_notification_callback {
+ void *data;
+ };
+
++struct ivi_rectangle
++{
++ int32_t x;
++ int32_t y;
++ int32_t width;
++ int32_t height;
++};
++
++static void
++remove_notification(struct wl_list *listener_list, void *callback, void *userdata);
++
+ static struct ivi_layout ivilayout = {0};
+
+ struct ivi_layout *
+@@ -139,12 +155,8 @@ remove_link_to_surface(struct ivi_layout_layer *ivilayer)
+ struct link_layer *next = NULL;
+
+ wl_list_for_each_safe(link, next, &ivilayer->link_to_surface, link_to_layer) {
+- if (!wl_list_empty(&link->link_to_layer)) {
+- wl_list_remove(&link->link_to_layer);
+- }
+- if (!wl_list_empty(&link->link)) {
+- wl_list_remove(&link->link);
+- }
++ wl_list_remove(&link->link_to_layer);
++ wl_list_remove(&link->link);
+ free(link);
+ }
+
+@@ -158,7 +170,6 @@ static void
+ add_link_to_layer(struct ivi_layout_screen *iviscrn,
+ struct link_screen *link_screen)
+ {
+- wl_list_init(&link_screen->link_to_screen);
+ wl_list_insert(&iviscrn->link_to_layer, &link_screen->link_to_screen);
+ }
+
+@@ -178,7 +189,6 @@ add_ordersurface_to_layer(struct ivi_layout_surface *ivisurf,
+ }
+
+ link_layer->ivilayer = ivilayer;
+- wl_list_init(&link_layer->link);
+ wl_list_insert(&ivisurf->layer_list, &link_layer->link);
+ add_link_to_surface(ivilayer, link_layer);
+ }
+@@ -190,12 +200,8 @@ remove_ordersurface_from_layer(struct ivi_layout_surface *ivisurf)
+ struct link_layer *next = NULL;
+
+ wl_list_for_each_safe(link_layer, next, &ivisurf->layer_list, link) {
+- if (!wl_list_empty(&link_layer->link)) {
+- wl_list_remove(&link_layer->link);
+- }
+- if (!wl_list_empty(&link_layer->link_to_layer)) {
+- wl_list_remove(&link_layer->link_to_layer);
+- }
++ wl_list_remove(&link_layer->link);
++ wl_list_remove(&link_layer->link_to_layer);
+ free(link_layer);
+ }
+ wl_list_init(&ivisurf->layer_list);
+@@ -217,7 +223,6 @@ add_orderlayer_to_screen(struct ivi_layout_layer *ivilayer,
+ }
+
+ link_scrn->iviscrn = iviscrn;
+- wl_list_init(&link_scrn->link);
+ wl_list_insert(&ivilayer->screen_list, &link_scrn->link);
+ add_link_to_layer(iviscrn, link_scrn);
+ }
+@@ -229,12 +234,8 @@ remove_orderlayer_from_screen(struct ivi_layout_layer *ivilayer)
+ struct link_screen *next = NULL;
+
+ wl_list_for_each_safe(link_scrn, next, &ivilayer->screen_list, link) {
+- if (!wl_list_empty(&link_scrn->link)) {
+- wl_list_remove(&link_scrn->link);
+- }
+- if (!wl_list_empty(&link_scrn->link_to_screen)) {
+- wl_list_remove(&link_scrn->link_to_screen);
+- }
++ wl_list_remove(&link_scrn->link);
++ wl_list_remove(&link_scrn->link_to_screen);
+ free(link_scrn);
+ }
+ wl_list_init(&ivilayer->screen_list);
+@@ -290,9 +291,7 @@ remove_all_notification(struct wl_list *listener_list)
+
+ wl_list_for_each_safe(listener, next, listener_list, link) {
+ struct listener_layout_notification *notification = NULL;
+- if (!wl_list_empty(&listener->link)) {
+- wl_list_remove(&listener->link);
+- }
++ wl_list_remove(&listener->link);
+
+ notification =
+ container_of(listener,
+@@ -315,29 +314,36 @@ ivi_layout_surface_remove_notification(struct ivi_layout_surface *ivisurf)
+ remove_all_notification(&ivisurf->property_changed.listener_list);
+ }
+
++static void
++ivi_layout_surface_remove_notification_by_callback(struct ivi_layout_surface *ivisurf,
++ surface_property_notification_func callback,
++ void *userdata)
++{
++ if (ivisurf == NULL) {
++ weston_log("ivi_layout_surface_remove_notification_by_callback: invalid argument\n");
++ return;
++ }
++
++ remove_notification(&ivisurf->property_changed.listener_list, callback, userdata);
++}
++
+ /**
+- * this shall not be called from controller because this is triggered by ivi_surface.destroy
+- * This means that this is called from westonsurface_destroy_from_ivisurface.
++ * Called at destruction of wl_surface/ivi_surface
+ */
+-static void
+-ivi_layout_surface_remove(struct ivi_layout_surface *ivisurf)
++void
++ivi_layout_surface_destroy(struct ivi_layout_surface *ivisurf)
+ {
+ struct ivi_layout *layout = get_instance();
+
+ if (ivisurf == NULL) {
+- weston_log("ivi_layout_surface_remove: invalid argument\n");
++ weston_log("%s: invalid argument\n", __func__);
+ return;
+ }
+
+- if (!wl_list_empty(&ivisurf->pending.link)) {
+- wl_list_remove(&ivisurf->pending.link);
+- }
+- if (!wl_list_empty(&ivisurf->order.link)) {
+- wl_list_remove(&ivisurf->order.link);
+- }
+- if (!wl_list_empty(&ivisurf->link)) {
+- wl_list_remove(&ivisurf->link);
+- }
++ wl_list_remove(&ivisurf->transform.link);
++ wl_list_remove(&ivisurf->pending.link);
++ wl_list_remove(&ivisurf->order.link);
++ wl_list_remove(&ivisurf->link);
+ remove_ordersurface_from_layer(ivisurf);
+
+ wl_signal_emit(&layout->surface_notification.removed, ivisurf);
+@@ -350,27 +356,6 @@ ivi_layout_surface_remove(struct ivi_layout_surface *ivisurf)
+ }
+
+ /**
+- * Called at destruction of ivi_surface
+- */
+-static void
+-westonsurface_destroy_from_ivisurface(struct wl_listener *listener, void *data)
+-{
+- struct ivi_layout_surface *ivisurf = NULL;
+-
+- ivisurf = container_of(listener, struct ivi_layout_surface,
+- surface_destroy_listener);
+-
+- wl_list_remove(&ivisurf->surface_rotation.link);
+- wl_list_remove(&ivisurf->layer_rotation.link);
+- wl_list_remove(&ivisurf->surface_pos.link);
+- wl_list_remove(&ivisurf->layer_pos.link);
+- wl_list_remove(&ivisurf->scaling.link);
+-
+- ivisurf->surface = NULL;
+- ivi_layout_surface_remove(ivisurf);
+-}
+-
+-/**
+ * Internal API to check ivi_layer/ivi_surface already added in ivi_layer/ivi_screen.
+ * Called by ivi_layout_layer_add_surface/ivi_layout_screenAddLayer
+ */
+@@ -423,14 +408,12 @@ create_screen(struct weston_compositor *ec)
+ continue;
+ }
+
+- wl_list_init(&iviscrn->link);
+ iviscrn->layout = layout;
+
+ iviscrn->id_screen = count;
+ count++;
+
+ iviscrn->output = output;
+- iviscrn->event_mask = 0;
+
+ wl_list_init(&iviscrn->pending.layer_list);
+ wl_list_init(&iviscrn->pending.link);
+@@ -494,293 +477,319 @@ update_opacity(struct ivi_layout_layer *ivilayer,
+ }
+
+ static void
+-update_surface_orientation(struct ivi_layout_layer *ivilayer,
+- struct ivi_layout_surface *ivisurf)
+-{
+- struct weston_view *view;
+- struct weston_matrix *matrix = &ivisurf->surface_rotation.matrix;
+- float width = 0.0f;
+- float height = 0.0f;
+- float v_sin = 0.0f;
+- float v_cos = 0.0f;
+- float cx = 0.0f;
+- float cy = 0.0f;
+- float sx = 1.0f;
+- float sy = 1.0f;
+-
+- wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
+- if (view != NULL) {
+- break;
+- }
+- }
+-
+- if (view == NULL) {
+- return;
+- }
+-
+- if ((ivilayer->prop.dest_width == 0) ||
+- (ivilayer->prop.dest_height == 0)) {
+- return;
+- }
+- width = (float)ivilayer->prop.dest_width;
+- height = (float)ivilayer->prop.dest_height;
+-
+- switch (ivisurf->prop.orientation) {
+- case WL_OUTPUT_TRANSFORM_NORMAL:
+- v_sin = 0.0f;
+- v_cos = 1.0f;
+- break;
++get_rotate_values(enum wl_output_transform orientation,
++ float *v_sin,
++ float *v_cos)
++{
++ switch (orientation) {
+ case WL_OUTPUT_TRANSFORM_90:
+- v_sin = 1.0f;
+- v_cos = 0.0f;
+- sx = width / height;
+- sy = height / width;
++ *v_sin = 1.0f;
++ *v_cos = 0.0f;
+ break;
+ case WL_OUTPUT_TRANSFORM_180:
+- v_sin = 0.0f;
+- v_cos = -1.0f;
++ *v_sin = 0.0f;
++ *v_cos = -1.0f;
+ break;
+ case WL_OUTPUT_TRANSFORM_270:
++ *v_sin = -1.0f;
++ *v_cos = 0.0f;
++ break;
++ case WL_OUTPUT_TRANSFORM_NORMAL:
+ default:
+- v_sin = -1.0f;
+- v_cos = 0.0f;
+- sx = width / height;
+- sy = height / width;
++ *v_sin = 0.0f;
++ *v_cos = 1.0f;
+ break;
+ }
+- wl_list_remove(&ivisurf->surface_rotation.link);
+- weston_view_geometry_dirty(view);
+-
+- weston_matrix_init(matrix);
+- cx = 0.5f * width;
+- cy = 0.5f * height;
+- weston_matrix_translate(matrix, -cx, -cy, 0.0f);
+- weston_matrix_rotate_xy(matrix, v_cos, v_sin);
+- weston_matrix_scale(matrix, sx, sy, 1.0);
+- weston_matrix_translate(matrix, cx, cy, 0.0f);
+- wl_list_insert(&view->geometry.transformation_list,
+- &ivisurf->surface_rotation.link);
+-
+- weston_view_set_transform_parent(view, NULL);
+- weston_view_update_transform(view);
+ }
+
+ static void
+-update_layer_orientation(struct ivi_layout_layer *ivilayer,
+- struct ivi_layout_surface *ivisurf)
+-{
+- struct weston_surface *es = ivisurf->surface;
+- struct weston_view *view;
+- struct weston_matrix *matrix = &ivisurf->layer_rotation.matrix;
+- struct weston_output *output = NULL;
+- float width = 0.0f;
+- float height = 0.0f;
+- float v_sin = 0.0f;
+- float v_cos = 0.0f;
+- float cx = 0.0f;
+- float cy = 0.0f;
+- float sx = 1.0f;
+- float sy = 1.0f;
+-
+- wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
+- if (view != NULL) {
+- break;
+- }
+- }
+-
+- if (es == NULL || view == NULL) {
+- return;
+- }
+-
+- output = es->output;
+- if (output == NULL) {
+- return;
+- }
+- if ((output->width == 0) || (output->height == 0)) {
+- return;
+- }
+- width = (float)output->width;
+- height = (float)output->height;
+-
+- switch (ivilayer->prop.orientation) {
+- case WL_OUTPUT_TRANSFORM_NORMAL:
+- v_sin = 0.0f;
+- v_cos = 1.0f;
+- break;
++get_scale(enum wl_output_transform orientation,
++ float dest_width,
++ float dest_height,
++ float source_width,
++ float source_height,
++ float *scale_x,
++ float *scale_y)
++{
++ switch (orientation) {
+ case WL_OUTPUT_TRANSFORM_90:
+- v_sin = 1.0f;
+- v_cos = 0.0f;
+- sx = width / height;
+- sy = height / width;
++ *scale_x = dest_width / source_height;
++ *scale_y = dest_height / source_width;
+ break;
+ case WL_OUTPUT_TRANSFORM_180:
+- v_sin = 0.0f;
+- v_cos = -1.0f;
++ *scale_x = dest_width / source_width;
++ *scale_y = dest_height / source_height;
+ break;
+ case WL_OUTPUT_TRANSFORM_270:
++ *scale_x = dest_width / source_height;
++ *scale_y = dest_height / source_width;
++ break;
++ case WL_OUTPUT_TRANSFORM_NORMAL:
+ default:
+- v_sin = -1.0f;
+- v_cos = 0.0f;
+- sx = width / height;
+- sy = height / width;
++ *scale_x = dest_width / source_width;
++ *scale_y = dest_height / source_height;
+ break;
+ }
+- wl_list_remove(&ivisurf->layer_rotation.link);
+- weston_view_geometry_dirty(view);
+-
+- weston_matrix_init(matrix);
+- cx = 0.5f * width;
+- cy = 0.5f * height;
+- weston_matrix_translate(matrix, -cx, -cy, 0.0f);
+- weston_matrix_rotate_xy(matrix, v_cos, v_sin);
+- weston_matrix_scale(matrix, sx, sy, 1.0);
+- weston_matrix_translate(matrix, cx, cy, 0.0f);
+- wl_list_insert(&view->geometry.transformation_list,
+- &ivisurf->layer_rotation.link);
++}
+
+- weston_view_set_transform_parent(view, NULL);
+- weston_view_update_transform(view);
++static void
++calc_transformation_matrix(struct ivi_rectangle *source_rect,
++ struct ivi_rectangle *dest_rect,
++ enum wl_output_transform orientation,
++ struct weston_matrix *m)
++{
++ float source_center_x;
++ float source_center_y;
++ float vsin;
++ float vcos;
++ float scale_x;
++ float scale_y;
++ float translate_x;
++ float translate_y;
++
++ source_center_x = source_rect->x + source_rect->width * 0.5f;
++ source_center_y = source_rect->y + source_rect->height * 0.5f;
++ weston_matrix_translate(m, -source_center_x, -source_center_y, 0.0f);
++
++ get_rotate_values(orientation, &vsin, &vcos);
++ weston_matrix_rotate_xy(m, vcos, vsin);
++
++ get_scale(orientation,
++ dest_rect->width,
++ dest_rect->height,
++ source_rect->width,
++ source_rect->height,
++ &scale_x,
++ &scale_y);
++ weston_matrix_scale(m, scale_x, scale_y, 1.0f);
++
++ translate_x = dest_rect->width * 0.5f + dest_rect->x;
++ translate_y = dest_rect->height * 0.5f + dest_rect->y;
++ weston_matrix_translate(m, translate_x, translate_y, 0.0f);
+ }
+
++/*
++ * This computes intersected rect_output from two ivi_rectangles
++ */
+ static void
+-update_surface_position(struct ivi_layout_surface *ivisurf)
++ivi_rectangle_intersect(const struct ivi_rectangle *rect1,
++ const struct ivi_rectangle *rect2,
++ struct ivi_rectangle *rect_output)
+ {
+- struct weston_view *view;
+- float tx = (float)ivisurf->prop.dest_x;
+- float ty = (float)ivisurf->prop.dest_y;
+- struct weston_matrix *matrix = &ivisurf->surface_pos.matrix;
++ int32_t rect1_right = rect1->x + rect1->width;
++ int32_t rect1_bottom = rect1->y + rect1->height;
++ int32_t rect2_right = rect2->x + rect2->width;
++ int32_t rect2_bottom = rect2->y + rect2->height;
+
+- wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
+- if (view != NULL) {
+- break;
+- }
+- }
++ rect_output->x = max(rect1->x, rect2->x);
++ rect_output->y = max(rect1->y, rect2->y);
++ rect_output->width = rect1_right < rect2_right ?
++ rect1_right - rect_output->x :
++ rect2_right - rect_output->x;
++ rect_output->height = rect1_bottom < rect2_bottom ?
++ rect1_bottom - rect_output->y :
++ rect2_bottom - rect_output->y;
+
+- if (view == NULL) {
+- return;
++ if (rect_output->width < 0 || rect_output->height < 0) {
++ rect_output->width = 0;
++ rect_output->height = 0;
+ }
+-
+- wl_list_remove(&ivisurf->surface_pos.link);
+-
+- weston_matrix_init(matrix);
+- weston_matrix_translate(matrix, tx, ty, 0.0f);
+- wl_list_insert(&view->geometry.transformation_list,
+- &ivisurf->surface_pos.link);
+-
+- weston_view_set_transform_parent(view, NULL);
+- weston_view_update_transform(view);
+ }
+
++/*
++ * Transform rect_input by the inverse of matrix, intersect with boundingbox,
++ * and store the result in rect_output.
++ * The boundingbox must be given in the same coordinate space as rect_output.
++ * Additionally, there are the following restrictions on the matrix:
++ * - no projective transformations
++ * - no skew
++ * - only multiples of 90-degree rotations supported
++ *
++ * In failure case of weston_matrix_invert, rect_output is set to boundingbox
++ * as a fail-safe with log.
++ */
+ static void
+-update_layer_position(struct ivi_layout_layer *ivilayer,
+- struct ivi_layout_surface *ivisurf)
++calc_inverse_matrix_transform(const struct weston_matrix *matrix,
++ const struct ivi_rectangle *rect_input,
++ const struct ivi_rectangle *boundingbox,
++ struct ivi_rectangle *rect_output)
+ {
+- struct weston_view *view;
+- struct weston_matrix *matrix = &ivisurf->layer_pos.matrix;
+- float tx = (float)ivilayer->prop.dest_x;
+- float ty = (float)ivilayer->prop.dest_y;
++ struct weston_matrix m;
++ struct weston_vector top_left;
++ struct weston_vector bottom_right;
+
+- wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
+- if (view != NULL) {
+- break;
+- }
+- }
++ assert(boundingbox != rect_output);
+
+- if (view == NULL) {
+- return;
++ if (weston_matrix_invert(&m, matrix) < 0) {
++ weston_log("ivi-shell: calc_inverse_matrix_transform fails to invert a matrix.\n");
++ weston_log("ivi-shell: boundingbox is set to the rect_output.\n");
++ rect_output->x = boundingbox->x;
++ rect_output->y = boundingbox->y;
++ rect_output->width = boundingbox->width;
++ rect_output->height = boundingbox->height;
+ }
+
+- wl_list_remove(&ivisurf->layer_pos.link);
++ /* The vectors and matrices involved will always produce f[3] == 1.0. */
++ top_left.f[0] = rect_input->x;
++ top_left.f[1] = rect_input->y;
++ top_left.f[2] = 0.0f;
++ top_left.f[3] = 1.0f;
+
+- weston_matrix_init(matrix);
+- weston_matrix_translate(matrix, tx, ty, 0.0f);
+- wl_list_insert(&view->geometry.transformation_list,
+- &ivisurf->layer_pos.link);
++ bottom_right.f[0] = rect_input->x + rect_input->width;
++ bottom_right.f[1] = rect_input->y + rect_input->height;
++ bottom_right.f[2] = 0.0f;
++ bottom_right.f[3] = 1.0f;
+
+- weston_view_set_transform_parent(view, NULL);
+- weston_view_update_transform(view);
+-}
++ weston_matrix_transform(&m, &top_left);
++ weston_matrix_transform(&m, &bottom_right);
+
+-static void
+-update_scale(struct ivi_layout_layer *ivilayer,
+- struct ivi_layout_surface *ivisurf)
+-{
+- struct weston_view *view;
+- struct weston_matrix *matrix = &ivisurf->scaling.matrix;
+- float sx = 0.0f;
+- float sy = 0.0f;
+- float lw = 0.0f;
+- float sw = 0.0f;
+- float lh = 0.0f;
+- float sh = 0.0f;
+-
+- wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
+- if (view != NULL) {
+- break;
+- }
++ if (top_left.f[0] < bottom_right.f[0]) {
++ rect_output->x = top_left.f[0];
++ rect_output->width = bottom_right.f[0] - rect_output->x;
++ } else {
++ rect_output->x = bottom_right.f[0];
++ rect_output->width = top_left.f[0] - rect_output->x;
+ }
+
+- if (view == NULL) {
+- return;
++ if (top_left.f[1] < bottom_right.f[1]) {
++ rect_output->y = top_left.f[1];
++ rect_output->height = bottom_right.f[1] - rect_output->y;
++ } else {
++ rect_output->y = bottom_right.f[1];
++ rect_output->height = top_left.f[1] - rect_output->y;
+ }
+
+- if (ivisurf->prop.source_width == 0 || ivisurf->prop.source_height == 0) {
+- weston_log("ivi-shell: source rectangle is not yet set by ivi_layout_surface_set_source_rectangle\n");
+- return;
+- }
++ ivi_rectangle_intersect(rect_output, boundingbox, rect_output);
++}
+
+- if (ivisurf->prop.dest_width == 0 || ivisurf->prop.dest_height == 0) {
+- weston_log("ivi-shell: destination rectangle is not yet set by ivi_layout_surface_set_destination_rectangle\n");
+- return;
+- }
++/**
++ * This computes the whole transformation matrix:m from surface-local
++ * coordinates to global coordinates. It is assumed that
++ * weston_view::geometry.{x,y} are zero.
++ *
++ * Additionally, this computes the mask on surface-local coordinates as a
++ * ivi_rectangle. This can be set to weston_view_set_mask.
++ *
++ * The mask is computed by following steps
++ * - destination rectangle of layer is inversed to surface-local cooodinates
++ * by inversed matrix:m.
++ * - the area is intersected by intersected area between weston_surface and
++ * source rectangle of ivi_surface.
++ */
++static void
++calc_surface_to_global_matrix_and_mask_to_weston_surface(
++ struct ivi_layout_layer *ivilayer,
++ struct ivi_layout_surface *ivisurf,
++ struct weston_matrix *m,
++ struct ivi_rectangle *result)
++{
++ const struct ivi_layout_surface_properties *sp = &ivisurf->prop;
++ const struct ivi_layout_layer_properties *lp = &ivilayer->prop;
++ struct ivi_rectangle weston_surface_rect = { 0,
++ 0,
++ ivisurf->surface->width,
++ ivisurf->surface->height };
++ struct ivi_rectangle surface_source_rect = { sp->source_x,
++ sp->source_y,
++ sp->source_width,
++ sp->source_height };
++ struct ivi_rectangle surface_dest_rect = { sp->dest_x,
++ sp->dest_y,
++ sp->dest_width,
++ sp->dest_height };
++ struct ivi_rectangle layer_source_rect = { lp->source_x,
++ lp->source_y,
++ lp->source_width,
++ lp->source_height };
++ struct ivi_rectangle layer_dest_rect = { lp->dest_x,
++ lp->dest_y,
++ lp->dest_width,
++ lp->dest_height };
++ struct ivi_rectangle surface_result;
+
+- lw = ((float)ivilayer->prop.dest_width / (float)ivilayer->prop.source_width );
+- sw = ((float)ivisurf->prop.dest_width / (float)ivisurf->prop.source_width );
+- lh = ((float)ivilayer->prop.dest_height / (float)ivilayer->prop.source_height);
+- sh = ((float)ivisurf->prop.dest_height / (float)ivisurf->prop.source_height );
+- sx = sw * lw;
+- sy = sh * lh;
++ /*
++ * the whole transformation matrix:m from surface-local
++ * coordinates to global coordinates, which is computed by
++ * two steps,
++ * - surface-local coordinates to layer-local coordinates
++ * - layer-local coordinates to global coordinates
++ */
++ calc_transformation_matrix(&surface_source_rect,
++ &surface_dest_rect,
++ sp->orientation, m);
+
+- wl_list_remove(&ivisurf->scaling.link);
+- weston_matrix_init(matrix);
+- weston_matrix_scale(matrix, sx, sy, 1.0f);
++ calc_transformation_matrix(&layer_source_rect,
++ &layer_dest_rect,
++ lp->orientation, m);
+
+- wl_list_insert(&view->geometry.transformation_list,
+- &ivisurf->scaling.link);
++ /* this intersected ivi_rectangle would be used for masking
++ * weston_surface
++ */
++ ivi_rectangle_intersect(&surface_source_rect, &weston_surface_rect,
++ &surface_result);
+
+- weston_view_set_transform_parent(view, NULL);
+- weston_view_update_transform(view);
++ /* calc masking area of weston_surface from m */
++ calc_inverse_matrix_transform(m,
++ &layer_dest_rect,
++ &surface_result,
++ result);
+ }
+
+ static void
+ update_prop(struct ivi_layout_layer *ivilayer,
+ struct ivi_layout_surface *ivisurf)
+ {
+- if (ivilayer->event_mask | ivisurf->event_mask) {
+- struct weston_view *tmpview;
+- update_opacity(ivilayer, ivisurf);
+- update_layer_orientation(ivilayer, ivisurf);
+- update_layer_position(ivilayer, ivisurf);
+- update_surface_position(ivisurf);
+- update_surface_orientation(ivilayer, ivisurf);
+- update_scale(ivilayer, ivisurf);
++ struct weston_view *tmpview;
++ struct ivi_rectangle r;
++ bool can_calc = true;
+
+- ivisurf->update_count++;
++ if (!ivilayer->event_mask && !ivisurf->event_mask) {
++ return;
++ }
+
+- wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
+- if (tmpview != NULL) {
+- break;
+- }
+- }
++ update_opacity(ivilayer, ivisurf);
+
++ wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
+ if (tmpview != NULL) {
+- weston_view_geometry_dirty(tmpview);
++ break;
+ }
++ }
+
+- if (ivisurf->surface != NULL) {
+- weston_surface_damage(ivisurf->surface);
++ if (ivisurf->prop.source_width == 0 || ivisurf->prop.source_height == 0) {
++ weston_log("ivi-shell: source rectangle is not yet set by ivi_layout_surface_set_source_rectangle\n");
++ can_calc = false;
++ }
++
++ if (ivisurf->prop.dest_width == 0 || ivisurf->prop.dest_height == 0) {
++ weston_log("ivi-shell: destination rectangle is not yet set by ivi_layout_surface_set_destination_rectangle\n");
++ can_calc = false;
++ }
++
++ if (can_calc) {
++ wl_list_remove(&ivisurf->transform.link);
++ weston_matrix_init(&ivisurf->transform.matrix);
++
++ calc_surface_to_global_matrix_and_mask_to_weston_surface(
++ ivilayer, ivisurf, &ivisurf->transform.matrix, &r);
++
++ if (tmpview != NULL) {
++ weston_view_set_mask(tmpview, r.x, r.y, r.width, r.height);
++ wl_list_insert(&tmpview->geometry.transformation_list,
++ &ivisurf->transform.link);
++
++ weston_view_set_transform_parent(tmpview, NULL);
+ }
+ }
++
++ ivisurf->update_count++;
++
++ if (tmpview != NULL) {
++ weston_view_geometry_dirty(tmpview);
++ }
++
++ if (ivisurf->surface != NULL) {
++ weston_surface_damage(ivisurf->surface);
++ }
+ }
+
+ static void
+@@ -810,7 +819,7 @@ commit_surface_list(struct ivi_layout *layout)
+ int32_t configured = 0;
+
+ wl_list_for_each(ivisurf, &layout->surface_list, link) {
+- if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEFAULT) {
++ if (ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEFAULT) {
+ dest_x = ivisurf->prop.dest_x;
+ dest_y = ivisurf->prop.dest_y;
+ dest_width = ivisurf->prop.dest_width;
+@@ -823,7 +832,7 @@ commit_surface_list(struct ivi_layout *layout)
+ ivisurf->pending.prop.dest_height,
+ ivisurf->pending.prop.transition_duration);
+
+- if(ivisurf->pending.prop.visibility) {
++ if (ivisurf->pending.prop.visibility) {
+ ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
+ } else {
+ ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
+@@ -837,7 +846,7 @@ commit_surface_list(struct ivi_layout *layout)
+ ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
+ ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
+
+- } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY){
++ } else if (ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY) {
+ dest_x = ivisurf->prop.dest_x;
+ dest_y = ivisurf->prop.dest_y;
+ dest_width = ivisurf->prop.dest_width;
+@@ -859,9 +868,9 @@ commit_surface_list(struct ivi_layout *layout)
+ ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
+ ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
+
+- } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY){
++ } else if (ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY) {
+ configured = 0;
+- if(ivisurf->pending.prop.visibility) {
++ if (ivisurf->pending.prop.visibility) {
+ ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
+ } else {
+ ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
+@@ -903,9 +912,9 @@ commit_layer_list(struct ivi_layout *layout)
+ struct ivi_layout_surface *next = NULL;
+
+ wl_list_for_each(ivilayer, &layout->layer_list, link) {
+- if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_MOVE) {
++ if (ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_MOVE) {
+ ivi_layout_transition_move_layer(ivilayer, ivilayer->pending.prop.dest_x, ivilayer->pending.prop.dest_y, ivilayer->pending.prop.transition_duration);
+- } else if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_FADE) {
++ } else if (ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_FADE) {
+ ivi_layout_transition_fade_layer(ivilayer,ivilayer->pending.prop.is_fade_in,
+ ivilayer->pending.prop.start_alpha,ivilayer->pending.prop.end_alpha,
+ NULL, NULL,
+@@ -915,53 +924,30 @@ commit_layer_list(struct ivi_layout *layout)
+
+ ivilayer->prop = ivilayer->pending.prop;
+
+- if (!(ivilayer->event_mask &
+- (IVI_NOTIFICATION_ADD | IVI_NOTIFICATION_REMOVE)) ) {
++ if (!ivilayer->order.dirty) {
+ continue;
+ }
+
+- if (ivilayer->event_mask & IVI_NOTIFICATION_REMOVE) {
+- wl_list_for_each_safe(ivisurf, next,
+- &ivilayer->order.surface_list, order.link) {
+- remove_ordersurface_from_layer(ivisurf);
+-
+- if (!wl_list_empty(&ivisurf->order.link)) {
+- wl_list_remove(&ivisurf->order.link);
+- }
+-
+- wl_list_init(&ivisurf->order.link);
+- ivisurf->event_mask |= IVI_NOTIFICATION_REMOVE;
+- }
+-
+- wl_list_init(&ivilayer->order.surface_list);
++ wl_list_for_each_safe(ivisurf, next, &ivilayer->order.surface_list,
++ order.link) {
++ remove_ordersurface_from_layer(ivisurf);
++ wl_list_remove(&ivisurf->order.link);
++ wl_list_init(&ivisurf->order.link);
++ ivisurf->event_mask |= IVI_NOTIFICATION_REMOVE;
+ }
+
+- if (ivilayer->event_mask & IVI_NOTIFICATION_ADD) {
+- wl_list_for_each_safe(ivisurf, next,
+- &ivilayer->order.surface_list, order.link) {
+- remove_ordersurface_from_layer(ivisurf);
+-
+- if (!wl_list_empty(&ivisurf->order.link)) {
+- wl_list_remove(&ivisurf->order.link);
+- }
+-
+- wl_list_init(&ivisurf->order.link);
+- }
++ assert(wl_list_empty(&ivilayer->order.surface_list));
+
+- wl_list_init(&ivilayer->order.surface_list);
+- wl_list_for_each(ivisurf, &ivilayer->pending.surface_list,
++ wl_list_for_each(ivisurf, &ivilayer->pending.surface_list,
+ pending.link) {
+- if(!wl_list_empty(&ivisurf->order.link)){
+- wl_list_remove(&ivisurf->order.link);
+- wl_list_init(&ivisurf->order.link);
+- }
+-
+- wl_list_insert(&ivilayer->order.surface_list,
+- &ivisurf->order.link);
+- add_ordersurface_to_layer(ivisurf, ivilayer);
+- ivisurf->event_mask |= IVI_NOTIFICATION_ADD;
+- }
++ wl_list_remove(&ivisurf->order.link);
++ wl_list_insert(&ivilayer->order.surface_list,
++ &ivisurf->order.link);
++ add_ordersurface_to_layer(ivisurf, ivilayer);
++ ivisurf->event_mask |= IVI_NOTIFICATION_ADD;
+ }
++
++ ivilayer->order.dirty = 0;
+ }
+ }
+
+@@ -974,33 +960,17 @@ commit_screen_list(struct ivi_layout *layout)
+ struct ivi_layout_surface *ivisurf = NULL;
+
+ wl_list_for_each(iviscrn, &layout->screen_list, link) {
+- if (iviscrn->event_mask & IVI_NOTIFICATION_REMOVE) {
++ if (iviscrn->order.dirty) {
+ wl_list_for_each_safe(ivilayer, next,
+ &iviscrn->order.layer_list, order.link) {
+ remove_orderlayer_from_screen(ivilayer);
+-
+- if (!wl_list_empty(&ivilayer->order.link)) {
+- wl_list_remove(&ivilayer->order.link);
+- }
+-
++ wl_list_remove(&ivilayer->order.link);
+ wl_list_init(&ivilayer->order.link);
+ ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
+ }
+- }
+
+- if (iviscrn->event_mask & IVI_NOTIFICATION_ADD) {
+- wl_list_for_each_safe(ivilayer, next,
+- &iviscrn->order.layer_list, order.link) {
+- remove_orderlayer_from_screen(ivilayer);
++ assert(wl_list_empty(&iviscrn->order.layer_list));
+
+- if (!wl_list_empty(&ivilayer->order.link)) {
+- wl_list_remove(&ivilayer->order.link);
+- }
+-
+- wl_list_init(&ivilayer->order.link);
+- }
+-
+- wl_list_init(&iviscrn->order.layer_list);
+ wl_list_for_each(ivilayer, &iviscrn->pending.layer_list,
+ pending.link) {
+ wl_list_insert(&iviscrn->order.layer_list,
+@@ -1008,9 +978,9 @@ commit_screen_list(struct ivi_layout *layout)
+ add_orderlayer_to_screen(ivilayer, iviscrn);
+ ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
+ }
+- }
+
+- iviscrn->event_mask = 0;
++ iviscrn->order.dirty = 0;
++ }
+
+ /* Clear view list of layout ivi_layer */
+ wl_list_init(&layout->layout_layer.view_list.link);
+@@ -1046,7 +1016,7 @@ commit_screen_list(struct ivi_layout *layout)
+ static void
+ commit_transition(struct ivi_layout* layout)
+ {
+- if(wl_list_empty(&layout->pending_transition_list)){
++ if (wl_list_empty(&layout->pending_transition_list)) {
+ return;
+ }
+
+@@ -1079,11 +1049,13 @@ send_prop(struct ivi_layout *layout)
+ struct ivi_layout_surface *ivisurf = NULL;
+
+ wl_list_for_each_reverse(ivilayer, &layout->layer_list, link) {
+- send_layer_prop(ivilayer);
++ if (ivilayer->event_mask)
++ send_layer_prop(ivilayer);
+ }
+
+ wl_list_for_each_reverse(ivisurf, &layout->surface_list, link) {
+- send_surface_prop(ivisurf);
++ if (ivisurf->event_mask)
++ send_surface_prop(ivisurf);
+ }
+ }
+
+@@ -1095,14 +1067,9 @@ clear_surface_pending_list(struct ivi_layout_layer *ivilayer)
+
+ wl_list_for_each_safe(surface_link, surface_next,
+ &ivilayer->pending.surface_list, pending.link) {
+- if (!wl_list_empty(&surface_link->pending.link)) {
+- wl_list_remove(&surface_link->pending.link);
+- }
+-
++ wl_list_remove(&surface_link->pending.link);
+ wl_list_init(&surface_link->pending.link);
+ }
+-
+- ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
+ }
+
+ static void
+@@ -1113,14 +1080,9 @@ clear_surface_order_list(struct ivi_layout_layer *ivilayer)
+
+ wl_list_for_each_safe(surface_link, surface_next,
+ &ivilayer->order.surface_list, order.link) {
+- if (!wl_list_empty(&surface_link->order.link)) {
+- wl_list_remove(&surface_link->order.link);
+- }
+-
++ wl_list_remove(&surface_link->order.link);
+ wl_list_init(&surface_link->order.link);
+ }
+-
+- ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
+ }
+
+ static void
+@@ -1287,9 +1249,7 @@ remove_notification(struct wl_list *listener_list, void *callback, void *userdat
+ continue;
+ }
+
+- if (!wl_list_empty(&listener->link)) {
+- wl_list_remove(&listener->link);
+- }
++ wl_list_remove(&listener->link);
+
+ free(notification->userdata);
+ free(notification);
+@@ -1480,6 +1440,12 @@ ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer)
+ return ivilayer->id_layer;
+ }
+
++static uint32_t
++ivi_layout_get_id_of_screen(struct ivi_layout_screen *iviscrn)
++{
++ return iviscrn->id_screen;
++}
++
+ static struct ivi_layout_layer *
+ ivi_layout_get_layer_from_id(uint32_t id_layer)
+ {
+@@ -1531,7 +1497,7 @@ ivi_layout_get_screen_resolution(struct ivi_layout_screen *iviscrn,
+ {
+ struct weston_output *output = NULL;
+
+- if (pWidth == NULL || pHeight == NULL) {
++ if (iviscrn == NULL || pWidth == NULL || pHeight == NULL) {
+ weston_log("ivi_layout_get_screen_resolution: invalid argument\n");
+ return IVI_FAILED;
+ }
+@@ -1605,7 +1571,7 @@ ivi_layout_get_screens(int32_t *pLength, struct ivi_layout_screen ***ppArray)
+
+ length = wl_list_length(&layout->screen_list);
+
+- if (length != 0){
++ if (length != 0) {
+ /* the Array must be free by module which called this function */
+ *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
+ if (*ppArray == NULL) {
+@@ -1639,7 +1605,7 @@ ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer,
+
+ length = wl_list_length(&ivilayer->screen_list);
+
+- if (length != 0){
++ if (length != 0) {
+ /* the Array must be free by module which called this function */
+ *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
+ if (*ppArray == NULL) {
+@@ -1672,7 +1638,7 @@ ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray)
+
+ length = wl_list_length(&layout->layer_list);
+
+- if (length != 0){
++ if (length != 0) {
+ /* the Array must be free by module which called this function */
+ *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
+ if (*ppArray == NULL) {
+@@ -1706,7 +1672,7 @@ ivi_layout_get_layers_on_screen(struct ivi_layout_screen *iviscrn,
+
+ length = wl_list_length(&iviscrn->order.layer_list);
+
+- if (length != 0){
++ if (length != 0) {
+ /* the Array must be free by module which called this function */
+ *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
+ if (*ppArray == NULL) {
+@@ -1714,7 +1680,7 @@ ivi_layout_get_layers_on_screen(struct ivi_layout_screen *iviscrn,
+ return IVI_FAILED;
+ }
+
+- wl_list_for_each(ivilayer, &iviscrn->order.layer_list, link) {
++ wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
+ (*ppArray)[n++] = ivilayer;
+ }
+ }
+@@ -1740,7 +1706,7 @@ ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf,
+
+ length = wl_list_length(&ivisurf->layer_list);
+
+- if (length != 0){
++ if (length != 0) {
+ /* the Array must be free by module which called this function */
+ *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
+ if (*ppArray == NULL) {
+@@ -1774,7 +1740,7 @@ ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray)
+
+ length = wl_list_length(&layout->surface_list);
+
+- if (length != 0){
++ if (length != 0) {
+ /* the Array must be free by module which called this function */
+ *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
+ if (*ppArray == NULL) {
+@@ -1836,6 +1802,7 @@ ivi_layout_layer_create_with_dimension(uint32_t id_layer,
+ ivilayer = get_layer(&layout->layer_list, id_layer);
+ if (ivilayer != NULL) {
+ weston_log("id_layer is already created\n");
++ ++ivilayer->ref_count;
+ return ivilayer;
+ }
+
+@@ -1845,7 +1812,7 @@ ivi_layout_layer_create_with_dimension(uint32_t id_layer,
+ return NULL;
+ }
+
+- wl_list_init(&ivilayer->link);
++ ivilayer->ref_count = 1;
+ wl_signal_init(&ivilayer->property_changed);
+ wl_list_init(&ivilayer->screen_list);
+ wl_list_init(&ivilayer->link_to_surface);
+@@ -1881,7 +1848,20 @@ ivi_layout_layer_remove_notification(struct ivi_layout_layer *ivilayer)
+ }
+
+ static void
+-ivi_layout_layer_remove(struct ivi_layout_layer *ivilayer)
++ivi_layout_layer_remove_notification_by_callback(struct ivi_layout_layer *ivilayer,
++ layer_property_notification_func callback,
++ void *userdata)
++{
++ if (ivilayer == NULL) {
++ weston_log("ivi_layout_layer_remove_notification_by_callback: invalid argument\n");
++ return;
++ }
++
++ remove_notification(&ivilayer->property_changed.listener_list, callback, userdata);
++}
++
++static void
++ivi_layout_layer_destroy(struct ivi_layout_layer *ivilayer)
+ {
+ struct ivi_layout *layout = get_instance();
+
+@@ -1890,20 +1870,18 @@ ivi_layout_layer_remove(struct ivi_layout_layer *ivilayer)
+ return;
+ }
+
++ if (--ivilayer->ref_count > 0)
++ return;
++
+ wl_signal_emit(&layout->layer_notification.removed, ivilayer);
+
+ clear_surface_pending_list(ivilayer);
+ clear_surface_order_list(ivilayer);
+
+- if (!wl_list_empty(&ivilayer->pending.link)) {
+- wl_list_remove(&ivilayer->pending.link);
+- }
+- if (!wl_list_empty(&ivilayer->order.link)) {
+- wl_list_remove(&ivilayer->order.link);
+- }
+- if (!wl_list_empty(&ivilayer->link)) {
+- wl_list_remove(&ivilayer->link);
+- }
++ wl_list_remove(&ivilayer->pending.link);
++ wl_list_remove(&ivilayer->order.link);
++ wl_list_remove(&ivilayer->link);
++
+ remove_orderlayer_from_screen(ivilayer);
+ remove_link_to_surface(ivilayer);
+ ivi_layout_layer_remove_notification(ivilayer);
+@@ -1925,7 +1903,10 @@ ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer,
+ prop = &ivilayer->pending.prop;
+ prop->visibility = newVisibility;
+
+- ivilayer->event_mask |= IVI_NOTIFICATION_VISIBILITY;
++ if (ivilayer->prop.visibility != newVisibility)
++ ivilayer->event_mask |= IVI_NOTIFICATION_VISIBILITY;
++ else
++ ivilayer->event_mask &= ~IVI_NOTIFICATION_VISIBILITY;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -1947,7 +1928,9 @@ ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
+ {
+ struct ivi_layout_layer_properties *prop = NULL;
+
+- if (ivilayer == NULL) {
++ if (ivilayer == NULL ||
++ opacity < wl_fixed_from_double(0.0) ||
++ wl_fixed_from_double(1.0) < opacity) {
+ weston_log("ivi_layout_layer_set_opacity: invalid argument\n");
+ return IVI_FAILED;
+ }
+@@ -1955,7 +1938,10 @@ ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
+ prop = &ivilayer->pending.prop;
+ prop->opacity = opacity;
+
+- ivilayer->event_mask |= IVI_NOTIFICATION_OPACITY;
++ if (ivilayer->prop.opacity != opacity)
++ ivilayer->event_mask |= IVI_NOTIFICATION_OPACITY;
++ else
++ ivilayer->event_mask &= ~IVI_NOTIFICATION_OPACITY;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -1989,7 +1975,12 @@ ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer,
+ prop->source_width = width;
+ prop->source_height = height;
+
+- ivilayer->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
++ if (ivilayer->prop.source_x != x || ivilayer->prop.source_y != y ||
++ ivilayer->prop.source_width != width ||
++ ivilayer->prop.source_height != height)
++ ivilayer->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
++ else
++ ivilayer->event_mask &= ~IVI_NOTIFICATION_SOURCE_RECT;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2012,7 +2003,12 @@ ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer,
+ prop->dest_width = width;
+ prop->dest_height = height;
+
+- ivilayer->event_mask |= IVI_NOTIFICATION_DEST_RECT;
++ if (ivilayer->prop.dest_x != x || ivilayer->prop.dest_y != y ||
++ ivilayer->prop.dest_width != width ||
++ ivilayer->prop.dest_height != height)
++ ivilayer->event_mask |= IVI_NOTIFICATION_DEST_RECT;
++ else
++ ivilayer->event_mask &= ~IVI_NOTIFICATION_DEST_RECT;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2048,7 +2044,11 @@ ivi_layout_layer_set_dimension(struct ivi_layout_layer *ivilayer,
+ prop->dest_width = dest_width;
+ prop->dest_height = dest_height;
+
+- ivilayer->event_mask |= IVI_NOTIFICATION_DIMENSION;
++ if (ivilayer->prop.dest_width != dest_width ||
++ ivilayer->prop.dest_height != dest_height)
++ ivilayer->event_mask |= IVI_NOTIFICATION_DIMENSION;
++ else
++ ivilayer->event_mask &= ~IVI_NOTIFICATION_DIMENSION;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2083,7 +2083,10 @@ ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer,
+ prop->dest_x = dest_x;
+ prop->dest_y = dest_y;
+
+- ivilayer->event_mask |= IVI_NOTIFICATION_POSITION;
++ if (ivilayer->prop.dest_x != dest_x || ivilayer->prop.dest_y != dest_y)
++ ivilayer->event_mask |= IVI_NOTIFICATION_POSITION;
++ else
++ ivilayer->event_mask &= ~IVI_NOTIFICATION_POSITION;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2102,7 +2105,10 @@ ivi_layout_layer_set_orientation(struct ivi_layout_layer *ivilayer,
+ prop = &ivilayer->pending.prop;
+ prop->orientation = orientation;
+
+- ivilayer->event_mask |= IVI_NOTIFICATION_ORIENTATION;
++ if (ivilayer->prop.orientation != orientation)
++ ivilayer->event_mask |= IVI_NOTIFICATION_ORIENTATION;
++ else
++ ivilayer->event_mask &= ~IVI_NOTIFICATION_ORIENTATION;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2134,17 +2140,7 @@ ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
+ return IVI_FAILED;
+ }
+
+- if (pSurface == NULL) {
+- wl_list_for_each_safe(ivisurf, next, &ivilayer->pending.surface_list, pending.link) {
+- if (!wl_list_empty(&ivisurf->pending.link)) {
+- wl_list_remove(&ivisurf->pending.link);
+- }
+-
+- wl_list_init(&ivisurf->pending.link);
+- }
+- ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
+- return IVI_SUCCEEDED;
+- }
++ clear_surface_pending_list(ivilayer);
+
+ for (i = 0; i < number; i++) {
+ id_surface = &pSurface[i]->id_surface;
+@@ -2154,17 +2150,14 @@ ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
+ continue;
+ }
+
+- if (!wl_list_empty(&ivisurf->pending.link)) {
+- wl_list_remove(&ivisurf->pending.link);
+- }
+- wl_list_init(&ivisurf->pending.link);
++ wl_list_remove(&ivisurf->pending.link);
+ wl_list_insert(&ivilayer->pending.surface_list,
+ &ivisurf->pending.link);
+ break;
+ }
+ }
+
+- ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
++ ivilayer->order.dirty = 1;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2183,7 +2176,10 @@ ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf,
+ prop = &ivisurf->pending.prop;
+ prop->visibility = newVisibility;
+
+- ivisurf->event_mask |= IVI_NOTIFICATION_VISIBILITY;
++ if (ivisurf->prop.visibility != newVisibility)
++ ivisurf->event_mask |= IVI_NOTIFICATION_VISIBILITY;
++ else
++ ivisurf->event_mask &= ~IVI_NOTIFICATION_VISIBILITY;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2205,7 +2201,9 @@ ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
+ {
+ struct ivi_layout_surface_properties *prop = NULL;
+
+- if (ivisurf == NULL) {
++ if (ivisurf == NULL ||
++ opacity < wl_fixed_from_double(0.0) ||
++ wl_fixed_from_double(1.0) < opacity) {
+ weston_log("ivi_layout_surface_set_opacity: invalid argument\n");
+ return IVI_FAILED;
+ }
+@@ -2213,7 +2211,10 @@ ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
+ prop = &ivisurf->pending.prop;
+ prop->opacity = opacity;
+
+- ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY;
++ if (ivisurf->prop.opacity != opacity)
++ ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY;
++ else
++ ivisurf->event_mask &= ~IVI_NOTIFICATION_OPACITY;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2251,7 +2252,12 @@ ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
+ prop->dest_width = width;
+ prop->dest_height = height;
+
+- ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT;
++ if (ivisurf->prop.dest_x != x || ivisurf->prop.dest_y != y ||
++ ivisurf->prop.dest_width != width ||
++ ivisurf->prop.dest_height != height)
++ ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT;
++ else
++ ivisurf->event_mask &= ~IVI_NOTIFICATION_DEST_RECT;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2271,7 +2277,11 @@ ivi_layout_surface_set_dimension(struct ivi_layout_surface *ivisurf,
+ prop->dest_width = dest_width;
+ prop->dest_height = dest_height;
+
+- ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION;
++ if (ivisurf->prop.dest_width != dest_width ||
++ ivisurf->prop.dest_height != dest_height)
++ ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION;
++ else
++ ivisurf->event_mask &= ~IVI_NOTIFICATION_DIMENSION;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2306,7 +2316,10 @@ ivi_layout_surface_set_position(struct ivi_layout_surface *ivisurf,
+ prop->dest_x = dest_x;
+ prop->dest_y = dest_y;
+
+- ivisurf->event_mask |= IVI_NOTIFICATION_POSITION;
++ if (ivisurf->prop.dest_x != dest_x || ivisurf->prop.dest_y != dest_y)
++ ivisurf->event_mask |= IVI_NOTIFICATION_POSITION;
++ else
++ ivisurf->event_mask &= ~IVI_NOTIFICATION_POSITION;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2340,7 +2353,10 @@ ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf,
+ prop = &ivisurf->pending.prop;
+ prop->orientation = orientation;
+
+- ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION;
++ if (ivisurf->prop.orientation != orientation)
++ ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION;
++ else
++ ivisurf->event_mask &= ~IVI_NOTIFICATION_ORIENTATION;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2378,17 +2394,14 @@ ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn,
+
+ wl_list_for_each_safe(ivilayer, next, &layout->layer_list, link) {
+ if (ivilayer->id_layer == addlayer->id_layer) {
+- if (!wl_list_empty(&ivilayer->pending.link)) {
+- wl_list_remove(&ivilayer->pending.link);
+- }
+- wl_list_init(&ivilayer->pending.link);
++ wl_list_remove(&ivilayer->pending.link);
+ wl_list_insert(&iviscrn->pending.layer_list,
+ &ivilayer->pending.link);
+ break;
+ }
+ }
+
+- iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
++ iviscrn->order.dirty = 1;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2411,23 +2424,11 @@ ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn,
+
+ wl_list_for_each_safe(ivilayer, next,
+ &iviscrn->pending.layer_list, pending.link) {
++ wl_list_remove(&ivilayer->pending.link);
+ wl_list_init(&ivilayer->pending.link);
+ }
+
+- wl_list_init(&iviscrn->pending.layer_list);
+-
+- if (pLayer == NULL) {
+- wl_list_for_each_safe(ivilayer, next, &iviscrn->pending.layer_list, pending.link) {
+- if (!wl_list_empty(&ivilayer->pending.link)) {
+- wl_list_remove(&ivilayer->pending.link);
+- }
+-
+- wl_list_init(&ivilayer->pending.link);
+- }
+-
+- iviscrn->event_mask |= IVI_NOTIFICATION_REMOVE;
+- return IVI_SUCCEEDED;
+- }
++ assert(wl_list_empty(&iviscrn->pending.layer_list));
+
+ for (i = 0; i < number; i++) {
+ id_layer = &pLayer[i]->id_layer;
+@@ -2436,17 +2437,14 @@ ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn,
+ continue;
+ }
+
+- if (!wl_list_empty(&ivilayer->pending.link)) {
+- wl_list_remove(&ivilayer->pending.link);
+- }
+- wl_list_init(&ivilayer->pending.link);
++ wl_list_remove(&ivilayer->pending.link);
+ wl_list_insert(&iviscrn->pending.layer_list,
+ &ivilayer->pending.link);
+ break;
+ }
+ }
+
+- iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
++ iviscrn->order.dirty = 1;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2555,17 +2553,14 @@ ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer,
+
+ wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
+ if (ivisurf->id_surface == addsurf->id_surface) {
+- if (!wl_list_empty(&ivisurf->pending.link)) {
+- wl_list_remove(&ivisurf->pending.link);
+- }
+- wl_list_init(&ivisurf->pending.link);
++ wl_list_remove(&ivisurf->pending.link);
+ wl_list_insert(&ivilayer->pending.surface_list,
+ &ivisurf->pending.link);
+ break;
+ }
+ }
+
+- ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
++ ivilayer->order.dirty = 1;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2585,15 +2580,13 @@ ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer,
+ wl_list_for_each_safe(ivisurf, next,
+ &ivilayer->pending.surface_list, pending.link) {
+ if (ivisurf->id_surface == remsurf->id_surface) {
+- if (!wl_list_empty(&ivisurf->pending.link)) {
+- wl_list_remove(&ivisurf->pending.link);
+- }
++ wl_list_remove(&ivisurf->pending.link);
+ wl_list_init(&ivisurf->pending.link);
+ break;
+ }
+ }
+
+- remsurf->event_mask |= IVI_NOTIFICATION_REMOVE;
++ ivilayer->order.dirty = 1;
+ }
+
+ static int32_t
+@@ -2614,7 +2607,12 @@ ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf,
+ prop->source_width = width;
+ prop->source_height = height;
+
+- ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
++ if (ivisurf->prop.source_x != x || ivisurf->prop.source_y != y ||
++ ivisurf->prop.source_width != width ||
++ ivisurf->prop.source_height != height)
++ ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
++ else
++ ivisurf->event_mask &= ~IVI_NOTIFICATION_SOURCE_RECT;
+
+ return IVI_SUCCEEDED;
+ }
+@@ -2731,7 +2729,7 @@ ivi_layout_get_weston_view(struct ivi_layout_surface *surface)
+ {
+ struct weston_view *tmpview = NULL;
+
+- if(surface == NULL)
++ if (surface == NULL)
+ return NULL;
+
+ wl_list_for_each(tmpview, &surface->surface->views, surface_link)
+@@ -2796,7 +2794,6 @@ ivi_layout_surface_create(struct weston_surface *wl_surface,
+ return NULL;
+ }
+
+- wl_list_init(&ivisurf->link);
+ wl_signal_init(&ivisurf->property_changed);
+ wl_signal_init(&ivisurf->configured);
+ wl_list_init(&ivisurf->layer_list);
+@@ -2804,10 +2801,6 @@ ivi_layout_surface_create(struct weston_surface *wl_surface,
+ ivisurf->layout = layout;
+
+ ivisurf->surface = wl_surface;
+- ivisurf->surface_destroy_listener.notify =
+- westonsurface_destroy_from_ivisurface;
+- wl_resource_add_destroy_listener(wl_surface->resource,
+- &ivisurf->surface_destroy_listener);
+
+ tmpview = weston_view_create(wl_surface);
+ if (tmpview == NULL) {
+@@ -2817,17 +2810,8 @@ ivi_layout_surface_create(struct weston_surface *wl_surface,
+ ivisurf->surface->width_from_buffer = 0;
+ ivisurf->surface->height_from_buffer = 0;
+
+- weston_matrix_init(&ivisurf->surface_rotation.matrix);
+- weston_matrix_init(&ivisurf->layer_rotation.matrix);
+- weston_matrix_init(&ivisurf->surface_pos.matrix);
+- weston_matrix_init(&ivisurf->layer_pos.matrix);
+- weston_matrix_init(&ivisurf->scaling.matrix);
+-
+- wl_list_init(&ivisurf->surface_rotation.link);
+- wl_list_init(&ivisurf->layer_rotation.link);
+- wl_list_init(&ivisurf->surface_pos.link);
+- wl_list_init(&ivisurf->layer_pos.link);
+- wl_list_init(&ivisurf->scaling.link);
++ weston_matrix_init(&ivisurf->transform.matrix);
++ wl_list_init(&ivisurf->transform.link);
+
+ init_surface_properties(&ivisurf->prop);
+ ivisurf->event_mask = 0;
+@@ -2927,7 +2911,7 @@ static struct ivi_controller_interface ivi_controller_interface = {
+ .add_notification_remove_layer = ivi_layout_add_notification_remove_layer,
+ .remove_notification_remove_layer = ivi_layout_remove_notification_remove_layer,
+ .layer_create_with_dimension = ivi_layout_layer_create_with_dimension,
+- .layer_remove = ivi_layout_layer_remove,
++ .layer_destroy = ivi_layout_layer_destroy,
+ .get_layers = ivi_layout_get_layers,
+ .get_id_of_layer = ivi_layout_get_id_of_layer,
+ .get_layer_from_id = ivi_layout_get_layer_from_id,
+@@ -2954,7 +2938,7 @@ static struct ivi_controller_interface ivi_controller_interface = {
+ .layer_set_transition = ivi_layout_layer_set_transition,
+
+ /**
+- * screen controller interfaces
++ * screen controller interfaces part1
+ */
+ .get_screen_from_id = ivi_layout_get_screen_from_id,
+ .get_screen_resolution = ivi_layout_get_screen_resolution,
+@@ -2975,6 +2959,17 @@ static struct ivi_controller_interface ivi_controller_interface = {
+ */
+ .surface_get_size = ivi_layout_surface_get_size,
+ .surface_dump = ivi_layout_surface_dump,
++
++ /**
++ * remove notification by callback on property changes of ivi_surface/layer
++ */
++ .surface_remove_notification_by_callback = ivi_layout_surface_remove_notification_by_callback,
++ .layer_remove_notification_by_callback = ivi_layout_layer_remove_notification_by_callback,
++
++ /**
++ * screen controller interfaces part2
++ */
++ .get_id_of_screen = ivi_layout_get_id_of_screen
+ };
+
+ int
+diff --git a/ivi-shell/ivi-shell.c b/ivi-shell/ivi-shell.c
+index 4a688cc..4c63410 100644
+--- a/ivi-shell/ivi-shell.c
++++ b/ivi-shell/ivi-shell.c
+@@ -1,23 +1,26 @@
+ /*
+ * Copyright (C) 2013 DENSO CORPORATION
+ *
+- * Permission to use, copy, modify, distribute, and sell this software and
+- * its documentation for any purpose is hereby granted without fee, provided
+- * that the above copyright notice appear in all copies and that both that
+- * copyright notice and this permission notice appear in supporting
+- * documentation, and that the name of the copyright holders not be used in
+- * advertising or publicity pertaining to distribution of the software
+- * without specific, written prior permission. The copyright holders make
+- * no representations about the suitability of this software for any
+- * purpose. It is provided "as is" without express or implied warranty.
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
+ *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial
++ * portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
+ */
+
+ /*
+@@ -126,6 +129,22 @@ ivi_shell_surface_configure(struct weston_surface *surface,
+ }
+ }
+
++static void
++layout_surface_cleanup(struct ivi_shell_surface *ivisurf)
++{
++ assert(ivisurf->layout_surface != NULL);
++
++ ivi_layout_surface_destroy(ivisurf->layout_surface);
++ ivisurf->layout_surface = NULL;
++
++ ivisurf->surface->configure = NULL;
++ ivisurf->surface->configure_private = NULL;
++ ivisurf->surface = NULL;
++
++ // destroy weston_surface destroy signal.
++ wl_list_remove(&ivisurf->surface_destroy_listener.link);
++}
++
+ /*
+ * The ivi_surface wl_resource destructor.
+ *
+@@ -135,9 +154,18 @@ static void
+ shell_destroy_shell_surface(struct wl_resource *resource)
+ {
+ struct ivi_shell_surface *ivisurf = wl_resource_get_user_data(resource);
+- if (ivisurf != NULL) {
+- ivisurf->resource = NULL;
+- }
++
++ if (ivisurf == NULL)
++ return;
++
++ assert(ivisurf->resource == resource);
++
++ if (ivisurf->layout_surface != NULL)
++ layout_surface_cleanup(ivisurf);
++
++ wl_list_remove(&ivisurf->link);
++
++ free(ivisurf);
+ }
+
+ /* Gets called through the weston_surface destroy signal. */
+@@ -150,21 +178,8 @@ shell_handle_surface_destroy(struct wl_listener *listener, void *data)
+
+ assert(ivisurf != NULL);
+
+- if (ivisurf->surface!=NULL) {
+- ivisurf->surface->configure = NULL;
+- ivisurf->surface->configure_private = NULL;
+- ivisurf->surface = NULL;
+- }
+-
+- wl_list_remove(&ivisurf->surface_destroy_listener.link);
+- wl_list_remove(&ivisurf->link);
+-
+- if (ivisurf->resource != NULL) {
+- wl_resource_set_user_data(ivisurf->resource, NULL);
+- ivisurf->resource = NULL;
+- }
+- free(ivisurf);
+-
++ if (ivisurf->layout_surface != NULL)
++ layout_surface_cleanup(ivisurf);
+ }
+
+ /* Gets called, when a client sends ivi_surface.destroy request. */
+@@ -219,7 +234,7 @@ application_surface_create(struct wl_client *client,
+ layout_surface = ivi_layout_surface_create(weston_surface, id_surface);
+
+ /* check if id_ivi is already used for wl_surface*/
+- if (layout_surface == NULL){
++ if (layout_surface == NULL) {
+ wl_resource_post_error(resource,
+ IVI_APPLICATION_ERROR_IVI_ID,
+ "surface_id is already assigned "
+@@ -338,8 +353,8 @@ shell_destroy(struct wl_listener *listener, void *data)
+ }
+
+ static void
+-terminate_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
+- void *data)
++terminate_binding(struct weston_seat *seat, uint32_t time,
++ uint32_t key, void *data)
+ {
+ struct weston_compositor *compositor = data;
+
+@@ -423,6 +438,8 @@ module_init(struct weston_compositor *compositor,
+ if (input_panel_setup(shell) < 0)
+ goto out_settings;
+
++ text_backend_init(compositor);
++
+ if (wl_global_create(compositor->wl_display,
+ &ivi_application_interface, 1,
+ shell, bind_ivi_application) == NULL)
+diff --git a/ivi-shell/ivi-shell.h b/ivi-shell/ivi-shell.h
+index 2f42173..9a05eb2 100644
+--- a/ivi-shell/ivi-shell.h
++++ b/ivi-shell/ivi-shell.h
+@@ -1,23 +1,26 @@
+ /*
+ * Copyright (C) 2013 DENSO CORPORATION
+ *
+- * Permission to use, copy, modify, distribute, and sell this software and
+- * its documentation for any purpose is hereby granted without fee, provided
+- * that the above copyright notice appear in all copies and that both that
+- * copyright notice and this permission notice appear in supporting
+- * documentation, and that the name of the copyright holders not be used in
+- * advertising or publicity pertaining to distribution of the software
+- * without specific, written prior permission. The copyright holders make
+- * no representations about the suitability of this software for any
+- * purpose. It is provided "as is" without express or implied warranty.
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
+ *
+- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial
++ * portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
+ */
+
+ #include <stdbool.h>
+@@ -32,6 +35,8 @@ struct ivi_shell
+
+ struct wl_list ivi_surface_list; /* struct ivi_shell_surface::link */
+
++ struct text_backend *text_backend;
++
+ struct wl_listener show_input_panel_listener;
+ struct wl_listener hide_input_panel_listener;
+ struct wl_listener update_input_panel_listener;
+--
+1.8.3.1
+