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