blob: 904e8d615a2230b4c5f8c32d5510385eb8eb6ade [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
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +090079int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090080is_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
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900159struct ivi_layout_transition_set *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900160ivi_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();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100331 if (transition == NULL)
332 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900333
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100334 struct move_resize_view_data *data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900335 if (data == NULL) {
336 weston_log("%s: memory allocation fails\n", __func__);
337 return NULL;
338 }
339
340 transition->type = IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE;
341 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_resize_view_func;
342
343 transition->frame_func = frame_func;
344 transition->destroy_func = destroy_func;
345 transition->private_data = data;
346
347 if (duration != 0)
348 transition->time_duration = duration;
349
350 data->surface = surface;
351 data->start_x = start_x;
352 data->start_y = start_y;
353 data->end_x = end_x;
354 data->end_y = end_y;
355
356 data->start_width = start_width;
357 data->start_height = start_height;
358 data->end_width = end_width;
359 data->end_height = end_height;
360
361 return transition;
362}
363
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900364void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900365ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface,
366 int32_t dest_x, int32_t dest_y,
367 int32_t dest_width, int32_t dest_height,
368 uint32_t duration)
369{
370 struct ivi_layout_transition *transition;
371 int32_t start_pos[2] = {
372 surface->pending.prop.start_x,
373 surface->pending.prop.start_y
374 };
375
376 int32_t start_size[2] = {
377 surface->pending.prop.start_width,
378 surface->pending.prop.start_height
379 };
380
381 transition = get_transition_from_type_and_id(
382 IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
383 surface);
384 if (transition) {
385 struct move_resize_view_data *data = transition->private_data;
386 transition->time_start = 0;
387 transition->time_duration = duration;
388
389 data->start_x = start_pos[0];
390 data->start_y = start_pos[1];
391 data->end_x = dest_x;
392 data->end_y = dest_y;
393
394 data->start_width = start_size[0];
395 data->start_height = start_size[1];
396 data->end_width = dest_width;
397 data->end_height = dest_height;
398 return;
399 }
400
401 transition = create_move_resize_view_transition(
402 surface,
403 start_pos[0], start_pos[1],
404 dest_x, dest_y,
405 start_size[0], start_size[1],
406 dest_width, dest_height,
407 transition_move_resize_view_user_frame,
408 transition_move_resize_view_destroy,
409 duration);
410
411 layout_transition_register(transition);
412}
413
414/* fade transition */
415struct fade_view_data {
416 struct ivi_layout_surface *surface;
417 double start_alpha;
418 double end_alpha;
419};
420
421struct store_alpha{
422 double alpha;
423};
424
425static void
426fade_view_user_frame(struct ivi_layout_transition *transition)
427{
428 struct fade_view_data *fade = transition->private_data;
429 struct ivi_layout_surface *surface = fade->surface;
430
431 const double current = time_to_nowpos(transition);
432 const double alpha = fade->start_alpha +
433 (fade->end_alpha - fade->start_alpha) * current;
434
435 ivi_layout_surface_set_opacity(surface, wl_fixed_from_double(alpha));
436 ivi_layout_surface_set_visibility(surface, true);
437}
438
439static int32_t
440is_transition_fade_view_func(struct fade_view_data *data,
441 struct ivi_layout_surface *view)
442{
443 return data->surface == view;
444}
445
446static struct ivi_layout_transition *
447create_fade_view_transition(
448 struct ivi_layout_surface *surface,
449 double start_alpha, double end_alpha,
450 ivi_layout_transition_frame_func frame_func,
451 void *user_data,
452 ivi_layout_transition_destroy_func destroy_func,
453 uint32_t duration)
454{
455 struct ivi_layout_transition *transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100456 if (transition == NULL)
457 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900458
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100459 struct fade_view_data *data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900460 if (data == NULL) {
461 weston_log("%s: memory allocation fails\n", __func__);
462 return NULL;
463 }
464
465 transition->type = IVI_LAYOUT_TRANSITION_VIEW_FADE;
466 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_view_func;
467
468 transition->user_data = user_data;
469 transition->private_data = data;
470 transition->frame_func = frame_func;
471 transition->destroy_func = destroy_func;
472
473 if (duration != 0)
474 transition->time_duration = duration;
475
476 data->surface = surface;
477 data->start_alpha = start_alpha;
478 data->end_alpha = end_alpha;
479
480 return transition;
481}
482
483static void
484create_visibility_transition(struct ivi_layout_surface *surface,
485 double start_alpha,
486 double dest_alpha,
487 void *user_data,
488 ivi_layout_transition_destroy_func destroy_func,
489 uint32_t duration)
490{
491 struct ivi_layout_transition *transition = NULL;
492
493 transition = create_fade_view_transition(
494 surface,
495 start_alpha, dest_alpha,
496 fade_view_user_frame,
497 user_data,
498 destroy_func,
499 duration);
500
501 layout_transition_register(transition);
502}
503
504static void
505visibility_on_transition_destroy(struct ivi_layout_transition *transition)
506{
507 struct fade_view_data *data = transition->private_data;
508 struct store_alpha *user_data = transition->user_data;
509
510 ivi_layout_surface_set_visibility(data->surface, true);
511
512 free(data);
513 transition->private_data = NULL;
514
515 free(user_data);
516 transition->user_data = NULL;
517}
518
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900519void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900520ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
521 uint32_t duration)
522{
523 struct ivi_layout_transition *transition;
524 bool is_visible = ivi_layout_surface_get_visibility(surface);
525 wl_fixed_t dest_alpha = ivi_layout_surface_get_opacity(surface);
526 struct store_alpha *user_data = NULL;
527 wl_fixed_t start_alpha = 0.0;
528 struct fade_view_data *data = NULL;
529
530 transition = get_transition_from_type_and_id(
531 IVI_LAYOUT_TRANSITION_VIEW_FADE,
532 surface);
533 if (transition) {
534 start_alpha = ivi_layout_surface_get_opacity(surface);
535 user_data = transition->user_data;
536 data = transition->private_data;
537
538 transition->time_start = 0;
539 transition->time_duration = duration;
540 transition->destroy_func = visibility_on_transition_destroy;
541
542 data->start_alpha = wl_fixed_to_double(start_alpha);
543 data->end_alpha = user_data->alpha;
544 return;
545 }
546
547 if (is_visible)
548 return;
549
550 user_data = malloc(sizeof(*user_data));
551 if (user_data == NULL) {
552 weston_log("%s: memory allocation fails\n", __func__);
553 return;
554 }
555
556 user_data->alpha = wl_fixed_to_double(dest_alpha);
557
558 create_visibility_transition(surface,
559 0.0, // start_alpha
560 wl_fixed_to_double(dest_alpha),
561 user_data,
562 visibility_on_transition_destroy,
563 duration);
564}
565
566static void
567visibility_off_transition_destroy(struct ivi_layout_transition *transition)
568{
569 struct fade_view_data *data = transition->private_data;
570 struct store_alpha *user_data = transition->user_data;
571
572 ivi_layout_surface_set_visibility(data->surface, false);
573
574 ivi_layout_surface_set_opacity(data->surface,
575 wl_fixed_from_double(user_data->alpha));
576
577 free(data);
578 transition->private_data = NULL;
579
580 free(user_data);
581 transition->user_data= NULL;
582}
583
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900584void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900585ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
586 uint32_t duration)
587{
588 struct ivi_layout_transition *transition;
589 wl_fixed_t start_alpha = ivi_layout_surface_get_opacity(surface);
590 struct store_alpha* user_data = NULL;
591 struct fade_view_data* data = NULL;
592
593 transition =
594 get_transition_from_type_and_id(IVI_LAYOUT_TRANSITION_VIEW_FADE,
595 surface);
596 if (transition) {
597 data = transition->private_data;
598
599 transition->time_start = 0;
600 transition->time_duration = duration;
601 transition->destroy_func = visibility_off_transition_destroy;
602
603 data->start_alpha = wl_fixed_to_double(start_alpha);
604 data->end_alpha = 0;
605 return;
606 }
607
608 user_data = malloc(sizeof(*user_data));
609 if (user_data == NULL) {
610 weston_log("%s: memory allocation fails\n", __func__);
611 return;
612 }
613
614 user_data->alpha = wl_fixed_to_double(start_alpha);
615
616 create_visibility_transition(surface,
617 wl_fixed_to_double(start_alpha),
618 0.0, // dest_alpha
619 user_data,
620 visibility_off_transition_destroy,
621 duration);
622}
623
624/* move layer transition */
625
626struct move_layer_data {
627 struct ivi_layout_layer *layer;
628 int32_t start_x;
629 int32_t start_y;
630 int32_t end_x;
631 int32_t end_y;
632 ivi_layout_transition_destroy_user_func destroy_func;
633};
634
635static void
636transition_move_layer_user_frame(struct ivi_layout_transition *transition)
637{
638 struct move_layer_data *data = transition->private_data;
639 struct ivi_layout_layer *layer = data->layer;
640
641 const float current = time_to_nowpos(transition);
642
643 const int32_t dest_x = data->start_x +
644 (data->end_x - data->start_x) * current;
645
646 const int32_t dest_y = data->start_y +
647 (data->end_y - data->start_y) * current;
648
649 ivi_layout_layer_set_position(layer, dest_x, dest_y);
650}
651
652static void
653transition_move_layer_destroy(struct ivi_layout_transition *transition)
654{
655 struct move_layer_data *data = transition->private_data;
656
657 if(data->destroy_func)
658 data->destroy_func(transition->user_data);
659
660 free(data);
661 transition->private_data = NULL;
662}
663
664static int32_t
665is_transition_move_layer_func(struct move_layer_data *data,
666 struct ivi_layout_layer *layer)
667{
668 return data->layer == layer;
669}
670
671
672static struct ivi_layout_transition *
673create_move_layer_transition(
674 struct ivi_layout_layer *layer,
675 int32_t start_x, int32_t start_y,
676 int32_t end_x, int32_t end_y,
677 void *user_data,
678 ivi_layout_transition_destroy_user_func destroy_user_func,
679 uint32_t duration)
680{
681 struct ivi_layout_transition *transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100682 if (transition == NULL)
683 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900684
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100685 struct move_layer_data *data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900686 if (data == NULL) {
687 weston_log("%s: memory allocation fails\n", __func__);
688 return NULL;
689 }
690
691 transition->type = IVI_LAYOUT_TRANSITION_LAYER_MOVE;
692 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_layer_func;
693
694 transition->frame_func = transition_move_layer_user_frame;
695 transition->destroy_func = transition_move_layer_destroy;
696 transition->private_data = data;
697 transition->user_data = user_data;
698
699 if (duration != 0)
700 transition->time_duration = duration;
701
702 data->layer = layer;
703 data->start_x = start_x;
704 data->start_y = start_y;
705 data->end_x = end_x;
706 data->end_y = end_y;
707 data->destroy_func = destroy_user_func;
708
709 return transition;
710}
711
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900712void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900713ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
714 int32_t dest_x, int32_t dest_y,
715 uint32_t duration)
716{
717 int32_t start_pos_x = 0;
718 int32_t start_pos_y = 0;
719 struct ivi_layout_transition *transition = NULL;
720
721 ivi_layout_layer_get_position(layer, &start_pos_x, &start_pos_y);
722
723 transition = create_move_layer_transition(
724 layer,
725 start_pos_x, start_pos_y,
726 dest_x, dest_y,
727 NULL, NULL,
728 duration);
729
730 layout_transition_register(transition);
731
732 return;
733}
734
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900735void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900736ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer)
737{
738 struct ivi_layout_transition *transition =
739 get_transition_from_type_and_id(
740 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
741 layer);
742 if (transition) {
743 layout_transition_destroy(transition);
744 }
745}
746
747/* fade layer transition */
748struct fade_layer_data {
749 struct ivi_layout_layer *layer;
750 uint32_t is_fade_in;
751 double start_alpha;
752 double end_alpha;
753 ivi_layout_transition_destroy_user_func destroy_func;
754};
755
756static void
757transition_fade_layer_destroy(struct ivi_layout_transition *transition)
758{
759 struct fade_layer_data *data = transition->private_data;
760 transition->private_data = NULL;
761
762 free(data);
763}
764
765static void
766transition_fade_layer_user_frame(struct ivi_layout_transition *transition)
767{
768 double current = time_to_nowpos(transition);
769 struct fade_layer_data *data = transition->private_data;
770 double alpha = data->start_alpha +
771 (data->end_alpha - data->start_alpha) * current;
772 wl_fixed_t fixed_alpha = wl_fixed_from_double(alpha);
773
774 int32_t is_done = transition->is_done;
775 bool is_visible = !is_done || data->is_fade_in;
776
777 ivi_layout_layer_set_opacity(data->layer, fixed_alpha);
778 ivi_layout_layer_set_visibility(data->layer, is_visible);
779}
780
781static int32_t
782is_transition_fade_layer_func(struct fade_layer_data *data,
783 struct ivi_layout_layer *layer)
784{
785 return data->layer == layer;
786}
787
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900788void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900789ivi_layout_transition_fade_layer(
790 struct ivi_layout_layer *layer,
791 uint32_t is_fade_in,
792 double start_alpha, double end_alpha,
793 void* user_data,
794 ivi_layout_transition_destroy_user_func destroy_func,
795 uint32_t duration)
796{
797 struct ivi_layout_transition *transition;
798 struct fade_layer_data *data = NULL;
799 wl_fixed_t fixed_opacity = 0.0;
800 double now_opacity = 0.0;
801 double remain = 0.0;
802
803 transition = get_transition_from_type_and_id(
804 IVI_LAYOUT_TRANSITION_LAYER_FADE,
805 layer);
806 if (transition) {
807 /* transition update */
808 data = transition->private_data;
809
810 /* FIXME */
811 fixed_opacity = ivi_layout_layer_get_opacity(layer);
812 now_opacity = wl_fixed_to_double(fixed_opacity);
813 remain = 0.0;
814
815 data->is_fade_in = is_fade_in;
816 data->start_alpha = now_opacity;
817 data->end_alpha = end_alpha;
818
819 remain = is_fade_in? 1.0 - now_opacity : now_opacity;
820 transition->time_start = 0;
821 transition->time_elapsed = 0;
822 transition->time_duration = duration * remain;
823
824 return;
825 }
826
827 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100828 if (transition == NULL)
829 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900830
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100831 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900832 if (data == NULL) {
833 weston_log("%s: memory allocation fails\n", __func__);
834 return;
835 }
836
837 transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
838 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
839
840 transition->private_data = data;
841 transition->user_data = user_data;
842
843 transition->frame_func = transition_fade_layer_user_frame;
844 transition->destroy_func = transition_fade_layer_destroy;
845
846 if (duration != 0)
847 transition->time_duration = duration;
848
849 data->layer = layer;
850 data->is_fade_in = is_fade_in;
851 data->start_alpha = start_alpha;
852 data->end_alpha = end_alpha;
853 data->destroy_func = destroy_func;
854
855 layout_transition_register(transition);
856
857 return;
858}
859