--- /dev/null
+/*
+ * 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.
+ *
+ * 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 ivi-layout library supports API set of controlling properties of
+ * surface and layer which groups surfaces. An unique ID whose type is integer
+ * is required to create surface and layer. With the unique ID, surface and
+ * layer are identified to control them. The API set consists of APIs to control
+ * properties of surface and layers about followings,
+ * - visibility.
+ * - opacity.
+ * - clipping (x,y,width,height).
+ * - position and size of it to be displayed.
+ * - orientation per 90 degree.
+ * - add or remove surfaces to a layer.
+ * - order of surfaces/layers in layer/screen to be displayed.
+ * - commit to apply property changes.
+ * - notifications of property change.
+ *
+ * Management of surfaces and layers grouping these surfaces are common
+ * way in In-Vehicle Infotainment system, which integrate several domains
+ * in one system. A layer is allocated to a domain in order to control
+ * application surfaces grouped to the layer all together.
+ *
+ * This API and ABI follow following specifications.
+ * http://projects.genivi.org/wayland-ivi-extension/layer-manager-apis
+ */
+
+#ifndef _IVI_LAYOUT_EXPORT_H_
+#define _IVI_LAYOUT_EXPORT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "stdbool.h"
+#include "compositor.h"
+
+#define IVI_SUCCEEDED (0)
+#define IVI_FAILED (-1)
+
+struct ivi_layout_layer;
+struct ivi_layout_screen;
+struct ivi_layout_surface;
+
+struct ivi_layout_surface_properties
+{
+ wl_fixed_t opacity;
+ int32_t source_x;
+ int32_t source_y;
+ int32_t source_width;
+ int32_t source_height;
+ int32_t start_x;
+ int32_t start_y;
+ int32_t start_width;
+ int32_t start_height;
+ int32_t dest_x;
+ int32_t dest_y;
+ int32_t dest_width;
+ int32_t dest_height;
+ enum wl_output_transform orientation;
+ bool visibility;
+ int32_t transition_type;
+ uint32_t transition_duration;
+};
+
+struct ivi_layout_layer_properties
+{
+ wl_fixed_t opacity;
+ int32_t source_x;
+ int32_t source_y;
+ int32_t source_width;
+ int32_t source_height;
+ int32_t dest_x;
+ int32_t dest_y;
+ int32_t dest_width;
+ int32_t dest_height;
+ enum wl_output_transform orientation;
+ uint32_t visibility;
+ int32_t transition_type;
+ uint32_t transition_duration;
+ double start_alpha;
+ double end_alpha;
+ uint32_t is_fade_in;
+};
+
+enum ivi_layout_notification_mask {
+ IVI_NOTIFICATION_NONE = 0,
+ IVI_NOTIFICATION_OPACITY = (1 << 1),
+ IVI_NOTIFICATION_SOURCE_RECT = (1 << 2),
+ IVI_NOTIFICATION_DEST_RECT = (1 << 3),
+ IVI_NOTIFICATION_DIMENSION = (1 << 4),
+ IVI_NOTIFICATION_POSITION = (1 << 5),
+ IVI_NOTIFICATION_ORIENTATION = (1 << 6),
+ IVI_NOTIFICATION_VISIBILITY = (1 << 7),
+ IVI_NOTIFICATION_PIXELFORMAT = (1 << 8),
+ IVI_NOTIFICATION_ADD = (1 << 9),
+ IVI_NOTIFICATION_REMOVE = (1 << 10),
+ IVI_NOTIFICATION_CONFIGURE = (1 << 11),
+ IVI_NOTIFICATION_ALL = 0xFFFF
+};
+
+enum ivi_layout_transition_type{
+ IVI_LAYOUT_TRANSITION_NONE,
+ IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,
+ IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY,
+ IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY,
+ IVI_LAYOUT_TRANSITION_LAYER_FADE,
+ IVI_LAYOUT_TRANSITION_LAYER_MOVE,
+ IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
+ IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
+ IVI_LAYOUT_TRANSITION_VIEW_RESIZE,
+ IVI_LAYOUT_TRANSITION_VIEW_FADE,
+ IVI_LAYOUT_TRANSITION_MAX,
+};
+
+typedef void (*layer_property_notification_func)(
+ struct ivi_layout_layer *ivilayer,
+ const struct ivi_layout_layer_properties *,
+ enum ivi_layout_notification_mask mask,
+ void *userdata);
+
+typedef void (*surface_property_notification_func)(
+ struct ivi_layout_surface *ivisurf,
+ const struct ivi_layout_surface_properties *,
+ enum ivi_layout_notification_mask mask,
+ void *userdata);
+
+typedef void (*layer_create_notification_func)(
+ struct ivi_layout_layer *ivilayer,
+ void *userdata);
+
+typedef void (*layer_remove_notification_func)(
+ struct ivi_layout_layer *ivilayer,
+ void *userdata);
+
+typedef void (*surface_create_notification_func)(
+ struct ivi_layout_surface *ivisurf,
+ void *userdata);
+
+typedef void (*surface_remove_notification_func)(
+ struct ivi_layout_surface *ivisurf,
+ void *userdata);
+
+typedef void (*surface_configure_notification_func)(
+ struct ivi_layout_surface *ivisurf,
+ void *userdata);
+
+typedef void (*ivi_controller_surface_content_callback)(
+ struct ivi_layout_surface *ivisurf,
+ int32_t content,
+ void *userdata);
+
+/**
+ * \brief register for notification when layer is created
+ */
+int32_t
+ivi_layout_add_notification_create_layer(
+ layer_create_notification_func callback,
+ void *userdata);
+
+void
+ivi_layout_remove_notification_create_layer(
+ layer_create_notification_func callback,
+ void *userdata);
+
+/**
+ * \brief register for notification when layer is removed
+ */
+int32_t
+ivi_layout_add_notification_remove_layer(
+ layer_remove_notification_func callback,
+ void *userdata);
+
+void
+ivi_layout_remove_notification_remove_layer(
+ layer_remove_notification_func callback,
+ void *userdata);
+
+/**
+ * \brief register for notification when surface is created
+ */
+int32_t
+ivi_layout_add_notification_create_surface(
+ surface_create_notification_func callback,
+ void *userdata);
+
+void
+ivi_layout_remove_notification_create_surface(
+ surface_create_notification_func callback,
+ void *userdata);
+
+/**
+ * \brief register for notification when surface is removed
+ */
+int32_t
+ivi_layout_add_notification_remove_surface(
+ surface_remove_notification_func callback,
+ void *userdata);
+
+void
+ivi_layout_remove_notification_remove_surface(
+ surface_remove_notification_func callback,
+ void *userdata);
+
+/**
+ * \brief register for notification when surface is configured
+ */
+int32_t
+ivi_layout_add_notification_configure_surface(
+ surface_configure_notification_func callback,
+ void *userdata);
+
+void
+ivi_layout_remove_notification_configure_surface(
+ surface_configure_notification_func callback,
+ void *userdata);
+
+/**
+ * \brief get id of surface from ivi_layout_surface
+ *
+ * \return id of surface
+ */
+uint32_t
+ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf);
+
+/**
+ * \brief get id of layer from ivi_layout_layer
+ *
+ *
+ * \return id of layer
+ */
+uint32_t
+ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer);
+
+/**
+ * \brief get ivi_layout_surface from id of surface
+ *
+ * \return (struct ivi_layout_surface *)
+ * if the method call was successful
+ * \return NULL if the method call was failed
+ */
+struct ivi_layout_surface *
+ivi_layout_get_surface_from_id(uint32_t id_surface);
+
+/**
+ * \brief get ivi_layout_screen from id of screen
+ *
+ * \return (struct ivi_layout_screen *)
+ * if the method call was successful
+ * \return NULL if the method call was failed
+ */
+struct ivi_layout_screen *
+ivi_layout_get_screen_from_id(uint32_t id_screen);
+
+/**
+ * \brief Get the screen resolution of a specific screen
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_get_screen_resolution(struct ivi_layout_screen *iviscrn,
+ int32_t *pWidth,
+ int32_t *pHeight);
+
+/**
+ * \brief Set an observer callback for surface content status change.
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_surface_set_content_observer(
+ struct ivi_layout_surface *ivisurf,
+ ivi_controller_surface_content_callback callback,
+ void* userdata);
+
+/**
+ * \brief Get the layer properties
+ *
+ * \return (const struct ivi_layout_layer_properties *)
+ * if the method call was successful
+ * \return NULL if the method call was failed
+ */
+const struct ivi_layout_layer_properties *
+ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer);
+
+/**
+ * \brief Get the screens
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_get_screens(int32_t *pLength, struct ivi_layout_screen ***ppArray);
+
+/**
+ * \brief Get the screens under the given layer
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer,
+ int32_t *pLength,
+ struct ivi_layout_screen ***ppArray);
+
+/**
+ * \brief Get all Layers which are currently registered and managed
+ * by the services
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray);
+
+/**
+ * \brief Get all Layers under the given surface
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf,
+ int32_t *pLength,
+ struct ivi_layout_layer ***ppArray);
+
+/**
+ * \brief Get all Surfaces which are currently registered and managed
+ * by the services
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray);
+
+/**
+ * \brief Create a layer which should be managed by the service
+ *
+ * \return (struct ivi_layout_layer *)
+ * if the method call was successful
+ * \return NULL if the method call was failed
+ */
+struct ivi_layout_layer *
+ivi_layout_layer_create_with_dimension(uint32_t id_layer,
+ int32_t width, int32_t height);
+
+/**
+ * \brief Removes a layer which is currently managed by the service
+ */
+void
+ivi_layout_layer_remove(struct ivi_layout_layer *ivilayer);
+
+/**
+ * \brief Set the visibility of a layer. If a layer is not visible, the
+ * layer and its surfaces will not be rendered.
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer,
+ bool newVisibility);
+
+/**
+ * \brief Set the opacity of a layer.
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
+ wl_fixed_t opacity);
+
+/**
+ * \brief Get the opacity of a layer.
+ *
+ * \return opacity if the method call was successful
+ * \return wl_fixed_from_double(0.0) if the method call was failed
+ */
+wl_fixed_t
+ivi_layout_layer_get_opacity(struct ivi_layout_layer *ivilayer);
+
+/**
+ * \brief Set the area of a layer which should be used for the rendering.
+ *
+ * Only this part will be visible.
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height);
+
+/**
+ * \brief Set the destination area on the display for a layer.
+ *
+ * The layer will be scaled and positioned to this rectangle
+ * for rendering
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height);
+
+/**
+ * \brief Get the horizontal and vertical position of the layer.
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_layer_get_position(struct ivi_layout_layer *ivilayer,
+ int32_t *dest_x, int32_t *dest_y);
+
+/**
+ * \brief Sets the horizontal and vertical position of the layer.
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer,
+ int32_t dest_x, int32_t dest_y);
+
+/**
+ * \brief Sets the orientation of a layer.
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_layer_set_orientation(struct ivi_layout_layer *ivilayer,
+ enum wl_output_transform orientation);
+
+/**
+ * \brief Sets render order of surfaces within one layer
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
+ struct ivi_layout_surface **pSurface,
+ int32_t number);
+
+/**
+ * \brief Set the visibility of a surface.
+ *
+ * If a surface is not visible it will not be rendered.
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf,
+ bool newVisibility);
+
+/**
+ * \brief Get the visibility of a surface.
+ *
+ * If a surface is not visible it will not be rendered.
+ *
+ * \return true if surface is visible
+ * \return false if surface is invisible or the method call was failed
+ */
+bool
+ivi_layout_surface_get_visibility(struct ivi_layout_surface *ivisurf);
+
+/**
+ * \brief Set the opacity of a surface.
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
+ wl_fixed_t opacity);
+
+/**
+ * \brief Get the opacity of a surface.
+ *
+ * \return opacity if the method call was successful
+ * \return wl_fixed_from_double(0.0) if the method call was failed
+ */
+wl_fixed_t
+ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf);
+
+/**
+ * \brief Set the destination area of a surface within a layer for rendering.
+ *
+ * The surface will be scaled to this rectangle for rendering.
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height);
+
+/**
+ * \brief Sets the orientation of a surface.
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf,
+ enum wl_output_transform orientation);
+
+/**
+ * \brief Add a layer to a screen which is currently managed by the service
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn,
+ struct ivi_layout_layer *addlayer);
+
+/**
+ * \brief Sets render order of layers on a display
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn,
+ struct ivi_layout_layer **pLayer,
+ const int32_t number);
+
+/**
+ * \brief register for notification on property changes of layer
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_layer_add_notification(struct ivi_layout_layer *ivilayer,
+ layer_property_notification_func callback,
+ void *userdata);
+
+/**
+ * \brief remove notification on property changes of layer
+ */
+void
+ivi_layout_layer_remove_notification(struct ivi_layout_layer *ivilayer);
+
+/**
+ * \brief register for notification on property changes of surface
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_surface_add_notification(struct ivi_layout_surface *ivisurf,
+ surface_property_notification_func callback,
+ void *userdata);
+
+/**
+ * \brief remove notification on property changes of surface
+ */
+void
+ivi_layout_surface_remove_notification(struct ivi_layout_surface *ivisurf);
+
+/**
+ * \brief Get the surface properties
+ *
+ * \return (const struct ivi_surface_layer_properties *)
+ * if the method call was successful
+ * \return NULL if the method call was failed
+ */
+const struct ivi_layout_surface_properties *
+ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf);
+
+/**
+ * \brief Add a surface to a layer which is currently managed by the service
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer,
+ struct ivi_layout_surface *addsurf);
+
+/**
+ * \brief Removes a surface from a layer which is currently managed by the service
+ */
+void
+ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer,
+ struct ivi_layout_surface *remsurf);
+
+/**
+ * \brief Set the area of a surface which should be used for the rendering.
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height);
+
+/**
+ * \brief get weston_output from ivi_layout_screen.
+ *
+ * \return (struct weston_output *)
+ * if the method call was successful
+ * \return NULL if the method call was failed
+ */
+struct weston_output *
+ivi_layout_screen_get_output(struct ivi_layout_screen *);
+
+struct weston_surface *
+ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf);
+
+int32_t
+ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer,
+ enum ivi_layout_transition_type type,
+ uint32_t duration);
+
+int32_t
+ivi_layout_layer_set_fade_info(struct ivi_layout_layer* layer,
+ uint32_t is_fade_in,
+ double start_alpha, double end_alpha);
+
+int32_t
+ivi_layout_surface_set_transition(struct ivi_layout_surface *ivisurf,
+ enum ivi_layout_transition_type type,
+ uint32_t duration);
+
+void
+ivi_layout_transition_layer_render_order(struct ivi_layout_layer* layer,
+ struct ivi_layout_surface** new_order,
+ uint32_t surface_num,
+ uint32_t duration);
+
+void
+ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer* layer);
+
+/**
+ * \brief Commit all changes and execute all enqueued commands since
+ * last commit.
+ *
+ * \return IVI_SUCCEEDED if the method call was successful
+ * \return IVI_FAILED if the method call was failed
+ */
+int32_t
+ivi_layout_commit_changes(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _IVI_LAYOUT_EXPORT_H_ */
--- /dev/null
+/*
+ * 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.
+ *
+ * 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.
+ */
+
+#include <time.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "ivi-layout-export.h"
+#include "ivi-layout-private.h"
+
+struct ivi_layout_transition;
+
+typedef void (*ivi_layout_transition_frame_func)(
+ struct ivi_layout_transition *transition);
+typedef void (*ivi_layout_transition_destroy_func)(
+ struct ivi_layout_transition *transition);
+typedef int32_t (*ivi_layout_is_transition_func)(void *private_data, void *id);
+
+struct ivi_layout_transition {
+ enum ivi_layout_transition_type type;
+ void *private_data;
+ void *user_data;
+
+ uint32_t time_start;
+ uint32_t time_duration;
+ uint32_t time_elapsed;
+ uint32_t is_done;
+ ivi_layout_is_transition_func is_transition_func;
+ ivi_layout_transition_frame_func frame_func;
+ ivi_layout_transition_destroy_func destroy_func;
+};
+
+struct transition_node {
+ struct ivi_layout_transition *transition;
+ struct wl_list link;
+};
+
+static void layout_transition_destroy(struct ivi_layout_transition *transition);
+
+static struct ivi_layout_transition *
+get_transition_from_type_and_id(enum ivi_layout_transition_type type,
+ void *id_data)
+{
+ struct ivi_layout *layout = get_instance();
+ struct transition_node *node;
+ struct ivi_layout_transition *tran;
+
+ wl_list_for_each(node, &layout->transitions->transition_list, link) {
+ tran = node->transition;
+
+ if (tran->type == type &&
+ tran->is_transition_func(tran->private_data, id_data))
+ return tran;
+ }
+
+ return NULL;
+}
+
+WL_EXPORT int32_t
+is_surface_transition(struct ivi_layout_surface *surface)
+{
+ struct ivi_layout *layout = get_instance();
+ struct transition_node *node;
+ struct ivi_layout_transition *tran;
+
+ wl_list_for_each(node, &layout->transitions->transition_list, link) {
+ tran = node->transition;
+
+ if ((tran->type == IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE ||
+ tran->type == IVI_LAYOUT_TRANSITION_VIEW_RESIZE) &&
+ tran->is_transition_func(tran->private_data, surface))
+ return 1;
+ }
+
+ return 0;
+}
+
+static void
+tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp)
+{
+ const double t = timestamp - transition->time_start;
+
+ if (transition->time_duration <= t) {
+ transition->time_elapsed = transition->time_duration;
+ transition->is_done = 1;
+ } else {
+ transition->time_elapsed = t;
+ }
+}
+
+static float time_to_nowpos(struct ivi_layout_transition *transition)
+{
+ return sin((float)transition->time_elapsed /
+ (float)transition->time_duration * M_PI_2);
+}
+
+static void
+do_transition_frame(struct ivi_layout_transition *transition,
+ uint32_t timestamp)
+{
+ if (0 == transition->time_start)
+ transition->time_start = timestamp;
+
+ tick_transition(transition, timestamp);
+ transition->frame_func(transition);
+
+ if (transition->is_done)
+ layout_transition_destroy(transition);
+}
+
+static int32_t
+layout_transition_frame(void *data)
+{
+ struct ivi_layout_transition_set *transitions = data;
+ uint32_t fps = 30;
+ struct timespec timestamp = {};
+ uint32_t msec = 0;
+ struct transition_node *node = NULL;
+ struct transition_node *next = NULL;
+
+ if (wl_list_empty(&transitions->transition_list)) {
+ wl_event_source_timer_update(transitions->event_source, 0);
+ return 1;
+ }
+
+ wl_event_source_timer_update(transitions->event_source, 1000 / fps);
+
+ clock_gettime(CLOCK_MONOTONIC, ×tamp);/* FIXME */
+ msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec);
+
+ wl_list_for_each_safe(node, next, &transitions->transition_list, link) {
+ do_transition_frame(node->transition, msec);
+ }
+
+ ivi_layout_commit_changes();
+ return 1;
+}
+
+WL_EXPORT struct ivi_layout_transition_set *
+ivi_layout_transition_set_create(struct weston_compositor *ec)
+{
+ struct ivi_layout_transition_set *transitions;
+ struct wl_event_loop *loop;
+
+ transitions = malloc(sizeof(*transitions));
+ if (transitions == NULL) {
+ weston_log("%s: memory allocation fails\n", __func__);
+ return NULL;
+ }
+
+ wl_list_init(&transitions->transition_list);
+
+ loop = wl_display_get_event_loop(ec->wl_display);
+ transitions->event_source =
+ wl_event_loop_add_timer(loop, layout_transition_frame,
+ transitions);
+
+ return transitions;
+}
+
+static void
+layout_transition_register(struct ivi_layout_transition *trans)
+{
+ struct ivi_layout *layout = get_instance();
+ struct transition_node *node;
+
+ node = malloc(sizeof(*node));
+ if (node == NULL) {
+ weston_log("%s: memory allocation fails\n", __func__);
+ return;
+ }
+
+ node->transition = trans;
+ wl_list_insert(&layout->pending_transition_list, &node->link);
+}
+
+static void
+remove_transition(struct ivi_layout *layout,
+ struct ivi_layout_transition *trans)
+{
+ struct transition_node *node;
+ struct transition_node *next;
+
+ wl_list_for_each_safe(node, next,
+ &layout->transitions->transition_list, link) {
+ if (node->transition == trans) {
+ wl_list_remove(&node->link);
+ free(node);
+ return;
+ }
+ }
+
+ wl_list_for_each_safe(node, next,
+ &layout->pending_transition_list, link) {
+ if (node->transition == trans) {
+ wl_list_remove(&node->link);
+ free(node);
+ return;
+ }
+ }
+}
+
+static void
+layout_transition_destroy(struct ivi_layout_transition *transition)
+{
+ struct ivi_layout *layout = get_instance();
+
+ remove_transition(layout, transition);
+ if(transition->destroy_func)
+ transition->destroy_func(transition);
+ free(transition);
+}
+
+static struct ivi_layout_transition *
+create_layout_transition(void)
+{
+ struct ivi_layout_transition *transition = malloc(sizeof(*transition));
+
+ if (transition == NULL) {
+ weston_log("%s: memory allocation fails\n", __func__);
+ return NULL;
+ }
+
+ transition->type = IVI_LAYOUT_TRANSITION_MAX;
+ transition->time_start = 0;
+ transition->time_duration = 300; /* 300ms */
+ transition->time_elapsed = 0;
+
+ transition->is_done = 0;
+
+ transition->private_data = NULL;
+ transition->user_data = NULL;
+
+ transition->frame_func = NULL;
+ transition->destroy_func = NULL;
+
+ return transition;
+}
+
+/* move and resize view transition */
+
+struct move_resize_view_data {
+ struct ivi_layout_surface *surface;
+ int32_t start_x;
+ int32_t start_y;
+ int32_t end_x;
+ int32_t end_y;
+ int32_t start_width;
+ int32_t start_height;
+ int32_t end_width;
+ int32_t end_height;
+};
+
+static void
+transition_move_resize_view_destroy(struct ivi_layout_transition *transition)
+{
+ struct move_resize_view_data *data =
+ (struct move_resize_view_data *)transition->private_data;
+ struct ivi_layout_surface *layout_surface = data->surface;
+
+ wl_signal_emit(&layout_surface->configured, layout_surface);
+
+ if (transition->private_data) {
+ free(transition->private_data);
+ transition->private_data = NULL;
+ }
+}
+
+static void
+transition_move_resize_view_user_frame(struct ivi_layout_transition *transition)
+{
+ struct move_resize_view_data *mrv = transition->private_data;
+ const double current = time_to_nowpos(transition);
+
+ const int32_t destx = mrv->start_x +
+ (mrv->end_x - mrv->start_x) * current;
+
+ const int32_t desty = mrv->start_y +
+ (mrv->end_y - mrv->start_y) * current;
+
+ const int32_t dest_width = mrv->start_width +
+ (mrv->end_width - mrv->start_width) * current;
+
+ const int32_t dest_height = mrv->start_height +
+ (mrv->end_height - mrv->start_height) * current;
+
+ ivi_layout_surface_set_destination_rectangle(mrv->surface,
+ destx, desty,
+ dest_width, dest_height);
+}
+
+static int32_t
+is_transition_move_resize_view_func(struct move_resize_view_data *data,
+ struct ivi_layout_surface *view)
+{
+ return data->surface == view;
+}
+
+static struct ivi_layout_transition *
+create_move_resize_view_transition(
+ struct ivi_layout_surface *surface,
+ int32_t start_x, int32_t start_y,
+ int32_t end_x, int32_t end_y,
+ int32_t start_width, int32_t start_height,
+ int32_t end_width, int32_t end_height,
+ ivi_layout_transition_frame_func frame_func,
+ ivi_layout_transition_destroy_func destroy_func,
+ uint32_t duration)
+{
+ struct ivi_layout_transition *transition = create_layout_transition();
+ struct move_resize_view_data *data = malloc(sizeof(*data));
+
+ if (data == NULL) {
+ weston_log("%s: memory allocation fails\n", __func__);
+ return NULL;
+ }
+
+ transition->type = IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE;
+ transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_resize_view_func;
+
+ transition->frame_func = frame_func;
+ transition->destroy_func = destroy_func;
+ transition->private_data = data;
+
+ if (duration != 0)
+ transition->time_duration = duration;
+
+ data->surface = surface;
+ data->start_x = start_x;
+ data->start_y = start_y;
+ data->end_x = end_x;
+ data->end_y = end_y;
+
+ data->start_width = start_width;
+ data->start_height = start_height;
+ data->end_width = end_width;
+ data->end_height = end_height;
+
+ return transition;
+}
+
+WL_EXPORT void
+ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface,
+ int32_t dest_x, int32_t dest_y,
+ int32_t dest_width, int32_t dest_height,
+ uint32_t duration)
+{
+ struct ivi_layout_transition *transition;
+ int32_t start_pos[2] = {
+ surface->pending.prop.start_x,
+ surface->pending.prop.start_y
+ };
+
+ int32_t start_size[2] = {
+ surface->pending.prop.start_width,
+ surface->pending.prop.start_height
+ };
+
+ transition = get_transition_from_type_and_id(
+ IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
+ surface);
+ if (transition) {
+ struct move_resize_view_data *data = transition->private_data;
+ transition->time_start = 0;
+ transition->time_duration = duration;
+
+ data->start_x = start_pos[0];
+ data->start_y = start_pos[1];
+ data->end_x = dest_x;
+ data->end_y = dest_y;
+
+ data->start_width = start_size[0];
+ data->start_height = start_size[1];
+ data->end_width = dest_width;
+ data->end_height = dest_height;
+ return;
+ }
+
+ transition = create_move_resize_view_transition(
+ surface,
+ start_pos[0], start_pos[1],
+ dest_x, dest_y,
+ start_size[0], start_size[1],
+ dest_width, dest_height,
+ transition_move_resize_view_user_frame,
+ transition_move_resize_view_destroy,
+ duration);
+
+ layout_transition_register(transition);
+}
+
+/* fade transition */
+struct fade_view_data {
+ struct ivi_layout_surface *surface;
+ double start_alpha;
+ double end_alpha;
+};
+
+struct store_alpha{
+ double alpha;
+};
+
+static void
+fade_view_user_frame(struct ivi_layout_transition *transition)
+{
+ struct fade_view_data *fade = transition->private_data;
+ struct ivi_layout_surface *surface = fade->surface;
+
+ const double current = time_to_nowpos(transition);
+ const double alpha = fade->start_alpha +
+ (fade->end_alpha - fade->start_alpha) * current;
+
+ ivi_layout_surface_set_opacity(surface, wl_fixed_from_double(alpha));
+ ivi_layout_surface_set_visibility(surface, true);
+}
+
+static int32_t
+is_transition_fade_view_func(struct fade_view_data *data,
+ struct ivi_layout_surface *view)
+{
+ return data->surface == view;
+}
+
+static struct ivi_layout_transition *
+create_fade_view_transition(
+ struct ivi_layout_surface *surface,
+ double start_alpha, double end_alpha,
+ ivi_layout_transition_frame_func frame_func,
+ void *user_data,
+ ivi_layout_transition_destroy_func destroy_func,
+ uint32_t duration)
+{
+ struct ivi_layout_transition *transition = create_layout_transition();
+ struct fade_view_data *data = malloc(sizeof(*data));
+
+ if (data == NULL) {
+ weston_log("%s: memory allocation fails\n", __func__);
+ return NULL;
+ }
+
+ transition->type = IVI_LAYOUT_TRANSITION_VIEW_FADE;
+ transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_view_func;
+
+ transition->user_data = user_data;
+ transition->private_data = data;
+ transition->frame_func = frame_func;
+ transition->destroy_func = destroy_func;
+
+ if (duration != 0)
+ transition->time_duration = duration;
+
+ data->surface = surface;
+ data->start_alpha = start_alpha;
+ data->end_alpha = end_alpha;
+
+ return transition;
+}
+
+static void
+create_visibility_transition(struct ivi_layout_surface *surface,
+ double start_alpha,
+ double dest_alpha,
+ void *user_data,
+ ivi_layout_transition_destroy_func destroy_func,
+ uint32_t duration)
+{
+ struct ivi_layout_transition *transition = NULL;
+
+ transition = create_fade_view_transition(
+ surface,
+ start_alpha, dest_alpha,
+ fade_view_user_frame,
+ user_data,
+ destroy_func,
+ duration);
+
+ layout_transition_register(transition);
+}
+
+static void
+visibility_on_transition_destroy(struct ivi_layout_transition *transition)
+{
+ struct fade_view_data *data = transition->private_data;
+ struct store_alpha *user_data = transition->user_data;
+
+ ivi_layout_surface_set_visibility(data->surface, true);
+
+ free(data);
+ transition->private_data = NULL;
+
+ free(user_data);
+ transition->user_data = NULL;
+}
+
+WL_EXPORT void
+ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
+ uint32_t duration)
+{
+ struct ivi_layout_transition *transition;
+ bool is_visible = ivi_layout_surface_get_visibility(surface);
+ wl_fixed_t dest_alpha = ivi_layout_surface_get_opacity(surface);
+ struct store_alpha *user_data = NULL;
+ wl_fixed_t start_alpha = 0.0;
+ struct fade_view_data *data = NULL;
+
+ transition = get_transition_from_type_and_id(
+ IVI_LAYOUT_TRANSITION_VIEW_FADE,
+ surface);
+ if (transition) {
+ start_alpha = ivi_layout_surface_get_opacity(surface);
+ user_data = transition->user_data;
+ data = transition->private_data;
+
+ transition->time_start = 0;
+ transition->time_duration = duration;
+ transition->destroy_func = visibility_on_transition_destroy;
+
+ data->start_alpha = wl_fixed_to_double(start_alpha);
+ data->end_alpha = user_data->alpha;
+ return;
+ }
+
+ if (is_visible)
+ return;
+
+ user_data = malloc(sizeof(*user_data));
+ if (user_data == NULL) {
+ weston_log("%s: memory allocation fails\n", __func__);
+ return;
+ }
+
+ user_data->alpha = wl_fixed_to_double(dest_alpha);
+
+ create_visibility_transition(surface,
+ 0.0, // start_alpha
+ wl_fixed_to_double(dest_alpha),
+ user_data,
+ visibility_on_transition_destroy,
+ duration);
+}
+
+static void
+visibility_off_transition_destroy(struct ivi_layout_transition *transition)
+{
+ struct fade_view_data *data = transition->private_data;
+ struct store_alpha *user_data = transition->user_data;
+
+ ivi_layout_surface_set_visibility(data->surface, false);
+
+ ivi_layout_surface_set_opacity(data->surface,
+ wl_fixed_from_double(user_data->alpha));
+
+ free(data);
+ transition->private_data = NULL;
+
+ free(user_data);
+ transition->user_data= NULL;
+}
+
+WL_EXPORT void
+ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
+ uint32_t duration)
+{
+ struct ivi_layout_transition *transition;
+ wl_fixed_t start_alpha = ivi_layout_surface_get_opacity(surface);
+ struct store_alpha* user_data = NULL;
+ struct fade_view_data* data = NULL;
+
+ transition =
+ get_transition_from_type_and_id(IVI_LAYOUT_TRANSITION_VIEW_FADE,
+ surface);
+ if (transition) {
+ data = transition->private_data;
+
+ transition->time_start = 0;
+ transition->time_duration = duration;
+ transition->destroy_func = visibility_off_transition_destroy;
+
+ data->start_alpha = wl_fixed_to_double(start_alpha);
+ data->end_alpha = 0;
+ return;
+ }
+
+ user_data = malloc(sizeof(*user_data));
+ if (user_data == NULL) {
+ weston_log("%s: memory allocation fails\n", __func__);
+ return;
+ }
+
+ user_data->alpha = wl_fixed_to_double(start_alpha);
+
+ create_visibility_transition(surface,
+ wl_fixed_to_double(start_alpha),
+ 0.0, // dest_alpha
+ user_data,
+ visibility_off_transition_destroy,
+ duration);
+}
+
+/* move layer transition */
+
+struct move_layer_data {
+ struct ivi_layout_layer *layer;
+ int32_t start_x;
+ int32_t start_y;
+ int32_t end_x;
+ int32_t end_y;
+ ivi_layout_transition_destroy_user_func destroy_func;
+};
+
+static void
+transition_move_layer_user_frame(struct ivi_layout_transition *transition)
+{
+ struct move_layer_data *data = transition->private_data;
+ struct ivi_layout_layer *layer = data->layer;
+
+ const float current = time_to_nowpos(transition);
+
+ const int32_t dest_x = data->start_x +
+ (data->end_x - data->start_x) * current;
+
+ const int32_t dest_y = data->start_y +
+ (data->end_y - data->start_y) * current;
+
+ ivi_layout_layer_set_position(layer, dest_x, dest_y);
+}
+
+static void
+transition_move_layer_destroy(struct ivi_layout_transition *transition)
+{
+ struct move_layer_data *data = transition->private_data;
+
+ if(data->destroy_func)
+ data->destroy_func(transition->user_data);
+
+ free(data);
+ transition->private_data = NULL;
+}
+
+static int32_t
+is_transition_move_layer_func(struct move_layer_data *data,
+ struct ivi_layout_layer *layer)
+{
+ return data->layer == layer;
+}
+
+
+static struct ivi_layout_transition *
+create_move_layer_transition(
+ struct ivi_layout_layer *layer,
+ int32_t start_x, int32_t start_y,
+ int32_t end_x, int32_t end_y,
+ void *user_data,
+ ivi_layout_transition_destroy_user_func destroy_user_func,
+ uint32_t duration)
+{
+ struct ivi_layout_transition *transition = create_layout_transition();
+ struct move_layer_data *data = malloc(sizeof(*data));
+
+ if (data == NULL) {
+ weston_log("%s: memory allocation fails\n", __func__);
+ return NULL;
+ }
+
+ transition->type = IVI_LAYOUT_TRANSITION_LAYER_MOVE;
+ transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_layer_func;
+
+ transition->frame_func = transition_move_layer_user_frame;
+ transition->destroy_func = transition_move_layer_destroy;
+ transition->private_data = data;
+ transition->user_data = user_data;
+
+ if (duration != 0)
+ transition->time_duration = duration;
+
+ data->layer = layer;
+ data->start_x = start_x;
+ data->start_y = start_y;
+ data->end_x = end_x;
+ data->end_y = end_y;
+ data->destroy_func = destroy_user_func;
+
+ return transition;
+}
+
+WL_EXPORT void
+ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
+ int32_t dest_x, int32_t dest_y,
+ uint32_t duration)
+{
+ int32_t start_pos_x = 0;
+ int32_t start_pos_y = 0;
+ struct ivi_layout_transition *transition = NULL;
+
+ ivi_layout_layer_get_position(layer, &start_pos_x, &start_pos_y);
+
+ transition = create_move_layer_transition(
+ layer,
+ start_pos_x, start_pos_y,
+ dest_x, dest_y,
+ NULL, NULL,
+ duration);
+
+ layout_transition_register(transition);
+
+ return;
+}
+
+WL_EXPORT void
+ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer)
+{
+ struct ivi_layout_transition *transition =
+ get_transition_from_type_and_id(
+ IVI_LAYOUT_TRANSITION_LAYER_MOVE,
+ layer);
+ if (transition) {
+ layout_transition_destroy(transition);
+ }
+}
+
+/* fade layer transition */
+struct fade_layer_data {
+ struct ivi_layout_layer *layer;
+ uint32_t is_fade_in;
+ double start_alpha;
+ double end_alpha;
+ ivi_layout_transition_destroy_user_func destroy_func;
+};
+
+static void
+transition_fade_layer_destroy(struct ivi_layout_transition *transition)
+{
+ struct fade_layer_data *data = transition->private_data;
+ transition->private_data = NULL;
+
+ free(data);
+}
+
+static void
+transition_fade_layer_user_frame(struct ivi_layout_transition *transition)
+{
+ double current = time_to_nowpos(transition);
+ struct fade_layer_data *data = transition->private_data;
+ double alpha = data->start_alpha +
+ (data->end_alpha - data->start_alpha) * current;
+ wl_fixed_t fixed_alpha = wl_fixed_from_double(alpha);
+
+ int32_t is_done = transition->is_done;
+ bool is_visible = !is_done || data->is_fade_in;
+
+ ivi_layout_layer_set_opacity(data->layer, fixed_alpha);
+ ivi_layout_layer_set_visibility(data->layer, is_visible);
+}
+
+static int32_t
+is_transition_fade_layer_func(struct fade_layer_data *data,
+ struct ivi_layout_layer *layer)
+{
+ return data->layer == layer;
+}
+
+WL_EXPORT void
+ivi_layout_transition_fade_layer(
+ struct ivi_layout_layer *layer,
+ uint32_t is_fade_in,
+ double start_alpha, double end_alpha,
+ void* user_data,
+ ivi_layout_transition_destroy_user_func destroy_func,
+ uint32_t duration)
+{
+ struct ivi_layout_transition *transition;
+ struct fade_layer_data *data = NULL;
+ wl_fixed_t fixed_opacity = 0.0;
+ double now_opacity = 0.0;
+ double remain = 0.0;
+
+ transition = get_transition_from_type_and_id(
+ IVI_LAYOUT_TRANSITION_LAYER_FADE,
+ layer);
+ if (transition) {
+ /* transition update */
+ data = transition->private_data;
+
+ /* FIXME */
+ fixed_opacity = ivi_layout_layer_get_opacity(layer);
+ now_opacity = wl_fixed_to_double(fixed_opacity);
+ remain = 0.0;
+
+ data->is_fade_in = is_fade_in;
+ data->start_alpha = now_opacity;
+ data->end_alpha = end_alpha;
+
+ remain = is_fade_in? 1.0 - now_opacity : now_opacity;
+ transition->time_start = 0;
+ transition->time_elapsed = 0;
+ transition->time_duration = duration * remain;
+
+ return;
+ }
+
+ transition = create_layout_transition();
+ data = malloc(sizeof(*data));
+
+ if (data == NULL) {
+ weston_log("%s: memory allocation fails\n", __func__);
+ return;
+ }
+
+ transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
+ transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
+
+ transition->private_data = data;
+ transition->user_data = user_data;
+
+ transition->frame_func = transition_fade_layer_user_frame;
+ transition->destroy_func = transition_fade_layer_destroy;
+
+ if (duration != 0)
+ transition->time_duration = duration;
+
+ data->layer = layer;
+ data->is_fade_in = is_fade_in;
+ data->start_alpha = start_alpha;
+ data->end_alpha = end_alpha;
+ data->destroy_func = destroy_func;
+
+ layout_transition_register(transition);
+
+ return;
+}
+
+/* render order transition */
+struct surface_reorder {
+ uint32_t id_surface;
+ uint32_t new_index;
+};
+
+struct change_order_data {
+ struct ivi_layout_layer *layer;
+ uint32_t surface_num;
+ struct surface_reorder *reorder;
+};
+
+struct surf_with_index {
+ uint32_t id_surface;
+ float surface_index;
+};
+
+static int
+cmp_order_asc(const void *lhs, const void *rhs)
+{
+ const struct surf_with_index *l = lhs;
+ const struct surf_with_index *r = rhs;
+
+ return l->surface_index > r->surface_index;
+}
+
+/*
+render oerder transition
+
+index 0 1 2
+old surfA, surfB, surfC
+new surfB, surfC, surfA
+ (-1) (-1) (+2)
+
+after 10% of time elapsed
+ 0.2 0.9 1.9
+ surfA, surfB, surfC
+
+after 50% of time elapsed
+ 0.5 1.0 1.5
+ surfB, surfA, surfC
+*/
+
+static void
+transition_change_order_user_frame(struct ivi_layout_transition *transition)
+{
+ uint32_t i, old_index;
+ double current = time_to_nowpos(transition);
+ struct change_order_data *data = transition->private_data;
+
+ struct surf_with_index *swi = malloc(sizeof(*swi) * data->surface_num);
+ struct ivi_layout_surface **new_surface_order = NULL;
+ uint32_t surface_num = 0;
+
+ if (swi == NULL) {
+ weston_log("%s: memory allocation fails\n", __func__);
+ return;
+ }
+
+ for (old_index = 0; old_index < data->surface_num; old_index++) {
+ swi[old_index].id_surface = data->reorder[old_index].id_surface;
+ swi[old_index].surface_index = (float)old_index +
+ ((float)data->reorder[old_index].new_index - (float)old_index) * current;
+ }
+
+ qsort(swi, data->surface_num, sizeof(*swi), cmp_order_asc);
+
+ new_surface_order =
+ malloc(sizeof(*new_surface_order) * data->surface_num);
+
+ if (new_surface_order == NULL) {
+ weston_log("%s: memory allocation fails\n", __func__);
+ return;
+ }
+
+ for (i = 0; i < data->surface_num; i++) {
+ struct ivi_layout_surface *surf =
+ ivi_layout_get_surface_from_id(swi[i].id_surface);
+ if(surf)
+ new_surface_order[surface_num++] = surf;
+ }
+
+ ivi_layout_layer_set_render_order(data->layer, new_surface_order,
+ surface_num);
+
+ free(new_surface_order);
+ free(swi);
+}
+
+static void
+transition_change_order_destroy(struct ivi_layout_transition *transition)
+{
+ struct change_order_data *data = transition->private_data;
+
+ free(data->reorder);
+ free(data);
+}
+
+static int32_t find_surface(struct ivi_layout_surface **surfaces,
+ uint32_t surface_num,
+ struct ivi_layout_surface *target)
+{
+ uint32_t i = 0;
+
+ for(i = 0; i < surface_num; i++) {
+ if (surfaces[i] == target)
+ return i;
+ }
+
+ return -1;
+}
+
+static int32_t
+is_transition_change_order_func(struct change_order_data *data,
+ struct ivi_layout_layer *layer)
+{
+ return data->layer == layer;
+}
+
+WL_EXPORT void
+ivi_layout_transition_layer_render_order(struct ivi_layout_layer *layer,
+ struct ivi_layout_surface **new_order,
+ uint32_t surface_num,
+ uint32_t duration)
+{
+ struct surface_reorder *reorder;
+ struct ivi_layout_surface *surf;
+ uint32_t old_index = 0;
+ struct ivi_layout_transition *transition;
+ struct change_order_data *data = NULL;
+ int32_t new_index = 0;
+ uint32_t id = 0;
+
+ reorder = malloc(sizeof(*reorder) * surface_num);
+ if (reorder == NULL) {
+ weston_log("%s: memory allocation fails\n", __func__);
+ return;
+ }
+
+ wl_list_for_each(surf, &layer->order.surface_list, order.link) {
+ new_index = find_surface(new_order, surface_num, surf);
+ id = ivi_layout_get_id_of_surface(surf);
+ if(new_index < 0){
+ fprintf(stderr, "invalid render order!!!\n");
+ return;
+ }
+
+ reorder[old_index].id_surface = id;
+ reorder[old_index].new_index = new_index;
+ old_index++;
+ }
+
+ transition = get_transition_from_type_and_id(
+ IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
+ layer);
+ if (transition) {
+ /* update transition */
+ struct change_order_data *data = transition->private_data;
+ transition->time_start = 0; /* timer reset */
+
+ if (duration != 0) {
+ transition->time_duration = duration;
+ }
+
+ free(data->reorder);
+ data->reorder = reorder;
+ return;
+ }
+
+ transition = create_layout_transition();
+ data = malloc(sizeof(*data));
+
+ if (data == NULL) {
+ weston_log("%s: memory allocation fails\n", __func__);
+ return;
+ }
+
+ transition->type = IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER;
+ transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_change_order_func;
+
+ transition->private_data = data;
+ transition->frame_func = transition_change_order_user_frame;
+ transition->destroy_func = transition_change_order_destroy;
+
+ if (duration != 0)
+ transition->time_duration = duration;
+
+ data->layer = layer;
+ data->reorder = reorder;
+ data->surface_num = old_index;
+
+ layout_transition_register(transition);
+}
+
+WL_EXPORT int32_t
+ivi_layout_surface_set_transition(struct ivi_layout_surface *ivisurf,
+ enum ivi_layout_transition_type type,
+ uint32_t duration)
+{
+ struct ivi_layout_surface_properties *prop;
+
+ if (ivisurf == NULL) {
+ weston_log("%s: invalid argument\n", __func__);
+ return -1;
+ }
+
+ prop = &ivisurf->pending.prop;
+ prop->transition_type = type;
+ prop->transition_duration = duration;
+ return 0;
+}
+
+int32_t
+ivi_layout_surface_set_transition_duration(struct ivi_layout_surface *ivisurf,
+ uint32_t duration)
+{
+ struct ivi_layout_surface_properties *prop;
+
+ if (ivisurf == NULL) {
+ weston_log("%s: invalid argument\n", __func__);
+ return -1;
+ }
+
+ prop = &ivisurf->pending.prop;
+ prop->transition_duration = duration*10;
+ return 0;
+}
+
+WL_EXPORT int32_t
+ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer,
+ enum ivi_layout_transition_type type,
+ uint32_t duration)
+{
+ if (ivilayer == NULL) {
+ weston_log("%s: invalid argument\n", __func__);
+ return -1;
+ }
+
+ ivilayer->pending.prop.transition_type = type;
+ ivilayer->pending.prop.transition_duration = duration;
+
+ return 0;
+}
+
+WL_EXPORT int32_t
+ivi_layout_layer_set_fade_info(struct ivi_layout_layer* ivilayer,
+ uint32_t is_fade_in,
+ double start_alpha, double end_alpha)
+{
+ if (ivilayer == NULL) {
+ weston_log("%s: invalid argument\n", __func__);
+ return -1;
+ }
+
+ ivilayer->pending.prop.is_fade_in = is_fade_in;
+ ivilayer->pending.prop.start_alpha = start_alpha;
+ ivilayer->pending.prop.end_alpha = end_alpha;
+
+ return 0;
+}
--- /dev/null
+/*
+ * 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.
+ *
+ * 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.
+ */
+
+/**
+ * Implementation of ivi-layout library. The actual view on ivi_screen is
+ * not updated till calling ivi_layout_commit_changes. A overview from
+ * calling API for updating properties of ivi_surface/ivi_layer to asking
+ * compositor to compose them by using weston_compositor_schedule_repaint,
+ * 0/ initialize this library by ivi_layout_init_with_compositor
+ * with (struct weston_compositor *ec) from ivi-shell.
+ * 1/ When a API for updating properties of ivi_surface/ivi_layer, it updates
+ * pending prop of ivi_surface/ivi_layer/ivi_screen which are structure to
+ * store properties.
+ * 2/ Before calling commitChanges, in case of calling a API to get a property,
+ * return current property, not pending property.
+ * 3/ At the timing of calling ivi_layout_commitChanges, pending properties
+ * are applied to properties.
+ *
+ * *) ivi_layout_commitChanges is also called by transition animation
+ * per each frame. See ivi-layout-transition.c in details. Transition
+ * animation interpolates frames between previous properties of ivi_surface
+ * and new ones.
+ * For example, when a property of ivi_surface is changed from invisibility
+ * to visibility, it behaves like fade-in. When ivi_layout_commitChange is
+ * called during transition animation, it cancels the transition and
+ * re-start transition to new properties from current properties of final
+ * frame just before the the cancellation.
+ *
+ * 4/ According properties, set transformation by using weston_matrix and
+ * weston_view per ivi_surfaces and ivi_layers in while loop.
+ * 5/ Set damage and trigger transform by using weston_view_geometry_dirty.
+ * 6/ Notify update of properties.
+ * 7/ Trigger composition by weston_compositor_schedule_repaint.
+ *
+ */
+
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <linux/input.h>
+
+#include "compositor.h"
+#include "ivi-layout-export.h"
+#include "ivi-layout-private.h"
+
+struct link_layer {
+ struct ivi_layout_layer *ivilayer;
+ struct wl_list link;
+ struct wl_list link_to_layer;
+};
+
+struct link_screen {
+ struct ivi_layout_screen *iviscrn;
+ struct wl_list link;
+ struct wl_list link_to_screen;
+};
+
+struct listener_layout_notification {
+ void *userdata;
+ struct wl_listener listener;
+};
+
+struct ivi_layout;
+
+struct ivi_layout_screen {
+ struct wl_list link;
+ struct wl_list link_to_layer;
+ uint32_t id_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 {
+ struct wl_list layer_list;
+ struct wl_list link;
+ } order;
+};
+
+struct ivi_layout_notification_callback {
+ void *callback;
+ void *data;
+};
+
+static struct ivi_layout ivilayout = {0};
+
+struct ivi_layout *
+get_instance(void)
+{
+ return &ivilayout;
+}
+
+/**
+ * Internal API to add/remove a link to ivi_surface from ivi_layer.
+ */
+static void
+add_link_to_surface(struct ivi_layout_layer *ivilayer,
+ struct link_layer *link_layer)
+{
+ struct link_layer *link = NULL;
+
+ wl_list_for_each(link, &ivilayer->link_to_surface, link_to_layer) {
+ if (link == link_layer)
+ return;
+ }
+
+ wl_list_insert(&ivilayer->link_to_surface, &link_layer->link_to_layer);
+}
+
+static void
+remove_link_to_surface(struct ivi_layout_layer *ivilayer)
+{
+ struct link_layer *link = NULL;
+ 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);
+ }
+ free(link);
+ }
+
+ wl_list_init(&ivilayer->link_to_surface);
+}
+
+/**
+ * Internal API to add a link to ivi_layer from ivi_screen.
+ */
+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);
+}
+
+/**
+ * Internal API to add/remove a ivi_surface from ivi_layer.
+ */
+static void
+add_ordersurface_to_layer(struct ivi_layout_surface *ivisurf,
+ struct ivi_layout_layer *ivilayer)
+{
+ struct link_layer *link_layer = NULL;
+
+ link_layer = malloc(sizeof *link_layer);
+ if (link_layer == NULL) {
+ weston_log("fails to allocate memory\n");
+ return;
+ }
+
+ 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);
+}
+
+static void
+remove_ordersurface_from_layer(struct ivi_layout_surface *ivisurf)
+{
+ struct link_layer *link_layer = NULL;
+ 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);
+ }
+ free(link_layer);
+ }
+ wl_list_init(&ivisurf->layer_list);
+}
+
+/**
+ * Internal API to add/remove a ivi_layer to/from ivi_screen.
+ */
+static void
+add_orderlayer_to_screen(struct ivi_layout_layer *ivilayer,
+ struct ivi_layout_screen *iviscrn)
+{
+ struct link_screen *link_scrn = NULL;
+
+ link_scrn = malloc(sizeof *link_scrn);
+ if (link_scrn == NULL) {
+ weston_log("fails to allocate memory\n");
+ return;
+ }
+
+ 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);
+}
+
+static void
+remove_orderlayer_from_screen(struct ivi_layout_layer *ivilayer)
+{
+ struct link_screen *link_scrn = NULL;
+ 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);
+ }
+ free(link_scrn);
+ }
+ wl_list_init(&ivilayer->screen_list);
+}
+
+/**
+ * Internal API to add/remove a ivi_layer to/from ivi_screen.
+ */
+static struct ivi_layout_surface *
+get_surface(struct wl_list *surf_list, uint32_t id_surface)
+{
+ struct ivi_layout_surface *ivisurf;
+
+ wl_list_for_each(ivisurf, surf_list, link) {
+ if (ivisurf->id_surface == id_surface) {
+ return ivisurf;
+ }
+ }
+
+ return NULL;
+}
+
+static struct ivi_layout_layer *
+get_layer(struct wl_list *layer_list, uint32_t id_layer)
+{
+ struct ivi_layout_layer *ivilayer;
+
+ wl_list_for_each(ivilayer, layer_list, link) {
+ if (ivilayer->id_layer == id_layer) {
+ return ivilayer;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * 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
+ */
+static int
+is_surface_in_layer(struct ivi_layout_surface *ivisurf,
+ struct ivi_layout_layer *ivilayer)
+{
+ struct ivi_layout_surface *surf = NULL;
+
+ wl_list_for_each(surf, &ivilayer->pending.surface_list, pending.link) {
+ if (surf->id_surface == ivisurf->id_surface) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+is_layer_in_screen(struct ivi_layout_layer *ivilayer,
+ struct ivi_layout_screen *iviscrn)
+{
+ struct ivi_layout_layer *layer = NULL;
+
+ wl_list_for_each(layer, &iviscrn->pending.layer_list, pending.link) {
+ if (layer->id_layer == ivilayer->id_layer) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Internal API to initialize ivi_screens found from output_list of weston_compositor.
+ * Called by ivi_layout_init_with_compositor.
+ */
+static void
+create_screen(struct weston_compositor *ec)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_screen *iviscrn = NULL;
+ struct weston_output *output = NULL;
+ int32_t count = 0;
+
+ wl_list_for_each(output, &ec->output_list, link) {
+ iviscrn = calloc(1, sizeof *iviscrn);
+ if (iviscrn == NULL) {
+ weston_log("fails to allocate memory\n");
+ 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);
+
+ wl_list_init(&iviscrn->order.layer_list);
+ wl_list_init(&iviscrn->order.link);
+
+ wl_list_init(&iviscrn->link_to_layer);
+
+ wl_list_insert(&layout->screen_list, &iviscrn->link);
+ }
+}
+
+/**
+ * Internal APIs to initialize properties of ivi_surface/ivi_layer when they are created.
+ */
+static void
+init_layer_properties(struct ivi_layout_layer_properties *prop,
+ int32_t width, int32_t height)
+{
+ memset(prop, 0, sizeof *prop);
+ prop->opacity = wl_fixed_from_double(1.0);
+ prop->source_width = width;
+ prop->source_height = height;
+ prop->dest_width = width;
+ prop->dest_height = height;
+}
+
+static void
+init_surface_properties(struct ivi_layout_surface_properties *prop)
+{
+ memset(prop, 0, sizeof *prop);
+ prop->opacity = wl_fixed_from_double(1.0);
+}
+
+/**
+ * Internal APIs to be called from ivi_layout_commit_changes.
+ */
+static void
+update_opacity(struct ivi_layout_layer *ivilayer,
+ struct ivi_layout_surface *ivisurf)
+{
+ double layer_alpha = wl_fixed_to_double(ivilayer->prop.opacity);
+ double surf_alpha = wl_fixed_to_double(ivisurf->prop.opacity);
+
+ if ((ivilayer->event_mask & IVI_NOTIFICATION_OPACITY) ||
+ (ivisurf->event_mask & IVI_NOTIFICATION_OPACITY)) {
+ struct weston_view *tmpview = NULL;
+ wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
+ if (tmpview == NULL) {
+ continue;
+ }
+ tmpview->alpha = layer_alpha * surf_alpha;
+ }
+ }
+}
+
+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;
+ case WL_OUTPUT_TRANSFORM_90:
+ v_sin = 1.0f;
+ v_cos = 0.0f;
+ sx = width / height;
+ sy = height / width;
+ break;
+ case WL_OUTPUT_TRANSFORM_180:
+ v_sin = 0.0f;
+ v_cos = -1.0f;
+ break;
+ case WL_OUTPUT_TRANSFORM_270:
+ default:
+ v_sin = -1.0f;
+ v_cos = 0.0f;
+ sx = width / height;
+ sy = height / width;
+ 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;
+ case WL_OUTPUT_TRANSFORM_90:
+ v_sin = 1.0f;
+ v_cos = 0.0f;
+ sx = width / height;
+ sy = height / width;
+ break;
+ case WL_OUTPUT_TRANSFORM_180:
+ v_sin = 0.0f;
+ v_cos = -1.0f;
+ break;
+ case WL_OUTPUT_TRANSFORM_270:
+ default:
+ v_sin = -1.0f;
+ v_cos = 0.0f;
+ sx = width / height;
+ sy = height / width;
+ 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
+update_surface_position(struct ivi_layout_surface *ivisurf)
+{
+ 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;
+
+ wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
+ if (view != NULL) {
+ break;
+ }
+ }
+
+ if (view == NULL) {
+ return;
+ }
+
+ 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);
+}
+
+static void
+update_layer_position(struct ivi_layout_layer *ivilayer,
+ struct ivi_layout_surface *ivisurf)
+{
+ 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;
+
+ wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
+ if (view != NULL) {
+ break;
+ }
+ }
+
+ if (view == NULL) {
+ return;
+ }
+
+ wl_list_remove(&ivisurf->layer_pos.link);
+
+ weston_matrix_init(matrix);
+ weston_matrix_translate(matrix, tx, ty, 0.0f);
+ wl_list_insert(&view->geometry.transformation_list,
+ &ivisurf->layer_pos.link);
+
+ weston_view_set_transform_parent(view, NULL);
+ weston_view_update_transform(view);
+}
+
+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 (view == NULL) {
+ return;
+ }
+
+ if (ivisurf->prop.dest_width == 0 && ivisurf->prop.dest_height == 0) {
+ ivisurf->prop.dest_width = ivisurf->surface->width_from_buffer;
+ ivisurf->prop.dest_height = ivisurf->surface->height_from_buffer;
+ }
+
+ 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;
+
+ wl_list_remove(&ivisurf->scaling.link);
+ weston_matrix_init(matrix);
+ weston_matrix_scale(matrix, sx, sy, 1.0f);
+
+ wl_list_insert(&view->geometry.transformation_list,
+ &ivisurf->scaling.link);
+
+ weston_view_set_transform_parent(view, NULL);
+ weston_view_update_transform(view);
+}
+
+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);
+
+ ivisurf->update_count++;
+
+ wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
+ if (tmpview != NULL) {
+ break;
+ }
+ }
+
+ if (tmpview != NULL) {
+ weston_view_geometry_dirty(tmpview);
+ }
+
+ if (ivisurf->surface != NULL) {
+ weston_surface_damage(ivisurf->surface);
+ }
+ }
+}
+
+static void
+commit_changes(struct ivi_layout *layout)
+{
+ struct ivi_layout_screen *iviscrn = NULL;
+ struct ivi_layout_layer *ivilayer = NULL;
+ struct ivi_layout_surface *ivisurf = NULL;
+
+ wl_list_for_each(iviscrn, &layout->screen_list, link) {
+ wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
+ wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
+ update_prop(ivilayer, ivisurf);
+ }
+ }
+ }
+}
+
+static void
+commit_surface_list(struct ivi_layout *layout)
+{
+ struct ivi_layout_surface *ivisurf = NULL;
+ int32_t dest_x = 0;
+ int32_t dest_y = 0;
+ int32_t dest_width = 0;
+ int32_t dest_height = 0;
+ int32_t configured = 0;
+
+ wl_list_for_each(ivisurf, &layout->surface_list, link) {
+ 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;
+ dest_height = ivisurf->prop.dest_height;
+
+ ivi_layout_transition_move_resize_view(ivisurf,
+ ivisurf->pending.prop.dest_x,
+ ivisurf->pending.prop.dest_y,
+ ivisurf->pending.prop.dest_width,
+ ivisurf->pending.prop.dest_height,
+ ivisurf->pending.prop.transition_duration);
+
+ 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);
+ }
+
+ ivisurf->prop = ivisurf->pending.prop;
+ ivisurf->prop.dest_x = dest_x;
+ ivisurf->prop.dest_y = dest_y;
+ ivisurf->prop.dest_width = dest_width;
+ ivisurf->prop.dest_height = dest_height;
+ 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){
+ dest_x = ivisurf->prop.dest_x;
+ dest_y = ivisurf->prop.dest_y;
+ dest_width = ivisurf->prop.dest_width;
+ dest_height = ivisurf->prop.dest_height;
+
+ ivi_layout_transition_move_resize_view(ivisurf,
+ ivisurf->pending.prop.dest_x,
+ ivisurf->pending.prop.dest_y,
+ ivisurf->pending.prop.dest_width,
+ ivisurf->pending.prop.dest_height,
+ ivisurf->pending.prop.transition_duration);
+
+ ivisurf->prop = ivisurf->pending.prop;
+ ivisurf->prop.dest_x = dest_x;
+ ivisurf->prop.dest_y = dest_y;
+ ivisurf->prop.dest_width = dest_width;
+ ivisurf->prop.dest_height = dest_height;
+
+ 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){
+ configured = 0;
+ 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);
+ }
+
+ if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
+ ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
+ configured = 1;
+ }
+
+ ivisurf->prop = ivisurf->pending.prop;
+ ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
+ ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
+
+ if (configured && !is_surface_transition(ivisurf))
+ wl_signal_emit(&ivisurf->configured, ivisurf);
+ } else {
+ configured = 0;
+ if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
+ ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
+ configured = 1;
+ }
+
+ ivisurf->prop = ivisurf->pending.prop;
+ ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
+ ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
+
+ if (configured && !is_surface_transition(ivisurf))
+ wl_signal_emit(&ivisurf->configured, ivisurf);
+ }
+ }
+}
+
+static void
+commit_layer_list(struct ivi_layout *layout)
+{
+ struct ivi_layout_layer *ivilayer = NULL;
+ struct ivi_layout_surface *ivisurf = NULL;
+ 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) {
+ 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) {
+ ivi_layout_transition_fade_layer(ivilayer,ivilayer->pending.prop.is_fade_in,
+ ivilayer->pending.prop.start_alpha,ivilayer->pending.prop.end_alpha,
+ NULL, NULL,
+ ivilayer->pending.prop.transition_duration);
+ }
+ ivilayer->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
+
+ ivilayer->prop = ivilayer->pending.prop;
+
+ if (!(ivilayer->event_mask &
+ (IVI_NOTIFICATION_ADD | IVI_NOTIFICATION_REMOVE)) ) {
+ 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);
+ }
+
+ 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);
+ }
+
+ wl_list_init(&ivilayer->order.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;
+ }
+ }
+ }
+}
+
+static void
+commit_screen_list(struct ivi_layout *layout)
+{
+ struct ivi_layout_screen *iviscrn = NULL;
+ struct ivi_layout_layer *ivilayer = NULL;
+ struct ivi_layout_layer *next = NULL;
+ struct ivi_layout_surface *ivisurf = NULL;
+
+ wl_list_for_each(iviscrn, &layout->screen_list, link) {
+ if (iviscrn->event_mask & IVI_NOTIFICATION_REMOVE) {
+ 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_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);
+
+ 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,
+ &ivilayer->order.link);
+ add_orderlayer_to_screen(ivilayer, iviscrn);
+ ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
+ }
+ }
+
+ iviscrn->event_mask = 0;
+
+ /* Clear view list of layout ivi_layer */
+ wl_list_init(&layout->layout_layer.view_list.link);
+
+ wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
+ if (ivilayer->prop.visibility == false)
+ continue;
+
+ wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
+ struct weston_view *tmpview = NULL;
+ wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
+ if (tmpview != NULL) {
+ break;
+ }
+ }
+
+ if (ivisurf->prop.visibility == false)
+ continue;
+ if (ivisurf->surface == NULL || tmpview == NULL)
+ continue;
+
+ weston_layer_entry_insert(&layout->layout_layer.view_list,
+ &tmpview->layer_link);
+
+ ivisurf->surface->output = iviscrn->output;
+ }
+ }
+
+ break;
+ }
+}
+
+static void
+commit_transition(struct ivi_layout* layout)
+{
+ if(wl_list_empty(&layout->pending_transition_list)){
+ return;
+ }
+
+ wl_list_insert_list(&layout->transitions->transition_list,
+ &layout->pending_transition_list);
+
+ wl_list_init(&layout->pending_transition_list);
+
+ wl_event_source_timer_update(layout->transitions->event_source, 1);
+}
+
+static void
+send_surface_prop(struct ivi_layout_surface *ivisurf)
+{
+ wl_signal_emit(&ivisurf->property_changed, ivisurf);
+ ivisurf->event_mask = 0;
+}
+
+static void
+send_layer_prop(struct ivi_layout_layer *ivilayer)
+{
+ wl_signal_emit(&ivilayer->property_changed, ivilayer);
+ ivilayer->event_mask = 0;
+}
+
+static void
+send_prop(struct ivi_layout *layout)
+{
+ struct ivi_layout_layer *ivilayer = NULL;
+ struct ivi_layout_surface *ivisurf = NULL;
+
+ wl_list_for_each_reverse(ivilayer, &layout->layer_list, link) {
+ send_layer_prop(ivilayer);
+ }
+
+ wl_list_for_each_reverse(ivisurf, &layout->surface_list, link) {
+ send_surface_prop(ivisurf);
+ }
+}
+
+static void
+clear_surface_pending_list(struct ivi_layout_layer *ivilayer)
+{
+ struct ivi_layout_surface *surface_link = NULL;
+ struct ivi_layout_surface *surface_next = NULL;
+
+ 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_init(&surface_link->pending.link);
+ }
+
+ ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
+}
+
+static void
+clear_surface_order_list(struct ivi_layout_layer *ivilayer)
+{
+ struct ivi_layout_surface *surface_link = NULL;
+ struct ivi_layout_surface *surface_next = NULL;
+
+ 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_init(&surface_link->order.link);
+ }
+
+ ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
+}
+
+static void
+layer_created(struct wl_listener *listener, void *data)
+{
+ struct ivi_layout_layer *ivilayer = data;
+
+ struct listener_layout_notification *notification =
+ container_of(listener,
+ struct listener_layout_notification,
+ listener);
+
+ struct ivi_layout_notification_callback *created_callback =
+ notification->userdata;
+
+ ((layer_create_notification_func)created_callback->callback)
+ (ivilayer, created_callback->data);
+}
+
+static void
+layer_removed(struct wl_listener *listener, void *data)
+{
+ struct ivi_layout_layer *ivilayer = data;
+
+ struct listener_layout_notification *notification =
+ container_of(listener,
+ struct listener_layout_notification,
+ listener);
+
+ struct ivi_layout_notification_callback *removed_callback =
+ notification->userdata;
+
+ ((layer_remove_notification_func)removed_callback->callback)
+ (ivilayer, removed_callback->data);
+}
+
+static void
+layer_prop_changed(struct wl_listener *listener, void *data)
+{
+ struct ivi_layout_layer *ivilayer = data;
+
+ struct listener_layout_notification *layout_listener =
+ container_of(listener,
+ struct listener_layout_notification,
+ listener);
+
+ struct ivi_layout_notification_callback *prop_callback =
+ layout_listener->userdata;
+
+ ((layer_property_notification_func)prop_callback->callback)
+ (ivilayer, &ivilayer->prop, ivilayer->event_mask, prop_callback->data);
+}
+
+static void
+surface_created(struct wl_listener *listener, void *data)
+{
+ struct ivi_layout_surface *ivisurface = data;
+
+ struct listener_layout_notification *notification =
+ container_of(listener,
+ struct listener_layout_notification,
+ listener);
+
+ struct ivi_layout_notification_callback *created_callback =
+ notification->userdata;
+
+ ((surface_create_notification_func)created_callback->callback)
+ (ivisurface, created_callback->data);
+}
+
+static void
+surface_removed(struct wl_listener *listener, void *data)
+{
+ struct ivi_layout_surface *ivisurface = data;
+
+ struct listener_layout_notification *notification =
+ container_of(listener,
+ struct listener_layout_notification,
+ listener);
+
+ struct ivi_layout_notification_callback *removed_callback =
+ notification->userdata;
+
+ ((surface_remove_notification_func)removed_callback->callback)
+ (ivisurface, removed_callback->data);
+}
+
+static void
+surface_prop_changed(struct wl_listener *listener, void *data)
+{
+ struct ivi_layout_surface *ivisurf = data;
+
+ struct listener_layout_notification *layout_listener =
+ container_of(listener,
+ struct listener_layout_notification,
+ listener);
+
+ struct ivi_layout_notification_callback *prop_callback =
+ layout_listener->userdata;
+
+ ((surface_property_notification_func)prop_callback->callback)
+ (ivisurf, &ivisurf->prop, ivisurf->event_mask, prop_callback->data);
+
+ ivisurf->event_mask = 0;
+}
+
+static void
+surface_configure_changed(struct wl_listener *listener,
+ void *data)
+{
+ struct ivi_layout_surface *ivisurface = data;
+
+ struct listener_layout_notification *notification =
+ container_of(listener,
+ struct listener_layout_notification,
+ listener);
+
+ struct ivi_layout_notification_callback *configure_changed_callback =
+ notification->userdata;
+
+ ((surface_configure_notification_func)configure_changed_callback->callback)
+ (ivisurface, configure_changed_callback->data);
+}
+
+static int32_t
+add_notification(struct wl_signal *signal,
+ wl_notify_func_t callback,
+ void *userdata)
+{
+ struct listener_layout_notification *notification = NULL;
+
+ notification = malloc(sizeof *notification);
+ if (notification == NULL) {
+ weston_log("fails to allocate memory\n");
+ free(userdata);
+ return IVI_FAILED;
+ }
+
+ notification->listener.notify = callback;
+ notification->userdata = userdata;
+
+ wl_signal_add(signal, ¬ification->listener);
+
+ return IVI_SUCCEEDED;
+}
+
+static void
+remove_notification(struct wl_list *listener_list, void *callback, void *userdata)
+{
+ struct wl_listener *listener = NULL;
+ struct wl_listener *next = NULL;
+
+ wl_list_for_each_safe(listener, next, listener_list, link) {
+ struct listener_layout_notification *notification =
+ container_of(listener,
+ struct listener_layout_notification,
+ listener);
+
+ struct ivi_layout_notification_callback *notification_callback =
+ notification->userdata;
+
+ if ((notification_callback->callback != callback) ||
+ (notification_callback->data != userdata)) {
+ continue;
+ }
+
+ if (!wl_list_empty(&listener->link)) {
+ wl_list_remove(&listener->link);
+ }
+
+ free(notification->userdata);
+ free(notification);
+ }
+}
+
+static void
+remove_all_notification(struct wl_list *listener_list)
+{
+ struct wl_listener *listener = NULL;
+ struct wl_listener *next = NULL;
+
+ 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);
+ }
+
+ notification =
+ container_of(listener,
+ struct listener_layout_notification,
+ listener);
+
+ free(notification->userdata);
+ free(notification);
+ }
+}
+
+/**
+ * Exported APIs of ivi-layout library are implemented from here.
+ * Brief of APIs is described in ivi-layout-export.h.
+ */
+WL_EXPORT int32_t
+ivi_layout_add_notification_create_layer(layer_create_notification_func callback,
+ void *userdata)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_notification_callback *created_callback = NULL;
+
+ if (callback == NULL) {
+ weston_log("ivi_layout_add_notification_create_layer: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ created_callback = malloc(sizeof *created_callback);
+ if (created_callback == NULL) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ created_callback->callback = callback;
+ created_callback->data = userdata;
+
+ return add_notification(&layout->layer_notification.created,
+ layer_created,
+ created_callback);
+}
+
+WL_EXPORT void
+ivi_layout_remove_notification_create_layer(layer_create_notification_func callback,
+ void *userdata)
+{
+ struct ivi_layout *layout = get_instance();
+ remove_notification(&layout->layer_notification.created.listener_list, callback, userdata);
+}
+
+WL_EXPORT int32_t
+ivi_layout_add_notification_remove_layer(layer_remove_notification_func callback,
+ void *userdata)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_notification_callback *removed_callback = NULL;
+
+ if (callback == NULL) {
+ weston_log("ivi_layout_add_notification_remove_layer: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ removed_callback = malloc(sizeof *removed_callback);
+ if (removed_callback == NULL) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ removed_callback->callback = callback;
+ removed_callback->data = userdata;
+ return add_notification(&layout->layer_notification.removed,
+ layer_removed,
+ removed_callback);
+}
+
+WL_EXPORT void
+ivi_layout_remove_notification_remove_layer(layer_remove_notification_func callback,
+ void *userdata)
+{
+ struct ivi_layout *layout = get_instance();
+ remove_notification(&layout->layer_notification.removed.listener_list, callback, userdata);
+}
+
+WL_EXPORT int32_t
+ivi_layout_add_notification_create_surface(surface_create_notification_func callback,
+ void *userdata)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_notification_callback *created_callback = NULL;
+
+ if (callback == NULL) {
+ weston_log("ivi_layout_add_notification_create_surface: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ created_callback = malloc(sizeof *created_callback);
+ if (created_callback == NULL) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ created_callback->callback = callback;
+ created_callback->data = userdata;
+
+ return add_notification(&layout->surface_notification.created,
+ surface_created,
+ created_callback);
+}
+
+WL_EXPORT void
+ivi_layout_remove_notification_create_surface(surface_create_notification_func callback,
+ void *userdata)
+{
+ struct ivi_layout *layout = get_instance();
+ remove_notification(&layout->surface_notification.created.listener_list, callback, userdata);
+}
+
+WL_EXPORT int32_t
+ivi_layout_add_notification_remove_surface(surface_remove_notification_func callback,
+ void *userdata)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_notification_callback *removed_callback = NULL;
+
+ if (callback == NULL) {
+ weston_log("ivi_layout_add_notification_remove_surface: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ removed_callback = malloc(sizeof *removed_callback);
+ if (removed_callback == NULL) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ removed_callback->callback = callback;
+ removed_callback->data = userdata;
+
+ return add_notification(&layout->surface_notification.removed,
+ surface_removed,
+ removed_callback);
+}
+
+WL_EXPORT void
+ivi_layout_remove_notification_remove_surface(surface_remove_notification_func callback,
+ void *userdata)
+{
+ struct ivi_layout *layout = get_instance();
+ remove_notification(&layout->surface_notification.removed.listener_list, callback, userdata);
+}
+
+WL_EXPORT int32_t
+ivi_layout_add_notification_configure_surface(surface_configure_notification_func callback,
+ void *userdata)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_notification_callback *configure_changed_callback = NULL;
+ if (callback == NULL) {
+ weston_log("ivi_layout_add_notification_configure_surface: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ configure_changed_callback = malloc(sizeof *configure_changed_callback);
+ if (configure_changed_callback == NULL) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ configure_changed_callback->callback = callback;
+ configure_changed_callback->data = userdata;
+
+ return add_notification(&layout->surface_notification.configure_changed,
+ surface_configure_changed,
+ configure_changed_callback);
+}
+
+WL_EXPORT void
+ivi_layout_remove_notification_configure_surface(surface_configure_notification_func callback,
+ void *userdata)
+{
+ struct ivi_layout *layout = get_instance();
+ remove_notification(&layout->surface_notification.configure_changed.listener_list, callback, userdata);
+}
+
+WL_EXPORT uint32_t
+ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf)
+{
+ return ivisurf->id_surface;
+}
+
+WL_EXPORT uint32_t
+ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer)
+{
+ return ivilayer->id_layer;
+}
+
+struct ivi_layout_layer *
+ivi_layout_get_layer_from_id(uint32_t id_layer)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_layer *ivilayer = NULL;
+
+ wl_list_for_each(ivilayer, &layout->layer_list, link) {
+ if (ivilayer->id_layer == id_layer) {
+ return ivilayer;
+ }
+ }
+
+ return NULL;
+}
+
+WL_EXPORT struct ivi_layout_surface *
+ivi_layout_get_surface_from_id(uint32_t id_surface)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_surface *ivisurf = NULL;
+
+ wl_list_for_each(ivisurf, &layout->surface_list, link) {
+ if (ivisurf->id_surface == id_surface) {
+ return ivisurf;
+ }
+ }
+
+ return NULL;
+}
+
+WL_EXPORT struct ivi_layout_screen *
+ivi_layout_get_screen_from_id(uint32_t id_screen)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_screen *iviscrn = NULL;
+
+ wl_list_for_each(iviscrn, &layout->screen_list, link) {
+/* FIXME : select iviscrn from screen_list by id_screen */
+ return iviscrn;
+ break;
+ }
+
+ return NULL;
+}
+
+WL_EXPORT int32_t
+ivi_layout_get_screen_resolution(struct ivi_layout_screen *iviscrn,
+ int32_t *pWidth, int32_t *pHeight)
+{
+ struct weston_output *output = NULL;
+
+ if (pWidth == NULL || pHeight == NULL) {
+ weston_log("ivi_layout_get_screen_resolution: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ output = iviscrn->output;
+ *pWidth = output->current_mode->width;
+ *pHeight = output->current_mode->height;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT int32_t
+ivi_layout_surface_add_notification(struct ivi_layout_surface *ivisurf,
+ surface_property_notification_func callback,
+ void *userdata)
+{
+ struct listener_layout_notification* notification = NULL;
+ struct ivi_layout_notification_callback *prop_callback = NULL;
+
+ if (ivisurf == NULL || callback == NULL) {
+ weston_log("ivi_layout_surface_add_notification: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ notification = malloc(sizeof *notification);
+ if (notification == NULL) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ prop_callback = malloc(sizeof *prop_callback);
+ if (prop_callback == NULL) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ prop_callback->callback = callback;
+ prop_callback->data = userdata;
+
+ notification->listener.notify = surface_prop_changed;
+ notification->userdata = prop_callback;
+
+ wl_signal_add(&ivisurf->property_changed, ¬ification->listener);
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT void
+ivi_layout_surface_remove_notification(struct ivi_layout_surface *ivisurf)
+{
+ if (ivisurf == NULL) {
+ weston_log("ivi_layout_surface_remove_notification: invalid argument\n");
+ return;
+ }
+
+ remove_all_notification(&ivisurf->property_changed.listener_list);
+}
+
+static void
+remove_configured_listener(struct ivi_layout_surface *ivisurf)
+{
+ struct wl_listener *link = NULL;
+ struct wl_listener *next = NULL;
+
+ wl_list_for_each_safe(link, next, &ivisurf->configured.listener_list, link) {
+ wl_list_remove(&link->link);
+ }
+}
+
+void
+ivi_layout_surface_remove(struct ivi_layout_surface *ivisurf)
+{
+ struct ivi_layout *layout = get_instance();
+
+ if (ivisurf == NULL) {
+ weston_log("ivi_layout_surface_remove: invalid argument\n");
+ 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);
+ }
+ remove_ordersurface_from_layer(ivisurf);
+
+ wl_signal_emit(&layout->surface_notification.removed, ivisurf);
+
+ remove_configured_listener(ivisurf);
+
+ ivi_layout_surface_remove_notification(ivisurf);
+
+ free(ivisurf);
+}
+
+WL_EXPORT const struct ivi_layout_layer_properties *
+ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer)
+{
+ if (ivilayer == NULL) {
+ weston_log("ivi_layout_get_properties_of_layer: invalid argument\n");
+ return NULL;
+ }
+
+ return &ivilayer->prop;
+}
+
+WL_EXPORT int32_t
+ivi_layout_get_screens(int32_t *pLength, struct ivi_layout_screen ***ppArray)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_screen *iviscrn = NULL;
+ int32_t length = 0;
+ int32_t n = 0;
+
+ if (pLength == NULL || ppArray == NULL) {
+ weston_log("ivi_layout_get_screens: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ length = wl_list_length(&layout->screen_list);
+
+ 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) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ wl_list_for_each(iviscrn, &layout->screen_list, link) {
+ (*ppArray)[n++] = iviscrn;
+ }
+ }
+
+ *pLength = length;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT int32_t
+ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer,
+ int32_t *pLength,
+ struct ivi_layout_screen ***ppArray)
+{
+ struct link_screen *link_scrn = NULL;
+ int32_t length = 0;
+ int32_t n = 0;
+
+ if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
+ weston_log("ivi_layout_get_screens_under_layer: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ length = wl_list_length(&ivilayer->screen_list);
+
+ 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) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ wl_list_for_each(link_scrn, &ivilayer->screen_list, link) {
+ (*ppArray)[n++] = link_scrn->iviscrn;
+ }
+ }
+
+ *pLength = length;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT int32_t
+ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_layer *ivilayer = NULL;
+ int32_t length = 0;
+ int32_t n = 0;
+
+ if (pLength == NULL || ppArray == NULL) {
+ weston_log("ivi_layout_get_layers: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ length = wl_list_length(&layout->layer_list);
+
+ 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) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ wl_list_for_each(ivilayer, &layout->layer_list, link) {
+ (*ppArray)[n++] = ivilayer;
+ }
+ }
+
+ *pLength = length;
+
+ return IVI_SUCCEEDED;
+}
+
+int32_t
+ivi_layout_get_layers_on_screen(struct ivi_layout_screen *iviscrn,
+ int32_t *pLength,
+ struct ivi_layout_layer ***ppArray)
+{
+ struct ivi_layout_layer *ivilayer = NULL;
+ int32_t length = 0;
+ int32_t n = 0;
+
+ if (iviscrn == NULL || pLength == NULL || ppArray == NULL) {
+ weston_log("ivi_layout_get_layers_on_screen: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ length = wl_list_length(&iviscrn->order.layer_list);
+
+ 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) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ wl_list_for_each(ivilayer, &iviscrn->order.layer_list, link) {
+ (*ppArray)[n++] = ivilayer;
+ }
+ }
+
+ *pLength = length;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT int32_t
+ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf,
+ int32_t *pLength,
+ struct ivi_layout_layer ***ppArray)
+{
+ struct link_layer *link_layer = NULL;
+ int32_t length = 0;
+ int32_t n = 0;
+
+ if (ivisurf == NULL || pLength == NULL || ppArray == NULL) {
+ weston_log("ivi_layout_getLayers: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ length = wl_list_length(&ivisurf->layer_list);
+
+ 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) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ wl_list_for_each(link_layer, &ivisurf->layer_list, link) {
+ (*ppArray)[n++] = link_layer->ivilayer;
+ }
+ }
+
+ *pLength = length;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT int32_t
+ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_surface *ivisurf = NULL;
+ int32_t length = 0;
+ int32_t n = 0;
+
+ if (pLength == NULL || ppArray == NULL) {
+ weston_log("ivi_layout_get_surfaces: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ length = wl_list_length(&layout->surface_list);
+
+ 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) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ wl_list_for_each(ivisurf, &layout->surface_list, link) {
+ (*ppArray)[n++] = ivisurf;
+ }
+ }
+
+ *pLength = length;
+
+ return IVI_SUCCEEDED;
+}
+
+int32_t
+ivi_layout_get_surfaces_on_layer(struct ivi_layout_layer *ivilayer,
+ int32_t *pLength,
+ struct ivi_layout_surface ***ppArray)
+{
+ struct ivi_layout_surface *ivisurf = NULL;
+ int32_t length = 0;
+ int32_t n = 0;
+
+ if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
+ weston_log("ivi_layout_getSurfaceIDsOnLayer: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ length = wl_list_length(&ivilayer->order.surface_list);
+
+ 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) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
+ (*ppArray)[n++] = ivisurf;
+ }
+ }
+
+ *pLength = length;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT struct ivi_layout_layer *
+ivi_layout_layer_create_with_dimension(uint32_t id_layer,
+ int32_t width, int32_t height)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_layer *ivilayer = NULL;
+
+ ivilayer = get_layer(&layout->layer_list, id_layer);
+ if (ivilayer != NULL) {
+ weston_log("id_layer is already created\n");
+ return ivilayer;
+ }
+
+ ivilayer = calloc(1, sizeof *ivilayer);
+ if (ivilayer == NULL) {
+ weston_log("fails to allocate memory\n");
+ return NULL;
+ }
+
+ wl_list_init(&ivilayer->link);
+ wl_signal_init(&ivilayer->property_changed);
+ wl_list_init(&ivilayer->screen_list);
+ wl_list_init(&ivilayer->link_to_surface);
+ ivilayer->layout = layout;
+ ivilayer->id_layer = id_layer;
+
+ init_layer_properties(&ivilayer->prop, width, height);
+ ivilayer->event_mask = 0;
+
+ wl_list_init(&ivilayer->pending.surface_list);
+ wl_list_init(&ivilayer->pending.link);
+ ivilayer->pending.prop = ivilayer->prop;
+
+ wl_list_init(&ivilayer->order.surface_list);
+ wl_list_init(&ivilayer->order.link);
+
+ wl_list_insert(&layout->layer_list, &ivilayer->link);
+
+ wl_signal_emit(&layout->layer_notification.created, ivilayer);
+
+ return ivilayer;
+}
+
+WL_EXPORT void
+ivi_layout_layer_remove(struct ivi_layout_layer *ivilayer)
+{
+ struct ivi_layout *layout = get_instance();
+
+ if (ivilayer == NULL) {
+ weston_log("ivi_layout_layer_remove: invalid argument\n");
+ 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);
+ }
+ remove_orderlayer_from_screen(ivilayer);
+ remove_link_to_surface(ivilayer);
+ ivi_layout_layer_remove_notification(ivilayer);
+
+ free(ivilayer);
+}
+
+WL_EXPORT int32_t
+ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer,
+ bool newVisibility)
+{
+ struct ivi_layout_layer_properties *prop = NULL;
+
+ if (ivilayer == NULL) {
+ weston_log("ivi_layout_layer_set_visibility: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop = &ivilayer->pending.prop;
+ prop->visibility = newVisibility;
+
+ ivilayer->event_mask |= IVI_NOTIFICATION_VISIBILITY;
+
+ return IVI_SUCCEEDED;
+}
+
+bool
+ivi_layout_layer_get_visibility(struct ivi_layout_layer *ivilayer)
+{
+ if (ivilayer == NULL) {
+ weston_log("ivi_layout_layer_get_visibility: invalid argument\n");
+ return false;
+ }
+
+ return ivilayer->prop.visibility;
+}
+
+WL_EXPORT int32_t
+ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
+ wl_fixed_t opacity)
+{
+ struct ivi_layout_layer_properties *prop = NULL;
+
+ if (ivilayer == NULL) {
+ weston_log("ivi_layout_layer_set_opacity: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop = &ivilayer->pending.prop;
+ prop->opacity = opacity;
+
+ ivilayer->event_mask |= IVI_NOTIFICATION_OPACITY;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT wl_fixed_t
+ivi_layout_layer_get_opacity(struct ivi_layout_layer *ivilayer)
+{
+ if (ivilayer == NULL) {
+ weston_log("ivi_layout_layer_get_opacity: invalid argument\n");
+ return wl_fixed_from_double(0.0);
+ }
+
+ return ivilayer->prop.opacity;
+}
+
+WL_EXPORT int32_t
+ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height)
+{
+ struct ivi_layout_layer_properties *prop = NULL;
+
+ if (ivilayer == NULL) {
+ weston_log("ivi_layout_layer_set_source_rectangle: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop = &ivilayer->pending.prop;
+ prop->source_x = x;
+ prop->source_y = y;
+ prop->source_width = width;
+ prop->source_height = height;
+
+ ivilayer->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT int32_t
+ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height)
+{
+ struct ivi_layout_layer_properties *prop = NULL;
+
+ if (ivilayer == NULL) {
+ weston_log("ivi_layout_layer_set_destination_rectangle: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop = &ivilayer->pending.prop;
+ prop->dest_x = x;
+ prop->dest_y = y;
+ prop->dest_width = width;
+ prop->dest_height = height;
+
+ ivilayer->event_mask |= IVI_NOTIFICATION_DEST_RECT;
+
+ return IVI_SUCCEEDED;
+}
+
+int32_t
+ivi_layout_layer_get_dimension(struct ivi_layout_layer *ivilayer,
+ int32_t *dest_width, int32_t *dest_height)
+{
+ if (ivilayer == NULL || dest_width == NULL || dest_height == NULL) {
+ weston_log("ivi_layout_layer_get_dimension: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ *dest_width = ivilayer->prop.dest_width;
+ *dest_height = ivilayer->prop.dest_height;
+
+ return IVI_SUCCEEDED;
+}
+
+int32_t
+ivi_layout_layer_set_dimension(struct ivi_layout_layer *ivilayer,
+ int32_t dest_width, int32_t dest_height)
+{
+ struct ivi_layout_layer_properties *prop = NULL;
+
+ if (ivilayer == NULL) {
+ weston_log("ivi_layout_layer_set_dimension: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop = &ivilayer->pending.prop;
+
+ prop->dest_width = dest_width;
+ prop->dest_height = dest_height;
+
+ ivilayer->event_mask |= IVI_NOTIFICATION_DIMENSION;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT int32_t
+ivi_layout_layer_get_position(struct ivi_layout_layer *ivilayer,
+ int32_t *dest_x, int32_t *dest_y)
+{
+ if (ivilayer == NULL || dest_x == NULL || dest_y == NULL) {
+ weston_log("ivi_layout_layer_get_position: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ *dest_x = ivilayer->prop.dest_x;
+ *dest_y = ivilayer->prop.dest_y;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT int32_t
+ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer,
+ int32_t dest_x, int32_t dest_y)
+{
+ struct ivi_layout_layer_properties *prop = NULL;
+
+ if (ivilayer == NULL) {
+ weston_log("ivi_layout_layer_set_position: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop = &ivilayer->pending.prop;
+ prop->dest_x = dest_x;
+ prop->dest_y = dest_y;
+
+ ivilayer->event_mask |= IVI_NOTIFICATION_POSITION;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT int32_t
+ivi_layout_layer_set_orientation(struct ivi_layout_layer *ivilayer,
+ enum wl_output_transform orientation)
+{
+ struct ivi_layout_layer_properties *prop = NULL;
+
+ if (ivilayer == NULL) {
+ weston_log("ivi_layout_layer_set_orientation: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop = &ivilayer->pending.prop;
+ prop->orientation = orientation;
+
+ ivilayer->event_mask |= IVI_NOTIFICATION_ORIENTATION;
+
+ return IVI_SUCCEEDED;
+}
+
+enum wl_output_transform
+ivi_layout_layer_get_orientation(struct ivi_layout_layer *ivilayer)
+{
+ if (ivilayer == NULL) {
+ weston_log("ivi_layout_layer_get_orientation: invalid argument\n");
+ return 0;
+ }
+
+ return ivilayer->prop.orientation;
+}
+
+WL_EXPORT int32_t
+ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
+ struct ivi_layout_surface **pSurface,
+ int32_t number)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_surface *ivisurf = NULL;
+ struct ivi_layout_surface *next = NULL;
+ uint32_t *id_surface = NULL;
+ int32_t i = 0;
+
+ if (ivilayer == NULL) {
+ weston_log("ivi_layout_layer_set_render_order: invalid argument\n");
+ 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;
+ }
+
+ for (i = 0; i < number; i++) {
+ id_surface = &pSurface[i]->id_surface;
+
+ wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
+ if (*id_surface != ivisurf->id_surface) {
+ continue;
+ }
+
+ if (!wl_list_empty(&ivisurf->pending.link)) {
+ wl_list_remove(&ivisurf->pending.link);
+ }
+ wl_list_init(&ivisurf->pending.link);
+ wl_list_insert(&ivilayer->pending.surface_list,
+ &ivisurf->pending.link);
+ break;
+ }
+ }
+
+ ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT int32_t
+ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf,
+ bool newVisibility)
+{
+ struct ivi_layout_surface_properties *prop = NULL;
+
+ if (ivisurf == NULL) {
+ weston_log("ivi_layout_surface_set_visibility: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop = &ivisurf->pending.prop;
+ prop->visibility = newVisibility;
+
+ ivisurf->event_mask |= IVI_NOTIFICATION_VISIBILITY;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT bool
+ivi_layout_surface_get_visibility(struct ivi_layout_surface *ivisurf)
+{
+ if (ivisurf == NULL) {
+ weston_log("ivi_layout_surface_get_visibility: invalid argument\n");
+ return false;
+ }
+
+ return ivisurf->prop.visibility;
+}
+
+WL_EXPORT int32_t
+ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
+ wl_fixed_t opacity)
+{
+ struct ivi_layout_surface_properties *prop = NULL;
+
+ if (ivisurf == NULL) {
+ weston_log("ivi_layout_surface_set_opacity: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop = &ivisurf->pending.prop;
+ prop->opacity = opacity;
+
+ ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT wl_fixed_t
+ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf)
+{
+ if (ivisurf == NULL) {
+ weston_log("ivi_layout_surface_get_opacity: invalid argument\n");
+ return wl_fixed_from_double(0.0);
+ }
+
+ return ivisurf->prop.opacity;
+}
+
+WL_EXPORT int32_t
+ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height)
+{
+ struct ivi_layout_surface_properties *prop = NULL;
+
+ if (ivisurf == NULL) {
+ weston_log("ivi_layout_surface_set_destination_rectangle: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop = &ivisurf->pending.prop;
+ prop->start_x = prop->dest_x;
+ prop->start_y = prop->dest_y;
+ prop->dest_x = x;
+ prop->dest_y = y;
+ prop->start_width = prop->dest_width;
+ prop->start_height = prop->dest_height;
+ prop->dest_width = width;
+ prop->dest_height = height;
+
+ ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT;
+
+ return IVI_SUCCEEDED;
+}
+
+int32_t
+ivi_layout_surface_set_dimension(struct ivi_layout_surface *ivisurf,
+ int32_t dest_width, int32_t dest_height)
+{
+ struct ivi_layout_surface_properties *prop = NULL;
+
+ if (ivisurf == NULL) {
+ weston_log("ivi_layout_surface_set_dimension: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop = &ivisurf->pending.prop;
+ prop->dest_width = dest_width;
+ prop->dest_height = dest_height;
+
+ ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION;
+
+ return IVI_SUCCEEDED;
+}
+
+int32_t
+ivi_layout_surface_get_dimension(struct ivi_layout_surface *ivisurf,
+ int32_t *dest_width, int32_t *dest_height)
+{
+ if (ivisurf == NULL || dest_width == NULL || dest_height == NULL) {
+ weston_log("ivi_layout_surface_get_dimension: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ *dest_width = ivisurf->prop.dest_width;
+ *dest_height = ivisurf->prop.dest_height;
+
+ return IVI_SUCCEEDED;
+}
+
+int32_t
+ivi_layout_surface_set_position(struct ivi_layout_surface *ivisurf,
+ int32_t dest_x, int32_t dest_y)
+{
+ struct ivi_layout_surface_properties *prop = NULL;
+
+ if (ivisurf == NULL) {
+ weston_log("ivi_layout_surface_set_position: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop = &ivisurf->pending.prop;
+ prop->dest_x = dest_x;
+ prop->dest_y = dest_y;
+
+ ivisurf->event_mask |= IVI_NOTIFICATION_POSITION;
+
+ return IVI_SUCCEEDED;
+}
+
+int32_t
+ivi_layout_surface_get_position(struct ivi_layout_surface *ivisurf,
+ int32_t *dest_x, int32_t *dest_y)
+{
+ if (ivisurf == NULL || dest_x == NULL || dest_y == NULL) {
+ weston_log("ivi_layout_surface_get_position: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ *dest_x = ivisurf->prop.dest_x;
+ *dest_y = ivisurf->prop.dest_y;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT int32_t
+ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf,
+ enum wl_output_transform orientation)
+{
+ struct ivi_layout_surface_properties *prop = NULL;
+
+ if (ivisurf == NULL) {
+ weston_log("ivi_layout_surface_set_orientation: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop = &ivisurf->pending.prop;
+ prop->orientation = orientation;
+
+ ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION;
+
+ return IVI_SUCCEEDED;
+}
+
+enum wl_output_transform
+ivi_layout_surface_get_orientation(struct ivi_layout_surface *ivisurf)
+{
+ if (ivisurf == NULL) {
+ weston_log("ivi_layout_surface_get_orientation: invalid argument\n");
+ return 0;
+ }
+
+ return ivisurf->prop.orientation;
+}
+
+WL_EXPORT int32_t
+ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn,
+ struct ivi_layout_layer *addlayer)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_layer *ivilayer = NULL;
+ struct ivi_layout_layer *next = NULL;
+ int is_layer_in_scrn = 0;
+
+ if (iviscrn == NULL || addlayer == NULL) {
+ weston_log("ivi_layout_screen_add_layer: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ is_layer_in_scrn = is_layer_in_screen(addlayer, iviscrn);
+ if (is_layer_in_scrn == 1) {
+ weston_log("ivi_layout_screen_add_layer: addlayer is already available\n");
+ return IVI_SUCCEEDED;
+ }
+
+ 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_insert(&iviscrn->pending.layer_list,
+ &ivilayer->pending.link);
+ break;
+ }
+ }
+
+ iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT int32_t
+ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn,
+ struct ivi_layout_layer **pLayer,
+ const int32_t number)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_layer *ivilayer = NULL;
+ struct ivi_layout_layer *next = NULL;
+ uint32_t *id_layer = NULL;
+ int32_t i = 0;
+
+ if (iviscrn == NULL) {
+ weston_log("ivi_layout_screen_set_render_order: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ wl_list_for_each_safe(ivilayer, next,
+ &iviscrn->pending.layer_list, 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;
+ }
+
+ for (i = 0; i < number; i++) {
+ id_layer = &pLayer[i]->id_layer;
+ wl_list_for_each(ivilayer, &layout->layer_list, link) {
+ if (*id_layer != ivilayer->id_layer) {
+ continue;
+ }
+
+ if (!wl_list_empty(&ivilayer->pending.link)) {
+ wl_list_remove(&ivilayer->pending.link);
+ }
+ wl_list_init(&ivilayer->pending.link);
+ wl_list_insert(&iviscrn->pending.layer_list,
+ &ivilayer->pending.link);
+ break;
+ }
+ }
+
+ iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT struct weston_output *
+ivi_layout_screen_get_output(struct ivi_layout_screen *iviscrn)
+{
+ return iviscrn->output;
+}
+
+/**
+ * This function is used by the additional ivi-module because of dumping ivi_surface sceenshot.
+ * The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of Genivi's Layer Management.
+ * This function is used to get the result of drawing by clients.
+ */
+WL_EXPORT struct weston_surface *
+ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf)
+{
+ return ivisurf != NULL ? ivisurf->surface : NULL;
+}
+
+WL_EXPORT int32_t
+ivi_layout_layer_add_notification(struct ivi_layout_layer *ivilayer,
+ layer_property_notification_func callback,
+ void *userdata)
+{
+ struct ivi_layout_notification_callback *prop_callback = NULL;
+
+ if (ivilayer == NULL || callback == NULL) {
+ weston_log("ivi_layout_layer_add_notification: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop_callback = malloc(sizeof *prop_callback);
+ if (prop_callback == NULL) {
+ weston_log("fails to allocate memory\n");
+ return IVI_FAILED;
+ }
+
+ prop_callback->callback = callback;
+ prop_callback->data = userdata;
+
+ return add_notification(&ivilayer->property_changed,
+ layer_prop_changed,
+ prop_callback);
+}
+
+WL_EXPORT void
+ivi_layout_layer_remove_notification(struct ivi_layout_layer *ivilayer)
+{
+ if (ivilayer == NULL) {
+ weston_log("ivi_layout_layer_remove_notification: invalid argument\n");
+ return;
+ }
+
+ remove_all_notification(&ivilayer->property_changed.listener_list);
+}
+
+WL_EXPORT const struct ivi_layout_surface_properties *
+ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf)
+{
+ if (ivisurf == NULL) {
+ weston_log("ivi_layout_get_properties_of_surface: invalid argument\n");
+ return NULL;
+ }
+
+ return &ivisurf->prop;
+}
+
+WL_EXPORT int32_t
+ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer,
+ struct ivi_layout_surface *addsurf)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_surface *ivisurf = NULL;
+ struct ivi_layout_surface *next = NULL;
+ int is_surf_in_layer = 0;
+
+ if (ivilayer == NULL || addsurf == NULL) {
+ weston_log("ivi_layout_layer_add_surface: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ is_surf_in_layer = is_surface_in_layer(addsurf, ivilayer);
+ if (is_surf_in_layer == 1) {
+ weston_log("ivi_layout_layer_add_surface: addsurf is already available\n");
+ return IVI_SUCCEEDED;
+ }
+
+ 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_insert(&ivilayer->pending.surface_list,
+ &ivisurf->pending.link);
+ break;
+ }
+ }
+
+ ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT void
+ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer,
+ struct ivi_layout_surface *remsurf)
+{
+ struct ivi_layout_surface *ivisurf = NULL;
+ struct ivi_layout_surface *next = NULL;
+
+ if (ivilayer == NULL || remsurf == NULL) {
+ weston_log("ivi_layout_layer_remove_surface: invalid argument\n");
+ return;
+ }
+
+ 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_init(&ivisurf->pending.link);
+ break;
+ }
+ }
+
+ remsurf->event_mask |= IVI_NOTIFICATION_REMOVE;
+}
+
+WL_EXPORT int32_t
+ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height)
+{
+ struct ivi_layout_surface_properties *prop = NULL;
+
+ if (ivisurf == NULL) {
+ weston_log("ivi_layout_surface_set_source_rectangle: invalid argument\n");
+ return IVI_FAILED;
+ }
+
+ prop = &ivisurf->pending.prop;
+ prop->source_x = x;
+ prop->source_y = y;
+ prop->source_width = width;
+ prop->source_height = height;
+
+ ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
+
+ return IVI_SUCCEEDED;
+}
+
+WL_EXPORT int32_t
+ivi_layout_commit_changes(void)
+{
+ struct ivi_layout *layout = get_instance();
+
+ commit_surface_list(layout);
+ commit_layer_list(layout);
+ commit_screen_list(layout);
+
+ commit_transition(layout);
+
+ commit_changes(layout);
+ send_prop(layout);
+ weston_compositor_schedule_repaint(layout->compositor);
+
+ return IVI_SUCCEEDED;
+}
+
+/***called from ivi-shell**/
+static struct weston_view *
+ivi_layout_get_weston_view(struct ivi_layout_surface *surface)
+{
+ struct weston_view *tmpview = NULL;
+
+ if(surface == NULL)
+ return NULL;
+
+ wl_list_for_each(tmpview, &surface->surface->views, surface_link)
+ {
+ if (tmpview != NULL) {
+ break;
+ }
+ }
+ return tmpview;
+}
+
+static void
+ivi_layout_surface_configure(struct ivi_layout_surface *ivisurf,
+ int32_t width, int32_t height)
+{
+ struct ivi_layout *layout = get_instance();
+ int32_t in_init = 0;
+ ivisurf->surface->width_from_buffer = width;
+ ivisurf->surface->height_from_buffer = height;
+
+ if (ivisurf->prop.source_width == 0 || ivisurf->prop.source_height == 0) {
+ in_init = 1;
+ }
+
+ /* FIXME: when sourceHeight/Width is used as clipping range in image buffer */
+ /* if (ivisurf->prop.sourceWidth == 0 || ivisurf->prop.sourceHeight == 0) { */
+ ivisurf->pending.prop.source_width = width;
+ ivisurf->pending.prop.source_height = height;
+ ivisurf->prop.source_width = width;
+ ivisurf->prop.source_height = height;
+ /* } */
+
+ ivisurf->event_mask |= IVI_NOTIFICATION_CONFIGURE;
+
+ if (in_init) {
+ wl_signal_emit(&layout->surface_notification.configure_changed, ivisurf);
+ } else {
+ ivi_layout_commit_changes();
+ }
+}
+
+WL_EXPORT int32_t
+ivi_layout_surface_set_content_observer(struct ivi_layout_surface *ivisurf,
+ ivi_controller_surface_content_callback callback,
+ void* userdata)
+{
+ int32_t ret = IVI_FAILED;
+
+ if (ivisurf != NULL) {
+ ivisurf->content_observer.callback = callback;
+ ivisurf->content_observer.userdata = userdata;
+ ret = IVI_SUCCEEDED;
+ }
+ return ret;
+}
+
+static struct ivi_layout_surface*
+ivi_layout_surface_create(struct weston_surface *wl_surface,
+ uint32_t id_surface)
+{
+ struct ivi_layout *layout = get_instance();
+ struct ivi_layout_surface *ivisurf = NULL;
+ struct weston_view *tmpview = NULL;
+
+ if (wl_surface == NULL) {
+ weston_log("ivi_layout_surface_create: invalid argument\n");
+ return NULL;
+ }
+
+ ivisurf = get_surface(&layout->surface_list, id_surface);
+ if (ivisurf != NULL) {
+ if (ivisurf->surface != NULL) {
+ weston_log("id_surface(%d) is already created\n", id_surface);
+ return NULL;
+ }
+ }
+
+ ivisurf = calloc(1, sizeof *ivisurf);
+ if (ivisurf == NULL) {
+ weston_log("fails to allocate memory\n");
+ return NULL;
+ }
+
+ wl_list_init(&ivisurf->link);
+ wl_signal_init(&ivisurf->property_changed);
+ wl_signal_init(&ivisurf->configured);
+ wl_list_init(&ivisurf->layer_list);
+ ivisurf->id_surface = id_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) {
+ weston_log("fails to allocate memory\n");
+ }
+
+ 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);
+
+ init_surface_properties(&ivisurf->prop);
+ ivisurf->event_mask = 0;
+
+ ivisurf->pending.prop = ivisurf->prop;
+ wl_list_init(&ivisurf->pending.link);
+
+ wl_list_init(&ivisurf->order.link);
+ wl_list_init(&ivisurf->order.layer_list);
+
+ wl_list_insert(&layout->surface_list, &ivisurf->link);
+
+ wl_signal_emit(&layout->surface_notification.created, ivisurf);
+
+ return ivisurf;
+}
+
+static void
+ivi_layout_init_with_compositor(struct weston_compositor *ec)
+{
+ struct ivi_layout *layout = get_instance();
+
+ layout->compositor = ec;
+
+ wl_list_init(&layout->surface_list);
+ wl_list_init(&layout->layer_list);
+ wl_list_init(&layout->screen_list);
+
+ wl_signal_init(&layout->layer_notification.created);
+ wl_signal_init(&layout->layer_notification.removed);
+
+ wl_signal_init(&layout->surface_notification.created);
+ wl_signal_init(&layout->surface_notification.removed);
+ wl_signal_init(&layout->surface_notification.configure_changed);
+
+ /* Add layout_layer at the last of weston_compositor.layer_list */
+ weston_layer_init(&layout->layout_layer, ec->layer_list.prev);
+
+ create_screen(ec);
+
+ layout->transitions = ivi_layout_transition_set_create(ec);
+ wl_list_init(&layout->pending_transition_list);
+}
+
+
+static void
+ivi_layout_surface_add_configured_listener(struct ivi_layout_surface* ivisurf,
+ struct wl_listener* listener)
+{
+ wl_signal_add(&ivisurf->configured, listener);
+}
+
+WL_EXPORT struct ivi_layout_interface ivi_layout_interface = {
+ .get_weston_view = ivi_layout_get_weston_view,
+ .surface_configure = ivi_layout_surface_configure,
+ .surface_create = ivi_layout_surface_create,
+ .init_with_compositor = ivi_layout_init_with_compositor,
+ .get_surface_dimension = ivi_layout_surface_get_dimension,
+ .add_surface_configured_listener = ivi_layout_surface_add_configured_listener
+};