diff options
Diffstat (limited to 'meta-ivi/recipes-graphics/wayland')
67 files changed, 24529 insertions, 14206 deletions
diff --git a/meta-ivi/recipes-graphics/wayland/wayland-ivi-extension/apply_weston-1.6.x.patch b/meta-ivi/recipes-graphics/wayland/wayland-ivi-extension/apply_weston-1.6.x.patch new file mode 100644 index 0000000..7f8ef4e --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/wayland-ivi-extension/apply_weston-1.6.x.patch @@ -0,0 +1,2135 @@ +diff --git a/weston-ivi-shell/src/ivi-controller.c b/weston-ivi-shell/src/ivi-controller.c +index f341454..049859e 100755 +--- a/weston-ivi-shell/src/ivi-controller.c ++++ b/weston-ivi-shell/src/ivi-controller.c +@@ -202,7 +202,7 @@ destroy_ivicontroller_layer(struct wl_resource *resource) + struct ivicontroller_layer *next = NULL; + uint32_t id_layer = 0; + +- id_layer = ivi_layout_getIdOfLayer(ivilayer->layout_layer); ++ id_layer = ivi_layout_get_id_of_layer(ivilayer->layout_layer); + + wl_list_for_each_safe(ctrllayer, next, + &shell->list_controller_layer, link) { +@@ -222,7 +222,7 @@ destroy_ivicontroller_layer(struct wl_resource *resource) + if ((ivilayer->layout_layer != NULL) && + (ivilayer->controller_layer_count == 0) && + (ivilayer->layer_canbe_removed == 1)) { +- ivi_layout_layerRemove(ivilayer->layout_layer); ++ ivi_layout_layer_remove(ivilayer->layout_layer); + } + } + +@@ -271,7 +271,7 @@ get_surface(struct wl_list *list_surf, uint32_t id_surface) + uint32_t ivisurf_id = 0; + + wl_list_for_each(ivisurf, list_surf, link) { +- ivisurf_id = ivi_layout_getIdOfSurface(ivisurf->layout_surface); ++ ivisurf_id = ivi_layout_get_id_of_surface(ivisurf->layout_surface); + if (ivisurf_id == id_surface) { + return ivisurf; + } +@@ -287,7 +287,7 @@ get_layer(struct wl_list *list_layer, uint32_t id_layer) + uint32_t ivilayer_id = 0; + + wl_list_for_each(ivilayer, list_layer, link) { +- ivilayer_id = ivi_layout_getIdOfLayer(ivilayer->layout_layer); ++ ivilayer_id = ivi_layout_get_id_of_layer(ivilayer->layout_layer); + if (ivilayer_id == id_layer) { + return ivilayer; + } +@@ -361,7 +361,7 @@ send_surface_add_event(struct ivisurface *ivisurf, + struct wl_client *surface_client = wl_resource_get_client(resource); + int found = 0; + +- ans = ivi_layout_getLayersUnderSurface(ivisurf->layout_surface, ++ ans = ivi_layout_get_layers_under_surface(ivisurf->layout_surface, + &length, &pArray); + if (0 != ans) { + weston_log("failed to get layers at send_surface_add_event\n"); +@@ -389,7 +389,7 @@ send_surface_add_event(struct ivisurface *ivisurf, + } + + id_layout_layer = +- ivi_layout_getIdOfLayer(ivilayer->layout_layer); ++ ivi_layout_get_id_of_layer(ivilayer->layout_layer); + wl_list_for_each(ctrllayer, &shell->list_controller_layer, link) { + if (id_layout_layer != ctrllayer->id_layer) { + continue; +@@ -412,7 +412,7 @@ send_surface_add_event(struct ivisurface *ivisurf, + static void + send_surface_event(struct wl_resource *resource, + struct ivisurface *ivisurf, +- struct ivi_layout_SurfaceProperties *prop, ++ struct ivi_layout_surface_properties *prop, + uint32_t mask) + { + if (mask & IVI_NOTIFICATION_OPACITY) { +@@ -421,13 +421,13 @@ send_surface_event(struct wl_resource *resource, + } + if (mask & IVI_NOTIFICATION_SOURCE_RECT) { + ivi_controller_surface_send_source_rectangle(resource, +- prop->sourceX, prop->sourceY, +- prop->sourceWidth, prop->sourceHeight); ++ 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->destX, prop->destY, +- prop->destWidth, prop->destHeight); ++ prop->dest_x, prop->dest_y, ++ prop->dest_width, prop->dest_height); + } + if (mask & IVI_NOTIFICATION_ORIENTATION) { + ivi_controller_surface_send_orientation(resource, +@@ -437,15 +437,6 @@ send_surface_event(struct wl_resource *resource, + ivi_controller_surface_send_visibility(resource, + prop->visibility); + } +- if (mask & IVI_NOTIFICATION_PIXELFORMAT) { +- ivi_controller_surface_send_pixelformat(resource, +- prop->pixelformat); +- } +- if (mask & IVI_NOTIFICATION_KEYBOARD_FOCUS) { +- ivi_controller_surface_send_input_focus(resource, +- IVI_CONTROLLER_SURFACE_INPUT_DEVICE_KEYBOARD, +- prop->hasKeyboardFocus); +- } + if (mask & IVI_NOTIFICATION_REMOVE) { + send_surface_add_event(ivisurf, resource, IVI_NOTIFICATION_REMOVE); + } +@@ -464,7 +455,7 @@ update_surface_prop(struct ivisurface *ivisurf, + int i = 0; + struct ivishell *shell = ivisurf->shell; + +- ans = ivi_layout_getLayersUnderSurface(ivisurf->layout_surface, ++ ans = ivi_layout_get_layers_under_surface(ivisurf->layout_surface, + &length, &pArray); + if (0 != ans) { + weston_log("failed to get layers at send_surface_add_event\n"); +@@ -511,7 +502,7 @@ update_surface_prop(struct ivisurface *ivisurf, + + static void + send_surface_prop(struct ivi_layout_surface *layout_surface, +- struct ivi_layout_SurfaceProperties *prop, ++ struct ivi_layout_surface_properties *prop, + enum ivi_layout_notification_mask mask, + void *userdata) + { +@@ -520,7 +511,7 @@ send_surface_prop(struct ivi_layout_surface *layout_surface, + struct ivicontroller_surface *ctrlsurf = NULL; + uint32_t id_surface = 0; + +- id_surface = ivi_layout_getIdOfSurface(layout_surface); ++ id_surface = ivi_layout_get_id_of_surface(layout_surface); + + wl_list_for_each(ctrlsurf, &shell->list_controller_surface, link) { + if (id_surface != ctrlsurf->id_surface) { +@@ -548,7 +539,7 @@ send_layer_add_event(struct ivilayer *ivilayer, + struct wl_client *client = wl_resource_get_client(resource); + struct wl_resource *resource_output = NULL; + +- ans = ivi_layout_getScreensUnderLayer(ivilayer->layout_layer, ++ ans = ivi_layout_get_screens_under_layer(ivilayer->layout_layer, + &length, &pArray); + if (0 != ans) { + weston_log("failed to get screens at send_layer_add_event\n"); +@@ -591,7 +582,7 @@ send_layer_add_event(struct ivilayer *ivilayer, + static void + send_layer_event(struct wl_resource *resource, + struct ivilayer *ivilayer, +- struct ivi_layout_LayerProperties *prop, ++ struct ivi_layout_layer_properties *prop, + uint32_t mask) + { + if (mask & IVI_NOTIFICATION_OPACITY) { +@@ -600,17 +591,17 @@ send_layer_event(struct wl_resource *resource, + } + if (mask & IVI_NOTIFICATION_SOURCE_RECT) { + ivi_controller_layer_send_source_rectangle(resource, +- prop->sourceX, +- prop->sourceY, +- prop->sourceWidth, +- prop->sourceHeight); ++ 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->destX, +- prop->destY, +- prop->destWidth, +- prop->destHeight); ++ prop->dest_x, ++ prop->dest_y, ++ prop->dest_width, ++ prop->dest_height); + } + if (mask & IVI_NOTIFICATION_ORIENTATION) { + ivi_controller_layer_send_orientation(resource, +@@ -638,7 +629,7 @@ update_layer_prop(struct ivilayer *ivilayer, + struct link_screen *link_scrn = NULL; + struct link_screen *next = NULL; + +- ans = ivi_layout_getScreensUnderLayer(ivilayer->layout_layer, ++ ans = ivi_layout_get_screens_under_layer(ivilayer->layout_layer, + &length, &pArray); + if (0 != ans) { + weston_log("failed to get screens at send_layer_add_event\n"); +@@ -687,7 +678,7 @@ update_layer_prop(struct ivilayer *ivilayer, + + static void + send_layer_prop(struct ivi_layout_layer *layer, +- struct ivi_layout_LayerProperties *prop, ++ struct ivi_layout_layer_properties *prop, + enum ivi_layout_notification_mask mask, + void *userdata) + { +@@ -696,7 +687,7 @@ send_layer_prop(struct ivi_layout_layer *layer, + struct ivishell *shell = ivilayer->shell; + uint32_t id_layout_layer = 0; + +- id_layout_layer = ivi_layout_getIdOfLayer(layer); ++ id_layout_layer = ivi_layout_get_id_of_layer(layer); + wl_list_for_each(ctrllayer, &shell->list_controller_layer, link) { + if (id_layout_layer != ctrllayer->id_layer) { + continue; +@@ -714,7 +705,7 @@ controller_surface_set_opacity(struct wl_client *client, + { + struct ivisurface *ivisurf = wl_resource_get_user_data(resource); + (void)client; +- ivi_layout_surfaceSetOpacity(ivisurf->layout_surface, (float)opacity); ++ ivi_layout_surface_set_opacity(ivisurf->layout_surface, (float)opacity); + } + + static void +@@ -727,7 +718,7 @@ controller_surface_set_source_rectangle(struct wl_client *client, + { + struct ivisurface *ivisurf = wl_resource_get_user_data(resource); + (void)client; +- ivi_layout_surfaceSetSourceRectangle(ivisurf->layout_surface, ++ ivi_layout_surface_set_source_rectangle(ivisurf->layout_surface, + (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height); + } + +@@ -743,11 +734,11 @@ controller_surface_set_destination_rectangle(struct wl_client *client, + (void)client; + + // TODO: create set transition type protocol +- ivi_layout_surfaceSetTransition( ivisurf->layout_surface, ++ ivi_layout_surface_set_transition(ivisurf->layout_surface, + IVI_LAYOUT_TRANSITION_NONE, + 300); // ms + +- ivi_layout_surfaceSetDestinationRectangle(ivisurf->layout_surface, ++ ivi_layout_surface_set_destination_rectangle(ivisurf->layout_surface, + (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height); + } + +@@ -758,7 +749,7 @@ controller_surface_set_visibility(struct wl_client *client, + { + struct ivisurface *ivisurf = wl_resource_get_user_data(resource); + (void)client; +- ivi_layout_surfaceSetVisibility(ivisurf->layout_surface, visibility); ++ ivi_layout_surface_set_visibility(ivisurf->layout_surface, visibility); + } + + static void +@@ -780,7 +771,7 @@ controller_surface_set_orientation(struct wl_client *client, + { + struct ivisurface *ivisurf = wl_resource_get_user_data(resource); + (void)client; +- ivi_layout_surfaceSetOrientation(ivisurf->layout_surface, (uint32_t)orientation); ++ ivi_layout_surface_set_orientation(ivisurf->layout_surface, (uint32_t)orientation); + } + + static int +@@ -941,7 +932,7 @@ clear_viewlist_but_specified_surface(struct weston_compositor *compositor, + } + + static void +-get_gl_surface_rectangle(struct ivi_layout_SurfaceProperties *prop, ++get_gl_surface_rectangle(struct ivi_layout_surface_properties *prop, + int32_t *x, + int32_t *y, + int32_t *width, +@@ -951,10 +942,10 @@ get_gl_surface_rectangle(struct ivi_layout_SurfaceProperties *prop, + return; + } + +- *x = prop->sourceX; +- *y = prop->sourceY; +- *width = prop->sourceWidth; +- *height = prop->sourceHeight; ++ *x = prop->source_x; ++ *y = prop->source_y; ++ *width = prop->source_width; ++ *height = prop->source_height; + } + + static int +@@ -967,7 +958,7 @@ gl_surface_screenshot(struct ivisurface *ivisurf, + struct weston_view *view = NULL; + struct weston_output *output = NULL; + struct iviscreen *link_scrn = NULL; +- struct ivi_layout_SurfaceProperties prop = {}; ++ struct ivi_layout_surface_properties *prop; + int32_t x = 0; + int32_t y = 0; + int32_t width = 0; +@@ -984,7 +975,9 @@ gl_surface_screenshot(struct ivisurface *ivisurf, + return -1; + } + +- if (ivi_layout_getPropertiesOfSurface(ivisurf->layout_surface, &prop) != 0) { ++ prop = (struct ivi_layout_surface_properties *) ++ ivi_layout_get_properties_of_surface(ivisurf->layout_surface); ++ if (prop == NULL) { + fprintf(stderr, "Failed to get surface properties."); + return -1; + } +@@ -997,7 +990,7 @@ gl_surface_screenshot(struct ivisurface *ivisurf, + view->plane = &compositor->primary_plane; + } + +- get_gl_surface_rectangle(&prop, &x, &y, &width, &height); ++ get_gl_surface_rectangle(prop, &x, &y, &width, &height); + dump_surface(link_scrn->output, + compositor, + filename, +@@ -1026,13 +1019,13 @@ controller_surface_screenshot(struct wl_client *client, + int32_t height = 0; + int32_t stride = 0; + +- weston_surface = ivi_layout_surfaceGetWestonSurface(ivisurf->layout_surface); ++ weston_surface = ivi_layout_surface_get_weston_surface(ivisurf->layout_surface); + if (weston_surface == NULL) { + fprintf(stderr, "Failed to get weston surface.\n"); + return; + } + +- if (ivi_layout_surfaceGetSize(ivisurf->layout_surface, &width, &height, &stride) != 0) { ++ if (ivi_layout_surface_get_size(ivisurf->layout_surface, &width, &height, &stride) != 0) { + fprintf(stderr, "Failed to get surface size.\n"); + return; + } +@@ -1069,43 +1062,24 @@ controller_surface_destroy(struct wl_client *client, + wl_resource_destroy(resource); + } + +-static void send_all_keyboard_focus(struct ivishell *shell) +-{ +- struct ivi_layout_SurfaceProperties props; +- struct ivicontroller_surface *ctrlsurf; +- struct ivisurface *current_surf; +- uint32_t id_surface; +- +- wl_list_for_each(current_surf, &shell->list_surface, link) { +- ivi_layout_getPropertiesOfSurface(current_surf->layout_surface, +- &props); +- id_surface = ivi_layout_getIdOfSurface(current_surf->layout_surface); +- wl_list_for_each(ctrlsurf, &shell->list_controller_surface, link) { +- if (id_surface != ctrlsurf->id_surface) { +- continue; +- } +- ivi_controller_surface_send_input_focus(ctrlsurf->resource, +- IVI_CONTROLLER_SURFACE_INPUT_DEVICE_KEYBOARD, +- props.hasKeyboardFocus); +- } +- } +-} +- + static void + controller_surface_set_input_focus(struct wl_client *client, + struct wl_resource *resource, + uint32_t device, + int32_t enabled) + { ++ weston_log("%s: %p, %p, %x, %d\n", __FUNCTION__, client, resource, device, enabled); ++#if 0 + (void)client; + struct ivisurface *ivisurf = wl_resource_get_user_data(resource); + + if (device & IVI_CONTROLLER_SURFACE_INPUT_DEVICE_KEYBOARD) { + if (enabled) { +- ivi_layout_SetKeyboardFocusOn(ivisurf->layout_surface); ++ ivi_layout_SetKeyboardFocusOn(ivisurf->layout_surface); // tolkien + send_all_keyboard_focus(ivisurf->shell); + } + } ++#endif + } + + static const +@@ -1132,7 +1106,7 @@ controller_layer_set_source_rectangle(struct wl_client *client, + { + struct ivilayer *ivilayer = wl_resource_get_user_data(resource); + (void)client; +- ivi_layout_layerSetSourceRectangle(ivilayer->layout_layer, ++ ivi_layout_layer_set_source_rectangle(ivilayer->layout_layer, + (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height); + } + +@@ -1146,7 +1120,7 @@ controller_layer_set_destination_rectangle(struct wl_client *client, + { + struct ivilayer *ivilayer = wl_resource_get_user_data(resource); + (void)client; +- ivi_layout_layerSetDestinationRectangle(ivilayer->layout_layer, ++ ivi_layout_layer_set_destination_rectangle(ivilayer->layout_layer, + (uint32_t)x, (uint32_t)y, (uint32_t)width, (uint32_t)height); + } + +@@ -1157,7 +1131,7 @@ controller_layer_set_visibility(struct wl_client *client, + { + struct ivilayer *ivilayer = wl_resource_get_user_data(resource); + (void)client; +- ivi_layout_layerSetVisibility(ivilayer->layout_layer, visibility); ++ ivi_layout_layer_set_visibility(ivilayer->layout_layer, visibility); + } + + static void +@@ -1167,7 +1141,7 @@ controller_layer_set_opacity(struct wl_client *client, + { + struct ivilayer *ivilayer = wl_resource_get_user_data(resource); + (void)client; +- ivi_layout_layerSetOpacity(ivilayer->layout_layer, (float)opacity); ++ ivi_layout_layer_set_opacity(ivilayer->layout_layer, (float)opacity); + } + + static void +@@ -1190,7 +1164,7 @@ controller_layer_set_orientation(struct wl_client *client, + { + struct ivilayer *ivilayer = wl_resource_get_user_data(resource); + (void)client; +- ivi_layout_layerSetOrientation(ivilayer->layout_layer, (uint32_t)orientation); ++ ivi_layout_layer_set_orientation(ivilayer->layout_layer, (uint32_t)orientation); + } + + static void +@@ -1199,7 +1173,7 @@ controller_layer_clear_surfaces(struct wl_client *client, + { + struct ivilayer *ivilayer = wl_resource_get_user_data(resource); + (void)client; +- ivi_layout_layerSetRenderOrder(ivilayer->layout_layer, NULL, 0); ++ ivi_layout_layer_set_render_order(ivilayer->layout_layer, NULL, 0); + } + + static void +@@ -1210,7 +1184,7 @@ controller_layer_add_surface(struct wl_client *client, + struct ivilayer *ivilayer = wl_resource_get_user_data(resource); + struct ivisurface *ivisurf = wl_resource_get_user_data(surface); + (void)client; +- ivi_layout_layerAddSurface(ivilayer->layout_layer, ivisurf->layout_surface); ++ ivi_layout_layer_add_surface(ivilayer->layout_layer, ivisurf->layout_surface); + } + + static void +@@ -1221,7 +1195,7 @@ controller_layer_remove_surface(struct wl_client *client, + struct ivilayer *ivilayer = wl_resource_get_user_data(resource); + struct ivisurface *ivisurf = wl_resource_get_user_data(surface); + (void)client; +- ivi_layout_layerRemoveSurface(ivilayer->layout_layer, ivisurf->layout_surface); ++ ivi_layout_layer_remove_surface(ivilayer->layout_layer, ivisurf->layout_surface); + } + + static void +@@ -1252,7 +1226,7 @@ controller_layer_set_render_order(struct wl_client *client, + + wl_array_for_each(id_surface, id_surfaces) { + wl_list_for_each(ivisurf, &ivilayer->shell->list_surface, link) { +- id_layout_surface = ivi_layout_getIdOfSurface(ivisurf->layout_surface); ++ id_layout_surface = ivi_layout_get_id_of_surface(ivisurf->layout_surface); + if (*id_surface == id_layout_surface) { + layoutsurf_array[i] = ivisurf->layout_surface; + i++; +@@ -1261,7 +1235,7 @@ controller_layer_set_render_order(struct wl_client *client, + } + } + +- ivi_layout_layerSetRenderOrder(ivilayer->layout_layer, ++ ivi_layout_layer_set_render_order(ivilayer->layout_layer, + layoutsurf_array, i); + free(layoutsurf_array); + } +@@ -1275,7 +1249,7 @@ controller_layer_destroy(struct wl_client *client, + struct ivishell *shell = ivilayer->shell; + struct ivicontroller_layer *ctrllayer = NULL; + struct ivicontroller_layer *next = NULL; +- uint32_t id_layer = ivi_layout_getIdOfLayer(ivilayer->layout_layer); ++ uint32_t id_layer = ivi_layout_get_id_of_layer(ivilayer->layout_layer); + (void)client; + (void)destroy_scene_object; + +@@ -1335,7 +1309,7 @@ controller_screen_clear(struct wl_client *client, + { + struct iviscreen *iviscrn = wl_resource_get_user_data(resource); + (void)client; +- ivi_layout_screenSetRenderOrder(iviscrn->layout_screen, NULL, 0); ++ ivi_layout_screen_set_render_order(iviscrn->layout_screen, NULL, 0); + } + + static void +@@ -1346,7 +1320,7 @@ controller_screen_add_layer(struct wl_client *client, + struct iviscreen *iviscrn = wl_resource_get_user_data(resource); + struct ivilayer *ivilayer = wl_resource_get_user_data(layer); + (void)client; +- ivi_layout_screenAddLayer(iviscrn->layout_screen, ivilayer->layout_layer); ++ ivi_layout_screen_add_layer(iviscrn->layout_screen, ivilayer->layout_layer); + } + + static void +@@ -1365,7 +1339,7 @@ controller_screen_screenshot(struct wl_client *client, + int32_t stride = 0; + uint8_t *readpixs = NULL; + +- output = ivi_layout_screenGetOutput(iviscrn->layout_screen); ++ output = ivi_layout_screen_get_output(iviscrn->layout_screen); + --output->disable_planes; + + width = output->current_mode->width; +@@ -1409,7 +1383,7 @@ controller_screen_set_render_order(struct wl_client *client, + + wl_array_for_each(id_layer, id_layers) { + wl_list_for_each(ivilayer, &iviscrn->shell->list_layer, link) { +- id_layout_layer = ivi_layout_getIdOfLayer(ivilayer->layout_layer); ++ id_layout_layer = ivi_layout_get_id_of_layer(ivilayer->layout_layer); + if (*id_layer == id_layout_layer) { + layoutlayer_array[i] = ivilayer->layout_layer; + i++; +@@ -1418,7 +1392,7 @@ controller_screen_set_render_order(struct wl_client *client, + } + } + +- ivi_layout_screenSetRenderOrder(iviscrn->layout_screen, ++ ivi_layout_screen_set_render_order(iviscrn->layout_screen, + layoutlayer_array, i); + free(layoutlayer_array); + } +@@ -1440,7 +1414,7 @@ controller_commit_changes(struct wl_client *client, + (void)client; + (void)resource; + +- ans = ivi_layout_commitChanges(); ++ ans = ivi_layout_commit_changes(); + if (ans < 0) { + weston_log("Failed to commit changes at controller_commit_changes\n"); + } +@@ -1459,11 +1433,11 @@ controller_layer_create(struct wl_client *client, + struct ivi_layout_layer *layout_layer = NULL; + struct ivicontroller_layer *ctrllayer = NULL; + struct ivilayer *ivilayer = NULL; +- struct ivi_layout_LayerProperties prop; ++ struct ivi_layout_layer_properties *prop = NULL; + + ivilayer = get_layer(&shell->list_layer, id_layer); + if (ivilayer == NULL) { +- layout_layer = ivi_layout_layerCreateWithDimension(id_layer, ++ layout_layer = ivi_layout_layer_create_with_dimension(id_layer, + (uint32_t)width, (uint32_t)height); + if (layout_layer == NULL) { + weston_log("id_layer is already created\n"); +@@ -1505,11 +1479,9 @@ controller_layer_create(struct wl_client *client, + &controller_layer_implementation, + ivilayer, destroy_ivicontroller_layer); + +- memset(&prop, 0, sizeof prop); +- +- ivi_layout_getPropertiesOfLayer(ivilayer->layout_layer, &prop); ++ prop = ivi_layout_get_properties_of_surface(ivilayer->layout_layer); + send_layer_event(ctrllayer->resource, ivilayer, +- &prop, IVI_NOTIFICATION_ALL); ++ prop, IVI_NOTIFICATION_ALL); + } + + static void +@@ -1533,7 +1505,7 @@ controller_surface_create(struct wl_client *client, + struct ivicontroller *ctrl = wl_resource_get_user_data(resource); + struct ivishell *shell = ctrl->shell; + struct ivicontroller_surface *ctrlsurf = NULL; +- struct ivi_layout_SurfaceProperties prop; ++ struct ivi_layout_surface_properties *prop = NULL; + struct ivisurface *ivisurf = NULL; + struct ivicontroller_surface *ctrl_link = NULL; + +@@ -1583,13 +1555,11 @@ controller_surface_create(struct wl_client *client, + + ctrlsurf->implementation_set = 1; + +- memset(&prop, 0, sizeof prop); +- +- ivi_layout_getPropertiesOfSurface(ivisurf->layout_surface, &prop); +- ivi_layout_surfaceSetContentObserver(ivisurf->layout_surface, surface_event_content, shell); ++ prop = ivi_layout_get_properties_of_surface(ivisurf->layout_surface); ++ ivi_layout_surface_set_content_observer(ivisurf->layout_surface, surface_event_content, shell); + + send_surface_event(ctrlsurf->resource, ivisurf, +- &prop, IVI_NOTIFICATION_ALL); ++ prop, IVI_NOTIFICATION_ALL); + } + + static const struct ivi_controller_interface controller_implementation = { +@@ -1629,14 +1599,14 @@ add_client_to_resources(struct ivishell *shell, + } + wl_list_for_each_reverse(ivilayer, &shell->list_layer, link) { + id_layout_layer = +- ivi_layout_getIdOfLayer(ivilayer->layout_layer); ++ ivi_layout_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 = +- ivi_layout_getIdOfSurface(ivisurf->layout_surface); ++ ivi_layout_get_id_of_surface(ivisurf->layout_surface); + + ivi_controller_send_surface(controller->resource, + id_layout_surface); +@@ -1687,7 +1657,7 @@ create_screen(struct ivishell *shell, struct weston_output *output) + iviscrn->output = output; + + // TODO : Only Single display +- iviscrn->layout_screen = ivi_layout_getScreenFromId(0); ++ iviscrn->layout_screen = ivi_layout_get_screen_from_id(0); + + wl_list_init(&iviscrn->link); + +@@ -1720,7 +1690,7 @@ create_layer(struct ivishell *shell, + wl_list_insert(&shell->list_layer, &ivilayer->link); + ivilayer->layout_layer = layout_layer; + +- ivi_layout_layerAddNotification(layout_layer, send_layer_prop, ivilayer); ++ ivi_layout_layer_add_notification(layout_layer, send_layer_prop, ivilayer); + + wl_list_for_each(controller, &shell->list_controller, link) { + ivi_controller_send_layer(controller->resource, id_layer); +@@ -1760,7 +1730,7 @@ create_surface(struct ivishell *shell, + id_surface); + } + +- ivi_layout_surfaceAddNotification(layout_surface, ++ ivi_layout_layer_add_notification(layout_surface, + send_surface_prop, ivisurf); + + return ivisurf; +@@ -1774,7 +1744,7 @@ layer_event_create(struct ivi_layout_layer *layout_layer, + struct ivilayer *ivilayer = NULL; + uint32_t id_layer = 0; + +- id_layer = ivi_layout_getIdOfLayer(layout_layer); ++ id_layer = ivi_layout_get_id_of_layer(layout_layer); + + ivilayer = create_layer(shell, layout_layer, id_layer); + if (ivilayer == NULL) { +@@ -1808,7 +1778,7 @@ layer_event_remove(struct ivi_layout_layer *layout_layer, + } + + if (is_removed) { +- id_layer = ivi_layout_getIdOfLayer(layout_layer); ++ id_layer = ivi_layout_get_id_of_layer(layout_layer); + + wl_list_for_each(ctrllayer, &shell->list_controller_layer, link) { + if (id_layer != ctrllayer->id_layer) { +@@ -1829,7 +1799,7 @@ surface_event_create(struct ivi_layout_surface *layout_surface, + uint32_t id_surface = 0; + struct ivicontroller_surface *ctrlsurf = NULL; + +- id_surface = ivi_layout_getIdOfSurface(layout_surface); ++ id_surface = ivi_layout_get_id_of_surface(layout_surface); + + ivisurf = create_surface(shell, layout_surface, id_surface); + if (ivisurf == NULL) { +@@ -1875,7 +1845,7 @@ surface_event_remove(struct ivi_layout_surface *layout_surface, + } + + if (is_removed) { +- id_surface = ivi_layout_getIdOfSurface(layout_surface); ++ id_surface = ivi_layout_get_id_of_surface(layout_surface); + + wl_list_for_each(ctrlsurf, &shell->list_controller_surface, link) { + if (id_surface != ctrlsurf->id_surface) { +@@ -1894,10 +1864,10 @@ surface_event_configure(struct ivi_layout_surface *layout_surface, + struct ivishell *shell = userdata; + struct ivisurface *ivisurf = NULL; + struct ivicontroller_surface *ctrlsurf = NULL; +- struct ivi_layout_SurfaceProperties prop; ++ struct ivi_layout_surface_properties *prop = NULL; + uint32_t id_surface = 0; + +- id_surface = ivi_layout_getIdOfSurface(layout_surface); ++ id_surface = ivi_layout_get_id_of_surface(layout_surface); + + ivisurf = get_surface(&shell->list_surface, id_surface); + if (ivisurf == NULL) { +@@ -1905,8 +1875,7 @@ surface_event_configure(struct ivi_layout_surface *layout_surface, + return; + } + +- memset(&prop, 0, sizeof prop); +- ivi_layout_getPropertiesOfSurface(layout_surface, &prop); ++ prop = ivi_layout_get_properties_of_surface(layout_surface); + + wl_list_for_each(ctrlsurf, &shell->list_controller_surface, link) { + if (id_surface != ctrlsurf->id_surface) { +@@ -1927,7 +1896,7 @@ check_layout_layers(struct ivishell *shell) + uint32_t i = 0; + int32_t ret = 0; + +- ret = ivi_layout_getLayers(&length, &pArray); ++ ret = ivi_layout_get_layers(&length, &pArray); + if(ret != 0) { + weston_log("failed to get layers at check_layout_layers\n"); + return -1; +@@ -1939,7 +1908,7 @@ check_layout_layers(struct ivishell *shell) + } + + for (i = 0; i < length; i++) { +- id_layer = ivi_layout_getIdOfLayer(pArray[i]); ++ id_layer = ivi_layout_get_id_of_layer(pArray[i]); + ivilayer = create_layer(shell, pArray[i], id_layer); + if (ivilayer == NULL) { + weston_log("failed to create layer"); +@@ -1962,7 +1931,7 @@ check_layout_surfaces(struct ivishell *shell) + uint32_t i = 0; + int32_t ret = 0; + +- ret = ivi_layout_getSurfaces(&length, &pArray); ++ ret = ivi_layout_get_surfaces(&length, &pArray); + if(ret != 0) { + weston_log("failed to get surfaces at check_layout_surfaces\n"); + return -1; +@@ -1974,7 +1943,7 @@ check_layout_surfaces(struct ivishell *shell) + } + + for (i = 0; i < length; i++) { +- id_surface = ivi_layout_getIdOfSurface(pArray[i]); ++ id_surface = ivi_layout_get_id_of_surface(pArray[i]); + ivisurf = create_surface(shell, pArray[i], id_surface); + if (ivisurf == NULL) { + weston_log("failed to create surface"); +@@ -2023,12 +1992,12 @@ init_ivi_shell(struct weston_compositor *ec, struct ivishell *shell) + weston_log("failed to check_layout_surfaces"); + } + +- ivi_layout_addNotificationCreateLayer(layer_event_create, shell); +- ivi_layout_addNotificationRemoveLayer(layer_event_remove, shell); ++ ivi_layout_add_notification_create_layer(layer_event_create, shell); ++ ivi_layout_add_notification_remove_layer(layer_event_remove, shell); + +- ivi_layout_addNotificationCreateSurface(surface_event_create, shell); +- ivi_layout_addNotificationRemoveSurface(surface_event_remove, shell); +- ivi_layout_addNotificationConfigureSurface(surface_event_configure, shell); ++ ivi_layout_add_notification_create_surface(surface_event_create, shell); ++ ivi_layout_add_notification_remove_surface(surface_event_remove, shell); ++ ivi_layout_add_notification_configure_surface(surface_event_configure, shell); + } + + WL_EXPORT int +diff --git a/weston-ivi-shell/src/ivi-layout-export.h b/weston-ivi-shell/src/ivi-layout-export.h +index 3d1afc9..eb3752c 100644 +--- a/weston-ivi-shell/src/ivi-layout-export.h ++++ b/weston-ivi-shell/src/ivi-layout-export.h +@@ -36,10 +36,13 @@ + * - commit to apply property changes. + * - notifications of property change. + * +- * Management of surfaces and layers grouping these surfaces are common way in +- * In-Vehicle Infotainment system, which integrate several domains in one system. +- * A layer is allocated to a domain in order to control application surfaces +- * grouped to the layer all together. ++ * Management of surfaces and layers grouping these surfaces are common ++ * way in In-Vehicle Infotainment system, which integrate several domains ++ * in one system. A layer is allocated to a domain in order to control ++ * application surfaces grouped to the layer all together. ++ * ++ * This API and ABI follow following specifications. ++ * http://projects.genivi.org/wayland-ivi-extension/layer-manager-apis + */ + + #ifndef _IVI_LAYOUT_EXPORT_H_ +@@ -49,181 +52,205 @@ + extern "C" { + #endif /* __cplusplus */ + +-#include "compositor.h" +-#include "ivi-layout.h" ++#include "stdbool.h" ++#include <weston/compositor.h> ++ ++#define IVI_SUCCEEDED (0) ++#define IVI_FAILED (-1) + + struct ivi_layout_layer; + struct ivi_layout_screen; ++struct ivi_layout_surface; ++ ++struct ivi_layout_surface_properties ++{ ++ wl_fixed_t opacity; ++ int32_t source_x; ++ int32_t source_y; ++ int32_t source_width; ++ int32_t source_height; ++ int32_t start_x; ++ int32_t start_y; ++ int32_t start_width; ++ int32_t start_height; ++ int32_t dest_x; ++ int32_t dest_y; ++ int32_t dest_width; ++ int32_t dest_height; ++ enum wl_output_transform orientation; ++ bool visibility; ++ int32_t transition_type; ++ uint32_t transition_duration; ++}; ++ ++struct ivi_layout_layer_properties ++{ ++ wl_fixed_t opacity; ++ int32_t source_x; ++ int32_t source_y; ++ int32_t source_width; ++ int32_t source_height; ++ int32_t dest_x; ++ int32_t dest_y; ++ int32_t dest_width; ++ int32_t dest_height; ++ enum wl_output_transform orientation; ++ uint32_t visibility; ++ int32_t transition_type; ++ uint32_t transition_duration; ++ double start_alpha; ++ double end_alpha; ++ uint32_t is_fade_in; ++}; + + enum ivi_layout_notification_mask { +- IVI_NOTIFICATION_NONE = 0, +- IVI_NOTIFICATION_OPACITY = (1 << 1), +- IVI_NOTIFICATION_SOURCE_RECT = (1 << 2), +- IVI_NOTIFICATION_DEST_RECT = (1 << 3), +- IVI_NOTIFICATION_DIMENSION = (1 << 4), +- IVI_NOTIFICATION_POSITION = (1 << 5), +- IVI_NOTIFICATION_ORIENTATION = (1 << 6), +- IVI_NOTIFICATION_VISIBILITY = (1 << 7), +- IVI_NOTIFICATION_PIXELFORMAT = (1 << 8), +- IVI_NOTIFICATION_ADD = (1 << 9), +- IVI_NOTIFICATION_REMOVE = (1 << 10), +- IVI_NOTIFICATION_CONFIGURE = (1 << 11), +- IVI_NOTIFICATION_KEYBOARD_FOCUS = (1 << 12), +- IVI_NOTIFICATION_ALL = 0xFFFF ++ IVI_NOTIFICATION_NONE = 0, ++ IVI_NOTIFICATION_OPACITY = (1 << 1), ++ IVI_NOTIFICATION_SOURCE_RECT = (1 << 2), ++ IVI_NOTIFICATION_DEST_RECT = (1 << 3), ++ IVI_NOTIFICATION_DIMENSION = (1 << 4), ++ IVI_NOTIFICATION_POSITION = (1 << 5), ++ IVI_NOTIFICATION_ORIENTATION = (1 << 6), ++ IVI_NOTIFICATION_VISIBILITY = (1 << 7), ++ IVI_NOTIFICATION_PIXELFORMAT = (1 << 8), ++ IVI_NOTIFICATION_ADD = (1 << 9), ++ IVI_NOTIFICATION_REMOVE = (1 << 10), ++ IVI_NOTIFICATION_CONFIGURE = (1 << 11), ++ IVI_NOTIFICATION_ALL = 0xFFFF + }; + + enum ivi_layout_transition_type{ +- IVI_LAYOUT_TRANSITION_NONE, +- IVI_LAYOUT_TRANSITION_VIEW_DEFAULT, +- IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY, +- IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY, +- IVI_LAYOUT_TRANSITION_LAYER_FADE, +- IVI_LAYOUT_TRANSITION_LAYER_MOVE, +- IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER, +- IVI_LAYOUT_TRANSITION_MAX, ++ IVI_LAYOUT_TRANSITION_NONE, ++ IVI_LAYOUT_TRANSITION_VIEW_DEFAULT, ++ IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY, ++ IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY, ++ IVI_LAYOUT_TRANSITION_LAYER_FADE, ++ IVI_LAYOUT_TRANSITION_LAYER_MOVE, ++ IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER, ++ IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE, ++ IVI_LAYOUT_TRANSITION_VIEW_RESIZE, ++ IVI_LAYOUT_TRANSITION_VIEW_FADE, ++ IVI_LAYOUT_TRANSITION_MAX, + }; + +-typedef void(*shellWarningNotificationFunc)(uint32_t id_surface, +- enum ivi_layout_warning_flag warn, +- void *userdata); +- +-typedef void(*layerPropertyNotificationFunc)(struct ivi_layout_layer *ivilayer, +- struct ivi_layout_LayerProperties*, +- enum ivi_layout_notification_mask mask, +- void *userdata); +- +-typedef void(*surfacePropertyNotificationFunc)(struct ivi_layout_surface *ivisurf, +- struct ivi_layout_SurfaceProperties*, +- enum ivi_layout_notification_mask mask, +- void *userdata); ++typedef void (*layer_property_notification_func)( ++ struct ivi_layout_layer *ivilayer, ++ const struct ivi_layout_layer_properties *, ++ enum ivi_layout_notification_mask mask, ++ void *userdata); + +-typedef void(*layerCreateNotificationFunc)(struct ivi_layout_layer *ivilayer, +- void *userdata); ++typedef void (*surface_property_notification_func)( ++ struct ivi_layout_surface *ivisurf, ++ const struct ivi_layout_surface_properties *, ++ enum ivi_layout_notification_mask mask, ++ void *userdata); + +-typedef void(*layerRemoveNotificationFunc)(struct ivi_layout_layer *ivilayer, +- void *userdata); ++typedef void (*layer_create_notification_func)( ++ struct ivi_layout_layer *ivilayer, ++ void *userdata); + +-typedef void(*surfaceCreateNotificationFunc)(struct ivi_layout_surface *ivisurf, +- void *userdata); ++typedef void (*layer_remove_notification_func)( ++ struct ivi_layout_layer *ivilayer, ++ void *userdata); + +-typedef void(*surfaceRemoveNotificationFunc)(struct ivi_layout_surface *ivisurf, +- void *userdata); ++typedef void (*surface_create_notification_func)( ++ struct ivi_layout_surface *ivisurf, ++ void *userdata); + +-typedef void(*surfaceConfigureNotificationFunc)(struct ivi_layout_surface *ivisurf, +- void *userdata); ++typedef void (*surface_remove_notification_func)( ++ struct ivi_layout_surface *ivisurf, ++ void *userdata); + +-typedef void(*ivi_controller_surface_content_callback)(struct ivi_layout_surface *ivisurf, +- int32_t content, +- void *userdata); +- +-int32_t +-ivi_layout_addNotificationShellWarning(shellWarningNotificationFunc callback, +- void *userdata); +- +-void +-ivi_layout_removeNotificationShellWarning(shellWarningNotificationFunc callback, +- void *userdata); +- +-/** +- * \brief to be called by ivi-shell in order to set initail view of +- * weston_surface. +- */ +-/* +-struct weston_view * +-ivi_layout_get_weston_view(struct ivi_layout_surface *surface); +-*/ ++typedef void (*surface_configure_notification_func)( ++ struct ivi_layout_surface *ivisurf, ++ void *userdata); + +-/** +- * \brief initialize ivi-layout +- */ +-/* +-void +-ivi_layout_initWithCompositor(struct weston_compositor *ec); +-*/ ++typedef void (*ivi_controller_surface_content_callback)( ++ struct ivi_layout_surface *ivisurf, ++ int32_t content, ++ void *userdata); + + /** + * \brief register for notification when layer is created + */ + int32_t +-ivi_layout_addNotificationCreateLayer(layerCreateNotificationFunc callback, +- void *userdata); ++ivi_layout_add_notification_create_layer( ++ layer_create_notification_func callback, ++ void *userdata); + + void +-ivi_layout_removeNotificationCreateLayer(layerCreateNotificationFunc callback, +- void *userdata); ++ivi_layout_remove_notification_create_layer( ++ layer_create_notification_func callback, ++ void *userdata); + + /** + * \brief register for notification when layer is removed + */ + int32_t +-ivi_layout_addNotificationRemoveLayer(layerRemoveNotificationFunc callback, +- void *userdata); ++ivi_layout_add_notification_remove_layer( ++ layer_remove_notification_func callback, ++ void *userdata); + + void +-ivi_layout_removeNotificationRemoveLayer(layerRemoveNotificationFunc callback, +- void *userdata); ++ivi_layout_remove_notification_remove_layer( ++ layer_remove_notification_func callback, ++ void *userdata); + + /** + * \brief register for notification when surface is created + */ + int32_t +-ivi_layout_addNotificationCreateSurface(surfaceCreateNotificationFunc callback, +- void *userdata); ++ivi_layout_add_notification_create_surface( ++ surface_create_notification_func callback, ++ void *userdata); + + void +-ivi_layout_removeNotificationCreateSurface(surfaceCreateNotificationFunc callback, +- void *userdata); ++ivi_layout_remove_notification_create_surface( ++ surface_create_notification_func callback, ++ void *userdata); + + /** + * \brief register for notification when surface is removed + */ + int32_t +-ivi_layout_addNotificationRemoveSurface(surfaceRemoveNotificationFunc callback, +- void *userdata); ++ivi_layout_add_notification_remove_surface( ++ surface_remove_notification_func callback, ++ void *userdata); + + void +-ivi_layout_removeNotificationRemoveSurface(surfaceRemoveNotificationFunc callback, +- void *userdata); ++ivi_layout_remove_notification_remove_surface( ++ surface_remove_notification_func callback, ++ void *userdata); + + /** + * \brief register for notification when surface is configured + */ + int32_t +-ivi_layout_addNotificationConfigureSurface(surfaceConfigureNotificationFunc callback, +- void *userdata); ++ivi_layout_add_notification_configure_surface( ++ surface_configure_notification_func callback, ++ void *userdata); + + void +-ivi_layout_removeNotificationConfigureSurface(surfaceConfigureNotificationFunc callback, +- void *userdata); ++ivi_layout_remove_notification_configure_surface( ++ surface_configure_notification_func callback, ++ void *userdata); + + /** + * \brief get id of surface from ivi_layout_surface + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return id of surface + */ + uint32_t +-ivi_layout_getIdOfSurface(struct ivi_layout_surface *ivisurf); ++ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf); + + /** + * \brief get id of layer from ivi_layout_layer + * + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return id of layer + */ + uint32_t +-ivi_layout_getIdOfLayer(struct ivi_layout_layer *ivilayer); +- +-/** +- * \brief get ivi_layout_layer from id of layer +- * +- * \return (struct ivi_layout_layer *) +- * if the method call was successful +- * \return NULL if the method call was failed +- */ +-struct ivi_layout_layer * +-ivi_layout_getLayerFromId(uint32_t id_layer); ++ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer); + + /** + * \brief get ivi_layout_surface from id of surface +@@ -233,7 +260,7 @@ ivi_layout_getLayerFromId(uint32_t id_layer); + * \return NULL if the method call was failed + */ + struct ivi_layout_surface * +-ivi_layout_getSurfaceFromId(uint32_t id_surface); ++ivi_layout_get_surface_from_id(uint32_t id_surface); + + /** + * \brief get ivi_layout_screen from id of screen +@@ -243,708 +270,420 @@ ivi_layout_getSurfaceFromId(uint32_t id_surface); + * \return NULL if the method call was failed + */ + struct ivi_layout_screen * +-ivi_layout_getScreenFromId(uint32_t id_screen); ++ivi_layout_get_screen_from_id(uint32_t id_screen); + + /** + * \brief Get the screen resolution of a specific screen + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_getScreenResolution(struct ivi_layout_screen *iviscrn, +- int32_t *pWidth, +- int32_t *pHeight); +- +-/** +- * \brief register for notification on property changes of surface +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_surfaceAddNotification(struct ivi_layout_surface *ivisurf, +- surfacePropertyNotificationFunc callback, +- void *userdata); +- +-/** +- * \brief remove notification on property changes of surface +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_surfaceRemoveNotification(struct ivi_layout_surface *ivisurf); +- +-/** +- * \brief Create a surface +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-/* +-struct ivi_layout_surface * +-ivi_layout_surfaceCreate(struct weston_surface *wl_surface, +- uint32_t id_surface); +-*/ +- +-/** +- * \brief Set the native content of an application to be used as surface content. +- * If wl_surface is NULL, remove the native content of a surface +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-/* +-int32_t +-ivi_layout_surfaceSetNativeContent(struct weston_surface *wl_surface, +- uint32_t width, +- uint32_t height, +- uint32_t id_surface); +-*/ ++ivi_layout_get_screen_resolution(struct ivi_layout_screen *iviscrn, ++ int32_t *pWidth, ++ int32_t *pHeight); + + /** + * \brief Set an observer callback for surface content status change. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_surfaceSetContentObserver(struct ivi_layout_surface *ivisurf, +- ivi_controller_surface_content_callback callback, +- void* userdata); +- +-/** +- * \brief initialize ivi_layout_surface dest/source width and height +- */ +-/* +-void +-ivi_layout_surfaceConfigure(struct ivi_layout_surface *ivisurf, +- uint32_t width, uint32_t height); +-*/ +- +-/** +- * \brief Remove a surface +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_surfaceRemove(struct ivi_layout_surface *ivisurf); +- +-/** +- * \brief Set from which kind of devices the surface can accept input events. +- * By default, a surface accept input events from all kind of devices (keyboards, pointer, ...) +- * By calling this function, you can adjust surface preferences. Note that this function only +- * adjust the acceptance for the specified devices. Non specified are keept untouched. +- * +- * Typicall use case for this function is when dealing with pointer or touch events. +- * Those are normally dispatched to the first visible surface below the coordinate. +- * If you want a different behavior (i.e. forward events to an other surface below the coordinate, +- * you can set all above surfaces to refuse input events) +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_UpdateInputEventAcceptanceOn(struct ivi_layout_surface *ivisurf, +- int32_t devices, +- int32_t acceptance); ++ivi_layout_surface_set_content_observer( ++ struct ivi_layout_surface *ivisurf, ++ ivi_controller_surface_content_callback callback, ++ void* userdata); + + /** + * \brief Get the layer properties + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_getPropertiesOfLayer(struct ivi_layout_layer *ivilayer, +- struct ivi_layout_LayerProperties *pLayerProperties); +- +-/** +- * \brief Get the number of hardware layers of a screen +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return (const struct ivi_layout_layer_properties *) ++ * if the method call was successful ++ * \return NULL if the method call was failed + */ +-int32_t +-ivi_layout_getNumberOfHardwareLayers(uint32_t id_screen, +- int32_t *pNumberOfHardwareLayers); ++const struct ivi_layout_layer_properties * ++ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer); + + /** + * \brief Get the screens + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_getScreens(int32_t *pLength, struct ivi_layout_screen ***ppArray); ++ivi_layout_get_screens(int32_t *pLength, struct ivi_layout_screen ***ppArray); + + /** + * \brief Get the screens under the given layer + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_getScreensUnderLayer(struct ivi_layout_layer *ivilayer, +- int32_t *pLength, +- struct ivi_layout_screen ***ppArray); +- +-/** +- * \brief Get all Layers which are currently registered and managed by the services +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_getLayers(int32_t *pLength, struct ivi_layout_layer ***ppArray); ++ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer, ++ int32_t *pLength, ++ struct ivi_layout_screen ***ppArray); + + /** +- * \brief Get all Layers of the given screen ++ * \brief Get all Layers which are currently registered and managed ++ * by the services + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_getLayersOnScreen(struct ivi_layout_screen *iviscrn, +- int32_t *pLength, +- struct ivi_layout_layer ***ppArray); ++ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray); + + /** + * \brief Get all Layers under the given surface + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_getLayersUnderSurface(struct ivi_layout_surface *ivisurf, +- int32_t *pLength, +- struct ivi_layout_layer ***ppArray); +- +-/** +- * \brief Get all Surfaces which are currently registered and managed by the services +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_getSurfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray); ++ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf, ++ int32_t *pLength, ++ struct ivi_layout_layer ***ppArray); + + /** +- * \brief Get all Surfaces which are currently registered to a given layer and are managed by the services ++ * \brief Get all Surfaces which are currently registered and managed ++ * by the services + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_getSurfacesOnLayer(struct ivi_layout_layer *ivilayer, +- int32_t *pLength, +- struct ivi_layout_surface ***ppArray); ++ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray); + + /** + * \brief Create a layer which should be managed by the service + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return (struct ivi_layout_layer *) ++ * if the method call was successful ++ * \return NULL if the method call was failed + */ + struct ivi_layout_layer * +-ivi_layout_layerCreateWithDimension(uint32_t id_layer, +- int32_t width, int32_t height); ++ivi_layout_layer_create_with_dimension(uint32_t id_layer, ++ int32_t width, int32_t height); + + /** + * \brief Removes a layer which is currently managed by the service +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_layerRemove(struct ivi_layout_layer *ivilayer); +- +-/** +- * \brief Get the current type of the layer. +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed + */ +-int32_t +-ivi_layout_layerGetType(struct ivi_layout_layer *ivilayer, +- int32_t *pLayerType); +- +-/** +- * \brief Set the visibility of a layer. If a layer is not visible, the layer and its +- * surfaces will not be rendered. +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_layerSetVisibility(struct ivi_layout_layer *ivilayer, +- int32_t newVisibility); ++void ++ivi_layout_layer_remove(struct ivi_layout_layer *ivilayer); + + /** +- * \brief Get the visibility of a layer. If a layer is not visible, the layer and its +- * surfaces will not be rendered. ++ * \brief Set the visibility of a layer. If a layer is not visible, the ++ * layer and its surfaces will not be rendered. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_layerGetVisibility(struct ivi_layout_layer *ivilayer, +- int32_t *pVisibility); ++ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer, ++ bool newVisibility); + + /** + * \brief Set the opacity of a layer. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_layerSetOpacity(struct ivi_layout_layer *ivilayer, float opacity); ++ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer, ++ wl_fixed_t opacity); + + /** + * \brief Get the opacity of a layer. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return opacity if the method call was successful ++ * \return wl_fixed_from_double(0.0) if the method call was failed + */ +-int32_t +-ivi_layout_layerGetOpacity(struct ivi_layout_layer *ivilayer, float *pOpacity); ++wl_fixed_t ++ivi_layout_layer_get_opacity(struct ivi_layout_layer *ivilayer); + + /** + * \brief Set the area of a layer which should be used for the rendering. +- * Only this part will be visible. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_layerSetSourceRectangle(struct ivi_layout_layer *ivilayer, +- int32_t x, int32_t y, +- int32_t width, int32_t height); +- +-/** +- * \brief Set the destination area on the display for a layer. +- * The layer will be scaled and positioned to this rectangle for rendering ++ * Only this part will be visible. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_layerSetDestinationRectangle(struct ivi_layout_layer *ivilayer, +- int32_t x, int32_t y, +- int32_t width, int32_t height); ++ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer, ++ int32_t x, int32_t y, ++ int32_t width, int32_t height); + + /** +- * \brief Get the horizontal and vertical dimension of the layer. ++ * \brief Set the destination area on the display for a layer. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_layerGetDimension(struct ivi_layout_layer *ivilayer, +- int32_t *pDimension); +- +-/** +- * \brief Set the horizontal and vertical dimension of the layer. ++ * The layer will be scaled and positioned to this rectangle ++ * for rendering + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_layerSetDimension(struct ivi_layout_layer *ivilayer, +- int32_t *pDimension); ++ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer, ++ int32_t x, int32_t y, ++ int32_t width, int32_t height); + + /** + * \brief Get the horizontal and vertical position of the layer. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_layerGetPosition(struct ivi_layout_layer *ivilayer, +- int32_t *pPosition); ++ivi_layout_layer_get_position(struct ivi_layout_layer *ivilayer, ++ int32_t *dest_x, int32_t *dest_y); + + /** + * \brief Sets the horizontal and vertical position of the layer. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_layerSetPosition(struct ivi_layout_layer *ivilayer, +- int32_t *pPosition); ++ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer, ++ int32_t dest_x, int32_t dest_y); + + /** + * \brief Sets the orientation of a layer. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_layerSetOrientation(struct ivi_layout_layer *ivilayer, +- int32_t orientation); +- +-/** +- * \brief Gets the orientation of a layer. +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_layerGetOrientation(struct ivi_layout_layer *ivilayer, +- int32_t *pOrientation); +- +-/** +- * \brief Sets the color value which defines the transparency value. +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_layerSetChromaKey(struct ivi_layout_layer *ivilayer, +- int32_t* pColor); ++ivi_layout_layer_set_orientation(struct ivi_layout_layer *ivilayer, ++ enum wl_output_transform orientation); + + /** + * \brief Sets render order of surfaces within one layer + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_layerSetRenderOrder(struct ivi_layout_layer *ivilayer, +- struct ivi_layout_surface **pSurface, +- int32_t number); +- +-/** +- * \brief Get the capabilities of a layer +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_layerGetCapabilities(struct ivi_layout_layer *ivilayer, +- int32_t *pCapabilities); +- +-/** +- * \brief Get the possible capabilities of a layertype +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_layerTypeGetCapabilities(int32_t layerType, +- int32_t *pCapabilities); +- +-/** +- * \brief Create the logical surface, which has no native buffer associated +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_surfaceInitialize(struct ivi_layout_surface **pSurface); ++ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface **pSurface, ++ int32_t number); + + /** + * \brief Set the visibility of a surface. +- * If a surface is not visible it will not be rendered. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * If a surface is not visible it will not be rendered. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_surfaceSetVisibility(struct ivi_layout_surface *ivisurf, +- int32_t newVisibility); ++ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf, ++ bool newVisibility); + + /** + * \brief Get the visibility of a surface. +- * If a surface is not visible it will not be rendered. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * If a surface is not visible it will not be rendered. ++ * ++ * \return true if surface is visible ++ * \return false if surface is invisible or the method call was failed + */ +-int32_t +-ivi_layout_surfaceGetVisibility(struct ivi_layout_surface *ivisurf, +- int32_t *pVisibility); ++bool ++ivi_layout_surface_get_visibility(struct ivi_layout_surface *ivisurf); + + /** + * \brief Set the opacity of a surface. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_surfaceSetOpacity(struct ivi_layout_surface *ivisurf, +- float opacity); ++ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf, ++ wl_fixed_t opacity); + + /** + * \brief Get the opacity of a surface. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_surfaceGetOpacity(struct ivi_layout_surface *ivisurf, +- float *pOpacity); +- +-/** +- * \brief Set the keyboard focus on a certain surface +- * To receive keyboard events, 2 conditions must be fulfilled: +- * 1- The surface must accept events from keyboard. See ilm_UpdateInputEventAcceptanceOn +- * 2- The keyboard focus must be set on that surface +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return opacity if the method call was successful ++ * \return wl_fixed_from_double(0.0) if the method call was failed + */ +-int32_t +-ivi_layout_SetKeyboardFocusOn(struct ivi_layout_surface *ivisurf); +- +-/** +- * \brief Get the indentifier of the surface which hold the keyboard focus +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_GetKeyboardFocusSurfaceId(struct ivi_layout_surface **pSurfaceId); ++wl_fixed_t ++ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf); + + /** + * \brief Set the destination area of a surface within a layer for rendering. +- * The surface will be scaled to this rectangle for rendering. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_surfaceSetDestinationRectangle(struct ivi_layout_surface *ivisurf, +- int32_t x, int32_t y, +- int32_t width, int32_t height); +- +-/** +- * \brief Set the horizontal and vertical dimension of the surface. ++ * The surface will be scaled to this rectangle for rendering. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_surfaceSetDimension(struct ivi_layout_surface *ivisurf, +- int32_t *pDimension); +- +-/** +- * \brief Get the horizontal and vertical dimension of the surface. +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_surfaceGetDimension(struct ivi_layout_surface *ivisurf, +- int32_t *pDimension); +- +-/** +- * \brief Sets the horizontal and vertical position of the surface. +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_surfaceSetPosition(struct ivi_layout_surface *ivisurf, +- int32_t *pPosition); +- +-/** +- * \brief Get the horizontal and vertical position of the surface. +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_surfaceGetPosition(struct ivi_layout_surface *ivisurf, +- int32_t *pPosition); ++ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf, ++ int32_t x, int32_t y, ++ int32_t width, int32_t height); + + /** + * \brief Sets the orientation of a surface. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_surfaceSetOrientation(struct ivi_layout_surface *ivisurf, +- int32_t orientation); +- +-/** +- * \brief Gets the orientation of a surface. +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_surfaceGetOrientation(struct ivi_layout_surface *ivisurf, +- int32_t *pOrientation); +- +-/** +- * \brief Gets the pixelformat of a surface. +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_surfaceGetPixelformat(struct ivi_layout_layer *ivisurf, +- int32_t *pPixelformat); +- +-/** +- * \brief Sets the color value which defines the transparency value of a surface. +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed +- */ +-int32_t +-ivi_layout_surfaceSetChromaKey(struct ivi_layout_surface *ivisurf, +- int32_t* pColor); ++ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf, ++ enum wl_output_transform orientation); + + /** + * \brief Add a layer to a screen which is currently managed by the service + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_screenAddLayer(struct ivi_layout_screen *iviscrn, +- struct ivi_layout_layer *addlayer); ++ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn, ++ struct ivi_layout_layer *addlayer); + + /** + * \brief Sets render order of layers on a display + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_screenSetRenderOrder(struct ivi_layout_screen *iviscrn, +- struct ivi_layout_layer **pLayer, +- const int32_t number); ++ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn, ++ struct ivi_layout_layer **pLayer, ++ const int32_t number); + + /** +- * \brief Enable or disable a rendering optimization ++ * \brief register for notification on property changes of layer + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_SetOptimizationMode(uint32_t id, int32_t mode); ++ivi_layout_layer_add_notification(struct ivi_layout_layer *ivilayer, ++ layer_property_notification_func callback, ++ void *userdata); + + /** +- * \brief Get the current enablement for an optimization +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \brief remove notification on property changes of layer + */ +-int32_t +-ivi_layout_GetOptimizationMode(uint32_t id, int32_t *pMode); ++void ++ivi_layout_layer_remove_notification(struct ivi_layout_layer *ivilayer); + + /** +- * \brief register for notification on property changes of layer ++ * \brief register for notification on property changes of surface + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_layerAddNotification(struct ivi_layout_layer *ivilayer, +- layerPropertyNotificationFunc callback, +- void *userdata); ++ivi_layout_surface_add_notification(struct ivi_layout_surface *ivisurf, ++ surface_property_notification_func callback, ++ void *userdata); + + /** +- * \brief remove notification on property changes of layer +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \brief remove notification on property changes of surface + */ +-int32_t +-ivi_layout_layerRemoveNotification(struct ivi_layout_layer *ivilayer); ++void ++ivi_layout_surface_remove_notification(struct ivi_layout_surface *ivisurf); + + /** + * \brief Get the surface properties + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return (const struct ivi_surface_layer_properties *) ++ * if the method call was successful ++ * \return NULL if the method call was failed + */ +-int32_t +-ivi_layout_getPropertiesOfSurface(struct ivi_layout_surface *ivisurf, +- struct ivi_layout_SurfaceProperties *pSurfaceProperties); ++const struct ivi_layout_surface_properties * ++ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf); + + /** + * \brief Add a surface to a layer which is currently managed by the service + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_layerAddSurface(struct ivi_layout_layer *ivilayer, +- struct ivi_layout_surface *addsurf); ++ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface *addsurf); + + /** + * \brief Removes a surface from a layer which is currently managed by the service +- * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed + */ +-int32_t +-ivi_layout_layerRemoveSurface(struct ivi_layout_layer *ivilayer, +- struct ivi_layout_surface *remsurf); ++void ++ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface *remsurf); + + /** + * \brief Set the area of a surface which should be used for the rendering. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_surfaceSetSourceRectangle(struct ivi_layout_surface *ivisurf, +- int32_t x, int32_t y, +- int32_t width, int32_t height); ++ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf, ++ int32_t x, int32_t y, ++ int32_t width, int32_t height); + + /** + * \brief get weston_output from ivi_layout_screen. + * +- * \return (struct weston_screen *) ++ * \return (struct weston_output *) + * if the method call was successful + * \return NULL if the method call was failed + */ + struct weston_output * +-ivi_layout_screenGetOutput(struct ivi_layout_screen *); ++ivi_layout_screen_get_output(struct ivi_layout_screen *); + + struct weston_surface * +-ivi_layout_surfaceGetWestonSurface(struct ivi_layout_surface *ivisurf); ++ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf); + + int32_t +-ivi_layout_surfaceGetSize(struct ivi_layout_surface *ivisurf, int32_t *width, int32_t *height, int32_t *stride); ++ivi_layout_surface_get_size(struct ivi_layout_surface *ivisurf, ++ int32_t *width, ++ int32_t *height, ++ int32_t *stride); + + int32_t +-ivi_layout_layerSetTransition(struct ivi_layout_layer *ivilayer, +- enum ivi_layout_transition_type type, +- uint32_t duration); ++ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer, ++ enum ivi_layout_transition_type type, ++ uint32_t duration); + + int32_t +-ivi_layout_layerSetFadeInfo(struct ivi_layout_layer* layer, +- uint32_t is_fade_in, +- double start_alpha, double end_alpha); ++ivi_layout_layer_set_fade_info(struct ivi_layout_layer* layer, ++ uint32_t is_fade_in, ++ double start_alpha, double end_alpha); + + int32_t +-ivi_layout_surfaceSetTransition(struct ivi_layout_surface *ivisurf, +- enum ivi_layout_transition_type type, +- uint32_t duration); ++ivi_layout_surface_set_transition(struct ivi_layout_surface *ivisurf, ++ enum ivi_layout_transition_type type, ++ uint32_t duration); + +-int32_t +-ivi_layout_surfaceSetTransitionDuration(struct ivi_layout_surface *ivisurf,uint32_t duration); ++void ++ivi_layout_transition_layer_render_order(struct ivi_layout_layer* layer, ++ struct ivi_layout_surface** new_order, ++ uint32_t surface_num, ++ uint32_t duration); ++ ++void ++ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer* layer); + + /** +- * \brief Commit all changes and execute all enqueued commands since last commit. ++ * \brief Commit all changes and execute all enqueued commands since ++ * last commit. + * +- * \return 0 if the method call was successful +- * \return -1 if the method call was failed ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed + */ + int32_t +-ivi_layout_commitChanges(void); ++ivi_layout_commit_changes(void); + + #ifdef __cplusplus +-} /**/ ++} + #endif /* __cplusplus */ + + #endif /* _IVI_LAYOUT_EXPORT_H_ */ +diff --git a/weston-ivi-shell/src/ivi-layout.h b/weston-ivi-shell/src/ivi-layout.h +deleted file mode 100644 +index 7a53733..0000000 +--- a/weston-ivi-shell/src/ivi-layout.h ++++ /dev/null +@@ -1,147 +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. +- */ +- +-/** +- * The ivi-layout library supports API set of controlling properties of +- * surface and layer which groups surfaces. An unique ID whose type is integer +- * is required to create surface and layer. With the unique ID, surface and +- * layer are identified to control them. The API set consists of APIs to control +- * properties of surface and layers about followings, +- * - visibility. +- * - opacity. +- * - clipping (x,y,width,height). +- * - position and size of it to be displayed. +- * - orientation per 90 degree. +- * - add or remove surfaces to a layer. +- * - order of surfaces/layers in layer/screen to be displayed. +- * - commit to apply property changes. +- * - notifications of property change. +- * +- * Management of surfaces and layers grouping these surfaces are common way in +- * In-Vehicle Infotainment system, which integrate several domains in one system. +- * A layer is allocated to a domain in order to control application surfaces +- * grouped to the layer all together. +- */ +- +-#ifndef _IVI_LAYOUT_H_ +-#define _IVI_LAYOUT_H_ +- +-#ifdef __cplusplus +-extern "C" { +-#endif /* __cplusplus */ +- +-#include "compositor.h" +- +-struct ivi_layout_surface; +-struct ivi_layout_layer; +-struct ivi_layout_screen; +- +-struct ivi_layout_SurfaceProperties +-{ +- float opacity; +- uint32_t sourceX; +- uint32_t sourceY; +- uint32_t sourceWidth; +- uint32_t sourceHeight; +- uint32_t origSourceWidth; +- uint32_t origSourceHeight; +- int32_t startX; +- int32_t startY; +- uint32_t startWidth; +- uint32_t startHeight; +- int32_t destX; +- int32_t destY; +- uint32_t destWidth; +- uint32_t destHeight; +- uint32_t orientation; +- uint32_t visibility; +- uint32_t frameCounter; +- uint32_t drawCounter; +- uint32_t updateCounter; +- uint32_t pixelformat; +- uint32_t nativeSurface; +- uint32_t inputDevicesAcceptance; +- uint32_t chromaKeyEnabled; +- uint32_t chromaKeyRed; +- uint32_t chromaKeyGreen; +- uint32_t chromaKeyBlue; +- int32_t creatorPid; +- int32_t transitionType; +- uint32_t transitionDuration; +- uint32_t hasKeyboardFocus; +-}; +- +-struct ivi_layout_LayerProperties +-{ +- float opacity; +- uint32_t sourceX; +- uint32_t sourceY; +- uint32_t sourceWidth; +- uint32_t sourceHeight; +- uint32_t origSourceWidth; +- uint32_t origSourceHeight; +- int32_t destX; +- int32_t destY; +- uint32_t destWidth; +- uint32_t destHeight; +- uint32_t orientation; +- uint32_t visibility; +- uint32_t type; +- uint32_t chromaKeyEnabled; +- uint32_t chromaKeyRed; +- uint32_t chromaKeyGreen; +- uint32_t chromaKeyBlue; +- int32_t creatorPid; +- int32_t transitionType; +- uint32_t transitionDuration; +- double startAlpha; +- double endAlpha; +- uint32_t isFadeIn; +-}; +- +-enum ivi_layout_warning_flag { +- IVI_WARNING_INVALID_WL_SURFACE, +- IVI_WARNING_IVI_ID_IN_USE +-}; +- +-struct ivi_layout_interface { +- struct weston_view* (*get_weston_view)(struct ivi_layout_surface *surface); +- void (*surfaceConfigure)(struct ivi_layout_surface *ivisurf, +- int32_t width, int32_t height); +- int32_t (*surfaceSetNativeContent)(struct weston_surface *wl_surface, +- int32_t width, +- int32_t height, +- uint32_t id_surface); +- struct ivi_layout_surface* (*surfaceCreate)(struct weston_surface *wl_surface, +- uint32_t id_surface); +- void (*initWithCompositor)(struct weston_compositor *ec); +- void (*emitWarningSignal)(uint32_t id_surface, +- enum ivi_layout_warning_flag flag); +-}; +- +-WL_EXPORT struct ivi_layout_interface ivi_layout_interface; +- +-#ifdef __cplusplus +-} /**/ +-#endif /* __cplusplus */ +- +-#endif /* _IVI_LAYOUT_H_ */ diff --git a/meta-ivi/recipes-graphics/wayland/wayland-ivi-extension_1.3.0.bb b/meta-ivi/recipes-graphics/wayland/wayland-ivi-extension_1.3.0.bb index c8f9ca8..f7d8d0a 100644 --- a/meta-ivi/recipes-graphics/wayland/wayland-ivi-extension_1.3.0.bb +++ b/meta-ivi/recipes-graphics/wayland/wayland-ivi-extension_1.3.0.bb @@ -10,11 +10,15 @@ DEPENDS = "weston" # FIX ME # This should be TAG = "${PV}" but yocto doesn't support lightweight tags for now # https://bugzilla.yoctoproject.org/show_bug.cgi?id=6881 -TAG = "a4bde3e5a4c21ff7cf28cc027d45d7c63cac2f66" +#TAG = "a4bde3e5a4c21ff7cf28cc027d45d7c63cac2f66" +TAG = "1.3.91" SRC_URI = "git://git.projects.genivi.org/${PN}.git;tag=${TAG} \ file://use_sysroot_dir.patch \ - file://fix_compositor_include.patch \ + file://apply_weston-1.6.x.patch \ " +#" +# file://fix_compositor_include.patch \ +#" S = "${WORKDIR}/git" inherit cmake autotools diff --git a/meta-ivi/recipes-graphics/wayland/wayland_1.6.0.bbappend b/meta-ivi/recipes-graphics/wayland/wayland_1.6.0.bbappend new file mode 100644 index 0000000..3d3584a --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/wayland_1.6.0.bbappend @@ -0,0 +1,8 @@ +PR = "r1" + +# [PATCH] build fix up of "error: 'WL_POINTER_ERROR_ROLE' undeclared" +# to support this macro, we have to go version 1.6.91 +# Signed-off-by: Yong-iL Joh <yong-il.joh at windriver.com> +SRC_URI_remove = "http://wayland.freedesktop.org/releases/${BPN}-${PV}.tar.xz" +SRC_URI_append += "git://anongit.freedesktop.org/wayland/wayland.git;tag=1.6.91" +S = "${WORKDIR}/git" diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0001-README-modifed-for-ivi-shell.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0001-README-modifed-for-ivi-shell.patch new file mode 100644 index 0000000..5712d02 --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0001-README-modifed-for-ivi-shell.patch @@ -0,0 +1,110 @@ +From 0a9f945fe49de1653681589711a31f2431522282 Mon Sep 17 00:00:00 2001 +From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +Date: Wed, 29 Jan 2014 15:53:59 +0900 +Subject: [PATCH 01/15] README modifed for ivi-shell + +changes for amendament v1: + add ivi-shell/README. + move description of ivi-shell from README to ivi-shell/README + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------------- +changes for v2: +ivi-shell: Update README more details + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> +--- + ivi-shell/README | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 79 insertions(+) + create mode 100644 ivi-shell/README + +diff --git a/ivi-shell/README b/ivi-shell/README +new file mode 100644 +index 0000000..7f41291 +--- /dev/null ++++ b/ivi-shell/README +@@ -0,0 +1,79 @@ ++ In-vehicle infotainment (information and entertainment) ++ graphical environment support modules for Weston ++ ++ ++IVI-shell is an alternative shell for Weston, a Wayland display server. ++Window management and application interaction with the display server ++are very different to that of a normal desktop, which is why this is ++a separate shell and not an extension to the desktop-shell suite with ++xdg_shell. As such, applications need to be specifically written to use ++IVI-shell. ++ ++IVI-shell contains two main features: ++- Common layout library for surface, which allow ivi-shell developer ++ to develop own shell, linking Common layout library. ++ For the time being, the library refers Genivi ilm interface. ++ ++ http://projects.genivi.org/wayland-ivi-extension/ ++ ++- Extension protocal; ivi-application to tie wl_surface and a given ID. ++ With this ID, shell can identify which wl_surface is drawn by which ++ application. In in-vehicle infortainment system, a shell has to update ++ a property of a wl_surface. E.g. there may be a use case when vehicle ++ starts to move, the wl_surface drawn by Car navigation is expected to ++ move top of surfaces. ++ ++The actual software components delivered with Weston are: ++ ++- ivi-application.xml: ++ Wayland protocol extension for IVI-applications; the public ++ shell protocol (the same concept as xdg_shell). ++ Implemented by ivi-shell.so. ++ ++- ivi-shell.so: ++ A Weston shell module that implements ivi-application.xml interfaces. ++ Loads ivi-layout.so. ++ ++- ivi-layout.so: ++ Implements the IVI window management concepts: Screen, Layer, ++ Surface, groups of Layers, groups of Surfaces, see: ++ http://projects.genivi.org/ivi-layer-management/node/13 ++ Offers a stable API for writing IVI-controller modules like ++ hmi-controller.so against the IVI concepts. In other words, ++ it offers an API to write IVI window manager modules. ++ ++- hmi-controller.so: ++ A sample implementation of an IVI-controller module, usually ++ replaced by IVI system vendors. ++ Uses ivi-layout.so to perform essentially window manager tasks. ++ This implementation keeps all window management inside the module, ++ while IVI-systems may use another module that exposes all window ++ management via Wayland or other protocol for an external process ++ to control: ++ http://git.projects.genivi.org/?p=wayland-ivi-extension.git;a=summary ++ ++- ivi-hmi-controller.xml: ++ Wayland protocol extension for IVI display control; the private ++ shell protocol for weston-ivi-shell-user-interface client ++ (the same concept as desktop-shell.xml). ++ Implemented by hmi-controller.so, and usually replaced by IVI ++ system vendors. ++ ++- weston-ivi-shell-user-interface: ++ A sample implementation of an IVI shell helper client, usually ++ replaced by IVI system vendors. ++ A helper client for basic display content, similar to ++ weston-desktop-shell. ++ ++ ++How to compile: ++same as weston. To disable, use option: --disable-ivi-shell for configure. ++ ++How to configure weston.ini: ++reference ini file will be generated in <build_dir>/ivi-shell. ++ ++How to run: ++same as weston. exec weston. ++ ++How to use UI: ++http://lists.freedesktop.org/archives/wayland-devel/attachments/20140625/abbfc064/attachment-0001.png +-- +1.7.9.5 + diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0002-protocol-add-interface-ivi_application-extension.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0002-protocol-add-interface-ivi_application-extension.patch new file mode 100644 index 0000000..8087743 --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0002-protocol-add-interface-ivi_application-extension.patch @@ -0,0 +1,239 @@ +From 983fb7e0cf9f91a60e1cb07f73fb5e70b4cc9362 Mon Sep 17 00:00:00 2001 +From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +Date: Mon, 17 Mar 2014 14:15:14 +0900 +Subject: [PATCH 02/15] protocol: add interface ivi_application extension + +- introduces ivi-application.xml + +<<<<<<new +Many applications in an IVI-system are special single-purpose +applications that have a very specific role in the whole IVI UI, for +example a rear camera, speedometer, map, etc. The IVI system vendor +specifies what these are and how they integrate into the UI. They also +vary between particular IVI systems. This is why we use (system-)global, +unique, pre-determined ID numbers to tell what wl_surface is which +application, instead of writing specific shell requests for each one. +Using ID numbers allows vendors to easily invent new component +applications without extending or breaking the actual Wayland protocol. +In IVI-systems, the ID is a standard concept already used in several +APIs, with a vendor-specified global definition of ID assignments.` +>>>>>>old +ivi_applicatoin extension creates ivi_surface objects tied +to a given wl_surface with a given id. The given id can be used in a +shell to identify which application is assigned to a wl_surface and +layout the surface wherever the shell wants. ivi_surface objects can +be used to receive status of wl_surface in the scenegraph of the +compositor. +------ + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +ivi-application.xml: Add configure event in ivi_surface + +Configure event is notified to suggest resize of its surface + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------------- +protocol: update description of destroy. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------------- +protocol: ivi-application, remove Visibility event. + +Visibility event can be replaced with frame event. We need to clarify +IVI use case to enalbe again, why explicit event is required. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------------- +protocol: ivi-application.xml, update decription of ivi-application + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------------- +protocol: ivi-application add errors and modify description of +surface_create + +Indeed, the new role stuff. For more information, see: +http://cgit.freedesktop.org/wayland/wayland/commit/?id=ff2df60b1a07c3d26d170e65cd5440d15cdf3088 +and examples: +http://cgit.freedesktop.org/wayland/wayland/commit/?id=a27501f40e9a369ed5d4c655674130e76214281f +http://cgit.freedesktop.org/wayland/wayland/commit/?id=7a0b86ab22e026387b6d529a46d8eb416caa26fa +http://cgit.freedesktop.org/wayland/weston/commit/?id=50b67479033709d8ab32744c7b8346b130ace9e0 + +So, you also need to add a protocol error code for role errors like in +the examples. + +What happens if the ID is already used by an existing surface? Does that +depend on the particular ID perhaps? + +Would you want to tie ID as a role? Note, that if you do, there cannot +be two surfaces with the same ID. + +I think we talked about this before, but the specifications are still +missing here. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------------- +protocol: ivi-application.xml. alignment of indents + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------------- +protocol: fix xml format error + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------------- +Makefile.am: add ivi-application to toolkit + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------------- +protocol: ivi-application.xml, add clear decription of surface_create + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------------- +protocol: ivi-application.xml, update license file test + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +--- + Makefile.am | 7 ++- + protocol/ivi-application.xml | 96 ++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 101 insertions(+), 2 deletions(-) + create mode 100644 protocol/ivi-application.xml + +diff --git a/Makefile.am b/Makefile.am +index b2d6893..2330933 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -446,7 +446,9 @@ nodist_libtoytoolkit_la_SOURCES = \ + protocol/workspaces-protocol.c \ + protocol/workspaces-client-protocol.h \ + protocol/xdg-shell-protocol.c \ +- protocol/xdg-shell-client-protocol.h ++ protocol/xdg-shell-client-protocol.h \ ++ protocol/ivi-application-protocol.c \ ++ protocol/ivi-application-client-protocol.h + + BUILT_SOURCES += $(nodist_libtoytoolkit_la_SOURCES) + +@@ -987,7 +989,8 @@ EXTRA_DIST += \ + protocol/wayland-test.xml \ + protocol/xdg-shell.xml \ + protocol/fullscreen-shell.xml \ +- protocol/scaler.xml ++ protocol/scaler.xml \ ++ protocol/ivi-application.xml + + man_MANS = weston.1 weston.ini.5 + +diff --git a/protocol/ivi-application.xml b/protocol/ivi-application.xml +new file mode 100644 +index 0000000..6bb90a7 +--- /dev/null ++++ b/protocol/ivi-application.xml +@@ -0,0 +1,96 @@ ++<?xml version="1.0" encoding="UTF-8"?> ++<protocol name="ivi_application"> ++ ++ <copyright> ++ Copyright (C) 2013 DENSO CORPORATION ++ Copyright (c) 2013 BMW Car IT GmbH ++ ++ 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. ++ </copyright> ++ ++ <interface name="ivi_surface" version="1"> ++ <description summary="application interface to surface in ivi compositor"/> ++ ++ <request name="destroy" type="destructor"> ++ <description summary="destroy ivi_surface"> ++ This removes link from ivi_id to wl_surface and destroys ivi_surface. ++ The ID, ivi_id, is free and can be used for surface_create again. ++ </description> ++ </request> ++ ++ <event name="configure"> ++ <description summary="suggest resize"> ++ The configure event asks the client to resize its surface. ++ ++ The size is a hint, in the sense that the client is free to ++ ignore it if it doesn't resize, pick a smaller size (to ++ satisfy aspect ratio or resize in steps of NxM pixels). ++ ++ The client is free to dismiss all but the last configure ++ event it received. ++ ++ The width and height arguments specify the size of the window ++ in surface local coordinates. ++ </description> ++ <arg name="width" type="int"/> ++ <arg name="height" type="int"/> ++ </event> ++ </interface> ++ ++ <interface name="ivi_application" version="1"> ++ <description summary="create ivi-style surfaces"> ++ This interface is exposed as a global singleton. ++ This interface is implemented by servers that provide IVI-style user interfaces. ++ It allows clients to associate a ivi_surface with wl_surface. ++ </description> ++ ++ <enum name="error"> ++ <entry name="role" value="0" summary="given wl_surface has another role"/> ++ <entry name="ivi_id" value="1" summary="given ivi_id is assigned to another wl_surface"/> ++ </enum> ++ ++ <request name="surface_create"> ++ <description summary="create ivi_surface with numeric ID in ivi compositor"> ++ This request gives the wl_surface the role of an IVI Surface. Creating more than ++ one ivi_surface for a wl_surface is not allowed. Note, that this still allows the ++ following example: ++ ++ 1. create a wl_surface ++ 2. create ivi_surface for the wl_surface ++ 3. destroy the ivi_surface ++ 4. create ivi_surface for the wl_surface (with the same or another ivi_id as before) ++ ++ surface_create will create a interface:ivi_surface with numeric ID; ivi_id in ++ ivi compositor. These ivi_ids are defined as unique in the system to identify ++ it inside of ivi compositor. The ivi compositor implements business logic how to ++ set properties of the surface with ivi_id according to status of the system. ++ E.g. a unique ID for Car Navigation application is used for implementing special ++ logic of the application about where it shall be located. ++ The server regards following cases as protocol errors and disconnects the client. ++ - wl_surface already has an nother role. ++ - ivi_id is already assigned to an another wl_surface ++ </description> ++ <arg name="ivi_id" type="uint"/> ++ <arg name="surface" type="object" interface="wl_surface"/> ++ <arg name="id" type="new_id" interface="ivi_surface"/> ++ </request> ++ ++ </interface> ++ ++</protocol> +-- +1.7.9.5 + diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0003-ivi-shell-add-IVI-layout-APIs.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0003-ivi-shell-add-IVI-layout-APIs.patch new file mode 100644 index 0000000..94919dd --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0003-ivi-shell-add-IVI-layout-APIs.patch @@ -0,0 +1,5642 @@ +From f67d989f4b5e1ffd7e6cc562bf6065917b748342 Mon Sep 17 00:00:00 2001 +From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +Date: Tue, 6 May 2014 17:25:31 +0900 +Subject: [PATCH 03/15] ivi-shell: add IVI layout APIs + +- ivi-layout.so +- introduces ivi-layout-export.h, ivi-layout.[ch] + +API set of controlling properties of surface and layer which groups +surfaces. An unique ID whose type is integer is required to create +surface and layer. With the unique ID, surface and layer are identified +to control them. The API set consists of APIs to control properties of +surface and layers about followings, + +- visibility. +- opacity. +- clipping (x,y,width,height). +- position and size of it to be displayed. +- orientation per 90 degree. +- add or remove surfaces to a layer. +- order of surfaces/layers in layer/screen to be displayed. +- commit to apply property changes. +- notifications of property change. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +ivi-layout: fix calculation of view scale. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +-------------------------------------------------------- +ivi-shell/ivi-layout.[ch] from transition animation + +-------------------------------------------------------- +ivi-shell/ivi-layout-export.h from transition animation + +-------------------------------------------------------- +ivi-shell/ivi-layout-private.h from transition animation + +-------------------------------------------------------- +ivi-shell: Add IVI layout APIs - ivi_layout_surfaceGetWestonSurface - ivi_layout_surfaceGetSize These are used by screenshot APIs. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------- +update for configure support + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------ +ivi-shell: transition animation support + +- introduces ivi-shell/ivi-layout-transition.[ch] + +interpolate animation when an atribute of surface is changed by +commitChanges. + +----------------------------------------------------------- +update for configure support for transition animation + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Insert a space between "void" and "(*". + +> > In all function pointer type definitions, need a space between "void" +> > and "(*". +> [ntanibata] I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +----------------------------------------------------------- + +ivi-shell: Define return type. + +> > Hm, the return type is unsigned, so -1 makes little sense. Should +> > there +> > be something like #define IVI_INVALID_ID 0xffffffff and the use +> > that? +> [ntanibata] I agree. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Delete unused APIs + +> What is color? An array? How many bits per channel? +> What if the output or buffer is at different bit depth? +> [ntanibata] This is not valid. I will remove. + +> What are capabilities? +> [ntanibata] This is not valid now. I will remove. + +> What is a layer type? +> [ntanibata] This is not valid now. I will remove. + +> Unimplemented... how would you use this? +> How would you set the content? +> [ntanibata] This is not valid now. I will remove. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: remove commented-out code + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Delete input acceptance function. + +> > Is this really necessary, when you could be forcing the input region +> > of +> > weston_surface? What are 'devices' and... +> > +> > Oh, I see that this function is not actually implemented. You should +> > remove +> > all functions you do not implement. You can add the implementations +> > later, +> > and if you need the stubs to be able to test non-upstream code, you +> > can +> > keep the stubs in your own repository. +> > +> [ntanibata] I agree. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: layout APIs header, clean up public and private ones in two +headers, ivi-layout-export/private.h + +> b40fdf4 ivi-shell: add IVI layout APIs +> +> Header rearrangements? +> What are the API stability guarantees? +> New title: "ivi-shell: add ivi-layout.so module and API" + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Changed stdbool from uint32_t + +> Supposedly visibility is a boolean? Non-zero means visible? +> [ntanibata] It should be a Boolean. I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Change the return-type of APIs to void if it had not used. + +> > It's kind of strange to see this sort of function being able to +> > return +> > failure. How could it reasonably fail? +> > +> > Looking at your implementation, it cannot fail, unless the caller +> > made +> > a mistake. It is worth returning a failure only if the called can +> > sensibly +> > react to or recover from it. +> > +> > Couldn't this (and all other remove functions) just return void? +> > +> > You can still do the sanity check in the code and log an error, but +> > I +> don't +> > see value in returning the error from the function. Is there some +> > value? +> > +> [ntanibata] I will change it to void. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +Change return-type of getter of properties APIs to const properties pointer. + +> > Any particular reason to return a copy, rather than a const pointer to +> > the original? +> [ntanibata] I will check. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Return the requested value in the return value. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Change type of orientation value int32_t to wl_output_transform. + +> > > > What is 'orientation'? enum wl_output_transform? +> > > [ntanibata] rotate surface/layer with 0,90,180,270 degree. +> > +> > Yeah, I guessed that much, but what is the actual API here? :-) +> > The values from enum wl_output_transform? +> [ntanibata] they are from here. However, it should use enum +> defined in Weston. I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Delete functions of Keyboard focus. + +> > Keyboard focus of which weston_seat? How do you handle multiple +> > weston_seats? +> [ntanibata] This would be discuss later with patch of src/input.c. +> For the time being, this will be removed. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Replace allocation check assert to if-statement. + +> > Heh, considering your usual paranoid pointer checks, using an assert +> > here is surprising. ;-) +> > +> > I think in Weston we are accustomed to check the return value from +> > malloc() and propagate the failure, even though it usually is in +> > vain. +> > +> > assert()s should be reserved for programmer errors. +> [ntanibata] I see. I will fix. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Delete needless memory allocation. + +> > Just allocate it from stack instead? +> [ntanibata] I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Use the weston_config that has already been created. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Output log when mamory allocation fails. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Delete cursor check. + +> > > > What is this about? +> > > > Why would you remove the cursor_layer? +> > > > Also, there is a default cursor theme if nothing is set in +> > > > weston.ini. +> > > [ntanibata] I think I should add comments clearly. +> > > If cursor-theme is not set, I want to disable showing cursor +> > > because cursor is not mandatory on ivi system e.g with touch +> > > panel. +> > > So I call wl_list_remove. +> > +> > But a cursor theme has nothing to do whether a cursor will be shown. +> > If no theme is set, a default theme is used (and if that does not +> > exist, a built-in theme from libwayland-cursor gets used). So there +> > is always some theme, regardless of settings. +> > +> > A cursor will be shown, if the compositor has a wl_pointer device (a +> > mouse). +> > If there are no wl_pointer devices, there are also no cursors. +> > That is how Weston works already. +> [ntanibata] Oh, I see. This feature fix may use case. So I will remove +> this code. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Fix ivi_layout_layerGetDimension + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Change int type from array type + +> Just one value? Or is it supposed to be an array of two values? +> [ntanibata] It is an array two values. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Delete unsupported APIs. + +> > Why would an external module want to know? It cannot really do +> > anything +> > with that information, can it? +> > +> > Handling hardware overlays is an internal detail of a Weston +> > backend, and +> > deliberately not exposed to clients, and not even to outside of the +> > backend really. +> [ntanibata] I will remote this API. This is just a history from Layer +> manager + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Modification of function name + +> "identifier"? +> [ntanibata] right. I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Fix comment out message + +> Twice? +> [ntanibata] Oh, I will remove one. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Add function header comments. + +> > What is this for really? The implementation looks suspiciously +> > broken, +> > depending on how it is supposed to be used. +> [ntanibata] If this is not used, I will remove. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- + +ivi-shell: Fix ivi_layout_surfaceSetPosition. Change int type from array type + +> Again, array of two or? +> [ntanibata] I will fix. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- + +Add comments: what happens when commitchange is called during transition +animation in comment of ivi-layout.c + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Delete ivi_layout_surface_pixelformat + +> Does this pixel format enumeration come from somewhere, or was it +> invented here? Or are you removing it with the unsupported/unused features? +> [ntanibata]Yes, I will remove them. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Change quoted_printable_encode form camelcase + +> Is the style here, that all internal and Weston core facing things are +> named with underscores, and all ivi-layout public API is in CamelCase? +> [ntanibata] I will change them to underscores to avoid CamelCase. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +add FIXME at calling clock_gettime + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Replace list_thing with thing_list. + +> > We'd prefer naming it as thing_list, not list_thing. Like in English +> > you can have a "note list" meaning a "list of notes", while "list +> > note" +> > sounds like it is one note about a list. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Declare variable in the beginning of a block. + +> > Declarations mixed up with code. Our style has declarations only in +> > the beginning of a block. +> [ntanibata] I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: ivi-layout.c, clean-up definition of valueable in the middle function. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: ivi-layout.c, remove #if 0 + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- + ivi-shell: ivi-layout-transition.c, clean-up definition of valueable in the middle + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- + ivi-shell: ivi-layout-transition.c, remove code commented out + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: ivi-layout, modify comments, surface/layer/screen -> ivi_* + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Delete duplicated of definition. + +> > > > Looks identical to enum ivi_layout_transition_type, do you +> > > > really need another? +> > > [ntanibata] Question: Do you mean why there are many types? +> > +> > Why define ivi_layout_inner_transition_type, when +> > ivi_layout_transition_type is already the same down to the actual +> > values, if I'm not mistaken? +> > +> > Why not just use ivi_layout_transition_type everywhere? +> [ntanibata] Oh, I see "inner". I will fix them. I jumped the gun:) + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: ivi-layout-export/private.h, reorgenize two interface from private to export because it is used by hmi-controller.c + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Use error-code defined in ivi-application-protocol. + +> > You also need to add the two error codes into ivi-application +> > interface and use those instead of WL_DISPLAY_ERROR_INVALID_OBJECT. +> [ntanibata] I will fix this according to two error codes. +> <enum name="error"> +> <entry name="role" value="0" summary="given wl_surface has +> another role"/> +> <entry name="ivi_id" value="1" summary="given ivi_id is assigned +> to another wl_surface"/> +> </enum> +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Amend wrong comments regarding return values: + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Fix transition bug on visibility change. + +This is embeded during cleaning up code. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Qualify const modifier to readonly argument. + +This is embded during cleaning up code before. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Fix invalid type. + +> prop->opacity = wlfixedfrom_double(1.0); +> What? 'opacity' is a float, isn't it? + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell:ivi-layout.c Change type of calculatable variables to signed from unsigned + +> FWIW, if you are going to do calculations with these variables, they +> should be signed. If you mix unsigned and signed variables in +> calculations, the result is probably not what you expect in all cases. +> This is just a reminder for you, that you might want to change these in the future. +> Weston core categorically uses signed variables for anything that is +> involved in calculations, even if negative values would not make any +> sense for a particular variable. +> Counters (that may wrap around) are of course better stored as unsigned. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +Makefile.am: clean up Makefile.am with FR3 for ivi-layout + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +configure.ac: remove checking module cairo. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: ivi-layout-export.h, remove unused member of structure. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: ivi-layout-transition, remove wl_event_source_timer_update +because The timer is already disarmed when you create it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: ivi-layout-export.h, add an explanation of what kind of +stability guarantees this API +and ABI should have. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Move functions that are not used by other to private.h from export.h. + +> +WL_EXPORT int32_t +ivi_layout_surface_get_dimension(struct +> ivi_layout_surface ivisurf, + int32_t dest_width, int32_t +*dest_height) +> Does this function need to be WL_EXPORT? +> hmi-controller does not use it, and it is exposed to ivi-shell.so via +> struct ivi_layout_interface. + +For the time being, there are some APIs which is not used by +hmi-controller.c. but it is used by ivi-controller.so maintained by +another project. I will add reference implementation for them later in +hmi-controller.c + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-layout: ivi-layout-export.h remove type of ivi_layout_layer_properties + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Rename confusing functions + +> .oO( That looks strange, it's returning either 0 or 1 as an identifier. +> Maybe this has nothing to do with identifiers... ) + +This callback is to detect whether transition happens or not. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: ivi-layout-private/export.h, move struct ivi_layout_interface declarations from > ivi-layout-export.h into ivi-layout-private.h + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: ivi-layout.c, Remove casts to (void) + +> I don't think we need these casts. The warning about unused arguments is disabled, isn't it? +> You should be able to remove casts to (void) from all places. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-layout: private.h, remove WL_EXPORT definition of ivi_layout_interface + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-layout: remove ivi_layout_surface_set_native_content. + +There are two use case to +- create ivi_surface without wl_surface to set property in advanced +- keep property per ID during deletion of ivi_surface. + +This is supported later. For the time being, remove this function. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-layout: Fix invalid memory read/write. correct destruction methods + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-layout: code style clean up + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-layout: revert destruction method to re-organize them. + +This commit is a target of this revert. +https://github.com/ntanibata/weston-ivi-shell/commit/f097ccf90a12efad954228f2534a4cad8f578d19 + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-layout: remove unused function. This was called from ivi-shell. +However it is not called anymore after code clean up. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: ivi-layout.c, Remove all configure event on specified surface. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-layout.c: remove unneeded casts + +Also a couple of whitespace fixes. + +ivi-layout.c: reflow long lines + +---------------------------------------------------------- +ivi-layout.c: simplify add_link_to_surface() + +There is a way to make this function even simpler. + +If you guarantee, that it is always legal to call wl_list_remove() on the +link, this function could literally be just: + +wl_list_remove(&link_layer->link_to_layer); +wl_list_insert(&ivilayer->link_to_surface, &link_layer->link_to_layer); + +You would go from an O(n) operation to O(1) operation! +--- + Makefile.am | 20 + + configure.ac | 9 + + ivi-shell/ivi-layout-export.h | 689 +++++++++ + ivi-shell/ivi-layout-private.h | 319 +++++ + ivi-shell/ivi-layout-transition.c | 1111 +++++++++++++++ + ivi-shell/ivi-layout.c | 2809 +++++++++++++++++++++++++++++++++++++ + 6 files changed, 4957 insertions(+) + create mode 100644 ivi-shell/ivi-layout-export.h + create mode 100644 ivi-shell/ivi-layout-private.h + create mode 100644 ivi-shell/ivi-layout-transition.c + create mode 100644 ivi-shell/ivi-layout.c + +diff --git a/Makefile.am b/Makefile.am +index 2330933..812b4bd 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -720,6 +720,26 @@ nodist_fullscreen_shell_la_SOURCES = \ + BUILT_SOURCES += $(nodist_fullscreen_shell_la_SOURCES) + endif + ++if ENABLE_IVI_SHELL ++ ++module_LTLIBRARIES += \ ++ $(ivi_layout) ++ ++ivi_layout = ivi-layout.la ++ivi_layout_la_LDFLAGS = -module -avoid-version ++ivi_layout_la_LIBADD = $(COMPOSITOR_LIBS) libshared.la ++ivi_layout_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS) ++ivi_layout_la_SOURCES = \ ++ ivi-shell/ivi-layout-export.h \ ++ ivi-shell/ivi-layout-private.h \ ++ ivi-shell/ivi-layout.c \ ++ ivi-shell/ivi-layout-transition.c ++ ++BUILT_SOURCES += $(nodist_ivi_layout_la_SOURCES) ++ ++endif ++ ++ + if ENABLE_SCREEN_SHARING + + module_LTLIBRARIES += screen-share.la +diff --git a/configure.ac b/configure.ac +index 05e883d..e45dbeb 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -434,6 +434,13 @@ if test "x$enable_dbus" != "xno"; then + fi + AM_CONDITIONAL(ENABLE_DBUS, test "x$enable_dbus" = "xyes") + ++# ivi-shell support ++AC_ARG_ENABLE(ivi-shell, ++ AS_HELP_STRING([--disable-ivi-shell], ++ [do not build ivi-shell server plugin and client]),, ++ enable_ivi_shell=yes) ++AM_CONDITIONAL(ENABLE_IVI_SHELL, test "x$enable_ivi_shell" = "xyes") ++ + AC_ARG_ENABLE(wcap-tools, [ --disable-wcap-tools],, enable_wcap_tools=yes) + AM_CONDITIONAL(BUILD_WCAP_TOOLS, test x$enable_wcap_tools = xyes) + if test x$enable_wcap_tools = xyes; then +@@ -523,6 +530,8 @@ AC_MSG_RESULT([ + XWayland ${enable_xwayland} + dbus ${enable_dbus} + ++ ivi-shell ${enable_ivi_shell} ++ + Build wcap utility ${enable_wcap_tools} + Build Fullscreen Shell ${enable_fullscreen_shell} + +diff --git a/ivi-shell/ivi-layout-export.h b/ivi-shell/ivi-layout-export.h +new file mode 100644 +index 0000000..18b1dc3 +--- /dev/null ++++ b/ivi-shell/ivi-layout-export.h +@@ -0,0 +1,689 @@ ++/* ++ * Copyright (C) 2013 DENSO CORPORATION ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and ++ * its documentation for any purpose is hereby granted without fee, provided ++ * that the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of the copyright holders not be used in ++ * advertising or publicity pertaining to distribution of the software ++ * without specific, written prior permission. The copyright holders make ++ * no representations about the suitability of this software for any ++ * purpose. It is provided "as is" without express or implied warranty. ++ * ++ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS ++ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND ++ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY ++ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ++ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF ++ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++/** ++ * The ivi-layout library supports API set of controlling properties of ++ * surface and layer which groups surfaces. An unique ID whose type is integer ++ * is required to create surface and layer. With the unique ID, surface and ++ * layer are identified to control them. The API set consists of APIs to control ++ * properties of surface and layers about followings, ++ * - visibility. ++ * - opacity. ++ * - clipping (x,y,width,height). ++ * - position and size of it to be displayed. ++ * - orientation per 90 degree. ++ * - add or remove surfaces to a layer. ++ * - order of surfaces/layers in layer/screen to be displayed. ++ * - commit to apply property changes. ++ * - notifications of property change. ++ * ++ * Management of surfaces and layers grouping these surfaces are common ++ * way in In-Vehicle Infotainment system, which integrate several domains ++ * in one system. A layer is allocated to a domain in order to control ++ * application surfaces grouped to the layer all together. ++ * ++ * This API and ABI follow following specifications. ++ * http://projects.genivi.org/wayland-ivi-extension/layer-manager-apis ++ */ ++ ++#ifndef _IVI_LAYOUT_EXPORT_H_ ++#define _IVI_LAYOUT_EXPORT_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++ ++#include "stdbool.h" ++#include "compositor.h" ++ ++#define IVI_SUCCEEDED (0) ++#define IVI_FAILED (-1) ++ ++struct ivi_layout_layer; ++struct ivi_layout_screen; ++struct ivi_layout_surface; ++ ++struct ivi_layout_surface_properties ++{ ++ wl_fixed_t opacity; ++ int32_t source_x; ++ int32_t source_y; ++ int32_t source_width; ++ int32_t source_height; ++ int32_t start_x; ++ int32_t start_y; ++ int32_t start_width; ++ int32_t start_height; ++ int32_t dest_x; ++ int32_t dest_y; ++ int32_t dest_width; ++ int32_t dest_height; ++ enum wl_output_transform orientation; ++ bool visibility; ++ int32_t transition_type; ++ uint32_t transition_duration; ++}; ++ ++struct ivi_layout_layer_properties ++{ ++ wl_fixed_t opacity; ++ int32_t source_x; ++ int32_t source_y; ++ int32_t source_width; ++ int32_t source_height; ++ int32_t dest_x; ++ int32_t dest_y; ++ int32_t dest_width; ++ int32_t dest_height; ++ enum wl_output_transform orientation; ++ uint32_t visibility; ++ int32_t transition_type; ++ uint32_t transition_duration; ++ double start_alpha; ++ double end_alpha; ++ uint32_t is_fade_in; ++}; ++ ++enum ivi_layout_notification_mask { ++ IVI_NOTIFICATION_NONE = 0, ++ IVI_NOTIFICATION_OPACITY = (1 << 1), ++ IVI_NOTIFICATION_SOURCE_RECT = (1 << 2), ++ IVI_NOTIFICATION_DEST_RECT = (1 << 3), ++ IVI_NOTIFICATION_DIMENSION = (1 << 4), ++ IVI_NOTIFICATION_POSITION = (1 << 5), ++ IVI_NOTIFICATION_ORIENTATION = (1 << 6), ++ IVI_NOTIFICATION_VISIBILITY = (1 << 7), ++ IVI_NOTIFICATION_PIXELFORMAT = (1 << 8), ++ IVI_NOTIFICATION_ADD = (1 << 9), ++ IVI_NOTIFICATION_REMOVE = (1 << 10), ++ IVI_NOTIFICATION_CONFIGURE = (1 << 11), ++ IVI_NOTIFICATION_ALL = 0xFFFF ++}; ++ ++enum ivi_layout_transition_type{ ++ IVI_LAYOUT_TRANSITION_NONE, ++ IVI_LAYOUT_TRANSITION_VIEW_DEFAULT, ++ IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY, ++ IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY, ++ IVI_LAYOUT_TRANSITION_LAYER_FADE, ++ IVI_LAYOUT_TRANSITION_LAYER_MOVE, ++ IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER, ++ IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE, ++ IVI_LAYOUT_TRANSITION_VIEW_RESIZE, ++ IVI_LAYOUT_TRANSITION_VIEW_FADE, ++ IVI_LAYOUT_TRANSITION_MAX, ++}; ++ ++typedef void (*layer_property_notification_func)( ++ struct ivi_layout_layer *ivilayer, ++ const struct ivi_layout_layer_properties *, ++ enum ivi_layout_notification_mask mask, ++ void *userdata); ++ ++typedef void (*surface_property_notification_func)( ++ struct ivi_layout_surface *ivisurf, ++ const struct ivi_layout_surface_properties *, ++ enum ivi_layout_notification_mask mask, ++ void *userdata); ++ ++typedef void (*layer_create_notification_func)( ++ struct ivi_layout_layer *ivilayer, ++ void *userdata); ++ ++typedef void (*layer_remove_notification_func)( ++ struct ivi_layout_layer *ivilayer, ++ void *userdata); ++ ++typedef void (*surface_create_notification_func)( ++ struct ivi_layout_surface *ivisurf, ++ void *userdata); ++ ++typedef void (*surface_remove_notification_func)( ++ struct ivi_layout_surface *ivisurf, ++ void *userdata); ++ ++typedef void (*surface_configure_notification_func)( ++ struct ivi_layout_surface *ivisurf, ++ void *userdata); ++ ++typedef void (*ivi_controller_surface_content_callback)( ++ struct ivi_layout_surface *ivisurf, ++ int32_t content, ++ void *userdata); ++ ++/** ++ * \brief register for notification when layer is created ++ */ ++int32_t ++ivi_layout_add_notification_create_layer( ++ layer_create_notification_func callback, ++ void *userdata); ++ ++void ++ivi_layout_remove_notification_create_layer( ++ layer_create_notification_func callback, ++ void *userdata); ++ ++/** ++ * \brief register for notification when layer is removed ++ */ ++int32_t ++ivi_layout_add_notification_remove_layer( ++ layer_remove_notification_func callback, ++ void *userdata); ++ ++void ++ivi_layout_remove_notification_remove_layer( ++ layer_remove_notification_func callback, ++ void *userdata); ++ ++/** ++ * \brief register for notification when surface is created ++ */ ++int32_t ++ivi_layout_add_notification_create_surface( ++ surface_create_notification_func callback, ++ void *userdata); ++ ++void ++ivi_layout_remove_notification_create_surface( ++ surface_create_notification_func callback, ++ void *userdata); ++ ++/** ++ * \brief register for notification when surface is removed ++ */ ++int32_t ++ivi_layout_add_notification_remove_surface( ++ surface_remove_notification_func callback, ++ void *userdata); ++ ++void ++ivi_layout_remove_notification_remove_surface( ++ surface_remove_notification_func callback, ++ void *userdata); ++ ++/** ++ * \brief register for notification when surface is configured ++ */ ++int32_t ++ivi_layout_add_notification_configure_surface( ++ surface_configure_notification_func callback, ++ void *userdata); ++ ++void ++ivi_layout_remove_notification_configure_surface( ++ surface_configure_notification_func callback, ++ void *userdata); ++ ++/** ++ * \brief get id of surface from ivi_layout_surface ++ * ++ * \return id of surface ++ */ ++uint32_t ++ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf); ++ ++/** ++ * \brief get id of layer from ivi_layout_layer ++ * ++ * ++ * \return id of layer ++ */ ++uint32_t ++ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer); ++ ++/** ++ * \brief get ivi_layout_surface from id of surface ++ * ++ * \return (struct ivi_layout_surface *) ++ * if the method call was successful ++ * \return NULL if the method call was failed ++ */ ++struct ivi_layout_surface * ++ivi_layout_get_surface_from_id(uint32_t id_surface); ++ ++/** ++ * \brief get ivi_layout_screen from id of screen ++ * ++ * \return (struct ivi_layout_screen *) ++ * if the method call was successful ++ * \return NULL if the method call was failed ++ */ ++struct ivi_layout_screen * ++ivi_layout_get_screen_from_id(uint32_t id_screen); ++ ++/** ++ * \brief Get the screen resolution of a specific screen ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_get_screen_resolution(struct ivi_layout_screen *iviscrn, ++ int32_t *pWidth, ++ int32_t *pHeight); ++ ++/** ++ * \brief Set an observer callback for surface content status change. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_surface_set_content_observer( ++ struct ivi_layout_surface *ivisurf, ++ ivi_controller_surface_content_callback callback, ++ void* userdata); ++ ++/** ++ * \brief Get the layer properties ++ * ++ * \return (const struct ivi_layout_layer_properties *) ++ * if the method call was successful ++ * \return NULL if the method call was failed ++ */ ++const struct ivi_layout_layer_properties * ++ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer); ++ ++/** ++ * \brief Get the screens ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_get_screens(int32_t *pLength, struct ivi_layout_screen ***ppArray); ++ ++/** ++ * \brief Get the screens under the given layer ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer, ++ int32_t *pLength, ++ struct ivi_layout_screen ***ppArray); ++ ++/** ++ * \brief Get all Layers which are currently registered and managed ++ * by the services ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray); ++ ++/** ++ * \brief Get all Layers under the given surface ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf, ++ int32_t *pLength, ++ struct ivi_layout_layer ***ppArray); ++ ++/** ++ * \brief Get all Surfaces which are currently registered and managed ++ * by the services ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray); ++ ++/** ++ * \brief Create a layer which should be managed by the service ++ * ++ * \return (struct ivi_layout_layer *) ++ * if the method call was successful ++ * \return NULL if the method call was failed ++ */ ++struct ivi_layout_layer * ++ivi_layout_layer_create_with_dimension(uint32_t id_layer, ++ int32_t width, int32_t height); ++ ++/** ++ * \brief Removes a layer which is currently managed by the service ++ */ ++void ++ivi_layout_layer_remove(struct ivi_layout_layer *ivilayer); ++ ++/** ++ * \brief Set the visibility of a layer. If a layer is not visible, the ++ * layer and its surfaces will not be rendered. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer, ++ bool newVisibility); ++ ++/** ++ * \brief Set the opacity of a layer. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer, ++ wl_fixed_t opacity); ++ ++/** ++ * \brief Get the opacity of a layer. ++ * ++ * \return opacity if the method call was successful ++ * \return wl_fixed_from_double(0.0) if the method call was failed ++ */ ++wl_fixed_t ++ivi_layout_layer_get_opacity(struct ivi_layout_layer *ivilayer); ++ ++/** ++ * \brief Set the area of a layer which should be used for the rendering. ++ * ++ * Only this part will be visible. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer, ++ int32_t x, int32_t y, ++ int32_t width, int32_t height); ++ ++/** ++ * \brief Set the destination area on the display for a layer. ++ * ++ * The layer will be scaled and positioned to this rectangle ++ * for rendering ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer, ++ int32_t x, int32_t y, ++ int32_t width, int32_t height); ++ ++/** ++ * \brief Get the horizontal and vertical position of the layer. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_layer_get_position(struct ivi_layout_layer *ivilayer, ++ int32_t *dest_x, int32_t *dest_y); ++ ++/** ++ * \brief Sets the horizontal and vertical position of the layer. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer, ++ int32_t dest_x, int32_t dest_y); ++ ++/** ++ * \brief Sets the orientation of a layer. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_layer_set_orientation(struct ivi_layout_layer *ivilayer, ++ enum wl_output_transform orientation); ++ ++/** ++ * \brief Sets render order of surfaces within one layer ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface **pSurface, ++ int32_t number); ++ ++/** ++ * \brief Set the visibility of a surface. ++ * ++ * If a surface is not visible it will not be rendered. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf, ++ bool newVisibility); ++ ++/** ++ * \brief Get the visibility of a surface. ++ * ++ * If a surface is not visible it will not be rendered. ++ * ++ * \return true if surface is visible ++ * \return false if surface is invisible or the method call was failed ++ */ ++bool ++ivi_layout_surface_get_visibility(struct ivi_layout_surface *ivisurf); ++ ++/** ++ * \brief Set the opacity of a surface. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf, ++ wl_fixed_t opacity); ++ ++/** ++ * \brief Get the opacity of a surface. ++ * ++ * \return opacity if the method call was successful ++ * \return wl_fixed_from_double(0.0) if the method call was failed ++ */ ++wl_fixed_t ++ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf); ++ ++/** ++ * \brief Set the destination area of a surface within a layer for rendering. ++ * ++ * The surface will be scaled to this rectangle for rendering. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf, ++ int32_t x, int32_t y, ++ int32_t width, int32_t height); ++ ++/** ++ * \brief Sets the orientation of a surface. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf, ++ enum wl_output_transform orientation); ++ ++/** ++ * \brief Add a layer to a screen which is currently managed by the service ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn, ++ struct ivi_layout_layer *addlayer); ++ ++/** ++ * \brief Sets render order of layers on a display ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn, ++ struct ivi_layout_layer **pLayer, ++ const int32_t number); ++ ++/** ++ * \brief register for notification on property changes of layer ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_layer_add_notification(struct ivi_layout_layer *ivilayer, ++ layer_property_notification_func callback, ++ void *userdata); ++ ++/** ++ * \brief remove notification on property changes of layer ++ */ ++void ++ivi_layout_layer_remove_notification(struct ivi_layout_layer *ivilayer); ++ ++/** ++ * \brief register for notification on property changes of surface ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_surface_add_notification(struct ivi_layout_surface *ivisurf, ++ surface_property_notification_func callback, ++ void *userdata); ++ ++/** ++ * \brief remove notification on property changes of surface ++ */ ++void ++ivi_layout_surface_remove_notification(struct ivi_layout_surface *ivisurf); ++ ++/** ++ * \brief Get the surface properties ++ * ++ * \return (const struct ivi_surface_layer_properties *) ++ * if the method call was successful ++ * \return NULL if the method call was failed ++ */ ++const struct ivi_layout_surface_properties * ++ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf); ++ ++/** ++ * \brief Add a surface to a layer which is currently managed by the service ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface *addsurf); ++ ++/** ++ * \brief Removes a surface from a layer which is currently managed by the service ++ */ ++void ++ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface *remsurf); ++ ++/** ++ * \brief Set the area of a surface which should be used for the rendering. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf, ++ int32_t x, int32_t y, ++ int32_t width, int32_t height); ++ ++/** ++ * \brief get weston_output from ivi_layout_screen. ++ * ++ * \return (struct weston_output *) ++ * if the method call was successful ++ * \return NULL if the method call was failed ++ */ ++struct weston_output * ++ivi_layout_screen_get_output(struct ivi_layout_screen *); ++ ++struct weston_surface * ++ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf); ++ ++int32_t ++ivi_layout_surface_get_size(struct ivi_layout_surface *ivisurf, ++ int32_t *width, ++ int32_t *height, ++ int32_t *stride); ++ ++int32_t ++ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer, ++ enum ivi_layout_transition_type type, ++ uint32_t duration); ++ ++int32_t ++ivi_layout_layer_set_fade_info(struct ivi_layout_layer* layer, ++ uint32_t is_fade_in, ++ double start_alpha, double end_alpha); ++ ++int32_t ++ivi_layout_surface_set_transition(struct ivi_layout_surface *ivisurf, ++ enum ivi_layout_transition_type type, ++ uint32_t duration); ++ ++void ++ivi_layout_transition_layer_render_order(struct ivi_layout_layer* layer, ++ struct ivi_layout_surface** new_order, ++ uint32_t surface_num, ++ uint32_t duration); ++ ++void ++ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer* layer); ++ ++/** ++ * \brief Commit all changes and execute all enqueued commands since ++ * last commit. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_commit_changes(void); ++ ++#ifdef __cplusplus ++} ++#endif /* __cplusplus */ ++ ++#endif /* _IVI_LAYOUT_EXPORT_H_ */ +diff --git a/ivi-shell/ivi-layout-private.h b/ivi-shell/ivi-layout-private.h +new file mode 100644 +index 0000000..8287e93 +--- /dev/null ++++ b/ivi-shell/ivi-layout-private.h +@@ -0,0 +1,319 @@ ++/* ++ * Copyright (C) 2014 DENSO CORPORATION ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and ++ * its documentation for any purpose is hereby granted without fee, provided ++ * that the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of the copyright holders not be used in ++ * advertising or publicity pertaining to distribution of the software ++ * without specific, written prior permission. The copyright holders make ++ * no representations about the suitability of this software for any ++ * purpose. It is provided "as is" without express or implied warranty. ++ * ++ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS ++ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND ++ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY ++ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ++ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF ++ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#ifndef _ivi_layout_PRIVATE_H_ ++#define _ivi_layout_PRIVATE_H_ ++ ++#include "compositor.h" ++#include "ivi-layout-export.h" ++ ++struct ivi_layout_surface { ++ struct wl_list link; ++ struct wl_signal property_changed; ++ struct wl_list layer_list; ++ int32_t update_count; ++ uint32_t id_surface; ++ ++ struct ivi_layout *layout; ++ struct weston_surface *surface; ++ ++ struct wl_listener surface_destroy_listener; ++ struct weston_transform surface_rotation; ++ struct weston_transform layer_rotation; ++ struct weston_transform surface_pos; ++ struct weston_transform layer_pos; ++ struct weston_transform scaling; ++ ++ struct ivi_layout_surface_properties prop; ++ uint32_t event_mask; ++ ++ struct { ++ struct ivi_layout_surface_properties prop; ++ struct wl_list link; ++ } pending; ++ ++ struct { ++ struct wl_list link; ++ struct wl_list layer_list; ++ } order; ++ ++ struct { ++ ivi_controller_surface_content_callback callback; ++ void *userdata; ++ } content_observer; ++ ++ struct wl_signal configured; ++}; ++ ++struct ivi_layout_layer { ++ struct wl_list link; ++ struct wl_signal property_changed; ++ struct wl_list screen_list; ++ struct wl_list link_to_surface; ++ uint32_t id_layer; ++ ++ struct ivi_layout *layout; ++ ++ struct ivi_layout_layer_properties prop; ++ uint32_t event_mask; ++ ++ struct { ++ struct ivi_layout_layer_properties prop; ++ struct wl_list surface_list; ++ struct wl_list link; ++ } pending; ++ ++ struct { ++ struct wl_list surface_list; ++ struct wl_list link; ++ } order; ++}; ++ ++struct ivi_layout { ++ struct weston_compositor *compositor; ++ ++ struct wl_list surface_list; ++ struct wl_list layer_list; ++ struct wl_list screen_list; ++ ++ struct { ++ struct wl_signal created; ++ struct wl_signal removed; ++ } layer_notification; ++ ++ struct { ++ struct wl_signal created; ++ struct wl_signal removed; ++ struct wl_signal configure_changed; ++ } surface_notification; ++ ++ struct weston_layer layout_layer; ++ struct wl_signal warning_signal; ++ ++ struct ivi_layout_transition_set *transitions; ++ struct wl_list pending_transition_list; ++}; ++ ++struct ivi_layout *get_instance(void); ++ ++struct ivi_layout_transition; ++ ++struct ivi_layout_transition_set { ++ struct wl_event_source *event_source; ++ struct wl_list transition_list; ++}; ++ ++typedef void (*ivi_layout_transition_destroy_user_func)(void *user_data); ++ ++struct ivi_layout_transition_set * ++ivi_layout_transition_set_create(struct weston_compositor *ec); ++ ++void ++ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface, ++ int32_t dest_x, int32_t dest_y, ++ int32_t dest_width, int32_t dest_height, ++ uint32_t duration); ++ ++void ++ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface, ++ uint32_t duration); ++ ++void ++ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface, ++ uint32_t duration); ++ ++ ++void ++ivi_layout_transition_move_layer(struct ivi_layout_layer *layer, ++ int32_t dest_x, int32_t dest_y, ++ uint32_t duration); ++ ++void ++ivi_layout_transition_fade_layer(struct ivi_layout_layer *layer, ++ uint32_t is_fade_in, ++ double start_alpha, double end_alpha, ++ void *user_data, ++ ivi_layout_transition_destroy_user_func destroy_func, ++ uint32_t duration); ++ ++int32_t ++is_surface_transition(struct ivi_layout_surface *surface); ++ ++/** ++ * \brief get ivi_layout_layer from id of layer ++ * ++ * \return (struct ivi_layout_layer *) ++ * if the method call was successful ++ * \return NULL if the method call was failed ++ */ ++struct ivi_layout_layer * ++ivi_layout_get_layer_from_id(uint32_t id_layer); ++ ++/** ++ * \brief Remove a surface ++ */ ++void ++ivi_layout_surface_remove(struct ivi_layout_surface *ivisurf); ++ ++/** ++ * \brief Get all Layers of the given screen ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_get_layers_on_screen(struct ivi_layout_screen *iviscrn, ++ int32_t *pLength, ++ struct ivi_layout_layer ***ppArray); ++ ++/** ++ * \brief Get all Surfaces which are currently registered to a given ++ * layer and are managed by the services ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_get_surfaces_on_layer(struct ivi_layout_layer *ivilayer, ++ int32_t *pLength, ++ struct ivi_layout_surface ***ppArray); ++ ++/** ++ * \brief Get the visibility of a layer. If a layer is not visible, ++ * the layer and its surfaces will not be rendered. ++ * ++ * \return true if layer is visible ++ * \return false if layer is invisible or the method call was failed ++ */ ++bool ++ivi_layout_layer_get_visibility(struct ivi_layout_layer *ivilayer); ++ ++/** ++ * \brief Get the horizontal and vertical dimension of the layer. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_layer_get_dimension(struct ivi_layout_layer *ivilayer, ++ int32_t *dest_width, int32_t *dest_height); ++ ++/** ++ * \brief Set the horizontal and vertical dimension of the layer. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_layer_set_dimension(struct ivi_layout_layer *ivilayer, ++ int32_t dest_width, int32_t dest_height); ++ ++/** ++ * \brief Gets the orientation of a layer. ++ * ++ * \return (enum wl_output_transform) ++ * if the method call was successful ++ * \return WL_OUTPUT_TRANSFORM_NORMAL if the method call was failed ++ */ ++enum wl_output_transform ++ivi_layout_layer_get_orientation(struct ivi_layout_layer *ivilayer); ++ ++/** ++ * \brief Set the horizontal and vertical dimension of the surface. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_surface_set_dimension(struct ivi_layout_surface *ivisurf, ++ int32_t dest_width, int32_t dest_height); ++ ++/** ++ * \brief Get the horizontal and vertical dimension of the surface. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_surface_get_dimension(struct ivi_layout_surface *ivisurf, ++ int32_t *dest_width, int32_t *dest_height); ++ ++/** ++ * \brief Sets the horizontal and vertical position of the surface. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_surface_set_position(struct ivi_layout_surface *ivisurf, ++ int32_t dest_x, int32_t dest_y); ++ ++/** ++ * \brief Get the horizontal and vertical position of the surface. ++ * ++ * \return IVI_SUCCEEDED if the method call was successful ++ * \return IVI_FAILED if the method call was failed ++ */ ++int32_t ++ivi_layout_surface_get_position(struct ivi_layout_surface *ivisurf, ++ int32_t *dest_x, int32_t *dest_y); ++ ++/** ++ * \brief Gets the orientation of a surface. ++ * ++ * \return (enum wl_output_transform) ++ * if the method call was successful ++ * \return WL_OUTPUT_TRANSFORM_NORMAL if the method call was failed ++ */ ++enum wl_output_transform ++ivi_layout_surface_get_orientation(struct ivi_layout_surface *ivisurf); ++ ++int32_t ++ivi_layout_surface_set_transition_duration( ++ struct ivi_layout_surface *ivisurf, ++ uint32_t duration); ++ ++struct ivi_layout_interface { ++ struct weston_view *(*get_weston_view)( ++ struct ivi_layout_surface *surface); ++ ++ void (*surface_configure)(struct ivi_layout_surface *ivisurf, ++ int32_t width, ++ int32_t height); ++ ++ struct ivi_layout_surface *(*surface_create)( ++ struct weston_surface *wl_surface, ++ uint32_t id_surface); ++ ++ void (*init_with_compositor)(struct weston_compositor *ec); ++ ++ int32_t (*get_surface_dimension)( ++ struct ivi_layout_surface *ivisurf, ++ int32_t *dest_width, ++ int32_t *dest_height); ++ ++ void (*add_surface_configured_listener)( ++ struct ivi_layout_surface *ivisurf, ++ struct wl_listener* listener); ++}; ++ ++#endif +diff --git a/ivi-shell/ivi-layout-transition.c b/ivi-shell/ivi-layout-transition.c +new file mode 100644 +index 0000000..0c45c4a +--- /dev/null ++++ b/ivi-shell/ivi-layout-transition.c +@@ -0,0 +1,1111 @@ ++/* ++ * Copyright (C) 2014 DENSO CORPORATION ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and ++ * its documentation for any purpose is hereby granted without fee, provided ++ * that the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of the copyright holders not be used in ++ * advertising or publicity pertaining to distribution of the software ++ * without specific, written prior permission. The copyright holders make ++ * no representations about the suitability of this software for any ++ * purpose. It is provided "as is" without express or implied warranty. ++ * ++ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS ++ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND ++ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY ++ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ++ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF ++ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include <time.h> ++#include <assert.h> ++#include <stdlib.h> ++#include <stdio.h> ++ ++#include "ivi-layout-export.h" ++#include "ivi-layout-private.h" ++ ++struct ivi_layout_transition; ++ ++typedef void (*ivi_layout_transition_frame_func)( ++ struct ivi_layout_transition *transition); ++typedef void (*ivi_layout_transition_destroy_func)( ++ struct ivi_layout_transition *transition); ++typedef int32_t (*ivi_layout_is_transition_func)(void *private_data, void *id); ++ ++struct ivi_layout_transition { ++ enum ivi_layout_transition_type type; ++ void *private_data; ++ void *user_data; ++ ++ uint32_t time_start; ++ uint32_t time_duration; ++ uint32_t time_elapsed; ++ uint32_t is_done; ++ ivi_layout_is_transition_func is_transition_func; ++ ivi_layout_transition_frame_func frame_func; ++ ivi_layout_transition_destroy_func destroy_func; ++}; ++ ++struct transition_node { ++ struct ivi_layout_transition *transition; ++ struct wl_list link; ++}; ++ ++static void layout_transition_destroy(struct ivi_layout_transition *transition); ++ ++static struct ivi_layout_transition * ++get_transition_from_type_and_id(enum ivi_layout_transition_type type, ++ void *id_data) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct transition_node *node; ++ struct ivi_layout_transition *tran; ++ ++ wl_list_for_each(node, &layout->transitions->transition_list, link) { ++ tran = node->transition; ++ ++ if (tran->type == type && ++ tran->is_transition_func(tran->private_data, id_data)) ++ return tran; ++ } ++ ++ return NULL; ++} ++ ++WL_EXPORT int32_t ++is_surface_transition(struct ivi_layout_surface *surface) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct transition_node *node; ++ struct ivi_layout_transition *tran; ++ ++ wl_list_for_each(node, &layout->transitions->transition_list, link) { ++ tran = node->transition; ++ ++ if ((tran->type == IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE || ++ tran->type == IVI_LAYOUT_TRANSITION_VIEW_RESIZE) && ++ tran->is_transition_func(tran->private_data, surface)) ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static void ++tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp) ++{ ++ const double t = timestamp - transition->time_start; ++ ++ if (transition->time_duration <= t) { ++ transition->time_elapsed = transition->time_duration; ++ transition->is_done = 1; ++ } else { ++ transition->time_elapsed = t; ++ } ++} ++ ++static float time_to_nowpos(struct ivi_layout_transition *transition) ++{ ++ return sin((float)transition->time_elapsed / ++ (float)transition->time_duration * M_PI_2); ++} ++ ++static void ++do_transition_frame(struct ivi_layout_transition *transition, ++ uint32_t timestamp) ++{ ++ if (0 == transition->time_start) ++ transition->time_start = timestamp; ++ ++ tick_transition(transition, timestamp); ++ transition->frame_func(transition); ++ ++ if (transition->is_done) ++ layout_transition_destroy(transition); ++} ++ ++static int32_t ++layout_transition_frame(void *data) ++{ ++ struct ivi_layout_transition_set *transitions = data; ++ uint32_t fps = 30; ++ struct timespec timestamp = {}; ++ uint32_t msec = 0; ++ struct transition_node *node = NULL; ++ struct transition_node *next = NULL; ++ ++ if (wl_list_empty(&transitions->transition_list)) { ++ wl_event_source_timer_update(transitions->event_source, 0); ++ return 1; ++ } ++ ++ wl_event_source_timer_update(transitions->event_source, 1000 / fps); ++ ++ clock_gettime(CLOCK_MONOTONIC, ×tamp);//FIXME; ++ msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec); ++ ++ wl_list_for_each_safe(node, next, &transitions->transition_list, link) { ++ do_transition_frame(node->transition, msec); ++ } ++ ++ ivi_layout_commit_changes(); ++ return 1; ++} ++ ++WL_EXPORT struct ivi_layout_transition_set * ++ivi_layout_transition_set_create(struct weston_compositor *ec) ++{ ++ struct ivi_layout_transition_set *transitions; ++ struct wl_event_loop *loop; ++ ++ transitions = malloc(sizeof(*transitions)); ++ if (transitions == NULL) { ++ weston_log("%s: memory allocation fails\n", __func__); ++ return NULL; ++ } ++ ++ wl_list_init(&transitions->transition_list); ++ ++ loop = wl_display_get_event_loop(ec->wl_display); ++ transitions->event_source = ++ wl_event_loop_add_timer(loop, layout_transition_frame, ++ transitions); ++ ++ return transitions; ++} ++ ++static void ++layout_transition_register(struct ivi_layout_transition *trans) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct transition_node *node; ++ ++ node = malloc(sizeof(*node)); ++ if (node == NULL) { ++ weston_log("%s: memory allocation fails\n", __func__); ++ return; ++ } ++ ++ node->transition = trans; ++ wl_list_insert(&layout->pending_transition_list, &node->link); ++} ++ ++static void ++remove_transition(struct ivi_layout *layout, ++ struct ivi_layout_transition *trans) ++{ ++ struct transition_node *node; ++ struct transition_node *next; ++ ++ wl_list_for_each_safe(node, next, ++ &layout->transitions->transition_list, link) { ++ if (node->transition == trans) { ++ wl_list_remove(&node->link); ++ free(node); ++ return; ++ } ++ } ++ ++ wl_list_for_each_safe(node, next, ++ &layout->pending_transition_list, link) { ++ if (node->transition == trans) { ++ wl_list_remove(&node->link); ++ free(node); ++ return; ++ } ++ } ++} ++ ++static void ++layout_transition_destroy(struct ivi_layout_transition *transition) ++{ ++ struct ivi_layout *layout = get_instance(); ++ ++ remove_transition(layout, transition); ++ if(transition->destroy_func) ++ transition->destroy_func(transition); ++ free(transition); ++} ++ ++static struct ivi_layout_transition * ++create_layout_transition(void) ++{ ++ struct ivi_layout_transition *transition = malloc(sizeof(*transition)); ++ ++ if (transition == NULL) { ++ weston_log("%s: memory allocation fails\n", __func__); ++ return NULL; ++ } ++ ++ transition->type = IVI_LAYOUT_TRANSITION_MAX; ++ transition->time_start = 0; ++ transition->time_duration = 300; /* 300ms */ ++ transition->time_elapsed = 0; ++ ++ transition->is_done = 0; ++ ++ transition->private_data = NULL; ++ transition->user_data = NULL; ++ ++ transition->frame_func = NULL; ++ transition->destroy_func = NULL; ++ ++ return transition; ++} ++ ++/* move and resize view transition */ ++ ++struct move_resize_view_data { ++ struct ivi_layout_surface *surface; ++ int32_t start_x; ++ int32_t start_y; ++ int32_t end_x; ++ int32_t end_y; ++ int32_t start_width; ++ int32_t start_height; ++ int32_t end_width; ++ int32_t end_height; ++}; ++ ++static void ++transition_move_resize_view_destroy(struct ivi_layout_transition *transition) ++{ ++ struct move_resize_view_data *data = ++ (struct move_resize_view_data *)transition->private_data; ++ struct ivi_layout_surface *layout_surface = data->surface; ++ ++ wl_signal_emit(&layout_surface->configured, layout_surface); ++ ++ if (transition->private_data) { ++ free(transition->private_data); ++ transition->private_data = NULL; ++ } ++} ++ ++static void ++transition_move_resize_view_user_frame(struct ivi_layout_transition *transition) ++{ ++ struct move_resize_view_data *mrv = transition->private_data; ++ const double current = time_to_nowpos(transition); ++ ++ const int32_t destx = mrv->start_x + ++ (mrv->end_x - mrv->start_x) * current; ++ ++ const int32_t desty = mrv->start_y + ++ (mrv->end_y - mrv->start_y) * current; ++ ++ const int32_t dest_width = mrv->start_width + ++ (mrv->end_width - mrv->start_width) * current; ++ ++ const int32_t dest_height = mrv->start_height + ++ (mrv->end_height - mrv->start_height) * current; ++ ++ ivi_layout_surface_set_destination_rectangle(mrv->surface, ++ destx, desty, ++ dest_width, dest_height); ++} ++ ++static int32_t ++is_transition_move_resize_view_func(struct move_resize_view_data *data, ++ struct ivi_layout_surface *view) ++{ ++ return data->surface == view; ++} ++ ++static struct ivi_layout_transition * ++create_move_resize_view_transition( ++ struct ivi_layout_surface *surface, ++ int32_t start_x, int32_t start_y, ++ int32_t end_x, int32_t end_y, ++ int32_t start_width, int32_t start_height, ++ int32_t end_width, int32_t end_height, ++ ivi_layout_transition_frame_func frame_func, ++ ivi_layout_transition_destroy_func destroy_func, ++ uint32_t duration) ++{ ++ struct ivi_layout_transition *transition = create_layout_transition(); ++ struct move_resize_view_data *data = malloc(sizeof(*data)); ++ ++ if (data == NULL) { ++ weston_log("%s: memory allocation fails\n", __func__); ++ return NULL; ++ } ++ ++ transition->type = IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE; ++ transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_resize_view_func; ++ ++ transition->frame_func = frame_func; ++ transition->destroy_func = destroy_func; ++ transition->private_data = data; ++ ++ if (duration != 0) ++ transition->time_duration = duration; ++ ++ data->surface = surface; ++ data->start_x = start_x; ++ data->start_y = start_y; ++ data->end_x = end_x; ++ data->end_y = end_y; ++ ++ data->start_width = start_width; ++ data->start_height = start_height; ++ data->end_width = end_width; ++ data->end_height = end_height; ++ ++ return transition; ++} ++ ++WL_EXPORT void ++ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface, ++ int32_t dest_x, int32_t dest_y, ++ int32_t dest_width, int32_t dest_height, ++ uint32_t duration) ++{ ++ struct ivi_layout_transition *transition; ++ int32_t start_pos[2] = { ++ surface->pending.prop.start_x, ++ surface->pending.prop.start_y ++ }; ++ ++ int32_t start_size[2] = { ++ surface->pending.prop.start_width, ++ surface->pending.prop.start_height ++ }; ++ ++ transition = get_transition_from_type_and_id( ++ IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE, ++ surface); ++ if (transition) { ++ struct move_resize_view_data *data = transition->private_data; ++ transition->time_start = 0; ++ transition->time_duration = duration; ++ ++ data->start_x = start_pos[0]; ++ data->start_y = start_pos[1]; ++ data->end_x = dest_x; ++ data->end_y = dest_y; ++ ++ data->start_width = start_size[0]; ++ data->start_height = start_size[1]; ++ data->end_width = dest_width; ++ data->end_height = dest_height; ++ return; ++ } ++ ++ transition = create_move_resize_view_transition( ++ surface, ++ start_pos[0], start_pos[1], ++ dest_x, dest_y, ++ start_size[0], start_size[1], ++ dest_width, dest_height, ++ transition_move_resize_view_user_frame, ++ transition_move_resize_view_destroy, ++ duration); ++ ++ layout_transition_register(transition); ++} ++ ++/* fade transition */ ++struct fade_view_data { ++ struct ivi_layout_surface *surface; ++ double start_alpha; ++ double end_alpha; ++}; ++ ++struct store_alpha{ ++ double alpha; ++}; ++ ++static void ++fade_view_user_frame(struct ivi_layout_transition *transition) ++{ ++ struct fade_view_data *fade = transition->private_data; ++ struct ivi_layout_surface *surface = fade->surface; ++ ++ const double current = time_to_nowpos(transition); ++ const double alpha = fade->start_alpha + ++ (fade->end_alpha - fade->start_alpha) * current; ++ ++ ivi_layout_surface_set_opacity(surface, wl_fixed_from_double(alpha)); ++ ivi_layout_surface_set_visibility(surface, true); ++} ++ ++static int32_t ++is_transition_fade_view_func(struct fade_view_data *data, ++ struct ivi_layout_surface *view) ++{ ++ return data->surface == view; ++} ++ ++static struct ivi_layout_transition * ++create_fade_view_transition( ++ struct ivi_layout_surface *surface, ++ double start_alpha, double end_alpha, ++ ivi_layout_transition_frame_func frame_func, ++ void *user_data, ++ ivi_layout_transition_destroy_func destroy_func, ++ uint32_t duration) ++{ ++ struct ivi_layout_transition *transition = create_layout_transition(); ++ struct fade_view_data *data = malloc(sizeof(*data)); ++ ++ if (data == NULL) { ++ weston_log("%s: memory allocation fails\n", __func__); ++ return NULL; ++ } ++ ++ transition->type = IVI_LAYOUT_TRANSITION_VIEW_FADE; ++ transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_view_func; ++ ++ transition->user_data = user_data; ++ transition->private_data = data; ++ transition->frame_func = frame_func; ++ transition->destroy_func = destroy_func; ++ ++ if (duration != 0) ++ transition->time_duration = duration; ++ ++ data->surface = surface; ++ data->start_alpha = start_alpha; ++ data->end_alpha = end_alpha; ++ ++ return transition; ++} ++ ++static void ++create_visibility_transition(struct ivi_layout_surface *surface, ++ double start_alpha, ++ double dest_alpha, ++ void *user_data, ++ ivi_layout_transition_destroy_func destroy_func, ++ uint32_t duration) ++{ ++ struct ivi_layout_transition *transition = NULL; ++ ++ transition = create_fade_view_transition( ++ surface, ++ start_alpha, dest_alpha, ++ fade_view_user_frame, ++ user_data, ++ destroy_func, ++ duration); ++ ++ layout_transition_register(transition); ++} ++ ++static void ++visibility_on_transition_destroy(struct ivi_layout_transition *transition) ++{ ++ struct fade_view_data *data = transition->private_data; ++ struct store_alpha *user_data = transition->user_data; ++ ++ ivi_layout_surface_set_visibility(data->surface, true); ++ ++ free(data); ++ transition->private_data = NULL; ++ ++ free(user_data); ++ transition->user_data = NULL; ++} ++ ++WL_EXPORT void ++ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface, ++ uint32_t duration) ++{ ++ struct ivi_layout_transition *transition; ++ bool is_visible = ivi_layout_surface_get_visibility(surface); ++ wl_fixed_t dest_alpha = ivi_layout_surface_get_opacity(surface); ++ struct store_alpha *user_data = NULL; ++ wl_fixed_t start_alpha = 0.0; ++ struct fade_view_data *data = NULL; ++ ++ transition = get_transition_from_type_and_id( ++ IVI_LAYOUT_TRANSITION_VIEW_FADE, ++ surface); ++ if (transition) { ++ start_alpha = ivi_layout_surface_get_opacity(surface); ++ user_data = transition->user_data; ++ data = transition->private_data; ++ ++ transition->time_start = 0; ++ transition->time_duration = duration; ++ transition->destroy_func = visibility_on_transition_destroy; ++ ++ data->start_alpha = wl_fixed_to_double(start_alpha); ++ data->end_alpha = user_data->alpha; ++ return; ++ } ++ ++ if (is_visible) ++ return; ++ ++ user_data = malloc(sizeof(*user_data)); ++ if (user_data == NULL) { ++ weston_log("%s: memory allocation fails\n", __func__); ++ return; ++ } ++ ++ user_data->alpha = wl_fixed_to_double(dest_alpha); ++ ++ create_visibility_transition(surface, ++ 0.0, // start_alpha ++ wl_fixed_to_double(dest_alpha), ++ user_data, ++ visibility_on_transition_destroy, ++ duration); ++} ++ ++static void ++visibility_off_transition_destroy(struct ivi_layout_transition *transition) ++{ ++ struct fade_view_data *data = transition->private_data; ++ struct store_alpha *user_data = transition->user_data; ++ ++ ivi_layout_surface_set_visibility(data->surface, false); ++ ++ ivi_layout_surface_set_opacity(data->surface, ++ wl_fixed_from_double(user_data->alpha)); ++ ++ free(data); ++ transition->private_data = NULL; ++ ++ free(user_data); ++ transition->user_data= NULL; ++} ++ ++WL_EXPORT void ++ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface, ++ uint32_t duration) ++{ ++ struct ivi_layout_transition *transition; ++ wl_fixed_t start_alpha = ivi_layout_surface_get_opacity(surface); ++ struct store_alpha* user_data = NULL; ++ struct fade_view_data* data = NULL; ++ ++ transition = ++ get_transition_from_type_and_id(IVI_LAYOUT_TRANSITION_VIEW_FADE, ++ surface); ++ if (transition) { ++ data = transition->private_data; ++ ++ transition->time_start = 0; ++ transition->time_duration = duration; ++ transition->destroy_func = visibility_off_transition_destroy; ++ ++ data->start_alpha = wl_fixed_to_double(start_alpha); ++ data->end_alpha = 0; ++ return; ++ } ++ ++ user_data = malloc(sizeof(*user_data)); ++ if (user_data == NULL) { ++ weston_log("%s: memory allocation fails\n", __func__); ++ return; ++ } ++ ++ user_data->alpha = wl_fixed_to_double(start_alpha); ++ ++ create_visibility_transition(surface, ++ wl_fixed_to_double(start_alpha), ++ 0.0, // dest_alpha ++ user_data, ++ visibility_off_transition_destroy, ++ duration); ++} ++ ++/* move layer transition */ ++ ++struct move_layer_data { ++ struct ivi_layout_layer *layer; ++ int32_t start_x; ++ int32_t start_y; ++ int32_t end_x; ++ int32_t end_y; ++ ivi_layout_transition_destroy_user_func destroy_func; ++}; ++ ++static void ++transition_move_layer_user_frame(struct ivi_layout_transition *transition) ++{ ++ struct move_layer_data *data = transition->private_data; ++ struct ivi_layout_layer *layer = data->layer; ++ ++ const float current = time_to_nowpos(transition); ++ ++ const int32_t dest_x = data->start_x + ++ (data->end_x - data->start_x) * current; ++ ++ const int32_t dest_y = data->start_y + ++ (data->end_y - data->start_y) * current; ++ ++ ivi_layout_layer_set_position(layer, dest_x, dest_y); ++} ++ ++static void ++transition_move_layer_destroy(struct ivi_layout_transition *transition) ++{ ++ struct move_layer_data *data = transition->private_data; ++ ++ if(data->destroy_func) ++ data->destroy_func(transition->user_data); ++ ++ free(data); ++ transition->private_data = NULL; ++} ++ ++static int32_t ++is_transition_move_layer_func(struct move_layer_data *data, ++ struct ivi_layout_layer *layer) ++{ ++ return data->layer == layer; ++} ++ ++ ++static struct ivi_layout_transition * ++create_move_layer_transition( ++ struct ivi_layout_layer *layer, ++ int32_t start_x, int32_t start_y, ++ int32_t end_x, int32_t end_y, ++ void *user_data, ++ ivi_layout_transition_destroy_user_func destroy_user_func, ++ uint32_t duration) ++{ ++ struct ivi_layout_transition *transition = create_layout_transition(); ++ struct move_layer_data *data = malloc(sizeof(*data)); ++ ++ if (data == NULL) { ++ weston_log("%s: memory allocation fails\n", __func__); ++ return NULL; ++ } ++ ++ transition->type = IVI_LAYOUT_TRANSITION_LAYER_MOVE; ++ transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_layer_func; ++ ++ transition->frame_func = transition_move_layer_user_frame; ++ transition->destroy_func = transition_move_layer_destroy; ++ transition->private_data = data; ++ transition->user_data = user_data; ++ ++ if (duration != 0) ++ transition->time_duration = duration; ++ ++ data->layer = layer; ++ data->start_x = start_x; ++ data->start_y = start_y; ++ data->end_x = end_x; ++ data->end_y = end_y; ++ data->destroy_func = destroy_user_func; ++ ++ return transition; ++} ++ ++WL_EXPORT void ++ivi_layout_transition_move_layer(struct ivi_layout_layer *layer, ++ int32_t dest_x, int32_t dest_y, ++ uint32_t duration) ++{ ++ int32_t start_pos_x = 0; ++ int32_t start_pos_y = 0; ++ struct ivi_layout_transition *transition = NULL; ++ ++ ivi_layout_layer_get_position(layer, &start_pos_x, &start_pos_y); ++ ++ transition = create_move_layer_transition( ++ layer, ++ start_pos_x, start_pos_y, ++ dest_x, dest_y, ++ NULL, NULL, ++ duration); ++ ++ layout_transition_register(transition); ++ ++ return; ++} ++ ++WL_EXPORT void ++ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer) ++{ ++ struct ivi_layout_transition *transition = ++ get_transition_from_type_and_id( ++ IVI_LAYOUT_TRANSITION_LAYER_MOVE, ++ layer); ++ if (transition) { ++ layout_transition_destroy(transition); ++ } ++} ++ ++/* fade layer transition */ ++struct fade_layer_data { ++ struct ivi_layout_layer *layer; ++ uint32_t is_fade_in; ++ double start_alpha; ++ double end_alpha; ++ ivi_layout_transition_destroy_user_func destroy_func; ++}; ++ ++static void ++transition_fade_layer_destroy(struct ivi_layout_transition *transition) ++{ ++ struct fade_layer_data *data = transition->private_data; ++ transition->private_data = NULL; ++ ++ free(data); ++} ++ ++static void ++transition_fade_layer_user_frame(struct ivi_layout_transition *transition) ++{ ++ double current = time_to_nowpos(transition); ++ struct fade_layer_data *data = transition->private_data; ++ double alpha = data->start_alpha + ++ (data->end_alpha - data->start_alpha) * current; ++ wl_fixed_t fixed_alpha = wl_fixed_from_double(alpha); ++ ++ int32_t is_done = transition->is_done; ++ bool is_visible = !is_done || data->is_fade_in; ++ ++ ivi_layout_layer_set_opacity(data->layer, fixed_alpha); ++ ivi_layout_layer_set_visibility(data->layer, is_visible); ++} ++ ++static int32_t ++is_transition_fade_layer_func(struct fade_layer_data *data, ++ struct ivi_layout_layer *layer) ++{ ++ return data->layer == layer; ++} ++ ++WL_EXPORT void ++ivi_layout_transition_fade_layer( ++ struct ivi_layout_layer *layer, ++ uint32_t is_fade_in, ++ double start_alpha, double end_alpha, ++ void* user_data, ++ ivi_layout_transition_destroy_user_func destroy_func, ++ uint32_t duration) ++{ ++ struct ivi_layout_transition *transition; ++ struct fade_layer_data *data = NULL; ++ wl_fixed_t fixed_opacity = 0.0; ++ double now_opacity = 0.0; ++ double remain = 0.0; ++ ++ transition = get_transition_from_type_and_id( ++ IVI_LAYOUT_TRANSITION_LAYER_FADE, ++ layer); ++ if (transition) { ++ /* transition update */ ++ data = transition->private_data; ++ ++ /* FIXME */ ++ fixed_opacity = ivi_layout_layer_get_opacity(layer); ++ now_opacity = wl_fixed_to_double(fixed_opacity); ++ remain = 0.0; ++ ++ data->is_fade_in = is_fade_in; ++ data->start_alpha = now_opacity; ++ data->end_alpha = end_alpha; ++ ++ remain = is_fade_in? 1.0 - now_opacity : now_opacity; ++ transition->time_start = 0; ++ transition->time_elapsed = 0; ++ transition->time_duration = duration * remain; ++ ++ return; ++ } ++ ++ transition = create_layout_transition(); ++ data = malloc(sizeof(*data)); ++ ++ if (data == NULL) { ++ weston_log("%s: memory allocation fails\n", __func__); ++ return; ++ } ++ ++ transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE; ++ transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func; ++ ++ transition->private_data = data; ++ transition->user_data = user_data; ++ ++ transition->frame_func = transition_fade_layer_user_frame; ++ transition->destroy_func = transition_fade_layer_destroy; ++ ++ if (duration != 0) ++ transition->time_duration = duration; ++ ++ data->layer = layer; ++ data->is_fade_in = is_fade_in; ++ data->start_alpha = start_alpha; ++ data->end_alpha = end_alpha; ++ data->destroy_func = destroy_func; ++ ++ layout_transition_register(transition); ++ ++ return; ++} ++ ++/* render order transition */ ++struct surface_reorder { ++ uint32_t id_surface; ++ uint32_t new_index; ++}; ++ ++struct change_order_data { ++ struct ivi_layout_layer *layer; ++ uint32_t surface_num; ++ struct surface_reorder *reorder; ++}; ++ ++struct surf_with_index { ++ uint32_t id_surface; ++ float surface_index; ++}; ++ ++static int ++cmp_order_asc(const void *lhs, const void *rhs) ++{ ++ const struct surf_with_index *l = lhs; ++ const struct surf_with_index *r = rhs; ++ ++ return l->surface_index > r->surface_index; ++} ++ ++/* ++render oerder transition ++ ++index 0 1 2 ++old surfA, surfB, surfC ++new surfB, surfC, surfA ++ (-1) (-1) (+2) ++ ++after 10% of time elapsed ++ 0.2 0.9 1.9 ++ surfA, surfB, surfC ++ ++after 50% of time elapsed ++ 0.5 1.0 1.5 ++ surfB, surfA, surfC ++*/ ++ ++static void ++transition_change_order_user_frame(struct ivi_layout_transition *transition) ++{ ++ uint32_t i, old_index; ++ double current = time_to_nowpos(transition); ++ struct change_order_data *data = transition->private_data; ++ ++ struct surf_with_index *swi = malloc(sizeof(*swi) * data->surface_num); ++ struct ivi_layout_surface **new_surface_order = NULL; ++ uint32_t surface_num = 0; ++ ++ if (swi == NULL) { ++ weston_log("%s: memory allocation fails\n", __func__); ++ return; ++ } ++ ++ for (old_index = 0; old_index < data->surface_num; old_index++) { ++ swi[old_index].id_surface = data->reorder[old_index].id_surface; ++ swi[old_index].surface_index = (float)old_index + ++ ((float)data->reorder[old_index].new_index - (float)old_index) * current; ++ } ++ ++ qsort(swi, data->surface_num, sizeof(*swi), cmp_order_asc); ++ ++ new_surface_order = ++ malloc(sizeof(*new_surface_order) * data->surface_num); ++ ++ if (new_surface_order == NULL) { ++ weston_log("%s: memory allocation fails\n", __func__); ++ return; ++ } ++ ++ for (i = 0; i < data->surface_num; i++) { ++ struct ivi_layout_surface *surf = ++ ivi_layout_get_surface_from_id(swi[i].id_surface); ++ if(surf) ++ new_surface_order[surface_num++] = surf; ++ } ++ ++ ivi_layout_layer_set_render_order(data->layer, new_surface_order, ++ surface_num); ++ ++ free(new_surface_order); ++ free(swi); ++} ++ ++static void ++transition_change_order_destroy(struct ivi_layout_transition *transition) ++{ ++ struct change_order_data *data = transition->private_data; ++ ++ free(data->reorder); ++ free(data); ++} ++ ++static int32_t find_surface(struct ivi_layout_surface **surfaces, ++ uint32_t surface_num, ++ struct ivi_layout_surface *target) ++{ ++ uint32_t i = 0; ++ ++ for(i = 0; i < surface_num; i++) { ++ if (surfaces[i] == target) ++ return i; ++ } ++ ++ return -1; ++} ++ ++static int32_t ++is_transition_change_order_func(struct change_order_data *data, ++ struct ivi_layout_layer *layer) ++{ ++ return data->layer == layer; ++} ++ ++WL_EXPORT void ++ivi_layout_transition_layer_render_order(struct ivi_layout_layer *layer, ++ struct ivi_layout_surface **new_order, ++ uint32_t surface_num, ++ uint32_t duration) ++{ ++ struct surface_reorder *reorder; ++ struct ivi_layout_surface *surf; ++ uint32_t old_index = 0; ++ struct ivi_layout_transition *transition; ++ struct change_order_data *data = NULL; ++ int32_t new_index = 0; ++ uint32_t id = 0; ++ ++ reorder = malloc(sizeof(*reorder) * surface_num); ++ if (reorder == NULL) { ++ weston_log("%s: memory allocation fails\n", __func__); ++ return; ++ } ++ ++ wl_list_for_each(surf, &layer->order.surface_list, order.link) { ++ new_index = find_surface(new_order, surface_num, surf); ++ id = ivi_layout_get_id_of_surface(surf); ++ if(new_index < 0){ ++ fprintf(stderr, "invalid render order!!!\n"); ++ return; ++ } ++ ++ reorder[old_index].id_surface = id; ++ reorder[old_index].new_index = new_index; ++ old_index++; ++ } ++ ++ transition = get_transition_from_type_and_id( ++ IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER, ++ layer); ++ if (transition) { ++ /* update transition */ ++ struct change_order_data *data = transition->private_data; ++ transition->time_start = 0; /* timer reset */ ++ ++ if (duration != 0) { ++ transition->time_duration = duration; ++ } ++ ++ free(data->reorder); ++ data->reorder = reorder; ++ return; ++ } ++ ++ transition = create_layout_transition(); ++ data = malloc(sizeof(*data)); ++ ++ if (data == NULL) { ++ weston_log("%s: memory allocation fails\n", __func__); ++ return; ++ } ++ ++ transition->type = IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER; ++ transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_change_order_func; ++ ++ transition->private_data = data; ++ transition->frame_func = transition_change_order_user_frame; ++ transition->destroy_func = transition_change_order_destroy; ++ ++ if (duration != 0) ++ transition->time_duration = duration; ++ ++ data->layer = layer; ++ data->reorder = reorder; ++ data->surface_num = old_index; ++ ++ layout_transition_register(transition); ++} ++ ++WL_EXPORT int32_t ++ivi_layout_surface_set_transition(struct ivi_layout_surface *ivisurf, ++ enum ivi_layout_transition_type type, ++ uint32_t duration) ++{ ++ struct ivi_layout_surface_properties *prop; ++ ++ if (ivisurf == NULL) { ++ weston_log("%s: invalid argument\n", __func__); ++ return -1; ++ } ++ ++ prop = &ivisurf->pending.prop; ++ prop->transition_type = type; ++ prop->transition_duration = duration; ++ return 0; ++} ++ ++int32_t ++ivi_layout_surface_set_transition_duration(struct ivi_layout_surface *ivisurf, ++ uint32_t duration) ++{ ++ struct ivi_layout_surface_properties *prop; ++ ++ if (ivisurf == NULL) { ++ weston_log("%s: invalid argument\n", __func__); ++ return -1; ++ } ++ ++ prop = &ivisurf->pending.prop; ++ prop->transition_duration = duration*10; ++ return 0; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer, ++ enum ivi_layout_transition_type type, ++ uint32_t duration) ++{ ++ if (ivilayer == NULL) { ++ weston_log("%s: invalid argument\n", __func__); ++ return -1; ++ } ++ ++ ivilayer->pending.prop.transition_type = type; ++ ivilayer->pending.prop.transition_duration = duration; ++ ++ return 0; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_layer_set_fade_info(struct ivi_layout_layer* ivilayer, ++ uint32_t is_fade_in, ++ double start_alpha, double end_alpha) ++{ ++ if (ivilayer == NULL) { ++ weston_log("%s: invalid argument\n", __func__); ++ return -1; ++ } ++ ++ ivilayer->pending.prop.is_fade_in = is_fade_in; ++ ivilayer->pending.prop.start_alpha = start_alpha; ++ ivilayer->pending.prop.end_alpha = end_alpha; ++ ++ return 0; ++} +diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c +new file mode 100644 +index 0000000..6f7c3c2 +--- /dev/null ++++ b/ivi-shell/ivi-layout.c +@@ -0,0 +1,2809 @@ ++/* ++ * Copyright (C) 2013 DENSO CORPORATION ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and ++ * its documentation for any purpose is hereby granted without fee, provided ++ * that the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of the copyright holders not be used in ++ * advertising or publicity pertaining to distribution of the software ++ * without specific, written prior permission. The copyright holders make ++ * no representations about the suitability of this software for any ++ * purpose. It is provided "as is" without express or implied warranty. ++ * ++ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS ++ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND ++ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY ++ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ++ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF ++ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++/** ++ * Implementation of ivi-layout library. The actual view on ivi_screen is ++ * not updated till calling ivi_layout_commit_changes. A overview from ++ * calling API for updating properties of ivi_surface/ivi_layer to asking ++ * compositor to compose them by using weston_compositor_schedule_repaint, ++ * 0/ initialize this library by ivi_layout_init_with_compositor ++ * with (struct weston_compositor *ec) from ivi-shell. ++ * 1/ When a API for updating properties of ivi_surface/ivi_layer, it updates ++ * pending prop of ivi_surface/ivi_layer/ivi_screen which are structure to ++ * store properties. ++ * 2/ Before calling commitChanges, in case of calling a API to get a property, ++ * return current property, not pending property. ++ * 3/ At the timing of calling ivi_layout_commitChanges, pending properties ++ * are applied to properties. ++ * ++ * *) ivi_layout_commitChanges is also called by transition animation ++ * per each frame. See ivi-layout-transition.c in details. Transition ++ * animation interpolates frames between previous properties of ivi_surface ++ * and new ones. ++ * For example, when a property of ivi_surface is changed from invisibility ++ * to visibility, it behaves like fade-in. When ivi_layout_commitChange is ++ * called during transition animation, it cancels the transition and ++ * re-start transition to new properties from current properties of final ++ * frame just before the the cancellation. ++ * ++ * 4/ According properties, set transformation by using weston_matrix and ++ * weston_view per ivi_surfaces and ivi_layers in while loop. ++ * 5/ Set damage and trigger transform by using weston_view_geometry_dirty. ++ * 6/ Notify update of properties. ++ * 7/ Trigger composition by weston_compositor_schedule_repaint. ++ * ++ */ ++ ++#include <sys/wait.h> ++#include <unistd.h> ++#include <stdlib.h> ++#include <stdio.h> ++#include <string.h> ++#include <linux/input.h> ++ ++#include "compositor.h" ++#include "ivi-layout-export.h" ++#include "ivi-layout-private.h" ++ ++struct link_layer { ++ struct ivi_layout_layer *ivilayer; ++ struct wl_list link; ++ struct wl_list link_to_layer; ++}; ++ ++struct link_screen { ++ struct ivi_layout_screen *iviscrn; ++ struct wl_list link; ++ struct wl_list link_to_screen; ++}; ++ ++struct listener_layout_notification { ++ void *userdata; ++ struct wl_listener listener; ++}; ++ ++struct ivi_layout; ++ ++struct ivi_layout_screen { ++ struct wl_list link; ++ struct wl_list link_to_layer; ++ uint32_t id_screen; ++ ++ struct ivi_layout *layout; ++ struct weston_output *output; ++ ++ uint32_t event_mask; ++ ++ struct { ++ struct wl_list layer_list; ++ struct wl_list link; ++ } pending; ++ ++ struct { ++ struct wl_list layer_list; ++ struct wl_list link; ++ } order; ++}; ++ ++struct ivi_layout_notification_callback { ++ void *callback; ++ void *data; ++}; ++ ++static struct ivi_layout ivilayout = {0}; ++ ++struct ivi_layout * ++get_instance(void) ++{ ++ return &ivilayout; ++} ++ ++/** ++ * Internal API to add/remove a link to ivi_surface from ivi_layer. ++ */ ++static void ++add_link_to_surface(struct ivi_layout_layer *ivilayer, ++ struct link_layer *link_layer) ++{ ++ struct link_layer *link = NULL; ++ ++ wl_list_for_each(link, &ivilayer->link_to_surface, link_to_layer) { ++ if (link == link_layer) ++ return; ++ } ++ ++ wl_list_insert(&ivilayer->link_to_surface, &link_layer->link_to_layer); ++} ++ ++static void ++remove_link_to_surface(struct ivi_layout_layer *ivilayer) ++{ ++ struct link_layer *link = NULL; ++ struct link_layer *next = NULL; ++ ++ wl_list_for_each_safe(link, next, &ivilayer->link_to_surface, link_to_layer) { ++ if (!wl_list_empty(&link->link_to_layer)) { ++ wl_list_remove(&link->link_to_layer); ++ } ++ if (!wl_list_empty(&link->link)) { ++ wl_list_remove(&link->link); ++ } ++ free(link); ++ } ++ ++ wl_list_init(&ivilayer->link_to_surface); ++} ++ ++/** ++ * Internal API to add a link to ivi_layer from ivi_screen. ++ */ ++static void ++add_link_to_layer(struct ivi_layout_screen *iviscrn, ++ struct link_screen *link_screen) ++{ ++ wl_list_init(&link_screen->link_to_screen); ++ wl_list_insert(&iviscrn->link_to_layer, &link_screen->link_to_screen); ++} ++ ++/** ++ * Internal API to add/remove a ivi_surface from ivi_layer. ++ */ ++static void ++add_ordersurface_to_layer(struct ivi_layout_surface *ivisurf, ++ struct ivi_layout_layer *ivilayer) ++{ ++ struct link_layer *link_layer = NULL; ++ ++ link_layer = malloc(sizeof *link_layer); ++ if (link_layer == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return; ++ } ++ ++ link_layer->ivilayer = ivilayer; ++ wl_list_init(&link_layer->link); ++ wl_list_insert(&ivisurf->layer_list, &link_layer->link); ++ add_link_to_surface(ivilayer, link_layer); ++} ++ ++static void ++remove_ordersurface_from_layer(struct ivi_layout_surface *ivisurf) ++{ ++ struct link_layer *link_layer = NULL; ++ struct link_layer *next = NULL; ++ ++ wl_list_for_each_safe(link_layer, next, &ivisurf->layer_list, link) { ++ if (!wl_list_empty(&link_layer->link)) { ++ wl_list_remove(&link_layer->link); ++ } ++ if (!wl_list_empty(&link_layer->link_to_layer)) { ++ wl_list_remove(&link_layer->link_to_layer); ++ } ++ free(link_layer); ++ } ++ wl_list_init(&ivisurf->layer_list); ++} ++ ++/** ++ * Internal API to add/remove a ivi_layer to/from ivi_screen. ++ */ ++static void ++add_orderlayer_to_screen(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_screen *iviscrn) ++{ ++ struct link_screen *link_scrn = NULL; ++ ++ link_scrn = malloc(sizeof *link_scrn); ++ if (link_scrn == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return; ++ } ++ ++ link_scrn->iviscrn = iviscrn; ++ wl_list_init(&link_scrn->link); ++ wl_list_insert(&ivilayer->screen_list, &link_scrn->link); ++ add_link_to_layer(iviscrn, link_scrn); ++} ++ ++static void ++remove_orderlayer_from_screen(struct ivi_layout_layer *ivilayer) ++{ ++ struct link_screen *link_scrn = NULL; ++ struct link_screen *next = NULL; ++ ++ wl_list_for_each_safe(link_scrn, next, &ivilayer->screen_list, link) { ++ if (!wl_list_empty(&link_scrn->link)) { ++ wl_list_remove(&link_scrn->link); ++ } ++ if (!wl_list_empty(&link_scrn->link_to_screen)) { ++ wl_list_remove(&link_scrn->link_to_screen); ++ } ++ free(link_scrn); ++ } ++ wl_list_init(&ivilayer->screen_list); ++} ++ ++/** ++ * Internal API to add/remove a ivi_layer to/from ivi_screen. ++ */ ++static struct ivi_layout_surface * ++get_surface(struct wl_list *surf_list, uint32_t id_surface) ++{ ++ struct ivi_layout_surface *ivisurf; ++ ++ wl_list_for_each(ivisurf, surf_list, link) { ++ if (ivisurf->id_surface == id_surface) { ++ return ivisurf; ++ } ++ } ++ ++ return NULL; ++} ++ ++static struct ivi_layout_layer * ++get_layer(struct wl_list *layer_list, uint32_t id_layer) ++{ ++ struct ivi_layout_layer *ivilayer; ++ ++ wl_list_for_each(ivilayer, layer_list, link) { ++ if (ivilayer->id_layer == id_layer) { ++ return ivilayer; ++ } ++ } ++ ++ return NULL; ++} ++ ++/** ++ * Called at destruction of ivi_surface ++ */ ++static void ++westonsurface_destroy_from_ivisurface(struct wl_listener *listener, void *data) ++{ ++ struct ivi_layout_surface *ivisurf = NULL; ++ ++ ivisurf = container_of(listener, struct ivi_layout_surface, ++ surface_destroy_listener); ++ ++ wl_list_init(&ivisurf->surface_rotation.link); ++ wl_list_init(&ivisurf->layer_rotation.link); ++ wl_list_init(&ivisurf->surface_pos.link); ++ wl_list_init(&ivisurf->layer_pos.link); ++ wl_list_init(&ivisurf->scaling.link); ++ ++ ivisurf->surface = NULL; ++ ivi_layout_surface_remove(ivisurf); ++} ++ ++/** ++ * Internal API to check ivi_layer/ivi_surface already added in ivi_layer/ivi_screen. ++ * Called by ivi_layout_layer_add_surface/ivi_layout_screenAddLayer ++ */ ++static int ++is_surface_in_layer(struct ivi_layout_surface *ivisurf, ++ struct ivi_layout_layer *ivilayer) ++{ ++ struct ivi_layout_surface *surf = NULL; ++ ++ wl_list_for_each(surf, &ivilayer->pending.surface_list, pending.link) { ++ if (surf->id_surface == ivisurf->id_surface) { ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++static int ++is_layer_in_screen(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_screen *iviscrn) ++{ ++ struct ivi_layout_layer *layer = NULL; ++ ++ wl_list_for_each(layer, &iviscrn->pending.layer_list, pending.link) { ++ if (layer->id_layer == ivilayer->id_layer) { ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++/** ++ * Internal API to initialize ivi_screens found from output_list of weston_compositor. ++ * Called by ivi_layout_init_with_compositor. ++ */ ++static void ++create_screen(struct weston_compositor *ec) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_screen *iviscrn = NULL; ++ struct weston_output *output = NULL; ++ int32_t count = 0; ++ ++ wl_list_for_each(output, &ec->output_list, link) { ++ iviscrn = calloc(1, sizeof *iviscrn); ++ if (iviscrn == NULL) { ++ weston_log("fails to allocate memory\n"); ++ continue; ++ } ++ ++ wl_list_init(&iviscrn->link); ++ iviscrn->layout = layout; ++ ++ iviscrn->id_screen = count; ++ count++; ++ ++ iviscrn->output = output; ++ iviscrn->event_mask = 0; ++ ++ wl_list_init(&iviscrn->pending.layer_list); ++ wl_list_init(&iviscrn->pending.link); ++ ++ wl_list_init(&iviscrn->order.layer_list); ++ wl_list_init(&iviscrn->order.link); ++ ++ wl_list_init(&iviscrn->link_to_layer); ++ ++ wl_list_insert(&layout->screen_list, &iviscrn->link); ++ } ++} ++ ++/** ++ * Internal APIs to initialize properties of ivi_surface/ivi_layer when they are created. ++ */ ++static void ++init_layer_properties(struct ivi_layout_layer_properties *prop, ++ int32_t width, int32_t height) ++{ ++ memset(prop, 0, sizeof *prop); ++ prop->opacity = wl_fixed_from_double(1.0); ++ prop->source_width = width; ++ prop->source_height = height; ++ prop->dest_width = width; ++ prop->dest_height = height; ++} ++ ++static void ++init_surface_properties(struct ivi_layout_surface_properties *prop) ++{ ++ memset(prop, 0, sizeof *prop); ++ prop->opacity = wl_fixed_from_double(1.0); ++} ++ ++/** ++ * Internal APIs to be called from ivi_layout_commit_changes. ++ */ ++static void ++update_opacity(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface *ivisurf) ++{ ++ double layer_alpha = wl_fixed_to_double(ivilayer->prop.opacity); ++ double surf_alpha = wl_fixed_to_double(ivisurf->prop.opacity); ++ ++ if ((ivilayer->event_mask & IVI_NOTIFICATION_OPACITY) || ++ (ivisurf->event_mask & IVI_NOTIFICATION_OPACITY)) { ++ struct weston_view *tmpview = NULL; ++ wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) { ++ if (tmpview == NULL) { ++ continue; ++ } ++ tmpview->alpha = layer_alpha * surf_alpha; ++ } ++ } ++} ++ ++static void ++update_surface_orientation(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface *ivisurf) ++{ ++ struct weston_view *view; ++ struct weston_matrix *matrix = &ivisurf->surface_rotation.matrix; ++ float width = 0.0f; ++ float height = 0.0f; ++ float v_sin = 0.0f; ++ float v_cos = 0.0f; ++ float cx = 0.0f; ++ float cy = 0.0f; ++ float sx = 1.0f; ++ float sy = 1.0f; ++ ++ wl_list_for_each(view, &ivisurf->surface->views, surface_link) { ++ if (view != NULL) { ++ break; ++ } ++ } ++ ++ if (view == NULL) { ++ return; ++ } ++ ++ if ((ivilayer->prop.dest_width == 0) || ++ (ivilayer->prop.dest_height == 0)) { ++ return; ++ } ++ width = (float)ivilayer->prop.dest_width; ++ height = (float)ivilayer->prop.dest_height; ++ ++ switch (ivisurf->prop.orientation) { ++ case WL_OUTPUT_TRANSFORM_NORMAL: ++ v_sin = 0.0f; ++ v_cos = 1.0f; ++ break; ++ case WL_OUTPUT_TRANSFORM_90: ++ v_sin = 1.0f; ++ v_cos = 0.0f; ++ sx = width / height; ++ sy = height / width; ++ break; ++ case WL_OUTPUT_TRANSFORM_180: ++ v_sin = 0.0f; ++ v_cos = -1.0f; ++ break; ++ case WL_OUTPUT_TRANSFORM_270: ++ default: ++ v_sin = -1.0f; ++ v_cos = 0.0f; ++ sx = width / height; ++ sy = height / width; ++ break; ++ } ++ wl_list_remove(&ivisurf->surface_rotation.link); ++ weston_view_geometry_dirty(view); ++ ++ weston_matrix_init(matrix); ++ cx = 0.5f * width; ++ cy = 0.5f * height; ++ weston_matrix_translate(matrix, -cx, -cy, 0.0f); ++ weston_matrix_rotate_xy(matrix, v_cos, v_sin); ++ weston_matrix_scale(matrix, sx, sy, 1.0); ++ weston_matrix_translate(matrix, cx, cy, 0.0f); ++ wl_list_insert(&view->geometry.transformation_list, ++ &ivisurf->surface_rotation.link); ++ ++ weston_view_set_transform_parent(view, NULL); ++ weston_view_update_transform(view); ++} ++ ++static void ++update_layer_orientation(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface *ivisurf) ++{ ++ struct weston_surface *es = ivisurf->surface; ++ struct weston_view *view; ++ struct weston_matrix *matrix = &ivisurf->layer_rotation.matrix; ++ struct weston_output *output = NULL; ++ float width = 0.0f; ++ float height = 0.0f; ++ float v_sin = 0.0f; ++ float v_cos = 0.0f; ++ float cx = 0.0f; ++ float cy = 0.0f; ++ float sx = 1.0f; ++ float sy = 1.0f; ++ ++ wl_list_for_each(view, &ivisurf->surface->views, surface_link) { ++ if (view != NULL) { ++ break; ++ } ++ } ++ ++ if (es == NULL || view == NULL) { ++ return; ++ } ++ ++ output = es->output; ++ if (output == NULL) { ++ return; ++ } ++ if ((output->width == 0) || (output->height == 0)) { ++ return; ++ } ++ width = (float)output->width; ++ height = (float)output->height; ++ ++ switch (ivilayer->prop.orientation) { ++ case WL_OUTPUT_TRANSFORM_NORMAL: ++ v_sin = 0.0f; ++ v_cos = 1.0f; ++ break; ++ case WL_OUTPUT_TRANSFORM_90: ++ v_sin = 1.0f; ++ v_cos = 0.0f; ++ sx = width / height; ++ sy = height / width; ++ break; ++ case WL_OUTPUT_TRANSFORM_180: ++ v_sin = 0.0f; ++ v_cos = -1.0f; ++ break; ++ case WL_OUTPUT_TRANSFORM_270: ++ default: ++ v_sin = -1.0f; ++ v_cos = 0.0f; ++ sx = width / height; ++ sy = height / width; ++ break; ++ } ++ wl_list_remove(&ivisurf->layer_rotation.link); ++ weston_view_geometry_dirty(view); ++ ++ weston_matrix_init(matrix); ++ cx = 0.5f * width; ++ cy = 0.5f * height; ++ weston_matrix_translate(matrix, -cx, -cy, 0.0f); ++ weston_matrix_rotate_xy(matrix, v_cos, v_sin); ++ weston_matrix_scale(matrix, sx, sy, 1.0); ++ weston_matrix_translate(matrix, cx, cy, 0.0f); ++ wl_list_insert(&view->geometry.transformation_list, ++ &ivisurf->layer_rotation.link); ++ ++ weston_view_set_transform_parent(view, NULL); ++ weston_view_update_transform(view); ++} ++ ++static void ++update_surface_position(struct ivi_layout_surface *ivisurf) ++{ ++ struct weston_view *view; ++ float tx = (float)ivisurf->prop.dest_x; ++ float ty = (float)ivisurf->prop.dest_y; ++ struct weston_matrix *matrix = &ivisurf->surface_pos.matrix; ++ ++ wl_list_for_each(view, &ivisurf->surface->views, surface_link) { ++ if (view != NULL) { ++ break; ++ } ++ } ++ ++ if (view == NULL) { ++ return; ++ } ++ ++ wl_list_remove(&ivisurf->surface_pos.link); ++ ++ weston_matrix_init(matrix); ++ weston_matrix_translate(matrix, tx, ty, 0.0f); ++ wl_list_insert(&view->geometry.transformation_list, ++ &ivisurf->surface_pos.link); ++ ++ weston_view_set_transform_parent(view, NULL); ++ weston_view_update_transform(view); ++} ++ ++static void ++update_layer_position(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface *ivisurf) ++{ ++ struct weston_view *view; ++ struct weston_matrix *matrix = &ivisurf->layer_pos.matrix; ++ float tx = (float)ivilayer->prop.dest_x; ++ float ty = (float)ivilayer->prop.dest_y; ++ ++ wl_list_for_each(view, &ivisurf->surface->views, surface_link) { ++ if (view != NULL) { ++ break; ++ } ++ } ++ ++ if (view == NULL) { ++ return; ++ } ++ ++ wl_list_remove(&ivisurf->layer_pos.link); ++ ++ weston_matrix_init(matrix); ++ weston_matrix_translate(matrix, tx, ty, 0.0f); ++ wl_list_insert(&view->geometry.transformation_list, ++ &ivisurf->layer_pos.link); ++ ++ weston_view_set_transform_parent(view, NULL); ++ weston_view_update_transform(view); ++} ++ ++static void ++update_scale(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface *ivisurf) ++{ ++ struct weston_view *view; ++ struct weston_matrix *matrix = &ivisurf->scaling.matrix; ++ float sx = 0.0f; ++ float sy = 0.0f; ++ float lw = 0.0f; ++ float sw = 0.0f; ++ float lh = 0.0f; ++ float sh = 0.0f; ++ ++ wl_list_for_each(view, &ivisurf->surface->views, surface_link) { ++ if (view != NULL) { ++ break; ++ } ++ } ++ ++ if (view == NULL) { ++ return; ++ } ++ ++ if (ivisurf->prop.dest_width == 0 && ivisurf->prop.dest_height == 0) { ++ ivisurf->prop.dest_width = ivisurf->surface->width_from_buffer; ++ ivisurf->prop.dest_height = ivisurf->surface->height_from_buffer; ++ } ++ ++ lw = ((float)ivilayer->prop.dest_width / (float)ivilayer->prop.source_width ); ++ sw = ((float)ivisurf->prop.dest_width / (float)ivisurf->prop.source_width ); ++ lh = ((float)ivilayer->prop.dest_height / (float)ivilayer->prop.source_height); ++ sh = ((float)ivisurf->prop.dest_height / (float)ivisurf->prop.source_height ); ++ sx = sw * lw; ++ sy = sh * lh; ++ ++ wl_list_remove(&ivisurf->scaling.link); ++ weston_matrix_init(matrix); ++ weston_matrix_scale(matrix, sx, sy, 1.0f); ++ ++ wl_list_insert(&view->geometry.transformation_list, ++ &ivisurf->scaling.link); ++ ++ weston_view_set_transform_parent(view, NULL); ++ weston_view_update_transform(view); ++} ++ ++static void ++update_prop(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface *ivisurf) ++{ ++ if (ivilayer->event_mask | ivisurf->event_mask) { ++ struct weston_view *tmpview; ++ update_opacity(ivilayer, ivisurf); ++ update_layer_orientation(ivilayer, ivisurf); ++ update_layer_position(ivilayer, ivisurf); ++ update_surface_position(ivisurf); ++ update_surface_orientation(ivilayer, ivisurf); ++ update_scale(ivilayer, ivisurf); ++ ++ ivisurf->update_count++; ++ ++ wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) { ++ if (tmpview != NULL) { ++ break; ++ } ++ } ++ ++ if (tmpview != NULL) { ++ weston_view_geometry_dirty(tmpview); ++ } ++ ++ if (ivisurf->surface != NULL) { ++ weston_surface_damage(ivisurf->surface); ++ } ++ } ++} ++ ++static void ++commit_changes(struct ivi_layout *layout) ++{ ++ struct ivi_layout_screen *iviscrn = NULL; ++ struct ivi_layout_layer *ivilayer = NULL; ++ struct ivi_layout_surface *ivisurf = NULL; ++ ++ wl_list_for_each(iviscrn, &layout->screen_list, link) { ++ wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) { ++ wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) { ++ update_prop(ivilayer, ivisurf); ++ } ++ } ++ } ++} ++ ++static void ++commit_surface_list(struct ivi_layout *layout) ++{ ++ struct ivi_layout_surface *ivisurf = NULL; ++ int32_t dest_x = 0; ++ int32_t dest_y = 0; ++ int32_t dest_width = 0; ++ int32_t dest_height = 0; ++ int32_t configured = 0; ++ ++ wl_list_for_each(ivisurf, &layout->surface_list, link) { ++ if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEFAULT) { ++ dest_x = ivisurf->prop.dest_x; ++ dest_y = ivisurf->prop.dest_y; ++ dest_width = ivisurf->prop.dest_width; ++ dest_height = ivisurf->prop.dest_height; ++ ++ ivi_layout_transition_move_resize_view(ivisurf, ++ ivisurf->pending.prop.dest_x, ++ ivisurf->pending.prop.dest_y, ++ ivisurf->pending.prop.dest_width, ++ ivisurf->pending.prop.dest_height, ++ ivisurf->pending.prop.transition_duration); ++ ++ if(ivisurf->pending.prop.visibility) { ++ ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration); ++ } else { ++ ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration); ++ } ++ ++ ivisurf->prop = ivisurf->pending.prop; ++ ivisurf->prop.dest_x = dest_x; ++ ivisurf->prop.dest_y = dest_y; ++ ivisurf->prop.dest_width = dest_width; ++ ivisurf->prop.dest_height = dest_height; ++ ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE; ++ ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE; ++ ++ } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY){ ++ dest_x = ivisurf->prop.dest_x; ++ dest_y = ivisurf->prop.dest_y; ++ dest_width = ivisurf->prop.dest_width; ++ dest_height = ivisurf->prop.dest_height; ++ ++ ivi_layout_transition_move_resize_view(ivisurf, ++ ivisurf->pending.prop.dest_x, ++ ivisurf->pending.prop.dest_y, ++ ivisurf->pending.prop.dest_width, ++ ivisurf->pending.prop.dest_height, ++ ivisurf->pending.prop.transition_duration); ++ ++ ivisurf->prop = ivisurf->pending.prop; ++ ivisurf->prop.dest_x = dest_x; ++ ivisurf->prop.dest_y = dest_y; ++ ivisurf->prop.dest_width = dest_width; ++ ivisurf->prop.dest_height = dest_height; ++ ++ ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE; ++ ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE; ++ ++ } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY){ ++ configured = 0; ++ if(ivisurf->pending.prop.visibility) { ++ ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration); ++ } else { ++ ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration); ++ } ++ ++ if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width || ++ ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) { ++ configured = 1; ++ } ++ ++ ivisurf->prop = ivisurf->pending.prop; ++ ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE; ++ ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE; ++ ++ if (configured && !is_surface_transition(ivisurf)) ++ wl_signal_emit(&ivisurf->configured, ivisurf); ++ } else { ++ configured = 0; ++ if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width || ++ ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) { ++ configured = 1; ++ } ++ ++ ivisurf->prop = ivisurf->pending.prop; ++ ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE; ++ ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE; ++ ++ if (configured && !is_surface_transition(ivisurf)) ++ wl_signal_emit(&ivisurf->configured, ivisurf); ++ } ++ } ++} ++ ++static void ++commit_layer_list(struct ivi_layout *layout) ++{ ++ struct ivi_layout_layer *ivilayer = NULL; ++ struct ivi_layout_surface *ivisurf = NULL; ++ struct ivi_layout_surface *next = NULL; ++ ++ wl_list_for_each(ivilayer, &layout->layer_list, link) { ++ if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_MOVE) { ++ ivi_layout_transition_move_layer(ivilayer, ivilayer->pending.prop.dest_x, ivilayer->pending.prop.dest_y, ivilayer->pending.prop.transition_duration); ++ } else if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_FADE) { ++ ivi_layout_transition_fade_layer(ivilayer,ivilayer->pending.prop.is_fade_in, ++ ivilayer->pending.prop.start_alpha,ivilayer->pending.prop.end_alpha, ++ NULL, NULL, ++ ivilayer->pending.prop.transition_duration); ++ } ++ ivilayer->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE; ++ ++ ivilayer->prop = ivilayer->pending.prop; ++ ++ if (!(ivilayer->event_mask & ++ (IVI_NOTIFICATION_ADD | IVI_NOTIFICATION_REMOVE)) ) { ++ continue; ++ } ++ ++ if (ivilayer->event_mask & IVI_NOTIFICATION_REMOVE) { ++ wl_list_for_each_safe(ivisurf, next, ++ &ivilayer->order.surface_list, order.link) { ++ remove_ordersurface_from_layer(ivisurf); ++ ++ if (!wl_list_empty(&ivisurf->order.link)) { ++ wl_list_remove(&ivisurf->order.link); ++ } ++ ++ wl_list_init(&ivisurf->order.link); ++ ivisurf->event_mask |= IVI_NOTIFICATION_REMOVE; ++ } ++ ++ wl_list_init(&ivilayer->order.surface_list); ++ } ++ ++ if (ivilayer->event_mask & IVI_NOTIFICATION_ADD) { ++ wl_list_for_each_safe(ivisurf, next, ++ &ivilayer->order.surface_list, order.link) { ++ remove_ordersurface_from_layer(ivisurf); ++ ++ if (!wl_list_empty(&ivisurf->order.link)) { ++ wl_list_remove(&ivisurf->order.link); ++ } ++ ++ wl_list_init(&ivisurf->order.link); ++ } ++ ++ wl_list_init(&ivilayer->order.surface_list); ++ wl_list_for_each(ivisurf, &ivilayer->pending.surface_list, ++ pending.link) { ++ if(!wl_list_empty(&ivisurf->order.link)){ ++ wl_list_remove(&ivisurf->order.link); ++ wl_list_init(&ivisurf->order.link); ++ } ++ ++ wl_list_insert(&ivilayer->order.surface_list, ++ &ivisurf->order.link); ++ add_ordersurface_to_layer(ivisurf, ivilayer); ++ ivisurf->event_mask |= IVI_NOTIFICATION_ADD; ++ } ++ } ++ } ++} ++ ++static void ++commit_screen_list(struct ivi_layout *layout) ++{ ++ struct ivi_layout_screen *iviscrn = NULL; ++ struct ivi_layout_layer *ivilayer = NULL; ++ struct ivi_layout_layer *next = NULL; ++ struct ivi_layout_surface *ivisurf = NULL; ++ ++ wl_list_for_each(iviscrn, &layout->screen_list, link) { ++ if (iviscrn->event_mask & IVI_NOTIFICATION_REMOVE) { ++ wl_list_for_each_safe(ivilayer, next, ++ &iviscrn->order.layer_list, order.link) { ++ remove_orderlayer_from_screen(ivilayer); ++ ++ if (!wl_list_empty(&ivilayer->order.link)) { ++ wl_list_remove(&ivilayer->order.link); ++ } ++ ++ wl_list_init(&ivilayer->order.link); ++ ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE; ++ } ++ } ++ ++ if (iviscrn->event_mask & IVI_NOTIFICATION_ADD) { ++ wl_list_for_each_safe(ivilayer, next, ++ &iviscrn->order.layer_list, order.link) { ++ remove_orderlayer_from_screen(ivilayer); ++ ++ if (!wl_list_empty(&ivilayer->order.link)) { ++ wl_list_remove(&ivilayer->order.link); ++ } ++ ++ wl_list_init(&ivilayer->order.link); ++ } ++ ++ wl_list_init(&iviscrn->order.layer_list); ++ wl_list_for_each(ivilayer, &iviscrn->pending.layer_list, ++ pending.link) { ++ wl_list_insert(&iviscrn->order.layer_list, ++ &ivilayer->order.link); ++ add_orderlayer_to_screen(ivilayer, iviscrn); ++ ivilayer->event_mask |= IVI_NOTIFICATION_ADD; ++ } ++ } ++ ++ iviscrn->event_mask = 0; ++ ++ /* Clear view list of layout ivi_layer */ ++ wl_list_init(&layout->layout_layer.view_list.link); ++ ++ wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) { ++ if (ivilayer->prop.visibility == false) ++ continue; ++ ++ wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) { ++ struct weston_view *tmpview = NULL; ++ wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) { ++ if (tmpview != NULL) { ++ break; ++ } ++ } ++ ++ if (ivisurf->prop.visibility == false) ++ continue; ++ if (ivisurf->surface == NULL || tmpview == NULL) ++ continue; ++ ++ weston_layer_entry_insert(&layout->layout_layer.view_list, ++ &tmpview->layer_link); ++ ++ ivisurf->surface->output = iviscrn->output; ++ } ++ } ++ ++ break; ++ } ++} ++ ++static void ++commit_transition(struct ivi_layout* layout) ++{ ++ if(wl_list_empty(&layout->pending_transition_list)){ ++ return; ++ } ++ ++ wl_list_insert_list(&layout->transitions->transition_list, ++ &layout->pending_transition_list); ++ ++ wl_list_init(&layout->pending_transition_list); ++ ++ wl_event_source_timer_update(layout->transitions->event_source, 1); ++} ++ ++static void ++send_surface_prop(struct ivi_layout_surface *ivisurf) ++{ ++ wl_signal_emit(&ivisurf->property_changed, ivisurf); ++ ivisurf->event_mask = 0; ++} ++ ++static void ++send_layer_prop(struct ivi_layout_layer *ivilayer) ++{ ++ wl_signal_emit(&ivilayer->property_changed, ivilayer); ++ ivilayer->event_mask = 0; ++} ++ ++static void ++send_prop(struct ivi_layout *layout) ++{ ++ struct ivi_layout_layer *ivilayer = NULL; ++ struct ivi_layout_surface *ivisurf = NULL; ++ ++ wl_list_for_each_reverse(ivilayer, &layout->layer_list, link) { ++ send_layer_prop(ivilayer); ++ } ++ ++ wl_list_for_each_reverse(ivisurf, &layout->surface_list, link) { ++ send_surface_prop(ivisurf); ++ } ++} ++ ++static void ++clear_surface_pending_list(struct ivi_layout_layer *ivilayer) ++{ ++ struct ivi_layout_surface *surface_link = NULL; ++ struct ivi_layout_surface *surface_next = NULL; ++ ++ wl_list_for_each_safe(surface_link, surface_next, ++ &ivilayer->pending.surface_list, pending.link) { ++ if (!wl_list_empty(&surface_link->pending.link)) { ++ wl_list_remove(&surface_link->pending.link); ++ } ++ ++ wl_list_init(&surface_link->pending.link); ++ } ++ ++ ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE; ++} ++ ++static void ++clear_surface_order_list(struct ivi_layout_layer *ivilayer) ++{ ++ struct ivi_layout_surface *surface_link = NULL; ++ struct ivi_layout_surface *surface_next = NULL; ++ ++ wl_list_for_each_safe(surface_link, surface_next, ++ &ivilayer->order.surface_list, order.link) { ++ if (!wl_list_empty(&surface_link->order.link)) { ++ wl_list_remove(&surface_link->order.link); ++ } ++ ++ wl_list_init(&surface_link->order.link); ++ } ++ ++ ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE; ++} ++ ++static void ++layer_created(struct wl_listener *listener, void *data) ++{ ++ struct ivi_layout_layer *ivilayer = data; ++ ++ struct listener_layout_notification *notification = ++ container_of(listener, ++ struct listener_layout_notification, ++ listener); ++ ++ struct ivi_layout_notification_callback *created_callback = ++ notification->userdata; ++ ++ ((layer_create_notification_func)created_callback->callback) ++ (ivilayer, created_callback->data); ++} ++ ++static void ++layer_removed(struct wl_listener *listener, void *data) ++{ ++ struct ivi_layout_layer *ivilayer = data; ++ ++ struct listener_layout_notification *notification = ++ container_of(listener, ++ struct listener_layout_notification, ++ listener); ++ ++ struct ivi_layout_notification_callback *removed_callback = ++ notification->userdata; ++ ++ ((layer_remove_notification_func)removed_callback->callback) ++ (ivilayer, removed_callback->data); ++} ++ ++static void ++layer_prop_changed(struct wl_listener *listener, void *data) ++{ ++ struct ivi_layout_layer *ivilayer = data; ++ ++ struct listener_layout_notification *layout_listener = ++ container_of(listener, ++ struct listener_layout_notification, ++ listener); ++ ++ struct ivi_layout_notification_callback *prop_callback = ++ layout_listener->userdata; ++ ++ ((layer_property_notification_func)prop_callback->callback) ++ (ivilayer, &ivilayer->prop, ivilayer->event_mask, prop_callback->data); ++} ++ ++static void ++surface_created(struct wl_listener *listener, void *data) ++{ ++ struct ivi_layout_surface *ivisurface = data; ++ ++ struct listener_layout_notification *notification = ++ container_of(listener, ++ struct listener_layout_notification, ++ listener); ++ ++ struct ivi_layout_notification_callback *created_callback = ++ notification->userdata; ++ ++ ((surface_create_notification_func)created_callback->callback) ++ (ivisurface, created_callback->data); ++} ++ ++static void ++surface_removed(struct wl_listener *listener, void *data) ++{ ++ struct ivi_layout_surface *ivisurface = data; ++ ++ struct listener_layout_notification *notification = ++ container_of(listener, ++ struct listener_layout_notification, ++ listener); ++ ++ struct ivi_layout_notification_callback *removed_callback = ++ notification->userdata; ++ ++ ((surface_remove_notification_func)removed_callback->callback) ++ (ivisurface, removed_callback->data); ++} ++ ++static void ++surface_prop_changed(struct wl_listener *listener, void *data) ++{ ++ struct ivi_layout_surface *ivisurf = data; ++ ++ struct listener_layout_notification *layout_listener = ++ container_of(listener, ++ struct listener_layout_notification, ++ listener); ++ ++ struct ivi_layout_notification_callback *prop_callback = ++ layout_listener->userdata; ++ ++ ((surface_property_notification_func)prop_callback->callback) ++ (ivisurf, &ivisurf->prop, ivisurf->event_mask, prop_callback->data); ++ ++ ivisurf->event_mask = 0; ++} ++ ++static void ++surface_configure_changed(struct wl_listener *listener, ++ void *data) ++{ ++ struct ivi_layout_surface *ivisurface = data; ++ ++ struct listener_layout_notification *notification = ++ container_of(listener, ++ struct listener_layout_notification, ++ listener); ++ ++ struct ivi_layout_notification_callback *configure_changed_callback = ++ notification->userdata; ++ ++ ((surface_configure_notification_func)configure_changed_callback->callback) ++ (ivisurface, configure_changed_callback->data); ++} ++ ++static int32_t ++add_notification(struct wl_signal *signal, ++ wl_notify_func_t callback, ++ void *userdata) ++{ ++ struct listener_layout_notification *notification = NULL; ++ ++ notification = malloc(sizeof *notification); ++ if (notification == NULL) { ++ weston_log("fails to allocate memory\n"); ++ free(userdata); ++ return IVI_FAILED; ++ } ++ ++ notification->listener.notify = callback; ++ notification->userdata = userdata; ++ ++ wl_signal_add(signal, ¬ification->listener); ++ ++ return IVI_SUCCEEDED; ++} ++ ++static void ++remove_notification(struct wl_list *listener_list, void *callback, void *userdata) ++{ ++ struct wl_listener *listener = NULL; ++ struct wl_listener *next = NULL; ++ ++ wl_list_for_each_safe(listener, next, listener_list, link) { ++ struct listener_layout_notification *notification = ++ container_of(listener, ++ struct listener_layout_notification, ++ listener); ++ ++ struct ivi_layout_notification_callback *notification_callback = ++ notification->userdata; ++ ++ if ((notification_callback->callback != callback) || ++ (notification_callback->data != userdata)) { ++ continue; ++ } ++ ++ if (!wl_list_empty(&listener->link)) { ++ wl_list_remove(&listener->link); ++ } ++ ++ free(notification->userdata); ++ free(notification); ++ } ++} ++ ++static void ++remove_all_notification(struct wl_list *listener_list) ++{ ++ struct wl_listener *listener = NULL; ++ struct wl_listener *next = NULL; ++ ++ wl_list_for_each_safe(listener, next, listener_list, link) { ++ struct listener_layout_notification *notification = NULL; ++ if (!wl_list_empty(&listener->link)) { ++ wl_list_remove(&listener->link); ++ } ++ ++ notification = ++ container_of(listener, ++ struct listener_layout_notification, ++ listener); ++ ++ free(notification->userdata); ++ free(notification); ++ } ++} ++ ++/** ++ * Exported APIs of ivi-layout library are implemented from here. ++ * Brief of APIs is described in ivi-layout-export.h. ++ */ ++WL_EXPORT int32_t ++ivi_layout_add_notification_create_layer(layer_create_notification_func callback, ++ void *userdata) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_notification_callback *created_callback = NULL; ++ ++ if (callback == NULL) { ++ weston_log("ivi_layout_add_notification_create_layer: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ created_callback = malloc(sizeof *created_callback); ++ if (created_callback == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ created_callback->callback = callback; ++ created_callback->data = userdata; ++ ++ return add_notification(&layout->layer_notification.created, ++ layer_created, ++ created_callback); ++} ++ ++WL_EXPORT void ++ivi_layout_remove_notification_create_layer(layer_create_notification_func callback, ++ void *userdata) ++{ ++ struct ivi_layout *layout = get_instance(); ++ remove_notification(&layout->layer_notification.created.listener_list, callback, userdata); ++} ++ ++WL_EXPORT int32_t ++ivi_layout_add_notification_remove_layer(layer_remove_notification_func callback, ++ void *userdata) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_notification_callback *removed_callback = NULL; ++ ++ if (callback == NULL) { ++ weston_log("ivi_layout_add_notification_remove_layer: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ removed_callback = malloc(sizeof *removed_callback); ++ if (removed_callback == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ removed_callback->callback = callback; ++ removed_callback->data = userdata; ++ return add_notification(&layout->layer_notification.removed, ++ layer_removed, ++ removed_callback); ++} ++ ++WL_EXPORT void ++ivi_layout_remove_notification_remove_layer(layer_remove_notification_func callback, ++ void *userdata) ++{ ++ struct ivi_layout *layout = get_instance(); ++ remove_notification(&layout->layer_notification.removed.listener_list, callback, userdata); ++} ++ ++WL_EXPORT int32_t ++ivi_layout_add_notification_create_surface(surface_create_notification_func callback, ++ void *userdata) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_notification_callback *created_callback = NULL; ++ ++ if (callback == NULL) { ++ weston_log("ivi_layout_add_notification_create_surface: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ created_callback = malloc(sizeof *created_callback); ++ if (created_callback == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ created_callback->callback = callback; ++ created_callback->data = userdata; ++ ++ return add_notification(&layout->surface_notification.created, ++ surface_created, ++ created_callback); ++} ++ ++WL_EXPORT void ++ivi_layout_remove_notification_create_surface(surface_create_notification_func callback, ++ void *userdata) ++{ ++ struct ivi_layout *layout = get_instance(); ++ remove_notification(&layout->surface_notification.created.listener_list, callback, userdata); ++} ++ ++WL_EXPORT int32_t ++ivi_layout_add_notification_remove_surface(surface_remove_notification_func callback, ++ void *userdata) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_notification_callback *removed_callback = NULL; ++ ++ if (callback == NULL) { ++ weston_log("ivi_layout_add_notification_remove_surface: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ removed_callback = malloc(sizeof *removed_callback); ++ if (removed_callback == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ removed_callback->callback = callback; ++ removed_callback->data = userdata; ++ ++ return add_notification(&layout->surface_notification.removed, ++ surface_removed, ++ removed_callback); ++} ++ ++WL_EXPORT void ++ivi_layout_remove_notification_remove_surface(surface_remove_notification_func callback, ++ void *userdata) ++{ ++ struct ivi_layout *layout = get_instance(); ++ remove_notification(&layout->surface_notification.removed.listener_list, callback, userdata); ++} ++ ++WL_EXPORT int32_t ++ivi_layout_add_notification_configure_surface(surface_configure_notification_func callback, ++ void *userdata) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_notification_callback *configure_changed_callback = NULL; ++ if (callback == NULL) { ++ weston_log("ivi_layout_add_notification_configure_surface: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ configure_changed_callback = malloc(sizeof *configure_changed_callback); ++ if (configure_changed_callback == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ configure_changed_callback->callback = callback; ++ configure_changed_callback->data = userdata; ++ ++ return add_notification(&layout->surface_notification.configure_changed, ++ surface_configure_changed, ++ configure_changed_callback); ++} ++ ++WL_EXPORT void ++ivi_layout_remove_notification_configure_surface(surface_configure_notification_func callback, ++ void *userdata) ++{ ++ struct ivi_layout *layout = get_instance(); ++ remove_notification(&layout->surface_notification.configure_changed.listener_list, callback, userdata); ++} ++ ++WL_EXPORT uint32_t ++ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf) ++{ ++ return ivisurf->id_surface; ++} ++ ++WL_EXPORT uint32_t ++ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer) ++{ ++ return ivilayer->id_layer; ++} ++ ++struct ivi_layout_layer * ++ivi_layout_get_layer_from_id(uint32_t id_layer) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_layer *ivilayer = NULL; ++ ++ wl_list_for_each(ivilayer, &layout->layer_list, link) { ++ if (ivilayer->id_layer == id_layer) { ++ return ivilayer; ++ } ++ } ++ ++ return NULL; ++} ++ ++WL_EXPORT struct ivi_layout_surface * ++ivi_layout_get_surface_from_id(uint32_t id_surface) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_surface *ivisurf = NULL; ++ ++ wl_list_for_each(ivisurf, &layout->surface_list, link) { ++ if (ivisurf->id_surface == id_surface) { ++ return ivisurf; ++ } ++ } ++ ++ return NULL; ++} ++ ++WL_EXPORT struct ivi_layout_screen * ++ivi_layout_get_screen_from_id(uint32_t id_screen) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_screen *iviscrn = NULL; ++ ++ wl_list_for_each(iviscrn, &layout->screen_list, link) { ++//FIXME : select iviscrn from screen_list by id_screen ++ return iviscrn; ++ break; ++ } ++ ++ return NULL; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_get_screen_resolution(struct ivi_layout_screen *iviscrn, ++ int32_t *pWidth, int32_t *pHeight) ++{ ++ struct weston_output *output = NULL; ++ ++ if (pWidth == NULL || pHeight == NULL) { ++ weston_log("ivi_layout_get_screen_resolution: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ output = iviscrn->output; ++ *pWidth = output->current_mode->width; ++ *pHeight = output->current_mode->height; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_surface_add_notification(struct ivi_layout_surface *ivisurf, ++ surface_property_notification_func callback, ++ void *userdata) ++{ ++ struct listener_layout_notification* notification = NULL; ++ struct ivi_layout_notification_callback *prop_callback = NULL; ++ ++ if (ivisurf == NULL || callback == NULL) { ++ weston_log("ivi_layout_surface_add_notification: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ notification = malloc(sizeof *notification); ++ if (notification == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ prop_callback = malloc(sizeof *prop_callback); ++ if (prop_callback == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ prop_callback->callback = callback; ++ prop_callback->data = userdata; ++ ++ notification->listener.notify = surface_prop_changed; ++ notification->userdata = prop_callback; ++ ++ wl_signal_add(&ivisurf->property_changed, ¬ification->listener); ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT void ++ivi_layout_surface_remove_notification(struct ivi_layout_surface *ivisurf) ++{ ++ if (ivisurf == NULL) { ++ weston_log("ivi_layout_surface_remove_notification: invalid argument\n"); ++ return; ++ } ++ ++ remove_all_notification(&ivisurf->property_changed.listener_list); ++} ++ ++static void ++remove_configured_listener(struct ivi_layout_surface *ivisurf) ++{ ++ struct wl_listener *link = NULL; ++ struct wl_listener *next = NULL; ++ ++ wl_list_for_each_safe(link, next, &ivisurf->configured.listener_list, link) { ++ wl_list_remove(&link->link); ++ } ++} ++ ++void ++ivi_layout_surface_remove(struct ivi_layout_surface *ivisurf) ++{ ++ struct ivi_layout *layout = get_instance(); ++ ++ if (ivisurf == NULL) { ++ weston_log("ivi_layout_surface_remove: invalid argument\n"); ++ return; ++ } ++ ++ if (!wl_list_empty(&ivisurf->pending.link)) { ++ wl_list_remove(&ivisurf->pending.link); ++ } ++ if (!wl_list_empty(&ivisurf->order.link)) { ++ wl_list_remove(&ivisurf->order.link); ++ } ++ if (!wl_list_empty(&ivisurf->link)) { ++ wl_list_remove(&ivisurf->link); ++ } ++ remove_ordersurface_from_layer(ivisurf); ++ ++ wl_signal_emit(&layout->surface_notification.removed, ivisurf); ++ ++ remove_configured_listener(ivisurf); ++ ++ ivi_layout_surface_remove_notification(ivisurf); ++ ++ free(ivisurf); ++} ++ ++WL_EXPORT const struct ivi_layout_layer_properties * ++ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer) ++{ ++ if (ivilayer == NULL) { ++ weston_log("ivi_layout_get_properties_of_layer: invalid argument\n"); ++ return NULL; ++ } ++ ++ return &ivilayer->prop; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_get_screens(int32_t *pLength, struct ivi_layout_screen ***ppArray) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_screen *iviscrn = NULL; ++ int32_t length = 0; ++ int32_t n = 0; ++ ++ if (pLength == NULL || ppArray == NULL) { ++ weston_log("ivi_layout_get_screens: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ length = wl_list_length(&layout->screen_list); ++ ++ if (length != 0){ ++ /* the Array must be free by module which called this function */ ++ *ppArray = calloc(length, sizeof(struct ivi_layout_screen *)); ++ if (*ppArray == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ wl_list_for_each(iviscrn, &layout->screen_list, link) { ++ (*ppArray)[n++] = iviscrn; ++ } ++ } ++ ++ *pLength = length; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer, ++ int32_t *pLength, ++ struct ivi_layout_screen ***ppArray) ++{ ++ struct link_screen *link_scrn = NULL; ++ int32_t length = 0; ++ int32_t n = 0; ++ ++ if (ivilayer == NULL || pLength == NULL || ppArray == NULL) { ++ weston_log("ivi_layout_get_screens_under_layer: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ length = wl_list_length(&ivilayer->screen_list); ++ ++ if (length != 0){ ++ /* the Array must be free by module which called this function */ ++ *ppArray = calloc(length, sizeof(struct ivi_layout_screen *)); ++ if (*ppArray == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ wl_list_for_each(link_scrn, &ivilayer->screen_list, link) { ++ (*ppArray)[n++] = link_scrn->iviscrn; ++ } ++ } ++ ++ *pLength = length; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_layer *ivilayer = NULL; ++ int32_t length = 0; ++ int32_t n = 0; ++ ++ if (pLength == NULL || ppArray == NULL) { ++ weston_log("ivi_layout_get_layers: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ length = wl_list_length(&layout->layer_list); ++ ++ if (length != 0){ ++ /* the Array must be free by module which called this function */ ++ *ppArray = calloc(length, sizeof(struct ivi_layout_layer *)); ++ if (*ppArray == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ wl_list_for_each(ivilayer, &layout->layer_list, link) { ++ (*ppArray)[n++] = ivilayer; ++ } ++ } ++ ++ *pLength = length; ++ ++ return IVI_SUCCEEDED; ++} ++ ++int32_t ++ivi_layout_get_layers_on_screen(struct ivi_layout_screen *iviscrn, ++ int32_t *pLength, ++ struct ivi_layout_layer ***ppArray) ++{ ++ struct ivi_layout_layer *ivilayer = NULL; ++ int32_t length = 0; ++ int32_t n = 0; ++ ++ if (iviscrn == NULL || pLength == NULL || ppArray == NULL) { ++ weston_log("ivi_layout_get_layers_on_screen: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ length = wl_list_length(&iviscrn->order.layer_list); ++ ++ if (length != 0){ ++ /* the Array must be free by module which called this function */ ++ *ppArray = calloc(length, sizeof(struct ivi_layout_layer *)); ++ if (*ppArray == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ wl_list_for_each(ivilayer, &iviscrn->order.layer_list, link) { ++ (*ppArray)[n++] = ivilayer; ++ } ++ } ++ ++ *pLength = length; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf, ++ int32_t *pLength, ++ struct ivi_layout_layer ***ppArray) ++{ ++ struct link_layer *link_layer = NULL; ++ int32_t length = 0; ++ int32_t n = 0; ++ ++ if (ivisurf == NULL || pLength == NULL || ppArray == NULL) { ++ weston_log("ivi_layout_getLayers: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ length = wl_list_length(&ivisurf->layer_list); ++ ++ if (length != 0){ ++ /* the Array must be free by module which called this function */ ++ *ppArray = calloc(length, sizeof(struct ivi_layout_layer *)); ++ if (*ppArray == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ wl_list_for_each(link_layer, &ivisurf->layer_list, link) { ++ (*ppArray)[n++] = link_layer->ivilayer; ++ } ++ } ++ ++ *pLength = length; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_surface *ivisurf = NULL; ++ int32_t length = 0; ++ int32_t n = 0; ++ ++ if (pLength == NULL || ppArray == NULL) { ++ weston_log("ivi_layout_get_surfaces: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ length = wl_list_length(&layout->surface_list); ++ ++ if (length != 0){ ++ /* the Array must be free by module which called this function */ ++ *ppArray = calloc(length, sizeof(struct ivi_layout_surface *)); ++ if (*ppArray == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ wl_list_for_each(ivisurf, &layout->surface_list, link) { ++ (*ppArray)[n++] = ivisurf; ++ } ++ } ++ ++ *pLength = length; ++ ++ return IVI_SUCCEEDED; ++} ++ ++int32_t ++ivi_layout_get_surfaces_on_layer(struct ivi_layout_layer *ivilayer, ++ int32_t *pLength, ++ struct ivi_layout_surface ***ppArray) ++{ ++ struct ivi_layout_surface *ivisurf = NULL; ++ int32_t length = 0; ++ int32_t n = 0; ++ ++ if (ivilayer == NULL || pLength == NULL || ppArray == NULL) { ++ weston_log("ivi_layout_getSurfaceIDsOnLayer: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ length = wl_list_length(&ivilayer->order.surface_list); ++ ++ if (length != 0) { ++ /* the Array must be free by module which called this function */ ++ *ppArray = calloc(length, sizeof(struct ivi_layout_surface *)); ++ if (*ppArray == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) { ++ (*ppArray)[n++] = ivisurf; ++ } ++ } ++ ++ *pLength = length; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT struct ivi_layout_layer * ++ivi_layout_layer_create_with_dimension(uint32_t id_layer, ++ int32_t width, int32_t height) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_layer *ivilayer = NULL; ++ ++ ivilayer = get_layer(&layout->layer_list, id_layer); ++ if (ivilayer != NULL) { ++ weston_log("id_layer is already created\n"); ++ return ivilayer; ++ } ++ ++ ivilayer = calloc(1, sizeof *ivilayer); ++ if (ivilayer == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return NULL; ++ } ++ ++ wl_list_init(&ivilayer->link); ++ wl_signal_init(&ivilayer->property_changed); ++ wl_list_init(&ivilayer->screen_list); ++ wl_list_init(&ivilayer->link_to_surface); ++ ivilayer->layout = layout; ++ ivilayer->id_layer = id_layer; ++ ++ init_layer_properties(&ivilayer->prop, width, height); ++ ivilayer->event_mask = 0; ++ ++ wl_list_init(&ivilayer->pending.surface_list); ++ wl_list_init(&ivilayer->pending.link); ++ ivilayer->pending.prop = ivilayer->prop; ++ ++ wl_list_init(&ivilayer->order.surface_list); ++ wl_list_init(&ivilayer->order.link); ++ ++ wl_list_insert(&layout->layer_list, &ivilayer->link); ++ ++ wl_signal_emit(&layout->layer_notification.created, ivilayer); ++ ++ return ivilayer; ++} ++ ++WL_EXPORT void ++ivi_layout_layer_remove(struct ivi_layout_layer *ivilayer) ++{ ++ struct ivi_layout *layout = get_instance(); ++ ++ if (ivilayer == NULL) { ++ weston_log("ivi_layout_layer_remove: invalid argument\n"); ++ return; ++ } ++ ++ wl_signal_emit(&layout->layer_notification.removed, ivilayer); ++ ++ clear_surface_pending_list(ivilayer); ++ clear_surface_order_list(ivilayer); ++ ++ if (!wl_list_empty(&ivilayer->pending.link)) { ++ wl_list_remove(&ivilayer->pending.link); ++ } ++ if (!wl_list_empty(&ivilayer->order.link)) { ++ wl_list_remove(&ivilayer->order.link); ++ } ++ if (!wl_list_empty(&ivilayer->link)) { ++ wl_list_remove(&ivilayer->link); ++ } ++ remove_orderlayer_from_screen(ivilayer); ++ remove_link_to_surface(ivilayer); ++ ivi_layout_layer_remove_notification(ivilayer); ++ ++ free(ivilayer); ++} ++ ++WL_EXPORT int32_t ++ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer, ++ bool newVisibility) ++{ ++ struct ivi_layout_layer_properties *prop = NULL; ++ ++ if (ivilayer == NULL) { ++ weston_log("ivi_layout_layer_set_visibility: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop = &ivilayer->pending.prop; ++ prop->visibility = newVisibility; ++ ++ ivilayer->event_mask |= IVI_NOTIFICATION_VISIBILITY; ++ ++ return IVI_SUCCEEDED; ++} ++ ++bool ++ivi_layout_layer_get_visibility(struct ivi_layout_layer *ivilayer) ++{ ++ if (ivilayer == NULL) { ++ weston_log("ivi_layout_layer_get_visibility: invalid argument\n"); ++ return false; ++ } ++ ++ return ivilayer->prop.visibility; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer, ++ wl_fixed_t opacity) ++{ ++ struct ivi_layout_layer_properties *prop = NULL; ++ ++ if (ivilayer == NULL) { ++ weston_log("ivi_layout_layer_set_opacity: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop = &ivilayer->pending.prop; ++ prop->opacity = opacity; ++ ++ ivilayer->event_mask |= IVI_NOTIFICATION_OPACITY; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT wl_fixed_t ++ivi_layout_layer_get_opacity(struct ivi_layout_layer *ivilayer) ++{ ++ if (ivilayer == NULL) { ++ weston_log("ivi_layout_layer_get_opacity: invalid argument\n"); ++ return wl_fixed_from_double(0.0); ++ } ++ ++ return ivilayer->prop.opacity; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer, ++ int32_t x, int32_t y, ++ int32_t width, int32_t height) ++{ ++ struct ivi_layout_layer_properties *prop = NULL; ++ ++ if (ivilayer == NULL) { ++ weston_log("ivi_layout_layer_set_source_rectangle: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop = &ivilayer->pending.prop; ++ prop->source_x = x; ++ prop->source_y = y; ++ prop->source_width = width; ++ prop->source_height = height; ++ ++ ivilayer->event_mask |= IVI_NOTIFICATION_SOURCE_RECT; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer, ++ int32_t x, int32_t y, ++ int32_t width, int32_t height) ++{ ++ struct ivi_layout_layer_properties *prop = NULL; ++ ++ if (ivilayer == NULL) { ++ weston_log("ivi_layout_layer_set_destination_rectangle: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop = &ivilayer->pending.prop; ++ prop->dest_x = x; ++ prop->dest_y = y; ++ prop->dest_width = width; ++ prop->dest_height = height; ++ ++ ivilayer->event_mask |= IVI_NOTIFICATION_DEST_RECT; ++ ++ return IVI_SUCCEEDED; ++} ++ ++int32_t ++ivi_layout_layer_get_dimension(struct ivi_layout_layer *ivilayer, ++ int32_t *dest_width, int32_t *dest_height) ++{ ++ if (ivilayer == NULL || dest_width == NULL || dest_height == NULL) { ++ weston_log("ivi_layout_layer_get_dimension: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ *dest_width = ivilayer->prop.dest_width; ++ *dest_height = ivilayer->prop.dest_height; ++ ++ return IVI_SUCCEEDED; ++} ++ ++int32_t ++ivi_layout_layer_set_dimension(struct ivi_layout_layer *ivilayer, ++ int32_t dest_width, int32_t dest_height) ++{ ++ struct ivi_layout_layer_properties *prop = NULL; ++ ++ if (ivilayer == NULL) { ++ weston_log("ivi_layout_layer_set_dimension: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop = &ivilayer->pending.prop; ++ ++ prop->dest_width = dest_width; ++ prop->dest_height = dest_height; ++ ++ ivilayer->event_mask |= IVI_NOTIFICATION_DIMENSION; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_layer_get_position(struct ivi_layout_layer *ivilayer, ++ int32_t *dest_x, int32_t *dest_y) ++{ ++ if (ivilayer == NULL || dest_x == NULL || dest_y == NULL) { ++ weston_log("ivi_layout_layer_get_position: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ *dest_x = ivilayer->prop.dest_x; ++ *dest_y = ivilayer->prop.dest_y; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer, ++ int32_t dest_x, int32_t dest_y) ++{ ++ struct ivi_layout_layer_properties *prop = NULL; ++ ++ if (ivilayer == NULL) { ++ weston_log("ivi_layout_layer_set_position: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop = &ivilayer->pending.prop; ++ prop->dest_x = dest_x; ++ prop->dest_y = dest_y; ++ ++ ivilayer->event_mask |= IVI_NOTIFICATION_POSITION; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_layer_set_orientation(struct ivi_layout_layer *ivilayer, ++ enum wl_output_transform orientation) ++{ ++ struct ivi_layout_layer_properties *prop = NULL; ++ ++ if (ivilayer == NULL) { ++ weston_log("ivi_layout_layer_set_orientation: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop = &ivilayer->pending.prop; ++ prop->orientation = orientation; ++ ++ ivilayer->event_mask |= IVI_NOTIFICATION_ORIENTATION; ++ ++ return IVI_SUCCEEDED; ++} ++ ++enum wl_output_transform ++ivi_layout_layer_get_orientation(struct ivi_layout_layer *ivilayer) ++{ ++ if (ivilayer == NULL) { ++ weston_log("ivi_layout_layer_get_orientation: invalid argument\n"); ++ return 0; ++ } ++ ++ return ivilayer->prop.orientation; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface **pSurface, ++ int32_t number) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_surface *ivisurf = NULL; ++ struct ivi_layout_surface *next = NULL; ++ uint32_t *id_surface = NULL; ++ int32_t i = 0; ++ ++ if (ivilayer == NULL) { ++ weston_log("ivi_layout_layer_set_render_order: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ if (pSurface == NULL) { ++ wl_list_for_each_safe(ivisurf, next, &ivilayer->pending.surface_list, pending.link) { ++ if (!wl_list_empty(&ivisurf->pending.link)) { ++ wl_list_remove(&ivisurf->pending.link); ++ } ++ ++ wl_list_init(&ivisurf->pending.link); ++ } ++ ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE; ++ return IVI_SUCCEEDED; ++ } ++ ++ for (i = 0; i < number; i++) { ++ id_surface = &pSurface[i]->id_surface; ++ ++ wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) { ++ if (*id_surface != ivisurf->id_surface) { ++ continue; ++ } ++ ++ if (!wl_list_empty(&ivisurf->pending.link)) { ++ wl_list_remove(&ivisurf->pending.link); ++ } ++ wl_list_init(&ivisurf->pending.link); ++ wl_list_insert(&ivilayer->pending.surface_list, ++ &ivisurf->pending.link); ++ break; ++ } ++ } ++ ++ ivilayer->event_mask |= IVI_NOTIFICATION_ADD; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf, ++ bool newVisibility) ++{ ++ struct ivi_layout_surface_properties *prop = NULL; ++ ++ if (ivisurf == NULL) { ++ weston_log("ivi_layout_surface_set_visibility: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop = &ivisurf->pending.prop; ++ prop->visibility = newVisibility; ++ ++ ivisurf->event_mask |= IVI_NOTIFICATION_VISIBILITY; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT bool ++ivi_layout_surface_get_visibility(struct ivi_layout_surface *ivisurf) ++{ ++ if (ivisurf == NULL) { ++ weston_log("ivi_layout_surface_get_visibility: invalid argument\n"); ++ return false; ++ } ++ ++ return ivisurf->prop.visibility; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf, ++ wl_fixed_t opacity) ++{ ++ struct ivi_layout_surface_properties *prop = NULL; ++ ++ if (ivisurf == NULL) { ++ weston_log("ivi_layout_surface_set_opacity: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop = &ivisurf->pending.prop; ++ prop->opacity = opacity; ++ ++ ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT wl_fixed_t ++ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf) ++{ ++ if (ivisurf == NULL) { ++ weston_log("ivi_layout_surface_get_opacity: invalid argument\n"); ++ return wl_fixed_from_double(0.0); ++ } ++ ++ return ivisurf->prop.opacity; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf, ++ int32_t x, int32_t y, ++ int32_t width, int32_t height) ++{ ++ struct ivi_layout_surface_properties *prop = NULL; ++ ++ if (ivisurf == NULL) { ++ weston_log("ivi_layout_surface_set_destination_rectangle: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop = &ivisurf->pending.prop; ++ prop->start_x = prop->dest_x; ++ prop->start_y = prop->dest_y; ++ prop->dest_x = x; ++ prop->dest_y = y; ++ prop->start_width = prop->dest_width; ++ prop->start_height = prop->dest_height; ++ prop->dest_width = width; ++ prop->dest_height = height; ++ ++ ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT; ++ ++ return IVI_SUCCEEDED; ++} ++ ++int32_t ++ivi_layout_surface_set_dimension(struct ivi_layout_surface *ivisurf, ++ int32_t dest_width, int32_t dest_height) ++{ ++ struct ivi_layout_surface_properties *prop = NULL; ++ ++ if (ivisurf == NULL) { ++ weston_log("ivi_layout_surface_set_dimension: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop = &ivisurf->pending.prop; ++ prop->dest_width = dest_width; ++ prop->dest_height = dest_height; ++ ++ ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION; ++ ++ return IVI_SUCCEEDED; ++} ++ ++int32_t ++ivi_layout_surface_get_dimension(struct ivi_layout_surface *ivisurf, ++ int32_t *dest_width, int32_t *dest_height) ++{ ++ if (ivisurf == NULL || dest_width == NULL || dest_height == NULL) { ++ weston_log("ivi_layout_surface_get_dimension: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ *dest_width = ivisurf->prop.dest_width; ++ *dest_height = ivisurf->prop.dest_height; ++ ++ return IVI_SUCCEEDED; ++} ++ ++int32_t ++ivi_layout_surface_set_position(struct ivi_layout_surface *ivisurf, ++ int32_t dest_x, int32_t dest_y) ++{ ++ struct ivi_layout_surface_properties *prop = NULL; ++ ++ if (ivisurf == NULL) { ++ weston_log("ivi_layout_surface_set_position: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop = &ivisurf->pending.prop; ++ prop->dest_x = dest_x; ++ prop->dest_y = dest_y; ++ ++ ivisurf->event_mask |= IVI_NOTIFICATION_POSITION; ++ ++ return IVI_SUCCEEDED; ++} ++ ++int32_t ++ivi_layout_surface_get_position(struct ivi_layout_surface *ivisurf, ++ int32_t *dest_x, int32_t *dest_y) ++{ ++ if (ivisurf == NULL || dest_x == NULL || dest_y == NULL) { ++ weston_log("ivi_layout_surface_get_position: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ *dest_x = ivisurf->prop.dest_x; ++ *dest_y = ivisurf->prop.dest_y; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf, ++ enum wl_output_transform orientation) ++{ ++ struct ivi_layout_surface_properties *prop = NULL; ++ ++ if (ivisurf == NULL) { ++ weston_log("ivi_layout_surface_set_orientation: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop = &ivisurf->pending.prop; ++ prop->orientation = orientation; ++ ++ ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION; ++ ++ return IVI_SUCCEEDED; ++} ++ ++enum wl_output_transform ++ivi_layout_surface_get_orientation(struct ivi_layout_surface *ivisurf) ++{ ++ if (ivisurf == NULL) { ++ weston_log("ivi_layout_surface_get_orientation: invalid argument\n"); ++ return 0; ++ } ++ ++ return ivisurf->prop.orientation; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn, ++ struct ivi_layout_layer *addlayer) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_layer *ivilayer = NULL; ++ struct ivi_layout_layer *next = NULL; ++ int is_layer_in_scrn = 0; ++ ++ if (iviscrn == NULL || addlayer == NULL) { ++ weston_log("ivi_layout_screen_add_layer: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ is_layer_in_scrn = is_layer_in_screen(addlayer, iviscrn); ++ if (is_layer_in_scrn == 1) { ++ weston_log("ivi_layout_screen_add_layer: addlayer is already available\n"); ++ return IVI_SUCCEEDED; ++ } ++ ++ wl_list_for_each_safe(ivilayer, next, &layout->layer_list, link) { ++ if (ivilayer->id_layer == addlayer->id_layer) { ++ if (!wl_list_empty(&ivilayer->pending.link)) { ++ wl_list_remove(&ivilayer->pending.link); ++ } ++ wl_list_init(&ivilayer->pending.link); ++ wl_list_insert(&iviscrn->pending.layer_list, ++ &ivilayer->pending.link); ++ break; ++ } ++ } ++ ++ iviscrn->event_mask |= IVI_NOTIFICATION_ADD; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn, ++ struct ivi_layout_layer **pLayer, ++ const int32_t number) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_layer *ivilayer = NULL; ++ struct ivi_layout_layer *next = NULL; ++ uint32_t *id_layer = NULL; ++ int32_t i = 0; ++ ++ if (iviscrn == NULL) { ++ weston_log("ivi_layout_screen_set_render_order: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ wl_list_for_each_safe(ivilayer, next, ++ &iviscrn->pending.layer_list, pending.link) { ++ wl_list_init(&ivilayer->pending.link); ++ } ++ ++ wl_list_init(&iviscrn->pending.layer_list); ++ ++ if (pLayer == NULL) { ++ wl_list_for_each_safe(ivilayer, next, &iviscrn->pending.layer_list, pending.link) { ++ if (!wl_list_empty(&ivilayer->pending.link)) { ++ wl_list_remove(&ivilayer->pending.link); ++ } ++ ++ wl_list_init(&ivilayer->pending.link); ++ } ++ ++ iviscrn->event_mask |= IVI_NOTIFICATION_REMOVE; ++ return IVI_SUCCEEDED; ++ } ++ ++ for (i = 0; i < number; i++) { ++ id_layer = &pLayer[i]->id_layer; ++ wl_list_for_each(ivilayer, &layout->layer_list, link) { ++ if (*id_layer != ivilayer->id_layer) { ++ continue; ++ } ++ ++ if (!wl_list_empty(&ivilayer->pending.link)) { ++ wl_list_remove(&ivilayer->pending.link); ++ } ++ wl_list_init(&ivilayer->pending.link); ++ wl_list_insert(&iviscrn->pending.layer_list, ++ &ivilayer->pending.link); ++ break; ++ } ++ } ++ ++ iviscrn->event_mask |= IVI_NOTIFICATION_ADD; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT struct weston_output * ++ivi_layout_screen_get_output(struct ivi_layout_screen *iviscrn) ++{ ++ return iviscrn->output; ++} ++ ++/** ++ * This function is used by the additional ivi-module because of dumping ivi_surface sceenshot. ++ * The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of Genivi's Layer Management. ++ * This function is used to get the result of drawing by clients. ++ */ ++WL_EXPORT struct weston_surface * ++ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf) ++{ ++ return ivisurf != NULL ? ivisurf->surface : NULL; ++} ++ ++/** ++ * This function is used by the additional ivi-module because of dumping ivi_surface sceenshot. ++ * The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of Genivi's Layer Management. ++ * This function is used to get the region and the stride. ++ */ ++WL_EXPORT int32_t ++ivi_layout_surface_get_size(struct ivi_layout_surface *ivisurf, int32_t *width, int32_t *height, int32_t *stride) ++{ ++ if (ivisurf == NULL) { ++ return IVI_FAILED; ++ } ++ ++ if (width != NULL) { ++ *width = ivisurf->prop.source_width; ++ } ++ ++ if (height != NULL) { ++ *height = ivisurf->prop.source_height; ++ } ++ ++ if (stride != NULL && ++ ivisurf->surface->buffer_ref.buffer != NULL && ++ ivisurf->surface->buffer_ref.buffer->shm_buffer != NULL) { ++ *stride = wl_shm_buffer_get_stride(ivisurf->surface->buffer_ref.buffer->shm_buffer); ++ } ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_layer_add_notification(struct ivi_layout_layer *ivilayer, ++ layer_property_notification_func callback, ++ void *userdata) ++{ ++ struct ivi_layout_notification_callback *prop_callback = NULL; ++ ++ if (ivilayer == NULL || callback == NULL) { ++ weston_log("ivi_layout_layer_add_notification: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop_callback = malloc(sizeof *prop_callback); ++ if (prop_callback == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return IVI_FAILED; ++ } ++ ++ prop_callback->callback = callback; ++ prop_callback->data = userdata; ++ ++ return add_notification(&ivilayer->property_changed, ++ layer_prop_changed, ++ prop_callback); ++} ++ ++WL_EXPORT void ++ivi_layout_layer_remove_notification(struct ivi_layout_layer *ivilayer) ++{ ++ if (ivilayer == NULL) { ++ weston_log("ivi_layout_layer_remove_notification: invalid argument\n"); ++ return; ++ } ++ ++ remove_all_notification(&ivilayer->property_changed.listener_list); ++} ++ ++WL_EXPORT const struct ivi_layout_surface_properties * ++ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf) ++{ ++ if (ivisurf == NULL) { ++ weston_log("ivi_layout_get_properties_of_surface: invalid argument\n"); ++ return NULL; ++ } ++ ++ return &ivisurf->prop; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface *addsurf) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_surface *ivisurf = NULL; ++ struct ivi_layout_surface *next = NULL; ++ int is_surf_in_layer = 0; ++ ++ if (ivilayer == NULL || addsurf == NULL) { ++ weston_log("ivi_layout_layer_add_surface: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ is_surf_in_layer = is_surface_in_layer(addsurf, ivilayer); ++ if (is_surf_in_layer == 1) { ++ weston_log("ivi_layout_layer_add_surface: addsurf is already available\n"); ++ return IVI_SUCCEEDED; ++ } ++ ++ wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) { ++ if (ivisurf->id_surface == addsurf->id_surface) { ++ if (!wl_list_empty(&ivisurf->pending.link)) { ++ wl_list_remove(&ivisurf->pending.link); ++ } ++ wl_list_init(&ivisurf->pending.link); ++ wl_list_insert(&ivilayer->pending.surface_list, ++ &ivisurf->pending.link); ++ break; ++ } ++ } ++ ++ ivilayer->event_mask |= IVI_NOTIFICATION_ADD; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT void ++ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer, ++ struct ivi_layout_surface *remsurf) ++{ ++ struct ivi_layout_surface *ivisurf = NULL; ++ struct ivi_layout_surface *next = NULL; ++ ++ if (ivilayer == NULL || remsurf == NULL) { ++ weston_log("ivi_layout_layer_remove_surface: invalid argument\n"); ++ return; ++ } ++ ++ wl_list_for_each_safe(ivisurf, next, ++ &ivilayer->pending.surface_list, pending.link) { ++ if (ivisurf->id_surface == remsurf->id_surface) { ++ if (!wl_list_empty(&ivisurf->pending.link)) { ++ wl_list_remove(&ivisurf->pending.link); ++ } ++ wl_list_init(&ivisurf->pending.link); ++ break; ++ } ++ } ++ ++ remsurf->event_mask |= IVI_NOTIFICATION_REMOVE; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf, ++ int32_t x, int32_t y, ++ int32_t width, int32_t height) ++{ ++ struct ivi_layout_surface_properties *prop = NULL; ++ ++ if (ivisurf == NULL) { ++ weston_log("ivi_layout_surface_set_source_rectangle: invalid argument\n"); ++ return IVI_FAILED; ++ } ++ ++ prop = &ivisurf->pending.prop; ++ prop->source_x = x; ++ prop->source_y = y; ++ prop->source_width = width; ++ prop->source_height = height; ++ ++ ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT; ++ ++ return IVI_SUCCEEDED; ++} ++ ++WL_EXPORT int32_t ++ivi_layout_commit_changes(void) ++{ ++ struct ivi_layout *layout = get_instance(); ++ ++ commit_surface_list(layout); ++ commit_layer_list(layout); ++ commit_screen_list(layout); ++ ++ commit_transition(layout); ++ ++ commit_changes(layout); ++ send_prop(layout); ++ weston_compositor_schedule_repaint(layout->compositor); ++ ++ return IVI_SUCCEEDED; ++} ++ ++/***called from ivi-shell**/ ++static struct weston_view * ++ivi_layout_get_weston_view(struct ivi_layout_surface *surface) ++{ ++ struct weston_view *tmpview = NULL; ++ ++ if(surface == NULL) ++ return NULL; ++ ++ wl_list_for_each(tmpview, &surface->surface->views, surface_link) ++ { ++ if (tmpview != NULL) { ++ break; ++ } ++ } ++ return tmpview; ++} ++ ++static void ++ivi_layout_surface_configure(struct ivi_layout_surface *ivisurf, ++ int32_t width, int32_t height) ++{ ++ struct ivi_layout *layout = get_instance(); ++ int32_t in_init = 0; ++ ivisurf->surface->width_from_buffer = width; ++ ivisurf->surface->height_from_buffer = height; ++ ++ if (ivisurf->prop.source_width == 0 || ivisurf->prop.source_height == 0) { ++ in_init = 1; ++ } ++ ++ /* FIXME: when sourceHeight/Width is used as clipping range in image buffer */ ++ /* if (ivisurf->prop.sourceWidth == 0 || ivisurf->prop.sourceHeight == 0) { */ ++ ivisurf->pending.prop.source_width = width; ++ ivisurf->pending.prop.source_height = height; ++ ivisurf->prop.source_width = width; ++ ivisurf->prop.source_height = height; ++ /* } */ ++ ++ ivisurf->event_mask |= IVI_NOTIFICATION_CONFIGURE; ++ ++ if (in_init) { ++ wl_signal_emit(&layout->surface_notification.configure_changed, ivisurf); ++ } else { ++ ivi_layout_commit_changes(); ++ } ++} ++ ++WL_EXPORT int32_t ++ivi_layout_surface_set_content_observer(struct ivi_layout_surface *ivisurf, ++ ivi_controller_surface_content_callback callback, ++ void* userdata) ++{ ++ int32_t ret = IVI_FAILED; ++ ++ if (ivisurf != NULL) { ++ ivisurf->content_observer.callback = callback; ++ ivisurf->content_observer.userdata = userdata; ++ ret = IVI_SUCCEEDED; ++ } ++ return ret; ++} ++ ++static struct ivi_layout_surface* ++ivi_layout_surface_create(struct weston_surface *wl_surface, ++ uint32_t id_surface) ++{ ++ struct ivi_layout *layout = get_instance(); ++ struct ivi_layout_surface *ivisurf = NULL; ++ struct weston_view *tmpview = NULL; ++ ++ if (wl_surface == NULL) { ++ weston_log("ivi_layout_surface_create: invalid argument\n"); ++ return NULL; ++ } ++ ++ ivisurf = get_surface(&layout->surface_list, id_surface); ++ if (ivisurf != NULL) { ++ if (ivisurf->surface != NULL) { ++ weston_log("id_surface(%d) is already created\n", id_surface); ++ return NULL; ++ } ++ } ++ ++ ivisurf = calloc(1, sizeof *ivisurf); ++ if (ivisurf == NULL) { ++ weston_log("fails to allocate memory\n"); ++ return NULL; ++ } ++ ++ wl_list_init(&ivisurf->link); ++ wl_signal_init(&ivisurf->property_changed); ++ wl_signal_init(&ivisurf->configured); ++ wl_list_init(&ivisurf->layer_list); ++ ivisurf->id_surface = id_surface; ++ ivisurf->layout = layout; ++ ++ ivisurf->surface = wl_surface; ++ ivisurf->surface_destroy_listener.notify = ++ westonsurface_destroy_from_ivisurface; ++ wl_resource_add_destroy_listener(wl_surface->resource, ++ &ivisurf->surface_destroy_listener); ++ ++ tmpview = weston_view_create(wl_surface); ++ if (tmpview == NULL) { ++ weston_log("fails to allocate memory\n"); ++ } ++ ++ ivisurf->surface->width_from_buffer = 0; ++ ivisurf->surface->height_from_buffer = 0; ++ ++ weston_matrix_init(&ivisurf->surface_rotation.matrix); ++ weston_matrix_init(&ivisurf->layer_rotation.matrix); ++ weston_matrix_init(&ivisurf->surface_pos.matrix); ++ weston_matrix_init(&ivisurf->layer_pos.matrix); ++ weston_matrix_init(&ivisurf->scaling.matrix); ++ ++ wl_list_init(&ivisurf->surface_rotation.link); ++ wl_list_init(&ivisurf->layer_rotation.link); ++ wl_list_init(&ivisurf->surface_pos.link); ++ wl_list_init(&ivisurf->layer_pos.link); ++ wl_list_init(&ivisurf->scaling.link); ++ ++ init_surface_properties(&ivisurf->prop); ++ ivisurf->event_mask = 0; ++ ++ ivisurf->pending.prop = ivisurf->prop; ++ wl_list_init(&ivisurf->pending.link); ++ ++ wl_list_init(&ivisurf->order.link); ++ wl_list_init(&ivisurf->order.layer_list); ++ ++ wl_list_insert(&layout->surface_list, &ivisurf->link); ++ ++ wl_signal_emit(&layout->surface_notification.created, ivisurf); ++ ++ return ivisurf; ++} ++ ++static void ++ivi_layout_init_with_compositor(struct weston_compositor *ec) ++{ ++ struct ivi_layout *layout = get_instance(); ++ ++ layout->compositor = ec; ++ ++ wl_list_init(&layout->surface_list); ++ wl_list_init(&layout->layer_list); ++ wl_list_init(&layout->screen_list); ++ ++ wl_signal_init(&layout->layer_notification.created); ++ wl_signal_init(&layout->layer_notification.removed); ++ ++ wl_signal_init(&layout->surface_notification.created); ++ wl_signal_init(&layout->surface_notification.removed); ++ wl_signal_init(&layout->surface_notification.configure_changed); ++ ++ /* Add layout_layer at the last of weston_compositor.layer_list */ ++ weston_layer_init(&layout->layout_layer, ec->layer_list.prev); ++ ++ create_screen(ec); ++ ++ layout->transitions = ivi_layout_transition_set_create(ec); ++ wl_list_init(&layout->pending_transition_list); ++} ++ ++ ++static void ++ivi_layout_surface_add_configured_listener(struct ivi_layout_surface* ivisurf, ++ struct wl_listener* listener) ++{ ++ wl_signal_add(&ivisurf->configured, listener); ++} ++ ++WL_EXPORT struct ivi_layout_interface ivi_layout_interface = { ++ .get_weston_view = ivi_layout_get_weston_view, ++ .surface_configure = ivi_layout_surface_configure, ++ .surface_create = ivi_layout_surface_create, ++ .init_with_compositor = ivi_layout_init_with_compositor, ++ .get_surface_dimension = ivi_layout_surface_get_dimension, ++ .add_surface_configured_listener = ivi_layout_surface_add_configured_listener ++}; +-- +1.7.9.5 + diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0004-ivi-shell-add-the-shell-plugin-for-In-Vehicle-Infota.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0004-ivi-shell-add-the-shell-plugin-for-In-Vehicle-Infota.patch new file mode 100644 index 0000000..9320abb --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0004-ivi-shell-add-the-shell-plugin-for-In-Vehicle-Infota.patch @@ -0,0 +1,1027 @@ +From 6b3f32ba6541b27062ab87aeb88665986c67e31d Mon Sep 17 00:00:00 2001 +From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +Date: Wed, 15 Oct 2014 11:26:29 +0900 +Subject: [PATCH 04/15] ivi-shell: add the shell plugin for In-Vehicle + Infotainment system + +- ivi-shell.so +- introduces ivi-shell/ivi-shell.[ch] + +In-Vehicle Infotainment system traditionally manages surfaces with +global identification. A protocol, ivi_application, supports such a +feature by implementing a request, ivi_application::surface_creation +defined in ivi_application.xml. + +The ivi-shell explicitly loads ivi-layout.so and a module to add +business logic like how to layout surfaces by using ivi-layout APIs. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +ivi-shell: send ivi_surface configure event when ivi_layout_surface configured signal emitted. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +ivi-shell: Release module when initialzing failed. + +> f9839a9 ivi-shell: add the shell plugin for In-Vehicle Infotainment system +> +> New title: "ivi-shell: add ivi-shell.so shell module" +> Destructors and few minor things need fixing. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +ivi-shell: Fix ivi_layout_surfaceSetPosition. Change int type from array type + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +ivi-shell: Change quoted_printable_encode form camelcase + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +ivi-shell: add comment why it doesn't use weston_load_module + +The reason why the following code is written newly without using +weston_load_module is it doesn't open library with RTLD_GLOBAL option. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- + ivi-shell: Replace list_thing with thing_list. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +ivi-shell/ivi-shell.c: remove non-availalable header including + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +ivi-shell: ivi-shell.[ch] clean-up code + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +ivi-shell: Remove call wl_resource_set_implementation + +> This call in not needed, AFAIK. +> [ntanibata] I will remove it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +ivi-shell: Move surface_configure_notify() definition + +> Move surface_configure_notify() definition above the line where it is +> needed, and remove the declaration from the beginning of the file. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +ivi-shell: Add shell-surface destructor. + +>> No destructor function? So what happens, if the client unexpectedly +>> disconnects, and libwayland-server destroys all wl_resources in a +>> random order? I think you'd be leaking everything you allocated in +>> this function. + +> [ntanibata] I will check and fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +ivi-shell: Fix wl_resource_create form application_surface_create + +> 'res' is wrong, you need to use 'resource' which is the object whose +> method you are executing. +> [ntanibata] I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: Fix resource leak. + +I think there is a bug. +surface_destroy() needs to call wl_resource_destroy(resource). +wl_resource_destroy() will internally as the last thing call the +destructor function you set with wl_resource_set_implementation(), which +means that shell_destroy_shell_surface() will get called when you call +wl_resource_destroy(). + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: Use error-code defined in ivi-application-protocol. +> > You also need to add the two error codes into ivi-application +> > interface and use those instead of WL_DISPLAY_ERROR_INVALID_OBJECT. +> [ntanibata] I will fix this according to two error codes. +> <enum name="error"> +> <entry name="role" value="0" summary="given wl_surface has +> another role"/> +> <entry name="ivi_id" value="1" summary="given ivi_id is assigned +> to another wl_surface"/> +> </enum> + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: Throw error-code when ivi-surface already created in application_surface_create + +> [ntanibata] I will fix it. [ntanibata] This is the first clarification. +> This is required for, - If application_surface_create is called as +> duplicate - id_surface is duplicate To avoid ivi_surface creation with the same id_surface. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: Fix destinations of error when resource error occurred. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: Remove an unnecessary call of weston_config_parse() + +> Do not call weston_config_parse, but use weston_compositor::config instead. +> [ntanibata] I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: Throw error-code when ivi-surface already created in application_surface_create + +> [ntanibata] I will fix it. [ntanibata] This is the first clarification. +> This is required for, - If application_surface_create is called as +> duplicate - id_surface is duplicate To avoid ivi_surface creation with the same id_surface. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: Fix destinations of error when resource error occurred. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell, > wl_resource_post_error uses printf-format +arguments, and passing a +> non-constant string as the format string (here 'msg' argument) is +> considered +> a security hazard, which is why compilers warn about it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: Register a ivi-surface destroy handler to weston-surface destroy signal. + +> Even if you wanted that, you still need a destroy listener to reset the +> pointer to NULL. Otherwise you will have a dangling pointer to a freed +> struct weston_surface, if the weston_surface (wl_surface) gets +> destroyed. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: clean-up Makefile.am FR3. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: Remove redundant cast + +> if (weston_config_section_get_string( + section, "ivi-module", (char **)&dest->ivi_module, NULL ) != 0) +> Why the cast? + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c +ivi_shell_setting_create(struct ivi_shell_setting *dest, struct > > +weston_compositor *compositor) > > Too long line. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c, You could get rid of one level of indenting + + wl_resource_post_error(resource, + IVI_APPLICATION_ERROR_ROLE, + "wl_surface is invalid"); + return; + } + + That's nice and clear: one can immediately read from each branch +what went wrong if execution ends up there. + + You could get rid of one level of indenting but moving the if +(!weston_surface) check to the top, since it ends in return. No need for +an else block then. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c, assert() would likely be enough here. Removes one level of indenting too. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: Remove unnecessary check for application_surface_create() + +> Didn't you already check for this condition above? Can it pass the +> earlier check and then fail here? How could this inconsistency happen? +> Or is this a paranoid check, that if we get here, there is an +> implementation bug somewhere server-side? If so, you should probably +> highlight it more, and at least make it distinguishable from the earlier check. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: Fix memory leaks by shell_destroy_shell_surface() + +> I believe you are missing free(ivisurf) here. The lifetime of ivisurf is +> tied to the lifetime of the ivi_surface protocol object (wl_resource). + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell:ivi-shell.c add null check of ivisurf->surface + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell:ivi-shell.c remove unused method, is_surf_in_surfaces + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c, remove surface_set_native_content. + +There are two use case to +- create ivi_surface without wl_surface to set property in advanced +- keep property per ID during deletion of ivi_surface. + +This is supported later. For the time being, remove this function. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c, Fix surface destructor. + +> You cannot do this. The client is destroying the wl_surface, not the +> ivi_surface. Calling wl_resource_destroy() here creates a disagreement +> between the server and the client on what protocol objects exist. It +> inevitably leads to a protocol error if the client attempts to destroy +> the ivi_surface after the wl_surface. +> Instead, you need to detach all listeners etc. from the weston_surface +> here, and set ivisurf->surface = NULL. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: Fix invalid memory read/write. correct destruction methods + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +ivi-shell: ivi-shell, revert commit of + +------------------------------------------------------------------ +https://github.com/ntanibata/weston-ivi-shell/commit/f78b50f31f6ade37de2d00845ae70872707d9fd8 +Distruction method shall be reorganized. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c, revert of fix of destruction to be re-organized. + +https://github.com/ntanibata/weston-ivi-shell/commit/0395a7ecc72ef4f4767c996473cccbbd121a34af + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c, remove wl_resource_destroy + +> vi_shell_surface, + +> + surface_destroy_listener); + + if (ivisurf->resource) { + +> wl_resource_destroy(ivisurf->resource); + +You cannot do this. The client is destroying the wl_surface, not the +ivi_surface. Calling wl_resource_destroy() here creates a disagreement +between the server and the client on what protocol objects exist. It +inevitably leads to a protocol error if the client attempts to destroy +the ivi_surface after the wl_surface. + +Instead, you need to detach all listeners etc. from the weston_surface +here, and set ivisurf->surface = NULL. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c, add comment FIXMEs to improve creation and +destruction process. + +When I compare this code with desktop-shell/shell.c, there are several +differences in process. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c, move destruction process from +shell_destroy_shell_surface to shell_handle_surface_destroy. + +This follows the same way in desktop-shell. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c, fix simple bug of assert + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell, remove unnecessary code. + +This removeing code for listener of ivi_layout_surface is already called +in ivi_layout.c. Additonally, ivisurf.ivi_layout_surface is already +cleaned up before this distroy destruction. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shekk, Remove a link from surface-list of shell. + +Forget to remove it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell.c: add comments about the destruction sequence + +Also move surface_destroy_listener together with the weston_surface +pointer it watches. + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c, Set NULL to resource of ivisurface when shell_destroy_shell_surface called + +> /* FIXME: Need to set ivisurf->resource = NULL. */ + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c, Remove unnecessary check for weston_surface of application_surface_create() + +> FIXME: This is not checked in desktop_shell, required to check? +> - Not required to check this, because libwayland-server will raise +> a protocol error automatically, if the passed in object is null +> but the protocol XML does not specify allow-null="true" for the argument. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c, Add NULL check of ivisurf->resource + +> FIXME: shell_surf->resource might be NULL, +> if controller decides to reconfigure a surface after a client +> has destroyed it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c, Move down function call for wl_resource creation + +> FIXME: this shall be done below:TAG_1, if I use the same order of +> calling in create_common_surface +> FIXME: not required if move res to below:TAG_1 +> FIXME: Move below:TAG_1 + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------ +ivi-shell: ivi-shell.c,Move ivi_layout_interface into struct ivi_shell + +> FIXME: move this static variable into struct ivi_shell. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +--- + Makefile.am | 17 +- + ivi-shell/ivi-shell.c | 529 +++++++++++++++++++++++++++++++++++++++++++++++++ + ivi-shell/ivi-shell.h | 37 ++++ + 3 files changed, 582 insertions(+), 1 deletion(-) + create mode 100644 ivi-shell/ivi-shell.c + create mode 100644 ivi-shell/ivi-shell.h + +diff --git a/Makefile.am b/Makefile.am +index 812b4bd..b16cfaa 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -723,7 +723,8 @@ endif + if ENABLE_IVI_SHELL + + module_LTLIBRARIES += \ +- $(ivi_layout) ++ $(ivi_layout) \ ++ $(ivi_shell) + + ivi_layout = ivi-layout.la + ivi_layout_la_LDFLAGS = -module -avoid-version +@@ -737,6 +738,20 @@ ivi_layout_la_SOURCES = \ + + BUILT_SOURCES += $(nodist_ivi_layout_la_SOURCES) + ++ivi_shell = ivi-shell.la ++ivi_shell_la_LDFLAGS = -module -avoid-version ++ivi_shell_la_LIBADD = $(COMPOSITOR_LIBS) libshared.la ++ivi_shell_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS) ++ivi_shell_la_SOURCES = \ ++ ivi-shell/ivi-shell.h \ ++ ivi-shell/ivi-shell.c \ ++ ivi-shell/ivi-layout-private.h ++nodist_ivi_shell_la_SOURCES = \ ++ protocol/ivi-application-protocol.c \ ++ protocol/ivi-application-server-protocol.h ++ ++BUILT_SOURCES += $(nodist_ivi_shell_la_SOURCES) ++ + endif + + +diff --git a/ivi-shell/ivi-shell.c b/ivi-shell/ivi-shell.c +new file mode 100644 +index 0000000..3904402 +--- /dev/null ++++ b/ivi-shell/ivi-shell.c +@@ -0,0 +1,529 @@ ++/* ++ * 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. ++ */ ++ ++/* ++ * ivi-shell supports a type of shell for In-Vehicle Infotainment system. ++ * In-Vehicle Infotainment system traditionally manages surfaces with global ++ * identification. A protocol, ivi_application, supports such a feature ++ * by implementing a request, ivi_application::surface_creation defined in ++ * ivi_application.xml. ++ * ++ * The ivi-shell explicitly loads a module to add business logic like how to ++ * layout surfaces by using internal ivi-layout APIs. ++ */ ++#include "config.h" ++ ++#include <sys/wait.h> ++#include <unistd.h> ++#include <stdlib.h> ++#include <stdio.h> ++#include <string.h> ++#include <linux/input.h> ++#include <dlfcn.h> ++#include <limits.h> ++#include <assert.h> ++ ++#include "ivi-shell.h" ++#include "ivi-application-server-protocol.h" ++#include "ivi-layout-private.h" ++ ++#include "../shared/os-compatibility.h" ++ ++/* Representation of ivi_surface protocol object. */ ++struct ivi_shell_surface ++{ ++ struct wl_resource* resource; ++ struct ivi_shell *shell; ++ struct ivi_layout_surface *layout_surface; ++ ++ struct weston_surface *surface; ++ struct wl_listener surface_destroy_listener; ++ ++ uint32_t id_surface; ++ ++ int32_t width; ++ int32_t height; ++ ++ struct wl_list link; ++ ++ struct wl_listener configured_listener; ++}; ++ ++struct ivi_shell_setting ++{ ++ char *ivi_module; ++}; ++ ++/* FIXME: move this static variable into struct ivi_shell. ++ * FIXED: Moved ++ */ ++ ++/* ++ * Implementation of ivi_surface ++ */ ++ ++static void ++surface_configure_notify(struct wl_listener *listener, void *data) ++{ ++ struct ivi_layout_surface *layout_surf = ++ (struct ivi_layout_surface *)data; ++ ++ struct ivi_shell_surface *shell_surf = ++ container_of(listener, ++ struct ivi_shell_surface, ++ configured_listener); ++ ++ int32_t dest_width = 0; ++ int32_t dest_height = 0; ++ shell_surf->shell->ivi_layout->get_surface_dimension(layout_surf, ++ &dest_width, &dest_height); ++ ++ /* FIXME: shell_surf->resource might be NULL, ++ * if controller decides to reconfigure a surface after a client ++ * has destroyed it. ++ * FIXED: Add NULL Check ++ */ ++ if (shell_surf->resource) ++ ivi_surface_send_configure(shell_surf->resource, ++ dest_width, dest_height); ++} ++ ++static void ++ivi_shell_surface_configure(struct weston_surface *, int32_t, int32_t); ++ ++static struct ivi_shell_surface * ++get_ivi_shell_surface(struct weston_surface *surface) ++{ ++ if (surface->configure == ivi_shell_surface_configure) ++ return surface->configure_private; ++ ++ return NULL; ++} ++ ++static void ++ivi_shell_surface_configure(struct weston_surface *surface, ++ int32_t sx, int32_t sy) ++{ ++ struct ivi_shell_surface *ivisurf = get_ivi_shell_surface(surface); ++ struct weston_view *view; ++ float from_x; ++ float from_y; ++ float to_x; ++ float to_y; ++ ++ if (surface->width == 0 || surface->height == 0 || ivisurf == NULL) ++ return; ++ ++ view = ivisurf->shell->ivi_layout->get_weston_view(ivisurf->layout_surface); ++ if (view == NULL) ++ return; ++ ++ if (ivisurf->width != surface->width || ++ ivisurf->height != surface->height) { ++ ivisurf->width = surface->width; ++ ivisurf->height = surface->height; ++ ++ weston_view_to_global_float(view, 0, 0, &from_x, &from_y); ++ weston_view_to_global_float(view, sx, sy, &to_x, &to_y); ++ ++ weston_view_set_position(view, ++ view->geometry.x + to_x - from_x, ++ view->geometry.y + to_y - from_y); ++ weston_view_update_transform(view); ++ ++ ivisurf->shell->ivi_layout->surface_configure(ivisurf->layout_surface, ++ surface->width, surface->height); ++ } ++} ++ ++/* ++ * The ivi_surface wl_resource destructor. ++ * ++ * Gets called via ivi_surface.destroy request or automatic wl_client clean-up. ++ */ ++static void ++shell_destroy_shell_surface(struct wl_resource *resource) ++{ ++/* FIXME: When I compare destruction logic of desktop-shell, ++ this part shall be done in shell_handle_surface_destroy, not here? ++FIXED: moved. ++*/ ++ /* FIXME: Need to set ivisurf->resource = NULL. ++ * FIXED: ivisurf->resource = NULL ++ */ ++ struct ivi_shell_surface *ivisurf = wl_resource_get_user_data(resource); ++ ivisurf->resource = NULL; ++} ++ ++/* Gets called through the weston_surface destroy signal. */ ++static void ++shell_handle_surface_destroy(struct wl_listener *listener, void *data) ++{ ++ struct ivi_shell_surface *ivisurf = ++ container_of(listener, struct ivi_shell_surface, ++ surface_destroy_listener); ++ ++ assert(ivisurf != NULL); ++ ++ /* FIXME: When I see desktop-shell, the following part is divided as ++ subfuction, destroy_shell_surface. ++ * - Looking at shell.c, looks like destroy_shell_surface() would ++ * not need to be a separate function. It could be done in ++ * shell_handle_surface_destroy() too. ++ */ ++ if (ivisurf->surface!=NULL) { ++ ivisurf->surface->configure = NULL; ++ ivisurf->surface->configure_private = NULL; ++ ivisurf->surface = NULL; ++ } ++ ++ wl_list_remove(&ivisurf->surface_destroy_listener.link); ++ wl_list_remove(&ivisurf->link); ++ ivisurf->resource = NULL; ++ free(ivisurf); ++ ++} ++ ++/* Gets called, when a client sends ivi_surface.destroy request. */ ++static void ++surface_destroy(struct wl_client *client, struct wl_resource *resource) ++{ ++ /* ++ * Fires the wl_resource destroy signal, and then calls ++ * ivi_surface wl_resource destructor: shell_destroy_shell_surface() ++ */ ++ wl_resource_destroy(resource); ++} ++ ++static const struct ivi_surface_interface surface_implementation = { ++ surface_destroy, ++}; ++ ++/** ++ * Request handler for ivi_application.surface_create. ++ * ++ * Creates an ivi_surface protocol object associated with the given wl_surface. ++ * ivi_surface protocol object is represented by struct ivi_shell_surface. ++ * ++ * \param client The client. ++ * \param resource The ivi_application protocol object. ++ * \param id_surface The IVI surface ID. ++ * \param surface_resource The wl_surface protocol object. ++ * \param id The protocol object id for the new ivi_surface protocol object. ++ * ++ * The wl_surface is given the ivi_surface role and associated with a unique ++ * IVI ID which is used to identify the surface in a controller ++ * (window manager). ++ */ ++static void ++application_surface_create(struct wl_client *client, ++ struct wl_resource *resource, ++ uint32_t id_surface, ++ struct wl_resource *surface_resource, ++ uint32_t id) ++{ ++ struct ivi_shell *shell = wl_resource_get_user_data(resource); ++ struct ivi_shell_surface *ivisurf; ++ struct ivi_layout_surface *layout_surface; ++ struct weston_surface *weston_surface = ++ wl_resource_get_user_data(surface_resource); ++ struct wl_resource *res; ++ ++ ++ /* FIXME: This is not checked in desktop_shell, required to check? ++ * - Not required to check this, because libwayland-server will raise ++ * a protocol error automatically, if the passed in object is null ++ * but the protocol XML does not specify allow-null="true" for the ++ * argument. ++ * FIXED: Delete NULL check ++ */ ++ ++ /* FIXME: This is the similar check with ++ desktop-shell::get_shell_surface ++ * - Yes. To be changed into a weston_surface_set_role() call, ++ * rebasing on top of upstream master branch. ++ */ ++ /* check if a wl_surface already has another role*/ ++ if (weston_surface->configure) { ++ wl_resource_post_error(resource, ++ IVI_APPLICATION_ERROR_ROLE, ++ "surface->configure already " ++ "set"); ++ return; ++ } ++ ++ ++ /* FIXME: from here, it is the similar functionality ++ with desktop-shell::create_common_surface */ ++ layout_surface = shell->ivi_layout->surface_create(weston_surface, ++ id_surface); ++ ++ /* check if id_ivi is already used for wl_surface*/ ++ if (layout_surface == NULL){ ++ wl_resource_post_error(resource, ++ IVI_APPLICATION_ERROR_IVI_ID, ++ "surface_id is already assigned " ++ "by another app"); ++ return; ++ } ++ ++ /* FIXME: this shall be done below:TAG_1, if I use the same order of calling in ++ create_common_surface ++ * FIXED: Moved ++ */ ++ ++ ivisurf = zalloc(sizeof *ivisurf); ++ if (ivisurf == NULL) { ++ wl_resource_post_no_memory(resource); ++ /*FIXME: not required if move res to below:TAG_1 ++ *FIXED: Delete ++ */ ++ return; ++ } ++ ++ wl_list_init(&ivisurf->link); ++ wl_list_insert(&shell->ivi_surface_list, &ivisurf->link); ++ ++ ivisurf->shell = shell; ++ ivisurf->id_surface = id_surface; ++ ++ /*FIXME: Move below:TAG_1 ++ *FIXED: Moved ++ */ ++ ivisurf->width = 0; ++ ivisurf->height = 0; ++ ivisurf->layout_surface = layout_surface; ++ ivisurf->configured_listener.notify = surface_configure_notify; ++ ivisurf->shell->ivi_layout->add_surface_configured_listener(layout_surface, ++ &ivisurf->configured_listener); ++ ++ /*FIXME: when I compare this logic with desktop shell: create_common_surface ++ ++shsurf->resource_destroy_listener.notify = handle_resource_destroy; ++wl_resource_add_destroy_listener(surface->resource, ++&shsurf->resource_destroy_listener); ++ ++ to be add the above lisnter?? ++ * - That is linking to the wl_resource destroy signal, this below ++ * here is linking to the weston_surface destroy signal. They have ++ * a different purpose, and you need to choose which suits the ++ * semantics you want, or if might need both. So, figure out what ++ * semantics you want first. ++ */ ++ ++ ivisurf->surface_destroy_listener.notify = shell_handle_surface_destroy; ++ wl_signal_add(&weston_surface->destroy_signal, ++ &ivisurf->surface_destroy_listener); ++ ++ ivisurf->surface = weston_surface; ++ ++ weston_surface->configure = ivi_shell_surface_configure; ++ weston_surface->configure_private = ivisurf; ++ ++ /* FIXME: End of desktop-shell::create_common_surface */ ++ /* FIXME: TAG_1 */ ++ res = wl_resource_create(client, &ivi_surface_interface, 1, id); ++ if (res == NULL) { ++ wl_client_post_no_memory(client); ++ return; ++ } ++ ++ ivisurf->resource = res; ++ ++ wl_resource_set_implementation(res, &surface_implementation, ++ ivisurf, shell_destroy_shell_surface); ++} ++ ++static const struct ivi_application_interface application_implementation = { ++ application_surface_create ++}; ++ ++/* ++ * Handle wl_registry.bind of ivi_application global singleton. ++ */ ++static void ++bind_ivi_application(struct wl_client *client, ++ void *data, uint32_t version, uint32_t id) ++{ ++ struct ivi_shell *shell = data; ++ struct wl_resource *resource; ++ ++ resource = wl_resource_create(client, &ivi_application_interface, ++ 1, id); ++ ++ wl_resource_set_implementation(resource, ++ &application_implementation, ++ shell, NULL); ++} ++ ++/* ++ * Called through the compositor's destroy signal. ++ */ ++static void ++shell_destroy(struct wl_listener *listener, void *data) ++{ ++ struct ivi_shell *shell = ++ container_of(listener, struct ivi_shell, destroy_listener); ++ struct ivi_shell_surface *ivisurf, *next; ++ ++ wl_list_for_each_safe(ivisurf, next, &shell->ivi_surface_list, link) { ++ wl_list_remove(&ivisurf->link); ++ free(ivisurf); ++ } ++ ++ free(shell); ++} ++ ++static void ++init_ivi_shell(struct weston_compositor *compositor, struct ivi_shell *shell) ++{ ++ shell->compositor = compositor; ++ ++ wl_list_init(&shell->ivi_surface_list); ++ ++} ++ ++static int ++ivi_shell_setting_create(struct ivi_shell_setting *dest, ++ struct weston_compositor *compositor) ++{ ++ int result = 0; ++ struct weston_config *config = compositor->config; ++ struct weston_config_section *section; ++ ++ if (NULL == dest) ++ return -1; ++ ++ section = weston_config_get_section(config, "ivi-shell", NULL, NULL); ++ ++ if (weston_config_section_get_string( ++ section, "ivi-module", &dest->ivi_module, NULL) != 0) ++ { ++ result = -1; ++ } ++ ++ return result; ++} ++ ++/* ++ * Initialization of ivi-shell. ++ */ ++static int ++ivi_load_modules(struct weston_compositor *compositor, const char *modules, ++ int *argc, char *argv[]) ++{ ++ const char *p, *end; ++ char buffer[256]; ++ int (*module_init)(struct weston_compositor *compositor, ++ int *argc, char *argv[]); ++ ++ if (modules == NULL) ++ return 0; ++ ++ p = modules; ++ while (*p) { ++ end = strchrnul(p, ','); ++ snprintf(buffer, sizeof buffer, "%.*s", (int)(end - p), p); ++ ++ module_init = weston_load_module(buffer, "module_init"); ++ if (module_init) ++ module_init(compositor, argc, argv); ++ ++ p = end; ++ while (*p == ',') ++ p++; ++ } ++ ++ return 0; ++} ++ ++WL_EXPORT int ++module_init(struct weston_compositor *compositor, ++ int *argc, char *argv[]) ++{ ++ struct ivi_shell *shell; ++ char ivi_layout_path[PATH_MAX]; ++ void *module; ++ struct ivi_shell_setting setting = { }; ++ ++ shell = zalloc(sizeof *shell); ++ if (shell == NULL) ++ return -1; ++ ++ init_ivi_shell(compositor, shell); ++ ++ shell->destroy_listener.notify = shell_destroy; ++ wl_signal_add(&compositor->destroy_signal, &shell->destroy_listener); ++ ++ ++ if (wl_global_create(compositor->wl_display, ++ &ivi_application_interface, 1, ++ shell, bind_ivi_application) == NULL) ++ return -1; ++ ++ if (ivi_shell_setting_create(&setting, compositor) != 0) ++ return -1; ++ ++ /* ++ * load module:ivi-layout ++ * ivi_layout_interface is referred by ivi-shell to use ivi-layout. ++ * The reason why the following code is written newly without ++ * using weston_load_module is it doesn't open library with ++ * RTLD_GLOBAL option. ++ */ ++ snprintf(ivi_layout_path, sizeof ivi_layout_path, ++ "%s/%s", MODULEDIR, "ivi-layout.so"); ++ module = dlopen(ivi_layout_path, RTLD_NOW | RTLD_NOLOAD); ++ if (module) { ++ weston_log("ivi-shell: Module '%s' already loaded\n", ++ ivi_layout_path); ++ dlclose(module); ++ return -1; ++ } ++ ++ weston_log("ivi-shell: Loading module '%s'\n", ivi_layout_path); ++ module = dlopen(ivi_layout_path, RTLD_NOW | RTLD_GLOBAL); ++ if (!module) { ++ weston_log("ivi-shell: Failed to load module: %s\n", dlerror()); ++ return -1; ++ } ++ ++ shell->ivi_layout = dlsym(module,"ivi_layout_interface"); ++ if (!shell->ivi_layout){ ++ weston_log("ivi-shell: couldn't find ivi_layout_interface in '%s'\n", ivi_layout_path); ++ free(setting.ivi_module); ++ dlclose(module); ++ return -1; ++ } ++ ++ shell->ivi_layout->init_with_compositor(compositor); ++ ++ /* Call module_init of ivi-modules which are defined in weston.ini */ ++ if (ivi_load_modules(compositor, setting.ivi_module, argc, argv) < 0) { ++ free(setting.ivi_module); ++ dlclose(module); ++ return -1; ++ } ++ ++ free(setting.ivi_module); ++ return 0; ++} +diff --git a/ivi-shell/ivi-shell.h b/ivi-shell/ivi-shell.h +new file mode 100644 +index 0000000..1283a00 +--- /dev/null ++++ b/ivi-shell/ivi-shell.h +@@ -0,0 +1,37 @@ ++/* ++ * 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. ++ */ ++ ++#include <stdbool.h> ++ ++#include "compositor.h" ++ ++struct ivi_shell ++{ ++ struct wl_resource *resource; ++ struct wl_listener destroy_listener; ++ ++ struct weston_compositor *compositor; ++ ++ struct wl_list ivi_surface_list; /* struct ivi_shell_surface::link */ ++ ++ struct ivi_layout_interface *ivi_layout; ++}; +-- +1.7.9.5 + diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0005-protocol-ivi-hmi-controller-protocol-to-set-up-IVI-s.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0005-protocol-ivi-hmi-controller-protocol-to-set-up-IVI-s.patch new file mode 100644 index 0000000..9bc8574 --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0005-protocol-ivi-hmi-controller-protocol-to-set-up-IVI-s.patch @@ -0,0 +1,176 @@ +From d8147a8e834dcb16b3114ad08168eb7fcafbd3a8 Mon Sep 17 00:00:00 2001 +From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +Date: Tue, 11 Mar 2014 10:18:30 +0900 +Subject: [PATCH 05/15] protocol: ivi hmi controller protocol to set up IVI + style UI + +- introduces ivi-hmi-controller.xml + +This protocol realizes following features, +- UI ready +- changing modes; tiling, side by side, full_screen, and random +- Give control a surface; workspace to be controlled by using ivi layout APIs +- Display/undisplay a surface; home contains sevaral workspaces to launch + application + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +Makefile.am: delete protocol/ivi-hmi-controller.xml + +> 79ba752 protocol: ivi hmi controller protocol to set up IVI style UI +> Did not look at this too carefully, because it is a private +> protocol between hmi-controller.so and +> weston-ivi-shell-user-interface. No review email. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +Makefile.am: add ivi-hmi-controller.xml to EXTRA_DIST + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +Makefile.am: add ivi-hmi-cotronller client protocol to be built as tookkit + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +ivi-shell: ivi-hmi-contoller.xml, clean-up Makefile.am + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------------- +protocol: hmi-controller.xml, update license text and clean up + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +--- + Makefile.am | 3 +- + protocol/ivi-hmi-controller.xml | 101 +++++++++++++++++++++++++++++++++++++++ + 2 files changed, 103 insertions(+), 1 deletion(-) + create mode 100644 protocol/ivi-hmi-controller.xml + +diff --git a/Makefile.am b/Makefile.am +index b16cfaa..112bff2 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1025,7 +1025,8 @@ EXTRA_DIST += \ + protocol/xdg-shell.xml \ + protocol/fullscreen-shell.xml \ + protocol/scaler.xml \ +- protocol/ivi-application.xml ++ protocol/ivi-application.xml \ ++ protocol/ivi-hmi-controller.xml + + man_MANS = weston.1 weston.ini.5 + +diff --git a/protocol/ivi-hmi-controller.xml b/protocol/ivi-hmi-controller.xml +new file mode 100644 +index 0000000..a35dd64 +--- /dev/null ++++ b/protocol/ivi-hmi-controller.xml +@@ -0,0 +1,101 @@ ++<?xml version="1.0" encoding="UTF-8"?> ++<protocol name="ivi_hmi_controller"> ++ ++ <copyright> ++ Copyright (C) 2013 DENSO CORPORATION ++ Copyright (c) 2013 BMW Car IT GmbH ++ ++ 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. ++ </copyright> ++ ++ <interface name="ivi_hmi_controller" version="1"> ++ <description summary="set up and control IVI style UI"/> ++ ++ <enum name="error_code"> ++ <entry name="init_failed" value="0"/> ++ </enum> ++ ++ <request name="UI_ready"> ++ <description summary="inform the ready for drawing desktop." /> ++ </request> ++ ++ <request name="workspace_control"> ++ <description summary="start controlling a surface by server"> ++ Reference protocol to control a surface by server. ++ To control a surface by server, it gives seat to the server ++ to e.g. control Home screen. Home screen has several workspaces ++ to group launchers of wayland application. These workspaces ++ are drawn on a horizontally long surface to be controlled ++ by motion of input device. E.g. A motion from right to left ++ happens, the viewport of surface is controlled in the ivi-shell ++ by using ivi-layout. client can recognizes the end of controlling ++ by event "workspace_end_control". ++ </description> ++ <arg name="seat" type="object" interface="wl_seat"/> ++ <arg name="serial" type="uint"/> ++ </request> ++ ++ <enum name="layout_mode"> ++ <entry name="tiling" value="0"/> ++ <entry name="side_by_side" value="1"/> ++ <entry name="full_screen" value="2"/> ++ <entry name="random" value="3" /> ++ </enum> ++ ++ <request name="switch_mode"> ++ <description summary="request mode switch of application layout"> ++ hmi-controller loaded to ivi-shall implements 4 types of layout ++ as a reference; tiling, side by side, full_screen, and random. ++ </description> ++ <arg name="layout_mode" type="uint"/> ++ </request> ++ ++ <enum name="home"> ++ <entry name="off" value="0"/> ++ <entry name="on" value="1"/> ++ </enum> ++ ++ <request name="home"> ++ <description summary="request displaying/undisplaying home screen"> ++ home screen is a reference implementation of launcher to launch ++ wayland applications. The home screen has several workspaces to ++ group wayland applications. By defining the following keys in ++ weston.ini, user can add launcher icon to launch a wayland application ++ to a workspace. ++ [ivi-launcher] ++ workspace-id=0 ++ : id of workspace to add a launcher ++ icon-id=4001 ++ : ivi id of ivi_surface to draw a icon ++ icon=/home/user/review/build-ivi-shell/data/icon_ivi_flower.png ++ : path to icon image ++ path=/home/user/review/build-ivi-shell/weston-dnd ++ : path to wayland application ++ </description> ++ <arg name="home" type="uint"/> ++ </request> ++ ++ <event name="workspace_end_control"> ++ <description summary="notify controlling workspace end"/> ++ <arg name="is_controlled" type="int"/> ++ </event> ++ ++ </interface> ++ ++</protocol> +-- +1.7.9.5 + diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0006-ivi-shell-a-reference-implementation-how-to-use-ivi-.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0006-ivi-shell-a-reference-implementation-how-to-use-ivi-.patch new file mode 100644 index 0000000..846fc66 --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0006-ivi-shell-a-reference-implementation-how-to-use-ivi-.patch @@ -0,0 +1,2189 @@ +From 7fd5b817649f0cb829bb0e033fe371a275810ad8 Mon Sep 17 00:00:00 2001 +From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +Date: Tue, 24 Jun 2014 23:06:02 +0900 +Subject: [PATCH 06/15] ivi-shell: a reference implementation how to use + ivi-layout internal APIs + +- hmi-controller.so +- introduces hmi-controller.so + +The library is used to manage layout of surfaces/layers. Layout change +is triggered by ivi-hmi-controller protocol, ivi-hmi-controller.xml. A +reference how to use the protocol, see ivi-shell-user-interface.c. + +In-Vehicle Infotainment system usually manages properties of +surfaces/layers by only a central component which decide where +surfaces/layers shall be. This is differenct use case from desktop +style; each application can request property of its window via xdg-shell +protocol, like fullscreen and set its to top level. In-Vehicle +Infortainment system doesn't allow each application to chagen them from +its application because of safty reasons. The concept of layer is +simillar with a use case of cursor layer of Destop. For In-Vehicle +Infortainment system, it is extended to all applications. For example, +rearview camera application is assigned to a layer to group several +surfaces, e.g. captured image and drawing lines separately. Central +manaegr can control property of the layer of rearview camera. + +This reference show examples to implement the central component as a +module of weston. + +Default Scene graph of UI is defined in hmi_controller_create. It +consists of +- In the bottom, a base layer to group surfaces of background, panel, + and buttons +- Next, a application layer to show application surfaces. +- Workspace background layer to show a surface of background image. +- Workspace layer to show launcher to launch application with icons. + Paths to binary and icon are defined in weston.ini. The width of + this layer is longer than the size of screen because a workspace + has several pages and is controlled by motion of input. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +data: add reference image files for weston-ivi-shell-user-interface + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------ +ivi-shell/hmi-controller.c from transition animation + +------------------------------------------ +clients/ivi-shell-user-interface.c from transition animation + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +remove clients/ivi-shell-suer-interface.c + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: clean up LIBS /CFLAGS of hmi-controller + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: clean-up headers to be used for hmi-controller + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: .gitignore update +remove unnecesary lines. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +hmi-controller: change stdbool from unit32_t + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Modification of function name + +> Typo in function name. +> [ntanibata] I will fix. -> application + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: fix invalid condition in get_hmi_grab_device + +> Should probably compare serial to something. +> [ntanibata] I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Fix delete API + +> Is this necessary? The client should just eventually (or alreay did) +> get a hangup from the connection, and exit. +> [ntanibata] I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Fix minor modifications of hmi_controller_create + +> This assignment should be in hmi_controller_create(). +> [ntanibata] I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: change int type from array type + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +hmi-controller: Use the weston_config that has already been created. + +> > Don't call weston_config_parse(), but have the +> > weston_compositor::config variable passed in here. +> [ntanibata] Yes, the same as previous comment. I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Use the weston_config that has already been created. + +> Don't parse, but use weston_compositor::config. +> All this re-parsing of weston.ini might actually slow down your start-up. +> [ntanibata] I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +hmi-controller: Fix initialized flag setting bug. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Fix add include file + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: change API name from range_val to clamp + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +hmi-controller: Fix array memory allocation. + +> > Declarations mixed up with code. Our style has declarations only in +> > the beginning of a block. +> [ntanibata] I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: Change quoted_printable_encode form camelcase + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +add FIXME at calling clock_gettime + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +hmi-controller: Declare variable in the beginning of a block. + +> > Declarations mixed up with code. Our style has declarations only +> > in the beginning of a block. +> [ntanibata] I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell/hmi-controller.c: remove non-availalable header including + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +Makefile.am: hmi-controller.so needs weston_parser feature to read configs + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: hmi-controller.c, clean-up definition of valueable in the +middle function. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: hmi-controller.c, remove code commented out. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------------- +ivi-shell: hmi-controller, modify comments, surface/layer/screen -> ivi_* + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: hmi-controller. avoid including ivi-layout-private.h + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Get hmi_controller from resource when before setup time. + +> Every one of these calls commit. Wouldn't it be better to call commit +> only once in the end of this function? +> [ntanibata] Exactly, I will fix it. +> It doesn't make too much sense to pass 'resource' as the argument to +> these function calls. Would be better to pass in struct +> hmi_controller, because that is what every single function needs and +> not the wl_resource. +> [ntanibata] I agree. I will fix it. +> ivi_hmi_controller_UI_ready() is the only function that is actually a +> request handler. +> [ntanibata] Right. I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Modification to end of function + +> Every one of these calls commit. Wouldn't it be better to call commit +> only once in the end of this function? +> [ntanibata] Exactly, I will fix it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell:hmi-controller.c Change type of calculatable variables to signed from unsigned + +> FWIW, if you are going to do calculations with these variables, they +> should be signed. If you mix unsigned and signed variables in +> calculations, the result is probably not what you expect in all cases. +> This is just a reminder for you, that you might want to change these in +> the future. +> Weston core categorically uses signed variables for anything that is +> involved in calculations, even if negative values would not make any +> sense for a particular variable. +> Counters (that may wrap around) are of course better stored as unsigned. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +Makefile.am: clean up Makefile.am with FR3 for hmi-controller + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: Move register process of destroy signal handler when hmi-controller created. + +> This does not belong here with the client launching, it belongs in +> hmicontrollercreate() with the hmi-controller init. +> Where is the function to be called on compositor destroy, anyway? + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: To improve documentary value. + +> To improve documentary value, you should have: +> struct hmicontroller *hmictrl = data; + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: remove IVI_SHELL_{LIBS,CFLAGS} from Makefile.am + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: Use weston_log() instead. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: Should be a tab, not spaces in Makefile.am + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: Change type of temporary variables from void *into int32_t *. + +> Since it's always an uint32t anyway, might as well use 'uint32t *dest' +> here and drop a cast below. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: Remove a unused assignment. + +> Useless return. Also pp_surface = NULL; has no use. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: Remove unused variables as return value. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: Fix invalid calculation. + +> 'time' is zero, so why these calculations with it? +> Something is missing here, at least you need a comment explaining what +> it is. I'd assume 'time' shouldn't be zero. +> Maybe a mistake when moving code around. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: Set initialized-flag when UI settings succeeded. + +> So, if getting any single id from the config fails, you ignore them all, +> do not set up any of the UI components except launchers, and then +> continue as if nothing went wrong? Seems a bit strange, but if you +> like it that way, so be it. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: remove useless return + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +ivi-shell: Replace weston_client_launch() with weston_client_start() + +> Since you are not really using the SIGCHLD handler for anything, a +> better function to call would be weston_client_start(). +> Allows you to remove the 'process' field from struct hmi_controller + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: Remove casts to (void) + +> I don't think we need these casts. The warning about unused arguments is +> disabled, isn't it? +> You should be able to remove casts to (void) from all places. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: fix code mixed with declarations + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: hmi-controller, Set handler to destroy-listener. + +> Ok, but do you actually set hmictrl->destroylistener.notify somewhere? I +> can't find it, and if it is not set, you should be getting a crash +> during weston shutdown. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: Post error-code if initialize failed. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: Check authorization of protocol binding. + +> ..and use 'hmictrl' here instead of 'data'. That way the reader sees +> what the userdata for the wlresource is without tracking it further. +> This function is missing authorization checks. Any client is allowed to +> bind to hmicontroller and use it to do whatever they want. You'd +> probably rather want access to hmicontroller to be restricted to the +> client you launch in launchhmiclientprocess(). +> To implement the authorization check, you would save the wlclient +> pointer from westonclientlaunch() or westonclientstart(), and compare +> 'client' to the saved pointer here. If the pointers differ, the client +> attempting to bind to hmicontroller is not the one you launched, and so +> you can send a protocol error and just return. +> If you want to implement respawn for the controller client, hook into +> the wlclient destruction, not SIGCHLD. You should hook to the wl_client +> destruction anyway, so you know when to reset the saved client pointer +> to NULL. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: Post invalid-object-error if binding failed. + +> missing an error sending. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller: hmi_controller_destroy feature to release memory + +> ok, though shouldn't that function be freeing some things? I suspect you +> might want to free struct hmi_controller there, and its members. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +---------------------------------------------------------- +hmi-controller.c: indent with tabs + +For the stray changes, see 'git show -b <sha1>'. + +---------------------------------------------------------- +hmi-controller.c: remove unneeded braces from if-statements + +---------------------------------------------------------- +hmi-controller.c: whitespace fixes + +---------------------------------------------------------- +hmi-controller.c: remove unneeded casts + +---------------------------------------------------------- +hmi-controller.c: split long lines +--- + Makefile.am | 16 +- + ivi-shell/.gitignore | 1 + + ivi-shell/hmi-controller.c | 1710 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 1726 insertions(+), 1 deletion(-) + create mode 100644 ivi-shell/.gitignore + create mode 100644 ivi-shell/hmi-controller.c + +diff --git a/Makefile.am b/Makefile.am +index 112bff2..76780a8 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -724,7 +724,8 @@ if ENABLE_IVI_SHELL + + module_LTLIBRARIES += \ + $(ivi_layout) \ +- $(ivi_shell) ++ $(ivi_shell) \ ++ $(hmi_controller) + + ivi_layout = ivi-layout.la + ivi_layout_la_LDFLAGS = -module -avoid-version +@@ -752,6 +753,19 @@ nodist_ivi_shell_la_SOURCES = \ + + BUILT_SOURCES += $(nodist_ivi_shell_la_SOURCES) + ++hmi_controller = hmi-controller.la ++hmi_controller_la_LDFLAGS = -module -avoid-version ++hmi_controller_la_LIBADD = $(COMPOSITOR_LIBS) libshared.la ++hmi_controller_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS) ++hmi_controller_la_SOURCES = \ ++ ivi-shell/ivi-layout-export.h \ ++ ivi-shell/hmi-controller.c ++nodist_hmi_controller_la_SOURCES = \ ++ protocol/ivi-hmi-controller-protocol.c \ ++ protocol/ivi-hmi-controller-server-protocol.h ++ ++BUILT_SOURCES += $(nodist_hmi_controller_la_SOURCES) ++ + endif + + +diff --git a/ivi-shell/.gitignore b/ivi-shell/.gitignore +new file mode 100644 +index 0000000..e690c59 +--- /dev/null ++++ b/ivi-shell/.gitignore +@@ -0,0 +1 @@ ++weston.ini +diff --git a/ivi-shell/hmi-controller.c b/ivi-shell/hmi-controller.c +new file mode 100644 +index 0000000..b7a6c61 +--- /dev/null ++++ b/ivi-shell/hmi-controller.c +@@ -0,0 +1,1710 @@ ++/* ++ * Copyright (C) 2014 DENSO CORPORATION ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and ++ * its documentation for any purpose is hereby granted without fee, provided ++ * that the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of the copyright holders not be used in ++ * advertising or publicity pertaining to distribution of the software ++ * without specific, written prior permission. The copyright holders make ++ * no representations about the suitability of this software for any ++ * purpose. It is provided "as is" without express or implied warranty. ++ * ++ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS ++ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND ++ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY ++ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ++ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF ++ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++/** ++ * A reference implementation how to use ivi-layout APIs in order to manage ++ * layout of ivi_surfaces/ivi_layers. Layout change is triggered by ++ * ivi-hmi-controller protocol, ivi-hmi-controller.xml. A reference how to ++ * use the protocol, see hmi-controller-homescreen. ++ * ++ * In-Vehicle Infotainment system usually manage properties of ++ * ivi_surfaces/ivi_layers by only a central component which decide where ++ * ivi_surfaces/ivi_layers shall be. This reference show examples to ++ * implement the central component as a module of weston. ++ * ++ * Default Scene graph of UI is defined in hmi_controller_create. It ++ * consists of ++ * - In the bottom, a base ivi_layer to group ivi_surfaces of background, ++ * panel, and buttons ++ * - Next, a application ivi_layer to show application ivi_surfaces. ++ * - Workspace background ivi_layer to show a ivi_surface of background image. ++ * - Workspace ivi_layer to show launcher to launch application with icons. ++ * Paths to binary and icon are defined in weston.ini. The width of this ++ * ivi_layer is longer than the size of ivi_screen because a workspace has ++ * several pages and is controlled by motion of input. ++ * ++ * TODO: animation method shall be refined ++ * TODO: support fade-in when UI is ready ++ */ ++ ++#include <sys/wait.h> ++#include <unistd.h> ++#include <stdlib.h> ++#include <stdio.h> ++#include <string.h> ++#include <linux/input.h> ++#include <assert.h> ++#include <time.h> ++ ++#include "ivi-layout-export.h" ++#include "ivi-hmi-controller-server-protocol.h" ++ ++/***************************************************************************** ++ * structure, globals ++ ****************************************************************************/ ++struct hmi_controller_layer { ++ struct ivi_layout_layer *ivilayer; ++ uint32_t id_layer; ++ int32_t x; ++ int32_t y; ++ int32_t width; ++ int32_t height; ++}; ++ ++struct link_layer { ++ struct ivi_layout_layer *layout_layer; ++ struct wl_list link; ++}; ++ ++struct hmi_controller_fade { ++ uint32_t is_fade_in; ++ struct wl_list layer_list; ++}; ++ ++struct hmi_server_setting { ++ uint32_t base_layer_id; ++ uint32_t application_layer_id; ++ uint32_t workspace_background_layer_id; ++ uint32_t workspace_layer_id; ++ int32_t panel_height; ++ uint32_t transition_duration; ++ char *ivi_homescreen; ++}; ++ ++struct hmi_controller { ++ struct hmi_server_setting *hmi_setting; ++ struct hmi_controller_layer base_layer; ++ struct hmi_controller_layer application_layer; ++ struct hmi_controller_layer workspace_background_layer; ++ struct hmi_controller_layer workspace_layer; ++ enum ivi_hmi_controller_layout_mode layout_mode; ++ ++ struct hmi_controller_fade workspace_fade; ++ ++ int32_t workspace_count; ++ struct wl_array ui_widgets; ++ int32_t is_initialized; ++ ++ struct weston_compositor *compositor; ++ struct wl_listener destroy_listener; ++ ++ struct wl_client *user_interface; ++}; ++ ++struct launcher_info { ++ uint32_t surface_id; ++ uint32_t workspace_id; ++ int32_t index; ++}; ++ ++/***************************************************************************** ++ * local functions ++ ****************************************************************************/ ++static void * ++fail_on_null(void *p, size_t size, char *file, int32_t line) ++{ ++ if (size && !p) { ++ weston_log("%s(%d) %zd: out of memory\n", file, line, size); ++ exit(EXIT_FAILURE); ++ } ++ ++ return p; ++} ++ ++static void * ++mem_alloc(size_t size, char *file, int32_t line) ++{ ++ return fail_on_null(calloc(1, size), size, file, line); ++} ++ ++#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__) ++ ++static int32_t ++is_surf_in_ui_widget(struct hmi_controller *hmi_ctrl, ++ struct ivi_layout_surface *ivisurf) ++{ ++ uint32_t id = ivi_layout_get_id_of_surface(ivisurf); ++ ++ uint32_t *ui_widget_id = NULL; ++ wl_array_for_each(ui_widget_id, &hmi_ctrl->ui_widgets) { ++ if (*ui_widget_id == id) ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static int ++compare_launcher_info(const void *lhs, const void *rhs) ++{ ++ const struct launcher_info *left = lhs; ++ const struct launcher_info *right = rhs; ++ ++ if (left->workspace_id < right->workspace_id) ++ return -1; ++ ++ if (left->workspace_id > right->workspace_id) ++ return 1; ++ ++ if (left->index < right->index) ++ return -1; ++ ++ if (left->index > right->index) ++ return 1; ++ ++ return 0; ++} ++ ++/** ++ * Internal methods called by mainly ivi_hmi_controller_switch_mode ++ * This reference shows 4 examples how to use ivi_layout APIs. ++ */ ++static void ++mode_divided_into_tiling(struct hmi_controller *hmi_ctrl, ++ struct ivi_layout_surface **pp_surface, ++ int32_t surface_length, ++ struct hmi_controller_layer *layer) ++{ ++ const float surface_width = (float)layer->width * 0.25; ++ const float surface_height = (float)layer->height * 0.5; ++ int32_t surface_x = 0; ++ int32_t surface_y = 0; ++ struct ivi_layout_surface *ivisurf = NULL; ++ struct ivi_layout_surface **surfaces; ++ struct ivi_layout_surface **new_order; ++ const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; ++ ++ int32_t i = 0; ++ int32_t surf_num = 0; ++ uint32_t num = 1; ++ ++ surfaces = MEM_ALLOC(sizeof(*surfaces) * surface_length); ++ new_order = MEM_ALLOC(sizeof(*surfaces) * surface_length); ++ ++ for (i = 0; i < surface_length; i++) { ++ ivisurf = pp_surface[i]; ++ ++ /* skip ui widgets */ ++ if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) ++ continue; ++ ++ surfaces[surf_num++] = ivisurf; ++ } ++ ++ for (i = 0; i < surf_num; i++) { ++ ivisurf = surfaces[i]; ++ new_order[i] = ivisurf; ++ ++ if (num <= 8) { ++ if (num < 5) { ++ surface_x = (int32_t)((num - 1) * (surface_width)); ++ surface_y = 0; ++ } else { ++ surface_x = (int32_t)((num - 5) * (surface_width)); ++ surface_y = (int32_t)surface_height; ++ } ++ ++ ivi_layout_surface_set_transition(ivisurf, ++ IVI_LAYOUT_TRANSITION_VIEW_DEFAULT, ++ duration); ++ ivi_layout_surface_set_visibility(ivisurf, true); ++ ivi_layout_surface_set_destination_rectangle(ivisurf, ++ surface_x, surface_y, ++ (int32_t)surface_width, ++ (int32_t)surface_height); ++ ++ num++; ++ continue; ++ } ++ ivi_layout_surface_set_visibility(ivisurf, false); ++ } ++ ++ if (surf_num > 0) { ++ ivi_layout_layer_set_transition(layer->ivilayer, ++ IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER, ++ duration); ++ //TODO: implement IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER later. ++ ivi_layout_transition_layer_render_order(layer->ivilayer, ++ new_order, ++ surf_num, ++ duration); ++ } ++ ++ free(surfaces); ++ free(new_order); ++} ++ ++static void ++mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl, ++ struct ivi_layout_surface **pp_surface, ++ int32_t surface_length, ++ struct hmi_controller_layer *layer) ++{ ++ int32_t surface_width = layer->width / 2; ++ int32_t surface_height = layer->height; ++ struct ivi_layout_surface *ivisurf = NULL; ++ ++ const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; ++ int32_t i = 0; ++ int32_t num = 1; ++ ++ for (i = 0; i < surface_length; i++) { ++ ivisurf = pp_surface[i]; ++ ++ /* skip ui widgets */ ++ if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) ++ continue; ++ ++ if (num == 1) { ++ ivi_layout_surface_set_transition(ivisurf, ++ IVI_LAYOUT_TRANSITION_VIEW_DEFAULT, ++ duration); ++ ivi_layout_surface_set_visibility(ivisurf, true); ++ ivi_layout_surface_set_destination_rectangle(ivisurf, ++ 0, 0, ++ surface_width, ++ surface_height); ++ ++ num++; ++ continue; ++ } else if (num == 2) { ++ ivi_layout_surface_set_transition(ivisurf, ++ IVI_LAYOUT_TRANSITION_VIEW_DEFAULT, ++ duration); ++ ivi_layout_surface_set_visibility(ivisurf, true); ++ ivi_layout_surface_set_destination_rectangle(ivisurf, ++ surface_width, 0, ++ surface_width, ++ surface_height); ++ ++ num++; ++ continue; ++ } ++ ivi_layout_surface_set_transition(ivisurf, ++ IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY, ++ duration); ++ ivi_layout_surface_set_visibility(ivisurf, false); ++ } ++} ++ ++static void ++mode_fullscreen_someone(struct hmi_controller *hmi_ctrl, ++ struct ivi_layout_surface **pp_surface, ++ int32_t surface_length, ++ struct hmi_controller_layer *layer) ++{ ++ const int32_t surface_width = layer->width; ++ const int32_t surface_height = layer->height; ++ struct ivi_layout_surface *ivisurf = NULL; ++ int32_t i = 0; ++ const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; ++ ++ for (i = 0; i < surface_length; i++) { ++ ivisurf = pp_surface[i]; ++ ++ /* skip ui widgets */ ++ if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) ++ continue; ++ ++ ivi_layout_surface_set_transition(ivisurf, ++ IVI_LAYOUT_TRANSITION_VIEW_DEFAULT, ++ duration); ++ ivi_layout_surface_set_visibility(ivisurf, true); ++ ivi_layout_surface_set_destination_rectangle(ivisurf, 0, 0, ++ surface_width, ++ surface_height); ++ } ++} ++ ++static void ++mode_random_replace(struct hmi_controller *hmi_ctrl, ++ struct ivi_layout_surface **pp_surface, ++ int32_t surface_length, ++ struct hmi_controller_layer *layer) ++{ ++ const int32_t surface_width = (int32_t)(layer->width * 0.25f); ++ const int32_t surface_height = (int32_t)(layer->height * 0.25f); ++ int32_t surface_x = 0; ++ int32_t surface_y = 0; ++ struct ivi_layout_surface *ivisurf = NULL; ++ const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; ++ int32_t i = 0; ++ ++ for (i = 0; i < surface_length; i++) { ++ ivisurf = pp_surface[i]; ++ ++ /* skip ui widgets */ ++ if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) ++ continue; ++ ++ ivi_layout_surface_set_transition(ivisurf, ++ IVI_LAYOUT_TRANSITION_VIEW_DEFAULT, ++ duration); ++ ivi_layout_surface_set_visibility(ivisurf, true); ++ surface_x = rand() % (layer->width - surface_width); ++ surface_y = rand() % (layer->height - surface_height); ++ ++ ivi_layout_surface_set_destination_rectangle(ivisurf, ++ surface_x, ++ surface_y, ++ surface_width, ++ surface_height); ++ } ++} ++ ++static int32_t ++has_application_surface(struct hmi_controller *hmi_ctrl, ++ struct ivi_layout_surface **pp_surface, ++ int32_t surface_length) ++{ ++ struct ivi_layout_surface *ivisurf = NULL; ++ int32_t i = 0; ++ ++ for (i = 0; i < surface_length; i++) { ++ ivisurf = pp_surface[i]; ++ ++ /* skip ui widgets */ ++ if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) ++ continue; ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/** ++ * Supports 4 example to layout of application ivi_surfaces; ++ * tiling, side by side, fullscreen, and random. ++ */ ++static void ++switch_mode(struct hmi_controller *hmi_ctrl, ++ enum ivi_hmi_controller_layout_mode layout_mode) ++{ ++ struct hmi_controller_layer *layer = &hmi_ctrl->application_layer; ++ struct ivi_layout_surface **pp_surface = NULL; ++ int32_t surface_length = 0; ++ int32_t ret = 0; ++ ++ if (!hmi_ctrl->is_initialized) ++ return; ++ ++ hmi_ctrl->layout_mode = layout_mode; ++ ++ ret = ivi_layout_get_surfaces(&surface_length, &pp_surface); ++ assert(!ret); ++ ++ if (!has_application_surface(hmi_ctrl, pp_surface, surface_length)) { ++ free(pp_surface); ++ pp_surface = NULL; ++ return; ++ } ++ ++ switch (layout_mode) { ++ case IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING: ++ mode_divided_into_tiling(hmi_ctrl, pp_surface, surface_length, ++ layer); ++ break; ++ case IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE: ++ mode_divided_into_sidebyside(hmi_ctrl, pp_surface, ++ surface_length, layer); ++ break; ++ case IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN: ++ mode_fullscreen_someone(hmi_ctrl, pp_surface, surface_length, ++ layer); ++ break; ++ case IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM: ++ mode_random_replace(hmi_ctrl, pp_surface, surface_length, ++ layer); ++ break; ++ } ++ ++ ivi_layout_commit_changes(); ++ free(pp_surface); ++} ++ ++/** ++ * Internal method for transition ++ */ ++static void ++hmi_controller_fade_run(struct hmi_controller *hmi_ctrl, uint32_t is_fade_in, ++ struct hmi_controller_fade *fade) ++{ ++ double tint = is_fade_in ? 1.0 : 0.0; ++ struct link_layer *linklayer = NULL; ++ const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; ++ ++ fade->is_fade_in = is_fade_in; ++ ++ wl_list_for_each(linklayer, &fade->layer_list, link) { ++ ivi_layout_layer_set_transition(linklayer->layout_layer, ++ IVI_LAYOUT_TRANSITION_LAYER_FADE, ++ duration); ++ ivi_layout_layer_set_fade_info(linklayer->layout_layer, ++ is_fade_in, 1.0 - tint, tint); ++ } ++} ++ ++/** ++ * Internal method to create ivi_layer with hmi_controller_layer and ++ * add to a ivi_screen ++ */ ++static void ++create_layer(struct ivi_layout_screen *iviscrn, ++ struct hmi_controller_layer *layer) ++{ ++ int32_t ret = 0; ++ ++ layer->ivilayer = ++ ivi_layout_layer_create_with_dimension(layer->id_layer, ++ layer->width, ++ layer->height); ++ assert(layer->ivilayer != NULL); ++ ++ ret = ivi_layout_screen_add_layer(iviscrn, layer->ivilayer); ++ assert(!ret); ++ ++ ret = ivi_layout_layer_set_destination_rectangle(layer->ivilayer, ++ layer->x, layer->y, ++ layer->width, ++ layer->height); ++ assert(!ret); ++ ++ ret = ivi_layout_layer_set_visibility(layer->ivilayer, true); ++ assert(!ret); ++} ++ ++/** ++ * Internal set notification ++ */ ++static void ++set_notification_create_surface(struct ivi_layout_surface *ivisurf, ++ void *userdata) ++{ ++ struct hmi_controller *hmi_ctrl = userdata; ++ struct ivi_layout_layer *application_layer = ++ hmi_ctrl->application_layer.ivilayer; ++ int32_t ret = 0; ++ ++ /* skip ui widgets */ ++ if (is_surf_in_ui_widget(hmi_ctrl, ivisurf)) ++ return; ++ ++ ret = ivi_layout_layer_add_surface(application_layer, ivisurf); ++ assert(!ret); ++} ++ ++static void ++set_notification_remove_surface(struct ivi_layout_surface *ivisurf, ++ void *userdata) ++{ ++ struct hmi_controller *hmi_ctrl = userdata; ++ ++ switch_mode(hmi_ctrl, hmi_ctrl->layout_mode); ++} ++ ++static void ++set_notification_configure_surface(struct ivi_layout_surface *ivisurf, ++ void *userdata) ++{ ++ struct hmi_controller *hmi_ctrl = userdata; ++ ++ switch_mode(hmi_ctrl, hmi_ctrl->layout_mode); ++} ++ ++/** ++ * A hmi_controller used 4 ivi_layers to manage ivi_surfaces. The IDs of ++ * corresponding ivi_layer are defined in weston.ini. Default scene graph ++ * of ivi_layers are initialized in hmi_controller_create ++ */ ++static struct hmi_server_setting * ++hmi_server_setting_create(struct weston_compositor *ec) ++{ ++ struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting)); ++ struct weston_config *config = ec->config; ++ struct weston_config_section *shell_section = NULL; ++ ++ shell_section = weston_config_get_section(config, "ivi-shell", ++ NULL, NULL); ++ ++ weston_config_section_get_uint(shell_section, "base-layer-id", ++ &setting->base_layer_id, 1000); ++ ++ weston_config_section_get_uint(shell_section, ++ "workspace-background-layer-id", ++ &setting->workspace_background_layer_id, ++ 2000); ++ ++ weston_config_section_get_uint(shell_section, "workspace-layer-id", ++ &setting->workspace_layer_id, 3000); ++ ++ weston_config_section_get_uint(shell_section, "application-layer-id", ++ &setting->application_layer_id, 4000); ++ ++ weston_config_section_get_uint(shell_section, "transition-duration", ++ &setting->transition_duration, 300); ++ ++ setting->panel_height = 70; ++ ++ weston_config_section_get_string(shell_section, ++ "ivi-shell-user-interface", ++ &setting->ivi_homescreen, NULL); ++ ++ return setting; ++} ++ ++static void ++hmi_controller_destroy(struct wl_listener *listener, void *data) ++{ ++ struct link_layer *link = NULL; ++ struct link_layer *next = NULL; ++ struct hmi_controller *hmi_ctrl = ++ container_of(listener, struct hmi_controller, destroy_listener); ++ ++ wl_list_for_each_safe(link, next, ++ &hmi_ctrl->workspace_fade.layer_list, link) { ++ wl_list_remove(&link->link); ++ free(link); ++ } ++ ++ wl_array_release(&hmi_ctrl->ui_widgets); ++ free(hmi_ctrl->hmi_setting); ++ free(hmi_ctrl); ++} ++ ++/** ++ * This is a starting method called from module_init. ++ * This sets up scene graph of ivi_layers; base, application, workspace ++ * background, and workspace. These ivi_layers are created/added to ++ * ivi_screen in create_layer ++ * ++ * base: to group ivi_surfaces of panel and background ++ * application: to group ivi_surfaces of ivi_applications ++ * workspace background: to group a ivi_surface of background in workspace ++ * workspace: to group ivi_surfaces for launching ivi_applications ++ * ++ * ivi_layers of workspace background and workspace is set to invisible at ++ * first. The properties of it is updated with animation when ++ * ivi_hmi_controller_home is requested. ++ */ ++static struct hmi_controller * ++hmi_controller_create(struct weston_compositor *ec) ++{ ++ struct ivi_layout_screen **pp_screen = NULL; ++ struct ivi_layout_screen *iviscrn = NULL; ++ int32_t screen_length = 0; ++ int32_t screen_width = 0; ++ int32_t screen_height = 0; ++ struct link_layer *tmp_link_layer = NULL; ++ int32_t panel_height = 0; ++ struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl)); ++ ++ wl_array_init(&hmi_ctrl->ui_widgets); ++ hmi_ctrl->layout_mode = IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING; ++ hmi_ctrl->hmi_setting = hmi_server_setting_create(ec); ++ hmi_ctrl->compositor = ec; ++ ++ ivi_layout_get_screens(&screen_length, &pp_screen); ++ ++ iviscrn = pp_screen[0]; ++ ++ ivi_layout_get_screen_resolution(iviscrn, &screen_width, ++ &screen_height); ++ ++ /* init base ivi_layer*/ ++ hmi_ctrl->base_layer.x = 0; ++ hmi_ctrl->base_layer.y = 0; ++ hmi_ctrl->base_layer.width = screen_width; ++ hmi_ctrl->base_layer.height = screen_height; ++ hmi_ctrl->base_layer.id_layer = hmi_ctrl->hmi_setting->base_layer_id; ++ ++ create_layer(iviscrn, &hmi_ctrl->base_layer); ++ ++ panel_height = hmi_ctrl->hmi_setting->panel_height; ++ ++ /* init application ivi_layer */ ++ hmi_ctrl->application_layer.x = 0; ++ hmi_ctrl->application_layer.y = 0; ++ hmi_ctrl->application_layer.width = screen_width; ++ hmi_ctrl->application_layer.height = screen_height - panel_height; ++ hmi_ctrl->application_layer.id_layer = ++ hmi_ctrl->hmi_setting->application_layer_id; ++ ++ create_layer(iviscrn, &hmi_ctrl->application_layer); ++ ++ /* init workspace background ivi_layer */ ++ hmi_ctrl->workspace_background_layer.x = 0; ++ hmi_ctrl->workspace_background_layer.y = 0; ++ hmi_ctrl->workspace_background_layer.width = screen_width; ++ hmi_ctrl->workspace_background_layer.height = ++ screen_height - panel_height; ++ ++ hmi_ctrl->workspace_background_layer.id_layer = ++ hmi_ctrl->hmi_setting->workspace_background_layer_id; ++ ++ create_layer(iviscrn, &hmi_ctrl->workspace_background_layer); ++ ivi_layout_layer_set_opacity( ++ hmi_ctrl->workspace_background_layer.ivilayer, 0); ++ ivi_layout_layer_set_visibility( ++ hmi_ctrl->workspace_background_layer.ivilayer, false); ++ ++ /* init workspace ivi_layer */ ++ hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x; ++ hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y; ++ hmi_ctrl->workspace_layer.width = ++ hmi_ctrl->workspace_background_layer.width; ++ hmi_ctrl->workspace_layer.height = ++ hmi_ctrl->workspace_background_layer.height; ++ hmi_ctrl->workspace_layer.id_layer = ++ hmi_ctrl->hmi_setting->workspace_layer_id; ++ ++ create_layer(iviscrn, &hmi_ctrl->workspace_layer); ++ ivi_layout_layer_set_opacity(hmi_ctrl->workspace_layer.ivilayer, 0); ++ ivi_layout_layer_set_visibility(hmi_ctrl->workspace_layer.ivilayer, ++ false); ++ ++ wl_list_init(&hmi_ctrl->workspace_fade.layer_list); ++ tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer)); ++ tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer; ++ wl_list_insert(&hmi_ctrl->workspace_fade.layer_list, ++ &tmp_link_layer->link); ++ tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer)); ++ tmp_link_layer->layout_layer = ++ hmi_ctrl->workspace_background_layer.ivilayer; ++ wl_list_insert(&hmi_ctrl->workspace_fade.layer_list, ++ &tmp_link_layer->link); ++ ++ ivi_layout_add_notification_create_surface( ++ set_notification_create_surface, hmi_ctrl); ++ ivi_layout_add_notification_remove_surface( ++ set_notification_remove_surface, hmi_ctrl); ++ ivi_layout_add_notification_configure_surface( ++ set_notification_configure_surface, hmi_ctrl); ++ ++ hmi_ctrl->destroy_listener.notify = hmi_controller_destroy; ++ wl_signal_add(&hmi_ctrl->compositor->destroy_signal, ++ &hmi_ctrl->destroy_listener); ++ ++ free(pp_screen); ++ pp_screen = NULL; ++ ++ return hmi_ctrl; ++} ++ ++/** ++ * Implementations of ivi-hmi-controller.xml ++ */ ++ ++/** ++ * A ivi_surface drawing background is identified by id_surface. ++ * Properties of the ivi_surface is set by using ivi_layout APIs according to ++ * the scene graph of UI defined in hmi_controller_create. ++ * ++ * UI ivi_layer is used to add this ivi_surface. ++ */ ++static void ++ivi_hmi_controller_set_background(struct hmi_controller *hmi_ctrl, ++ uint32_t id_surface) ++{ ++ struct ivi_layout_surface *ivisurf = NULL; ++ struct ivi_layout_layer *ivilayer = hmi_ctrl->base_layer.ivilayer; ++ const int32_t dstx = hmi_ctrl->application_layer.x; ++ const int32_t dsty = hmi_ctrl->application_layer.y; ++ const int32_t width = hmi_ctrl->application_layer.width; ++ const int32_t height = hmi_ctrl->application_layer.height; ++ int32_t ret = 0; ++ ++ uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets, ++ sizeof(*add_surface_id)); ++ *add_surface_id = id_surface; ++ ++ ivisurf = ivi_layout_get_surface_from_id(id_surface); ++ assert(ivisurf != NULL); ++ ++ ret = ivi_layout_layer_add_surface(ivilayer, ivisurf); ++ assert(!ret); ++ ++ ret = ivi_layout_surface_set_destination_rectangle(ivisurf, ++ dstx, dsty, width, height); ++ assert(!ret); ++ ++ ret = ivi_layout_surface_set_visibility(ivisurf, true); ++ assert(!ret); ++} ++ ++/** ++ * A ivi_surface drawing panel is identified by id_surface. ++ * Properties of the ivi_surface is set by using ivi_layout APIs according to ++ * the scene graph of UI defined in hmi_controller_create. ++ * ++ * UI ivi_layer is used to add this ivi_surface. ++ */ ++static void ++ivi_hmi_controller_set_panel(struct hmi_controller *hmi_ctrl, ++ uint32_t id_surface) ++{ ++ struct ivi_layout_surface *ivisurf = NULL; ++ struct ivi_layout_layer *ivilayer = hmi_ctrl->base_layer.ivilayer; ++ const int32_t width = hmi_ctrl->base_layer.width; ++ int32_t ret = 0; ++ int32_t panel_height = 0; ++ const int32_t dstx = 0; ++ int32_t dsty = 0; ++ ++ uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets, ++ sizeof(*add_surface_id)); ++ *add_surface_id = id_surface; ++ ++ ivisurf = ivi_layout_get_surface_from_id(id_surface); ++ assert(ivisurf != NULL); ++ ++ ret = ivi_layout_layer_add_surface(ivilayer, ivisurf); ++ assert(!ret); ++ ++ panel_height = hmi_ctrl->hmi_setting->panel_height; ++ ++ dsty = hmi_ctrl->base_layer.height - panel_height; ++ ++ ret = ivi_layout_surface_set_destination_rectangle( ++ ivisurf, dstx, dsty, width, panel_height); ++ assert(!ret); ++ ++ ret = ivi_layout_surface_set_visibility(ivisurf, true); ++ assert(!ret); ++} ++ ++/** ++ * A ivi_surface drawing buttons in panel is identified by id_surface. ++ * It can set several buttons. Properties of the ivi_surface is set by ++ * using ivi_layout APIs according to the scene graph of UI defined in ++ * hmi_controller_create. Additionally, the position of it is shifted to ++ * right when new one is requested. ++ * ++ * UI ivi_layer is used to add these ivi_surfaces. ++ */ ++static void ++ivi_hmi_controller_set_button(struct hmi_controller *hmi_ctrl, ++ uint32_t id_surface, int32_t number) ++{ ++ struct ivi_layout_surface *ivisurf = NULL; ++ struct ivi_layout_layer *ivilayer = hmi_ctrl->base_layer.ivilayer; ++ const int32_t width = 48; ++ const int32_t height = 48; ++ int32_t ret = 0; ++ int32_t panel_height = 0; ++ int32_t dstx = 0; ++ int32_t dsty = 0; ++ uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets, ++ sizeof(*add_surface_id)); ++ *add_surface_id = id_surface; ++ ++ ivisurf = ivi_layout_get_surface_from_id(id_surface); ++ assert(ivisurf != NULL); ++ ++ ret = ivi_layout_layer_add_surface(ivilayer, ivisurf); ++ assert(!ret); ++ ++ panel_height = hmi_ctrl->hmi_setting->panel_height; ++ ++ dstx = (60 * number) + 15; ++ dsty = (hmi_ctrl->base_layer.height - panel_height) + 5; ++ ++ ret = ivi_layout_surface_set_destination_rectangle( ++ ivisurf,dstx, dsty, width, height); ++ assert(!ret); ++ ++ ret = ivi_layout_surface_set_visibility(ivisurf, true); ++ assert(!ret); ++} ++ ++/** ++ * A ivi_surface drawing home button in panel is identified by id_surface. ++ * Properties of the ivi_surface is set by using ivi_layout APIs according to ++ * the scene graph of UI defined in hmi_controller_create. ++ * ++ * UI ivi_layer is used to add these ivi_surfaces. ++ */ ++static void ++ivi_hmi_controller_set_home_button(struct hmi_controller *hmi_ctrl, ++ uint32_t id_surface) ++{ ++ struct ivi_layout_surface *ivisurf = NULL; ++ struct ivi_layout_layer *ivilayer = hmi_ctrl->base_layer.ivilayer; ++ int32_t ret = 0; ++ int32_t size = 48; ++ int32_t panel_height = hmi_ctrl->hmi_setting->panel_height; ++ const int32_t dstx = (hmi_ctrl->base_layer.width - size) / 2; ++ const int32_t dsty = (hmi_ctrl->base_layer.height - panel_height) + 5; ++ ++ uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets, ++ sizeof(*add_surface_id)); ++ *add_surface_id = id_surface; ++ ++ ivisurf = ivi_layout_get_surface_from_id(id_surface); ++ assert(ivisurf != NULL); ++ ++ ret = ivi_layout_layer_add_surface(ivilayer, ivisurf); ++ assert(!ret); ++ ++ ret = ivi_layout_surface_set_destination_rectangle( ++ ivisurf, dstx, dsty, size, size); ++ assert(!ret); ++ ++ ret = ivi_layout_surface_set_visibility(ivisurf, true); ++ assert(!ret); ++} ++ ++/** ++ * A ivi_surface drawing background of workspace is identified by id_surface. ++ * Properties of the ivi_surface is set by using ivi_layout APIs according to ++ * the scene graph of UI defined in hmi_controller_create. ++ * ++ * A ivi_layer of workspace_background is used to add this ivi_surface. ++ */ ++static void ++ivi_hmi_controller_set_workspacebackground(struct hmi_controller *hmi_ctrl, ++ uint32_t id_surface) ++{ ++ struct ivi_layout_surface *ivisurf = NULL; ++ struct ivi_layout_layer *ivilayer = NULL; ++ const int32_t width = hmi_ctrl->workspace_background_layer.width; ++ const int32_t height = hmi_ctrl->workspace_background_layer.height; ++ int32_t ret = 0; ++ ++ uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets, ++ sizeof(*add_surface_id)); ++ *add_surface_id = id_surface; ++ ivilayer = hmi_ctrl->workspace_background_layer.ivilayer; ++ ++ ivisurf = ivi_layout_get_surface_from_id(id_surface); ++ assert(ivisurf != NULL); ++ ++ ret = ivi_layout_layer_add_surface(ivilayer, ivisurf); ++ assert(!ret); ++ ++ ret = ivi_layout_surface_set_destination_rectangle(ivisurf, ++ 0, 0, width, height); ++ assert(!ret); ++ ++ ret = ivi_layout_surface_set_visibility(ivisurf, true); ++ assert(!ret); ++} ++ ++/** ++ * A list of ivi_surfaces drawing launchers in workspace is identified by ++ * id_surfaces. Properties of the ivi_surface is set by using ivi_layout ++ * APIs according to the scene graph of UI defined in hmi_controller_create. ++ * ++ * The workspace can have several pages to group ivi_surfaces of launcher. ++ * Each call of this interface increments a number of page to add a group ++ * of ivi_surfaces ++ */ ++static void ++ivi_hmi_controller_add_launchers(struct wl_resource *resource, ++ int32_t icon_size) ++{ ++ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); ++ struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer; ++ int32_t minspace_x = 10; ++ int32_t minspace_y = minspace_x; ++ ++ int32_t width = hmi_ctrl->workspace_layer.width; ++ int32_t height = hmi_ctrl->workspace_layer.height; ++ ++ int32_t x_count = (width - minspace_x) / (minspace_x + icon_size); ++ int32_t space_x = (int32_t)((width - x_count * icon_size) / (1.0 + x_count)); ++ float fcell_size_x = icon_size + space_x; ++ ++ int32_t y_count = (height - minspace_y) / (minspace_y + icon_size); ++ int32_t space_y = (int32_t)((height - y_count * icon_size) / (1.0 + y_count)); ++ float fcell_size_y = icon_size + space_y; ++ ++ struct weston_config *config = NULL; ++ struct weston_config_section *section = NULL; ++ const char *name = NULL; ++ int launcher_count = 0; ++ struct wl_array launchers; ++ int32_t nx = 0; ++ int32_t ny = 0; ++ int32_t prev = -1; ++ struct launcher_info *data = NULL; ++ ++ uint32_t surfaceid = 0; ++ uint32_t workspaceid = 0; ++ struct launcher_info *info = NULL; ++ ++ int32_t x = 0; ++ int32_t y = 0; ++ int32_t ret = 0; ++ struct ivi_layout_surface* layout_surface = NULL; ++ uint32_t *add_surface_id = NULL; ++ ++ if (0 == x_count) ++ x_count = 1; ++ ++ if (0 == y_count) ++ y_count = 1; ++ ++ config = hmi_ctrl->compositor->config; ++ if (!config) ++ return; ++ ++ section = weston_config_get_section(config, "ivi-shell", NULL, NULL); ++ if (!section) ++ return; ++ ++ wl_array_init(&launchers); ++ ++ while (weston_config_next_section(config, §ion, &name)) { ++ surfaceid = 0; ++ workspaceid = 0; ++ info = NULL; ++ if (0 != strcmp(name, "ivi-launcher")) ++ continue; ++ ++ if (0 != weston_config_section_get_uint(section, "icon-id", ++ &surfaceid, 0)) ++ continue; ++ ++ if (0 != weston_config_section_get_uint(section, ++ "workspace-id", ++ &workspaceid, 0)) ++ continue; ++ ++ info = wl_array_add(&launchers, sizeof(*info)); ++ ++ if (info) { ++ info->surface_id = surfaceid; ++ info->workspace_id = workspaceid; ++ info->index = launcher_count; ++ ++launcher_count; ++ } ++ } ++ ++ qsort(launchers.data, launcher_count, sizeof(struct launcher_info), ++ compare_launcher_info); ++ ++ wl_array_for_each(data, &launchers) { ++ x = 0; ++ y = 0; ++ ret = 0; ++ layout_surface = NULL; ++ add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets, ++ sizeof(*add_surface_id)); ++ ++ *add_surface_id = data->surface_id; ++ ++ if (0 > prev || (uint32_t)prev != data->workspace_id) { ++ nx = 0; ++ ny = 0; ++ prev = data->workspace_id; ++ ++ if (0 <= prev) ++ hmi_ctrl->workspace_count++; ++ } ++ ++ if (y_count == ny) { ++ ny = 0; ++ hmi_ctrl->workspace_count++; ++ } ++ ++ x = nx * fcell_size_x + (hmi_ctrl->workspace_count - 1) * width + space_x; ++ y = ny * fcell_size_y + space_y; ++ ++ layout_surface = ++ ivi_layout_get_surface_from_id(data->surface_id); ++ assert(layout_surface); ++ ++ ret = ivi_layout_layer_add_surface(layer, layout_surface); ++ assert(!ret); ++ ++ ret = ivi_layout_surface_set_destination_rectangle( ++ layout_surface, x, y, icon_size, icon_size); ++ assert(!ret); ++ ++ ret = ivi_layout_surface_set_visibility(layout_surface, true); ++ assert(!ret); ++ ++ nx++; ++ ++ if (x_count == nx) { ++ ny++; ++ nx = 0; ++ } ++ } ++ ++ wl_array_release(&launchers); ++ ivi_layout_commit_changes(); ++} ++ ++static void ++ivi_hmi_controller_UI_ready(struct wl_client *client, ++ struct wl_resource *resource) ++{ ++ struct setting { ++ uint32_t background_id; ++ uint32_t panel_id; ++ uint32_t tiling_id; ++ uint32_t sidebyside_id; ++ uint32_t fullscreen_id; ++ uint32_t random_id; ++ uint32_t home_id; ++ uint32_t workspace_background_id; ++ }; ++ ++ struct config_command { ++ char *key; ++ uint32_t *dest; ++ }; ++ ++ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); ++ struct weston_config *config = hmi_ctrl->compositor->config; ++ struct weston_config_section *section = NULL; ++ struct setting dest; ++ int result = 0; ++ int i = 0; ++ ++ const struct config_command uint_commands[] = { ++ { "background-id", &dest.background_id }, ++ { "panel-id", &dest.panel_id }, ++ { "tiling-id", &dest.tiling_id }, ++ { "sidebyside-id", &dest.sidebyside_id }, ++ { "fullscreen-id", &dest.fullscreen_id }, ++ { "random-id", &dest.random_id }, ++ { "home-id", &dest.home_id }, ++ { "workspace-background-id", &dest.workspace_background_id }, ++ { NULL, NULL } ++ }; ++ ++ section = weston_config_get_section(config, "ivi-shell", NULL, NULL); ++ ++ for (i = 0; -1 != result; ++i) { ++ const struct config_command *command = &uint_commands[i]; ++ ++ if (!command->key) ++ break; ++ ++ if (weston_config_section_get_uint( ++ section, command->key, command->dest, 0) != 0) ++ result = -1; ++ } ++ ++ if (-1 == result) { ++ wl_resource_post_error(resource, ++ IVI_HMI_CONTROLLER_ERROR_CODE_INIT_FAILED, ++ "Failed to initialize hmi-controller."); ++ return; ++ } ++ ++ ivi_hmi_controller_set_background(hmi_ctrl, dest.background_id); ++ ivi_hmi_controller_set_panel(hmi_ctrl, dest.panel_id); ++ ivi_hmi_controller_set_button(hmi_ctrl, dest.tiling_id, 0); ++ ivi_hmi_controller_set_button(hmi_ctrl, dest.sidebyside_id, 1); ++ ivi_hmi_controller_set_button(hmi_ctrl, dest.fullscreen_id, 2); ++ ivi_hmi_controller_set_button(hmi_ctrl, dest.random_id, 3); ++ ivi_hmi_controller_set_home_button(hmi_ctrl, dest.home_id); ++ ivi_hmi_controller_set_workspacebackground(hmi_ctrl, ++ dest.workspace_background_id); ++ ivi_layout_commit_changes(); ++ ++ ivi_hmi_controller_add_launchers(resource, 256); ++ hmi_ctrl->is_initialized = 1; ++} ++ ++/** ++ * Implementation of request and event of ivi_hmi_controller_workspace_control ++ * and controlling workspace. ++ * ++ * When motion of input is detected in a ivi_surface of workspace background, ++ * ivi_hmi_controller_workspace_control shall be invoked and to start ++ * controlling of workspace. The workspace has several pages to show several ++ * groups of applications. ++ * The workspace is slid by using ivi-layout to select a a page in layer_set_pos ++ * according to motion. When motion finished, e.g. touch up detected, control is ++ * terminated and event:ivi_hmi_controller_workspace_control is notified. ++ */ ++struct pointer_grab { ++ struct weston_pointer_grab grab; ++ struct ivi_layout_layer *layer; ++ struct wl_resource *resource; ++}; ++ ++struct touch_grab { ++ struct weston_touch_grab grab; ++ struct ivi_layout_layer *layer; ++ struct wl_resource *resource; ++}; ++ ++struct move_grab { ++ wl_fixed_t dst[2]; ++ wl_fixed_t rgn[2][2]; ++ double v[2]; ++ struct timespec start_time; ++ struct timespec pre_time; ++ wl_fixed_t start_pos[2]; ++ wl_fixed_t pos[2]; ++ int32_t is_moved; ++}; ++ ++struct pointer_move_grab { ++ struct pointer_grab base; ++ struct move_grab move; ++}; ++ ++struct touch_move_grab { ++ struct touch_grab base; ++ struct move_grab move; ++ int32_t is_active; ++}; ++ ++static void ++pointer_grab_start(struct pointer_grab *grab, ++ struct ivi_layout_layer *layer, ++ const struct weston_pointer_grab_interface *interface, ++ struct weston_pointer *pointer) ++{ ++ grab->grab.interface = interface; ++ grab->layer = layer; ++ weston_pointer_start_grab(pointer, &grab->grab); ++} ++ ++static void ++touch_grab_start(struct touch_grab *grab, ++ struct ivi_layout_layer *layer, ++ const struct weston_touch_grab_interface *interface, ++ struct weston_touch* touch) ++{ ++ grab->grab.interface = interface; ++ grab->layer = layer; ++ weston_touch_start_grab(touch, &grab->grab); ++} ++ ++static int32_t ++clamp(int32_t val, int32_t min, int32_t max) ++{ ++ if (val < min) ++ return min; ++ ++ if (max < val) ++ return max; ++ ++ return val; ++} ++ ++static void ++move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource, ++ wl_fixed_t grab_x, struct ivi_layout_layer *layer) ++{ ++ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); ++ int32_t width = hmi_ctrl->workspace_background_layer.width; ++ ++ struct timespec time = {0}; ++ double grab_time = 0.0; ++ double from_motion_time = 0.0; ++ double pointer_v = 0.0; ++ int32_t is_flick = 0; ++ int32_t pos_x = 0; ++ int32_t pos_y = 0; ++ int page_no = 0; ++ double end_pos = 0.0; ++ uint32_t duration = 0; ++ ++ clock_gettime(CLOCK_MONOTONIC, &time); ++ ++ grab_time = 1e+3 * (time.tv_sec - move->start_time.tv_sec) + ++ 1e-6 * (time.tv_nsec - move->start_time.tv_nsec); ++ ++ from_motion_time = 1e+3 * (time.tv_sec - move->pre_time.tv_sec) + ++ 1e-6 * (time.tv_nsec - move->pre_time.tv_nsec); ++ ++ pointer_v = move->v[0]; ++ ++ is_flick = grab_time < 400 && 0.4 < fabs(pointer_v); ++ if (200 < from_motion_time) ++ pointer_v = 0.0; ++ ++ ivi_layout_layer_get_position(layer, &pos_x, &pos_y); ++ ++ ++ if (is_flick) { ++ int orgx = wl_fixed_to_int(move->dst[0] + grab_x); ++ page_no = (-orgx + width / 2) / width; ++ ++ if (pointer_v < 0.0) ++ page_no++; ++ else ++ page_no--; ++ } else { ++ page_no = (-pos_x + width / 2) / width; ++ } ++ ++ page_no = clamp(page_no, 0, hmi_ctrl->workspace_count - 1); ++ end_pos = -page_no * width; ++ ++ duration = hmi_ctrl->hmi_setting->transition_duration; ++ ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved); ++ ivi_layout_layer_set_transition(layer, ++ IVI_LAYOUT_TRANSITION_LAYER_MOVE, ++ duration); ++ ivi_layout_layer_set_destination_rectangle(layer, ++ end_pos, pos_y, ++ hmi_ctrl->workspace_background_layer.width, ++ hmi_ctrl->workspace_background_layer.height); ++ ivi_layout_commit_changes(); ++} ++ ++static void ++pointer_move_workspace_grab_end(struct pointer_grab *grab) ++{ ++ struct pointer_move_grab *pnt_move_grab = ++ (struct pointer_move_grab *)grab; ++ struct ivi_layout_layer *layer = pnt_move_grab->base.layer; ++ ++ move_workspace_grab_end(&pnt_move_grab->move, grab->resource, ++ grab->grab.pointer->grab_x, layer); ++ ++ weston_pointer_end_grab(grab->grab.pointer); ++} ++ ++static void ++touch_move_workspace_grab_end(struct touch_grab *grab) ++{ ++ struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab; ++ struct ivi_layout_layer *layer = tch_move_grab->base.layer; ++ ++ move_workspace_grab_end(&tch_move_grab->move, grab->resource, ++ grab->grab.touch->grab_x, layer); ++ ++ weston_touch_end_grab(grab->grab.touch); ++} ++ ++static void ++pointer_noop_grab_focus(struct weston_pointer_grab *grab) ++{ ++} ++ ++static void ++move_grab_update(struct move_grab *move, wl_fixed_t pointer[2]) ++{ ++ struct timespec timestamp = {0}; ++ int32_t ii = 0; ++ double dt = 0.0; ++ ++ clock_gettime(CLOCK_MONOTONIC, ×tamp); //FIXME ++ dt = (1e+3 * (timestamp.tv_sec - move->pre_time.tv_sec) + ++ 1e-6 * (timestamp.tv_nsec - move->pre_time.tv_nsec)); ++ ++ if (dt < 1e-6) ++ dt = 1e-6; ++ ++ move->pre_time = timestamp; ++ ++ for (ii = 0; ii < 2; ii++) { ++ wl_fixed_t prepos = move->pos[ii]; ++ move->pos[ii] = pointer[ii] + move->dst[ii]; ++ ++ if (move->pos[ii] < move->rgn[0][ii]) { ++ move->pos[ii] = move->rgn[0][ii]; ++ move->dst[ii] = move->pos[ii] - pointer[ii]; ++ } else if (move->rgn[1][ii] < move->pos[ii]) { ++ move->pos[ii] = move->rgn[1][ii]; ++ move->dst[ii] = move->pos[ii] - pointer[ii]; ++ } ++ ++ move->v[ii] = wl_fixed_to_double(move->pos[ii] - prepos) / dt; ++ ++ if (!move->is_moved && ++ 0 < wl_fixed_to_int(move->pos[ii] - move->start_pos[ii])) ++ move->is_moved = 1; ++ } ++} ++ ++static void ++layer_set_pos(struct ivi_layout_layer *layer, wl_fixed_t pos_x, ++ wl_fixed_t pos_y) ++{ ++ int32_t layout_pos_x = 0; ++ int32_t layout_pos_y = 0; ++ ++ layout_pos_x = wl_fixed_to_int(pos_x); ++ layout_pos_y = wl_fixed_to_int(pos_y); ++ ivi_layout_layer_set_position(layer, layout_pos_x, layout_pos_y); ++ ivi_layout_commit_changes(); ++} ++ ++static void ++pointer_move_grab_motion(struct weston_pointer_grab *grab, uint32_t time, ++ wl_fixed_t x, wl_fixed_t y) ++{ ++ struct pointer_move_grab *pnt_move_grab = ++ (struct pointer_move_grab *)grab; ++ wl_fixed_t pointer_pos[2] = {x, y}; ++ ++ move_grab_update(&pnt_move_grab->move, pointer_pos); ++ layer_set_pos(pnt_move_grab->base.layer, ++ pnt_move_grab->move.pos[0], pnt_move_grab->move.pos[1]); ++ weston_pointer_move(pnt_move_grab->base.grab.pointer, x, y); ++} ++ ++static void ++touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time, ++ int touch_id, wl_fixed_t x, wl_fixed_t y) ++{ ++ struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab; ++ ++ if (!tch_move_grab->is_active) ++ return; ++ ++ wl_fixed_t pointer_pos[2] = { ++ grab->touch->grab_x, ++ grab->touch->grab_y ++ }; ++ ++ move_grab_update(&tch_move_grab->move, pointer_pos); ++ layer_set_pos(tch_move_grab->base.layer, ++ tch_move_grab->move.pos[0], tch_move_grab->move.pos[1]); ++} ++ ++static void ++pointer_move_workspace_grab_button(struct weston_pointer_grab *grab, ++ uint32_t time, uint32_t button, ++ uint32_t state_w) ++{ ++ if (BTN_LEFT == button && ++ WL_POINTER_BUTTON_STATE_RELEASED == state_w) { ++ struct pointer_grab *pg = (struct pointer_grab *)grab; ++ ++ pointer_move_workspace_grab_end(pg); ++ free(grab); ++ } ++} ++ ++static void ++touch_nope_grab_down(struct weston_touch_grab *grab, uint32_t time, ++ int touch_id, wl_fixed_t sx, wl_fixed_t sy) ++{ ++} ++ ++static void ++touch_move_workspace_grab_up(struct weston_touch_grab *grab, uint32_t time, ++ int touch_id) ++{ ++ struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab; ++ ++ if (0 == touch_id) ++ tch_move_grab->is_active = 0; ++ ++ if (0 == grab->touch->num_tp) { ++ touch_move_workspace_grab_end(&tch_move_grab->base); ++ free(grab); ++ } ++} ++ ++static void ++pointer_move_workspace_grab_cancel(struct weston_pointer_grab *grab) ++{ ++ struct pointer_grab *pg = (struct pointer_grab *)grab; ++ ++ pointer_move_workspace_grab_end(pg); ++ free(grab); ++} ++ ++static void ++touch_move_workspace_grab_cancel(struct weston_touch_grab *grab) ++{ ++ struct touch_grab *tg = (struct touch_grab *)grab; ++ ++ touch_move_workspace_grab_end(tg); ++ free(grab); ++} ++ ++static const struct weston_pointer_grab_interface pointer_move_grab_workspace_interface = { ++ pointer_noop_grab_focus, ++ pointer_move_grab_motion, ++ pointer_move_workspace_grab_button, ++ pointer_move_workspace_grab_cancel ++}; ++ ++static const struct weston_touch_grab_interface touch_move_grab_workspace_interface = { ++ touch_nope_grab_down, ++ touch_move_workspace_grab_up, ++ touch_move_grab_motion, ++ touch_move_workspace_grab_cancel ++}; ++ ++enum HMI_GRAB_DEVICE { ++ HMI_GRAB_DEVICE_NONE, ++ HMI_GRAB_DEVICE_POINTER, ++ HMI_GRAB_DEVICE_TOUCH ++}; ++ ++static enum HMI_GRAB_DEVICE ++get_hmi_grab_device(struct weston_seat *seat, uint32_t serial) ++{ ++ if (seat->pointer && ++ seat->pointer->focus && ++ seat->pointer->button_count && ++ seat->pointer->grab_serial == serial) ++ return HMI_GRAB_DEVICE_POINTER; ++ ++ if (seat->touch && ++ seat->touch->focus && ++ seat->touch->grab_serial == serial) ++ return HMI_GRAB_DEVICE_TOUCH; ++ ++ return HMI_GRAB_DEVICE_NONE; ++} ++ ++static void ++move_grab_init(struct move_grab* move, wl_fixed_t start_pos[2], ++ wl_fixed_t grab_pos[2], wl_fixed_t rgn[2][2], ++ struct wl_resource* resource) ++{ ++ clock_gettime(CLOCK_MONOTONIC, &move->start_time); //FIXME ++ move->pre_time = move->start_time; ++ move->pos[0] = start_pos[0]; ++ move->pos[1] = start_pos[1]; ++ move->start_pos[0] = start_pos[0]; ++ move->start_pos[1] = start_pos[1]; ++ move->dst[0] = start_pos[0] - grab_pos[0]; ++ move->dst[1] = start_pos[1] - grab_pos[1]; ++ memcpy(move->rgn, rgn, sizeof(move->rgn)); ++} ++ ++static void ++move_grab_init_workspace(struct move_grab* move, ++ wl_fixed_t grab_x, wl_fixed_t grab_y, ++ struct wl_resource *resource) ++{ ++ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); ++ struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer; ++ int32_t workspace_count = hmi_ctrl->workspace_count; ++ int32_t workspace_width = hmi_ctrl->workspace_background_layer.width; ++ int32_t layer_pos_x = 0; ++ int32_t layer_pos_y = 0; ++ wl_fixed_t start_pos[2] = {0}; ++ wl_fixed_t rgn[2][2] = {{0}}; ++ wl_fixed_t grab_pos[2] = { grab_x, grab_y }; ++ ++ ivi_layout_layer_get_position(layer, &layer_pos_x, &layer_pos_y); ++ ++ start_pos[0] = wl_fixed_from_int(layer_pos_x); ++ start_pos[1] = wl_fixed_from_int(layer_pos_y); ++ ++ rgn[0][0] = wl_fixed_from_int(-workspace_width * (workspace_count - 1)); ++ ++ rgn[0][1] = wl_fixed_from_int(0); ++ rgn[1][0] = wl_fixed_from_int(0); ++ rgn[1][1] = wl_fixed_from_int(0); ++ ++ move_grab_init(move, start_pos, grab_pos, rgn, resource); ++} ++ ++static struct pointer_move_grab * ++create_workspace_pointer_move(struct weston_pointer *pointer, ++ struct wl_resource* resource) ++{ ++ struct pointer_move_grab *pnt_move_grab = ++ MEM_ALLOC(sizeof(*pnt_move_grab)); ++ ++ pnt_move_grab->base.resource = resource; ++ move_grab_init_workspace(&pnt_move_grab->move, pointer->grab_x, ++ pointer->grab_y, resource); ++ ++ return pnt_move_grab; ++} ++ ++static struct touch_move_grab * ++create_workspace_touch_move(struct weston_touch *touch, ++ struct wl_resource* resource) ++{ ++ struct touch_move_grab *tch_move_grab = ++ MEM_ALLOC(sizeof(*tch_move_grab)); ++ ++ tch_move_grab->base.resource = resource; ++ tch_move_grab->is_active = 1; ++ move_grab_init_workspace(&tch_move_grab->move, touch->grab_x, ++ touch->grab_y, resource); ++ ++ return tch_move_grab; ++} ++ ++static void ++ivi_hmi_controller_workspace_control(struct wl_client *client, ++ struct wl_resource *resource, ++ struct wl_resource *seat_resource, ++ uint32_t serial) ++{ ++ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); ++ struct ivi_layout_layer *layer = NULL; ++ struct pointer_move_grab *pnt_move_grab = NULL; ++ struct touch_move_grab *tch_move_grab = NULL; ++ struct weston_seat *seat = NULL; ++ enum HMI_GRAB_DEVICE device; ++ ++ if (hmi_ctrl->workspace_count < 2) ++ return; ++ ++ seat = wl_resource_get_user_data(seat_resource); ++ device = get_hmi_grab_device(seat, serial); ++ ++ if (HMI_GRAB_DEVICE_POINTER != device && ++ HMI_GRAB_DEVICE_TOUCH != device) ++ return; ++ ++ layer = hmi_ctrl->workspace_layer.ivilayer; ++ ++ ivi_layout_transition_move_layer_cancel(layer); ++ ++ switch (device) { ++ case HMI_GRAB_DEVICE_POINTER: ++ pnt_move_grab = create_workspace_pointer_move(seat->pointer, ++ resource); ++ ++ pointer_grab_start(&pnt_move_grab->base, layer, ++ &pointer_move_grab_workspace_interface, ++ seat->pointer); ++ break; ++ ++ case HMI_GRAB_DEVICE_TOUCH: ++ tch_move_grab = create_workspace_touch_move(seat->touch, ++ resource); ++ ++ touch_grab_start(&tch_move_grab->base, layer, ++ &touch_move_grab_workspace_interface, ++ seat->touch); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++/** ++ * Implementation of switch_mode ++ */ ++static void ++ivi_hmi_controller_switch_mode(struct wl_client *client, ++ struct wl_resource *resource, ++ uint32_t layout_mode) ++{ ++ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); ++ ++ switch_mode(hmi_ctrl, layout_mode); ++} ++ ++/** ++ * Implementation of on/off displaying workspace and workspace background ++ * ivi_layers. ++ */ ++static void ++ivi_hmi_controller_home(struct wl_client *client, ++ struct wl_resource *resource, ++ uint32_t home) ++{ ++ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); ++ uint32_t is_fade_in; ++ ++ if ((IVI_HMI_CONTROLLER_HOME_ON == home && ++ !hmi_ctrl->workspace_fade.is_fade_in) || ++ (IVI_HMI_CONTROLLER_HOME_OFF == home && ++ hmi_ctrl->workspace_fade.is_fade_in)) { ++ is_fade_in = !hmi_ctrl->workspace_fade.is_fade_in; ++ hmi_controller_fade_run(hmi_ctrl, is_fade_in, ++ &hmi_ctrl->workspace_fade); ++ } ++ ++ ivi_layout_commit_changes(); ++} ++ ++/** ++ * binding ivi-hmi-controller implementation ++ */ ++static const struct ivi_hmi_controller_interface ivi_hmi_controller_implementation = { ++ ivi_hmi_controller_UI_ready, ++ ivi_hmi_controller_workspace_control, ++ ivi_hmi_controller_switch_mode, ++ ivi_hmi_controller_home ++}; ++ ++static void ++unbind_hmi_controller(struct wl_resource *resource) ++{ ++} ++ ++static void ++bind_hmi_controller(struct wl_client *client, ++ void *data, uint32_t version, uint32_t id) ++{ ++ struct wl_resource *resource = NULL; ++ struct hmi_controller *hmi_ctrl = data; ++ ++ if (hmi_ctrl->user_interface != client) { ++ wl_resource_post_error(resource, ++ WL_DISPLAY_ERROR_INVALID_OBJECT, ++ "hmi-controller failed: permission denied"); ++ return; ++ } ++ ++ resource = wl_resource_create( ++ client, &ivi_hmi_controller_interface, 1, id); ++ ++ wl_resource_set_implementation( ++ resource, &ivi_hmi_controller_implementation, ++ hmi_ctrl, unbind_hmi_controller); ++} ++ ++static void ++launch_hmi_client_process(void *data) ++{ ++ struct hmi_controller *hmi_ctrl = ++ (struct hmi_controller *)data; ++ ++ hmi_ctrl->user_interface = ++ weston_client_start(hmi_ctrl->compositor, ++ hmi_ctrl->hmi_setting->ivi_homescreen); ++ ++ free(hmi_ctrl->hmi_setting->ivi_homescreen); ++} ++ ++/***************************************************************************** ++ * exported functions ++ ****************************************************************************/ ++ ++WL_EXPORT int ++module_init(struct weston_compositor *ec, ++ int *argc, char *argv[]) ++{ ++ struct hmi_controller *hmi_ctrl = hmi_controller_create(ec); ++ struct wl_event_loop *loop = NULL; ++ ++ if (wl_global_create(ec->wl_display, ++ &ivi_hmi_controller_interface, 1, ++ hmi_ctrl, bind_hmi_controller) == NULL) { ++ return -1; ++ } ++ ++ loop = wl_display_get_event_loop(ec->wl_display); ++ wl_event_loop_add_idle(loop, launch_hmi_client_process, hmi_ctrl); ++ ++ return 0; ++} +-- +1.7.9.5 + diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0007-clients-a-reference-implementation-of-UI-client-how-.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0007-clients-a-reference-implementation-of-UI-client-how-.patch new file mode 100644 index 0000000..45f9550 --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0007-clients-a-reference-implementation-of-UI-client-how-.patch @@ -0,0 +1,1600 @@ +From 82eab90f7842cefa60fbeaa000acc4ae71f7ff8b Mon Sep 17 00:00:00 2001 +From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +Date: Mon, 27 Oct 2014 11:17:51 +0900 +Subject: [PATCH 07/15] clients: a reference implementation of UI client how + to use ivi-hmi-controller. + +- introduces ivi-shell-user-interface.c + +This is launched from hmi-controller by launch_hmi_client_process and +invoke a +client process. + +The basic flow is as followed, +1/ process invoked +2/ read configuration from weston.ini. +3/ draw png file to surface according to configuration of weston.ini +4/ all parts of UI are ready. request "UI_ready" to draw UI. +5/ Enter event loop +6/ If a surface receives touch/pointer event, followings are invoked +according + to type of event and surface +6-1/ If a surface to launch ivi_application receive touch up, it execs + ivi-application configured in weston.ini. +6-2/ If a surface to switch layout mode receive touch up, it sends a +request, + ivi_hmi_controller_switch_mode, to hmi-controller. +6-3/ If a surface to show workspace having launchers, it sends a +request, + ivi_hmi_controller_home, to hmi-controller. +6-4/ If touch down events happens in workspace, + ivi_hmi_controller_workspace_control is sent to slide workspace. + When control finished, event: +ivi_hmi_controller_workspace_end_control + is received. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: remove pthread.h from ivi-shell-user-interface.c + +it doesn't refer it anymore. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- + +clients: Change SIGTERM form SIGKILL + +> I cannot say, that 'volatile' in this case is wrong. It might even be necessary, +> since you are changing it from a signal handler, which I probably overlooked. +> Another mixup I might had is that this volatile is accessed "directly" +> rather than through a pointer. There was something about variables accessed +> through a pointer behaving slightly differently... +> Anyway, since it's modified from a signal handler, keep the 'volatile'. +> I likely have my own misconceptions about 'volatile'. +> Btw. you cannot catch SIGKILL. Do you need to catch any signals? This code +> makes the program exit with EXIT_SUCCESS even if killed by SIGINT. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +user_interface reference. Update Makefile.am +add xml to BUILT_SOURCES + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface, remove pthread from comment + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface, remove declarations in the middle + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface, remove casts to (void) + +> I don't think we need these casts. The warning about unused arguments is disabled, isn't it? +> You should be able to remove casts to (void) from all places. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface, Check return value of wl_display_dispatch. + +> So here is the main loop, and it gracefully ignores all error +> conditions, which means that this program never exits if it gets +> disconnected - instead it starts eating 100% CPU until forcefully +> killed. +> Now I see why you had the server kill this client. You'd better fix this +> main loop instead. +> For guidance, see what simple-shm.c does. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface, Move declaration to top + +> Mixed decl & code. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface, Delete signal handlings + +> I don't think you need to catch these at all. The default action is to +> kill the process, which is quite fine. The default action even sets the +> process exit code properly, unlike these. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface.c , Remove redundant function calls + +> _set_user_data() is redundant here, _add_listener() does it too. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface.c, Remove unnecessary do-while + +> Using if () { } else if () { ... +> would let you get rid of one level of indent and the breaks. } + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface.c , Fix Invalid value for registry_listener + +> NULL here will cause a segfault when the event arrives. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface.c ,use os_create_anonymous_file when temporary file + +> You should use oscreateanonymous_file() instead. +> Here you forget to e.g. unlink the file, and set the file descriptor CLOEXEC. +> Oh hey, my /tmp has 109 files from September from this function, and +> it's not even a tmpfs so they actually ended up on disk. Apparently that +> is the last time I actually tried to run this. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface, Remove unnecessary function calls + +> This is a strange place for a roundtrip. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface.c,Remove unnecessary function calls + +> Yet another roundtrip that makes no sense. A flush might be good, except +> it is the main loop's job to flush. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface.c,Remove unnecessary function calls + +> It does not matter if we bind only wl_shm or any number of other global +> interfaces too, they all will be covered by the same two roundtrips. +> The mistake the demos used to do is to call dispatch instead of one of +> the roundtrips, IIRC. +> For a truly correct solution, you do what weston-info.c does wrt. +> roundtrips, but the two is enough here. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface,Change appropriate function name + +> You call it createWLContext, but what it actually does is create one +> wlsurface and one wlbuffer. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface,Delete wl_display_roundtrip in function of WLSurface creation + +> Why a roundtrip here, isn't the flush enough? Well, this is a strange +> place for a flush, too. +> Looks like you just leak everything that gets created through this +> function. No, wait, maybe you don't? I don't know, all the naming here +> makes me dizzy. I'd expect a "context" here is basically a singleton, +> since we have no need multiple contexts, but maybe here it actually +> means a window? + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface.c ,Add wl_display_roundtrip in function of WLbuffer creation + +> Hmm, wonder where the other roundtrip is. Hopefully it happens before +> you create any wlbuffers, so that the wlshm.format events are +> guaranteed to been received. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface.c, replace 4 spaces to tab. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface.c, align member of structure + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients: ivi-shell-user-interface.c, align indent of parameters in methods + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------------- +clients/ivi-shell-user-interface.c: whitespace fixes + +-------------------------------------------------------------- +clients/ivi-shell-user-interface.c: split long lines + +hmi_homescreen_setting_create() lost one level of ident through a little +refactoring. + +-------------------------------------------------------------- +clients/ivi-shell-user-interface.c: remove unnecessary braces +--- + Makefile.am | 23 +- + clients/ivi-shell-user-interface.c | 1308 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 1329 insertions(+), 2 deletions(-) + create mode 100644 clients/ivi-shell-user-interface.c + +diff --git a/Makefile.am b/Makefile.am +index 76780a8..48cad9b 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -364,6 +364,11 @@ libexec_PROGRAMS += \ + weston-keyboard \ + weston-simple-im + ++if ENABLE_IVI_SHELL ++libexec_PROGRAMS += \ ++ weston-ivi-shell-user-interface ++endif ++ + demo_clients = \ + weston-flower \ + weston-image \ +@@ -590,6 +595,17 @@ nodist_weston_desktop_shell_SOURCES = \ + weston_desktop_shell_LDADD = libtoytoolkit.la + weston_desktop_shell_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS) + ++if ENABLE_IVI_SHELL ++weston_ivi_shell_user_interface_SOURCES = clients/ivi-shell-user-interface.c ++nodist_weston_ivi_shell_user_interface_SOURCES = \ ++ protocol/ivi-hmi-controller-client-protocol.h \ ++ protocol/ivi-hmi-controller-protocol.c \ ++ protocol/ivi-application-client-protocol.h \ ++ protocol/ivi-application-protocol.c ++weston_ivi_shell_user_interface_LDADD = libtoytoolkit.la ++weston_ivi_shell_user_interface_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS) ++endif ++ + if BUILD_FULL_GL_CLIENTS + demo_clients += weston-gears + weston_gears_SOURCES = clients/gears.c +@@ -636,8 +652,11 @@ BUILT_SOURCES += \ + protocol/fullscreen-shell-protocol.c \ + protocol/fullscreen-shell-client-protocol.h \ + protocol/xdg-shell-protocol.c \ +- protocol/xdg-shell-client-protocol.h +- ++ protocol/xdg-shell-client-protocol.h \ ++ protocol/ivi-hmi-controller-protocol.c \ ++ protocol/ivi-hmi-controller-client-protocol.h \ ++ protocol/ivi-application-protocol.c \ ++ protocol/ivi-application-client-protocol.h + + westondatadir = $(datadir)/weston + dist_westondata_DATA = \ +diff --git a/clients/ivi-shell-user-interface.c b/clients/ivi-shell-user-interface.c +new file mode 100644 +index 0000000..3c69541 +--- /dev/null ++++ b/clients/ivi-shell-user-interface.c +@@ -0,0 +1,1308 @@ ++/* ++ * 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. ++ */ ++ ++#include <sys/wait.h> ++#include <unistd.h> ++#include <stdlib.h> ++#include <stdio.h> ++#include <string.h> ++#include <linux/input.h> ++#include <assert.h> ++#include <fcntl.h> ++#include <signal.h> ++#include <sys/mman.h> ++#include <getopt.h> ++#include <wayland-cursor.h> ++#include "../shared/cairo-util.h" ++#include "../shared/config-parser.h" ++#include "../shared/os-compatibility.h" ++#include "ivi-application-client-protocol.h" ++#include "ivi-hmi-controller-client-protocol.h" ++ ++/** ++ * A reference implementation how to use ivi-hmi-controller interface to ++ * interact with hmi-controller. This is launched from hmi-controller by using ++ * hmi_client_start and create a pthread. ++ * ++ * The basic flow is as followed, ++ * 1/ read configuration from weston.ini. ++ * 2/ draw png file to surface according to configuration of weston.ini ++ * 3/ set up UI by using ivi-hmi-controller protocol ++ * 4/ Enter event loop ++ * 5/ If a surface receives touch/pointer event, followings are invoked ++ * according to type of event and surface ++ * 5-1/ If a surface to launch ivi_application receive touch up, it execs ++ * ivi-application configured in weston.ini. ++ * 5-2/ If a surface to switch layout mode receive touch up, it sends a request, ++ * ivi_hmi_controller_switch_mode, to hmi-controller. ++ * 5-3/ If a surface to show workspace having launchers, it sends a request, ++ * ivi_hmi_controller_home, to hmi-controller. ++ * 5-4/ If touch down events happens in workspace, ++ * ivi_hmi_controller_workspace_control is sent to slide workspace. ++ * When control finished, event: ivi_hmi_controller_workspace_end_control ++ * is received. ++ */ ++ ++/***************************************************************************** ++ * structure, globals ++ ****************************************************************************/ ++enum cursor_type { ++ CURSOR_BOTTOM_LEFT, ++ CURSOR_BOTTOM_RIGHT, ++ CURSOR_BOTTOM, ++ CURSOR_DRAGGING, ++ CURSOR_LEFT_PTR, ++ CURSOR_LEFT, ++ CURSOR_RIGHT, ++ CURSOR_TOP_LEFT, ++ CURSOR_TOP_RIGHT, ++ CURSOR_TOP, ++ CURSOR_IBEAM, ++ CURSOR_HAND1, ++ CURSOR_WATCH, ++ ++ CURSOR_BLANK ++}; ++struct wlContextCommon { ++ struct wl_display *wlDisplay; ++ struct wl_registry *wlRegistry; ++ struct wl_compositor *wlCompositor; ++ struct wl_shm *wlShm; ++ struct wl_seat *wlSeat; ++ struct wl_pointer *wlPointer; ++ struct wl_touch *wlTouch; ++ struct ivi_application *iviApplication; ++ struct ivi_hmi_controller *hmiCtrl; ++ struct hmi_homescreen_setting *hmi_setting; ++ struct wl_list *list_wlContextStruct; ++ struct wl_surface *enterSurface; ++ int32_t is_home_on; ++ struct wl_cursor_theme *cursor_theme; ++ struct wl_cursor **cursors; ++ struct wl_surface *pointer_surface; ++ enum cursor_type current_cursor; ++ uint32_t enter_serial; ++}; ++ ++struct wlContextStruct { ++ struct wlContextCommon cmm; ++ struct wl_surface *wlSurface; ++ struct wl_buffer *wlBuffer; ++ uint32_t formats; ++ cairo_surface_t *ctx_image; ++ void *data; ++ uint32_t id_surface; ++ struct wl_list link; ++}; ++ ++struct ++hmi_homescreen_srf { ++ uint32_t id; ++ char *filePath; ++ uint32_t color; ++}; ++ ++struct ++hmi_homescreen_workspace { ++ struct wl_array launcher_id_array; ++ struct wl_list link; ++}; ++ ++struct ++hmi_homescreen_launcher { ++ uint32_t icon_surface_id; ++ uint32_t workspace_id; ++ char *icon; ++ char *path; ++ struct wl_list link; ++}; ++ ++struct ++hmi_homescreen_setting { ++ struct hmi_homescreen_srf background; ++ struct hmi_homescreen_srf panel; ++ struct hmi_homescreen_srf tiling; ++ struct hmi_homescreen_srf sidebyside; ++ struct hmi_homescreen_srf fullscreen; ++ struct hmi_homescreen_srf random; ++ struct hmi_homescreen_srf home; ++ struct hmi_homescreen_srf workspace_background; ++ ++ struct wl_list workspace_list; ++ struct wl_list launcher_list; ++ ++ char *cursor_theme; ++ int32_t cursor_size; ++ uint32_t transition_duration; ++}; ++ ++static void * ++fail_on_null(void *p, size_t size, char *file, int32_t line) ++{ ++ if (size && !p) { ++ fprintf(stderr, "%s(%d) %zd: out of memory\n", ++ file, line, size); ++ exit(EXIT_FAILURE); ++ } ++ ++ return p; ++} ++ ++static void * ++mem_alloc(size_t size, char *file, int32_t line) ++{ ++ return fail_on_null(calloc(1, size), size, file, line); ++} ++ ++#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__) ++#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) ++ ++/***************************************************************************** ++ * Event Handler ++ ****************************************************************************/ ++ ++static void ++shm_format(void *data, struct wl_shm *pWlShm, uint32_t format) ++{ ++ struct wlContextStruct *pDsp = data; ++ pDsp->formats |= (1 << format); ++} ++ ++static struct wl_shm_listener shm_listenter = { ++ shm_format ++}; ++ ++static int32_t ++getIdOfWlSurface(struct wlContextCommon *pCtx, struct wl_surface *wlSurface) ++{ ++ struct wlContextStruct *pWlCtxSt = NULL; ++ ++ if (NULL == pCtx || NULL == wlSurface ) ++ return 0; ++ ++ wl_list_for_each(pWlCtxSt, pCtx->list_wlContextStruct, link) { ++ if (pWlCtxSt->wlSurface == wlSurface) ++ return pWlCtxSt->id_surface; ++ } ++ ++ return -1; ++} ++ ++static void ++set_pointer_image(struct wlContextCommon *pCtx, uint32_t index) ++{ ++ struct wl_cursor *cursor = NULL; ++ struct wl_cursor_image *image = NULL; ++ struct wl_buffer *buffer = NULL; ++ ++ if (!pCtx->wlPointer || !pCtx->cursors) ++ return; ++ ++ if (CURSOR_BLANK == pCtx->current_cursor) { ++ wl_pointer_set_cursor(pCtx->wlPointer, pCtx->enter_serial, ++ NULL, 0, 0); ++ return; ++ } ++ ++ cursor = pCtx->cursors[pCtx->current_cursor]; ++ if (!cursor) ++ return; ++ ++ if (cursor->image_count <= index) { ++ fprintf(stderr, "cursor index out of range\n"); ++ return; ++ } ++ ++ image = cursor->images[index]; ++ buffer = wl_cursor_image_get_buffer(image); ++ ++ if (!buffer) ++ return; ++ ++ wl_pointer_set_cursor(pCtx->wlPointer, pCtx->enter_serial, ++ pCtx->pointer_surface, ++ image->hotspot_x, image->hotspot_y); ++ ++ wl_surface_attach(pCtx->pointer_surface, buffer, 0, 0); ++ ++ wl_surface_damage(pCtx->pointer_surface, 0, 0, ++ image->width, image->height); ++ ++ wl_surface_commit(pCtx->pointer_surface); ++} ++ ++static void ++PointerHandleEnter(void *data, struct wl_pointer *wlPointer, uint32_t serial, ++ struct wl_surface *wlSurface, wl_fixed_t sx, wl_fixed_t sy) ++{ ++ struct wlContextCommon *pCtx = data; ++ ++ pCtx->enter_serial = serial; ++ pCtx->enterSurface = wlSurface; ++ set_pointer_image(pCtx, 0); ++#ifdef _DEBUG ++ printf("ENTER PointerHandleEnter: x(%d), y(%d)\n", sx, sy); ++#endif ++} ++ ++static void ++PointerHandleLeave(void *data, struct wl_pointer *wlPointer, uint32_t serial, ++ struct wl_surface *wlSurface) ++{ ++ struct wlContextCommon *pCtx = data; ++ ++ pCtx->enterSurface = NULL; ++ ++#ifdef _DEBUG ++ printf("ENTER PointerHandleLeave: serial(%d)\n", serial); ++#endif ++} ++ ++static void ++PointerHandleMotion(void *data, struct wl_pointer *wlPointer, uint32_t time, ++ wl_fixed_t sx, wl_fixed_t sy) ++{ ++#ifdef _DEBUG ++ printf("ENTER PointerHandleMotion: x(%d), y(%d)\n", ++ gPointerX, gPointerY); ++#endif ++} ++ ++/** ++ * if a surface assigned as launcher receives touch-off event, invoking ++ * ivi-application which configured in weston.ini with path to binary. ++ */ ++extern char **environ; /*defied by libc */ ++ ++static pid_t ++execute_process(char *path, char *argv[]) ++{ ++ pid_t pid = fork(); ++ if (pid < 0) ++ fprintf(stderr, "Failed to fork\n"); ++ ++ if (pid) ++ return pid; ++ ++ if (-1 == execve(path, argv, environ)) { ++ fprintf(stderr, "Failed to execve %s\n", path); ++ exit(1); ++ } ++ ++ return pid; ++} ++ ++static int32_t ++launcher_button(uint32_t surfaceId, struct wl_list *launcher_list) ++{ ++ struct hmi_homescreen_launcher *launcher = NULL; ++ ++ wl_list_for_each(launcher, launcher_list, link) { ++ char *argv[] = { NULL }; ++ ++ if (surfaceId != launcher->icon_surface_id) ++ continue; ++ ++ execute_process(launcher->path, argv); ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/** ++ * is-method to identify a surface set as launcher in workspace or workspace ++ * itself. This is-method is used to decide whether request; ++ * ivi_hmi_controller_workspace_control is sent or not. ++ */ ++static int32_t ++isWorkspaceSurface(uint32_t id, struct hmi_homescreen_setting *hmi_setting) ++{ ++ struct hmi_homescreen_launcher *launcher = NULL; ++ ++ if (id == hmi_setting->workspace_background.id) ++ return 1; ++ ++ wl_list_for_each(launcher, &hmi_setting->launcher_list, link) { ++ if (id == launcher->icon_surface_id) ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/** ++ * Decide which request is sent to hmi-controller ++ */ ++static void ++touch_up(struct ivi_hmi_controller *hmi_ctrl, uint32_t id_surface, ++ int32_t *is_home_on, struct hmi_homescreen_setting *hmi_setting) ++{ ++ if (launcher_button(id_surface, &hmi_setting->launcher_list)) { ++ *is_home_on = 0; ++ ivi_hmi_controller_home(hmi_ctrl, IVI_HMI_CONTROLLER_HOME_OFF); ++ } else if (id_surface == hmi_setting->tiling.id) { ++ ivi_hmi_controller_switch_mode(hmi_ctrl, ++ IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING); ++ } else if (id_surface == hmi_setting->sidebyside.id) { ++ ivi_hmi_controller_switch_mode(hmi_ctrl, ++ IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE); ++ } else if (id_surface == hmi_setting->fullscreen.id) { ++ ivi_hmi_controller_switch_mode(hmi_ctrl, ++ IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN); ++ } else if (id_surface == hmi_setting->random.id) { ++ ivi_hmi_controller_switch_mode(hmi_ctrl, ++ IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM); ++ } else if (id_surface == hmi_setting->home.id) { ++ *is_home_on = !(*is_home_on); ++ if (*is_home_on) { ++ ivi_hmi_controller_home(hmi_ctrl, ++ IVI_HMI_CONTROLLER_HOME_ON); ++ } else { ++ ivi_hmi_controller_home(hmi_ctrl, ++ IVI_HMI_CONTROLLER_HOME_OFF); ++ } ++ } ++} ++ ++/** ++ * Even handler of Pointer event. IVI system is usually manipulated by touch ++ * screen. However, some systems also have pointer device. ++ * Release is the same behavior as touch off ++ * Pressed is the same behavior as touch on ++ */ ++static void ++PointerHandleButton(void *data, struct wl_pointer *wlPointer, uint32_t serial, ++ uint32_t time, uint32_t button, uint32_t state) ++{ ++ struct wlContextCommon *pCtx = data; ++ struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl; ++ const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface); ++ ++ if (BTN_RIGHT == button) ++ return; ++ ++ switch (state) { ++ case WL_POINTER_BUTTON_STATE_RELEASED: ++ touch_up(hmi_ctrl, id_surface, &pCtx->is_home_on, ++ pCtx->hmi_setting); ++ break; ++ ++ case WL_POINTER_BUTTON_STATE_PRESSED: ++ ++ if (isWorkspaceSurface(id_surface, pCtx->hmi_setting)) { ++ ivi_hmi_controller_workspace_control(hmi_ctrl, ++ pCtx->wlSeat, ++ serial); ++ } ++ ++ break; ++ } ++#ifdef _DEBUG ++ printf("ENTER PointerHandleButton: button(%d), state(%d)\n", ++ button, state); ++#endif ++} ++ ++static void ++PointerHandleAxis(void *data, struct wl_pointer *wlPointer, uint32_t time, ++ uint32_t axis, wl_fixed_t value) ++{ ++#ifdef _DEBUG ++ printf("ENTER PointerHandleAxis: axis(%d), value(%d)\n", axis, value); ++#endif ++} ++ ++static struct wl_pointer_listener pointer_listener = { ++ PointerHandleEnter, ++ PointerHandleLeave, ++ PointerHandleMotion, ++ PointerHandleButton, ++ PointerHandleAxis ++}; ++ ++/** ++ * Even handler of touch event ++ */ ++static void ++TouchHandleDown(void *data, struct wl_touch *wlTouch, uint32_t serial, ++ uint32_t time, struct wl_surface *surface, int32_t id, ++ wl_fixed_t x_w, wl_fixed_t y_w) ++{ ++ struct wlContextCommon *pCtx = data; ++ struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl; ++ uint32_t id_surface = 0; ++ ++ if (0 == id) ++ pCtx->enterSurface = surface; ++ ++ id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface); ++ ++ /** ++ * When touch down happens on surfaces of workspace, ask ++ * hmi-controller to start control workspace to select page of ++ * workspace. After sending seat to hmi-controller by ++ * ivi_hmi_controller_workspace_control, ++ * hmi-controller-homescreen doesn't receive any event till ++ * hmi-controller sends back it. ++ */ ++ if (isWorkspaceSurface(id_surface, pCtx->hmi_setting)) { ++ ivi_hmi_controller_workspace_control(hmi_ctrl, pCtx->wlSeat, ++ serial); ++ } ++} ++ ++static void ++TouchHandleUp(void *data, struct wl_touch *wlTouch, uint32_t serial, ++ uint32_t time, int32_t id) ++{ ++ struct wlContextCommon *pCtx = data; ++ struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl; ++ ++ const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface); ++ ++ /** ++ * triggering event according to touch-up happening on which surface. ++ */ ++ if (id == 0){ ++ touch_up(hmi_ctrl, id_surface, &pCtx->is_home_on, ++ pCtx->hmi_setting); ++ } ++} ++ ++static void ++TouchHandleMotion(void *data, struct wl_touch *wlTouch, uint32_t time, ++ int32_t id, wl_fixed_t x_w, wl_fixed_t y_w) ++{ ++} ++ ++static void ++TouchHandleFrame(void *data, struct wl_touch *wlTouch) ++{ ++} ++ ++static void ++TouchHandleCancel(void *data, struct wl_touch *wlTouch) ++{ ++} ++ ++static struct wl_touch_listener touch_listener = { ++ TouchHandleDown, ++ TouchHandleUp, ++ TouchHandleMotion, ++ TouchHandleFrame, ++ TouchHandleCancel, ++}; ++ ++/** ++ * Handler of capabilities ++ */ ++static void ++seat_handle_capabilities(void *data, struct wl_seat *seat, uint32_t caps) ++{ ++ struct wlContextCommon *p_wlCtx = (struct wlContextCommon*)data; ++ struct wl_seat *wlSeat = p_wlCtx->wlSeat; ++ struct wl_pointer *wlPointer = p_wlCtx->wlPointer; ++ struct wl_touch *wlTouch = p_wlCtx->wlTouch; ++ ++ if (p_wlCtx->hmi_setting->cursor_theme) { ++ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wlPointer){ ++ wlPointer = wl_seat_get_pointer(wlSeat); ++ wl_pointer_add_listener(wlPointer, ++ &pointer_listener, data); ++ } else ++ if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wlPointer){ ++ wl_pointer_destroy(wlPointer); ++ wlPointer = NULL; ++ } ++ p_wlCtx->wlPointer = wlPointer; ++ } ++ ++ if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !wlTouch){ ++ wlTouch = wl_seat_get_touch(wlSeat); ++ wl_touch_add_listener(wlTouch, &touch_listener, data); ++ } else ++ if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && wlTouch){ ++ wl_touch_destroy(wlTouch); ++ wlTouch = NULL; ++ } ++ p_wlCtx->wlTouch = wlTouch; ++} ++ ++static struct wl_seat_listener seat_Listener = { ++ seat_handle_capabilities, ++}; ++ ++/** ++ * Registration of event ++ * This event is received when hmi-controller server finished controlling ++ * workspace. ++ */ ++static void ++ivi_hmi_controller_workspace_end_control(void *data, ++ struct ivi_hmi_controller *hmi_ctrl, ++ int32_t is_controlled) ++{ ++ struct wlContextCommon *pCtx = data; ++ const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface); ++ ++ if (is_controlled) ++ return; ++ ++ /** ++ * During being controlled by hmi-controller, any input event is not ++ * notified. So when control ends with touch up, it invokes launcher ++ * if up event happens on a launcher surface. ++ * ++ */ ++ if (launcher_button(id_surface, &pCtx->hmi_setting->launcher_list)) { ++ pCtx->is_home_on = 0; ++ ivi_hmi_controller_home(hmi_ctrl, IVI_HMI_CONTROLLER_HOME_OFF); ++ } ++} ++ ++static const struct ivi_hmi_controller_listener hmi_controller_listener = { ++ ivi_hmi_controller_workspace_end_control ++}; ++ ++/** ++ * Registration of interfaces ++ */ ++static void ++registry_handle_global(void *data, struct wl_registry *registry, uint32_t name, ++ const char *interface, uint32_t version) ++{ ++ struct wlContextCommon *p_wlCtx = (struct wlContextCommon*)data; ++ ++ if (!strcmp(interface, "wl_compositor")) { ++ p_wlCtx->wlCompositor = ++ wl_registry_bind(registry, name, ++ &wl_compositor_interface, 1); ++ } else if (!strcmp(interface, "wl_shm")) { ++ p_wlCtx->wlShm = ++ wl_registry_bind(registry, name, &wl_shm_interface, 1); ++ wl_shm_add_listener(p_wlCtx->wlShm, &shm_listenter, p_wlCtx); ++ } else if (!strcmp(interface, "wl_seat")) { ++ p_wlCtx->wlSeat = ++ wl_registry_bind(registry, name, &wl_seat_interface, 1); ++ wl_seat_add_listener(p_wlCtx->wlSeat, &seat_Listener, data); ++ } else if (!strcmp(interface, "ivi_application")) { ++ p_wlCtx->iviApplication = ++ wl_registry_bind(registry, name, ++ &ivi_application_interface, 1); ++ } else if (!strcmp(interface, "ivi_hmi_controller")) { ++ p_wlCtx->hmiCtrl = ++ wl_registry_bind(registry, name, ++ &ivi_hmi_controller_interface, 1); ++ ++ if (p_wlCtx->hmiCtrl) { ++ ivi_hmi_controller_add_listener(p_wlCtx->hmiCtrl, ++ &hmi_controller_listener, p_wlCtx); ++ } ++ } ++} ++ ++static void ++registry_handle_global_remove(void *data, struct wl_registry *registry, ++ uint32_t name) ++{ ++} ++ ++static const struct wl_registry_listener registry_listener = { ++ registry_handle_global, ++ registry_handle_global_remove ++}; ++ ++static void ++frame_listener_func(void *data, struct wl_callback *callback, uint32_t time) ++{ ++ if (callback) ++ wl_callback_destroy(callback); ++} ++ ++static const struct wl_callback_listener frame_listener = { ++ frame_listener_func ++}; ++ ++/* ++ * The following correspondences between file names and cursors was copied ++ * from: https://bugs.kde.org/attachment.cgi?id=67313 ++ */ ++static const char *bottom_left_corners[] = { ++ "bottom_left_corner", ++ "sw-resize", ++ "size_bdiag" ++}; ++ ++static const char *bottom_right_corners[] = { ++ "bottom_right_corner", ++ "se-resize", ++ "size_fdiag" ++}; ++ ++static const char *bottom_sides[] = { ++ "bottom_side", ++ "s-resize", ++ "size_ver" ++}; ++ ++static const char *grabbings[] = { ++ "grabbing", ++ "closedhand", ++ "208530c400c041818281048008011002" ++}; ++ ++static const char *left_ptrs[] = { ++ "left_ptr", ++ "default", ++ "top_left_arrow", ++ "left-arrow" ++}; ++ ++static const char *left_sides[] = { ++ "left_side", ++ "w-resize", ++ "size_hor" ++}; ++ ++static const char *right_sides[] = { ++ "right_side", ++ "e-resize", ++ "size_hor" ++}; ++ ++static const char *top_left_corners[] = { ++ "top_left_corner", ++ "nw-resize", ++ "size_fdiag" ++}; ++ ++static const char *top_right_corners[] = { ++ "top_right_corner", ++ "ne-resize", ++ "size_bdiag" ++}; ++ ++static const char *top_sides[] = { ++ "top_side", ++ "n-resize", ++ "size_ver" ++}; ++ ++static const char *xterms[] = { ++ "xterm", ++ "ibeam", ++ "text" ++}; ++ ++static const char *hand1s[] = { ++ "hand1", ++ "pointer", ++ "pointing_hand", ++ "e29285e634086352946a0e7090d73106" ++}; ++ ++static const char *watches[] = { ++ "watch", ++ "wait", ++ "0426c94ea35c87780ff01dc239897213" ++}; ++ ++struct cursor_alternatives { ++ const char **names; ++ size_t count; ++}; ++ ++static const struct cursor_alternatives cursors[] = { ++ { bottom_left_corners, ARRAY_LENGTH(bottom_left_corners) }, ++ { bottom_right_corners, ARRAY_LENGTH(bottom_right_corners) }, ++ { bottom_sides, ARRAY_LENGTH(bottom_sides) }, ++ { grabbings, ARRAY_LENGTH(grabbings) }, ++ { left_ptrs, ARRAY_LENGTH(left_ptrs) }, ++ { left_sides, ARRAY_LENGTH(left_sides) }, ++ { right_sides, ARRAY_LENGTH(right_sides) }, ++ { top_left_corners, ARRAY_LENGTH(top_left_corners) }, ++ { top_right_corners, ARRAY_LENGTH(top_right_corners) }, ++ { top_sides, ARRAY_LENGTH(top_sides) }, ++ { xterms, ARRAY_LENGTH(xterms) }, ++ { hand1s, ARRAY_LENGTH(hand1s) }, ++ { watches, ARRAY_LENGTH(watches) }, ++}; ++ ++static void ++create_cursors(struct wlContextCommon *cmm) ++{ ++ uint32_t i = 0; ++ uint32_t j = 0; ++ struct wl_cursor *cursor = NULL; ++ char *cursor_theme = cmm->hmi_setting->cursor_theme; ++ int32_t cursor_size = cmm->hmi_setting->cursor_size; ++ ++ cmm->cursor_theme = wl_cursor_theme_load(cursor_theme, cursor_size, ++ cmm->wlShm); ++ ++ cmm->cursors = ++ MEM_ALLOC(ARRAY_LENGTH(cursors) * sizeof(cmm->cursors[0])); ++ ++ for (i = 0; i < ARRAY_LENGTH(cursors); i++) { ++ cursor = NULL; ++ ++ for (j = 0; !cursor && j < cursors[i].count; ++j) { ++ cursor = wl_cursor_theme_get_cursor( ++ cmm->cursor_theme, cursors[i].names[j]); ++ } ++ ++ if (!cursor) { ++ fprintf(stderr, "could not load cursor '%s'\n", ++ cursors[i].names[0]); ++ } ++ ++ cmm->cursors[i] = cursor; ++ } ++} ++ ++static void ++destroy_cursors(struct wlContextCommon *cmm) ++{ ++ if (cmm->cursor_theme) ++ wl_cursor_theme_destroy(cmm->cursor_theme); ++ ++ free(cmm->cursors); ++} ++ ++/** ++ * Internal method to prepare parts of UI ++ */ ++static void ++createShmBuffer(struct wlContextStruct *p_wlCtx) ++{ ++ struct wl_shm_pool *pool; ++ ++ int fd = -1; ++ int size = 0; ++ int width = 0; ++ int height = 0; ++ int stride = 0; ++ ++ width = cairo_image_surface_get_width(p_wlCtx->ctx_image); ++ height = cairo_image_surface_get_height(p_wlCtx->ctx_image); ++ stride = cairo_image_surface_get_stride(p_wlCtx->ctx_image); ++ ++ size = stride * height; ++ ++ fd = os_create_anonymous_file(size); ++ if (fd < 0) { ++ fprintf(stderr, "creating a buffer file for %d B failed: %m\n", ++ size); ++ return ; ++ } ++ ++ p_wlCtx->data = ++ mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); ++ ++ if (MAP_FAILED == p_wlCtx->data) { ++ fprintf(stderr, "mmap failed: %m\n"); ++ close(fd); ++ return; ++ } ++ ++ pool = wl_shm_create_pool(p_wlCtx->cmm.wlShm, fd, size); ++ p_wlCtx->wlBuffer = wl_shm_pool_create_buffer(pool, 0, ++ width, ++ height, ++ stride, ++ WL_SHM_FORMAT_ARGB8888); ++ ++ if (NULL == p_wlCtx->wlBuffer) { ++ fprintf(stderr, "wl_shm_create_buffer failed: %m\n"); ++ close(fd); ++ return; ++ } ++ ++ wl_display_roundtrip(p_wlCtx->cmm.wlDisplay); ++ ++ wl_shm_pool_destroy(pool); ++ close(fd); ++ ++ return; ++} ++ ++static void ++destroyWLContextCommon(struct wlContextCommon *p_wlCtx) ++{ ++ destroy_cursors(p_wlCtx); ++ ++ if (p_wlCtx->pointer_surface) ++ wl_surface_destroy(p_wlCtx->pointer_surface); ++ ++ if (p_wlCtx->wlCompositor) ++ wl_compositor_destroy(p_wlCtx->wlCompositor); ++} ++ ++static void ++destroyWLContextStruct(struct wlContextStruct *p_wlCtx) ++{ ++ if (p_wlCtx->wlSurface) ++ wl_surface_destroy(p_wlCtx->wlSurface); ++ ++ if (p_wlCtx->ctx_image) { ++ cairo_surface_destroy(p_wlCtx->ctx_image); ++ p_wlCtx->ctx_image = NULL; ++ } ++} ++ ++static int ++createSurface(struct wlContextStruct *p_wlCtx) ++{ ++ p_wlCtx->wlSurface = ++ wl_compositor_create_surface(p_wlCtx->cmm.wlCompositor); ++ if (NULL == p_wlCtx->wlSurface) { ++ printf("Error: wl_compositor_create_surface failed.\n"); ++ destroyWLContextCommon(&p_wlCtx->cmm); ++ abort(); ++ } ++ ++ return 0; ++} ++ ++static void ++drawImage(struct wlContextStruct *p_wlCtx) ++{ ++ struct wl_callback *callback; ++ ++ int width = 0; ++ int height = 0; ++ int stride = 0; ++ void *data = NULL; ++ ++ width = cairo_image_surface_get_width(p_wlCtx->ctx_image); ++ height = cairo_image_surface_get_height(p_wlCtx->ctx_image); ++ stride = cairo_image_surface_get_stride(p_wlCtx->ctx_image); ++ data = cairo_image_surface_get_data(p_wlCtx->ctx_image); ++ ++ memcpy(p_wlCtx->data, data, stride * height); ++ ++ wl_surface_attach(p_wlCtx->wlSurface, p_wlCtx->wlBuffer, 0, 0); ++ wl_surface_damage(p_wlCtx->wlSurface, 0, 0, width, height); ++ ++ callback = wl_surface_frame(p_wlCtx->wlSurface); ++ wl_callback_add_listener(callback, &frame_listener, NULL); ++ ++ wl_surface_commit(p_wlCtx->wlSurface); ++ ++ wl_display_roundtrip(p_wlCtx->cmm.wlDisplay); ++} ++ ++static void ++create_ivisurface(struct wlContextStruct *p_wlCtx, ++ uint32_t id_surface, ++ cairo_surface_t *surface) ++{ ++ struct ivi_surface *ivisurf = NULL; ++ ++ p_wlCtx->ctx_image = surface; ++ ++ p_wlCtx->id_surface = id_surface; ++ wl_list_init(&p_wlCtx->link); ++ wl_list_insert(p_wlCtx->cmm.list_wlContextStruct, &p_wlCtx->link); ++ ++ createSurface(p_wlCtx); ++ createShmBuffer(p_wlCtx); ++ ++ ivisurf = ivi_application_surface_create(p_wlCtx->cmm.iviApplication, ++ id_surface, ++ p_wlCtx->wlSurface); ++ if (ivisurf == NULL) { ++ fprintf(stderr, "Failed to create ivi_client_surface\n"); ++ return; ++ } ++ ++ drawImage(p_wlCtx); ++} ++ ++static void ++create_ivisurfaceFromFile(struct wlContextStruct *p_wlCtx, ++ uint32_t id_surface, ++ const char *imageFile) ++{ ++ cairo_surface_t *surface = load_cairo_surface(imageFile); ++ ++ if (NULL == surface) { ++ fprintf(stderr, "Failed to load_cairo_surface %s\n", imageFile); ++ return; ++ } ++ ++ create_ivisurface(p_wlCtx, id_surface, surface); ++} ++ ++static void ++set_hex_color(cairo_t *cr, uint32_t color) ++{ ++ cairo_set_source_rgba(cr, ++ ((color >> 16) & 0xff) / 255.0, ++ ((color >> 8) & 0xff) / 255.0, ++ ((color >> 0) & 0xff) / 255.0, ++ ((color >> 24) & 0xff) / 255.0); ++} ++ ++static void ++create_ivisurfaceFromColor(struct wlContextStruct *p_wlCtx, ++ uint32_t id_surface, ++ uint32_t width, uint32_t height, ++ uint32_t color) ++{ ++ cairo_surface_t *surface = NULL; ++ cairo_t *cr = NULL; ++ ++ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ++ width, height); ++ ++ cr = cairo_create(surface); ++ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); ++ cairo_rectangle(cr, 0, 0, width, height); ++ set_hex_color(cr, color); ++ cairo_fill(cr); ++ cairo_destroy(cr); ++ ++ create_ivisurface(p_wlCtx, id_surface, surface); ++} ++ ++static void ++UI_ready(struct ivi_hmi_controller *controller) ++{ ++ ivi_hmi_controller_UI_ready(controller); ++} ++ ++/** ++ * Internal method to set up UI by using ivi-hmi-controller ++ */ ++static void ++create_background(struct wlContextStruct *p_wlCtx, const uint32_t id_surface, ++ const char *imageFile) ++{ ++ create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile); ++} ++ ++static void ++create_panel(struct wlContextStruct *p_wlCtx, const uint32_t id_surface, ++ const char *imageFile) ++{ ++ create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile); ++} ++ ++static void ++create_button(struct wlContextStruct *p_wlCtx, const uint32_t id_surface, ++ const char *imageFile, uint32_t number) ++{ ++ create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile); ++} ++ ++static void ++create_home_button(struct wlContextStruct *p_wlCtx, const uint32_t id_surface, ++ const char *imageFile) ++{ ++ create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile); ++} ++ ++static void ++create_workspace_background(struct wlContextStruct *p_wlCtx, ++ struct hmi_homescreen_srf *srf) ++{ ++ create_ivisurfaceFromColor(p_wlCtx, srf->id, 1, 1, srf->color); ++} ++ ++static void ++create_launchers(struct wlContextCommon *cmm, struct wl_list *launcher_list) ++{ ++ struct hmi_homescreen_launcher **launchers; ++ struct hmi_homescreen_launcher *launcher = NULL; ++ ++ int launcher_count = wl_list_length(launcher_list); ++ int ii = 0; ++ int start = 0; ++ ++ if (0 == launcher_count) ++ return; ++ ++ launchers = MEM_ALLOC(launcher_count * sizeof(*launchers)); ++ ++ wl_list_for_each(launcher, launcher_list, link) { ++ launchers[ii] = launcher; ++ ii++; ++ } ++ ++ for (ii = 0; ii < launcher_count; ii++) { ++ int jj = 0; ++ ++ if (ii != launcher_count - 1 && ++ launchers[ii]->workspace_id == ++ launchers[ii + 1]->workspace_id) ++ continue; ++ ++ for (jj = start; jj <= ii; jj++) { ++ struct wlContextStruct *p_wlCtx; ++ ++ p_wlCtx = MEM_ALLOC(sizeof(*p_wlCtx)); ++ p_wlCtx->cmm = *cmm; ++ create_ivisurfaceFromFile(p_wlCtx, ++ launchers[jj]->icon_surface_id, ++ launchers[jj]->icon); ++ } ++ ++ start = ii + 1; ++ } ++ ++ free(launchers); ++} ++ ++/** ++ * Internal method to read out weston.ini to get configuration ++ */ ++static struct hmi_homescreen_setting * ++hmi_homescreen_setting_create(void) ++{ ++ struct weston_config *config = NULL; ++ struct weston_config_section *shellSection = NULL; ++ struct hmi_homescreen_setting *setting = MEM_ALLOC(sizeof(*setting)); ++ struct weston_config_section *section = NULL; ++ const char *name = NULL; ++ uint32_t workspace_layer_id; ++ uint32_t icon_surface_id = 0; ++ ++ wl_list_init(&setting->workspace_list); ++ wl_list_init(&setting->launcher_list); ++ ++ config = weston_config_parse("weston.ini"); ++ ++ shellSection = ++ weston_config_get_section(config, "ivi-shell", NULL, NULL); ++ ++ weston_config_section_get_string( ++ shellSection, "cursor-theme", &setting->cursor_theme, NULL); ++ ++ weston_config_section_get_int( ++ shellSection, "cursor-size", &setting->cursor_size, 32); ++ ++ weston_config_section_get_uint( ++ shellSection, "workspace-layer-id", &workspace_layer_id, 3000); ++ ++ weston_config_section_get_string( ++ shellSection, "background-image", &setting->background.filePath, ++ DATADIR "/weston/background.png"); ++ ++ weston_config_section_get_uint( ++ shellSection, "background-id", &setting->background.id, 1001); ++ ++ weston_config_section_get_string( ++ shellSection, "panel-image", &setting->panel.filePath, ++ DATADIR "/weston/panel.png"); ++ ++ weston_config_section_get_uint( ++ shellSection, "panel-id", &setting->panel.id, 1002); ++ ++ weston_config_section_get_string( ++ shellSection, "tiling-image", &setting->tiling.filePath, ++ DATADIR "/weston/tiling.png"); ++ ++ weston_config_section_get_uint( ++ shellSection, "tiling-id", &setting->tiling.id, 1003); ++ ++ weston_config_section_get_string( ++ shellSection, "sidebyside-image", &setting->sidebyside.filePath, ++ DATADIR "/weston/sidebyside.png"); ++ ++ weston_config_section_get_uint( ++ shellSection, "sidebyside-id", &setting->sidebyside.id, 1004); ++ ++ weston_config_section_get_string( ++ shellSection, "fullscreen-image", &setting->fullscreen.filePath, ++ DATADIR "/weston/fullscreen.png"); ++ ++ weston_config_section_get_uint( ++ shellSection, "fullscreen-id", &setting->fullscreen.id, 1005); ++ ++ weston_config_section_get_string( ++ shellSection, "random-image", &setting->random.filePath, ++ DATADIR "/weston/random.png"); ++ ++ weston_config_section_get_uint( ++ shellSection, "random-id", &setting->random.id, 1006); ++ ++ weston_config_section_get_string( ++ shellSection, "home-image", &setting->home.filePath, ++ DATADIR "/weston/home.png"); ++ ++ weston_config_section_get_uint( ++ shellSection, "home-id", &setting->home.id, 1007); ++ ++ weston_config_section_get_uint( ++ shellSection, "workspace-background-color", ++ &setting->workspace_background.color, 0x99000000); ++ ++ weston_config_section_get_uint( ++ shellSection, "workspace-background-id", ++ &setting->workspace_background.id, 2001); ++ ++ icon_surface_id = workspace_layer_id + 1; ++ ++ while (weston_config_next_section(config, §ion, &name)) { ++ struct hmi_homescreen_launcher *launcher; ++ ++ if (strcmp(name, "ivi-launcher") != 0) ++ continue; ++ ++ launcher = MEM_ALLOC(sizeof(*launcher)); ++ wl_list_init(&launcher->link); ++ ++ weston_config_section_get_string(section, "icon", ++ &launcher->icon, NULL); ++ weston_config_section_get_string(section, "path", ++ &launcher->path, NULL); ++ weston_config_section_get_uint(section, "workspace-id", ++ &launcher->workspace_id, 0); ++ weston_config_section_get_uint(section, "icon-id", ++ &launcher->icon_surface_id, ++ icon_surface_id); ++ icon_surface_id++; ++ ++ wl_list_insert(setting->launcher_list.prev, &launcher->link); ++ } ++ ++ weston_config_destroy(config); ++ return setting; ++} ++ ++/** ++ * Main thread ++ * ++ * The basic flow are as followed, ++ * 1/ read configuration from weston.ini by hmi_homescreen_setting_create ++ * 2/ draw png file to surface according to configuration of weston.ini and ++ * set up UI by using ivi-hmi-controller protocol by each create_* method ++ */ ++int main(int argc, char **argv) ++{ ++ struct wlContextCommon wlCtxCommon; ++ struct wlContextStruct wlCtx_BackGround; ++ struct wlContextStruct wlCtx_Panel; ++ struct wlContextStruct wlCtx_Button_1; ++ struct wlContextStruct wlCtx_Button_2; ++ struct wlContextStruct wlCtx_Button_3; ++ struct wlContextStruct wlCtx_Button_4; ++ struct wlContextStruct wlCtx_HomeButton; ++ struct wlContextStruct wlCtx_WorkSpaceBackGround; ++ struct wl_list launcher_wlCtxList; ++ int ret = 0; ++ struct hmi_homescreen_setting *hmi_setting; ++ struct wlContextStruct *pWlCtxSt = NULL; ++ ++ hmi_setting = hmi_homescreen_setting_create(); ++ ++ memset(&wlCtxCommon, 0x00, sizeof(wlCtxCommon)); ++ memset(&wlCtx_BackGround, 0x00, sizeof(wlCtx_BackGround)); ++ memset(&wlCtx_Panel, 0x00, sizeof(wlCtx_Panel)); ++ memset(&wlCtx_Button_1, 0x00, sizeof(wlCtx_Button_1)); ++ memset(&wlCtx_Button_2, 0x00, sizeof(wlCtx_Button_2)); ++ memset(&wlCtx_Button_3, 0x00, sizeof(wlCtx_Button_3)); ++ memset(&wlCtx_Button_4, 0x00, sizeof(wlCtx_Button_4)); ++ memset(&wlCtx_HomeButton, 0x00, sizeof(wlCtx_HomeButton)); ++ memset(&wlCtx_WorkSpaceBackGround, 0x00, ++ sizeof(wlCtx_WorkSpaceBackGround)); ++ wl_list_init(&launcher_wlCtxList); ++ wlCtxCommon.list_wlContextStruct = MEM_ALLOC(sizeof(struct wl_list)); ++ assert(wlCtxCommon.list_wlContextStruct); ++ wl_list_init(wlCtxCommon.list_wlContextStruct); ++ ++ wlCtxCommon.hmi_setting = hmi_setting; ++ ++ wlCtxCommon.wlDisplay = wl_display_connect(NULL); ++ if (NULL == wlCtxCommon.wlDisplay) { ++ printf("Error: wl_display_connect failed.\n"); ++ return -1; ++ } ++ ++ /* get wl_registry */ ++ wlCtxCommon.wlRegistry = wl_display_get_registry(wlCtxCommon.wlDisplay); ++ wl_registry_add_listener(wlCtxCommon.wlRegistry, ++ ®istry_listener, &wlCtxCommon); ++ wl_display_roundtrip(wlCtxCommon.wlDisplay); ++ ++ if (wlCtxCommon.hmi_setting->cursor_theme) { ++ create_cursors(&wlCtxCommon); ++ ++ wlCtxCommon.pointer_surface = ++ wl_compositor_create_surface(wlCtxCommon.wlCompositor); ++ ++ wlCtxCommon.current_cursor = CURSOR_LEFT_PTR; ++ } ++ ++ wlCtx_BackGround.cmm = wlCtxCommon; ++ wlCtx_Panel.cmm = wlCtxCommon; ++ wlCtx_Button_1.cmm = wlCtxCommon; ++ wlCtx_Button_2.cmm = wlCtxCommon; ++ wlCtx_Button_3.cmm = wlCtxCommon; ++ wlCtx_Button_4.cmm = wlCtxCommon; ++ wlCtx_HomeButton.cmm = wlCtxCommon; ++ wlCtx_WorkSpaceBackGround.cmm = wlCtxCommon; ++ ++ /* create desktop widgets */ ++ create_background(&wlCtx_BackGround, hmi_setting->background.id, ++ hmi_setting->background.filePath); ++ ++ create_panel(&wlCtx_Panel, hmi_setting->panel.id, ++ hmi_setting->panel.filePath); ++ ++ create_button(&wlCtx_Button_1, hmi_setting->tiling.id, ++ hmi_setting->tiling.filePath, 0); ++ ++ create_button(&wlCtx_Button_2, hmi_setting->sidebyside.id, ++ hmi_setting->sidebyside.filePath, 1); ++ ++ create_button(&wlCtx_Button_3, hmi_setting->fullscreen.id, ++ hmi_setting->fullscreen.filePath, 2); ++ ++ create_button(&wlCtx_Button_4, hmi_setting->random.id, ++ hmi_setting->random.filePath, 3); ++ ++ create_workspace_background(&wlCtx_WorkSpaceBackGround, ++ &hmi_setting->workspace_background); ++ ++ create_launchers(&wlCtxCommon, &hmi_setting->launcher_list); ++ ++ create_home_button(&wlCtx_HomeButton, hmi_setting->home.id, ++ hmi_setting->home.filePath); ++ ++ UI_ready(wlCtxCommon.hmiCtrl); ++ ++ while(ret != -1) ++ ret = wl_display_dispatch(wlCtxCommon.wlDisplay); ++ ++ wl_list_for_each(pWlCtxSt, wlCtxCommon.list_wlContextStruct, link) { ++ destroyWLContextStruct(pWlCtxSt); ++ } ++ ++ destroyWLContextCommon(&wlCtxCommon); ++ free(wlCtxCommon.list_wlContextStruct); ++ ++ return 0; ++} +-- +1.7.9.5 + diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0008-data-add-reference-image-files-for-weston-ivi-shell-.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0008-data-add-reference-image-files-for-weston-ivi-shell-.patch new file mode 100644 index 0000000..3db0932 --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0008-data-add-reference-image-files-for-weston-ivi-shell-.patch @@ -0,0 +1,10101 @@ +From 3d8effbdca1db5344c1e6413876ddf270a8d9320 Mon Sep 17 00:00:00 2001 +From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +Date: Tue, 11 Mar 2014 11:54:45 +0900 +Subject: [PATCH 08/15] data: add reference image files for + weston-ivi-shell-user-interface + +- introduces ivi-shell-user-interface.c + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------ +COPYING: append license of images to COPYING file. + +> 800457d data: add reference image files for weston-ivi-shell-user-interface +> Do add a note of the image copyrights and licence to the commit +> message, and if the licence not MIT, add it to the COPYING +> file, too. +> No review email. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +------------------------------------------------------------ +data: add list of images under DENSO copyright + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +--- + Makefile.am | 14 +++++++++++++- + data/COPYING | 29 ++++++++++++++++++++++++++++- + data/background.png | Bin 0 -> 245579 bytes + data/fullscreen.png | Bin 0 -> 3406 bytes + data/home.png | Bin 0 -> 4629 bytes + data/icon_ivi_clickdot.png | Bin 0 -> 39523 bytes + data/icon_ivi_flower.png | Bin 0 -> 24475 bytes + data/icon_ivi_simple-egl.png | Bin 0 -> 29316 bytes + data/icon_ivi_simple-shm.png | Bin 0 -> 71120 bytes + data/icon_ivi_smoke.png | Bin 0 -> 46577 bytes + data/panel.png | Bin 0 -> 41955 bytes + data/random.png | Bin 0 -> 4891 bytes + data/sidebyside.png | Bin 0 -> 3929 bytes + data/tiling.png | Bin 0 -> 5620 bytes + 14 files changed, 41 insertions(+), 2 deletions(-) + create mode 100644 data/background.png + create mode 100644 data/fullscreen.png + create mode 100644 data/home.png + create mode 100644 data/icon_ivi_clickdot.png + create mode 100644 data/icon_ivi_flower.png + create mode 100644 data/icon_ivi_simple-egl.png + create mode 100644 data/icon_ivi_simple-shm.png + create mode 100644 data/icon_ivi_smoke.png + create mode 100644 data/panel.png + create mode 100644 data/random.png + create mode 100644 data/sidebyside.png + create mode 100644 data/tiling.png + +diff --git a/Makefile.am b/Makefile.am +index 48cad9b..f25b898 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -668,7 +668,19 @@ dist_westondata_DATA = \ + data/icon_window.png \ + data/sign_close.png \ + data/sign_maximize.png \ +- data/sign_minimize.png ++ data/sign_minimize.png \ ++ data/background.png \ ++ data/tiling.png \ ++ data/fullscreen.png \ ++ data/panel.png \ ++ data/random.png \ ++ data/sidebyside.png \ ++ data/home.png \ ++ data/icon_ivi_clickdot.png \ ++ data/icon_ivi_flower.png \ ++ data/icon_ivi_simple-egl.png \ ++ data/icon_ivi_simple-shm.png \ ++ data/icon_ivi_smoke.png + + + if BUILD_WCAP_TOOLS +diff --git a/data/COPYING b/data/COPYING +index 430a864..221244b 100644 +--- a/data/COPYING ++++ b/data/COPYING +@@ -8,4 +8,31 @@ http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative + Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA. + + The terminal icon is taken from the gnome-icon-theme collection which +-is also distributed under the Creative Commons BY-SA 3.0 license. +\ No newline at end of file ++is also distributed under the Creative Commons BY-SA 3.0 license. ++ ++ ++(C) 2013 DENSO CORPORATION ++ ++Permission to use, copy, modify, distribute, and sell following listed images ++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 images ++without specific, written prior permission. The copyright holders make ++no representations about the suitability of these images for any ++purpose. It is provided "as is" without express or implied warranty. ++ ++background.png ++tiling.png ++fullscreen.png ++panel.png ++random.png ++sidebyside.png ++home.png ++icon_ivi_clickdot.png ++icon_ivi_flower.png ++icon_ivi_simple-egl.png ++icon_ivi_simple-shm.png ++icon_ivi_smoke.png ++ +diff --git a/data/background.png b/data/background.png +new file mode 100644 +index 0000000000000000000000000000000000000000..60c317c945ae3a8c9f0875cc59a80fd248692fac +GIT binary patch +literal 245579 +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 +z0`ZFh$I>KaVvGbMxY�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⪻2o(9WT- +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 +Hu0mjfAuR9E + +literal 0 +HcmV?d00001 + +diff --git a/data/fullscreen.png b/data/fullscreen.png +new file mode 100644 +index 0000000000000000000000000000000000000000..dc5a302d55f2d7910729aa8d68358160ec8d869b +GIT binary patch +literal 3406 +zcmV-U4YBfxP)<h;3K|Lk000e1NJLTq003YB003YJ0ssI2ZTjGE00009a7bBm000id +z000id0mpBsWB>pF2XskIMF-vj7z8Oh`N<{x000c_Nkl<Zc-rk;*=`)i6|GZM-95wM +zaFMuLj49Fbg5)7F3_m1*AN(WvxqLwWA+V76$xB{>7!F{FG9_}jh_jKs)Xl?e-Cavp +zYetl%(TI>BPIq<Ht#h|?Zx{ahx4$RnXM_Lzc-uKm8598K{UOE}V|Z=X-|dH#qAZQJ +zcGmvzd31l9;+UySrWc)T&{t8jxxKr&+KPgJh-fJV1R_SHqDGP>Y4=JAN#OGKzyHp{ +zMz(Q(Z-4Krj}8wu))SRwiWadW`G<Q5NPp(th;lM3&bgH0^u_59-+%Y4^CI2;AX{0L +zap$zLy}Pr&fAsOk`w#ZE+AFD2ifED2VIC`|sw)?TJ~9o<7-NhJ5rknJCu-0~@8#~p +zkD~1@nE-pO)>n@Y_a5wB_xfj-mjD*Cb+kAE(Sl%Q12s($6a*(P&Q4x-rIcShJow$C +zBS{QVC?9OBZM9d<E-yRRT_JcaOMO=+bfE|`iGC!YtNySTC!4M2?pph3>z-tc5wSE= +ziBbTB-~zltKIDOdg-aL<lAujz!8qrfgL80z5lfYdvrIC^7*R$_DPmv%0Ompv6$Ul` +z{w__ddsaTzPwv8a`Qz0qQkhcH1_7(9$;oa4QeuoTl%!RX9*mX-xqnH!m#nrZKL;{S +zm#o$d<;gN~*g&p5Z<#*^#gQOP1&bWkY<2}+#z99DRr(}UJZm%#Jp5c4n?8Dvv2@BZ +z;-wqkBd8<;Ifcy#L&Q+D?>-Vk&2O=waTetfO6o#J1TkQW;N^x<QE+l38kF_6;ONN` +zX@Dr_*T`vykh_GcBV}k;63qV5^7P_e&NvM;S@UG^x$k({Dq@)dG_ygN*`T~+DZk(4 +zJ=dd00@FN{C8~nW6A)vJ2uA1-bRSg43;ZbpxV#=Cl+ZbXip={^&N=6Tb0F{SDCb~N +zM15XLO#8Yb{6|scU<xnGi#0iIvOInAUn0le<Oky5x@(fNRRBWDAPA=NDRVerm^{ui +z@ixZv_D!sjkQx&kGVhY7L7x06LUUxK0nXDTzC1fSy|^^79i#A^v}GZ;D)I>P&BhyA +zuwRud>qsJtYFQE^EoTK-qtRU5*Z`lnbL0dhr5yBnKmGXqPe1=$j$|uo9r7k|$a{pk +zPkd!!fEW=27zeiZAAI)37mxzHsA3}oC2`z&{`~6nbZ2L$)movctZT7ZzkLDe+5y}Q +zhnMH)D~%}P2%1eHIL&ggiQ6EeOsTD{t*^iS`r)I8S(*|Nm0}?Ox!RSghLq`5uXOyf +zI1SE)l=9^G_+L-HiJFar&5bxqLn+m$a)FT-!$^sV7_GEgkB*K$`Rvo~U=SyX7x`M3 +zY$r!nJKqTPpCyC{!XQy9Y%~PttBvqB6#~eV%Edv&wQ;aGNl&h>uls|M%cnONJid-c +z=f~uN%OE_yygKjoT2Yi_S*hqXi-Q0NA#R3)XHTEr#L53&oL&uvd_u3Giq);Wz~33W +zHPYYI_#l;YE`;p7c>c22i^5PZcggAfobw<EPM^R0_Q{hV49~jVVH`s%armza9sy1@ +zOEfoFs>cM9_;%3k20J?(P(;WjU9uEeGh)O@aI_myLrOirc=rSZ;8uWcZv!bgpo|D& +zj47p(Bx$d&fBEOX93CDfNs_7Tolj3W=TZhI&yK%+@}$8z7*l2ċNrJ^X>KR9^! +z_;G(QOp@fTh{o4iFmio_;6V_^X&Qu~G66#7kv5W(%F_N|@bv8bdN?xD&{k1JL+4|9 +zr$%CyP1;7wKb@QbCu)Qd1uqsnJ3a4od#lYxrpoOtQXhmA#YuWS9A5VNV(i9H?NKmu +zpH!^lu<E3g$_w&0SK8A(1w>O73xeyxU=YVq7!XnE$r2`(3}6CWa4s<U7DkpYH)m+{ +z3TM!kM<v7*ZicD+L<WpNLn`z!wZaGr?9I&0b8ybNr6oaHQe*(&qrawK!KE!Irt^TQ +z$^<R^flh|8B5zh*u7xR`huaunmc{eYBF7XDn9WFAQw9J|Hh20PULvcRg=p4lu%?0? +zSyYU4x#r1Zs`lzEKU<6k>gWFsQ&uqZksQmQQ(ub$M2^F0WsYne1VWq^F`m!4wi> +zj(#E6@BQw9#nq!;0zAjwnCiFV{2h$A<LafVZrG|h<y3<-?BUMU<c&zjf^P8N=8WI0 +zm~39`RfqJU4HrB8MU%OXt9UJo`mVypAxv4wv{1HM$VY&>8?><)uePgo`4Jlsa!%WN +ztI=)eFPi-DnJmf;41~89Pk5zUTsCMLBu!fw$P~6)Dg`Jf@1$=coN=>{S;!SH4bc;o +zosq59Oohw@RpBnTixU>!;Vp-co2t=r7@6M(J<ov^H~Dy%jHxEsgj?8DvhkosOp&d3 +z5tb2h<Ijj5Seib-h%rJz-5dy-qucE5Z8Cy04nip#o;8=uYzoLH7dI#E#=39rTXO9P +zS$b>%XJmv5KZpVy24fuL+VZ7|rX5}k-l)?{h|Yk-Kk@Y`4J^2oR%evVhL$g7)>T9L +za-Q4C7N^%V@BaNW{^OwL6J5F3dk{H3veItB4_SB(0LQ`<#YF(Q*T~;v#4Ti5|7P-t +zIB4#@uiN!E{~XMk<KTlZx9YqLiNAy~Ttcx<RKXn1VJmFaVzM|wB6Dg-7W7rO_!X_t +zG~pW&MaXf|v%Y^UvqvMR4T8zOmneUN*&x6JxK=(8WljM#J(~?vUL91W1=Hlm>BX>A +z@ey(_qf~k^lxx&eJ3+Ow9ve`I+1`&vWo+#~!iak?CHW;kI59R;V>@~;-q3LH_5cR2 +zZ!{Z%EN?ThB0=PS!@w2G<az5lZ^7CM9mHMkifMDUV$Bgrqr^$$?Xf{%cQ-jlBt6#5 +zk`02P8PR9=W-G$H`4jUiC3qQ2<UN)v7hCSisuMwO70g*C1N-X}*32VqpIWO=>gJ@2 +zs<Zj`RFFFtgLx0g^!jP7gxROE?mwm*J3h#AcMLdf5Daf%FDDg5&NxW-VWS^woC9B= +zSg+TMTBtM{75q2VbY*(WYCa9+MgP07h7P=S;DIxeE{Uyphy`qgBU_LTt%OcC@<+?F +z@;AWZ8R4{Is6$4AnR<eAP>~u|!8sQ~<W6D8Cn02?9Tlcn3=wFmKg0^HGO#6*w&r!q +zYaZ~i-iAv#=UfQR`Rsfp$Lmmx5jbQJ1YsBiK@cQ`w|(5(M`X#}wb(j$<-{tLJB&cK +zK4~g*QdZ8ud{#|~Y2sYSAP`dKqCCu6$^bbtjsOE24hFv-A17IMe0JWQy$)4ON-giG +z80T7ea|PuqC&>#YJ2VCztZh7g2`@AOQSKO&LW2*NQl6ch+zfBpjfOcFo9ZFJFVD~a +z`OQC~M)RWAAI1qU=xE)L<8Fx2xt=v5e{P1utMl`%%?*a~TQQ@9CP^t3M$y*Z{%stG +zVZ^~!!XOX=<`XL5Iug}2Z~xv*ho!A`h=50=NURkG_tx5nAAZ<qGzNpdK|ooWv^O_D +z{o|hwKmO!{&GpqNOqEiK*fM=qTCIDVo7XR2Dy0kv3WD(d&Tf`v+w1MsC?ZC*H1e4$ +zN<!4Txyh6glk-hv9;K9JgPYrvG?jwe9HdG6$sJy3YNMZ*NUZu~GykJ_P%9Rnt^%A3 +zAv)cDl4VkavnEbV-7Ha>roA+Aw69nmN#u<Cw0rfgZgL6;8o5ihsMF^-5Tk%N7c!8; +zI96)*7L?2%{Wh&8f_WXCVl~Otjt;&fSe-#7m58c0uk#`$Mx%3p`Sh&l{K*Ri0vd3H +zA%4e=VD7`8^=G{bHw!QKIyszedKPlYi<$aB;n#3st=U`R;CarVsC$Y9=?dqJG%W8` +zaxda?nHV9aA1q*ij~|5rOU_l%t_ojR*itU&-T~FKa*sLwQX@SiDa9DgGI%k~;HyK^ +zs`Di*J7jTYhOP*D6)S9;mAk)ul(>$TKZ*>;0#a$p6p26vQ4~a>Oj8cPQCass+LGBA +zMSs?r>ZK~~S=kRXm<ULSAP9vNOevZiMI~FiduTRKU!2~?$?^F`cQBk<aw8u`T6{uo +zn#yFjL7FO~D(EsC@L?bf3_&VYM+jrZ;t)b~&N{5wYOJ+o7;-SV_xYEIZ@&NTyQF)4 +z)*lSxWaR6p=p|v^lPd5y-973gmSbXsY>Y~t%%DnO6HL@45h;aci*N7UKYG+`uSqbu +zvb~#JU7S7tHSPAK6zk0fF)g0AuaWFjS!I_49NMc32u_?)PO(59`dmC|WGo*=Y1UY8 +z-#dD=_uxS{O@HZJNEP3*AP5c~?mhnG_aE$St+q0iDIyP(;CXnL50BwPP57L~$f_09 +zZ3l>C7&h8#-6Z|_v~$%TO3E_Eg;-l}-`hC+=;&Z`J;^eqRGmoCXC8|^LX#GBrOB6p +kNydKZTwL{sPcN?i4_e9s)xMViO#lD@07*qoM6N<$g2DV?+yDRo + +literal 0 +HcmV?d00001 + +diff --git a/data/home.png b/data/home.png +new file mode 100644 +index 0000000000000000000000000000000000000000..af9f60372169a77d2bb18decbf52bb769bfa0c59 +GIT binary patch +literal 4629 +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 +LNkvXXu0mjf_(~g- + +literal 0 +HcmV?d00001 + +diff --git a/data/icon_ivi_clickdot.png b/data/icon_ivi_clickdot.png +new file mode 100644 +index 0000000000000000000000000000000000000000..711bcfcbd616fc6715053a87bc2cb7410caf3493 +GIT binary patch +literal 39523 +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 + +literal 0 +HcmV?d00001 + +diff --git a/data/icon_ivi_flower.png b/data/icon_ivi_flower.png +new file mode 100644 +index 0000000000000000000000000000000000000000..0a71479c6fec61bc29e755ba6236aa1681452cae +GIT binary patch +literal 24475 +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 + +literal 0 +HcmV?d00001 + +diff --git a/data/icon_ivi_simple-egl.png b/data/icon_ivi_simple-egl.png +new file mode 100644 +index 0000000000000000000000000000000000000000..02539503312941be368a5b69b21c57e135d4f5f5 +GIT binary patch +literal 29316 +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 + +literal 0 +HcmV?d00001 + +diff --git a/data/icon_ivi_simple-shm.png b/data/icon_ivi_simple-shm.png +new file mode 100644 +index 0000000000000000000000000000000000000000..6aacaaa8743c2ce103fe033911052d737511ee24 +GIT binary patch +literal 71120 +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 +MPe+G64~ftF9|U`lMgRZ+ + +literal 0 +HcmV?d00001 + +diff --git a/data/icon_ivi_smoke.png b/data/icon_ivi_smoke.png +new file mode 100644 +index 0000000000000000000000000000000000000000..0dbe20ea0198b8d45e6b13e3b15470a0120faf45 +GIT binary patch +literal 46577 +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 + +literal 0 +HcmV?d00001 + +diff --git a/data/panel.png b/data/panel.png +new file mode 100644 +index 0000000000000000000000000000000000000000..0fd72b87f988bb5745f952545e163c7ee8f0784d +GIT binary patch +literal 41955 +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 + +literal 0 +HcmV?d00001 + +diff --git a/data/random.png b/data/random.png +new file mode 100644 +index 0000000000000000000000000000000000000000..7640aa052db2815aa29cae857f9cceed13774e07 +GIT binary patch +literal 4891 +zcmV+$6XfiPP)<h;3K|Lk000e1NJLTq003YB003YJ0ssI2ZTjGE00009a7bBm000id +z000id0mpBsWB>pF2XskIMF-vj7z8H}%l7dy000uYNkl<Zc-rM%+j1O7a;=k9)pNyw +zAOR8-B|(%($zgk?UE6x_I`)D35dWM%z#k!UL)sTz_QkOqp>T)*2?7{gW`Jo-Un>33 +z-7|fu>h1wX&~A8w5e&}sr7A1y<jGT6Mf~S~{dYJ%p8d~{^OK`UzyJ`fKP-e00>9Yx +zcl%*uIF35o4@dv>yUv3h4gz6f6`h{Mvn$i-^>!X@4F?^qnVJ7z8VJmS*>t*L97fY~ +zBNc<x{4alwy>5K(!S3VTKYX(H{=Lo6#IfOZj7a|FEeuqB=iQhxYZVbGC6C@6{qX&F +z2Pf~Mo%iDYPz5JP-JM4dA3y&1`SZt5cDFbBkuipOoz@X8dd^K(uFLz__E;f=5G1Ac +zydVh8><X6`k3RaOv$L&2V0SS1!?V5JC%co&tK+jX0P7h#UY~(@O>X6KYR)`J>$mTY +z-(F0WQvdqV`yV|0Sg}CIQ%~-Vwm166XJ;pqsg$%5Qr{JXuGNEVrcVrXe&t^V;ntw{ +zXteS1_I)LUU=~qqLSq0(NfOjxA8z3VYqv1gWI@-Qg&-m#5P<-}A~Gh3V<m(T%rP5d +zSU>;(M4bn5;i2~L?-F9`Th-?J>@K9;PkV3J#KtI>3phhf&UTrTvJgU`WUZ3*U_~0_ +z{^rWP?8Ksc8`#=hcA^=|jTKyjfvWO8%ZG>-zZ4q{A()rWTIdB5=QL}f40ptYs@+#$ +zEDVdBuPp}?AgPGR9S1D4Klz6-Cgw<Rj21BomG4pU30r(^_RTi)9;tQ8Hd3V<QL-oy +zg~8<fESv{6f{jXVId`wnp4S@;m8S*s-;W2OXdo<x4?=*Kodk%al#{cwzyA4$@!?_2 +zhS@T*)!CmQAQA3A+I{xVUu->mDB?J0U)(5A-R9So0vlUBNB|2D#=-|k$}kAVhll6K +zM-O(k`~5yIrj)30R$Tl3*?8R5x+^j2b+7#EFp6-a#sdT_=AX@r;Q-lcsL1|e!%bvA +zy;misL3!S$bUMK&!~9@p=f#T`dwY9v94EMoT(rywAR<yqzdhLh_T@|Mc^}-rcYkxV +zA4c;qr1YuW%#@M3A^@or5ha(f;0maKYnXW9a?X&EV~*HxHl;Z0b0O9wPgiABgvDD8 +zi~gYh^y$;*pZ&vhHVeWK>E(+6x$L%-QhQ!#jMwdw5W|i)>~^FiUfp#BAqs=Z*;yC_ +z%whp#IXDNm;k0>=0<_oZ4Tnm56=Ymu5DHU_D?YfmhLeXdgdk85MQ_h1ldBmK@<z#r +z43ea@w|{zZGQApT6~;#JGD-p#w`WGdb&@6!ky4Yhv%miM!}#4{Y*GXStSLhyGvvhE +zLG<9!?z7)~zP0mE7{hFq?!{%sgFFVgksXrcd_F&T{j)z0emXinznT#WWINBnh#;jp +zd3Sg*z4W#=4L9ciutEzUiJ~AFzdJlXN)a$4744M~&SP1Ej6JQpgpGc8=3j@Af#o5v +zfb^1WFF{E#1QBUZPfy2x`r|99z2nK$4+7Mu{6HAYXO~m8vrRw=391ac%Flpg9<g9H +z#%ynIzj*Q0-rimuM{JnI%A{d|jNiO`sXg!g`}ZD<HeZL)JP0XEF92T9p~XB_O)#*W +zlFUL9HoBdzQnlHd05F%}`P@^or7!@eS1_~a4+l@5K7Ib#XL$r%=_94oT4%_}!%k<| +z^%Rwn5#>N3R3Z9hFp&o<HYN&#jnU@6{rm4f{P4pt3}X}5j+Iney*=3f_SLJ7B!XZT +z0-Otr6>iVXa}dBhLBQFJR+p?YWIP{VUiP#OO`Ok<%D@9&e5IDHgo{G4F~;lnA3u5W +z(X(e)Ge3;N8kV0#u^@`H=NV%Xe#kdqb7`v}CC%s82d`iILGaVNql=kOVr9XKh)AmO +zyTgm=rB0EN?fFqT7eh;7h1tYc{_OS1crx>ea%0HVvC;=eCnwX(f#=1X_zoK9l7${+ +z2sjy!|MbU~QhUeKsUHM+loYMQJP1KBzq*|6CdkMwP#y~mLURtl%wZT!eE;m~ijY&) +zxI9);>&eWY%>ykZ3%<QD#1KXZZ-IaUXqjVhf!`;{sAYzXErfGb9kc|4*r5d_rjZ#D +z%9GXf0Ys8OdFiQjLS2G_M70XTa5UQdvV?%`6<AIteip@Ez3NIz{FuS);Kuea-!?Y_ +z64bN?Z(7Qd^{;N}JZxg)4f^jb5HJjjT$fu$F;Az+$i^(hlg0s5!V2ahFAq8U+32Cw +ziHq_RP|=laoQT=P@oeVrACD)#pNnGLQlTeFT6+ga;{+LvVahV|ybzYp*_TWjwoI`W +zxf+AAU0_-@HY0xvn;;A)zJE5oN_F+7Vd66R2q!b&p9dW&v&6&MU%00j+`(p<&Y_{V +zKv8Li!-wDyCaSh(AyNb+$fbE;6*Q_ZBBBI6b23G4Nz5$?shYuWFWg%A_w5xe%X<Kk +zh(l-*#>yi>*@DeVj;xAiXD+RYw1-(MfLRtc8uerpMygD`nXPuoPiU(fp#ch9Us7(! +zQ64qapzVrCVv~DYnAw`=H9PU@VyoMO@@gUq*qCJ0sA@h-?!b00U@j*Y$od8#FaC3m +zO0|y<sp6Rf4X!Ndq3V`4e@r_I;o`GYyDnx2V>B$MSk#MlgANx_Xps`Mf;8BsQm%t2 +ztnD!tAkCucJ2_!yA$1qVP#_y7<c&=^J)jz~EAkIJ@R;2To@|SXppqloK!=N{fjqpR +zC}m{dH#2F@Q3)v}NhwKExxQhMoPd%`Xjvk1%M}^4h@Pm`m8`>L9mkw-Xk*fOH!G># +zM5LAWw5OF;S`mm~9Z*3emC{mb2nc3yJ@&%EVamA*N*J^v@S<r9*#14M8Wxwwk89t5 +zv%eoi(ZTU}GV=*eMFvDts^i1A^J{<D@x-k|U~ygQ<^gP_U<`*Q%_VP4h!ug(#wXvr +z{MzewPo|fC5RiKmlMr)#?Vpdw_eZ1lOzPLI*>W@!8Bw&;FJ?B{^Bz3f?P{ev9tkn< +zJWtAk23E!_7AyuG@BV1Cx3|~p_KYz%kl71C9D<0XOq3L&<@|24H!qS^NhCpuQpWAg +zR0q<=7!Je!VEFv=FFJ%LTbsj<7shc~(9)<>LG-%4`&(P{FuGL{3=05CYwdYTYo&Fe +z2F{h$mkdNwX)UE%ESId1YSh#tFdOB0_a8nS_PX1njX}rbHpRW!H*Cy2jHdo|Yz*CK +z7A0-VBj81XfF*Xz6~8MRC`HEWYk$!33jPm=27rYoT}*sXrq#?Qp841NVJJbhIabkN +zoGxoc#)MH!3u?eEK!_LBa3G@7@yR!@zV<rZlSzhvfK%FVBzOg6Tm<t>1S$_aY??G& +zA(T0cq96>I8%VSbKLk>pVP!3mjnSP90X;8S>F-D>sDgk^21@duB{KGU%qCw7VVSb9 +z^B{Yl3Bpk+kar6%#6!v#Q=yhOTg+qFa1{0j!%si|qC<FZYjfD~q6z|XNyAyFf$U_w +z2{HyzB#bGgT_yPx4n4?~%mD8C93rRIZ^xB7l{Fi32(R1Q9t?-Q?!(c>pyMSAtyOgk +zLNGHkCwEmNY$2C6CWxY`@5jcV*r@zJkzab|C6)k|bd>9)F=h}+r3iA7;Im!ksd!Lr +zB|;{PQW(WY7n7_`5~YcQtlM!E8Dmldq4a!YB_v=@kTFh?F%uM6WI{zlm|q1g03nE? +zAefw;hCz_-6mnK~Rt?mQ*hwX=VUxN?dFWUOL4fwW-e5y}y71Nl$3q_9AVir@<#L-! +zE|$F+C_anJ5(`Q-TOg^_<m~h>KYo9F_|_O^W>J}pw`9pl5s?FkSqKpDV0ZV^-~6`s +z@F6d%ez-_sU=x;dY7|%?n@U{dLAOY|0gw!X;P~+E+0nc0?VbLh&v#hU3c|JTpN_{p +zPj@9Y`n}opbr>;RmH%9y(V|Ke!8J&OTBR)28`&@$!`s_CFTVO}Z*MP-BEzOxK)JPR +zB~?Ff_V>Se`L*tN?`>^vk2Vg%Fsu5hnY(byyl`UB&8kpSBw+3j(>lh>*(?ad_Gs3= +znxSGKsXZ?;rqk_0@WAs19ZwSYHhY7bLArIG&E?sRw2J3qGEF5Btbj6hMqSr{biMTK +zVthI4X&J?FzNiH&4hh;MtGJQH0Z1u>`Sro;pZy^C-=mX@*{pe6)vY}!2@xlUZ!az{ +z_2$SpWr>@Alr^ljUkb}AI-s<^I6e9H)k~?p@$_<5g97XGpyZb@2(G4+-R%eMMP96K +zpmnS)v0xU8XxQy|N&#(Kf)>W&8gWj-%(a%1fVGEDRnL_h9Di9@z+o7UHt&7;`~OI* +zc;fixz}TGf^8$mE(r*s-zkT(xlT`h%s4YloGbIYQTlJuoAI-d|V|@RkXV0%@voKnz +z7WKvklG@Wj6l<@;#;luSK?tEx$gA=KNjqVTQ}H@k!!U7tHS-U~r%4oZ%hs+%4K!d6 +z7ZfNWskOI%G9FK_`ksyr7whoRs`P`g%t!OP0)!Aq*2UJaezjB}!zi52{IjboM-*#Z +z^+BzH3R(w|lscUF*M1OcDVZ6oZC$O68B0BgZ2`==wGVcU8|g2J1}Ldm<<uOLP^`GD +zos7r{sUQMCnF^6Fl@Msf+L!&Z_?ueyyv;gTvwIphLnX_P>D-3M*Zn|XRZYU4iP*Lx +zpt2x~lCaRWoWL4LP!_R^wPk3ej<zRQrDV8)6cueg)he)92+XyeZk;w3cQWysz-&eD +zf^cp-yxoIynsjl@QLWaq6_%nz8&Fs*M(JL5)*`y+kR8C7ioC_mB%8g}RUDB#nQo9_ +zv``T4$b;5X3|V`(a&SquY}T;tTrVD-z?Da#Ns_u5nJoAwEU@ByyDJTZqs?@uL%)7s +z!Y_+$`F-=n6vV<oT^m5GyTEQ9-^EIKJ+H8x-oc4ba-ovsBt(U+++7Lj-<m(#6h$oP +zrt6G}nla=RZNx47f>$(my*SvsBwc^-!Xk?C-@V7+mwB3UB|qimPiy9gWfZZN#-n<@ +zO<CdE_tt|+ePMnZ-VdASRd^7@txk4>B~ISOIcTMqLfonwHZ!Xt>jZ3T^Ki^VS4{{O +zl@eBYhg%R$w)<LX?Yh9EVL_pKL9~uwW%tu<$;Gc6s@wt%Zu+!h>2Z-sg9SKEXxT*@ +zN@5(ALW3;|uq89%3M!R}xO1YUN4;R#-n3j`aq>o%kXLwnx={$IH#QhcZ3v+Cy9Dmg +zyGolI`If1nJDbntH7iXtI86gLQad)op`oHZAGB=8^?@t<rm-S)SjY~obujVk026BV +z%iZ>)Zs~z#lCzGT;48O*-6e3XsPx(l)Cf6?tv<;g*SgQm8f{5iNJ^5aZ2t=dSF0xN +zs!>F>b2*1$07^OP;R|M98v){`lg&zds8a(;t))_V{TVr(lWoeOgQK(6`ISv;T-E$Z +zoX55AzuA8sMA81q+0^%CWq&a{Jg8dpS!<wNaWj!r>iF%Ox$h4=U1&Sj186FL^jmI0 +z39f_(RXUyRwmuynfAjKduhSi0UR?(v{qng+^5$zlsh{6irc7B;FYJe7IyriEa;S>; +zt!jH_W3<=V*?qjIhaY&_lM>=i!WoN!r|*w8_V)Jry`C{9o2<P0>tU}^v|uRO)e}G% +zW{#r%aQNwOf7b!;ZjJ_?j^cG3`o7|)+v{y@-3y{{`D(Vog-e=nL=@FTlv;X__u%2f +zVYj=pF&KCr-{sM*oK7ZVOb~^a*Yh|wxOw?Y*`~_wKJ6$7mY~iYo7wgCn=q8F&2DVL +zfP8ecgLJ*N&ACEuX2TrECX8e2#-eJ{Z{czkkWtBDIz;JKWs=n$%}y{wvB$<3KaLw~ +z=TV7g5cWC)*S_%FPOaiv52pv9NTRIz+|hhn4~b;b{iNP0HIRuSVOVOVJ00EeR1_tw +z%f;Q99XbwIx>PyP-Oi>OCFja^B0D^ym_1d7lO3;H9t|a>)}B<7jp6M0Vl{lUi(c>O +z-O)S<_s6HxnZJ-PoCn!(0oqtt!@naH$u8zLRc#LCq;w;5Z5XezF9%kDAf-GxKB4}g +zJK9j5M-b}qzkEsa>+iq&E}Tw|uV#J_CISx^QyJLDq$yFTEmB22F)S%Z3A3@eURsy9 +zEGpy1B!*#=E}7XF^ar%FyZ!WOZ!}UusKL&o;QaLX@J%$mR8nsCy453hYx-E8=xzE7 +zhk<I74Mwe>aUKtId>bv!r&^3N8;;`cXk+{7)7|%<OvC8s(^C}(bD^~N!AHB#KK;k{ +zcDILv*u;jp1rb7{nBqXA7Wm&#O1{#61GEC=U}oicy^YZ{jD9*gIiLB8<5-ZC8=D*V +z@9ll^@%vkwVH_J{+A_tq?YN25aJzTih}uDr5K4%jPfpKg{_E58{{x)L(EOMxu^<2d +N002ovPDHLkV1m))aYg_D + +literal 0 +HcmV?d00001 + +diff --git a/data/sidebyside.png b/data/sidebyside.png +new file mode 100644 +index 0000000000000000000000000000000000000000..98ea7803b39202f969f920b3fd2b4dc7e3a4ef8a +GIT binary patch +literal 3929 +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 + +literal 0 +HcmV?d00001 + +diff --git a/data/tiling.png b/data/tiling.png +new file mode 100644 +index 0000000000000000000000000000000000000000..dd3e02c0fb4c6844ae7a9efc1a2aaa82169d8019 +GIT binary patch +literal 5620 +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 +O0000<MNUMnLSTZaONc!H + +literal 0 +HcmV?d00001 + +-- +1.7.9.5 + diff --git a/meta-ivi/recipes-graphics/wayland/weston/0009-ivi-shell-a-reference-of-weston.ini-for-ivi-shell-an.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0009-ivi-shell-a-reference-of-weston.ini-for-ivi-shell-an.patch index b8b1499..cc1ee06 100644 --- a/meta-ivi/recipes-graphics/wayland/weston/0009-ivi-shell-a-reference-of-weston.ini-for-ivi-shell-an.patch +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0009-ivi-shell-a-reference-of-weston.ini-for-ivi-shell-an.patch @@ -1,30 +1,36 @@ -From 93a62d17c4673d40b3b83807d20c2e2cdd508f35 Mon Sep 17 00:00:00 2001 +From ffb5dfe56a1d9ba7ad43cbe74f6a09565fc4e2e8 Mon Sep 17 00:00:00 2001 From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Date: Thu, 6 Mar 2014 11:03:05 +0900 -Subject: [PATCH 09/31] ivi-shell: a reference of weston.ini for ivi-shell and +Subject: [PATCH 09/15] ivi-shell: a reference of weston.ini for ivi-shell and ivi-hmi-controller. +- introduces ivi-shell/weston.ini.in + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +squash ivi-shell/weston.ini.in from transition animation + Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> --- - Makefile.am | 13 +++++-- - ivi-shell/weston.ini.in | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 101 insertions(+), 3 deletions(-) + Makefile.am | 13 +++++-- + ivi-shell/weston.ini.in | 93 +++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 ivi-shell/weston.ini.in diff --git a/Makefile.am b/Makefile.am -index 98995b4..835d721 100644 +index f25b898..89b7025 100644 --- a/Makefile.am +++ b/Makefile.am -@@ -8,7 +8,7 @@ BUILT_SOURCES = - - DISTCHECK_CONFIGURE_FLAGS = --disable-setuid-install +@@ -11,7 +11,7 @@ BUILT_SOURCES = + # Do not run xwayland test while it is known broken. + AM_DISTCHECK_CONFIGURE_FLAGS = --disable-setuid-install --disable-xwayland-test -EXTRA_DIST = weston.ini.in +EXTRA_DIST = weston.ini.in ivi-shell/weston.ini.in weston.ini : $(srcdir)/weston.ini.in $(AM_V_GEN)$(SED) \ -@@ -17,7 +17,14 @@ weston.ini : $(srcdir)/weston.ini.in +@@ -20,7 +20,14 @@ weston.ini : $(srcdir)/weston.ini.in -e 's|@libexecdir[@]|$(libexecdir)|g' \ $< > $@ @@ -40,7 +46,7 @@ index 98995b4..835d721 100644 AM_CFLAGS = $(GCC_CFLAGS) -@@ -33,7 +40,7 @@ AM_CPPFLAGS = \ +@@ -36,7 +43,7 @@ AM_CPPFLAGS = \ -DLIBEXECDIR='"$(libexecdir)"' \ -DBINDIR='"$(bindir)"' @@ -51,10 +57,10 @@ index 98995b4..835d721 100644 diff --git a/ivi-shell/weston.ini.in b/ivi-shell/weston.ini.in new file mode 100644 -index 0000000..3c9fb6a +index 0000000..f8ef12f --- /dev/null +++ b/ivi-shell/weston.ini.in -@@ -0,0 +1,91 @@ +@@ -0,0 +1,93 @@ +[core] +shell=ivi-shell.so + @@ -70,6 +76,8 @@ index 0000000..3c9fb6a +workspace-layer-id=3000 +application-layer-id=4000 + ++transition-duration=300 ++ +background-image=@abs_top_builddir@/data/background.png +background-id=1001 +panel-image=@abs_top_builddir@/data/panel.png @@ -147,5 +155,5 @@ index 0000000..3c9fb6a +icon=@abs_top_builddir@/data/icon_ivi_smoke.png +path=@abs_top_builddir@/clients/weston-smoke -- -1.9.3 +1.7.9.5 diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0010-clients-support-ivi-application.xml-for-clients-simp.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0010-clients-support-ivi-application.xml-for-clients-simp.patch new file mode 100644 index 0000000..5f0220d --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0010-clients-support-ivi-application.xml-for-clients-simp.patch @@ -0,0 +1,164 @@ +From 7fb2e8ec7eba02a6802c73f5d1d766a5de9308af Mon Sep 17 00:00:00 2001 +From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +Date: Wed, 15 Oct 2014 12:09:35 +0900 +Subject: [PATCH 10/15] clients: support ivi-application.xml for + clients/simple-shm.c + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +remove NULL entry in listener + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------- +clients: simple-shm, remove visibility listener. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------- +clients: simple-shm, remove unnecesary roundtrip + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------- +clients: simple-shm, Opening brace needs to be on the previous line. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------- +clients:simple-shm, Indent with spaces, should be tabs. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------- +clients:simple-shm, simple-shm is not resizable + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------- +clients:simple-shm, remove unnecesary addition + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +--- + Makefile.am | 4 +++- + clients/simple-shm.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 45 insertions(+), 1 deletion(-) + +diff --git a/Makefile.am b/Makefile.am +index 89b7025..df67cbc 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -410,7 +410,9 @@ nodist_weston_simple_shm_SOURCES = \ + protocol/xdg-shell-protocol.c \ + protocol/xdg-shell-client-protocol.h \ + protocol/fullscreen-shell-protocol.c \ +- protocol/fullscreen-shell-client-protocol.h ++ protocol/fullscreen-shell-client-protocol.h \ ++ protocol/ivi-application-protocol.c \ ++ protocol/ivi-application-client-protocol.h + weston_simple_shm_CFLAGS = $(AM_CFLAGS) $(SIMPLE_CLIENT_CFLAGS) + weston_simple_shm_LDADD = $(SIMPLE_CLIENT_LIBS) libshared.la + +diff --git a/clients/simple-shm.c b/clients/simple-shm.c +index c1cb386..e6025aa 100644 +--- a/clients/simple-shm.c ++++ b/clients/simple-shm.c +@@ -37,6 +37,10 @@ + #include "xdg-shell-client-protocol.h" + #include "fullscreen-shell-client-protocol.h" + ++#include <sys/types.h> ++#include "ivi-application-client-protocol.h" ++#define IVI_SURFACE_ID 9000 ++ + struct display { + struct wl_display *display; + struct wl_registry *registry; +@@ -45,6 +49,7 @@ struct display { + struct _wl_fullscreen_shell *fshell; + struct wl_shm *shm; + uint32_t formats; ++ struct ivi_application *ivi_application; + }; + + struct buffer { +@@ -58,6 +63,7 @@ struct window { + int width, height; + struct wl_surface *surface; + struct xdg_surface *xdg_surface; ++ struct ivi_surface *ivi_surface; + struct buffer buffers[2]; + struct buffer *prev_buffer; + struct wl_callback *callback; +@@ -134,6 +140,17 @@ static const struct xdg_surface_listener xdg_surface_listener = { + handle_delete, + }; + ++static void ++handle_ivi_surface_configure(void *data, struct ivi_surface *ivi_surface, ++ int32_t width, int32_t height) ++{ ++ /* Simple-shm is resizable */ ++} ++ ++static const struct ivi_surface_listener ivi_surface_listener = { ++ handle_ivi_surface_configure, ++}; ++ + static struct window * + create_window(struct display *display, int width, int height) + { +@@ -160,11 +177,25 @@ create_window(struct display *display, int width, int height) + &xdg_surface_listener, window); + + xdg_surface_set_title(window->xdg_surface, "simple-shm"); ++ + } else if (display->fshell) { + _wl_fullscreen_shell_present_surface(display->fshell, + window->surface, + _WL_FULLSCREEN_SHELL_PRESENT_METHOD_DEFAULT, + NULL); ++ } else if (display->ivi_application ) { ++ uint32_t id_ivisurf = IVI_SURFACE_ID + (uint32_t)getpid(); ++ window->ivi_surface = ++ ivi_application_surface_create(display->ivi_application, ++ id_ivisurf, window->surface); ++ if (window->ivi_surface == NULL) { ++ fprintf(stderr, "Failed to create ivi_client_surface\n"); ++ abort(); ++ } ++ ++ ivi_surface_add_listener(window->ivi_surface, ++ &ivi_surface_listener, window); ++ + } else { + assert(0); + } +@@ -350,6 +381,11 @@ registry_handle_global(void *data, struct wl_registry *registry, + id, &wl_shm_interface, 1); + wl_shm_add_listener(d->shm, &shm_listener, d); + } ++ else if (strcmp(interface, "ivi_application") == 0) { ++ d->ivi_application = ++ wl_registry_bind(registry, id, ++ &ivi_application_interface, 1); ++ } + } + + static void +@@ -451,6 +487,12 @@ main(int argc, char **argv) + ret = wl_display_dispatch(display->display); + + fprintf(stderr, "simple-shm exiting\n"); ++ ++ if (window->display->ivi_application) { ++ ivi_surface_destroy(window->ivi_surface); ++ ivi_application_destroy(window->display->ivi_application); ++ } ++ + destroy_window(window); + destroy_display(display); + +-- +1.7.9.5 + diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0011-clients-support-ivi-application.xml-for-clients-simp.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0011-clients-support-ivi-application.xml-for-clients-simp.patch new file mode 100644 index 0000000..7ff4a4d --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0011-clients-support-ivi-application.xml-for-clients-simp.patch @@ -0,0 +1,397 @@ +From 072fc2e415ad7ba7e2737ee1a71c2ac1375a8f5f Mon Sep 17 00:00:00 2001 +From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +Date: Wed, 15 Oct 2014 12:13:14 +0900 +Subject: [PATCH 11/15] clients: support ivi-application.xml for + clients/simple-egl.c + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +remove NULL entry in listener + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl, remove listener of visibility event + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl, remove unnecesary roundtrip + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl, remove useless commented code + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl, Opening brace belongs on the previous line. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl, Follow the style already in this file: 'else if + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl.c,Fix invalid function calling. + +> Calling handle_surface_configure() is detrimental here, you are +> confusing +> xdg_shell code paths with ivi_application code paths, and needing to +> modify +> the xdg_shell code path to cope with a bogus call. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl.c, whitespace clean up + +> Why this change? Broken indentation. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl.c,Rename variable name from fullscreen into maximized. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl,whitespace clean up + +> Why these changes? + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl,clean up + +> Instead of reindenting everything, just do +> at the top. c + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl,Separate a messy function to two functions. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl,whitespace clean up + +> Broken indentation + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl, replace 8 spaces to tab + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl,Delete unnecessary if condition. + +> You are still adding the 'if (states)' which was not there originally. +> What I meant was, you should not have done any modifications to this +> function. This is an xdg_shell event handler, not for ivi_application + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: simple-egl.c, clean up code + +> You shouldn't have changed this in the first place. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: cimple-egl, Delete unnecessary function call. + +> That's better, now the earlier original changes to +> handle_surface_configure() are not needed at all. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +--- + Makefile.am | 4 +- + clients/simple-egl.c | 114 ++++++++++++++++++++++++++++++++++++++++---------- + 2 files changed, 96 insertions(+), 22 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index df67cbc..081c854 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -441,7 +441,9 @@ demo_clients += weston-simple-egl + weston_simple_egl_SOURCES = clients/simple-egl.c + nodist_weston_simple_egl_SOURCES = \ + protocol/xdg-shell-protocol.c \ +- protocol/xdg-shell-client-protocol.h ++ protocol/xdg-shell-client-protocol.h \ ++ protocol/ivi-application-protocol.c \ ++ protocol/ivi-application-client-protocol.h + weston_simple_egl_CFLAGS = $(AM_CFLAGS) $(SIMPLE_EGL_CLIENT_CFLAGS) + weston_simple_egl_LDADD = $(SIMPLE_EGL_CLIENT_LIBS) -lm + endif +diff --git a/clients/simple-egl.c b/clients/simple-egl.c +index 33e711c..8e4433d 100644 +--- a/clients/simple-egl.c ++++ b/clients/simple-egl.c +@@ -41,6 +41,10 @@ + #include <EGL/eglext.h> + + #include "xdg-shell-client-protocol.h" ++#include <sys/types.h> ++#include <unistd.h> ++#include "protocol/ivi-application-client-protocol.h" ++#define IVI_SURFACE_ID 9000 + + #ifndef EGL_EXT_swap_buffers_with_damage + #define EGL_EXT_swap_buffers_with_damage 1 +@@ -74,6 +78,7 @@ struct display { + EGLConfig conf; + } egl; + struct window *window; ++ struct ivi_application *ivi_application; + + PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage; + }; +@@ -95,9 +100,10 @@ struct window { + struct wl_egl_window *native; + struct wl_surface *surface; + struct xdg_surface *xdg_surface; ++ struct ivi_surface *ivi_surface; + EGLSurface egl_surface; + struct wl_callback *callback; +- int fullscreen, opaque, buffer_size, frame_sync; ++ int maximized, opaque, buffer_size, frame_sync; + }; + + static const char *vert_shader_text = +@@ -255,7 +261,7 @@ init_gl(struct window *window) + } + + glUseProgram(program); +- ++ + window->gl.pos = 0; + window->gl.col = 1; + +@@ -275,24 +281,24 @@ handle_surface_configure(void *data, struct xdg_surface *surface, + struct window *window = data; + uint32_t *p; + +- window->fullscreen = 0; ++ window->maximized = 0; + wl_array_for_each(p, states) { + uint32_t state = *p; + switch (state) { +- case XDG_SURFACE_STATE_FULLSCREEN: +- window->fullscreen = 1; +- break; ++ case XDG_SURFACE_STATE_FULLSCREEN: ++ window->maximized = 1; ++ break; + } + } + + if (width > 0 && height > 0) { +- if (!window->fullscreen) { ++ if (!window->maximized) { + window->window_size.width = width; + window->window_size.height = height; + } + window->geometry.width = width; + window->geometry.height = height; +- } else if (!window->fullscreen) { ++ } else if (!window->maximized) { + window->geometry = window->window_size; + } + +@@ -301,6 +307,9 @@ handle_surface_configure(void *data, struct xdg_surface *surface, + window->geometry.width, + window->geometry.height, 0, 0); + ++ if (!window->display || !window->display->shell) ++ return; ++ + xdg_surface_ack_configure(surface, serial); + } + +@@ -316,18 +325,61 @@ static const struct xdg_surface_listener xdg_surface_listener = { + }; + + static void +-create_surface(struct window *window) ++handle_ivi_surface_configure(void *data, struct ivi_surface *ivi_surface, ++ int32_t width, int32_t height) ++{ ++ struct window *window = data; ++ ++ wl_egl_window_resize(window->native, width, height, 0, 0); ++ ++ window->geometry.width = width; ++ window->geometry.height = height; ++ ++ if (!window->maximized) ++ window->window_size = window->geometry; ++} ++ ++static const struct ivi_surface_listener ivi_surface_listener = { ++ handle_ivi_surface_configure, ++}; ++ ++static void ++create_xdg_surface(struct window *window, struct display *display) + { +- struct display *display = window->display; +- EGLBoolean ret; +- +- window->surface = wl_compositor_create_surface(display->compositor); + window->xdg_surface = xdg_shell_get_xdg_surface(display->shell, + window->surface); + + xdg_surface_add_listener(window->xdg_surface, + &xdg_surface_listener, window); + ++ xdg_surface_set_title(window->xdg_surface, "simple-egl"); ++} ++ ++static void ++create_ivi_surface(struct window *window, struct display *display) ++{ ++ uint32_t id_ivisurf = IVI_SURFACE_ID + (uint32_t)getpid(); ++ window->ivi_surface = ++ ivi_application_surface_create(display->ivi_application, ++ id_ivisurf, window->surface); ++ ++ if (window->ivi_surface == NULL) { ++ fprintf(stderr, "Failed to create ivi_client_surface\n"); ++ abort(); ++ } ++ ++ ivi_surface_add_listener(window->ivi_surface, ++ &ivi_surface_listener, window); ++} ++ ++static void ++create_surface(struct window *window) ++{ ++ struct display *display = window->display; ++ EGLBoolean ret; ++ ++ window->surface = wl_compositor_create_surface(display->compositor); ++ + window->native = + wl_egl_window_create(window->surface, + window->geometry.width, +@@ -337,7 +389,13 @@ create_surface(struct window *window) + display->egl.conf, + window->native, NULL); + +- xdg_surface_set_title(window->xdg_surface, "simple-egl"); ++ if (display->shell) { ++ create_xdg_surface(window, display); ++ } else if (display->ivi_application ) { ++ create_ivi_surface(window, display); ++ } else { ++ assert(0); ++ } + + ret = eglMakeCurrent(window->display->egl.dpy, window->egl_surface, + window->egl_surface, window->display->egl.ctx); +@@ -346,7 +404,7 @@ create_surface(struct window *window) + if (!window->frame_sync) + eglSwapInterval(display->egl.dpy, 0); + +- if (window->fullscreen) ++ if (window->maximized) + xdg_surface_set_fullscreen(window->xdg_surface, NULL); + } + +@@ -443,7 +501,7 @@ redraw(void *data, struct wl_callback *callback, uint32_t time) + glDisableVertexAttribArray(window->gl.pos); + glDisableVertexAttribArray(window->gl.col); + +- if (window->opaque || window->fullscreen) { ++ if (window->opaque || window->maximized) { + region = wl_compositor_create_region(window->display->compositor); + wl_region_add(region, 0, 0, + window->geometry.width, +@@ -478,7 +536,7 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer, + struct wl_cursor *cursor = display->default_cursor; + struct wl_cursor_image *image; + +- if (display->window->fullscreen) ++ if (display->window->maximized) + wl_pointer_set_cursor(pointer, serial, NULL, 0, 0); + else if (cursor) { + image = display->default_cursor->images[0]; +@@ -516,8 +574,13 @@ pointer_handle_button(void *data, struct wl_pointer *wl_pointer, + struct display *display = data; + + if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED) ++ { ++ if (!display->window->xdg_surface) ++ return; ++ + xdg_surface_move(display->window->xdg_surface, +- display->seat, serial); ++ display->seat, serial); ++ } + } + + static void +@@ -601,7 +664,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard, + struct display *d = data; + + if (key == KEY_F11 && state) { +- if (d->window->fullscreen) ++ if (d->window->maximized) + xdg_surface_unset_fullscreen(d->window->xdg_surface); + else + xdg_surface_set_fullscreen(d->window->xdg_surface, NULL); +@@ -710,6 +773,10 @@ registry_handle_global(void *data, struct wl_registry *registry, + fprintf(stderr, "unable to load default left pointer\n"); + // TODO: abort ? + } ++ } else if (strcmp(interface, "ivi_application") == 0) { ++ d->ivi_application = ++ wl_registry_bind(registry, name, ++ &ivi_application_interface, 1); + } + } + +@@ -734,7 +801,7 @@ static void + usage(int error_code) + { + fprintf(stderr, "Usage: simple-egl [OPTIONS]\n\n" +- " -f\tRun in fullscreen mode\n" ++ " -f\tRun in maximized mode\n" + " -o\tCreate an opaque surface\n" + " -s\tUse a 16 bpp EGL config\n" + " -b\tDon't sync to compositor redraw (eglSwapInterval 0)\n" +@@ -761,7 +828,7 @@ main(int argc, char **argv) + + for (i = 1; i < argc; i++) { + if (strcmp("-f", argv[i]) == 0) +- window.fullscreen = 1; ++ window.maximized = 1; + else if (strcmp("-o", argv[i]) == 0) + window.opaque = 1; + else if (strcmp("-s", argv[i]) == 0) +@@ -806,6 +873,11 @@ main(int argc, char **argv) + + fprintf(stderr, "simple-egl exiting\n"); + ++ if (window.display->ivi_application) { ++ ivi_surface_destroy(window.ivi_surface); ++ ivi_application_destroy(window.display->ivi_application); ++ } ++ + destroy_surface(&window); + fini_egl(&display); + +-- +1.7.9.5 + diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0012-clients-support-ivi-application.xml-for-clients-wind.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0012-clients-support-ivi-application.xml-for-clients-wind.patch new file mode 100644 index 0000000..17544d5 --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0012-clients-support-ivi-application.xml-for-clients-wind.patch @@ -0,0 +1,274 @@ +From df22893f76fe2a101c659e53f4594121176fa174 Mon Sep 17 00:00:00 2001 +From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +Date: Wed, 15 Oct 2014 12:13:52 +0900 +Subject: [PATCH 12/15] clients: support ivi-application.xml for + clients/window.c + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +remove NULL entry in listener + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------- +clients: window, remove visibility listener. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------- + +clients: window, don't reindent, but just do + +if (!display->xdg_shell) return; + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------- +clients: window, remove unnecesary roundtrip + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------- +clients: window.c, +surface->toysurface->destroy(surface->toysurface); + + if (surface->window->display->ivi_application) + { + ivi_surface_destroy(surface->window->ivi_surface); + ivi_application_destroy(surface->window->display->ivi_application); + +I don't think this is the right place to destroy ivi_application. This +means that the ivi_application is destroyed when the first window is +destroyed, which prevents opening any new windows. + +Maybe it would be best to replace this hunk with just: + +if (surface->window->ivi_surface) +ivi_surface_destroy(surface->window->ivi_surface); + +Note, that your destruction order is also funny: the wl_surface gets +destroyed before the ivi_surface. Maybe that should be the other way +around? + +Finally, I think this is the wrong place to destroy ivi_surface +altogether. ivi_surface is a shell surface, and it should be destroyed +with the window, just like xdg_surface is. That is, in window_destroy(), +in similar way as xdg_surface_destroy() is called. + +ivi_surface is similar to xdg_surface here, not wl_surface. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +----------------------------------------------------- +clients: window.c, This is in the wrong place. ivi_surface should be +created with the window, not with the underlying wl_surface or buffers. + + if (!surface->toysurface) { + uint32_t id_ivisurf = IVI_SURFACE_ID + (uint32_t)getpid(); + surface->window->ivi_surface = + ivi_application_surface_create(display->ivi_application, + id_ivisurf, surface->surface); + if (surface->window->ivi_surface == NULL) { + fprintf(stderr, "Failed to create ivi_client_surface\n"); + abort(); + } + + ivi_surface_add_listener(surface->window->ivi_surface, + &ivi_surface_listener, surface->window); + } + } + +This is in the wrong place. ivi_surface should be created with the +window, not with the underlying wl_surface or buffers. + +This code should be in window_create(), the same place as +xdg_shell_get_xdg_surface() is used. Make sure you cannot create both +xdg_surface and ivi_surface, if both xdg_shell and ivi_shell are +advertised by the compositor. + +When you create ivi_surface in window_create(), that automatically means +that window_create_custom() will not create a ivi_surface. That should +finally fix the virtual keyboard application, so that you do not need +the strcmp(surface->window->title,"Virtual keyboard") hack. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: window.c, clean up code + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: window.c, jsut call fail_on_null(window->ivi_surface) + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +--------------------------------------------------------- +clients: window.c, off a bit to struct ivi_surface *ivi_surface + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +--- + clients/window.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 57 insertions(+), 10 deletions(-) + +diff --git a/clients/window.c b/clients/window.c +index e44d65c..2f05351 100644 +--- a/clients/window.c ++++ b/clients/window.c +@@ -72,6 +72,10 @@ typedef void *EGLContext; + + #include "window.h" + ++#include <sys/types.h> ++#include "ivi-application-client-protocol.h" ++#define IVI_SURFACE_ID 9000 ++ + struct shm_pool; + + struct global { +@@ -133,6 +137,7 @@ struct display { + + int has_rgb565; + int seat_version; ++ struct ivi_application *ivi_application; + }; + + struct window_output { +@@ -249,6 +254,8 @@ struct window { + struct window *parent; + struct wl_surface *last_parent_surface; + ++ struct ivi_surface *ivi_surface; ++ + struct window_frame *frame; + + /* struct surface::link, contains also main_surface */ +@@ -1379,6 +1386,19 @@ window_get_display(struct window *window) + } + + static void ++handle_ivi_surface_configure(void *data, struct ivi_surface *ivi_surface, ++ int32_t width, int32_t height) ++{ ++ struct window *window = data; ++ ++ window_schedule_resize(window, width, height); ++} ++ ++static const struct ivi_surface_listener ivi_surface_listener = { ++ handle_ivi_surface_configure, ++}; ++ ++static void + surface_create_surface(struct surface *surface, uint32_t flags) + { + struct display *display = surface->window->display; +@@ -1501,7 +1521,7 @@ window_destroy(struct window *window) + + wl_list_remove(&window->redraw_task.link); + +- wl_list_for_each(input, &display->input_list, link) { ++ wl_list_for_each(input, &display->input_list, link) { + if (input->touch_focus == window) + input->touch_focus = NULL; + if (input->pointer_focus == window) +@@ -1526,6 +1546,9 @@ window_destroy(struct window *window) + if (window->xdg_popup) + xdg_popup_destroy(window->xdg_popup); + ++ if (window->ivi_surface) ++ ivi_surface_destroy(window->ivi_surface); ++ + surface_destroy(window->main_surface); + + wl_list_remove(&window->link); +@@ -3051,7 +3074,7 @@ touch_handle_down(void *data, struct wl_touch *wl_touch, + wl_list_insert(&input->touch_point_list, &tp->link); + + if (widget->touch_down_handler) +- (*widget->touch_down_handler)(widget, input, ++ (*widget->touch_down_handler)(widget, input, + serial, time, id, + sx, sy, + widget->user_data); +@@ -4489,7 +4512,7 @@ window_create_internal(struct display *display, int custom) + surface = surface_create(window); + window->main_surface = surface; + +- assert(custom || display->xdg_shell); ++ assert(custom || display->xdg_shell || display->ivi_application); + + window->custom = custom; + window->preferred_format = WINDOW_PREFERRED_FORMAT_NONE; +@@ -4509,17 +4532,30 @@ struct window * + window_create(struct display *display) + { + struct window *window; ++ uint32_t id_ivisurf; + + window = window_create_internal(display, 0); + +- window->xdg_surface = +- xdg_shell_get_xdg_surface(window->display->xdg_shell, +- window->main_surface->surface); +- fail_on_null(window->xdg_surface); ++ if (window->display->xdg_shell) { ++ window->xdg_surface = ++ xdg_shell_get_xdg_surface(window->display->xdg_shell, ++ window->main_surface->surface); ++ fail_on_null(window->xdg_surface); + +- xdg_surface_set_user_data(window->xdg_surface, window); +- xdg_surface_add_listener(window->xdg_surface, +- &xdg_surface_listener, window); ++ xdg_surface_set_user_data(window->xdg_surface, window); ++ xdg_surface_add_listener(window->xdg_surface, ++ &xdg_surface_listener, window); ++ } else if (display->ivi_application) { ++ /* auto generation of ivi_id based on process id + basement of id */ ++ id_ivisurf = IVI_SURFACE_ID + (uint32_t)getpid(); ++ window->ivi_surface = ++ ivi_application_surface_create(display->ivi_application, ++ id_ivisurf, window->main_surface->surface); ++ fail_on_null(window->ivi_surface); ++ ++ ivi_surface_add_listener(window->ivi_surface, ++ &ivi_surface_listener, window); ++ } + + return window; + } +@@ -4772,6 +4808,9 @@ window_show_menu(struct display *display, + + frame_interior(menu->frame, &ix, &iy, NULL, NULL); + ++ if (!display->xdg_shell) ++ return; ++ + window->xdg_popup = xdg_shell_get_xdg_popup(display->xdg_shell, + window->main_surface->surface, + parent->main_surface->surface, +@@ -5231,6 +5270,11 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, + wl_registry_bind(registry, id, + &wl_subcompositor_interface, 1); + } ++ else if (strcmp(interface, "ivi_application") == 0) { ++ d->ivi_application = ++ wl_registry_bind(registry, id, ++ &ivi_application_interface, 1); ++ } + + if (d->global_handler) + d->global_handler(d, id, interface, version, d->user_data); +@@ -5529,6 +5573,9 @@ display_destroy(struct display *display) + if (display->xdg_shell) + xdg_shell_destroy(display->xdg_shell); + ++ if (display->ivi_application) ++ ivi_application_destroy(display->ivi_application); ++ + if (display->shm) + wl_shm_destroy(display->shm); + +-- +1.7.9.5 + diff --git a/meta-ivi/recipes-graphics/wayland/weston/0012-Reference-implementation-of-input-panel-for-ivi-shel.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0013-Reference-implementation-of-input-panel-for-ivi-shel.patch index 0fb0620..3e938f5 100644 --- a/meta-ivi/recipes-graphics/wayland/weston/0012-Reference-implementation-of-input-panel-for-ivi-shel.patch +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0013-Reference-implementation-of-input-panel-for-ivi-shel.patch @@ -1,45 +1,63 @@ -From 6d3a3ecea52f4c9f429267a5aa4d994513d72a69 Mon Sep 17 00:00:00 2001 +From 301505d5b731d89e87a81de04d83230cb2de2246 Mon Sep 17 00:00:00 2001 From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Mon, 12 May 2014 15:07:14 +0900 -Subject: [PATCH 12/31] Reference implementation of input panel for ivi-shell. +Date: Thu, 6 Nov 2014 13:44:18 +0900 +Subject: [PATCH 13/15] Reference implementation of input panel for ivi-shell. + - introduces ivi-shell/input-panel-ivi.c The basement of this code is from input-panel.c of desktop shell. +-------------------------------------------------------- +ivi-shell/input-panel-ivi.c: remove non-availalable header including + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------- +input-panel-ivi: remove DENSO copyright + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------- +input-panel-ivi: revert one patch to be separeated + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> + +-------------------------------------------------------- +input-panel-ivi: remove panel_layer which is not required + Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> --- - Makefile.am | 3 +- - ivi-shell/input-panel-ivi.c | 359 ++++++++++++++++++++++++++++++++++++++++++++ - ivi-shell/ivi-shell.c | 31 ++++ - ivi-shell/ivi-shell.h | 29 ++++ - ivi-shell/weston.ini.in | 3 + - 5 files changed, 424 insertions(+), 1 deletion(-) + Makefile.am | 3 +- + ivi-shell/input-panel-ivi.c | 391 +++++++++++++++++++++++++++++++++++++++++++ + ivi-shell/ivi-shell.c | 30 ++++ + ivi-shell/ivi-shell.h | 28 ++++ + ivi-shell/weston.ini.in | 3 + + 5 files changed, 454 insertions(+), 1 deletion(-) create mode 100644 ivi-shell/input-panel-ivi.c diff --git a/Makefile.am b/Makefile.am -index b133fcd..13fe45b 100644 +index 081c854..2c9ffde 100644 --- a/Makefile.am +++ b/Makefile.am -@@ -753,7 +753,8 @@ ivi_shell_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS) $(IVI_SHELL_CFLAGS) +@@ -788,7 +788,8 @@ ivi_shell_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS) ivi_shell_la_SOURCES = \ ivi-shell/ivi-shell.h \ ivi-shell/ivi-shell.c \ -- ivi-shell/ivi-layout.h -+ ivi-shell/ivi-layout.h \ +- ivi-shell/ivi-layout-private.h ++ ivi-shell/ivi-layout-private.h \ + ivi-shell/input-panel-ivi.c nodist_ivi_shell_la_SOURCES = \ protocol/ivi-application-protocol.c \ protocol/ivi-application-server-protocol.h diff --git a/ivi-shell/input-panel-ivi.c b/ivi-shell/input-panel-ivi.c new file mode 100644 -index 0000000..218da6e +index 0000000..01fd329 --- /dev/null +++ b/ivi-shell/input-panel-ivi.c -@@ -0,0 +1,359 @@ +@@ -0,0 +1,391 @@ +/* + * Copyright © 2010-2012 Intel Corporation + * Copyright © 2011-2012 Collabora, Ltd. + * Copyright © 2013 Raspberry Pi Foundation -+ * Copyright © 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 @@ -68,7 +86,7 @@ index 0000000..218da6e + +#include "ivi-shell.h" +#include "input-method-server-protocol.h" -+#include "ivi-layout.h" ++#include "ivi-layout-private.h" + +struct input_panel_surface { + struct wl_resource *resource; @@ -81,11 +99,54 @@ index 0000000..218da6e + struct weston_view *view; + struct wl_listener surface_destroy_listener; + ++ struct weston_view_animation *anim; ++ + struct weston_output *output; + uint32_t panel; +}; + +static void ++input_panel_slide_done(struct weston_view_animation *animation, void *data) ++{ ++ struct input_panel_surface *ipsurf = data; ++ ++ ipsurf->anim = NULL; ++} ++ ++static void ++show_input_panel_surface(struct input_panel_surface *ipsurf) ++{ ++ struct ivi_shell *shell = ipsurf->shell; ++ struct weston_seat *seat; ++ struct weston_surface *focus; ++ float x, y; ++ ++ wl_list_for_each(seat, &shell->compositor->seat_list, link) { ++ if (!seat->keyboard) ++ continue; ++ focus = weston_surface_get_main_surface(seat->keyboard->focus); ++ ipsurf->output = focus->output; ++ x = ipsurf->output->x + (ipsurf->output->width - ipsurf->surface->width) / 2; ++ y = ipsurf->output->y + ipsurf->output->height - ipsurf->surface->height; ++ weston_view_set_position(ipsurf->view, x, y); ++ } ++ ++ weston_layer_entry_insert(&shell->input_panel_layer.view_list, ++ &ipsurf->view->layer_link); ++ weston_view_geometry_dirty(ipsurf->view); ++ weston_view_update_transform(ipsurf->view); ++ weston_surface_damage(ipsurf->surface); ++ ++ if (ipsurf->anim) ++ weston_view_animation_destroy(ipsurf->anim); ++ ++ ipsurf->anim = ++ weston_slide_run(ipsurf->view, ++ ipsurf->surface->height * 0.9, 0, ++ input_panel_slide_done, ipsurf); ++} ++ ++static void +show_input_panels(struct wl_listener *listener, void *data) +{ + struct ivi_shell *shell = @@ -101,20 +162,15 @@ index 0000000..218da6e + shell->showing_input_panels = true; + + if (!shell->locked) -+ wl_list_insert(&shell->panel_layer.link, ++ wl_list_insert(&shell->compositor->cursor_layer.link, + &shell->input_panel_layer.link); + + wl_list_for_each_safe(ipsurf, next, + &shell->input_panel.surfaces, link) { + if (ipsurf->surface->width == 0) + continue; -+ wl_list_insert(&shell->input_panel_layer.view_list, -+ &ipsurf->view->layer_link); -+ weston_view_geometry_dirty(ipsurf->view); -+ weston_view_update_transform(ipsurf->view); -+ weston_surface_damage(ipsurf->surface); -+ weston_slide_run(ipsurf->view, ipsurf->surface->height * 0.9, -+ 0, NULL, NULL); ++ ++ show_input_panel_surface(ipsurf); + } +} + @@ -135,7 +191,8 @@ index 0000000..218da6e + wl_list_remove(&shell->input_panel_layer.link); + + wl_list_for_each_safe(view, next, -+ &shell->input_panel_layer.view_list, layer_link) ++ &shell->input_panel_layer.view_list.link, ++ layer_link.link) + weston_view_unmap(view); +} + @@ -173,13 +230,8 @@ index 0000000..218da6e + + weston_view_set_position(ip_surface->view, x, y); + -+ if (!weston_surface_is_mapped(surface) && shell->showing_input_panels) { -+ wl_list_insert(&shell->input_panel_layer.view_list, -+ &ip_surface->view->layer_link); -+ weston_view_update_transform(ip_surface->view); -+ weston_surface_damage(surface); -+ weston_slide_run(ip_surface->view, ip_surface->view->surface->height * 0.9, 0, NULL, NULL); -+ } ++ if (!weston_surface_is_mapped(surface) && shell->showing_input_panels) ++ show_input_panel_surface(ip_surface); +} + +static void @@ -342,7 +394,7 @@ index 0000000..218da6e + +static void +bind_input_panel(struct wl_client *client, -+ void *data, uint32_t version, uint32_t id) ++ void *data, uint32_t version, uint32_t id) +{ + struct ivi_shell *shell = data; + struct wl_resource *resource; @@ -360,7 +412,6 @@ index 0000000..218da6e + + wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, + "interface object already bound"); -+ wl_resource_destroy(resource); +} + +void @@ -395,96 +446,94 @@ index 0000000..218da6e + return 0; +} diff --git a/ivi-shell/ivi-shell.c b/ivi-shell/ivi-shell.c -index bd650b7..d7d7bb5 100644 +index 3904402..5723c00 100644 --- a/ivi-shell/ivi-shell.c +++ b/ivi-shell/ivi-shell.c -@@ -269,6 +269,29 @@ bind_ivi_application(struct wl_client *client, - shell, NULL); +@@ -375,6 +375,31 @@ bind_ivi_application(struct wl_client *client, + shell, NULL); } +struct weston_view * +get_default_view(struct weston_surface *surface) +{ -+ struct ivi_shell_surface *shsurf; -+ struct weston_view *view; ++ struct ivi_shell_surface *shsurf; ++ struct weston_view *view; + -+ if (!surface || wl_list_empty(&surface->views)) -+ return NULL; ++ if (!surface || wl_list_empty(&surface->views)) ++ return NULL; + -+ shsurf = get_ivi_shell_surface(surface); -+ if (shsurf && shsurf->layout_surface) { -+ view = ivi_layout->get_weston_view(shsurf->layout_surface); -+ if (view) -+ return view; -+ } ++ shsurf = get_ivi_shell_surface(surface); ++ if (shsurf && shsurf->layout_surface) { ++ view = shsurf->shell->ivi_layout->get_weston_view(shsurf->layout_surface); ++ if (view) ++ return view; ++ } + -+ wl_list_for_each(view, &surface->views, surface_link) -+ if (weston_view_is_mapped(view)) -+ return view; ++ wl_list_for_each(view, &surface->views, surface_link) { ++ if (weston_view_is_mapped(view)) ++ return view; ++ } + -+ return container_of(surface->views.next, struct weston_view, surface_link); ++ return container_of(surface->views.next, ++ struct weston_view, surface_link); +} + - /** - * Initialization/destruction method of ivi-shell + /* + * Called through the compositor's destroy signal. */ -@@ -279,6 +302,8 @@ shell_destroy(struct wl_listener *listener, void *data) - container_of(listener, struct ivi_shell, destroy_listener); - struct ivi_shell_surface *ivisurf, *next; +@@ -385,6 +410,8 @@ shell_destroy(struct wl_listener *listener, void *data) + container_of(listener, struct ivi_shell, destroy_listener); + struct ivi_shell_surface *ivisurf, *next; -+ input_panel_destroy(shell); ++ input_panel_destroy(shell); + - wl_list_for_each_safe(ivisurf, next, &shell->ivi_surface_list, link) { - wl_list_remove(&ivisurf->link); - free(ivisurf); -@@ -293,6 +318,9 @@ init_ivi_shell(struct weston_compositor *compositor, struct ivi_shell *shell) - shell->compositor = compositor; + wl_list_for_each_safe(ivisurf, next, &shell->ivi_surface_list, link) { + wl_list_remove(&ivisurf->link); + free(ivisurf); +@@ -400,6 +427,7 @@ init_ivi_shell(struct weston_compositor *compositor, struct ivi_shell *shell) - wl_list_init(&shell->ivi_surface_list); -+ -+ weston_layer_init(&shell->panel_layer, &compositor->cursor_layer.link); -+ weston_layer_init(&shell->input_panel_layer, NULL); + wl_list_init(&shell->ivi_surface_list); + ++ weston_layer_init(&shell->input_panel_layer, NULL); } static int -@@ -369,6 +397,9 @@ module_init(struct weston_compositor *compositor, - shell->destroy_listener.notify = shell_destroy; - wl_signal_add(&compositor->destroy_signal, &shell->destroy_listener); +@@ -474,6 +502,8 @@ module_init(struct weston_compositor *compositor, + shell->destroy_listener.notify = shell_destroy; + wl_signal_add(&compositor->destroy_signal, &shell->destroy_listener); -+ if (input_panel_setup(shell) < 0) -+ return -1; -+ - if (wl_global_create(compositor->wl_display, &ivi_application_interface, 1, - shell, bind_ivi_application) == NULL) { - return -1; ++ if (input_panel_setup(shell) < 0) ++ return -1; + + if (wl_global_create(compositor->wl_display, + &ivi_application_interface, 1, diff --git a/ivi-shell/ivi-shell.h b/ivi-shell/ivi-shell.h -index 157c5ae..ad94f64 100644 +index 1283a00..3441119 100644 --- a/ivi-shell/ivi-shell.h +++ b/ivi-shell/ivi-shell.h -@@ -32,4 +32,33 @@ struct ivi_shell - struct weston_compositor *compositor; +@@ -34,4 +34,32 @@ struct ivi_shell + struct wl_list ivi_surface_list; /* struct ivi_shell_surface::link */ - struct wl_list ivi_surface_list; /* struct ivi_shell_surface::link */ + struct ivi_layout_interface *ivi_layout; + -+ struct wl_listener show_input_panel_listener; -+ struct wl_listener hide_input_panel_listener; -+ struct wl_listener update_input_panel_listener; ++ struct wl_listener show_input_panel_listener; ++ struct wl_listener hide_input_panel_listener; ++ struct wl_listener update_input_panel_listener; + -+ struct weston_layer panel_layer; -+ struct weston_layer input_panel_layer; ++ struct weston_layer input_panel_layer; + -+ bool locked; -+ bool showing_input_panels; ++ bool locked; ++ bool showing_input_panels; + -+ struct { -+ struct weston_surface *surface; -+ pixman_box32_t cursor_rectangle; -+ } text_input; ++ struct { ++ struct weston_surface *surface; ++ pixman_box32_t cursor_rectangle; ++ } text_input; + -+ struct { -+ struct wl_resource *binding; -+ struct wl_list surfaces; -+ } input_panel; ++ struct { ++ struct wl_resource *binding; ++ struct wl_list surfaces; ++ } input_panel; }; + +struct weston_view * @@ -496,10 +545,10 @@ index 157c5ae..ad94f64 100644 +void +input_panel_destroy(struct ivi_shell *shell); diff --git a/ivi-shell/weston.ini.in b/ivi-shell/weston.ini.in -index 3c9fb6a..c192d68 100644 +index f8ef12f..050b806 100644 --- a/ivi-shell/weston.ini.in +++ b/ivi-shell/weston.ini.in -@@ -30,6 +30,9 @@ home-id=1007 +@@ -32,6 +32,9 @@ home-id=1007 workspace-background-color=0x99000000 workspace-background-id=2001 @@ -510,5 +559,5 @@ index 3c9fb6a..c192d68 100644 workspace-id=0 icon-id=4001 -- -1.9.3 +1.7.9.5 diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0014-input-panel-ivi-add-seat-keyboard-focus-to-condition.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0014-input-panel-ivi-add-seat-keyboard-focus-to-condition.patch new file mode 100644 index 0000000..73920b2 --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0014-input-panel-ivi-add-seat-keyboard-focus-to-condition.patch @@ -0,0 +1,27 @@ +From 63612ed0ca90dd06ace20585cfe1eece0b51e18e Mon Sep 17 00:00:00 2001 +From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +Date: Wed, 12 Nov 2014 17:06:09 +0900 +Subject: [PATCH 14/15] input-panel-ivi: add \!seat->keyboard->focus to + condition + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +--- + ivi-shell/input-panel-ivi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ivi-shell/input-panel-ivi.c b/ivi-shell/input-panel-ivi.c +index 01fd329..6b89177 100644 +--- a/ivi-shell/input-panel-ivi.c ++++ b/ivi-shell/input-panel-ivi.c +@@ -66,7 +66,7 @@ show_input_panel_surface(struct input_panel_surface *ipsurf) + float x, y; + + wl_list_for_each(seat, &shell->compositor->seat_list, link) { +- if (!seat->keyboard) ++ if (!seat->keyboard || !seat->keyboard->focus) + continue; + focus = weston_surface_get_main_surface(seat->keyboard->focus); + ipsurf->output = focus->output; +-- +1.7.9.5 + diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0015-protocol-ivi-application.xml-update-description-of-i.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0015-protocol-ivi-application.xml-update-description-of-i.patch new file mode 100644 index 0000000..97dc74d --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/0015-protocol-ivi-application.xml-update-description-of-i.patch @@ -0,0 +1,32 @@ +From 814f152d3f3ca5973162cad8c19f1e86f85f6d27 Mon Sep 17 00:00:00 2001 +From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +Date: Fri, 21 Nov 2014 01:04:42 +0900 +Subject: [PATCH 15/15] protocol: ivi-application.xml: update description of + ivi-application::surface_create. ivi_id can be reused + when destruction of ivi_surface or wl_surface + happens. + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> +--- + protocol/ivi-application.xml | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/protocol/ivi-application.xml b/protocol/ivi-application.xml +index 6bb90a7..f815baf 100644 +--- a/protocol/ivi-application.xml ++++ b/protocol/ivi-application.xml +@@ -84,7 +84,10 @@ + logic of the application about where it shall be located. + The server regards following cases as protocol errors and disconnects the client. + - wl_surface already has an nother role. +- - ivi_id is already assigned to an another wl_surface ++ - ivi_id is already assigned to an another wl_surface. ++ ++ If client destroy ivi_surface or wl_surface which is assigne to the ivi_surface, ++ ivi_id which is assigned to the ivi_surface is free for reuse. + </description> + <arg name="ivi_id" type="uint"/> + <arg name="surface" type="object" interface="wl_surface"/> +-- +1.7.9.5 + diff --git a/meta-ivi/recipes-graphics/wayland/weston/0001-Enable-disable-default-virtual-keyboard.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/Enable-disable-default-virtual-keyboard.patch index d6ae6c2..c23a720 100644 --- a/meta-ivi/recipes-graphics/wayland/weston/0001-Enable-disable-default-virtual-keyboard.patch +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/Enable-disable-default-virtual-keyboard.patch @@ -1,9 +1,10 @@ -From 42f5cc1e4436c34dd1c939ff49f403be609f8f1c Mon Sep 17 00:00:00 2001 +rom 42f5cc1e4436c34dd1c939ff49f403be609f8f1c Mon Sep 17 00:00:00 2001 From: Imran Zaman <imran.zaman@intel.com> Date: Thu, 5 Feb 2015 13:21:44 +0100 Subject: [PATCH] Enable/disable default virtual keyboard Adapted from Tizen commit ad9e205ea7fdb859679b63698a931fa127c5523a +Adapted for weston 1.6.0 <quote> Since fullscreen shell does not support virtual keyboard, @@ -17,18 +18,15 @@ Signed-off-by: Imran Zaman <imran.zaman@intel.com> </quote> Signed-off-by: Holger Behrens <holger.behrens@windriver.com> ---- - configure.ac | 10 ++++++++++ - src/text-backend.c | 15 ++++++++++++--- - 2 files changed, 22 insertions(+), 3 deletions(-) +Signed-off-by: Andrei Gherzan <andrei.gherzan@windriver.com> -diff --git a/configure.ac b/configure.ac -index d14ed16..9f898ca 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -456,6 +456,15 @@ if test x$enable_ivi_shell = xyes; then - PKG_CHECK_MODULES(IVI_SHELL, [cairo]) - fi +Index: git/configure.ac +=================================================================== +--- git.orig/configure.ac ++++ git/configure.ac +@@ -449,6 +449,15 @@ AC_ARG_ENABLE(ivi-shell, + enable_ivi_shell=yes) + AM_CONDITIONAL(ENABLE_IVI_SHELL, test "x$enable_ivi_shell" = "xyes") +AC_ARG_ENABLE([default-vkb], + [AC_HELP_STRING([--enable-default-vkb], @@ -42,43 +40,26 @@ index d14ed16..9f898ca 100644 AC_ARG_ENABLE(wcap-tools, [ --disable-wcap-tools],, enable_wcap_tools=yes) AM_CONDITIONAL(BUILD_WCAP_TOOLS, test x$enable_wcap_tools = xyes) if test x$enable_wcap_tools = xyes; then -@@ -558,6 +567,7 @@ AC_MSG_RESULT([ +@@ -551,6 +560,7 @@ AC_MSG_RESULT([ dbus ${enable_dbus} ivi-shell ${enable_ivi_shell} -+ default virtual keyboard ${enable_default_vkb} ++ default virtual keyboard ${enable_default_vkb} Build wcap utility ${enable_wcap_tools} Build Fullscreen Shell ${enable_fullscreen_shell} -diff --git a/src/text-backend.c b/src/text-backend.c -index d6a6f3b..4908b8a 100644 ---- a/src/text-backend.c -+++ b/src/text-backend.c -@@ -939,12 +939,21 @@ static void - text_backend_configuration(struct text_backend *text_backend) - { - struct weston_config_section *section; -+ char *client = NULL; -+ int ret = -1; +Index: git/src/text-backend.c +=================================================================== +--- git.orig/src/text-backend.c ++++ git/src/text-backend.c +@@ -948,8 +948,10 @@ text_backend_configuration(struct text_b section = weston_config_get_section(text_backend->compositor->config, "input-method", NULL, NULL); -- weston_config_section_get_string(section, "path", -- &text_backend->input_method.path, -- LIBEXECDIR "/weston-keyboard"); -+#if HAVE_DEFAULT_VKB -+ ret = asprintf(&client, "%s/weston-keyboard", -+ weston_config_get_libexec_dir()); -+#endif -+ if (ret < 0) -+ client = NULL; -+ -+ weston_config_section_get_string(section, "path", -+ &text_backend->input_method.path, -+ client); - } - - static void --- -2.2.2 - ++ #if HAVE_DEFAULT_VKB + ret = asprintf(&client, "%s/weston-keyboard", + weston_config_get_libexec_dir()); ++ #endif + if (ret < 0) + client = NULL; + weston_config_section_get_string(section, "path", diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/build.fix.up.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/build.fix.up.patch new file mode 100644 index 0000000..ea267dc --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/build.fix.up.patch @@ -0,0 +1,82 @@ +From 3a6eceb060336dd67bb300f629052fc915bd2f9b Mon Sep 17 00:00:00 2001 +From: Yong-iL Joh <yong-il.joh@windriver.com> +Date: Mon, 14 Sep 2015 22:12:25 +0900 +Subject: [PATCH] fix up for mismatched off_t among files + +root@qemux86:/var/volatile/log# cat ivi-shell-user-interface.log +[create_ivisurface:937] +[createShmBuffer:815] sizeof(size) = 4 +[createShmBuffer:816] sizeof(off_t) = 4 +root@qemux86:/var/volatile/log# cat os-compatibility.log +[os_create_anonymous_file:153] sizeof(size) = 8 +[os_create_anonymous_file:154] sizeof(off_t) = 8 +[os_create_anonymous_file:155] sizeof(long int) = 4 +[os_create_anonymous_file:180] 3145728 < 0, bfeaae38 +[os_create_anonymous_file:187] posix_fallocate(3145728)Invalid argument + +Signed-off-by: Yong-iL Joh <yong-il.joh@windriver.com> + +%% original patch: build.fix.up.patch + +Signed-off-by: Yong-iL Joh <yong-il.joh@windriver.com> +--- + clients/ivi-shell-user-interface.c | 2 ++ + ivi-shell/hmi-controller.c | 1 + + ivi-shell/ivi-layout-transition.c | 2 ++ + ivi-shell/ivi-layout.c | 2 ++ + 4 files changed, 7 insertions(+) + +diff --git a/clients/ivi-shell-user-interface.c b/clients/ivi-shell-user-interface.c +index 3c69541..c04b589 100644 +--- a/clients/ivi-shell-user-interface.c ++++ b/clients/ivi-shell-user-interface.c +@@ -20,6 +20,8 @@ + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + ++#include "config.h" ++ + #include <sys/wait.h> + #include <unistd.h> + #include <stdlib.h> +diff --git a/ivi-shell/hmi-controller.c b/ivi-shell/hmi-controller.c +index b7a6c61..0afd866 100644 +--- a/ivi-shell/hmi-controller.c ++++ b/ivi-shell/hmi-controller.c +@@ -45,6 +45,7 @@ + * TODO: animation method shall be refined + * TODO: support fade-in when UI is ready + */ ++#include "config.h" + + #include <sys/wait.h> + #include <unistd.h> +diff --git a/ivi-shell/ivi-layout-transition.c b/ivi-shell/ivi-layout-transition.c +index 0c45c4a..f289c93 100644 +--- a/ivi-shell/ivi-layout-transition.c ++++ b/ivi-shell/ivi-layout-transition.c +@@ -20,6 +20,8 @@ + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + ++#include "config.h" ++ + #include <time.h> + #include <assert.h> + #include <stdlib.h> +diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c +index 6f7c3c2..c2c8786 100644 +--- a/ivi-shell/ivi-layout.c ++++ b/ivi-shell/ivi-layout.c +@@ -53,6 +53,8 @@ + * + */ + ++#include "config.h" ++ + #include <sys/wait.h> + #include <unistd.h> + #include <stdlib.h> +-- +1.7.9.5 + diff --git a/meta-ivi/recipes-graphics/wayland/weston-1.6.0/ivi-shell-click-event.patch b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/ivi-shell-click-event.patch new file mode 100644 index 0000000..3d26ee9 --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston-1.6.0/ivi-shell-click-event.patch @@ -0,0 +1,54 @@ +Subject: [PATCH] Add the processing which has notice of click event from compositor + +Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA at xddp.denso.co.jp> +--- + ivi-shell/ivi-shell.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/ivi-shell/ivi-shell.c b/ivi-shell/ivi-shell.c +index 2f2e4fa..933e878 100644 +--- a/ivi-shell/ivi-shell.c ++++ b/ivi-shell/ivi-shell.c +@@ -36,6 +36,7 @@ + #include <dlfcn.h> + #include <limits.h> + #include <assert.h> ++#include <linux/input.h> + + #include "ivi-shell.h" + #include "ivi-application-server-protocol.h" +@@ -385,6 +386,21 @@ + return result; + } + ++static void ++click_to_activate_binding(struct weston_seat *seat, ++ uint32_t time, uint32_t button, ++ void *data) ++{ ++ if (seat->pointer->grab != &seat->pointer->default_grab) { ++ return; ++ } ++ if (seat->pointer->focus == NULL) { ++ return; ++ } ++ ++ weston_surface_activate(seat->pointer->focus->surface, seat); ++} ++ + /* + * Initialization of ivi-shell. + */ +@@ -424,6 +440,8 @@ + return -1; + } + ++ weston_compositor_add_button_binding(compositor, BTN_LEFT, 0, click_to_activate_binding, shell); ++ + free(setting.ivi_module); + return 0; + } +1.7.11.7 + +BR, +Nobuhiko Tanibata diff --git a/meta-ivi/recipes-graphics/wayland/weston/0001-README-modifed-for-ivi-shell.patch b/meta-ivi/recipes-graphics/wayland/weston/0001-README-modifed-for-ivi-shell.patch deleted file mode 100644 index 96a1f05..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0001-README-modifed-for-ivi-shell.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 7ae0a0dc56381b3b9410f16247f3fcaa1b25989b Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@denso.co.jp> -Date: Wed, 29 Jan 2014 15:53:59 +0900 -Subject: [PATCH 01/31] README modifed for ivi-shell - ---- - README | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/README b/README -index 3821e5d..cf7eca5 100644 ---- a/README -+++ b/README -@@ -1,3 +1,20 @@ -+ivi-shell addon: -+ -+ivi-shell proposes two features -+- Common layout library for surface, which allow ivi-shell developer -+ to develop own shell, linking Common layout library. -+ For the time being, the library refers Genivi ilm interface. -+ -+ http://projects.genivi.org/ivi-layer-management/ -+ -+- Extension protocal; ivi-application to tie wl_surface and a given ID. -+ With this ID, shell can identify which wl_surface is drawn by which -+ application. In in-vehicle infortainment system, a shell has to update -+ a property of a wl_surface. E.g. there may be a use case when vehicle -+ starts to move, the wl_surface drawn by Car navigation is expected to -+ move top of surfaces. -+ -+----------------------------- - Weston - - Weston is the reference implementation of a Wayland compositor, and a --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0002-protocol-add-interface-ivi_application-extension.patch b/meta-ivi/recipes-graphics/wayland/weston/0002-protocol-add-interface-ivi_application-extension.patch deleted file mode 100644 index 0704067..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0002-protocol-add-interface-ivi_application-extension.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 7ca2bb54ccadb6dc53643cfad12cb5939c853734 Mon Sep 17 00:00:00 2001 -From: Andrei Gherzan <andrei.gherzan@windriver.com> -Date: Thu, 25 Sep 2014 16:46:57 +0200 -Subject: [PATCH 02/31] protocol: add interface ivi_application extension - -ivi_applicatoin extension creates ivi_surface objects tied -to a given wl_surface with a given id. The given id can be used in a -shell to identify which application is assigned to a wl_surface and -layout the surface wherever the shell wants. ivi_surface objects can -be used to receive status of wl_surface in the scenegraph of the -compositor. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - Makefile.am | 3 +- - protocol/ivi-application.xml | 70 ++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 72 insertions(+), 1 deletion(-) - create mode 100644 protocol/ivi-application.xml - -diff --git a/Makefile.am b/Makefile.am -index 343adc6..b45e8f2 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -969,7 +969,8 @@ EXTRA_DIST += \ - protocol/wayland-test.xml \ - protocol/xdg-shell.xml \ - protocol/fullscreen-shell.xml \ -- protocol/scaler.xml -+ protocol/scaler.xml \ -+ protocol/ivi-application.xml - - man_MANS = weston.1 weston.ini.5 - -diff --git a/protocol/ivi-application.xml b/protocol/ivi-application.xml -new file mode 100644 -index 0000000..80ab790 ---- /dev/null -+++ b/protocol/ivi-application.xml -@@ -0,0 +1,70 @@ -+<?xml version="1.0" encoding="UTF-8"?> -+<protocol name="ivi_application"> -+ -+ <copyright> -+ Copyright (C) 2013 DENSO CORPORATION -+ Copyright (c) 2013 BMW Car IT GmbH -+ -+ Permission is hereby granted, free of charge, to any person obtaining a copy -+ of this software and associated documentation files (the "Software"), to deal -+ in the Software without restriction, including without limitation the rights -+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+ copies of the Software, and to permit persons to whom the Software is -+ furnished to do so, subject to the following conditions: -+ -+ The above copyright notice and this permission notice shall be included in -+ all copies or substantial portions of the Software. -+ -+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -+ THE SOFTWARE. -+ </copyright> -+ -+ <interface name="ivi_surface" version="1"> -+ <description summary="application interface to surface in ivi compositor"/> -+ -+ <request name="destroy" type="destructor"> -+ <description summary="destroy ivi_surface"> -+ This removes link from ivi_id to wl_surface and destroys ivi_surface. -+ </description> -+ </request> -+ -+ <event name="visibility"> -+ <description summary="visibility of surface in ivi compositor has changed"> -+ The new visibility state is provided in argument visibility. -+ If visibility is 0, the surface has become invisible. -+ If visibility is not 0, the surface has become visible. -+ </description> -+ <arg name="visibility" type="int"/> -+ </event> -+ </interface> -+ -+ <interface name="ivi_application" version="1"> -+ <description summary="create ivi-style surfaces"> -+ This interface is implemented by servers that provide desktop-style user interfaces. -+ It allows clients to associate a ivi_surface with a basic surface. -+ </description> -+ -+ <request name="surface_create"> -+ <description summary="create ivi_surface with numeric ID in ivi compositor"> -+ surface_create will create a interface:ivi_surface with numeric ID; ivi_id in -+ ivi compositor. These ivi_ids are defined as unique in the system to identify -+ it inside of ivi compositor. The ivi compositor implements business logic how to -+ set properties of the surface with ivi_id according to status of the system. -+ E.g. a unique ID for Car Navigation application is used for implementing special -+ logic of the application about where it shall be located. -+ if a wl_surface which already has another role is set, the server regards this as -+ error and disconnects the client. -+ </description> -+ <arg name="ivi_id" type="uint"/> -+ <arg name="surface" type="object" interface="wl_surface"/> -+ <arg name="id" type="new_id" interface="ivi_surface"/> -+ </request> -+ -+ </interface> -+ -+</protocol> --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0003-ivi-shell-add-the-shell-plugin-for-In-Vehicle-Infota.patch b/meta-ivi/recipes-graphics/wayland/weston/0003-ivi-shell-add-the-shell-plugin-for-In-Vehicle-Infota.patch deleted file mode 100644 index 3865b05..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0003-ivi-shell-add-the-shell-plugin-for-In-Vehicle-Infota.patch +++ /dev/null @@ -1,643 +0,0 @@ -From 2764ba27394f6aceedfbab9059e4dca29341b789 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Tue, 6 May 2014 17:05:47 +0900 -Subject: [PATCH 03/31] ivi-shell: add the shell plugin for In-Vehicle - Infotainment system - -In-Vehicle Infotainment system traditionally manages surfaces with global -identification. A protocol, ivi_application, supports such a feature by -implementing a request, ivi_application::surface_creation defined in -ivi_application.xml. - -The ivi-shell explicitly loads ivi-layout.so and a module to add business -logic like how to layout surfaces by using ivi-layout APIs. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - Makefile.am | 22 +++ - configure.ac | 12 ++ - ivi-shell/ivi-layout.h | 82 ++++++++++ - ivi-shell/ivi-shell.c | 416 +++++++++++++++++++++++++++++++++++++++++++++++++ - ivi-shell/ivi-shell.h | 35 +++++ - 5 files changed, 567 insertions(+) - create mode 100644 ivi-shell/ivi-layout.h - create mode 100644 ivi-shell/ivi-shell.c - create mode 100644 ivi-shell/ivi-shell.h - -diff --git a/Makefile.am b/Makefile.am -index b45e8f2..e825fdd 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -700,6 +700,28 @@ nodist_fullscreen_shell_la_SOURCES = \ - BUILT_SOURCES += $(nodist_fullscreen_shell_la_SOURCES) - endif - -+if ENABLE_IVI_SHELL -+ -+module_LTLIBRARIES += \ -+ $(ivi_shell) -+ -+ivi_shell = ivi-shell.la -+ivi_shell_la_LDFLAGS = -module -avoid-version -+ivi_shell_la_LIBADD = $(COMPOSITOR_LIBS) $(IVI_SHELL_LIBS) libshared.la -+ivi_shell_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS) $(IVI_SHELL_CFLAGS) -+ivi_shell_la_SOURCES = \ -+ ivi-shell/ivi-shell.h \ -+ ivi-shell/ivi-shell.c \ -+ ivi-shell/ivi-layout.h -+nodist_ivi_shell_la_SOURCES = \ -+ protocol/ivi-application-protocol.c \ -+ protocol/ivi-application-server-protocol.h -+ -+BUILT_SOURCES += $(nodist_ivi_shell_la_SOURCES) -+ -+endif -+ -+ - if ENABLE_SCREEN_SHARING - - module_LTLIBRARIES += screen-share.la -diff --git a/configure.ac b/configure.ac -index 1a1bd3b..d14ed16 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -446,6 +446,16 @@ if test "x$enable_dbus" != "xno"; then - fi - AM_CONDITIONAL(ENABLE_DBUS, test "x$enable_dbus" = "xyes") - -+# ivi-shell support -+AC_ARG_ENABLE(ivi-shell, -+ AS_HELP_STRING([--disable-ivi-shell], -+ [do not build ivi-shell server plugin and client]),, -+ enable_ivi_shell=yes) -+AM_CONDITIONAL(ENABLE_IVI_SHELL, test "x$enable_ivi_shell" = "xyes") -+if test x$enable_ivi_shell = xyes; then -+ PKG_CHECK_MODULES(IVI_SHELL, [cairo]) -+fi -+ - AC_ARG_ENABLE(wcap-tools, [ --disable-wcap-tools],, enable_wcap_tools=yes) - AM_CONDITIONAL(BUILD_WCAP_TOOLS, test x$enable_wcap_tools = xyes) - if test x$enable_wcap_tools = xyes; then -@@ -547,6 +557,8 @@ AC_MSG_RESULT([ - XWayland ${enable_xwayland} - dbus ${enable_dbus} - -+ ivi-shell ${enable_ivi_shell} -+ - Build wcap utility ${enable_wcap_tools} - Build Fullscreen Shell ${enable_fullscreen_shell} - -diff --git a/ivi-shell/ivi-layout.h b/ivi-shell/ivi-layout.h -new file mode 100644 -index 0000000..5d7488a ---- /dev/null -+++ b/ivi-shell/ivi-layout.h -@@ -0,0 +1,82 @@ -+/* -+ * Copyright (C) 2013 DENSO CORPORATION -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and -+ * its documentation for any purpose is hereby granted without fee, provided -+ * that the above copyright notice appear in all copies and that both that -+ * copyright notice and this permission notice appear in supporting -+ * documentation, and that the name of the copyright holders not be used in -+ * advertising or publicity pertaining to distribution of the software -+ * without specific, written prior permission. The copyright holders make -+ * no representations about the suitability of this software for any -+ * purpose. It is provided "as is" without express or implied warranty. -+ * -+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS -+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY -+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+/** -+ * The ivi-layout library supports API set of controlling properties of -+ * surface and layer which groups surfaces. An unique ID whose type is integer -+ * is required to create surface and layer. With the unique ID, surface and -+ * layer are identified to control them. The API set consists of APIs to control -+ * properties of surface and layers about followings, -+ * - visibility. -+ * - opacity. -+ * - clipping (x,y,width,height). -+ * - position and size of it to be displayed. -+ * - orientation per 90 degree. -+ * - add or remove surfaces to a layer. -+ * - order of surfaces/layers in layer/screen to be displayed. -+ * - commit to apply property changes. -+ * - notifications of property change. -+ * -+ * Management of surfaces and layers grouping these surfaces are common way in -+ * In-Vehicle Infotainment system, which integrate several domains in one system. -+ * A layer is allocated to a domain in order to control application surfaces -+ * grouped to the layer all together. -+ */ -+ -+#ifndef _IVI_LAYOUT_H_ -+#define _IVI_LAYOUT_H_ -+ -+#ifdef __cplusplus -+extern "C" { -+#endif /* __cplusplus */ -+ -+#include "compositor.h" -+ -+struct ivi_layout_surface; -+ -+enum ivi_layout_warning_flag { -+ IVI_WARNING_INVALID_WL_SURFACE, -+ IVI_WARNING_IVI_ID_IN_USE -+}; -+ -+struct ivi_layout_interface { -+ struct weston_view* (*get_weston_view)(struct ivi_layout_surface *surface); -+ void (*surfaceConfigure)(struct ivi_layout_surface *ivisurf, -+ int32_t width, int32_t height); -+ int32_t (*surfaceSetNativeContent)(struct weston_surface *wl_surface, -+ int32_t width, -+ int32_t height, -+ uint32_t id_surface); -+ struct ivi_layout_surface* (*surfaceCreate)(struct weston_surface *wl_surface, -+ uint32_t id_surface); -+ void (*initWithCompositor)(struct weston_compositor *ec); -+ void (*emitWarningSignal)(uint32_t id_surface, -+ enum ivi_layout_warning_flag flag); -+}; -+ -+WL_EXPORT struct ivi_layout_interface ivi_layout_interface; -+ -+#ifdef __cplusplus -+} /**/ -+#endif /* __cplusplus */ -+ -+#endif /* _IVI_LAYOUT_H_ */ -diff --git a/ivi-shell/ivi-shell.c b/ivi-shell/ivi-shell.c -new file mode 100644 -index 0000000..bd650b7 ---- /dev/null -+++ b/ivi-shell/ivi-shell.c -@@ -0,0 +1,416 @@ -+/* -+ * 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. -+ */ -+ -+ -+/** -+ * ivi-shell supports a type of shell for In-Vehicle Infotainment system. -+ * In-Vehicle Infotainment system traditionally manages surfaces with global -+ * identification. A protocol, ivi_application, supports such a feature -+ * by implementing a request, ivi_application::surface_creation defined in -+ * ivi_application.xml. -+ * -+ * The ivi-shell explicitly loads a module to add business logic like how to -+ * layout surfaces by using internal ivi-layout APIs. -+ */ -+#include "config.h" -+ -+#include <sys/wait.h> -+#include <unistd.h> -+#include <stdlib.h> -+#include <stdio.h> -+#include <string.h> -+#include <linux/input.h> -+#include <dlfcn.h> -+#include <limits.h> -+ -+#include "ivi-shell.h" -+#include "ivi-application-server-protocol.h" -+#include "ivi-layout.h" -+ -+#include "../shared/os-compatibility.h" -+ -+struct ivi_shell_surface -+{ -+ struct ivi_shell *shell; -+ struct ivi_layout_surface *layout_surface; -+ -+ struct weston_surface *surface; -+ uint32_t id_surface; -+ -+ int32_t width; -+ int32_t height; -+ -+ struct wl_list link; -+}; -+ -+struct ivi_shell_setting -+{ -+ char *ivi_module; -+}; -+ -+static struct ivi_layout_interface *ivi_layout; -+ -+/* ------------------------------------------------------------------------- */ -+ -+ /* common functions */ -+/* ------------------------------------------------------------------------- */ -+ -+/** -+ * Implementation of ivi_surface -+ */ -+ -+static void -+ivi_shell_surface_configure(struct weston_surface *, int32_t, int32_t); -+ -+static struct ivi_shell_surface * -+get_ivi_shell_surface(struct weston_surface *surface) -+{ -+ if (surface->configure == ivi_shell_surface_configure) { -+ return surface->configure_private; -+ } else { -+ return NULL; -+ } -+} -+ -+static void -+ivi_shell_surface_configure(struct weston_surface *surface, -+ int32_t sx, int32_t sy) -+{ -+ struct ivi_shell_surface *ivisurf = get_ivi_shell_surface(surface); -+ struct weston_view *view = NULL; -+ float from_x = 0.0f; -+ float from_y = 0.0f; -+ float to_x = 0.0f; -+ float to_y = 0.0f; -+ -+ if ((surface->width == 0) || (surface->height == 0) || (ivisurf == NULL)) { -+ return; -+ } -+ -+ view = ivi_layout->get_weston_view(ivisurf->layout_surface); -+ if (view == NULL) { -+ return; -+ } -+ -+ if (ivisurf->width != surface->width || ivisurf->height != surface->height) { -+ -+ ivisurf->width = surface->width; -+ ivisurf->height = surface->height; -+ -+ weston_view_to_global_float(view, 0, 0, &from_x, &from_y); -+ weston_view_to_global_float(view, sx, sy, &to_x, &to_y); -+ -+ weston_view_set_position(view, -+ view->geometry.x + to_x - from_x, -+ view->geometry.y + to_y - from_y); -+ weston_view_update_transform(view); -+ -+ ivi_layout->surfaceConfigure(ivisurf->layout_surface, surface->width, surface->height); -+ } -+} -+ -+static void -+surface_destroy(struct wl_client *client, struct wl_resource *resource) -+{ -+ struct ivi_shell_surface *ivisurf = wl_resource_get_user_data(resource); -+ if (ivisurf != NULL) { -+ ivisurf->surface->configure = NULL; -+ ivisurf->surface->configure_private = NULL; -+ ivisurf->surface = NULL; -+ ivi_layout->surfaceSetNativeContent(NULL, 0, 0, ivisurf->id_surface); -+ } -+ -+ wl_resource_destroy(resource); -+} -+ -+static const struct ivi_surface_interface surface_implementation = { -+ surface_destroy, -+}; -+ -+static struct ivi_shell_surface * -+is_surf_in_surfaces(struct wl_list *list_surf, uint32_t id_surface) -+{ -+ struct ivi_shell_surface *ivisurf; -+ -+ wl_list_for_each(ivisurf, list_surf, link) { -+ if (ivisurf->id_surface == id_surface) { -+ return ivisurf; -+ } -+ } -+ -+ return NULL; -+} -+ -+static const struct { -+ enum ivi_layout_warning_flag flag; -+ const char *message; -+} warning_strings[] = { -+ { IVI_WARNING_INVALID_WL_SURFACE, "wl_surface is invalid" }, -+ { IVI_WARNING_IVI_ID_IN_USE, "surface_id is already assigned by another app" }, -+}; -+ -+/** -+ * Implementation of ivi_application::surface_create. -+ * Creating new ivi_shell_surface with identification to identify the surface -+ * in the system. -+ */ -+static void -+application_surface_create(struct wl_client *client, -+ struct wl_resource *resource, -+ uint32_t id_surface, -+ struct wl_resource *surface_resource, -+ uint32_t id) -+{ -+ struct ivi_shell *shell = wl_resource_get_user_data(resource); -+ struct ivi_shell_surface *ivisurf = NULL; -+ struct ivi_layout_surface *layout_surface = NULL; -+ struct weston_surface *weston_surface = wl_resource_get_user_data(surface_resource); -+ struct wl_resource *res; -+ int32_t warn_idx = -1; -+ -+ if (weston_surface != NULL) { -+ -+ /* check if a surface already has another role*/ -+ if (weston_surface->configure) { -+ wl_resource_post_error(weston_surface->resource, -+ WL_DISPLAY_ERROR_INVALID_OBJECT, -+ "surface->configure already " -+ "set"); -+ return; -+ } -+ -+ layout_surface = ivi_layout->surfaceCreate(weston_surface, id_surface); -+ -+ if (layout_surface == NULL) -+ warn_idx = 1; -+ } else { -+ warn_idx = 0; -+ } -+ -+ res = wl_resource_create(client, &ivi_surface_interface, 1, id); -+ if (res == NULL) { -+ wl_client_post_no_memory(client); -+ return; -+ } -+ -+ if (warn_idx >= 0) { -+ wl_resource_set_implementation(res, &surface_implementation, -+ NULL, NULL); -+ -+ ivi_layout->emitWarningSignal(id_surface, warning_strings[warn_idx].flag); -+ -+ wl_resource_post_error(res, -+ WL_DISPLAY_ERROR_INVALID_OBJECT, -+ warning_strings[warn_idx].message); -+ return; -+ } -+ -+ ivisurf = is_surf_in_surfaces(&shell->ivi_surface_list, id_surface); -+ if (ivisurf == NULL) { -+ ivisurf = zalloc(sizeof *ivisurf); -+ if (ivisurf == NULL) { -+ wl_resource_post_no_memory(res); -+ return; -+ } -+ -+ wl_list_init(&ivisurf->link); -+ wl_list_insert(&shell->ivi_surface_list, &ivisurf->link); -+ -+ ivisurf->shell = shell; -+ ivisurf->id_surface = id_surface; -+ } -+ -+ ivisurf->width = 0; -+ ivisurf->height = 0; -+ ivisurf->layout_surface = layout_surface; -+ ivisurf->surface = weston_surface; -+ -+ weston_surface->configure = ivi_shell_surface_configure; -+ weston_surface->configure_private = ivisurf; -+ -+ wl_resource_set_implementation(res, &surface_implementation, -+ ivisurf, NULL); -+} -+ -+static const struct ivi_application_interface application_implementation = { -+ application_surface_create -+}; -+ -+static void -+bind_ivi_application(struct wl_client *client, -+ void *data, uint32_t version, uint32_t id) -+{ -+ struct ivi_shell *shell = data; -+ struct wl_resource *resource = NULL; -+ -+ resource = wl_resource_create(client, &ivi_application_interface, 1, id); -+ -+ wl_resource_set_implementation(resource, -+ &application_implementation, -+ shell, NULL); -+} -+ -+/** -+ * Initialization/destruction method of ivi-shell -+ */ -+static void -+shell_destroy(struct wl_listener *listener, void *data) -+{ -+ struct ivi_shell *shell = -+ container_of(listener, struct ivi_shell, destroy_listener); -+ struct ivi_shell_surface *ivisurf, *next; -+ -+ wl_list_for_each_safe(ivisurf, next, &shell->ivi_surface_list, link) { -+ wl_list_remove(&ivisurf->link); -+ free(ivisurf); -+ } -+ -+ free(shell); -+} -+ -+static void -+init_ivi_shell(struct weston_compositor *compositor, struct ivi_shell *shell) -+{ -+ shell->compositor = compositor; -+ -+ wl_list_init(&shell->ivi_surface_list); -+} -+ -+static int -+ivi_shell_setting_create(struct ivi_shell_setting *dest) -+{ -+ int result = 0; -+ struct weston_config *config = NULL; -+ struct weston_config_section *section = NULL; -+ -+ if (NULL == dest) { -+ return -1; -+ } -+ -+ config = weston_config_parse("weston.ini"); -+ section = weston_config_get_section(config, "ivi-shell", NULL, NULL); -+ -+ if (weston_config_section_get_string( -+ section, "ivi-module", (char **)&dest->ivi_module, NULL) != 0) -+ { -+ result = -1; -+ } -+ -+ weston_config_destroy(config); -+ return result; -+} -+ -+/** -+ * Initialization of ivi-shell. -+ */ -+static int -+ivi_load_modules(struct weston_compositor *compositor, const char *modules, -+ int *argc, char *argv[]) -+{ -+ const char *p, *end; -+ char buffer[256]; -+ int (*module_init)(struct weston_compositor *compositor, -+ int *argc, char *argv[]); -+ -+ if (modules == NULL) -+ return 0; -+ -+ p = modules; -+ while (*p) { -+ end = strchrnul(p, ','); -+ snprintf(buffer, sizeof buffer, "%.*s", (int) (end - p), p); -+ module_init = weston_load_module(buffer, "module_init"); -+ if (module_init) -+ module_init(compositor, argc, argv); -+ p = end; -+ while (*p == ',') -+ p++; -+ -+ } -+ -+ return 0; -+} -+ -+WL_EXPORT int -+module_init(struct weston_compositor *compositor, -+ int *argc, char *argv[]) -+{ -+ struct ivi_shell *shell = NULL; -+ char ivi_layout_path[PATH_MAX]; -+ void *module; -+ struct ivi_shell_setting setting = { }; -+ -+ shell = zalloc(sizeof *shell); -+ if (shell == NULL) { -+ return -1; -+ } -+ -+ init_ivi_shell(compositor, shell); -+ -+ shell->destroy_listener.notify = shell_destroy; -+ wl_signal_add(&compositor->destroy_signal, &shell->destroy_listener); -+ -+ if (wl_global_create(compositor->wl_display, &ivi_application_interface, 1, -+ shell, bind_ivi_application) == NULL) { -+ return -1; -+ } -+ -+ if (ivi_shell_setting_create(&setting) != 0) { -+ return 0; -+ } -+ -+ /*load module:ivi-layout*/ -+ /*ivi_layout_interface is referred by ivi-shell to use ivi-layout*/ -+ snprintf(ivi_layout_path, sizeof ivi_layout_path, "%s/%s", MODULEDIR, "ivi-layout.so"); -+ module = dlopen(ivi_layout_path, RTLD_NOW | RTLD_NOLOAD); -+ if (module) { -+ weston_log("ivi-shell: Module '%s' already loaded\n", ivi_layout_path); -+ dlclose(module); -+ return -1; -+ } -+ -+ weston_log("ivi-shell: Loading module '%s'\n", ivi_layout_path); -+ module = dlopen(ivi_layout_path, RTLD_NOW | RTLD_GLOBAL); -+ if (!module) { -+ weston_log("ivi-shell: Failed to load module: %s\n", dlerror()); -+ return -1; -+ } -+ -+ ivi_layout = dlsym(module,"ivi_layout_interface"); -+ if (!ivi_layout){ -+ weston_log("ivi-shell: couldn't find ivi_layout_interface in '%s'\n", ivi_layout_path); -+ free(setting.ivi_module); -+ return -1; -+ } -+ else{ -+ ivi_layout->initWithCompositor(compositor); -+ } -+ -+ /*Call module_init of ivi-modules which are defined in weston.ini*/ -+ if (ivi_load_modules(compositor,setting.ivi_module,argc,argv) < 0){ -+ free(setting.ivi_module); -+ return -1; -+ } -+ -+ free(setting.ivi_module); -+ return 0; -+} -diff --git a/ivi-shell/ivi-shell.h b/ivi-shell/ivi-shell.h -new file mode 100644 -index 0000000..157c5ae ---- /dev/null -+++ b/ivi-shell/ivi-shell.h -@@ -0,0 +1,35 @@ -+/* -+ * 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. -+ */ -+ -+#include <stdbool.h> -+ -+#include "compositor.h" -+ -+struct ivi_shell -+{ -+ struct wl_resource *resource; -+ struct wl_listener destroy_listener; -+ -+ struct weston_compositor *compositor; -+ -+ struct wl_list ivi_surface_list; /* struct ivi_shell_surface::link */ -+}; --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0004-ivi-shell-add-IVI-layout-APIs.patch b/meta-ivi/recipes-graphics/wayland/weston/0004-ivi-shell-add-IVI-layout-APIs.patch deleted file mode 100644 index 0edbb38..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0004-ivi-shell-add-IVI-layout-APIs.patch +++ /dev/null @@ -1,4110 +0,0 @@ -From 8ace41517c3cdf2545652def228044e2523a2644 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Tue, 6 May 2014 17:25:31 +0900 -Subject: [PATCH 04/31] ivi-shell: add IVI layout APIs - -API set of controlling properties of surface and layer which groups -surfaces. An unique ID whose type is integer is required to create -surface and layer. With the unique ID, surface and layer are identified -to control them. The API set consists of APIs to control properties of -surface and layers about followings, - -- visibility. -- opacity. -- clipping (x,y,width,height). -- position and size of it to be displayed. -- orientation per 90 degree. -- add or remove surfaces to a layer. -- order of surfaces/layers in layer/screen to be displayed. -- commit to apply property changes. -- notifications of property change. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - Makefile.am | 17 +- - ivi-shell/ivi-layout-export.h | 964 +++++++++++++ - ivi-shell/ivi-layout.c | 3066 +++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 4046 insertions(+), 1 deletion(-) - create mode 100644 ivi-shell/ivi-layout-export.h - create mode 100644 ivi-shell/ivi-layout.c - -diff --git a/Makefile.am b/Makefile.am -index e825fdd..148529f 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -703,7 +703,8 @@ endif - if ENABLE_IVI_SHELL - - module_LTLIBRARIES += \ -- $(ivi_shell) -+ $(ivi_shell) \ -+ $(ivi_layout) - - ivi_shell = ivi-shell.la - ivi_shell_la_LDFLAGS = -module -avoid-version -@@ -719,6 +720,20 @@ nodist_ivi_shell_la_SOURCES = \ - - BUILT_SOURCES += $(nodist_ivi_shell_la_SOURCES) - -+ivi_layout = ivi-layout.la -+ivi_layout_la_LDFLAGS = -module -avoid-version -+ivi_layout_la_LIBADD = $(COMPOSITOR_LIBS) $(IVI_SHELL_LIBS) libshared.la -+ivi_layout_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS) $(IVI_SHELL_CFLAGS) -+ivi_layout_la_SOURCES = \ -+ ivi-shell/ivi-layout.h \ -+ ivi-shell/ivi-layout-export.h \ -+ ivi-shell/ivi-layout.c -+nodist_ivi_layout_la_SOURCES = \ -+ protocol/ivi-application-protocol.c \ -+ protocol/ivi-application-server-protocol.h -+ -+BUILT_SOURCES += $(nodist_ivi_layout_la_SOURCES) -+ - endif - - -diff --git a/ivi-shell/ivi-layout-export.h b/ivi-shell/ivi-layout-export.h -new file mode 100644 -index 0000000..81dd6f3 ---- /dev/null -+++ b/ivi-shell/ivi-layout-export.h -@@ -0,0 +1,964 @@ -+/* -+ * Copyright (C) 2013 DENSO CORPORATION -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and -+ * its documentation for any purpose is hereby granted without fee, provided -+ * that the above copyright notice appear in all copies and that both that -+ * copyright notice and this permission notice appear in supporting -+ * documentation, and that the name of the copyright holders not be used in -+ * advertising or publicity pertaining to distribution of the software -+ * without specific, written prior permission. The copyright holders make -+ * no representations about the suitability of this software for any -+ * purpose. It is provided "as is" without express or implied warranty. -+ * -+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS -+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY -+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+/** -+ * The ivi-layout library supports API set of controlling properties of -+ * surface and layer which groups surfaces. An unique ID whose type is integer -+ * is required to create surface and layer. With the unique ID, surface and -+ * layer are identified to control them. The API set consists of APIs to control -+ * properties of surface and layers about followings, -+ * - visibility. -+ * - opacity. -+ * - clipping (x,y,width,height). -+ * - position and size of it to be displayed. -+ * - orientation per 90 degree. -+ * - add or remove surfaces to a layer. -+ * - order of surfaces/layers in layer/screen to be displayed. -+ * - commit to apply property changes. -+ * - notifications of property change. -+ * -+ * Management of surfaces and layers grouping these surfaces are common way in -+ * In-Vehicle Infotainment system, which integrate several domains in one system. -+ * A layer is allocated to a domain in order to control application surfaces -+ * grouped to the layer all together. -+ */ -+ -+#ifndef _IVI_LAYOUT_EXPORT_H_ -+#define _IVI_LAYOUT_EXPORT_H_ -+ -+#ifdef __cplusplus -+extern "C" { -+#endif /* __cplusplus */ -+ -+#include "compositor.h" -+#include "ivi-layout.h" -+ -+struct ivi_layout_SurfaceProperties -+{ -+ float opacity; -+ int32_t sourceX; -+ int32_t sourceY; -+ int32_t sourceWidth; -+ int32_t sourceHeight; -+ int32_t origSourceWidth; -+ int32_t origSourceHeight; -+ int32_t destX; -+ int32_t destY; -+ int32_t destWidth; -+ int32_t destHeight; -+ int32_t orientation; -+ int32_t visibility; -+ int32_t frameCounter; -+ int32_t drawCounter; -+ int32_t updateCounter; -+ int32_t pixelformat; -+ int32_t nativeSurface; -+ int32_t inputDevicesAcceptance; -+ int32_t chromaKeyEnabled; -+ int32_t chromaKeyRed; -+ int32_t chromaKeyGreen; -+ int32_t chromaKeyBlue; -+ int32_t creatorPid; -+}; -+ -+struct ivi_layout_LayerProperties -+{ -+ float opacity; -+ int32_t sourceX; -+ int32_t sourceY; -+ int32_t sourceWidth; -+ int32_t sourceHeight; -+ int32_t origSourceWidth; -+ int32_t origSourceHeight; -+ int32_t destX; -+ int32_t destY; -+ int32_t destWidth; -+ int32_t destHeight; -+ int32_t orientation; -+ int32_t visibility; -+ int32_t type; -+ int32_t chromaKeyEnabled; -+ int32_t chromaKeyRed; -+ int32_t chromaKeyGreen; -+ int32_t chromaKeyBlue; -+ int32_t creatorPid; -+}; -+ -+struct ivi_layout_layer; -+struct ivi_layout_screen; -+ -+enum ivi_layout_notification_mask { -+ IVI_NOTIFICATION_NONE = 0, -+ IVI_NOTIFICATION_OPACITY = (1 << 1), -+ IVI_NOTIFICATION_SOURCE_RECT = (1 << 2), -+ IVI_NOTIFICATION_DEST_RECT = (1 << 3), -+ IVI_NOTIFICATION_DIMENSION = (1 << 4), -+ IVI_NOTIFICATION_POSITION = (1 << 5), -+ IVI_NOTIFICATION_ORIENTATION = (1 << 6), -+ IVI_NOTIFICATION_VISIBILITY = (1 << 7), -+ IVI_NOTIFICATION_PIXELFORMAT = (1 << 8), -+ IVI_NOTIFICATION_ADD = (1 << 9), -+ IVI_NOTIFICATION_REMOVE = (1 << 10), -+ IVI_NOTIFICATION_ALL = 0xFFFF -+}; -+ -+typedef void(*shellWarningNotificationFunc)(uint32_t id_surface, -+ enum ivi_layout_warning_flag warn, -+ void *userdata); -+ -+typedef void(*layerPropertyNotificationFunc)(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_LayerProperties*, -+ enum ivi_layout_notification_mask mask, -+ void *userdata); -+ -+typedef void(*surfacePropertyNotificationFunc)(struct ivi_layout_surface *ivisurf, -+ struct ivi_layout_SurfaceProperties*, -+ enum ivi_layout_notification_mask mask, -+ void *userdata); -+ -+typedef void(*layerCreateNotificationFunc)(struct ivi_layout_layer *ivilayer, -+ void *userdata); -+ -+typedef void(*layerRemoveNotificationFunc)(struct ivi_layout_layer *ivilayer, -+ void *userdata); -+ -+typedef void(*surfaceCreateNotificationFunc)(struct ivi_layout_surface *ivisurf, -+ void *userdata); -+ -+typedef void(*surfaceRemoveNotificationFunc)(struct ivi_layout_surface *ivisurf, -+ void *userdata); -+ -+typedef void(*surfaceConfigureNotificationFunc)(struct ivi_layout_surface *ivisurf, -+ void *userdata); -+ -+typedef void(*ivi_controller_surface_content_callback)(struct ivi_layout_surface *ivisurf, -+ int32_t content, -+ void *userdata); -+ -+int32_t -+ivi_layout_addNotificationShellWarning(shellWarningNotificationFunc callback, -+ void *userdata); -+ -+void -+ivi_layout_removeNotificationShellWarning(shellWarningNotificationFunc callback, -+ void *userdata); -+ -+/** -+ * \brief to be called by ivi-shell in order to set initail view of -+ * weston_surface. -+ */ -+/* -+struct weston_view * -+ivi_layout_get_weston_view(struct ivi_layout_surface *surface); -+*/ -+ -+/** -+ * \brief initialize ivi-layout -+ */ -+/* -+void -+ivi_layout_initWithCompositor(struct weston_compositor *ec); -+*/ -+ -+/** -+ * \brief register for notification when layer is created -+ */ -+int32_t -+ivi_layout_addNotificationCreateLayer(layerCreateNotificationFunc callback, -+ void *userdata); -+ -+void -+ivi_layout_removeNotificationCreateLayer(layerCreateNotificationFunc callback, -+ void *userdata); -+ -+/** -+ * \brief register for notification when layer is removed -+ */ -+int32_t -+ivi_layout_addNotificationRemoveLayer(layerRemoveNotificationFunc callback, -+ void *userdata); -+ -+void -+ivi_layout_removeNotificationRemoveLayer(layerRemoveNotificationFunc callback, -+ void *userdata); -+ -+/** -+ * \brief register for notification when surface is created -+ */ -+int32_t -+ivi_layout_addNotificationCreateSurface(surfaceCreateNotificationFunc callback, -+ void *userdata); -+ -+void -+ivi_layout_removeNotificationCreateSurface(surfaceCreateNotificationFunc callback, -+ void *userdata); -+ -+/** -+ * \brief register for notification when surface is removed -+ */ -+int32_t -+ivi_layout_addNotificationRemoveSurface(surfaceRemoveNotificationFunc callback, -+ void *userdata); -+ -+void -+ivi_layout_removeNotificationRemoveSurface(surfaceRemoveNotificationFunc callback, -+ void *userdata); -+ -+/** -+ * \brief register for notification when surface is configured -+ */ -+int32_t -+ivi_layout_addNotificationConfigureSurface(surfaceConfigureNotificationFunc callback, -+ void *userdata); -+ -+void -+ivi_layout_removeNotificationConfigureSurface(surfaceConfigureNotificationFunc callback, -+ void *userdata); -+ -+/** -+ * \brief get id of surface from ivi_layout_surface -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+uint32_t -+ivi_layout_getIdOfSurface(struct ivi_layout_surface *ivisurf); -+ -+/** -+ * \brief get id of layer from ivi_layout_layer -+ * -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+uint32_t -+ivi_layout_getIdOfLayer(struct ivi_layout_layer *ivilayer); -+ -+/** -+ * \brief get ivi_layout_layer from id of layer -+ * -+ * \return (struct ivi_layout_layer *) -+ * if the method call was successful -+ * \return NULL if the method call was failed -+ */ -+struct ivi_layout_layer * -+ivi_layout_getLayerFromId(uint32_t id_layer); -+ -+/** -+ * \brief get ivi_layout_surface from id of surface -+ * -+ * \return (struct ivi_layout_surface *) -+ * if the method call was successful -+ * \return NULL if the method call was failed -+ */ -+struct ivi_layout_surface * -+ivi_layout_getSurfaceFromId(uint32_t id_surface); -+ -+/** -+ * \brief get ivi_layout_screen from id of screen -+ * -+ * \return (struct ivi_layout_screen *) -+ * if the method call was successful -+ * \return NULL if the method call was failed -+ */ -+struct ivi_layout_screen * -+ivi_layout_getScreenFromId(uint32_t id_screen); -+ -+/** -+ * \brief Get the screen resolution of a specific screen -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_getScreenResolution(struct ivi_layout_screen *iviscrn, -+ int32_t *pWidth, -+ int32_t *pHeight); -+ -+/** -+ * \brief register for notification on property changes of surface -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceAddNotification(struct ivi_layout_surface *ivisurf, -+ surfacePropertyNotificationFunc callback, -+ void *userdata); -+ -+/** -+ * \brief remove notification on property changes of surface -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceRemoveNotification(struct ivi_layout_surface *ivisurf); -+ -+/** -+ * \brief Create a surface -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+/* -+struct ivi_layout_surface * -+ivi_layout_surfaceCreate(struct weston_surface *wl_surface, -+ uint32_t id_surface); -+*/ -+ -+/** -+ * \brief Set the native content of an application to be used as surface content. -+ * If wl_surface is NULL, remove the native content of a surface -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+/* -+int32_t -+ivi_layout_surfaceSetNativeContent(struct weston_surface *wl_surface, -+ uint32_t width, -+ uint32_t height, -+ uint32_t id_surface); -+*/ -+ -+/** -+ * \brief Set an observer callback for surface content status change. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceSetContentObserver(struct ivi_layout_surface *ivisurf, -+ ivi_controller_surface_content_callback callback, -+ void* userdata); -+ -+/** -+ * \brief initialize ivi_layout_surface dest/source width and height -+ */ -+/* -+void -+ivi_layout_surfaceConfigure(struct ivi_layout_surface *ivisurf, -+ uint32_t width, uint32_t height); -+*/ -+ -+/** -+ * \brief Remove a surface -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceRemove(struct ivi_layout_surface *ivisurf); -+ -+/** -+ * \brief Set from which kind of devices the surface can accept input events. -+ * By default, a surface accept input events from all kind of devices (keyboards, pointer, ...) -+ * By calling this function, you can adjust surface preferences. Note that this function only -+ * adjust the acceptance for the specified devices. Non specified are keept untouched. -+ * -+ * Typicall use case for this function is when dealing with pointer or touch events. -+ * Those are normally dispatched to the first visible surface below the coordinate. -+ * If you want a different behavior (i.e. forward events to an other surface below the coordinate, -+ * you can set all above surfaces to refuse input events) -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_UpdateInputEventAcceptanceOn(struct ivi_layout_surface *ivisurf, -+ int32_t devices, -+ int32_t acceptance); -+ -+/** -+ * \brief Get the layer properties -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_getPropertiesOfLayer(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_LayerProperties *pLayerProperties); -+ -+/** -+ * \brief Get the number of hardware layers of a screen -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_getNumberOfHardwareLayers(uint32_t id_screen, -+ int32_t *pNumberOfHardwareLayers); -+ -+/** -+ * \brief Get the screens -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_getScreens(int32_t *pLength, struct ivi_layout_screen ***ppArray); -+ -+/** -+ * \brief Get the screens under the given layer -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_getScreensUnderLayer(struct ivi_layout_layer *ivilayer, -+ int32_t *pLength, -+ struct ivi_layout_screen ***ppArray); -+ -+/** -+ * \brief Get all Layers which are currently registered and managed by the services -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_getLayers(int32_t *pLength, struct ivi_layout_layer ***ppArray); -+ -+/** -+ * \brief Get all Layers of the given screen -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_getLayersOnScreen(struct ivi_layout_screen *iviscrn, -+ int32_t *pLength, -+ struct ivi_layout_layer ***ppArray); -+ -+/** -+ * \brief Get all Layers under the given surface -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_getLayersUnderSurface(struct ivi_layout_surface *ivisurf, -+ int32_t *pLength, -+ struct ivi_layout_layer ***ppArray); -+ -+/** -+ * \brief Get all Surfaces which are currently registered and managed by the services -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_getSurfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray); -+ -+/** -+ * \brief Get all Surfaces which are currently registered to a given layer and are managed by the services -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_getSurfacesOnLayer(struct ivi_layout_layer *ivilayer, -+ int32_t *pLength, -+ struct ivi_layout_surface ***ppArray); -+ -+/** -+ * \brief Create a layer which should be managed by the service -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+struct ivi_layout_layer * -+ivi_layout_layerCreateWithDimension(uint32_t id_layer, -+ int32_t width, int32_t height); -+ -+/** -+ * \brief Removes a layer which is currently managed by the service -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerRemove(struct ivi_layout_layer *ivilayer); -+ -+/** -+ * \brief Get the current type of the layer. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerGetType(struct ivi_layout_layer *ivilayer, -+ int32_t *pLayerType); -+ -+/** -+ * \brief Set the visibility of a layer. If a layer is not visible, the layer and its -+ * surfaces will not be rendered. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerSetVisibility(struct ivi_layout_layer *ivilayer, -+ int32_t newVisibility); -+ -+/** -+ * \brief Get the visibility of a layer. If a layer is not visible, the layer and its -+ * surfaces will not be rendered. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerGetVisibility(struct ivi_layout_layer *ivilayer, -+ int32_t *pVisibility); -+ -+/** -+ * \brief Set the opacity of a layer. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerSetOpacity(struct ivi_layout_layer *ivilayer, float opacity); -+ -+/** -+ * \brief Get the opacity of a layer. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerGetOpacity(struct ivi_layout_layer *ivilayer, float *pOpacity); -+ -+/** -+ * \brief Set the area of a layer which should be used for the rendering. -+ * Only this part will be visible. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerSetSourceRectangle(struct ivi_layout_layer *ivilayer, -+ int32_t x, int32_t y, -+ int32_t width, int32_t height); -+ -+/** -+ * \brief Set the destination area on the display for a layer. -+ * The layer will be scaled and positioned to this rectangle for rendering -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerSetDestinationRectangle(struct ivi_layout_layer *ivilayer, -+ int32_t x, int32_t y, -+ int32_t width, int32_t height); -+ -+/** -+ * \brief Get the horizontal and vertical dimension of the layer. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerGetDimension(struct ivi_layout_layer *ivilayer, -+ int32_t *pDimension); -+ -+/** -+ * \brief Set the horizontal and vertical dimension of the layer. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerSetDimension(struct ivi_layout_layer *ivilayer, -+ int32_t *pDimension); -+ -+/** -+ * \brief Get the horizontal and vertical position of the layer. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerGetPosition(struct ivi_layout_layer *ivilayer, -+ int32_t *pPosition); -+ -+/** -+ * \brief Sets the horizontal and vertical position of the layer. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerSetPosition(struct ivi_layout_layer *ivilayer, -+ int32_t *pPosition); -+ -+/** -+ * \brief Sets the orientation of a layer. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerSetOrientation(struct ivi_layout_layer *ivilayer, -+ int32_t orientation); -+ -+/** -+ * \brief Gets the orientation of a layer. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerGetOrientation(struct ivi_layout_layer *ivilayer, -+ int32_t *pOrientation); -+ -+/** -+ * \brief Sets the color value which defines the transparency value. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerSetChromaKey(struct ivi_layout_layer *ivilayer, -+ int32_t* pColor); -+ -+/** -+ * \brief Sets render order of surfaces within one layer -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerSetRenderOrder(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_surface **pSurface, -+ int32_t number); -+ -+/** -+ * \brief Get the capabilities of a layer -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerGetCapabilities(struct ivi_layout_layer *ivilayer, -+ int32_t *pCapabilities); -+ -+/** -+ * \brief Get the possible capabilities of a layertype -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerTypeGetCapabilities(int32_t layerType, -+ int32_t *pCapabilities); -+ -+/** -+ * \brief Create the logical surface, which has no native buffer associated -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceInitialize(struct ivi_layout_surface **pSurface); -+ -+/** -+ * \brief Set the visibility of a surface. -+ * If a surface is not visible it will not be rendered. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceSetVisibility(struct ivi_layout_surface *ivisurf, -+ int32_t newVisibility); -+ -+/** -+ * \brief Get the visibility of a surface. -+ * If a surface is not visible it will not be rendered. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceGetVisibility(struct ivi_layout_surface *ivisurf, -+ int32_t *pVisibility); -+ -+/** -+ * \brief Set the opacity of a surface. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceSetOpacity(struct ivi_layout_surface *ivisurf, -+ float opacity); -+ -+/** -+ * \brief Get the opacity of a surface. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceGetOpacity(struct ivi_layout_surface *ivisurf, -+ float *pOpacity); -+ -+/** -+ * \brief Set the keyboard focus on a certain surface -+ * To receive keyboard events, 2 conditions must be fulfilled: -+ * 1- The surface must accept events from keyboard. See ilm_UpdateInputEventAcceptanceOn -+ * 2- The keyboard focus must be set on that surface -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_SetKeyboardFocusOn(struct ivi_layout_surface *ivisurf); -+ -+/** -+ * \brief Get the indentifier of the surface which hold the keyboard focus -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_GetKeyboardFocusSurfaceId(struct ivi_layout_surface **pSurfaceId); -+ -+/** -+ * \brief Set the destination area of a surface within a layer for rendering. -+ * The surface will be scaled to this rectangle for rendering. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceSetDestinationRectangle(struct ivi_layout_surface *ivisurf, -+ int32_t x, int32_t y, -+ int32_t width, int32_t height); -+ -+/** -+ * \brief Set the horizontal and vertical dimension of the surface. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceSetDimension(struct ivi_layout_surface *ivisurf, -+ int32_t *pDimension); -+ -+/** -+ * \brief Get the horizontal and vertical dimension of the surface. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceGetDimension(struct ivi_layout_surface *ivisurf, -+ int32_t *pDimension); -+ -+/** -+ * \brief Sets the horizontal and vertical position of the surface. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceSetPosition(struct ivi_layout_surface *ivisurf, -+ int32_t *pPosition); -+ -+/** -+ * \brief Get the horizontal and vertical position of the surface. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceGetPosition(struct ivi_layout_surface *ivisurf, -+ int32_t *pPosition); -+ -+/** -+ * \brief Sets the orientation of a surface. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceSetOrientation(struct ivi_layout_surface *ivisurf, -+ int32_t orientation); -+ -+/** -+ * \brief Gets the orientation of a surface. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceGetOrientation(struct ivi_layout_surface *ivisurf, -+ int32_t *pOrientation); -+ -+/** -+ * \brief Gets the pixelformat of a surface. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceGetPixelformat(struct ivi_layout_layer *ivisurf, -+ int32_t *pPixelformat); -+ -+/** -+ * \brief Sets the color value which defines the transparency value of a surface. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceSetChromaKey(struct ivi_layout_surface *ivisurf, -+ int32_t* pColor); -+ -+/** -+ * \brief Add a layer to a screen which is currently managed by the service -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_screenAddLayer(struct ivi_layout_screen *iviscrn, -+ struct ivi_layout_layer *addlayer); -+ -+/** -+ * \brief Sets render order of layers on a display -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_screenSetRenderOrder(struct ivi_layout_screen *iviscrn, -+ struct ivi_layout_layer **pLayer, -+ const int32_t number); -+ -+/** -+ * \brief Enable or disable a rendering optimization -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_SetOptimizationMode(uint32_t id, int32_t mode); -+ -+/** -+ * \brief Get the current enablement for an optimization -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_GetOptimizationMode(uint32_t id, int32_t *pMode); -+ -+/** -+ * \brief register for notification on property changes of layer -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerAddNotification(struct ivi_layout_layer *ivilayer, -+ layerPropertyNotificationFunc callback, -+ void *userdata); -+ -+/** -+ * \brief remove notification on property changes of layer -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerRemoveNotification(struct ivi_layout_layer *ivilayer); -+ -+/** -+ * \brief Get the surface properties -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_getPropertiesOfSurface(struct ivi_layout_surface *ivisurf, -+ struct ivi_layout_SurfaceProperties *pSurfaceProperties); -+ -+/** -+ * \brief Add a surface to a layer which is currently managed by the service -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerAddSurface(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_surface *addsurf); -+ -+/** -+ * \brief Removes a surface from a layer which is currently managed by the service -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_layerRemoveSurface(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_surface *remsurf); -+ -+/** -+ * \brief Set the area of a surface which should be used for the rendering. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_surfaceSetSourceRectangle(struct ivi_layout_surface *ivisurf, -+ int32_t x, int32_t y, -+ int32_t width, int32_t height); -+ -+/** -+ * \brief get weston_output from ivi_layout_screen. -+ * -+ * \return (struct weston_screen *) -+ * if the method call was successful -+ * \return NULL if the method call was failed -+ */ -+struct weston_output * -+ivi_layout_screenGetOutput(struct ivi_layout_screen *); -+ -+/** -+ * \brief Commit all changes and execute all enqueued commands since last commit. -+ * -+ * \return 0 if the method call was successful -+ * \return -1 if the method call was failed -+ */ -+int32_t -+ivi_layout_commitChanges(void); -+ -+#ifdef __cplusplus -+} /**/ -+#endif /* __cplusplus */ -+ -+#endif /* _IVI_LAYOUT_EXPORT_H_ */ -diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c -new file mode 100644 -index 0000000..985798a ---- /dev/null -+++ b/ivi-shell/ivi-layout.c -@@ -0,0 +1,3066 @@ -+/* -+ * Copyright (C) 2013 DENSO CORPORATION -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and -+ * its documentation for any purpose is hereby granted without fee, provided -+ * that the above copyright notice appear in all copies and that both that -+ * copyright notice and this permission notice appear in supporting -+ * documentation, and that the name of the copyright holders not be used in -+ * advertising or publicity pertaining to distribution of the software -+ * without specific, written prior permission. The copyright holders make -+ * no representations about the suitability of this software for any -+ * purpose. It is provided "as is" without express or implied warranty. -+ * -+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS -+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY -+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+/** -+ * Implementation of ivi-layout library. The actual view on screen is -+ * not updated till calling ivi_layout_commitChanges. A overview from -+ * calling API for updating properties of surfaces/layer to asking compositor -+ * to compose them by using weston_compositor_schedule_repaint, -+ * 0/ initialize this library by ivi_layout_initWithCompositor -+ * with (struct weston_compositor *ec) from ivi-shell. -+ * 1/ When a API for updating properties of surface/layer, it updates -+ * pending prop of ivi_layout_surface/layer/screen which are structure to -+ * store properties. -+ * 2/ Before calling commitChanges, in case of calling a API to get a property, -+ * return current property, not pending property. -+ * 3/ At the timing of calling ivi_layout_commitChanges, pending properties -+ * are applied -+ * to properties. -+ * 4/ According properties, set transformation by using weston_matrix and -+ * weston_view per surfaces and layers in while loop. -+ * 5/ Set damage and trigger transform by using weston_view_geometry_dirty and -+ * weston_view_geometry_dirty. -+ * 6/ Notify update of properties. -+ * 7/ Trigger composition by weston_compositor_schedule_repaint. -+ * -+ */ -+ -+#include <sys/wait.h> -+#include <unistd.h> -+#include <stdlib.h> -+#include <stdio.h> -+#include <string.h> -+#include <linux/input.h> -+ -+#include "compositor.h" -+#include "ivi-layout.h" -+#include "ivi-layout-export.h" -+ -+enum ivi_layout_surface_orientation { -+ IVI_LAYOUT_SURFACE_ORIENTATION_0_DEGREES = 0, -+ IVI_LAYOUT_SURFACE_ORIENTATION_90_DEGREES = 1, -+ IVI_LAYOUT_SURFACE_ORIENTATION_180_DEGREES = 2, -+ IVI_LAYOUT_SURFACE_ORIENTATION_270_DEGREES = 3, -+}; -+ -+enum ivi_layout_surface_pixelformat { -+ IVI_LAYOUT_SURFACE_PIXELFORMAT_R_8 = 0, -+ IVI_LAYOUT_SURFACE_PIXELFORMAT_RGB_888 = 1, -+ IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_8888 = 2, -+ IVI_LAYOUT_SURFACE_PIXELFORMAT_RGB_565 = 3, -+ IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_5551 = 4, -+ IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_6661 = 5, -+ IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_4444 = 6, -+ IVI_LAYOUT_SURFACE_PIXELFORMAT_UNKNOWN = 7, -+}; -+ -+struct link_layer { -+ struct ivi_layout_layer *ivilayer; -+ struct wl_list link; -+ struct wl_list link_to_layer; -+}; -+ -+struct link_screen { -+ struct ivi_layout_screen *iviscrn; -+ struct wl_list link; -+ struct wl_list link_to_screen; -+}; -+ -+struct listener_layoutNotification { -+ void *userdata; -+ struct wl_listener listener; -+}; -+ -+struct ivi_layout; -+ -+struct ivi_layout_surface { -+ struct wl_list link; -+ struct wl_signal property_changed; -+ struct wl_list list_layer; -+ int32_t update_count; -+ uint32_t id_surface; -+ -+ struct ivi_layout *layout; -+ struct weston_surface *surface; -+ -+ struct wl_listener surface_destroy_listener; -+ struct weston_transform surface_rotation; -+ struct weston_transform layer_rotation; -+ struct weston_transform surface_pos; -+ struct weston_transform layer_pos; -+ struct weston_transform scaling; -+ struct ivi_layout_SurfaceProperties prop; -+ int32_t pixelformat; -+ uint32_t event_mask; -+ -+ struct { -+ struct ivi_layout_SurfaceProperties prop; -+ struct wl_list link; -+ } pending; -+ -+ struct { -+ struct wl_list link; -+ struct wl_list list_layer; -+ } order; -+ -+ struct { -+ ivi_controller_surface_content_callback callback; -+ void* userdata; -+ } content_observer; -+}; -+ -+struct ivi_layout_layer { -+ struct wl_list link; -+ struct wl_signal property_changed; -+ struct wl_list list_screen; -+ struct wl_list link_to_surface; -+ uint32_t id_layer; -+ -+ struct ivi_layout *layout; -+ -+ struct ivi_layout_LayerProperties prop; -+ uint32_t event_mask; -+ -+ struct { -+ struct ivi_layout_LayerProperties prop; -+ struct wl_list list_surface; -+ struct wl_list link; -+ } pending; -+ -+ struct { -+ struct wl_list list_surface; -+ struct wl_list link; -+ } order; -+}; -+ -+struct ivi_layout_screen { -+ struct wl_list link; -+ struct wl_list link_to_layer; -+ uint32_t id_screen; -+ -+ struct ivi_layout *layout; -+ struct weston_output *output; -+ -+ uint32_t event_mask; -+ -+ struct { -+ struct wl_list list_layer; -+ struct wl_list link; -+ } pending; -+ -+ struct { -+ struct wl_list list_layer; -+ struct wl_list link; -+ } order; -+}; -+ -+struct ivi_layout { -+ struct weston_compositor *compositor; -+ -+ struct wl_list list_surface; -+ struct wl_list list_layer; -+ struct wl_list list_screen; -+ -+ struct { -+ struct wl_signal created; -+ struct wl_signal removed; -+ } layer_notification; -+ -+ struct { -+ struct wl_signal created; -+ struct wl_signal removed; -+ struct wl_signal configure_changed; -+ } surface_notification; -+ -+ struct weston_layer layout_layer; -+ struct wl_signal warning_signal; -+}; -+ -+struct ivi_layout_notificationCallback { -+ void *callback; -+ void *data; -+}; -+ -+struct shellWarningArgs { -+ uint32_t id_surface; -+ enum ivi_layout_warning_flag flag; -+}; -+ -+static struct ivi_layout ivilayout = {0}; -+ -+static struct ivi_layout * -+get_instance(void) -+{ -+ return &ivilayout; -+} -+ -+static void -+ivi_layout_emitWarningSignal(uint32_t id_surface, -+ enum ivi_layout_warning_flag flag) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct shellWarningArgs *args = malloc(sizeof *args); -+ -+ if (args == NULL) { -+ weston_log("ivi_layout_emitWarningSignal: failed to allocate memory\n"); -+ return; -+ } -+ -+ args->id_surface = id_surface; -+ args->flag = flag; -+ -+ wl_signal_emit(&layout->warning_signal, args); -+ free(args); -+} -+ -+/** -+ * Internal API to add/remove a link to surface from layer. -+ */ -+static void -+add_link_to_surface(struct ivi_layout_layer *ivilayer, -+ struct link_layer *link_layer) -+{ -+ struct link_layer *link = NULL; -+ int found = 0; -+ -+ wl_list_for_each(link, &ivilayer->link_to_surface, link_to_layer) { -+ if (link == link_layer) { -+ found = 1; -+ break; -+ } -+ } -+ -+ if (found == 0) { -+ wl_list_init(&link_layer->link_to_layer); -+ wl_list_insert(&ivilayer->link_to_surface, &link_layer->link_to_layer); -+ } -+} -+ -+static void -+remove_link_to_surface(struct ivi_layout_layer *ivilayer) -+{ -+ struct link_layer *link = NULL; -+ struct link_layer *next = NULL; -+ -+ wl_list_for_each_safe(link, next, &ivilayer->link_to_surface, link_to_layer) { -+ if (!wl_list_empty(&link->link_to_layer)) { -+ wl_list_remove(&link->link_to_layer); -+ } -+ if (!wl_list_empty(&link->link)) { -+ wl_list_remove(&link->link); -+ } -+ free(link); -+ } -+ -+ wl_list_init(&ivilayer->link_to_surface); -+} -+ -+/** -+ * Internal API to add a link to layer from screen. -+ */ -+static void -+add_link_to_layer(struct ivi_layout_screen *iviscrn, -+ struct link_screen *link_screen) -+{ -+ wl_list_init(&link_screen->link_to_screen); -+ wl_list_insert(&iviscrn->link_to_layer, &link_screen->link_to_screen); -+} -+ -+/** -+ * Internal API to add/remove a surface from layer. -+ */ -+static void -+add_ordersurface_to_layer(struct ivi_layout_surface *ivisurf, -+ struct ivi_layout_layer *ivilayer) -+{ -+ struct link_layer *link_layer = NULL; -+ -+ link_layer = malloc(sizeof *link_layer); -+ if (link_layer == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return; -+ } -+ -+ link_layer->ivilayer = ivilayer; -+ wl_list_init(&link_layer->link); -+ wl_list_insert(&ivisurf->list_layer, &link_layer->link); -+ add_link_to_surface(ivilayer, link_layer); -+} -+ -+static void -+remove_ordersurface_from_layer(struct ivi_layout_surface *ivisurf) -+{ -+ struct link_layer *link_layer = NULL; -+ struct link_layer *next = NULL; -+ -+ wl_list_for_each_safe(link_layer, next, &ivisurf->list_layer, link) { -+ if (!wl_list_empty(&link_layer->link)) { -+ wl_list_remove(&link_layer->link); -+ } -+ if (!wl_list_empty(&link_layer->link_to_layer)) { -+ wl_list_remove(&link_layer->link_to_layer); -+ } -+ free(link_layer); -+ } -+ wl_list_init(&ivisurf->list_layer); -+} -+ -+/** -+ * Internal API to add/remove a layer from screen. -+ */ -+static void -+add_orderlayer_to_screen(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_screen *iviscrn) -+{ -+ struct link_screen *link_scrn = NULL; -+ -+ link_scrn = malloc(sizeof *link_scrn); -+ if (link_scrn == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return; -+ } -+ -+ link_scrn->iviscrn = iviscrn; -+ wl_list_init(&link_scrn->link); -+ wl_list_insert(&ivilayer->list_screen, &link_scrn->link); -+ add_link_to_layer(iviscrn, link_scrn); -+} -+ -+static void -+remove_orderlayer_from_screen(struct ivi_layout_layer *ivilayer) -+{ -+ struct link_screen *link_scrn = NULL; -+ struct link_screen *next = NULL; -+ -+ wl_list_for_each_safe(link_scrn, next, &ivilayer->list_screen, link) { -+ if (!wl_list_empty(&link_scrn->link)) { -+ wl_list_remove(&link_scrn->link); -+ } -+ if (!wl_list_empty(&link_scrn->link_to_screen)) { -+ wl_list_remove(&link_scrn->link_to_screen); -+ } -+ free(link_scrn); -+ } -+ wl_list_init(&ivilayer->list_screen); -+} -+ -+/** -+ * Internal API to add/remove a layer from screen. -+ */ -+static struct ivi_layout_surface * -+get_surface(struct wl_list *list_surf, uint32_t id_surface) -+{ -+ struct ivi_layout_surface *ivisurf; -+ -+ wl_list_for_each(ivisurf, list_surf, link) { -+ if (ivisurf->id_surface == id_surface) { -+ return ivisurf; -+ } -+ } -+ -+ return NULL; -+} -+ -+static struct ivi_layout_layer * -+get_layer(struct wl_list *list_layer, uint32_t id_layer) -+{ -+ struct ivi_layout_layer *ivilayer; -+ -+ wl_list_for_each(ivilayer, list_layer, link) { -+ if (ivilayer->id_layer == id_layer) { -+ return ivilayer; -+ } -+ } -+ -+ return NULL; -+} -+ -+/** -+ * Called at destruction of ivi_surface -+ */ -+static void -+westonsurface_destroy_from_ivisurface(struct wl_listener *listener, void *data) -+{ -+ struct ivi_layout_surface *ivisurf = NULL; -+ -+ ivisurf = container_of(listener, struct ivi_layout_surface, -+ surface_destroy_listener); -+ -+ wl_list_init(&ivisurf->surface_rotation.link); -+ wl_list_init(&ivisurf->layer_rotation.link); -+ wl_list_init(&ivisurf->surface_pos.link); -+ wl_list_init(&ivisurf->layer_pos.link); -+ wl_list_init(&ivisurf->scaling.link); -+ -+ ivisurf->surface = NULL; -+ ivi_layout_surfaceRemove(ivisurf); -+} -+ -+/** -+ * Internal API to check layer/surface already added in layer/screen. -+ * Called by ivi_layout_layerAddSurface/ivi_layout_screenAddLayer -+ */ -+static int -+is_surface_in_layer(struct ivi_layout_surface *ivisurf, -+ struct ivi_layout_layer *ivilayer) -+{ -+ struct ivi_layout_surface *surf = NULL; -+ -+ wl_list_for_each(surf, &ivilayer->pending.list_surface, pending.link) { -+ if (surf->id_surface == ivisurf->id_surface) { -+ return 1; -+ } -+ } -+ -+ return 0; -+} -+ -+static int -+is_layer_in_screen(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_screen *iviscrn) -+{ -+ struct ivi_layout_layer *layer = NULL; -+ -+ wl_list_for_each(layer, &iviscrn->pending.list_layer, pending.link) { -+ if (layer->id_layer == ivilayer->id_layer) { -+ return 1; -+ } -+ } -+ -+ return 0; -+} -+ -+/** -+ * Internal API to initialize screens found from output_list of weston_compositor. -+ * Called by ivi_layout_initWithCompositor. -+ */ -+static void -+create_screen(struct weston_compositor *ec) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_screen *iviscrn = NULL; -+ struct weston_output *output = NULL; -+ int32_t count = 0; -+ -+ wl_list_for_each(output, &ec->output_list, link) { -+ iviscrn = calloc(1, sizeof *iviscrn); -+ if (iviscrn == NULL) { -+ weston_log("fails to allocate memory\n"); -+ continue; -+ } -+ -+ wl_list_init(&iviscrn->link); -+ iviscrn->layout = layout; -+ -+ iviscrn->id_screen = count; -+ count++; -+ -+ iviscrn->output = output; -+ iviscrn->event_mask = 0; -+ -+ wl_list_init(&iviscrn->pending.list_layer); -+ wl_list_init(&iviscrn->pending.link); -+ -+ wl_list_init(&iviscrn->order.list_layer); -+ wl_list_init(&iviscrn->order.link); -+ -+ wl_list_init(&iviscrn->link_to_layer); -+ -+ wl_list_insert(&layout->list_screen, &iviscrn->link); -+ } -+} -+ -+/** -+ * Internal APIs to initialize properties of surface/layer when they are created. -+ */ -+static void -+init_layerProperties(struct ivi_layout_LayerProperties *prop, -+ int32_t width, int32_t height) -+{ -+ memset(prop, 0, sizeof *prop); -+ prop->opacity = wl_fixed_from_double(1.0); -+ prop->sourceWidth = width; -+ prop->sourceHeight = height; -+ prop->destWidth = width; -+ prop->destHeight = height; -+} -+ -+static void -+init_surfaceProperties(struct ivi_layout_SurfaceProperties *prop) -+{ -+ memset(prop, 0, sizeof *prop); -+ prop->opacity = wl_fixed_from_double(1.0); -+} -+ -+/** -+ * Internal APIs to be called from ivi_layout_commitChanges. -+ */ -+static void -+update_opacity(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_surface *ivisurf) -+{ -+ double layer_alpha = wl_fixed_to_double(ivilayer->prop.opacity); -+ double surf_alpha = wl_fixed_to_double(ivisurf->prop.opacity); -+ -+ if ((ivilayer->event_mask & IVI_NOTIFICATION_OPACITY) || -+ (ivisurf->event_mask & IVI_NOTIFICATION_OPACITY)) { -+ struct weston_view *tmpview = NULL; -+ wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) -+ { -+ if (tmpview == NULL) { -+ continue; -+ } -+ tmpview->alpha = layer_alpha * surf_alpha; -+ } -+ } -+} -+ -+static void -+update_surface_orientation(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_surface *ivisurf) -+{ -+ struct weston_view *view; -+ struct weston_matrix *matrix = &ivisurf->surface_rotation.matrix; -+ float width = 0.0f; -+ float height = 0.0f; -+ float v_sin = 0.0f; -+ float v_cos = 0.0f; -+ float cx = 0.0f; -+ float cy = 0.0f; -+ float sx = 1.0f; -+ float sy = 1.0f; -+ -+ wl_list_for_each(view, &ivisurf->surface->views, surface_link) -+ { -+ if (view != NULL) { -+ break; -+ } -+ } -+ -+ if (view == NULL) { -+ return; -+ } -+ -+ if ((ivilayer->prop.destWidth == 0) || -+ (ivilayer->prop.destHeight == 0)) { -+ return; -+ } -+ width = (float)ivilayer->prop.destWidth; -+ height = (float)ivilayer->prop.destHeight; -+ -+ switch (ivisurf->prop.orientation) { -+ case IVI_LAYOUT_SURFACE_ORIENTATION_0_DEGREES: -+ v_sin = 0.0f; -+ v_cos = 1.0f; -+ break; -+ case IVI_LAYOUT_SURFACE_ORIENTATION_90_DEGREES: -+ v_sin = 1.0f; -+ v_cos = 0.0f; -+ sx = width / height; -+ sy = height / width; -+ break; -+ case IVI_LAYOUT_SURFACE_ORIENTATION_180_DEGREES: -+ v_sin = 0.0f; -+ v_cos = -1.0f; -+ break; -+ case IVI_LAYOUT_SURFACE_ORIENTATION_270_DEGREES: -+ default: -+ v_sin = -1.0f; -+ v_cos = 0.0f; -+ sx = width / height; -+ sy = height / width; -+ break; -+ } -+ wl_list_remove(&ivisurf->surface_rotation.link); -+ weston_view_geometry_dirty(view); -+ -+ weston_matrix_init(matrix); -+ cx = 0.5f * width; -+ cy = 0.5f * height; -+ weston_matrix_translate(matrix, -cx, -cy, 0.0f); -+ weston_matrix_rotate_xy(matrix, v_cos, v_sin); -+ weston_matrix_scale(matrix, sx, sy, 1.0); -+ weston_matrix_translate(matrix, cx, cy, 0.0f); -+ wl_list_insert(&view->geometry.transformation_list, -+ &ivisurf->surface_rotation.link); -+ -+ weston_view_set_transform_parent(view, NULL); -+ weston_view_update_transform(view); -+} -+ -+static void -+update_layer_orientation(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_surface *ivisurf) -+{ -+ struct weston_surface *es = ivisurf->surface; -+ struct weston_view *view; -+ struct weston_matrix *matrix = &ivisurf->layer_rotation.matrix; -+ struct weston_output *output = NULL; -+ float width = 0.0f; -+ float height = 0.0f; -+ float v_sin = 0.0f; -+ float v_cos = 0.0f; -+ float cx = 0.0f; -+ float cy = 0.0f; -+ float sx = 1.0f; -+ float sy = 1.0f; -+ -+ wl_list_for_each(view, &ivisurf->surface->views, surface_link) -+ { -+ if (view != NULL) { -+ break; -+ } -+ } -+ -+ if (es == NULL || view == NULL) { -+ return; -+ } -+ -+ output = es->output; -+ if (output == NULL) { -+ return; -+ } -+ if ((output->width == 0) || (output->height == 0)) { -+ return; -+ } -+ width = (float)output->width; -+ height = (float)output->height; -+ -+ switch (ivilayer->prop.orientation) { -+ case IVI_LAYOUT_SURFACE_ORIENTATION_0_DEGREES: -+ v_sin = 0.0f; -+ v_cos = 1.0f; -+ break; -+ case IVI_LAYOUT_SURFACE_ORIENTATION_90_DEGREES: -+ v_sin = 1.0f; -+ v_cos = 0.0f; -+ sx = width / height; -+ sy = height / width; -+ break; -+ case IVI_LAYOUT_SURFACE_ORIENTATION_180_DEGREES: -+ v_sin = 0.0f; -+ v_cos = -1.0f; -+ break; -+ case IVI_LAYOUT_SURFACE_ORIENTATION_270_DEGREES: -+ default: -+ v_sin = -1.0f; -+ v_cos = 0.0f; -+ sx = width / height; -+ sy = height / width; -+ break; -+ } -+ wl_list_remove(&ivisurf->layer_rotation.link); -+ weston_view_geometry_dirty(view); -+ -+ weston_matrix_init(matrix); -+ cx = 0.5f * width; -+ cy = 0.5f * height; -+ weston_matrix_translate(matrix, -cx, -cy, 0.0f); -+ weston_matrix_rotate_xy(matrix, v_cos, v_sin); -+ weston_matrix_scale(matrix, sx, sy, 1.0); -+ weston_matrix_translate(matrix, cx, cy, 0.0f); -+ wl_list_insert(&view->geometry.transformation_list, -+ &ivisurf->layer_rotation.link); -+ -+ weston_view_set_transform_parent(view, NULL); -+ weston_view_update_transform(view); -+} -+ -+static void -+update_surface_position(struct ivi_layout_surface *ivisurf) -+{ -+ struct weston_view *view; -+ float tx = (float)ivisurf->prop.destX; -+ float ty = (float)ivisurf->prop.destY; -+ struct weston_matrix *matrix = &ivisurf->surface_pos.matrix; -+ -+ wl_list_for_each(view, &ivisurf->surface->views, surface_link) -+ { -+ if (view != NULL) { -+ break; -+ } -+ } -+ -+ if (view == NULL) { -+ return; -+ } -+ -+ wl_list_remove(&ivisurf->surface_pos.link); -+ -+ weston_matrix_init(matrix); -+ weston_matrix_translate(matrix, tx, ty, 0.0f); -+ wl_list_insert(&view->geometry.transformation_list, -+ &ivisurf->surface_pos.link); -+ -+ weston_view_set_transform_parent(view, NULL); -+ weston_view_update_transform(view); -+ -+#if 0 -+ /* disable zoom animation */ -+ weston_zoom_run(es, 0.0, 1.0, NULL, NULL); -+#endif -+ -+} -+ -+static void -+update_layer_position(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_surface *ivisurf) -+{ -+ struct weston_view *view; -+ struct weston_matrix *matrix = &ivisurf->layer_pos.matrix; -+ float tx = (float)ivilayer->prop.destX; -+ float ty = (float)ivilayer->prop.destY; -+ -+ wl_list_for_each(view, &ivisurf->surface->views, surface_link) -+ { -+ if (view != NULL) { -+ break; -+ } -+ } -+ -+ if (view == NULL) { -+ return; -+ } -+ -+ wl_list_remove(&ivisurf->layer_pos.link); -+ -+ weston_matrix_init(matrix); -+ weston_matrix_translate(matrix, tx, ty, 0.0f); -+ wl_list_insert( -+ &view->geometry.transformation_list, -+ &ivisurf->layer_pos.link); -+ -+ weston_view_set_transform_parent(view, NULL); -+ weston_view_update_transform(view); -+} -+ -+static void -+update_scale(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_surface *ivisurf) -+{ -+ struct weston_view *view; -+ struct weston_matrix *matrix = &ivisurf->scaling.matrix; -+ float sx = 0.0f; -+ float sy = 0.0f; -+ float lw = 0.0f; -+ float sw = 0.0f; -+ float lh = 0.0f; -+ float sh = 0.0f; -+ -+ wl_list_for_each(view, &ivisurf->surface->views, surface_link) -+ { -+ if (view != NULL) { -+ break; -+ } -+ } -+ -+ if (view == NULL) { -+ return; -+ } -+ -+ if (ivisurf->prop.sourceWidth == 0 && ivisurf->prop.sourceHeight == 0) { -+ ivisurf->prop.sourceWidth = ivisurf->surface->width_from_buffer; -+ ivisurf->prop.sourceHeight = ivisurf->surface->height_from_buffer; -+ -+ if (ivisurf->prop.destWidth == 0 && ivisurf->prop.destHeight == 0) { -+ ivisurf->prop.destWidth = ivisurf->surface->width_from_buffer; -+ ivisurf->prop.destHeight = ivisurf->surface->height_from_buffer; -+ } -+ } -+ -+ lw = ((float)ivilayer->prop.destWidth / ivilayer->prop.sourceWidth ); -+ sw = ((float)ivisurf->prop.destWidth / ivisurf->prop.sourceWidth ); -+ lh = ((float)ivilayer->prop.destHeight / ivilayer->prop.sourceHeight); -+ sh = ((float)ivisurf->prop.destHeight / ivisurf->prop.sourceHeight ); -+ sx = sw * lw; -+ sy = sh * lh; -+ -+ wl_list_remove(&ivisurf->scaling.link); -+ weston_matrix_init(matrix); -+ weston_matrix_scale(matrix, sx, sy, 1.0f); -+ -+ wl_list_insert(&view->geometry.transformation_list, -+ &ivisurf->scaling.link); -+ -+ weston_view_set_transform_parent(view, NULL); -+ weston_view_update_transform(view); -+} -+ -+static void -+update_prop(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_surface *ivisurf) -+{ -+ if (ivilayer->event_mask | ivisurf->event_mask) { -+ update_opacity(ivilayer, ivisurf); -+ update_layer_orientation(ivilayer, ivisurf); -+ update_layer_position(ivilayer, ivisurf); -+ update_surface_position(ivisurf); -+ update_surface_orientation(ivilayer, ivisurf); -+ update_scale(ivilayer, ivisurf); -+ -+ ivisurf->update_count++; -+ -+ struct weston_view *tmpview; -+ wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) -+ { -+ if (tmpview != NULL) { -+ break; -+ } -+ } -+ -+ if (tmpview != NULL) { -+ weston_view_geometry_dirty(tmpview); -+ } -+ -+ if (ivisurf->surface != NULL) { -+ weston_surface_damage(ivisurf->surface); -+ } -+ } -+} -+ -+static void -+commit_changes(struct ivi_layout *layout) -+{ -+ struct ivi_layout_screen *iviscrn = NULL; -+ struct ivi_layout_layer *ivilayer = NULL; -+ struct ivi_layout_surface *ivisurf = NULL; -+ -+ wl_list_for_each(iviscrn, &layout->list_screen, link) { -+ wl_list_for_each(ivilayer, &iviscrn->order.list_layer, order.link) { -+ wl_list_for_each(ivisurf, &ivilayer->order.list_surface, order.link) { -+ update_prop(ivilayer, ivisurf); -+ } -+ } -+ } -+} -+ -+static void -+commit_list_surface(struct ivi_layout *layout) -+{ -+ struct ivi_layout_surface *ivisurf = NULL; -+ -+ wl_list_for_each(ivisurf, &layout->list_surface, link) { -+ ivisurf->prop = ivisurf->pending.prop; -+ } -+} -+ -+static void -+commit_list_layer(struct ivi_layout *layout) -+{ -+ struct ivi_layout_layer *ivilayer = NULL; -+ struct ivi_layout_surface *ivisurf = NULL; -+ struct ivi_layout_surface *next = NULL; -+ -+ wl_list_for_each(ivilayer, &layout->list_layer, link) { -+ ivilayer->prop = ivilayer->pending.prop; -+ -+ if (!(ivilayer->event_mask & -+ (IVI_NOTIFICATION_ADD | IVI_NOTIFICATION_REMOVE)) ) { -+ continue; -+ } -+ -+ if (ivilayer->event_mask & IVI_NOTIFICATION_REMOVE) { -+ wl_list_for_each_safe(ivisurf, next, -+ &ivilayer->order.list_surface, order.link) { -+ remove_ordersurface_from_layer(ivisurf); -+ -+ if (!wl_list_empty(&ivisurf->order.link)) { -+ wl_list_remove(&ivisurf->order.link); -+ } -+ -+ wl_list_init(&ivisurf->order.link); -+ ivisurf->event_mask |= IVI_NOTIFICATION_REMOVE; -+ } -+ -+ wl_list_init(&ivilayer->order.list_surface); -+ } -+ -+ if (ivilayer->event_mask & IVI_NOTIFICATION_ADD) { -+ wl_list_for_each_safe(ivisurf, next, -+ &ivilayer->order.list_surface, order.link) { -+ remove_ordersurface_from_layer(ivisurf); -+ -+ if (!wl_list_empty(&ivisurf->order.link)) { -+ wl_list_remove(&ivisurf->order.link); -+ } -+ -+ wl_list_init(&ivisurf->order.link); -+ } -+ -+ wl_list_init(&ivilayer->order.list_surface); -+ wl_list_for_each(ivisurf, &ivilayer->pending.list_surface, -+ pending.link) { -+ if(!wl_list_empty(&ivisurf->order.link)){ -+ wl_list_remove(&ivisurf->order.link); -+ wl_list_init(&ivisurf->order.link); -+ } -+ -+ wl_list_insert(&ivilayer->order.list_surface, -+ &ivisurf->order.link); -+ add_ordersurface_to_layer(ivisurf, ivilayer); -+ ivisurf->event_mask |= IVI_NOTIFICATION_ADD; -+ } -+ } -+ } -+} -+ -+static void -+commit_list_screen(struct ivi_layout *layout) -+{ -+ struct ivi_layout_screen *iviscrn = NULL; -+ struct ivi_layout_layer *ivilayer = NULL; -+ struct ivi_layout_layer *next = NULL; -+ struct ivi_layout_surface *ivisurf = NULL; -+ -+ wl_list_for_each(iviscrn, &layout->list_screen, link) { -+ if (iviscrn->event_mask & IVI_NOTIFICATION_REMOVE) { -+ wl_list_for_each_safe(ivilayer, next, -+ &iviscrn->order.list_layer, order.link) { -+ remove_orderlayer_from_screen(ivilayer); -+ -+ if (!wl_list_empty(&ivilayer->order.link)) { -+ wl_list_remove(&ivilayer->order.link); -+ } -+ -+ wl_list_init(&ivilayer->order.link); -+ ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE; -+ } -+ } -+ -+ if (iviscrn->event_mask & IVI_NOTIFICATION_ADD) { -+ wl_list_for_each_safe(ivilayer, next, -+ &iviscrn->order.list_layer, order.link) { -+ remove_orderlayer_from_screen(ivilayer); -+ -+ if (!wl_list_empty(&ivilayer->order.link)) { -+ wl_list_remove(&ivilayer->order.link); -+ } -+ -+ wl_list_init(&ivilayer->order.link); -+ } -+ -+ wl_list_init(&iviscrn->order.list_layer); -+ wl_list_for_each(ivilayer, &iviscrn->pending.list_layer, -+ pending.link) { -+ wl_list_insert(&iviscrn->order.list_layer, -+ &ivilayer->order.link); -+ add_orderlayer_to_screen(ivilayer, iviscrn); -+ ivilayer->event_mask |= IVI_NOTIFICATION_ADD; -+ } -+ } -+ -+ iviscrn->event_mask = 0; -+ -+ /* Clear view list of layout layer */ -+ wl_list_init(&layout->layout_layer.view_list); -+ -+ wl_list_for_each(ivilayer, &iviscrn->order.list_layer, order.link) { -+ -+ if (ivilayer->prop.visibility == 0) -+ continue; -+ -+ wl_list_for_each(ivisurf, &ivilayer->order.list_surface, order.link) { -+ struct weston_view *tmpview = NULL; -+ wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) -+ { -+ if (tmpview != NULL) { -+ break; -+ } -+ } -+ -+ if (ivisurf->prop.visibility == 0) -+ continue; -+ if (ivisurf->surface == NULL || tmpview == NULL) -+ continue; -+ -+ wl_list_insert(&layout->layout_layer.view_list, -+ &tmpview->layer_link); -+ -+ ivisurf->surface->output = iviscrn->output; -+ } -+ } -+ -+ break; -+ } -+} -+ -+static void -+send_surface_prop(struct ivi_layout_surface *ivisurf) -+{ -+ wl_signal_emit(&ivisurf->property_changed, ivisurf); -+ ivisurf->event_mask = 0; -+} -+ -+static void -+send_layer_prop(struct ivi_layout_layer *ivilayer) -+{ -+ wl_signal_emit(&ivilayer->property_changed, ivilayer); -+ ivilayer->event_mask = 0; -+} -+ -+static void -+send_prop(struct ivi_layout *layout) -+{ -+ struct ivi_layout_layer *ivilayer = NULL; -+ struct ivi_layout_surface *ivisurf = NULL; -+ -+ wl_list_for_each_reverse(ivilayer, &layout->list_layer, link) { -+ send_layer_prop(ivilayer); -+ } -+ -+ wl_list_for_each_reverse(ivisurf, &layout->list_surface, link) { -+ send_surface_prop(ivisurf); -+ } -+} -+ -+static void -+clear_surface_pending_list(struct ivi_layout_layer *ivilayer) -+{ -+ struct ivi_layout_surface *surface_link = NULL; -+ struct ivi_layout_surface *surface_next = NULL; -+ -+ wl_list_for_each_safe(surface_link, surface_next, -+ &ivilayer->pending.list_surface, pending.link) { -+ if (!wl_list_empty(&surface_link->pending.link)) { -+ wl_list_remove(&surface_link->pending.link); -+ } -+ -+ wl_list_init(&surface_link->pending.link); -+ } -+ -+ ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE; -+} -+ -+static void -+clear_surface_order_list(struct ivi_layout_layer *ivilayer) -+{ -+ struct ivi_layout_surface *surface_link = NULL; -+ struct ivi_layout_surface *surface_next = NULL; -+ -+ wl_list_for_each_safe(surface_link, surface_next, -+ &ivilayer->order.list_surface, order.link) { -+ if (!wl_list_empty(&surface_link->order.link)) { -+ wl_list_remove(&surface_link->order.link); -+ } -+ -+ wl_list_init(&surface_link->order.link); -+ } -+ -+ ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE; -+} -+ -+static void -+layer_created(struct wl_listener *listener, void *data) -+{ -+ struct ivi_layout_layer *ivilayer = (struct ivi_layout_layer *)data; -+ -+ struct listener_layoutNotification *notification = -+ container_of(listener, -+ struct listener_layoutNotification, -+ listener); -+ -+ struct ivi_layout_notificationCallback *created_callback = -+ (struct ivi_layout_notificationCallback *)notification->userdata; -+ -+ ((layerCreateNotificationFunc)created_callback->callback) -+ (ivilayer, created_callback->data); -+} -+ -+static void -+layer_removed(struct wl_listener *listener, void *data) -+{ -+ struct ivi_layout_layer *ivilayer = (struct ivi_layout_layer *)data; -+ -+ struct listener_layoutNotification *notification = -+ container_of(listener, -+ struct listener_layoutNotification, -+ listener); -+ -+ struct ivi_layout_notificationCallback *removed_callback = -+ (struct ivi_layout_notificationCallback *)notification->userdata; -+ -+ ((layerRemoveNotificationFunc)removed_callback->callback) -+ (ivilayer, removed_callback->data); -+} -+ -+static void -+layer_prop_changed(struct wl_listener *listener, void *data) -+{ -+ struct ivi_layout_layer *ivilayer = (struct ivi_layout_layer *)data; -+ -+ struct listener_layoutNotification *layout_listener = -+ container_of(listener, -+ struct listener_layoutNotification, -+ listener); -+ -+ struct ivi_layout_notificationCallback *prop_callback = -+ (struct ivi_layout_notificationCallback *)layout_listener->userdata; -+ -+ ((layerPropertyNotificationFunc)prop_callback->callback) -+ (ivilayer, &ivilayer->prop, ivilayer->event_mask, prop_callback->data); -+} -+ -+static void -+surface_created(struct wl_listener *listener, void *data) -+{ -+ struct ivi_layout_surface *ivisurface = (struct ivi_layout_surface *)data; -+ -+ struct listener_layoutNotification *notification = -+ container_of(listener, -+ struct listener_layoutNotification, -+ listener); -+ -+ struct ivi_layout_notificationCallback *created_callback = -+ (struct ivi_layout_notificationCallback *)notification->userdata; -+ -+ ((surfaceCreateNotificationFunc)created_callback->callback) -+ (ivisurface, created_callback->data); -+} -+ -+static void -+surface_removed(struct wl_listener *listener, void *data) -+{ -+ struct ivi_layout_surface *ivisurface = (struct ivi_layout_surface *)data; -+ -+ struct listener_layoutNotification *notification = -+ container_of(listener, -+ struct listener_layoutNotification, -+ listener); -+ -+ struct ivi_layout_notificationCallback *removed_callback = -+ (struct ivi_layout_notificationCallback *)notification->userdata; -+ -+ ((surfaceRemoveNotificationFunc)removed_callback->callback) -+ (ivisurface, removed_callback->data); -+} -+ -+static void -+surface_prop_changed(struct wl_listener *listener, void *data) -+{ -+ struct ivi_layout_surface *ivisurf = (struct ivi_layout_surface *)data; -+ -+ struct listener_layoutNotification *layout_listener = -+ container_of(listener, -+ struct listener_layoutNotification, -+ listener); -+ -+ struct ivi_layout_notificationCallback *prop_callback = -+ (struct ivi_layout_notificationCallback *)layout_listener->userdata; -+ -+ ((surfacePropertyNotificationFunc)prop_callback->callback) -+ (ivisurf, &ivisurf->prop, ivisurf->event_mask, prop_callback->data); -+ -+ ivisurf->event_mask = 0; -+} -+ -+static void -+surface_configure_changed(struct wl_listener *listener, -+ void *data) -+{ -+ struct ivi_layout_surface *ivisurface = (struct ivi_layout_surface *)data; -+ -+ struct listener_layoutNotification *notification = -+ container_of(listener, -+ struct listener_layoutNotification, -+ listener); -+ -+ struct ivi_layout_notificationCallback *configure_changed_callback = -+ (struct ivi_layout_notificationCallback *)notification->userdata; -+ -+ ((surfaceConfigureNotificationFunc)configure_changed_callback->callback) -+ (ivisurface, configure_changed_callback->data); -+} -+ -+static void -+warning_occurred(struct wl_listener *listener, void *data) -+{ -+ struct shellWarningArgs *args = (struct shellWarningArgs *)data; -+ -+ struct listener_layoutNotification *layout_listener = -+ container_of(listener, -+ struct listener_layoutNotification, -+ listener); -+ -+ struct ivi_layout_notificationCallback *callback = -+ (struct ivi_layout_notificationCallback *)layout_listener->userdata; -+ -+ ((shellWarningNotificationFunc)callback->callback) -+ (args->id_surface, args->flag, callback->data); -+} -+ -+static int32_t -+add_notification(struct wl_signal *signal, -+ wl_notify_func_t callback, -+ void *userdata) -+{ -+ struct listener_layoutNotification *notification = NULL; -+ -+ notification = malloc(sizeof *notification); -+ if (notification == NULL) { -+ weston_log("fails to allocate memory\n"); -+ free(userdata); -+ return -1; -+ } -+ -+ notification->listener.notify = callback; -+ notification->userdata = userdata; -+ -+ wl_signal_add(signal, ¬ification->listener); -+ -+ return 0; -+} -+ -+static void -+remove_notification(struct wl_list *listener_list, void *callback, void *userdata) -+{ -+ struct wl_listener *listener = NULL; -+ struct wl_listener *next = NULL; -+ -+ wl_list_for_each_safe(listener, next, listener_list, link) { -+ struct listener_layoutNotification *notification = -+ container_of(listener, -+ struct listener_layoutNotification, -+ listener); -+ -+ struct ivi_layout_notificationCallback *notification_callback = -+ (struct ivi_layout_notificationCallback *)notification->userdata; -+ -+ if ((notification_callback->callback != callback) || -+ (notification_callback->data != userdata)) { -+ continue; -+ } -+ -+ if (!wl_list_empty(&listener->link)) { -+ wl_list_remove(&listener->link); -+ } -+ -+ free(notification->userdata); -+ free(notification); -+ } -+} -+ -+static void -+remove_all_notification(struct wl_list *listener_list) -+{ -+ struct wl_listener *listener = NULL; -+ struct wl_listener *next = NULL; -+ -+ wl_list_for_each_safe(listener, next, listener_list, link) { -+ if (!wl_list_empty(&listener->link)) { -+ wl_list_remove(&listener->link); -+ } -+ -+ struct listener_layoutNotification *notification = -+ container_of(listener, -+ struct listener_layoutNotification, -+ listener); -+ -+ free(notification->userdata); -+ free(notification); -+ } -+} -+ -+/** -+ * Exported APIs of ivi-layout library are implemented from here. -+ * Brief of APIs is described in ivi-layout-export.h. -+ */ -+WL_EXPORT int32_t -+ivi_layout_addNotificationCreateLayer(layerCreateNotificationFunc callback, -+ void *userdata) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_notificationCallback *created_callback = NULL; -+ -+ if (callback == NULL) { -+ weston_log("ivi_layout_addNotificationCreateLayer: invalid argument\n"); -+ return -1; -+ } -+ -+ created_callback = malloc(sizeof *created_callback); -+ if (created_callback == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ created_callback->callback = callback; -+ created_callback->data = userdata; -+ -+ return add_notification(&layout->layer_notification.created, -+ layer_created, -+ created_callback); -+} -+ -+WL_EXPORT void -+ivi_layout_removeNotificationCreateLayer(layerCreateNotificationFunc callback, -+ void *userdata) -+{ -+ struct ivi_layout *layout = get_instance(); -+ remove_notification(&layout->layer_notification.created.listener_list, callback, userdata); -+} -+ -+WL_EXPORT int32_t -+ivi_layout_addNotificationRemoveLayer(layerRemoveNotificationFunc callback, -+ void *userdata) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_notificationCallback *removed_callback = NULL; -+ -+ if (callback == NULL) { -+ weston_log("ivi_layout_addNotificationRemoveLayer: invalid argument\n"); -+ return -1; -+ } -+ -+ removed_callback = malloc(sizeof *removed_callback); -+ if (removed_callback == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ removed_callback->callback = callback; -+ removed_callback->data = userdata; -+ add_notification(&layout->layer_notification.removed, -+ layer_removed, -+ removed_callback); -+ -+ return 0; -+} -+ -+WL_EXPORT void -+ivi_layout_removeNotificationRemoveLayer(layerRemoveNotificationFunc callback, -+ void *userdata) -+{ -+ struct ivi_layout *layout = get_instance(); -+ remove_notification(&layout->layer_notification.removed.listener_list, callback, userdata); -+} -+ -+WL_EXPORT int32_t -+ivi_layout_addNotificationCreateSurface(surfaceCreateNotificationFunc callback, -+ void *userdata) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_notificationCallback *created_callback = NULL; -+ -+ if (callback == NULL) { -+ weston_log("ivi_layout_addNotificationCreateSurface: invalid argument\n"); -+ return -1; -+ } -+ -+ created_callback = malloc(sizeof *created_callback); -+ if (created_callback == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ created_callback->callback = callback; -+ created_callback->data = userdata; -+ -+ add_notification(&layout->surface_notification.created, -+ surface_created, -+ created_callback); -+ return 0; -+} -+ -+WL_EXPORT void -+ivi_layout_removeNotificationCreateSurface(surfaceCreateNotificationFunc callback, -+ void *userdata) -+{ -+ struct ivi_layout *layout = get_instance(); -+ remove_notification(&layout->surface_notification.created.listener_list, callback, userdata); -+} -+ -+WL_EXPORT int32_t -+ivi_layout_addNotificationRemoveSurface(surfaceRemoveNotificationFunc callback, -+ void *userdata) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_notificationCallback *removed_callback = NULL; -+ -+ if (callback == NULL) { -+ weston_log("ivi_layout_addNotificationRemoveSurface: invalid argument\n"); -+ return -1; -+ } -+ -+ removed_callback = malloc(sizeof *removed_callback); -+ if (removed_callback == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ removed_callback->callback = callback; -+ removed_callback->data = userdata; -+ -+ add_notification(&layout->surface_notification.removed, -+ surface_removed, -+ removed_callback); -+ -+ return 0; -+} -+ -+WL_EXPORT void -+ivi_layout_removeNotificationRemoveSurface(surfaceRemoveNotificationFunc callback, -+ void *userdata) -+{ -+ struct ivi_layout *layout = get_instance(); -+ remove_notification(&layout->surface_notification.removed.listener_list, callback, userdata); -+} -+ -+WL_EXPORT int32_t -+ivi_layout_addNotificationConfigureSurface(surfaceConfigureNotificationFunc callback, -+ void *userdata) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_notificationCallback *configure_changed_callback = NULL; -+ if (callback == NULL) { -+ weston_log("ivi_layout_addNotificationConfigureSurface: invalid argument\n"); -+ return -1; -+ } -+ -+ configure_changed_callback = malloc(sizeof *configure_changed_callback); -+ if (configure_changed_callback == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ configure_changed_callback->callback = callback; -+ configure_changed_callback->data = userdata; -+ -+ add_notification(&layout->surface_notification.configure_changed, -+ surface_configure_changed, -+ configure_changed_callback); -+ return 0; -+} -+ -+WL_EXPORT void -+ivi_layout_removeNotificationConfigureSurface(surfaceConfigureNotificationFunc callback, -+ void *userdata) -+{ -+ struct ivi_layout *layout = get_instance(); -+ remove_notification(&layout->surface_notification.configure_changed.listener_list, callback, userdata); -+} -+ -+WL_EXPORT int32_t -+ivi_layout_addNotificationShellWarning(shellWarningNotificationFunc callback, -+ void *userdata) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_notificationCallback *warn_callback = NULL; -+ -+ if (callback == NULL) { -+ weston_log("ivi_layout_addNotificationShellWarning: invalid argument\n"); -+ return -1; -+ } -+ -+ warn_callback = malloc(sizeof *warn_callback); -+ if (warn_callback == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ warn_callback->callback = callback; -+ warn_callback->data = userdata; -+ -+ return add_notification(&layout->warning_signal, -+ warning_occurred, -+ warn_callback); -+} -+ -+WL_EXPORT void -+ivi_layout_removeNotificationShellWarning(shellWarningNotificationFunc callback, -+ void *userdata) -+{ -+ struct ivi_layout *layout = get_instance(); -+ remove_notification(&layout->warning_signal.listener_list, callback, userdata); -+} -+ -+WL_EXPORT uint32_t -+ivi_layout_getIdOfSurface(struct ivi_layout_surface *ivisurf) -+{ -+ return ivisurf->id_surface; -+} -+ -+WL_EXPORT uint32_t -+ivi_layout_getIdOfLayer(struct ivi_layout_layer *ivilayer) -+{ -+ return ivilayer->id_layer; -+} -+ -+WL_EXPORT struct ivi_layout_layer * -+ivi_layout_getLayerFromId(uint32_t id_layer) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_layer *ivilayer = NULL; -+ -+ wl_list_for_each(ivilayer, &layout->list_layer, link) { -+ if (ivilayer->id_layer == id_layer) { -+ return ivilayer; -+ } -+ } -+ -+ return NULL; -+} -+ -+WL_EXPORT struct ivi_layout_surface * -+ivi_layout_getSurfaceFromId(uint32_t id_surface) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_surface *ivisurf = NULL; -+ -+ wl_list_for_each(ivisurf, &layout->list_surface, link) { -+ if (ivisurf->id_surface == id_surface) { -+ return ivisurf; -+ } -+ } -+ -+ return NULL; -+} -+ -+WL_EXPORT struct ivi_layout_screen * -+ivi_layout_getScreenFromId(uint32_t id_screen) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_screen *iviscrn = NULL; -+ (void)id_screen; -+ -+ wl_list_for_each(iviscrn, &layout->list_screen, link) { -+//FIXME : select iviscrn from list_screen by id_screen -+ return iviscrn; -+ break; -+ } -+ -+ return NULL; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_getScreenResolution(struct ivi_layout_screen *iviscrn, -+ int32_t *pWidth, int32_t *pHeight) -+{ -+ struct weston_output *output = NULL; -+ -+ if (pWidth == NULL || pHeight == NULL) { -+ weston_log("ivi_layout_getScreenResolution: invalid argument\n"); -+ return -1; -+ } -+ -+ output = iviscrn->output; -+ *pWidth = output->current_mode->width; -+ *pHeight = output->current_mode->height; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceAddNotification(struct ivi_layout_surface *ivisurf, -+ surfacePropertyNotificationFunc callback, -+ void *userdata) -+{ -+ struct listener_layoutNotification* notification = NULL; -+ struct ivi_layout_notificationCallback *prop_callback = NULL; -+ -+ if (ivisurf == NULL || callback == NULL) { -+ weston_log("ivi_layout_surfaceAddNotification: invalid argument\n"); -+ return -1; -+ } -+ -+ notification = malloc(sizeof *notification); -+ if (notification == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ prop_callback = malloc(sizeof *prop_callback); -+ if (prop_callback == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ prop_callback->callback = callback; -+ prop_callback->data = userdata; -+ -+ notification->listener.notify = surface_prop_changed; -+ notification->userdata = prop_callback; -+ -+ wl_signal_add(&ivisurf->property_changed, ¬ification->listener); -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceRemoveNotification(struct ivi_layout_surface *ivisurf) -+{ -+ if (ivisurf == NULL) { -+ weston_log("ivi_layout_surfaceRemoveNotification: invalid argument\n"); -+ return -1; -+ } -+ -+ remove_all_notification(&ivisurf->property_changed.listener_list); -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceRemove(struct ivi_layout_surface *ivisurf) -+{ -+ struct ivi_layout *layout = get_instance(); -+ -+ if (ivisurf == NULL) { -+ weston_log("ivi_layout_surfaceRemove: invalid argument\n"); -+ return -1; -+ } -+ -+ if (!wl_list_empty(&ivisurf->pending.link)) { -+ wl_list_remove(&ivisurf->pending.link); -+ } -+ if (!wl_list_empty(&ivisurf->order.link)) { -+ wl_list_remove(&ivisurf->order.link); -+ } -+ if (!wl_list_empty(&ivisurf->link)) { -+ wl_list_remove(&ivisurf->link); -+ } -+ remove_ordersurface_from_layer(ivisurf); -+ -+ wl_signal_emit(&layout->surface_notification.removed, ivisurf); -+ -+ ivi_layout_surfaceRemoveNotification(ivisurf); -+ -+ free(ivisurf); -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_UpdateInputEventAcceptanceOn(struct ivi_layout_surface *ivisurf, -+ int32_t devices, int32_t acceptance) -+{ -+ /* TODO */ -+ (void)ivisurf; -+ (void)devices; -+ (void)acceptance; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceInitialize(struct ivi_layout_surface **pSurfaceId) -+{ -+ /* TODO */ -+ (void)pSurfaceId; -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_getPropertiesOfLayer(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_LayerProperties *pLayerProperties) -+{ -+ if (ivilayer == NULL || pLayerProperties == NULL) { -+ weston_log("ivi_layout_getPropertiesOfLayer: invalid argument\n"); -+ return -1; -+ } -+ -+ *pLayerProperties = ivilayer->prop; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_getNumberOfHardwareLayers(uint32_t id_screen, -+ int32_t *pNumberOfHardwareLayers) -+{ -+ /* TODO */ -+ (void)id_screen; -+ (void)pNumberOfHardwareLayers; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_getScreens(int32_t *pLength, struct ivi_layout_screen ***ppArray) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_screen *iviscrn = NULL; -+ int32_t length = 0; -+ int32_t n = 0; -+ -+ if (pLength == NULL || ppArray == NULL) { -+ weston_log("ivi_layout_getScreens: invalid argument\n"); -+ return -1; -+ } -+ -+ length = wl_list_length(&layout->list_screen); -+ -+ if (length != 0){ -+ /* the Array must be free by module which called this function */ -+ *ppArray = calloc(length, sizeof(struct ivi_layout_screen *)); -+ if (*ppArray == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ wl_list_for_each(iviscrn, &layout->list_screen, link) { -+ (*ppArray)[n++] = iviscrn; -+ } -+ } -+ -+ *pLength = length; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_getScreensUnderLayer(struct ivi_layout_layer *ivilayer, -+ int32_t *pLength, -+ struct ivi_layout_screen ***ppArray) -+{ -+ struct link_screen *link_scrn = NULL; -+ int32_t length = 0; -+ int32_t n = 0; -+ -+ if (ivilayer == NULL || pLength == NULL || ppArray == NULL) { -+ weston_log("ivi_layout_getScreensUnderLayer: invalid argument\n"); -+ return -1; -+ } -+ -+ length = wl_list_length(&ivilayer->list_screen); -+ -+ if (length != 0){ -+ /* the Array must be free by module which called this function */ -+ *ppArray = calloc(length, sizeof(struct ivi_layout_screen *)); -+ if (*ppArray == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ wl_list_for_each(link_scrn, &ivilayer->list_screen, link) { -+ (*ppArray)[n++] = link_scrn->iviscrn; -+ } -+ } -+ -+ *pLength = length; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_getLayers(int32_t *pLength, struct ivi_layout_layer ***ppArray) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_layer *ivilayer = NULL; -+ int32_t length = 0; -+ int32_t n = 0; -+ -+ if (pLength == NULL || ppArray == NULL) { -+ weston_log("ivi_layout_getLayers: invalid argument\n"); -+ return -1; -+ } -+ -+ length = wl_list_length(&layout->list_layer); -+ -+ if (length != 0){ -+ /* the Array must be free by module which called this function */ -+ *ppArray = calloc(length, sizeof(struct ivi_layout_layer *)); -+ if (*ppArray == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ wl_list_for_each(ivilayer, &layout->list_layer, link) { -+ (*ppArray)[n++] = ivilayer; -+ } -+ } -+ -+ *pLength = length; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_getLayersOnScreen(struct ivi_layout_screen *iviscrn, -+ int32_t *pLength, -+ struct ivi_layout_layer ***ppArray) -+{ -+ struct ivi_layout_layer *ivilayer = NULL; -+ int32_t length = 0; -+ int32_t n = 0; -+ -+ if (iviscrn == NULL || pLength == NULL || ppArray == NULL) { -+ weston_log("ivi_layout_getLayersOnScreen: invalid argument\n"); -+ return -1; -+ } -+ -+ length = wl_list_length(&iviscrn->order.list_layer); -+ -+ if (length != 0){ -+ /* the Array must be free by module which called this function */ -+ *ppArray = calloc(length, sizeof(struct ivi_layout_layer *)); -+ if (*ppArray == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ wl_list_for_each(ivilayer, &iviscrn->order.list_layer, link) { -+ (*ppArray)[n++] = ivilayer; -+ } -+ } -+ -+ *pLength = length; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_getLayersUnderSurface(struct ivi_layout_surface *ivisurf, -+ int32_t *pLength, -+ struct ivi_layout_layer ***ppArray) -+{ -+ struct link_layer *link_layer = NULL; -+ int32_t length = 0; -+ int32_t n = 0; -+ -+ if (ivisurf == NULL || pLength == NULL || ppArray == NULL) { -+ weston_log("ivi_layout_getLayers: invalid argument\n"); -+ return -1; -+ } -+ -+ length = wl_list_length(&ivisurf->list_layer); -+ -+ if (length != 0){ -+ /* the Array must be free by module which called this function */ -+ *ppArray = calloc(length, sizeof(struct ivi_layout_layer *)); -+ if (*ppArray == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ wl_list_for_each(link_layer, &ivisurf->list_layer, link) { -+ (*ppArray)[n++] = link_layer->ivilayer; -+ } -+ } -+ -+ *pLength = length; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_getSurfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_surface *ivisurf = NULL; -+ int32_t length = 0; -+ int32_t n = 0; -+ -+ if (pLength == NULL || ppArray == NULL) { -+ weston_log("ivi_layout_getSurfaces: invalid argument\n"); -+ return -1; -+ } -+ -+ length = wl_list_length(&layout->list_surface); -+ -+ if (length != 0){ -+ /* the Array must be free by module which called this function */ -+ *ppArray = calloc(length, sizeof(struct ivi_layout_surface *)); -+ if (*ppArray == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ wl_list_for_each(ivisurf, &layout->list_surface, link) { -+ (*ppArray)[n++] = ivisurf; -+ } -+ } -+ -+ *pLength = length; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_getSurfacesOnLayer(struct ivi_layout_layer *ivilayer, -+ int32_t *pLength, -+ struct ivi_layout_surface ***ppArray) -+{ -+ struct ivi_layout_surface *ivisurf = NULL; -+ int32_t length = 0; -+ int32_t n = 0; -+ -+ if (ivilayer == NULL || pLength == NULL || ppArray == NULL) { -+ weston_log("ivi_layout_getSurfaceIDsOnLayer: invalid argument\n"); -+ return -1; -+ } -+ -+ length = wl_list_length(&ivilayer->order.list_surface); -+ -+ if (length != 0) { -+ /* the Array must be free by module which called this function */ -+ *ppArray = calloc(length, sizeof(struct ivi_layout_surface *)); -+ if (*ppArray == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ wl_list_for_each(ivisurf, &ivilayer->order.list_surface, order.link) { -+ (*ppArray)[n++] = ivisurf; -+ } -+ } -+ -+ *pLength = length; -+ -+ return 0; -+} -+ -+WL_EXPORT struct ivi_layout_layer * -+ivi_layout_layerCreateWithDimension(uint32_t id_layer, -+ int32_t width, int32_t height) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_layer *ivilayer = NULL; -+ -+ ivilayer = get_layer(&layout->list_layer, id_layer); -+ if (ivilayer != NULL) { -+ weston_log("id_layer is already created\n"); -+ return ivilayer; -+ } -+ -+ ivilayer = calloc(1, sizeof *ivilayer); -+ if (ivilayer == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return NULL; -+ } -+ -+ wl_list_init(&ivilayer->link); -+ wl_signal_init(&ivilayer->property_changed); -+ wl_list_init(&ivilayer->list_screen); -+ wl_list_init(&ivilayer->link_to_surface); -+ ivilayer->layout = layout; -+ ivilayer->id_layer = id_layer; -+ -+ init_layerProperties(&ivilayer->prop, width, height); -+ ivilayer->event_mask = 0; -+ -+ wl_list_init(&ivilayer->pending.list_surface); -+ wl_list_init(&ivilayer->pending.link); -+ ivilayer->pending.prop = ivilayer->prop; -+ -+ wl_list_init(&ivilayer->order.list_surface); -+ wl_list_init(&ivilayer->order.link); -+ -+ wl_list_insert(&layout->list_layer, &ivilayer->link); -+ -+ wl_signal_emit(&layout->layer_notification.created, ivilayer); -+ -+ return ivilayer; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerRemove(struct ivi_layout_layer *ivilayer) -+{ -+ struct ivi_layout *layout = get_instance(); -+ -+ if (ivilayer == NULL) { -+ weston_log("ivi_layout_layerRemove: invalid argument\n"); -+ return -1; -+ } -+ -+ wl_signal_emit(&layout->layer_notification.removed, ivilayer); -+ -+ clear_surface_pending_list(ivilayer); -+ clear_surface_order_list(ivilayer); -+ -+ if (!wl_list_empty(&ivilayer->pending.link)) { -+ wl_list_remove(&ivilayer->pending.link); -+ } -+ if (!wl_list_empty(&ivilayer->order.link)) { -+ wl_list_remove(&ivilayer->order.link); -+ } -+ if (!wl_list_empty(&ivilayer->link)) { -+ wl_list_remove(&ivilayer->link); -+ } -+ remove_orderlayer_from_screen(ivilayer); -+ remove_link_to_surface(ivilayer); -+ ivi_layout_layerRemoveNotification(ivilayer); -+ -+ free(ivilayer); -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerGetType(struct ivi_layout_layer *ivilayer, -+ int32_t *pLayerType) -+{ -+ /* TODO */ -+ (void)ivilayer; -+ (void)pLayerType; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerSetVisibility(struct ivi_layout_layer *ivilayer, -+ int32_t newVisibility) -+{ -+ struct ivi_layout_LayerProperties *prop = NULL; -+ -+ if (ivilayer == NULL) { -+ weston_log("ivi_layout_layerSetVisibility: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivilayer->pending.prop; -+ prop->visibility = newVisibility; -+ -+ ivilayer->event_mask |= IVI_NOTIFICATION_VISIBILITY; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerGetVisibility(struct ivi_layout_layer *ivilayer, int32_t *pVisibility) -+{ -+ if (ivilayer == NULL || pVisibility == NULL) { -+ weston_log("ivi_layout_layerGetVisibility: invalid argument\n"); -+ return -1; -+ } -+ -+ *pVisibility = ivilayer->prop.visibility; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerSetOpacity(struct ivi_layout_layer *ivilayer, -+ float opacity) -+{ -+ struct ivi_layout_LayerProperties *prop = NULL; -+ -+ if (ivilayer == NULL) { -+ weston_log("ivi_layout_layerSetOpacity: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivilayer->pending.prop; -+ prop->opacity = opacity; -+ -+ ivilayer->event_mask |= IVI_NOTIFICATION_OPACITY; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerGetOpacity(struct ivi_layout_layer *ivilayer, -+ float *pOpacity) -+{ -+ if (ivilayer == NULL || pOpacity == NULL) { -+ weston_log("ivi_layout_layerGetOpacity: invalid argument\n"); -+ return -1; -+ } -+ -+ *pOpacity = ivilayer->prop.opacity; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerSetSourceRectangle(struct ivi_layout_layer *ivilayer, -+ int32_t x, int32_t y, -+ int32_t width, int32_t height) -+{ -+ struct ivi_layout_LayerProperties *prop = NULL; -+ -+ if (ivilayer == NULL) { -+ weston_log("ivi_layout_layerSetSourceRectangle: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivilayer->pending.prop; -+ prop->sourceX = x; -+ prop->sourceY = y; -+ prop->sourceWidth = width; -+ prop->sourceHeight = height; -+ -+ ivilayer->event_mask |= IVI_NOTIFICATION_SOURCE_RECT; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerSetDestinationRectangle(struct ivi_layout_layer *ivilayer, -+ int32_t x, int32_t y, -+ int32_t width, int32_t height) -+{ -+ struct ivi_layout_LayerProperties *prop = NULL; -+ -+ if (ivilayer == NULL) { -+ weston_log("ivi_layout_layerSetDestinationRectangle: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivilayer->pending.prop; -+ prop->destX = x; -+ prop->destY = y; -+ prop->destWidth = width; -+ prop->destHeight = height; -+ -+ ivilayer->event_mask |= IVI_NOTIFICATION_DEST_RECT; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerGetDimension(struct ivi_layout_layer *ivilayer, -+ int32_t *pDimension) -+{ -+ if (ivilayer == NULL || &pDimension[0] == NULL || &pDimension[1] == NULL) { -+ weston_log("ivi_layout_layerGetDimension: invalid argument\n"); -+ return -1; -+ } -+ -+ pDimension[0] = ivilayer->prop.destX; -+ pDimension[1] = ivilayer->prop.destY; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerSetDimension(struct ivi_layout_layer *ivilayer, -+ int32_t *pDimension) -+{ -+ struct ivi_layout_LayerProperties *prop = NULL; -+ -+ if (ivilayer == NULL || &pDimension[0] == NULL || &pDimension[1] == NULL) { -+ weston_log("ivi_layout_layerSetDimension: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivilayer->pending.prop; -+ -+ prop->destWidth = pDimension[0]; -+ prop->destHeight = pDimension[1]; -+ -+ ivilayer->event_mask |= IVI_NOTIFICATION_DIMENSION; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerGetPosition(struct ivi_layout_layer *ivilayer, int32_t *pPosition) -+{ -+ if (ivilayer == NULL || pPosition == NULL) { -+ weston_log("ivi_layout_layerGetPosition: invalid argument\n"); -+ return -1; -+ } -+ -+ pPosition[0] = ivilayer->prop.destX; -+ pPosition[1] = ivilayer->prop.destY; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerSetPosition(struct ivi_layout_layer *ivilayer, int32_t *pPosition) -+{ -+ struct ivi_layout_LayerProperties *prop = NULL; -+ -+ if (ivilayer == NULL || pPosition == NULL) { -+ weston_log("ivi_layout_layerSetPosition: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivilayer->pending.prop; -+ prop->destX = pPosition[0]; -+ prop->destY = pPosition[1]; -+ -+ ivilayer->event_mask |= IVI_NOTIFICATION_POSITION; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerSetOrientation(struct ivi_layout_layer *ivilayer, -+ int32_t orientation) -+{ -+ struct ivi_layout_LayerProperties *prop = NULL; -+ -+ if (ivilayer == NULL) { -+ weston_log("ivi_layout_layerSetOrientation: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivilayer->pending.prop; -+ prop->orientation = orientation; -+ -+ ivilayer->event_mask |= IVI_NOTIFICATION_ORIENTATION; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerGetOrientation(struct ivi_layout_layer *ivilayer, -+ int32_t *pOrientation) -+{ -+ if (ivilayer == NULL || pOrientation == NULL) { -+ weston_log("ivi_layout_layerGetOrientation: invalid argument\n"); -+ return -1; -+ } -+ -+ *pOrientation = ivilayer->prop.orientation; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerSetChromaKey(struct ivi_layout_layer *ivilayer, int32_t* pColor) -+{ -+ /* TODO */ -+ (void)ivilayer; -+ (void)pColor; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerSetRenderOrder(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_surface **pSurface, -+ int32_t number) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_surface *ivisurf = NULL; -+ struct ivi_layout_surface *next = NULL; -+ uint32_t *id_surface = NULL; -+ int32_t i = 0; -+ -+ if (ivilayer == NULL) { -+ weston_log("ivi_layout_layerSetRenderOrder: invalid argument\n"); -+ return -1; -+ } -+ -+ if (pSurface == NULL) { -+ wl_list_for_each_safe(ivisurf, next, &ivilayer->pending.list_surface, pending.link) { -+ if (!wl_list_empty(&ivisurf->pending.link)) { -+ wl_list_remove(&ivisurf->pending.link); -+ } -+ -+ wl_list_init(&ivisurf->pending.link); -+ } -+ ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE; -+ return 0; -+ } -+ -+ for (i = 0; i < number; i++) { -+ id_surface = &pSurface[i]->id_surface; -+ -+ wl_list_for_each_safe(ivisurf, next, &layout->list_surface, pending.link) { -+ if (*id_surface != ivisurf->id_surface) { -+ continue; -+ } -+ -+ if (!wl_list_empty(&ivisurf->pending.link)) { -+ wl_list_remove(&ivisurf->pending.link); -+ } -+ wl_list_init(&ivisurf->pending.link); -+ wl_list_insert(&ivilayer->pending.list_surface, -+ &ivisurf->pending.link); -+ break; -+ } -+ } -+ -+ ivilayer->event_mask |= IVI_NOTIFICATION_ADD; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerGetCapabilities(struct ivi_layout_layer *ivilayer, -+ int32_t *pCapabilities) -+{ -+ /* TODO */ -+ (void)ivilayer; -+ (void)pCapabilities; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerTypeGetCapabilities(int32_t layerType, -+ int32_t *pCapabilities) -+{ -+ /* TODO */ -+ (void)layerType; -+ (void)pCapabilities; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceSetVisibility(struct ivi_layout_surface *ivisurf, -+ int32_t newVisibility) -+{ -+ struct ivi_layout_SurfaceProperties *prop = NULL; -+ -+ if (ivisurf == NULL) { -+ weston_log("ivi_layout_surfaceSetVisibility: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivisurf->pending.prop; -+ prop->visibility = newVisibility; -+ -+ ivisurf->event_mask |= IVI_NOTIFICATION_VISIBILITY; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceGetVisibility(struct ivi_layout_surface *ivisurf, -+ int32_t *pVisibility) -+{ -+ if (ivisurf == NULL || pVisibility == NULL) { -+ weston_log("ivi_layout_surfaceGetVisibility: invalid argument\n"); -+ return -1; -+ } -+ -+ *pVisibility = ivisurf->prop.visibility; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceSetOpacity(struct ivi_layout_surface *ivisurf, -+ float opacity) -+{ -+ struct ivi_layout_SurfaceProperties *prop = NULL; -+ -+ if (ivisurf == NULL) { -+ weston_log("ivi_layout_surfaceSetOpacity: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivisurf->pending.prop; -+ prop->opacity = opacity; -+ -+ ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceGetOpacity(struct ivi_layout_surface *ivisurf, -+ float *pOpacity) -+{ -+ if (ivisurf == NULL || pOpacity == NULL) { -+ weston_log("ivi_layout_surfaceGetOpacity: invalid argument\n"); -+ return -1; -+ } -+ -+ *pOpacity = ivisurf->prop.opacity; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_SetKeyboardFocusOn(struct ivi_layout_surface *ivisurf) -+{ -+ /* TODO */ -+ (void)ivisurf; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_GetKeyboardFocusSurfaceId(struct ivi_layout_surface **pSurfaceId) -+{ -+ /* TODO */ -+ (void)pSurfaceId; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceSetDestinationRectangle(struct ivi_layout_surface *ivisurf, -+ int32_t x, int32_t y, -+ int32_t width, int32_t height) -+{ -+ struct ivi_layout_SurfaceProperties *prop = NULL; -+ -+ if (ivisurf == NULL) { -+ weston_log("ivi_layout_surfaceSetDestinationRectangle: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivisurf->pending.prop; -+ prop->destX = x; -+ prop->destY = y; -+ prop->destWidth = width; -+ prop->destHeight = height; -+ -+ ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceSetDimension(struct ivi_layout_surface *ivisurf, int32_t *pDimension) -+{ -+ struct ivi_layout_SurfaceProperties *prop = NULL; -+ -+ if (ivisurf == NULL || &pDimension[0] == NULL || &pDimension[1] == NULL) { -+ weston_log("ivi_layout_surfaceSetDimension: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivisurf->pending.prop; -+ prop->destWidth = pDimension[0]; -+ prop->destHeight = pDimension[1]; -+ -+ ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceGetDimension(struct ivi_layout_surface *ivisurf, -+ int32_t *pDimension) -+{ -+ if (ivisurf == NULL || &pDimension[0] == NULL || &pDimension[1] == NULL) { -+ weston_log("ivi_layout_surfaceGetDimension: invalid argument\n"); -+ return -1; -+ } -+ -+ pDimension[0] = ivisurf->prop.destWidth; -+ pDimension[1] = ivisurf->prop.destHeight; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceSetPosition(struct ivi_layout_surface *ivisurf, -+ int32_t *pPosition) -+{ -+ struct ivi_layout_SurfaceProperties *prop = NULL; -+ -+ if (ivisurf == NULL || pPosition == NULL) { -+ weston_log("ivi_layout_surfaceSetPosition: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivisurf->pending.prop; -+ prop->destX = pPosition[0]; -+ prop->destY = pPosition[1]; -+ -+ ivisurf->event_mask |= IVI_NOTIFICATION_POSITION; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceGetPosition(struct ivi_layout_surface *ivisurf, -+ int32_t *pPosition) -+{ -+ if (ivisurf == NULL || pPosition == NULL) { -+ weston_log("ivi_layout_surfaceGetPosition: invalid argument\n"); -+ return -1; -+ } -+ -+ pPosition[0] = ivisurf->prop.destX; -+ pPosition[1] = ivisurf->prop.destY; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceSetOrientation(struct ivi_layout_surface *ivisurf, -+ int32_t orientation) -+{ -+ struct ivi_layout_SurfaceProperties *prop = NULL; -+ -+ if (ivisurf == NULL) { -+ weston_log("ivi_layout_surfaceSetOrientation: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivisurf->pending.prop; -+ prop->orientation = orientation; -+ -+ ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceGetOrientation(struct ivi_layout_surface *ivisurf, -+ int32_t *pOrientation) -+{ -+ if (ivisurf == NULL || pOrientation == NULL) { -+ weston_log("ivi_layout_surfaceGetOrientation: invalid argument\n"); -+ return -1; -+ } -+ -+ *pOrientation = ivisurf->prop.orientation; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceGetPixelformat(struct ivi_layout_layer *ivisurf, int32_t *pPixelformat) -+{ -+ /* TODO */ -+ (void)ivisurf; -+ (void)pPixelformat; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceSetChromaKey(struct ivi_layout_surface *ivisurf, int32_t* pColor) -+{ -+ /* TODO */ -+ (void)ivisurf; -+ (void)pColor; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_screenAddLayer(struct ivi_layout_screen *iviscrn, -+ struct ivi_layout_layer *addlayer) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_layer *ivilayer = NULL; -+ struct ivi_layout_layer *next = NULL; -+ int is_layer_in_scrn = 0; -+ -+ if (iviscrn == NULL || addlayer == NULL) { -+ weston_log("ivi_layout_screenAddLayer: invalid argument\n"); -+ return -1; -+ } -+ -+ is_layer_in_scrn = is_layer_in_screen(addlayer, iviscrn); -+ if (is_layer_in_scrn == 1) { -+ weston_log("ivi_layout_screenAddLayer: addlayer is already available\n"); -+ return 0; -+ } -+ -+ wl_list_for_each_safe(ivilayer, next, &layout->list_layer, link) { -+ if (ivilayer->id_layer == addlayer->id_layer) { -+ if (!wl_list_empty(&ivilayer->pending.link)) { -+ wl_list_remove(&ivilayer->pending.link); -+ } -+ wl_list_init(&ivilayer->pending.link); -+ wl_list_insert(&iviscrn->pending.list_layer, -+ &ivilayer->pending.link); -+ break; -+ } -+ } -+ -+ iviscrn->event_mask |= IVI_NOTIFICATION_ADD; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_screenSetRenderOrder(struct ivi_layout_screen *iviscrn, -+ struct ivi_layout_layer **pLayer, -+ const int32_t number) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_layer *ivilayer = NULL; -+ struct ivi_layout_layer *next = NULL; -+ uint32_t *id_layer = NULL; -+ int32_t i = 0; -+ -+ if (iviscrn == NULL) { -+ weston_log("ivi_layout_screenSetRenderOrder: invalid argument\n"); -+ return -1; -+ } -+ -+ wl_list_for_each_safe(ivilayer, next, -+ &iviscrn->pending.list_layer, pending.link) { -+ wl_list_init(&ivilayer->pending.link); -+ } -+ -+ wl_list_init(&iviscrn->pending.list_layer); -+ -+ if (pLayer == NULL) { -+ wl_list_for_each_safe(ivilayer, next, &iviscrn->pending.list_layer, pending.link) { -+ if (!wl_list_empty(&ivilayer->pending.link)) { -+ wl_list_remove(&ivilayer->pending.link); -+ } -+ -+ wl_list_init(&ivilayer->pending.link); -+ } -+ -+ iviscrn->event_mask |= IVI_NOTIFICATION_REMOVE; -+ return 0; -+ } -+ -+ for (i = 0; i < number; i++) { -+ id_layer = &pLayer[i]->id_layer; -+ wl_list_for_each(ivilayer, &layout->list_layer, link) { -+ if (*id_layer != ivilayer->id_layer) { -+ continue; -+ } -+ -+ if (!wl_list_empty(&ivilayer->pending.link)) { -+ wl_list_remove(&ivilayer->pending.link); -+ } -+ wl_list_init(&ivilayer->pending.link); -+ wl_list_insert(&iviscrn->pending.list_layer, -+ &ivilayer->pending.link); -+ break; -+ } -+ } -+ -+ iviscrn->event_mask |= IVI_NOTIFICATION_ADD; -+ -+ return 0; -+} -+ -+WL_EXPORT struct weston_output * -+ivi_layout_screenGetOutput(struct ivi_layout_screen *iviscrn) -+{ -+ return iviscrn->output; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_SetOptimizationMode(uint32_t id, int32_t mode) -+{ -+ /* TODO */ -+ (void)id; -+ (void)mode; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_GetOptimizationMode(uint32_t id, int32_t *pMode) -+{ -+ /* TODO */ -+ (void)id; -+ (void)pMode; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerAddNotification(struct ivi_layout_layer *ivilayer, -+ layerPropertyNotificationFunc callback, -+ void *userdata) -+{ -+ struct ivi_layout_notificationCallback *prop_callback = NULL; -+ -+ if (ivilayer == NULL || callback == NULL) { -+ weston_log("ivi_layout_layerAddNotification: invalid argument\n"); -+ return -1; -+ } -+ -+ prop_callback = malloc(sizeof *prop_callback); -+ if (prop_callback == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ prop_callback->callback = callback; -+ prop_callback->data = userdata; -+ -+ return add_notification(&ivilayer->property_changed, -+ layer_prop_changed, -+ prop_callback); -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerRemoveNotification(struct ivi_layout_layer *ivilayer) -+{ -+ if (ivilayer == NULL) { -+ weston_log("ivi_layout_layerRemoveNotification: invalid argument\n"); -+ return -1; -+ } -+ -+ remove_all_notification(&ivilayer->property_changed.listener_list); -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_getPropertiesOfSurface(struct ivi_layout_surface *ivisurf, -+ struct ivi_layout_SurfaceProperties *pSurfaceProperties) -+{ -+ if (ivisurf == NULL || pSurfaceProperties == NULL) { -+ weston_log("ivi_layout_getPropertiesOfSurface: invalid argument\n"); -+ return -1; -+ } -+ -+ *pSurfaceProperties = ivisurf->prop; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerAddSurface(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_surface *addsurf) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_surface *ivisurf = NULL; -+ struct ivi_layout_surface *next = NULL; -+ int is_surf_in_layer = 0; -+ -+ if (ivilayer == NULL || addsurf == NULL) { -+ weston_log("ivi_layout_layerAddSurface: invalid argument\n"); -+ return -1; -+ } -+ -+ is_surf_in_layer = is_surface_in_layer(addsurf, ivilayer); -+ if (is_surf_in_layer == 1) { -+ weston_log("ivi_layout_layerAddSurface: addsurf is already available\n"); -+ return 0; -+ } -+ -+ wl_list_for_each_safe(ivisurf, next, &layout->list_surface, link) { -+ if (ivisurf->id_surface == addsurf->id_surface) { -+ if (!wl_list_empty(&ivisurf->pending.link)) { -+ wl_list_remove(&ivisurf->pending.link); -+ } -+ wl_list_init(&ivisurf->pending.link); -+ wl_list_insert(&ivilayer->pending.list_surface, -+ &ivisurf->pending.link); -+ break; -+ } -+ } -+ -+ ivilayer->event_mask |= IVI_NOTIFICATION_ADD; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerRemoveSurface(struct ivi_layout_layer *ivilayer, -+ struct ivi_layout_surface *remsurf) -+{ -+ struct ivi_layout_surface *ivisurf = NULL; -+ struct ivi_layout_surface *next = NULL; -+ -+ if (ivilayer == NULL || remsurf == NULL) { -+ weston_log("ivi_layout_layerRemoveSurface: invalid argument\n"); -+ return -1; -+ } -+ -+ wl_list_for_each_safe(ivisurf, next, -+ &ivilayer->pending.list_surface, pending.link) { -+ if (ivisurf->id_surface == remsurf->id_surface) { -+ if (!wl_list_empty(&ivisurf->pending.link)) { -+ wl_list_remove(&ivisurf->pending.link); -+ } -+ wl_list_init(&ivisurf->pending.link); -+ break; -+ } -+ } -+ -+ remsurf->event_mask |= IVI_NOTIFICATION_REMOVE; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceSetSourceRectangle(struct ivi_layout_surface *ivisurf, -+ int32_t x, int32_t y, -+ int32_t width, int32_t height) -+{ -+ struct ivi_layout_SurfaceProperties *prop = NULL; -+ -+ if (ivisurf == NULL) { -+ weston_log("ivi_layout_surfaceSetSourceRectangle: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivisurf->pending.prop; -+ prop->sourceX = x; -+ prop->sourceY = y; -+ prop->sourceWidth = width; -+ prop->sourceHeight = height; -+ -+ ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_commitChanges(void) -+{ -+ struct ivi_layout *layout = get_instance(); -+ -+ commit_list_surface(layout); -+ commit_list_layer(layout); -+ commit_list_screen(layout); -+ -+ commit_changes(layout); -+ send_prop(layout); -+ weston_compositor_schedule_repaint(layout->compositor); -+ -+ return 0; -+} -+ -+/***called from ivi-shell**/ -+static struct weston_view * -+ivi_layout_get_weston_view(struct ivi_layout_surface *surface) -+{ -+ if(surface == NULL) return NULL; -+ struct weston_view *tmpview = NULL; -+ wl_list_for_each(tmpview, &surface->surface->views, surface_link) -+ { -+ if (tmpview != NULL) { -+ break; -+ } -+ } -+ return tmpview; -+} -+ -+static void -+ivi_layout_surfaceConfigure(struct ivi_layout_surface *ivisurf, -+ int32_t width, int32_t height) -+{ -+ struct ivi_layout *layout = get_instance(); -+ -+ ivisurf->surface->width_from_buffer = width; -+ ivisurf->surface->height_from_buffer = height; -+ -+ wl_signal_emit(&layout->surface_notification.configure_changed, ivisurf); -+} -+ -+static int32_t -+ivi_layout_surfaceSetNativeContent(struct weston_surface *surface, -+ int32_t width, -+ int32_t height, -+ uint32_t id_surface) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_surface *ivisurf; -+ -+ ivisurf = get_surface(&layout->list_surface, id_surface); -+ if (ivisurf == NULL) { -+ weston_log("layout surface is not found\n"); -+ return -1; -+ } -+ -+ if (ivisurf->surface != NULL) { -+ if (surface != NULL) { -+ weston_log("id_surface(%d) is already set the native content\n", -+ id_surface); -+ return -1; -+ } -+ -+ wl_list_remove(&ivisurf->surface_destroy_listener.link); -+ -+ ivisurf->surface = NULL; -+ -+ wl_list_remove(&ivisurf->surface_rotation.link); -+ wl_list_remove(&ivisurf->layer_rotation.link); -+ wl_list_remove(&ivisurf->surface_pos.link); -+ wl_list_remove(&ivisurf->layer_pos.link); -+ wl_list_remove(&ivisurf->scaling.link); -+ wl_list_init(&ivisurf->surface_rotation.link); -+ wl_list_init(&ivisurf->layer_rotation.link); -+ wl_list_init(&ivisurf->surface_pos.link); -+ wl_list_init(&ivisurf->layer_pos.link); -+ wl_list_init(&ivisurf->scaling.link); -+ -+ } -+ -+ if (surface == NULL) { -+ if (ivisurf->content_observer.callback) { -+ (*(ivisurf->content_observer.callback))(ivisurf, -+ 0, ivisurf->content_observer.userdata); -+ } -+ -+ ivi_layout_surfaceRemoveNotification(ivisurf); -+ return 0; -+ } -+ -+ ivisurf->surface = surface; -+ ivisurf->surface_destroy_listener.notify = -+ westonsurface_destroy_from_ivisurface; -+ wl_resource_add_destroy_listener(surface->resource, -+ &ivisurf->surface_destroy_listener); -+ -+ struct weston_view *tmpview = weston_view_create(surface); -+ if (tmpview == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return -1; -+ } -+ -+ ivisurf->surface->width_from_buffer = width; -+ ivisurf->surface->height_from_buffer = height; -+ ivisurf->pixelformat = IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_8888; -+ -+ wl_signal_emit(&layout->surface_notification.created, ivisurf); -+ -+ if (ivisurf->content_observer.callback) { -+ (*(ivisurf->content_observer.callback))(ivisurf, -+ 1, ivisurf->content_observer.userdata); -+ } -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceSetContentObserver(struct ivi_layout_surface *ivisurf, -+ ivi_controller_surface_content_callback callback, -+ void* userdata) -+{ -+ int32_t ret = -1; -+ if (ivisurf != NULL) { -+ ivisurf->content_observer.callback = callback; -+ ivisurf->content_observer.userdata = userdata; -+ ret = 0; -+ } -+ return ret; -+} -+ -+static struct ivi_layout_surface* -+ivi_layout_surfaceCreate(struct weston_surface *wl_surface, -+ uint32_t id_surface) -+{ -+ struct ivi_layout *layout = get_instance(); -+ struct ivi_layout_surface *ivisurf = NULL; -+ -+ if (wl_surface == NULL) { -+ weston_log("ivi_layout_surfaceCreate: invalid argument\n"); -+ return NULL; -+ } -+ -+ ivisurf = get_surface(&layout->list_surface, id_surface); -+ if (ivisurf != NULL) { -+ if (ivisurf->surface != NULL) { -+ weston_log("id_surface(%d) is already created\n", id_surface); -+ return NULL; -+ } else { -+ /* if ivisurf->surface exist, wl_surface is tied to id_surface again */ -+ /* This means client destroys ivi_surface once, and then tries to tie -+ the id_surface to new wl_surface again. The property of id_surface can -+ be inherited. -+ */ -+ ivi_layout_surfaceSetNativeContent( -+ wl_surface, wl_surface->width, wl_surface->height, id_surface); -+ return ivisurf; -+ } -+ } -+ -+ ivisurf = calloc(1, sizeof *ivisurf); -+ if (ivisurf == NULL) { -+ weston_log("fails to allocate memory\n"); -+ return NULL; -+ } -+ -+ wl_list_init(&ivisurf->link); -+ wl_signal_init(&ivisurf->property_changed); -+ wl_list_init(&ivisurf->list_layer); -+ ivisurf->id_surface = id_surface; -+ ivisurf->layout = layout; -+ -+ ivisurf->surface = wl_surface; -+ ivisurf->surface_destroy_listener.notify = -+ westonsurface_destroy_from_ivisurface; -+ wl_resource_add_destroy_listener(wl_surface->resource, -+ &ivisurf->surface_destroy_listener); -+ -+ struct weston_view *tmpview = weston_view_create(wl_surface); -+ if (tmpview == NULL) { -+ weston_log("fails to allocate memory\n"); -+ } -+ -+ ivisurf->surface->width_from_buffer = 0; -+ ivisurf->surface->height_from_buffer = 0; -+ -+ weston_matrix_init(&ivisurf->surface_rotation.matrix); -+ weston_matrix_init(&ivisurf->layer_rotation.matrix); -+ weston_matrix_init(&ivisurf->surface_pos.matrix); -+ weston_matrix_init(&ivisurf->layer_pos.matrix); -+ weston_matrix_init(&ivisurf->scaling.matrix); -+ -+ wl_list_init(&ivisurf->surface_rotation.link); -+ wl_list_init(&ivisurf->layer_rotation.link); -+ wl_list_init(&ivisurf->surface_pos.link); -+ wl_list_init(&ivisurf->layer_pos.link); -+ wl_list_init(&ivisurf->scaling.link); -+ -+ init_surfaceProperties(&ivisurf->prop); -+ ivisurf->pixelformat = IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_8888; -+ ivisurf->event_mask = 0; -+ -+ ivisurf->pending.prop = ivisurf->prop; -+ wl_list_init(&ivisurf->pending.link); -+ -+ wl_list_init(&ivisurf->order.link); -+ wl_list_init(&ivisurf->order.list_layer); -+ -+ wl_list_insert(&layout->list_surface, &ivisurf->link); -+ -+ wl_signal_emit(&layout->surface_notification.created, ivisurf); -+ -+ return ivisurf; -+} -+ -+static void -+ivi_layout_initWithCompositor(struct weston_compositor *ec) -+{ -+ struct ivi_layout *layout = get_instance(); -+ -+ layout->compositor = ec; -+ -+ wl_list_init(&layout->list_surface); -+ wl_list_init(&layout->list_layer); -+ wl_list_init(&layout->list_screen); -+ -+ wl_signal_init(&layout->layer_notification.created); -+ wl_signal_init(&layout->layer_notification.removed); -+ -+ wl_signal_init(&layout->surface_notification.created); -+ wl_signal_init(&layout->surface_notification.removed); -+ wl_signal_init(&layout->surface_notification.configure_changed); -+ -+ wl_signal_init(&layout->warning_signal); -+ -+ /* Add layout_layer at the last of weston_compositor.layer_list */ -+ weston_layer_init(&layout->layout_layer, ec->layer_list.prev); -+ -+ create_screen(ec); -+ -+ struct weston_config *config = weston_config_parse("weston.ini"); -+ struct weston_config_section *s = -+ weston_config_get_section(config, "ivi-shell", NULL, NULL); -+ -+ /*A cursor is configured if weston.ini has keys.*/ -+ char* cursor_theme = NULL; -+ weston_config_section_get_string(s, "cursor-theme", &cursor_theme, NULL); -+ if (cursor_theme) -+ free(cursor_theme); -+ else -+ wl_list_remove(&ec->cursor_layer.link); -+ weston_config_destroy(config); -+} -+ -+ -+WL_EXPORT struct ivi_layout_interface ivi_layout_interface = { -+ .get_weston_view = ivi_layout_get_weston_view, -+ .surfaceConfigure = ivi_layout_surfaceConfigure, -+ .surfaceSetNativeContent = ivi_layout_surfaceSetNativeContent, -+ .surfaceCreate = ivi_layout_surfaceCreate, -+ .initWithCompositor = ivi_layout_initWithCompositor, -+ .emitWarningSignal = ivi_layout_emitWarningSignal -+}; --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0005-protocol-ivi-hmi-controller-protocol-to-set-up-IVI-s.patch b/meta-ivi/recipes-graphics/wayland/weston/0005-protocol-ivi-hmi-controller-protocol-to-set-up-IVI-s.patch deleted file mode 100644 index 50c7cad..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0005-protocol-ivi-hmi-controller-protocol-to-set-up-IVI-s.patch +++ /dev/null @@ -1,140 +0,0 @@ -From f1bb1117bd4e0a99bb1ae44385343735e686df8e Mon Sep 17 00:00:00 2001 -From: Andrei Gherzan <andrei.gherzan@windriver.com> -Date: Thu, 25 Sep 2014 16:49:58 +0200 -Subject: [PATCH 05/31] protocol: ivi hmi controller protocol to set up IVI - style UI - -This protocol realizes following features, -- UI ready -- changing modes; tiling, side by side, full_screen, and random -- Give control a surface; workspace to be controlled by using ivi layout APIs -- Display/undisplay a surface; home contains sevaral workspaces to launch - application - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Signed-off-by: Andrei Gherzan <andrei.gherzan@windriver.com> ---- - Makefile.am | 3 +- - protocol/ivi-hmi-controller.xml | 96 +++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 98 insertions(+), 1 deletion(-) - create mode 100644 protocol/ivi-hmi-controller.xml - -diff --git a/Makefile.am b/Makefile.am -index 148529f..748556b 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -1007,7 +1007,8 @@ EXTRA_DIST += \ - protocol/xdg-shell.xml \ - protocol/fullscreen-shell.xml \ - protocol/scaler.xml \ -- protocol/ivi-application.xml -+ protocol/ivi-application.xml \ -+ protocol/ivi-hmi-controller.xml - - man_MANS = weston.1 weston.ini.5 - -diff --git a/protocol/ivi-hmi-controller.xml b/protocol/ivi-hmi-controller.xml -new file mode 100644 -index 0000000..fd5ce2b ---- /dev/null -+++ b/protocol/ivi-hmi-controller.xml -@@ -0,0 +1,96 @@ -+<?xml version="1.0" encoding="UTF-8"?> -+<protocol name="ivi_hmi_controller"> -+ -+ <copyright> -+ Copyright (C) 2013 DENSO CORPORATION -+ -+ Permission is hereby granted, free of charge, to any person obtaining a copy -+ of this software and associated documentation files (the "Software"), to deal -+ in the Software without restriction, including without limitation the rights -+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+ copies of the Software, and to permit persons to whom the Software is -+ furnished to do so, subject to the following conditions: -+ -+ The above copyright notice and this permission notice shall be included in -+ all copies or substantial portions of the Software. -+ -+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -+ THE SOFTWARE. -+ </copyright> -+ -+ <interface name="ivi_hmi_controller" version="1"> -+ <description summary="set up and control IVI style UI"/> -+ -+ <request name="UI_ready"> -+ <description summary="inform the ready for drawing desktop." /> -+ </request> -+ -+ <request name="workspace_control"> -+ <description summary="start controlling a surface by server"> -+ Reference protocol to control a surface by server. -+ To control a surface by server, it gives seat to the server -+ to e.g. control Home screen. Home screen has several workspaces -+ to group launchers of wayland application. These workspaces -+ are drawn on a horizontally long surface to be controlled -+ by motion of input device. E.g. A motion from right to left -+ happens, the viewport of surface is controlled in the ivi-shell -+ by using ivi-layout. client can recognizes the end of controlling -+ by event "workspace_end_control". -+ </description> -+ <arg name="seat" type="object" interface="wl_seat"/> -+ <arg name="serial" type="uint"/> -+ </request> -+ -+ <enum name="layout_mode"> -+ <entry name="tiling" value="0"/> -+ <entry name="side_by_side" value="1"/> -+ <entry name="full_screen" value="2"/> -+ <entry name="random" value="3" /> -+ </enum> -+ -+ <request name="switch_mode"> -+ <description summary="request mode switch of application layout"> -+ hmi-controller loaded to ivi-shall implements 4 types of layout -+ as a reference; tiling, side by side, full_screen, and random. -+ </description> -+ <arg name="layout_mode" type="uint"/> -+ </request> -+ -+ <enum name="home"> -+ <entry name="off" value="0"/> -+ <entry name="on" value="1"/> -+ </enum> -+ -+ <request name="home"> -+ <description summary="request displaying/undisplaying home screen"> -+ home screen is a reference implementation of launcher to launch -+ wayland applications. The home screen has several workspaces to -+ group wayland applications. By defining the following keys in -+ weston.ini, user can add launcher icon to launch a wayland application -+ to a workspace. -+ [ivi-launcher] -+ workspace-id=0 -+ : id of workspace to add a launcher -+ icon-id=4001 -+ : ivi id of ivi_surface to draw a icon -+ icon=/home/user/review/build-ivi-shell/data/icon_ivi_flower.png -+ : path to icon image -+ path=/home/user/review/build-ivi-shell/weston-dnd -+ : path to wayland application -+ </description> -+ <arg name="home" type="uint"/> -+ </request> -+ -+ <event name="workspace_end_control"> -+ <description summary="notify controlling workspace end"/> -+ <arg name="is_controlled" type="int"/> -+ </event> -+ -+ </interface> -+ -+</protocol> --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0006-ivi-shell-a-reference-implementation-how-to-use-ivi-.patch b/meta-ivi/recipes-graphics/wayland/weston/0006-ivi-shell-a-reference-implementation-how-to-use-ivi-.patch deleted file mode 100644 index 9c8de6c..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0006-ivi-shell-a-reference-implementation-how-to-use-ivi-.patch +++ /dev/null @@ -1,2027 +0,0 @@ -From 0db90d2ae7da57e453c2bde193be73394e5deb68 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Tue, 24 Jun 2014 23:06:02 +0900 -Subject: [PATCH 06/31] ivi-shell: a reference implementation how to use - ivi-layout internal APIs - -The library is used to manage layout of surfaces/layers. Layout change -is triggered by ivi-hmi-controller protocol, ivi-hmi-controller.xml. A -reference how to use the protocol, see hmi-controller-homescreen. - -In-Vehicle Infotainment system usually manage properties of -surfaces/layers by only a central component which decide where -surfaces/layers shall be. This reference show examples to implement the -central component as a module of weston. - -Default Scene graph of UI is defined in hmi_controller_create. It -consists of -- In the bottom, a base layer to group surfaces of background, panel, - and buttons -- Next, a application layer to show application surfaces. -- Workspace background layer to show a surface of background image. -- Workspace layer to show launcher to launch application with icons. - Paths to binary and icon are defined in weston.ini. The width of - this layer is longer than the size of screen because a workspace - has several pages and is controlled by motion of input. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - Makefile.am | 20 +- - ivi-shell/.gitignore | 7 + - ivi-shell/hmi-controller.c | 1925 ++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 1951 insertions(+), 1 deletion(-) - create mode 100644 ivi-shell/.gitignore - create mode 100644 ivi-shell/hmi-controller.c - -diff --git a/Makefile.am b/Makefile.am -index 748556b..9dd492b 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -704,7 +704,8 @@ if ENABLE_IVI_SHELL - - module_LTLIBRARIES += \ - $(ivi_shell) \ -- $(ivi_layout) -+ $(ivi_layout) \ -+ $(hmi_controller) - - ivi_shell = ivi-shell.la - ivi_shell_la_LDFLAGS = -module -avoid-version -@@ -720,6 +721,7 @@ nodist_ivi_shell_la_SOURCES = \ - - BUILT_SOURCES += $(nodist_ivi_shell_la_SOURCES) - -+ - ivi_layout = ivi-layout.la - ivi_layout_la_LDFLAGS = -module -avoid-version - ivi_layout_la_LIBADD = $(COMPOSITOR_LIBS) $(IVI_SHELL_LIBS) libshared.la -@@ -734,6 +736,22 @@ nodist_ivi_layout_la_SOURCES = \ - - BUILT_SOURCES += $(nodist_ivi_layout_la_SOURCES) - -+hmi_controller = hmi-controller.la -+hmi_controller_la_LDFLAGS = -module -avoid-version -+hmi_controller_la_LIBADD = $(CLIENT_LIBS) $(IVI_SHELL_LIBS) libshared-cairo.la -+hmi_controller_la_CFLAGS = $(GCC_CFLAGS) $(IVI_SHELL_CFLAGS) -+hmi_controller_la_SOURCES = \ -+ ivi-shell/ivi-layout-export.h \ -+ ivi-shell/hmi-controller.c -+nodist_hmi_controller_la_SOURCES = \ -+ protocol/ivi-application-protocol.c \ -+ protocol/ivi-application-client-protocol.h \ -+ protocol/ivi-hmi-controller-protocol.c \ -+ protocol/ivi-hmi-controller-client-protocol.h \ -+ protocol/ivi-hmi-controller-server-protocol.h -+ -+BUILT_SOURCES += $(nodist_hmi_controller_la_SOURCES) -+ - endif - - -diff --git a/ivi-shell/.gitignore b/ivi-shell/.gitignore -new file mode 100644 -index 0000000..9f31bfd ---- /dev/null -+++ b/ivi-shell/.gitignore -@@ -0,0 +1,7 @@ -+ivi-application-client-protocol.h -+ivi-application-protocol.c -+ivi-application-server-protocol.h -+ivi-hmi-controller-client-protocol.h -+ivi-hmi-controller-protocol.c -+ivi-hmi-controller-server-protocol.h -+weston.ini -diff --git a/ivi-shell/hmi-controller.c b/ivi-shell/hmi-controller.c -new file mode 100644 -index 0000000..e04fe61 ---- /dev/null -+++ b/ivi-shell/hmi-controller.c -@@ -0,0 +1,1925 @@ -+/* -+ * Copyright (C) 2014 DENSO CORPORATION -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and -+ * its documentation for any purpose is hereby granted without fee, provided -+ * that the above copyright notice appear in all copies and that both that -+ * copyright notice and this permission notice appear in supporting -+ * documentation, and that the name of the copyright holders not be used in -+ * advertising or publicity pertaining to distribution of the software -+ * without specific, written prior permission. The copyright holders make -+ * no representations about the suitability of this software for any -+ * purpose. It is provided "as is" without express or implied warranty. -+ * -+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS -+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY -+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+/** -+ * A reference implementation how to use ivi-layout APIs in order to manage -+ * layout of surfaces/layers. Layout change is triggered by ivi-hmi-controller -+ * protocol, ivi-hmi-controller.xml. A reference how to use the protocol, see -+ * hmi-controller-homescreen. -+ * -+ * In-Vehicle Infotainment system usually manage properties of surfaces/layers -+ * by only a central component which decide where surfaces/layers shall be. This -+ * reference show examples to implement the central component as a module of weston. -+ * -+ * Default Scene graph of UI is defined in hmi_controller_create. It consists of -+ * - In the bottom, a base layer to group surfaces of background, panel, -+ * and buttons -+ * - Next, a application layer to show application surfaces. -+ * - Workspace background layer to show a surface of background image. -+ * - Workspace layer to show launcher to launch application with icons. Paths to -+ * binary and icon are defined in weston.ini. The width of this layer is longer -+ * than the size of screen because a workspace has several pages and is controlled -+ * by motion of input. -+ * -+ * TODO: animation method shall be refined -+ * TODO: support fade-in when UI is ready -+ */ -+ -+#include <sys/wait.h> -+#include <unistd.h> -+#include <stdlib.h> -+#include <stdio.h> -+#include <string.h> -+#include <linux/input.h> -+#include <assert.h> -+#include <time.h> -+ -+#include "ivi-layout-export.h" -+#include "ivi-hmi-controller-server-protocol.h" -+ -+/***************************************************************************** -+ * structure, globals -+ ****************************************************************************/ -+struct hmi_controller_layer { -+ struct ivi_layout_layer *ivilayer; -+ uint32_t id_layer; -+ int32_t x; -+ int32_t y; -+ int32_t width; -+ int32_t height; -+}; -+ -+struct link_layer { -+ struct ivi_layout_layer *layout_layer; -+ struct wl_list link; -+}; -+ -+struct link_animation { -+ struct hmi_controller_animation *animation; -+ struct wl_list link; -+}; -+ -+struct hmi_controller_animation; -+typedef void (*hmi_controller_animation_frame_func)(void *animation, int32_t timestamp); -+typedef void (*hmi_controller_animation_frame_user_func)(void *animation); -+typedef void (*hmi_controller_animation_destroy_func)(struct hmi_controller_animation *animation); -+ -+struct move_animation_user_data { -+ struct ivi_layout_layer* layer; -+ struct animation_set *anima_set; -+ struct hmi_controller *hmi_ctrl; -+}; -+ -+struct hmi_controller_animation { -+ void *user_data; -+ uint32_t time_start; -+ int32_t is_done; -+ hmi_controller_animation_frame_func frame_func; -+ hmi_controller_animation_frame_user_func frame_user_func; -+ hmi_controller_animation_destroy_func destroy_func; -+}; -+ -+struct hmi_controller_animation_fade { -+ struct hmi_controller_animation base; -+ double start; -+ double end; -+ struct weston_spring spring; -+}; -+ -+struct hmi_controller_animation_move { -+ struct hmi_controller_animation base; -+ double pos; -+ double pos_start; -+ double pos_end; -+ double v0; -+ double a; -+ double time_end; -+}; -+ -+struct hmi_controller_fade { -+ int32_t isFadeIn; -+ struct hmi_controller_animation_fade *animation; -+ struct animation_set *anima_set; -+ struct wl_list layer_list; -+}; -+ -+struct animation_set { -+ struct wl_event_source *event_source; -+ struct wl_list animation_list; -+}; -+ -+struct -+hmi_server_setting { -+ uint32_t base_layer_id; -+ uint32_t application_layer_id; -+ uint32_t workspace_background_layer_id; -+ uint32_t workspace_layer_id; -+ int32_t panel_height; -+ char *ivi_homescreen; -+}; -+ -+struct hmi_controller -+{ -+ struct hmi_server_setting *hmi_setting; -+ struct hmi_controller_layer base_layer; -+ struct hmi_controller_layer application_layer; -+ struct hmi_controller_layer workspace_background_layer; -+ struct hmi_controller_layer workspace_layer; -+ enum ivi_hmi_controller_layout_mode layout_mode; -+ -+ struct animation_set *anima_set; -+ struct hmi_controller_fade workspace_fade; -+ struct hmi_controller_animation_move *workspace_swipe_animation; -+ int32_t workspace_count; -+ struct wl_array ui_widgets; -+ int32_t is_initialized; -+}; -+ -+struct launcher_info -+{ -+ uint32_t surface_id; -+ uint32_t workspace_id; -+ int32_t index; -+}; -+ -+/***************************************************************************** -+ * local functions -+ ****************************************************************************/ -+static void * -+fail_on_null(void *p, size_t size, char* file, int32_t line) -+{ -+ if (size && !p) { -+ fprintf(stderr, "%s(%d) %zd: out of memory\n", file, line, size); -+ exit(EXIT_FAILURE); -+ } -+ -+ return p; -+} -+ -+static void * -+mem_alloc(size_t size, char* file, int32_t line) -+{ -+ return fail_on_null(calloc(1, size), size, file, line); -+} -+ -+#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__) -+ -+static int32_t -+is_surf_in_uiWidget(struct hmi_controller *hmi_ctrl, -+ struct ivi_layout_surface *ivisurf) -+{ -+ uint32_t id = ivi_layout_getIdOfSurface(ivisurf); -+ -+ uint32_t *ui_widget_id = NULL; -+ wl_array_for_each (ui_widget_id, &hmi_ctrl->ui_widgets) { -+ if (*ui_widget_id == id) { -+ return 1; -+ } -+ } -+ -+ return 0; -+} -+ -+static int -+compare_launcher_info(const void *lhs, const void *rhs) -+{ -+ const struct launcher_info *left = (const struct launcher_info *)lhs; -+ const struct launcher_info *right = (const struct launcher_info *)rhs; -+ -+ if (left->workspace_id < right->workspace_id) { -+ return -1; -+ } -+ -+ if (left->workspace_id > right->workspace_id) { -+ return 1; -+ } -+ -+ if (left->index < right->index) { -+ return -1; -+ } -+ -+ if (left->index > right->index) { -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/** -+ * Internal methods called by mainly ivi_hmi_controller_switch_mode -+ * This reference shows 4 examples how to use ivi_layout APIs. -+ */ -+static void -+mode_divided_into_tiling(struct hmi_controller *hmi_ctrl, -+ struct ivi_layout_surface **ppSurface, -+ int32_t surface_length, -+ struct hmi_controller_layer *layer) -+{ -+ const float surface_width = (float)layer->width * 0.25; -+ const float surface_height = (float)layer->height * 0.5; -+ int32_t surface_x = 0; -+ int32_t surface_y = 0; -+ struct ivi_layout_surface *ivisurf = NULL; -+ int32_t ret = 0; -+ -+ int32_t i = 0; -+ int32_t num = 1; -+ for (i = 0; i < surface_length; i++) { -+ ivisurf = ppSurface[i]; -+ -+ /* skip ui widgets */ -+ if (is_surf_in_uiWidget(hmi_ctrl, ivisurf)) { -+ continue; -+ } -+ -+ if (num <= 8) { -+ if (num < 5) { -+ surface_x = (int32_t)((num - 1) * (surface_width)); -+ surface_y = 0; -+ } -+ else { -+ surface_x = (int32_t)((num - 5) * (surface_width)); -+ surface_y = (int32_t)surface_height; -+ } -+ ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, surface_x, surface_y, -+ surface_width, surface_height); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -+ assert(!ret); -+ -+ num++; -+ continue; -+ } -+ -+ ret = ivi_layout_surfaceSetVisibility(ivisurf, 0); -+ assert(!ret); -+ } -+} -+ -+static void -+mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl, -+ struct ivi_layout_surface **ppSurface, -+ int32_t surface_length, -+ struct hmi_controller_layer *layer) -+{ -+ int32_t surface_width = layer->width / 2; -+ int32_t surface_height = layer->height; -+ struct ivi_layout_surface *ivisurf = NULL; -+ int32_t ret = 0; -+ -+ int32_t i = 0; -+ int32_t num = 1; -+ for (i = 0; i < surface_length; i++) { -+ ivisurf = ppSurface[i]; -+ -+ /* skip ui widgets */ -+ if (is_surf_in_uiWidget(hmi_ctrl, ivisurf)) { -+ continue; -+ } -+ -+ if (num == 1) { -+ ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, 0, 0, -+ surface_width, surface_height); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -+ assert(!ret); -+ -+ num++; -+ continue; -+ } -+ else if (num == 2) { -+ ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, surface_width, 0, -+ surface_width, surface_height); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -+ assert(!ret); -+ -+ num++; -+ continue; -+ } -+ -+ ivi_layout_surfaceSetVisibility(ivisurf, 0); -+ assert(!ret); -+ } -+} -+ -+static void -+mode_fullscreen_someone(struct hmi_controller *hmi_ctrl, -+ struct ivi_layout_surface **ppSurface, -+ int32_t surface_length, -+ struct hmi_controller_layer *layer) -+{ -+ const int32_t surface_width = layer->width; -+ const int32_t surface_height = layer->height; -+ struct ivi_layout_surface *ivisurf = NULL; -+ int32_t ret = 0; -+ -+ int32_t i = 0; -+ for (i = 0; i < surface_length; i++) { -+ ivisurf = ppSurface[i]; -+ -+ /* skip ui widgets */ -+ if (is_surf_in_uiWidget(hmi_ctrl, ivisurf)) { -+ continue; -+ } -+ -+ ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, 0, 0, -+ surface_width, surface_height); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -+ assert(!ret); -+ } -+} -+ -+static void -+mode_random_replace(struct hmi_controller *hmi_ctrl, -+ struct ivi_layout_surface **ppSurface, -+ int32_t surface_length, -+ struct hmi_controller_layer *layer) -+{ -+ const int32_t surface_width = (int32_t)(layer->width * 0.25f); -+ const int32_t surface_height = (int32_t)(layer->height * 0.25f); -+ int32_t surface_x = 0; -+ int32_t surface_y = 0; -+ struct ivi_layout_surface *ivisurf = NULL; -+ int32_t ret = 0; -+ -+ int32_t i = 0; -+ for (i = 0; i < surface_length; i++) { -+ ivisurf = ppSurface[i]; -+ -+ /* skip ui widgets */ -+ if (is_surf_in_uiWidget(hmi_ctrl, ivisurf)) { -+ continue; -+ } -+ -+ surface_x = rand() % (layer->width - surface_width); -+ surface_y = rand() % (layer->height - surface_height); -+ -+ ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, surface_x, surface_y, -+ surface_width, surface_height); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -+ assert(!ret); -+ } -+} -+ -+static int32_t -+has_applicatipn_surface(struct hmi_controller *hmi_ctrl, -+ struct ivi_layout_surface **ppSurface, -+ int32_t surface_length) -+{ -+ struct ivi_layout_surface *ivisurf = NULL; -+ int32_t i = 0; -+ -+ for (i = 0; i < surface_length; i++) { -+ ivisurf = ppSurface[i]; -+ -+ /* skip ui widgets */ -+ if (is_surf_in_uiWidget(hmi_ctrl, ivisurf)) { -+ continue; -+ } -+ -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/** -+ * Supports 4 example to layout of application surfaces; -+ * tiling, side by side, fullscreen, and random. -+ */ -+static void -+switch_mode(struct hmi_controller *hmi_ctrl, -+ enum ivi_hmi_controller_layout_mode layout_mode) -+{ -+ if (!hmi_ctrl->is_initialized) { -+ return; -+ } -+ -+ struct hmi_controller_layer *layer = &hmi_ctrl->application_layer; -+ struct ivi_layout_surface **ppSurface = NULL; -+ int32_t surface_length = 0; -+ int32_t ret = 0; -+ -+ hmi_ctrl->layout_mode = layout_mode; -+ -+ ret = ivi_layout_getSurfaces(&surface_length, &ppSurface); -+ assert(!ret); -+ -+ if (!has_applicatipn_surface(hmi_ctrl, ppSurface, surface_length)) { -+ free(ppSurface); -+ ppSurface = NULL; -+ return; -+ } -+ -+ switch (layout_mode) { -+ case IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING: -+ mode_divided_into_tiling(hmi_ctrl, ppSurface, surface_length, layer); -+ break; -+ case IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE: -+ mode_divided_into_sidebyside(hmi_ctrl, ppSurface, surface_length, layer); -+ break; -+ case IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN: -+ mode_fullscreen_someone(hmi_ctrl, ppSurface, surface_length, layer); -+ break; -+ case IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM: -+ mode_random_replace(hmi_ctrl, ppSurface, surface_length, layer); -+ break; -+ } -+ -+ ivi_layout_commitChanges(); -+ -+ free(ppSurface); -+ ppSurface = NULL; -+ -+ return; -+} -+ -+/** -+ * Internal method for animation -+ */ -+static void -+hmi_controller_animation_frame( -+ struct hmi_controller_animation *animation, int32_t timestamp) -+{ -+ if (0 == animation->time_start) { -+ animation->time_start = timestamp; -+ } -+ -+ animation->frame_func(animation, timestamp); -+ animation->frame_user_func(animation); -+} -+ -+static int -+animation_set_do_anima(void* data) -+{ -+ struct animation_set *anima_set = data; -+ int32_t fps = 30; -+ -+ if (wl_list_empty(&anima_set->animation_list)) { -+ wl_event_source_timer_update(anima_set->event_source, 0); -+ return 1; -+ } -+ -+ wl_event_source_timer_update(anima_set->event_source, 1000 / fps); -+ -+ struct timespec timestamp = {0}; -+ clock_gettime(CLOCK_MONOTONIC, ×tamp); -+ int32_t msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec); -+ -+ struct link_animation *link_animation = NULL; -+ struct link_animation *next = NULL; -+ -+ wl_list_for_each_safe(link_animation, next, &anima_set->animation_list, link) { -+ hmi_controller_animation_frame(link_animation->animation, msec); -+ } -+ -+ ivi_layout_commitChanges(); -+ return 1; -+} -+ -+static struct animation_set * -+animation_set_create(struct weston_compositor* ec) -+{ -+ struct animation_set *anima_set = MEM_ALLOC(sizeof(*anima_set)); -+ -+ wl_list_init(&anima_set->animation_list); -+ -+ struct wl_event_loop *loop = wl_display_get_event_loop(ec->wl_display); -+ anima_set->event_source = wl_event_loop_add_timer(loop, animation_set_do_anima, anima_set); -+ wl_event_source_timer_update(anima_set->event_source, 0); -+ -+ return anima_set; -+} -+ -+static void -+animation_set_add_animation(struct animation_set *anima_set, -+ struct hmi_controller_animation *anima) -+{ -+ struct link_animation *link_anima = NULL; -+ -+ link_anima = MEM_ALLOC(sizeof(*link_anima)); -+ if (NULL == link_anima) { -+ return; -+ } -+ -+ link_anima->animation = anima; -+ wl_list_insert(&anima_set->animation_list, &link_anima->link); -+ wl_event_source_timer_update(anima_set->event_source, 1); -+} -+ -+static void -+animation_set_remove_animation(struct animation_set *anima_set, -+ struct hmi_controller_animation *anima) -+{ -+ struct link_animation *link_animation = NULL; -+ struct link_animation *next = NULL; -+ -+ wl_list_for_each_safe(link_animation, next, &anima_set->animation_list, link) { -+ if (link_animation->animation == anima) { -+ wl_list_remove(&link_animation->link); -+ free(link_animation); -+ break; -+ } -+ } -+} -+ -+static void -+hmi_controller_animation_spring_frame( -+ struct hmi_controller_animation_fade *animation, int32_t timestamp) -+{ -+ if (0 == animation->spring.timestamp) { -+ animation->spring.timestamp = timestamp; -+ } -+ -+ weston_spring_update(&animation->spring, timestamp); -+ animation->base.is_done = weston_spring_done(&animation->spring); -+} -+ -+static void -+hmi_controller_animation_move_frame( -+ struct hmi_controller_animation_move *animation, int32_t timestamp) -+{ -+ double s = animation->pos_start; -+ double t = timestamp - animation->base.time_start; -+ double v0 = animation->v0; -+ double a = animation->a; -+ double time_end = animation->time_end; -+ -+ if (time_end <= t) { -+ animation->pos = animation->pos_end; -+ animation->base.is_done = 1; -+ } else { -+ animation->pos = v0 * t + 0.5 * a * t * t + s; -+ } -+} -+ -+static void -+hmi_controller_animation_destroy(struct hmi_controller_animation *animation) -+{ -+ if (animation->destroy_func) { -+ animation->destroy_func(animation); -+ } -+ -+ free(animation); -+} -+ -+static void -+hmi_controller_fade_animation_destroy(struct hmi_controller_animation *animation) -+{ -+ struct hmi_controller_fade *fade = animation->user_data; -+ animation_set_remove_animation(fade->anima_set, animation); -+ fade->animation = NULL; -+ animation->user_data = NULL; -+} -+ -+static struct hmi_controller_animation_fade * -+hmi_controller_animation_fade_create(double start, double end, double k, -+ hmi_controller_animation_frame_user_func frame_user_func, void* user_data, -+ hmi_controller_animation_destroy_func destroy_func) -+{ -+ struct hmi_controller_animation_fade* animation = MEM_ALLOC(sizeof(*animation)); -+ -+ animation->base.frame_user_func = frame_user_func; -+ animation->base.user_data = user_data; -+ animation->base.frame_func = -+ (hmi_controller_animation_frame_func)hmi_controller_animation_spring_frame; -+ animation->base.destroy_func = destroy_func; -+ -+ animation->start = start; -+ animation->end = end; -+ weston_spring_init(&animation->spring, k, start, end); -+ animation->spring.friction = 1400; -+ animation->spring.previous = -(end - start) * 0.03; -+ -+ return animation; -+} -+ -+static struct hmi_controller_animation_move * -+hmi_controller_animation_move_create( -+ double pos_start, double pos_end, double v_start, double v_end, -+ hmi_controller_animation_frame_user_func frame_user_func, void* user_data, -+ hmi_controller_animation_destroy_func destroy_func) -+{ -+ struct hmi_controller_animation_move* animation = MEM_ALLOC(sizeof(*animation)); -+ -+ animation->base.frame_user_func = frame_user_func; -+ animation->base.user_data = user_data; -+ animation->base.frame_func = -+ (hmi_controller_animation_frame_func)hmi_controller_animation_move_frame; -+ animation->base.destroy_func = destroy_func; -+ -+ animation->pos_start = pos_start; -+ animation->pos_end = pos_end; -+ animation->v0 = v_start; -+ animation->pos = pos_start; -+ -+ double dx = (pos_end - pos_start); -+ -+ if (1e-3 < fabs(dx)) { -+ animation->a = 0.5 * (v_end * v_end - v_start * v_start) / dx; -+ if (1e-6 < fabs(animation->a)) { -+ animation->time_end = (v_end - v_start) / animation->a; -+ -+ } else { -+ animation->a = 0; -+ animation->time_end = fabs(dx / animation->v0); -+ } -+ -+ } else { -+ animation->time_end = 0; -+ } -+ -+ return animation; -+} -+ -+static double -+hmi_controller_animation_fade_alpha_get(struct hmi_controller_animation_fade* animation) -+{ -+ if (animation->spring.current > 0.999) { -+ return 1.0; -+ } else if (animation->spring.current < 0.001 ) { -+ return 0.0; -+ } else { -+ return animation->spring.current; -+ } -+} -+ -+static int32_t -+hmi_controller_animation_is_done(struct hmi_controller_animation *animation) -+{ -+ return animation->is_done; -+} -+ -+static void -+hmi_controller_fade_update(struct hmi_controller_animation_fade *animation, double end) -+{ -+ animation->spring.target = end; -+} -+ -+static void -+hmi_controller_anima_fade_user_frame(struct hmi_controller_animation_fade *animation) -+{ -+ double alpha = hmi_controller_animation_fade_alpha_get(animation); -+ alpha = wl_fixed_from_double(alpha); -+ struct hmi_controller_fade *fade = animation->base.user_data; -+ struct link_layer *linklayer = NULL; -+ int32_t is_done = hmi_controller_animation_is_done(&animation->base); -+ int32_t is_visible = !is_done || fade->isFadeIn; -+ -+ wl_list_for_each(linklayer, &fade->layer_list, link) { -+ ivi_layout_layerSetOpacity(linklayer->layout_layer, alpha); -+ ivi_layout_layerSetVisibility(linklayer->layout_layer, is_visible); -+ } -+ -+ if (is_done) { -+ hmi_controller_animation_destroy(&animation->base); -+ } -+} -+ -+static void -+hmi_controller_anima_move_user_frame(struct hmi_controller_animation_move *animation) -+{ -+ struct move_animation_user_data* user_data = animation->base.user_data; -+ struct ivi_layout_layer *layer = user_data->layer; -+ int32_t is_done = hmi_controller_animation_is_done(&animation->base); -+ -+ int32_t pos[2] = {0}; -+ ivi_layout_layerGetPosition(layer, pos); -+ -+ pos[0] = (int32_t)animation->pos; -+ ivi_layout_layerSetPosition(layer, pos); -+ -+ if (is_done) { -+ hmi_controller_animation_destroy(&animation->base); -+ } -+} -+ -+static void -+hmi_controller_fade_run(int32_t isFadeIn, struct hmi_controller_fade *fade) -+{ -+ double tint = isFadeIn ? 1.0 : 0.0; -+ fade->isFadeIn = isFadeIn; -+ -+ if (fade->animation) { -+ hmi_controller_fade_update(fade->animation, tint); -+ } else { -+ fade->animation = hmi_controller_animation_fade_create( -+ 1.0 - tint, tint, 300.0, -+ (hmi_controller_animation_frame_user_func)hmi_controller_anima_fade_user_frame, -+ fade, hmi_controller_fade_animation_destroy); -+ -+ animation_set_add_animation(fade->anima_set, &fade->animation->base); -+ } -+} -+ -+/** -+ * Internal method to create layer with hmi_controller_layer and add to a screen -+ */ -+static void -+create_layer(struct ivi_layout_screen *iviscrn, -+ struct hmi_controller_layer *layer) -+{ -+ int32_t ret = 0; -+ -+ layer->ivilayer = ivi_layout_layerCreateWithDimension(layer->id_layer, -+ layer->width, layer->height); -+ assert(layer->ivilayer != NULL); -+ -+ ret = ivi_layout_screenAddLayer(iviscrn, layer->ivilayer); -+ assert(!ret); -+ -+ ret = ivi_layout_layerSetDestinationRectangle(layer->ivilayer, layer->x, layer->y, -+ layer->width, layer->height); -+ assert(!ret); -+ -+ ret = ivi_layout_layerSetVisibility(layer->ivilayer, 1); -+ assert(!ret); -+} -+ -+/** -+ * Internal set notification -+ */ -+static void -+set_notification_create_surface(struct ivi_layout_surface *ivisurf, -+ void *userdata) -+{ -+ struct hmi_controller* hmi_ctrl = userdata; -+ struct ivi_layout_layer *application_layer = hmi_ctrl->application_layer.ivilayer; -+ int32_t ret = 0; -+ -+ /* skip ui widgets */ -+ if (is_surf_in_uiWidget(hmi_ctrl, ivisurf)) { -+ return; -+ } -+ -+ ret = ivi_layout_layerAddSurface(application_layer, ivisurf); -+ assert(!ret); -+} -+ -+static void -+set_notification_remove_surface(struct ivi_layout_surface *ivisurf, -+ void *userdata) -+{ -+ (void)ivisurf; -+ struct hmi_controller* hmi_ctrl = userdata; -+ switch_mode(hmi_ctrl, hmi_ctrl->layout_mode); -+} -+ -+static void -+set_notification_configure_surface(struct ivi_layout_surface *ivisurf, -+ void *userdata) -+{ -+ (void)ivisurf; -+ struct hmi_controller* hmi_ctrl = userdata; -+ switch_mode(hmi_ctrl, hmi_ctrl->layout_mode); -+} -+ -+/** -+ * A hmi_controller used 4 layers to manage surfaces. The IDs of corresponding layer -+ * are defined in weston.ini. Default scene graph of layers are initialized in -+ * hmi_controller_create -+ */ -+static struct hmi_server_setting * -+hmi_server_setting_create(void) -+{ -+ struct hmi_server_setting* setting = MEM_ALLOC(sizeof(*setting)); -+ -+ struct weston_config *config = NULL; -+ config = weston_config_parse("weston.ini"); -+ -+ struct weston_config_section *shellSection = NULL; -+ shellSection = weston_config_get_section(config, "ivi-shell", NULL, NULL); -+ -+ weston_config_section_get_uint( -+ shellSection, "base-layer-id", &setting->base_layer_id, 1000); -+ -+ weston_config_section_get_uint( -+ shellSection, "workspace-background-layer-id", &setting->workspace_background_layer_id, 2000); -+ -+ weston_config_section_get_uint( -+ shellSection, "workspace-layer-id", &setting->workspace_layer_id, 3000); -+ -+ weston_config_section_get_uint( -+ shellSection, "application-layer-id", &setting->application_layer_id, 4000); -+ -+ setting->panel_height = 70; -+ -+ weston_config_destroy(config); -+ -+ return setting; -+} -+ -+/** -+ * This is a starting method called from module_init. -+ * This sets up scene graph of layers; base, application, workspace background, -+ * and workspace. These layers are created/added to screen in create_layer -+ * -+ * base: to group surfaces of panel and background -+ * application: to group surfaces of ivi_applications -+ * workspace background: to group a surface of background in workspace -+ * workspace: to group surfaces for launching ivi_applications -+ * -+ * Layers of workspace background and workspace is set to invisible at first. -+ * The properties of it is updated with animation when ivi_hmi_controller_home is -+ * requested. -+ */ -+static struct hmi_controller * -+hmi_controller_create(struct weston_compositor *ec) -+{ -+ struct ivi_layout_screen **ppScreen = NULL; -+ struct ivi_layout_screen *iviscrn = NULL; -+ int32_t screen_length = 0; -+ int32_t screen_width = 0; -+ int32_t screen_height = 0; -+ int32_t ret = 0; -+ struct link_layer *tmp_link_layer = NULL; -+ -+ struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl)); -+ wl_array_init(&hmi_ctrl->ui_widgets); -+ hmi_ctrl->layout_mode = IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING; -+ hmi_ctrl->hmi_setting = hmi_server_setting_create(); -+ -+ ivi_layout_getScreens(&screen_length, &ppScreen); -+ -+ iviscrn = ppScreen[0]; -+ -+ ivi_layout_getScreenResolution(iviscrn, &screen_width, &screen_height); -+ assert(!ret); -+ -+ /* init base layer*/ -+ hmi_ctrl->base_layer.x = 0; -+ hmi_ctrl->base_layer.y = 0; -+ hmi_ctrl->base_layer.width = screen_width; -+ hmi_ctrl->base_layer.height = screen_height; -+ hmi_ctrl->base_layer.id_layer = hmi_ctrl->hmi_setting->base_layer_id; -+ -+ create_layer(iviscrn, &hmi_ctrl->base_layer); -+ -+ int32_t panel_height = hmi_ctrl->hmi_setting->panel_height; -+ -+ -+ /* init application layer */ -+ hmi_ctrl->application_layer.x = 0; -+ hmi_ctrl->application_layer.y = 0; -+ hmi_ctrl->application_layer.width = screen_width; -+ hmi_ctrl->application_layer.height = screen_height - panel_height; -+ hmi_ctrl->application_layer.id_layer = hmi_ctrl->hmi_setting->application_layer_id; -+ -+ create_layer(iviscrn, &hmi_ctrl->application_layer); -+ -+ /* init workspace background layer */ -+ hmi_ctrl->workspace_background_layer.x = 0; -+ hmi_ctrl->workspace_background_layer.y = 0; -+ hmi_ctrl->workspace_background_layer.width = screen_width; -+ hmi_ctrl->workspace_background_layer.height = screen_height - panel_height; -+ -+ hmi_ctrl->workspace_background_layer.id_layer = -+ hmi_ctrl->hmi_setting->workspace_background_layer_id; -+ -+ create_layer(iviscrn, &hmi_ctrl->workspace_background_layer); -+ ivi_layout_layerSetOpacity(hmi_ctrl->workspace_background_layer.ivilayer, 0); -+ ivi_layout_layerSetVisibility(hmi_ctrl->workspace_background_layer.ivilayer, 0); -+ -+ /* init workspace layer */ -+ hmi_ctrl->workspace_layer.x = hmi_ctrl->workspace_background_layer.x; -+ hmi_ctrl->workspace_layer.y = hmi_ctrl->workspace_background_layer.y; -+ hmi_ctrl->workspace_layer.width = hmi_ctrl->workspace_background_layer.width; -+ hmi_ctrl->workspace_layer.height = hmi_ctrl->workspace_background_layer.height; -+ hmi_ctrl->workspace_layer.id_layer = hmi_ctrl->hmi_setting->workspace_layer_id; -+ -+ create_layer(iviscrn, &hmi_ctrl->workspace_layer); -+ ivi_layout_layerSetOpacity(hmi_ctrl->workspace_layer.ivilayer, 0); -+ ivi_layout_layerSetVisibility(hmi_ctrl->workspace_layer.ivilayer, 0); -+ -+ /* set up animation to workspace background and workspace */ -+ hmi_ctrl->anima_set = animation_set_create(ec); -+ -+ wl_list_init(&hmi_ctrl->workspace_fade.layer_list); -+ tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer)); -+ tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer; -+ wl_list_insert(&hmi_ctrl->workspace_fade.layer_list, &tmp_link_layer->link); -+ tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer)); -+ tmp_link_layer->layout_layer = hmi_ctrl->workspace_background_layer.ivilayer; -+ wl_list_insert(&hmi_ctrl->workspace_fade.layer_list, &tmp_link_layer->link); -+ hmi_ctrl->workspace_fade.anima_set = hmi_ctrl->anima_set; -+ -+ ivi_layout_addNotificationCreateSurface(set_notification_create_surface, hmi_ctrl); -+ ivi_layout_addNotificationRemoveSurface(set_notification_remove_surface, hmi_ctrl); -+ ivi_layout_addNotificationConfigureSurface(set_notification_configure_surface, hmi_ctrl); -+ -+ free(ppScreen); -+ ppScreen = NULL; -+ -+ return hmi_ctrl; -+} -+ -+/** -+ * Implementations of ivi-hmi-controller.xml -+ */ -+ -+/** -+ * A surface drawing background is identified by id_surface. -+ * Properties of the surface is set by using ivi_layout APIs according to -+ * the scene graph of UI defined in hmi_controller_create. -+ * -+ * UI layer is used to add this surface. -+ */ -+static void -+ivi_hmi_controller_set_background(struct wl_resource *resource, -+ uint32_t id_surface) -+ -+{ -+ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); -+ struct ivi_layout_surface *ivisurf = NULL; -+ struct ivi_layout_layer *ivilayer = hmi_ctrl->base_layer.ivilayer; -+ const int32_t dstx = hmi_ctrl->application_layer.x; -+ const int32_t dsty = hmi_ctrl->application_layer.y; -+ const int32_t width = hmi_ctrl->application_layer.width; -+ const int32_t height = hmi_ctrl->application_layer.height; -+ int32_t ret = 0; -+ -+ uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets, -+ sizeof(*add_surface_id)); -+ *add_surface_id = id_surface; -+ -+ ivisurf = ivi_layout_getSurfaceFromId(id_surface); -+ assert(ivisurf != NULL); -+ -+ ret = ivi_layout_layerAddSurface(ivilayer, ivisurf); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, -+ dstx, dsty, width, height); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -+ assert(!ret); -+ -+ ivi_layout_commitChanges(); -+} -+ -+/** -+ * A surface drawing panel is identified by id_surface. -+ * Properties of the surface is set by using ivi_layout APIs according to -+ * the scene graph of UI defined in hmi_controller_create. -+ * -+ * UI layer is used to add this surface. -+ */ -+static void -+ivi_hmi_controller_set_panel(struct wl_resource *resource, -+ uint32_t id_surface) -+{ -+ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); -+ struct ivi_layout_surface *ivisurf = NULL; -+ struct ivi_layout_layer *ivilayer = hmi_ctrl->base_layer.ivilayer; -+ const int32_t width = hmi_ctrl->base_layer.width; -+ int32_t ret = 0; -+ -+ uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets, -+ sizeof(*add_surface_id)); -+ *add_surface_id = id_surface; -+ -+ ivisurf = ivi_layout_getSurfaceFromId(id_surface); -+ assert(ivisurf != NULL); -+ -+ ret = ivi_layout_layerAddSurface(ivilayer, ivisurf); -+ assert(!ret); -+ int32_t panel_height = hmi_ctrl->hmi_setting->panel_height; -+ const int32_t dstx = 0; -+ const int32_t dsty = hmi_ctrl->base_layer.height - panel_height; -+ -+ ret = ivi_layout_surfaceSetDestinationRectangle( -+ ivisurf, dstx, dsty, width, panel_height); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -+ assert(!ret); -+ -+ ivi_layout_commitChanges(); -+} -+ -+/** -+ * A surface drawing buttons in panel is identified by id_surface. It can set -+ * several buttons. Properties of the surface is set by using ivi_layout -+ * APIs according to the scene graph of UI defined in hmi_controller_create. -+ * Additionally, the position of it is shifted to right when new one is requested. -+ * -+ * UI layer is used to add these surfaces. -+ */ -+static void -+ivi_hmi_controller_set_button(struct wl_resource *resource, -+ uint32_t id_surface, int32_t number) -+{ -+ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); -+ struct ivi_layout_surface *ivisurf = NULL; -+ struct ivi_layout_layer *ivilayer = hmi_ctrl->base_layer.ivilayer; -+ const int32_t width = 48; -+ const int32_t height = 48; -+ int32_t ret = 0; -+ -+ uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets, -+ sizeof(*add_surface_id)); -+ *add_surface_id = id_surface; -+ -+ ivisurf = ivi_layout_getSurfaceFromId(id_surface); -+ assert(ivisurf != NULL); -+ -+ ret = ivi_layout_layerAddSurface(ivilayer, ivisurf); -+ assert(!ret); -+ -+ int32_t panel_height = hmi_ctrl->hmi_setting->panel_height; -+ -+ const int32_t dstx = (60 * number) + 15; -+ const int32_t dsty = (hmi_ctrl->base_layer.height - panel_height) + 5; -+ -+ ret = ivi_layout_surfaceSetDestinationRectangle( -+ ivisurf,dstx, dsty, width, height); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -+ assert(!ret); -+ -+ ivi_layout_commitChanges(); -+} -+ -+/** -+ * A surface drawing home button in panel is identified by id_surface. -+ * Properties of the surface is set by using ivi_layout APIs according to -+ * the scene graph of UI defined in hmi_controller_create. -+ * -+ * UI layer is used to add these surfaces. -+ */ -+static void -+ivi_hmi_controller_set_home_button(struct wl_resource *resource, -+ uint32_t id_surface) -+{ -+ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); -+ struct ivi_layout_surface *ivisurf = NULL; -+ struct ivi_layout_layer *ivilayer = hmi_ctrl->base_layer.ivilayer; -+ int32_t ret = 0; -+ int32_t size = 48; -+ int32_t panel_height = hmi_ctrl->hmi_setting->panel_height; -+ const int32_t dstx = (hmi_ctrl->base_layer.width - size) / 2; -+ const int32_t dsty = (hmi_ctrl->base_layer.height - panel_height) + 5; -+ -+ uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets, -+ sizeof(*add_surface_id)); -+ *add_surface_id = id_surface; -+ -+ ivisurf = ivi_layout_getSurfaceFromId(id_surface); -+ assert(ivisurf != NULL); -+ -+ ret = ivi_layout_layerAddSurface(ivilayer, ivisurf); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetDestinationRectangle( -+ ivisurf, dstx, dsty, size, size); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -+ assert(!ret); -+ -+ ivi_layout_commitChanges(); -+ hmi_ctrl->is_initialized = 1; -+} -+ -+/** -+ * A surface drawing background of workspace is identified by id_surface. -+ * Properties of the surface is set by using ivi_layout APIs according to -+ * the scene graph of UI defined in hmi_controller_create. -+ * -+ * A layer of workspace_background is used to add this surface. -+ */ -+static void -+ivi_hmi_controller_set_workspacebackground(struct wl_resource *resource, -+ uint32_t id_surface) -+{ -+ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); -+ struct ivi_layout_surface *ivisurf = NULL; -+ struct ivi_layout_layer *ivilayer = NULL; -+ ivilayer = hmi_ctrl->workspace_background_layer.ivilayer; -+ -+ uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets, -+ sizeof(*add_surface_id)); -+ *add_surface_id = id_surface; -+ -+ const int32_t width = hmi_ctrl->workspace_background_layer.width; -+ const int32_t height = hmi_ctrl->workspace_background_layer.height; -+ int32_t ret = 0; -+ -+ ivisurf = ivi_layout_getSurfaceFromId(id_surface); -+ assert(ivisurf != NULL); -+ -+ ret = ivi_layout_layerAddSurface(ivilayer, ivisurf); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, -+ 0, 0, width, height); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -+ assert(!ret); -+ -+ ivi_layout_commitChanges(); -+} -+ -+/** -+ * A list of surfaces drawing launchers in workspace is identified by id_surfaces. -+ * Properties of the surface is set by using ivi_layout APIs according to -+ * the scene graph of UI defined in hmi_controller_create. -+ * -+ * The workspace can have several pages to group surfaces of launcher. Each call -+ * of this interface increments a number of page to add a group of surfaces -+ */ -+static void -+ivi_hmi_controller_add_launchers(struct wl_resource *resource, -+ int32_t icon_size) -+{ -+ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); -+ struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer; -+ int32_t minspace_x = 10; -+ int32_t minspace_y = minspace_x; -+ -+ int32_t width = hmi_ctrl->workspace_layer.width; -+ int32_t height = hmi_ctrl->workspace_layer.height; -+ -+ int32_t x_count = (width - minspace_x) / (minspace_x + icon_size); -+ int32_t space_x = (int32_t)((width - x_count * icon_size) / (1.0 + x_count)); -+ float fcell_size_x = icon_size + space_x; -+ -+ int32_t y_count = (height - minspace_y) / (minspace_y + icon_size); -+ int32_t space_y = (int32_t)((height - y_count * icon_size) / (1.0 + y_count)); -+ float fcell_size_y = icon_size + space_y; -+ -+ if (0 == x_count) { -+ x_count = 1; -+ } -+ -+ if (0 == y_count) { -+ y_count = 1; -+ } -+ -+ struct weston_config *config = weston_config_parse("weston.ini"); -+ if (!config) { -+ return; -+ } -+ -+ struct weston_config_section *section = weston_config_get_section(config, "ivi-shell", NULL, NULL); -+ if (!section) { -+ return; -+ } -+ -+ const char *name = NULL; -+ int launcher_count = 0; -+ struct wl_array launchers; -+ wl_array_init(&launchers); -+ -+ while (weston_config_next_section(config, §ion, &name)) { -+ uint32_t surfaceid = 0; -+ uint32_t workspaceid = 0; -+ if (0 != strcmp(name, "ivi-launcher")) { -+ continue; -+ } -+ -+ if (0 != weston_config_section_get_uint(section, "icon-id", &surfaceid, 0)) { -+ continue; -+ } -+ -+ if (0 != weston_config_section_get_uint(section, "workspace-id", &workspaceid, 0)) { -+ continue; -+ } -+ -+ struct launcher_info *info = wl_array_add(&launchers, sizeof(*info)); -+ -+ if (info) { -+ info->surface_id = surfaceid; -+ info->workspace_id = workspaceid; -+ info->index = launcher_count; -+ ++launcher_count; -+ } -+ } -+ -+ qsort(launchers.data, launcher_count, sizeof(struct launcher_info), compare_launcher_info); -+ -+ int32_t nx = 0; -+ int32_t ny = 0; -+ int32_t prev = -1; -+ struct launcher_info *data = NULL; -+ wl_array_for_each(data, &launchers) -+ { -+ uint32_t *add_surface_id = wl_array_add(&hmi_ctrl->ui_widgets, -+ sizeof(*add_surface_id)); -+ *add_surface_id = data->surface_id; -+ -+ if (0 > prev || (uint32_t)prev != data->workspace_id) { -+ nx = 0; -+ ny = 0; -+ prev = data->workspace_id; -+ -+ if (0 <= prev) { -+ hmi_ctrl->workspace_count++; -+ } -+ } -+ -+ if (y_count == ny) { -+ ny = 0; -+ hmi_ctrl->workspace_count++; -+ } -+ -+ int32_t x = nx * fcell_size_x + (hmi_ctrl->workspace_count - 1) * width + space_x; -+ int32_t y = ny * fcell_size_y + space_y; -+ -+ struct ivi_layout_surface* layout_surface = NULL; -+ layout_surface = ivi_layout_getSurfaceFromId(data->surface_id); -+ assert(layout_surface); -+ -+ int32_t ret = 0; -+ ret = ivi_layout_layerAddSurface(layer, layout_surface); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetDestinationRectangle( -+ layout_surface, x, y, icon_size, icon_size); -+ assert(!ret); -+ -+ ret = ivi_layout_surfaceSetVisibility(layout_surface, 1); -+ assert(!ret); -+ -+ nx++; -+ -+ if (x_count == nx) { -+ ny++; -+ nx = 0; -+ } -+ } -+ -+ wl_array_release(&launchers); -+ weston_config_destroy(config); -+ ivi_layout_commitChanges(); -+} -+ -+static void -+ivi_hmi_controller_UI_ready(struct wl_client *client, -+ struct wl_resource *resource) -+{ -+ struct setting { -+ uint32_t background_id; -+ uint32_t panel_id; -+ uint32_t tiling_id; -+ uint32_t sidebyside_id; -+ uint32_t fullscreen_id; -+ uint32_t random_id; -+ uint32_t home_id; -+ uint32_t workspace_background_id; -+ }; -+ -+ struct config_command { -+ char *key; -+ void *dest; -+ }; -+ -+ struct weston_config *config = NULL; -+ struct weston_config_section *section = NULL; -+ struct setting dest; -+ int result = 0; -+ int i = 0; -+ -+ const struct config_command uint_commands[] = { -+ { "background-id", &dest.background_id }, -+ { "panel-id", &dest.panel_id }, -+ { "tiling-id", &dest.tiling_id }, -+ { "sidebyside-id", &dest.sidebyside_id }, -+ { "fullscreen-id", &dest.fullscreen_id }, -+ { "random-id", &dest.random_id }, -+ { "home-id", &dest.home_id }, -+ { "workspace-background-id", &dest.workspace_background_id }, -+ { NULL, NULL } -+ }; -+ -+ config = weston_config_parse("weston.ini"); -+ section = weston_config_get_section(config, "ivi-shell", NULL, NULL); -+ -+ for (i = 0; -1 != result; ++i) -+ { -+ const struct config_command *command = &uint_commands[i]; -+ -+ if (!command->key) -+ { -+ break; -+ } -+ -+ if (weston_config_section_get_uint( -+ section, command->key, (uint32_t *)command->dest, 0) != 0) -+ { -+ result = -1; -+ } -+ } -+ -+ if (-1 != result) -+ { -+ ivi_hmi_controller_set_background(resource, dest.background_id); -+ ivi_hmi_controller_set_panel(resource, dest.panel_id); -+ ivi_hmi_controller_set_button(resource, dest.tiling_id, 0); -+ ivi_hmi_controller_set_button(resource, dest.sidebyside_id, 1); -+ ivi_hmi_controller_set_button(resource, dest.fullscreen_id, 2); -+ ivi_hmi_controller_set_button(resource, dest.random_id, 3); -+ ivi_hmi_controller_set_home_button(resource, dest.home_id); -+ ivi_hmi_controller_set_workspacebackground(resource, dest.workspace_background_id); -+ } -+ -+ weston_config_destroy(config); -+ -+ ivi_hmi_controller_add_launchers(resource, 256); -+} -+ -+/** -+ * Implementation of request and event of ivi_hmi_controller_workspace_control -+ * and controlling workspace. -+ * -+ * When motion of input is detected in a surface of workspace background, -+ * ivi_hmi_controller_workspace_control shall be invoked and to start controlling of -+ * workspace. The workspace has several pages to show several groups of applications. -+ * The workspace is slid by using ivi-layout to select a a page in layer_set_pos -+ * according to motion. When motion finished, e.g. touch up detected, control is -+ * terminated and event:ivi_hmi_controller_workspace_control is notified. -+ */ -+struct pointer_grab { -+ struct weston_pointer_grab grab; -+ struct ivi_layout_layer *layer; -+ struct wl_resource *resource; -+}; -+ -+struct touch_grab { -+ struct weston_touch_grab grab; -+ struct ivi_layout_layer *layer; -+ struct wl_resource *resource; -+}; -+ -+struct move_grab { -+ wl_fixed_t dst[2]; -+ wl_fixed_t rgn[2][2]; -+ double v[2]; -+ struct timespec start_time; -+ struct timespec pre_time; -+ wl_fixed_t start_pos[2]; -+ wl_fixed_t pos[2]; -+ int32_t is_moved; -+}; -+ -+struct pointer_move_grab { -+ struct pointer_grab base; -+ struct move_grab move; -+}; -+ -+struct touch_move_grab { -+ struct touch_grab base; -+ struct move_grab move; -+ int32_t is_active; -+}; -+ -+static void -+pointer_grab_start(struct pointer_grab *grab, -+ struct ivi_layout_layer *layer, -+ const struct weston_pointer_grab_interface *interface, -+ struct weston_pointer *pointer) -+{ -+ grab->grab.interface = interface; -+ grab->layer = layer; -+ weston_pointer_start_grab(pointer, &grab->grab); -+} -+ -+static void -+touch_grab_start(struct touch_grab *grab, -+ struct ivi_layout_layer *layer, -+ const struct weston_touch_grab_interface *interface, -+ struct weston_touch* touch) -+{ -+ grab->grab.interface = interface; -+ grab->layer = layer; -+ weston_touch_start_grab(touch, &grab->grab); -+} -+ -+static int32_t -+range_val(int32_t val, int32_t min, int32_t max) -+{ -+ if (val < min) { -+ return min; -+ } -+ -+ if (max < val) { -+ return max; -+ } -+ -+ return val; -+} -+ -+static void -+hmi_controller_move_animation_destroy(struct hmi_controller_animation *animation) -+{ -+ struct move_animation_user_data *user_data = animation->user_data; -+ if (animation == &user_data->hmi_ctrl->workspace_swipe_animation->base) { -+ user_data->hmi_ctrl->workspace_swipe_animation = NULL; -+ } -+ -+ animation_set_remove_animation(user_data->anima_set, animation); -+ free(animation->user_data); -+ animation->user_data = NULL; -+} -+ -+static void -+move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource, -+ wl_fixed_t grab_x, struct ivi_layout_layer *layer) -+{ -+ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); -+ int32_t width = hmi_ctrl->workspace_background_layer.width; -+ -+ struct timespec time = {0}; -+ clock_gettime(CLOCK_MONOTONIC, &time); -+ -+ double grab_time = 1e+3 * (time.tv_sec - move->start_time.tv_sec) + -+ 1e-6 * (time.tv_nsec - move->start_time.tv_nsec); -+ -+ double from_motion_time = 1e+3 * (time.tv_sec - move->pre_time.tv_sec) + -+ 1e-6 * (time.tv_nsec - move->pre_time.tv_nsec); -+ -+ double pointer_v = move->v[0]; -+ -+ if (200 < from_motion_time) { -+ pointer_v = 0.0; -+ } -+ -+ int32_t is_flick = grab_time < 400 && -+ 0.4 < fabs(pointer_v); -+ -+ int32_t pos[2] = {0}; -+ ivi_layout_layerGetPosition(layer, pos); -+ -+ int page_no = 0; -+ -+ if (is_flick) { -+ int orgx = wl_fixed_to_int(move->dst[0] + grab_x); -+ page_no = (-orgx + width / 2) / width; -+ -+ if (pointer_v < 0.0) { -+ page_no++; -+ }else { -+ page_no--; -+ } -+ }else { -+ page_no = (-pos[0] + width / 2) / width; -+ } -+ -+ page_no = range_val(page_no, 0, hmi_ctrl->workspace_count - 1); -+ double end_pos = -page_no * width; -+ -+ double dst = fabs(end_pos - pos[0]); -+ double max_time = 0.5 * 1e+3; -+ double v = dst / max_time; -+ -+ double vmin = 1000 * 1e-3; -+ if (v < vmin ) { -+ v = vmin; -+ } -+ -+ double v0 = 0.0; -+ if (pos[0] < end_pos) { -+ v0 = v; -+ } else { -+ v0 = -v; -+ } -+ -+ struct move_animation_user_data *animation_user_data = NULL; -+ animation_user_data = MEM_ALLOC(sizeof(*animation_user_data)); -+ animation_user_data->layer = layer; -+ animation_user_data->anima_set = hmi_ctrl->anima_set; -+ animation_user_data->hmi_ctrl = hmi_ctrl; -+ -+ struct hmi_controller_animation_move* animation = NULL; -+ animation = hmi_controller_animation_move_create( -+ pos[0], end_pos, v0, v0, -+ (hmi_controller_animation_frame_user_func)hmi_controller_anima_move_user_frame, -+ animation_user_data, hmi_controller_move_animation_destroy); -+ -+ hmi_ctrl->workspace_swipe_animation = animation; -+ animation_set_add_animation(hmi_ctrl->anima_set, &animation->base); -+ -+ ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved); -+} -+ -+static void -+pointer_move_workspace_grab_end(struct pointer_grab *grab) -+{ -+ struct pointer_move_grab *pnt_move_grab = (struct pointer_move_grab *) grab; -+ struct ivi_layout_layer *layer = pnt_move_grab->base.layer; -+ -+ move_workspace_grab_end(&pnt_move_grab->move, grab->resource, -+ grab->grab.pointer->grab_x, layer); -+ -+ weston_pointer_end_grab(grab->grab.pointer); -+} -+ -+static void -+touch_move_workspace_grab_end(struct touch_grab *grab) -+{ -+ struct touch_move_grab *tch_move_grab = (struct touch_move_grab *) grab; -+ struct ivi_layout_layer *layer = tch_move_grab->base.layer; -+ -+ move_workspace_grab_end(&tch_move_grab->move, grab->resource, -+ grab->grab.touch->grab_x, layer); -+ -+ weston_touch_end_grab(grab->grab.touch); -+} -+ -+static void -+pointer_noop_grab_focus(struct weston_pointer_grab *grab) -+{ -+} -+ -+static void -+move_grab_update(struct move_grab *move, wl_fixed_t pointer[2]) -+{ -+ struct timespec timestamp = {0}; -+ clock_gettime(CLOCK_MONOTONIC, ×tamp); -+ -+ double dt = (1e+3 * (timestamp.tv_sec - move->pre_time.tv_sec) + -+ 1e-6 * (timestamp.tv_nsec - move->pre_time.tv_nsec)); -+ -+ if (dt < 1e-6) { -+ dt = 1e-6; -+ } -+ -+ move->pre_time = timestamp; -+ -+ int32_t ii = 0; -+ for (ii = 0; ii < 2; ii++) { -+ wl_fixed_t prepos = move->pos[ii]; -+ move->pos[ii] = pointer[ii] + move->dst[ii]; -+ -+ if (move->pos[ii] < move->rgn[0][ii]) { -+ move->pos[ii] = move->rgn[0][ii]; -+ move->dst[ii] = move->pos[ii] - pointer[ii]; -+ } else if (move->rgn[1][ii] < move->pos[ii]) { -+ move->pos[ii] = move->rgn[1][ii]; -+ move->dst[ii] = move->pos[ii] - pointer[ii]; -+ } -+ -+ move->v[ii] = wl_fixed_to_double(move->pos[ii] - prepos) / dt; -+ -+ if (!move->is_moved && -+ 0 < wl_fixed_to_int(move->pos[ii] - move->start_pos[ii])) { -+ move->is_moved = 1; -+ } -+ } -+} -+ -+static void -+layer_set_pos(struct ivi_layout_layer *layer, wl_fixed_t pos[2]) -+{ -+ int32_t layout_pos[2] = {0}; -+ layout_pos[0] = wl_fixed_to_int(pos[0]); -+ layout_pos[1] = wl_fixed_to_int(pos[1]); -+ ivi_layout_layerSetPosition(layer, layout_pos); -+ ivi_layout_commitChanges(); -+} -+ -+static void -+pointer_move_grab_motion(struct weston_pointer_grab *grab, uint32_t time, -+ wl_fixed_t x, wl_fixed_t y) -+{ -+ struct pointer_move_grab *pnt_move_grab = (struct pointer_move_grab *) grab; -+ wl_fixed_t pointer_pos[2] = {x, y}; -+ move_grab_update(&pnt_move_grab->move, pointer_pos); -+ layer_set_pos(pnt_move_grab->base.layer, pnt_move_grab->move.pos); -+ weston_pointer_move(pnt_move_grab->base.grab.pointer, x, y); -+} -+ -+static void -+touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time, -+ int touch_id, wl_fixed_t x, wl_fixed_t y) -+{ -+ struct touch_move_grab *tch_move_grab = (struct touch_move_grab *) grab; -+ -+ if (!tch_move_grab->is_active) { -+ return; -+ } -+ -+ wl_fixed_t pointer_pos[2] = {grab->touch->grab_x, grab->touch->grab_y}; -+ move_grab_update(&tch_move_grab->move, pointer_pos); -+ layer_set_pos(tch_move_grab->base.layer, tch_move_grab->move.pos); -+} -+ -+static void -+pointer_move_workspace_grab_button(struct weston_pointer_grab *grab, -+ uint32_t time, uint32_t button, -+ uint32_t state_w) -+{ -+ if (BTN_LEFT == button && -+ WL_POINTER_BUTTON_STATE_RELEASED == state_w) { -+ struct pointer_grab *pg = (struct pointer_grab *)grab; -+ pointer_move_workspace_grab_end(pg); -+ free(grab); -+ } -+} -+ -+static void -+touch_nope_grab_down(struct weston_touch_grab *grab, uint32_t time, -+ int touch_id, wl_fixed_t sx, wl_fixed_t sy) -+{ -+} -+ -+static void -+touch_move_workspace_grab_up(struct weston_touch_grab *grab, uint32_t time, int touch_id) -+{ -+ struct touch_move_grab *tch_move_grab = (struct touch_move_grab *)grab; -+ -+ if (0 == touch_id) { -+ tch_move_grab->is_active = 0; -+ } -+ -+ if (0 == grab->touch->num_tp) { -+ touch_move_workspace_grab_end(&tch_move_grab->base); -+ free(grab); -+ } -+} -+ -+static void -+pointer_move_workspace_grab_cancel(struct weston_pointer_grab *grab) -+{ -+ struct pointer_grab *pg = (struct pointer_grab *)grab; -+ pointer_move_workspace_grab_end(pg); -+ free(grab); -+} -+ -+static void -+touch_move_workspace_grab_cancel(struct weston_touch_grab *grab) -+{ -+ struct touch_grab *tg = (struct touch_grab *)grab; -+ touch_move_workspace_grab_end(tg); -+ free(grab); -+} -+ -+static const struct weston_pointer_grab_interface pointer_move_grab_workspace_interface = { -+ pointer_noop_grab_focus, -+ pointer_move_grab_motion, -+ pointer_move_workspace_grab_button, -+ pointer_move_workspace_grab_cancel -+}; -+ -+static const struct weston_touch_grab_interface touch_move_grab_workspace_interface = { -+ touch_nope_grab_down, -+ touch_move_workspace_grab_up, -+ touch_move_grab_motion, -+ touch_move_workspace_grab_cancel -+}; -+ -+enum HMI_GRAB_DEVICE -+{ -+ HMI_GRAB_DEVICE_NONE, -+ HMI_GRAB_DEVICE_POINTER, -+ HMI_GRAB_DEVICE_TOUCH -+}; -+ -+static enum HMI_GRAB_DEVICE -+get_hmi_grab_device(struct weston_seat *seat, int32_t serial) -+{ -+ if (seat->pointer && -+ seat->pointer->focus && -+ seat->pointer->button_count && -+ (int32_t)seat->pointer->grab_serial == serial) { -+ return HMI_GRAB_DEVICE_POINTER; -+ } -+ -+ if (seat->touch && -+ seat->touch->focus && -+ seat->touch->grab_serial) { -+ return HMI_GRAB_DEVICE_TOUCH; -+ } -+ -+ return HMI_GRAB_DEVICE_NONE; -+} -+ -+static void -+move_grab_init(struct move_grab* move, wl_fixed_t start_pos[2], -+ wl_fixed_t grab_pos[2], wl_fixed_t rgn[2][2], -+ struct wl_resource* resource) -+{ -+ clock_gettime(CLOCK_MONOTONIC, &move->start_time); -+ move->pre_time = move->start_time; -+ move->pos[0] = start_pos[0]; -+ move->pos[1] = start_pos[1]; -+ move->start_pos[0] = start_pos[0]; -+ move->start_pos[1] = start_pos[1]; -+ move->dst[0] = start_pos[0] - grab_pos[0]; -+ move->dst[1] = start_pos[1] - grab_pos[1]; -+ memcpy(move->rgn, rgn, sizeof(move->rgn)); -+} -+ -+static void -+move_grab_init_workspace(struct move_grab* move, -+ wl_fixed_t grab_x, wl_fixed_t grab_y, -+ struct wl_resource *resource) -+{ -+ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); -+ struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer; -+ int32_t workspace_count = hmi_ctrl->workspace_count; -+ int32_t workspace_width = hmi_ctrl->workspace_background_layer.width; -+ int32_t layer_pos[2] = {0}; -+ ivi_layout_layerGetPosition(layer, layer_pos); -+ -+ wl_fixed_t start_pos[2] = {0}; -+ start_pos[0] = wl_fixed_from_int(layer_pos[0]); -+ start_pos[1] = wl_fixed_from_int(layer_pos[1]); -+ -+ wl_fixed_t rgn[2][2] = {{0}}; -+ rgn[0][0] = wl_fixed_from_int(-workspace_width * (workspace_count - 1)); -+ -+ rgn[0][1] = wl_fixed_from_int(0); -+ rgn[1][0] = wl_fixed_from_int(0); -+ rgn[1][1] = wl_fixed_from_int(0); -+ -+ wl_fixed_t grab_pos[2] = {grab_x, grab_y}; -+ -+ move_grab_init(move, start_pos, grab_pos, rgn, resource); -+} -+ -+static struct pointer_move_grab * -+create_workspace_pointer_move(struct weston_pointer *pointer, struct wl_resource* resource) -+{ -+ struct pointer_move_grab *pnt_move_grab = MEM_ALLOC(sizeof(*pnt_move_grab)); -+ pnt_move_grab->base.resource = resource; -+ move_grab_init_workspace(&pnt_move_grab->move, pointer->grab_x, pointer->grab_y, resource); -+ return pnt_move_grab; -+} -+ -+static struct touch_move_grab * -+create_workspace_touch_move(struct weston_touch *touch, struct wl_resource* resource) -+{ -+ struct touch_move_grab *tch_move_grab = MEM_ALLOC(sizeof(*tch_move_grab)); -+ tch_move_grab->base.resource = resource; -+ tch_move_grab->is_active = 1; -+ move_grab_init_workspace(&tch_move_grab->move, touch->grab_x,touch->grab_y, resource); -+ return tch_move_grab; -+} -+ -+static void -+ivi_hmi_controller_workspace_control(struct wl_client *client, -+ struct wl_resource *resource, -+ struct wl_resource *seat_resource, -+ uint32_t serial) -+{ -+ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); -+ -+ if (hmi_ctrl->workspace_count < 2) { -+ return; -+ } -+ -+ struct weston_seat* seat = wl_resource_get_user_data(seat_resource); -+ enum HMI_GRAB_DEVICE device = get_hmi_grab_device(seat, serial); -+ -+ if (HMI_GRAB_DEVICE_POINTER != device && -+ HMI_GRAB_DEVICE_TOUCH != device) { -+ return; -+ } -+ -+ if (hmi_ctrl->workspace_swipe_animation) { -+ hmi_controller_animation_destroy(&hmi_ctrl->workspace_swipe_animation->base); -+ } -+ -+ struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer; -+ struct pointer_move_grab *pnt_move_grab = NULL; -+ struct touch_move_grab *tch_move_grab = NULL; -+ -+ switch (device) { -+ case HMI_GRAB_DEVICE_POINTER: -+ pnt_move_grab = create_workspace_pointer_move(seat->pointer, resource); -+ -+ pointer_grab_start( -+ &pnt_move_grab->base, layer, &pointer_move_grab_workspace_interface, -+ seat->pointer); -+ break; -+ -+ case HMI_GRAB_DEVICE_TOUCH: -+ tch_move_grab = create_workspace_touch_move(seat->touch, resource); -+ -+ touch_grab_start( -+ &tch_move_grab->base, layer, &touch_move_grab_workspace_interface, -+ seat->touch); -+ break; -+ -+ default: -+ break; -+ } -+} -+ -+/** -+ * Implementation of switch_mode -+ */ -+static void -+ivi_hmi_controller_switch_mode(struct wl_client *client, -+ struct wl_resource *resource, -+ uint32_t layout_mode) -+{ -+ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); -+ switch_mode(hmi_ctrl, layout_mode); -+} -+ -+/** -+ * Implementation of on/off displaying workspace and workspace background layers. -+ */ -+static void -+ivi_hmi_controller_home(struct wl_client *client, -+ struct wl_resource *resource, -+ uint32_t home) -+{ -+ struct hmi_controller *hmi_ctrl = wl_resource_get_user_data(resource); -+ -+ if ((IVI_HMI_CONTROLLER_HOME_ON == home && !hmi_ctrl->workspace_fade.isFadeIn) || -+ (IVI_HMI_CONTROLLER_HOME_OFF == home && hmi_ctrl->workspace_fade.isFadeIn)) { -+ -+ int32_t isFadeIn = !hmi_ctrl->workspace_fade.isFadeIn; -+ hmi_controller_fade_run(isFadeIn, &hmi_ctrl->workspace_fade); -+ } -+} -+ -+/** -+ * binding ivi-hmi-controller implementation -+ */ -+static const struct ivi_hmi_controller_interface ivi_hmi_controller_implementation = { -+ ivi_hmi_controller_UI_ready, -+ ivi_hmi_controller_workspace_control, -+ ivi_hmi_controller_switch_mode, -+ ivi_hmi_controller_home -+}; -+ -+static void -+unbind_hmi_controller(struct wl_resource *resource) -+{ -+} -+ -+static void -+bind_hmi_controller(struct wl_client *client, -+ void *data, uint32_t version, uint32_t id) -+{ -+ struct wl_resource *resource = NULL; -+ -+ resource = wl_resource_create( -+ client, &ivi_hmi_controller_interface, 1, id); -+ -+ wl_resource_set_implementation( -+ resource, &ivi_hmi_controller_implementation, -+ data, unbind_hmi_controller); -+} -+ -+static void -+launch_hmi_client(void *data) -+{ -+ /*Nothing to do here*/ -+} -+ -+/***************************************************************************** -+ * exported functions -+ ****************************************************************************/ -+ -+WL_EXPORT int -+module_init(struct weston_compositor *ec, -+ int *argc, char *argv[]) -+{ -+ struct hmi_controller *hmi_ctrl = hmi_controller_create(ec); -+ -+ if (wl_global_create(ec->wl_display, -+ &ivi_hmi_controller_interface, 1, -+ hmi_ctrl, bind_hmi_controller) == NULL) { -+ return -1; -+ } -+ -+ struct wl_event_loop *loop = wl_display_get_event_loop(ec->wl_display); -+ wl_event_loop_add_idle(loop, launch_hmi_client, ec); -+ -+ return 0; -+} --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0007-clients-a-reference-implementation-of-UI-client-how-.patch b/meta-ivi/recipes-graphics/wayland/weston/0007-clients-a-reference-implementation-of-UI-client-how-.patch deleted file mode 100644 index 8c7c2e4..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0007-clients-a-reference-implementation-of-UI-client-how-.patch +++ /dev/null @@ -1,1495 +0,0 @@ -From 7db20ce9615417c69a16628b1c98cae43e941c06 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Thu, 20 Mar 2014 09:28:52 +0900 -Subject: [PATCH 07/31] clients: a reference implementation of UI client how to - use ivi-hmi-controller. - -This is launched from hmi-controller by launch_hmi_client_process and invoke a -client process. - -The basic flow is as followed, -1/ process invoked -2/ read configuration from weston.ini. -3/ draw png file to surface according to configuration of weston.ini -4/ all parts of UI are ready. request "UI_ready" to draw UI. -5/ Enter event loop -6/ If a surface receives touch/pointer event, followings are invoked according - to type of event and surface -6-1/ If a surface to launch ivi_application receive touch up, it execs - ivi-application configured in weston.ini. -6-2/ If a surface to switch layout mode receive touch up, it sends a request, - ivi_hmi_controller_switch_mode, to hmi-controller. -6-3/ If a surface to show workspace having launchers, it sends a request, - ivi_hmi_controller_home, to hmi-controller. -6-4/ If touch down events happens in workspace, - ivi_hmi_controller_workspace_control is sent to slide workspace. - When control finished, event: ivi_hmi_controller_workspace_end_control - is received. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> - -data: add reference image files for weston-ivi-shell-user-interface - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - Makefile.am | 15 + - clients/ivi-shell-user-interface.c | 1332 ++++++++++++++++++++++++++++++++++++ - ivi-shell/hmi-controller.c | 41 +- - 3 files changed, 1385 insertions(+), 3 deletions(-) - create mode 100644 clients/ivi-shell-user-interface.c - -diff --git a/Makefile.am b/Makefile.am -index 9dd492b..ec6b721 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -361,6 +361,11 @@ libexec_PROGRAMS += \ - weston-keyboard \ - weston-simple-im - -+if ENABLE_IVI_SHELL -+libexec_PROGRAMS += \ -+ weston-ivi-shell-user-interface -+endif -+ - demo_clients = \ - weston-flower \ - weston-image \ -@@ -570,6 +575,16 @@ nodist_weston_desktop_shell_SOURCES = \ - weston_desktop_shell_LDADD = libtoytoolkit.la - weston_desktop_shell_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS) - -+if ENABLE_IVI_SHELL -+weston_ivi_shell_user_interface_SOURCES = clients/ivi-shell-user-interface.c -+nodist_weston_ivi_shell_user_interface_SOURCES = \ -+ protocol/ivi-hmi-controller-client-protocol.h \ -+ protocol/ivi-hmi-controller-protocol.c \ -+ protocol/ivi-application-protocol.c -+weston_ivi_shell_user_interface_LDADD = libtoytoolkit.la -+weston_ivi_shell_user_interface_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS) -+endif -+ - if BUILD_FULL_GL_CLIENTS - demo_clients += weston-gears - weston_gears_SOURCES = clients/gears.c -diff --git a/clients/ivi-shell-user-interface.c b/clients/ivi-shell-user-interface.c -new file mode 100644 -index 0000000..70b854b ---- /dev/null -+++ b/clients/ivi-shell-user-interface.c -@@ -0,0 +1,1332 @@ -+/* -+ * 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. -+ */ -+ -+#include <sys/wait.h> -+#include <unistd.h> -+#include <stdlib.h> -+#include <stdio.h> -+#include <string.h> -+#include <linux/input.h> -+#include <assert.h> -+#include <fcntl.h> -+#include <signal.h> -+#include <sys/mman.h> -+#include <getopt.h> -+#include <pthread.h> -+#include <wayland-cursor.h> -+#include "../shared/cairo-util.h" -+#include "../shared/config-parser.h" -+#include "ivi-application-client-protocol.h" -+#include "ivi-hmi-controller-client-protocol.h" -+ -+/** -+ * A reference implementation how to use ivi-hmi-controller interface to interact -+ * with hmi-controller. This is launched from hmi-controller by using -+ * hmi_client_start and create a pthread. -+ * -+ * The basic flow is as followed, -+ * 1/ create pthread -+ * 2/ read configuration from weston.ini. -+ * 3/ draw png file to surface according to configuration of weston.ini -+ * 4/ set up UI by using ivi-hmi-controller protocol -+ * 5/ Enter event loop -+ * 6/ If a surface receives touch/pointer event, followings are invoked according -+ * to type of event and surface -+ * 6-1/ If a surface to launch ivi_application receive touch up, it execs -+ * ivi-application configured in weston.ini. -+ * 6-2/ If a surface to switch layout mode receive touch up, it sends a request, -+ * ivi_hmi_controller_switch_mode, to hmi-controller. -+ * 6-3/ If a surface to show workspace having launchers, it sends a request, -+ * ivi_hmi_controller_home, to hmi-controller. -+ * 6-4/ If touch down events happens in workspace, -+ * ivi_hmi_controller_workspace_control is sent to slide workspace. -+ * When control finished, event: ivi_hmi_controller_workspace_end_control -+ * is received. -+ */ -+ -+/***************************************************************************** -+ * structure, globals -+ ****************************************************************************/ -+enum cursor_type { -+ CURSOR_BOTTOM_LEFT, -+ CURSOR_BOTTOM_RIGHT, -+ CURSOR_BOTTOM, -+ CURSOR_DRAGGING, -+ CURSOR_LEFT_PTR, -+ CURSOR_LEFT, -+ CURSOR_RIGHT, -+ CURSOR_TOP_LEFT, -+ CURSOR_TOP_RIGHT, -+ CURSOR_TOP, -+ CURSOR_IBEAM, -+ CURSOR_HAND1, -+ CURSOR_WATCH, -+ -+ CURSOR_BLANK -+}; -+struct wlContextCommon { -+ struct wl_display *wlDisplay; -+ struct wl_registry *wlRegistry; -+ struct wl_compositor *wlCompositor; -+ struct wl_shm *wlShm; -+ struct wl_seat *wlSeat; -+ struct wl_pointer *wlPointer; -+ struct wl_touch *wlTouch; -+ struct ivi_application *iviApplication; -+ struct ivi_hmi_controller *hmiCtrl; -+ struct hmi_homescreen_setting *hmi_setting; -+ struct wl_list *list_wlContextStruct; -+ struct wl_surface *enterSurface; -+ int32_t is_home_on; -+ struct wl_cursor_theme *cursor_theme; -+ struct wl_cursor **cursors; -+ struct wl_surface *pointer_surface; -+ enum cursor_type current_cursor; -+ uint32_t enter_serial; -+}; -+ -+struct wlContextStruct { -+ struct wlContextCommon cmm; -+ struct wl_surface *wlSurface; -+ struct wl_buffer *wlBuffer; -+ uint32_t formats; -+ cairo_surface_t *ctx_image; -+ void *data; -+ uint32_t id_surface; -+ struct wl_list link; -+}; -+ -+struct -+hmi_homescreen_srf { -+ uint32_t id; -+ char *filePath; -+ uint32_t color; -+}; -+ -+struct -+hmi_homescreen_workspace { -+ struct wl_array launcher_id_array; -+ struct wl_list link; -+}; -+ -+struct -+hmi_homescreen_launcher { -+ uint32_t icon_surface_id; -+ uint32_t workspace_id; -+ char* icon; -+ char* path; -+ struct wl_list link; -+}; -+ -+struct -+hmi_homescreen_setting { -+ struct hmi_homescreen_srf background; -+ struct hmi_homescreen_srf panel; -+ struct hmi_homescreen_srf tiling; -+ struct hmi_homescreen_srf sidebyside; -+ struct hmi_homescreen_srf fullscreen; -+ struct hmi_homescreen_srf random; -+ struct hmi_homescreen_srf home; -+ struct hmi_homescreen_srf workspace_background; -+ -+ struct wl_list workspace_list; -+ struct wl_list launcher_list; -+ -+ char *cursor_theme; -+ int32_t cursor_size; -+}; -+ -+volatile int gRun = 0; -+ -+static void * -+fail_on_null(void *p, size_t size, char* file, int32_t line) -+{ -+ if (size && !p) { -+ fprintf(stderr, "%s(%d) %zd: out of memory\n", file, line, size); -+ exit(EXIT_FAILURE); -+ } -+ -+ return p; -+} -+ -+static void * -+mem_alloc(size_t size, char* file, int32_t line) -+{ -+ return fail_on_null(calloc(1, size), size, file, line); -+} -+ -+#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__) -+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) -+ -+/***************************************************************************** -+ * Event Handler -+ ****************************************************************************/ -+ -+static void -+shm_format(void* data, struct wl_shm* pWlShm, uint32_t format) -+{ -+ struct wlContextStruct* pDsp = data; -+ pDsp->formats |= (1 << format); -+} -+ -+static struct wl_shm_listener shm_listenter = { -+ shm_format -+}; -+ -+static int32_t -+getIdOfWlSurface(struct wlContextCommon *pCtx, struct wl_surface *wlSurface) -+{ -+ if (NULL == pCtx || -+ NULL == wlSurface ) { -+ return 0; -+ } -+ -+ struct wlContextStruct* pWlCtxSt = NULL; -+ wl_list_for_each(pWlCtxSt, pCtx->list_wlContextStruct, link) { -+ if (pWlCtxSt->wlSurface == wlSurface) { -+ return pWlCtxSt->id_surface; -+ } -+ continue; -+ } -+ return -1; -+} -+ -+static void -+set_pointer_image(struct wlContextCommon *pCtx, uint32_t index) -+{ -+ if (!pCtx->wlPointer || -+ !pCtx->cursors) { -+ return; -+ } -+ -+ if (CURSOR_BLANK == pCtx->current_cursor) { -+ wl_pointer_set_cursor(pCtx->wlPointer, pCtx->enter_serial, -+ NULL, 0, 0); -+ return; -+ } -+ -+ struct wl_cursor *cursor = pCtx->cursors[pCtx->current_cursor]; -+ if (!cursor) { -+ return; -+ } -+ -+ if (cursor->image_count <= index) { -+ fprintf(stderr, "cursor index out of range\n"); -+ return; -+ } -+ -+ struct wl_cursor_image *image = cursor->images[index]; -+ struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); -+ -+ if (!buffer) { -+ return; -+ } -+ -+ wl_pointer_set_cursor(pCtx->wlPointer, pCtx->enter_serial, -+ pCtx->pointer_surface, -+ image->hotspot_x, image->hotspot_y); -+ -+ wl_surface_attach(pCtx->pointer_surface, buffer, 0, 0); -+ -+ wl_surface_damage(pCtx->pointer_surface, 0, 0, -+ image->width, image->height); -+ -+ wl_surface_commit(pCtx->pointer_surface); -+} -+ -+static void -+PointerHandleEnter(void* data, struct wl_pointer* wlPointer, uint32_t serial, -+ struct wl_surface* wlSurface, wl_fixed_t sx, wl_fixed_t sy) -+{ -+ (void)wlPointer; -+ (void)serial; -+ -+ struct wlContextCommon *pCtx = data; -+ pCtx->enter_serial = serial; -+ pCtx->enterSurface = wlSurface; -+ set_pointer_image(pCtx, 0); -+#ifdef _DEBUG -+ printf("ENTER PointerHandleEnter: x(%d), y(%d)\n", sx, sy); -+#endif -+} -+ -+static void -+PointerHandleLeave(void* data, struct wl_pointer* wlPointer, uint32_t serial, -+ struct wl_surface* wlSurface) -+{ -+ (void)wlPointer; -+ (void)wlSurface; -+ -+ struct wlContextCommon *pCtx = data; -+ pCtx->enterSurface = NULL; -+ -+#ifdef _DEBUG -+ printf("ENTER PointerHandleLeave: serial(%d)\n", serial); -+#endif -+} -+ -+static void -+PointerHandleMotion(void* data, struct wl_pointer* wlPointer, uint32_t time, -+ wl_fixed_t sx, wl_fixed_t sy) -+{ -+ (void)data; -+ (void)wlPointer; -+ (void)time; -+ -+#ifdef _DEBUG -+ printf("ENTER PointerHandleMotion: x(%d), y(%d)\n", gPointerX, gPointerY); -+#endif -+} -+ -+/** -+ * if a surface assigned as launcher receives touch-off event, invoking -+ * ivi-application which configured in weston.ini with path to binary. -+ */ -+extern char **environ; /*defied by libc */ -+ -+static pid_t execute_process(char* path, char *argv[]) -+{ -+ pid_t pid = fork(); -+ if (pid < 0) { -+ fprintf(stderr, "Failed to fork\n"); -+ } -+ -+ if (pid) { -+ return pid; -+ } -+ -+ if (-1 == execve(path, argv, environ)) { -+ fprintf(stderr, "Failed to execve %s\n", path); -+ exit(1); -+ } -+ -+ return pid; -+} -+ -+static int32_t -+launcher_button(uint32_t surfaceId, struct wl_list *launcher_list) -+{ -+ struct hmi_homescreen_launcher *launcher = NULL; -+ -+ wl_list_for_each(launcher, launcher_list, link) { -+ if (surfaceId != launcher->icon_surface_id) { -+ continue; -+ } -+ -+ char *argv[] = {NULL}; -+ execute_process(launcher->path, argv); -+ -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/** -+ * is-method to identify a surface set as launcher in workspace or workspace -+ * itself. This is-method is used to decide whether request; -+ * ivi_hmi_controller_workspace_control is sent or not. -+ */ -+static int32_t -+isWorkspaceSurface(uint32_t id, struct hmi_homescreen_setting *hmi_setting) -+{ -+ if (id == hmi_setting->workspace_background.id) { -+ return 1; -+ } -+ -+ struct hmi_homescreen_launcher *launcher = NULL; -+ wl_list_for_each(launcher, &hmi_setting->launcher_list, link) { -+ if (id == launcher->icon_surface_id) { -+ return 1; -+ } -+ } -+ -+ return 0; -+} -+ -+/** -+ * Decide which request is sent to hmi-controller -+ */ -+static void -+touch_up(struct ivi_hmi_controller *hmi_ctrl, uint32_t id_surface, -+ int32_t *is_home_on, struct hmi_homescreen_setting* hmi_setting) -+{ -+ if (launcher_button(id_surface, &hmi_setting->launcher_list)) { -+ *is_home_on = 0; -+ ivi_hmi_controller_home(hmi_ctrl, IVI_HMI_CONTROLLER_HOME_OFF); -+ } else if (id_surface == hmi_setting->tiling.id) { -+ ivi_hmi_controller_switch_mode( -+ hmi_ctrl, IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING); -+ } else if (id_surface == hmi_setting->sidebyside.id) { -+ ivi_hmi_controller_switch_mode( -+ hmi_ctrl, IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE); -+ } else if (id_surface == hmi_setting->fullscreen.id) { -+ ivi_hmi_controller_switch_mode( -+ hmi_ctrl, IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN); -+ } else if (id_surface == hmi_setting->random.id) { -+ ivi_hmi_controller_switch_mode( -+ hmi_ctrl, IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM); -+ } else if (id_surface == hmi_setting->home.id) { -+ *is_home_on = !(*is_home_on); -+ if (*is_home_on) { -+ ivi_hmi_controller_home(hmi_ctrl, IVI_HMI_CONTROLLER_HOME_ON); -+ } else { -+ ivi_hmi_controller_home(hmi_ctrl, IVI_HMI_CONTROLLER_HOME_OFF); -+ } -+ } -+} -+ -+/** -+ * Even handler of Pointer event. IVI system is usually manipulated by touch -+ * screen. However, some systems also have pointer device. -+ * Release is the same behavior as touch off -+ * Pressed is the same behavior as touch on -+ */ -+static void -+PointerHandleButton(void* data, struct wl_pointer* wlPointer, uint32_t serial, -+ uint32_t time, uint32_t button, uint32_t state) -+{ -+ (void)wlPointer; -+ (void)serial; -+ (void)time; -+ struct wlContextCommon *pCtx = data; -+ struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl; -+ -+ if (BTN_RIGHT == button) { -+ return; -+ } -+ -+ const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface); -+ -+ switch (state) { -+ case WL_POINTER_BUTTON_STATE_RELEASED: -+ touch_up(hmi_ctrl, id_surface, &pCtx->is_home_on, pCtx->hmi_setting); -+ break; -+ -+ case WL_POINTER_BUTTON_STATE_PRESSED: -+ -+ if (isWorkspaceSurface(id_surface, pCtx->hmi_setting)) { -+ ivi_hmi_controller_workspace_control(hmi_ctrl, pCtx->wlSeat, serial); -+ } -+ -+ break; -+ } -+#ifdef _DEBUG -+ printf("ENTER PointerHandleButton: button(%d), state(%d)\n", button, state); -+#endif -+} -+ -+static void -+PointerHandleAxis(void* data, struct wl_pointer* wlPointer, uint32_t time, -+ uint32_t axis, wl_fixed_t value) -+{ -+ (void)data; -+ (void)wlPointer; -+ (void)time; -+#ifdef _DEBUG -+ printf("ENTER PointerHandleAxis: axis(%d), value(%d)\n", axis, value); -+#endif -+} -+ -+static struct wl_pointer_listener pointer_listener = { -+ PointerHandleEnter, -+ PointerHandleLeave, -+ PointerHandleMotion, -+ PointerHandleButton, -+ PointerHandleAxis -+}; -+ -+/** -+ * Even handler of touch event -+ */ -+static void -+TouchHandleDown(void *data, struct wl_touch *wlTouch, uint32_t serial, uint32_t time, -+ struct wl_surface *surface, int32_t id, wl_fixed_t x_w, wl_fixed_t y_w) -+{ -+ struct wlContextCommon *pCtx = data; -+ struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl; -+ -+ if (0 == id){ -+ pCtx->enterSurface = surface; -+ } -+ -+ const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface); -+ -+ /** -+ * When touch down happens on surfaces of workspace, ask hmi-controller to start -+ * control workspace to select page of workspace. -+ * After sending seat to hmi-controller by ivi_hmi_controller_workspace_control, -+ * hmi-controller-homescreen doesn't receive any event till hmi-controller sends -+ * back it. -+ */ -+ if (isWorkspaceSurface(id_surface, pCtx->hmi_setting)) { -+ ivi_hmi_controller_workspace_control(hmi_ctrl, pCtx->wlSeat, serial); -+ } -+} -+ -+static void -+TouchHandleUp(void *data, struct wl_touch *wlTouch, uint32_t serial, uint32_t time, -+ int32_t id) -+{ -+ (void)serial; -+ (void)time; -+ struct wlContextCommon *pCtx = data; -+ struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl; -+ -+ const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface); -+ -+ /** -+ * triggering event according to touch-up happening on which surface. -+ */ -+ if (id == 0){ -+ touch_up(hmi_ctrl, id_surface, &pCtx->is_home_on, pCtx->hmi_setting); -+ } -+} -+ -+static void -+TouchHandleMotion(void *data, struct wl_touch *wlTouch, uint32_t time, -+ int32_t id, wl_fixed_t x_w, wl_fixed_t y_w) -+{ -+} -+ -+static void -+TouchHandleFrame(void *data, struct wl_touch *wlTouch) -+{ -+} -+ -+static void -+TouchHandleCancel(void *data, struct wl_touch *wlTouch) -+{ -+} -+ -+static struct wl_touch_listener touch_listener = { -+ TouchHandleDown, -+ TouchHandleUp, -+ TouchHandleMotion, -+ TouchHandleFrame, -+ TouchHandleCancel, -+}; -+ -+/** -+ * Handler of capabilities -+ */ -+static void -+seat_handle_capabilities(void* data, struct wl_seat* seat, uint32_t caps) -+{ -+ (void)seat; -+ struct wlContextCommon* p_wlCtx = (struct wlContextCommon*)data; -+ struct wl_seat* wlSeat = p_wlCtx->wlSeat; -+ struct wl_pointer* wlPointer = p_wlCtx->wlPointer; -+ struct wl_touch* wlTouch = p_wlCtx->wlTouch; -+ -+ if (p_wlCtx->hmi_setting->cursor_theme) { -+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wlPointer){ -+ wlPointer = wl_seat_get_pointer(wlSeat); -+ wl_pointer_set_user_data(wlPointer, data); -+ wl_pointer_add_listener(wlPointer, &pointer_listener, data); -+ } else -+ if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wlPointer){ -+ wl_pointer_destroy(wlPointer); -+ wlPointer = NULL; -+ } -+ p_wlCtx->wlPointer = wlPointer; -+ } -+ -+ if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !wlTouch){ -+ wlTouch = wl_seat_get_touch(wlSeat); -+ wl_touch_set_user_data(wlTouch, data); -+ wl_touch_add_listener(wlTouch, &touch_listener, data); -+ } else -+ if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && wlTouch){ -+ wl_touch_destroy(wlTouch); -+ wlTouch = NULL; -+ } -+ p_wlCtx->wlTouch = wlTouch; -+} -+ -+static struct wl_seat_listener seat_Listener = { -+ seat_handle_capabilities, -+}; -+ -+/** -+ * Registration of event -+ * This event is received when hmi-controller server finished controlling -+ * workspace. -+ */ -+static void -+ivi_hmi_controller_workspace_end_control(void *data, -+ struct ivi_hmi_controller *hmi_ctrl, -+ int32_t is_controlled) -+{ -+ if (is_controlled) { -+ return; -+ } -+ -+ struct wlContextCommon *pCtx = data; -+ const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface); -+ -+ /** -+ * During being controlled by hmi-controller, any input event is not -+ * notified. So when control ends with touch up, it invokes launcher -+ * if up event happens on a launcher surface. -+ * -+ */ -+ if (launcher_button(id_surface, &pCtx->hmi_setting->launcher_list)) { -+ pCtx->is_home_on = 0; -+ ivi_hmi_controller_home(hmi_ctrl, IVI_HMI_CONTROLLER_HOME_OFF); -+ } -+} -+ -+static const struct ivi_hmi_controller_listener hmi_controller_listener = { -+ ivi_hmi_controller_workspace_end_control -+}; -+ -+/** -+ * Registration of interfaces -+ */ -+static void -+registry_handle_global(void* data, struct wl_registry* registry, uint32_t name, -+ const char *interface, uint32_t version) -+{ -+ (void)version; -+ struct wlContextCommon* p_wlCtx = (struct wlContextCommon*)data; -+ -+ do { -+ if (!strcmp(interface, "wl_compositor")) { -+ p_wlCtx->wlCompositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1); -+ break; -+ } -+ if (!strcmp(interface, "wl_shm")) { -+ p_wlCtx->wlShm = wl_registry_bind(registry, name, &wl_shm_interface, 1); -+ wl_shm_add_listener(p_wlCtx->wlShm, &shm_listenter, p_wlCtx); -+ break; -+ } -+ if (!strcmp(interface, "wl_seat")) { -+ p_wlCtx->wlSeat = wl_registry_bind(registry, name, &wl_seat_interface, 1); -+ wl_seat_add_listener(p_wlCtx->wlSeat, &seat_Listener, data); -+ break; -+ } -+ if (!strcmp(interface, "ivi_application")) { -+ p_wlCtx->iviApplication = wl_registry_bind(registry, name, &ivi_application_interface, 1); -+ break; -+ } -+ if (!strcmp(interface, "ivi_hmi_controller")) { -+ p_wlCtx->hmiCtrl = wl_registry_bind(registry, name, &ivi_hmi_controller_interface, 1); -+ -+ if (p_wlCtx->hmiCtrl) { -+ ivi_hmi_controller_add_listener(p_wlCtx->hmiCtrl, &hmi_controller_listener, p_wlCtx); -+ } -+ break; -+ } -+ -+ } while(0); -+} -+ -+static const struct wl_registry_listener registry_listener = { -+ registry_handle_global, -+ NULL -+}; -+ -+static void -+frame_listener_func(void *data, struct wl_callback *callback, uint32_t time) -+{ -+ if (callback) { -+ wl_callback_destroy(callback); -+ } -+} -+ -+static const struct wl_callback_listener frame_listener = { -+ frame_listener_func -+}; -+ -+/* -+ * The following correspondences between file names and cursors was copied -+ * from: https://bugs.kde.org/attachment.cgi?id=67313 -+ */ -+static const char *bottom_left_corners[] = { -+ "bottom_left_corner", -+ "sw-resize", -+ "size_bdiag" -+}; -+ -+static const char *bottom_right_corners[] = { -+ "bottom_right_corner", -+ "se-resize", -+ "size_fdiag" -+}; -+ -+static const char *bottom_sides[] = { -+ "bottom_side", -+ "s-resize", -+ "size_ver" -+}; -+ -+static const char *grabbings[] = { -+ "grabbing", -+ "closedhand", -+ "208530c400c041818281048008011002" -+}; -+ -+static const char *left_ptrs[] = { -+ "left_ptr", -+ "default", -+ "top_left_arrow", -+ "left-arrow" -+}; -+ -+static const char *left_sides[] = { -+ "left_side", -+ "w-resize", -+ "size_hor" -+}; -+ -+static const char *right_sides[] = { -+ "right_side", -+ "e-resize", -+ "size_hor" -+}; -+ -+static const char *top_left_corners[] = { -+ "top_left_corner", -+ "nw-resize", -+ "size_fdiag" -+}; -+ -+static const char *top_right_corners[] = { -+ "top_right_corner", -+ "ne-resize", -+ "size_bdiag" -+}; -+ -+static const char *top_sides[] = { -+ "top_side", -+ "n-resize", -+ "size_ver" -+}; -+ -+static const char *xterms[] = { -+ "xterm", -+ "ibeam", -+ "text" -+}; -+ -+static const char *hand1s[] = { -+ "hand1", -+ "pointer", -+ "pointing_hand", -+ "e29285e634086352946a0e7090d73106" -+}; -+ -+static const char *watches[] = { -+ "watch", -+ "wait", -+ "0426c94ea35c87780ff01dc239897213" -+}; -+ -+struct cursor_alternatives { -+ const char **names; -+ size_t count; -+}; -+ -+static const struct cursor_alternatives cursors[] = { -+ {bottom_left_corners, ARRAY_LENGTH(bottom_left_corners)}, -+ {bottom_right_corners, ARRAY_LENGTH(bottom_right_corners)}, -+ {bottom_sides, ARRAY_LENGTH(bottom_sides)}, -+ {grabbings, ARRAY_LENGTH(grabbings)}, -+ {left_ptrs, ARRAY_LENGTH(left_ptrs)}, -+ {left_sides, ARRAY_LENGTH(left_sides)}, -+ {right_sides, ARRAY_LENGTH(right_sides)}, -+ {top_left_corners, ARRAY_LENGTH(top_left_corners)}, -+ {top_right_corners, ARRAY_LENGTH(top_right_corners)}, -+ {top_sides, ARRAY_LENGTH(top_sides)}, -+ {xterms, ARRAY_LENGTH(xterms)}, -+ {hand1s, ARRAY_LENGTH(hand1s)}, -+ {watches, ARRAY_LENGTH(watches)}, -+}; -+ -+static void -+create_cursors(struct wlContextCommon *cmm) -+{ -+ uint32_t i = 0; -+ uint32_t j = 0; -+ struct wl_cursor *cursor = NULL; -+ char* cursor_theme = cmm->hmi_setting->cursor_theme; -+ int32_t cursor_size = cmm->hmi_setting->cursor_size; -+ -+ cmm->cursor_theme = wl_cursor_theme_load(cursor_theme, cursor_size, cmm->wlShm); -+ -+ cmm->cursors = MEM_ALLOC(ARRAY_LENGTH(cursors) * sizeof(cmm->cursors[0])); -+ -+ for (i = 0; i < ARRAY_LENGTH(cursors); i++) { -+ cursor = NULL; -+ -+ for (j = 0; !cursor && j < cursors[i].count; ++j) { -+ cursor = wl_cursor_theme_get_cursor( -+ cmm->cursor_theme, cursors[i].names[j]); -+ } -+ -+ if (!cursor) { -+ fprintf(stderr, "could not load cursor '%s'\n", -+ cursors[i].names[0]); -+ } -+ -+ cmm->cursors[i] = cursor; -+ } -+} -+ -+static void -+destroy_cursors(struct wlContextCommon *cmm) -+{ -+ if (cmm->cursor_theme) { -+ wl_cursor_theme_destroy(cmm->cursor_theme); -+ } -+ -+ free(cmm->cursors); -+} -+ -+/** -+ * Internal method to prepare parts of UI -+ */ -+static void -+createShmBuffer(struct wlContextStruct *p_wlCtx) -+{ -+ struct wl_shm_pool *pool; -+ -+ char filename[] = "/tmp/wayland-shm-XXXXXX"; -+ int fd = -1; -+ int size = 0; -+ int width = 0; -+ int height = 0; -+ int stride = 0; -+ -+ fd = mkstemp(filename); -+ if (fd < 0) { -+ fprintf(stderr, "open %s failed: %m\n", filename); -+ return; -+ } -+ -+ width = cairo_image_surface_get_width(p_wlCtx->ctx_image); -+ height = cairo_image_surface_get_height(p_wlCtx->ctx_image); -+ stride = cairo_image_surface_get_stride(p_wlCtx->ctx_image); -+ -+ size = stride * height; -+ if (ftruncate(fd, size) < 0) { -+ fprintf(stderr, "ftruncate failed: %m\n"); -+ close(fd); -+ return; -+ } -+ -+ p_wlCtx->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); -+ -+ if (MAP_FAILED == p_wlCtx->data) { -+ fprintf(stderr, "mmap failed: %m\n"); -+ close(fd); -+ return; -+ } -+ -+ pool = wl_shm_create_pool(p_wlCtx->cmm.wlShm, fd, size); -+ p_wlCtx->wlBuffer = wl_shm_pool_create_buffer(pool, 0, -+ width, -+ height, -+ stride, -+ WL_SHM_FORMAT_ARGB8888); -+ -+ if (NULL == p_wlCtx->wlBuffer) { -+ fprintf(stderr, "wl_shm_create_buffer failed: %m\n"); -+ close(fd); -+ return; -+ } -+ wl_shm_pool_destroy(pool); -+ close(fd); -+ -+ return; -+} -+ -+static void -+destroyWLContextCommon(struct wlContextCommon *p_wlCtx) -+{ -+ destroy_cursors(p_wlCtx); -+ -+ if (p_wlCtx->pointer_surface) { -+ wl_surface_destroy(p_wlCtx->pointer_surface); -+ } -+ -+ if (p_wlCtx->wlCompositor) { -+ wl_compositor_destroy(p_wlCtx->wlCompositor); -+ } -+} -+ -+static void -+destroyWLContextStruct(struct wlContextStruct *p_wlCtx) -+{ -+ if (p_wlCtx->wlSurface) { -+ wl_surface_destroy(p_wlCtx->wlSurface); -+ } -+ -+ if (p_wlCtx->ctx_image) { -+ cairo_surface_destroy(p_wlCtx->ctx_image); -+ p_wlCtx->ctx_image = NULL; -+ } -+} -+ -+static int -+createWLContext(struct wlContextStruct *p_wlCtx) -+{ -+ wl_display_roundtrip(p_wlCtx->cmm.wlDisplay); -+ -+ p_wlCtx->wlSurface = wl_compositor_create_surface(p_wlCtx->cmm.wlCompositor); -+ if (NULL == p_wlCtx->wlSurface) { -+ printf("Error: wl_compositor_create_surface failed.\n"); -+ destroyWLContextCommon(&p_wlCtx->cmm); -+ abort(); -+ } -+ -+ -+ createShmBuffer(p_wlCtx); -+ -+ wl_display_flush(p_wlCtx->cmm.wlDisplay); -+ wl_display_roundtrip(p_wlCtx->cmm.wlDisplay); -+ -+ return 0; -+} -+ -+static void -+drawImage(struct wlContextStruct *p_wlCtx) -+{ -+ struct wl_callback *callback; -+ -+ int width = 0; -+ int height = 0; -+ int stride = 0; -+ void *data = NULL; -+ -+ width = cairo_image_surface_get_width(p_wlCtx->ctx_image); -+ height = cairo_image_surface_get_height(p_wlCtx->ctx_image); -+ stride = cairo_image_surface_get_stride(p_wlCtx->ctx_image); -+ data = cairo_image_surface_get_data(p_wlCtx->ctx_image); -+ -+ memcpy(p_wlCtx->data, data, stride * height); -+ -+ wl_surface_attach(p_wlCtx->wlSurface, p_wlCtx->wlBuffer, 0, 0); -+ wl_surface_damage(p_wlCtx->wlSurface, 0, 0, width, height); -+ -+ callback = wl_surface_frame(p_wlCtx->wlSurface); -+ wl_callback_add_listener(callback, &frame_listener, NULL); -+ -+ wl_surface_commit(p_wlCtx->wlSurface); -+ -+ wl_display_flush(p_wlCtx->cmm.wlDisplay); -+ wl_display_roundtrip(p_wlCtx->cmm.wlDisplay); -+} -+ -+static void -+create_ivisurface(struct wlContextStruct *p_wlCtx, -+ uint32_t id_surface, -+ cairo_surface_t* surface) -+{ -+ struct ivi_surface *ivisurf = NULL; -+ -+ p_wlCtx->ctx_image = surface; -+ -+ p_wlCtx->id_surface = id_surface; -+ wl_list_init(&p_wlCtx->link); -+ wl_list_insert(p_wlCtx->cmm.list_wlContextStruct, &p_wlCtx->link); -+ -+ createWLContext(p_wlCtx); -+ -+ ivisurf = ivi_application_surface_create(p_wlCtx->cmm.iviApplication, -+ id_surface, p_wlCtx->wlSurface); -+ if (ivisurf == NULL) { -+ fprintf(stderr, "Failed to create ivi_client_surface\n"); -+ return; -+ } -+ -+ drawImage(p_wlCtx); -+ -+ wl_display_roundtrip(p_wlCtx->cmm.wlDisplay); -+} -+ -+static void -+create_ivisurfaceFromFile(struct wlContextStruct *p_wlCtx, -+ uint32_t id_surface, -+ const char* imageFile) -+{ -+ cairo_surface_t* surface = load_cairo_surface(imageFile); -+ -+ if (NULL == surface) { -+ fprintf(stderr, "Failed to load_cairo_surface %s\n", imageFile); -+ return; -+ } -+ -+ create_ivisurface(p_wlCtx, id_surface, surface); -+} -+ -+static void -+set_hex_color(cairo_t *cr, uint32_t color) -+{ -+ cairo_set_source_rgba(cr, -+ ((color >> 16) & 0xff) / 255.0, -+ ((color >> 8) & 0xff) / 255.0, -+ ((color >> 0) & 0xff) / 255.0, -+ ((color >> 24) & 0xff) / 255.0); -+} -+ -+static void -+create_ivisurfaceFromColor(struct wlContextStruct *p_wlCtx, -+ uint32_t id_surface, -+ uint32_t width, uint32_t height, -+ uint32_t color) -+{ -+ cairo_surface_t *surface = NULL; -+ cairo_t *cr = NULL; -+ -+ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); -+ -+ cr = cairo_create(surface); -+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); -+ cairo_rectangle(cr, 0, 0, width, height); -+ set_hex_color(cr, color); -+ cairo_fill(cr); -+ cairo_destroy(cr); -+ -+ create_ivisurface(p_wlCtx, id_surface, surface); -+} -+ -+static void -+UI_ready(struct ivi_hmi_controller *controller) -+{ -+ ivi_hmi_controller_UI_ready(controller); -+} -+ -+/** -+ * Internal method to set up UI by using ivi-hmi-controller -+ */ -+static void -+create_background(struct wlContextStruct *p_wlCtx, const uint32_t id_surface, -+ const char* imageFile) -+{ -+ create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile); -+} -+ -+static void -+create_panel(struct wlContextStruct *p_wlCtx, const uint32_t id_surface, -+ const char* imageFile) -+{ -+ create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile); -+} -+ -+static void -+create_button(struct wlContextStruct *p_wlCtx, const uint32_t id_surface, -+ const char* imageFile, uint32_t number) -+{ -+ create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile); -+} -+ -+static void -+create_home_button(struct wlContextStruct *p_wlCtx, const uint32_t id_surface, -+ const char* imageFile) -+{ -+ create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile); -+} -+ -+static void -+create_workspace_background( -+ struct wlContextStruct *p_wlCtx, struct hmi_homescreen_srf *srf) -+{ -+ create_ivisurfaceFromColor(p_wlCtx, srf->id, 1, 1, srf->color); -+} -+ -+static void -+create_launchers(struct wlContextCommon *cmm, struct wl_list *launcher_list) -+{ -+ int launcher_count = wl_list_length(launcher_list); -+ -+ if (0 == launcher_count) { -+ return; -+ } -+ -+ struct hmi_homescreen_launcher** launchers; -+ launchers = MEM_ALLOC(launcher_count * sizeof(*launchers)); -+ -+ int ii = 0; -+ struct hmi_homescreen_launcher *launcher = NULL; -+ -+ wl_list_for_each(launcher, launcher_list, link) { -+ launchers[ii] = launcher; -+ ii++; -+ } -+ -+ int start = 0; -+ -+ for (ii = 0; ii < launcher_count; ii++) { -+ -+ if (ii != launcher_count -1 && -+ launchers[ii]->workspace_id == launchers[ii + 1]->workspace_id) { -+ continue; -+ } -+ -+ int jj = 0; -+ for (jj = start; jj <= ii; jj++) { -+ struct wlContextStruct *p_wlCtx = MEM_ALLOC(sizeof(*p_wlCtx)); -+ p_wlCtx->cmm = *cmm; -+ create_ivisurfaceFromFile(p_wlCtx,launchers[jj]->icon_surface_id, launchers[jj]->icon); -+ } -+ -+ start = ii + 1; -+ } -+ -+ free(launchers); -+} -+ -+static void sigFunc(int signum) -+{ -+ gRun = 0; -+} -+ -+/** -+ * Internal method to read out weston.ini to get configuration -+ */ -+static struct hmi_homescreen_setting* -+hmi_homescreen_setting_create(void) -+{ -+ struct hmi_homescreen_setting* setting = MEM_ALLOC(sizeof(*setting)); -+ -+ wl_list_init(&setting->workspace_list); -+ wl_list_init(&setting->launcher_list); -+ -+ struct weston_config *config = NULL; -+ config = weston_config_parse("weston.ini"); -+ -+ struct weston_config_section *shellSection = NULL; -+ shellSection = weston_config_get_section(config, "ivi-shell", NULL, NULL); -+ -+ weston_config_section_get_string( -+ shellSection, "cursor-theme", &setting->cursor_theme, NULL); -+ -+ weston_config_section_get_int(shellSection, "cursor-size", &setting->cursor_size, 32); -+ -+ uint32_t workspace_layer_id; -+ weston_config_section_get_uint( -+ shellSection, "workspace-layer-id", &workspace_layer_id, 3000); -+ -+ weston_config_section_get_string( -+ shellSection, "background-image", &setting->background.filePath, -+ DATADIR "/weston/background.png"); -+ -+ weston_config_section_get_uint( -+ shellSection, "background-id", &setting->background.id, 1001); -+ -+ weston_config_section_get_string( -+ shellSection, "panel-image", &setting->panel.filePath, -+ DATADIR "/weston/panel.png"); -+ -+ weston_config_section_get_uint( -+ shellSection, "panel-id", &setting->panel.id, 1002); -+ -+ weston_config_section_get_string( -+ shellSection, "tiling-image", &setting->tiling.filePath, -+ DATADIR "/weston/tiling.png"); -+ -+ weston_config_section_get_uint( -+ shellSection, "tiling-id", &setting->tiling.id, 1003); -+ -+ weston_config_section_get_string( -+ shellSection, "sidebyside-image", &setting->sidebyside.filePath, -+ DATADIR "/weston/sidebyside.png"); -+ -+ weston_config_section_get_uint( -+ shellSection, "sidebyside-id", &setting->sidebyside.id, 1004); -+ -+ weston_config_section_get_string( -+ shellSection, "fullscreen-image", &setting->fullscreen.filePath, -+ DATADIR "/weston/fullscreen.png"); -+ -+ weston_config_section_get_uint( -+ shellSection, "fullscreen-id", &setting->fullscreen.id, 1005); -+ -+ weston_config_section_get_string( -+ shellSection, "random-image", &setting->random.filePath, -+ DATADIR "/weston/random.png"); -+ -+ weston_config_section_get_uint( -+ shellSection, "random-id", &setting->random.id, 1006); -+ -+ weston_config_section_get_string( -+ shellSection, "home-image", &setting->home.filePath, -+ DATADIR "/weston/home.png"); -+ -+ weston_config_section_get_uint( -+ shellSection, "home-id", &setting->home.id, 1007); -+ -+ weston_config_section_get_uint( -+ shellSection, "workspace-background-color", -+ &setting->workspace_background.color, 0x99000000); -+ -+ weston_config_section_get_uint( -+ shellSection, "workspace-background-id", -+ &setting->workspace_background.id, 2001); -+ -+ struct weston_config_section *section = NULL; -+ const char *name = NULL; -+ -+ uint32_t icon_surface_id = workspace_layer_id + 1; -+ -+ while (weston_config_next_section(config, §ion, &name)) { -+ -+ if (0 == strcmp(name, "ivi-launcher")) { -+ -+ struct hmi_homescreen_launcher *launcher = NULL; -+ launcher = MEM_ALLOC(sizeof(*launcher)); -+ wl_list_init(&launcher->link); -+ -+ weston_config_section_get_string(section, "icon", &launcher->icon, NULL); -+ weston_config_section_get_string(section, "path", &launcher->path, NULL); -+ weston_config_section_get_uint(section, "workspace-id", &launcher->workspace_id, 0); -+ weston_config_section_get_uint(section, "icon-id", &launcher->icon_surface_id, icon_surface_id); -+ icon_surface_id++; -+ -+ wl_list_insert(setting->launcher_list.prev, &launcher->link); -+ } -+ } -+ -+ weston_config_destroy(config); -+ return setting; -+} -+ -+/** -+ * Main thread -+ * -+ * The basic flow are as followed, -+ * 1/ read configuration from weston.ini by hmi_homescreen_setting_create -+ * 2/ draw png file to surface according to configuration of weston.ini and -+ * set up UI by using ivi-hmi-controller protocol by each create_* method -+ */ -+int main(int argc, char **argv) -+{ -+ struct wlContextCommon wlCtxCommon; -+ struct wlContextStruct wlCtx_BackGround; -+ struct wlContextStruct wlCtx_Panel; -+ struct wlContextStruct wlCtx_Button_1; -+ struct wlContextStruct wlCtx_Button_2; -+ struct wlContextStruct wlCtx_Button_3; -+ struct wlContextStruct wlCtx_Button_4; -+ struct wlContextStruct wlCtx_HomeButton; -+ struct wlContextStruct wlCtx_WorkSpaceBackGround; -+ struct wl_list launcher_wlCtxList; -+ -+ memset(&wlCtxCommon, 0x00, sizeof(wlCtxCommon)); -+ memset(&wlCtx_BackGround, 0x00, sizeof(wlCtx_BackGround)); -+ memset(&wlCtx_Panel, 0x00, sizeof(wlCtx_Panel)); -+ memset(&wlCtx_Button_1, 0x00, sizeof(wlCtx_Button_1)); -+ memset(&wlCtx_Button_2, 0x00, sizeof(wlCtx_Button_2)); -+ memset(&wlCtx_Button_3, 0x00, sizeof(wlCtx_Button_3)); -+ memset(&wlCtx_Button_4, 0x00, sizeof(wlCtx_Button_4)); -+ memset(&wlCtx_HomeButton, 0x00, sizeof(wlCtx_HomeButton)); -+ memset(&wlCtx_WorkSpaceBackGround, 0x00, sizeof(wlCtx_WorkSpaceBackGround)); -+ wl_list_init(&launcher_wlCtxList); -+ wlCtxCommon.list_wlContextStruct = MEM_ALLOC(sizeof(struct wl_list)); -+ assert(wlCtxCommon.list_wlContextStruct); -+ wl_list_init(wlCtxCommon.list_wlContextStruct); -+ -+ struct hmi_homescreen_setting *hmi_setting = hmi_homescreen_setting_create(); -+ wlCtxCommon.hmi_setting = hmi_setting; -+ -+ gRun = 1; -+ -+ wlCtxCommon.wlDisplay = wl_display_connect(NULL); -+ if (NULL == wlCtxCommon.wlDisplay) { -+ printf("Error: wl_display_connect failed.\n"); -+ return -1; -+ } -+ -+ /* get wl_registry */ -+ wlCtxCommon.wlRegistry = wl_display_get_registry(wlCtxCommon.wlDisplay); -+ wl_registry_add_listener(wlCtxCommon.wlRegistry, -+ ®istry_listener, &wlCtxCommon); -+ wl_display_dispatch(wlCtxCommon.wlDisplay); -+ wl_display_roundtrip(wlCtxCommon.wlDisplay); -+ -+ if (wlCtxCommon.hmi_setting->cursor_theme) { -+ create_cursors(&wlCtxCommon); -+ -+ wlCtxCommon.pointer_surface = -+ wl_compositor_create_surface(wlCtxCommon.wlCompositor); -+ -+ wlCtxCommon.current_cursor = CURSOR_LEFT_PTR; -+ } -+ -+ wlCtx_BackGround.cmm = wlCtxCommon; -+ wlCtx_Panel.cmm = wlCtxCommon; -+ wlCtx_Button_1.cmm = wlCtxCommon; -+ wlCtx_Button_2.cmm = wlCtxCommon; -+ wlCtx_Button_3.cmm = wlCtxCommon; -+ wlCtx_Button_4.cmm = wlCtxCommon; -+ wlCtx_HomeButton.cmm = wlCtxCommon; -+ wlCtx_WorkSpaceBackGround.cmm = wlCtxCommon; -+ -+ /* create desktop widgets */ -+ create_background(&wlCtx_BackGround, hmi_setting->background.id, -+ hmi_setting->background.filePath); -+ -+ create_panel(&wlCtx_Panel, hmi_setting->panel.id, -+ hmi_setting->panel.filePath); -+ -+ create_button(&wlCtx_Button_1, hmi_setting->tiling.id, -+ hmi_setting->tiling.filePath, 0); -+ -+ create_button(&wlCtx_Button_2, hmi_setting->sidebyside.id, -+ hmi_setting->sidebyside.filePath, 1); -+ -+ create_button(&wlCtx_Button_3, hmi_setting->fullscreen.id, -+ hmi_setting->fullscreen.filePath, 2); -+ -+ create_button(&wlCtx_Button_4, hmi_setting->random.id, -+ hmi_setting->random.filePath, 3); -+ -+ create_workspace_background(&wlCtx_WorkSpaceBackGround, -+ &hmi_setting->workspace_background); -+ -+ create_launchers(&wlCtxCommon, &hmi_setting->launcher_list); -+ -+ create_home_button(&wlCtx_HomeButton, hmi_setting->home.id, -+ hmi_setting->home.filePath); -+ -+ UI_ready(wlCtxCommon.hmiCtrl); -+ -+ /* signal handling */ -+ signal(SIGINT, sigFunc); -+ signal(SIGKILL, sigFunc); -+ -+ while(gRun) { -+ wl_display_dispatch(wlCtxCommon.wlDisplay); -+ } -+ -+ struct wlContextStruct* pWlCtxSt = NULL; -+ wl_list_for_each(pWlCtxSt, wlCtxCommon.list_wlContextStruct, link) { -+ destroyWLContextStruct(pWlCtxSt); -+ } -+ -+ destroyWLContextCommon(&wlCtxCommon); -+ free(wlCtxCommon.list_wlContextStruct); -+ -+ return 0; -+} -diff --git a/ivi-shell/hmi-controller.c b/ivi-shell/hmi-controller.c -index e04fe61..4fd15e8 100644 ---- a/ivi-shell/hmi-controller.c -+++ b/ivi-shell/hmi-controller.c -@@ -152,6 +152,10 @@ struct hmi_controller - int32_t workspace_count; - struct wl_array ui_widgets; - int32_t is_initialized; -+ -+ struct weston_compositor *compositor; -+ struct weston_process process; -+ struct wl_listener destroy_listener; - }; - - struct launcher_info -@@ -831,6 +835,9 @@ hmi_server_setting_create(void) - - setting->panel_height = 70; - -+ weston_config_section_get_string( -+ shellSection, "ivi-shell-user-interface", &setting->ivi_homescreen, NULL); -+ - weston_config_destroy(config); - - return setting; -@@ -1897,9 +1904,36 @@ bind_hmi_controller(struct wl_client *client, - } - - static void --launch_hmi_client(void *data) -+handle_hmi_client_process_sigchld(struct weston_process *proc, int status) -+{ -+ proc->pid = 0; -+} -+ -+static void -+hmi_client_destroy(struct wl_listener *listener, void *data) -+{ -+ struct hmi_controller *hmi_ctrl = -+ container_of(listener, struct hmi_controller, destroy_listener); -+ -+ kill(hmi_ctrl->process.pid, SIGTERM); -+ hmi_ctrl->process.pid = 0; -+} -+ -+static void -+launch_hmi_client_process(void *data) - { -- /*Nothing to do here*/ -+ struct hmi_controller *hmi_ctrl = -+ (struct hmi_controller *)data; -+ -+ weston_client_launch(hmi_ctrl->compositor, -+ &hmi_ctrl->process, -+ hmi_ctrl->hmi_setting->ivi_homescreen, -+ handle_hmi_client_process_sigchld); -+ -+ hmi_ctrl->destroy_listener.notify = hmi_client_destroy; -+ wl_signal_add(&hmi_ctrl->compositor->destroy_signal, &hmi_ctrl->destroy_listener); -+ -+ free(hmi_ctrl->hmi_setting->ivi_homescreen); - } - - /***************************************************************************** -@@ -1911,6 +1945,7 @@ module_init(struct weston_compositor *ec, - int *argc, char *argv[]) - { - struct hmi_controller *hmi_ctrl = hmi_controller_create(ec); -+ hmi_ctrl->compositor = ec; - - if (wl_global_create(ec->wl_display, - &ivi_hmi_controller_interface, 1, -@@ -1919,7 +1954,7 @@ module_init(struct weston_compositor *ec, - } - - struct wl_event_loop *loop = wl_display_get_event_loop(ec->wl_display); -- wl_event_loop_add_idle(loop, launch_hmi_client, ec); -+ wl_event_loop_add_idle(loop, launch_hmi_client_process, hmi_ctrl); - - return 0; - } --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0008-data-add-reference-image-files-for-weston-ivi-shell-.patch b/meta-ivi/recipes-graphics/wayland/weston/0008-data-add-reference-image-files-for-weston-ivi-shell-.patch deleted file mode 100644 index e936453..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0008-data-add-reference-image-files-for-weston-ivi-shell-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 528e4dfff905b10efe6a7428232636eafbfbfc56 Mon Sep 17 00:00:00 2001 -From: Andrei Gherzan <andrei.gherzan@windriver.com> -Date: Thu, 25 Sep 2014 16:58:29 +0200 -Subject: [PATCH 08/31] data: add reference image files for - weston-ivi-shell-user-interface - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Signed-off-by: Andrei Gherzan <andrei.gherzan@windriver.com> ---- - Makefile.am | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/Makefile.am b/Makefile.am -index ec6b721..98995b4 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -644,7 +644,19 @@ dist_westondata_DATA = \ - data/icon_window.png \ - data/sign_close.png \ - data/sign_maximize.png \ -- data/sign_minimize.png -+ data/sign_minimize.png \ -+ data/background.png \ -+ data/tiling.png \ -+ data/fullscreen.png \ -+ data/panel.png \ -+ data/random.png \ -+ data/sidebyside.png \ -+ data/home.png \ -+ data/icon_ivi_clickdot.png \ -+ data/icon_ivi_flower.png \ -+ data/icon_ivi_simple-egl.png \ -+ data/icon_ivi_simple-shm.png \ -+ data/icon_ivi_smoke.png - - - if BUILD_WCAP_TOOLS --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0010-clients-modify-example-clients-to-support-ivi-applic.patch b/meta-ivi/recipes-graphics/wayland/weston/0010-clients-modify-example-clients-to-support-ivi-applic.patch deleted file mode 100644 index 449681a..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0010-clients-modify-example-clients-to-support-ivi-applic.patch +++ /dev/null @@ -1,479 +0,0 @@ -From 44182c3ce1867ee7bad801824a9af62a2c1a6a4d Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Tue, 18 Mar 2014 14:19:48 +0900 -Subject: [PATCH 10/31] clients: modify example clients to support - ivi-application.xml - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - Makefile.am | 12 ++++++-- - clients/simple-egl.c | 70 +++++++++++++++++++++++++++++++++++-------- - clients/simple-shm.c | 34 ++++++++++++++++++++- - clients/window.c | 84 ++++++++++++++++++++++++++++++++++++++-------------- - 4 files changed, 161 insertions(+), 39 deletions(-) - -diff --git a/Makefile.am b/Makefile.am -index 835d721..869567d 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -406,7 +406,9 @@ nodist_weston_simple_shm_SOURCES = \ - protocol/xdg-shell-protocol.c \ - protocol/xdg-shell-client-protocol.h \ - protocol/fullscreen-shell-protocol.c \ -- protocol/fullscreen-shell-client-protocol.h -+ protocol/fullscreen-shell-client-protocol.h \ -+ protocol/ivi-application-protocol.c \ -+ protocol/ivi-application-client-protocol.h - weston_simple_shm_CFLAGS = $(AM_CFLAGS) $(SIMPLE_CLIENT_CFLAGS) - weston_simple_shm_LDADD = $(SIMPLE_CLIENT_LIBS) libshared.la - -@@ -424,7 +426,9 @@ demo_clients += weston-simple-egl - weston_simple_egl_SOURCES = clients/simple-egl.c - nodist_weston_simple_egl_SOURCES = \ - protocol/xdg-shell-protocol.c \ -- protocol/xdg-shell-client-protocol.h -+ protocol/xdg-shell-client-protocol.h \ -+ protocol/ivi-application-protocol.c \ -+ protocol/ivi-application-client-protocol.h - weston_simple_egl_CFLAGS = $(AM_CFLAGS) $(SIMPLE_EGL_CLIENT_CFLAGS) - weston_simple_egl_LDADD = $(SIMPLE_EGL_CLIENT_LIBS) -lm - endif -@@ -443,7 +447,9 @@ nodist_libtoytoolkit_la_SOURCES = \ - protocol/workspaces-protocol.c \ - protocol/workspaces-client-protocol.h \ - protocol/xdg-shell-protocol.c \ -- protocol/xdg-shell-client-protocol.h -+ protocol/xdg-shell-client-protocol.h \ -+ protocol/ivi-application-protocol.c \ -+ protocol/ivi-application-client-protocol.h - - BUILT_SOURCES += $(nodist_libtoytoolkit_la_SOURCES) - -diff --git a/clients/simple-egl.c b/clients/simple-egl.c -index 0d4673b..92f2dc2 100644 ---- a/clients/simple-egl.c -+++ b/clients/simple-egl.c -@@ -41,6 +41,10 @@ - #include <EGL/eglext.h> - - #include "xdg-shell-client-protocol.h" -+#include <sys/types.h> -+#include <unistd.h> -+#include "protocol/ivi-application-client-protocol.h" -+#define IVI_SURFACE_ID 9000 - - #ifndef EGL_EXT_swap_buffers_with_damage - #define EGL_EXT_swap_buffers_with_damage 1 -@@ -74,6 +78,7 @@ struct display { - EGLConfig conf; - } egl; - struct window *window; -+ struct ivi_application *ivi_application; - - PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage; - }; -@@ -95,6 +100,7 @@ struct window { - struct wl_egl_window *native; - struct wl_surface *surface; - struct xdg_surface *xdg_surface; -+ struct ivi_surface *ivi_surface; - EGLSurface egl_surface; - struct wl_callback *callback; - int fullscreen, opaque, buffer_size, frame_sync; -@@ -254,7 +260,7 @@ init_gl(struct window *window) - } - - glUseProgram(program); -- -+ - window->gl.pos = 0; - window->gl.col = 1; - -@@ -333,13 +339,8 @@ create_surface(struct window *window) - { - struct display *display = window->display; - EGLBoolean ret; -- -- window->surface = wl_compositor_create_surface(display->compositor); -- window->xdg_surface = xdg_shell_get_xdg_surface(display->shell, -- window->surface); - -- xdg_surface_add_listener(window->xdg_surface, -- &xdg_surface_listener, window); -+ window->surface = wl_compositor_create_surface(display->compositor); - - window->native = - wl_egl_window_create(window->surface, -@@ -350,7 +351,28 @@ create_surface(struct window *window) - display->egl.conf, - window->native, NULL); - -- xdg_surface_set_title(window->xdg_surface, "simple-egl"); -+ if (display->shell) { -+ window->xdg_surface = xdg_shell_get_xdg_surface(display->shell, -+ window->surface); -+ -+ xdg_surface_add_listener(window->xdg_surface, -+ &xdg_surface_listener, window); -+ -+ xdg_surface_set_title(window->xdg_surface, "simple-egl"); -+ } else if (display->ivi_application ) { -+ uint32_t id_ivisurf = IVI_SURFACE_ID + (uint32_t)getpid(); -+ window->ivi_surface = -+ ivi_application_surface_create(display->ivi_application, -+ id_ivisurf, window->surface); -+ handle_surface_configure(window, NULL, 250, 250); -+ -+ if (window->ivi_surface == NULL) { -+ fprintf(stderr, "Failed to create ivi_client_surface\n"); -+ abort(); -+ } -+ } else { -+ assert(0); -+ } - - ret = eglMakeCurrent(window->display->egl.dpy, window->egl_surface, - window->egl_surface, window->display->egl.ctx); -@@ -359,9 +381,12 @@ create_surface(struct window *window) - if (!window->frame_sync) - eglSwapInterval(display->egl.dpy, 0); - -- xdg_surface_request_change_state(window->xdg_surface, -- XDG_SURFACE_STATE_FULLSCREEN, -- window->fullscreen, 0); -+ if (display->shell) -+ { -+ xdg_surface_request_change_state(window->xdg_surface, -+ XDG_SURFACE_STATE_FULLSCREEN, -+ window->fullscreen, 0); -+ } - } - - static void -@@ -536,8 +561,13 @@ pointer_handle_button(void *data, struct wl_pointer *wl_pointer, - struct display *display = data; - - if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED) -- xdg_surface_move(display->window->xdg_surface, -- display->seat, serial); -+ { -+ if (display->shell) -+ { -+ xdg_surface_move(display->window->xdg_surface, -+ display->seat, serial); -+ } -+ } - } - - static void -@@ -730,6 +760,11 @@ registry_handle_global(void *data, struct wl_registry *registry, - // TODO: abort ? - } - } -+ else if (strcmp(interface, "ivi_application") == 0) { -+ d->ivi_application = -+ wl_registry_bind(registry, name, -+ &ivi_application_interface, 1); -+ } - } - - static void -@@ -824,6 +859,12 @@ main(int argc, char **argv) - - fprintf(stderr, "simple-egl exiting\n"); - -+ if (window.display->ivi_application) -+ { -+ ivi_surface_destroy(window.ivi_surface); -+ ivi_application_destroy(window.display->ivi_application); -+ } -+ - destroy_surface(&window); - fini_egl(&display); - -@@ -838,6 +879,9 @@ main(int argc, char **argv) - wl_compositor_destroy(display.compositor); - - wl_registry_destroy(display.registry); -+ if (window.display->ivi_application) -+ wl_display_roundtrip(display.display); -+ - wl_display_flush(display.display); - wl_display_disconnect(display.display); - -diff --git a/clients/simple-shm.c b/clients/simple-shm.c -index 2087a0e..c54b5d7 100644 ---- a/clients/simple-shm.c -+++ b/clients/simple-shm.c -@@ -37,6 +37,10 @@ - #include "xdg-shell-client-protocol.h" - #include "fullscreen-shell-client-protocol.h" - -+#include <sys/types.h> -+#include "ivi-application-client-protocol.h" -+#define IVI_SURFACE_ID 9000 -+ - struct display { - struct wl_display *display; - struct wl_registry *registry; -@@ -45,6 +49,7 @@ struct display { - struct _wl_fullscreen_shell *fshell; - struct wl_shm *shm; - uint32_t formats; -+ struct ivi_application *ivi_application; - }; - - struct buffer { -@@ -58,6 +63,7 @@ struct window { - int width, height; - struct wl_surface *surface; - struct xdg_surface *xdg_surface; -+ struct ivi_surface *ivi_surface; - struct buffer buffers[2]; - struct buffer *prev_buffer; - struct wl_callback *callback; -@@ -179,11 +185,21 @@ create_window(struct display *display, int width, int height) - &xdg_surface_listener, window); - - xdg_surface_set_title(window->xdg_surface, "simple-shm"); -+ - } else if (display->fshell) { - _wl_fullscreen_shell_present_surface(display->fshell, - window->surface, - _WL_FULLSCREEN_SHELL_PRESENT_METHOD_DEFAULT, - NULL); -+ } else if (display->ivi_application ) { -+ uint32_t id_ivisurf = IVI_SURFACE_ID + (uint32_t)getpid(); -+ window->ivi_surface = -+ ivi_application_surface_create(display->ivi_application, -+ id_ivisurf, window->surface); -+ if (window->ivi_surface == NULL) { -+ fprintf(stderr, "Failed to create ivi_client_surface\n"); -+ abort(); -+ } - } else { - assert(0); - } -@@ -369,6 +385,11 @@ registry_handle_global(void *data, struct wl_registry *registry, - id, &wl_shm_interface, 1); - wl_shm_add_listener(d->shm, &shm_listener, d); - } -+ else if (strcmp(interface, "ivi_application") == 0) { -+ d->ivi_application = -+ wl_registry_bind(registry, id, -+ &ivi_application_interface, 1); -+ } - } - - static void -@@ -413,7 +434,7 @@ create_display(void) - } - - wl_display_get_fd(display->display); -- -+ - return display; - } - -@@ -433,6 +454,10 @@ destroy_display(struct display *display) - wl_compositor_destroy(display->compositor); - - wl_registry_destroy(display->registry); -+ -+ if (display->ivi_application) -+ wl_display_roundtrip(display->display); -+ - wl_display_flush(display->display); - wl_display_disconnect(display->display); - free(display); -@@ -472,6 +497,13 @@ main(int argc, char **argv) - ret = wl_display_dispatch(display->display); - - fprintf(stderr, "simple-shm exiting\n"); -+ -+ if (window->display->ivi_application) -+ { -+ ivi_surface_destroy(window->ivi_surface); -+ ivi_application_destroy(window->display->ivi_application); -+ } -+ - destroy_window(window); - destroy_display(display); - -diff --git a/clients/window.c b/clients/window.c -index 4592ef9..47434dc 100644 ---- a/clients/window.c -+++ b/clients/window.c -@@ -72,6 +72,10 @@ typedef void *EGLContext; - - #include "window.h" - -+#include <sys/types.h> -+#include "ivi-application-client-protocol.h" -+#define IVI_SURFACE_ID 9000 -+ - struct shm_pool; - - struct global { -@@ -133,6 +137,7 @@ struct display { - - int has_rgb565; - int seat_version; -+ struct ivi_application *ivi_application; - }; - - struct window_output { -@@ -245,6 +250,7 @@ struct window { - struct xdg_popup *xdg_popup; - - struct window *transient_for; -+ struct ivi_surface *ivi_surface; - - struct window_frame *frame; - -@@ -1373,6 +1379,20 @@ surface_create_surface(struct surface *surface, uint32_t flags) - struct display *display = surface->window->display; - struct rectangle allocation = surface->allocation; - -+ if (display->ivi_application) -+ { -+ if (!surface->toysurface) { -+ uint32_t id_ivisurf = IVI_SURFACE_ID + (uint32_t)getpid(); -+ surface->window->ivi_surface = -+ ivi_application_surface_create(display->ivi_application, -+ id_ivisurf, surface->surface); -+ if (surface->window->ivi_surface == NULL) { -+ fprintf(stderr, "Failed to create ivi_client_surface\n"); -+ abort(); -+ } -+ } -+ } -+ - if (!surface->toysurface && display->dpy && - surface->buffer_type == WINDOW_BUFFER_TYPE_EGL_WINDOW) { - surface->toysurface = -@@ -1476,6 +1496,12 @@ surface_destroy(struct surface *surface) - if (surface->toysurface) - surface->toysurface->destroy(surface->toysurface); - -+ if (surface->window->display->ivi_application) -+ { -+ ivi_surface_destroy(surface->window->ivi_surface); -+ ivi_application_destroy(surface->window->display->ivi_application); -+ } -+ - wl_list_remove(&surface->link); - free(surface); - } -@@ -1490,7 +1516,7 @@ window_destroy(struct window *window) - - wl_list_remove(&window->redraw_task.link); - -- wl_list_for_each(input, &display->input_list, link) { -+ wl_list_for_each(input, &display->input_list, link) { - if (input->touch_focus == window) - input->touch_focus = NULL; - if (input->pointer_focus == window) -@@ -3006,7 +3032,7 @@ touch_handle_down(void *data, struct wl_touch *wl_touch, - wl_list_insert(&input->touch_point_list, &tp->link); - - if (widget->touch_down_handler) -- (*widget->touch_down_handler)(widget, input, -+ (*widget->touch_down_handler)(widget, input, - serial, time, id, - sx, sy, - widget->user_data); -@@ -4386,7 +4412,7 @@ window_create_internal(struct display *display, int custom) - surface = surface_create(window); - window->main_surface = surface; - -- assert(custom || display->xdg_shell); -+ assert(custom || display->xdg_shell || display->ivi_application); - - window->custom = custom; - window->preferred_format = WINDOW_PREFERRED_FORMAT_NONE; -@@ -4409,14 +4435,17 @@ window_create(struct display *display) - - window = window_create_internal(display, 0); - -- window->xdg_surface = -- xdg_shell_get_xdg_surface(window->display->xdg_shell, -- window->main_surface->surface); -- fail_on_null(window->xdg_surface); -+ if (window->display->xdg_shell) -+ { -+ window->xdg_surface = -+ xdg_shell_get_xdg_surface(window->display->xdg_shell, -+ window->main_surface->surface); -+ fail_on_null(window->xdg_surface); - -- xdg_surface_set_user_data(window->xdg_surface, window); -- xdg_surface_add_listener(window->xdg_surface, -- &xdg_surface_listener, window); -+ xdg_surface_set_user_data(window->xdg_surface, window); -+ xdg_surface_add_listener(window->xdg_surface, -+ &xdg_surface_listener, window); -+ } - - return window; - } -@@ -4634,19 +4663,22 @@ window_show_menu(struct display *display, - - frame_interior(menu->frame, &ix, &iy, NULL, NULL); - -- window->xdg_popup = xdg_shell_get_xdg_popup(display->xdg_shell, -- window->main_surface->surface, -- parent->main_surface->surface, -- input->seat, -- display_get_serial(window->display), -- window->x - ix, -- window->y - iy, -- 0); -- fail_on_null(window->xdg_popup); -+ if (display->xdg_shell) -+ { -+ window->xdg_popup = xdg_shell_get_xdg_popup(display->xdg_shell, -+ window->main_surface->surface, -+ parent->main_surface->surface, -+ input->seat, -+ display_get_serial(window->display), -+ window->x - ix, -+ window->y - iy, -+ 0); -+ fail_on_null(window->xdg_popup); - -- xdg_popup_set_user_data(window->xdg_popup, window); -- xdg_popup_add_listener(window->xdg_popup, -- &xdg_popup_listener, window); -+ xdg_popup_set_user_data(window->xdg_popup, window); -+ xdg_popup_add_listener(window->xdg_popup, -+ &xdg_popup_listener, window); -+ } - } - - void -@@ -5091,6 +5123,11 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, - wl_registry_bind(registry, id, - &wl_subcompositor_interface, 1); - } -+ else if (strcmp(interface, "ivi_application") == 0) { -+ d->ivi_application = -+ wl_registry_bind(registry, id, -+ &ivi_application_interface, 1); -+ } - - if (d->global_handler) - d->global_handler(d, id, interface, version, d->user_data); -@@ -5400,6 +5437,9 @@ display_destroy(struct display *display) - - close(display->epoll_fd); - -+ if (display->ivi_application) -+ wl_display_roundtrip(display->display); -+ - if (!(display->display_fd_events & EPOLLERR) && - !(display->display_fd_events & EPOLLHUP)) - wl_display_flush(display->display); --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0011-ingnore-data-wayland.png.patch b/meta-ivi/recipes-graphics/wayland/weston/0011-ingnore-data-wayland.png.patch deleted file mode 100644 index 97d15b6..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0011-ingnore-data-wayland.png.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 9f5ea45fed46102e9045311936481cdb2c13fced Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Sun, 20 Apr 2014 22:13:12 +0900 -Subject: [PATCH 11/31] ingnore data/wayland.png - -Change-Id: I2f74d8e7842c9cb481f7758e0412875c069926f4 ---- - Makefile.am | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/Makefile.am b/Makefile.am -index 869567d..b133fcd 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -650,7 +650,6 @@ BUILT_SOURCES += \ - westondatadir = $(datadir)/weston - dist_westondata_DATA = \ - data/wayland.svg \ -- data/wayland.png \ - data/pattern.png \ - data/terminal.png \ - data/border.png \ --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0013-If-window-is-requsted-by-Virtual-keyboard-ivi_applic.patch b/meta-ivi/recipes-graphics/wayland/weston/0013-If-window-is-requsted-by-Virtual-keyboard-ivi_applic.patch deleted file mode 100644 index 2ba3068..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0013-If-window-is-requsted-by-Virtual-keyboard-ivi_applic.patch +++ /dev/null @@ -1,39 +0,0 @@ -From a34086db0ad4c46aed9ef400c6524378f9aac84d Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Wed, 14 May 2014 16:10:06 +0900 -Subject: [PATCH 13/31] If window is requsted by "Virtual keyboard", - ivi_application surface is not created. - -The positioning of it is done by ivi_shell directly without ivi_application surface. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - clients/window.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/clients/window.c b/clients/window.c -index 47434dc..684f98e 100644 ---- a/clients/window.c -+++ b/clients/window.c -@@ -1381,7 +1381,7 @@ surface_create_surface(struct surface *surface, uint32_t flags) - - if (display->ivi_application) - { -- if (!surface->toysurface) { -+ if (!surface->toysurface && strcmp(surface->window->title,"Virtual keyboard")!=0) { - uint32_t id_ivisurf = IVI_SURFACE_ID + (uint32_t)getpid(); - surface->window->ivi_surface = - ivi_application_surface_create(display->ivi_application, -@@ -1498,7 +1498,8 @@ surface_destroy(struct surface *surface) - - if (surface->window->display->ivi_application) - { -- ivi_surface_destroy(surface->window->ivi_surface); -+ if(strcmp(surface->window->title,"Virtual keyboard")!=0) -+ ivi_surface_destroy(surface->window->ivi_surface); - ivi_application_destroy(surface->window->display->ivi_application); - } - --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0014-input-panel-Change-unsigned-to-signed-to-follow-west.patch b/meta-ivi/recipes-graphics/wayland/weston/0014-input-panel-Change-unsigned-to-signed-to-follow-west.patch deleted file mode 100644 index 2f7b4bc..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0014-input-panel-Change-unsigned-to-signed-to-follow-west.patch +++ /dev/null @@ -1,35 +0,0 @@ -From f530dd6b41c86478750a0a3bf0bfe9c434182559 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Tue, 24 Jun 2014 11:59:01 +0900 -Subject: [PATCH 14/31] input-panel:Change unsigned to signed to follow weston - coding manner. - ---- - ivi-shell/input-panel-ivi.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ivi-shell/input-panel-ivi.c b/ivi-shell/input-panel-ivi.c -index 218da6e..32be989 100644 ---- a/ivi-shell/input-panel-ivi.c -+++ b/ivi-shell/input-panel-ivi.c -@@ -45,7 +45,7 @@ struct input_panel_surface { - struct wl_listener surface_destroy_listener; - - struct weston_output *output; -- uint32_t panel; -+ int32_t panel; - }; - - static void -@@ -305,7 +305,7 @@ unbind_input_panel(struct wl_resource *resource) - - static void - bind_input_panel(struct wl_client *client, -- void *data, uint32_t version, uint32_t id) -+ void *data, uint32_t version, uint32_t id) - { - struct ivi_shell *shell = data; - struct wl_resource *resource; --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0015-This-applies-transition-animation-to-ivi-shell.patch b/meta-ivi/recipes-graphics/wayland/weston/0015-This-applies-transition-animation-to-ivi-shell.patch deleted file mode 100644 index e0e30d9..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0015-This-applies-transition-animation-to-ivi-shell.patch +++ /dev/null @@ -1,2548 +0,0 @@ -From 3c91c0ef4a57fefe02e074f5d1e3a06fdddb43b4 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Mon, 7 Jul 2014 21:43:12 +0900 -Subject: [PATCH 15/31] This applies transition animation to ivi-shell. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - Makefile.am | 4 +- - clients/ivi-shell-user-interface.c | 1 + - ivi-shell/hmi-controller.c | 487 ++++------------- - ivi-shell/ivi-layout-export.h | 80 ++- - ivi-shell/ivi-layout-private.h | 207 ++++++++ - ivi-shell/ivi-layout-transition.c | 1013 ++++++++++++++++++++++++++++++++++++ - ivi-shell/ivi-layout-transition.h | 77 +++ - ivi-shell/ivi-layout.c | 200 ++++--- - ivi-shell/ivi-layout.h | 64 +++ - ivi-shell/weston.ini.in | 2 + - 10 files changed, 1602 insertions(+), 533 deletions(-) - create mode 100644 ivi-shell/ivi-layout-private.h - create mode 100644 ivi-shell/ivi-layout-transition.c - create mode 100644 ivi-shell/ivi-layout-transition.h - -diff --git a/Makefile.am b/Makefile.am -index 13fe45b..3ebc89a 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -769,7 +769,9 @@ ivi_layout_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS) $(IVI_SHELL_CFLAGS) - ivi_layout_la_SOURCES = \ - ivi-shell/ivi-layout.h \ - ivi-shell/ivi-layout-export.h \ -- ivi-shell/ivi-layout.c -+ ivi-shell/ivi-layout.c \ -+ ivi-shell/ivi-layout-transition.h \ -+ ivi-shell/ivi-layout-transition.c - nodist_ivi_layout_la_SOURCES = \ - protocol/ivi-application-protocol.c \ - protocol/ivi-application-server-protocol.h -diff --git a/clients/ivi-shell-user-interface.c b/clients/ivi-shell-user-interface.c -index 70b854b..a8089f1 100644 ---- a/clients/ivi-shell-user-interface.c -+++ b/clients/ivi-shell-user-interface.c -@@ -153,6 +153,7 @@ hmi_homescreen_setting { - - char *cursor_theme; - int32_t cursor_size; -+ uint32_t transition_duration; - }; - - volatile int gRun = 0; -diff --git a/ivi-shell/hmi-controller.c b/ivi-shell/hmi-controller.c -index 4fd15e8..fd150ff 100644 ---- a/ivi-shell/hmi-controller.c -+++ b/ivi-shell/hmi-controller.c -@@ -55,6 +55,7 @@ - - #include "ivi-layout-export.h" - #include "ivi-hmi-controller-server-protocol.h" -+#include "ivi-layout-transition.h" - - /***************************************************************************** - * structure, globals -@@ -73,67 +74,19 @@ struct link_layer { - struct wl_list link; - }; - --struct link_animation { -- struct hmi_controller_animation *animation; -- struct wl_list link; --}; -- --struct hmi_controller_animation; --typedef void (*hmi_controller_animation_frame_func)(void *animation, int32_t timestamp); --typedef void (*hmi_controller_animation_frame_user_func)(void *animation); --typedef void (*hmi_controller_animation_destroy_func)(struct hmi_controller_animation *animation); -- --struct move_animation_user_data { -- struct ivi_layout_layer* layer; -- struct animation_set *anima_set; -- struct hmi_controller *hmi_ctrl; --}; -- --struct hmi_controller_animation { -- void *user_data; -- uint32_t time_start; -- int32_t is_done; -- hmi_controller_animation_frame_func frame_func; -- hmi_controller_animation_frame_user_func frame_user_func; -- hmi_controller_animation_destroy_func destroy_func; --}; -- --struct hmi_controller_animation_fade { -- struct hmi_controller_animation base; -- double start; -- double end; -- struct weston_spring spring; --}; -- --struct hmi_controller_animation_move { -- struct hmi_controller_animation base; -- double pos; -- double pos_start; -- double pos_end; -- double v0; -- double a; -- double time_end; --}; -- - struct hmi_controller_fade { -- int32_t isFadeIn; -- struct hmi_controller_animation_fade *animation; -- struct animation_set *anima_set; -+ uint32_t isFadeIn; - struct wl_list layer_list; - }; - --struct animation_set { -- struct wl_event_source *event_source; -- struct wl_list animation_list; --}; -- - struct - hmi_server_setting { - uint32_t base_layer_id; - uint32_t application_layer_id; - uint32_t workspace_background_layer_id; - uint32_t workspace_layer_id; -- int32_t panel_height; -+ int32_t panel_height; -+ uint32_t transition_duration; - char *ivi_homescreen; - }; - -@@ -146,9 +99,8 @@ struct hmi_controller - struct hmi_controller_layer workspace_layer; - enum ivi_hmi_controller_layout_mode layout_mode; - -- struct animation_set *anima_set; - struct hmi_controller_fade workspace_fade; -- struct hmi_controller_animation_move *workspace_swipe_animation; -+ - int32_t workspace_count; - struct wl_array ui_widgets; - int32_t is_initialized; -@@ -243,10 +195,14 @@ mode_divided_into_tiling(struct hmi_controller *hmi_ctrl, - int32_t surface_x = 0; - int32_t surface_y = 0; - struct ivi_layout_surface *ivisurf = NULL; -- int32_t ret = 0; -+ -+ struct ivi_layout_surface *surfaces[1024] = {}; //FIXME -+ struct ivi_layout_surface *new_order[1024] = {}; //FIXME -+ -+ const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; - - int32_t i = 0; -- int32_t num = 1; -+ int32_t surf_num = 0; - for (i = 0; i < surface_length; i++) { - ivisurf = ppSurface[i]; - -@@ -255,6 +211,16 @@ mode_divided_into_tiling(struct hmi_controller *hmi_ctrl, - continue; - } - -+ surfaces[surf_num++] = ivisurf; -+ } -+ -+ static uint32_t si = 0; -+ uint32_t num = 1; -+ for(i=0; i < surf_num; i++){ -+ -+ ivisurf = surfaces[(i + si) % surf_num]; -+ new_order[i] = ivisurf; -+ - if (num <= 8) { - if (num < 5) { - surface_x = (int32_t)((num - 1) * (surface_width)); -@@ -264,20 +230,28 @@ mode_divided_into_tiling(struct hmi_controller *hmi_ctrl, - surface_x = (int32_t)((num - 5) * (surface_width)); - surface_y = (int32_t)surface_height; - } -- ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, surface_x, surface_y, -- surface_width, surface_height); -- assert(!ret); - -- ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -- assert(!ret); -+ ivi_layout_surfaceSetTransition(ivisurf,IVI_LAYOUT_TRANSITION_VIEW_DEFAULT, duration); -+ ivi_layout_surfaceSetVisibility(ivisurf, 1); -+ ivi_layout_surfaceSetDestinationRectangle(ivisurf, surface_x, surface_y, -+ (uint32_t)surface_width, (uint32_t)surface_height); - - num++; - continue; - } -+ ivi_layout_surfaceSetVisibility(ivisurf, 0); -+ } - -- ret = ivi_layout_surfaceSetVisibility(ivisurf, 0); -- assert(!ret); -+ if(surf_num > 0){ -+ ivi_layout_layerSetTransition(layer->ivilayer,IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,duration); -+ //TODO: implement IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER later. -+ ivi_layout_transition_layer_render_order(layer->ivilayer, -+ new_order, -+ surf_num, -+ duration); - } -+ -+ si++; - } - - static void -@@ -291,6 +265,7 @@ mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl, - struct ivi_layout_surface *ivisurf = NULL; - int32_t ret = 0; - -+ const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; - int32_t i = 0; - int32_t num = 1; - for (i = 0; i < surface_length; i++) { -@@ -302,29 +277,26 @@ mode_divided_into_sidebyside(struct hmi_controller *hmi_ctrl, - } - - if (num == 1) { -- ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, 0, 0, -- surface_width, surface_height); -- assert(!ret); -- -- ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -- assert(!ret); -+ ivi_layout_surfaceSetTransition(ivisurf,IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,duration); -+ ivi_layout_surfaceSetVisibility(ivisurf, 1); -+ ivi_layout_surfaceSetDestinationRectangle(ivisurf, 0, 0, -+ (uint32_t)surface_width, (uint32_t)surface_height); - - num++; - continue; - } - else if (num == 2) { -- ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, surface_width, 0, -- surface_width, surface_height); -- assert(!ret); -- -- ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -- assert(!ret); -+ ivi_layout_surfaceSetTransition(ivisurf,IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,duration); -+ ivi_layout_surfaceSetVisibility(ivisurf, 1); -+ ivi_layout_surfaceSetDestinationRectangle(ivisurf, surface_width, 0, -+ (uint32_t)surface_width, (uint32_t)surface_height); - - num++; - continue; - } -- -+ ivi_layout_surfaceSetTransition(ivisurf,IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY,duration); - ivi_layout_surfaceSetVisibility(ivisurf, 0); -+ - assert(!ret); - } - } -@@ -338,9 +310,9 @@ mode_fullscreen_someone(struct hmi_controller *hmi_ctrl, - const int32_t surface_width = layer->width; - const int32_t surface_height = layer->height; - struct ivi_layout_surface *ivisurf = NULL; -- int32_t ret = 0; - - int32_t i = 0; -+ const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; - for (i = 0; i < surface_length; i++) { - ivisurf = ppSurface[i]; - -@@ -348,14 +320,12 @@ mode_fullscreen_someone(struct hmi_controller *hmi_ctrl, - if (is_surf_in_uiWidget(hmi_ctrl, ivisurf)) { - continue; - } -- -- ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, 0, 0, -- surface_width, surface_height); -- assert(!ret); -- -- ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -- assert(!ret); -+ ivi_layout_surfaceSetTransition(ivisurf,IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,duration); -+ ivi_layout_surfaceSetVisibility(ivisurf, 1); -+ ivi_layout_surfaceSetDestinationRectangle(ivisurf, 0, 0, -+ (uint32_t)surface_width, (uint32_t)surface_height); - } -+ - } - - static void -@@ -368,8 +338,11 @@ mode_random_replace(struct hmi_controller *hmi_ctrl, - const int32_t surface_height = (int32_t)(layer->height * 0.25f); - int32_t surface_x = 0; - int32_t surface_y = 0; -+ -+ - struct ivi_layout_surface *ivisurf = NULL; -- int32_t ret = 0; -+ -+ const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; - - int32_t i = 0; - for (i = 0; i < surface_length; i++) { -@@ -380,16 +353,15 @@ mode_random_replace(struct hmi_controller *hmi_ctrl, - continue; - } - -+ ivi_layout_surfaceSetTransition(ivisurf,IVI_LAYOUT_TRANSITION_VIEW_DEFAULT,duration); -+ ivi_layout_surfaceSetVisibility(ivisurf, 1); - surface_x = rand() % (layer->width - surface_width); - surface_y = rand() % (layer->height - surface_height); - -- ret = ivi_layout_surfaceSetDestinationRectangle(ivisurf, surface_x, surface_y, -- surface_width, surface_height); -- assert(!ret); -- -- ret = ivi_layout_surfaceSetVisibility(ivisurf, 1); -- assert(!ret); -+ ivi_layout_surfaceSetDestinationRectangle(ivisurf, surface_x, surface_y, -+ surface_width, surface_height); - } -+ - } - - static int32_t -@@ -458,7 +430,6 @@ switch_mode(struct hmi_controller *hmi_ctrl, - } - - ivi_layout_commitChanges(); -- - free(ppSurface); - ppSurface = NULL; - -@@ -466,280 +437,21 @@ switch_mode(struct hmi_controller *hmi_ctrl, - } - - /** -- * Internal method for animation -+ * Internal method for transition - */ - static void --hmi_controller_animation_frame( -- struct hmi_controller_animation *animation, int32_t timestamp) --{ -- if (0 == animation->time_start) { -- animation->time_start = timestamp; -- } -- -- animation->frame_func(animation, timestamp); -- animation->frame_user_func(animation); --} -- --static int --animation_set_do_anima(void* data) --{ -- struct animation_set *anima_set = data; -- int32_t fps = 30; -- -- if (wl_list_empty(&anima_set->animation_list)) { -- wl_event_source_timer_update(anima_set->event_source, 0); -- return 1; -- } -- -- wl_event_source_timer_update(anima_set->event_source, 1000 / fps); -- -- struct timespec timestamp = {0}; -- clock_gettime(CLOCK_MONOTONIC, ×tamp); -- int32_t msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec); -- -- struct link_animation *link_animation = NULL; -- struct link_animation *next = NULL; -- -- wl_list_for_each_safe(link_animation, next, &anima_set->animation_list, link) { -- hmi_controller_animation_frame(link_animation->animation, msec); -- } -- -- ivi_layout_commitChanges(); -- return 1; --} -- --static struct animation_set * --animation_set_create(struct weston_compositor* ec) --{ -- struct animation_set *anima_set = MEM_ALLOC(sizeof(*anima_set)); -- -- wl_list_init(&anima_set->animation_list); -- -- struct wl_event_loop *loop = wl_display_get_event_loop(ec->wl_display); -- anima_set->event_source = wl_event_loop_add_timer(loop, animation_set_do_anima, anima_set); -- wl_event_source_timer_update(anima_set->event_source, 0); -- -- return anima_set; --} -- --static void --animation_set_add_animation(struct animation_set *anima_set, -- struct hmi_controller_animation *anima) --{ -- struct link_animation *link_anima = NULL; -- -- link_anima = MEM_ALLOC(sizeof(*link_anima)); -- if (NULL == link_anima) { -- return; -- } -- -- link_anima->animation = anima; -- wl_list_insert(&anima_set->animation_list, &link_anima->link); -- wl_event_source_timer_update(anima_set->event_source, 1); --} -- --static void --animation_set_remove_animation(struct animation_set *anima_set, -- struct hmi_controller_animation *anima) --{ -- struct link_animation *link_animation = NULL; -- struct link_animation *next = NULL; -- -- wl_list_for_each_safe(link_animation, next, &anima_set->animation_list, link) { -- if (link_animation->animation == anima) { -- wl_list_remove(&link_animation->link); -- free(link_animation); -- break; -- } -- } --} -- --static void --hmi_controller_animation_spring_frame( -- struct hmi_controller_animation_fade *animation, int32_t timestamp) --{ -- if (0 == animation->spring.timestamp) { -- animation->spring.timestamp = timestamp; -- } -- -- weston_spring_update(&animation->spring, timestamp); -- animation->base.is_done = weston_spring_done(&animation->spring); --} -- --static void --hmi_controller_animation_move_frame( -- struct hmi_controller_animation_move *animation, int32_t timestamp) --{ -- double s = animation->pos_start; -- double t = timestamp - animation->base.time_start; -- double v0 = animation->v0; -- double a = animation->a; -- double time_end = animation->time_end; -- -- if (time_end <= t) { -- animation->pos = animation->pos_end; -- animation->base.is_done = 1; -- } else { -- animation->pos = v0 * t + 0.5 * a * t * t + s; -- } --} -- --static void --hmi_controller_animation_destroy(struct hmi_controller_animation *animation) --{ -- if (animation->destroy_func) { -- animation->destroy_func(animation); -- } -- -- free(animation); --} -- --static void --hmi_controller_fade_animation_destroy(struct hmi_controller_animation *animation) --{ -- struct hmi_controller_fade *fade = animation->user_data; -- animation_set_remove_animation(fade->anima_set, animation); -- fade->animation = NULL; -- animation->user_data = NULL; --} -- --static struct hmi_controller_animation_fade * --hmi_controller_animation_fade_create(double start, double end, double k, -- hmi_controller_animation_frame_user_func frame_user_func, void* user_data, -- hmi_controller_animation_destroy_func destroy_func) --{ -- struct hmi_controller_animation_fade* animation = MEM_ALLOC(sizeof(*animation)); -- -- animation->base.frame_user_func = frame_user_func; -- animation->base.user_data = user_data; -- animation->base.frame_func = -- (hmi_controller_animation_frame_func)hmi_controller_animation_spring_frame; -- animation->base.destroy_func = destroy_func; -- -- animation->start = start; -- animation->end = end; -- weston_spring_init(&animation->spring, k, start, end); -- animation->spring.friction = 1400; -- animation->spring.previous = -(end - start) * 0.03; -- -- return animation; --} -- --static struct hmi_controller_animation_move * --hmi_controller_animation_move_create( -- double pos_start, double pos_end, double v_start, double v_end, -- hmi_controller_animation_frame_user_func frame_user_func, void* user_data, -- hmi_controller_animation_destroy_func destroy_func) --{ -- struct hmi_controller_animation_move* animation = MEM_ALLOC(sizeof(*animation)); -- -- animation->base.frame_user_func = frame_user_func; -- animation->base.user_data = user_data; -- animation->base.frame_func = -- (hmi_controller_animation_frame_func)hmi_controller_animation_move_frame; -- animation->base.destroy_func = destroy_func; -- -- animation->pos_start = pos_start; -- animation->pos_end = pos_end; -- animation->v0 = v_start; -- animation->pos = pos_start; -- -- double dx = (pos_end - pos_start); -- -- if (1e-3 < fabs(dx)) { -- animation->a = 0.5 * (v_end * v_end - v_start * v_start) / dx; -- if (1e-6 < fabs(animation->a)) { -- animation->time_end = (v_end - v_start) / animation->a; -- -- } else { -- animation->a = 0; -- animation->time_end = fabs(dx / animation->v0); -- } -- -- } else { -- animation->time_end = 0; -- } -- -- return animation; --} -- --static double --hmi_controller_animation_fade_alpha_get(struct hmi_controller_animation_fade* animation) --{ -- if (animation->spring.current > 0.999) { -- return 1.0; -- } else if (animation->spring.current < 0.001 ) { -- return 0.0; -- } else { -- return animation->spring.current; -- } --} -- --static int32_t --hmi_controller_animation_is_done(struct hmi_controller_animation *animation) --{ -- return animation->is_done; --} -- --static void --hmi_controller_fade_update(struct hmi_controller_animation_fade *animation, double end) --{ -- animation->spring.target = end; --} -- --static void --hmi_controller_anima_fade_user_frame(struct hmi_controller_animation_fade *animation) --{ -- double alpha = hmi_controller_animation_fade_alpha_get(animation); -- alpha = wl_fixed_from_double(alpha); -- struct hmi_controller_fade *fade = animation->base.user_data; -- struct link_layer *linklayer = NULL; -- int32_t is_done = hmi_controller_animation_is_done(&animation->base); -- int32_t is_visible = !is_done || fade->isFadeIn; -- -- wl_list_for_each(linklayer, &fade->layer_list, link) { -- ivi_layout_layerSetOpacity(linklayer->layout_layer, alpha); -- ivi_layout_layerSetVisibility(linklayer->layout_layer, is_visible); -- } -- -- if (is_done) { -- hmi_controller_animation_destroy(&animation->base); -- } --} -- --static void --hmi_controller_anima_move_user_frame(struct hmi_controller_animation_move *animation) --{ -- struct move_animation_user_data* user_data = animation->base.user_data; -- struct ivi_layout_layer *layer = user_data->layer; -- int32_t is_done = hmi_controller_animation_is_done(&animation->base); -- -- int32_t pos[2] = {0}; -- ivi_layout_layerGetPosition(layer, pos); -- -- pos[0] = (int32_t)animation->pos; -- ivi_layout_layerSetPosition(layer, pos); -- -- if (is_done) { -- hmi_controller_animation_destroy(&animation->base); -- } --} -- --static void --hmi_controller_fade_run(int32_t isFadeIn, struct hmi_controller_fade *fade) -+hmi_controller_fade_run(struct hmi_controller* hmi_ctrl, uint32_t isFadeIn, struct hmi_controller_fade *fade) - { - double tint = isFadeIn ? 1.0 : 0.0; - fade->isFadeIn = isFadeIn; - -- if (fade->animation) { -- hmi_controller_fade_update(fade->animation, tint); -- } else { -- fade->animation = hmi_controller_animation_fade_create( -- 1.0 - tint, tint, 300.0, -- (hmi_controller_animation_frame_user_func)hmi_controller_anima_fade_user_frame, -- fade, hmi_controller_fade_animation_destroy); -+ struct link_layer* linklayer = NULL; -+ -+ const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; - -- animation_set_add_animation(fade->anima_set, &fade->animation->base); -+ wl_list_for_each(linklayer, &fade->layer_list, link){ -+ ivi_layout_layerSetTransition(linklayer->layout_layer,IVI_LAYOUT_TRANSITION_LAYER_FADE,duration); -+ ivi_layout_layerSetFadeInfo(linklayer->layout_layer,isFadeIn,1.0 - tint, tint); - } - } - -@@ -833,6 +545,10 @@ hmi_server_setting_create(void) - weston_config_section_get_uint( - shellSection, "application-layer-id", &setting->application_layer_id, 4000); - -+ weston_config_section_get_uint( -+ shellSection, "transition-duration", -+ &setting->transition_duration, 300); -+ - setting->panel_height = 70; - - weston_config_section_get_string( -@@ -925,9 +641,6 @@ hmi_controller_create(struct weston_compositor *ec) - ivi_layout_layerSetOpacity(hmi_ctrl->workspace_layer.ivilayer, 0); - ivi_layout_layerSetVisibility(hmi_ctrl->workspace_layer.ivilayer, 0); - -- /* set up animation to workspace background and workspace */ -- hmi_ctrl->anima_set = animation_set_create(ec); -- - wl_list_init(&hmi_ctrl->workspace_fade.layer_list); - tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer)); - tmp_link_layer->layout_layer = hmi_ctrl->workspace_layer.ivilayer; -@@ -935,7 +648,6 @@ hmi_controller_create(struct weston_compositor *ec) - tmp_link_layer = MEM_ALLOC(sizeof(*tmp_link_layer)); - tmp_link_layer->layout_layer = hmi_ctrl->workspace_background_layer.ivilayer; - wl_list_insert(&hmi_ctrl->workspace_fade.layer_list, &tmp_link_layer->link); -- hmi_ctrl->workspace_fade.anima_set = hmi_ctrl->anima_set; - - ivi_layout_addNotificationCreateSurface(set_notification_create_surface, hmi_ctrl); - ivi_layout_addNotificationRemoveSurface(set_notification_remove_surface, hmi_ctrl); -@@ -1018,7 +730,9 @@ ivi_hmi_controller_set_panel(struct wl_resource *resource, - - ret = ivi_layout_layerAddSurface(ivilayer, ivisurf); - assert(!ret); -+ - int32_t panel_height = hmi_ctrl->hmi_setting->panel_height; -+ - const int32_t dstx = 0; - const int32_t dsty = hmi_ctrl->base_layer.height - panel_height; - -@@ -1447,19 +1161,6 @@ range_val(int32_t val, int32_t min, int32_t max) - } - - static void --hmi_controller_move_animation_destroy(struct hmi_controller_animation *animation) --{ -- struct move_animation_user_data *user_data = animation->user_data; -- if (animation == &user_data->hmi_ctrl->workspace_swipe_animation->base) { -- user_data->hmi_ctrl->workspace_swipe_animation = NULL; -- } -- -- animation_set_remove_animation(user_data->anima_set, animation); -- free(animation->user_data); -- animation->user_data = NULL; --} -- --static void - move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource, - wl_fixed_t grab_x, struct ivi_layout_layer *layer) - { -@@ -1505,6 +1206,7 @@ move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource, - page_no = range_val(page_no, 0, hmi_ctrl->workspace_count - 1); - double end_pos = -page_no * width; - -+/* - double dst = fabs(end_pos - pos[0]); - double max_time = 0.5 * 1e+3; - double v = dst / max_time; -@@ -1520,23 +1222,16 @@ move_workspace_grab_end(struct move_grab *move, struct wl_resource* resource, - } else { - v0 = -v; - } -+*/ - -- struct move_animation_user_data *animation_user_data = NULL; -- animation_user_data = MEM_ALLOC(sizeof(*animation_user_data)); -- animation_user_data->layer = layer; -- animation_user_data->anima_set = hmi_ctrl->anima_set; -- animation_user_data->hmi_ctrl = hmi_ctrl; -- -- struct hmi_controller_animation_move* animation = NULL; -- animation = hmi_controller_animation_move_create( -- pos[0], end_pos, v0, v0, -- (hmi_controller_animation_frame_user_func)hmi_controller_anima_move_user_frame, -- animation_user_data, hmi_controller_move_animation_destroy); -- -- hmi_ctrl->workspace_swipe_animation = animation; -- animation_set_add_animation(hmi_ctrl->anima_set, &animation->base); -- -+ const uint32_t duration = hmi_ctrl->hmi_setting->transition_duration; - ivi_hmi_controller_send_workspace_end_control(resource, move->is_moved); -+ ivi_layout_layerSetTransition(layer,IVI_LAYOUT_TRANSITION_LAYER_MOVE,duration); -+ ivi_layout_layerSetDestinationRectangle(layer, -+ end_pos, pos[1], -+ hmi_ctrl->workspace_background_layer.width, -+ hmi_ctrl->workspace_background_layer.height); -+ ivi_layout_commitChanges(); - } - - static void -@@ -1814,14 +1509,12 @@ ivi_hmi_controller_workspace_control(struct wl_client *client, - return; - } - -- if (hmi_ctrl->workspace_swipe_animation) { -- hmi_controller_animation_destroy(&hmi_ctrl->workspace_swipe_animation->base); -- } -- - struct ivi_layout_layer *layer = hmi_ctrl->workspace_layer.ivilayer; - struct pointer_move_grab *pnt_move_grab = NULL; - struct touch_move_grab *tch_move_grab = NULL; - -+ ivi_layout_transition_move_layer_cancel(layer); -+ - switch (device) { - case HMI_GRAB_DEVICE_POINTER: - pnt_move_grab = create_workspace_pointer_move(seat->pointer, resource); -@@ -1869,9 +1562,11 @@ ivi_hmi_controller_home(struct wl_client *client, - if ((IVI_HMI_CONTROLLER_HOME_ON == home && !hmi_ctrl->workspace_fade.isFadeIn) || - (IVI_HMI_CONTROLLER_HOME_OFF == home && hmi_ctrl->workspace_fade.isFadeIn)) { - -- int32_t isFadeIn = !hmi_ctrl->workspace_fade.isFadeIn; -- hmi_controller_fade_run(isFadeIn, &hmi_ctrl->workspace_fade); -+ uint32_t isFadeIn = !hmi_ctrl->workspace_fade.isFadeIn; -+ hmi_controller_fade_run(hmi_ctrl, isFadeIn, &hmi_ctrl->workspace_fade); - } -+ -+ ivi_layout_commitChanges(); - } - - /** -diff --git a/ivi-shell/ivi-layout-export.h b/ivi-shell/ivi-layout-export.h -index 81dd6f3..ea1adea 100644 ---- a/ivi-shell/ivi-layout-export.h -+++ b/ivi-shell/ivi-layout-export.h -@@ -52,57 +52,6 @@ extern "C" { - #include "compositor.h" - #include "ivi-layout.h" - --struct ivi_layout_SurfaceProperties --{ -- float opacity; -- int32_t sourceX; -- int32_t sourceY; -- int32_t sourceWidth; -- int32_t sourceHeight; -- int32_t origSourceWidth; -- int32_t origSourceHeight; -- int32_t destX; -- int32_t destY; -- int32_t destWidth; -- int32_t destHeight; -- int32_t orientation; -- int32_t visibility; -- int32_t frameCounter; -- int32_t drawCounter; -- int32_t updateCounter; -- int32_t pixelformat; -- int32_t nativeSurface; -- int32_t inputDevicesAcceptance; -- int32_t chromaKeyEnabled; -- int32_t chromaKeyRed; -- int32_t chromaKeyGreen; -- int32_t chromaKeyBlue; -- int32_t creatorPid; --}; -- --struct ivi_layout_LayerProperties --{ -- float opacity; -- int32_t sourceX; -- int32_t sourceY; -- int32_t sourceWidth; -- int32_t sourceHeight; -- int32_t origSourceWidth; -- int32_t origSourceHeight; -- int32_t destX; -- int32_t destY; -- int32_t destWidth; -- int32_t destHeight; -- int32_t orientation; -- int32_t visibility; -- int32_t type; -- int32_t chromaKeyEnabled; -- int32_t chromaKeyRed; -- int32_t chromaKeyGreen; -- int32_t chromaKeyBlue; -- int32_t creatorPid; --}; -- - struct ivi_layout_layer; - struct ivi_layout_screen; - -@@ -121,6 +70,17 @@ enum ivi_layout_notification_mask { - IVI_NOTIFICATION_ALL = 0xFFFF - }; - -+enum ivi_layout_transition_type{ -+ IVI_LAYOUT_TRANSITION_NONE, -+ IVI_LAYOUT_TRANSITION_VIEW_DEFAULT, -+ IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY, -+ IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY, -+ IVI_LAYOUT_TRANSITION_LAYER_FADE, -+ IVI_LAYOUT_TRANSITION_LAYER_MOVE, -+ IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER, -+ IVI_LAYOUT_TRANSITION_MAX, -+}; -+ - typedef void(*shellWarningNotificationFunc)(uint32_t id_surface, - enum ivi_layout_warning_flag warn, - void *userdata); -@@ -948,6 +908,24 @@ ivi_layout_surfaceSetSourceRectangle(struct ivi_layout_surface *ivisurf, - struct weston_output * - ivi_layout_screenGetOutput(struct ivi_layout_screen *); - -+int32_t -+ivi_layout_layerSetTransition(struct ivi_layout_layer *ivilayer, -+ enum ivi_layout_transition_type type, -+ uint32_t duration); -+ -+int32_t -+ivi_layout_layerSetFadeInfo(struct ivi_layout_layer* layer, -+ uint32_t is_fade_in, -+ double start_alpha, double end_alpha); -+ -+int32_t -+ivi_layout_surfaceSetTransition(struct ivi_layout_surface *ivisurf, -+ enum ivi_layout_transition_type type, -+ uint32_t duration); -+ -+int32_t -+ivi_layout_surfaceSetTransitionDuration(struct ivi_layout_surface *ivisurf,uint32_t duration); -+ - /** - * \brief Commit all changes and execute all enqueued commands since last commit. - * -diff --git a/ivi-shell/ivi-layout-private.h b/ivi-shell/ivi-layout-private.h -new file mode 100644 -index 0000000..f05f8e9 ---- /dev/null -+++ b/ivi-shell/ivi-layout-private.h -@@ -0,0 +1,207 @@ -+/* -+ * Copyright (C) 2014 DENSO CORPORATION -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and -+ * its documentation for any purpose is hereby granted without fee, provided -+ * that the above copyright notice appear in all copies and that both that -+ * copyright notice and this permission notice appear in supporting -+ * documentation, and that the name of the copyright holders not be used in -+ * advertising or publicity pertaining to distribution of the software -+ * without specific, written prior permission. The copyright holders make -+ * no representations about the suitability of this software for any -+ * purpose. It is provided "as is" without express or implied warranty. -+ * -+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS -+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY -+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#ifndef _ivi_layout_PRIVATE_H_ -+#define _ivi_layout_PRIVATE_H_ -+ -+#include "compositor.h" -+#include "ivi-layout.h" -+#include "ivi-layout-transition.h" -+ -+struct ivi_layout_surface { -+ struct wl_list link; -+ struct wl_signal property_changed; -+ struct wl_list list_layer; -+ int32_t update_count; -+ uint32_t id_surface; -+ -+ struct ivi_layout *layout; -+ struct weston_surface *surface; -+ -+ struct wl_listener surface_destroy_listener; -+ struct weston_transform surface_rotation; -+ struct weston_transform layer_rotation; -+ struct weston_transform surface_pos; -+ struct weston_transform layer_pos; -+ struct weston_transform scaling; -+ struct ivi_layout_SurfaceProperties prop; -+ int32_t pixelformat; -+ uint32_t event_mask; -+ -+ struct { -+ struct ivi_layout_SurfaceProperties prop; -+ struct wl_list link; -+ } pending; -+ -+ struct { -+ struct wl_list link; -+ struct wl_list list_layer; -+ } order; -+ -+ struct { -+ ivi_controller_surface_content_callback callback; -+ void* userdata; -+ } content_observer; -+}; -+ -+struct ivi_layout_layer { -+ struct wl_list link; -+ struct wl_signal property_changed; -+ struct wl_list list_screen; -+ struct wl_list link_to_surface; -+ uint32_t id_layer; -+ -+ struct ivi_layout *layout; -+ -+ struct ivi_layout_LayerProperties prop; -+ uint32_t event_mask; -+ -+ struct { -+ struct ivi_layout_LayerProperties prop; -+ struct wl_list list_surface; -+ struct wl_list link; -+ } pending; -+ -+ struct { -+ struct wl_list list_surface; -+ struct wl_list link; -+ } order; -+}; -+ -+/* -+struct ivi_layout_surface { -+ struct wl_list link; -+ struct wl_list list_notification; -+ struct wl_list list_layer; -+ uint32_t update_count; -+ uint32_t id_surface; -+ -+ struct ivi_layout *layout; -+ struct weston_surface *surface; -+ struct weston_view *view; -+ -+ uint32_t buffer_width; -+ uint32_t buffer_height; -+ -+ struct wl_listener surface_destroy_listener; -+ struct weston_transform surface_rotation; -+ struct weston_transform layer_rotation; -+ struct weston_transform surface_pos; -+ struct weston_transform layer_pos; -+ struct weston_transform scaling; -+ struct ivi_layout_SurfaceProperties prop; -+ int32_t pixelformat; -+ uint32_t event_mask; -+ -+ struct { -+ struct ivi_layout_SurfaceProperties prop; -+ struct wl_list link; -+ } pending; -+ -+ struct { -+ struct wl_list link; -+ struct wl_list list_layer; -+ } order; -+ -+ struct { -+ ivi_controller_surface_content_callback callback; -+ void* userdata; -+ } content_observer; -+}; -+ -+struct ivi_layout_layer { -+ struct wl_list link; -+ struct wl_list list_notification; -+ struct wl_list list_screen; -+ struct wl_list link_to_surface; -+ uint32_t id_layer; -+ -+ struct ivi_layout *layout; -+ -+ struct ivi_layout_LayerProperties prop; -+ uint32_t event_mask; -+ -+ struct { -+ struct ivi_layout_LayerProperties prop; -+ struct wl_list list_surface; -+ struct wl_list link; -+ } pending; -+ -+ struct { -+ struct wl_list list_surface; -+ struct wl_list link; -+ } order; -+}; -+*/ -+ -+struct ivi_layout { -+ struct weston_compositor *compositor; -+ -+ struct wl_list list_surface; -+ struct wl_list list_layer; -+ struct wl_list list_screen; -+ -+ struct { -+ struct wl_signal created; -+ struct wl_signal removed; -+ } layer_notification; -+ -+ struct { -+ struct wl_signal created; -+ struct wl_signal removed; -+ struct wl_signal configure_changed; -+ } surface_notification; -+ -+ struct weston_layer layout_layer; -+ struct wl_signal warning_signal; -+ -+ struct ivi_layout_transition_set* transitions; -+ struct wl_list pending_transition_list; -+}; -+/* -+struct ivi_layout { -+ struct weston_compositor *compositor; -+ -+ struct wl_list list_surface; -+ struct wl_list list_layer; -+ struct wl_list list_screen; -+ -+ struct { -+ struct wl_list list_create; -+ struct wl_list list_remove; -+ } layer_notification; -+ -+ struct { -+ struct wl_list list_create; -+ struct wl_list list_remove; -+ struct wl_list list_configure; -+ } surface_notification; -+ -+ struct weston_layer layout_layer; -+ -+ struct ivi_layout_transition_set* transitions; -+ struct wl_list pending_transition_list; -+}; -+*/ -+struct ivi_layout *get_instance(void); -+ -+#endif -diff --git a/ivi-shell/ivi-layout-transition.c b/ivi-shell/ivi-layout-transition.c -new file mode 100644 -index 0000000..1f1e846 ---- /dev/null -+++ b/ivi-shell/ivi-layout-transition.c -@@ -0,0 +1,1013 @@ -+/* -+ * Copyright (C) 2014 DENSO CORPORATION -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and -+ * its documentation for any purpose is hereby granted without fee, provided -+ * that the above copyright notice appear in all copies and that both that -+ * copyright notice and this permission notice appear in supporting -+ * documentation, and that the name of the copyright holders not be used in -+ * advertising or publicity pertaining to distribution of the software -+ * without specific, written prior permission. The copyright holders make -+ * no representations about the suitability of this software for any -+ * purpose. It is provided "as is" without express or implied warranty. -+ * -+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS -+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY -+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include <time.h> -+#include <assert.h> -+#include <stdlib.h> -+#include <stdio.h> -+ -+#include "ivi-layout.h" -+#include "ivi-layout-export.h" -+#include "ivi-layout-transition.h" -+#include "ivi-layout-private.h" -+ -+struct ivi_layout_transition; -+typedef void (*ivi_layout_transition_frame_func)(struct ivi_layout_transition *transition); -+typedef void (*ivi_layout_transition_destroy_func)(struct ivi_layout_transition* transition); -+typedef int32_t (*ivi_layout_transition_identifire_func)(void* private_data, void* id); -+ -+enum ivi_layout_inner_transition_type{ -+ IVI_LAYOUT_INNER_TRANSITION_NONE, -+ IVI_LAYOUT_INNER_TRANSITION_VIEW_MOVE_RESIZE, -+ IVI_LAYOUT_INNER_TRANSITION_VIEW_RESIZE, -+ IVI_LAYOUT_INNER_TRANSITION_VIEW_FADE, -+ IVI_LAYOUT_INNER_TRANSITION_LAYER_FADE, -+ IVI_LAYOUT_INNER_TRANSITION_LAYER_MOVE, -+ IVI_LAYOUT_INNER_TRANSITION_LAYER_VIEW_ORDER, -+ IVI_LAYOUT_INNER_TRANSITION_MAX, -+}; -+ -+struct ivi_layout_transition { -+ enum ivi_layout_inner_transition_type type; -+ void *private_data; -+ void *user_data; -+ -+ uint32_t time_start; -+ uint32_t time_duration; -+ uint32_t time_elapsed; -+ uint32_t is_done; -+ ivi_layout_transition_identifire_func id_func; -+ ivi_layout_transition_frame_func frame_func; -+ ivi_layout_transition_destroy_func destroy_func; -+}; -+ -+struct transition_node { -+ struct ivi_layout_transition *transition; -+ struct wl_list link; -+}; -+ -+static void layout_transition_destroy(struct ivi_layout_transition* transition); -+ -+static struct ivi_layout_transition* -+get_transition_from_type_and_id(enum ivi_layout_inner_transition_type type, void* id_data) -+{ -+ struct ivi_layout* layout = get_instance(); -+ struct transition_node *node=NULL; -+ wl_list_for_each(node, &layout->transitions->transition_list, link){ -+ if(node->transition->type == type) -+ if(node->transition->id_func(node->transition->private_data, id_data)) -+ return node->transition; -+ } -+ return NULL; -+} -+ -+static void -+tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp) -+{ -+ const double t = timestamp - transition->time_start; -+ -+ if (transition->time_duration <= t) { -+ transition->time_elapsed = transition->time_duration; -+ transition->is_done = 1; -+ } else { -+ transition->time_elapsed = t; -+ } -+} -+ -+static float time_to_nowpos(struct ivi_layout_transition* transition) -+{ -+ return sin((float)transition->time_elapsed / (float)transition->time_duration * M_PI_2); -+} -+ -+static void -+do_transition_frame( -+ struct ivi_layout_transition *transition, uint32_t timestamp) -+{ -+ if (0 == transition->time_start) { -+ transition->time_start = timestamp; -+ } -+ -+ tick_transition(transition, timestamp); -+ transition->frame_func(transition); -+ -+ if(transition->is_done){ -+ layout_transition_destroy(transition); -+ } -+} -+ -+static int32_t -+layout_transition_frame(void* data) -+{ -+ struct ivi_layout_transition_set *transitions = data; -+ uint32_t fps = 30; -+ -+ if (wl_list_empty(&transitions->transition_list)) { -+ wl_event_source_timer_update(transitions->event_source, 0); -+ return 1; -+ } -+ -+ wl_event_source_timer_update(transitions->event_source, 1000 / fps); -+ -+ struct timespec timestamp = {0}; -+ clock_gettime(CLOCK_MONOTONIC, ×tamp); -+ uint32_t msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec); -+ -+ struct transition_node *node = NULL; -+ struct transition_node *next = NULL; -+ -+ wl_list_for_each_safe(node, next, &transitions->transition_list, link) { -+ do_transition_frame(node->transition, msec); -+ } -+ -+ ivi_layout_commitChanges(); -+ return 1; -+} -+ -+WL_EXPORT struct ivi_layout_transition_set * -+ivi_layout_transition_set_create(struct weston_compositor* ec) -+{ -+ struct ivi_layout_transition_set *transitions = malloc(sizeof(*transitions)); -+ assert(transitions); -+ -+ wl_list_init(&transitions->transition_list); -+ -+ struct wl_event_loop *loop = wl_display_get_event_loop(ec->wl_display); -+ transitions->event_source = wl_event_loop_add_timer(loop, layout_transition_frame, transitions); -+ wl_event_source_timer_update(transitions->event_source, 0); -+ -+ return transitions; -+} -+ -+static void -+layout_transition_register(struct ivi_layout_transition *trans) -+{ -+ struct ivi_layout* layout = get_instance(); -+ struct transition_node *node = NULL; -+ -+ node = malloc(sizeof(*node)); -+ assert(node); -+ -+ node->transition = trans; -+ wl_list_insert(&layout->pending_transition_list, &node->link); -+} -+ -+static void -+remove_transition(struct ivi_layout* layout, -+ struct ivi_layout_transition *trans) -+{ -+ struct transition_node *node = NULL; -+ struct transition_node *next = NULL; -+ -+ wl_list_for_each_safe(node, next, &layout->transitions->transition_list, link) { -+ if (node->transition == trans) { -+ wl_list_remove(&node->link); -+ free(node); -+ return; -+ } -+ } -+ -+ wl_list_for_each_safe(node, next, &layout->pending_transition_list, link) { -+ if (node->transition == trans) { -+ wl_list_remove(&node->link); -+ free(node); -+ return; -+ } -+ } -+ -+ return; -+} -+ -+static void -+layout_transition_destroy(struct ivi_layout_transition *transition) -+{ -+ struct ivi_layout* layout = get_instance(); -+ -+ remove_transition(layout, transition); -+ if(transition->destroy_func) -+ transition->destroy_func(transition); -+ free(transition); -+} -+ -+static struct ivi_layout_transition* -+create_layout_transition(void) -+{ -+ struct ivi_layout_transition* transition = malloc(sizeof(*transition)); -+ assert(transition); -+ -+ transition->type = IVI_LAYOUT_INNER_TRANSITION_MAX; -+ transition->time_start = 0; -+ transition->time_duration = 300; // 300ms -+ transition->time_elapsed = 0; -+ -+ transition->is_done = 0; -+ -+ transition->private_data = NULL; -+ transition->user_data = NULL; -+ -+ transition->frame_func = NULL; -+ transition->destroy_func = NULL; -+ -+ return transition; -+} -+ -+/* move and resize view transition */ -+ -+struct move_resize_view_data { -+ struct ivi_layout_surface* surface; -+ int32_t start_x; -+ int32_t start_y; -+ int32_t end_x; -+ int32_t end_y; -+ uint32_t start_width; -+ uint32_t start_height; -+ uint32_t end_width; -+ uint32_t end_height; -+}; -+ -+static void -+transition_move_resize_view_destroy(struct ivi_layout_transition* transition) -+{ -+ if(transition->private_data){ -+ free(transition->private_data); -+ transition->private_data = NULL; -+ } -+} -+ -+static void -+transition_move_resize_view_user_frame(struct ivi_layout_transition *transition) -+{ -+ struct move_resize_view_data* private_data = transition->private_data; -+ struct ivi_layout_surface *surface = private_data->surface; -+ -+ const double current = time_to_nowpos(transition); -+ const int32_t destx = private_data->start_x + (private_data->end_x - private_data->start_x)*current; -+ const int32_t desty = private_data->start_y + (private_data->end_y - private_data->start_y)*current; -+ -+ const uint32_t dest_width = (int32_t)private_data->start_width + -+ ((int32_t)private_data->end_width - (int32_t)private_data->start_width) *current; -+ -+ const uint32_t dest_height = (int32_t)private_data->start_height + -+ ((int32_t)private_data->end_height - (int32_t)private_data->start_height)*current; -+ -+ ivi_layout_surfaceSetDestinationRectangle(surface, -+ destx, desty, dest_width, dest_height); -+} -+ -+static int32_t -+transition_move_resize_view_identifire(struct move_resize_view_data* data, -+ struct ivi_layout_surface* view) -+{ -+ return data->surface == view; -+} -+ -+static struct ivi_layout_transition * -+create_move_resize_view_transition( -+ struct ivi_layout_surface* surface, -+ int32_t start_x, int32_t start_y, -+ int32_t end_x, int32_t end_y, -+ uint32_t start_width, uint32_t start_height, -+ uint32_t end_width, uint32_t end_height, -+ ivi_layout_transition_frame_func frame_func, -+ ivi_layout_transition_destroy_func destroy_func, -+ uint32_t duration) -+{ -+ struct ivi_layout_transition* transition = create_layout_transition(); -+ struct move_resize_view_data* data = malloc(sizeof(*data)); -+ -+ transition->type = IVI_LAYOUT_INNER_TRANSITION_VIEW_MOVE_RESIZE; -+ transition->id_func = (ivi_layout_transition_identifire_func)transition_move_resize_view_identifire; -+ -+ transition->frame_func = frame_func; -+ transition->destroy_func = destroy_func; -+ transition->private_data = data; -+ -+ if(duration != 0){ -+ transition->time_duration = duration; -+ } -+ -+ data->surface = surface; -+ data->start_x = start_x; -+ data->start_y = start_y; -+ data->end_x = end_x; -+ data->end_y = end_y; -+ -+ data->start_width = start_width; -+ data->start_height = start_height; -+ data->end_width = end_width; -+ data->end_height = end_height; -+ -+ return transition; -+} -+ -+WL_EXPORT void -+ivi_layout_transition_move_resize_view(struct ivi_layout_surface* surface, -+ int32_t dest_x, int32_t dest_y, -+ uint32_t dest_width, uint32_t dest_height, -+ uint32_t duration) -+{ -+ int32_t start_pos[2] = {surface->pending.prop.startX,surface->pending.prop.startY}; -+ -+ uint32_t start_size[2] = {surface->pending.prop.startWidth,surface->pending.prop.startHeight}; -+ -+ struct ivi_layout_transition* transition = NULL; -+ -+ transition = get_transition_from_type_and_id(IVI_LAYOUT_INNER_TRANSITION_VIEW_MOVE_RESIZE, -+ surface); -+ if(transition){ -+ -+ transition->time_start = 0; -+ transition->time_duration = duration; -+ -+ struct move_resize_view_data* data = transition->private_data; -+ data->start_x = start_pos[0]; -+ data->start_y = start_pos[1]; -+ data->end_x = dest_x; -+ data->end_y = dest_y; -+ -+ data->start_width = start_size[0]; -+ data->start_height = start_size[1]; -+ data->end_width = dest_width; -+ data->end_height = dest_height; -+ return; -+ } -+ -+ transition = create_move_resize_view_transition( -+ surface, -+ start_pos[0], start_pos[1], -+ dest_x, dest_y, -+ start_size[0], start_size[1], -+ dest_width, dest_height, -+ transition_move_resize_view_user_frame, -+ transition_move_resize_view_destroy, -+ duration); -+ -+ layout_transition_register(transition); -+ -+} -+ -+/* fade transition */ -+struct fade_view_data { -+ struct ivi_layout_surface* surface; -+ float start_alpha; -+ float end_alpha; -+}; -+ -+struct store_alpha{ -+ float alpha; -+}; -+ -+static void -+fade_view_user_frame(struct ivi_layout_transition *transition) -+{ -+ struct fade_view_data* private_data = transition->private_data; -+ struct ivi_layout_surface *surface = private_data->surface; -+ -+ const double current = time_to_nowpos(transition); -+ const float alpha = private_data->start_alpha + (private_data->end_alpha - private_data->start_alpha)*current; -+ -+ ivi_layout_surfaceSetOpacity(surface, wl_fixed_from_double(alpha)); -+ ivi_layout_surfaceSetVisibility(surface, 1); -+} -+ -+static int32_t -+transition_fade_view_identifire(struct fade_view_data* data, -+ struct ivi_layout_surface* view) -+{ -+ return data->surface == view; -+} -+ -+static struct ivi_layout_transition* -+create_fade_view_transition( -+ struct ivi_layout_surface* surface, -+ float start_alpha, float end_alpha, -+ ivi_layout_transition_frame_func frame_func, -+ void* user_data, -+ ivi_layout_transition_destroy_func destroy_func, -+ uint32_t duration) -+{ -+ struct ivi_layout_transition* transition = create_layout_transition(); -+ struct fade_view_data* data = malloc(sizeof(*data)); -+ assert(data); -+ -+ transition->type = IVI_LAYOUT_INNER_TRANSITION_VIEW_FADE; -+ transition->id_func = (ivi_layout_transition_identifire_func)transition_fade_view_identifire; -+ -+ transition->user_data = user_data; -+ transition->private_data = data; -+ transition->frame_func = frame_func; -+ transition->destroy_func = destroy_func; -+ -+ if(duration != 0){ -+ transition->time_duration = duration; -+ } -+ -+ data->surface = surface; -+ data->start_alpha = start_alpha; -+ data->end_alpha = end_alpha; -+ -+ return transition; -+} -+ -+static void -+create_visibility_transition(struct ivi_layout_surface* surface, -+ float start_alpha, -+ float dest_alpha, -+ void* user_data, -+ ivi_layout_transition_destroy_func destroy_func, -+ uint32_t duration) -+{ -+ struct ivi_layout_transition* transition = NULL; -+ -+ transition = create_fade_view_transition( -+ surface, -+ start_alpha, dest_alpha, -+ fade_view_user_frame, -+ user_data, -+ destroy_func, -+ duration); -+ -+ layout_transition_register(transition); -+ -+} -+ -+static void -+visibility_on_transition_destroy(struct ivi_layout_transition* transition) -+{ -+ struct fade_view_data *data = transition->private_data; -+ ivi_layout_surfaceSetVisibility(data->surface, 1); -+ -+ free(data); -+ transition->private_data = NULL; -+ -+ struct store_alpha *user_data = transition->user_data; -+ -+ free(user_data); -+ transition->user_data = NULL; -+ -+} -+ -+WL_EXPORT void -+ivi_layout_transition_visibility_on(struct ivi_layout_surface* surface, -+ uint32_t duration) -+{ -+ -+ struct ivi_layout_transition* transition = NULL; -+ -+ transition = get_transition_from_type_and_id(IVI_LAYOUT_INNER_TRANSITION_VIEW_FADE, -+ surface); -+ if(transition){ -+ transition->time_start = 0; -+ transition->time_duration = duration; -+ transition->destroy_func = visibility_on_transition_destroy; -+ -+ float start_alpha=0.0; -+ ivi_layout_surfaceGetOpacity(surface, &start_alpha); -+ -+ const struct store_alpha* user_data = transition->user_data; -+ struct fade_view_data* data = transition->private_data; -+ data->start_alpha = wl_fixed_to_double(start_alpha); -+ data->end_alpha = user_data->alpha; -+ return; -+ } -+ -+ int32_t is_visible = 0; -+ ivi_layout_surfaceGetVisibility(surface, &is_visible); -+ if(is_visible){ -+ return; -+ } -+ -+ float dest_alpha = 0; -+ ivi_layout_surfaceGetOpacity(surface, &dest_alpha); -+ -+ struct store_alpha* user_data = malloc(sizeof(*user_data)); -+ user_data->alpha = wl_fixed_to_double(dest_alpha); -+ -+ create_visibility_transition(surface, -+ 0.0, // start_alpha -+ wl_fixed_to_double(dest_alpha), -+ user_data, -+ visibility_on_transition_destroy, -+ duration); -+} -+ -+static void -+visibility_off_transition_destroy(struct ivi_layout_transition* transition) -+{ -+ struct fade_view_data *data = transition->private_data; -+ -+ ivi_layout_surfaceSetVisibility(data->surface, 0); -+ -+ struct store_alpha* user_data = transition->user_data; -+ ivi_layout_surfaceSetOpacity(data->surface, wl_fixed_from_double(user_data->alpha)); -+ -+ free(data); -+ transition->private_data = NULL; -+ -+ free(user_data); -+ transition->user_data= NULL; -+ -+} -+ -+WL_EXPORT void -+ivi_layout_transition_visibility_off(struct ivi_layout_surface* surface, -+ uint32_t duration) -+{ -+ -+ struct ivi_layout_transition* transition = NULL; -+ -+ transition = get_transition_from_type_and_id(IVI_LAYOUT_INNER_TRANSITION_VIEW_FADE, -+ surface); -+ if(transition){ -+ transition->time_start = 0; -+ transition->time_duration = duration; -+ transition->destroy_func = visibility_off_transition_destroy; -+ -+ float start_alpha=0.0; -+ ivi_layout_surfaceGetOpacity(surface, &start_alpha); -+ -+ struct fade_view_data* data = transition->private_data; -+ data->start_alpha = wl_fixed_to_double(start_alpha); -+ data->end_alpha = 0; -+ return; -+ } -+ -+ float start_alpha=0; -+ ivi_layout_surfaceGetOpacity(surface, &start_alpha); -+ -+ struct store_alpha* user_data = malloc(sizeof(*user_data)); -+ user_data->alpha = wl_fixed_to_double(start_alpha); -+ -+ create_visibility_transition(surface, -+ wl_fixed_to_double(start_alpha), -+ 0.0f, // dest_alpha -+ user_data, -+ visibility_off_transition_destroy, -+ duration); -+} -+ -+/* move layer transition */ -+ -+struct move_layer_data { -+ struct ivi_layout_layer* layer; -+ int32_t start_x; -+ int32_t start_y; -+ int32_t end_x; -+ int32_t end_y; -+ ivi_layout_transition_destroy_user_func destroy_func; -+}; -+ -+static void -+transition_move_layer_user_frame(struct ivi_layout_transition* transition) -+{ -+ struct move_layer_data* data = transition->private_data; -+ struct ivi_layout_layer* layer = data->layer; -+ -+ const float current = time_to_nowpos(transition); -+ -+ const int32_t dest_x = data->start_x + (data->end_x - data->start_x) * current; -+ const int32_t dest_y = data->start_y + (data->end_y - data->start_y) * current; -+ -+ int32_t pos[2] = {dest_x, dest_y}; -+ -+ ivi_layout_layerSetPosition(layer, pos); -+ -+} -+ -+static void -+transition_move_layer_destroy(struct ivi_layout_transition* transition) -+{ -+ -+ struct move_layer_data* data = transition->private_data; -+ -+ if(data->destroy_func) -+ data->destroy_func(transition->user_data); -+ -+ free(data); -+ transition->private_data = NULL; -+ -+} -+ -+static int32_t -+transition_move_layer_identifire(struct move_layer_data* data, struct ivi_layout_layer* layer) -+{ -+ return data->layer == layer; -+} -+ -+ -+static struct ivi_layout_transition* -+create_move_layer_transition( -+ struct ivi_layout_layer* layer, -+ int32_t start_x, int32_t start_y, -+ int32_t end_x, int32_t end_y, -+ void* user_data, -+ ivi_layout_transition_destroy_user_func destroy_user_func, -+ uint32_t duration) -+{ -+ struct ivi_layout_transition* transition = create_layout_transition(); -+ struct move_layer_data* data = malloc(sizeof(*data)); -+ -+ transition->type = IVI_LAYOUT_INNER_TRANSITION_LAYER_MOVE; -+ transition->id_func = (ivi_layout_transition_identifire_func)transition_move_layer_identifire; -+ -+ transition->frame_func = transition_move_layer_user_frame; -+ transition->destroy_func = transition_move_layer_destroy; -+ transition->private_data = data; -+ transition->user_data = user_data; -+ -+ if(duration != 0) -+ transition->time_duration = duration; -+ -+ data->layer = layer; -+ data->start_x = start_x; -+ data->start_y = start_y; -+ data->end_x = end_x; -+ data->end_y = end_y; -+ data->destroy_func = destroy_user_func; -+ -+ return transition; -+} -+ -+WL_EXPORT void -+ivi_layout_transition_move_layer(struct ivi_layout_layer* layer, -+ int32_t dest_x, int32_t dest_y, -+ uint32_t duration) -+{ -+ int32_t start_pos[2] = {}; -+ ivi_layout_layerGetPosition(layer, start_pos); -+ -+ struct ivi_layout_transition* transition = NULL; -+ transition = create_move_layer_transition( -+ layer, -+ start_pos[0], start_pos[1], -+ dest_x, dest_y, -+ NULL, NULL, -+ duration); -+ -+ layout_transition_register(transition); -+ -+ return; -+} -+ -+WL_EXPORT void -+ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer* layer) -+{ -+ struct ivi_layout_transition* transition = -+ get_transition_from_type_and_id(IVI_LAYOUT_INNER_TRANSITION_LAYER_MOVE, layer); -+ if(transition){ -+ layout_transition_destroy(transition); -+ } -+} -+ -+/* fade layer transition */ -+struct fade_layer_data { -+ struct ivi_layout_layer* layer; -+ int32_t is_fade_in; -+ double start_alpha; -+ double end_alpha; -+ ivi_layout_transition_destroy_user_func destroy_func; -+}; -+ -+static void -+transition_fade_layer_destroy(struct ivi_layout_transition* transition) -+{ -+ struct fade_layer_data* data = transition->private_data; -+ transition->private_data = NULL; -+ -+ free(data); -+} -+ -+static void -+transition_fade_layer_user_frame(struct ivi_layout_transition *transition) -+{ -+ double current = time_to_nowpos(transition); -+ struct fade_layer_data* data = transition->private_data; -+ double alpha = data->start_alpha + (data->end_alpha - data->start_alpha) * current; -+ int32_t fixed_alpha = wl_fixed_from_double(alpha); -+ -+ int32_t is_done = transition->is_done; -+ int32_t is_visible = !is_done || data->is_fade_in; -+ -+ ivi_layout_layerSetOpacity(data->layer, fixed_alpha); -+ ivi_layout_layerSetVisibility(data->layer, is_visible); -+} -+ -+static int32_t -+transition_fade_layer_identifire(struct fade_layer_data* data, struct ivi_layout_layer* layer) -+{ -+ return data->layer == layer; -+} -+ -+WL_EXPORT void -+ivi_layout_transition_fade_layer(struct ivi_layout_layer* layer, -+ int32_t is_fade_in, -+ double start_alpha, double end_alpha, -+ void* user_data, -+ ivi_layout_transition_destroy_user_func destroy_func, -+ uint32_t duration) -+{ -+ struct ivi_layout_transition* transition = NULL; -+ -+ transition = get_transition_from_type_and_id(IVI_LAYOUT_INNER_TRANSITION_LAYER_FADE, layer); -+ if(transition){ -+ /* transition update */ -+ struct fade_layer_data* data = transition->private_data; -+ -+ float fixed_opacity=0.0; //FIXME -+ ivi_layout_layerGetOpacity(layer, &fixed_opacity); -+ const double now_opacity = wl_fixed_to_double(fixed_opacity); -+ -+ data->is_fade_in = is_fade_in; -+ data->start_alpha = now_opacity; -+ data->end_alpha = end_alpha; -+ -+ float remain = is_fade_in? 1.0 - now_opacity : now_opacity; -+ transition->time_start = 0; -+ transition->time_elapsed = 0; -+ transition->time_duration = duration * remain; -+ -+ return; -+ } -+ -+ transition = create_layout_transition(); -+ struct fade_layer_data* data = malloc(sizeof(*data)); -+ assert(data); -+ -+ transition->type = IVI_LAYOUT_INNER_TRANSITION_LAYER_FADE; -+ transition->id_func = (ivi_layout_transition_identifire_func)transition_fade_layer_identifire; -+ -+ transition->private_data = data; -+ transition->user_data = user_data; -+ -+ transition->frame_func = transition_fade_layer_user_frame; -+ transition->destroy_func = transition_fade_layer_destroy; -+ -+ if(duration != 0){ -+ transition->time_duration = duration; -+ } -+ -+ data->layer = layer; -+ data->is_fade_in = is_fade_in; -+ data->start_alpha = start_alpha; -+ data->end_alpha = end_alpha; -+ data->destroy_func = destroy_func; -+ -+ layout_transition_register(transition); -+ -+ return; -+} -+ -+/* render order transition */ -+struct surface_reorder{ -+ uint32_t id_surface; -+ uint32_t new_index; -+}; -+ -+struct change_order_data{ -+ struct ivi_layout_layer* layer; -+ uint32_t surface_num; -+ struct surface_reorder* reorder; -+}; -+ -+struct surf_with_index{ -+ uint32_t id_surface; -+ float surface_index; -+}; -+ -+static int cmp_order_asc(const void* lhs, const void* rhs) -+{ -+ return ((struct surf_with_index*)lhs)->surface_index > ((struct surf_with_index*)rhs)->surface_index; -+} -+ -+/* -+render oerder transition -+ -+index 0 1 2 -+old surfA, surfB, surfC -+new surfB, surfC, surfA -+ (-1) (-1) (+2) -+ -+after 10% of time elapsed -+ 0.2 0.9 1.9 -+ surfA, surfB, surfC -+ -+after 50% of time elapsed -+ 0.5 1.0 1.5 -+ surfB, surfA, surfC -+*/ -+ -+static void -+transition_change_order_user_frame(struct ivi_layout_transition *transition) -+{ -+ uint32_t i, old_index; -+ double current = time_to_nowpos(transition); -+ struct change_order_data* data = transition->private_data; -+ -+ struct surf_with_index* swi = malloc(sizeof(*swi)*data->surface_num); -+ -+ for(old_index=0; old_index<data->surface_num; old_index++){ -+ swi[old_index].id_surface = data->reorder[old_index].id_surface; -+ swi[old_index].surface_index = (float)old_index + -+ ((float)data->reorder[old_index].new_index - (float)old_index) * current; -+ } -+ -+ qsort(swi, data->surface_num, sizeof(*swi), cmp_order_asc); -+ -+/* -+ fprintf(stderr, "=========\n"); -+ for(i=0; i<data->surface_num;i++){ -+ fprintf(stderr, "surface %d: %f\n", swi[i].id_surface, swi[i].surface_index); -+ } -+*/ -+ -+ struct ivi_layout_surface** new_surface_order = -+ malloc(sizeof(*new_surface_order) * data->surface_num); -+ -+ uint32_t surface_num = 0; -+ for(i=0; i<data->surface_num; i++){ -+ struct ivi_layout_surface* surf = ivi_layout_getSurfaceFromId(swi[i].id_surface); -+ if(surf) -+ new_surface_order[surface_num++] = surf; -+ } -+ -+ ivi_layout_layerSetRenderOrder(data->layer, new_surface_order, surface_num); -+ -+ free(new_surface_order); -+ free(swi); -+} -+ -+static void -+transition_change_order_destroy(struct ivi_layout_transition* transition) -+{ -+ struct change_order_data* data = transition->private_data; -+ -+ free(data->reorder); -+ free(data); -+} -+ -+static int32_t find_surface(struct ivi_layout_surface** surfaces, -+ uint32_t surface_num, -+ struct ivi_layout_surface* target) -+{ -+ uint32_t i=0; -+ for(i=0; i<surface_num; i++){ -+ if(surfaces[i] == target) -+ return i; -+ } -+ -+ return -1; -+} -+ -+static int32_t -+transition_change_order_identifire(struct change_order_data* data, struct ivi_layout_layer* layer) -+{ -+ return data->layer == layer; -+} -+ -+WL_EXPORT void -+ivi_layout_transition_layer_render_order(struct ivi_layout_layer* layer, -+ struct ivi_layout_surface** new_order, -+ uint32_t surface_num, -+ uint32_t duration) -+{ -+ struct surface_reorder* reorder = malloc(sizeof(*reorder)*surface_num); -+ struct ivi_layout_surface* surf=NULL; -+ uint32_t old_index = 0; -+ -+ wl_list_for_each(surf, &layer->order.list_surface, order.link){ -+ int32_t new_index = find_surface(new_order, surface_num, surf); -+ if(new_index < 0){ -+ fprintf(stderr, "invalid render order!!!\n"); -+ return; -+ } -+ -+ const uint32_t id = ivi_layout_getIdOfSurface(surf); -+ -+ reorder[old_index].id_surface = id; -+ reorder[old_index].new_index = new_index; -+ old_index++; -+ } -+ -+ struct ivi_layout_transition* transition = NULL; -+ -+ transition = get_transition_from_type_and_id(IVI_LAYOUT_INNER_TRANSITION_LAYER_VIEW_ORDER, layer); -+ if(transition){ -+ /* update transition */ -+ transition->time_start = 0; /* timer reset */ -+ -+ if(duration != 0){ -+ transition->time_duration = duration; -+ } -+ -+ struct change_order_data* data = transition->private_data; -+ free(data->reorder); -+ data->reorder = reorder; -+ return; -+ } -+ -+ transition = create_layout_transition(); -+ struct change_order_data* data = malloc(sizeof(*data)); -+ assert(data); -+ -+ transition->type = IVI_LAYOUT_INNER_TRANSITION_LAYER_VIEW_ORDER; -+ transition->id_func = (ivi_layout_transition_identifire_func)transition_change_order_identifire; -+ -+ transition->private_data = data; -+ transition->frame_func = transition_change_order_user_frame; -+ transition->destroy_func = transition_change_order_destroy; -+ -+ if(duration != 0){ -+ transition->time_duration = duration; -+ } -+ -+ data->layer = layer; -+ data->reorder = reorder; -+ data->surface_num = old_index; -+ -+ layout_transition_register(transition); -+ -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceSetTransition(struct ivi_layout_surface *ivisurf, -+ enum ivi_layout_transition_type type, -+ uint32_t duration) -+{ -+ struct ivi_layout_SurfaceProperties *prop = NULL; -+ -+ if (ivisurf == NULL) { -+ weston_log("ivi_layout_surfaceSetTransition: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivisurf->pending.prop; -+ prop->transitionType = type; -+ prop->transitionDuration = duration; -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceSetTransitionDuration(struct ivi_layout_surface *ivisurf,uint32_t duration) -+{ -+ struct ivi_layout_SurfaceProperties *prop = NULL; -+ -+ if (ivisurf == NULL) { -+ weston_log("ivi_layout_surfaceSetTransitionDuration: invalid argument\n"); -+ return -1; -+ } -+ -+ prop = &ivisurf->pending.prop; -+ prop->transitionDuration = duration*10; -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerSetTransition(struct ivi_layout_layer *ivilayer, -+ enum ivi_layout_transition_type type, -+ uint32_t duration) -+{ -+ if (ivilayer == NULL) { -+ weston_log("ivi_layout_layerSetTransitionType: invalid argument\n"); -+ return -1; -+ } -+ -+ ivilayer->pending.prop.transitionType = type; -+ ivilayer->pending.prop.transitionDuration = duration; -+ -+ return 0; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_layerSetFadeInfo(struct ivi_layout_layer* ivilayer, -+ uint32_t is_fade_in, -+ double start_alpha, double end_alpha) -+{ -+ if (ivilayer == NULL) { -+ weston_log("ivi_layout_layerSetFadeInfo: invalid argument\n"); -+ return -1; -+ } -+ -+ ivilayer->pending.prop.isFadeIn = is_fade_in; -+ ivilayer->pending.prop.startAlpha = start_alpha; -+ ivilayer->pending.prop.endAlpha = end_alpha; -+ -+ return 0; -+} -diff --git a/ivi-shell/ivi-layout-transition.h b/ivi-shell/ivi-layout-transition.h -new file mode 100644 -index 0000000..e8e5509 ---- /dev/null -+++ b/ivi-shell/ivi-layout-transition.h -@@ -0,0 +1,77 @@ -+/* -+ * Copyright (C) 2014 DENSO CORPORATION -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and -+ * its documentation for any purpose is hereby granted without fee, provided -+ * that the above copyright notice appear in all copies and that both that -+ * copyright notice and this permission notice appear in supporting -+ * documentation, and that the name of the copyright holders not be used in -+ * advertising or publicity pertaining to distribution of the software -+ * without specific, written prior permission. The copyright holders make -+ * no representations about the suitability of this software for any -+ * purpose. It is provided "as is" without express or implied warranty. -+ * -+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS -+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY -+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#ifndef _WESTON_LAYOUT_TRANSITION_H_ -+#define _WESTON_LAYOUT_TRANSITION_H_ -+ -+#include "ivi-layout.h" -+ -+struct ivi_layout_transition; -+ -+struct ivi_layout_transition_set { -+ struct wl_event_source *event_source; -+ struct wl_list transition_list; -+}; -+ -+typedef void (*ivi_layout_transition_destroy_user_func)(void* user_data); -+ -+struct ivi_layout_transition_set * -+ivi_layout_transition_set_create(struct weston_compositor* ec); -+ -+void -+ivi_layout_transition_move_resize_view(struct ivi_layout_surface* surface, -+ int32_t dest_x, int32_t dest_y, -+ uint32_t dest_width, uint32_t dest_height, -+ uint32_t duration); -+ -+void -+ivi_layout_transition_visibility_on(struct ivi_layout_surface* surface, -+ uint32_t duration); -+ -+void -+ivi_layout_transition_visibility_off(struct ivi_layout_surface* surface, -+ uint32_t duration); -+ -+ -+void -+ivi_layout_transition_move_layer(struct ivi_layout_layer* layer, -+ int32_t dest_x, int32_t dest_y, -+ uint32_t duration); -+ -+void -+ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer* layer); -+ -+void -+ivi_layout_transition_fade_layer(struct ivi_layout_layer* layer, -+ int32_t is_fade_in, -+ double start_alpha, double end_alpha, -+ void* user_data, -+ ivi_layout_transition_destroy_user_func destroy_func, -+ uint32_t duration); -+ -+void -+ivi_layout_transition_layer_render_order(struct ivi_layout_layer* layer, -+ struct ivi_layout_surface** new_order, -+ uint32_t surface_num, -+ uint32_t duration); -+ -+#endif -diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c -index 985798a..82ff868 100644 ---- a/ivi-shell/ivi-layout.c -+++ b/ivi-shell/ivi-layout.c -@@ -54,6 +54,8 @@ - #include "compositor.h" - #include "ivi-layout.h" - #include "ivi-layout-export.h" -+#include "ivi-layout-private.h" -+ - - enum ivi_layout_surface_orientation { - IVI_LAYOUT_SURFACE_ORIENTATION_0_DEGREES = 0, -@@ -92,66 +94,6 @@ struct listener_layoutNotification { - - struct ivi_layout; - --struct ivi_layout_surface { -- struct wl_list link; -- struct wl_signal property_changed; -- struct wl_list list_layer; -- int32_t update_count; -- uint32_t id_surface; -- -- struct ivi_layout *layout; -- struct weston_surface *surface; -- -- struct wl_listener surface_destroy_listener; -- struct weston_transform surface_rotation; -- struct weston_transform layer_rotation; -- struct weston_transform surface_pos; -- struct weston_transform layer_pos; -- struct weston_transform scaling; -- struct ivi_layout_SurfaceProperties prop; -- int32_t pixelformat; -- uint32_t event_mask; -- -- struct { -- struct ivi_layout_SurfaceProperties prop; -- struct wl_list link; -- } pending; -- -- struct { -- struct wl_list link; -- struct wl_list list_layer; -- } order; -- -- struct { -- ivi_controller_surface_content_callback callback; -- void* userdata; -- } content_observer; --}; -- --struct ivi_layout_layer { -- struct wl_list link; -- struct wl_signal property_changed; -- struct wl_list list_screen; -- struct wl_list link_to_surface; -- uint32_t id_layer; -- -- struct ivi_layout *layout; -- -- struct ivi_layout_LayerProperties prop; -- uint32_t event_mask; -- -- struct { -- struct ivi_layout_LayerProperties prop; -- struct wl_list list_surface; -- struct wl_list link; -- } pending; -- -- struct { -- struct wl_list list_surface; -- struct wl_list link; -- } order; --}; -- - struct ivi_layout_screen { - struct wl_list link; - struct wl_list link_to_layer; -@@ -173,28 +115,6 @@ struct ivi_layout_screen { - } order; - }; - --struct ivi_layout { -- struct weston_compositor *compositor; -- -- struct wl_list list_surface; -- struct wl_list list_layer; -- struct wl_list list_screen; -- -- struct { -- struct wl_signal created; -- struct wl_signal removed; -- } layer_notification; -- -- struct { -- struct wl_signal created; -- struct wl_signal removed; -- struct wl_signal configure_changed; -- } surface_notification; -- -- struct weston_layer layout_layer; -- struct wl_signal warning_signal; --}; -- - struct ivi_layout_notificationCallback { - void *callback; - void *data; -@@ -207,7 +127,7 @@ struct shellWarningArgs { - - static struct ivi_layout ivilayout = {0}; - --static struct ivi_layout * -+struct ivi_layout * - get_instance(void) - { - return &ivilayout; -@@ -715,7 +635,7 @@ update_surface_position(struct ivi_layout_surface *ivisurf) - weston_view_update_transform(view); - - #if 0 -- /* disable zoom animation */ -+ /* disable zoom transition */ - weston_zoom_run(es, 0.0, 1.0, NULL, NULL); - #endif - -@@ -859,7 +779,79 @@ commit_list_surface(struct ivi_layout *layout) - struct ivi_layout_surface *ivisurf = NULL; - - wl_list_for_each(ivisurf, &layout->list_surface, link) { -- ivisurf->prop = ivisurf->pending.prop; -+ if(ivisurf->pending.prop.transitionType == IVI_LAYOUT_TRANSITION_VIEW_DEFAULT){ -+ ivi_layout_transition_move_resize_view(ivisurf, -+ ivisurf->pending.prop.destX, -+ ivisurf->pending.prop.destY, -+ ivisurf->pending.prop.destWidth, -+ ivisurf->pending.prop.destHeight, -+ ivisurf->pending.prop.transitionDuration); -+ -+ if(ivisurf->pending.prop.visibility) -+ { -+ ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transitionDuration); -+ } -+ else -+ { -+ ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transitionDuration); -+ } -+ -+ int32_t destX = ivisurf->prop.destX; -+ int32_t destY = ivisurf->prop.destY; -+ int32_t destWidth = ivisurf->prop.destWidth; -+ int32_t destHeight = ivisurf->prop.destHeight; -+ -+ ivisurf->prop = ivisurf->pending.prop; -+ ivisurf->prop.destX = destX; -+ ivisurf->prop.destY = destY; -+ ivisurf->prop.destWidth = destWidth; -+ ivisurf->prop.destHeight = destHeight; -+ ivisurf->prop.transitionType = IVI_LAYOUT_TRANSITION_NONE; -+ ivisurf->pending.prop.transitionType = IVI_LAYOUT_TRANSITION_NONE; -+ -+ } -+ else if(ivisurf->pending.prop.transitionType == IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY){ -+ ivi_layout_transition_move_resize_view(ivisurf, -+ ivisurf->pending.prop.destX, -+ ivisurf->pending.prop.destY, -+ ivisurf->pending.prop.destWidth, -+ ivisurf->pending.prop.destHeight, -+ ivisurf->pending.prop.transitionDuration); -+ -+ int32_t destX = ivisurf->prop.destX; -+ int32_t destY = ivisurf->prop.destY; -+ int32_t destWidth = ivisurf->prop.destWidth; -+ int32_t destHeight = ivisurf->prop.destHeight; -+ -+ ivisurf->prop = ivisurf->pending.prop; -+ ivisurf->prop.destX = destX; -+ ivisurf->prop.destY = destY; -+ ivisurf->prop.destWidth = destWidth; -+ ivisurf->prop.destHeight = destHeight; -+ -+ ivisurf->prop.transitionType = IVI_LAYOUT_TRANSITION_NONE; -+ ivisurf->pending.prop.transitionType = IVI_LAYOUT_TRANSITION_NONE; -+ -+ } -+ else if(ivisurf->pending.prop.transitionType == IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY){ -+ if(ivisurf->pending.prop.visibility) -+ { -+ ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transitionDuration); -+ } -+ else -+ { -+ ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transitionDuration); -+ } -+ -+ ivisurf->prop = ivisurf->pending.prop; -+ ivisurf->prop.transitionType = IVI_LAYOUT_TRANSITION_NONE; -+ ivisurf->pending.prop.transitionType = IVI_LAYOUT_TRANSITION_NONE; -+ } -+ else{ -+ ivisurf->prop = ivisurf->pending.prop; -+ ivisurf->prop.transitionType = IVI_LAYOUT_TRANSITION_NONE; -+ ivisurf->pending.prop.transitionType = IVI_LAYOUT_TRANSITION_NONE; -+ } - } - } - -@@ -871,6 +863,19 @@ commit_list_layer(struct ivi_layout *layout) - struct ivi_layout_surface *next = NULL; - - wl_list_for_each(ivilayer, &layout->list_layer, link) { -+ if(ivilayer->pending.prop.transitionType == IVI_LAYOUT_TRANSITION_LAYER_MOVE) -+ { -+ ivi_layout_transition_move_layer(ivilayer, ivilayer->pending.prop.destX, ivilayer->pending.prop.destY, ivilayer->pending.prop.transitionDuration); -+ } -+ else if(ivilayer->pending.prop.transitionType == IVI_LAYOUT_TRANSITION_LAYER_FADE) -+ { -+ ivi_layout_transition_fade_layer(ivilayer,ivilayer->pending.prop.isFadeIn, -+ ivilayer->pending.prop.startAlpha,ivilayer->pending.prop.endAlpha, -+ NULL, NULL, -+ ivilayer->pending.prop.transitionDuration); -+ } -+ ivilayer->pending.prop.transitionType = IVI_LAYOUT_TRANSITION_NONE; -+ - ivilayer->prop = ivilayer->pending.prop; - - if (!(ivilayer->event_mask & -@@ -1004,6 +1009,21 @@ commit_list_screen(struct ivi_layout *layout) - } - - static void -+commit_transition(struct ivi_layout* layout) -+{ -+ if(wl_list_empty(&layout->pending_transition_list)){ -+ return; -+ } -+ -+ wl_list_insert_list(&layout->transitions->transition_list, -+ &layout->pending_transition_list); -+ -+ wl_list_init(&layout->pending_transition_list); -+ -+ wl_event_source_timer_update(layout->transitions->event_source, 1); -+} -+ -+static void - send_surface_prop(struct ivi_layout_surface *ivisurf) - { - wl_signal_emit(&ivisurf->property_changed, ivisurf); -@@ -2406,8 +2426,12 @@ ivi_layout_surfaceSetDestinationRectangle(struct ivi_layout_surface *ivisurf, - } - - prop = &ivisurf->pending.prop; -+ prop->startX = prop->destX; -+ prop->startY = prop->destY; - prop->destX = x; - prop->destY = y; -+ prop->startWidth = prop->destWidth; -+ prop->startHeight = prop->destHeight; - prop->destWidth = width; - prop->destHeight = height; - -@@ -2809,6 +2833,8 @@ ivi_layout_commitChanges(void) - commit_list_layer(layout); - commit_list_screen(layout); - -+ commit_transition(layout); -+ - commit_changes(layout); - send_prop(layout); - weston_compositor_schedule_repaint(layout->compositor); -@@ -3053,6 +3079,10 @@ ivi_layout_initWithCompositor(struct weston_compositor *ec) - else - wl_list_remove(&ec->cursor_layer.link); - weston_config_destroy(config); -+ -+ layout->transitions = ivi_layout_transition_set_create(ec); -+ wl_list_init(&layout->pending_transition_list); -+ - } - - -diff --git a/ivi-shell/ivi-layout.h b/ivi-shell/ivi-layout.h -index 5d7488a..8cca33c 100644 ---- a/ivi-shell/ivi-layout.h -+++ b/ivi-shell/ivi-layout.h -@@ -52,6 +52,70 @@ extern "C" { - #include "compositor.h" - - struct ivi_layout_surface; -+struct ivi_layout_layer; -+struct ivi_layout_screen; -+ -+struct ivi_layout_SurfaceProperties -+{ -+ float opacity; -+ uint32_t sourceX; -+ uint32_t sourceY; -+ uint32_t sourceWidth; -+ uint32_t sourceHeight; -+ uint32_t origSourceWidth; -+ uint32_t origSourceHeight; -+ int32_t startX; -+ int32_t startY; -+ uint32_t startWidth; -+ uint32_t startHeight; -+ int32_t destX; -+ int32_t destY; -+ uint32_t destWidth; -+ uint32_t destHeight; -+ uint32_t orientation; -+ uint32_t visibility; -+ uint32_t frameCounter; -+ uint32_t drawCounter; -+ uint32_t updateCounter; -+ uint32_t pixelformat; -+ uint32_t nativeSurface; -+ uint32_t inputDevicesAcceptance; -+ uint32_t chromaKeyEnabled; -+ uint32_t chromaKeyRed; -+ uint32_t chromaKeyGreen; -+ uint32_t chromaKeyBlue; -+ int32_t creatorPid; -+ int32_t transitionType; -+ uint32_t transitionDuration; -+}; -+ -+struct ivi_layout_LayerProperties -+{ -+ float opacity; -+ uint32_t sourceX; -+ uint32_t sourceY; -+ uint32_t sourceWidth; -+ uint32_t sourceHeight; -+ uint32_t origSourceWidth; -+ uint32_t origSourceHeight; -+ int32_t destX; -+ int32_t destY; -+ uint32_t destWidth; -+ uint32_t destHeight; -+ uint32_t orientation; -+ uint32_t visibility; -+ uint32_t type; -+ uint32_t chromaKeyEnabled; -+ uint32_t chromaKeyRed; -+ uint32_t chromaKeyGreen; -+ uint32_t chromaKeyBlue; -+ int32_t creatorPid; -+ int32_t transitionType; -+ uint32_t transitionDuration; -+ double startAlpha; -+ double endAlpha; -+ uint32_t isFadeIn; -+}; - - enum ivi_layout_warning_flag { - IVI_WARNING_INVALID_WL_SURFACE, -diff --git a/ivi-shell/weston.ini.in b/ivi-shell/weston.ini.in -index c192d68..050b806 100644 ---- a/ivi-shell/weston.ini.in -+++ b/ivi-shell/weston.ini.in -@@ -13,6 +13,8 @@ workspace-background-layer-id=2000 - workspace-layer-id=3000 - application-layer-id=4000 - -+transition-duration=300 -+ - background-image=@abs_top_builddir@/data/background.png - background-id=1001 - panel-image=@abs_top_builddir@/data/panel.png --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0016-Update-README-to-show-how-to-build-congirue-and-star.patch b/meta-ivi/recipes-graphics/wayland/weston/0016-Update-README-to-show-how-to-build-congirue-and-star.patch deleted file mode 100644 index 559547d..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0016-Update-README-to-show-how-to-build-congirue-and-star.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 428ef287660b50a71ca4f9849b126885b305a1a3 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Wed, 9 Jul 2014 18:31:56 +0900 -Subject: [PATCH 16/31] Update README to show how to build, congirue, and start - ivi-shell. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - README | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/README b/README -index cf7eca5..5ca1aed 100644 ---- a/README -+++ b/README -@@ -14,6 +14,18 @@ ivi-shell proposes two features - starts to move, the wl_surface drawn by Car navigation is expected to - move top of surfaces. - -+How to compile: -+same as weston. To disable, use option: --disable-ivi-shell for configure. -+ -+How to configure weston.ini: -+reference ini file will be generated in <build_dir>/ivi-shell. -+ -+How to run: -+same as weston. exec weston. -+ -+How to use UI: -+http://lists.freedesktop.org/archives/wayland-devel/attachments/20140625/abbfc064/attachment-0001.png -+ - ----------------------------- - Weston - --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0017-ivi-shell-Fix-incorrect-member-reference-in-wl_list_.patch b/meta-ivi/recipes-graphics/wayland/weston/0017-ivi-shell-Fix-incorrect-member-reference-in-wl_list_.patch deleted file mode 100644 index db25e18..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0017-ivi-shell-Fix-incorrect-member-reference-in-wl_list_.patch +++ /dev/null @@ -1,27 +0,0 @@ -From ffee67a374d6373122845caf0ef269f7f7bd5535 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Fri, 8 Aug 2014 09:59:01 +0900 -Subject: [PATCH 17/31] ivi-shell: Fix incorrect member reference in - wl_list_for_each. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - ivi-shell/ivi-layout.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c -index 82ff868..8ba60ca 100644 ---- a/ivi-shell/ivi-layout.c -+++ b/ivi-shell/ivi-layout.c -@@ -2287,7 +2287,7 @@ ivi_layout_layerSetRenderOrder(struct ivi_layout_layer *ivilayer, - for (i = 0; i < number; i++) { - id_surface = &pSurface[i]->id_surface; - -- wl_list_for_each_safe(ivisurf, next, &layout->list_surface, pending.link) { -+ wl_list_for_each_safe(ivisurf, next, &layout->list_surface, link) { - if (*id_surface != ivisurf->id_surface) { - continue; - } --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0018-ivi-shell-Set-source-surface-size-if-surfaceConfigur.patch b/meta-ivi/recipes-graphics/wayland/weston/0018-ivi-shell-Set-source-surface-size-if-surfaceConfigur.patch deleted file mode 100644 index 7049d34..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0018-ivi-shell-Set-source-surface-size-if-surfaceConfigur.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 472f0e7c5abcb5808964c44235eab9cf00d94649 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Mon, 28 Jul 2014 17:56:01 +0900 -Subject: [PATCH 18/31] ivi-shell: Set source surface size if surfaceConfigure - event occurred. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - ivi-shell/ivi-layout.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c -index 8ba60ca..5e9c1d7 100644 ---- a/ivi-shell/ivi-layout.c -+++ b/ivi-shell/ivi-layout.c -@@ -2866,6 +2866,13 @@ ivi_layout_surfaceConfigure(struct ivi_layout_surface *ivisurf, - ivisurf->surface->width_from_buffer = width; - ivisurf->surface->height_from_buffer = height; - -+ if (ivisurf->prop.sourceWidth == 0 || ivisurf->prop.sourceHeight == 0) { -+ ivisurf->pending.prop.sourceWidth = width; -+ ivisurf->pending.prop.sourceHeight = height; -+ ivisurf->prop.sourceWidth = width; -+ ivisurf->prop.sourceHeight = height; -+ } -+ - wl_signal_emit(&layout->surface_notification.configure_changed, ivisurf); - } - --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0019-ivi-shell-Add-IVI-layout-APIs-ivi_layout_surfaceGetW.patch b/meta-ivi/recipes-graphics/wayland/weston/0019-ivi-shell-Add-IVI-layout-APIs-ivi_layout_surfaceGetW.patch deleted file mode 100644 index 38c072b..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0019-ivi-shell-Add-IVI-layout-APIs-ivi_layout_surfaceGetW.patch +++ /dev/null @@ -1,124 +0,0 @@ -From a3c139755e56ecdd398b3829a4c6cad15e1ab7a0 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Mon, 28 Jul 2014 17:57:16 +0900 -Subject: [PATCH 19/31] ivi-shell: Add IVI layout APIs - - ivi_layout_surfaceGetWestonSurface - ivi_layout_surfaceGetSize These are used - by screenshot APIs. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - ivi-shell/ivi-layout-export.h | 6 ++++ - ivi-shell/ivi-layout.c | 80 +++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 86 insertions(+) - -diff --git a/ivi-shell/ivi-layout-export.h b/ivi-shell/ivi-layout-export.h -index ea1adea..f0654f1 100644 ---- a/ivi-shell/ivi-layout-export.h -+++ b/ivi-shell/ivi-layout-export.h -@@ -908,6 +908,12 @@ ivi_layout_surfaceSetSourceRectangle(struct ivi_layout_surface *ivisurf, - struct weston_output * - ivi_layout_screenGetOutput(struct ivi_layout_screen *); - -+struct weston_surface * -+ivi_layout_surfaceGetWestonSurface(struct ivi_layout_surface *ivisurf); -+ -+int32_t -+ivi_layout_surfaceGetSize(struct ivi_layout_surface *ivisurf, int32_t *width, int32_t *height, int32_t *stride); -+ - int32_t - ivi_layout_layerSetTransition(struct ivi_layout_layer *ivilayer, - enum ivi_layout_transition_type type, -diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c -index 5e9c1d7..0244072 100644 ---- a/ivi-shell/ivi-layout.c -+++ b/ivi-shell/ivi-layout.c -@@ -2663,6 +2663,86 @@ ivi_layout_screenGetOutput(struct ivi_layout_screen *iviscrn) - return iviscrn->output; - } - -+WL_EXPORT struct weston_surface * -+ivi_layout_surfaceGetWestonSurface(struct ivi_layout_surface *ivisurf) -+{ -+ return ivisurf != NULL ? ivisurf->surface : NULL; -+} -+ -+static int32_t -+surfaceGetBitPerPixel(struct ivi_layout_surface *ivisurf) -+{ -+ int32_t bpp = 0; -+ -+ if (ivisurf == NULL) { -+ return bpp; -+ } -+ -+ switch (ivisurf->pixelformat) { -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_R_8: -+ bpp = 8; -+ break; -+ -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_RGB_888: -+ bpp = 24; -+ break; -+ -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_8888: -+ bpp = 32; -+ break; -+ -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_RGB_565: -+ bpp = 16; -+ break; -+ -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_5551: -+ bpp = 16; -+ break; -+ -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_6661: -+ bpp = 0; // 19 -+ break; -+ -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_4444: -+ bpp = 16; -+ break; -+ -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_UNKNOWN: -+ default: -+ bpp = 0; -+ break; -+ } -+ -+ return bpp; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceGetSize(struct ivi_layout_surface *ivisurf, int32_t *width, int32_t *height, int32_t *stride) -+{ -+ if (ivisurf == NULL) { -+ return -1; -+ } -+ -+ if (width != NULL) { -+ *width = ivisurf->prop.sourceWidth; -+ } -+ -+ if (height != NULL) { -+ *height = ivisurf->prop.sourceHeight; -+ } -+ -+ if (stride != NULL) { -+ int32_t bpp = surfaceGetBitPerPixel(ivisurf); -+ if ((bpp == 0) ||(bpp % 8 != 0)) { -+ return -1; -+ } -+ -+ *stride = ivisurf->prop.sourceWidth * (bpp / 8); -+ } -+ -+ return 0; -+} -+ - WL_EXPORT int32_t - ivi_layout_SetOptimizationMode(uint32_t id, int32_t mode) - { --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0019-ivi-shell-Add-IVI-layout-APIs.patch b/meta-ivi/recipes-graphics/wayland/weston/0019-ivi-shell-Add-IVI-layout-APIs.patch deleted file mode 100644 index be08b40..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0019-ivi-shell-Add-IVI-layout-APIs.patch +++ /dev/null @@ -1,124 +0,0 @@ -From e881b106681c6e45257579024e524ee3f6d8a928 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Mon, 28 Jul 2014 17:57:16 +0900 -Subject: [PATCH 19/31] ivi-shell: Add IVI layout APIs - - ivi_layout_surfaceGetWestonSurface - ivi_layout_surfaceGetSize These are used - by screenshot APIs. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - ivi-shell/ivi-layout-export.h | 6 ++++ - ivi-shell/ivi-layout.c | 80 +++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 86 insertions(+) - -diff --git a/ivi-shell/ivi-layout-export.h b/ivi-shell/ivi-layout-export.h -index ea1adea..f0654f1 100644 ---- a/ivi-shell/ivi-layout-export.h -+++ b/ivi-shell/ivi-layout-export.h -@@ -908,6 +908,12 @@ ivi_layout_surfaceSetSourceRectangle(struct ivi_layout_surface *ivisurf, - struct weston_output * - ivi_layout_screenGetOutput(struct ivi_layout_screen *); - -+struct weston_surface * -+ivi_layout_surfaceGetWestonSurface(struct ivi_layout_surface *ivisurf); -+ -+int32_t -+ivi_layout_surfaceGetSize(struct ivi_layout_surface *ivisurf, int32_t *width, int32_t *height, int32_t *stride); -+ - int32_t - ivi_layout_layerSetTransition(struct ivi_layout_layer *ivilayer, - enum ivi_layout_transition_type type, -diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c -index 5e9c1d7..0244072 100644 ---- a/ivi-shell/ivi-layout.c -+++ b/ivi-shell/ivi-layout.c -@@ -2663,6 +2663,86 @@ ivi_layout_screenGetOutput(struct ivi_layout_screen *iviscrn) - return iviscrn->output; - } - -+WL_EXPORT struct weston_surface * -+ivi_layout_surfaceGetWestonSurface(struct ivi_layout_surface *ivisurf) -+{ -+ return ivisurf != NULL ? ivisurf->surface : NULL; -+} -+ -+static int32_t -+surfaceGetBitPerPixel(struct ivi_layout_surface *ivisurf) -+{ -+ int32_t bpp = 0; -+ -+ if (ivisurf == NULL) { -+ return bpp; -+ } -+ -+ switch (ivisurf->pixelformat) { -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_R_8: -+ bpp = 8; -+ break; -+ -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_RGB_888: -+ bpp = 24; -+ break; -+ -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_8888: -+ bpp = 32; -+ break; -+ -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_RGB_565: -+ bpp = 16; -+ break; -+ -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_5551: -+ bpp = 16; -+ break; -+ -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_6661: -+ bpp = 0; // 19 -+ break; -+ -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_RGBA_4444: -+ bpp = 16; -+ break; -+ -+ case IVI_LAYOUT_SURFACE_PIXELFORMAT_UNKNOWN: -+ default: -+ bpp = 0; -+ break; -+ } -+ -+ return bpp; -+} -+ -+WL_EXPORT int32_t -+ivi_layout_surfaceGetSize(struct ivi_layout_surface *ivisurf, int32_t *width, int32_t *height, int32_t *stride) -+{ -+ if (ivisurf == NULL) { -+ return -1; -+ } -+ -+ if (width != NULL) { -+ *width = ivisurf->prop.sourceWidth; -+ } -+ -+ if (height != NULL) { -+ *height = ivisurf->prop.sourceHeight; -+ } -+ -+ if (stride != NULL) { -+ int32_t bpp = surfaceGetBitPerPixel(ivisurf); -+ if ((bpp == 0) ||(bpp % 8 != 0)) { -+ return -1; -+ } -+ -+ *stride = ivisurf->prop.sourceWidth * (bpp / 8); -+ } -+ -+ return 0; -+} -+ - WL_EXPORT int32_t - ivi_layout_SetOptimizationMode(uint32_t id, int32_t mode) - { --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0020-ivi-layout-fix-transform-matrix-could-not-be-inverti.patch b/meta-ivi/recipes-graphics/wayland/weston/0020-ivi-layout-fix-transform-matrix-could-not-be-inverti.patch deleted file mode 100644 index 800b239..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0020-ivi-layout-fix-transform-matrix-could-not-be-inverti.patch +++ /dev/null @@ -1,46 +0,0 @@ -From a3242c0d0d251d13faebd5e72eb109b4fab6d9ca Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Thu, 21 Aug 2014 15:20:45 +0900 -Subject: [PATCH 20/31] ivi-layout: fix transform matrix could not be - invertible in update_scale - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - ivi-shell/ivi-layout.c | 19 +++++++------------ - 1 file changed, 7 insertions(+), 12 deletions(-) - -diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c -index 0244072..39b7a96 100644 ---- a/ivi-shell/ivi-layout.c -+++ b/ivi-shell/ivi-layout.c -@@ -697,20 +697,15 @@ update_scale(struct ivi_layout_layer *ivilayer, - return; - } - -- if (ivisurf->prop.sourceWidth == 0 && ivisurf->prop.sourceHeight == 0) { -- ivisurf->prop.sourceWidth = ivisurf->surface->width_from_buffer; -- ivisurf->prop.sourceHeight = ivisurf->surface->height_from_buffer; -- -- if (ivisurf->prop.destWidth == 0 && ivisurf->prop.destHeight == 0) { -- ivisurf->prop.destWidth = ivisurf->surface->width_from_buffer; -- ivisurf->prop.destHeight = ivisurf->surface->height_from_buffer; -- } -+ if (ivisurf->prop.destWidth == 0 && ivisurf->prop.destHeight == 0) { -+ ivisurf->prop.destWidth = ivisurf->surface->width_from_buffer; -+ ivisurf->prop.destHeight = ivisurf->surface->height_from_buffer; - } - -- lw = ((float)ivilayer->prop.destWidth / ivilayer->prop.sourceWidth ); -- sw = ((float)ivisurf->prop.destWidth / ivisurf->prop.sourceWidth ); -- lh = ((float)ivilayer->prop.destHeight / ivilayer->prop.sourceHeight); -- sh = ((float)ivisurf->prop.destHeight / ivisurf->prop.sourceHeight ); -+ lw = ((float)ivilayer->prop.destWidth / (float)ivilayer->prop.sourceWidth ); -+ sw = ((float)ivisurf->prop.destWidth / (float)ivisurf->prop.sourceWidth ); -+ lh = ((float)ivilayer->prop.destHeight / (float)ivilayer->prop.sourceHeight); -+ sh = ((float)ivisurf->prop.destHeight / (float)ivisurf->prop.sourceHeight ); - sx = sw * lw; - sy = sh * lh; - --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0021-To-get-resolution-of-a-screen-refer-width-and-height.patch b/meta-ivi/recipes-graphics/wayland/weston/0021-To-get-resolution-of-a-screen-refer-width-and-height.patch deleted file mode 100644 index 35ff4eb..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0021-To-get-resolution-of-a-screen-refer-width-and-height.patch +++ /dev/null @@ -1,33 +0,0 @@ -From a2aadad0910ff4803d917dc29508037019e21222 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Tue, 15 Jul 2014 19:00:59 +0900 -Subject: [PATCH 21/31] To get resolution of a screen, refer width and height - of screen's of weston_output. - -Priviously, this code refers width and height of current_mode. However it is not always available. E.g. on Tizen. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - ivi-shell/ivi-layout.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c -index 39b7a96..5ed5513 100644 ---- a/ivi-shell/ivi-layout.c -+++ b/ivi-shell/ivi-layout.c -@@ -1576,8 +1576,10 @@ ivi_layout_getScreenResolution(struct ivi_layout_screen *iviscrn, - } - - output = iviscrn->output; -- *pWidth = output->current_mode->width; -- *pHeight = output->current_mode->height; -+ weston_log("ivi-shell uses %s as a screen.\n", output->name); -+ *pWidth = output->width; -+ *pHeight = output->height; -+ weston_log("ivi-shell: screen resolution is (%i,%i).\n", *pWidth,*pHeight); - - return 0; - } --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0022-input.c-give-control-of-default_grab_keyboard_key-to.patch b/meta-ivi/recipes-graphics/wayland/weston/0022-input.c-give-control-of-default_grab_keyboard_key-to.patch deleted file mode 100644 index a326241..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0022-input.c-give-control-of-default_grab_keyboard_key-to.patch +++ /dev/null @@ -1,65 +0,0 @@ -From b726a845433596e9b169312f280df1aa15e52fc6 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Tue, 26 Aug 2014 08:48:06 -0700 -Subject: [PATCH 22/31] input.c: give control of default_grab_keyboard_key to a - shell. - -In automotive usecase, a surface which is not focused also wants to -receive keyboard event. E.g. Media Player in background wants to receive -volume up/down. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - src/input.c | 29 ++++++++++++++++++++--------- - 1 file changed, 20 insertions(+), 9 deletions(-) - -diff --git a/src/input.c b/src/input.c -index 2c799f4..8e0dac3 100644 ---- a/src/input.c -+++ b/src/input.c -@@ -34,6 +34,13 @@ - #include "../shared/os-compatibility.h" - #include "compositor.h" - -+// for input focus step1 -+typedef void -+(*keyboard_key)(struct weston_keyboard_grab *grab, -+ uint32_t time, uint32_t key, uint32_t state); -+ -+WL_EXPORT keyboard_key keyboard_key_func=NULL; -+ - static void - empty_region(pixman_region32_t *region) - { -@@ -318,15 +325,19 @@ default_grab_keyboard_key(struct weston_keyboard_grab *grab, - uint32_t serial; - struct wl_list *resource_list; - -- resource_list = &keyboard->focus_resource_list; -- if (!wl_list_empty(resource_list)) { -- serial = wl_display_next_serial(display); -- wl_resource_for_each(resource, resource_list) -- wl_keyboard_send_key(resource, -- serial, -- time, -- key, -- state); -+ if (keyboard_key_func) { -+ keyboard_key_func(grab, time, key, state); -+ } else { -+ resource_list = &keyboard->focus_resource_list; -+ if (!wl_list_empty(resource_list)) { -+ serial = wl_display_next_serial(display); -+ wl_resource_for_each(resource, resource_list) -+ wl_keyboard_send_key(resource, -+ serial, -+ time, -+ key, -+ state); -+ } - } - } - --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0023-ivi-layout-send-key-event-to-clients-that-are-bindin.patch b/meta-ivi/recipes-graphics/wayland/weston/0023-ivi-layout-send-key-event-to-clients-that-are-bindin.patch deleted file mode 100644 index 7f7d9c9..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0023-ivi-layout-send-key-event-to-clients-that-are-bindin.patch +++ /dev/null @@ -1,114 +0,0 @@ -From d625ef81bf48050819d487df0859ae4c51e8a5b4 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Tue, 16 Sep 2014 16:48:23 +0900 -Subject: [PATCH 23/31] ivi-layout: send key event to clients that are binding - wl_keyboard. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - ivi-shell/ivi-layout.c | 42 +++++++++++++++++++++++++++++++++++++++++- - ivi-shell/ivi-layout.h | 2 ++ - ivi-shell/ivi-shell.c | 9 +++++++++ - 3 files changed, 52 insertions(+), 1 deletion(-) - -diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c -index 5ed5513..562e0bc 100644 ---- a/ivi-shell/ivi-layout.c -+++ b/ivi-shell/ivi-layout.c -@@ -3169,6 +3169,45 @@ ivi_layout_initWithCompositor(struct weston_compositor *ec) - - } - -+static struct wl_resource * -+find_resource_for_surface(struct wl_list *list, struct weston_surface *surface) -+{ -+ if (!surface) -+ return NULL; -+ -+ if (!surface->resource) -+ return NULL; -+ -+ return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource)); -+} -+ -+static void -+ivi_layout_grabKeyboardKey(struct weston_keyboard_grab *grab, -+ uint32_t time, uint32_t key, uint32_t state) -+{ -+ struct weston_keyboard *keyboard = grab->keyboard; -+ struct wl_display *display = keyboard->seat->compositor->wl_display; -+ uint32_t serial; -+ struct wl_resource *resource; -+ -+ wl_resource_for_each(resource, &keyboard->focus_resource_list) { -+ serial = wl_display_next_serial(display); -+ wl_keyboard_send_key(resource, -+ serial, -+ time, -+ key, -+ state); -+ } -+ -+ wl_resource_for_each(resource, &keyboard->resource_list) { -+ serial = wl_display_next_serial(display); -+ wl_keyboard_send_key(resource, -+ serial, -+ time, -+ key, -+ state); -+ } -+} - - WL_EXPORT struct ivi_layout_interface ivi_layout_interface = { - .get_weston_view = ivi_layout_get_weston_view, -@@ -3176,5 +3215,6 @@ WL_EXPORT struct ivi_layout_interface ivi_layout_interface = { - .surfaceSetNativeContent = ivi_layout_surfaceSetNativeContent, - .surfaceCreate = ivi_layout_surfaceCreate, - .initWithCompositor = ivi_layout_initWithCompositor, -- .emitWarningSignal = ivi_layout_emitWarningSignal -+ .emitWarningSignal = ivi_layout_emitWarningSignal, -+ .grab_keyboard_key = ivi_layout_grabKeyboardKey - }; -diff --git a/ivi-shell/ivi-layout.h b/ivi-shell/ivi-layout.h -index 8cca33c..073a1e1 100644 ---- a/ivi-shell/ivi-layout.h -+++ b/ivi-shell/ivi-layout.h -@@ -135,6 +135,8 @@ struct ivi_layout_interface { - void (*initWithCompositor)(struct weston_compositor *ec); - void (*emitWarningSignal)(uint32_t id_surface, - enum ivi_layout_warning_flag flag); -+ void (*grab_keyboard_key)(struct weston_keyboard_grab *grab, -+ uint32_t time, uint32_t key, uint32_t state); - }; - - WL_EXPORT struct ivi_layout_interface ivi_layout_interface; -diff --git a/ivi-shell/ivi-shell.c b/ivi-shell/ivi-shell.c -index d7d7bb5..bf4affd 100644 ---- a/ivi-shell/ivi-shell.c -+++ b/ivi-shell/ivi-shell.c -@@ -48,6 +48,13 @@ - - #include "../shared/os-compatibility.h" - -+// for input focus step1 -+typedef void -+(*keyboard_key)(struct weston_keyboard_grab *grab, -+ uint32_t time, uint32_t key, uint32_t state); -+ -+extern keyboard_key keyboard_key_func; -+ - struct ivi_shell_surface - { - struct ivi_shell *shell; -@@ -442,6 +449,8 @@ module_init(struct weston_compositor *compositor, - return -1; - } - -+ keyboard_key_func = ivi_layout->grab_keyboard_key; -+ - free(setting.ivi_module); - return 0; - } --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0024-DEBUG-add-weston-simple-keyboard-binding.patch b/meta-ivi/recipes-graphics/wayland/weston/0024-DEBUG-add-weston-simple-keyboard-binding.patch deleted file mode 100644 index 30ab5e0..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0024-DEBUG-add-weston-simple-keyboard-binding.patch +++ /dev/null @@ -1,945 +0,0 @@ -From 702e955acdf63134f43cd4a606499cf166d09b44 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Tue, 16 Sep 2014 19:12:45 +0900 -Subject: [PATCH 24/31] DEBUG: add weston-simple-keyboard-binding - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - Makefile.am | 10 + - clients/simple-keyboard-binding.c | 903 ++++++++++++++++++++++++++++++++++++++ - 2 files changed, 913 insertions(+) - create mode 100644 clients/simple-keyboard-binding.c - -diff --git a/Makefile.am b/Makefile.am -index 3ebc89a..41915cb 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -433,6 +433,16 @@ weston_simple_egl_CFLAGS = $(AM_CFLAGS) $(SIMPLE_EGL_CLIENT_CFLAGS) - weston_simple_egl_LDADD = $(SIMPLE_EGL_CLIENT_LIBS) -lm - endif - -+demo_clients += weston-simple-keyboard-binding -+weston_simple_keyboard_binding_SOURCES = clients/simple-keyboard-binding.c -+nodist_weston_simple_keyboard_binding_SOURCES = \ -+ protocol/xdg-shell-protocol.c \ -+ protocol/xdg-shell-client-protocol.h \ -+ protocol/ivi-application-protocol.c \ -+ protocol/ivi-application-client-protocol.h -+weston_simple_keyboard_binding_CFLAGS = $(AM_CFLAGS) $(SIMPLE_EGL_CLIENT_CFLAGS) -+weston_simple_keyboard_binding_LDADD = $(SIMPLE_EGL_CLIENT_LIBS) -lm -+ - noinst_LTLIBRARIES += libtoytoolkit.la - - libtoytoolkit_la_SOURCES = \ -diff --git a/clients/simple-keyboard-binding.c b/clients/simple-keyboard-binding.c -new file mode 100644 -index 0000000..74a76df ---- /dev/null -+++ b/clients/simple-keyboard-binding.c -@@ -0,0 +1,903 @@ -+/* -+ * Copyright © 2011 Benjamin Franzke -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and its -+ * documentation for any purpose is hereby granted without fee, provided that -+ * the above copyright notice appear in all copies and that both that copyright -+ * notice and this permission notice appear in supporting documentation, and -+ * that the name of the copyright holders not be used in advertising or -+ * publicity pertaining to distribution of the software without specific, -+ * written prior permission. The copyright holders make no representations -+ * about the suitability of this software for any purpose. It is provided "as -+ * is" without express or implied warranty. -+ * -+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR -+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -+ * OF THIS SOFTWARE. -+ */ -+ -+#include "config.h" -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <string.h> -+#include <stdbool.h> -+#include <math.h> -+#include <assert.h> -+#include <signal.h> -+ -+#include <linux/input.h> -+ -+#include <wayland-client.h> -+#include <wayland-egl.h> -+#include <wayland-cursor.h> -+ -+#include <GLES2/gl2.h> -+#include <EGL/egl.h> -+#include <EGL/eglext.h> -+ -+#include "xdg-shell-client-protocol.h" -+#include <sys/types.h> -+#include <unistd.h> -+#include "protocol/ivi-application-client-protocol.h" -+#define IVI_SURFACE_ID 9000 -+ -+#ifndef EGL_EXT_swap_buffers_with_damage -+#define EGL_EXT_swap_buffers_with_damage 1 -+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC)(EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); -+#endif -+ -+#ifndef EGL_EXT_buffer_age -+#define EGL_EXT_buffer_age 1 -+#define EGL_BUFFER_AGE_EXT 0x313D -+#endif -+ -+struct window; -+struct seat; -+ -+struct display { -+ struct wl_display *display; -+ struct wl_registry *registry; -+ struct wl_compositor *compositor; -+ struct xdg_shell *shell; -+ struct wl_seat *seat; -+ struct wl_pointer *pointer; -+ struct wl_touch *touch; -+ struct wl_keyboard *keyboard; -+ struct wl_shm *shm; -+ struct wl_cursor_theme *cursor_theme; -+ struct wl_cursor *default_cursor; -+ struct wl_surface *cursor_surface; -+ struct { -+ EGLDisplay dpy; -+ EGLContext ctx; -+ EGLConfig conf; -+ } egl; -+ struct window *window; -+ struct ivi_application *ivi_application; -+ -+ PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage; -+}; -+ -+struct geometry { -+ int width, height; -+}; -+ -+struct window { -+ struct display *display; -+ struct geometry geometry, window_size; -+ struct { -+ GLuint rotation_uniform; -+ GLuint pos; -+ GLuint col; -+ } gl; -+ -+ uint32_t benchmark_time, frames; -+ struct wl_egl_window *native; -+ struct wl_surface *surface; -+ struct xdg_surface *xdg_surface; -+ struct ivi_surface *ivi_surface; -+ EGLSurface egl_surface; -+ struct wl_callback *callback; -+ int fullscreen, opaque, buffer_size, frame_sync; -+}; -+ -+static const char *vert_shader_text = -+ "uniform mat4 rotation;\n" -+ "attribute vec4 pos;\n" -+ "attribute vec4 color;\n" -+ "varying vec4 v_color;\n" -+ "void main() {\n" -+ " gl_Position = rotation * pos;\n" -+ " v_color = color;\n" -+ "}\n"; -+ -+static const char *frag_shader_text = -+ "precision mediump float;\n" -+ "varying vec4 v_color;\n" -+ "void main() {\n" -+ " gl_FragColor = v_color;\n" -+ "}\n"; -+ -+static int running = 1; -+ -+static void -+init_egl(struct display *display, struct window *window) -+{ -+ static const EGLint context_attribs[] = { -+ EGL_CONTEXT_CLIENT_VERSION, 2, -+ EGL_NONE -+ }; -+ const char *extensions; -+ -+ EGLint config_attribs[] = { -+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT, -+ EGL_RED_SIZE, 1, -+ EGL_GREEN_SIZE, 1, -+ EGL_BLUE_SIZE, 1, -+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, -+ EGL_NONE -+ }; -+ -+ EGLint major, minor, n, count, i, size; -+ EGLConfig *configs; -+ EGLBoolean ret; -+ -+ if (window->opaque || window->buffer_size == 16) -+ config_attribs[9] = 0; -+ -+ display->egl.dpy = eglGetDisplay(display->display); -+ assert(display->egl.dpy); -+ -+ ret = eglInitialize(display->egl.dpy, &major, &minor); -+ assert(ret == EGL_TRUE); -+ ret = eglBindAPI(EGL_OPENGL_ES_API); -+ assert(ret == EGL_TRUE); -+ -+ if (!eglGetConfigs(display->egl.dpy, NULL, 0, &count) || count < 1) -+ assert(0); -+ -+ configs = calloc(count, sizeof *configs); -+ assert(configs); -+ -+ ret = eglChooseConfig(display->egl.dpy, config_attribs, -+ configs, count, &n); -+ assert(ret && n >= 1); -+ -+ for (i = 0; i < n; i++) { -+ eglGetConfigAttrib(display->egl.dpy, -+ configs[i], EGL_BUFFER_SIZE, &size); -+ if (window->buffer_size == size) { -+ display->egl.conf = configs[i]; -+ break; -+ } -+ } -+ free(configs); -+ if (display->egl.conf == NULL) { -+ fprintf(stderr, "did not find config with buffer size %d\n", -+ window->buffer_size); -+ exit(EXIT_FAILURE); -+ } -+ -+ display->egl.ctx = eglCreateContext(display->egl.dpy, -+ display->egl.conf, -+ EGL_NO_CONTEXT, context_attribs); -+ assert(display->egl.ctx); -+ -+ display->swap_buffers_with_damage = NULL; -+ extensions = eglQueryString(display->egl.dpy, EGL_EXTENSIONS); -+ if (extensions && -+ strstr(extensions, "EGL_EXT_swap_buffers_with_damage") && -+ strstr(extensions, "EGL_EXT_buffer_age")) -+ display->swap_buffers_with_damage = -+ (PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) -+ eglGetProcAddress("eglSwapBuffersWithDamageEXT"); -+ -+ if (display->swap_buffers_with_damage) -+ printf("has EGL_EXT_buffer_age and EGL_EXT_swap_buffers_with_damage\n"); -+ -+} -+ -+static void -+fini_egl(struct display *display) -+{ -+ eglTerminate(display->egl.dpy); -+ eglReleaseThread(); -+} -+ -+static GLuint -+create_shader(struct window *window, const char *source, GLenum shader_type) -+{ -+ GLuint shader; -+ GLint status; -+ -+ shader = glCreateShader(shader_type); -+ assert(shader != 0); -+ -+ glShaderSource(shader, 1, (const char **) &source, NULL); -+ glCompileShader(shader); -+ -+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status); -+ if (!status) { -+ char log[1000]; -+ GLsizei len; -+ glGetShaderInfoLog(shader, 1000, &len, log); -+ fprintf(stderr, "Error: compiling %s: %*s\n", -+ shader_type == GL_VERTEX_SHADER ? "vertex" : "fragment", -+ len, log); -+ exit(1); -+ } -+ -+ return shader; -+} -+ -+static void -+init_gl(struct window *window) -+{ -+ GLuint frag, vert; -+ GLuint program; -+ GLint status; -+ -+ frag = create_shader(window, frag_shader_text, GL_FRAGMENT_SHADER); -+ vert = create_shader(window, vert_shader_text, GL_VERTEX_SHADER); -+ -+ program = glCreateProgram(); -+ glAttachShader(program, frag); -+ glAttachShader(program, vert); -+ glLinkProgram(program); -+ -+ glGetProgramiv(program, GL_LINK_STATUS, &status); -+ if (!status) { -+ char log[1000]; -+ GLsizei len; -+ glGetProgramInfoLog(program, 1000, &len, log); -+ fprintf(stderr, "Error: linking:\n%*s\n", len, log); -+ exit(1); -+ } -+ -+ glUseProgram(program); -+ -+ window->gl.pos = 0; -+ window->gl.col = 1; -+ -+ glBindAttribLocation(program, window->gl.pos, "pos"); -+ glBindAttribLocation(program, window->gl.col, "color"); -+ glLinkProgram(program); -+ -+ window->gl.rotation_uniform = -+ glGetUniformLocation(program, "rotation"); -+} -+ -+static void -+handle_surface_configure(void *data, struct xdg_surface *surface, -+ int32_t width, int32_t height) -+{ -+ struct window *window = data; -+ -+ if (window->native) -+ wl_egl_window_resize(window->native, width, height, 0, 0); -+ -+ window->geometry.width = width; -+ window->geometry.height = height; -+ -+ if (!window->fullscreen) -+ window->window_size = window->geometry; -+} -+ -+static void -+handle_surface_change_state(void *data, struct xdg_surface *xdg_surface, -+ uint32_t state, -+ uint32_t value, -+ uint32_t serial) -+{ -+ struct window *window = data; -+ -+ switch (state) { -+ case XDG_SURFACE_STATE_FULLSCREEN: -+ window->fullscreen = value; -+ -+ if (!value) -+ handle_surface_configure(window, window->xdg_surface, -+ window->window_size.width, -+ window->window_size.height); -+ break; -+ } -+ -+ xdg_surface_ack_change_state(xdg_surface, state, value, serial); -+} -+ -+static void -+handle_surface_activated(void *data, struct xdg_surface *xdg_surface) -+{ -+} -+ -+static void -+handle_surface_deactivated(void *data, struct xdg_surface *xdg_surface) -+{ -+} -+ -+static void -+handle_surface_delete(void *data, struct xdg_surface *xdg_surface) -+{ -+ running = 0; -+} -+ -+static const struct xdg_surface_listener xdg_surface_listener = { -+ handle_surface_configure, -+ handle_surface_change_state, -+ handle_surface_activated, -+ handle_surface_deactivated, -+ handle_surface_delete, -+}; -+ -+static void -+create_surface(struct window *window) -+{ -+ struct display *display = window->display; -+ EGLBoolean ret; -+ -+ window->surface = wl_compositor_create_surface(display->compositor); -+ -+ window->native = -+ wl_egl_window_create(window->surface, -+ window->window_size.width, -+ window->window_size.height); -+ window->egl_surface = -+ eglCreateWindowSurface(display->egl.dpy, -+ display->egl.conf, -+ window->native, NULL); -+ -+ if (display->shell) { -+ window->xdg_surface = xdg_shell_get_xdg_surface(display->shell, -+ window->surface); -+ -+ xdg_surface_add_listener(window->xdg_surface, -+ &xdg_surface_listener, window); -+ -+ xdg_surface_set_title(window->xdg_surface, "simple-egl"); -+ } else if (display->ivi_application ) { -+ uint32_t id_ivisurf = IVI_SURFACE_ID + (uint32_t)getpid(); -+ window->ivi_surface = -+ ivi_application_surface_create(display->ivi_application, -+ id_ivisurf, window->surface); -+ handle_surface_configure(window, NULL, 250, 250); -+ -+ if (window->ivi_surface == NULL) { -+ fprintf(stderr, "Failed to create ivi_client_surface\n"); -+ abort(); -+ } -+ } else { -+ assert(0); -+ } -+ -+ ret = eglMakeCurrent(window->display->egl.dpy, window->egl_surface, -+ window->egl_surface, window->display->egl.ctx); -+ assert(ret == EGL_TRUE); -+ -+ -+ if (!window->frame_sync) -+ eglSwapInterval(display->egl.dpy, 0); -+ -+ if (display->shell) -+ { -+ xdg_surface_request_change_state(window->xdg_surface, -+ XDG_SURFACE_STATE_FULLSCREEN, -+ window->fullscreen, 0); -+ } -+} -+ -+static void -+destroy_surface(struct window *window) -+{ -+ /* Required, otherwise segfault in egl_dri2.c: dri2_make_current() -+ * on eglReleaseThread(). */ -+ eglMakeCurrent(window->display->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, -+ EGL_NO_CONTEXT); -+ -+ eglDestroySurface(window->display->egl.dpy, window->egl_surface); -+ wl_egl_window_destroy(window->native); -+ -+ xdg_surface_destroy(window->xdg_surface); -+ wl_surface_destroy(window->surface); -+ -+ if (window->callback) -+ wl_callback_destroy(window->callback); -+} -+ -+static const struct wl_callback_listener frame_listener; -+ -+static void -+redraw(void *data, struct wl_callback *callback, uint32_t time) -+{ -+ struct window *window = data; -+ struct display *display = window->display; -+ -+ static const GLfloat verts[3][2] = { -+ { -0.5, -0.5 }, -+ { 0.5, -0.5 }, -+ { 0, 0.5 } -+ }; -+ static const GLfloat colors[3][3] = { -+ { 1, 0, 0 }, -+ { 0, 1, 0 }, -+ { 0, 0, 1 } -+ }; -+ GLfloat angle; -+ GLfloat rotation[4][4] = { -+ { 1, 0, 0, 0 }, -+ { 0, 1, 0, 0 }, -+ { 0, 0, 1, 0 }, -+ { 0, 0, 0, 1 } -+ }; -+ static const uint32_t speed_div = 5, benchmark_interval = 5; -+ struct wl_region *region; -+ EGLint rect[4]; -+ EGLint buffer_age = 0; -+ struct timeval tv; -+ -+ assert(window->callback == callback); -+ window->callback = NULL; -+ -+ if (callback) -+ wl_callback_destroy(callback); -+ -+ gettimeofday(&tv, NULL); -+ time = tv.tv_sec * 1000 + tv.tv_usec / 1000; -+ if (window->frames == 0) -+ window->benchmark_time = time; -+ if (time - window->benchmark_time > (benchmark_interval * 1000)) { -+ printf("%d frames in %d seconds: %f fps\n", -+ window->frames, -+ benchmark_interval, -+ (float) window->frames / benchmark_interval); -+ window->benchmark_time = time; -+ window->frames = 0; -+ } -+ -+ angle = (time / speed_div) % 360 * M_PI / 180.0; -+ rotation[0][0] = cos(angle); -+ rotation[0][2] = sin(angle); -+ rotation[2][0] = -sin(angle); -+ rotation[2][2] = cos(angle); -+ -+ if (display->swap_buffers_with_damage) -+ eglQuerySurface(display->egl.dpy, window->egl_surface, -+ EGL_BUFFER_AGE_EXT, &buffer_age); -+ -+ glViewport(0, 0, window->geometry.width, window->geometry.height); -+ -+ glUniformMatrix4fv(window->gl.rotation_uniform, 1, GL_FALSE, -+ (GLfloat *) rotation); -+ -+ glClearColor(0.0, 0.0, 0.0, 0.5); -+ glClear(GL_COLOR_BUFFER_BIT); -+ -+ glVertexAttribPointer(window->gl.pos, 2, GL_FLOAT, GL_FALSE, 0, verts); -+ glVertexAttribPointer(window->gl.col, 3, GL_FLOAT, GL_FALSE, 0, colors); -+ glEnableVertexAttribArray(window->gl.pos); -+ glEnableVertexAttribArray(window->gl.col); -+ -+ glDrawArrays(GL_TRIANGLES, 0, 3); -+ -+ glDisableVertexAttribArray(window->gl.pos); -+ glDisableVertexAttribArray(window->gl.col); -+ -+ if (window->opaque || window->fullscreen) { -+ region = wl_compositor_create_region(window->display->compositor); -+ wl_region_add(region, 0, 0, -+ window->geometry.width, -+ window->geometry.height); -+ wl_surface_set_opaque_region(window->surface, region); -+ wl_region_destroy(region); -+ } else { -+// wl_surface_set_opaque_region(window->surface, NULL); -+ } -+ -+ if (display->swap_buffers_with_damage && buffer_age > 0) { -+ rect[0] = window->geometry.width / 4 - 1; -+ rect[1] = window->geometry.height / 4 - 1; -+ rect[2] = window->geometry.width / 2 + 2; -+ rect[3] = window->geometry.height / 2 + 2; -+ display->swap_buffers_with_damage(display->egl.dpy, -+ window->egl_surface, -+ rect, 1); -+ } else { -+ eglSwapBuffers(display->egl.dpy, window->egl_surface); -+ } -+ window->frames++; -+} -+ -+static const struct wl_callback_listener frame_listener = { -+ redraw -+}; -+ -+static void -+pointer_handle_enter(void *data, struct wl_pointer *pointer, -+ uint32_t serial, struct wl_surface *surface, -+ wl_fixed_t sx, wl_fixed_t sy) -+{ -+ struct display *display = data; -+ struct wl_buffer *buffer; -+ struct wl_cursor *cursor = display->default_cursor; -+ struct wl_cursor_image *image; -+ -+ if (display->window->fullscreen) -+ wl_pointer_set_cursor(pointer, serial, NULL, 0, 0); -+ else if (cursor) { -+ image = display->default_cursor->images[0]; -+ buffer = wl_cursor_image_get_buffer(image); -+ if (!buffer) -+ return; -+ wl_pointer_set_cursor(pointer, serial, -+ display->cursor_surface, -+ image->hotspot_x, -+ image->hotspot_y); -+ wl_surface_attach(display->cursor_surface, buffer, 0, 0); -+ wl_surface_damage(display->cursor_surface, 0, 0, -+ image->width, image->height); -+ wl_surface_commit(display->cursor_surface); -+ } -+} -+ -+static void -+pointer_handle_leave(void *data, struct wl_pointer *pointer, -+ uint32_t serial, struct wl_surface *surface) -+{ -+} -+ -+static void -+pointer_handle_motion(void *data, struct wl_pointer *pointer, -+ uint32_t time, wl_fixed_t sx, wl_fixed_t sy) -+{ -+} -+ -+static void -+pointer_handle_button(void *data, struct wl_pointer *wl_pointer, -+ uint32_t serial, uint32_t time, uint32_t button, -+ uint32_t state) -+{ -+ struct display *display = data; -+ -+ if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED) -+ { -+ if (display->shell) -+ { -+ xdg_surface_move(display->window->xdg_surface, -+ display->seat, serial); -+ } -+ } -+} -+ -+static void -+pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, -+ uint32_t time, uint32_t axis, wl_fixed_t value) -+{ -+} -+ -+static const struct wl_pointer_listener pointer_listener = { -+ pointer_handle_enter, -+ pointer_handle_leave, -+ pointer_handle_motion, -+ pointer_handle_button, -+ pointer_handle_axis, -+}; -+ -+static void -+touch_handle_down(void *data, struct wl_touch *wl_touch, -+ uint32_t serial, uint32_t time, struct wl_surface *surface, -+ int32_t id, wl_fixed_t x_w, wl_fixed_t y_w) -+{ -+ struct display *d = (struct display *)data; -+ -+ xdg_surface_move(d->window->xdg_surface, d->seat, serial); -+} -+ -+static void -+touch_handle_up(void *data, struct wl_touch *wl_touch, -+ uint32_t serial, uint32_t time, int32_t id) -+{ -+} -+ -+static void -+touch_handle_motion(void *data, struct wl_touch *wl_touch, -+ uint32_t time, int32_t id, wl_fixed_t x_w, wl_fixed_t y_w) -+{ -+} -+ -+static void -+touch_handle_frame(void *data, struct wl_touch *wl_touch) -+{ -+} -+ -+static void -+touch_handle_cancel(void *data, struct wl_touch *wl_touch) -+{ -+} -+ -+static const struct wl_touch_listener touch_listener = { -+ touch_handle_down, -+ touch_handle_up, -+ touch_handle_motion, -+ touch_handle_frame, -+ touch_handle_cancel, -+}; -+ -+static void -+keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, -+ uint32_t format, int fd, uint32_t size) -+{ -+} -+ -+static void -+keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, -+ uint32_t serial, struct wl_surface *surface, -+ struct wl_array *keys) -+{ -+} -+ -+static void -+keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, -+ uint32_t serial, struct wl_surface *surface) -+{ -+} -+ -+static void -+keyboard_handle_key(void *data, struct wl_keyboard *keyboard, -+ uint32_t serial, uint32_t time, uint32_t key, -+ uint32_t state) -+{ -+ struct display *d = data; -+ -+ printf("@@@@@@ keyboard_handle_key: 0x%x\n", key); -+ -+ if (key == KEY_F11 && state) -+ xdg_surface_request_change_state(d->window->xdg_surface, -+ XDG_SURFACE_STATE_FULLSCREEN, -+ !d->window->fullscreen, 0); -+ else if (key == KEY_ESC && state) -+ running = 0; -+} -+ -+static void -+keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, -+ uint32_t serial, uint32_t mods_depressed, -+ uint32_t mods_latched, uint32_t mods_locked, -+ uint32_t group) -+{ -+} -+ -+static const struct wl_keyboard_listener keyboard_listener = { -+ keyboard_handle_keymap, -+ keyboard_handle_enter, -+ keyboard_handle_leave, -+ keyboard_handle_key, -+ keyboard_handle_modifiers, -+}; -+ -+static void -+seat_handle_name(void *data, struct wl_seat *seat, -+ const char *name) -+{ -+ -+} -+ -+static void -+seat_handle_capabilities(void *data, struct wl_seat *seat, -+ enum wl_seat_capability caps) -+{ -+ struct display *d = data; -+ -+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !d->pointer) { -+ d->pointer = wl_seat_get_pointer(seat); -+ wl_pointer_add_listener(d->pointer, &pointer_listener, d); -+ } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && d->pointer) { -+ wl_pointer_destroy(d->pointer); -+ d->pointer = NULL; -+ } -+ -+ if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !d->keyboard) { -+ d->keyboard = wl_seat_get_keyboard(seat); -+ wl_keyboard_add_listener(d->keyboard, &keyboard_listener, d); -+ } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && d->keyboard) { -+ wl_keyboard_destroy(d->keyboard); -+ d->keyboard = NULL; -+ } -+ -+ if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !d->touch) { -+ d->touch = wl_seat_get_touch(seat); -+ wl_touch_set_user_data(d->touch, d); -+ wl_touch_add_listener(d->touch, &touch_listener, d); -+ } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && d->touch) { -+ wl_touch_destroy(d->touch); -+ d->touch = NULL; -+ } -+} -+ -+static const struct wl_seat_listener seat_listener = { -+ seat_handle_capabilities, -+ seat_handle_name -+}; -+ -+static void -+xdg_shell_ping(void *data, struct xdg_shell *shell, uint32_t serial) -+{ -+ xdg_shell_pong(shell, serial); -+} -+ -+static const struct xdg_shell_listener xdg_shell_listener = { -+ xdg_shell_ping, -+}; -+ -+#define XDG_VERSION 3 /* The version of xdg-shell that we implement */ -+#ifdef static_assert -+static_assert(XDG_VERSION == XDG_SHELL_VERSION_CURRENT, -+ "Interface version doesn't match implementation version"); -+#endif -+ -+static void -+registry_handle_global(void *data, struct wl_registry *registry, -+ uint32_t name, const char *interface, uint32_t version) -+{ -+ struct display *d = data; -+ -+ if (strcmp(interface, "wl_compositor") == 0) { -+// d->compositor = -+// wl_registry_bind(registry, name, -+// &wl_compositor_interface, 1); -+ } else if (strcmp(interface, "xdg_shell") == 0) { -+// d->shell = wl_registry_bind(registry, name, -+// &xdg_shell_interface, 1); -+// xdg_shell_add_listener(d->shell, &xdg_shell_listener, d); -+// xdg_shell_use_unstable_version(d->shell, XDG_VERSION); -+ } else if (strcmp(interface, "wl_seat") == 0) { -+ d->seat = wl_registry_bind(registry, name, -+ &wl_seat_interface, 3); -+ wl_seat_add_listener(d->seat, &seat_listener, d); -+ } else if (strcmp(interface, "wl_shm") == 0) { -+// d->shm = wl_registry_bind(registry, name, -+// &wl_shm_interface, 1); -+// d->cursor_theme = wl_cursor_theme_load(NULL, 32, d->shm); -+// if (!d->cursor_theme) { -+// fprintf(stderr, "unable to load default theme\n"); -+// return; -+// } -+// d->default_cursor = -+// wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr"); -+// if (!d->default_cursor) { -+// fprintf(stderr, "unable to load default left pointer\n"); -+// // TODO: abort ? -+// } -+ } -+ else if (strcmp(interface, "ivi_application") == 0) { -+// d->ivi_application = -+// wl_registry_bind(registry, name, -+// &ivi_application_interface, 1); -+ } -+} -+ -+static void -+registry_handle_global_remove(void *data, struct wl_registry *registry, -+ uint32_t name) -+{ -+} -+ -+static const struct wl_registry_listener registry_listener = { -+ registry_handle_global, -+ registry_handle_global_remove -+}; -+ -+static void -+signal_int(int signum) -+{ -+ running = 0; -+} -+ -+static void -+usage(int error_code) -+{ -+ fprintf(stderr, "Usage: simple-egl [OPTIONS]\n\n" -+ " -f\tRun in fullscreen mode\n" -+ " -o\tCreate an opaque surface\n" -+ " -s\tUse a 16 bpp EGL config\n" -+ " -b\tDon't sync to compositor redraw (eglSwapInterval 0)\n" -+ " -h\tThis help text\n\n"); -+ -+ exit(error_code); -+} -+ -+int -+main(int argc, char **argv) -+{ -+ struct sigaction sigint; -+ struct display display = { 0 }; -+ struct window window = { 0 }; -+ int i, ret = 0; -+ -+ window.display = &display; -+ display.window = &window; -+ window.window_size.width = 250; -+ window.window_size.height = 250; -+ window.buffer_size = 32; -+ window.frame_sync = 1; -+ -+ for (i = 1; i < argc; i++) { -+ if (strcmp("-f", argv[i]) == 0) -+ window.fullscreen = 1; -+ else if (strcmp("-o", argv[i]) == 0) -+ window.opaque = 1; -+ else if (strcmp("-s", argv[i]) == 0) -+ window.buffer_size = 16; -+ else if (strcmp("-b", argv[i]) == 0) -+ window.frame_sync = 0; -+ else if (strcmp("-h", argv[i]) == 0) -+ usage(EXIT_SUCCESS); -+ else -+ usage(EXIT_FAILURE); -+ } -+ -+ display.display = wl_display_connect(NULL); -+ assert(display.display); -+ -+ display.registry = wl_display_get_registry(display.display); -+ wl_registry_add_listener(display.registry, -+ ®istry_listener, &display); -+ -+ wl_display_dispatch(display.display); -+ -+ init_egl(&display, &window); -+// create_surface(&window); -+// init_gl(&window); -+ -+// display.cursor_surface = -+// wl_compositor_create_surface(display.compositor); -+ -+ sigint.sa_handler = signal_int; -+ sigemptyset(&sigint.sa_mask); -+ sigint.sa_flags = SA_RESETHAND; -+ sigaction(SIGINT, &sigint, NULL); -+ -+ /* The mainloop here is a little subtle. Redrawing will cause -+ * EGL to read events so we can just call -+ * wl_display_dispatch_pending() to handle any events that got -+ * queued up as a side effect. */ -+ while (running && ret != -1) { -+ wl_display_dispatch(display.display); -+ wl_display_flush(display.display); -+ wl_display_dispatch_pending(display.display); -+// redraw(&window, NULL, 0); -+ } -+ -+ fprintf(stderr, "simple-keyboard-binding exiting\n"); -+ -+ if (window.display->ivi_application) -+ { -+ ivi_surface_destroy(window.ivi_surface); -+ ivi_application_destroy(window.display->ivi_application); -+ } -+ -+// destroy_surface(&window); -+ fini_egl(&display); -+ -+// wl_surface_destroy(display.cursor_surface); -+ if (display.cursor_theme) -+ wl_cursor_theme_destroy(display.cursor_theme); -+ -+ if (display.shell) -+ xdg_shell_destroy(display.shell); -+ -+ if (display.compositor) -+ wl_compositor_destroy(display.compositor); -+ -+ wl_registry_destroy(display.registry); -+ if (window.display->ivi_application) -+ wl_display_roundtrip(display.display); -+ -+ wl_display_flush(display.display); -+ wl_display_disconnect(display.display); -+ -+ return 0; -+} --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0025-ivi-application.xml-Add-configure-event-in-ivi_surfa.patch b/meta-ivi/recipes-graphics/wayland/weston/0025-ivi-application.xml-Add-configure-event-in-ivi_surfa.patch deleted file mode 100644 index 591e71a..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0025-ivi-application.xml-Add-configure-event-in-ivi_surfa.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 7547e12fc219c8a282ee812ad41ada721990003a Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Wed, 10 Sep 2014 13:25:52 +0900 -Subject: [PATCH 25/31] ivi-application.xml: Add configure event in ivi_surface - -Configure event is notified to suggest resize of its surface - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - protocol/ivi-application.xml | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/protocol/ivi-application.xml b/protocol/ivi-application.xml -index 80ab790..0c3fb8c 100644 ---- a/protocol/ivi-application.xml -+++ b/protocol/ivi-application.xml -@@ -41,6 +41,24 @@ - </description> - <arg name="visibility" type="int"/> - </event> -+ -+ <event name="configure"> -+ <description summary="suggest resize"> -+ The configure event asks the client to resize its surface. -+ -+ The size is a hint, in the sense that the client is free to -+ ignore it if it doesn't resize, pick a smaller size (to -+ satisfy aspect ratio or resize in steps of NxM pixels). -+ -+ The client is free to dismiss all but the last configure -+ event it received. -+ -+ The width and height arguments specify the size of the window -+ in surface local coordinates. -+ </description> -+ <arg name="width" type="int"/> -+ <arg name="height" type="int"/> -+ </event> - </interface> - - <interface name="ivi_application" version="1"> --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0026-ivi-layout-Add-configured-signal-in-ivi_layout_surfa.patch b/meta-ivi/recipes-graphics/wayland/weston/0026-ivi-layout-Add-configured-signal-in-ivi_layout_surfa.patch deleted file mode 100644 index 19ea4df..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0026-ivi-layout-Add-configured-signal-in-ivi_layout_surfa.patch +++ /dev/null @@ -1,181 +0,0 @@ -From fe535096b569f1337a512618775684779eace11f Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Fri, 19 Sep 2014 10:13:16 +0900 -Subject: [PATCH 26/31] ivi-layout: Add configured signal in ivi_layout_surface - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - ivi-shell/ivi-layout-private.h | 2 ++ - ivi-shell/ivi-layout-transition.c | 21 ++++++++++++++++++ - ivi-shell/ivi-layout-transition.h | 3 +++ - ivi-shell/ivi-layout.c | 45 ++++++++++++++++++++++++++++++++++++++- - ivi-shell/ivi-layout.h | 6 ++++++ - 5 files changed, 76 insertions(+), 1 deletion(-) - -diff --git a/ivi-shell/ivi-layout-private.h b/ivi-shell/ivi-layout-private.h -index f05f8e9..812a3d4 100644 ---- a/ivi-shell/ivi-layout-private.h -+++ b/ivi-shell/ivi-layout-private.h -@@ -61,6 +61,8 @@ struct ivi_layout_surface { - ivi_controller_surface_content_callback callback; - void* userdata; - } content_observer; -+ -+ struct wl_signal configured; - }; - - struct ivi_layout_layer { -diff --git a/ivi-shell/ivi-layout-transition.c b/ivi-shell/ivi-layout-transition.c -index 1f1e846..ce369f9 100644 ---- a/ivi-shell/ivi-layout-transition.c -+++ b/ivi-shell/ivi-layout-transition.c -@@ -80,6 +80,21 @@ get_transition_from_type_and_id(enum ivi_layout_inner_transition_type type, void - return NULL; - } - -+WL_EXPORT int32_t -+is_surface_transition(struct ivi_layout_surface* surface) -+{ -+ struct ivi_layout* layout = get_instance(); -+ struct transition_node *node=NULL; -+ wl_list_for_each(node, &layout->transitions->transition_list, link){ -+ if ( node->transition->type == IVI_LAYOUT_INNER_TRANSITION_VIEW_MOVE_RESIZE || -+ node->transition->type == IVI_LAYOUT_INNER_TRANSITION_VIEW_RESIZE) -+ if ( node->transition->id_func(node->transition->private_data, surface)) -+ return 1; /* true */ -+ } -+ -+ return 0; /* false */ -+} -+ - static void - tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp) - { -@@ -246,6 +261,12 @@ struct move_resize_view_data { - static void - transition_move_resize_view_destroy(struct ivi_layout_transition* transition) - { -+ struct move_resize_view_data* data = -+ (struct move_resize_view_data*)transition->private_data; -+ struct ivi_layout_surface* layout_surface = data->surface; -+ -+ wl_signal_emit(&layout_surface->configured, layout_surface); -+ - if(transition->private_data){ - free(transition->private_data); - transition->private_data = NULL; -diff --git a/ivi-shell/ivi-layout-transition.h b/ivi-shell/ivi-layout-transition.h -index e8e5509..2c556ed 100644 ---- a/ivi-shell/ivi-layout-transition.h -+++ b/ivi-shell/ivi-layout-transition.h -@@ -74,4 +74,7 @@ ivi_layout_transition_layer_render_order(struct ivi_layout_layer* layer, - uint32_t surface_num, - uint32_t duration); - -+WL_EXPORT int32_t -+is_surface_transition(struct ivi_layout_surface* surface); -+ - #endif -diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c -index 562e0bc..e25c4dc 100644 ---- a/ivi-shell/ivi-layout.c -+++ b/ivi-shell/ivi-layout.c -@@ -838,14 +838,32 @@ commit_list_surface(struct ivi_layout *layout) - ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transitionDuration); - } - -+ int32_t configured = 0; -+ if (ivisurf->prop.destWidth != ivisurf->pending.prop.destWidth || -+ ivisurf->prop.destHeight != ivisurf->pending.prop.destHeight) { -+ configured = 1; -+ } -+ - ivisurf->prop = ivisurf->pending.prop; - ivisurf->prop.transitionType = IVI_LAYOUT_TRANSITION_NONE; - ivisurf->pending.prop.transitionType = IVI_LAYOUT_TRANSITION_NONE; -+ -+ if (configured && !is_surface_transition(ivisurf)) -+ wl_signal_emit(&ivisurf->configured, ivisurf); - } - else{ -+ int32_t configured = 0; -+ if (ivisurf->prop.destWidth != ivisurf->pending.prop.destWidth || -+ ivisurf->prop.destHeight != ivisurf->pending.prop.destHeight) { -+ configured = 1; -+ } -+ - ivisurf->prop = ivisurf->pending.prop; - ivisurf->prop.transitionType = IVI_LAYOUT_TRANSITION_NONE; - ivisurf->pending.prop.transitionType = IVI_LAYOUT_TRANSITION_NONE; -+ -+ if (configured && !is_surface_transition(ivisurf)) -+ wl_signal_emit(&ivisurf->configured, ivisurf); - } - } - } -@@ -3079,6 +3097,7 @@ ivi_layout_surfaceCreate(struct weston_surface *wl_surface, - - wl_list_init(&ivisurf->link); - wl_signal_init(&ivisurf->property_changed); -+ wl_signal_init(&ivisurf->configured); - wl_list_init(&ivisurf->list_layer); - ivisurf->id_surface = id_surface; - ivisurf->layout = layout; -@@ -3209,6 +3228,27 @@ ivi_layout_grabKeyboardKey(struct weston_keyboard_grab *grab, - } - } - -+static void -+ivi_layout_surfaceAddConfiguredListener(struct ivi_layout_surface* ivisurf, -+ struct wl_listener* listener) -+{ -+ wl_signal_add(&ivisurf->configured, listener); -+} -+ -+static void -+ivi_layout_surfaceRemoveConfiguredListener(struct ivi_layout_surface* ivisurf, -+ struct wl_listener* target) -+{ -+ struct wl_listener *listener = NULL; -+ struct wl_listener *next = NULL; -+ -+ wl_list_for_each_safe(listener, next, &ivisurf->configured.listener_list, link) { -+ if (target == listener) { -+ wl_list_remove(&listener->link); -+ } -+ } -+} -+ - WL_EXPORT struct ivi_layout_interface ivi_layout_interface = { - .get_weston_view = ivi_layout_get_weston_view, - .surfaceConfigure = ivi_layout_surfaceConfigure, -@@ -3216,5 +3256,8 @@ WL_EXPORT struct ivi_layout_interface ivi_layout_interface = { - .surfaceCreate = ivi_layout_surfaceCreate, - .initWithCompositor = ivi_layout_initWithCompositor, - .emitWarningSignal = ivi_layout_emitWarningSignal, -- .grab_keyboard_key = ivi_layout_grabKeyboardKey -+ .grab_keyboard_key = ivi_layout_grabKeyboardKey, -+ .get_surface_dimension = ivi_layout_surfaceGetDimension, -+ .add_surface_configured_listener = ivi_layout_surfaceAddConfiguredListener, -+ .remove_surface_configured_listener = ivi_layout_surfaceRemoveConfiguredListener - }; -diff --git a/ivi-shell/ivi-layout.h b/ivi-shell/ivi-layout.h -index 073a1e1..6d4ad73 100644 ---- a/ivi-shell/ivi-layout.h -+++ b/ivi-shell/ivi-layout.h -@@ -137,6 +137,12 @@ struct ivi_layout_interface { - enum ivi_layout_warning_flag flag); - void (*grab_keyboard_key)(struct weston_keyboard_grab *grab, - uint32_t time, uint32_t key, uint32_t state); -+ int32_t (*get_surface_dimension)(struct ivi_layout_surface *ivisurf, -+ int32_t *pDimension); -+ void (*add_surface_configured_listener)(struct ivi_layout_surface *ivisurf, -+ struct wl_listener* listener); -+ void (*remove_surface_configured_listener)(struct ivi_layout_surface *ivisurf, -+ struct wl_listener* listener); - }; - - WL_EXPORT struct ivi_layout_interface ivi_layout_interface; --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0027-ivi-shell-send-ivi_surface-configure-event-when-ivi_.patch b/meta-ivi/recipes-graphics/wayland/weston/0027-ivi-shell-send-ivi_surface-configure-event-when-ivi_.patch deleted file mode 100644 index cc7f15b..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0027-ivi-shell-send-ivi_surface-configure-event-when-ivi_.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 309d3189451ec761098004e3dbcf5443df7146a4 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Wed, 10 Sep 2014 13:32:14 +0900 -Subject: [PATCH 27/31] ivi-shell: send ivi_surface configure event when - ivi_layout_surface configured signal emitted. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - ivi-shell/ivi-shell.c | 28 ++++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - -diff --git a/ivi-shell/ivi-shell.c b/ivi-shell/ivi-shell.c -index bf4affd..468e66a 100644 ---- a/ivi-shell/ivi-shell.c -+++ b/ivi-shell/ivi-shell.c -@@ -57,6 +57,7 @@ extern keyboard_key keyboard_key_func; - - struct ivi_shell_surface - { -+ struct wl_resource* resource; - struct ivi_shell *shell; - struct ivi_layout_surface *layout_surface; - -@@ -67,6 +68,8 @@ struct ivi_shell_surface - int32_t height; - - struct wl_list link; -+ -+ struct wl_listener configured_listener; - }; - - struct ivi_shell_setting -@@ -85,6 +88,8 @@ static struct ivi_layout_interface *ivi_layout; - * Implementation of ivi_surface - */ - -+static void surface_configure_notify(struct wl_listener *listener, void *data); -+ - static void - ivi_shell_surface_configure(struct weston_surface *, int32_t, int32_t); - -@@ -144,6 +149,7 @@ surface_destroy(struct wl_client *client, struct wl_resource *resource) - ivisurf->surface->configure_private = NULL; - ivisurf->surface = NULL; - ivi_layout->surfaceSetNativeContent(NULL, 0, 0, ivisurf->id_surface); -+ ivi_layout->remove_surface_configured_listener(ivisurf->layout_surface, &ivisurf->configured_listener); - } - - wl_resource_destroy(resource); -@@ -246,9 +252,13 @@ application_surface_create(struct wl_client *client, - ivisurf->id_surface = id_surface; - } - -+ ivisurf->resource = res; - ivisurf->width = 0; - ivisurf->height = 0; - ivisurf->layout_surface = layout_surface; -+ ivisurf->configured_listener.notify = surface_configure_notify; -+ ivi_layout->add_surface_configured_listener(layout_surface, &ivisurf->configured_listener); -+ - ivisurf->surface = weston_surface; - - weston_surface->configure = ivi_shell_surface_configure; -@@ -385,6 +395,24 @@ ivi_load_modules(struct weston_compositor *compositor, const char *modules, - return 0; - } - -+static void -+surface_configure_notify(struct wl_listener *listener, void *data) -+{ -+ struct ivi_layout_surface* layout_surf = -+ (struct ivi_layout_surface*) data; -+ -+ struct ivi_shell_surface *shell_surf = -+ container_of(listener, -+ struct ivi_shell_surface, -+ configured_listener); -+ -+ int32_t dim[2] = {}; -+ ivi_layout->get_surface_dimension(layout_surf, dim); -+ -+ ivi_surface_send_configure(shell_surf->resource, dim[0], dim[1]); -+ -+} -+ - WL_EXPORT int - module_init(struct weston_compositor *compositor, - int *argc, char *argv[]) --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0028-ivi-layout-fix-calculation-of-view-scale.patch b/meta-ivi/recipes-graphics/wayland/weston/0028-ivi-layout-fix-calculation-of-view-scale.patch deleted file mode 100644 index dd47e39..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0028-ivi-layout-fix-calculation-of-view-scale.patch +++ /dev/null @@ -1,63 +0,0 @@ -From b307f8ae4da32bc58c5dfe2d32dc6c70529b4a5e Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Fri, 19 Sep 2014 10:23:26 +0900 -Subject: [PATCH 28/31] ivi-layout: fix calculation of view scale. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - ivi-shell/ivi-layout-export.h | 1 + - ivi-shell/ivi-layout.c | 17 ++++++++++++++--- - 2 files changed, 15 insertions(+), 3 deletions(-) - -diff --git a/ivi-shell/ivi-layout-export.h b/ivi-shell/ivi-layout-export.h -index f0654f1..f24fa99 100644 ---- a/ivi-shell/ivi-layout-export.h -+++ b/ivi-shell/ivi-layout-export.h -@@ -67,6 +67,7 @@ enum ivi_layout_notification_mask { - IVI_NOTIFICATION_PIXELFORMAT = (1 << 8), - IVI_NOTIFICATION_ADD = (1 << 9), - IVI_NOTIFICATION_REMOVE = (1 << 10), -+ IVI_NOTIFICATION_CONFIGURE = (1 << 11), - IVI_NOTIFICATION_ALL = 0xFFFF - }; - -diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c -index e25c4dc..3edf5a3 100644 ---- a/ivi-shell/ivi-layout.c -+++ b/ivi-shell/ivi-layout.c -@@ -2957,18 +2957,29 @@ ivi_layout_surfaceConfigure(struct ivi_layout_surface *ivisurf, - int32_t width, int32_t height) - { - struct ivi_layout *layout = get_instance(); -- -+ int32_t in_init = 0; - ivisurf->surface->width_from_buffer = width; - ivisurf->surface->height_from_buffer = height; - - if (ivisurf->prop.sourceWidth == 0 || ivisurf->prop.sourceHeight == 0) { -+ in_init = 1; -+ } -+ -+ /* FIXME: when sourceHeight/Width is used as clipping range in image buffer */ -+ /* if (ivisurf->prop.sourceWidth == 0 || ivisurf->prop.sourceHeight == 0) { */ - ivisurf->pending.prop.sourceWidth = width; - ivisurf->pending.prop.sourceHeight = height; - ivisurf->prop.sourceWidth = width; - ivisurf->prop.sourceHeight = height; -- } -+ /* } */ -+ -+ ivisurf->event_mask |= IVI_NOTIFICATION_CONFIGURE; - -- wl_signal_emit(&layout->surface_notification.configure_changed, ivisurf); -+ if (in_init) { -+ wl_signal_emit(&layout->surface_notification.configure_changed, ivisurf); -+ } else { -+ ivi_layout_commitChanges(); -+ } - } - - static int32_t --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0029-DEBUG-simple-egl-receive-configure-event-and-resize-.patch b/meta-ivi/recipes-graphics/wayland/weston/0029-DEBUG-simple-egl-receive-configure-event-and-resize-.patch deleted file mode 100644 index eced223..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0029-DEBUG-simple-egl-receive-configure-event-and-resize-.patch +++ /dev/null @@ -1,56 +0,0 @@ -From a3fbe909645b636460cca2d20d68557517cf3b45 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Wed, 10 Sep 2014 13:57:10 +0900 -Subject: [PATCH 29/31] DEBUG: simple-egl receive configure event and resize - buffer. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - clients/simple-egl.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/clients/simple-egl.c b/clients/simple-egl.c -index 92f2dc2..d752614 100644 ---- a/clients/simple-egl.c -+++ b/clients/simple-egl.c -@@ -335,6 +335,26 @@ static const struct xdg_surface_listener xdg_surface_listener = { - }; - - static void -+handle_ivi_surface_configure(void *data, struct ivi_surface *ivi_surface, -+ int32_t width, int32_t height) -+{ -+ struct window *window = data; -+ -+ wl_egl_window_resize(window->native, width, height, 0, 0); -+ -+ window->geometry.width = width; -+ window->geometry.height = height; -+ -+ if (!window->fullscreen) -+ window->window_size = window->geometry; -+} -+ -+static const struct ivi_surface_listener ivi_surface_listener = { -+ NULL, -+ handle_ivi_surface_configure, -+}; -+ -+static void - create_surface(struct window *window) - { - struct display *display = window->display; -@@ -370,6 +390,10 @@ create_surface(struct window *window) - fprintf(stderr, "Failed to create ivi_client_surface\n"); - abort(); - } -+ -+ ivi_surface_add_listener(window->ivi_surface, -+ &ivi_surface_listener, window); -+ - } else { - assert(0); - } --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0030-simple-shm-support-ivi_surface-configure-event.patch b/meta-ivi/recipes-graphics/wayland/weston/0030-simple-shm-support-ivi_surface-configure-event.patch deleted file mode 100644 index 6c6f59d..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0030-simple-shm-support-ivi_surface-configure-event.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 58da4d5a0b0fd9e8dd512aef0291c66c855b531b Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Tue, 16 Sep 2014 15:21:12 +0900 -Subject: [PATCH 30/31] simple-shm: support ivi_surface configure event. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - clients/simple-shm.c | 31 +++++++++++++++++++++++++++++++ - 1 file changed, 31 insertions(+) - -diff --git a/clients/simple-shm.c b/clients/simple-shm.c -index c54b5d7..123d1a2 100644 ---- a/clients/simple-shm.c -+++ b/clients/simple-shm.c -@@ -159,6 +159,33 @@ static const struct xdg_surface_listener xdg_surface_listener = { - handle_delete, - }; - -+static void -+handle_ivi_surface_configure(void *data, struct ivi_surface *ivi_surface, -+ int32_t width, int32_t height) -+{ -+ struct window *window = data; -+ -+ if (window->buffers[0].buffer) { -+ wl_buffer_destroy(window->buffers[0].buffer); -+ window->buffers[0].buffer = NULL; -+ window->buffers[0].busy = 0; -+ } -+ -+ if (window->buffers[1].buffer) { -+ wl_buffer_destroy(window->buffers[1].buffer); -+ window->buffers[1].buffer = NULL; -+ window->buffers[1].busy = 0; -+ } -+ -+ window->width = width; -+ window->height = height; -+} -+ -+static const struct ivi_surface_listener ivi_surface_listener = { -+ NULL, -+ handle_ivi_surface_configure, -+}; -+ - static struct window * - create_window(struct display *display, int width, int height) - { -@@ -200,6 +227,10 @@ create_window(struct display *display, int width, int height) - fprintf(stderr, "Failed to create ivi_client_surface\n"); - abort(); - } -+ -+ ivi_surface_add_listener(window->ivi_surface, -+ &ivi_surface_listener, window); -+ - } else { - assert(0); - } --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/0031-window.c-support-ivi_surface-configure-event.patch b/meta-ivi/recipes-graphics/wayland/weston/0031-window.c-support-ivi_surface-configure-event.patch deleted file mode 100644 index 9fe8592..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/0031-window.c-support-ivi_surface-configure-event.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 8803555db2e6f1cd6e2001935216774260774875 Mon Sep 17 00:00:00 2001 -From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> -Date: Tue, 16 Sep 2014 15:40:25 +0900 -Subject: [PATCH 31/31] window.c: support ivi_surface configure event. - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> ---- - clients/window.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/clients/window.c b/clients/window.c -index 684f98e..99460b8 100644 ---- a/clients/window.c -+++ b/clients/window.c -@@ -1374,6 +1374,20 @@ window_get_display(struct window *window) - } - - static void -+handle_ivi_surface_configure(void *data, struct ivi_surface *ivi_surface, -+ int32_t width, int32_t height) -+{ -+ struct window *window = data; -+ -+ window_schedule_resize(window, width, height); -+} -+ -+static const struct ivi_surface_listener ivi_surface_listener = { -+ NULL, -+ handle_ivi_surface_configure, -+}; -+ -+static void - surface_create_surface(struct surface *surface, uint32_t flags) - { - struct display *display = surface->window->display; -@@ -1390,6 +1404,9 @@ surface_create_surface(struct surface *surface, uint32_t flags) - fprintf(stderr, "Failed to create ivi_client_surface\n"); - abort(); - } -+ -+ ivi_surface_add_listener(surface->window->ivi_surface, -+ &ivi_surface_listener, surface->window); - } - } - --- -1.9.3 - diff --git a/meta-ivi/recipes-graphics/wayland/weston/background.png b/meta-ivi/recipes-graphics/wayland/weston/background.png Binary files differdeleted file mode 100644 index 60c317c..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/background.png +++ /dev/null diff --git a/meta-ivi/recipes-graphics/wayland/weston/fullscreen.png b/meta-ivi/recipes-graphics/wayland/weston/fullscreen.png Binary files differdeleted file mode 100644 index dc5a302..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/fullscreen.png +++ /dev/null diff --git a/meta-ivi/recipes-graphics/wayland/weston/home.png b/meta-ivi/recipes-graphics/wayland/weston/home.png Binary files differdeleted file mode 100644 index af9f603..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/home.png +++ /dev/null diff --git a/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_clickdot.png b/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_clickdot.png Binary files differdeleted file mode 100644 index 711bcfc..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_clickdot.png +++ /dev/null diff --git a/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_flower.png b/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_flower.png Binary files differdeleted file mode 100644 index 0a71479..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_flower.png +++ /dev/null diff --git a/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_simple-egl.png b/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_simple-egl.png Binary files differdeleted file mode 100644 index 0253950..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_simple-egl.png +++ /dev/null diff --git a/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_simple-shm.png b/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_simple-shm.png Binary files differdeleted file mode 100644 index 6aacaaa..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_simple-shm.png +++ /dev/null diff --git a/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_smoke.png b/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_smoke.png Binary files differdeleted file mode 100644 index 0dbe20e..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/icon_ivi_smoke.png +++ /dev/null diff --git a/meta-ivi/recipes-graphics/wayland/weston/ivi-shell-click-event.patch b/meta-ivi/recipes-graphics/wayland/weston/ivi-shell-click-event.patch deleted file mode 100644 index 3921ca9..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/ivi-shell-click-event.patch +++ /dev/null @@ -1,124 +0,0 @@ -From ntanibata@jp.adit-jv.com Fri Dec 12 03:56:24 2014 -Received: from mail.windriver.com (147.11.1.11) by ALA-HCA.corp.ad.wrs.com - (147.11.189.50) with Microsoft SMTP Server (TLS) id 14.3.174.1; Thu, 11 Dec - 2014 18:56:23 -0800 -Received: from mr1.windriver.com (mr1 [192.124.127.25]) by mail.windriver.com - (8.14.9/8.14.5) with ESMTP id sBC2uLlr026848 (version=TLSv1/SSLv3 - cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 11 Dec 2014 18:56:22 - -0800 (PST) -Received: from esa2.edoxs1.iphmx.com (esa2.edoxs1.iphmx.com [68.232.135.254]) - by mr1.windriver.com (8.14.9/8.14.9) with ESMTP id sBC2uL7v028404 - (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=FAIL); Thu, 11 Dec 2014 - 18:56:21 -0800 -X-IronPort-Anti-Spam-Filtered: true -X-IronPort-Anti-Spam-Result: AtUAAKJYilSFwLVOnGdsb2JhbABZg1hYw1aCGwqFbgKBFRYBAQEBAREBAQEBAQYNCQkULoQMAQEBBAECCRsJEAEBLAsBCwQCAQgRBAEBAQoGFwEGAR4JBBoJCAIEEwgMB4gQDsBZhVIBBZFGAQEBAQEBAQEBAQEBAQEBAQEBAQEBEQaPDwEQAgEeBisHBoInTB2BE4Uig3YohEQEgzqBQIFcIoFzgQwNI4ItihODN4QdXwGBAiSBHAEBAQ -X-IPAS-Result: AtUAAKJYilSFwLVOnGdsb2JhbABZg1hYw1aCGwqFbgKBFRYBAQEBAREBAQEBAQYNCQkULoQMAQEBBAECCRsJEAEBLAsBCwQCAQgRBAEBAQoGFwEGAR4JBBoJCAIEEwgMB4gQDsBZhVIBBZFGAQEBAQEBAQEBAQEBAQEBAQEBAQEBEQaPDwEQAgEeBisHBoInTB2BE4Uig3YohEQEgzqBQIFcIoFzgQwNI4ItihODN4QdXwGBAiSBHAEBAQ -X-IronPort-AV: E=Sophos;i="5.07,561,1413270000"; - d="scan'208";a="110097519" -Received: from ma-dnext03.denso.co.jp ([133.192.181.78]) by - esa2.edoxs1.iphmx.com with ESMTP; 11 Dec 2014 18:56:12 -0800 -Received: from guardw2.denso.co.jp (unknown [133.192.24.24]) by - ma-dnext03.denso.co.jp (Postfix) with ESMTP id 25D295D02BA; Fri, 12 Dec 2014 - 11:56:09 +0900 (JST) -DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=adit-jv.com; - s=jpadit-jvmail2011; t=1418352969; - bh=AfmD+uPkOMv42mZQfFad+rgrE601l5DmedvTjy11d4c=; - h=MIME-Version:Content-Type:Content-Transfer-Encoding:Subject:Date: - Message-ID:In-Reply-To:References:From:To:Cc; - b=V6gBLvmpZtG28BTmzIocIVwltzkvm1YCiUgCQ+FFRQ6rUVlsPjLbJ7OGQP3Z47xQT - BveplQwKTCpnNCHqvvqyCNQcuTWbOBjOpgCzkOQH8163Mi6fHeRsrOIWVwvb5WLLbQ - Otpd6b/gvSfgv5uBk3cUQHNeG2aby+iZmdRsaQILqkhv1oUlT7FWBP1hHCLGHpqJL4 - p4MxHtAqKjQlnDJELSK/8ExdbQJGlDsAc0DNk4RzzwUp4Ff3m3CMwRBmkvtma4UVQh - NYbSXaPGDnJcYSg7r9qT5k7K1mbBuoKcz0bNYMtTDUsBOLEirXT0kYWqoFfl+Jaw/q - eY6yHT+Z0lw2A== -Received: by guardw2.denso.co.jp (Postfix, from userid 0) id 15D6E6DF3; Fri, - 12 Dec 2014 11:56:09 +0900 (JST) -Received: from smtp1.denso.co.jp [133.192.24.88] by guardw2 with ESMTP id - MAA08496; Fri, 12 Dec 2014 11:56:08 +0900 -Received: from msj2.adit-jv.com ([10.71.113.25]) by smtp01.denso.co.jp (MOS - 4.2.4-GA) with ESMTP id CJC78590; Fri, 12 Dec 2014 11:56:07 +0900 -X-MimeOLE: Produced By Microsoft Exchange V6.5 -Content-Class: urn:content-classes:message -Content-Type: text/plain; charset="iso-8859-1" -Content-Transfer-Encoding: quoted-printable -Subject: RE: weston-ivi-shell input method not supported -Date: Fri, 12 Dec 2014 11:56:06 +0900 -Message-ID: <EC24A990E5DA3D41A67C0F9C755F987BEA7A60@msj2.adit-jv.com> -In-Reply-To: <0994C93624B9194C867A2AA78BFAA734AD74977C@ALA-MBB.corp.ad.wrs.com> -X-MS-Has-Attach: -X-MS-TNEF-Correlator: -Thread-Topic: weston-ivi-shell input method not supported -Thread-Index: AdAEo9qzd7B8JvN8SiCG1HHmuOgOQgAps/xQAgi50BAAHfTugAAGiR4wACG0O/AAJFPVgAAfTuMAABx/dYABEnjvXgABCAagAFhzyOA= -References: <0994C93624B9194C867A2AA78BFAA734AD7327F7@ALA-MBB.corp.ad.wrs.com> <EC24A990E5DA3D41A67C0F9C755F987BE562C8@msj2.adit-jv.com> <0994C93624B9194C867A2AA78BFAA734AD73F017@ALA-MBB.corp.ad.wrs.com> <EC24A990E5DA3D41A67C0F9C755F987BEA73BB@msj2.adit-jv.com> <0994C93624B9194C867A2AA78BFAA734AD73F824@ALA-MBB.corp.ad.wrs.com> <EC24A990E5DA3D41A67C0F9C755F987BEA7445@msj2.adit-jv.com> <547ECC2F.5000201@windriver.com> <EC24A990E5DA3D41A67C0F9C755F987BEA7500@msj2.adit-jv.com>,<54805D89.5010003@windriver.com> <7A688B48FC95D148BFE83E098348BE505CF002FB@ALA-MBA.corp.ad.wrs.com> <0994C93624B9194C867A2AA78BFAA734AD74977C@ALA-MBB.corp.ad.wrs.com> -From: "Tanibata, Nobuhiko (ADITJ/SWG)" <ntanibata@jp.adit-jv.com> -To: =?iso-8859-1?Q?Bourcier=2C_Fr=E9d=E9ric?= - <Frederic.Bourcier@windriver.com>, "Behrens, Holger" - <Holger.Behrens@windriver.com>, "Sarbu, Florin-Ionut (Florin)" - <Florin.Sarbu@windriver.com>, "Gherzan, Andrei" - <Andrei.Gherzan@windriver.com> -CC: <genivi-ivi-layer-management@lists.genivi.org>, - <philippe.robin@technoveo.com>, "Ishikawa, Tetsuri (ADITJ/SWG)" - <tishikawa@jp.adit-jv.com> -Return-Path: ntanibata@jp.adit-jv.com -X-MS-Exchange-Organization-AuthSource: ALA-HCA.corp.ad.wrs.com -X-MS-Exchange-Organization-AuthAs: Anonymous -MIME-Version: 1.0 -Status: RO -Content-Length: 10061 -Lines: 284 - -Hi Frederic-san, Holger-san, - -I think I find root cause as result of debug. - -For first check, please apply this patch on ivi-shell, branch genivi-1.2.0;= - I think you are using now. -Please forget genivi-1.3.0 in my another mail. Formally we should use 1.3.0= - but for demo purpose first fix might be better. - ------------------------------------------------------------------------------------------------ -Subject: [PATCH] Add the processing which has notice of click event from compositor - -Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA at xddp.denso.co.jp> ---- - ivi-shell/ivi-shell.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/ivi-shell/ivi-shell.c b/ivi-shell/ivi-shell.c -index 468e66a..9238e93 100644 ---- a/ivi-shell/ivi-shell.c -+++ b/ivi-shell/ivi-shell.c -@@ -413,6 +413,20 @@ surface_configure_notify(struct wl_listener *listener, void *data) - - } - -+static void -+click_to_activate_binding(struct weston_seat *seat, uint32_t time, uint32_t button, -+ void *data) -+{ -+ if (seat->pointer->grab != &seat->pointer->default_grab) { -+ return; -+ } -+ if (seat->pointer->focus == NULL) { -+ return; -+ } -+ -+ weston_surface_activate(seat->pointer->focus->surface, seat); -+} -+ - WL_EXPORT int - module_init(struct weston_compositor *compositor, - int *argc, char *argv[]) -@@ -479,6 +493,8 @@ module_init(struct weston_compositor *compositor, - - keyboard_key_func = ivi_layout->grab_keyboard_key; - -+ weston_compositor_add_button_binding(compositor, BTN_LEFT, 0, click_to_activate_binding, shell); -+ - free(setting.ivi_module); - return 0; - } -1.7.11.7 - -BR, -Nobuhiko Tanibata diff --git a/meta-ivi/recipes-graphics/wayland/weston/panel.png b/meta-ivi/recipes-graphics/wayland/weston/panel.png Binary files differdeleted file mode 100644 index 0fd72b8..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/panel.png +++ /dev/null diff --git a/meta-ivi/recipes-graphics/wayland/weston/pattern.png b/meta-ivi/recipes-graphics/wayland/weston/pattern.png Binary files differdeleted file mode 100644 index 5ac8986..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/pattern.png +++ /dev/null diff --git a/meta-ivi/recipes-graphics/wayland/weston/random.png b/meta-ivi/recipes-graphics/wayland/weston/random.png Binary files differdeleted file mode 100644 index 7640aa0..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/random.png +++ /dev/null diff --git a/meta-ivi/recipes-graphics/wayland/weston/sidebyside.png b/meta-ivi/recipes-graphics/wayland/weston/sidebyside.png Binary files differdeleted file mode 100644 index 98ea780..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/sidebyside.png +++ /dev/null diff --git a/meta-ivi/recipes-graphics/wayland/weston/tiling.png b/meta-ivi/recipes-graphics/wayland/weston/tiling.png Binary files differdeleted file mode 100644 index dd3e02c..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston/tiling.png +++ /dev/null diff --git a/meta-ivi/recipes-graphics/wayland/weston_1.5.0.bbappend b/meta-ivi/recipes-graphics/wayland/weston_1.5.0.bbappend deleted file mode 100644 index 52522b0..0000000 --- a/meta-ivi/recipes-graphics/wayland/weston_1.5.0.bbappend +++ /dev/null @@ -1,103 +0,0 @@ -FILESEXTRAPATHS_append := ":${THISDIR}/${PN}" - -# -# Add weston-ivi-shell patches -# Repo: https://github.com/Tarnyko/weston-ivi-shell -# Branch: genivi-1.2.0 -# -SRC_URI_append = " \ - file://0001-README-modifed-for-ivi-shell.patch \ - file://0002-protocol-add-interface-ivi_application-extension.patch \ - file://0003-ivi-shell-add-the-shell-plugin-for-In-Vehicle-Infota.patch \ - file://0004-ivi-shell-add-IVI-layout-APIs.patch \ - file://0005-protocol-ivi-hmi-controller-protocol-to-set-up-IVI-s.patch \ - file://0006-ivi-shell-a-reference-implementation-how-to-use-ivi-.patch \ - file://0007-clients-a-reference-implementation-of-UI-client-how-.patch \ - file://0008-data-add-reference-image-files-for-weston-ivi-shell-.patch \ - file://0009-ivi-shell-a-reference-of-weston.ini-for-ivi-shell-an.patch \ - file://0010-clients-modify-example-clients-to-support-ivi-applic.patch \ - file://0011-ingnore-data-wayland.png.patch \ - file://0012-Reference-implementation-of-input-panel-for-ivi-shel.patch \ - file://0013-If-window-is-requsted-by-Virtual-keyboard-ivi_applic.patch \ - file://0014-input-panel-Change-unsigned-to-signed-to-follow-west.patch \ - file://0015-This-applies-transition-animation-to-ivi-shell.patch \ - file://0016-Update-README-to-show-how-to-build-congirue-and-star.patch \ - file://0017-ivi-shell-Fix-incorrect-member-reference-in-wl_list_.patch \ - file://0018-ivi-shell-Set-source-surface-size-if-surfaceConfigur.patch \ - file://0019-ivi-shell-Add-IVI-layout-APIs.patch \ - file://0020-ivi-layout-fix-transform-matrix-could-not-be-inverti.patch \ - file://0021-To-get-resolution-of-a-screen-refer-width-and-height.patch \ - file://0022-input.c-give-control-of-default_grab_keyboard_key-to.patch \ - file://0023-ivi-layout-send-key-event-to-clients-that-are-bindin.patch \ - file://0024-DEBUG-add-weston-simple-keyboard-binding.patch \ - file://0025-ivi-application.xml-Add-configure-event-in-ivi_surfa.patch \ - file://0026-ivi-layout-Add-configured-signal-in-ivi_layout_surfa.patch \ - file://0027-ivi-shell-send-ivi_surface-configure-event-when-ivi_.patch \ - file://0028-ivi-layout-fix-calculation-of-view-scale.patch \ - file://0029-DEBUG-simple-egl-receive-configure-event-and-resize-.patch \ - file://0030-simple-shm-support-ivi_surface-configure-event.patch \ - file://0031-window.c-support-ivi_surface-configure-event.patch \ - " - -# -# [PATCH] Add the processing which has notice of click event from compositor -# Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA at xddp.denso.co.jp> -SRC_URI_append = "\ - file://ivi-shell-click-event.patch \ - " -# -# [PATCH] Enable/disable default virtual keyboard -# Signed-off-by: Imran Zaman <imran.zaman@intel.com> -SRC_URI_append = "\ - file://0001-Enable-disable-default-virtual-keyboard.patch \ - " - -EXTRA_OECONF += "\ - --disable-default-vkb \ - " - -# -# TO DO -# Remove when bug is fixed: https://bugzilla.yoctoproject.org/show_bug.cgi?id=5968 -# Due to a yocto bug, applying patches with something else then quilt fails. -# We can't use quilt for this (0008) patch as this tool does not support binary -# diffs. So we manually copy files from: -# 0008-data-add-reference-image-files-for-weston-ivi-shell-.patch -# The above patch was modified to not apply binary diffs but only text diff. -# -SRC_URI_append = " \ - file://background.png \ - file://home.png \ - file://icon_ivi_flower.png \ - file://icon_ivi_simple-shm.png \ - file://panel.png \ - file://sidebyside.png \ - file://fullscreen.png \ - file://icon_ivi_clickdot.png \ - file://icon_ivi_simple-egl.png \ - file://icon_ivi_smoke.png \ - file://random.png \ - file://tiling.png \ - " - -FILES_${PN} += "${libdir}/weston/* ${sysconfdir}/xdg" -FILES_${PN}-dbg += "${libdir}/weston/.debug/*" - -do_configure_append() { - # TO DO - # Remove when bug is fixed: https://bugzilla.yoctoproject.org/show_bug.cgi?id=5968 - # Copy files from 0007-data-add-reference-image-files-for-weston-ivi-shell-.patch - cp -rvf ${WORKDIR}/*.png ${S}/data -} - -do_install_append() { - WESTON_INI_CONFIG=${sysconfdir}/xdg/weston - install -d ${D}${WESTON_INI_CONFIG} - install -m 0644 ${S}/ivi-shell/weston.ini.in ${D}${WESTON_INI_CONFIG}/weston.ini - sed -i -e 's/hmi-controller.so/hmi-controller.so,ivi-controller.so/' \ - -e 's|\@libexecdir\@|${libexecdir}|' \ - -e 's|\@abs_top_builddir\@\/data|${datadir}\/weston|' \ - -e 's|\@abs_top_builddir\@\/clients|${bindir}|' \ - -e 's|\@abs_top_builddir\@\/weston-ivi-shell-user-interface|${libdir}/weston/weston-ivi-shell-user-interface|' ${D}${WESTON_INI_CONFIG}/weston.ini - -} diff --git a/meta-ivi/recipes-graphics/wayland/weston_1.6.0.bbappend b/meta-ivi/recipes-graphics/wayland/weston_1.6.0.bbappend new file mode 100644 index 0000000..1f78696 --- /dev/null +++ b/meta-ivi/recipes-graphics/wayland/weston_1.6.0.bbappend @@ -0,0 +1,73 @@ +PR = "r1" + +FILESEXTRAPATHS_append := ":${THISDIR}/${PN}:${THISDIR}/${PN}-${PV}" + +# We patch compositor.c so ignore license in that file +LIC_FILES_CHKSUM = "file://COPYING;md5=275efac2559a224527bd4fd593d38466" + +# Weston ivi shell needs libinput backend +PACKAGECONFIG_append += "libinput" + +# Use git repository because we want to use 'git' for applying patches +SRC_URI_remove = "http://wayland.freedesktop.org/releases/${BPN}-${PV}.tar.xz" +SRC_URI_append = "git://anongit.freedesktop.org/wayland/${PN}" +SRCREV = "2858cc2a50854685b44eee72994dea57f5aa4246" +S = "${WORKDIR}/git" + +# +# Add weston-ivi-shell patches +# Repo: https://github.com/ntanibata/weston-ivi-shell +# Branch: weston-ivi-shell-1.6.0-WIP-06-working +# +SRC_URI_append = " \ + file://0001-README-modifed-for-ivi-shell.patch \ + file://0002-protocol-add-interface-ivi_application-extension.patch \ + file://0003-ivi-shell-add-IVI-layout-APIs.patch \ + file://0004-ivi-shell-add-the-shell-plugin-for-In-Vehicle-Infota.patch \ + file://0005-protocol-ivi-hmi-controller-protocol-to-set-up-IVI-s.patch \ + file://0006-ivi-shell-a-reference-implementation-how-to-use-ivi-.patch \ + file://0007-clients-a-reference-implementation-of-UI-client-how-.patch \ + file://0008-data-add-reference-image-files-for-weston-ivi-shell-.patch \ + file://0009-ivi-shell-a-reference-of-weston.ini-for-ivi-shell-an.patch \ + file://0010-clients-support-ivi-application.xml-for-clients-simp.patch \ + file://0011-clients-support-ivi-application.xml-for-clients-simp.patch \ + file://0012-clients-support-ivi-application.xml-for-clients-wind.patch \ + file://0013-Reference-implementation-of-input-panel-for-ivi-shel.patch \ + file://0014-input-panel-ivi-add-seat-keyboard-focus-to-condition.patch \ + file://0015-protocol-ivi-application.xml-update-description-of-i.patch \ + " + +# We use git because we need binary diff support or the above patches (png files) +PATCHTOOL = 'git' + +# or use this. +#SRCREV = "814f152d3f3ca5973162cad8c19f1e86f85f6d27" +#SRC_URI_append += "git://github.com/ntanibata/weston-ivi-shell.git;protocol=https;branch=weston-ivi-shell-1.6.0-WIP-06-working" + +# [PATCH] Add the processing which has notice of click event from compositor +# Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA at xddp.denso.co.jp> +SRC_URI_append = " file://ivi-shell-click-event.patch" + +# [PATCH] Enable/disable default virtual keyboard +# Signed-off-by: Imran Zaman <imran.zaman@intel.com> +SRC_URI_append = " file://Enable-disable-default-virtual-keyboard.patch" +EXTRA_OECONF += "--disable-default-vkb" + +# [PATCH] fix up for GENIVI baseline 9.0 +# Signed-off-by: Yong-iL Joh <yong-il.joh@windriver.com> +SRC_URI_append = " file://build.fix.up.patch" + +FILES_${PN} += "${libdir}/weston/* ${sysconfdir}/xdg" +FILES_${PN}-dbg += "${libdir}/weston/.debug/*" + +do_install_append() { + WESTON_INI_CONFIG=${sysconfdir}/xdg/weston + install -d ${D}${WESTON_INI_CONFIG} + install -m 0644 ${S}/ivi-shell/weston.ini.in ${D}${WESTON_INI_CONFIG}/weston.ini + sed -i -e 's/hmi-controller.so/hmi-controller.so,ivi-controller.so/' \ + -e 's|\@libexecdir\@|${libexecdir}|' \ + -e 's|\@abs_top_builddir\@\/data|${datadir}\/weston|' \ + -e 's|\@abs_top_builddir\@\/clients|${bindir}|' \ + -e 's|\@abs_top_builddir\@\/weston-ivi-shell-user-interface|${libdir}/weston/weston-ivi-shell-user-interface|' ${D}${WESTON_INI_CONFIG}/weston.ini + +} |