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