blob: 079b3e3a9d0e322441dffc776c4705823e3ab6c0 [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/**
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900323 * Called at destruction of wl_surface/ivi_surface
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900324 */
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900325void
326ivi_layout_surface_destroy(struct ivi_layout_surface *ivisurf)
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900327{
328 struct ivi_layout *layout = get_instance();
329
330 if (ivisurf == NULL) {
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900331 weston_log("%s: invalid argument\n", __func__);
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900332 return;
333 }
334
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900335 wl_list_remove(&ivisurf->surface_rotation.link);
336 wl_list_remove(&ivisurf->layer_rotation.link);
337 wl_list_remove(&ivisurf->surface_pos.link);
338 wl_list_remove(&ivisurf->layer_pos.link);
339 wl_list_remove(&ivisurf->scaling.link);
340
341 wl_list_remove(&ivisurf->pending.link);
342 wl_list_remove(&ivisurf->order.link);
343 wl_list_remove(&ivisurf->link);
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900344 remove_ordersurface_from_layer(ivisurf);
345
346 wl_signal_emit(&layout->surface_notification.removed, ivisurf);
347
348 remove_configured_listener(ivisurf);
349
350 ivi_layout_surface_remove_notification(ivisurf);
351
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900352 ivisurf->surface = NULL;
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900353
354 free(ivisurf);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900355}
356
357/**
358 * Internal API to check ivi_layer/ivi_surface already added in ivi_layer/ivi_screen.
359 * Called by ivi_layout_layer_add_surface/ivi_layout_screenAddLayer
360 */
361static int
362is_surface_in_layer(struct ivi_layout_surface *ivisurf,
363 struct ivi_layout_layer *ivilayer)
364{
365 struct ivi_layout_surface *surf = NULL;
366
367 wl_list_for_each(surf, &ivilayer->pending.surface_list, pending.link) {
368 if (surf->id_surface == ivisurf->id_surface) {
369 return 1;
370 }
371 }
372
373 return 0;
374}
375
376static int
377is_layer_in_screen(struct ivi_layout_layer *ivilayer,
378 struct ivi_layout_screen *iviscrn)
379{
380 struct ivi_layout_layer *layer = NULL;
381
382 wl_list_for_each(layer, &iviscrn->pending.layer_list, pending.link) {
383 if (layer->id_layer == ivilayer->id_layer) {
384 return 1;
385 }
386 }
387
388 return 0;
389}
390
391/**
392 * Internal API to initialize ivi_screens found from output_list of weston_compositor.
393 * Called by ivi_layout_init_with_compositor.
394 */
395static void
396create_screen(struct weston_compositor *ec)
397{
398 struct ivi_layout *layout = get_instance();
399 struct ivi_layout_screen *iviscrn = NULL;
400 struct weston_output *output = NULL;
401 int32_t count = 0;
402
403 wl_list_for_each(output, &ec->output_list, link) {
404 iviscrn = calloc(1, sizeof *iviscrn);
405 if (iviscrn == NULL) {
406 weston_log("fails to allocate memory\n");
407 continue;
408 }
409
410 wl_list_init(&iviscrn->link);
411 iviscrn->layout = layout;
412
413 iviscrn->id_screen = count;
414 count++;
415
416 iviscrn->output = output;
417 iviscrn->event_mask = 0;
418
419 wl_list_init(&iviscrn->pending.layer_list);
420 wl_list_init(&iviscrn->pending.link);
421
422 wl_list_init(&iviscrn->order.layer_list);
423 wl_list_init(&iviscrn->order.link);
424
425 wl_list_init(&iviscrn->link_to_layer);
426
427 wl_list_insert(&layout->screen_list, &iviscrn->link);
428 }
429}
430
431/**
432 * Internal APIs to initialize properties of ivi_surface/ivi_layer when they are created.
433 */
434static void
435init_layer_properties(struct ivi_layout_layer_properties *prop,
436 int32_t width, int32_t height)
437{
438 memset(prop, 0, sizeof *prop);
439 prop->opacity = wl_fixed_from_double(1.0);
440 prop->source_width = width;
441 prop->source_height = height;
442 prop->dest_width = width;
443 prop->dest_height = height;
444}
445
446static void
447init_surface_properties(struct ivi_layout_surface_properties *prop)
448{
449 memset(prop, 0, sizeof *prop);
450 prop->opacity = wl_fixed_from_double(1.0);
Nobuhiko Tanibatae259a7a2015-04-27 17:02:54 +0900451 /*
452 * FIXME: this shall be finxed by ivi-layout-transition.
453 */
454 prop->dest_width = 1;
455 prop->dest_height = 1;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900456}
457
458/**
459 * Internal APIs to be called from ivi_layout_commit_changes.
460 */
461static void
462update_opacity(struct ivi_layout_layer *ivilayer,
463 struct ivi_layout_surface *ivisurf)
464{
465 double layer_alpha = wl_fixed_to_double(ivilayer->prop.opacity);
466 double surf_alpha = wl_fixed_to_double(ivisurf->prop.opacity);
467
468 if ((ivilayer->event_mask & IVI_NOTIFICATION_OPACITY) ||
469 (ivisurf->event_mask & IVI_NOTIFICATION_OPACITY)) {
470 struct weston_view *tmpview = NULL;
471 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
472 if (tmpview == NULL) {
473 continue;
474 }
475 tmpview->alpha = layer_alpha * surf_alpha;
476 }
477 }
478}
479
480static void
481update_surface_orientation(struct ivi_layout_layer *ivilayer,
482 struct ivi_layout_surface *ivisurf)
483{
484 struct weston_view *view;
485 struct weston_matrix *matrix = &ivisurf->surface_rotation.matrix;
486 float width = 0.0f;
487 float height = 0.0f;
488 float v_sin = 0.0f;
489 float v_cos = 0.0f;
490 float cx = 0.0f;
491 float cy = 0.0f;
492 float sx = 1.0f;
493 float sy = 1.0f;
494
495 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
496 if (view != NULL) {
497 break;
498 }
499 }
500
501 if (view == NULL) {
502 return;
503 }
504
505 if ((ivilayer->prop.dest_width == 0) ||
506 (ivilayer->prop.dest_height == 0)) {
507 return;
508 }
509 width = (float)ivilayer->prop.dest_width;
510 height = (float)ivilayer->prop.dest_height;
511
512 switch (ivisurf->prop.orientation) {
513 case WL_OUTPUT_TRANSFORM_NORMAL:
514 v_sin = 0.0f;
515 v_cos = 1.0f;
516 break;
517 case WL_OUTPUT_TRANSFORM_90:
518 v_sin = 1.0f;
519 v_cos = 0.0f;
520 sx = width / height;
521 sy = height / width;
522 break;
523 case WL_OUTPUT_TRANSFORM_180:
524 v_sin = 0.0f;
525 v_cos = -1.0f;
526 break;
527 case WL_OUTPUT_TRANSFORM_270:
528 default:
529 v_sin = -1.0f;
530 v_cos = 0.0f;
531 sx = width / height;
532 sy = height / width;
533 break;
534 }
535 wl_list_remove(&ivisurf->surface_rotation.link);
536 weston_view_geometry_dirty(view);
537
538 weston_matrix_init(matrix);
539 cx = 0.5f * width;
540 cy = 0.5f * height;
541 weston_matrix_translate(matrix, -cx, -cy, 0.0f);
542 weston_matrix_rotate_xy(matrix, v_cos, v_sin);
543 weston_matrix_scale(matrix, sx, sy, 1.0);
544 weston_matrix_translate(matrix, cx, cy, 0.0f);
545 wl_list_insert(&view->geometry.transformation_list,
546 &ivisurf->surface_rotation.link);
547
548 weston_view_set_transform_parent(view, NULL);
549 weston_view_update_transform(view);
550}
551
552static void
553update_layer_orientation(struct ivi_layout_layer *ivilayer,
554 struct ivi_layout_surface *ivisurf)
555{
556 struct weston_surface *es = ivisurf->surface;
557 struct weston_view *view;
558 struct weston_matrix *matrix = &ivisurf->layer_rotation.matrix;
559 struct weston_output *output = NULL;
560 float width = 0.0f;
561 float height = 0.0f;
562 float v_sin = 0.0f;
563 float v_cos = 0.0f;
564 float cx = 0.0f;
565 float cy = 0.0f;
566 float sx = 1.0f;
567 float sy = 1.0f;
568
569 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
570 if (view != NULL) {
571 break;
572 }
573 }
574
575 if (es == NULL || view == NULL) {
576 return;
577 }
578
579 output = es->output;
580 if (output == NULL) {
581 return;
582 }
583 if ((output->width == 0) || (output->height == 0)) {
584 return;
585 }
586 width = (float)output->width;
587 height = (float)output->height;
588
589 switch (ivilayer->prop.orientation) {
590 case WL_OUTPUT_TRANSFORM_NORMAL:
591 v_sin = 0.0f;
592 v_cos = 1.0f;
593 break;
594 case WL_OUTPUT_TRANSFORM_90:
595 v_sin = 1.0f;
596 v_cos = 0.0f;
597 sx = width / height;
598 sy = height / width;
599 break;
600 case WL_OUTPUT_TRANSFORM_180:
601 v_sin = 0.0f;
602 v_cos = -1.0f;
603 break;
604 case WL_OUTPUT_TRANSFORM_270:
605 default:
606 v_sin = -1.0f;
607 v_cos = 0.0f;
608 sx = width / height;
609 sy = height / width;
610 break;
611 }
612 wl_list_remove(&ivisurf->layer_rotation.link);
613 weston_view_geometry_dirty(view);
614
615 weston_matrix_init(matrix);
616 cx = 0.5f * width;
617 cy = 0.5f * height;
618 weston_matrix_translate(matrix, -cx, -cy, 0.0f);
619 weston_matrix_rotate_xy(matrix, v_cos, v_sin);
620 weston_matrix_scale(matrix, sx, sy, 1.0);
621 weston_matrix_translate(matrix, cx, cy, 0.0f);
622 wl_list_insert(&view->geometry.transformation_list,
623 &ivisurf->layer_rotation.link);
624
625 weston_view_set_transform_parent(view, NULL);
626 weston_view_update_transform(view);
627}
628
629static void
630update_surface_position(struct ivi_layout_surface *ivisurf)
631{
632 struct weston_view *view;
633 float tx = (float)ivisurf->prop.dest_x;
634 float ty = (float)ivisurf->prop.dest_y;
635 struct weston_matrix *matrix = &ivisurf->surface_pos.matrix;
636
637 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
638 if (view != NULL) {
639 break;
640 }
641 }
642
643 if (view == NULL) {
644 return;
645 }
646
647 wl_list_remove(&ivisurf->surface_pos.link);
648
649 weston_matrix_init(matrix);
650 weston_matrix_translate(matrix, tx, ty, 0.0f);
651 wl_list_insert(&view->geometry.transformation_list,
652 &ivisurf->surface_pos.link);
653
654 weston_view_set_transform_parent(view, NULL);
655 weston_view_update_transform(view);
656}
657
658static void
659update_layer_position(struct ivi_layout_layer *ivilayer,
660 struct ivi_layout_surface *ivisurf)
661{
662 struct weston_view *view;
663 struct weston_matrix *matrix = &ivisurf->layer_pos.matrix;
664 float tx = (float)ivilayer->prop.dest_x;
665 float ty = (float)ivilayer->prop.dest_y;
666
667 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
668 if (view != NULL) {
669 break;
670 }
671 }
672
673 if (view == NULL) {
674 return;
675 }
676
677 wl_list_remove(&ivisurf->layer_pos.link);
678
679 weston_matrix_init(matrix);
680 weston_matrix_translate(matrix, tx, ty, 0.0f);
681 wl_list_insert(&view->geometry.transformation_list,
682 &ivisurf->layer_pos.link);
683
684 weston_view_set_transform_parent(view, NULL);
685 weston_view_update_transform(view);
686}
687
688static void
689update_scale(struct ivi_layout_layer *ivilayer,
690 struct ivi_layout_surface *ivisurf)
691{
692 struct weston_view *view;
693 struct weston_matrix *matrix = &ivisurf->scaling.matrix;
694 float sx = 0.0f;
695 float sy = 0.0f;
696 float lw = 0.0f;
697 float sw = 0.0f;
698 float lh = 0.0f;
699 float sh = 0.0f;
700
701 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
702 if (view != NULL) {
703 break;
704 }
705 }
706
707 if (view == NULL) {
708 return;
709 }
710
Nobuhiko Tanibatabcff6322015-04-27 16:57:26 +0900711 if (ivisurf->prop.source_width == 0 || ivisurf->prop.source_height == 0) {
712 weston_log("ivi-shell: source rectangle is not yet set by ivi_layout_surface_set_source_rectangle\n");
713 return;
714 }
715
716 if (ivisurf->prop.dest_width == 0 || ivisurf->prop.dest_height == 0) {
717 weston_log("ivi-shell: destination rectangle is not yet set by ivi_layout_surface_set_destination_rectangle\n");
718 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900719 }
720
721 lw = ((float)ivilayer->prop.dest_width / (float)ivilayer->prop.source_width );
722 sw = ((float)ivisurf->prop.dest_width / (float)ivisurf->prop.source_width );
723 lh = ((float)ivilayer->prop.dest_height / (float)ivilayer->prop.source_height);
724 sh = ((float)ivisurf->prop.dest_height / (float)ivisurf->prop.source_height );
725 sx = sw * lw;
726 sy = sh * lh;
727
728 wl_list_remove(&ivisurf->scaling.link);
729 weston_matrix_init(matrix);
730 weston_matrix_scale(matrix, sx, sy, 1.0f);
731
732 wl_list_insert(&view->geometry.transformation_list,
733 &ivisurf->scaling.link);
734
735 weston_view_set_transform_parent(view, NULL);
736 weston_view_update_transform(view);
737}
738
739static void
740update_prop(struct ivi_layout_layer *ivilayer,
741 struct ivi_layout_surface *ivisurf)
742{
743 if (ivilayer->event_mask | ivisurf->event_mask) {
744 struct weston_view *tmpview;
745 update_opacity(ivilayer, ivisurf);
746 update_layer_orientation(ivilayer, ivisurf);
747 update_layer_position(ivilayer, ivisurf);
748 update_surface_position(ivisurf);
749 update_surface_orientation(ivilayer, ivisurf);
750 update_scale(ivilayer, ivisurf);
751
752 ivisurf->update_count++;
753
754 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
755 if (tmpview != NULL) {
756 break;
757 }
758 }
759
760 if (tmpview != NULL) {
761 weston_view_geometry_dirty(tmpview);
762 }
763
764 if (ivisurf->surface != NULL) {
765 weston_surface_damage(ivisurf->surface);
766 }
767 }
768}
769
770static void
771commit_changes(struct ivi_layout *layout)
772{
773 struct ivi_layout_screen *iviscrn = NULL;
774 struct ivi_layout_layer *ivilayer = NULL;
775 struct ivi_layout_surface *ivisurf = NULL;
776
777 wl_list_for_each(iviscrn, &layout->screen_list, link) {
778 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
779 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
780 update_prop(ivilayer, ivisurf);
781 }
782 }
783 }
784}
785
786static void
787commit_surface_list(struct ivi_layout *layout)
788{
789 struct ivi_layout_surface *ivisurf = NULL;
790 int32_t dest_x = 0;
791 int32_t dest_y = 0;
792 int32_t dest_width = 0;
793 int32_t dest_height = 0;
794 int32_t configured = 0;
795
796 wl_list_for_each(ivisurf, &layout->surface_list, link) {
797 if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEFAULT) {
798 dest_x = ivisurf->prop.dest_x;
799 dest_y = ivisurf->prop.dest_y;
800 dest_width = ivisurf->prop.dest_width;
801 dest_height = ivisurf->prop.dest_height;
802
803 ivi_layout_transition_move_resize_view(ivisurf,
804 ivisurf->pending.prop.dest_x,
805 ivisurf->pending.prop.dest_y,
806 ivisurf->pending.prop.dest_width,
807 ivisurf->pending.prop.dest_height,
808 ivisurf->pending.prop.transition_duration);
809
810 if(ivisurf->pending.prop.visibility) {
811 ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
812 } else {
813 ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
814 }
815
816 ivisurf->prop = ivisurf->pending.prop;
817 ivisurf->prop.dest_x = dest_x;
818 ivisurf->prop.dest_y = dest_y;
819 ivisurf->prop.dest_width = dest_width;
820 ivisurf->prop.dest_height = dest_height;
821 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
822 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
823
824 } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY){
825 dest_x = ivisurf->prop.dest_x;
826 dest_y = ivisurf->prop.dest_y;
827 dest_width = ivisurf->prop.dest_width;
828 dest_height = ivisurf->prop.dest_height;
829
830 ivi_layout_transition_move_resize_view(ivisurf,
831 ivisurf->pending.prop.dest_x,
832 ivisurf->pending.prop.dest_y,
833 ivisurf->pending.prop.dest_width,
834 ivisurf->pending.prop.dest_height,
835 ivisurf->pending.prop.transition_duration);
836
837 ivisurf->prop = ivisurf->pending.prop;
838 ivisurf->prop.dest_x = dest_x;
839 ivisurf->prop.dest_y = dest_y;
840 ivisurf->prop.dest_width = dest_width;
841 ivisurf->prop.dest_height = dest_height;
842
843 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
844 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
845
846 } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY){
847 configured = 0;
848 if(ivisurf->pending.prop.visibility) {
849 ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
850 } else {
851 ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
852 }
853
854 if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
855 ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
856 configured = 1;
857 }
858
859 ivisurf->prop = ivisurf->pending.prop;
860 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
861 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
862
863 if (configured && !is_surface_transition(ivisurf))
864 wl_signal_emit(&ivisurf->configured, ivisurf);
865 } else {
866 configured = 0;
867 if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
868 ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
869 configured = 1;
870 }
871
872 ivisurf->prop = ivisurf->pending.prop;
873 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
874 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
875
876 if (configured && !is_surface_transition(ivisurf))
877 wl_signal_emit(&ivisurf->configured, ivisurf);
878 }
879 }
880}
881
882static void
883commit_layer_list(struct ivi_layout *layout)
884{
885 struct ivi_layout_layer *ivilayer = NULL;
886 struct ivi_layout_surface *ivisurf = NULL;
887 struct ivi_layout_surface *next = NULL;
888
889 wl_list_for_each(ivilayer, &layout->layer_list, link) {
890 if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_MOVE) {
891 ivi_layout_transition_move_layer(ivilayer, ivilayer->pending.prop.dest_x, ivilayer->pending.prop.dest_y, ivilayer->pending.prop.transition_duration);
892 } else if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_FADE) {
893 ivi_layout_transition_fade_layer(ivilayer,ivilayer->pending.prop.is_fade_in,
894 ivilayer->pending.prop.start_alpha,ivilayer->pending.prop.end_alpha,
895 NULL, NULL,
896 ivilayer->pending.prop.transition_duration);
897 }
898 ivilayer->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
899
900 ivilayer->prop = ivilayer->pending.prop;
901
902 if (!(ivilayer->event_mask &
903 (IVI_NOTIFICATION_ADD | IVI_NOTIFICATION_REMOVE)) ) {
904 continue;
905 }
906
907 if (ivilayer->event_mask & IVI_NOTIFICATION_REMOVE) {
908 wl_list_for_each_safe(ivisurf, next,
909 &ivilayer->order.surface_list, order.link) {
910 remove_ordersurface_from_layer(ivisurf);
911
912 if (!wl_list_empty(&ivisurf->order.link)) {
913 wl_list_remove(&ivisurf->order.link);
914 }
915
916 wl_list_init(&ivisurf->order.link);
917 ivisurf->event_mask |= IVI_NOTIFICATION_REMOVE;
918 }
919
920 wl_list_init(&ivilayer->order.surface_list);
921 }
922
923 if (ivilayer->event_mask & IVI_NOTIFICATION_ADD) {
924 wl_list_for_each_safe(ivisurf, next,
925 &ivilayer->order.surface_list, order.link) {
926 remove_ordersurface_from_layer(ivisurf);
927
928 if (!wl_list_empty(&ivisurf->order.link)) {
929 wl_list_remove(&ivisurf->order.link);
930 }
931
932 wl_list_init(&ivisurf->order.link);
933 }
934
935 wl_list_init(&ivilayer->order.surface_list);
936 wl_list_for_each(ivisurf, &ivilayer->pending.surface_list,
937 pending.link) {
938 if(!wl_list_empty(&ivisurf->order.link)){
939 wl_list_remove(&ivisurf->order.link);
940 wl_list_init(&ivisurf->order.link);
941 }
942
943 wl_list_insert(&ivilayer->order.surface_list,
944 &ivisurf->order.link);
945 add_ordersurface_to_layer(ivisurf, ivilayer);
946 ivisurf->event_mask |= IVI_NOTIFICATION_ADD;
947 }
948 }
949 }
950}
951
952static void
953commit_screen_list(struct ivi_layout *layout)
954{
955 struct ivi_layout_screen *iviscrn = NULL;
956 struct ivi_layout_layer *ivilayer = NULL;
957 struct ivi_layout_layer *next = NULL;
958 struct ivi_layout_surface *ivisurf = NULL;
959
960 wl_list_for_each(iviscrn, &layout->screen_list, link) {
961 if (iviscrn->event_mask & IVI_NOTIFICATION_REMOVE) {
962 wl_list_for_each_safe(ivilayer, next,
963 &iviscrn->order.layer_list, order.link) {
964 remove_orderlayer_from_screen(ivilayer);
965
966 if (!wl_list_empty(&ivilayer->order.link)) {
967 wl_list_remove(&ivilayer->order.link);
968 }
969
970 wl_list_init(&ivilayer->order.link);
971 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
972 }
973 }
974
975 if (iviscrn->event_mask & IVI_NOTIFICATION_ADD) {
976 wl_list_for_each_safe(ivilayer, next,
977 &iviscrn->order.layer_list, order.link) {
978 remove_orderlayer_from_screen(ivilayer);
979
980 if (!wl_list_empty(&ivilayer->order.link)) {
981 wl_list_remove(&ivilayer->order.link);
982 }
983
984 wl_list_init(&ivilayer->order.link);
985 }
986
987 wl_list_init(&iviscrn->order.layer_list);
988 wl_list_for_each(ivilayer, &iviscrn->pending.layer_list,
989 pending.link) {
990 wl_list_insert(&iviscrn->order.layer_list,
991 &ivilayer->order.link);
992 add_orderlayer_to_screen(ivilayer, iviscrn);
993 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
994 }
995 }
996
997 iviscrn->event_mask = 0;
998
999 /* Clear view list of layout ivi_layer */
1000 wl_list_init(&layout->layout_layer.view_list.link);
1001
1002 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
1003 if (ivilayer->prop.visibility == false)
1004 continue;
1005
1006 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
1007 struct weston_view *tmpview = NULL;
1008 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
1009 if (tmpview != NULL) {
1010 break;
1011 }
1012 }
1013
1014 if (ivisurf->prop.visibility == false)
1015 continue;
1016 if (ivisurf->surface == NULL || tmpview == NULL)
1017 continue;
1018
1019 weston_layer_entry_insert(&layout->layout_layer.view_list,
1020 &tmpview->layer_link);
1021
1022 ivisurf->surface->output = iviscrn->output;
1023 }
1024 }
1025
1026 break;
1027 }
1028}
1029
1030static void
1031commit_transition(struct ivi_layout* layout)
1032{
1033 if(wl_list_empty(&layout->pending_transition_list)){
1034 return;
1035 }
1036
1037 wl_list_insert_list(&layout->transitions->transition_list,
1038 &layout->pending_transition_list);
1039
1040 wl_list_init(&layout->pending_transition_list);
1041
1042 wl_event_source_timer_update(layout->transitions->event_source, 1);
1043}
1044
1045static void
1046send_surface_prop(struct ivi_layout_surface *ivisurf)
1047{
1048 wl_signal_emit(&ivisurf->property_changed, ivisurf);
1049 ivisurf->event_mask = 0;
1050}
1051
1052static void
1053send_layer_prop(struct ivi_layout_layer *ivilayer)
1054{
1055 wl_signal_emit(&ivilayer->property_changed, ivilayer);
1056 ivilayer->event_mask = 0;
1057}
1058
1059static void
1060send_prop(struct ivi_layout *layout)
1061{
1062 struct ivi_layout_layer *ivilayer = NULL;
1063 struct ivi_layout_surface *ivisurf = NULL;
1064
1065 wl_list_for_each_reverse(ivilayer, &layout->layer_list, link) {
1066 send_layer_prop(ivilayer);
1067 }
1068
1069 wl_list_for_each_reverse(ivisurf, &layout->surface_list, link) {
1070 send_surface_prop(ivisurf);
1071 }
1072}
1073
1074static void
1075clear_surface_pending_list(struct ivi_layout_layer *ivilayer)
1076{
1077 struct ivi_layout_surface *surface_link = NULL;
1078 struct ivi_layout_surface *surface_next = NULL;
1079
1080 wl_list_for_each_safe(surface_link, surface_next,
1081 &ivilayer->pending.surface_list, pending.link) {
1082 if (!wl_list_empty(&surface_link->pending.link)) {
1083 wl_list_remove(&surface_link->pending.link);
1084 }
1085
1086 wl_list_init(&surface_link->pending.link);
1087 }
1088
1089 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
1090}
1091
1092static void
1093clear_surface_order_list(struct ivi_layout_layer *ivilayer)
1094{
1095 struct ivi_layout_surface *surface_link = NULL;
1096 struct ivi_layout_surface *surface_next = NULL;
1097
1098 wl_list_for_each_safe(surface_link, surface_next,
1099 &ivilayer->order.surface_list, order.link) {
1100 if (!wl_list_empty(&surface_link->order.link)) {
1101 wl_list_remove(&surface_link->order.link);
1102 }
1103
1104 wl_list_init(&surface_link->order.link);
1105 }
1106
1107 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
1108}
1109
1110static void
1111layer_created(struct wl_listener *listener, void *data)
1112{
1113 struct ivi_layout_layer *ivilayer = data;
1114
1115 struct listener_layout_notification *notification =
1116 container_of(listener,
1117 struct listener_layout_notification,
1118 listener);
1119
1120 struct ivi_layout_notification_callback *created_callback =
1121 notification->userdata;
1122
1123 ((layer_create_notification_func)created_callback->callback)
1124 (ivilayer, created_callback->data);
1125}
1126
1127static void
1128layer_removed(struct wl_listener *listener, void *data)
1129{
1130 struct ivi_layout_layer *ivilayer = data;
1131
1132 struct listener_layout_notification *notification =
1133 container_of(listener,
1134 struct listener_layout_notification,
1135 listener);
1136
1137 struct ivi_layout_notification_callback *removed_callback =
1138 notification->userdata;
1139
1140 ((layer_remove_notification_func)removed_callback->callback)
1141 (ivilayer, removed_callback->data);
1142}
1143
1144static void
1145layer_prop_changed(struct wl_listener *listener, void *data)
1146{
1147 struct ivi_layout_layer *ivilayer = data;
1148
1149 struct listener_layout_notification *layout_listener =
1150 container_of(listener,
1151 struct listener_layout_notification,
1152 listener);
1153
1154 struct ivi_layout_notification_callback *prop_callback =
1155 layout_listener->userdata;
1156
1157 ((layer_property_notification_func)prop_callback->callback)
1158 (ivilayer, &ivilayer->prop, ivilayer->event_mask, prop_callback->data);
1159}
1160
1161static void
1162surface_created(struct wl_listener *listener, void *data)
1163{
1164 struct ivi_layout_surface *ivisurface = data;
1165
1166 struct listener_layout_notification *notification =
1167 container_of(listener,
1168 struct listener_layout_notification,
1169 listener);
1170
1171 struct ivi_layout_notification_callback *created_callback =
1172 notification->userdata;
1173
1174 ((surface_create_notification_func)created_callback->callback)
1175 (ivisurface, created_callback->data);
1176}
1177
1178static void
1179surface_removed(struct wl_listener *listener, void *data)
1180{
1181 struct ivi_layout_surface *ivisurface = data;
1182
1183 struct listener_layout_notification *notification =
1184 container_of(listener,
1185 struct listener_layout_notification,
1186 listener);
1187
1188 struct ivi_layout_notification_callback *removed_callback =
1189 notification->userdata;
1190
1191 ((surface_remove_notification_func)removed_callback->callback)
1192 (ivisurface, removed_callback->data);
1193}
1194
1195static void
1196surface_prop_changed(struct wl_listener *listener, void *data)
1197{
1198 struct ivi_layout_surface *ivisurf = data;
1199
1200 struct listener_layout_notification *layout_listener =
1201 container_of(listener,
1202 struct listener_layout_notification,
1203 listener);
1204
1205 struct ivi_layout_notification_callback *prop_callback =
1206 layout_listener->userdata;
1207
1208 ((surface_property_notification_func)prop_callback->callback)
1209 (ivisurf, &ivisurf->prop, ivisurf->event_mask, prop_callback->data);
1210
1211 ivisurf->event_mask = 0;
1212}
1213
1214static void
1215surface_configure_changed(struct wl_listener *listener,
1216 void *data)
1217{
1218 struct ivi_layout_surface *ivisurface = data;
1219
1220 struct listener_layout_notification *notification =
1221 container_of(listener,
1222 struct listener_layout_notification,
1223 listener);
1224
1225 struct ivi_layout_notification_callback *configure_changed_callback =
1226 notification->userdata;
1227
1228 ((surface_configure_notification_func)configure_changed_callback->callback)
1229 (ivisurface, configure_changed_callback->data);
1230}
1231
1232static int32_t
1233add_notification(struct wl_signal *signal,
1234 wl_notify_func_t callback,
1235 void *userdata)
1236{
1237 struct listener_layout_notification *notification = NULL;
1238
1239 notification = malloc(sizeof *notification);
1240 if (notification == NULL) {
1241 weston_log("fails to allocate memory\n");
1242 free(userdata);
1243 return IVI_FAILED;
1244 }
1245
1246 notification->listener.notify = callback;
1247 notification->userdata = userdata;
1248
1249 wl_signal_add(signal, &notification->listener);
1250
1251 return IVI_SUCCEEDED;
1252}
1253
1254static void
1255remove_notification(struct wl_list *listener_list, void *callback, void *userdata)
1256{
1257 struct wl_listener *listener = NULL;
1258 struct wl_listener *next = NULL;
1259
1260 wl_list_for_each_safe(listener, next, listener_list, link) {
1261 struct listener_layout_notification *notification =
1262 container_of(listener,
1263 struct listener_layout_notification,
1264 listener);
1265
1266 struct ivi_layout_notification_callback *notification_callback =
1267 notification->userdata;
1268
1269 if ((notification_callback->callback != callback) ||
1270 (notification_callback->data != userdata)) {
1271 continue;
1272 }
1273
1274 if (!wl_list_empty(&listener->link)) {
1275 wl_list_remove(&listener->link);
1276 }
1277
1278 free(notification->userdata);
1279 free(notification);
1280 }
1281}
1282
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001283/**
1284 * Exported APIs of ivi-layout library are implemented from here.
1285 * Brief of APIs is described in ivi-layout-export.h.
1286 */
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001287static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001288ivi_layout_add_notification_create_layer(layer_create_notification_func callback,
1289 void *userdata)
1290{
1291 struct ivi_layout *layout = get_instance();
1292 struct ivi_layout_notification_callback *created_callback = NULL;
1293
1294 if (callback == NULL) {
1295 weston_log("ivi_layout_add_notification_create_layer: invalid argument\n");
1296 return IVI_FAILED;
1297 }
1298
1299 created_callback = malloc(sizeof *created_callback);
1300 if (created_callback == NULL) {
1301 weston_log("fails to allocate memory\n");
1302 return IVI_FAILED;
1303 }
1304
1305 created_callback->callback = callback;
1306 created_callback->data = userdata;
1307
1308 return add_notification(&layout->layer_notification.created,
1309 layer_created,
1310 created_callback);
1311}
1312
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001313static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001314ivi_layout_remove_notification_create_layer(layer_create_notification_func callback,
1315 void *userdata)
1316{
1317 struct ivi_layout *layout = get_instance();
1318 remove_notification(&layout->layer_notification.created.listener_list, callback, userdata);
1319}
1320
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001321static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001322ivi_layout_add_notification_remove_layer(layer_remove_notification_func callback,
1323 void *userdata)
1324{
1325 struct ivi_layout *layout = get_instance();
1326 struct ivi_layout_notification_callback *removed_callback = NULL;
1327
1328 if (callback == NULL) {
1329 weston_log("ivi_layout_add_notification_remove_layer: invalid argument\n");
1330 return IVI_FAILED;
1331 }
1332
1333 removed_callback = malloc(sizeof *removed_callback);
1334 if (removed_callback == NULL) {
1335 weston_log("fails to allocate memory\n");
1336 return IVI_FAILED;
1337 }
1338
1339 removed_callback->callback = callback;
1340 removed_callback->data = userdata;
1341 return add_notification(&layout->layer_notification.removed,
1342 layer_removed,
1343 removed_callback);
1344}
1345
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001346static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001347ivi_layout_remove_notification_remove_layer(layer_remove_notification_func callback,
1348 void *userdata)
1349{
1350 struct ivi_layout *layout = get_instance();
1351 remove_notification(&layout->layer_notification.removed.listener_list, callback, userdata);
1352}
1353
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001354static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001355ivi_layout_add_notification_create_surface(surface_create_notification_func callback,
1356 void *userdata)
1357{
1358 struct ivi_layout *layout = get_instance();
1359 struct ivi_layout_notification_callback *created_callback = NULL;
1360
1361 if (callback == NULL) {
1362 weston_log("ivi_layout_add_notification_create_surface: invalid argument\n");
1363 return IVI_FAILED;
1364 }
1365
1366 created_callback = malloc(sizeof *created_callback);
1367 if (created_callback == NULL) {
1368 weston_log("fails to allocate memory\n");
1369 return IVI_FAILED;
1370 }
1371
1372 created_callback->callback = callback;
1373 created_callback->data = userdata;
1374
1375 return add_notification(&layout->surface_notification.created,
1376 surface_created,
1377 created_callback);
1378}
1379
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001380static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001381ivi_layout_remove_notification_create_surface(surface_create_notification_func callback,
1382 void *userdata)
1383{
1384 struct ivi_layout *layout = get_instance();
1385 remove_notification(&layout->surface_notification.created.listener_list, callback, userdata);
1386}
1387
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001388static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001389ivi_layout_add_notification_remove_surface(surface_remove_notification_func callback,
1390 void *userdata)
1391{
1392 struct ivi_layout *layout = get_instance();
1393 struct ivi_layout_notification_callback *removed_callback = NULL;
1394
1395 if (callback == NULL) {
1396 weston_log("ivi_layout_add_notification_remove_surface: invalid argument\n");
1397 return IVI_FAILED;
1398 }
1399
1400 removed_callback = malloc(sizeof *removed_callback);
1401 if (removed_callback == NULL) {
1402 weston_log("fails to allocate memory\n");
1403 return IVI_FAILED;
1404 }
1405
1406 removed_callback->callback = callback;
1407 removed_callback->data = userdata;
1408
1409 return add_notification(&layout->surface_notification.removed,
1410 surface_removed,
1411 removed_callback);
1412}
1413
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001414static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001415ivi_layout_remove_notification_remove_surface(surface_remove_notification_func callback,
1416 void *userdata)
1417{
1418 struct ivi_layout *layout = get_instance();
1419 remove_notification(&layout->surface_notification.removed.listener_list, callback, userdata);
1420}
1421
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001422static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001423ivi_layout_add_notification_configure_surface(surface_configure_notification_func callback,
1424 void *userdata)
1425{
1426 struct ivi_layout *layout = get_instance();
1427 struct ivi_layout_notification_callback *configure_changed_callback = NULL;
1428 if (callback == NULL) {
1429 weston_log("ivi_layout_add_notification_configure_surface: invalid argument\n");
1430 return IVI_FAILED;
1431 }
1432
1433 configure_changed_callback = malloc(sizeof *configure_changed_callback);
1434 if (configure_changed_callback == NULL) {
1435 weston_log("fails to allocate memory\n");
1436 return IVI_FAILED;
1437 }
1438
1439 configure_changed_callback->callback = callback;
1440 configure_changed_callback->data = userdata;
1441
1442 return add_notification(&layout->surface_notification.configure_changed,
1443 surface_configure_changed,
1444 configure_changed_callback);
1445}
1446
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001447static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001448ivi_layout_remove_notification_configure_surface(surface_configure_notification_func callback,
1449 void *userdata)
1450{
1451 struct ivi_layout *layout = get_instance();
1452 remove_notification(&layout->surface_notification.configure_changed.listener_list, callback, userdata);
1453}
1454
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001455uint32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001456ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf)
1457{
1458 return ivisurf->id_surface;
1459}
1460
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001461static uint32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001462ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer)
1463{
1464 return ivilayer->id_layer;
1465}
1466
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001467static struct ivi_layout_layer *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001468ivi_layout_get_layer_from_id(uint32_t id_layer)
1469{
1470 struct ivi_layout *layout = get_instance();
1471 struct ivi_layout_layer *ivilayer = NULL;
1472
1473 wl_list_for_each(ivilayer, &layout->layer_list, link) {
1474 if (ivilayer->id_layer == id_layer) {
1475 return ivilayer;
1476 }
1477 }
1478
1479 return NULL;
1480}
1481
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001482struct ivi_layout_surface *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001483ivi_layout_get_surface_from_id(uint32_t id_surface)
1484{
1485 struct ivi_layout *layout = get_instance();
1486 struct ivi_layout_surface *ivisurf = NULL;
1487
1488 wl_list_for_each(ivisurf, &layout->surface_list, link) {
1489 if (ivisurf->id_surface == id_surface) {
1490 return ivisurf;
1491 }
1492 }
1493
1494 return NULL;
1495}
1496
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001497static struct ivi_layout_screen *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001498ivi_layout_get_screen_from_id(uint32_t id_screen)
1499{
1500 struct ivi_layout *layout = get_instance();
1501 struct ivi_layout_screen *iviscrn = NULL;
1502
1503 wl_list_for_each(iviscrn, &layout->screen_list, link) {
1504/* FIXME : select iviscrn from screen_list by id_screen */
1505 return iviscrn;
1506 break;
1507 }
1508
1509 return NULL;
1510}
1511
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001512static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001513ivi_layout_get_screen_resolution(struct ivi_layout_screen *iviscrn,
1514 int32_t *pWidth, int32_t *pHeight)
1515{
1516 struct weston_output *output = NULL;
1517
Nobuhiko Tanibata0c217cb2015-06-22 15:30:32 +09001518 if (iviscrn == NULL || pWidth == NULL || pHeight == NULL) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001519 weston_log("ivi_layout_get_screen_resolution: invalid argument\n");
1520 return IVI_FAILED;
1521 }
1522
1523 output = iviscrn->output;
1524 *pWidth = output->current_mode->width;
1525 *pHeight = output->current_mode->height;
1526
1527 return IVI_SUCCEEDED;
1528}
1529
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001530static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001531ivi_layout_surface_add_notification(struct ivi_layout_surface *ivisurf,
1532 surface_property_notification_func callback,
1533 void *userdata)
1534{
1535 struct listener_layout_notification* notification = NULL;
1536 struct ivi_layout_notification_callback *prop_callback = NULL;
1537
1538 if (ivisurf == NULL || callback == NULL) {
1539 weston_log("ivi_layout_surface_add_notification: invalid argument\n");
1540 return IVI_FAILED;
1541 }
1542
1543 notification = malloc(sizeof *notification);
1544 if (notification == NULL) {
1545 weston_log("fails to allocate memory\n");
1546 return IVI_FAILED;
1547 }
1548
1549 prop_callback = malloc(sizeof *prop_callback);
1550 if (prop_callback == NULL) {
1551 weston_log("fails to allocate memory\n");
1552 return IVI_FAILED;
1553 }
1554
1555 prop_callback->callback = callback;
1556 prop_callback->data = userdata;
1557
1558 notification->listener.notify = surface_prop_changed;
1559 notification->userdata = prop_callback;
1560
1561 wl_signal_add(&ivisurf->property_changed, &notification->listener);
1562
1563 return IVI_SUCCEEDED;
1564}
1565
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001566static const struct ivi_layout_layer_properties *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001567ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer)
1568{
1569 if (ivilayer == NULL) {
1570 weston_log("ivi_layout_get_properties_of_layer: invalid argument\n");
1571 return NULL;
1572 }
1573
1574 return &ivilayer->prop;
1575}
1576
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001577static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001578ivi_layout_get_screens(int32_t *pLength, struct ivi_layout_screen ***ppArray)
1579{
1580 struct ivi_layout *layout = get_instance();
1581 struct ivi_layout_screen *iviscrn = NULL;
1582 int32_t length = 0;
1583 int32_t n = 0;
1584
1585 if (pLength == NULL || ppArray == NULL) {
1586 weston_log("ivi_layout_get_screens: invalid argument\n");
1587 return IVI_FAILED;
1588 }
1589
1590 length = wl_list_length(&layout->screen_list);
1591
1592 if (length != 0){
1593 /* the Array must be free by module which called this function */
1594 *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
1595 if (*ppArray == NULL) {
1596 weston_log("fails to allocate memory\n");
1597 return IVI_FAILED;
1598 }
1599
1600 wl_list_for_each(iviscrn, &layout->screen_list, link) {
1601 (*ppArray)[n++] = iviscrn;
1602 }
1603 }
1604
1605 *pLength = length;
1606
1607 return IVI_SUCCEEDED;
1608}
1609
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001610static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001611ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer,
1612 int32_t *pLength,
1613 struct ivi_layout_screen ***ppArray)
1614{
1615 struct link_screen *link_scrn = NULL;
1616 int32_t length = 0;
1617 int32_t n = 0;
1618
1619 if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1620 weston_log("ivi_layout_get_screens_under_layer: invalid argument\n");
1621 return IVI_FAILED;
1622 }
1623
1624 length = wl_list_length(&ivilayer->screen_list);
1625
1626 if (length != 0){
1627 /* the Array must be free by module which called this function */
1628 *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
1629 if (*ppArray == NULL) {
1630 weston_log("fails to allocate memory\n");
1631 return IVI_FAILED;
1632 }
1633
1634 wl_list_for_each(link_scrn, &ivilayer->screen_list, link) {
1635 (*ppArray)[n++] = link_scrn->iviscrn;
1636 }
1637 }
1638
1639 *pLength = length;
1640
1641 return IVI_SUCCEEDED;
1642}
1643
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001644static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001645ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray)
1646{
1647 struct ivi_layout *layout = get_instance();
1648 struct ivi_layout_layer *ivilayer = NULL;
1649 int32_t length = 0;
1650 int32_t n = 0;
1651
1652 if (pLength == NULL || ppArray == NULL) {
1653 weston_log("ivi_layout_get_layers: invalid argument\n");
1654 return IVI_FAILED;
1655 }
1656
1657 length = wl_list_length(&layout->layer_list);
1658
1659 if (length != 0){
1660 /* the Array must be free by module which called this function */
1661 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1662 if (*ppArray == NULL) {
1663 weston_log("fails to allocate memory\n");
1664 return IVI_FAILED;
1665 }
1666
1667 wl_list_for_each(ivilayer, &layout->layer_list, link) {
1668 (*ppArray)[n++] = ivilayer;
1669 }
1670 }
1671
1672 *pLength = length;
1673
1674 return IVI_SUCCEEDED;
1675}
1676
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001677static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001678ivi_layout_get_layers_on_screen(struct ivi_layout_screen *iviscrn,
1679 int32_t *pLength,
1680 struct ivi_layout_layer ***ppArray)
1681{
1682 struct ivi_layout_layer *ivilayer = NULL;
1683 int32_t length = 0;
1684 int32_t n = 0;
1685
1686 if (iviscrn == NULL || pLength == NULL || ppArray == NULL) {
1687 weston_log("ivi_layout_get_layers_on_screen: invalid argument\n");
1688 return IVI_FAILED;
1689 }
1690
1691 length = wl_list_length(&iviscrn->order.layer_list);
1692
1693 if (length != 0){
1694 /* the Array must be free by module which called this function */
1695 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1696 if (*ppArray == NULL) {
1697 weston_log("fails to allocate memory\n");
1698 return IVI_FAILED;
1699 }
1700
Nobuhiko Tanibatae2b82142015-06-22 15:30:19 +09001701 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001702 (*ppArray)[n++] = ivilayer;
1703 }
1704 }
1705
1706 *pLength = length;
1707
1708 return IVI_SUCCEEDED;
1709}
1710
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001711static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001712ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf,
1713 int32_t *pLength,
1714 struct ivi_layout_layer ***ppArray)
1715{
1716 struct link_layer *link_layer = NULL;
1717 int32_t length = 0;
1718 int32_t n = 0;
1719
1720 if (ivisurf == NULL || pLength == NULL || ppArray == NULL) {
1721 weston_log("ivi_layout_getLayers: invalid argument\n");
1722 return IVI_FAILED;
1723 }
1724
1725 length = wl_list_length(&ivisurf->layer_list);
1726
1727 if (length != 0){
1728 /* the Array must be free by module which called this function */
1729 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1730 if (*ppArray == NULL) {
1731 weston_log("fails to allocate memory\n");
1732 return IVI_FAILED;
1733 }
1734
1735 wl_list_for_each(link_layer, &ivisurf->layer_list, link) {
1736 (*ppArray)[n++] = link_layer->ivilayer;
1737 }
1738 }
1739
1740 *pLength = length;
1741
1742 return IVI_SUCCEEDED;
1743}
1744
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001745static
1746int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001747ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray)
1748{
1749 struct ivi_layout *layout = get_instance();
1750 struct ivi_layout_surface *ivisurf = NULL;
1751 int32_t length = 0;
1752 int32_t n = 0;
1753
1754 if (pLength == NULL || ppArray == NULL) {
1755 weston_log("ivi_layout_get_surfaces: invalid argument\n");
1756 return IVI_FAILED;
1757 }
1758
1759 length = wl_list_length(&layout->surface_list);
1760
1761 if (length != 0){
1762 /* the Array must be free by module which called this function */
1763 *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1764 if (*ppArray == NULL) {
1765 weston_log("fails to allocate memory\n");
1766 return IVI_FAILED;
1767 }
1768
1769 wl_list_for_each(ivisurf, &layout->surface_list, link) {
1770 (*ppArray)[n++] = ivisurf;
1771 }
1772 }
1773
1774 *pLength = length;
1775
1776 return IVI_SUCCEEDED;
1777}
1778
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001779static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001780ivi_layout_get_surfaces_on_layer(struct ivi_layout_layer *ivilayer,
1781 int32_t *pLength,
1782 struct ivi_layout_surface ***ppArray)
1783{
1784 struct ivi_layout_surface *ivisurf = NULL;
1785 int32_t length = 0;
1786 int32_t n = 0;
1787
1788 if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1789 weston_log("ivi_layout_getSurfaceIDsOnLayer: invalid argument\n");
1790 return IVI_FAILED;
1791 }
1792
1793 length = wl_list_length(&ivilayer->order.surface_list);
1794
1795 if (length != 0) {
1796 /* the Array must be free by module which called this function */
1797 *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1798 if (*ppArray == NULL) {
1799 weston_log("fails to allocate memory\n");
1800 return IVI_FAILED;
1801 }
1802
1803 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
1804 (*ppArray)[n++] = ivisurf;
1805 }
1806 }
1807
1808 *pLength = length;
1809
1810 return IVI_SUCCEEDED;
1811}
1812
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001813static struct ivi_layout_layer *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001814ivi_layout_layer_create_with_dimension(uint32_t id_layer,
1815 int32_t width, int32_t height)
1816{
1817 struct ivi_layout *layout = get_instance();
1818 struct ivi_layout_layer *ivilayer = NULL;
1819
1820 ivilayer = get_layer(&layout->layer_list, id_layer);
1821 if (ivilayer != NULL) {
1822 weston_log("id_layer is already created\n");
1823 return ivilayer;
1824 }
1825
1826 ivilayer = calloc(1, sizeof *ivilayer);
1827 if (ivilayer == NULL) {
1828 weston_log("fails to allocate memory\n");
1829 return NULL;
1830 }
1831
1832 wl_list_init(&ivilayer->link);
1833 wl_signal_init(&ivilayer->property_changed);
1834 wl_list_init(&ivilayer->screen_list);
1835 wl_list_init(&ivilayer->link_to_surface);
1836 ivilayer->layout = layout;
1837 ivilayer->id_layer = id_layer;
1838
1839 init_layer_properties(&ivilayer->prop, width, height);
1840 ivilayer->event_mask = 0;
1841
1842 wl_list_init(&ivilayer->pending.surface_list);
1843 wl_list_init(&ivilayer->pending.link);
1844 ivilayer->pending.prop = ivilayer->prop;
1845
1846 wl_list_init(&ivilayer->order.surface_list);
1847 wl_list_init(&ivilayer->order.link);
1848
1849 wl_list_insert(&layout->layer_list, &ivilayer->link);
1850
1851 wl_signal_emit(&layout->layer_notification.created, ivilayer);
1852
1853 return ivilayer;
1854}
1855
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001856static void
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +09001857ivi_layout_layer_remove_notification(struct ivi_layout_layer *ivilayer)
1858{
1859 if (ivilayer == NULL) {
1860 weston_log("ivi_layout_layer_remove_notification: invalid argument\n");
1861 return;
1862 }
1863
1864 remove_all_notification(&ivilayer->property_changed.listener_list);
1865}
1866
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001867static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001868ivi_layout_layer_remove(struct ivi_layout_layer *ivilayer)
1869{
1870 struct ivi_layout *layout = get_instance();
1871
1872 if (ivilayer == NULL) {
1873 weston_log("ivi_layout_layer_remove: invalid argument\n");
1874 return;
1875 }
1876
1877 wl_signal_emit(&layout->layer_notification.removed, ivilayer);
1878
1879 clear_surface_pending_list(ivilayer);
1880 clear_surface_order_list(ivilayer);
1881
1882 if (!wl_list_empty(&ivilayer->pending.link)) {
1883 wl_list_remove(&ivilayer->pending.link);
1884 }
1885 if (!wl_list_empty(&ivilayer->order.link)) {
1886 wl_list_remove(&ivilayer->order.link);
1887 }
1888 if (!wl_list_empty(&ivilayer->link)) {
1889 wl_list_remove(&ivilayer->link);
1890 }
1891 remove_orderlayer_from_screen(ivilayer);
1892 remove_link_to_surface(ivilayer);
1893 ivi_layout_layer_remove_notification(ivilayer);
1894
1895 free(ivilayer);
1896}
1897
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001898int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001899ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer,
1900 bool newVisibility)
1901{
1902 struct ivi_layout_layer_properties *prop = NULL;
1903
1904 if (ivilayer == NULL) {
1905 weston_log("ivi_layout_layer_set_visibility: invalid argument\n");
1906 return IVI_FAILED;
1907 }
1908
1909 prop = &ivilayer->pending.prop;
1910 prop->visibility = newVisibility;
1911
1912 ivilayer->event_mask |= IVI_NOTIFICATION_VISIBILITY;
1913
1914 return IVI_SUCCEEDED;
1915}
1916
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001917static bool
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001918ivi_layout_layer_get_visibility(struct ivi_layout_layer *ivilayer)
1919{
1920 if (ivilayer == NULL) {
1921 weston_log("ivi_layout_layer_get_visibility: invalid argument\n");
1922 return false;
1923 }
1924
1925 return ivilayer->prop.visibility;
1926}
1927
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001928int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001929ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
1930 wl_fixed_t opacity)
1931{
1932 struct ivi_layout_layer_properties *prop = NULL;
1933
Nobuhiko Tanibata7bbacc62015-06-22 15:30:09 +09001934 if (ivilayer == NULL ||
1935 opacity < wl_fixed_from_double(0.0) ||
1936 wl_fixed_from_double(1.0) < opacity) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001937 weston_log("ivi_layout_layer_set_opacity: invalid argument\n");
1938 return IVI_FAILED;
1939 }
1940
1941 prop = &ivilayer->pending.prop;
1942 prop->opacity = opacity;
1943
1944 ivilayer->event_mask |= IVI_NOTIFICATION_OPACITY;
1945
1946 return IVI_SUCCEEDED;
1947}
1948
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001949wl_fixed_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001950ivi_layout_layer_get_opacity(struct ivi_layout_layer *ivilayer)
1951{
1952 if (ivilayer == NULL) {
1953 weston_log("ivi_layout_layer_get_opacity: invalid argument\n");
1954 return wl_fixed_from_double(0.0);
1955 }
1956
1957 return ivilayer->prop.opacity;
1958}
1959
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001960static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001961ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer,
1962 int32_t x, int32_t y,
1963 int32_t width, int32_t height)
1964{
1965 struct ivi_layout_layer_properties *prop = NULL;
1966
1967 if (ivilayer == NULL) {
1968 weston_log("ivi_layout_layer_set_source_rectangle: invalid argument\n");
1969 return IVI_FAILED;
1970 }
1971
1972 prop = &ivilayer->pending.prop;
1973 prop->source_x = x;
1974 prop->source_y = y;
1975 prop->source_width = width;
1976 prop->source_height = height;
1977
1978 ivilayer->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
1979
1980 return IVI_SUCCEEDED;
1981}
1982
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001983static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001984ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer,
1985 int32_t x, int32_t y,
1986 int32_t width, int32_t height)
1987{
1988 struct ivi_layout_layer_properties *prop = NULL;
1989
1990 if (ivilayer == NULL) {
1991 weston_log("ivi_layout_layer_set_destination_rectangle: invalid argument\n");
1992 return IVI_FAILED;
1993 }
1994
1995 prop = &ivilayer->pending.prop;
1996 prop->dest_x = x;
1997 prop->dest_y = y;
1998 prop->dest_width = width;
1999 prop->dest_height = height;
2000
2001 ivilayer->event_mask |= IVI_NOTIFICATION_DEST_RECT;
2002
2003 return IVI_SUCCEEDED;
2004}
2005
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002006static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002007ivi_layout_layer_get_dimension(struct ivi_layout_layer *ivilayer,
2008 int32_t *dest_width, int32_t *dest_height)
2009{
2010 if (ivilayer == NULL || dest_width == NULL || dest_height == NULL) {
2011 weston_log("ivi_layout_layer_get_dimension: invalid argument\n");
2012 return IVI_FAILED;
2013 }
2014
2015 *dest_width = ivilayer->prop.dest_width;
2016 *dest_height = ivilayer->prop.dest_height;
2017
2018 return IVI_SUCCEEDED;
2019}
2020
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002021static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002022ivi_layout_layer_set_dimension(struct ivi_layout_layer *ivilayer,
2023 int32_t dest_width, int32_t dest_height)
2024{
2025 struct ivi_layout_layer_properties *prop = NULL;
2026
2027 if (ivilayer == NULL) {
2028 weston_log("ivi_layout_layer_set_dimension: invalid argument\n");
2029 return IVI_FAILED;
2030 }
2031
2032 prop = &ivilayer->pending.prop;
2033
2034 prop->dest_width = dest_width;
2035 prop->dest_height = dest_height;
2036
2037 ivilayer->event_mask |= IVI_NOTIFICATION_DIMENSION;
2038
2039 return IVI_SUCCEEDED;
2040}
2041
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002042int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002043ivi_layout_layer_get_position(struct ivi_layout_layer *ivilayer,
2044 int32_t *dest_x, int32_t *dest_y)
2045{
2046 if (ivilayer == NULL || dest_x == NULL || dest_y == NULL) {
2047 weston_log("ivi_layout_layer_get_position: invalid argument\n");
2048 return IVI_FAILED;
2049 }
2050
2051 *dest_x = ivilayer->prop.dest_x;
2052 *dest_y = ivilayer->prop.dest_y;
2053
2054 return IVI_SUCCEEDED;
2055}
2056
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002057int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002058ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer,
2059 int32_t dest_x, int32_t dest_y)
2060{
2061 struct ivi_layout_layer_properties *prop = NULL;
2062
2063 if (ivilayer == NULL) {
2064 weston_log("ivi_layout_layer_set_position: invalid argument\n");
2065 return IVI_FAILED;
2066 }
2067
2068 prop = &ivilayer->pending.prop;
2069 prop->dest_x = dest_x;
2070 prop->dest_y = dest_y;
2071
2072 ivilayer->event_mask |= IVI_NOTIFICATION_POSITION;
2073
2074 return IVI_SUCCEEDED;
2075}
2076
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002077static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002078ivi_layout_layer_set_orientation(struct ivi_layout_layer *ivilayer,
2079 enum wl_output_transform orientation)
2080{
2081 struct ivi_layout_layer_properties *prop = NULL;
2082
2083 if (ivilayer == NULL) {
2084 weston_log("ivi_layout_layer_set_orientation: invalid argument\n");
2085 return IVI_FAILED;
2086 }
2087
2088 prop = &ivilayer->pending.prop;
2089 prop->orientation = orientation;
2090
2091 ivilayer->event_mask |= IVI_NOTIFICATION_ORIENTATION;
2092
2093 return IVI_SUCCEEDED;
2094}
2095
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002096static enum wl_output_transform
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002097ivi_layout_layer_get_orientation(struct ivi_layout_layer *ivilayer)
2098{
2099 if (ivilayer == NULL) {
2100 weston_log("ivi_layout_layer_get_orientation: invalid argument\n");
2101 return 0;
2102 }
2103
2104 return ivilayer->prop.orientation;
2105}
2106
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002107int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002108ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
2109 struct ivi_layout_surface **pSurface,
2110 int32_t number)
2111{
2112 struct ivi_layout *layout = get_instance();
2113 struct ivi_layout_surface *ivisurf = NULL;
2114 struct ivi_layout_surface *next = NULL;
2115 uint32_t *id_surface = NULL;
2116 int32_t i = 0;
2117
2118 if (ivilayer == NULL) {
2119 weston_log("ivi_layout_layer_set_render_order: invalid argument\n");
2120 return IVI_FAILED;
2121 }
2122
2123 if (pSurface == NULL) {
2124 wl_list_for_each_safe(ivisurf, next, &ivilayer->pending.surface_list, pending.link) {
2125 if (!wl_list_empty(&ivisurf->pending.link)) {
2126 wl_list_remove(&ivisurf->pending.link);
2127 }
2128
2129 wl_list_init(&ivisurf->pending.link);
2130 }
2131 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
2132 return IVI_SUCCEEDED;
2133 }
2134
2135 for (i = 0; i < number; i++) {
2136 id_surface = &pSurface[i]->id_surface;
2137
2138 wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
2139 if (*id_surface != ivisurf->id_surface) {
2140 continue;
2141 }
2142
2143 if (!wl_list_empty(&ivisurf->pending.link)) {
2144 wl_list_remove(&ivisurf->pending.link);
2145 }
2146 wl_list_init(&ivisurf->pending.link);
2147 wl_list_insert(&ivilayer->pending.surface_list,
2148 &ivisurf->pending.link);
2149 break;
2150 }
2151 }
2152
2153 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
2154
2155 return IVI_SUCCEEDED;
2156}
2157
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002158int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002159ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf,
2160 bool newVisibility)
2161{
2162 struct ivi_layout_surface_properties *prop = NULL;
2163
2164 if (ivisurf == NULL) {
2165 weston_log("ivi_layout_surface_set_visibility: invalid argument\n");
2166 return IVI_FAILED;
2167 }
2168
2169 prop = &ivisurf->pending.prop;
2170 prop->visibility = newVisibility;
2171
2172 ivisurf->event_mask |= IVI_NOTIFICATION_VISIBILITY;
2173
2174 return IVI_SUCCEEDED;
2175}
2176
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002177bool
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002178ivi_layout_surface_get_visibility(struct ivi_layout_surface *ivisurf)
2179{
2180 if (ivisurf == NULL) {
2181 weston_log("ivi_layout_surface_get_visibility: invalid argument\n");
2182 return false;
2183 }
2184
2185 return ivisurf->prop.visibility;
2186}
2187
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002188int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002189ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
2190 wl_fixed_t opacity)
2191{
2192 struct ivi_layout_surface_properties *prop = NULL;
2193
Nobuhiko Tanibataa86226c2015-06-22 15:29:20 +09002194 if (ivisurf == NULL ||
2195 opacity < wl_fixed_from_double(0.0) ||
2196 wl_fixed_from_double(1.0) < opacity) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002197 weston_log("ivi_layout_surface_set_opacity: invalid argument\n");
2198 return IVI_FAILED;
2199 }
2200
2201 prop = &ivisurf->pending.prop;
2202 prop->opacity = opacity;
2203
2204 ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY;
2205
2206 return IVI_SUCCEEDED;
2207}
2208
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002209wl_fixed_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002210ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf)
2211{
2212 if (ivisurf == NULL) {
2213 weston_log("ivi_layout_surface_get_opacity: invalid argument\n");
2214 return wl_fixed_from_double(0.0);
2215 }
2216
2217 return ivisurf->prop.opacity;
2218}
2219
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002220int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002221ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
2222 int32_t x, int32_t y,
2223 int32_t width, int32_t height)
2224{
2225 struct ivi_layout_surface_properties *prop = NULL;
2226
2227 if (ivisurf == NULL) {
2228 weston_log("ivi_layout_surface_set_destination_rectangle: invalid argument\n");
2229 return IVI_FAILED;
2230 }
2231
2232 prop = &ivisurf->pending.prop;
2233 prop->start_x = prop->dest_x;
2234 prop->start_y = prop->dest_y;
2235 prop->dest_x = x;
2236 prop->dest_y = y;
2237 prop->start_width = prop->dest_width;
2238 prop->start_height = prop->dest_height;
2239 prop->dest_width = width;
2240 prop->dest_height = height;
2241
2242 ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT;
2243
2244 return IVI_SUCCEEDED;
2245}
2246
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002247static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002248ivi_layout_surface_set_dimension(struct ivi_layout_surface *ivisurf,
2249 int32_t dest_width, int32_t dest_height)
2250{
2251 struct ivi_layout_surface_properties *prop = NULL;
2252
2253 if (ivisurf == NULL) {
2254 weston_log("ivi_layout_surface_set_dimension: invalid argument\n");
2255 return IVI_FAILED;
2256 }
2257
2258 prop = &ivisurf->pending.prop;
2259 prop->dest_width = dest_width;
2260 prop->dest_height = dest_height;
2261
2262 ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION;
2263
2264 return IVI_SUCCEEDED;
2265}
2266
2267int32_t
2268ivi_layout_surface_get_dimension(struct ivi_layout_surface *ivisurf,
2269 int32_t *dest_width, int32_t *dest_height)
2270{
2271 if (ivisurf == NULL || dest_width == NULL || dest_height == NULL) {
2272 weston_log("ivi_layout_surface_get_dimension: invalid argument\n");
2273 return IVI_FAILED;
2274 }
2275
2276 *dest_width = ivisurf->prop.dest_width;
2277 *dest_height = ivisurf->prop.dest_height;
2278
2279 return IVI_SUCCEEDED;
2280}
2281
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002282static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002283ivi_layout_surface_set_position(struct ivi_layout_surface *ivisurf,
2284 int32_t dest_x, int32_t dest_y)
2285{
2286 struct ivi_layout_surface_properties *prop = NULL;
2287
2288 if (ivisurf == NULL) {
2289 weston_log("ivi_layout_surface_set_position: invalid argument\n");
2290 return IVI_FAILED;
2291 }
2292
2293 prop = &ivisurf->pending.prop;
2294 prop->dest_x = dest_x;
2295 prop->dest_y = dest_y;
2296
2297 ivisurf->event_mask |= IVI_NOTIFICATION_POSITION;
2298
2299 return IVI_SUCCEEDED;
2300}
2301
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002302static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002303ivi_layout_surface_get_position(struct ivi_layout_surface *ivisurf,
2304 int32_t *dest_x, int32_t *dest_y)
2305{
2306 if (ivisurf == NULL || dest_x == NULL || dest_y == NULL) {
2307 weston_log("ivi_layout_surface_get_position: invalid argument\n");
2308 return IVI_FAILED;
2309 }
2310
2311 *dest_x = ivisurf->prop.dest_x;
2312 *dest_y = ivisurf->prop.dest_y;
2313
2314 return IVI_SUCCEEDED;
2315}
2316
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002317static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002318ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf,
2319 enum wl_output_transform orientation)
2320{
2321 struct ivi_layout_surface_properties *prop = NULL;
2322
2323 if (ivisurf == NULL) {
2324 weston_log("ivi_layout_surface_set_orientation: invalid argument\n");
2325 return IVI_FAILED;
2326 }
2327
2328 prop = &ivisurf->pending.prop;
2329 prop->orientation = orientation;
2330
2331 ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION;
2332
2333 return IVI_SUCCEEDED;
2334}
2335
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002336static enum wl_output_transform
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002337ivi_layout_surface_get_orientation(struct ivi_layout_surface *ivisurf)
2338{
2339 if (ivisurf == NULL) {
2340 weston_log("ivi_layout_surface_get_orientation: invalid argument\n");
2341 return 0;
2342 }
2343
2344 return ivisurf->prop.orientation;
2345}
2346
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002347static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002348ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn,
2349 struct ivi_layout_layer *addlayer)
2350{
2351 struct ivi_layout *layout = get_instance();
2352 struct ivi_layout_layer *ivilayer = NULL;
2353 struct ivi_layout_layer *next = NULL;
2354 int is_layer_in_scrn = 0;
2355
2356 if (iviscrn == NULL || addlayer == NULL) {
2357 weston_log("ivi_layout_screen_add_layer: invalid argument\n");
2358 return IVI_FAILED;
2359 }
2360
2361 is_layer_in_scrn = is_layer_in_screen(addlayer, iviscrn);
2362 if (is_layer_in_scrn == 1) {
2363 weston_log("ivi_layout_screen_add_layer: addlayer is already available\n");
2364 return IVI_SUCCEEDED;
2365 }
2366
2367 wl_list_for_each_safe(ivilayer, next, &layout->layer_list, link) {
2368 if (ivilayer->id_layer == addlayer->id_layer) {
2369 if (!wl_list_empty(&ivilayer->pending.link)) {
2370 wl_list_remove(&ivilayer->pending.link);
2371 }
2372 wl_list_init(&ivilayer->pending.link);
2373 wl_list_insert(&iviscrn->pending.layer_list,
2374 &ivilayer->pending.link);
2375 break;
2376 }
2377 }
2378
2379 iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
2380
2381 return IVI_SUCCEEDED;
2382}
2383
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002384static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002385ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn,
2386 struct ivi_layout_layer **pLayer,
2387 const int32_t number)
2388{
2389 struct ivi_layout *layout = get_instance();
2390 struct ivi_layout_layer *ivilayer = NULL;
2391 struct ivi_layout_layer *next = NULL;
2392 uint32_t *id_layer = NULL;
2393 int32_t i = 0;
2394
2395 if (iviscrn == NULL) {
2396 weston_log("ivi_layout_screen_set_render_order: invalid argument\n");
2397 return IVI_FAILED;
2398 }
2399
2400 wl_list_for_each_safe(ivilayer, next,
2401 &iviscrn->pending.layer_list, pending.link) {
2402 wl_list_init(&ivilayer->pending.link);
2403 }
2404
2405 wl_list_init(&iviscrn->pending.layer_list);
2406
2407 if (pLayer == NULL) {
2408 wl_list_for_each_safe(ivilayer, next, &iviscrn->pending.layer_list, pending.link) {
2409 if (!wl_list_empty(&ivilayer->pending.link)) {
2410 wl_list_remove(&ivilayer->pending.link);
2411 }
2412
2413 wl_list_init(&ivilayer->pending.link);
2414 }
2415
2416 iviscrn->event_mask |= IVI_NOTIFICATION_REMOVE;
2417 return IVI_SUCCEEDED;
2418 }
2419
2420 for (i = 0; i < number; i++) {
2421 id_layer = &pLayer[i]->id_layer;
2422 wl_list_for_each(ivilayer, &layout->layer_list, link) {
2423 if (*id_layer != ivilayer->id_layer) {
2424 continue;
2425 }
2426
2427 if (!wl_list_empty(&ivilayer->pending.link)) {
2428 wl_list_remove(&ivilayer->pending.link);
2429 }
2430 wl_list_init(&ivilayer->pending.link);
2431 wl_list_insert(&iviscrn->pending.layer_list,
2432 &ivilayer->pending.link);
2433 break;
2434 }
2435 }
2436
2437 iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
2438
2439 return IVI_SUCCEEDED;
2440}
2441
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002442static struct weston_output *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002443ivi_layout_screen_get_output(struct ivi_layout_screen *iviscrn)
2444{
2445 return iviscrn->output;
2446}
2447
2448/**
2449 * This function is used by the additional ivi-module because of dumping ivi_surface sceenshot.
2450 * The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of Genivi's Layer Management.
2451 * This function is used to get the result of drawing by clients.
2452 */
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002453static struct weston_surface *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002454ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf)
2455{
2456 return ivisurf != NULL ? ivisurf->surface : NULL;
2457}
2458
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002459static int32_t
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09002460ivi_layout_surface_get_size(struct ivi_layout_surface *ivisurf,
2461 int32_t *width, int32_t *height,
2462 int32_t *stride)
2463{
2464 int32_t w;
2465 int32_t h;
2466 const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
2467
2468 if (ivisurf == NULL || ivisurf->surface == NULL) {
2469 weston_log("%s: invalid argument\n", __func__);
2470 return IVI_FAILED;
2471 }
2472
2473 weston_surface_get_content_size(ivisurf->surface, &w, &h);
2474
2475 if (width != NULL)
2476 *width = w;
2477
2478 if (height != NULL)
2479 *height = h;
2480
2481 if (stride != NULL)
2482 *stride = w * bytespp;
2483
2484 return IVI_SUCCEEDED;
2485}
2486
2487static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002488ivi_layout_layer_add_notification(struct ivi_layout_layer *ivilayer,
2489 layer_property_notification_func callback,
2490 void *userdata)
2491{
2492 struct ivi_layout_notification_callback *prop_callback = NULL;
2493
2494 if (ivilayer == NULL || callback == NULL) {
2495 weston_log("ivi_layout_layer_add_notification: invalid argument\n");
2496 return IVI_FAILED;
2497 }
2498
2499 prop_callback = malloc(sizeof *prop_callback);
2500 if (prop_callback == NULL) {
2501 weston_log("fails to allocate memory\n");
2502 return IVI_FAILED;
2503 }
2504
2505 prop_callback->callback = callback;
2506 prop_callback->data = userdata;
2507
2508 return add_notification(&ivilayer->property_changed,
2509 layer_prop_changed,
2510 prop_callback);
2511}
2512
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002513static const struct ivi_layout_surface_properties *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002514ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf)
2515{
2516 if (ivisurf == NULL) {
2517 weston_log("ivi_layout_get_properties_of_surface: invalid argument\n");
2518 return NULL;
2519 }
2520
2521 return &ivisurf->prop;
2522}
2523
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002524static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002525ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer,
2526 struct ivi_layout_surface *addsurf)
2527{
2528 struct ivi_layout *layout = get_instance();
2529 struct ivi_layout_surface *ivisurf = NULL;
2530 struct ivi_layout_surface *next = NULL;
2531 int is_surf_in_layer = 0;
2532
2533 if (ivilayer == NULL || addsurf == NULL) {
2534 weston_log("ivi_layout_layer_add_surface: invalid argument\n");
2535 return IVI_FAILED;
2536 }
2537
2538 is_surf_in_layer = is_surface_in_layer(addsurf, ivilayer);
2539 if (is_surf_in_layer == 1) {
2540 weston_log("ivi_layout_layer_add_surface: addsurf is already available\n");
2541 return IVI_SUCCEEDED;
2542 }
2543
2544 wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
2545 if (ivisurf->id_surface == addsurf->id_surface) {
2546 if (!wl_list_empty(&ivisurf->pending.link)) {
2547 wl_list_remove(&ivisurf->pending.link);
2548 }
2549 wl_list_init(&ivisurf->pending.link);
2550 wl_list_insert(&ivilayer->pending.surface_list,
2551 &ivisurf->pending.link);
2552 break;
2553 }
2554 }
2555
2556 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
2557
2558 return IVI_SUCCEEDED;
2559}
2560
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002561static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002562ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer,
2563 struct ivi_layout_surface *remsurf)
2564{
2565 struct ivi_layout_surface *ivisurf = NULL;
2566 struct ivi_layout_surface *next = NULL;
2567
2568 if (ivilayer == NULL || remsurf == NULL) {
2569 weston_log("ivi_layout_layer_remove_surface: invalid argument\n");
2570 return;
2571 }
2572
2573 wl_list_for_each_safe(ivisurf, next,
2574 &ivilayer->pending.surface_list, pending.link) {
2575 if (ivisurf->id_surface == remsurf->id_surface) {
2576 if (!wl_list_empty(&ivisurf->pending.link)) {
2577 wl_list_remove(&ivisurf->pending.link);
2578 }
2579 wl_list_init(&ivisurf->pending.link);
2580 break;
2581 }
2582 }
2583
2584 remsurf->event_mask |= IVI_NOTIFICATION_REMOVE;
2585}
2586
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002587static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002588ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf,
2589 int32_t x, int32_t y,
2590 int32_t width, int32_t height)
2591{
2592 struct ivi_layout_surface_properties *prop = NULL;
2593
2594 if (ivisurf == NULL) {
2595 weston_log("ivi_layout_surface_set_source_rectangle: invalid argument\n");
2596 return IVI_FAILED;
2597 }
2598
2599 prop = &ivisurf->pending.prop;
2600 prop->source_x = x;
2601 prop->source_y = y;
2602 prop->source_width = width;
2603 prop->source_height = height;
2604
2605 ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
2606
2607 return IVI_SUCCEEDED;
2608}
2609
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002610int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002611ivi_layout_commit_changes(void)
2612{
2613 struct ivi_layout *layout = get_instance();
2614
2615 commit_surface_list(layout);
2616 commit_layer_list(layout);
2617 commit_screen_list(layout);
2618
2619 commit_transition(layout);
2620
2621 commit_changes(layout);
2622 send_prop(layout);
2623 weston_compositor_schedule_repaint(layout->compositor);
2624
2625 return IVI_SUCCEEDED;
2626}
2627
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002628static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002629ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer,
2630 enum ivi_layout_transition_type type,
2631 uint32_t duration)
2632{
2633 if (ivilayer == NULL) {
2634 weston_log("%s: invalid argument\n", __func__);
2635 return -1;
2636 }
2637
2638 ivilayer->pending.prop.transition_type = type;
2639 ivilayer->pending.prop.transition_duration = duration;
2640
2641 return 0;
2642}
2643
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002644static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002645ivi_layout_layer_set_fade_info(struct ivi_layout_layer* ivilayer,
2646 uint32_t is_fade_in,
2647 double start_alpha, double end_alpha)
2648{
2649 if (ivilayer == NULL) {
2650 weston_log("%s: invalid argument\n", __func__);
2651 return -1;
2652 }
2653
2654 ivilayer->pending.prop.is_fade_in = is_fade_in;
2655 ivilayer->pending.prop.start_alpha = start_alpha;
2656 ivilayer->pending.prop.end_alpha = end_alpha;
2657
2658 return 0;
2659}
2660
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002661static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002662ivi_layout_surface_set_transition_duration(struct ivi_layout_surface *ivisurf,
2663 uint32_t duration)
2664{
2665 struct ivi_layout_surface_properties *prop;
2666
2667 if (ivisurf == NULL) {
2668 weston_log("%s: invalid argument\n", __func__);
2669 return -1;
2670 }
2671
2672 prop = &ivisurf->pending.prop;
2673 prop->transition_duration = duration*10;
2674 return 0;
2675}
2676
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002677static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002678ivi_layout_surface_set_transition(struct ivi_layout_surface *ivisurf,
2679 enum ivi_layout_transition_type type,
2680 uint32_t duration)
2681{
2682 struct ivi_layout_surface_properties *prop;
2683
2684 if (ivisurf == NULL) {
2685 weston_log("%s: invalid argument\n", __func__);
2686 return -1;
2687 }
2688
2689 prop = &ivisurf->pending.prop;
2690 prop->transition_type = type;
2691 prop->transition_duration = duration;
2692 return 0;
2693}
2694
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09002695static int32_t
2696ivi_layout_surface_dump(struct weston_surface *surface,
2697 void *target, size_t size,int32_t x, int32_t y,
2698 int32_t width, int32_t height)
2699{
2700 int result = 0;
2701
2702 if (surface == NULL) {
2703 weston_log("%s: invalid argument\n", __func__);
2704 return IVI_FAILED;
2705 }
2706
2707 result = weston_surface_copy_content(
2708 surface, target, size,
2709 x, y, width, height);
2710
2711 return result == 0 ? IVI_SUCCEEDED : IVI_FAILED;
2712}
2713
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002714/**
2715 * methods of interaction between ivi-shell with ivi-layout
2716 */
2717struct weston_view *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002718ivi_layout_get_weston_view(struct ivi_layout_surface *surface)
2719{
2720 struct weston_view *tmpview = NULL;
2721
2722 if(surface == NULL)
2723 return NULL;
2724
2725 wl_list_for_each(tmpview, &surface->surface->views, surface_link)
2726 {
2727 if (tmpview != NULL) {
2728 break;
2729 }
2730 }
2731 return tmpview;
2732}
2733
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002734void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002735ivi_layout_surface_configure(struct ivi_layout_surface *ivisurf,
2736 int32_t width, int32_t height)
2737{
2738 struct ivi_layout *layout = get_instance();
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002739
Nobuhiko Tanibatae6cc9972015-04-27 16:54:01 +09002740 /* emit callback which is set by ivi-layout api user */
2741 wl_signal_emit(&layout->surface_notification.configure_changed,
2742 ivisurf);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002743}
2744
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002745static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002746ivi_layout_surface_set_content_observer(struct ivi_layout_surface *ivisurf,
2747 ivi_controller_surface_content_callback callback,
2748 void* userdata)
2749{
2750 int32_t ret = IVI_FAILED;
2751
2752 if (ivisurf != NULL) {
2753 ivisurf->content_observer.callback = callback;
2754 ivisurf->content_observer.userdata = userdata;
2755 ret = IVI_SUCCEEDED;
2756 }
2757 return ret;
2758}
2759
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002760struct ivi_layout_surface*
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002761ivi_layout_surface_create(struct weston_surface *wl_surface,
2762 uint32_t id_surface)
2763{
2764 struct ivi_layout *layout = get_instance();
2765 struct ivi_layout_surface *ivisurf = NULL;
2766 struct weston_view *tmpview = NULL;
2767
2768 if (wl_surface == NULL) {
2769 weston_log("ivi_layout_surface_create: invalid argument\n");
2770 return NULL;
2771 }
2772
2773 ivisurf = get_surface(&layout->surface_list, id_surface);
2774 if (ivisurf != NULL) {
2775 if (ivisurf->surface != NULL) {
2776 weston_log("id_surface(%d) is already created\n", id_surface);
2777 return NULL;
2778 }
2779 }
2780
2781 ivisurf = calloc(1, sizeof *ivisurf);
2782 if (ivisurf == NULL) {
2783 weston_log("fails to allocate memory\n");
2784 return NULL;
2785 }
2786
2787 wl_list_init(&ivisurf->link);
2788 wl_signal_init(&ivisurf->property_changed);
2789 wl_signal_init(&ivisurf->configured);
2790 wl_list_init(&ivisurf->layer_list);
2791 ivisurf->id_surface = id_surface;
2792 ivisurf->layout = layout;
2793
2794 ivisurf->surface = wl_surface;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002795
2796 tmpview = weston_view_create(wl_surface);
2797 if (tmpview == NULL) {
2798 weston_log("fails to allocate memory\n");
2799 }
2800
2801 ivisurf->surface->width_from_buffer = 0;
2802 ivisurf->surface->height_from_buffer = 0;
2803
2804 weston_matrix_init(&ivisurf->surface_rotation.matrix);
2805 weston_matrix_init(&ivisurf->layer_rotation.matrix);
2806 weston_matrix_init(&ivisurf->surface_pos.matrix);
2807 weston_matrix_init(&ivisurf->layer_pos.matrix);
2808 weston_matrix_init(&ivisurf->scaling.matrix);
2809
2810 wl_list_init(&ivisurf->surface_rotation.link);
2811 wl_list_init(&ivisurf->layer_rotation.link);
2812 wl_list_init(&ivisurf->surface_pos.link);
2813 wl_list_init(&ivisurf->layer_pos.link);
2814 wl_list_init(&ivisurf->scaling.link);
2815
2816 init_surface_properties(&ivisurf->prop);
2817 ivisurf->event_mask = 0;
2818
2819 ivisurf->pending.prop = ivisurf->prop;
2820 wl_list_init(&ivisurf->pending.link);
2821
2822 wl_list_init(&ivisurf->order.link);
2823 wl_list_init(&ivisurf->order.layer_list);
2824
2825 wl_list_insert(&layout->surface_list, &ivisurf->link);
2826
2827 wl_signal_emit(&layout->surface_notification.created, ivisurf);
2828
2829 return ivisurf;
2830}
2831
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002832void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002833ivi_layout_init_with_compositor(struct weston_compositor *ec)
2834{
2835 struct ivi_layout *layout = get_instance();
2836
2837 layout->compositor = ec;
2838
2839 wl_list_init(&layout->surface_list);
2840 wl_list_init(&layout->layer_list);
2841 wl_list_init(&layout->screen_list);
2842
2843 wl_signal_init(&layout->layer_notification.created);
2844 wl_signal_init(&layout->layer_notification.removed);
2845
2846 wl_signal_init(&layout->surface_notification.created);
2847 wl_signal_init(&layout->surface_notification.removed);
2848 wl_signal_init(&layout->surface_notification.configure_changed);
2849
2850 /* Add layout_layer at the last of weston_compositor.layer_list */
2851 weston_layer_init(&layout->layout_layer, ec->layer_list.prev);
2852
2853 create_screen(ec);
2854
2855 layout->transitions = ivi_layout_transition_set_create(ec);
2856 wl_list_init(&layout->pending_transition_list);
2857}
2858
2859
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002860void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002861ivi_layout_surface_add_configured_listener(struct ivi_layout_surface* ivisurf,
2862 struct wl_listener* listener)
2863{
2864 wl_signal_add(&ivisurf->configured, listener);
2865}
2866
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002867static struct ivi_controller_interface ivi_controller_interface = {
2868 /**
2869 * commit all changes
2870 */
2871 .commit_changes = ivi_layout_commit_changes,
2872
2873 /**
2874 * surface controller interfaces
2875 */
2876 .add_notification_create_surface = ivi_layout_add_notification_create_surface,
2877 .remove_notification_create_surface = ivi_layout_remove_notification_create_surface,
2878 .add_notification_remove_surface = ivi_layout_add_notification_remove_surface,
2879 .remove_notification_remove_surface = ivi_layout_remove_notification_remove_surface,
2880 .add_notification_configure_surface = ivi_layout_add_notification_configure_surface,
2881 .remove_notification_configure_surface = ivi_layout_remove_notification_configure_surface,
2882 .get_surfaces = ivi_layout_get_surfaces,
2883 .get_id_of_surface = ivi_layout_get_id_of_surface,
2884 .get_surface_from_id = ivi_layout_get_surface_from_id,
2885 .get_properties_of_surface = ivi_layout_get_properties_of_surface,
2886 .get_surfaces_on_layer = ivi_layout_get_surfaces_on_layer,
2887 .surface_set_visibility = ivi_layout_surface_set_visibility,
2888 .surface_get_visibility = ivi_layout_surface_get_visibility,
2889 .surface_set_opacity = ivi_layout_surface_set_opacity,
2890 .surface_get_opacity = ivi_layout_surface_get_opacity,
2891 .surface_set_source_rectangle = ivi_layout_surface_set_source_rectangle,
2892 .surface_set_destination_rectangle = ivi_layout_surface_set_destination_rectangle,
2893 .surface_set_position = ivi_layout_surface_set_position,
2894 .surface_get_position = ivi_layout_surface_get_position,
2895 .surface_set_dimension = ivi_layout_surface_set_dimension,
2896 .surface_get_dimension = ivi_layout_surface_get_dimension,
2897 .surface_set_orientation = ivi_layout_surface_set_orientation,
2898 .surface_get_orientation = ivi_layout_surface_get_orientation,
2899 .surface_set_content_observer = ivi_layout_surface_set_content_observer,
2900 .surface_add_notification = ivi_layout_surface_add_notification,
2901 .surface_remove_notification = ivi_layout_surface_remove_notification,
2902 .surface_get_weston_surface = ivi_layout_surface_get_weston_surface,
2903 .surface_set_transition = ivi_layout_surface_set_transition,
2904 .surface_set_transition_duration = ivi_layout_surface_set_transition_duration,
2905
2906 /**
2907 * layer controller interfaces
2908 */
2909 .add_notification_create_layer = ivi_layout_add_notification_create_layer,
2910 .remove_notification_create_layer = ivi_layout_remove_notification_create_layer,
2911 .add_notification_remove_layer = ivi_layout_add_notification_remove_layer,
2912 .remove_notification_remove_layer = ivi_layout_remove_notification_remove_layer,
2913 .layer_create_with_dimension = ivi_layout_layer_create_with_dimension,
2914 .layer_remove = ivi_layout_layer_remove,
2915 .get_layers = ivi_layout_get_layers,
2916 .get_id_of_layer = ivi_layout_get_id_of_layer,
2917 .get_layer_from_id = ivi_layout_get_layer_from_id,
2918 .get_properties_of_layer = ivi_layout_get_properties_of_layer,
2919 .get_layers_under_surface = ivi_layout_get_layers_under_surface,
2920 .get_layers_on_screen = ivi_layout_get_layers_on_screen,
2921 .layer_set_visibility = ivi_layout_layer_set_visibility,
2922 .layer_get_visibility = ivi_layout_layer_get_visibility,
2923 .layer_set_opacity = ivi_layout_layer_set_opacity,
2924 .layer_get_opacity = ivi_layout_layer_get_opacity,
2925 .layer_set_source_rectangle = ivi_layout_layer_set_source_rectangle,
2926 .layer_set_destination_rectangle = ivi_layout_layer_set_destination_rectangle,
2927 .layer_set_position = ivi_layout_layer_set_position,
2928 .layer_get_position = ivi_layout_layer_get_position,
2929 .layer_set_dimension = ivi_layout_layer_set_dimension,
2930 .layer_get_dimension = ivi_layout_layer_get_dimension,
2931 .layer_set_orientation = ivi_layout_layer_set_orientation,
2932 .layer_get_orientation = ivi_layout_layer_get_orientation,
2933 .layer_add_surface = ivi_layout_layer_add_surface,
2934 .layer_remove_surface = ivi_layout_layer_remove_surface,
2935 .layer_set_render_order = ivi_layout_layer_set_render_order,
2936 .layer_add_notification = ivi_layout_layer_add_notification,
2937 .layer_remove_notification = ivi_layout_layer_remove_notification,
2938 .layer_set_transition = ivi_layout_layer_set_transition,
2939
2940 /**
2941 * screen controller interfaces
2942 */
2943 .get_screen_from_id = ivi_layout_get_screen_from_id,
2944 .get_screen_resolution = ivi_layout_get_screen_resolution,
2945 .get_screens = ivi_layout_get_screens,
2946 .get_screens_under_layer = ivi_layout_get_screens_under_layer,
2947 .screen_add_layer = ivi_layout_screen_add_layer,
2948 .screen_set_render_order = ivi_layout_screen_set_render_order,
2949 .screen_get_output = ivi_layout_screen_get_output,
2950
2951 /**
2952 * animation
2953 */
2954 .transition_move_layer_cancel = ivi_layout_transition_move_layer_cancel,
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09002955 .layer_set_fade_info = ivi_layout_layer_set_fade_info,
2956
2957 /**
2958 * surface content dumping for debugging
2959 */
2960 .surface_get_size = ivi_layout_surface_get_size,
2961 .surface_dump = ivi_layout_surface_dump,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002962};
2963
2964int
2965load_controller_modules(struct weston_compositor *compositor, const char *modules,
2966 int *argc, char *argv[])
2967{
2968 const char *p, *end;
2969 char buffer[256];
2970 int (*controller_module_init)(struct weston_compositor *compositor,
2971 int *argc, char *argv[],
2972 const struct ivi_controller_interface *interface,
2973 size_t interface_version);
2974
2975 if (modules == NULL)
2976 return 0;
2977
2978 p = modules;
2979 while (*p) {
2980 end = strchrnul(p, ',');
2981 snprintf(buffer, sizeof buffer, "%.*s", (int)(end - p), p);
2982
2983 controller_module_init = weston_load_module(buffer, "controller_module_init");
Pekka Paalanen97246c02015-03-26 15:47:29 +02002984 if (!controller_module_init)
2985 return -1;
2986
2987 if (controller_module_init(compositor, argc, argv,
2988 &ivi_controller_interface,
2989 sizeof(struct ivi_controller_interface)) != 0) {
2990 weston_log("ivi-shell: Initialization of controller module fails");
2991 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002992 }
2993
2994 p = end;
2995 while (*p == ',')
2996 p++;
2997 }
2998
2999 return 0;
3000}