• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 DENSO CORPORATION
3  *
4  * 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:
11  *
12  * 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.
24  */
25 
26 #include "config.h"
27 
28 #include <time.h>
29 #include <assert.h>
30 #include <stdlib.h>
31 #include <stdint.h>
32 #include <stdio.h>
33 #include <stdbool.h>
34 
35 #include "ivi-shell.h"
36 #include "ivi-layout-export.h"
37 #include "ivi-layout-private.h"
38 
39 struct ivi_layout_transition;
40 
41 typedef void (*ivi_layout_transition_frame_func)(
42 			struct ivi_layout_transition *transition);
43 typedef void (*ivi_layout_transition_destroy_func)(
44 			struct ivi_layout_transition *transition);
45 typedef int32_t (*ivi_layout_is_transition_func)(void *private_data, void *id);
46 
47 struct 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 
61 struct transition_node {
62 	struct ivi_layout_transition *transition;
63 
64 	/* ivi_layout::pending_transition_list
65 	 * ivi_layout_transition_set::transition_list
66 	 */
67 	struct wl_list link;
68 };
69 
70 static void layout_transition_destroy(struct ivi_layout_transition *transition);
71 
72 static struct ivi_layout_transition *
get_transition_from_type_and_id(enum ivi_layout_transition_type type,void * id_data)73 get_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 
91 int32_t
is_surface_transition(struct ivi_layout_surface * surface)92 is_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 
110 void
ivi_layout_remove_all_surface_transitions(struct ivi_layout_surface * surface)111 ivi_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 
126 static void
tick_transition(struct ivi_layout_transition * transition,uint32_t timestamp)127 tick_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 
time_to_nowpos(struct ivi_layout_transition * transition)139 static 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 
145 static void
do_transition_frame(struct ivi_layout_transition * transition,uint32_t timestamp)146 do_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 
159 static int32_t
layout_transition_frame(void * data)160 layout_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 
187 struct ivi_layout_transition_set *
ivi_layout_transition_set_create(struct weston_compositor * ec)188 ivi_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 
209 static bool
layout_transition_register(struct ivi_layout_transition * trans)210 layout_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__);
218 		return false;
219 	}
220 
221 	node->transition = trans;
222 	wl_list_insert(&layout->pending_transition_list, &node->link);
223 	return true;
224 }
225 
226 static void
remove_transition(struct ivi_layout * layout,struct ivi_layout_transition * trans)227 remove_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 
252 static void
layout_transition_destroy(struct ivi_layout_transition * transition)253 layout_transition_destroy(struct ivi_layout_transition *transition)
254 {
255 	struct ivi_layout *layout = get_instance();
256 
257 	remove_transition(layout, transition);
258 	if (transition->destroy_func)
259 		transition->destroy_func(transition);
260 	free(transition);
261 }
262 
263 static struct ivi_layout_transition *
create_layout_transition(void)264 create_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 
280 	transition->is_transition_func = NULL;
281 	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 
292 struct 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 
304 static void
transition_move_resize_view_destroy(struct ivi_layout_transition * transition)305 transition_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 
311 	ivi_layout_surface_set_size(layout_surface,
312 				    layout_surface->prop.dest_width,
313 				    layout_surface->prop.dest_height);
314 
315 	if (transition->private_data) {
316 		free(transition->private_data);
317 		transition->private_data = NULL;
318 	}
319 }
320 
321 static void
transition_move_resize_view_user_frame(struct ivi_layout_transition * transition)322 transition_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 
344 static int32_t
is_transition_move_resize_view_func(struct move_resize_view_data * data,struct ivi_layout_surface * view)345 is_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 
351 static struct ivi_layout_transition *
create_move_resize_view_transition(struct ivi_layout_surface * surface,int32_t start_x,int32_t start_y,int32_t end_x,int32_t end_y,int32_t start_width,int32_t start_height,int32_t end_width,int32_t end_height,ivi_layout_transition_frame_func frame_func,ivi_layout_transition_destroy_func destroy_func,uint32_t duration)352 create_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 {
362 	struct ivi_layout_transition *transition;
363 	struct move_resize_view_data *data;
364 
365 	transition = create_layout_transition();
366 	if (transition == NULL)
367 		return NULL;
368 
369 	data = malloc(sizeof(*data));
370 	if (data == NULL) {
371 		weston_log("%s: memory allocation fails\n", __func__);
372 		free(transition);
373 		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 
400 void
ivi_layout_transition_move_resize_view(struct ivi_layout_surface * surface,int32_t dest_x,int32_t dest_y,int32_t dest_width,int32_t dest_height,uint32_t duration)401 ivi_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 
447 	if (transition && layout_transition_register(transition))
448 		return;
449 	layout_transition_destroy(transition);
450 }
451 
452 /* fade transition */
453 struct fade_view_data {
454 	struct ivi_layout_surface *surface;
455 	double start_alpha;
456 	double end_alpha;
457 };
458 
459 struct store_alpha{
460 	double alpha;
461 };
462 
463 static void
fade_view_user_frame(struct ivi_layout_transition * transition)464 fade_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 
477 static int32_t
is_transition_fade_view_func(struct fade_view_data * data,struct ivi_layout_surface * view)478 is_transition_fade_view_func(struct fade_view_data *data,
479 			     struct ivi_layout_surface *view)
480 {
481 	return data->surface == view;
482 }
483 
484 static struct ivi_layout_transition *
create_fade_view_transition(struct ivi_layout_surface * surface,double start_alpha,double end_alpha,ivi_layout_transition_frame_func frame_func,void * user_data,ivi_layout_transition_destroy_func destroy_func,uint32_t duration)485 create_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 {
493 	struct ivi_layout_transition *transition;
494 	struct fade_view_data *data;
495 
496 	transition = create_layout_transition();
497 	if (transition == NULL)
498 		return NULL;
499 
500 	data = malloc(sizeof(*data));
501 	if (data == NULL) {
502 		weston_log("%s: memory allocation fails\n", __func__);
503 		free(transition);
504 		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 
525 static void
create_visibility_transition(struct ivi_layout_surface * surface,double start_alpha,double dest_alpha,void * user_data,ivi_layout_transition_destroy_func destroy_func,uint32_t duration)526 create_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 
543 	if (transition && layout_transition_register(transition))
544 		return;
545 	layout_transition_destroy(transition);
546 }
547 
548 static void
visibility_on_transition_destroy(struct ivi_layout_transition * transition)549 visibility_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 
563 void
ivi_layout_transition_visibility_on(struct ivi_layout_surface * surface,uint32_t duration)564 ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
565 				    uint32_t duration)
566 {
567 	struct ivi_layout_transition *transition;
568 	bool is_visible = surface->prop.visibility;
569 	wl_fixed_t dest_alpha = surface->prop.opacity;
570 	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) {
578 		start_alpha = surface->prop.opacity;
579 		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 
610 static void
visibility_off_transition_destroy(struct ivi_layout_transition * transition)611 visibility_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 
628 void
ivi_layout_transition_visibility_off(struct ivi_layout_surface * surface,uint32_t duration)629 ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
630 				     uint32_t duration)
631 {
632 	struct ivi_layout_transition *transition;
633 	wl_fixed_t start_alpha = surface->prop.opacity;
634 	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 
670 struct 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 
679 static void
transition_move_layer_user_frame(struct ivi_layout_transition * transition)680 transition_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 
693 	ivi_layout_layer_set_destination_rectangle(layer, dest_x, dest_y,
694 			layer->prop.dest_width, layer->prop.dest_height);
695 }
696 
697 static void
transition_move_layer_destroy(struct ivi_layout_transition * transition)698 transition_move_layer_destroy(struct ivi_layout_transition *transition)
699 {
700 	struct move_layer_data *data = transition->private_data;
701 
702 	if (data->destroy_func)
703 		data->destroy_func(transition->user_data);
704 
705 	free(data);
706 	transition->private_data = NULL;
707 }
708 
709 static int32_t
is_transition_move_layer_func(struct move_layer_data * data,struct ivi_layout_layer * layer)710 is_transition_move_layer_func(struct move_layer_data *data,
711 			      struct ivi_layout_layer *layer)
712 {
713 	return data->layer == layer;
714 }
715 
716 
717 static struct ivi_layout_transition *
create_move_layer_transition(struct ivi_layout_layer * layer,int32_t start_x,int32_t start_y,int32_t end_x,int32_t end_y,void * user_data,ivi_layout_transition_destroy_user_func destroy_user_func,uint32_t duration)718 create_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 {
726 	struct ivi_layout_transition *transition;
727 	struct move_layer_data *data;
728 
729 	transition = create_layout_transition();
730 	if (transition == NULL)
731 		return NULL;
732 
733 	data = malloc(sizeof(*data));
734 	if (data == NULL) {
735 		weston_log("%s: memory allocation fails\n", __func__);
736 		free(transition);
737 		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 
761 void
ivi_layout_transition_move_layer(struct ivi_layout_layer * layer,int32_t dest_x,int32_t dest_y,uint32_t duration)762 ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
763 				 int32_t dest_x, int32_t dest_y,
764 				 uint32_t duration)
765 {
766 	int32_t start_pos_x = layer->prop.dest_x;
767 	int32_t start_pos_y = layer->prop.dest_y;
768 	struct ivi_layout_transition *transition = NULL;
769 
770 	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 
777 	if (transition && layout_transition_register(transition))
778 		return;
779 
780 	free(transition);
781 }
782 
783 void
ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer * layer)784 ivi_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 */
796 struct 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 
804 static void
transition_fade_layer_destroy(struct ivi_layout_transition * transition)805 transition_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 
813 static void
transition_fade_layer_user_frame(struct ivi_layout_transition * transition)814 transition_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 
829 static int32_t
is_transition_fade_layer_func(struct fade_layer_data * data,struct ivi_layout_layer * layer)830 is_transition_fade_layer_func(struct fade_layer_data *data,
831 			      struct ivi_layout_layer *layer)
832 {
833 	return data->layer == layer;
834 }
835 
836 void
ivi_layout_transition_fade_layer(struct ivi_layout_layer * layer,uint32_t is_fade_in,double start_alpha,double end_alpha,void * user_data,ivi_layout_transition_destroy_user_func destroy_func,uint32_t duration)837 ivi_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;
847 	wl_fixed_t fixed_opacity;
848 	double now_opacity;
849 	double remain;
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 */
859 		fixed_opacity = layer->prop.opacity;
860 		now_opacity = wl_fixed_to_double(fixed_opacity);
861 
862 		data->is_fade_in = is_fade_in;
863 		data->start_alpha = now_opacity;
864 		data->end_alpha = end_alpha;
865 
866 		remain = is_fade_in? 1.0 - now_opacity : now_opacity;
867 		transition->time_start = 0;
868 		transition->time_elapsed = 0;
869 		transition->time_duration = duration * remain;
870 
871 		return;
872 	}
873 
874 	transition = create_layout_transition();
875 	if (transition == NULL)
876 		return;
877 
878 	data = malloc(sizeof(*data));
879 	if (data == NULL) {
880 		weston_log("%s: memory allocation fails\n", __func__);
881 		free(transition);
882 		return;
883 	}
884 
885 	transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
886 	transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
887 
888 	transition->private_data = data;
889 	transition->user_data = user_data;
890 
891 	transition->frame_func = transition_fade_layer_user_frame;
892 	transition->destroy_func = transition_fade_layer_destroy;
893 
894 	if (duration != 0)
895 		transition->time_duration = duration;
896 
897 	data->layer = layer;
898 	data->is_fade_in = is_fade_in;
899 	data->start_alpha = start_alpha;
900 	data->end_alpha = end_alpha;
901 	data->destroy_func = destroy_func;
902 
903 	if (!layout_transition_register(transition))
904 		layout_transition_destroy(transition);
905 
906 	return;
907 }
908 
909