2 * Copyright © 2010-2011 Intel Corporation
3 * Copyright © 2008-2011 Kristian Høgsberg
4 * Copyright © 2013 TOYOTA MOTOR CORPORATION.
6 * Permission to use, copy, modify, distribute, and sell this software and
7 * its documentation for any purpose is hereby granted without fee, provided
8 * that the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of the copyright holders not be used in
11 * advertising or publicity pertaining to distribution of the software
12 * without specific, written prior permission. The copyright holders make
13 * no representations about the suitability of this software for any
14 * purpose. It is provided "as is" without express or implied warranty.
16 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
20 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
21 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 * @brief Window Animation (Weston(Wayland) PlugIn)
37 #include <sys/types.h>
41 #include <weston/compositor.h>
42 #include "ico_ivi_common.h"
43 #include "ico_ivi_shell.h"
44 #include "ico_window_mgr.h"
47 #define ANIMA_ZOOM 1 /* ZoomIn/ZoomOut */
48 #define ANIMA_FADE 2 /* FadeIn/FadeOut */
49 #define ANIMA_SLIDE_TORIGHT 3 /* SlideIn left to right/SlideOut right to left*/
50 #define ANIMA_SLIDE_TOLEFT 4 /* SlideIn right to left/SlideOut left to right*/
51 #define ANIMA_SLIDE_TOBOTTOM 5 /* SlideIn top to bottom/SlideOut bottom to top*/
52 #define ANIMA_SLIDE_TOTOP 6 /* SlideIn bottom to top/SlideOut top to bottom*/
54 /* Visible control at end of animation */
55 #define ANIMA_NOCONTROL_AT_END 0 /* no need surface show/hide at end of animation*/
56 #define ANIMA_SHOW_AT_END 1 /* surface show at end of animation */
57 #define ANIMA_HIDE_AT_END 2 /* surface hide at end of animation */
60 struct animation_data {
61 struct animation_data *next_free; /* free data list */
62 int x; /* original X coordinate */
63 int y; /* original Y coordinate */
64 int width; /* original width */
65 int height; /* original height */
66 char geometry_saved; /* need geometry restor at end */
67 char res[3]; /* (unused) */
68 struct weston_transform transform; /* transform matrix */
71 /* static valiables */
72 static struct weston_compositor *weston_ec; /* Weston compositor */
73 static char *default_animation; /* default animation name */
74 static int animation_time; /* animation time(ms) */
75 static int animation_fpar; /* animation frame parcent(%) */
76 static struct animation_data *free_data; /* free data list */
80 static void animation_slide(struct weston_animation *animation,
81 struct weston_output *output, uint32_t msecs);
83 static void animation_fade(struct weston_animation *animation,
84 struct weston_output *output, uint32_t msecs);
85 /* continue animation */
86 static int animation_cont(struct weston_animation *animation,
87 struct weston_output *output, uint32_t msecs);
88 /* terminate animation */
89 static void animation_end(struct uifw_win_surface *usurf, const int disp);
91 /*--------------------------------------------------------------------------*/
93 * @brief ico_window_animation: Animation addin entry
95 * @param[in] op animation operation
96 * @param[in] data data
98 * @retval ICO_WINDOW_MGR_ANIMATION_RET_ANIMA success
99 * @retval ICO_WINDOW_MGR_ANIMATION_RET_ANIMASHOW success(force visible)
100 * @retval ICO_WINDOW_MGR_ANIMATION_RET_NOANIMA error(no animation)
102 /*--------------------------------------------------------------------------*/
104 ico_window_animation(const int op, void *data)
106 struct uifw_win_surface *usurf;
107 struct weston_output *output;
110 struct timeval nowtv;
112 if (op == ICO_WINDOW_MGR_ANIMATION_TYPE) {
113 /* convert animation name to animation type value */
114 if (strcasecmp((char *)data, "fade") == 0) {
115 uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_FADE);
118 else if (strcasecmp((char *)data, "zoom") == 0) {
119 uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_ZOOM);
122 else if (strcasecmp((char *)data, "slide.toleft") == 0) {
123 uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_SLIDE_TOLEFT);
124 return ANIMA_SLIDE_TOLEFT;
126 else if (strcasecmp((char *)data, "slide.toright") == 0) {
127 uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_SLIDE_TORIGHT);
128 return ANIMA_SLIDE_TORIGHT;
130 else if (strcasecmp((char *)data, "slide.totop") == 0) {
131 uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_SLIDE_TOTOP);
132 return ANIMA_SLIDE_TOTOP;
134 else if (strcasecmp((char *)data, "slide.tobottom") == 0) {
135 uifw_trace("ico_window_animation: Type %s=>%d", (char *)data, ANIMA_SLIDE_TOBOTTOM);
136 return ANIMA_SLIDE_TOBOTTOM;
138 uifw_warn("ico_window_animation: Unknown Type %s", (char *)data);
139 return ICO_WINDOW_MGR_ANIMATION_RET_NOANIMA;
142 usurf = (struct uifw_win_surface *)data;
144 if (op == ICO_WINDOW_MGR_ANIMATION_DESTROY) {
145 if ((usurf->animation.state != ICO_WINDOW_MGR_ANIMATION_STATE_NONE) ||
146 (usurf->animadata != NULL)) {
147 uifw_trace("ico_window_animation: Destroy %08x", (int)usurf);
148 animation_end(usurf, 0);
150 return ICO_WINDOW_MGR_ANIMATION_RET_NOANIMA;
152 if (op == ICO_WINDOW_MGR_ANIMATION_OPCANCEL) {
153 /* cancel animation */
154 if ((usurf->animation.state != ICO_WINDOW_MGR_ANIMATION_STATE_NONE) &&
155 (usurf->animation.animation.frame != NULL)) {
156 uifw_trace("ico_window_animation: cancel %s.%08x",
157 usurf->uclient->appid, usurf->id);
158 (*usurf->animation.animation.frame)(&usurf->animation.animation, NULL, 0);
160 animation_end(usurf, 1);
161 ret = ICO_WINDOW_MGR_ANIMATION_RET_ANIMA;
164 /* setup animation */
165 if ((usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_NONE) ||
166 (usurf->animation.current > 95)) {
167 usurf->animation.animation.frame_counter = 1;
168 usurf->animation.current = 0;
169 wl_list_init(&usurf->animation.animation.link);
170 output = container_of(weston_ec->output_list.next,
171 struct weston_output, link);
172 wl_list_insert(output->animation_list.prev, &usurf->animation.animation.link);
174 else if (((usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) &&
175 (op == ICO_WINDOW_MGR_ANIMATION_OPOUT)) ||
176 ((usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_OUT) &&
177 (op == ICO_WINDOW_MGR_ANIMATION_OPIN))) {
178 gettimeofday(&nowtv, NULL);
179 nowsec = (uint32_t)(((long long)nowtv.tv_sec) * 1000L +
180 ((long long)nowtv.tv_usec) / 1000L);
181 usurf->animation.current = 100 - usurf->animation.current;
182 ret = ((usurf->animation.current) * animation_time) / 100;
183 if (nowsec >= (uint32_t)ret) {
184 usurf->animation.starttime = nowsec - ret;
187 usurf->animation.starttime = ((long long)nowsec) + ((long long)0x100000000L)
190 usurf->animation.animation.frame_counter = 2;
193 /* set animation function */
194 if (op == ICO_WINDOW_MGR_ANIMATION_OPIN) {
195 usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_IN;
196 uifw_trace("ico_window_animation: show(in) %s.%08x",
197 usurf->uclient->appid, usurf->id);
198 ret = ICO_WINDOW_MGR_ANIMATION_RET_ANIMA;
201 usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_OUT;
202 uifw_trace("ico_window_animation: hide(out) %s.%08x",
203 usurf->uclient->appid, usurf->id);
204 ret = ICO_WINDOW_MGR_ANIMATION_RET_ANIMASHOW;
206 if ((usurf->animation.type == ANIMA_SLIDE_TOLEFT) ||
207 (usurf->animation.type == ANIMA_SLIDE_TORIGHT) ||
208 (usurf->animation.type == ANIMA_SLIDE_TOTOP) ||
209 (usurf->animation.type == ANIMA_SLIDE_TOBOTTOM)) {
210 usurf->animation.animation.frame = animation_slide;
211 ivi_shell_restrain_configure(usurf->shsurf, 1);
212 (*usurf->animation.animation.frame)(&usurf->animation.animation, NULL, 1);
214 else if (usurf->animation.type == ANIMA_FADE) {
215 usurf->animation.animation.frame = animation_fade;
216 ivi_shell_restrain_configure(usurf->shsurf, 1);
217 (*usurf->animation.animation.frame)(&usurf->animation.animation, NULL, 1);
221 usurf->animation.animation.frame = NULL;
222 usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_NONE;
223 ivi_shell_restrain_configure(usurf->shsurf, 0);
224 wl_list_remove(&usurf->animation.animation.link);
225 ret = ICO_WINDOW_MGR_ANIMATION_RET_NOANIMA;
228 if (ret == ICO_WINDOW_MGR_ANIMATION_RET_ANIMASHOW) {
229 usurf->animation.visible = ANIMA_HIDE_AT_END;
232 usurf->animation.visible = ANIMA_NOCONTROL_AT_END;
234 weston_compositor_schedule_repaint(weston_ec);
238 /*--------------------------------------------------------------------------*/
240 * @brief animation_cont: continue animation
242 * @param[in] animation weston animation table
243 * @param[in] output weston output table
244 * @param[in] msecs current time stamp
245 * @return time has come
246 * @retval =0 time has come
247 * @retval >0 time has not yet come(return value is current parcent)
249 /*--------------------------------------------------------------------------*/
251 animation_cont(struct weston_animation *animation, struct weston_output *output,
254 struct uifw_win_surface *usurf;
255 struct animation_data *animadata;
258 struct timeval nowtv;
260 gettimeofday(&nowtv, NULL);
261 nowsec = (uint32_t)(((long long)nowtv.tv_sec) * 1000L +
262 ((long long)nowtv.tv_usec) / 1000L);
264 usurf = container_of(animation, struct uifw_win_surface, animation.animation);
266 if (animation->frame_counter <= 1) {
267 /* first call, initialize */
268 animation->frame_counter = 1;
269 usurf->animation.starttime = nowsec;
270 usurf->animation.current = 1000;
271 if (! usurf->animadata) {
273 usurf->animadata = (void *)free_data;
274 free_data = free_data->next_free;
277 usurf->animadata = (void *)malloc(sizeof(struct animation_data));
279 memset(usurf->animadata, 0, sizeof(struct animation_data));
281 animadata = (struct animation_data *)usurf->animadata;
282 animadata->x = usurf->x;
283 animadata->y = usurf->y;
284 animadata->width = usurf->width;
285 animadata->height = usurf->height;
286 animadata->geometry_saved = 1;
287 weston_matrix_init(&animadata->transform.matrix);
288 wl_list_init(&animadata->transform.link);
290 else if (! usurf->animadata) {
291 animation_end(usurf, 0);
295 if (nowsec >= usurf->animation.starttime) {
296 nowsec = nowsec - usurf->animation.starttime; /* elapsed time(ms) */
299 nowsec = (uint32_t)(((long long)0x100000000L) +
300 ((long long)nowsec) - ((long long)usurf->animation.starttime));
302 if (((output == NULL) && (msecs == 0)) || (nowsec >= ((uint32_t)animation_time))) {
306 par = (nowsec * 100 + animation_time / 2) / animation_time;
307 if (par < 2) par = 2;
310 (abs(usurf->animation.current - par) >= animation_fpar)) {
311 usurf->animation.current = par;
317 /*--------------------------------------------------------------------------*/
319 * @brief animation_end: terminate animation
321 * @param[in] usurf UIFW surface table
322 * @param[in] disp display control(1)/no display(0)
325 /*--------------------------------------------------------------------------*/
327 animation_end(struct uifw_win_surface *usurf, const int disp)
329 struct animation_data *animadata;
331 usurf->animation.state = ICO_WINDOW_MGR_ANIMATION_STATE_NONE;
332 animadata = (struct animation_data *)usurf->animadata;
335 if (animadata->geometry_saved > 1) {
336 usurf->x = animadata->x;
337 usurf->y = animadata->y;
338 usurf->width = animadata->width;
339 usurf->height = animadata->height;
340 animadata->geometry_saved = 0;
342 wl_list_remove(&usurf->animation.animation.link);
343 wl_list_init(&usurf->animation.animation.link);
346 if ((usurf->animation.visible == ANIMA_HIDE_AT_END) &&
347 (ivi_shell_is_visible(usurf->shsurf))) {
348 ivi_shell_set_visible(usurf->shsurf, 0);
349 weston_surface_damage_below(usurf->surface);
350 weston_surface_damage(usurf->surface);
351 weston_compositor_schedule_repaint(weston_ec);
353 if ((usurf->animation.visible == ANIMA_SHOW_AT_END) &&
354 (! ivi_shell_is_visible(usurf->shsurf))) {
355 ivi_shell_set_visible(usurf->shsurf, 1);
356 weston_surface_damage_below(usurf->surface);
357 weston_surface_damage(usurf->surface);
358 weston_compositor_schedule_repaint(weston_ec);
360 ivi_shell_restrain_configure(usurf->shsurf, 0);
362 usurf->animation.visible = ANIMA_NOCONTROL_AT_END;
363 usurf->animation.type = usurf->animation.type_next;
365 usurf->animadata = NULL;
366 animadata->next_free = free_data;
367 free_data = animadata;
371 /*--------------------------------------------------------------------------*/
373 * @brief animation_slide: slide animation
375 * @param[in] animation weston animation table
376 * @param[in] outout weston output table
377 * @param[in] mseces current time(unused)
380 /*--------------------------------------------------------------------------*/
382 animation_slide(struct weston_animation *animation,
383 struct weston_output *output, uint32_t msecs)
385 struct uifw_win_surface *usurf;
386 struct animation_data *animadata;
387 struct weston_surface *es;
391 usurf = container_of(animation, struct uifw_win_surface, animation.animation);
393 par = animation_cont(animation, output, msecs);
395 uifw_trace("animation_slide: usurf=%08x count=%d %d%% skip",
396 (int)usurf, animation->frame_counter, par);
397 /* continue animation */
399 weston_compositor_schedule_repaint(weston_ec);
403 par = usurf->animation.current;
404 animadata = (struct animation_data *)usurf->animadata;
406 uifw_trace("animation_slide: usurf=%08x count=%d %d%% type=%d state=%d",
407 (int)usurf, animation->frame_counter, par,
408 usurf->animation.type, usurf->animation.state);
412 switch (usurf->animation.type) {
413 case ANIMA_SLIDE_TORIGHT: /* slide in left to right */
414 if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) {
415 /* slide in left to right */
416 usurf->x = 0 - ((animadata->x + animadata->width) * (100 - par) / 100);
419 /* slide out right to left */
420 usurf->x = 0 - ((animadata->x + animadata->width) * par / 100);
423 case ANIMA_SLIDE_TOLEFT: /* slide in right to left */
424 dwidth = (container_of(weston_ec->output_list.next,
425 struct weston_output, link))->width;
426 if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) {
427 /* slide in right to left */
428 usurf->x = animadata->x + (dwidth - animadata->x) * (100 - par) / 100;
431 /* slide out left to right */
432 usurf->x = animadata->x + (dwidth - animadata->x) * par / 100;
435 case ANIMA_SLIDE_TOBOTTOM: /* slide in top to bottom */
436 if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) {
437 /* slide in top to bottom */
438 usurf->y = 0 - ((animadata->y + animadata->height) * (100 - par) / 100);
441 /* slide out bottom to top */
442 usurf->y = 0 - ((animadata->y + animadata->height) * par / 100);
445 default: /*ANIMA_SLIDE_TOTOP*/ /* slide in bottom to top */
446 dheight = (container_of(weston_ec->output_list.next,
447 struct weston_output, link))->height;
448 if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) {
449 /* slide in bottom to top */
450 usurf->y = animadata->y + (dheight - animadata->y) * (100 - par) / 100;
453 /* slide out top to bottom */
454 usurf->y = animadata->y + (dheight - animadata->y) * par / 100;
459 es->geometry.x = usurf->x;
460 es->geometry.y = usurf->y;
461 ivi_shell_set_positionsize(usurf->shsurf,
462 usurf->x, usurf->y, usurf->width, usurf->height);
463 if ((es->output) && (es->buffer) &&
464 (es->geometry.width > 0) && (es->geometry.height > 0)) {
465 weston_surface_damage_below(es);
466 weston_surface_damage(es);
469 /* end of animation */
470 animadata->geometry_saved ++; /* restore geometry */
471 animation_end(usurf, 1);
472 uifw_trace("animation_slide: End of animation");
475 /* continue animation */
476 weston_compositor_schedule_repaint(weston_ec);
480 /*--------------------------------------------------------------------------*/
482 * @brief animation_fade: fade animation
484 * @param[in] animation weston animation table
485 * @param[in] outout weston output table
486 * @param[in] mseces current time(unused)
489 /*--------------------------------------------------------------------------*/
491 animation_fade(struct weston_animation *animation,
492 struct weston_output *output, uint32_t msecs)
494 struct uifw_win_surface *usurf;
495 struct animation_data *animadata;
496 struct weston_surface *es;
499 usurf = container_of(animation, struct uifw_win_surface, animation.animation);
501 par = animation_cont(animation, output, msecs);
503 uifw_trace("animation_fade: usurf=%08x count=%d %d%% skip",
504 (int)usurf, animation->frame_counter, par);
505 /* continue animation */
507 weston_compositor_schedule_repaint(weston_ec);
512 animadata = (struct animation_data *)usurf->animadata;
514 par = usurf->animation.current;
515 if (animation->frame_counter == 1) {
516 wl_list_insert(&es->geometry.transformation_list,
517 &animadata->transform.link);
520 uifw_trace("animation_fade: usurf=%08x count=%d %d%% type=%d state=%d",
521 (int)usurf, animation->frame_counter, par,
522 usurf->animation.type, usurf->animation.state);
525 if (usurf->animation.state == ICO_WINDOW_MGR_ANIMATION_STATE_IN) {
527 es->alpha = ((double)par) / ((double)100.0);
531 es->alpha = ((double)1.0) - ((double)par) / ((double)100.0);
533 if (es->alpha < 0.0) es->alpha = 0.0;
534 else if (es->alpha > 1.0) es->alpha = 1.0;
536 if ((es->output) && (es->buffer) &&
537 (es->geometry.width > 0) && (es->geometry.height > 0)) {
538 weston_surface_damage_below(es);
539 weston_surface_damage(es);
542 /* end of animation */
543 wl_list_remove(&animadata->transform.link);
544 animation_end(usurf, 1);
545 uifw_trace("animation_fade: End of animation");
548 /* continue animation */
549 weston_compositor_schedule_repaint(weston_ec);
553 /*--------------------------------------------------------------------------*/
555 * @brief module_init: initialize ico_window_animation
556 * this function called from ico_pluign_loader
558 * @param[in] es weston compositor
563 /*--------------------------------------------------------------------------*/
565 module_init(struct weston_compositor *ec)
568 struct animation_data *animadata;
570 uifw_info("ico_window_animation: Enter(module_init)");
572 /* allocate animation datas */
574 for (i = 0; i < 50; i++) {
575 animadata = (struct animation_data *)malloc(sizeof(struct animation_data));
577 uifw_error("ico_window_animation: No Memory(module_init)");
580 animadata->next_free = free_data;
581 free_data = animadata;
585 default_animation = (char *)ivi_shell_default_animation(&animation_time,
587 animation_fpar = ((1000 * 100) / animation_fpar) / animation_time;
589 ico_window_mgr_set_animation(ico_window_animation);
591 uifw_info("ico_window_animation: Leave(module_init)");