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