From 48a3aa7d05aa8d9dba5e58d7f4dda0eaa706fc35 Mon Sep 17 00:00:00 2001 From: Nakamura Hayato Date: Tue, 4 Jun 2013 16:48:57 +0900 Subject: [PATCH] Addition of the window animation interface. Change-Id: Ifacf3ac6748a2f87a90ced1258a182b05c09d9b6 Signed-off-by: Nakamura Hayato --- packaging/ico-uxf-weston-plugin.changes | 4 + packaging/ico-uxf-weston-plugin.spec | 2 +- protocol/ico_window_mgr.xml | 43 +++ protocol/xxx.xml | 100 ------ src/Makefile.am | 11 +- src/ico_ivi_shell.c | 183 ++++++++-- src/ico_ivi_shell.h | 6 +- src/ico_window_animation.c | 595 ++++++++++++++++++++++++++++++++ src/ico_window_mgr.c | 319 +++++++++++++---- src/ico_window_mgr.h | 66 ++++ tests/test-homescreen.c | 3 +- tests/testdata/hs_slide.dat | 18 + tests/weston-plugin-test.slide | 75 ++++ tests/weston_ivi_plugin.ini | 11 +- weston_ivi_plugin.ini | 8 +- 15 files changed, 1251 insertions(+), 193 deletions(-) delete mode 100644 protocol/xxx.xml create mode 100644 src/ico_window_animation.c create mode 100644 tests/testdata/hs_slide.dat create mode 100755 tests/weston-plugin-test.slide diff --git a/packaging/ico-uxf-weston-plugin.changes b/packaging/ico-uxf-weston-plugin.changes index 7b92590..db4e4de 100644 --- a/packaging/ico-uxf-weston-plugin.changes +++ b/packaging/ico-uxf-weston-plugin.changes @@ -1,3 +1,7 @@ +* Tue Jun 04 2013 Shibata Makoto accepted/2.0alpha-wayland/20130603.172729@9aedceb +- 0.5.04 release. +- Work around - Addition of the window animation interface and window animation plugin(ico_window_animation). + * Fri May 24 2013 Shibata Makoto accepted/2.0alpha-wayland/20130520.093312@6f0a9e8 - 0.5.03 release - Fix for TIVI-976 - Sometimes weston failed to be startup with 10% possibility. diff --git a/packaging/ico-uxf-weston-plugin.spec b/packaging/ico-uxf-weston-plugin.spec index 7bbda2a..cf778a6 100644 --- a/packaging/ico-uxf-weston-plugin.spec +++ b/packaging/ico-uxf-weston-plugin.spec @@ -1,6 +1,6 @@ Name: ico-uxf-weston-plugin Summary: Weston Plugins for IVI -Version: 0.5.03 +Version: 0.5.04 Release: 1.1 Group: System/GUI/Libraries License: MIT diff --git a/protocol/ico_window_mgr.xml b/protocol/ico_window_mgr.xml index b36b98f..24af317 100644 --- a/protocol/ico_window_mgr.xml +++ b/protocol/ico_window_mgr.xml @@ -5,6 +5,42 @@ for IVI HomeScreen interface. + + + Surface show/hide control define. + + + + + + + + + + + Surface raise/lower control define. + + + + + + + + + Set client application attribute. + + + + + + + Set animation for surface change. + + + + + + @@ -35,6 +71,7 @@ + @@ -48,6 +85,12 @@ + + + + + + diff --git a/protocol/xxx.xml b/protocol/xxx.xml deleted file mode 100644 index a0e1a4e..0000000 --- a/protocol/xxx.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - Order a correspondence charge account to the application of the input switch - to Multi Input Manager from HomeScreen. - - - - - Assign input switch to application from HomeScreen. - - - - - - - - - De-assign input switch to application from HomeScreen. - - - - - - - - - - Inform the switch name and number which there is for application, - and notify application of ON/OFF of the switch. - - - - - Set client application Id for RemoteUI - (currentry not support RemoteUI) - - - - - - - Send Input device and switch information to application - - - - - - - - - - Send Input switch event to application - - - - - - - - - - - An input controller informs attribute of the device and ON/OFF of the switch - to Multi Input Manager. - - - - - Input Controller type mask define. - - - - - - - - - - Define input switch from Input Controller - - - - - - - - - - Event of switch input from Input Controller - - - - - - - - - diff --git a/src/Makefile.am b/src/Makefile.am index c1e458d..784549f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -32,10 +32,9 @@ module_LTLIBRARIES = \ $(ico_ivi_common) \ $(ico_ivi_shell) \ $(ico_window_mgr) \ + $(ico_window_animation) \ $(ico_input_mgr) -# $(ico_input_mgr) - # Weston Plugin Loader ico_plugin_loader = ico_plugin_loader.la ico_plugin_loader_la_LDFLAGS = -module -avoid-version @@ -74,6 +73,14 @@ ico_window_mgr_la_SOURCES = \ ico_window_mgr.c \ ico_window_mgr-protocol.c \ ico_window_mgr-server-protocol.h +# +# Window Animation +ico_window_animation = ico_window_animation.la +ico_window_animation_la_LDFLAGS = -module -avoid-version +ico_window_animation_la_LIBADD = $(PLUGIN_LIBS) $(AUL_LIBS) +ico_window_animation_la_CFLAGS = $(GCC_CFLAGS) $(EXT_CFLAGS) $(PLUGIN_CFLAGS) +ico_window_animation_la_SOURCES = \ + ico_window_animation.c # Multi Input Manager ico_input_mgr = ico_input_mgr.la diff --git a/src/ico_ivi_shell.c b/src/ico_ivi_shell.c index 1621d3a..c5215f5 100644 --- a/src/ico_ivi_shell.c +++ b/src/ico_ivi_shell.c @@ -64,6 +64,8 @@ struct ivi_shell { struct ivi_layer_list ivi_layer; /* Layer list */ char win_animation[ICO_WINDOW_ANIMATION_LEN]; /* Default animation name */ + int win_animation_time; /* animation time(ms) */ + int win_animation_fps; /* animation frame rate(fps) */ int win_visible_on_create; /* Visible on create surface */ struct shell_surface *active_pointer_shsurf; /* Pointer active shell surface */ @@ -75,7 +77,10 @@ struct ivi_shell { enum shell_surface_type { SHELL_SURFACE_NONE, /* Surface type undefine */ SHELL_SURFACE_TOPLEVEL, /* Top level surface for application */ - SHELL_SURFACE_CHILD /* Child surface */ + SHELL_SURFACE_TRANSIENT, /* Child surface */ + SHELL_SURFACE_FULLSCREEN, /* Full screen surface */ + SHELL_SURFACE_MAXIMIZED, /* maximum screen */ + SHELL_SURFACE_POPUP /* pop up screen */ }; /* Shell surface table */ @@ -96,12 +101,21 @@ struct shell_surface { int geometry_y; int geometry_width; int geometry_height; - short visible; - short mapped; + char visible; + char mapped; + char noconfigure; + char restrain; struct ivi_layer_list *layer_list; struct wl_list ivi_layer; struct { + unsigned short x; + unsigned short y; + unsigned short width; + unsigned short height; + } configure_app; + + struct { struct weston_transform transform; struct weston_matrix rotation; } rotation; @@ -113,6 +127,7 @@ struct shell_surface { } transient; struct wl_list link; + struct wl_client *wclient; const struct weston_shell_client *client; }; @@ -153,9 +168,13 @@ shell_configuration(struct ivi_shell *shell) { int config_fd; char *win_animation = NULL; + int win_animation_time = 800; + int win_animation_fps = 15; struct config_key shell_keys[] = { { "animation", CONFIG_KEY_STRING, &win_animation }, + { "animation_time", CONFIG_KEY_INTEGER, &win_animation_time }, + { "animation_fps", CONFIG_KEY_INTEGER, &win_animation_fps }, { "visible_on_create", CONFIG_KEY_INTEGER, &shell->win_visible_on_create }, }; @@ -167,11 +186,17 @@ shell_configuration(struct ivi_shell *shell) parse_config_file(config_fd, cs, ARRAY_LENGTH(cs), shell); close(config_fd); - strncpy(shell->win_animation, win_animation, sizeof(shell->win_animation)-1); - - uifw_info("shell_configuration: Anima=%s Visible=%d Debug=%d", - shell->win_animation, shell->win_visible_on_create, - ico_ivi_debuglevel()); + if (win_animation) { + strncpy(shell->win_animation, win_animation, sizeof(shell->win_animation)-1); + } + if (win_animation_time < 100) win_animation_time = 100; + shell->win_animation_time = win_animation_time; + if (win_animation_fps > 30) win_animation_fps = 30; + if (win_animation_fps < 5) win_animation_fps = 5; + shell->win_animation_fps = win_animation_fps; + uifw_info("shell_configuration: Anima=%s,%dms,%dfps Visible=%d Debug=%d", + shell->win_animation, shell->win_animation_time, shell->win_animation_fps, + shell->win_visible_on_create, ico_ivi_debuglevel()); } /*--------------------------------------------------------------------------*/ @@ -191,6 +216,12 @@ send_configure(struct weston_surface *surface, { struct shell_surface *shsurf = get_shell_surface(surface); + uifw_trace("send_configure: %08x edges=%x w/h=%d/%d map=%d", + (int)shsurf->surface, edges, width, height, shsurf->mapped); + if (shsurf->mapped == 0) return; + + shsurf->configure_app.width = width; + shsurf->configure_app.height = height; wl_shell_surface_send_configure(&shsurf->resource, edges, width, height); } @@ -241,7 +272,7 @@ set_surface_type(struct shell_surface *shsurf) switch (shsurf->type) { case SHELL_SURFACE_TOPLEVEL: break; - case SHELL_SURFACE_CHILD: + case SHELL_SURFACE_TRANSIENT: psh = get_shell_surface(pes); if (psh) { shsurf->geometry_x = psh->geometry_x + shsurf->transient.x; @@ -288,7 +319,7 @@ static void shell_surface_move(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial) { - uifw_trace("shell_surface_move: NOP[%08x]", (int)resource->data); + uifw_trace("shell_surface_move: [%08x] NOP", (int)resource->data); } /*--------------------------------------------------------------------------*/ @@ -308,7 +339,7 @@ shell_surface_resize(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, uint32_t edges) { - uifw_trace("shell_surface_resize: NOP[%08x]", (int)resource->data); + uifw_trace("shell_surface_resize: [%08x] NOP", (int)resource->data); } /*--------------------------------------------------------------------------*/ @@ -366,7 +397,7 @@ set_transient(struct shell_surface *shsurf, shsurf->transient.x = x; shsurf->transient.y = y; shsurf->transient.flags = flags; - shsurf->next_type = SHELL_SURFACE_CHILD; + shsurf->next_type = SHELL_SURFACE_TRANSIENT; } /*--------------------------------------------------------------------------*/ @@ -390,6 +421,8 @@ shell_surface_set_transient(struct wl_client *client, struct wl_resource *resour struct shell_surface *shsurf = resource->data; struct weston_surface *parent = parent_resource->data; + uifw_trace("shell_surface_set_transient: Set Transient[%08x] surf=%08x", + (int)shsurf, (int)shsurf->surface); set_transient(shsurf, parent, x, y, flags); } @@ -413,7 +446,7 @@ shell_surface_set_fullscreen(struct wl_client *client, struct wl_resource *resou struct shell_surface *shsurf = resource->data; uifw_trace("shell_surface_set_fullscreen: " "NOP(same as set_toplevel)[%08x]", (int)shsurf); - set_toplevel(shsurf); + shsurf->next_type = SHELL_SURFACE_FULLSCREEN; } /*--------------------------------------------------------------------------*/ @@ -439,7 +472,7 @@ shell_surface_set_popup(struct wl_client *client, struct wl_resource *resource, { struct shell_surface *shsurf = resource->data; uifw_trace("shell_surface_set_popup: NOP(same as set_toplevel)[%08x]", (int)shsurf); - set_toplevel(shsurf); + shsurf->next_type = SHELL_SURFACE_POPUP; } /*--------------------------------------------------------------------------*/ @@ -458,7 +491,7 @@ shell_surface_set_maximized(struct wl_client *client, struct wl_resource *resour { struct shell_surface *shsurf = resource->data; uifw_trace("shell_surface_set_maximized: NOP(same as set_toplevel)[%08x]", (int)shsurf); - set_toplevel(shsurf); + shsurf->next_type = SHELL_SURFACE_MAXIMIZED; } /*--------------------------------------------------------------------------*/ @@ -509,6 +542,25 @@ shell_surface_set_class(struct wl_client *client, shsurf->class = strdup(class); } +/*--------------------------------------------------------------------------*/ +/** + * @brief shell_surface_raise: raise surface + * + * @param[in] client wayland client + * @param[in] resource set class request resource + * @return none + */ +/*--------------------------------------------------------------------------*/ +static void +shell_surface_raise(struct wl_client *client, struct wl_resource *resource) +{ + struct shell_surface *shsurf = resource->data; + + uifw_trace("shell_surface_raise: [%08x]", (int)shsurf); + + ivi_shell_set_raise(shsurf, 1); +} + static const struct wl_shell_surface_interface shell_surface_implementation = { shell_surface_pong, shell_surface_move, @@ -519,7 +571,8 @@ static const struct wl_shell_surface_interface shell_surface_implementation = { shell_surface_set_popup, shell_surface_set_maximized, shell_surface_set_title, - shell_surface_set_class + shell_surface_set_class, + shell_surface_raise }; /*--------------------------------------------------------------------------*/ @@ -701,6 +754,7 @@ create_shell_surface(void *shell, struct weston_surface *surface, shsurf->client = client; wl_list_init(&shsurf->ivi_layer); + return shsurf; } @@ -741,6 +795,7 @@ shell_get_shell_surface(struct wl_client *client, struct wl_resource *resource, return; } + shsurf->wclient = client; shsurf->resource.destroy = shell_destroy_shell_surface; shsurf->resource.object.id = id; shsurf->resource.object.interface = &wl_shell_surface_interface; @@ -861,7 +916,7 @@ map(struct ivi_shell *shell, struct weston_surface *surface, } switch (surface_type) { - case SHELL_SURFACE_CHILD: + case SHELL_SURFACE_TRANSIENT: parent = shsurf->parent; wl_list_insert(parent->layer_link.prev, &surface->layer_link); break; @@ -966,6 +1021,11 @@ shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy) uifw_trace("shell_surface_configure: Enter(surf=%08x out=%08x buf=%08x)", (int)es, (int)es->output, (int)es->buffer); + if (shsurf->restrain) { + uifw_trace("shell_surface_configure: Leave(restrain)"); + return; + } + if (shsurf->next_type != SHELL_SURFACE_NONE && shsurf->type != shsurf->next_type) { set_surface_type(shsurf); @@ -1352,15 +1412,78 @@ ivi_shell_set_active(struct shell_surface *shsurf, const int target) /*--------------------------------------------------------------------------*/ /** + * @brief ivi_shell_set_client_attr : set client ttribute + * + * @param[in] client target client + * @param[in] attr attribute + * @param[in] value attribute value + * @return none + */ +/*--------------------------------------------------------------------------*/ +WL_EXPORT void +ivi_shell_set_client_attr(struct wl_client *client, const int attr, const int value) +{ + struct shell_surface *es; + struct ivi_layer_list *el; + + uifw_trace("ivi_shell_set_client_attr: Enter(%08x,%d,%d)", (int)client, attr, value); + + wl_list_for_each (el, &default_shell->ivi_layer.link, link) { + wl_list_for_each (es, &el->surface_list, ivi_layer) { + if (es->wclient == client) { + switch(attr) { + case ICO_CLEINT_ATTR_NOCONFIGURE: + es->noconfigure = value; + uifw_trace("ivi_shell_set_client_attr: set surface %08x", (int)es); + break; + default: + break; + } + } + } + } + uifw_trace("ivi_shell_set_client_attr: Leave"); +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief ivi_shell_set_active: surface active control + * + * @param[in] shsurf shell surface(if NULL, no active surface) + * @param[in] restrain restrain(1)/not restrain(0) + * @return none + */ +/*--------------------------------------------------------------------------*/ +WL_EXPORT void +ivi_shell_restrain_configure(struct shell_surface *shsurf, const int restrain) +{ + uifw_trace("ivi_shell_restrain_configure: set %08x to %d", + (int)shsurf, restrain); + shsurf->restrain = restrain; + + if (restrain == 0) { + ivi_shell_restack_ivi_layer(shell_surface_get_shell(shsurf), shsurf); + } +} + +/*--------------------------------------------------------------------------*/ +/** * @brief ivi_shell_default_animation: window default animation * - * @param none + * @param[out] msec animation time(ms) + * @param[out] fps animation frame rate(fps) * @return default animation name */ /*--------------------------------------------------------------------------*/ WL_EXPORT const char * -ivi_shell_default_animation(void) +ivi_shell_default_animation(int *msec, int *fps) { + if (msec) { + *msec = default_shell->win_animation_time; + } + if (fps) { + *fps = default_shell->win_animation_fps; + } return default_shell->win_animation; } @@ -1628,11 +1751,27 @@ ivi_shell_send_configure(struct shell_surface *shsurf, const int id, const int edges, const int width, const int height) { /* send cgange event to manager */ - uifw_trace("ivi_shell_send_configure: (%08x) edges=%x w/h=%d/%d", - (int)shsurf->surface, edges, width, height); + uifw_trace("ivi_shell_send_configure: (%08x) edges=%x w/h=%d/%d map=%d", + (int)shsurf->surface, edges, width, height, shsurf->mapped); + shsurf->geometry_width = width; shsurf->geometry_height = height; - wl_shell_surface_send_configure(&shsurf->resource, edges, width, height); + + if ((shsurf->mapped == 0) || (shsurf->noconfigure != 0) || + (width == 0) || (height == 0)) { + return; + } + + /* send cgange event to application */ + uifw_trace("ivi_shell_send_configure: Send (%08x) w/h=%d/%d(old=%d/%d)", + (int)shsurf->surface, width, height, + shsurf->configure_app.width, shsurf->configure_app.height); + shsurf->configure_app.width = width; + shsurf->configure_app.height = height; + + wl_shell_surface_send_configure(&shsurf->resource, + WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT, + width, height); } /*--------------------------------------------------------------------------*/ diff --git a/src/ico_ivi_shell.h b/src/ico_ivi_shell.h index 15e6772..2a8b07d 100644 --- a/src/ico_ivi_shell.h +++ b/src/ico_ivi_shell.h @@ -36,6 +36,8 @@ struct shell_surface; #define ICO_WINDOW_ANIMATION_LEN 20 /* length of window animation name */ /* option flag */ #define ICO_OPTION_FLAG_UNVISIBLE 0x00000001 /* unvisible control */ +/* client attribute */ +#define ICO_CLEINT_ATTR_NOCONFIGURE 0 /* client no need configure event */ /* Prototype for get/set function */ void ivi_shell_set_layer(struct shell_surface *shsurf, const int layer); @@ -52,7 +54,9 @@ void ivi_shell_set_layer_visible(const int layer, const int visible); void ivi_shell_surface_configure(struct shell_surface *shsurf, const int x, const int y, const int width, const int height); void ivi_shell_set_active(struct shell_surface *shsurf, const int target); -const char *ivi_shell_default_animation(void); +void ivi_shell_set_client_attr(struct wl_client *client, const int attr, const int value); +void ivi_shell_restrain_configure(struct shell_surface *shsurf, const int restrain); +const char *ivi_shell_default_animation(int *msec, int *fps); /* Prototypr for hook routine */ void ivi_shell_hook_bind(void (*hook_bind)(struct wl_client *client)); diff --git a/src/ico_window_animation.c b/src/ico_window_animation.c new file mode 100644 index 0000000..8b3960f --- /dev/null +++ b/src/ico_window_animation.c @@ -0,0 +1,595 @@ +/* + * Copyright © 2010-2011 Intel Corporation + * Copyright © 2008-2011 Kristian Høgsberg + * Copyright © 2013 TOYOTA MOTOR 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. + */ +/** + * @brief Window Animation (Weston(Wayland) PlugIn) + * + * @date May-29-2013 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "ico_ivi_common.h" +#include "ico_ivi_shell.h" +#include "ico_window_mgr.h" + +/* Animation type */ +#define ANIMA_ZOOM 1 /* ZoomIn/ZoomOut */ +#define ANIMA_FADE 2 /* FadeIn/FadeOut */ +#define ANIMA_SLIDE_TORIGHT 3 /* SlideIn left to right/SlideOut right to left*/ +#define ANIMA_SLIDE_TOLEFT 4 /* SlideIn right to left/SlideOut left to right*/ +#define ANIMA_SLIDE_TOBOTTOM 5 /* SlideIn top to bottom/SlideOut bottom to top*/ +#define ANIMA_SLIDE_TOTOP 6 /* SlideIn bottom to top/SlideOut top to bottom*/ + +/* Visible control at end of animation */ +#define ANIMA_NOCONTROL_AT_END 0 /* no need surface show/hide at end of animation*/ +#define ANIMA_SHOW_AT_END 1 /* surface show at end of animation */ +#define ANIMA_HIDE_AT_END 2 /* surface hide at end of animation */ + +/* animation data */ +struct animation_data { + struct animation_data *next_free; /* free data list */ + int x; /* original X coordinate */ + int y; /* original Y coordinate */ + int width; /* original width */ + int height; /* original height */ + char geometry_saved; /* need geometry restor at end */ + char res[3]; /* (unused) */ + struct weston_transform transform; /* transform matrix */ +}; + +/* static valiables */ +static struct weston_compositor *weston_ec; /* Weston compositor */ +static char *default_animation; /* default animation name */ +static int animation_time; /* animation time(ms) */ +static int animation_fpar; /* animation frame parcent(%) */ +static struct animation_data *free_data; /* free data list */ + +/* static function */ + /* slide animation */ +static void animation_slide(struct weston_animation *animation, + struct weston_output *output, uint32_t msecs); + /* fade animation */ +static void animation_fade(struct weston_animation *animation, + struct weston_output *output, uint32_t msecs); + /* continue animation */ +static int animation_cont(struct weston_animation *animation, + struct weston_output *output, uint32_t msecs); + /* terminate animation */ +static void animation_end(struct uifw_win_surface *usurf, const int disp); + +/*--------------------------------------------------------------------------*/ +/** + * @brief ico_window_animation: Animation addin entry + * + * @param[in] op animation operation + * @param[in] data data + * @return result + * @retval ICO_WINDOW_MGR_ANIMATION_RET_ANIMA success + * @retval ICO_WINDOW_MGR_ANIMATION_RET_ANIMASHOW success(force visible) + * @retval ICO_WINDOW_MGR_ANIMATION_RET_NOANIMA error(no animation) + */ +/*--------------------------------------------------------------------------*/ +static int +ico_window_animation(const int op, void *data) +{ + struct uifw_win_surface *usurf; + struct weston_output *output; + int ret; + uint32_t nowsec; + struct timeval nowtv; + + if (op == ICO_WINDOW_MGR_ANIMATION_TYPE) { + /* convert animation name to animation type value */ + if (strcasecmp((char *)data, "fade") == 0) { + uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_FADE); + return ANIMA_FADE; + } + else if (strcasecmp((char *)data, "zoom") == 0) { + uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_ZOOM); + return ANIMA_ZOOM; + } + else if (strcasecmp((char *)data, "slide.toleft") == 0) { + uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_SLIDE_TOLEFT); + return ANIMA_SLIDE_TOLEFT; + } + else if (strcasecmp((char *)data, "slide.toright") == 0) { + uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_SLIDE_TORIGHT); + return ANIMA_SLIDE_TORIGHT; + } + else if (strcasecmp((char *)data, "slide.totop") == 0) { + uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_SLIDE_TOTOP); + return ANIMA_SLIDE_TOTOP; + } + else if (strcasecmp((char *)data, "slide.tobottom") == 0) { + uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_SLIDE_TOBOTTOM); + return ANIMA_SLIDE_TOBOTTOM; + } + uifw_warn("ico_window_animation: Unknown Type %s", (char *)data); + return ICO_WINDOW_MGR_ANIMATION_RET_NOANIMA; + } + + usurf = (struct uifw_win_surface *)data; + + if (op == ICO_WINDOW_MGR_ANIMATION_DESTROY) { + if ((usurf->animation.state != ICO_WINDOW_MGR_ANIMATION_STATE_NONE) || + (usurf->animadata != NULL)) { + uifw_trace("ico_window_animation: Destroy %08x", (int)usurf); + animation_end(usurf, 0); + } + return ICO_WINDOW_MGR_ANIMATION_RET_NOANIMA; + } + if (op == ICO_WINDOW_MGR_ANIMATION_OPCANCEL) { + /* cancel animation */ + if ((usurf->animation.state != ICO_WINDOW_MGR_ANIMATION_STATE_NONE) && + (usurf->animation.animation.frame != NULL)) { + uifw_trace("ico_window_animation: cancel %s.%08x", + usurf->uclient->appid, usurf->id); + (*usurf->animation.animation.frame)(&usurf->animation.animation, NULL, 0); + } + animation_end(usurf, 1); + ret = ICO_WINDOW_MGR_ANIMATION_RET_ANIMA; + } + else { + /* setup animation */ + if ((usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_NONE) || + (usurf->animation.current > 95)) { + usurf->animation.animation.frame_counter = 1; + usurf->animation.current = 0; + wl_list_init(&usurf->animation.animation.link); + output = container_of(weston_ec->output_list.next, + struct weston_output, link); + wl_list_insert(output->animation_list.prev, &usurf->animation.animation.link); + } + else if (((usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) && + (op == ICO_WINDOW_MGR_ANIMATION_OPOUT)) || + ((usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_OUT) && + (op == ICO_WINDOW_MGR_ANIMATION_OPIN))) { + gettimeofday(&nowtv, NULL); + nowsec = (uint32_t)(((long long)nowtv.tv_sec) * 1000L + + ((long long)nowtv.tv_usec) / 1000L); + usurf->animation.current = 100 - usurf->animation.current; + ret = ((usurf->animation.current) * animation_time) / 100; + if (nowsec >= (uint32_t)ret) { + usurf->animation.starttime = nowsec - ret; + } + else { + usurf->animation.starttime = ((long long)nowsec) + ((long long)0x100000000L) + - ((long long)ret); + } + usurf->animation.animation.frame_counter = 2; + } + + /* set animation function */ + if (op == ICO_WINDOW_MGR_ANIMATION_OPIN) { + usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_IN; + uifw_trace("ico_window_animation: show(in) %s.%08x", + usurf->uclient->appid, usurf->id); + ret = ICO_WINDOW_MGR_ANIMATION_RET_ANIMA; + } + else { + usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_OUT; + uifw_trace("ico_window_animation: hide(out) %s.%08x", + usurf->uclient->appid, usurf->id); + ret = ICO_WINDOW_MGR_ANIMATION_RET_ANIMASHOW; + } + if ((usurf->animation.type == ANIMA_SLIDE_TOLEFT) || + (usurf->animation.type == ANIMA_SLIDE_TORIGHT) || + (usurf->animation.type == ANIMA_SLIDE_TOTOP) || + (usurf->animation.type == ANIMA_SLIDE_TOBOTTOM)) { + usurf->animation.animation.frame = animation_slide; + ivi_shell_restrain_configure(usurf->shsurf, 1); + (*usurf->animation.animation.frame)(&usurf->animation.animation, NULL, 1); + } + else if (usurf->animation.type == ANIMA_FADE) { + usurf->animation.animation.frame = animation_fade; + ivi_shell_restrain_configure(usurf->shsurf, 1); + (*usurf->animation.animation.frame)(&usurf->animation.animation, NULL, 1); + } + else { + /* no yet support */ + usurf->animation.animation.frame = NULL; + usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_NONE; + ivi_shell_restrain_configure(usurf->shsurf, 0); + wl_list_remove(&usurf->animation.animation.link); + ret = ICO_WINDOW_MGR_ANIMATION_RET_NOANIMA; + } + } + if (ret == ICO_WINDOW_MGR_ANIMATION_RET_ANIMASHOW) { + usurf->animation.visible = ANIMA_HIDE_AT_END; + } + else { + usurf->animation.visible = ANIMA_NOCONTROL_AT_END; + } + weston_compositor_schedule_repaint(weston_ec); + return ret; +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief animation_cont: continue animation + * + * @param[in] animation weston animation table + * @param[in] output weston output table + * @param[in] msecs current time stamp + * @return time has come + * @retval =0 time has come + * @retval >0 time has not yet come(return value is current parcent) + */ +/*--------------------------------------------------------------------------*/ +static int +animation_cont(struct weston_animation *animation, struct weston_output *output, + uint32_t msecs) +{ + struct uifw_win_surface *usurf; + struct animation_data *animadata; + int par; + uint32_t nowsec; + struct timeval nowtv; + + gettimeofday(&nowtv, NULL); + nowsec = (uint32_t)(((long long)nowtv.tv_sec) * 1000L + + ((long long)nowtv.tv_usec) / 1000L); + + usurf = container_of(animation, struct uifw_win_surface, animation.animation); + + if (animation->frame_counter <= 1) { + /* first call, initialize */ + animation->frame_counter = 1; + usurf->animation.starttime = nowsec; + usurf->animation.current = 1000; + if (! usurf->animadata) { + if (free_data) { + usurf->animadata = (void *)free_data; + free_data = free_data->next_free; + } + else { + usurf->animadata = (void *)malloc(sizeof(struct animation_data)); + } + memset(usurf->animadata, 0, sizeof(struct animation_data)); + } + animadata = (struct animation_data *)usurf->animadata; + animadata->x = usurf->x; + animadata->y = usurf->y; + animadata->width = usurf->width; + animadata->height = usurf->height; + animadata->geometry_saved = 1; + weston_matrix_init(&animadata->transform.matrix); + wl_list_init(&animadata->transform.link); + } + else if (! usurf->animadata) { + animation_end(usurf, 0); + return 999; + } + + if (nowsec >= usurf->animation.starttime) { + nowsec = nowsec - usurf->animation.starttime; /* elapsed time(ms) */ + } + else { + nowsec = (uint32_t)(((long long)0x100000000L) + + ((long long)nowsec) - ((long long)usurf->animation.starttime)); + } + if (((output == NULL) && (msecs == 0)) || (nowsec >= ((uint32_t)animation_time))) { + par = 100; + } + else { + par = (nowsec * 100 + animation_time / 2) / animation_time; + if (par < 2) par = 2; + } + if ((par >= 100) || + (abs(usurf->animation.current - par) >= animation_fpar)) { + usurf->animation.current = par; + return 0; + } + return par; +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief animation_end: terminate animation + * + * @param[in] usurf UIFW surface table + * @param[in] disp display control(1)/no display(0) + * @return none + */ +/*--------------------------------------------------------------------------*/ +static void +animation_end(struct uifw_win_surface *usurf, const int disp) +{ + struct animation_data *animadata; + + usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_NONE; + animadata = (struct animation_data *)usurf->animadata; + + if (animadata) { + if (animadata->geometry_saved > 1) { + usurf->x = animadata->x; + usurf->y = animadata->y; + usurf->width = animadata->width; + usurf->height = animadata->height; + animadata->geometry_saved = 0; + } + wl_list_remove(&usurf->animation.animation.link); + wl_list_init(&usurf->animation.animation.link); + } + if (disp) { + if ((usurf->animation.visible == ANIMA_HIDE_AT_END) && + (ivi_shell_is_visible(usurf->shsurf))) { + ivi_shell_set_visible(usurf->shsurf, 0); + weston_surface_damage_below(usurf->surface); + weston_surface_damage(usurf->surface); + weston_compositor_schedule_repaint(weston_ec); + } + if ((usurf->animation.visible == ANIMA_SHOW_AT_END) && + (! ivi_shell_is_visible(usurf->shsurf))) { + ivi_shell_set_visible(usurf->shsurf, 1); + weston_surface_damage_below(usurf->surface); + weston_surface_damage(usurf->surface); + weston_compositor_schedule_repaint(weston_ec); + } + ivi_shell_restrain_configure(usurf->shsurf, 0); + } + usurf->animation.visible = ANIMA_NOCONTROL_AT_END; + usurf->animation.type = usurf->animation.type_next; + if (animadata) { + usurf->animadata = NULL; + animadata->next_free = free_data; + free_data = animadata; + } +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief animation_slide: slide animation + * + * @param[in] animation weston animation table + * @param[in] outout weston output table + * @param[in] mseces current time(unused) + * @return none + */ +/*--------------------------------------------------------------------------*/ +static void +animation_slide(struct weston_animation *animation, + struct weston_output *output, uint32_t msecs) +{ + struct uifw_win_surface *usurf; + struct animation_data *animadata; + struct weston_surface *es; + int dwidth, dheight; + int par; + + usurf = container_of(animation, struct uifw_win_surface, animation.animation); + + par = animation_cont(animation, output, msecs); + if (par > 0) { + uifw_trace("animation_slide: usurf=%08x count=%d %d%% skip", + (int)usurf, animation->frame_counter, par); + /* continue animation */ + if( par <= 100) { + weston_compositor_schedule_repaint(weston_ec); + } + return; + } + par = usurf->animation.current; + animadata = (struct animation_data *)usurf->animadata; + + uifw_trace("animation_slide: usurf=%08x count=%d %d%% type=%d state=%d", + (int)usurf, animation->frame_counter, par, + usurf->animation.type, usurf->animation.state); + + es = usurf->surface; + + switch (usurf->animation.type) { + case ANIMA_SLIDE_TORIGHT: /* slide in left to right */ + if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) { + /* slide in left to right */ + usurf->x = 0 - ((animadata->x + animadata->width) * (100 - par) / 100); + } + else { + /* slide out right to left */ + usurf->x = 0 - ((animadata->x + animadata->width) * par / 100); + } + break; + case ANIMA_SLIDE_TOLEFT: /* slide in right to left */ + dwidth = (container_of(weston_ec->output_list.next, + struct weston_output, link))->width; + if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) { + /* slide in right to left */ + usurf->x = animadata->x + (dwidth - animadata->x) * (100 - par) / 100; + } + else { + /* slide out left to right */ + usurf->x = animadata->x + (dwidth - animadata->x) * par / 100; + } + break; + case ANIMA_SLIDE_TOBOTTOM: /* slide in top to bottom */ + if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) { + /* slide in top to bottom */ + usurf->y = 0 - ((animadata->y + animadata->height) * (100 - par) / 100); + } + else { + /* slide out bottom to top */ + usurf->y = 0 - ((animadata->y + animadata->height) * par / 100); + } + break; + default: /*ANIMA_SLIDE_TOTOP*/ /* slide in bottom to top */ + dheight = (container_of(weston_ec->output_list.next, + struct weston_output, link))->height; + if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) { + /* slide in bottom to top */ + usurf->y = animadata->y + (dheight - animadata->y) * (100 - par) / 100; + } + else { + /* slide out top to bottom */ + usurf->y = animadata->y + (dheight - animadata->y) * par / 100; + } + break; + } + + es->geometry.x = usurf->x; + es->geometry.y = usurf->y; + ivi_shell_set_positionsize(usurf->shsurf, + usurf->x, usurf->y, usurf->width, usurf->height); + if ((es->output) && (es->buffer) && + (es->geometry.width > 0) && (es->geometry.height > 0)) { + weston_surface_damage_below(es); + weston_surface_damage(es); + } + if (par >= 100) { + /* end of animation */ + animadata->geometry_saved ++; /* restore geometry */ + animation_end(usurf, 1); + uifw_trace("animation_slide: End of animation"); + } + else { + /* continue animation */ + weston_compositor_schedule_repaint(weston_ec); + } +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief animation_fade: fade animation + * + * @param[in] animation weston animation table + * @param[in] outout weston output table + * @param[in] mseces current time(unused) + * @return none + */ +/*--------------------------------------------------------------------------*/ +static void +animation_fade(struct weston_animation *animation, + struct weston_output *output, uint32_t msecs) +{ + struct uifw_win_surface *usurf; + struct animation_data *animadata; + struct weston_surface *es; + int par; + + usurf = container_of(animation, struct uifw_win_surface, animation.animation); + + par = animation_cont(animation, output, msecs); + if (par > 0) { + uifw_trace("animation_fade: usurf=%08x count=%d %d%% skip", + (int)usurf, animation->frame_counter, par); + /* continue animation */ + if( par <= 100) { + weston_compositor_schedule_repaint(weston_ec); + } + return; + } + + animadata = (struct animation_data *)usurf->animadata; + es = usurf->surface; + par = usurf->animation.current; + if (animation->frame_counter == 1) { + wl_list_insert(&es->geometry.transformation_list, + &animadata->transform.link); + } + + uifw_trace("animation_fade: usurf=%08x count=%d %d%% type=%d state=%d", + (int)usurf, animation->frame_counter, par, + usurf->animation.type, usurf->animation.state); + + + if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) { + /* fade in */ + es->alpha = ((double)par) / ((double)100.0); + } + else { + /* fade out */ + es->alpha = ((double)1.0) - ((double)par) / ((double)100.0); + } + if (es->alpha < 0.0) es->alpha = 0.0; + else if (es->alpha > 1.0) es->alpha = 1.0; + + if ((es->output) && (es->buffer) && + (es->geometry.width > 0) && (es->geometry.height > 0)) { + weston_surface_damage_below(es); + weston_surface_damage(es); + } + if (par >= 100) { + /* end of animation */ + wl_list_remove(&animadata->transform.link); + animation_end(usurf, 1); + uifw_trace("animation_fade: End of animation"); + } + else { + /* continue animation */ + weston_compositor_schedule_repaint(weston_ec); + } +} + +/*--------------------------------------------------------------------------*/ +/** + * @brief module_init: initialize ico_window_animation + * this function called from ico_pluign_loader + * + * @param[in] es weston compositor + * @return result + * @retval 0 sccess + * @retval -1 error + */ +/*--------------------------------------------------------------------------*/ +WL_EXPORT int +module_init(struct weston_compositor *ec) +{ + int i; + struct animation_data *animadata; + + uifw_info("ico_window_animation: Enter(module_init)"); + + /* allocate animation datas */ + free_data = NULL; + for (i = 0; i < 50; i++) { + animadata = (struct animation_data *)malloc(sizeof(struct animation_data)); + if (! animadata) { + uifw_error("ico_window_animation: No Memory(module_init)"); + return -1; + } + animadata->next_free = free_data; + free_data = animadata; + } + + weston_ec = ec; + default_animation = (char *)ivi_shell_default_animation(&animation_time, + &animation_fpar); + animation_fpar = ((1000 * 100) / animation_fpar) / animation_time; + + ico_window_mgr_set_animation(ico_window_animation); + + uifw_info("ico_window_animation: Leave(module_init)"); + + return 0; +} + diff --git a/src/ico_window_mgr.c b/src/ico_window_mgr.c index ac8ce1e..8fa5065 100644 --- a/src/ico_window_mgr.c +++ b/src/ico_window_mgr.c @@ -59,35 +59,18 @@ #define SURCAFE_ID_MASK 0x0ffff /* SurfaceId bit mask pattern */ #define UIFW_HASH 64 /* Hash value (2's compliment) */ -/* Cleint management table */ -struct uifw_client { - struct wl_client *client; /* Wayland client */ - int pid; /* ProcessId (pid) */ - char appid[ICO_IVI_APPID_LENGTH]; /* ApplicationId(from AppCore AUL) */ - int manager; /* Manager flag (Need send event) */ - struct wl_resource *resource; +/* Client attribute table */ +#define MAX_CLIENT_ATTR 4 +struct uifw_client_attr { + char appid[ICO_IVI_APPID_LENGTH]; /* ApplicationId */ + struct _uifw_client_attr_value { + short attr; + short res; + int value; + } attrs[MAX_CLIENT_ATTR]; struct wl_list link; }; -/* UIFW Surface */ -struct shell_surface; -struct uifw_win_surface { - uint32_t id; /* UIFW SurfaceId */ - int layer; /* LayerId */ - struct weston_surface *surface; /* Weston surface */ - struct shell_surface *shsurf; /* Shell(IVI-Shell) surface */ - struct uifw_client *uclient; /* Client */ - int x; /* X-axis */ - int y; /* Y-axis */ - int width; /* Width */ - int height; /* Height */ - char animation[ICO_WINDOW_ANIMATION_LEN]; - /* Animation name */ - struct wl_list link; /* */ - struct uifw_win_surface *next_idhash; /* UIFW SurfaceId hash list */ - struct uifw_win_surface *next_wshash; /* Weston SurfaceId hash list */ -}; - /* Manager table */ struct uifw_manager { struct wl_resource *resource; /* Manager resource */ @@ -104,6 +87,7 @@ struct ico_win_mgr { struct wl_list manager_list; /* Manager(ex.HomeScreen) list */ int num_manager; /* Number of managers */ struct wl_list surface_list; /* Surface list */ + struct wl_list client_attr_list; /* Client attribute list */ struct uifw_win_surface *active_pointer_surface; /* Active Pointer Surface */ struct uifw_win_surface *active_keyboard_surface; /* Active Keyboard Surface */ @@ -163,7 +147,7 @@ static void uifw_set_visible(struct wl_client *client, struct wl_resource *resou uint32_t surfaceid, int32_t visible, int32_t raise); /* set surface animation */ static void uifw_set_animation(struct wl_client *client, struct wl_resource *resource, - uint32_t surfaceid, const char *animation); + uint32_t surfaceid, int32_t change, const char *animation); /* set active surface (form HomeScreen) */ static void uifw_set_active(struct wl_client *client, struct wl_resource *resource, uint32_t surfaceid, uint32_t target); @@ -171,6 +155,9 @@ static void uifw_set_active(struct wl_client *client, struct wl_resource *resour static void uifw_set_layer_visible(struct wl_client *client, struct wl_resource *resource, int32_t layer, int32_t visible); /* send surface change event to manager */ +static void uifw_set_client_attr(struct wl_client *client, struct wl_resource *resource, + const char *appid, int32_t attr, int32_t value); + /* set client application attribute */ static void win_mgr_surface_change(struct weston_surface *surface, const int to, const int manager); /* surface change from manager */ @@ -190,6 +177,8 @@ static int ico_win_mgr_send_to_mgr(const int event, const int surfaceid, const char *appid, const int param1, const int param2, const int param3, const int param4, const int param5, const int param6); + /* convert animation name to type value */ +static int ico_get_animation_type(const char *animation); /* hook for set user */ static void (*win_mgr_hook_set_user) (struct wl_client *client, const char *appid) = NULL; @@ -199,6 +188,8 @@ static void (*win_mgr_hook_create) int surfaceId, const char *appid) = NULL; /* hook for surface destory */ static void (*win_mgr_hook_destroy)(struct weston_surface *surface) = NULL; + /* hook for animation */ +static int (*win_mgr_hook_animation)(const int op, void *data) = NULL; /* static tables */ /* Multi Window Manager interface */ @@ -210,7 +201,8 @@ static const struct ico_window_mgr_interface ico_window_mgr_implementation = { uifw_set_visible, uifw_set_animation, uifw_set_active, - uifw_set_layer_visible + uifw_set_layer_visible, + uifw_set_client_attr }; /* static management table */ @@ -404,6 +396,7 @@ static void bind_shell_client(struct wl_client *client) { struct uifw_client *uclient; + struct uifw_client_attr *lattr; pid_t pid; uid_t uid; gid_t gid; @@ -490,6 +483,25 @@ bind_shell_client(struct wl_client *client) sprintf(uclient->appid, "?%d?", uclient->pid); } } + + wl_list_for_each (lattr, &_ico_win_mgr->client_attr_list, link) { + if (strcmp(lattr->appid, uclient->appid) == 0) { + for (i = 0; i < MAX_CLIENT_ATTR; i++) { + switch (lattr->attrs[i].attr) { + case ICO_WINDOW_MGR_CLIENT_ATTR_NOCONFIGURE: + uclient->noconfigure = lattr->attrs[i].value; + ivi_shell_set_client_attr(uclient->client, + ICO_CLEINT_ATTR_NOCONFIGURE, + lattr->attrs[i].value); + uifw_trace("bind_shell_client: set to ivi-shell"); + break; + default: + break; + } + } + break; + } + } } else { uifw_trace("bind_shell_client: client=%08x pid dose not exist", (int)client); @@ -523,6 +535,32 @@ unbind_shell_client(struct wl_client *client) /*--------------------------------------------------------------------------*/ /** + * @brief ico_get_animation_type: convert animation name to type value + * + * @param[in] animation animation name + * @return animation type value + */ +/*--------------------------------------------------------------------------*/ +static int +ico_get_animation_type(const char *animation) +{ + int anima = ICO_WINDOW_MGR_ANIMATION_NONE; + + if (strcasecmp(animation, "none") == 0) { + return ICO_WINDOW_MGR_ANIMATION_NONE; + } + + if (win_mgr_hook_animation) { + anima = (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_TYPE, (void *)animation); + } + if (anima <= 0) { + anima = ICO_WINDOW_MGR_ANIMATION_NONE; + } + return anima; +} + +/*--------------------------------------------------------------------------*/ +/** * @brief client_register_surface: create UIFW surface * * @param[in] client Wayland client @@ -539,7 +577,9 @@ client_register_surface(struct wl_client *client, struct wl_resource *resource, struct uifw_win_surface *us; struct uifw_win_surface *phash; struct uifw_win_surface *bhash; + struct uifw_client_attr *lattr; uint32_t hash; + int i; uifw_trace("client_register_surface: Enter(surf=%08x,client=%08x,res=%08x)", (int)surface, (int)client, (int)resource); @@ -563,7 +603,9 @@ client_register_surface(struct wl_client *client, struct wl_resource *resource, us->id = generate_id(); us->surface = surface; us->shsurf = shsurf; - strncpy(us->animation, ivi_shell_default_animation(), sizeof(us->animation)-1); + wl_list_init(&us->animation.animation.link); + us->animation.type = ico_get_animation_type(ivi_shell_default_animation(NULL, NULL)); + us->animation.type_next = us->animation.type; if (_ico_win_mgr->num_manager <= 0) { uifw_trace("client_register_surface: No Manager, Force visible"); @@ -620,12 +662,33 @@ client_register_surface(struct wl_client *client, struct wl_resource *resource, /* set default layer id */ ivi_shell_set_layer(shsurf, 0); + /* set client attribute */ + wl_list_for_each (lattr, &_ico_win_mgr->client_attr_list, link) { + if (strcmp(lattr->appid, us->uclient->appid) == 0) { + for (i = 0; i < MAX_CLIENT_ATTR; i++) { + switch (lattr->attrs[i].attr) { + case ICO_WINDOW_MGR_CLIENT_ATTR_NOCONFIGURE: + us->uclient->noconfigure = lattr->attrs[i].value; + ivi_shell_set_client_attr(us->uclient->client, + ICO_CLEINT_ATTR_NOCONFIGURE, + lattr->attrs[i].value); + uifw_trace("client_register_surface: set attr(%d=%d) to %08x", + lattr->attrs[i].attr, lattr->attrs[i].value, us->id); + break; + default: + break; + } + } + break; + } + } + /* send event to manager */ ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_CREATED, us->id, us->uclient->appid, us->uclient->pid, 0,0,0,0,0); if (win_mgr_hook_create) { - /* call surface create hook for ico_window_mgr */ + /* call surface create hook for other plugin */ (void) (*win_mgr_hook_create)(client, surface, us->id, us->uclient->appid); } uifw_trace("client_register_surface: Leave(surfaceId=%08x)", us->id); @@ -912,6 +975,16 @@ uifw_set_positionsize(struct wl_client *client, struct wl_resource *resource, if (width > ICO_IVI_MAX_COORDINATE) width = usurf->width; if (height > ICO_IVI_MAX_COORDINATE) height = usurf->height; + /* check animation */ + if ((usurf->animation.type != ICO_WINDOW_MGR_ANIMATION_NONE) && + (usurf->animation.state != ICO_WINDOW_MGR_ANIMATION_STATE_NONE) && + (win_mgr_hook_animation != NULL) && + (x == usurf->x) && (y == usurf->y) && + (width == usurf->width) && (height == usurf->height)) { + uifw_trace("uifw_set_positionsize: Leave(same position size at animation)"); + return; + } + uclient = find_client_from_client(client); if (uclient) { if (! uclient->manager) uclient = NULL; @@ -980,6 +1053,7 @@ uifw_set_visible(struct wl_client *client, struct wl_resource *resource, { struct uifw_win_surface* usurf; struct uifw_client *uclient; + int animation; uifw_trace("uifw_set_visible: Enter(surf=%08x,%d,%d)", surfaceid, visible, raise); @@ -1005,7 +1079,8 @@ uifw_set_visible(struct wl_client *client, struct wl_resource *resource, return; } - if (visible == 1) { + if ((visible == ICO_WINDOW_MGR_VISIBLE_SHOW) || + (visible == ICO_WINDOW_MGR_VISIBLE_SHOW_WO_ANIMATION)) { if ((usurf->width <= 0) || (usurf->height <= 0)) { /* not declare surface geometry, initialize */ usurf->width = usurf->surface->geometry.width; @@ -1027,48 +1102,57 @@ uifw_set_visible(struct wl_client *client, struct wl_resource *resource, usurf->width, usurf->height); uifw_set_weston_surface(usurf); ivi_shell_set_surface_type(usurf->shsurf); + + if ((visible == ICO_WINDOW_MGR_VISIBLE_SHOW) && + (usurf->animation.type != ICO_WINDOW_MGR_ANIMATION_NONE) && + (win_mgr_hook_animation != NULL)) { + animation = (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_OPIN, + (void *)usurf); + } } - else if ((raise != 0) && (raise != 1)) { + else if ((raise != ICO_WINDOW_MGR_RAISE_LOWER) && + (raise != ICO_WINDOW_MGR_RAISE_RAISE)) { uifw_trace("uifw_set_visible: Leave(No Change)"); return; } -#if 0 /* the animation function does not yet support it */ - if (strcasecmp(usurf->animation, "fade") == 0) { - uifw_trace("uifw_set_visible: start animation fade(%08x)", (int)usurf->surface); - weston_fade_run(usurf->surface, NULL, NULL); - } - else if (strcasecmp(usurf->animation, "zoom") == 0) { - uifw_trace("uifw_set_visible: start animation zoom(%08x)", (int)usurf->surface); - weston_zoom_run(usurf->surface, 0.8, 1.0, NULL, NULL); - } - else if (strcasecmp(usurf->animation, "slide") == 0) { - uifw_trace("uifw_set_visible: start animation slide(%08x)", (int)usurf->surface); - weston_slide_run(usurf->surface, (float)usurf->surface->geometry.height, - 0.0, NULL, NULL); - } -#endif /* the animation function does not yet support it */ } - else if (visible == 0) { + else if ((visible == ICO_WINDOW_MGR_VISIBLE_HIDE) || + (visible == ICO_WINDOW_MGR_VISIBLE_HIDE_WO_ANIMATION)) { if (ivi_shell_is_visible(usurf->shsurf)) { - ivi_shell_set_visible(usurf->shsurf, 0); - uifw_trace("uifw_set_visible: Change to UnVisible"); /* Weston surface configure */ uifw_set_weston_surface(usurf); + + animation = ICO_WINDOW_MGR_ANIMATION_RET_ANIMA; + if ((visible == ICO_WINDOW_MGR_VISIBLE_HIDE) && + (usurf->animation.type > 0) && + (win_mgr_hook_animation != NULL)) { + animation = (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_OPOUT, + (void *)usurf); + } + if (animation != ICO_WINDOW_MGR_ANIMATION_RET_ANIMASHOW) { + ivi_shell_set_visible(usurf->shsurf, 0); + uifw_trace("uifw_set_visible: Change to UnVisible"); + } + else { + uifw_trace("uifw_set_visible: UnVisible but animation"); + } } - else if ((raise != 0) && (raise != 1)) { + else if ((raise != ICO_WINDOW_MGR_RAISE_LOWER) && + (raise != ICO_WINDOW_MGR_RAISE_RAISE)) { uifw_trace("uifw_set_visible: Leave(No Change)"); return; } } - else if ((raise != 0) && (raise != 1)) { + else if ((raise != ICO_WINDOW_MGR_RAISE_LOWER) && + (raise != ICO_WINDOW_MGR_RAISE_RAISE)) { uifw_trace("uifw_set_visible: Leave(No Change)"); return; } /* raise/lower */ - if ((raise == 1) || (raise == 0)) { + if ((raise == ICO_WINDOW_MGR_RAISE_LOWER) || (raise != ICO_WINDOW_MGR_RAISE_RAISE)) { ivi_shell_set_raise(usurf->shsurf, raise); } @@ -1079,7 +1163,13 @@ uifw_set_visible(struct wl_client *client, struct wl_resource *resource, } /* send event(VISIBLE) to manager */ ico_win_mgr_send_to_mgr(ICO_WINDOW_MGR_WINDOW_VISIBLE, - surfaceid, NULL, visible, raise, uclient ? 0 : 1, 0,0,0); + surfaceid, NULL, + (visible == ICO_WINDOW_MGR_VISIBLE_SHOW) || + (visible == ICO_WINDOW_MGR_VISIBLE_SHOW_WO_ANIMATION) ? 1 : + ((visible == ICO_WINDOW_MGR_VISIBLE_HIDE) || + (visible == ICO_WINDOW_MGR_VISIBLE_HIDE_WO_ANIMATION) ? 0 : + ICO_WINDOW_MGR_VISIBLE_NOCHANGE), + raise, uclient ? 0 : 1, 0,0,0); uifw_trace("uifw_set_visible: Leave(OK)"); } @@ -1091,23 +1181,31 @@ uifw_set_visible(struct wl_client *client, struct wl_resource *resource, * @param[in] client Weyland client * @param[in] resource resource of request * @param[in] surfaceid UIFW surface id - * @param[in] animation animation name + * @param[in] change change type(show/hide,reeize,move) + * @param[in] anmation animation name * @return none */ /*--------------------------------------------------------------------------*/ static void uifw_set_animation(struct wl_client *client, struct wl_resource *resource, - uint32_t surfaceid, const char *animation) + uint32_t surfaceid, int32_t change, const char *animation) { struct uifw_win_surface* usurf = find_uifw_win_surface_by_id(surfaceid); - uifw_trace("uifw_set_transition: Enter(surf=%08x, animation=%s)", - surfaceid, animation); + uifw_trace("uifw_set_transition: Enter(surf=%08x, change=%d, animation=%s)", + surfaceid, change, animation); if (usurf) { - memset(usurf->animation, 0, sizeof(usurf->animation)); - strncpy(usurf->animation, animation, sizeof(usurf->animation)-1); - uifw_trace("uifw_set_animation: Leave(OK)"); + if (change != ICO_WINDOW_MGR_ANIMATION_CHANGE_VISIBLE) { + uifw_trace("uifw_set_animation: Leave(change type(%d9 not support)", change); + } + else { + usurf->animation.type_next = ico_get_animation_type(animation); + uifw_trace("uifw_set_animation: Leave(OK) type=%d", usurf->animation.type_next); + if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_NONE) { + usurf->animation.type = usurf->animation.type_next; + } + } } else { uifw_trace("uifw_set_animation: Leave(Surface(%08x) Not exist)", surfaceid); @@ -1248,6 +1346,85 @@ uifw_set_layer_visible(struct wl_client *client, struct wl_resource *resource, /*--------------------------------------------------------------------------*/ /** + * @brief uifw_set_client_attr: set client application attribute + * + * @param[in] client Weyland client + * @param[in] resource resource of request + * @param[in] appid client application name + * @param[in] attr attribute + * @param[in] value attribute value + * @return none + */ +/*--------------------------------------------------------------------------*/ +static void +uifw_set_client_attr(struct wl_client *client, struct wl_resource *resource, + const char *appid, int32_t attr, int32_t value) +{ + struct uifw_client_attr *lattr; + struct uifw_client *uclient; + int idx, freeidx; + + uifw_trace("uifw_set_client_attr: Enter(appid=%s, attr=%d, value=%d)", + appid, attr, value); + + freeidx = -1; + wl_list_for_each (lattr, &_ico_win_mgr->client_attr_list, link) { + if (strcmp(lattr->appid, appid) == 0) { + for (idx = 0; idx < MAX_CLIENT_ATTR; idx++) { + if (lattr->attrs[idx].attr == attr) { + lattr->attrs[idx].value = value; + freeidx = 999; + break; + } + if ((freeidx < 0) && (lattr->attrs[idx].attr < 0)) { + freeidx = idx; + } + } + if ((idx >= MAX_CLIENT_ATTR) && (freeidx >= 0)) { + lattr->attrs[freeidx].attr = attr; + lattr->attrs[freeidx].value = value; + } + else { + freeidx = 998; + } + break; + } + } + if (freeidx < 0) { + lattr = malloc(sizeof(struct uifw_client_attr)); + if (lattr) { + memset(lattr, 0, sizeof(struct uifw_client_attr)); + strncpy(lattr->appid, appid, ICO_IVI_APPID_LENGTH-1); + for (idx = 1; idx < MAX_CLIENT_ATTR; idx++) { + lattr->attrs[idx].attr = -1; + } + lattr->attrs[0].attr = attr; + lattr->attrs[0].value = value; + wl_list_insert(&_ico_win_mgr->client_attr_list, &lattr->link); + } + } + + wl_list_for_each (uclient, &_ico_win_mgr->client_list, link) { + if (strcmp(uclient->appid, appid) == 0) { + switch(attr) { + case ICO_WINDOW_MGR_CLIENT_ATTR_NOCONFIGURE: + uclient->noconfigure = value; + ivi_shell_set_client_attr(uclient->client, + ICO_CLEINT_ATTR_NOCONFIGURE, value); + uifw_trace("uifw_set_client_attr: set to ivi-shell"); + break; + default: + uifw_trace("uifw_set_client_attr: Unknown attr(%d)", attr); + break; + } + break; + } + } + uifw_trace("uifw_set_client_attr: Leave"); +} + +/*--------------------------------------------------------------------------*/ +/** * @brief win_mgr_surface_change_mgr: surface chagen from manager(HomeScreen) * * @param[in] surface Weston surface @@ -1381,6 +1558,10 @@ win_mgr_surface_destroy(struct weston_surface *surface) return; } + /* destory animation extenson */ + if (win_mgr_hook_animation) { + (*win_mgr_hook_animation)(ICO_WINDOW_MGR_ANIMATION_DESTROY, (void *)usurf); + } hash = MAKE_IDHASH(usurf->id); phash = _ico_win_mgr->idhash[hash]; bhash = NULL; @@ -1439,7 +1620,7 @@ win_mgr_surface_destroy(struct weston_surface *surface) /*--------------------------------------------------------------------------*/ static void bind_ico_win_mgr(struct wl_client *client, - void *data, uint32_t version, uint32_t id) + void *data, uint32_t version, uint32_t id) { struct wl_resource *add_resource; struct uifw_manager *nm; @@ -1630,6 +1811,19 @@ ico_win_mgr_hook_destroy(void (*hook_destroy)(struct weston_surface *surface)) win_mgr_hook_destroy = hook_destroy; } +/*--------------------------------------------------------------------------*/ +/** + * @brief ico_window_mgr_set_animation: set animation hook routine + * + * @param[in] hook_animation hook routine + * @return none + */ +/*--------------------------------------------------------------------------*/ +WL_EXPORT void +ico_window_mgr_set_animation(int (*hook_animation)(const int op, void *data)) +{ + win_mgr_hook_animation = hook_animation; +} /*--------------------------------------------------------------------------*/ /** @@ -1679,6 +1873,7 @@ module_init(struct weston_compositor *ec) wl_list_init(&_ico_win_mgr->surface_list); wl_list_init(&_ico_win_mgr->client_list); wl_list_init(&_ico_win_mgr->manager_list); + wl_list_init(&_ico_win_mgr->client_attr_list); nodeId = ico_ivi_get_mynode(); _ico_win_mgr->surface_head = ICO_IVI_SURFACEID_BASE(nodeId); diff --git a/src/ico_window_mgr.h b/src/ico_window_mgr.h index d195219..62f73f2 100644 --- a/src/ico_window_mgr.h +++ b/src/ico_window_mgr.h @@ -30,9 +30,75 @@ #ifndef _ICO_WINDOW_MGR_H_ #define _ICO_WINDOW_MGR_H_ +/* Cleint management table */ +struct uifw_client { + struct wl_client *client; /* Wayland client */ + int pid; /* ProcessId (pid) */ + char appid[ICO_IVI_APPID_LENGTH]; /* ApplicationId(from AppCore AUL) */ + char manager; /* Manager flag (Need send event) */ + char noconfigure; /* no need configure event */ + char res[2]; + struct wl_resource *resource; + struct wl_list link; +}; + +/* UIFW surface */ struct shell_surface; +struct uifw_win_surface { + uint32_t id; /* UIFW SurfaceId */ + int layer; /* LayerId */ + struct weston_surface *surface; /* Weston surface */ + struct shell_surface *shsurf; /* Shell(IVI-Shell) surface */ + struct uifw_client *uclient; /* Client */ + int x; /* X-axis */ + int y; /* Y-axis */ + int width; /* Width */ + int height; /* Height */ + struct _uifw_win_surface_animation { /* wndow animation */ + struct weston_animation animation; /* animation control */ + short type; /* animation type */ + short type_next; /* next animation type */ + short current; /* animation current percentage */ + char state; /* animation state */ + char visible; /* need visible(1)/hide(2) at end of animation*/ + uint32_t starttime; /* start time(ms) */ + } animation; + void *animadata; /* animation data */ + struct wl_list link; /* surface link list */ + struct uifw_win_surface *next_idhash; /* UIFW SurfaceId hash list */ + struct uifw_win_surface *next_wshash; /* Weston SurfaceId hash list */ +}; + +/* animation operation */ +/* default animation */ +#define ICO_WINDOW_MGR_ANIMATION_NONE 0 /* no animation */ + +/* return code of animation hook function*/ +#define ICO_WINDOW_MGR_ANIMATION_RET_NOANIMA -1 /* no animation */ +#define ICO_WINDOW_MGR_ANIMATION_RET_ANIMA 0 /* animation */ +#define ICO_WINDOW_MGR_ANIMATION_RET_ANIMASHOW 1 /* animation with visible */ + +/* animation state */ +#define ICO_WINDOW_MGR_ANIMATION_STATE_NONE 0 /* not animation */ +#define ICO_WINDOW_MGR_ANIMATION_STATE_IN 1 /* show(in) animation */ +#define ICO_WINDOW_MGR_ANIMATION_STATE_OUT 2 /* hide(out) animation */ +#define ICO_WINDOW_MGR_ANIMATION_STATE_MOVE 3 /* move animation */ +#define ICO_WINDOW_MGR_ANIMATION_STATE_RESIZE 4 /* resize animation */ + +/* extended(plugin) animation operation */ +#define ICO_WINDOW_MGR_ANIMATION_TYPE 0 /* convert animation name to value*/ +#define ICO_WINDOW_MGR_ANIMATION_DESTROY 99 /* surface destroy */ +#define ICO_WINDOW_MGR_ANIMATION_OPIN 1 /* change to show */ +#define ICO_WINDOW_MGR_ANIMATION_OPOUT 2 /* change to hide */ +#define ICO_WINDOW_MGR_ANIMATION_OPMOVE 3 /* surface move */ +#define ICO_WINDOW_MGR_ANIMATION_OPRESIZE 4 /* surface resize */ +#define ICO_WINDOW_MGR_ANIMATION_OPCANCEL 9 /* animation cancel */ /* Prototype for function */ + /* get client applicationId */ char *ico_window_mgr_appid(struct wl_client* client); + /* set window animation hook */ +void ico_window_mgr_set_animation(int (*hook_animation)(const int op, void *data)); #endif /*_ICO_WINDOW_MGR_H_*/ + diff --git a/tests/test-homescreen.c b/tests/test-homescreen.c index c76564a..595a9b9 100644 --- a/tests/test-homescreen.c +++ b/tests/test-homescreen.c @@ -1031,7 +1031,8 @@ animation_surface(struct display *display, char *buf) surfaceid = search_surface(display, args[0]); if (surfaceid >= 0) { print_log("HOMESCREEN: animation(%s,%08x,%d)", args[0], surfaceid, args[1]); - ico_window_mgr_set_animation(display->ico_window_mgr, surfaceid, args[1]); + ico_window_mgr_set_animation(display->ico_window_mgr, surfaceid, + ICO_WINDOW_MGR_ANIMATION_CHANGE_VISIBLE, args[1]); } else { print_log("HOMESCREEN: Unknown surface(%s) at animation command", args[0]); diff --git a/tests/testdata/hs_slide.dat b/tests/testdata/hs_slide.dat new file mode 100644 index 0000000..db31759 --- /dev/null +++ b/tests/testdata/hs_slide.dat @@ -0,0 +1,18 @@ +# Test for Weston IVI Plugin for HomeScreen(SystemController) +# Slide test +# +# 1. Pure client +launch ../tests/test-client < ../tests/testdata/cl_surface2.dat 2> ../tests/testlog/test-client2.log +waitcreate 2 +hide test-client +animation test-client Slide.toRight +sleep 1 +show test-client +sleep 3 +hide test-client +sleep 3 +kill test-client +# +# 9. End of Test +bye + diff --git a/tests/weston-plugin-test.slide b/tests/weston-plugin-test.slide new file mode 100755 index 0000000..d5ae9d6 --- /dev/null +++ b/tests/weston-plugin-test.slide @@ -0,0 +1,75 @@ +#!/bin/sh +# +# Weston IVI Plugin Test (Resize Buf test) +# +# Remark: This examination premises that Weston does not run. + +# 1 Delete log file +if [ -d ../tests/testlog ] ; then + rm -fr ../tests/testlog/* +else + mkdir ../tests/testlog +fi + +# 2 Weston/Wayland Envionment +export XDG_RUNTIME_DIR=/tmp/run-root +export QT_QPA_PLATFORM=wayland +export ELM_ENGINE=wayland_egl +export ECORE_EVAS_ENGINE=wayland_egl +#export ELM_ENGINE=wayland_shm +#export ECORE_EVAS_ENGINE=wayland_shm +export EVAS_FONT_DPI=72 +export ECORE_IMF_MODULE=isf +export ELM_MODULES="ctxpopup_copypasteUI>entry/api:datetime_input_ctxpopup>datetime/api" +export ELM_SCALE="0.7" +export ELM_PROFILE=mobile + +# 3 Set Environment for Test +export WESTON_IVI_PLUGIN_DIR="../src/.libs" + +# 4 Start Weston +export XDG_CONFIG_HOME="../tests" +MOD_DIR="$PWD/../src/.libs" +/usr/bin/weston --backend=drm-backend.so --modules=$MOD_DIR/ico_plugin_loader.so --idle-time=0 --log=../tests/testlog/weston.log & +sleep 1 + +# 5 Set library path +export LD_LIBRARY_PATH=../src/.libs:$LD_LIBRARY_PATH + +# 6 Start test-homescreen +../tests/test-homescreen < ../tests/testdata/hs_slide.dat 2> ../tests/testlog/test-homescreen.log + +# 7 End of Test +sleep 1 +/usr/bin/killall weston +sleep 1 + +# 8 Check Error +FOUND_ERR=0 +/bin/grep "ERR>" testlog/* +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi +/bin/grep "WRN>" testlog/* +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi +/bin/grep "Error" testlog/* +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi +/bin/grep "error" testlog/* | /bin/grep -v "error_but_no_problem_for_test" +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi +/bin/grep "Fail" testlog/* | /bin/grep -v "error_but_no_problem_for_test" +if [ "$?" != "1" ] ; then + FOUND_ERR=1 +fi + +if [ $FOUND_ERR = 0 ] ; then + echo "Weston IVI Plugin Test: OK" +else + echo "Weston IVI Plugin Test: ERROR" +fi + diff --git a/tests/weston_ivi_plugin.ini b/tests/weston_ivi_plugin.ini index 69145ac..a021d9b 100644 --- a/tests/weston_ivi_plugin.ini +++ b/tests/weston_ivi_plugin.ini @@ -1,9 +1,14 @@ [plugin] -modules=ico_ivi_common.so,ico_ivi_shell.so,ico_window_mgr.so,ico_input_mgr.so +modules=ico_ivi_common.so,ico_ivi_shell.so,ico_window_mgr.so,ico_window_animation.so,ico_input_mgr.so [shell] -#animation=none -animation=fade +# default animation +animation=none +# animation time (ms) +animation_time=600 +# animation frame rate(frame/sec) +animation_fps=15 + # 0=hide on surface create(for with HomeScreen)/1=show on surface create(for Debug) visible_on_create=0 diff --git a/weston_ivi_plugin.ini b/weston_ivi_plugin.ini index 0c24230..a021d9b 100644 --- a/weston_ivi_plugin.ini +++ b/weston_ivi_plugin.ini @@ -1,8 +1,14 @@ [plugin] -modules=ico_ivi_common.so,ico_ivi_shell.so,ico_window_mgr.so,ico_input_mgr.so +modules=ico_ivi_common.so,ico_ivi_shell.so,ico_window_mgr.so,ico_window_animation.so,ico_input_mgr.so [shell] +# default animation animation=none +# animation time (ms) +animation_time=600 +# animation frame rate(frame/sec) +animation_fps=15 + # 0=hide on surface create(for with HomeScreen)/1=show on surface create(for Debug) visible_on_create=0 -- 2.7.4