blob: e4ab5bb9c9c4369d5c474260df9fc6dff50622c5 [file] [log] [blame]
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001/*
2 * Copyright (C) 2014 DENSO CORPORATION
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#include <time.h>
24#include <assert.h>
25#include <stdlib.h>
26#include <stdio.h>
27
28#include "ivi-layout-export.h"
29#include "ivi-layout-private.h"
30
31struct ivi_layout_transition;
32
33typedef void (*ivi_layout_transition_frame_func)(
34 struct ivi_layout_transition *transition);
35typedef void (*ivi_layout_transition_destroy_func)(
36 struct ivi_layout_transition *transition);
37typedef int32_t (*ivi_layout_is_transition_func)(void *private_data, void *id);
38
39struct ivi_layout_transition {
40 enum ivi_layout_transition_type type;
41 void *private_data;
42 void *user_data;
43
44 uint32_t time_start;
45 uint32_t time_duration;
46 uint32_t time_elapsed;
47 uint32_t is_done;
48 ivi_layout_is_transition_func is_transition_func;
49 ivi_layout_transition_frame_func frame_func;
50 ivi_layout_transition_destroy_func destroy_func;
51};
52
53struct transition_node {
54 struct ivi_layout_transition *transition;
55 struct wl_list link;
56};
57
58static void layout_transition_destroy(struct ivi_layout_transition *transition);
59
60static struct ivi_layout_transition *
61get_transition_from_type_and_id(enum ivi_layout_transition_type type,
62 void *id_data)
63{
64 struct ivi_layout *layout = get_instance();
65 struct transition_node *node;
66 struct ivi_layout_transition *tran;
67
68 wl_list_for_each(node, &layout->transitions->transition_list, link) {
69 tran = node->transition;
70
71 if (tran->type == type &&
72 tran->is_transition_func(tran->private_data, id_data))
73 return tran;
74 }
75
76 return NULL;
77}
78
79WL_EXPORT int32_t
80is_surface_transition(struct ivi_layout_surface *surface)
81{
82 struct ivi_layout *layout = get_instance();
83 struct transition_node *node;
84 struct ivi_layout_transition *tran;
85
86 wl_list_for_each(node, &layout->transitions->transition_list, link) {
87 tran = node->transition;
88
89 if ((tran->type == IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE ||
90 tran->type == IVI_LAYOUT_TRANSITION_VIEW_RESIZE) &&
91 tran->is_transition_func(tran->private_data, surface))
92 return 1;
93 }
94
95 return 0;
96}
97
98static void
99tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp)
100{
101 const double t = timestamp - transition->time_start;
102
103 if (transition->time_duration <= t) {
104 transition->time_elapsed = transition->time_duration;
105 transition->is_done = 1;
106 } else {
107 transition->time_elapsed = t;
108 }
109}
110
111static float time_to_nowpos(struct ivi_layout_transition *transition)
112{
113 return sin((float)transition->time_elapsed /
114 (float)transition->time_duration * M_PI_2);
115}
116
117static void
118do_transition_frame(struct ivi_layout_transition *transition,
119 uint32_t timestamp)
120{
121 if (0 == transition->time_start)
122 transition->time_start = timestamp;
123
124 tick_transition(transition, timestamp);
125 transition->frame_func(transition);
126
127 if (transition->is_done)
128 layout_transition_destroy(transition);
129}
130
131static int32_t
132layout_transition_frame(void *data)
133{
134 struct ivi_layout_transition_set *transitions = data;
135 uint32_t fps = 30;
136 struct timespec timestamp = {};
137 uint32_t msec = 0;
138 struct transition_node *node = NULL;
139 struct transition_node *next = NULL;
140
141 if (wl_list_empty(&transitions->transition_list)) {
142 wl_event_source_timer_update(transitions->event_source, 0);
143 return 1;
144 }
145
146 wl_event_source_timer_update(transitions->event_source, 1000 / fps);
147
148 clock_gettime(CLOCK_MONOTONIC, &timestamp);/* FIXME */
149 msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec);
150
151 wl_list_for_each_safe(node, next, &transitions->transition_list, link) {
152 do_transition_frame(node->transition, msec);
153 }
154
155 ivi_layout_commit_changes();
156 return 1;
157}
158
159WL_EXPORT struct ivi_layout_transition_set *
160ivi_layout_transition_set_create(struct weston_compositor *ec)
161{
162 struct ivi_layout_transition_set *transitions;
163 struct wl_event_loop *loop;
164
165 transitions = malloc(sizeof(*transitions));
166 if (transitions == NULL) {
167 weston_log("%s: memory allocation fails\n", __func__);
168 return NULL;
169 }
170
171 wl_list_init(&transitions->transition_list);
172
173 loop = wl_display_get_event_loop(ec->wl_display);
174 transitions->event_source =
175 wl_event_loop_add_timer(loop, layout_transition_frame,
176 transitions);
177
178 return transitions;
179}
180
181static void
182layout_transition_register(struct ivi_layout_transition *trans)
183{
184 struct ivi_layout *layout = get_instance();
185 struct transition_node *node;
186
187 node = malloc(sizeof(*node));
188 if (node == NULL) {
189 weston_log("%s: memory allocation fails\n", __func__);
190 return;
191 }
192
193 node->transition = trans;
194 wl_list_insert(&layout->pending_transition_list, &node->link);
195}
196
197static void
198remove_transition(struct ivi_layout *layout,
199 struct ivi_layout_transition *trans)
200{
201 struct transition_node *node;
202 struct transition_node *next;
203
204 wl_list_for_each_safe(node, next,
205 &layout->transitions->transition_list, link) {
206 if (node->transition == trans) {
207 wl_list_remove(&node->link);
208 free(node);
209 return;
210 }
211 }
212
213 wl_list_for_each_safe(node, next,
214 &layout->pending_transition_list, link) {
215 if (node->transition == trans) {
216 wl_list_remove(&node->link);
217 free(node);
218 return;
219 }
220 }
221}
222
223static void
224layout_transition_destroy(struct ivi_layout_transition *transition)
225{
226 struct ivi_layout *layout = get_instance();
227
228 remove_transition(layout, transition);
229 if(transition->destroy_func)
230 transition->destroy_func(transition);
231 free(transition);
232}
233
234static struct ivi_layout_transition *
235create_layout_transition(void)
236{
237 struct ivi_layout_transition *transition = malloc(sizeof(*transition));
238
239 if (transition == NULL) {
240 weston_log("%s: memory allocation fails\n", __func__);
241 return NULL;
242 }
243
244 transition->type = IVI_LAYOUT_TRANSITION_MAX;
245 transition->time_start = 0;
246 transition->time_duration = 300; /* 300ms */
247 transition->time_elapsed = 0;
248
249 transition->is_done = 0;
250
251 transition->private_data = NULL;
252 transition->user_data = NULL;
253
254 transition->frame_func = NULL;
255 transition->destroy_func = NULL;
256
257 return transition;
258}
259
260/* move and resize view transition */
261
262struct move_resize_view_data {
263 struct ivi_layout_surface *surface;
264 int32_t start_x;
265 int32_t start_y;
266 int32_t end_x;
267 int32_t end_y;
268 int32_t start_width;
269 int32_t start_height;
270 int32_t end_width;
271 int32_t end_height;
272};
273
274static void
275transition_move_resize_view_destroy(struct ivi_layout_transition *transition)
276{
277 struct move_resize_view_data *data =
278 (struct move_resize_view_data *)transition->private_data;
279 struct ivi_layout_surface *layout_surface = data->surface;
280
281 wl_signal_emit(&layout_surface->configured, layout_surface);
282
283 if (transition->private_data) {
284 free(transition->private_data);
285 transition->private_data = NULL;
286 }
287}
288
289static void
290transition_move_resize_view_user_frame(struct ivi_layout_transition *transition)
291{
292 struct move_resize_view_data *mrv = transition->private_data;
293 const double current = time_to_nowpos(transition);
294
295 const int32_t destx = mrv->start_x +
296 (mrv->end_x - mrv->start_x) * current;
297
298 const int32_t desty = mrv->start_y +
299 (mrv->end_y - mrv->start_y) * current;
300
301 const int32_t dest_width = mrv->start_width +
302 (mrv->end_width - mrv->start_width) * current;
303
304 const int32_t dest_height = mrv->start_height +
305 (mrv->end_height - mrv->start_height) * current;
306
307 ivi_layout_surface_set_destination_rectangle(mrv->surface,
308 destx, desty,
309 dest_width, dest_height);
310}
311
312static int32_t
313is_transition_move_resize_view_func(struct move_resize_view_data *data,
314 struct ivi_layout_surface *view)
315{
316 return data->surface == view;
317}
318
319static struct ivi_layout_transition *
320create_move_resize_view_transition(
321 struct ivi_layout_surface *surface,
322 int32_t start_x, int32_t start_y,
323 int32_t end_x, int32_t end_y,
324 int32_t start_width, int32_t start_height,
325 int32_t end_width, int32_t end_height,
326 ivi_layout_transition_frame_func frame_func,
327 ivi_layout_transition_destroy_func destroy_func,
328 uint32_t duration)
329{
330 struct ivi_layout_transition *transition = create_layout_transition();
331 struct move_resize_view_data *data = malloc(sizeof(*data));
332
333 if (data == NULL) {
334 weston_log("%s: memory allocation fails\n", __func__);
335 return NULL;
336 }
337
338 transition->type = IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE;
339 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_resize_view_func;
340
341 transition->frame_func = frame_func;
342 transition->destroy_func = destroy_func;
343 transition->private_data = data;
344
345 if (duration != 0)
346 transition->time_duration = duration;
347
348 data->surface = surface;
349 data->start_x = start_x;
350 data->start_y = start_y;
351 data->end_x = end_x;
352 data->end_y = end_y;
353
354 data->start_width = start_width;
355 data->start_height = start_height;
356 data->end_width = end_width;
357 data->end_height = end_height;
358
359 return transition;
360}
361
362WL_EXPORT void
363ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface,
364 int32_t dest_x, int32_t dest_y,
365 int32_t dest_width, int32_t dest_height,
366 uint32_t duration)
367{
368 struct ivi_layout_transition *transition;
369 int32_t start_pos[2] = {
370 surface->pending.prop.start_x,
371 surface->pending.prop.start_y
372 };
373
374 int32_t start_size[2] = {
375 surface->pending.prop.start_width,
376 surface->pending.prop.start_height
377 };
378
379 transition = get_transition_from_type_and_id(
380 IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
381 surface);
382 if (transition) {
383 struct move_resize_view_data *data = transition->private_data;
384 transition->time_start = 0;
385 transition->time_duration = duration;
386
387 data->start_x = start_pos[0];
388 data->start_y = start_pos[1];
389 data->end_x = dest_x;
390 data->end_y = dest_y;
391
392 data->start_width = start_size[0];
393 data->start_height = start_size[1];
394 data->end_width = dest_width;
395 data->end_height = dest_height;
396 return;
397 }
398
399 transition = create_move_resize_view_transition(
400 surface,
401 start_pos[0], start_pos[1],
402 dest_x, dest_y,
403 start_size[0], start_size[1],
404 dest_width, dest_height,
405 transition_move_resize_view_user_frame,
406 transition_move_resize_view_destroy,
407 duration);
408
409 layout_transition_register(transition);
410}
411
412/* fade transition */
413struct fade_view_data {
414 struct ivi_layout_surface *surface;
415 double start_alpha;
416 double end_alpha;
417};
418
419struct store_alpha{
420 double alpha;
421};
422
423static void
424fade_view_user_frame(struct ivi_layout_transition *transition)
425{
426 struct fade_view_data *fade = transition->private_data;
427 struct ivi_layout_surface *surface = fade->surface;
428
429 const double current = time_to_nowpos(transition);
430 const double alpha = fade->start_alpha +
431 (fade->end_alpha - fade->start_alpha) * current;
432
433 ivi_layout_surface_set_opacity(surface, wl_fixed_from_double(alpha));
434 ivi_layout_surface_set_visibility(surface, true);
435}
436
437static int32_t
438is_transition_fade_view_func(struct fade_view_data *data,
439 struct ivi_layout_surface *view)
440{
441 return data->surface == view;
442}
443
444static struct ivi_layout_transition *
445create_fade_view_transition(
446 struct ivi_layout_surface *surface,
447 double start_alpha, double end_alpha,
448 ivi_layout_transition_frame_func frame_func,
449 void *user_data,
450 ivi_layout_transition_destroy_func destroy_func,
451 uint32_t duration)
452{
453 struct ivi_layout_transition *transition = create_layout_transition();
454 struct fade_view_data *data = malloc(sizeof(*data));
455
456 if (data == NULL) {
457 weston_log("%s: memory allocation fails\n", __func__);
458 return NULL;
459 }
460
461 transition->type = IVI_LAYOUT_TRANSITION_VIEW_FADE;
462 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_view_func;
463
464 transition->user_data = user_data;
465 transition->private_data = data;
466 transition->frame_func = frame_func;
467 transition->destroy_func = destroy_func;
468
469 if (duration != 0)
470 transition->time_duration = duration;
471
472 data->surface = surface;
473 data->start_alpha = start_alpha;
474 data->end_alpha = end_alpha;
475
476 return transition;
477}
478
479static void
480create_visibility_transition(struct ivi_layout_surface *surface,
481 double start_alpha,
482 double dest_alpha,
483 void *user_data,
484 ivi_layout_transition_destroy_func destroy_func,
485 uint32_t duration)
486{
487 struct ivi_layout_transition *transition = NULL;
488
489 transition = create_fade_view_transition(
490 surface,
491 start_alpha, dest_alpha,
492 fade_view_user_frame,
493 user_data,
494 destroy_func,
495 duration);
496
497 layout_transition_register(transition);
498}
499
500static void
501visibility_on_transition_destroy(struct ivi_layout_transition *transition)
502{
503 struct fade_view_data *data = transition->private_data;
504 struct store_alpha *user_data = transition->user_data;
505
506 ivi_layout_surface_set_visibility(data->surface, true);
507
508 free(data);
509 transition->private_data = NULL;
510
511 free(user_data);
512 transition->user_data = NULL;
513}
514
515WL_EXPORT void
516ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
517 uint32_t duration)
518{
519 struct ivi_layout_transition *transition;
520 bool is_visible = ivi_layout_surface_get_visibility(surface);
521 wl_fixed_t dest_alpha = ivi_layout_surface_get_opacity(surface);
522 struct store_alpha *user_data = NULL;
523 wl_fixed_t start_alpha = 0.0;
524 struct fade_view_data *data = NULL;
525
526 transition = get_transition_from_type_and_id(
527 IVI_LAYOUT_TRANSITION_VIEW_FADE,
528 surface);
529 if (transition) {
530 start_alpha = ivi_layout_surface_get_opacity(surface);
531 user_data = transition->user_data;
532 data = transition->private_data;
533
534 transition->time_start = 0;
535 transition->time_duration = duration;
536 transition->destroy_func = visibility_on_transition_destroy;
537
538 data->start_alpha = wl_fixed_to_double(start_alpha);
539 data->end_alpha = user_data->alpha;
540 return;
541 }
542
543 if (is_visible)
544 return;
545
546 user_data = malloc(sizeof(*user_data));
547 if (user_data == NULL) {
548 weston_log("%s: memory allocation fails\n", __func__);
549 return;
550 }
551
552 user_data->alpha = wl_fixed_to_double(dest_alpha);
553
554 create_visibility_transition(surface,
555 0.0, // start_alpha
556 wl_fixed_to_double(dest_alpha),
557 user_data,
558 visibility_on_transition_destroy,
559 duration);
560}
561
562static void
563visibility_off_transition_destroy(struct ivi_layout_transition *transition)
564{
565 struct fade_view_data *data = transition->private_data;
566 struct store_alpha *user_data = transition->user_data;
567
568 ivi_layout_surface_set_visibility(data->surface, false);
569
570 ivi_layout_surface_set_opacity(data->surface,
571 wl_fixed_from_double(user_data->alpha));
572
573 free(data);
574 transition->private_data = NULL;
575
576 free(user_data);
577 transition->user_data= NULL;
578}
579
580WL_EXPORT void
581ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
582 uint32_t duration)
583{
584 struct ivi_layout_transition *transition;
585 wl_fixed_t start_alpha = ivi_layout_surface_get_opacity(surface);
586 struct store_alpha* user_data = NULL;
587 struct fade_view_data* data = NULL;
588
589 transition =
590 get_transition_from_type_and_id(IVI_LAYOUT_TRANSITION_VIEW_FADE,
591 surface);
592 if (transition) {
593 data = transition->private_data;
594
595 transition->time_start = 0;
596 transition->time_duration = duration;
597 transition->destroy_func = visibility_off_transition_destroy;
598
599 data->start_alpha = wl_fixed_to_double(start_alpha);
600 data->end_alpha = 0;
601 return;
602 }
603
604 user_data = malloc(sizeof(*user_data));
605 if (user_data == NULL) {
606 weston_log("%s: memory allocation fails\n", __func__);
607 return;
608 }
609
610 user_data->alpha = wl_fixed_to_double(start_alpha);
611
612 create_visibility_transition(surface,
613 wl_fixed_to_double(start_alpha),
614 0.0, // dest_alpha
615 user_data,
616 visibility_off_transition_destroy,
617 duration);
618}
619
620/* move layer transition */
621
622struct move_layer_data {
623 struct ivi_layout_layer *layer;
624 int32_t start_x;
625 int32_t start_y;
626 int32_t end_x;
627 int32_t end_y;
628 ivi_layout_transition_destroy_user_func destroy_func;
629};
630
631static void
632transition_move_layer_user_frame(struct ivi_layout_transition *transition)
633{
634 struct move_layer_data *data = transition->private_data;
635 struct ivi_layout_layer *layer = data->layer;
636
637 const float current = time_to_nowpos(transition);
638
639 const int32_t dest_x = data->start_x +
640 (data->end_x - data->start_x) * current;
641
642 const int32_t dest_y = data->start_y +
643 (data->end_y - data->start_y) * current;
644
645 ivi_layout_layer_set_position(layer, dest_x, dest_y);
646}
647
648static void
649transition_move_layer_destroy(struct ivi_layout_transition *transition)
650{
651 struct move_layer_data *data = transition->private_data;
652
653 if(data->destroy_func)
654 data->destroy_func(transition->user_data);
655
656 free(data);
657 transition->private_data = NULL;
658}
659
660static int32_t
661is_transition_move_layer_func(struct move_layer_data *data,
662 struct ivi_layout_layer *layer)
663{
664 return data->layer == layer;
665}
666
667
668static struct ivi_layout_transition *
669create_move_layer_transition(
670 struct ivi_layout_layer *layer,
671 int32_t start_x, int32_t start_y,
672 int32_t end_x, int32_t end_y,
673 void *user_data,
674 ivi_layout_transition_destroy_user_func destroy_user_func,
675 uint32_t duration)
676{
677 struct ivi_layout_transition *transition = create_layout_transition();
678 struct move_layer_data *data = malloc(sizeof(*data));
679
680 if (data == NULL) {
681 weston_log("%s: memory allocation fails\n", __func__);
682 return NULL;
683 }
684
685 transition->type = IVI_LAYOUT_TRANSITION_LAYER_MOVE;
686 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_layer_func;
687
688 transition->frame_func = transition_move_layer_user_frame;
689 transition->destroy_func = transition_move_layer_destroy;
690 transition->private_data = data;
691 transition->user_data = user_data;
692
693 if (duration != 0)
694 transition->time_duration = duration;
695
696 data->layer = layer;
697 data->start_x = start_x;
698 data->start_y = start_y;
699 data->end_x = end_x;
700 data->end_y = end_y;
701 data->destroy_func = destroy_user_func;
702
703 return transition;
704}
705
706WL_EXPORT void
707ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
708 int32_t dest_x, int32_t dest_y,
709 uint32_t duration)
710{
711 int32_t start_pos_x = 0;
712 int32_t start_pos_y = 0;
713 struct ivi_layout_transition *transition = NULL;
714
715 ivi_layout_layer_get_position(layer, &start_pos_x, &start_pos_y);
716
717 transition = create_move_layer_transition(
718 layer,
719 start_pos_x, start_pos_y,
720 dest_x, dest_y,
721 NULL, NULL,
722 duration);
723
724 layout_transition_register(transition);
725
726 return;
727}
728
729WL_EXPORT void
730ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer)
731{
732 struct ivi_layout_transition *transition =
733 get_transition_from_type_and_id(
734 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
735 layer);
736 if (transition) {
737 layout_transition_destroy(transition);
738 }
739}
740
741/* fade layer transition */
742struct fade_layer_data {
743 struct ivi_layout_layer *layer;
744 uint32_t is_fade_in;
745 double start_alpha;
746 double end_alpha;
747 ivi_layout_transition_destroy_user_func destroy_func;
748};
749
750static void
751transition_fade_layer_destroy(struct ivi_layout_transition *transition)
752{
753 struct fade_layer_data *data = transition->private_data;
754 transition->private_data = NULL;
755
756 free(data);
757}
758
759static void
760transition_fade_layer_user_frame(struct ivi_layout_transition *transition)
761{
762 double current = time_to_nowpos(transition);
763 struct fade_layer_data *data = transition->private_data;
764 double alpha = data->start_alpha +
765 (data->end_alpha - data->start_alpha) * current;
766 wl_fixed_t fixed_alpha = wl_fixed_from_double(alpha);
767
768 int32_t is_done = transition->is_done;
769 bool is_visible = !is_done || data->is_fade_in;
770
771 ivi_layout_layer_set_opacity(data->layer, fixed_alpha);
772 ivi_layout_layer_set_visibility(data->layer, is_visible);
773}
774
775static int32_t
776is_transition_fade_layer_func(struct fade_layer_data *data,
777 struct ivi_layout_layer *layer)
778{
779 return data->layer == layer;
780}
781
782WL_EXPORT void
783ivi_layout_transition_fade_layer(
784 struct ivi_layout_layer *layer,
785 uint32_t is_fade_in,
786 double start_alpha, double end_alpha,
787 void* user_data,
788 ivi_layout_transition_destroy_user_func destroy_func,
789 uint32_t duration)
790{
791 struct ivi_layout_transition *transition;
792 struct fade_layer_data *data = NULL;
793 wl_fixed_t fixed_opacity = 0.0;
794 double now_opacity = 0.0;
795 double remain = 0.0;
796
797 transition = get_transition_from_type_and_id(
798 IVI_LAYOUT_TRANSITION_LAYER_FADE,
799 layer);
800 if (transition) {
801 /* transition update */
802 data = transition->private_data;
803
804 /* FIXME */
805 fixed_opacity = ivi_layout_layer_get_opacity(layer);
806 now_opacity = wl_fixed_to_double(fixed_opacity);
807 remain = 0.0;
808
809 data->is_fade_in = is_fade_in;
810 data->start_alpha = now_opacity;
811 data->end_alpha = end_alpha;
812
813 remain = is_fade_in? 1.0 - now_opacity : now_opacity;
814 transition->time_start = 0;
815 transition->time_elapsed = 0;
816 transition->time_duration = duration * remain;
817
818 return;
819 }
820
821 transition = create_layout_transition();
822 data = malloc(sizeof(*data));
823
824 if (data == NULL) {
825 weston_log("%s: memory allocation fails\n", __func__);
826 return;
827 }
828
829 transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
830 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
831
832 transition->private_data = data;
833 transition->user_data = user_data;
834
835 transition->frame_func = transition_fade_layer_user_frame;
836 transition->destroy_func = transition_fade_layer_destroy;
837
838 if (duration != 0)
839 transition->time_duration = duration;
840
841 data->layer = layer;
842 data->is_fade_in = is_fade_in;
843 data->start_alpha = start_alpha;
844 data->end_alpha = end_alpha;
845 data->destroy_func = destroy_func;
846
847 layout_transition_register(transition);
848
849 return;
850}
851
852/* render order transition */
853struct surface_reorder {
854 uint32_t id_surface;
855 uint32_t new_index;
856};
857
858struct change_order_data {
859 struct ivi_layout_layer *layer;
860 uint32_t surface_num;
861 struct surface_reorder *reorder;
862};
863
864struct surf_with_index {
865 uint32_t id_surface;
866 float surface_index;
867};
868
869static int
870cmp_order_asc(const void *lhs, const void *rhs)
871{
872 const struct surf_with_index *l = lhs;
873 const struct surf_with_index *r = rhs;
874
875 return l->surface_index > r->surface_index;
876}
877
878/*
879render oerder transition
880
881index 0 1 2
882old surfA, surfB, surfC
883new surfB, surfC, surfA
884 (-1) (-1) (+2)
885
886after 10% of time elapsed
887 0.2 0.9 1.9
888 surfA, surfB, surfC
889
890after 50% of time elapsed
891 0.5 1.0 1.5
892 surfB, surfA, surfC
893*/
894
895static void
896transition_change_order_user_frame(struct ivi_layout_transition *transition)
897{
898 uint32_t i, old_index;
899 double current = time_to_nowpos(transition);
900 struct change_order_data *data = transition->private_data;
901
902 struct surf_with_index *swi = malloc(sizeof(*swi) * data->surface_num);
903 struct ivi_layout_surface **new_surface_order = NULL;
904 uint32_t surface_num = 0;
905
906 if (swi == NULL) {
907 weston_log("%s: memory allocation fails\n", __func__);
908 return;
909 }
910
911 for (old_index = 0; old_index < data->surface_num; old_index++) {
912 swi[old_index].id_surface = data->reorder[old_index].id_surface;
913 swi[old_index].surface_index = (float)old_index +
914 ((float)data->reorder[old_index].new_index - (float)old_index) * current;
915 }
916
917 qsort(swi, data->surface_num, sizeof(*swi), cmp_order_asc);
918
919 new_surface_order =
920 malloc(sizeof(*new_surface_order) * data->surface_num);
921
922 if (new_surface_order == NULL) {
923 weston_log("%s: memory allocation fails\n", __func__);
924 return;
925 }
926
927 for (i = 0; i < data->surface_num; i++) {
928 struct ivi_layout_surface *surf =
929 ivi_layout_get_surface_from_id(swi[i].id_surface);
930 if(surf)
931 new_surface_order[surface_num++] = surf;
932 }
933
934 ivi_layout_layer_set_render_order(data->layer, new_surface_order,
935 surface_num);
936
937 free(new_surface_order);
938 free(swi);
939}
940
941static void
942transition_change_order_destroy(struct ivi_layout_transition *transition)
943{
944 struct change_order_data *data = transition->private_data;
945
946 free(data->reorder);
947 free(data);
948}
949
950static int32_t find_surface(struct ivi_layout_surface **surfaces,
951 uint32_t surface_num,
952 struct ivi_layout_surface *target)
953{
954 uint32_t i = 0;
955
956 for(i = 0; i < surface_num; i++) {
957 if (surfaces[i] == target)
958 return i;
959 }
960
961 return -1;
962}
963
964static int32_t
965is_transition_change_order_func(struct change_order_data *data,
966 struct ivi_layout_layer *layer)
967{
968 return data->layer == layer;
969}
970
971WL_EXPORT void
972ivi_layout_transition_layer_render_order(struct ivi_layout_layer *layer,
973 struct ivi_layout_surface **new_order,
974 uint32_t surface_num,
975 uint32_t duration)
976{
977 struct surface_reorder *reorder;
978 struct ivi_layout_surface *surf;
979 uint32_t old_index = 0;
980 struct ivi_layout_transition *transition;
981 struct change_order_data *data = NULL;
982 int32_t new_index = 0;
983 uint32_t id = 0;
984
985 reorder = malloc(sizeof(*reorder) * surface_num);
986 if (reorder == NULL) {
987 weston_log("%s: memory allocation fails\n", __func__);
988 return;
989 }
990
991 wl_list_for_each(surf, &layer->order.surface_list, order.link) {
992 new_index = find_surface(new_order, surface_num, surf);
993 id = ivi_layout_get_id_of_surface(surf);
994 if(new_index < 0){
995 fprintf(stderr, "invalid render order!!!\n");
996 return;
997 }
998
999 reorder[old_index].id_surface = id;
1000 reorder[old_index].new_index = new_index;
1001 old_index++;
1002 }
1003
1004 transition = get_transition_from_type_and_id(
1005 IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
1006 layer);
1007 if (transition) {
1008 /* update transition */
1009 struct change_order_data *data = transition->private_data;
1010 transition->time_start = 0; /* timer reset */
1011
1012 if (duration != 0) {
1013 transition->time_duration = duration;
1014 }
1015
1016 free(data->reorder);
1017 data->reorder = reorder;
1018 return;
1019 }
1020
1021 transition = create_layout_transition();
1022 data = malloc(sizeof(*data));
1023
1024 if (data == NULL) {
1025 weston_log("%s: memory allocation fails\n", __func__);
1026 return;
1027 }
1028
1029 transition->type = IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER;
1030 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_change_order_func;
1031
1032 transition->private_data = data;
1033 transition->frame_func = transition_change_order_user_frame;
1034 transition->destroy_func = transition_change_order_destroy;
1035
1036 if (duration != 0)
1037 transition->time_duration = duration;
1038
1039 data->layer = layer;
1040 data->reorder = reorder;
1041 data->surface_num = old_index;
1042
1043 layout_transition_register(transition);
1044}
1045
1046WL_EXPORT int32_t
1047ivi_layout_surface_set_transition(struct ivi_layout_surface *ivisurf,
1048 enum ivi_layout_transition_type type,
1049 uint32_t duration)
1050{
1051 struct ivi_layout_surface_properties *prop;
1052
1053 if (ivisurf == NULL) {
1054 weston_log("%s: invalid argument\n", __func__);
1055 return -1;
1056 }
1057
1058 prop = &ivisurf->pending.prop;
1059 prop->transition_type = type;
1060 prop->transition_duration = duration;
1061 return 0;
1062}
1063
1064int32_t
1065ivi_layout_surface_set_transition_duration(struct ivi_layout_surface *ivisurf,
1066 uint32_t duration)
1067{
1068 struct ivi_layout_surface_properties *prop;
1069
1070 if (ivisurf == NULL) {
1071 weston_log("%s: invalid argument\n", __func__);
1072 return -1;
1073 }
1074
1075 prop = &ivisurf->pending.prop;
1076 prop->transition_duration = duration*10;
1077 return 0;
1078}
1079
1080WL_EXPORT int32_t
1081ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer,
1082 enum ivi_layout_transition_type type,
1083 uint32_t duration)
1084{
1085 if (ivilayer == NULL) {
1086 weston_log("%s: invalid argument\n", __func__);
1087 return -1;
1088 }
1089
1090 ivilayer->pending.prop.transition_type = type;
1091 ivilayer->pending.prop.transition_duration = duration;
1092
1093 return 0;
1094}
1095
1096WL_EXPORT int32_t
1097ivi_layout_layer_set_fade_info(struct ivi_layout_layer* ivilayer,
1098 uint32_t is_fade_in,
1099 double start_alpha, double end_alpha)
1100{
1101 if (ivilayer == NULL) {
1102 weston_log("%s: invalid argument\n", __func__);
1103 return -1;
1104 }
1105
1106 ivilayer->pending.prop.is_fade_in = is_fade_in;
1107 ivilayer->pending.prop.start_alpha = start_alpha;
1108 ivilayer->pending.prop.end_alpha = end_alpha;
1109
1110 return 0;
1111}