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