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