blob: 8683e7dd0228db7819745680253a90e7503a6cef [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 */
55
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090056#include <string.h>
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090057
58#include "compositor.h"
59#include "ivi-layout-export.h"
60#include "ivi-layout-private.h"
61
62struct link_layer {
63 struct ivi_layout_layer *ivilayer;
64 struct wl_list link;
65 struct wl_list link_to_layer;
66};
67
68struct link_screen {
69 struct ivi_layout_screen *iviscrn;
70 struct wl_list link;
71 struct wl_list link_to_screen;
72};
73
74struct listener_layout_notification {
75 void *userdata;
76 struct wl_listener listener;
77};
78
79struct ivi_layout;
80
81struct ivi_layout_screen {
82 struct wl_list link;
83 struct wl_list link_to_layer;
84 uint32_t id_screen;
85
86 struct ivi_layout *layout;
87 struct weston_output *output;
88
89 uint32_t event_mask;
90
91 struct {
92 struct wl_list layer_list;
93 struct wl_list link;
94 } pending;
95
96 struct {
97 struct wl_list layer_list;
98 struct wl_list link;
99 } order;
100};
101
102struct ivi_layout_notification_callback {
103 void *callback;
104 void *data;
105};
106
107static struct ivi_layout ivilayout = {0};
108
109struct ivi_layout *
110get_instance(void)
111{
112 return &ivilayout;
113}
114
115/**
116 * Internal API to add/remove a link to ivi_surface from ivi_layer.
117 */
118static void
119add_link_to_surface(struct ivi_layout_layer *ivilayer,
120 struct link_layer *link_layer)
121{
122 struct link_layer *link = NULL;
123
124 wl_list_for_each(link, &ivilayer->link_to_surface, link_to_layer) {
125 if (link == link_layer)
126 return;
127 }
128
129 wl_list_insert(&ivilayer->link_to_surface, &link_layer->link_to_layer);
130}
131
132static void
133remove_link_to_surface(struct ivi_layout_layer *ivilayer)
134{
135 struct link_layer *link = NULL;
136 struct link_layer *next = NULL;
137
138 wl_list_for_each_safe(link, next, &ivilayer->link_to_surface, link_to_layer) {
139 if (!wl_list_empty(&link->link_to_layer)) {
140 wl_list_remove(&link->link_to_layer);
141 }
142 if (!wl_list_empty(&link->link)) {
143 wl_list_remove(&link->link);
144 }
145 free(link);
146 }
147
148 wl_list_init(&ivilayer->link_to_surface);
149}
150
151/**
152 * Internal API to add a link to ivi_layer from ivi_screen.
153 */
154static void
155add_link_to_layer(struct ivi_layout_screen *iviscrn,
156 struct link_screen *link_screen)
157{
158 wl_list_init(&link_screen->link_to_screen);
159 wl_list_insert(&iviscrn->link_to_layer, &link_screen->link_to_screen);
160}
161
162/**
163 * Internal API to add/remove a ivi_surface from ivi_layer.
164 */
165static void
166add_ordersurface_to_layer(struct ivi_layout_surface *ivisurf,
167 struct ivi_layout_layer *ivilayer)
168{
169 struct link_layer *link_layer = NULL;
170
171 link_layer = malloc(sizeof *link_layer);
172 if (link_layer == NULL) {
173 weston_log("fails to allocate memory\n");
174 return;
175 }
176
177 link_layer->ivilayer = ivilayer;
178 wl_list_init(&link_layer->link);
179 wl_list_insert(&ivisurf->layer_list, &link_layer->link);
180 add_link_to_surface(ivilayer, link_layer);
181}
182
183static void
184remove_ordersurface_from_layer(struct ivi_layout_surface *ivisurf)
185{
186 struct link_layer *link_layer = NULL;
187 struct link_layer *next = NULL;
188
189 wl_list_for_each_safe(link_layer, next, &ivisurf->layer_list, link) {
190 if (!wl_list_empty(&link_layer->link)) {
191 wl_list_remove(&link_layer->link);
192 }
193 if (!wl_list_empty(&link_layer->link_to_layer)) {
194 wl_list_remove(&link_layer->link_to_layer);
195 }
196 free(link_layer);
197 }
198 wl_list_init(&ivisurf->layer_list);
199}
200
201/**
202 * Internal API to add/remove a ivi_layer to/from ivi_screen.
203 */
204static void
205add_orderlayer_to_screen(struct ivi_layout_layer *ivilayer,
206 struct ivi_layout_screen *iviscrn)
207{
208 struct link_screen *link_scrn = NULL;
209
210 link_scrn = malloc(sizeof *link_scrn);
211 if (link_scrn == NULL) {
212 weston_log("fails to allocate memory\n");
213 return;
214 }
215
216 link_scrn->iviscrn = iviscrn;
217 wl_list_init(&link_scrn->link);
218 wl_list_insert(&ivilayer->screen_list, &link_scrn->link);
219 add_link_to_layer(iviscrn, link_scrn);
220}
221
222static void
223remove_orderlayer_from_screen(struct ivi_layout_layer *ivilayer)
224{
225 struct link_screen *link_scrn = NULL;
226 struct link_screen *next = NULL;
227
228 wl_list_for_each_safe(link_scrn, next, &ivilayer->screen_list, link) {
229 if (!wl_list_empty(&link_scrn->link)) {
230 wl_list_remove(&link_scrn->link);
231 }
232 if (!wl_list_empty(&link_scrn->link_to_screen)) {
233 wl_list_remove(&link_scrn->link_to_screen);
234 }
235 free(link_scrn);
236 }
237 wl_list_init(&ivilayer->screen_list);
238}
239
240/**
241 * Internal API to add/remove a ivi_layer to/from ivi_screen.
242 */
243static struct ivi_layout_surface *
244get_surface(struct wl_list *surf_list, uint32_t id_surface)
245{
246 struct ivi_layout_surface *ivisurf;
247
248 wl_list_for_each(ivisurf, surf_list, link) {
249 if (ivisurf->id_surface == id_surface) {
250 return ivisurf;
251 }
252 }
253
254 return NULL;
255}
256
257static struct ivi_layout_layer *
258get_layer(struct wl_list *layer_list, uint32_t id_layer)
259{
260 struct ivi_layout_layer *ivilayer;
261
262 wl_list_for_each(ivilayer, layer_list, link) {
263 if (ivilayer->id_layer == id_layer) {
264 return ivilayer;
265 }
266 }
267
268 return NULL;
269}
270
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900271static void
272remove_configured_listener(struct ivi_layout_surface *ivisurf)
273{
274 struct wl_listener *link = NULL;
275 struct wl_listener *next = NULL;
276
277 wl_list_for_each_safe(link, next, &ivisurf->configured.listener_list, link) {
278 wl_list_remove(&link->link);
279 }
280}
281
282
283static void
284remove_all_notification(struct wl_list *listener_list)
285{
286 struct wl_listener *listener = NULL;
287 struct wl_listener *next = NULL;
288
289 wl_list_for_each_safe(listener, next, listener_list, link) {
290 struct listener_layout_notification *notification = NULL;
291 if (!wl_list_empty(&listener->link)) {
292 wl_list_remove(&listener->link);
293 }
294
295 notification =
296 container_of(listener,
297 struct listener_layout_notification,
298 listener);
299
300 free(notification->userdata);
301 free(notification);
302 }
303}
304
305WL_EXPORT void
306ivi_layout_surface_remove_notification(struct ivi_layout_surface *ivisurf)
307{
308 if (ivisurf == NULL) {
309 weston_log("ivi_layout_surface_remove_notification: invalid argument\n");
310 return;
311 }
312
313 remove_all_notification(&ivisurf->property_changed.listener_list);
314}
315
316void
317ivi_layout_surface_remove(struct ivi_layout_surface *ivisurf)
318{
319 struct ivi_layout *layout = get_instance();
320
321 if (ivisurf == NULL) {
322 weston_log("ivi_layout_surface_remove: invalid argument\n");
323 return;
324 }
325
326 if (!wl_list_empty(&ivisurf->pending.link)) {
327 wl_list_remove(&ivisurf->pending.link);
328 }
329 if (!wl_list_empty(&ivisurf->order.link)) {
330 wl_list_remove(&ivisurf->order.link);
331 }
332 if (!wl_list_empty(&ivisurf->link)) {
333 wl_list_remove(&ivisurf->link);
334 }
335 remove_ordersurface_from_layer(ivisurf);
336
337 wl_signal_emit(&layout->surface_notification.removed, ivisurf);
338
339 remove_configured_listener(ivisurf);
340
341 ivi_layout_surface_remove_notification(ivisurf);
342
343 free(ivisurf);
344}
345
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900346/**
347 * Called at destruction of ivi_surface
348 */
349static void
350westonsurface_destroy_from_ivisurface(struct wl_listener *listener, void *data)
351{
352 struct ivi_layout_surface *ivisurf = NULL;
353
354 ivisurf = container_of(listener, struct ivi_layout_surface,
355 surface_destroy_listener);
356
357 wl_list_remove(&ivisurf->surface_rotation.link);
358 wl_list_remove(&ivisurf->layer_rotation.link);
359 wl_list_remove(&ivisurf->surface_pos.link);
360 wl_list_remove(&ivisurf->layer_pos.link);
361 wl_list_remove(&ivisurf->scaling.link);
362
363 ivisurf->surface = NULL;
364 ivi_layout_surface_remove(ivisurf);
365}
366
367/**
368 * Internal API to check ivi_layer/ivi_surface already added in ivi_layer/ivi_screen.
369 * Called by ivi_layout_layer_add_surface/ivi_layout_screenAddLayer
370 */
371static int
372is_surface_in_layer(struct ivi_layout_surface *ivisurf,
373 struct ivi_layout_layer *ivilayer)
374{
375 struct ivi_layout_surface *surf = NULL;
376
377 wl_list_for_each(surf, &ivilayer->pending.surface_list, pending.link) {
378 if (surf->id_surface == ivisurf->id_surface) {
379 return 1;
380 }
381 }
382
383 return 0;
384}
385
386static int
387is_layer_in_screen(struct ivi_layout_layer *ivilayer,
388 struct ivi_layout_screen *iviscrn)
389{
390 struct ivi_layout_layer *layer = NULL;
391
392 wl_list_for_each(layer, &iviscrn->pending.layer_list, pending.link) {
393 if (layer->id_layer == ivilayer->id_layer) {
394 return 1;
395 }
396 }
397
398 return 0;
399}
400
401/**
402 * Internal API to initialize ivi_screens found from output_list of weston_compositor.
403 * Called by ivi_layout_init_with_compositor.
404 */
405static void
406create_screen(struct weston_compositor *ec)
407{
408 struct ivi_layout *layout = get_instance();
409 struct ivi_layout_screen *iviscrn = NULL;
410 struct weston_output *output = NULL;
411 int32_t count = 0;
412
413 wl_list_for_each(output, &ec->output_list, link) {
414 iviscrn = calloc(1, sizeof *iviscrn);
415 if (iviscrn == NULL) {
416 weston_log("fails to allocate memory\n");
417 continue;
418 }
419
420 wl_list_init(&iviscrn->link);
421 iviscrn->layout = layout;
422
423 iviscrn->id_screen = count;
424 count++;
425
426 iviscrn->output = output;
427 iviscrn->event_mask = 0;
428
429 wl_list_init(&iviscrn->pending.layer_list);
430 wl_list_init(&iviscrn->pending.link);
431
432 wl_list_init(&iviscrn->order.layer_list);
433 wl_list_init(&iviscrn->order.link);
434
435 wl_list_init(&iviscrn->link_to_layer);
436
437 wl_list_insert(&layout->screen_list, &iviscrn->link);
438 }
439}
440
441/**
442 * Internal APIs to initialize properties of ivi_surface/ivi_layer when they are created.
443 */
444static void
445init_layer_properties(struct ivi_layout_layer_properties *prop,
446 int32_t width, int32_t height)
447{
448 memset(prop, 0, sizeof *prop);
449 prop->opacity = wl_fixed_from_double(1.0);
450 prop->source_width = width;
451 prop->source_height = height;
452 prop->dest_width = width;
453 prop->dest_height = height;
454}
455
456static void
457init_surface_properties(struct ivi_layout_surface_properties *prop)
458{
459 memset(prop, 0, sizeof *prop);
460 prop->opacity = wl_fixed_from_double(1.0);
461}
462
463/**
464 * Internal APIs to be called from ivi_layout_commit_changes.
465 */
466static void
467update_opacity(struct ivi_layout_layer *ivilayer,
468 struct ivi_layout_surface *ivisurf)
469{
470 double layer_alpha = wl_fixed_to_double(ivilayer->prop.opacity);
471 double surf_alpha = wl_fixed_to_double(ivisurf->prop.opacity);
472
473 if ((ivilayer->event_mask & IVI_NOTIFICATION_OPACITY) ||
474 (ivisurf->event_mask & IVI_NOTIFICATION_OPACITY)) {
475 struct weston_view *tmpview = NULL;
476 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
477 if (tmpview == NULL) {
478 continue;
479 }
480 tmpview->alpha = layer_alpha * surf_alpha;
481 }
482 }
483}
484
485static void
486update_surface_orientation(struct ivi_layout_layer *ivilayer,
487 struct ivi_layout_surface *ivisurf)
488{
489 struct weston_view *view;
490 struct weston_matrix *matrix = &ivisurf->surface_rotation.matrix;
491 float width = 0.0f;
492 float height = 0.0f;
493 float v_sin = 0.0f;
494 float v_cos = 0.0f;
495 float cx = 0.0f;
496 float cy = 0.0f;
497 float sx = 1.0f;
498 float sy = 1.0f;
499
500 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
501 if (view != NULL) {
502 break;
503 }
504 }
505
506 if (view == NULL) {
507 return;
508 }
509
510 if ((ivilayer->prop.dest_width == 0) ||
511 (ivilayer->prop.dest_height == 0)) {
512 return;
513 }
514 width = (float)ivilayer->prop.dest_width;
515 height = (float)ivilayer->prop.dest_height;
516
517 switch (ivisurf->prop.orientation) {
518 case WL_OUTPUT_TRANSFORM_NORMAL:
519 v_sin = 0.0f;
520 v_cos = 1.0f;
521 break;
522 case WL_OUTPUT_TRANSFORM_90:
523 v_sin = 1.0f;
524 v_cos = 0.0f;
525 sx = width / height;
526 sy = height / width;
527 break;
528 case WL_OUTPUT_TRANSFORM_180:
529 v_sin = 0.0f;
530 v_cos = -1.0f;
531 break;
532 case WL_OUTPUT_TRANSFORM_270:
533 default:
534 v_sin = -1.0f;
535 v_cos = 0.0f;
536 sx = width / height;
537 sy = height / width;
538 break;
539 }
540 wl_list_remove(&ivisurf->surface_rotation.link);
541 weston_view_geometry_dirty(view);
542
543 weston_matrix_init(matrix);
544 cx = 0.5f * width;
545 cy = 0.5f * height;
546 weston_matrix_translate(matrix, -cx, -cy, 0.0f);
547 weston_matrix_rotate_xy(matrix, v_cos, v_sin);
548 weston_matrix_scale(matrix, sx, sy, 1.0);
549 weston_matrix_translate(matrix, cx, cy, 0.0f);
550 wl_list_insert(&view->geometry.transformation_list,
551 &ivisurf->surface_rotation.link);
552
553 weston_view_set_transform_parent(view, NULL);
554 weston_view_update_transform(view);
555}
556
557static void
558update_layer_orientation(struct ivi_layout_layer *ivilayer,
559 struct ivi_layout_surface *ivisurf)
560{
561 struct weston_surface *es = ivisurf->surface;
562 struct weston_view *view;
563 struct weston_matrix *matrix = &ivisurf->layer_rotation.matrix;
564 struct weston_output *output = NULL;
565 float width = 0.0f;
566 float height = 0.0f;
567 float v_sin = 0.0f;
568 float v_cos = 0.0f;
569 float cx = 0.0f;
570 float cy = 0.0f;
571 float sx = 1.0f;
572 float sy = 1.0f;
573
574 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
575 if (view != NULL) {
576 break;
577 }
578 }
579
580 if (es == NULL || view == NULL) {
581 return;
582 }
583
584 output = es->output;
585 if (output == NULL) {
586 return;
587 }
588 if ((output->width == 0) || (output->height == 0)) {
589 return;
590 }
591 width = (float)output->width;
592 height = (float)output->height;
593
594 switch (ivilayer->prop.orientation) {
595 case WL_OUTPUT_TRANSFORM_NORMAL:
596 v_sin = 0.0f;
597 v_cos = 1.0f;
598 break;
599 case WL_OUTPUT_TRANSFORM_90:
600 v_sin = 1.0f;
601 v_cos = 0.0f;
602 sx = width / height;
603 sy = height / width;
604 break;
605 case WL_OUTPUT_TRANSFORM_180:
606 v_sin = 0.0f;
607 v_cos = -1.0f;
608 break;
609 case WL_OUTPUT_TRANSFORM_270:
610 default:
611 v_sin = -1.0f;
612 v_cos = 0.0f;
613 sx = width / height;
614 sy = height / width;
615 break;
616 }
617 wl_list_remove(&ivisurf->layer_rotation.link);
618 weston_view_geometry_dirty(view);
619
620 weston_matrix_init(matrix);
621 cx = 0.5f * width;
622 cy = 0.5f * height;
623 weston_matrix_translate(matrix, -cx, -cy, 0.0f);
624 weston_matrix_rotate_xy(matrix, v_cos, v_sin);
625 weston_matrix_scale(matrix, sx, sy, 1.0);
626 weston_matrix_translate(matrix, cx, cy, 0.0f);
627 wl_list_insert(&view->geometry.transformation_list,
628 &ivisurf->layer_rotation.link);
629
630 weston_view_set_transform_parent(view, NULL);
631 weston_view_update_transform(view);
632}
633
634static void
635update_surface_position(struct ivi_layout_surface *ivisurf)
636{
637 struct weston_view *view;
638 float tx = (float)ivisurf->prop.dest_x;
639 float ty = (float)ivisurf->prop.dest_y;
640 struct weston_matrix *matrix = &ivisurf->surface_pos.matrix;
641
642 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
643 if (view != NULL) {
644 break;
645 }
646 }
647
648 if (view == NULL) {
649 return;
650 }
651
652 wl_list_remove(&ivisurf->surface_pos.link);
653
654 weston_matrix_init(matrix);
655 weston_matrix_translate(matrix, tx, ty, 0.0f);
656 wl_list_insert(&view->geometry.transformation_list,
657 &ivisurf->surface_pos.link);
658
659 weston_view_set_transform_parent(view, NULL);
660 weston_view_update_transform(view);
661}
662
663static void
664update_layer_position(struct ivi_layout_layer *ivilayer,
665 struct ivi_layout_surface *ivisurf)
666{
667 struct weston_view *view;
668 struct weston_matrix *matrix = &ivisurf->layer_pos.matrix;
669 float tx = (float)ivilayer->prop.dest_x;
670 float ty = (float)ivilayer->prop.dest_y;
671
672 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
673 if (view != NULL) {
674 break;
675 }
676 }
677
678 if (view == NULL) {
679 return;
680 }
681
682 wl_list_remove(&ivisurf->layer_pos.link);
683
684 weston_matrix_init(matrix);
685 weston_matrix_translate(matrix, tx, ty, 0.0f);
686 wl_list_insert(&view->geometry.transformation_list,
687 &ivisurf->layer_pos.link);
688
689 weston_view_set_transform_parent(view, NULL);
690 weston_view_update_transform(view);
691}
692
693static void
694update_scale(struct ivi_layout_layer *ivilayer,
695 struct ivi_layout_surface *ivisurf)
696{
697 struct weston_view *view;
698 struct weston_matrix *matrix = &ivisurf->scaling.matrix;
699 float sx = 0.0f;
700 float sy = 0.0f;
701 float lw = 0.0f;
702 float sw = 0.0f;
703 float lh = 0.0f;
704 float sh = 0.0f;
705
706 wl_list_for_each(view, &ivisurf->surface->views, surface_link) {
707 if (view != NULL) {
708 break;
709 }
710 }
711
712 if (view == NULL) {
713 return;
714 }
715
716 if (ivisurf->prop.dest_width == 0 && ivisurf->prop.dest_height == 0) {
717 ivisurf->prop.dest_width = ivisurf->surface->width_from_buffer;
718 ivisurf->prop.dest_height = ivisurf->surface->height_from_buffer;
719 }
720
721 lw = ((float)ivilayer->prop.dest_width / (float)ivilayer->prop.source_width );
722 sw = ((float)ivisurf->prop.dest_width / (float)ivisurf->prop.source_width );
723 lh = ((float)ivilayer->prop.dest_height / (float)ivilayer->prop.source_height);
724 sh = ((float)ivisurf->prop.dest_height / (float)ivisurf->prop.source_height );
725 sx = sw * lw;
726 sy = sh * lh;
727
728 wl_list_remove(&ivisurf->scaling.link);
729 weston_matrix_init(matrix);
730 weston_matrix_scale(matrix, sx, sy, 1.0f);
731
732 wl_list_insert(&view->geometry.transformation_list,
733 &ivisurf->scaling.link);
734
735 weston_view_set_transform_parent(view, NULL);
736 weston_view_update_transform(view);
737}
738
739static void
740update_prop(struct ivi_layout_layer *ivilayer,
741 struct ivi_layout_surface *ivisurf)
742{
743 if (ivilayer->event_mask | ivisurf->event_mask) {
744 struct weston_view *tmpview;
745 update_opacity(ivilayer, ivisurf);
746 update_layer_orientation(ivilayer, ivisurf);
747 update_layer_position(ivilayer, ivisurf);
748 update_surface_position(ivisurf);
749 update_surface_orientation(ivilayer, ivisurf);
750 update_scale(ivilayer, ivisurf);
751
752 ivisurf->update_count++;
753
754 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
755 if (tmpview != NULL) {
756 break;
757 }
758 }
759
760 if (tmpview != NULL) {
761 weston_view_geometry_dirty(tmpview);
762 }
763
764 if (ivisurf->surface != NULL) {
765 weston_surface_damage(ivisurf->surface);
766 }
767 }
768}
769
770static void
771commit_changes(struct ivi_layout *layout)
772{
773 struct ivi_layout_screen *iviscrn = NULL;
774 struct ivi_layout_layer *ivilayer = NULL;
775 struct ivi_layout_surface *ivisurf = NULL;
776
777 wl_list_for_each(iviscrn, &layout->screen_list, link) {
778 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
779 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
780 update_prop(ivilayer, ivisurf);
781 }
782 }
783 }
784}
785
786static void
787commit_surface_list(struct ivi_layout *layout)
788{
789 struct ivi_layout_surface *ivisurf = NULL;
790 int32_t dest_x = 0;
791 int32_t dest_y = 0;
792 int32_t dest_width = 0;
793 int32_t dest_height = 0;
794 int32_t configured = 0;
795
796 wl_list_for_each(ivisurf, &layout->surface_list, link) {
797 if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEFAULT) {
798 dest_x = ivisurf->prop.dest_x;
799 dest_y = ivisurf->prop.dest_y;
800 dest_width = ivisurf->prop.dest_width;
801 dest_height = ivisurf->prop.dest_height;
802
803 ivi_layout_transition_move_resize_view(ivisurf,
804 ivisurf->pending.prop.dest_x,
805 ivisurf->pending.prop.dest_y,
806 ivisurf->pending.prop.dest_width,
807 ivisurf->pending.prop.dest_height,
808 ivisurf->pending.prop.transition_duration);
809
810 if(ivisurf->pending.prop.visibility) {
811 ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
812 } else {
813 ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
814 }
815
816 ivisurf->prop = ivisurf->pending.prop;
817 ivisurf->prop.dest_x = dest_x;
818 ivisurf->prop.dest_y = dest_y;
819 ivisurf->prop.dest_width = dest_width;
820 ivisurf->prop.dest_height = dest_height;
821 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
822 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
823
824 } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY){
825 dest_x = ivisurf->prop.dest_x;
826 dest_y = ivisurf->prop.dest_y;
827 dest_width = ivisurf->prop.dest_width;
828 dest_height = ivisurf->prop.dest_height;
829
830 ivi_layout_transition_move_resize_view(ivisurf,
831 ivisurf->pending.prop.dest_x,
832 ivisurf->pending.prop.dest_y,
833 ivisurf->pending.prop.dest_width,
834 ivisurf->pending.prop.dest_height,
835 ivisurf->pending.prop.transition_duration);
836
837 ivisurf->prop = ivisurf->pending.prop;
838 ivisurf->prop.dest_x = dest_x;
839 ivisurf->prop.dest_y = dest_y;
840 ivisurf->prop.dest_width = dest_width;
841 ivisurf->prop.dest_height = dest_height;
842
843 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
844 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
845
846 } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY){
847 configured = 0;
848 if(ivisurf->pending.prop.visibility) {
849 ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
850 } else {
851 ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
852 }
853
854 if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
855 ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
856 configured = 1;
857 }
858
859 ivisurf->prop = ivisurf->pending.prop;
860 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
861 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
862
863 if (configured && !is_surface_transition(ivisurf))
864 wl_signal_emit(&ivisurf->configured, ivisurf);
865 } else {
866 configured = 0;
867 if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
868 ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
869 configured = 1;
870 }
871
872 ivisurf->prop = ivisurf->pending.prop;
873 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
874 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
875
876 if (configured && !is_surface_transition(ivisurf))
877 wl_signal_emit(&ivisurf->configured, ivisurf);
878 }
879 }
880}
881
882static void
883commit_layer_list(struct ivi_layout *layout)
884{
885 struct ivi_layout_layer *ivilayer = NULL;
886 struct ivi_layout_surface *ivisurf = NULL;
887 struct ivi_layout_surface *next = NULL;
888
889 wl_list_for_each(ivilayer, &layout->layer_list, link) {
890 if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_MOVE) {
891 ivi_layout_transition_move_layer(ivilayer, ivilayer->pending.prop.dest_x, ivilayer->pending.prop.dest_y, ivilayer->pending.prop.transition_duration);
892 } else if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_FADE) {
893 ivi_layout_transition_fade_layer(ivilayer,ivilayer->pending.prop.is_fade_in,
894 ivilayer->pending.prop.start_alpha,ivilayer->pending.prop.end_alpha,
895 NULL, NULL,
896 ivilayer->pending.prop.transition_duration);
897 }
898 ivilayer->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
899
900 ivilayer->prop = ivilayer->pending.prop;
901
902 if (!(ivilayer->event_mask &
903 (IVI_NOTIFICATION_ADD | IVI_NOTIFICATION_REMOVE)) ) {
904 continue;
905 }
906
907 if (ivilayer->event_mask & IVI_NOTIFICATION_REMOVE) {
908 wl_list_for_each_safe(ivisurf, next,
909 &ivilayer->order.surface_list, order.link) {
910 remove_ordersurface_from_layer(ivisurf);
911
912 if (!wl_list_empty(&ivisurf->order.link)) {
913 wl_list_remove(&ivisurf->order.link);
914 }
915
916 wl_list_init(&ivisurf->order.link);
917 ivisurf->event_mask |= IVI_NOTIFICATION_REMOVE;
918 }
919
920 wl_list_init(&ivilayer->order.surface_list);
921 }
922
923 if (ivilayer->event_mask & IVI_NOTIFICATION_ADD) {
924 wl_list_for_each_safe(ivisurf, next,
925 &ivilayer->order.surface_list, order.link) {
926 remove_ordersurface_from_layer(ivisurf);
927
928 if (!wl_list_empty(&ivisurf->order.link)) {
929 wl_list_remove(&ivisurf->order.link);
930 }
931
932 wl_list_init(&ivisurf->order.link);
933 }
934
935 wl_list_init(&ivilayer->order.surface_list);
936 wl_list_for_each(ivisurf, &ivilayer->pending.surface_list,
937 pending.link) {
938 if(!wl_list_empty(&ivisurf->order.link)){
939 wl_list_remove(&ivisurf->order.link);
940 wl_list_init(&ivisurf->order.link);
941 }
942
943 wl_list_insert(&ivilayer->order.surface_list,
944 &ivisurf->order.link);
945 add_ordersurface_to_layer(ivisurf, ivilayer);
946 ivisurf->event_mask |= IVI_NOTIFICATION_ADD;
947 }
948 }
949 }
950}
951
952static void
953commit_screen_list(struct ivi_layout *layout)
954{
955 struct ivi_layout_screen *iviscrn = NULL;
956 struct ivi_layout_layer *ivilayer = NULL;
957 struct ivi_layout_layer *next = NULL;
958 struct ivi_layout_surface *ivisurf = NULL;
959
960 wl_list_for_each(iviscrn, &layout->screen_list, link) {
961 if (iviscrn->event_mask & IVI_NOTIFICATION_REMOVE) {
962 wl_list_for_each_safe(ivilayer, next,
963 &iviscrn->order.layer_list, order.link) {
964 remove_orderlayer_from_screen(ivilayer);
965
966 if (!wl_list_empty(&ivilayer->order.link)) {
967 wl_list_remove(&ivilayer->order.link);
968 }
969
970 wl_list_init(&ivilayer->order.link);
971 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
972 }
973 }
974
975 if (iviscrn->event_mask & IVI_NOTIFICATION_ADD) {
976 wl_list_for_each_safe(ivilayer, next,
977 &iviscrn->order.layer_list, order.link) {
978 remove_orderlayer_from_screen(ivilayer);
979
980 if (!wl_list_empty(&ivilayer->order.link)) {
981 wl_list_remove(&ivilayer->order.link);
982 }
983
984 wl_list_init(&ivilayer->order.link);
985 }
986
987 wl_list_init(&iviscrn->order.layer_list);
988 wl_list_for_each(ivilayer, &iviscrn->pending.layer_list,
989 pending.link) {
990 wl_list_insert(&iviscrn->order.layer_list,
991 &ivilayer->order.link);
992 add_orderlayer_to_screen(ivilayer, iviscrn);
993 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
994 }
995 }
996
997 iviscrn->event_mask = 0;
998
999 /* Clear view list of layout ivi_layer */
1000 wl_list_init(&layout->layout_layer.view_list.link);
1001
1002 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
1003 if (ivilayer->prop.visibility == false)
1004 continue;
1005
1006 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
1007 struct weston_view *tmpview = NULL;
1008 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
1009 if (tmpview != NULL) {
1010 break;
1011 }
1012 }
1013
1014 if (ivisurf->prop.visibility == false)
1015 continue;
1016 if (ivisurf->surface == NULL || tmpview == NULL)
1017 continue;
1018
1019 weston_layer_entry_insert(&layout->layout_layer.view_list,
1020 &tmpview->layer_link);
1021
1022 ivisurf->surface->output = iviscrn->output;
1023 }
1024 }
1025
1026 break;
1027 }
1028}
1029
1030static void
1031commit_transition(struct ivi_layout* layout)
1032{
1033 if(wl_list_empty(&layout->pending_transition_list)){
1034 return;
1035 }
1036
1037 wl_list_insert_list(&layout->transitions->transition_list,
1038 &layout->pending_transition_list);
1039
1040 wl_list_init(&layout->pending_transition_list);
1041
1042 wl_event_source_timer_update(layout->transitions->event_source, 1);
1043}
1044
1045static void
1046send_surface_prop(struct ivi_layout_surface *ivisurf)
1047{
1048 wl_signal_emit(&ivisurf->property_changed, ivisurf);
1049 ivisurf->event_mask = 0;
1050}
1051
1052static void
1053send_layer_prop(struct ivi_layout_layer *ivilayer)
1054{
1055 wl_signal_emit(&ivilayer->property_changed, ivilayer);
1056 ivilayer->event_mask = 0;
1057}
1058
1059static void
1060send_prop(struct ivi_layout *layout)
1061{
1062 struct ivi_layout_layer *ivilayer = NULL;
1063 struct ivi_layout_surface *ivisurf = NULL;
1064
1065 wl_list_for_each_reverse(ivilayer, &layout->layer_list, link) {
1066 send_layer_prop(ivilayer);
1067 }
1068
1069 wl_list_for_each_reverse(ivisurf, &layout->surface_list, link) {
1070 send_surface_prop(ivisurf);
1071 }
1072}
1073
1074static void
1075clear_surface_pending_list(struct ivi_layout_layer *ivilayer)
1076{
1077 struct ivi_layout_surface *surface_link = NULL;
1078 struct ivi_layout_surface *surface_next = NULL;
1079
1080 wl_list_for_each_safe(surface_link, surface_next,
1081 &ivilayer->pending.surface_list, pending.link) {
1082 if (!wl_list_empty(&surface_link->pending.link)) {
1083 wl_list_remove(&surface_link->pending.link);
1084 }
1085
1086 wl_list_init(&surface_link->pending.link);
1087 }
1088
1089 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
1090}
1091
1092static void
1093clear_surface_order_list(struct ivi_layout_layer *ivilayer)
1094{
1095 struct ivi_layout_surface *surface_link = NULL;
1096 struct ivi_layout_surface *surface_next = NULL;
1097
1098 wl_list_for_each_safe(surface_link, surface_next,
1099 &ivilayer->order.surface_list, order.link) {
1100 if (!wl_list_empty(&surface_link->order.link)) {
1101 wl_list_remove(&surface_link->order.link);
1102 }
1103
1104 wl_list_init(&surface_link->order.link);
1105 }
1106
1107 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
1108}
1109
1110static void
1111layer_created(struct wl_listener *listener, void *data)
1112{
1113 struct ivi_layout_layer *ivilayer = data;
1114
1115 struct listener_layout_notification *notification =
1116 container_of(listener,
1117 struct listener_layout_notification,
1118 listener);
1119
1120 struct ivi_layout_notification_callback *created_callback =
1121 notification->userdata;
1122
1123 ((layer_create_notification_func)created_callback->callback)
1124 (ivilayer, created_callback->data);
1125}
1126
1127static void
1128layer_removed(struct wl_listener *listener, void *data)
1129{
1130 struct ivi_layout_layer *ivilayer = data;
1131
1132 struct listener_layout_notification *notification =
1133 container_of(listener,
1134 struct listener_layout_notification,
1135 listener);
1136
1137 struct ivi_layout_notification_callback *removed_callback =
1138 notification->userdata;
1139
1140 ((layer_remove_notification_func)removed_callback->callback)
1141 (ivilayer, removed_callback->data);
1142}
1143
1144static void
1145layer_prop_changed(struct wl_listener *listener, void *data)
1146{
1147 struct ivi_layout_layer *ivilayer = data;
1148
1149 struct listener_layout_notification *layout_listener =
1150 container_of(listener,
1151 struct listener_layout_notification,
1152 listener);
1153
1154 struct ivi_layout_notification_callback *prop_callback =
1155 layout_listener->userdata;
1156
1157 ((layer_property_notification_func)prop_callback->callback)
1158 (ivilayer, &ivilayer->prop, ivilayer->event_mask, prop_callback->data);
1159}
1160
1161static void
1162surface_created(struct wl_listener *listener, void *data)
1163{
1164 struct ivi_layout_surface *ivisurface = data;
1165
1166 struct listener_layout_notification *notification =
1167 container_of(listener,
1168 struct listener_layout_notification,
1169 listener);
1170
1171 struct ivi_layout_notification_callback *created_callback =
1172 notification->userdata;
1173
1174 ((surface_create_notification_func)created_callback->callback)
1175 (ivisurface, created_callback->data);
1176}
1177
1178static void
1179surface_removed(struct wl_listener *listener, void *data)
1180{
1181 struct ivi_layout_surface *ivisurface = data;
1182
1183 struct listener_layout_notification *notification =
1184 container_of(listener,
1185 struct listener_layout_notification,
1186 listener);
1187
1188 struct ivi_layout_notification_callback *removed_callback =
1189 notification->userdata;
1190
1191 ((surface_remove_notification_func)removed_callback->callback)
1192 (ivisurface, removed_callback->data);
1193}
1194
1195static void
1196surface_prop_changed(struct wl_listener *listener, void *data)
1197{
1198 struct ivi_layout_surface *ivisurf = data;
1199
1200 struct listener_layout_notification *layout_listener =
1201 container_of(listener,
1202 struct listener_layout_notification,
1203 listener);
1204
1205 struct ivi_layout_notification_callback *prop_callback =
1206 layout_listener->userdata;
1207
1208 ((surface_property_notification_func)prop_callback->callback)
1209 (ivisurf, &ivisurf->prop, ivisurf->event_mask, prop_callback->data);
1210
1211 ivisurf->event_mask = 0;
1212}
1213
1214static void
1215surface_configure_changed(struct wl_listener *listener,
1216 void *data)
1217{
1218 struct ivi_layout_surface *ivisurface = data;
1219
1220 struct listener_layout_notification *notification =
1221 container_of(listener,
1222 struct listener_layout_notification,
1223 listener);
1224
1225 struct ivi_layout_notification_callback *configure_changed_callback =
1226 notification->userdata;
1227
1228 ((surface_configure_notification_func)configure_changed_callback->callback)
1229 (ivisurface, configure_changed_callback->data);
1230}
1231
1232static int32_t
1233add_notification(struct wl_signal *signal,
1234 wl_notify_func_t callback,
1235 void *userdata)
1236{
1237 struct listener_layout_notification *notification = NULL;
1238
1239 notification = malloc(sizeof *notification);
1240 if (notification == NULL) {
1241 weston_log("fails to allocate memory\n");
1242 free(userdata);
1243 return IVI_FAILED;
1244 }
1245
1246 notification->listener.notify = callback;
1247 notification->userdata = userdata;
1248
1249 wl_signal_add(signal, &notification->listener);
1250
1251 return IVI_SUCCEEDED;
1252}
1253
1254static void
1255remove_notification(struct wl_list *listener_list, void *callback, void *userdata)
1256{
1257 struct wl_listener *listener = NULL;
1258 struct wl_listener *next = NULL;
1259
1260 wl_list_for_each_safe(listener, next, listener_list, link) {
1261 struct listener_layout_notification *notification =
1262 container_of(listener,
1263 struct listener_layout_notification,
1264 listener);
1265
1266 struct ivi_layout_notification_callback *notification_callback =
1267 notification->userdata;
1268
1269 if ((notification_callback->callback != callback) ||
1270 (notification_callback->data != userdata)) {
1271 continue;
1272 }
1273
1274 if (!wl_list_empty(&listener->link)) {
1275 wl_list_remove(&listener->link);
1276 }
1277
1278 free(notification->userdata);
1279 free(notification);
1280 }
1281}
1282
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001283/**
1284 * Exported APIs of ivi-layout library are implemented from here.
1285 * Brief of APIs is described in ivi-layout-export.h.
1286 */
1287WL_EXPORT int32_t
1288ivi_layout_add_notification_create_layer(layer_create_notification_func callback,
1289 void *userdata)
1290{
1291 struct ivi_layout *layout = get_instance();
1292 struct ivi_layout_notification_callback *created_callback = NULL;
1293
1294 if (callback == NULL) {
1295 weston_log("ivi_layout_add_notification_create_layer: invalid argument\n");
1296 return IVI_FAILED;
1297 }
1298
1299 created_callback = malloc(sizeof *created_callback);
1300 if (created_callback == NULL) {
1301 weston_log("fails to allocate memory\n");
1302 return IVI_FAILED;
1303 }
1304
1305 created_callback->callback = callback;
1306 created_callback->data = userdata;
1307
1308 return add_notification(&layout->layer_notification.created,
1309 layer_created,
1310 created_callback);
1311}
1312
1313WL_EXPORT void
1314ivi_layout_remove_notification_create_layer(layer_create_notification_func callback,
1315 void *userdata)
1316{
1317 struct ivi_layout *layout = get_instance();
1318 remove_notification(&layout->layer_notification.created.listener_list, callback, userdata);
1319}
1320
1321WL_EXPORT int32_t
1322ivi_layout_add_notification_remove_layer(layer_remove_notification_func callback,
1323 void *userdata)
1324{
1325 struct ivi_layout *layout = get_instance();
1326 struct ivi_layout_notification_callback *removed_callback = NULL;
1327
1328 if (callback == NULL) {
1329 weston_log("ivi_layout_add_notification_remove_layer: invalid argument\n");
1330 return IVI_FAILED;
1331 }
1332
1333 removed_callback = malloc(sizeof *removed_callback);
1334 if (removed_callback == NULL) {
1335 weston_log("fails to allocate memory\n");
1336 return IVI_FAILED;
1337 }
1338
1339 removed_callback->callback = callback;
1340 removed_callback->data = userdata;
1341 return add_notification(&layout->layer_notification.removed,
1342 layer_removed,
1343 removed_callback);
1344}
1345
1346WL_EXPORT void
1347ivi_layout_remove_notification_remove_layer(layer_remove_notification_func callback,
1348 void *userdata)
1349{
1350 struct ivi_layout *layout = get_instance();
1351 remove_notification(&layout->layer_notification.removed.listener_list, callback, userdata);
1352}
1353
1354WL_EXPORT int32_t
1355ivi_layout_add_notification_create_surface(surface_create_notification_func callback,
1356 void *userdata)
1357{
1358 struct ivi_layout *layout = get_instance();
1359 struct ivi_layout_notification_callback *created_callback = NULL;
1360
1361 if (callback == NULL) {
1362 weston_log("ivi_layout_add_notification_create_surface: invalid argument\n");
1363 return IVI_FAILED;
1364 }
1365
1366 created_callback = malloc(sizeof *created_callback);
1367 if (created_callback == NULL) {
1368 weston_log("fails to allocate memory\n");
1369 return IVI_FAILED;
1370 }
1371
1372 created_callback->callback = callback;
1373 created_callback->data = userdata;
1374
1375 return add_notification(&layout->surface_notification.created,
1376 surface_created,
1377 created_callback);
1378}
1379
1380WL_EXPORT void
1381ivi_layout_remove_notification_create_surface(surface_create_notification_func callback,
1382 void *userdata)
1383{
1384 struct ivi_layout *layout = get_instance();
1385 remove_notification(&layout->surface_notification.created.listener_list, callback, userdata);
1386}
1387
1388WL_EXPORT int32_t
1389ivi_layout_add_notification_remove_surface(surface_remove_notification_func callback,
1390 void *userdata)
1391{
1392 struct ivi_layout *layout = get_instance();
1393 struct ivi_layout_notification_callback *removed_callback = NULL;
1394
1395 if (callback == NULL) {
1396 weston_log("ivi_layout_add_notification_remove_surface: invalid argument\n");
1397 return IVI_FAILED;
1398 }
1399
1400 removed_callback = malloc(sizeof *removed_callback);
1401 if (removed_callback == NULL) {
1402 weston_log("fails to allocate memory\n");
1403 return IVI_FAILED;
1404 }
1405
1406 removed_callback->callback = callback;
1407 removed_callback->data = userdata;
1408
1409 return add_notification(&layout->surface_notification.removed,
1410 surface_removed,
1411 removed_callback);
1412}
1413
1414WL_EXPORT void
1415ivi_layout_remove_notification_remove_surface(surface_remove_notification_func callback,
1416 void *userdata)
1417{
1418 struct ivi_layout *layout = get_instance();
1419 remove_notification(&layout->surface_notification.removed.listener_list, callback, userdata);
1420}
1421
1422WL_EXPORT int32_t
1423ivi_layout_add_notification_configure_surface(surface_configure_notification_func callback,
1424 void *userdata)
1425{
1426 struct ivi_layout *layout = get_instance();
1427 struct ivi_layout_notification_callback *configure_changed_callback = NULL;
1428 if (callback == NULL) {
1429 weston_log("ivi_layout_add_notification_configure_surface: invalid argument\n");
1430 return IVI_FAILED;
1431 }
1432
1433 configure_changed_callback = malloc(sizeof *configure_changed_callback);
1434 if (configure_changed_callback == NULL) {
1435 weston_log("fails to allocate memory\n");
1436 return IVI_FAILED;
1437 }
1438
1439 configure_changed_callback->callback = callback;
1440 configure_changed_callback->data = userdata;
1441
1442 return add_notification(&layout->surface_notification.configure_changed,
1443 surface_configure_changed,
1444 configure_changed_callback);
1445}
1446
1447WL_EXPORT void
1448ivi_layout_remove_notification_configure_surface(surface_configure_notification_func callback,
1449 void *userdata)
1450{
1451 struct ivi_layout *layout = get_instance();
1452 remove_notification(&layout->surface_notification.configure_changed.listener_list, callback, userdata);
1453}
1454
1455WL_EXPORT uint32_t
1456ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf)
1457{
1458 return ivisurf->id_surface;
1459}
1460
1461WL_EXPORT uint32_t
1462ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer)
1463{
1464 return ivilayer->id_layer;
1465}
1466
1467struct ivi_layout_layer *
1468ivi_layout_get_layer_from_id(uint32_t id_layer)
1469{
1470 struct ivi_layout *layout = get_instance();
1471 struct ivi_layout_layer *ivilayer = NULL;
1472
1473 wl_list_for_each(ivilayer, &layout->layer_list, link) {
1474 if (ivilayer->id_layer == id_layer) {
1475 return ivilayer;
1476 }
1477 }
1478
1479 return NULL;
1480}
1481
1482WL_EXPORT struct ivi_layout_surface *
1483ivi_layout_get_surface_from_id(uint32_t id_surface)
1484{
1485 struct ivi_layout *layout = get_instance();
1486 struct ivi_layout_surface *ivisurf = NULL;
1487
1488 wl_list_for_each(ivisurf, &layout->surface_list, link) {
1489 if (ivisurf->id_surface == id_surface) {
1490 return ivisurf;
1491 }
1492 }
1493
1494 return NULL;
1495}
1496
1497WL_EXPORT struct ivi_layout_screen *
1498ivi_layout_get_screen_from_id(uint32_t id_screen)
1499{
1500 struct ivi_layout *layout = get_instance();
1501 struct ivi_layout_screen *iviscrn = NULL;
1502
1503 wl_list_for_each(iviscrn, &layout->screen_list, link) {
1504/* FIXME : select iviscrn from screen_list by id_screen */
1505 return iviscrn;
1506 break;
1507 }
1508
1509 return NULL;
1510}
1511
1512WL_EXPORT int32_t
1513ivi_layout_get_screen_resolution(struct ivi_layout_screen *iviscrn,
1514 int32_t *pWidth, int32_t *pHeight)
1515{
1516 struct weston_output *output = NULL;
1517
1518 if (pWidth == NULL || pHeight == NULL) {
1519 weston_log("ivi_layout_get_screen_resolution: invalid argument\n");
1520 return IVI_FAILED;
1521 }
1522
1523 output = iviscrn->output;
1524 *pWidth = output->current_mode->width;
1525 *pHeight = output->current_mode->height;
1526
1527 return IVI_SUCCEEDED;
1528}
1529
1530WL_EXPORT int32_t
1531ivi_layout_surface_add_notification(struct ivi_layout_surface *ivisurf,
1532 surface_property_notification_func callback,
1533 void *userdata)
1534{
1535 struct listener_layout_notification* notification = NULL;
1536 struct ivi_layout_notification_callback *prop_callback = NULL;
1537
1538 if (ivisurf == NULL || callback == NULL) {
1539 weston_log("ivi_layout_surface_add_notification: invalid argument\n");
1540 return IVI_FAILED;
1541 }
1542
1543 notification = malloc(sizeof *notification);
1544 if (notification == NULL) {
1545 weston_log("fails to allocate memory\n");
1546 return IVI_FAILED;
1547 }
1548
1549 prop_callback = malloc(sizeof *prop_callback);
1550 if (prop_callback == NULL) {
1551 weston_log("fails to allocate memory\n");
1552 return IVI_FAILED;
1553 }
1554
1555 prop_callback->callback = callback;
1556 prop_callback->data = userdata;
1557
1558 notification->listener.notify = surface_prop_changed;
1559 notification->userdata = prop_callback;
1560
1561 wl_signal_add(&ivisurf->property_changed, &notification->listener);
1562
1563 return IVI_SUCCEEDED;
1564}
1565
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001566WL_EXPORT const struct ivi_layout_layer_properties *
1567ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer)
1568{
1569 if (ivilayer == NULL) {
1570 weston_log("ivi_layout_get_properties_of_layer: invalid argument\n");
1571 return NULL;
1572 }
1573
1574 return &ivilayer->prop;
1575}
1576
1577WL_EXPORT int32_t
1578ivi_layout_get_screens(int32_t *pLength, struct ivi_layout_screen ***ppArray)
1579{
1580 struct ivi_layout *layout = get_instance();
1581 struct ivi_layout_screen *iviscrn = NULL;
1582 int32_t length = 0;
1583 int32_t n = 0;
1584
1585 if (pLength == NULL || ppArray == NULL) {
1586 weston_log("ivi_layout_get_screens: invalid argument\n");
1587 return IVI_FAILED;
1588 }
1589
1590 length = wl_list_length(&layout->screen_list);
1591
1592 if (length != 0){
1593 /* the Array must be free by module which called this function */
1594 *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
1595 if (*ppArray == NULL) {
1596 weston_log("fails to allocate memory\n");
1597 return IVI_FAILED;
1598 }
1599
1600 wl_list_for_each(iviscrn, &layout->screen_list, link) {
1601 (*ppArray)[n++] = iviscrn;
1602 }
1603 }
1604
1605 *pLength = length;
1606
1607 return IVI_SUCCEEDED;
1608}
1609
1610WL_EXPORT int32_t
1611ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer,
1612 int32_t *pLength,
1613 struct ivi_layout_screen ***ppArray)
1614{
1615 struct link_screen *link_scrn = NULL;
1616 int32_t length = 0;
1617 int32_t n = 0;
1618
1619 if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1620 weston_log("ivi_layout_get_screens_under_layer: invalid argument\n");
1621 return IVI_FAILED;
1622 }
1623
1624 length = wl_list_length(&ivilayer->screen_list);
1625
1626 if (length != 0){
1627 /* the Array must be free by module which called this function */
1628 *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
1629 if (*ppArray == NULL) {
1630 weston_log("fails to allocate memory\n");
1631 return IVI_FAILED;
1632 }
1633
1634 wl_list_for_each(link_scrn, &ivilayer->screen_list, link) {
1635 (*ppArray)[n++] = link_scrn->iviscrn;
1636 }
1637 }
1638
1639 *pLength = length;
1640
1641 return IVI_SUCCEEDED;
1642}
1643
1644WL_EXPORT int32_t
1645ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray)
1646{
1647 struct ivi_layout *layout = get_instance();
1648 struct ivi_layout_layer *ivilayer = NULL;
1649 int32_t length = 0;
1650 int32_t n = 0;
1651
1652 if (pLength == NULL || ppArray == NULL) {
1653 weston_log("ivi_layout_get_layers: invalid argument\n");
1654 return IVI_FAILED;
1655 }
1656
1657 length = wl_list_length(&layout->layer_list);
1658
1659 if (length != 0){
1660 /* the Array must be free by module which called this function */
1661 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1662 if (*ppArray == NULL) {
1663 weston_log("fails to allocate memory\n");
1664 return IVI_FAILED;
1665 }
1666
1667 wl_list_for_each(ivilayer, &layout->layer_list, link) {
1668 (*ppArray)[n++] = ivilayer;
1669 }
1670 }
1671
1672 *pLength = length;
1673
1674 return IVI_SUCCEEDED;
1675}
1676
1677int32_t
1678ivi_layout_get_layers_on_screen(struct ivi_layout_screen *iviscrn,
1679 int32_t *pLength,
1680 struct ivi_layout_layer ***ppArray)
1681{
1682 struct ivi_layout_layer *ivilayer = NULL;
1683 int32_t length = 0;
1684 int32_t n = 0;
1685
1686 if (iviscrn == NULL || pLength == NULL || ppArray == NULL) {
1687 weston_log("ivi_layout_get_layers_on_screen: invalid argument\n");
1688 return IVI_FAILED;
1689 }
1690
1691 length = wl_list_length(&iviscrn->order.layer_list);
1692
1693 if (length != 0){
1694 /* the Array must be free by module which called this function */
1695 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1696 if (*ppArray == NULL) {
1697 weston_log("fails to allocate memory\n");
1698 return IVI_FAILED;
1699 }
1700
1701 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, link) {
1702 (*ppArray)[n++] = ivilayer;
1703 }
1704 }
1705
1706 *pLength = length;
1707
1708 return IVI_SUCCEEDED;
1709}
1710
1711WL_EXPORT int32_t
1712ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf,
1713 int32_t *pLength,
1714 struct ivi_layout_layer ***ppArray)
1715{
1716 struct link_layer *link_layer = NULL;
1717 int32_t length = 0;
1718 int32_t n = 0;
1719
1720 if (ivisurf == NULL || pLength == NULL || ppArray == NULL) {
1721 weston_log("ivi_layout_getLayers: invalid argument\n");
1722 return IVI_FAILED;
1723 }
1724
1725 length = wl_list_length(&ivisurf->layer_list);
1726
1727 if (length != 0){
1728 /* the Array must be free by module which called this function */
1729 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1730 if (*ppArray == NULL) {
1731 weston_log("fails to allocate memory\n");
1732 return IVI_FAILED;
1733 }
1734
1735 wl_list_for_each(link_layer, &ivisurf->layer_list, link) {
1736 (*ppArray)[n++] = link_layer->ivilayer;
1737 }
1738 }
1739
1740 *pLength = length;
1741
1742 return IVI_SUCCEEDED;
1743}
1744
1745WL_EXPORT int32_t
1746ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray)
1747{
1748 struct ivi_layout *layout = get_instance();
1749 struct ivi_layout_surface *ivisurf = NULL;
1750 int32_t length = 0;
1751 int32_t n = 0;
1752
1753 if (pLength == NULL || ppArray == NULL) {
1754 weston_log("ivi_layout_get_surfaces: invalid argument\n");
1755 return IVI_FAILED;
1756 }
1757
1758 length = wl_list_length(&layout->surface_list);
1759
1760 if (length != 0){
1761 /* the Array must be free by module which called this function */
1762 *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1763 if (*ppArray == NULL) {
1764 weston_log("fails to allocate memory\n");
1765 return IVI_FAILED;
1766 }
1767
1768 wl_list_for_each(ivisurf, &layout->surface_list, link) {
1769 (*ppArray)[n++] = ivisurf;
1770 }
1771 }
1772
1773 *pLength = length;
1774
1775 return IVI_SUCCEEDED;
1776}
1777
1778int32_t
1779ivi_layout_get_surfaces_on_layer(struct ivi_layout_layer *ivilayer,
1780 int32_t *pLength,
1781 struct ivi_layout_surface ***ppArray)
1782{
1783 struct ivi_layout_surface *ivisurf = NULL;
1784 int32_t length = 0;
1785 int32_t n = 0;
1786
1787 if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1788 weston_log("ivi_layout_getSurfaceIDsOnLayer: invalid argument\n");
1789 return IVI_FAILED;
1790 }
1791
1792 length = wl_list_length(&ivilayer->order.surface_list);
1793
1794 if (length != 0) {
1795 /* the Array must be free by module which called this function */
1796 *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1797 if (*ppArray == NULL) {
1798 weston_log("fails to allocate memory\n");
1799 return IVI_FAILED;
1800 }
1801
1802 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
1803 (*ppArray)[n++] = ivisurf;
1804 }
1805 }
1806
1807 *pLength = length;
1808
1809 return IVI_SUCCEEDED;
1810}
1811
1812WL_EXPORT struct ivi_layout_layer *
1813ivi_layout_layer_create_with_dimension(uint32_t id_layer,
1814 int32_t width, int32_t height)
1815{
1816 struct ivi_layout *layout = get_instance();
1817 struct ivi_layout_layer *ivilayer = NULL;
1818
1819 ivilayer = get_layer(&layout->layer_list, id_layer);
1820 if (ivilayer != NULL) {
1821 weston_log("id_layer is already created\n");
1822 return ivilayer;
1823 }
1824
1825 ivilayer = calloc(1, sizeof *ivilayer);
1826 if (ivilayer == NULL) {
1827 weston_log("fails to allocate memory\n");
1828 return NULL;
1829 }
1830
1831 wl_list_init(&ivilayer->link);
1832 wl_signal_init(&ivilayer->property_changed);
1833 wl_list_init(&ivilayer->screen_list);
1834 wl_list_init(&ivilayer->link_to_surface);
1835 ivilayer->layout = layout;
1836 ivilayer->id_layer = id_layer;
1837
1838 init_layer_properties(&ivilayer->prop, width, height);
1839 ivilayer->event_mask = 0;
1840
1841 wl_list_init(&ivilayer->pending.surface_list);
1842 wl_list_init(&ivilayer->pending.link);
1843 ivilayer->pending.prop = ivilayer->prop;
1844
1845 wl_list_init(&ivilayer->order.surface_list);
1846 wl_list_init(&ivilayer->order.link);
1847
1848 wl_list_insert(&layout->layer_list, &ivilayer->link);
1849
1850 wl_signal_emit(&layout->layer_notification.created, ivilayer);
1851
1852 return ivilayer;
1853}
1854
1855WL_EXPORT void
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +09001856ivi_layout_layer_remove_notification(struct ivi_layout_layer *ivilayer)
1857{
1858 if (ivilayer == NULL) {
1859 weston_log("ivi_layout_layer_remove_notification: invalid argument\n");
1860 return;
1861 }
1862
1863 remove_all_notification(&ivilayer->property_changed.listener_list);
1864}
1865
1866WL_EXPORT void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001867ivi_layout_layer_remove(struct ivi_layout_layer *ivilayer)
1868{
1869 struct ivi_layout *layout = get_instance();
1870
1871 if (ivilayer == NULL) {
1872 weston_log("ivi_layout_layer_remove: invalid argument\n");
1873 return;
1874 }
1875
1876 wl_signal_emit(&layout->layer_notification.removed, ivilayer);
1877
1878 clear_surface_pending_list(ivilayer);
1879 clear_surface_order_list(ivilayer);
1880
1881 if (!wl_list_empty(&ivilayer->pending.link)) {
1882 wl_list_remove(&ivilayer->pending.link);
1883 }
1884 if (!wl_list_empty(&ivilayer->order.link)) {
1885 wl_list_remove(&ivilayer->order.link);
1886 }
1887 if (!wl_list_empty(&ivilayer->link)) {
1888 wl_list_remove(&ivilayer->link);
1889 }
1890 remove_orderlayer_from_screen(ivilayer);
1891 remove_link_to_surface(ivilayer);
1892 ivi_layout_layer_remove_notification(ivilayer);
1893
1894 free(ivilayer);
1895}
1896
1897WL_EXPORT int32_t
1898ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer,
1899 bool newVisibility)
1900{
1901 struct ivi_layout_layer_properties *prop = NULL;
1902
1903 if (ivilayer == NULL) {
1904 weston_log("ivi_layout_layer_set_visibility: invalid argument\n");
1905 return IVI_FAILED;
1906 }
1907
1908 prop = &ivilayer->pending.prop;
1909 prop->visibility = newVisibility;
1910
1911 ivilayer->event_mask |= IVI_NOTIFICATION_VISIBILITY;
1912
1913 return IVI_SUCCEEDED;
1914}
1915
1916bool
1917ivi_layout_layer_get_visibility(struct ivi_layout_layer *ivilayer)
1918{
1919 if (ivilayer == NULL) {
1920 weston_log("ivi_layout_layer_get_visibility: invalid argument\n");
1921 return false;
1922 }
1923
1924 return ivilayer->prop.visibility;
1925}
1926
1927WL_EXPORT int32_t
1928ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
1929 wl_fixed_t opacity)
1930{
1931 struct ivi_layout_layer_properties *prop = NULL;
1932
1933 if (ivilayer == NULL) {
1934 weston_log("ivi_layout_layer_set_opacity: invalid argument\n");
1935 return IVI_FAILED;
1936 }
1937
1938 prop = &ivilayer->pending.prop;
1939 prop->opacity = opacity;
1940
1941 ivilayer->event_mask |= IVI_NOTIFICATION_OPACITY;
1942
1943 return IVI_SUCCEEDED;
1944}
1945
1946WL_EXPORT wl_fixed_t
1947ivi_layout_layer_get_opacity(struct ivi_layout_layer *ivilayer)
1948{
1949 if (ivilayer == NULL) {
1950 weston_log("ivi_layout_layer_get_opacity: invalid argument\n");
1951 return wl_fixed_from_double(0.0);
1952 }
1953
1954 return ivilayer->prop.opacity;
1955}
1956
1957WL_EXPORT int32_t
1958ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer,
1959 int32_t x, int32_t y,
1960 int32_t width, int32_t height)
1961{
1962 struct ivi_layout_layer_properties *prop = NULL;
1963
1964 if (ivilayer == NULL) {
1965 weston_log("ivi_layout_layer_set_source_rectangle: invalid argument\n");
1966 return IVI_FAILED;
1967 }
1968
1969 prop = &ivilayer->pending.prop;
1970 prop->source_x = x;
1971 prop->source_y = y;
1972 prop->source_width = width;
1973 prop->source_height = height;
1974
1975 ivilayer->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
1976
1977 return IVI_SUCCEEDED;
1978}
1979
1980WL_EXPORT int32_t
1981ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer,
1982 int32_t x, int32_t y,
1983 int32_t width, int32_t height)
1984{
1985 struct ivi_layout_layer_properties *prop = NULL;
1986
1987 if (ivilayer == NULL) {
1988 weston_log("ivi_layout_layer_set_destination_rectangle: invalid argument\n");
1989 return IVI_FAILED;
1990 }
1991
1992 prop = &ivilayer->pending.prop;
1993 prop->dest_x = x;
1994 prop->dest_y = y;
1995 prop->dest_width = width;
1996 prop->dest_height = height;
1997
1998 ivilayer->event_mask |= IVI_NOTIFICATION_DEST_RECT;
1999
2000 return IVI_SUCCEEDED;
2001}
2002
2003int32_t
2004ivi_layout_layer_get_dimension(struct ivi_layout_layer *ivilayer,
2005 int32_t *dest_width, int32_t *dest_height)
2006{
2007 if (ivilayer == NULL || dest_width == NULL || dest_height == NULL) {
2008 weston_log("ivi_layout_layer_get_dimension: invalid argument\n");
2009 return IVI_FAILED;
2010 }
2011
2012 *dest_width = ivilayer->prop.dest_width;
2013 *dest_height = ivilayer->prop.dest_height;
2014
2015 return IVI_SUCCEEDED;
2016}
2017
2018int32_t
2019ivi_layout_layer_set_dimension(struct ivi_layout_layer *ivilayer,
2020 int32_t dest_width, int32_t dest_height)
2021{
2022 struct ivi_layout_layer_properties *prop = NULL;
2023
2024 if (ivilayer == NULL) {
2025 weston_log("ivi_layout_layer_set_dimension: invalid argument\n");
2026 return IVI_FAILED;
2027 }
2028
2029 prop = &ivilayer->pending.prop;
2030
2031 prop->dest_width = dest_width;
2032 prop->dest_height = dest_height;
2033
2034 ivilayer->event_mask |= IVI_NOTIFICATION_DIMENSION;
2035
2036 return IVI_SUCCEEDED;
2037}
2038
2039WL_EXPORT int32_t
2040ivi_layout_layer_get_position(struct ivi_layout_layer *ivilayer,
2041 int32_t *dest_x, int32_t *dest_y)
2042{
2043 if (ivilayer == NULL || dest_x == NULL || dest_y == NULL) {
2044 weston_log("ivi_layout_layer_get_position: invalid argument\n");
2045 return IVI_FAILED;
2046 }
2047
2048 *dest_x = ivilayer->prop.dest_x;
2049 *dest_y = ivilayer->prop.dest_y;
2050
2051 return IVI_SUCCEEDED;
2052}
2053
2054WL_EXPORT int32_t
2055ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer,
2056 int32_t dest_x, int32_t dest_y)
2057{
2058 struct ivi_layout_layer_properties *prop = NULL;
2059
2060 if (ivilayer == NULL) {
2061 weston_log("ivi_layout_layer_set_position: invalid argument\n");
2062 return IVI_FAILED;
2063 }
2064
2065 prop = &ivilayer->pending.prop;
2066 prop->dest_x = dest_x;
2067 prop->dest_y = dest_y;
2068
2069 ivilayer->event_mask |= IVI_NOTIFICATION_POSITION;
2070
2071 return IVI_SUCCEEDED;
2072}
2073
2074WL_EXPORT int32_t
2075ivi_layout_layer_set_orientation(struct ivi_layout_layer *ivilayer,
2076 enum wl_output_transform orientation)
2077{
2078 struct ivi_layout_layer_properties *prop = NULL;
2079
2080 if (ivilayer == NULL) {
2081 weston_log("ivi_layout_layer_set_orientation: invalid argument\n");
2082 return IVI_FAILED;
2083 }
2084
2085 prop = &ivilayer->pending.prop;
2086 prop->orientation = orientation;
2087
2088 ivilayer->event_mask |= IVI_NOTIFICATION_ORIENTATION;
2089
2090 return IVI_SUCCEEDED;
2091}
2092
2093enum wl_output_transform
2094ivi_layout_layer_get_orientation(struct ivi_layout_layer *ivilayer)
2095{
2096 if (ivilayer == NULL) {
2097 weston_log("ivi_layout_layer_get_orientation: invalid argument\n");
2098 return 0;
2099 }
2100
2101 return ivilayer->prop.orientation;
2102}
2103
2104WL_EXPORT int32_t
2105ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
2106 struct ivi_layout_surface **pSurface,
2107 int32_t number)
2108{
2109 struct ivi_layout *layout = get_instance();
2110 struct ivi_layout_surface *ivisurf = NULL;
2111 struct ivi_layout_surface *next = NULL;
2112 uint32_t *id_surface = NULL;
2113 int32_t i = 0;
2114
2115 if (ivilayer == NULL) {
2116 weston_log("ivi_layout_layer_set_render_order: invalid argument\n");
2117 return IVI_FAILED;
2118 }
2119
2120 if (pSurface == NULL) {
2121 wl_list_for_each_safe(ivisurf, next, &ivilayer->pending.surface_list, pending.link) {
2122 if (!wl_list_empty(&ivisurf->pending.link)) {
2123 wl_list_remove(&ivisurf->pending.link);
2124 }
2125
2126 wl_list_init(&ivisurf->pending.link);
2127 }
2128 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
2129 return IVI_SUCCEEDED;
2130 }
2131
2132 for (i = 0; i < number; i++) {
2133 id_surface = &pSurface[i]->id_surface;
2134
2135 wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
2136 if (*id_surface != ivisurf->id_surface) {
2137 continue;
2138 }
2139
2140 if (!wl_list_empty(&ivisurf->pending.link)) {
2141 wl_list_remove(&ivisurf->pending.link);
2142 }
2143 wl_list_init(&ivisurf->pending.link);
2144 wl_list_insert(&ivilayer->pending.surface_list,
2145 &ivisurf->pending.link);
2146 break;
2147 }
2148 }
2149
2150 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
2151
2152 return IVI_SUCCEEDED;
2153}
2154
2155WL_EXPORT int32_t
2156ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf,
2157 bool newVisibility)
2158{
2159 struct ivi_layout_surface_properties *prop = NULL;
2160
2161 if (ivisurf == NULL) {
2162 weston_log("ivi_layout_surface_set_visibility: invalid argument\n");
2163 return IVI_FAILED;
2164 }
2165
2166 prop = &ivisurf->pending.prop;
2167 prop->visibility = newVisibility;
2168
2169 ivisurf->event_mask |= IVI_NOTIFICATION_VISIBILITY;
2170
2171 return IVI_SUCCEEDED;
2172}
2173
2174WL_EXPORT bool
2175ivi_layout_surface_get_visibility(struct ivi_layout_surface *ivisurf)
2176{
2177 if (ivisurf == NULL) {
2178 weston_log("ivi_layout_surface_get_visibility: invalid argument\n");
2179 return false;
2180 }
2181
2182 return ivisurf->prop.visibility;
2183}
2184
2185WL_EXPORT int32_t
2186ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
2187 wl_fixed_t opacity)
2188{
2189 struct ivi_layout_surface_properties *prop = NULL;
2190
2191 if (ivisurf == NULL) {
2192 weston_log("ivi_layout_surface_set_opacity: invalid argument\n");
2193 return IVI_FAILED;
2194 }
2195
2196 prop = &ivisurf->pending.prop;
2197 prop->opacity = opacity;
2198
2199 ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY;
2200
2201 return IVI_SUCCEEDED;
2202}
2203
2204WL_EXPORT wl_fixed_t
2205ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf)
2206{
2207 if (ivisurf == NULL) {
2208 weston_log("ivi_layout_surface_get_opacity: invalid argument\n");
2209 return wl_fixed_from_double(0.0);
2210 }
2211
2212 return ivisurf->prop.opacity;
2213}
2214
2215WL_EXPORT int32_t
2216ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
2217 int32_t x, int32_t y,
2218 int32_t width, int32_t height)
2219{
2220 struct ivi_layout_surface_properties *prop = NULL;
2221
2222 if (ivisurf == NULL) {
2223 weston_log("ivi_layout_surface_set_destination_rectangle: invalid argument\n");
2224 return IVI_FAILED;
2225 }
2226
2227 prop = &ivisurf->pending.prop;
2228 prop->start_x = prop->dest_x;
2229 prop->start_y = prop->dest_y;
2230 prop->dest_x = x;
2231 prop->dest_y = y;
2232 prop->start_width = prop->dest_width;
2233 prop->start_height = prop->dest_height;
2234 prop->dest_width = width;
2235 prop->dest_height = height;
2236
2237 ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT;
2238
2239 return IVI_SUCCEEDED;
2240}
2241
2242int32_t
2243ivi_layout_surface_set_dimension(struct ivi_layout_surface *ivisurf,
2244 int32_t dest_width, int32_t dest_height)
2245{
2246 struct ivi_layout_surface_properties *prop = NULL;
2247
2248 if (ivisurf == NULL) {
2249 weston_log("ivi_layout_surface_set_dimension: invalid argument\n");
2250 return IVI_FAILED;
2251 }
2252
2253 prop = &ivisurf->pending.prop;
2254 prop->dest_width = dest_width;
2255 prop->dest_height = dest_height;
2256
2257 ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION;
2258
2259 return IVI_SUCCEEDED;
2260}
2261
2262int32_t
2263ivi_layout_surface_get_dimension(struct ivi_layout_surface *ivisurf,
2264 int32_t *dest_width, int32_t *dest_height)
2265{
2266 if (ivisurf == NULL || dest_width == NULL || dest_height == NULL) {
2267 weston_log("ivi_layout_surface_get_dimension: invalid argument\n");
2268 return IVI_FAILED;
2269 }
2270
2271 *dest_width = ivisurf->prop.dest_width;
2272 *dest_height = ivisurf->prop.dest_height;
2273
2274 return IVI_SUCCEEDED;
2275}
2276
2277int32_t
2278ivi_layout_surface_set_position(struct ivi_layout_surface *ivisurf,
2279 int32_t dest_x, int32_t dest_y)
2280{
2281 struct ivi_layout_surface_properties *prop = NULL;
2282
2283 if (ivisurf == NULL) {
2284 weston_log("ivi_layout_surface_set_position: invalid argument\n");
2285 return IVI_FAILED;
2286 }
2287
2288 prop = &ivisurf->pending.prop;
2289 prop->dest_x = dest_x;
2290 prop->dest_y = dest_y;
2291
2292 ivisurf->event_mask |= IVI_NOTIFICATION_POSITION;
2293
2294 return IVI_SUCCEEDED;
2295}
2296
2297int32_t
2298ivi_layout_surface_get_position(struct ivi_layout_surface *ivisurf,
2299 int32_t *dest_x, int32_t *dest_y)
2300{
2301 if (ivisurf == NULL || dest_x == NULL || dest_y == NULL) {
2302 weston_log("ivi_layout_surface_get_position: invalid argument\n");
2303 return IVI_FAILED;
2304 }
2305
2306 *dest_x = ivisurf->prop.dest_x;
2307 *dest_y = ivisurf->prop.dest_y;
2308
2309 return IVI_SUCCEEDED;
2310}
2311
2312WL_EXPORT int32_t
2313ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf,
2314 enum wl_output_transform orientation)
2315{
2316 struct ivi_layout_surface_properties *prop = NULL;
2317
2318 if (ivisurf == NULL) {
2319 weston_log("ivi_layout_surface_set_orientation: invalid argument\n");
2320 return IVI_FAILED;
2321 }
2322
2323 prop = &ivisurf->pending.prop;
2324 prop->orientation = orientation;
2325
2326 ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION;
2327
2328 return IVI_SUCCEEDED;
2329}
2330
2331enum wl_output_transform
2332ivi_layout_surface_get_orientation(struct ivi_layout_surface *ivisurf)
2333{
2334 if (ivisurf == NULL) {
2335 weston_log("ivi_layout_surface_get_orientation: invalid argument\n");
2336 return 0;
2337 }
2338
2339 return ivisurf->prop.orientation;
2340}
2341
2342WL_EXPORT int32_t
2343ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn,
2344 struct ivi_layout_layer *addlayer)
2345{
2346 struct ivi_layout *layout = get_instance();
2347 struct ivi_layout_layer *ivilayer = NULL;
2348 struct ivi_layout_layer *next = NULL;
2349 int is_layer_in_scrn = 0;
2350
2351 if (iviscrn == NULL || addlayer == NULL) {
2352 weston_log("ivi_layout_screen_add_layer: invalid argument\n");
2353 return IVI_FAILED;
2354 }
2355
2356 is_layer_in_scrn = is_layer_in_screen(addlayer, iviscrn);
2357 if (is_layer_in_scrn == 1) {
2358 weston_log("ivi_layout_screen_add_layer: addlayer is already available\n");
2359 return IVI_SUCCEEDED;
2360 }
2361
2362 wl_list_for_each_safe(ivilayer, next, &layout->layer_list, link) {
2363 if (ivilayer->id_layer == addlayer->id_layer) {
2364 if (!wl_list_empty(&ivilayer->pending.link)) {
2365 wl_list_remove(&ivilayer->pending.link);
2366 }
2367 wl_list_init(&ivilayer->pending.link);
2368 wl_list_insert(&iviscrn->pending.layer_list,
2369 &ivilayer->pending.link);
2370 break;
2371 }
2372 }
2373
2374 iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
2375
2376 return IVI_SUCCEEDED;
2377}
2378
2379WL_EXPORT int32_t
2380ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn,
2381 struct ivi_layout_layer **pLayer,
2382 const int32_t number)
2383{
2384 struct ivi_layout *layout = get_instance();
2385 struct ivi_layout_layer *ivilayer = NULL;
2386 struct ivi_layout_layer *next = NULL;
2387 uint32_t *id_layer = NULL;
2388 int32_t i = 0;
2389
2390 if (iviscrn == NULL) {
2391 weston_log("ivi_layout_screen_set_render_order: invalid argument\n");
2392 return IVI_FAILED;
2393 }
2394
2395 wl_list_for_each_safe(ivilayer, next,
2396 &iviscrn->pending.layer_list, pending.link) {
2397 wl_list_init(&ivilayer->pending.link);
2398 }
2399
2400 wl_list_init(&iviscrn->pending.layer_list);
2401
2402 if (pLayer == NULL) {
2403 wl_list_for_each_safe(ivilayer, next, &iviscrn->pending.layer_list, pending.link) {
2404 if (!wl_list_empty(&ivilayer->pending.link)) {
2405 wl_list_remove(&ivilayer->pending.link);
2406 }
2407
2408 wl_list_init(&ivilayer->pending.link);
2409 }
2410
2411 iviscrn->event_mask |= IVI_NOTIFICATION_REMOVE;
2412 return IVI_SUCCEEDED;
2413 }
2414
2415 for (i = 0; i < number; i++) {
2416 id_layer = &pLayer[i]->id_layer;
2417 wl_list_for_each(ivilayer, &layout->layer_list, link) {
2418 if (*id_layer != ivilayer->id_layer) {
2419 continue;
2420 }
2421
2422 if (!wl_list_empty(&ivilayer->pending.link)) {
2423 wl_list_remove(&ivilayer->pending.link);
2424 }
2425 wl_list_init(&ivilayer->pending.link);
2426 wl_list_insert(&iviscrn->pending.layer_list,
2427 &ivilayer->pending.link);
2428 break;
2429 }
2430 }
2431
2432 iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
2433
2434 return IVI_SUCCEEDED;
2435}
2436
2437WL_EXPORT struct weston_output *
2438ivi_layout_screen_get_output(struct ivi_layout_screen *iviscrn)
2439{
2440 return iviscrn->output;
2441}
2442
2443/**
2444 * This function is used by the additional ivi-module because of dumping ivi_surface sceenshot.
2445 * The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of Genivi's Layer Management.
2446 * This function is used to get the result of drawing by clients.
2447 */
2448WL_EXPORT struct weston_surface *
2449ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf)
2450{
2451 return ivisurf != NULL ? ivisurf->surface : NULL;
2452}
2453
2454WL_EXPORT int32_t
2455ivi_layout_layer_add_notification(struct ivi_layout_layer *ivilayer,
2456 layer_property_notification_func callback,
2457 void *userdata)
2458{
2459 struct ivi_layout_notification_callback *prop_callback = NULL;
2460
2461 if (ivilayer == NULL || callback == NULL) {
2462 weston_log("ivi_layout_layer_add_notification: invalid argument\n");
2463 return IVI_FAILED;
2464 }
2465
2466 prop_callback = malloc(sizeof *prop_callback);
2467 if (prop_callback == NULL) {
2468 weston_log("fails to allocate memory\n");
2469 return IVI_FAILED;
2470 }
2471
2472 prop_callback->callback = callback;
2473 prop_callback->data = userdata;
2474
2475 return add_notification(&ivilayer->property_changed,
2476 layer_prop_changed,
2477 prop_callback);
2478}
2479
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002480WL_EXPORT const struct ivi_layout_surface_properties *
2481ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf)
2482{
2483 if (ivisurf == NULL) {
2484 weston_log("ivi_layout_get_properties_of_surface: invalid argument\n");
2485 return NULL;
2486 }
2487
2488 return &ivisurf->prop;
2489}
2490
2491WL_EXPORT int32_t
2492ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer,
2493 struct ivi_layout_surface *addsurf)
2494{
2495 struct ivi_layout *layout = get_instance();
2496 struct ivi_layout_surface *ivisurf = NULL;
2497 struct ivi_layout_surface *next = NULL;
2498 int is_surf_in_layer = 0;
2499
2500 if (ivilayer == NULL || addsurf == NULL) {
2501 weston_log("ivi_layout_layer_add_surface: invalid argument\n");
2502 return IVI_FAILED;
2503 }
2504
2505 is_surf_in_layer = is_surface_in_layer(addsurf, ivilayer);
2506 if (is_surf_in_layer == 1) {
2507 weston_log("ivi_layout_layer_add_surface: addsurf is already available\n");
2508 return IVI_SUCCEEDED;
2509 }
2510
2511 wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
2512 if (ivisurf->id_surface == addsurf->id_surface) {
2513 if (!wl_list_empty(&ivisurf->pending.link)) {
2514 wl_list_remove(&ivisurf->pending.link);
2515 }
2516 wl_list_init(&ivisurf->pending.link);
2517 wl_list_insert(&ivilayer->pending.surface_list,
2518 &ivisurf->pending.link);
2519 break;
2520 }
2521 }
2522
2523 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
2524
2525 return IVI_SUCCEEDED;
2526}
2527
2528WL_EXPORT void
2529ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer,
2530 struct ivi_layout_surface *remsurf)
2531{
2532 struct ivi_layout_surface *ivisurf = NULL;
2533 struct ivi_layout_surface *next = NULL;
2534
2535 if (ivilayer == NULL || remsurf == NULL) {
2536 weston_log("ivi_layout_layer_remove_surface: invalid argument\n");
2537 return;
2538 }
2539
2540 wl_list_for_each_safe(ivisurf, next,
2541 &ivilayer->pending.surface_list, pending.link) {
2542 if (ivisurf->id_surface == remsurf->id_surface) {
2543 if (!wl_list_empty(&ivisurf->pending.link)) {
2544 wl_list_remove(&ivisurf->pending.link);
2545 }
2546 wl_list_init(&ivisurf->pending.link);
2547 break;
2548 }
2549 }
2550
2551 remsurf->event_mask |= IVI_NOTIFICATION_REMOVE;
2552}
2553
2554WL_EXPORT int32_t
2555ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf,
2556 int32_t x, int32_t y,
2557 int32_t width, int32_t height)
2558{
2559 struct ivi_layout_surface_properties *prop = NULL;
2560
2561 if (ivisurf == NULL) {
2562 weston_log("ivi_layout_surface_set_source_rectangle: invalid argument\n");
2563 return IVI_FAILED;
2564 }
2565
2566 prop = &ivisurf->pending.prop;
2567 prop->source_x = x;
2568 prop->source_y = y;
2569 prop->source_width = width;
2570 prop->source_height = height;
2571
2572 ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
2573
2574 return IVI_SUCCEEDED;
2575}
2576
2577WL_EXPORT int32_t
2578ivi_layout_commit_changes(void)
2579{
2580 struct ivi_layout *layout = get_instance();
2581
2582 commit_surface_list(layout);
2583 commit_layer_list(layout);
2584 commit_screen_list(layout);
2585
2586 commit_transition(layout);
2587
2588 commit_changes(layout);
2589 send_prop(layout);
2590 weston_compositor_schedule_repaint(layout->compositor);
2591
2592 return IVI_SUCCEEDED;
2593}
2594
2595/***called from ivi-shell**/
2596static struct weston_view *
2597ivi_layout_get_weston_view(struct ivi_layout_surface *surface)
2598{
2599 struct weston_view *tmpview = NULL;
2600
2601 if(surface == NULL)
2602 return NULL;
2603
2604 wl_list_for_each(tmpview, &surface->surface->views, surface_link)
2605 {
2606 if (tmpview != NULL) {
2607 break;
2608 }
2609 }
2610 return tmpview;
2611}
2612
2613static void
2614ivi_layout_surface_configure(struct ivi_layout_surface *ivisurf,
2615 int32_t width, int32_t height)
2616{
2617 struct ivi_layout *layout = get_instance();
2618 int32_t in_init = 0;
2619 ivisurf->surface->width_from_buffer = width;
2620 ivisurf->surface->height_from_buffer = height;
2621
2622 if (ivisurf->prop.source_width == 0 || ivisurf->prop.source_height == 0) {
2623 in_init = 1;
2624 }
2625
2626 /* FIXME: when sourceHeight/Width is used as clipping range in image buffer */
2627 /* if (ivisurf->prop.sourceWidth == 0 || ivisurf->prop.sourceHeight == 0) { */
2628 ivisurf->pending.prop.source_width = width;
2629 ivisurf->pending.prop.source_height = height;
2630 ivisurf->prop.source_width = width;
2631 ivisurf->prop.source_height = height;
2632 /* } */
2633
2634 ivisurf->event_mask |= IVI_NOTIFICATION_CONFIGURE;
2635
2636 if (in_init) {
2637 wl_signal_emit(&layout->surface_notification.configure_changed, ivisurf);
2638 } else {
2639 ivi_layout_commit_changes();
2640 }
2641}
2642
2643WL_EXPORT int32_t
2644ivi_layout_surface_set_content_observer(struct ivi_layout_surface *ivisurf,
2645 ivi_controller_surface_content_callback callback,
2646 void* userdata)
2647{
2648 int32_t ret = IVI_FAILED;
2649
2650 if (ivisurf != NULL) {
2651 ivisurf->content_observer.callback = callback;
2652 ivisurf->content_observer.userdata = userdata;
2653 ret = IVI_SUCCEEDED;
2654 }
2655 return ret;
2656}
2657
2658static struct ivi_layout_surface*
2659ivi_layout_surface_create(struct weston_surface *wl_surface,
2660 uint32_t id_surface)
2661{
2662 struct ivi_layout *layout = get_instance();
2663 struct ivi_layout_surface *ivisurf = NULL;
2664 struct weston_view *tmpview = NULL;
2665
2666 if (wl_surface == NULL) {
2667 weston_log("ivi_layout_surface_create: invalid argument\n");
2668 return NULL;
2669 }
2670
2671 ivisurf = get_surface(&layout->surface_list, id_surface);
2672 if (ivisurf != NULL) {
2673 if (ivisurf->surface != NULL) {
2674 weston_log("id_surface(%d) is already created\n", id_surface);
2675 return NULL;
2676 }
2677 }
2678
2679 ivisurf = calloc(1, sizeof *ivisurf);
2680 if (ivisurf == NULL) {
2681 weston_log("fails to allocate memory\n");
2682 return NULL;
2683 }
2684
2685 wl_list_init(&ivisurf->link);
2686 wl_signal_init(&ivisurf->property_changed);
2687 wl_signal_init(&ivisurf->configured);
2688 wl_list_init(&ivisurf->layer_list);
2689 ivisurf->id_surface = id_surface;
2690 ivisurf->layout = layout;
2691
2692 ivisurf->surface = wl_surface;
2693 ivisurf->surface_destroy_listener.notify =
2694 westonsurface_destroy_from_ivisurface;
2695 wl_resource_add_destroy_listener(wl_surface->resource,
2696 &ivisurf->surface_destroy_listener);
2697
2698 tmpview = weston_view_create(wl_surface);
2699 if (tmpview == NULL) {
2700 weston_log("fails to allocate memory\n");
2701 }
2702
2703 ivisurf->surface->width_from_buffer = 0;
2704 ivisurf->surface->height_from_buffer = 0;
2705
2706 weston_matrix_init(&ivisurf->surface_rotation.matrix);
2707 weston_matrix_init(&ivisurf->layer_rotation.matrix);
2708 weston_matrix_init(&ivisurf->surface_pos.matrix);
2709 weston_matrix_init(&ivisurf->layer_pos.matrix);
2710 weston_matrix_init(&ivisurf->scaling.matrix);
2711
2712 wl_list_init(&ivisurf->surface_rotation.link);
2713 wl_list_init(&ivisurf->layer_rotation.link);
2714 wl_list_init(&ivisurf->surface_pos.link);
2715 wl_list_init(&ivisurf->layer_pos.link);
2716 wl_list_init(&ivisurf->scaling.link);
2717
2718 init_surface_properties(&ivisurf->prop);
2719 ivisurf->event_mask = 0;
2720
2721 ivisurf->pending.prop = ivisurf->prop;
2722 wl_list_init(&ivisurf->pending.link);
2723
2724 wl_list_init(&ivisurf->order.link);
2725 wl_list_init(&ivisurf->order.layer_list);
2726
2727 wl_list_insert(&layout->surface_list, &ivisurf->link);
2728
2729 wl_signal_emit(&layout->surface_notification.created, ivisurf);
2730
2731 return ivisurf;
2732}
2733
2734static void
2735ivi_layout_init_with_compositor(struct weston_compositor *ec)
2736{
2737 struct ivi_layout *layout = get_instance();
2738
2739 layout->compositor = ec;
2740
2741 wl_list_init(&layout->surface_list);
2742 wl_list_init(&layout->layer_list);
2743 wl_list_init(&layout->screen_list);
2744
2745 wl_signal_init(&layout->layer_notification.created);
2746 wl_signal_init(&layout->layer_notification.removed);
2747
2748 wl_signal_init(&layout->surface_notification.created);
2749 wl_signal_init(&layout->surface_notification.removed);
2750 wl_signal_init(&layout->surface_notification.configure_changed);
2751
2752 /* Add layout_layer at the last of weston_compositor.layer_list */
2753 weston_layer_init(&layout->layout_layer, ec->layer_list.prev);
2754
2755 create_screen(ec);
2756
2757 layout->transitions = ivi_layout_transition_set_create(ec);
2758 wl_list_init(&layout->pending_transition_list);
2759}
2760
2761
2762static void
2763ivi_layout_surface_add_configured_listener(struct ivi_layout_surface* ivisurf,
2764 struct wl_listener* listener)
2765{
2766 wl_signal_add(&ivisurf->configured, listener);
2767}
2768
2769WL_EXPORT struct ivi_layout_interface ivi_layout_interface = {
2770 .get_weston_view = ivi_layout_get_weston_view,
2771 .surface_configure = ivi_layout_surface_configure,
2772 .surface_create = ivi_layout_surface_create,
2773 .init_with_compositor = ivi_layout_init_with_compositor,
2774 .get_surface_dimension = ivi_layout_surface_get_dimension,
2775 .add_surface_configured_listener = ivi_layout_surface_add_configured_listener
2776};