2 * Copyright (C) 2013 DENSO CORPORATION
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.
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.
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
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.
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
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.
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.
61 #include <linux/input.h>
63 #include "compositor.h"
64 #include "ivi-layout-export.h"
65 #include "ivi-layout-private.h"
68 struct ivi_layout_layer *ivilayer;
70 struct wl_list link_to_layer;
74 struct ivi_layout_screen *iviscrn;
76 struct wl_list link_to_screen;
79 struct listener_layout_notification {
81 struct wl_listener listener;
86 struct ivi_layout_screen {
88 struct wl_list link_to_layer;
91 struct ivi_layout *layout;
92 struct weston_output *output;
97 struct wl_list layer_list;
102 struct wl_list layer_list;
108 struct weston_keyboard_grab grab;
109 struct wl_listener updated_caps_listener;
110 struct wl_listener destroy_listener;
113 struct ivi_layout_notification_callback {
118 static struct ivi_layout ivilayout = {0};
121 get_layout_instance(void)
127 * Internal API to add/remove a link to ivi_surface from ivi_layer.
130 add_link_to_surface(struct ivi_layout_layer *ivilayer,
131 struct link_layer *link_layer)
133 struct link_layer *link = NULL;
135 wl_list_for_each(link, &ivilayer->link_to_surface, link_to_layer) {
136 if (link == link_layer)
140 wl_list_insert(&ivilayer->link_to_surface, &link_layer->link_to_layer);
144 remove_link_to_surface(struct ivi_layout_layer *ivilayer)
146 struct link_layer *link = NULL;
147 struct link_layer *next = NULL;
149 wl_list_for_each_safe(link, next, &ivilayer->link_to_surface, link_to_layer) {
150 if (!wl_list_empty(&link->link_to_layer)) {
151 wl_list_remove(&link->link_to_layer);
153 if (!wl_list_empty(&link->link)) {
154 wl_list_remove(&link->link);
159 wl_list_init(&ivilayer->link_to_surface);
163 * Internal API to add a link to ivi_layer from ivi_screen.
166 add_link_to_layer(struct ivi_layout_screen *iviscrn,
167 struct link_screen *link_screen)
169 wl_list_init(&link_screen->link_to_screen);
170 wl_list_insert(&iviscrn->link_to_layer, &link_screen->link_to_screen);
174 * Internal API to add/remove a ivi_surface from ivi_layer.
177 add_ordersurface_to_layer(struct ivi_layout_surface *ivisurf,
178 struct ivi_layout_layer *ivilayer)
180 struct link_layer *link_layer = NULL;
182 link_layer = malloc(sizeof *link_layer);
183 if (link_layer == NULL) {
184 weston_log("fails to allocate memory\n");
188 link_layer->ivilayer = ivilayer;
189 wl_list_init(&link_layer->link);
190 wl_list_insert(&ivisurf->layer_list, &link_layer->link);
191 add_link_to_surface(ivilayer, link_layer);
195 remove_ordersurface_from_layer(struct ivi_layout_surface *ivisurf)
197 struct link_layer *link_layer = NULL;
198 struct link_layer *next = NULL;
200 wl_list_for_each_safe(link_layer, next, &ivisurf->layer_list, link) {
201 if (!wl_list_empty(&link_layer->link)) {
202 wl_list_remove(&link_layer->link);
204 if (!wl_list_empty(&link_layer->link_to_layer)) {
205 wl_list_remove(&link_layer->link_to_layer);
209 wl_list_init(&ivisurf->layer_list);
213 * Internal API to add/remove a ivi_layer to/from ivi_screen.
216 add_orderlayer_to_screen(struct ivi_layout_layer *ivilayer,
217 struct ivi_layout_screen *iviscrn)
219 struct link_screen *link_scrn = NULL;
221 link_scrn = malloc(sizeof *link_scrn);
222 if (link_scrn == NULL) {
223 weston_log("fails to allocate memory\n");
227 link_scrn->iviscrn = iviscrn;
228 wl_list_init(&link_scrn->link);
229 wl_list_insert(&ivilayer->screen_list, &link_scrn->link);
230 add_link_to_layer(iviscrn, link_scrn);
234 remove_orderlayer_from_screen(struct ivi_layout_layer *ivilayer)
236 struct link_screen *link_scrn = NULL;
237 struct link_screen *next = NULL;
239 wl_list_for_each_safe(link_scrn, next, &ivilayer->screen_list, link) {
240 if (!wl_list_empty(&link_scrn->link)) {
241 wl_list_remove(&link_scrn->link);
243 if (!wl_list_empty(&link_scrn->link_to_screen)) {
244 wl_list_remove(&link_scrn->link_to_screen);
248 wl_list_init(&ivilayer->screen_list);
252 * Internal API to add/remove a ivi_layer to/from ivi_screen.
254 static struct ivi_layout_surface *
255 get_surface(struct wl_list *surf_list, uint32_t id_surface)
257 struct ivi_layout_surface *ivisurf;
259 wl_list_for_each(ivisurf, surf_list, link) {
260 if (ivisurf->id_surface == id_surface) {
268 static struct ivi_layout_layer *
269 get_layer(struct wl_list *layer_list, uint32_t id_layer)
271 struct ivi_layout_layer *ivilayer;
273 wl_list_for_each(ivilayer, layer_list, link) {
274 if (ivilayer->id_layer == id_layer) {
283 * Called at destruction of ivi_surface
286 westonsurface_destroy_from_ivisurface(struct wl_listener *listener, void *data)
288 struct ivi_layout_surface *ivisurf = NULL;
290 ivisurf = container_of(listener, struct ivi_layout_surface,
291 surface_destroy_listener);
293 wl_list_remove(&ivisurf->surface_rotation.link);
294 wl_list_remove(&ivisurf->layer_rotation.link);
295 wl_list_remove(&ivisurf->surface_pos.link);
296 wl_list_remove(&ivisurf->layer_pos.link);
297 wl_list_remove(&ivisurf->scaling.link);
299 ivisurf->surface = NULL;
300 ivisurf->view = NULL;
301 ivi_layout_surface_remove(ivisurf);
305 * Internal API to check ivi_layer/ivi_surface already added in ivi_layer/ivi_screen.
306 * Called by ivi_layout_layer_add_surface/ivi_layout_screenAddLayer
309 is_surface_in_layer(struct ivi_layout_surface *ivisurf,
310 struct ivi_layout_layer *ivilayer)
312 struct ivi_layout_surface *surf = NULL;
314 wl_list_for_each(surf, &ivilayer->pending.surface_list, pending.link) {
315 if (surf->id_surface == ivisurf->id_surface) {
324 is_layer_in_screen(struct ivi_layout_layer *ivilayer,
325 struct ivi_layout_screen *iviscrn)
327 struct ivi_layout_layer *layer = NULL;
329 wl_list_for_each(layer, &iviscrn->pending.layer_list, pending.link) {
330 if (layer->id_layer == ivilayer->id_layer) {
339 * Internal API to initialize ivi_screens found from output_list of weston_compositor.
340 * Called by ivi_layout_init_with_compositor.
343 create_screen(struct weston_compositor *ec)
345 struct ivi_layout *layout = get_layout_instance();
346 struct ivi_layout_screen *iviscrn = NULL;
347 struct weston_output *output = NULL;
350 wl_list_for_each(output, &ec->output_list, link) {
351 iviscrn = calloc(1, sizeof *iviscrn);
352 if (iviscrn == NULL) {
353 weston_log("fails to allocate memory\n");
357 wl_list_init(&iviscrn->link);
358 iviscrn->layout = layout;
360 iviscrn->id_screen = count;
363 iviscrn->output = output;
364 iviscrn->event_mask = 0;
366 wl_list_init(&iviscrn->pending.layer_list);
367 wl_list_init(&iviscrn->pending.link);
369 wl_list_init(&iviscrn->order.layer_list);
370 wl_list_init(&iviscrn->order.link);
372 wl_list_init(&iviscrn->link_to_layer);
374 wl_list_insert(&layout->screen_list, &iviscrn->link);
379 * Internal APIs to initialize properties of ivi_surface/ivi_layer when they are created.
382 init_layer_properties(struct ivi_layout_layer_properties *prop,
383 int32_t width, int32_t height)
385 memset(prop, 0, sizeof *prop);
387 prop->source_width = width;
388 prop->source_height = height;
389 prop->dest_width = width;
390 prop->dest_height = height;
394 init_surface_properties(struct ivi_layout_surface_properties *prop)
396 memset(prop, 0, sizeof *prop);
401 * Internal APIs to be called from ivi_layout_commit_changes.
404 update_opacity(struct ivi_layout_layer *ivilayer,
405 struct ivi_layout_surface *ivisurf)
407 double layer_alpha = ivilayer->prop.opacity;
408 double surf_alpha = ivisurf->prop.opacity;
410 if ((ivilayer->event_mask & IVI_NOTIFICATION_OPACITY) ||
411 (ivisurf->event_mask & IVI_NOTIFICATION_OPACITY)) {
412 if (ivisurf->view == NULL)
414 ivisurf->view->alpha = layer_alpha * surf_alpha;
419 update_surface_orientation(struct ivi_layout_layer *ivilayer,
420 struct ivi_layout_surface *ivisurf)
422 struct weston_view *view = ivisurf->view;
423 struct weston_matrix *matrix = &ivisurf->surface_rotation.matrix;
436 if ((ivilayer->prop.dest_width == 0) ||
437 (ivilayer->prop.dest_height == 0)) {
440 width = (float)ivilayer->prop.dest_width;
441 height = (float)ivilayer->prop.dest_height;
443 switch (ivisurf->prop.orientation) {
444 case WL_OUTPUT_TRANSFORM_NORMAL:
448 case WL_OUTPUT_TRANSFORM_90:
454 case WL_OUTPUT_TRANSFORM_180:
458 case WL_OUTPUT_TRANSFORM_270:
466 wl_list_remove(&ivisurf->surface_rotation.link);
467 weston_view_geometry_dirty(view);
469 weston_matrix_init(matrix);
472 weston_matrix_translate(matrix, -cx, -cy, 0.0f);
473 weston_matrix_rotate_xy(matrix, v_cos, v_sin);
474 weston_matrix_scale(matrix, sx, sy, 1.0);
475 weston_matrix_translate(matrix, cx, cy, 0.0f);
476 wl_list_insert(&view->geometry.transformation_list,
477 &ivisurf->surface_rotation.link);
479 weston_view_set_transform_parent(view, NULL);
480 weston_view_update_transform(view);
484 update_layer_orientation(struct ivi_layout_layer *ivilayer,
485 struct ivi_layout_surface *ivisurf)
487 struct weston_surface *es = ivisurf->surface;
488 struct weston_view *view = ivisurf->view;
489 struct weston_matrix *matrix = &ivisurf->layer_rotation.matrix;
490 struct weston_output *output = NULL;
500 if (es == NULL || view == NULL) {
505 if (output == NULL) {
508 if ((output->width == 0) || (output->height == 0)) {
511 width = (float)output->width;
512 height = (float)output->height;
514 switch (ivilayer->prop.orientation) {
515 case WL_OUTPUT_TRANSFORM_NORMAL:
519 case WL_OUTPUT_TRANSFORM_90:
525 case WL_OUTPUT_TRANSFORM_180:
529 case WL_OUTPUT_TRANSFORM_270:
537 wl_list_remove(&ivisurf->layer_rotation.link);
538 weston_view_geometry_dirty(view);
540 weston_matrix_init(matrix);
543 weston_matrix_translate(matrix, -cx, -cy, 0.0f);
544 weston_matrix_rotate_xy(matrix, v_cos, v_sin);
545 weston_matrix_scale(matrix, sx, sy, 1.0);
546 weston_matrix_translate(matrix, cx, cy, 0.0f);
547 wl_list_insert(&view->geometry.transformation_list,
548 &ivisurf->layer_rotation.link);
550 weston_view_set_transform_parent(view, NULL);
551 weston_view_update_transform(view);
555 update_surface_position(struct ivi_layout_surface *ivisurf)
557 struct weston_view *view = ivisurf->view;
558 float tx = (float)ivisurf->prop.dest_x;
559 float ty = (float)ivisurf->prop.dest_y;
560 struct weston_matrix *matrix = &ivisurf->surface_pos.matrix;
566 wl_list_remove(&ivisurf->surface_pos.link);
568 weston_matrix_init(matrix);
569 weston_matrix_translate(matrix, tx, ty, 0.0f);
570 wl_list_insert(&view->geometry.transformation_list,
571 &ivisurf->surface_pos.link);
573 weston_view_set_transform_parent(view, NULL);
574 weston_view_update_transform(view);
578 update_layer_position(struct ivi_layout_layer *ivilayer,
579 struct ivi_layout_surface *ivisurf)
581 struct weston_view *view = ivisurf->view;
582 struct weston_matrix *matrix = &ivisurf->layer_pos.matrix;
583 float tx = (float)ivilayer->prop.dest_x;
584 float ty = (float)ivilayer->prop.dest_y;
590 wl_list_remove(&ivisurf->layer_pos.link);
592 weston_matrix_init(matrix);
593 weston_matrix_translate(matrix, tx, ty, 0.0f);
594 wl_list_insert(&view->geometry.transformation_list,
595 &ivisurf->layer_pos.link);
597 weston_view_set_transform_parent(view, NULL);
598 weston_view_update_transform(view);
602 update_scale(struct ivi_layout_layer *ivilayer,
603 struct ivi_layout_surface *ivisurf)
605 struct weston_view *view = ivisurf->view;
606 struct weston_matrix *matrix = &ivisurf->scaling.matrix;
618 if (ivisurf->prop.dest_width == 0 && ivisurf->prop.dest_height == 0) {
619 ivisurf->prop.dest_width = ivisurf->surface->width_from_buffer;
620 ivisurf->prop.dest_height = ivisurf->surface->height_from_buffer;
623 lw = ((float)ivilayer->prop.dest_width / (float)ivilayer->prop.source_width );
624 sw = ((float)ivisurf->prop.dest_width / (float)ivisurf->prop.source_width );
625 lh = ((float)ivilayer->prop.dest_height / (float)ivilayer->prop.source_height);
626 sh = ((float)ivisurf->prop.dest_height / (float)ivisurf->prop.source_height );
630 wl_list_remove(&ivisurf->scaling.link);
631 weston_matrix_init(matrix);
632 weston_matrix_scale(matrix, sx, sy, 1.0f);
634 wl_list_insert(&view->geometry.transformation_list,
635 &ivisurf->scaling.link);
637 weston_view_set_transform_parent(view, NULL);
638 weston_view_update_transform(view);
642 update_prop(struct ivi_layout_layer *ivilayer,
643 struct ivi_layout_surface *ivisurf)
645 if (ivilayer->event_mask | ivisurf->event_mask) {
646 update_opacity(ivilayer, ivisurf);
647 update_layer_orientation(ivilayer, ivisurf);
648 update_layer_position(ivilayer, ivisurf);
649 update_surface_position(ivisurf);
650 update_surface_orientation(ivilayer, ivisurf);
651 update_scale(ivilayer, ivisurf);
653 ivisurf->update_count++;
655 if (ivisurf->view != NULL) {
656 weston_view_geometry_dirty(ivisurf->view);
659 if (ivisurf->surface != NULL) {
660 weston_surface_damage(ivisurf->surface);
666 commit_changes(struct ivi_layout *layout)
668 struct ivi_layout_screen *iviscrn = NULL;
669 struct ivi_layout_layer *ivilayer = NULL;
670 struct ivi_layout_surface *ivisurf = NULL;
672 wl_list_for_each(iviscrn, &layout->screen_list, link) {
673 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
674 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
675 update_prop(ivilayer, ivisurf);
682 commit_surface_list(struct ivi_layout *layout)
684 struct ivi_layout_surface *ivisurf = NULL;
687 int32_t dest_width = 0;
688 int32_t dest_height = 0;
689 int32_t configured = 0;
691 wl_list_for_each(ivisurf, &layout->surface_list, link) {
692 if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEFAULT) {
693 dest_x = ivisurf->prop.dest_x;
694 dest_y = ivisurf->prop.dest_y;
695 dest_width = ivisurf->prop.dest_width;
696 dest_height = ivisurf->prop.dest_height;
698 ivi_layout_transition_move_resize_view(ivisurf,
699 ivisurf->pending.prop.dest_x,
700 ivisurf->pending.prop.dest_y,
701 ivisurf->pending.prop.dest_width,
702 ivisurf->pending.prop.dest_height,
703 ivisurf->pending.prop.transition_duration);
705 if(ivisurf->pending.prop.visibility) {
706 ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
708 ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
711 ivisurf->prop = ivisurf->pending.prop;
712 ivisurf->prop.dest_x = dest_x;
713 ivisurf->prop.dest_y = dest_y;
714 ivisurf->prop.dest_width = dest_width;
715 ivisurf->prop.dest_height = dest_height;
716 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
717 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
719 } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY){
720 dest_x = ivisurf->prop.dest_x;
721 dest_y = ivisurf->prop.dest_y;
722 dest_width = ivisurf->prop.dest_width;
723 dest_height = ivisurf->prop.dest_height;
725 ivi_layout_transition_move_resize_view(ivisurf,
726 ivisurf->pending.prop.dest_x,
727 ivisurf->pending.prop.dest_y,
728 ivisurf->pending.prop.dest_width,
729 ivisurf->pending.prop.dest_height,
730 ivisurf->pending.prop.transition_duration);
732 ivisurf->prop = ivisurf->pending.prop;
733 ivisurf->prop.dest_x = dest_x;
734 ivisurf->prop.dest_y = dest_y;
735 ivisurf->prop.dest_width = dest_width;
736 ivisurf->prop.dest_height = dest_height;
738 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
739 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
741 } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY){
743 if(ivisurf->pending.prop.visibility) {
744 ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
746 ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
749 if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
750 ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
754 ivisurf->prop = ivisurf->pending.prop;
755 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
756 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
758 if (configured && !is_surface_transition(ivisurf))
759 wl_signal_emit(&ivisurf->configured, ivisurf);
762 if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
763 ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
767 ivisurf->prop = ivisurf->pending.prop;
768 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
769 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
771 if (configured && !is_surface_transition(ivisurf))
772 wl_signal_emit(&ivisurf->configured, ivisurf);
778 commit_layer_list(struct ivi_layout *layout)
780 struct ivi_layout_layer *ivilayer = NULL;
781 struct ivi_layout_surface *ivisurf = NULL;
782 struct ivi_layout_surface *next = NULL;
784 wl_list_for_each(ivilayer, &layout->layer_list, link) {
785 if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_MOVE) {
786 ivi_layout_transition_move_layer(ivilayer, ivilayer->pending.prop.dest_x, ivilayer->pending.prop.dest_y, ivilayer->pending.prop.transition_duration);
787 } else if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_FADE) {
788 ivi_layout_transition_fade_layer(ivilayer,ivilayer->pending.prop.is_fade_in,
789 ivilayer->pending.prop.start_alpha,ivilayer->pending.prop.end_alpha,
791 ivilayer->pending.prop.transition_duration);
793 ivilayer->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
795 ivilayer->prop = ivilayer->pending.prop;
797 if (!(ivilayer->event_mask &
798 (IVI_NOTIFICATION_ADD | IVI_NOTIFICATION_REMOVE)) ) {
802 if (ivilayer->event_mask & IVI_NOTIFICATION_REMOVE) {
803 wl_list_for_each_safe(ivisurf, next,
804 &ivilayer->order.surface_list, order.link) {
805 remove_ordersurface_from_layer(ivisurf);
807 if (!wl_list_empty(&ivisurf->order.link)) {
808 wl_list_remove(&ivisurf->order.link);
811 wl_list_init(&ivisurf->order.link);
812 ivisurf->event_mask |= IVI_NOTIFICATION_REMOVE;
815 wl_list_init(&ivilayer->order.surface_list);
818 if (ivilayer->event_mask & IVI_NOTIFICATION_ADD) {
819 wl_list_for_each_safe(ivisurf, next,
820 &ivilayer->order.surface_list, order.link) {
821 remove_ordersurface_from_layer(ivisurf);
823 if (!wl_list_empty(&ivisurf->order.link)) {
824 wl_list_remove(&ivisurf->order.link);
827 wl_list_init(&ivisurf->order.link);
830 wl_list_init(&ivilayer->order.surface_list);
831 wl_list_for_each(ivisurf, &ivilayer->pending.surface_list,
833 if(!wl_list_empty(&ivisurf->order.link)){
834 wl_list_remove(&ivisurf->order.link);
835 wl_list_init(&ivisurf->order.link);
838 wl_list_insert(&ivilayer->order.surface_list,
839 &ivisurf->order.link);
840 add_ordersurface_to_layer(ivisurf, ivilayer);
841 ivisurf->event_mask |= IVI_NOTIFICATION_ADD;
850 commit_screen_list(struct ivi_layout *layout)
852 struct ivi_layout_screen *iviscrn = NULL;
853 struct ivi_layout_layer *ivilayer = NULL;
854 struct ivi_layout_layer *next = NULL;
855 struct ivi_layout_surface *ivisurf = NULL;
856 struct weston_view *view, *n;
858 /* clear view list of layout layer */
859 wl_list_for_each_safe(view, n, &layout->layout_layer.view_list.link, layer_link.link) {
860 weston_layer_entry_remove(&view->layer_link);
864 wl_list_for_each(iviscrn, &layout->screen_list, link) {
865 if (iviscrn->event_mask & IVI_NOTIFICATION_REMOVE) {
866 wl_list_for_each_safe(ivilayer, next,
867 &iviscrn->order.layer_list, order.link) {
868 remove_orderlayer_from_screen(ivilayer);
870 if (!wl_list_empty(&ivilayer->order.link)) {
871 wl_list_remove(&ivilayer->order.link);
874 wl_list_init(&ivilayer->order.link);
875 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
879 if (iviscrn->event_mask & IVI_NOTIFICATION_ADD) {
880 wl_list_for_each_safe(ivilayer, next,
881 &iviscrn->order.layer_list, order.link) {
882 remove_orderlayer_from_screen(ivilayer);
884 if (!wl_list_empty(&ivilayer->order.link)) {
885 wl_list_remove(&ivilayer->order.link);
888 wl_list_init(&ivilayer->order.link);
891 wl_list_init(&iviscrn->order.layer_list);
892 wl_list_for_each(ivilayer, &iviscrn->pending.layer_list,
894 wl_list_insert(&iviscrn->order.layer_list,
895 &ivilayer->order.link);
896 add_orderlayer_to_screen(ivilayer, iviscrn);
897 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
901 iviscrn->event_mask = 0;
903 /* rebuild view list of layout layer */
904 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
905 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
906 if (ivisurf->surface == NULL || ivisurf->view == NULL)
909 if (ivilayer->prop.visibility == false ||
910 ivisurf->prop.visibility == false) {
911 weston_view_unmap(ivisurf->view);
914 weston_layer_entry_insert(&layout->layout_layer.view_list,
915 &ivisurf->view->layer_link);
917 if (!weston_view_is_mapped(ivisurf->view) ||
918 (ivilayer->event_mask & IVI_NOTIFICATION_ADD)) {
919 weston_view_geometry_dirty(ivisurf->view);
920 weston_view_update_transform(ivisurf->view);
929 commit_transition(struct ivi_layout* layout)
931 if(wl_list_empty(&layout->pending_transition_list)){
935 wl_list_insert_list(&layout->transitions->transition_list,
936 &layout->pending_transition_list);
938 wl_list_init(&layout->pending_transition_list);
940 wl_event_source_timer_update(layout->transitions->event_source, 1);
944 send_surface_prop(struct ivi_layout_surface *ivisurf)
946 wl_signal_emit(&ivisurf->property_changed, ivisurf);
947 ivisurf->event_mask = 0;
951 send_layer_prop(struct ivi_layout_layer *ivilayer)
953 wl_signal_emit(&ivilayer->property_changed, ivilayer);
954 ivilayer->event_mask = 0;
958 send_prop(struct ivi_layout *layout)
960 struct ivi_layout_layer *ivilayer = NULL;
961 struct ivi_layout_surface *ivisurf = NULL;
963 wl_list_for_each_reverse(ivilayer, &layout->layer_list, link) {
964 send_layer_prop(ivilayer);
967 wl_list_for_each_reverse(ivisurf, &layout->surface_list, link) {
968 send_surface_prop(ivisurf);
973 clear_surface_pending_list(struct ivi_layout_layer *ivilayer)
975 struct ivi_layout_surface *surface_link = NULL;
976 struct ivi_layout_surface *surface_next = NULL;
978 wl_list_for_each_safe(surface_link, surface_next,
979 &ivilayer->pending.surface_list, pending.link) {
980 if (!wl_list_empty(&surface_link->pending.link)) {
981 wl_list_remove(&surface_link->pending.link);
984 wl_list_init(&surface_link->pending.link);
987 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
991 clear_surface_order_list(struct ivi_layout_layer *ivilayer)
993 struct ivi_layout_surface *surface_link = NULL;
994 struct ivi_layout_surface *surface_next = NULL;
996 wl_list_for_each_safe(surface_link, surface_next,
997 &ivilayer->order.surface_list, order.link) {
998 if (!wl_list_empty(&surface_link->order.link)) {
999 wl_list_remove(&surface_link->order.link);
1002 wl_list_init(&surface_link->order.link);
1005 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
1009 layer_created(struct wl_listener *listener, void *data)
1011 struct ivi_layout_layer *ivilayer = data;
1013 struct listener_layout_notification *notification =
1014 container_of(listener,
1015 struct listener_layout_notification,
1018 struct ivi_layout_notification_callback *created_callback =
1019 notification->userdata;
1021 ((layer_create_notification_func)created_callback->callback)
1022 (ivilayer, created_callback->data);
1026 layer_removed(struct wl_listener *listener, void *data)
1028 struct ivi_layout_layer *ivilayer = data;
1030 struct listener_layout_notification *notification =
1031 container_of(listener,
1032 struct listener_layout_notification,
1035 struct ivi_layout_notification_callback *removed_callback =
1036 notification->userdata;
1038 ((layer_remove_notification_func)removed_callback->callback)
1039 (ivilayer, removed_callback->data);
1043 layer_prop_changed(struct wl_listener *listener, void *data)
1045 struct ivi_layout_layer *ivilayer = data;
1047 struct listener_layout_notification *layout_listener =
1048 container_of(listener,
1049 struct listener_layout_notification,
1052 struct ivi_layout_notification_callback *prop_callback =
1053 layout_listener->userdata;
1055 ((layer_property_notification_func)prop_callback->callback)
1056 (ivilayer, &ivilayer->prop, ivilayer->event_mask, prop_callback->data);
1060 surface_created(struct wl_listener *listener, void *data)
1062 struct ivi_layout_surface *ivisurface = data;
1064 struct listener_layout_notification *notification =
1065 container_of(listener,
1066 struct listener_layout_notification,
1069 struct ivi_layout_notification_callback *created_callback =
1070 notification->userdata;
1072 ((surface_create_notification_func)created_callback->callback)
1073 (ivisurface, created_callback->data);
1077 surface_removed(struct wl_listener *listener, void *data)
1079 struct ivi_layout_surface *ivisurface = data;
1081 struct listener_layout_notification *notification =
1082 container_of(listener,
1083 struct listener_layout_notification,
1086 struct ivi_layout_notification_callback *removed_callback =
1087 notification->userdata;
1089 ((surface_remove_notification_func)removed_callback->callback)
1090 (ivisurface, removed_callback->data);
1094 surface_prop_changed(struct wl_listener *listener, void *data)
1096 struct ivi_layout_surface *ivisurf = data;
1098 struct listener_layout_notification *layout_listener =
1099 container_of(listener,
1100 struct listener_layout_notification,
1103 struct ivi_layout_notification_callback *prop_callback =
1104 layout_listener->userdata;
1106 ((surface_property_notification_func)prop_callback->callback)
1107 (ivisurf, &ivisurf->prop, ivisurf->event_mask, prop_callback->data);
1111 surface_configure_changed(struct wl_listener *listener,
1114 struct ivi_layout_surface *ivisurface = data;
1116 struct listener_layout_notification *notification =
1117 container_of(listener,
1118 struct listener_layout_notification,
1121 struct ivi_layout_notification_callback *configure_changed_callback =
1122 notification->userdata;
1124 ((surface_configure_notification_func)configure_changed_callback->callback)
1125 (ivisurface, configure_changed_callback->data);
1129 add_notification(struct wl_signal *signal,
1130 wl_notify_func_t callback,
1133 struct listener_layout_notification *notification = NULL;
1135 notification = malloc(sizeof *notification);
1136 if (notification == NULL) {
1137 weston_log("fails to allocate memory\n");
1142 notification->listener.notify = callback;
1143 notification->userdata = userdata;
1145 wl_signal_add(signal, ¬ification->listener);
1147 return IVI_SUCCEEDED;
1151 remove_notification(struct wl_list *listener_list, void *callback, void *userdata)
1153 struct wl_listener *listener = NULL;
1154 struct wl_listener *next = NULL;
1156 wl_list_for_each_safe(listener, next, listener_list, link) {
1157 struct listener_layout_notification *notification =
1158 container_of(listener,
1159 struct listener_layout_notification,
1162 struct ivi_layout_notification_callback *notification_callback =
1163 notification->userdata;
1165 if ((notification_callback->callback != callback) ||
1166 (notification_callback->data != userdata)) {
1170 if (!wl_list_empty(&listener->link)) {
1171 wl_list_remove(&listener->link);
1174 free(notification->userdata);
1180 remove_all_notification(struct wl_list *listener_list)
1182 struct wl_listener *listener = NULL;
1183 struct wl_listener *next = NULL;
1185 wl_list_for_each_safe(listener, next, listener_list, link) {
1186 struct listener_layout_notification *notification = NULL;
1187 if (!wl_list_empty(&listener->link)) {
1188 wl_list_remove(&listener->link);
1192 container_of(listener,
1193 struct listener_layout_notification,
1196 free(notification->userdata);
1202 * Exported APIs of ivi-layout library are implemented from here.
1203 * Brief of APIs is described in ivi-layout-export.h.
1206 ivi_layout_add_notification_create_layer(layer_create_notification_func callback,
1209 struct ivi_layout *layout = get_layout_instance();
1210 struct ivi_layout_notification_callback *created_callback = NULL;
1212 if (callback == NULL) {
1213 weston_log("ivi_layout_add_notification_create_layer: invalid argument\n");
1217 created_callback = malloc(sizeof *created_callback);
1218 if (created_callback == NULL) {
1219 weston_log("fails to allocate memory\n");
1223 created_callback->callback = callback;
1224 created_callback->data = userdata;
1226 return add_notification(&layout->layer_notification.created,
1232 ivi_layout_remove_notification_create_layer(layer_create_notification_func callback,
1235 struct ivi_layout *layout = get_layout_instance();
1236 remove_notification(&layout->layer_notification.created.listener_list, callback, userdata);
1240 ivi_layout_add_notification_remove_layer(layer_remove_notification_func callback,
1243 struct ivi_layout *layout = get_layout_instance();
1244 struct ivi_layout_notification_callback *removed_callback = NULL;
1246 if (callback == NULL) {
1247 weston_log("ivi_layout_add_notification_remove_layer: invalid argument\n");
1251 removed_callback = malloc(sizeof *removed_callback);
1252 if (removed_callback == NULL) {
1253 weston_log("fails to allocate memory\n");
1257 removed_callback->callback = callback;
1258 removed_callback->data = userdata;
1259 return add_notification(&layout->layer_notification.removed,
1265 ivi_layout_remove_notification_remove_layer(layer_remove_notification_func callback,
1268 struct ivi_layout *layout = get_layout_instance();
1269 remove_notification(&layout->layer_notification.removed.listener_list, callback, userdata);
1273 ivi_layout_add_notification_create_surface(surface_create_notification_func callback,
1276 struct ivi_layout *layout = get_layout_instance();
1277 struct ivi_layout_notification_callback *created_callback = NULL;
1279 if (callback == NULL) {
1280 weston_log("ivi_layout_add_notification_create_surface: invalid argument\n");
1284 created_callback = malloc(sizeof *created_callback);
1285 if (created_callback == NULL) {
1286 weston_log("fails to allocate memory\n");
1290 created_callback->callback = callback;
1291 created_callback->data = userdata;
1293 return add_notification(&layout->surface_notification.created,
1299 ivi_layout_remove_notification_create_surface(surface_create_notification_func callback,
1302 struct ivi_layout *layout = get_layout_instance();
1303 remove_notification(&layout->surface_notification.created.listener_list, callback, userdata);
1307 ivi_layout_add_notification_remove_surface(surface_remove_notification_func callback,
1310 struct ivi_layout *layout = get_layout_instance();
1311 struct ivi_layout_notification_callback *removed_callback = NULL;
1313 if (callback == NULL) {
1314 weston_log("ivi_layout_add_notification_remove_surface: invalid argument\n");
1318 removed_callback = malloc(sizeof *removed_callback);
1319 if (removed_callback == NULL) {
1320 weston_log("fails to allocate memory\n");
1324 removed_callback->callback = callback;
1325 removed_callback->data = userdata;
1327 return add_notification(&layout->surface_notification.removed,
1333 ivi_layout_remove_notification_remove_surface(surface_remove_notification_func callback,
1336 struct ivi_layout *layout = get_layout_instance();
1337 remove_notification(&layout->surface_notification.removed.listener_list, callback, userdata);
1341 ivi_layout_add_notification_configure_surface(surface_configure_notification_func callback,
1344 struct ivi_layout *layout = get_layout_instance();
1345 struct ivi_layout_notification_callback *configure_changed_callback = NULL;
1346 if (callback == NULL) {
1347 weston_log("ivi_layout_add_notification_configure_surface: invalid argument\n");
1351 configure_changed_callback = malloc(sizeof *configure_changed_callback);
1352 if (configure_changed_callback == NULL) {
1353 weston_log("fails to allocate memory\n");
1357 configure_changed_callback->callback = callback;
1358 configure_changed_callback->data = userdata;
1360 return add_notification(&layout->surface_notification.configure_changed,
1361 surface_configure_changed,
1362 configure_changed_callback);
1366 ivi_layout_remove_notification_configure_surface(surface_configure_notification_func callback,
1369 struct ivi_layout *layout = get_layout_instance();
1370 remove_notification(&layout->surface_notification.configure_changed.listener_list, callback, userdata);
1374 ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf)
1376 return ivisurf->id_surface;
1380 ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer)
1382 return ivilayer->id_layer;
1385 WL_EXPORT struct ivi_layout_layer *
1386 ivi_layout_get_layer_from_id(uint32_t id_layer)
1388 struct ivi_layout *layout = get_layout_instance();
1389 struct ivi_layout_layer *ivilayer = NULL;
1391 wl_list_for_each(ivilayer, &layout->layer_list, link) {
1392 if (ivilayer->id_layer == id_layer) {
1400 WL_EXPORT struct ivi_layout_surface *
1401 ivi_layout_get_surface_from_id(uint32_t id_surface)
1403 struct ivi_layout *layout = get_layout_instance();
1404 struct ivi_layout_surface *ivisurf = NULL;
1406 wl_list_for_each(ivisurf, &layout->surface_list, link) {
1407 if (ivisurf->id_surface == id_surface) {
1415 WL_EXPORT struct ivi_layout_screen *
1416 ivi_layout_get_screen_from_id(uint32_t id_screen)
1418 struct ivi_layout *layout = get_layout_instance();
1419 struct ivi_layout_screen *iviscrn = NULL;
1421 wl_list_for_each(iviscrn, &layout->screen_list, link) {
1422 /* FIXME : select iviscrn from screen_list by id_screen */
1431 ivi_layout_get_screen_resolution(struct ivi_layout_screen *iviscrn,
1432 int32_t *pWidth, int32_t *pHeight)
1434 struct weston_output *output = NULL;
1436 if (pWidth == NULL || pHeight == NULL) {
1437 weston_log("ivi_layout_get_screen_resolution: invalid argument\n");
1441 output = iviscrn->output;
1442 *pWidth = output->current_mode->width;
1443 *pHeight = output->current_mode->height;
1445 return IVI_SUCCEEDED;
1449 ivi_layout_surface_add_notification(struct ivi_layout_surface *ivisurf,
1450 surface_property_notification_func callback,
1453 struct listener_layout_notification* notification = NULL;
1454 struct ivi_layout_notification_callback *prop_callback = NULL;
1456 if (ivisurf == NULL || callback == NULL) {
1457 weston_log("ivi_layout_surface_add_notification: invalid argument\n");
1461 notification = malloc(sizeof *notification);
1462 if (notification == NULL) {
1463 weston_log("fails to allocate memory\n");
1467 prop_callback = malloc(sizeof *prop_callback);
1468 if (prop_callback == NULL) {
1469 weston_log("fails to allocate memory\n");
1473 prop_callback->callback = callback;
1474 prop_callback->data = userdata;
1476 notification->listener.notify = surface_prop_changed;
1477 notification->userdata = prop_callback;
1479 wl_signal_add(&ivisurf->property_changed, ¬ification->listener);
1481 return IVI_SUCCEEDED;
1485 ivi_layout_surface_remove_notification(struct ivi_layout_surface *ivisurf)
1487 if (ivisurf == NULL) {
1488 weston_log("ivi_layout_surface_remove_notification: invalid argument\n");
1492 remove_all_notification(&ivisurf->property_changed.listener_list);
1496 remove_configured_listener(struct ivi_layout_surface *ivisurf)
1498 struct wl_listener *link = NULL;
1499 struct wl_listener *next = NULL;
1501 wl_list_for_each_safe(link, next, &ivisurf->configured.listener_list, link) {
1502 wl_list_remove(&link->link);
1507 ivi_layout_surface_remove(struct ivi_layout_surface *ivisurf)
1509 struct ivi_layout *layout = get_layout_instance();
1511 if (ivisurf == NULL) {
1512 weston_log("ivi_layout_surface_remove: invalid argument\n");
1516 if (!wl_list_empty(&ivisurf->pending.link)) {
1517 wl_list_remove(&ivisurf->pending.link);
1519 if (!wl_list_empty(&ivisurf->order.link)) {
1520 wl_list_remove(&ivisurf->order.link);
1522 if (!wl_list_empty(&ivisurf->link)) {
1523 wl_list_remove(&ivisurf->link);
1525 remove_ordersurface_from_layer(ivisurf);
1527 wl_signal_emit(&layout->surface_notification.removed, ivisurf);
1529 remove_configured_listener(ivisurf);
1531 ivi_layout_surface_remove_notification(ivisurf);
1536 WL_EXPORT const struct ivi_layout_layer_properties *
1537 ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer)
1539 if (ivilayer == NULL) {
1540 weston_log("ivi_layout_get_properties_of_layer: invalid argument\n");
1544 return &ivilayer->prop;
1548 ivi_layout_get_screens(int32_t *pLength, struct ivi_layout_screen ***ppArray)
1550 struct ivi_layout *layout = get_layout_instance();
1551 struct ivi_layout_screen *iviscrn = NULL;
1555 if (pLength == NULL || ppArray == NULL) {
1556 weston_log("ivi_layout_get_screens: invalid argument\n");
1560 length = wl_list_length(&layout->screen_list);
1563 /* the Array must be free by module which called this function */
1564 *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
1565 if (*ppArray == NULL) {
1566 weston_log("fails to allocate memory\n");
1570 wl_list_for_each(iviscrn, &layout->screen_list, link) {
1571 (*ppArray)[n++] = iviscrn;
1577 return IVI_SUCCEEDED;
1581 ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer,
1583 struct ivi_layout_screen ***ppArray)
1585 struct link_screen *link_scrn = NULL;
1589 if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1590 weston_log("ivi_layout_get_screens_under_layer: invalid argument\n");
1594 length = wl_list_length(&ivilayer->screen_list);
1597 /* the Array must be free by module which called this function */
1598 *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
1599 if (*ppArray == NULL) {
1600 weston_log("fails to allocate memory\n");
1604 wl_list_for_each(link_scrn, &ivilayer->screen_list, link) {
1605 (*ppArray)[n++] = link_scrn->iviscrn;
1611 return IVI_SUCCEEDED;
1615 ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray)
1617 struct ivi_layout *layout = get_layout_instance();
1618 struct ivi_layout_layer *ivilayer = NULL;
1622 if (pLength == NULL || ppArray == NULL) {
1623 weston_log("ivi_layout_get_layers: invalid argument\n");
1627 length = wl_list_length(&layout->layer_list);
1630 /* the Array must be free by module which called this function */
1631 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1632 if (*ppArray == NULL) {
1633 weston_log("fails to allocate memory\n");
1637 wl_list_for_each(ivilayer, &layout->layer_list, link) {
1638 (*ppArray)[n++] = ivilayer;
1644 return IVI_SUCCEEDED;
1648 ivi_layout_get_layers_on_screen(struct ivi_layout_screen *iviscrn,
1650 struct ivi_layout_layer ***ppArray)
1652 struct ivi_layout_layer *ivilayer = NULL;
1656 if (iviscrn == NULL || pLength == NULL || ppArray == NULL) {
1657 weston_log("ivi_layout_get_layers_on_screen: invalid argument\n");
1661 length = wl_list_length(&iviscrn->order.layer_list);
1664 /* the Array must be free by module which called this function */
1665 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1666 if (*ppArray == NULL) {
1667 weston_log("fails to allocate memory\n");
1671 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, link) {
1672 (*ppArray)[n++] = ivilayer;
1678 return IVI_SUCCEEDED;
1682 ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf,
1684 struct ivi_layout_layer ***ppArray)
1686 struct link_layer *link_layer = NULL;
1690 if (ivisurf == NULL || pLength == NULL || ppArray == NULL) {
1691 weston_log("ivi_layout_getLayers: invalid argument\n");
1695 length = wl_list_length(&ivisurf->layer_list);
1698 /* the Array must be free by module which called this function */
1699 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1700 if (*ppArray == NULL) {
1701 weston_log("fails to allocate memory\n");
1705 wl_list_for_each(link_layer, &ivisurf->layer_list, link) {
1706 (*ppArray)[n++] = link_layer->ivilayer;
1712 return IVI_SUCCEEDED;
1716 ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray)
1718 struct ivi_layout *layout = get_layout_instance();
1719 struct ivi_layout_surface *ivisurf = NULL;
1723 if (pLength == NULL || ppArray == NULL) {
1724 weston_log("ivi_layout_get_surfaces: invalid argument\n");
1728 length = wl_list_length(&layout->surface_list);
1731 /* the Array must be free by module which called this function */
1732 *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1733 if (*ppArray == NULL) {
1734 weston_log("fails to allocate memory\n");
1738 wl_list_for_each(ivisurf, &layout->surface_list, link) {
1739 (*ppArray)[n++] = ivisurf;
1745 return IVI_SUCCEEDED;
1749 ivi_layout_get_surfaces_on_layer(struct ivi_layout_layer *ivilayer,
1751 struct ivi_layout_surface ***ppArray)
1753 struct ivi_layout_surface *ivisurf = NULL;
1757 if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1758 weston_log("ivi_layout_getSurfaceIDsOnLayer: invalid argument\n");
1762 length = wl_list_length(&ivilayer->order.surface_list);
1765 /* the Array must be free by module which called this function */
1766 *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1767 if (*ppArray == NULL) {
1768 weston_log("fails to allocate memory\n");
1772 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
1773 (*ppArray)[n++] = ivisurf;
1779 return IVI_SUCCEEDED;
1782 WL_EXPORT struct ivi_layout_layer *
1783 ivi_layout_layer_create_with_dimension(uint32_t id_layer,
1784 int32_t width, int32_t height)
1786 struct ivi_layout *layout = get_layout_instance();
1787 struct ivi_layout_layer *ivilayer = NULL;
1789 ivilayer = get_layer(&layout->layer_list, id_layer);
1790 if (ivilayer != NULL) {
1791 weston_log("id_layer is already created\n");
1795 ivilayer = calloc(1, sizeof *ivilayer);
1796 if (ivilayer == NULL) {
1797 weston_log("fails to allocate memory\n");
1801 wl_list_init(&ivilayer->link);
1802 wl_signal_init(&ivilayer->property_changed);
1803 wl_list_init(&ivilayer->screen_list);
1804 wl_list_init(&ivilayer->link_to_surface);
1805 ivilayer->layout = layout;
1806 ivilayer->id_layer = id_layer;
1808 init_layer_properties(&ivilayer->prop, width, height);
1809 ivilayer->event_mask = 0;
1811 wl_list_init(&ivilayer->pending.surface_list);
1812 wl_list_init(&ivilayer->pending.link);
1813 ivilayer->pending.prop = ivilayer->prop;
1815 wl_list_init(&ivilayer->order.surface_list);
1816 wl_list_init(&ivilayer->order.link);
1818 wl_list_insert(&layout->layer_list, &ivilayer->link);
1820 wl_signal_emit(&layout->layer_notification.created, ivilayer);
1826 ivi_layout_layer_remove(struct ivi_layout_layer *ivilayer)
1828 struct ivi_layout *layout = get_layout_instance();
1830 if (ivilayer == NULL) {
1831 weston_log("ivi_layout_layer_remove: invalid argument\n");
1835 wl_signal_emit(&layout->layer_notification.removed, ivilayer);
1837 clear_surface_pending_list(ivilayer);
1838 clear_surface_order_list(ivilayer);
1840 if (!wl_list_empty(&ivilayer->pending.link)) {
1841 wl_list_remove(&ivilayer->pending.link);
1843 if (!wl_list_empty(&ivilayer->order.link)) {
1844 wl_list_remove(&ivilayer->order.link);
1846 if (!wl_list_empty(&ivilayer->link)) {
1847 wl_list_remove(&ivilayer->link);
1849 remove_orderlayer_from_screen(ivilayer);
1850 remove_link_to_surface(ivilayer);
1851 ivi_layout_layer_remove_notification(ivilayer);
1857 ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer,
1860 struct ivi_layout_layer_properties *prop = NULL;
1862 if (ivilayer == NULL) {
1863 weston_log("ivi_layout_layer_set_visibility: invalid argument\n");
1867 prop = &ivilayer->pending.prop;
1868 prop->visibility = newVisibility;
1870 ivilayer->event_mask |= IVI_NOTIFICATION_VISIBILITY;
1872 return IVI_SUCCEEDED;
1876 ivi_layout_layer_get_visibility(struct ivi_layout_layer *ivilayer)
1878 if (ivilayer == NULL) {
1879 weston_log("ivi_layout_layer_get_visibility: invalid argument\n");
1883 return ivilayer->prop.visibility;
1887 ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
1890 struct ivi_layout_layer_properties *prop = NULL;
1892 if (ivilayer == NULL) {
1893 weston_log("ivi_layout_layer_set_opacity: invalid argument\n");
1897 prop = &ivilayer->pending.prop;
1898 prop->opacity = opacity;
1900 ivilayer->event_mask |= IVI_NOTIFICATION_OPACITY;
1902 return IVI_SUCCEEDED;
1905 WL_EXPORT wl_fixed_t
1906 ivi_layout_layer_get_opacity(struct ivi_layout_layer *ivilayer)
1908 if (ivilayer == NULL) {
1909 weston_log("ivi_layout_layer_get_opacity: invalid argument\n");
1910 return wl_fixed_from_double(0.0);
1913 return ivilayer->prop.opacity;
1917 ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer,
1918 int32_t x, int32_t y,
1919 int32_t width, int32_t height)
1921 struct ivi_layout_layer_properties *prop = NULL;
1923 if (ivilayer == NULL) {
1924 weston_log("ivi_layout_layer_set_source_rectangle: invalid argument\n");
1928 prop = &ivilayer->pending.prop;
1931 prop->source_width = width;
1932 prop->source_height = height;
1934 ivilayer->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
1936 return IVI_SUCCEEDED;
1940 ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer,
1941 int32_t x, int32_t y,
1942 int32_t width, int32_t height)
1944 struct ivi_layout_layer_properties *prop = NULL;
1946 if (ivilayer == NULL) {
1947 weston_log("ivi_layout_layer_set_destination_rectangle: invalid argument\n");
1951 prop = &ivilayer->pending.prop;
1954 prop->dest_width = width;
1955 prop->dest_height = height;
1957 ivilayer->event_mask |= IVI_NOTIFICATION_DEST_RECT;
1959 return IVI_SUCCEEDED;
1963 ivi_layout_layer_get_dimension(struct ivi_layout_layer *ivilayer,
1964 int32_t *dest_width, int32_t *dest_height)
1966 if (ivilayer == NULL || dest_width == NULL || dest_height == NULL) {
1967 weston_log("ivi_layout_layer_get_dimension: invalid argument\n");
1971 *dest_width = ivilayer->prop.dest_width;
1972 *dest_height = ivilayer->prop.dest_height;
1974 return IVI_SUCCEEDED;
1978 ivi_layout_layer_set_dimension(struct ivi_layout_layer *ivilayer,
1979 int32_t dest_width, int32_t dest_height)
1981 struct ivi_layout_layer_properties *prop = NULL;
1983 if (ivilayer == NULL) {
1984 weston_log("ivi_layout_layer_set_dimension: invalid argument\n");
1988 prop = &ivilayer->pending.prop;
1990 prop->dest_width = dest_width;
1991 prop->dest_height = dest_height;
1993 ivilayer->event_mask |= IVI_NOTIFICATION_DIMENSION;
1995 return IVI_SUCCEEDED;
1999 ivi_layout_layer_get_position(struct ivi_layout_layer *ivilayer,
2000 int32_t *dest_x, int32_t *dest_y)
2002 if (ivilayer == NULL || dest_x == NULL || dest_y == NULL) {
2003 weston_log("ivi_layout_layer_get_position: invalid argument\n");
2007 *dest_x = ivilayer->prop.dest_x;
2008 *dest_y = ivilayer->prop.dest_y;
2010 return IVI_SUCCEEDED;
2014 ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer,
2015 int32_t dest_x, int32_t dest_y)
2017 struct ivi_layout_layer_properties *prop = NULL;
2019 if (ivilayer == NULL) {
2020 weston_log("ivi_layout_layer_set_position: invalid argument\n");
2024 prop = &ivilayer->pending.prop;
2025 prop->dest_x = dest_x;
2026 prop->dest_y = dest_y;
2028 ivilayer->event_mask |= IVI_NOTIFICATION_POSITION;
2030 return IVI_SUCCEEDED;
2034 ivi_layout_layer_set_orientation(struct ivi_layout_layer *ivilayer,
2035 enum wl_output_transform orientation)
2037 struct ivi_layout_layer_properties *prop = NULL;
2039 if (ivilayer == NULL) {
2040 weston_log("ivi_layout_layer_set_orientation: invalid argument\n");
2044 prop = &ivilayer->pending.prop;
2045 prop->orientation = orientation;
2047 ivilayer->event_mask |= IVI_NOTIFICATION_ORIENTATION;
2049 return IVI_SUCCEEDED;
2052 enum wl_output_transform
2053 ivi_layout_layer_get_orientation(struct ivi_layout_layer *ivilayer)
2055 if (ivilayer == NULL) {
2056 weston_log("ivi_layout_layer_get_orientation: invalid argument\n");
2060 return ivilayer->prop.orientation;
2064 ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
2065 struct ivi_layout_surface **pSurface,
2068 struct ivi_layout *layout = get_layout_instance();
2069 struct ivi_layout_surface *ivisurf = NULL;
2070 struct ivi_layout_surface *next = NULL;
2071 uint32_t *id_surface = NULL;
2074 if (ivilayer == NULL) {
2075 weston_log("ivi_layout_layer_set_render_order: invalid argument\n");
2079 if (pSurface == NULL) {
2080 wl_list_for_each_safe(ivisurf, next, &ivilayer->pending.surface_list, pending.link) {
2081 if (!wl_list_empty(&ivisurf->pending.link)) {
2082 wl_list_remove(&ivisurf->pending.link);
2085 wl_list_init(&ivisurf->pending.link);
2087 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
2088 return IVI_SUCCEEDED;
2091 for (i = 0; i < number; i++) {
2092 id_surface = &pSurface[i]->id_surface;
2094 wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
2095 if (*id_surface != ivisurf->id_surface) {
2099 if (!wl_list_empty(&ivisurf->pending.link)) {
2100 wl_list_remove(&ivisurf->pending.link);
2102 wl_list_init(&ivisurf->pending.link);
2103 wl_list_insert(&ivilayer->pending.surface_list,
2104 &ivisurf->pending.link);
2109 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
2111 return IVI_SUCCEEDED;
2115 ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf,
2118 struct ivi_layout_surface_properties *prop = NULL;
2120 if (ivisurf == NULL) {
2121 weston_log("ivi_layout_surface_set_visibility: invalid argument\n");
2125 prop = &ivisurf->pending.prop;
2126 prop->visibility = newVisibility;
2128 ivisurf->event_mask |= IVI_NOTIFICATION_VISIBILITY;
2130 return IVI_SUCCEEDED;
2134 ivi_layout_surface_get_visibility(struct ivi_layout_surface *ivisurf)
2136 if (ivisurf == NULL) {
2137 weston_log("ivi_layout_surface_get_visibility: invalid argument\n");
2141 return ivisurf->prop.visibility;
2145 ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
2148 struct ivi_layout_surface_properties *prop = NULL;
2150 if (ivisurf == NULL) {
2151 weston_log("ivi_layout_surface_set_opacity: invalid argument\n");
2155 prop = &ivisurf->pending.prop;
2156 prop->opacity = opacity;
2158 ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY;
2160 return IVI_SUCCEEDED;
2163 WL_EXPORT wl_fixed_t
2164 ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf)
2166 if (ivisurf == NULL) {
2167 weston_log("ivi_layout_surface_get_opacity: invalid argument\n");
2168 return wl_fixed_from_double(0.0);
2171 return ivisurf->prop.opacity;
2175 ivi_layout_set_keyboard_focus_on(struct ivi_layout_surface *ivisurf)
2177 struct ivi_layout *layout = get_layout_instance();
2178 struct wl_list *seat_list = &layout->compositor->seat_list;
2179 struct wl_list *surface_list = &layout->surface_list;
2180 struct ivi_layout_surface *current_surf;
2182 if (ivisurf == NULL) {
2183 weston_log("%s: invalid argument\n", __FUNCTION__);
2187 if (seat_list == NULL) {
2188 weston_log("%s: seat list is NULL\n", __FUNCTION__);
2192 if (ivisurf->surface == NULL) {
2193 weston_log("%s: ivisurf has no surface\n", __FUNCTION__);
2197 if (surface_list == NULL) {
2198 weston_log("%s: surface list is NULL\n", __FUNCTION__);
2202 wl_list_for_each(current_surf, &layout->surface_list, link) {
2203 if (current_surf == ivisurf) {
2204 current_surf->prop.has_keyboard_focus = 1;
2205 current_surf->pending.prop.has_keyboard_focus = 1;
2207 current_surf->prop.has_keyboard_focus = 0;
2208 current_surf->pending.prop.has_keyboard_focus = 0;
2210 current_surf->event_mask |= IVI_NOTIFICATION_KEYBOARD_FOCUS;
2217 ivi_layout_get_keyboard_focus_surface_id(struct ivi_layout_surface **pSurfaceId)
2219 struct wl_list *surface_list = &get_layout_instance()->surface_list;
2220 struct ivi_layout_surface *current_surf;
2222 if (surface_list == NULL) {
2223 weston_log("%s: surface list is NULL\n", __FUNCTION__);
2227 wl_list_for_each(current_surf, surface_list, link) {
2228 if (current_surf->prop.has_keyboard_focus != 0) {
2229 *pSurfaceId = current_surf;
2239 ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
2240 int32_t x, int32_t y,
2241 int32_t width, int32_t height)
2243 struct ivi_layout_surface_properties *prop = NULL;
2245 if (ivisurf == NULL) {
2246 weston_log("ivi_layout_surface_set_destination_rectangle: invalid argument\n");
2250 prop = &ivisurf->pending.prop;
2251 prop->start_x = prop->dest_x;
2252 prop->start_y = prop->dest_y;
2255 prop->start_width = prop->dest_width;
2256 prop->start_height = prop->dest_height;
2257 prop->dest_width = width;
2258 prop->dest_height = height;
2260 ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT;
2262 return IVI_SUCCEEDED;
2266 ivi_layout_surface_set_dimension(struct ivi_layout_surface *ivisurf,
2267 int32_t dest_width, int32_t dest_height)
2269 struct ivi_layout_surface_properties *prop = NULL;
2271 if (ivisurf == NULL) {
2272 weston_log("ivi_layout_surface_set_dimension: invalid argument\n");
2276 prop = &ivisurf->pending.prop;
2277 prop->dest_width = dest_width;
2278 prop->dest_height = dest_height;
2280 ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION;
2282 return IVI_SUCCEEDED;
2286 ivi_layout_surface_get_dimension(struct ivi_layout_surface *ivisurf,
2287 int32_t *dest_width, int32_t *dest_height)
2289 if (ivisurf == NULL || dest_width == NULL || dest_height == NULL) {
2290 weston_log("ivi_layout_surface_get_dimension: invalid argument\n");
2294 *dest_width = ivisurf->prop.dest_width;
2295 *dest_height = ivisurf->prop.dest_height;
2297 return IVI_SUCCEEDED;
2301 ivi_layout_surface_set_position(struct ivi_layout_surface *ivisurf,
2302 int32_t dest_x, int32_t dest_y)
2304 struct ivi_layout_surface_properties *prop = NULL;
2306 if (ivisurf == NULL) {
2307 weston_log("ivi_layout_surface_set_position: invalid argument\n");
2311 prop = &ivisurf->pending.prop;
2312 prop->dest_x = dest_x;
2313 prop->dest_y = dest_y;
2315 ivisurf->event_mask |= IVI_NOTIFICATION_POSITION;
2317 return IVI_SUCCEEDED;
2321 ivi_layout_surface_get_position(struct ivi_layout_surface *ivisurf,
2322 int32_t *dest_x, int32_t *dest_y)
2324 if (ivisurf == NULL || dest_x == NULL || dest_y == NULL) {
2325 weston_log("ivi_layout_surface_get_position: invalid argument\n");
2329 *dest_x = ivisurf->prop.dest_x;
2330 *dest_y = ivisurf->prop.dest_y;
2332 return IVI_SUCCEEDED;
2336 ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf,
2337 enum wl_output_transform orientation)
2339 struct ivi_layout_surface_properties *prop = NULL;
2341 if (ivisurf == NULL) {
2342 weston_log("ivi_layout_surface_set_orientation: invalid argument\n");
2346 prop = &ivisurf->pending.prop;
2347 prop->orientation = orientation;
2349 ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION;
2351 return IVI_SUCCEEDED;
2354 enum wl_output_transform
2355 ivi_layout_surface_get_orientation(struct ivi_layout_surface *ivisurf)
2357 if (ivisurf == NULL) {
2358 weston_log("ivi_layout_surface_get_orientation: invalid argument\n");
2362 return ivisurf->prop.orientation;
2366 ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn,
2367 struct ivi_layout_layer *addlayer)
2369 struct ivi_layout *layout = get_layout_instance();
2370 struct ivi_layout_layer *ivilayer = NULL;
2371 struct ivi_layout_layer *next = NULL;
2372 int is_layer_in_scrn = 0;
2374 if (iviscrn == NULL || addlayer == NULL) {
2375 weston_log("ivi_layout_screen_add_layer: invalid argument\n");
2379 is_layer_in_scrn = is_layer_in_screen(addlayer, iviscrn);
2380 if (is_layer_in_scrn == 1) {
2381 weston_log("ivi_layout_screen_add_layer: addlayer is already available\n");
2382 return IVI_SUCCEEDED;
2385 wl_list_for_each_safe(ivilayer, next, &layout->layer_list, link) {
2386 if (ivilayer->id_layer == addlayer->id_layer) {
2387 if (!wl_list_empty(&ivilayer->pending.link)) {
2388 wl_list_remove(&ivilayer->pending.link);
2390 wl_list_init(&ivilayer->pending.link);
2391 wl_list_insert(&iviscrn->pending.layer_list,
2392 &ivilayer->pending.link);
2397 iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
2399 return IVI_SUCCEEDED;
2403 ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn,
2404 struct ivi_layout_layer **pLayer,
2405 const int32_t number)
2407 struct ivi_layout *layout = get_layout_instance();
2408 struct ivi_layout_layer *ivilayer = NULL;
2409 struct ivi_layout_layer *next = NULL;
2410 uint32_t *id_layer = NULL;
2413 if (iviscrn == NULL) {
2414 weston_log("ivi_layout_screen_set_render_order: invalid argument\n");
2418 wl_list_for_each_safe(ivilayer, next,
2419 &iviscrn->pending.layer_list, pending.link) {
2420 wl_list_init(&ivilayer->pending.link);
2423 wl_list_init(&iviscrn->pending.layer_list);
2425 if (pLayer == NULL) {
2426 wl_list_for_each_safe(ivilayer, next, &iviscrn->pending.layer_list, pending.link) {
2427 if (!wl_list_empty(&ivilayer->pending.link)) {
2428 wl_list_remove(&ivilayer->pending.link);
2431 wl_list_init(&ivilayer->pending.link);
2434 iviscrn->event_mask |= IVI_NOTIFICATION_REMOVE;
2435 return IVI_SUCCEEDED;
2438 for (i = 0; i < number; i++) {
2439 id_layer = &pLayer[i]->id_layer;
2440 wl_list_for_each(ivilayer, &layout->layer_list, link) {
2441 if (*id_layer != ivilayer->id_layer) {
2445 if (!wl_list_empty(&ivilayer->pending.link)) {
2446 wl_list_remove(&ivilayer->pending.link);
2448 wl_list_init(&ivilayer->pending.link);
2449 wl_list_insert(&iviscrn->pending.layer_list,
2450 &ivilayer->pending.link);
2455 iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
2457 return IVI_SUCCEEDED;
2460 WL_EXPORT struct weston_output *
2461 ivi_layout_screen_get_output(struct ivi_layout_screen *iviscrn)
2463 return iviscrn->output;
2467 * This function is used by the additional ivi-module because of dumping ivi_surface sceenshot.
2468 * The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of Genivi's Layer Management.
2469 * This function is used to get the result of drawing by clients.
2471 WL_EXPORT struct weston_surface *
2472 ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf)
2474 return ivisurf != NULL ? ivisurf->surface : NULL;
2478 * This function is used by the additional ivi-module because of dumping ivi_surface sceenshot.
2479 * The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of GENIVI's Layer Management.
2480 * This function is used to get the region and the stride.
2483 ivi_layout_surface_get_size(struct ivi_layout_surface *ivisurf,
2488 if (ivisurf == NULL) {
2492 if (width != NULL) {
2493 *width = ivisurf->prop.source_width;
2496 if (height != NULL) {
2497 *height = ivisurf->prop.source_height;
2500 if (stride != NULL &&
2501 ivisurf->surface->buffer_ref.buffer != NULL &&
2502 ivisurf->surface->buffer_ref.buffer->shm_buffer != NULL) {
2503 *stride = wl_shm_buffer_get_stride(ivisurf->surface->buffer_ref.buffer->shm_buffer);
2506 return IVI_SUCCEEDED;
2510 ivi_layout_layer_add_notification(struct ivi_layout_layer *ivilayer,
2511 layer_property_notification_func callback,
2514 struct ivi_layout_notification_callback *prop_callback = NULL;
2516 if (ivilayer == NULL || callback == NULL) {
2517 weston_log("ivi_layout_layer_add_notification: invalid argument\n");
2521 prop_callback = malloc(sizeof *prop_callback);
2522 if (prop_callback == NULL) {
2523 weston_log("fails to allocate memory\n");
2527 prop_callback->callback = callback;
2528 prop_callback->data = userdata;
2530 return add_notification(&ivilayer->property_changed,
2536 ivi_layout_layer_remove_notification(struct ivi_layout_layer *ivilayer)
2538 if (ivilayer == NULL) {
2539 weston_log("ivi_layout_layer_remove_notification: invalid argument\n");
2543 remove_all_notification(&ivilayer->property_changed.listener_list);
2546 WL_EXPORT const struct ivi_layout_surface_properties *
2547 ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf)
2549 if (ivisurf == NULL) {
2550 weston_log("ivi_layout_get_properties_of_surface: invalid argument\n");
2554 return &ivisurf->prop;
2558 ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer,
2559 struct ivi_layout_surface *addsurf)
2561 struct ivi_layout *layout = get_layout_instance();
2562 struct ivi_layout_surface *ivisurf = NULL;
2563 struct ivi_layout_surface *next = NULL;
2564 int is_surf_in_layer = 0;
2566 if (ivilayer == NULL || addsurf == NULL) {
2567 weston_log("ivi_layout_layer_add_surface: invalid argument\n");
2571 is_surf_in_layer = is_surface_in_layer(addsurf, ivilayer);
2572 if (is_surf_in_layer == 1) {
2573 weston_log("ivi_layout_layer_add_surface: addsurf is already available\n");
2574 return IVI_SUCCEEDED;
2577 wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
2578 if (ivisurf->id_surface == addsurf->id_surface) {
2579 if (!wl_list_empty(&ivisurf->pending.link)) {
2580 wl_list_remove(&ivisurf->pending.link);
2582 wl_list_init(&ivisurf->pending.link);
2583 wl_list_insert(&ivilayer->pending.surface_list,
2584 &ivisurf->pending.link);
2589 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
2591 return IVI_SUCCEEDED;
2595 ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer,
2596 struct ivi_layout_surface *remsurf)
2598 struct ivi_layout_surface *ivisurf = NULL;
2599 struct ivi_layout_surface *next = NULL;
2601 if (ivilayer == NULL || remsurf == NULL) {
2602 weston_log("ivi_layout_layer_remove_surface: invalid argument\n");
2606 wl_list_for_each_safe(ivisurf, next,
2607 &ivilayer->pending.surface_list, pending.link) {
2608 if (ivisurf->id_surface == remsurf->id_surface) {
2609 if (!wl_list_empty(&ivisurf->pending.link)) {
2610 wl_list_remove(&ivisurf->pending.link);
2612 wl_list_init(&ivisurf->pending.link);
2617 remsurf->event_mask |= IVI_NOTIFICATION_REMOVE;
2621 ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf,
2622 int32_t x, int32_t y,
2623 int32_t width, int32_t height)
2625 struct ivi_layout_surface_properties *prop = NULL;
2627 if (ivisurf == NULL) {
2628 weston_log("ivi_layout_surface_set_source_rectangle: invalid argument\n");
2632 prop = &ivisurf->pending.prop;
2635 prop->source_width = width;
2636 prop->source_height = height;
2638 ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
2640 return IVI_SUCCEEDED;
2644 ivi_layout_commit_changes(void)
2646 struct ivi_layout *layout = get_layout_instance();
2648 commit_surface_list(layout);
2649 commit_layer_list(layout);
2650 commit_screen_list(layout);
2652 commit_transition(layout);
2654 commit_changes(layout);
2656 weston_compositor_schedule_repaint(layout->compositor);
2658 return IVI_SUCCEEDED;
2661 /***called from ivi-shell**/
2662 static struct weston_surface *
2663 ivi_layout_get_weston_surface(struct ivi_layout_surface *surface)
2665 return (surface != NULL) ? surface->surface : NULL;
2668 static struct weston_view *
2669 ivi_layout_get_weston_view(struct ivi_layout_surface *surface)
2671 return (surface != NULL) ? surface->view : NULL;
2675 ivi_layout_surface_configure(struct ivi_layout_surface *ivisurf,
2676 int32_t width, int32_t height)
2678 struct ivi_layout *layout = get_layout_instance();
2681 ivisurf->surface->width_from_buffer = width;
2682 ivisurf->surface->height_from_buffer = height;
2684 if (ivisurf->prop.source_width == 0 || ivisurf->prop.source_height == 0) {
2685 ivisurf->prop.source_width = width;
2686 ivisurf->prop.source_height = height;
2689 if (width != ivisurf->pending.prop.source_width ||
2690 height != ivisurf->pending.prop.source_height) {
2692 * This is quick fix for resizing buffers and will reset zooming
2693 * TODO: replace this with some more complex code that tries to * preserve the zooming ratio and relative position
2695 ivisurf->pending.prop.source_x = 0;
2696 ivisurf->pending.prop.source_y = 0;
2697 ivisurf->pending.prop.source_width = width;
2698 ivisurf->pending.prop.source_height = height;
2700 needs_commit = (ivisurf->event_mask == 0) ? 1 : 0;
2702 ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
2704 weston_log("resizing source rectangle of surface %u to %dx%d (%s)\n",
2705 ivisurf->id_surface, width,height,
2706 needs_commit ? "commiting it" : "no commit");
2709 ivi_layout_commit_changes();
2712 wl_signal_emit(&layout->surface_notification.configure_changed, ivisurf);
2717 ivi_layout_surface_set_content_observer(struct ivi_layout_surface *ivisurf,
2718 ivi_controller_surface_content_callback callback,
2721 int32_t ret = IVI_FAILED;
2723 if (ivisurf != NULL) {
2724 ivisurf->content_observer.callback = callback;
2725 ivisurf->content_observer.userdata = userdata;
2726 ret = IVI_SUCCEEDED;
2731 static struct ivi_layout_surface*
2732 ivi_layout_surface_create(struct weston_surface *wl_surface,
2733 uint32_t id_surface)
2735 struct ivi_layout *layout = get_layout_instance();
2736 struct ivi_layout_surface *ivisurf = NULL;
2738 if (wl_surface == NULL) {
2739 weston_log("ivi_layout_surface_create: invalid argument\n");
2743 ivisurf = get_surface(&layout->surface_list, id_surface);
2744 if (ivisurf != NULL) {
2745 if (ivisurf->surface != NULL) {
2746 weston_log("id_surface(%d) is already created\n", id_surface);
2751 ivisurf = calloc(1, sizeof *ivisurf);
2752 if (ivisurf == NULL) {
2753 weston_log("fails to allocate memory\n");
2757 wl_list_init(&ivisurf->link);
2758 wl_signal_init(&ivisurf->property_changed);
2759 wl_signal_init(&ivisurf->configured);
2760 wl_list_init(&ivisurf->layer_list);
2761 ivisurf->id_surface = id_surface;
2762 ivisurf->layout = layout;
2764 ivisurf->surface = wl_surface;
2765 ivisurf->surface_destroy_listener.notify =
2766 westonsurface_destroy_from_ivisurface;
2767 wl_resource_add_destroy_listener(wl_surface->resource,
2768 &ivisurf->surface_destroy_listener);
2770 ivisurf->view = weston_view_create(wl_surface);
2771 if (ivisurf->view == NULL) {
2772 weston_log("fails to allocate memory\n");
2775 ivisurf->surface->width_from_buffer = 0;
2776 ivisurf->surface->height_from_buffer = 0;
2778 weston_matrix_init(&ivisurf->surface_rotation.matrix);
2779 weston_matrix_init(&ivisurf->layer_rotation.matrix);
2780 weston_matrix_init(&ivisurf->surface_pos.matrix);
2781 weston_matrix_init(&ivisurf->layer_pos.matrix);
2782 weston_matrix_init(&ivisurf->scaling.matrix);
2784 wl_list_init(&ivisurf->surface_rotation.link);
2785 wl_list_init(&ivisurf->layer_rotation.link);
2786 wl_list_init(&ivisurf->surface_pos.link);
2787 wl_list_init(&ivisurf->layer_pos.link);
2788 wl_list_init(&ivisurf->scaling.link);
2790 init_surface_properties(&ivisurf->prop);
2791 ivisurf->event_mask = 0;
2793 ivisurf->pending.prop = ivisurf->prop;
2794 wl_list_init(&ivisurf->pending.link);
2796 wl_list_init(&ivisurf->order.link);
2797 wl_list_init(&ivisurf->order.layer_list);
2799 wl_list_insert(&layout->surface_list, &ivisurf->link);
2801 wl_signal_emit(&layout->surface_notification.created, ivisurf);
2806 static struct ivi_layout_surface*
2807 ivi_layout_surface_find(struct weston_surface *wl_surface)
2809 struct ivi_layout *layout = get_layout_instance();
2810 struct ivi_layout_surface *ivisurf;
2812 if (wl_surface != NULL) {
2813 wl_list_for_each(ivisurf, &layout->surface_list, link) {
2814 if (wl_surface == ivisurf->surface)
2823 background_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
2828 background_create(struct ivi_layout *layout, struct weston_output *output)
2830 struct ivi_background *bg;
2831 struct weston_surface *surface;
2832 struct weston_view *view;
2833 int32_t x1, y1, x2, y2;
2835 weston_log("creating background %d,%d %dx%d\n",
2836 output->x,output->y, output->width,output->height);
2838 if (output->width <= 0 || output->height <= 0)
2843 x2 = x1 + output->width;
2844 y2 = y1 + output->height;
2847 bg = calloc(1, sizeof(*bg));
2852 wl_list_init(&bg->link);
2855 surface = weston_surface_create(layout->compositor);
2856 if (surface == NULL) {
2861 view = weston_view_create(surface);
2863 weston_surface_destroy(surface);
2868 surface->configure = background_surface_configure;
2869 surface->configure_private = layout;
2871 weston_surface_set_color(surface,
2872 layout->background_color.red,
2873 layout->background_color.green,
2874 layout->background_color.blue,
2877 pixman_region32_fini(&surface->opaque);
2878 pixman_region32_init_rect(&surface->opaque, x1,y1, x2,y2);
2880 pixman_region32_fini(&surface->input);
2881 pixman_region32_init_rect(&surface->input, x1,y1, x2,y2);
2883 weston_surface_set_size(surface, output->width, output->height);
2885 wl_list_init(&bg->link);
2886 bg->surface = surface;
2889 wl_list_insert(&layout->background_list, &bg->link);
2891 weston_layer_entry_insert(&layout->background_layer.view_list,
2894 weston_view_set_position(view, x1,y1);
2895 // weston_view_geometry_dirty(view);
2896 weston_view_update_transform(view);
2897 weston_surface_damage(surface);
2901 static int parse_color(char **str_ptr, int separator, float *value_ptr)
2903 char *value_str = *str_ptr;
2907 while (*value_str == ' ' || *value_str == '\t')
2911 p = value_str + strlen(value_str);
2913 if (!(p = strchr(value_str, separator)))
2918 value = strtod(value_str, &e);
2920 if (e <= value_str || *e || value < 0.0 || value > 1.0)
2929 static void parse_background_color(struct ivi_layout *layout)
2931 struct weston_config_section *section;
2933 float red, green, blue;
2935 layout->background_color.red = 0.0;
2936 layout->background_color.green = 0.0;
2937 layout->background_color.blue = 0.0;
2939 section = weston_config_get_section(layout->compositor->config,
2940 "ivi-shell", NULL, NULL);
2941 if (section == NULL)
2944 weston_config_section_get_string(section, "background-color", &def, NULL);
2951 if (!parse_color(&p, ',', &red) ||
2952 !parse_color(&p, ',', &green) ||
2953 !parse_color(&p, 0, &blue) )
2954 weston_log("invalid background color definition: '%s'\n", def);
2956 layout->background_color.red = red;
2957 layout->background_color.green = green;
2958 layout->background_color.blue = blue;
2965 keyboard_grab_key(struct weston_keyboard_grab *grab, uint32_t time,
2966 uint32_t key, uint32_t state)
2968 struct ivi_layout *layout = get_layout_instance();
2969 struct weston_keyboard *keyboard = grab->keyboard;
2970 struct wl_display *display = keyboard->seat->compositor->wl_display;
2971 struct ivi_layout_surface *surf;
2972 struct wl_resource *resource;
2975 wl_list_for_each(surf, &layout->surface_list, link) {
2976 if (surf->prop.has_keyboard_focus) {
2977 resource = wl_resource_find_for_client(
2978 &keyboard->resource_list,
2979 wl_resource_get_client(surf->surface->resource));
2981 resource = wl_resource_find_for_client(
2982 &keyboard->focus_resource_list,
2983 wl_resource_get_client(surf->surface->resource));
2986 serial = wl_display_next_serial(display);
2987 wl_keyboard_send_key(resource, serial, time, key, state);
2989 weston_log("%s: No resource found for surface %d\n",
2990 __FUNCTION__, surf->id_surface);
2997 keyboard_grab_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
2998 uint32_t mods_depressed, uint32_t mods_latched,
2999 uint32_t mods_locked, uint32_t group)
3001 struct ivi_layout *layout = get_layout_instance();
3002 struct weston_keyboard *keyboard = grab->keyboard;
3003 struct ivi_layout_surface *surf;
3004 struct wl_resource *resource;
3005 int sent_to_pointer_client = 0;
3006 struct weston_pointer *pointer = keyboard->seat->pointer;
3008 /* Send modifiers to focussed surface */
3009 wl_list_for_each(surf, &layout->surface_list, link) {
3010 if (surf->prop.has_keyboard_focus) {
3011 resource = wl_resource_find_for_client(
3012 &keyboard->resource_list,
3013 wl_resource_get_client(surf->surface->resource));
3015 resource = wl_resource_find_for_client(
3016 &keyboard->focus_resource_list,
3017 wl_resource_get_client(surf->surface->resource));
3020 wl_keyboard_send_modifiers(resource, serial,
3022 mods_latched, mods_locked,
3024 if (pointer && pointer->focus
3025 && pointer->focus->surface->resource
3026 && pointer->focus->surface == surf->surface)
3027 sent_to_pointer_client = 1;
3029 weston_log("%s: No resource found for surface %d\n",
3030 __FUNCTION__, surf->id_surface);
3035 /* Send modifiers to pointer's client, if not already sent */
3036 if (!sent_to_pointer_client && pointer && pointer->focus
3037 && pointer->focus->surface->resource) {
3038 struct wl_client *pointer_client =
3039 wl_resource_get_client(pointer->focus->surface->resource);
3040 wl_resource_for_each(resource, &keyboard->resource_list) {
3041 if (wl_resource_get_client(resource) == pointer_client) {
3042 sent_to_pointer_client = 1;
3043 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
3044 mods_latched, mods_locked, group);
3049 if (!sent_to_pointer_client) {
3050 wl_resource_for_each(resource, &keyboard->focus_resource_list) {
3051 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
3052 mods_latched, mods_locked, group);
3060 keyboard_grab_cancel(struct weston_keyboard_grab *grab)
3064 static struct weston_keyboard_grab_interface keyboard_grab_interface = {
3066 keyboard_grab_modifiers,
3067 keyboard_grab_cancel
3071 handle_seat_updated_caps(struct wl_listener *listener, void *data)
3073 struct weston_seat *seat = data;
3074 struct seat_ctx *ctx = wl_container_of(listener, ctx,
3075 updated_caps_listener);
3076 if (seat->keyboard && seat->keyboard != ctx->grab.keyboard)
3077 weston_keyboard_start_grab(seat->keyboard, &ctx->grab);
3081 handle_seat_destroy(struct wl_listener *listener, void *data)
3083 struct seat_ctx *ctx = wl_container_of(listener, ctx, destroy_listener);
3084 if (ctx->grab.keyboard)
3085 keyboard_grab_cancel(&ctx->grab);
3091 handle_seat_create(struct wl_listener *listener, void *data)
3093 struct weston_seat *seat = data;
3095 struct seat_ctx *ctx = calloc(1, sizeof *ctx);
3097 weston_log("%s: failed to allocate memory\n", __FUNCTION__);
3101 ctx->grab.interface = &keyboard_grab_interface;
3103 ctx->destroy_listener.notify = &handle_seat_destroy;
3104 wl_signal_add(&seat->destroy_signal, &ctx->destroy_listener);
3106 ctx->updated_caps_listener.notify = &handle_seat_updated_caps;
3107 wl_signal_add(&seat->updated_caps_signal, &ctx->updated_caps_listener);
3111 ivi_layout_init_with_compositor(struct weston_compositor *ec)
3113 struct ivi_layout *layout = get_layout_instance();
3114 struct weston_output *output;
3115 struct weston_seat *seat;
3117 layout->compositor = ec;
3119 wl_list_init(&layout->surface_list);
3120 wl_list_init(&layout->layer_list);
3121 wl_list_init(&layout->screen_list);
3123 wl_signal_init(&layout->layer_notification.created);
3124 wl_signal_init(&layout->layer_notification.removed);
3126 wl_signal_init(&layout->surface_notification.created);
3127 wl_signal_init(&layout->surface_notification.removed);
3128 wl_signal_init(&layout->surface_notification.configure_changed);
3130 /* Add layout_layer at the last of weston_compositor.layer_list */
3131 weston_layer_init(&layout->layout_layer, ec->layer_list.prev);
3132 weston_layer_init(&layout->background_layer, ec->layer_list.prev);
3136 layout->transitions = ivi_layout_transition_set_create(ec);
3137 wl_list_init(&layout->pending_transition_list);
3139 /* Listen to seat creation, for grab purposes */
3140 layout->seat_create_listener.notify = &handle_seat_create;
3141 wl_signal_add(&ec->seat_created_signal, &layout->seat_create_listener);
3143 /* Handle existing seats */
3144 wl_list_for_each(seat, &ec->seat_list, link) {
3145 handle_seat_create(NULL, seat);
3146 wl_signal_emit(&seat->updated_caps_signal, seat);
3149 wl_list_init(&layout->background_list);
3150 parse_background_color(layout);
3151 wl_list_for_each(output, &ec->output_list, link)
3152 background_create(layout, output);
3157 ivi_layout_surface_add_configured_listener(struct ivi_layout_surface* ivisurf,
3158 struct wl_listener* listener)
3160 wl_signal_add(&ivisurf->configured, listener);
3164 WL_EXPORT struct ivi_layout_interface ivi_layout_interface = {
3165 .get_weston_surface = ivi_layout_get_weston_surface,
3166 .get_weston_view = ivi_layout_get_weston_view,
3167 .surface_configure = ivi_layout_surface_configure,
3168 .surface_create = ivi_layout_surface_create,
3169 .surface_find = ivi_layout_surface_find,
3170 .surface_add_notification = ivi_layout_surface_add_notification,
3171 .surface_remove_notification = ivi_layout_surface_remove_notification,
3172 .init_with_compositor = ivi_layout_init_with_compositor,
3173 .get_surface_dimension = ivi_layout_surface_get_dimension,
3174 .add_surface_configured_listener = ivi_layout_surface_add_configured_listener