1 /**************************************************************************
3 * Copyright (C) 2013 DENSO CORPORATION
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ****************************************************************************/
30 #include <sys/eventfd.h>
32 #include "ilm_common.h"
33 #include "ilm_control_platform.h"
34 #include "wayland-util.h"
35 #include "ivi-controller-client-protocol.h"
38 #if defined(__GNUC__) && __GNUC__ >= 4
39 #define ILM_EXPORT __attribute__ ((visibility("default")))
44 struct surface_context {
47 struct ivi_surface *surface;
48 struct ivi_controller_surface *controller;
50 t_ilm_uint id_surface;
51 struct ilmSurfaceProperties prop;
52 surfaceNotificationFunc notification;
58 struct wayland_context *ctx;
61 struct layer_context {
64 struct ivi_controller_layer *controller;
67 struct ilmLayerProperties prop;
68 layerNotificationFunc notification;
71 struct wl_list list_surface;
75 struct wayland_context *ctx;
78 struct screen_context {
81 struct wl_output *output;
82 struct ivi_controller_screen *controller;
83 t_ilm_uint id_from_server;
86 struct ilmScreenProperties prop;
89 struct wl_list list_layer;
92 struct ilm_control_context *ctx;
95 struct nativehandle_context {
97 uint32_t nativehandle;
101 struct wayland_context {
102 struct wl_display *display;
103 struct wl_registry *registry;
104 struct wl_event_queue *queue;
105 struct wl_compositor *compositor;
106 struct ivi_controller *controller;
109 struct wl_list list_surface;
110 struct wl_list list_layer;
111 struct wl_list list_screen;
114 struct ilm_control_context {
115 struct wayland_context wl;
118 uint32_t internal_id_layer;
120 struct wl_list list_nativehandle;
123 pthread_mutex_t mutex;
125 uint32_t internal_id_surface;
128 static void roundtrip_done(void *data, struct wl_callback *callback,
137 static struct wl_callback_listener roundtrip_listener = {roundtrip_done};
139 int display_roundtrip_queue(struct wl_display *display,
140 struct wl_event_queue *queue)
144 struct wl_callback *callback = wl_display_sync(display);
145 wl_proxy_set_queue((void *)callback, queue);
146 wl_callback_add_listener(callback, &roundtrip_listener, &done);
148 while (ret != -1 && !done)
150 ret = wl_display_dispatch_queue(display, queue);
153 wl_callback_destroy(callback);
158 static inline void lock_context(struct ilm_control_context *ctx)
160 pthread_mutex_lock(&ctx->mutex);
163 static inline void unlock_context(struct ilm_control_context *ctx)
165 pthread_mutex_unlock(&ctx->mutex);
168 static int init_control(void);
170 static struct ilm_control_context* sync_and_acquire_instance(void);
172 static void release_instance(void);
174 static int create_controller_layer(struct wayland_context *ctx, t_ilm_uint width, t_ilm_uint height, t_ilm_layer layerid);
177 wayland_controller_is_inside_surface_list(struct wl_list *list,
180 struct surface_context *ctx_surf = NULL;
181 wl_list_for_each(ctx_surf, list, link) {
182 if (ctx_surf->id_surface == id_surface) {
191 wayland_controller_is_inside_layer_list(struct wl_list *list,
194 struct layer_context *ctx_layer = NULL;
195 wl_list_for_each(ctx_layer, list, link) {
196 if (ctx_layer->id_layer == id_layer) {
204 static struct layer_context*
205 wayland_controller_get_layer_context(struct wayland_context *ctx,
208 struct layer_context *ctx_layer = NULL;
210 if (ctx->controller == NULL) {
211 fprintf(stderr, "controller is not initialized in ilmControl\n");
215 wl_list_for_each(ctx_layer, &ctx->list_layer, link) {
216 if (ctx_layer->id_layer == id_layer) {
221 fprintf(stderr, "failed to get layer context in ilmControl\n");
226 output_listener_geometry(void *data,
227 struct wl_output *output,
230 int32_t physical_width,
231 int32_t physical_height,
247 output_listener_mode(void *data,
248 struct wl_output *output,
261 if (flags & WL_OUTPUT_MODE_CURRENT)
263 struct screen_context *ctx_scrn = data;
264 ctx_scrn->prop.screenWidth = width;
265 ctx_scrn->prop.screenHeight = height;
270 output_listener_done(void *data,
271 struct wl_output *output)
278 output_listener_scale(void *data,
279 struct wl_output *output,
287 static struct wl_output_listener output_listener = {
288 output_listener_geometry,
289 output_listener_mode,
290 output_listener_done,
291 output_listener_scale
294 static struct screen_context*
295 get_screen_context_by_output(struct wayland_context *ctx,
296 struct wl_output *output)
298 struct screen_context *ctx_scrn = NULL;
299 struct wl_proxy *pxy_out = NULL;
300 struct wl_proxy *pxy_out_in_scrn = NULL;
302 uint32_t pxy_id_in_scrn = 0;
304 wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
305 pxy_out = (struct wl_proxy*)output;
306 pxy_out_in_scrn = (struct wl_proxy*)ctx_scrn->output;
307 pxy_id = wl_proxy_get_id(pxy_out);
308 pxy_id_in_scrn = wl_proxy_get_id(pxy_out_in_scrn);
309 if (pxy_id == pxy_id_in_scrn) {
316 static struct screen_context*
317 get_screen_context_by_serverid(struct wayland_context *ctx,
320 struct screen_context *ctx_scrn = NULL;
322 wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
323 if (ctx_scrn->id_from_server == id_screen) {
331 add_orderlayer_to_screen(struct layer_context *ctx_layer,
332 struct wl_output* output)
334 struct screen_context *ctx_scrn = NULL;
336 ctx_scrn = get_screen_context_by_output(ctx_layer->ctx, output);
337 if (ctx_scrn == NULL) {
338 fprintf(stderr, "failed to add_orderlayer_to_screen\n");
343 struct layer_context *layer_link;
344 wl_list_for_each(layer_link, &ctx_scrn->order.list_layer, order.link) {
345 if (layer_link == ctx_layer) {
352 wl_list_init(&ctx_layer->order.link);
353 wl_list_insert(&ctx_scrn->order.list_layer, &ctx_layer->order.link);
358 remove_orderlayer_from_screen(struct layer_context *ctx_layer)
360 wl_list_remove(&ctx_layer->order.link);
361 wl_list_init(&ctx_layer->order.link);
365 controller_layer_listener_visibility(void *data,
366 struct ivi_controller_layer *controller,
369 struct layer_context *ctx_layer = data;
371 ctx_layer->prop.visibility = (t_ilm_bool)visibility;
373 if (ctx_layer->notification != NULL) {
374 ctx_layer->notification(ctx_layer->id_layer,
376 ILM_NOTIFICATION_VISIBILITY);
381 controller_layer_listener_opacity(void *data,
382 struct ivi_controller_layer *controller,
385 struct layer_context *ctx_layer = data;
387 ctx_layer->prop.opacity = (t_ilm_float)wl_fixed_to_double(opacity);
389 if (ctx_layer->notification != NULL) {
390 ctx_layer->notification(ctx_layer->id_layer,
392 ILM_NOTIFICATION_OPACITY);
397 controller_layer_listener_source_rectangle(void *data,
398 struct ivi_controller_layer *controller,
404 struct layer_context *ctx_layer = data;
406 ctx_layer->prop.sourceX = (t_ilm_uint)x;
407 ctx_layer->prop.sourceY = (t_ilm_uint)y;
408 ctx_layer->prop.sourceWidth = (t_ilm_uint)width;
409 ctx_layer->prop.sourceHeight = (t_ilm_uint)height;
410 if (ctx_layer->prop.origSourceWidth == 0) {
411 ctx_layer->prop.origSourceWidth = (t_ilm_uint)width;
413 if (ctx_layer->prop.origSourceHeight == 0) {
414 ctx_layer->prop.origSourceHeight = (t_ilm_uint)height;
417 if (ctx_layer->notification != NULL) {
418 ctx_layer->notification(ctx_layer->id_layer,
420 ILM_NOTIFICATION_SOURCE_RECT);
425 controller_layer_listener_destination_rectangle(void *data,
426 struct ivi_controller_layer *controller,
432 struct layer_context *ctx_layer = data;
434 ctx_layer->prop.destX = (t_ilm_uint)x;
435 ctx_layer->prop.destY = (t_ilm_uint)y;
436 ctx_layer->prop.destWidth = (t_ilm_uint)width;
437 ctx_layer->prop.destHeight = (t_ilm_uint)height;
439 if (ctx_layer->notification != NULL) {
440 ctx_layer->notification(ctx_layer->id_layer,
442 ILM_NOTIFICATION_DEST_RECT);
447 controller_layer_listener_configuration(void *data,
448 struct ivi_controller_layer *controller,
452 struct layer_context *ctx_layer = data;
454 ctx_layer->prop.sourceWidth = (t_ilm_uint)width;
455 ctx_layer->prop.sourceHeight = (t_ilm_uint)height;
459 controller_layer_listener_orientation(void *data,
460 struct ivi_controller_layer *controller,
463 ilmOrientation ilmorientation = ILM_ZERO;
464 struct layer_context *ctx_layer = data;
466 switch(orientation) {
467 case IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES:
468 ilmorientation = ILM_ZERO;
470 case IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES:
471 ilmorientation = ILM_NINETY;
473 case IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES:
474 ilmorientation = ILM_ONEHUNDREDEIGHTY;
476 case IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES:
477 ilmorientation = ILM_TWOHUNDREDSEVENTY;
483 ctx_layer->prop.orientation = ilmorientation;
485 if (ctx_layer->notification != NULL) {
486 ctx_layer->notification(ctx_layer->id_layer,
488 ILM_NOTIFICATION_ORIENTATION);
493 controller_layer_listener_screen(void *data,
494 struct ivi_controller_layer *controller,
495 struct wl_output *output)
497 struct layer_context *ctx_layer = data;
499 if (output == NULL) {
500 remove_orderlayer_from_screen(ctx_layer);
502 add_orderlayer_to_screen(ctx_layer, output);
507 controller_layer_listener_destroyed(void *data,
508 struct ivi_controller_layer *controller)
510 struct layer_context *ctx_layer = data;
511 wl_list_remove(&ctx_layer->link);
515 static struct ivi_controller_layer_listener controller_layer_listener =
517 controller_layer_listener_visibility,
518 controller_layer_listener_opacity,
519 controller_layer_listener_source_rectangle,
520 controller_layer_listener_destination_rectangle,
521 controller_layer_listener_configuration,
522 controller_layer_listener_orientation,
523 controller_layer_listener_screen,
524 controller_layer_listener_destroyed
528 add_ordersurface_to_layer(struct surface_context *ctx_surf,
529 struct ivi_controller_layer *layer)
531 struct layer_context *ctx_layer = NULL;
532 struct surface_context *link = NULL;
535 ctx_layer = ivi_controller_layer_get_user_data(layer);
537 wl_list_for_each(link, &ctx_layer->order.list_surface, order.link) {
538 if (link == ctx_surf) {
545 wl_list_init(&ctx_surf->order.link);
546 wl_list_insert(&ctx_layer->order.list_surface, &ctx_surf->order.link);
551 remove_ordersurface_from_layer(struct surface_context *ctx_surf)
553 wl_list_remove(&ctx_surf->order.link);
554 wl_list_init(&ctx_surf->order.link);
558 controller_surface_listener_visibility(void *data,
559 struct ivi_controller_surface *controller,
562 struct surface_context *ctx_surf = data;
564 ctx_surf->prop.visibility = (t_ilm_bool)visibility;
566 if (ctx_surf->notification != NULL) {
567 ctx_surf->notification(ctx_surf->id_surface,
569 ILM_NOTIFICATION_VISIBILITY);
574 controller_surface_listener_opacity(void *data,
575 struct ivi_controller_surface *controller,
578 struct surface_context *ctx_surf = data;
580 ctx_surf->prop.opacity = (t_ilm_float)wl_fixed_to_double(opacity);
582 if (ctx_surf->notification != NULL) {
583 ctx_surf->notification(ctx_surf->id_surface,
585 ILM_NOTIFICATION_OPACITY);
590 controller_surface_listener_configuration(void *data,
591 struct ivi_controller_surface *controller,
595 struct surface_context *ctx_surf = data;
597 ctx_surf->prop.sourceWidth = (t_ilm_uint)width;
598 ctx_surf->prop.sourceHeight = (t_ilm_uint)height;
602 controller_surface_listener_source_rectangle(void *data,
603 struct ivi_controller_surface *controller,
609 struct surface_context *ctx_surf = data;
611 ctx_surf->prop.sourceX = (t_ilm_uint)x;
612 ctx_surf->prop.sourceY = (t_ilm_uint)y;
613 ctx_surf->prop.sourceWidth = (t_ilm_uint)width;
614 ctx_surf->prop.sourceHeight = (t_ilm_uint)height;
615 if (ctx_surf->prop.origSourceWidth == 0) {
616 ctx_surf->prop.origSourceWidth = (t_ilm_uint)width;
618 if (ctx_surf->prop.origSourceHeight == 0) {
619 ctx_surf->prop.origSourceHeight = (t_ilm_uint)height;
622 if (ctx_surf->notification != NULL) {
623 ctx_surf->notification(ctx_surf->id_surface,
625 ILM_NOTIFICATION_SOURCE_RECT);
630 controller_surface_listener_destination_rectangle(void *data,
631 struct ivi_controller_surface *controller,
637 struct surface_context *ctx_surf = data;
639 ctx_surf->prop.destX = (t_ilm_uint)x;
640 ctx_surf->prop.destY = (t_ilm_uint)y;
641 ctx_surf->prop.destWidth = (t_ilm_uint)width;
642 ctx_surf->prop.destHeight = (t_ilm_uint)height;
644 if (ctx_surf->notification != NULL) {
645 ctx_surf->notification(ctx_surf->id_surface,
647 ILM_NOTIFICATION_DEST_RECT);
652 controller_surface_listener_orientation(void *data,
653 struct ivi_controller_surface *controller,
656 struct surface_context *ctx_surf = data;
657 ilmOrientation ilmorientation = ILM_ZERO;
659 switch (orientation) {
660 case IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES:
661 ilmorientation = ILM_ZERO;
663 case IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES:
664 ilmorientation = ILM_NINETY;
666 case IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES:
667 ilmorientation = ILM_ONEHUNDREDEIGHTY;
669 case IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES:
670 ilmorientation = ILM_TWOHUNDREDSEVENTY;
676 ctx_surf->prop.orientation = ilmorientation;
678 if (ctx_surf->notification != NULL) {
679 ctx_surf->notification(ctx_surf->id_surface,
681 ILM_NOTIFICATION_ORIENTATION);
686 controller_surface_listener_pixelformat(void *data,
687 struct ivi_controller_surface *controller,
690 struct surface_context *ctx_surf = data;
692 ctx_surf->prop.pixelformat = (t_ilm_uint)pixelformat;
696 controller_surface_listener_layer(void *data,
697 struct ivi_controller_surface *controller,
698 struct ivi_controller_layer *layer)
700 struct surface_context *ctx_surf = data;
703 remove_ordersurface_from_layer(ctx_surf);
705 add_ordersurface_to_layer(ctx_surf, layer);
710 controller_surface_listener_stats(void *data,
711 struct ivi_controller_surface *controller,
712 uint32_t redraw_count,
713 uint32_t frame_count,
714 uint32_t update_count,
716 const char *process_name)
718 struct surface_context *ctx_surf = data;
721 ctx_surf->prop.drawCounter = (t_ilm_uint)redraw_count;
722 ctx_surf->prop.frameCounter = (t_ilm_uint)frame_count;
723 ctx_surf->prop.updateCounter = (t_ilm_uint)update_count;
724 ctx_surf->prop.creatorPid = (t_ilm_uint)pid;
728 controller_surface_listener_destroyed(void *data,
729 struct ivi_controller_surface *controller)
731 struct surface_context *ctx_surf = data;
733 wl_list_remove(&ctx_surf->link);
738 controller_surface_listener_content(void *data,
739 struct ivi_controller_surface *controller,
740 int32_t content_state)
742 // if client surface (=content) was removed with ilm_surfaceDestroy()
743 // the expected behavior within ILM API mandates a full removal
744 // of the surface from the scene. We must remove the controller
746 if (IVI_CONTROLLER_SURFACE_CONTENT_STATE_CONTENT_REMOVED == content_state)
748 struct surface_context *ctx_surf = data;
750 ivi_controller_surface_destroy(controller, 1);
752 wl_list_remove(&ctx_surf->link);
758 controller_surface_listener_input_focus(void *data,
759 struct ivi_controller_surface *controller,
767 static struct ivi_controller_surface_listener controller_surface_listener=
769 controller_surface_listener_visibility,
770 controller_surface_listener_opacity,
771 controller_surface_listener_source_rectangle,
772 controller_surface_listener_destination_rectangle,
773 controller_surface_listener_configuration,
774 controller_surface_listener_orientation,
775 controller_surface_listener_pixelformat,
776 controller_surface_listener_layer,
777 controller_surface_listener_stats,
778 controller_surface_listener_destroyed,
779 controller_surface_listener_content,
780 controller_surface_listener_input_focus
784 controller_listener_layer(void *data,
785 struct ivi_controller *controller,
788 struct wayland_context *ctx = data;
790 if (wayland_controller_is_inside_layer_list(&ctx->list_layer, id_layer))
795 (void) create_controller_layer(ctx, 0, 0, id_layer);
799 controller_listener_surface(void *data,
800 struct ivi_controller *controller,
803 struct wayland_context *ctx = data;
804 struct surface_context *ctx_surf = NULL;
805 int32_t is_inside = 0;
807 is_inside = wayland_controller_is_inside_surface_list(
808 &ctx->list_surface, id_surface);
810 if (is_inside != 0) {
811 fprintf(stderr, "invalid id_surface in controller_listener_surface\n");
815 ctx_surf = calloc(1, sizeof *ctx_surf);
816 if (ctx_surf == NULL) {
817 fprintf(stderr, "Failed to allocate memory for surface_context\n");
821 ctx_surf->controller = ivi_controller_surface_create(
822 controller, id_surface);
823 if (ctx_surf->controller == NULL) {
825 fprintf(stderr, "Failed to create controller surface\n");
828 ctx_surf->id_surface = id_surface;
829 ctx_surf->prop.inputDevicesAcceptance = ILM_INPUT_DEVICE_ALL;
832 wl_list_init(&ctx_surf->link);
833 wl_list_insert(&ctx->list_surface, &ctx_surf->link);
834 wl_list_init(&ctx_surf->order.link);
835 ivi_controller_surface_add_listener(ctx_surf->controller,
836 &controller_surface_listener, ctx_surf);
840 controller_listener_error(void *data,
841 struct ivi_controller *ivi_controller,
845 const char *error_text)
848 (void)ivi_controller;
856 controller_listener_screen(void *data,
857 struct ivi_controller *ivi_controller,
859 struct ivi_controller_screen *controller_screen)
861 struct wayland_context *ctx = data;
862 struct screen_context *ctx_screen;
863 (void)ivi_controller;
865 ctx_screen = get_screen_context_by_serverid(ctx, id_screen);
866 if (ctx_screen == NULL) {
867 fprintf(stderr, "Failed to allocate memory for screen_context\n");
870 ctx_screen->controller = controller_screen;
873 static struct ivi_controller_listener controller_listener= {
874 controller_listener_screen,
875 controller_listener_layer,
876 controller_listener_surface,
877 controller_listener_error
881 registry_handle_control(void *data,
882 struct wl_registry *registry,
883 uint32_t name, const char *interface,
886 struct wayland_context *ctx = data;
889 if (strcmp(interface, "ivi_controller") == 0) {
890 ctx->controller = wl_registry_bind(registry, name,
891 &ivi_controller_interface, 1);
892 if (ctx->controller == NULL) {
893 fprintf(stderr, "Failed to registry bind ivi_controller\n");
896 if (ivi_controller_add_listener(ctx->controller,
897 &controller_listener,
899 fprintf(stderr, "Failed to add ivi_controller listener\n");
902 } else if (strcmp(interface, "wl_output") == 0) {
904 struct screen_context *ctx_scrn = calloc(1, sizeof *ctx_scrn);
905 struct wl_proxy *pxy = NULL;
907 if (ctx_scrn == NULL) {
908 fprintf(stderr, "Failed to allocate memory for screen_context\n");
911 wl_list_init(&ctx_scrn->link);
912 ctx_scrn->output = wl_registry_bind(registry, name,
913 &wl_output_interface, 1);
914 if (ctx_scrn->output == NULL) {
916 fprintf(stderr, "Failed to registry bind wl_output\n");
920 if (wl_output_add_listener(ctx_scrn->output,
924 fprintf(stderr, "Failed to add wl_output listener\n");
928 pxy = (struct wl_proxy*)ctx_scrn->output;
929 ctx_scrn->id_from_server = wl_proxy_get_id(pxy);
930 ctx_scrn->id_screen = ctx->num_screen;
932 wl_list_init(&ctx_scrn->order.list_layer);
933 wl_list_insert(&ctx->list_screen, &ctx_scrn->link);
937 static const struct wl_registry_listener
938 registry_control_listener= {
939 registry_handle_control,
943 static struct ilm_control_context ilm_context;
945 static void destroy_control_resources(void)
947 struct ilm_control_context *ctx = &ilm_context;
949 if (ctx->wl.controller != NULL) {
951 struct surface_context *l;
952 struct surface_context *n;
953 wl_list_for_each_safe(l, n, &ctx->wl.list_surface, link) {
954 wl_list_remove(&l->link);
955 wl_list_remove(&l->order.link);
956 ivi_controller_surface_destroy(l->controller, 0);
962 struct layer_context *l;
963 struct layer_context *n;
964 wl_list_for_each_safe(l, n, &ctx->wl.list_layer, link) {
965 wl_list_remove(&l->link);
966 wl_list_remove(&l->order.link);
972 struct screen_context *ctx_scrn;
973 struct screen_context *next;
975 wl_list_for_each_safe(ctx_scrn, next, &ctx->wl.list_screen, link) {
976 if (ctx_scrn->output != NULL) {
977 wl_output_destroy(ctx_scrn->output);
980 wl_list_remove(&ctx_scrn->link);
981 ivi_controller_screen_destroy(ctx_scrn->controller);
986 ivi_controller_destroy(ctx->wl.controller);
987 ctx->wl.controller = NULL;
990 wl_display_flush(ctx->wl.display);
992 wl_event_queue_destroy(ctx->wl.queue);
993 ctx->wl.queue = NULL;
995 wl_registry_destroy(ctx->wl.registry);
996 ctx->wl.registry = NULL;
998 if (0 != pthread_mutex_destroy(&ctx->mutex)) {
999 fprintf(stderr, "failed to destroy pthread_mutex\n");
1003 static void send_shutdown_event(struct ilm_control_context *ctx)
1006 while (write(ctx->shutdown_fd, &buf, sizeof buf) == -1 && errno == EINTR)
1011 ilmControl_destroy(void)
1013 struct ilm_control_context *ctx = &ilm_context;
1015 send_shutdown_event(ctx);
1017 if (0 != pthread_join(ctx->thread, NULL)) {
1018 fprintf(stderr, "failed to join control thread\n");
1021 destroy_control_resources();
1023 close(ctx->shutdown_fd);
1025 memset(ctx, 0, sizeof *ctx);
1028 ILM_EXPORT ilmErrorTypes
1029 ilmControl_init(t_ilm_nativedisplay nativedisplay)
1031 struct ilm_control_context *ctx = &ilm_context;
1033 if (ctx->initialized)
1035 fprintf(stderr, "Already initialized!\n");
1039 if (nativedisplay == 0) {
1040 return ILM_ERROR_INVALID_ARGUMENTS;
1043 memset(ctx, 0, sizeof *ctx);
1045 ctx->wl.display = (struct wl_display*)nativedisplay;
1047 wl_list_init(&ctx->wl.list_screen);
1048 wl_list_init(&ctx->wl.list_layer);
1049 wl_list_init(&ctx->wl.list_surface);
1052 pthread_mutexattr_t a;
1053 if (pthread_mutexattr_init(&a) != 0)
1058 if (pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE) != 0)
1060 pthread_mutexattr_destroy(&a);
1064 if (pthread_mutex_init(&ctx->mutex, &a) != 0)
1066 pthread_mutexattr_destroy(&a);
1067 fprintf(stderr, "failed to initialize pthread_mutex\n");
1071 pthread_mutexattr_destroy(&a);
1074 ctx->shutdown_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
1076 if (ctx->shutdown_fd == -1)
1078 fprintf(stderr, "Could not setup shutdown-fd: %s\n", strerror(errno));
1082 return init_control() == 0 ? ILM_SUCCESS : ILM_FAILED;
1086 control_thread(void *p_ret)
1088 struct ilm_control_context *const ctx = &ilm_context;
1089 struct wayland_context *const wl = &ctx->wl;
1090 struct wl_display *const display = wl->display;
1091 struct wl_event_queue *const queue = wl->queue;
1092 int const fd = wl_display_get_fd(display);
1093 int const shutdown_fd = ctx->shutdown_fd;
1098 while (wl_display_prepare_read_queue(display, queue) != 0)
1101 wl_display_dispatch_queue_pending(display, queue);
1102 unlock_context(ctx);
1105 if (wl_display_flush(display) == -1)
1110 struct pollfd pfd[2] = {
1111 { .fd = fd, .events = POLLIN },
1112 { .fd = shutdown_fd, .events = POLLIN }
1115 int pollret = poll(pfd, 2, -1);
1116 if (pollret != -1 && (pfd[0].revents & POLLIN))
1118 wl_display_read_events(display);
1121 int ret = wl_display_dispatch_queue_pending(display, queue);
1122 unlock_context(ctx);
1131 wl_display_cancel_read(display);
1133 if (pollret == -1 || (pfd[1].revents & POLLIN))
1146 struct ilm_control_context *ctx = &ilm_context;
1147 struct wayland_context *wl = &ctx->wl;
1151 wl_list_init(&ctx->list_nativehandle);
1153 wl->queue = wl_display_create_queue(wl->display);
1155 /* registry_add_listener for request by ivi-controller */
1156 wl->registry = wl_display_get_registry(wl->display);
1157 if (wl->registry == NULL) {
1158 wl_event_queue_destroy(wl->queue);
1160 fprintf(stderr, "Failed to get registry\n");
1163 wl_proxy_set_queue((void*)wl->registry, wl->queue);
1165 if (wl_registry_add_listener(wl->registry,
1166 ®istry_control_listener, ctx)) {
1167 fprintf(stderr, "Failed to add registry listener\n");
1171 // first level objects; ivi_controller
1172 display_roundtrip_queue(wl->display, wl->queue);
1173 // second level object: ivi_controller_surfaces/layers
1174 display_roundtrip_queue(wl->display, wl->queue);
1175 // third level objects: ivi_controller_surfaces/layers properties
1176 display_roundtrip_queue(wl->display, wl->queue);
1178 ret = pthread_create(&ctx->thread, NULL, control_thread, NULL);
1181 fprintf(stderr, "Failed to start internal receive thread. returned %d\n", ret);
1185 ctx->initialized = true;
1190 #define sync_and_acquire_instance() ({ \
1191 struct ilm_control_context *ctx = &ilm_context; \
1192 if (! ctx->initialized) { \
1193 fputs("Not initialized\n", stderr); \
1194 return ILM_FAILED; \
1196 lock_context(ctx); \
1197 display_roundtrip_queue(ctx->wl.display, ctx->wl.queue); \
1201 static void release_instance(void)
1203 struct ilm_control_context *ctx = &ilm_context;
1204 unlock_context(ctx);
1208 gen_layer_id(struct ilm_control_context *ctx)
1210 struct layer_context *ctx_layer = NULL;
1213 if (wl_list_length(&ctx->wl.list_layer) == 0) {
1214 ctx->internal_id_layer++;
1215 return ctx->internal_id_layer;
1217 wl_list_for_each(ctx_layer, &ctx->wl.list_layer, link) {
1218 if (ctx_layer->id_layer == ctx->internal_id_layer) {
1224 return ctx->internal_id_layer;
1227 ctx->internal_id_layer++;
1231 static struct surface_context*
1232 get_surface_context(struct wayland_context *ctx,
1233 uint32_t id_surface)
1235 struct surface_context *ctx_surf = NULL;
1237 if (ctx->controller == NULL) {
1238 fprintf(stderr, "controller is not initialized in ilmControl\n");
1242 wl_list_for_each(ctx_surf, &ctx->list_surface, link) {
1243 if (ctx_surf->id_surface == id_surface) {
1248 fprintf(stderr, "failed to get surface context in ilmControl\n");
1252 static struct screen_context*
1253 get_screen_context_by_id(struct wayland_context *ctx, uint32_t id_screen)
1255 struct screen_context *ctx_scrn = NULL;
1257 if (ctx->controller == NULL) {
1258 fprintf(stderr, "get_screen_context_by_id: controller is NULL\n");
1262 wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
1263 if (ctx_scrn->id_screen == id_screen) {
1270 ILM_EXPORT ilmErrorTypes
1271 ilm_getPropertiesOfLayer(t_ilm_uint layerID,
1272 struct ilmLayerProperties* pLayerProperties)
1274 ilmErrorTypes returnValue = ILM_FAILED;
1275 struct ilm_control_context *ctx = sync_and_acquire_instance();
1276 struct layer_context *ctx_layer = NULL;
1278 if (pLayerProperties != NULL) {
1280 ctx_layer = (struct layer_context*)
1281 wayland_controller_get_layer_context(
1282 &ctx->wl, (uint32_t)layerID);
1284 if (ctx_layer != NULL) {
1285 *pLayerProperties = ctx_layer->prop;
1286 returnValue = ILM_SUCCESS;
1295 create_layerids(struct screen_context *ctx_screen,
1296 t_ilm_layer **layer_ids, t_ilm_uint *layer_count)
1298 struct layer_context *ctx_layer = NULL;
1299 t_ilm_layer *ids = NULL;
1301 *layer_count = wl_list_length(&ctx_screen->order.list_layer);
1302 if (*layer_count == 0) {
1307 *layer_ids = malloc(*layer_count * sizeof(t_ilm_layer));
1308 if (*layer_ids == NULL) {
1309 fprintf(stderr, "memory insufficient for layerids\n");
1315 wl_list_for_each_reverse(ctx_layer, &ctx_screen->order.list_layer, order.link) {
1316 *ids = (t_ilm_layer)ctx_layer->id_layer;
1321 ILM_EXPORT ilmErrorTypes
1322 ilm_getPropertiesOfScreen(t_ilm_display screenID,
1323 struct ilmScreenProperties* pScreenProperties)
1325 ilmErrorTypes returnValue = ILM_FAILED;
1327 if (! pScreenProperties)
1329 return ILM_ERROR_INVALID_ARGUMENTS;
1332 struct ilm_control_context *ctx = sync_and_acquire_instance();
1334 struct screen_context *ctx_screen = NULL;
1335 ctx_screen = get_screen_context_by_id(&ctx->wl, (uint32_t)screenID);
1336 if (ctx_screen != NULL) {
1337 *pScreenProperties = ctx_screen->prop;
1338 create_layerids(ctx_screen, &pScreenProperties->layerIds,
1339 &pScreenProperties->layerCount);
1340 returnValue = ILM_SUCCESS;
1347 ILM_EXPORT ilmErrorTypes
1348 ilm_getNumberOfHardwareLayers(t_ilm_uint screenID,
1349 t_ilm_uint* pNumberOfHardwareLayers)
1353 if (pNumberOfHardwareLayers != NULL) {
1354 *pNumberOfHardwareLayers = 0;
1361 ILM_EXPORT ilmErrorTypes
1362 ilm_getScreenIDs(t_ilm_uint* pNumberOfIDs, t_ilm_uint** ppIDs)
1364 ilmErrorTypes returnValue = ILM_FAILED;
1365 struct ilm_control_context *ctx = sync_and_acquire_instance();
1367 if ((pNumberOfIDs != NULL) && (ppIDs != NULL)) {
1368 struct screen_context *ctx_scrn = NULL;
1369 t_ilm_uint length = wl_list_length(&ctx->wl.list_screen);
1372 *ppIDs = (t_ilm_uint*)malloc(length * sizeof **ppIDs);
1373 if (*ppIDs != NULL) {
1374 t_ilm_uint* ids = *ppIDs;
1375 wl_list_for_each(ctx_scrn, &ctx->wl.list_screen, link) {
1376 *ids = ctx_scrn->id_screen;
1379 *pNumberOfIDs = length;
1381 returnValue = ILM_SUCCESS;
1389 ILM_EXPORT ilmErrorTypes
1390 ilm_getLayerIDs(t_ilm_int* pLength, t_ilm_layer** ppArray)
1392 ilmErrorTypes returnValue = ILM_FAILED;
1393 struct ilm_control_context *ctx = sync_and_acquire_instance();
1395 if ((pLength != NULL) && (ppArray != NULL)) {
1396 struct layer_context *ctx_layer = NULL;
1397 t_ilm_uint length = wl_list_length(&ctx->wl.list_layer);
1400 *ppArray = (t_ilm_layer*)malloc(length * sizeof **ppArray);
1401 if (*ppArray != NULL) {
1402 // compositor sends layers in opposite order
1403 // write ids from back to front to turn them around
1404 t_ilm_layer* ids = *ppArray;
1405 wl_list_for_each_reverse(ctx_layer, &ctx->wl.list_layer, link)
1407 *ids = ctx_layer->id_layer;
1412 returnValue = ILM_SUCCESS;
1420 ILM_EXPORT ilmErrorTypes
1421 ilm_getLayerIDsOnScreen(t_ilm_uint screenId,
1423 t_ilm_layer** ppArray)
1425 ilmErrorTypes returnValue = ILM_FAILED;
1426 struct ilm_control_context *ctx = sync_and_acquire_instance();
1428 if ((pLength != NULL) && (ppArray != NULL)) {
1429 struct screen_context *ctx_screen = NULL;
1430 ctx_screen = get_screen_context_by_id(&ctx->wl, screenId);
1431 if (ctx_screen != NULL) {
1432 struct layer_context *ctx_layer = NULL;
1433 t_ilm_int length = wl_list_length(&ctx_screen->order.list_layer);
1437 *ppArray = (t_ilm_layer*)malloc(length * sizeof **ppArray);
1438 if (*ppArray != NULL) {
1439 // compositor sends layers in opposite order
1440 // write ids from back to front to turn them around
1441 t_ilm_layer* ids = *ppArray;
1442 wl_list_for_each_reverse(ctx_layer, &ctx_screen->order.list_layer, order.link)
1444 *ids = ctx_layer->id_layer;
1456 returnValue = ILM_SUCCESS;
1464 ILM_EXPORT ilmErrorTypes
1465 ilm_getSurfaceIDs(t_ilm_int* pLength, t_ilm_surface** ppArray)
1467 ilmErrorTypes returnValue = ILM_FAILED;
1468 struct ilm_control_context *ctx = sync_and_acquire_instance();
1470 if ((pLength != NULL) && (ppArray != NULL)) {
1471 struct surface_context *ctx_surf = NULL;
1472 t_ilm_uint length = wl_list_length(&ctx->wl.list_surface);
1475 *ppArray = (t_ilm_surface*)malloc(length * sizeof **ppArray);
1476 if (*ppArray != NULL) {
1477 t_ilm_surface* ids = *ppArray;
1478 wl_list_for_each_reverse(ctx_surf, &ctx->wl.list_surface, link) {
1479 *ids = ctx_surf->id_surface;
1484 returnValue = ILM_SUCCESS;
1492 ILM_EXPORT ilmErrorTypes
1493 ilm_getSurfaceIDsOnLayer(t_ilm_layer layer,
1495 t_ilm_surface** ppArray)
1497 struct ilm_control_context *ctx = sync_and_acquire_instance();
1498 struct layer_context *ctx_layer = NULL;
1499 struct surface_context *ctx_surf = NULL;
1500 t_ilm_uint length = 0;
1501 t_ilm_surface* ids = NULL;
1503 if ((pLength == NULL) || (ppArray == NULL)) {
1508 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1509 &ctx->wl, (uint32_t)layer);
1511 if (ctx_layer == NULL) {
1516 length = wl_list_length(&ctx_layer->order.list_surface);
1517 *ppArray = (t_ilm_surface*)malloc(length * sizeof **ppArray);
1518 if (*ppArray == NULL) {
1524 wl_list_for_each_reverse(ctx_surf, &ctx_layer->order.list_surface, order.link) {
1525 *ids = (t_ilm_surface)ctx_surf->id_surface;
1534 static int create_controller_layer(struct wayland_context *ctx, t_ilm_uint width, t_ilm_uint height, t_ilm_layer layerid)
1536 struct layer_context *ctx_layer = calloc(1, sizeof *ctx_layer);
1537 if (ctx_layer == NULL) {
1538 fprintf(stderr, "Failed to allocate memory for layer_context\n");
1542 ctx_layer->controller = ivi_controller_layer_create(
1544 layerid, width, height);
1545 if (ctx_layer->controller == NULL) {
1546 fprintf(stderr, "Failed to create layer\n");
1550 ctx_layer->id_layer = layerid;
1551 ctx_layer->ctx = ctx;
1553 wl_list_init(&ctx_layer->link);
1554 wl_list_insert(&ctx->list_layer, &ctx_layer->link);
1555 wl_list_init(&ctx_layer->order.link);
1556 wl_list_init(&ctx_layer->order.list_surface);
1558 ivi_controller_layer_add_listener(ctx_layer->controller,
1559 &controller_layer_listener, ctx_layer);
1564 ILM_EXPORT ilmErrorTypes
1565 ilm_layerCreateWithDimension(t_ilm_layer* pLayerId,
1569 ilmErrorTypes returnValue = ILM_FAILED;
1570 struct ilm_control_context *ctx = sync_and_acquire_instance();
1571 uint32_t layerid = 0;
1572 int32_t is_inside = 0;
1575 if (pLayerId == NULL) {
1579 if (*pLayerId != INVALID_ID) {
1580 /* Return failed, if layerid is already inside list_layer */
1581 is_inside = wayland_controller_is_inside_layer_list(
1582 &ctx->wl.list_layer, *pLayerId);
1583 if (0 != is_inside) {
1584 fprintf(stderr, "layerid=%d is already used.\n", *pLayerId);
1587 layerid = *pLayerId;
1590 /* Generate ID, if layerid is INVALID_ID */
1591 layerid = gen_layer_id(ctx);
1592 *pLayerId = layerid;
1595 if (create_controller_layer(&ctx->wl, width, height, layerid) == 0)
1597 returnValue = ILM_SUCCESS;
1605 ILM_EXPORT ilmErrorTypes
1606 ilm_layerRemove(t_ilm_layer layerId)
1608 ilmErrorTypes returnValue = ILM_FAILED;
1609 struct ilm_control_context *ctx = sync_and_acquire_instance();
1610 struct layer_context *ctx_layer = NULL;
1611 struct layer_context *ctx_next = NULL;
1613 wl_list_for_each_safe(ctx_layer, ctx_next,
1614 &ctx->wl.list_layer, link) {
1615 if (ctx_layer->id_layer == layerId) {
1616 ivi_controller_layer_destroy(ctx_layer->controller, 1);
1618 wl_list_remove(&ctx_layer->link);
1621 returnValue = ILM_SUCCESS;
1630 ILM_EXPORT ilmErrorTypes
1631 ilm_layerGetType(t_ilm_layer layerId, ilmLayerType* pLayerType)
1635 return ILM_ERROR_INVALID_ARGUMENTS;
1638 struct ilm_control_context *ctx = sync_and_acquire_instance();
1640 *pLayerType = wayland_controller_is_inside_layer_list(&ctx->wl.list_layer, layerId) ?
1641 ILM_LAYERTYPE_SOFTWARE2D :
1642 ILM_LAYERTYPE_UNKNOWN;
1645 return ILM_SUCCESS; // even if non existent?
1648 ILM_EXPORT ilmErrorTypes
1649 ilm_layerSetVisibility(t_ilm_layer layerId, t_ilm_bool newVisibility)
1651 ilmErrorTypes returnValue = ILM_FAILED;
1652 struct ilm_control_context *ctx = sync_and_acquire_instance();
1653 struct layer_context *ctx_layer = NULL;
1655 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1656 &ctx->wl, (uint32_t)layerId);
1658 if (ctx_layer != NULL) {
1659 uint32_t visibility = 0;
1660 if (newVisibility == ILM_TRUE) {
1663 ivi_controller_layer_set_visibility(ctx_layer->controller,
1665 returnValue = ILM_SUCCESS;
1672 ILM_EXPORT ilmErrorTypes
1673 ilm_layerGetVisibility(t_ilm_layer layerId, t_ilm_bool *pVisibility)
1675 ilmErrorTypes returnValue = ILM_FAILED;
1676 struct ilm_control_context *ctx = sync_and_acquire_instance();
1678 if (pVisibility != NULL) {
1679 struct layer_context *ctx_layer = NULL;
1681 ctx_layer = (struct layer_context*)
1682 wayland_controller_get_layer_context(
1683 &ctx->wl, (uint32_t)layerId);
1685 if (ctx_layer != NULL) {
1686 *pVisibility = ctx_layer->prop.visibility;
1687 returnValue = ILM_SUCCESS;
1695 ILM_EXPORT ilmErrorTypes
1696 ilm_layerSetOpacity(t_ilm_layer layerId, t_ilm_float opacity)
1698 ilmErrorTypes returnValue = ILM_FAILED;
1699 struct ilm_control_context *ctx = sync_and_acquire_instance();
1700 struct layer_context *ctx_layer = NULL;
1702 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1703 &ctx->wl, (uint32_t)layerId);
1705 if (ctx_layer != NULL) {
1706 wl_fixed_t opacity_fixed = wl_fixed_from_double((double)opacity);
1707 ivi_controller_layer_set_opacity(ctx_layer->controller,
1709 returnValue = ILM_SUCCESS;
1716 ILM_EXPORT ilmErrorTypes
1717 ilm_layerGetOpacity(t_ilm_layer layerId, t_ilm_float *pOpacity)
1719 ilmErrorTypes returnValue = ILM_FAILED;
1720 struct ilm_control_context *ctx = sync_and_acquire_instance();
1722 if (pOpacity != NULL) {
1723 struct layer_context *ctx_layer = NULL;
1725 ctx_layer = (struct layer_context*)
1726 wayland_controller_get_layer_context(
1727 &ctx->wl, (uint32_t)layerId);
1729 if (ctx_layer != NULL) {
1730 *pOpacity = ctx_layer->prop.opacity;
1731 returnValue = ILM_SUCCESS;
1739 ILM_EXPORT ilmErrorTypes
1740 ilm_layerSetSourceRectangle(t_ilm_layer layerId,
1741 t_ilm_uint x, t_ilm_uint y,
1742 t_ilm_uint width, t_ilm_uint height)
1744 ilmErrorTypes returnValue = ILM_FAILED;
1745 struct ilm_control_context *ctx = sync_and_acquire_instance();
1746 struct layer_context *ctx_layer = NULL;
1748 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1749 &ctx->wl, (uint32_t)layerId);
1751 if (ctx_layer != NULL) {
1752 ivi_controller_layer_set_source_rectangle(ctx_layer->controller,
1757 returnValue = ILM_SUCCESS;
1764 ILM_EXPORT ilmErrorTypes
1765 ilm_layerSetDestinationRectangle(t_ilm_layer layerId,
1766 t_ilm_int x, t_ilm_int y,
1767 t_ilm_int width, t_ilm_int height)
1769 ilmErrorTypes returnValue = ILM_FAILED;
1770 struct ilm_control_context *ctx = sync_and_acquire_instance();
1771 struct layer_context *ctx_layer = NULL;
1773 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1774 &ctx->wl, (uint32_t)layerId);
1775 if (ctx_layer != NULL) {
1776 ivi_controller_layer_set_destination_rectangle(
1777 ctx_layer->controller,
1778 (uint32_t)x, (uint32_t)y,
1781 returnValue = ILM_SUCCESS;
1788 ILM_EXPORT ilmErrorTypes
1789 ilm_layerGetDimension(t_ilm_layer layerId, t_ilm_uint *pDimension)
1791 ilmErrorTypes returnValue = ILM_FAILED;
1792 struct ilm_control_context *ctx = sync_and_acquire_instance();
1793 struct layer_context *ctx_layer = NULL;
1795 if (pDimension != NULL) {
1796 ctx_layer = (struct layer_context*)
1797 wayland_controller_get_layer_context(
1798 &ctx->wl, (uint32_t)layerId);
1799 if (ctx_layer != NULL) {
1800 *pDimension = ctx_layer->prop.destWidth;
1801 *(pDimension + 1) = ctx_layer->prop.destHeight;
1802 returnValue = ILM_SUCCESS;
1810 ILM_EXPORT ilmErrorTypes
1811 ilm_layerSetDimension(t_ilm_layer layerId, t_ilm_uint *pDimension)
1813 ilmErrorTypes returnValue = ILM_FAILED;
1814 struct ilm_control_context *ctx = sync_and_acquire_instance();
1815 struct layer_context *ctx_layer = NULL;
1817 if (pDimension != NULL) {
1818 ctx_layer = (struct layer_context*)
1819 wayland_controller_get_layer_context(
1820 &ctx->wl, (uint32_t)layerId);
1821 if (ctx_layer != NULL) {
1822 ivi_controller_layer_set_destination_rectangle(
1823 ctx_layer->controller,
1824 ctx_layer->prop.destX, ctx_layer->prop.destY,
1825 (int32_t)*pDimension, (int32_t)*(pDimension + 1));
1826 returnValue = ILM_SUCCESS;
1834 ILM_EXPORT ilmErrorTypes
1835 ilm_layerGetPosition(t_ilm_layer layerId, t_ilm_uint *pPosition)
1837 ilmErrorTypes returnValue = ILM_FAILED;
1838 struct ilm_control_context *ctx = sync_and_acquire_instance();
1839 struct layer_context *ctx_layer = NULL;
1841 if (pPosition != NULL) {
1842 ctx_layer = (struct layer_context*)
1843 wayland_controller_get_layer_context(
1844 &ctx->wl, (uint32_t)layerId);
1845 if (ctx_layer != NULL) {
1846 *pPosition = ctx_layer->prop.destX;
1847 *(pPosition + 1) = ctx_layer->prop.destY;
1848 returnValue = ILM_SUCCESS;
1856 ILM_EXPORT ilmErrorTypes
1857 ilm_layerSetPosition(t_ilm_layer layerId, t_ilm_uint *pPosition)
1859 ilmErrorTypes returnValue = ILM_FAILED;
1860 struct ilm_control_context *ctx = sync_and_acquire_instance();
1861 struct layer_context *ctx_layer = NULL;
1863 if (pPosition != NULL) {
1864 ctx_layer = (struct layer_context*)
1865 wayland_controller_get_layer_context(
1866 &ctx->wl, (uint32_t)layerId);
1867 if (ctx_layer != NULL) {
1868 ivi_controller_layer_set_destination_rectangle(
1869 ctx_layer->controller,
1870 (int32_t)*pPosition, (int32_t)*(pPosition + 1),
1871 ctx_layer->prop.destWidth, ctx_layer->prop.destHeight);
1872 returnValue = ILM_SUCCESS;
1880 ILM_EXPORT ilmErrorTypes
1881 ilm_layerSetOrientation(t_ilm_layer layerId, ilmOrientation orientation)
1883 ilmErrorTypes returnValue = ILM_FAILED;
1884 struct ilm_control_context *ctx = sync_and_acquire_instance();
1885 struct layer_context *ctx_layer = NULL;
1886 int32_t iviorientation = 0;
1889 switch(orientation) {
1891 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES;
1894 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES;
1896 case ILM_ONEHUNDREDEIGHTY:
1897 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES;
1899 case ILM_TWOHUNDREDSEVENTY:
1900 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES;
1903 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
1907 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1908 &ctx->wl, (uint32_t)layerId);
1909 if (ctx_layer == NULL) {
1910 returnValue = ILM_FAILED;
1914 ivi_controller_layer_set_orientation(ctx_layer->controller,
1917 returnValue = ILM_SUCCESS;
1924 ILM_EXPORT ilmErrorTypes
1925 ilm_layerGetOrientation(t_ilm_layer layerId, ilmOrientation *pOrientation)
1927 ilmErrorTypes returnValue = ILM_FAILED;
1928 struct ilm_control_context *ctx = sync_and_acquire_instance();
1929 struct layer_context *ctx_layer = NULL;
1931 if (pOrientation != NULL) {
1932 ctx_layer = (struct layer_context*)
1933 wayland_controller_get_layer_context(
1934 &ctx->wl, (uint32_t)layerId);
1935 if (ctx_layer != NULL) {
1936 *pOrientation = ctx_layer->prop.orientation;
1937 returnValue = ILM_SUCCESS;
1945 ILM_EXPORT ilmErrorTypes
1946 ilm_layerSetChromaKey(t_ilm_layer layerId, t_ilm_int* pColor)
1954 ILM_EXPORT ilmErrorTypes
1955 ilm_layerSetRenderOrder(t_ilm_layer layerId,
1956 t_ilm_surface *pSurfaceId,
1959 ilmErrorTypes returnValue = ILM_FAILED;
1960 struct ilm_control_context *ctx = sync_and_acquire_instance();
1961 struct layer_context *ctx_layer = NULL;
1963 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1964 &ctx->wl, (uint32_t)layerId);
1968 struct wl_array ids;
1969 wl_array_init(&ids);
1970 uint32_t *pids = wl_array_add(&ids, number * sizeof *pids);
1972 for (i = 0; i < number; i++) pids[i] = (uint32_t)pSurfaceId[i];
1973 ivi_controller_layer_set_render_order(ctx_layer->controller, &ids);
1974 wl_array_release(&ids);
1975 returnValue = ILM_SUCCESS;
1982 ILM_EXPORT ilmErrorTypes
1983 ilm_layerGetCapabilities(t_ilm_layer layerId,
1984 t_ilm_layercapabilities *pCapabilities)
1987 (void)pCapabilities;
1992 ILM_EXPORT ilmErrorTypes
1993 ilm_layerTypeGetCapabilities(ilmLayerType layerType,
1994 t_ilm_layercapabilities *pCapabilities)
1997 (void)pCapabilities;
2002 ILM_EXPORT ilmErrorTypes
2003 ilm_surfaceSetVisibility(t_ilm_surface surfaceId, t_ilm_bool newVisibility)
2005 ilmErrorTypes returnValue = ILM_FAILED;
2006 struct ilm_control_context *ctx = sync_and_acquire_instance();
2007 struct surface_context *ctx_surf = NULL;
2008 uint32_t visibility = 0;
2010 if (newVisibility == ILM_TRUE) {
2013 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2015 ivi_controller_surface_set_visibility(ctx_surf->controller,
2017 returnValue = ILM_SUCCESS;
2024 ILM_EXPORT ilmErrorTypes
2025 ilm_surfaceSetOpacity(t_ilm_surface surfaceId, t_ilm_float opacity)
2027 ilmErrorTypes returnValue = ILM_FAILED;
2028 struct ilm_control_context *ctx = sync_and_acquire_instance();
2029 struct surface_context *ctx_surf = NULL;
2030 wl_fixed_t opacity_fixed = 0;
2032 opacity_fixed = wl_fixed_from_double((double)opacity);
2033 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2035 ivi_controller_surface_set_opacity(ctx_surf->controller,
2037 returnValue = ILM_SUCCESS;
2044 ILM_EXPORT ilmErrorTypes
2045 ilm_surfaceGetOpacity(t_ilm_surface surfaceId, t_ilm_float *pOpacity)
2047 ilmErrorTypes returnValue = ILM_FAILED;
2048 struct ilm_control_context *ctx = sync_and_acquire_instance();
2050 if (pOpacity != NULL) {
2051 struct surface_context *ctx_surf = NULL;
2052 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2054 *pOpacity = ctx_surf->prop.opacity;
2055 returnValue = ILM_SUCCESS;
2063 ILM_EXPORT ilmErrorTypes
2064 ilm_SetKeyboardFocusOn(t_ilm_surface surfaceId)
2066 ilmErrorTypes returnValue = ILM_FAILED;
2068 returnValue = ILM_SUCCESS;
2072 ILM_EXPORT ilmErrorTypes
2073 ilm_GetKeyboardFocusSurfaceId(t_ilm_surface* pSurfaceId)
2075 ilmErrorTypes returnValue = ILM_FAILED;
2077 returnValue = ILM_SUCCESS;
2081 ILM_EXPORT ilmErrorTypes
2082 ilm_surfaceSetDestinationRectangle(t_ilm_surface surfaceId,
2083 t_ilm_int x, t_ilm_int y,
2084 t_ilm_int width, t_ilm_int height)
2086 ilmErrorTypes returnValue = ILM_FAILED;
2087 struct ilm_control_context *ctx = sync_and_acquire_instance();
2088 struct surface_context *ctx_surf = NULL;
2090 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2092 ivi_controller_surface_set_destination_rectangle(
2093 ctx_surf->controller,
2094 x, y, width, height);
2095 returnValue = ILM_SUCCESS;
2102 ILM_EXPORT ilmErrorTypes
2103 ilm_surfaceSetDimension(t_ilm_surface surfaceId, t_ilm_uint *pDimension)
2105 ilmErrorTypes returnValue = ILM_FAILED;
2106 struct ilm_control_context *ctx = sync_and_acquire_instance();
2108 if (pDimension != NULL) {
2109 struct surface_context *ctx_surf = NULL;
2110 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2112 uint32_t width = *pDimension;
2113 uint32_t height = *(pDimension + 1);
2114 ivi_controller_surface_set_destination_rectangle(
2115 ctx_surf->controller,
2116 ctx_surf->prop.destX, ctx_surf->prop.destY, width, height);
2117 returnValue = ILM_SUCCESS;
2125 ILM_EXPORT ilmErrorTypes
2126 ilm_surfaceGetPosition(t_ilm_surface surfaceId, t_ilm_uint *pPosition)
2128 ilmErrorTypes returnValue = ILM_FAILED;
2129 struct ilm_control_context *ctx = sync_and_acquire_instance();
2131 if (pPosition != NULL) {
2132 struct surface_context *ctx_surf = NULL;
2133 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2135 *pPosition = ctx_surf->prop.destX;
2136 *(pPosition + 1) = ctx_surf->prop.destY;
2137 returnValue = ILM_SUCCESS;
2145 ILM_EXPORT ilmErrorTypes
2146 ilm_surfaceSetPosition(t_ilm_surface surfaceId, t_ilm_uint *pPosition)
2148 ilmErrorTypes returnValue = ILM_FAILED;
2149 struct ilm_control_context *ctx = sync_and_acquire_instance();
2151 if (pPosition != NULL) {
2152 struct surface_context *ctx_surf = NULL;
2153 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2155 int32_t destX = (int32_t)*pPosition;
2156 int32_t destY = (int32_t)*(pPosition + 1);
2157 ivi_controller_surface_set_destination_rectangle(
2158 ctx_surf->controller, destX, destY,
2159 ctx_surf->prop.destWidth, ctx_surf->prop.destHeight);
2160 returnValue = ILM_SUCCESS;
2168 ILM_EXPORT ilmErrorTypes
2169 ilm_surfaceSetOrientation(t_ilm_surface surfaceId,
2170 ilmOrientation orientation)
2172 ilmErrorTypes returnValue = ILM_FAILED;
2173 struct ilm_control_context *ctx = sync_and_acquire_instance();
2174 struct surface_context *ctx_surf = NULL;
2175 int32_t iviorientation = 0;
2178 switch(orientation) {
2180 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES;
2183 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES;
2185 case ILM_ONEHUNDREDEIGHTY:
2186 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES;
2188 case ILM_TWOHUNDREDSEVENTY:
2189 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES;
2192 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2196 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2197 if (ctx_surf == NULL) {
2198 returnValue = ILM_FAILED;
2202 ivi_controller_surface_set_orientation(ctx_surf->controller,
2205 returnValue = ILM_SUCCESS;
2212 ILM_EXPORT ilmErrorTypes
2213 ilm_surfaceGetOrientation(t_ilm_surface surfaceId,
2214 ilmOrientation *pOrientation)
2216 ilmErrorTypes returnValue = ILM_FAILED;
2217 struct ilm_control_context *ctx = sync_and_acquire_instance();
2219 if (pOrientation != NULL) {
2220 struct surface_context *ctx_surf = NULL;
2221 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2223 *pOrientation = ctx_surf->prop.orientation;
2224 returnValue = ILM_SUCCESS;
2232 ILM_EXPORT ilmErrorTypes
2233 ilm_surfaceGetPixelformat(t_ilm_layer surfaceId,
2234 ilmPixelFormat *pPixelformat)
2236 ilmErrorTypes returnValue = ILM_FAILED;
2237 struct ilm_control_context *ctx = sync_and_acquire_instance();
2239 if (pPixelformat != NULL) {
2240 struct surface_context *ctx_surf = NULL;
2241 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2243 *pPixelformat = ctx_surf->prop.pixelformat;
2244 returnValue = ILM_SUCCESS;
2252 ILM_EXPORT ilmErrorTypes
2253 ilm_surfaceSetChromaKey(t_ilm_surface surfaceId, t_ilm_int* pColor)
2261 ILM_EXPORT ilmErrorTypes
2262 ilm_displaySetRenderOrder(t_ilm_display display,
2263 t_ilm_layer *pLayerId, const t_ilm_uint number)
2265 ilmErrorTypes returnValue = ILM_FAILED;
2266 struct ilm_control_context *ctx = sync_and_acquire_instance();
2267 struct screen_context *ctx_scrn = NULL;
2269 ctx_scrn = get_screen_context_by_id(&ctx->wl, (uint32_t)display);
2270 if (ctx_scrn != NULL) {
2271 struct wl_array ids;
2272 wl_array_init(&ids);
2273 uint32_t *pids = wl_array_add(&ids, number * sizeof *pids);
2275 for (i = 0; i < number; i++) pids[i] = (uint32_t)pLayerId[i];
2276 ivi_controller_screen_set_render_order(ctx_scrn->controller, &ids);
2277 wl_array_release(&ids);
2278 returnValue = ILM_SUCCESS;
2285 ILM_EXPORT ilmErrorTypes
2286 ilm_takeScreenshot(t_ilm_uint screen, t_ilm_const_string filename)
2288 ilmErrorTypes returnValue = ILM_FAILED;
2289 struct ilm_control_context *ctx = sync_and_acquire_instance();
2290 struct screen_context *ctx_scrn = NULL;
2292 ctx_scrn = get_screen_context_by_id(&ctx->wl, (uint32_t)screen);
2293 if (ctx_scrn != NULL) {
2294 ivi_controller_screen_screenshot(ctx_scrn->controller,
2296 wl_display_flush(ctx->wl.display);
2297 returnValue = ILM_SUCCESS;
2304 ILM_EXPORT ilmErrorTypes
2305 ilm_takeLayerScreenshot(t_ilm_const_string filename, t_ilm_layer layerid)
2307 ilmErrorTypes returnValue = ILM_FAILED;
2308 struct ilm_control_context *ctx = sync_and_acquire_instance();
2309 struct layer_context *ctx_layer = NULL;
2311 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2312 &ctx->wl, (uint32_t)layerid);
2313 if (ctx_layer != NULL) {
2314 ivi_controller_layer_screenshot(ctx_layer->controller,
2316 wl_display_flush(ctx->wl.display);
2317 returnValue = ILM_SUCCESS;
2324 ILM_EXPORT ilmErrorTypes
2325 ilm_takeSurfaceScreenshot(t_ilm_const_string filename,
2326 t_ilm_surface surfaceid)
2328 ilmErrorTypes returnValue = ILM_FAILED;
2329 struct ilm_control_context *ctx = sync_and_acquire_instance();
2330 struct surface_context *ctx_surf = NULL;
2332 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceid);
2334 ivi_controller_surface_screenshot(ctx_surf->controller,
2336 wl_display_flush(ctx->wl.display);
2337 returnValue = ILM_SUCCESS;
2344 ILM_EXPORT ilmErrorTypes
2345 ilm_SetOptimizationMode(ilmOptimization id, ilmOptimizationMode mode)
2353 ILM_EXPORT ilmErrorTypes
2354 ilm_GetOptimizationMode(ilmOptimization id, ilmOptimizationMode* pMode)
2362 ILM_EXPORT ilmErrorTypes
2363 ilm_layerAddNotification(t_ilm_layer layer,
2364 layerNotificationFunc callback)
2366 ilmErrorTypes returnValue = ILM_FAILED;
2367 struct ilm_control_context *ctx = sync_and_acquire_instance();
2368 struct layer_context *ctx_layer = NULL;
2370 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2371 &ctx->wl, (uint32_t)layer);
2372 if (ctx_layer == NULL) {
2373 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2375 ctx_layer->notification = callback;
2377 returnValue = ILM_SUCCESS;
2384 ILM_EXPORT ilmErrorTypes
2385 ilm_layerRemoveNotification(t_ilm_layer layer)
2387 return ilm_layerAddNotification(layer, NULL);
2390 ILM_EXPORT ilmErrorTypes
2391 ilm_surfaceAddNotification(t_ilm_surface surface,
2392 surfaceNotificationFunc callback)
2394 ilmErrorTypes returnValue = ILM_FAILED;
2395 struct ilm_control_context *ctx = sync_and_acquire_instance();
2396 struct surface_context *ctx_surf = NULL;
2398 ctx_surf = (struct surface_context*)get_surface_context(
2399 &ctx->wl, (uint32_t)surface);
2400 if (ctx_surf == NULL) {
2401 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2403 ctx_surf->notification = callback;
2405 returnValue = ILM_SUCCESS;
2412 ILM_EXPORT ilmErrorTypes
2413 ilm_surfaceRemoveNotification(t_ilm_surface surface)
2415 return ilm_surfaceAddNotification(surface, NULL);
2418 ILM_EXPORT ilmErrorTypes
2419 ilm_getNativeHandle(t_ilm_uint pid, t_ilm_int *n_handle,
2420 t_ilm_nativehandle **p_handles)
2422 struct ilm_control_context *ctx = sync_and_acquire_instance();
2423 struct nativehandle_context *p_nh_ctx = NULL;
2428 wl_list_for_each(p_nh_ctx, &ctx->list_nativehandle, link)
2430 if (p_nh_ctx->pid == pid)
2434 (t_ilm_nativehandle*)malloc(sizeof(t_ilm_nativehandle));
2435 (*p_handles)[0] = p_nh_ctx->nativehandle;
2441 return (*n_handle > 0) ? ILM_SUCCESS : ILM_FAILED;
2444 ILM_EXPORT ilmErrorTypes
2445 ilm_getPropertiesOfSurface(t_ilm_uint surfaceID,
2446 struct ilmSurfaceProperties* pSurfaceProperties)
2448 ilmErrorTypes returnValue = ILM_FAILED;
2449 struct ilm_control_context *ctx = sync_and_acquire_instance();
2451 if (pSurfaceProperties != NULL) {
2452 struct surface_context *ctx_surf = NULL;
2454 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceID);
2455 if (ctx_surf != NULL) {
2457 *pSurfaceProperties = ctx_surf->prop;
2458 returnValue = ILM_SUCCESS;
2466 ILM_EXPORT ilmErrorTypes
2467 ilm_layerAddSurface(t_ilm_layer layerId,
2468 t_ilm_surface surfaceId)
2470 ilmErrorTypes returnValue = ILM_FAILED;
2471 struct ilm_control_context *ctx = sync_and_acquire_instance();
2472 struct layer_context *ctx_layer = NULL;
2473 struct surface_context *ctx_surf = NULL;
2475 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2476 &ctx->wl, (uint32_t)layerId);
2477 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2478 if ((ctx_layer != NULL) && (ctx_surf != NULL)) {
2479 ivi_controller_layer_add_surface(ctx_layer->controller,
2480 ctx_surf->controller);
2481 returnValue = ILM_SUCCESS;
2488 ILM_EXPORT ilmErrorTypes
2489 ilm_layerRemoveSurface(t_ilm_layer layerId,
2490 t_ilm_surface surfaceId)
2492 ilmErrorTypes returnValue = ILM_FAILED;
2493 struct ilm_control_context *ctx = sync_and_acquire_instance();
2494 struct layer_context *ctx_layer = NULL;
2495 struct surface_context *ctx_surf = NULL;
2497 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2498 &ctx->wl, (uint32_t)layerId);
2499 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2500 if ((ctx_layer != NULL) && (ctx_surf != NULL)) {
2501 ivi_controller_layer_remove_surface(ctx_layer->controller,
2502 ctx_surf->controller);
2503 returnValue = ILM_SUCCESS;
2510 ILM_EXPORT ilmErrorTypes
2511 ilm_surfaceGetDimension(t_ilm_surface surfaceId,
2512 t_ilm_uint *pDimension)
2514 ilmErrorTypes returnValue = ILM_FAILED;
2515 struct ilm_control_context *ctx = sync_and_acquire_instance();
2517 if (pDimension != NULL) {
2518 struct surface_context *ctx_surf = NULL;
2520 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2521 if (ctx_surf != NULL) {
2522 *pDimension = (t_ilm_uint)ctx_surf->prop.destWidth;
2523 *(pDimension + 1) = (t_ilm_uint)ctx_surf->prop.destHeight;
2524 returnValue = ILM_SUCCESS;
2532 ILM_EXPORT ilmErrorTypes
2533 ilm_surfaceGetVisibility(t_ilm_surface surfaceId,
2534 t_ilm_bool *pVisibility)
2536 ilmErrorTypes returnValue = ILM_FAILED;
2537 struct ilm_control_context *ctx = sync_and_acquire_instance();
2538 struct surface_context *ctx_surf = NULL;
2540 if (pVisibility != NULL) {
2541 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2542 if (ctx_surf != NULL) {
2543 *pVisibility = (t_ilm_bool)ctx_surf->prop.visibility;
2544 returnValue = ILM_SUCCESS;
2552 ILM_EXPORT ilmErrorTypes
2553 ilm_surfaceSetSourceRectangle(t_ilm_surface surfaceId,
2554 t_ilm_int x, t_ilm_int y,
2555 t_ilm_int width, t_ilm_int height)
2557 ilmErrorTypes returnValue = ILM_FAILED;
2558 struct ilm_control_context *ctx = sync_and_acquire_instance();
2559 struct surface_context *ctx_surf = NULL;
2561 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2562 if (ctx_surf != NULL) {
2563 if (ctx_surf->controller != NULL) {
2564 ivi_controller_surface_set_source_rectangle(
2565 ctx_surf->controller,
2566 x, y, width, height);
2567 returnValue = ILM_SUCCESS;
2575 ILM_EXPORT ilmErrorTypes
2576 ilm_commitChanges(void)
2578 ilmErrorTypes returnValue = ILM_FAILED;
2579 struct ilm_control_context *ctx = sync_and_acquire_instance();
2581 if (ctx->wl.controller != NULL) {
2582 ivi_controller_commit_changes(ctx->wl.controller);
2584 if (display_roundtrip_queue(ctx->wl.display, ctx->wl.queue) != -1)
2586 returnValue = ILM_SUCCESS;