905 lines
23 KiB
C
905 lines
23 KiB
C
/*
|
|
* Copyright (C) 2014 DENSO CORPORATION
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
* a copy of this software and associated documentation files (the
|
|
* "Software"), to deal in the Software without restriction, including
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
* the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the
|
|
* next paragraph) shall be included in all copies or substantial
|
|
* portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <time.h>
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "ivi-shell.h"
|
|
#include "ivi-layout-export.h"
|
|
#include "ivi-layout-private.h"
|
|
|
|
struct ivi_layout_transition;
|
|
|
|
typedef void (*ivi_layout_transition_frame_func)(
|
|
struct ivi_layout_transition *transition);
|
|
typedef void (*ivi_layout_transition_destroy_func)(
|
|
struct ivi_layout_transition *transition);
|
|
typedef int32_t (*ivi_layout_is_transition_func)(void *private_data, void *id);
|
|
|
|
struct ivi_layout_transition {
|
|
enum ivi_layout_transition_type type;
|
|
void *private_data;
|
|
void *user_data;
|
|
|
|
uint32_t time_start;
|
|
uint32_t time_duration;
|
|
uint32_t time_elapsed;
|
|
uint32_t is_done;
|
|
ivi_layout_is_transition_func is_transition_func;
|
|
ivi_layout_transition_frame_func frame_func;
|
|
ivi_layout_transition_destroy_func destroy_func;
|
|
};
|
|
|
|
struct transition_node {
|
|
struct ivi_layout_transition *transition;
|
|
struct wl_list link;
|
|
};
|
|
|
|
static void layout_transition_destroy(struct ivi_layout_transition *transition);
|
|
|
|
static struct ivi_layout_transition *
|
|
get_transition_from_type_and_id(enum ivi_layout_transition_type type,
|
|
void *id_data)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct transition_node *node;
|
|
struct ivi_layout_transition *tran;
|
|
|
|
wl_list_for_each(node, &layout->transitions->transition_list, link) {
|
|
tran = node->transition;
|
|
|
|
if (tran->type == type &&
|
|
tran->is_transition_func(tran->private_data, id_data))
|
|
return tran;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int32_t
|
|
is_surface_transition(struct ivi_layout_surface *surface)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct transition_node *node;
|
|
struct ivi_layout_transition *tran;
|
|
|
|
wl_list_for_each(node, &layout->transitions->transition_list, link) {
|
|
tran = node->transition;
|
|
|
|
if ((tran->type == IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE ||
|
|
tran->type == IVI_LAYOUT_TRANSITION_VIEW_RESIZE) &&
|
|
tran->is_transition_func(tran->private_data, surface))
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
ivi_layout_remove_all_surface_transitions(struct ivi_layout_surface *surface)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct transition_node *node;
|
|
struct transition_node *tmp;
|
|
struct ivi_layout_transition *tran;
|
|
|
|
wl_list_for_each_safe(node, tmp, &layout->transitions->transition_list, link) {
|
|
tran = node->transition;
|
|
if (tran->is_transition_func(tran->private_data, surface)) {
|
|
layout_transition_destroy(tran);
|
|
}
|
|
};
|
|
}
|
|
|
|
static void
|
|
tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp)
|
|
{
|
|
const double t = timestamp - transition->time_start;
|
|
|
|
if (transition->time_duration <= t) {
|
|
transition->time_elapsed = transition->time_duration;
|
|
transition->is_done = 1;
|
|
} else {
|
|
transition->time_elapsed = t;
|
|
}
|
|
}
|
|
|
|
static float time_to_nowpos(struct ivi_layout_transition *transition)
|
|
{
|
|
return sin((float)transition->time_elapsed /
|
|
(float)transition->time_duration * M_PI_2);
|
|
}
|
|
|
|
static void
|
|
do_transition_frame(struct ivi_layout_transition *transition,
|
|
uint32_t timestamp)
|
|
{
|
|
if (0 == transition->time_start)
|
|
transition->time_start = timestamp;
|
|
|
|
tick_transition(transition, timestamp);
|
|
transition->frame_func(transition);
|
|
|
|
if (transition->is_done)
|
|
layout_transition_destroy(transition);
|
|
}
|
|
|
|
static int32_t
|
|
layout_transition_frame(void *data)
|
|
{
|
|
struct ivi_layout_transition_set *transitions = data;
|
|
uint32_t fps = 30;
|
|
struct timespec timestamp = {};
|
|
uint32_t msec = 0;
|
|
struct transition_node *node = NULL;
|
|
struct transition_node *next = NULL;
|
|
|
|
if (wl_list_empty(&transitions->transition_list)) {
|
|
wl_event_source_timer_update(transitions->event_source, 0);
|
|
return 1;
|
|
}
|
|
|
|
wl_event_source_timer_update(transitions->event_source, 1000 / fps);
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, ×tamp);/* FIXME */
|
|
msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec);
|
|
|
|
wl_list_for_each_safe(node, next, &transitions->transition_list, link) {
|
|
do_transition_frame(node->transition, msec);
|
|
}
|
|
|
|
ivi_layout_commit_changes();
|
|
return 1;
|
|
}
|
|
|
|
struct ivi_layout_transition_set *
|
|
ivi_layout_transition_set_create(struct weston_compositor *ec)
|
|
{
|
|
struct ivi_layout_transition_set *transitions;
|
|
struct wl_event_loop *loop;
|
|
|
|
transitions = malloc(sizeof(*transitions));
|
|
if (transitions == NULL) {
|
|
weston_log("%s: memory allocation fails\n", __func__);
|
|
return NULL;
|
|
}
|
|
|
|
wl_list_init(&transitions->transition_list);
|
|
|
|
loop = wl_display_get_event_loop(ec->wl_display);
|
|
transitions->event_source =
|
|
wl_event_loop_add_timer(loop, layout_transition_frame,
|
|
transitions);
|
|
|
|
return transitions;
|
|
}
|
|
|
|
static bool
|
|
layout_transition_register(struct ivi_layout_transition *trans)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct transition_node *node;
|
|
|
|
node = malloc(sizeof(*node));
|
|
if (node == NULL) {
|
|
weston_log("%s: memory allocation fails\n", __func__);
|
|
return false;
|
|
}
|
|
|
|
node->transition = trans;
|
|
wl_list_insert(&layout->pending_transition_list, &node->link);
|
|
return true;
|
|
}
|
|
|
|
static void
|
|
remove_transition(struct ivi_layout *layout,
|
|
struct ivi_layout_transition *trans)
|
|
{
|
|
struct transition_node *node;
|
|
struct transition_node *next;
|
|
|
|
wl_list_for_each_safe(node, next,
|
|
&layout->transitions->transition_list, link) {
|
|
if (node->transition == trans) {
|
|
wl_list_remove(&node->link);
|
|
free(node);
|
|
return;
|
|
}
|
|
}
|
|
|
|
wl_list_for_each_safe(node, next,
|
|
&layout->pending_transition_list, link) {
|
|
if (node->transition == trans) {
|
|
wl_list_remove(&node->link);
|
|
free(node);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
layout_transition_destroy(struct ivi_layout_transition *transition)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
|
|
remove_transition(layout, transition);
|
|
if (transition->destroy_func)
|
|
transition->destroy_func(transition);
|
|
free(transition);
|
|
}
|
|
|
|
static struct ivi_layout_transition *
|
|
create_layout_transition(void)
|
|
{
|
|
struct ivi_layout_transition *transition = malloc(sizeof(*transition));
|
|
|
|
if (transition == NULL) {
|
|
weston_log("%s: memory allocation fails\n", __func__);
|
|
return NULL;
|
|
}
|
|
|
|
transition->type = IVI_LAYOUT_TRANSITION_MAX;
|
|
transition->time_start = 0;
|
|
transition->time_duration = 300; /* 300ms */
|
|
transition->time_elapsed = 0;
|
|
|
|
transition->is_done = 0;
|
|
|
|
transition->is_transition_func = NULL;
|
|
transition->private_data = NULL;
|
|
transition->user_data = NULL;
|
|
|
|
transition->frame_func = NULL;
|
|
transition->destroy_func = NULL;
|
|
|
|
return transition;
|
|
}
|
|
|
|
/* move and resize view transition */
|
|
|
|
struct move_resize_view_data {
|
|
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;
|
|
};
|
|
|
|
static void
|
|
transition_move_resize_view_destroy(struct ivi_layout_transition *transition)
|
|
{
|
|
struct move_resize_view_data *data =
|
|
(struct move_resize_view_data *)transition->private_data;
|
|
struct ivi_layout_surface *layout_surface = data->surface;
|
|
|
|
shell_surface_send_configure(layout_surface->surface,
|
|
layout_surface->prop.dest_width,
|
|
layout_surface->prop.dest_height);
|
|
|
|
if (transition->private_data) {
|
|
free(transition->private_data);
|
|
transition->private_data = NULL;
|
|
}
|
|
}
|
|
|
|
static void
|
|
transition_move_resize_view_user_frame(struct ivi_layout_transition *transition)
|
|
{
|
|
struct move_resize_view_data *mrv = transition->private_data;
|
|
const double current = time_to_nowpos(transition);
|
|
|
|
const int32_t destx = mrv->start_x +
|
|
(mrv->end_x - mrv->start_x) * current;
|
|
|
|
const int32_t desty = mrv->start_y +
|
|
(mrv->end_y - mrv->start_y) * current;
|
|
|
|
const int32_t dest_width = mrv->start_width +
|
|
(mrv->end_width - mrv->start_width) * current;
|
|
|
|
const int32_t dest_height = mrv->start_height +
|
|
(mrv->end_height - mrv->start_height) * current;
|
|
|
|
ivi_layout_surface_set_destination_rectangle(mrv->surface,
|
|
destx, desty,
|
|
dest_width, dest_height);
|
|
}
|
|
|
|
static int32_t
|
|
is_transition_move_resize_view_func(struct move_resize_view_data *data,
|
|
struct ivi_layout_surface *view)
|
|
{
|
|
return data->surface == view;
|
|
}
|
|
|
|
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)
|
|
{
|
|
struct ivi_layout_transition *transition;
|
|
struct move_resize_view_data *data;
|
|
|
|
transition = create_layout_transition();
|
|
if (transition == NULL)
|
|
return NULL;
|
|
|
|
data = malloc(sizeof(*data));
|
|
if (data == NULL) {
|
|
weston_log("%s: memory allocation fails\n", __func__);
|
|
free(transition);
|
|
return NULL;
|
|
}
|
|
|
|
transition->type = IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE;
|
|
transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_resize_view_func;
|
|
|
|
transition->frame_func = frame_func;
|
|
transition->destroy_func = destroy_func;
|
|
transition->private_data = data;
|
|
|
|
if (duration != 0)
|
|
transition->time_duration = duration;
|
|
|
|
data->surface = surface;
|
|
data->start_x = start_x;
|
|
data->start_y = start_y;
|
|
data->end_x = end_x;
|
|
data->end_y = end_y;
|
|
|
|
data->start_width = start_width;
|
|
data->start_height = start_height;
|
|
data->end_width = end_width;
|
|
data->end_height = end_height;
|
|
|
|
return transition;
|
|
}
|
|
|
|
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)
|
|
{
|
|
struct ivi_layout_transition *transition;
|
|
int32_t start_pos[2] = {
|
|
surface->pending.prop.start_x,
|
|
surface->pending.prop.start_y
|
|
};
|
|
|
|
int32_t start_size[2] = {
|
|
surface->pending.prop.start_width,
|
|
surface->pending.prop.start_height
|
|
};
|
|
|
|
transition = get_transition_from_type_and_id(
|
|
IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
|
|
surface);
|
|
if (transition) {
|
|
struct move_resize_view_data *data = transition->private_data;
|
|
transition->time_start = 0;
|
|
transition->time_duration = duration;
|
|
|
|
data->start_x = start_pos[0];
|
|
data->start_y = start_pos[1];
|
|
data->end_x = dest_x;
|
|
data->end_y = dest_y;
|
|
|
|
data->start_width = start_size[0];
|
|
data->start_height = start_size[1];
|
|
data->end_width = dest_width;
|
|
data->end_height = dest_height;
|
|
return;
|
|
}
|
|
|
|
transition = create_move_resize_view_transition(
|
|
surface,
|
|
start_pos[0], start_pos[1],
|
|
dest_x, dest_y,
|
|
start_size[0], start_size[1],
|
|
dest_width, dest_height,
|
|
transition_move_resize_view_user_frame,
|
|
transition_move_resize_view_destroy,
|
|
duration);
|
|
|
|
if(transition && layout_transition_register(transition))
|
|
return;
|
|
layout_transition_destroy(transition);
|
|
}
|
|
|
|
/* fade transition */
|
|
struct fade_view_data {
|
|
struct ivi_layout_surface *surface;
|
|
double start_alpha;
|
|
double end_alpha;
|
|
};
|
|
|
|
struct store_alpha{
|
|
double alpha;
|
|
};
|
|
|
|
static void
|
|
fade_view_user_frame(struct ivi_layout_transition *transition)
|
|
{
|
|
struct fade_view_data *fade = transition->private_data;
|
|
struct ivi_layout_surface *surface = fade->surface;
|
|
|
|
const double current = time_to_nowpos(transition);
|
|
const double alpha = fade->start_alpha +
|
|
(fade->end_alpha - fade->start_alpha) * current;
|
|
|
|
ivi_layout_surface_set_opacity(surface, wl_fixed_from_double(alpha));
|
|
ivi_layout_surface_set_visibility(surface, true);
|
|
}
|
|
|
|
static int32_t
|
|
is_transition_fade_view_func(struct fade_view_data *data,
|
|
struct ivi_layout_surface *view)
|
|
{
|
|
return data->surface == view;
|
|
}
|
|
|
|
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)
|
|
{
|
|
struct ivi_layout_transition *transition;
|
|
struct fade_view_data *data;
|
|
|
|
transition = create_layout_transition();
|
|
if (transition == NULL)
|
|
return NULL;
|
|
|
|
data = malloc(sizeof(*data));
|
|
if (data == NULL) {
|
|
weston_log("%s: memory allocation fails\n", __func__);
|
|
free(transition);
|
|
return NULL;
|
|
}
|
|
|
|
transition->type = IVI_LAYOUT_TRANSITION_VIEW_FADE;
|
|
transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_view_func;
|
|
|
|
transition->user_data = user_data;
|
|
transition->private_data = data;
|
|
transition->frame_func = frame_func;
|
|
transition->destroy_func = destroy_func;
|
|
|
|
if (duration != 0)
|
|
transition->time_duration = duration;
|
|
|
|
data->surface = surface;
|
|
data->start_alpha = start_alpha;
|
|
data->end_alpha = end_alpha;
|
|
|
|
return transition;
|
|
}
|
|
|
|
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)
|
|
{
|
|
struct ivi_layout_transition *transition = NULL;
|
|
|
|
transition = create_fade_view_transition(
|
|
surface,
|
|
start_alpha, dest_alpha,
|
|
fade_view_user_frame,
|
|
user_data,
|
|
destroy_func,
|
|
duration);
|
|
|
|
if (transition && layout_transition_register(transition))
|
|
return;
|
|
layout_transition_destroy(transition);
|
|
}
|
|
|
|
static void
|
|
visibility_on_transition_destroy(struct ivi_layout_transition *transition)
|
|
{
|
|
struct fade_view_data *data = transition->private_data;
|
|
struct store_alpha *user_data = transition->user_data;
|
|
|
|
ivi_layout_surface_set_visibility(data->surface, true);
|
|
|
|
free(data);
|
|
transition->private_data = NULL;
|
|
|
|
free(user_data);
|
|
transition->user_data = NULL;
|
|
}
|
|
|
|
void
|
|
ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
|
|
uint32_t duration)
|
|
{
|
|
struct ivi_layout_transition *transition;
|
|
bool is_visible = surface->prop.visibility;
|
|
wl_fixed_t dest_alpha = surface->prop.opacity;
|
|
struct store_alpha *user_data = NULL;
|
|
wl_fixed_t start_alpha = 0.0;
|
|
struct fade_view_data *data = NULL;
|
|
|
|
transition = get_transition_from_type_and_id(
|
|
IVI_LAYOUT_TRANSITION_VIEW_FADE,
|
|
surface);
|
|
if (transition) {
|
|
start_alpha = surface->prop.opacity;
|
|
user_data = transition->user_data;
|
|
data = transition->private_data;
|
|
|
|
transition->time_start = 0;
|
|
transition->time_duration = duration;
|
|
transition->destroy_func = visibility_on_transition_destroy;
|
|
|
|
data->start_alpha = wl_fixed_to_double(start_alpha);
|
|
data->end_alpha = user_data->alpha;
|
|
return;
|
|
}
|
|
|
|
if (is_visible)
|
|
return;
|
|
|
|
user_data = malloc(sizeof(*user_data));
|
|
if (user_data == NULL) {
|
|
weston_log("%s: memory allocation fails\n", __func__);
|
|
return;
|
|
}
|
|
|
|
user_data->alpha = wl_fixed_to_double(dest_alpha);
|
|
|
|
create_visibility_transition(surface,
|
|
0.0, // start_alpha
|
|
wl_fixed_to_double(dest_alpha),
|
|
user_data,
|
|
visibility_on_transition_destroy,
|
|
duration);
|
|
}
|
|
|
|
static void
|
|
visibility_off_transition_destroy(struct ivi_layout_transition *transition)
|
|
{
|
|
struct fade_view_data *data = transition->private_data;
|
|
struct store_alpha *user_data = transition->user_data;
|
|
|
|
ivi_layout_surface_set_visibility(data->surface, false);
|
|
|
|
ivi_layout_surface_set_opacity(data->surface,
|
|
wl_fixed_from_double(user_data->alpha));
|
|
|
|
free(data);
|
|
transition->private_data = NULL;
|
|
|
|
free(user_data);
|
|
transition->user_data= NULL;
|
|
}
|
|
|
|
void
|
|
ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
|
|
uint32_t duration)
|
|
{
|
|
struct ivi_layout_transition *transition;
|
|
wl_fixed_t start_alpha = surface->prop.opacity;
|
|
struct store_alpha* user_data = NULL;
|
|
struct fade_view_data* data = NULL;
|
|
|
|
transition =
|
|
get_transition_from_type_and_id(IVI_LAYOUT_TRANSITION_VIEW_FADE,
|
|
surface);
|
|
if (transition) {
|
|
data = transition->private_data;
|
|
|
|
transition->time_start = 0;
|
|
transition->time_duration = duration;
|
|
transition->destroy_func = visibility_off_transition_destroy;
|
|
|
|
data->start_alpha = wl_fixed_to_double(start_alpha);
|
|
data->end_alpha = 0;
|
|
return;
|
|
}
|
|
|
|
user_data = malloc(sizeof(*user_data));
|
|
if (user_data == NULL) {
|
|
weston_log("%s: memory allocation fails\n", __func__);
|
|
return;
|
|
}
|
|
|
|
user_data->alpha = wl_fixed_to_double(start_alpha);
|
|
|
|
create_visibility_transition(surface,
|
|
wl_fixed_to_double(start_alpha),
|
|
0.0, // dest_alpha
|
|
user_data,
|
|
visibility_off_transition_destroy,
|
|
duration);
|
|
}
|
|
|
|
/* move layer transition */
|
|
|
|
struct move_layer_data {
|
|
struct ivi_layout_layer *layer;
|
|
int32_t start_x;
|
|
int32_t start_y;
|
|
int32_t end_x;
|
|
int32_t end_y;
|
|
ivi_layout_transition_destroy_user_func destroy_func;
|
|
};
|
|
|
|
static void
|
|
transition_move_layer_user_frame(struct ivi_layout_transition *transition)
|
|
{
|
|
struct move_layer_data *data = transition->private_data;
|
|
struct ivi_layout_layer *layer = data->layer;
|
|
|
|
const float current = time_to_nowpos(transition);
|
|
|
|
const int32_t dest_x = data->start_x +
|
|
(data->end_x - data->start_x) * current;
|
|
|
|
const int32_t dest_y = data->start_y +
|
|
(data->end_y - data->start_y) * current;
|
|
|
|
ivi_layout_layer_set_destination_rectangle(layer, dest_x, dest_y,
|
|
layer->prop.dest_width, layer->prop.dest_height);
|
|
}
|
|
|
|
static void
|
|
transition_move_layer_destroy(struct ivi_layout_transition *transition)
|
|
{
|
|
struct move_layer_data *data = transition->private_data;
|
|
|
|
if (data->destroy_func)
|
|
data->destroy_func(transition->user_data);
|
|
|
|
free(data);
|
|
transition->private_data = NULL;
|
|
}
|
|
|
|
static int32_t
|
|
is_transition_move_layer_func(struct move_layer_data *data,
|
|
struct ivi_layout_layer *layer)
|
|
{
|
|
return data->layer == layer;
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
struct ivi_layout_transition *transition;
|
|
struct move_layer_data *data;
|
|
|
|
transition = create_layout_transition();
|
|
if (transition == NULL)
|
|
return NULL;
|
|
|
|
data = malloc(sizeof(*data));
|
|
if (data == NULL) {
|
|
weston_log("%s: memory allocation fails\n", __func__);
|
|
free(transition);
|
|
return NULL;
|
|
}
|
|
|
|
transition->type = IVI_LAYOUT_TRANSITION_LAYER_MOVE;
|
|
transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_layer_func;
|
|
|
|
transition->frame_func = transition_move_layer_user_frame;
|
|
transition->destroy_func = transition_move_layer_destroy;
|
|
transition->private_data = data;
|
|
transition->user_data = user_data;
|
|
|
|
if (duration != 0)
|
|
transition->time_duration = duration;
|
|
|
|
data->layer = layer;
|
|
data->start_x = start_x;
|
|
data->start_y = start_y;
|
|
data->end_x = end_x;
|
|
data->end_y = end_y;
|
|
data->destroy_func = destroy_user_func;
|
|
|
|
return transition;
|
|
}
|
|
|
|
void
|
|
ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
|
|
int32_t dest_x, int32_t dest_y,
|
|
uint32_t duration)
|
|
{
|
|
int32_t start_pos_x = layer->prop.dest_x;
|
|
int32_t start_pos_y = layer->prop.dest_y;
|
|
struct ivi_layout_transition *transition = NULL;
|
|
|
|
transition = create_move_layer_transition(
|
|
layer,
|
|
start_pos_x, start_pos_y,
|
|
dest_x, dest_y,
|
|
NULL, NULL,
|
|
duration);
|
|
|
|
if (transition && layout_transition_register(transition))
|
|
return;
|
|
|
|
free(transition);
|
|
}
|
|
|
|
void
|
|
ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer)
|
|
{
|
|
struct ivi_layout_transition *transition =
|
|
get_transition_from_type_and_id(
|
|
IVI_LAYOUT_TRANSITION_LAYER_MOVE,
|
|
layer);
|
|
if (transition) {
|
|
layout_transition_destroy(transition);
|
|
}
|
|
}
|
|
|
|
/* fade layer transition */
|
|
struct fade_layer_data {
|
|
struct ivi_layout_layer *layer;
|
|
uint32_t is_fade_in;
|
|
double start_alpha;
|
|
double end_alpha;
|
|
ivi_layout_transition_destroy_user_func destroy_func;
|
|
};
|
|
|
|
static void
|
|
transition_fade_layer_destroy(struct ivi_layout_transition *transition)
|
|
{
|
|
struct fade_layer_data *data = transition->private_data;
|
|
transition->private_data = NULL;
|
|
|
|
free(data);
|
|
}
|
|
|
|
static void
|
|
transition_fade_layer_user_frame(struct ivi_layout_transition *transition)
|
|
{
|
|
double current = time_to_nowpos(transition);
|
|
struct fade_layer_data *data = transition->private_data;
|
|
double alpha = data->start_alpha +
|
|
(data->end_alpha - data->start_alpha) * current;
|
|
wl_fixed_t fixed_alpha = wl_fixed_from_double(alpha);
|
|
|
|
int32_t is_done = transition->is_done;
|
|
bool is_visible = !is_done || data->is_fade_in;
|
|
|
|
ivi_layout_layer_set_opacity(data->layer, fixed_alpha);
|
|
ivi_layout_layer_set_visibility(data->layer, is_visible);
|
|
}
|
|
|
|
static int32_t
|
|
is_transition_fade_layer_func(struct fade_layer_data *data,
|
|
struct ivi_layout_layer *layer)
|
|
{
|
|
return data->layer == layer;
|
|
}
|
|
|
|
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)
|
|
{
|
|
struct ivi_layout_transition *transition;
|
|
struct fade_layer_data *data = NULL;
|
|
wl_fixed_t fixed_opacity = 0.0;
|
|
double now_opacity = 0.0;
|
|
double remain = 0.0;
|
|
|
|
transition = get_transition_from_type_and_id(
|
|
IVI_LAYOUT_TRANSITION_LAYER_FADE,
|
|
layer);
|
|
if (transition) {
|
|
/* transition update */
|
|
data = transition->private_data;
|
|
|
|
/* FIXME */
|
|
fixed_opacity = layer->prop.opacity;
|
|
now_opacity = wl_fixed_to_double(fixed_opacity);
|
|
remain = 0.0;
|
|
|
|
data->is_fade_in = is_fade_in;
|
|
data->start_alpha = now_opacity;
|
|
data->end_alpha = end_alpha;
|
|
|
|
remain = is_fade_in? 1.0 - now_opacity : now_opacity;
|
|
transition->time_start = 0;
|
|
transition->time_elapsed = 0;
|
|
transition->time_duration = duration * remain;
|
|
|
|
return;
|
|
}
|
|
|
|
transition = create_layout_transition();
|
|
if (transition == NULL)
|
|
return;
|
|
|
|
data = malloc(sizeof(*data));
|
|
if (data == NULL) {
|
|
weston_log("%s: memory allocation fails\n", __func__);
|
|
free(transition);
|
|
return;
|
|
}
|
|
|
|
transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
|
|
transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
|
|
|
|
transition->private_data = data;
|
|
transition->user_data = user_data;
|
|
|
|
transition->frame_func = transition_fade_layer_user_frame;
|
|
transition->destroy_func = transition_fade_layer_destroy;
|
|
|
|
if (duration != 0)
|
|
transition->time_duration = duration;
|
|
|
|
data->layer = layer;
|
|
data->is_fade_in = is_fade_in;
|
|
data->start_alpha = start_alpha;
|
|
data->end_alpha = end_alpha;
|
|
data->destroy_func = destroy_func;
|
|
|
|
if (!layout_transition_register(transition))
|
|
layout_transition_destroy(transition);
|
|
|
|
return;
|
|
}
|
|
|