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