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 struct ilm_control_context* sync_and_acquire_instance(void);
172 static struct surface_context* get_surface_context(struct wayland_context *, uint32_t);
174 static void release_instance(void);
176 static int create_controller_layer(struct wayland_context *ctx, t_ilm_uint width, t_ilm_uint height, t_ilm_layer layerid);
179 wayland_controller_is_inside_surface_list(struct wl_list *list,
182 struct surface_context *ctx_surf = NULL;
183 wl_list_for_each(ctx_surf, list, link) {
184 if (ctx_surf->id_surface == id_surface) {
193 wayland_controller_is_inside_layer_list(struct wl_list *list,
196 struct layer_context *ctx_layer = NULL;
197 wl_list_for_each(ctx_layer, list, link) {
198 if (ctx_layer->id_layer == id_layer) {
206 static struct layer_context*
207 wayland_controller_get_layer_context(struct wayland_context *ctx,
210 struct layer_context *ctx_layer = NULL;
212 if (ctx->controller == NULL) {
213 fprintf(stderr, "controller is not initialized in ilmControl\n");
217 wl_list_for_each(ctx_layer, &ctx->list_layer, link) {
218 if (ctx_layer->id_layer == id_layer) {
223 fprintf(stderr, "failed to get layer context in ilmControl\n");
228 output_listener_geometry(void *data,
229 struct wl_output *output,
232 int32_t physical_width,
233 int32_t physical_height,
249 output_listener_mode(void *data,
250 struct wl_output *output,
263 if (flags & WL_OUTPUT_MODE_CURRENT)
265 struct screen_context *ctx_scrn = data;
266 ctx_scrn->prop.screenWidth = width;
267 ctx_scrn->prop.screenHeight = height;
272 output_listener_done(void *data,
273 struct wl_output *output)
280 output_listener_scale(void *data,
281 struct wl_output *output,
289 static struct wl_output_listener output_listener = {
290 output_listener_geometry,
291 output_listener_mode,
292 output_listener_done,
293 output_listener_scale
296 static struct screen_context*
297 get_screen_context_by_output(struct wayland_context *ctx,
298 struct wl_output *output)
300 struct screen_context *ctx_scrn = NULL;
301 struct wl_proxy *pxy_out = NULL;
302 struct wl_proxy *pxy_out_in_scrn = NULL;
304 uint32_t pxy_id_in_scrn = 0;
306 wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
307 pxy_out = (struct wl_proxy*)output;
308 pxy_out_in_scrn = (struct wl_proxy*)ctx_scrn->output;
309 pxy_id = wl_proxy_get_id(pxy_out);
310 pxy_id_in_scrn = wl_proxy_get_id(pxy_out_in_scrn);
311 if (pxy_id == pxy_id_in_scrn) {
318 static struct screen_context*
319 get_screen_context_by_serverid(struct wayland_context *ctx,
322 struct screen_context *ctx_scrn = NULL;
324 wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
325 if (ctx_scrn->id_from_server == id_screen) {
333 add_orderlayer_to_screen(struct layer_context *ctx_layer,
334 struct wl_output* output)
336 struct screen_context *ctx_scrn = NULL;
338 ctx_scrn = get_screen_context_by_output(ctx_layer->ctx, output);
339 if (ctx_scrn == NULL) {
340 fprintf(stderr, "failed to add_orderlayer_to_screen\n");
345 struct layer_context *layer_link;
346 wl_list_for_each(layer_link, &ctx_scrn->order.list_layer, order.link) {
347 if (layer_link == ctx_layer) {
354 wl_list_init(&ctx_layer->order.link);
355 wl_list_insert(&ctx_scrn->order.list_layer, &ctx_layer->order.link);
360 remove_orderlayer_from_screen(struct layer_context *ctx_layer)
362 wl_list_remove(&ctx_layer->order.link);
363 wl_list_init(&ctx_layer->order.link);
367 controller_layer_listener_visibility(void *data,
368 struct ivi_controller_layer *controller,
371 struct layer_context *ctx_layer = data;
373 ctx_layer->prop.visibility = (t_ilm_bool)visibility;
375 if (ctx_layer->notification != NULL) {
376 ctx_layer->notification(ctx_layer->id_layer,
378 ILM_NOTIFICATION_VISIBILITY);
383 controller_layer_listener_opacity(void *data,
384 struct ivi_controller_layer *controller,
387 struct layer_context *ctx_layer = data;
389 ctx_layer->prop.opacity = (t_ilm_float)wl_fixed_to_double(opacity);
391 if (ctx_layer->notification != NULL) {
392 ctx_layer->notification(ctx_layer->id_layer,
394 ILM_NOTIFICATION_OPACITY);
399 controller_layer_listener_source_rectangle(void *data,
400 struct ivi_controller_layer *controller,
406 struct layer_context *ctx_layer = data;
408 ctx_layer->prop.sourceX = (t_ilm_uint)x;
409 ctx_layer->prop.sourceY = (t_ilm_uint)y;
410 ctx_layer->prop.sourceWidth = (t_ilm_uint)width;
411 ctx_layer->prop.sourceHeight = (t_ilm_uint)height;
412 if (ctx_layer->prop.origSourceWidth == 0) {
413 ctx_layer->prop.origSourceWidth = (t_ilm_uint)width;
415 if (ctx_layer->prop.origSourceHeight == 0) {
416 ctx_layer->prop.origSourceHeight = (t_ilm_uint)height;
419 if (ctx_layer->notification != NULL) {
420 ctx_layer->notification(ctx_layer->id_layer,
422 ILM_NOTIFICATION_SOURCE_RECT);
427 controller_layer_listener_destination_rectangle(void *data,
428 struct ivi_controller_layer *controller,
434 struct layer_context *ctx_layer = data;
436 ctx_layer->prop.destX = (t_ilm_uint)x;
437 ctx_layer->prop.destY = (t_ilm_uint)y;
438 ctx_layer->prop.destWidth = (t_ilm_uint)width;
439 ctx_layer->prop.destHeight = (t_ilm_uint)height;
441 if (ctx_layer->notification != NULL) {
442 ctx_layer->notification(ctx_layer->id_layer,
444 ILM_NOTIFICATION_DEST_RECT);
449 controller_layer_listener_configuration(void *data,
450 struct ivi_controller_layer *controller,
454 struct layer_context *ctx_layer = data;
456 ctx_layer->prop.sourceWidth = (t_ilm_uint)width;
457 ctx_layer->prop.sourceHeight = (t_ilm_uint)height;
461 controller_layer_listener_orientation(void *data,
462 struct ivi_controller_layer *controller,
465 ilmOrientation ilmorientation = ILM_ZERO;
466 struct layer_context *ctx_layer = data;
468 switch(orientation) {
469 case IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES:
470 ilmorientation = ILM_ZERO;
472 case IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES:
473 ilmorientation = ILM_NINETY;
475 case IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES:
476 ilmorientation = ILM_ONEHUNDREDEIGHTY;
478 case IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES:
479 ilmorientation = ILM_TWOHUNDREDSEVENTY;
485 ctx_layer->prop.orientation = ilmorientation;
487 if (ctx_layer->notification != NULL) {
488 ctx_layer->notification(ctx_layer->id_layer,
490 ILM_NOTIFICATION_ORIENTATION);
495 controller_layer_listener_screen(void *data,
496 struct ivi_controller_layer *controller,
497 struct wl_output *output)
499 struct layer_context *ctx_layer = data;
501 if (output == NULL) {
502 remove_orderlayer_from_screen(ctx_layer);
504 add_orderlayer_to_screen(ctx_layer, output);
509 controller_layer_listener_destroyed(void *data,
510 struct ivi_controller_layer *controller)
512 struct layer_context *ctx_layer = data;
513 wl_list_remove(&ctx_layer->link);
517 static struct ivi_controller_layer_listener controller_layer_listener =
519 controller_layer_listener_visibility,
520 controller_layer_listener_opacity,
521 controller_layer_listener_source_rectangle,
522 controller_layer_listener_destination_rectangle,
523 controller_layer_listener_configuration,
524 controller_layer_listener_orientation,
525 controller_layer_listener_screen,
526 controller_layer_listener_destroyed
530 add_ordersurface_to_layer(struct surface_context *ctx_surf,
531 struct ivi_controller_layer *layer)
533 struct layer_context *ctx_layer = NULL;
534 struct surface_context *link = NULL;
537 ctx_layer = ivi_controller_layer_get_user_data(layer);
539 wl_list_for_each(link, &ctx_layer->order.list_surface, order.link) {
540 if (link == ctx_surf) {
547 wl_list_init(&ctx_surf->order.link);
548 wl_list_insert(&ctx_layer->order.list_surface, &ctx_surf->order.link);
553 remove_ordersurface_from_layer(struct surface_context *ctx_surf)
555 wl_list_remove(&ctx_surf->order.link);
556 wl_list_init(&ctx_surf->order.link);
560 controller_surface_listener_visibility(void *data,
561 struct ivi_controller_surface *controller,
564 struct surface_context *ctx_surf = data;
566 ctx_surf->prop.visibility = (t_ilm_bool)visibility;
568 if (ctx_surf->notification != NULL) {
569 ctx_surf->notification(ctx_surf->id_surface,
571 ILM_NOTIFICATION_VISIBILITY);
576 controller_surface_listener_opacity(void *data,
577 struct ivi_controller_surface *controller,
580 struct surface_context *ctx_surf = data;
582 ctx_surf->prop.opacity = (t_ilm_float)wl_fixed_to_double(opacity);
584 if (ctx_surf->notification != NULL) {
585 ctx_surf->notification(ctx_surf->id_surface,
587 ILM_NOTIFICATION_OPACITY);
592 controller_surface_listener_configuration(void *data,
593 struct ivi_controller_surface *controller,
597 struct surface_context *ctx_surf = data;
599 ctx_surf->prop.sourceWidth = (t_ilm_uint)width;
600 ctx_surf->prop.sourceHeight = (t_ilm_uint)height;
604 controller_surface_listener_source_rectangle(void *data,
605 struct ivi_controller_surface *controller,
611 struct surface_context *ctx_surf = data;
613 ctx_surf->prop.sourceX = (t_ilm_uint)x;
614 ctx_surf->prop.sourceY = (t_ilm_uint)y;
615 ctx_surf->prop.sourceWidth = (t_ilm_uint)width;
616 ctx_surf->prop.sourceHeight = (t_ilm_uint)height;
617 if (ctx_surf->prop.origSourceWidth == 0) {
618 ctx_surf->prop.origSourceWidth = (t_ilm_uint)width;
620 if (ctx_surf->prop.origSourceHeight == 0) {
621 ctx_surf->prop.origSourceHeight = (t_ilm_uint)height;
624 if (ctx_surf->notification != NULL) {
625 ctx_surf->notification(ctx_surf->id_surface,
627 ILM_NOTIFICATION_SOURCE_RECT);
632 controller_surface_listener_destination_rectangle(void *data,
633 struct ivi_controller_surface *controller,
639 struct surface_context *ctx_surf = data;
641 ctx_surf->prop.destX = (t_ilm_uint)x;
642 ctx_surf->prop.destY = (t_ilm_uint)y;
643 ctx_surf->prop.destWidth = (t_ilm_uint)width;
644 ctx_surf->prop.destHeight = (t_ilm_uint)height;
646 if (ctx_surf->notification != NULL) {
647 ctx_surf->notification(ctx_surf->id_surface,
649 ILM_NOTIFICATION_DEST_RECT);
654 controller_surface_listener_orientation(void *data,
655 struct ivi_controller_surface *controller,
658 struct surface_context *ctx_surf = data;
659 ilmOrientation ilmorientation = ILM_ZERO;
661 switch (orientation) {
662 case IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES:
663 ilmorientation = ILM_ZERO;
665 case IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES:
666 ilmorientation = ILM_NINETY;
668 case IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES:
669 ilmorientation = ILM_ONEHUNDREDEIGHTY;
671 case IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES:
672 ilmorientation = ILM_TWOHUNDREDSEVENTY;
678 ctx_surf->prop.orientation = ilmorientation;
680 if (ctx_surf->notification != NULL) {
681 ctx_surf->notification(ctx_surf->id_surface,
683 ILM_NOTIFICATION_ORIENTATION);
688 controller_surface_listener_pixelformat(void *data,
689 struct ivi_controller_surface *controller,
692 struct surface_context *ctx_surf = data;
694 ctx_surf->prop.pixelformat = (t_ilm_uint)pixelformat;
698 controller_surface_listener_layer(void *data,
699 struct ivi_controller_surface *controller,
700 struct ivi_controller_layer *layer)
702 struct surface_context *ctx_surf = data;
705 remove_ordersurface_from_layer(ctx_surf);
707 add_ordersurface_to_layer(ctx_surf, layer);
712 controller_surface_listener_stats(void *data,
713 struct ivi_controller_surface *controller,
714 uint32_t redraw_count,
715 uint32_t frame_count,
716 uint32_t update_count,
718 const char *process_name)
720 struct surface_context *ctx_surf = data;
723 ctx_surf->prop.drawCounter = (t_ilm_uint)redraw_count;
724 ctx_surf->prop.frameCounter = (t_ilm_uint)frame_count;
725 ctx_surf->prop.updateCounter = (t_ilm_uint)update_count;
726 ctx_surf->prop.creatorPid = (t_ilm_uint)pid;
730 controller_surface_listener_destroyed(void *data,
731 struct ivi_controller_surface *controller)
733 struct surface_context *ctx_surf = data;
735 if (ctx_surf->notification != NULL) {
736 ctx_surf->notification(ctx_surf->id_surface,
738 ILM_NOTIFICATION_CONTENT_REMOVED);
741 wl_list_remove(&ctx_surf->link);
746 controller_surface_listener_content(void *data,
747 struct ivi_controller_surface *controller,
748 int32_t content_state)
750 struct surface_context *ctx_surf = data;
752 // if client surface (=content) was removed with ilm_surfaceDestroy()
753 // the expected behavior within ILM API mandates a full removal
754 // of the surface from the scene. We must remove the controller
756 if (IVI_CONTROLLER_SURFACE_CONTENT_STATE_CONTENT_REMOVED == content_state)
758 if (ctx_surf->notification != NULL) {
759 ctx_surf->notification(ctx_surf->id_surface,
761 ILM_NOTIFICATION_CONTENT_REMOVED);
764 ivi_controller_surface_destroy(controller, 1);
766 wl_list_remove(&ctx_surf->link);
769 else if (IVI_CONTROLLER_SURFACE_CONTENT_STATE_CONTENT_AVAILABLE == content_state)
771 if (ctx_surf->notification != NULL) {
772 ctx_surf->notification(ctx_surf->id_surface,
774 ILM_NOTIFICATION_CONTENT_AVAILABLE);
780 controller_surface_listener_input_focus(void *data,
781 struct ivi_controller_surface *controller,
791 static struct ivi_controller_surface_listener controller_surface_listener=
793 controller_surface_listener_visibility,
794 controller_surface_listener_opacity,
795 controller_surface_listener_source_rectangle,
796 controller_surface_listener_destination_rectangle,
797 controller_surface_listener_configuration,
798 controller_surface_listener_orientation,
799 controller_surface_listener_pixelformat,
800 controller_surface_listener_layer,
801 controller_surface_listener_stats,
802 controller_surface_listener_destroyed,
803 controller_surface_listener_content,
804 controller_surface_listener_input_focus
808 controller_listener_layer(void *data,
809 struct ivi_controller *controller,
812 struct wayland_context *ctx = data;
814 if (wayland_controller_is_inside_layer_list(&ctx->list_layer, id_layer))
819 (void) create_controller_layer(ctx, 0, 0, id_layer);
823 controller_listener_surface(void *data,
824 struct ivi_controller *controller,
827 struct wayland_context *ctx = data;
828 struct surface_context *ctx_surf = NULL;
830 ctx_surf = get_surface_context(ctx, id_surface);
831 if (ctx_surf != NULL) {
832 if (!ctx_surf->is_surface_creation_noticed) {
833 if (ctx_surf->notification != NULL) {
834 ctx_surf->notification(ctx_surf->id_surface,
836 ILM_NOTIFICATION_CONTENT_AVAILABLE);
837 ctx_surf->is_surface_creation_noticed = true;
839 ctx_surf->controller = ivi_controller_surface_create(
840 controller, id_surface);
843 fprintf(stderr, "invalid id_surface in controller_listener_surface\n");
848 ctx_surf = calloc(1, sizeof *ctx_surf);
849 if (ctx_surf == NULL) {
850 fprintf(stderr, "Failed to allocate memory for surface_context\n");
854 ctx_surf->controller = ivi_controller_surface_create(
855 controller, id_surface);
856 if (ctx_surf->controller == NULL) {
858 fprintf(stderr, "Failed to create controller surface\n");
861 ctx_surf->id_surface = id_surface;
862 ctx_surf->prop.inputDevicesAcceptance = ILM_INPUT_DEVICE_ALL;
864 ctx_surf->is_surface_creation_noticed = true;
866 wl_list_init(&ctx_surf->link);
867 wl_list_insert(&ctx->list_surface, &ctx_surf->link);
868 wl_list_init(&ctx_surf->order.link);
869 ivi_controller_surface_add_listener(ctx_surf->controller,
870 &controller_surface_listener, ctx_surf);
874 controller_listener_error(void *data,
875 struct ivi_controller *ivi_controller,
879 const char *error_text)
882 (void)ivi_controller;
890 controller_listener_screen(void *data,
891 struct ivi_controller *ivi_controller,
893 struct ivi_controller_screen *controller_screen)
895 struct wayland_context *ctx = data;
896 struct screen_context *ctx_screen;
897 (void)ivi_controller;
899 ctx_screen = get_screen_context_by_serverid(ctx, id_screen);
900 if (ctx_screen == NULL) {
901 fprintf(stderr, "Failed to allocate memory for screen_context\n");
904 ctx_screen->controller = controller_screen;
907 static struct ivi_controller_listener controller_listener= {
908 controller_listener_screen,
909 controller_listener_layer,
910 controller_listener_surface,
911 controller_listener_error
915 registry_handle_control(void *data,
916 struct wl_registry *registry,
917 uint32_t name, const char *interface,
920 struct wayland_context *ctx = data;
923 if (strcmp(interface, "ivi_controller") == 0) {
924 ctx->controller = wl_registry_bind(registry, name,
925 &ivi_controller_interface, 1);
926 if (ctx->controller == NULL) {
927 fprintf(stderr, "Failed to registry bind ivi_controller\n");
930 if (ivi_controller_add_listener(ctx->controller,
931 &controller_listener,
933 fprintf(stderr, "Failed to add ivi_controller listener\n");
936 } else if (strcmp(interface, "wl_output") == 0) {
938 struct screen_context *ctx_scrn = calloc(1, sizeof *ctx_scrn);
939 struct wl_proxy *pxy = NULL;
941 if (ctx_scrn == NULL) {
942 fprintf(stderr, "Failed to allocate memory for screen_context\n");
945 wl_list_init(&ctx_scrn->link);
946 ctx_scrn->output = wl_registry_bind(registry, name,
947 &wl_output_interface, 1);
948 if (ctx_scrn->output == NULL) {
950 fprintf(stderr, "Failed to registry bind wl_output\n");
954 if (wl_output_add_listener(ctx_scrn->output,
958 fprintf(stderr, "Failed to add wl_output listener\n");
962 pxy = (struct wl_proxy*)ctx_scrn->output;
963 ctx_scrn->id_from_server = wl_proxy_get_id(pxy);
964 ctx_scrn->id_screen = ctx->num_screen;
966 wl_list_init(&ctx_scrn->order.list_layer);
967 wl_list_insert(&ctx->list_screen, &ctx_scrn->link);
971 static const struct wl_registry_listener
972 registry_control_listener= {
973 registry_handle_control,
977 static struct ilm_control_context ilm_context;
979 static void destroy_control_resources(void)
981 struct ilm_control_context *ctx = &ilm_context;
983 if (ctx->wl.controller != NULL) {
985 struct surface_context *l;
986 struct surface_context *n;
987 wl_list_for_each_safe(l, n, &ctx->wl.list_surface, link) {
988 wl_list_remove(&l->link);
989 wl_list_remove(&l->order.link);
990 ivi_controller_surface_destroy(l->controller, 0);
996 struct layer_context *l;
997 struct layer_context *n;
998 wl_list_for_each_safe(l, n, &ctx->wl.list_layer, link) {
999 wl_list_remove(&l->link);
1000 wl_list_remove(&l->order.link);
1006 struct screen_context *ctx_scrn;
1007 struct screen_context *next;
1009 wl_list_for_each_safe(ctx_scrn, next, &ctx->wl.list_screen, link) {
1010 if (ctx_scrn->output != NULL) {
1011 wl_output_destroy(ctx_scrn->output);
1014 wl_list_remove(&ctx_scrn->link);
1015 ivi_controller_screen_destroy(ctx_scrn->controller);
1020 ivi_controller_destroy(ctx->wl.controller);
1021 ctx->wl.controller = NULL;
1024 wl_display_flush(ctx->wl.display);
1026 wl_event_queue_destroy(ctx->wl.queue);
1027 ctx->wl.queue = NULL;
1029 wl_registry_destroy(ctx->wl.registry);
1030 ctx->wl.registry = NULL;
1032 if (0 != pthread_mutex_destroy(&ctx->mutex)) {
1033 fprintf(stderr, "failed to destroy pthread_mutex\n");
1037 static void send_shutdown_event(struct ilm_control_context *ctx)
1040 while (write(ctx->shutdown_fd, &buf, sizeof buf) == -1 && errno == EINTR)
1045 ilmControl_destroy(void)
1047 struct ilm_control_context *ctx = &ilm_context;
1049 send_shutdown_event(ctx);
1051 if (0 != pthread_join(ctx->thread, NULL)) {
1052 fprintf(stderr, "failed to join control thread\n");
1055 destroy_control_resources();
1057 close(ctx->shutdown_fd);
1059 memset(ctx, 0, sizeof *ctx);
1062 ILM_EXPORT ilmErrorTypes
1063 ilmControl_init(t_ilm_nativedisplay nativedisplay)
1065 struct ilm_control_context *ctx = &ilm_context;
1067 if (ctx->initialized)
1069 fprintf(stderr, "Already initialized!\n");
1073 if (nativedisplay == 0) {
1074 return ILM_ERROR_INVALID_ARGUMENTS;
1077 memset(ctx, 0, sizeof *ctx);
1079 ctx->wl.display = (struct wl_display*)nativedisplay;
1081 wl_list_init(&ctx->wl.list_screen);
1082 wl_list_init(&ctx->wl.list_layer);
1083 wl_list_init(&ctx->wl.list_surface);
1086 pthread_mutexattr_t a;
1087 if (pthread_mutexattr_init(&a) != 0)
1092 if (pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE) != 0)
1094 pthread_mutexattr_destroy(&a);
1098 if (pthread_mutex_init(&ctx->mutex, &a) != 0)
1100 pthread_mutexattr_destroy(&a);
1101 fprintf(stderr, "failed to initialize pthread_mutex\n");
1105 pthread_mutexattr_destroy(&a);
1108 ctx->shutdown_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
1110 if (ctx->shutdown_fd == -1)
1112 fprintf(stderr, "Could not setup shutdown-fd: %s\n", strerror(errno));
1116 return init_control() == 0 ? ILM_SUCCESS : ILM_FAILED;
1120 control_thread(void *p_ret)
1122 struct ilm_control_context *const ctx = &ilm_context;
1123 struct wayland_context *const wl = &ctx->wl;
1124 struct wl_display *const display = wl->display;
1125 struct wl_event_queue *const queue = wl->queue;
1126 int const fd = wl_display_get_fd(display);
1127 int const shutdown_fd = ctx->shutdown_fd;
1132 while (wl_display_prepare_read_queue(display, queue) != 0)
1135 wl_display_dispatch_queue_pending(display, queue);
1136 unlock_context(ctx);
1139 if (wl_display_flush(display) == -1)
1144 struct pollfd pfd[2] = {
1145 { .fd = fd, .events = POLLIN },
1146 { .fd = shutdown_fd, .events = POLLIN }
1149 int pollret = poll(pfd, 2, -1);
1150 if (pollret != -1 && (pfd[0].revents & POLLIN))
1152 wl_display_read_events(display);
1155 int ret = wl_display_dispatch_queue_pending(display, queue);
1156 unlock_context(ctx);
1165 wl_display_cancel_read(display);
1167 if (pollret == -1 || (pfd[1].revents & POLLIN))
1180 struct ilm_control_context *ctx = &ilm_context;
1181 struct wayland_context *wl = &ctx->wl;
1185 wl_list_init(&ctx->list_nativehandle);
1187 wl->queue = wl_display_create_queue(wl->display);
1189 /* registry_add_listener for request by ivi-controller */
1190 wl->registry = wl_display_get_registry(wl->display);
1191 if (wl->registry == NULL) {
1192 wl_event_queue_destroy(wl->queue);
1194 fprintf(stderr, "Failed to get registry\n");
1197 wl_proxy_set_queue((void*)wl->registry, wl->queue);
1199 if (wl_registry_add_listener(wl->registry,
1200 ®istry_control_listener, ctx)) {
1201 fprintf(stderr, "Failed to add registry listener\n");
1205 // first level objects; ivi_controller
1206 display_roundtrip_queue(wl->display, wl->queue);
1207 // second level object: ivi_controller_surfaces/layers
1208 display_roundtrip_queue(wl->display, wl->queue);
1209 // third level objects: ivi_controller_surfaces/layers properties
1210 display_roundtrip_queue(wl->display, wl->queue);
1212 ret = pthread_create(&ctx->thread, NULL, control_thread, NULL);
1215 fprintf(stderr, "Failed to start internal receive thread. returned %d\n", ret);
1219 ctx->initialized = true;
1224 #define sync_and_acquire_instance() ({ \
1225 struct ilm_control_context *ctx = &ilm_context; \
1226 if (! ctx->initialized) { \
1227 fputs("Not initialized\n", stderr); \
1228 return ILM_FAILED; \
1230 lock_context(ctx); \
1231 display_roundtrip_queue(ctx->wl.display, ctx->wl.queue); \
1235 static void release_instance(void)
1237 struct ilm_control_context *ctx = &ilm_context;
1238 unlock_context(ctx);
1242 gen_layer_id(struct ilm_control_context *ctx)
1244 struct layer_context *ctx_layer = NULL;
1247 if (wl_list_length(&ctx->wl.list_layer) == 0) {
1248 ctx->internal_id_layer++;
1249 return ctx->internal_id_layer;
1251 wl_list_for_each(ctx_layer, &ctx->wl.list_layer, link) {
1252 if (ctx_layer->id_layer == ctx->internal_id_layer) {
1258 return ctx->internal_id_layer;
1261 ctx->internal_id_layer++;
1265 static struct surface_context*
1266 get_surface_context(struct wayland_context *ctx,
1267 uint32_t id_surface)
1269 struct surface_context *ctx_surf = NULL;
1271 if (ctx->controller == NULL) {
1272 fprintf(stderr, "controller is not initialized in ilmControl\n");
1276 wl_list_for_each(ctx_surf, &ctx->list_surface, link) {
1277 if (ctx_surf->id_surface == id_surface) {
1282 fprintf(stderr, "failed to get surface context in ilmControl\n");
1286 static struct screen_context*
1287 get_screen_context_by_id(struct wayland_context *ctx, uint32_t id_screen)
1289 struct screen_context *ctx_scrn = NULL;
1291 if (ctx->controller == NULL) {
1292 fprintf(stderr, "get_screen_context_by_id: controller is NULL\n");
1296 wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
1297 if (ctx_scrn->id_screen == id_screen) {
1304 ILM_EXPORT ilmErrorTypes
1305 ilm_getPropertiesOfLayer(t_ilm_uint layerID,
1306 struct ilmLayerProperties* pLayerProperties)
1308 ilmErrorTypes returnValue = ILM_FAILED;
1309 struct ilm_control_context *ctx = sync_and_acquire_instance();
1310 struct layer_context *ctx_layer = NULL;
1312 if (pLayerProperties != NULL) {
1314 ctx_layer = (struct layer_context*)
1315 wayland_controller_get_layer_context(
1316 &ctx->wl, (uint32_t)layerID);
1318 if (ctx_layer != NULL) {
1319 *pLayerProperties = ctx_layer->prop;
1320 returnValue = ILM_SUCCESS;
1329 create_layerids(struct screen_context *ctx_screen,
1330 t_ilm_layer **layer_ids, t_ilm_uint *layer_count)
1332 struct layer_context *ctx_layer = NULL;
1333 t_ilm_layer *ids = NULL;
1335 *layer_count = wl_list_length(&ctx_screen->order.list_layer);
1336 if (*layer_count == 0) {
1341 *layer_ids = malloc(*layer_count * sizeof(t_ilm_layer));
1342 if (*layer_ids == NULL) {
1343 fprintf(stderr, "memory insufficient for layerids\n");
1349 wl_list_for_each_reverse(ctx_layer, &ctx_screen->order.list_layer, order.link) {
1350 *ids = (t_ilm_layer)ctx_layer->id_layer;
1355 ILM_EXPORT ilmErrorTypes
1356 ilm_getPropertiesOfScreen(t_ilm_display screenID,
1357 struct ilmScreenProperties* pScreenProperties)
1359 ilmErrorTypes returnValue = ILM_FAILED;
1361 if (! pScreenProperties)
1363 return ILM_ERROR_INVALID_ARGUMENTS;
1366 struct ilm_control_context *ctx = sync_and_acquire_instance();
1368 struct screen_context *ctx_screen = NULL;
1369 ctx_screen = get_screen_context_by_id(&ctx->wl, (uint32_t)screenID);
1370 if (ctx_screen != NULL) {
1371 *pScreenProperties = ctx_screen->prop;
1372 create_layerids(ctx_screen, &pScreenProperties->layerIds,
1373 &pScreenProperties->layerCount);
1374 returnValue = ILM_SUCCESS;
1381 ILM_EXPORT ilmErrorTypes
1382 ilm_getNumberOfHardwareLayers(t_ilm_uint screenID,
1383 t_ilm_uint* pNumberOfHardwareLayers)
1387 if (pNumberOfHardwareLayers != NULL) {
1388 *pNumberOfHardwareLayers = 0;
1395 ILM_EXPORT ilmErrorTypes
1396 ilm_getScreenIDs(t_ilm_uint* pNumberOfIDs, t_ilm_uint** ppIDs)
1398 ilmErrorTypes returnValue = ILM_FAILED;
1399 struct ilm_control_context *ctx = sync_and_acquire_instance();
1401 if ((pNumberOfIDs != NULL) && (ppIDs != NULL)) {
1402 struct screen_context *ctx_scrn = NULL;
1403 t_ilm_uint length = wl_list_length(&ctx->wl.list_screen);
1406 *ppIDs = (t_ilm_uint*)malloc(length * sizeof **ppIDs);
1407 if (*ppIDs != NULL) {
1408 t_ilm_uint* ids = *ppIDs;
1409 wl_list_for_each(ctx_scrn, &ctx->wl.list_screen, link) {
1410 *ids = ctx_scrn->id_screen;
1413 *pNumberOfIDs = length;
1415 returnValue = ILM_SUCCESS;
1423 ILM_EXPORT ilmErrorTypes
1424 ilm_getLayerIDs(t_ilm_int* pLength, t_ilm_layer** ppArray)
1426 ilmErrorTypes returnValue = ILM_FAILED;
1427 struct ilm_control_context *ctx = sync_and_acquire_instance();
1429 if ((pLength != NULL) && (ppArray != NULL)) {
1430 struct layer_context *ctx_layer = NULL;
1431 t_ilm_uint length = wl_list_length(&ctx->wl.list_layer);
1434 *ppArray = (t_ilm_layer*)malloc(length * sizeof **ppArray);
1435 if (*ppArray != NULL) {
1436 // compositor sends layers in opposite order
1437 // write ids from back to front to turn them around
1438 t_ilm_layer* ids = *ppArray;
1439 wl_list_for_each_reverse(ctx_layer, &ctx->wl.list_layer, link)
1441 *ids = ctx_layer->id_layer;
1446 returnValue = ILM_SUCCESS;
1454 ILM_EXPORT ilmErrorTypes
1455 ilm_getLayerIDsOnScreen(t_ilm_uint screenId,
1457 t_ilm_layer** ppArray)
1459 ilmErrorTypes returnValue = ILM_FAILED;
1460 struct ilm_control_context *ctx = sync_and_acquire_instance();
1462 if ((pLength != NULL) && (ppArray != NULL)) {
1463 struct screen_context *ctx_screen = NULL;
1464 ctx_screen = get_screen_context_by_id(&ctx->wl, screenId);
1465 if (ctx_screen != NULL) {
1466 struct layer_context *ctx_layer = NULL;
1467 t_ilm_int length = wl_list_length(&ctx_screen->order.list_layer);
1471 *ppArray = (t_ilm_layer*)malloc(length * sizeof **ppArray);
1472 if (*ppArray != NULL) {
1473 // compositor sends layers in opposite order
1474 // write ids from back to front to turn them around
1475 t_ilm_layer* ids = *ppArray;
1476 wl_list_for_each_reverse(ctx_layer, &ctx_screen->order.list_layer, order.link)
1478 *ids = ctx_layer->id_layer;
1490 returnValue = ILM_SUCCESS;
1498 ILM_EXPORT ilmErrorTypes
1499 ilm_getSurfaceIDs(t_ilm_int* pLength, t_ilm_surface** ppArray)
1501 ilmErrorTypes returnValue = ILM_FAILED;
1502 struct ilm_control_context *ctx = sync_and_acquire_instance();
1504 if ((pLength != NULL) && (ppArray != NULL)) {
1505 struct surface_context *ctx_surf = NULL;
1506 t_ilm_uint length = wl_list_length(&ctx->wl.list_surface);
1509 *ppArray = (t_ilm_surface*)malloc(length * sizeof **ppArray);
1510 if (*ppArray != NULL) {
1511 t_ilm_surface* ids = *ppArray;
1512 wl_list_for_each_reverse(ctx_surf, &ctx->wl.list_surface, link) {
1513 *ids = ctx_surf->id_surface;
1518 returnValue = ILM_SUCCESS;
1526 ILM_EXPORT ilmErrorTypes
1527 ilm_getSurfaceIDsOnLayer(t_ilm_layer layer,
1529 t_ilm_surface** ppArray)
1531 struct ilm_control_context *ctx = sync_and_acquire_instance();
1532 struct layer_context *ctx_layer = NULL;
1533 struct surface_context *ctx_surf = NULL;
1534 t_ilm_uint length = 0;
1535 t_ilm_surface* ids = NULL;
1537 if ((pLength == NULL) || (ppArray == NULL)) {
1542 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1543 &ctx->wl, (uint32_t)layer);
1545 if (ctx_layer == NULL) {
1550 length = wl_list_length(&ctx_layer->order.list_surface);
1551 *ppArray = (t_ilm_surface*)malloc(length * sizeof **ppArray);
1552 if (*ppArray == NULL) {
1558 wl_list_for_each_reverse(ctx_surf, &ctx_layer->order.list_surface, order.link) {
1559 *ids = (t_ilm_surface)ctx_surf->id_surface;
1568 static int create_controller_layer(struct wayland_context *ctx, t_ilm_uint width, t_ilm_uint height, t_ilm_layer layerid)
1570 struct layer_context *ctx_layer = calloc(1, sizeof *ctx_layer);
1571 if (ctx_layer == NULL) {
1572 fprintf(stderr, "Failed to allocate memory for layer_context\n");
1576 ctx_layer->controller = ivi_controller_layer_create(
1578 layerid, width, height);
1579 if (ctx_layer->controller == NULL) {
1580 fprintf(stderr, "Failed to create layer\n");
1584 ctx_layer->id_layer = layerid;
1585 ctx_layer->ctx = ctx;
1587 wl_list_init(&ctx_layer->link);
1588 wl_list_insert(&ctx->list_layer, &ctx_layer->link);
1589 wl_list_init(&ctx_layer->order.link);
1590 wl_list_init(&ctx_layer->order.list_surface);
1592 ivi_controller_layer_add_listener(ctx_layer->controller,
1593 &controller_layer_listener, ctx_layer);
1598 ILM_EXPORT ilmErrorTypes
1599 ilm_layerCreateWithDimension(t_ilm_layer* pLayerId,
1603 ilmErrorTypes returnValue = ILM_FAILED;
1604 struct ilm_control_context *ctx = sync_and_acquire_instance();
1605 uint32_t layerid = 0;
1606 int32_t is_inside = 0;
1609 if (pLayerId == NULL) {
1613 if (*pLayerId != INVALID_ID) {
1614 /* Return failed, if layerid is already inside list_layer */
1615 is_inside = wayland_controller_is_inside_layer_list(
1616 &ctx->wl.list_layer, *pLayerId);
1617 if (0 != is_inside) {
1618 fprintf(stderr, "layerid=%d is already used.\n", *pLayerId);
1621 layerid = *pLayerId;
1624 /* Generate ID, if layerid is INVALID_ID */
1625 layerid = gen_layer_id(ctx);
1626 *pLayerId = layerid;
1629 if (create_controller_layer(&ctx->wl, width, height, layerid) == 0)
1631 returnValue = ILM_SUCCESS;
1639 ILM_EXPORT ilmErrorTypes
1640 ilm_layerRemove(t_ilm_layer layerId)
1642 ilmErrorTypes returnValue = ILM_FAILED;
1643 struct ilm_control_context *ctx = sync_and_acquire_instance();
1644 struct layer_context *ctx_layer = NULL;
1645 struct layer_context *ctx_next = NULL;
1647 wl_list_for_each_safe(ctx_layer, ctx_next,
1648 &ctx->wl.list_layer, link) {
1649 if (ctx_layer->id_layer == layerId) {
1650 ivi_controller_layer_destroy(ctx_layer->controller, 1);
1652 wl_list_remove(&ctx_layer->link);
1655 returnValue = ILM_SUCCESS;
1664 ILM_EXPORT ilmErrorTypes
1665 ilm_layerGetType(t_ilm_layer layerId, ilmLayerType* pLayerType)
1669 return ILM_ERROR_INVALID_ARGUMENTS;
1672 struct ilm_control_context *ctx = sync_and_acquire_instance();
1674 *pLayerType = wayland_controller_is_inside_layer_list(&ctx->wl.list_layer, layerId) ?
1675 ILM_LAYERTYPE_SOFTWARE2D :
1676 ILM_LAYERTYPE_UNKNOWN;
1679 return ILM_SUCCESS; // even if non existent?
1682 ILM_EXPORT ilmErrorTypes
1683 ilm_layerSetVisibility(t_ilm_layer layerId, t_ilm_bool newVisibility)
1685 ilmErrorTypes returnValue = ILM_FAILED;
1686 struct ilm_control_context *ctx = sync_and_acquire_instance();
1687 struct layer_context *ctx_layer = NULL;
1689 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1690 &ctx->wl, (uint32_t)layerId);
1692 if (ctx_layer != NULL) {
1693 uint32_t visibility = 0;
1694 if (newVisibility == ILM_TRUE) {
1697 ivi_controller_layer_set_visibility(ctx_layer->controller,
1699 returnValue = ILM_SUCCESS;
1706 ILM_EXPORT ilmErrorTypes
1707 ilm_layerGetVisibility(t_ilm_layer layerId, t_ilm_bool *pVisibility)
1709 ilmErrorTypes returnValue = ILM_FAILED;
1710 struct ilm_control_context *ctx = sync_and_acquire_instance();
1712 if (pVisibility != NULL) {
1713 struct layer_context *ctx_layer = NULL;
1715 ctx_layer = (struct layer_context*)
1716 wayland_controller_get_layer_context(
1717 &ctx->wl, (uint32_t)layerId);
1719 if (ctx_layer != NULL) {
1720 *pVisibility = ctx_layer->prop.visibility;
1721 returnValue = ILM_SUCCESS;
1729 ILM_EXPORT ilmErrorTypes
1730 ilm_layerSetOpacity(t_ilm_layer layerId, t_ilm_float opacity)
1732 ilmErrorTypes returnValue = ILM_FAILED;
1733 struct ilm_control_context *ctx = sync_and_acquire_instance();
1734 struct layer_context *ctx_layer = NULL;
1736 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1737 &ctx->wl, (uint32_t)layerId);
1739 if (ctx_layer != NULL) {
1740 wl_fixed_t opacity_fixed = wl_fixed_from_double((double)opacity);
1741 ivi_controller_layer_set_opacity(ctx_layer->controller,
1743 returnValue = ILM_SUCCESS;
1750 ILM_EXPORT ilmErrorTypes
1751 ilm_layerGetOpacity(t_ilm_layer layerId, t_ilm_float *pOpacity)
1753 ilmErrorTypes returnValue = ILM_FAILED;
1754 struct ilm_control_context *ctx = sync_and_acquire_instance();
1756 if (pOpacity != NULL) {
1757 struct layer_context *ctx_layer = NULL;
1759 ctx_layer = (struct layer_context*)
1760 wayland_controller_get_layer_context(
1761 &ctx->wl, (uint32_t)layerId);
1763 if (ctx_layer != NULL) {
1764 *pOpacity = ctx_layer->prop.opacity;
1765 returnValue = ILM_SUCCESS;
1773 ILM_EXPORT ilmErrorTypes
1774 ilm_layerSetSourceRectangle(t_ilm_layer layerId,
1775 t_ilm_uint x, t_ilm_uint y,
1776 t_ilm_uint width, t_ilm_uint height)
1778 ilmErrorTypes returnValue = ILM_FAILED;
1779 struct ilm_control_context *ctx = sync_and_acquire_instance();
1780 struct layer_context *ctx_layer = NULL;
1782 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1783 &ctx->wl, (uint32_t)layerId);
1785 if (ctx_layer != NULL) {
1786 ivi_controller_layer_set_source_rectangle(ctx_layer->controller,
1791 returnValue = ILM_SUCCESS;
1798 ILM_EXPORT ilmErrorTypes
1799 ilm_layerSetDestinationRectangle(t_ilm_layer layerId,
1800 t_ilm_int x, t_ilm_int y,
1801 t_ilm_int width, t_ilm_int height)
1803 ilmErrorTypes returnValue = ILM_FAILED;
1804 struct ilm_control_context *ctx = sync_and_acquire_instance();
1805 struct layer_context *ctx_layer = NULL;
1807 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1808 &ctx->wl, (uint32_t)layerId);
1809 if (ctx_layer != NULL) {
1810 ivi_controller_layer_set_destination_rectangle(
1811 ctx_layer->controller,
1812 (uint32_t)x, (uint32_t)y,
1815 returnValue = ILM_SUCCESS;
1822 ILM_EXPORT ilmErrorTypes
1823 ilm_layerGetDimension(t_ilm_layer layerId, t_ilm_uint *pDimension)
1825 ilmErrorTypes returnValue = ILM_FAILED;
1826 struct ilm_control_context *ctx = sync_and_acquire_instance();
1827 struct layer_context *ctx_layer = NULL;
1829 if (pDimension != NULL) {
1830 ctx_layer = (struct layer_context*)
1831 wayland_controller_get_layer_context(
1832 &ctx->wl, (uint32_t)layerId);
1833 if (ctx_layer != NULL) {
1834 *pDimension = ctx_layer->prop.destWidth;
1835 *(pDimension + 1) = ctx_layer->prop.destHeight;
1836 returnValue = ILM_SUCCESS;
1844 ILM_EXPORT ilmErrorTypes
1845 ilm_layerSetDimension(t_ilm_layer layerId, t_ilm_uint *pDimension)
1847 ilmErrorTypes returnValue = ILM_FAILED;
1848 struct ilm_control_context *ctx = sync_and_acquire_instance();
1849 struct layer_context *ctx_layer = NULL;
1851 if (pDimension != NULL) {
1852 ctx_layer = (struct layer_context*)
1853 wayland_controller_get_layer_context(
1854 &ctx->wl, (uint32_t)layerId);
1855 if (ctx_layer != NULL) {
1856 ivi_controller_layer_set_destination_rectangle(
1857 ctx_layer->controller,
1858 ctx_layer->prop.destX, ctx_layer->prop.destY,
1859 (int32_t)*pDimension, (int32_t)*(pDimension + 1));
1860 returnValue = ILM_SUCCESS;
1868 ILM_EXPORT ilmErrorTypes
1869 ilm_layerGetPosition(t_ilm_layer layerId, t_ilm_uint *pPosition)
1871 ilmErrorTypes returnValue = ILM_FAILED;
1872 struct ilm_control_context *ctx = sync_and_acquire_instance();
1873 struct layer_context *ctx_layer = NULL;
1875 if (pPosition != NULL) {
1876 ctx_layer = (struct layer_context*)
1877 wayland_controller_get_layer_context(
1878 &ctx->wl, (uint32_t)layerId);
1879 if (ctx_layer != NULL) {
1880 *pPosition = ctx_layer->prop.destX;
1881 *(pPosition + 1) = ctx_layer->prop.destY;
1882 returnValue = ILM_SUCCESS;
1890 ILM_EXPORT ilmErrorTypes
1891 ilm_layerSetPosition(t_ilm_layer layerId, t_ilm_uint *pPosition)
1893 ilmErrorTypes returnValue = ILM_FAILED;
1894 struct ilm_control_context *ctx = sync_and_acquire_instance();
1895 struct layer_context *ctx_layer = NULL;
1897 if (pPosition != NULL) {
1898 ctx_layer = (struct layer_context*)
1899 wayland_controller_get_layer_context(
1900 &ctx->wl, (uint32_t)layerId);
1901 if (ctx_layer != NULL) {
1902 ivi_controller_layer_set_destination_rectangle(
1903 ctx_layer->controller,
1904 (int32_t)*pPosition, (int32_t)*(pPosition + 1),
1905 ctx_layer->prop.destWidth, ctx_layer->prop.destHeight);
1906 returnValue = ILM_SUCCESS;
1914 ILM_EXPORT ilmErrorTypes
1915 ilm_layerSetOrientation(t_ilm_layer layerId, ilmOrientation orientation)
1917 ilmErrorTypes returnValue = ILM_FAILED;
1918 struct ilm_control_context *ctx = sync_and_acquire_instance();
1919 struct layer_context *ctx_layer = NULL;
1920 int32_t iviorientation = 0;
1923 switch(orientation) {
1925 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES;
1928 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES;
1930 case ILM_ONEHUNDREDEIGHTY:
1931 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES;
1933 case ILM_TWOHUNDREDSEVENTY:
1934 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES;
1937 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
1941 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1942 &ctx->wl, (uint32_t)layerId);
1943 if (ctx_layer == NULL) {
1944 returnValue = ILM_FAILED;
1948 ivi_controller_layer_set_orientation(ctx_layer->controller,
1951 returnValue = ILM_SUCCESS;
1958 ILM_EXPORT ilmErrorTypes
1959 ilm_layerGetOrientation(t_ilm_layer layerId, ilmOrientation *pOrientation)
1961 ilmErrorTypes returnValue = ILM_FAILED;
1962 struct ilm_control_context *ctx = sync_and_acquire_instance();
1963 struct layer_context *ctx_layer = NULL;
1965 if (pOrientation != NULL) {
1966 ctx_layer = (struct layer_context*)
1967 wayland_controller_get_layer_context(
1968 &ctx->wl, (uint32_t)layerId);
1969 if (ctx_layer != NULL) {
1970 *pOrientation = ctx_layer->prop.orientation;
1971 returnValue = ILM_SUCCESS;
1979 ILM_EXPORT ilmErrorTypes
1980 ilm_layerSetChromaKey(t_ilm_layer layerId, t_ilm_int* pColor)
1988 ILM_EXPORT ilmErrorTypes
1989 ilm_layerSetRenderOrder(t_ilm_layer layerId,
1990 t_ilm_surface *pSurfaceId,
1993 ilmErrorTypes returnValue = ILM_FAILED;
1994 struct ilm_control_context *ctx = sync_and_acquire_instance();
1995 struct layer_context *ctx_layer = NULL;
1997 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1998 &ctx->wl, (uint32_t)layerId);
2002 struct wl_array ids;
2003 wl_array_init(&ids);
2004 uint32_t *pids = wl_array_add(&ids, number * sizeof *pids);
2006 for (i = 0; i < number; i++) pids[i] = (uint32_t)pSurfaceId[i];
2007 ivi_controller_layer_set_render_order(ctx_layer->controller, &ids);
2008 wl_array_release(&ids);
2009 returnValue = ILM_SUCCESS;
2016 ILM_EXPORT ilmErrorTypes
2017 ilm_layerGetCapabilities(t_ilm_layer layerId,
2018 t_ilm_layercapabilities *pCapabilities)
2021 (void)pCapabilities;
2026 ILM_EXPORT ilmErrorTypes
2027 ilm_layerTypeGetCapabilities(ilmLayerType layerType,
2028 t_ilm_layercapabilities *pCapabilities)
2031 (void)pCapabilities;
2036 ILM_EXPORT ilmErrorTypes
2037 ilm_surfaceSetVisibility(t_ilm_surface surfaceId, t_ilm_bool newVisibility)
2039 ilmErrorTypes returnValue = ILM_FAILED;
2040 struct ilm_control_context *ctx = sync_and_acquire_instance();
2041 struct surface_context *ctx_surf = NULL;
2042 uint32_t visibility = 0;
2044 if (newVisibility == ILM_TRUE) {
2047 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2049 ivi_controller_surface_set_visibility(ctx_surf->controller,
2051 returnValue = ILM_SUCCESS;
2058 ILM_EXPORT ilmErrorTypes
2059 ilm_surfaceSetOpacity(t_ilm_surface surfaceId, t_ilm_float opacity)
2061 ilmErrorTypes returnValue = ILM_FAILED;
2062 struct ilm_control_context *ctx = sync_and_acquire_instance();
2063 struct surface_context *ctx_surf = NULL;
2064 wl_fixed_t opacity_fixed = 0;
2066 opacity_fixed = wl_fixed_from_double((double)opacity);
2067 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2069 ivi_controller_surface_set_opacity(ctx_surf->controller,
2071 returnValue = ILM_SUCCESS;
2078 ILM_EXPORT ilmErrorTypes
2079 ilm_surfaceGetOpacity(t_ilm_surface surfaceId, t_ilm_float *pOpacity)
2081 ilmErrorTypes returnValue = ILM_FAILED;
2082 struct ilm_control_context *ctx = sync_and_acquire_instance();
2084 if (pOpacity != NULL) {
2085 struct surface_context *ctx_surf = NULL;
2086 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2088 *pOpacity = ctx_surf->prop.opacity;
2089 returnValue = ILM_SUCCESS;
2097 ILM_EXPORT ilmErrorTypes
2098 ilm_SetKeyboardFocusOn(t_ilm_surface surfaceId)
2100 ilmErrorTypes returnValue = ILM_FAILED;
2102 returnValue = ILM_SUCCESS;
2106 ILM_EXPORT ilmErrorTypes
2107 ilm_GetKeyboardFocusSurfaceId(t_ilm_surface* pSurfaceId)
2109 ilmErrorTypes returnValue = ILM_FAILED;
2111 returnValue = ILM_SUCCESS;
2115 ILM_EXPORT ilmErrorTypes
2116 ilm_surfaceSetDestinationRectangle(t_ilm_surface surfaceId,
2117 t_ilm_int x, t_ilm_int y,
2118 t_ilm_int width, t_ilm_int height)
2120 ilmErrorTypes returnValue = ILM_FAILED;
2121 struct ilm_control_context *ctx = sync_and_acquire_instance();
2122 struct surface_context *ctx_surf = NULL;
2124 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2126 ivi_controller_surface_set_destination_rectangle(
2127 ctx_surf->controller,
2128 x, y, width, height);
2129 returnValue = ILM_SUCCESS;
2136 ILM_EXPORT ilmErrorTypes
2137 ilm_surfaceSetDimension(t_ilm_surface surfaceId, t_ilm_uint *pDimension)
2139 ilmErrorTypes returnValue = ILM_FAILED;
2140 struct ilm_control_context *ctx = sync_and_acquire_instance();
2142 if (pDimension != NULL) {
2143 struct surface_context *ctx_surf = NULL;
2144 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2146 uint32_t width = *pDimension;
2147 uint32_t height = *(pDimension + 1);
2148 ivi_controller_surface_set_destination_rectangle(
2149 ctx_surf->controller,
2150 ctx_surf->prop.destX, ctx_surf->prop.destY, width, height);
2151 returnValue = ILM_SUCCESS;
2159 ILM_EXPORT ilmErrorTypes
2160 ilm_surfaceGetPosition(t_ilm_surface surfaceId, t_ilm_uint *pPosition)
2162 ilmErrorTypes returnValue = ILM_FAILED;
2163 struct ilm_control_context *ctx = sync_and_acquire_instance();
2165 if (pPosition != NULL) {
2166 struct surface_context *ctx_surf = NULL;
2167 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2169 *pPosition = ctx_surf->prop.destX;
2170 *(pPosition + 1) = ctx_surf->prop.destY;
2171 returnValue = ILM_SUCCESS;
2179 ILM_EXPORT ilmErrorTypes
2180 ilm_surfaceSetPosition(t_ilm_surface surfaceId, t_ilm_uint *pPosition)
2182 ilmErrorTypes returnValue = ILM_FAILED;
2183 struct ilm_control_context *ctx = sync_and_acquire_instance();
2185 if (pPosition != NULL) {
2186 struct surface_context *ctx_surf = NULL;
2187 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2189 int32_t destX = (int32_t)*pPosition;
2190 int32_t destY = (int32_t)*(pPosition + 1);
2191 ivi_controller_surface_set_destination_rectangle(
2192 ctx_surf->controller, destX, destY,
2193 ctx_surf->prop.destWidth, ctx_surf->prop.destHeight);
2194 returnValue = ILM_SUCCESS;
2202 ILM_EXPORT ilmErrorTypes
2203 ilm_surfaceSetOrientation(t_ilm_surface surfaceId,
2204 ilmOrientation orientation)
2206 ilmErrorTypes returnValue = ILM_FAILED;
2207 struct ilm_control_context *ctx = sync_and_acquire_instance();
2208 struct surface_context *ctx_surf = NULL;
2209 int32_t iviorientation = 0;
2212 switch(orientation) {
2214 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES;
2217 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES;
2219 case ILM_ONEHUNDREDEIGHTY:
2220 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES;
2222 case ILM_TWOHUNDREDSEVENTY:
2223 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES;
2226 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2230 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2231 if (ctx_surf == NULL) {
2232 returnValue = ILM_FAILED;
2236 ivi_controller_surface_set_orientation(ctx_surf->controller,
2239 returnValue = ILM_SUCCESS;
2246 ILM_EXPORT ilmErrorTypes
2247 ilm_surfaceGetOrientation(t_ilm_surface surfaceId,
2248 ilmOrientation *pOrientation)
2250 ilmErrorTypes returnValue = ILM_FAILED;
2251 struct ilm_control_context *ctx = sync_and_acquire_instance();
2253 if (pOrientation != NULL) {
2254 struct surface_context *ctx_surf = NULL;
2255 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2257 *pOrientation = ctx_surf->prop.orientation;
2258 returnValue = ILM_SUCCESS;
2266 ILM_EXPORT ilmErrorTypes
2267 ilm_surfaceGetPixelformat(t_ilm_layer surfaceId,
2268 ilmPixelFormat *pPixelformat)
2270 ilmErrorTypes returnValue = ILM_FAILED;
2271 struct ilm_control_context *ctx = sync_and_acquire_instance();
2273 if (pPixelformat != NULL) {
2274 struct surface_context *ctx_surf = NULL;
2275 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2277 *pPixelformat = ctx_surf->prop.pixelformat;
2278 returnValue = ILM_SUCCESS;
2286 ILM_EXPORT ilmErrorTypes
2287 ilm_surfaceSetChromaKey(t_ilm_surface surfaceId, t_ilm_int* pColor)
2295 ILM_EXPORT ilmErrorTypes
2296 ilm_displaySetRenderOrder(t_ilm_display display,
2297 t_ilm_layer *pLayerId, const t_ilm_uint number)
2299 ilmErrorTypes returnValue = ILM_FAILED;
2300 struct ilm_control_context *ctx = sync_and_acquire_instance();
2301 struct screen_context *ctx_scrn = NULL;
2303 ctx_scrn = get_screen_context_by_id(&ctx->wl, (uint32_t)display);
2304 if (ctx_scrn != NULL) {
2305 struct wl_array ids;
2306 wl_array_init(&ids);
2307 uint32_t *pids = wl_array_add(&ids, number * sizeof *pids);
2309 for (i = 0; i < number; i++) pids[i] = (uint32_t)pLayerId[i];
2310 ivi_controller_screen_set_render_order(ctx_scrn->controller, &ids);
2311 wl_array_release(&ids);
2312 returnValue = ILM_SUCCESS;
2319 ILM_EXPORT ilmErrorTypes
2320 ilm_takeScreenshot(t_ilm_uint screen, t_ilm_const_string filename)
2322 ilmErrorTypes returnValue = ILM_FAILED;
2323 struct ilm_control_context *ctx = sync_and_acquire_instance();
2324 struct screen_context *ctx_scrn = NULL;
2326 ctx_scrn = get_screen_context_by_id(&ctx->wl, (uint32_t)screen);
2327 if (ctx_scrn != NULL) {
2328 ivi_controller_screen_screenshot(ctx_scrn->controller,
2330 wl_display_flush(ctx->wl.display);
2331 returnValue = ILM_SUCCESS;
2338 ILM_EXPORT ilmErrorTypes
2339 ilm_takeLayerScreenshot(t_ilm_const_string filename, t_ilm_layer layerid)
2341 ilmErrorTypes returnValue = ILM_FAILED;
2342 struct ilm_control_context *ctx = sync_and_acquire_instance();
2343 struct layer_context *ctx_layer = NULL;
2345 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2346 &ctx->wl, (uint32_t)layerid);
2347 if (ctx_layer != NULL) {
2348 ivi_controller_layer_screenshot(ctx_layer->controller,
2350 wl_display_flush(ctx->wl.display);
2351 returnValue = ILM_SUCCESS;
2358 ILM_EXPORT ilmErrorTypes
2359 ilm_takeSurfaceScreenshot(t_ilm_const_string filename,
2360 t_ilm_surface surfaceid)
2362 ilmErrorTypes returnValue = ILM_FAILED;
2363 struct ilm_control_context *ctx = sync_and_acquire_instance();
2364 struct surface_context *ctx_surf = NULL;
2366 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceid);
2368 ivi_controller_surface_screenshot(ctx_surf->controller,
2370 wl_display_flush(ctx->wl.display);
2371 returnValue = ILM_SUCCESS;
2378 ILM_EXPORT ilmErrorTypes
2379 ilm_SetOptimizationMode(ilmOptimization id, ilmOptimizationMode mode)
2387 ILM_EXPORT ilmErrorTypes
2388 ilm_GetOptimizationMode(ilmOptimization id, ilmOptimizationMode* pMode)
2396 ILM_EXPORT ilmErrorTypes
2397 ilm_layerAddNotification(t_ilm_layer layer,
2398 layerNotificationFunc callback)
2400 ilmErrorTypes returnValue = ILM_FAILED;
2401 struct ilm_control_context *ctx = sync_and_acquire_instance();
2402 struct layer_context *ctx_layer = NULL;
2404 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2405 &ctx->wl, (uint32_t)layer);
2406 if (ctx_layer == NULL) {
2407 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2409 ctx_layer->notification = callback;
2411 returnValue = ILM_SUCCESS;
2418 ILM_EXPORT ilmErrorTypes
2419 ilm_layerRemoveNotification(t_ilm_layer layer)
2421 return ilm_layerAddNotification(layer, NULL);
2424 ILM_EXPORT ilmErrorTypes
2425 ilm_surfaceAddNotification(t_ilm_surface surface,
2426 surfaceNotificationFunc callback)
2428 ilmErrorTypes returnValue = ILM_FAILED;
2429 struct ilm_control_context *ctx = sync_and_acquire_instance();
2430 struct surface_context *ctx_surf = NULL;
2432 ctx_surf = (struct surface_context*)get_surface_context(
2433 &ctx->wl, (uint32_t)surface);
2434 if (ctx_surf == NULL) {
2435 if (callback != NULL) {
2436 callback((uint32_t)surface, NULL, ILM_NOTIFICATION_CONTENT_REMOVED);
2437 controller_listener_surface(ctx, ctx->wl.controller, (uint32_t)surface);
2438 ctx_surf = (struct surface_context*)get_surface_context(
2439 &ctx->wl, (uint32_t)surface);
2440 ctx_surf->is_surface_creation_noticed = false;
2444 if (ctx_surf == NULL) {
2445 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2448 ctx_surf->notification = callback;
2450 returnValue = ILM_SUCCESS;
2457 ILM_EXPORT ilmErrorTypes
2458 ilm_surfaceRemoveNotification(t_ilm_surface surface)
2460 return ilm_surfaceAddNotification(surface, NULL);
2463 ILM_EXPORT ilmErrorTypes
2464 ilm_getNativeHandle(t_ilm_uint pid, t_ilm_int *n_handle,
2465 t_ilm_nativehandle **p_handles)
2467 struct ilm_control_context *ctx = sync_and_acquire_instance();
2468 struct nativehandle_context *p_nh_ctx = NULL;
2473 wl_list_for_each(p_nh_ctx, &ctx->list_nativehandle, link)
2475 if (p_nh_ctx->pid == pid)
2479 (t_ilm_nativehandle*)malloc(sizeof(t_ilm_nativehandle));
2480 (*p_handles)[0] = p_nh_ctx->nativehandle;
2486 return (*n_handle > 0) ? ILM_SUCCESS : ILM_FAILED;
2489 ILM_EXPORT ilmErrorTypes
2490 ilm_getPropertiesOfSurface(t_ilm_uint surfaceID,
2491 struct ilmSurfaceProperties* pSurfaceProperties)
2493 ilmErrorTypes returnValue = ILM_FAILED;
2494 struct ilm_control_context *ctx = sync_and_acquire_instance();
2496 if (pSurfaceProperties != NULL) {
2497 struct surface_context *ctx_surf = NULL;
2499 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceID);
2500 if (ctx_surf != NULL) {
2502 *pSurfaceProperties = ctx_surf->prop;
2503 returnValue = ILM_SUCCESS;
2511 ILM_EXPORT ilmErrorTypes
2512 ilm_layerAddSurface(t_ilm_layer layerId,
2513 t_ilm_surface surfaceId)
2515 ilmErrorTypes returnValue = ILM_FAILED;
2516 struct ilm_control_context *ctx = sync_and_acquire_instance();
2517 struct layer_context *ctx_layer = NULL;
2518 struct surface_context *ctx_surf = NULL;
2520 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2521 &ctx->wl, (uint32_t)layerId);
2522 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2523 if ((ctx_layer != NULL) && (ctx_surf != NULL)) {
2524 ivi_controller_layer_add_surface(ctx_layer->controller,
2525 ctx_surf->controller);
2526 returnValue = ILM_SUCCESS;
2533 ILM_EXPORT ilmErrorTypes
2534 ilm_layerRemoveSurface(t_ilm_layer layerId,
2535 t_ilm_surface surfaceId)
2537 ilmErrorTypes returnValue = ILM_FAILED;
2538 struct ilm_control_context *ctx = sync_and_acquire_instance();
2539 struct layer_context *ctx_layer = NULL;
2540 struct surface_context *ctx_surf = NULL;
2542 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2543 &ctx->wl, (uint32_t)layerId);
2544 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2545 if ((ctx_layer != NULL) && (ctx_surf != NULL)) {
2546 ivi_controller_layer_remove_surface(ctx_layer->controller,
2547 ctx_surf->controller);
2548 returnValue = ILM_SUCCESS;
2555 ILM_EXPORT ilmErrorTypes
2556 ilm_surfaceGetDimension(t_ilm_surface surfaceId,
2557 t_ilm_uint *pDimension)
2559 ilmErrorTypes returnValue = ILM_FAILED;
2560 struct ilm_control_context *ctx = sync_and_acquire_instance();
2562 if (pDimension != NULL) {
2563 struct surface_context *ctx_surf = NULL;
2565 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2566 if (ctx_surf != NULL) {
2567 *pDimension = (t_ilm_uint)ctx_surf->prop.destWidth;
2568 *(pDimension + 1) = (t_ilm_uint)ctx_surf->prop.destHeight;
2569 returnValue = ILM_SUCCESS;
2577 ILM_EXPORT ilmErrorTypes
2578 ilm_surfaceGetVisibility(t_ilm_surface surfaceId,
2579 t_ilm_bool *pVisibility)
2581 ilmErrorTypes returnValue = ILM_FAILED;
2582 struct ilm_control_context *ctx = sync_and_acquire_instance();
2583 struct surface_context *ctx_surf = NULL;
2585 if (pVisibility != NULL) {
2586 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2587 if (ctx_surf != NULL) {
2588 *pVisibility = (t_ilm_bool)ctx_surf->prop.visibility;
2589 returnValue = ILM_SUCCESS;
2597 ILM_EXPORT ilmErrorTypes
2598 ilm_surfaceSetSourceRectangle(t_ilm_surface surfaceId,
2599 t_ilm_int x, t_ilm_int y,
2600 t_ilm_int width, t_ilm_int height)
2602 ilmErrorTypes returnValue = ILM_FAILED;
2603 struct ilm_control_context *ctx = sync_and_acquire_instance();
2604 struct surface_context *ctx_surf = NULL;
2606 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2607 if (ctx_surf != NULL) {
2608 if (ctx_surf->controller != NULL) {
2609 ivi_controller_surface_set_source_rectangle(
2610 ctx_surf->controller,
2611 x, y, width, height);
2612 returnValue = ILM_SUCCESS;
2620 ILM_EXPORT ilmErrorTypes
2621 ilm_commitChanges(void)
2623 ilmErrorTypes returnValue = ILM_FAILED;
2624 struct ilm_control_context *ctx = sync_and_acquire_instance();
2626 if (ctx->wl.controller != NULL) {
2627 ivi_controller_commit_changes(ctx->wl.controller);
2629 if (display_roundtrip_queue(ctx->wl.display, ctx->wl.queue) != -1)
2631 returnValue = ILM_SUCCESS;