blob: 93a4144740c490a0efc775c9ac368053de150c9e [file] [log] [blame]
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001/*
2 * Copyright (C) 2013 DENSO CORPORATION
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */
22
23/**
24 * Implementation of ivi-layout library. The actual view on ivi_screen is
25 * not updated till calling ivi_layout_commit_changes. A overview from
26 * calling API for updating properties of ivi_surface/ivi_layer to asking
27 * compositor to compose them by using weston_compositor_schedule_repaint,
28 * 0/ initialize this library by ivi_layout_init_with_compositor
29 * with (struct weston_compositor *ec) from ivi-shell.
30 * 1/ When a API for updating properties of ivi_surface/ivi_layer, it updates
31 * pending prop of ivi_surface/ivi_layer/ivi_screen which are structure to
32 * store properties.
33 * 2/ Before calling commitChanges, in case of calling a API to get a property,
34 * return current property, not pending property.
35 * 3/ At the timing of calling ivi_layout_commitChanges, pending properties
36 * are applied to properties.
37 *
38 * *) ivi_layout_commitChanges is also called by transition animation
39 * per each frame. See ivi-layout-transition.c in details. Transition
40 * animation interpolates frames between previous properties of ivi_surface
41 * and new ones.
42 * For example, when a property of ivi_surface is changed from invisibility
43 * to visibility, it behaves like fade-in. When ivi_layout_commitChange is
44 * called during transition animation, it cancels the transition and
45 * re-start transition to new properties from current properties of final
46 * frame just before the the cancellation.
47 *
48 * 4/ According properties, set transformation by using weston_matrix and
49 * weston_view per ivi_surfaces and ivi_layers in while loop.
50 * 5/ Set damage and trigger transform by using weston_view_geometry_dirty.
51 * 6/ Notify update of properties.
52 * 7/ Trigger composition by weston_compositor_schedule_repaint.
53 *
54 */
55
56#include <sys/wait.h>
57#include <unistd.h>
58#include <stdlib.h>
59#include <stdio.h>
60#include <string.h>
61#include <linux/input.h>
62
63#include "compositor.h"
64#include "ivi-layout-export.h"
65#include "ivi-layout-private.h"
66
67struct link_layer {
68 struct ivi_layout_layer *ivilayer;
69 struct wl_list link;
70 struct wl_list link_to_layer;
71};
72
73struct link_screen {
74 struct ivi_layout_screen *iviscrn;
75 struct wl_list link;
76 struct wl_list link_to_screen;
77};
78
79struct listener_layout_notification {
80 void *userdata;
81 struct wl_listener listener;
82};
83
84struct ivi_layout;
85
86struct ivi_layout_screen {
87 struct wl_list link;
88 struct wl_list link_to_layer;
89 uint32_t id_screen;
90
91 struct ivi_layout *layout;
92 struct weston_output *output;
93
94 uint32_t event_mask;
95
96 struct {
97 struct wl_list layer_list;
98 struct wl_list link;
99 } pending;
100
101 struct {
102 struct wl_list layer_list;
103 struct wl_list link;
104 } order;
105};
106
107struct ivi_layout_notification_callback {
108 void *callback;
109 void *data;
110};
111
112static struct ivi_layout ivilayout = {0};
113
114struct ivi_layout *
115get_instance(void)
116{
117 return &ivilayout;
118}
119
120/**
121 * Internal API to add/remove a link to ivi_surface from ivi_layer.
122 */
123static void
124add_link_to_surface(struct ivi_layout_layer *ivilayer,
125 struct link_layer *link_layer)
126{
127 struct link_layer *link = NULL;
128
129 wl_list_for_each(link, &ivilayer->link_to_surface, link_to_layer) {
130 if (link == link_layer)
131 return;
132 }
133
134 wl_list_insert(&ivilayer->link_to_surface, &link_layer->link_to_layer);
135}
136
137static void
138remove_link_to_surface(struct ivi_layout_layer *ivilayer)
139{
140 struct link_layer *link = NULL;
141 struct link_layer *next = NULL;
142
143 wl_list_for_each_safe(link, next, &ivilayer->link_to_surface, link_to_layer) {
144 if (!wl_list_empty(&link->link_to_layer)) {
145 wl_list_remove(&link->link_to_layer);
146 }
147 if (!wl_list_empty(&link->link)) {
148 wl_list_remove(&link->link);
149 }
150 free(link);
151 }
152
153 wl_list_init(&ivilayer->link_to_surface);
154}
155
156/**
157 * Internal API to add a link to ivi_layer from ivi_screen.
158 */
159static void
160add_link_to_layer(struct ivi_layout_screen *iviscrn,
161 struct link_screen *link_screen)
162{
163 wl_list_init(&link_screen->link_to_screen);
164 wl_list_insert(&iviscrn->link_to_layer, &link_screen->link_to_screen);
165}
166
167/**
168 * Internal API to add/remove a ivi_surface from ivi_layer.
169 */
170static void
171add_ordersurface_to_layer(struct ivi_layout_surface *ivisurf,
172 struct ivi_layout_layer *ivilayer)
173{
174 struct link_layer *link_layer = NULL;
175
176 link_layer = malloc(sizeof *link_layer);
177 if (link_layer == NULL) {
178 weston_log("fails to allocate memory\n");
179 return;
180 }
181
182 link_layer->ivilayer = ivilayer;
183 wl_list_init(&link_layer->link);
184 wl_list_insert(&ivisurf->layer_list, &link_layer->link);
185 add_link_to_surface(ivilayer, link_layer);
186}
187
188static void
189remove_ordersurface_from_layer(struct ivi_layout_surface *ivisurf)
190{
191 struct link_layer *link_layer = NULL;
192 struct link_layer *next = NULL;
193
194 wl_list_for_each_safe(link_layer, next, &ivisurf->layer_list, link) {
195 if (!wl_list_empty(&link_layer->link)) {
196 wl_list_remove(&link_layer->link);
197 }
198 if (!wl_list_empty(&link_layer->link_to_layer)) {
199 wl_list_remove(&link_layer->link_to_layer);
200 }
201 free(link_layer);
202 }
203 wl_list_init(&ivisurf->layer_list);
204}
205
206/**
207 * Internal API to add/remove a ivi_layer to/from ivi_screen.
208 */
209static void
210add_orderlayer_to_screen(struct ivi_layout_layer *ivilayer,
211 struct ivi_layout_screen *iviscrn)
212{
213 struct link_screen *link_scrn = NULL;
214
215 link_scrn = malloc(sizeof *link_scrn);
216 if (link_scrn == NULL) {
217 weston_log("fails to allocate memory\n");
218 return;
219 }
220
221 link_scrn->iviscrn = iviscrn;
222 wl_list_init(&link_scrn->link);
223 wl_list_insert(&ivilayer->screen_list, &link_scrn->link);
224 add_link_to_layer(iviscrn, link_scrn);
225}
226
227static void
228remove_orderlayer_from_screen(struct ivi_layout_layer *ivilayer)
229{
230 struct link_screen *link_scrn = NULL;
231 struct link_screen *next = NULL;
232
233 wl_list_for_each_safe(link_scrn, next, &ivilayer->screen_list, link) {
234 if (!wl_list_empty(&link_scrn->link)) {
235 wl_list_remove(&link_scrn->link);
236 }
237 if (!wl_list_empty(&link_scrn->link_to_screen)) {
238 wl_list_remove(&link_scrn->link_to_screen);
239 }
240 free(link_scrn);
241 }
242 wl_list_init(&ivilayer->screen_list);
243}
244
245/**
246 * Internal API to add/remove a ivi_layer to/from ivi_screen.
247 */
248static struct ivi_layout_surface *
249get_surface(struct wl_list *surf_list, uint32_t id_surface)
250{
251 struct ivi_layout_surface *ivisurf;
252
253 wl_list_for_each(ivisurf, surf_list, link) {
254 if (ivisurf->id_surface == id_surface) {
255 return ivisurf;
256 }
257 }
258
259 return NULL;
260}
261
262static struct ivi_layout_layer *
263get_layer(struct wl_list *layer_list, uint32_t id_layer)
264{
265 struct ivi_layout_layer *ivilayer;
266
267 wl_list_for_each(ivilayer, layer_list, link) {
268 if (ivilayer->id_layer == id_layer) {
269 return ivilayer;
270 }
271 }
272
273 return NULL;
274}
275
276/**
277 * Called at destruction of ivi_surface
278 */
279static void
280westonsurface_destroy_from_ivisurface(struct wl_listener *listener, void *data)
281{
282 struct ivi_layout_surface *ivisurf = NULL;
283
284 ivisurf = container_of(listener, struct ivi_layout_surface,
285 surface_destroy_listener);
286
287 wl_list_remove(&ivisurf->surface_rotation.link);
288 wl_list_remove(&ivisurf->layer_rotation.link);
289 wl_list_remove(&ivisurf->surface_pos.link);
290 wl_list_remove(&ivisurf->layer_pos.link);
291 wl_list_remove(&ivisurf->scaling.link);
292
293 ivisurf->surface = NULL;
294 ivi_layout_surface_remove(ivisurf);
295}
296
297/**
298 * Internal API to check ivi_layer/ivi_surface already added in ivi_layer/ivi_screen.
299 * Called by ivi_layout_layer_add_surface/ivi_layout_screenAddLayer
300 */
301static int
302is_surface_in_layer(struct ivi_layout_surface *ivisurf,
303 struct ivi_layout_layer *ivilayer)
304{
305 struct ivi_layout_surface *surf = NULL;
306
307 wl_list_for_each(surf, &ivilayer->pending.surface_list, pending.link) {
308 if (surf->id_surface == ivisurf->id_surface) {
309 return 1;
310 }
311 }
312
313 return 0;
314}
315
316static int
317is_layer_in_screen(struct ivi_layout_layer *ivilayer,
318 struct ivi_layout_screen *iviscrn)
319{
320 struct ivi_layout_layer *layer = NULL;
321
322 wl_list_for_each(layer, &iviscrn->pending.layer_list, pending.link) {
323 if (layer->id_layer == ivilayer->id_layer) {
324 return 1;
325 }
326 }
327
328 return 0;
329}
330
331/**
332 * Internal API to initialize ivi_screens found from output_list of weston_compositor.
333 * Called by ivi_layout_init_with_compositor.
334 */
335static void
336create_screen(struct weston_compositor *ec)
337{
338 struct ivi_layout *layout = get_instance();
339 struct ivi_layout_screen *iviscrn = NULL;
340 struct weston_output *output = NULL;
341 int32_t count = 0;
342
343 wl_list_for_each(output, &ec->output_list, link) {
344 iviscrn = calloc(1, sizeof *iviscrn);
345 if (iviscrn == NULL) {
346 weston_log("fails to allocate memory\n");
347 continue;
348 }
349
350 wl_list_init(&iviscrn->link);
351 iviscrn->layout = layout;
352
353 iviscrn->id_screen = count;
354 count++;
355
356 iviscrn->output = output;
357 iviscrn->event_mask = 0;
358
359 wl_list_init(&iviscrn->pending.layer_list);
360 wl_list_init(&iviscrn->pending.link);
361
362 wl_list_init(&iviscrn->order.layer_list);
363 wl_list_init(&iviscrn->order.link);
364
365 wl_list_init(&iviscrn->link_to_layer);
366
367 wl_list_insert(&layout->screen_list, &iviscrn->link);
368 }
369}
370
371/**
372 * Internal APIs to initialize properties of ivi_surface/ivi_layer when they are created.
373 */
374static void
375init_layer_properties(struct ivi_layout_layer_properties *prop,
376 int32_t width, int32_t height)
377{
378 memset(prop, 0, sizeof *prop);
379 prop->opacity = wl_fixed_from_double(1.0);
380 prop->source_width = width;
381 prop->source_height = height;
382 prop->dest_width = width;
383 prop->dest_height = height;
384}
385
386static void
387init_surface_properties(struct ivi_layout_surface_properties *prop)
388{
389 memset(prop, 0, sizeof *prop);
390 prop->opacity = wl_fixed_from_double(1.0);
391}
392
393/**
394 * Internal APIs to be called from ivi_layout_commit_changes.
395 */
396static void
397update_opacity(struct ivi_layout_layer *ivilayer,
398 struct ivi_layout_surface *ivisurf)
399{
400 double layer_alpha = wl_fixed_to_double(ivilayer->prop.opacity);
401 double surf_alpha = wl_fixed_to_double(ivisurf->prop.opacity);
402
403 if ((ivilayer->event_mask & IVI_NOTIFICATION_OPACITY) ||
404 (ivisurf->event_mask & IVI_NOTIFICATION_OPACITY)) {
405 struct weston_view *tmpview = NULL;
406 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
407 if (tmpview == NULL) {
408 continue;
409 }
410 tmpview->alpha = layer_alpha * surf_alpha;
411 }
412 }
413}
414
415static void
416update_surface_orientation(struct ivi_layout_layer *ivilayer,
417 struct ivi_layout_surface *ivisurf)
418{
419 struct weston_view *view;
420 struct weston_matrix *matrix = &ivisurf->surface_rotation.matrix;
421 float width = 0.0f;
422 float height = 0.0f;
423 float v_sin = 0.0f;
424 float v_cos = 0.0f;
425 float cx = 0.0f;
426 float cy = 0.0f;
427 float sx = 1.0f;
428 float sy = 1.0f;
429
430 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
431 if (view != NULL) {
432 break;
433 }
434 }
435
436 if (view == NULL) {
437 return;
438 }
439
440 if ((ivilayer->prop.dest_width == 0) ||
441 (ivilayer->prop.dest_height == 0)) {
442 return;
443 }
444 width = (float)ivilayer->prop.dest_width;
445 height = (float)ivilayer->prop.dest_height;
446
447 switch (ivisurf->prop.orientation) {
448 case WL_OUTPUT_TRANSFORM_NORMAL:
449 v_sin = 0.0f;
450 v_cos = 1.0f;
451 break;
452 case WL_OUTPUT_TRANSFORM_90:
453 v_sin = 1.0f;
454 v_cos = 0.0f;
455 sx = width / height;
456 sy = height / width;
457 break;
458 case WL_OUTPUT_TRANSFORM_180:
459 v_sin = 0.0f;
460 v_cos = -1.0f;
461 break;
462 case WL_OUTPUT_TRANSFORM_270:
463 default:
464 v_sin = -1.0f;
465 v_cos = 0.0f;
466 sx = width / height;
467 sy = height / width;
468 break;
469 }
470 wl_list_remove(&ivisurf->surface_rotation.link);
471 weston_view_geometry_dirty(view);
472
473 weston_matrix_init(matrix);
474 cx = 0.5f * width;
475 cy = 0.5f * height;
476 weston_matrix_translate(matrix, -cx, -cy, 0.0f);
477 weston_matrix_rotate_xy(matrix, v_cos, v_sin);
478 weston_matrix_scale(matrix, sx, sy, 1.0);
479 weston_matrix_translate(matrix, cx, cy, 0.0f);
480 wl_list_insert(&view->geometry.transformation_list,
481 &ivisurf->surface_rotation.link);
482
483 weston_view_set_transform_parent(view, NULL);
484 weston_view_update_transform(view);
485}
486
487static void
488update_layer_orientation(struct ivi_layout_layer *ivilayer,
489 struct ivi_layout_surface *ivisurf)
490{
491 struct weston_surface *es = ivisurf->surface;
492 struct weston_view *view;
493 struct weston_matrix *matrix = &ivisurf->layer_rotation.matrix;
494 struct weston_output *output = NULL;
495 float width = 0.0f;
496 float height = 0.0f;
497 float v_sin = 0.0f;
498 float v_cos = 0.0f;
499 float cx = 0.0f;
500 float cy = 0.0f;
501 float sx = 1.0f;
502 float sy = 1.0f;
503
504 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
505 if (view != NULL) {
506 break;
507 }
508 }
509
510 if (es == NULL || view == NULL) {
511 return;
512 }
513
514 output = es->output;
515 if (output == NULL) {
516 return;
517 }
518 if ((output->width == 0) || (output->height == 0)) {
519 return;
520 }
521 width = (float)output->width;
522 height = (float)output->height;
523
524 switch (ivilayer->prop.orientation) {
525 case WL_OUTPUT_TRANSFORM_NORMAL:
526 v_sin = 0.0f;
527 v_cos = 1.0f;
528 break;
529 case WL_OUTPUT_TRANSFORM_90:
530 v_sin = 1.0f;
531 v_cos = 0.0f;
532 sx = width / height;
533 sy = height / width;
534 break;
535 case WL_OUTPUT_TRANSFORM_180:
536 v_sin = 0.0f;
537 v_cos = -1.0f;
538 break;
539 case WL_OUTPUT_TRANSFORM_270:
540 default:
541 v_sin = -1.0f;
542 v_cos = 0.0f;
543 sx = width / height;
544 sy = height / width;
545 break;
546 }
547 wl_list_remove(&ivisurf->layer_rotation.link);
548 weston_view_geometry_dirty(view);
549
550 weston_matrix_init(matrix);
551 cx = 0.5f * width;
552 cy = 0.5f * height;
553 weston_matrix_translate(matrix, -cx, -cy, 0.0f);
554 weston_matrix_rotate_xy(matrix, v_cos, v_sin);
555 weston_matrix_scale(matrix, sx, sy, 1.0);
556 weston_matrix_translate(matrix, cx, cy, 0.0f);
557 wl_list_insert(&view->geometry.transformation_list,
558 &ivisurf->layer_rotation.link);
559
560 weston_view_set_transform_parent(view, NULL);
561 weston_view_update_transform(view);
562}
563
564static void
565update_surface_position(struct ivi_layout_surface *ivisurf)
566{
567 struct weston_view *view;
568 float tx = (float)ivisurf->prop.dest_x;
569 float ty = (float)ivisurf->prop.dest_y;
570 struct weston_matrix *matrix = &ivisurf->surface_pos.matrix;
571
572 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
573 if (view != NULL) {
574 break;
575 }
576 }
577
578 if (view == NULL) {
579 return;
580 }
581
582 wl_list_remove(&ivisurf->surface_pos.link);
583
584 weston_matrix_init(matrix);
585 weston_matrix_translate(matrix, tx, ty, 0.0f);
586 wl_list_insert(&view->geometry.transformation_list,
587 &ivisurf->surface_pos.link);
588
589 weston_view_set_transform_parent(view, NULL);
590 weston_view_update_transform(view);
591}
592
593static void
594update_layer_position(struct ivi_layout_layer *ivilayer,
595 struct ivi_layout_surface *ivisurf)
596{
597 struct weston_view *view;
598 struct weston_matrix *matrix = &ivisurf->layer_pos.matrix;
599 float tx = (float)ivilayer->prop.dest_x;
600 float ty = (float)ivilayer->prop.dest_y;
601
602 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
603 if (view != NULL) {
604 break;
605 }
606 }
607
608 if (view == NULL) {
609 return;
610 }
611
612 wl_list_remove(&ivisurf->layer_pos.link);
613
614 weston_matrix_init(matrix);
615 weston_matrix_translate(matrix, tx, ty, 0.0f);
616 wl_list_insert(&view->geometry.transformation_list,
617 &ivisurf->layer_pos.link);
618
619 weston_view_set_transform_parent(view, NULL);
620 weston_view_update_transform(view);
621}
622
623static void
624update_scale(struct ivi_layout_layer *ivilayer,
625 struct ivi_layout_surface *ivisurf)
626{
627 struct weston_view *view;
628 struct weston_matrix *matrix = &ivisurf->scaling.matrix;
629 float sx = 0.0f;
630 float sy = 0.0f;
631 float lw = 0.0f;
632 float sw = 0.0f;
633 float lh = 0.0f;
634 float sh = 0.0f;
635
636 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
637 if (view != NULL) {
638 break;
639 }
640 }
641
642 if (view == NULL) {
643 return;
644 }
645
646 if (ivisurf->prop.dest_width == 0 && ivisurf->prop.dest_height == 0) {
647 ivisurf->prop.dest_width = ivisurf->surface->width_from_buffer;
648 ivisurf->prop.dest_height = ivisurf->surface->height_from_buffer;
649 }
650
651 lw = ((float)ivilayer->prop.dest_width / (float)ivilayer->prop.source_width );
652 sw = ((float)ivisurf->prop.dest_width / (float)ivisurf->prop.source_width );
653 lh = ((float)ivilayer->prop.dest_height / (float)ivilayer->prop.source_height);
654 sh = ((float)ivisurf->prop.dest_height / (float)ivisurf->prop.source_height );
655 sx = sw * lw;
656 sy = sh * lh;
657
658 wl_list_remove(&ivisurf->scaling.link);
659 weston_matrix_init(matrix);
660 weston_matrix_scale(matrix, sx, sy, 1.0f);
661
662 wl_list_insert(&view->geometry.transformation_list,
663 &ivisurf->scaling.link);
664
665 weston_view_set_transform_parent(view, NULL);
666 weston_view_update_transform(view);
667}
668
669static void
670update_prop(struct ivi_layout_layer *ivilayer,
671 struct ivi_layout_surface *ivisurf)
672{
673 if (ivilayer->event_mask | ivisurf->event_mask) {
674 struct weston_view *tmpview;
675 update_opacity(ivilayer, ivisurf);
676 update_layer_orientation(ivilayer, ivisurf);
677 update_layer_position(ivilayer, ivisurf);
678 update_surface_position(ivisurf);
679 update_surface_orientation(ivilayer, ivisurf);
680 update_scale(ivilayer, ivisurf);
681
682 ivisurf->update_count++;
683
684 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
685 if (tmpview != NULL) {
686 break;
687 }
688 }
689
690 if (tmpview != NULL) {
691 weston_view_geometry_dirty(tmpview);
692 }
693
694 if (ivisurf->surface != NULL) {
695 weston_surface_damage(ivisurf->surface);
696 }
697 }
698}
699
700static void
701commit_changes(struct ivi_layout *layout)
702{
703 struct ivi_layout_screen *iviscrn = NULL;
704 struct ivi_layout_layer *ivilayer = NULL;
705 struct ivi_layout_surface *ivisurf = NULL;
706
707 wl_list_for_each(iviscrn, &layout->screen_list, link) {
708 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
709 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
710 update_prop(ivilayer, ivisurf);
711 }
712 }
713 }
714}
715
716static void
717commit_surface_list(struct ivi_layout *layout)
718{
719 struct ivi_layout_surface *ivisurf = NULL;
720 int32_t dest_x = 0;
721 int32_t dest_y = 0;
722 int32_t dest_width = 0;
723 int32_t dest_height = 0;
724 int32_t configured = 0;
725
726 wl_list_for_each(ivisurf, &layout->surface_list, link) {
727 if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEFAULT) {
728 dest_x = ivisurf->prop.dest_x;
729 dest_y = ivisurf->prop.dest_y;
730 dest_width = ivisurf->prop.dest_width;
731 dest_height = ivisurf->prop.dest_height;
732
733 ivi_layout_transition_move_resize_view(ivisurf,
734 ivisurf->pending.prop.dest_x,
735 ivisurf->pending.prop.dest_y,
736 ivisurf->pending.prop.dest_width,
737 ivisurf->pending.prop.dest_height,
738 ivisurf->pending.prop.transition_duration);
739
740 if(ivisurf->pending.prop.visibility) {
741 ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
742 } else {
743 ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
744 }
745
746 ivisurf->prop = ivisurf->pending.prop;
747 ivisurf->prop.dest_x = dest_x;
748 ivisurf->prop.dest_y = dest_y;
749 ivisurf->prop.dest_width = dest_width;
750 ivisurf->prop.dest_height = dest_height;
751 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
752 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
753
754 } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY){
755 dest_x = ivisurf->prop.dest_x;
756 dest_y = ivisurf->prop.dest_y;
757 dest_width = ivisurf->prop.dest_width;
758 dest_height = ivisurf->prop.dest_height;
759
760 ivi_layout_transition_move_resize_view(ivisurf,
761 ivisurf->pending.prop.dest_x,
762 ivisurf->pending.prop.dest_y,
763 ivisurf->pending.prop.dest_width,
764 ivisurf->pending.prop.dest_height,
765 ivisurf->pending.prop.transition_duration);
766
767 ivisurf->prop = ivisurf->pending.prop;
768 ivisurf->prop.dest_x = dest_x;
769 ivisurf->prop.dest_y = dest_y;
770 ivisurf->prop.dest_width = dest_width;
771 ivisurf->prop.dest_height = dest_height;
772
773 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
774 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
775
776 } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY){
777 configured = 0;
778 if(ivisurf->pending.prop.visibility) {
779 ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
780 } else {
781 ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
782 }
783
784 if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
785 ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
786 configured = 1;
787 }
788
789 ivisurf->prop = ivisurf->pending.prop;
790 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
791 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
792
793 if (configured && !is_surface_transition(ivisurf))
794 wl_signal_emit(&ivisurf->configured, ivisurf);
795 } else {
796 configured = 0;
797 if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
798 ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
799 configured = 1;
800 }
801
802 ivisurf->prop = ivisurf->pending.prop;
803 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
804 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
805
806 if (configured && !is_surface_transition(ivisurf))
807 wl_signal_emit(&ivisurf->configured, ivisurf);
808 }
809 }
810}
811
812static void
813commit_layer_list(struct ivi_layout *layout)
814{
815 struct ivi_layout_layer *ivilayer = NULL;
816 struct ivi_layout_surface *ivisurf = NULL;
817 struct ivi_layout_surface *next = NULL;
818
819 wl_list_for_each(ivilayer, &layout->layer_list, link) {
820 if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_MOVE) {
821 ivi_layout_transition_move_layer(ivilayer, ivilayer->pending.prop.dest_x, ivilayer->pending.prop.dest_y, ivilayer->pending.prop.transition_duration);
822 } else if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_FADE) {
823 ivi_layout_transition_fade_layer(ivilayer,ivilayer->pending.prop.is_fade_in,
824 ivilayer->pending.prop.start_alpha,ivilayer->pending.prop.end_alpha,
825 NULL, NULL,
826 ivilayer->pending.prop.transition_duration);
827 }
828 ivilayer->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
829
830 ivilayer->prop = ivilayer->pending.prop;
831
832 if (!(ivilayer->event_mask &
833 (IVI_NOTIFICATION_ADD | IVI_NOTIFICATION_REMOVE)) ) {
834 continue;
835 }
836
837 if (ivilayer->event_mask & IVI_NOTIFICATION_REMOVE) {
838 wl_list_for_each_safe(ivisurf, next,
839 &ivilayer->order.surface_list, order.link) {
840 remove_ordersurface_from_layer(ivisurf);
841
842 if (!wl_list_empty(&ivisurf->order.link)) {
843 wl_list_remove(&ivisurf->order.link);
844 }
845
846 wl_list_init(&ivisurf->order.link);
847 ivisurf->event_mask |= IVI_NOTIFICATION_REMOVE;
848 }
849
850 wl_list_init(&ivilayer->order.surface_list);
851 }
852
853 if (ivilayer->event_mask & IVI_NOTIFICATION_ADD) {
854 wl_list_for_each_safe(ivisurf, next,
855 &ivilayer->order.surface_list, order.link) {
856 remove_ordersurface_from_layer(ivisurf);
857
858 if (!wl_list_empty(&ivisurf->order.link)) {
859 wl_list_remove(&ivisurf->order.link);
860 }
861
862 wl_list_init(&ivisurf->order.link);
863 }
864
865 wl_list_init(&ivilayer->order.surface_list);
866 wl_list_for_each(ivisurf, &ivilayer->pending.surface_list,
867 pending.link) {
868 if(!wl_list_empty(&ivisurf->order.link)){
869 wl_list_remove(&ivisurf->order.link);
870 wl_list_init(&ivisurf->order.link);
871 }
872
873 wl_list_insert(&ivilayer->order.surface_list,
874 &ivisurf->order.link);
875 add_ordersurface_to_layer(ivisurf, ivilayer);
876 ivisurf->event_mask |= IVI_NOTIFICATION_ADD;
877 }
878 }
879 }
880}
881
882static void
883commit_screen_list(struct ivi_layout *layout)
884{
885 struct ivi_layout_screen *iviscrn = NULL;
886 struct ivi_layout_layer *ivilayer = NULL;
887 struct ivi_layout_layer *next = NULL;
888 struct ivi_layout_surface *ivisurf = NULL;
889
890 wl_list_for_each(iviscrn, &layout->screen_list, link) {
891 if (iviscrn->event_mask & IVI_NOTIFICATION_REMOVE) {
892 wl_list_for_each_safe(ivilayer, next,
893 &iviscrn->order.layer_list, order.link) {
894 remove_orderlayer_from_screen(ivilayer);
895
896 if (!wl_list_empty(&ivilayer->order.link)) {
897 wl_list_remove(&ivilayer->order.link);
898 }
899
900 wl_list_init(&ivilayer->order.link);
901 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
902 }
903 }
904
905 if (iviscrn->event_mask & IVI_NOTIFICATION_ADD) {
906 wl_list_for_each_safe(ivilayer, next,
907 &iviscrn->order.layer_list, order.link) {
908 remove_orderlayer_from_screen(ivilayer);
909
910 if (!wl_list_empty(&ivilayer->order.link)) {
911 wl_list_remove(&ivilayer->order.link);
912 }
913
914 wl_list_init(&ivilayer->order.link);
915 }
916
917 wl_list_init(&iviscrn->order.layer_list);
918 wl_list_for_each(ivilayer, &iviscrn->pending.layer_list,
919 pending.link) {
920 wl_list_insert(&iviscrn->order.layer_list,
921 &ivilayer->order.link);
922 add_orderlayer_to_screen(ivilayer, iviscrn);
923 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
924 }
925 }
926
927 iviscrn->event_mask = 0;
928
929 /* Clear view list of layout ivi_layer */
930 wl_list_init(&layout->layout_layer.view_list.link);
931
932 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
933 if (ivilayer->prop.visibility == false)
934 continue;
935
936 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
937 struct weston_view *tmpview = NULL;
938 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
939 if (tmpview != NULL) {
940 break;
941 }
942 }
943
944 if (ivisurf->prop.visibility == false)
945 continue;
946 if (ivisurf->surface == NULL || tmpview == NULL)
947 continue;
948
949 weston_layer_entry_insert(&layout->layout_layer.view_list,
950 &tmpview->layer_link);
951
952 ivisurf->surface->output = iviscrn->output;
953 }
954 }
955
956 break;
957 }
958}
959
960static void
961commit_transition(struct ivi_layout* layout)
962{
963 if(wl_list_empty(&layout->pending_transition_list)){
964 return;
965 }
966
967 wl_list_insert_list(&layout->transitions->transition_list,
968 &layout->pending_transition_list);
969
970 wl_list_init(&layout->pending_transition_list);
971
972 wl_event_source_timer_update(layout->transitions->event_source, 1);
973}
974
975static void
976send_surface_prop(struct ivi_layout_surface *ivisurf)
977{
978 wl_signal_emit(&ivisurf->property_changed, ivisurf);
979 ivisurf->event_mask = 0;
980}
981
982static void
983send_layer_prop(struct ivi_layout_layer *ivilayer)
984{
985 wl_signal_emit(&ivilayer->property_changed, ivilayer);
986 ivilayer->event_mask = 0;
987}
988
989static void
990send_prop(struct ivi_layout *layout)
991{
992 struct ivi_layout_layer *ivilayer = NULL;
993 struct ivi_layout_surface *ivisurf = NULL;
994
995 wl_list_for_each_reverse(ivilayer, &layout->layer_list, link) {
996 send_layer_prop(ivilayer);
997 }
998
999 wl_list_for_each_reverse(ivisurf, &layout->surface_list, link) {
1000 send_surface_prop(ivisurf);
1001 }
1002}
1003
1004static void
1005clear_surface_pending_list(struct ivi_layout_layer *ivilayer)
1006{
1007 struct ivi_layout_surface *surface_link = NULL;
1008 struct ivi_layout_surface *surface_next = NULL;
1009
1010 wl_list_for_each_safe(surface_link, surface_next,
1011 &ivilayer->pending.surface_list, pending.link) {
1012 if (!wl_list_empty(&surface_link->pending.link)) {
1013 wl_list_remove(&surface_link->pending.link);
1014 }
1015
1016 wl_list_init(&surface_link->pending.link);
1017 }
1018
1019 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
1020}
1021
1022static void
1023clear_surface_order_list(struct ivi_layout_layer *ivilayer)
1024{
1025 struct ivi_layout_surface *surface_link = NULL;
1026 struct ivi_layout_surface *surface_next = NULL;
1027
1028 wl_list_for_each_safe(surface_link, surface_next,
1029 &ivilayer->order.surface_list, order.link) {
1030 if (!wl_list_empty(&surface_link->order.link)) {
1031 wl_list_remove(&surface_link->order.link);
1032 }
1033
1034 wl_list_init(&surface_link->order.link);
1035 }
1036
1037 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
1038}
1039
1040static void
1041layer_created(struct wl_listener *listener, void *data)
1042{
1043 struct ivi_layout_layer *ivilayer = data;
1044
1045 struct listener_layout_notification *notification =
1046 container_of(listener,
1047 struct listener_layout_notification,
1048 listener);
1049
1050 struct ivi_layout_notification_callback *created_callback =
1051 notification->userdata;
1052
1053 ((layer_create_notification_func)created_callback->callback)
1054 (ivilayer, created_callback->data);
1055}
1056
1057static void
1058layer_removed(struct wl_listener *listener, void *data)
1059{
1060 struct ivi_layout_layer *ivilayer = data;
1061
1062 struct listener_layout_notification *notification =
1063 container_of(listener,
1064 struct listener_layout_notification,
1065 listener);
1066
1067 struct ivi_layout_notification_callback *removed_callback =
1068 notification->userdata;
1069
1070 ((layer_remove_notification_func)removed_callback->callback)
1071 (ivilayer, removed_callback->data);
1072}
1073
1074static void
1075layer_prop_changed(struct wl_listener *listener, void *data)
1076{
1077 struct ivi_layout_layer *ivilayer = data;
1078
1079 struct listener_layout_notification *layout_listener =
1080 container_of(listener,
1081 struct listener_layout_notification,
1082 listener);
1083
1084 struct ivi_layout_notification_callback *prop_callback =
1085 layout_listener->userdata;
1086
1087 ((layer_property_notification_func)prop_callback->callback)
1088 (ivilayer, &ivilayer->prop, ivilayer->event_mask, prop_callback->data);
1089}
1090
1091static void
1092surface_created(struct wl_listener *listener, void *data)
1093{
1094 struct ivi_layout_surface *ivisurface = data;
1095
1096 struct listener_layout_notification *notification =
1097 container_of(listener,
1098 struct listener_layout_notification,
1099 listener);
1100
1101 struct ivi_layout_notification_callback *created_callback =
1102 notification->userdata;
1103
1104 ((surface_create_notification_func)created_callback->callback)
1105 (ivisurface, created_callback->data);
1106}
1107
1108static void
1109surface_removed(struct wl_listener *listener, void *data)
1110{
1111 struct ivi_layout_surface *ivisurface = data;
1112
1113 struct listener_layout_notification *notification =
1114 container_of(listener,
1115 struct listener_layout_notification,
1116 listener);
1117
1118 struct ivi_layout_notification_callback *removed_callback =
1119 notification->userdata;
1120
1121 ((surface_remove_notification_func)removed_callback->callback)
1122 (ivisurface, removed_callback->data);
1123}
1124
1125static void
1126surface_prop_changed(struct wl_listener *listener, void *data)
1127{
1128 struct ivi_layout_surface *ivisurf = data;
1129
1130 struct listener_layout_notification *layout_listener =
1131 container_of(listener,
1132 struct listener_layout_notification,
1133 listener);
1134
1135 struct ivi_layout_notification_callback *prop_callback =
1136 layout_listener->userdata;
1137
1138 ((surface_property_notification_func)prop_callback->callback)
1139 (ivisurf, &ivisurf->prop, ivisurf->event_mask, prop_callback->data);
1140
1141 ivisurf->event_mask = 0;
1142}
1143
1144static void
1145surface_configure_changed(struct wl_listener *listener,
1146 void *data)
1147{
1148 struct ivi_layout_surface *ivisurface = data;
1149
1150 struct listener_layout_notification *notification =
1151 container_of(listener,
1152 struct listener_layout_notification,
1153 listener);
1154
1155 struct ivi_layout_notification_callback *configure_changed_callback =
1156 notification->userdata;
1157
1158 ((surface_configure_notification_func)configure_changed_callback->callback)
1159 (ivisurface, configure_changed_callback->data);
1160}
1161
1162static int32_t
1163add_notification(struct wl_signal *signal,
1164 wl_notify_func_t callback,
1165 void *userdata)
1166{
1167 struct listener_layout_notification *notification = NULL;
1168
1169 notification = malloc(sizeof *notification);
1170 if (notification == NULL) {
1171 weston_log("fails to allocate memory\n");
1172 free(userdata);
1173 return IVI_FAILED;
1174 }
1175
1176 notification->listener.notify = callback;
1177 notification->userdata = userdata;
1178
1179 wl_signal_add(signal, &notification->listener);
1180
1181 return IVI_SUCCEEDED;
1182}
1183
1184static void
1185remove_notification(struct wl_list *listener_list, void *callback, void *userdata)
1186{
1187 struct wl_listener *listener = NULL;
1188 struct wl_listener *next = NULL;
1189
1190 wl_list_for_each_safe(listener, next, listener_list, link) {
1191 struct listener_layout_notification *notification =
1192 container_of(listener,
1193 struct listener_layout_notification,
1194 listener);
1195
1196 struct ivi_layout_notification_callback *notification_callback =
1197 notification->userdata;
1198
1199 if ((notification_callback->callback != callback) ||
1200 (notification_callback->data != userdata)) {
1201 continue;
1202 }
1203
1204 if (!wl_list_empty(&listener->link)) {
1205 wl_list_remove(&listener->link);
1206 }
1207
1208 free(notification->userdata);
1209 free(notification);
1210 }
1211}
1212
1213static void
1214remove_all_notification(struct wl_list *listener_list)
1215{
1216 struct wl_listener *listener = NULL;
1217 struct wl_listener *next = NULL;
1218
1219 wl_list_for_each_safe(listener, next, listener_list, link) {
1220 struct listener_layout_notification *notification = NULL;
1221 if (!wl_list_empty(&listener->link)) {
1222 wl_list_remove(&listener->link);
1223 }
1224
1225 notification =
1226 container_of(listener,
1227 struct listener_layout_notification,
1228 listener);
1229
1230 free(notification->userdata);
1231 free(notification);
1232 }
1233}
1234
1235/**
1236 * Exported APIs of ivi-layout library are implemented from here.
1237 * Brief of APIs is described in ivi-layout-export.h.
1238 */
1239WL_EXPORT int32_t
1240ivi_layout_add_notification_create_layer(layer_create_notification_func callback,
1241 void *userdata)
1242{
1243 struct ivi_layout *layout = get_instance();
1244 struct ivi_layout_notification_callback *created_callback = NULL;
1245
1246 if (callback == NULL) {
1247 weston_log("ivi_layout_add_notification_create_layer: invalid argument\n");
1248 return IVI_FAILED;
1249 }
1250
1251 created_callback = malloc(sizeof *created_callback);
1252 if (created_callback == NULL) {
1253 weston_log("fails to allocate memory\n");
1254 return IVI_FAILED;
1255 }
1256
1257 created_callback->callback = callback;
1258 created_callback->data = userdata;
1259
1260 return add_notification(&layout->layer_notification.created,
1261 layer_created,
1262 created_callback);
1263}
1264
1265WL_EXPORT void
1266ivi_layout_remove_notification_create_layer(layer_create_notification_func callback,
1267 void *userdata)
1268{
1269 struct ivi_layout *layout = get_instance();
1270 remove_notification(&layout->layer_notification.created.listener_list, callback, userdata);
1271}
1272
1273WL_EXPORT int32_t
1274ivi_layout_add_notification_remove_layer(layer_remove_notification_func callback,
1275 void *userdata)
1276{
1277 struct ivi_layout *layout = get_instance();
1278 struct ivi_layout_notification_callback *removed_callback = NULL;
1279
1280 if (callback == NULL) {
1281 weston_log("ivi_layout_add_notification_remove_layer: invalid argument\n");
1282 return IVI_FAILED;
1283 }
1284
1285 removed_callback = malloc(sizeof *removed_callback);
1286 if (removed_callback == NULL) {
1287 weston_log("fails to allocate memory\n");
1288 return IVI_FAILED;
1289 }
1290
1291 removed_callback->callback = callback;
1292 removed_callback->data = userdata;
1293 return add_notification(&layout->layer_notification.removed,
1294 layer_removed,
1295 removed_callback);
1296}
1297
1298WL_EXPORT void
1299ivi_layout_remove_notification_remove_layer(layer_remove_notification_func callback,
1300 void *userdata)
1301{
1302 struct ivi_layout *layout = get_instance();
1303 remove_notification(&layout->layer_notification.removed.listener_list, callback, userdata);
1304}
1305
1306WL_EXPORT int32_t
1307ivi_layout_add_notification_create_surface(surface_create_notification_func callback,
1308 void *userdata)
1309{
1310 struct ivi_layout *layout = get_instance();
1311 struct ivi_layout_notification_callback *created_callback = NULL;
1312
1313 if (callback == NULL) {
1314 weston_log("ivi_layout_add_notification_create_surface: invalid argument\n");
1315 return IVI_FAILED;
1316 }
1317
1318 created_callback = malloc(sizeof *created_callback);
1319 if (created_callback == NULL) {
1320 weston_log("fails to allocate memory\n");
1321 return IVI_FAILED;
1322 }
1323
1324 created_callback->callback = callback;
1325 created_callback->data = userdata;
1326
1327 return add_notification(&layout->surface_notification.created,
1328 surface_created,
1329 created_callback);
1330}
1331
1332WL_EXPORT void
1333ivi_layout_remove_notification_create_surface(surface_create_notification_func callback,
1334 void *userdata)
1335{
1336 struct ivi_layout *layout = get_instance();
1337 remove_notification(&layout->surface_notification.created.listener_list, callback, userdata);
1338}
1339
1340WL_EXPORT int32_t
1341ivi_layout_add_notification_remove_surface(surface_remove_notification_func callback,
1342 void *userdata)
1343{
1344 struct ivi_layout *layout = get_instance();
1345 struct ivi_layout_notification_callback *removed_callback = NULL;
1346
1347 if (callback == NULL) {
1348 weston_log("ivi_layout_add_notification_remove_surface: invalid argument\n");
1349 return IVI_FAILED;
1350 }
1351
1352 removed_callback = malloc(sizeof *removed_callback);
1353 if (removed_callback == NULL) {
1354 weston_log("fails to allocate memory\n");
1355 return IVI_FAILED;
1356 }
1357
1358 removed_callback->callback = callback;
1359 removed_callback->data = userdata;
1360
1361 return add_notification(&layout->surface_notification.removed,
1362 surface_removed,
1363 removed_callback);
1364}
1365
1366WL_EXPORT void
1367ivi_layout_remove_notification_remove_surface(surface_remove_notification_func callback,
1368 void *userdata)
1369{
1370 struct ivi_layout *layout = get_instance();
1371 remove_notification(&layout->surface_notification.removed.listener_list, callback, userdata);
1372}
1373
1374WL_EXPORT int32_t
1375ivi_layout_add_notification_configure_surface(surface_configure_notification_func callback,
1376 void *userdata)
1377{
1378 struct ivi_layout *layout = get_instance();
1379 struct ivi_layout_notification_callback *configure_changed_callback = NULL;
1380 if (callback == NULL) {
1381 weston_log("ivi_layout_add_notification_configure_surface: invalid argument\n");
1382 return IVI_FAILED;
1383 }
1384
1385 configure_changed_callback = malloc(sizeof *configure_changed_callback);
1386 if (configure_changed_callback == NULL) {
1387 weston_log("fails to allocate memory\n");
1388 return IVI_FAILED;
1389 }
1390
1391 configure_changed_callback->callback = callback;
1392 configure_changed_callback->data = userdata;
1393
1394 return add_notification(&layout->surface_notification.configure_changed,
1395 surface_configure_changed,
1396 configure_changed_callback);
1397}
1398
1399WL_EXPORT void
1400ivi_layout_remove_notification_configure_surface(surface_configure_notification_func callback,
1401 void *userdata)
1402{
1403 struct ivi_layout *layout = get_instance();
1404 remove_notification(&layout->surface_notification.configure_changed.listener_list, callback, userdata);
1405}
1406
1407WL_EXPORT uint32_t
1408ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf)
1409{
1410 return ivisurf->id_surface;
1411}
1412
1413WL_EXPORT uint32_t
1414ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer)
1415{
1416 return ivilayer->id_layer;
1417}
1418
1419struct ivi_layout_layer *
1420ivi_layout_get_layer_from_id(uint32_t id_layer)
1421{
1422 struct ivi_layout *layout = get_instance();
1423 struct ivi_layout_layer *ivilayer = NULL;
1424
1425 wl_list_for_each(ivilayer, &layout->layer_list, link) {
1426 if (ivilayer->id_layer == id_layer) {
1427 return ivilayer;
1428 }
1429 }
1430
1431 return NULL;
1432}
1433
1434WL_EXPORT struct ivi_layout_surface *
1435ivi_layout_get_surface_from_id(uint32_t id_surface)
1436{
1437 struct ivi_layout *layout = get_instance();
1438 struct ivi_layout_surface *ivisurf = NULL;
1439
1440 wl_list_for_each(ivisurf, &layout->surface_list, link) {
1441 if (ivisurf->id_surface == id_surface) {
1442 return ivisurf;
1443 }
1444 }
1445
1446 return NULL;
1447}
1448
1449WL_EXPORT struct ivi_layout_screen *
1450ivi_layout_get_screen_from_id(uint32_t id_screen)
1451{
1452 struct ivi_layout *layout = get_instance();
1453 struct ivi_layout_screen *iviscrn = NULL;
1454
1455 wl_list_for_each(iviscrn, &layout->screen_list, link) {
1456/* FIXME : select iviscrn from screen_list by id_screen */
1457 return iviscrn;
1458 break;
1459 }
1460
1461 return NULL;
1462}
1463
1464WL_EXPORT int32_t
1465ivi_layout_get_screen_resolution(struct ivi_layout_screen *iviscrn,
1466 int32_t *pWidth, int32_t *pHeight)
1467{
1468 struct weston_output *output = NULL;
1469
1470 if (pWidth == NULL || pHeight == NULL) {
1471 weston_log("ivi_layout_get_screen_resolution: invalid argument\n");
1472 return IVI_FAILED;
1473 }
1474
1475 output = iviscrn->output;
1476 *pWidth = output->current_mode->width;
1477 *pHeight = output->current_mode->height;
1478
1479 return IVI_SUCCEEDED;
1480}
1481
1482WL_EXPORT int32_t
1483ivi_layout_surface_add_notification(struct ivi_layout_surface *ivisurf,
1484 surface_property_notification_func callback,
1485 void *userdata)
1486{
1487 struct listener_layout_notification* notification = NULL;
1488 struct ivi_layout_notification_callback *prop_callback = NULL;
1489
1490 if (ivisurf == NULL || callback == NULL) {
1491 weston_log("ivi_layout_surface_add_notification: invalid argument\n");
1492 return IVI_FAILED;
1493 }
1494
1495 notification = malloc(sizeof *notification);
1496 if (notification == NULL) {
1497 weston_log("fails to allocate memory\n");
1498 return IVI_FAILED;
1499 }
1500
1501 prop_callback = malloc(sizeof *prop_callback);
1502 if (prop_callback == NULL) {
1503 weston_log("fails to allocate memory\n");
1504 return IVI_FAILED;
1505 }
1506
1507 prop_callback->callback = callback;
1508 prop_callback->data = userdata;
1509
1510 notification->listener.notify = surface_prop_changed;
1511 notification->userdata = prop_callback;
1512
1513 wl_signal_add(&ivisurf->property_changed, &notification->listener);
1514
1515 return IVI_SUCCEEDED;
1516}
1517
1518WL_EXPORT void
1519ivi_layout_surface_remove_notification(struct ivi_layout_surface *ivisurf)
1520{
1521 if (ivisurf == NULL) {
1522 weston_log("ivi_layout_surface_remove_notification: invalid argument\n");
1523 return;
1524 }
1525
1526 remove_all_notification(&ivisurf->property_changed.listener_list);
1527}
1528
1529static void
1530remove_configured_listener(struct ivi_layout_surface *ivisurf)
1531{
1532 struct wl_listener *link = NULL;
1533 struct wl_listener *next = NULL;
1534
1535 wl_list_for_each_safe(link, next, &ivisurf->configured.listener_list, link) {
1536 wl_list_remove(&link->link);
1537 }
1538}
1539
1540void
1541ivi_layout_surface_remove(struct ivi_layout_surface *ivisurf)
1542{
1543 struct ivi_layout *layout = get_instance();
1544
1545 if (ivisurf == NULL) {
1546 weston_log("ivi_layout_surface_remove: invalid argument\n");
1547 return;
1548 }
1549
1550 if (!wl_list_empty(&ivisurf->pending.link)) {
1551 wl_list_remove(&ivisurf->pending.link);
1552 }
1553 if (!wl_list_empty(&ivisurf->order.link)) {
1554 wl_list_remove(&ivisurf->order.link);
1555 }
1556 if (!wl_list_empty(&ivisurf->link)) {
1557 wl_list_remove(&ivisurf->link);
1558 }
1559 remove_ordersurface_from_layer(ivisurf);
1560
1561 wl_signal_emit(&layout->surface_notification.removed, ivisurf);
1562
1563 remove_configured_listener(ivisurf);
1564
1565 ivi_layout_surface_remove_notification(ivisurf);
1566
1567 free(ivisurf);
1568}
1569
1570WL_EXPORT const struct ivi_layout_layer_properties *
1571ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer)
1572{
1573 if (ivilayer == NULL) {
1574 weston_log("ivi_layout_get_properties_of_layer: invalid argument\n");
1575 return NULL;
1576 }
1577
1578 return &ivilayer->prop;
1579}
1580
1581WL_EXPORT int32_t
1582ivi_layout_get_screens(int32_t *pLength, struct ivi_layout_screen ***ppArray)
1583{
1584 struct ivi_layout *layout = get_instance();
1585 struct ivi_layout_screen *iviscrn = NULL;
1586 int32_t length = 0;
1587 int32_t n = 0;
1588
1589 if (pLength == NULL || ppArray == NULL) {
1590 weston_log("ivi_layout_get_screens: invalid argument\n");
1591 return IVI_FAILED;
1592 }
1593
1594 length = wl_list_length(&layout->screen_list);
1595
1596 if (length != 0){
1597 /* the Array must be free by module which called this function */
1598 *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
1599 if (*ppArray == NULL) {
1600 weston_log("fails to allocate memory\n");
1601 return IVI_FAILED;
1602 }
1603
1604 wl_list_for_each(iviscrn, &layout->screen_list, link) {
1605 (*ppArray)[n++] = iviscrn;
1606 }
1607 }
1608
1609 *pLength = length;
1610
1611 return IVI_SUCCEEDED;
1612}
1613
1614WL_EXPORT int32_t
1615ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer,
1616 int32_t *pLength,
1617 struct ivi_layout_screen ***ppArray)
1618{
1619 struct link_screen *link_scrn = NULL;
1620 int32_t length = 0;
1621 int32_t n = 0;
1622
1623 if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1624 weston_log("ivi_layout_get_screens_under_layer: invalid argument\n");
1625 return IVI_FAILED;
1626 }
1627
1628 length = wl_list_length(&ivilayer->screen_list);
1629
1630 if (length != 0){
1631 /* the Array must be free by module which called this function */
1632 *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
1633 if (*ppArray == NULL) {
1634 weston_log("fails to allocate memory\n");
1635 return IVI_FAILED;
1636 }
1637
1638 wl_list_for_each(link_scrn, &ivilayer->screen_list, link) {
1639 (*ppArray)[n++] = link_scrn->iviscrn;
1640 }
1641 }
1642
1643 *pLength = length;
1644
1645 return IVI_SUCCEEDED;
1646}
1647
1648WL_EXPORT int32_t
1649ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray)
1650{
1651 struct ivi_layout *layout = get_instance();
1652 struct ivi_layout_layer *ivilayer = NULL;
1653 int32_t length = 0;
1654 int32_t n = 0;
1655
1656 if (pLength == NULL || ppArray == NULL) {
1657 weston_log("ivi_layout_get_layers: invalid argument\n");
1658 return IVI_FAILED;
1659 }
1660
1661 length = wl_list_length(&layout->layer_list);
1662
1663 if (length != 0){
1664 /* the Array must be free by module which called this function */
1665 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1666 if (*ppArray == NULL) {
1667 weston_log("fails to allocate memory\n");
1668 return IVI_FAILED;
1669 }
1670
1671 wl_list_for_each(ivilayer, &layout->layer_list, link) {
1672 (*ppArray)[n++] = ivilayer;
1673 }
1674 }
1675
1676 *pLength = length;
1677
1678 return IVI_SUCCEEDED;
1679}
1680
1681int32_t
1682ivi_layout_get_layers_on_screen(struct ivi_layout_screen *iviscrn,
1683 int32_t *pLength,
1684 struct ivi_layout_layer ***ppArray)
1685{
1686 struct ivi_layout_layer *ivilayer = NULL;
1687 int32_t length = 0;
1688 int32_t n = 0;
1689
1690 if (iviscrn == NULL || pLength == NULL || ppArray == NULL) {
1691 weston_log("ivi_layout_get_layers_on_screen: invalid argument\n");
1692 return IVI_FAILED;
1693 }
1694
1695 length = wl_list_length(&iviscrn->order.layer_list);
1696
1697 if (length != 0){
1698 /* the Array must be free by module which called this function */
1699 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1700 if (*ppArray == NULL) {
1701 weston_log("fails to allocate memory\n");
1702 return IVI_FAILED;
1703 }
1704
1705 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, link) {
1706 (*ppArray)[n++] = ivilayer;
1707 }
1708 }
1709
1710 *pLength = length;
1711
1712 return IVI_SUCCEEDED;
1713}
1714
1715WL_EXPORT int32_t
1716ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf,
1717 int32_t *pLength,
1718 struct ivi_layout_layer ***ppArray)
1719{
1720 struct link_layer *link_layer = NULL;
1721 int32_t length = 0;
1722 int32_t n = 0;
1723
1724 if (ivisurf == NULL || pLength == NULL || ppArray == NULL) {
1725 weston_log("ivi_layout_getLayers: invalid argument\n");
1726 return IVI_FAILED;
1727 }
1728
1729 length = wl_list_length(&ivisurf->layer_list);
1730
1731 if (length != 0){
1732 /* the Array must be free by module which called this function */
1733 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1734 if (*ppArray == NULL) {
1735 weston_log("fails to allocate memory\n");
1736 return IVI_FAILED;
1737 }
1738
1739 wl_list_for_each(link_layer, &ivisurf->layer_list, link) {
1740 (*ppArray)[n++] = link_layer->ivilayer;
1741 }
1742 }
1743
1744 *pLength = length;
1745
1746 return IVI_SUCCEEDED;
1747}
1748
1749WL_EXPORT int32_t
1750ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray)
1751{
1752 struct ivi_layout *layout = get_instance();
1753 struct ivi_layout_surface *ivisurf = NULL;
1754 int32_t length = 0;
1755 int32_t n = 0;
1756
1757 if (pLength == NULL || ppArray == NULL) {
1758 weston_log("ivi_layout_get_surfaces: invalid argument\n");
1759 return IVI_FAILED;
1760 }
1761
1762 length = wl_list_length(&layout->surface_list);
1763
1764 if (length != 0){
1765 /* the Array must be free by module which called this function */
1766 *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1767 if (*ppArray == NULL) {
1768 weston_log("fails to allocate memory\n");
1769 return IVI_FAILED;
1770 }
1771
1772 wl_list_for_each(ivisurf, &layout->surface_list, link) {
1773 (*ppArray)[n++] = ivisurf;
1774 }
1775 }
1776
1777 *pLength = length;
1778
1779 return IVI_SUCCEEDED;
1780}
1781
1782int32_t
1783ivi_layout_get_surfaces_on_layer(struct ivi_layout_layer *ivilayer,
1784 int32_t *pLength,
1785 struct ivi_layout_surface ***ppArray)
1786{
1787 struct ivi_layout_surface *ivisurf = NULL;
1788 int32_t length = 0;
1789 int32_t n = 0;
1790
1791 if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1792 weston_log("ivi_layout_getSurfaceIDsOnLayer: invalid argument\n");
1793 return IVI_FAILED;
1794 }
1795
1796 length = wl_list_length(&ivilayer->order.surface_list);
1797
1798 if (length != 0) {
1799 /* the Array must be free by module which called this function */
1800 *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1801 if (*ppArray == NULL) {
1802 weston_log("fails to allocate memory\n");
1803 return IVI_FAILED;
1804 }
1805
1806 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
1807 (*ppArray)[n++] = ivisurf;
1808 }
1809 }
1810
1811 *pLength = length;
1812
1813 return IVI_SUCCEEDED;
1814}
1815
1816WL_EXPORT struct ivi_layout_layer *
1817ivi_layout_layer_create_with_dimension(uint32_t id_layer,
1818 int32_t width, int32_t height)
1819{
1820 struct ivi_layout *layout = get_instance();
1821 struct ivi_layout_layer *ivilayer = NULL;
1822
1823 ivilayer = get_layer(&layout->layer_list, id_layer);
1824 if (ivilayer != NULL) {
1825 weston_log("id_layer is already created\n");
1826 return ivilayer;
1827 }
1828
1829 ivilayer = calloc(1, sizeof *ivilayer);
1830 if (ivilayer == NULL) {
1831 weston_log("fails to allocate memory\n");
1832 return NULL;
1833 }
1834
1835 wl_list_init(&ivilayer->link);
1836 wl_signal_init(&ivilayer->property_changed);
1837 wl_list_init(&ivilayer->screen_list);
1838 wl_list_init(&ivilayer->link_to_surface);
1839 ivilayer->layout = layout;
1840 ivilayer->id_layer = id_layer;
1841
1842 init_layer_properties(&ivilayer->prop, width, height);
1843 ivilayer->event_mask = 0;
1844
1845 wl_list_init(&ivilayer->pending.surface_list);
1846 wl_list_init(&ivilayer->pending.link);
1847 ivilayer->pending.prop = ivilayer->prop;
1848
1849 wl_list_init(&ivilayer->order.surface_list);
1850 wl_list_init(&ivilayer->order.link);
1851
1852 wl_list_insert(&layout->layer_list, &ivilayer->link);
1853
1854 wl_signal_emit(&layout->layer_notification.created, ivilayer);
1855
1856 return ivilayer;
1857}
1858
1859WL_EXPORT void
1860ivi_layout_layer_remove(struct ivi_layout_layer *ivilayer)
1861{
1862 struct ivi_layout *layout = get_instance();
1863
1864 if (ivilayer == NULL) {
1865 weston_log("ivi_layout_layer_remove: invalid argument\n");
1866 return;
1867 }
1868
1869 wl_signal_emit(&layout->layer_notification.removed, ivilayer);
1870
1871 clear_surface_pending_list(ivilayer);
1872 clear_surface_order_list(ivilayer);
1873
1874 if (!wl_list_empty(&ivilayer->pending.link)) {
1875 wl_list_remove(&ivilayer->pending.link);
1876 }
1877 if (!wl_list_empty(&ivilayer->order.link)) {
1878 wl_list_remove(&ivilayer->order.link);
1879 }
1880 if (!wl_list_empty(&ivilayer->link)) {
1881 wl_list_remove(&ivilayer->link);
1882 }
1883 remove_orderlayer_from_screen(ivilayer);
1884 remove_link_to_surface(ivilayer);
1885 ivi_layout_layer_remove_notification(ivilayer);
1886
1887 free(ivilayer);
1888}
1889
1890WL_EXPORT int32_t
1891ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer,
1892 bool newVisibility)
1893{
1894 struct ivi_layout_layer_properties *prop = NULL;
1895
1896 if (ivilayer == NULL) {
1897 weston_log("ivi_layout_layer_set_visibility: invalid argument\n");
1898 return IVI_FAILED;
1899 }
1900
1901 prop = &ivilayer->pending.prop;
1902 prop->visibility = newVisibility;
1903
1904 ivilayer->event_mask |= IVI_NOTIFICATION_VISIBILITY;
1905
1906 return IVI_SUCCEEDED;
1907}
1908
1909bool
1910ivi_layout_layer_get_visibility(struct ivi_layout_layer *ivilayer)
1911{
1912 if (ivilayer == NULL) {
1913 weston_log("ivi_layout_layer_get_visibility: invalid argument\n");
1914 return false;
1915 }
1916
1917 return ivilayer->prop.visibility;
1918}
1919
1920WL_EXPORT int32_t
1921ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
1922 wl_fixed_t opacity)
1923{
1924 struct ivi_layout_layer_properties *prop = NULL;
1925
1926 if (ivilayer == NULL) {
1927 weston_log("ivi_layout_layer_set_opacity: invalid argument\n");
1928 return IVI_FAILED;
1929 }
1930
1931 prop = &ivilayer->pending.prop;
1932 prop->opacity = opacity;
1933
1934 ivilayer->event_mask |= IVI_NOTIFICATION_OPACITY;
1935
1936 return IVI_SUCCEEDED;
1937}
1938
1939WL_EXPORT wl_fixed_t
1940ivi_layout_layer_get_opacity(struct ivi_layout_layer *ivilayer)
1941{
1942 if (ivilayer == NULL) {
1943 weston_log("ivi_layout_layer_get_opacity: invalid argument\n");
1944 return wl_fixed_from_double(0.0);
1945 }
1946
1947 return ivilayer->prop.opacity;
1948}
1949
1950WL_EXPORT int32_t
1951ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer,
1952 int32_t x, int32_t y,
1953 int32_t width, int32_t height)
1954{
1955 struct ivi_layout_layer_properties *prop = NULL;
1956
1957 if (ivilayer == NULL) {
1958 weston_log("ivi_layout_layer_set_source_rectangle: invalid argument\n");
1959 return IVI_FAILED;
1960 }
1961
1962 prop = &ivilayer->pending.prop;
1963 prop->source_x = x;
1964 prop->source_y = y;
1965 prop->source_width = width;
1966 prop->source_height = height;
1967
1968 ivilayer->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
1969
1970 return IVI_SUCCEEDED;
1971}
1972
1973WL_EXPORT int32_t
1974ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer,
1975 int32_t x, int32_t y,
1976 int32_t width, int32_t height)
1977{
1978 struct ivi_layout_layer_properties *prop = NULL;
1979
1980 if (ivilayer == NULL) {
1981 weston_log("ivi_layout_layer_set_destination_rectangle: invalid argument\n");
1982 return IVI_FAILED;
1983 }
1984
1985 prop = &ivilayer->pending.prop;
1986 prop->dest_x = x;
1987 prop->dest_y = y;
1988 prop->dest_width = width;
1989 prop->dest_height = height;
1990
1991 ivilayer->event_mask |= IVI_NOTIFICATION_DEST_RECT;
1992
1993 return IVI_SUCCEEDED;
1994}
1995
1996int32_t
1997ivi_layout_layer_get_dimension(struct ivi_layout_layer *ivilayer,
1998 int32_t *dest_width, int32_t *dest_height)
1999{
2000 if (ivilayer == NULL || dest_width == NULL || dest_height == NULL) {
2001 weston_log("ivi_layout_layer_get_dimension: invalid argument\n");
2002 return IVI_FAILED;
2003 }
2004
2005 *dest_width = ivilayer->prop.dest_width;
2006 *dest_height = ivilayer->prop.dest_height;
2007
2008 return IVI_SUCCEEDED;
2009}
2010
2011int32_t
2012ivi_layout_layer_set_dimension(struct ivi_layout_layer *ivilayer,
2013 int32_t dest_width, int32_t dest_height)
2014{
2015 struct ivi_layout_layer_properties *prop = NULL;
2016
2017 if (ivilayer == NULL) {
2018 weston_log("ivi_layout_layer_set_dimension: invalid argument\n");
2019 return IVI_FAILED;
2020 }
2021
2022 prop = &ivilayer->pending.prop;
2023
2024 prop->dest_width = dest_width;
2025 prop->dest_height = dest_height;
2026
2027 ivilayer->event_mask |= IVI_NOTIFICATION_DIMENSION;
2028
2029 return IVI_SUCCEEDED;
2030}
2031
2032WL_EXPORT int32_t
2033ivi_layout_layer_get_position(struct ivi_layout_layer *ivilayer,
2034 int32_t *dest_x, int32_t *dest_y)
2035{
2036 if (ivilayer == NULL || dest_x == NULL || dest_y == NULL) {
2037 weston_log("ivi_layout_layer_get_position: invalid argument\n");
2038 return IVI_FAILED;
2039 }
2040
2041 *dest_x = ivilayer->prop.dest_x;
2042 *dest_y = ivilayer->prop.dest_y;
2043
2044 return IVI_SUCCEEDED;
2045}
2046
2047WL_EXPORT int32_t
2048ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer,
2049 int32_t dest_x, int32_t dest_y)
2050{
2051 struct ivi_layout_layer_properties *prop = NULL;
2052
2053 if (ivilayer == NULL) {
2054 weston_log("ivi_layout_layer_set_position: invalid argument\n");
2055 return IVI_FAILED;
2056 }
2057
2058 prop = &ivilayer->pending.prop;
2059 prop->dest_x = dest_x;
2060 prop->dest_y = dest_y;
2061
2062 ivilayer->event_mask |= IVI_NOTIFICATION_POSITION;
2063
2064 return IVI_SUCCEEDED;
2065}
2066
2067WL_EXPORT int32_t
2068ivi_layout_layer_set_orientation(struct ivi_layout_layer *ivilayer,
2069 enum wl_output_transform orientation)
2070{
2071 struct ivi_layout_layer_properties *prop = NULL;
2072
2073 if (ivilayer == NULL) {
2074 weston_log("ivi_layout_layer_set_orientation: invalid argument\n");
2075 return IVI_FAILED;
2076 }
2077
2078 prop = &ivilayer->pending.prop;
2079 prop->orientation = orientation;
2080
2081 ivilayer->event_mask |= IVI_NOTIFICATION_ORIENTATION;
2082
2083 return IVI_SUCCEEDED;
2084}
2085
2086enum wl_output_transform
2087ivi_layout_layer_get_orientation(struct ivi_layout_layer *ivilayer)
2088{
2089 if (ivilayer == NULL) {
2090 weston_log("ivi_layout_layer_get_orientation: invalid argument\n");
2091 return 0;
2092 }
2093
2094 return ivilayer->prop.orientation;
2095}
2096
2097WL_EXPORT int32_t
2098ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
2099 struct ivi_layout_surface **pSurface,
2100 int32_t number)
2101{
2102 struct ivi_layout *layout = get_instance();
2103 struct ivi_layout_surface *ivisurf = NULL;
2104 struct ivi_layout_surface *next = NULL;
2105 uint32_t *id_surface = NULL;
2106 int32_t i = 0;
2107
2108 if (ivilayer == NULL) {
2109 weston_log("ivi_layout_layer_set_render_order: invalid argument\n");
2110 return IVI_FAILED;
2111 }
2112
2113 if (pSurface == NULL) {
2114 wl_list_for_each_safe(ivisurf, next, &ivilayer->pending.surface_list, pending.link) {
2115 if (!wl_list_empty(&ivisurf->pending.link)) {
2116 wl_list_remove(&ivisurf->pending.link);
2117 }
2118
2119 wl_list_init(&ivisurf->pending.link);
2120 }
2121 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
2122 return IVI_SUCCEEDED;
2123 }
2124
2125 for (i = 0; i < number; i++) {
2126 id_surface = &pSurface[i]->id_surface;
2127
2128 wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
2129 if (*id_surface != ivisurf->id_surface) {
2130 continue;
2131 }
2132
2133 if (!wl_list_empty(&ivisurf->pending.link)) {
2134 wl_list_remove(&ivisurf->pending.link);
2135 }
2136 wl_list_init(&ivisurf->pending.link);
2137 wl_list_insert(&ivilayer->pending.surface_list,
2138 &ivisurf->pending.link);
2139 break;
2140 }
2141 }
2142
2143 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
2144
2145 return IVI_SUCCEEDED;
2146}
2147
2148WL_EXPORT int32_t
2149ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf,
2150 bool newVisibility)
2151{
2152 struct ivi_layout_surface_properties *prop = NULL;
2153
2154 if (ivisurf == NULL) {
2155 weston_log("ivi_layout_surface_set_visibility: invalid argument\n");
2156 return IVI_FAILED;
2157 }
2158
2159 prop = &ivisurf->pending.prop;
2160 prop->visibility = newVisibility;
2161
2162 ivisurf->event_mask |= IVI_NOTIFICATION_VISIBILITY;
2163
2164 return IVI_SUCCEEDED;
2165}
2166
2167WL_EXPORT bool
2168ivi_layout_surface_get_visibility(struct ivi_layout_surface *ivisurf)
2169{
2170 if (ivisurf == NULL) {
2171 weston_log("ivi_layout_surface_get_visibility: invalid argument\n");
2172 return false;
2173 }
2174
2175 return ivisurf->prop.visibility;
2176}
2177
2178WL_EXPORT int32_t
2179ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
2180 wl_fixed_t opacity)
2181{
2182 struct ivi_layout_surface_properties *prop = NULL;
2183
2184 if (ivisurf == NULL) {
2185 weston_log("ivi_layout_surface_set_opacity: invalid argument\n");
2186 return IVI_FAILED;
2187 }
2188
2189 prop = &ivisurf->pending.prop;
2190 prop->opacity = opacity;
2191
2192 ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY;
2193
2194 return IVI_SUCCEEDED;
2195}
2196
2197WL_EXPORT wl_fixed_t
2198ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf)
2199{
2200 if (ivisurf == NULL) {
2201 weston_log("ivi_layout_surface_get_opacity: invalid argument\n");
2202 return wl_fixed_from_double(0.0);
2203 }
2204
2205 return ivisurf->prop.opacity;
2206}
2207
2208WL_EXPORT int32_t
2209ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
2210 int32_t x, int32_t y,
2211 int32_t width, int32_t height)
2212{
2213 struct ivi_layout_surface_properties *prop = NULL;
2214
2215 if (ivisurf == NULL) {
2216 weston_log("ivi_layout_surface_set_destination_rectangle: invalid argument\n");
2217 return IVI_FAILED;
2218 }
2219
2220 prop = &ivisurf->pending.prop;
2221 prop->start_x = prop->dest_x;
2222 prop->start_y = prop->dest_y;
2223 prop->dest_x = x;
2224 prop->dest_y = y;
2225 prop->start_width = prop->dest_width;
2226 prop->start_height = prop->dest_height;
2227 prop->dest_width = width;
2228 prop->dest_height = height;
2229
2230 ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT;
2231
2232 return IVI_SUCCEEDED;
2233}
2234
2235int32_t
2236ivi_layout_surface_set_dimension(struct ivi_layout_surface *ivisurf,
2237 int32_t dest_width, int32_t dest_height)
2238{
2239 struct ivi_layout_surface_properties *prop = NULL;
2240
2241 if (ivisurf == NULL) {
2242 weston_log("ivi_layout_surface_set_dimension: invalid argument\n");
2243 return IVI_FAILED;
2244 }
2245
2246 prop = &ivisurf->pending.prop;
2247 prop->dest_width = dest_width;
2248 prop->dest_height = dest_height;
2249
2250 ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION;
2251
2252 return IVI_SUCCEEDED;
2253}
2254
2255int32_t
2256ivi_layout_surface_get_dimension(struct ivi_layout_surface *ivisurf,
2257 int32_t *dest_width, int32_t *dest_height)
2258{
2259 if (ivisurf == NULL || dest_width == NULL || dest_height == NULL) {
2260 weston_log("ivi_layout_surface_get_dimension: invalid argument\n");
2261 return IVI_FAILED;
2262 }
2263
2264 *dest_width = ivisurf->prop.dest_width;
2265 *dest_height = ivisurf->prop.dest_height;
2266
2267 return IVI_SUCCEEDED;
2268}
2269
2270int32_t
2271ivi_layout_surface_set_position(struct ivi_layout_surface *ivisurf,
2272 int32_t dest_x, int32_t dest_y)
2273{
2274 struct ivi_layout_surface_properties *prop = NULL;
2275
2276 if (ivisurf == NULL) {
2277 weston_log("ivi_layout_surface_set_position: invalid argument\n");
2278 return IVI_FAILED;
2279 }
2280
2281 prop = &ivisurf->pending.prop;
2282 prop->dest_x = dest_x;
2283 prop->dest_y = dest_y;
2284
2285 ivisurf->event_mask |= IVI_NOTIFICATION_POSITION;
2286
2287 return IVI_SUCCEEDED;
2288}
2289
2290int32_t
2291ivi_layout_surface_get_position(struct ivi_layout_surface *ivisurf,
2292 int32_t *dest_x, int32_t *dest_y)
2293{
2294 if (ivisurf == NULL || dest_x == NULL || dest_y == NULL) {
2295 weston_log("ivi_layout_surface_get_position: invalid argument\n");
2296 return IVI_FAILED;
2297 }
2298
2299 *dest_x = ivisurf->prop.dest_x;
2300 *dest_y = ivisurf->prop.dest_y;
2301
2302 return IVI_SUCCEEDED;
2303}
2304
2305WL_EXPORT int32_t
2306ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf,
2307 enum wl_output_transform orientation)
2308{
2309 struct ivi_layout_surface_properties *prop = NULL;
2310
2311 if (ivisurf == NULL) {
2312 weston_log("ivi_layout_surface_set_orientation: invalid argument\n");
2313 return IVI_FAILED;
2314 }
2315
2316 prop = &ivisurf->pending.prop;
2317 prop->orientation = orientation;
2318
2319 ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION;
2320
2321 return IVI_SUCCEEDED;
2322}
2323
2324enum wl_output_transform
2325ivi_layout_surface_get_orientation(struct ivi_layout_surface *ivisurf)
2326{
2327 if (ivisurf == NULL) {
2328 weston_log("ivi_layout_surface_get_orientation: invalid argument\n");
2329 return 0;
2330 }
2331
2332 return ivisurf->prop.orientation;
2333}
2334
2335WL_EXPORT int32_t
2336ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn,
2337 struct ivi_layout_layer *addlayer)
2338{
2339 struct ivi_layout *layout = get_instance();
2340 struct ivi_layout_layer *ivilayer = NULL;
2341 struct ivi_layout_layer *next = NULL;
2342 int is_layer_in_scrn = 0;
2343
2344 if (iviscrn == NULL || addlayer == NULL) {
2345 weston_log("ivi_layout_screen_add_layer: invalid argument\n");
2346 return IVI_FAILED;
2347 }
2348
2349 is_layer_in_scrn = is_layer_in_screen(addlayer, iviscrn);
2350 if (is_layer_in_scrn == 1) {
2351 weston_log("ivi_layout_screen_add_layer: addlayer is already available\n");
2352 return IVI_SUCCEEDED;
2353 }
2354
2355 wl_list_for_each_safe(ivilayer, next, &layout->layer_list, link) {
2356 if (ivilayer->id_layer == addlayer->id_layer) {
2357 if (!wl_list_empty(&ivilayer->pending.link)) {
2358 wl_list_remove(&ivilayer->pending.link);
2359 }
2360 wl_list_init(&ivilayer->pending.link);
2361 wl_list_insert(&iviscrn->pending.layer_list,
2362 &ivilayer->pending.link);
2363 break;
2364 }
2365 }
2366
2367 iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
2368
2369 return IVI_SUCCEEDED;
2370}
2371
2372WL_EXPORT int32_t
2373ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn,
2374 struct ivi_layout_layer **pLayer,
2375 const int32_t number)
2376{
2377 struct ivi_layout *layout = get_instance();
2378 struct ivi_layout_layer *ivilayer = NULL;
2379 struct ivi_layout_layer *next = NULL;
2380 uint32_t *id_layer = NULL;
2381 int32_t i = 0;
2382
2383 if (iviscrn == NULL) {
2384 weston_log("ivi_layout_screen_set_render_order: invalid argument\n");
2385 return IVI_FAILED;
2386 }
2387
2388 wl_list_for_each_safe(ivilayer, next,
2389 &iviscrn->pending.layer_list, pending.link) {
2390 wl_list_init(&ivilayer->pending.link);
2391 }
2392
2393 wl_list_init(&iviscrn->pending.layer_list);
2394
2395 if (pLayer == NULL) {
2396 wl_list_for_each_safe(ivilayer, next, &iviscrn->pending.layer_list, pending.link) {
2397 if (!wl_list_empty(&ivilayer->pending.link)) {
2398 wl_list_remove(&ivilayer->pending.link);
2399 }
2400
2401 wl_list_init(&ivilayer->pending.link);
2402 }
2403
2404 iviscrn->event_mask |= IVI_NOTIFICATION_REMOVE;
2405 return IVI_SUCCEEDED;
2406 }
2407
2408 for (i = 0; i < number; i++) {
2409 id_layer = &pLayer[i]->id_layer;
2410 wl_list_for_each(ivilayer, &layout->layer_list, link) {
2411 if (*id_layer != ivilayer->id_layer) {
2412 continue;
2413 }
2414
2415 if (!wl_list_empty(&ivilayer->pending.link)) {
2416 wl_list_remove(&ivilayer->pending.link);
2417 }
2418 wl_list_init(&ivilayer->pending.link);
2419 wl_list_insert(&iviscrn->pending.layer_list,
2420 &ivilayer->pending.link);
2421 break;
2422 }
2423 }
2424
2425 iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
2426
2427 return IVI_SUCCEEDED;
2428}
2429
2430WL_EXPORT struct weston_output *
2431ivi_layout_screen_get_output(struct ivi_layout_screen *iviscrn)
2432{
2433 return iviscrn->output;
2434}
2435
2436/**
2437 * This function is used by the additional ivi-module because of dumping ivi_surface sceenshot.
2438 * The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of Genivi's Layer Management.
2439 * This function is used to get the result of drawing by clients.
2440 */
2441WL_EXPORT struct weston_surface *
2442ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf)
2443{
2444 return ivisurf != NULL ? ivisurf->surface : NULL;
2445}
2446
2447WL_EXPORT int32_t
2448ivi_layout_layer_add_notification(struct ivi_layout_layer *ivilayer,
2449 layer_property_notification_func callback,
2450 void *userdata)
2451{
2452 struct ivi_layout_notification_callback *prop_callback = NULL;
2453
2454 if (ivilayer == NULL || callback == NULL) {
2455 weston_log("ivi_layout_layer_add_notification: invalid argument\n");
2456 return IVI_FAILED;
2457 }
2458
2459 prop_callback = malloc(sizeof *prop_callback);
2460 if (prop_callback == NULL) {
2461 weston_log("fails to allocate memory\n");
2462 return IVI_FAILED;
2463 }
2464
2465 prop_callback->callback = callback;
2466 prop_callback->data = userdata;
2467
2468 return add_notification(&ivilayer->property_changed,
2469 layer_prop_changed,
2470 prop_callback);
2471}
2472
2473WL_EXPORT void
2474ivi_layout_layer_remove_notification(struct ivi_layout_layer *ivilayer)
2475{
2476 if (ivilayer == NULL) {
2477 weston_log("ivi_layout_layer_remove_notification: invalid argument\n");
2478 return;
2479 }
2480
2481 remove_all_notification(&ivilayer->property_changed.listener_list);
2482}
2483
2484WL_EXPORT const struct ivi_layout_surface_properties *
2485ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf)
2486{
2487 if (ivisurf == NULL) {
2488 weston_log("ivi_layout_get_properties_of_surface: invalid argument\n");
2489 return NULL;
2490 }
2491
2492 return &ivisurf->prop;
2493}
2494
2495WL_EXPORT int32_t
2496ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer,
2497 struct ivi_layout_surface *addsurf)
2498{
2499 struct ivi_layout *layout = get_instance();
2500 struct ivi_layout_surface *ivisurf = NULL;
2501 struct ivi_layout_surface *next = NULL;
2502 int is_surf_in_layer = 0;
2503
2504 if (ivilayer == NULL || addsurf == NULL) {
2505 weston_log("ivi_layout_layer_add_surface: invalid argument\n");
2506 return IVI_FAILED;
2507 }
2508
2509 is_surf_in_layer = is_surface_in_layer(addsurf, ivilayer);
2510 if (is_surf_in_layer == 1) {
2511 weston_log("ivi_layout_layer_add_surface: addsurf is already available\n");
2512 return IVI_SUCCEEDED;
2513 }
2514
2515 wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
2516 if (ivisurf->id_surface == addsurf->id_surface) {
2517 if (!wl_list_empty(&ivisurf->pending.link)) {
2518 wl_list_remove(&ivisurf->pending.link);
2519 }
2520 wl_list_init(&ivisurf->pending.link);
2521 wl_list_insert(&ivilayer->pending.surface_list,
2522 &ivisurf->pending.link);
2523 break;
2524 }
2525 }
2526
2527 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
2528
2529 return IVI_SUCCEEDED;
2530}
2531
2532WL_EXPORT void
2533ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer,
2534 struct ivi_layout_surface *remsurf)
2535{
2536 struct ivi_layout_surface *ivisurf = NULL;
2537 struct ivi_layout_surface *next = NULL;
2538
2539 if (ivilayer == NULL || remsurf == NULL) {
2540 weston_log("ivi_layout_layer_remove_surface: invalid argument\n");
2541 return;
2542 }
2543
2544 wl_list_for_each_safe(ivisurf, next,
2545 &ivilayer->pending.surface_list, pending.link) {
2546 if (ivisurf->id_surface == remsurf->id_surface) {
2547 if (!wl_list_empty(&ivisurf->pending.link)) {
2548 wl_list_remove(&ivisurf->pending.link);
2549 }
2550 wl_list_init(&ivisurf->pending.link);
2551 break;
2552 }
2553 }
2554
2555 remsurf->event_mask |= IVI_NOTIFICATION_REMOVE;
2556}
2557
2558WL_EXPORT int32_t
2559ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf,
2560 int32_t x, int32_t y,
2561 int32_t width, int32_t height)
2562{
2563 struct ivi_layout_surface_properties *prop = NULL;
2564
2565 if (ivisurf == NULL) {
2566 weston_log("ivi_layout_surface_set_source_rectangle: invalid argument\n");
2567 return IVI_FAILED;
2568 }
2569
2570 prop = &ivisurf->pending.prop;
2571 prop->source_x = x;
2572 prop->source_y = y;
2573 prop->source_width = width;
2574 prop->source_height = height;
2575
2576 ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
2577
2578 return IVI_SUCCEEDED;
2579}
2580
2581WL_EXPORT int32_t
2582ivi_layout_commit_changes(void)
2583{
2584 struct ivi_layout *layout = get_instance();
2585
2586 commit_surface_list(layout);
2587 commit_layer_list(layout);
2588 commit_screen_list(layout);
2589
2590 commit_transition(layout);
2591
2592 commit_changes(layout);
2593 send_prop(layout);
2594 weston_compositor_schedule_repaint(layout->compositor);
2595
2596 return IVI_SUCCEEDED;
2597}
2598
2599/***called from ivi-shell**/
2600static struct weston_view *
2601ivi_layout_get_weston_view(struct ivi_layout_surface *surface)
2602{
2603 struct weston_view *tmpview = NULL;
2604
2605 if(surface == NULL)
2606 return NULL;
2607
2608 wl_list_for_each(tmpview, &surface->surface->views, surface_link)
2609 {
2610 if (tmpview != NULL) {
2611 break;
2612 }
2613 }
2614 return tmpview;
2615}
2616
2617static void
2618ivi_layout_surface_configure(struct ivi_layout_surface *ivisurf,
2619 int32_t width, int32_t height)
2620{
2621 struct ivi_layout *layout = get_instance();
2622 int32_t in_init = 0;
2623 ivisurf->surface->width_from_buffer = width;
2624 ivisurf->surface->height_from_buffer = height;
2625
2626 if (ivisurf->prop.source_width == 0 || ivisurf->prop.source_height == 0) {
2627 in_init = 1;
2628 }
2629
2630 /* FIXME: when sourceHeight/Width is used as clipping range in image buffer */
2631 /* if (ivisurf->prop.sourceWidth == 0 || ivisurf->prop.sourceHeight == 0) { */
2632 ivisurf->pending.prop.source_width = width;
2633 ivisurf->pending.prop.source_height = height;
2634 ivisurf->prop.source_width = width;
2635 ivisurf->prop.source_height = height;
2636 /* } */
2637
2638 ivisurf->event_mask |= IVI_NOTIFICATION_CONFIGURE;
2639
2640 if (in_init) {
2641 wl_signal_emit(&layout->surface_notification.configure_changed, ivisurf);
2642 } else {
2643 ivi_layout_commit_changes();
2644 }
2645}
2646
2647WL_EXPORT int32_t
2648ivi_layout_surface_set_content_observer(struct ivi_layout_surface *ivisurf,
2649 ivi_controller_surface_content_callback callback,
2650 void* userdata)
2651{
2652 int32_t ret = IVI_FAILED;
2653
2654 if (ivisurf != NULL) {
2655 ivisurf->content_observer.callback = callback;
2656 ivisurf->content_observer.userdata = userdata;
2657 ret = IVI_SUCCEEDED;
2658 }
2659 return ret;
2660}
2661
2662static struct ivi_layout_surface*
2663ivi_layout_surface_create(struct weston_surface *wl_surface,
2664 uint32_t id_surface)
2665{
2666 struct ivi_layout *layout = get_instance();
2667 struct ivi_layout_surface *ivisurf = NULL;
2668 struct weston_view *tmpview = NULL;
2669
2670 if (wl_surface == NULL) {
2671 weston_log("ivi_layout_surface_create: invalid argument\n");
2672 return NULL;
2673 }
2674
2675 ivisurf = get_surface(&layout->surface_list, id_surface);
2676 if (ivisurf != NULL) {
2677 if (ivisurf->surface != NULL) {
2678 weston_log("id_surface(%d) is already created\n", id_surface);
2679 return NULL;
2680 }
2681 }
2682
2683 ivisurf = calloc(1, sizeof *ivisurf);
2684 if (ivisurf == NULL) {
2685 weston_log("fails to allocate memory\n");
2686 return NULL;
2687 }
2688
2689 wl_list_init(&ivisurf->link);
2690 wl_signal_init(&ivisurf->property_changed);
2691 wl_signal_init(&ivisurf->configured);
2692 wl_list_init(&ivisurf->layer_list);
2693 ivisurf->id_surface = id_surface;
2694 ivisurf->layout = layout;
2695
2696 ivisurf->surface = wl_surface;
2697 ivisurf->surface_destroy_listener.notify =
2698 westonsurface_destroy_from_ivisurface;
2699 wl_resource_add_destroy_listener(wl_surface->resource,
2700 &ivisurf->surface_destroy_listener);
2701
2702 tmpview = weston_view_create(wl_surface);
2703 if (tmpview == NULL) {
2704 weston_log("fails to allocate memory\n");
2705 }
2706
2707 ivisurf->surface->width_from_buffer = 0;
2708 ivisurf->surface->height_from_buffer = 0;
2709
2710 weston_matrix_init(&ivisurf->surface_rotation.matrix);
2711 weston_matrix_init(&ivisurf->layer_rotation.matrix);
2712 weston_matrix_init(&ivisurf->surface_pos.matrix);
2713 weston_matrix_init(&ivisurf->layer_pos.matrix);
2714 weston_matrix_init(&ivisurf->scaling.matrix);
2715
2716 wl_list_init(&ivisurf->surface_rotation.link);
2717 wl_list_init(&ivisurf->layer_rotation.link);
2718 wl_list_init(&ivisurf->surface_pos.link);
2719 wl_list_init(&ivisurf->layer_pos.link);
2720 wl_list_init(&ivisurf->scaling.link);
2721
2722 init_surface_properties(&ivisurf->prop);
2723 ivisurf->event_mask = 0;
2724
2725 ivisurf->pending.prop = ivisurf->prop;
2726 wl_list_init(&ivisurf->pending.link);
2727
2728 wl_list_init(&ivisurf->order.link);
2729 wl_list_init(&ivisurf->order.layer_list);
2730
2731 wl_list_insert(&layout->surface_list, &ivisurf->link);
2732
2733 wl_signal_emit(&layout->surface_notification.created, ivisurf);
2734
2735 return ivisurf;
2736}
2737
2738static void
2739ivi_layout_init_with_compositor(struct weston_compositor *ec)
2740{
2741 struct ivi_layout *layout = get_instance();
2742
2743 layout->compositor = ec;
2744
2745 wl_list_init(&layout->surface_list);
2746 wl_list_init(&layout->layer_list);
2747 wl_list_init(&layout->screen_list);
2748
2749 wl_signal_init(&layout->layer_notification.created);
2750 wl_signal_init(&layout->layer_notification.removed);
2751
2752 wl_signal_init(&layout->surface_notification.created);
2753 wl_signal_init(&layout->surface_notification.removed);
2754 wl_signal_init(&layout->surface_notification.configure_changed);
2755
2756 /* Add layout_layer at the last of weston_compositor.layer_list */
2757 weston_layer_init(&layout->layout_layer, ec->layer_list.prev);
2758
2759 create_screen(ec);
2760
2761 layout->transitions = ivi_layout_transition_set_create(ec);
2762 wl_list_init(&layout->pending_transition_list);
2763}
2764
2765
2766static void
2767ivi_layout_surface_add_configured_listener(struct ivi_layout_surface* ivisurf,
2768 struct wl_listener* listener)
2769{
2770 wl_signal_add(&ivisurf->configured, listener);
2771}
2772
2773WL_EXPORT struct ivi_layout_interface ivi_layout_interface = {
2774 .get_weston_view = ivi_layout_get_weston_view,
2775 .surface_configure = ivi_layout_surface_configure,
2776 .surface_create = ivi_layout_surface_create,
2777 .init_with_compositor = ivi_layout_init_with_compositor,
2778 .get_surface_dimension = ivi_layout_surface_get_dimension,
2779 .add_surface_configured_listener = ivi_layout_surface_add_configured_listener
2780};