blob: 8e0a9f1487a1d66d43a08027d41d0ae1b291678f [file] [log] [blame]
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001/*
2 * Copyright (C) 2013 DENSO CORPORATION
3 *
Bryce Harringtonaf637c22015-06-11 12:55:55 -07004 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090011 *
Bryce Harringtonaf637c22015-06-11 12:55:55 -070012 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090024 */
25
26/**
27 * Implementation of ivi-layout library. The actual view on ivi_screen is
28 * not updated till calling ivi_layout_commit_changes. A overview from
29 * calling API for updating properties of ivi_surface/ivi_layer to asking
30 * compositor to compose them by using weston_compositor_schedule_repaint,
31 * 0/ initialize this library by ivi_layout_init_with_compositor
32 * with (struct weston_compositor *ec) from ivi-shell.
33 * 1/ When a API for updating properties of ivi_surface/ivi_layer, it updates
34 * pending prop of ivi_surface/ivi_layer/ivi_screen which are structure to
35 * store properties.
36 * 2/ Before calling commitChanges, in case of calling a API to get a property,
37 * return current property, not pending property.
38 * 3/ At the timing of calling ivi_layout_commitChanges, pending properties
39 * are applied to properties.
40 *
41 * *) ivi_layout_commitChanges is also called by transition animation
42 * per each frame. See ivi-layout-transition.c in details. Transition
43 * animation interpolates frames between previous properties of ivi_surface
44 * and new ones.
45 * For example, when a property of ivi_surface is changed from invisibility
46 * to visibility, it behaves like fade-in. When ivi_layout_commitChange is
47 * called during transition animation, it cancels the transition and
48 * re-start transition to new properties from current properties of final
49 * frame just before the the cancellation.
50 *
51 * 4/ According properties, set transformation by using weston_matrix and
52 * weston_view per ivi_surfaces and ivi_layers in while loop.
53 * 5/ Set damage and trigger transform by using weston_view_geometry_dirty.
54 * 6/ Notify update of properties.
55 * 7/ Trigger composition by weston_compositor_schedule_repaint.
56 *
57 */
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +090058#include "config.h"
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090059
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090060#include <string.h>
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090061
62#include "compositor.h"
63#include "ivi-layout-export.h"
64#include "ivi-layout-private.h"
65
Jon Cruz867d50e2015-06-15 15:37:10 -070066#include "shared/helpers.h"
Jon Cruz4678bab2015-06-15 15:37:07 -070067#include "shared/os-compatibility.h"
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +090068
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090069struct link_layer {
70 struct ivi_layout_layer *ivilayer;
71 struct wl_list link;
72 struct wl_list link_to_layer;
73};
74
75struct link_screen {
76 struct ivi_layout_screen *iviscrn;
77 struct wl_list link;
78 struct wl_list link_to_screen;
79};
80
81struct listener_layout_notification {
82 void *userdata;
83 struct wl_listener listener;
84};
85
86struct ivi_layout;
87
88struct ivi_layout_screen {
89 struct wl_list link;
90 struct wl_list link_to_layer;
91 uint32_t id_screen;
92
93 struct ivi_layout *layout;
94 struct weston_output *output;
95
96 uint32_t event_mask;
97
98 struct {
99 struct wl_list layer_list;
100 struct wl_list link;
101 } pending;
102
103 struct {
104 struct wl_list layer_list;
105 struct wl_list link;
106 } order;
107};
108
109struct ivi_layout_notification_callback {
110 void *callback;
111 void *data;
112};
113
Nobuhiko Tanibata82051702015-06-22 15:31:26 +0900114static void
115remove_notification(struct wl_list *listener_list, void *callback, void *userdata);
116
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900117static struct ivi_layout ivilayout = {0};
118
119struct ivi_layout *
120get_instance(void)
121{
122 return &ivilayout;
123}
124
125/**
126 * Internal API to add/remove a link to ivi_surface from ivi_layer.
127 */
128static void
129add_link_to_surface(struct ivi_layout_layer *ivilayer,
130 struct link_layer *link_layer)
131{
132 struct link_layer *link = NULL;
133
134 wl_list_for_each(link, &ivilayer->link_to_surface, link_to_layer) {
135 if (link == link_layer)
136 return;
137 }
138
139 wl_list_insert(&ivilayer->link_to_surface, &link_layer->link_to_layer);
140}
141
142static void
143remove_link_to_surface(struct ivi_layout_layer *ivilayer)
144{
145 struct link_layer *link = NULL;
146 struct link_layer *next = NULL;
147
148 wl_list_for_each_safe(link, next, &ivilayer->link_to_surface, link_to_layer) {
149 if (!wl_list_empty(&link->link_to_layer)) {
150 wl_list_remove(&link->link_to_layer);
151 }
152 if (!wl_list_empty(&link->link)) {
153 wl_list_remove(&link->link);
154 }
155 free(link);
156 }
157
158 wl_list_init(&ivilayer->link_to_surface);
159}
160
161/**
162 * Internal API to add a link to ivi_layer from ivi_screen.
163 */
164static void
165add_link_to_layer(struct ivi_layout_screen *iviscrn,
166 struct link_screen *link_screen)
167{
168 wl_list_init(&link_screen->link_to_screen);
169 wl_list_insert(&iviscrn->link_to_layer, &link_screen->link_to_screen);
170}
171
172/**
173 * Internal API to add/remove a ivi_surface from ivi_layer.
174 */
175static void
176add_ordersurface_to_layer(struct ivi_layout_surface *ivisurf,
177 struct ivi_layout_layer *ivilayer)
178{
179 struct link_layer *link_layer = NULL;
180
181 link_layer = malloc(sizeof *link_layer);
182 if (link_layer == NULL) {
183 weston_log("fails to allocate memory\n");
184 return;
185 }
186
187 link_layer->ivilayer = ivilayer;
188 wl_list_init(&link_layer->link);
189 wl_list_insert(&ivisurf->layer_list, &link_layer->link);
190 add_link_to_surface(ivilayer, link_layer);
191}
192
193static void
194remove_ordersurface_from_layer(struct ivi_layout_surface *ivisurf)
195{
196 struct link_layer *link_layer = NULL;
197 struct link_layer *next = NULL;
198
199 wl_list_for_each_safe(link_layer, next, &ivisurf->layer_list, link) {
200 if (!wl_list_empty(&link_layer->link)) {
201 wl_list_remove(&link_layer->link);
202 }
203 if (!wl_list_empty(&link_layer->link_to_layer)) {
204 wl_list_remove(&link_layer->link_to_layer);
205 }
206 free(link_layer);
207 }
208 wl_list_init(&ivisurf->layer_list);
209}
210
211/**
212 * Internal API to add/remove a ivi_layer to/from ivi_screen.
213 */
214static void
215add_orderlayer_to_screen(struct ivi_layout_layer *ivilayer,
216 struct ivi_layout_screen *iviscrn)
217{
218 struct link_screen *link_scrn = NULL;
219
220 link_scrn = malloc(sizeof *link_scrn);
221 if (link_scrn == NULL) {
222 weston_log("fails to allocate memory\n");
223 return;
224 }
225
226 link_scrn->iviscrn = iviscrn;
227 wl_list_init(&link_scrn->link);
228 wl_list_insert(&ivilayer->screen_list, &link_scrn->link);
229 add_link_to_layer(iviscrn, link_scrn);
230}
231
232static void
233remove_orderlayer_from_screen(struct ivi_layout_layer *ivilayer)
234{
235 struct link_screen *link_scrn = NULL;
236 struct link_screen *next = NULL;
237
238 wl_list_for_each_safe(link_scrn, next, &ivilayer->screen_list, link) {
239 if (!wl_list_empty(&link_scrn->link)) {
240 wl_list_remove(&link_scrn->link);
241 }
242 if (!wl_list_empty(&link_scrn->link_to_screen)) {
243 wl_list_remove(&link_scrn->link_to_screen);
244 }
245 free(link_scrn);
246 }
247 wl_list_init(&ivilayer->screen_list);
248}
249
250/**
251 * Internal API to add/remove a ivi_layer to/from ivi_screen.
252 */
253static struct ivi_layout_surface *
254get_surface(struct wl_list *surf_list, uint32_t id_surface)
255{
256 struct ivi_layout_surface *ivisurf;
257
258 wl_list_for_each(ivisurf, surf_list, link) {
259 if (ivisurf->id_surface == id_surface) {
260 return ivisurf;
261 }
262 }
263
264 return NULL;
265}
266
267static struct ivi_layout_layer *
268get_layer(struct wl_list *layer_list, uint32_t id_layer)
269{
270 struct ivi_layout_layer *ivilayer;
271
272 wl_list_for_each(ivilayer, layer_list, link) {
273 if (ivilayer->id_layer == id_layer) {
274 return ivilayer;
275 }
276 }
277
278 return NULL;
279}
280
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900281static void
282remove_configured_listener(struct ivi_layout_surface *ivisurf)
283{
284 struct wl_listener *link = NULL;
285 struct wl_listener *next = NULL;
286
287 wl_list_for_each_safe(link, next, &ivisurf->configured.listener_list, link) {
288 wl_list_remove(&link->link);
289 }
290}
291
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900292static void
293remove_all_notification(struct wl_list *listener_list)
294{
295 struct wl_listener *listener = NULL;
296 struct wl_listener *next = NULL;
297
298 wl_list_for_each_safe(listener, next, listener_list, link) {
299 struct listener_layout_notification *notification = NULL;
300 if (!wl_list_empty(&listener->link)) {
301 wl_list_remove(&listener->link);
302 }
303
304 notification =
305 container_of(listener,
306 struct listener_layout_notification,
307 listener);
308
309 free(notification->userdata);
310 free(notification);
311 }
312}
313
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900314static void
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900315ivi_layout_surface_remove_notification(struct ivi_layout_surface *ivisurf)
316{
317 if (ivisurf == NULL) {
318 weston_log("ivi_layout_surface_remove_notification: invalid argument\n");
319 return;
320 }
321
322 remove_all_notification(&ivisurf->property_changed.listener_list);
323}
324
Nobuhiko Tanibata82051702015-06-22 15:31:26 +0900325static void
326ivi_layout_surface_remove_notification_by_callback(struct ivi_layout_surface *ivisurf,
327 surface_property_notification_func callback,
328 void *userdata)
329{
330 if (ivisurf == NULL) {
331 weston_log("ivi_layout_surface_remove_notification_by_callback: invalid argument\n");
332 return;
333 }
334
335 remove_notification(&ivisurf->property_changed.listener_list, callback, userdata);
336}
337
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900338/**
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900339 * Called at destruction of wl_surface/ivi_surface
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900340 */
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900341void
342ivi_layout_surface_destroy(struct ivi_layout_surface *ivisurf)
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900343{
344 struct ivi_layout *layout = get_instance();
345
346 if (ivisurf == NULL) {
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900347 weston_log("%s: invalid argument\n", __func__);
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900348 return;
349 }
350
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900351 wl_list_remove(&ivisurf->pending.link);
352 wl_list_remove(&ivisurf->order.link);
353 wl_list_remove(&ivisurf->link);
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900354 remove_ordersurface_from_layer(ivisurf);
355
356 wl_signal_emit(&layout->surface_notification.removed, ivisurf);
357
358 remove_configured_listener(ivisurf);
359
360 ivi_layout_surface_remove_notification(ivisurf);
361
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900362 free(ivisurf);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900363}
364
365/**
366 * Internal API to check ivi_layer/ivi_surface already added in ivi_layer/ivi_screen.
367 * Called by ivi_layout_layer_add_surface/ivi_layout_screenAddLayer
368 */
369static int
370is_surface_in_layer(struct ivi_layout_surface *ivisurf,
371 struct ivi_layout_layer *ivilayer)
372{
373 struct ivi_layout_surface *surf = NULL;
374
375 wl_list_for_each(surf, &ivilayer->pending.surface_list, pending.link) {
376 if (surf->id_surface == ivisurf->id_surface) {
377 return 1;
378 }
379 }
380
381 return 0;
382}
383
384static int
385is_layer_in_screen(struct ivi_layout_layer *ivilayer,
386 struct ivi_layout_screen *iviscrn)
387{
388 struct ivi_layout_layer *layer = NULL;
389
390 wl_list_for_each(layer, &iviscrn->pending.layer_list, pending.link) {
391 if (layer->id_layer == ivilayer->id_layer) {
392 return 1;
393 }
394 }
395
396 return 0;
397}
398
399/**
400 * Internal API to initialize ivi_screens found from output_list of weston_compositor.
401 * Called by ivi_layout_init_with_compositor.
402 */
403static void
404create_screen(struct weston_compositor *ec)
405{
406 struct ivi_layout *layout = get_instance();
407 struct ivi_layout_screen *iviscrn = NULL;
408 struct weston_output *output = NULL;
409 int32_t count = 0;
410
411 wl_list_for_each(output, &ec->output_list, link) {
412 iviscrn = calloc(1, sizeof *iviscrn);
413 if (iviscrn == NULL) {
414 weston_log("fails to allocate memory\n");
415 continue;
416 }
417
418 wl_list_init(&iviscrn->link);
419 iviscrn->layout = layout;
420
421 iviscrn->id_screen = count;
422 count++;
423
424 iviscrn->output = output;
425 iviscrn->event_mask = 0;
426
427 wl_list_init(&iviscrn->pending.layer_list);
428 wl_list_init(&iviscrn->pending.link);
429
430 wl_list_init(&iviscrn->order.layer_list);
431 wl_list_init(&iviscrn->order.link);
432
433 wl_list_init(&iviscrn->link_to_layer);
434
435 wl_list_insert(&layout->screen_list, &iviscrn->link);
436 }
437}
438
439/**
440 * Internal APIs to initialize properties of ivi_surface/ivi_layer when they are created.
441 */
442static void
443init_layer_properties(struct ivi_layout_layer_properties *prop,
444 int32_t width, int32_t height)
445{
446 memset(prop, 0, sizeof *prop);
447 prop->opacity = wl_fixed_from_double(1.0);
448 prop->source_width = width;
449 prop->source_height = height;
450 prop->dest_width = width;
451 prop->dest_height = height;
452}
453
454static void
455init_surface_properties(struct ivi_layout_surface_properties *prop)
456{
457 memset(prop, 0, sizeof *prop);
458 prop->opacity = wl_fixed_from_double(1.0);
Nobuhiko Tanibatae259a7a2015-04-27 17:02:54 +0900459 /*
460 * FIXME: this shall be finxed by ivi-layout-transition.
461 */
462 prop->dest_width = 1;
463 prop->dest_height = 1;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900464}
465
466/**
467 * Internal APIs to be called from ivi_layout_commit_changes.
468 */
469static void
470update_opacity(struct ivi_layout_layer *ivilayer,
471 struct ivi_layout_surface *ivisurf)
472{
473 double layer_alpha = wl_fixed_to_double(ivilayer->prop.opacity);
474 double surf_alpha = wl_fixed_to_double(ivisurf->prop.opacity);
475
476 if ((ivilayer->event_mask & IVI_NOTIFICATION_OPACITY) ||
477 (ivisurf->event_mask & IVI_NOTIFICATION_OPACITY)) {
478 struct weston_view *tmpview = NULL;
479 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
480 if (tmpview == NULL) {
481 continue;
482 }
483 tmpview->alpha = layer_alpha * surf_alpha;
484 }
485 }
486}
487
488static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900489update_prop(struct ivi_layout_layer *ivilayer,
490 struct ivi_layout_surface *ivisurf)
491{
Nobuhiko Tanibata4c1dbf72015-07-15 13:55:50 +0900492 struct weston_view *tmpview;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900493
Nobuhiko Tanibata4c1dbf72015-07-15 13:55:50 +0900494 if (!ivilayer->event_mask && !ivisurf->event_mask) {
495 return;
496 }
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900497
Nobuhiko Tanibata4c1dbf72015-07-15 13:55:50 +0900498 update_opacity(ivilayer, ivisurf);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900499
Nobuhiko Tanibata4c1dbf72015-07-15 13:55:50 +0900500 ivisurf->update_count++;
501
502 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900503 if (tmpview != NULL) {
Nobuhiko Tanibata4c1dbf72015-07-15 13:55:50 +0900504 break;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900505 }
Nobuhiko Tanibata4c1dbf72015-07-15 13:55:50 +0900506 }
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900507
Nobuhiko Tanibata4c1dbf72015-07-15 13:55:50 +0900508 if (tmpview != NULL) {
509 weston_view_geometry_dirty(tmpview);
510 }
511
512 if (ivisurf->surface != NULL) {
513 weston_surface_damage(ivisurf->surface);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900514 }
515}
516
517static void
518commit_changes(struct ivi_layout *layout)
519{
520 struct ivi_layout_screen *iviscrn = NULL;
521 struct ivi_layout_layer *ivilayer = NULL;
522 struct ivi_layout_surface *ivisurf = NULL;
523
524 wl_list_for_each(iviscrn, &layout->screen_list, link) {
525 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
526 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
527 update_prop(ivilayer, ivisurf);
528 }
529 }
530 }
531}
532
533static void
534commit_surface_list(struct ivi_layout *layout)
535{
536 struct ivi_layout_surface *ivisurf = NULL;
537 int32_t dest_x = 0;
538 int32_t dest_y = 0;
539 int32_t dest_width = 0;
540 int32_t dest_height = 0;
541 int32_t configured = 0;
542
543 wl_list_for_each(ivisurf, &layout->surface_list, link) {
544 if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEFAULT) {
545 dest_x = ivisurf->prop.dest_x;
546 dest_y = ivisurf->prop.dest_y;
547 dest_width = ivisurf->prop.dest_width;
548 dest_height = ivisurf->prop.dest_height;
549
550 ivi_layout_transition_move_resize_view(ivisurf,
551 ivisurf->pending.prop.dest_x,
552 ivisurf->pending.prop.dest_y,
553 ivisurf->pending.prop.dest_width,
554 ivisurf->pending.prop.dest_height,
555 ivisurf->pending.prop.transition_duration);
556
557 if(ivisurf->pending.prop.visibility) {
558 ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
559 } else {
560 ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
561 }
562
563 ivisurf->prop = ivisurf->pending.prop;
564 ivisurf->prop.dest_x = dest_x;
565 ivisurf->prop.dest_y = dest_y;
566 ivisurf->prop.dest_width = dest_width;
567 ivisurf->prop.dest_height = dest_height;
568 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
569 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
570
571 } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY){
572 dest_x = ivisurf->prop.dest_x;
573 dest_y = ivisurf->prop.dest_y;
574 dest_width = ivisurf->prop.dest_width;
575 dest_height = ivisurf->prop.dest_height;
576
577 ivi_layout_transition_move_resize_view(ivisurf,
578 ivisurf->pending.prop.dest_x,
579 ivisurf->pending.prop.dest_y,
580 ivisurf->pending.prop.dest_width,
581 ivisurf->pending.prop.dest_height,
582 ivisurf->pending.prop.transition_duration);
583
584 ivisurf->prop = ivisurf->pending.prop;
585 ivisurf->prop.dest_x = dest_x;
586 ivisurf->prop.dest_y = dest_y;
587 ivisurf->prop.dest_width = dest_width;
588 ivisurf->prop.dest_height = dest_height;
589
590 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
591 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
592
593 } else if(ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY){
594 configured = 0;
595 if(ivisurf->pending.prop.visibility) {
596 ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
597 } else {
598 ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
599 }
600
601 if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
602 ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
603 configured = 1;
604 }
605
606 ivisurf->prop = ivisurf->pending.prop;
607 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
608 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
609
610 if (configured && !is_surface_transition(ivisurf))
611 wl_signal_emit(&ivisurf->configured, ivisurf);
612 } else {
613 configured = 0;
614 if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
615 ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
616 configured = 1;
617 }
618
619 ivisurf->prop = ivisurf->pending.prop;
620 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
621 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
622
623 if (configured && !is_surface_transition(ivisurf))
624 wl_signal_emit(&ivisurf->configured, ivisurf);
625 }
626 }
627}
628
629static void
630commit_layer_list(struct ivi_layout *layout)
631{
632 struct ivi_layout_layer *ivilayer = NULL;
633 struct ivi_layout_surface *ivisurf = NULL;
634 struct ivi_layout_surface *next = NULL;
635
636 wl_list_for_each(ivilayer, &layout->layer_list, link) {
637 if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_MOVE) {
638 ivi_layout_transition_move_layer(ivilayer, ivilayer->pending.prop.dest_x, ivilayer->pending.prop.dest_y, ivilayer->pending.prop.transition_duration);
639 } else if(ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_FADE) {
640 ivi_layout_transition_fade_layer(ivilayer,ivilayer->pending.prop.is_fade_in,
641 ivilayer->pending.prop.start_alpha,ivilayer->pending.prop.end_alpha,
642 NULL, NULL,
643 ivilayer->pending.prop.transition_duration);
644 }
645 ivilayer->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
646
647 ivilayer->prop = ivilayer->pending.prop;
648
649 if (!(ivilayer->event_mask &
650 (IVI_NOTIFICATION_ADD | IVI_NOTIFICATION_REMOVE)) ) {
651 continue;
652 }
653
654 if (ivilayer->event_mask & IVI_NOTIFICATION_REMOVE) {
655 wl_list_for_each_safe(ivisurf, next,
656 &ivilayer->order.surface_list, order.link) {
657 remove_ordersurface_from_layer(ivisurf);
658
659 if (!wl_list_empty(&ivisurf->order.link)) {
660 wl_list_remove(&ivisurf->order.link);
661 }
662
663 wl_list_init(&ivisurf->order.link);
664 ivisurf->event_mask |= IVI_NOTIFICATION_REMOVE;
665 }
666
667 wl_list_init(&ivilayer->order.surface_list);
668 }
669
670 if (ivilayer->event_mask & IVI_NOTIFICATION_ADD) {
671 wl_list_for_each_safe(ivisurf, next,
672 &ivilayer->order.surface_list, order.link) {
673 remove_ordersurface_from_layer(ivisurf);
674
675 if (!wl_list_empty(&ivisurf->order.link)) {
676 wl_list_remove(&ivisurf->order.link);
677 }
678
679 wl_list_init(&ivisurf->order.link);
680 }
681
682 wl_list_init(&ivilayer->order.surface_list);
683 wl_list_for_each(ivisurf, &ivilayer->pending.surface_list,
684 pending.link) {
685 if(!wl_list_empty(&ivisurf->order.link)){
686 wl_list_remove(&ivisurf->order.link);
687 wl_list_init(&ivisurf->order.link);
688 }
689
690 wl_list_insert(&ivilayer->order.surface_list,
691 &ivisurf->order.link);
692 add_ordersurface_to_layer(ivisurf, ivilayer);
693 ivisurf->event_mask |= IVI_NOTIFICATION_ADD;
694 }
695 }
696 }
697}
698
699static void
700commit_screen_list(struct ivi_layout *layout)
701{
702 struct ivi_layout_screen *iviscrn = NULL;
703 struct ivi_layout_layer *ivilayer = NULL;
704 struct ivi_layout_layer *next = NULL;
705 struct ivi_layout_surface *ivisurf = NULL;
706
707 wl_list_for_each(iviscrn, &layout->screen_list, link) {
708 if (iviscrn->event_mask & IVI_NOTIFICATION_REMOVE) {
709 wl_list_for_each_safe(ivilayer, next,
710 &iviscrn->order.layer_list, order.link) {
711 remove_orderlayer_from_screen(ivilayer);
712
713 if (!wl_list_empty(&ivilayer->order.link)) {
714 wl_list_remove(&ivilayer->order.link);
715 }
716
717 wl_list_init(&ivilayer->order.link);
718 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
719 }
720 }
721
722 if (iviscrn->event_mask & IVI_NOTIFICATION_ADD) {
723 wl_list_for_each_safe(ivilayer, next,
724 &iviscrn->order.layer_list, order.link) {
725 remove_orderlayer_from_screen(ivilayer);
726
727 if (!wl_list_empty(&ivilayer->order.link)) {
728 wl_list_remove(&ivilayer->order.link);
729 }
730
731 wl_list_init(&ivilayer->order.link);
732 }
733
734 wl_list_init(&iviscrn->order.layer_list);
735 wl_list_for_each(ivilayer, &iviscrn->pending.layer_list,
736 pending.link) {
737 wl_list_insert(&iviscrn->order.layer_list,
738 &ivilayer->order.link);
739 add_orderlayer_to_screen(ivilayer, iviscrn);
740 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
741 }
742 }
743
744 iviscrn->event_mask = 0;
745
746 /* Clear view list of layout ivi_layer */
747 wl_list_init(&layout->layout_layer.view_list.link);
748
749 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
750 if (ivilayer->prop.visibility == false)
751 continue;
752
753 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
754 struct weston_view *tmpview = NULL;
755 wl_list_for_each(tmpview, &ivisurf->surface->views, surface_link) {
756 if (tmpview != NULL) {
757 break;
758 }
759 }
760
761 if (ivisurf->prop.visibility == false)
762 continue;
763 if (ivisurf->surface == NULL || tmpview == NULL)
764 continue;
765
766 weston_layer_entry_insert(&layout->layout_layer.view_list,
767 &tmpview->layer_link);
768
769 ivisurf->surface->output = iviscrn->output;
770 }
771 }
772
773 break;
774 }
775}
776
777static void
778commit_transition(struct ivi_layout* layout)
779{
780 if(wl_list_empty(&layout->pending_transition_list)){
781 return;
782 }
783
784 wl_list_insert_list(&layout->transitions->transition_list,
785 &layout->pending_transition_list);
786
787 wl_list_init(&layout->pending_transition_list);
788
789 wl_event_source_timer_update(layout->transitions->event_source, 1);
790}
791
792static void
793send_surface_prop(struct ivi_layout_surface *ivisurf)
794{
795 wl_signal_emit(&ivisurf->property_changed, ivisurf);
796 ivisurf->event_mask = 0;
797}
798
799static void
800send_layer_prop(struct ivi_layout_layer *ivilayer)
801{
802 wl_signal_emit(&ivilayer->property_changed, ivilayer);
803 ivilayer->event_mask = 0;
804}
805
806static void
807send_prop(struct ivi_layout *layout)
808{
809 struct ivi_layout_layer *ivilayer = NULL;
810 struct ivi_layout_surface *ivisurf = NULL;
811
812 wl_list_for_each_reverse(ivilayer, &layout->layer_list, link) {
Nobuhiko Tanibata6ce3ef82015-06-22 15:32:06 +0900813 if (ivilayer->event_mask)
814 send_layer_prop(ivilayer);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900815 }
816
817 wl_list_for_each_reverse(ivisurf, &layout->surface_list, link) {
Nobuhiko Tanibata6ce3ef82015-06-22 15:32:06 +0900818 if (ivisurf->event_mask)
819 send_surface_prop(ivisurf);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900820 }
821}
822
823static void
824clear_surface_pending_list(struct ivi_layout_layer *ivilayer)
825{
826 struct ivi_layout_surface *surface_link = NULL;
827 struct ivi_layout_surface *surface_next = NULL;
828
829 wl_list_for_each_safe(surface_link, surface_next,
830 &ivilayer->pending.surface_list, pending.link) {
831 if (!wl_list_empty(&surface_link->pending.link)) {
832 wl_list_remove(&surface_link->pending.link);
833 }
834
835 wl_list_init(&surface_link->pending.link);
836 }
837
838 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
839}
840
841static void
842clear_surface_order_list(struct ivi_layout_layer *ivilayer)
843{
844 struct ivi_layout_surface *surface_link = NULL;
845 struct ivi_layout_surface *surface_next = NULL;
846
847 wl_list_for_each_safe(surface_link, surface_next,
848 &ivilayer->order.surface_list, order.link) {
849 if (!wl_list_empty(&surface_link->order.link)) {
850 wl_list_remove(&surface_link->order.link);
851 }
852
853 wl_list_init(&surface_link->order.link);
854 }
855
856 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
857}
858
859static void
860layer_created(struct wl_listener *listener, void *data)
861{
862 struct ivi_layout_layer *ivilayer = data;
863
864 struct listener_layout_notification *notification =
865 container_of(listener,
866 struct listener_layout_notification,
867 listener);
868
869 struct ivi_layout_notification_callback *created_callback =
870 notification->userdata;
871
872 ((layer_create_notification_func)created_callback->callback)
873 (ivilayer, created_callback->data);
874}
875
876static void
877layer_removed(struct wl_listener *listener, void *data)
878{
879 struct ivi_layout_layer *ivilayer = data;
880
881 struct listener_layout_notification *notification =
882 container_of(listener,
883 struct listener_layout_notification,
884 listener);
885
886 struct ivi_layout_notification_callback *removed_callback =
887 notification->userdata;
888
889 ((layer_remove_notification_func)removed_callback->callback)
890 (ivilayer, removed_callback->data);
891}
892
893static void
894layer_prop_changed(struct wl_listener *listener, void *data)
895{
896 struct ivi_layout_layer *ivilayer = data;
897
898 struct listener_layout_notification *layout_listener =
899 container_of(listener,
900 struct listener_layout_notification,
901 listener);
902
903 struct ivi_layout_notification_callback *prop_callback =
904 layout_listener->userdata;
905
906 ((layer_property_notification_func)prop_callback->callback)
907 (ivilayer, &ivilayer->prop, ivilayer->event_mask, prop_callback->data);
908}
909
910static void
911surface_created(struct wl_listener *listener, void *data)
912{
913 struct ivi_layout_surface *ivisurface = data;
914
915 struct listener_layout_notification *notification =
916 container_of(listener,
917 struct listener_layout_notification,
918 listener);
919
920 struct ivi_layout_notification_callback *created_callback =
921 notification->userdata;
922
923 ((surface_create_notification_func)created_callback->callback)
924 (ivisurface, created_callback->data);
925}
926
927static void
928surface_removed(struct wl_listener *listener, void *data)
929{
930 struct ivi_layout_surface *ivisurface = data;
931
932 struct listener_layout_notification *notification =
933 container_of(listener,
934 struct listener_layout_notification,
935 listener);
936
937 struct ivi_layout_notification_callback *removed_callback =
938 notification->userdata;
939
940 ((surface_remove_notification_func)removed_callback->callback)
941 (ivisurface, removed_callback->data);
942}
943
944static void
945surface_prop_changed(struct wl_listener *listener, void *data)
946{
947 struct ivi_layout_surface *ivisurf = data;
948
949 struct listener_layout_notification *layout_listener =
950 container_of(listener,
951 struct listener_layout_notification,
952 listener);
953
954 struct ivi_layout_notification_callback *prop_callback =
955 layout_listener->userdata;
956
957 ((surface_property_notification_func)prop_callback->callback)
958 (ivisurf, &ivisurf->prop, ivisurf->event_mask, prop_callback->data);
959
960 ivisurf->event_mask = 0;
961}
962
963static void
964surface_configure_changed(struct wl_listener *listener,
965 void *data)
966{
967 struct ivi_layout_surface *ivisurface = data;
968
969 struct listener_layout_notification *notification =
970 container_of(listener,
971 struct listener_layout_notification,
972 listener);
973
974 struct ivi_layout_notification_callback *configure_changed_callback =
975 notification->userdata;
976
977 ((surface_configure_notification_func)configure_changed_callback->callback)
978 (ivisurface, configure_changed_callback->data);
979}
980
981static int32_t
982add_notification(struct wl_signal *signal,
983 wl_notify_func_t callback,
984 void *userdata)
985{
986 struct listener_layout_notification *notification = NULL;
987
988 notification = malloc(sizeof *notification);
989 if (notification == NULL) {
990 weston_log("fails to allocate memory\n");
991 free(userdata);
992 return IVI_FAILED;
993 }
994
995 notification->listener.notify = callback;
996 notification->userdata = userdata;
997
998 wl_signal_add(signal, &notification->listener);
999
1000 return IVI_SUCCEEDED;
1001}
1002
1003static void
1004remove_notification(struct wl_list *listener_list, void *callback, void *userdata)
1005{
1006 struct wl_listener *listener = NULL;
1007 struct wl_listener *next = NULL;
1008
1009 wl_list_for_each_safe(listener, next, listener_list, link) {
1010 struct listener_layout_notification *notification =
1011 container_of(listener,
1012 struct listener_layout_notification,
1013 listener);
1014
1015 struct ivi_layout_notification_callback *notification_callback =
1016 notification->userdata;
1017
1018 if ((notification_callback->callback != callback) ||
1019 (notification_callback->data != userdata)) {
1020 continue;
1021 }
1022
1023 if (!wl_list_empty(&listener->link)) {
1024 wl_list_remove(&listener->link);
1025 }
1026
1027 free(notification->userdata);
1028 free(notification);
1029 }
1030}
1031
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001032/**
1033 * Exported APIs of ivi-layout library are implemented from here.
1034 * Brief of APIs is described in ivi-layout-export.h.
1035 */
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001036static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001037ivi_layout_add_notification_create_layer(layer_create_notification_func callback,
1038 void *userdata)
1039{
1040 struct ivi_layout *layout = get_instance();
1041 struct ivi_layout_notification_callback *created_callback = NULL;
1042
1043 if (callback == NULL) {
1044 weston_log("ivi_layout_add_notification_create_layer: invalid argument\n");
1045 return IVI_FAILED;
1046 }
1047
1048 created_callback = malloc(sizeof *created_callback);
1049 if (created_callback == NULL) {
1050 weston_log("fails to allocate memory\n");
1051 return IVI_FAILED;
1052 }
1053
1054 created_callback->callback = callback;
1055 created_callback->data = userdata;
1056
1057 return add_notification(&layout->layer_notification.created,
1058 layer_created,
1059 created_callback);
1060}
1061
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001062static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001063ivi_layout_remove_notification_create_layer(layer_create_notification_func callback,
1064 void *userdata)
1065{
1066 struct ivi_layout *layout = get_instance();
1067 remove_notification(&layout->layer_notification.created.listener_list, callback, userdata);
1068}
1069
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001070static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001071ivi_layout_add_notification_remove_layer(layer_remove_notification_func callback,
1072 void *userdata)
1073{
1074 struct ivi_layout *layout = get_instance();
1075 struct ivi_layout_notification_callback *removed_callback = NULL;
1076
1077 if (callback == NULL) {
1078 weston_log("ivi_layout_add_notification_remove_layer: invalid argument\n");
1079 return IVI_FAILED;
1080 }
1081
1082 removed_callback = malloc(sizeof *removed_callback);
1083 if (removed_callback == NULL) {
1084 weston_log("fails to allocate memory\n");
1085 return IVI_FAILED;
1086 }
1087
1088 removed_callback->callback = callback;
1089 removed_callback->data = userdata;
1090 return add_notification(&layout->layer_notification.removed,
1091 layer_removed,
1092 removed_callback);
1093}
1094
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001095static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001096ivi_layout_remove_notification_remove_layer(layer_remove_notification_func callback,
1097 void *userdata)
1098{
1099 struct ivi_layout *layout = get_instance();
1100 remove_notification(&layout->layer_notification.removed.listener_list, callback, userdata);
1101}
1102
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001103static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001104ivi_layout_add_notification_create_surface(surface_create_notification_func callback,
1105 void *userdata)
1106{
1107 struct ivi_layout *layout = get_instance();
1108 struct ivi_layout_notification_callback *created_callback = NULL;
1109
1110 if (callback == NULL) {
1111 weston_log("ivi_layout_add_notification_create_surface: invalid argument\n");
1112 return IVI_FAILED;
1113 }
1114
1115 created_callback = malloc(sizeof *created_callback);
1116 if (created_callback == NULL) {
1117 weston_log("fails to allocate memory\n");
1118 return IVI_FAILED;
1119 }
1120
1121 created_callback->callback = callback;
1122 created_callback->data = userdata;
1123
1124 return add_notification(&layout->surface_notification.created,
1125 surface_created,
1126 created_callback);
1127}
1128
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001129static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001130ivi_layout_remove_notification_create_surface(surface_create_notification_func callback,
1131 void *userdata)
1132{
1133 struct ivi_layout *layout = get_instance();
1134 remove_notification(&layout->surface_notification.created.listener_list, callback, userdata);
1135}
1136
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001137static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001138ivi_layout_add_notification_remove_surface(surface_remove_notification_func callback,
1139 void *userdata)
1140{
1141 struct ivi_layout *layout = get_instance();
1142 struct ivi_layout_notification_callback *removed_callback = NULL;
1143
1144 if (callback == NULL) {
1145 weston_log("ivi_layout_add_notification_remove_surface: invalid argument\n");
1146 return IVI_FAILED;
1147 }
1148
1149 removed_callback = malloc(sizeof *removed_callback);
1150 if (removed_callback == NULL) {
1151 weston_log("fails to allocate memory\n");
1152 return IVI_FAILED;
1153 }
1154
1155 removed_callback->callback = callback;
1156 removed_callback->data = userdata;
1157
1158 return add_notification(&layout->surface_notification.removed,
1159 surface_removed,
1160 removed_callback);
1161}
1162
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001163static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001164ivi_layout_remove_notification_remove_surface(surface_remove_notification_func callback,
1165 void *userdata)
1166{
1167 struct ivi_layout *layout = get_instance();
1168 remove_notification(&layout->surface_notification.removed.listener_list, callback, userdata);
1169}
1170
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001171static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001172ivi_layout_add_notification_configure_surface(surface_configure_notification_func callback,
1173 void *userdata)
1174{
1175 struct ivi_layout *layout = get_instance();
1176 struct ivi_layout_notification_callback *configure_changed_callback = NULL;
1177 if (callback == NULL) {
1178 weston_log("ivi_layout_add_notification_configure_surface: invalid argument\n");
1179 return IVI_FAILED;
1180 }
1181
1182 configure_changed_callback = malloc(sizeof *configure_changed_callback);
1183 if (configure_changed_callback == NULL) {
1184 weston_log("fails to allocate memory\n");
1185 return IVI_FAILED;
1186 }
1187
1188 configure_changed_callback->callback = callback;
1189 configure_changed_callback->data = userdata;
1190
1191 return add_notification(&layout->surface_notification.configure_changed,
1192 surface_configure_changed,
1193 configure_changed_callback);
1194}
1195
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001196static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001197ivi_layout_remove_notification_configure_surface(surface_configure_notification_func callback,
1198 void *userdata)
1199{
1200 struct ivi_layout *layout = get_instance();
1201 remove_notification(&layout->surface_notification.configure_changed.listener_list, callback, userdata);
1202}
1203
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001204uint32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001205ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf)
1206{
1207 return ivisurf->id_surface;
1208}
1209
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001210static uint32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001211ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer)
1212{
1213 return ivilayer->id_layer;
1214}
1215
Nobuhiko Tanibata4d0116e2015-06-22 15:31:57 +09001216static uint32_t
1217ivi_layout_get_id_of_screen(struct ivi_layout_screen *iviscrn)
1218{
1219 return iviscrn->id_screen;
1220}
1221
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001222static struct ivi_layout_layer *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001223ivi_layout_get_layer_from_id(uint32_t id_layer)
1224{
1225 struct ivi_layout *layout = get_instance();
1226 struct ivi_layout_layer *ivilayer = NULL;
1227
1228 wl_list_for_each(ivilayer, &layout->layer_list, link) {
1229 if (ivilayer->id_layer == id_layer) {
1230 return ivilayer;
1231 }
1232 }
1233
1234 return NULL;
1235}
1236
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001237struct ivi_layout_surface *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001238ivi_layout_get_surface_from_id(uint32_t id_surface)
1239{
1240 struct ivi_layout *layout = get_instance();
1241 struct ivi_layout_surface *ivisurf = NULL;
1242
1243 wl_list_for_each(ivisurf, &layout->surface_list, link) {
1244 if (ivisurf->id_surface == id_surface) {
1245 return ivisurf;
1246 }
1247 }
1248
1249 return NULL;
1250}
1251
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001252static struct ivi_layout_screen *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001253ivi_layout_get_screen_from_id(uint32_t id_screen)
1254{
1255 struct ivi_layout *layout = get_instance();
1256 struct ivi_layout_screen *iviscrn = NULL;
1257
1258 wl_list_for_each(iviscrn, &layout->screen_list, link) {
1259/* FIXME : select iviscrn from screen_list by id_screen */
1260 return iviscrn;
1261 break;
1262 }
1263
1264 return NULL;
1265}
1266
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001267static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001268ivi_layout_get_screen_resolution(struct ivi_layout_screen *iviscrn,
1269 int32_t *pWidth, int32_t *pHeight)
1270{
1271 struct weston_output *output = NULL;
1272
Nobuhiko Tanibata0c217cb2015-06-22 15:30:32 +09001273 if (iviscrn == NULL || pWidth == NULL || pHeight == NULL) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001274 weston_log("ivi_layout_get_screen_resolution: invalid argument\n");
1275 return IVI_FAILED;
1276 }
1277
1278 output = iviscrn->output;
1279 *pWidth = output->current_mode->width;
1280 *pHeight = output->current_mode->height;
1281
1282 return IVI_SUCCEEDED;
1283}
1284
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001285static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001286ivi_layout_surface_add_notification(struct ivi_layout_surface *ivisurf,
1287 surface_property_notification_func callback,
1288 void *userdata)
1289{
1290 struct listener_layout_notification* notification = NULL;
1291 struct ivi_layout_notification_callback *prop_callback = NULL;
1292
1293 if (ivisurf == NULL || callback == NULL) {
1294 weston_log("ivi_layout_surface_add_notification: invalid argument\n");
1295 return IVI_FAILED;
1296 }
1297
1298 notification = malloc(sizeof *notification);
1299 if (notification == NULL) {
1300 weston_log("fails to allocate memory\n");
1301 return IVI_FAILED;
1302 }
1303
1304 prop_callback = malloc(sizeof *prop_callback);
1305 if (prop_callback == NULL) {
1306 weston_log("fails to allocate memory\n");
1307 return IVI_FAILED;
1308 }
1309
1310 prop_callback->callback = callback;
1311 prop_callback->data = userdata;
1312
1313 notification->listener.notify = surface_prop_changed;
1314 notification->userdata = prop_callback;
1315
1316 wl_signal_add(&ivisurf->property_changed, &notification->listener);
1317
1318 return IVI_SUCCEEDED;
1319}
1320
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001321static const struct ivi_layout_layer_properties *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001322ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer)
1323{
1324 if (ivilayer == NULL) {
1325 weston_log("ivi_layout_get_properties_of_layer: invalid argument\n");
1326 return NULL;
1327 }
1328
1329 return &ivilayer->prop;
1330}
1331
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001332static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001333ivi_layout_get_screens(int32_t *pLength, struct ivi_layout_screen ***ppArray)
1334{
1335 struct ivi_layout *layout = get_instance();
1336 struct ivi_layout_screen *iviscrn = NULL;
1337 int32_t length = 0;
1338 int32_t n = 0;
1339
1340 if (pLength == NULL || ppArray == NULL) {
1341 weston_log("ivi_layout_get_screens: invalid argument\n");
1342 return IVI_FAILED;
1343 }
1344
1345 length = wl_list_length(&layout->screen_list);
1346
1347 if (length != 0){
1348 /* the Array must be free by module which called this function */
1349 *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
1350 if (*ppArray == NULL) {
1351 weston_log("fails to allocate memory\n");
1352 return IVI_FAILED;
1353 }
1354
1355 wl_list_for_each(iviscrn, &layout->screen_list, link) {
1356 (*ppArray)[n++] = iviscrn;
1357 }
1358 }
1359
1360 *pLength = length;
1361
1362 return IVI_SUCCEEDED;
1363}
1364
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001365static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001366ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer,
1367 int32_t *pLength,
1368 struct ivi_layout_screen ***ppArray)
1369{
1370 struct link_screen *link_scrn = NULL;
1371 int32_t length = 0;
1372 int32_t n = 0;
1373
1374 if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1375 weston_log("ivi_layout_get_screens_under_layer: invalid argument\n");
1376 return IVI_FAILED;
1377 }
1378
1379 length = wl_list_length(&ivilayer->screen_list);
1380
1381 if (length != 0){
1382 /* the Array must be free by module which called this function */
1383 *ppArray = calloc(length, sizeof(struct ivi_layout_screen *));
1384 if (*ppArray == NULL) {
1385 weston_log("fails to allocate memory\n");
1386 return IVI_FAILED;
1387 }
1388
1389 wl_list_for_each(link_scrn, &ivilayer->screen_list, link) {
1390 (*ppArray)[n++] = link_scrn->iviscrn;
1391 }
1392 }
1393
1394 *pLength = length;
1395
1396 return IVI_SUCCEEDED;
1397}
1398
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001399static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001400ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray)
1401{
1402 struct ivi_layout *layout = get_instance();
1403 struct ivi_layout_layer *ivilayer = NULL;
1404 int32_t length = 0;
1405 int32_t n = 0;
1406
1407 if (pLength == NULL || ppArray == NULL) {
1408 weston_log("ivi_layout_get_layers: invalid argument\n");
1409 return IVI_FAILED;
1410 }
1411
1412 length = wl_list_length(&layout->layer_list);
1413
1414 if (length != 0){
1415 /* the Array must be free by module which called this function */
1416 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1417 if (*ppArray == NULL) {
1418 weston_log("fails to allocate memory\n");
1419 return IVI_FAILED;
1420 }
1421
1422 wl_list_for_each(ivilayer, &layout->layer_list, link) {
1423 (*ppArray)[n++] = ivilayer;
1424 }
1425 }
1426
1427 *pLength = length;
1428
1429 return IVI_SUCCEEDED;
1430}
1431
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001432static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001433ivi_layout_get_layers_on_screen(struct ivi_layout_screen *iviscrn,
1434 int32_t *pLength,
1435 struct ivi_layout_layer ***ppArray)
1436{
1437 struct ivi_layout_layer *ivilayer = NULL;
1438 int32_t length = 0;
1439 int32_t n = 0;
1440
1441 if (iviscrn == NULL || pLength == NULL || ppArray == NULL) {
1442 weston_log("ivi_layout_get_layers_on_screen: invalid argument\n");
1443 return IVI_FAILED;
1444 }
1445
1446 length = wl_list_length(&iviscrn->order.layer_list);
1447
1448 if (length != 0){
1449 /* the Array must be free by module which called this function */
1450 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1451 if (*ppArray == NULL) {
1452 weston_log("fails to allocate memory\n");
1453 return IVI_FAILED;
1454 }
1455
Nobuhiko Tanibatae2b82142015-06-22 15:30:19 +09001456 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001457 (*ppArray)[n++] = ivilayer;
1458 }
1459 }
1460
1461 *pLength = length;
1462
1463 return IVI_SUCCEEDED;
1464}
1465
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001466static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001467ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf,
1468 int32_t *pLength,
1469 struct ivi_layout_layer ***ppArray)
1470{
1471 struct link_layer *link_layer = NULL;
1472 int32_t length = 0;
1473 int32_t n = 0;
1474
1475 if (ivisurf == NULL || pLength == NULL || ppArray == NULL) {
1476 weston_log("ivi_layout_getLayers: invalid argument\n");
1477 return IVI_FAILED;
1478 }
1479
1480 length = wl_list_length(&ivisurf->layer_list);
1481
1482 if (length != 0){
1483 /* the Array must be free by module which called this function */
1484 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1485 if (*ppArray == NULL) {
1486 weston_log("fails to allocate memory\n");
1487 return IVI_FAILED;
1488 }
1489
1490 wl_list_for_each(link_layer, &ivisurf->layer_list, link) {
1491 (*ppArray)[n++] = link_layer->ivilayer;
1492 }
1493 }
1494
1495 *pLength = length;
1496
1497 return IVI_SUCCEEDED;
1498}
1499
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001500static
1501int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001502ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray)
1503{
1504 struct ivi_layout *layout = get_instance();
1505 struct ivi_layout_surface *ivisurf = NULL;
1506 int32_t length = 0;
1507 int32_t n = 0;
1508
1509 if (pLength == NULL || ppArray == NULL) {
1510 weston_log("ivi_layout_get_surfaces: invalid argument\n");
1511 return IVI_FAILED;
1512 }
1513
1514 length = wl_list_length(&layout->surface_list);
1515
1516 if (length != 0){
1517 /* the Array must be free by module which called this function */
1518 *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1519 if (*ppArray == NULL) {
1520 weston_log("fails to allocate memory\n");
1521 return IVI_FAILED;
1522 }
1523
1524 wl_list_for_each(ivisurf, &layout->surface_list, link) {
1525 (*ppArray)[n++] = ivisurf;
1526 }
1527 }
1528
1529 *pLength = length;
1530
1531 return IVI_SUCCEEDED;
1532}
1533
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001534static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001535ivi_layout_get_surfaces_on_layer(struct ivi_layout_layer *ivilayer,
1536 int32_t *pLength,
1537 struct ivi_layout_surface ***ppArray)
1538{
1539 struct ivi_layout_surface *ivisurf = NULL;
1540 int32_t length = 0;
1541 int32_t n = 0;
1542
1543 if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1544 weston_log("ivi_layout_getSurfaceIDsOnLayer: invalid argument\n");
1545 return IVI_FAILED;
1546 }
1547
1548 length = wl_list_length(&ivilayer->order.surface_list);
1549
1550 if (length != 0) {
1551 /* the Array must be free by module which called this function */
1552 *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1553 if (*ppArray == NULL) {
1554 weston_log("fails to allocate memory\n");
1555 return IVI_FAILED;
1556 }
1557
1558 wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
1559 (*ppArray)[n++] = ivisurf;
1560 }
1561 }
1562
1563 *pLength = length;
1564
1565 return IVI_SUCCEEDED;
1566}
1567
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001568static struct ivi_layout_layer *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001569ivi_layout_layer_create_with_dimension(uint32_t id_layer,
1570 int32_t width, int32_t height)
1571{
1572 struct ivi_layout *layout = get_instance();
1573 struct ivi_layout_layer *ivilayer = NULL;
1574
1575 ivilayer = get_layer(&layout->layer_list, id_layer);
1576 if (ivilayer != NULL) {
1577 weston_log("id_layer is already created\n");
Nobuhiko Tanibata4b601e12015-06-22 15:31:16 +09001578 ++ivilayer->ref_count;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001579 return ivilayer;
1580 }
1581
1582 ivilayer = calloc(1, sizeof *ivilayer);
1583 if (ivilayer == NULL) {
1584 weston_log("fails to allocate memory\n");
1585 return NULL;
1586 }
1587
Nobuhiko Tanibata4b601e12015-06-22 15:31:16 +09001588 ivilayer->ref_count = 1;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001589 wl_list_init(&ivilayer->link);
1590 wl_signal_init(&ivilayer->property_changed);
1591 wl_list_init(&ivilayer->screen_list);
1592 wl_list_init(&ivilayer->link_to_surface);
1593 ivilayer->layout = layout;
1594 ivilayer->id_layer = id_layer;
1595
1596 init_layer_properties(&ivilayer->prop, width, height);
1597 ivilayer->event_mask = 0;
1598
1599 wl_list_init(&ivilayer->pending.surface_list);
1600 wl_list_init(&ivilayer->pending.link);
1601 ivilayer->pending.prop = ivilayer->prop;
1602
1603 wl_list_init(&ivilayer->order.surface_list);
1604 wl_list_init(&ivilayer->order.link);
1605
1606 wl_list_insert(&layout->layer_list, &ivilayer->link);
1607
1608 wl_signal_emit(&layout->layer_notification.created, ivilayer);
1609
1610 return ivilayer;
1611}
1612
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001613static void
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +09001614ivi_layout_layer_remove_notification(struct ivi_layout_layer *ivilayer)
1615{
1616 if (ivilayer == NULL) {
1617 weston_log("ivi_layout_layer_remove_notification: invalid argument\n");
1618 return;
1619 }
1620
1621 remove_all_notification(&ivilayer->property_changed.listener_list);
1622}
1623
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001624static void
Nobuhiko Tanibatadb8efd12015-06-22 15:31:39 +09001625ivi_layout_layer_remove_notification_by_callback(struct ivi_layout_layer *ivilayer,
1626 layer_property_notification_func callback,
1627 void *userdata)
1628{
1629 if (ivilayer == NULL) {
1630 weston_log("ivi_layout_layer_remove_notification_by_callback: invalid argument\n");
1631 return;
1632 }
1633
1634 remove_notification(&ivilayer->property_changed.listener_list, callback, userdata);
1635}
1636
1637static void
Nobuhiko Tanibata3aa8aed2015-06-22 15:32:23 +09001638ivi_layout_layer_destroy(struct ivi_layout_layer *ivilayer)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001639{
1640 struct ivi_layout *layout = get_instance();
1641
1642 if (ivilayer == NULL) {
1643 weston_log("ivi_layout_layer_remove: invalid argument\n");
1644 return;
1645 }
1646
Nobuhiko Tanibata4b601e12015-06-22 15:31:16 +09001647 if (--ivilayer->ref_count > 0)
1648 return;
1649
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001650 wl_signal_emit(&layout->layer_notification.removed, ivilayer);
1651
1652 clear_surface_pending_list(ivilayer);
1653 clear_surface_order_list(ivilayer);
1654
1655 if (!wl_list_empty(&ivilayer->pending.link)) {
1656 wl_list_remove(&ivilayer->pending.link);
1657 }
1658 if (!wl_list_empty(&ivilayer->order.link)) {
1659 wl_list_remove(&ivilayer->order.link);
1660 }
1661 if (!wl_list_empty(&ivilayer->link)) {
1662 wl_list_remove(&ivilayer->link);
1663 }
1664 remove_orderlayer_from_screen(ivilayer);
1665 remove_link_to_surface(ivilayer);
1666 ivi_layout_layer_remove_notification(ivilayer);
1667
1668 free(ivilayer);
1669}
1670
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001671int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001672ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer,
1673 bool newVisibility)
1674{
1675 struct ivi_layout_layer_properties *prop = NULL;
1676
1677 if (ivilayer == NULL) {
1678 weston_log("ivi_layout_layer_set_visibility: invalid argument\n");
1679 return IVI_FAILED;
1680 }
1681
1682 prop = &ivilayer->pending.prop;
1683 prop->visibility = newVisibility;
1684
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001685 if (ivilayer->prop.visibility != newVisibility)
1686 ivilayer->event_mask |= IVI_NOTIFICATION_VISIBILITY;
1687 else
1688 ivilayer->event_mask &= ~IVI_NOTIFICATION_VISIBILITY;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001689
1690 return IVI_SUCCEEDED;
1691}
1692
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001693static bool
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001694ivi_layout_layer_get_visibility(struct ivi_layout_layer *ivilayer)
1695{
1696 if (ivilayer == NULL) {
1697 weston_log("ivi_layout_layer_get_visibility: invalid argument\n");
1698 return false;
1699 }
1700
1701 return ivilayer->prop.visibility;
1702}
1703
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001704int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001705ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
1706 wl_fixed_t opacity)
1707{
1708 struct ivi_layout_layer_properties *prop = NULL;
1709
Nobuhiko Tanibata7bbacc62015-06-22 15:30:09 +09001710 if (ivilayer == NULL ||
1711 opacity < wl_fixed_from_double(0.0) ||
1712 wl_fixed_from_double(1.0) < opacity) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001713 weston_log("ivi_layout_layer_set_opacity: invalid argument\n");
1714 return IVI_FAILED;
1715 }
1716
1717 prop = &ivilayer->pending.prop;
1718 prop->opacity = opacity;
1719
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001720 if (ivilayer->prop.opacity != opacity)
1721 ivilayer->event_mask |= IVI_NOTIFICATION_OPACITY;
1722 else
1723 ivilayer->event_mask &= ~IVI_NOTIFICATION_OPACITY;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001724
1725 return IVI_SUCCEEDED;
1726}
1727
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001728wl_fixed_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001729ivi_layout_layer_get_opacity(struct ivi_layout_layer *ivilayer)
1730{
1731 if (ivilayer == NULL) {
1732 weston_log("ivi_layout_layer_get_opacity: invalid argument\n");
1733 return wl_fixed_from_double(0.0);
1734 }
1735
1736 return ivilayer->prop.opacity;
1737}
1738
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001739static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001740ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer,
1741 int32_t x, int32_t y,
1742 int32_t width, int32_t height)
1743{
1744 struct ivi_layout_layer_properties *prop = NULL;
1745
1746 if (ivilayer == NULL) {
1747 weston_log("ivi_layout_layer_set_source_rectangle: invalid argument\n");
1748 return IVI_FAILED;
1749 }
1750
1751 prop = &ivilayer->pending.prop;
1752 prop->source_x = x;
1753 prop->source_y = y;
1754 prop->source_width = width;
1755 prop->source_height = height;
1756
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001757 if (ivilayer->prop.source_x != x || ivilayer->prop.source_y != y ||
1758 ivilayer->prop.source_width != width ||
1759 ivilayer->prop.source_height != height)
1760 ivilayer->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
1761 else
1762 ivilayer->event_mask &= ~IVI_NOTIFICATION_SOURCE_RECT;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001763
1764 return IVI_SUCCEEDED;
1765}
1766
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001767static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001768ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer,
1769 int32_t x, int32_t y,
1770 int32_t width, int32_t height)
1771{
1772 struct ivi_layout_layer_properties *prop = NULL;
1773
1774 if (ivilayer == NULL) {
1775 weston_log("ivi_layout_layer_set_destination_rectangle: invalid argument\n");
1776 return IVI_FAILED;
1777 }
1778
1779 prop = &ivilayer->pending.prop;
1780 prop->dest_x = x;
1781 prop->dest_y = y;
1782 prop->dest_width = width;
1783 prop->dest_height = height;
1784
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001785 if (ivilayer->prop.dest_x != x || ivilayer->prop.dest_y != y ||
1786 ivilayer->prop.dest_width != width ||
1787 ivilayer->prop.dest_height != height)
1788 ivilayer->event_mask |= IVI_NOTIFICATION_DEST_RECT;
1789 else
1790 ivilayer->event_mask &= ~IVI_NOTIFICATION_DEST_RECT;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001791
1792 return IVI_SUCCEEDED;
1793}
1794
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001795static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001796ivi_layout_layer_get_dimension(struct ivi_layout_layer *ivilayer,
1797 int32_t *dest_width, int32_t *dest_height)
1798{
1799 if (ivilayer == NULL || dest_width == NULL || dest_height == NULL) {
1800 weston_log("ivi_layout_layer_get_dimension: invalid argument\n");
1801 return IVI_FAILED;
1802 }
1803
1804 *dest_width = ivilayer->prop.dest_width;
1805 *dest_height = ivilayer->prop.dest_height;
1806
1807 return IVI_SUCCEEDED;
1808}
1809
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001810static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001811ivi_layout_layer_set_dimension(struct ivi_layout_layer *ivilayer,
1812 int32_t dest_width, int32_t dest_height)
1813{
1814 struct ivi_layout_layer_properties *prop = NULL;
1815
1816 if (ivilayer == NULL) {
1817 weston_log("ivi_layout_layer_set_dimension: invalid argument\n");
1818 return IVI_FAILED;
1819 }
1820
1821 prop = &ivilayer->pending.prop;
1822
1823 prop->dest_width = dest_width;
1824 prop->dest_height = dest_height;
1825
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001826 if (ivilayer->prop.dest_width != dest_width ||
1827 ivilayer->prop.dest_height != dest_height)
1828 ivilayer->event_mask |= IVI_NOTIFICATION_DIMENSION;
1829 else
1830 ivilayer->event_mask &= ~IVI_NOTIFICATION_DIMENSION;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001831
1832 return IVI_SUCCEEDED;
1833}
1834
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001835int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001836ivi_layout_layer_get_position(struct ivi_layout_layer *ivilayer,
1837 int32_t *dest_x, int32_t *dest_y)
1838{
1839 if (ivilayer == NULL || dest_x == NULL || dest_y == NULL) {
1840 weston_log("ivi_layout_layer_get_position: invalid argument\n");
1841 return IVI_FAILED;
1842 }
1843
1844 *dest_x = ivilayer->prop.dest_x;
1845 *dest_y = ivilayer->prop.dest_y;
1846
1847 return IVI_SUCCEEDED;
1848}
1849
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001850int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001851ivi_layout_layer_set_position(struct ivi_layout_layer *ivilayer,
1852 int32_t dest_x, int32_t dest_y)
1853{
1854 struct ivi_layout_layer_properties *prop = NULL;
1855
1856 if (ivilayer == NULL) {
1857 weston_log("ivi_layout_layer_set_position: invalid argument\n");
1858 return IVI_FAILED;
1859 }
1860
1861 prop = &ivilayer->pending.prop;
1862 prop->dest_x = dest_x;
1863 prop->dest_y = dest_y;
1864
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001865 if (ivilayer->prop.dest_x != dest_x || ivilayer->prop.dest_y != dest_y)
1866 ivilayer->event_mask |= IVI_NOTIFICATION_POSITION;
1867 else
1868 ivilayer->event_mask &= ~IVI_NOTIFICATION_POSITION;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001869
1870 return IVI_SUCCEEDED;
1871}
1872
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001873static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001874ivi_layout_layer_set_orientation(struct ivi_layout_layer *ivilayer,
1875 enum wl_output_transform orientation)
1876{
1877 struct ivi_layout_layer_properties *prop = NULL;
1878
1879 if (ivilayer == NULL) {
1880 weston_log("ivi_layout_layer_set_orientation: invalid argument\n");
1881 return IVI_FAILED;
1882 }
1883
1884 prop = &ivilayer->pending.prop;
1885 prop->orientation = orientation;
1886
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001887 if (ivilayer->prop.orientation != orientation)
1888 ivilayer->event_mask |= IVI_NOTIFICATION_ORIENTATION;
1889 else
1890 ivilayer->event_mask &= ~IVI_NOTIFICATION_ORIENTATION;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001891
1892 return IVI_SUCCEEDED;
1893}
1894
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001895static enum wl_output_transform
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001896ivi_layout_layer_get_orientation(struct ivi_layout_layer *ivilayer)
1897{
1898 if (ivilayer == NULL) {
1899 weston_log("ivi_layout_layer_get_orientation: invalid argument\n");
1900 return 0;
1901 }
1902
1903 return ivilayer->prop.orientation;
1904}
1905
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001906int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001907ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
1908 struct ivi_layout_surface **pSurface,
1909 int32_t number)
1910{
1911 struct ivi_layout *layout = get_instance();
1912 struct ivi_layout_surface *ivisurf = NULL;
1913 struct ivi_layout_surface *next = NULL;
1914 uint32_t *id_surface = NULL;
1915 int32_t i = 0;
1916
1917 if (ivilayer == NULL) {
1918 weston_log("ivi_layout_layer_set_render_order: invalid argument\n");
1919 return IVI_FAILED;
1920 }
1921
1922 if (pSurface == NULL) {
1923 wl_list_for_each_safe(ivisurf, next, &ivilayer->pending.surface_list, pending.link) {
1924 if (!wl_list_empty(&ivisurf->pending.link)) {
1925 wl_list_remove(&ivisurf->pending.link);
1926 }
1927
1928 wl_list_init(&ivisurf->pending.link);
1929 }
1930 ivilayer->event_mask |= IVI_NOTIFICATION_REMOVE;
1931 return IVI_SUCCEEDED;
1932 }
1933
1934 for (i = 0; i < number; i++) {
1935 id_surface = &pSurface[i]->id_surface;
1936
1937 wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
1938 if (*id_surface != ivisurf->id_surface) {
1939 continue;
1940 }
1941
1942 if (!wl_list_empty(&ivisurf->pending.link)) {
1943 wl_list_remove(&ivisurf->pending.link);
1944 }
1945 wl_list_init(&ivisurf->pending.link);
1946 wl_list_insert(&ivilayer->pending.surface_list,
1947 &ivisurf->pending.link);
1948 break;
1949 }
1950 }
1951
1952 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
1953
1954 return IVI_SUCCEEDED;
1955}
1956
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001957int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001958ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf,
1959 bool newVisibility)
1960{
1961 struct ivi_layout_surface_properties *prop = NULL;
1962
1963 if (ivisurf == NULL) {
1964 weston_log("ivi_layout_surface_set_visibility: invalid argument\n");
1965 return IVI_FAILED;
1966 }
1967
1968 prop = &ivisurf->pending.prop;
1969 prop->visibility = newVisibility;
1970
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001971 if (ivisurf->prop.visibility != newVisibility)
1972 ivisurf->event_mask |= IVI_NOTIFICATION_VISIBILITY;
1973 else
1974 ivisurf->event_mask &= ~IVI_NOTIFICATION_VISIBILITY;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001975
1976 return IVI_SUCCEEDED;
1977}
1978
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001979bool
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001980ivi_layout_surface_get_visibility(struct ivi_layout_surface *ivisurf)
1981{
1982 if (ivisurf == NULL) {
1983 weston_log("ivi_layout_surface_get_visibility: invalid argument\n");
1984 return false;
1985 }
1986
1987 return ivisurf->prop.visibility;
1988}
1989
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001990int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001991ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
1992 wl_fixed_t opacity)
1993{
1994 struct ivi_layout_surface_properties *prop = NULL;
1995
Nobuhiko Tanibataa86226c2015-06-22 15:29:20 +09001996 if (ivisurf == NULL ||
1997 opacity < wl_fixed_from_double(0.0) ||
1998 wl_fixed_from_double(1.0) < opacity) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001999 weston_log("ivi_layout_surface_set_opacity: invalid argument\n");
2000 return IVI_FAILED;
2001 }
2002
2003 prop = &ivisurf->pending.prop;
2004 prop->opacity = opacity;
2005
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09002006 if (ivisurf->prop.opacity != opacity)
2007 ivisurf->event_mask |= IVI_NOTIFICATION_OPACITY;
2008 else
2009 ivisurf->event_mask &= ~IVI_NOTIFICATION_OPACITY;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002010
2011 return IVI_SUCCEEDED;
2012}
2013
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002014wl_fixed_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002015ivi_layout_surface_get_opacity(struct ivi_layout_surface *ivisurf)
2016{
2017 if (ivisurf == NULL) {
2018 weston_log("ivi_layout_surface_get_opacity: invalid argument\n");
2019 return wl_fixed_from_double(0.0);
2020 }
2021
2022 return ivisurf->prop.opacity;
2023}
2024
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002025int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002026ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
2027 int32_t x, int32_t y,
2028 int32_t width, int32_t height)
2029{
2030 struct ivi_layout_surface_properties *prop = NULL;
2031
2032 if (ivisurf == NULL) {
2033 weston_log("ivi_layout_surface_set_destination_rectangle: invalid argument\n");
2034 return IVI_FAILED;
2035 }
2036
2037 prop = &ivisurf->pending.prop;
2038 prop->start_x = prop->dest_x;
2039 prop->start_y = prop->dest_y;
2040 prop->dest_x = x;
2041 prop->dest_y = y;
2042 prop->start_width = prop->dest_width;
2043 prop->start_height = prop->dest_height;
2044 prop->dest_width = width;
2045 prop->dest_height = height;
2046
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09002047 if (ivisurf->prop.dest_x != x || ivisurf->prop.dest_y != y ||
2048 ivisurf->prop.dest_width != width ||
2049 ivisurf->prop.dest_height != height)
2050 ivisurf->event_mask |= IVI_NOTIFICATION_DEST_RECT;
2051 else
2052 ivisurf->event_mask &= ~IVI_NOTIFICATION_DEST_RECT;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002053
2054 return IVI_SUCCEEDED;
2055}
2056
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002057static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002058ivi_layout_surface_set_dimension(struct ivi_layout_surface *ivisurf,
2059 int32_t dest_width, int32_t dest_height)
2060{
2061 struct ivi_layout_surface_properties *prop = NULL;
2062
2063 if (ivisurf == NULL) {
2064 weston_log("ivi_layout_surface_set_dimension: invalid argument\n");
2065 return IVI_FAILED;
2066 }
2067
2068 prop = &ivisurf->pending.prop;
2069 prop->dest_width = dest_width;
2070 prop->dest_height = dest_height;
2071
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09002072 if (ivisurf->prop.dest_width != dest_width ||
2073 ivisurf->prop.dest_height != dest_height)
2074 ivisurf->event_mask |= IVI_NOTIFICATION_DIMENSION;
2075 else
2076 ivisurf->event_mask &= ~IVI_NOTIFICATION_DIMENSION;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002077
2078 return IVI_SUCCEEDED;
2079}
2080
2081int32_t
2082ivi_layout_surface_get_dimension(struct ivi_layout_surface *ivisurf,
2083 int32_t *dest_width, int32_t *dest_height)
2084{
2085 if (ivisurf == NULL || dest_width == NULL || dest_height == NULL) {
2086 weston_log("ivi_layout_surface_get_dimension: invalid argument\n");
2087 return IVI_FAILED;
2088 }
2089
2090 *dest_width = ivisurf->prop.dest_width;
2091 *dest_height = ivisurf->prop.dest_height;
2092
2093 return IVI_SUCCEEDED;
2094}
2095
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002096static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002097ivi_layout_surface_set_position(struct ivi_layout_surface *ivisurf,
2098 int32_t dest_x, int32_t dest_y)
2099{
2100 struct ivi_layout_surface_properties *prop = NULL;
2101
2102 if (ivisurf == NULL) {
2103 weston_log("ivi_layout_surface_set_position: invalid argument\n");
2104 return IVI_FAILED;
2105 }
2106
2107 prop = &ivisurf->pending.prop;
2108 prop->dest_x = dest_x;
2109 prop->dest_y = dest_y;
2110
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09002111 if (ivisurf->prop.dest_x != dest_x || ivisurf->prop.dest_y != dest_y)
2112 ivisurf->event_mask |= IVI_NOTIFICATION_POSITION;
2113 else
2114 ivisurf->event_mask &= ~IVI_NOTIFICATION_POSITION;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002115
2116 return IVI_SUCCEEDED;
2117}
2118
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002119static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002120ivi_layout_surface_get_position(struct ivi_layout_surface *ivisurf,
2121 int32_t *dest_x, int32_t *dest_y)
2122{
2123 if (ivisurf == NULL || dest_x == NULL || dest_y == NULL) {
2124 weston_log("ivi_layout_surface_get_position: invalid argument\n");
2125 return IVI_FAILED;
2126 }
2127
2128 *dest_x = ivisurf->prop.dest_x;
2129 *dest_y = ivisurf->prop.dest_y;
2130
2131 return IVI_SUCCEEDED;
2132}
2133
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002134static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002135ivi_layout_surface_set_orientation(struct ivi_layout_surface *ivisurf,
2136 enum wl_output_transform orientation)
2137{
2138 struct ivi_layout_surface_properties *prop = NULL;
2139
2140 if (ivisurf == NULL) {
2141 weston_log("ivi_layout_surface_set_orientation: invalid argument\n");
2142 return IVI_FAILED;
2143 }
2144
2145 prop = &ivisurf->pending.prop;
2146 prop->orientation = orientation;
2147
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09002148 if (ivisurf->prop.orientation != orientation)
2149 ivisurf->event_mask |= IVI_NOTIFICATION_ORIENTATION;
2150 else
2151 ivisurf->event_mask &= ~IVI_NOTIFICATION_ORIENTATION;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002152
2153 return IVI_SUCCEEDED;
2154}
2155
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002156static enum wl_output_transform
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002157ivi_layout_surface_get_orientation(struct ivi_layout_surface *ivisurf)
2158{
2159 if (ivisurf == NULL) {
2160 weston_log("ivi_layout_surface_get_orientation: invalid argument\n");
2161 return 0;
2162 }
2163
2164 return ivisurf->prop.orientation;
2165}
2166
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002167static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002168ivi_layout_screen_add_layer(struct ivi_layout_screen *iviscrn,
2169 struct ivi_layout_layer *addlayer)
2170{
2171 struct ivi_layout *layout = get_instance();
2172 struct ivi_layout_layer *ivilayer = NULL;
2173 struct ivi_layout_layer *next = NULL;
2174 int is_layer_in_scrn = 0;
2175
2176 if (iviscrn == NULL || addlayer == NULL) {
2177 weston_log("ivi_layout_screen_add_layer: invalid argument\n");
2178 return IVI_FAILED;
2179 }
2180
2181 is_layer_in_scrn = is_layer_in_screen(addlayer, iviscrn);
2182 if (is_layer_in_scrn == 1) {
2183 weston_log("ivi_layout_screen_add_layer: addlayer is already available\n");
2184 return IVI_SUCCEEDED;
2185 }
2186
2187 wl_list_for_each_safe(ivilayer, next, &layout->layer_list, link) {
2188 if (ivilayer->id_layer == addlayer->id_layer) {
2189 if (!wl_list_empty(&ivilayer->pending.link)) {
2190 wl_list_remove(&ivilayer->pending.link);
2191 }
2192 wl_list_init(&ivilayer->pending.link);
2193 wl_list_insert(&iviscrn->pending.layer_list,
2194 &ivilayer->pending.link);
2195 break;
2196 }
2197 }
2198
2199 iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
2200
2201 return IVI_SUCCEEDED;
2202}
2203
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002204static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002205ivi_layout_screen_set_render_order(struct ivi_layout_screen *iviscrn,
2206 struct ivi_layout_layer **pLayer,
2207 const int32_t number)
2208{
2209 struct ivi_layout *layout = get_instance();
2210 struct ivi_layout_layer *ivilayer = NULL;
2211 struct ivi_layout_layer *next = NULL;
2212 uint32_t *id_layer = NULL;
2213 int32_t i = 0;
2214
2215 if (iviscrn == NULL) {
2216 weston_log("ivi_layout_screen_set_render_order: invalid argument\n");
2217 return IVI_FAILED;
2218 }
2219
2220 wl_list_for_each_safe(ivilayer, next,
2221 &iviscrn->pending.layer_list, pending.link) {
2222 wl_list_init(&ivilayer->pending.link);
2223 }
2224
2225 wl_list_init(&iviscrn->pending.layer_list);
2226
2227 if (pLayer == NULL) {
2228 wl_list_for_each_safe(ivilayer, next, &iviscrn->pending.layer_list, pending.link) {
2229 if (!wl_list_empty(&ivilayer->pending.link)) {
2230 wl_list_remove(&ivilayer->pending.link);
2231 }
2232
2233 wl_list_init(&ivilayer->pending.link);
2234 }
2235
2236 iviscrn->event_mask |= IVI_NOTIFICATION_REMOVE;
2237 return IVI_SUCCEEDED;
2238 }
2239
2240 for (i = 0; i < number; i++) {
2241 id_layer = &pLayer[i]->id_layer;
2242 wl_list_for_each(ivilayer, &layout->layer_list, link) {
2243 if (*id_layer != ivilayer->id_layer) {
2244 continue;
2245 }
2246
2247 if (!wl_list_empty(&ivilayer->pending.link)) {
2248 wl_list_remove(&ivilayer->pending.link);
2249 }
2250 wl_list_init(&ivilayer->pending.link);
2251 wl_list_insert(&iviscrn->pending.layer_list,
2252 &ivilayer->pending.link);
2253 break;
2254 }
2255 }
2256
2257 iviscrn->event_mask |= IVI_NOTIFICATION_ADD;
2258
2259 return IVI_SUCCEEDED;
2260}
2261
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002262static struct weston_output *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002263ivi_layout_screen_get_output(struct ivi_layout_screen *iviscrn)
2264{
2265 return iviscrn->output;
2266}
2267
2268/**
2269 * This function is used by the additional ivi-module because of dumping ivi_surface sceenshot.
2270 * The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of Genivi's Layer Management.
2271 * This function is used to get the result of drawing by clients.
2272 */
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002273static struct weston_surface *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002274ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf)
2275{
2276 return ivisurf != NULL ? ivisurf->surface : NULL;
2277}
2278
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002279static int32_t
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09002280ivi_layout_surface_get_size(struct ivi_layout_surface *ivisurf,
2281 int32_t *width, int32_t *height,
2282 int32_t *stride)
2283{
2284 int32_t w;
2285 int32_t h;
2286 const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
2287
2288 if (ivisurf == NULL || ivisurf->surface == NULL) {
2289 weston_log("%s: invalid argument\n", __func__);
2290 return IVI_FAILED;
2291 }
2292
2293 weston_surface_get_content_size(ivisurf->surface, &w, &h);
2294
2295 if (width != NULL)
2296 *width = w;
2297
2298 if (height != NULL)
2299 *height = h;
2300
2301 if (stride != NULL)
2302 *stride = w * bytespp;
2303
2304 return IVI_SUCCEEDED;
2305}
2306
2307static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002308ivi_layout_layer_add_notification(struct ivi_layout_layer *ivilayer,
2309 layer_property_notification_func callback,
2310 void *userdata)
2311{
2312 struct ivi_layout_notification_callback *prop_callback = NULL;
2313
2314 if (ivilayer == NULL || callback == NULL) {
2315 weston_log("ivi_layout_layer_add_notification: invalid argument\n");
2316 return IVI_FAILED;
2317 }
2318
2319 prop_callback = malloc(sizeof *prop_callback);
2320 if (prop_callback == NULL) {
2321 weston_log("fails to allocate memory\n");
2322 return IVI_FAILED;
2323 }
2324
2325 prop_callback->callback = callback;
2326 prop_callback->data = userdata;
2327
2328 return add_notification(&ivilayer->property_changed,
2329 layer_prop_changed,
2330 prop_callback);
2331}
2332
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002333static const struct ivi_layout_surface_properties *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002334ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf)
2335{
2336 if (ivisurf == NULL) {
2337 weston_log("ivi_layout_get_properties_of_surface: invalid argument\n");
2338 return NULL;
2339 }
2340
2341 return &ivisurf->prop;
2342}
2343
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002344static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002345ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer,
2346 struct ivi_layout_surface *addsurf)
2347{
2348 struct ivi_layout *layout = get_instance();
2349 struct ivi_layout_surface *ivisurf = NULL;
2350 struct ivi_layout_surface *next = NULL;
2351 int is_surf_in_layer = 0;
2352
2353 if (ivilayer == NULL || addsurf == NULL) {
2354 weston_log("ivi_layout_layer_add_surface: invalid argument\n");
2355 return IVI_FAILED;
2356 }
2357
2358 is_surf_in_layer = is_surface_in_layer(addsurf, ivilayer);
2359 if (is_surf_in_layer == 1) {
2360 weston_log("ivi_layout_layer_add_surface: addsurf is already available\n");
2361 return IVI_SUCCEEDED;
2362 }
2363
2364 wl_list_for_each_safe(ivisurf, next, &layout->surface_list, link) {
2365 if (ivisurf->id_surface == addsurf->id_surface) {
2366 if (!wl_list_empty(&ivisurf->pending.link)) {
2367 wl_list_remove(&ivisurf->pending.link);
2368 }
2369 wl_list_init(&ivisurf->pending.link);
2370 wl_list_insert(&ivilayer->pending.surface_list,
2371 &ivisurf->pending.link);
2372 break;
2373 }
2374 }
2375
2376 ivilayer->event_mask |= IVI_NOTIFICATION_ADD;
2377
2378 return IVI_SUCCEEDED;
2379}
2380
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002381static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002382ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer,
2383 struct ivi_layout_surface *remsurf)
2384{
2385 struct ivi_layout_surface *ivisurf = NULL;
2386 struct ivi_layout_surface *next = NULL;
2387
2388 if (ivilayer == NULL || remsurf == NULL) {
2389 weston_log("ivi_layout_layer_remove_surface: invalid argument\n");
2390 return;
2391 }
2392
2393 wl_list_for_each_safe(ivisurf, next,
2394 &ivilayer->pending.surface_list, pending.link) {
2395 if (ivisurf->id_surface == remsurf->id_surface) {
2396 if (!wl_list_empty(&ivisurf->pending.link)) {
2397 wl_list_remove(&ivisurf->pending.link);
2398 }
2399 wl_list_init(&ivisurf->pending.link);
2400 break;
2401 }
2402 }
2403
2404 remsurf->event_mask |= IVI_NOTIFICATION_REMOVE;
2405}
2406
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002407static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002408ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf,
2409 int32_t x, int32_t y,
2410 int32_t width, int32_t height)
2411{
2412 struct ivi_layout_surface_properties *prop = NULL;
2413
2414 if (ivisurf == NULL) {
2415 weston_log("ivi_layout_surface_set_source_rectangle: invalid argument\n");
2416 return IVI_FAILED;
2417 }
2418
2419 prop = &ivisurf->pending.prop;
2420 prop->source_x = x;
2421 prop->source_y = y;
2422 prop->source_width = width;
2423 prop->source_height = height;
2424
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09002425 if (ivisurf->prop.source_x != x || ivisurf->prop.source_y != y ||
2426 ivisurf->prop.source_width != width ||
2427 ivisurf->prop.source_height != height)
2428 ivisurf->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
2429 else
2430 ivisurf->event_mask &= ~IVI_NOTIFICATION_SOURCE_RECT;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002431
2432 return IVI_SUCCEEDED;
2433}
2434
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002435int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002436ivi_layout_commit_changes(void)
2437{
2438 struct ivi_layout *layout = get_instance();
2439
2440 commit_surface_list(layout);
2441 commit_layer_list(layout);
2442 commit_screen_list(layout);
2443
2444 commit_transition(layout);
2445
2446 commit_changes(layout);
2447 send_prop(layout);
2448 weston_compositor_schedule_repaint(layout->compositor);
2449
2450 return IVI_SUCCEEDED;
2451}
2452
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002453static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002454ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer,
2455 enum ivi_layout_transition_type type,
2456 uint32_t duration)
2457{
2458 if (ivilayer == NULL) {
2459 weston_log("%s: invalid argument\n", __func__);
2460 return -1;
2461 }
2462
2463 ivilayer->pending.prop.transition_type = type;
2464 ivilayer->pending.prop.transition_duration = duration;
2465
2466 return 0;
2467}
2468
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002469static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002470ivi_layout_layer_set_fade_info(struct ivi_layout_layer* ivilayer,
2471 uint32_t is_fade_in,
2472 double start_alpha, double end_alpha)
2473{
2474 if (ivilayer == NULL) {
2475 weston_log("%s: invalid argument\n", __func__);
2476 return -1;
2477 }
2478
2479 ivilayer->pending.prop.is_fade_in = is_fade_in;
2480 ivilayer->pending.prop.start_alpha = start_alpha;
2481 ivilayer->pending.prop.end_alpha = end_alpha;
2482
2483 return 0;
2484}
2485
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002486static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002487ivi_layout_surface_set_transition_duration(struct ivi_layout_surface *ivisurf,
2488 uint32_t duration)
2489{
2490 struct ivi_layout_surface_properties *prop;
2491
2492 if (ivisurf == NULL) {
2493 weston_log("%s: invalid argument\n", __func__);
2494 return -1;
2495 }
2496
2497 prop = &ivisurf->pending.prop;
2498 prop->transition_duration = duration*10;
2499 return 0;
2500}
2501
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002502static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09002503ivi_layout_surface_set_transition(struct ivi_layout_surface *ivisurf,
2504 enum ivi_layout_transition_type type,
2505 uint32_t duration)
2506{
2507 struct ivi_layout_surface_properties *prop;
2508
2509 if (ivisurf == NULL) {
2510 weston_log("%s: invalid argument\n", __func__);
2511 return -1;
2512 }
2513
2514 prop = &ivisurf->pending.prop;
2515 prop->transition_type = type;
2516 prop->transition_duration = duration;
2517 return 0;
2518}
2519
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09002520static int32_t
2521ivi_layout_surface_dump(struct weston_surface *surface,
2522 void *target, size_t size,int32_t x, int32_t y,
2523 int32_t width, int32_t height)
2524{
2525 int result = 0;
2526
2527 if (surface == NULL) {
2528 weston_log("%s: invalid argument\n", __func__);
2529 return IVI_FAILED;
2530 }
2531
2532 result = weston_surface_copy_content(
2533 surface, target, size,
2534 x, y, width, height);
2535
2536 return result == 0 ? IVI_SUCCEEDED : IVI_FAILED;
2537}
2538
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002539/**
2540 * methods of interaction between ivi-shell with ivi-layout
2541 */
2542struct weston_view *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002543ivi_layout_get_weston_view(struct ivi_layout_surface *surface)
2544{
2545 struct weston_view *tmpview = NULL;
2546
2547 if(surface == NULL)
2548 return NULL;
2549
2550 wl_list_for_each(tmpview, &surface->surface->views, surface_link)
2551 {
2552 if (tmpview != NULL) {
2553 break;
2554 }
2555 }
2556 return tmpview;
2557}
2558
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002559void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002560ivi_layout_surface_configure(struct ivi_layout_surface *ivisurf,
2561 int32_t width, int32_t height)
2562{
2563 struct ivi_layout *layout = get_instance();
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002564
Nobuhiko Tanibatae6cc9972015-04-27 16:54:01 +09002565 /* emit callback which is set by ivi-layout api user */
2566 wl_signal_emit(&layout->surface_notification.configure_changed,
2567 ivisurf);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002568}
2569
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002570static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002571ivi_layout_surface_set_content_observer(struct ivi_layout_surface *ivisurf,
2572 ivi_controller_surface_content_callback callback,
2573 void* userdata)
2574{
2575 int32_t ret = IVI_FAILED;
2576
2577 if (ivisurf != NULL) {
2578 ivisurf->content_observer.callback = callback;
2579 ivisurf->content_observer.userdata = userdata;
2580 ret = IVI_SUCCEEDED;
2581 }
2582 return ret;
2583}
2584
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002585struct ivi_layout_surface*
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002586ivi_layout_surface_create(struct weston_surface *wl_surface,
2587 uint32_t id_surface)
2588{
2589 struct ivi_layout *layout = get_instance();
2590 struct ivi_layout_surface *ivisurf = NULL;
2591 struct weston_view *tmpview = NULL;
2592
2593 if (wl_surface == NULL) {
2594 weston_log("ivi_layout_surface_create: invalid argument\n");
2595 return NULL;
2596 }
2597
2598 ivisurf = get_surface(&layout->surface_list, id_surface);
2599 if (ivisurf != NULL) {
2600 if (ivisurf->surface != NULL) {
2601 weston_log("id_surface(%d) is already created\n", id_surface);
2602 return NULL;
2603 }
2604 }
2605
2606 ivisurf = calloc(1, sizeof *ivisurf);
2607 if (ivisurf == NULL) {
2608 weston_log("fails to allocate memory\n");
2609 return NULL;
2610 }
2611
2612 wl_list_init(&ivisurf->link);
2613 wl_signal_init(&ivisurf->property_changed);
2614 wl_signal_init(&ivisurf->configured);
2615 wl_list_init(&ivisurf->layer_list);
2616 ivisurf->id_surface = id_surface;
2617 ivisurf->layout = layout;
2618
2619 ivisurf->surface = wl_surface;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002620
2621 tmpview = weston_view_create(wl_surface);
2622 if (tmpview == NULL) {
2623 weston_log("fails to allocate memory\n");
2624 }
2625
2626 ivisurf->surface->width_from_buffer = 0;
2627 ivisurf->surface->height_from_buffer = 0;
2628
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002629
2630 init_surface_properties(&ivisurf->prop);
2631 ivisurf->event_mask = 0;
2632
2633 ivisurf->pending.prop = ivisurf->prop;
2634 wl_list_init(&ivisurf->pending.link);
2635
2636 wl_list_init(&ivisurf->order.link);
2637 wl_list_init(&ivisurf->order.layer_list);
2638
2639 wl_list_insert(&layout->surface_list, &ivisurf->link);
2640
2641 wl_signal_emit(&layout->surface_notification.created, ivisurf);
2642
2643 return ivisurf;
2644}
2645
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002646void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002647ivi_layout_init_with_compositor(struct weston_compositor *ec)
2648{
2649 struct ivi_layout *layout = get_instance();
2650
2651 layout->compositor = ec;
2652
2653 wl_list_init(&layout->surface_list);
2654 wl_list_init(&layout->layer_list);
2655 wl_list_init(&layout->screen_list);
2656
2657 wl_signal_init(&layout->layer_notification.created);
2658 wl_signal_init(&layout->layer_notification.removed);
2659
2660 wl_signal_init(&layout->surface_notification.created);
2661 wl_signal_init(&layout->surface_notification.removed);
2662 wl_signal_init(&layout->surface_notification.configure_changed);
2663
2664 /* Add layout_layer at the last of weston_compositor.layer_list */
2665 weston_layer_init(&layout->layout_layer, ec->layer_list.prev);
2666
2667 create_screen(ec);
2668
2669 layout->transitions = ivi_layout_transition_set_create(ec);
2670 wl_list_init(&layout->pending_transition_list);
2671}
2672
2673
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09002674void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09002675ivi_layout_surface_add_configured_listener(struct ivi_layout_surface* ivisurf,
2676 struct wl_listener* listener)
2677{
2678 wl_signal_add(&ivisurf->configured, listener);
2679}
2680
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002681static struct ivi_controller_interface ivi_controller_interface = {
2682 /**
2683 * commit all changes
2684 */
2685 .commit_changes = ivi_layout_commit_changes,
2686
2687 /**
2688 * surface controller interfaces
2689 */
2690 .add_notification_create_surface = ivi_layout_add_notification_create_surface,
2691 .remove_notification_create_surface = ivi_layout_remove_notification_create_surface,
2692 .add_notification_remove_surface = ivi_layout_add_notification_remove_surface,
2693 .remove_notification_remove_surface = ivi_layout_remove_notification_remove_surface,
2694 .add_notification_configure_surface = ivi_layout_add_notification_configure_surface,
2695 .remove_notification_configure_surface = ivi_layout_remove_notification_configure_surface,
2696 .get_surfaces = ivi_layout_get_surfaces,
2697 .get_id_of_surface = ivi_layout_get_id_of_surface,
2698 .get_surface_from_id = ivi_layout_get_surface_from_id,
2699 .get_properties_of_surface = ivi_layout_get_properties_of_surface,
2700 .get_surfaces_on_layer = ivi_layout_get_surfaces_on_layer,
2701 .surface_set_visibility = ivi_layout_surface_set_visibility,
2702 .surface_get_visibility = ivi_layout_surface_get_visibility,
2703 .surface_set_opacity = ivi_layout_surface_set_opacity,
2704 .surface_get_opacity = ivi_layout_surface_get_opacity,
2705 .surface_set_source_rectangle = ivi_layout_surface_set_source_rectangle,
2706 .surface_set_destination_rectangle = ivi_layout_surface_set_destination_rectangle,
2707 .surface_set_position = ivi_layout_surface_set_position,
2708 .surface_get_position = ivi_layout_surface_get_position,
2709 .surface_set_dimension = ivi_layout_surface_set_dimension,
2710 .surface_get_dimension = ivi_layout_surface_get_dimension,
2711 .surface_set_orientation = ivi_layout_surface_set_orientation,
2712 .surface_get_orientation = ivi_layout_surface_get_orientation,
2713 .surface_set_content_observer = ivi_layout_surface_set_content_observer,
2714 .surface_add_notification = ivi_layout_surface_add_notification,
2715 .surface_remove_notification = ivi_layout_surface_remove_notification,
2716 .surface_get_weston_surface = ivi_layout_surface_get_weston_surface,
2717 .surface_set_transition = ivi_layout_surface_set_transition,
2718 .surface_set_transition_duration = ivi_layout_surface_set_transition_duration,
2719
2720 /**
2721 * layer controller interfaces
2722 */
2723 .add_notification_create_layer = ivi_layout_add_notification_create_layer,
2724 .remove_notification_create_layer = ivi_layout_remove_notification_create_layer,
2725 .add_notification_remove_layer = ivi_layout_add_notification_remove_layer,
2726 .remove_notification_remove_layer = ivi_layout_remove_notification_remove_layer,
2727 .layer_create_with_dimension = ivi_layout_layer_create_with_dimension,
Nobuhiko Tanibata3aa8aed2015-06-22 15:32:23 +09002728 .layer_destroy = ivi_layout_layer_destroy,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002729 .get_layers = ivi_layout_get_layers,
2730 .get_id_of_layer = ivi_layout_get_id_of_layer,
2731 .get_layer_from_id = ivi_layout_get_layer_from_id,
2732 .get_properties_of_layer = ivi_layout_get_properties_of_layer,
2733 .get_layers_under_surface = ivi_layout_get_layers_under_surface,
2734 .get_layers_on_screen = ivi_layout_get_layers_on_screen,
2735 .layer_set_visibility = ivi_layout_layer_set_visibility,
2736 .layer_get_visibility = ivi_layout_layer_get_visibility,
2737 .layer_set_opacity = ivi_layout_layer_set_opacity,
2738 .layer_get_opacity = ivi_layout_layer_get_opacity,
2739 .layer_set_source_rectangle = ivi_layout_layer_set_source_rectangle,
2740 .layer_set_destination_rectangle = ivi_layout_layer_set_destination_rectangle,
2741 .layer_set_position = ivi_layout_layer_set_position,
2742 .layer_get_position = ivi_layout_layer_get_position,
2743 .layer_set_dimension = ivi_layout_layer_set_dimension,
2744 .layer_get_dimension = ivi_layout_layer_get_dimension,
2745 .layer_set_orientation = ivi_layout_layer_set_orientation,
2746 .layer_get_orientation = ivi_layout_layer_get_orientation,
2747 .layer_add_surface = ivi_layout_layer_add_surface,
2748 .layer_remove_surface = ivi_layout_layer_remove_surface,
2749 .layer_set_render_order = ivi_layout_layer_set_render_order,
2750 .layer_add_notification = ivi_layout_layer_add_notification,
2751 .layer_remove_notification = ivi_layout_layer_remove_notification,
2752 .layer_set_transition = ivi_layout_layer_set_transition,
2753
2754 /**
Nobuhiko Tanibata4d0116e2015-06-22 15:31:57 +09002755 * screen controller interfaces part1
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002756 */
2757 .get_screen_from_id = ivi_layout_get_screen_from_id,
2758 .get_screen_resolution = ivi_layout_get_screen_resolution,
2759 .get_screens = ivi_layout_get_screens,
2760 .get_screens_under_layer = ivi_layout_get_screens_under_layer,
2761 .screen_add_layer = ivi_layout_screen_add_layer,
2762 .screen_set_render_order = ivi_layout_screen_set_render_order,
2763 .screen_get_output = ivi_layout_screen_get_output,
2764
2765 /**
2766 * animation
2767 */
2768 .transition_move_layer_cancel = ivi_layout_transition_move_layer_cancel,
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09002769 .layer_set_fade_info = ivi_layout_layer_set_fade_info,
2770
2771 /**
2772 * surface content dumping for debugging
2773 */
2774 .surface_get_size = ivi_layout_surface_get_size,
2775 .surface_dump = ivi_layout_surface_dump,
Nobuhiko Tanibata82051702015-06-22 15:31:26 +09002776
2777 /**
Nobuhiko Tanibatadb8efd12015-06-22 15:31:39 +09002778 * remove notification by callback on property changes of ivi_surface/layer
Nobuhiko Tanibata82051702015-06-22 15:31:26 +09002779 */
Nobuhiko Tanibatadb8efd12015-06-22 15:31:39 +09002780 .surface_remove_notification_by_callback = ivi_layout_surface_remove_notification_by_callback,
Nobuhiko Tanibata4d0116e2015-06-22 15:31:57 +09002781 .layer_remove_notification_by_callback = ivi_layout_layer_remove_notification_by_callback,
2782
2783 /**
2784 * screen controller interfaces part2
2785 */
2786 .get_id_of_screen = ivi_layout_get_id_of_screen
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002787};
2788
2789int
2790load_controller_modules(struct weston_compositor *compositor, const char *modules,
2791 int *argc, char *argv[])
2792{
2793 const char *p, *end;
2794 char buffer[256];
2795 int (*controller_module_init)(struct weston_compositor *compositor,
2796 int *argc, char *argv[],
2797 const struct ivi_controller_interface *interface,
2798 size_t interface_version);
2799
2800 if (modules == NULL)
2801 return 0;
2802
2803 p = modules;
2804 while (*p) {
2805 end = strchrnul(p, ',');
2806 snprintf(buffer, sizeof buffer, "%.*s", (int)(end - p), p);
2807
2808 controller_module_init = weston_load_module(buffer, "controller_module_init");
Pekka Paalanen97246c02015-03-26 15:47:29 +02002809 if (!controller_module_init)
2810 return -1;
2811
2812 if (controller_module_init(compositor, argc, argv,
2813 &ivi_controller_interface,
2814 sizeof(struct ivi_controller_interface)) != 0) {
2815 weston_log("ivi-shell: Initialization of controller module fails");
2816 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002817 }
2818
2819 p = end;
2820 while (*p == ',')
2821 p++;
2822 }
2823
2824 return 0;
2825}