blob: 394179b8cb7391a15e3bb93710512571c68da5c9 [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
Bryce Harringtone6da35d2016-05-19 17:35:02 -070028 * not updated until ivi_layout_commit_changes is called. An overview from
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090029 * 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.
Bryce Harringtone6da35d2016-05-19 17:35:02 -070033 * 1/ When an API for updating properties of ivi_surface/ivi_layer, it updates
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090034 * pending prop of ivi_surface/ivi_layer/ivi_screen which are structure to
35 * store properties.
Bryce Harringtone6da35d2016-05-19 17:35:02 -070036 * 2/ Before calling commitChanges, in case of calling an API to get a property,
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090037 * 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.
Bryce Harringtone6da35d2016-05-19 17:35:02 -070045 * For example, when a property of ivi_surface is changed from invisibile
46 * to visibile, it behaves like fade-in. When ivi_layout_commitChange is
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090047 * called during transition animation, it cancels the transition and
48 * re-start transition to new properties from current properties of final
Bryce Harringtone6da35d2016-05-19 17:35:02 -070049 * frame just before the cancellation.
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090050 *
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>
Ucan, Emre (ADITG/SW1)38fcf382015-08-20 14:13:29 +000061#include <assert.h>
Jussi Kukkonen649bbce2016-07-19 14:16:27 +030062#include <stdint.h>
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090063
Pekka Paalanen58f98c92016-06-03 16:45:21 +030064#include "compositor/weston.h"
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090065#include "compositor.h"
Pekka Paalanen1f821932016-03-15 16:57:51 +020066#include "ivi-shell.h"
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090067#include "ivi-layout-export.h"
68#include "ivi-layout-private.h"
Pekka Paalanen32ca7912016-03-15 17:21:00 +020069#include "ivi-layout-shell.h"
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090070
Jon Cruz867d50e2015-06-15 15:37:10 -070071#include "shared/helpers.h"
Jon Cruz4678bab2015-06-15 15:37:07 -070072#include "shared/os-compatibility.h"
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +090073
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +090074#define max(a, b) ((a) > (b) ? (a) : (b))
75
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090076struct ivi_layout;
77
78struct ivi_layout_screen {
Ucan, Emre (ADITG/SW1)7da38232016-07-01 09:34:50 +000079 struct wl_list link; /* ivi_layout::screen_list */
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090080
81 struct ivi_layout *layout;
82 struct weston_output *output;
83
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090084 struct {
Ucan, Emre (ADITG/SW1)7da38232016-07-01 09:34:50 +000085 struct wl_list layer_list; /* ivi_layout_layer::pending.link */
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090086 } pending;
87
88 struct {
Ucan, Emre (ADITG/SW1)174257b2015-08-20 14:13:30 +000089 int dirty;
Ucan, Emre (ADITG/SW1)7da38232016-07-01 09:34:50 +000090 struct wl_list layer_list; /* ivi_layout_layer::order.link */
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090091 } order;
92};
93
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +090094struct ivi_rectangle
95{
96 int32_t x;
97 int32_t y;
98 int32_t width;
99 int32_t height;
100};
101
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900102static struct ivi_layout ivilayout = {0};
103
104struct ivi_layout *
105get_instance(void)
106{
107 return &ivilayout;
108}
109
110/**
Bryce Harringtone6da35d2016-05-19 17:35:02 -0700111 * Internal API to add/remove an ivi_layer to/from ivi_screen.
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900112 */
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900113static struct ivi_layout_surface *
114get_surface(struct wl_list *surf_list, uint32_t id_surface)
115{
116 struct ivi_layout_surface *ivisurf;
117
118 wl_list_for_each(ivisurf, surf_list, link) {
119 if (ivisurf->id_surface == id_surface) {
120 return ivisurf;
121 }
122 }
123
124 return NULL;
125}
126
127static struct ivi_layout_layer *
128get_layer(struct wl_list *layer_list, uint32_t id_layer)
129{
130 struct ivi_layout_layer *ivilayer;
131
132 wl_list_for_each(ivilayer, layer_list, link) {
133 if (ivilayer->id_layer == id_layer) {
134 return ivilayer;
135 }
136 }
137
138 return NULL;
139}
140
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000141static bool
142ivi_view_is_rendered(struct ivi_layout_view *view)
Ucan, Emre (ADITG/SW1)64635ee2015-08-28 12:59:06 +0000143{
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000144 return !wl_list_empty(&view->order_link);
145}
146
147static void
148ivi_view_destroy(struct ivi_layout_view *ivi_view)
149{
150 wl_list_remove(&ivi_view->transform.link);
151 wl_list_remove(&ivi_view->link);
152 wl_list_remove(&ivi_view->surf_link);
153 wl_list_remove(&ivi_view->pending_link);
154 wl_list_remove(&ivi_view->order_link);
155
156 weston_view_destroy(ivi_view->view);
157
158 free(ivi_view);
159}
160
161static struct ivi_layout_view*
162ivi_view_create(struct ivi_layout_layer *ivilayer,
163 struct ivi_layout_surface *ivisurf)
164{
165 struct ivi_layout_view *ivi_view;
166
167 ivi_view = calloc(1, sizeof *ivi_view);
168 if (ivi_view == NULL) {
169 weston_log("fails to allocate memory\n");
170 return NULL;
171 }
172
173 ivi_view->view = weston_view_create(ivisurf->surface);
174 if (ivi_view->view == NULL) {
175 weston_log("fails to allocate memory\n");
Raúl Peñacobabd8dc0a2017-03-29 18:13:36 +0200176 free(ivi_view);
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000177 return NULL;
178 }
179
180 weston_matrix_init(&ivi_view->transform.matrix);
181 wl_list_init(&ivi_view->transform.link);
182
183 ivi_view->ivisurf = ivisurf;
184 ivi_view->on_layer = ivilayer;
185 wl_list_insert(&ivilayer->layout->view_list,
186 &ivi_view->link);
187 wl_list_insert(&ivisurf->view_list,
188 &ivi_view->surf_link);
189
190 wl_list_init(&ivi_view->pending_link);
191 wl_list_init(&ivi_view->order_link);
192
193 return ivi_view;
194}
195
196static struct ivi_layout_view *
197get_ivi_view(struct ivi_layout_layer *ivilayer,
198 struct ivi_layout_surface *ivisurf)
199{
200 struct ivi_layout_view *ivi_view;
Ucan, Emre (ADITG/SW1)64635ee2015-08-28 12:59:06 +0000201
202 assert(ivisurf->surface != NULL);
203
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000204 wl_list_for_each(ivi_view, &ivisurf->view_list, surf_link) {
205 if (ivi_view->on_layer == ivilayer)
206 return ivi_view;
207 }
Ucan, Emre (ADITG/SW1)64635ee2015-08-28 12:59:06 +0000208
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000209 return NULL;
Ucan, Emre (ADITG/SW1)64635ee2015-08-28 12:59:06 +0000210}
211
Ucan, Emre (ADITG/SW1)b216c922016-03-17 15:30:46 +0000212static struct ivi_layout_screen *
213get_screen_from_output(struct weston_output *output)
214{
215 struct ivi_layout *layout = get_instance();
216 struct ivi_layout_screen *iviscrn = NULL;
217
218 wl_list_for_each(iviscrn, &layout->screen_list, link) {
219 if (iviscrn->output == output)
220 return iviscrn;
221 }
222
223 return NULL;
224}
225
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900226/**
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900227 * Called at destruction of wl_surface/ivi_surface
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900228 */
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900229void
230ivi_layout_surface_destroy(struct ivi_layout_surface *ivisurf)
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900231{
232 struct ivi_layout *layout = get_instance();
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000233 struct ivi_layout_view *ivi_view ,*next;
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900234
235 if (ivisurf == NULL) {
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900236 weston_log("%s: invalid argument\n", __func__);
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900237 return;
238 }
239
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900240 wl_list_remove(&ivisurf->link);
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900241
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000242 wl_list_for_each_safe(ivi_view, next, &ivisurf->view_list, surf_link) {
243 ivi_view_destroy(ivi_view);
244 }
245
Nobuhiko Tanibataef6c7862014-12-15 13:20:44 +0900246 wl_signal_emit(&layout->surface_notification.removed, ivisurf);
247
Mateusz Polroladada6e32016-03-09 09:13:26 +0000248 ivi_layout_remove_all_surface_transitions(ivisurf);
249
Nobuhiko Tanibata6f6c9382015-06-22 15:30:53 +0900250 free(ivisurf);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900251}
252
253/**
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900254 * Internal API to initialize ivi_screens found from output_list of weston_compositor.
255 * Called by ivi_layout_init_with_compositor.
256 */
257static void
258create_screen(struct weston_compositor *ec)
259{
260 struct ivi_layout *layout = get_instance();
261 struct ivi_layout_screen *iviscrn = NULL;
262 struct weston_output *output = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900263
264 wl_list_for_each(output, &ec->output_list, link) {
265 iviscrn = calloc(1, sizeof *iviscrn);
266 if (iviscrn == NULL) {
267 weston_log("fails to allocate memory\n");
268 continue;
269 }
270
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900271 iviscrn->layout = layout;
272
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900273 iviscrn->output = output;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900274
275 wl_list_init(&iviscrn->pending.layer_list);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900276
277 wl_list_init(&iviscrn->order.layer_list);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900278
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900279 wl_list_insert(&layout->screen_list, &iviscrn->link);
280 }
281}
282
283/**
284 * Internal APIs to initialize properties of ivi_surface/ivi_layer when they are created.
285 */
286static void
287init_layer_properties(struct ivi_layout_layer_properties *prop,
288 int32_t width, int32_t height)
289{
290 memset(prop, 0, sizeof *prop);
291 prop->opacity = wl_fixed_from_double(1.0);
292 prop->source_width = width;
293 prop->source_height = height;
294 prop->dest_width = width;
295 prop->dest_height = height;
296}
297
298static void
299init_surface_properties(struct ivi_layout_surface_properties *prop)
300{
301 memset(prop, 0, sizeof *prop);
302 prop->opacity = wl_fixed_from_double(1.0);
Nobuhiko Tanibatae259a7a2015-04-27 17:02:54 +0900303 /*
Bryce Harringtone6da35d2016-05-19 17:35:02 -0700304 * FIXME: this shall be fixed by ivi-layout-transition.
Nobuhiko Tanibatae259a7a2015-04-27 17:02:54 +0900305 */
306 prop->dest_width = 1;
307 prop->dest_height = 1;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900308}
309
310/**
311 * Internal APIs to be called from ivi_layout_commit_changes.
312 */
313static void
314update_opacity(struct ivi_layout_layer *ivilayer,
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000315 struct ivi_layout_surface *ivisurf,
316 struct weston_view *view)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900317{
318 double layer_alpha = wl_fixed_to_double(ivilayer->prop.opacity);
319 double surf_alpha = wl_fixed_to_double(ivisurf->prop.opacity);
320
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000321 view->alpha = layer_alpha * surf_alpha;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900322}
323
324static void
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900325calc_transformation_matrix(struct ivi_rectangle *source_rect,
326 struct ivi_rectangle *dest_rect,
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900327 struct weston_matrix *m)
328{
329 float source_center_x;
330 float source_center_y;
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900331 float scale_x;
332 float scale_y;
333 float translate_x;
334 float translate_y;
335
336 source_center_x = source_rect->x + source_rect->width * 0.5f;
337 source_center_y = source_rect->y + source_rect->height * 0.5f;
338 weston_matrix_translate(m, -source_center_x, -source_center_y, 0.0f);
339
Ucan, Emre (ADITG/SW1)57ac2602017-03-03 14:21:32 +0000340 scale_x = (float) dest_rect->width / (float) source_rect->width;
341 scale_y = (float) dest_rect->height / (float) source_rect->height;
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900342 weston_matrix_scale(m, scale_x, scale_y, 1.0f);
343
344 translate_x = dest_rect->width * 0.5f + dest_rect->x;
345 translate_y = dest_rect->height * 0.5f + dest_rect->y;
346 weston_matrix_translate(m, translate_x, translate_y, 0.0f);
347}
348
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900349/*
350 * This computes intersected rect_output from two ivi_rectangles
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900351 */
352static void
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900353ivi_rectangle_intersect(const struct ivi_rectangle *rect1,
354 const struct ivi_rectangle *rect2,
355 struct ivi_rectangle *rect_output)
356{
357 int32_t rect1_right = rect1->x + rect1->width;
358 int32_t rect1_bottom = rect1->y + rect1->height;
359 int32_t rect2_right = rect2->x + rect2->width;
360 int32_t rect2_bottom = rect2->y + rect2->height;
361
362 rect_output->x = max(rect1->x, rect2->x);
363 rect_output->y = max(rect1->y, rect2->y);
364 rect_output->width = rect1_right < rect2_right ?
365 rect1_right - rect_output->x :
366 rect2_right - rect_output->x;
367 rect_output->height = rect1_bottom < rect2_bottom ?
368 rect1_bottom - rect_output->y :
369 rect2_bottom - rect_output->y;
370
371 if (rect_output->width < 0 || rect_output->height < 0) {
372 rect_output->width = 0;
373 rect_output->height = 0;
374 }
375}
376
377/*
378 * Transform rect_input by the inverse of matrix, intersect with boundingbox,
379 * and store the result in rect_output.
380 * The boundingbox must be given in the same coordinate space as rect_output.
381 * Additionally, there are the following restrictions on the matrix:
382 * - no projective transformations
383 * - no skew
384 * - only multiples of 90-degree rotations supported
385 *
386 * In failure case of weston_matrix_invert, rect_output is set to boundingbox
387 * as a fail-safe with log.
388 */
389static void
390calc_inverse_matrix_transform(const struct weston_matrix *matrix,
391 const struct ivi_rectangle *rect_input,
392 const struct ivi_rectangle *boundingbox,
393 struct ivi_rectangle *rect_output)
394{
395 struct weston_matrix m;
396 struct weston_vector top_left;
397 struct weston_vector bottom_right;
398
399 assert(boundingbox != rect_output);
400
401 if (weston_matrix_invert(&m, matrix) < 0) {
402 weston_log("ivi-shell: calc_inverse_matrix_transform fails to invert a matrix.\n");
403 weston_log("ivi-shell: boundingbox is set to the rect_output.\n");
404 rect_output->x = boundingbox->x;
405 rect_output->y = boundingbox->y;
406 rect_output->width = boundingbox->width;
407 rect_output->height = boundingbox->height;
408 }
409
410 /* The vectors and matrices involved will always produce f[3] == 1.0. */
411 top_left.f[0] = rect_input->x;
412 top_left.f[1] = rect_input->y;
413 top_left.f[2] = 0.0f;
414 top_left.f[3] = 1.0f;
415
416 bottom_right.f[0] = rect_input->x + rect_input->width;
417 bottom_right.f[1] = rect_input->y + rect_input->height;
418 bottom_right.f[2] = 0.0f;
419 bottom_right.f[3] = 1.0f;
420
421 weston_matrix_transform(&m, &top_left);
422 weston_matrix_transform(&m, &bottom_right);
423
424 if (top_left.f[0] < bottom_right.f[0]) {
425 rect_output->x = top_left.f[0];
426 rect_output->width = bottom_right.f[0] - rect_output->x;
427 } else {
428 rect_output->x = bottom_right.f[0];
429 rect_output->width = top_left.f[0] - rect_output->x;
430 }
431
432 if (top_left.f[1] < bottom_right.f[1]) {
433 rect_output->y = top_left.f[1];
434 rect_output->height = bottom_right.f[1] - rect_output->y;
435 } else {
436 rect_output->y = bottom_right.f[1];
437 rect_output->height = top_left.f[1] - rect_output->y;
438 }
439
440 ivi_rectangle_intersect(rect_output, boundingbox, rect_output);
441}
442
443/**
444 * This computes the whole transformation matrix:m from surface-local
Yong Bakose0698712016-04-28 11:59:08 -0500445 * coordinates to multi-screen coordinates, which are global coordinates.
Nobuhiko Tanibata1c2618e2015-12-09 15:39:26 +0900446 * It is assumed that weston_view::geometry.{x,y} are zero.
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900447 *
Bryce Harringtone6da35d2016-05-19 17:35:02 -0700448 * Additionally, this computes the mask on surface-local coordinates as an
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900449 * ivi_rectangle. This can be set to weston_view_set_mask.
450 *
451 * The mask is computed by following steps
Yong Bakose0698712016-04-28 11:59:08 -0500452 * - destination rectangle of layer is transformed to multi-screen coordinates,
Nobuhiko Tanibata1c2618e2015-12-09 15:39:26 +0900453 * global coordinates. This is done by adding weston_output.{x,y} in simple
454 * because there is no scaled and rotated transformation.
Yong Bakose0698712016-04-28 11:59:08 -0500455 * - destination rectangle of layer in multi-screen coordinates needs to be
Nobuhiko Tanibata1c2618e2015-12-09 15:39:26 +0900456 * intersected inside of a screen the layer is assigned to. This is because
457 * overlapped region of weston surface in another screen shall not be
458 * displayed according to ivi use case.
459 * - destination rectangle of layer
Yong Bakose0698712016-04-28 11:59:08 -0500460 * - in multi-screen coordinates,
Nobuhiko Tanibata1c2618e2015-12-09 15:39:26 +0900461 * - and intersected inside of an assigned screen,
Yong Bakose0698712016-04-28 11:59:08 -0500462 * is inversed to surface-local coordinates by inversed matrix:m.
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900463 * - the area is intersected by intersected area between weston_surface and
464 * source rectangle of ivi_surface.
465 */
466static void
467calc_surface_to_global_matrix_and_mask_to_weston_surface(
Nobuhiko Tanibata29babdf2015-12-09 15:38:41 +0900468 struct ivi_layout_screen *iviscrn,
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900469 struct ivi_layout_layer *ivilayer,
470 struct ivi_layout_surface *ivisurf,
471 struct weston_matrix *m,
472 struct ivi_rectangle *result)
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900473{
474 const struct ivi_layout_surface_properties *sp = &ivisurf->prop;
475 const struct ivi_layout_layer_properties *lp = &ivilayer->prop;
Nobuhiko Tanibata29babdf2015-12-09 15:38:41 +0900476 struct weston_output *output = iviscrn->output;
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900477 struct ivi_rectangle weston_surface_rect = { 0,
478 0,
479 ivisurf->surface->width,
480 ivisurf->surface->height };
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900481 struct ivi_rectangle surface_source_rect = { sp->source_x,
482 sp->source_y,
483 sp->source_width,
484 sp->source_height };
485 struct ivi_rectangle surface_dest_rect = { sp->dest_x,
486 sp->dest_y,
487 sp->dest_width,
488 sp->dest_height };
489 struct ivi_rectangle layer_source_rect = { lp->source_x,
490 lp->source_y,
491 lp->source_width,
492 lp->source_height };
493 struct ivi_rectangle layer_dest_rect = { lp->dest_x,
494 lp->dest_y,
495 lp->dest_width,
496 lp->dest_height };
Nobuhiko Tanibata1c2618e2015-12-09 15:39:26 +0900497 struct ivi_rectangle screen_dest_rect = { output->x,
498 output->y,
499 output->width,
500 output->height };
501 struct ivi_rectangle layer_dest_rect_in_global =
502 { lp->dest_x + output->x,
503 lp->dest_y + output->y,
504 lp->dest_width,
505 lp->dest_height };
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900506 struct ivi_rectangle surface_result;
Nobuhiko Tanibata1c2618e2015-12-09 15:39:26 +0900507 struct ivi_rectangle layer_dest_rect_in_global_intersected;
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900508
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900509 /*
510 * the whole transformation matrix:m from surface-local
511 * coordinates to global coordinates, which is computed by
512 * two steps,
513 * - surface-local coordinates to layer-local coordinates
Yong Bakose0698712016-04-28 11:59:08 -0500514 * - layer-local coordinates to single screen-local coordinates
515 * - single screen-local coordinates to multi-screen coordinates,
516 * which are global coordinates.
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900517 */
Ucan, Emre (ADITG/SW1)57ac2602017-03-03 14:21:32 +0000518 calc_transformation_matrix(&surface_source_rect, &surface_dest_rect, m);
519 calc_transformation_matrix(&layer_source_rect, &layer_dest_rect, m);
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900520
Nobuhiko Tanibata29babdf2015-12-09 15:38:41 +0900521 weston_matrix_translate(m, output->x, output->y, 0.0f);
522
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900523 /* this intersected ivi_rectangle would be used for masking
524 * weston_surface
525 */
526 ivi_rectangle_intersect(&surface_source_rect, &weston_surface_rect,
527 &surface_result);
528
Nobuhiko Tanibata1c2618e2015-12-09 15:39:26 +0900529 /*
530 * destination rectangle of layer in multi screens coordinate
531 * is intersected to avoid displaying outside of an assigned screen.
532 */
533 ivi_rectangle_intersect(&layer_dest_rect_in_global, &screen_dest_rect,
534 &layer_dest_rect_in_global_intersected);
535
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900536 /* calc masking area of weston_surface from m */
537 calc_inverse_matrix_transform(m,
Nobuhiko Tanibata1c2618e2015-12-09 15:39:26 +0900538 &layer_dest_rect_in_global_intersected,
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900539 &surface_result,
540 result);
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900541}
542
543static void
Ucan, Emre (ADITG/SW1)1b92ba22017-01-30 13:36:05 +0000544update_prop(struct ivi_layout_view *ivi_view)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900545{
Ucan, Emre (ADITG/SW1)1b92ba22017-01-30 13:36:05 +0000546 struct ivi_layout_surface *ivisurf = ivi_view->ivisurf;
547 struct ivi_layout_layer *ivilayer = ivi_view->on_layer;
548 struct ivi_layout_screen *iviscrn = ivilayer->on_screen;
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900549 struct ivi_rectangle r;
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900550 bool can_calc = true;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900551
Nobuhiko Tanibatab4cb25d2015-12-09 15:36:58 +0900552 /*In case of no prop change, this just returns*/
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +0000553 if (!ivilayer->prop.event_mask && !ivisurf->prop.event_mask)
Nobuhiko Tanibata4c1dbf72015-07-15 13:55:50 +0900554 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900555
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000556 update_opacity(ivilayer, ivisurf, ivi_view->view);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900557
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900558 if (ivisurf->prop.source_width == 0 || ivisurf->prop.source_height == 0) {
559 weston_log("ivi-shell: source rectangle is not yet set by ivi_layout_surface_set_source_rectangle\n");
560 can_calc = false;
561 }
562
563 if (ivisurf->prop.dest_width == 0 || ivisurf->prop.dest_height == 0) {
564 weston_log("ivi-shell: destination rectangle is not yet set by ivi_layout_surface_set_destination_rectangle\n");
565 can_calc = false;
566 }
567
568 if (can_calc) {
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000569 wl_list_remove(&ivi_view->transform.link);
570 weston_matrix_init(&ivi_view->transform.matrix);
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900571
Nobuhiko Tanibataacbcc6c2015-08-24 10:24:15 +0900572 calc_surface_to_global_matrix_and_mask_to_weston_surface(
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000573 iviscrn, ivilayer, ivisurf, &ivi_view->transform.matrix, &r);
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900574
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000575 weston_view_set_mask(ivi_view->view, r.x, r.y, r.width, r.height);
576 wl_list_insert(&ivi_view->view->geometry.transformation_list,
577 &ivi_view->transform.link);
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900578
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000579 weston_view_set_transform_parent(ivi_view->view, NULL);
Nobuhiko Tanibata21deb282015-07-15 14:05:32 +0900580 }
581
582 ivisurf->update_count++;
583
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000584 weston_view_geometry_dirty(ivi_view->view);
Nobuhiko Tanibata4c1dbf72015-07-15 13:55:50 +0900585
Ucan, Emre (ADITG/SW1)64635ee2015-08-28 12:59:06 +0000586 weston_surface_damage(ivisurf->surface);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900587}
588
589static void
590commit_changes(struct ivi_layout *layout)
591{
Ucan, Emre (ADITG/SW1)27799352017-01-30 13:36:07 +0000592 struct ivi_layout_screen *iviscrn = NULL;
593 struct ivi_layout_layer *ivilayer = NULL;
594 struct ivi_layout_surface *ivisurf = NULL;
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000595 struct ivi_layout_view *ivi_view = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900596
Ucan, Emre (ADITG/SW1)27799352017-01-30 13:36:07 +0000597 wl_list_for_each(ivi_view, &layout->view_list, link) {
598 ivisurf = ivi_view->ivisurf;
599 ivilayer = ivi_view->on_layer;
600 iviscrn = ivilayer->on_screen;
Nobuhiko Tanibatab4cb25d2015-12-09 15:36:58 +0900601
Ucan, Emre (ADITG/SW1)27799352017-01-30 13:36:07 +0000602 /*
603 * If the view is not on the currently rendered scenegraph,
604 * we do not need to update its properties.
605 */
606 if (wl_list_empty(&ivi_view->order_link) || !iviscrn)
607 continue;
Nobuhiko Tanibatab4cb25d2015-12-09 15:36:58 +0900608
Ucan, Emre (ADITG/SW1)27799352017-01-30 13:36:07 +0000609 /*
610 * If the view's layer or surface is invisible, we do not need
611 * to update its properties.
612 */
Ucan, Emre (ADITG/SW1)7fe0bb22017-02-07 12:55:59 +0000613 if (!ivilayer->prop.visibility || !ivisurf->prop.visibility) {
614 /*
615 * If ivilayer or ivisurf of ivi_view is made invisible
616 * in this commit_changes call, we have to damage
617 * the weston_view below this ivi_view. Otherwise content
618 * of this ivi_view will stay visible.
619 */
Alexandros Frantzis0343c6a2017-11-17 13:39:06 +0200620 if ((ivilayer->prop.event_mask | ivisurf->prop.event_mask) &
Ucan, Emre (ADITG/SW1)7fe0bb22017-02-07 12:55:59 +0000621 IVI_NOTIFICATION_VISIBILITY)
622 weston_view_damage_below(ivi_view->view);
623
Ucan, Emre (ADITG/SW1)27799352017-01-30 13:36:07 +0000624 continue;
Ucan, Emre (ADITG/SW1)7fe0bb22017-02-07 12:55:59 +0000625 }
Ucan, Emre (ADITG/SW1)27799352017-01-30 13:36:07 +0000626
627 update_prop(ivi_view);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900628 }
629}
630
631static void
632commit_surface_list(struct ivi_layout *layout)
633{
634 struct ivi_layout_surface *ivisurf = NULL;
635 int32_t dest_x = 0;
636 int32_t dest_y = 0;
637 int32_t dest_width = 0;
638 int32_t dest_height = 0;
639 int32_t configured = 0;
640
641 wl_list_for_each(ivisurf, &layout->surface_list, link) {
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300642 if (ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEFAULT) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900643 dest_x = ivisurf->prop.dest_x;
644 dest_y = ivisurf->prop.dest_y;
645 dest_width = ivisurf->prop.dest_width;
646 dest_height = ivisurf->prop.dest_height;
647
648 ivi_layout_transition_move_resize_view(ivisurf,
649 ivisurf->pending.prop.dest_x,
650 ivisurf->pending.prop.dest_y,
651 ivisurf->pending.prop.dest_width,
652 ivisurf->pending.prop.dest_height,
653 ivisurf->pending.prop.transition_duration);
654
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300655 if (ivisurf->pending.prop.visibility) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900656 ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
657 } else {
658 ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
659 }
660
661 ivisurf->prop = ivisurf->pending.prop;
662 ivisurf->prop.dest_x = dest_x;
663 ivisurf->prop.dest_y = dest_y;
664 ivisurf->prop.dest_width = dest_width;
665 ivisurf->prop.dest_height = dest_height;
666 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
667 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
668
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300669 } else if (ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_DEST_RECT_ONLY) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900670 dest_x = ivisurf->prop.dest_x;
671 dest_y = ivisurf->prop.dest_y;
672 dest_width = ivisurf->prop.dest_width;
673 dest_height = ivisurf->prop.dest_height;
674
675 ivi_layout_transition_move_resize_view(ivisurf,
676 ivisurf->pending.prop.dest_x,
677 ivisurf->pending.prop.dest_y,
678 ivisurf->pending.prop.dest_width,
679 ivisurf->pending.prop.dest_height,
680 ivisurf->pending.prop.transition_duration);
681
682 ivisurf->prop = ivisurf->pending.prop;
683 ivisurf->prop.dest_x = dest_x;
684 ivisurf->prop.dest_y = dest_y;
685 ivisurf->prop.dest_width = dest_width;
686 ivisurf->prop.dest_height = dest_height;
687
688 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
689 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
690
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300691 } else if (ivisurf->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_VIEW_FADE_ONLY) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900692 configured = 0;
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300693 if (ivisurf->pending.prop.visibility) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900694 ivi_layout_transition_visibility_on(ivisurf, ivisurf->pending.prop.transition_duration);
695 } else {
696 ivi_layout_transition_visibility_off(ivisurf, ivisurf->pending.prop.transition_duration);
697 }
698
699 if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
700 ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
701 configured = 1;
702 }
703
704 ivisurf->prop = ivisurf->pending.prop;
705 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
706 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
707
Pekka Paalanen1f821932016-03-15 16:57:51 +0200708 if (configured && !is_surface_transition(ivisurf)) {
Pekka Paalanen1f821932016-03-15 16:57:51 +0200709 shell_surface_send_configure(ivisurf->surface,
710 ivisurf->prop.dest_width,
711 ivisurf->prop.dest_height);
712 }
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900713 } else {
714 configured = 0;
715 if (ivisurf->prop.dest_width != ivisurf->pending.prop.dest_width ||
716 ivisurf->prop.dest_height != ivisurf->pending.prop.dest_height) {
717 configured = 1;
718 }
719
720 ivisurf->prop = ivisurf->pending.prop;
721 ivisurf->prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
722 ivisurf->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
723
Pekka Paalanen1f821932016-03-15 16:57:51 +0200724 if (configured && !is_surface_transition(ivisurf)) {
Pekka Paalanen1f821932016-03-15 16:57:51 +0200725 shell_surface_send_configure(ivisurf->surface,
726 ivisurf->prop.dest_width,
727 ivisurf->prop.dest_height);
728 }
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900729 }
730 }
731}
732
733static void
734commit_layer_list(struct ivi_layout *layout)
735{
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000736 struct ivi_layout_view *ivi_view = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900737 struct ivi_layout_layer *ivilayer = NULL;
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000738 struct ivi_layout_view *next = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900739
740 wl_list_for_each(ivilayer, &layout->layer_list, link) {
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300741 if (ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_MOVE) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900742 ivi_layout_transition_move_layer(ivilayer, ivilayer->pending.prop.dest_x, ivilayer->pending.prop.dest_y, ivilayer->pending.prop.transition_duration);
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300743 } else if (ivilayer->pending.prop.transition_type == IVI_LAYOUT_TRANSITION_LAYER_FADE) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900744 ivi_layout_transition_fade_layer(ivilayer,ivilayer->pending.prop.is_fade_in,
745 ivilayer->pending.prop.start_alpha,ivilayer->pending.prop.end_alpha,
746 NULL, NULL,
747 ivilayer->pending.prop.transition_duration);
748 }
749 ivilayer->pending.prop.transition_type = IVI_LAYOUT_TRANSITION_NONE;
750
751 ivilayer->prop = ivilayer->pending.prop;
752
Ucan, Emre (ADITG/SW1)38fcf382015-08-20 14:13:29 +0000753 if (!ivilayer->order.dirty) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900754 continue;
755 }
756
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000757 wl_list_for_each_safe(ivi_view, next, &ivilayer->order.view_list,
758 order_link) {
759 wl_list_remove(&ivi_view->order_link);
760 wl_list_init(&ivi_view->order_link);
761 ivi_view->ivisurf->prop.event_mask |= IVI_NOTIFICATION_REMOVE;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900762 }
763
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000764 assert(wl_list_empty(&ivilayer->order.view_list));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900765
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000766 wl_list_for_each(ivi_view, &ivilayer->pending.view_list,
767 pending_link) {
768 wl_list_remove(&ivi_view->order_link);
769 wl_list_insert(&ivilayer->order.view_list, &ivi_view->order_link);
770 ivi_view->ivisurf->prop.event_mask |= IVI_NOTIFICATION_ADD;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900771 }
Ucan, Emre (ADITG/SW1)38fcf382015-08-20 14:13:29 +0000772
773 ivilayer->order.dirty = 0;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900774 }
775}
776
777static void
778commit_screen_list(struct ivi_layout *layout)
779{
780 struct ivi_layout_screen *iviscrn = NULL;
781 struct ivi_layout_layer *ivilayer = NULL;
782 struct ivi_layout_layer *next = NULL;
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000783 struct ivi_layout_view *ivi_view = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900784
Nobuhiko Tanibatafbfa8f22015-11-25 23:36:57 +0900785 /* Clear view list of layout ivi_layer */
786 wl_list_init(&layout->layout_layer.view_list.link);
787
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900788 wl_list_for_each(iviscrn, &layout->screen_list, link) {
Ucan, Emre (ADITG/SW1)174257b2015-08-20 14:13:30 +0000789 if (iviscrn->order.dirty) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900790 wl_list_for_each_safe(ivilayer, next,
791 &iviscrn->order.layer_list, order.link) {
Ucan, Emre (ADITG/SW1)8a223672015-08-28 12:58:55 +0000792 ivilayer->on_screen = NULL;
Ucan, Emre (ADITG/SW1)174257b2015-08-20 14:13:30 +0000793 wl_list_remove(&ivilayer->order.link);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900794 wl_list_init(&ivilayer->order.link);
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +0000795 ivilayer->prop.event_mask |= IVI_NOTIFICATION_REMOVE;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900796 }
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900797
Ucan, Emre (ADITG/SW1)174257b2015-08-20 14:13:30 +0000798 assert(wl_list_empty(&iviscrn->order.layer_list));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900799
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900800 wl_list_for_each(ivilayer, &iviscrn->pending.layer_list,
801 pending.link) {
Nobuhiko Tanibata77b0ee12015-11-25 23:36:46 +0900802 /* FIXME: avoid to insert order.link to multiple screens */
803 wl_list_remove(&ivilayer->order.link);
804
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900805 wl_list_insert(&iviscrn->order.layer_list,
806 &ivilayer->order.link);
Ucan, Emre (ADITG/SW1)8a223672015-08-28 12:58:55 +0000807 ivilayer->on_screen = iviscrn;
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +0000808 ivilayer->prop.event_mask |= IVI_NOTIFICATION_ADD;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900809 }
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900810
Ucan, Emre (ADITG/SW1)174257b2015-08-20 14:13:30 +0000811 iviscrn->order.dirty = 0;
812 }
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900813
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900814 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
815 if (ivilayer->prop.visibility == false)
816 continue;
817
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000818 wl_list_for_each(ivi_view, &ivilayer->order.view_list, order_link) {
819 if (ivi_view->ivisurf->prop.visibility == false)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900820 continue;
Ucan, Emre (ADITG/SW1)64635ee2015-08-28 12:59:06 +0000821
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900822 weston_layer_entry_insert(&layout->layout_layer.view_list,
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000823 &ivi_view->view->layer_link);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900824
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000825 ivi_view->view->output = iviscrn->output;
Armin Krezović50ff4bf2016-06-30 06:04:31 +0200826 ivi_view->ivisurf->surface->is_mapped = true;
827 ivi_view->view->is_mapped = true;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900828 }
829 }
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900830 }
831}
832
833static void
834commit_transition(struct ivi_layout* layout)
835{
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300836 if (wl_list_empty(&layout->pending_transition_list)) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900837 return;
838 }
839
840 wl_list_insert_list(&layout->transitions->transition_list,
841 &layout->pending_transition_list);
842
843 wl_list_init(&layout->pending_transition_list);
844
845 wl_event_source_timer_update(layout->transitions->event_source, 1);
846}
847
848static void
849send_surface_prop(struct ivi_layout_surface *ivisurf)
850{
851 wl_signal_emit(&ivisurf->property_changed, ivisurf);
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +0000852 ivisurf->pending.prop.event_mask = 0;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900853}
854
855static void
856send_layer_prop(struct ivi_layout_layer *ivilayer)
857{
858 wl_signal_emit(&ivilayer->property_changed, ivilayer);
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +0000859 ivilayer->pending.prop.event_mask = 0;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900860}
861
862static void
863send_prop(struct ivi_layout *layout)
864{
865 struct ivi_layout_layer *ivilayer = NULL;
866 struct ivi_layout_surface *ivisurf = NULL;
867
868 wl_list_for_each_reverse(ivilayer, &layout->layer_list, link) {
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +0000869 if (ivilayer->prop.event_mask)
Nobuhiko Tanibata6ce3ef82015-06-22 15:32:06 +0900870 send_layer_prop(ivilayer);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900871 }
872
873 wl_list_for_each_reverse(ivisurf, &layout->surface_list, link) {
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +0000874 if (ivisurf->prop.event_mask)
Nobuhiko Tanibata6ce3ef82015-06-22 15:32:06 +0900875 send_surface_prop(ivisurf);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900876 }
877}
878
879static void
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000880clear_view_pending_list(struct ivi_layout_layer *ivilayer)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900881{
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000882 struct ivi_layout_view *view_link = NULL;
883 struct ivi_layout_view *view_next = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900884
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +0000885 wl_list_for_each_safe(view_link, view_next,
886 &ivilayer->pending.view_list, pending_link) {
887 wl_list_remove(&view_link->pending_link);
888 wl_list_init(&view_link->pending_link);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900889 }
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900890}
891
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900892/**
893 * Exported APIs of ivi-layout library are implemented from here.
894 * Brief of APIs is described in ivi-layout-export.h.
895 */
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900896static int32_t
Ucan, Emre (ADITG/SW1)c98f2cf2016-04-04 08:05:12 +0000897ivi_layout_add_listener_create_layer(struct wl_listener *listener)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900898{
899 struct ivi_layout *layout = get_instance();
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900900
Ucan, Emre (ADITG/SW1)c98f2cf2016-04-04 08:05:12 +0000901 if (listener == NULL) {
902 weston_log("ivi_layout_add_listener_create_layer: invalid argument\n");
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900903 return IVI_FAILED;
904 }
905
Ucan, Emre (ADITG/SW1)c98f2cf2016-04-04 08:05:12 +0000906 wl_signal_add(&layout->layer_notification.created, listener);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900907
Ucan, Emre (ADITG/SW1)c98f2cf2016-04-04 08:05:12 +0000908 return IVI_SUCCEEDED;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900909}
910
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900911static int32_t
Ucan, Emre (ADITG/SW1)562f2ec2016-04-04 08:05:15 +0000912ivi_layout_add_listener_remove_layer(struct wl_listener *listener)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900913{
914 struct ivi_layout *layout = get_instance();
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900915
Ucan, Emre (ADITG/SW1)562f2ec2016-04-04 08:05:15 +0000916 if (listener == NULL) {
917 weston_log("ivi_layout_add_listener_remove_layer: invalid argument\n");
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900918 return IVI_FAILED;
919 }
920
Ucan, Emre (ADITG/SW1)562f2ec2016-04-04 08:05:15 +0000921 wl_signal_add(&layout->layer_notification.removed, listener);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900922
Ucan, Emre (ADITG/SW1)562f2ec2016-04-04 08:05:15 +0000923 return IVI_SUCCEEDED;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900924}
925
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900926static int32_t
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000927ivi_layout_add_listener_create_surface(struct wl_listener *listener)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900928{
929 struct ivi_layout *layout = get_instance();
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900930
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000931 if (listener == NULL) {
932 weston_log("ivi_layout_add_listener_create_surface: invalid argument\n");
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900933 return IVI_FAILED;
934 }
935
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000936 wl_signal_add(&layout->surface_notification.created, listener);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900937
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +0000938 return IVI_SUCCEEDED;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900939}
940
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900941static int32_t
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000942ivi_layout_add_listener_remove_surface(struct wl_listener *listener)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900943{
944 struct ivi_layout *layout = get_instance();
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900945
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000946 if (listener == NULL) {
947 weston_log("ivi_layout_add_listener_remove_surface: invalid argument\n");
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900948 return IVI_FAILED;
949 }
950
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000951 wl_signal_add(&layout->surface_notification.removed, listener);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900952
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +0000953 return IVI_SUCCEEDED;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900954}
955
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900956static int32_t
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000957ivi_layout_add_listener_configure_surface(struct wl_listener *listener)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900958{
959 struct ivi_layout *layout = get_instance();
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000960
961 if (listener == NULL) {
962 weston_log("ivi_layout_add_listener_configure_surface: invalid argument\n");
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900963 return IVI_FAILED;
964 }
965
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000966 wl_signal_add(&layout->surface_notification.configure_changed, listener);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900967
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +0000968 return IVI_SUCCEEDED;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900969}
970
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900971uint32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900972ivi_layout_get_id_of_surface(struct ivi_layout_surface *ivisurf)
973{
974 return ivisurf->id_surface;
975}
976
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900977static uint32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900978ivi_layout_get_id_of_layer(struct ivi_layout_layer *ivilayer)
979{
980 return ivilayer->id_layer;
981}
982
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900983static struct ivi_layout_layer *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900984ivi_layout_get_layer_from_id(uint32_t id_layer)
985{
986 struct ivi_layout *layout = get_instance();
987 struct ivi_layout_layer *ivilayer = NULL;
988
989 wl_list_for_each(ivilayer, &layout->layer_list, link) {
990 if (ivilayer->id_layer == id_layer) {
991 return ivilayer;
992 }
993 }
994
995 return NULL;
996}
997
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900998struct ivi_layout_surface *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900999ivi_layout_get_surface_from_id(uint32_t id_surface)
1000{
1001 struct ivi_layout *layout = get_instance();
1002 struct ivi_layout_surface *ivisurf = NULL;
1003
1004 wl_list_for_each(ivisurf, &layout->surface_list, link) {
1005 if (ivisurf->id_surface == id_surface) {
1006 return ivisurf;
1007 }
1008 }
1009
1010 return NULL;
1011}
1012
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001013static int32_t
Ucan, Emre (ADITG/SW1)706cb5a2016-04-04 08:05:03 +00001014ivi_layout_surface_add_listener(struct ivi_layout_surface *ivisurf,
1015 struct wl_listener *listener)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001016{
Ucan, Emre (ADITG/SW1)706cb5a2016-04-04 08:05:03 +00001017 if (ivisurf == NULL || listener == NULL) {
1018 weston_log("ivi_layout_surface_add_listener: invalid argument\n");
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001019 return IVI_FAILED;
1020 }
1021
Ucan, Emre (ADITG/SW1)706cb5a2016-04-04 08:05:03 +00001022 wl_signal_add(&ivisurf->property_changed, listener);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001023
1024 return IVI_SUCCEEDED;
1025}
1026
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001027static const struct ivi_layout_layer_properties *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001028ivi_layout_get_properties_of_layer(struct ivi_layout_layer *ivilayer)
1029{
1030 if (ivilayer == NULL) {
1031 weston_log("ivi_layout_get_properties_of_layer: invalid argument\n");
1032 return NULL;
1033 }
1034
1035 return &ivilayer->prop;
1036}
1037
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001038static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001039ivi_layout_get_screens_under_layer(struct ivi_layout_layer *ivilayer,
1040 int32_t *pLength,
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001041 struct weston_output ***ppArray)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001042{
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001043 int32_t length = 0;
1044 int32_t n = 0;
1045
1046 if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1047 weston_log("ivi_layout_get_screens_under_layer: invalid argument\n");
1048 return IVI_FAILED;
1049 }
1050
Ucan, Emre (ADITG/SW1)8a223672015-08-28 12:58:55 +00001051 if (ivilayer->on_screen != NULL)
1052 length = 1;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001053
Dawid Gajownik74a635b2015-08-06 17:12:19 -03001054 if (length != 0) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001055 /* the Array must be free by module which called this function */
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001056 *ppArray = calloc(length, sizeof(struct weston_output *));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001057 if (*ppArray == NULL) {
1058 weston_log("fails to allocate memory\n");
1059 return IVI_FAILED;
1060 }
1061
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001062 (*ppArray)[n++] = ivilayer->on_screen->output;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001063 }
1064
1065 *pLength = length;
1066
1067 return IVI_SUCCEEDED;
1068}
1069
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001070static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001071ivi_layout_get_layers(int32_t *pLength, struct ivi_layout_layer ***ppArray)
1072{
1073 struct ivi_layout *layout = get_instance();
1074 struct ivi_layout_layer *ivilayer = NULL;
1075 int32_t length = 0;
1076 int32_t n = 0;
1077
1078 if (pLength == NULL || ppArray == NULL) {
1079 weston_log("ivi_layout_get_layers: invalid argument\n");
1080 return IVI_FAILED;
1081 }
1082
1083 length = wl_list_length(&layout->layer_list);
1084
Dawid Gajownik74a635b2015-08-06 17:12:19 -03001085 if (length != 0) {
Bryce Harringtone6da35d2016-05-19 17:35:02 -07001086 /* the Array must be freed by module which called this function */
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001087 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1088 if (*ppArray == NULL) {
1089 weston_log("fails to allocate memory\n");
1090 return IVI_FAILED;
1091 }
1092
1093 wl_list_for_each(ivilayer, &layout->layer_list, link) {
1094 (*ppArray)[n++] = ivilayer;
1095 }
1096 }
1097
1098 *pLength = length;
1099
1100 return IVI_SUCCEEDED;
1101}
1102
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001103static int32_t
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001104ivi_layout_get_layers_on_screen(struct weston_output *output,
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001105 int32_t *pLength,
1106 struct ivi_layout_layer ***ppArray)
1107{
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001108 struct ivi_layout_screen *iviscrn = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001109 struct ivi_layout_layer *ivilayer = NULL;
1110 int32_t length = 0;
1111 int32_t n = 0;
1112
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001113 if (output == NULL || pLength == NULL || ppArray == NULL) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001114 weston_log("ivi_layout_get_layers_on_screen: invalid argument\n");
1115 return IVI_FAILED;
1116 }
1117
Ucan, Emre (ADITG/SW1)b216c922016-03-17 15:30:46 +00001118 iviscrn = get_screen_from_output(output);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001119 length = wl_list_length(&iviscrn->order.layer_list);
1120
Dawid Gajownik74a635b2015-08-06 17:12:19 -03001121 if (length != 0) {
Bryce Harringtone6da35d2016-05-19 17:35:02 -07001122 /* the Array must be freed by module which called this function */
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001123 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
1124 if (*ppArray == NULL) {
1125 weston_log("fails to allocate memory\n");
1126 return IVI_FAILED;
1127 }
1128
Nobuhiko Tanibatae2b82142015-06-22 15:30:19 +09001129 wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001130 (*ppArray)[n++] = ivilayer;
1131 }
1132 }
1133
1134 *pLength = length;
1135
1136 return IVI_SUCCEEDED;
1137}
1138
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001139static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001140ivi_layout_get_layers_under_surface(struct ivi_layout_surface *ivisurf,
1141 int32_t *pLength,
1142 struct ivi_layout_layer ***ppArray)
1143{
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001144 struct ivi_layout_view *ivi_view;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001145 int32_t length = 0;
1146 int32_t n = 0;
1147
1148 if (ivisurf == NULL || pLength == NULL || ppArray == NULL) {
1149 weston_log("ivi_layout_getLayers: invalid argument\n");
1150 return IVI_FAILED;
1151 }
1152
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001153 if (!wl_list_empty(&ivisurf->view_list)) {
1154 /* the Array must be free by module which called this function */
1155 length = wl_list_length(&ivisurf->view_list);
1156 *ppArray = calloc(length, sizeof(struct ivi_layout_layer *));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001157 if (*ppArray == NULL) {
1158 weston_log("fails to allocate memory\n");
1159 return IVI_FAILED;
1160 }
1161
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001162 wl_list_for_each_reverse(ivi_view, &ivisurf->view_list, surf_link) {
1163 if (ivi_view_is_rendered(ivi_view))
1164 (*ppArray)[n++] = ivi_view->on_layer;
1165 else
1166 length--;
1167 }
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001168 }
1169
1170 *pLength = length;
1171
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001172 if (!length) {
1173 free(*ppArray);
1174 *ppArray = NULL;
1175 }
1176
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001177 return IVI_SUCCEEDED;
1178}
1179
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001180static
1181int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001182ivi_layout_get_surfaces(int32_t *pLength, struct ivi_layout_surface ***ppArray)
1183{
1184 struct ivi_layout *layout = get_instance();
1185 struct ivi_layout_surface *ivisurf = NULL;
1186 int32_t length = 0;
1187 int32_t n = 0;
1188
1189 if (pLength == NULL || ppArray == NULL) {
1190 weston_log("ivi_layout_get_surfaces: invalid argument\n");
1191 return IVI_FAILED;
1192 }
1193
1194 length = wl_list_length(&layout->surface_list);
1195
Dawid Gajownik74a635b2015-08-06 17:12:19 -03001196 if (length != 0) {
Bryce Harringtone6da35d2016-05-19 17:35:02 -07001197 /* the Array must be freed by module which called this function */
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001198 *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1199 if (*ppArray == NULL) {
1200 weston_log("fails to allocate memory\n");
1201 return IVI_FAILED;
1202 }
1203
1204 wl_list_for_each(ivisurf, &layout->surface_list, link) {
1205 (*ppArray)[n++] = ivisurf;
1206 }
1207 }
1208
1209 *pLength = length;
1210
1211 return IVI_SUCCEEDED;
1212}
1213
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001214static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001215ivi_layout_get_surfaces_on_layer(struct ivi_layout_layer *ivilayer,
1216 int32_t *pLength,
1217 struct ivi_layout_surface ***ppArray)
1218{
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001219 struct ivi_layout_view *ivi_view = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001220 int32_t length = 0;
1221 int32_t n = 0;
1222
1223 if (ivilayer == NULL || pLength == NULL || ppArray == NULL) {
1224 weston_log("ivi_layout_getSurfaceIDsOnLayer: invalid argument\n");
1225 return IVI_FAILED;
1226 }
1227
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001228 length = wl_list_length(&ivilayer->order.view_list);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001229
1230 if (length != 0) {
Bryce Harringtone6da35d2016-05-19 17:35:02 -07001231 /* the Array must be freed by module which called this function */
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001232 *ppArray = calloc(length, sizeof(struct ivi_layout_surface *));
1233 if (*ppArray == NULL) {
1234 weston_log("fails to allocate memory\n");
1235 return IVI_FAILED;
1236 }
1237
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001238 wl_list_for_each(ivi_view, &ivilayer->order.view_list, order_link) {
1239 (*ppArray)[n++] = ivi_view->ivisurf;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001240 }
1241 }
1242
1243 *pLength = length;
1244
1245 return IVI_SUCCEEDED;
1246}
1247
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001248static struct ivi_layout_layer *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001249ivi_layout_layer_create_with_dimension(uint32_t id_layer,
1250 int32_t width, int32_t height)
1251{
1252 struct ivi_layout *layout = get_instance();
1253 struct ivi_layout_layer *ivilayer = NULL;
1254
1255 ivilayer = get_layer(&layout->layer_list, id_layer);
1256 if (ivilayer != NULL) {
1257 weston_log("id_layer is already created\n");
Nobuhiko Tanibata4b601e12015-06-22 15:31:16 +09001258 ++ivilayer->ref_count;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001259 return ivilayer;
1260 }
1261
1262 ivilayer = calloc(1, sizeof *ivilayer);
1263 if (ivilayer == NULL) {
1264 weston_log("fails to allocate memory\n");
1265 return NULL;
1266 }
1267
Nobuhiko Tanibata4b601e12015-06-22 15:31:16 +09001268 ivilayer->ref_count = 1;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001269 wl_signal_init(&ivilayer->property_changed);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001270 ivilayer->layout = layout;
1271 ivilayer->id_layer = id_layer;
1272
1273 init_layer_properties(&ivilayer->prop, width, height);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001274
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001275 wl_list_init(&ivilayer->pending.view_list);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001276 wl_list_init(&ivilayer->pending.link);
1277 ivilayer->pending.prop = ivilayer->prop;
1278
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001279 wl_list_init(&ivilayer->order.view_list);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001280 wl_list_init(&ivilayer->order.link);
1281
1282 wl_list_insert(&layout->layer_list, &ivilayer->link);
1283
1284 wl_signal_emit(&layout->layer_notification.created, ivilayer);
1285
1286 return ivilayer;
1287}
1288
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001289static void
Nobuhiko Tanibata3aa8aed2015-06-22 15:32:23 +09001290ivi_layout_layer_destroy(struct ivi_layout_layer *ivilayer)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001291{
1292 struct ivi_layout *layout = get_instance();
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001293 struct ivi_layout_view *ivi_view, *next;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001294
1295 if (ivilayer == NULL) {
Ucan, Emre (ADITG/SW1)66602522017-01-17 12:35:20 +00001296 weston_log("ivi_layout_layer_destroy: invalid argument\n");
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001297 return;
1298 }
1299
Nobuhiko Tanibata4b601e12015-06-22 15:31:16 +09001300 if (--ivilayer->ref_count > 0)
1301 return;
1302
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001303 /*Destroy all ivi_views*/
1304 wl_list_for_each_safe(ivi_view, next, &layout->view_list, link) {
1305 if (ivi_view->on_layer == ivilayer)
1306 ivi_view_destroy(ivi_view);
1307 }
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001308
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001309 wl_signal_emit(&layout->layer_notification.removed, ivilayer);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001310
Ucan, Emre (ADITG/SW1)cf34dc22015-08-20 14:13:33 +00001311 wl_list_remove(&ivilayer->pending.link);
1312 wl_list_remove(&ivilayer->order.link);
1313 wl_list_remove(&ivilayer->link);
1314
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001315 free(ivilayer);
1316}
1317
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001318int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001319ivi_layout_layer_set_visibility(struct ivi_layout_layer *ivilayer,
1320 bool newVisibility)
1321{
1322 struct ivi_layout_layer_properties *prop = NULL;
1323
1324 if (ivilayer == NULL) {
1325 weston_log("ivi_layout_layer_set_visibility: invalid argument\n");
1326 return IVI_FAILED;
1327 }
1328
1329 prop = &ivilayer->pending.prop;
1330 prop->visibility = newVisibility;
1331
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001332 if (ivilayer->prop.visibility != newVisibility)
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001333 prop->event_mask |= IVI_NOTIFICATION_VISIBILITY;
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001334 else
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001335 prop->event_mask &= ~IVI_NOTIFICATION_VISIBILITY;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001336
1337 return IVI_SUCCEEDED;
1338}
1339
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001340int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001341ivi_layout_layer_set_opacity(struct ivi_layout_layer *ivilayer,
1342 wl_fixed_t opacity)
1343{
1344 struct ivi_layout_layer_properties *prop = NULL;
1345
Nobuhiko Tanibata7bbacc62015-06-22 15:30:09 +09001346 if (ivilayer == NULL ||
1347 opacity < wl_fixed_from_double(0.0) ||
1348 wl_fixed_from_double(1.0) < opacity) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001349 weston_log("ivi_layout_layer_set_opacity: invalid argument\n");
1350 return IVI_FAILED;
1351 }
1352
1353 prop = &ivilayer->pending.prop;
1354 prop->opacity = opacity;
1355
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001356 if (ivilayer->prop.opacity != opacity)
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001357 prop->event_mask |= IVI_NOTIFICATION_OPACITY;
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001358 else
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001359 prop->event_mask &= ~IVI_NOTIFICATION_OPACITY;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001360
1361 return IVI_SUCCEEDED;
1362}
1363
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001364static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001365ivi_layout_layer_set_source_rectangle(struct ivi_layout_layer *ivilayer,
1366 int32_t x, int32_t y,
1367 int32_t width, int32_t height)
1368{
1369 struct ivi_layout_layer_properties *prop = NULL;
1370
1371 if (ivilayer == NULL) {
1372 weston_log("ivi_layout_layer_set_source_rectangle: invalid argument\n");
1373 return IVI_FAILED;
1374 }
1375
1376 prop = &ivilayer->pending.prop;
1377 prop->source_x = x;
1378 prop->source_y = y;
1379 prop->source_width = width;
1380 prop->source_height = height;
1381
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001382 if (ivilayer->prop.source_x != x || ivilayer->prop.source_y != y ||
1383 ivilayer->prop.source_width != width ||
1384 ivilayer->prop.source_height != height)
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001385 prop->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001386 else
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001387 prop->event_mask &= ~IVI_NOTIFICATION_SOURCE_RECT;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001388
1389 return IVI_SUCCEEDED;
1390}
1391
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +00001392int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001393ivi_layout_layer_set_destination_rectangle(struct ivi_layout_layer *ivilayer,
1394 int32_t x, int32_t y,
1395 int32_t width, int32_t height)
1396{
1397 struct ivi_layout_layer_properties *prop = NULL;
1398
1399 if (ivilayer == NULL) {
1400 weston_log("ivi_layout_layer_set_destination_rectangle: invalid argument\n");
1401 return IVI_FAILED;
1402 }
1403
1404 prop = &ivilayer->pending.prop;
1405 prop->dest_x = x;
1406 prop->dest_y = y;
1407 prop->dest_width = width;
1408 prop->dest_height = height;
1409
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001410 if (ivilayer->prop.dest_x != x || ivilayer->prop.dest_y != y ||
1411 ivilayer->prop.dest_width != width ||
1412 ivilayer->prop.dest_height != height)
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001413 prop->event_mask |= IVI_NOTIFICATION_DEST_RECT;
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001414 else
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001415 prop->event_mask &= ~IVI_NOTIFICATION_DEST_RECT;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001416
1417 return IVI_SUCCEEDED;
1418}
1419
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001420int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001421ivi_layout_layer_set_render_order(struct ivi_layout_layer *ivilayer,
1422 struct ivi_layout_surface **pSurface,
1423 int32_t number)
1424{
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001425 int32_t i = 0;
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001426 struct ivi_layout_view * ivi_view;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001427
1428 if (ivilayer == NULL) {
1429 weston_log("ivi_layout_layer_set_render_order: invalid argument\n");
1430 return IVI_FAILED;
1431 }
1432
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001433 clear_view_pending_list(ivilayer);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001434
1435 for (i = 0; i < number; i++) {
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001436 ivi_view = get_ivi_view(ivilayer, pSurface[i]);
1437 if (!ivi_view)
1438 ivi_view = ivi_view_create(ivilayer, pSurface[i]);
1439
1440 assert(ivi_view != NULL);
1441
1442 wl_list_remove(&ivi_view->pending_link);
1443 wl_list_insert(&ivilayer->pending.view_list, &ivi_view->pending_link);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001444 }
1445
Ucan, Emre (ADITG/SW1)38fcf382015-08-20 14:13:29 +00001446 ivilayer->order.dirty = 1;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001447
1448 return IVI_SUCCEEDED;
1449}
1450
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001451int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001452ivi_layout_surface_set_visibility(struct ivi_layout_surface *ivisurf,
1453 bool newVisibility)
1454{
1455 struct ivi_layout_surface_properties *prop = NULL;
1456
1457 if (ivisurf == NULL) {
1458 weston_log("ivi_layout_surface_set_visibility: invalid argument\n");
1459 return IVI_FAILED;
1460 }
1461
1462 prop = &ivisurf->pending.prop;
1463 prop->visibility = newVisibility;
1464
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001465 if (ivisurf->prop.visibility != newVisibility)
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001466 prop->event_mask |= IVI_NOTIFICATION_VISIBILITY;
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001467 else
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001468 prop->event_mask &= ~IVI_NOTIFICATION_VISIBILITY;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001469
1470 return IVI_SUCCEEDED;
1471}
1472
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001473int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001474ivi_layout_surface_set_opacity(struct ivi_layout_surface *ivisurf,
1475 wl_fixed_t opacity)
1476{
1477 struct ivi_layout_surface_properties *prop = NULL;
1478
Nobuhiko Tanibataa86226c2015-06-22 15:29:20 +09001479 if (ivisurf == NULL ||
1480 opacity < wl_fixed_from_double(0.0) ||
1481 wl_fixed_from_double(1.0) < opacity) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001482 weston_log("ivi_layout_surface_set_opacity: invalid argument\n");
1483 return IVI_FAILED;
1484 }
1485
1486 prop = &ivisurf->pending.prop;
1487 prop->opacity = opacity;
1488
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001489 if (ivisurf->prop.opacity != opacity)
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001490 prop->event_mask |= IVI_NOTIFICATION_OPACITY;
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001491 else
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001492 prop->event_mask &= ~IVI_NOTIFICATION_OPACITY;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001493
1494 return IVI_SUCCEEDED;
1495}
1496
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001497int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001498ivi_layout_surface_set_destination_rectangle(struct ivi_layout_surface *ivisurf,
1499 int32_t x, int32_t y,
1500 int32_t width, int32_t height)
1501{
1502 struct ivi_layout_surface_properties *prop = NULL;
1503
1504 if (ivisurf == NULL) {
1505 weston_log("ivi_layout_surface_set_destination_rectangle: invalid argument\n");
1506 return IVI_FAILED;
1507 }
1508
1509 prop = &ivisurf->pending.prop;
1510 prop->start_x = prop->dest_x;
1511 prop->start_y = prop->dest_y;
1512 prop->dest_x = x;
1513 prop->dest_y = y;
1514 prop->start_width = prop->dest_width;
1515 prop->start_height = prop->dest_height;
1516 prop->dest_width = width;
1517 prop->dest_height = height;
1518
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001519 if (ivisurf->prop.dest_x != x || ivisurf->prop.dest_y != y ||
1520 ivisurf->prop.dest_width != width ||
1521 ivisurf->prop.dest_height != height)
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001522 prop->event_mask |= IVI_NOTIFICATION_DEST_RECT;
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001523 else
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001524 prop->event_mask &= ~IVI_NOTIFICATION_DEST_RECT;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001525
1526 return IVI_SUCCEEDED;
1527}
1528
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001529static int32_t
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001530ivi_layout_screen_add_layer(struct weston_output *output,
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001531 struct ivi_layout_layer *addlayer)
1532{
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001533 struct ivi_layout_screen *iviscrn;
1534
1535 if (output == NULL || addlayer == NULL) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001536 weston_log("ivi_layout_screen_add_layer: invalid argument\n");
1537 return IVI_FAILED;
1538 }
1539
Ucan, Emre (ADITG/SW1)b216c922016-03-17 15:30:46 +00001540 iviscrn = get_screen_from_output(output);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001541
Ucan, Emre (ADITG/SW1)f46306f2016-03-16 13:37:07 +00001542 wl_list_remove(&addlayer->pending.link);
1543 wl_list_insert(&iviscrn->pending.layer_list, &addlayer->pending.link);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001544
Ucan, Emre (ADITG/SW1)174257b2015-08-20 14:13:30 +00001545 iviscrn->order.dirty = 1;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001546
1547 return IVI_SUCCEEDED;
1548}
1549
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001550static int32_t
Ucan, Emre (ADITG/SW1)deee8582017-03-02 08:47:33 +00001551ivi_layout_screen_remove_layer(struct weston_output *output,
1552 struct ivi_layout_layer *removelayer)
1553{
1554 struct ivi_layout_screen *iviscrn;
1555
1556 if (output == NULL || removelayer == NULL) {
1557 weston_log("ivi_layout_screen_remove_layer: invalid argument\n");
1558 return IVI_FAILED;
1559 }
1560
1561 iviscrn = get_screen_from_output(output);
1562
1563 wl_list_remove(&removelayer->pending.link);
1564 wl_list_init(&removelayer->pending.link);
1565
1566 iviscrn->order.dirty = 1;
1567
1568 return IVI_SUCCEEDED;
1569}
1570
1571static int32_t
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001572ivi_layout_screen_set_render_order(struct weston_output *output,
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001573 struct ivi_layout_layer **pLayer,
1574 const int32_t number)
1575{
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001576 struct ivi_layout_screen *iviscrn;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001577 struct ivi_layout_layer *ivilayer = NULL;
1578 struct ivi_layout_layer *next = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001579 int32_t i = 0;
1580
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001581 if (output == NULL) {
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001582 weston_log("ivi_layout_screen_set_render_order: invalid argument\n");
1583 return IVI_FAILED;
1584 }
1585
Ucan, Emre (ADITG/SW1)b216c922016-03-17 15:30:46 +00001586 iviscrn = get_screen_from_output(output);
Ucan, Emre (ADITG/SW1)273874e2016-03-17 15:30:42 +00001587
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001588 wl_list_for_each_safe(ivilayer, next,
1589 &iviscrn->pending.layer_list, pending.link) {
Ucan, Emre (ADITG/SW1)174257b2015-08-20 14:13:30 +00001590 wl_list_remove(&ivilayer->pending.link);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001591 wl_list_init(&ivilayer->pending.link);
1592 }
1593
Ucan, Emre (ADITG/SW1)174257b2015-08-20 14:13:30 +00001594 assert(wl_list_empty(&iviscrn->pending.layer_list));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001595
1596 for (i = 0; i < number; i++) {
Ucan, Emre (ADITG/SW1)4e221f02016-03-16 13:37:08 +00001597 wl_list_remove(&pLayer[i]->pending.link);
1598 wl_list_insert(&iviscrn->pending.layer_list,
1599 &pLayer[i]->pending.link);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001600 }
1601
Ucan, Emre (ADITG/SW1)174257b2015-08-20 14:13:30 +00001602 iviscrn->order.dirty = 1;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001603
1604 return IVI_SUCCEEDED;
1605}
1606
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001607/**
1608 * This function is used by the additional ivi-module because of dumping ivi_surface sceenshot.
1609 * The ivi-module, e.g. ivi-controller.so, is in wayland-ivi-extension of Genivi's Layer Management.
1610 * This function is used to get the result of drawing by clients.
1611 */
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001612static struct weston_surface *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001613ivi_layout_surface_get_weston_surface(struct ivi_layout_surface *ivisurf)
1614{
1615 return ivisurf != NULL ? ivisurf->surface : NULL;
1616}
1617
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001618static int32_t
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09001619ivi_layout_surface_get_size(struct ivi_layout_surface *ivisurf,
1620 int32_t *width, int32_t *height,
1621 int32_t *stride)
1622{
1623 int32_t w;
1624 int32_t h;
1625 const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
1626
1627 if (ivisurf == NULL || ivisurf->surface == NULL) {
1628 weston_log("%s: invalid argument\n", __func__);
1629 return IVI_FAILED;
1630 }
1631
1632 weston_surface_get_content_size(ivisurf->surface, &w, &h);
1633
1634 if (width != NULL)
1635 *width = w;
1636
1637 if (height != NULL)
1638 *height = h;
1639
1640 if (stride != NULL)
1641 *stride = w * bytespp;
1642
1643 return IVI_SUCCEEDED;
1644}
1645
1646static int32_t
Ucan, Emre (ADITG/SW1)3750d1b2016-04-04 08:05:05 +00001647ivi_layout_layer_add_listener(struct ivi_layout_layer *ivilayer,
1648 struct wl_listener *listener)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001649{
Ucan, Emre (ADITG/SW1)3750d1b2016-04-04 08:05:05 +00001650 if (ivilayer == NULL || listener == NULL) {
1651 weston_log("ivi_layout_layer_add_listener: invalid argument\n");
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001652 return IVI_FAILED;
1653 }
1654
Ucan, Emre (ADITG/SW1)3750d1b2016-04-04 08:05:05 +00001655 wl_signal_add(&ivilayer->property_changed, listener);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001656
Ucan, Emre (ADITG/SW1)3750d1b2016-04-04 08:05:05 +00001657 return IVI_SUCCEEDED;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001658}
1659
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001660static const struct ivi_layout_surface_properties *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001661ivi_layout_get_properties_of_surface(struct ivi_layout_surface *ivisurf)
1662{
1663 if (ivisurf == NULL) {
1664 weston_log("ivi_layout_get_properties_of_surface: invalid argument\n");
1665 return NULL;
1666 }
1667
1668 return &ivisurf->prop;
1669}
1670
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001671static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001672ivi_layout_layer_add_surface(struct ivi_layout_layer *ivilayer,
1673 struct ivi_layout_surface *addsurf)
1674{
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001675 struct ivi_layout_view *ivi_view;
1676
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001677 if (ivilayer == NULL || addsurf == NULL) {
1678 weston_log("ivi_layout_layer_add_surface: invalid argument\n");
1679 return IVI_FAILED;
1680 }
1681
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001682 ivi_view = get_ivi_view(ivilayer, addsurf);
1683 if (!ivi_view)
1684 ivi_view = ivi_view_create(ivilayer, addsurf);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001685
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001686 wl_list_remove(&ivi_view->pending_link);
1687 wl_list_insert(&ivilayer->pending.view_list, &ivi_view->pending_link);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001688
Ucan, Emre (ADITG/SW1)38fcf382015-08-20 14:13:29 +00001689 ivilayer->order.dirty = 1;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001690
1691 return IVI_SUCCEEDED;
1692}
1693
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001694static void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001695ivi_layout_layer_remove_surface(struct ivi_layout_layer *ivilayer,
1696 struct ivi_layout_surface *remsurf)
1697{
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001698 struct ivi_layout_view *ivi_view;
1699
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001700 if (ivilayer == NULL || remsurf == NULL) {
1701 weston_log("ivi_layout_layer_remove_surface: invalid argument\n");
1702 return;
1703 }
1704
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001705 ivi_view = get_ivi_view(ivilayer, remsurf);
1706 if (ivi_view) {
1707 wl_list_remove(&ivi_view->pending_link);
1708 wl_list_init(&ivi_view->pending_link);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001709
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001710 ivilayer->order.dirty = 1;
1711 }
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001712}
1713
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001714static int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001715ivi_layout_surface_set_source_rectangle(struct ivi_layout_surface *ivisurf,
1716 int32_t x, int32_t y,
1717 int32_t width, int32_t height)
1718{
1719 struct ivi_layout_surface_properties *prop = NULL;
1720
1721 if (ivisurf == NULL) {
1722 weston_log("ivi_layout_surface_set_source_rectangle: invalid argument\n");
1723 return IVI_FAILED;
1724 }
1725
1726 prop = &ivisurf->pending.prop;
1727 prop->source_x = x;
1728 prop->source_y = y;
1729 prop->source_width = width;
1730 prop->source_height = height;
1731
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001732 if (ivisurf->prop.source_x != x || ivisurf->prop.source_y != y ||
1733 ivisurf->prop.source_width != width ||
1734 ivisurf->prop.source_height != height)
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001735 prop->event_mask |= IVI_NOTIFICATION_SOURCE_RECT;
Nobuhiko Tanibata5d4a3232015-06-22 15:32:14 +09001736 else
Ucan, Emre (ADITG/SW1)0bd29b62016-03-31 11:08:52 +00001737 prop->event_mask &= ~IVI_NOTIFICATION_SOURCE_RECT;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001738
1739 return IVI_SUCCEEDED;
1740}
1741
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001742int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001743ivi_layout_commit_changes(void)
1744{
1745 struct ivi_layout *layout = get_instance();
1746
1747 commit_surface_list(layout);
1748 commit_layer_list(layout);
1749 commit_screen_list(layout);
1750
1751 commit_transition(layout);
1752
1753 commit_changes(layout);
1754 send_prop(layout);
1755 weston_compositor_schedule_repaint(layout->compositor);
1756
1757 return IVI_SUCCEEDED;
1758}
1759
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001760static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09001761ivi_layout_layer_set_transition(struct ivi_layout_layer *ivilayer,
1762 enum ivi_layout_transition_type type,
1763 uint32_t duration)
1764{
1765 if (ivilayer == NULL) {
1766 weston_log("%s: invalid argument\n", __func__);
1767 return -1;
1768 }
1769
1770 ivilayer->pending.prop.transition_type = type;
1771 ivilayer->pending.prop.transition_duration = duration;
1772
1773 return 0;
1774}
1775
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001776static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09001777ivi_layout_layer_set_fade_info(struct ivi_layout_layer* ivilayer,
1778 uint32_t is_fade_in,
1779 double start_alpha, double end_alpha)
1780{
1781 if (ivilayer == NULL) {
1782 weston_log("%s: invalid argument\n", __func__);
1783 return -1;
1784 }
1785
1786 ivilayer->pending.prop.is_fade_in = is_fade_in;
1787 ivilayer->pending.prop.start_alpha = start_alpha;
1788 ivilayer->pending.prop.end_alpha = end_alpha;
1789
1790 return 0;
1791}
1792
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001793static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09001794ivi_layout_surface_set_transition_duration(struct ivi_layout_surface *ivisurf,
1795 uint32_t duration)
1796{
1797 struct ivi_layout_surface_properties *prop;
1798
1799 if (ivisurf == NULL) {
1800 weston_log("%s: invalid argument\n", __func__);
1801 return -1;
1802 }
1803
1804 prop = &ivisurf->pending.prop;
1805 prop->transition_duration = duration*10;
1806 return 0;
1807}
1808
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001809static int32_t
Nobuhiko Tanibata3c6796f2014-12-15 13:20:58 +09001810ivi_layout_surface_set_transition(struct ivi_layout_surface *ivisurf,
1811 enum ivi_layout_transition_type type,
1812 uint32_t duration)
1813{
1814 struct ivi_layout_surface_properties *prop;
1815
1816 if (ivisurf == NULL) {
1817 weston_log("%s: invalid argument\n", __func__);
1818 return -1;
1819 }
1820
1821 prop = &ivisurf->pending.prop;
1822 prop->transition_type = type;
1823 prop->transition_duration = duration;
1824 return 0;
1825}
1826
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09001827static int32_t
1828ivi_layout_surface_dump(struct weston_surface *surface,
1829 void *target, size_t size,int32_t x, int32_t y,
1830 int32_t width, int32_t height)
1831{
1832 int result = 0;
1833
1834 if (surface == NULL) {
1835 weston_log("%s: invalid argument\n", __func__);
1836 return IVI_FAILED;
1837 }
1838
1839 result = weston_surface_copy_content(
1840 surface, target, size,
1841 x, y, width, height);
1842
1843 return result == 0 ? IVI_SUCCEEDED : IVI_FAILED;
1844}
1845
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09001846/**
1847 * methods of interaction between ivi-shell with ivi-layout
1848 */
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001849
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09001850void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001851ivi_layout_surface_configure(struct ivi_layout_surface *ivisurf,
1852 int32_t width, int32_t height)
1853{
1854 struct ivi_layout *layout = get_instance();
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001855
Nobuhiko Tanibatae6cc9972015-04-27 16:54:01 +09001856 /* emit callback which is set by ivi-layout api user */
1857 wl_signal_emit(&layout->surface_notification.configure_changed,
1858 ivisurf);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001859}
1860
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09001861struct ivi_layout_surface*
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001862ivi_layout_surface_create(struct weston_surface *wl_surface,
1863 uint32_t id_surface)
1864{
1865 struct ivi_layout *layout = get_instance();
1866 struct ivi_layout_surface *ivisurf = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001867
1868 if (wl_surface == NULL) {
1869 weston_log("ivi_layout_surface_create: invalid argument\n");
1870 return NULL;
1871 }
1872
1873 ivisurf = get_surface(&layout->surface_list, id_surface);
1874 if (ivisurf != NULL) {
1875 if (ivisurf->surface != NULL) {
1876 weston_log("id_surface(%d) is already created\n", id_surface);
1877 return NULL;
1878 }
1879 }
1880
1881 ivisurf = calloc(1, sizeof *ivisurf);
1882 if (ivisurf == NULL) {
1883 weston_log("fails to allocate memory\n");
1884 return NULL;
1885 }
1886
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001887 wl_signal_init(&ivisurf->property_changed);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001888 ivisurf->id_surface = id_surface;
1889 ivisurf->layout = layout;
1890
1891 ivisurf->surface = wl_surface;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001892
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001893 ivisurf->surface->width_from_buffer = 0;
1894 ivisurf->surface->height_from_buffer = 0;
1895
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001896 init_surface_properties(&ivisurf->prop);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001897
1898 ivisurf->pending.prop = ivisurf->prop;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001899
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001900 wl_list_init(&ivisurf->view_list);
1901
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001902 wl_list_insert(&layout->surface_list, &ivisurf->link);
1903
1904 wl_signal_emit(&layout->surface_notification.created, ivisurf);
1905
1906 return ivisurf;
1907}
1908
Nobuhiko Tanibata28dc18c2014-12-15 13:22:31 +09001909void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001910ivi_layout_init_with_compositor(struct weston_compositor *ec)
1911{
1912 struct ivi_layout *layout = get_instance();
1913
1914 layout->compositor = ec;
1915
1916 wl_list_init(&layout->surface_list);
1917 wl_list_init(&layout->layer_list);
1918 wl_list_init(&layout->screen_list);
Ucan, Emre (ADITG/SW1)5e8d55d2016-06-14 14:43:40 +00001919 wl_list_init(&layout->view_list);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001920
1921 wl_signal_init(&layout->layer_notification.created);
1922 wl_signal_init(&layout->layer_notification.removed);
1923
1924 wl_signal_init(&layout->surface_notification.created);
1925 wl_signal_init(&layout->surface_notification.removed);
1926 wl_signal_init(&layout->surface_notification.configure_changed);
1927
1928 /* Add layout_layer at the last of weston_compositor.layer_list */
Quentin Glidic82681572016-12-17 13:40:51 +01001929 weston_layer_init(&layout->layout_layer, ec);
1930 weston_layer_set_position(&layout->layout_layer,
1931 WESTON_LAYER_POSITION_NORMAL);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001932
1933 create_screen(ec);
1934
1935 layout->transitions = ivi_layout_transition_set_create(ec);
1936 wl_list_init(&layout->pending_transition_list);
1937}
1938
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00001939static struct ivi_layout_interface ivi_layout_interface = {
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001940 /**
1941 * commit all changes
1942 */
1943 .commit_changes = ivi_layout_commit_changes,
1944
1945 /**
1946 * surface controller interfaces
1947 */
Ucan, Emre (ADITG/SW1)970f8312016-04-04 08:05:09 +00001948 .add_listener_create_surface = ivi_layout_add_listener_create_surface,
Ucan, Emre (ADITG/SW1)67f0aa82016-04-04 08:05:18 +00001949 .add_listener_remove_surface = ivi_layout_add_listener_remove_surface,
Ucan, Emre (ADITG/SW1)c49aa5a2016-04-04 08:05:20 +00001950 .add_listener_configure_surface = ivi_layout_add_listener_configure_surface,
Pekka Paalaneneaa43fc2016-04-12 16:06:58 +03001951 .get_surface = shell_get_ivi_layout_surface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001952 .get_surfaces = ivi_layout_get_surfaces,
1953 .get_id_of_surface = ivi_layout_get_id_of_surface,
1954 .get_surface_from_id = ivi_layout_get_surface_from_id,
1955 .get_properties_of_surface = ivi_layout_get_properties_of_surface,
1956 .get_surfaces_on_layer = ivi_layout_get_surfaces_on_layer,
1957 .surface_set_visibility = ivi_layout_surface_set_visibility,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001958 .surface_set_opacity = ivi_layout_surface_set_opacity,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001959 .surface_set_source_rectangle = ivi_layout_surface_set_source_rectangle,
1960 .surface_set_destination_rectangle = ivi_layout_surface_set_destination_rectangle,
Ucan, Emre (ADITG/SW1)706cb5a2016-04-04 08:05:03 +00001961 .surface_add_listener = ivi_layout_surface_add_listener,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001962 .surface_get_weston_surface = ivi_layout_surface_get_weston_surface,
1963 .surface_set_transition = ivi_layout_surface_set_transition,
1964 .surface_set_transition_duration = ivi_layout_surface_set_transition_duration,
1965
1966 /**
1967 * layer controller interfaces
1968 */
Ucan, Emre (ADITG/SW1)c98f2cf2016-04-04 08:05:12 +00001969 .add_listener_create_layer = ivi_layout_add_listener_create_layer,
Ucan, Emre (ADITG/SW1)562f2ec2016-04-04 08:05:15 +00001970 .add_listener_remove_layer = ivi_layout_add_listener_remove_layer,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001971 .layer_create_with_dimension = ivi_layout_layer_create_with_dimension,
Nobuhiko Tanibata3aa8aed2015-06-22 15:32:23 +09001972 .layer_destroy = ivi_layout_layer_destroy,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001973 .get_layers = ivi_layout_get_layers,
1974 .get_id_of_layer = ivi_layout_get_id_of_layer,
1975 .get_layer_from_id = ivi_layout_get_layer_from_id,
1976 .get_properties_of_layer = ivi_layout_get_properties_of_layer,
1977 .get_layers_under_surface = ivi_layout_get_layers_under_surface,
1978 .get_layers_on_screen = ivi_layout_get_layers_on_screen,
1979 .layer_set_visibility = ivi_layout_layer_set_visibility,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001980 .layer_set_opacity = ivi_layout_layer_set_opacity,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001981 .layer_set_source_rectangle = ivi_layout_layer_set_source_rectangle,
1982 .layer_set_destination_rectangle = ivi_layout_layer_set_destination_rectangle,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001983 .layer_add_surface = ivi_layout_layer_add_surface,
1984 .layer_remove_surface = ivi_layout_layer_remove_surface,
1985 .layer_set_render_order = ivi_layout_layer_set_render_order,
Ucan, Emre (ADITG/SW1)3750d1b2016-04-04 08:05:05 +00001986 .layer_add_listener = ivi_layout_layer_add_listener,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001987 .layer_set_transition = ivi_layout_layer_set_transition,
1988
1989 /**
Ucan, Emre (ADITG/SW1)6d89b1c2016-03-17 15:30:49 +00001990 * screen controller interfaces
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001991 */
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001992 .get_screens_under_layer = ivi_layout_get_screens_under_layer,
1993 .screen_add_layer = ivi_layout_screen_add_layer,
Ucan, Emre (ADITG/SW1)deee8582017-03-02 08:47:33 +00001994 .screen_remove_layer = ivi_layout_screen_remove_layer,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001995 .screen_set_render_order = ivi_layout_screen_set_render_order,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09001996
1997 /**
1998 * animation
1999 */
2000 .transition_move_layer_cancel = ivi_layout_transition_move_layer_cancel,
Nobuhiko Tanibatac3fd6242015-04-21 02:13:15 +09002001 .layer_set_fade_info = ivi_layout_layer_set_fade_info,
2002
2003 /**
2004 * surface content dumping for debugging
2005 */
2006 .surface_get_size = ivi_layout_surface_get_size,
2007 .surface_dump = ivi_layout_surface_dump,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002008};
2009
2010int
2011load_controller_modules(struct weston_compositor *compositor, const char *modules,
2012 int *argc, char *argv[])
2013{
2014 const char *p, *end;
2015 char buffer[256];
2016 int (*controller_module_init)(struct weston_compositor *compositor,
2017 int *argc, char *argv[],
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00002018 const struct ivi_layout_interface *interface,
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002019 size_t interface_version);
2020
2021 if (modules == NULL)
2022 return 0;
2023
2024 p = modules;
2025 while (*p) {
2026 end = strchrnul(p, ',');
2027 snprintf(buffer, sizeof buffer, "%.*s", (int)(end - p), p);
2028
Quentin Glidic8af2bec2016-12-02 14:21:46 +01002029 controller_module_init =
2030 wet_load_module_entrypoint(buffer,
2031 "controller_module_init");
Pekka Paalanen97246c02015-03-26 15:47:29 +02002032 if (!controller_module_init)
2033 return -1;
2034
2035 if (controller_module_init(compositor, argc, argv,
Ucan, Emre \(ADITG/SW1\)0c0e51e2015-10-15 14:51:41 +00002036 &ivi_layout_interface,
2037 sizeof(struct ivi_layout_interface)) != 0) {
Pekka Paalanen97246c02015-03-26 15:47:29 +02002038 weston_log("ivi-shell: Initialization of controller module fails");
2039 return -1;
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +09002040 }
2041
2042 p = end;
2043 while (*p == ',')
2044 p++;
2045 }
2046
2047 return 0;
2048}