ilmControl: destroy event queue if get_registry fails
[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         wl_event_queue_destroy(wl->queue);
1381         wl->queue = NULL;
1382         fprintf(stderr, "Failed to get registry\n");
1383         return -1;
1384     }
1385     wl_proxy_set_queue((void*)wl->registry, wl->queue);
1386
1387     if (wl_registry_add_listener(wl->registry,
1388                              &registry_control_listener, ctx)) {
1389         fprintf(stderr, "Failed to add registry listener\n");
1390         return -1;
1391     }
1392
1393     // first level objects; ivi_controller
1394     display_roundtrip_queue(wl->display, wl->queue);
1395     // second level object: ivi_controller_surfaces/layers
1396     display_roundtrip_queue(wl->display, wl->queue);
1397     // third level objects: ivi_controller_surfaces/layers properties
1398     display_roundtrip_queue(wl->display, wl->queue);
1399
1400     ret = pthread_create(&ctx->thread, NULL, control_thread, NULL);
1401
1402     if (ret != 0) {
1403         fprintf(stderr, "Failed to start internal receive thread. returned %d\n", ret);
1404         return -1;
1405     }
1406
1407     ctx->initialized = true;
1408
1409     return 0;
1410 }
1411
1412 static struct ilm_control_context*
1413 sync_and_acquire_instance(void)
1414 {
1415     struct ilm_control_context *ctx = &ilm_context;
1416     lock_context(ctx);
1417     display_roundtrip_queue(ctx->wl.display, ctx->wl.queue);
1418     return ctx;
1419 }
1420
1421 static void release_instance(void)
1422 {
1423     struct ilm_control_context *ctx = &ilm_context;
1424     unlock_context(ctx);
1425 }
1426
1427 static uint32_t
1428 gen_layer_id(struct ilm_control_context *ctx)
1429 {
1430     struct layer_context *ctx_layer = NULL;
1431     do {
1432         int found = 0;
1433         if (wl_list_length(&ctx->wl.list_layer) == 0) {
1434             ctx->internal_id_layer++;
1435             return ctx->internal_id_layer;
1436         }
1437         wl_list_for_each(ctx_layer, &ctx->wl.list_layer, link) {
1438             if (ctx_layer->id_layer == ctx->internal_id_layer) {
1439                 found = 1;
1440                 break;
1441             }
1442
1443             if (found == 0) {
1444                 return ctx->internal_id_layer;
1445             }
1446         }
1447         ctx->internal_id_layer++;
1448     } while(1);
1449 }
1450
1451 static struct surface_context*
1452 get_surface_context(struct wayland_context *ctx,
1453                           uint32_t id_surface)
1454 {
1455     struct surface_context *ctx_surf = NULL;
1456
1457     if (ctx->controller == NULL) {
1458         fprintf(stderr, "controller is not initialized in ilmControl\n");
1459         return NULL;
1460     }
1461
1462     wl_list_for_each(ctx_surf, &ctx->list_surface, link) {
1463         if (ctx_surf->id_surface == id_surface) {
1464             return ctx_surf;
1465         }
1466     }
1467
1468     fprintf(stderr, "failed to get surface context in ilmControl\n");
1469     return NULL;
1470 }
1471
1472 static struct screen_context*
1473 get_screen_context_by_id(struct wayland_context *ctx, uint32_t id_screen)
1474 {
1475     struct screen_context *ctx_scrn = NULL;
1476
1477     if (ctx->controller == NULL) {
1478         fprintf(stderr, "get_screen_context_by_id: controller is NULL\n");
1479         return NULL;
1480     }
1481
1482     wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
1483         if (ctx_scrn->id_screen == id_screen) {
1484             return ctx_scrn;
1485         }
1486     }
1487     return NULL;
1488 }
1489
1490 static ilmErrorTypes
1491 wayland_getPropertiesOfLayer(t_ilm_uint layerID,
1492                          struct ilmLayerProperties* pLayerProperties)
1493 {
1494     ilmErrorTypes returnValue = ILM_FAILED;
1495     struct ilm_control_context *ctx = sync_and_acquire_instance();
1496     struct layer_context *ctx_layer = NULL;
1497
1498     if (pLayerProperties != NULL) {
1499
1500         ctx_layer = (struct layer_context*)
1501                     wayland_controller_get_layer_context(
1502                         &ctx->wl, (uint32_t)layerID);
1503
1504         if (ctx_layer != NULL) {
1505             *pLayerProperties = ctx_layer->prop;
1506             returnValue = ILM_SUCCESS;
1507         }
1508     }
1509
1510     release_instance();
1511     return returnValue;
1512 }
1513
1514 static void
1515 create_layerids(struct screen_context *ctx_screen,
1516                 t_ilm_layer **layer_ids, t_ilm_uint *layer_count)
1517 {
1518     struct layer_context *ctx_layer = NULL;
1519     t_ilm_layer *ids = NULL;
1520
1521     *layer_count = wl_list_length(&ctx_screen->order.list_layer);
1522     if (*layer_count == 0) {
1523         *layer_ids = NULL;
1524         return;
1525     }
1526
1527     *layer_ids = malloc(*layer_count * sizeof(t_ilm_layer));
1528     if (*layer_ids == NULL) {
1529         fprintf(stderr, "memory insufficient for layerids\n");
1530         *layer_count = 0;
1531         return;
1532     }
1533
1534     ids = *layer_ids;
1535     wl_list_for_each_reverse(ctx_layer, &ctx_screen->order.list_layer, order.link) {
1536         *ids = (t_ilm_layer)ctx_layer->id_layer;
1537         ids++;
1538     }
1539 }
1540
1541 static ilmErrorTypes
1542 wayland_getPropertiesOfScreen(t_ilm_display screenID,
1543                               struct ilmScreenProperties* pScreenProperties)
1544 {
1545     ilmErrorTypes returnValue = ILM_FAILED;
1546
1547     if (! pScreenProperties)
1548     {
1549         return ILM_ERROR_INVALID_ARGUMENTS;
1550     }
1551
1552     struct ilm_control_context *ctx = sync_and_acquire_instance();
1553
1554     struct screen_context *ctx_screen = NULL;
1555     ctx_screen = get_screen_context_by_id(&ctx->wl, (uint32_t)screenID);
1556     if (ctx_screen != NULL) {
1557         *pScreenProperties = ctx_screen->prop;
1558         create_layerids(ctx_screen, &pScreenProperties->layerIds,
1559                                     &pScreenProperties->layerCount);
1560         returnValue = ILM_SUCCESS;
1561     }
1562
1563     release_instance();
1564     return returnValue;
1565 }
1566
1567 static ilmErrorTypes
1568 wayland_getNumberOfHardwareLayers(t_ilm_uint screenID,
1569                                   t_ilm_uint* pNumberOfHardwareLayers)
1570 {
1571     (void)screenID;
1572     /* Not supported */
1573     if (pNumberOfHardwareLayers != NULL) {
1574         *pNumberOfHardwareLayers = 0;
1575         return ILM_SUCCESS;
1576     } else {
1577         return ILM_FAILED;
1578     }
1579 }
1580
1581 static ilmErrorTypes
1582 wayland_getScreenIDs(t_ilm_uint* pNumberOfIDs, t_ilm_uint** ppIDs)
1583 {
1584     ilmErrorTypes returnValue = ILM_FAILED;
1585     struct ilm_control_context *ctx = sync_and_acquire_instance();
1586
1587     if ((pNumberOfIDs != NULL) && (ppIDs != NULL)) {
1588         struct screen_context *ctx_scrn = NULL;
1589         t_ilm_uint length = wl_list_length(&ctx->wl.list_screen);
1590         *pNumberOfIDs = 0;
1591
1592         *ppIDs = (t_ilm_uint*)malloc(length * sizeof *ppIDs);
1593         if (*ppIDs != NULL) {
1594             t_ilm_uint* ids = *ppIDs;
1595             wl_list_for_each(ctx_scrn, &ctx->wl.list_screen, link) {
1596                 *ids = ctx_scrn->id_screen;
1597                 ids++;
1598             }
1599             *pNumberOfIDs = length;
1600
1601             returnValue = ILM_SUCCESS;
1602         }
1603     }
1604
1605     release_instance();
1606     return returnValue;
1607 }
1608
1609 static ilmErrorTypes
1610 wayland_getLayerIDs(t_ilm_int* pLength, t_ilm_layer** ppArray)
1611 {
1612     ilmErrorTypes returnValue = ILM_FAILED;
1613     struct ilm_control_context *ctx = sync_and_acquire_instance();
1614
1615     if ((pLength != NULL) && (ppArray != NULL)) {
1616         struct layer_context *ctx_layer = NULL;
1617         t_ilm_uint length = wl_list_length(&ctx->wl.list_layer);
1618         *pLength = 0;
1619
1620         *ppArray = (t_ilm_layer*)malloc(length * sizeof *ppArray);
1621         if (*ppArray != NULL) {
1622             // compositor sends layers in opposite order
1623             // write ids from back to front to turn them around
1624             t_ilm_layer* ids = *ppArray;
1625             wl_list_for_each_reverse(ctx_layer, &ctx->wl.list_layer, link)
1626             {
1627                 *ids = ctx_layer->id_layer;
1628                 ++ids;
1629             }
1630             *pLength = length;
1631
1632             returnValue = ILM_SUCCESS;
1633         }
1634     }
1635
1636     release_instance();
1637     return returnValue;
1638 }
1639
1640 static ilmErrorTypes
1641 wayland_getLayerIDsOnScreen(t_ilm_uint screenId,
1642                             t_ilm_int* pLength,
1643                             t_ilm_layer** ppArray)
1644 {
1645     ilmErrorTypes returnValue = ILM_FAILED;
1646     struct ilm_control_context *ctx = sync_and_acquire_instance();
1647
1648     if ((pLength != NULL) && (ppArray != NULL)) {
1649         struct screen_context *ctx_screen = NULL;
1650         ctx_screen = get_screen_context_by_id(&ctx->wl, screenId);
1651         if (ctx_screen != NULL) {
1652             struct layer_context *ctx_layer = NULL;
1653             t_ilm_int length = wl_list_length(&ctx_screen->order.list_layer);
1654
1655             if (0 < length)
1656             {
1657                 *ppArray = (t_ilm_layer*)malloc(length * sizeof *ppArray);
1658                 if (*ppArray != NULL) {
1659                     // compositor sends layers in opposite order
1660                     // write ids from back to front to turn them around
1661                     t_ilm_layer* ids = *ppArray;
1662                     wl_list_for_each_reverse(ctx_layer, &ctx_screen->order.list_layer, order.link)
1663                     {
1664                         *ids = ctx_layer->id_layer;
1665                         ++ids;
1666                     }
1667
1668                 }
1669             }
1670             else
1671             {
1672                 *ppArray = NULL;
1673             }
1674
1675             *pLength = length;
1676             returnValue = ILM_SUCCESS;
1677         }
1678     }
1679
1680     release_instance();
1681     return returnValue;
1682 }
1683
1684 static ilmErrorTypes
1685 wayland_getSurfaceIDs(t_ilm_int* pLength, t_ilm_surface** ppArray)
1686 {
1687     ilmErrorTypes returnValue = ILM_FAILED;
1688     struct ilm_control_context *ctx = sync_and_acquire_instance();
1689
1690     if ((pLength != NULL) && (ppArray != NULL)) {
1691         struct surface_context *ctx_surf = NULL;
1692         t_ilm_uint length = wl_list_length(&ctx->wl.list_surface);
1693         *pLength = 0;
1694
1695         *ppArray = (t_ilm_surface*)malloc(length * sizeof *ppArray);
1696         if (*ppArray != NULL) {
1697             t_ilm_surface* ids = *ppArray;
1698             wl_list_for_each_reverse(ctx_surf, &ctx->wl.list_surface, link) {
1699                 *ids = ctx_surf->id_surface;
1700                 ids++;
1701             }
1702             *pLength = length;
1703
1704             returnValue = ILM_SUCCESS;
1705         }
1706     }
1707
1708     release_instance();
1709     return returnValue;
1710 }
1711
1712 static ilmErrorTypes
1713 wayland_getSurfaceIDsOnLayer(t_ilm_layer layer,
1714                              t_ilm_int* pLength,
1715                              t_ilm_surface** ppArray)
1716 {
1717     struct ilm_control_context *ctx = sync_and_acquire_instance();
1718     struct layer_context *ctx_layer = NULL;
1719     struct surface_context *ctx_surf = NULL;
1720     t_ilm_uint length = 0;
1721     t_ilm_surface* ids = NULL;
1722
1723     if ((pLength == NULL) || (ppArray == NULL)) {
1724         release_instance();
1725         return ILM_FAILED;
1726     }
1727
1728     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1729                     &ctx->wl, (uint32_t)layer);
1730
1731     if (ctx_layer == NULL) {
1732         release_instance();
1733         return ILM_FAILED;
1734     }
1735
1736     length = wl_list_length(&ctx_layer->order.list_surface);
1737     *ppArray = (t_ilm_surface*)malloc(length * sizeof *ppArray);
1738     if (*ppArray == NULL) {
1739         release_instance();
1740         return ILM_FAILED;
1741     }
1742
1743     ids = *ppArray;
1744     wl_list_for_each_reverse(ctx_surf, &ctx_layer->order.list_surface, order.link) {
1745         *ids = (t_ilm_surface)ctx_surf->id_surface;
1746         ids++;
1747     }
1748     *pLength = length;
1749
1750     release_instance();
1751     return ILM_SUCCESS;
1752 }
1753
1754 static int create_controller_layer(struct wayland_context *ctx, t_ilm_uint width, t_ilm_uint height, t_ilm_layer layerid)
1755 {
1756      struct layer_context *ctx_layer = calloc(1, sizeof *ctx_layer);
1757      if (ctx_layer == NULL) {
1758          fprintf(stderr, "Failed to allocate memory for layer_context\n");
1759          return -1;
1760      }
1761
1762      ctx_layer->controller = ivi_controller_layer_create(
1763                                  ctx->controller,
1764                                  layerid, width, height);
1765      if (ctx_layer->controller == NULL) {
1766          fprintf(stderr, "Failed to create layer\n");
1767          free(ctx_layer);
1768          return -1;
1769      }
1770      ctx_layer->id_layer = layerid;
1771      ctx_layer->ctx = ctx;
1772
1773      wl_list_init(&ctx_layer->link);
1774      wl_list_insert(&ctx->list_layer, &ctx_layer->link);
1775      wl_list_init(&ctx_layer->order.link);
1776      wl_list_init(&ctx_layer->order.list_surface);
1777
1778      ivi_controller_layer_add_listener(ctx_layer->controller,
1779                                    &controller_layer_listener, ctx_layer);
1780
1781      return 0;
1782 }
1783
1784 static ilmErrorTypes
1785 wayland_layerCreateWithDimension(t_ilm_layer* pLayerId,
1786                                  t_ilm_uint width,
1787                                  t_ilm_uint height)
1788 {
1789     ilmErrorTypes returnValue = ILM_FAILED;
1790     struct ilm_control_context *ctx = sync_and_acquire_instance();
1791     uint32_t layerid = 0;
1792     int32_t is_inside = 0;
1793
1794     do {
1795         if (pLayerId == NULL) {
1796             break;
1797         }
1798
1799         if (*pLayerId != INVALID_ID) {
1800             /* Return failed, if layerid is already inside list_layer */
1801             is_inside = wayland_controller_is_inside_layer_list(
1802                             &ctx->wl.list_layer, *pLayerId);
1803             if (0 != is_inside) {
1804                 fprintf(stderr, "layerid=%d is already used.\n", *pLayerId);
1805                 break;
1806             }
1807             layerid = *pLayerId;
1808         }
1809         else {
1810             /* Generate ID, if layerid is INVALID_ID */
1811             layerid = gen_layer_id(ctx);
1812             *pLayerId = layerid;
1813         }
1814
1815         if (create_controller_layer(&ctx->wl, width, height, layerid) == 0)
1816         {
1817            returnValue = ILM_SUCCESS;
1818         }
1819     } while(0);
1820
1821     release_instance();
1822     return returnValue;
1823 }
1824
1825 static ilmErrorTypes
1826 wayland_layerRemove(t_ilm_layer layerId)
1827 {
1828     ilmErrorTypes returnValue = ILM_FAILED;
1829     struct ilm_control_context *ctx = sync_and_acquire_instance();
1830     struct layer_context *ctx_layer = NULL;
1831     struct layer_context *ctx_next = NULL;
1832
1833     wl_list_for_each_safe(ctx_layer, ctx_next,
1834             &ctx->wl.list_layer, link) {
1835         if (ctx_layer->id_layer == layerId) {
1836             ivi_controller_layer_destroy(ctx_layer->controller, 1);
1837
1838             wl_list_remove(&ctx_layer->link);
1839             free(ctx_layer);
1840
1841             returnValue = ILM_SUCCESS;
1842             break;
1843         }
1844     }
1845
1846     release_instance();
1847     return returnValue;
1848 }
1849
1850 static ilmErrorTypes
1851 wayland_layerGetType(t_ilm_layer layerId, ilmLayerType* pLayerType)
1852 {
1853     if (!pLayerType)
1854     {
1855        return ILM_ERROR_INVALID_ARGUMENTS;
1856     }
1857
1858     struct ilm_control_context *ctx = sync_and_acquire_instance();
1859
1860     *pLayerType = wayland_controller_is_inside_layer_list(&ctx->wl.list_layer, layerId) ?
1861        ILM_LAYERTYPE_SOFTWARE2D :
1862        ILM_LAYERTYPE_UNKNOWN;
1863
1864     release_instance();
1865     return ILM_SUCCESS; // even if non existent?
1866 }
1867
1868 static ilmErrorTypes
1869 wayland_layerSetVisibility(t_ilm_layer layerId, t_ilm_bool newVisibility)
1870 {
1871     ilmErrorTypes returnValue = ILM_FAILED;
1872     struct ilm_control_context *ctx = sync_and_acquire_instance();
1873     struct layer_context *ctx_layer = NULL;
1874
1875     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1876                     &ctx->wl, (uint32_t)layerId);
1877
1878     if (ctx_layer != NULL) {
1879         uint32_t visibility = 0;
1880         if (newVisibility == ILM_TRUE) {
1881             visibility = 1;
1882         }
1883         ivi_controller_layer_set_visibility(ctx_layer->controller,
1884                                             visibility);
1885         returnValue = ILM_SUCCESS;
1886     }
1887
1888     release_instance();
1889     return returnValue;
1890 }
1891
1892 static ilmErrorTypes
1893 wayland_layerGetVisibility(t_ilm_layer layerId, t_ilm_bool *pVisibility)
1894 {
1895     ilmErrorTypes returnValue = ILM_FAILED;
1896     struct ilm_control_context *ctx = sync_and_acquire_instance();
1897
1898     if (pVisibility != NULL) {
1899         struct layer_context *ctx_layer = NULL;
1900
1901         ctx_layer = (struct layer_context*)
1902                     wayland_controller_get_layer_context(
1903                         &ctx->wl, (uint32_t)layerId);
1904
1905         if (ctx_layer != NULL) {
1906             *pVisibility = ctx_layer->prop.visibility;
1907             returnValue = ILM_SUCCESS;
1908         }
1909     }
1910
1911     release_instance();
1912     return returnValue;
1913 }
1914
1915 static ilmErrorTypes
1916 wayland_layerSetOpacity(t_ilm_layer layerId, t_ilm_float opacity)
1917 {
1918     ilmErrorTypes returnValue = ILM_FAILED;
1919     struct ilm_control_context *ctx = sync_and_acquire_instance();
1920     struct layer_context *ctx_layer = NULL;
1921
1922     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1923                     &ctx->wl, (uint32_t)layerId);
1924
1925     if (ctx_layer != NULL) {
1926         wl_fixed_t opacity_fixed = wl_fixed_from_double((double)opacity);
1927         ivi_controller_layer_set_opacity(ctx_layer->controller,
1928                                          opacity_fixed);
1929         returnValue = ILM_SUCCESS;
1930     }
1931
1932     release_instance();
1933     return returnValue;
1934 }
1935
1936 static ilmErrorTypes
1937 wayland_layerGetOpacity(t_ilm_layer layerId, t_ilm_float *pOpacity)
1938 {
1939     ilmErrorTypes returnValue = ILM_FAILED;
1940     struct ilm_control_context *ctx = sync_and_acquire_instance();
1941
1942     if (pOpacity != NULL) {
1943         struct layer_context *ctx_layer = NULL;
1944
1945         ctx_layer = (struct layer_context*)
1946                     wayland_controller_get_layer_context(
1947                         &ctx->wl, (uint32_t)layerId);
1948
1949         if (ctx_layer != NULL) {
1950             *pOpacity = ctx_layer->prop.opacity;
1951             returnValue = ILM_SUCCESS;
1952         }
1953     }
1954
1955     release_instance();
1956     return returnValue;
1957 }
1958
1959 static ilmErrorTypes
1960 wayland_layerSetSourceRectangle(t_ilm_layer layerId,
1961                                 t_ilm_uint x, t_ilm_uint y,
1962                                 t_ilm_uint width, t_ilm_uint height)
1963 {
1964     ilmErrorTypes returnValue = ILM_FAILED;
1965     struct ilm_control_context *ctx = sync_and_acquire_instance();
1966     struct layer_context *ctx_layer = NULL;
1967
1968     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1969                     &ctx->wl, (uint32_t)layerId);
1970
1971     if (ctx_layer != NULL) {
1972         ivi_controller_layer_set_source_rectangle(ctx_layer->controller,
1973                                                   (uint32_t)x,
1974                                                   (uint32_t)y,
1975                                                   (uint32_t)width,
1976                                                   (uint32_t)height);
1977         returnValue = ILM_SUCCESS;
1978     }
1979
1980     release_instance();
1981     return returnValue;
1982 }
1983
1984 static ilmErrorTypes
1985 wayland_layerSetDestinationRectangle(t_ilm_layer layerId,
1986                                  t_ilm_int x, t_ilm_int y,
1987                                  t_ilm_int width, t_ilm_int height)
1988 {
1989     ilmErrorTypes returnValue = ILM_FAILED;
1990     struct ilm_control_context *ctx = sync_and_acquire_instance();
1991     struct layer_context *ctx_layer = NULL;
1992
1993     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1994                     &ctx->wl, (uint32_t)layerId);
1995     if (ctx_layer != NULL) {
1996         ivi_controller_layer_set_destination_rectangle(
1997                                          ctx_layer->controller,
1998                                          (uint32_t)x, (uint32_t)y,
1999                                          (uint32_t)width,
2000                                          (uint32_t)height);
2001         returnValue = ILM_SUCCESS;
2002     }
2003
2004     release_instance();
2005     return returnValue;
2006 }
2007
2008 static ilmErrorTypes
2009 wayland_layerGetDimension(t_ilm_layer layerId, t_ilm_uint *pDimension)
2010 {
2011     ilmErrorTypes returnValue = ILM_FAILED;
2012     struct ilm_control_context *ctx = sync_and_acquire_instance();
2013     struct layer_context *ctx_layer = NULL;
2014
2015     if (pDimension != NULL) {
2016         ctx_layer = (struct layer_context*)
2017                     wayland_controller_get_layer_context(
2018                         &ctx->wl, (uint32_t)layerId);
2019         if (ctx_layer != NULL) {
2020             *pDimension = ctx_layer->prop.destWidth;
2021             *(pDimension + 1) = ctx_layer->prop.destHeight;
2022             returnValue = ILM_SUCCESS;
2023         }
2024     }
2025
2026     release_instance();
2027     return returnValue;
2028 }
2029
2030 static ilmErrorTypes
2031 wayland_layerSetDimension(t_ilm_layer layerId, t_ilm_uint *pDimension)
2032 {
2033     ilmErrorTypes returnValue = ILM_FAILED;
2034     struct ilm_control_context *ctx = sync_and_acquire_instance();
2035     struct layer_context *ctx_layer = NULL;
2036
2037     if (pDimension != NULL) {
2038         ctx_layer = (struct layer_context*)
2039                     wayland_controller_get_layer_context(
2040                         &ctx->wl, (uint32_t)layerId);
2041         if (ctx_layer != NULL) {
2042             ivi_controller_layer_set_destination_rectangle(
2043                 ctx_layer->controller,
2044                 ctx_layer->prop.destX, ctx_layer->prop.destY,
2045                 (int32_t)*pDimension, (int32_t)*(pDimension + 1));
2046             returnValue = ILM_SUCCESS;
2047         }
2048     }
2049
2050     release_instance();
2051     return returnValue;
2052 }
2053
2054 static ilmErrorTypes
2055 wayland_layerGetPosition(t_ilm_layer layerId, t_ilm_uint *pPosition)
2056 {
2057     ilmErrorTypes returnValue = ILM_FAILED;
2058     struct ilm_control_context *ctx = sync_and_acquire_instance();
2059     struct layer_context *ctx_layer = NULL;
2060
2061     if (pPosition != NULL) {
2062         ctx_layer = (struct layer_context*)
2063                     wayland_controller_get_layer_context(
2064                         &ctx->wl, (uint32_t)layerId);
2065         if (ctx_layer != NULL) {
2066             *pPosition = ctx_layer->prop.destX;
2067             *(pPosition + 1) = ctx_layer->prop.destY;
2068             returnValue = ILM_SUCCESS;
2069         }
2070     }
2071
2072     release_instance();
2073     return returnValue;
2074 }
2075
2076 static ilmErrorTypes
2077 wayland_layerSetPosition(t_ilm_layer layerId, t_ilm_uint *pPosition)
2078 {
2079     ilmErrorTypes returnValue = ILM_FAILED;
2080     struct ilm_control_context *ctx = sync_and_acquire_instance();
2081     struct layer_context *ctx_layer = NULL;
2082
2083     if (pPosition != NULL) {
2084         ctx_layer = (struct layer_context*)
2085                     wayland_controller_get_layer_context(
2086                         &ctx->wl, (uint32_t)layerId);
2087         if (ctx_layer != NULL) {
2088             ivi_controller_layer_set_destination_rectangle(
2089                 ctx_layer->controller,
2090                 (int32_t)*pPosition, (int32_t)*(pPosition + 1),
2091                 ctx_layer->prop.destWidth, ctx_layer->prop.destHeight);
2092             returnValue = ILM_SUCCESS;
2093         }
2094     }
2095
2096     release_instance();
2097     return returnValue;
2098 }
2099
2100 static ilmErrorTypes
2101 wayland_layerSetOrientation(t_ilm_layer layerId, ilmOrientation orientation)
2102 {
2103     ilmErrorTypes returnValue = ILM_FAILED;
2104     struct ilm_control_context *ctx = sync_and_acquire_instance();
2105     struct layer_context *ctx_layer = NULL;
2106     int32_t iviorientation = 0;
2107
2108     do {
2109         switch(orientation) {
2110         case ILM_ZERO:
2111             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES;
2112             break;
2113         case ILM_NINETY:
2114             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES;
2115             break;
2116         case ILM_ONEHUNDREDEIGHTY:
2117             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES;
2118             break;
2119         case ILM_TWOHUNDREDSEVENTY:
2120             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES;
2121             break;
2122         default:
2123             returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2124             break;
2125         }
2126
2127         ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2128                         &ctx->wl, (uint32_t)layerId);
2129         if (ctx_layer == NULL) {
2130             returnValue = ILM_FAILED;
2131             break;
2132         }
2133
2134         ivi_controller_layer_set_orientation(ctx_layer->controller,
2135                                              iviorientation);
2136
2137         returnValue = ILM_SUCCESS;
2138     } while(0);
2139
2140     release_instance();
2141     return returnValue;
2142 }
2143
2144 static ilmErrorTypes
2145 wayland_layerGetOrientation(t_ilm_layer layerId, ilmOrientation *pOrientation)
2146 {
2147     ilmErrorTypes returnValue = ILM_FAILED;
2148     struct ilm_control_context *ctx = sync_and_acquire_instance();
2149     struct layer_context *ctx_layer = NULL;
2150
2151     if (pOrientation != NULL) {
2152         ctx_layer = (struct layer_context*)
2153                     wayland_controller_get_layer_context(
2154                         &ctx->wl, (uint32_t)layerId);
2155         if (ctx_layer != NULL) {
2156             *pOrientation = ctx_layer->prop.orientation;
2157             returnValue = ILM_SUCCESS;
2158         }
2159     }
2160
2161     release_instance();
2162     return returnValue;
2163 }
2164
2165 static ilmErrorTypes
2166 wayland_layerSetChromaKey(t_ilm_layer layerId, t_ilm_int* pColor)
2167 {
2168     (void)layerId;
2169     (void)pColor;
2170     /* Not supported */
2171     return ILM_FAILED;
2172 }
2173
2174 static ilmErrorTypes
2175 wayland_layerSetRenderOrder(t_ilm_layer layerId,
2176                         t_ilm_surface *pSurfaceId,
2177                         t_ilm_int number)
2178 {
2179     ilmErrorTypes returnValue = ILM_FAILED;
2180     struct ilm_control_context *ctx = sync_and_acquire_instance();
2181     struct layer_context *ctx_layer = NULL;
2182
2183     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2184                     &ctx->wl, (uint32_t)layerId);
2185
2186     if (ctx_layer)
2187     {
2188         struct wl_array ids;
2189         wl_array_init(&ids);
2190         uint32_t *pids = wl_array_add(&ids, number * sizeof *pids);
2191         t_ilm_uint i;
2192         for (i = 0; i < number; i++) pids[i] = (uint32_t)pSurfaceId[i];
2193         ivi_controller_layer_set_render_order(ctx_layer->controller, &ids);
2194         wl_array_release(&ids);
2195         returnValue = ILM_SUCCESS;
2196     }
2197
2198     release_instance();
2199     return returnValue;
2200 }
2201
2202 static ilmErrorTypes
2203 wayland_layerGetCapabilities(t_ilm_layer layerId,
2204                          t_ilm_layercapabilities *pCapabilities)
2205 {
2206     (void)layerId;
2207     (void)pCapabilities;
2208     /* Not supported */
2209     return ILM_FAILED;
2210 }
2211
2212 static ilmErrorTypes
2213 wayland_layerTypeGetCapabilities(ilmLayerType layerType,
2214                              t_ilm_layercapabilities *pCapabilities)
2215 {
2216     (void)layerType;
2217     (void)pCapabilities;
2218     /* Not supported */
2219     return ILM_FAILED;
2220 }
2221
2222 static ilmErrorTypes
2223 wayland_surfaceSetVisibility(t_ilm_surface surfaceId, t_ilm_bool newVisibility)
2224 {
2225     ilmErrorTypes returnValue = ILM_FAILED;
2226     struct ilm_control_context *ctx = sync_and_acquire_instance();
2227     struct surface_context *ctx_surf = NULL;
2228     uint32_t visibility = 0;
2229
2230     if (newVisibility == ILM_TRUE) {
2231         visibility = 1;
2232     }
2233     ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2234     if (ctx_surf) {
2235         ivi_controller_surface_set_visibility(ctx_surf->controller,
2236                                               visibility);
2237         returnValue = ILM_SUCCESS;
2238     }
2239
2240     release_instance();
2241     return returnValue;
2242 }
2243
2244 static ilmErrorTypes
2245 wayland_surfaceSetOpacity(t_ilm_surface surfaceId, t_ilm_float opacity)
2246 {
2247     ilmErrorTypes returnValue = ILM_FAILED;
2248     struct ilm_control_context *ctx = sync_and_acquire_instance();
2249     struct surface_context *ctx_surf = NULL;
2250     wl_fixed_t opacity_fixed = 0;
2251
2252     opacity_fixed = wl_fixed_from_double((double)opacity);
2253     ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2254     if (ctx_surf) {
2255         ivi_controller_surface_set_opacity(ctx_surf->controller,
2256                                            opacity_fixed);
2257         returnValue = ILM_SUCCESS;
2258     }
2259
2260     release_instance();
2261     return returnValue;
2262 }
2263
2264 static ilmErrorTypes
2265 wayland_surfaceGetOpacity(t_ilm_surface surfaceId, t_ilm_float *pOpacity)
2266 {
2267     ilmErrorTypes returnValue = ILM_FAILED;
2268     struct ilm_control_context *ctx = sync_and_acquire_instance();
2269
2270     if (pOpacity != NULL) {
2271         struct surface_context *ctx_surf = NULL;
2272         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2273         if (ctx_surf) {
2274             *pOpacity = ctx_surf->prop.opacity;
2275             returnValue = ILM_SUCCESS;
2276         }
2277     }
2278
2279     release_instance();
2280     return returnValue;
2281 }
2282
2283 static ilmErrorTypes
2284 wayland_SetKeyboardFocusOn(t_ilm_surface surfaceId)
2285 {
2286     ilmErrorTypes returnValue = ILM_FAILED;
2287     (void)surfaceId;
2288     returnValue = ILM_SUCCESS;
2289     return returnValue;
2290 }
2291
2292 static ilmErrorTypes
2293 wayland_GetKeyboardFocusSurfaceId(t_ilm_surface* pSurfaceId)
2294 {
2295     ilmErrorTypes returnValue = ILM_FAILED;
2296     (void)pSurfaceId;
2297     returnValue = ILM_SUCCESS;
2298     return returnValue;
2299 }
2300
2301 static ilmErrorTypes
2302 wayland_surfaceSetDestinationRectangle(t_ilm_surface surfaceId,
2303                                    t_ilm_int x, t_ilm_int y,
2304                                    t_ilm_int width, t_ilm_int height)
2305 {
2306     ilmErrorTypes returnValue = ILM_FAILED;
2307     struct ilm_control_context *ctx = sync_and_acquire_instance();
2308     struct surface_context *ctx_surf = NULL;
2309
2310     ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2311     if (ctx_surf) {
2312         ivi_controller_surface_set_destination_rectangle(
2313                                              ctx_surf->controller,
2314                                              x, y, width, height);
2315         returnValue = ILM_SUCCESS;
2316     }
2317
2318     release_instance();
2319     return returnValue;
2320 }
2321
2322 static ilmErrorTypes
2323 wayland_surfaceSetDimension(t_ilm_surface surfaceId, t_ilm_uint *pDimension)
2324 {
2325     ilmErrorTypes returnValue = ILM_FAILED;
2326     struct ilm_control_context *ctx = sync_and_acquire_instance();
2327
2328     if (pDimension != NULL) {
2329         struct surface_context *ctx_surf = NULL;
2330         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2331         if (ctx_surf) {
2332             uint32_t width = *pDimension;
2333             uint32_t height = *(pDimension + 1);
2334             ivi_controller_surface_set_destination_rectangle(
2335                 ctx_surf->controller,
2336                 ctx_surf->prop.destX, ctx_surf->prop.destY, width, height);
2337             returnValue = ILM_SUCCESS;
2338         }
2339     }
2340
2341     release_instance();
2342     return returnValue;
2343 }
2344
2345 static ilmErrorTypes
2346 wayland_surfaceGetPosition(t_ilm_surface surfaceId, t_ilm_uint *pPosition)
2347 {
2348     ilmErrorTypes returnValue = ILM_FAILED;
2349     struct ilm_control_context *ctx = sync_and_acquire_instance();
2350
2351     if (pPosition != NULL) {
2352         struct surface_context *ctx_surf = NULL;
2353         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2354         if (ctx_surf) {
2355             *pPosition = ctx_surf->prop.destX;
2356             *(pPosition + 1) = ctx_surf->prop.destY;
2357             returnValue = ILM_SUCCESS;
2358         }
2359     }
2360
2361     release_instance();
2362     return returnValue;
2363 }
2364
2365 static ilmErrorTypes
2366 wayland_surfaceSetPosition(t_ilm_surface surfaceId, t_ilm_uint *pPosition)
2367 {
2368     ilmErrorTypes returnValue = ILM_FAILED;
2369     struct ilm_control_context *ctx = sync_and_acquire_instance();
2370
2371     if (pPosition != NULL) {
2372         struct surface_context *ctx_surf = NULL;
2373         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2374         if (ctx_surf) {
2375             int32_t destX = (int32_t)*pPosition;
2376             int32_t destY = (int32_t)*(pPosition + 1);
2377             ivi_controller_surface_set_destination_rectangle(
2378                 ctx_surf->controller, destX, destY,
2379                 ctx_surf->prop.destWidth, ctx_surf->prop.destHeight);
2380             returnValue = ILM_SUCCESS;
2381         }
2382     }
2383
2384     release_instance();
2385     return returnValue;
2386 }
2387
2388 static ilmErrorTypes
2389 wayland_surfaceSetOrientation(t_ilm_surface surfaceId,
2390                               ilmOrientation orientation)
2391 {
2392     ilmErrorTypes returnValue = ILM_FAILED;
2393     struct ilm_control_context *ctx = sync_and_acquire_instance();
2394     struct surface_context *ctx_surf = NULL;
2395     int32_t iviorientation = 0;
2396
2397     do {
2398         switch(orientation) {
2399         case ILM_ZERO:
2400             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES;
2401             break;
2402         case ILM_NINETY:
2403             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES;
2404             break;
2405         case ILM_ONEHUNDREDEIGHTY:
2406             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES;
2407             break;
2408         case ILM_TWOHUNDREDSEVENTY:
2409             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES;
2410             break;
2411         default:
2412             returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2413             break;
2414         }
2415
2416         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2417         if (ctx_surf == NULL) {
2418             returnValue = ILM_FAILED;
2419             break;
2420         }
2421
2422         ivi_controller_surface_set_orientation(ctx_surf->controller,
2423                                                iviorientation);
2424
2425         returnValue = ILM_SUCCESS;
2426     } while(0);
2427
2428     release_instance();
2429     return returnValue;
2430 }
2431
2432 static ilmErrorTypes
2433 wayland_surfaceGetOrientation(t_ilm_surface surfaceId,
2434                               ilmOrientation *pOrientation)
2435 {
2436     ilmErrorTypes returnValue = ILM_FAILED;
2437     struct ilm_control_context *ctx = sync_and_acquire_instance();
2438
2439     if (pOrientation != NULL) {
2440         struct surface_context *ctx_surf = NULL;
2441         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2442         if (ctx_surf) {
2443             *pOrientation = ctx_surf->prop.orientation;
2444             returnValue = ILM_SUCCESS;
2445         }
2446     }
2447
2448     release_instance();
2449     return returnValue;
2450 }
2451
2452 static ilmErrorTypes
2453 wayland_surfaceGetPixelformat(t_ilm_layer surfaceId,
2454                               ilmPixelFormat *pPixelformat)
2455 {
2456     ilmErrorTypes returnValue = ILM_FAILED;
2457     struct ilm_control_context *ctx = sync_and_acquire_instance();
2458
2459     if (pPixelformat != NULL) {
2460         struct surface_context *ctx_surf = NULL;
2461         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2462         if (ctx_surf) {
2463             *pPixelformat = ctx_surf->prop.pixelformat;
2464             returnValue = ILM_SUCCESS;
2465         }
2466     }
2467
2468     release_instance();
2469     return returnValue;
2470 }
2471
2472 static ilmErrorTypes
2473 wayland_surfaceSetChromaKey(t_ilm_surface surfaceId, t_ilm_int* pColor)
2474 {
2475     (void)surfaceId;
2476     (void)pColor;
2477     /* Not supported */
2478     return ILM_FAILED;
2479 }
2480
2481 static ilmErrorTypes
2482 wayland_displaySetRenderOrder(t_ilm_display display,
2483                           t_ilm_layer *pLayerId, const t_ilm_uint number)
2484 {
2485     ilmErrorTypes returnValue = ILM_FAILED;
2486     struct ilm_control_context *ctx = sync_and_acquire_instance();
2487     struct screen_context *ctx_scrn = NULL;
2488
2489     ctx_scrn = get_screen_context_by_id(&ctx->wl, (uint32_t)display);
2490     if (ctx_scrn != NULL) {
2491         struct wl_array ids;
2492         wl_array_init(&ids);
2493         uint32_t *pids = wl_array_add(&ids, number * sizeof *pids);
2494         t_ilm_uint i;
2495         for (i = 0; i < number; i++) pids[i] = (uint32_t)pLayerId[i];
2496         ivi_controller_screen_set_render_order(ctx_scrn->controller, &ids);
2497         wl_array_release(&ids);
2498         returnValue = ILM_SUCCESS;
2499     }
2500
2501     release_instance();
2502     return returnValue;
2503 }
2504
2505 static ilmErrorTypes
2506 wayland_takeScreenshot(t_ilm_uint screen, t_ilm_const_string filename)
2507 {
2508     ilmErrorTypes returnValue = ILM_FAILED;
2509     struct ilm_control_context *ctx = sync_and_acquire_instance();
2510     struct screen_context *ctx_scrn = NULL;
2511
2512     ctx_scrn = get_screen_context_by_id(&ctx->wl, (uint32_t)screen);
2513     if (ctx_scrn != NULL) {
2514         ivi_controller_screen_screenshot(ctx_scrn->controller,
2515                                         filename);
2516         wl_display_flush(ctx->wl.display);
2517         returnValue = ILM_SUCCESS;
2518     }
2519
2520     release_instance();
2521     return returnValue;
2522 }
2523
2524 static ilmErrorTypes
2525 wayland_takeLayerScreenshot(t_ilm_const_string filename, t_ilm_layer layerid)
2526 {
2527     ilmErrorTypes returnValue = ILM_FAILED;
2528     struct ilm_control_context *ctx = sync_and_acquire_instance();
2529     struct layer_context *ctx_layer = NULL;
2530
2531     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2532                     &ctx->wl, (uint32_t)layerid);
2533     if (ctx_layer != NULL) {
2534         ivi_controller_layer_screenshot(ctx_layer->controller,
2535                                         filename);
2536         wl_display_flush(ctx->wl.display);
2537         returnValue = ILM_SUCCESS;
2538     }
2539
2540     release_instance();
2541     return returnValue;
2542 }
2543
2544 static ilmErrorTypes
2545 wayland_takeSurfaceScreenshot(t_ilm_const_string filename,
2546                               t_ilm_surface surfaceid)
2547 {
2548     ilmErrorTypes returnValue = ILM_FAILED;
2549     struct ilm_control_context *ctx = sync_and_acquire_instance();
2550     struct surface_context *ctx_surf = NULL;
2551
2552     ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceid);
2553     if (ctx_surf) {
2554         ivi_controller_surface_screenshot(ctx_surf->controller,
2555                                           filename);
2556         wl_display_flush(ctx->wl.display);
2557         returnValue = ILM_SUCCESS;
2558     }
2559
2560     release_instance();
2561     return returnValue;
2562 }
2563
2564 static ilmErrorTypes
2565 wayland_SetOptimizationMode(ilmOptimization id, ilmOptimizationMode mode)
2566 {
2567     (void)id;
2568     (void)mode;
2569     /* Not supported */
2570     return ILM_FAILED;
2571 }
2572
2573 static ilmErrorTypes
2574 wayland_GetOptimizationMode(ilmOptimization id, ilmOptimizationMode* pMode)
2575 {
2576     (void)id;
2577     (void)pMode;
2578     /* Not supported */
2579     return ILM_FAILED;
2580 }
2581
2582 // TODO
2583 static ilmErrorTypes
2584 wayland_layerAddNotification(t_ilm_layer layer,
2585                              layerNotificationFunc callback)
2586 {
2587     ilmErrorTypes returnValue = ILM_FAILED;
2588     struct ilm_control_context *ctx = sync_and_acquire_instance();
2589     struct layer_context *ctx_layer = NULL;
2590
2591     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2592                     &ctx->wl, (uint32_t)layer);
2593     if (ctx_layer == NULL) {
2594         returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2595     } else {
2596         ctx_layer->notification = callback;
2597
2598         returnValue = ILM_SUCCESS;
2599     }
2600
2601     release_instance();
2602     return returnValue;
2603 }
2604
2605 // TODO
2606 static ilmErrorTypes
2607 wayland_layerRemoveNotification(t_ilm_layer layer)
2608 {
2609    return wayland_layerAddNotification(layer, NULL);
2610 }
2611
2612 // TODO
2613 static ilmErrorTypes
2614 wayland_surfaceAddNotification(t_ilm_surface surface,
2615                              surfaceNotificationFunc callback)
2616 {
2617     ilmErrorTypes returnValue = ILM_FAILED;
2618     struct ilm_control_context *ctx = sync_and_acquire_instance();
2619     struct surface_context *ctx_surf = NULL;
2620
2621     ctx_surf = (struct surface_context*)get_surface_context(
2622                     &ctx->wl, (uint32_t)surface);
2623     if (ctx_surf == NULL) {
2624         returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2625     } else {
2626         ctx_surf->notification = callback;
2627
2628         returnValue = ILM_SUCCESS;
2629     }
2630
2631     release_instance();
2632     return returnValue;
2633 }
2634
2635 // TODO
2636 static ilmErrorTypes
2637 wayland_surfaceRemoveNotification(t_ilm_surface surface)
2638 {
2639     return wayland_surfaceAddNotification(surface, NULL);
2640 }
2641
2642 static ilmErrorTypes
2643 wayland_getNativeHandle(t_ilm_uint pid, t_ilm_int *n_handle,
2644                         t_ilm_nativehandle **p_handles)
2645 {
2646     struct ilm_control_context *ctx = sync_and_acquire_instance();
2647     struct nativehandle_context *p_nh_ctx = NULL;
2648
2649     *n_handle = 0;
2650     *p_handles = NULL;
2651
2652     wl_list_for_each(p_nh_ctx, &ctx->list_nativehandle, link)
2653     {
2654         if (p_nh_ctx->pid == pid)
2655         {
2656             *n_handle = 1;
2657             *p_handles =
2658                  (t_ilm_nativehandle*)malloc(sizeof(t_ilm_nativehandle));
2659             (*p_handles)[0] = p_nh_ctx->nativehandle;
2660             break;
2661         }
2662     }
2663
2664     release_instance();
2665     return (*n_handle > 0) ? ILM_SUCCESS : ILM_FAILED;
2666 }
2667
2668 static ilmErrorTypes
2669 wayland_getPropertiesOfSurface(t_ilm_uint surfaceID,
2670                         struct ilmSurfaceProperties* pSurfaceProperties)
2671 {
2672     ilmErrorTypes returnValue = ILM_FAILED;
2673     struct ilm_control_context *ctx = sync_and_acquire_instance();
2674
2675     if (pSurfaceProperties != NULL) {
2676         struct surface_context *ctx_surf = NULL;
2677
2678         ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceID);
2679         if (ctx_surf != NULL) {
2680
2681             *pSurfaceProperties = ctx_surf->prop;
2682             returnValue = ILM_SUCCESS;
2683         }
2684     }
2685
2686     release_instance();
2687     return returnValue;
2688 }
2689
2690 static ilmErrorTypes
2691 wayland_layerAddSurface(t_ilm_layer layerId,
2692                         t_ilm_surface surfaceId)
2693 {
2694     ilmErrorTypes returnValue = ILM_FAILED;
2695     struct ilm_control_context *ctx = sync_and_acquire_instance();
2696     struct layer_context *ctx_layer = NULL;
2697     struct surface_context *ctx_surf = NULL;
2698
2699     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2700                     &ctx->wl, (uint32_t)layerId);
2701     ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2702     if ((ctx_layer != NULL) && (ctx_surf != NULL)) {
2703         ivi_controller_layer_add_surface(ctx_layer->controller,
2704                                          ctx_surf->controller);
2705         returnValue = ILM_SUCCESS;
2706     }
2707
2708     release_instance();
2709     return returnValue;
2710 }
2711
2712 static ilmErrorTypes
2713 wayland_layerRemoveSurface(t_ilm_layer layerId,
2714                            t_ilm_surface surfaceId)
2715 {
2716     ilmErrorTypes returnValue = ILM_FAILED;
2717     struct ilm_control_context *ctx = sync_and_acquire_instance();
2718     struct layer_context *ctx_layer = NULL;
2719     struct surface_context *ctx_surf = NULL;
2720
2721     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2722                     &ctx->wl, (uint32_t)layerId);
2723     ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2724     if ((ctx_layer != NULL) && (ctx_surf != NULL)) {
2725         ivi_controller_layer_remove_surface(ctx_layer->controller,
2726                                             ctx_surf->controller);
2727         returnValue = ILM_SUCCESS;
2728     }
2729
2730     release_instance();
2731     return returnValue;
2732 }
2733
2734 static ilmErrorTypes
2735 wayland_surfaceGetDimension(t_ilm_surface surfaceId,
2736                             t_ilm_uint *pDimension)
2737 {
2738     ilmErrorTypes returnValue = ILM_FAILED;
2739     struct ilm_control_context *ctx = sync_and_acquire_instance();
2740
2741     if (pDimension != NULL) {
2742         struct surface_context *ctx_surf = NULL;
2743
2744         ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2745         if (ctx_surf != NULL) {
2746             *pDimension = (t_ilm_uint)ctx_surf->prop.destWidth;
2747             *(pDimension + 1) = (t_ilm_uint)ctx_surf->prop.destHeight;
2748             returnValue = ILM_SUCCESS;
2749         }
2750     }
2751
2752     release_instance();
2753     return returnValue;
2754 }
2755
2756 static ilmErrorTypes
2757 wayland_surfaceGetVisibility(t_ilm_surface surfaceId,
2758                              t_ilm_bool *pVisibility)
2759 {
2760     ilmErrorTypes returnValue = ILM_FAILED;
2761     struct ilm_control_context *ctx = sync_and_acquire_instance();
2762     struct surface_context *ctx_surf = NULL;
2763
2764     if (pVisibility != NULL) {
2765         ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2766         if (ctx_surf != NULL) {
2767             *pVisibility = (t_ilm_bool)ctx_surf->prop.visibility;
2768             returnValue = ILM_SUCCESS;
2769         }
2770     }
2771
2772     release_instance();
2773     return returnValue;
2774 }
2775
2776 static ilmErrorTypes
2777 wayland_surfaceSetSourceRectangle(t_ilm_surface surfaceId,
2778                                   t_ilm_int x, t_ilm_int y,
2779                                   t_ilm_int width, t_ilm_int height)
2780 {
2781     ilmErrorTypes returnValue = ILM_FAILED;
2782     struct ilm_control_context *ctx = sync_and_acquire_instance();
2783     struct surface_context *ctx_surf = NULL;
2784
2785     ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2786     if (ctx_surf != NULL) {
2787         if (ctx_surf->controller != NULL) {
2788             ivi_controller_surface_set_source_rectangle(
2789                     ctx_surf->controller,
2790                     x, y, width, height);
2791             returnValue = ILM_SUCCESS;
2792         }
2793     }
2794
2795     release_instance();
2796     return returnValue;
2797 }
2798
2799 static ilmErrorTypes
2800 wayland_commitChanges(void)
2801 {
2802     ilmErrorTypes returnValue = ILM_FAILED;
2803     struct ilm_control_context *ctx = sync_and_acquire_instance();
2804
2805     if (ctx->wl.controller != NULL) {
2806         ivi_controller_commit_changes(ctx->wl.controller);
2807
2808         if (display_roundtrip_queue(ctx->wl.display, ctx->wl.queue) != -1)
2809         {
2810             returnValue = ILM_SUCCESS;
2811         }
2812     }
2813
2814     release_instance();
2815
2816     return returnValue;
2817 }