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