blob: 3b613a5e68932d1979ae4316e7470384d01f2926 [file] [log] [blame]
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001/*
2 * Copyright (C) 2014 DENSO CORPORATION
3 *
Bryce Harringtonaf637c22015-06-11 12:55:55 -07004 * 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:
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090011 *
Bryce Harringtonaf637c22015-06-11 12:55:55 -070012 * 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.
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090024 */
25
26#include <time.h>
27#include <assert.h>
28#include <stdlib.h>
29#include <stdio.h>
Lucas Tanure9b5fe422015-09-21 14:10:32 -030030#include <stdbool.h>
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090031
32#include "ivi-layout-export.h"
33#include "ivi-layout-private.h"
34
35struct ivi_layout_transition;
36
37typedef void (*ivi_layout_transition_frame_func)(
38 struct ivi_layout_transition *transition);
39typedef void (*ivi_layout_transition_destroy_func)(
40 struct ivi_layout_transition *transition);
41typedef int32_t (*ivi_layout_is_transition_func)(void *private_data, void *id);
42
43struct ivi_layout_transition {
44 enum ivi_layout_transition_type type;
45 void *private_data;
46 void *user_data;
47
48 uint32_t time_start;
49 uint32_t time_duration;
50 uint32_t time_elapsed;
51 uint32_t is_done;
52 ivi_layout_is_transition_func is_transition_func;
53 ivi_layout_transition_frame_func frame_func;
54 ivi_layout_transition_destroy_func destroy_func;
55};
56
57struct transition_node {
58 struct ivi_layout_transition *transition;
59 struct wl_list link;
60};
61
62static void layout_transition_destroy(struct ivi_layout_transition *transition);
63
64static struct ivi_layout_transition *
65get_transition_from_type_and_id(enum ivi_layout_transition_type type,
66 void *id_data)
67{
68 struct ivi_layout *layout = get_instance();
69 struct transition_node *node;
70 struct ivi_layout_transition *tran;
71
72 wl_list_for_each(node, &layout->transitions->transition_list, link) {
73 tran = node->transition;
74
75 if (tran->type == type &&
76 tran->is_transition_func(tran->private_data, id_data))
77 return tran;
78 }
79
80 return NULL;
81}
82
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +090083int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090084is_surface_transition(struct ivi_layout_surface *surface)
85{
86 struct ivi_layout *layout = get_instance();
87 struct transition_node *node;
88 struct ivi_layout_transition *tran;
89
90 wl_list_for_each(node, &layout->transitions->transition_list, link) {
91 tran = node->transition;
92
93 if ((tran->type == IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE ||
94 tran->type == IVI_LAYOUT_TRANSITION_VIEW_RESIZE) &&
95 tran->is_transition_func(tran->private_data, surface))
96 return 1;
97 }
98
99 return 0;
100}
101
102static void
103tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp)
104{
105 const double t = timestamp - transition->time_start;
106
107 if (transition->time_duration <= t) {
108 transition->time_elapsed = transition->time_duration;
109 transition->is_done = 1;
110 } else {
111 transition->time_elapsed = t;
112 }
113}
114
115static float time_to_nowpos(struct ivi_layout_transition *transition)
116{
117 return sin((float)transition->time_elapsed /
118 (float)transition->time_duration * M_PI_2);
119}
120
121static void
122do_transition_frame(struct ivi_layout_transition *transition,
123 uint32_t timestamp)
124{
125 if (0 == transition->time_start)
126 transition->time_start = timestamp;
127
128 tick_transition(transition, timestamp);
129 transition->frame_func(transition);
130
131 if (transition->is_done)
132 layout_transition_destroy(transition);
133}
134
135static int32_t
136layout_transition_frame(void *data)
137{
138 struct ivi_layout_transition_set *transitions = data;
139 uint32_t fps = 30;
140 struct timespec timestamp = {};
141 uint32_t msec = 0;
142 struct transition_node *node = NULL;
143 struct transition_node *next = NULL;
144
145 if (wl_list_empty(&transitions->transition_list)) {
146 wl_event_source_timer_update(transitions->event_source, 0);
147 return 1;
148 }
149
150 wl_event_source_timer_update(transitions->event_source, 1000 / fps);
151
152 clock_gettime(CLOCK_MONOTONIC, &timestamp);/* FIXME */
153 msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec);
154
155 wl_list_for_each_safe(node, next, &transitions->transition_list, link) {
156 do_transition_frame(node->transition, msec);
157 }
158
159 ivi_layout_commit_changes();
160 return 1;
161}
162
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900163struct ivi_layout_transition_set *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900164ivi_layout_transition_set_create(struct weston_compositor *ec)
165{
166 struct ivi_layout_transition_set *transitions;
167 struct wl_event_loop *loop;
168
169 transitions = malloc(sizeof(*transitions));
170 if (transitions == NULL) {
171 weston_log("%s: memory allocation fails\n", __func__);
172 return NULL;
173 }
174
175 wl_list_init(&transitions->transition_list);
176
177 loop = wl_display_get_event_loop(ec->wl_display);
178 transitions->event_source =
179 wl_event_loop_add_timer(loop, layout_transition_frame,
180 transitions);
181
182 return transitions;
183}
184
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300185static bool
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900186layout_transition_register(struct ivi_layout_transition *trans)
187{
188 struct ivi_layout *layout = get_instance();
189 struct transition_node *node;
190
191 node = malloc(sizeof(*node));
192 if (node == NULL) {
193 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300194 return false;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900195 }
196
197 node->transition = trans;
198 wl_list_insert(&layout->pending_transition_list, &node->link);
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300199 return true;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900200}
201
202static void
203remove_transition(struct ivi_layout *layout,
204 struct ivi_layout_transition *trans)
205{
206 struct transition_node *node;
207 struct transition_node *next;
208
209 wl_list_for_each_safe(node, next,
210 &layout->transitions->transition_list, link) {
211 if (node->transition == trans) {
212 wl_list_remove(&node->link);
213 free(node);
214 return;
215 }
216 }
217
218 wl_list_for_each_safe(node, next,
219 &layout->pending_transition_list, link) {
220 if (node->transition == trans) {
221 wl_list_remove(&node->link);
222 free(node);
223 return;
224 }
225 }
226}
227
228static void
229layout_transition_destroy(struct ivi_layout_transition *transition)
230{
231 struct ivi_layout *layout = get_instance();
232
233 remove_transition(layout, transition);
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300234 if (transition->destroy_func)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900235 transition->destroy_func(transition);
236 free(transition);
237}
238
239static struct ivi_layout_transition *
240create_layout_transition(void)
241{
242 struct ivi_layout_transition *transition = malloc(sizeof(*transition));
243
244 if (transition == NULL) {
245 weston_log("%s: memory allocation fails\n", __func__);
246 return NULL;
247 }
248
249 transition->type = IVI_LAYOUT_TRANSITION_MAX;
250 transition->time_start = 0;
251 transition->time_duration = 300; /* 300ms */
252 transition->time_elapsed = 0;
253
254 transition->is_done = 0;
255
John-John Tedro9d7aff02015-09-20 02:47:37 +0200256 transition->is_transition_func = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900257 transition->private_data = NULL;
258 transition->user_data = NULL;
259
260 transition->frame_func = NULL;
261 transition->destroy_func = NULL;
262
263 return transition;
264}
265
266/* move and resize view transition */
267
268struct move_resize_view_data {
269 struct ivi_layout_surface *surface;
270 int32_t start_x;
271 int32_t start_y;
272 int32_t end_x;
273 int32_t end_y;
274 int32_t start_width;
275 int32_t start_height;
276 int32_t end_width;
277 int32_t end_height;
278};
279
280static void
281transition_move_resize_view_destroy(struct ivi_layout_transition *transition)
282{
283 struct move_resize_view_data *data =
284 (struct move_resize_view_data *)transition->private_data;
285 struct ivi_layout_surface *layout_surface = data->surface;
286
287 wl_signal_emit(&layout_surface->configured, layout_surface);
288
289 if (transition->private_data) {
290 free(transition->private_data);
291 transition->private_data = NULL;
292 }
293}
294
295static void
296transition_move_resize_view_user_frame(struct ivi_layout_transition *transition)
297{
298 struct move_resize_view_data *mrv = transition->private_data;
299 const double current = time_to_nowpos(transition);
300
301 const int32_t destx = mrv->start_x +
302 (mrv->end_x - mrv->start_x) * current;
303
304 const int32_t desty = mrv->start_y +
305 (mrv->end_y - mrv->start_y) * current;
306
307 const int32_t dest_width = mrv->start_width +
308 (mrv->end_width - mrv->start_width) * current;
309
310 const int32_t dest_height = mrv->start_height +
311 (mrv->end_height - mrv->start_height) * current;
312
313 ivi_layout_surface_set_destination_rectangle(mrv->surface,
314 destx, desty,
315 dest_width, dest_height);
316}
317
318static int32_t
319is_transition_move_resize_view_func(struct move_resize_view_data *data,
320 struct ivi_layout_surface *view)
321{
322 return data->surface == view;
323}
324
325static struct ivi_layout_transition *
326create_move_resize_view_transition(
327 struct ivi_layout_surface *surface,
328 int32_t start_x, int32_t start_y,
329 int32_t end_x, int32_t end_y,
330 int32_t start_width, int32_t start_height,
331 int32_t end_width, int32_t end_height,
332 ivi_layout_transition_frame_func frame_func,
333 ivi_layout_transition_destroy_func destroy_func,
334 uint32_t duration)
335{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100336 struct ivi_layout_transition *transition;
337 struct move_resize_view_data *data;
338
339 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100340 if (transition == NULL)
341 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900342
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100343 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900344 if (data == NULL) {
345 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300346 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900347 return NULL;
348 }
349
350 transition->type = IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE;
351 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_resize_view_func;
352
353 transition->frame_func = frame_func;
354 transition->destroy_func = destroy_func;
355 transition->private_data = data;
356
357 if (duration != 0)
358 transition->time_duration = duration;
359
360 data->surface = surface;
361 data->start_x = start_x;
362 data->start_y = start_y;
363 data->end_x = end_x;
364 data->end_y = end_y;
365
366 data->start_width = start_width;
367 data->start_height = start_height;
368 data->end_width = end_width;
369 data->end_height = end_height;
370
371 return transition;
372}
373
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900374void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900375ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface,
376 int32_t dest_x, int32_t dest_y,
377 int32_t dest_width, int32_t dest_height,
378 uint32_t duration)
379{
380 struct ivi_layout_transition *transition;
381 int32_t start_pos[2] = {
382 surface->pending.prop.start_x,
383 surface->pending.prop.start_y
384 };
385
386 int32_t start_size[2] = {
387 surface->pending.prop.start_width,
388 surface->pending.prop.start_height
389 };
390
391 transition = get_transition_from_type_and_id(
392 IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
393 surface);
394 if (transition) {
395 struct move_resize_view_data *data = transition->private_data;
396 transition->time_start = 0;
397 transition->time_duration = duration;
398
399 data->start_x = start_pos[0];
400 data->start_y = start_pos[1];
401 data->end_x = dest_x;
402 data->end_y = dest_y;
403
404 data->start_width = start_size[0];
405 data->start_height = start_size[1];
406 data->end_width = dest_width;
407 data->end_height = dest_height;
408 return;
409 }
410
411 transition = create_move_resize_view_transition(
412 surface,
413 start_pos[0], start_pos[1],
414 dest_x, dest_y,
415 start_size[0], start_size[1],
416 dest_width, dest_height,
417 transition_move_resize_view_user_frame,
418 transition_move_resize_view_destroy,
419 duration);
420
Lucas Tanurea3377cd2015-09-30 09:38:37 -0300421 if(transition && layout_transition_register(transition))
422 return;
423 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900424}
425
426/* fade transition */
427struct fade_view_data {
428 struct ivi_layout_surface *surface;
429 double start_alpha;
430 double end_alpha;
431};
432
433struct store_alpha{
434 double alpha;
435};
436
437static void
438fade_view_user_frame(struct ivi_layout_transition *transition)
439{
440 struct fade_view_data *fade = transition->private_data;
441 struct ivi_layout_surface *surface = fade->surface;
442
443 const double current = time_to_nowpos(transition);
444 const double alpha = fade->start_alpha +
445 (fade->end_alpha - fade->start_alpha) * current;
446
447 ivi_layout_surface_set_opacity(surface, wl_fixed_from_double(alpha));
448 ivi_layout_surface_set_visibility(surface, true);
449}
450
451static int32_t
452is_transition_fade_view_func(struct fade_view_data *data,
453 struct ivi_layout_surface *view)
454{
455 return data->surface == view;
456}
457
458static struct ivi_layout_transition *
459create_fade_view_transition(
460 struct ivi_layout_surface *surface,
461 double start_alpha, double end_alpha,
462 ivi_layout_transition_frame_func frame_func,
463 void *user_data,
464 ivi_layout_transition_destroy_func destroy_func,
465 uint32_t duration)
466{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100467 struct ivi_layout_transition *transition;
468 struct fade_view_data *data;
469
470 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100471 if (transition == NULL)
472 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900473
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100474 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900475 if (data == NULL) {
476 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300477 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900478 return NULL;
479 }
480
481 transition->type = IVI_LAYOUT_TRANSITION_VIEW_FADE;
482 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_view_func;
483
484 transition->user_data = user_data;
485 transition->private_data = data;
486 transition->frame_func = frame_func;
487 transition->destroy_func = destroy_func;
488
489 if (duration != 0)
490 transition->time_duration = duration;
491
492 data->surface = surface;
493 data->start_alpha = start_alpha;
494 data->end_alpha = end_alpha;
495
496 return transition;
497}
498
499static void
500create_visibility_transition(struct ivi_layout_surface *surface,
501 double start_alpha,
502 double dest_alpha,
503 void *user_data,
504 ivi_layout_transition_destroy_func destroy_func,
505 uint32_t duration)
506{
507 struct ivi_layout_transition *transition = NULL;
508
509 transition = create_fade_view_transition(
510 surface,
511 start_alpha, dest_alpha,
512 fade_view_user_frame,
513 user_data,
514 destroy_func,
515 duration);
516
Lucas Tanurea3377cd2015-09-30 09:38:37 -0300517 if (transition && layout_transition_register(transition))
518 return;
519 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900520}
521
522static void
523visibility_on_transition_destroy(struct ivi_layout_transition *transition)
524{
525 struct fade_view_data *data = transition->private_data;
526 struct store_alpha *user_data = transition->user_data;
527
528 ivi_layout_surface_set_visibility(data->surface, true);
529
530 free(data);
531 transition->private_data = NULL;
532
533 free(user_data);
534 transition->user_data = NULL;
535}
536
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900537void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900538ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
539 uint32_t duration)
540{
541 struct ivi_layout_transition *transition;
Ucan, Emre \(ADITG/SW1\)c6a138c2016-03-04 12:50:06 +0000542 bool is_visible = surface->prop.visibility;
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000543 wl_fixed_t dest_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900544 struct store_alpha *user_data = NULL;
545 wl_fixed_t start_alpha = 0.0;
546 struct fade_view_data *data = NULL;
547
548 transition = get_transition_from_type_and_id(
549 IVI_LAYOUT_TRANSITION_VIEW_FADE,
550 surface);
551 if (transition) {
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000552 start_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900553 user_data = transition->user_data;
554 data = transition->private_data;
555
556 transition->time_start = 0;
557 transition->time_duration = duration;
558 transition->destroy_func = visibility_on_transition_destroy;
559
560 data->start_alpha = wl_fixed_to_double(start_alpha);
561 data->end_alpha = user_data->alpha;
562 return;
563 }
564
565 if (is_visible)
566 return;
567
568 user_data = malloc(sizeof(*user_data));
569 if (user_data == NULL) {
570 weston_log("%s: memory allocation fails\n", __func__);
571 return;
572 }
573
574 user_data->alpha = wl_fixed_to_double(dest_alpha);
575
576 create_visibility_transition(surface,
577 0.0, // start_alpha
578 wl_fixed_to_double(dest_alpha),
579 user_data,
580 visibility_on_transition_destroy,
581 duration);
582}
583
584static void
585visibility_off_transition_destroy(struct ivi_layout_transition *transition)
586{
587 struct fade_view_data *data = transition->private_data;
588 struct store_alpha *user_data = transition->user_data;
589
590 ivi_layout_surface_set_visibility(data->surface, false);
591
592 ivi_layout_surface_set_opacity(data->surface,
593 wl_fixed_from_double(user_data->alpha));
594
595 free(data);
596 transition->private_data = NULL;
597
598 free(user_data);
599 transition->user_data= NULL;
600}
601
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900602void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900603ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
604 uint32_t duration)
605{
606 struct ivi_layout_transition *transition;
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000607 wl_fixed_t start_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900608 struct store_alpha* user_data = NULL;
609 struct fade_view_data* data = NULL;
610
611 transition =
612 get_transition_from_type_and_id(IVI_LAYOUT_TRANSITION_VIEW_FADE,
613 surface);
614 if (transition) {
615 data = transition->private_data;
616
617 transition->time_start = 0;
618 transition->time_duration = duration;
619 transition->destroy_func = visibility_off_transition_destroy;
620
621 data->start_alpha = wl_fixed_to_double(start_alpha);
622 data->end_alpha = 0;
623 return;
624 }
625
626 user_data = malloc(sizeof(*user_data));
627 if (user_data == NULL) {
628 weston_log("%s: memory allocation fails\n", __func__);
629 return;
630 }
631
632 user_data->alpha = wl_fixed_to_double(start_alpha);
633
634 create_visibility_transition(surface,
635 wl_fixed_to_double(start_alpha),
636 0.0, // dest_alpha
637 user_data,
638 visibility_off_transition_destroy,
639 duration);
640}
641
642/* move layer transition */
643
644struct move_layer_data {
645 struct ivi_layout_layer *layer;
646 int32_t start_x;
647 int32_t start_y;
648 int32_t end_x;
649 int32_t end_y;
650 ivi_layout_transition_destroy_user_func destroy_func;
651};
652
653static void
654transition_move_layer_user_frame(struct ivi_layout_transition *transition)
655{
656 struct move_layer_data *data = transition->private_data;
657 struct ivi_layout_layer *layer = data->layer;
658
659 const float current = time_to_nowpos(transition);
660
661 const int32_t dest_x = data->start_x +
662 (data->end_x - data->start_x) * current;
663
664 const int32_t dest_y = data->start_y +
665 (data->end_y - data->start_y) * current;
666
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +0000667 ivi_layout_layer_set_destination_rectangle(layer, dest_x, dest_y,
668 layer->prop.dest_width, layer->prop.dest_height);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900669}
670
671static void
672transition_move_layer_destroy(struct ivi_layout_transition *transition)
673{
674 struct move_layer_data *data = transition->private_data;
675
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300676 if (data->destroy_func)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900677 data->destroy_func(transition->user_data);
678
679 free(data);
680 transition->private_data = NULL;
681}
682
683static int32_t
684is_transition_move_layer_func(struct move_layer_data *data,
685 struct ivi_layout_layer *layer)
686{
687 return data->layer == layer;
688}
689
690
691static struct ivi_layout_transition *
692create_move_layer_transition(
693 struct ivi_layout_layer *layer,
694 int32_t start_x, int32_t start_y,
695 int32_t end_x, int32_t end_y,
696 void *user_data,
697 ivi_layout_transition_destroy_user_func destroy_user_func,
698 uint32_t duration)
699{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100700 struct ivi_layout_transition *transition;
701 struct move_layer_data *data;
702
703 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100704 if (transition == NULL)
705 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900706
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100707 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900708 if (data == NULL) {
709 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300710 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900711 return NULL;
712 }
713
714 transition->type = IVI_LAYOUT_TRANSITION_LAYER_MOVE;
715 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_layer_func;
716
717 transition->frame_func = transition_move_layer_user_frame;
718 transition->destroy_func = transition_move_layer_destroy;
719 transition->private_data = data;
720 transition->user_data = user_data;
721
722 if (duration != 0)
723 transition->time_duration = duration;
724
725 data->layer = layer;
726 data->start_x = start_x;
727 data->start_y = start_y;
728 data->end_x = end_x;
729 data->end_y = end_y;
730 data->destroy_func = destroy_user_func;
731
732 return transition;
733}
734
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900735void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900736ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
737 int32_t dest_x, int32_t dest_y,
738 uint32_t duration)
739{
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +0000740 int32_t start_pos_x = layer->prop.dest_x;
741 int32_t start_pos_y = layer->prop.dest_y;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900742 struct ivi_layout_transition *transition = NULL;
743
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900744 transition = create_move_layer_transition(
745 layer,
746 start_pos_x, start_pos_y,
747 dest_x, dest_y,
748 NULL, NULL,
749 duration);
750
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300751 if (transition && layout_transition_register(transition))
752 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900753
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300754 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900755}
756
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900757void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900758ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer)
759{
760 struct ivi_layout_transition *transition =
761 get_transition_from_type_and_id(
762 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
763 layer);
764 if (transition) {
765 layout_transition_destroy(transition);
766 }
767}
768
769/* fade layer transition */
770struct fade_layer_data {
771 struct ivi_layout_layer *layer;
772 uint32_t is_fade_in;
773 double start_alpha;
774 double end_alpha;
775 ivi_layout_transition_destroy_user_func destroy_func;
776};
777
778static void
779transition_fade_layer_destroy(struct ivi_layout_transition *transition)
780{
781 struct fade_layer_data *data = transition->private_data;
782 transition->private_data = NULL;
783
784 free(data);
785}
786
787static void
788transition_fade_layer_user_frame(struct ivi_layout_transition *transition)
789{
790 double current = time_to_nowpos(transition);
791 struct fade_layer_data *data = transition->private_data;
792 double alpha = data->start_alpha +
793 (data->end_alpha - data->start_alpha) * current;
794 wl_fixed_t fixed_alpha = wl_fixed_from_double(alpha);
795
796 int32_t is_done = transition->is_done;
797 bool is_visible = !is_done || data->is_fade_in;
798
799 ivi_layout_layer_set_opacity(data->layer, fixed_alpha);
800 ivi_layout_layer_set_visibility(data->layer, is_visible);
801}
802
803static int32_t
804is_transition_fade_layer_func(struct fade_layer_data *data,
805 struct ivi_layout_layer *layer)
806{
807 return data->layer == layer;
808}
809
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900810void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900811ivi_layout_transition_fade_layer(
812 struct ivi_layout_layer *layer,
813 uint32_t is_fade_in,
814 double start_alpha, double end_alpha,
815 void* user_data,
816 ivi_layout_transition_destroy_user_func destroy_func,
817 uint32_t duration)
818{
819 struct ivi_layout_transition *transition;
820 struct fade_layer_data *data = NULL;
821 wl_fixed_t fixed_opacity = 0.0;
822 double now_opacity = 0.0;
823 double remain = 0.0;
824
825 transition = get_transition_from_type_and_id(
826 IVI_LAYOUT_TRANSITION_LAYER_FADE,
827 layer);
828 if (transition) {
829 /* transition update */
830 data = transition->private_data;
831
832 /* FIXME */
Ucan, Emre \(ADITG/SW1\)c3aee1f2016-03-04 12:50:16 +0000833 fixed_opacity = layer->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900834 now_opacity = wl_fixed_to_double(fixed_opacity);
835 remain = 0.0;
836
837 data->is_fade_in = is_fade_in;
838 data->start_alpha = now_opacity;
839 data->end_alpha = end_alpha;
840
841 remain = is_fade_in? 1.0 - now_opacity : now_opacity;
842 transition->time_start = 0;
843 transition->time_elapsed = 0;
844 transition->time_duration = duration * remain;
845
846 return;
847 }
848
849 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100850 if (transition == NULL)
851 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900852
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100853 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900854 if (data == NULL) {
855 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300856 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900857 return;
858 }
859
860 transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
861 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
862
863 transition->private_data = data;
864 transition->user_data = user_data;
865
866 transition->frame_func = transition_fade_layer_user_frame;
867 transition->destroy_func = transition_fade_layer_destroy;
868
869 if (duration != 0)
870 transition->time_duration = duration;
871
872 data->layer = layer;
873 data->is_fade_in = is_fade_in;
874 data->start_alpha = start_alpha;
875 data->end_alpha = end_alpha;
876 data->destroy_func = destroy_func;
877
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300878 if (!layout_transition_register(transition))
879 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900880
881 return;
882}
883