• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 DENSO CORPORATION
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial
14  * portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  */
25 
26 /**
27  * Implementation of ivi-layout library. The actual view on ivi_screen is
28  * not updated until ivi_layout_commit_changes is called. An overview from
29  * calling API for updating properties of ivi_surface/ivi_layer to asking
30  * compositor to compose them by using weston_view_schedule_repaint,
31  * 0/ initialize this library by ivi_layout_init_with_compositor
32  *    with (struct weston_compositor *ec) from ivi-shell.
33  * 1/ When an API for updating properties of ivi_surface/ivi_layer, it updates
34  *    pending prop of ivi_surface/ivi_layer/ivi_screen which are structure to
35  *    store properties.
36  * 2/ Before calling commitChanges, in case of calling an API to get a property,
37  *    return current property, not pending property.
38  * 3/ At the timing of calling ivi_layout_commitChanges, pending properties
39  *    are applied to properties.
40  *
41  *    *) ivi_layout_commitChanges is also called by transition animation
42  *    per each frame. See ivi-layout-transition.c in details. Transition
43  *    animation interpolates frames between previous properties of ivi_surface
44  *    and new ones.
45  *    For example, when a property of ivi_surface is changed from invisible
46  *    to visible, it behaves like fade-in. When ivi_layout_commitChange is
47  *    called during transition animation, it cancels the transition and
48  *    re-start transition to new properties from current properties of final
49  *    frame just before the cancellation.
50  *
51  * 4/ According properties, set transformation by using weston_matrix and
52  *    weston_view per ivi_surfaces and ivi_layers in while loop.
53  * 5/ Set damage and trigger transform by using weston_view_geometry_dirty.
54  * 6/ Schedule repaint for each view by using weston_view_schedule_repaint.
55  * 7/ Notify update of properties.
56  *
57  */
58 #include "config.h"
59 
60 #include <string.h>
61 #include <assert.h>
62 #include <stdint.h>
63 
64 #include "compositor/weston.h"
65 #include <libweston/libweston.h>
66 #include "ivi-shell.h"
67 #include "ivi-layout-export.h"
68 #include "ivi-layout-private.h"
69 #include "ivi-layout-shell.h"
70 
71 #include "shared/helpers.h"
72 #include "shared/os-compatibility.h"
73 
74 #define max(a, b) ((a) > (b) ? (a) : (b))
75 #define VIRTUAL_OUTPUT_NAME "virtual_output"
76 
77 #include "libweston/trace.h"
78 DEFINE_LOG_LABEL("IVILayout");
79 
80 struct ivi_layout;
81 
82 struct ivi_layout_screen {
83 	struct wl_list link;	/* ivi_layout::screen_list */
84 
85 	struct ivi_layout *layout;
86 	struct weston_output *output;
87 
88 	struct {
89 		struct wl_list layer_list;	/* ivi_layout_layer::pending.link */
90 	} pending;
91 
92 	struct {
93 		int dirty;
94 		struct wl_list layer_list;	/* ivi_layout_layer::order.link */
95 	} order;
96 };
97 
98 struct ivi_rectangle
99 {
100 	int32_t x;
101 	int32_t y;
102 	int32_t width;
103 	int32_t height;
104 };
105 
106 static struct ivi_layout ivilayout = {0};
107 
108 struct ivi_layout *
get_instance(void)109 get_instance(void)
110 {
111 	return &ivilayout;
112 }
113 
114 
115 /**
116  * Internal API to add/remove an ivi_layer to/from ivi_screen.
117  */
118 static struct ivi_layout_surface *
get_surface(struct wl_list * surf_list,uint32_t id_surface)119 get_surface(struct wl_list *surf_list, uint32_t id_surface)
120 {
121 	struct ivi_layout_surface *ivisurf;
122 
123 	wl_list_for_each(ivisurf, surf_list, link) {
124 		if (ivisurf->id_surface == id_surface) {
125 			return ivisurf;
126 		}
127 	}
128 
129 	return NULL;
130 }
131 
132 static struct ivi_layout_layer *
get_layer(struct wl_list * layer_list,uint32_t id_layer)133 get_layer(struct wl_list *layer_list, uint32_t id_layer)
134 {
135 	struct ivi_layout_layer *ivilayer;
136 
137 	wl_list_for_each(ivilayer, layer_list, link) {
138 		if (ivilayer->id_layer == id_layer) {
139 			return ivilayer;
140 		}
141 	}
142 
143 	return NULL;
144 }
145 
146 static bool
ivi_view_is_rendered(struct ivi_layout_view * view)147 ivi_view_is_rendered(struct ivi_layout_view *view)
148 {
149 	return !wl_list_empty(&view->order_link);
150 }
151 
152 static void
ivi_view_destroy(struct ivi_layout_view * ivi_view)153 ivi_view_destroy(struct ivi_layout_view *ivi_view)
154 {
155 	wl_list_remove(&ivi_view->transform.link);
156 	wl_list_remove(&ivi_view->link);
157 	wl_list_remove(&ivi_view->surf_link);
158 	wl_list_remove(&ivi_view->pending_link);
159 	wl_list_remove(&ivi_view->order_link);
160 
161 	if (weston_surface_is_desktop_surface(ivi_view->ivisurf->surface))
162 		weston_desktop_surface_unlink_view(ivi_view->view);
163 	weston_view_destroy(ivi_view->view);
164 
165 	free(ivi_view);
166 }
167 
168 static struct ivi_layout_view*
ivi_view_create(struct ivi_layout_layer * ivilayer,struct ivi_layout_surface * ivisurf)169 ivi_view_create(struct ivi_layout_layer *ivilayer,
170 		struct ivi_layout_surface *ivisurf)
171 {
172 	struct ivi_layout_view *ivi_view;
173 
174 	ivi_view = calloc(1, sizeof *ivi_view);
175 	if (ivi_view == NULL) {
176 		weston_log("fails to allocate memory\n");
177 		return NULL;
178 	}
179 
180 	if (weston_surface_is_desktop_surface(ivisurf->surface)) {
181 		ivi_view->view = weston_desktop_surface_create_view(
182 				ivisurf->weston_desktop_surface);
183 	} else {
184 		ivi_view->view = weston_view_create(ivisurf->surface);
185 	}
186 
187 	if (ivi_view->view == NULL) {
188 		weston_log("fails to allocate memory\n");
189 		free(ivi_view);
190 		return NULL;
191 	}
192 
193 	weston_matrix_init(&ivi_view->transform.matrix);
194 	wl_list_init(&ivi_view->transform.link);
195 
196 	ivi_view->ivisurf = ivisurf;
197 	ivi_view->on_layer = ivilayer;
198 	wl_list_insert(&ivilayer->layout->view_list,
199 		       &ivi_view->link);
200 	wl_list_insert(&ivisurf->view_list,
201 		       &ivi_view->surf_link);
202 
203 	wl_list_init(&ivi_view->pending_link);
204 	wl_list_init(&ivi_view->order_link);
205 
206 	return ivi_view;
207 }
208 
209 static struct ivi_layout_view *
get_ivi_view(struct ivi_layout_layer * ivilayer,struct ivi_layout_surface * ivisurf)210 get_ivi_view(struct ivi_layout_layer *ivilayer,
211 		struct ivi_layout_surface *ivisurf)
212 {
213 	struct ivi_layout_view *ivi_view;
214 
215 	assert(ivisurf->surface != NULL);
216 
217 	wl_list_for_each(ivi_view, &ivisurf->view_list, surf_link) {
218 		if (ivi_view->on_layer == ivilayer)
219 			return ivi_view;
220 	}
221 
222 	return NULL;
223 }
224 
225 static struct ivi_layout_screen *
get_screen_from_id(const uint32_t screen_id)226 get_screen_from_id(const uint32_t screen_id)
227 {
228 	struct ivi_layout *layout = get_instance();
229 	struct ivi_layout_screen *iviscrn = NULL;
230 
231 	wl_list_for_each(iviscrn, &layout->screen_list, link) {
232 		if (iviscrn->output->id == screen_id)
233 			return iviscrn;
234 	}
235 
236 	return NULL;
237 }
238 
239 static struct ivi_layout_screen *
get_screen_from_output(struct weston_output * output)240 get_screen_from_output(struct weston_output *output)
241 {
242 	struct ivi_layout *layout = get_instance();
243 	struct ivi_layout_screen *iviscrn = NULL;
244 
245 	wl_list_for_each(iviscrn, &layout->screen_list, link) {
246 		if (iviscrn->output == output)
247 			return iviscrn;
248 	}
249 
250 	return NULL;
251 }
252 
253 /**
254  * Called at destruction of wl_surface/ivi_surface
255  */
256 void
ivi_layout_surface_destroy(struct ivi_layout_surface * ivisurf)257 ivi_layout_surface_destroy(struct ivi_layout_surface *ivisurf)
258 {
259 	struct ivi_layout *layout = get_instance();
260 	struct ivi_layout_view *ivi_view ,*next;
261 
262 	if (ivisurf == NULL) {
263 		weston_log("%s: invalid argument\n", __func__);
264 		return;
265 	}
266 
267 	wl_list_remove(&ivisurf->link);
268 
269 	wl_list_for_each_safe(ivi_view, next, &ivisurf->view_list, surf_link) {
270 		ivi_view_destroy(ivi_view);
271 	}
272 
273 	wl_signal_emit(&layout->surface_notification.removed, ivisurf);
274 
275 	ivi_layout_remove_all_surface_transitions(ivisurf);
276 
277 	free(ivisurf);
278 }
279 
280 /**
281  * Internal API to initialize ivi_screens found from output_list of weston_compositor.
282  * Called by ivi_layout_init_with_compositor.
283  */
284 static void
create_screen(struct weston_compositor * ec)285 create_screen(struct weston_compositor *ec)
286 {
287 	struct ivi_layout *layout = get_instance();
288 	struct ivi_layout_screen *iviscrn = NULL;
289 	struct weston_output *output = NULL;
290 
291 	wl_list_for_each(output, &ec->output_list, link) {
292 		iviscrn = calloc(1, sizeof *iviscrn);
293 		if (iviscrn == NULL) {
294 			weston_log("fails to allocate memory\n");
295 			continue;
296 		}
297 
298 		iviscrn->layout = layout;
299 
300 		iviscrn->output = output;
301 
302 		wl_list_init(&iviscrn->pending.layer_list);
303 
304 		wl_list_init(&iviscrn->order.layer_list);
305 
306 		wl_list_insert(&layout->screen_list, &iviscrn->link);
307 	}
308 }
309 
310 /**
311  * Internal APIs to initialize properties of ivi_surface/ivi_layer when they are created.
312  */
313 static void
init_layer_properties(struct ivi_layout_layer_properties * prop,int32_t width,int32_t height)314 init_layer_properties(struct ivi_layout_layer_properties *prop,
315 		      int32_t width, int32_t height)
316 {
317 	memset(prop, 0, sizeof *prop);
318 	prop->opacity = wl_fixed_from_double(1.0);
319 	prop->source_width = width;
320 	prop->source_height = height;
321 	prop->dest_width = width;
322 	prop->dest_height = height;
323 }
324 
325 static void
init_surface_properties(struct ivi_layout_surface_properties * prop)326 init_surface_properties(struct ivi_layout_surface_properties *prop)
327 {
328 	memset(prop, 0, sizeof *prop);
329 	prop->opacity = wl_fixed_from_double(1.0);
330 	/*
331 	 * FIXME: this shall be fixed by ivi-layout-transition.
332 	 */
333 	prop->dest_width = 1;
334 	prop->dest_height = 1;
335 }
336 
337 /**
338  * Internal APIs to be called from ivi_layout_commit_changes.
339  */
340 static void
update_opacity(struct ivi_layout_layer * ivilayer,struct ivi_layout_surface * ivisurf,struct weston_view * view)341 update_opacity(struct ivi_layout_layer *ivilayer,
342 	       struct ivi_layout_surface *ivisurf,
343 	       struct weston_view *view)
344 {
345 	double layer_alpha = wl_fixed_to_double(ivilayer->prop.opacity);
346 	double surf_alpha  = wl_fixed_to_double(ivisurf->prop.opacity);
347 
348 	view->alpha = layer_alpha * surf_alpha;
349 }
350 
351 static void
calc_transformation_matrix(struct ivi_rectangle * source_rect,struct ivi_rectangle * dest_rect,struct weston_matrix * m)352 calc_transformation_matrix(struct ivi_rectangle *source_rect,
353 			   struct ivi_rectangle *dest_rect,
354 			   struct weston_matrix *m)
355 {
356 	float source_center_x;
357 	float source_center_y;
358 	float scale_x;
359 	float scale_y;
360 	float translate_x;
361 	float translate_y;
362 
363 	source_center_x = source_rect->x + source_rect->width * 0.5f;
364 	source_center_y = source_rect->y + source_rect->height * 0.5f;
365 	weston_matrix_translate(m, -source_center_x, -source_center_y, 0.0f);
366 
367 	if ((dest_rect->width != source_rect->width) ||
368 	    (dest_rect->height != source_rect->height))
369 	{
370 		scale_x = (float) dest_rect->width / (float) source_rect->width;
371 		scale_y = (float) dest_rect->height / (float) source_rect->height;
372 		weston_matrix_scale(m, scale_x, scale_y, 1.0f);
373 	}
374 
375 	translate_x = dest_rect->width * 0.5f + dest_rect->x;
376 	translate_y = dest_rect->height * 0.5f + dest_rect->y;
377 	weston_matrix_translate(m, translate_x, translate_y, 0.0f);
378 }
379 
380 /*
381  * This computes intersected rect_output from two ivi_rectangles
382  */
383 static void
ivi_rectangle_intersect(const struct ivi_rectangle * rect1,const struct ivi_rectangle * rect2,struct ivi_rectangle * rect_output)384 ivi_rectangle_intersect(const struct ivi_rectangle *rect1,
385 		        const struct ivi_rectangle *rect2,
386 		        struct ivi_rectangle *rect_output)
387 {
388 	int32_t rect1_right = rect1->x + rect1->width;
389 	int32_t rect1_bottom = rect1->y + rect1->height;
390 	int32_t rect2_right = rect2->x + rect2->width;
391 	int32_t rect2_bottom = rect2->y + rect2->height;
392 
393 	rect_output->x = max(rect1->x, rect2->x);
394 	rect_output->y = max(rect1->y, rect2->y);
395 	rect_output->width = rect1_right < rect2_right ?
396 			     rect1_right - rect_output->x :
397 			     rect2_right - rect_output->x;
398 	rect_output->height = rect1_bottom < rect2_bottom ?
399 			      rect1_bottom - rect_output->y :
400 			      rect2_bottom - rect_output->y;
401 
402 	if (rect_output->width < 0 || rect_output->height < 0) {
403 		rect_output->width = 0;
404 		rect_output->height = 0;
405 	}
406 }
407 
408 /*
409  * Transform rect_input by the inverse of matrix, intersect with boundingbox,
410  * and store the result in rect_output.
411  * The boundingbox must be given in the same coordinate space as rect_output.
412  * Additionally, there are the following restrictions on the matrix:
413  * - no projective transformations
414  * - no skew
415  * - only multiples of 90-degree rotations supported
416  *
417  * In failure case of weston_matrix_invert, rect_output is set to boundingbox
418  * as a fail-safe with log.
419  */
420 static void
calc_inverse_matrix_transform(const struct weston_matrix * matrix,const struct ivi_rectangle * rect_input,const struct ivi_rectangle * boundingbox,struct ivi_rectangle * rect_output)421 calc_inverse_matrix_transform(const struct weston_matrix *matrix,
422 			      const struct ivi_rectangle *rect_input,
423 			      const struct ivi_rectangle *boundingbox,
424 			      struct ivi_rectangle *rect_output)
425 {
426 	struct weston_matrix m;
427 	struct weston_vector top_left;
428 	struct weston_vector bottom_right;
429 
430 	assert(boundingbox != rect_output);
431 
432 	if (weston_matrix_invert(&m, matrix) < 0) {
433 		weston_log("ivi-shell: calc_inverse_matrix_transform fails to invert a matrix.\n");
434 		weston_log("ivi-shell: boundingbox is set to the rect_output.\n");
435 		rect_output->x = boundingbox->x;
436 		rect_output->y = boundingbox->y;
437 		rect_output->width = boundingbox->width;
438 		rect_output->height = boundingbox->height;
439 	}
440 
441 	/* The vectors and matrices involved will always produce f[3] == 1.0. */
442 	top_left.f[0] = rect_input->x;
443 	top_left.f[1] = rect_input->y;
444 	top_left.f[2] = 0.0f;
445 	top_left.f[3] = 1.0f;
446 
447 	bottom_right.f[0] = rect_input->x + rect_input->width;
448 	bottom_right.f[1] = rect_input->y + rect_input->height;
449 	bottom_right.f[2] = 0.0f;
450 	bottom_right.f[3] = 1.0f;
451 
452 	weston_matrix_transform(&m, &top_left);
453 	weston_matrix_transform(&m, &bottom_right);
454 
455 	if (top_left.f[0] < bottom_right.f[0]) {
456 		rect_output->x = top_left.f[0];
457 		rect_output->width = bottom_right.f[0] - rect_output->x;
458 	} else {
459 		rect_output->x = bottom_right.f[0];
460 		rect_output->width = top_left.f[0] - rect_output->x;
461 	}
462 
463 	if (top_left.f[1] < bottom_right.f[1]) {
464 		rect_output->y = top_left.f[1];
465 		rect_output->height = bottom_right.f[1] - rect_output->y;
466 	} else {
467 		rect_output->y = bottom_right.f[1];
468 		rect_output->height = top_left.f[1] - rect_output->y;
469 	}
470 
471 	ivi_rectangle_intersect(rect_output, boundingbox, rect_output);
472 }
473 
474 /**
475  * This computes the whole transformation matrix:m from surface-local
476  * coordinates to multi-screen coordinates, which are global coordinates.
477  * It is assumed that weston_view::geometry.{x,y} are zero.
478  *
479  * Additionally, this computes the mask on surface-local coordinates as an
480  * ivi_rectangle. This can be set to weston_view_set_mask.
481  *
482  * The mask is computed by following steps
483  * - destination rectangle of layer is transformed to multi-screen coordinates,
484  *   global coordinates. This is done by adding weston_output.{x,y} in simple
485  *   because there is no scaled and rotated transformation.
486  * - destination rectangle of layer in multi-screen coordinates needs to be
487  *   intersected inside of a screen the layer is assigned to. This is because
488  *   overlapped region of weston surface in another screen shall not be
489  *   displayed according to ivi use case.
490  * - destination rectangle of layer
491  *   - in multi-screen coordinates,
492  *   - and intersected inside of an assigned screen,
493  *   is inversed to surface-local coordinates by inversed matrix:m.
494  * - the area is intersected by intersected area between weston_surface and
495  *   source rectangle of ivi_surface.
496  */
497 static void
calc_surface_to_global_matrix_and_mask_to_weston_surface(struct ivi_layout_screen * iviscrn,struct ivi_layout_layer * ivilayer,struct ivi_layout_surface * ivisurf,struct weston_matrix * m,struct ivi_rectangle * result)498 calc_surface_to_global_matrix_and_mask_to_weston_surface(
499 	struct ivi_layout_screen  *iviscrn,
500 	struct ivi_layout_layer *ivilayer,
501 	struct ivi_layout_surface *ivisurf,
502 	struct weston_matrix *m,
503 	struct ivi_rectangle *result)
504 {
505 	const struct ivi_layout_surface_properties *sp = &ivisurf->prop;
506 	const struct ivi_layout_layer_properties *lp = &ivilayer->prop;
507 	struct weston_output *output = iviscrn->output;
508 	struct ivi_rectangle weston_surface_rect = { 0,
509 						     0,
510 						     ivisurf->surface->width,
511 						     ivisurf->surface->height };
512 	struct ivi_rectangle surface_source_rect = { sp->source_x,
513 						     sp->source_y,
514 						     sp->source_width,
515 						     sp->source_height };
516 	struct ivi_rectangle surface_dest_rect =   { sp->dest_x,
517 						     sp->dest_y,
518 						     sp->dest_width,
519 						     sp->dest_height };
520 	struct ivi_rectangle layer_source_rect =   { lp->source_x,
521 						     lp->source_y,
522 						     lp->source_width,
523 						     lp->source_height };
524 	struct ivi_rectangle layer_dest_rect =     { lp->dest_x,
525 						     lp->dest_y,
526 						     lp->dest_width,
527 						     lp->dest_height };
528 	struct ivi_rectangle screen_dest_rect =    { output->x,
529 						     output->y,
530 						     output->width,
531 						     output->height };
532 	struct ivi_rectangle layer_dest_rect_in_global =
533 						   { lp->dest_x + output->x,
534 						     lp->dest_y + output->y,
535 						     lp->dest_width,
536 						     lp->dest_height };
537 	struct ivi_rectangle surface_result;
538 	struct ivi_rectangle layer_dest_rect_in_global_intersected;
539 
540 	/*
541 	 * the whole transformation matrix:m from surface-local
542 	 * coordinates to global coordinates, which is computed by
543 	 * two steps,
544 	 * - surface-local coordinates to layer-local coordinates
545 	 * - layer-local coordinates to single screen-local coordinates
546 	 * - single screen-local coordinates to multi-screen coordinates,
547 	 *   which are global coordinates.
548 	 */
549 	calc_transformation_matrix(&surface_source_rect, &surface_dest_rect, m);
550 	calc_transformation_matrix(&layer_source_rect, &layer_dest_rect, m);
551 
552 	weston_matrix_translate(m, output->x, output->y, 0.0f);
553 
554 	/* this intersected ivi_rectangle would be used for masking
555 	 * weston_surface
556 	 */
557 	// ivi_rectangle_intersect(&surface_source_rect, &weston_surface_rect,
558 	// 			&surface_result);
559 
560 	/*
561 	 * destination rectangle of layer in multi screens coordinate
562 	 * is intersected to avoid displaying outside of an assigned screen.
563 	 */
564 	ivi_rectangle_intersect(&layer_dest_rect_in_global, &screen_dest_rect,
565 				&layer_dest_rect_in_global_intersected);
566 
567 	/* calc masking area of weston_surface from m */
568 	calc_inverse_matrix_transform(m,
569 				      &layer_dest_rect_in_global_intersected,
570 				      &weston_surface_rect,
571 				      result);
572 }
573 
574 static void
update_prop(struct ivi_layout_view * ivi_view)575 update_prop(struct ivi_layout_view *ivi_view)
576 {
577     LOG_ENTER();
578 	struct ivi_layout_surface *ivisurf = ivi_view->ivisurf;
579 	struct ivi_layout_layer *ivilayer = ivi_view->on_layer;
580 	struct ivi_layout_screen *iviscrn = ivilayer->on_screen;
581 	struct ivi_rectangle r;
582 	bool can_calc = true;
583 
584 	/*In case of no prop change, this just returns*/
585 	if (!ivilayer->prop.event_mask && !ivisurf->prop.event_mask) {
586         LOG_ERROR("no prop change");
587         LOG_EXIT();
588 		return;
589     }
590     LOG_INFO("prop change");
591 
592 	update_opacity(ivilayer, ivisurf, ivi_view->view);
593 
594 	if (ivisurf->prop.source_width == 0 || ivisurf->prop.source_height == 0) {
595 		weston_log("ivi-shell: source rectangle is not yet set by ivi_layout_surface_set_source_rectangle\n");
596 		can_calc = false;
597 	}
598 
599 	if (ivisurf->prop.dest_width == 0 || ivisurf->prop.dest_height == 0) {
600 		weston_log("ivi-shell: destination rectangle is not yet set by ivi_layout_surface_set_destination_rectangle\n");
601 		can_calc = false;
602 	}
603 
604 	if (can_calc) {
605 		wl_list_remove(&ivi_view->transform.link);
606 		weston_matrix_init(&ivi_view->transform.matrix);
607 
608 		calc_surface_to_global_matrix_and_mask_to_weston_surface(
609 			iviscrn, ivilayer, ivisurf, &ivi_view->transform.matrix, &r);
610 
611 		weston_view_set_mask(ivi_view->view, r.x, r.y, r.width, r.height);
612 		wl_list_insert(&ivi_view->view->geometry.transformation_list,
613 			       &ivi_view->transform.link);
614 
615 		weston_view_set_transform_parent(ivi_view->view, NULL);
616 		weston_view_geometry_dirty(ivi_view->view);
617 		weston_view_update_transform(ivi_view->view);
618 	}
619 
620 	ivisurf->update_count++;
621 
622 	weston_view_schedule_repaint(ivi_view->view);
623     LOG_EXIT();
624 }
625 
626 static bool
ivi_view_is_mapped(struct ivi_layout_view * ivi_view)627 ivi_view_is_mapped(struct ivi_layout_view *ivi_view)
628 {
629 	return (!wl_list_empty(&ivi_view->order_link) &&
630 		ivi_view->on_layer->on_screen &&
631 		ivi_view->on_layer->prop.visibility &&
632 		ivi_view->ivisurf->prop.visibility);
633 }
634 
635 static void
commit_changes(struct ivi_layout * layout)636 commit_changes(struct ivi_layout *layout)
637 {
638     LOG_PASS();
639 	struct ivi_layout_view *ivi_view  = NULL;
640 
641 	wl_list_for_each(ivi_view, &layout->view_list, link) {
642 		/*
643 		 * If the view is not on the currently rendered scenegraph,
644 		 * we do not need to update its properties.
645 		 */
646         LOG_PASS();
647 		if (!ivi_view_is_mapped(ivi_view))
648 			continue;
649 
650         LOG_PASS();
651 		update_prop(ivi_view);
652 	}
653 }
654 
655 static void
commit_surface_list(struct ivi_layout * layout)656 commit_surface_list(struct ivi_layout *layout)
657 {
658 	struct ivi_layout_surface *ivisurf = NULL;
659 	int32_t dest_x = 0;
660 	int32_t dest_y = 0;
661 	int32_t dest_width = 0;
662 	int32_t dest_height = 0;
663 	int32_t configured = 0;
664 
665 	wl_list_for_each(ivisurf, &layout->surface_list, link) {
666 		if (ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEFAULT) {
667 			dest_x = ivisurf->prop.dest_x;
668 			dest_y = ivisurf->prop.dest_y;
669 			dest_width = ivisurf->prop.dest_width;
670 			dest_height = ivisurf->prop.dest_height;
671 
672 			ivi_layout_transition_move_resize_view(ivisurf,
673 							       ivisurf->pending.prop.dest_x,
674 							       ivisurf->pending.prop.dest_y,
675 							       ivisurf->pending.prop.dest_width,
676 							       ivisurf->pending.prop.dest_height,
677 							       ivisurf->pending.prop.transition_duration);
678 
679 			if (ivisurf->pending.prop.visibility) {
680 				ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
681 			} else {
682 				ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
683 			}
684 
685 			ivisurf->prop = ivisurf->pending.prop;
686 			ivisurf->prop.dest_x = dest_x;
687 			ivisurf->prop.dest_y = dest_y;
688 			ivisurf->prop.dest_width = dest_width;
689 			ivisurf->prop.dest_height = dest_height;
690 			ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
691 			ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
692 
693 		} else if (ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY) {
694 			dest_x = ivisurf->prop.dest_x;
695 			dest_y = ivisurf->prop.dest_y;
696 			dest_width = ivisurf->prop.dest_width;
697 			dest_height = ivisurf->prop.dest_height;
698 
699 			ivi_layout_transition_move_resize_view(ivisurf,
700 							       ivisurf->pending.prop.dest_x,
701 							       ivisurf->pending.prop.dest_y,
702 							       ivisurf->pending.prop.dest_width,
703 							       ivisurf->pending.prop.dest_height,
704 							       ivisurf->pending.prop.transition_duration);
705 
706 			ivisurf->prop = ivisurf->pending.prop;
707 			ivisurf->prop.dest_x = dest_x;
708 			ivisurf->prop.dest_y = dest_y;
709 			ivisurf->prop.dest_width = dest_width;
710 			ivisurf->prop.dest_height = dest_height;
711 
712 			ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
713 			ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
714 
715 		} else if (ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY) {
716 			configured = 0;
717 			if (ivisurf->pending.prop.visibility) {
718 				ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
719 			} else {
720 				ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
721 			}
722 
723 			if (ivisurf->prop.dest_width  != ivisurf->pending.prop.dest_width ||
724 			    ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
725 				configured = 1;
726 			}
727 
728 			ivisurf->prop = ivisurf->pending.prop;
729 			ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
730 			ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
731 
732 			if (configured && !is_surface_transition(ivisurf)) {
733 				ivi_layout_surface_set_size(ivisurf,
734 							    ivisurf->prop.dest_width,
735 							    ivisurf->prop.dest_height);
736 			}
737 		} else {
738 			configured = 0;
739 			if (ivisurf->prop.dest_width  != ivisurf->pending.prop.dest_width ||
740 			    ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
741 				configured = 1;
742 			}
743 
744 			ivisurf->prop = ivisurf->pending.prop;
745 			ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
746 			ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
747 
748 			if (configured && !is_surface_transition(ivisurf)) {
749 				ivi_layout_surface_set_size(ivisurf,
750 							    ivisurf->prop.dest_width,
751 							    ivisurf->prop.dest_height);
752 			}
753 		}
754 	}
755 }
756 
757 static void
commit_layer_list(struct ivi_layout * layout)758 commit_layer_list(struct ivi_layout *layout)
759 {
760 	struct ivi_layout_view *ivi_view = NULL;
761 	struct ivi_layout_layer   *ivilayer = NULL;
762 	struct ivi_layout_view *next     = NULL;
763 
764 	wl_list_for_each(ivilayer, &layout->layer_list, link) {
765 		if (ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_MOVE) {
766 			ivi_layout_transition_move_layer(ivilayer, ivilayer->pending.prop.dest_x, ivilayer->pending.prop.dest_y, ivilayer->pending.prop.transition_duration);
767 		} else if (ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_FADE) {
768 			ivi_layout_transition_fade_layer(ivilayer,ivilayer->pending.prop.is_fade_in,
769 							 ivilayer->pending.prop.start_alpha,ivilayer->pending.prop.end_alpha,
770 							 NULL, NULL,
771 							 ivilayer->pending.prop.transition_duration);
772 		}
773 		ivilayer->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
774 
775 		ivilayer->prop = ivilayer->pending.prop;
776 
777 		if (!ivilayer->order.dirty) {
778 			continue;
779 		}
780 
781 		wl_list_for_each_safe(ivi_view, next, &ivilayer->order.view_list,
782 					 order_link) {
783 			wl_list_remove(&ivi_view->order_link);
784 			wl_list_init(&ivi_view->order_link);
785 			ivi_view->ivisurf->prop.event_mask |= IVI_NOTIFICATION_REMOVE;
786 		}
787 
788 		assert(wl_list_empty(&ivilayer->order.view_list));
789 
790 		wl_list_for_each(ivi_view, &ivilayer->pending.view_list,
791 					 pending_link) {
792 			wl_list_remove(&ivi_view->order_link);
793 			wl_list_insert(&ivilayer->order.view_list, &ivi_view->order_link);
794 			ivi_view->ivisurf->prop.event_mask |= IVI_NOTIFICATION_ADD;
795 		}
796 
797 		ivilayer->order.dirty = 0;
798 	}
799 }
800 
801 static void
commit_screen_list(struct ivi_layout * layout)802 commit_screen_list(struct ivi_layout *layout)
803 {
804 	struct ivi_layout_screen  *iviscrn  = NULL;
805 	struct ivi_layout_layer   *ivilayer = NULL;
806 	struct ivi_layout_layer   *next     = NULL;
807 
808 	wl_list_for_each(iviscrn, &layout->screen_list, link) {
809 		if (iviscrn->order.dirty) {
810 			wl_list_for_each_safe(ivilayer, next,
811 					      &iviscrn->order.layer_list, order.link) {
812 				ivilayer->on_screen = NULL;
813 				wl_list_remove(&ivilayer->order.link);
814 				wl_list_init(&ivilayer->order.link);
815 				ivilayer->prop.event_mask |= IVI_NOTIFICATION_REMOVE;
816 			}
817 
818 			assert(wl_list_empty(&iviscrn->order.layer_list));
819 
820 			wl_list_for_each(ivilayer, &iviscrn->pending.layer_list,
821 					 pending.link) {
822 				/* FIXME: avoid to insert order.link to multiple screens */
823 				wl_list_remove(&ivilayer->order.link);
824 
825 				wl_list_insert(&iviscrn->order.layer_list,
826 					       &ivilayer->order.link);
827 				ivilayer->on_screen = iviscrn;
828 				ivilayer->prop.event_mask |= IVI_NOTIFICATION_ADD;
829 			}
830 
831 			iviscrn->order.dirty = 0;
832 		}
833 	}
834 }
835 
836 static void
build_view_list(struct ivi_layout * layout)837 build_view_list(struct ivi_layout *layout)
838 {
839 	struct ivi_layout_screen  *iviscrn;
840 	struct ivi_layout_layer   *ivilayer;
841 	struct ivi_layout_view   *ivi_view;
842 
843 	/* If ivi_view is not part of the scenegrapgh, we have to unmap
844 	 * weston_views
845 	 */
846 	wl_list_for_each(ivi_view, &layout->view_list, link) {
847 		if (!ivi_view_is_mapped(ivi_view))
848 			weston_view_unmap(ivi_view->view);
849 	}
850 
851 	/* Clear view list of layout ivi_layer */
852 	wl_list_init(&layout->layout_layer.view_list.link);
853 
854 	wl_list_for_each(iviscrn, &layout->screen_list, link) {
855 		wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
856 			if (ivilayer->prop.visibility == false)
857 				continue;
858 
859 			wl_list_for_each(ivi_view, &ivilayer->order.view_list, order_link) {
860 				if (ivi_view->ivisurf->prop.visibility == false)
861 					continue;
862 
863 				weston_layer_entry_insert(&layout->layout_layer.view_list,
864 							  &ivi_view->view->layer_link);
865 
866 				ivi_view->ivisurf->surface->is_mapped = true;
867 				ivi_view->view->is_mapped = true;
868 			}
869 		}
870 	}
871 }
872 
873 static void
commit_transition(struct ivi_layout * layout)874 commit_transition(struct ivi_layout* layout)
875 {
876 	if (wl_list_empty(&layout->pending_transition_list)) {
877 		return;
878 	}
879 
880 	wl_list_insert_list(&layout->transitions->transition_list,
881 			    &layout->pending_transition_list);
882 
883 	wl_list_init(&layout->pending_transition_list);
884 
885 	wl_event_source_timer_update(layout->transitions->event_source, 1);
886 }
887 
888 static void
send_surface_prop(struct ivi_layout_surface * ivisurf)889 send_surface_prop(struct ivi_layout_surface *ivisurf)
890 {
891 	wl_signal_emit(&ivisurf->property_changed, ivisurf);
892 	ivisurf->pending.prop.event_mask = 0;
893 }
894 
895 static void
send_layer_prop(struct ivi_layout_layer * ivilayer)896 send_layer_prop(struct ivi_layout_layer *ivilayer)
897 {
898 	wl_signal_emit(&ivilayer->property_changed, ivilayer);
899 	ivilayer->pending.prop.event_mask = 0;
900 }
901 
902 static void
send_prop(struct ivi_layout * layout)903 send_prop(struct ivi_layout *layout)
904 {
905 	struct ivi_layout_layer   *ivilayer = NULL;
906 	struct ivi_layout_surface *ivisurf  = NULL;
907 
908 	wl_list_for_each_reverse(ivilayer, &layout->layer_list, link) {
909 		if (ivilayer->prop.event_mask)
910 			send_layer_prop(ivilayer);
911 	}
912 
913 	wl_list_for_each_reverse(ivisurf, &layout->surface_list, link) {
914 		if (ivisurf->prop.event_mask)
915 			send_surface_prop(ivisurf);
916 	}
917 }
918 
919 static void
clear_view_pending_list(struct ivi_layout_layer * ivilayer)920 clear_view_pending_list(struct ivi_layout_layer *ivilayer)
921 {
922 	struct ivi_layout_view *view_link = NULL;
923 	struct ivi_layout_view *view_next = NULL;
924 
925 	wl_list_for_each_safe(view_link, view_next,
926 			      &ivilayer->pending.view_list, pending_link) {
927 		wl_list_remove(&view_link->pending_link);
928 		wl_list_init(&view_link->pending_link);
929 	}
930 }
931 
932 /**
933  * Exported APIs of ivi-layout library are implemented from here.
934  * Brief of APIs is described in ivi-layout-export.h.
935  */
936 static int32_t
ivi_layout_add_listener_create_layer(struct wl_listener * listener)937 ivi_layout_add_listener_create_layer(struct wl_listener *listener)
938 {
939 	struct ivi_layout *layout = get_instance();
940 
941 	if (listener == NULL) {
942 		weston_log("ivi_layout_add_listener_create_layer: invalid argument\n");
943 		return IVI_FAILED;
944 	}
945 
946 	wl_signal_add(&layout->layer_notification.created, listener);
947 
948 	return IVI_SUCCEEDED;
949 }
950 
951 static int32_t
ivi_layout_add_listener_remove_layer(struct wl_listener * listener)952 ivi_layout_add_listener_remove_layer(struct wl_listener *listener)
953 {
954 	struct ivi_layout *layout = get_instance();
955 
956 	if (listener == NULL) {
957 		weston_log("ivi_layout_add_listener_remove_layer: invalid argument\n");
958 		return IVI_FAILED;
959 	}
960 
961 	wl_signal_add(&layout->layer_notification.removed, listener);
962 
963 	return IVI_SUCCEEDED;
964 }
965 
966 static int32_t
ivi_layout_add_listener_create_surface(struct wl_listener * listener)967 ivi_layout_add_listener_create_surface(struct wl_listener *listener)
968 {
969 	struct ivi_layout *layout = get_instance();
970 
971 	if (listener == NULL) {
972 		weston_log("ivi_layout_add_listener_create_surface: invalid argument\n");
973 		return IVI_FAILED;
974 	}
975 
976 	wl_signal_add(&layout->surface_notification.created, listener);
977 
978 	return IVI_SUCCEEDED;
979 }
980 
981 static int32_t
ivi_layout_add_listener_remove_surface(struct wl_listener * listener)982 ivi_layout_add_listener_remove_surface(struct wl_listener *listener)
983 {
984 	struct ivi_layout *layout = get_instance();
985 
986 	if (listener == NULL) {
987 		weston_log("ivi_layout_add_listener_remove_surface: invalid argument\n");
988 		return IVI_FAILED;
989 	}
990 
991 	wl_signal_add(&layout->surface_notification.removed, listener);
992 
993 	return IVI_SUCCEEDED;
994 }
995 
996 static int32_t
ivi_layout_add_listener_configure_surface(struct wl_listener * listener)997 ivi_layout_add_listener_configure_surface(struct wl_listener *listener)
998 {
999 	struct ivi_layout *layout = get_instance();
1000 
1001 	if (listener == NULL) {
1002 		weston_log("ivi_layout_add_listener_configure_surface: invalid argument\n");
1003 		return IVI_FAILED;
1004 	}
1005 
1006 	wl_signal_add(&layout->surface_notification.configure_changed, listener);
1007 
1008 	return IVI_SUCCEEDED;
1009 }
1010 
1011 static int32_t
ivi_layout_add_listener_configure_desktop_surface(struct wl_listener * listener)1012 ivi_layout_add_listener_configure_desktop_surface(struct wl_listener *listener)
1013 {
1014 	struct ivi_layout *layout = get_instance();
1015 
1016 	if (!listener) {
1017 		weston_log("ivi_layout_add_listener_configure_desktop_surface: invalid argument\n");
1018 		return IVI_FAILED;
1019 	}
1020 
1021 	wl_signal_add(&layout->surface_notification.configure_desktop_changed, listener);
1022 
1023 	return IVI_SUCCEEDED;
1024 }
1025 
1026 uint32_t
ivi_layout_get_id_of_surface(struct ivi_layout_surface * ivisurf)1027 ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf)
1028 {
1029 	return ivisurf->id_surface;
1030 }
1031 
1032 static uint32_t
ivi_layout_get_id_of_layer(struct ivi_layout_layer * ivilayer)1033 ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer)
1034 {
1035 	return ivilayer->id_layer;
1036 }
1037 
1038 static struct ivi_layout_layer *
ivi_layout_get_layer_from_id(uint32_t id_layer)1039 ivi_layout_get_layer_from_id(uint32_t id_layer)
1040 {
1041 	struct ivi_layout *layout = get_instance();
1042 	struct ivi_layout_layer *ivilayer = NULL;
1043 
1044 	wl_list_for_each(ivilayer, &layout->layer_list, link) {
1045 		if (ivilayer->id_layer == id_layer) {
1046 			return ivilayer;
1047 		}
1048 	}
1049 
1050 	return NULL;
1051 }
1052 
1053 struct ivi_layout_surface *
ivi_layout_get_surface_from_id(uint32_t id_surface)1054 ivi_layout_get_surface_from_id(uint32_t id_surface)
1055 {
1056 	struct ivi_layout *layout = get_instance();
1057 	struct ivi_layout_surface *ivisurf = NULL;
1058 
1059 	wl_list_for_each(ivisurf, &layout->surface_list, link) {
1060 		if (ivisurf->id_surface == id_surface) {
1061 			return ivisurf;
1062 		}
1063 	}
1064 
1065 	return NULL;
1066 }
1067 
1068 static int32_t
ivi_layout_surface_add_listener(struct ivi_layout_surface * ivisurf,struct wl_listener * listener)1069 ivi_layout_surface_add_listener(struct ivi_layout_surface *ivisurf,
1070 				    struct wl_listener *listener)
1071 {
1072 	if (ivisurf == NULL || listener == NULL) {
1073 		weston_log("ivi_layout_surface_add_listener: invalid argument\n");
1074 		return IVI_FAILED;
1075 	}
1076 
1077 	wl_signal_add(&ivisurf->property_changed, listener);
1078 
1079 	return IVI_SUCCEEDED;
1080 }
1081 
1082 static const struct ivi_layout_layer_properties *
ivi_layout_get_properties_of_layer(struct ivi_layout_layer * ivilayer)1083 ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer)
1084 {
1085 	if (ivilayer == NULL) {
1086 		weston_log("ivi_layout_get_properties_of_layer: invalid argument\n");
1087 		return NULL;
1088 	}
1089 
1090 	return &ivilayer->prop;
1091 }
1092 
1093 static int32_t
ivi_layout_get_screens_under_layer(struct ivi_layout_layer * ivilayer,int32_t * pLength,struct weston_output *** ppArray)1094 ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer,
1095 				   int32_t *pLength,
1096 				   struct weston_output ***ppArray)
1097 {
1098 	int32_t length = 0;
1099 	int32_t n = 0;
1100 
1101 	if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1102 		weston_log("ivi_layout_get_screens_under_layer: invalid argument\n");
1103 		return IVI_FAILED;
1104 	}
1105 
1106 	if (ivilayer->on_screen != NULL)
1107 		length = 1;
1108 
1109 	if (length != 0) {
1110 		/* the Array must be free by module which called this function */
1111 		*ppArray = calloc(length, sizeof(struct weston_output *));
1112 		if (*ppArray == NULL) {
1113 			weston_log("fails to allocate memory\n");
1114 			return IVI_FAILED;
1115 		}
1116 
1117 		(*ppArray)[n++] = ivilayer->on_screen->output;
1118 	}
1119 
1120 	*pLength = length;
1121 
1122 	return IVI_SUCCEEDED;
1123 }
1124 
1125 static int32_t
ivi_layout_get_layers(int32_t * pLength,struct ivi_layout_layer *** ppArray)1126 ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray)
1127 {
1128 	struct ivi_layout *layout = get_instance();
1129 	struct ivi_layout_layer *ivilayer = NULL;
1130 	int32_t length = 0;
1131 	int32_t n = 0;
1132 
1133 	if (pLength == NULL || ppArray == NULL) {
1134 		weston_log("ivi_layout_get_layers: invalid argument\n");
1135 		return IVI_FAILED;
1136 	}
1137 
1138 	length = wl_list_length(&layout->layer_list);
1139 
1140 	if (length != 0) {
1141 		/* the Array must be freed by module which called this function */
1142 		*ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1143 		if (*ppArray == NULL) {
1144 			weston_log("fails to allocate memory\n");
1145 			return IVI_FAILED;
1146 		}
1147 
1148 		wl_list_for_each(ivilayer, &layout->layer_list, link) {
1149 			(*ppArray)[n++] = ivilayer;
1150 		}
1151 	}
1152 
1153 	*pLength = length;
1154 
1155 	return IVI_SUCCEEDED;
1156 }
1157 
1158 static int32_t
ivi_layout_get_layers_on_screen(struct weston_output * output,int32_t * pLength,struct ivi_layout_layer *** ppArray)1159 ivi_layout_get_layers_on_screen(struct weston_output *output,
1160 				int32_t *pLength,
1161 				struct ivi_layout_layer ***ppArray)
1162 {
1163 	struct ivi_layout_screen *iviscrn = NULL;
1164 	struct ivi_layout_layer *ivilayer = NULL;
1165 	int32_t length = 0;
1166 	int32_t n = 0;
1167 
1168 	if (output == NULL || pLength == NULL || ppArray == NULL) {
1169 		weston_log("ivi_layout_get_layers_on_screen: invalid argument\n");
1170 		return IVI_FAILED;
1171 	}
1172 
1173 	iviscrn = get_screen_from_output(output);
1174 	length = wl_list_length(&iviscrn->order.layer_list);
1175 
1176 	if (length != 0) {
1177 		/* the Array must be freed by module which called this function */
1178 		*ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1179 		if (*ppArray == NULL) {
1180 			weston_log("fails to allocate memory\n");
1181 			return IVI_FAILED;
1182 		}
1183 
1184 		wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
1185 			(*ppArray)[n++] = ivilayer;
1186 		}
1187 	}
1188 
1189 	*pLength = length;
1190 
1191 	return IVI_SUCCEEDED;
1192 }
1193 
1194 static int32_t
ivi_layout_get_layers_under_surface(struct ivi_layout_surface * ivisurf,int32_t * pLength,struct ivi_layout_layer *** ppArray)1195 ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf,
1196 				    int32_t *pLength,
1197 				    struct ivi_layout_layer ***ppArray)
1198 {
1199 	struct ivi_layout_view *ivi_view;
1200 	int32_t length = 0;
1201 	int32_t n = 0;
1202 
1203 	if (ivisurf == NULL || pLength == NULL || ppArray == NULL) {
1204 		weston_log("ivi_layout_getLayers: invalid argument\n");
1205 		return IVI_FAILED;
1206 	}
1207 
1208 	if (!wl_list_empty(&ivisurf->view_list)) {
1209 		/* the Array must be free by module which called this function */
1210 		length = wl_list_length(&ivisurf->view_list);
1211 		*ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1212 		if (*ppArray == NULL) {
1213 			weston_log("fails to allocate memory\n");
1214 			return IVI_FAILED;
1215 		}
1216 
1217 		wl_list_for_each_reverse(ivi_view, &ivisurf->view_list, surf_link) {
1218 			if (ivi_view_is_rendered(ivi_view))
1219 				(*ppArray)[n++] = ivi_view->on_layer;
1220 			else
1221 				length--;
1222 		}
1223 	}
1224 
1225 	*pLength = length;
1226 
1227 	if (!length) {
1228 		free(*ppArray);
1229 		*ppArray = NULL;
1230 	}
1231 
1232 	return IVI_SUCCEEDED;
1233 }
1234 
1235 static
1236 int32_t
ivi_layout_get_surfaces(int32_t * pLength,struct ivi_layout_surface *** ppArray)1237 ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray)
1238 {
1239 	struct ivi_layout *layout = get_instance();
1240 	struct ivi_layout_surface *ivisurf = NULL;
1241 	int32_t length = 0;
1242 	int32_t n = 0;
1243 
1244 	if (pLength == NULL || ppArray == NULL) {
1245 		weston_log("ivi_layout_get_surfaces: invalid argument\n");
1246 		return IVI_FAILED;
1247 	}
1248 
1249 	length = wl_list_length(&layout->surface_list);
1250 
1251 	if (length != 0) {
1252 		/* the Array must be freed by module which called this function */
1253 		*ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1254 		if (*ppArray == NULL) {
1255 			weston_log("fails to allocate memory\n");
1256 			return IVI_FAILED;
1257 		}
1258 
1259 		wl_list_for_each(ivisurf, &layout->surface_list, link) {
1260 			(*ppArray)[n++] = ivisurf;
1261 		}
1262 	}
1263 
1264 	*pLength = length;
1265 
1266 	return IVI_SUCCEEDED;
1267 }
1268 
1269 static int32_t
ivi_layout_get_surfaces_on_layer(struct ivi_layout_layer * ivilayer,int32_t * pLength,struct ivi_layout_surface *** ppArray)1270 ivi_layout_get_surfaces_on_layer(struct ivi_layout_layer *ivilayer,
1271 				 int32_t *pLength,
1272 				 struct ivi_layout_surface ***ppArray)
1273 {
1274 	struct ivi_layout_view *ivi_view = NULL;
1275 	int32_t length = 0;
1276 	int32_t n = 0;
1277 
1278 	if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1279 		weston_log("ivi_layout_getSurfaceIDsOnLayer: invalid argument\n");
1280 		return IVI_FAILED;
1281 	}
1282 
1283 	length = wl_list_length(&ivilayer->order.view_list);
1284 
1285 	if (length != 0) {
1286 		/* the Array must be freed by module which called this function */
1287 		*ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1288 		if (*ppArray == NULL) {
1289 			weston_log("fails to allocate memory\n");
1290 			return IVI_FAILED;
1291 		}
1292 
1293 		wl_list_for_each(ivi_view, &ivilayer->order.view_list, order_link) {
1294 			(*ppArray)[n++] = ivi_view->ivisurf;
1295 		}
1296 	}
1297 
1298 	*pLength = length;
1299 
1300 	return IVI_SUCCEEDED;
1301 }
1302 
1303 static struct ivi_layout_layer *
ivi_layout_layer_create_with_dimension(uint32_t id_layer,int32_t width,int32_t height)1304 ivi_layout_layer_create_with_dimension(uint32_t id_layer,
1305 				       int32_t width, int32_t height)
1306 {
1307 	struct ivi_layout *layout = get_instance();
1308 	struct ivi_layout_layer *ivilayer = NULL;
1309 
1310 	ivilayer = get_layer(&layout->layer_list, id_layer);
1311 	if (ivilayer != NULL) {
1312 		weston_log("id_layer is already created\n");
1313 		++ivilayer->ref_count;
1314 		return ivilayer;
1315 	}
1316 
1317 	ivilayer = calloc(1, sizeof *ivilayer);
1318 	if (ivilayer == NULL) {
1319 		weston_log("fails to allocate memory\n");
1320 		return NULL;
1321 	}
1322 
1323 	ivilayer->ref_count = 1;
1324 	wl_signal_init(&ivilayer->property_changed);
1325 	ivilayer->layout = layout;
1326 	ivilayer->id_layer = id_layer;
1327 
1328 	init_layer_properties(&ivilayer->prop, width, height);
1329 
1330 	wl_list_init(&ivilayer->pending.view_list);
1331 	wl_list_init(&ivilayer->pending.link);
1332 	ivilayer->pending.prop = ivilayer->prop;
1333 
1334 	wl_list_init(&ivilayer->order.view_list);
1335 	wl_list_init(&ivilayer->order.link);
1336 
1337 	wl_list_insert(&layout->layer_list, &ivilayer->link);
1338 
1339 	wl_signal_emit(&layout->layer_notification.created, ivilayer);
1340 
1341 	return ivilayer;
1342 }
1343 
1344 static void
ivi_layout_layer_destroy(struct ivi_layout_layer * ivilayer)1345 ivi_layout_layer_destroy(struct ivi_layout_layer *ivilayer)
1346 {
1347 	struct ivi_layout *layout = get_instance();
1348 	struct ivi_layout_view *ivi_view, *next;
1349 
1350 	if (ivilayer == NULL) {
1351 		weston_log("ivi_layout_layer_destroy: invalid argument\n");
1352 		return;
1353 	}
1354 
1355 	if (--ivilayer->ref_count > 0)
1356 		return;
1357 
1358 	/*Destroy all ivi_views*/
1359 	wl_list_for_each_safe(ivi_view, next, &layout->view_list, link) {
1360 		if (ivi_view->on_layer == ivilayer)
1361 			ivi_view_destroy(ivi_view);
1362 	}
1363 
1364 	wl_signal_emit(&layout->layer_notification.removed, ivilayer);
1365 
1366 	wl_list_remove(&ivilayer->pending.link);
1367 	wl_list_remove(&ivilayer->order.link);
1368 	wl_list_remove(&ivilayer->link);
1369 
1370 	free(ivilayer);
1371 }
1372 
1373 int32_t
ivi_layout_layer_set_visibility(struct ivi_layout_layer * ivilayer,bool newVisibility)1374 ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer,
1375 				bool newVisibility)
1376 {
1377 	struct ivi_layout_layer_properties *prop = NULL;
1378 
1379 	if (ivilayer == NULL) {
1380 		weston_log("ivi_layout_layer_set_visibility: invalid argument\n");
1381 		return IVI_FAILED;
1382 	}
1383 
1384 	prop = &ivilayer->pending.prop;
1385 	prop->visibility = newVisibility;
1386 
1387 	if (ivilayer->prop.visibility != newVisibility)
1388 		prop->event_mask |= IVI_NOTIFICATION_VISIBILITY;
1389 	else
1390 		prop->event_mask &= ~IVI_NOTIFICATION_VISIBILITY;
1391 
1392 	return IVI_SUCCEEDED;
1393 }
1394 
1395 int32_t
ivi_layout_layer_set_opacity(struct ivi_layout_layer * ivilayer,wl_fixed_t opacity)1396 ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
1397 			     wl_fixed_t opacity)
1398 {
1399 	struct ivi_layout_layer_properties *prop = NULL;
1400 
1401 	if (ivilayer == NULL ||
1402 	    opacity < wl_fixed_from_double(0.0) ||
1403 	    wl_fixed_from_double(1.0) < opacity) {
1404 		weston_log("ivi_layout_layer_set_opacity: invalid argument\n");
1405 		return IVI_FAILED;
1406 	}
1407 
1408 	prop = &ivilayer->pending.prop;
1409 	prop->opacity = opacity;
1410 
1411 	if (ivilayer->prop.opacity != opacity)
1412 		prop->event_mask |= IVI_NOTIFICATION_OPACITY;
1413 	else
1414 		prop->event_mask &= ~IVI_NOTIFICATION_OPACITY;
1415 
1416 	return IVI_SUCCEEDED;
1417 }
1418 
1419 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)1420 ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer,
1421 				      int32_t x, int32_t y,
1422 				      int32_t width, int32_t height)
1423 {
1424 	struct ivi_layout_layer_properties *prop = NULL;
1425 
1426 	if (ivilayer == NULL) {
1427 		weston_log("ivi_layout_layer_set_source_rectangle: invalid argument\n");
1428 		return IVI_FAILED;
1429 	}
1430 
1431 	prop = &ivilayer->pending.prop;
1432 	prop->source_x = x;
1433 	prop->source_y = y;
1434 	prop->source_width = width;
1435 	prop->source_height = height;
1436 
1437 	if (ivilayer->prop.source_x != x || ivilayer->prop.source_y != y ||
1438 	    ivilayer->prop.source_width != width ||
1439 	    ivilayer->prop.source_height != height)
1440 		prop->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
1441 	else
1442 		prop->event_mask &= ~IVI_NOTIFICATION_SOURCE_RECT;
1443 
1444 	return IVI_SUCCEEDED;
1445 }
1446 
1447 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)1448 ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer,
1449 					   int32_t x, int32_t y,
1450 					   int32_t width, int32_t height)
1451 {
1452 	struct ivi_layout_layer_properties *prop = NULL;
1453 
1454 	if (ivilayer == NULL) {
1455 		weston_log("ivi_layout_layer_set_destination_rectangle: invalid argument\n");
1456 		return IVI_FAILED;
1457 	}
1458 
1459 	prop = &ivilayer->pending.prop;
1460 	prop->dest_x = x;
1461 	prop->dest_y = y;
1462 	prop->dest_width = width;
1463 	prop->dest_height = height;
1464 
1465 	if (ivilayer->prop.dest_x != x || ivilayer->prop.dest_y != y ||
1466 	    ivilayer->prop.dest_width != width ||
1467 	    ivilayer->prop.dest_height != height)
1468 		prop->event_mask |= IVI_NOTIFICATION_DEST_RECT;
1469 	else
1470 		prop->event_mask &= ~IVI_NOTIFICATION_DEST_RECT;
1471 
1472 	return IVI_SUCCEEDED;
1473 }
1474 
1475 int32_t
ivi_layout_layer_set_render_order(struct ivi_layout_layer * ivilayer,struct ivi_layout_surface ** pSurface,int32_t number)1476 ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
1477 				  struct ivi_layout_surface **pSurface,
1478 				  int32_t number)
1479 {
1480 	int32_t i = 0;
1481 	struct ivi_layout_view * ivi_view;
1482 
1483 	if (ivilayer == NULL) {
1484 		weston_log("ivi_layout_layer_set_render_order: invalid argument\n");
1485 		return IVI_FAILED;
1486 	}
1487 
1488 	clear_view_pending_list(ivilayer);
1489 
1490 	for (i = 0; i < number; i++) {
1491 		ivi_view = get_ivi_view(ivilayer, pSurface[i]);
1492 		if (!ivi_view)
1493 			ivi_view = ivi_view_create(ivilayer, pSurface[i]);
1494 
1495 		assert(ivi_view != NULL);
1496 
1497 		wl_list_remove(&ivi_view->pending_link);
1498 		wl_list_insert(&ivilayer->pending.view_list, &ivi_view->pending_link);
1499 	}
1500 
1501 	ivilayer->order.dirty = 1;
1502 
1503 	return IVI_SUCCEEDED;
1504 }
1505 
1506 int32_t
ivi_layout_surface_set_visibility(struct ivi_layout_surface * ivisurf,bool newVisibility)1507 ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf,
1508 				  bool newVisibility)
1509 {
1510 	struct ivi_layout_surface_properties *prop = NULL;
1511 
1512 	if (ivisurf == NULL) {
1513 		weston_log("ivi_layout_surface_set_visibility: invalid argument\n");
1514 		return IVI_FAILED;
1515 	}
1516 
1517 	prop = &ivisurf->pending.prop;
1518 	prop->visibility = newVisibility;
1519 
1520 	if (ivisurf->prop.visibility != newVisibility)
1521 		prop->event_mask |= IVI_NOTIFICATION_VISIBILITY;
1522 	else
1523 		prop->event_mask &= ~IVI_NOTIFICATION_VISIBILITY;
1524 
1525 	return IVI_SUCCEEDED;
1526 }
1527 
1528 int32_t
ivi_layout_surface_set_opacity(struct ivi_layout_surface * ivisurf,wl_fixed_t opacity)1529 ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
1530 			       wl_fixed_t opacity)
1531 {
1532 	struct ivi_layout_surface_properties *prop = NULL;
1533 
1534 	if (ivisurf == NULL ||
1535 	    opacity < wl_fixed_from_double(0.0) ||
1536 	    wl_fixed_from_double(1.0) < opacity) {
1537 		weston_log("ivi_layout_surface_set_opacity: invalid argument\n");
1538 		return IVI_FAILED;
1539 	}
1540 
1541 	prop = &ivisurf->pending.prop;
1542 	prop->opacity = opacity;
1543 
1544 	if (ivisurf->prop.opacity != opacity)
1545 		prop->event_mask |= IVI_NOTIFICATION_OPACITY;
1546 	else
1547 		prop->event_mask &= ~IVI_NOTIFICATION_OPACITY;
1548 
1549 	return IVI_SUCCEEDED;
1550 }
1551 
1552 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)1553 ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
1554 					     int32_t x, int32_t y,
1555 					     int32_t width, int32_t height)
1556 {
1557 	struct ivi_layout_surface_properties *prop = NULL;
1558 
1559 	if (ivisurf == NULL) {
1560 		weston_log("ivi_layout_surface_set_destination_rectangle: invalid argument\n");
1561 		return IVI_FAILED;
1562 	}
1563 
1564 	prop = &ivisurf->pending.prop;
1565 	prop->start_x = prop->dest_x;
1566 	prop->start_y = prop->dest_y;
1567 	prop->dest_x = x;
1568 	prop->dest_y = y;
1569 	prop->start_width = prop->dest_width;
1570 	prop->start_height = prop->dest_height;
1571 	prop->dest_width = width;
1572 	prop->dest_height = height;
1573 
1574 	if (ivisurf->prop.dest_x != x || ivisurf->prop.dest_y != y ||
1575 	    ivisurf->prop.dest_width != width ||
1576 	    ivisurf->prop.dest_height != height)
1577 		prop->event_mask |= IVI_NOTIFICATION_DEST_RECT;
1578 	else
1579 		prop->event_mask &= ~IVI_NOTIFICATION_DEST_RECT;
1580 
1581 	return IVI_SUCCEEDED;
1582 }
1583 
1584 void
ivi_layout_surface_set_size(struct ivi_layout_surface * ivisurf,int32_t width,int32_t height)1585 ivi_layout_surface_set_size(struct ivi_layout_surface *ivisurf,
1586 			    int32_t width, int32_t height)
1587 {
1588 	if (weston_surface_is_desktop_surface(ivisurf->surface)) {
1589 		weston_desktop_surface_set_size(ivisurf->weston_desktop_surface,
1590 						width, height);
1591 	} else {
1592 		shell_surface_send_configure(ivisurf->surface,
1593 					     width, height);
1594 	}
1595 }
1596 
1597 static int32_t
ivi_layout_screen_add_layer(struct weston_output * output,struct ivi_layout_layer * addlayer)1598 ivi_layout_screen_add_layer(struct weston_output *output,
1599 			    struct ivi_layout_layer *addlayer)
1600 {
1601 	struct ivi_layout_screen *iviscrn;
1602 	struct ivi_layout_layer *layer;
1603 	struct wl_list *p_insert = NULL;
1604 
1605 	if (output == NULL || addlayer == NULL) {
1606 		weston_log("ivi_layout_screen_add_layer: invalid argument\n");
1607 		return IVI_FAILED;
1608 	}
1609 
1610 	iviscrn = get_screen_from_output(output);
1611 
1612 	/*if layer is already assigned to screen make order of it dirty
1613 	 * we are going to remove it (in commit_screen_list)*/
1614 	if (addlayer->on_screen)
1615 		addlayer->on_screen->order.dirty = 1;
1616 
1617 	wl_list_remove(&addlayer->pending.link);
1618 
1619 	wl_list_for_each(layer, &iviscrn->pending.layer_list, pending.link) {
1620 		if (addlayer->id_layer > layer->id_layer) {
1621 			p_insert = layer->pending.link.prev;
1622 			break;
1623 		}
1624 
1625 		if (layer->pending.link.next == &iviscrn->pending.layer_list) {
1626 			p_insert = &layer->pending.link;
1627 			break;
1628 		}
1629 	}
1630 
1631 	if (!p_insert) {
1632 		p_insert = &iviscrn->pending.layer_list;
1633 	}
1634 
1635 	wl_list_insert(p_insert, &addlayer->pending.link);
1636 
1637 	iviscrn->order.dirty = 1;
1638 
1639 	return IVI_SUCCEEDED;
1640 }
1641 
1642 static int32_t
ivi_layout_screen_remove_layer(struct weston_output * output,struct ivi_layout_layer * removelayer)1643 ivi_layout_screen_remove_layer(struct weston_output *output,
1644 			    struct ivi_layout_layer *removelayer)
1645 {
1646 	struct ivi_layout_screen *iviscrn;
1647 
1648 	if (output == NULL || removelayer == NULL) {
1649 		weston_log("ivi_layout_screen_remove_layer: invalid argument\n");
1650 		return IVI_FAILED;
1651 	}
1652 
1653 	iviscrn = get_screen_from_output(output);
1654 
1655 	wl_list_remove(&removelayer->pending.link);
1656 	wl_list_init(&removelayer->pending.link);
1657 
1658 	iviscrn->order.dirty = 1;
1659 
1660 	return IVI_SUCCEEDED;
1661 }
1662 
1663 static int32_t
ivi_layout_screen_set_render_order(struct weston_output * output,struct ivi_layout_layer ** pLayer,const int32_t number)1664 ivi_layout_screen_set_render_order(struct weston_output *output,
1665 				   struct ivi_layout_layer **pLayer,
1666 				   const int32_t number)
1667 {
1668 	struct ivi_layout_screen *iviscrn;
1669 	struct ivi_layout_layer *ivilayer = NULL;
1670 	struct ivi_layout_layer *next = NULL;
1671 	int32_t i = 0;
1672 
1673 	if (output == NULL) {
1674 		weston_log("ivi_layout_screen_set_render_order: invalid argument\n");
1675 		return IVI_FAILED;
1676 	}
1677 
1678 	iviscrn = get_screen_from_output(output);
1679 
1680 	wl_list_for_each_safe(ivilayer, next,
1681 			      &iviscrn->pending.layer_list, pending.link) {
1682 		wl_list_remove(&ivilayer->pending.link);
1683 		wl_list_init(&ivilayer->pending.link);
1684 	}
1685 
1686 	assert(wl_list_empty(&iviscrn->pending.layer_list));
1687 
1688 	for (i = 0; i < number; i++) {
1689 		wl_list_remove(&pLayer[i]->pending.link);
1690 		wl_list_insert(&iviscrn->pending.layer_list,
1691 				&pLayer[i]->pending.link);
1692 	}
1693 
1694 	iviscrn->order.dirty = 1;
1695 
1696 	return IVI_SUCCEEDED;
1697 }
1698 
1699 /**
1700  * This function is used by the additional ivi-module because of dumping ivi_surface sceenshot.
1701  * The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of Genivi's Layer Management.
1702  * This function is used to get the result of drawing by clients.
1703  */
1704 static struct weston_surface *
ivi_layout_surface_get_weston_surface(struct ivi_layout_surface * ivisurf)1705 ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf)
1706 {
1707 	return ivisurf != NULL ? ivisurf->surface : NULL;
1708 }
1709 
1710 static int32_t
ivi_layout_surface_get_size(struct ivi_layout_surface * ivisurf,int32_t * width,int32_t * height,int32_t * stride)1711 ivi_layout_surface_get_size(struct ivi_layout_surface *ivisurf,
1712 			    int32_t *width, int32_t *height,
1713 			    int32_t *stride)
1714 {
1715 	int32_t w;
1716 	int32_t h;
1717 	const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
1718 
1719 	if (ivisurf == NULL || ivisurf->surface == NULL) {
1720 		weston_log("%s: invalid argument\n", __func__);
1721 		return IVI_FAILED;
1722 	}
1723 
1724 	weston_surface_get_content_size(ivisurf->surface, &w, &h);
1725 
1726 	if (width != NULL)
1727 		*width = w;
1728 
1729 	if (height != NULL)
1730 		*height = h;
1731 
1732 	if (stride != NULL)
1733 		*stride = w * bytespp;
1734 
1735 	return IVI_SUCCEEDED;
1736 }
1737 
1738 static int32_t
ivi_layout_layer_add_listener(struct ivi_layout_layer * ivilayer,struct wl_listener * listener)1739 ivi_layout_layer_add_listener(struct ivi_layout_layer *ivilayer,
1740 				  struct wl_listener *listener)
1741 {
1742 	if (ivilayer == NULL || listener == NULL) {
1743 		weston_log("ivi_layout_layer_add_listener: invalid argument\n");
1744 		return IVI_FAILED;
1745 	}
1746 
1747 	wl_signal_add(&ivilayer->property_changed, listener);
1748 
1749 	return IVI_SUCCEEDED;
1750 }
1751 
1752 static const struct ivi_layout_surface_properties *
ivi_layout_get_properties_of_surface(struct ivi_layout_surface * ivisurf)1753 ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf)
1754 {
1755 	if (ivisurf == NULL) {
1756 		weston_log("ivi_layout_get_properties_of_surface: invalid argument\n");
1757 		return NULL;
1758 	}
1759 
1760 	return &ivisurf->prop;
1761 }
1762 
1763 static int32_t
ivi_layout_layer_add_surface(struct ivi_layout_layer * ivilayer,struct ivi_layout_surface * addsurf)1764 ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer,
1765 			     struct ivi_layout_surface *addsurf)
1766 {
1767 	struct ivi_layout_view *ivi_view;
1768 
1769 	if (ivilayer == NULL || addsurf == NULL) {
1770 		weston_log("ivi_layout_layer_add_surface: invalid argument\n");
1771 		return IVI_FAILED;
1772 	}
1773 
1774 	ivi_view = get_ivi_view(ivilayer, addsurf);
1775 	if (!ivi_view)
1776 		ivi_view = ivi_view_create(ivilayer, addsurf);
1777 
1778 	wl_list_remove(&ivi_view->pending_link);
1779 	wl_list_insert(&ivilayer->pending.view_list, &ivi_view->pending_link);
1780 
1781 	ivilayer->order.dirty = 1;
1782 
1783 	return IVI_SUCCEEDED;
1784 }
1785 
1786 static void
ivi_layout_layer_remove_surface(struct ivi_layout_layer * ivilayer,struct ivi_layout_surface * remsurf)1787 ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer,
1788 				struct ivi_layout_surface *remsurf)
1789 {
1790 	struct ivi_layout_view *ivi_view;
1791 
1792 	if (ivilayer == NULL || remsurf == NULL) {
1793 		weston_log("ivi_layout_layer_remove_surface: invalid argument\n");
1794 		return;
1795 	}
1796 
1797 	ivi_view = get_ivi_view(ivilayer, remsurf);
1798 	if (ivi_view) {
1799 		wl_list_remove(&ivi_view->pending_link);
1800 		wl_list_init(&ivi_view->pending_link);
1801 
1802 		ivilayer->order.dirty = 1;
1803 	}
1804 }
1805 
1806 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)1807 ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf,
1808 					int32_t x, int32_t y,
1809 					int32_t width, int32_t height)
1810 {
1811 	struct ivi_layout_surface_properties *prop = NULL;
1812 
1813 	if (ivisurf == NULL) {
1814 		weston_log("ivi_layout_surface_set_source_rectangle: invalid argument\n");
1815 		return IVI_FAILED;
1816 	}
1817 
1818 	prop = &ivisurf->pending.prop;
1819 	prop->source_x = x;
1820 	prop->source_y = y;
1821 	prop->source_width = width;
1822 	prop->source_height = height;
1823 
1824 	if (ivisurf->prop.source_x != x || ivisurf->prop.source_y != y ||
1825 	    ivisurf->prop.source_width != width ||
1826 	    ivisurf->prop.source_height != height)
1827 		prop->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
1828 	else
1829 		prop->event_mask &= ~IVI_NOTIFICATION_SOURCE_RECT;
1830 
1831 	return IVI_SUCCEEDED;
1832 }
1833 
1834 static int32_t
ivi_layout_surface_set_force_refresh(struct ivi_layout_surface * ivisurf)1835 ivi_layout_surface_set_force_refresh(struct ivi_layout_surface *ivisurf)
1836 {
1837     LOG_PASS();
1838 	struct ivi_layout_surface_properties *prop = NULL;
1839 
1840 	if (ivisurf == NULL) {
1841 		weston_log("ivi_layout_surface_set_force_refresh: invalid argument\n");
1842 		return IVI_FAILED;
1843 	}
1844 
1845 	prop = &ivisurf->pending.prop;
1846 
1847 	prop->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
1848 	prop->event_mask |= IVI_NOTIFICATION_DEST_RECT;
1849 
1850 	return IVI_SUCCEEDED;
1851 }
1852 
1853 int32_t
ivi_layout_commit_changes(void)1854 ivi_layout_commit_changes(void)
1855 {
1856     LOG_ENTER();
1857 	struct ivi_layout *layout = get_instance();
1858 
1859 	commit_surface_list(layout);
1860 	commit_layer_list(layout);
1861 	commit_screen_list(layout);
1862 	build_view_list(layout);
1863 
1864 	commit_transition(layout);
1865 
1866 	commit_changes(layout);
1867 	send_prop(layout);
1868 
1869     LOG_EXIT();
1870 	return IVI_SUCCEEDED;
1871 }
1872 
1873 static int32_t
ivi_layout_layer_set_transition(struct ivi_layout_layer * ivilayer,enum ivi_layout_transition_type type,uint32_t duration)1874 ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer,
1875 				enum ivi_layout_transition_type type,
1876 				uint32_t duration)
1877 {
1878 	if (ivilayer == NULL) {
1879 		weston_log("%s: invalid argument\n", __func__);
1880 		return -1;
1881 	}
1882 
1883 	ivilayer->pending.prop.transition_type = type;
1884 	ivilayer->pending.prop.transition_duration = duration;
1885 
1886 	return 0;
1887 }
1888 
1889 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)1890 ivi_layout_layer_set_fade_info(struct ivi_layout_layer* ivilayer,
1891 			       uint32_t is_fade_in,
1892 			       double start_alpha, double end_alpha)
1893 {
1894 	if (ivilayer == NULL) {
1895 		weston_log("%s: invalid argument\n", __func__);
1896 		return -1;
1897 	}
1898 
1899 	ivilayer->pending.prop.is_fade_in = is_fade_in;
1900 	ivilayer->pending.prop.start_alpha = start_alpha;
1901 	ivilayer->pending.prop.end_alpha = end_alpha;
1902 
1903 	return 0;
1904 }
1905 
1906 static int32_t
ivi_layout_surface_set_transition_duration(struct ivi_layout_surface * ivisurf,uint32_t duration)1907 ivi_layout_surface_set_transition_duration(struct ivi_layout_surface *ivisurf,
1908 					   uint32_t duration)
1909 {
1910 	struct ivi_layout_surface_properties *prop;
1911 
1912 	if (ivisurf == NULL) {
1913 		weston_log("%s: invalid argument\n", __func__);
1914 		return -1;
1915 	}
1916 
1917 	prop = &ivisurf->pending.prop;
1918 	prop->transition_duration = duration*10;
1919 	return 0;
1920 }
1921 
1922 /*
1923  * This interface enables e.g. an id agent to set the id of an ivi-layout
1924  * surface, that has been created by a desktop application. This can only be
1925  * done once as long as the initial surface id equals IVI_INVALID_ID. Afterwards
1926  * two events are emitted, namely surface_created and surface_configured.
1927  */
1928 static int32_t
ivi_layout_surface_set_id(struct ivi_layout_surface * ivisurf,uint32_t id_surface)1929 ivi_layout_surface_set_id(struct ivi_layout_surface *ivisurf,
1930 			  uint32_t id_surface)
1931 {
1932 	struct ivi_layout *layout = get_instance();
1933 	struct ivi_layout_surface *search_ivisurf = NULL;
1934 
1935 	if (!ivisurf) {
1936 		weston_log("%s: invalid argument\n", __func__);
1937 		return IVI_FAILED;
1938 	}
1939 
1940 	if (ivisurf->id_surface != IVI_INVALID_ID) {
1941 		weston_log("surface id can only be set once\n");
1942 		return IVI_FAILED;
1943 	}
1944 
1945 	search_ivisurf = get_surface(&layout->surface_list, id_surface);
1946 	if (search_ivisurf) {
1947 		weston_log("id_surface(%d) is already created\n", id_surface);
1948 		return IVI_FAILED;
1949 	}
1950 
1951 	ivisurf->id_surface = id_surface;
1952 
1953 	wl_signal_emit(&layout->surface_notification.created, ivisurf);
1954 	wl_signal_emit(&layout->surface_notification.configure_changed,
1955 		       ivisurf);
1956 
1957 	return IVI_SUCCEEDED;
1958 }
1959 
1960 static int32_t
ivi_layout_surface_set_transition(struct ivi_layout_surface * ivisurf,enum ivi_layout_transition_type type,uint32_t duration)1961 ivi_layout_surface_set_transition(struct ivi_layout_surface *ivisurf,
1962 				  enum ivi_layout_transition_type type,
1963 				  uint32_t duration)
1964 {
1965 	struct ivi_layout_surface_properties *prop;
1966 
1967 	if (ivisurf == NULL) {
1968 		weston_log("%s: invalid argument\n", __func__);
1969 		return -1;
1970 	}
1971 
1972 	prop = &ivisurf->pending.prop;
1973 	prop->transition_type = type;
1974 	prop->transition_duration = duration;
1975 	return 0;
1976 }
1977 
1978 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)1979 ivi_layout_surface_dump(struct weston_surface *surface,
1980 			void *target, size_t size,int32_t x, int32_t y,
1981 			int32_t width, int32_t height)
1982 {
1983 	int result = 0;
1984 
1985 	if (surface == NULL) {
1986 		weston_log("%s: invalid argument\n", __func__);
1987 		return IVI_FAILED;
1988 	}
1989 
1990 	result = weston_surface_copy_content(
1991 		surface, target, size,
1992 		x, y, width, height);
1993 
1994 	return result == 0 ? IVI_SUCCEEDED : IVI_FAILED;
1995 }
1996 
1997 /**
1998  * methods of interaction between ivi-shell with ivi-layout
1999  */
2000 
2001 static struct ivi_layout_surface*
surface_create(struct weston_surface * wl_surface,uint32_t id_surface)2002 surface_create(struct weston_surface *wl_surface, uint32_t id_surface)
2003 {
2004 	struct ivi_layout *layout = get_instance();
2005 	struct ivi_layout_surface *ivisurf = NULL;
2006 
2007 	if (wl_surface == NULL) {
2008 		weston_log("ivi_layout_surface_create: invalid argument\n");
2009 		return NULL;
2010 	}
2011 
2012 	ivisurf = calloc(1, sizeof *ivisurf);
2013 	if (ivisurf == NULL) {
2014 		weston_log("fails to allocate memory\n");
2015 		return NULL;
2016 	}
2017 
2018 	wl_signal_init(&ivisurf->property_changed);
2019 	ivisurf->id_surface = id_surface;
2020 	ivisurf->layout = layout;
2021 
2022 	ivisurf->surface = wl_surface;
2023 
2024 	ivisurf->surface->width_from_buffer  = 0;
2025 	ivisurf->surface->height_from_buffer = 0;
2026 
2027 	init_surface_properties(&ivisurf->prop);
2028 
2029 	ivisurf->pending.prop = ivisurf->prop;
2030 
2031 	wl_list_init(&ivisurf->view_list);
2032 
2033 	wl_list_insert(&layout->surface_list, &ivisurf->link);
2034 
2035 	return ivisurf;
2036 }
2037 
2038 void
ivi_layout_desktop_surface_configure(struct ivi_layout_surface * ivisurf,int32_t width,int32_t height)2039 ivi_layout_desktop_surface_configure(struct ivi_layout_surface *ivisurf,
2040 				 int32_t width, int32_t height)
2041 {
2042 	struct ivi_layout *layout = get_instance();
2043 
2044 	/* emit callback which is set by ivi-layout api user */
2045 	wl_signal_emit(&layout->surface_notification.configure_desktop_changed,
2046 		       ivisurf);
2047 }
2048 
2049 struct ivi_layout_surface*
ivi_layout_desktop_surface_create(struct weston_surface * wl_surface)2050 ivi_layout_desktop_surface_create(struct weston_surface *wl_surface)
2051 {
2052 	return surface_create(wl_surface, IVI_INVALID_ID);
2053 }
2054 
2055 void
ivi_layout_surface_configure(struct ivi_layout_surface * ivisurf,int32_t width,int32_t height)2056 ivi_layout_surface_configure(struct ivi_layout_surface *ivisurf,
2057 			     int32_t width, int32_t height)
2058 {
2059 	struct ivi_layout *layout = get_instance();
2060 
2061 	/* emit callback which is set by ivi-layout api user */
2062 	wl_signal_emit(&layout->surface_notification.configure_changed,
2063 		       ivisurf);
2064 }
2065 
2066 struct ivi_layout_surface*
ivi_layout_surface_create(struct weston_surface * wl_surface,uint32_t id_surface)2067 ivi_layout_surface_create(struct weston_surface *wl_surface,
2068 			  uint32_t id_surface)
2069 {
2070 	struct ivi_layout *layout = get_instance();
2071 	struct ivi_layout_surface *ivisurf = NULL;
2072 
2073 	ivisurf = get_surface(&layout->surface_list, id_surface);
2074 	if (ivisurf) {
2075 		weston_log("id_surface(%d) is already created\n", id_surface);
2076 		return NULL;
2077 	}
2078 
2079 	ivisurf = surface_create(wl_surface, id_surface);
2080 
2081 	if (ivisurf)
2082 		wl_signal_emit(&layout->surface_notification.created, ivisurf);
2083 
2084 	return ivisurf;
2085 }
2086 
output_created_event(struct wl_listener * listener,void * data)2087 static void output_created_event(struct wl_listener *listener, void *data)
2088 {
2089 	LOG_ENTER();
2090 	struct ivi_layout *layout = get_instance();
2091 	struct weston_output *output = (struct weston_output*)data;
2092 	struct ivi_layout_screen *iviscrn = NULL;
2093 
2094 	LOG_INFO("hzj test, output created, id: %d", output->id);
2095 
2096 	wl_list_for_each(iviscrn, &layout->screen_list, link) {
2097 		if (iviscrn->output == output) {
2098 			LOG_ERROR("output already created");
2099 			return;
2100 		}
2101 	}
2102 
2103 	iviscrn = calloc(1, sizeof *iviscrn);
2104 	if (iviscrn == NULL) {
2105 		LOG_ERROR("fails to allocate memory\n");
2106 		return;
2107 	}
2108 
2109 	iviscrn->layout = layout;
2110 	iviscrn->output = output;
2111 
2112 	wl_list_init(&iviscrn->pending.layer_list);
2113 	wl_list_init(&iviscrn->order.layer_list);
2114 	wl_list_insert(&layout->screen_list, &iviscrn->link);
2115 
2116 	LOG_EXIT();
2117 }
2118 
output_destroyed_event(struct wl_listener * listener,void * data)2119 static void output_destroyed_event(struct wl_listener *listener, void *data)
2120 {
2121 	LOG_ENTER();
2122 	struct ivi_layout *layout = get_instance();
2123 	struct weston_output *output = (struct weston_output*)data;
2124 	struct ivi_layout_screen *iviscrn = NULL;
2125 	struct ivi_layout_layer  *ivilayer = NULL;
2126 	struct ivi_layout_layer  *next = NULL;
2127 
2128 	LOG_INFO("hzj test, output destroyed, id: %d", output->id);
2129 
2130 	iviscrn = get_screen_from_output(output);
2131 	if (iviscrn == NULL) {
2132 		LOG_ERROR("output does not exist");
2133 		return;
2134 	}
2135 
2136 	wl_list_for_each_safe(ivilayer, next,
2137 					&iviscrn->pending.layer_list, pending.link) {
2138 		ivi_layout_layer_destroy(ivilayer);
2139 	}
2140 
2141 	wl_list_remove(&iviscrn->link);
2142 	free(iviscrn);
2143 
2144 	LOG_EXIT();
2145 }
2146 
2147 static struct ivi_layout_interface ivi_layout_interface;
2148 static struct ivi_layout_interface_for_wms ivi_layout_interface_for_wms;
2149 
2150 void
ivi_layout_init_with_compositor(struct weston_compositor * ec)2151 ivi_layout_init_with_compositor(struct weston_compositor *ec)
2152 {
2153     LOG_PASS();
2154 	struct ivi_layout *layout = get_instance();
2155 
2156 	layout->compositor = ec;
2157 
2158 	wl_list_init(&layout->surface_list);
2159 	wl_list_init(&layout->layer_list);
2160 	wl_list_init(&layout->screen_list);
2161 	wl_list_init(&layout->view_list);
2162 
2163 	wl_signal_init(&layout->layer_notification.created);
2164 	wl_signal_init(&layout->layer_notification.removed);
2165 
2166 	wl_signal_init(&layout->surface_notification.created);
2167 	wl_signal_init(&layout->surface_notification.removed);
2168 	wl_signal_init(&layout->surface_notification.configure_changed);
2169 	wl_signal_init(&layout->surface_notification.configure_desktop_changed);
2170 
2171 	/* Add layout_layer at the last of weston_compositor.layer_list */
2172 	weston_layer_init(&layout->layout_layer, ec);
2173 	weston_layer_set_position(&layout->layout_layer,
2174 				  WESTON_LAYER_POSITION_NORMAL);
2175 
2176 	create_screen(ec);
2177 
2178 	layout->output_listener.created.notify = output_created_event;
2179 	layout->output_listener.destroyed.notify = output_destroyed_event;
2180 
2181 	wl_signal_add(&ec->output_created_signal, &layout->output_listener.created);
2182 	wl_signal_add(&ec->output_destroyed_signal, &layout->output_listener.destroyed);
2183 
2184 	layout->transitions = ivi_layout_transition_set_create(ec);
2185 	wl_list_init(&layout->pending_transition_list);
2186 
2187 	weston_plugin_api_register(ec, IVI_LAYOUT_API_NAME,
2188 				   &ivi_layout_interface,
2189 				   sizeof(struct ivi_layout_interface));
2190 	weston_plugin_api_register(ec, IVI_LAYOUT_API_NAME_FOR_WMS,
2191 				   &ivi_layout_interface_for_wms,
2192 				   sizeof(struct ivi_layout_interface_for_wms));
2193 }
2194 
2195 static void
wl_list_insert_before(struct wl_list * list,struct wl_list * elm)2196 wl_list_insert_before(struct wl_list *list, struct wl_list *elm)
2197 {
2198 	elm->next = list;
2199 	elm->prev = list->prev;
2200 	list->prev = elm;
2201 	elm->prev->next = elm;
2202 }
2203 
2204 static struct weston_output*
create_virtual_screen(int32_t x,int32_t y,uint32_t width,uint32_t height)2205 create_virtual_screen(int32_t x, int32_t y, uint32_t width, uint32_t height)
2206 {
2207 	LOG_ENTER();
2208 	struct ivi_layout *layout = get_instance();
2209 	struct weston_compositor *ec = layout->compositor;
2210 	struct ivi_layout_screen *iviscrn = NULL;
2211 	struct weston_output *output = NULL;
2212 	uint32_t id = 0;
2213 
2214 	wl_list_for_each(output, &ec->output_list, link) {
2215 		if (id < output->id)
2216 			id = output->id;
2217 		LOG_ERROR("virtual output id:%d\n", id);
2218 	}
2219 	id++;
2220 
2221 	output = calloc(1, sizeof *output);
2222 	if (output == NULL) {
2223 		LOG_ERROR("fails to allocate memory\n");
2224 		return NULL;
2225 	}
2226 
2227 	output->id = id;
2228 	output->name = VIRTUAL_OUTPUT_NAME;
2229 	output->x = x;
2230 	output->y = y;
2231 	output->width = width;
2232 	output->height = height;
2233 
2234 	iviscrn = calloc(1, sizeof *iviscrn);
2235 	if (iviscrn == NULL) {
2236 		LOG_ERROR("fails to allocate memory\n");
2237 		free(output);
2238 		return NULL;
2239 	}
2240 
2241 	iviscrn->layout = layout;
2242 	iviscrn->output = output;
2243 
2244 	wl_list_init(&iviscrn->pending.layer_list);
2245 	wl_list_init(&iviscrn->order.layer_list);
2246 	wl_list_insert_before(&layout->screen_list, &iviscrn->link);
2247 
2248 	LOG_EXIT();
2249 	return output;
2250 }
2251 
2252 static int32_t
destroy_virtual_screen(uint32_t screen_id)2253 destroy_virtual_screen(uint32_t screen_id)
2254 {
2255 	LOG_ENTER();
2256 	struct ivi_layout_screen *iviscrn = get_screen_from_id(screen_id);
2257 	struct ivi_layout_layer  *ivilayer = NULL;
2258 	struct ivi_layout_layer  *next = NULL;
2259 
2260 	if (!iviscrn) {
2261 		LOG_ERROR("get_screen_from_id return null: invalid argument\n");
2262 		return IVI_FAILED;
2263 	}
2264 	wl_list_for_each_safe(ivilayer, next,
2265 					&iviscrn->pending.layer_list, pending.link) {
2266 		ivi_layout_layer_destroy(ivilayer);
2267 	}
2268 
2269 	wl_list_remove(&iviscrn->link);
2270 	free(iviscrn->output);
2271 	free(iviscrn);
2272 
2273 	LOG_EXIT();
2274 	return IVI_SUCCEEDED;
2275 }
2276 
2277 static int32_t
screen_clone(const uint32_t screen_id_from,const uint32_t screen_id_to)2278 screen_clone(const uint32_t screen_id_from,
2279 			 const uint32_t screen_id_to)
2280 {
2281 	struct ivi_layout_screen *iviscrn_from = get_screen_from_id(screen_id_from);
2282 	struct ivi_layout_screen *iviscrn_to = get_screen_from_id(screen_id_to);
2283 	struct ivi_layout_layer   *ivilayer = NULL;
2284 	struct ivi_layout_layer   *ivilayer_new = NULL;
2285 	struct ivi_layout_view   *iviview = NULL;
2286 	struct ivi_layout_surface *ivisurf  = NULL;
2287 
2288 	if (!iviscrn_from || !iviscrn_to) {
2289 		weston_log("get_screen_from_id return null: invalid argument\n");
2290 		return IVI_FAILED;
2291 	}
2292 
2293 	wl_list_for_each(ivilayer,
2294 			      &iviscrn_from->order.layer_list, order.link) {
2295 		ivilayer_new = ivi_layout_get_layer_from_id(ivilayer->id_layer + screen_id_to);
2296 		if (!ivilayer_new) {
2297 			ivilayer_new = ivi_layout_layer_create_with_dimension(
2298 							ivilayer->id_layer + screen_id_to,
2299 							iviscrn_to->output->width,
2300 							iviscrn_to->output->height);
2301 			if (!ivilayer_new) {
2302 				weston_log("ivi_layout_layer_create_with_dimension failed.");
2303 				return IVI_FAILED;
2304 			}
2305 
2306 			ivi_layout_screen_add_layer(iviscrn_to->output, ivilayer_new);
2307 			ivi_layout_layer_set_visibility(ivilayer_new, true);
2308 		}
2309 
2310 		wl_list_for_each(iviview, &ivilayer->order.view_list, order_link) {
2311 			ivi_layout_layer_add_surface(ivilayer_new,
2312 								iviview->ivisurf);
2313 		}
2314 	}
2315 
2316 	return IVI_SUCCEEDED;
2317 }
2318 
2319 static int32_t
screen_clear(const uint32_t screen_id)2320 screen_clear(const uint32_t screen_id)
2321 {
2322 	struct ivi_layout_screen *iviscrn = get_screen_from_id(screen_id);
2323 	struct ivi_layout_layer   *ivilayer = NULL;
2324 	struct ivi_layout_view   *iviview = NULL;
2325 
2326 	if (!iviscrn) {
2327 		weston_log("get_screen_from_id return null: invalid argument\n");
2328 		return IVI_FAILED;
2329 	}
2330 
2331 	wl_list_for_each(ivilayer,
2332 			      &iviscrn->order.layer_list, order.link) {
2333 		wl_list_for_each(iviview,
2334 				  &ivilayer->order.view_list, order_link) {
2335 			ivi_layout_layer_remove_surface(ivilayer, iviview->ivisurf);
2336 		}
2337 		//ivi_layout_screen_remove_layer(iviscrn->output, ivilayer);
2338 	}
2339 
2340 	return IVI_SUCCEEDED;
2341 }
2342 
2343 static struct ivi_layout_interface ivi_layout_interface = {
2344 	/**
2345 	 * commit all changes
2346 	 */
2347 	.commit_changes = ivi_layout_commit_changes,
2348 
2349 	/**
2350 	 * surface controller interfaces
2351 	 */
2352 	.add_listener_create_surface	= ivi_layout_add_listener_create_surface,
2353 	.add_listener_remove_surface	= ivi_layout_add_listener_remove_surface,
2354 	.add_listener_configure_surface	= ivi_layout_add_listener_configure_surface,
2355 	.add_listener_configure_desktop_surface	= ivi_layout_add_listener_configure_desktop_surface,
2356 	.get_surface				= shell_get_ivi_layout_surface,
2357 	.get_surfaces				= ivi_layout_get_surfaces,
2358 	.get_id_of_surface			= ivi_layout_get_id_of_surface,
2359 	.get_surface_from_id			= ivi_layout_get_surface_from_id,
2360 	.get_properties_of_surface		= ivi_layout_get_properties_of_surface,
2361 	.get_surfaces_on_layer			= ivi_layout_get_surfaces_on_layer,
2362 	.surface_set_visibility			= ivi_layout_surface_set_visibility,
2363 	.surface_set_opacity			= ivi_layout_surface_set_opacity,
2364 	.surface_set_source_rectangle		= ivi_layout_surface_set_source_rectangle,
2365 	.surface_set_destination_rectangle	= ivi_layout_surface_set_destination_rectangle,
2366 	.surface_add_listener			= ivi_layout_surface_add_listener,
2367 	.surface_get_weston_surface		= ivi_layout_surface_get_weston_surface,
2368 	.surface_set_transition			= ivi_layout_surface_set_transition,
2369 	.surface_set_transition_duration	= ivi_layout_surface_set_transition_duration,
2370 	.surface_set_id				= ivi_layout_surface_set_id,
2371 
2372 	/**
2373 	 * layer controller interfaces
2374 	 */
2375 	.add_listener_create_layer			= ivi_layout_add_listener_create_layer,
2376 	.add_listener_remove_layer		= ivi_layout_add_listener_remove_layer,
2377 	.layer_create_with_dimension		= ivi_layout_layer_create_with_dimension,
2378 	.layer_destroy				= ivi_layout_layer_destroy,
2379 	.get_layers				= ivi_layout_get_layers,
2380 	.get_id_of_layer			= ivi_layout_get_id_of_layer,
2381 	.get_layer_from_id			= ivi_layout_get_layer_from_id,
2382 	.get_properties_of_layer		= ivi_layout_get_properties_of_layer,
2383 	.get_layers_under_surface		= ivi_layout_get_layers_under_surface,
2384 	.get_layers_on_screen			= ivi_layout_get_layers_on_screen,
2385 	.layer_set_visibility			= ivi_layout_layer_set_visibility,
2386 	.layer_set_opacity			= ivi_layout_layer_set_opacity,
2387 	.layer_set_source_rectangle		= ivi_layout_layer_set_source_rectangle,
2388 	.layer_set_destination_rectangle	= ivi_layout_layer_set_destination_rectangle,
2389 	.layer_add_surface			= ivi_layout_layer_add_surface,
2390 	.layer_remove_surface			= ivi_layout_layer_remove_surface,
2391 	.layer_set_render_order			= ivi_layout_layer_set_render_order,
2392 	.layer_add_listener			= ivi_layout_layer_add_listener,
2393 	.layer_set_transition			= ivi_layout_layer_set_transition,
2394 
2395 	/**
2396 	 * screen controller interfaces
2397 	 */
2398 	.get_screens_under_layer	= ivi_layout_get_screens_under_layer,
2399 	.screen_add_layer		= ivi_layout_screen_add_layer,
2400 	.screen_remove_layer		= ivi_layout_screen_remove_layer,
2401 	.screen_set_render_order	= ivi_layout_screen_set_render_order,
2402 
2403 	/**
2404 	 * animation
2405 	 */
2406 	.transition_move_layer_cancel	= ivi_layout_transition_move_layer_cancel,
2407 	.layer_set_fade_info		= ivi_layout_layer_set_fade_info,
2408 
2409 	/**
2410 	 * surface content dumping for debugging
2411 	 */
2412 	.surface_get_size		= ivi_layout_surface_get_size,
2413 	.surface_dump			= ivi_layout_surface_dump,
2414 };
2415 
2416 int32_t
ivi_layout_surface_change_top(struct ivi_layout_surface * ivisurf)2417 ivi_layout_surface_change_top(struct ivi_layout_surface *ivisurf)
2418 {
2419 	struct ivi_layout_view *layout_view;
2420 	struct ivi_layout_layer *layout_layer;
2421 
2422 	if (ivisurf == NULL) {
2423 		weston_log("%s: invalid argument\n", __func__);
2424 		return IVI_FAILED;
2425 	}
2426 
2427 	wl_list_for_each(layout_view, &ivisurf->view_list, surf_link) {
2428 		if (!ivi_view_is_mapped(layout_view)) {
2429 			continue;
2430 		}
2431 		layout_layer = layout_view->on_layer;
2432 		if (!layout_layer) {
2433 			continue;
2434 		}
2435 
2436 		wl_list_remove(&layout_view->pending_link);
2437 		wl_list_insert(&layout_layer->pending.view_list, &layout_view->pending_link);
2438 		layout_layer->order.dirty = 1;
2439 	}
2440 
2441 	return IVI_SUCCEEDED;
2442 }
2443 
2444 static struct ivi_layout_interface_for_wms ivi_layout_interface_for_wms = {
2445 	.surface_create = ivi_layout_surface_create,
2446 	.surface_destroy = ivi_layout_surface_destroy,
2447 	.get_properties_of_surface = ivi_layout_get_properties_of_surface,
2448 	.surface_set_transition	= ivi_layout_surface_set_transition,
2449 	.surface_set_destination_rectangle = ivi_layout_surface_set_destination_rectangle,
2450 	.surface_set_source_rectangle = ivi_layout_surface_set_source_rectangle,
2451 	.surface_set_visibility	= ivi_layout_surface_set_visibility,
2452 	.commit_changes = ivi_layout_commit_changes,
2453 	.get_layer_from_id = ivi_layout_get_layer_from_id,
2454 	.layer_create_with_dimension = ivi_layout_layer_create_with_dimension,
2455 	.screen_add_layer = ivi_layout_screen_add_layer,
2456 	.layer_add_surface	= ivi_layout_layer_add_surface,
2457 	.layer_remove_surface	= ivi_layout_layer_remove_surface,
2458 	.surface_change_top = ivi_layout_surface_change_top,
2459 	.layer_set_visibility = ivi_layout_layer_set_visibility,
2460 	.layer_set_source_rectangle = ivi_layout_layer_set_source_rectangle,
2461 	.screen_clone = screen_clone,
2462 	.screen_clear = screen_clear,
2463 	.surface_set_force_refresh = ivi_layout_surface_set_force_refresh,
2464 	.get_surfaces_on_layer	 = ivi_layout_get_surfaces_on_layer,
2465 	.get_layers_on_screen	= ivi_layout_get_layers_on_screen,
2466 	.get_id_of_layer	= ivi_layout_get_id_of_layer,
2467 	.get_id_of_surface	= ivi_layout_get_id_of_surface,
2468 	.create_virtual_screen = create_virtual_screen,
2469 	.destroy_virtual_screen = destroy_virtual_screen,
2470 };
2471