blob: 4913db45f04f470ee1c6a75b3da093ba433707ea [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>
31#include <stdio.h>
Lucas Tanure9b5fe422015-09-21 14:10:32 -030032#include <stdbool.h>
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090033
Pekka Paalanen1f821932016-03-15 16:57:51 +020034#include "ivi-shell.h"
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090035#include "ivi-layout-export.h"
36#include "ivi-layout-private.h"
37
38struct ivi_layout_transition;
39
40typedef void (*ivi_layout_transition_frame_func)(
41 struct ivi_layout_transition *transition);
42typedef void (*ivi_layout_transition_destroy_func)(
43 struct ivi_layout_transition *transition);
44typedef int32_t (*ivi_layout_is_transition_func)(void *private_data, void *id);
45
46struct ivi_layout_transition {
47 enum ivi_layout_transition_type type;
48 void *private_data;
49 void *user_data;
50
51 uint32_t time_start;
52 uint32_t time_duration;
53 uint32_t time_elapsed;
54 uint32_t is_done;
55 ivi_layout_is_transition_func is_transition_func;
56 ivi_layout_transition_frame_func frame_func;
57 ivi_layout_transition_destroy_func destroy_func;
58};
59
60struct transition_node {
61 struct ivi_layout_transition *transition;
62 struct wl_list link;
63};
64
65static void layout_transition_destroy(struct ivi_layout_transition *transition);
66
67static struct ivi_layout_transition *
68get_transition_from_type_and_id(enum ivi_layout_transition_type type,
69 void *id_data)
70{
71 struct ivi_layout *layout = get_instance();
72 struct transition_node *node;
73 struct ivi_layout_transition *tran;
74
75 wl_list_for_each(node, &layout->transitions->transition_list, link) {
76 tran = node->transition;
77
78 if (tran->type == type &&
79 tran->is_transition_func(tran->private_data, id_data))
80 return tran;
81 }
82
83 return NULL;
84}
85
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +090086int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090087is_surface_transition(struct ivi_layout_surface *surface)
88{
89 struct ivi_layout *layout = get_instance();
90 struct transition_node *node;
91 struct ivi_layout_transition *tran;
92
93 wl_list_for_each(node, &layout->transitions->transition_list, link) {
94 tran = node->transition;
95
96 if ((tran->type == IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE ||
97 tran->type == IVI_LAYOUT_TRANSITION_VIEW_RESIZE) &&
98 tran->is_transition_func(tran->private_data, surface))
99 return 1;
100 }
101
102 return 0;
103}
104
Mateusz Polroladada6e32016-03-09 09:13:26 +0000105void
106ivi_layout_remove_all_surface_transitions(struct ivi_layout_surface *surface)
107{
108 struct ivi_layout *layout = get_instance();
109 struct transition_node *node;
110 struct transition_node *tmp;
111 struct ivi_layout_transition *tran;
112
113 wl_list_for_each_safe(node, tmp, &layout->transitions->transition_list, link) {
114 tran = node->transition;
115 if (tran->is_transition_func(tran->private_data, surface)) {
116 layout_transition_destroy(tran);
117 }
118 };
119}
120
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900121static void
122tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp)
123{
124 const double t = timestamp - transition->time_start;
125
126 if (transition->time_duration <= t) {
127 transition->time_elapsed = transition->time_duration;
128 transition->is_done = 1;
129 } else {
130 transition->time_elapsed = t;
131 }
132}
133
134static float time_to_nowpos(struct ivi_layout_transition *transition)
135{
136 return sin((float)transition->time_elapsed /
137 (float)transition->time_duration * M_PI_2);
138}
139
140static void
141do_transition_frame(struct ivi_layout_transition *transition,
142 uint32_t timestamp)
143{
144 if (0 == transition->time_start)
145 transition->time_start = timestamp;
146
147 tick_transition(transition, timestamp);
148 transition->frame_func(transition);
149
150 if (transition->is_done)
151 layout_transition_destroy(transition);
152}
153
154static int32_t
155layout_transition_frame(void *data)
156{
157 struct ivi_layout_transition_set *transitions = data;
158 uint32_t fps = 30;
159 struct timespec timestamp = {};
160 uint32_t msec = 0;
161 struct transition_node *node = NULL;
162 struct transition_node *next = NULL;
163
164 if (wl_list_empty(&transitions->transition_list)) {
165 wl_event_source_timer_update(transitions->event_source, 0);
166 return 1;
167 }
168
169 wl_event_source_timer_update(transitions->event_source, 1000 / fps);
170
171 clock_gettime(CLOCK_MONOTONIC, &timestamp);/* FIXME */
172 msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec);
173
174 wl_list_for_each_safe(node, next, &transitions->transition_list, link) {
175 do_transition_frame(node->transition, msec);
176 }
177
178 ivi_layout_commit_changes();
179 return 1;
180}
181
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900182struct ivi_layout_transition_set *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900183ivi_layout_transition_set_create(struct weston_compositor *ec)
184{
185 struct ivi_layout_transition_set *transitions;
186 struct wl_event_loop *loop;
187
188 transitions = malloc(sizeof(*transitions));
189 if (transitions == NULL) {
190 weston_log("%s: memory allocation fails\n", __func__);
191 return NULL;
192 }
193
194 wl_list_init(&transitions->transition_list);
195
196 loop = wl_display_get_event_loop(ec->wl_display);
197 transitions->event_source =
198 wl_event_loop_add_timer(loop, layout_transition_frame,
199 transitions);
200
201 return transitions;
202}
203
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300204static bool
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900205layout_transition_register(struct ivi_layout_transition *trans)
206{
207 struct ivi_layout *layout = get_instance();
208 struct transition_node *node;
209
210 node = malloc(sizeof(*node));
211 if (node == NULL) {
212 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300213 return false;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900214 }
215
216 node->transition = trans;
217 wl_list_insert(&layout->pending_transition_list, &node->link);
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300218 return true;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900219}
220
221static void
222remove_transition(struct ivi_layout *layout,
223 struct ivi_layout_transition *trans)
224{
225 struct transition_node *node;
226 struct transition_node *next;
227
228 wl_list_for_each_safe(node, next,
229 &layout->transitions->transition_list, link) {
230 if (node->transition == trans) {
231 wl_list_remove(&node->link);
232 free(node);
233 return;
234 }
235 }
236
237 wl_list_for_each_safe(node, next,
238 &layout->pending_transition_list, link) {
239 if (node->transition == trans) {
240 wl_list_remove(&node->link);
241 free(node);
242 return;
243 }
244 }
245}
246
247static void
248layout_transition_destroy(struct ivi_layout_transition *transition)
249{
250 struct ivi_layout *layout = get_instance();
251
252 remove_transition(layout, transition);
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300253 if (transition->destroy_func)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900254 transition->destroy_func(transition);
255 free(transition);
256}
257
258static struct ivi_layout_transition *
259create_layout_transition(void)
260{
261 struct ivi_layout_transition *transition = malloc(sizeof(*transition));
262
263 if (transition == NULL) {
264 weston_log("%s: memory allocation fails\n", __func__);
265 return NULL;
266 }
267
268 transition->type = IVI_LAYOUT_TRANSITION_MAX;
269 transition->time_start = 0;
270 transition->time_duration = 300; /* 300ms */
271 transition->time_elapsed = 0;
272
273 transition->is_done = 0;
274
John-John Tedro9d7aff02015-09-20 02:47:37 +0200275 transition->is_transition_func = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900276 transition->private_data = NULL;
277 transition->user_data = NULL;
278
279 transition->frame_func = NULL;
280 transition->destroy_func = NULL;
281
282 return transition;
283}
284
285/* move and resize view transition */
286
287struct move_resize_view_data {
288 struct ivi_layout_surface *surface;
289 int32_t start_x;
290 int32_t start_y;
291 int32_t end_x;
292 int32_t end_y;
293 int32_t start_width;
294 int32_t start_height;
295 int32_t end_width;
296 int32_t end_height;
297};
298
299static void
300transition_move_resize_view_destroy(struct ivi_layout_transition *transition)
301{
302 struct move_resize_view_data *data =
303 (struct move_resize_view_data *)transition->private_data;
304 struct ivi_layout_surface *layout_surface = data->surface;
305
Pekka Paalanen1f821932016-03-15 16:57:51 +0200306 shell_surface_send_configure(layout_surface->surface,
307 layout_surface->prop.dest_width,
308 layout_surface->prop.dest_height);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900309
310 if (transition->private_data) {
311 free(transition->private_data);
312 transition->private_data = NULL;
313 }
314}
315
316static void
317transition_move_resize_view_user_frame(struct ivi_layout_transition *transition)
318{
319 struct move_resize_view_data *mrv = transition->private_data;
320 const double current = time_to_nowpos(transition);
321
322 const int32_t destx = mrv->start_x +
323 (mrv->end_x - mrv->start_x) * current;
324
325 const int32_t desty = mrv->start_y +
326 (mrv->end_y - mrv->start_y) * current;
327
328 const int32_t dest_width = mrv->start_width +
329 (mrv->end_width - mrv->start_width) * current;
330
331 const int32_t dest_height = mrv->start_height +
332 (mrv->end_height - mrv->start_height) * current;
333
334 ivi_layout_surface_set_destination_rectangle(mrv->surface,
335 destx, desty,
336 dest_width, dest_height);
337}
338
339static int32_t
340is_transition_move_resize_view_func(struct move_resize_view_data *data,
341 struct ivi_layout_surface *view)
342{
343 return data->surface == view;
344}
345
346static struct ivi_layout_transition *
347create_move_resize_view_transition(
348 struct ivi_layout_surface *surface,
349 int32_t start_x, int32_t start_y,
350 int32_t end_x, int32_t end_y,
351 int32_t start_width, int32_t start_height,
352 int32_t end_width, int32_t end_height,
353 ivi_layout_transition_frame_func frame_func,
354 ivi_layout_transition_destroy_func destroy_func,
355 uint32_t duration)
356{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100357 struct ivi_layout_transition *transition;
358 struct move_resize_view_data *data;
359
360 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100361 if (transition == NULL)
362 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900363
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100364 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900365 if (data == NULL) {
366 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300367 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900368 return NULL;
369 }
370
371 transition->type = IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE;
372 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_resize_view_func;
373
374 transition->frame_func = frame_func;
375 transition->destroy_func = destroy_func;
376 transition->private_data = data;
377
378 if (duration != 0)
379 transition->time_duration = duration;
380
381 data->surface = surface;
382 data->start_x = start_x;
383 data->start_y = start_y;
384 data->end_x = end_x;
385 data->end_y = end_y;
386
387 data->start_width = start_width;
388 data->start_height = start_height;
389 data->end_width = end_width;
390 data->end_height = end_height;
391
392 return transition;
393}
394
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900395void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900396ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface,
397 int32_t dest_x, int32_t dest_y,
398 int32_t dest_width, int32_t dest_height,
399 uint32_t duration)
400{
401 struct ivi_layout_transition *transition;
402 int32_t start_pos[2] = {
403 surface->pending.prop.start_x,
404 surface->pending.prop.start_y
405 };
406
407 int32_t start_size[2] = {
408 surface->pending.prop.start_width,
409 surface->pending.prop.start_height
410 };
411
412 transition = get_transition_from_type_and_id(
413 IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
414 surface);
415 if (transition) {
416 struct move_resize_view_data *data = transition->private_data;
417 transition->time_start = 0;
418 transition->time_duration = duration;
419
420 data->start_x = start_pos[0];
421 data->start_y = start_pos[1];
422 data->end_x = dest_x;
423 data->end_y = dest_y;
424
425 data->start_width = start_size[0];
426 data->start_height = start_size[1];
427 data->end_width = dest_width;
428 data->end_height = dest_height;
429 return;
430 }
431
432 transition = create_move_resize_view_transition(
433 surface,
434 start_pos[0], start_pos[1],
435 dest_x, dest_y,
436 start_size[0], start_size[1],
437 dest_width, dest_height,
438 transition_move_resize_view_user_frame,
439 transition_move_resize_view_destroy,
440 duration);
441
Bryce Harrington1dbdc0b2016-07-12 16:59:05 -0700442 if (transition && layout_transition_register(transition))
Lucas Tanurea3377cd2015-09-30 09:38:37 -0300443 return;
444 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900445}
446
447/* fade transition */
448struct fade_view_data {
449 struct ivi_layout_surface *surface;
450 double start_alpha;
451 double end_alpha;
452};
453
454struct store_alpha{
455 double alpha;
456};
457
458static void
459fade_view_user_frame(struct ivi_layout_transition *transition)
460{
461 struct fade_view_data *fade = transition->private_data;
462 struct ivi_layout_surface *surface = fade->surface;
463
464 const double current = time_to_nowpos(transition);
465 const double alpha = fade->start_alpha +
466 (fade->end_alpha - fade->start_alpha) * current;
467
468 ivi_layout_surface_set_opacity(surface, wl_fixed_from_double(alpha));
469 ivi_layout_surface_set_visibility(surface, true);
470}
471
472static int32_t
473is_transition_fade_view_func(struct fade_view_data *data,
474 struct ivi_layout_surface *view)
475{
476 return data->surface == view;
477}
478
479static struct ivi_layout_transition *
480create_fade_view_transition(
481 struct ivi_layout_surface *surface,
482 double start_alpha, double end_alpha,
483 ivi_layout_transition_frame_func frame_func,
484 void *user_data,
485 ivi_layout_transition_destroy_func destroy_func,
486 uint32_t duration)
487{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100488 struct ivi_layout_transition *transition;
489 struct fade_view_data *data;
490
491 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100492 if (transition == NULL)
493 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900494
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100495 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900496 if (data == NULL) {
497 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300498 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900499 return NULL;
500 }
501
502 transition->type = IVI_LAYOUT_TRANSITION_VIEW_FADE;
503 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_view_func;
504
505 transition->user_data = user_data;
506 transition->private_data = data;
507 transition->frame_func = frame_func;
508 transition->destroy_func = destroy_func;
509
510 if (duration != 0)
511 transition->time_duration = duration;
512
513 data->surface = surface;
514 data->start_alpha = start_alpha;
515 data->end_alpha = end_alpha;
516
517 return transition;
518}
519
520static void
521create_visibility_transition(struct ivi_layout_surface *surface,
522 double start_alpha,
523 double dest_alpha,
524 void *user_data,
525 ivi_layout_transition_destroy_func destroy_func,
526 uint32_t duration)
527{
528 struct ivi_layout_transition *transition = NULL;
529
530 transition = create_fade_view_transition(
531 surface,
532 start_alpha, dest_alpha,
533 fade_view_user_frame,
534 user_data,
535 destroy_func,
536 duration);
537
Lucas Tanurea3377cd2015-09-30 09:38:37 -0300538 if (transition && layout_transition_register(transition))
539 return;
540 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900541}
542
543static void
544visibility_on_transition_destroy(struct ivi_layout_transition *transition)
545{
546 struct fade_view_data *data = transition->private_data;
547 struct store_alpha *user_data = transition->user_data;
548
549 ivi_layout_surface_set_visibility(data->surface, true);
550
551 free(data);
552 transition->private_data = NULL;
553
554 free(user_data);
555 transition->user_data = NULL;
556}
557
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900558void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900559ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
560 uint32_t duration)
561{
562 struct ivi_layout_transition *transition;
Ucan, Emre \(ADITG/SW1\)c6a138c2016-03-04 12:50:06 +0000563 bool is_visible = surface->prop.visibility;
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000564 wl_fixed_t dest_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900565 struct store_alpha *user_data = NULL;
566 wl_fixed_t start_alpha = 0.0;
567 struct fade_view_data *data = NULL;
568
569 transition = get_transition_from_type_and_id(
570 IVI_LAYOUT_TRANSITION_VIEW_FADE,
571 surface);
572 if (transition) {
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000573 start_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900574 user_data = transition->user_data;
575 data = transition->private_data;
576
577 transition->time_start = 0;
578 transition->time_duration = duration;
579 transition->destroy_func = visibility_on_transition_destroy;
580
581 data->start_alpha = wl_fixed_to_double(start_alpha);
582 data->end_alpha = user_data->alpha;
583 return;
584 }
585
586 if (is_visible)
587 return;
588
589 user_data = malloc(sizeof(*user_data));
590 if (user_data == NULL) {
591 weston_log("%s: memory allocation fails\n", __func__);
592 return;
593 }
594
595 user_data->alpha = wl_fixed_to_double(dest_alpha);
596
597 create_visibility_transition(surface,
598 0.0, // start_alpha
599 wl_fixed_to_double(dest_alpha),
600 user_data,
601 visibility_on_transition_destroy,
602 duration);
603}
604
605static void
606visibility_off_transition_destroy(struct ivi_layout_transition *transition)
607{
608 struct fade_view_data *data = transition->private_data;
609 struct store_alpha *user_data = transition->user_data;
610
611 ivi_layout_surface_set_visibility(data->surface, false);
612
613 ivi_layout_surface_set_opacity(data->surface,
614 wl_fixed_from_double(user_data->alpha));
615
616 free(data);
617 transition->private_data = NULL;
618
619 free(user_data);
620 transition->user_data= NULL;
621}
622
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900623void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900624ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
625 uint32_t duration)
626{
627 struct ivi_layout_transition *transition;
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000628 wl_fixed_t start_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900629 struct store_alpha* user_data = NULL;
630 struct fade_view_data* data = NULL;
631
632 transition =
633 get_transition_from_type_and_id(IVI_LAYOUT_TRANSITION_VIEW_FADE,
634 surface);
635 if (transition) {
636 data = transition->private_data;
637
638 transition->time_start = 0;
639 transition->time_duration = duration;
640 transition->destroy_func = visibility_off_transition_destroy;
641
642 data->start_alpha = wl_fixed_to_double(start_alpha);
643 data->end_alpha = 0;
644 return;
645 }
646
647 user_data = malloc(sizeof(*user_data));
648 if (user_data == NULL) {
649 weston_log("%s: memory allocation fails\n", __func__);
650 return;
651 }
652
653 user_data->alpha = wl_fixed_to_double(start_alpha);
654
655 create_visibility_transition(surface,
656 wl_fixed_to_double(start_alpha),
657 0.0, // dest_alpha
658 user_data,
659 visibility_off_transition_destroy,
660 duration);
661}
662
663/* move layer transition */
664
665struct move_layer_data {
666 struct ivi_layout_layer *layer;
667 int32_t start_x;
668 int32_t start_y;
669 int32_t end_x;
670 int32_t end_y;
671 ivi_layout_transition_destroy_user_func destroy_func;
672};
673
674static void
675transition_move_layer_user_frame(struct ivi_layout_transition *transition)
676{
677 struct move_layer_data *data = transition->private_data;
678 struct ivi_layout_layer *layer = data->layer;
679
680 const float current = time_to_nowpos(transition);
681
682 const int32_t dest_x = data->start_x +
683 (data->end_x - data->start_x) * current;
684
685 const int32_t dest_y = data->start_y +
686 (data->end_y - data->start_y) * current;
687
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +0000688 ivi_layout_layer_set_destination_rectangle(layer, dest_x, dest_y,
689 layer->prop.dest_width, layer->prop.dest_height);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900690}
691
692static void
693transition_move_layer_destroy(struct ivi_layout_transition *transition)
694{
695 struct move_layer_data *data = transition->private_data;
696
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300697 if (data->destroy_func)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900698 data->destroy_func(transition->user_data);
699
700 free(data);
701 transition->private_data = NULL;
702}
703
704static int32_t
705is_transition_move_layer_func(struct move_layer_data *data,
706 struct ivi_layout_layer *layer)
707{
708 return data->layer == layer;
709}
710
711
712static struct ivi_layout_transition *
713create_move_layer_transition(
714 struct ivi_layout_layer *layer,
715 int32_t start_x, int32_t start_y,
716 int32_t end_x, int32_t end_y,
717 void *user_data,
718 ivi_layout_transition_destroy_user_func destroy_user_func,
719 uint32_t duration)
720{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100721 struct ivi_layout_transition *transition;
722 struct move_layer_data *data;
723
724 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100725 if (transition == NULL)
726 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900727
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100728 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900729 if (data == NULL) {
730 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300731 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900732 return NULL;
733 }
734
735 transition->type = IVI_LAYOUT_TRANSITION_LAYER_MOVE;
736 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_layer_func;
737
738 transition->frame_func = transition_move_layer_user_frame;
739 transition->destroy_func = transition_move_layer_destroy;
740 transition->private_data = data;
741 transition->user_data = user_data;
742
743 if (duration != 0)
744 transition->time_duration = duration;
745
746 data->layer = layer;
747 data->start_x = start_x;
748 data->start_y = start_y;
749 data->end_x = end_x;
750 data->end_y = end_y;
751 data->destroy_func = destroy_user_func;
752
753 return transition;
754}
755
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900756void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900757ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
758 int32_t dest_x, int32_t dest_y,
759 uint32_t duration)
760{
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +0000761 int32_t start_pos_x = layer->prop.dest_x;
762 int32_t start_pos_y = layer->prop.dest_y;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900763 struct ivi_layout_transition *transition = NULL;
764
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900765 transition = create_move_layer_transition(
766 layer,
767 start_pos_x, start_pos_y,
768 dest_x, dest_y,
769 NULL, NULL,
770 duration);
771
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300772 if (transition && layout_transition_register(transition))
773 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900774
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300775 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900776}
777
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900778void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900779ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer)
780{
781 struct ivi_layout_transition *transition =
782 get_transition_from_type_and_id(
783 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
784 layer);
785 if (transition) {
786 layout_transition_destroy(transition);
787 }
788}
789
790/* fade layer transition */
791struct fade_layer_data {
792 struct ivi_layout_layer *layer;
793 uint32_t is_fade_in;
794 double start_alpha;
795 double end_alpha;
796 ivi_layout_transition_destroy_user_func destroy_func;
797};
798
799static void
800transition_fade_layer_destroy(struct ivi_layout_transition *transition)
801{
802 struct fade_layer_data *data = transition->private_data;
803 transition->private_data = NULL;
804
805 free(data);
806}
807
808static void
809transition_fade_layer_user_frame(struct ivi_layout_transition *transition)
810{
811 double current = time_to_nowpos(transition);
812 struct fade_layer_data *data = transition->private_data;
813 double alpha = data->start_alpha +
814 (data->end_alpha - data->start_alpha) * current;
815 wl_fixed_t fixed_alpha = wl_fixed_from_double(alpha);
816
817 int32_t is_done = transition->is_done;
818 bool is_visible = !is_done || data->is_fade_in;
819
820 ivi_layout_layer_set_opacity(data->layer, fixed_alpha);
821 ivi_layout_layer_set_visibility(data->layer, is_visible);
822}
823
824static int32_t
825is_transition_fade_layer_func(struct fade_layer_data *data,
826 struct ivi_layout_layer *layer)
827{
828 return data->layer == layer;
829}
830
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900831void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900832ivi_layout_transition_fade_layer(
833 struct ivi_layout_layer *layer,
834 uint32_t is_fade_in,
835 double start_alpha, double end_alpha,
836 void* user_data,
837 ivi_layout_transition_destroy_user_func destroy_func,
838 uint32_t duration)
839{
840 struct ivi_layout_transition *transition;
841 struct fade_layer_data *data = NULL;
842 wl_fixed_t fixed_opacity = 0.0;
843 double now_opacity = 0.0;
844 double remain = 0.0;
845
846 transition = get_transition_from_type_and_id(
847 IVI_LAYOUT_TRANSITION_LAYER_FADE,
848 layer);
849 if (transition) {
850 /* transition update */
851 data = transition->private_data;
852
853 /* FIXME */
Ucan, Emre \(ADITG/SW1\)c3aee1f2016-03-04 12:50:16 +0000854 fixed_opacity = layer->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900855 now_opacity = wl_fixed_to_double(fixed_opacity);
856 remain = 0.0;
857
858 data->is_fade_in = is_fade_in;
859 data->start_alpha = now_opacity;
860 data->end_alpha = end_alpha;
861
862 remain = is_fade_in? 1.0 - now_opacity : now_opacity;
863 transition->time_start = 0;
864 transition->time_elapsed = 0;
865 transition->time_duration = duration * remain;
866
867 return;
868 }
869
870 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100871 if (transition == NULL)
872 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900873
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100874 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900875 if (data == NULL) {
876 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300877 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900878 return;
879 }
880
881 transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
882 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
883
884 transition->private_data = data;
885 transition->user_data = user_data;
886
887 transition->frame_func = transition_fade_layer_user_frame;
888 transition->destroy_func = transition_fade_layer_destroy;
889
890 if (duration != 0)
891 transition->time_duration = duration;
892
893 data->layer = layer;
894 data->is_fade_in = is_fade_in;
895 data->start_alpha = start_alpha;
896 data->end_alpha = end_alpha;
897 data->destroy_func = destroy_func;
898
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300899 if (!layout_transition_register(transition))
900 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900901
902 return;
903}
904