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