1 /*
2 * Copyright (C) 2014 DENSO CORPORATION
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26 #include "config.h"
27
28 #include <time.h>
29 #include <assert.h>
30 #include <stdlib.h>
31 #include <stdint.h>
32 #include <stdio.h>
33 #include <stdbool.h>
34
35 #include "ivi-shell.h"
36 #include "ivi-layout-export.h"
37 #include "ivi-layout-private.h"
38
39 struct ivi_layout_transition;
40
41 typedef void (*ivi_layout_transition_frame_func)(
42 struct ivi_layout_transition *transition);
43 typedef void (*ivi_layout_transition_destroy_func)(
44 struct ivi_layout_transition *transition);
45 typedef int32_t (*ivi_layout_is_transition_func)(void *private_data, void *id);
46
47 struct ivi_layout_transition {
48 enum ivi_layout_transition_type type;
49 void *private_data;
50 void *user_data;
51
52 uint32_t time_start;
53 uint32_t time_duration;
54 uint32_t time_elapsed;
55 uint32_t is_done;
56 ivi_layout_is_transition_func is_transition_func;
57 ivi_layout_transition_frame_func frame_func;
58 ivi_layout_transition_destroy_func destroy_func;
59 };
60
61 struct transition_node {
62 struct ivi_layout_transition *transition;
63
64 /* ivi_layout::pending_transition_list
65 * ivi_layout_transition_set::transition_list
66 */
67 struct wl_list link;
68 };
69
70 static void layout_transition_destroy(struct ivi_layout_transition *transition);
71
72 static struct ivi_layout_transition *
get_transition_from_type_and_id(enum ivi_layout_transition_type type,void * id_data)73 get_transition_from_type_and_id(enum ivi_layout_transition_type type,
74 void *id_data)
75 {
76 struct ivi_layout *layout = get_instance();
77 struct transition_node *node;
78 struct ivi_layout_transition *tran;
79
80 wl_list_for_each(node, &layout->transitions->transition_list, link) {
81 tran = node->transition;
82
83 if (tran->type == type &&
84 tran->is_transition_func(tran->private_data, id_data))
85 return tran;
86 }
87
88 return NULL;
89 }
90
91 int32_t
is_surface_transition(struct ivi_layout_surface * surface)92 is_surface_transition(struct ivi_layout_surface *surface)
93 {
94 struct ivi_layout *layout = get_instance();
95 struct transition_node *node;
96 struct ivi_layout_transition *tran;
97
98 wl_list_for_each(node, &layout->transitions->transition_list, link) {
99 tran = node->transition;
100
101 if ((tran->type == IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE ||
102 tran->type == IVI_LAYOUT_TRANSITION_VIEW_RESIZE) &&
103 tran->is_transition_func(tran->private_data, surface))
104 return 1;
105 }
106
107 return 0;
108 }
109
110 void
ivi_layout_remove_all_surface_transitions(struct ivi_layout_surface * surface)111 ivi_layout_remove_all_surface_transitions(struct ivi_layout_surface *surface)
112 {
113 struct ivi_layout *layout = get_instance();
114 struct transition_node *node;
115 struct transition_node *tmp;
116 struct ivi_layout_transition *tran;
117
118 wl_list_for_each_safe(node, tmp, &layout->transitions->transition_list, link) {
119 tran = node->transition;
120 if (tran->is_transition_func(tran->private_data, surface)) {
121 layout_transition_destroy(tran);
122 }
123 };
124 }
125
126 static void
tick_transition(struct ivi_layout_transition * transition,uint32_t timestamp)127 tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp)
128 {
129 const double t = timestamp - transition->time_start;
130
131 if (transition->time_duration <= t) {
132 transition->time_elapsed = transition->time_duration;
133 transition->is_done = 1;
134 } else {
135 transition->time_elapsed = t;
136 }
137 }
138
time_to_nowpos(struct ivi_layout_transition * transition)139 static float time_to_nowpos(struct ivi_layout_transition *transition)
140 {
141 return sin((float)transition->time_elapsed /
142 (float)transition->time_duration * M_PI_2);
143 }
144
145 static void
do_transition_frame(struct ivi_layout_transition * transition,uint32_t timestamp)146 do_transition_frame(struct ivi_layout_transition *transition,
147 uint32_t timestamp)
148 {
149 if (0 == transition->time_start)
150 transition->time_start = timestamp;
151
152 tick_transition(transition, timestamp);
153 transition->frame_func(transition);
154
155 if (transition->is_done)
156 layout_transition_destroy(transition);
157 }
158
159 static int32_t
layout_transition_frame(void * data)160 layout_transition_frame(void *data)
161 {
162 struct ivi_layout_transition_set *transitions = data;
163 uint32_t fps = 30;
164 struct timespec timestamp = {};
165 uint32_t msec = 0;
166 struct transition_node *node = NULL;
167 struct transition_node *next = NULL;
168
169 if (wl_list_empty(&transitions->transition_list)) {
170 wl_event_source_timer_update(transitions->event_source, 0);
171 return 1;
172 }
173
174 wl_event_source_timer_update(transitions->event_source, 1000 / fps);
175
176 clock_gettime(CLOCK_MONOTONIC, ×tamp);/* FIXME */
177 msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec);
178
179 wl_list_for_each_safe(node, next, &transitions->transition_list, link) {
180 do_transition_frame(node->transition, msec);
181 }
182
183 ivi_layout_commit_changes();
184 return 1;
185 }
186
187 struct ivi_layout_transition_set *
ivi_layout_transition_set_create(struct weston_compositor * ec)188 ivi_layout_transition_set_create(struct weston_compositor *ec)
189 {
190 struct ivi_layout_transition_set *transitions;
191 struct wl_event_loop *loop;
192
193 transitions = malloc(sizeof(*transitions));
194 if (transitions == NULL) {
195 weston_log("%s: memory allocation fails\n", __func__);
196 return NULL;
197 }
198
199 wl_list_init(&transitions->transition_list);
200
201 loop = wl_display_get_event_loop(ec->wl_display);
202 transitions->event_source =
203 wl_event_loop_add_timer(loop, layout_transition_frame,
204 transitions);
205
206 return transitions;
207 }
208
209 static bool
layout_transition_register(struct ivi_layout_transition * trans)210 layout_transition_register(struct ivi_layout_transition *trans)
211 {
212 struct ivi_layout *layout = get_instance();
213 struct transition_node *node;
214
215 node = malloc(sizeof(*node));
216 if (node == NULL) {
217 weston_log("%s: memory allocation fails\n", __func__);
218 return false;
219 }
220
221 node->transition = trans;
222 wl_list_insert(&layout->pending_transition_list, &node->link);
223 return true;
224 }
225
226 static void
remove_transition(struct ivi_layout * layout,struct ivi_layout_transition * trans)227 remove_transition(struct ivi_layout *layout,
228 struct ivi_layout_transition *trans)
229 {
230 struct transition_node *node;
231 struct transition_node *next;
232
233 wl_list_for_each_safe(node, next,
234 &layout->transitions->transition_list, link) {
235 if (node->transition == trans) {
236 wl_list_remove(&node->link);
237 free(node);
238 return;
239 }
240 }
241
242 wl_list_for_each_safe(node, next,
243 &layout->pending_transition_list, link) {
244 if (node->transition == trans) {
245 wl_list_remove(&node->link);
246 free(node);
247 return;
248 }
249 }
250 }
251
252 static void
layout_transition_destroy(struct ivi_layout_transition * transition)253 layout_transition_destroy(struct ivi_layout_transition *transition)
254 {
255 struct ivi_layout *layout = get_instance();
256
257 remove_transition(layout, transition);
258 if (transition->destroy_func)
259 transition->destroy_func(transition);
260 free(transition);
261 }
262
263 static struct ivi_layout_transition *
create_layout_transition(void)264 create_layout_transition(void)
265 {
266 struct ivi_layout_transition *transition = malloc(sizeof(*transition));
267
268 if (transition == NULL) {
269 weston_log("%s: memory allocation fails\n", __func__);
270 return NULL;
271 }
272
273 transition->type = IVI_LAYOUT_TRANSITION_MAX;
274 transition->time_start = 0;
275 transition->time_duration = 300; /* 300ms */
276 transition->time_elapsed = 0;
277
278 transition->is_done = 0;
279
280 transition->is_transition_func = NULL;
281 transition->private_data = NULL;
282 transition->user_data = NULL;
283
284 transition->frame_func = NULL;
285 transition->destroy_func = NULL;
286
287 return transition;
288 }
289
290 /* move and resize view transition */
291
292 struct move_resize_view_data {
293 struct ivi_layout_surface *surface;
294 int32_t start_x;
295 int32_t start_y;
296 int32_t end_x;
297 int32_t end_y;
298 int32_t start_width;
299 int32_t start_height;
300 int32_t end_width;
301 int32_t end_height;
302 };
303
304 static void
transition_move_resize_view_destroy(struct ivi_layout_transition * transition)305 transition_move_resize_view_destroy(struct ivi_layout_transition *transition)
306 {
307 struct move_resize_view_data *data =
308 (struct move_resize_view_data *)transition->private_data;
309 struct ivi_layout_surface *layout_surface = data->surface;
310
311 ivi_layout_surface_set_size(layout_surface,
312 layout_surface->prop.dest_width,
313 layout_surface->prop.dest_height);
314
315 if (transition->private_data) {
316 free(transition->private_data);
317 transition->private_data = NULL;
318 }
319 }
320
321 static void
transition_move_resize_view_user_frame(struct ivi_layout_transition * transition)322 transition_move_resize_view_user_frame(struct ivi_layout_transition *transition)
323 {
324 struct move_resize_view_data *mrv = transition->private_data;
325 const double current = time_to_nowpos(transition);
326
327 const int32_t destx = mrv->start_x +
328 (mrv->end_x - mrv->start_x) * current;
329
330 const int32_t desty = mrv->start_y +
331 (mrv->end_y - mrv->start_y) * current;
332
333 const int32_t dest_width = mrv->start_width +
334 (mrv->end_width - mrv->start_width) * current;
335
336 const int32_t dest_height = mrv->start_height +
337 (mrv->end_height - mrv->start_height) * current;
338
339 ivi_layout_surface_set_destination_rectangle(mrv->surface,
340 destx, desty,
341 dest_width, dest_height);
342 }
343
344 static int32_t
is_transition_move_resize_view_func(struct move_resize_view_data * data,struct ivi_layout_surface * view)345 is_transition_move_resize_view_func(struct move_resize_view_data *data,
346 struct ivi_layout_surface *view)
347 {
348 return data->surface == view;
349 }
350
351 static struct ivi_layout_transition *
create_move_resize_view_transition(struct ivi_layout_surface * surface,int32_t start_x,int32_t start_y,int32_t end_x,int32_t end_y,int32_t start_width,int32_t start_height,int32_t end_width,int32_t end_height,ivi_layout_transition_frame_func frame_func,ivi_layout_transition_destroy_func destroy_func,uint32_t duration)352 create_move_resize_view_transition(
353 struct ivi_layout_surface *surface,
354 int32_t start_x, int32_t start_y,
355 int32_t end_x, int32_t end_y,
356 int32_t start_width, int32_t start_height,
357 int32_t end_width, int32_t end_height,
358 ivi_layout_transition_frame_func frame_func,
359 ivi_layout_transition_destroy_func destroy_func,
360 uint32_t duration)
361 {
362 struct ivi_layout_transition *transition;
363 struct move_resize_view_data *data;
364
365 transition = create_layout_transition();
366 if (transition == NULL)
367 return NULL;
368
369 data = malloc(sizeof(*data));
370 if (data == NULL) {
371 weston_log("%s: memory allocation fails\n", __func__);
372 free(transition);
373 return NULL;
374 }
375
376 transition->type = IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE;
377 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_resize_view_func;
378
379 transition->frame_func = frame_func;
380 transition->destroy_func = destroy_func;
381 transition->private_data = data;
382
383 if (duration != 0)
384 transition->time_duration = duration;
385
386 data->surface = surface;
387 data->start_x = start_x;
388 data->start_y = start_y;
389 data->end_x = end_x;
390 data->end_y = end_y;
391
392 data->start_width = start_width;
393 data->start_height = start_height;
394 data->end_width = end_width;
395 data->end_height = end_height;
396
397 return transition;
398 }
399
400 void
ivi_layout_transition_move_resize_view(struct ivi_layout_surface * surface,int32_t dest_x,int32_t dest_y,int32_t dest_width,int32_t dest_height,uint32_t duration)401 ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface,
402 int32_t dest_x, int32_t dest_y,
403 int32_t dest_width, int32_t dest_height,
404 uint32_t duration)
405 {
406 struct ivi_layout_transition *transition;
407 int32_t start_pos[2] = {
408 surface->pending.prop.start_x,
409 surface->pending.prop.start_y
410 };
411
412 int32_t start_size[2] = {
413 surface->pending.prop.start_width,
414 surface->pending.prop.start_height
415 };
416
417 transition = get_transition_from_type_and_id(
418 IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
419 surface);
420 if (transition) {
421 struct move_resize_view_data *data = transition->private_data;
422 transition->time_start = 0;
423 transition->time_duration = duration;
424
425 data->start_x = start_pos[0];
426 data->start_y = start_pos[1];
427 data->end_x = dest_x;
428 data->end_y = dest_y;
429
430 data->start_width = start_size[0];
431 data->start_height = start_size[1];
432 data->end_width = dest_width;
433 data->end_height = dest_height;
434 return;
435 }
436
437 transition = create_move_resize_view_transition(
438 surface,
439 start_pos[0], start_pos[1],
440 dest_x, dest_y,
441 start_size[0], start_size[1],
442 dest_width, dest_height,
443 transition_move_resize_view_user_frame,
444 transition_move_resize_view_destroy,
445 duration);
446
447 if (transition && layout_transition_register(transition))
448 return;
449 layout_transition_destroy(transition);
450 }
451
452 /* fade transition */
453 struct fade_view_data {
454 struct ivi_layout_surface *surface;
455 double start_alpha;
456 double end_alpha;
457 };
458
459 struct store_alpha{
460 double alpha;
461 };
462
463 static void
fade_view_user_frame(struct ivi_layout_transition * transition)464 fade_view_user_frame(struct ivi_layout_transition *transition)
465 {
466 struct fade_view_data *fade = transition->private_data;
467 struct ivi_layout_surface *surface = fade->surface;
468
469 const double current = time_to_nowpos(transition);
470 const double alpha = fade->start_alpha +
471 (fade->end_alpha - fade->start_alpha) * current;
472
473 ivi_layout_surface_set_opacity(surface, wl_fixed_from_double(alpha));
474 ivi_layout_surface_set_visibility(surface, true);
475 }
476
477 static int32_t
is_transition_fade_view_func(struct fade_view_data * data,struct ivi_layout_surface * view)478 is_transition_fade_view_func(struct fade_view_data *data,
479 struct ivi_layout_surface *view)
480 {
481 return data->surface == view;
482 }
483
484 static struct ivi_layout_transition *
create_fade_view_transition(struct ivi_layout_surface * surface,double start_alpha,double end_alpha,ivi_layout_transition_frame_func frame_func,void * user_data,ivi_layout_transition_destroy_func destroy_func,uint32_t duration)485 create_fade_view_transition(
486 struct ivi_layout_surface *surface,
487 double start_alpha, double end_alpha,
488 ivi_layout_transition_frame_func frame_func,
489 void *user_data,
490 ivi_layout_transition_destroy_func destroy_func,
491 uint32_t duration)
492 {
493 struct ivi_layout_transition *transition;
494 struct fade_view_data *data;
495
496 transition = create_layout_transition();
497 if (transition == NULL)
498 return NULL;
499
500 data = malloc(sizeof(*data));
501 if (data == NULL) {
502 weston_log("%s: memory allocation fails\n", __func__);
503 free(transition);
504 return NULL;
505 }
506
507 transition->type = IVI_LAYOUT_TRANSITION_VIEW_FADE;
508 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_view_func;
509
510 transition->user_data = user_data;
511 transition->private_data = data;
512 transition->frame_func = frame_func;
513 transition->destroy_func = destroy_func;
514
515 if (duration != 0)
516 transition->time_duration = duration;
517
518 data->surface = surface;
519 data->start_alpha = start_alpha;
520 data->end_alpha = end_alpha;
521
522 return transition;
523 }
524
525 static void
create_visibility_transition(struct ivi_layout_surface * surface,double start_alpha,double dest_alpha,void * user_data,ivi_layout_transition_destroy_func destroy_func,uint32_t duration)526 create_visibility_transition(struct ivi_layout_surface *surface,
527 double start_alpha,
528 double dest_alpha,
529 void *user_data,
530 ivi_layout_transition_destroy_func destroy_func,
531 uint32_t duration)
532 {
533 struct ivi_layout_transition *transition = NULL;
534
535 transition = create_fade_view_transition(
536 surface,
537 start_alpha, dest_alpha,
538 fade_view_user_frame,
539 user_data,
540 destroy_func,
541 duration);
542
543 if (transition && layout_transition_register(transition))
544 return;
545 layout_transition_destroy(transition);
546 }
547
548 static void
visibility_on_transition_destroy(struct ivi_layout_transition * transition)549 visibility_on_transition_destroy(struct ivi_layout_transition *transition)
550 {
551 struct fade_view_data *data = transition->private_data;
552 struct store_alpha *user_data = transition->user_data;
553
554 ivi_layout_surface_set_visibility(data->surface, true);
555
556 free(data);
557 transition->private_data = NULL;
558
559 free(user_data);
560 transition->user_data = NULL;
561 }
562
563 void
ivi_layout_transition_visibility_on(struct ivi_layout_surface * surface,uint32_t duration)564 ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
565 uint32_t duration)
566 {
567 struct ivi_layout_transition *transition;
568 bool is_visible = surface->prop.visibility;
569 wl_fixed_t dest_alpha = surface->prop.opacity;
570 struct store_alpha *user_data = NULL;
571 wl_fixed_t start_alpha = 0.0;
572 struct fade_view_data *data = NULL;
573
574 transition = get_transition_from_type_and_id(
575 IVI_LAYOUT_TRANSITION_VIEW_FADE,
576 surface);
577 if (transition) {
578 start_alpha = surface->prop.opacity;
579 user_data = transition->user_data;
580 data = transition->private_data;
581
582 transition->time_start = 0;
583 transition->time_duration = duration;
584 transition->destroy_func = visibility_on_transition_destroy;
585
586 data->start_alpha = wl_fixed_to_double(start_alpha);
587 data->end_alpha = user_data->alpha;
588 return;
589 }
590
591 if (is_visible)
592 return;
593
594 user_data = malloc(sizeof(*user_data));
595 if (user_data == NULL) {
596 weston_log("%s: memory allocation fails\n", __func__);
597 return;
598 }
599
600 user_data->alpha = wl_fixed_to_double(dest_alpha);
601
602 create_visibility_transition(surface,
603 0.0, // start_alpha
604 wl_fixed_to_double(dest_alpha),
605 user_data,
606 visibility_on_transition_destroy,
607 duration);
608 }
609
610 static void
visibility_off_transition_destroy(struct ivi_layout_transition * transition)611 visibility_off_transition_destroy(struct ivi_layout_transition *transition)
612 {
613 struct fade_view_data *data = transition->private_data;
614 struct store_alpha *user_data = transition->user_data;
615
616 ivi_layout_surface_set_visibility(data->surface, false);
617
618 ivi_layout_surface_set_opacity(data->surface,
619 wl_fixed_from_double(user_data->alpha));
620
621 free(data);
622 transition->private_data = NULL;
623
624 free(user_data);
625 transition->user_data= NULL;
626 }
627
628 void
ivi_layout_transition_visibility_off(struct ivi_layout_surface * surface,uint32_t duration)629 ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
630 uint32_t duration)
631 {
632 struct ivi_layout_transition *transition;
633 wl_fixed_t start_alpha = surface->prop.opacity;
634 struct store_alpha* user_data = NULL;
635 struct fade_view_data* data = NULL;
636
637 transition =
638 get_transition_from_type_and_id(IVI_LAYOUT_TRANSITION_VIEW_FADE,
639 surface);
640 if (transition) {
641 data = transition->private_data;
642
643 transition->time_start = 0;
644 transition->time_duration = duration;
645 transition->destroy_func = visibility_off_transition_destroy;
646
647 data->start_alpha = wl_fixed_to_double(start_alpha);
648 data->end_alpha = 0;
649 return;
650 }
651
652 user_data = malloc(sizeof(*user_data));
653 if (user_data == NULL) {
654 weston_log("%s: memory allocation fails\n", __func__);
655 return;
656 }
657
658 user_data->alpha = wl_fixed_to_double(start_alpha);
659
660 create_visibility_transition(surface,
661 wl_fixed_to_double(start_alpha),
662 0.0, // dest_alpha
663 user_data,
664 visibility_off_transition_destroy,
665 duration);
666 }
667
668 /* move layer transition */
669
670 struct move_layer_data {
671 struct ivi_layout_layer *layer;
672 int32_t start_x;
673 int32_t start_y;
674 int32_t end_x;
675 int32_t end_y;
676 ivi_layout_transition_destroy_user_func destroy_func;
677 };
678
679 static void
transition_move_layer_user_frame(struct ivi_layout_transition * transition)680 transition_move_layer_user_frame(struct ivi_layout_transition *transition)
681 {
682 struct move_layer_data *data = transition->private_data;
683 struct ivi_layout_layer *layer = data->layer;
684
685 const float current = time_to_nowpos(transition);
686
687 const int32_t dest_x = data->start_x +
688 (data->end_x - data->start_x) * current;
689
690 const int32_t dest_y = data->start_y +
691 (data->end_y - data->start_y) * current;
692
693 ivi_layout_layer_set_destination_rectangle(layer, dest_x, dest_y,
694 layer->prop.dest_width, layer->prop.dest_height);
695 }
696
697 static void
transition_move_layer_destroy(struct ivi_layout_transition * transition)698 transition_move_layer_destroy(struct ivi_layout_transition *transition)
699 {
700 struct move_layer_data *data = transition->private_data;
701
702 if (data->destroy_func)
703 data->destroy_func(transition->user_data);
704
705 free(data);
706 transition->private_data = NULL;
707 }
708
709 static int32_t
is_transition_move_layer_func(struct move_layer_data * data,struct ivi_layout_layer * layer)710 is_transition_move_layer_func(struct move_layer_data *data,
711 struct ivi_layout_layer *layer)
712 {
713 return data->layer == layer;
714 }
715
716
717 static struct ivi_layout_transition *
create_move_layer_transition(struct ivi_layout_layer * layer,int32_t start_x,int32_t start_y,int32_t end_x,int32_t end_y,void * user_data,ivi_layout_transition_destroy_user_func destroy_user_func,uint32_t duration)718 create_move_layer_transition(
719 struct ivi_layout_layer *layer,
720 int32_t start_x, int32_t start_y,
721 int32_t end_x, int32_t end_y,
722 void *user_data,
723 ivi_layout_transition_destroy_user_func destroy_user_func,
724 uint32_t duration)
725 {
726 struct ivi_layout_transition *transition;
727 struct move_layer_data *data;
728
729 transition = create_layout_transition();
730 if (transition == NULL)
731 return NULL;
732
733 data = malloc(sizeof(*data));
734 if (data == NULL) {
735 weston_log("%s: memory allocation fails\n", __func__);
736 free(transition);
737 return NULL;
738 }
739
740 transition->type = IVI_LAYOUT_TRANSITION_LAYER_MOVE;
741 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_layer_func;
742
743 transition->frame_func = transition_move_layer_user_frame;
744 transition->destroy_func = transition_move_layer_destroy;
745 transition->private_data = data;
746 transition->user_data = user_data;
747
748 if (duration != 0)
749 transition->time_duration = duration;
750
751 data->layer = layer;
752 data->start_x = start_x;
753 data->start_y = start_y;
754 data->end_x = end_x;
755 data->end_y = end_y;
756 data->destroy_func = destroy_user_func;
757
758 return transition;
759 }
760
761 void
ivi_layout_transition_move_layer(struct ivi_layout_layer * layer,int32_t dest_x,int32_t dest_y,uint32_t duration)762 ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
763 int32_t dest_x, int32_t dest_y,
764 uint32_t duration)
765 {
766 int32_t start_pos_x = layer->prop.dest_x;
767 int32_t start_pos_y = layer->prop.dest_y;
768 struct ivi_layout_transition *transition = NULL;
769
770 transition = create_move_layer_transition(
771 layer,
772 start_pos_x, start_pos_y,
773 dest_x, dest_y,
774 NULL, NULL,
775 duration);
776
777 if (transition && layout_transition_register(transition))
778 return;
779
780 free(transition);
781 }
782
783 void
ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer * layer)784 ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer)
785 {
786 struct ivi_layout_transition *transition =
787 get_transition_from_type_and_id(
788 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
789 layer);
790 if (transition) {
791 layout_transition_destroy(transition);
792 }
793 }
794
795 /* fade layer transition */
796 struct fade_layer_data {
797 struct ivi_layout_layer *layer;
798 uint32_t is_fade_in;
799 double start_alpha;
800 double end_alpha;
801 ivi_layout_transition_destroy_user_func destroy_func;
802 };
803
804 static void
transition_fade_layer_destroy(struct ivi_layout_transition * transition)805 transition_fade_layer_destroy(struct ivi_layout_transition *transition)
806 {
807 struct fade_layer_data *data = transition->private_data;
808 transition->private_data = NULL;
809
810 free(data);
811 }
812
813 static void
transition_fade_layer_user_frame(struct ivi_layout_transition * transition)814 transition_fade_layer_user_frame(struct ivi_layout_transition *transition)
815 {
816 double current = time_to_nowpos(transition);
817 struct fade_layer_data *data = transition->private_data;
818 double alpha = data->start_alpha +
819 (data->end_alpha - data->start_alpha) * current;
820 wl_fixed_t fixed_alpha = wl_fixed_from_double(alpha);
821
822 int32_t is_done = transition->is_done;
823 bool is_visible = !is_done || data->is_fade_in;
824
825 ivi_layout_layer_set_opacity(data->layer, fixed_alpha);
826 ivi_layout_layer_set_visibility(data->layer, is_visible);
827 }
828
829 static int32_t
is_transition_fade_layer_func(struct fade_layer_data * data,struct ivi_layout_layer * layer)830 is_transition_fade_layer_func(struct fade_layer_data *data,
831 struct ivi_layout_layer *layer)
832 {
833 return data->layer == layer;
834 }
835
836 void
ivi_layout_transition_fade_layer(struct ivi_layout_layer * layer,uint32_t is_fade_in,double start_alpha,double end_alpha,void * user_data,ivi_layout_transition_destroy_user_func destroy_func,uint32_t duration)837 ivi_layout_transition_fade_layer(
838 struct ivi_layout_layer *layer,
839 uint32_t is_fade_in,
840 double start_alpha, double end_alpha,
841 void* user_data,
842 ivi_layout_transition_destroy_user_func destroy_func,
843 uint32_t duration)
844 {
845 struct ivi_layout_transition *transition;
846 struct fade_layer_data *data;
847 wl_fixed_t fixed_opacity;
848 double now_opacity;
849 double remain;
850
851 transition = get_transition_from_type_and_id(
852 IVI_LAYOUT_TRANSITION_LAYER_FADE,
853 layer);
854 if (transition) {
855 /* transition update */
856 data = transition->private_data;
857
858 /* FIXME */
859 fixed_opacity = layer->prop.opacity;
860 now_opacity = wl_fixed_to_double(fixed_opacity);
861
862 data->is_fade_in = is_fade_in;
863 data->start_alpha = now_opacity;
864 data->end_alpha = end_alpha;
865
866 remain = is_fade_in? 1.0 - now_opacity : now_opacity;
867 transition->time_start = 0;
868 transition->time_elapsed = 0;
869 transition->time_duration = duration * remain;
870
871 return;
872 }
873
874 transition = create_layout_transition();
875 if (transition == NULL)
876 return;
877
878 data = malloc(sizeof(*data));
879 if (data == NULL) {
880 weston_log("%s: memory allocation fails\n", __func__);
881 free(transition);
882 return;
883 }
884
885 transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
886 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
887
888 transition->private_data = data;
889 transition->user_data = user_data;
890
891 transition->frame_func = transition_fade_layer_user_frame;
892 transition->destroy_func = transition_fade_layer_destroy;
893
894 if (duration != 0)
895 transition->time_duration = duration;
896
897 data->layer = layer;
898 data->is_fade_in = is_fade_in;
899 data->start_alpha = start_alpha;
900 data->end_alpha = end_alpha;
901 data->destroy_func = destroy_func;
902
903 if (!layout_transition_register(transition))
904 layout_transition_destroy(transition);
905
906 return;
907 }
908
909