summaryrefslogtreecommitdiff
path: root/weston-ivi-shell/src/ivi-controller.c
diff options
context:
space:
mode:
Diffstat (limited to 'weston-ivi-shell/src/ivi-controller.c')
-rw-r--r--weston-ivi-shell/src/ivi-controller.c1556
1 files changed, 1556 insertions, 0 deletions
diff --git a/weston-ivi-shell/src/ivi-controller.c b/weston-ivi-shell/src/ivi-controller.c
new file mode 100644
index 0000000..871fc05
--- /dev/null
+++ b/weston-ivi-shell/src/ivi-controller.c
@@ -0,0 +1,1556 @@
+/*
+ * 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.
+ */
+/*
+ * This is implementation of ivi-controller.xml. This implementation uses
+ * ivi-extension APIs, which uses ivi_controller_interface pvoided by
+ * ivi-layout.c in weston.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <weston/compositor.h>
+#include <weston/ivi-layout-export.h>
+#include "ivi-controller-server-protocol.h"
+#include "bitmap.h"
+
+#include "wayland-util.h"
+#ifdef IVI_SHARE_ENABLE
+# include "ivi-share.h"
+#endif
+
+struct ivilayer;
+struct iviscreen;
+
+struct ivisurface {
+ struct wl_list link;
+ struct ivishell *shell;
+ uint32_t update_count;
+ struct ivi_layout_surface *layout_surface;
+ const struct ivi_layout_surface_properties *prop;
+ struct wl_listener property_changed;
+ struct wl_listener surface_destroy_listener;
+ struct wl_list resource_list;
+};
+
+struct ivilayer {
+ struct wl_list link;
+ struct ivishell *shell;
+ struct ivi_layout_layer *layout_layer;
+ const struct ivi_layout_layer_properties *prop;
+ struct wl_listener property_changed;
+ struct wl_list resource_list;
+};
+
+struct iviscreen {
+ struct wl_list link;
+ struct ivishell *shell;
+ uint32_t id_screen;
+ struct weston_output *output;
+ struct wl_list resource_list;
+};
+
+struct ivicontroller {
+ struct wl_resource *resource;
+ uint32_t id;
+ struct wl_client *client;
+ struct wl_list link;
+ struct ivishell *shell;
+};
+
+struct ivishell {
+ struct weston_compositor *compositor;
+ const struct ivi_layout_interface *interface;
+
+ struct wl_list list_surface;
+ struct wl_list list_layer;
+ struct wl_list list_screen;
+
+ struct wl_list list_controller;
+
+ struct wl_listener surface_created;
+ struct wl_listener surface_removed;
+ struct wl_listener surface_configured;
+
+ struct wl_listener layer_created;
+ struct wl_listener layer_removed;
+};
+
+struct screenshot_frame_listener {
+ struct wl_listener listener;
+ char *filename;
+};
+
+static void
+destroy_ivicontroller_surface(struct wl_resource *resource)
+{
+ wl_list_remove(wl_resource_get_link(resource));
+}
+
+static void
+destroy_ivicontroller_layer(struct wl_resource *resource)
+{
+ wl_list_remove(wl_resource_get_link(resource));
+}
+
+static void
+destroy_ivicontroller_screen(struct wl_resource *resource)
+{
+ wl_list_remove(wl_resource_get_link(resource));
+}
+
+static void
+unbind_resource_controller(struct wl_resource *resource)
+{
+ struct ivicontroller *controller = wl_resource_get_user_data(resource);
+
+ wl_list_remove(&controller->link);
+
+ free(controller);
+ controller = NULL;
+}
+
+static struct ivisurface*
+get_surface(struct wl_list *list_surf, struct ivi_layout_surface *layout_surface)
+{
+ struct ivisurface *ivisurf = NULL;
+
+ wl_list_for_each(ivisurf, list_surf, link) {
+ if (layout_surface == ivisurf->layout_surface) {
+ return ivisurf;
+ }
+ }
+
+ return NULL;
+}
+
+static struct ivilayer*
+get_layer(struct wl_list *list_layer, struct ivi_layout_layer *layout_layer)
+{
+ struct ivilayer *ivilayer = NULL;
+
+ wl_list_for_each(ivilayer, list_layer, link) {
+ if (layout_layer == ivilayer->layout_layer) {
+ return ivilayer;
+ }
+ }
+
+ return NULL;
+}
+
+static void
+send_surface_add_event(struct ivisurface *ivisurf,
+ struct wl_resource *resource,
+ enum ivi_layout_notification_mask mask)
+{
+ struct wl_resource *layer_resource;
+ struct ivi_layout_layer **pArray = NULL;
+ int32_t length = 0;
+ int32_t ans = 0;
+ int i = 0;
+ struct ivilayer *ivilayer = NULL;
+ struct ivishell *shell = ivisurf->shell;
+ const struct ivi_layout_interface *lyt = shell->interface;
+ struct wl_client *client = wl_resource_get_client(resource);
+
+ ans = lyt->get_layers_under_surface(ivisurf->layout_surface,
+ &length, &pArray);
+ if (0 != ans) {
+ weston_log("failed to get layers at send_surface_add_event\n");
+ return;
+ }
+
+ /* Send Null to cancel added surface */
+ if (mask & IVI_NOTIFICATION_REMOVE) {
+ ivi_controller_surface_send_layer(resource, NULL);
+ }
+ else if (mask & IVI_NOTIFICATION_ADD) {
+ for (i = 0; i < (int)length; i++) {
+ /* Send new surface event */
+ if (wl_list_empty(&shell->list_layer)) {
+ break;
+ }
+
+ wl_list_for_each(ivilayer, &shell->list_layer, link) {
+ if (ivilayer->layout_layer == pArray[i]) {
+ layer_resource =
+ wl_resource_find_for_client(&ivilayer->resource_list,
+ client);
+ if (layer_resource != NULL) {
+ ivi_controller_surface_send_layer(resource, layer_resource);
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ free(pArray);
+ pArray = NULL;
+}
+
+static void
+send_surface_configure_event(struct ivisurface *ivisurf,
+ struct wl_resource *resource)
+{
+ struct weston_surface *surface;
+ struct ivi_layout_surface* layout_surface;
+ struct ivishell *shell = ivisurf->shell;
+ const struct ivi_layout_interface *lyt = shell->interface;
+
+ layout_surface = ivisurf->layout_surface;
+
+ surface = lyt->surface_get_weston_surface(layout_surface);
+
+ if (!surface)
+ return;
+
+ if ((surface->width == 0) || (surface->height == 0))
+ return;
+
+ ivi_controller_surface_send_configuration(resource,
+ surface->width,
+ surface->height);
+}
+
+static void
+send_surface_event(struct wl_resource *resource,
+ struct ivisurface *ivisurf,
+ const struct ivi_layout_surface_properties *prop,
+ uint32_t mask)
+{
+ if (mask & IVI_NOTIFICATION_OPACITY) {
+ ivi_controller_surface_send_opacity(resource,
+ prop->opacity);
+ }
+ if (mask & IVI_NOTIFICATION_SOURCE_RECT) {
+ ivi_controller_surface_send_source_rectangle(resource,
+ prop->source_x, prop->source_y,
+ prop->source_width, prop->source_height);
+ }
+ if (mask & IVI_NOTIFICATION_DEST_RECT) {
+ ivi_controller_surface_send_destination_rectangle(resource,
+ prop->dest_x, prop->dest_y,
+ prop->dest_width, prop->dest_height);
+ }
+ if (mask & IVI_NOTIFICATION_ORIENTATION) {
+ ivi_controller_surface_send_orientation(resource,
+ prop->orientation);
+ }
+ if (mask & IVI_NOTIFICATION_VISIBILITY) {
+ ivi_controller_surface_send_visibility(resource,
+ prop->visibility);
+ }
+ if (mask & IVI_NOTIFICATION_REMOVE) {
+ send_surface_add_event(ivisurf, resource, IVI_NOTIFICATION_REMOVE);
+ }
+ if (mask & IVI_NOTIFICATION_ADD) {
+ send_surface_add_event(ivisurf, resource, IVI_NOTIFICATION_ADD);
+ }
+ if (mask & IVI_NOTIFICATION_CONFIGURE) {
+ send_surface_configure_event(ivisurf, resource);
+ }
+}
+
+static void
+send_surface_prop(struct wl_listener *listener, void *data)
+{
+ struct ivisurface *ivisurf =
+ wl_container_of(listener, ivisurf,
+ property_changed);
+ (void)data;
+ enum ivi_layout_notification_mask mask;
+ struct wl_resource *resource;
+
+ mask = ivisurf->prop->event_mask;
+
+ wl_resource_for_each(resource, &ivisurf->resource_list) {
+ send_surface_event(resource, ivisurf, ivisurf->prop, mask);
+ }
+}
+
+static void
+send_layer_add_event(struct ivilayer *ivilayer,
+ struct wl_resource *resource,
+ enum ivi_layout_notification_mask mask)
+{
+ struct weston_output **pArray = NULL;
+ int32_t length = 0;
+ int32_t ans = 0;
+ int i = 0;
+ struct iviscreen *iviscrn = NULL;
+ struct ivishell *shell = ivilayer->shell;
+ const struct ivi_layout_interface *lyt = shell->interface;
+ struct wl_client *client = wl_resource_get_client(resource);
+ struct wl_resource *resource_output = NULL;
+
+ ans = lyt->get_screens_under_layer(ivilayer->layout_layer,
+ &length, &pArray);
+ if (0 != ans) {
+ weston_log("failed to get screens at send_layer_add_event\n");
+ return;
+ }
+
+ /* Send Null to cancel added layer */
+ if (mask & IVI_NOTIFICATION_REMOVE) {
+ ivi_controller_layer_send_screen(resource, NULL);
+ }
+ else if (mask & IVI_NOTIFICATION_ADD) {
+ for (i = 0; i < (int)length; i++) {
+ /* Send new layer event */
+ if (wl_list_empty(&shell->list_screen)){
+ break;
+ }
+
+ wl_list_for_each(iviscrn, &shell->list_screen, link) {
+ if (iviscrn->output == pArray[i]) {
+ resource_output =
+ wl_resource_find_for_client(&iviscrn->output->resource_list,
+ client);
+ if (resource_output != NULL) {
+ ivi_controller_layer_send_screen(resource, resource_output);
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ free(pArray);
+ pArray = NULL;
+}
+
+static void
+send_layer_event(struct wl_resource *resource,
+ struct ivilayer *ivilayer,
+ const struct ivi_layout_layer_properties *prop,
+ uint32_t mask)
+{
+ if (mask & IVI_NOTIFICATION_OPACITY) {
+ ivi_controller_layer_send_opacity(resource,
+ prop->opacity);
+ }
+ if (mask & IVI_NOTIFICATION_SOURCE_RECT) {
+ ivi_controller_layer_send_source_rectangle(resource,
+ prop->source_x,
+ prop->source_y,
+ prop->source_width,
+ prop->source_height);
+ }
+ if (mask & IVI_NOTIFICATION_DEST_RECT) {
+ ivi_controller_layer_send_destination_rectangle(resource,
+ prop->dest_x,
+ prop->dest_y,
+ prop->dest_width,
+ prop->dest_height);
+ }
+ if (mask & IVI_NOTIFICATION_ORIENTATION) {
+ ivi_controller_layer_send_orientation(resource,
+ prop->orientation);
+ }
+ if (mask & IVI_NOTIFICATION_VISIBILITY) {
+ ivi_controller_layer_send_visibility(resource,
+ prop->visibility);
+ }
+ if (mask & IVI_NOTIFICATION_REMOVE) {
+ send_layer_add_event(ivilayer, resource, IVI_NOTIFICATION_REMOVE);
+ }
+ if (mask & IVI_NOTIFICATION_ADD) {
+ send_layer_add_event(ivilayer, resource, IVI_NOTIFICATION_ADD);
+ }
+}
+
+static void
+send_layer_prop(struct wl_listener *listener, void *data)
+{
+ struct ivilayer *ivilayer =
+ wl_container_of(listener, ivilayer, property_changed);
+ (void)data;
+ enum ivi_layout_notification_mask mask;
+ struct wl_resource *resource;
+
+ mask = ivilayer->prop->event_mask;
+
+ wl_resource_for_each(resource, &ivilayer->resource_list) {
+ send_layer_event(resource, ivilayer, ivilayer->prop, mask);
+ }
+}
+
+static void
+controller_surface_set_opacity(struct wl_client *client,
+ struct wl_resource *resource,
+ wl_fixed_t opacity)
+{
+ struct ivisurface *ivisurf = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = ivisurf->shell->interface;
+ (void)client;
+ lyt->surface_set_opacity(ivisurf->layout_surface, opacity);
+}
+
+static void
+controller_surface_set_source_rectangle(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t x,
+ int32_t y,
+ int32_t width,
+ int32_t height)
+{
+ struct ivisurface *ivisurf = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = ivisurf->shell->interface;
+ (void)client;
+ lyt->surface_set_source_rectangle(ivisurf->layout_surface,
+ (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height);
+}
+
+static void
+controller_surface_set_destination_rectangle(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t x,
+ int32_t y,
+ int32_t width,
+ int32_t height)
+{
+ struct ivisurface *ivisurf = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = ivisurf->shell->interface;
+ (void)client;
+
+ // TODO: create set transition type protocol
+ lyt->surface_set_transition(ivisurf->layout_surface,
+ IVI_LAYOUT_TRANSITION_NONE,
+ 300); // ms
+
+ lyt->surface_set_destination_rectangle(ivisurf->layout_surface,
+ (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height);
+}
+
+static void
+controller_surface_set_visibility(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t visibility)
+{
+ struct ivisurface *ivisurf = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = ivisurf->shell->interface;
+ (void)client;
+ lyt->surface_set_visibility(ivisurf->layout_surface, visibility);
+}
+
+static void
+controller_surface_set_configuration(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t width, int32_t height)
+{
+ /* This interface has been supported yet. */
+ (void)client;
+ (void)resource;
+ (void)width;
+ (void)height;
+}
+
+static void
+controller_surface_set_orientation(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t orientation)
+{
+ struct ivisurface *ivisurf = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = ivisurf->shell->interface;
+ (void)client;
+ lyt->surface_set_orientation(ivisurf->layout_surface, (uint32_t)orientation);
+}
+
+static void
+controller_surface_screenshot(struct wl_client *client,
+ struct wl_resource *resource,
+ const char *filename)
+{
+ int32_t result = IVI_FAILED;
+ struct ivisurface *ivisurf = wl_resource_get_user_data(resource);
+ struct weston_surface *weston_surface = NULL;
+ int32_t width = 0;
+ int32_t height = 0;
+ int32_t stride = 0;
+ int32_t size = 0;
+ const struct ivi_layout_interface *lyt = ivisurf->shell->interface;
+ char *buffer = NULL;
+ int32_t image_stride = 0;
+ int32_t image_size = 0;
+ char *image_buffer = NULL;
+ int32_t row = 0;
+ int32_t col = 0;
+ int32_t offset = 0;
+ int32_t image_offset = 0;
+
+ result = lyt->surface_get_size(ivisurf->layout_surface, &width,
+ &height, &stride);
+ if (result != IVI_SUCCEEDED) {
+ weston_log("failed to get surface size\n");
+ return;
+ }
+
+ size = stride * height;
+ image_stride = (((width * 3) + 31) & ~31);
+ image_size = image_stride * height;
+
+ buffer = malloc(size);
+ image_buffer = malloc(image_size);
+ if (buffer == NULL || image_buffer == NULL) {
+ free(image_buffer);
+ free(buffer);
+ weston_log("failed to allocate memory\n");
+ return;
+ }
+
+ weston_surface = lyt->surface_get_weston_surface(ivisurf->layout_surface);
+
+ result = lyt->surface_dump(weston_surface, buffer, size, 0, 0,
+ width, height);
+
+ if (result != IVI_SUCCEEDED) {
+ free(image_buffer);
+ free(buffer);
+ weston_log("failed to dump surface\n");
+ return;
+ }
+
+ for (row = 0; row < height; ++row) {
+ for (col = 0; col < width; ++col) {
+ offset = row * width + col;
+ image_offset = (height - row - 1) * width + col;
+
+ image_buffer[image_offset * 3] = buffer[offset * 4 + 2];
+ image_buffer[image_offset * 3 + 1] = buffer[offset * 4 + 1];
+ image_buffer[image_offset * 3 + 2] = buffer[offset * 4];
+ }
+ }
+
+ free(buffer);
+
+ if (save_as_bitmap(filename, (const char *)image_buffer,
+ image_size, width, height, 24) != 0) {
+ weston_log("failed to take screenshot\n");
+ }
+
+ free(image_buffer);
+}
+
+
+static void
+controller_surface_send_stats(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ struct ivisurface *ivisurf = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = ivisurf->shell->interface;
+ struct weston_surface *surface;
+ struct wl_client* target_client;
+ pid_t pid;
+ uid_t uid;
+ gid_t gid;
+
+ /* Get pid that creates surface */
+ surface = lyt->surface_get_weston_surface(ivisurf->layout_surface);
+ target_client = wl_resource_get_client(surface->resource);
+
+ wl_client_get_credentials(target_client, &pid, &uid, &gid);
+
+ ivi_controller_surface_send_stats(resource, 0, 0,
+ ivisurf->update_count, pid, "");
+}
+
+static void
+controller_surface_destroy(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t destroy_scene_object)
+{
+ (void)client;
+ struct ivisurface *ivisurf = wl_resource_get_user_data(resource);
+
+ wl_resource_destroy(resource);
+
+ if (wl_list_empty(&ivisurf->resource_list) && destroy_scene_object) {
+ wl_list_remove(&ivisurf->link);
+ free(ivisurf);
+ }
+}
+
+static const
+struct ivi_controller_surface_interface controller_surface_implementation = {
+ controller_surface_set_visibility,
+ controller_surface_set_opacity,
+ controller_surface_set_source_rectangle,
+ controller_surface_set_destination_rectangle,
+ controller_surface_set_configuration,
+ controller_surface_set_orientation,
+ controller_surface_screenshot,
+ controller_surface_send_stats,
+ controller_surface_destroy
+};
+
+static void
+controller_layer_set_source_rectangle(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t x,
+ int32_t y,
+ int32_t width,
+ int32_t height)
+{
+ struct ivilayer *ivilayer = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = ivilayer->shell->interface;
+ (void)client;
+ lyt->layer_set_source_rectangle(ivilayer->layout_layer,
+ (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height);
+}
+
+static void
+controller_layer_set_destination_rectangle(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t x,
+ int32_t y,
+ int32_t width,
+ int32_t height)
+{
+ struct ivilayer *ivilayer = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = ivilayer->shell->interface;
+ (void)client;
+ lyt->layer_set_destination_rectangle(ivilayer->layout_layer,
+ (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height);
+}
+
+static void
+controller_layer_set_visibility(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t visibility)
+{
+ struct ivilayer *ivilayer = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = ivilayer->shell->interface;
+ (void)client;
+ lyt->layer_set_visibility(ivilayer->layout_layer, visibility);
+}
+
+static void
+controller_layer_set_opacity(struct wl_client *client,
+ struct wl_resource *resource,
+ wl_fixed_t opacity)
+{
+ struct ivilayer *ivilayer = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = ivilayer->shell->interface;
+ (void)client;
+ lyt->layer_set_opacity(ivilayer->layout_layer, opacity);
+}
+
+static void
+controller_layer_set_configuration(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t width,
+ int32_t height)
+{
+ /* This interface has been supported yet. */
+ (void)client;
+ (void)resource;
+ (void)width;
+ (void)height;
+}
+
+static void
+controller_layer_set_orientation(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t orientation)
+{
+ struct ivilayer *ivilayer = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = ivilayer->shell->interface;
+ (void)client;
+ lyt->layer_set_orientation(ivilayer->layout_layer, (uint32_t)orientation);
+}
+
+static void
+controller_layer_clear_surfaces(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ struct ivilayer *ivilayer = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = ivilayer->shell->interface;
+ (void)client;
+ lyt->layer_set_render_order(ivilayer->layout_layer, NULL, 0);
+}
+
+static void
+controller_layer_add_surface(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *surface)
+{
+ struct ivilayer *ivilayer = wl_resource_get_user_data(resource);
+ struct ivisurface *ivisurf = wl_resource_get_user_data(surface);
+ const struct ivi_layout_interface *lyt = ivilayer->shell->interface;
+ (void)client;
+ lyt->layer_add_surface(ivilayer->layout_layer, ivisurf->layout_surface);
+}
+
+static void
+controller_layer_remove_surface(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *surface)
+{
+ struct ivilayer *ivilayer = wl_resource_get_user_data(resource);
+ struct ivisurface *ivisurf = wl_resource_get_user_data(surface);
+ const struct ivi_layout_interface *lyt = ivilayer->shell->interface;
+ (void)client;
+ lyt->layer_remove_surface(ivilayer->layout_layer, ivisurf->layout_surface);
+}
+
+static void
+controller_layer_screenshot(struct wl_client *client,
+ struct wl_resource *resource,
+ const char *filename)
+{
+ (void)client;
+ (void)resource;
+ (void)filename;
+}
+
+static void
+controller_layer_set_render_order(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_array *id_surfaces)
+{
+ struct ivilayer *ivilayer = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = ivilayer->shell->interface;
+ struct ivi_layout_surface **layoutsurf_array = NULL;
+ struct ivisurface *ivisurf = NULL;
+ uint32_t *id_surface = NULL;
+ uint32_t id_layout_surface = 0;
+ int i = 0;
+ (void)client;
+
+ layoutsurf_array = (struct ivi_layout_surface**)calloc(
+ id_surfaces->size, sizeof(void*));
+
+ wl_array_for_each(id_surface, id_surfaces) {
+ wl_list_for_each(ivisurf, &ivilayer->shell->list_surface, link) {
+ id_layout_surface = lyt->get_id_of_surface(ivisurf->layout_surface);
+ if (*id_surface == id_layout_surface) {
+ layoutsurf_array[i] = ivisurf->layout_surface;
+ i++;
+ break;
+ }
+ }
+ }
+
+ lyt->layer_set_render_order(ivilayer->layout_layer,
+ layoutsurf_array, i);
+ free(layoutsurf_array);
+}
+
+static void
+controller_layer_destroy(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t destroy_scene_object)
+{
+ struct ivilayer *ivilayer = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = ivilayer->shell->interface;
+ (void)client;
+
+ if (destroy_scene_object) {
+ if (ivilayer->layout_layer != NULL) {
+ lyt->layer_destroy(ivilayer->layout_layer);
+ ivilayer->layout_layer = NULL;
+ }
+
+ wl_resource_destroy(resource);
+
+ if (wl_list_empty(&ivilayer->resource_list)) {
+ wl_list_remove(&ivilayer->link);
+ free(ivilayer);
+ }
+ } else {
+ wl_resource_destroy(resource);
+ }
+}
+
+static const
+struct ivi_controller_layer_interface controller_layer_implementation = {
+ controller_layer_set_visibility,
+ controller_layer_set_opacity,
+ controller_layer_set_source_rectangle,
+ controller_layer_set_destination_rectangle,
+ controller_layer_set_configuration,
+ controller_layer_set_orientation,
+ controller_layer_screenshot,
+ controller_layer_clear_surfaces,
+ controller_layer_add_surface,
+ controller_layer_remove_surface,
+ controller_layer_set_render_order,
+ controller_layer_destroy
+};
+
+static void
+controller_screen_destroy(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ (void)client;
+ wl_resource_destroy(resource);
+}
+
+static void
+controller_screen_clear(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ struct iviscreen *iviscrn = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = iviscrn->shell->interface;
+ (void)client;
+ lyt->screen_set_render_order(iviscrn->output, NULL, 0);
+}
+
+static void
+controller_screen_add_layer(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *layer)
+{
+ struct iviscreen *iviscrn = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = iviscrn->shell->interface;
+ struct ivilayer *ivilayer = wl_resource_get_user_data(layer);
+ (void)client;
+ lyt->screen_add_layer(iviscrn->output, ivilayer->layout_layer);
+}
+
+static void
+controller_screenshot_notify(struct wl_listener *listener, void *data)
+{
+ struct screenshot_frame_listener *l =
+ wl_container_of(listener, l, listener);
+ char *filename = l->filename;
+
+ struct weston_output *output = data;
+ int32_t width = 0;
+ int32_t height = 0;
+ int32_t stride = 0;
+ uint8_t *readpixs = NULL;
+
+ --output->disable_planes;
+ wl_list_remove(&listener->link);
+
+ width = output->current_mode->width;
+ height = output->current_mode->height;
+ stride = width * (PIXMAN_FORMAT_BPP(output->compositor->read_format) / 8);
+
+ readpixs = malloc(stride * height);
+ if (readpixs == NULL) {
+ weston_log("fails to allocate memory\n");
+ free(l->filename);
+ free(l);
+ return;
+ }
+
+ output->compositor->renderer->read_pixels(
+ output,
+ output->compositor->read_format,
+ readpixs,
+ 0,
+ 0,
+ width,
+ height);
+
+ save_as_bitmap(filename, (const char*)readpixs, stride * height, width, height,
+ PIXMAN_FORMAT_BPP(output->compositor->read_format));
+ free(readpixs);
+ free(l->filename);
+ free(l);
+}
+
+static void
+controller_screen_screenshot(struct wl_client *client,
+ struct wl_resource *resource,
+ const char *filename)
+{
+ struct iviscreen *iviscrn = wl_resource_get_user_data(resource);
+ struct screenshot_frame_listener *l;
+ (void)client;
+
+ l = malloc(sizeof *l);
+ if(l == NULL) {
+ fprintf(stderr, "fails to allocate memory\n");
+ return;
+ }
+
+ l->filename = strdup(filename);
+ if(l->filename == NULL) {
+ fprintf(stderr, "fails to allocate memory\n");
+ free(l);
+ return;
+ }
+
+ l->listener.notify = controller_screenshot_notify;
+ wl_signal_add(&iviscrn->output->frame_signal, &l->listener);
+ iviscrn->output->disable_planes++;
+ weston_output_schedule_repaint(iviscrn->output);
+ return;
+}
+
+static void
+controller_screen_set_render_order(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_array *id_layers)
+{
+ struct iviscreen *iviscrn = wl_resource_get_user_data(resource);
+ const struct ivi_layout_interface *lyt = iviscrn->shell->interface;
+ struct ivi_layout_layer **layoutlayer_array = NULL;
+ struct ivilayer *ivilayer = NULL;
+ uint32_t *id_layer = NULL;
+ uint32_t id_layout_layer = 0;
+ int i = 0;
+ (void)client;
+
+ layoutlayer_array = (struct ivi_layout_layer**)calloc(
+ id_layers->size, sizeof(void*));
+
+ wl_array_for_each(id_layer, id_layers) {
+ wl_list_for_each(ivilayer, &iviscrn->shell->list_layer, link) {
+ id_layout_layer = lyt->get_id_of_layer(ivilayer->layout_layer);
+ if (*id_layer == id_layout_layer) {
+ layoutlayer_array[i] = ivilayer->layout_layer;
+ i++;
+ break;
+ }
+ }
+ }
+
+ lyt->screen_set_render_order(iviscrn->output,
+ layoutlayer_array, i);
+ free(layoutlayer_array);
+}
+
+static const
+struct ivi_controller_screen_interface controller_screen_implementation = {
+ controller_screen_destroy,
+ controller_screen_clear,
+ controller_screen_add_layer,
+ controller_screen_screenshot,
+ controller_screen_set_render_order
+};
+
+static void
+controller_commit_changes(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ int32_t ans = 0;
+ (void)client;
+ struct ivicontroller *controller = wl_resource_get_user_data(resource);
+
+ ans = controller->shell->interface->commit_changes();
+ if (ans < 0) {
+ weston_log("Failed to commit changes at controller_commit_changes\n");
+ }
+}
+
+static void
+controller_layer_create(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id_layer,
+ int32_t width,
+ int32_t height,
+ uint32_t id)
+{
+ struct wl_resource *layer_resource;
+ struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
+ struct ivishell *shell = ctrl->shell;
+ const struct ivi_layout_interface *lyt = shell->interface;
+ struct ivi_layout_layer *layout_layer = NULL;
+ struct ivilayer *ivilayer = NULL;
+ const struct ivi_layout_layer_properties *prop;
+
+ layout_layer = lyt->get_layer_from_id(id_layer);
+ if (layout_layer == NULL) {
+ layout_layer = lyt->layer_create_with_dimension(id_layer,
+ (uint32_t)width, (uint32_t)height);
+ if (layout_layer == NULL) {
+ weston_log("id_layer is already created\n");
+ return;
+ }
+ }
+
+ /* ivilayer will be created by layer_event_create */
+ ivilayer = get_layer(&shell->list_layer, layout_layer);
+ if (ivilayer == NULL) {
+ weston_log("couldn't get layer object\n");
+ return;
+ }
+
+ layer_resource = wl_resource_create(client,
+ &ivi_controller_layer_interface, 1, id);
+ if (layer_resource == NULL) {
+ weston_log("couldn't get layer object\n");
+ return;
+ }
+
+ wl_list_insert(&ivilayer->resource_list, wl_resource_get_link(layer_resource));
+ wl_resource_set_implementation(layer_resource,
+ &controller_layer_implementation,
+ ivilayer, destroy_ivicontroller_layer);
+
+ prop = lyt->get_properties_of_layer(ivilayer->layout_layer);
+ send_layer_event(layer_resource, ivilayer,
+ prop, IVI_NOTIFICATION_ALL);
+}
+
+static void
+controller_surface_create(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id_surface,
+ uint32_t id)
+{
+ struct wl_resource *surf_resource;
+ struct ivicontroller *ctrl = wl_resource_get_user_data(resource);
+ struct ivishell *shell = ctrl->shell;
+ const struct ivi_layout_interface *lyt = shell->interface;
+ const struct ivi_layout_surface_properties *prop;
+ struct ivi_layout_surface *layout_surface = NULL;
+ struct ivisurface *ivisurf = NULL;
+
+ layout_surface = lyt->get_surface_from_id(id_surface);
+ if (layout_surface == NULL) {
+ return;
+ }
+
+ ivisurf = get_surface(&shell->list_surface, layout_surface);
+ if (ivisurf == NULL) {
+ return;
+ }
+
+ surf_resource = wl_resource_create(client,
+ &ivi_controller_surface_interface, 1, id);
+ if (surf_resource == NULL) {
+ weston_log("couldn't surface object");
+ return;
+ }
+
+ wl_list_insert(&ivisurf->resource_list, wl_resource_get_link(surf_resource));
+ wl_resource_set_implementation(surf_resource,
+ &controller_surface_implementation,
+ ivisurf, destroy_ivicontroller_surface);
+
+ prop = lyt->get_properties_of_surface(ivisurf->layout_surface);
+
+ send_surface_event(surf_resource, ivisurf, prop, IVI_NOTIFICATION_ALL);
+}
+
+static const struct ivi_controller_interface controller_implementation = {
+ controller_commit_changes,
+ controller_layer_create,
+ controller_surface_create
+};
+
+static void
+add_client_to_resources(struct ivishell *shell,
+ struct wl_client *client,
+ struct ivicontroller *controller)
+{
+ const struct ivi_layout_interface *lyt = shell->interface;
+ struct wl_resource *screen_resource;
+ struct ivisurface* ivisurf = NULL;
+ struct ivilayer* ivilayer = NULL;
+ struct iviscreen* iviscrn = NULL;
+ struct wl_resource *resource_output = NULL;
+ uint32_t id_layout_surface = 0;
+ uint32_t id_layout_layer = 0;
+
+ wl_list_for_each(iviscrn, &shell->list_screen, link) {
+ resource_output = wl_resource_find_for_client(
+ &iviscrn->output->resource_list, client);
+ if (resource_output == NULL) {
+ continue;
+ }
+
+ screen_resource = wl_resource_create(client, &ivi_controller_screen_interface, 1, 0);
+ if (screen_resource == NULL) {
+ weston_log("couldn't new screen controller object");
+ return;
+ }
+
+ wl_resource_set_implementation(screen_resource,
+ &controller_screen_implementation,
+ iviscrn, destroy_ivicontroller_screen);
+
+ wl_list_insert(&iviscrn->resource_list, wl_resource_get_link(screen_resource));
+
+ ivi_controller_send_screen(controller->resource,
+ wl_resource_get_id(resource_output),
+ screen_resource);
+ }
+ wl_list_for_each_reverse(ivilayer, &shell->list_layer, link) {
+ id_layout_layer = lyt->get_id_of_layer(ivilayer->layout_layer);
+
+ ivi_controller_send_layer(controller->resource,
+ id_layout_layer);
+ }
+ wl_list_for_each_reverse(ivisurf, &shell->list_surface, link) {
+ id_layout_surface = lyt->get_id_of_surface(ivisurf->layout_surface);
+
+ ivi_controller_send_surface(controller->resource,
+ id_layout_surface);
+ }
+}
+
+static void
+bind_ivi_controller(struct wl_client *client, void *data,
+ uint32_t version, uint32_t id)
+{
+ struct ivishell *shell = data;
+ struct ivicontroller *controller;
+ (void)version;
+
+ controller = calloc(1, sizeof *controller);
+ if (controller == NULL) {
+ weston_log("no memory to allocate controller\n");
+ return;
+ }
+
+ controller->resource =
+ wl_resource_create(client, &ivi_controller_interface, 1, id);
+ wl_resource_set_implementation(controller->resource,
+ &controller_implementation,
+ controller, unbind_resource_controller);
+
+ controller->shell = shell;
+ controller->client = client;
+ controller->id = id;
+
+ wl_list_insert(&shell->list_controller, &controller->link);
+
+ add_client_to_resources(shell, client, controller);
+}
+
+static struct iviscreen*
+create_screen(struct ivishell *shell, struct weston_output *output)
+{
+ struct iviscreen *iviscrn;
+ iviscrn = calloc(1, sizeof *iviscrn);
+ if (iviscrn == NULL) {
+ weston_log("no memory to allocate client screen\n");
+ return NULL;
+ }
+
+ iviscrn->shell = shell;
+ iviscrn->output = output;
+
+ iviscrn->id_screen = output->id;
+
+ wl_list_init(&iviscrn->link);
+ wl_list_init(&iviscrn->resource_list);
+
+ return iviscrn;
+}
+
+static struct ivilayer*
+create_layer(struct ivishell *shell,
+ struct ivi_layout_layer *layout_layer,
+ uint32_t id_layer)
+{
+ const struct ivi_layout_interface *lyt = shell->interface;
+ struct ivilayer *ivilayer = NULL;
+ struct ivicontroller *controller = NULL;
+
+ ivilayer = calloc(1, sizeof *ivilayer);
+ if (NULL == ivilayer) {
+ weston_log("no memory to allocate client layer\n");
+ return NULL;
+ }
+
+ ivilayer->shell = shell;
+ wl_list_insert(&shell->list_layer, &ivilayer->link);
+ wl_list_init(&ivilayer->resource_list);
+ ivilayer->layout_layer = layout_layer;
+ ivilayer->prop = lyt->get_properties_of_layer(layout_layer);
+
+ ivilayer->property_changed.notify = send_layer_prop;
+ lyt->layer_add_listener(layout_layer, &ivilayer->property_changed);
+
+ wl_list_for_each(controller, &shell->list_controller, link) {
+ ivi_controller_send_layer(controller->resource, id_layer);
+ }
+
+ return ivilayer;
+}
+
+static struct ivisurface*
+create_surface(struct ivishell *shell,
+ struct ivi_layout_surface *layout_surface,
+ uint32_t id_surface)
+{
+ const struct ivi_layout_interface *lyt = shell->interface;
+ struct ivisurface *ivisurf = NULL;
+ struct ivicontroller *controller = NULL;
+
+ ivisurf = calloc(1, sizeof *ivisurf);
+ if (ivisurf == NULL) {
+ weston_log("no memory to allocate client surface\n");
+ return NULL;
+ }
+
+ ivisurf->shell = shell;
+ ivisurf->layout_surface = layout_surface;
+ ivisurf->prop = lyt->get_properties_of_surface(layout_surface);
+ wl_list_insert(&shell->list_surface, &ivisurf->link);
+ wl_list_init(&ivisurf->resource_list);
+
+ wl_list_for_each(controller, &shell->list_controller, link) {
+ ivi_controller_send_surface(controller->resource,
+ id_surface);
+ }
+
+ ivisurf->property_changed.notify = send_surface_prop;
+ lyt->surface_add_listener(layout_surface, &ivisurf->property_changed);
+
+ return ivisurf;
+}
+
+static void
+layer_event_create(struct wl_listener *listener, void *data)
+{
+ struct ivishell *shell = wl_container_of(listener, shell, layer_created);
+ const struct ivi_layout_interface *lyt = shell->interface;
+ struct ivilayer *ivilayer = NULL;
+ struct ivi_layout_layer *layout_layer =
+ (struct ivi_layout_layer *) data;
+ uint32_t id_layer = 0;
+
+ id_layer = lyt->get_id_of_layer(layout_layer);
+
+ ivilayer = create_layer(shell, layout_layer, id_layer);
+ if (ivilayer == NULL) {
+ weston_log("failed to create layer");
+ return;
+ }
+}
+
+static void
+layer_event_remove(struct wl_listener *listener, void *data)
+{
+ struct wl_resource *resource;
+ struct ivishell *shell = wl_container_of(listener, shell, layer_removed);
+ struct ivilayer *ivilayer = NULL;
+ struct ivi_layout_layer *layout_layer =
+ (struct ivi_layout_layer *) data;
+
+ ivilayer = get_layer(&shell->list_layer, layout_layer);
+ if (ivilayer == NULL) {
+ weston_log("id_surface is not created yet\n");
+ return;
+ }
+
+ /*If there is no ivi_controller_layer objects, free
+ * ivilayer immediately. Otherwise wait for clients to destroy
+ * their proxies. */
+ if (wl_list_empty(&ivilayer->resource_list)) {
+ wl_list_remove(&ivilayer->link);
+ wl_list_remove(&ivilayer->property_changed.link);
+ free(ivilayer);
+ } else {
+ wl_resource_for_each(resource, &ivilayer->resource_list) {
+ ivi_controller_layer_send_destroyed(resource);
+ }
+ }
+}
+
+
+static void
+surface_event_create(struct wl_listener *listener, void *data)
+{
+ struct wl_resource *resource;
+ struct ivishell *shell = wl_container_of(listener, shell, surface_created);
+ const struct ivi_layout_interface *lyt = shell->interface;
+ struct ivisurface *ivisurf = NULL;
+ struct ivi_layout_surface *layout_surface =
+ (struct ivi_layout_surface *) data;
+ uint32_t id_surface = 0;
+
+ id_surface = lyt->get_id_of_surface(layout_surface);
+
+ ivisurf = create_surface(shell, layout_surface, id_surface);
+ if (ivisurf == NULL) {
+ weston_log("failed to create surface");
+ return;
+ }
+
+ wl_resource_for_each(resource, &ivisurf->resource_list) {
+ ivi_controller_surface_send_content(resource, IVI_CONTROLLER_SURFACE_CONTENT_STATE_CONTENT_AVAILABLE);
+ }
+}
+
+static void
+surface_event_remove(struct wl_listener *listener, void *data)
+{
+ struct wl_resource *resource;
+ struct ivishell *shell = wl_container_of(listener, shell, surface_removed);
+ struct ivisurface *ivisurf = NULL;
+ struct ivi_layout_surface *layout_surface =
+ (struct ivi_layout_surface *) data;
+
+ ivisurf = get_surface(&shell->list_surface, layout_surface);
+ if (ivisurf == NULL) {
+ weston_log("id_surface is not created yet\n");
+ return;
+ }
+
+ /*If there is no ivi_controller_surface objects, free
+ * ivisurf immediately. Otherwise wait for clients to destroy
+ * their proxies. */
+ if (wl_list_empty(&ivisurf->resource_list)) {
+ wl_list_remove(&ivisurf->link);
+ wl_list_remove(&ivisurf->property_changed.link);
+ free(ivisurf);
+ } else {
+ wl_resource_for_each(resource, &ivisurf->resource_list) {
+ ivi_controller_surface_send_destroyed(resource);
+ }
+ }
+}
+
+static void
+surface_event_configure(struct wl_listener *listener, void *data)
+{
+ struct wl_resource *resource;
+ struct ivishell *shell = wl_container_of(listener, shell, surface_configured);
+ const struct ivi_layout_interface *lyt = shell->interface;
+ struct ivisurface *ivisurf = NULL;
+ struct ivi_layout_surface *layout_surface =
+ (struct ivi_layout_surface *) data;
+ const struct ivi_layout_surface_properties *prop;
+
+ ivisurf = get_surface(&shell->list_surface, layout_surface);
+ if (ivisurf == NULL) {
+ weston_log("id_surface is not created yet\n");
+ return;
+ }
+
+ prop = lyt->get_properties_of_surface(layout_surface);
+
+ wl_resource_for_each(resource, &ivisurf->resource_list) {
+ send_surface_event(resource, ivisurf,
+ prop, IVI_NOTIFICATION_CONFIGURE);
+ }
+}
+
+static int32_t
+check_layout_layers(struct ivishell *shell)
+{
+ struct ivi_layout_layer **pArray = NULL;
+ struct ivilayer *ivilayer = NULL;
+ const struct ivi_layout_interface *lyt = shell->interface;
+ uint32_t id_layer = 0;
+ int32_t length = 0;
+ uint32_t i = 0;
+ int32_t ret = 0;
+
+ ret = lyt->get_layers(&length, &pArray);
+ if(ret != 0) {
+ weston_log("failed to get layers at check_layout_layers\n");
+ return -1;
+ }
+
+ if (length == 0) {
+ /* if length is 0, pArray doesn't need to free.*/
+ return 0;
+ }
+
+ for (i = 0; i < length; i++) {
+ id_layer = lyt->get_id_of_layer(pArray[i]);
+ ivilayer = create_layer(shell, pArray[i], id_layer);
+ if (ivilayer == NULL) {
+ weston_log("failed to create layer");
+ }
+ }
+
+ free(pArray);
+ pArray = NULL;
+
+ return 0;
+}
+
+static int32_t
+check_layout_surfaces(struct ivishell *shell)
+{
+ struct ivi_layout_surface **pArray = NULL;
+ struct ivisurface *ivisurf = NULL;
+ const struct ivi_layout_interface *lyt = shell->interface;
+ uint32_t id_surface = 0;
+ int32_t length = 0;
+ uint32_t i = 0;
+ int32_t ret = 0;
+
+ ret = lyt->get_surfaces(&length, &pArray);
+ if(ret != 0) {
+ weston_log("failed to get surfaces at check_layout_surfaces\n");
+ return -1;
+ }
+
+ if (length == 0) {
+ /* if length is 0, pArray doesn't need to free.*/
+ return 0;
+ }
+
+ for (i = 0; i < length; i++) {
+ id_surface = lyt->get_id_of_surface(pArray[i]);
+ ivisurf = create_surface(shell, pArray[i], id_surface);
+ if (ivisurf == NULL) {
+ weston_log("failed to create surface");
+ }
+ }
+
+ free(pArray);
+ pArray = NULL;
+
+ return 0;
+}
+
+void
+init_ivi_shell(struct weston_compositor *ec, struct ivishell *shell)
+{
+ const struct ivi_layout_interface *lyt = shell->interface;
+ struct weston_output *output = NULL;
+ struct iviscreen *iviscrn = NULL;
+ int32_t ret = 0;
+
+ shell->compositor = ec;
+
+ wl_list_init(&shell->list_surface);
+ wl_list_init(&shell->list_layer);
+ wl_list_init(&shell->list_screen);
+ wl_list_init(&shell->list_controller);
+
+ wl_list_for_each(output, &ec->output_list, link) {
+ iviscrn = create_screen(shell, output);
+ if (iviscrn != NULL) {
+ wl_list_insert(&shell->list_screen, &iviscrn->link);
+ }
+ }
+
+ ret = check_layout_layers(shell);
+ if (ret != 0) {
+ weston_log("failed to check_layout_layers");
+ }
+
+ ret = check_layout_surfaces(shell);
+ if (ret != 0) {
+ weston_log("failed to check_layout_surfaces");
+ }
+
+ shell->layer_created.notify = layer_event_create;
+ shell->layer_removed.notify = layer_event_remove;
+
+ lyt->add_listener_create_layer(&shell->layer_created);
+ lyt->add_listener_remove_layer(&shell->layer_removed);
+
+ shell->surface_created.notify = surface_event_create;
+ shell->surface_removed.notify = surface_event_remove;
+ shell->surface_configured.notify = surface_event_configure;
+
+ lyt->add_listener_create_surface(&shell->surface_created);
+ lyt->add_listener_remove_surface(&shell->surface_removed);
+ lyt->add_listener_configure_surface(&shell->surface_configured);
+}
+
+int
+setup_ivi_controller_server(struct weston_compositor *compositor,
+ struct ivishell *shell)
+{
+ if (wl_global_create(compositor->wl_display, &ivi_controller_interface, 1,
+ shell, bind_ivi_controller) == NULL) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+load_input_module(struct weston_compositor *ec,
+ const struct ivi_layout_interface *interface,
+ size_t interface_version)
+{
+ struct weston_config *config = ec->config;
+ struct weston_config_section *section;
+ char *input_module = NULL;
+
+ int (*input_module_init)(struct weston_compositor *ec,
+ const struct ivi_layout_interface *interface,
+ size_t interface_version);
+
+ section = weston_config_get_section(config, "ivi-shell", NULL, NULL);
+
+ if (weston_config_section_get_string(section, "ivi-input-module",
+ &input_module, NULL) < 0) {
+ /* input events are handled by weston's default grabs */
+ weston_log("ivi-controller: No ivi-input-module set\n");
+ return 0;
+ }
+
+ input_module_init = weston_load_module(input_module, "input_controller_module_init");
+ if (!input_module_init)
+ return -1;
+
+ if (input_module_init(ec, interface,
+ sizeof(struct ivi_layout_interface)) != 0) {
+ weston_log("ivi-controller: Initialization of input module failes");
+ return -1;
+ }
+
+ free(input_module);
+
+ return 0;
+}
+
+WL_EXPORT int
+controller_module_init(struct weston_compositor *compositor,
+ int *argc, char *argv[],
+ const struct ivi_layout_interface *interface,
+ size_t interface_version)
+{
+ struct ivishell *shell;
+ (void)argc;
+ (void)argv;
+
+ shell = malloc(sizeof *shell);
+ if (shell == NULL)
+ return -1;
+
+ memset(shell, 0, sizeof *shell);
+
+ shell->interface = interface;
+
+ init_ivi_shell(compositor, shell);
+
+#ifdef IVI_SHARE_ENABLE
+ if (setup_buffer_sharing(compositor, interface) < 0) {
+ free(shell);
+ return -1;
+ }
+#endif
+
+ if (setup_ivi_controller_server(compositor, shell)) {
+ free(shell);
+ return -1;
+ }
+
+ if (load_input_module(compositor, interface, interface_version) < 0) {
+ free(shell);
+ return -1;
+ }
+
+ return 0;
+}