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