blob: b887ff657880254b76c8e5d2b0bf18f8a6b9eee5 [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
Pekka Paalanenae8c3d82016-03-15 17:39:21 +020026#include "config.h"
27
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090028#include <time.h>
29#include <assert.h>
30#include <stdlib.h>
Jussi Kukkonen649bbce2016-07-19 14:16:27 +030031#include <stdint.h>
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090032#include <stdio.h>
Lucas Tanure9b5fe422015-09-21 14:10:32 -030033#include <stdbool.h>
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090034
Pekka Paalanen1f821932016-03-15 16:57:51 +020035#include "ivi-shell.h"
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090036#include "ivi-layout-export.h"
37#include "ivi-layout-private.h"
38
39struct ivi_layout_transition;
40
41typedef void (*ivi_layout_transition_frame_func)(
42 struct ivi_layout_transition *transition);
43typedef void (*ivi_layout_transition_destroy_func)(
44 struct ivi_layout_transition *transition);
45typedef int32_t (*ivi_layout_is_transition_func)(void *private_data, void *id);
46
47struct 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
61struct transition_node {
62 struct ivi_layout_transition *transition;
Ucan, Emre (ADITG/SW1)7da38232016-07-01 09:34:50 +000063
64 /* ivi_layout::pending_transition_list
65 * ivi_layout_transition_set::transition_list
66 */
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090067 struct wl_list link;
68};
69
70static void layout_transition_destroy(struct ivi_layout_transition *transition);
71
72static struct ivi_layout_transition *
73get_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
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +090091int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090092is_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
Mateusz Polroladada6e32016-03-09 09:13:26 +0000110void
111ivi_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
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900126static void
127tick_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
139static 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
145static void
146do_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
159static int32_t
160layout_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, &timestamp);/* 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
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900187struct ivi_layout_transition_set *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900188ivi_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
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300209static bool
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900210layout_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__);
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300218 return false;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900219 }
220
221 node->transition = trans;
222 wl_list_insert(&layout->pending_transition_list, &node->link);
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300223 return true;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900224}
225
226static void
227remove_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
252static void
253layout_transition_destroy(struct ivi_layout_transition *transition)
254{
255 struct ivi_layout *layout = get_instance();
256
257 remove_transition(layout, transition);
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300258 if (transition->destroy_func)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900259 transition->destroy_func(transition);
260 free(transition);
261}
262
263static struct ivi_layout_transition *
264create_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
John-John Tedro9d7aff02015-09-20 02:47:37 +0200280 transition->is_transition_func = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900281 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
292struct 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
304static void
305transition_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
Pekka Paalanen1f821932016-03-15 16:57:51 +0200311 shell_surface_send_configure(layout_surface->surface,
312 layout_surface->prop.dest_width,
313 layout_surface->prop.dest_height);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900314
315 if (transition->private_data) {
316 free(transition->private_data);
317 transition->private_data = NULL;
318 }
319}
320
321static void
322transition_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
344static int32_t
345is_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
351static struct ivi_layout_transition *
352create_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{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100362 struct ivi_layout_transition *transition;
363 struct move_resize_view_data *data;
364
365 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100366 if (transition == NULL)
367 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900368
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100369 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900370 if (data == NULL) {
371 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300372 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900373 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
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900400void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900401ivi_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
Bryce Harrington1dbdc0b2016-07-12 16:59:05 -0700447 if (transition && layout_transition_register(transition))
Lucas Tanurea3377cd2015-09-30 09:38:37 -0300448 return;
449 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900450}
451
452/* fade transition */
453struct fade_view_data {
454 struct ivi_layout_surface *surface;
455 double start_alpha;
456 double end_alpha;
457};
458
459struct store_alpha{
460 double alpha;
461};
462
463static void
464fade_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
477static int32_t
478is_transition_fade_view_func(struct fade_view_data *data,
479 struct ivi_layout_surface *view)
480{
481 return data->surface == view;
482}
483
484static struct ivi_layout_transition *
485create_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{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100493 struct ivi_layout_transition *transition;
494 struct fade_view_data *data;
495
496 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100497 if (transition == NULL)
498 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900499
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100500 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900501 if (data == NULL) {
502 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300503 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900504 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
525static void
526create_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
Lucas Tanurea3377cd2015-09-30 09:38:37 -0300543 if (transition && layout_transition_register(transition))
544 return;
545 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900546}
547
548static void
549visibility_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
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900563void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900564ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
565 uint32_t duration)
566{
567 struct ivi_layout_transition *transition;
Ucan, Emre \(ADITG/SW1\)c6a138c2016-03-04 12:50:06 +0000568 bool is_visible = surface->prop.visibility;
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000569 wl_fixed_t dest_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900570 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) {
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000578 start_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900579 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
610static void
611visibility_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
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900628void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900629ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
630 uint32_t duration)
631{
632 struct ivi_layout_transition *transition;
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000633 wl_fixed_t start_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900634 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
670struct 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
679static void
680transition_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
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +0000693 ivi_layout_layer_set_destination_rectangle(layer, dest_x, dest_y,
694 layer->prop.dest_width, layer->prop.dest_height);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900695}
696
697static void
698transition_move_layer_destroy(struct ivi_layout_transition *transition)
699{
700 struct move_layer_data *data = transition->private_data;
701
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300702 if (data->destroy_func)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900703 data->destroy_func(transition->user_data);
704
705 free(data);
706 transition->private_data = NULL;
707}
708
709static int32_t
710is_transition_move_layer_func(struct move_layer_data *data,
711 struct ivi_layout_layer *layer)
712{
713 return data->layer == layer;
714}
715
716
717static struct ivi_layout_transition *
718create_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{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100726 struct ivi_layout_transition *transition;
727 struct move_layer_data *data;
728
729 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100730 if (transition == NULL)
731 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900732
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100733 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900734 if (data == NULL) {
735 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300736 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900737 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
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900761void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900762ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
763 int32_t dest_x, int32_t dest_y,
764 uint32_t duration)
765{
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +0000766 int32_t start_pos_x = layer->prop.dest_x;
767 int32_t start_pos_y = layer->prop.dest_y;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900768 struct ivi_layout_transition *transition = NULL;
769
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900770 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
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300777 if (transition && layout_transition_register(transition))
778 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900779
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300780 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900781}
782
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900783void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900784ivi_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 */
796struct 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
804static void
805transition_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
813static void
814transition_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
829static int32_t
830is_transition_fade_layer_func(struct fade_layer_data *data,
831 struct ivi_layout_layer *layer)
832{
833 return data->layer == layer;
834}
835
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900836void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900837ivi_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 = NULL;
847 wl_fixed_t fixed_opacity = 0.0;
848 double now_opacity = 0.0;
849 double remain = 0.0;
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 */
Ucan, Emre \(ADITG/SW1\)c3aee1f2016-03-04 12:50:16 +0000859 fixed_opacity = layer->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900860 now_opacity = wl_fixed_to_double(fixed_opacity);
861 remain = 0.0;
862
863 data->is_fade_in = is_fade_in;
864 data->start_alpha = now_opacity;
865 data->end_alpha = end_alpha;
866
867 remain = is_fade_in? 1.0 - now_opacity : now_opacity;
868 transition->time_start = 0;
869 transition->time_elapsed = 0;
870 transition->time_duration = duration * remain;
871
872 return;
873 }
874
875 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100876 if (transition == NULL)
877 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900878
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100879 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900880 if (data == NULL) {
881 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300882 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900883 return;
884 }
885
886 transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
887 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
888
889 transition->private_data = data;
890 transition->user_data = user_data;
891
892 transition->frame_func = transition_fade_layer_user_frame;
893 transition->destroy_func = transition_fade_layer_destroy;
894
895 if (duration != 0)
896 transition->time_duration = duration;
897
898 data->layer = layer;
899 data->is_fade_in = is_fade_in;
900 data->start_alpha = start_alpha;
901 data->end_alpha = end_alpha;
902 data->destroy_func = destroy_func;
903
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300904 if (!layout_transition_register(transition))
905 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900906
907 return;
908}
909