blob: cf3fa68ec2bfac2acea143f68b3681223befa59c [file] [log] [blame]
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001/*
2 * Copyright (C) 2013 DENSO CORPORATION
3 *
Bryce Harringtonaf637c22015-06-11 12:55:55 -07004 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090011 *
Bryce Harringtonaf637c22015-06-11 12:55:55 -070012 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090024 */
25
26/**
27 * Implementation of ivi-layout library. The actual view on ivi_screen is
28 * not updated till calling ivi_layout_commit_changes. A overview from
29 * calling API for updating properties of ivi_surface/ivi_layer to asking
30 * compositor to compose them by using weston_compositor_schedule_repaint,
31 * 0/ initialize this library by ivi_layout_init_with_compositor
32 * with (struct weston_compositor *ec) from ivi-shell.
33 * 1/ When a API for updating properties of ivi_surface/ivi_layer, it updates
34 * pending prop of ivi_surface/ivi_layer/ivi_screen which are structure to
35 * store properties.
36 * 2/ Before calling commitChanges, in case of calling a API to get a property,
37 * return current property, not pending property.
38 * 3/ At the timing of calling ivi_layout_commitChanges, pending properties
39 * are applied to properties.
40 *
41 * *) ivi_layout_commitChanges is also called by transition animation
42 * per each frame. See ivi-layout-transition.c in details. Transition
43 * animation interpolates frames between previous properties of ivi_surface
44 * and new ones.
45 * For example, when a property of ivi_surface is changed from invisibility
46 * to visibility, it behaves like fade-in. When ivi_layout_commitChange is
47 * called during transition animation, it cancels the transition and
48 * re-start transition to new properties from current properties of final
49 * frame just before the the cancellation.
50 *
51 * 4/ According properties, set transformation by using weston_matrix and
52 * weston_view per ivi_surfaces and ivi_layers in while loop.
53 * 5/ Set damage and trigger transform by using weston_view_geometry_dirty.
54 * 6/ Notify update of properties.
55 * 7/ Trigger composition by weston_compositor_schedule_repaint.
56 *
57 */
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +090058#include "config.h"
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090059
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090060#include <string.h>
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090061
62#include "compositor.h"
63#include "ivi-layout-export.h"
64#include "ivi-layout-private.h"
65
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +090066#include "../shared/os-compatibility.h"
67
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090068struct link_layer {
69 struct ivi_layout_layer *ivilayer;
70 struct wl_list link;
71 struct wl_list link_to_layer;
72};
73
74struct link_screen {
75 struct ivi_layout_screen *iviscrn;
76 struct wl_list link;
77 struct wl_list link_to_screen;
78};
79
80struct listener_layout_notification {
81 void *userdata;
82 struct wl_listener listener;
83};
84
85struct ivi_layout;
86
87struct ivi_layout_screen {
88 struct wl_list link;
89 struct wl_list link_to_layer;
90 uint32_t id_screen;
91
92 struct ivi_layout *layout;
93 struct weston_output *output;
94
95 uint32_t event_mask;
96
97 struct {
98 struct wl_list layer_list;
99 struct wl_list link;
100 } pending;
101
102 struct {
103 struct wl_list layer_list;
104 struct wl_list link;
105 } order;
106};
107
108struct ivi_layout_notification_callback {
109 void *callback;
110 void *data;
111};
112
113static struct ivi_layout ivilayout = {0};
114
115struct ivi_layout *
116get_instance(void)
117{
118 return &ivilayout;
119}
120
121/**
122 * Internal API to add/remove a link to ivi_surface from ivi_layer.
123 */
124static void
125add_link_to_surface(struct ivi_layout_layer *ivilayer,
126 struct link_layer *link_layer)
127{
128 struct link_layer *link = NULL;
129
130 wl_list_for_each(link, &ivilayer->link_to_surface, link_to_layer) {
131 if (link == link_layer)
132 return;
133 }
134
135 wl_list_insert(&ivilayer->link_to_surface, &link_layer->link_to_layer);
136}
137
138static void
139remove_link_to_surface(struct ivi_layout_layer *ivilayer)
140{
141 struct link_layer *link = NULL;
142 struct link_layer *next = NULL;
143
144 wl_list_for_each_safe(link, next, &ivilayer->link_to_surface, link_to_layer) {
145 if (!wl_list_empty(&link->link_to_layer)) {
146 wl_list_remove(&link->link_to_layer);
147 }
148 if (!wl_list_empty(&link->link)) {
149 wl_list_remove(&link->link);
150 }
151 free(link);
152 }
153
154 wl_list_init(&ivilayer->link_to_surface);
155}
156
157/**
158 * Internal API to add a link to ivi_layer from ivi_screen.
159 */
160static void
161add_link_to_layer(struct ivi_layout_screen *iviscrn,
162 struct link_screen *link_screen)
163{
164 wl_list_init(&link_screen->link_to_screen);
165 wl_list_insert(&iviscrn->link_to_layer, &link_screen->link_to_screen);
166}
167
168/**
169 * Internal API to add/remove a ivi_surface from ivi_layer.
170 */
171static void
172add_ordersurface_to_layer(struct ivi_layout_surface *ivisurf,
173 struct ivi_layout_layer *ivilayer)
174{
175 struct link_layer *link_layer = NULL;
176
177 link_layer = malloc(sizeof *link_layer);
178 if (link_layer == NULL) {
179 weston_log("fails to allocate memory\n");
180 return;
181 }
182
183 link_layer->ivilayer = ivilayer;
184 wl_list_init(&link_layer->link);
185 wl_list_insert(&ivisurf->layer_list, &link_layer->link);
186 add_link_to_surface(ivilayer, link_layer);
187}
188
189static void
190remove_ordersurface_from_layer(struct ivi_layout_surface *ivisurf)
191{
192 struct link_layer *link_layer = NULL;
193 struct link_layer *next = NULL;
194
195 wl_list_for_each_safe(link_layer, next, &ivisurf->layer_list, link) {
196 if (!wl_list_empty(&link_layer->link)) {
197 wl_list_remove(&link_layer->link);
198 }
199 if (!wl_list_empty(&link_layer->link_to_layer)) {
200 wl_list_remove(&link_layer->link_to_layer);
201 }
202 free(link_layer);
203 }
204 wl_list_init(&ivisurf->layer_list);
205}
206
207/**
208 * Internal API to add/remove a ivi_layer to/from ivi_screen.
209 */
210static void
211add_orderlayer_to_screen(struct ivi_layout_layer *ivilayer,
212 struct ivi_layout_screen *iviscrn)
213{
214 struct link_screen *link_scrn = NULL;
215
216 link_scrn = malloc(sizeof *link_scrn);
217 if (link_scrn == NULL) {
218 weston_log("fails to allocate memory\n");
219 return;
220 }
221
222 link_scrn->iviscrn = iviscrn;
223 wl_list_init(&link_scrn->link);
224 wl_list_insert(&ivilayer->screen_list, &link_scrn->link);
225 add_link_to_layer(iviscrn, link_scrn);
226}
227
228static void
229remove_orderlayer_from_screen(struct ivi_layout_layer *ivilayer)
230{
231 struct link_screen *link_scrn = NULL;
232 struct link_screen *next = NULL;
233
234 wl_list_for_each_safe(link_scrn, next, &ivilayer->screen_list, link) {
235 if (!wl_list_empty(&link_scrn->link)) {
236 wl_list_remove(&link_scrn->link);
237 }
238 if (!wl_list_empty(&link_scrn->link_to_screen)) {
239 wl_list_remove(&link_scrn->link_to_screen);
240 }
241 free(link_scrn);
242 }
243 wl_list_init(&ivilayer->screen_list);
244}
245
246/**
247 * Internal API to add/remove a ivi_layer to/from ivi_screen.
248 */
249static struct ivi_layout_surface *
250get_surface(struct wl_list *surf_list, uint32_t id_surface)
251{
252 struct ivi_layout_surface *ivisurf;
253
254 wl_list_for_each(ivisurf, surf_list, link) {
255 if (ivisurf->id_surface == id_surface) {
256 return ivisurf;
257 }
258 }
259
260 return NULL;
261}
262
263static struct ivi_layout_layer *
264get_layer(struct wl_list *layer_list, uint32_t id_layer)
265{
266 struct ivi_layout_layer *ivilayer;
267
268 wl_list_for_each(ivilayer, layer_list, link) {
269 if (ivilayer->id_layer == id_layer) {
270 return ivilayer;
271 }
272 }
273
274 return NULL;
275}
276
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900277static void
278remove_configured_listener(struct ivi_layout_surface *ivisurf)
279{
280 struct wl_listener *link = NULL;
281 struct wl_listener *next = NULL;
282
283 wl_list_for_each_safe(link, next, &ivisurf->configured.listener_list, link) {
284 wl_list_remove(&link->link);
285 }
286}
287
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900288static void
289remove_all_notification(struct wl_list *listener_list)
290{
291 struct wl_listener *listener = NULL;
292 struct wl_listener *next = NULL;
293
294 wl_list_for_each_safe(listener, next, listener_list, link) {
295 struct listener_layout_notification *notification = NULL;
296 if (!wl_list_empty(&listener->link)) {
297 wl_list_remove(&listener->link);
298 }
299
300 notification =
301 container_of(listener,
302 struct listener_layout_notification,
303 listener);
304
305 free(notification->userdata);
306 free(notification);
307 }
308}
309
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900310static void
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900311ivi_layout_surface_remove_notification(struct ivi_layout_surface *ivisurf)
312{
313 if (ivisurf == NULL) {
314 weston_log("ivi_layout_surface_remove_notification: invalid argument\n");
315 return;
316 }
317
318 remove_all_notification(&ivisurf->property_changed.listener_list);
319}
320
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900321/**
322 * this shall not be called from controller because this is triggered by ivi_surface.destroy
323 * This means that this is called from westonsurface_destroy_from_ivisurface.
324 */
325static void
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900326ivi_layout_surface_remove(struct ivi_layout_surface *ivisurf)
327{
328 struct ivi_layout *layout = get_instance();
329
330 if (ivisurf == NULL) {
331 weston_log("ivi_layout_surface_remove: invalid argument\n");
332 return;
333 }
334
335 if (!wl_list_empty(&ivisurf->pending.link)) {
336 wl_list_remove(&ivisurf->pending.link);
337 }
338 if (!wl_list_empty(&ivisurf->order.link)) {
339 wl_list_remove(&ivisurf->order.link);
340 }
341 if (!wl_list_empty(&ivisurf->link)) {
342 wl_list_remove(&ivisurf->link);
343 }
344 remove_ordersurface_from_layer(ivisurf);
345
346 wl_signal_emit(&layout->surface_notification.removed, ivisurf);
347
348 remove_configured_listener(ivisurf);
349
350 ivi_layout_surface_remove_notification(ivisurf);
351
352 free(ivisurf);
353}
354
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900355/**
356 * Called at destruction of ivi_surface
357 */
358static void
359westonsurface_destroy_from_ivisurface(struct wl_listener *listener, void *data)
360{
361 struct ivi_layout_surface *ivisurf = NULL;
362
363 ivisurf = container_of(listener, struct ivi_layout_surface,
364 surface_destroy_listener);
365
366 wl_list_remove(&ivisurf->surface_rotation.link);
367 wl_list_remove(&ivisurf->layer_rotation.link);
368 wl_list_remove(&ivisurf->surface_pos.link);
369 wl_list_remove(&ivisurf->layer_pos.link);
370 wl_list_remove(&ivisurf->scaling.link);
371
372 ivisurf->surface = NULL;
373 ivi_layout_surface_remove(ivisurf);
374}
375
376/**
377 * Internal API to check ivi_layer/ivi_surface already added in ivi_layer/ivi_screen.
378 * Called by ivi_layout_layer_add_surface/ivi_layout_screenAddLayer
379 */
380static int
381is_surface_in_layer(struct ivi_layout_surface *ivisurf,
382 struct ivi_layout_layer *ivilayer)
383{
384 struct ivi_layout_surface *surf = NULL;
385
386 wl_list_for_each(surf, &ivilayer->pending.surface_list, pending.link) {
387 if (surf->id_surface == ivisurf->id_surface) {
388 return 1;
389 }
390 }
391
392 return 0;
393}
394
395static int
396is_layer_in_screen(struct ivi_layout_layer *ivilayer,
397 struct ivi_layout_screen *iviscrn)
398{
399 struct ivi_layout_layer *layer = NULL;
400
401 wl_list_for_each(layer, &iviscrn->pending.layer_list, pending.link) {
402 if (layer->id_layer == ivilayer->id_layer) {
403 return 1;
404 }
405 }
406
407 return 0;
408}
409
410/**
411 * Internal API to initialize ivi_screens found from output_list of weston_compositor.
412 * Called by ivi_layout_init_with_compositor.
413 */
414static void
415create_screen(struct weston_compositor *ec)
416{
417 struct ivi_layout *layout = get_instance();
418 struct ivi_layout_screen *iviscrn = NULL;
419 struct weston_output *output = NULL;
420 int32_t count = 0;
421
422 wl_list_for_each(output, &ec->output_list, link) {
423 iviscrn = calloc(1, sizeof *iviscrn);
424 if (iviscrn == NULL) {
425 weston_log("fails to allocate memory\n");
426 continue;
427 }
428
429 wl_list_init(&iviscrn->link);
430 iviscrn->layout = layout;
431
432 iviscrn->id_screen = count;
433 count++;
434
435 iviscrn->output = output;
436 iviscrn->event_mask = 0;
437
438 wl_list_init(&iviscrn->pending.layer_list);
439 wl_list_init(&iviscrn->pending.link);
440
441 wl_list_init(&iviscrn->order.layer_list);
442 wl_list_init(&iviscrn->order.link);
443
444 wl_list_init(&iviscrn->link_to_layer);
445
446 wl_list_insert(&layout->screen_list, &iviscrn->link);
447 }
448}
449
450/**
451 * Internal APIs to initialize properties of ivi_surface/ivi_layer when they are created.
452 */
453static void
454init_layer_properties(struct ivi_layout_layer_properties *prop,
455 int32_t width, int32_t height)
456{
457 memset(prop, 0, sizeof *prop);
458 prop->opacity = wl_fixed_from_double(1.0);
459 prop->source_width = width;
460 prop->source_height = height;
461 prop->dest_width = width;
462 prop->dest_height = height;
463}
464
465static void
466init_surface_properties(struct ivi_layout_surface_properties *prop)
467{
468 memset(prop, 0, sizeof *prop);
469 prop->opacity = wl_fixed_from_double(1.0);
Nobuhiko Tanibatae259a7a2015-04-27 17:02:54 +0900470 /*
471 * FIXME: this shall be finxed by ivi-layout-transition.
472 */
473 prop->dest_width = 1;
474 prop->dest_height = 1;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900475}
476
477/**
478 * Internal APIs to be called from ivi_layout_commit_changes.
479 */
480static void
481update_opacity(struct ivi_layout_layer *ivilayer,
482 struct ivi_layout_surface *ivisurf)
483{
484 double layer_alpha = wl_fixed_to_double(ivilayer->prop.opacity);
485 double surf_alpha = wl_fixed_to_double(ivisurf->prop.opacity);
486
487 if ((ivilayer->event_mask & IVI_NOTIFICATION_OPACITY) ||
488 (ivisurf->event_mask & IVI_NOTIFICATION_OPACITY)) {
489 struct weston_view *tmpview = NULL;
490 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
491 if (tmpview == NULL) {
492 continue;
493 }
494 tmpview->alpha = layer_alpha * surf_alpha;
495 }
496 }
497}
498
499static void
500update_surface_orientation(struct ivi_layout_layer *ivilayer,
501 struct ivi_layout_surface *ivisurf)
502{
503 struct weston_view *view;
504 struct weston_matrix *matrix = &ivisurf->surface_rotation.matrix;
505 float width = 0.0f;
506 float height = 0.0f;
507 float v_sin = 0.0f;
508 float v_cos = 0.0f;
509 float cx = 0.0f;
510 float cy = 0.0f;
511 float sx = 1.0f;
512 float sy = 1.0f;
513
514 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
515 if (view != NULL) {
516 break;
517 }
518 }
519
520 if (view == NULL) {
521 return;
522 }
523
524 if ((ivilayer->prop.dest_width == 0) ||
525 (ivilayer->prop.dest_height == 0)) {
526 return;
527 }
528 width = (float)ivilayer->prop.dest_width;
529 height = (float)ivilayer->prop.dest_height;
530
531 switch (ivisurf->prop.orientation) {
532 case WL_OUTPUT_TRANSFORM_NORMAL:
533 v_sin = 0.0f;
534 v_cos = 1.0f;
535 break;
536 case WL_OUTPUT_TRANSFORM_90:
537 v_sin = 1.0f;
538 v_cos = 0.0f;
539 sx = width / height;
540 sy = height / width;
541 break;
542 case WL_OUTPUT_TRANSFORM_180:
543 v_sin = 0.0f;
544 v_cos = -1.0f;
545 break;
546 case WL_OUTPUT_TRANSFORM_270:
547 default:
548 v_sin = -1.0f;
549 v_cos = 0.0f;
550 sx = width / height;
551 sy = height / width;
552 break;
553 }
554 wl_list_remove(&ivisurf->surface_rotation.link);
555 weston_view_geometry_dirty(view);
556
557 weston_matrix_init(matrix);
558 cx = 0.5f * width;
559 cy = 0.5f * height;
560 weston_matrix_translate(matrix, -cx, -cy, 0.0f);
561 weston_matrix_rotate_xy(matrix, v_cos, v_sin);
562 weston_matrix_scale(matrix, sx, sy, 1.0);
563 weston_matrix_translate(matrix, cx, cy, 0.0f);
564 wl_list_insert(&view->geometry.transformation_list,
565 &ivisurf->surface_rotation.link);
566
567 weston_view_set_transform_parent(view, NULL);
568 weston_view_update_transform(view);
569}
570
571static void
572update_layer_orientation(struct ivi_layout_layer *ivilayer,
573 struct ivi_layout_surface *ivisurf)
574{
575 struct weston_surface *es = ivisurf->surface;
576 struct weston_view *view;
577 struct weston_matrix *matrix = &ivisurf->layer_rotation.matrix;
578 struct weston_output *output = NULL;
579 float width = 0.0f;
580 float height = 0.0f;
581 float v_sin = 0.0f;
582 float v_cos = 0.0f;
583 float cx = 0.0f;
584 float cy = 0.0f;
585 float sx = 1.0f;
586 float sy = 1.0f;
587
588 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
589 if (view != NULL) {
590 break;
591 }
592 }
593
594 if (es == NULL || view == NULL) {
595 return;
596 }
597
598 output = es->output;
599 if (output == NULL) {
600 return;
601 }
602 if ((output->width == 0) || (output->height == 0)) {
603 return;
604 }
605 width = (float)output->width;
606 height = (float)output->height;
607
608 switch (ivilayer->prop.orientation) {
609 case WL_OUTPUT_TRANSFORM_NORMAL:
610 v_sin = 0.0f;
611 v_cos = 1.0f;
612 break;
613 case WL_OUTPUT_TRANSFORM_90:
614 v_sin = 1.0f;
615 v_cos = 0.0f;
616 sx = width / height;
617 sy = height / width;
618 break;
619 case WL_OUTPUT_TRANSFORM_180:
620 v_sin = 0.0f;
621 v_cos = -1.0f;
622 break;
623 case WL_OUTPUT_TRANSFORM_270:
624 default:
625 v_sin = -1.0f;
626 v_cos = 0.0f;
627 sx = width / height;
628 sy = height / width;
629 break;
630 }
631 wl_list_remove(&ivisurf->layer_rotation.link);
632 weston_view_geometry_dirty(view);
633
634 weston_matrix_init(matrix);
635 cx = 0.5f * width;
636 cy = 0.5f * height;
637 weston_matrix_translate(matrix, -cx, -cy, 0.0f);
638 weston_matrix_rotate_xy(matrix, v_cos, v_sin);
639 weston_matrix_scale(matrix, sx, sy, 1.0);
640 weston_matrix_translate(matrix, cx, cy, 0.0f);
641 wl_list_insert(&view->geometry.transformation_list,
642 &ivisurf->layer_rotation.link);
643
644 weston_view_set_transform_parent(view, NULL);
645 weston_view_update_transform(view);
646}
647
648static void
649update_surface_position(struct ivi_layout_surface *ivisurf)
650{
651 struct weston_view *view;
652 float tx = (float)ivisurf->prop.dest_x;
653 float ty = (float)ivisurf->prop.dest_y;
654 struct weston_matrix *matrix = &ivisurf->surface_pos.matrix;
655
656 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
657 if (view != NULL) {
658 break;
659 }
660 }
661
662 if (view == NULL) {
663 return;
664 }
665
666 wl_list_remove(&ivisurf->surface_pos.link);
667
668 weston_matrix_init(matrix);
669 weston_matrix_translate(matrix, tx, ty, 0.0f);
670 wl_list_insert(&view->geometry.transformation_list,
671 &ivisurf->surface_pos.link);
672
673 weston_view_set_transform_parent(view, NULL);
674 weston_view_update_transform(view);
675}
676
677static void
678update_layer_position(struct ivi_layout_layer *ivilayer,
679 struct ivi_layout_surface *ivisurf)
680{
681 struct weston_view *view;
682 struct weston_matrix *matrix = &ivisurf->layer_pos.matrix;
683 float tx = (float)ivilayer->prop.dest_x;
684 float ty = (float)ivilayer->prop.dest_y;
685
686 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
687 if (view != NULL) {
688 break;
689 }
690 }
691
692 if (view == NULL) {
693 return;
694 }
695
696 wl_list_remove(&ivisurf->layer_pos.link);
697
698 weston_matrix_init(matrix);
699 weston_matrix_translate(matrix, tx, ty, 0.0f);
700 wl_list_insert(&view->geometry.transformation_list,
701 &ivisurf->layer_pos.link);
702
703 weston_view_set_transform_parent(view, NULL);
704 weston_view_update_transform(view);
705}
706
707static void
708update_scale(struct ivi_layout_layer *ivilayer,
709 struct ivi_layout_surface *ivisurf)
710{
711 struct weston_view *view;
712 struct weston_matrix *matrix = &ivisurf->scaling.matrix;
713 float sx = 0.0f;
714 float sy = 0.0f;
715 float lw = 0.0f;
716 float sw = 0.0f;
717 float lh = 0.0f;
718 float sh = 0.0f;
719
720 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
721 if (view != NULL) {
722 break;
723 }
724 }
725
726 if (view == NULL) {
727 return;
728 }
729
Nobuhiko Tanibatabcff6322015-04-27 16:57:26 +0900730 if (ivisurf->prop.source_width == 0 || ivisurf->prop.source_height == 0) {
731 weston_log("ivi-shell: source rectangle is not yet set by ivi_layout_surface_set_source_rectangle\n");
732 return;
733 }
734
735 if (ivisurf->prop.dest_width == 0 || ivisurf->prop.dest_height == 0) {
736 weston_log("ivi-shell: destination rectangle is not yet set by ivi_layout_surface_set_destination_rectangle\n");
737 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900738 }
739
740 lw = ((float)ivilayer->prop.dest_width / (float)ivilayer->prop.source_width );
741 sw = ((float)ivisurf->prop.dest_width / (float)ivisurf->prop.source_width );
742 lh = ((float)ivilayer->prop.dest_height / (float)ivilayer->prop.source_height);
743 sh = ((float)ivisurf->prop.dest_height / (float)ivisurf->prop.source_height );
744 sx = sw * lw;
745 sy = sh * lh;
746
747 wl_list_remove(&ivisurf->scaling.link);
748 weston_matrix_init(matrix);
749 weston_matrix_scale(matrix, sx, sy, 1.0f);
750
751 wl_list_insert(&view->geometry.transformation_list,
752 &ivisurf->scaling.link);
753
754 weston_view_set_transform_parent(view, NULL);
755 weston_view_update_transform(view);
756}
757
758static void
759update_prop(struct ivi_layout_layer *ivilayer,
760 struct ivi_layout_surface *ivisurf)
761{
762 if (ivilayer->event_mask | ivisurf->event_mask) {
763 struct weston_view *tmpview;
764 update_opacity(ivilayer, ivisurf);
765 update_layer_orientation(ivilayer, ivisurf);
766 update_layer_position(ivilayer, ivisurf);
767 update_surface_position(ivisurf);
768 update_surface_orientation(ivilayer, ivisurf);
769 update_scale(ivilayer, ivisurf);
770
771 ivisurf->update_count++;
772
773 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
774 if (tmpview != NULL) {
775 break;
776 }
777 }
778
779 if (tmpview != NULL) {
780 weston_view_geometry_dirty(tmpview);
781 }
782
783 if (ivisurf->surface != NULL) {
784 weston_surface_damage(ivisurf->surface);
785 }
786 }
787}
788
789static void
790commit_changes(struct ivi_layout *layout)
791{
792 struct ivi_layout_screen *iviscrn = NULL;
793 struct ivi_layout_layer *ivilayer = NULL;
794 struct ivi_layout_surface *ivisurf = NULL;
795
796 wl_list_for_each(iviscrn, &layout->screen_list, link) {
797 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
798 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
799 update_prop(ivilayer, ivisurf);
800 }
801 }
802 }
803}
804
805static void
806commit_surface_list(struct ivi_layout *layout)
807{
808 struct ivi_layout_surface *ivisurf = NULL;
809 int32_t dest_x = 0;
810 int32_t dest_y = 0;
811 int32_t dest_width = 0;
812 int32_t dest_height = 0;
813 int32_t configured = 0;
814
815 wl_list_for_each(ivisurf, &layout->surface_list, link) {
816 if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEFAULT) {
817 dest_x = ivisurf->prop.dest_x;
818 dest_y = ivisurf->prop.dest_y;
819 dest_width = ivisurf->prop.dest_width;
820 dest_height = ivisurf->prop.dest_height;
821
822 ivi_layout_transition_move_resize_view(ivisurf,
823 ivisurf->pending.prop.dest_x,
824 ivisurf->pending.prop.dest_y,
825 ivisurf->pending.prop.dest_width,
826 ivisurf->pending.prop.dest_height,
827 ivisurf->pending.prop.transition_duration);
828
829 if(ivisurf->pending.prop.visibility) {
830 ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
831 } else {
832 ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
833 }
834
835 ivisurf->prop = ivisurf->pending.prop;
836 ivisurf->prop.dest_x = dest_x;
837 ivisurf->prop.dest_y = dest_y;
838 ivisurf->prop.dest_width = dest_width;
839 ivisurf->prop.dest_height = dest_height;
840 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
841 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
842
843 } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY){
844 dest_x = ivisurf->prop.dest_x;
845 dest_y = ivisurf->prop.dest_y;
846 dest_width = ivisurf->prop.dest_width;
847 dest_height = ivisurf->prop.dest_height;
848
849 ivi_layout_transition_move_resize_view(ivisurf,
850 ivisurf->pending.prop.dest_x,
851 ivisurf->pending.prop.dest_y,
852 ivisurf->pending.prop.dest_width,
853 ivisurf->pending.prop.dest_height,
854 ivisurf->pending.prop.transition_duration);
855
856 ivisurf->prop = ivisurf->pending.prop;
857 ivisurf->prop.dest_x = dest_x;
858 ivisurf->prop.dest_y = dest_y;
859 ivisurf->prop.dest_width = dest_width;
860 ivisurf->prop.dest_height = dest_height;
861
862 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
863 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
864
865 } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY){
866 configured = 0;
867 if(ivisurf->pending.prop.visibility) {
868 ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
869 } else {
870 ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
871 }
872
873 if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
874 ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
875 configured = 1;
876 }
877
878 ivisurf->prop = ivisurf->pending.prop;
879 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
880 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
881
882 if (configured && !is_surface_transition(ivisurf))
883 wl_signal_emit(&ivisurf->configured, ivisurf);
884 } else {
885 configured = 0;
886 if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
887 ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
888 configured = 1;
889 }
890
891 ivisurf->prop = ivisurf->pending.prop;
892 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
893 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
894
895 if (configured && !is_surface_transition(ivisurf))
896 wl_signal_emit(&ivisurf->configured, ivisurf);
897 }
898 }
899}
900
901static void
902commit_layer_list(struct ivi_layout *layout)
903{
904 struct ivi_layout_layer *ivilayer = NULL;
905 struct ivi_layout_surface *ivisurf = NULL;
906 struct ivi_layout_surface *next = NULL;
907
908 wl_list_for_each(ivilayer, &layout->layer_list, link) {
909 if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_MOVE) {
910 ivi_layout_transition_move_layer(ivilayer, ivilayer->pending.prop.dest_x, ivilayer->pending.prop.dest_y, ivilayer->pending.prop.transition_duration);
911 } else if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_FADE) {
912 ivi_layout_transition_fade_layer(ivilayer,ivilayer->pending.prop.is_fade_in,
913 ivilayer->pending.prop.start_alpha,ivilayer->pending.prop.end_alpha,
914 NULL, NULL,
915 ivilayer->pending.prop.transition_duration);
916 }
917 ivilayer->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
918
919 ivilayer->prop = ivilayer->pending.prop;
920
921 if (!(ivilayer->event_mask &
922 (IVI_NOTIFICATION_ADD | IVI_NOTIFICATION_REMOVE)) ) {
923 continue;
924 }
925
926 if (ivilayer->event_mask & IVI_NOTIFICATION_REMOVE) {
927 wl_list_for_each_safe(ivisurf, next,
928 &ivilayer->order.surface_list, order.link) {
929 remove_ordersurface_from_layer(ivisurf);
930
931 if (!wl_list_empty(&ivisurf->order.link)) {
932 wl_list_remove(&ivisurf->order.link);
933 }
934
935 wl_list_init(&ivisurf->order.link);
936 ivisurf->event_mask |= IVI_NOTIFICATION_REMOVE;
937 }
938
939 wl_list_init(&ivilayer->order.surface_list);
940 }
941
942 if (ivilayer->event_mask & IVI_NOTIFICATION_ADD) {
943 wl_list_for_each_safe(ivisurf, next,
944 &ivilayer->order.surface_list, order.link) {
945 remove_ordersurface_from_layer(ivisurf);
946
947 if (!wl_list_empty(&ivisurf->order.link)) {
948 wl_list_remove(&ivisurf->order.link);
949 }
950
951 wl_list_init(&ivisurf->order.link);
952 }
953
954 wl_list_init(&ivilayer->order.surface_list);
955 wl_list_for_each(ivisurf, &ivilayer->pending.surface_list,
956 pending.link) {
957 if(!wl_list_empty(&ivisurf->order.link)){
958 wl_list_remove(&ivisurf->order.link);
959 wl_list_init(&ivisurf->order.link);
960 }
961
962 wl_list_insert(&ivilayer->order.surface_list,
963 &ivisurf->order.link);
964 add_ordersurface_to_layer(ivisurf, ivilayer);
965 ivisurf->event_mask |= IVI_NOTIFICATION_ADD;
966 }
967 }
968 }
969}
970
971static void
972commit_screen_list(struct ivi_layout *layout)
973{
974 struct ivi_layout_screen *iviscrn = NULL;
975 struct ivi_layout_layer *ivilayer = NULL;
976 struct ivi_layout_layer *next = NULL;
977 struct ivi_layout_surface *ivisurf = NULL;
978
979 wl_list_for_each(iviscrn, &layout->screen_list, link) {
980 if (iviscrn->event_mask & IVI_NOTIFICATION_REMOVE) {
981 wl_list_for_each_safe(ivilayer, next,
982 &iviscrn->order.layer_list, order.link) {
983 remove_orderlayer_from_screen(ivilayer);
984
985 if (!wl_list_empty(&ivilayer->order.link)) {
986 wl_list_remove(&ivilayer->order.link);
987 }
988
989 wl_list_init(&ivilayer->order.link);
990 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
991 }
992 }
993
994 if (iviscrn->event_mask & IVI_NOTIFICATION_ADD) {
995 wl_list_for_each_safe(ivilayer, next,
996 &iviscrn->order.layer_list, order.link) {
997 remove_orderlayer_from_screen(ivilayer);
998
999 if (!wl_list_empty(&ivilayer->order.link)) {
1000 wl_list_remove(&ivilayer->order.link);
1001 }
1002
1003 wl_list_init(&ivilayer->order.link);
1004 }
1005
1006 wl_list_init(&iviscrn->order.layer_list);
1007 wl_list_for_each(ivilayer, &iviscrn->pending.layer_list,
1008 pending.link) {
1009 wl_list_insert(&iviscrn->order.layer_list,
1010 &ivilayer->order.link);
1011 add_orderlayer_to_screen(ivilayer, iviscrn);
1012 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
1013 }
1014 }
1015
1016 iviscrn->event_mask = 0;
1017
1018 /* Clear view list of layout ivi_layer */
1019 wl_list_init(&layout->layout_layer.view_list.link);
1020
1021 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
1022 if (ivilayer->prop.visibility == false)
1023 continue;
1024
1025 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
1026 struct weston_view *tmpview = NULL;
1027 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
1028 if (tmpview != NULL) {
1029 break;
1030 }
1031 }
1032
1033 if (ivisurf->prop.visibility == false)
1034 continue;
1035 if (ivisurf->surface == NULL || tmpview == NULL)
1036 continue;
1037
1038 weston_layer_entry_insert(&layout->layout_layer.view_list,
1039 &tmpview->layer_link);
1040
1041 ivisurf->surface->output = iviscrn->output;
1042 }
1043 }
1044
1045 break;
1046 }
1047}
1048
1049static void
1050commit_transition(struct ivi_layout* layout)
1051{
1052 if(wl_list_empty(&layout->pending_transition_list)){
1053 return;
1054 }
1055
1056 wl_list_insert_list(&layout->transitions->transition_list,
1057 &layout->pending_transition_list);
1058
1059 wl_list_init(&layout->pending_transition_list);
1060
1061 wl_event_source_timer_update(layout->transitions->event_source, 1);
1062}
1063
1064static void
1065send_surface_prop(struct ivi_layout_surface *ivisurf)
1066{
1067 wl_signal_emit(&ivisurf->property_changed, ivisurf);
1068 ivisurf->event_mask = 0;
1069}
1070
1071static void
1072send_layer_prop(struct ivi_layout_layer *ivilayer)
1073{
1074 wl_signal_emit(&ivilayer->property_changed, ivilayer);
1075 ivilayer->event_mask = 0;
1076}
1077
1078static void
1079send_prop(struct ivi_layout *layout)
1080{
1081 struct ivi_layout_layer *ivilayer = NULL;
1082 struct ivi_layout_surface *ivisurf = NULL;
1083
1084 wl_list_for_each_reverse(ivilayer, &layout->layer_list, link) {
1085 send_layer_prop(ivilayer);
1086 }
1087
1088 wl_list_for_each_reverse(ivisurf, &layout->surface_list, link) {
1089 send_surface_prop(ivisurf);
1090 }
1091}
1092
1093static void
1094clear_surface_pending_list(struct ivi_layout_layer *ivilayer)
1095{
1096 struct ivi_layout_surface *surface_link = NULL;
1097 struct ivi_layout_surface *surface_next = NULL;
1098
1099 wl_list_for_each_safe(surface_link, surface_next,
1100 &ivilayer->pending.surface_list, pending.link) {
1101 if (!wl_list_empty(&surface_link->pending.link)) {
1102 wl_list_remove(&surface_link->pending.link);
1103 }
1104
1105 wl_list_init(&surface_link->pending.link);
1106 }
1107
1108 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
1109}
1110
1111static void
1112clear_surface_order_list(struct ivi_layout_layer *ivilayer)
1113{
1114 struct ivi_layout_surface *surface_link = NULL;
1115 struct ivi_layout_surface *surface_next = NULL;
1116
1117 wl_list_for_each_safe(surface_link, surface_next,
1118 &ivilayer->order.surface_list, order.link) {
1119 if (!wl_list_empty(&surface_link->order.link)) {
1120 wl_list_remove(&surface_link->order.link);
1121 }
1122
1123 wl_list_init(&surface_link->order.link);
1124 }
1125
1126 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
1127}
1128
1129static void
1130layer_created(struct wl_listener *listener, void *data)
1131{
1132 struct ivi_layout_layer *ivilayer = data;
1133
1134 struct listener_layout_notification *notification =
1135 container_of(listener,
1136 struct listener_layout_notification,
1137 listener);
1138
1139 struct ivi_layout_notification_callback *created_callback =
1140 notification->userdata;
1141
1142 ((layer_create_notification_func)created_callback->callback)
1143 (ivilayer, created_callback->data);
1144}
1145
1146static void
1147layer_removed(struct wl_listener *listener, void *data)
1148{
1149 struct ivi_layout_layer *ivilayer = data;
1150
1151 struct listener_layout_notification *notification =
1152 container_of(listener,
1153 struct listener_layout_notification,
1154 listener);
1155
1156 struct ivi_layout_notification_callback *removed_callback =
1157 notification->userdata;
1158
1159 ((layer_remove_notification_func)removed_callback->callback)
1160 (ivilayer, removed_callback->data);
1161}
1162
1163static void
1164layer_prop_changed(struct wl_listener *listener, void *data)
1165{
1166 struct ivi_layout_layer *ivilayer = data;
1167
1168 struct listener_layout_notification *layout_listener =
1169 container_of(listener,
1170 struct listener_layout_notification,
1171 listener);
1172
1173 struct ivi_layout_notification_callback *prop_callback =
1174 layout_listener->userdata;
1175
1176 ((layer_property_notification_func)prop_callback->callback)
1177 (ivilayer, &ivilayer->prop, ivilayer->event_mask, prop_callback->data);
1178}
1179
1180static void
1181surface_created(struct wl_listener *listener, void *data)
1182{
1183 struct ivi_layout_surface *ivisurface = data;
1184
1185 struct listener_layout_notification *notification =
1186 container_of(listener,
1187 struct listener_layout_notification,
1188 listener);
1189
1190 struct ivi_layout_notification_callback *created_callback =
1191 notification->userdata;
1192
1193 ((surface_create_notification_func)created_callback->callback)
1194 (ivisurface, created_callback->data);
1195}
1196
1197static void
1198surface_removed(struct wl_listener *listener, void *data)
1199{
1200 struct ivi_layout_surface *ivisurface = data;
1201
1202 struct listener_layout_notification *notification =
1203 container_of(listener,
1204 struct listener_layout_notification,
1205 listener);
1206
1207 struct ivi_layout_notification_callback *removed_callback =
1208 notification->userdata;
1209
1210 ((surface_remove_notification_func)removed_callback->callback)
1211 (ivisurface, removed_callback->data);
1212}
1213
1214static void
1215surface_prop_changed(struct wl_listener *listener, void *data)
1216{
1217 struct ivi_layout_surface *ivisurf = data;
1218
1219 struct listener_layout_notification *layout_listener =
1220 container_of(listener,
1221 struct listener_layout_notification,
1222 listener);
1223
1224 struct ivi_layout_notification_callback *prop_callback =
1225 layout_listener->userdata;
1226
1227 ((surface_property_notification_func)prop_callback->callback)
1228 (ivisurf, &ivisurf->prop, ivisurf->event_mask, prop_callback->data);
1229
1230 ivisurf->event_mask = 0;
1231}
1232
1233static void
1234surface_configure_changed(struct wl_listener *listener,
1235 void *data)
1236{
1237 struct ivi_layout_surface *ivisurface = data;
1238
1239 struct listener_layout_notification *notification =
1240 container_of(listener,
1241 struct listener_layout_notification,
1242 listener);
1243
1244 struct ivi_layout_notification_callback *configure_changed_callback =
1245 notification->userdata;
1246
1247 ((surface_configure_notification_func)configure_changed_callback->callback)
1248 (ivisurface, configure_changed_callback->data);
1249}
1250
1251static int32_t
1252add_notification(struct wl_signal *signal,
1253 wl_notify_func_t callback,
1254 void *userdata)
1255{
1256 struct listener_layout_notification *notification = NULL;
1257
1258 notification = malloc(sizeof *notification);
1259 if (notification == NULL) {
1260 weston_log("fails to allocate memory\n");
1261 free(userdata);
1262 return IVI_FAILED;
1263 }
1264
1265 notification->listener.notify = callback;
1266 notification->userdata = userdata;
1267
1268 wl_signal_add(signal, &notification->listener);
1269
1270 return IVI_SUCCEEDED;
1271}
1272
1273static void
1274remove_notification(struct wl_list *listener_list, void *callback, void *userdata)
1275{
1276 struct wl_listener *listener = NULL;
1277 struct wl_listener *next = NULL;
1278
1279 wl_list_for_each_safe(listener, next, listener_list, link) {
1280 struct listener_layout_notification *notification =
1281 container_of(listener,
1282 struct listener_layout_notification,
1283 listener);
1284
1285 struct ivi_layout_notification_callback *notification_callback =
1286 notification->userdata;
1287
1288 if ((notification_callback->callback != callback) ||
1289 (notification_callback->data != userdata)) {
1290 continue;
1291 }
1292
1293 if (!wl_list_empty(&listener->link)) {
1294 wl_list_remove(&listener->link);
1295 }
1296
1297 free(notification->userdata);
1298 free(notification);
1299 }
1300}
1301
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001302/**
1303 * Exported APIs of ivi-layout library are implemented from here.
1304 * Brief of APIs is described in ivi-layout-export.h.
1305 */
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001306static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001307ivi_layout_add_notification_create_layer(layer_create_notification_func callback,
1308 void *userdata)
1309{
1310 struct ivi_layout *layout = get_instance();
1311 struct ivi_layout_notification_callback *created_callback = NULL;
1312
1313 if (callback == NULL) {
1314 weston_log("ivi_layout_add_notification_create_layer: invalid argument\n");
1315 return IVI_FAILED;
1316 }
1317
1318 created_callback = malloc(sizeof *created_callback);
1319 if (created_callback == NULL) {
1320 weston_log("fails to allocate memory\n");
1321 return IVI_FAILED;
1322 }
1323
1324 created_callback->callback = callback;
1325 created_callback->data = userdata;
1326
1327 return add_notification(&layout->layer_notification.created,
1328 layer_created,
1329 created_callback);
1330}
1331
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001332static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001333ivi_layout_remove_notification_create_layer(layer_create_notification_func callback,
1334 void *userdata)
1335{
1336 struct ivi_layout *layout = get_instance();
1337 remove_notification(&layout->layer_notification.created.listener_list, callback, userdata);
1338}
1339
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001340static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001341ivi_layout_add_notification_remove_layer(layer_remove_notification_func callback,
1342 void *userdata)
1343{
1344 struct ivi_layout *layout = get_instance();
1345 struct ivi_layout_notification_callback *removed_callback = NULL;
1346
1347 if (callback == NULL) {
1348 weston_log("ivi_layout_add_notification_remove_layer: invalid argument\n");
1349 return IVI_FAILED;
1350 }
1351
1352 removed_callback = malloc(sizeof *removed_callback);
1353 if (removed_callback == NULL) {
1354 weston_log("fails to allocate memory\n");
1355 return IVI_FAILED;
1356 }
1357
1358 removed_callback->callback = callback;
1359 removed_callback->data = userdata;
1360 return add_notification(&layout->layer_notification.removed,
1361 layer_removed,
1362 removed_callback);
1363}
1364
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001365static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001366ivi_layout_remove_notification_remove_layer(layer_remove_notification_func callback,
1367 void *userdata)
1368{
1369 struct ivi_layout *layout = get_instance();
1370 remove_notification(&layout->layer_notification.removed.listener_list, callback, userdata);
1371}
1372
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001373static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001374ivi_layout_add_notification_create_surface(surface_create_notification_func callback,
1375 void *userdata)
1376{
1377 struct ivi_layout *layout = get_instance();
1378 struct ivi_layout_notification_callback *created_callback = NULL;
1379
1380 if (callback == NULL) {
1381 weston_log("ivi_layout_add_notification_create_surface: invalid argument\n");
1382 return IVI_FAILED;
1383 }
1384
1385 created_callback = malloc(sizeof *created_callback);
1386 if (created_callback == NULL) {
1387 weston_log("fails to allocate memory\n");
1388 return IVI_FAILED;
1389 }
1390
1391 created_callback->callback = callback;
1392 created_callback->data = userdata;
1393
1394 return add_notification(&layout->surface_notification.created,
1395 surface_created,
1396 created_callback);
1397}
1398
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001399static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001400ivi_layout_remove_notification_create_surface(surface_create_notification_func callback,
1401 void *userdata)
1402{
1403 struct ivi_layout *layout = get_instance();
1404 remove_notification(&layout->surface_notification.created.listener_list, callback, userdata);
1405}
1406
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001407static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001408ivi_layout_add_notification_remove_surface(surface_remove_notification_func callback,
1409 void *userdata)
1410{
1411 struct ivi_layout *layout = get_instance();
1412 struct ivi_layout_notification_callback *removed_callback = NULL;
1413
1414 if (callback == NULL) {
1415 weston_log("ivi_layout_add_notification_remove_surface: invalid argument\n");
1416 return IVI_FAILED;
1417 }
1418
1419 removed_callback = malloc(sizeof *removed_callback);
1420 if (removed_callback == NULL) {
1421 weston_log("fails to allocate memory\n");
1422 return IVI_FAILED;
1423 }
1424
1425 removed_callback->callback = callback;
1426 removed_callback->data = userdata;
1427
1428 return add_notification(&layout->surface_notification.removed,
1429 surface_removed,
1430 removed_callback);
1431}
1432
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001433static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001434ivi_layout_remove_notification_remove_surface(surface_remove_notification_func callback,
1435 void *userdata)
1436{
1437 struct ivi_layout *layout = get_instance();
1438 remove_notification(&layout->surface_notification.removed.listener_list, callback, userdata);
1439}
1440
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001441static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001442ivi_layout_add_notification_configure_surface(surface_configure_notification_func callback,
1443 void *userdata)
1444{
1445 struct ivi_layout *layout = get_instance();
1446 struct ivi_layout_notification_callback *configure_changed_callback = NULL;
1447 if (callback == NULL) {
1448 weston_log("ivi_layout_add_notification_configure_surface: invalid argument\n");
1449 return IVI_FAILED;
1450 }
1451
1452 configure_changed_callback = malloc(sizeof *configure_changed_callback);
1453 if (configure_changed_callback == NULL) {
1454 weston_log("fails to allocate memory\n");
1455 return IVI_FAILED;
1456 }
1457
1458 configure_changed_callback->callback = callback;
1459 configure_changed_callback->data = userdata;
1460
1461 return add_notification(&layout->surface_notification.configure_changed,
1462 surface_configure_changed,
1463 configure_changed_callback);
1464}
1465
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001466static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001467ivi_layout_remove_notification_configure_surface(surface_configure_notification_func callback,
1468 void *userdata)
1469{
1470 struct ivi_layout *layout = get_instance();
1471 remove_notification(&layout->surface_notification.configure_changed.listener_list, callback, userdata);
1472}
1473
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001474uint32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001475ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf)
1476{
1477 return ivisurf->id_surface;
1478}
1479
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001480static uint32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001481ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer)
1482{
1483 return ivilayer->id_layer;
1484}
1485
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001486static struct ivi_layout_layer *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001487ivi_layout_get_layer_from_id(uint32_t id_layer)
1488{
1489 struct ivi_layout *layout = get_instance();
1490 struct ivi_layout_layer *ivilayer = NULL;
1491
1492 wl_list_for_each(ivilayer, &layout->layer_list, link) {
1493 if (ivilayer->id_layer == id_layer) {
1494 return ivilayer;
1495 }
1496 }
1497
1498 return NULL;
1499}
1500
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001501struct ivi_layout_surface *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001502ivi_layout_get_surface_from_id(uint32_t id_surface)
1503{
1504 struct ivi_layout *layout = get_instance();
1505 struct ivi_layout_surface *ivisurf = NULL;
1506
1507 wl_list_for_each(ivisurf, &layout->surface_list, link) {
1508 if (ivisurf->id_surface == id_surface) {
1509 return ivisurf;
1510 }
1511 }
1512
1513 return NULL;
1514}
1515
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001516static struct ivi_layout_screen *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001517ivi_layout_get_screen_from_id(uint32_t id_screen)
1518{
1519 struct ivi_layout *layout = get_instance();
1520 struct ivi_layout_screen *iviscrn = NULL;
1521
1522 wl_list_for_each(iviscrn, &layout->screen_list, link) {
1523/* FIXME : select iviscrn from screen_list by id_screen */
1524 return iviscrn;
1525 break;
1526 }
1527
1528 return NULL;
1529}
1530
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001531static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001532ivi_layout_get_screen_resolution(struct ivi_layout_screen *iviscrn,
1533 int32_t *pWidth, int32_t *pHeight)
1534{
1535 struct weston_output *output = NULL;
1536
1537 if (pWidth == NULL || pHeight == NULL) {
1538 weston_log("ivi_layout_get_screen_resolution: invalid argument\n");
1539 return IVI_FAILED;
1540 }
1541
1542 output = iviscrn->output;
1543 *pWidth = output->current_mode->width;
1544 *pHeight = output->current_mode->height;
1545
1546 return IVI_SUCCEEDED;
1547}
1548
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001549static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001550ivi_layout_surface_add_notification(struct ivi_layout_surface *ivisurf,
1551 surface_property_notification_func callback,
1552 void *userdata)
1553{
1554 struct listener_layout_notification* notification = NULL;
1555 struct ivi_layout_notification_callback *prop_callback = NULL;
1556
1557 if (ivisurf == NULL || callback == NULL) {
1558 weston_log("ivi_layout_surface_add_notification: invalid argument\n");
1559 return IVI_FAILED;
1560 }
1561
1562 notification = malloc(sizeof *notification);
1563 if (notification == NULL) {
1564 weston_log("fails to allocate memory\n");
1565 return IVI_FAILED;
1566 }
1567
1568 prop_callback = malloc(sizeof *prop_callback);
1569 if (prop_callback == NULL) {
1570 weston_log("fails to allocate memory\n");
1571 return IVI_FAILED;
1572 }
1573
1574 prop_callback->callback = callback;
1575 prop_callback->data = userdata;
1576
1577 notification->listener.notify = surface_prop_changed;
1578 notification->userdata = prop_callback;
1579
1580 wl_signal_add(&ivisurf->property_changed, &notification->listener);
1581
1582 return IVI_SUCCEEDED;
1583}
1584
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001585static const struct ivi_layout_layer_properties *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001586ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer)
1587{
1588 if (ivilayer == NULL) {
1589 weston_log("ivi_layout_get_properties_of_layer: invalid argument\n");
1590 return NULL;
1591 }
1592
1593 return &ivilayer->prop;
1594}
1595
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001596static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001597ivi_layout_get_screens(int32_t *pLength, struct ivi_layout_screen ***ppArray)
1598{
1599 struct ivi_layout *layout = get_instance();
1600 struct ivi_layout_screen *iviscrn = NULL;
1601 int32_t length = 0;
1602 int32_t n = 0;
1603
1604 if (pLength == NULL || ppArray == NULL) {
1605 weston_log("ivi_layout_get_screens: invalid argument\n");
1606 return IVI_FAILED;
1607 }
1608
1609 length = wl_list_length(&layout->screen_list);
1610
1611 if (length != 0){
1612 /* the Array must be free by module which called this function */
1613 *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
1614 if (*ppArray == NULL) {
1615 weston_log("fails to allocate memory\n");
1616 return IVI_FAILED;
1617 }
1618
1619 wl_list_for_each(iviscrn, &layout->screen_list, link) {
1620 (*ppArray)[n++] = iviscrn;
1621 }
1622 }
1623
1624 *pLength = length;
1625
1626 return IVI_SUCCEEDED;
1627}
1628
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001629static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001630ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer,
1631 int32_t *pLength,
1632 struct ivi_layout_screen ***ppArray)
1633{
1634 struct link_screen *link_scrn = NULL;
1635 int32_t length = 0;
1636 int32_t n = 0;
1637
1638 if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1639 weston_log("ivi_layout_get_screens_under_layer: invalid argument\n");
1640 return IVI_FAILED;
1641 }
1642
1643 length = wl_list_length(&ivilayer->screen_list);
1644
1645 if (length != 0){
1646 /* the Array must be free by module which called this function */
1647 *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
1648 if (*ppArray == NULL) {
1649 weston_log("fails to allocate memory\n");
1650 return IVI_FAILED;
1651 }
1652
1653 wl_list_for_each(link_scrn, &ivilayer->screen_list, link) {
1654 (*ppArray)[n++] = link_scrn->iviscrn;
1655 }
1656 }
1657
1658 *pLength = length;
1659
1660 return IVI_SUCCEEDED;
1661}
1662
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001663static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001664ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray)
1665{
1666 struct ivi_layout *layout = get_instance();
1667 struct ivi_layout_layer *ivilayer = NULL;
1668 int32_t length = 0;
1669 int32_t n = 0;
1670
1671 if (pLength == NULL || ppArray == NULL) {
1672 weston_log("ivi_layout_get_layers: invalid argument\n");
1673 return IVI_FAILED;
1674 }
1675
1676 length = wl_list_length(&layout->layer_list);
1677
1678 if (length != 0){
1679 /* the Array must be free by module which called this function */
1680 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1681 if (*ppArray == NULL) {
1682 weston_log("fails to allocate memory\n");
1683 return IVI_FAILED;
1684 }
1685
1686 wl_list_for_each(ivilayer, &layout->layer_list, link) {
1687 (*ppArray)[n++] = ivilayer;
1688 }
1689 }
1690
1691 *pLength = length;
1692
1693 return IVI_SUCCEEDED;
1694}
1695
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001696static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001697ivi_layout_get_layers_on_screen(struct ivi_layout_screen *iviscrn,
1698 int32_t *pLength,
1699 struct ivi_layout_layer ***ppArray)
1700{
1701 struct ivi_layout_layer *ivilayer = NULL;
1702 int32_t length = 0;
1703 int32_t n = 0;
1704
1705 if (iviscrn == NULL || pLength == NULL || ppArray == NULL) {
1706 weston_log("ivi_layout_get_layers_on_screen: invalid argument\n");
1707 return IVI_FAILED;
1708 }
1709
1710 length = wl_list_length(&iviscrn->order.layer_list);
1711
1712 if (length != 0){
1713 /* the Array must be free by module which called this function */
1714 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1715 if (*ppArray == NULL) {
1716 weston_log("fails to allocate memory\n");
1717 return IVI_FAILED;
1718 }
1719
1720 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, link) {
1721 (*ppArray)[n++] = ivilayer;
1722 }
1723 }
1724
1725 *pLength = length;
1726
1727 return IVI_SUCCEEDED;
1728}
1729
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001730static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001731ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf,
1732 int32_t *pLength,
1733 struct ivi_layout_layer ***ppArray)
1734{
1735 struct link_layer *link_layer = NULL;
1736 int32_t length = 0;
1737 int32_t n = 0;
1738
1739 if (ivisurf == NULL || pLength == NULL || ppArray == NULL) {
1740 weston_log("ivi_layout_getLayers: invalid argument\n");
1741 return IVI_FAILED;
1742 }
1743
1744 length = wl_list_length(&ivisurf->layer_list);
1745
1746 if (length != 0){
1747 /* the Array must be free by module which called this function */
1748 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1749 if (*ppArray == NULL) {
1750 weston_log("fails to allocate memory\n");
1751 return IVI_FAILED;
1752 }
1753
1754 wl_list_for_each(link_layer, &ivisurf->layer_list, link) {
1755 (*ppArray)[n++] = link_layer->ivilayer;
1756 }
1757 }
1758
1759 *pLength = length;
1760
1761 return IVI_SUCCEEDED;
1762}
1763
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001764static
1765int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001766ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray)
1767{
1768 struct ivi_layout *layout = get_instance();
1769 struct ivi_layout_surface *ivisurf = NULL;
1770 int32_t length = 0;
1771 int32_t n = 0;
1772
1773 if (pLength == NULL || ppArray == NULL) {
1774 weston_log("ivi_layout_get_surfaces: invalid argument\n");
1775 return IVI_FAILED;
1776 }
1777
1778 length = wl_list_length(&layout->surface_list);
1779
1780 if (length != 0){
1781 /* the Array must be free by module which called this function */
1782 *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1783 if (*ppArray == NULL) {
1784 weston_log("fails to allocate memory\n");
1785 return IVI_FAILED;
1786 }
1787
1788 wl_list_for_each(ivisurf, &layout->surface_list, link) {
1789 (*ppArray)[n++] = ivisurf;
1790 }
1791 }
1792
1793 *pLength = length;
1794
1795 return IVI_SUCCEEDED;
1796}
1797
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001798static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001799ivi_layout_get_surfaces_on_layer(struct ivi_layout_layer *ivilayer,
1800 int32_t *pLength,
1801 struct ivi_layout_surface ***ppArray)
1802{
1803 struct ivi_layout_surface *ivisurf = NULL;
1804 int32_t length = 0;
1805 int32_t n = 0;
1806
1807 if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1808 weston_log("ivi_layout_getSurfaceIDsOnLayer: invalid argument\n");
1809 return IVI_FAILED;
1810 }
1811
1812 length = wl_list_length(&ivilayer->order.surface_list);
1813
1814 if (length != 0) {
1815 /* the Array must be free by module which called this function */
1816 *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1817 if (*ppArray == NULL) {
1818 weston_log("fails to allocate memory\n");
1819 return IVI_FAILED;
1820 }
1821
1822 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
1823 (*ppArray)[n++] = ivisurf;
1824 }
1825 }
1826
1827 *pLength = length;
1828
1829 return IVI_SUCCEEDED;
1830}
1831
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001832static struct ivi_layout_layer *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001833ivi_layout_layer_create_with_dimension(uint32_t id_layer,
1834 int32_t width, int32_t height)
1835{
1836 struct ivi_layout *layout = get_instance();
1837 struct ivi_layout_layer *ivilayer = NULL;
1838
1839 ivilayer = get_layer(&layout->layer_list, id_layer);
1840 if (ivilayer != NULL) {
1841 weston_log("id_layer is already created\n");
1842 return ivilayer;
1843 }
1844
1845 ivilayer = calloc(1, sizeof *ivilayer);
1846 if (ivilayer == NULL) {
1847 weston_log("fails to allocate memory\n");
1848 return NULL;
1849 }
1850
1851 wl_list_init(&ivilayer->link);
1852 wl_signal_init(&ivilayer->property_changed);
1853 wl_list_init(&ivilayer->screen_list);
1854 wl_list_init(&ivilayer->link_to_surface);
1855 ivilayer->layout = layout;
1856 ivilayer->id_layer = id_layer;
1857
1858 init_layer_properties(&ivilayer->prop, width, height);
1859 ivilayer->event_mask = 0;
1860
1861 wl_list_init(&ivilayer->pending.surface_list);
1862 wl_list_init(&ivilayer->pending.link);
1863 ivilayer->pending.prop = ivilayer->prop;
1864
1865 wl_list_init(&ivilayer->order.surface_list);
1866 wl_list_init(&ivilayer->order.link);
1867
1868 wl_list_insert(&layout->layer_list, &ivilayer->link);
1869
1870 wl_signal_emit(&layout->layer_notification.created, ivilayer);
1871
1872 return ivilayer;
1873}
1874
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001875static void
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +09001876ivi_layout_layer_remove_notification(struct ivi_layout_layer *ivilayer)
1877{
1878 if (ivilayer == NULL) {
1879 weston_log("ivi_layout_layer_remove_notification: invalid argument\n");
1880 return;
1881 }
1882
1883 remove_all_notification(&ivilayer->property_changed.listener_list);
1884}
1885
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001886static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001887ivi_layout_layer_remove(struct ivi_layout_layer *ivilayer)
1888{
1889 struct ivi_layout *layout = get_instance();
1890
1891 if (ivilayer == NULL) {
1892 weston_log("ivi_layout_layer_remove: invalid argument\n");
1893 return;
1894 }
1895
1896 wl_signal_emit(&layout->layer_notification.removed, ivilayer);
1897
1898 clear_surface_pending_list(ivilayer);
1899 clear_surface_order_list(ivilayer);
1900
1901 if (!wl_list_empty(&ivilayer->pending.link)) {
1902 wl_list_remove(&ivilayer->pending.link);
1903 }
1904 if (!wl_list_empty(&ivilayer->order.link)) {
1905 wl_list_remove(&ivilayer->order.link);
1906 }
1907 if (!wl_list_empty(&ivilayer->link)) {
1908 wl_list_remove(&ivilayer->link);
1909 }
1910 remove_orderlayer_from_screen(ivilayer);
1911 remove_link_to_surface(ivilayer);
1912 ivi_layout_layer_remove_notification(ivilayer);
1913
1914 free(ivilayer);
1915}
1916
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001917int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001918ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer,
1919 bool newVisibility)
1920{
1921 struct ivi_layout_layer_properties *prop = NULL;
1922
1923 if (ivilayer == NULL) {
1924 weston_log("ivi_layout_layer_set_visibility: invalid argument\n");
1925 return IVI_FAILED;
1926 }
1927
1928 prop = &ivilayer->pending.prop;
1929 prop->visibility = newVisibility;
1930
1931 ivilayer->event_mask |= IVI_NOTIFICATION_VISIBILITY;
1932
1933 return IVI_SUCCEEDED;
1934}
1935
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001936static bool
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001937ivi_layout_layer_get_visibility(struct ivi_layout_layer *ivilayer)
1938{
1939 if (ivilayer == NULL) {
1940 weston_log("ivi_layout_layer_get_visibility: invalid argument\n");
1941 return false;
1942 }
1943
1944 return ivilayer->prop.visibility;
1945}
1946
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001947int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001948ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
1949 wl_fixed_t opacity)
1950{
1951 struct ivi_layout_layer_properties *prop = NULL;
1952
1953 if (ivilayer == NULL) {
1954 weston_log("ivi_layout_layer_set_opacity: invalid argument\n");
1955 return IVI_FAILED;
1956 }
1957
1958 prop = &ivilayer->pending.prop;
1959 prop->opacity = opacity;
1960
1961 ivilayer->event_mask |= IVI_NOTIFICATION_OPACITY;
1962
1963 return IVI_SUCCEEDED;
1964}
1965
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001966wl_fixed_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001967ivi_layout_layer_get_opacity(struct ivi_layout_layer *ivilayer)
1968{
1969 if (ivilayer == NULL) {
1970 weston_log("ivi_layout_layer_get_opacity: invalid argument\n");
1971 return wl_fixed_from_double(0.0);
1972 }
1973
1974 return ivilayer->prop.opacity;
1975}
1976
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001977static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001978ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer,
1979 int32_t x, int32_t y,
1980 int32_t width, int32_t height)
1981{
1982 struct ivi_layout_layer_properties *prop = NULL;
1983
1984 if (ivilayer == NULL) {
1985 weston_log("ivi_layout_layer_set_source_rectangle: invalid argument\n");
1986 return IVI_FAILED;
1987 }
1988
1989 prop = &ivilayer->pending.prop;
1990 prop->source_x = x;
1991 prop->source_y = y;
1992 prop->source_width = width;
1993 prop->source_height = height;
1994
1995 ivilayer->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
1996
1997 return IVI_SUCCEEDED;
1998}
1999
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002000static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002001ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer,
2002 int32_t x, int32_t y,
2003 int32_t width, int32_t height)
2004{
2005 struct ivi_layout_layer_properties *prop = NULL;
2006
2007 if (ivilayer == NULL) {
2008 weston_log("ivi_layout_layer_set_destination_rectangle: invalid argument\n");
2009 return IVI_FAILED;
2010 }
2011
2012 prop = &ivilayer->pending.prop;
2013 prop->dest_x = x;
2014 prop->dest_y = y;
2015 prop->dest_width = width;
2016 prop->dest_height = height;
2017
2018 ivilayer->event_mask |= IVI_NOTIFICATION_DEST_RECT;
2019
2020 return IVI_SUCCEEDED;
2021}
2022
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002023static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002024ivi_layout_layer_get_dimension(struct ivi_layout_layer *ivilayer,
2025 int32_t *dest_width, int32_t *dest_height)
2026{
2027 if (ivilayer == NULL || dest_width == NULL || dest_height == NULL) {
2028 weston_log("ivi_layout_layer_get_dimension: invalid argument\n");
2029 return IVI_FAILED;
2030 }
2031
2032 *dest_width = ivilayer->prop.dest_width;
2033 *dest_height = ivilayer->prop.dest_height;
2034
2035 return IVI_SUCCEEDED;
2036}
2037
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002038static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002039ivi_layout_layer_set_dimension(struct ivi_layout_layer *ivilayer,
2040 int32_t dest_width, int32_t dest_height)
2041{
2042 struct ivi_layout_layer_properties *prop = NULL;
2043
2044 if (ivilayer == NULL) {
2045 weston_log("ivi_layout_layer_set_dimension: invalid argument\n");
2046 return IVI_FAILED;
2047 }
2048
2049 prop = &ivilayer->pending.prop;
2050
2051 prop->dest_width = dest_width;
2052 prop->dest_height = dest_height;
2053
2054 ivilayer->event_mask |= IVI_NOTIFICATION_DIMENSION;
2055
2056 return IVI_SUCCEEDED;
2057}
2058
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002059int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002060ivi_layout_layer_get_position(struct ivi_layout_layer *ivilayer,
2061 int32_t *dest_x, int32_t *dest_y)
2062{
2063 if (ivilayer == NULL || dest_x == NULL || dest_y == NULL) {
2064 weston_log("ivi_layout_layer_get_position: invalid argument\n");
2065 return IVI_FAILED;
2066 }
2067
2068 *dest_x = ivilayer->prop.dest_x;
2069 *dest_y = ivilayer->prop.dest_y;
2070
2071 return IVI_SUCCEEDED;
2072}
2073
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002074int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002075ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer,
2076 int32_t dest_x, int32_t dest_y)
2077{
2078 struct ivi_layout_layer_properties *prop = NULL;
2079
2080 if (ivilayer == NULL) {
2081 weston_log("ivi_layout_layer_set_position: invalid argument\n");
2082 return IVI_FAILED;
2083 }
2084
2085 prop = &ivilayer->pending.prop;
2086 prop->dest_x = dest_x;
2087 prop->dest_y = dest_y;
2088
2089 ivilayer->event_mask |= IVI_NOTIFICATION_POSITION;
2090
2091 return IVI_SUCCEEDED;
2092}
2093
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002094static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002095ivi_layout_layer_set_orientation(struct ivi_layout_layer *ivilayer,
2096 enum wl_output_transform orientation)
2097{
2098 struct ivi_layout_layer_properties *prop = NULL;
2099
2100 if (ivilayer == NULL) {
2101 weston_log("ivi_layout_layer_set_orientation: invalid argument\n");
2102 return IVI_FAILED;
2103 }
2104
2105 prop = &ivilayer->pending.prop;
2106 prop->orientation = orientation;
2107
2108 ivilayer->event_mask |= IVI_NOTIFICATION_ORIENTATION;
2109
2110 return IVI_SUCCEEDED;
2111}
2112
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002113static enum wl_output_transform
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002114ivi_layout_layer_get_orientation(struct ivi_layout_layer *ivilayer)
2115{
2116 if (ivilayer == NULL) {
2117 weston_log("ivi_layout_layer_get_orientation: invalid argument\n");
2118 return 0;
2119 }
2120
2121 return ivilayer->prop.orientation;
2122}
2123
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002124int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002125ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
2126 struct ivi_layout_surface **pSurface,
2127 int32_t number)
2128{
2129 struct ivi_layout *layout = get_instance();
2130 struct ivi_layout_surface *ivisurf = NULL;
2131 struct ivi_layout_surface *next = NULL;
2132 uint32_t *id_surface = NULL;
2133 int32_t i = 0;
2134
2135 if (ivilayer == NULL) {
2136 weston_log("ivi_layout_layer_set_render_order: invalid argument\n");
2137 return IVI_FAILED;
2138 }
2139
2140 if (pSurface == NULL) {
2141 wl_list_for_each_safe(ivisurf, next, &ivilayer->pending.surface_list, pending.link) {
2142 if (!wl_list_empty(&ivisurf->pending.link)) {
2143 wl_list_remove(&ivisurf->pending.link);
2144 }
2145
2146 wl_list_init(&ivisurf->pending.link);
2147 }
2148 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
2149 return IVI_SUCCEEDED;
2150 }
2151
2152 for (i = 0; i < number; i++) {
2153 id_surface = &pSurface[i]->id_surface;
2154
2155 wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
2156 if (*id_surface != ivisurf->id_surface) {
2157 continue;
2158 }
2159
2160 if (!wl_list_empty(&ivisurf->pending.link)) {
2161 wl_list_remove(&ivisurf->pending.link);
2162 }
2163 wl_list_init(&ivisurf->pending.link);
2164 wl_list_insert(&ivilayer->pending.surface_list,
2165 &ivisurf->pending.link);
2166 break;
2167 }
2168 }
2169
2170 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
2171
2172 return IVI_SUCCEEDED;
2173}
2174
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002175int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002176ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf,
2177 bool newVisibility)
2178{
2179 struct ivi_layout_surface_properties *prop = NULL;
2180
2181 if (ivisurf == NULL) {
2182 weston_log("ivi_layout_surface_set_visibility: invalid argument\n");
2183 return IVI_FAILED;
2184 }
2185
2186 prop = &ivisurf->pending.prop;
2187 prop->visibility = newVisibility;
2188
2189 ivisurf->event_mask |= IVI_NOTIFICATION_VISIBILITY;
2190
2191 return IVI_SUCCEEDED;
2192}
2193
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002194bool
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002195ivi_layout_surface_get_visibility(struct ivi_layout_surface *ivisurf)
2196{
2197 if (ivisurf == NULL) {
2198 weston_log("ivi_layout_surface_get_visibility: invalid argument\n");
2199 return false;
2200 }
2201
2202 return ivisurf->prop.visibility;
2203}
2204
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002205int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002206ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
2207 wl_fixed_t opacity)
2208{
2209 struct ivi_layout_surface_properties *prop = NULL;
2210
2211 if (ivisurf == NULL) {
2212 weston_log("ivi_layout_surface_set_opacity: invalid argument\n");
2213 return IVI_FAILED;
2214 }
2215
2216 prop = &ivisurf->pending.prop;
2217 prop->opacity = opacity;
2218
2219 ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY;
2220
2221 return IVI_SUCCEEDED;
2222}
2223
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002224wl_fixed_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002225ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf)
2226{
2227 if (ivisurf == NULL) {
2228 weston_log("ivi_layout_surface_get_opacity: invalid argument\n");
2229 return wl_fixed_from_double(0.0);
2230 }
2231
2232 return ivisurf->prop.opacity;
2233}
2234
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002235int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002236ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
2237 int32_t x, int32_t y,
2238 int32_t width, int32_t height)
2239{
2240 struct ivi_layout_surface_properties *prop = NULL;
2241
2242 if (ivisurf == NULL) {
2243 weston_log("ivi_layout_surface_set_destination_rectangle: invalid argument\n");
2244 return IVI_FAILED;
2245 }
2246
2247 prop = &ivisurf->pending.prop;
2248 prop->start_x = prop->dest_x;
2249 prop->start_y = prop->dest_y;
2250 prop->dest_x = x;
2251 prop->dest_y = y;
2252 prop->start_width = prop->dest_width;
2253 prop->start_height = prop->dest_height;
2254 prop->dest_width = width;
2255 prop->dest_height = height;
2256
2257 ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT;
2258
2259 return IVI_SUCCEEDED;
2260}
2261
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002262static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002263ivi_layout_surface_set_dimension(struct ivi_layout_surface *ivisurf,
2264 int32_t dest_width, int32_t dest_height)
2265{
2266 struct ivi_layout_surface_properties *prop = NULL;
2267
2268 if (ivisurf == NULL) {
2269 weston_log("ivi_layout_surface_set_dimension: invalid argument\n");
2270 return IVI_FAILED;
2271 }
2272
2273 prop = &ivisurf->pending.prop;
2274 prop->dest_width = dest_width;
2275 prop->dest_height = dest_height;
2276
2277 ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION;
2278
2279 return IVI_SUCCEEDED;
2280}
2281
2282int32_t
2283ivi_layout_surface_get_dimension(struct ivi_layout_surface *ivisurf,
2284 int32_t *dest_width, int32_t *dest_height)
2285{
2286 if (ivisurf == NULL || dest_width == NULL || dest_height == NULL) {
2287 weston_log("ivi_layout_surface_get_dimension: invalid argument\n");
2288 return IVI_FAILED;
2289 }
2290
2291 *dest_width = ivisurf->prop.dest_width;
2292 *dest_height = ivisurf->prop.dest_height;
2293
2294 return IVI_SUCCEEDED;
2295}
2296
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002297static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002298ivi_layout_surface_set_position(struct ivi_layout_surface *ivisurf,
2299 int32_t dest_x, int32_t dest_y)
2300{
2301 struct ivi_layout_surface_properties *prop = NULL;
2302
2303 if (ivisurf == NULL) {
2304 weston_log("ivi_layout_surface_set_position: invalid argument\n");
2305 return IVI_FAILED;
2306 }
2307
2308 prop = &ivisurf->pending.prop;
2309 prop->dest_x = dest_x;
2310 prop->dest_y = dest_y;
2311
2312 ivisurf->event_mask |= IVI_NOTIFICATION_POSITION;
2313
2314 return IVI_SUCCEEDED;
2315}
2316
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002317static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002318ivi_layout_surface_get_position(struct ivi_layout_surface *ivisurf,
2319 int32_t *dest_x, int32_t *dest_y)
2320{
2321 if (ivisurf == NULL || dest_x == NULL || dest_y == NULL) {
2322 weston_log("ivi_layout_surface_get_position: invalid argument\n");
2323 return IVI_FAILED;
2324 }
2325
2326 *dest_x = ivisurf->prop.dest_x;
2327 *dest_y = ivisurf->prop.dest_y;
2328
2329 return IVI_SUCCEEDED;
2330}
2331
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002332static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002333ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf,
2334 enum wl_output_transform orientation)
2335{
2336 struct ivi_layout_surface_properties *prop = NULL;
2337
2338 if (ivisurf == NULL) {
2339 weston_log("ivi_layout_surface_set_orientation: invalid argument\n");
2340 return IVI_FAILED;
2341 }
2342
2343 prop = &ivisurf->pending.prop;
2344 prop->orientation = orientation;
2345
2346 ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION;
2347
2348 return IVI_SUCCEEDED;
2349}
2350
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002351static enum wl_output_transform
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002352ivi_layout_surface_get_orientation(struct ivi_layout_surface *ivisurf)
2353{
2354 if (ivisurf == NULL) {
2355 weston_log("ivi_layout_surface_get_orientation: invalid argument\n");
2356 return 0;
2357 }
2358
2359 return ivisurf->prop.orientation;
2360}
2361
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002362static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002363ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn,
2364 struct ivi_layout_layer *addlayer)
2365{
2366 struct ivi_layout *layout = get_instance();
2367 struct ivi_layout_layer *ivilayer = NULL;
2368 struct ivi_layout_layer *next = NULL;
2369 int is_layer_in_scrn = 0;
2370
2371 if (iviscrn == NULL || addlayer == NULL) {
2372 weston_log("ivi_layout_screen_add_layer: invalid argument\n");
2373 return IVI_FAILED;
2374 }
2375
2376 is_layer_in_scrn = is_layer_in_screen(addlayer, iviscrn);
2377 if (is_layer_in_scrn == 1) {
2378 weston_log("ivi_layout_screen_add_layer: addlayer is already available\n");
2379 return IVI_SUCCEEDED;
2380 }
2381
2382 wl_list_for_each_safe(ivilayer, next, &layout->layer_list, link) {
2383 if (ivilayer->id_layer == addlayer->id_layer) {
2384 if (!wl_list_empty(&ivilayer->pending.link)) {
2385 wl_list_remove(&ivilayer->pending.link);
2386 }
2387 wl_list_init(&ivilayer->pending.link);
2388 wl_list_insert(&iviscrn->pending.layer_list,
2389 &ivilayer->pending.link);
2390 break;
2391 }
2392 }
2393
2394 iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
2395
2396 return IVI_SUCCEEDED;
2397}
2398
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002399static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002400ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn,
2401 struct ivi_layout_layer **pLayer,
2402 const int32_t number)
2403{
2404 struct ivi_layout *layout = get_instance();
2405 struct ivi_layout_layer *ivilayer = NULL;
2406 struct ivi_layout_layer *next = NULL;
2407 uint32_t *id_layer = NULL;
2408 int32_t i = 0;
2409
2410 if (iviscrn == NULL) {
2411 weston_log("ivi_layout_screen_set_render_order: invalid argument\n");
2412 return IVI_FAILED;
2413 }
2414
2415 wl_list_for_each_safe(ivilayer, next,
2416 &iviscrn->pending.layer_list, pending.link) {
2417 wl_list_init(&ivilayer->pending.link);
2418 }
2419
2420 wl_list_init(&iviscrn->pending.layer_list);
2421
2422 if (pLayer == NULL) {
2423 wl_list_for_each_safe(ivilayer, next, &iviscrn->pending.layer_list, pending.link) {
2424 if (!wl_list_empty(&ivilayer->pending.link)) {
2425 wl_list_remove(&ivilayer->pending.link);
2426 }
2427
2428 wl_list_init(&ivilayer->pending.link);
2429 }
2430
2431 iviscrn->event_mask |= IVI_NOTIFICATION_REMOVE;
2432 return IVI_SUCCEEDED;
2433 }
2434
2435 for (i = 0; i < number; i++) {
2436 id_layer = &pLayer[i]->id_layer;
2437 wl_list_for_each(ivilayer, &layout->layer_list, link) {
2438 if (*id_layer != ivilayer->id_layer) {
2439 continue;
2440 }
2441
2442 if (!wl_list_empty(&ivilayer->pending.link)) {
2443 wl_list_remove(&ivilayer->pending.link);
2444 }
2445 wl_list_init(&ivilayer->pending.link);
2446 wl_list_insert(&iviscrn->pending.layer_list,
2447 &ivilayer->pending.link);
2448 break;
2449 }
2450 }
2451
2452 iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
2453
2454 return IVI_SUCCEEDED;
2455}
2456
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002457static struct weston_output *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002458ivi_layout_screen_get_output(struct ivi_layout_screen *iviscrn)
2459{
2460 return iviscrn->output;
2461}
2462
2463/**
2464 * This function is used by the additional ivi-module because of dumping ivi_surface sceenshot.
2465 * The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of Genivi's Layer Management.
2466 * This function is used to get the result of drawing by clients.
2467 */
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002468static struct weston_surface *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002469ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf)
2470{
2471 return ivisurf != NULL ? ivisurf->surface : NULL;
2472}
2473
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002474static int32_t
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09002475ivi_layout_surface_get_size(struct ivi_layout_surface *ivisurf,
2476 int32_t *width, int32_t *height,
2477 int32_t *stride)
2478{
2479 int32_t w;
2480 int32_t h;
2481 const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
2482
2483 if (ivisurf == NULL || ivisurf->surface == NULL) {
2484 weston_log("%s: invalid argument\n", __func__);
2485 return IVI_FAILED;
2486 }
2487
2488 weston_surface_get_content_size(ivisurf->surface, &w, &h);
2489
2490 if (width != NULL)
2491 *width = w;
2492
2493 if (height != NULL)
2494 *height = h;
2495
2496 if (stride != NULL)
2497 *stride = w * bytespp;
2498
2499 return IVI_SUCCEEDED;
2500}
2501
2502static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002503ivi_layout_layer_add_notification(struct ivi_layout_layer *ivilayer,
2504 layer_property_notification_func callback,
2505 void *userdata)
2506{
2507 struct ivi_layout_notification_callback *prop_callback = NULL;
2508
2509 if (ivilayer == NULL || callback == NULL) {
2510 weston_log("ivi_layout_layer_add_notification: invalid argument\n");
2511 return IVI_FAILED;
2512 }
2513
2514 prop_callback = malloc(sizeof *prop_callback);
2515 if (prop_callback == NULL) {
2516 weston_log("fails to allocate memory\n");
2517 return IVI_FAILED;
2518 }
2519
2520 prop_callback->callback = callback;
2521 prop_callback->data = userdata;
2522
2523 return add_notification(&ivilayer->property_changed,
2524 layer_prop_changed,
2525 prop_callback);
2526}
2527
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002528static const struct ivi_layout_surface_properties *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002529ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf)
2530{
2531 if (ivisurf == NULL) {
2532 weston_log("ivi_layout_get_properties_of_surface: invalid argument\n");
2533 return NULL;
2534 }
2535
2536 return &ivisurf->prop;
2537}
2538
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002539static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002540ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer,
2541 struct ivi_layout_surface *addsurf)
2542{
2543 struct ivi_layout *layout = get_instance();
2544 struct ivi_layout_surface *ivisurf = NULL;
2545 struct ivi_layout_surface *next = NULL;
2546 int is_surf_in_layer = 0;
2547
2548 if (ivilayer == NULL || addsurf == NULL) {
2549 weston_log("ivi_layout_layer_add_surface: invalid argument\n");
2550 return IVI_FAILED;
2551 }
2552
2553 is_surf_in_layer = is_surface_in_layer(addsurf, ivilayer);
2554 if (is_surf_in_layer == 1) {
2555 weston_log("ivi_layout_layer_add_surface: addsurf is already available\n");
2556 return IVI_SUCCEEDED;
2557 }
2558
2559 wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
2560 if (ivisurf->id_surface == addsurf->id_surface) {
2561 if (!wl_list_empty(&ivisurf->pending.link)) {
2562 wl_list_remove(&ivisurf->pending.link);
2563 }
2564 wl_list_init(&ivisurf->pending.link);
2565 wl_list_insert(&ivilayer->pending.surface_list,
2566 &ivisurf->pending.link);
2567 break;
2568 }
2569 }
2570
2571 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
2572
2573 return IVI_SUCCEEDED;
2574}
2575
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002576static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002577ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer,
2578 struct ivi_layout_surface *remsurf)
2579{
2580 struct ivi_layout_surface *ivisurf = NULL;
2581 struct ivi_layout_surface *next = NULL;
2582
2583 if (ivilayer == NULL || remsurf == NULL) {
2584 weston_log("ivi_layout_layer_remove_surface: invalid argument\n");
2585 return;
2586 }
2587
2588 wl_list_for_each_safe(ivisurf, next,
2589 &ivilayer->pending.surface_list, pending.link) {
2590 if (ivisurf->id_surface == remsurf->id_surface) {
2591 if (!wl_list_empty(&ivisurf->pending.link)) {
2592 wl_list_remove(&ivisurf->pending.link);
2593 }
2594 wl_list_init(&ivisurf->pending.link);
2595 break;
2596 }
2597 }
2598
2599 remsurf->event_mask |= IVI_NOTIFICATION_REMOVE;
2600}
2601
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002602static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002603ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf,
2604 int32_t x, int32_t y,
2605 int32_t width, int32_t height)
2606{
2607 struct ivi_layout_surface_properties *prop = NULL;
2608
2609 if (ivisurf == NULL) {
2610 weston_log("ivi_layout_surface_set_source_rectangle: invalid argument\n");
2611 return IVI_FAILED;
2612 }
2613
2614 prop = &ivisurf->pending.prop;
2615 prop->source_x = x;
2616 prop->source_y = y;
2617 prop->source_width = width;
2618 prop->source_height = height;
2619
2620 ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
2621
2622 return IVI_SUCCEEDED;
2623}
2624
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002625int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002626ivi_layout_commit_changes(void)
2627{
2628 struct ivi_layout *layout = get_instance();
2629
2630 commit_surface_list(layout);
2631 commit_layer_list(layout);
2632 commit_screen_list(layout);
2633
2634 commit_transition(layout);
2635
2636 commit_changes(layout);
2637 send_prop(layout);
2638 weston_compositor_schedule_repaint(layout->compositor);
2639
2640 return IVI_SUCCEEDED;
2641}
2642
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002643static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002644ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer,
2645 enum ivi_layout_transition_type type,
2646 uint32_t duration)
2647{
2648 if (ivilayer == NULL) {
2649 weston_log("%s: invalid argument\n", __func__);
2650 return -1;
2651 }
2652
2653 ivilayer->pending.prop.transition_type = type;
2654 ivilayer->pending.prop.transition_duration = duration;
2655
2656 return 0;
2657}
2658
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002659static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002660ivi_layout_layer_set_fade_info(struct ivi_layout_layer* ivilayer,
2661 uint32_t is_fade_in,
2662 double start_alpha, double end_alpha)
2663{
2664 if (ivilayer == NULL) {
2665 weston_log("%s: invalid argument\n", __func__);
2666 return -1;
2667 }
2668
2669 ivilayer->pending.prop.is_fade_in = is_fade_in;
2670 ivilayer->pending.prop.start_alpha = start_alpha;
2671 ivilayer->pending.prop.end_alpha = end_alpha;
2672
2673 return 0;
2674}
2675
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002676static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002677ivi_layout_surface_set_transition_duration(struct ivi_layout_surface *ivisurf,
2678 uint32_t duration)
2679{
2680 struct ivi_layout_surface_properties *prop;
2681
2682 if (ivisurf == NULL) {
2683 weston_log("%s: invalid argument\n", __func__);
2684 return -1;
2685 }
2686
2687 prop = &ivisurf->pending.prop;
2688 prop->transition_duration = duration*10;
2689 return 0;
2690}
2691
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002692static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002693ivi_layout_surface_set_transition(struct ivi_layout_surface *ivisurf,
2694 enum ivi_layout_transition_type type,
2695 uint32_t duration)
2696{
2697 struct ivi_layout_surface_properties *prop;
2698
2699 if (ivisurf == NULL) {
2700 weston_log("%s: invalid argument\n", __func__);
2701 return -1;
2702 }
2703
2704 prop = &ivisurf->pending.prop;
2705 prop->transition_type = type;
2706 prop->transition_duration = duration;
2707 return 0;
2708}
2709
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09002710static int32_t
2711ivi_layout_surface_dump(struct weston_surface *surface,
2712 void *target, size_t size,int32_t x, int32_t y,
2713 int32_t width, int32_t height)
2714{
2715 int result = 0;
2716
2717 if (surface == NULL) {
2718 weston_log("%s: invalid argument\n", __func__);
2719 return IVI_FAILED;
2720 }
2721
2722 result = weston_surface_copy_content(
2723 surface, target, size,
2724 x, y, width, height);
2725
2726 return result == 0 ? IVI_SUCCEEDED : IVI_FAILED;
2727}
2728
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002729/**
2730 * methods of interaction between ivi-shell with ivi-layout
2731 */
2732struct weston_view *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002733ivi_layout_get_weston_view(struct ivi_layout_surface *surface)
2734{
2735 struct weston_view *tmpview = NULL;
2736
2737 if(surface == NULL)
2738 return NULL;
2739
2740 wl_list_for_each(tmpview, &surface->surface->views, surface_link)
2741 {
2742 if (tmpview != NULL) {
2743 break;
2744 }
2745 }
2746 return tmpview;
2747}
2748
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002749void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002750ivi_layout_surface_configure(struct ivi_layout_surface *ivisurf,
2751 int32_t width, int32_t height)
2752{
2753 struct ivi_layout *layout = get_instance();
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002754
Nobuhiko Tanibatae6cc9972015-04-27 16:54:01 +09002755 /* emit callback which is set by ivi-layout api user */
2756 wl_signal_emit(&layout->surface_notification.configure_changed,
2757 ivisurf);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002758}
2759
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002760static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002761ivi_layout_surface_set_content_observer(struct ivi_layout_surface *ivisurf,
2762 ivi_controller_surface_content_callback callback,
2763 void* userdata)
2764{
2765 int32_t ret = IVI_FAILED;
2766
2767 if (ivisurf != NULL) {
2768 ivisurf->content_observer.callback = callback;
2769 ivisurf->content_observer.userdata = userdata;
2770 ret = IVI_SUCCEEDED;
2771 }
2772 return ret;
2773}
2774
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002775struct ivi_layout_surface*
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002776ivi_layout_surface_create(struct weston_surface *wl_surface,
2777 uint32_t id_surface)
2778{
2779 struct ivi_layout *layout = get_instance();
2780 struct ivi_layout_surface *ivisurf = NULL;
2781 struct weston_view *tmpview = NULL;
2782
2783 if (wl_surface == NULL) {
2784 weston_log("ivi_layout_surface_create: invalid argument\n");
2785 return NULL;
2786 }
2787
2788 ivisurf = get_surface(&layout->surface_list, id_surface);
2789 if (ivisurf != NULL) {
2790 if (ivisurf->surface != NULL) {
2791 weston_log("id_surface(%d) is already created\n", id_surface);
2792 return NULL;
2793 }
2794 }
2795
2796 ivisurf = calloc(1, sizeof *ivisurf);
2797 if (ivisurf == NULL) {
2798 weston_log("fails to allocate memory\n");
2799 return NULL;
2800 }
2801
2802 wl_list_init(&ivisurf->link);
2803 wl_signal_init(&ivisurf->property_changed);
2804 wl_signal_init(&ivisurf->configured);
2805 wl_list_init(&ivisurf->layer_list);
2806 ivisurf->id_surface = id_surface;
2807 ivisurf->layout = layout;
2808
2809 ivisurf->surface = wl_surface;
2810 ivisurf->surface_destroy_listener.notify =
2811 westonsurface_destroy_from_ivisurface;
2812 wl_resource_add_destroy_listener(wl_surface->resource,
2813 &ivisurf->surface_destroy_listener);
2814
2815 tmpview = weston_view_create(wl_surface);
2816 if (tmpview == NULL) {
2817 weston_log("fails to allocate memory\n");
2818 }
2819
2820 ivisurf->surface->width_from_buffer = 0;
2821 ivisurf->surface->height_from_buffer = 0;
2822
2823 weston_matrix_init(&ivisurf->surface_rotation.matrix);
2824 weston_matrix_init(&ivisurf->layer_rotation.matrix);
2825 weston_matrix_init(&ivisurf->surface_pos.matrix);
2826 weston_matrix_init(&ivisurf->layer_pos.matrix);
2827 weston_matrix_init(&ivisurf->scaling.matrix);
2828
2829 wl_list_init(&ivisurf->surface_rotation.link);
2830 wl_list_init(&ivisurf->layer_rotation.link);
2831 wl_list_init(&ivisurf->surface_pos.link);
2832 wl_list_init(&ivisurf->layer_pos.link);
2833 wl_list_init(&ivisurf->scaling.link);
2834
2835 init_surface_properties(&ivisurf->prop);
2836 ivisurf->event_mask = 0;
2837
2838 ivisurf->pending.prop = ivisurf->prop;
2839 wl_list_init(&ivisurf->pending.link);
2840
2841 wl_list_init(&ivisurf->order.link);
2842 wl_list_init(&ivisurf->order.layer_list);
2843
2844 wl_list_insert(&layout->surface_list, &ivisurf->link);
2845
2846 wl_signal_emit(&layout->surface_notification.created, ivisurf);
2847
2848 return ivisurf;
2849}
2850
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002851void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002852ivi_layout_init_with_compositor(struct weston_compositor *ec)
2853{
2854 struct ivi_layout *layout = get_instance();
2855
2856 layout->compositor = ec;
2857
2858 wl_list_init(&layout->surface_list);
2859 wl_list_init(&layout->layer_list);
2860 wl_list_init(&layout->screen_list);
2861
2862 wl_signal_init(&layout->layer_notification.created);
2863 wl_signal_init(&layout->layer_notification.removed);
2864
2865 wl_signal_init(&layout->surface_notification.created);
2866 wl_signal_init(&layout->surface_notification.removed);
2867 wl_signal_init(&layout->surface_notification.configure_changed);
2868
2869 /* Add layout_layer at the last of weston_compositor.layer_list */
2870 weston_layer_init(&layout->layout_layer, ec->layer_list.prev);
2871
2872 create_screen(ec);
2873
2874 layout->transitions = ivi_layout_transition_set_create(ec);
2875 wl_list_init(&layout->pending_transition_list);
2876}
2877
2878
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002879void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002880ivi_layout_surface_add_configured_listener(struct ivi_layout_surface* ivisurf,
2881 struct wl_listener* listener)
2882{
2883 wl_signal_add(&ivisurf->configured, listener);
2884}
2885
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002886static struct ivi_controller_interface ivi_controller_interface = {
2887 /**
2888 * commit all changes
2889 */
2890 .commit_changes = ivi_layout_commit_changes,
2891
2892 /**
2893 * surface controller interfaces
2894 */
2895 .add_notification_create_surface = ivi_layout_add_notification_create_surface,
2896 .remove_notification_create_surface = ivi_layout_remove_notification_create_surface,
2897 .add_notification_remove_surface = ivi_layout_add_notification_remove_surface,
2898 .remove_notification_remove_surface = ivi_layout_remove_notification_remove_surface,
2899 .add_notification_configure_surface = ivi_layout_add_notification_configure_surface,
2900 .remove_notification_configure_surface = ivi_layout_remove_notification_configure_surface,
2901 .get_surfaces = ivi_layout_get_surfaces,
2902 .get_id_of_surface = ivi_layout_get_id_of_surface,
2903 .get_surface_from_id = ivi_layout_get_surface_from_id,
2904 .get_properties_of_surface = ivi_layout_get_properties_of_surface,
2905 .get_surfaces_on_layer = ivi_layout_get_surfaces_on_layer,
2906 .surface_set_visibility = ivi_layout_surface_set_visibility,
2907 .surface_get_visibility = ivi_layout_surface_get_visibility,
2908 .surface_set_opacity = ivi_layout_surface_set_opacity,
2909 .surface_get_opacity = ivi_layout_surface_get_opacity,
2910 .surface_set_source_rectangle = ivi_layout_surface_set_source_rectangle,
2911 .surface_set_destination_rectangle = ivi_layout_surface_set_destination_rectangle,
2912 .surface_set_position = ivi_layout_surface_set_position,
2913 .surface_get_position = ivi_layout_surface_get_position,
2914 .surface_set_dimension = ivi_layout_surface_set_dimension,
2915 .surface_get_dimension = ivi_layout_surface_get_dimension,
2916 .surface_set_orientation = ivi_layout_surface_set_orientation,
2917 .surface_get_orientation = ivi_layout_surface_get_orientation,
2918 .surface_set_content_observer = ivi_layout_surface_set_content_observer,
2919 .surface_add_notification = ivi_layout_surface_add_notification,
2920 .surface_remove_notification = ivi_layout_surface_remove_notification,
2921 .surface_get_weston_surface = ivi_layout_surface_get_weston_surface,
2922 .surface_set_transition = ivi_layout_surface_set_transition,
2923 .surface_set_transition_duration = ivi_layout_surface_set_transition_duration,
2924
2925 /**
2926 * layer controller interfaces
2927 */
2928 .add_notification_create_layer = ivi_layout_add_notification_create_layer,
2929 .remove_notification_create_layer = ivi_layout_remove_notification_create_layer,
2930 .add_notification_remove_layer = ivi_layout_add_notification_remove_layer,
2931 .remove_notification_remove_layer = ivi_layout_remove_notification_remove_layer,
2932 .layer_create_with_dimension = ivi_layout_layer_create_with_dimension,
2933 .layer_remove = ivi_layout_layer_remove,
2934 .get_layers = ivi_layout_get_layers,
2935 .get_id_of_layer = ivi_layout_get_id_of_layer,
2936 .get_layer_from_id = ivi_layout_get_layer_from_id,
2937 .get_properties_of_layer = ivi_layout_get_properties_of_layer,
2938 .get_layers_under_surface = ivi_layout_get_layers_under_surface,
2939 .get_layers_on_screen = ivi_layout_get_layers_on_screen,
2940 .layer_set_visibility = ivi_layout_layer_set_visibility,
2941 .layer_get_visibility = ivi_layout_layer_get_visibility,
2942 .layer_set_opacity = ivi_layout_layer_set_opacity,
2943 .layer_get_opacity = ivi_layout_layer_get_opacity,
2944 .layer_set_source_rectangle = ivi_layout_layer_set_source_rectangle,
2945 .layer_set_destination_rectangle = ivi_layout_layer_set_destination_rectangle,
2946 .layer_set_position = ivi_layout_layer_set_position,
2947 .layer_get_position = ivi_layout_layer_get_position,
2948 .layer_set_dimension = ivi_layout_layer_set_dimension,
2949 .layer_get_dimension = ivi_layout_layer_get_dimension,
2950 .layer_set_orientation = ivi_layout_layer_set_orientation,
2951 .layer_get_orientation = ivi_layout_layer_get_orientation,
2952 .layer_add_surface = ivi_layout_layer_add_surface,
2953 .layer_remove_surface = ivi_layout_layer_remove_surface,
2954 .layer_set_render_order = ivi_layout_layer_set_render_order,
2955 .layer_add_notification = ivi_layout_layer_add_notification,
2956 .layer_remove_notification = ivi_layout_layer_remove_notification,
2957 .layer_set_transition = ivi_layout_layer_set_transition,
2958
2959 /**
2960 * screen controller interfaces
2961 */
2962 .get_screen_from_id = ivi_layout_get_screen_from_id,
2963 .get_screen_resolution = ivi_layout_get_screen_resolution,
2964 .get_screens = ivi_layout_get_screens,
2965 .get_screens_under_layer = ivi_layout_get_screens_under_layer,
2966 .screen_add_layer = ivi_layout_screen_add_layer,
2967 .screen_set_render_order = ivi_layout_screen_set_render_order,
2968 .screen_get_output = ivi_layout_screen_get_output,
2969
2970 /**
2971 * animation
2972 */
2973 .transition_move_layer_cancel = ivi_layout_transition_move_layer_cancel,
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09002974 .layer_set_fade_info = ivi_layout_layer_set_fade_info,
2975
2976 /**
2977 * surface content dumping for debugging
2978 */
2979 .surface_get_size = ivi_layout_surface_get_size,
2980 .surface_dump = ivi_layout_surface_dump,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002981};
2982
2983int
2984load_controller_modules(struct weston_compositor *compositor, const char *modules,
2985 int *argc, char *argv[])
2986{
2987 const char *p, *end;
2988 char buffer[256];
2989 int (*controller_module_init)(struct weston_compositor *compositor,
2990 int *argc, char *argv[],
2991 const struct ivi_controller_interface *interface,
2992 size_t interface_version);
2993
2994 if (modules == NULL)
2995 return 0;
2996
2997 p = modules;
2998 while (*p) {
2999 end = strchrnul(p, ',');
3000 snprintf(buffer, sizeof buffer, "%.*s", (int)(end - p), p);
3001
3002 controller_module_init = weston_load_module(buffer, "controller_module_init");
Pekka Paalanen97246c02015-03-26 15:47:29 +02003003 if (!controller_module_init)
3004 return -1;
3005
3006 if (controller_module_init(compositor, argc, argv,
3007 &ivi_controller_interface,
3008 sizeof(struct ivi_controller_interface)) != 0) {
3009 weston_log("ivi-shell: Initialization of controller module fails");
3010 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09003011 }
3012
3013 p = end;
3014 while (*p == ',')
3015 p++;
3016 }
3017
3018 return 0;
3019}