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