c28373d275934e934105084d82c3909aa28c4087
[profile/ivi/wayland-ivi-extension.git] / ivi-layermanagement-api / ilmControl / src / ilm_control_wayland_platform.c
1 /**************************************************************************
2  *
3  * Copyright (C) 2013 DENSO CORPORATION
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  ****************************************************************************/
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <memory.h>
22 #include <pthread.h>
23 #include <signal.h>
24 #include <stdbool.h>
25
26 #include <unistd.h>
27 #include <poll.h>
28
29 #include "ilm_common.h"
30 #include "ilm_control_platform.h"
31 #include "wayland-util.h"
32 #include "ivi-controller-client-protocol.h"
33
34 static ilmErrorTypes wayland_getPropertiesOfLayer(t_ilm_uint layerID,
35                          struct ilmLayerProperties* pLayerProperties);
36 static ilmErrorTypes wayland_getPropertiesOfScreen(t_ilm_display screenID,
37                          struct ilmScreenProperties* pScreenProperties);
38 static ilmErrorTypes wayland_getNumberOfHardwareLayers(t_ilm_uint screenID,
39                          t_ilm_uint* pNumberOfHardwareLayers);
40 static ilmErrorTypes wayland_getScreenIDs(t_ilm_uint* pNumberOfIDs,
41                          t_ilm_uint** ppIDs);
42 static ilmErrorTypes wayland_getLayerIDs(t_ilm_int* pLength,
43                          t_ilm_layer** ppArray);
44 static ilmErrorTypes wayland_getLayerIDsOnScreen(t_ilm_uint screenId,
45                          t_ilm_int* pLength, t_ilm_layer** ppArray);
46 static ilmErrorTypes wayland_getSurfaceIDs(t_ilm_int* pLength,
47                          t_ilm_surface** ppArray);
48 static ilmErrorTypes wayland_getSurfaceIDsOnLayer(t_ilm_layer layer,
49                          t_ilm_int* pLength, t_ilm_surface** ppArray);
50 static ilmErrorTypes wayland_layerCreateWithDimension(t_ilm_layer* pLayerId,
51                          t_ilm_uint width, t_ilm_uint height);
52 static ilmErrorTypes wayland_layerRemove(t_ilm_layer layerId);
53 static ilmErrorTypes wayland_layerGetType(t_ilm_layer layerId,
54                          ilmLayerType* pLayerType);
55 static ilmErrorTypes wayland_layerSetVisibility(t_ilm_layer layerId,
56                          t_ilm_bool newVisibility);
57 static ilmErrorTypes wayland_layerGetVisibility(t_ilm_layer layerId,
58                          t_ilm_bool *pVisibility);
59 static ilmErrorTypes wayland_layerSetOpacity(t_ilm_layer layerId,
60                          t_ilm_float opacity);
61 static ilmErrorTypes wayland_layerGetOpacity(t_ilm_layer layerId,
62                          t_ilm_float *pOpacity);
63 static ilmErrorTypes wayland_layerSetSourceRectangle(t_ilm_layer layerId,
64                          t_ilm_uint x, t_ilm_uint y,
65                          t_ilm_uint width, t_ilm_uint height);
66 static ilmErrorTypes wayland_layerSetDestinationRectangle(t_ilm_layer layerId,
67                          t_ilm_int x, t_ilm_int y,
68                          t_ilm_int width, t_ilm_int height);
69 static ilmErrorTypes wayland_layerGetDimension(t_ilm_layer layerId,
70                          t_ilm_uint *pDimension);
71 static ilmErrorTypes wayland_layerSetDimension(t_ilm_layer layerId,
72                          t_ilm_uint *pDimension);
73 static ilmErrorTypes wayland_layerGetPosition(t_ilm_layer layerId,
74                          t_ilm_uint *pPosition);
75 static ilmErrorTypes wayland_layerSetPosition(t_ilm_layer layerId,
76                          t_ilm_uint *pPosition);
77 static ilmErrorTypes wayland_layerSetOrientation(t_ilm_layer layerId,
78                          ilmOrientation orientation);
79 static ilmErrorTypes wayland_layerGetOrientation(t_ilm_layer layerId,
80                          ilmOrientation *pOrientation);
81 static ilmErrorTypes wayland_layerSetChromaKey(t_ilm_layer layerId,
82                          t_ilm_int* pColor);
83 static ilmErrorTypes wayland_layerSetRenderOrder(t_ilm_layer layerId,
84                          t_ilm_layer *pSurfaceId,
85                          t_ilm_int number);
86 static ilmErrorTypes wayland_layerGetCapabilities(t_ilm_layer layerId,
87                          t_ilm_layercapabilities *pCapabilities);
88 static ilmErrorTypes wayland_layerTypeGetCapabilities(ilmLayerType layerType,
89                          t_ilm_layercapabilities *pCapabilities);
90 static ilmErrorTypes wayland_surfaceSetVisibility(t_ilm_surface surfaceId,
91                          t_ilm_bool newVisibility);
92 static ilmErrorTypes wayland_surfaceSetOpacity(t_ilm_surface surfaceId,
93                          t_ilm_float opacity);
94 static ilmErrorTypes wayland_surfaceGetOpacity(t_ilm_surface surfaceId,
95                          t_ilm_float *pOpacity);
96 static ilmErrorTypes wayland_SetKeyboardFocusOn(t_ilm_surface surfaceId);
97 static ilmErrorTypes wayland_GetKeyboardFocusSurfaceId(
98                          t_ilm_surface* pSurfaceId);
99 static ilmErrorTypes wayland_surfaceSetDestinationRectangle(
100                          t_ilm_surface surfaceId,
101                          t_ilm_int x, t_ilm_int y,
102                          t_ilm_int width, t_ilm_int height);
103 static ilmErrorTypes wayland_surfaceSetDimension(t_ilm_surface surfaceId,
104                          t_ilm_uint *pDimension);
105 static ilmErrorTypes wayland_surfaceGetPosition(t_ilm_surface surfaceId,
106                          t_ilm_uint *pPosition);
107 static ilmErrorTypes wayland_surfaceSetPosition(t_ilm_surface surfaceId,
108                          t_ilm_uint *pPosition);
109 static ilmErrorTypes wayland_surfaceSetOrientation(t_ilm_surface surfaceId,
110                          ilmOrientation orientation);
111 static ilmErrorTypes wayland_surfaceGetOrientation(t_ilm_surface surfaceId,
112                          ilmOrientation *pOrientation);
113 static ilmErrorTypes wayland_surfaceGetPixelformat(t_ilm_layer surfaceId,
114                          ilmPixelFormat *pPixelformat);
115 static ilmErrorTypes wayland_surfaceSetChromaKey(t_ilm_surface surfaceId,
116                          t_ilm_int* pColor);
117 static ilmErrorTypes wayland_displaySetRenderOrder(t_ilm_display display,
118                          t_ilm_layer *pLayerId, const t_ilm_uint number);
119 static ilmErrorTypes wayland_takeScreenshot(t_ilm_uint screen,
120                          t_ilm_const_string filename);
121 static ilmErrorTypes wayland_takeLayerScreenshot(t_ilm_const_string filename,
122                          t_ilm_layer layerid);
123 static ilmErrorTypes wayland_takeSurfaceScreenshot(t_ilm_const_string filename,
124                          t_ilm_surface surfaceid);
125 static ilmErrorTypes wayland_SetOptimizationMode(ilmOptimization id,
126                          ilmOptimizationMode mode);
127 static ilmErrorTypes wayland_GetOptimizationMode(ilmOptimization id,
128                          ilmOptimizationMode* pMode);
129 static ilmErrorTypes wayland_layerAddNotification(t_ilm_layer layer,
130                          layerNotificationFunc callback);
131 static ilmErrorTypes wayland_layerRemoveNotification(t_ilm_layer layer);
132 static ilmErrorTypes wayland_surfaceAddNotification(t_ilm_surface surface,
133                          surfaceNotificationFunc callback);
134 static ilmErrorTypes wayland_surfaceRemoveNotification(t_ilm_surface surface);
135 static ilmErrorTypes wayland_init(t_ilm_nativedisplay nativedisplay);
136 static void wayland_destroy(void);
137 static ilmErrorTypes wayland_getNativeHandle(t_ilm_uint pid,
138                          t_ilm_int *n_handle,
139                          t_ilm_nativehandle **p_handles);
140 static ilmErrorTypes wayland_getPropertiesOfSurface(t_ilm_uint surfaceID,
141                          struct ilmSurfaceProperties* pSurfaceProperties);
142 static ilmErrorTypes wayland_layerAddSurface(t_ilm_layer layerId,
143                          t_ilm_surface surfaceId);
144 static ilmErrorTypes wayland_layerRemoveSurface(t_ilm_layer layerId,
145                          t_ilm_surface surfaceId);
146 static ilmErrorTypes wayland_surfaceGetDimension(t_ilm_surface surfaceId,
147                          t_ilm_uint *pDimension);
148 static ilmErrorTypes wayland_surfaceGetVisibility(t_ilm_surface surfaceId,
149                          t_ilm_bool *pVisibility);
150 static ilmErrorTypes wayland_surfaceSetSourceRectangle(t_ilm_surface surfaceId,
151                          t_ilm_int x, t_ilm_int y,
152                          t_ilm_int width, t_ilm_int height);
153 static ilmErrorTypes wayland_commitChanges(void);
154
155 void init_ilmControlPlatformTable(void)
156 {
157     gIlmControlPlatformFunc.getPropertiesOfLayer =
158         wayland_getPropertiesOfLayer;
159     gIlmControlPlatformFunc.getPropertiesOfScreen =
160         wayland_getPropertiesOfScreen;
161     gIlmControlPlatformFunc.getNumberOfHardwareLayers =
162         wayland_getNumberOfHardwareLayers;
163     gIlmControlPlatformFunc.getScreenIDs =
164         wayland_getScreenIDs;
165     gIlmControlPlatformFunc.getLayerIDs =
166         wayland_getLayerIDs;
167     gIlmControlPlatformFunc.getLayerIDsOnScreen =
168         wayland_getLayerIDsOnScreen;
169     gIlmControlPlatformFunc.getSurfaceIDs =
170         wayland_getSurfaceIDs;
171     gIlmControlPlatformFunc.getSurfaceIDsOnLayer =
172         wayland_getSurfaceIDsOnLayer;
173     gIlmControlPlatformFunc.layerCreateWithDimension =
174         wayland_layerCreateWithDimension;
175     gIlmControlPlatformFunc.layerRemove =
176         wayland_layerRemove;
177     gIlmControlPlatformFunc.layerGetType =
178         wayland_layerGetType;
179     gIlmControlPlatformFunc.layerSetVisibility =
180         wayland_layerSetVisibility;
181     gIlmControlPlatformFunc.layerGetVisibility =
182         wayland_layerGetVisibility;
183     gIlmControlPlatformFunc.layerSetOpacity =
184         wayland_layerSetOpacity;
185     gIlmControlPlatformFunc.layerGetOpacity =
186         wayland_layerGetOpacity;
187     gIlmControlPlatformFunc.layerSetSourceRectangle =
188         wayland_layerSetSourceRectangle;
189     gIlmControlPlatformFunc.layerSetDestinationRectangle =
190         wayland_layerSetDestinationRectangle;
191     gIlmControlPlatformFunc.layerGetDimension =
192         wayland_layerGetDimension;
193     gIlmControlPlatformFunc.layerSetDimension =
194         wayland_layerSetDimension;
195     gIlmControlPlatformFunc.layerGetPosition =
196         wayland_layerGetPosition;
197     gIlmControlPlatformFunc.layerSetPosition =
198         wayland_layerSetPosition;
199     gIlmControlPlatformFunc.layerSetOrientation =
200         wayland_layerSetOrientation;
201     gIlmControlPlatformFunc.layerGetOrientation =
202         wayland_layerGetOrientation;
203     gIlmControlPlatformFunc.layerSetChromaKey =
204         wayland_layerSetChromaKey;
205     gIlmControlPlatformFunc.layerSetRenderOrder =
206         wayland_layerSetRenderOrder;
207     gIlmControlPlatformFunc.layerGetCapabilities =
208         wayland_layerGetCapabilities;
209     gIlmControlPlatformFunc.layerTypeGetCapabilities =
210         wayland_layerTypeGetCapabilities;
211     gIlmControlPlatformFunc.surfaceSetVisibility =
212         wayland_surfaceSetVisibility;
213     gIlmControlPlatformFunc.surfaceSetOpacity =
214         wayland_surfaceSetOpacity;
215     gIlmControlPlatformFunc.surfaceGetOpacity =
216         wayland_surfaceGetOpacity;
217     gIlmControlPlatformFunc.SetKeyboardFocusOn =
218         wayland_SetKeyboardFocusOn;
219     gIlmControlPlatformFunc.GetKeyboardFocusSurfaceId =
220         wayland_GetKeyboardFocusSurfaceId;
221     gIlmControlPlatformFunc.surfaceSetDestinationRectangle =
222         wayland_surfaceSetDestinationRectangle;
223     gIlmControlPlatformFunc.surfaceSetDimension =
224         wayland_surfaceSetDimension;
225     gIlmControlPlatformFunc.surfaceGetPosition =
226         wayland_surfaceGetPosition;
227     gIlmControlPlatformFunc.surfaceSetPosition =
228         wayland_surfaceSetPosition;
229     gIlmControlPlatformFunc.surfaceSetOrientation =
230         wayland_surfaceSetOrientation;
231     gIlmControlPlatformFunc.surfaceGetOrientation =
232         wayland_surfaceGetOrientation;
233     gIlmControlPlatformFunc.surfaceGetPixelformat =
234         wayland_surfaceGetPixelformat;
235     gIlmControlPlatformFunc.surfaceSetChromaKey =
236         wayland_surfaceSetChromaKey;
237     gIlmControlPlatformFunc.displaySetRenderOrder =
238         wayland_displaySetRenderOrder;
239     gIlmControlPlatformFunc.takeScreenshot =
240         wayland_takeScreenshot;
241     gIlmControlPlatformFunc.takeLayerScreenshot =
242         wayland_takeLayerScreenshot;
243     gIlmControlPlatformFunc.takeSurfaceScreenshot =
244         wayland_takeSurfaceScreenshot;
245     gIlmControlPlatformFunc.SetOptimizationMode =
246         wayland_SetOptimizationMode;
247     gIlmControlPlatformFunc.GetOptimizationMode =
248         wayland_GetOptimizationMode;
249     gIlmControlPlatformFunc.layerAddNotification =
250         wayland_layerAddNotification;
251     gIlmControlPlatformFunc.layerRemoveNotification =
252         wayland_layerRemoveNotification;
253     gIlmControlPlatformFunc.surfaceAddNotification =
254         wayland_surfaceAddNotification;
255     gIlmControlPlatformFunc.surfaceRemoveNotification =
256         wayland_surfaceRemoveNotification;
257     gIlmControlPlatformFunc.init =
258         wayland_init;
259     gIlmControlPlatformFunc.destroy =
260         wayland_destroy;
261     gIlmControlPlatformFunc.getNativeHandle =
262         wayland_getNativeHandle;
263     gIlmControlPlatformFunc.getPropertiesOfSurface =
264         wayland_getPropertiesOfSurface;
265     gIlmControlPlatformFunc.layerAddSurface =
266         wayland_layerAddSurface;
267     gIlmControlPlatformFunc.layerRemoveSurface =
268         wayland_layerRemoveSurface;
269     gIlmControlPlatformFunc.surfaceGetDimension =
270         wayland_surfaceGetDimension;
271     gIlmControlPlatformFunc.surfaceGetVisibility =
272         wayland_surfaceGetVisibility;
273     gIlmControlPlatformFunc.surfaceSetSourceRectangle =
274         wayland_surfaceSetSourceRectangle;
275     gIlmControlPlatformFunc.commitChanges =
276         wayland_commitChanges;
277 }
278
279 struct surface_context {
280     struct wl_list link;
281
282     struct ivi_surface *surface;
283     struct ivi_controller_surface *controller;
284
285     t_ilm_uint id_surface;
286     struct ilmSurfaceProperties prop;
287     surfaceNotificationFunc notification;
288
289     struct {
290         struct wl_list link;
291     } order;
292
293     struct wayland_context *ctx;
294 };
295
296 struct layer_context {
297     struct wl_list link;
298
299     struct ivi_controller_layer *controller;
300     t_ilm_uint id_layer;
301
302     struct ilmLayerProperties prop;
303     layerNotificationFunc notification;
304
305     struct {
306         struct wl_list list_surface;
307         struct wl_list link;
308     } order;
309
310     struct wayland_context *ctx;
311 };
312
313 struct screen_context {
314     struct wl_list link;
315
316     struct wl_output *output;
317     struct ivi_controller_screen *controller;
318     t_ilm_uint id_from_server;
319     t_ilm_uint id_screen;
320
321     struct ilmScreenProperties prop;
322
323     struct {
324         struct wl_list list_layer;
325     } order;
326
327     struct ilm_control_context *ctx;
328 };
329
330 struct nativehandle_context {
331     uint32_t pid;
332     uint32_t nativehandle;
333     struct wl_list link;
334 };
335
336 struct wayland_context {
337     struct wl_display *display;
338     struct wl_registry *registry;
339     struct wl_event_queue *queue;
340     struct wl_compositor *compositor;
341     struct ivi_controller *controller;
342     uint32_t num_screen;
343
344     struct wl_list list_surface;
345     struct wl_list list_layer;
346     struct wl_list list_screen;
347 };
348
349 struct ilm_control_context {
350     struct wayland_context wl;
351     bool initialized;
352
353     uint32_t internal_id_layer;
354
355     struct wl_list list_nativehandle;
356
357     pthread_t thread;
358     pthread_mutex_t mutex;
359     uint32_t internal_id_surface;
360 };
361
362 static void roundtrip_done(void *data, struct wl_callback *callback,
363                            uint32_t serial)
364 {
365     (void) callback;
366     (void) serial;
367
368     *(int *)data = 1;
369 }
370
371 static struct wl_callback_listener roundtrip_listener = {roundtrip_done};
372
373 int display_roundtrip_queue(struct wl_display *display,
374                             struct wl_event_queue *queue)
375 {
376     int done = 0;
377     int ret = 0;
378     struct wl_callback *callback = wl_display_sync(display);
379     wl_proxy_set_queue((void *)callback, queue);
380     wl_callback_add_listener(callback, &roundtrip_listener, &done);
381
382     while (ret != -1 && !done)
383     {
384         ret = wl_display_dispatch_queue(display, queue);
385     }
386
387     wl_callback_destroy(callback);
388
389     return ret;
390 }
391
392 static inline void lock_context(struct ilm_control_context *ctx)
393 {
394    pthread_mutex_lock(&ctx->mutex);
395 }
396
397 static inline void unlock_context(struct ilm_control_context *ctx)
398 {
399    pthread_mutex_unlock(&ctx->mutex);
400 }
401
402 static int init_control(void);
403
404 static struct ilm_control_context* sync_and_acquire_instance(void);
405
406 static void release_instance(void);
407
408 static int create_controller_layer(struct wayland_context *ctx, t_ilm_uint width, t_ilm_uint height, t_ilm_layer layerid);
409
410 static int32_t
411 wayland_controller_is_inside_surface_list(struct wl_list *list,
412                                           uint32_t id_surface)
413 {
414     struct surface_context *ctx_surf = NULL;
415     wl_list_for_each(ctx_surf, list, link) {
416         if (ctx_surf->id_surface == id_surface) {
417             return 1;
418         }
419     }
420
421     return 0;
422 }
423
424 static int32_t
425 wayland_controller_is_inside_layer_list(struct wl_list *list,
426                                         uint32_t id_layer)
427 {
428     struct layer_context *ctx_layer = NULL;
429     wl_list_for_each(ctx_layer, list, link) {
430         if (ctx_layer->id_layer == id_layer) {
431             return 1;
432         }
433     }
434
435     return 0;
436 }
437
438 static struct layer_context*
439 wayland_controller_get_layer_context(struct wayland_context *ctx,
440                                      uint32_t id_layer)
441 {
442     struct layer_context *ctx_layer = NULL;
443
444     if (ctx->controller == NULL) {
445         fprintf(stderr, "controller is not initialized in ilmControl\n");
446         return NULL;
447     }
448
449     wl_list_for_each(ctx_layer, &ctx->list_layer, link) {
450         if (ctx_layer->id_layer == id_layer) {
451             return ctx_layer;
452         }
453     }
454
455     fprintf(stderr, "failed to get layer context in ilmControl\n");
456     return NULL;
457 }
458
459 static void
460 output_listener_geometry(void *data,
461                          struct wl_output *output,
462                          int32_t x,
463                          int32_t y,
464                          int32_t physical_width,
465                          int32_t physical_height,
466                          int32_t subpixel,
467                          const char *make,
468                          const char *model,
469                          int32_t transform)
470 {
471     (void)output;
472     (void)x;
473     (void)y;
474     (void)subpixel;
475     (void)make;
476     (void)model;
477     (void)transform;
478 }
479
480 static void
481 output_listener_mode(void *data,
482                      struct wl_output *output,
483                      uint32_t flags,
484                      int32_t width,
485                      int32_t height,
486                      int32_t refresh)
487 {
488     (void)data;
489     (void)output;
490     (void)flags;
491     (void)width;
492     (void)height;
493     (void)refresh;
494
495     if (flags & WL_OUTPUT_MODE_CURRENT)
496     {
497         struct screen_context *ctx_scrn = data;
498         ctx_scrn->prop.screenWidth = width;
499         ctx_scrn->prop.screenHeight = height;
500     }
501 }
502
503 static void
504 output_listener_done(void *data,
505                      struct wl_output *output)
506 {
507     (void)data;
508     (void)output;
509 }
510
511 static void
512 output_listener_scale(void *data,
513                       struct wl_output *output,
514                       int32_t factor)
515 {
516     (void)data;
517     (void)output;
518     (void)factor;
519 }
520
521 static struct wl_output_listener output_listener = {
522     output_listener_geometry,
523     output_listener_mode,
524     output_listener_done,
525     output_listener_scale
526 };
527
528 static struct screen_context*
529 get_screen_context_by_output(struct wayland_context *ctx,
530                              struct wl_output *output)
531 {
532     struct screen_context *ctx_scrn = NULL;
533     struct wl_proxy *pxy_out = NULL;
534     struct wl_proxy *pxy_out_in_scrn = NULL;
535     uint32_t pxy_id = 0;
536     uint32_t pxy_id_in_scrn = 0;
537
538     wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
539         pxy_out = (struct wl_proxy*)output;
540         pxy_out_in_scrn = (struct wl_proxy*)ctx_scrn->output;
541         pxy_id = wl_proxy_get_id(pxy_out);
542         pxy_id_in_scrn = wl_proxy_get_id(pxy_out_in_scrn);
543         if (pxy_id == pxy_id_in_scrn) {
544             return ctx_scrn;
545         }
546     }
547     return NULL;
548 }
549
550 static struct screen_context*
551 get_screen_context_by_serverid(struct wayland_context *ctx,
552                                uint32_t id_screen)
553 {
554     struct screen_context *ctx_scrn = NULL;
555
556     wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
557         if (ctx_scrn->id_from_server == id_screen) {
558             return ctx_scrn;
559         }
560     }
561     return NULL;
562 }
563
564 static void
565 add_orderlayer_to_screen(struct layer_context *ctx_layer,
566                          struct wl_output* output)
567 {
568     struct screen_context *ctx_scrn = NULL;
569
570     ctx_scrn = get_screen_context_by_output(ctx_layer->ctx, output);
571     if (ctx_scrn == NULL) {
572         fprintf(stderr, "failed to add_orderlayer_to_screen\n");
573         return;
574     }
575
576     int found = 0;
577     struct layer_context *layer_link;
578     wl_list_for_each(layer_link, &ctx_scrn->order.list_layer, order.link) {
579         if (layer_link == ctx_layer) {
580             found = 1;
581             break;
582         }
583     }
584
585     if (found == 0) {
586         wl_list_init(&ctx_layer->order.link);
587         wl_list_insert(&ctx_scrn->order.list_layer, &ctx_layer->order.link);
588     }
589 }
590
591 static void
592 remove_orderlayer_from_screen(struct layer_context *ctx_layer)
593 {
594     wl_list_remove(&ctx_layer->order.link);
595     wl_list_init(&ctx_layer->order.link);
596 }
597
598 static void
599 controller_layer_listener_visibility(void *data,
600                             struct ivi_controller_layer *controller,
601                             int32_t visibility)
602 {
603     struct layer_context *ctx_layer = data;
604
605     ctx_layer->prop.visibility = (t_ilm_bool)visibility;
606
607     if (ctx_layer->notification != NULL) {
608         ctx_layer->notification(ctx_layer->id_layer,
609                                 &ctx_layer->prop,
610                                 ILM_NOTIFICATION_VISIBILITY);
611     }
612 }
613
614 static void
615 controller_layer_listener_opacity(void *data,
616                        struct ivi_controller_layer *controller,
617                        wl_fixed_t opacity)
618 {
619     struct layer_context *ctx_layer = data;
620
621     ctx_layer->prop.opacity = (t_ilm_float)wl_fixed_to_double(opacity);
622
623     if (ctx_layer->notification != NULL) {
624         ctx_layer->notification(ctx_layer->id_layer,
625                                 &ctx_layer->prop,
626                                 ILM_NOTIFICATION_OPACITY);
627     }
628 }
629
630 static void
631 controller_layer_listener_source_rectangle(void *data,
632                                 struct ivi_controller_layer *controller,
633                                 int32_t x,
634                                 int32_t y,
635                                 int32_t width,
636                                 int32_t height)
637 {
638     struct layer_context *ctx_layer = data;
639
640     ctx_layer->prop.sourceX = (t_ilm_uint)x;
641     ctx_layer->prop.sourceY = (t_ilm_uint)y;
642     ctx_layer->prop.sourceWidth = (t_ilm_uint)width;
643     ctx_layer->prop.sourceHeight = (t_ilm_uint)height;
644     if (ctx_layer->prop.origSourceWidth == 0) {
645         ctx_layer->prop.origSourceWidth = (t_ilm_uint)width;
646     }
647     if (ctx_layer->prop.origSourceHeight == 0) {
648         ctx_layer->prop.origSourceHeight = (t_ilm_uint)height;
649     }
650
651     if (ctx_layer->notification != NULL) {
652         ctx_layer->notification(ctx_layer->id_layer,
653                                 &ctx_layer->prop,
654                                 ILM_NOTIFICATION_SOURCE_RECT);
655     }
656 }
657
658 static void
659 controller_layer_listener_destination_rectangle(void *data,
660                                      struct ivi_controller_layer *controller,
661                                      int32_t x,
662                                      int32_t y,
663                                      int32_t width,
664                                      int32_t height)
665 {
666     struct layer_context *ctx_layer = data;
667
668     ctx_layer->prop.destX = (t_ilm_uint)x;
669     ctx_layer->prop.destY = (t_ilm_uint)y;
670     ctx_layer->prop.destWidth = (t_ilm_uint)width;
671     ctx_layer->prop.destHeight = (t_ilm_uint)height;
672
673     if (ctx_layer->notification != NULL) {
674         ctx_layer->notification(ctx_layer->id_layer,
675                                 &ctx_layer->prop,
676                                 ILM_NOTIFICATION_DEST_RECT);
677     }
678 }
679
680 static void
681 controller_layer_listener_configuration(void *data,
682                           struct ivi_controller_layer *controller,
683                           int32_t width,
684                           int32_t height)
685 {
686     struct layer_context *ctx_layer = data;
687
688     ctx_layer->prop.sourceWidth = (t_ilm_uint)width;
689     ctx_layer->prop.sourceHeight = (t_ilm_uint)height;
690 }
691
692 static void
693 controller_layer_listener_orientation(void *data,
694                              struct ivi_controller_layer *controller,
695                              int32_t orientation)
696 {
697     ilmOrientation ilmorientation = ILM_ZERO;
698     struct layer_context *ctx_layer = data;
699
700     switch(orientation) {
701     case IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES:
702         ilmorientation = ILM_ZERO;
703         break;
704     case IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES:
705         ilmorientation = ILM_NINETY;
706         break;
707     case IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES:
708         ilmorientation = ILM_ONEHUNDREDEIGHTY;
709         break;
710     case IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES:
711         ilmorientation = ILM_TWOHUNDREDSEVENTY;
712         break;
713     default:
714         break;
715     }
716
717     ctx_layer->prop.orientation = ilmorientation;
718
719     if (ctx_layer->notification != NULL) {
720         ctx_layer->notification(ctx_layer->id_layer,
721                                 &ctx_layer->prop,
722                                 ILM_NOTIFICATION_ORIENTATION);
723     }
724 }
725
726 static void
727 controller_layer_listener_screen(void *data,
728                                  struct ivi_controller_layer *controller,
729                                  struct wl_output *output)
730 {
731     struct layer_context *ctx_layer = data;
732
733     if (output == NULL) {
734         remove_orderlayer_from_screen(ctx_layer);
735     } else {
736         add_orderlayer_to_screen(ctx_layer, output);
737     }
738 }
739
740 static void
741 controller_layer_listener_destroyed(void *data,
742                                     struct ivi_controller_layer *controller)
743 {
744     struct layer_context *ctx_layer = data;
745     wl_list_remove(&ctx_layer->link);
746     free(ctx_layer);
747 }
748
749 static struct ivi_controller_layer_listener controller_layer_listener =
750 {
751     controller_layer_listener_visibility,
752     controller_layer_listener_opacity,
753     controller_layer_listener_source_rectangle,
754     controller_layer_listener_destination_rectangle,
755     controller_layer_listener_configuration,
756     controller_layer_listener_orientation,
757     controller_layer_listener_screen,
758     controller_layer_listener_destroyed
759 };
760
761 static void
762 add_ordersurface_to_layer(struct surface_context *ctx_surf,
763                           struct ivi_controller_layer *layer)
764 {
765     struct layer_context *ctx_layer = NULL;
766     struct surface_context *link = NULL;
767     int found = 0;
768
769     ctx_layer = ivi_controller_layer_get_user_data(layer);
770
771     wl_list_for_each(link, &ctx_layer->order.list_surface, order.link) {
772         if (link == ctx_surf) {
773             found = 1;
774             break;
775         }
776     }
777
778     if (found == 0) {
779         wl_list_init(&ctx_surf->order.link);
780         wl_list_insert(&ctx_layer->order.list_surface, &ctx_surf->order.link);
781     }
782 }
783
784 static void
785 remove_ordersurface_from_layer(struct surface_context *ctx_surf)
786 {
787     wl_list_remove(&ctx_surf->order.link);
788     wl_list_init(&ctx_surf->order.link);
789 }
790
791 static void
792 controller_surface_listener_visibility(void *data,
793                             struct ivi_controller_surface *controller,
794                             int32_t visibility)
795 {
796     struct surface_context *ctx_surf = data;
797
798     ctx_surf->prop.visibility = (t_ilm_bool)visibility;
799
800     if (ctx_surf->notification != NULL) {
801         ctx_surf->notification(ctx_surf->id_surface,
802                                 &ctx_surf->prop,
803                                 ILM_NOTIFICATION_VISIBILITY);
804     }
805 }
806
807 static void
808 controller_surface_listener_opacity(void *data,
809                          struct ivi_controller_surface *controller,
810                          wl_fixed_t opacity)
811 {
812     struct surface_context *ctx_surf = data;
813
814     ctx_surf->prop.opacity = (t_ilm_float)wl_fixed_to_double(opacity);
815
816     if (ctx_surf->notification != NULL) {
817         ctx_surf->notification(ctx_surf->id_surface,
818                                 &ctx_surf->prop,
819                                 ILM_NOTIFICATION_OPACITY);
820     }
821 }
822
823 static void
824 controller_surface_listener_configuration(void *data,
825                            struct ivi_controller_surface *controller,
826                            int32_t width,
827                            int32_t height)
828 {
829     struct surface_context *ctx_surf = data;
830
831     ctx_surf->prop.sourceWidth = (t_ilm_uint)width;
832     ctx_surf->prop.sourceHeight = (t_ilm_uint)height;
833 }
834
835 static void
836 controller_surface_listener_source_rectangle(void *data,
837                                   struct ivi_controller_surface *controller,
838                                   int32_t x,
839                                   int32_t y,
840                                   int32_t width,
841                                   int32_t height)
842 {
843     struct surface_context *ctx_surf = data;
844
845     ctx_surf->prop.sourceX = (t_ilm_uint)x;
846     ctx_surf->prop.sourceY = (t_ilm_uint)y;
847     ctx_surf->prop.sourceWidth = (t_ilm_uint)width;
848     ctx_surf->prop.sourceHeight = (t_ilm_uint)height;
849     if (ctx_surf->prop.origSourceWidth == 0) {
850         ctx_surf->prop.origSourceWidth = (t_ilm_uint)width;
851     }
852     if (ctx_surf->prop.origSourceHeight == 0) {
853         ctx_surf->prop.origSourceHeight = (t_ilm_uint)height;
854     }
855
856     if (ctx_surf->notification != NULL) {
857         ctx_surf->notification(ctx_surf->id_surface,
858                                 &ctx_surf->prop,
859                                 ILM_NOTIFICATION_SOURCE_RECT);
860     }
861 }
862
863 static void
864 controller_surface_listener_destination_rectangle(void *data,
865                    struct ivi_controller_surface *controller,
866                    int32_t x,
867                    int32_t y,
868                    int32_t width,
869                    int32_t height)
870 {
871     struct surface_context *ctx_surf = data;
872
873     ctx_surf->prop.destX = (t_ilm_uint)x;
874     ctx_surf->prop.destY = (t_ilm_uint)y;
875     ctx_surf->prop.destWidth = (t_ilm_uint)width;
876     ctx_surf->prop.destHeight = (t_ilm_uint)height;
877
878     if (ctx_surf->notification != NULL) {
879         ctx_surf->notification(ctx_surf->id_surface,
880                                 &ctx_surf->prop,
881                                 ILM_NOTIFICATION_DEST_RECT);
882     }
883 }
884
885 static void
886 controller_surface_listener_orientation(void *data,
887                              struct ivi_controller_surface *controller,
888                              int32_t orientation)
889 {
890     struct surface_context *ctx_surf = data;
891     ilmOrientation ilmorientation = ILM_ZERO;
892
893     switch (orientation) {
894     case IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES:
895         ilmorientation = ILM_ZERO;
896         break;
897     case IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES:
898         ilmorientation = ILM_NINETY;
899         break;
900     case IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES:
901         ilmorientation = ILM_ONEHUNDREDEIGHTY;
902         break;
903     case IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES:
904         ilmorientation = ILM_TWOHUNDREDSEVENTY;
905         break;
906     default:
907         break;
908     }
909
910     ctx_surf->prop.orientation = ilmorientation;
911
912     if (ctx_surf->notification != NULL) {
913         ctx_surf->notification(ctx_surf->id_surface,
914                                 &ctx_surf->prop,
915                                 ILM_NOTIFICATION_ORIENTATION);
916     }
917 }
918
919 static void
920 controller_surface_listener_pixelformat(void *data,
921                              struct ivi_controller_surface *controller,
922                              int32_t pixelformat)
923 {
924     struct surface_context *ctx_surf = data;
925
926     ctx_surf->prop.pixelformat = (t_ilm_uint)pixelformat;
927 }
928
929 static void
930 controller_surface_listener_layer(void *data,
931                                   struct ivi_controller_surface *controller,
932                                   struct ivi_controller_layer *layer)
933 {
934     struct surface_context *ctx_surf = data;
935
936     if (layer == NULL) {
937         remove_ordersurface_from_layer(ctx_surf);
938     } else {
939         add_ordersurface_to_layer(ctx_surf, layer);
940     }
941 }
942
943 static void
944 controller_surface_listener_stats(void *data,
945                                   struct ivi_controller_surface *controller,
946                                   uint32_t redraw_count,
947                                   uint32_t frame_count,
948                                   uint32_t update_count,
949                                   uint32_t pid,
950                                   const char *process_name)
951 {
952     struct surface_context *ctx_surf = data;
953     (void)process_name;
954
955     ctx_surf->prop.drawCounter = (t_ilm_uint)redraw_count;
956     ctx_surf->prop.frameCounter = (t_ilm_uint)frame_count;
957     ctx_surf->prop.updateCounter = (t_ilm_uint)update_count;
958     ctx_surf->prop.creatorPid = (t_ilm_uint)pid;
959 }
960
961 static void
962 controller_surface_listener_destroyed(void *data,
963                   struct ivi_controller_surface *controller)
964 {
965     struct surface_context *ctx_surf = data;
966
967     wl_list_remove(&ctx_surf->link);
968     free(ctx_surf);
969 }
970
971 static void
972 controller_surface_listener_content(void *data,
973                    struct ivi_controller_surface *controller,
974                    int32_t content_state)
975 {
976     // if client surface (=content) was removed with ilm_surfaceDestroy()
977     // the expected behavior within ILM API mandates a full removal
978     // of the surface from the scene. We must remove the controller
979     // from scene, too.
980     if (IVI_CONTROLLER_SURFACE_CONTENT_STATE_CONTENT_REMOVED == content_state)
981     {
982         struct surface_context *ctx_surf = data;
983
984         ivi_controller_surface_destroy(controller, 1);
985
986         wl_list_remove(&ctx_surf->link);
987         free(ctx_surf);
988     }
989 }
990
991 static void
992 controller_surface_listener_input_focus(void *data,
993                    struct ivi_controller_surface *controller,
994                    int32_t enabled)
995 {
996     (void)data;
997     (void)controller;
998     (void)enabled;
999 }
1000
1001 static struct ivi_controller_surface_listener controller_surface_listener=
1002 {
1003     controller_surface_listener_visibility,
1004     controller_surface_listener_opacity,
1005     controller_surface_listener_source_rectangle,
1006     controller_surface_listener_destination_rectangle,
1007     controller_surface_listener_configuration,
1008     controller_surface_listener_orientation,
1009     controller_surface_listener_pixelformat,
1010     controller_surface_listener_layer,
1011     controller_surface_listener_stats,
1012     controller_surface_listener_destroyed,
1013     controller_surface_listener_content,
1014     controller_surface_listener_input_focus
1015 };
1016
1017 static void
1018 controller_listener_layer(void *data,
1019                           struct ivi_controller *controller,
1020                           uint32_t id_layer)
1021 {
1022    struct wayland_context *ctx = data;
1023
1024    if (wayland_controller_is_inside_layer_list(&ctx->list_layer, id_layer))
1025    {
1026       return;
1027    }
1028
1029    (void) create_controller_layer(ctx, 0, 0, id_layer);
1030 }
1031
1032 static void
1033 controller_listener_surface(void *data,
1034                             struct ivi_controller *controller,
1035                             uint32_t id_surface)
1036 {
1037     struct wayland_context *ctx = data;
1038     struct surface_context *ctx_surf = NULL;
1039     int32_t is_inside = 0;
1040
1041     is_inside = wayland_controller_is_inside_surface_list(
1042                     &ctx->list_surface, id_surface);
1043
1044     if (is_inside != 0) {
1045         fprintf(stderr, "invalid id_surface in controller_listener_surface\n");
1046         return;
1047     }
1048
1049     ctx_surf = calloc(1, sizeof *ctx_surf);
1050     if (ctx_surf == NULL) {
1051         fprintf(stderr, "Failed to allocate memory for surface_context\n");
1052         return;
1053     }
1054
1055     ctx_surf->controller = ivi_controller_surface_create(
1056                                controller, id_surface);
1057     if (ctx_surf->controller == NULL) {
1058         free(ctx_surf);
1059         fprintf(stderr, "Failed to create controller surface\n");
1060         return;
1061     }
1062     ctx_surf->id_surface = id_surface;
1063     ctx_surf->prop.inputDevicesAcceptance = ILM_INPUT_DEVICE_ALL;
1064     ctx_surf->ctx = ctx;
1065
1066     wl_list_init(&ctx_surf->link);
1067     wl_list_insert(&ctx->list_surface, &ctx_surf->link);
1068     wl_list_init(&ctx_surf->order.link);
1069     ivi_controller_surface_add_listener(ctx_surf->controller,
1070                                         &controller_surface_listener, ctx_surf);
1071 }
1072
1073 static void
1074 controller_listener_error(void *data,
1075                           struct ivi_controller *ivi_controller,
1076                           int32_t object_id,
1077                           int32_t object_type,
1078                           int32_t error_code,
1079                           const char *error_text)
1080 {
1081     (void)data;
1082     (void)ivi_controller;
1083     (void)object_id;
1084     (void)object_type;
1085     (void)error_code;
1086     (void)error_text;
1087 }
1088
1089 static void
1090 controller_listener_screen(void *data,
1091                            struct ivi_controller *ivi_controller,
1092                            uint32_t id_screen,
1093                            struct ivi_controller_screen *controller_screen)
1094 {
1095     struct wayland_context *ctx = data;
1096     struct screen_context *ctx_screen;
1097     (void)ivi_controller;
1098
1099     ctx_screen = get_screen_context_by_serverid(ctx, id_screen);
1100     if (ctx_screen == NULL) {
1101         fprintf(stderr, "Failed to allocate memory for screen_context\n");
1102         return;
1103     }
1104     ctx_screen->controller = controller_screen;
1105 }
1106
1107 static struct ivi_controller_listener controller_listener= {
1108     controller_listener_screen,
1109     controller_listener_layer,
1110     controller_listener_surface,
1111     controller_listener_error
1112 };
1113
1114 static void
1115 registry_handle_control(void *data,
1116                        struct wl_registry *registry,
1117                        uint32_t name, const char *interface,
1118                        uint32_t version)
1119 {
1120     struct wayland_context *ctx = data;
1121     (void)version;
1122
1123     if (strcmp(interface, "ivi_controller") == 0) {
1124         ctx->controller = wl_registry_bind(registry, name,
1125                                            &ivi_controller_interface, 1);
1126         if (ctx->controller == NULL) {
1127             fprintf(stderr, "Failed to registry bind ivi_controller\n");
1128             return;
1129         }
1130         if (ivi_controller_add_listener(ctx->controller,
1131                                        &controller_listener,
1132                                        ctx)) {
1133             fprintf(stderr, "Failed to add ivi_controller listener\n");
1134             return;
1135         }
1136     } else if (strcmp(interface, "wl_output") == 0) {
1137
1138         struct screen_context *ctx_scrn = calloc(1, sizeof *ctx_scrn);
1139         struct wl_proxy *pxy = NULL;
1140
1141         if (ctx_scrn == NULL) {
1142             fprintf(stderr, "Failed to allocate memory for screen_context\n");
1143             return;
1144         }
1145         wl_list_init(&ctx_scrn->link);
1146         ctx_scrn->output = wl_registry_bind(registry, name,
1147                                            &wl_output_interface, 1);
1148         if (ctx_scrn->output == NULL) {
1149             free(ctx_scrn);
1150             fprintf(stderr, "Failed to registry bind wl_output\n");
1151             return;
1152         }
1153
1154         if (wl_output_add_listener(ctx_scrn->output,
1155                                    &output_listener,
1156                                    ctx_scrn)) {
1157             free(ctx_scrn);
1158             fprintf(stderr, "Failed to add wl_output listener\n");
1159             return;
1160         }
1161
1162         pxy = (struct wl_proxy*)ctx_scrn->output;
1163         ctx_scrn->id_from_server = wl_proxy_get_id(pxy);
1164         ctx_scrn->id_screen = ctx->num_screen;
1165         ctx->num_screen++;
1166         wl_list_init(&ctx_scrn->order.list_layer);
1167         wl_list_insert(&ctx->list_screen, &ctx_scrn->link);
1168     }
1169 }
1170
1171 static const struct wl_registry_listener
1172 registry_control_listener= {
1173     registry_handle_control,
1174     NULL
1175 };
1176
1177 static struct ilm_control_context ilm_context;
1178
1179 static void destroy_control_resources(void)
1180 {
1181     struct ilm_control_context *ctx = &ilm_context;
1182
1183     if (ctx->wl.controller != NULL) {
1184         {
1185             struct surface_context *l;
1186             struct surface_context *n;
1187             wl_list_for_each_safe(l, n, &ctx->wl.list_surface, link) {
1188                 wl_list_remove(&l->link);
1189                 wl_list_remove(&l->order.link);
1190                 ivi_controller_surface_destroy(l->controller, 0);
1191                 free(l);
1192             }
1193         }
1194
1195         {
1196             struct layer_context *l;
1197             struct layer_context *n;
1198             wl_list_for_each_safe(l, n, &ctx->wl.list_layer, link) {
1199                 wl_list_remove(&l->link);
1200                 wl_list_remove(&l->order.link);
1201                 ivi_controller_layer_destroy(l->controller, 0);
1202                 free(l);
1203             }
1204         }
1205
1206         {
1207             struct screen_context *ctx_scrn;
1208             struct screen_context *next;
1209
1210             wl_list_for_each_safe(ctx_scrn, next, &ctx->wl.list_screen, link) {
1211                 if (ctx_scrn->output != NULL) {
1212                     wl_output_destroy(ctx_scrn->output);
1213                 }
1214
1215                 wl_list_remove(&ctx_scrn->link);
1216                 ivi_controller_screen_destroy(ctx_scrn->controller);
1217                 free(ctx_scrn);
1218             }
1219         }
1220
1221         ivi_controller_destroy(ctx->wl.controller);
1222         ctx->wl.controller = NULL;
1223     }
1224
1225     wl_display_flush(ctx->wl.display);
1226
1227     wl_event_queue_destroy(ctx->wl.queue);
1228     ctx->wl.queue = NULL;
1229
1230     wl_registry_destroy(ctx->wl.registry);
1231     ctx->wl.registry = NULL;
1232
1233     if (0 != pthread_mutex_destroy(&ctx->mutex)) {
1234         fprintf(stderr, "failed to destroy pthread_mutex\n");
1235     }
1236 }
1237
1238 static void
1239 wayland_destroy(void)
1240 {
1241     struct ilm_control_context *ctx = &ilm_context;
1242     pthread_cancel(ctx->thread);
1243     if (0 != pthread_join(ctx->thread, NULL)) {
1244         fprintf(stderr, "failed to join control thread\n");
1245     }
1246     destroy_control_resources();
1247     memset(ctx, 0, sizeof *ctx);
1248 }
1249
1250 static ilmErrorTypes
1251 wayland_init(t_ilm_nativedisplay nativedisplay)
1252 {
1253     struct ilm_control_context *ctx = &ilm_context;
1254
1255     if (ctx->initialized)
1256     {
1257         fprintf(stderr, "Already initialized!\n");
1258         return ILM_FAILED;
1259     }
1260
1261     if (nativedisplay == 0) {
1262         return ILM_ERROR_INVALID_ARGUMENTS;
1263     }
1264
1265     memset(ctx, 0, sizeof *ctx);
1266
1267     ctx->wl.display = (struct wl_display*)nativedisplay;
1268
1269     wl_list_init(&ctx->wl.list_screen);
1270     wl_list_init(&ctx->wl.list_layer);
1271     wl_list_init(&ctx->wl.list_surface);
1272
1273     {
1274        pthread_mutexattr_t a;
1275        if (pthread_mutexattr_init(&a) != 0)
1276        {
1277           return ILM_FAILED;
1278        }
1279
1280        if (pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE) != 0)
1281        {
1282           pthread_mutexattr_destroy(&a);
1283           return ILM_FAILED;
1284        }
1285
1286        if (pthread_mutex_init(&ctx->mutex, &a) != 0)
1287        {
1288            pthread_mutexattr_destroy(&a);
1289            fprintf(stderr, "failed to initialize pthread_mutex\n");
1290            return ILM_FAILED;
1291        }
1292
1293        pthread_mutexattr_destroy(&a);
1294     }
1295
1296     return init_control() == 0 ? ILM_SUCCESS : ILM_FAILED;
1297 }
1298
1299 static void cancel_read(void *d)
1300 {
1301     wl_display_cancel_read(d);
1302 }
1303
1304 static void*
1305 control_thread(void *p_ret)
1306 {
1307     struct ilm_control_context *ctx = &ilm_context;
1308     struct wayland_context *wl = &ctx->wl;
1309     struct wl_display *display = wl->display;
1310     struct wl_event_queue *queue = wl->queue;
1311     int fd = wl_display_get_fd(display);
1312
1313     (void) p_ret;
1314
1315     while (1)
1316     {
1317         if (wl_display_prepare_read_queue(display, queue) != 0)
1318         {
1319             lock_context(ctx);
1320             wl_display_dispatch_queue_pending(display, queue);
1321             unlock_context(ctx);
1322
1323             continue;
1324         }
1325
1326         if (wl_display_flush(display) == -1)
1327         {
1328             break;
1329         }
1330
1331         struct pollfd pfd;
1332
1333         pfd.fd = fd;
1334         pfd.events = POLLIN;
1335         pfd.revents = 0;
1336
1337         int pollret = -1;
1338
1339         pthread_cleanup_push(cancel_read, display);
1340         pollret = poll(&pfd, 1, -1);
1341         pthread_cleanup_pop(0);
1342
1343         if (pollret != -1 && (pfd.revents & POLLIN))
1344         {
1345             wl_display_read_events(display);
1346
1347             lock_context(ctx);
1348             int ret = wl_display_dispatch_queue_pending(display, queue);
1349             unlock_context(ctx);
1350
1351             if (ret == -1)
1352             {
1353                 break;
1354             }
1355         }
1356         else
1357         {
1358             wl_display_cancel_read(display);
1359         }
1360     }
1361
1362     return NULL;
1363 }
1364
1365 static int
1366 init_control(void)
1367 {
1368     struct ilm_control_context *ctx = &ilm_context;
1369     struct wayland_context *wl = &ctx->wl;
1370     int wait_count = 0;
1371     int ret = 0;
1372
1373     wl_list_init(&ctx->list_nativehandle);
1374
1375     wl->queue = wl_display_create_queue(wl->display);
1376
1377     /* registry_add_listener for request by ivi-controller */
1378     wl->registry = wl_display_get_registry(wl->display);
1379     if (wl->registry == NULL) {
1380         fprintf(stderr, "Failed to get registry\n");
1381         return -1;
1382     }
1383     wl_proxy_set_queue((void*)wl->registry, wl->queue);
1384
1385     if (wl_registry_add_listener(wl->registry,
1386                              &registry_control_listener, ctx)) {
1387         fprintf(stderr, "Failed to add registry listener\n");
1388         return -1;
1389     }
1390
1391     // first level objects; ivi_controller
1392     display_roundtrip_queue(wl->display, wl->queue);
1393     // second level object: ivi_controller_surfaces/layers
1394     display_roundtrip_queue(wl->display, wl->queue);
1395     // third level objects: ivi_controller_surfaces/layers properties
1396     display_roundtrip_queue(wl->display, wl->queue);
1397
1398     ret = pthread_create(&ctx->thread, NULL, control_thread, NULL);
1399
1400     if (ret != 0) {
1401         fprintf(stderr, "Failed to start internal receive thread. returned %d\n", ret);
1402         return -1;
1403     }
1404
1405     ctx->initialized = true;
1406
1407     return 0;
1408 }
1409
1410 static struct ilm_control_context*
1411 sync_and_acquire_instance(void)
1412 {
1413     struct ilm_control_context *ctx = &ilm_context;
1414     lock_context(ctx);
1415     display_roundtrip_queue(ctx->wl.display, ctx->wl.queue);
1416     return ctx;
1417 }
1418
1419 static void release_instance(void)
1420 {
1421     struct ilm_control_context *ctx = &ilm_context;
1422     unlock_context(ctx);
1423 }
1424
1425 static uint32_t
1426 gen_layer_id(struct ilm_control_context *ctx)
1427 {
1428     struct layer_context *ctx_layer = NULL;
1429     do {
1430         int found = 0;
1431         if (wl_list_length(&ctx->wl.list_layer) == 0) {
1432             ctx->internal_id_layer++;
1433             return ctx->internal_id_layer;
1434         }
1435         wl_list_for_each(ctx_layer, &ctx->wl.list_layer, link) {
1436             if (ctx_layer->id_layer == ctx->internal_id_layer) {
1437                 found = 1;
1438                 break;
1439             }
1440
1441             if (found == 0) {
1442                 return ctx->internal_id_layer;
1443             }
1444         }
1445         ctx->internal_id_layer++;
1446     } while(1);
1447 }
1448
1449 static struct surface_context*
1450 get_surface_context(struct wayland_context *ctx,
1451                           uint32_t id_surface)
1452 {
1453     struct surface_context *ctx_surf = NULL;
1454
1455     if (ctx->controller == NULL) {
1456         fprintf(stderr, "controller is not initialized in ilmControl\n");
1457         return NULL;
1458     }
1459
1460     wl_list_for_each(ctx_surf, &ctx->list_surface, link) {
1461         if (ctx_surf->id_surface == id_surface) {
1462             return ctx_surf;
1463         }
1464     }
1465
1466     fprintf(stderr, "failed to get surface context in ilmControl\n");
1467     return NULL;
1468 }
1469
1470 static struct screen_context*
1471 get_screen_context_by_id(struct wayland_context *ctx, uint32_t id_screen)
1472 {
1473     struct screen_context *ctx_scrn = NULL;
1474
1475     if (ctx->controller == NULL) {
1476         fprintf(stderr, "get_screen_context_by_id: controller is NULL\n");
1477         return NULL;
1478     }
1479
1480     wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
1481         if (ctx_scrn->id_screen == id_screen) {
1482             return ctx_scrn;
1483         }
1484     }
1485     return NULL;
1486 }
1487
1488 static ilmErrorTypes
1489 wayland_getPropertiesOfLayer(t_ilm_uint layerID,
1490                          struct ilmLayerProperties* pLayerProperties)
1491 {
1492     ilmErrorTypes returnValue = ILM_FAILED;
1493     struct ilm_control_context *ctx = sync_and_acquire_instance();
1494     struct layer_context *ctx_layer = NULL;
1495
1496     if (pLayerProperties != NULL) {
1497
1498         ctx_layer = (struct layer_context*)
1499                     wayland_controller_get_layer_context(
1500                         &ctx->wl, (uint32_t)layerID);
1501
1502         if (ctx_layer != NULL) {
1503             *pLayerProperties = ctx_layer->prop;
1504             returnValue = ILM_SUCCESS;
1505         }
1506     }
1507
1508     release_instance();
1509     return returnValue;
1510 }
1511
1512 static void
1513 create_layerids(struct screen_context *ctx_screen,
1514                 t_ilm_layer **layer_ids, t_ilm_uint *layer_count)
1515 {
1516     struct layer_context *ctx_layer = NULL;
1517     t_ilm_layer *ids = NULL;
1518
1519     *layer_count = wl_list_length(&ctx_screen->order.list_layer);
1520     if (*layer_count == 0) {
1521         *layer_ids = NULL;
1522         return;
1523     }
1524
1525     *layer_ids = malloc(*layer_count * sizeof(t_ilm_layer));
1526     if (*layer_ids == NULL) {
1527         fprintf(stderr, "memory insufficient for layerids\n");
1528         *layer_count = 0;
1529         return;
1530     }
1531
1532     ids = *layer_ids;
1533     wl_list_for_each_reverse(ctx_layer, &ctx_screen->order.list_layer, order.link) {
1534         *ids = (t_ilm_layer)ctx_layer->id_layer;
1535         ids++;
1536     }
1537 }
1538
1539 static ilmErrorTypes
1540 wayland_getPropertiesOfScreen(t_ilm_display screenID,
1541                               struct ilmScreenProperties* pScreenProperties)
1542 {
1543     ilmErrorTypes returnValue = ILM_FAILED;
1544
1545     if (! pScreenProperties)
1546     {
1547         return ILM_ERROR_INVALID_ARGUMENTS;
1548     }
1549
1550     struct ilm_control_context *ctx = sync_and_acquire_instance();
1551
1552     struct screen_context *ctx_screen = NULL;
1553     ctx_screen = get_screen_context_by_id(&ctx->wl, (uint32_t)screenID);
1554     if (ctx_screen != NULL) {
1555         *pScreenProperties = ctx_screen->prop;
1556         create_layerids(ctx_screen, &pScreenProperties->layerIds,
1557                                     &pScreenProperties->layerCount);
1558         returnValue = ILM_SUCCESS;
1559     }
1560
1561     release_instance();
1562     return returnValue;
1563 }
1564
1565 static ilmErrorTypes
1566 wayland_getNumberOfHardwareLayers(t_ilm_uint screenID,
1567                                   t_ilm_uint* pNumberOfHardwareLayers)
1568 {
1569     (void)screenID;
1570     /* Not supported */
1571     if (pNumberOfHardwareLayers != NULL) {
1572         *pNumberOfHardwareLayers = 0;
1573         return ILM_SUCCESS;
1574     } else {
1575         return ILM_FAILED;
1576     }
1577 }
1578
1579 static ilmErrorTypes
1580 wayland_getScreenIDs(t_ilm_uint* pNumberOfIDs, t_ilm_uint** ppIDs)
1581 {
1582     ilmErrorTypes returnValue = ILM_FAILED;
1583     struct ilm_control_context *ctx = sync_and_acquire_instance();
1584
1585     if ((pNumberOfIDs != NULL) && (ppIDs != NULL)) {
1586         struct screen_context *ctx_scrn = NULL;
1587         t_ilm_uint length = wl_list_length(&ctx->wl.list_screen);
1588         *pNumberOfIDs = 0;
1589
1590         *ppIDs = (t_ilm_uint*)malloc(length * sizeof *ppIDs);
1591         if (*ppIDs != NULL) {
1592             t_ilm_uint* ids = *ppIDs;
1593             wl_list_for_each(ctx_scrn, &ctx->wl.list_screen, link) {
1594                 *ids = ctx_scrn->id_screen;
1595                 ids++;
1596             }
1597             *pNumberOfIDs = length;
1598
1599             returnValue = ILM_SUCCESS;
1600         }
1601     }
1602
1603     release_instance();
1604     return returnValue;
1605 }
1606
1607 static ilmErrorTypes
1608 wayland_getLayerIDs(t_ilm_int* pLength, t_ilm_layer** ppArray)
1609 {
1610     ilmErrorTypes returnValue = ILM_FAILED;
1611     struct ilm_control_context *ctx = sync_and_acquire_instance();
1612
1613     if ((pLength != NULL) && (ppArray != NULL)) {
1614         struct layer_context *ctx_layer = NULL;
1615         t_ilm_uint length = wl_list_length(&ctx->wl.list_layer);
1616         *pLength = 0;
1617
1618         *ppArray = (t_ilm_layer*)malloc(length * sizeof *ppArray);
1619         if (*ppArray != NULL) {
1620             // compositor sends layers in opposite order
1621             // write ids from back to front to turn them around
1622             t_ilm_layer* ids = *ppArray;
1623             wl_list_for_each_reverse(ctx_layer, &ctx->wl.list_layer, link)
1624             {
1625                 *ids = ctx_layer->id_layer;
1626                 ++ids;
1627             }
1628             *pLength = length;
1629
1630             returnValue = ILM_SUCCESS;
1631         }
1632     }
1633
1634     release_instance();
1635     return returnValue;
1636 }
1637
1638 static ilmErrorTypes
1639 wayland_getLayerIDsOnScreen(t_ilm_uint screenId,
1640                             t_ilm_int* pLength,
1641                             t_ilm_layer** ppArray)
1642 {
1643     ilmErrorTypes returnValue = ILM_FAILED;
1644     struct ilm_control_context *ctx = sync_and_acquire_instance();
1645
1646     if ((pLength != NULL) && (ppArray != NULL)) {
1647         struct screen_context *ctx_screen = NULL;
1648         ctx_screen = get_screen_context_by_id(&ctx->wl, screenId);
1649         if (ctx_screen != NULL) {
1650             struct layer_context *ctx_layer = NULL;
1651             t_ilm_int length = wl_list_length(&ctx_screen->order.list_layer);
1652
1653             if (0 < length)
1654             {
1655                 *ppArray = (t_ilm_layer*)malloc(length * sizeof *ppArray);
1656                 if (*ppArray != NULL) {
1657                     // compositor sends layers in opposite order
1658                     // write ids from back to front to turn them around
1659                     t_ilm_layer* ids = *ppArray;
1660                     wl_list_for_each_reverse(ctx_layer, &ctx_screen->order.list_layer, order.link)
1661                     {
1662                         *ids = ctx_layer->id_layer;
1663                         ++ids;
1664                     }
1665
1666                 }
1667             }
1668             else
1669             {
1670                 *ppArray = NULL;
1671             }
1672
1673             *pLength = length;
1674             returnValue = ILM_SUCCESS;
1675         }
1676     }
1677
1678     release_instance();
1679     return returnValue;
1680 }
1681
1682 static ilmErrorTypes
1683 wayland_getSurfaceIDs(t_ilm_int* pLength, t_ilm_surface** ppArray)
1684 {
1685     ilmErrorTypes returnValue = ILM_FAILED;
1686     struct ilm_control_context *ctx = sync_and_acquire_instance();
1687
1688     if ((pLength != NULL) && (ppArray != NULL)) {
1689         struct surface_context *ctx_surf = NULL;
1690         t_ilm_uint length = wl_list_length(&ctx->wl.list_surface);
1691         *pLength = 0;
1692
1693         *ppArray = (t_ilm_surface*)malloc(length * sizeof *ppArray);
1694         if (*ppArray != NULL) {
1695             t_ilm_surface* ids = *ppArray;
1696             wl_list_for_each_reverse(ctx_surf, &ctx->wl.list_surface, link) {
1697                 *ids = ctx_surf->id_surface;
1698                 ids++;
1699             }
1700             *pLength = length;
1701
1702             returnValue = ILM_SUCCESS;
1703         }
1704     }
1705
1706     release_instance();
1707     return returnValue;
1708 }
1709
1710 static ilmErrorTypes
1711 wayland_getSurfaceIDsOnLayer(t_ilm_layer layer,
1712                              t_ilm_int* pLength,
1713                              t_ilm_surface** ppArray)
1714 {
1715     struct ilm_control_context *ctx = sync_and_acquire_instance();
1716     struct layer_context *ctx_layer = NULL;
1717     struct surface_context *ctx_surf = NULL;
1718     t_ilm_uint length = 0;
1719     t_ilm_surface* ids = NULL;
1720
1721     if ((pLength == NULL) || (ppArray == NULL)) {
1722         release_instance();
1723         return ILM_FAILED;
1724     }
1725
1726     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1727                     &ctx->wl, (uint32_t)layer);
1728
1729     if (ctx_layer == NULL) {
1730         release_instance();
1731         return ILM_FAILED;
1732     }
1733
1734     length = wl_list_length(&ctx_layer->order.list_surface);
1735     *ppArray = (t_ilm_surface*)malloc(length * sizeof *ppArray);
1736     if (*ppArray == NULL) {
1737         release_instance();
1738         return ILM_FAILED;
1739     }
1740
1741     ids = *ppArray;
1742     wl_list_for_each_reverse(ctx_surf, &ctx_layer->order.list_surface, order.link) {
1743         *ids = (t_ilm_surface)ctx_surf->id_surface;
1744         ids++;
1745     }
1746     *pLength = length;
1747
1748     release_instance();
1749     return ILM_SUCCESS;
1750 }
1751
1752 static int create_controller_layer(struct wayland_context *ctx, t_ilm_uint width, t_ilm_uint height, t_ilm_layer layerid)
1753 {
1754      struct layer_context *ctx_layer = calloc(1, sizeof *ctx_layer);
1755      if (ctx_layer == NULL) {
1756          fprintf(stderr, "Failed to allocate memory for layer_context\n");
1757          return -1;
1758      }
1759
1760      ctx_layer->controller = ivi_controller_layer_create(
1761                                  ctx->controller,
1762                                  layerid, width, height);
1763      if (ctx_layer->controller == NULL) {
1764          fprintf(stderr, "Failed to create layer\n");
1765          free(ctx_layer);
1766          return -1;
1767      }
1768      ctx_layer->id_layer = layerid;
1769      ctx_layer->ctx = ctx;
1770
1771      wl_list_init(&ctx_layer->link);
1772      wl_list_insert(&ctx->list_layer, &ctx_layer->link);
1773      wl_list_init(&ctx_layer->order.link);
1774      wl_list_init(&ctx_layer->order.list_surface);
1775
1776      ivi_controller_layer_add_listener(ctx_layer->controller,
1777                                    &controller_layer_listener, ctx_layer);
1778
1779      return 0;
1780 }
1781
1782 static ilmErrorTypes
1783 wayland_layerCreateWithDimension(t_ilm_layer* pLayerId,
1784                                  t_ilm_uint width,
1785                                  t_ilm_uint height)
1786 {
1787     ilmErrorTypes returnValue = ILM_FAILED;
1788     struct ilm_control_context *ctx = sync_and_acquire_instance();
1789     uint32_t layerid = 0;
1790     int32_t is_inside = 0;
1791
1792     do {
1793         if (pLayerId == NULL) {
1794             break;
1795         }
1796
1797         if (*pLayerId != INVALID_ID) {
1798             /* Return failed, if layerid is already inside list_layer */
1799             is_inside = wayland_controller_is_inside_layer_list(
1800                             &ctx->wl.list_layer, *pLayerId);
1801             if (0 != is_inside) {
1802                 fprintf(stderr, "layerid=%d is already used.\n", *pLayerId);
1803                 break;
1804             }
1805             layerid = *pLayerId;
1806         }
1807         else {
1808             /* Generate ID, if layerid is INVALID_ID */
1809             layerid = gen_layer_id(ctx);
1810             *pLayerId = layerid;
1811         }
1812
1813         if (create_controller_layer(&ctx->wl, width, height, layerid) == 0)
1814         {
1815            returnValue = ILM_SUCCESS;
1816         }
1817     } while(0);
1818
1819     release_instance();
1820     return returnValue;
1821 }
1822
1823 static ilmErrorTypes
1824 wayland_layerRemove(t_ilm_layer layerId)
1825 {
1826     ilmErrorTypes returnValue = ILM_FAILED;
1827     struct ilm_control_context *ctx = sync_and_acquire_instance();
1828     struct layer_context *ctx_layer = NULL;
1829     struct layer_context *ctx_next = NULL;
1830
1831     wl_list_for_each_safe(ctx_layer, ctx_next,
1832             &ctx->wl.list_layer, link) {
1833         if (ctx_layer->id_layer == layerId) {
1834             ivi_controller_layer_destroy(ctx_layer->controller, 1);
1835
1836             wl_list_remove(&ctx_layer->link);
1837             free(ctx_layer);
1838
1839             returnValue = ILM_SUCCESS;
1840             break;
1841         }
1842     }
1843
1844     release_instance();
1845     return returnValue;
1846 }
1847
1848 static ilmErrorTypes
1849 wayland_layerGetType(t_ilm_layer layerId, ilmLayerType* pLayerType)
1850 {
1851     if (!pLayerType)
1852     {
1853        return ILM_ERROR_INVALID_ARGUMENTS;
1854     }
1855
1856     struct ilm_control_context *ctx = sync_and_acquire_instance();
1857
1858     *pLayerType = wayland_controller_is_inside_layer_list(&ctx->wl.list_layer, layerId) ?
1859        ILM_LAYERTYPE_SOFTWARE2D :
1860        ILM_LAYERTYPE_UNKNOWN;
1861
1862     release_instance();
1863     return ILM_SUCCESS; // even if non existent?
1864 }
1865
1866 static ilmErrorTypes
1867 wayland_layerSetVisibility(t_ilm_layer layerId, t_ilm_bool newVisibility)
1868 {
1869     ilmErrorTypes returnValue = ILM_FAILED;
1870     struct ilm_control_context *ctx = sync_and_acquire_instance();
1871     struct layer_context *ctx_layer = NULL;
1872
1873     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1874                     &ctx->wl, (uint32_t)layerId);
1875
1876     if (ctx_layer != NULL) {
1877         uint32_t visibility = 0;
1878         if (newVisibility == ILM_TRUE) {
1879             visibility = 1;
1880         }
1881         ivi_controller_layer_set_visibility(ctx_layer->controller,
1882                                             visibility);
1883         returnValue = ILM_SUCCESS;
1884     }
1885
1886     release_instance();
1887     return returnValue;
1888 }
1889
1890 static ilmErrorTypes
1891 wayland_layerGetVisibility(t_ilm_layer layerId, t_ilm_bool *pVisibility)
1892 {
1893     ilmErrorTypes returnValue = ILM_FAILED;
1894     struct ilm_control_context *ctx = sync_and_acquire_instance();
1895
1896     if (pVisibility != NULL) {
1897         struct layer_context *ctx_layer = NULL;
1898
1899         ctx_layer = (struct layer_context*)
1900                     wayland_controller_get_layer_context(
1901                         &ctx->wl, (uint32_t)layerId);
1902
1903         if (ctx_layer != NULL) {
1904             *pVisibility = ctx_layer->prop.visibility;
1905             returnValue = ILM_SUCCESS;
1906         }
1907     }
1908
1909     release_instance();
1910     return returnValue;
1911 }
1912
1913 static ilmErrorTypes
1914 wayland_layerSetOpacity(t_ilm_layer layerId, t_ilm_float opacity)
1915 {
1916     ilmErrorTypes returnValue = ILM_FAILED;
1917     struct ilm_control_context *ctx = sync_and_acquire_instance();
1918     struct layer_context *ctx_layer = NULL;
1919
1920     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1921                     &ctx->wl, (uint32_t)layerId);
1922
1923     if (ctx_layer != NULL) {
1924         wl_fixed_t opacity_fixed = wl_fixed_from_double((double)opacity);
1925         ivi_controller_layer_set_opacity(ctx_layer->controller,
1926                                          opacity_fixed);
1927         returnValue = ILM_SUCCESS;
1928     }
1929
1930     release_instance();
1931     return returnValue;
1932 }
1933
1934 static ilmErrorTypes
1935 wayland_layerGetOpacity(t_ilm_layer layerId, t_ilm_float *pOpacity)
1936 {
1937     ilmErrorTypes returnValue = ILM_FAILED;
1938     struct ilm_control_context *ctx = sync_and_acquire_instance();
1939
1940     if (pOpacity != NULL) {
1941         struct layer_context *ctx_layer = NULL;
1942
1943         ctx_layer = (struct layer_context*)
1944                     wayland_controller_get_layer_context(
1945                         &ctx->wl, (uint32_t)layerId);
1946
1947         if (ctx_layer != NULL) {
1948             *pOpacity = ctx_layer->prop.opacity;
1949             returnValue = ILM_SUCCESS;
1950         }
1951     }
1952
1953     release_instance();
1954     return returnValue;
1955 }
1956
1957 static ilmErrorTypes
1958 wayland_layerSetSourceRectangle(t_ilm_layer layerId,
1959                                 t_ilm_uint x, t_ilm_uint y,
1960                                 t_ilm_uint width, t_ilm_uint height)
1961 {
1962     ilmErrorTypes returnValue = ILM_FAILED;
1963     struct ilm_control_context *ctx = sync_and_acquire_instance();
1964     struct layer_context *ctx_layer = NULL;
1965
1966     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1967                     &ctx->wl, (uint32_t)layerId);
1968
1969     if (ctx_layer != NULL) {
1970         ivi_controller_layer_set_source_rectangle(ctx_layer->controller,
1971                                                   (uint32_t)x,
1972                                                   (uint32_t)y,
1973                                                   (uint32_t)width,
1974                                                   (uint32_t)height);
1975         returnValue = ILM_SUCCESS;
1976     }
1977
1978     release_instance();
1979     return returnValue;
1980 }
1981
1982 static ilmErrorTypes
1983 wayland_layerSetDestinationRectangle(t_ilm_layer layerId,
1984                                  t_ilm_int x, t_ilm_int y,
1985                                  t_ilm_int width, t_ilm_int height)
1986 {
1987     ilmErrorTypes returnValue = ILM_FAILED;
1988     struct ilm_control_context *ctx = sync_and_acquire_instance();
1989     struct layer_context *ctx_layer = NULL;
1990
1991     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1992                     &ctx->wl, (uint32_t)layerId);
1993     if (ctx_layer != NULL) {
1994         ivi_controller_layer_set_destination_rectangle(
1995                                          ctx_layer->controller,
1996                                          (uint32_t)x, (uint32_t)y,
1997                                          (uint32_t)width,
1998                                          (uint32_t)height);
1999         returnValue = ILM_SUCCESS;
2000     }
2001
2002     release_instance();
2003     return returnValue;
2004 }
2005
2006 static ilmErrorTypes
2007 wayland_layerGetDimension(t_ilm_layer layerId, t_ilm_uint *pDimension)
2008 {
2009     ilmErrorTypes returnValue = ILM_FAILED;
2010     struct ilm_control_context *ctx = sync_and_acquire_instance();
2011     struct layer_context *ctx_layer = NULL;
2012
2013     if (pDimension != NULL) {
2014         ctx_layer = (struct layer_context*)
2015                     wayland_controller_get_layer_context(
2016                         &ctx->wl, (uint32_t)layerId);
2017         if (ctx_layer != NULL) {
2018             *pDimension = ctx_layer->prop.destWidth;
2019             *(pDimension + 1) = ctx_layer->prop.destHeight;
2020             returnValue = ILM_SUCCESS;
2021         }
2022     }
2023
2024     release_instance();
2025     return returnValue;
2026 }
2027
2028 static ilmErrorTypes
2029 wayland_layerSetDimension(t_ilm_layer layerId, t_ilm_uint *pDimension)
2030 {
2031     ilmErrorTypes returnValue = ILM_FAILED;
2032     struct ilm_control_context *ctx = sync_and_acquire_instance();
2033     struct layer_context *ctx_layer = NULL;
2034
2035     if (pDimension != NULL) {
2036         ctx_layer = (struct layer_context*)
2037                     wayland_controller_get_layer_context(
2038                         &ctx->wl, (uint32_t)layerId);
2039         if (ctx_layer != NULL) {
2040             ivi_controller_layer_set_destination_rectangle(
2041                 ctx_layer->controller,
2042                 ctx_layer->prop.destX, ctx_layer->prop.destY,
2043                 (int32_t)*pDimension, (int32_t)*(pDimension + 1));
2044             returnValue = ILM_SUCCESS;
2045         }
2046     }
2047
2048     release_instance();
2049     return returnValue;
2050 }
2051
2052 static ilmErrorTypes
2053 wayland_layerGetPosition(t_ilm_layer layerId, t_ilm_uint *pPosition)
2054 {
2055     ilmErrorTypes returnValue = ILM_FAILED;
2056     struct ilm_control_context *ctx = sync_and_acquire_instance();
2057     struct layer_context *ctx_layer = NULL;
2058
2059     if (pPosition != NULL) {
2060         ctx_layer = (struct layer_context*)
2061                     wayland_controller_get_layer_context(
2062                         &ctx->wl, (uint32_t)layerId);
2063         if (ctx_layer != NULL) {
2064             *pPosition = ctx_layer->prop.destX;
2065             *(pPosition + 1) = ctx_layer->prop.destY;
2066             returnValue = ILM_SUCCESS;
2067         }
2068     }
2069
2070     release_instance();
2071     return returnValue;
2072 }
2073
2074 static ilmErrorTypes
2075 wayland_layerSetPosition(t_ilm_layer layerId, t_ilm_uint *pPosition)
2076 {
2077     ilmErrorTypes returnValue = ILM_FAILED;
2078     struct ilm_control_context *ctx = sync_and_acquire_instance();
2079     struct layer_context *ctx_layer = NULL;
2080
2081     if (pPosition != NULL) {
2082         ctx_layer = (struct layer_context*)
2083                     wayland_controller_get_layer_context(
2084                         &ctx->wl, (uint32_t)layerId);
2085         if (ctx_layer != NULL) {
2086             ivi_controller_layer_set_destination_rectangle(
2087                 ctx_layer->controller,
2088                 (int32_t)*pPosition, (int32_t)*(pPosition + 1),
2089                 ctx_layer->prop.destWidth, ctx_layer->prop.destHeight);
2090             returnValue = ILM_SUCCESS;
2091         }
2092     }
2093
2094     release_instance();
2095     return returnValue;
2096 }
2097
2098 static ilmErrorTypes
2099 wayland_layerSetOrientation(t_ilm_layer layerId, ilmOrientation orientation)
2100 {
2101     ilmErrorTypes returnValue = ILM_FAILED;
2102     struct ilm_control_context *ctx = sync_and_acquire_instance();
2103     struct layer_context *ctx_layer = NULL;
2104     int32_t iviorientation = 0;
2105
2106     do {
2107         switch(orientation) {
2108         case ILM_ZERO:
2109             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES;
2110             break;
2111         case ILM_NINETY:
2112             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES;
2113             break;
2114         case ILM_ONEHUNDREDEIGHTY:
2115             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES;
2116             break;
2117         case ILM_TWOHUNDREDSEVENTY:
2118             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES;
2119             break;
2120         default:
2121             returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2122             break;
2123         }
2124
2125         ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2126                         &ctx->wl, (uint32_t)layerId);
2127         if (ctx_layer == NULL) {
2128             returnValue = ILM_FAILED;
2129             break;
2130         }
2131
2132         ivi_controller_layer_set_orientation(ctx_layer->controller,
2133                                              iviorientation);
2134
2135         returnValue = ILM_SUCCESS;
2136     } while(0);
2137
2138     release_instance();
2139     return returnValue;
2140 }
2141
2142 static ilmErrorTypes
2143 wayland_layerGetOrientation(t_ilm_layer layerId, ilmOrientation *pOrientation)
2144 {
2145     ilmErrorTypes returnValue = ILM_FAILED;
2146     struct ilm_control_context *ctx = sync_and_acquire_instance();
2147     struct layer_context *ctx_layer = NULL;
2148
2149     if (pOrientation != NULL) {
2150         ctx_layer = (struct layer_context*)
2151                     wayland_controller_get_layer_context(
2152                         &ctx->wl, (uint32_t)layerId);
2153         if (ctx_layer != NULL) {
2154             *pOrientation = ctx_layer->prop.orientation;
2155             returnValue = ILM_SUCCESS;
2156         }
2157     }
2158
2159     release_instance();
2160     return returnValue;
2161 }
2162
2163 static ilmErrorTypes
2164 wayland_layerSetChromaKey(t_ilm_layer layerId, t_ilm_int* pColor)
2165 {
2166     (void)layerId;
2167     (void)pColor;
2168     /* Not supported */
2169     return ILM_FAILED;
2170 }
2171
2172 static ilmErrorTypes
2173 wayland_layerSetRenderOrder(t_ilm_layer layerId,
2174                         t_ilm_surface *pSurfaceId,
2175                         t_ilm_int number)
2176 {
2177     ilmErrorTypes returnValue = ILM_FAILED;
2178     struct ilm_control_context *ctx = sync_and_acquire_instance();
2179     struct layer_context *ctx_layer = NULL;
2180
2181     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2182                     &ctx->wl, (uint32_t)layerId);
2183
2184     if (ctx_layer)
2185     {
2186         struct wl_array ids;
2187         wl_array_init(&ids);
2188         uint32_t *pids = wl_array_add(&ids, number * sizeof *pids);
2189         t_ilm_uint i;
2190         for (i = 0; i < number; i++) pids[i] = (uint32_t)pSurfaceId[i];
2191         ivi_controller_layer_set_render_order(ctx_layer->controller, &ids);
2192         wl_array_release(&ids);
2193         returnValue = ILM_SUCCESS;
2194     }
2195
2196     release_instance();
2197     return returnValue;
2198 }
2199
2200 static ilmErrorTypes
2201 wayland_layerGetCapabilities(t_ilm_layer layerId,
2202                          t_ilm_layercapabilities *pCapabilities)
2203 {
2204     (void)layerId;
2205     (void)pCapabilities;
2206     /* Not supported */
2207     return ILM_FAILED;
2208 }
2209
2210 static ilmErrorTypes
2211 wayland_layerTypeGetCapabilities(ilmLayerType layerType,
2212                              t_ilm_layercapabilities *pCapabilities)
2213 {
2214     (void)layerType;
2215     (void)pCapabilities;
2216     /* Not supported */
2217     return ILM_FAILED;
2218 }
2219
2220 static ilmErrorTypes
2221 wayland_surfaceSetVisibility(t_ilm_surface surfaceId, t_ilm_bool newVisibility)
2222 {
2223     ilmErrorTypes returnValue = ILM_FAILED;
2224     struct ilm_control_context *ctx = sync_and_acquire_instance();
2225     struct surface_context *ctx_surf = NULL;
2226     uint32_t visibility = 0;
2227
2228     if (newVisibility == ILM_TRUE) {
2229         visibility = 1;
2230     }
2231     ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2232     if (ctx_surf) {
2233         ivi_controller_surface_set_visibility(ctx_surf->controller,
2234                                               visibility);
2235         returnValue = ILM_SUCCESS;
2236     }
2237
2238     release_instance();
2239     return returnValue;
2240 }
2241
2242 static ilmErrorTypes
2243 wayland_surfaceSetOpacity(t_ilm_surface surfaceId, t_ilm_float opacity)
2244 {
2245     ilmErrorTypes returnValue = ILM_FAILED;
2246     struct ilm_control_context *ctx = sync_and_acquire_instance();
2247     struct surface_context *ctx_surf = NULL;
2248     wl_fixed_t opacity_fixed = 0;
2249
2250     opacity_fixed = wl_fixed_from_double((double)opacity);
2251     ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2252     if (ctx_surf) {
2253         ivi_controller_surface_set_opacity(ctx_surf->controller,
2254                                            opacity_fixed);
2255         returnValue = ILM_SUCCESS;
2256     }
2257
2258     release_instance();
2259     return returnValue;
2260 }
2261
2262 static ilmErrorTypes
2263 wayland_surfaceGetOpacity(t_ilm_surface surfaceId, t_ilm_float *pOpacity)
2264 {
2265     ilmErrorTypes returnValue = ILM_FAILED;
2266     struct ilm_control_context *ctx = sync_and_acquire_instance();
2267
2268     if (pOpacity != NULL) {
2269         struct surface_context *ctx_surf = NULL;
2270         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2271         if (ctx_surf) {
2272             *pOpacity = ctx_surf->prop.opacity;
2273             returnValue = ILM_SUCCESS;
2274         }
2275     }
2276
2277     release_instance();
2278     return returnValue;
2279 }
2280
2281 static ilmErrorTypes
2282 wayland_SetKeyboardFocusOn(t_ilm_surface surfaceId)
2283 {
2284     ilmErrorTypes returnValue = ILM_FAILED;
2285     (void)surfaceId;
2286     returnValue = ILM_SUCCESS;
2287     return returnValue;
2288 }
2289
2290 static ilmErrorTypes
2291 wayland_GetKeyboardFocusSurfaceId(t_ilm_surface* pSurfaceId)
2292 {
2293     ilmErrorTypes returnValue = ILM_FAILED;
2294     (void)pSurfaceId;
2295     returnValue = ILM_SUCCESS;
2296     return returnValue;
2297 }
2298
2299 static ilmErrorTypes
2300 wayland_surfaceSetDestinationRectangle(t_ilm_surface surfaceId,
2301                                    t_ilm_int x, t_ilm_int y,
2302                                    t_ilm_int width, t_ilm_int height)
2303 {
2304     ilmErrorTypes returnValue = ILM_FAILED;
2305     struct ilm_control_context *ctx = sync_and_acquire_instance();
2306     struct surface_context *ctx_surf = NULL;
2307
2308     ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2309     if (ctx_surf) {
2310         ivi_controller_surface_set_destination_rectangle(
2311                                              ctx_surf->controller,
2312                                              x, y, width, height);
2313         returnValue = ILM_SUCCESS;
2314     }
2315
2316     release_instance();
2317     return returnValue;
2318 }
2319
2320 static ilmErrorTypes
2321 wayland_surfaceSetDimension(t_ilm_surface surfaceId, t_ilm_uint *pDimension)
2322 {
2323     ilmErrorTypes returnValue = ILM_FAILED;
2324     struct ilm_control_context *ctx = sync_and_acquire_instance();
2325
2326     if (pDimension != NULL) {
2327         struct surface_context *ctx_surf = NULL;
2328         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2329         if (ctx_surf) {
2330             uint32_t width = *pDimension;
2331             uint32_t height = *(pDimension + 1);
2332             ivi_controller_surface_set_destination_rectangle(
2333                 ctx_surf->controller,
2334                 ctx_surf->prop.destX, ctx_surf->prop.destY, width, height);
2335             returnValue = ILM_SUCCESS;
2336         }
2337     }
2338
2339     release_instance();
2340     return returnValue;
2341 }
2342
2343 static ilmErrorTypes
2344 wayland_surfaceGetPosition(t_ilm_surface surfaceId, t_ilm_uint *pPosition)
2345 {
2346     ilmErrorTypes returnValue = ILM_FAILED;
2347     struct ilm_control_context *ctx = sync_and_acquire_instance();
2348
2349     if (pPosition != NULL) {
2350         struct surface_context *ctx_surf = NULL;
2351         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2352         if (ctx_surf) {
2353             *pPosition = ctx_surf->prop.destX;
2354             *(pPosition + 1) = ctx_surf->prop.destY;
2355             returnValue = ILM_SUCCESS;
2356         }
2357     }
2358
2359     release_instance();
2360     return returnValue;
2361 }
2362
2363 static ilmErrorTypes
2364 wayland_surfaceSetPosition(t_ilm_surface surfaceId, t_ilm_uint *pPosition)
2365 {
2366     ilmErrorTypes returnValue = ILM_FAILED;
2367     struct ilm_control_context *ctx = sync_and_acquire_instance();
2368
2369     if (pPosition != NULL) {
2370         struct surface_context *ctx_surf = NULL;
2371         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2372         if (ctx_surf) {
2373             int32_t destX = (int32_t)*pPosition;
2374             int32_t destY = (int32_t)*(pPosition + 1);
2375             ivi_controller_surface_set_destination_rectangle(
2376                 ctx_surf->controller, destX, destY,
2377                 ctx_surf->prop.destWidth, ctx_surf->prop.destHeight);
2378             returnValue = ILM_SUCCESS;
2379         }
2380     }
2381
2382     release_instance();
2383     return returnValue;
2384 }
2385
2386 static ilmErrorTypes
2387 wayland_surfaceSetOrientation(t_ilm_surface surfaceId,
2388                               ilmOrientation orientation)
2389 {
2390     ilmErrorTypes returnValue = ILM_FAILED;
2391     struct ilm_control_context *ctx = sync_and_acquire_instance();
2392     struct surface_context *ctx_surf = NULL;
2393     int32_t iviorientation = 0;
2394
2395     do {
2396         switch(orientation) {
2397         case ILM_ZERO:
2398             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES;
2399             break;
2400         case ILM_NINETY:
2401             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES;
2402             break;
2403         case ILM_ONEHUNDREDEIGHTY:
2404             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES;
2405             break;
2406         case ILM_TWOHUNDREDSEVENTY:
2407             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES;
2408             break;
2409         default:
2410             returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2411             break;
2412         }
2413
2414         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2415         if (ctx_surf == NULL) {
2416             returnValue = ILM_FAILED;
2417             break;
2418         }
2419
2420         ivi_controller_surface_set_orientation(ctx_surf->controller,
2421                                                iviorientation);
2422
2423         returnValue = ILM_SUCCESS;
2424     } while(0);
2425
2426     release_instance();
2427     return returnValue;
2428 }
2429
2430 static ilmErrorTypes
2431 wayland_surfaceGetOrientation(t_ilm_surface surfaceId,
2432                               ilmOrientation *pOrientation)
2433 {
2434     ilmErrorTypes returnValue = ILM_FAILED;
2435     struct ilm_control_context *ctx = sync_and_acquire_instance();
2436
2437     if (pOrientation != NULL) {
2438         struct surface_context *ctx_surf = NULL;
2439         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2440         if (ctx_surf) {
2441             *pOrientation = ctx_surf->prop.orientation;
2442             returnValue = ILM_SUCCESS;
2443         }
2444     }
2445
2446     release_instance();
2447     return returnValue;
2448 }
2449
2450 static ilmErrorTypes
2451 wayland_surfaceGetPixelformat(t_ilm_layer surfaceId,
2452                               ilmPixelFormat *pPixelformat)
2453 {
2454     ilmErrorTypes returnValue = ILM_FAILED;
2455     struct ilm_control_context *ctx = sync_and_acquire_instance();
2456
2457     if (pPixelformat != NULL) {
2458         struct surface_context *ctx_surf = NULL;
2459         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2460         if (ctx_surf) {
2461             *pPixelformat = ctx_surf->prop.pixelformat;
2462             returnValue = ILM_SUCCESS;
2463         }
2464     }
2465
2466     release_instance();
2467     return returnValue;
2468 }
2469
2470 static ilmErrorTypes
2471 wayland_surfaceSetChromaKey(t_ilm_surface surfaceId, t_ilm_int* pColor)
2472 {
2473     (void)surfaceId;
2474     (void)pColor;
2475     /* Not supported */
2476     return ILM_FAILED;
2477 }
2478
2479 static ilmErrorTypes
2480 wayland_displaySetRenderOrder(t_ilm_display display,
2481                           t_ilm_layer *pLayerId, const t_ilm_uint number)
2482 {
2483     ilmErrorTypes returnValue = ILM_FAILED;
2484     struct ilm_control_context *ctx = sync_and_acquire_instance();
2485     struct screen_context *ctx_scrn = NULL;
2486
2487     ctx_scrn = get_screen_context_by_id(&ctx->wl, (uint32_t)display);
2488     if (ctx_scrn != NULL) {
2489         struct wl_array ids;
2490         wl_array_init(&ids);
2491         uint32_t *pids = wl_array_add(&ids, number * sizeof *pids);
2492         t_ilm_uint i;
2493         for (i = 0; i < number; i++) pids[i] = (uint32_t)pLayerId[i];
2494         ivi_controller_screen_set_render_order(ctx_scrn->controller, &ids);
2495         wl_array_release(&ids);
2496         returnValue = ILM_SUCCESS;
2497     }
2498
2499     release_instance();
2500     return returnValue;
2501 }
2502
2503 static ilmErrorTypes
2504 wayland_takeScreenshot(t_ilm_uint screen, t_ilm_const_string filename)
2505 {
2506     ilmErrorTypes returnValue = ILM_FAILED;
2507     struct ilm_control_context *ctx = sync_and_acquire_instance();
2508     struct screen_context *ctx_scrn = NULL;
2509
2510     ctx_scrn = get_screen_context_by_id(&ctx->wl, (uint32_t)screen);
2511     if (ctx_scrn != NULL) {
2512         ivi_controller_screen_screenshot(ctx_scrn->controller,
2513                                         filename);
2514         wl_display_flush(ctx->wl.display);
2515         returnValue = ILM_SUCCESS;
2516     }
2517
2518     release_instance();
2519     return returnValue;
2520 }
2521
2522 static ilmErrorTypes
2523 wayland_takeLayerScreenshot(t_ilm_const_string filename, t_ilm_layer layerid)
2524 {
2525     ilmErrorTypes returnValue = ILM_FAILED;
2526     struct ilm_control_context *ctx = sync_and_acquire_instance();
2527     struct layer_context *ctx_layer = NULL;
2528
2529     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2530                     &ctx->wl, (uint32_t)layerid);
2531     if (ctx_layer != NULL) {
2532         ivi_controller_layer_screenshot(ctx_layer->controller,
2533                                         filename);
2534         wl_display_flush(ctx->wl.display);
2535         returnValue = ILM_SUCCESS;
2536     }
2537
2538     release_instance();
2539     return returnValue;
2540 }
2541
2542 static ilmErrorTypes
2543 wayland_takeSurfaceScreenshot(t_ilm_const_string filename,
2544                               t_ilm_surface surfaceid)
2545 {
2546     ilmErrorTypes returnValue = ILM_FAILED;
2547     struct ilm_control_context *ctx = sync_and_acquire_instance();
2548     struct surface_context *ctx_surf = NULL;
2549
2550     ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceid);
2551     if (ctx_surf) {
2552         ivi_controller_surface_screenshot(ctx_surf->controller,
2553                                           filename);
2554         wl_display_flush(ctx->wl.display);
2555         returnValue = ILM_SUCCESS;
2556     }
2557
2558     release_instance();
2559     return returnValue;
2560 }
2561
2562 static ilmErrorTypes
2563 wayland_SetOptimizationMode(ilmOptimization id, ilmOptimizationMode mode)
2564 {
2565     (void)id;
2566     (void)mode;
2567     /* Not supported */
2568     return ILM_FAILED;
2569 }
2570
2571 static ilmErrorTypes
2572 wayland_GetOptimizationMode(ilmOptimization id, ilmOptimizationMode* pMode)
2573 {
2574     (void)id;
2575     (void)pMode;
2576     /* Not supported */
2577     return ILM_FAILED;
2578 }
2579
2580 // TODO
2581 static ilmErrorTypes
2582 wayland_layerAddNotification(t_ilm_layer layer,
2583                              layerNotificationFunc callback)
2584 {
2585     ilmErrorTypes returnValue = ILM_FAILED;
2586     struct ilm_control_context *ctx = sync_and_acquire_instance();
2587     struct layer_context *ctx_layer = NULL;
2588
2589     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2590                     &ctx->wl, (uint32_t)layer);
2591     if (ctx_layer == NULL) {
2592         returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2593     } else {
2594         ctx_layer->notification = callback;
2595
2596         returnValue = ILM_SUCCESS;
2597     }
2598
2599     release_instance();
2600     return returnValue;
2601 }
2602
2603 // TODO
2604 static ilmErrorTypes
2605 wayland_layerRemoveNotification(t_ilm_layer layer)
2606 {
2607    return wayland_layerAddNotification(layer, NULL);
2608 }
2609
2610 // TODO
2611 static ilmErrorTypes
2612 wayland_surfaceAddNotification(t_ilm_surface surface,
2613                              surfaceNotificationFunc callback)
2614 {
2615     ilmErrorTypes returnValue = ILM_FAILED;
2616     struct ilm_control_context *ctx = sync_and_acquire_instance();
2617     struct surface_context *ctx_surf = NULL;
2618
2619     ctx_surf = (struct surface_context*)get_surface_context(
2620                     &ctx->wl, (uint32_t)surface);
2621     if (ctx_surf == NULL) {
2622         returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2623     } else {
2624         ctx_surf->notification = callback;
2625
2626         returnValue = ILM_SUCCESS;
2627     }
2628
2629     release_instance();
2630     return returnValue;
2631 }
2632
2633 // TODO
2634 static ilmErrorTypes
2635 wayland_surfaceRemoveNotification(t_ilm_surface surface)
2636 {
2637     return wayland_surfaceAddNotification(surface, NULL);
2638 }
2639
2640 static ilmErrorTypes
2641 wayland_getNativeHandle(t_ilm_uint pid, t_ilm_int *n_handle,
2642                         t_ilm_nativehandle **p_handles)
2643 {
2644     struct ilm_control_context *ctx = sync_and_acquire_instance();
2645     struct nativehandle_context *p_nh_ctx = NULL;
2646
2647     *n_handle = 0;
2648     *p_handles = NULL;
2649
2650     wl_list_for_each(p_nh_ctx, &ctx->list_nativehandle, link)
2651     {
2652         if (p_nh_ctx->pid == pid)
2653         {
2654             *n_handle = 1;
2655             *p_handles =
2656                  (t_ilm_nativehandle*)malloc(sizeof(t_ilm_nativehandle));
2657             (*p_handles)[0] = p_nh_ctx->nativehandle;
2658             break;
2659         }
2660     }
2661
2662     release_instance();
2663     return (*n_handle > 0) ? ILM_SUCCESS : ILM_FAILED;
2664 }
2665
2666 static ilmErrorTypes
2667 wayland_getPropertiesOfSurface(t_ilm_uint surfaceID,
2668                         struct ilmSurfaceProperties* pSurfaceProperties)
2669 {
2670     ilmErrorTypes returnValue = ILM_FAILED;
2671     struct ilm_control_context *ctx = sync_and_acquire_instance();
2672
2673     if (pSurfaceProperties != NULL) {
2674         struct surface_context *ctx_surf = NULL;
2675
2676         ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceID);
2677         if (ctx_surf != NULL) {
2678
2679             *pSurfaceProperties = ctx_surf->prop;
2680             returnValue = ILM_SUCCESS;
2681         }
2682     }
2683
2684     release_instance();
2685     return returnValue;
2686 }
2687
2688 static ilmErrorTypes
2689 wayland_layerAddSurface(t_ilm_layer layerId,
2690                         t_ilm_surface surfaceId)
2691 {
2692     ilmErrorTypes returnValue = ILM_FAILED;
2693     struct ilm_control_context *ctx = sync_and_acquire_instance();
2694     struct layer_context *ctx_layer = NULL;
2695     struct surface_context *ctx_surf = NULL;
2696
2697     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2698                     &ctx->wl, (uint32_t)layerId);
2699     ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2700     if ((ctx_layer != NULL) && (ctx_surf != NULL)) {
2701         ivi_controller_layer_add_surface(ctx_layer->controller,
2702                                          ctx_surf->controller);
2703         returnValue = ILM_SUCCESS;
2704     }
2705
2706     release_instance();
2707     return returnValue;
2708 }
2709
2710 static ilmErrorTypes
2711 wayland_layerRemoveSurface(t_ilm_layer layerId,
2712                            t_ilm_surface surfaceId)
2713 {
2714     ilmErrorTypes returnValue = ILM_FAILED;
2715     struct ilm_control_context *ctx = sync_and_acquire_instance();
2716     struct layer_context *ctx_layer = NULL;
2717     struct surface_context *ctx_surf = NULL;
2718
2719     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2720                     &ctx->wl, (uint32_t)layerId);
2721     ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2722     if ((ctx_layer != NULL) && (ctx_surf != NULL)) {
2723         ivi_controller_layer_remove_surface(ctx_layer->controller,
2724                                             ctx_surf->controller);
2725         returnValue = ILM_SUCCESS;
2726     }
2727
2728     release_instance();
2729     return returnValue;
2730 }
2731
2732 static ilmErrorTypes
2733 wayland_surfaceGetDimension(t_ilm_surface surfaceId,
2734                             t_ilm_uint *pDimension)
2735 {
2736     ilmErrorTypes returnValue = ILM_FAILED;
2737     struct ilm_control_context *ctx = sync_and_acquire_instance();
2738
2739     if (pDimension != NULL) {
2740         struct surface_context *ctx_surf = NULL;
2741
2742         ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2743         if (ctx_surf != NULL) {
2744             *pDimension = (t_ilm_uint)ctx_surf->prop.destWidth;
2745             *(pDimension + 1) = (t_ilm_uint)ctx_surf->prop.destHeight;
2746             returnValue = ILM_SUCCESS;
2747         }
2748     }
2749
2750     release_instance();
2751     return returnValue;
2752 }
2753
2754 static ilmErrorTypes
2755 wayland_surfaceGetVisibility(t_ilm_surface surfaceId,
2756                              t_ilm_bool *pVisibility)
2757 {
2758     ilmErrorTypes returnValue = ILM_FAILED;
2759     struct ilm_control_context *ctx = sync_and_acquire_instance();
2760     struct surface_context *ctx_surf = NULL;
2761
2762     if (pVisibility != NULL) {
2763         ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2764         if (ctx_surf != NULL) {
2765             *pVisibility = (t_ilm_bool)ctx_surf->prop.visibility;
2766             returnValue = ILM_SUCCESS;
2767         }
2768     }
2769
2770     release_instance();
2771     return returnValue;
2772 }
2773
2774 static ilmErrorTypes
2775 wayland_surfaceSetSourceRectangle(t_ilm_surface surfaceId,
2776                                   t_ilm_int x, t_ilm_int y,
2777                                   t_ilm_int width, t_ilm_int height)
2778 {
2779     ilmErrorTypes returnValue = ILM_FAILED;
2780     struct ilm_control_context *ctx = sync_and_acquire_instance();
2781     struct surface_context *ctx_surf = NULL;
2782
2783     ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2784     if (ctx_surf != NULL) {
2785         if (ctx_surf->controller != NULL) {
2786             ivi_controller_surface_set_source_rectangle(
2787                     ctx_surf->controller,
2788                     x, y, width, height);
2789             returnValue = ILM_SUCCESS;
2790         }
2791     }
2792
2793     release_instance();
2794     return returnValue;
2795 }
2796
2797 static ilmErrorTypes
2798 wayland_commitChanges(void)
2799 {
2800     ilmErrorTypes returnValue = ILM_FAILED;
2801     struct ilm_control_context *ctx = sync_and_acquire_instance();
2802
2803     if (ctx->wl.controller != NULL) {
2804         ivi_controller_commit_changes(ctx->wl.controller);
2805
2806         if (display_roundtrip_queue(ctx->wl.display, ctx->wl.queue) != -1)
2807         {
2808             returnValue = ILM_SUCCESS;
2809         }
2810     }
2811
2812     release_instance();
2813
2814     return returnValue;
2815 }