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