blob: 50ce22fdfed7fbb859e78aec20cbaeedd9033135 [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
Nobuhiko Tanibataa86226c2015-06-22 15:29:20 +09002212 if (ivisurf == NULL ||
2213 opacity < wl_fixed_from_double(0.0) ||
2214 wl_fixed_from_double(1.0) < opacity) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002215 weston_log("ivi_layout_surface_set_opacity: invalid argument\n");
2216 return IVI_FAILED;
2217 }
2218
2219 prop = &ivisurf->pending.prop;
2220 prop->opacity = opacity;
2221
2222 ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY;
2223
2224 return IVI_SUCCEEDED;
2225}
2226
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002227wl_fixed_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002228ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf)
2229{
2230 if (ivisurf == NULL) {
2231 weston_log("ivi_layout_surface_get_opacity: invalid argument\n");
2232 return wl_fixed_from_double(0.0);
2233 }
2234
2235 return ivisurf->prop.opacity;
2236}
2237
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002238int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002239ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
2240 int32_t x, int32_t y,
2241 int32_t width, int32_t height)
2242{
2243 struct ivi_layout_surface_properties *prop = NULL;
2244
2245 if (ivisurf == NULL) {
2246 weston_log("ivi_layout_surface_set_destination_rectangle: invalid argument\n");
2247 return IVI_FAILED;
2248 }
2249
2250 prop = &ivisurf->pending.prop;
2251 prop->start_x = prop->dest_x;
2252 prop->start_y = prop->dest_y;
2253 prop->dest_x = x;
2254 prop->dest_y = y;
2255 prop->start_width = prop->dest_width;
2256 prop->start_height = prop->dest_height;
2257 prop->dest_width = width;
2258 prop->dest_height = height;
2259
2260 ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT;
2261
2262 return IVI_SUCCEEDED;
2263}
2264
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002265static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002266ivi_layout_surface_set_dimension(struct ivi_layout_surface *ivisurf,
2267 int32_t dest_width, int32_t dest_height)
2268{
2269 struct ivi_layout_surface_properties *prop = NULL;
2270
2271 if (ivisurf == NULL) {
2272 weston_log("ivi_layout_surface_set_dimension: invalid argument\n");
2273 return IVI_FAILED;
2274 }
2275
2276 prop = &ivisurf->pending.prop;
2277 prop->dest_width = dest_width;
2278 prop->dest_height = dest_height;
2279
2280 ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION;
2281
2282 return IVI_SUCCEEDED;
2283}
2284
2285int32_t
2286ivi_layout_surface_get_dimension(struct ivi_layout_surface *ivisurf,
2287 int32_t *dest_width, int32_t *dest_height)
2288{
2289 if (ivisurf == NULL || dest_width == NULL || dest_height == NULL) {
2290 weston_log("ivi_layout_surface_get_dimension: invalid argument\n");
2291 return IVI_FAILED;
2292 }
2293
2294 *dest_width = ivisurf->prop.dest_width;
2295 *dest_height = ivisurf->prop.dest_height;
2296
2297 return IVI_SUCCEEDED;
2298}
2299
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002300static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002301ivi_layout_surface_set_position(struct ivi_layout_surface *ivisurf,
2302 int32_t dest_x, int32_t dest_y)
2303{
2304 struct ivi_layout_surface_properties *prop = NULL;
2305
2306 if (ivisurf == NULL) {
2307 weston_log("ivi_layout_surface_set_position: invalid argument\n");
2308 return IVI_FAILED;
2309 }
2310
2311 prop = &ivisurf->pending.prop;
2312 prop->dest_x = dest_x;
2313 prop->dest_y = dest_y;
2314
2315 ivisurf->event_mask |= IVI_NOTIFICATION_POSITION;
2316
2317 return IVI_SUCCEEDED;
2318}
2319
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002320static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002321ivi_layout_surface_get_position(struct ivi_layout_surface *ivisurf,
2322 int32_t *dest_x, int32_t *dest_y)
2323{
2324 if (ivisurf == NULL || dest_x == NULL || dest_y == NULL) {
2325 weston_log("ivi_layout_surface_get_position: invalid argument\n");
2326 return IVI_FAILED;
2327 }
2328
2329 *dest_x = ivisurf->prop.dest_x;
2330 *dest_y = ivisurf->prop.dest_y;
2331
2332 return IVI_SUCCEEDED;
2333}
2334
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002335static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002336ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf,
2337 enum wl_output_transform orientation)
2338{
2339 struct ivi_layout_surface_properties *prop = NULL;
2340
2341 if (ivisurf == NULL) {
2342 weston_log("ivi_layout_surface_set_orientation: invalid argument\n");
2343 return IVI_FAILED;
2344 }
2345
2346 prop = &ivisurf->pending.prop;
2347 prop->orientation = orientation;
2348
2349 ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION;
2350
2351 return IVI_SUCCEEDED;
2352}
2353
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002354static enum wl_output_transform
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002355ivi_layout_surface_get_orientation(struct ivi_layout_surface *ivisurf)
2356{
2357 if (ivisurf == NULL) {
2358 weston_log("ivi_layout_surface_get_orientation: invalid argument\n");
2359 return 0;
2360 }
2361
2362 return ivisurf->prop.orientation;
2363}
2364
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002365static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002366ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn,
2367 struct ivi_layout_layer *addlayer)
2368{
2369 struct ivi_layout *layout = get_instance();
2370 struct ivi_layout_layer *ivilayer = NULL;
2371 struct ivi_layout_layer *next = NULL;
2372 int is_layer_in_scrn = 0;
2373
2374 if (iviscrn == NULL || addlayer == NULL) {
2375 weston_log("ivi_layout_screen_add_layer: invalid argument\n");
2376 return IVI_FAILED;
2377 }
2378
2379 is_layer_in_scrn = is_layer_in_screen(addlayer, iviscrn);
2380 if (is_layer_in_scrn == 1) {
2381 weston_log("ivi_layout_screen_add_layer: addlayer is already available\n");
2382 return IVI_SUCCEEDED;
2383 }
2384
2385 wl_list_for_each_safe(ivilayer, next, &layout->layer_list, link) {
2386 if (ivilayer->id_layer == addlayer->id_layer) {
2387 if (!wl_list_empty(&ivilayer->pending.link)) {
2388 wl_list_remove(&ivilayer->pending.link);
2389 }
2390 wl_list_init(&ivilayer->pending.link);
2391 wl_list_insert(&iviscrn->pending.layer_list,
2392 &ivilayer->pending.link);
2393 break;
2394 }
2395 }
2396
2397 iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
2398
2399 return IVI_SUCCEEDED;
2400}
2401
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002402static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002403ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn,
2404 struct ivi_layout_layer **pLayer,
2405 const int32_t number)
2406{
2407 struct ivi_layout *layout = get_instance();
2408 struct ivi_layout_layer *ivilayer = NULL;
2409 struct ivi_layout_layer *next = NULL;
2410 uint32_t *id_layer = NULL;
2411 int32_t i = 0;
2412
2413 if (iviscrn == NULL) {
2414 weston_log("ivi_layout_screen_set_render_order: invalid argument\n");
2415 return IVI_FAILED;
2416 }
2417
2418 wl_list_for_each_safe(ivilayer, next,
2419 &iviscrn->pending.layer_list, pending.link) {
2420 wl_list_init(&ivilayer->pending.link);
2421 }
2422
2423 wl_list_init(&iviscrn->pending.layer_list);
2424
2425 if (pLayer == NULL) {
2426 wl_list_for_each_safe(ivilayer, next, &iviscrn->pending.layer_list, pending.link) {
2427 if (!wl_list_empty(&ivilayer->pending.link)) {
2428 wl_list_remove(&ivilayer->pending.link);
2429 }
2430
2431 wl_list_init(&ivilayer->pending.link);
2432 }
2433
2434 iviscrn->event_mask |= IVI_NOTIFICATION_REMOVE;
2435 return IVI_SUCCEEDED;
2436 }
2437
2438 for (i = 0; i < number; i++) {
2439 id_layer = &pLayer[i]->id_layer;
2440 wl_list_for_each(ivilayer, &layout->layer_list, link) {
2441 if (*id_layer != ivilayer->id_layer) {
2442 continue;
2443 }
2444
2445 if (!wl_list_empty(&ivilayer->pending.link)) {
2446 wl_list_remove(&ivilayer->pending.link);
2447 }
2448 wl_list_init(&ivilayer->pending.link);
2449 wl_list_insert(&iviscrn->pending.layer_list,
2450 &ivilayer->pending.link);
2451 break;
2452 }
2453 }
2454
2455 iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
2456
2457 return IVI_SUCCEEDED;
2458}
2459
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002460static struct weston_output *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002461ivi_layout_screen_get_output(struct ivi_layout_screen *iviscrn)
2462{
2463 return iviscrn->output;
2464}
2465
2466/**
2467 * This function is used by the additional ivi-module because of dumping ivi_surface sceenshot.
2468 * The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of Genivi's Layer Management.
2469 * This function is used to get the result of drawing by clients.
2470 */
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002471static struct weston_surface *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002472ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf)
2473{
2474 return ivisurf != NULL ? ivisurf->surface : NULL;
2475}
2476
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002477static int32_t
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09002478ivi_layout_surface_get_size(struct ivi_layout_surface *ivisurf,
2479 int32_t *width, int32_t *height,
2480 int32_t *stride)
2481{
2482 int32_t w;
2483 int32_t h;
2484 const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
2485
2486 if (ivisurf == NULL || ivisurf->surface == NULL) {
2487 weston_log("%s: invalid argument\n", __func__);
2488 return IVI_FAILED;
2489 }
2490
2491 weston_surface_get_content_size(ivisurf->surface, &w, &h);
2492
2493 if (width != NULL)
2494 *width = w;
2495
2496 if (height != NULL)
2497 *height = h;
2498
2499 if (stride != NULL)
2500 *stride = w * bytespp;
2501
2502 return IVI_SUCCEEDED;
2503}
2504
2505static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002506ivi_layout_layer_add_notification(struct ivi_layout_layer *ivilayer,
2507 layer_property_notification_func callback,
2508 void *userdata)
2509{
2510 struct ivi_layout_notification_callback *prop_callback = NULL;
2511
2512 if (ivilayer == NULL || callback == NULL) {
2513 weston_log("ivi_layout_layer_add_notification: invalid argument\n");
2514 return IVI_FAILED;
2515 }
2516
2517 prop_callback = malloc(sizeof *prop_callback);
2518 if (prop_callback == NULL) {
2519 weston_log("fails to allocate memory\n");
2520 return IVI_FAILED;
2521 }
2522
2523 prop_callback->callback = callback;
2524 prop_callback->data = userdata;
2525
2526 return add_notification(&ivilayer->property_changed,
2527 layer_prop_changed,
2528 prop_callback);
2529}
2530
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002531static const struct ivi_layout_surface_properties *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002532ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf)
2533{
2534 if (ivisurf == NULL) {
2535 weston_log("ivi_layout_get_properties_of_surface: invalid argument\n");
2536 return NULL;
2537 }
2538
2539 return &ivisurf->prop;
2540}
2541
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002542static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002543ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer,
2544 struct ivi_layout_surface *addsurf)
2545{
2546 struct ivi_layout *layout = get_instance();
2547 struct ivi_layout_surface *ivisurf = NULL;
2548 struct ivi_layout_surface *next = NULL;
2549 int is_surf_in_layer = 0;
2550
2551 if (ivilayer == NULL || addsurf == NULL) {
2552 weston_log("ivi_layout_layer_add_surface: invalid argument\n");
2553 return IVI_FAILED;
2554 }
2555
2556 is_surf_in_layer = is_surface_in_layer(addsurf, ivilayer);
2557 if (is_surf_in_layer == 1) {
2558 weston_log("ivi_layout_layer_add_surface: addsurf is already available\n");
2559 return IVI_SUCCEEDED;
2560 }
2561
2562 wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
2563 if (ivisurf->id_surface == addsurf->id_surface) {
2564 if (!wl_list_empty(&ivisurf->pending.link)) {
2565 wl_list_remove(&ivisurf->pending.link);
2566 }
2567 wl_list_init(&ivisurf->pending.link);
2568 wl_list_insert(&ivilayer->pending.surface_list,
2569 &ivisurf->pending.link);
2570 break;
2571 }
2572 }
2573
2574 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
2575
2576 return IVI_SUCCEEDED;
2577}
2578
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002579static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002580ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer,
2581 struct ivi_layout_surface *remsurf)
2582{
2583 struct ivi_layout_surface *ivisurf = NULL;
2584 struct ivi_layout_surface *next = NULL;
2585
2586 if (ivilayer == NULL || remsurf == NULL) {
2587 weston_log("ivi_layout_layer_remove_surface: invalid argument\n");
2588 return;
2589 }
2590
2591 wl_list_for_each_safe(ivisurf, next,
2592 &ivilayer->pending.surface_list, pending.link) {
2593 if (ivisurf->id_surface == remsurf->id_surface) {
2594 if (!wl_list_empty(&ivisurf->pending.link)) {
2595 wl_list_remove(&ivisurf->pending.link);
2596 }
2597 wl_list_init(&ivisurf->pending.link);
2598 break;
2599 }
2600 }
2601
2602 remsurf->event_mask |= IVI_NOTIFICATION_REMOVE;
2603}
2604
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002605static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002606ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf,
2607 int32_t x, int32_t y,
2608 int32_t width, int32_t height)
2609{
2610 struct ivi_layout_surface_properties *prop = NULL;
2611
2612 if (ivisurf == NULL) {
2613 weston_log("ivi_layout_surface_set_source_rectangle: invalid argument\n");
2614 return IVI_FAILED;
2615 }
2616
2617 prop = &ivisurf->pending.prop;
2618 prop->source_x = x;
2619 prop->source_y = y;
2620 prop->source_width = width;
2621 prop->source_height = height;
2622
2623 ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
2624
2625 return IVI_SUCCEEDED;
2626}
2627
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002628int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002629ivi_layout_commit_changes(void)
2630{
2631 struct ivi_layout *layout = get_instance();
2632
2633 commit_surface_list(layout);
2634 commit_layer_list(layout);
2635 commit_screen_list(layout);
2636
2637 commit_transition(layout);
2638
2639 commit_changes(layout);
2640 send_prop(layout);
2641 weston_compositor_schedule_repaint(layout->compositor);
2642
2643 return IVI_SUCCEEDED;
2644}
2645
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002646static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002647ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer,
2648 enum ivi_layout_transition_type type,
2649 uint32_t duration)
2650{
2651 if (ivilayer == NULL) {
2652 weston_log("%s: invalid argument\n", __func__);
2653 return -1;
2654 }
2655
2656 ivilayer->pending.prop.transition_type = type;
2657 ivilayer->pending.prop.transition_duration = duration;
2658
2659 return 0;
2660}
2661
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002662static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002663ivi_layout_layer_set_fade_info(struct ivi_layout_layer* ivilayer,
2664 uint32_t is_fade_in,
2665 double start_alpha, double end_alpha)
2666{
2667 if (ivilayer == NULL) {
2668 weston_log("%s: invalid argument\n", __func__);
2669 return -1;
2670 }
2671
2672 ivilayer->pending.prop.is_fade_in = is_fade_in;
2673 ivilayer->pending.prop.start_alpha = start_alpha;
2674 ivilayer->pending.prop.end_alpha = end_alpha;
2675
2676 return 0;
2677}
2678
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002679static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002680ivi_layout_surface_set_transition_duration(struct ivi_layout_surface *ivisurf,
2681 uint32_t duration)
2682{
2683 struct ivi_layout_surface_properties *prop;
2684
2685 if (ivisurf == NULL) {
2686 weston_log("%s: invalid argument\n", __func__);
2687 return -1;
2688 }
2689
2690 prop = &ivisurf->pending.prop;
2691 prop->transition_duration = duration*10;
2692 return 0;
2693}
2694
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002695static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002696ivi_layout_surface_set_transition(struct ivi_layout_surface *ivisurf,
2697 enum ivi_layout_transition_type type,
2698 uint32_t duration)
2699{
2700 struct ivi_layout_surface_properties *prop;
2701
2702 if (ivisurf == NULL) {
2703 weston_log("%s: invalid argument\n", __func__);
2704 return -1;
2705 }
2706
2707 prop = &ivisurf->pending.prop;
2708 prop->transition_type = type;
2709 prop->transition_duration = duration;
2710 return 0;
2711}
2712
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09002713static int32_t
2714ivi_layout_surface_dump(struct weston_surface *surface,
2715 void *target, size_t size,int32_t x, int32_t y,
2716 int32_t width, int32_t height)
2717{
2718 int result = 0;
2719
2720 if (surface == NULL) {
2721 weston_log("%s: invalid argument\n", __func__);
2722 return IVI_FAILED;
2723 }
2724
2725 result = weston_surface_copy_content(
2726 surface, target, size,
2727 x, y, width, height);
2728
2729 return result == 0 ? IVI_SUCCEEDED : IVI_FAILED;
2730}
2731
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002732/**
2733 * methods of interaction between ivi-shell with ivi-layout
2734 */
2735struct weston_view *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002736ivi_layout_get_weston_view(struct ivi_layout_surface *surface)
2737{
2738 struct weston_view *tmpview = NULL;
2739
2740 if(surface == NULL)
2741 return NULL;
2742
2743 wl_list_for_each(tmpview, &surface->surface->views, surface_link)
2744 {
2745 if (tmpview != NULL) {
2746 break;
2747 }
2748 }
2749 return tmpview;
2750}
2751
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002752void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002753ivi_layout_surface_configure(struct ivi_layout_surface *ivisurf,
2754 int32_t width, int32_t height)
2755{
2756 struct ivi_layout *layout = get_instance();
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002757
Nobuhiko Tanibatae6cc9972015-04-27 16:54:01 +09002758 /* emit callback which is set by ivi-layout api user */
2759 wl_signal_emit(&layout->surface_notification.configure_changed,
2760 ivisurf);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002761}
2762
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002763static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002764ivi_layout_surface_set_content_observer(struct ivi_layout_surface *ivisurf,
2765 ivi_controller_surface_content_callback callback,
2766 void* userdata)
2767{
2768 int32_t ret = IVI_FAILED;
2769
2770 if (ivisurf != NULL) {
2771 ivisurf->content_observer.callback = callback;
2772 ivisurf->content_observer.userdata = userdata;
2773 ret = IVI_SUCCEEDED;
2774 }
2775 return ret;
2776}
2777
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002778struct ivi_layout_surface*
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002779ivi_layout_surface_create(struct weston_surface *wl_surface,
2780 uint32_t id_surface)
2781{
2782 struct ivi_layout *layout = get_instance();
2783 struct ivi_layout_surface *ivisurf = NULL;
2784 struct weston_view *tmpview = NULL;
2785
2786 if (wl_surface == NULL) {
2787 weston_log("ivi_layout_surface_create: invalid argument\n");
2788 return NULL;
2789 }
2790
2791 ivisurf = get_surface(&layout->surface_list, id_surface);
2792 if (ivisurf != NULL) {
2793 if (ivisurf->surface != NULL) {
2794 weston_log("id_surface(%d) is already created\n", id_surface);
2795 return NULL;
2796 }
2797 }
2798
2799 ivisurf = calloc(1, sizeof *ivisurf);
2800 if (ivisurf == NULL) {
2801 weston_log("fails to allocate memory\n");
2802 return NULL;
2803 }
2804
2805 wl_list_init(&ivisurf->link);
2806 wl_signal_init(&ivisurf->property_changed);
2807 wl_signal_init(&ivisurf->configured);
2808 wl_list_init(&ivisurf->layer_list);
2809 ivisurf->id_surface = id_surface;
2810 ivisurf->layout = layout;
2811
2812 ivisurf->surface = wl_surface;
2813 ivisurf->surface_destroy_listener.notify =
2814 westonsurface_destroy_from_ivisurface;
2815 wl_resource_add_destroy_listener(wl_surface->resource,
2816 &ivisurf->surface_destroy_listener);
2817
2818 tmpview = weston_view_create(wl_surface);
2819 if (tmpview == NULL) {
2820 weston_log("fails to allocate memory\n");
2821 }
2822
2823 ivisurf->surface->width_from_buffer = 0;
2824 ivisurf->surface->height_from_buffer = 0;
2825
2826 weston_matrix_init(&ivisurf->surface_rotation.matrix);
2827 weston_matrix_init(&ivisurf->layer_rotation.matrix);
2828 weston_matrix_init(&ivisurf->surface_pos.matrix);
2829 weston_matrix_init(&ivisurf->layer_pos.matrix);
2830 weston_matrix_init(&ivisurf->scaling.matrix);
2831
2832 wl_list_init(&ivisurf->surface_rotation.link);
2833 wl_list_init(&ivisurf->layer_rotation.link);
2834 wl_list_init(&ivisurf->surface_pos.link);
2835 wl_list_init(&ivisurf->layer_pos.link);
2836 wl_list_init(&ivisurf->scaling.link);
2837
2838 init_surface_properties(&ivisurf->prop);
2839 ivisurf->event_mask = 0;
2840
2841 ivisurf->pending.prop = ivisurf->prop;
2842 wl_list_init(&ivisurf->pending.link);
2843
2844 wl_list_init(&ivisurf->order.link);
2845 wl_list_init(&ivisurf->order.layer_list);
2846
2847 wl_list_insert(&layout->surface_list, &ivisurf->link);
2848
2849 wl_signal_emit(&layout->surface_notification.created, ivisurf);
2850
2851 return ivisurf;
2852}
2853
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002854void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002855ivi_layout_init_with_compositor(struct weston_compositor *ec)
2856{
2857 struct ivi_layout *layout = get_instance();
2858
2859 layout->compositor = ec;
2860
2861 wl_list_init(&layout->surface_list);
2862 wl_list_init(&layout->layer_list);
2863 wl_list_init(&layout->screen_list);
2864
2865 wl_signal_init(&layout->layer_notification.created);
2866 wl_signal_init(&layout->layer_notification.removed);
2867
2868 wl_signal_init(&layout->surface_notification.created);
2869 wl_signal_init(&layout->surface_notification.removed);
2870 wl_signal_init(&layout->surface_notification.configure_changed);
2871
2872 /* Add layout_layer at the last of weston_compositor.layer_list */
2873 weston_layer_init(&layout->layout_layer, ec->layer_list.prev);
2874
2875 create_screen(ec);
2876
2877 layout->transitions = ivi_layout_transition_set_create(ec);
2878 wl_list_init(&layout->pending_transition_list);
2879}
2880
2881
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002882void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002883ivi_layout_surface_add_configured_listener(struct ivi_layout_surface* ivisurf,
2884 struct wl_listener* listener)
2885{
2886 wl_signal_add(&ivisurf->configured, listener);
2887}
2888
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002889static struct ivi_controller_interface ivi_controller_interface = {
2890 /**
2891 * commit all changes
2892 */
2893 .commit_changes = ivi_layout_commit_changes,
2894
2895 /**
2896 * surface controller interfaces
2897 */
2898 .add_notification_create_surface = ivi_layout_add_notification_create_surface,
2899 .remove_notification_create_surface = ivi_layout_remove_notification_create_surface,
2900 .add_notification_remove_surface = ivi_layout_add_notification_remove_surface,
2901 .remove_notification_remove_surface = ivi_layout_remove_notification_remove_surface,
2902 .add_notification_configure_surface = ivi_layout_add_notification_configure_surface,
2903 .remove_notification_configure_surface = ivi_layout_remove_notification_configure_surface,
2904 .get_surfaces = ivi_layout_get_surfaces,
2905 .get_id_of_surface = ivi_layout_get_id_of_surface,
2906 .get_surface_from_id = ivi_layout_get_surface_from_id,
2907 .get_properties_of_surface = ivi_layout_get_properties_of_surface,
2908 .get_surfaces_on_layer = ivi_layout_get_surfaces_on_layer,
2909 .surface_set_visibility = ivi_layout_surface_set_visibility,
2910 .surface_get_visibility = ivi_layout_surface_get_visibility,
2911 .surface_set_opacity = ivi_layout_surface_set_opacity,
2912 .surface_get_opacity = ivi_layout_surface_get_opacity,
2913 .surface_set_source_rectangle = ivi_layout_surface_set_source_rectangle,
2914 .surface_set_destination_rectangle = ivi_layout_surface_set_destination_rectangle,
2915 .surface_set_position = ivi_layout_surface_set_position,
2916 .surface_get_position = ivi_layout_surface_get_position,
2917 .surface_set_dimension = ivi_layout_surface_set_dimension,
2918 .surface_get_dimension = ivi_layout_surface_get_dimension,
2919 .surface_set_orientation = ivi_layout_surface_set_orientation,
2920 .surface_get_orientation = ivi_layout_surface_get_orientation,
2921 .surface_set_content_observer = ivi_layout_surface_set_content_observer,
2922 .surface_add_notification = ivi_layout_surface_add_notification,
2923 .surface_remove_notification = ivi_layout_surface_remove_notification,
2924 .surface_get_weston_surface = ivi_layout_surface_get_weston_surface,
2925 .surface_set_transition = ivi_layout_surface_set_transition,
2926 .surface_set_transition_duration = ivi_layout_surface_set_transition_duration,
2927
2928 /**
2929 * layer controller interfaces
2930 */
2931 .add_notification_create_layer = ivi_layout_add_notification_create_layer,
2932 .remove_notification_create_layer = ivi_layout_remove_notification_create_layer,
2933 .add_notification_remove_layer = ivi_layout_add_notification_remove_layer,
2934 .remove_notification_remove_layer = ivi_layout_remove_notification_remove_layer,
2935 .layer_create_with_dimension = ivi_layout_layer_create_with_dimension,
2936 .layer_remove = ivi_layout_layer_remove,
2937 .get_layers = ivi_layout_get_layers,
2938 .get_id_of_layer = ivi_layout_get_id_of_layer,
2939 .get_layer_from_id = ivi_layout_get_layer_from_id,
2940 .get_properties_of_layer = ivi_layout_get_properties_of_layer,
2941 .get_layers_under_surface = ivi_layout_get_layers_under_surface,
2942 .get_layers_on_screen = ivi_layout_get_layers_on_screen,
2943 .layer_set_visibility = ivi_layout_layer_set_visibility,
2944 .layer_get_visibility = ivi_layout_layer_get_visibility,
2945 .layer_set_opacity = ivi_layout_layer_set_opacity,
2946 .layer_get_opacity = ivi_layout_layer_get_opacity,
2947 .layer_set_source_rectangle = ivi_layout_layer_set_source_rectangle,
2948 .layer_set_destination_rectangle = ivi_layout_layer_set_destination_rectangle,
2949 .layer_set_position = ivi_layout_layer_set_position,
2950 .layer_get_position = ivi_layout_layer_get_position,
2951 .layer_set_dimension = ivi_layout_layer_set_dimension,
2952 .layer_get_dimension = ivi_layout_layer_get_dimension,
2953 .layer_set_orientation = ivi_layout_layer_set_orientation,
2954 .layer_get_orientation = ivi_layout_layer_get_orientation,
2955 .layer_add_surface = ivi_layout_layer_add_surface,
2956 .layer_remove_surface = ivi_layout_layer_remove_surface,
2957 .layer_set_render_order = ivi_layout_layer_set_render_order,
2958 .layer_add_notification = ivi_layout_layer_add_notification,
2959 .layer_remove_notification = ivi_layout_layer_remove_notification,
2960 .layer_set_transition = ivi_layout_layer_set_transition,
2961
2962 /**
2963 * screen controller interfaces
2964 */
2965 .get_screen_from_id = ivi_layout_get_screen_from_id,
2966 .get_screen_resolution = ivi_layout_get_screen_resolution,
2967 .get_screens = ivi_layout_get_screens,
2968 .get_screens_under_layer = ivi_layout_get_screens_under_layer,
2969 .screen_add_layer = ivi_layout_screen_add_layer,
2970 .screen_set_render_order = ivi_layout_screen_set_render_order,
2971 .screen_get_output = ivi_layout_screen_get_output,
2972
2973 /**
2974 * animation
2975 */
2976 .transition_move_layer_cancel = ivi_layout_transition_move_layer_cancel,
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09002977 .layer_set_fade_info = ivi_layout_layer_set_fade_info,
2978
2979 /**
2980 * surface content dumping for debugging
2981 */
2982 .surface_get_size = ivi_layout_surface_get_size,
2983 .surface_dump = ivi_layout_surface_dump,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002984};
2985
2986int
2987load_controller_modules(struct weston_compositor *compositor, const char *modules,
2988 int *argc, char *argv[])
2989{
2990 const char *p, *end;
2991 char buffer[256];
2992 int (*controller_module_init)(struct weston_compositor *compositor,
2993 int *argc, char *argv[],
2994 const struct ivi_controller_interface *interface,
2995 size_t interface_version);
2996
2997 if (modules == NULL)
2998 return 0;
2999
3000 p = modules;
3001 while (*p) {
3002 end = strchrnul(p, ',');
3003 snprintf(buffer, sizeof buffer, "%.*s", (int)(end - p), p);
3004
3005 controller_module_init = weston_load_module(buffer, "controller_module_init");
Pekka Paalanen97246c02015-03-26 15:47:29 +02003006 if (!controller_module_init)
3007 return -1;
3008
3009 if (controller_module_init(compositor, argc, argv,
3010 &ivi_controller_interface,
3011 sizeof(struct ivi_controller_interface)) != 0) {
3012 weston_log("ivi-shell: Initialization of controller module fails");
3013 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09003014 }
3015
3016 p = end;
3017 while (*p == ',')
3018 p++;
3019 }
3020
3021 return 0;
3022}