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;
59 bool is_surface_creation_noticed;
62 struct layer_context {
65 struct ivi_controller_layer *controller;
68 struct ilmLayerProperties prop;
69 layerNotificationFunc notification;
72 struct wl_list list_surface;
76 struct wayland_context *ctx;
79 struct screen_context {
82 struct wl_output *output;
83 struct ivi_controller_screen *controller;
84 t_ilm_uint id_from_server;
87 struct ilmScreenProperties prop;
90 struct wl_list list_layer;
93 struct ilm_control_context *ctx;
96 struct nativehandle_context {
98 uint32_t nativehandle;
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;
110 struct wl_list list_surface;
111 struct wl_list list_layer;
112 struct wl_list list_screen;
115 struct ilm_control_context {
116 struct wayland_context wl;
119 uint32_t internal_id_layer;
121 struct wl_list list_nativehandle;
124 pthread_mutex_t mutex;
126 uint32_t internal_id_surface;
129 static void roundtrip_done(void *data, struct wl_callback *callback,
138 static struct wl_callback_listener roundtrip_listener = {roundtrip_done};
140 int display_roundtrip_queue(struct wl_display *display,
141 struct wl_event_queue *queue)
145 struct wl_callback *callback = wl_display_sync(display);
146 wl_proxy_set_queue((void *)callback, queue);
147 wl_callback_add_listener(callback, &roundtrip_listener, &done);
149 while (ret != -1 && !done)
151 ret = wl_display_dispatch_queue(display, queue);
154 wl_callback_destroy(callback);
159 static inline void lock_context(struct ilm_control_context *ctx)
161 pthread_mutex_lock(&ctx->mutex);
164 static inline void unlock_context(struct ilm_control_context *ctx)
166 pthread_mutex_unlock(&ctx->mutex);
169 static int init_control(void);
171 static ilmErrorTypes impl_sync_and_acquire_instance(struct ilm_control_context *ctx);
173 static struct surface_context* get_surface_context(struct wayland_context *, uint32_t);
175 static void release_instance(void);
177 static int create_controller_layer(struct wayland_context *ctx, t_ilm_uint width, t_ilm_uint height, t_ilm_layer layerid);
180 wayland_controller_is_inside_surface_list(struct wl_list *list,
183 struct surface_context *ctx_surf = NULL;
184 wl_list_for_each(ctx_surf, list, link) {
185 if (ctx_surf->id_surface == id_surface) {
194 wayland_controller_is_inside_layer_list(struct wl_list *list,
197 struct layer_context *ctx_layer = NULL;
198 wl_list_for_each(ctx_layer, list, link) {
199 if (ctx_layer->id_layer == id_layer) {
207 static struct layer_context*
208 wayland_controller_get_layer_context(struct wayland_context *ctx,
211 struct layer_context *ctx_layer = NULL;
213 if (ctx->controller == NULL) {
214 fprintf(stderr, "controller is not initialized in ilmControl\n");
218 wl_list_for_each(ctx_layer, &ctx->list_layer, link) {
219 if (ctx_layer->id_layer == id_layer) {
224 fprintf(stderr, "failed to get layer context in ilmControl\n");
229 output_listener_geometry(void *data,
230 struct wl_output *output,
233 int32_t physical_width,
234 int32_t physical_height,
250 output_listener_mode(void *data,
251 struct wl_output *output,
264 if (flags & WL_OUTPUT_MODE_CURRENT)
266 struct screen_context *ctx_scrn = data;
267 ctx_scrn->prop.screenWidth = width;
268 ctx_scrn->prop.screenHeight = height;
273 output_listener_done(void *data,
274 struct wl_output *output)
281 output_listener_scale(void *data,
282 struct wl_output *output,
290 static struct wl_output_listener output_listener = {
291 output_listener_geometry,
292 output_listener_mode,
293 output_listener_done,
294 output_listener_scale
297 static struct screen_context*
298 get_screen_context_by_serverid(struct wayland_context *ctx,
301 struct screen_context *ctx_scrn = NULL;
303 wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
304 if (ctx_scrn->id_from_server == id_screen) {
312 add_orderlayer_to_screen(struct layer_context *ctx_layer,
313 struct wl_output* output)
315 struct screen_context *ctx_scrn = wl_output_get_user_data(output);
318 struct layer_context *layer_link;
319 wl_list_for_each(layer_link, &ctx_scrn->order.list_layer, order.link) {
320 if (layer_link == ctx_layer) {
327 wl_list_init(&ctx_layer->order.link);
328 wl_list_insert(&ctx_scrn->order.list_layer, &ctx_layer->order.link);
333 remove_orderlayer_from_screen(struct layer_context *ctx_layer)
335 wl_list_remove(&ctx_layer->order.link);
336 wl_list_init(&ctx_layer->order.link);
340 controller_layer_listener_visibility(void *data,
341 struct ivi_controller_layer *controller,
344 struct layer_context *ctx_layer = data;
346 ctx_layer->prop.visibility = (t_ilm_bool)visibility;
348 if (ctx_layer->notification != NULL) {
349 ctx_layer->notification(ctx_layer->id_layer,
351 ILM_NOTIFICATION_VISIBILITY);
356 controller_layer_listener_opacity(void *data,
357 struct ivi_controller_layer *controller,
360 struct layer_context *ctx_layer = data;
362 ctx_layer->prop.opacity = (t_ilm_float)wl_fixed_to_double(opacity);
364 if (ctx_layer->notification != NULL) {
365 ctx_layer->notification(ctx_layer->id_layer,
367 ILM_NOTIFICATION_OPACITY);
372 controller_layer_listener_source_rectangle(void *data,
373 struct ivi_controller_layer *controller,
379 struct layer_context *ctx_layer = data;
381 ctx_layer->prop.sourceX = (t_ilm_uint)x;
382 ctx_layer->prop.sourceY = (t_ilm_uint)y;
383 ctx_layer->prop.sourceWidth = (t_ilm_uint)width;
384 ctx_layer->prop.sourceHeight = (t_ilm_uint)height;
385 if (ctx_layer->prop.origSourceWidth == 0) {
386 ctx_layer->prop.origSourceWidth = (t_ilm_uint)width;
388 if (ctx_layer->prop.origSourceHeight == 0) {
389 ctx_layer->prop.origSourceHeight = (t_ilm_uint)height;
392 if (ctx_layer->notification != NULL) {
393 ctx_layer->notification(ctx_layer->id_layer,
395 ILM_NOTIFICATION_SOURCE_RECT);
400 controller_layer_listener_destination_rectangle(void *data,
401 struct ivi_controller_layer *controller,
407 struct layer_context *ctx_layer = data;
409 ctx_layer->prop.destX = (t_ilm_uint)x;
410 ctx_layer->prop.destY = (t_ilm_uint)y;
411 ctx_layer->prop.destWidth = (t_ilm_uint)width;
412 ctx_layer->prop.destHeight = (t_ilm_uint)height;
414 if (ctx_layer->notification != NULL) {
415 ctx_layer->notification(ctx_layer->id_layer,
417 ILM_NOTIFICATION_DEST_RECT);
422 controller_layer_listener_configuration(void *data,
423 struct ivi_controller_layer *controller,
427 struct layer_context *ctx_layer = data;
429 ctx_layer->prop.sourceWidth = (t_ilm_uint)width;
430 ctx_layer->prop.sourceHeight = (t_ilm_uint)height;
434 controller_layer_listener_orientation(void *data,
435 struct ivi_controller_layer *controller,
438 ilmOrientation ilmorientation = ILM_ZERO;
439 struct layer_context *ctx_layer = data;
441 switch(orientation) {
442 case IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES:
443 ilmorientation = ILM_ZERO;
445 case IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES:
446 ilmorientation = ILM_NINETY;
448 case IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES:
449 ilmorientation = ILM_ONEHUNDREDEIGHTY;
451 case IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES:
452 ilmorientation = ILM_TWOHUNDREDSEVENTY;
458 ctx_layer->prop.orientation = ilmorientation;
460 if (ctx_layer->notification != NULL) {
461 ctx_layer->notification(ctx_layer->id_layer,
463 ILM_NOTIFICATION_ORIENTATION);
468 controller_layer_listener_screen(void *data,
469 struct ivi_controller_layer *controller,
470 struct wl_output *output)
472 struct layer_context *ctx_layer = data;
474 if (output == NULL) {
475 remove_orderlayer_from_screen(ctx_layer);
477 add_orderlayer_to_screen(ctx_layer, output);
482 controller_layer_listener_destroyed(void *data,
483 struct ivi_controller_layer *controller)
485 struct layer_context *ctx_layer = data;
486 wl_list_remove(&ctx_layer->link);
490 static struct ivi_controller_layer_listener controller_layer_listener =
492 controller_layer_listener_visibility,
493 controller_layer_listener_opacity,
494 controller_layer_listener_source_rectangle,
495 controller_layer_listener_destination_rectangle,
496 controller_layer_listener_configuration,
497 controller_layer_listener_orientation,
498 controller_layer_listener_screen,
499 controller_layer_listener_destroyed
503 add_ordersurface_to_layer(struct surface_context *ctx_surf,
504 struct ivi_controller_layer *layer)
506 struct layer_context *ctx_layer = NULL;
507 struct surface_context *link = NULL;
510 ctx_layer = ivi_controller_layer_get_user_data(layer);
512 wl_list_for_each(link, &ctx_layer->order.list_surface, order.link) {
513 if (link == ctx_surf) {
520 wl_list_init(&ctx_surf->order.link);
521 wl_list_insert(&ctx_layer->order.list_surface, &ctx_surf->order.link);
526 remove_ordersurface_from_layer(struct surface_context *ctx_surf)
528 wl_list_remove(&ctx_surf->order.link);
529 wl_list_init(&ctx_surf->order.link);
533 controller_surface_listener_visibility(void *data,
534 struct ivi_controller_surface *controller,
537 struct surface_context *ctx_surf = data;
539 ctx_surf->prop.visibility = (t_ilm_bool)visibility;
541 if (ctx_surf->notification != NULL) {
542 ctx_surf->notification(ctx_surf->id_surface,
544 ILM_NOTIFICATION_VISIBILITY);
549 controller_surface_listener_opacity(void *data,
550 struct ivi_controller_surface *controller,
553 struct surface_context *ctx_surf = data;
555 ctx_surf->prop.opacity = (t_ilm_float)wl_fixed_to_double(opacity);
557 if (ctx_surf->notification != NULL) {
558 ctx_surf->notification(ctx_surf->id_surface,
560 ILM_NOTIFICATION_OPACITY);
565 controller_surface_listener_configuration(void *data,
566 struct ivi_controller_surface *controller,
570 struct surface_context *ctx_surf = data;
572 ctx_surf->prop.sourceWidth = (t_ilm_uint)width;
573 ctx_surf->prop.sourceHeight = (t_ilm_uint)height;
577 controller_surface_listener_source_rectangle(void *data,
578 struct ivi_controller_surface *controller,
584 struct surface_context *ctx_surf = data;
586 ctx_surf->prop.sourceX = (t_ilm_uint)x;
587 ctx_surf->prop.sourceY = (t_ilm_uint)y;
588 ctx_surf->prop.sourceWidth = (t_ilm_uint)width;
589 ctx_surf->prop.sourceHeight = (t_ilm_uint)height;
590 if (ctx_surf->prop.origSourceWidth == 0) {
591 ctx_surf->prop.origSourceWidth = (t_ilm_uint)width;
593 if (ctx_surf->prop.origSourceHeight == 0) {
594 ctx_surf->prop.origSourceHeight = (t_ilm_uint)height;
597 if (ctx_surf->notification != NULL) {
598 ctx_surf->notification(ctx_surf->id_surface,
600 ILM_NOTIFICATION_SOURCE_RECT);
605 controller_surface_listener_destination_rectangle(void *data,
606 struct ivi_controller_surface *controller,
612 struct surface_context *ctx_surf = data;
614 ctx_surf->prop.destX = (t_ilm_uint)x;
615 ctx_surf->prop.destY = (t_ilm_uint)y;
616 ctx_surf->prop.destWidth = (t_ilm_uint)width;
617 ctx_surf->prop.destHeight = (t_ilm_uint)height;
619 if (ctx_surf->notification != NULL) {
620 ctx_surf->notification(ctx_surf->id_surface,
622 ILM_NOTIFICATION_DEST_RECT);
627 controller_surface_listener_orientation(void *data,
628 struct ivi_controller_surface *controller,
631 struct surface_context *ctx_surf = data;
632 ilmOrientation ilmorientation = ILM_ZERO;
634 switch (orientation) {
635 case IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES:
636 ilmorientation = ILM_ZERO;
638 case IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES:
639 ilmorientation = ILM_NINETY;
641 case IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES:
642 ilmorientation = ILM_ONEHUNDREDEIGHTY;
644 case IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES:
645 ilmorientation = ILM_TWOHUNDREDSEVENTY;
651 ctx_surf->prop.orientation = ilmorientation;
653 if (ctx_surf->notification != NULL) {
654 ctx_surf->notification(ctx_surf->id_surface,
656 ILM_NOTIFICATION_ORIENTATION);
661 controller_surface_listener_pixelformat(void *data,
662 struct ivi_controller_surface *controller,
665 struct surface_context *ctx_surf = data;
667 ctx_surf->prop.pixelformat = (t_ilm_uint)pixelformat;
671 controller_surface_listener_layer(void *data,
672 struct ivi_controller_surface *controller,
673 struct ivi_controller_layer *layer)
675 struct surface_context *ctx_surf = data;
678 remove_ordersurface_from_layer(ctx_surf);
680 add_ordersurface_to_layer(ctx_surf, layer);
685 controller_surface_listener_stats(void *data,
686 struct ivi_controller_surface *controller,
687 uint32_t redraw_count,
688 uint32_t frame_count,
689 uint32_t update_count,
691 const char *process_name)
693 struct surface_context *ctx_surf = data;
696 ctx_surf->prop.drawCounter = (t_ilm_uint)redraw_count;
697 ctx_surf->prop.frameCounter = (t_ilm_uint)frame_count;
698 ctx_surf->prop.updateCounter = (t_ilm_uint)update_count;
699 ctx_surf->prop.creatorPid = (t_ilm_uint)pid;
703 controller_surface_listener_destroyed(void *data,
704 struct ivi_controller_surface *controller)
706 struct surface_context *ctx_surf = data;
708 if (ctx_surf->notification != NULL) {
709 ctx_surf->notification(ctx_surf->id_surface,
711 ILM_NOTIFICATION_CONTENT_REMOVED);
714 wl_list_remove(&ctx_surf->link);
719 controller_surface_listener_content(void *data,
720 struct ivi_controller_surface *controller,
721 int32_t content_state)
723 struct surface_context *ctx_surf = data;
725 // if client surface (=content) was removed with ilm_surfaceDestroy()
726 // the expected behavior within ILM API mandates a full removal
727 // of the surface from the scene. We must remove the controller
729 if (IVI_CONTROLLER_SURFACE_CONTENT_STATE_CONTENT_REMOVED == content_state)
731 if (ctx_surf->notification != NULL) {
732 ctx_surf->notification(ctx_surf->id_surface,
734 ILM_NOTIFICATION_CONTENT_REMOVED);
737 ivi_controller_surface_destroy(controller, 1);
739 wl_list_remove(&ctx_surf->link);
742 else if (IVI_CONTROLLER_SURFACE_CONTENT_STATE_CONTENT_AVAILABLE == content_state)
744 if (ctx_surf->notification != NULL) {
745 ctx_surf->notification(ctx_surf->id_surface,
747 ILM_NOTIFICATION_CONTENT_AVAILABLE);
753 controller_surface_listener_input_focus(void *data,
754 struct ivi_controller_surface *controller,
764 static struct ivi_controller_surface_listener controller_surface_listener=
766 controller_surface_listener_visibility,
767 controller_surface_listener_opacity,
768 controller_surface_listener_source_rectangle,
769 controller_surface_listener_destination_rectangle,
770 controller_surface_listener_configuration,
771 controller_surface_listener_orientation,
772 controller_surface_listener_pixelformat,
773 controller_surface_listener_layer,
774 controller_surface_listener_stats,
775 controller_surface_listener_destroyed,
776 controller_surface_listener_content,
777 controller_surface_listener_input_focus
781 controller_listener_layer(void *data,
782 struct ivi_controller *controller,
785 struct wayland_context *ctx = data;
787 if (wayland_controller_is_inside_layer_list(&ctx->list_layer, id_layer))
792 (void) create_controller_layer(ctx, 0, 0, id_layer);
796 controller_listener_surface(void *data,
797 struct ivi_controller *controller,
800 struct wayland_context *ctx = data;
801 struct surface_context *ctx_surf = NULL;
803 ctx_surf = get_surface_context(ctx, id_surface);
804 if (ctx_surf != NULL) {
805 if (!ctx_surf->is_surface_creation_noticed) {
806 if (ctx_surf->notification != NULL) {
807 ctx_surf->notification(ctx_surf->id_surface,
809 ILM_NOTIFICATION_CONTENT_AVAILABLE);
810 ctx_surf->is_surface_creation_noticed = true;
812 ctx_surf->controller = ivi_controller_surface_create(
813 controller, id_surface);
816 fprintf(stderr, "invalid id_surface in controller_listener_surface\n");
821 ctx_surf = calloc(1, sizeof *ctx_surf);
822 if (ctx_surf == NULL) {
823 fprintf(stderr, "Failed to allocate memory for surface_context\n");
827 ctx_surf->controller = ivi_controller_surface_create(
828 controller, id_surface);
829 if (ctx_surf->controller == NULL) {
831 fprintf(stderr, "Failed to create controller surface\n");
834 ctx_surf->id_surface = id_surface;
835 ctx_surf->prop.inputDevicesAcceptance = ILM_INPUT_DEVICE_ALL;
837 ctx_surf->is_surface_creation_noticed = true;
839 wl_list_init(&ctx_surf->link);
840 wl_list_insert(&ctx->list_surface, &ctx_surf->link);
841 wl_list_init(&ctx_surf->order.link);
842 ivi_controller_surface_add_listener(ctx_surf->controller,
843 &controller_surface_listener, ctx_surf);
847 controller_listener_error(void *data,
848 struct ivi_controller *ivi_controller,
852 const char *error_text)
855 (void)ivi_controller;
863 controller_listener_screen(void *data,
864 struct ivi_controller *ivi_controller,
866 struct ivi_controller_screen *controller_screen)
868 struct wayland_context *ctx = data;
869 struct screen_context *ctx_screen;
870 (void)ivi_controller;
872 ctx_screen = get_screen_context_by_serverid(ctx, id_screen);
873 if (ctx_screen == NULL) {
874 fprintf(stderr, "Failed to allocate memory for screen_context\n");
877 ctx_screen->controller = controller_screen;
880 static struct ivi_controller_listener controller_listener= {
881 controller_listener_screen,
882 controller_listener_layer,
883 controller_listener_surface,
884 controller_listener_error
888 registry_handle_control(void *data,
889 struct wl_registry *registry,
890 uint32_t name, const char *interface,
893 struct wayland_context *ctx = data;
896 if (strcmp(interface, "ivi_controller") == 0) {
897 ctx->controller = wl_registry_bind(registry, name,
898 &ivi_controller_interface, 1);
899 if (ctx->controller == NULL) {
900 fprintf(stderr, "Failed to registry bind ivi_controller\n");
903 if (ivi_controller_add_listener(ctx->controller,
904 &controller_listener,
906 fprintf(stderr, "Failed to add ivi_controller listener\n");
909 } else if (strcmp(interface, "wl_output") == 0) {
910 struct screen_context *ctx_scrn = calloc(1, sizeof *ctx_scrn);
911 struct wl_proxy *pxy = NULL;
913 if (ctx_scrn == NULL) {
914 fprintf(stderr, "Failed to allocate memory for screen_context\n");
917 wl_list_init(&ctx_scrn->link);
918 ctx_scrn->output = wl_registry_bind(registry, name,
919 &wl_output_interface, 1);
920 if (ctx_scrn->output == NULL) {
922 fprintf(stderr, "Failed to registry bind wl_output\n");
926 if (wl_output_add_listener(ctx_scrn->output,
930 fprintf(stderr, "Failed to add wl_output listener\n");
934 pxy = (struct wl_proxy*)ctx_scrn->output;
935 ctx_scrn->id_from_server = wl_proxy_get_id(pxy);
936 ctx_scrn->id_screen = ctx->num_screen;
938 wl_list_init(&ctx_scrn->order.list_layer);
939 wl_list_insert(&ctx->list_screen, &ctx_scrn->link);
943 static const struct wl_registry_listener
944 registry_control_listener= {
945 registry_handle_control,
949 static struct ilm_control_context ilm_context;
951 static void destroy_control_resources(void)
953 struct ilm_control_context *ctx = &ilm_context;
955 // free resources of output objects
956 if (! ctx->wl.controller) {
957 struct screen_context *ctx_scrn;
958 struct screen_context *next;
960 wl_list_for_each_safe(ctx_scrn, next, &ctx->wl.list_screen, link) {
961 if (ctx_scrn->output != NULL) {
962 wl_output_destroy(ctx_scrn->output);
965 wl_list_remove(&ctx_scrn->link);
970 if (ctx->wl.controller != NULL) {
972 struct surface_context *l;
973 struct surface_context *n;
974 wl_list_for_each_safe(l, n, &ctx->wl.list_surface, link) {
975 wl_list_remove(&l->link);
976 wl_list_remove(&l->order.link);
977 ivi_controller_surface_destroy(l->controller, 0);
983 struct layer_context *l;
984 struct layer_context *n;
985 wl_list_for_each_safe(l, n, &ctx->wl.list_layer, link) {
986 wl_list_remove(&l->link);
987 wl_list_remove(&l->order.link);
993 struct screen_context *ctx_scrn;
994 struct screen_context *next;
996 wl_list_for_each_safe(ctx_scrn, next, &ctx->wl.list_screen, link) {
997 if (ctx_scrn->output != NULL) {
998 wl_output_destroy(ctx_scrn->output);
1001 wl_list_remove(&ctx_scrn->link);
1002 ivi_controller_screen_destroy(ctx_scrn->controller);
1007 ivi_controller_destroy(ctx->wl.controller);
1008 ctx->wl.controller = NULL;
1011 if (ctx->wl.display) {
1012 wl_display_flush(ctx->wl.display);
1015 if (ctx->wl.registry) {
1016 wl_registry_destroy(ctx->wl.registry);
1017 ctx->wl.registry = NULL;
1020 if (ctx->wl.queue) {
1021 wl_event_queue_destroy(ctx->wl.queue);
1022 ctx->wl.queue = NULL;
1025 if (0 != pthread_mutex_destroy(&ctx->mutex)) {
1026 fprintf(stderr, "failed to destroy pthread_mutex\n");
1030 static void send_shutdown_event(struct ilm_control_context *ctx)
1033 while (write(ctx->shutdown_fd, &buf, sizeof buf) == -1 && errno == EINTR)
1038 ilmControl_destroy(void)
1040 struct ilm_control_context *ctx = &ilm_context;
1042 send_shutdown_event(ctx);
1044 if (0 != pthread_join(ctx->thread, NULL)) {
1045 fprintf(stderr, "failed to join control thread\n");
1048 destroy_control_resources();
1050 close(ctx->shutdown_fd);
1052 memset(ctx, 0, sizeof *ctx);
1055 ILM_EXPORT ilmErrorTypes
1056 ilmControl_init(t_ilm_nativedisplay nativedisplay)
1058 struct ilm_control_context *ctx = &ilm_context;
1060 if (ctx->initialized)
1062 fprintf(stderr, "Already initialized!\n");
1066 if (nativedisplay == 0) {
1067 return ILM_ERROR_INVALID_ARGUMENTS;
1070 ctx->shutdown_fd = -1;
1072 ctx->wl.display = (struct wl_display*)nativedisplay;
1074 wl_list_init(&ctx->wl.list_screen);
1075 wl_list_init(&ctx->wl.list_layer);
1076 wl_list_init(&ctx->wl.list_surface);
1079 pthread_mutexattr_t a;
1080 if (pthread_mutexattr_init(&a) != 0)
1085 if (pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE) != 0)
1087 pthread_mutexattr_destroy(&a);
1091 if (pthread_mutex_init(&ctx->mutex, &a) != 0)
1093 pthread_mutexattr_destroy(&a);
1094 fprintf(stderr, "failed to initialize pthread_mutex\n");
1098 pthread_mutexattr_destroy(&a);
1101 return init_control() == 0 ? ILM_SUCCESS : ILM_FAILED;
1105 control_thread(void *p_ret)
1107 struct ilm_control_context *const ctx = &ilm_context;
1108 struct wayland_context *const wl = &ctx->wl;
1109 struct wl_display *const display = wl->display;
1110 struct wl_event_queue *const queue = wl->queue;
1111 int const fd = wl_display_get_fd(display);
1112 int const shutdown_fd = ctx->shutdown_fd;
1117 while (wl_display_prepare_read_queue(display, queue) != 0)
1120 wl_display_dispatch_queue_pending(display, queue);
1121 unlock_context(ctx);
1124 if (wl_display_flush(display) == -1)
1129 struct pollfd pfd[2] = {
1130 { .fd = fd, .events = POLLIN },
1131 { .fd = shutdown_fd, .events = POLLIN }
1134 int pollret = poll(pfd, 2, -1);
1135 if (pollret != -1 && (pfd[0].revents & POLLIN))
1137 wl_display_read_events(display);
1140 int ret = wl_display_dispatch_queue_pending(display, queue);
1141 unlock_context(ctx);
1150 wl_display_cancel_read(display);
1152 if (pollret == -1 || (pfd[1].revents & POLLIN))
1165 struct ilm_control_context *ctx = &ilm_context;
1166 struct wayland_context *wl = &ctx->wl;
1170 wl_list_init(&ctx->list_nativehandle);
1172 wl->queue = wl_display_create_queue(wl->display);
1174 /* registry_add_listener for request by ivi-controller */
1175 wl->registry = wl_display_get_registry(wl->display);
1176 if (wl->registry == NULL) {
1177 wl_event_queue_destroy(wl->queue);
1179 fprintf(stderr, "Failed to get registry\n");
1182 wl_proxy_set_queue((void*)wl->registry, wl->queue);
1184 if (wl_registry_add_listener(wl->registry,
1185 ®istry_control_listener, ctx)) {
1186 fprintf(stderr, "Failed to add registry listener\n");
1190 // first level objects; ivi_controller
1191 display_roundtrip_queue(wl->display, wl->queue);
1192 // second level object: ivi_controller_surfaces/layers
1193 display_roundtrip_queue(wl->display, wl->queue);
1194 // third level objects: ivi_controller_surfaces/layers properties
1195 display_roundtrip_queue(wl->display, wl->queue);
1197 if (! wl->controller)
1199 fprintf(stderr, "ivi_controller not available\n");
1203 ctx->shutdown_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
1205 if (ctx->shutdown_fd == -1)
1207 fprintf(stderr, "Could not setup shutdown-fd: %s\n", strerror(errno));
1211 ret = pthread_create(&ctx->thread, NULL, control_thread, NULL);
1214 fprintf(stderr, "Failed to start internal receive thread. returned %d\n", ret);
1218 ctx->initialized = true;
1223 static ilmErrorTypes impl_sync_and_acquire_instance(struct ilm_control_context *ctx)
1225 if (! ctx->initialized) {
1226 fprintf(stderr, "Not initialized\n");
1232 if (display_roundtrip_queue(ctx->wl.display, ctx->wl.queue) == -1) {
1233 int err = wl_display_get_error(ctx->wl.display);
1234 fprintf(stderr, "Error communicating with wayland: %s\n", strerror(err));
1235 unlock_context(ctx);
1242 #define sync_and_acquire_instance() ({ \
1243 struct ilm_control_context *ctx = &ilm_context; \
1245 ilmErrorTypes status = impl_sync_and_acquire_instance(ctx); \
1246 if (status != ILM_SUCCESS) { \
1253 static void release_instance(void)
1255 struct ilm_control_context *ctx = &ilm_context;
1256 unlock_context(ctx);
1260 gen_layer_id(struct ilm_control_context *ctx)
1262 struct layer_context *ctx_layer = NULL;
1265 if (wl_list_length(&ctx->wl.list_layer) == 0) {
1266 ctx->internal_id_layer++;
1267 return ctx->internal_id_layer;
1269 wl_list_for_each(ctx_layer, &ctx->wl.list_layer, link) {
1270 if (ctx_layer->id_layer == ctx->internal_id_layer) {
1276 return ctx->internal_id_layer;
1279 ctx->internal_id_layer++;
1283 static struct surface_context*
1284 get_surface_context(struct wayland_context *ctx,
1285 uint32_t id_surface)
1287 struct surface_context *ctx_surf = NULL;
1289 if (ctx->controller == NULL) {
1290 fprintf(stderr, "controller is not initialized in ilmControl\n");
1294 wl_list_for_each(ctx_surf, &ctx->list_surface, link) {
1295 if (ctx_surf->id_surface == id_surface) {
1300 fprintf(stderr, "failed to get surface context in ilmControl\n");
1304 static struct screen_context*
1305 get_screen_context_by_id(struct wayland_context *ctx, uint32_t id_screen)
1307 struct screen_context *ctx_scrn = NULL;
1309 if (ctx->controller == NULL) {
1310 fprintf(stderr, "get_screen_context_by_id: controller is NULL\n");
1314 wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
1315 if (ctx_scrn->id_screen == id_screen) {
1322 ILM_EXPORT ilmErrorTypes
1323 ilm_getPropertiesOfLayer(t_ilm_uint layerID,
1324 struct ilmLayerProperties* pLayerProperties)
1326 ilmErrorTypes returnValue = ILM_FAILED;
1327 struct ilm_control_context *ctx = sync_and_acquire_instance();
1328 struct layer_context *ctx_layer = NULL;
1330 if (pLayerProperties != NULL) {
1332 ctx_layer = (struct layer_context*)
1333 wayland_controller_get_layer_context(
1334 &ctx->wl, (uint32_t)layerID);
1336 if (ctx_layer != NULL) {
1337 *pLayerProperties = ctx_layer->prop;
1338 returnValue = ILM_SUCCESS;
1347 create_layerids(struct screen_context *ctx_screen,
1348 t_ilm_layer **layer_ids, t_ilm_uint *layer_count)
1350 struct layer_context *ctx_layer = NULL;
1351 t_ilm_layer *ids = NULL;
1353 *layer_count = wl_list_length(&ctx_screen->order.list_layer);
1354 if (*layer_count == 0) {
1359 *layer_ids = malloc(*layer_count * sizeof(t_ilm_layer));
1360 if (*layer_ids == NULL) {
1361 fprintf(stderr, "memory insufficient for layerids\n");
1367 wl_list_for_each_reverse(ctx_layer, &ctx_screen->order.list_layer, order.link) {
1368 *ids = (t_ilm_layer)ctx_layer->id_layer;
1373 ILM_EXPORT ilmErrorTypes
1374 ilm_getPropertiesOfScreen(t_ilm_display screenID,
1375 struct ilmScreenProperties* pScreenProperties)
1377 ilmErrorTypes returnValue = ILM_FAILED;
1379 if (! pScreenProperties)
1381 return ILM_ERROR_INVALID_ARGUMENTS;
1384 struct ilm_control_context *ctx = sync_and_acquire_instance();
1386 struct screen_context *ctx_screen = NULL;
1387 ctx_screen = get_screen_context_by_id(&ctx->wl, (uint32_t)screenID);
1388 if (ctx_screen != NULL) {
1389 *pScreenProperties = ctx_screen->prop;
1390 create_layerids(ctx_screen, &pScreenProperties->layerIds,
1391 &pScreenProperties->layerCount);
1392 returnValue = ILM_SUCCESS;
1399 ILM_EXPORT ilmErrorTypes
1400 ilm_getNumberOfHardwareLayers(t_ilm_uint screenID,
1401 t_ilm_uint* pNumberOfHardwareLayers)
1405 if (pNumberOfHardwareLayers != NULL) {
1406 *pNumberOfHardwareLayers = 0;
1413 ILM_EXPORT ilmErrorTypes
1414 ilm_getScreenIDs(t_ilm_uint* pNumberOfIDs, t_ilm_uint** ppIDs)
1416 ilmErrorTypes returnValue = ILM_FAILED;
1417 struct ilm_control_context *ctx = sync_and_acquire_instance();
1419 if ((pNumberOfIDs != NULL) && (ppIDs != NULL)) {
1420 struct screen_context *ctx_scrn = NULL;
1421 t_ilm_uint length = wl_list_length(&ctx->wl.list_screen);
1424 *ppIDs = (t_ilm_uint*)malloc(length * sizeof **ppIDs);
1425 if (*ppIDs != NULL) {
1426 t_ilm_uint* ids = *ppIDs;
1427 wl_list_for_each(ctx_scrn, &ctx->wl.list_screen, link) {
1428 *ids = ctx_scrn->id_screen;
1431 *pNumberOfIDs = length;
1433 returnValue = ILM_SUCCESS;
1441 ILM_EXPORT ilmErrorTypes
1442 ilm_getLayerIDs(t_ilm_int* pLength, t_ilm_layer** ppArray)
1444 ilmErrorTypes returnValue = ILM_FAILED;
1445 struct ilm_control_context *ctx = sync_and_acquire_instance();
1447 if ((pLength != NULL) && (ppArray != NULL)) {
1448 struct layer_context *ctx_layer = NULL;
1449 t_ilm_uint length = wl_list_length(&ctx->wl.list_layer);
1452 *ppArray = (t_ilm_layer*)malloc(length * sizeof **ppArray);
1453 if (*ppArray != NULL) {
1454 // compositor sends layers in opposite order
1455 // write ids from back to front to turn them around
1456 t_ilm_layer* ids = *ppArray;
1457 wl_list_for_each_reverse(ctx_layer, &ctx->wl.list_layer, link)
1459 *ids = ctx_layer->id_layer;
1464 returnValue = ILM_SUCCESS;
1472 ILM_EXPORT ilmErrorTypes
1473 ilm_getLayerIDsOnScreen(t_ilm_uint screenId,
1475 t_ilm_layer** ppArray)
1477 ilmErrorTypes returnValue = ILM_FAILED;
1478 struct ilm_control_context *ctx = sync_and_acquire_instance();
1480 if ((pLength != NULL) && (ppArray != NULL)) {
1481 struct screen_context *ctx_screen = NULL;
1482 ctx_screen = get_screen_context_by_id(&ctx->wl, screenId);
1483 if (ctx_screen != NULL) {
1484 struct layer_context *ctx_layer = NULL;
1485 t_ilm_int length = wl_list_length(&ctx_screen->order.list_layer);
1489 *ppArray = (t_ilm_layer*)malloc(length * sizeof **ppArray);
1490 if (*ppArray != NULL) {
1491 // compositor sends layers in opposite order
1492 // write ids from back to front to turn them around
1493 t_ilm_layer* ids = *ppArray;
1494 wl_list_for_each_reverse(ctx_layer, &ctx_screen->order.list_layer, order.link)
1496 *ids = ctx_layer->id_layer;
1508 returnValue = ILM_SUCCESS;
1516 ILM_EXPORT ilmErrorTypes
1517 ilm_getSurfaceIDs(t_ilm_int* pLength, t_ilm_surface** ppArray)
1519 ilmErrorTypes returnValue = ILM_FAILED;
1520 struct ilm_control_context *ctx = sync_and_acquire_instance();
1522 if ((pLength != NULL) && (ppArray != NULL)) {
1523 struct surface_context *ctx_surf = NULL;
1524 t_ilm_uint length = wl_list_length(&ctx->wl.list_surface);
1527 *ppArray = (t_ilm_surface*)malloc(length * sizeof **ppArray);
1528 if (*ppArray != NULL) {
1529 t_ilm_surface* ids = *ppArray;
1530 wl_list_for_each_reverse(ctx_surf, &ctx->wl.list_surface, link) {
1531 *ids = ctx_surf->id_surface;
1536 returnValue = ILM_SUCCESS;
1544 ILM_EXPORT ilmErrorTypes
1545 ilm_getSurfaceIDsOnLayer(t_ilm_layer layer,
1547 t_ilm_surface** ppArray)
1549 struct ilm_control_context *ctx = sync_and_acquire_instance();
1550 struct layer_context *ctx_layer = NULL;
1551 struct surface_context *ctx_surf = NULL;
1552 t_ilm_uint length = 0;
1553 t_ilm_surface* ids = NULL;
1555 if ((pLength == NULL) || (ppArray == NULL)) {
1560 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1561 &ctx->wl, (uint32_t)layer);
1563 if (ctx_layer == NULL) {
1568 length = wl_list_length(&ctx_layer->order.list_surface);
1569 *ppArray = (t_ilm_surface*)malloc(length * sizeof **ppArray);
1570 if (*ppArray == NULL) {
1576 wl_list_for_each_reverse(ctx_surf, &ctx_layer->order.list_surface, order.link) {
1577 *ids = (t_ilm_surface)ctx_surf->id_surface;
1586 static int create_controller_layer(struct wayland_context *ctx, t_ilm_uint width, t_ilm_uint height, t_ilm_layer layerid)
1588 struct layer_context *ctx_layer = calloc(1, sizeof *ctx_layer);
1589 if (ctx_layer == NULL) {
1590 fprintf(stderr, "Failed to allocate memory for layer_context\n");
1594 ctx_layer->controller = ivi_controller_layer_create(
1596 layerid, width, height);
1597 if (ctx_layer->controller == NULL) {
1598 fprintf(stderr, "Failed to create layer\n");
1602 ctx_layer->id_layer = layerid;
1603 ctx_layer->ctx = ctx;
1605 wl_list_init(&ctx_layer->link);
1606 wl_list_insert(&ctx->list_layer, &ctx_layer->link);
1607 wl_list_init(&ctx_layer->order.link);
1608 wl_list_init(&ctx_layer->order.list_surface);
1610 ivi_controller_layer_add_listener(ctx_layer->controller,
1611 &controller_layer_listener, ctx_layer);
1616 ILM_EXPORT ilmErrorTypes
1617 ilm_layerCreateWithDimension(t_ilm_layer* pLayerId,
1621 ilmErrorTypes returnValue = ILM_FAILED;
1622 struct ilm_control_context *ctx = sync_and_acquire_instance();
1623 uint32_t layerid = 0;
1624 int32_t is_inside = 0;
1627 if (pLayerId == NULL) {
1631 if (*pLayerId != INVALID_ID) {
1632 /* Return failed, if layerid is already inside list_layer */
1633 is_inside = wayland_controller_is_inside_layer_list(
1634 &ctx->wl.list_layer, *pLayerId);
1635 if (0 != is_inside) {
1636 fprintf(stderr, "layerid=%d is already used.\n", *pLayerId);
1639 layerid = *pLayerId;
1642 /* Generate ID, if layerid is INVALID_ID */
1643 layerid = gen_layer_id(ctx);
1644 *pLayerId = layerid;
1647 if (create_controller_layer(&ctx->wl, width, height, layerid) == 0)
1649 returnValue = ILM_SUCCESS;
1657 ILM_EXPORT ilmErrorTypes
1658 ilm_layerRemove(t_ilm_layer layerId)
1660 ilmErrorTypes returnValue = ILM_FAILED;
1661 struct ilm_control_context *ctx = sync_and_acquire_instance();
1662 struct layer_context *ctx_layer = NULL;
1663 struct layer_context *ctx_next = NULL;
1665 wl_list_for_each_safe(ctx_layer, ctx_next,
1666 &ctx->wl.list_layer, link) {
1667 if (ctx_layer->id_layer == layerId) {
1668 ivi_controller_layer_destroy(ctx_layer->controller, 1);
1670 wl_list_remove(&ctx_layer->link);
1673 returnValue = ILM_SUCCESS;
1682 ILM_EXPORT ilmErrorTypes
1683 ilm_layerGetType(t_ilm_layer layerId, ilmLayerType* pLayerType)
1687 return ILM_ERROR_INVALID_ARGUMENTS;
1690 struct ilm_control_context *ctx = sync_and_acquire_instance();
1692 *pLayerType = wayland_controller_is_inside_layer_list(&ctx->wl.list_layer, layerId) ?
1693 ILM_LAYERTYPE_SOFTWARE2D :
1694 ILM_LAYERTYPE_UNKNOWN;
1697 return ILM_SUCCESS; // even if non existent?
1700 ILM_EXPORT ilmErrorTypes
1701 ilm_layerSetVisibility(t_ilm_layer layerId, t_ilm_bool newVisibility)
1703 ilmErrorTypes returnValue = ILM_FAILED;
1704 struct ilm_control_context *ctx = sync_and_acquire_instance();
1705 struct layer_context *ctx_layer = NULL;
1707 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1708 &ctx->wl, (uint32_t)layerId);
1710 if (ctx_layer != NULL) {
1711 uint32_t visibility = 0;
1712 if (newVisibility == ILM_TRUE) {
1715 ivi_controller_layer_set_visibility(ctx_layer->controller,
1717 returnValue = ILM_SUCCESS;
1724 ILM_EXPORT ilmErrorTypes
1725 ilm_layerGetVisibility(t_ilm_layer layerId, t_ilm_bool *pVisibility)
1727 ilmErrorTypes returnValue = ILM_FAILED;
1728 struct ilm_control_context *ctx = sync_and_acquire_instance();
1730 if (pVisibility != NULL) {
1731 struct layer_context *ctx_layer = NULL;
1733 ctx_layer = (struct layer_context*)
1734 wayland_controller_get_layer_context(
1735 &ctx->wl, (uint32_t)layerId);
1737 if (ctx_layer != NULL) {
1738 *pVisibility = ctx_layer->prop.visibility;
1739 returnValue = ILM_SUCCESS;
1747 ILM_EXPORT ilmErrorTypes
1748 ilm_layerSetOpacity(t_ilm_layer layerId, t_ilm_float opacity)
1750 ilmErrorTypes returnValue = ILM_FAILED;
1751 struct ilm_control_context *ctx = sync_and_acquire_instance();
1752 struct layer_context *ctx_layer = NULL;
1754 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1755 &ctx->wl, (uint32_t)layerId);
1757 if (ctx_layer != NULL) {
1758 wl_fixed_t opacity_fixed = wl_fixed_from_double((double)opacity);
1759 ivi_controller_layer_set_opacity(ctx_layer->controller,
1761 returnValue = ILM_SUCCESS;
1768 ILM_EXPORT ilmErrorTypes
1769 ilm_layerGetOpacity(t_ilm_layer layerId, t_ilm_float *pOpacity)
1771 ilmErrorTypes returnValue = ILM_FAILED;
1772 struct ilm_control_context *ctx = sync_and_acquire_instance();
1774 if (pOpacity != NULL) {
1775 struct layer_context *ctx_layer = NULL;
1777 ctx_layer = (struct layer_context*)
1778 wayland_controller_get_layer_context(
1779 &ctx->wl, (uint32_t)layerId);
1781 if (ctx_layer != NULL) {
1782 *pOpacity = ctx_layer->prop.opacity;
1783 returnValue = ILM_SUCCESS;
1791 ILM_EXPORT ilmErrorTypes
1792 ilm_layerSetSourceRectangle(t_ilm_layer layerId,
1793 t_ilm_uint x, t_ilm_uint y,
1794 t_ilm_uint width, t_ilm_uint height)
1796 ilmErrorTypes returnValue = ILM_FAILED;
1797 struct ilm_control_context *ctx = sync_and_acquire_instance();
1798 struct layer_context *ctx_layer = NULL;
1800 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1801 &ctx->wl, (uint32_t)layerId);
1803 if (ctx_layer != NULL) {
1804 ivi_controller_layer_set_source_rectangle(ctx_layer->controller,
1809 returnValue = ILM_SUCCESS;
1816 ILM_EXPORT ilmErrorTypes
1817 ilm_layerSetDestinationRectangle(t_ilm_layer layerId,
1818 t_ilm_int x, t_ilm_int y,
1819 t_ilm_int width, t_ilm_int height)
1821 ilmErrorTypes returnValue = ILM_FAILED;
1822 struct ilm_control_context *ctx = sync_and_acquire_instance();
1823 struct layer_context *ctx_layer = NULL;
1825 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1826 &ctx->wl, (uint32_t)layerId);
1827 if (ctx_layer != NULL) {
1828 ivi_controller_layer_set_destination_rectangle(
1829 ctx_layer->controller,
1830 (uint32_t)x, (uint32_t)y,
1833 returnValue = ILM_SUCCESS;
1840 ILM_EXPORT ilmErrorTypes
1841 ilm_layerGetDimension(t_ilm_layer layerId, t_ilm_uint *pDimension)
1843 ilmErrorTypes returnValue = ILM_FAILED;
1844 struct ilm_control_context *ctx = sync_and_acquire_instance();
1845 struct layer_context *ctx_layer = NULL;
1847 if (pDimension != NULL) {
1848 ctx_layer = (struct layer_context*)
1849 wayland_controller_get_layer_context(
1850 &ctx->wl, (uint32_t)layerId);
1851 if (ctx_layer != NULL) {
1852 *pDimension = ctx_layer->prop.destWidth;
1853 *(pDimension + 1) = ctx_layer->prop.destHeight;
1854 returnValue = ILM_SUCCESS;
1862 ILM_EXPORT ilmErrorTypes
1863 ilm_layerSetDimension(t_ilm_layer layerId, t_ilm_uint *pDimension)
1865 ilmErrorTypes returnValue = ILM_FAILED;
1866 struct ilm_control_context *ctx = sync_and_acquire_instance();
1867 struct layer_context *ctx_layer = NULL;
1869 if (pDimension != NULL) {
1870 ctx_layer = (struct layer_context*)
1871 wayland_controller_get_layer_context(
1872 &ctx->wl, (uint32_t)layerId);
1873 if (ctx_layer != NULL) {
1874 ivi_controller_layer_set_destination_rectangle(
1875 ctx_layer->controller,
1876 ctx_layer->prop.destX, ctx_layer->prop.destY,
1877 (int32_t)*pDimension, (int32_t)*(pDimension + 1));
1878 returnValue = ILM_SUCCESS;
1886 ILM_EXPORT ilmErrorTypes
1887 ilm_layerGetPosition(t_ilm_layer layerId, t_ilm_uint *pPosition)
1889 ilmErrorTypes returnValue = ILM_FAILED;
1890 struct ilm_control_context *ctx = sync_and_acquire_instance();
1891 struct layer_context *ctx_layer = NULL;
1893 if (pPosition != NULL) {
1894 ctx_layer = (struct layer_context*)
1895 wayland_controller_get_layer_context(
1896 &ctx->wl, (uint32_t)layerId);
1897 if (ctx_layer != NULL) {
1898 *pPosition = ctx_layer->prop.destX;
1899 *(pPosition + 1) = ctx_layer->prop.destY;
1900 returnValue = ILM_SUCCESS;
1908 ILM_EXPORT ilmErrorTypes
1909 ilm_layerSetPosition(t_ilm_layer layerId, t_ilm_uint *pPosition)
1911 ilmErrorTypes returnValue = ILM_FAILED;
1912 struct ilm_control_context *ctx = sync_and_acquire_instance();
1913 struct layer_context *ctx_layer = NULL;
1915 if (pPosition != NULL) {
1916 ctx_layer = (struct layer_context*)
1917 wayland_controller_get_layer_context(
1918 &ctx->wl, (uint32_t)layerId);
1919 if (ctx_layer != NULL) {
1920 ivi_controller_layer_set_destination_rectangle(
1921 ctx_layer->controller,
1922 (int32_t)*pPosition, (int32_t)*(pPosition + 1),
1923 ctx_layer->prop.destWidth, ctx_layer->prop.destHeight);
1924 returnValue = ILM_SUCCESS;
1932 ILM_EXPORT ilmErrorTypes
1933 ilm_layerSetOrientation(t_ilm_layer layerId, ilmOrientation orientation)
1935 ilmErrorTypes returnValue = ILM_FAILED;
1936 struct ilm_control_context *ctx = sync_and_acquire_instance();
1937 struct layer_context *ctx_layer = NULL;
1938 int32_t iviorientation = 0;
1941 switch(orientation) {
1943 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES;
1946 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES;
1948 case ILM_ONEHUNDREDEIGHTY:
1949 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES;
1951 case ILM_TWOHUNDREDSEVENTY:
1952 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES;
1955 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
1959 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1960 &ctx->wl, (uint32_t)layerId);
1961 if (ctx_layer == NULL) {
1962 returnValue = ILM_FAILED;
1966 ivi_controller_layer_set_orientation(ctx_layer->controller,
1969 returnValue = ILM_SUCCESS;
1976 ILM_EXPORT ilmErrorTypes
1977 ilm_layerGetOrientation(t_ilm_layer layerId, ilmOrientation *pOrientation)
1979 ilmErrorTypes returnValue = ILM_FAILED;
1980 struct ilm_control_context *ctx = sync_and_acquire_instance();
1981 struct layer_context *ctx_layer = NULL;
1983 if (pOrientation != NULL) {
1984 ctx_layer = (struct layer_context*)
1985 wayland_controller_get_layer_context(
1986 &ctx->wl, (uint32_t)layerId);
1987 if (ctx_layer != NULL) {
1988 *pOrientation = ctx_layer->prop.orientation;
1989 returnValue = ILM_SUCCESS;
1997 ILM_EXPORT ilmErrorTypes
1998 ilm_layerSetChromaKey(t_ilm_layer layerId, t_ilm_int* pColor)
2006 ILM_EXPORT ilmErrorTypes
2007 ilm_layerSetRenderOrder(t_ilm_layer layerId,
2008 t_ilm_surface *pSurfaceId,
2011 ilmErrorTypes returnValue = ILM_FAILED;
2012 struct ilm_control_context *ctx = sync_and_acquire_instance();
2013 struct layer_context *ctx_layer = NULL;
2015 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2016 &ctx->wl, (uint32_t)layerId);
2020 struct wl_array ids;
2021 wl_array_init(&ids);
2022 uint32_t *pids = wl_array_add(&ids, number * sizeof *pids);
2024 for (i = 0; i < number; i++) pids[i] = (uint32_t)pSurfaceId[i];
2025 ivi_controller_layer_set_render_order(ctx_layer->controller, &ids);
2026 wl_array_release(&ids);
2027 returnValue = ILM_SUCCESS;
2034 ILM_EXPORT ilmErrorTypes
2035 ilm_layerGetCapabilities(t_ilm_layer layerId,
2036 t_ilm_layercapabilities *pCapabilities)
2039 (void)pCapabilities;
2044 ILM_EXPORT ilmErrorTypes
2045 ilm_layerTypeGetCapabilities(ilmLayerType layerType,
2046 t_ilm_layercapabilities *pCapabilities)
2049 (void)pCapabilities;
2054 ILM_EXPORT ilmErrorTypes
2055 ilm_surfaceSetVisibility(t_ilm_surface surfaceId, t_ilm_bool newVisibility)
2057 ilmErrorTypes returnValue = ILM_FAILED;
2058 struct ilm_control_context *ctx = sync_and_acquire_instance();
2059 struct surface_context *ctx_surf = NULL;
2060 uint32_t visibility = 0;
2062 if (newVisibility == ILM_TRUE) {
2065 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2067 ivi_controller_surface_set_visibility(ctx_surf->controller,
2069 returnValue = ILM_SUCCESS;
2076 ILM_EXPORT ilmErrorTypes
2077 ilm_surfaceSetOpacity(t_ilm_surface surfaceId, t_ilm_float opacity)
2079 ilmErrorTypes returnValue = ILM_FAILED;
2080 struct ilm_control_context *ctx = sync_and_acquire_instance();
2081 struct surface_context *ctx_surf = NULL;
2082 wl_fixed_t opacity_fixed = 0;
2084 opacity_fixed = wl_fixed_from_double((double)opacity);
2085 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2087 ivi_controller_surface_set_opacity(ctx_surf->controller,
2089 returnValue = ILM_SUCCESS;
2096 ILM_EXPORT ilmErrorTypes
2097 ilm_surfaceGetOpacity(t_ilm_surface surfaceId, t_ilm_float *pOpacity)
2099 ilmErrorTypes returnValue = ILM_FAILED;
2100 struct ilm_control_context *ctx = sync_and_acquire_instance();
2102 if (pOpacity != NULL) {
2103 struct surface_context *ctx_surf = NULL;
2104 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2106 *pOpacity = ctx_surf->prop.opacity;
2107 returnValue = ILM_SUCCESS;
2115 ILM_EXPORT ilmErrorTypes
2116 ilm_SetKeyboardFocusOn(t_ilm_surface surfaceId)
2118 ilmErrorTypes returnValue = ILM_FAILED;
2120 returnValue = ILM_SUCCESS;
2124 ILM_EXPORT ilmErrorTypes
2125 ilm_GetKeyboardFocusSurfaceId(t_ilm_surface* pSurfaceId)
2127 ilmErrorTypes returnValue = ILM_FAILED;
2129 returnValue = ILM_SUCCESS;
2133 ILM_EXPORT ilmErrorTypes
2134 ilm_surfaceSetDestinationRectangle(t_ilm_surface surfaceId,
2135 t_ilm_int x, t_ilm_int y,
2136 t_ilm_int width, t_ilm_int height)
2138 ilmErrorTypes returnValue = ILM_FAILED;
2139 struct ilm_control_context *ctx = sync_and_acquire_instance();
2140 struct surface_context *ctx_surf = NULL;
2142 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2144 ivi_controller_surface_set_destination_rectangle(
2145 ctx_surf->controller,
2146 x, y, width, height);
2147 returnValue = ILM_SUCCESS;
2154 ILM_EXPORT ilmErrorTypes
2155 ilm_surfaceSetDimension(t_ilm_surface surfaceId, t_ilm_uint *pDimension)
2157 ilmErrorTypes returnValue = ILM_FAILED;
2158 struct ilm_control_context *ctx = sync_and_acquire_instance();
2160 if (pDimension != NULL) {
2161 struct surface_context *ctx_surf = NULL;
2162 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2164 uint32_t width = *pDimension;
2165 uint32_t height = *(pDimension + 1);
2166 ivi_controller_surface_set_destination_rectangle(
2167 ctx_surf->controller,
2168 ctx_surf->prop.destX, ctx_surf->prop.destY, width, height);
2169 returnValue = ILM_SUCCESS;
2177 ILM_EXPORT ilmErrorTypes
2178 ilm_surfaceGetPosition(t_ilm_surface surfaceId, t_ilm_uint *pPosition)
2180 ilmErrorTypes returnValue = ILM_FAILED;
2181 struct ilm_control_context *ctx = sync_and_acquire_instance();
2183 if (pPosition != NULL) {
2184 struct surface_context *ctx_surf = NULL;
2185 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2187 *pPosition = ctx_surf->prop.destX;
2188 *(pPosition + 1) = ctx_surf->prop.destY;
2189 returnValue = ILM_SUCCESS;
2197 ILM_EXPORT ilmErrorTypes
2198 ilm_surfaceSetPosition(t_ilm_surface surfaceId, t_ilm_uint *pPosition)
2200 ilmErrorTypes returnValue = ILM_FAILED;
2201 struct ilm_control_context *ctx = sync_and_acquire_instance();
2203 if (pPosition != NULL) {
2204 struct surface_context *ctx_surf = NULL;
2205 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2207 int32_t destX = (int32_t)*pPosition;
2208 int32_t destY = (int32_t)*(pPosition + 1);
2209 ivi_controller_surface_set_destination_rectangle(
2210 ctx_surf->controller, destX, destY,
2211 ctx_surf->prop.destWidth, ctx_surf->prop.destHeight);
2212 returnValue = ILM_SUCCESS;
2220 ILM_EXPORT ilmErrorTypes
2221 ilm_surfaceSetOrientation(t_ilm_surface surfaceId,
2222 ilmOrientation orientation)
2224 ilmErrorTypes returnValue = ILM_FAILED;
2225 struct ilm_control_context *ctx = sync_and_acquire_instance();
2226 struct surface_context *ctx_surf = NULL;
2227 int32_t iviorientation = 0;
2230 switch(orientation) {
2232 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES;
2235 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES;
2237 case ILM_ONEHUNDREDEIGHTY:
2238 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES;
2240 case ILM_TWOHUNDREDSEVENTY:
2241 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES;
2244 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2248 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2249 if (ctx_surf == NULL) {
2250 returnValue = ILM_FAILED;
2254 ivi_controller_surface_set_orientation(ctx_surf->controller,
2257 returnValue = ILM_SUCCESS;
2264 ILM_EXPORT ilmErrorTypes
2265 ilm_surfaceGetOrientation(t_ilm_surface surfaceId,
2266 ilmOrientation *pOrientation)
2268 ilmErrorTypes returnValue = ILM_FAILED;
2269 struct ilm_control_context *ctx = sync_and_acquire_instance();
2271 if (pOrientation != NULL) {
2272 struct surface_context *ctx_surf = NULL;
2273 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2275 *pOrientation = ctx_surf->prop.orientation;
2276 returnValue = ILM_SUCCESS;
2284 ILM_EXPORT ilmErrorTypes
2285 ilm_surfaceGetPixelformat(t_ilm_layer surfaceId,
2286 ilmPixelFormat *pPixelformat)
2288 ilmErrorTypes returnValue = ILM_FAILED;
2289 struct ilm_control_context *ctx = sync_and_acquire_instance();
2291 if (pPixelformat != NULL) {
2292 struct surface_context *ctx_surf = NULL;
2293 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2295 *pPixelformat = ctx_surf->prop.pixelformat;
2296 returnValue = ILM_SUCCESS;
2304 ILM_EXPORT ilmErrorTypes
2305 ilm_surfaceSetChromaKey(t_ilm_surface surfaceId, t_ilm_int* pColor)
2313 ILM_EXPORT ilmErrorTypes
2314 ilm_displaySetRenderOrder(t_ilm_display display,
2315 t_ilm_layer *pLayerId, const t_ilm_uint number)
2317 ilmErrorTypes returnValue = ILM_FAILED;
2318 struct ilm_control_context *ctx = sync_and_acquire_instance();
2319 struct screen_context *ctx_scrn = NULL;
2321 ctx_scrn = get_screen_context_by_id(&ctx->wl, (uint32_t)display);
2322 if (ctx_scrn != NULL) {
2323 struct wl_array ids;
2324 wl_array_init(&ids);
2325 uint32_t *pids = wl_array_add(&ids, number * sizeof *pids);
2327 for (i = 0; i < number; i++) pids[i] = (uint32_t)pLayerId[i];
2328 ivi_controller_screen_set_render_order(ctx_scrn->controller, &ids);
2329 wl_array_release(&ids);
2330 returnValue = ILM_SUCCESS;
2337 ILM_EXPORT ilmErrorTypes
2338 ilm_takeScreenshot(t_ilm_uint screen, t_ilm_const_string filename)
2340 ilmErrorTypes returnValue = ILM_FAILED;
2341 struct ilm_control_context *ctx = sync_and_acquire_instance();
2342 struct screen_context *ctx_scrn = NULL;
2344 ctx_scrn = get_screen_context_by_id(&ctx->wl, (uint32_t)screen);
2345 if (ctx_scrn != NULL) {
2346 ivi_controller_screen_screenshot(ctx_scrn->controller,
2348 wl_display_flush(ctx->wl.display);
2349 returnValue = ILM_SUCCESS;
2356 ILM_EXPORT ilmErrorTypes
2357 ilm_takeLayerScreenshot(t_ilm_const_string filename, t_ilm_layer layerid)
2359 ilmErrorTypes returnValue = ILM_FAILED;
2360 struct ilm_control_context *ctx = sync_and_acquire_instance();
2361 struct layer_context *ctx_layer = NULL;
2363 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2364 &ctx->wl, (uint32_t)layerid);
2365 if (ctx_layer != NULL) {
2366 ivi_controller_layer_screenshot(ctx_layer->controller,
2368 wl_display_flush(ctx->wl.display);
2369 returnValue = ILM_SUCCESS;
2376 ILM_EXPORT ilmErrorTypes
2377 ilm_takeSurfaceScreenshot(t_ilm_const_string filename,
2378 t_ilm_surface surfaceid)
2380 ilmErrorTypes returnValue = ILM_FAILED;
2381 struct ilm_control_context *ctx = sync_and_acquire_instance();
2382 struct surface_context *ctx_surf = NULL;
2384 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceid);
2386 ivi_controller_surface_screenshot(ctx_surf->controller,
2388 wl_display_flush(ctx->wl.display);
2389 returnValue = ILM_SUCCESS;
2396 ILM_EXPORT ilmErrorTypes
2397 ilm_SetOptimizationMode(ilmOptimization id, ilmOptimizationMode mode)
2405 ILM_EXPORT ilmErrorTypes
2406 ilm_GetOptimizationMode(ilmOptimization id, ilmOptimizationMode* pMode)
2414 ILM_EXPORT ilmErrorTypes
2415 ilm_layerAddNotification(t_ilm_layer layer,
2416 layerNotificationFunc callback)
2418 ilmErrorTypes returnValue = ILM_FAILED;
2419 struct ilm_control_context *ctx = sync_and_acquire_instance();
2420 struct layer_context *ctx_layer = NULL;
2422 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2423 &ctx->wl, (uint32_t)layer);
2424 if (ctx_layer == NULL) {
2425 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2427 ctx_layer->notification = callback;
2429 returnValue = ILM_SUCCESS;
2436 ILM_EXPORT ilmErrorTypes
2437 ilm_layerRemoveNotification(t_ilm_layer layer)
2439 return ilm_layerAddNotification(layer, NULL);
2442 ILM_EXPORT ilmErrorTypes
2443 ilm_surfaceAddNotification(t_ilm_surface surface,
2444 surfaceNotificationFunc callback)
2446 ilmErrorTypes returnValue = ILM_FAILED;
2447 struct ilm_control_context *ctx = sync_and_acquire_instance();
2448 struct surface_context *ctx_surf = NULL;
2450 ctx_surf = (struct surface_context*)get_surface_context(
2451 &ctx->wl, (uint32_t)surface);
2452 if (ctx_surf == NULL) {
2453 if (callback != NULL) {
2454 callback((uint32_t)surface, NULL, ILM_NOTIFICATION_CONTENT_REMOVED);
2455 controller_listener_surface(ctx, ctx->wl.controller, (uint32_t)surface);
2456 ctx_surf = (struct surface_context*)get_surface_context(
2457 &ctx->wl, (uint32_t)surface);
2458 ctx_surf->is_surface_creation_noticed = false;
2462 if (ctx_surf == NULL) {
2463 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2466 ctx_surf->notification = callback;
2468 returnValue = ILM_SUCCESS;
2475 ILM_EXPORT ilmErrorTypes
2476 ilm_surfaceRemoveNotification(t_ilm_surface surface)
2478 return ilm_surfaceAddNotification(surface, NULL);
2481 ILM_EXPORT ilmErrorTypes
2482 ilm_getNativeHandle(t_ilm_uint pid, t_ilm_int *n_handle,
2483 t_ilm_nativehandle **p_handles)
2485 struct ilm_control_context *ctx = sync_and_acquire_instance();
2486 struct nativehandle_context *p_nh_ctx = NULL;
2491 wl_list_for_each(p_nh_ctx, &ctx->list_nativehandle, link)
2493 if (p_nh_ctx->pid == pid)
2497 (t_ilm_nativehandle*)malloc(sizeof(t_ilm_nativehandle));
2498 (*p_handles)[0] = p_nh_ctx->nativehandle;
2504 return (*n_handle > 0) ? ILM_SUCCESS : ILM_FAILED;
2507 ILM_EXPORT ilmErrorTypes
2508 ilm_getPropertiesOfSurface(t_ilm_uint surfaceID,
2509 struct ilmSurfaceProperties* pSurfaceProperties)
2511 ilmErrorTypes returnValue = ILM_FAILED;
2512 struct ilm_control_context *ctx = sync_and_acquire_instance();
2514 if (pSurfaceProperties != NULL) {
2515 struct surface_context *ctx_surf = NULL;
2517 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceID);
2518 if (ctx_surf != NULL) {
2520 *pSurfaceProperties = ctx_surf->prop;
2521 returnValue = ILM_SUCCESS;
2529 ILM_EXPORT ilmErrorTypes
2530 ilm_layerAddSurface(t_ilm_layer layerId,
2531 t_ilm_surface surfaceId)
2533 ilmErrorTypes returnValue = ILM_FAILED;
2534 struct ilm_control_context *ctx = sync_and_acquire_instance();
2535 struct layer_context *ctx_layer = NULL;
2536 struct surface_context *ctx_surf = NULL;
2538 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2539 &ctx->wl, (uint32_t)layerId);
2540 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2541 if ((ctx_layer != NULL) && (ctx_surf != NULL)) {
2542 ivi_controller_layer_add_surface(ctx_layer->controller,
2543 ctx_surf->controller);
2544 returnValue = ILM_SUCCESS;
2551 ILM_EXPORT ilmErrorTypes
2552 ilm_layerRemoveSurface(t_ilm_layer layerId,
2553 t_ilm_surface surfaceId)
2555 ilmErrorTypes returnValue = ILM_FAILED;
2556 struct ilm_control_context *ctx = sync_and_acquire_instance();
2557 struct layer_context *ctx_layer = NULL;
2558 struct surface_context *ctx_surf = NULL;
2560 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2561 &ctx->wl, (uint32_t)layerId);
2562 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2563 if ((ctx_layer != NULL) && (ctx_surf != NULL)) {
2564 ivi_controller_layer_remove_surface(ctx_layer->controller,
2565 ctx_surf->controller);
2566 returnValue = ILM_SUCCESS;
2573 ILM_EXPORT ilmErrorTypes
2574 ilm_surfaceGetDimension(t_ilm_surface surfaceId,
2575 t_ilm_uint *pDimension)
2577 ilmErrorTypes returnValue = ILM_FAILED;
2578 struct ilm_control_context *ctx = sync_and_acquire_instance();
2580 if (pDimension != NULL) {
2581 struct surface_context *ctx_surf = NULL;
2583 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2584 if (ctx_surf != NULL) {
2585 *pDimension = (t_ilm_uint)ctx_surf->prop.destWidth;
2586 *(pDimension + 1) = (t_ilm_uint)ctx_surf->prop.destHeight;
2587 returnValue = ILM_SUCCESS;
2595 ILM_EXPORT ilmErrorTypes
2596 ilm_surfaceGetVisibility(t_ilm_surface surfaceId,
2597 t_ilm_bool *pVisibility)
2599 ilmErrorTypes returnValue = ILM_FAILED;
2600 struct ilm_control_context *ctx = sync_and_acquire_instance();
2601 struct surface_context *ctx_surf = NULL;
2603 if (pVisibility != NULL) {
2604 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2605 if (ctx_surf != NULL) {
2606 *pVisibility = (t_ilm_bool)ctx_surf->prop.visibility;
2607 returnValue = ILM_SUCCESS;
2615 ILM_EXPORT ilmErrorTypes
2616 ilm_surfaceSetSourceRectangle(t_ilm_surface surfaceId,
2617 t_ilm_int x, t_ilm_int y,
2618 t_ilm_int width, t_ilm_int height)
2620 ilmErrorTypes returnValue = ILM_FAILED;
2621 struct ilm_control_context *ctx = sync_and_acquire_instance();
2622 struct surface_context *ctx_surf = NULL;
2624 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2625 if (ctx_surf != NULL) {
2626 if (ctx_surf->controller != NULL) {
2627 ivi_controller_surface_set_source_rectangle(
2628 ctx_surf->controller,
2629 x, y, width, height);
2630 returnValue = ILM_SUCCESS;
2638 ILM_EXPORT ilmErrorTypes
2639 ilm_commitChanges(void)
2641 ilmErrorTypes returnValue = ILM_FAILED;
2642 struct ilm_control_context *ctx = sync_and_acquire_instance();
2644 if (ctx->wl.controller != NULL) {
2645 ivi_controller_commit_changes(ctx->wl.controller);
2647 if (display_roundtrip_queue(ctx->wl.display, ctx->wl.queue) != -1)
2649 returnValue = ILM_SUCCESS;