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