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