downstream: ivi-controller: add argument 'pid' and 'title' to surface event
[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     struct surface_context *ctx_surf = data;
769
770     if (ctx_surf == NULL) {
771         fprintf(stderr, "%s: Invalid surface context\n", __FUNCTION__);
772         return;
773     }
774     if (device & IVI_CONTROLLER_SURFACE_INPUT_DEVICE_KEYBOARD) {
775         ctx_surf->prop.hasKeyboardFocus = enabled;
776     }
777 }
778
779 static struct ivi_controller_surface_listener controller_surface_listener=
780 {
781     controller_surface_listener_visibility,
782     controller_surface_listener_opacity,
783     controller_surface_listener_source_rectangle,
784     controller_surface_listener_destination_rectangle,
785     controller_surface_listener_configuration,
786     controller_surface_listener_orientation,
787     controller_surface_listener_pixelformat,
788     controller_surface_listener_layer,
789     controller_surface_listener_stats,
790     controller_surface_listener_destroyed,
791     controller_surface_listener_content,
792     controller_surface_listener_input_focus
793 };
794
795 static void
796 controller_listener_layer(void *data,
797                           struct ivi_controller *controller,
798                           uint32_t id_layer)
799 {
800    struct wayland_context *ctx = data;
801
802    if (wayland_controller_is_inside_layer_list(&ctx->list_layer, id_layer))
803    {
804       return;
805    }
806
807    (void) create_controller_layer(ctx, 0, 0, id_layer);
808 }
809
810 static void
811 controller_listener_surface(void *data,
812                             struct ivi_controller *controller,
813                             uint32_t id_surface,
814                             int32_t pid,
815                             const char *title)
816 {
817     struct wayland_context *ctx = data;
818     struct surface_context *ctx_surf = NULL;
819     int32_t is_inside = 0;
820
821     (void)pid;
822     (void)title;
823
824     ctx_surf = get_surface_context(ctx, id_surface);
825     if (ctx_surf != NULL) {
826         if (!ctx_surf->is_surface_creation_noticed) {
827             if (ctx_surf->notification != NULL) {
828                 ctx_surf->notification(ctx_surf->id_surface,
829                                        &ctx_surf->prop,
830                                        ILM_NOTIFICATION_CONTENT_AVAILABLE);
831                 ctx_surf->is_surface_creation_noticed = true;
832             }
833             ctx_surf->controller = ivi_controller_surface_create(
834                                        controller, id_surface);
835         }
836         else {
837             fprintf(stderr, "invalid id_surface in controller_listener_surface\n");
838         }
839         return;
840     }
841
842     ctx_surf = calloc(1, sizeof *ctx_surf);
843     if (ctx_surf == NULL) {
844         fprintf(stderr, "Failed to allocate memory for surface_context\n");
845         return;
846     }
847
848     ctx_surf->controller = ivi_controller_surface_create(
849                                controller, id_surface);
850     if (ctx_surf->controller == NULL) {
851         free(ctx_surf);
852         fprintf(stderr, "Failed to create controller surface\n");
853         return;
854     }
855     ctx_surf->id_surface = id_surface;
856     ctx_surf->prop.inputDevicesAcceptance = ILM_INPUT_DEVICE_ALL;
857     ctx_surf->ctx = ctx;
858     ctx_surf->is_surface_creation_noticed = true;
859
860     wl_list_init(&ctx_surf->link);
861     wl_list_insert(&ctx->list_surface, &ctx_surf->link);
862     wl_list_init(&ctx_surf->order.link);
863     ivi_controller_surface_add_listener(ctx_surf->controller,
864                                         &controller_surface_listener, ctx_surf);
865 }
866
867 static void
868 controller_listener_error(void *data,
869                           struct ivi_controller *ivi_controller,
870                           int32_t object_id,
871                           int32_t object_type,
872                           int32_t error_code,
873                           const char *error_text)
874 {
875     (void)data;
876     (void)ivi_controller;
877     (void)object_id;
878     (void)object_type;
879     (void)error_code;
880     (void)error_text;
881 }
882
883 static void
884 controller_listener_screen(void *data,
885                            struct ivi_controller *ivi_controller,
886                            uint32_t id_screen,
887                            struct ivi_controller_screen *controller_screen)
888 {
889     struct wayland_context *ctx = data;
890     struct screen_context *ctx_screen;
891     (void)ivi_controller;
892
893     ctx_screen = get_screen_context_by_serverid(ctx, id_screen);
894     if (ctx_screen == NULL) {
895         fprintf(stderr, "Failed to allocate memory for screen_context\n");
896         return;
897     }
898     ctx_screen->controller = controller_screen;
899 }
900
901 static struct ivi_controller_listener controller_listener= {
902     controller_listener_screen,
903     controller_listener_layer,
904     controller_listener_surface,
905     controller_listener_error
906 };
907
908 static void
909 registry_handle_control(void *data,
910                        struct wl_registry *registry,
911                        uint32_t name, const char *interface,
912                        uint32_t version)
913 {
914     struct wayland_context *ctx = data;
915     (void)version;
916
917     if (strcmp(interface, "ivi_controller") == 0) {
918         ctx->controller = wl_registry_bind(registry, name,
919                                            &ivi_controller_interface, 1);
920         if (ctx->controller == NULL) {
921             fprintf(stderr, "Failed to registry bind ivi_controller\n");
922             return;
923         }
924         if (ivi_controller_add_listener(ctx->controller,
925                                        &controller_listener,
926                                        ctx)) {
927             fprintf(stderr, "Failed to add ivi_controller listener\n");
928             return;
929         }
930     } else if (strcmp(interface, "wl_output") == 0) {
931         struct screen_context *ctx_scrn = calloc(1, sizeof *ctx_scrn);
932         struct wl_proxy *pxy = NULL;
933
934         if (ctx_scrn == NULL) {
935             fprintf(stderr, "Failed to allocate memory for screen_context\n");
936             return;
937         }
938         wl_list_init(&ctx_scrn->link);
939         ctx_scrn->output = wl_registry_bind(registry, name,
940                                            &wl_output_interface, 1);
941         if (ctx_scrn->output == NULL) {
942             free(ctx_scrn);
943             fprintf(stderr, "Failed to registry bind wl_output\n");
944             return;
945         }
946
947         if (wl_output_add_listener(ctx_scrn->output,
948                                    &output_listener,
949                                    ctx_scrn)) {
950             free(ctx_scrn);
951             fprintf(stderr, "Failed to add wl_output listener\n");
952             return;
953         }
954
955         pxy = (struct wl_proxy*)ctx_scrn->output;
956         ctx_scrn->id_from_server = wl_proxy_get_id(pxy);
957         ctx_scrn->id_screen = ctx->num_screen;
958         ctx->num_screen++;
959         wl_list_init(&ctx_scrn->order.list_layer);
960         wl_list_insert(&ctx->list_screen, &ctx_scrn->link);
961     }
962 }
963
964 static const struct wl_registry_listener
965 registry_control_listener= {
966     registry_handle_control,
967     NULL
968 };
969
970 static struct ilm_control_context ilm_context;
971
972 static void destroy_control_resources(void)
973 {
974     struct ilm_control_context *ctx = &ilm_context;
975
976     // free resources of output objects
977     if (! ctx->wl.controller) {
978         struct screen_context *ctx_scrn;
979         struct screen_context *next;
980
981         wl_list_for_each_safe(ctx_scrn, next, &ctx->wl.list_screen, link) {
982             if (ctx_scrn->output != NULL) {
983                 wl_output_destroy(ctx_scrn->output);
984             }
985
986             wl_list_remove(&ctx_scrn->link);
987             free(ctx_scrn);
988         }
989     }
990
991     if (ctx->wl.controller != NULL) {
992         {
993             struct surface_context *l;
994             struct surface_context *n;
995             wl_list_for_each_safe(l, n, &ctx->wl.list_surface, link) {
996                 wl_list_remove(&l->link);
997                 wl_list_remove(&l->order.link);
998                 ivi_controller_surface_destroy(l->controller, 0);
999                 free(l);
1000             }
1001         }
1002
1003         {
1004             struct layer_context *l;
1005             struct layer_context *n;
1006             wl_list_for_each_safe(l, n, &ctx->wl.list_layer, link) {
1007                 wl_list_remove(&l->link);
1008                 wl_list_remove(&l->order.link);
1009                 free(l);
1010             }
1011         }
1012
1013         {
1014             struct screen_context *ctx_scrn;
1015             struct screen_context *next;
1016
1017             wl_list_for_each_safe(ctx_scrn, next, &ctx->wl.list_screen, link) {
1018                 if (ctx_scrn->output != NULL) {
1019                     wl_output_destroy(ctx_scrn->output);
1020                 }
1021
1022                 wl_list_remove(&ctx_scrn->link);
1023                 ivi_controller_screen_destroy(ctx_scrn->controller);
1024                 free(ctx_scrn);
1025             }
1026         }
1027
1028         ivi_controller_destroy(ctx->wl.controller);
1029         ctx->wl.controller = NULL;
1030     }
1031
1032     if (ctx->wl.display) {
1033         wl_display_flush(ctx->wl.display);
1034     }
1035
1036     if (ctx->wl.registry) {
1037         wl_registry_destroy(ctx->wl.registry);
1038         ctx->wl.registry = NULL;
1039     }
1040
1041     if (ctx->wl.queue) {
1042         wl_event_queue_destroy(ctx->wl.queue);
1043         ctx->wl.queue = NULL;
1044     }
1045
1046     if (0 != pthread_mutex_destroy(&ctx->mutex)) {
1047         fprintf(stderr, "failed to destroy pthread_mutex\n");
1048     }
1049 }
1050
1051 static void send_shutdown_event(struct ilm_control_context *ctx)
1052 {
1053     uint64_t buf = 1;
1054     while (write(ctx->shutdown_fd, &buf, sizeof buf) == -1 && errno == EINTR)
1055        ;
1056 }
1057
1058 ILM_EXPORT void
1059 ilmControl_destroy(void)
1060 {
1061     struct ilm_control_context *ctx = &ilm_context;
1062
1063     send_shutdown_event(ctx);
1064
1065     if (0 != pthread_join(ctx->thread, NULL)) {
1066         fprintf(stderr, "failed to join control thread\n");
1067     }
1068
1069     destroy_control_resources();
1070
1071     close(ctx->shutdown_fd);
1072
1073     memset(ctx, 0, sizeof *ctx);
1074 }
1075
1076 ILM_EXPORT ilmErrorTypes
1077 ilmControl_init(t_ilm_nativedisplay nativedisplay)
1078 {
1079     struct ilm_control_context *ctx = &ilm_context;
1080
1081     if (ctx->initialized)
1082     {
1083         fprintf(stderr, "Already initialized!\n");
1084         return ILM_FAILED;
1085     }
1086
1087     if (nativedisplay == 0) {
1088         return ILM_ERROR_INVALID_ARGUMENTS;
1089     }
1090
1091     ctx->shutdown_fd = -1;
1092
1093     ctx->wl.display = (struct wl_display*)nativedisplay;
1094
1095     wl_list_init(&ctx->wl.list_screen);
1096     wl_list_init(&ctx->wl.list_layer);
1097     wl_list_init(&ctx->wl.list_surface);
1098
1099     {
1100        pthread_mutexattr_t a;
1101        if (pthread_mutexattr_init(&a) != 0)
1102        {
1103           return ILM_FAILED;
1104        }
1105
1106        if (pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE) != 0)
1107        {
1108           pthread_mutexattr_destroy(&a);
1109           return ILM_FAILED;
1110        }
1111
1112        if (pthread_mutex_init(&ctx->mutex, &a) != 0)
1113        {
1114            pthread_mutexattr_destroy(&a);
1115            fprintf(stderr, "failed to initialize pthread_mutex\n");
1116            return ILM_FAILED;
1117        }
1118
1119        pthread_mutexattr_destroy(&a);
1120     }
1121
1122     return init_control() == 0 ? ILM_SUCCESS : ILM_FAILED;
1123 }
1124
1125 static void*
1126 control_thread(void *p_ret)
1127 {
1128     struct ilm_control_context *const ctx = &ilm_context;
1129     struct wayland_context *const wl = &ctx->wl;
1130     struct wl_display *const display = wl->display;
1131     struct wl_event_queue *const queue = wl->queue;
1132     int const fd = wl_display_get_fd(display);
1133     int const shutdown_fd = ctx->shutdown_fd;
1134     (void) p_ret;
1135
1136     while (1)
1137     {
1138         while (wl_display_prepare_read_queue(display, queue) != 0)
1139         {
1140             lock_context(ctx);
1141             wl_display_dispatch_queue_pending(display, queue);
1142             unlock_context(ctx);
1143         }
1144
1145         if (wl_display_flush(display) == -1)
1146         {
1147             break;
1148         }
1149
1150         struct pollfd pfd[2] = {
1151            { .fd = fd,          .events = POLLIN },
1152            { .fd = shutdown_fd, .events = POLLIN }
1153         };
1154
1155         int pollret = poll(pfd, 2, -1);
1156         if (pollret != -1 && (pfd[0].revents & POLLIN))
1157         {
1158             wl_display_read_events(display);
1159
1160             lock_context(ctx);
1161             int ret = wl_display_dispatch_queue_pending(display, queue);
1162             unlock_context(ctx);
1163
1164             if (ret == -1)
1165             {
1166                 break;
1167             }
1168         }
1169         else
1170         {
1171             wl_display_cancel_read(display);
1172
1173             if (pollret == -1 || (pfd[1].revents & POLLIN))
1174             {
1175                 break;
1176             }
1177         }
1178     }
1179
1180     return NULL;
1181 }
1182
1183 static int
1184 init_control(void)
1185 {
1186     struct ilm_control_context *ctx = &ilm_context;
1187     struct wayland_context *wl = &ctx->wl;
1188     int wait_count = 0;
1189     int ret = 0;
1190
1191     wl_list_init(&ctx->list_nativehandle);
1192
1193     wl->queue = wl_display_create_queue(wl->display);
1194     if (! wl->queue) {
1195         fprintf(stderr, "Could not create wayland event queue\n");
1196         return -1;
1197     }
1198
1199     /* registry_add_listener for request by ivi-controller */
1200     wl->registry = wl_display_get_registry(wl->display);
1201     if (wl->registry == NULL) {
1202         wl_event_queue_destroy(wl->queue);
1203         wl->queue = NULL;
1204         fprintf(stderr, "Failed to get registry\n");
1205         return -1;
1206     }
1207     wl_proxy_set_queue((void*)wl->registry, wl->queue);
1208
1209     if (wl_registry_add_listener(wl->registry,
1210                              &registry_control_listener, ctx)) {
1211         fprintf(stderr, "Failed to add registry listener\n");
1212         return -1;
1213     }
1214
1215     if (
1216        // first level objects; ivi_controller
1217        display_roundtrip_queue(wl->display, wl->queue) == -1 ||
1218        // second level object: ivi_controller_surfaces/layers
1219        display_roundtrip_queue(wl->display, wl->queue) == -1 ||
1220        // third level objects: ivi_controller_surfaces/layers properties
1221        display_roundtrip_queue(wl->display, wl->queue) == -1)
1222     {
1223         fprintf(stderr, "Failed to initialize wayland connection: %s\n", strerror(errno));
1224         return -1;
1225     }
1226
1227     if (! wl->controller)
1228     {
1229         fprintf(stderr, "ivi_controller not available\n");
1230         return -1;
1231     }
1232
1233     ctx->shutdown_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
1234
1235     if (ctx->shutdown_fd == -1)
1236     {
1237         fprintf(stderr, "Could not setup shutdown-fd: %s\n", strerror(errno));
1238         return ILM_FAILED;
1239     }
1240
1241     ret = pthread_create(&ctx->thread, NULL, control_thread, NULL);
1242
1243     if (ret != 0) {
1244         fprintf(stderr, "Failed to start internal receive thread. returned %d\n", ret);
1245         return -1;
1246     }
1247
1248     ctx->initialized = true;
1249
1250     return 0;
1251 }
1252
1253 static ilmErrorTypes impl_sync_and_acquire_instance(struct ilm_control_context *ctx)
1254 {
1255     if (! ctx->initialized) {
1256         fprintf(stderr, "Not initialized\n");
1257         return ILM_FAILED;
1258     }
1259
1260     lock_context(ctx);
1261
1262     if (display_roundtrip_queue(ctx->wl.display, ctx->wl.queue) == -1) {
1263         int err = wl_display_get_error(ctx->wl.display);
1264         fprintf(stderr, "Error communicating with wayland: %s\n", strerror(err));
1265         unlock_context(ctx);
1266         return ILM_FAILED;
1267     }
1268
1269     return ILM_SUCCESS;
1270 }
1271
1272 #define sync_and_acquire_instance() ({ \
1273     struct ilm_control_context *ctx = &ilm_context; \
1274     { \
1275         ilmErrorTypes status = impl_sync_and_acquire_instance(ctx); \
1276         if (status != ILM_SUCCESS) { \
1277             return status; \
1278         } \
1279     } \
1280     ctx; \
1281 })
1282
1283 static void release_instance(void)
1284 {
1285     struct ilm_control_context *ctx = &ilm_context;
1286     unlock_context(ctx);
1287 }
1288
1289 static uint32_t
1290 gen_layer_id(struct ilm_control_context *ctx)
1291 {
1292     struct layer_context *ctx_layer = NULL;
1293     do {
1294         int found = 0;
1295         if (wl_list_length(&ctx->wl.list_layer) == 0) {
1296             ctx->internal_id_layer++;
1297             return ctx->internal_id_layer;
1298         }
1299         wl_list_for_each(ctx_layer, &ctx->wl.list_layer, link) {
1300             if (ctx_layer->id_layer == ctx->internal_id_layer) {
1301                 found = 1;
1302                 break;
1303             }
1304
1305             if (found == 0) {
1306                 return ctx->internal_id_layer;
1307             }
1308         }
1309         ctx->internal_id_layer++;
1310     } while(1);
1311 }
1312
1313 static struct surface_context*
1314 get_surface_context(struct wayland_context *ctx,
1315                           uint32_t id_surface)
1316 {
1317     struct surface_context *ctx_surf = NULL;
1318
1319     if (ctx->controller == NULL) {
1320         fprintf(stderr, "controller is not initialized in ilmControl\n");
1321         return NULL;
1322     }
1323
1324     wl_list_for_each(ctx_surf, &ctx->list_surface, link) {
1325         if (ctx_surf->id_surface == id_surface) {
1326             return ctx_surf;
1327         }
1328     }
1329
1330     fprintf(stderr, "failed to get surface context in ilmControl\n");
1331     return NULL;
1332 }
1333
1334 static struct screen_context*
1335 get_screen_context_by_id(struct wayland_context *ctx, uint32_t id_screen)
1336 {
1337     struct screen_context *ctx_scrn = NULL;
1338
1339     if (ctx->controller == NULL) {
1340         fprintf(stderr, "get_screen_context_by_id: controller is NULL\n");
1341         return NULL;
1342     }
1343
1344     wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
1345         if (ctx_scrn->id_screen == id_screen) {
1346             return ctx_scrn;
1347         }
1348     }
1349     return NULL;
1350 }
1351
1352 ILM_EXPORT ilmErrorTypes
1353 ilm_getPropertiesOfLayer(t_ilm_uint layerID,
1354                          struct ilmLayerProperties* pLayerProperties)
1355 {
1356     ilmErrorTypes returnValue = ILM_FAILED;
1357     struct ilm_control_context *ctx = sync_and_acquire_instance();
1358     struct layer_context *ctx_layer = NULL;
1359
1360     if (pLayerProperties != NULL) {
1361
1362         ctx_layer = (struct layer_context*)
1363                     wayland_controller_get_layer_context(
1364                         &ctx->wl, (uint32_t)layerID);
1365
1366         if (ctx_layer != NULL) {
1367             *pLayerProperties = ctx_layer->prop;
1368             returnValue = ILM_SUCCESS;
1369         }
1370     }
1371
1372     release_instance();
1373     return returnValue;
1374 }
1375
1376 static void
1377 create_layerids(struct screen_context *ctx_screen,
1378                 t_ilm_layer **layer_ids, t_ilm_uint *layer_count)
1379 {
1380     struct layer_context *ctx_layer = NULL;
1381     t_ilm_layer *ids = NULL;
1382
1383     *layer_count = wl_list_length(&ctx_screen->order.list_layer);
1384     if (*layer_count == 0) {
1385         *layer_ids = NULL;
1386         return;
1387     }
1388
1389     *layer_ids = malloc(*layer_count * sizeof(t_ilm_layer));
1390     if (*layer_ids == NULL) {
1391         fprintf(stderr, "memory insufficient for layerids\n");
1392         *layer_count = 0;
1393         return;
1394     }
1395
1396     ids = *layer_ids;
1397     wl_list_for_each_reverse(ctx_layer, &ctx_screen->order.list_layer, order.link) {
1398         *ids = (t_ilm_layer)ctx_layer->id_layer;
1399         ids++;
1400     }
1401 }
1402
1403 ILM_EXPORT ilmErrorTypes
1404 ilm_getPropertiesOfScreen(t_ilm_display screenID,
1405                               struct ilmScreenProperties* pScreenProperties)
1406 {
1407     ilmErrorTypes returnValue = ILM_FAILED;
1408
1409     if (! pScreenProperties)
1410     {
1411         return ILM_ERROR_INVALID_ARGUMENTS;
1412     }
1413
1414     struct ilm_control_context *ctx = sync_and_acquire_instance();
1415
1416     struct screen_context *ctx_screen = NULL;
1417     ctx_screen = get_screen_context_by_id(&ctx->wl, (uint32_t)screenID);
1418     if (ctx_screen != NULL) {
1419         *pScreenProperties = ctx_screen->prop;
1420         create_layerids(ctx_screen, &pScreenProperties->layerIds,
1421                                     &pScreenProperties->layerCount);
1422         returnValue = ILM_SUCCESS;
1423     }
1424
1425     release_instance();
1426     return returnValue;
1427 }
1428
1429 ILM_EXPORT ilmErrorTypes
1430 ilm_getNumberOfHardwareLayers(t_ilm_uint screenID,
1431                                   t_ilm_uint* pNumberOfHardwareLayers)
1432 {
1433     (void)screenID;
1434     /* Not supported */
1435     if (pNumberOfHardwareLayers != NULL) {
1436         *pNumberOfHardwareLayers = 0;
1437         return ILM_SUCCESS;
1438     } else {
1439         return ILM_FAILED;
1440     }
1441 }
1442
1443 ILM_EXPORT ilmErrorTypes
1444 ilm_getScreenIDs(t_ilm_uint* pNumberOfIDs, t_ilm_uint** ppIDs)
1445 {
1446     ilmErrorTypes returnValue = ILM_FAILED;
1447     struct ilm_control_context *ctx = sync_and_acquire_instance();
1448
1449     if ((pNumberOfIDs != NULL) && (ppIDs != NULL)) {
1450         struct screen_context *ctx_scrn = NULL;
1451         t_ilm_uint length = wl_list_length(&ctx->wl.list_screen);
1452         *pNumberOfIDs = 0;
1453
1454         *ppIDs = (t_ilm_uint*)malloc(length * sizeof **ppIDs);
1455         if (*ppIDs != NULL) {
1456             t_ilm_uint* ids = *ppIDs;
1457             wl_list_for_each(ctx_scrn, &ctx->wl.list_screen, link) {
1458                 *ids = ctx_scrn->id_screen;
1459                 ids++;
1460             }
1461             *pNumberOfIDs = length;
1462
1463             returnValue = ILM_SUCCESS;
1464         }
1465     }
1466
1467     release_instance();
1468     return returnValue;
1469 }
1470
1471 ILM_EXPORT ilmErrorTypes
1472 ilm_getLayerIDs(t_ilm_int* pLength, t_ilm_layer** ppArray)
1473 {
1474     ilmErrorTypes returnValue = ILM_FAILED;
1475     struct ilm_control_context *ctx = sync_and_acquire_instance();
1476
1477     if ((pLength != NULL) && (ppArray != NULL)) {
1478         struct layer_context *ctx_layer = NULL;
1479         t_ilm_uint length = wl_list_length(&ctx->wl.list_layer);
1480         *pLength = 0;
1481
1482         *ppArray = (t_ilm_layer*)malloc(length * sizeof **ppArray);
1483         if (*ppArray != NULL) {
1484             // compositor sends layers in opposite order
1485             // write ids from back to front to turn them around
1486             t_ilm_layer* ids = *ppArray;
1487             wl_list_for_each_reverse(ctx_layer, &ctx->wl.list_layer, link)
1488             {
1489                 *ids = ctx_layer->id_layer;
1490                 ++ids;
1491             }
1492             *pLength = length;
1493
1494             returnValue = ILM_SUCCESS;
1495         }
1496     }
1497
1498     release_instance();
1499     return returnValue;
1500 }
1501
1502 ILM_EXPORT ilmErrorTypes
1503 ilm_getLayerIDsOnScreen(t_ilm_uint screenId,
1504                             t_ilm_int* pLength,
1505                             t_ilm_layer** ppArray)
1506 {
1507     ilmErrorTypes returnValue = ILM_FAILED;
1508     struct ilm_control_context *ctx = sync_and_acquire_instance();
1509
1510     if ((pLength != NULL) && (ppArray != NULL)) {
1511         struct screen_context *ctx_screen = NULL;
1512         ctx_screen = get_screen_context_by_id(&ctx->wl, screenId);
1513         if (ctx_screen != NULL) {
1514             struct layer_context *ctx_layer = NULL;
1515             t_ilm_int length = wl_list_length(&ctx_screen->order.list_layer);
1516
1517             if (0 < length)
1518             {
1519                 *ppArray = (t_ilm_layer*)malloc(length * sizeof **ppArray);
1520                 if (*ppArray != NULL) {
1521                     // compositor sends layers in opposite order
1522                     // write ids from back to front to turn them around
1523                     t_ilm_layer* ids = *ppArray;
1524                     wl_list_for_each_reverse(ctx_layer, &ctx_screen->order.list_layer, order.link)
1525                     {
1526                         *ids = ctx_layer->id_layer;
1527                         ++ids;
1528                     }
1529
1530                 }
1531             }
1532             else
1533             {
1534                 *ppArray = NULL;
1535             }
1536
1537             *pLength = length;
1538             returnValue = ILM_SUCCESS;
1539         }
1540     }
1541
1542     release_instance();
1543     return returnValue;
1544 }
1545
1546 ILM_EXPORT ilmErrorTypes
1547 ilm_getSurfaceIDs(t_ilm_int* pLength, t_ilm_surface** ppArray)
1548 {
1549     ilmErrorTypes returnValue = ILM_FAILED;
1550     struct ilm_control_context *ctx = sync_and_acquire_instance();
1551
1552     if ((pLength != NULL) && (ppArray != NULL)) {
1553         struct surface_context *ctx_surf = NULL;
1554         t_ilm_uint length = wl_list_length(&ctx->wl.list_surface);
1555         *pLength = 0;
1556
1557         *ppArray = (t_ilm_surface*)malloc(length * sizeof **ppArray);
1558         if (*ppArray != NULL) {
1559             t_ilm_surface* ids = *ppArray;
1560             wl_list_for_each_reverse(ctx_surf, &ctx->wl.list_surface, link) {
1561                 *ids = ctx_surf->id_surface;
1562                 ids++;
1563             }
1564             *pLength = length;
1565
1566             returnValue = ILM_SUCCESS;
1567         }
1568     }
1569
1570     release_instance();
1571     return returnValue;
1572 }
1573
1574 ILM_EXPORT ilmErrorTypes
1575 ilm_getSurfaceIDsOnLayer(t_ilm_layer layer,
1576                              t_ilm_int* pLength,
1577                              t_ilm_surface** ppArray)
1578 {
1579     struct ilm_control_context *ctx = sync_and_acquire_instance();
1580     struct layer_context *ctx_layer = NULL;
1581     struct surface_context *ctx_surf = NULL;
1582     t_ilm_uint length = 0;
1583     t_ilm_surface* ids = NULL;
1584
1585     if ((pLength == NULL) || (ppArray == NULL)) {
1586         release_instance();
1587         return ILM_FAILED;
1588     }
1589
1590     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1591                     &ctx->wl, (uint32_t)layer);
1592
1593     if (ctx_layer == NULL) {
1594         release_instance();
1595         return ILM_FAILED;
1596     }
1597
1598     length = wl_list_length(&ctx_layer->order.list_surface);
1599     *ppArray = (t_ilm_surface*)malloc(length * sizeof **ppArray);
1600     if (*ppArray == NULL) {
1601         release_instance();
1602         return ILM_FAILED;
1603     }
1604
1605     ids = *ppArray;
1606     wl_list_for_each_reverse(ctx_surf, &ctx_layer->order.list_surface, order.link) {
1607         *ids = (t_ilm_surface)ctx_surf->id_surface;
1608         ids++;
1609     }
1610     *pLength = length;
1611
1612     release_instance();
1613     return ILM_SUCCESS;
1614 }
1615
1616 static int create_controller_layer(struct wayland_context *ctx, t_ilm_uint width, t_ilm_uint height, t_ilm_layer layerid)
1617 {
1618      struct layer_context *ctx_layer = calloc(1, sizeof *ctx_layer);
1619      if (ctx_layer == NULL) {
1620          fprintf(stderr, "Failed to allocate memory for layer_context\n");
1621          return -1;
1622      }
1623
1624      ctx_layer->controller = ivi_controller_layer_create(
1625                                  ctx->controller,
1626                                  layerid, width, height);
1627      if (ctx_layer->controller == NULL) {
1628          fprintf(stderr, "Failed to create layer\n");
1629          free(ctx_layer);
1630          return -1;
1631      }
1632      ctx_layer->id_layer = layerid;
1633      ctx_layer->ctx = ctx;
1634
1635      wl_list_init(&ctx_layer->link);
1636      wl_list_insert(&ctx->list_layer, &ctx_layer->link);
1637      wl_list_init(&ctx_layer->order.link);
1638      wl_list_init(&ctx_layer->order.list_surface);
1639
1640      ivi_controller_layer_add_listener(ctx_layer->controller,
1641                                    &controller_layer_listener, ctx_layer);
1642
1643      return 0;
1644 }
1645
1646 ILM_EXPORT ilmErrorTypes
1647 ilm_layerCreateWithDimension(t_ilm_layer* pLayerId,
1648                                  t_ilm_uint width,
1649                                  t_ilm_uint height)
1650 {
1651     ilmErrorTypes returnValue = ILM_FAILED;
1652     struct ilm_control_context *ctx = sync_and_acquire_instance();
1653     uint32_t layerid = 0;
1654     int32_t is_inside = 0;
1655
1656     do {
1657         if (pLayerId == NULL) {
1658             break;
1659         }
1660
1661         if (*pLayerId != INVALID_ID) {
1662             /* Return failed, if layerid is already inside list_layer */
1663             is_inside = wayland_controller_is_inside_layer_list(
1664                             &ctx->wl.list_layer, *pLayerId);
1665             if (0 != is_inside) {
1666                 fprintf(stderr, "layerid=%d is already used.\n", *pLayerId);
1667                 break;
1668             }
1669             layerid = *pLayerId;
1670         }
1671         else {
1672             /* Generate ID, if layerid is INVALID_ID */
1673             layerid = gen_layer_id(ctx);
1674             *pLayerId = layerid;
1675         }
1676
1677         if (create_controller_layer(&ctx->wl, width, height, layerid) == 0)
1678         {
1679            returnValue = ILM_SUCCESS;
1680         }
1681     } while(0);
1682
1683     release_instance();
1684     return returnValue;
1685 }
1686
1687 ILM_EXPORT ilmErrorTypes
1688 ilm_layerRemove(t_ilm_layer layerId)
1689 {
1690     ilmErrorTypes returnValue = ILM_FAILED;
1691     struct ilm_control_context *ctx = sync_and_acquire_instance();
1692     struct layer_context *ctx_layer = NULL;
1693     struct layer_context *ctx_next = NULL;
1694
1695     wl_list_for_each_safe(ctx_layer, ctx_next,
1696             &ctx->wl.list_layer, link) {
1697         if (ctx_layer->id_layer == layerId) {
1698             ivi_controller_layer_destroy(ctx_layer->controller, 1);
1699
1700             wl_list_remove(&ctx_layer->link);
1701             free(ctx_layer);
1702
1703             returnValue = ILM_SUCCESS;
1704             break;
1705         }
1706     }
1707
1708     release_instance();
1709     return returnValue;
1710 }
1711
1712 ILM_EXPORT ilmErrorTypes
1713 ilm_layerGetType(t_ilm_layer layerId, ilmLayerType* pLayerType)
1714 {
1715     if (!pLayerType)
1716     {
1717        return ILM_ERROR_INVALID_ARGUMENTS;
1718     }
1719
1720     struct ilm_control_context *ctx = sync_and_acquire_instance();
1721
1722     *pLayerType = wayland_controller_is_inside_layer_list(&ctx->wl.list_layer, layerId) ?
1723        ILM_LAYERTYPE_SOFTWARE2D :
1724        ILM_LAYERTYPE_UNKNOWN;
1725
1726     release_instance();
1727     return ILM_SUCCESS; // even if non existent?
1728 }
1729
1730 ILM_EXPORT ilmErrorTypes
1731 ilm_layerSetVisibility(t_ilm_layer layerId, t_ilm_bool newVisibility)
1732 {
1733     ilmErrorTypes returnValue = ILM_FAILED;
1734     struct ilm_control_context *ctx = sync_and_acquire_instance();
1735     struct layer_context *ctx_layer = NULL;
1736
1737     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1738                     &ctx->wl, (uint32_t)layerId);
1739
1740     if (ctx_layer != NULL) {
1741         uint32_t visibility = 0;
1742         if (newVisibility == ILM_TRUE) {
1743             visibility = 1;
1744         }
1745         ivi_controller_layer_set_visibility(ctx_layer->controller,
1746                                             visibility);
1747         returnValue = ILM_SUCCESS;
1748     }
1749
1750     release_instance();
1751     return returnValue;
1752 }
1753
1754 ILM_EXPORT ilmErrorTypes
1755 ilm_layerGetVisibility(t_ilm_layer layerId, t_ilm_bool *pVisibility)
1756 {
1757     ilmErrorTypes returnValue = ILM_FAILED;
1758     struct ilm_control_context *ctx = sync_and_acquire_instance();
1759
1760     if (pVisibility != NULL) {
1761         struct layer_context *ctx_layer = NULL;
1762
1763         ctx_layer = (struct layer_context*)
1764                     wayland_controller_get_layer_context(
1765                         &ctx->wl, (uint32_t)layerId);
1766
1767         if (ctx_layer != NULL) {
1768             *pVisibility = ctx_layer->prop.visibility;
1769             returnValue = ILM_SUCCESS;
1770         }
1771     }
1772
1773     release_instance();
1774     return returnValue;
1775 }
1776
1777 ILM_EXPORT ilmErrorTypes
1778 ilm_layerSetOpacity(t_ilm_layer layerId, t_ilm_float opacity)
1779 {
1780     ilmErrorTypes returnValue = ILM_FAILED;
1781     struct ilm_control_context *ctx = sync_and_acquire_instance();
1782     struct layer_context *ctx_layer = NULL;
1783
1784     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1785                     &ctx->wl, (uint32_t)layerId);
1786
1787     if (ctx_layer != NULL) {
1788         wl_fixed_t opacity_fixed = wl_fixed_from_double((double)opacity);
1789         ivi_controller_layer_set_opacity(ctx_layer->controller,
1790                                          opacity_fixed);
1791         returnValue = ILM_SUCCESS;
1792     }
1793
1794     release_instance();
1795     return returnValue;
1796 }
1797
1798 ILM_EXPORT ilmErrorTypes
1799 ilm_layerGetOpacity(t_ilm_layer layerId, t_ilm_float *pOpacity)
1800 {
1801     ilmErrorTypes returnValue = ILM_FAILED;
1802     struct ilm_control_context *ctx = sync_and_acquire_instance();
1803
1804     if (pOpacity != NULL) {
1805         struct layer_context *ctx_layer = NULL;
1806
1807         ctx_layer = (struct layer_context*)
1808                     wayland_controller_get_layer_context(
1809                         &ctx->wl, (uint32_t)layerId);
1810
1811         if (ctx_layer != NULL) {
1812             *pOpacity = ctx_layer->prop.opacity;
1813             returnValue = ILM_SUCCESS;
1814         }
1815     }
1816
1817     release_instance();
1818     return returnValue;
1819 }
1820
1821 ILM_EXPORT ilmErrorTypes
1822 ilm_layerSetSourceRectangle(t_ilm_layer layerId,
1823                                 t_ilm_uint x, t_ilm_uint y,
1824                                 t_ilm_uint width, t_ilm_uint height)
1825 {
1826     ilmErrorTypes returnValue = ILM_FAILED;
1827     struct ilm_control_context *ctx = sync_and_acquire_instance();
1828     struct layer_context *ctx_layer = NULL;
1829
1830     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1831                     &ctx->wl, (uint32_t)layerId);
1832
1833     if (ctx_layer != NULL) {
1834         ivi_controller_layer_set_source_rectangle(ctx_layer->controller,
1835                                                   (uint32_t)x,
1836                                                   (uint32_t)y,
1837                                                   (uint32_t)width,
1838                                                   (uint32_t)height);
1839         returnValue = ILM_SUCCESS;
1840     }
1841
1842     release_instance();
1843     return returnValue;
1844 }
1845
1846 ILM_EXPORT ilmErrorTypes
1847 ilm_layerSetDestinationRectangle(t_ilm_layer layerId,
1848                                  t_ilm_int x, t_ilm_int y,
1849                                  t_ilm_int width, t_ilm_int height)
1850 {
1851     ilmErrorTypes returnValue = ILM_FAILED;
1852     struct ilm_control_context *ctx = sync_and_acquire_instance();
1853     struct layer_context *ctx_layer = NULL;
1854
1855     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1856                     &ctx->wl, (uint32_t)layerId);
1857     if (ctx_layer != NULL) {
1858         ivi_controller_layer_set_destination_rectangle(
1859                                          ctx_layer->controller,
1860                                          (uint32_t)x, (uint32_t)y,
1861                                          (uint32_t)width,
1862                                          (uint32_t)height);
1863         returnValue = ILM_SUCCESS;
1864     }
1865
1866     release_instance();
1867     return returnValue;
1868 }
1869
1870 ILM_EXPORT ilmErrorTypes
1871 ilm_layerGetDimension(t_ilm_layer layerId, t_ilm_uint *pDimension)
1872 {
1873     ilmErrorTypes returnValue = ILM_FAILED;
1874     struct ilm_control_context *ctx = sync_and_acquire_instance();
1875     struct layer_context *ctx_layer = NULL;
1876
1877     if (pDimension != NULL) {
1878         ctx_layer = (struct layer_context*)
1879                     wayland_controller_get_layer_context(
1880                         &ctx->wl, (uint32_t)layerId);
1881         if (ctx_layer != NULL) {
1882             *pDimension = ctx_layer->prop.destWidth;
1883             *(pDimension + 1) = ctx_layer->prop.destHeight;
1884             returnValue = ILM_SUCCESS;
1885         }
1886     }
1887
1888     release_instance();
1889     return returnValue;
1890 }
1891
1892 ILM_EXPORT ilmErrorTypes
1893 ilm_layerSetDimension(t_ilm_layer layerId, t_ilm_uint *pDimension)
1894 {
1895     ilmErrorTypes returnValue = ILM_FAILED;
1896     struct ilm_control_context *ctx = sync_and_acquire_instance();
1897     struct layer_context *ctx_layer = NULL;
1898
1899     if (pDimension != NULL) {
1900         ctx_layer = (struct layer_context*)
1901                     wayland_controller_get_layer_context(
1902                         &ctx->wl, (uint32_t)layerId);
1903         if (ctx_layer != NULL) {
1904             ivi_controller_layer_set_destination_rectangle(
1905                 ctx_layer->controller,
1906                 ctx_layer->prop.destX, ctx_layer->prop.destY,
1907                 (int32_t)*pDimension, (int32_t)*(pDimension + 1));
1908             returnValue = ILM_SUCCESS;
1909         }
1910     }
1911
1912     release_instance();
1913     return returnValue;
1914 }
1915
1916 ILM_EXPORT ilmErrorTypes
1917 ilm_layerGetPosition(t_ilm_layer layerId, t_ilm_uint *pPosition)
1918 {
1919     ilmErrorTypes returnValue = ILM_FAILED;
1920     struct ilm_control_context *ctx = sync_and_acquire_instance();
1921     struct layer_context *ctx_layer = NULL;
1922
1923     if (pPosition != NULL) {
1924         ctx_layer = (struct layer_context*)
1925                     wayland_controller_get_layer_context(
1926                         &ctx->wl, (uint32_t)layerId);
1927         if (ctx_layer != NULL) {
1928             *pPosition = ctx_layer->prop.destX;
1929             *(pPosition + 1) = ctx_layer->prop.destY;
1930             returnValue = ILM_SUCCESS;
1931         }
1932     }
1933
1934     release_instance();
1935     return returnValue;
1936 }
1937
1938 ILM_EXPORT ilmErrorTypes
1939 ilm_layerSetPosition(t_ilm_layer layerId, t_ilm_uint *pPosition)
1940 {
1941     ilmErrorTypes returnValue = ILM_FAILED;
1942     struct ilm_control_context *ctx = sync_and_acquire_instance();
1943     struct layer_context *ctx_layer = NULL;
1944
1945     if (pPosition != NULL) {
1946         ctx_layer = (struct layer_context*)
1947                     wayland_controller_get_layer_context(
1948                         &ctx->wl, (uint32_t)layerId);
1949         if (ctx_layer != NULL) {
1950             ivi_controller_layer_set_destination_rectangle(
1951                 ctx_layer->controller,
1952                 (int32_t)*pPosition, (int32_t)*(pPosition + 1),
1953                 ctx_layer->prop.destWidth, ctx_layer->prop.destHeight);
1954             returnValue = ILM_SUCCESS;
1955         }
1956     }
1957
1958     release_instance();
1959     return returnValue;
1960 }
1961
1962 ILM_EXPORT ilmErrorTypes
1963 ilm_layerSetOrientation(t_ilm_layer layerId, ilmOrientation orientation)
1964 {
1965     ilmErrorTypes returnValue = ILM_FAILED;
1966     struct ilm_control_context *ctx = sync_and_acquire_instance();
1967     struct layer_context *ctx_layer = NULL;
1968     int32_t iviorientation = 0;
1969
1970     do {
1971         switch(orientation) {
1972         case ILM_ZERO:
1973             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES;
1974             break;
1975         case ILM_NINETY:
1976             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES;
1977             break;
1978         case ILM_ONEHUNDREDEIGHTY:
1979             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES;
1980             break;
1981         case ILM_TWOHUNDREDSEVENTY:
1982             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES;
1983             break;
1984         default:
1985             returnValue = ILM_ERROR_INVALID_ARGUMENTS;
1986             break;
1987         }
1988
1989         ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1990                         &ctx->wl, (uint32_t)layerId);
1991         if (ctx_layer == NULL) {
1992             returnValue = ILM_FAILED;
1993             break;
1994         }
1995
1996         ivi_controller_layer_set_orientation(ctx_layer->controller,
1997                                              iviorientation);
1998
1999         returnValue = ILM_SUCCESS;
2000     } while(0);
2001
2002     release_instance();
2003     return returnValue;
2004 }
2005
2006 ILM_EXPORT ilmErrorTypes
2007 ilm_layerGetOrientation(t_ilm_layer layerId, ilmOrientation *pOrientation)
2008 {
2009     ilmErrorTypes returnValue = ILM_FAILED;
2010     struct ilm_control_context *ctx = sync_and_acquire_instance();
2011     struct layer_context *ctx_layer = NULL;
2012
2013     if (pOrientation != NULL) {
2014         ctx_layer = (struct layer_context*)
2015                     wayland_controller_get_layer_context(
2016                         &ctx->wl, (uint32_t)layerId);
2017         if (ctx_layer != NULL) {
2018             *pOrientation = ctx_layer->prop.orientation;
2019             returnValue = ILM_SUCCESS;
2020         }
2021     }
2022
2023     release_instance();
2024     return returnValue;
2025 }
2026
2027 ILM_EXPORT ilmErrorTypes
2028 ilm_layerSetChromaKey(t_ilm_layer layerId, t_ilm_int* pColor)
2029 {
2030     (void)layerId;
2031     (void)pColor;
2032     /* Not supported */
2033     return ILM_FAILED;
2034 }
2035
2036 ILM_EXPORT ilmErrorTypes
2037 ilm_layerSetRenderOrder(t_ilm_layer layerId,
2038                         t_ilm_surface *pSurfaceId,
2039                         t_ilm_int number)
2040 {
2041     ilmErrorTypes returnValue = ILM_FAILED;
2042     struct ilm_control_context *ctx = sync_and_acquire_instance();
2043     struct layer_context *ctx_layer = NULL;
2044
2045     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2046                     &ctx->wl, (uint32_t)layerId);
2047
2048     if (ctx_layer)
2049     {
2050         struct wl_array ids;
2051         wl_array_init(&ids);
2052         uint32_t *pids = wl_array_add(&ids, number * sizeof *pids);
2053         t_ilm_uint i;
2054         for (i = 0; i < number; i++) pids[i] = (uint32_t)pSurfaceId[i];
2055         ivi_controller_layer_set_render_order(ctx_layer->controller, &ids);
2056         wl_array_release(&ids);
2057         returnValue = ILM_SUCCESS;
2058     }
2059
2060     release_instance();
2061     return returnValue;
2062 }
2063
2064 ILM_EXPORT ilmErrorTypes
2065 ilm_layerGetCapabilities(t_ilm_layer layerId,
2066                          t_ilm_layercapabilities *pCapabilities)
2067 {
2068     (void)layerId;
2069     (void)pCapabilities;
2070     /* Not supported */
2071     return ILM_FAILED;
2072 }
2073
2074 ILM_EXPORT ilmErrorTypes
2075 ilm_layerTypeGetCapabilities(ilmLayerType layerType,
2076                              t_ilm_layercapabilities *pCapabilities)
2077 {
2078     (void)layerType;
2079     (void)pCapabilities;
2080     /* Not supported */
2081     return ILM_FAILED;
2082 }
2083
2084 ILM_EXPORT ilmErrorTypes
2085 ilm_surfaceSetVisibility(t_ilm_surface surfaceId, t_ilm_bool newVisibility)
2086 {
2087     ilmErrorTypes returnValue = ILM_FAILED;
2088     struct ilm_control_context *ctx = sync_and_acquire_instance();
2089     struct surface_context *ctx_surf = NULL;
2090     uint32_t visibility = 0;
2091
2092     if (newVisibility == ILM_TRUE) {
2093         visibility = 1;
2094     }
2095     ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2096     if (ctx_surf) {
2097         ivi_controller_surface_set_visibility(ctx_surf->controller,
2098                                               visibility);
2099         returnValue = ILM_SUCCESS;
2100     }
2101
2102     release_instance();
2103     return returnValue;
2104 }
2105
2106 ILM_EXPORT ilmErrorTypes
2107 ilm_surfaceSetOpacity(t_ilm_surface surfaceId, t_ilm_float opacity)
2108 {
2109     ilmErrorTypes returnValue = ILM_FAILED;
2110     struct ilm_control_context *ctx = sync_and_acquire_instance();
2111     struct surface_context *ctx_surf = NULL;
2112     wl_fixed_t opacity_fixed = 0;
2113
2114     opacity_fixed = wl_fixed_from_double((double)opacity);
2115     ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2116     if (ctx_surf) {
2117         ivi_controller_surface_set_opacity(ctx_surf->controller,
2118                                            opacity_fixed);
2119         returnValue = ILM_SUCCESS;
2120     }
2121
2122     release_instance();
2123     return returnValue;
2124 }
2125
2126 ILM_EXPORT ilmErrorTypes
2127 ilm_surfaceGetOpacity(t_ilm_surface surfaceId, t_ilm_float *pOpacity)
2128 {
2129     ilmErrorTypes returnValue = ILM_FAILED;
2130     struct ilm_control_context *ctx = sync_and_acquire_instance();
2131
2132     if (pOpacity != NULL) {
2133         struct surface_context *ctx_surf = NULL;
2134         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2135         if (ctx_surf) {
2136             *pOpacity = ctx_surf->prop.opacity;
2137             returnValue = ILM_SUCCESS;
2138         }
2139     }
2140
2141     release_instance();
2142     return returnValue;
2143 }
2144
2145 ILM_EXPORT ilmErrorTypes
2146 ilm_SetKeyboardFocusOn(t_ilm_surface surfaceId)
2147 {
2148     ilmErrorTypes returnValue = ILM_FAILED;
2149     struct ilm_control_context *ctx = sync_and_acquire_instance();
2150     struct surface_context *ctx_surf =
2151         get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2152
2153     if (ctx_surf != NULL
2154         && ctx_surf->prop.inputDevicesAcceptance & ILM_INPUT_DEVICE_KEYBOARD)
2155     {
2156         ivi_controller_surface_set_input_focus(ctx_surf->controller,
2157                         IVI_CONTROLLER_SURFACE_INPUT_DEVICE_KEYBOARD, 1);
2158         returnValue = ILM_SUCCESS;
2159     }
2160     release_instance();
2161     return returnValue;
2162 }
2163
2164 ILM_EXPORT ilmErrorTypes
2165 ilm_GetKeyboardFocusSurfaceId(t_ilm_surface* pSurfaceId)
2166 {
2167     struct ilm_control_context *ctx = sync_and_acquire_instance();
2168     struct surface_context *ctx_surf = NULL;
2169
2170     wl_list_for_each(ctx_surf, &ctx->wl.list_surface, link) {
2171         if (ctx_surf->prop.hasKeyboardFocus) {
2172             *pSurfaceId = ctx_surf->id_surface;
2173             break;
2174         }
2175     }
2176
2177     release_instance();
2178     return ILM_SUCCESS;
2179 }
2180
2181 ILM_EXPORT ilmErrorTypes
2182 ilm_SetKeyboardMultiFocus(t_ilm_surface *pSurfaceIds, t_ilm_int number)
2183 {
2184     struct ilm_control_context *ctx = sync_and_acquire_instance();
2185     struct surface_context *ctx_surf;
2186     unsigned int i, send_elements = 0;
2187     struct wl_array send_array;
2188     ilmErrorTypes retval = ILM_FAILED;
2189     uint32_t *data;
2190
2191     wl_array_init(&send_array);
2192     wl_array_add(&send_array, sizeof(uint32_t) * number);
2193
2194     data = send_array.data;
2195     for (i = 0; i < number; i++) {
2196         ctx_surf = get_surface_context(&ctx->wl, (uint32_t) pSurfaceIds[i]);
2197         if (ctx_surf->prop.inputDevicesAcceptance & ILM_INPUT_DEVICE_KEYBOARD) {
2198             data[send_elements] = pSurfaceIds[i];
2199             send_elements++;
2200         }
2201     }
2202
2203     if (send_elements > 0) {
2204         ivi_controller_set_keyboard_focus(ctx->wl.controller, &send_array);
2205         retval = ILM_SUCCESS;
2206     }
2207
2208     wl_array_release(&send_array);
2209     release_instance();
2210     return retval;
2211 }
2212
2213 ILM_EXPORT ilmErrorTypes
2214 ilm_GetKeyboardMultiFocusSurfaceIds(t_ilm_surface *pSurfaceIds, t_ilm_int size,
2215                                     t_ilm_int *pCount)
2216 {
2217     struct ilm_control_context *ctx = sync_and_acquire_instance();
2218     struct surface_context *ctx_surf;
2219
2220     *pCount = 0;
2221     wl_list_for_each(ctx_surf, &ctx->wl.list_surface, link) {
2222         if (ctx_surf->prop.hasKeyboardFocus) {
2223             if (*pCount >= size) {
2224                 fprintf(stderr, "not enough space to store surface IDs\n");
2225                 break;
2226             }
2227             pSurfaceIds[*pCount] = ctx_surf->id_surface;
2228             (*pCount)++;
2229         }
2230     }
2231
2232     release_instance();
2233
2234     return ILM_SUCCESS;
2235 }
2236
2237 ILM_EXPORT ilmErrorTypes
2238 ilm_surfaceSetDestinationRectangle(t_ilm_surface surfaceId,
2239                                    t_ilm_int x, t_ilm_int y,
2240                                    t_ilm_int width, t_ilm_int height)
2241 {
2242     ilmErrorTypes returnValue = ILM_FAILED;
2243     struct ilm_control_context *ctx = sync_and_acquire_instance();
2244     struct surface_context *ctx_surf = NULL;
2245
2246     ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2247     if (ctx_surf) {
2248         ivi_controller_surface_set_destination_rectangle(
2249                                              ctx_surf->controller,
2250                                              x, y, width, height);
2251         returnValue = ILM_SUCCESS;
2252     }
2253
2254     release_instance();
2255     return returnValue;
2256 }
2257
2258 ILM_EXPORT ilmErrorTypes
2259 ilm_surfaceSetDimension(t_ilm_surface surfaceId, t_ilm_uint *pDimension)
2260 {
2261     ilmErrorTypes returnValue = ILM_FAILED;
2262     struct ilm_control_context *ctx = sync_and_acquire_instance();
2263
2264     if (pDimension != NULL) {
2265         struct surface_context *ctx_surf = NULL;
2266         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2267         if (ctx_surf) {
2268             uint32_t width = *pDimension;
2269             uint32_t height = *(pDimension + 1);
2270             ivi_controller_surface_set_destination_rectangle(
2271                 ctx_surf->controller,
2272                 ctx_surf->prop.destX, ctx_surf->prop.destY, width, height);
2273             returnValue = ILM_SUCCESS;
2274         }
2275     }
2276
2277     release_instance();
2278     return returnValue;
2279 }
2280
2281 ILM_EXPORT ilmErrorTypes
2282 ilm_surfaceGetPosition(t_ilm_surface surfaceId, t_ilm_uint *pPosition)
2283 {
2284     ilmErrorTypes returnValue = ILM_FAILED;
2285     struct ilm_control_context *ctx = sync_and_acquire_instance();
2286
2287     if (pPosition != NULL) {
2288         struct surface_context *ctx_surf = NULL;
2289         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2290         if (ctx_surf) {
2291             *pPosition = ctx_surf->prop.destX;
2292             *(pPosition + 1) = ctx_surf->prop.destY;
2293             returnValue = ILM_SUCCESS;
2294         }
2295     }
2296
2297     release_instance();
2298     return returnValue;
2299 }
2300
2301 ILM_EXPORT ilmErrorTypes
2302 ilm_surfaceSetPosition(t_ilm_surface surfaceId, t_ilm_uint *pPosition)
2303 {
2304     ilmErrorTypes returnValue = ILM_FAILED;
2305     struct ilm_control_context *ctx = sync_and_acquire_instance();
2306
2307     if (pPosition != NULL) {
2308         struct surface_context *ctx_surf = NULL;
2309         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2310         if (ctx_surf) {
2311             int32_t destX = (int32_t)*pPosition;
2312             int32_t destY = (int32_t)*(pPosition + 1);
2313             ivi_controller_surface_set_destination_rectangle(
2314                 ctx_surf->controller, destX, destY,
2315                 ctx_surf->prop.destWidth, ctx_surf->prop.destHeight);
2316             returnValue = ILM_SUCCESS;
2317         }
2318     }
2319
2320     release_instance();
2321     return returnValue;
2322 }
2323
2324 ILM_EXPORT ilmErrorTypes
2325 ilm_surfaceSetOrientation(t_ilm_surface surfaceId,
2326                               ilmOrientation orientation)
2327 {
2328     ilmErrorTypes returnValue = ILM_FAILED;
2329     struct ilm_control_context *ctx = sync_and_acquire_instance();
2330     struct surface_context *ctx_surf = NULL;
2331     int32_t iviorientation = 0;
2332
2333     do {
2334         switch(orientation) {
2335         case ILM_ZERO:
2336             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES;
2337             break;
2338         case ILM_NINETY:
2339             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES;
2340             break;
2341         case ILM_ONEHUNDREDEIGHTY:
2342             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES;
2343             break;
2344         case ILM_TWOHUNDREDSEVENTY:
2345             iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES;
2346             break;
2347         default:
2348             returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2349             break;
2350         }
2351
2352         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2353         if (ctx_surf == NULL) {
2354             returnValue = ILM_FAILED;
2355             break;
2356         }
2357
2358         ivi_controller_surface_set_orientation(ctx_surf->controller,
2359                                                iviorientation);
2360
2361         returnValue = ILM_SUCCESS;
2362     } while(0);
2363
2364     release_instance();
2365     return returnValue;
2366 }
2367
2368 ILM_EXPORT ilmErrorTypes
2369 ilm_surfaceGetOrientation(t_ilm_surface surfaceId,
2370                               ilmOrientation *pOrientation)
2371 {
2372     ilmErrorTypes returnValue = ILM_FAILED;
2373     struct ilm_control_context *ctx = sync_and_acquire_instance();
2374
2375     if (pOrientation != NULL) {
2376         struct surface_context *ctx_surf = NULL;
2377         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2378         if (ctx_surf) {
2379             *pOrientation = ctx_surf->prop.orientation;
2380             returnValue = ILM_SUCCESS;
2381         }
2382     }
2383
2384     release_instance();
2385     return returnValue;
2386 }
2387
2388 ILM_EXPORT ilmErrorTypes
2389 ilm_surfaceGetPixelformat(t_ilm_layer surfaceId,
2390                               ilmPixelFormat *pPixelformat)
2391 {
2392     ilmErrorTypes returnValue = ILM_FAILED;
2393     struct ilm_control_context *ctx = sync_and_acquire_instance();
2394
2395     if (pPixelformat != NULL) {
2396         struct surface_context *ctx_surf = NULL;
2397         ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2398         if (ctx_surf) {
2399             *pPixelformat = ctx_surf->prop.pixelformat;
2400             returnValue = ILM_SUCCESS;
2401         }
2402     }
2403
2404     release_instance();
2405     return returnValue;
2406 }
2407
2408 ILM_EXPORT ilmErrorTypes
2409 ilm_surfaceSetChromaKey(t_ilm_surface surfaceId, t_ilm_int* pColor)
2410 {
2411     (void)surfaceId;
2412     (void)pColor;
2413     /* Not supported */
2414     return ILM_FAILED;
2415 }
2416
2417 ILM_EXPORT ilmErrorTypes
2418 ilm_displaySetRenderOrder(t_ilm_display display,
2419                           t_ilm_layer *pLayerId, const t_ilm_uint number)
2420 {
2421     ilmErrorTypes returnValue = ILM_FAILED;
2422     struct ilm_control_context *ctx = sync_and_acquire_instance();
2423     struct screen_context *ctx_scrn = NULL;
2424
2425     ctx_scrn = get_screen_context_by_id(&ctx->wl, (uint32_t)display);
2426     if (ctx_scrn != NULL) {
2427         struct wl_array ids;
2428         wl_array_init(&ids);
2429         uint32_t *pids = wl_array_add(&ids, number * sizeof *pids);
2430         t_ilm_uint i;
2431         for (i = 0; i < number; i++) pids[i] = (uint32_t)pLayerId[i];
2432         ivi_controller_screen_set_render_order(ctx_scrn->controller, &ids);
2433         wl_array_release(&ids);
2434         returnValue = ILM_SUCCESS;
2435     }
2436
2437     release_instance();
2438     return returnValue;
2439 }
2440
2441 ILM_EXPORT ilmErrorTypes
2442 ilm_takeScreenshot(t_ilm_uint screen, t_ilm_const_string filename)
2443 {
2444     ilmErrorTypes returnValue = ILM_FAILED;
2445     struct ilm_control_context *ctx = sync_and_acquire_instance();
2446     struct screen_context *ctx_scrn = NULL;
2447
2448     ctx_scrn = get_screen_context_by_id(&ctx->wl, (uint32_t)screen);
2449     if (ctx_scrn != NULL) {
2450         ivi_controller_screen_screenshot(ctx_scrn->controller,
2451                                         filename);
2452         wl_display_flush(ctx->wl.display);
2453         returnValue = ILM_SUCCESS;
2454     }
2455
2456     release_instance();
2457     return returnValue;
2458 }
2459
2460 ILM_EXPORT ilmErrorTypes
2461 ilm_takeLayerScreenshot(t_ilm_const_string filename, t_ilm_layer layerid)
2462 {
2463     ilmErrorTypes returnValue = ILM_FAILED;
2464     struct ilm_control_context *ctx = sync_and_acquire_instance();
2465     struct layer_context *ctx_layer = NULL;
2466
2467     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2468                     &ctx->wl, (uint32_t)layerid);
2469     if (ctx_layer != NULL) {
2470         ivi_controller_layer_screenshot(ctx_layer->controller,
2471                                         filename);
2472         wl_display_flush(ctx->wl.display);
2473         returnValue = ILM_SUCCESS;
2474     }
2475
2476     release_instance();
2477     return returnValue;
2478 }
2479
2480 ILM_EXPORT ilmErrorTypes
2481 ilm_takeSurfaceScreenshot(t_ilm_const_string filename,
2482                               t_ilm_surface surfaceid)
2483 {
2484     ilmErrorTypes returnValue = ILM_FAILED;
2485     struct ilm_control_context *ctx = sync_and_acquire_instance();
2486     struct surface_context *ctx_surf = NULL;
2487
2488     ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceid);
2489     if (ctx_surf) {
2490         ivi_controller_surface_screenshot(ctx_surf->controller,
2491                                           filename);
2492         wl_display_flush(ctx->wl.display);
2493         returnValue = ILM_SUCCESS;
2494     }
2495
2496     release_instance();
2497     return returnValue;
2498 }
2499
2500 ILM_EXPORT ilmErrorTypes
2501 ilm_SetOptimizationMode(ilmOptimization id, ilmOptimizationMode mode)
2502 {
2503     (void)id;
2504     (void)mode;
2505     /* Not supported */
2506     return ILM_FAILED;
2507 }
2508
2509 ILM_EXPORT ilmErrorTypes
2510 ilm_GetOptimizationMode(ilmOptimization id, ilmOptimizationMode* pMode)
2511 {
2512     (void)id;
2513     (void)pMode;
2514     /* Not supported */
2515     return ILM_FAILED;
2516 }
2517
2518 ILM_EXPORT ilmErrorTypes
2519 ilm_layerAddNotification(t_ilm_layer layer,
2520                              layerNotificationFunc callback)
2521 {
2522     ilmErrorTypes returnValue = ILM_FAILED;
2523     struct ilm_control_context *ctx = sync_and_acquire_instance();
2524     struct layer_context *ctx_layer = NULL;
2525
2526     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2527                     &ctx->wl, (uint32_t)layer);
2528     if (ctx_layer == NULL) {
2529         returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2530     } else {
2531         ctx_layer->notification = callback;
2532
2533         returnValue = ILM_SUCCESS;
2534     }
2535
2536     release_instance();
2537     return returnValue;
2538 }
2539
2540 ILM_EXPORT ilmErrorTypes
2541 ilm_layerRemoveNotification(t_ilm_layer layer)
2542 {
2543    return ilm_layerAddNotification(layer, NULL);
2544 }
2545
2546 ILM_EXPORT ilmErrorTypes
2547 ilm_surfaceAddNotification(t_ilm_surface surface,
2548                              surfaceNotificationFunc callback)
2549 {
2550     ilmErrorTypes returnValue = ILM_FAILED;
2551     struct ilm_control_context *ctx = sync_and_acquire_instance();
2552     struct surface_context *ctx_surf = NULL;
2553
2554     ctx_surf = (struct surface_context*)get_surface_context(
2555                     &ctx->wl, (uint32_t)surface);
2556     if (ctx_surf == NULL) {
2557         if (callback != NULL) {
2558             callback((uint32_t)surface, NULL, ILM_NOTIFICATION_CONTENT_REMOVED);
2559             controller_listener_surface(ctx, ctx->wl.controller, (uint32_t)surface, 0, NULL);
2560             ctx_surf = (struct surface_context*)get_surface_context(
2561                         &ctx->wl, (uint32_t)surface);
2562             ctx_surf->is_surface_creation_noticed = false;
2563         }
2564     }
2565
2566     if (ctx_surf == NULL) {
2567         returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2568     }
2569     else {
2570         ctx_surf->notification = callback;
2571
2572         returnValue = ILM_SUCCESS;
2573     }
2574
2575     release_instance();
2576     return returnValue;
2577 }
2578
2579 ILM_EXPORT ilmErrorTypes
2580 ilm_surfaceRemoveNotification(t_ilm_surface surface)
2581 {
2582     return ilm_surfaceAddNotification(surface, NULL);
2583 }
2584
2585 ILM_EXPORT ilmErrorTypes
2586 ilm_getNativeHandle(t_ilm_uint pid, t_ilm_int *n_handle,
2587                         t_ilm_nativehandle **p_handles)
2588 {
2589     struct ilm_control_context *ctx = sync_and_acquire_instance();
2590     struct nativehandle_context *p_nh_ctx = NULL;
2591
2592     *n_handle = 0;
2593     *p_handles = NULL;
2594
2595     wl_list_for_each(p_nh_ctx, &ctx->list_nativehandle, link)
2596     {
2597         if (p_nh_ctx->pid == pid)
2598         {
2599             *n_handle = 1;
2600             *p_handles =
2601                  (t_ilm_nativehandle*)malloc(sizeof(t_ilm_nativehandle));
2602             (*p_handles)[0] = p_nh_ctx->nativehandle;
2603             break;
2604         }
2605     }
2606
2607     release_instance();
2608     return (*n_handle > 0) ? ILM_SUCCESS : ILM_FAILED;
2609 }
2610
2611 ILM_EXPORT ilmErrorTypes
2612 ilm_getPropertiesOfSurface(t_ilm_uint surfaceID,
2613                         struct ilmSurfaceProperties* pSurfaceProperties)
2614 {
2615     ilmErrorTypes returnValue = ILM_FAILED;
2616     struct ilm_control_context *ctx = sync_and_acquire_instance();
2617
2618     if (pSurfaceProperties != NULL) {
2619         struct surface_context *ctx_surf = NULL;
2620
2621         ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceID);
2622         if (ctx_surf != NULL) {
2623             // request statistics for surface
2624             ivi_controller_surface_send_stats(ctx_surf->controller);
2625             // force submission
2626             int ret = display_roundtrip_queue(ctx->wl.display, ctx->wl.queue);
2627
2628             // If we got an error here, there is really no sense
2629             // in returning the properties as something is fundamentally
2630             // broken.
2631             if (ret != -1)
2632             {
2633                *pSurfaceProperties = ctx_surf->prop;
2634                returnValue = ILM_SUCCESS;
2635             }
2636         }
2637     }
2638
2639     release_instance();
2640     return returnValue;
2641 }
2642
2643 ILM_EXPORT ilmErrorTypes
2644 ilm_layerAddSurface(t_ilm_layer layerId,
2645                         t_ilm_surface surfaceId)
2646 {
2647     ilmErrorTypes returnValue = ILM_FAILED;
2648     struct ilm_control_context *ctx = sync_and_acquire_instance();
2649     struct layer_context *ctx_layer = NULL;
2650     struct surface_context *ctx_surf = NULL;
2651
2652     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2653                     &ctx->wl, (uint32_t)layerId);
2654     ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2655     if ((ctx_layer != NULL) && (ctx_surf != NULL)) {
2656         ivi_controller_layer_add_surface(ctx_layer->controller,
2657                                          ctx_surf->controller);
2658         returnValue = ILM_SUCCESS;
2659     }
2660
2661     release_instance();
2662     return returnValue;
2663 }
2664
2665 ILM_EXPORT ilmErrorTypes
2666 ilm_layerRemoveSurface(t_ilm_layer layerId,
2667                            t_ilm_surface surfaceId)
2668 {
2669     ilmErrorTypes returnValue = ILM_FAILED;
2670     struct ilm_control_context *ctx = sync_and_acquire_instance();
2671     struct layer_context *ctx_layer = NULL;
2672     struct surface_context *ctx_surf = NULL;
2673
2674     ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2675                     &ctx->wl, (uint32_t)layerId);
2676     ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2677     if ((ctx_layer != NULL) && (ctx_surf != NULL)) {
2678         ivi_controller_layer_remove_surface(ctx_layer->controller,
2679                                             ctx_surf->controller);
2680         returnValue = ILM_SUCCESS;
2681     }
2682
2683     release_instance();
2684     return returnValue;
2685 }
2686
2687 ILM_EXPORT ilmErrorTypes
2688 ilm_surfaceGetDimension(t_ilm_surface surfaceId,
2689                             t_ilm_uint *pDimension)
2690 {
2691     ilmErrorTypes returnValue = ILM_FAILED;
2692     struct ilm_control_context *ctx = sync_and_acquire_instance();
2693
2694     if (pDimension != NULL) {
2695         struct surface_context *ctx_surf = NULL;
2696
2697         ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2698         if (ctx_surf != NULL) {
2699             *pDimension = (t_ilm_uint)ctx_surf->prop.destWidth;
2700             *(pDimension + 1) = (t_ilm_uint)ctx_surf->prop.destHeight;
2701             returnValue = ILM_SUCCESS;
2702         }
2703     }
2704
2705     release_instance();
2706     return returnValue;
2707 }
2708
2709 ILM_EXPORT ilmErrorTypes
2710 ilm_surfaceGetVisibility(t_ilm_surface surfaceId,
2711                              t_ilm_bool *pVisibility)
2712 {
2713     ilmErrorTypes returnValue = ILM_FAILED;
2714     struct ilm_control_context *ctx = sync_and_acquire_instance();
2715     struct surface_context *ctx_surf = NULL;
2716
2717     if (pVisibility != NULL) {
2718         ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2719         if (ctx_surf != NULL) {
2720             *pVisibility = (t_ilm_bool)ctx_surf->prop.visibility;
2721             returnValue = ILM_SUCCESS;
2722         }
2723     }
2724
2725     release_instance();
2726     return returnValue;
2727 }
2728
2729 ILM_EXPORT ilmErrorTypes
2730 ilm_surfaceSetSourceRectangle(t_ilm_surface surfaceId,
2731                                   t_ilm_int x, t_ilm_int y,
2732                                   t_ilm_int width, t_ilm_int height)
2733 {
2734     ilmErrorTypes returnValue = ILM_FAILED;
2735     struct ilm_control_context *ctx = sync_and_acquire_instance();
2736     struct surface_context *ctx_surf = NULL;
2737
2738     ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2739     if (ctx_surf != NULL) {
2740         if (ctx_surf->controller != NULL) {
2741             ivi_controller_surface_set_source_rectangle(
2742                     ctx_surf->controller,
2743                     x, y, width, height);
2744             returnValue = ILM_SUCCESS;
2745         }
2746     }
2747
2748     release_instance();
2749     return returnValue;
2750 }
2751
2752 ILM_EXPORT ilmErrorTypes
2753 ilm_commitChanges(void)
2754 {
2755     ilmErrorTypes returnValue = ILM_FAILED;
2756     struct ilm_control_context *ctx = sync_and_acquire_instance();
2757
2758     if (ctx->wl.controller != NULL) {
2759         ivi_controller_commit_changes(ctx->wl.controller);
2760
2761         if (display_roundtrip_queue(ctx->wl.display, ctx->wl.queue) != -1)
2762         {
2763             returnValue = ILM_SUCCESS;
2764         }
2765     }
2766
2767     release_instance();
2768
2769     return returnValue;
2770 }