weston/ivi-shell/ivi-layout-transition.c
Nobuhiko Tanibata 6f9df656e0 ivi-shell: add IVI layout APIs
- ivi-layout.so
- introduces ivi-layout-export.h, ivi-layout.[ch]

API set of controlling properties of surface and layer which groups
surfaces. An unique ID whose type is integer is required to create
surface and layer. With the unique ID, surface and layer are identified
to control them. The API set consists of APIs to control properties of
surface and layers about followings,

- visibility.
- opacity.
- clipping (x,y,width,height).
- position and size of it to be displayed.
- orientation per 90 degree.
- add or remove surfaces to a layer.
- order of surfaces/layers in layer/screen to be displayed.
- commit to apply property changes.
- notifications of property change.

Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp>
Acked-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2014-12-04 17:13:41 +02:00

1112 lines
28 KiB
C

/*
* Copyright (C) 2014 DENSO CORPORATION
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the copyright holders not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. The copyright holders make
* no representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <time.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.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;
}
WL_EXPORT 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;
}
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, &timestamp);/* 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;
}
WL_EXPORT 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 void
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;
}
node->transition = trans;
wl_list_insert(&layout->pending_transition_list, &node->link);
}
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->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;
wl_signal_emit(&layout_surface->configured, layout_surface);
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 = create_layout_transition();
struct move_resize_view_data *data = malloc(sizeof(*data));
if (data == NULL) {
weston_log("%s: memory allocation fails\n", __func__);
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;
}
WL_EXPORT 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);
layout_transition_register(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 = create_layout_transition();
struct fade_view_data *data = malloc(sizeof(*data));
if (data == NULL) {
weston_log("%s: memory allocation fails\n", __func__);
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);
layout_transition_register(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;
}
WL_EXPORT void
ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
uint32_t duration)
{
struct ivi_layout_transition *transition;
bool is_visible = ivi_layout_surface_get_visibility(surface);
wl_fixed_t dest_alpha = ivi_layout_surface_get_opacity(surface);
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 = ivi_layout_surface_get_opacity(surface);
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;
}
WL_EXPORT void
ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
uint32_t duration)
{
struct ivi_layout_transition *transition;
wl_fixed_t start_alpha = ivi_layout_surface_get_opacity(surface);
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_position(layer, dest_x, dest_y);
}
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 = create_layout_transition();
struct move_layer_data *data = malloc(sizeof(*data));
if (data == NULL) {
weston_log("%s: memory allocation fails\n", __func__);
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;
}
WL_EXPORT 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 = 0;
int32_t start_pos_y = 0;
struct ivi_layout_transition *transition = NULL;
ivi_layout_layer_get_position(layer, &start_pos_x, &start_pos_y);
transition = create_move_layer_transition(
layer,
start_pos_x, start_pos_y,
dest_x, dest_y,
NULL, NULL,
duration);
layout_transition_register(transition);
return;
}
WL_EXPORT 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;
}
WL_EXPORT 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 = ivi_layout_layer_get_opacity(layer);
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();
data = malloc(sizeof(*data));
if (data == NULL) {
weston_log("%s: memory allocation fails\n", __func__);
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;
layout_transition_register(transition);
return;
}
/* render order transition */
struct surface_reorder {
uint32_t id_surface;
uint32_t new_index;
};
struct change_order_data {
struct ivi_layout_layer *layer;
uint32_t surface_num;
struct surface_reorder *reorder;
};
struct surf_with_index {
uint32_t id_surface;
float surface_index;
};
static int
cmp_order_asc(const void *lhs, const void *rhs)
{
const struct surf_with_index *l = lhs;
const struct surf_with_index *r = rhs;
return l->surface_index > r->surface_index;
}
/*
render oerder transition
index 0 1 2
old surfA, surfB, surfC
new surfB, surfC, surfA
(-1) (-1) (+2)
after 10% of time elapsed
0.2 0.9 1.9
surfA, surfB, surfC
after 50% of time elapsed
0.5 1.0 1.5
surfB, surfA, surfC
*/
static void
transition_change_order_user_frame(struct ivi_layout_transition *transition)
{
uint32_t i, old_index;
double current = time_to_nowpos(transition);
struct change_order_data *data = transition->private_data;
struct surf_with_index *swi = malloc(sizeof(*swi) * data->surface_num);
struct ivi_layout_surface **new_surface_order = NULL;
uint32_t surface_num = 0;
if (swi == NULL) {
weston_log("%s: memory allocation fails\n", __func__);
return;
}
for (old_index = 0; old_index < data->surface_num; old_index++) {
swi[old_index].id_surface = data->reorder[old_index].id_surface;
swi[old_index].surface_index = (float)old_index +
((float)data->reorder[old_index].new_index - (float)old_index) * current;
}
qsort(swi, data->surface_num, sizeof(*swi), cmp_order_asc);
new_surface_order =
malloc(sizeof(*new_surface_order) * data->surface_num);
if (new_surface_order == NULL) {
weston_log("%s: memory allocation fails\n", __func__);
return;
}
for (i = 0; i < data->surface_num; i++) {
struct ivi_layout_surface *surf =
ivi_layout_get_surface_from_id(swi[i].id_surface);
if(surf)
new_surface_order[surface_num++] = surf;
}
ivi_layout_layer_set_render_order(data->layer, new_surface_order,
surface_num);
free(new_surface_order);
free(swi);
}
static void
transition_change_order_destroy(struct ivi_layout_transition *transition)
{
struct change_order_data *data = transition->private_data;
free(data->reorder);
free(data);
}
static int32_t find_surface(struct ivi_layout_surface **surfaces,
uint32_t surface_num,
struct ivi_layout_surface *target)
{
uint32_t i = 0;
for(i = 0; i < surface_num; i++) {
if (surfaces[i] == target)
return i;
}
return -1;
}
static int32_t
is_transition_change_order_func(struct change_order_data *data,
struct ivi_layout_layer *layer)
{
return data->layer == layer;
}
WL_EXPORT void
ivi_layout_transition_layer_render_order(struct ivi_layout_layer *layer,
struct ivi_layout_surface **new_order,
uint32_t surface_num,
uint32_t duration)
{
struct surface_reorder *reorder;
struct ivi_layout_surface *surf;
uint32_t old_index = 0;
struct ivi_layout_transition *transition;
struct change_order_data *data = NULL;
int32_t new_index = 0;
uint32_t id = 0;
reorder = malloc(sizeof(*reorder) * surface_num);
if (reorder == NULL) {
weston_log("%s: memory allocation fails\n", __func__);
return;
}
wl_list_for_each(surf, &layer->order.surface_list, order.link) {
new_index = find_surface(new_order, surface_num, surf);
id = ivi_layout_get_id_of_surface(surf);
if(new_index < 0){
fprintf(stderr, "invalid render order!!!\n");
return;
}
reorder[old_index].id_surface = id;
reorder[old_index].new_index = new_index;
old_index++;
}
transition = get_transition_from_type_and_id(
IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER,
layer);
if (transition) {
/* update transition */
struct change_order_data *data = transition->private_data;
transition->time_start = 0; /* timer reset */
if (duration != 0) {
transition->time_duration = duration;
}
free(data->reorder);
data->reorder = reorder;
return;
}
transition = create_layout_transition();
data = malloc(sizeof(*data));
if (data == NULL) {
weston_log("%s: memory allocation fails\n", __func__);
return;
}
transition->type = IVI_LAYOUT_TRANSITION_LAYER_VIEW_ORDER;
transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_change_order_func;
transition->private_data = data;
transition->frame_func = transition_change_order_user_frame;
transition->destroy_func = transition_change_order_destroy;
if (duration != 0)
transition->time_duration = duration;
data->layer = layer;
data->reorder = reorder;
data->surface_num = old_index;
layout_transition_register(transition);
}
WL_EXPORT int32_t
ivi_layout_surface_set_transition(struct ivi_layout_surface *ivisurf,
enum ivi_layout_transition_type type,
uint32_t duration)
{
struct ivi_layout_surface_properties *prop;
if (ivisurf == NULL) {
weston_log("%s: invalid argument\n", __func__);
return -1;
}
prop = &ivisurf->pending.prop;
prop->transition_type = type;
prop->transition_duration = duration;
return 0;
}
int32_t
ivi_layout_surface_set_transition_duration(struct ivi_layout_surface *ivisurf,
uint32_t duration)
{
struct ivi_layout_surface_properties *prop;
if (ivisurf == NULL) {
weston_log("%s: invalid argument\n", __func__);
return -1;
}
prop = &ivisurf->pending.prop;
prop->transition_duration = duration*10;
return 0;
}
WL_EXPORT int32_t
ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer,
enum ivi_layout_transition_type type,
uint32_t duration)
{
if (ivilayer == NULL) {
weston_log("%s: invalid argument\n", __func__);
return -1;
}
ivilayer->pending.prop.transition_type = type;
ivilayer->pending.prop.transition_duration = duration;
return 0;
}
WL_EXPORT int32_t
ivi_layout_layer_set_fade_info(struct ivi_layout_layer* ivilayer,
uint32_t is_fade_in,
double start_alpha, double end_alpha)
{
if (ivilayer == NULL) {
weston_log("%s: invalid argument\n", __func__);
return -1;
}
ivilayer->pending.prop.is_fade_in = is_fade_in;
ivilayer->pending.prop.start_alpha = start_alpha;
ivilayer->pending.prop.end_alpha = end_alpha;
return 0;
}