3aa8aedb47
"remove" is not proper name beacause it destorys a layer. The name of the api is changed from layer_remove to layer_destroy. Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
3106 lines
82 KiB
C
3106 lines
82 KiB
C
/*
|
|
* Copyright (C) 2013 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.
|
|
*/
|
|
|
|
/**
|
|
* Implementation of ivi-layout library. The actual view on ivi_screen is
|
|
* not updated till calling ivi_layout_commit_changes. A overview from
|
|
* calling API for updating properties of ivi_surface/ivi_layer to asking
|
|
* compositor to compose them by using weston_compositor_schedule_repaint,
|
|
* 0/ initialize this library by ivi_layout_init_with_compositor
|
|
* with (struct weston_compositor *ec) from ivi-shell.
|
|
* 1/ When a API for updating properties of ivi_surface/ivi_layer, it updates
|
|
* pending prop of ivi_surface/ivi_layer/ivi_screen which are structure to
|
|
* store properties.
|
|
* 2/ Before calling commitChanges, in case of calling a API to get a property,
|
|
* return current property, not pending property.
|
|
* 3/ At the timing of calling ivi_layout_commitChanges, pending properties
|
|
* are applied to properties.
|
|
*
|
|
* *) ivi_layout_commitChanges is also called by transition animation
|
|
* per each frame. See ivi-layout-transition.c in details. Transition
|
|
* animation interpolates frames between previous properties of ivi_surface
|
|
* and new ones.
|
|
* For example, when a property of ivi_surface is changed from invisibility
|
|
* to visibility, it behaves like fade-in. When ivi_layout_commitChange is
|
|
* called during transition animation, it cancels the transition and
|
|
* re-start transition to new properties from current properties of final
|
|
* frame just before the the cancellation.
|
|
*
|
|
* 4/ According properties, set transformation by using weston_matrix and
|
|
* weston_view per ivi_surfaces and ivi_layers in while loop.
|
|
* 5/ Set damage and trigger transform by using weston_view_geometry_dirty.
|
|
* 6/ Notify update of properties.
|
|
* 7/ Trigger composition by weston_compositor_schedule_repaint.
|
|
*
|
|
*/
|
|
#include "config.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "compositor.h"
|
|
#include "ivi-layout-export.h"
|
|
#include "ivi-layout-private.h"
|
|
|
|
#include "shared/helpers.h"
|
|
#include "shared/os-compatibility.h"
|
|
|
|
struct link_layer {
|
|
struct ivi_layout_layer *ivilayer;
|
|
struct wl_list link;
|
|
struct wl_list link_to_layer;
|
|
};
|
|
|
|
struct link_screen {
|
|
struct ivi_layout_screen *iviscrn;
|
|
struct wl_list link;
|
|
struct wl_list link_to_screen;
|
|
};
|
|
|
|
struct listener_layout_notification {
|
|
void *userdata;
|
|
struct wl_listener listener;
|
|
};
|
|
|
|
struct ivi_layout;
|
|
|
|
struct ivi_layout_screen {
|
|
struct wl_list link;
|
|
struct wl_list link_to_layer;
|
|
uint32_t id_screen;
|
|
|
|
struct ivi_layout *layout;
|
|
struct weston_output *output;
|
|
|
|
uint32_t event_mask;
|
|
|
|
struct {
|
|
struct wl_list layer_list;
|
|
struct wl_list link;
|
|
} pending;
|
|
|
|
struct {
|
|
struct wl_list layer_list;
|
|
struct wl_list link;
|
|
} order;
|
|
};
|
|
|
|
struct ivi_layout_notification_callback {
|
|
void *callback;
|
|
void *data;
|
|
};
|
|
|
|
static void
|
|
remove_notification(struct wl_list *listener_list, void *callback, void *userdata);
|
|
|
|
static struct ivi_layout ivilayout = {0};
|
|
|
|
struct ivi_layout *
|
|
get_instance(void)
|
|
{
|
|
return &ivilayout;
|
|
}
|
|
|
|
/**
|
|
* Internal API to add/remove a link to ivi_surface from ivi_layer.
|
|
*/
|
|
static void
|
|
add_link_to_surface(struct ivi_layout_layer *ivilayer,
|
|
struct link_layer *link_layer)
|
|
{
|
|
struct link_layer *link = NULL;
|
|
|
|
wl_list_for_each(link, &ivilayer->link_to_surface, link_to_layer) {
|
|
if (link == link_layer)
|
|
return;
|
|
}
|
|
|
|
wl_list_insert(&ivilayer->link_to_surface, &link_layer->link_to_layer);
|
|
}
|
|
|
|
static void
|
|
remove_link_to_surface(struct ivi_layout_layer *ivilayer)
|
|
{
|
|
struct link_layer *link = NULL;
|
|
struct link_layer *next = NULL;
|
|
|
|
wl_list_for_each_safe(link, next, &ivilayer->link_to_surface, link_to_layer) {
|
|
if (!wl_list_empty(&link->link_to_layer)) {
|
|
wl_list_remove(&link->link_to_layer);
|
|
}
|
|
if (!wl_list_empty(&link->link)) {
|
|
wl_list_remove(&link->link);
|
|
}
|
|
free(link);
|
|
}
|
|
|
|
wl_list_init(&ivilayer->link_to_surface);
|
|
}
|
|
|
|
/**
|
|
* Internal API to add a link to ivi_layer from ivi_screen.
|
|
*/
|
|
static void
|
|
add_link_to_layer(struct ivi_layout_screen *iviscrn,
|
|
struct link_screen *link_screen)
|
|
{
|
|
wl_list_init(&link_screen->link_to_screen);
|
|
wl_list_insert(&iviscrn->link_to_layer, &link_screen->link_to_screen);
|
|
}
|
|
|
|
/**
|
|
* Internal API to add/remove a ivi_surface from ivi_layer.
|
|
*/
|
|
static void
|
|
add_ordersurface_to_layer(struct ivi_layout_surface *ivisurf,
|
|
struct ivi_layout_layer *ivilayer)
|
|
{
|
|
struct link_layer *link_layer = NULL;
|
|
|
|
link_layer = malloc(sizeof *link_layer);
|
|
if (link_layer == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return;
|
|
}
|
|
|
|
link_layer->ivilayer = ivilayer;
|
|
wl_list_init(&link_layer->link);
|
|
wl_list_insert(&ivisurf->layer_list, &link_layer->link);
|
|
add_link_to_surface(ivilayer, link_layer);
|
|
}
|
|
|
|
static void
|
|
remove_ordersurface_from_layer(struct ivi_layout_surface *ivisurf)
|
|
{
|
|
struct link_layer *link_layer = NULL;
|
|
struct link_layer *next = NULL;
|
|
|
|
wl_list_for_each_safe(link_layer, next, &ivisurf->layer_list, link) {
|
|
if (!wl_list_empty(&link_layer->link)) {
|
|
wl_list_remove(&link_layer->link);
|
|
}
|
|
if (!wl_list_empty(&link_layer->link_to_layer)) {
|
|
wl_list_remove(&link_layer->link_to_layer);
|
|
}
|
|
free(link_layer);
|
|
}
|
|
wl_list_init(&ivisurf->layer_list);
|
|
}
|
|
|
|
/**
|
|
* Internal API to add/remove a ivi_layer to/from ivi_screen.
|
|
*/
|
|
static void
|
|
add_orderlayer_to_screen(struct ivi_layout_layer *ivilayer,
|
|
struct ivi_layout_screen *iviscrn)
|
|
{
|
|
struct link_screen *link_scrn = NULL;
|
|
|
|
link_scrn = malloc(sizeof *link_scrn);
|
|
if (link_scrn == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return;
|
|
}
|
|
|
|
link_scrn->iviscrn = iviscrn;
|
|
wl_list_init(&link_scrn->link);
|
|
wl_list_insert(&ivilayer->screen_list, &link_scrn->link);
|
|
add_link_to_layer(iviscrn, link_scrn);
|
|
}
|
|
|
|
static void
|
|
remove_orderlayer_from_screen(struct ivi_layout_layer *ivilayer)
|
|
{
|
|
struct link_screen *link_scrn = NULL;
|
|
struct link_screen *next = NULL;
|
|
|
|
wl_list_for_each_safe(link_scrn, next, &ivilayer->screen_list, link) {
|
|
if (!wl_list_empty(&link_scrn->link)) {
|
|
wl_list_remove(&link_scrn->link);
|
|
}
|
|
if (!wl_list_empty(&link_scrn->link_to_screen)) {
|
|
wl_list_remove(&link_scrn->link_to_screen);
|
|
}
|
|
free(link_scrn);
|
|
}
|
|
wl_list_init(&ivilayer->screen_list);
|
|
}
|
|
|
|
/**
|
|
* Internal API to add/remove a ivi_layer to/from ivi_screen.
|
|
*/
|
|
static struct ivi_layout_surface *
|
|
get_surface(struct wl_list *surf_list, uint32_t id_surface)
|
|
{
|
|
struct ivi_layout_surface *ivisurf;
|
|
|
|
wl_list_for_each(ivisurf, surf_list, link) {
|
|
if (ivisurf->id_surface == id_surface) {
|
|
return ivisurf;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static struct ivi_layout_layer *
|
|
get_layer(struct wl_list *layer_list, uint32_t id_layer)
|
|
{
|
|
struct ivi_layout_layer *ivilayer;
|
|
|
|
wl_list_for_each(ivilayer, layer_list, link) {
|
|
if (ivilayer->id_layer == id_layer) {
|
|
return ivilayer;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
remove_configured_listener(struct ivi_layout_surface *ivisurf)
|
|
{
|
|
struct wl_listener *link = NULL;
|
|
struct wl_listener *next = NULL;
|
|
|
|
wl_list_for_each_safe(link, next, &ivisurf->configured.listener_list, link) {
|
|
wl_list_remove(&link->link);
|
|
}
|
|
}
|
|
|
|
static void
|
|
remove_all_notification(struct wl_list *listener_list)
|
|
{
|
|
struct wl_listener *listener = NULL;
|
|
struct wl_listener *next = NULL;
|
|
|
|
wl_list_for_each_safe(listener, next, listener_list, link) {
|
|
struct listener_layout_notification *notification = NULL;
|
|
if (!wl_list_empty(&listener->link)) {
|
|
wl_list_remove(&listener->link);
|
|
}
|
|
|
|
notification =
|
|
container_of(listener,
|
|
struct listener_layout_notification,
|
|
listener);
|
|
|
|
free(notification->userdata);
|
|
free(notification);
|
|
}
|
|
}
|
|
|
|
static void
|
|
ivi_layout_surface_remove_notification(struct ivi_layout_surface *ivisurf)
|
|
{
|
|
if (ivisurf == NULL) {
|
|
weston_log("ivi_layout_surface_remove_notification: invalid argument\n");
|
|
return;
|
|
}
|
|
|
|
remove_all_notification(&ivisurf->property_changed.listener_list);
|
|
}
|
|
|
|
static void
|
|
ivi_layout_surface_remove_notification_by_callback(struct ivi_layout_surface *ivisurf,
|
|
surface_property_notification_func callback,
|
|
void *userdata)
|
|
{
|
|
if (ivisurf == NULL) {
|
|
weston_log("ivi_layout_surface_remove_notification_by_callback: invalid argument\n");
|
|
return;
|
|
}
|
|
|
|
remove_notification(&ivisurf->property_changed.listener_list, callback, userdata);
|
|
}
|
|
|
|
/**
|
|
* Called at destruction of wl_surface/ivi_surface
|
|
*/
|
|
void
|
|
ivi_layout_surface_destroy(struct ivi_layout_surface *ivisurf)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
|
|
if (ivisurf == NULL) {
|
|
weston_log("%s: invalid argument\n", __func__);
|
|
return;
|
|
}
|
|
|
|
wl_list_remove(&ivisurf->surface_rotation.link);
|
|
wl_list_remove(&ivisurf->layer_rotation.link);
|
|
wl_list_remove(&ivisurf->surface_pos.link);
|
|
wl_list_remove(&ivisurf->layer_pos.link);
|
|
wl_list_remove(&ivisurf->scaling.link);
|
|
|
|
wl_list_remove(&ivisurf->pending.link);
|
|
wl_list_remove(&ivisurf->order.link);
|
|
wl_list_remove(&ivisurf->link);
|
|
remove_ordersurface_from_layer(ivisurf);
|
|
|
|
wl_signal_emit(&layout->surface_notification.removed, ivisurf);
|
|
|
|
remove_configured_listener(ivisurf);
|
|
|
|
ivi_layout_surface_remove_notification(ivisurf);
|
|
|
|
ivisurf->surface = NULL;
|
|
|
|
free(ivisurf);
|
|
}
|
|
|
|
/**
|
|
* Internal API to check ivi_layer/ivi_surface already added in ivi_layer/ivi_screen.
|
|
* Called by ivi_layout_layer_add_surface/ivi_layout_screenAddLayer
|
|
*/
|
|
static int
|
|
is_surface_in_layer(struct ivi_layout_surface *ivisurf,
|
|
struct ivi_layout_layer *ivilayer)
|
|
{
|
|
struct ivi_layout_surface *surf = NULL;
|
|
|
|
wl_list_for_each(surf, &ivilayer->pending.surface_list, pending.link) {
|
|
if (surf->id_surface == ivisurf->id_surface) {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
is_layer_in_screen(struct ivi_layout_layer *ivilayer,
|
|
struct ivi_layout_screen *iviscrn)
|
|
{
|
|
struct ivi_layout_layer *layer = NULL;
|
|
|
|
wl_list_for_each(layer, &iviscrn->pending.layer_list, pending.link) {
|
|
if (layer->id_layer == ivilayer->id_layer) {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Internal API to initialize ivi_screens found from output_list of weston_compositor.
|
|
* Called by ivi_layout_init_with_compositor.
|
|
*/
|
|
static void
|
|
create_screen(struct weston_compositor *ec)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_screen *iviscrn = NULL;
|
|
struct weston_output *output = NULL;
|
|
int32_t count = 0;
|
|
|
|
wl_list_for_each(output, &ec->output_list, link) {
|
|
iviscrn = calloc(1, sizeof *iviscrn);
|
|
if (iviscrn == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
continue;
|
|
}
|
|
|
|
wl_list_init(&iviscrn->link);
|
|
iviscrn->layout = layout;
|
|
|
|
iviscrn->id_screen = count;
|
|
count++;
|
|
|
|
iviscrn->output = output;
|
|
iviscrn->event_mask = 0;
|
|
|
|
wl_list_init(&iviscrn->pending.layer_list);
|
|
wl_list_init(&iviscrn->pending.link);
|
|
|
|
wl_list_init(&iviscrn->order.layer_list);
|
|
wl_list_init(&iviscrn->order.link);
|
|
|
|
wl_list_init(&iviscrn->link_to_layer);
|
|
|
|
wl_list_insert(&layout->screen_list, &iviscrn->link);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Internal APIs to initialize properties of ivi_surface/ivi_layer when they are created.
|
|
*/
|
|
static void
|
|
init_layer_properties(struct ivi_layout_layer_properties *prop,
|
|
int32_t width, int32_t height)
|
|
{
|
|
memset(prop, 0, sizeof *prop);
|
|
prop->opacity = wl_fixed_from_double(1.0);
|
|
prop->source_width = width;
|
|
prop->source_height = height;
|
|
prop->dest_width = width;
|
|
prop->dest_height = height;
|
|
}
|
|
|
|
static void
|
|
init_surface_properties(struct ivi_layout_surface_properties *prop)
|
|
{
|
|
memset(prop, 0, sizeof *prop);
|
|
prop->opacity = wl_fixed_from_double(1.0);
|
|
/*
|
|
* FIXME: this shall be finxed by ivi-layout-transition.
|
|
*/
|
|
prop->dest_width = 1;
|
|
prop->dest_height = 1;
|
|
}
|
|
|
|
/**
|
|
* Internal APIs to be called from ivi_layout_commit_changes.
|
|
*/
|
|
static void
|
|
update_opacity(struct ivi_layout_layer *ivilayer,
|
|
struct ivi_layout_surface *ivisurf)
|
|
{
|
|
double layer_alpha = wl_fixed_to_double(ivilayer->prop.opacity);
|
|
double surf_alpha = wl_fixed_to_double(ivisurf->prop.opacity);
|
|
|
|
if ((ivilayer->event_mask & IVI_NOTIFICATION_OPACITY) ||
|
|
(ivisurf->event_mask & IVI_NOTIFICATION_OPACITY)) {
|
|
struct weston_view *tmpview = NULL;
|
|
wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
|
|
if (tmpview == NULL) {
|
|
continue;
|
|
}
|
|
tmpview->alpha = layer_alpha * surf_alpha;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
update_surface_orientation(struct ivi_layout_layer *ivilayer,
|
|
struct ivi_layout_surface *ivisurf)
|
|
{
|
|
struct weston_view *view;
|
|
struct weston_matrix *matrix = &ivisurf->surface_rotation.matrix;
|
|
float width = 0.0f;
|
|
float height = 0.0f;
|
|
float v_sin = 0.0f;
|
|
float v_cos = 0.0f;
|
|
float cx = 0.0f;
|
|
float cy = 0.0f;
|
|
float sx = 1.0f;
|
|
float sy = 1.0f;
|
|
|
|
wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
|
|
if (view != NULL) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (view == NULL) {
|
|
return;
|
|
}
|
|
|
|
if ((ivilayer->prop.dest_width == 0) ||
|
|
(ivilayer->prop.dest_height == 0)) {
|
|
return;
|
|
}
|
|
width = (float)ivilayer->prop.dest_width;
|
|
height = (float)ivilayer->prop.dest_height;
|
|
|
|
switch (ivisurf->prop.orientation) {
|
|
case WL_OUTPUT_TRANSFORM_NORMAL:
|
|
v_sin = 0.0f;
|
|
v_cos = 1.0f;
|
|
break;
|
|
case WL_OUTPUT_TRANSFORM_90:
|
|
v_sin = 1.0f;
|
|
v_cos = 0.0f;
|
|
sx = width / height;
|
|
sy = height / width;
|
|
break;
|
|
case WL_OUTPUT_TRANSFORM_180:
|
|
v_sin = 0.0f;
|
|
v_cos = -1.0f;
|
|
break;
|
|
case WL_OUTPUT_TRANSFORM_270:
|
|
default:
|
|
v_sin = -1.0f;
|
|
v_cos = 0.0f;
|
|
sx = width / height;
|
|
sy = height / width;
|
|
break;
|
|
}
|
|
wl_list_remove(&ivisurf->surface_rotation.link);
|
|
weston_view_geometry_dirty(view);
|
|
|
|
weston_matrix_init(matrix);
|
|
cx = 0.5f * width;
|
|
cy = 0.5f * height;
|
|
weston_matrix_translate(matrix, -cx, -cy, 0.0f);
|
|
weston_matrix_rotate_xy(matrix, v_cos, v_sin);
|
|
weston_matrix_scale(matrix, sx, sy, 1.0);
|
|
weston_matrix_translate(matrix, cx, cy, 0.0f);
|
|
wl_list_insert(&view->geometry.transformation_list,
|
|
&ivisurf->surface_rotation.link);
|
|
|
|
weston_view_set_transform_parent(view, NULL);
|
|
weston_view_update_transform(view);
|
|
}
|
|
|
|
static void
|
|
update_layer_orientation(struct ivi_layout_layer *ivilayer,
|
|
struct ivi_layout_surface *ivisurf)
|
|
{
|
|
struct weston_surface *es = ivisurf->surface;
|
|
struct weston_view *view;
|
|
struct weston_matrix *matrix = &ivisurf->layer_rotation.matrix;
|
|
struct weston_output *output = NULL;
|
|
float width = 0.0f;
|
|
float height = 0.0f;
|
|
float v_sin = 0.0f;
|
|
float v_cos = 0.0f;
|
|
float cx = 0.0f;
|
|
float cy = 0.0f;
|
|
float sx = 1.0f;
|
|
float sy = 1.0f;
|
|
|
|
wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
|
|
if (view != NULL) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (es == NULL || view == NULL) {
|
|
return;
|
|
}
|
|
|
|
output = es->output;
|
|
if (output == NULL) {
|
|
return;
|
|
}
|
|
if ((output->width == 0) || (output->height == 0)) {
|
|
return;
|
|
}
|
|
width = (float)output->width;
|
|
height = (float)output->height;
|
|
|
|
switch (ivilayer->prop.orientation) {
|
|
case WL_OUTPUT_TRANSFORM_NORMAL:
|
|
v_sin = 0.0f;
|
|
v_cos = 1.0f;
|
|
break;
|
|
case WL_OUTPUT_TRANSFORM_90:
|
|
v_sin = 1.0f;
|
|
v_cos = 0.0f;
|
|
sx = width / height;
|
|
sy = height / width;
|
|
break;
|
|
case WL_OUTPUT_TRANSFORM_180:
|
|
v_sin = 0.0f;
|
|
v_cos = -1.0f;
|
|
break;
|
|
case WL_OUTPUT_TRANSFORM_270:
|
|
default:
|
|
v_sin = -1.0f;
|
|
v_cos = 0.0f;
|
|
sx = width / height;
|
|
sy = height / width;
|
|
break;
|
|
}
|
|
wl_list_remove(&ivisurf->layer_rotation.link);
|
|
weston_view_geometry_dirty(view);
|
|
|
|
weston_matrix_init(matrix);
|
|
cx = 0.5f * width;
|
|
cy = 0.5f * height;
|
|
weston_matrix_translate(matrix, -cx, -cy, 0.0f);
|
|
weston_matrix_rotate_xy(matrix, v_cos, v_sin);
|
|
weston_matrix_scale(matrix, sx, sy, 1.0);
|
|
weston_matrix_translate(matrix, cx, cy, 0.0f);
|
|
wl_list_insert(&view->geometry.transformation_list,
|
|
&ivisurf->layer_rotation.link);
|
|
|
|
weston_view_set_transform_parent(view, NULL);
|
|
weston_view_update_transform(view);
|
|
}
|
|
|
|
static void
|
|
update_surface_position(struct ivi_layout_surface *ivisurf)
|
|
{
|
|
struct weston_view *view;
|
|
float tx = (float)ivisurf->prop.dest_x;
|
|
float ty = (float)ivisurf->prop.dest_y;
|
|
struct weston_matrix *matrix = &ivisurf->surface_pos.matrix;
|
|
|
|
wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
|
|
if (view != NULL) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (view == NULL) {
|
|
return;
|
|
}
|
|
|
|
wl_list_remove(&ivisurf->surface_pos.link);
|
|
|
|
weston_matrix_init(matrix);
|
|
weston_matrix_translate(matrix, tx, ty, 0.0f);
|
|
wl_list_insert(&view->geometry.transformation_list,
|
|
&ivisurf->surface_pos.link);
|
|
|
|
weston_view_set_transform_parent(view, NULL);
|
|
weston_view_update_transform(view);
|
|
}
|
|
|
|
static void
|
|
update_layer_position(struct ivi_layout_layer *ivilayer,
|
|
struct ivi_layout_surface *ivisurf)
|
|
{
|
|
struct weston_view *view;
|
|
struct weston_matrix *matrix = &ivisurf->layer_pos.matrix;
|
|
float tx = (float)ivilayer->prop.dest_x;
|
|
float ty = (float)ivilayer->prop.dest_y;
|
|
|
|
wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
|
|
if (view != NULL) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (view == NULL) {
|
|
return;
|
|
}
|
|
|
|
wl_list_remove(&ivisurf->layer_pos.link);
|
|
|
|
weston_matrix_init(matrix);
|
|
weston_matrix_translate(matrix, tx, ty, 0.0f);
|
|
wl_list_insert(&view->geometry.transformation_list,
|
|
&ivisurf->layer_pos.link);
|
|
|
|
weston_view_set_transform_parent(view, NULL);
|
|
weston_view_update_transform(view);
|
|
}
|
|
|
|
static void
|
|
update_scale(struct ivi_layout_layer *ivilayer,
|
|
struct ivi_layout_surface *ivisurf)
|
|
{
|
|
struct weston_view *view;
|
|
struct weston_matrix *matrix = &ivisurf->scaling.matrix;
|
|
float sx = 0.0f;
|
|
float sy = 0.0f;
|
|
float lw = 0.0f;
|
|
float sw = 0.0f;
|
|
float lh = 0.0f;
|
|
float sh = 0.0f;
|
|
|
|
wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
|
|
if (view != NULL) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (view == NULL) {
|
|
return;
|
|
}
|
|
|
|
if (ivisurf->prop.source_width == 0 || ivisurf->prop.source_height == 0) {
|
|
weston_log("ivi-shell: source rectangle is not yet set by ivi_layout_surface_set_source_rectangle\n");
|
|
return;
|
|
}
|
|
|
|
if (ivisurf->prop.dest_width == 0 || ivisurf->prop.dest_height == 0) {
|
|
weston_log("ivi-shell: destination rectangle is not yet set by ivi_layout_surface_set_destination_rectangle\n");
|
|
return;
|
|
}
|
|
|
|
lw = ((float)ivilayer->prop.dest_width / (float)ivilayer->prop.source_width );
|
|
sw = ((float)ivisurf->prop.dest_width / (float)ivisurf->prop.source_width );
|
|
lh = ((float)ivilayer->prop.dest_height / (float)ivilayer->prop.source_height);
|
|
sh = ((float)ivisurf->prop.dest_height / (float)ivisurf->prop.source_height );
|
|
sx = sw * lw;
|
|
sy = sh * lh;
|
|
|
|
wl_list_remove(&ivisurf->scaling.link);
|
|
weston_matrix_init(matrix);
|
|
weston_matrix_scale(matrix, sx, sy, 1.0f);
|
|
|
|
wl_list_insert(&view->geometry.transformation_list,
|
|
&ivisurf->scaling.link);
|
|
|
|
weston_view_set_transform_parent(view, NULL);
|
|
weston_view_update_transform(view);
|
|
}
|
|
|
|
static void
|
|
update_prop(struct ivi_layout_layer *ivilayer,
|
|
struct ivi_layout_surface *ivisurf)
|
|
{
|
|
if (ivilayer->event_mask | ivisurf->event_mask) {
|
|
struct weston_view *tmpview;
|
|
update_opacity(ivilayer, ivisurf);
|
|
update_layer_orientation(ivilayer, ivisurf);
|
|
update_layer_position(ivilayer, ivisurf);
|
|
update_surface_position(ivisurf);
|
|
update_surface_orientation(ivilayer, ivisurf);
|
|
update_scale(ivilayer, ivisurf);
|
|
|
|
ivisurf->update_count++;
|
|
|
|
wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
|
|
if (tmpview != NULL) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (tmpview != NULL) {
|
|
weston_view_geometry_dirty(tmpview);
|
|
}
|
|
|
|
if (ivisurf->surface != NULL) {
|
|
weston_surface_damage(ivisurf->surface);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
commit_changes(struct ivi_layout *layout)
|
|
{
|
|
struct ivi_layout_screen *iviscrn = NULL;
|
|
struct ivi_layout_layer *ivilayer = NULL;
|
|
struct ivi_layout_surface *ivisurf = NULL;
|
|
|
|
wl_list_for_each(iviscrn, &layout->screen_list, link) {
|
|
wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
|
|
wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
|
|
update_prop(ivilayer, ivisurf);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
commit_surface_list(struct ivi_layout *layout)
|
|
{
|
|
struct ivi_layout_surface *ivisurf = NULL;
|
|
int32_t dest_x = 0;
|
|
int32_t dest_y = 0;
|
|
int32_t dest_width = 0;
|
|
int32_t dest_height = 0;
|
|
int32_t configured = 0;
|
|
|
|
wl_list_for_each(ivisurf, &layout->surface_list, link) {
|
|
if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEFAULT) {
|
|
dest_x = ivisurf->prop.dest_x;
|
|
dest_y = ivisurf->prop.dest_y;
|
|
dest_width = ivisurf->prop.dest_width;
|
|
dest_height = ivisurf->prop.dest_height;
|
|
|
|
ivi_layout_transition_move_resize_view(ivisurf,
|
|
ivisurf->pending.prop.dest_x,
|
|
ivisurf->pending.prop.dest_y,
|
|
ivisurf->pending.prop.dest_width,
|
|
ivisurf->pending.prop.dest_height,
|
|
ivisurf->pending.prop.transition_duration);
|
|
|
|
if(ivisurf->pending.prop.visibility) {
|
|
ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
|
|
} else {
|
|
ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
|
|
}
|
|
|
|
ivisurf->prop = ivisurf->pending.prop;
|
|
ivisurf->prop.dest_x = dest_x;
|
|
ivisurf->prop.dest_y = dest_y;
|
|
ivisurf->prop.dest_width = dest_width;
|
|
ivisurf->prop.dest_height = dest_height;
|
|
ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
|
|
ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
|
|
|
|
} else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY){
|
|
dest_x = ivisurf->prop.dest_x;
|
|
dest_y = ivisurf->prop.dest_y;
|
|
dest_width = ivisurf->prop.dest_width;
|
|
dest_height = ivisurf->prop.dest_height;
|
|
|
|
ivi_layout_transition_move_resize_view(ivisurf,
|
|
ivisurf->pending.prop.dest_x,
|
|
ivisurf->pending.prop.dest_y,
|
|
ivisurf->pending.prop.dest_width,
|
|
ivisurf->pending.prop.dest_height,
|
|
ivisurf->pending.prop.transition_duration);
|
|
|
|
ivisurf->prop = ivisurf->pending.prop;
|
|
ivisurf->prop.dest_x = dest_x;
|
|
ivisurf->prop.dest_y = dest_y;
|
|
ivisurf->prop.dest_width = dest_width;
|
|
ivisurf->prop.dest_height = dest_height;
|
|
|
|
ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
|
|
ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
|
|
|
|
} else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY){
|
|
configured = 0;
|
|
if(ivisurf->pending.prop.visibility) {
|
|
ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
|
|
} else {
|
|
ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
|
|
}
|
|
|
|
if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
|
|
ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
|
|
configured = 1;
|
|
}
|
|
|
|
ivisurf->prop = ivisurf->pending.prop;
|
|
ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
|
|
ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
|
|
|
|
if (configured && !is_surface_transition(ivisurf))
|
|
wl_signal_emit(&ivisurf->configured, ivisurf);
|
|
} else {
|
|
configured = 0;
|
|
if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
|
|
ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
|
|
configured = 1;
|
|
}
|
|
|
|
ivisurf->prop = ivisurf->pending.prop;
|
|
ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
|
|
ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
|
|
|
|
if (configured && !is_surface_transition(ivisurf))
|
|
wl_signal_emit(&ivisurf->configured, ivisurf);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
commit_layer_list(struct ivi_layout *layout)
|
|
{
|
|
struct ivi_layout_layer *ivilayer = NULL;
|
|
struct ivi_layout_surface *ivisurf = NULL;
|
|
struct ivi_layout_surface *next = NULL;
|
|
|
|
wl_list_for_each(ivilayer, &layout->layer_list, link) {
|
|
if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_MOVE) {
|
|
ivi_layout_transition_move_layer(ivilayer, ivilayer->pending.prop.dest_x, ivilayer->pending.prop.dest_y, ivilayer->pending.prop.transition_duration);
|
|
} else if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_FADE) {
|
|
ivi_layout_transition_fade_layer(ivilayer,ivilayer->pending.prop.is_fade_in,
|
|
ivilayer->pending.prop.start_alpha,ivilayer->pending.prop.end_alpha,
|
|
NULL, NULL,
|
|
ivilayer->pending.prop.transition_duration);
|
|
}
|
|
ivilayer->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
|
|
|
|
ivilayer->prop = ivilayer->pending.prop;
|
|
|
|
if (!(ivilayer->event_mask &
|
|
(IVI_NOTIFICATION_ADD | IVI_NOTIFICATION_REMOVE)) ) {
|
|
continue;
|
|
}
|
|
|
|
if (ivilayer->event_mask & IVI_NOTIFICATION_REMOVE) {
|
|
wl_list_for_each_safe(ivisurf, next,
|
|
&ivilayer->order.surface_list, order.link) {
|
|
remove_ordersurface_from_layer(ivisurf);
|
|
|
|
if (!wl_list_empty(&ivisurf->order.link)) {
|
|
wl_list_remove(&ivisurf->order.link);
|
|
}
|
|
|
|
wl_list_init(&ivisurf->order.link);
|
|
ivisurf->event_mask |= IVI_NOTIFICATION_REMOVE;
|
|
}
|
|
|
|
wl_list_init(&ivilayer->order.surface_list);
|
|
}
|
|
|
|
if (ivilayer->event_mask & IVI_NOTIFICATION_ADD) {
|
|
wl_list_for_each_safe(ivisurf, next,
|
|
&ivilayer->order.surface_list, order.link) {
|
|
remove_ordersurface_from_layer(ivisurf);
|
|
|
|
if (!wl_list_empty(&ivisurf->order.link)) {
|
|
wl_list_remove(&ivisurf->order.link);
|
|
}
|
|
|
|
wl_list_init(&ivisurf->order.link);
|
|
}
|
|
|
|
wl_list_init(&ivilayer->order.surface_list);
|
|
wl_list_for_each(ivisurf, &ivilayer->pending.surface_list,
|
|
pending.link) {
|
|
if(!wl_list_empty(&ivisurf->order.link)){
|
|
wl_list_remove(&ivisurf->order.link);
|
|
wl_list_init(&ivisurf->order.link);
|
|
}
|
|
|
|
wl_list_insert(&ivilayer->order.surface_list,
|
|
&ivisurf->order.link);
|
|
add_ordersurface_to_layer(ivisurf, ivilayer);
|
|
ivisurf->event_mask |= IVI_NOTIFICATION_ADD;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
commit_screen_list(struct ivi_layout *layout)
|
|
{
|
|
struct ivi_layout_screen *iviscrn = NULL;
|
|
struct ivi_layout_layer *ivilayer = NULL;
|
|
struct ivi_layout_layer *next = NULL;
|
|
struct ivi_layout_surface *ivisurf = NULL;
|
|
|
|
wl_list_for_each(iviscrn, &layout->screen_list, link) {
|
|
if (iviscrn->event_mask & IVI_NOTIFICATION_REMOVE) {
|
|
wl_list_for_each_safe(ivilayer, next,
|
|
&iviscrn->order.layer_list, order.link) {
|
|
remove_orderlayer_from_screen(ivilayer);
|
|
|
|
if (!wl_list_empty(&ivilayer->order.link)) {
|
|
wl_list_remove(&ivilayer->order.link);
|
|
}
|
|
|
|
wl_list_init(&ivilayer->order.link);
|
|
ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
|
|
}
|
|
}
|
|
|
|
if (iviscrn->event_mask & IVI_NOTIFICATION_ADD) {
|
|
wl_list_for_each_safe(ivilayer, next,
|
|
&iviscrn->order.layer_list, order.link) {
|
|
remove_orderlayer_from_screen(ivilayer);
|
|
|
|
if (!wl_list_empty(&ivilayer->order.link)) {
|
|
wl_list_remove(&ivilayer->order.link);
|
|
}
|
|
|
|
wl_list_init(&ivilayer->order.link);
|
|
}
|
|
|
|
wl_list_init(&iviscrn->order.layer_list);
|
|
wl_list_for_each(ivilayer, &iviscrn->pending.layer_list,
|
|
pending.link) {
|
|
wl_list_insert(&iviscrn->order.layer_list,
|
|
&ivilayer->order.link);
|
|
add_orderlayer_to_screen(ivilayer, iviscrn);
|
|
ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
|
|
}
|
|
}
|
|
|
|
iviscrn->event_mask = 0;
|
|
|
|
/* Clear view list of layout ivi_layer */
|
|
wl_list_init(&layout->layout_layer.view_list.link);
|
|
|
|
wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
|
|
if (ivilayer->prop.visibility == false)
|
|
continue;
|
|
|
|
wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
|
|
struct weston_view *tmpview = NULL;
|
|
wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
|
|
if (tmpview != NULL) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ivisurf->prop.visibility == false)
|
|
continue;
|
|
if (ivisurf->surface == NULL || tmpview == NULL)
|
|
continue;
|
|
|
|
weston_layer_entry_insert(&layout->layout_layer.view_list,
|
|
&tmpview->layer_link);
|
|
|
|
ivisurf->surface->output = iviscrn->output;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
commit_transition(struct ivi_layout* layout)
|
|
{
|
|
if(wl_list_empty(&layout->pending_transition_list)){
|
|
return;
|
|
}
|
|
|
|
wl_list_insert_list(&layout->transitions->transition_list,
|
|
&layout->pending_transition_list);
|
|
|
|
wl_list_init(&layout->pending_transition_list);
|
|
|
|
wl_event_source_timer_update(layout->transitions->event_source, 1);
|
|
}
|
|
|
|
static void
|
|
send_surface_prop(struct ivi_layout_surface *ivisurf)
|
|
{
|
|
wl_signal_emit(&ivisurf->property_changed, ivisurf);
|
|
ivisurf->event_mask = 0;
|
|
}
|
|
|
|
static void
|
|
send_layer_prop(struct ivi_layout_layer *ivilayer)
|
|
{
|
|
wl_signal_emit(&ivilayer->property_changed, ivilayer);
|
|
ivilayer->event_mask = 0;
|
|
}
|
|
|
|
static void
|
|
send_prop(struct ivi_layout *layout)
|
|
{
|
|
struct ivi_layout_layer *ivilayer = NULL;
|
|
struct ivi_layout_surface *ivisurf = NULL;
|
|
|
|
wl_list_for_each_reverse(ivilayer, &layout->layer_list, link) {
|
|
if (ivilayer->event_mask)
|
|
send_layer_prop(ivilayer);
|
|
}
|
|
|
|
wl_list_for_each_reverse(ivisurf, &layout->surface_list, link) {
|
|
if (ivisurf->event_mask)
|
|
send_surface_prop(ivisurf);
|
|
}
|
|
}
|
|
|
|
static void
|
|
clear_surface_pending_list(struct ivi_layout_layer *ivilayer)
|
|
{
|
|
struct ivi_layout_surface *surface_link = NULL;
|
|
struct ivi_layout_surface *surface_next = NULL;
|
|
|
|
wl_list_for_each_safe(surface_link, surface_next,
|
|
&ivilayer->pending.surface_list, pending.link) {
|
|
if (!wl_list_empty(&surface_link->pending.link)) {
|
|
wl_list_remove(&surface_link->pending.link);
|
|
}
|
|
|
|
wl_list_init(&surface_link->pending.link);
|
|
}
|
|
|
|
ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
|
|
}
|
|
|
|
static void
|
|
clear_surface_order_list(struct ivi_layout_layer *ivilayer)
|
|
{
|
|
struct ivi_layout_surface *surface_link = NULL;
|
|
struct ivi_layout_surface *surface_next = NULL;
|
|
|
|
wl_list_for_each_safe(surface_link, surface_next,
|
|
&ivilayer->order.surface_list, order.link) {
|
|
if (!wl_list_empty(&surface_link->order.link)) {
|
|
wl_list_remove(&surface_link->order.link);
|
|
}
|
|
|
|
wl_list_init(&surface_link->order.link);
|
|
}
|
|
|
|
ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
|
|
}
|
|
|
|
static void
|
|
layer_created(struct wl_listener *listener, void *data)
|
|
{
|
|
struct ivi_layout_layer *ivilayer = data;
|
|
|
|
struct listener_layout_notification *notification =
|
|
container_of(listener,
|
|
struct listener_layout_notification,
|
|
listener);
|
|
|
|
struct ivi_layout_notification_callback *created_callback =
|
|
notification->userdata;
|
|
|
|
((layer_create_notification_func)created_callback->callback)
|
|
(ivilayer, created_callback->data);
|
|
}
|
|
|
|
static void
|
|
layer_removed(struct wl_listener *listener, void *data)
|
|
{
|
|
struct ivi_layout_layer *ivilayer = data;
|
|
|
|
struct listener_layout_notification *notification =
|
|
container_of(listener,
|
|
struct listener_layout_notification,
|
|
listener);
|
|
|
|
struct ivi_layout_notification_callback *removed_callback =
|
|
notification->userdata;
|
|
|
|
((layer_remove_notification_func)removed_callback->callback)
|
|
(ivilayer, removed_callback->data);
|
|
}
|
|
|
|
static void
|
|
layer_prop_changed(struct wl_listener *listener, void *data)
|
|
{
|
|
struct ivi_layout_layer *ivilayer = data;
|
|
|
|
struct listener_layout_notification *layout_listener =
|
|
container_of(listener,
|
|
struct listener_layout_notification,
|
|
listener);
|
|
|
|
struct ivi_layout_notification_callback *prop_callback =
|
|
layout_listener->userdata;
|
|
|
|
((layer_property_notification_func)prop_callback->callback)
|
|
(ivilayer, &ivilayer->prop, ivilayer->event_mask, prop_callback->data);
|
|
}
|
|
|
|
static void
|
|
surface_created(struct wl_listener *listener, void *data)
|
|
{
|
|
struct ivi_layout_surface *ivisurface = data;
|
|
|
|
struct listener_layout_notification *notification =
|
|
container_of(listener,
|
|
struct listener_layout_notification,
|
|
listener);
|
|
|
|
struct ivi_layout_notification_callback *created_callback =
|
|
notification->userdata;
|
|
|
|
((surface_create_notification_func)created_callback->callback)
|
|
(ivisurface, created_callback->data);
|
|
}
|
|
|
|
static void
|
|
surface_removed(struct wl_listener *listener, void *data)
|
|
{
|
|
struct ivi_layout_surface *ivisurface = data;
|
|
|
|
struct listener_layout_notification *notification =
|
|
container_of(listener,
|
|
struct listener_layout_notification,
|
|
listener);
|
|
|
|
struct ivi_layout_notification_callback *removed_callback =
|
|
notification->userdata;
|
|
|
|
((surface_remove_notification_func)removed_callback->callback)
|
|
(ivisurface, removed_callback->data);
|
|
}
|
|
|
|
static void
|
|
surface_prop_changed(struct wl_listener *listener, void *data)
|
|
{
|
|
struct ivi_layout_surface *ivisurf = data;
|
|
|
|
struct listener_layout_notification *layout_listener =
|
|
container_of(listener,
|
|
struct listener_layout_notification,
|
|
listener);
|
|
|
|
struct ivi_layout_notification_callback *prop_callback =
|
|
layout_listener->userdata;
|
|
|
|
((surface_property_notification_func)prop_callback->callback)
|
|
(ivisurf, &ivisurf->prop, ivisurf->event_mask, prop_callback->data);
|
|
|
|
ivisurf->event_mask = 0;
|
|
}
|
|
|
|
static void
|
|
surface_configure_changed(struct wl_listener *listener,
|
|
void *data)
|
|
{
|
|
struct ivi_layout_surface *ivisurface = data;
|
|
|
|
struct listener_layout_notification *notification =
|
|
container_of(listener,
|
|
struct listener_layout_notification,
|
|
listener);
|
|
|
|
struct ivi_layout_notification_callback *configure_changed_callback =
|
|
notification->userdata;
|
|
|
|
((surface_configure_notification_func)configure_changed_callback->callback)
|
|
(ivisurface, configure_changed_callback->data);
|
|
}
|
|
|
|
static int32_t
|
|
add_notification(struct wl_signal *signal,
|
|
wl_notify_func_t callback,
|
|
void *userdata)
|
|
{
|
|
struct listener_layout_notification *notification = NULL;
|
|
|
|
notification = malloc(sizeof *notification);
|
|
if (notification == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
free(userdata);
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
notification->listener.notify = callback;
|
|
notification->userdata = userdata;
|
|
|
|
wl_signal_add(signal, ¬ification->listener);
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static void
|
|
remove_notification(struct wl_list *listener_list, void *callback, void *userdata)
|
|
{
|
|
struct wl_listener *listener = NULL;
|
|
struct wl_listener *next = NULL;
|
|
|
|
wl_list_for_each_safe(listener, next, listener_list, link) {
|
|
struct listener_layout_notification *notification =
|
|
container_of(listener,
|
|
struct listener_layout_notification,
|
|
listener);
|
|
|
|
struct ivi_layout_notification_callback *notification_callback =
|
|
notification->userdata;
|
|
|
|
if ((notification_callback->callback != callback) ||
|
|
(notification_callback->data != userdata)) {
|
|
continue;
|
|
}
|
|
|
|
if (!wl_list_empty(&listener->link)) {
|
|
wl_list_remove(&listener->link);
|
|
}
|
|
|
|
free(notification->userdata);
|
|
free(notification);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Exported APIs of ivi-layout library are implemented from here.
|
|
* Brief of APIs is described in ivi-layout-export.h.
|
|
*/
|
|
static int32_t
|
|
ivi_layout_add_notification_create_layer(layer_create_notification_func callback,
|
|
void *userdata)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_notification_callback *created_callback = NULL;
|
|
|
|
if (callback == NULL) {
|
|
weston_log("ivi_layout_add_notification_create_layer: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
created_callback = malloc(sizeof *created_callback);
|
|
if (created_callback == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
created_callback->callback = callback;
|
|
created_callback->data = userdata;
|
|
|
|
return add_notification(&layout->layer_notification.created,
|
|
layer_created,
|
|
created_callback);
|
|
}
|
|
|
|
static void
|
|
ivi_layout_remove_notification_create_layer(layer_create_notification_func callback,
|
|
void *userdata)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
remove_notification(&layout->layer_notification.created.listener_list, callback, userdata);
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_add_notification_remove_layer(layer_remove_notification_func callback,
|
|
void *userdata)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_notification_callback *removed_callback = NULL;
|
|
|
|
if (callback == NULL) {
|
|
weston_log("ivi_layout_add_notification_remove_layer: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
removed_callback = malloc(sizeof *removed_callback);
|
|
if (removed_callback == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
removed_callback->callback = callback;
|
|
removed_callback->data = userdata;
|
|
return add_notification(&layout->layer_notification.removed,
|
|
layer_removed,
|
|
removed_callback);
|
|
}
|
|
|
|
static void
|
|
ivi_layout_remove_notification_remove_layer(layer_remove_notification_func callback,
|
|
void *userdata)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
remove_notification(&layout->layer_notification.removed.listener_list, callback, userdata);
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_add_notification_create_surface(surface_create_notification_func callback,
|
|
void *userdata)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_notification_callback *created_callback = NULL;
|
|
|
|
if (callback == NULL) {
|
|
weston_log("ivi_layout_add_notification_create_surface: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
created_callback = malloc(sizeof *created_callback);
|
|
if (created_callback == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
created_callback->callback = callback;
|
|
created_callback->data = userdata;
|
|
|
|
return add_notification(&layout->surface_notification.created,
|
|
surface_created,
|
|
created_callback);
|
|
}
|
|
|
|
static void
|
|
ivi_layout_remove_notification_create_surface(surface_create_notification_func callback,
|
|
void *userdata)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
remove_notification(&layout->surface_notification.created.listener_list, callback, userdata);
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_add_notification_remove_surface(surface_remove_notification_func callback,
|
|
void *userdata)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_notification_callback *removed_callback = NULL;
|
|
|
|
if (callback == NULL) {
|
|
weston_log("ivi_layout_add_notification_remove_surface: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
removed_callback = malloc(sizeof *removed_callback);
|
|
if (removed_callback == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
removed_callback->callback = callback;
|
|
removed_callback->data = userdata;
|
|
|
|
return add_notification(&layout->surface_notification.removed,
|
|
surface_removed,
|
|
removed_callback);
|
|
}
|
|
|
|
static void
|
|
ivi_layout_remove_notification_remove_surface(surface_remove_notification_func callback,
|
|
void *userdata)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
remove_notification(&layout->surface_notification.removed.listener_list, callback, userdata);
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_add_notification_configure_surface(surface_configure_notification_func callback,
|
|
void *userdata)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_notification_callback *configure_changed_callback = NULL;
|
|
if (callback == NULL) {
|
|
weston_log("ivi_layout_add_notification_configure_surface: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
configure_changed_callback = malloc(sizeof *configure_changed_callback);
|
|
if (configure_changed_callback == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
configure_changed_callback->callback = callback;
|
|
configure_changed_callback->data = userdata;
|
|
|
|
return add_notification(&layout->surface_notification.configure_changed,
|
|
surface_configure_changed,
|
|
configure_changed_callback);
|
|
}
|
|
|
|
static void
|
|
ivi_layout_remove_notification_configure_surface(surface_configure_notification_func callback,
|
|
void *userdata)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
remove_notification(&layout->surface_notification.configure_changed.listener_list, callback, userdata);
|
|
}
|
|
|
|
uint32_t
|
|
ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf)
|
|
{
|
|
return ivisurf->id_surface;
|
|
}
|
|
|
|
static uint32_t
|
|
ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer)
|
|
{
|
|
return ivilayer->id_layer;
|
|
}
|
|
|
|
static uint32_t
|
|
ivi_layout_get_id_of_screen(struct ivi_layout_screen *iviscrn)
|
|
{
|
|
return iviscrn->id_screen;
|
|
}
|
|
|
|
static struct ivi_layout_layer *
|
|
ivi_layout_get_layer_from_id(uint32_t id_layer)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_layer *ivilayer = NULL;
|
|
|
|
wl_list_for_each(ivilayer, &layout->layer_list, link) {
|
|
if (ivilayer->id_layer == id_layer) {
|
|
return ivilayer;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
struct ivi_layout_surface *
|
|
ivi_layout_get_surface_from_id(uint32_t id_surface)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_surface *ivisurf = NULL;
|
|
|
|
wl_list_for_each(ivisurf, &layout->surface_list, link) {
|
|
if (ivisurf->id_surface == id_surface) {
|
|
return ivisurf;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static struct ivi_layout_screen *
|
|
ivi_layout_get_screen_from_id(uint32_t id_screen)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_screen *iviscrn = NULL;
|
|
|
|
wl_list_for_each(iviscrn, &layout->screen_list, link) {
|
|
/* FIXME : select iviscrn from screen_list by id_screen */
|
|
return iviscrn;
|
|
break;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_get_screen_resolution(struct ivi_layout_screen *iviscrn,
|
|
int32_t *pWidth, int32_t *pHeight)
|
|
{
|
|
struct weston_output *output = NULL;
|
|
|
|
if (iviscrn == NULL || pWidth == NULL || pHeight == NULL) {
|
|
weston_log("ivi_layout_get_screen_resolution: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
output = iviscrn->output;
|
|
*pWidth = output->current_mode->width;
|
|
*pHeight = output->current_mode->height;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_surface_add_notification(struct ivi_layout_surface *ivisurf,
|
|
surface_property_notification_func callback,
|
|
void *userdata)
|
|
{
|
|
struct listener_layout_notification* notification = NULL;
|
|
struct ivi_layout_notification_callback *prop_callback = NULL;
|
|
|
|
if (ivisurf == NULL || callback == NULL) {
|
|
weston_log("ivi_layout_surface_add_notification: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
notification = malloc(sizeof *notification);
|
|
if (notification == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop_callback = malloc(sizeof *prop_callback);
|
|
if (prop_callback == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop_callback->callback = callback;
|
|
prop_callback->data = userdata;
|
|
|
|
notification->listener.notify = surface_prop_changed;
|
|
notification->userdata = prop_callback;
|
|
|
|
wl_signal_add(&ivisurf->property_changed, ¬ification->listener);
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static const struct ivi_layout_layer_properties *
|
|
ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer)
|
|
{
|
|
if (ivilayer == NULL) {
|
|
weston_log("ivi_layout_get_properties_of_layer: invalid argument\n");
|
|
return NULL;
|
|
}
|
|
|
|
return &ivilayer->prop;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_get_screens(int32_t *pLength, struct ivi_layout_screen ***ppArray)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_screen *iviscrn = NULL;
|
|
int32_t length = 0;
|
|
int32_t n = 0;
|
|
|
|
if (pLength == NULL || ppArray == NULL) {
|
|
weston_log("ivi_layout_get_screens: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
length = wl_list_length(&layout->screen_list);
|
|
|
|
if (length != 0){
|
|
/* the Array must be free by module which called this function */
|
|
*ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
|
|
if (*ppArray == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
wl_list_for_each(iviscrn, &layout->screen_list, link) {
|
|
(*ppArray)[n++] = iviscrn;
|
|
}
|
|
}
|
|
|
|
*pLength = length;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer,
|
|
int32_t *pLength,
|
|
struct ivi_layout_screen ***ppArray)
|
|
{
|
|
struct link_screen *link_scrn = NULL;
|
|
int32_t length = 0;
|
|
int32_t n = 0;
|
|
|
|
if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
|
|
weston_log("ivi_layout_get_screens_under_layer: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
length = wl_list_length(&ivilayer->screen_list);
|
|
|
|
if (length != 0){
|
|
/* the Array must be free by module which called this function */
|
|
*ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
|
|
if (*ppArray == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
wl_list_for_each(link_scrn, &ivilayer->screen_list, link) {
|
|
(*ppArray)[n++] = link_scrn->iviscrn;
|
|
}
|
|
}
|
|
|
|
*pLength = length;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_layer *ivilayer = NULL;
|
|
int32_t length = 0;
|
|
int32_t n = 0;
|
|
|
|
if (pLength == NULL || ppArray == NULL) {
|
|
weston_log("ivi_layout_get_layers: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
length = wl_list_length(&layout->layer_list);
|
|
|
|
if (length != 0){
|
|
/* the Array must be free by module which called this function */
|
|
*ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
|
|
if (*ppArray == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
wl_list_for_each(ivilayer, &layout->layer_list, link) {
|
|
(*ppArray)[n++] = ivilayer;
|
|
}
|
|
}
|
|
|
|
*pLength = length;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_get_layers_on_screen(struct ivi_layout_screen *iviscrn,
|
|
int32_t *pLength,
|
|
struct ivi_layout_layer ***ppArray)
|
|
{
|
|
struct ivi_layout_layer *ivilayer = NULL;
|
|
int32_t length = 0;
|
|
int32_t n = 0;
|
|
|
|
if (iviscrn == NULL || pLength == NULL || ppArray == NULL) {
|
|
weston_log("ivi_layout_get_layers_on_screen: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
length = wl_list_length(&iviscrn->order.layer_list);
|
|
|
|
if (length != 0){
|
|
/* the Array must be free by module which called this function */
|
|
*ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
|
|
if (*ppArray == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
|
|
(*ppArray)[n++] = ivilayer;
|
|
}
|
|
}
|
|
|
|
*pLength = length;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf,
|
|
int32_t *pLength,
|
|
struct ivi_layout_layer ***ppArray)
|
|
{
|
|
struct link_layer *link_layer = NULL;
|
|
int32_t length = 0;
|
|
int32_t n = 0;
|
|
|
|
if (ivisurf == NULL || pLength == NULL || ppArray == NULL) {
|
|
weston_log("ivi_layout_getLayers: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
length = wl_list_length(&ivisurf->layer_list);
|
|
|
|
if (length != 0){
|
|
/* the Array must be free by module which called this function */
|
|
*ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
|
|
if (*ppArray == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
wl_list_for_each(link_layer, &ivisurf->layer_list, link) {
|
|
(*ppArray)[n++] = link_layer->ivilayer;
|
|
}
|
|
}
|
|
|
|
*pLength = length;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static
|
|
int32_t
|
|
ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_surface *ivisurf = NULL;
|
|
int32_t length = 0;
|
|
int32_t n = 0;
|
|
|
|
if (pLength == NULL || ppArray == NULL) {
|
|
weston_log("ivi_layout_get_surfaces: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
length = wl_list_length(&layout->surface_list);
|
|
|
|
if (length != 0){
|
|
/* the Array must be free by module which called this function */
|
|
*ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
|
|
if (*ppArray == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
wl_list_for_each(ivisurf, &layout->surface_list, link) {
|
|
(*ppArray)[n++] = ivisurf;
|
|
}
|
|
}
|
|
|
|
*pLength = length;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_get_surfaces_on_layer(struct ivi_layout_layer *ivilayer,
|
|
int32_t *pLength,
|
|
struct ivi_layout_surface ***ppArray)
|
|
{
|
|
struct ivi_layout_surface *ivisurf = NULL;
|
|
int32_t length = 0;
|
|
int32_t n = 0;
|
|
|
|
if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
|
|
weston_log("ivi_layout_getSurfaceIDsOnLayer: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
length = wl_list_length(&ivilayer->order.surface_list);
|
|
|
|
if (length != 0) {
|
|
/* the Array must be free by module which called this function */
|
|
*ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
|
|
if (*ppArray == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
|
|
(*ppArray)[n++] = ivisurf;
|
|
}
|
|
}
|
|
|
|
*pLength = length;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static struct ivi_layout_layer *
|
|
ivi_layout_layer_create_with_dimension(uint32_t id_layer,
|
|
int32_t width, int32_t height)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_layer *ivilayer = NULL;
|
|
|
|
ivilayer = get_layer(&layout->layer_list, id_layer);
|
|
if (ivilayer != NULL) {
|
|
weston_log("id_layer is already created\n");
|
|
++ivilayer->ref_count;
|
|
return ivilayer;
|
|
}
|
|
|
|
ivilayer = calloc(1, sizeof *ivilayer);
|
|
if (ivilayer == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return NULL;
|
|
}
|
|
|
|
ivilayer->ref_count = 1;
|
|
wl_list_init(&ivilayer->link);
|
|
wl_signal_init(&ivilayer->property_changed);
|
|
wl_list_init(&ivilayer->screen_list);
|
|
wl_list_init(&ivilayer->link_to_surface);
|
|
ivilayer->layout = layout;
|
|
ivilayer->id_layer = id_layer;
|
|
|
|
init_layer_properties(&ivilayer->prop, width, height);
|
|
ivilayer->event_mask = 0;
|
|
|
|
wl_list_init(&ivilayer->pending.surface_list);
|
|
wl_list_init(&ivilayer->pending.link);
|
|
ivilayer->pending.prop = ivilayer->prop;
|
|
|
|
wl_list_init(&ivilayer->order.surface_list);
|
|
wl_list_init(&ivilayer->order.link);
|
|
|
|
wl_list_insert(&layout->layer_list, &ivilayer->link);
|
|
|
|
wl_signal_emit(&layout->layer_notification.created, ivilayer);
|
|
|
|
return ivilayer;
|
|
}
|
|
|
|
static void
|
|
ivi_layout_layer_remove_notification(struct ivi_layout_layer *ivilayer)
|
|
{
|
|
if (ivilayer == NULL) {
|
|
weston_log("ivi_layout_layer_remove_notification: invalid argument\n");
|
|
return;
|
|
}
|
|
|
|
remove_all_notification(&ivilayer->property_changed.listener_list);
|
|
}
|
|
|
|
static void
|
|
ivi_layout_layer_remove_notification_by_callback(struct ivi_layout_layer *ivilayer,
|
|
layer_property_notification_func callback,
|
|
void *userdata)
|
|
{
|
|
if (ivilayer == NULL) {
|
|
weston_log("ivi_layout_layer_remove_notification_by_callback: invalid argument\n");
|
|
return;
|
|
}
|
|
|
|
remove_notification(&ivilayer->property_changed.listener_list, callback, userdata);
|
|
}
|
|
|
|
static void
|
|
ivi_layout_layer_destroy(struct ivi_layout_layer *ivilayer)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
|
|
if (ivilayer == NULL) {
|
|
weston_log("ivi_layout_layer_remove: invalid argument\n");
|
|
return;
|
|
}
|
|
|
|
if (--ivilayer->ref_count > 0)
|
|
return;
|
|
|
|
wl_signal_emit(&layout->layer_notification.removed, ivilayer);
|
|
|
|
clear_surface_pending_list(ivilayer);
|
|
clear_surface_order_list(ivilayer);
|
|
|
|
if (!wl_list_empty(&ivilayer->pending.link)) {
|
|
wl_list_remove(&ivilayer->pending.link);
|
|
}
|
|
if (!wl_list_empty(&ivilayer->order.link)) {
|
|
wl_list_remove(&ivilayer->order.link);
|
|
}
|
|
if (!wl_list_empty(&ivilayer->link)) {
|
|
wl_list_remove(&ivilayer->link);
|
|
}
|
|
remove_orderlayer_from_screen(ivilayer);
|
|
remove_link_to_surface(ivilayer);
|
|
ivi_layout_layer_remove_notification(ivilayer);
|
|
|
|
free(ivilayer);
|
|
}
|
|
|
|
int32_t
|
|
ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer,
|
|
bool newVisibility)
|
|
{
|
|
struct ivi_layout_layer_properties *prop = NULL;
|
|
|
|
if (ivilayer == NULL) {
|
|
weston_log("ivi_layout_layer_set_visibility: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop = &ivilayer->pending.prop;
|
|
prop->visibility = newVisibility;
|
|
|
|
if (ivilayer->prop.visibility != newVisibility)
|
|
ivilayer->event_mask |= IVI_NOTIFICATION_VISIBILITY;
|
|
else
|
|
ivilayer->event_mask &= ~IVI_NOTIFICATION_VISIBILITY;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static bool
|
|
ivi_layout_layer_get_visibility(struct ivi_layout_layer *ivilayer)
|
|
{
|
|
if (ivilayer == NULL) {
|
|
weston_log("ivi_layout_layer_get_visibility: invalid argument\n");
|
|
return false;
|
|
}
|
|
|
|
return ivilayer->prop.visibility;
|
|
}
|
|
|
|
int32_t
|
|
ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
|
|
wl_fixed_t opacity)
|
|
{
|
|
struct ivi_layout_layer_properties *prop = NULL;
|
|
|
|
if (ivilayer == NULL ||
|
|
opacity < wl_fixed_from_double(0.0) ||
|
|
wl_fixed_from_double(1.0) < opacity) {
|
|
weston_log("ivi_layout_layer_set_opacity: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop = &ivilayer->pending.prop;
|
|
prop->opacity = opacity;
|
|
|
|
if (ivilayer->prop.opacity != opacity)
|
|
ivilayer->event_mask |= IVI_NOTIFICATION_OPACITY;
|
|
else
|
|
ivilayer->event_mask &= ~IVI_NOTIFICATION_OPACITY;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
wl_fixed_t
|
|
ivi_layout_layer_get_opacity(struct ivi_layout_layer *ivilayer)
|
|
{
|
|
if (ivilayer == NULL) {
|
|
weston_log("ivi_layout_layer_get_opacity: invalid argument\n");
|
|
return wl_fixed_from_double(0.0);
|
|
}
|
|
|
|
return ivilayer->prop.opacity;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer,
|
|
int32_t x, int32_t y,
|
|
int32_t width, int32_t height)
|
|
{
|
|
struct ivi_layout_layer_properties *prop = NULL;
|
|
|
|
if (ivilayer == NULL) {
|
|
weston_log("ivi_layout_layer_set_source_rectangle: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop = &ivilayer->pending.prop;
|
|
prop->source_x = x;
|
|
prop->source_y = y;
|
|
prop->source_width = width;
|
|
prop->source_height = height;
|
|
|
|
if (ivilayer->prop.source_x != x || ivilayer->prop.source_y != y ||
|
|
ivilayer->prop.source_width != width ||
|
|
ivilayer->prop.source_height != height)
|
|
ivilayer->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
|
|
else
|
|
ivilayer->event_mask &= ~IVI_NOTIFICATION_SOURCE_RECT;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer,
|
|
int32_t x, int32_t y,
|
|
int32_t width, int32_t height)
|
|
{
|
|
struct ivi_layout_layer_properties *prop = NULL;
|
|
|
|
if (ivilayer == NULL) {
|
|
weston_log("ivi_layout_layer_set_destination_rectangle: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop = &ivilayer->pending.prop;
|
|
prop->dest_x = x;
|
|
prop->dest_y = y;
|
|
prop->dest_width = width;
|
|
prop->dest_height = height;
|
|
|
|
if (ivilayer->prop.dest_x != x || ivilayer->prop.dest_y != y ||
|
|
ivilayer->prop.dest_width != width ||
|
|
ivilayer->prop.dest_height != height)
|
|
ivilayer->event_mask |= IVI_NOTIFICATION_DEST_RECT;
|
|
else
|
|
ivilayer->event_mask &= ~IVI_NOTIFICATION_DEST_RECT;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_layer_get_dimension(struct ivi_layout_layer *ivilayer,
|
|
int32_t *dest_width, int32_t *dest_height)
|
|
{
|
|
if (ivilayer == NULL || dest_width == NULL || dest_height == NULL) {
|
|
weston_log("ivi_layout_layer_get_dimension: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
*dest_width = ivilayer->prop.dest_width;
|
|
*dest_height = ivilayer->prop.dest_height;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_layer_set_dimension(struct ivi_layout_layer *ivilayer,
|
|
int32_t dest_width, int32_t dest_height)
|
|
{
|
|
struct ivi_layout_layer_properties *prop = NULL;
|
|
|
|
if (ivilayer == NULL) {
|
|
weston_log("ivi_layout_layer_set_dimension: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop = &ivilayer->pending.prop;
|
|
|
|
prop->dest_width = dest_width;
|
|
prop->dest_height = dest_height;
|
|
|
|
if (ivilayer->prop.dest_width != dest_width ||
|
|
ivilayer->prop.dest_height != dest_height)
|
|
ivilayer->event_mask |= IVI_NOTIFICATION_DIMENSION;
|
|
else
|
|
ivilayer->event_mask &= ~IVI_NOTIFICATION_DIMENSION;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
int32_t
|
|
ivi_layout_layer_get_position(struct ivi_layout_layer *ivilayer,
|
|
int32_t *dest_x, int32_t *dest_y)
|
|
{
|
|
if (ivilayer == NULL || dest_x == NULL || dest_y == NULL) {
|
|
weston_log("ivi_layout_layer_get_position: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
*dest_x = ivilayer->prop.dest_x;
|
|
*dest_y = ivilayer->prop.dest_y;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
int32_t
|
|
ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer,
|
|
int32_t dest_x, int32_t dest_y)
|
|
{
|
|
struct ivi_layout_layer_properties *prop = NULL;
|
|
|
|
if (ivilayer == NULL) {
|
|
weston_log("ivi_layout_layer_set_position: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop = &ivilayer->pending.prop;
|
|
prop->dest_x = dest_x;
|
|
prop->dest_y = dest_y;
|
|
|
|
if (ivilayer->prop.dest_x != dest_x || ivilayer->prop.dest_y != dest_y)
|
|
ivilayer->event_mask |= IVI_NOTIFICATION_POSITION;
|
|
else
|
|
ivilayer->event_mask &= ~IVI_NOTIFICATION_POSITION;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_layer_set_orientation(struct ivi_layout_layer *ivilayer,
|
|
enum wl_output_transform orientation)
|
|
{
|
|
struct ivi_layout_layer_properties *prop = NULL;
|
|
|
|
if (ivilayer == NULL) {
|
|
weston_log("ivi_layout_layer_set_orientation: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop = &ivilayer->pending.prop;
|
|
prop->orientation = orientation;
|
|
|
|
if (ivilayer->prop.orientation != orientation)
|
|
ivilayer->event_mask |= IVI_NOTIFICATION_ORIENTATION;
|
|
else
|
|
ivilayer->event_mask &= ~IVI_NOTIFICATION_ORIENTATION;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static enum wl_output_transform
|
|
ivi_layout_layer_get_orientation(struct ivi_layout_layer *ivilayer)
|
|
{
|
|
if (ivilayer == NULL) {
|
|
weston_log("ivi_layout_layer_get_orientation: invalid argument\n");
|
|
return 0;
|
|
}
|
|
|
|
return ivilayer->prop.orientation;
|
|
}
|
|
|
|
int32_t
|
|
ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
|
|
struct ivi_layout_surface **pSurface,
|
|
int32_t number)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_surface *ivisurf = NULL;
|
|
struct ivi_layout_surface *next = NULL;
|
|
uint32_t *id_surface = NULL;
|
|
int32_t i = 0;
|
|
|
|
if (ivilayer == NULL) {
|
|
weston_log("ivi_layout_layer_set_render_order: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
if (pSurface == NULL) {
|
|
wl_list_for_each_safe(ivisurf, next, &ivilayer->pending.surface_list, pending.link) {
|
|
if (!wl_list_empty(&ivisurf->pending.link)) {
|
|
wl_list_remove(&ivisurf->pending.link);
|
|
}
|
|
|
|
wl_list_init(&ivisurf->pending.link);
|
|
}
|
|
ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
for (i = 0; i < number; i++) {
|
|
id_surface = &pSurface[i]->id_surface;
|
|
|
|
wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
|
|
if (*id_surface != ivisurf->id_surface) {
|
|
continue;
|
|
}
|
|
|
|
if (!wl_list_empty(&ivisurf->pending.link)) {
|
|
wl_list_remove(&ivisurf->pending.link);
|
|
}
|
|
wl_list_init(&ivisurf->pending.link);
|
|
wl_list_insert(&ivilayer->pending.surface_list,
|
|
&ivisurf->pending.link);
|
|
break;
|
|
}
|
|
}
|
|
|
|
ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
int32_t
|
|
ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf,
|
|
bool newVisibility)
|
|
{
|
|
struct ivi_layout_surface_properties *prop = NULL;
|
|
|
|
if (ivisurf == NULL) {
|
|
weston_log("ivi_layout_surface_set_visibility: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop = &ivisurf->pending.prop;
|
|
prop->visibility = newVisibility;
|
|
|
|
if (ivisurf->prop.visibility != newVisibility)
|
|
ivisurf->event_mask |= IVI_NOTIFICATION_VISIBILITY;
|
|
else
|
|
ivisurf->event_mask &= ~IVI_NOTIFICATION_VISIBILITY;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
bool
|
|
ivi_layout_surface_get_visibility(struct ivi_layout_surface *ivisurf)
|
|
{
|
|
if (ivisurf == NULL) {
|
|
weston_log("ivi_layout_surface_get_visibility: invalid argument\n");
|
|
return false;
|
|
}
|
|
|
|
return ivisurf->prop.visibility;
|
|
}
|
|
|
|
int32_t
|
|
ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
|
|
wl_fixed_t opacity)
|
|
{
|
|
struct ivi_layout_surface_properties *prop = NULL;
|
|
|
|
if (ivisurf == NULL ||
|
|
opacity < wl_fixed_from_double(0.0) ||
|
|
wl_fixed_from_double(1.0) < opacity) {
|
|
weston_log("ivi_layout_surface_set_opacity: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop = &ivisurf->pending.prop;
|
|
prop->opacity = opacity;
|
|
|
|
if (ivisurf->prop.opacity != opacity)
|
|
ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY;
|
|
else
|
|
ivisurf->event_mask &= ~IVI_NOTIFICATION_OPACITY;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
wl_fixed_t
|
|
ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf)
|
|
{
|
|
if (ivisurf == NULL) {
|
|
weston_log("ivi_layout_surface_get_opacity: invalid argument\n");
|
|
return wl_fixed_from_double(0.0);
|
|
}
|
|
|
|
return ivisurf->prop.opacity;
|
|
}
|
|
|
|
int32_t
|
|
ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
|
|
int32_t x, int32_t y,
|
|
int32_t width, int32_t height)
|
|
{
|
|
struct ivi_layout_surface_properties *prop = NULL;
|
|
|
|
if (ivisurf == NULL) {
|
|
weston_log("ivi_layout_surface_set_destination_rectangle: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop = &ivisurf->pending.prop;
|
|
prop->start_x = prop->dest_x;
|
|
prop->start_y = prop->dest_y;
|
|
prop->dest_x = x;
|
|
prop->dest_y = y;
|
|
prop->start_width = prop->dest_width;
|
|
prop->start_height = prop->dest_height;
|
|
prop->dest_width = width;
|
|
prop->dest_height = height;
|
|
|
|
if (ivisurf->prop.dest_x != x || ivisurf->prop.dest_y != y ||
|
|
ivisurf->prop.dest_width != width ||
|
|
ivisurf->prop.dest_height != height)
|
|
ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT;
|
|
else
|
|
ivisurf->event_mask &= ~IVI_NOTIFICATION_DEST_RECT;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_surface_set_dimension(struct ivi_layout_surface *ivisurf,
|
|
int32_t dest_width, int32_t dest_height)
|
|
{
|
|
struct ivi_layout_surface_properties *prop = NULL;
|
|
|
|
if (ivisurf == NULL) {
|
|
weston_log("ivi_layout_surface_set_dimension: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop = &ivisurf->pending.prop;
|
|
prop->dest_width = dest_width;
|
|
prop->dest_height = dest_height;
|
|
|
|
if (ivisurf->prop.dest_width != dest_width ||
|
|
ivisurf->prop.dest_height != dest_height)
|
|
ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION;
|
|
else
|
|
ivisurf->event_mask &= ~IVI_NOTIFICATION_DIMENSION;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
int32_t
|
|
ivi_layout_surface_get_dimension(struct ivi_layout_surface *ivisurf,
|
|
int32_t *dest_width, int32_t *dest_height)
|
|
{
|
|
if (ivisurf == NULL || dest_width == NULL || dest_height == NULL) {
|
|
weston_log("ivi_layout_surface_get_dimension: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
*dest_width = ivisurf->prop.dest_width;
|
|
*dest_height = ivisurf->prop.dest_height;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_surface_set_position(struct ivi_layout_surface *ivisurf,
|
|
int32_t dest_x, int32_t dest_y)
|
|
{
|
|
struct ivi_layout_surface_properties *prop = NULL;
|
|
|
|
if (ivisurf == NULL) {
|
|
weston_log("ivi_layout_surface_set_position: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop = &ivisurf->pending.prop;
|
|
prop->dest_x = dest_x;
|
|
prop->dest_y = dest_y;
|
|
|
|
if (ivisurf->prop.dest_x != dest_x || ivisurf->prop.dest_y != dest_y)
|
|
ivisurf->event_mask |= IVI_NOTIFICATION_POSITION;
|
|
else
|
|
ivisurf->event_mask &= ~IVI_NOTIFICATION_POSITION;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_surface_get_position(struct ivi_layout_surface *ivisurf,
|
|
int32_t *dest_x, int32_t *dest_y)
|
|
{
|
|
if (ivisurf == NULL || dest_x == NULL || dest_y == NULL) {
|
|
weston_log("ivi_layout_surface_get_position: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
*dest_x = ivisurf->prop.dest_x;
|
|
*dest_y = ivisurf->prop.dest_y;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf,
|
|
enum wl_output_transform orientation)
|
|
{
|
|
struct ivi_layout_surface_properties *prop = NULL;
|
|
|
|
if (ivisurf == NULL) {
|
|
weston_log("ivi_layout_surface_set_orientation: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop = &ivisurf->pending.prop;
|
|
prop->orientation = orientation;
|
|
|
|
if (ivisurf->prop.orientation != orientation)
|
|
ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION;
|
|
else
|
|
ivisurf->event_mask &= ~IVI_NOTIFICATION_ORIENTATION;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static enum wl_output_transform
|
|
ivi_layout_surface_get_orientation(struct ivi_layout_surface *ivisurf)
|
|
{
|
|
if (ivisurf == NULL) {
|
|
weston_log("ivi_layout_surface_get_orientation: invalid argument\n");
|
|
return 0;
|
|
}
|
|
|
|
return ivisurf->prop.orientation;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn,
|
|
struct ivi_layout_layer *addlayer)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_layer *ivilayer = NULL;
|
|
struct ivi_layout_layer *next = NULL;
|
|
int is_layer_in_scrn = 0;
|
|
|
|
if (iviscrn == NULL || addlayer == NULL) {
|
|
weston_log("ivi_layout_screen_add_layer: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
is_layer_in_scrn = is_layer_in_screen(addlayer, iviscrn);
|
|
if (is_layer_in_scrn == 1) {
|
|
weston_log("ivi_layout_screen_add_layer: addlayer is already available\n");
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
wl_list_for_each_safe(ivilayer, next, &layout->layer_list, link) {
|
|
if (ivilayer->id_layer == addlayer->id_layer) {
|
|
if (!wl_list_empty(&ivilayer->pending.link)) {
|
|
wl_list_remove(&ivilayer->pending.link);
|
|
}
|
|
wl_list_init(&ivilayer->pending.link);
|
|
wl_list_insert(&iviscrn->pending.layer_list,
|
|
&ivilayer->pending.link);
|
|
break;
|
|
}
|
|
}
|
|
|
|
iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn,
|
|
struct ivi_layout_layer **pLayer,
|
|
const int32_t number)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_layer *ivilayer = NULL;
|
|
struct ivi_layout_layer *next = NULL;
|
|
uint32_t *id_layer = NULL;
|
|
int32_t i = 0;
|
|
|
|
if (iviscrn == NULL) {
|
|
weston_log("ivi_layout_screen_set_render_order: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
wl_list_for_each_safe(ivilayer, next,
|
|
&iviscrn->pending.layer_list, pending.link) {
|
|
wl_list_init(&ivilayer->pending.link);
|
|
}
|
|
|
|
wl_list_init(&iviscrn->pending.layer_list);
|
|
|
|
if (pLayer == NULL) {
|
|
wl_list_for_each_safe(ivilayer, next, &iviscrn->pending.layer_list, pending.link) {
|
|
if (!wl_list_empty(&ivilayer->pending.link)) {
|
|
wl_list_remove(&ivilayer->pending.link);
|
|
}
|
|
|
|
wl_list_init(&ivilayer->pending.link);
|
|
}
|
|
|
|
iviscrn->event_mask |= IVI_NOTIFICATION_REMOVE;
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
for (i = 0; i < number; i++) {
|
|
id_layer = &pLayer[i]->id_layer;
|
|
wl_list_for_each(ivilayer, &layout->layer_list, link) {
|
|
if (*id_layer != ivilayer->id_layer) {
|
|
continue;
|
|
}
|
|
|
|
if (!wl_list_empty(&ivilayer->pending.link)) {
|
|
wl_list_remove(&ivilayer->pending.link);
|
|
}
|
|
wl_list_init(&ivilayer->pending.link);
|
|
wl_list_insert(&iviscrn->pending.layer_list,
|
|
&ivilayer->pending.link);
|
|
break;
|
|
}
|
|
}
|
|
|
|
iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static struct weston_output *
|
|
ivi_layout_screen_get_output(struct ivi_layout_screen *iviscrn)
|
|
{
|
|
return iviscrn->output;
|
|
}
|
|
|
|
/**
|
|
* This function is used by the additional ivi-module because of dumping ivi_surface sceenshot.
|
|
* The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of Genivi's Layer Management.
|
|
* This function is used to get the result of drawing by clients.
|
|
*/
|
|
static struct weston_surface *
|
|
ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf)
|
|
{
|
|
return ivisurf != NULL ? ivisurf->surface : NULL;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_surface_get_size(struct ivi_layout_surface *ivisurf,
|
|
int32_t *width, int32_t *height,
|
|
int32_t *stride)
|
|
{
|
|
int32_t w;
|
|
int32_t h;
|
|
const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
|
|
|
|
if (ivisurf == NULL || ivisurf->surface == NULL) {
|
|
weston_log("%s: invalid argument\n", __func__);
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
weston_surface_get_content_size(ivisurf->surface, &w, &h);
|
|
|
|
if (width != NULL)
|
|
*width = w;
|
|
|
|
if (height != NULL)
|
|
*height = h;
|
|
|
|
if (stride != NULL)
|
|
*stride = w * bytespp;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_layer_add_notification(struct ivi_layout_layer *ivilayer,
|
|
layer_property_notification_func callback,
|
|
void *userdata)
|
|
{
|
|
struct ivi_layout_notification_callback *prop_callback = NULL;
|
|
|
|
if (ivilayer == NULL || callback == NULL) {
|
|
weston_log("ivi_layout_layer_add_notification: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop_callback = malloc(sizeof *prop_callback);
|
|
if (prop_callback == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop_callback->callback = callback;
|
|
prop_callback->data = userdata;
|
|
|
|
return add_notification(&ivilayer->property_changed,
|
|
layer_prop_changed,
|
|
prop_callback);
|
|
}
|
|
|
|
static const struct ivi_layout_surface_properties *
|
|
ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf)
|
|
{
|
|
if (ivisurf == NULL) {
|
|
weston_log("ivi_layout_get_properties_of_surface: invalid argument\n");
|
|
return NULL;
|
|
}
|
|
|
|
return &ivisurf->prop;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer,
|
|
struct ivi_layout_surface *addsurf)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_surface *ivisurf = NULL;
|
|
struct ivi_layout_surface *next = NULL;
|
|
int is_surf_in_layer = 0;
|
|
|
|
if (ivilayer == NULL || addsurf == NULL) {
|
|
weston_log("ivi_layout_layer_add_surface: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
is_surf_in_layer = is_surface_in_layer(addsurf, ivilayer);
|
|
if (is_surf_in_layer == 1) {
|
|
weston_log("ivi_layout_layer_add_surface: addsurf is already available\n");
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
|
|
if (ivisurf->id_surface == addsurf->id_surface) {
|
|
if (!wl_list_empty(&ivisurf->pending.link)) {
|
|
wl_list_remove(&ivisurf->pending.link);
|
|
}
|
|
wl_list_init(&ivisurf->pending.link);
|
|
wl_list_insert(&ivilayer->pending.surface_list,
|
|
&ivisurf->pending.link);
|
|
break;
|
|
}
|
|
}
|
|
|
|
ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static void
|
|
ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer,
|
|
struct ivi_layout_surface *remsurf)
|
|
{
|
|
struct ivi_layout_surface *ivisurf = NULL;
|
|
struct ivi_layout_surface *next = NULL;
|
|
|
|
if (ivilayer == NULL || remsurf == NULL) {
|
|
weston_log("ivi_layout_layer_remove_surface: invalid argument\n");
|
|
return;
|
|
}
|
|
|
|
wl_list_for_each_safe(ivisurf, next,
|
|
&ivilayer->pending.surface_list, pending.link) {
|
|
if (ivisurf->id_surface == remsurf->id_surface) {
|
|
if (!wl_list_empty(&ivisurf->pending.link)) {
|
|
wl_list_remove(&ivisurf->pending.link);
|
|
}
|
|
wl_list_init(&ivisurf->pending.link);
|
|
break;
|
|
}
|
|
}
|
|
|
|
remsurf->event_mask |= IVI_NOTIFICATION_REMOVE;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf,
|
|
int32_t x, int32_t y,
|
|
int32_t width, int32_t height)
|
|
{
|
|
struct ivi_layout_surface_properties *prop = NULL;
|
|
|
|
if (ivisurf == NULL) {
|
|
weston_log("ivi_layout_surface_set_source_rectangle: invalid argument\n");
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
prop = &ivisurf->pending.prop;
|
|
prop->source_x = x;
|
|
prop->source_y = y;
|
|
prop->source_width = width;
|
|
prop->source_height = height;
|
|
|
|
if (ivisurf->prop.source_x != x || ivisurf->prop.source_y != y ||
|
|
ivisurf->prop.source_width != width ||
|
|
ivisurf->prop.source_height != height)
|
|
ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
|
|
else
|
|
ivisurf->event_mask &= ~IVI_NOTIFICATION_SOURCE_RECT;
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
int32_t
|
|
ivi_layout_commit_changes(void)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
|
|
commit_surface_list(layout);
|
|
commit_layer_list(layout);
|
|
commit_screen_list(layout);
|
|
|
|
commit_transition(layout);
|
|
|
|
commit_changes(layout);
|
|
send_prop(layout);
|
|
weston_compositor_schedule_repaint(layout->compositor);
|
|
|
|
return IVI_SUCCEEDED;
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static 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;
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_surface_dump(struct weston_surface *surface,
|
|
void *target, size_t size,int32_t x, int32_t y,
|
|
int32_t width, int32_t height)
|
|
{
|
|
int result = 0;
|
|
|
|
if (surface == NULL) {
|
|
weston_log("%s: invalid argument\n", __func__);
|
|
return IVI_FAILED;
|
|
}
|
|
|
|
result = weston_surface_copy_content(
|
|
surface, target, size,
|
|
x, y, width, height);
|
|
|
|
return result == 0 ? IVI_SUCCEEDED : IVI_FAILED;
|
|
}
|
|
|
|
/**
|
|
* methods of interaction between ivi-shell with ivi-layout
|
|
*/
|
|
struct weston_view *
|
|
ivi_layout_get_weston_view(struct ivi_layout_surface *surface)
|
|
{
|
|
struct weston_view *tmpview = NULL;
|
|
|
|
if(surface == NULL)
|
|
return NULL;
|
|
|
|
wl_list_for_each(tmpview, &surface->surface->views, surface_link)
|
|
{
|
|
if (tmpview != NULL) {
|
|
break;
|
|
}
|
|
}
|
|
return tmpview;
|
|
}
|
|
|
|
void
|
|
ivi_layout_surface_configure(struct ivi_layout_surface *ivisurf,
|
|
int32_t width, int32_t height)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
|
|
/* emit callback which is set by ivi-layout api user */
|
|
wl_signal_emit(&layout->surface_notification.configure_changed,
|
|
ivisurf);
|
|
}
|
|
|
|
static int32_t
|
|
ivi_layout_surface_set_content_observer(struct ivi_layout_surface *ivisurf,
|
|
ivi_controller_surface_content_callback callback,
|
|
void* userdata)
|
|
{
|
|
int32_t ret = IVI_FAILED;
|
|
|
|
if (ivisurf != NULL) {
|
|
ivisurf->content_observer.callback = callback;
|
|
ivisurf->content_observer.userdata = userdata;
|
|
ret = IVI_SUCCEEDED;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
struct ivi_layout_surface*
|
|
ivi_layout_surface_create(struct weston_surface *wl_surface,
|
|
uint32_t id_surface)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
struct ivi_layout_surface *ivisurf = NULL;
|
|
struct weston_view *tmpview = NULL;
|
|
|
|
if (wl_surface == NULL) {
|
|
weston_log("ivi_layout_surface_create: invalid argument\n");
|
|
return NULL;
|
|
}
|
|
|
|
ivisurf = get_surface(&layout->surface_list, id_surface);
|
|
if (ivisurf != NULL) {
|
|
if (ivisurf->surface != NULL) {
|
|
weston_log("id_surface(%d) is already created\n", id_surface);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
ivisurf = calloc(1, sizeof *ivisurf);
|
|
if (ivisurf == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
return NULL;
|
|
}
|
|
|
|
wl_list_init(&ivisurf->link);
|
|
wl_signal_init(&ivisurf->property_changed);
|
|
wl_signal_init(&ivisurf->configured);
|
|
wl_list_init(&ivisurf->layer_list);
|
|
ivisurf->id_surface = id_surface;
|
|
ivisurf->layout = layout;
|
|
|
|
ivisurf->surface = wl_surface;
|
|
|
|
tmpview = weston_view_create(wl_surface);
|
|
if (tmpview == NULL) {
|
|
weston_log("fails to allocate memory\n");
|
|
}
|
|
|
|
ivisurf->surface->width_from_buffer = 0;
|
|
ivisurf->surface->height_from_buffer = 0;
|
|
|
|
weston_matrix_init(&ivisurf->surface_rotation.matrix);
|
|
weston_matrix_init(&ivisurf->layer_rotation.matrix);
|
|
weston_matrix_init(&ivisurf->surface_pos.matrix);
|
|
weston_matrix_init(&ivisurf->layer_pos.matrix);
|
|
weston_matrix_init(&ivisurf->scaling.matrix);
|
|
|
|
wl_list_init(&ivisurf->surface_rotation.link);
|
|
wl_list_init(&ivisurf->layer_rotation.link);
|
|
wl_list_init(&ivisurf->surface_pos.link);
|
|
wl_list_init(&ivisurf->layer_pos.link);
|
|
wl_list_init(&ivisurf->scaling.link);
|
|
|
|
init_surface_properties(&ivisurf->prop);
|
|
ivisurf->event_mask = 0;
|
|
|
|
ivisurf->pending.prop = ivisurf->prop;
|
|
wl_list_init(&ivisurf->pending.link);
|
|
|
|
wl_list_init(&ivisurf->order.link);
|
|
wl_list_init(&ivisurf->order.layer_list);
|
|
|
|
wl_list_insert(&layout->surface_list, &ivisurf->link);
|
|
|
|
wl_signal_emit(&layout->surface_notification.created, ivisurf);
|
|
|
|
return ivisurf;
|
|
}
|
|
|
|
void
|
|
ivi_layout_init_with_compositor(struct weston_compositor *ec)
|
|
{
|
|
struct ivi_layout *layout = get_instance();
|
|
|
|
layout->compositor = ec;
|
|
|
|
wl_list_init(&layout->surface_list);
|
|
wl_list_init(&layout->layer_list);
|
|
wl_list_init(&layout->screen_list);
|
|
|
|
wl_signal_init(&layout->layer_notification.created);
|
|
wl_signal_init(&layout->layer_notification.removed);
|
|
|
|
wl_signal_init(&layout->surface_notification.created);
|
|
wl_signal_init(&layout->surface_notification.removed);
|
|
wl_signal_init(&layout->surface_notification.configure_changed);
|
|
|
|
/* Add layout_layer at the last of weston_compositor.layer_list */
|
|
weston_layer_init(&layout->layout_layer, ec->layer_list.prev);
|
|
|
|
create_screen(ec);
|
|
|
|
layout->transitions = ivi_layout_transition_set_create(ec);
|
|
wl_list_init(&layout->pending_transition_list);
|
|
}
|
|
|
|
|
|
void
|
|
ivi_layout_surface_add_configured_listener(struct ivi_layout_surface* ivisurf,
|
|
struct wl_listener* listener)
|
|
{
|
|
wl_signal_add(&ivisurf->configured, listener);
|
|
}
|
|
|
|
static struct ivi_controller_interface ivi_controller_interface = {
|
|
/**
|
|
* commit all changes
|
|
*/
|
|
.commit_changes = ivi_layout_commit_changes,
|
|
|
|
/**
|
|
* surface controller interfaces
|
|
*/
|
|
.add_notification_create_surface = ivi_layout_add_notification_create_surface,
|
|
.remove_notification_create_surface = ivi_layout_remove_notification_create_surface,
|
|
.add_notification_remove_surface = ivi_layout_add_notification_remove_surface,
|
|
.remove_notification_remove_surface = ivi_layout_remove_notification_remove_surface,
|
|
.add_notification_configure_surface = ivi_layout_add_notification_configure_surface,
|
|
.remove_notification_configure_surface = ivi_layout_remove_notification_configure_surface,
|
|
.get_surfaces = ivi_layout_get_surfaces,
|
|
.get_id_of_surface = ivi_layout_get_id_of_surface,
|
|
.get_surface_from_id = ivi_layout_get_surface_from_id,
|
|
.get_properties_of_surface = ivi_layout_get_properties_of_surface,
|
|
.get_surfaces_on_layer = ivi_layout_get_surfaces_on_layer,
|
|
.surface_set_visibility = ivi_layout_surface_set_visibility,
|
|
.surface_get_visibility = ivi_layout_surface_get_visibility,
|
|
.surface_set_opacity = ivi_layout_surface_set_opacity,
|
|
.surface_get_opacity = ivi_layout_surface_get_opacity,
|
|
.surface_set_source_rectangle = ivi_layout_surface_set_source_rectangle,
|
|
.surface_set_destination_rectangle = ivi_layout_surface_set_destination_rectangle,
|
|
.surface_set_position = ivi_layout_surface_set_position,
|
|
.surface_get_position = ivi_layout_surface_get_position,
|
|
.surface_set_dimension = ivi_layout_surface_set_dimension,
|
|
.surface_get_dimension = ivi_layout_surface_get_dimension,
|
|
.surface_set_orientation = ivi_layout_surface_set_orientation,
|
|
.surface_get_orientation = ivi_layout_surface_get_orientation,
|
|
.surface_set_content_observer = ivi_layout_surface_set_content_observer,
|
|
.surface_add_notification = ivi_layout_surface_add_notification,
|
|
.surface_remove_notification = ivi_layout_surface_remove_notification,
|
|
.surface_get_weston_surface = ivi_layout_surface_get_weston_surface,
|
|
.surface_set_transition = ivi_layout_surface_set_transition,
|
|
.surface_set_transition_duration = ivi_layout_surface_set_transition_duration,
|
|
|
|
/**
|
|
* layer controller interfaces
|
|
*/
|
|
.add_notification_create_layer = ivi_layout_add_notification_create_layer,
|
|
.remove_notification_create_layer = ivi_layout_remove_notification_create_layer,
|
|
.add_notification_remove_layer = ivi_layout_add_notification_remove_layer,
|
|
.remove_notification_remove_layer = ivi_layout_remove_notification_remove_layer,
|
|
.layer_create_with_dimension = ivi_layout_layer_create_with_dimension,
|
|
.layer_destroy = ivi_layout_layer_destroy,
|
|
.get_layers = ivi_layout_get_layers,
|
|
.get_id_of_layer = ivi_layout_get_id_of_layer,
|
|
.get_layer_from_id = ivi_layout_get_layer_from_id,
|
|
.get_properties_of_layer = ivi_layout_get_properties_of_layer,
|
|
.get_layers_under_surface = ivi_layout_get_layers_under_surface,
|
|
.get_layers_on_screen = ivi_layout_get_layers_on_screen,
|
|
.layer_set_visibility = ivi_layout_layer_set_visibility,
|
|
.layer_get_visibility = ivi_layout_layer_get_visibility,
|
|
.layer_set_opacity = ivi_layout_layer_set_opacity,
|
|
.layer_get_opacity = ivi_layout_layer_get_opacity,
|
|
.layer_set_source_rectangle = ivi_layout_layer_set_source_rectangle,
|
|
.layer_set_destination_rectangle = ivi_layout_layer_set_destination_rectangle,
|
|
.layer_set_position = ivi_layout_layer_set_position,
|
|
.layer_get_position = ivi_layout_layer_get_position,
|
|
.layer_set_dimension = ivi_layout_layer_set_dimension,
|
|
.layer_get_dimension = ivi_layout_layer_get_dimension,
|
|
.layer_set_orientation = ivi_layout_layer_set_orientation,
|
|
.layer_get_orientation = ivi_layout_layer_get_orientation,
|
|
.layer_add_surface = ivi_layout_layer_add_surface,
|
|
.layer_remove_surface = ivi_layout_layer_remove_surface,
|
|
.layer_set_render_order = ivi_layout_layer_set_render_order,
|
|
.layer_add_notification = ivi_layout_layer_add_notification,
|
|
.layer_remove_notification = ivi_layout_layer_remove_notification,
|
|
.layer_set_transition = ivi_layout_layer_set_transition,
|
|
|
|
/**
|
|
* screen controller interfaces part1
|
|
*/
|
|
.get_screen_from_id = ivi_layout_get_screen_from_id,
|
|
.get_screen_resolution = ivi_layout_get_screen_resolution,
|
|
.get_screens = ivi_layout_get_screens,
|
|
.get_screens_under_layer = ivi_layout_get_screens_under_layer,
|
|
.screen_add_layer = ivi_layout_screen_add_layer,
|
|
.screen_set_render_order = ivi_layout_screen_set_render_order,
|
|
.screen_get_output = ivi_layout_screen_get_output,
|
|
|
|
/**
|
|
* animation
|
|
*/
|
|
.transition_move_layer_cancel = ivi_layout_transition_move_layer_cancel,
|
|
.layer_set_fade_info = ivi_layout_layer_set_fade_info,
|
|
|
|
/**
|
|
* surface content dumping for debugging
|
|
*/
|
|
.surface_get_size = ivi_layout_surface_get_size,
|
|
.surface_dump = ivi_layout_surface_dump,
|
|
|
|
/**
|
|
* remove notification by callback on property changes of ivi_surface/layer
|
|
*/
|
|
.surface_remove_notification_by_callback = ivi_layout_surface_remove_notification_by_callback,
|
|
.layer_remove_notification_by_callback = ivi_layout_layer_remove_notification_by_callback,
|
|
|
|
/**
|
|
* screen controller interfaces part2
|
|
*/
|
|
.get_id_of_screen = ivi_layout_get_id_of_screen
|
|
};
|
|
|
|
int
|
|
load_controller_modules(struct weston_compositor *compositor, const char *modules,
|
|
int *argc, char *argv[])
|
|
{
|
|
const char *p, *end;
|
|
char buffer[256];
|
|
int (*controller_module_init)(struct weston_compositor *compositor,
|
|
int *argc, char *argv[],
|
|
const struct ivi_controller_interface *interface,
|
|
size_t interface_version);
|
|
|
|
if (modules == NULL)
|
|
return 0;
|
|
|
|
p = modules;
|
|
while (*p) {
|
|
end = strchrnul(p, ',');
|
|
snprintf(buffer, sizeof buffer, "%.*s", (int)(end - p), p);
|
|
|
|
controller_module_init = weston_load_module(buffer, "controller_module_init");
|
|
if (!controller_module_init)
|
|
return -1;
|
|
|
|
if (controller_module_init(compositor, argc, argv,
|
|
&ivi_controller_interface,
|
|
sizeof(struct ivi_controller_interface)) != 0) {
|
|
weston_log("ivi-shell: Initialization of controller module fails");
|
|
return -1;
|
|
}
|
|
|
|
p = end;
|
|
while (*p == ',')
|
|
p++;
|
|
}
|
|
|
|
return 0;
|
|
}
|