blob: bf0640ee0c69d8a1d096f1d72023c8cb5bd28da9 [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;
63 struct wl_list link;
64};
65
66static void layout_transition_destroy(struct ivi_layout_transition *transition);
67
68static struct ivi_layout_transition *
69get_transition_from_type_and_id(enum ivi_layout_transition_type type,
70 void *id_data)
71{
72 struct ivi_layout *layout = get_instance();
73 struct transition_node *node;
74 struct ivi_layout_transition *tran;
75
76 wl_list_for_each(node, &layout->transitions->transition_list, link) {
77 tran = node->transition;
78
79 if (tran->type == type &&
80 tran->is_transition_func(tran->private_data, id_data))
81 return tran;
82 }
83
84 return NULL;
85}
86
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +090087int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090088is_surface_transition(struct ivi_layout_surface *surface)
89{
90 struct ivi_layout *layout = get_instance();
91 struct transition_node *node;
92 struct ivi_layout_transition *tran;
93
94 wl_list_for_each(node, &layout->transitions->transition_list, link) {
95 tran = node->transition;
96
97 if ((tran->type == IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE ||
98 tran->type == IVI_LAYOUT_TRANSITION_VIEW_RESIZE) &&
99 tran->is_transition_func(tran->private_data, surface))
100 return 1;
101 }
102
103 return 0;
104}
105
Mateusz Polroladada6e32016-03-09 09:13:26 +0000106void
107ivi_layout_remove_all_surface_transitions(struct ivi_layout_surface *surface)
108{
109 struct ivi_layout *layout = get_instance();
110 struct transition_node *node;
111 struct transition_node *tmp;
112 struct ivi_layout_transition *tran;
113
114 wl_list_for_each_safe(node, tmp, &layout->transitions->transition_list, link) {
115 tran = node->transition;
116 if (tran->is_transition_func(tran->private_data, surface)) {
117 layout_transition_destroy(tran);
118 }
119 };
120}
121
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900122static void
123tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp)
124{
125 const double t = timestamp - transition->time_start;
126
127 if (transition->time_duration <= t) {
128 transition->time_elapsed = transition->time_duration;
129 transition->is_done = 1;
130 } else {
131 transition->time_elapsed = t;
132 }
133}
134
135static float time_to_nowpos(struct ivi_layout_transition *transition)
136{
137 return sin((float)transition->time_elapsed /
138 (float)transition->time_duration * M_PI_2);
139}
140
141static void
142do_transition_frame(struct ivi_layout_transition *transition,
143 uint32_t timestamp)
144{
145 if (0 == transition->time_start)
146 transition->time_start = timestamp;
147
148 tick_transition(transition, timestamp);
149 transition->frame_func(transition);
150
151 if (transition->is_done)
152 layout_transition_destroy(transition);
153}
154
155static int32_t
156layout_transition_frame(void *data)
157{
158 struct ivi_layout_transition_set *transitions = data;
159 uint32_t fps = 30;
160 struct timespec timestamp = {};
161 uint32_t msec = 0;
162 struct transition_node *node = NULL;
163 struct transition_node *next = NULL;
164
165 if (wl_list_empty(&transitions->transition_list)) {
166 wl_event_source_timer_update(transitions->event_source, 0);
167 return 1;
168 }
169
170 wl_event_source_timer_update(transitions->event_source, 1000 / fps);
171
172 clock_gettime(CLOCK_MONOTONIC, &timestamp);/* FIXME */
173 msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec);
174
175 wl_list_for_each_safe(node, next, &transitions->transition_list, link) {
176 do_transition_frame(node->transition, msec);
177 }
178
179 ivi_layout_commit_changes();
180 return 1;
181}
182
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900183struct ivi_layout_transition_set *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900184ivi_layout_transition_set_create(struct weston_compositor *ec)
185{
186 struct ivi_layout_transition_set *transitions;
187 struct wl_event_loop *loop;
188
189 transitions = malloc(sizeof(*transitions));
190 if (transitions == NULL) {
191 weston_log("%s: memory allocation fails\n", __func__);
192 return NULL;
193 }
194
195 wl_list_init(&transitions->transition_list);
196
197 loop = wl_display_get_event_loop(ec->wl_display);
198 transitions->event_source =
199 wl_event_loop_add_timer(loop, layout_transition_frame,
200 transitions);
201
202 return transitions;
203}
204
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300205static bool
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900206layout_transition_register(struct ivi_layout_transition *trans)
207{
208 struct ivi_layout *layout = get_instance();
209 struct transition_node *node;
210
211 node = malloc(sizeof(*node));
212 if (node == NULL) {
213 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300214 return false;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900215 }
216
217 node->transition = trans;
218 wl_list_insert(&layout->pending_transition_list, &node->link);
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300219 return true;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900220}
221
222static void
223remove_transition(struct ivi_layout *layout,
224 struct ivi_layout_transition *trans)
225{
226 struct transition_node *node;
227 struct transition_node *next;
228
229 wl_list_for_each_safe(node, next,
230 &layout->transitions->transition_list, link) {
231 if (node->transition == trans) {
232 wl_list_remove(&node->link);
233 free(node);
234 return;
235 }
236 }
237
238 wl_list_for_each_safe(node, next,
239 &layout->pending_transition_list, link) {
240 if (node->transition == trans) {
241 wl_list_remove(&node->link);
242 free(node);
243 return;
244 }
245 }
246}
247
248static void
249layout_transition_destroy(struct ivi_layout_transition *transition)
250{
251 struct ivi_layout *layout = get_instance();
252
253 remove_transition(layout, transition);
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300254 if (transition->destroy_func)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900255 transition->destroy_func(transition);
256 free(transition);
257}
258
259static struct ivi_layout_transition *
260create_layout_transition(void)
261{
262 struct ivi_layout_transition *transition = malloc(sizeof(*transition));
263
264 if (transition == NULL) {
265 weston_log("%s: memory allocation fails\n", __func__);
266 return NULL;
267 }
268
269 transition->type = IVI_LAYOUT_TRANSITION_MAX;
270 transition->time_start = 0;
271 transition->time_duration = 300; /* 300ms */
272 transition->time_elapsed = 0;
273
274 transition->is_done = 0;
275
John-John Tedro9d7aff02015-09-20 02:47:37 +0200276 transition->is_transition_func = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900277 transition->private_data = NULL;
278 transition->user_data = NULL;
279
280 transition->frame_func = NULL;
281 transition->destroy_func = NULL;
282
283 return transition;
284}
285
286/* move and resize view transition */
287
288struct move_resize_view_data {
289 struct ivi_layout_surface *surface;
290 int32_t start_x;
291 int32_t start_y;
292 int32_t end_x;
293 int32_t end_y;
294 int32_t start_width;
295 int32_t start_height;
296 int32_t end_width;
297 int32_t end_height;
298};
299
300static void
301transition_move_resize_view_destroy(struct ivi_layout_transition *transition)
302{
303 struct move_resize_view_data *data =
304 (struct move_resize_view_data *)transition->private_data;
305 struct ivi_layout_surface *layout_surface = data->surface;
306
Pekka Paalanen1f821932016-03-15 16:57:51 +0200307 shell_surface_send_configure(layout_surface->surface,
308 layout_surface->prop.dest_width,
309 layout_surface->prop.dest_height);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900310
311 if (transition->private_data) {
312 free(transition->private_data);
313 transition->private_data = NULL;
314 }
315}
316
317static void
318transition_move_resize_view_user_frame(struct ivi_layout_transition *transition)
319{
320 struct move_resize_view_data *mrv = transition->private_data;
321 const double current = time_to_nowpos(transition);
322
323 const int32_t destx = mrv->start_x +
324 (mrv->end_x - mrv->start_x) * current;
325
326 const int32_t desty = mrv->start_y +
327 (mrv->end_y - mrv->start_y) * current;
328
329 const int32_t dest_width = mrv->start_width +
330 (mrv->end_width - mrv->start_width) * current;
331
332 const int32_t dest_height = mrv->start_height +
333 (mrv->end_height - mrv->start_height) * current;
334
335 ivi_layout_surface_set_destination_rectangle(mrv->surface,
336 destx, desty,
337 dest_width, dest_height);
338}
339
340static int32_t
341is_transition_move_resize_view_func(struct move_resize_view_data *data,
342 struct ivi_layout_surface *view)
343{
344 return data->surface == view;
345}
346
347static struct ivi_layout_transition *
348create_move_resize_view_transition(
349 struct ivi_layout_surface *surface,
350 int32_t start_x, int32_t start_y,
351 int32_t end_x, int32_t end_y,
352 int32_t start_width, int32_t start_height,
353 int32_t end_width, int32_t end_height,
354 ivi_layout_transition_frame_func frame_func,
355 ivi_layout_transition_destroy_func destroy_func,
356 uint32_t duration)
357{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100358 struct ivi_layout_transition *transition;
359 struct move_resize_view_data *data;
360
361 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100362 if (transition == NULL)
363 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900364
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100365 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900366 if (data == NULL) {
367 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300368 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900369 return NULL;
370 }
371
372 transition->type = IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE;
373 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_resize_view_func;
374
375 transition->frame_func = frame_func;
376 transition->destroy_func = destroy_func;
377 transition->private_data = data;
378
379 if (duration != 0)
380 transition->time_duration = duration;
381
382 data->surface = surface;
383 data->start_x = start_x;
384 data->start_y = start_y;
385 data->end_x = end_x;
386 data->end_y = end_y;
387
388 data->start_width = start_width;
389 data->start_height = start_height;
390 data->end_width = end_width;
391 data->end_height = end_height;
392
393 return transition;
394}
395
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900396void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900397ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface,
398 int32_t dest_x, int32_t dest_y,
399 int32_t dest_width, int32_t dest_height,
400 uint32_t duration)
401{
402 struct ivi_layout_transition *transition;
403 int32_t start_pos[2] = {
404 surface->pending.prop.start_x,
405 surface->pending.prop.start_y
406 };
407
408 int32_t start_size[2] = {
409 surface->pending.prop.start_width,
410 surface->pending.prop.start_height
411 };
412
413 transition = get_transition_from_type_and_id(
414 IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
415 surface);
416 if (transition) {
417 struct move_resize_view_data *data = transition->private_data;
418 transition->time_start = 0;
419 transition->time_duration = duration;
420
421 data->start_x = start_pos[0];
422 data->start_y = start_pos[1];
423 data->end_x = dest_x;
424 data->end_y = dest_y;
425
426 data->start_width = start_size[0];
427 data->start_height = start_size[1];
428 data->end_width = dest_width;
429 data->end_height = dest_height;
430 return;
431 }
432
433 transition = create_move_resize_view_transition(
434 surface,
435 start_pos[0], start_pos[1],
436 dest_x, dest_y,
437 start_size[0], start_size[1],
438 dest_width, dest_height,
439 transition_move_resize_view_user_frame,
440 transition_move_resize_view_destroy,
441 duration);
442
Bryce Harrington1dbdc0b2016-07-12 16:59:05 -0700443 if (transition && layout_transition_register(transition))
Lucas Tanurea3377cd2015-09-30 09:38:37 -0300444 return;
445 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900446}
447
448/* fade transition */
449struct fade_view_data {
450 struct ivi_layout_surface *surface;
451 double start_alpha;
452 double end_alpha;
453};
454
455struct store_alpha{
456 double alpha;
457};
458
459static void
460fade_view_user_frame(struct ivi_layout_transition *transition)
461{
462 struct fade_view_data *fade = transition->private_data;
463 struct ivi_layout_surface *surface = fade->surface;
464
465 const double current = time_to_nowpos(transition);
466 const double alpha = fade->start_alpha +
467 (fade->end_alpha - fade->start_alpha) * current;
468
469 ivi_layout_surface_set_opacity(surface, wl_fixed_from_double(alpha));
470 ivi_layout_surface_set_visibility(surface, true);
471}
472
473static int32_t
474is_transition_fade_view_func(struct fade_view_data *data,
475 struct ivi_layout_surface *view)
476{
477 return data->surface == view;
478}
479
480static struct ivi_layout_transition *
481create_fade_view_transition(
482 struct ivi_layout_surface *surface,
483 double start_alpha, double end_alpha,
484 ivi_layout_transition_frame_func frame_func,
485 void *user_data,
486 ivi_layout_transition_destroy_func destroy_func,
487 uint32_t duration)
488{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100489 struct ivi_layout_transition *transition;
490 struct fade_view_data *data;
491
492 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100493 if (transition == NULL)
494 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900495
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100496 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900497 if (data == NULL) {
498 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300499 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900500 return NULL;
501 }
502
503 transition->type = IVI_LAYOUT_TRANSITION_VIEW_FADE;
504 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_view_func;
505
506 transition->user_data = user_data;
507 transition->private_data = data;
508 transition->frame_func = frame_func;
509 transition->destroy_func = destroy_func;
510
511 if (duration != 0)
512 transition->time_duration = duration;
513
514 data->surface = surface;
515 data->start_alpha = start_alpha;
516 data->end_alpha = end_alpha;
517
518 return transition;
519}
520
521static void
522create_visibility_transition(struct ivi_layout_surface *surface,
523 double start_alpha,
524 double dest_alpha,
525 void *user_data,
526 ivi_layout_transition_destroy_func destroy_func,
527 uint32_t duration)
528{
529 struct ivi_layout_transition *transition = NULL;
530
531 transition = create_fade_view_transition(
532 surface,
533 start_alpha, dest_alpha,
534 fade_view_user_frame,
535 user_data,
536 destroy_func,
537 duration);
538
Lucas Tanurea3377cd2015-09-30 09:38:37 -0300539 if (transition && layout_transition_register(transition))
540 return;
541 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900542}
543
544static void
545visibility_on_transition_destroy(struct ivi_layout_transition *transition)
546{
547 struct fade_view_data *data = transition->private_data;
548 struct store_alpha *user_data = transition->user_data;
549
550 ivi_layout_surface_set_visibility(data->surface, true);
551
552 free(data);
553 transition->private_data = NULL;
554
555 free(user_data);
556 transition->user_data = NULL;
557}
558
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900559void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900560ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
561 uint32_t duration)
562{
563 struct ivi_layout_transition *transition;
Ucan, Emre \(ADITG/SW1\)c6a138c2016-03-04 12:50:06 +0000564 bool is_visible = surface->prop.visibility;
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000565 wl_fixed_t dest_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900566 struct store_alpha *user_data = NULL;
567 wl_fixed_t start_alpha = 0.0;
568 struct fade_view_data *data = NULL;
569
570 transition = get_transition_from_type_and_id(
571 IVI_LAYOUT_TRANSITION_VIEW_FADE,
572 surface);
573 if (transition) {
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000574 start_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900575 user_data = transition->user_data;
576 data = transition->private_data;
577
578 transition->time_start = 0;
579 transition->time_duration = duration;
580 transition->destroy_func = visibility_on_transition_destroy;
581
582 data->start_alpha = wl_fixed_to_double(start_alpha);
583 data->end_alpha = user_data->alpha;
584 return;
585 }
586
587 if (is_visible)
588 return;
589
590 user_data = malloc(sizeof(*user_data));
591 if (user_data == NULL) {
592 weston_log("%s: memory allocation fails\n", __func__);
593 return;
594 }
595
596 user_data->alpha = wl_fixed_to_double(dest_alpha);
597
598 create_visibility_transition(surface,
599 0.0, // start_alpha
600 wl_fixed_to_double(dest_alpha),
601 user_data,
602 visibility_on_transition_destroy,
603 duration);
604}
605
606static void
607visibility_off_transition_destroy(struct ivi_layout_transition *transition)
608{
609 struct fade_view_data *data = transition->private_data;
610 struct store_alpha *user_data = transition->user_data;
611
612 ivi_layout_surface_set_visibility(data->surface, false);
613
614 ivi_layout_surface_set_opacity(data->surface,
615 wl_fixed_from_double(user_data->alpha));
616
617 free(data);
618 transition->private_data = NULL;
619
620 free(user_data);
621 transition->user_data= NULL;
622}
623
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900624void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900625ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
626 uint32_t duration)
627{
628 struct ivi_layout_transition *transition;
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000629 wl_fixed_t start_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900630 struct store_alpha* user_data = NULL;
631 struct fade_view_data* data = NULL;
632
633 transition =
634 get_transition_from_type_and_id(IVI_LAYOUT_TRANSITION_VIEW_FADE,
635 surface);
636 if (transition) {
637 data = transition->private_data;
638
639 transition->time_start = 0;
640 transition->time_duration = duration;
641 transition->destroy_func = visibility_off_transition_destroy;
642
643 data->start_alpha = wl_fixed_to_double(start_alpha);
644 data->end_alpha = 0;
645 return;
646 }
647
648 user_data = malloc(sizeof(*user_data));
649 if (user_data == NULL) {
650 weston_log("%s: memory allocation fails\n", __func__);
651 return;
652 }
653
654 user_data->alpha = wl_fixed_to_double(start_alpha);
655
656 create_visibility_transition(surface,
657 wl_fixed_to_double(start_alpha),
658 0.0, // dest_alpha
659 user_data,
660 visibility_off_transition_destroy,
661 duration);
662}
663
664/* move layer transition */
665
666struct move_layer_data {
667 struct ivi_layout_layer *layer;
668 int32_t start_x;
669 int32_t start_y;
670 int32_t end_x;
671 int32_t end_y;
672 ivi_layout_transition_destroy_user_func destroy_func;
673};
674
675static void
676transition_move_layer_user_frame(struct ivi_layout_transition *transition)
677{
678 struct move_layer_data *data = transition->private_data;
679 struct ivi_layout_layer *layer = data->layer;
680
681 const float current = time_to_nowpos(transition);
682
683 const int32_t dest_x = data->start_x +
684 (data->end_x - data->start_x) * current;
685
686 const int32_t dest_y = data->start_y +
687 (data->end_y - data->start_y) * current;
688
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +0000689 ivi_layout_layer_set_destination_rectangle(layer, dest_x, dest_y,
690 layer->prop.dest_width, layer->prop.dest_height);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900691}
692
693static void
694transition_move_layer_destroy(struct ivi_layout_transition *transition)
695{
696 struct move_layer_data *data = transition->private_data;
697
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300698 if (data->destroy_func)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900699 data->destroy_func(transition->user_data);
700
701 free(data);
702 transition->private_data = NULL;
703}
704
705static int32_t
706is_transition_move_layer_func(struct move_layer_data *data,
707 struct ivi_layout_layer *layer)
708{
709 return data->layer == layer;
710}
711
712
713static struct ivi_layout_transition *
714create_move_layer_transition(
715 struct ivi_layout_layer *layer,
716 int32_t start_x, int32_t start_y,
717 int32_t end_x, int32_t end_y,
718 void *user_data,
719 ivi_layout_transition_destroy_user_func destroy_user_func,
720 uint32_t duration)
721{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100722 struct ivi_layout_transition *transition;
723 struct move_layer_data *data;
724
725 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100726 if (transition == NULL)
727 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900728
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100729 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900730 if (data == NULL) {
731 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300732 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900733 return NULL;
734 }
735
736 transition->type = IVI_LAYOUT_TRANSITION_LAYER_MOVE;
737 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_layer_func;
738
739 transition->frame_func = transition_move_layer_user_frame;
740 transition->destroy_func = transition_move_layer_destroy;
741 transition->private_data = data;
742 transition->user_data = user_data;
743
744 if (duration != 0)
745 transition->time_duration = duration;
746
747 data->layer = layer;
748 data->start_x = start_x;
749 data->start_y = start_y;
750 data->end_x = end_x;
751 data->end_y = end_y;
752 data->destroy_func = destroy_user_func;
753
754 return transition;
755}
756
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900757void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900758ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
759 int32_t dest_x, int32_t dest_y,
760 uint32_t duration)
761{
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +0000762 int32_t start_pos_x = layer->prop.dest_x;
763 int32_t start_pos_y = layer->prop.dest_y;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900764 struct ivi_layout_transition *transition = NULL;
765
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900766 transition = create_move_layer_transition(
767 layer,
768 start_pos_x, start_pos_y,
769 dest_x, dest_y,
770 NULL, NULL,
771 duration);
772
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300773 if (transition && layout_transition_register(transition))
774 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900775
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300776 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900777}
778
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900779void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900780ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer)
781{
782 struct ivi_layout_transition *transition =
783 get_transition_from_type_and_id(
784 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
785 layer);
786 if (transition) {
787 layout_transition_destroy(transition);
788 }
789}
790
791/* fade layer transition */
792struct fade_layer_data {
793 struct ivi_layout_layer *layer;
794 uint32_t is_fade_in;
795 double start_alpha;
796 double end_alpha;
797 ivi_layout_transition_destroy_user_func destroy_func;
798};
799
800static void
801transition_fade_layer_destroy(struct ivi_layout_transition *transition)
802{
803 struct fade_layer_data *data = transition->private_data;
804 transition->private_data = NULL;
805
806 free(data);
807}
808
809static void
810transition_fade_layer_user_frame(struct ivi_layout_transition *transition)
811{
812 double current = time_to_nowpos(transition);
813 struct fade_layer_data *data = transition->private_data;
814 double alpha = data->start_alpha +
815 (data->end_alpha - data->start_alpha) * current;
816 wl_fixed_t fixed_alpha = wl_fixed_from_double(alpha);
817
818 int32_t is_done = transition->is_done;
819 bool is_visible = !is_done || data->is_fade_in;
820
821 ivi_layout_layer_set_opacity(data->layer, fixed_alpha);
822 ivi_layout_layer_set_visibility(data->layer, is_visible);
823}
824
825static int32_t
826is_transition_fade_layer_func(struct fade_layer_data *data,
827 struct ivi_layout_layer *layer)
828{
829 return data->layer == layer;
830}
831
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900832void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900833ivi_layout_transition_fade_layer(
834 struct ivi_layout_layer *layer,
835 uint32_t is_fade_in,
836 double start_alpha, double end_alpha,
837 void* user_data,
838 ivi_layout_transition_destroy_user_func destroy_func,
839 uint32_t duration)
840{
841 struct ivi_layout_transition *transition;
842 struct fade_layer_data *data = NULL;
843 wl_fixed_t fixed_opacity = 0.0;
844 double now_opacity = 0.0;
845 double remain = 0.0;
846
847 transition = get_transition_from_type_and_id(
848 IVI_LAYOUT_TRANSITION_LAYER_FADE,
849 layer);
850 if (transition) {
851 /* transition update */
852 data = transition->private_data;
853
854 /* FIXME */
Ucan, Emre \(ADITG/SW1\)c3aee1f2016-03-04 12:50:16 +0000855 fixed_opacity = layer->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900856 now_opacity = wl_fixed_to_double(fixed_opacity);
857 remain = 0.0;
858
859 data->is_fade_in = is_fade_in;
860 data->start_alpha = now_opacity;
861 data->end_alpha = end_alpha;
862
863 remain = is_fade_in? 1.0 - now_opacity : now_opacity;
864 transition->time_start = 0;
865 transition->time_elapsed = 0;
866 transition->time_duration = duration * remain;
867
868 return;
869 }
870
871 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100872 if (transition == NULL)
873 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900874
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100875 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900876 if (data == NULL) {
877 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300878 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900879 return;
880 }
881
882 transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
883 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
884
885 transition->private_data = data;
886 transition->user_data = user_data;
887
888 transition->frame_func = transition_fade_layer_user_frame;
889 transition->destroy_func = transition_fade_layer_destroy;
890
891 if (duration != 0)
892 transition->time_duration = duration;
893
894 data->layer = layer;
895 data->is_fade_in = is_fade_in;
896 data->start_alpha = start_alpha;
897 data->end_alpha = end_alpha;
898 data->destroy_func = destroy_func;
899
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300900 if (!layout_transition_register(transition))
901 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900902
903 return;
904}
905