From 665b0e8b78878c237ed31c94607d82f203984cfa Mon Sep 17 00:00:00 2001 From: Emre Ucan Date: Mon, 27 Jun 2016 11:43:56 +0200 Subject: ivi-controller: rename ivi-controller-impl.c as ivi-controller.c Signed-off-by: Emre Ucan --- weston-ivi-shell/CMakeLists.txt | 2 +- weston-ivi-shell/src/ivi-controller-impl.c | 1556 ---------------------------- weston-ivi-shell/src/ivi-controller.c | 1556 ++++++++++++++++++++++++++++ 3 files changed, 1557 insertions(+), 1557 deletions(-) delete mode 100644 weston-ivi-shell/src/ivi-controller-impl.c create mode 100644 weston-ivi-shell/src/ivi-controller.c diff --git a/weston-ivi-shell/CMakeLists.txt b/weston-ivi-shell/CMakeLists.txt index 05910ed..2b22383 100644 --- a/weston-ivi-shell/CMakeLists.txt +++ b/weston-ivi-shell/CMakeLists.txt @@ -55,7 +55,7 @@ link_directories( add_library(${PROJECT_NAME} MODULE - src/ivi-controller-impl.c + src/ivi-controller.c src/bitmap.c ${BUFFER_SHARING_SRC_FILES} ) diff --git a/weston-ivi-shell/src/ivi-controller-impl.c b/weston-ivi-shell/src/ivi-controller-impl.c deleted file mode 100644 index 871fc05..0000000 --- a/weston-ivi-shell/src/ivi-controller-impl.c +++ /dev/null @@ -1,1556 +0,0 @@ -/* - * 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 -#include - -#include -#include -#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; -} 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 +#include + +#include +#include +#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; +} -- cgit v1.2.1