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_serverid(struct wayland_context *ctx,
300 struct screen_context *ctx_scrn = NULL;
302 wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
303 if (ctx_scrn->id_from_server == id_screen) {
311 add_orderlayer_to_screen(struct layer_context *ctx_layer,
312 struct wl_output* output)
314 struct screen_context *ctx_scrn = wl_output_get_user_data(output);
317 struct layer_context *layer_link;
318 wl_list_for_each(layer_link, &ctx_scrn->order.list_layer, order.link) {
319 if (layer_link == ctx_layer) {
326 wl_list_init(&ctx_layer->order.link);
327 wl_list_insert(&ctx_scrn->order.list_layer, &ctx_layer->order.link);
332 remove_orderlayer_from_screen(struct layer_context *ctx_layer)
334 wl_list_remove(&ctx_layer->order.link);
335 wl_list_init(&ctx_layer->order.link);
339 controller_layer_listener_visibility(void *data,
340 struct ivi_controller_layer *controller,
343 struct layer_context *ctx_layer = data;
345 ctx_layer->prop.visibility = (t_ilm_bool)visibility;
347 if (ctx_layer->notification != NULL) {
348 ctx_layer->notification(ctx_layer->id_layer,
350 ILM_NOTIFICATION_VISIBILITY);
355 controller_layer_listener_opacity(void *data,
356 struct ivi_controller_layer *controller,
359 struct layer_context *ctx_layer = data;
361 ctx_layer->prop.opacity = (t_ilm_float)wl_fixed_to_double(opacity);
363 if (ctx_layer->notification != NULL) {
364 ctx_layer->notification(ctx_layer->id_layer,
366 ILM_NOTIFICATION_OPACITY);
371 controller_layer_listener_source_rectangle(void *data,
372 struct ivi_controller_layer *controller,
378 struct layer_context *ctx_layer = data;
380 ctx_layer->prop.sourceX = (t_ilm_uint)x;
381 ctx_layer->prop.sourceY = (t_ilm_uint)y;
382 ctx_layer->prop.sourceWidth = (t_ilm_uint)width;
383 ctx_layer->prop.sourceHeight = (t_ilm_uint)height;
384 if (ctx_layer->prop.origSourceWidth == 0) {
385 ctx_layer->prop.origSourceWidth = (t_ilm_uint)width;
387 if (ctx_layer->prop.origSourceHeight == 0) {
388 ctx_layer->prop.origSourceHeight = (t_ilm_uint)height;
391 if (ctx_layer->notification != NULL) {
392 ctx_layer->notification(ctx_layer->id_layer,
394 ILM_NOTIFICATION_SOURCE_RECT);
399 controller_layer_listener_destination_rectangle(void *data,
400 struct ivi_controller_layer *controller,
406 struct layer_context *ctx_layer = data;
408 ctx_layer->prop.destX = (t_ilm_uint)x;
409 ctx_layer->prop.destY = (t_ilm_uint)y;
410 ctx_layer->prop.destWidth = (t_ilm_uint)width;
411 ctx_layer->prop.destHeight = (t_ilm_uint)height;
413 if (ctx_layer->notification != NULL) {
414 ctx_layer->notification(ctx_layer->id_layer,
416 ILM_NOTIFICATION_DEST_RECT);
421 controller_layer_listener_configuration(void *data,
422 struct ivi_controller_layer *controller,
426 struct layer_context *ctx_layer = data;
428 ctx_layer->prop.sourceWidth = (t_ilm_uint)width;
429 ctx_layer->prop.sourceHeight = (t_ilm_uint)height;
433 controller_layer_listener_orientation(void *data,
434 struct ivi_controller_layer *controller,
437 ilmOrientation ilmorientation = ILM_ZERO;
438 struct layer_context *ctx_layer = data;
440 switch(orientation) {
441 case IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES:
442 ilmorientation = ILM_ZERO;
444 case IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES:
445 ilmorientation = ILM_NINETY;
447 case IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES:
448 ilmorientation = ILM_ONEHUNDREDEIGHTY;
450 case IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES:
451 ilmorientation = ILM_TWOHUNDREDSEVENTY;
457 ctx_layer->prop.orientation = ilmorientation;
459 if (ctx_layer->notification != NULL) {
460 ctx_layer->notification(ctx_layer->id_layer,
462 ILM_NOTIFICATION_ORIENTATION);
467 controller_layer_listener_screen(void *data,
468 struct ivi_controller_layer *controller,
469 struct wl_output *output)
471 struct layer_context *ctx_layer = data;
473 if (output == NULL) {
474 remove_orderlayer_from_screen(ctx_layer);
476 add_orderlayer_to_screen(ctx_layer, output);
481 controller_layer_listener_destroyed(void *data,
482 struct ivi_controller_layer *controller)
484 struct layer_context *ctx_layer = data;
485 wl_list_remove(&ctx_layer->link);
489 static struct ivi_controller_layer_listener controller_layer_listener =
491 controller_layer_listener_visibility,
492 controller_layer_listener_opacity,
493 controller_layer_listener_source_rectangle,
494 controller_layer_listener_destination_rectangle,
495 controller_layer_listener_configuration,
496 controller_layer_listener_orientation,
497 controller_layer_listener_screen,
498 controller_layer_listener_destroyed
502 add_ordersurface_to_layer(struct surface_context *ctx_surf,
503 struct ivi_controller_layer *layer)
505 struct layer_context *ctx_layer = NULL;
506 struct surface_context *link = NULL;
509 ctx_layer = ivi_controller_layer_get_user_data(layer);
511 wl_list_for_each(link, &ctx_layer->order.list_surface, order.link) {
512 if (link == ctx_surf) {
519 wl_list_init(&ctx_surf->order.link);
520 wl_list_insert(&ctx_layer->order.list_surface, &ctx_surf->order.link);
525 remove_ordersurface_from_layer(struct surface_context *ctx_surf)
527 wl_list_remove(&ctx_surf->order.link);
528 wl_list_init(&ctx_surf->order.link);
532 controller_surface_listener_visibility(void *data,
533 struct ivi_controller_surface *controller,
536 struct surface_context *ctx_surf = data;
538 ctx_surf->prop.visibility = (t_ilm_bool)visibility;
540 if (ctx_surf->notification != NULL) {
541 ctx_surf->notification(ctx_surf->id_surface,
543 ILM_NOTIFICATION_VISIBILITY);
548 controller_surface_listener_opacity(void *data,
549 struct ivi_controller_surface *controller,
552 struct surface_context *ctx_surf = data;
554 ctx_surf->prop.opacity = (t_ilm_float)wl_fixed_to_double(opacity);
556 if (ctx_surf->notification != NULL) {
557 ctx_surf->notification(ctx_surf->id_surface,
559 ILM_NOTIFICATION_OPACITY);
564 controller_surface_listener_configuration(void *data,
565 struct ivi_controller_surface *controller,
569 struct surface_context *ctx_surf = data;
571 ctx_surf->prop.sourceWidth = (t_ilm_uint)width;
572 ctx_surf->prop.sourceHeight = (t_ilm_uint)height;
576 controller_surface_listener_source_rectangle(void *data,
577 struct ivi_controller_surface *controller,
583 struct surface_context *ctx_surf = data;
585 ctx_surf->prop.sourceX = (t_ilm_uint)x;
586 ctx_surf->prop.sourceY = (t_ilm_uint)y;
587 ctx_surf->prop.sourceWidth = (t_ilm_uint)width;
588 ctx_surf->prop.sourceHeight = (t_ilm_uint)height;
589 if (ctx_surf->prop.origSourceWidth == 0) {
590 ctx_surf->prop.origSourceWidth = (t_ilm_uint)width;
592 if (ctx_surf->prop.origSourceHeight == 0) {
593 ctx_surf->prop.origSourceHeight = (t_ilm_uint)height;
596 if (ctx_surf->notification != NULL) {
597 ctx_surf->notification(ctx_surf->id_surface,
599 ILM_NOTIFICATION_SOURCE_RECT);
604 controller_surface_listener_destination_rectangle(void *data,
605 struct ivi_controller_surface *controller,
611 struct surface_context *ctx_surf = data;
613 ctx_surf->prop.destX = (t_ilm_uint)x;
614 ctx_surf->prop.destY = (t_ilm_uint)y;
615 ctx_surf->prop.destWidth = (t_ilm_uint)width;
616 ctx_surf->prop.destHeight = (t_ilm_uint)height;
618 if (ctx_surf->notification != NULL) {
619 ctx_surf->notification(ctx_surf->id_surface,
621 ILM_NOTIFICATION_DEST_RECT);
626 controller_surface_listener_orientation(void *data,
627 struct ivi_controller_surface *controller,
630 struct surface_context *ctx_surf = data;
631 ilmOrientation ilmorientation = ILM_ZERO;
633 switch (orientation) {
634 case IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES:
635 ilmorientation = ILM_ZERO;
637 case IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES:
638 ilmorientation = ILM_NINETY;
640 case IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES:
641 ilmorientation = ILM_ONEHUNDREDEIGHTY;
643 case IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES:
644 ilmorientation = ILM_TWOHUNDREDSEVENTY;
650 ctx_surf->prop.orientation = ilmorientation;
652 if (ctx_surf->notification != NULL) {
653 ctx_surf->notification(ctx_surf->id_surface,
655 ILM_NOTIFICATION_ORIENTATION);
660 controller_surface_listener_pixelformat(void *data,
661 struct ivi_controller_surface *controller,
664 struct surface_context *ctx_surf = data;
666 ctx_surf->prop.pixelformat = (t_ilm_uint)pixelformat;
670 controller_surface_listener_layer(void *data,
671 struct ivi_controller_surface *controller,
672 struct ivi_controller_layer *layer)
674 struct surface_context *ctx_surf = data;
677 remove_ordersurface_from_layer(ctx_surf);
679 add_ordersurface_to_layer(ctx_surf, layer);
684 controller_surface_listener_stats(void *data,
685 struct ivi_controller_surface *controller,
686 uint32_t redraw_count,
687 uint32_t frame_count,
688 uint32_t update_count,
690 const char *process_name)
692 struct surface_context *ctx_surf = data;
695 ctx_surf->prop.drawCounter = (t_ilm_uint)redraw_count;
696 ctx_surf->prop.frameCounter = (t_ilm_uint)frame_count;
697 ctx_surf->prop.updateCounter = (t_ilm_uint)update_count;
698 ctx_surf->prop.creatorPid = (t_ilm_uint)pid;
702 controller_surface_listener_destroyed(void *data,
703 struct ivi_controller_surface *controller)
705 struct surface_context *ctx_surf = data;
707 if (ctx_surf->notification != NULL) {
708 ctx_surf->notification(ctx_surf->id_surface,
710 ILM_NOTIFICATION_CONTENT_REMOVED);
713 wl_list_remove(&ctx_surf->link);
718 controller_surface_listener_content(void *data,
719 struct ivi_controller_surface *controller,
720 int32_t content_state)
722 struct surface_context *ctx_surf = data;
724 // if client surface (=content) was removed with ilm_surfaceDestroy()
725 // the expected behavior within ILM API mandates a full removal
726 // of the surface from the scene. We must remove the controller
728 if (IVI_CONTROLLER_SURFACE_CONTENT_STATE_CONTENT_REMOVED == content_state)
730 if (ctx_surf->notification != NULL) {
731 ctx_surf->notification(ctx_surf->id_surface,
733 ILM_NOTIFICATION_CONTENT_REMOVED);
736 ivi_controller_surface_destroy(controller, 1);
738 wl_list_remove(&ctx_surf->link);
741 else if (IVI_CONTROLLER_SURFACE_CONTENT_STATE_CONTENT_AVAILABLE == content_state)
743 if (ctx_surf->notification != NULL) {
744 ctx_surf->notification(ctx_surf->id_surface,
746 ILM_NOTIFICATION_CONTENT_AVAILABLE);
752 controller_surface_listener_input_focus(void *data,
753 struct ivi_controller_surface *controller,
763 static struct ivi_controller_surface_listener controller_surface_listener=
765 controller_surface_listener_visibility,
766 controller_surface_listener_opacity,
767 controller_surface_listener_source_rectangle,
768 controller_surface_listener_destination_rectangle,
769 controller_surface_listener_configuration,
770 controller_surface_listener_orientation,
771 controller_surface_listener_pixelformat,
772 controller_surface_listener_layer,
773 controller_surface_listener_stats,
774 controller_surface_listener_destroyed,
775 controller_surface_listener_content,
776 controller_surface_listener_input_focus
780 controller_listener_layer(void *data,
781 struct ivi_controller *controller,
784 struct wayland_context *ctx = data;
786 if (wayland_controller_is_inside_layer_list(&ctx->list_layer, id_layer))
791 (void) create_controller_layer(ctx, 0, 0, id_layer);
795 controller_listener_surface(void *data,
796 struct ivi_controller *controller,
799 struct wayland_context *ctx = data;
800 struct surface_context *ctx_surf = NULL;
802 ctx_surf = get_surface_context(ctx, id_surface);
803 if (ctx_surf != NULL) {
804 if (!ctx_surf->is_surface_creation_noticed) {
805 if (ctx_surf->notification != NULL) {
806 ctx_surf->notification(ctx_surf->id_surface,
808 ILM_NOTIFICATION_CONTENT_AVAILABLE);
809 ctx_surf->is_surface_creation_noticed = true;
811 ctx_surf->controller = ivi_controller_surface_create(
812 controller, id_surface);
815 fprintf(stderr, "invalid id_surface in controller_listener_surface\n");
820 ctx_surf = calloc(1, sizeof *ctx_surf);
821 if (ctx_surf == NULL) {
822 fprintf(stderr, "Failed to allocate memory for surface_context\n");
826 ctx_surf->controller = ivi_controller_surface_create(
827 controller, id_surface);
828 if (ctx_surf->controller == NULL) {
830 fprintf(stderr, "Failed to create controller surface\n");
833 ctx_surf->id_surface = id_surface;
834 ctx_surf->prop.inputDevicesAcceptance = ILM_INPUT_DEVICE_ALL;
836 ctx_surf->is_surface_creation_noticed = true;
838 wl_list_init(&ctx_surf->link);
839 wl_list_insert(&ctx->list_surface, &ctx_surf->link);
840 wl_list_init(&ctx_surf->order.link);
841 ivi_controller_surface_add_listener(ctx_surf->controller,
842 &controller_surface_listener, ctx_surf);
846 controller_listener_error(void *data,
847 struct ivi_controller *ivi_controller,
851 const char *error_text)
854 (void)ivi_controller;
862 controller_listener_screen(void *data,
863 struct ivi_controller *ivi_controller,
865 struct ivi_controller_screen *controller_screen)
867 struct wayland_context *ctx = data;
868 struct screen_context *ctx_screen;
869 (void)ivi_controller;
871 ctx_screen = get_screen_context_by_serverid(ctx, id_screen);
872 if (ctx_screen == NULL) {
873 fprintf(stderr, "Failed to allocate memory for screen_context\n");
876 ctx_screen->controller = controller_screen;
879 static struct ivi_controller_listener controller_listener= {
880 controller_listener_screen,
881 controller_listener_layer,
882 controller_listener_surface,
883 controller_listener_error
887 registry_handle_control(void *data,
888 struct wl_registry *registry,
889 uint32_t name, const char *interface,
892 struct wayland_context *ctx = data;
895 if (strcmp(interface, "ivi_controller") == 0) {
896 ctx->controller = wl_registry_bind(registry, name,
897 &ivi_controller_interface, 1);
898 if (ctx->controller == NULL) {
899 fprintf(stderr, "Failed to registry bind ivi_controller\n");
902 if (ivi_controller_add_listener(ctx->controller,
903 &controller_listener,
905 fprintf(stderr, "Failed to add ivi_controller listener\n");
908 } else if (strcmp(interface, "wl_output") == 0) {
909 struct screen_context *ctx_scrn = calloc(1, sizeof *ctx_scrn);
910 struct wl_proxy *pxy = NULL;
912 if (ctx_scrn == NULL) {
913 fprintf(stderr, "Failed to allocate memory for screen_context\n");
916 wl_list_init(&ctx_scrn->link);
917 ctx_scrn->output = wl_registry_bind(registry, name,
918 &wl_output_interface, 1);
919 if (ctx_scrn->output == NULL) {
921 fprintf(stderr, "Failed to registry bind wl_output\n");
925 if (wl_output_add_listener(ctx_scrn->output,
929 fprintf(stderr, "Failed to add wl_output listener\n");
933 pxy = (struct wl_proxy*)ctx_scrn->output;
934 ctx_scrn->id_from_server = wl_proxy_get_id(pxy);
935 ctx_scrn->id_screen = ctx->num_screen;
937 wl_list_init(&ctx_scrn->order.list_layer);
938 wl_list_insert(&ctx->list_screen, &ctx_scrn->link);
942 static const struct wl_registry_listener
943 registry_control_listener= {
944 registry_handle_control,
948 static struct ilm_control_context ilm_context;
950 static void destroy_control_resources(void)
952 struct ilm_control_context *ctx = &ilm_context;
954 // free resources of output objects
955 if (! ctx->wl.controller) {
956 struct screen_context *ctx_scrn;
957 struct screen_context *next;
959 wl_list_for_each_safe(ctx_scrn, next, &ctx->wl.list_screen, link) {
960 if (ctx_scrn->output != NULL) {
961 wl_output_destroy(ctx_scrn->output);
964 wl_list_remove(&ctx_scrn->link);
969 if (ctx->wl.controller != NULL) {
971 struct surface_context *l;
972 struct surface_context *n;
973 wl_list_for_each_safe(l, n, &ctx->wl.list_surface, link) {
974 wl_list_remove(&l->link);
975 wl_list_remove(&l->order.link);
976 ivi_controller_surface_destroy(l->controller, 0);
982 struct layer_context *l;
983 struct layer_context *n;
984 wl_list_for_each_safe(l, n, &ctx->wl.list_layer, link) {
985 wl_list_remove(&l->link);
986 wl_list_remove(&l->order.link);
992 struct screen_context *ctx_scrn;
993 struct screen_context *next;
995 wl_list_for_each_safe(ctx_scrn, next, &ctx->wl.list_screen, link) {
996 if (ctx_scrn->output != NULL) {
997 wl_output_destroy(ctx_scrn->output);
1000 wl_list_remove(&ctx_scrn->link);
1001 ivi_controller_screen_destroy(ctx_scrn->controller);
1006 ivi_controller_destroy(ctx->wl.controller);
1007 ctx->wl.controller = NULL;
1010 if (ctx->wl.display) {
1011 wl_display_flush(ctx->wl.display);
1014 if (ctx->wl.registry) {
1015 wl_registry_destroy(ctx->wl.registry);
1016 ctx->wl.registry = NULL;
1019 if (ctx->wl.queue) {
1020 wl_event_queue_destroy(ctx->wl.queue);
1021 ctx->wl.queue = NULL;
1024 if (0 != pthread_mutex_destroy(&ctx->mutex)) {
1025 fprintf(stderr, "failed to destroy pthread_mutex\n");
1029 static void send_shutdown_event(struct ilm_control_context *ctx)
1032 while (write(ctx->shutdown_fd, &buf, sizeof buf) == -1 && errno == EINTR)
1037 ilmControl_destroy(void)
1039 struct ilm_control_context *ctx = &ilm_context;
1041 send_shutdown_event(ctx);
1043 if (0 != pthread_join(ctx->thread, NULL)) {
1044 fprintf(stderr, "failed to join control thread\n");
1047 destroy_control_resources();
1049 close(ctx->shutdown_fd);
1051 memset(ctx, 0, sizeof *ctx);
1054 ILM_EXPORT ilmErrorTypes
1055 ilmControl_init(t_ilm_nativedisplay nativedisplay)
1057 struct ilm_control_context *ctx = &ilm_context;
1059 if (ctx->initialized)
1061 fprintf(stderr, "Already initialized!\n");
1065 if (nativedisplay == 0) {
1066 return ILM_ERROR_INVALID_ARGUMENTS;
1069 ctx->shutdown_fd = -1;
1071 ctx->wl.display = (struct wl_display*)nativedisplay;
1073 wl_list_init(&ctx->wl.list_screen);
1074 wl_list_init(&ctx->wl.list_layer);
1075 wl_list_init(&ctx->wl.list_surface);
1078 pthread_mutexattr_t a;
1079 if (pthread_mutexattr_init(&a) != 0)
1084 if (pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE) != 0)
1086 pthread_mutexattr_destroy(&a);
1090 if (pthread_mutex_init(&ctx->mutex, &a) != 0)
1092 pthread_mutexattr_destroy(&a);
1093 fprintf(stderr, "failed to initialize pthread_mutex\n");
1097 pthread_mutexattr_destroy(&a);
1100 return init_control() == 0 ? ILM_SUCCESS : ILM_FAILED;
1104 control_thread(void *p_ret)
1106 struct ilm_control_context *const ctx = &ilm_context;
1107 struct wayland_context *const wl = &ctx->wl;
1108 struct wl_display *const display = wl->display;
1109 struct wl_event_queue *const queue = wl->queue;
1110 int const fd = wl_display_get_fd(display);
1111 int const shutdown_fd = ctx->shutdown_fd;
1116 while (wl_display_prepare_read_queue(display, queue) != 0)
1119 wl_display_dispatch_queue_pending(display, queue);
1120 unlock_context(ctx);
1123 if (wl_display_flush(display) == -1)
1128 struct pollfd pfd[2] = {
1129 { .fd = fd, .events = POLLIN },
1130 { .fd = shutdown_fd, .events = POLLIN }
1133 int pollret = poll(pfd, 2, -1);
1134 if (pollret != -1 && (pfd[0].revents & POLLIN))
1136 wl_display_read_events(display);
1139 int ret = wl_display_dispatch_queue_pending(display, queue);
1140 unlock_context(ctx);
1149 wl_display_cancel_read(display);
1151 if (pollret == -1 || (pfd[1].revents & POLLIN))
1164 struct ilm_control_context *ctx = &ilm_context;
1165 struct wayland_context *wl = &ctx->wl;
1169 wl_list_init(&ctx->list_nativehandle);
1171 wl->queue = wl_display_create_queue(wl->display);
1173 /* registry_add_listener for request by ivi-controller */
1174 wl->registry = wl_display_get_registry(wl->display);
1175 if (wl->registry == NULL) {
1176 wl_event_queue_destroy(wl->queue);
1178 fprintf(stderr, "Failed to get registry\n");
1181 wl_proxy_set_queue((void*)wl->registry, wl->queue);
1183 if (wl_registry_add_listener(wl->registry,
1184 ®istry_control_listener, ctx)) {
1185 fprintf(stderr, "Failed to add registry listener\n");
1189 // first level objects; ivi_controller
1190 display_roundtrip_queue(wl->display, wl->queue);
1191 // second level object: ivi_controller_surfaces/layers
1192 display_roundtrip_queue(wl->display, wl->queue);
1193 // third level objects: ivi_controller_surfaces/layers properties
1194 display_roundtrip_queue(wl->display, wl->queue);
1196 if (! wl->controller)
1198 fputs("ivi_controller not available\n", stderr);
1202 ctx->shutdown_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
1204 if (ctx->shutdown_fd == -1)
1206 fprintf(stderr, "Could not setup shutdown-fd: %s\n", strerror(errno));
1210 ret = pthread_create(&ctx->thread, NULL, control_thread, NULL);
1213 fprintf(stderr, "Failed to start internal receive thread. returned %d\n", ret);
1217 ctx->initialized = true;
1222 #define sync_and_acquire_instance() ({ \
1223 struct ilm_control_context *ctx = &ilm_context; \
1224 if (! ctx->initialized) { \
1225 fputs("Not initialized\n", stderr); \
1226 return ILM_FAILED; \
1228 lock_context(ctx); \
1229 display_roundtrip_queue(ctx->wl.display, ctx->wl.queue); \
1233 static void release_instance(void)
1235 struct ilm_control_context *ctx = &ilm_context;
1236 unlock_context(ctx);
1240 gen_layer_id(struct ilm_control_context *ctx)
1242 struct layer_context *ctx_layer = NULL;
1245 if (wl_list_length(&ctx->wl.list_layer) == 0) {
1246 ctx->internal_id_layer++;
1247 return ctx->internal_id_layer;
1249 wl_list_for_each(ctx_layer, &ctx->wl.list_layer, link) {
1250 if (ctx_layer->id_layer == ctx->internal_id_layer) {
1256 return ctx->internal_id_layer;
1259 ctx->internal_id_layer++;
1263 static struct surface_context*
1264 get_surface_context(struct wayland_context *ctx,
1265 uint32_t id_surface)
1267 struct surface_context *ctx_surf = NULL;
1269 if (ctx->controller == NULL) {
1270 fprintf(stderr, "controller is not initialized in ilmControl\n");
1274 wl_list_for_each(ctx_surf, &ctx->list_surface, link) {
1275 if (ctx_surf->id_surface == id_surface) {
1280 fprintf(stderr, "failed to get surface context in ilmControl\n");
1284 static struct screen_context*
1285 get_screen_context_by_id(struct wayland_context *ctx, uint32_t id_screen)
1287 struct screen_context *ctx_scrn = NULL;
1289 if (ctx->controller == NULL) {
1290 fprintf(stderr, "get_screen_context_by_id: controller is NULL\n");
1294 wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
1295 if (ctx_scrn->id_screen == id_screen) {
1302 ILM_EXPORT ilmErrorTypes
1303 ilm_getPropertiesOfLayer(t_ilm_uint layerID,
1304 struct ilmLayerProperties* pLayerProperties)
1306 ilmErrorTypes returnValue = ILM_FAILED;
1307 struct ilm_control_context *ctx = sync_and_acquire_instance();
1308 struct layer_context *ctx_layer = NULL;
1310 if (pLayerProperties != NULL) {
1312 ctx_layer = (struct layer_context*)
1313 wayland_controller_get_layer_context(
1314 &ctx->wl, (uint32_t)layerID);
1316 if (ctx_layer != NULL) {
1317 *pLayerProperties = ctx_layer->prop;
1318 returnValue = ILM_SUCCESS;
1327 create_layerids(struct screen_context *ctx_screen,
1328 t_ilm_layer **layer_ids, t_ilm_uint *layer_count)
1330 struct layer_context *ctx_layer = NULL;
1331 t_ilm_layer *ids = NULL;
1333 *layer_count = wl_list_length(&ctx_screen->order.list_layer);
1334 if (*layer_count == 0) {
1339 *layer_ids = malloc(*layer_count * sizeof(t_ilm_layer));
1340 if (*layer_ids == NULL) {
1341 fprintf(stderr, "memory insufficient for layerids\n");
1347 wl_list_for_each_reverse(ctx_layer, &ctx_screen->order.list_layer, order.link) {
1348 *ids = (t_ilm_layer)ctx_layer->id_layer;
1353 ILM_EXPORT ilmErrorTypes
1354 ilm_getPropertiesOfScreen(t_ilm_display screenID,
1355 struct ilmScreenProperties* pScreenProperties)
1357 ilmErrorTypes returnValue = ILM_FAILED;
1359 if (! pScreenProperties)
1361 return ILM_ERROR_INVALID_ARGUMENTS;
1364 struct ilm_control_context *ctx = sync_and_acquire_instance();
1366 struct screen_context *ctx_screen = NULL;
1367 ctx_screen = get_screen_context_by_id(&ctx->wl, (uint32_t)screenID);
1368 if (ctx_screen != NULL) {
1369 *pScreenProperties = ctx_screen->prop;
1370 create_layerids(ctx_screen, &pScreenProperties->layerIds,
1371 &pScreenProperties->layerCount);
1372 returnValue = ILM_SUCCESS;
1379 ILM_EXPORT ilmErrorTypes
1380 ilm_getNumberOfHardwareLayers(t_ilm_uint screenID,
1381 t_ilm_uint* pNumberOfHardwareLayers)
1385 if (pNumberOfHardwareLayers != NULL) {
1386 *pNumberOfHardwareLayers = 0;
1393 ILM_EXPORT ilmErrorTypes
1394 ilm_getScreenIDs(t_ilm_uint* pNumberOfIDs, t_ilm_uint** ppIDs)
1396 ilmErrorTypes returnValue = ILM_FAILED;
1397 struct ilm_control_context *ctx = sync_and_acquire_instance();
1399 if ((pNumberOfIDs != NULL) && (ppIDs != NULL)) {
1400 struct screen_context *ctx_scrn = NULL;
1401 t_ilm_uint length = wl_list_length(&ctx->wl.list_screen);
1404 *ppIDs = (t_ilm_uint*)malloc(length * sizeof **ppIDs);
1405 if (*ppIDs != NULL) {
1406 t_ilm_uint* ids = *ppIDs;
1407 wl_list_for_each(ctx_scrn, &ctx->wl.list_screen, link) {
1408 *ids = ctx_scrn->id_screen;
1411 *pNumberOfIDs = length;
1413 returnValue = ILM_SUCCESS;
1421 ILM_EXPORT ilmErrorTypes
1422 ilm_getLayerIDs(t_ilm_int* pLength, t_ilm_layer** ppArray)
1424 ilmErrorTypes returnValue = ILM_FAILED;
1425 struct ilm_control_context *ctx = sync_and_acquire_instance();
1427 if ((pLength != NULL) && (ppArray != NULL)) {
1428 struct layer_context *ctx_layer = NULL;
1429 t_ilm_uint length = wl_list_length(&ctx->wl.list_layer);
1432 *ppArray = (t_ilm_layer*)malloc(length * sizeof **ppArray);
1433 if (*ppArray != NULL) {
1434 // compositor sends layers in opposite order
1435 // write ids from back to front to turn them around
1436 t_ilm_layer* ids = *ppArray;
1437 wl_list_for_each_reverse(ctx_layer, &ctx->wl.list_layer, link)
1439 *ids = ctx_layer->id_layer;
1444 returnValue = ILM_SUCCESS;
1452 ILM_EXPORT ilmErrorTypes
1453 ilm_getLayerIDsOnScreen(t_ilm_uint screenId,
1455 t_ilm_layer** ppArray)
1457 ilmErrorTypes returnValue = ILM_FAILED;
1458 struct ilm_control_context *ctx = sync_and_acquire_instance();
1460 if ((pLength != NULL) && (ppArray != NULL)) {
1461 struct screen_context *ctx_screen = NULL;
1462 ctx_screen = get_screen_context_by_id(&ctx->wl, screenId);
1463 if (ctx_screen != NULL) {
1464 struct layer_context *ctx_layer = NULL;
1465 t_ilm_int length = wl_list_length(&ctx_screen->order.list_layer);
1469 *ppArray = (t_ilm_layer*)malloc(length * sizeof **ppArray);
1470 if (*ppArray != NULL) {
1471 // compositor sends layers in opposite order
1472 // write ids from back to front to turn them around
1473 t_ilm_layer* ids = *ppArray;
1474 wl_list_for_each_reverse(ctx_layer, &ctx_screen->order.list_layer, order.link)
1476 *ids = ctx_layer->id_layer;
1488 returnValue = ILM_SUCCESS;
1496 ILM_EXPORT ilmErrorTypes
1497 ilm_getSurfaceIDs(t_ilm_int* pLength, t_ilm_surface** ppArray)
1499 ilmErrorTypes returnValue = ILM_FAILED;
1500 struct ilm_control_context *ctx = sync_and_acquire_instance();
1502 if ((pLength != NULL) && (ppArray != NULL)) {
1503 struct surface_context *ctx_surf = NULL;
1504 t_ilm_uint length = wl_list_length(&ctx->wl.list_surface);
1507 *ppArray = (t_ilm_surface*)malloc(length * sizeof **ppArray);
1508 if (*ppArray != NULL) {
1509 t_ilm_surface* ids = *ppArray;
1510 wl_list_for_each_reverse(ctx_surf, &ctx->wl.list_surface, link) {
1511 *ids = ctx_surf->id_surface;
1516 returnValue = ILM_SUCCESS;
1524 ILM_EXPORT ilmErrorTypes
1525 ilm_getSurfaceIDsOnLayer(t_ilm_layer layer,
1527 t_ilm_surface** ppArray)
1529 struct ilm_control_context *ctx = sync_and_acquire_instance();
1530 struct layer_context *ctx_layer = NULL;
1531 struct surface_context *ctx_surf = NULL;
1532 t_ilm_uint length = 0;
1533 t_ilm_surface* ids = NULL;
1535 if ((pLength == NULL) || (ppArray == NULL)) {
1540 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1541 &ctx->wl, (uint32_t)layer);
1543 if (ctx_layer == NULL) {
1548 length = wl_list_length(&ctx_layer->order.list_surface);
1549 *ppArray = (t_ilm_surface*)malloc(length * sizeof **ppArray);
1550 if (*ppArray == NULL) {
1556 wl_list_for_each_reverse(ctx_surf, &ctx_layer->order.list_surface, order.link) {
1557 *ids = (t_ilm_surface)ctx_surf->id_surface;
1566 static int create_controller_layer(struct wayland_context *ctx, t_ilm_uint width, t_ilm_uint height, t_ilm_layer layerid)
1568 struct layer_context *ctx_layer = calloc(1, sizeof *ctx_layer);
1569 if (ctx_layer == NULL) {
1570 fprintf(stderr, "Failed to allocate memory for layer_context\n");
1574 ctx_layer->controller = ivi_controller_layer_create(
1576 layerid, width, height);
1577 if (ctx_layer->controller == NULL) {
1578 fprintf(stderr, "Failed to create layer\n");
1582 ctx_layer->id_layer = layerid;
1583 ctx_layer->ctx = ctx;
1585 wl_list_init(&ctx_layer->link);
1586 wl_list_insert(&ctx->list_layer, &ctx_layer->link);
1587 wl_list_init(&ctx_layer->order.link);
1588 wl_list_init(&ctx_layer->order.list_surface);
1590 ivi_controller_layer_add_listener(ctx_layer->controller,
1591 &controller_layer_listener, ctx_layer);
1596 ILM_EXPORT ilmErrorTypes
1597 ilm_layerCreateWithDimension(t_ilm_layer* pLayerId,
1601 ilmErrorTypes returnValue = ILM_FAILED;
1602 struct ilm_control_context *ctx = sync_and_acquire_instance();
1603 uint32_t layerid = 0;
1604 int32_t is_inside = 0;
1607 if (pLayerId == NULL) {
1611 if (*pLayerId != INVALID_ID) {
1612 /* Return failed, if layerid is already inside list_layer */
1613 is_inside = wayland_controller_is_inside_layer_list(
1614 &ctx->wl.list_layer, *pLayerId);
1615 if (0 != is_inside) {
1616 fprintf(stderr, "layerid=%d is already used.\n", *pLayerId);
1619 layerid = *pLayerId;
1622 /* Generate ID, if layerid is INVALID_ID */
1623 layerid = gen_layer_id(ctx);
1624 *pLayerId = layerid;
1627 if (create_controller_layer(&ctx->wl, width, height, layerid) == 0)
1629 returnValue = ILM_SUCCESS;
1637 ILM_EXPORT ilmErrorTypes
1638 ilm_layerRemove(t_ilm_layer layerId)
1640 ilmErrorTypes returnValue = ILM_FAILED;
1641 struct ilm_control_context *ctx = sync_and_acquire_instance();
1642 struct layer_context *ctx_layer = NULL;
1643 struct layer_context *ctx_next = NULL;
1645 wl_list_for_each_safe(ctx_layer, ctx_next,
1646 &ctx->wl.list_layer, link) {
1647 if (ctx_layer->id_layer == layerId) {
1648 ivi_controller_layer_destroy(ctx_layer->controller, 1);
1650 wl_list_remove(&ctx_layer->link);
1653 returnValue = ILM_SUCCESS;
1662 ILM_EXPORT ilmErrorTypes
1663 ilm_layerGetType(t_ilm_layer layerId, ilmLayerType* pLayerType)
1667 return ILM_ERROR_INVALID_ARGUMENTS;
1670 struct ilm_control_context *ctx = sync_and_acquire_instance();
1672 *pLayerType = wayland_controller_is_inside_layer_list(&ctx->wl.list_layer, layerId) ?
1673 ILM_LAYERTYPE_SOFTWARE2D :
1674 ILM_LAYERTYPE_UNKNOWN;
1677 return ILM_SUCCESS; // even if non existent?
1680 ILM_EXPORT ilmErrorTypes
1681 ilm_layerSetVisibility(t_ilm_layer layerId, t_ilm_bool newVisibility)
1683 ilmErrorTypes returnValue = ILM_FAILED;
1684 struct ilm_control_context *ctx = sync_and_acquire_instance();
1685 struct layer_context *ctx_layer = NULL;
1687 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1688 &ctx->wl, (uint32_t)layerId);
1690 if (ctx_layer != NULL) {
1691 uint32_t visibility = 0;
1692 if (newVisibility == ILM_TRUE) {
1695 ivi_controller_layer_set_visibility(ctx_layer->controller,
1697 returnValue = ILM_SUCCESS;
1704 ILM_EXPORT ilmErrorTypes
1705 ilm_layerGetVisibility(t_ilm_layer layerId, t_ilm_bool *pVisibility)
1707 ilmErrorTypes returnValue = ILM_FAILED;
1708 struct ilm_control_context *ctx = sync_and_acquire_instance();
1710 if (pVisibility != NULL) {
1711 struct layer_context *ctx_layer = NULL;
1713 ctx_layer = (struct layer_context*)
1714 wayland_controller_get_layer_context(
1715 &ctx->wl, (uint32_t)layerId);
1717 if (ctx_layer != NULL) {
1718 *pVisibility = ctx_layer->prop.visibility;
1719 returnValue = ILM_SUCCESS;
1727 ILM_EXPORT ilmErrorTypes
1728 ilm_layerSetOpacity(t_ilm_layer layerId, t_ilm_float opacity)
1730 ilmErrorTypes returnValue = ILM_FAILED;
1731 struct ilm_control_context *ctx = sync_and_acquire_instance();
1732 struct layer_context *ctx_layer = NULL;
1734 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1735 &ctx->wl, (uint32_t)layerId);
1737 if (ctx_layer != NULL) {
1738 wl_fixed_t opacity_fixed = wl_fixed_from_double((double)opacity);
1739 ivi_controller_layer_set_opacity(ctx_layer->controller,
1741 returnValue = ILM_SUCCESS;
1748 ILM_EXPORT ilmErrorTypes
1749 ilm_layerGetOpacity(t_ilm_layer layerId, t_ilm_float *pOpacity)
1751 ilmErrorTypes returnValue = ILM_FAILED;
1752 struct ilm_control_context *ctx = sync_and_acquire_instance();
1754 if (pOpacity != NULL) {
1755 struct layer_context *ctx_layer = NULL;
1757 ctx_layer = (struct layer_context*)
1758 wayland_controller_get_layer_context(
1759 &ctx->wl, (uint32_t)layerId);
1761 if (ctx_layer != NULL) {
1762 *pOpacity = ctx_layer->prop.opacity;
1763 returnValue = ILM_SUCCESS;
1771 ILM_EXPORT ilmErrorTypes
1772 ilm_layerSetSourceRectangle(t_ilm_layer layerId,
1773 t_ilm_uint x, t_ilm_uint y,
1774 t_ilm_uint width, t_ilm_uint height)
1776 ilmErrorTypes returnValue = ILM_FAILED;
1777 struct ilm_control_context *ctx = sync_and_acquire_instance();
1778 struct layer_context *ctx_layer = NULL;
1780 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1781 &ctx->wl, (uint32_t)layerId);
1783 if (ctx_layer != NULL) {
1784 ivi_controller_layer_set_source_rectangle(ctx_layer->controller,
1789 returnValue = ILM_SUCCESS;
1796 ILM_EXPORT ilmErrorTypes
1797 ilm_layerSetDestinationRectangle(t_ilm_layer layerId,
1798 t_ilm_int x, t_ilm_int y,
1799 t_ilm_int width, t_ilm_int height)
1801 ilmErrorTypes returnValue = ILM_FAILED;
1802 struct ilm_control_context *ctx = sync_and_acquire_instance();
1803 struct layer_context *ctx_layer = NULL;
1805 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1806 &ctx->wl, (uint32_t)layerId);
1807 if (ctx_layer != NULL) {
1808 ivi_controller_layer_set_destination_rectangle(
1809 ctx_layer->controller,
1810 (uint32_t)x, (uint32_t)y,
1813 returnValue = ILM_SUCCESS;
1820 ILM_EXPORT ilmErrorTypes
1821 ilm_layerGetDimension(t_ilm_layer layerId, t_ilm_uint *pDimension)
1823 ilmErrorTypes returnValue = ILM_FAILED;
1824 struct ilm_control_context *ctx = sync_and_acquire_instance();
1825 struct layer_context *ctx_layer = NULL;
1827 if (pDimension != NULL) {
1828 ctx_layer = (struct layer_context*)
1829 wayland_controller_get_layer_context(
1830 &ctx->wl, (uint32_t)layerId);
1831 if (ctx_layer != NULL) {
1832 *pDimension = ctx_layer->prop.destWidth;
1833 *(pDimension + 1) = ctx_layer->prop.destHeight;
1834 returnValue = ILM_SUCCESS;
1842 ILM_EXPORT ilmErrorTypes
1843 ilm_layerSetDimension(t_ilm_layer layerId, t_ilm_uint *pDimension)
1845 ilmErrorTypes returnValue = ILM_FAILED;
1846 struct ilm_control_context *ctx = sync_and_acquire_instance();
1847 struct layer_context *ctx_layer = NULL;
1849 if (pDimension != NULL) {
1850 ctx_layer = (struct layer_context*)
1851 wayland_controller_get_layer_context(
1852 &ctx->wl, (uint32_t)layerId);
1853 if (ctx_layer != NULL) {
1854 ivi_controller_layer_set_destination_rectangle(
1855 ctx_layer->controller,
1856 ctx_layer->prop.destX, ctx_layer->prop.destY,
1857 (int32_t)*pDimension, (int32_t)*(pDimension + 1));
1858 returnValue = ILM_SUCCESS;
1866 ILM_EXPORT ilmErrorTypes
1867 ilm_layerGetPosition(t_ilm_layer layerId, t_ilm_uint *pPosition)
1869 ilmErrorTypes returnValue = ILM_FAILED;
1870 struct ilm_control_context *ctx = sync_and_acquire_instance();
1871 struct layer_context *ctx_layer = NULL;
1873 if (pPosition != NULL) {
1874 ctx_layer = (struct layer_context*)
1875 wayland_controller_get_layer_context(
1876 &ctx->wl, (uint32_t)layerId);
1877 if (ctx_layer != NULL) {
1878 *pPosition = ctx_layer->prop.destX;
1879 *(pPosition + 1) = ctx_layer->prop.destY;
1880 returnValue = ILM_SUCCESS;
1888 ILM_EXPORT ilmErrorTypes
1889 ilm_layerSetPosition(t_ilm_layer layerId, t_ilm_uint *pPosition)
1891 ilmErrorTypes returnValue = ILM_FAILED;
1892 struct ilm_control_context *ctx = sync_and_acquire_instance();
1893 struct layer_context *ctx_layer = NULL;
1895 if (pPosition != NULL) {
1896 ctx_layer = (struct layer_context*)
1897 wayland_controller_get_layer_context(
1898 &ctx->wl, (uint32_t)layerId);
1899 if (ctx_layer != NULL) {
1900 ivi_controller_layer_set_destination_rectangle(
1901 ctx_layer->controller,
1902 (int32_t)*pPosition, (int32_t)*(pPosition + 1),
1903 ctx_layer->prop.destWidth, ctx_layer->prop.destHeight);
1904 returnValue = ILM_SUCCESS;
1912 ILM_EXPORT ilmErrorTypes
1913 ilm_layerSetOrientation(t_ilm_layer layerId, ilmOrientation orientation)
1915 ilmErrorTypes returnValue = ILM_FAILED;
1916 struct ilm_control_context *ctx = sync_and_acquire_instance();
1917 struct layer_context *ctx_layer = NULL;
1918 int32_t iviorientation = 0;
1921 switch(orientation) {
1923 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES;
1926 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES;
1928 case ILM_ONEHUNDREDEIGHTY:
1929 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES;
1931 case ILM_TWOHUNDREDSEVENTY:
1932 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES;
1935 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
1939 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1940 &ctx->wl, (uint32_t)layerId);
1941 if (ctx_layer == NULL) {
1942 returnValue = ILM_FAILED;
1946 ivi_controller_layer_set_orientation(ctx_layer->controller,
1949 returnValue = ILM_SUCCESS;
1956 ILM_EXPORT ilmErrorTypes
1957 ilm_layerGetOrientation(t_ilm_layer layerId, ilmOrientation *pOrientation)
1959 ilmErrorTypes returnValue = ILM_FAILED;
1960 struct ilm_control_context *ctx = sync_and_acquire_instance();
1961 struct layer_context *ctx_layer = NULL;
1963 if (pOrientation != NULL) {
1964 ctx_layer = (struct layer_context*)
1965 wayland_controller_get_layer_context(
1966 &ctx->wl, (uint32_t)layerId);
1967 if (ctx_layer != NULL) {
1968 *pOrientation = ctx_layer->prop.orientation;
1969 returnValue = ILM_SUCCESS;
1977 ILM_EXPORT ilmErrorTypes
1978 ilm_layerSetChromaKey(t_ilm_layer layerId, t_ilm_int* pColor)
1986 ILM_EXPORT ilmErrorTypes
1987 ilm_layerSetRenderOrder(t_ilm_layer layerId,
1988 t_ilm_surface *pSurfaceId,
1991 ilmErrorTypes returnValue = ILM_FAILED;
1992 struct ilm_control_context *ctx = sync_and_acquire_instance();
1993 struct layer_context *ctx_layer = NULL;
1995 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
1996 &ctx->wl, (uint32_t)layerId);
2000 struct wl_array ids;
2001 wl_array_init(&ids);
2002 uint32_t *pids = wl_array_add(&ids, number * sizeof *pids);
2004 for (i = 0; i < number; i++) pids[i] = (uint32_t)pSurfaceId[i];
2005 ivi_controller_layer_set_render_order(ctx_layer->controller, &ids);
2006 wl_array_release(&ids);
2007 returnValue = ILM_SUCCESS;
2014 ILM_EXPORT ilmErrorTypes
2015 ilm_layerGetCapabilities(t_ilm_layer layerId,
2016 t_ilm_layercapabilities *pCapabilities)
2019 (void)pCapabilities;
2024 ILM_EXPORT ilmErrorTypes
2025 ilm_layerTypeGetCapabilities(ilmLayerType layerType,
2026 t_ilm_layercapabilities *pCapabilities)
2029 (void)pCapabilities;
2034 ILM_EXPORT ilmErrorTypes
2035 ilm_surfaceSetVisibility(t_ilm_surface surfaceId, t_ilm_bool newVisibility)
2037 ilmErrorTypes returnValue = ILM_FAILED;
2038 struct ilm_control_context *ctx = sync_and_acquire_instance();
2039 struct surface_context *ctx_surf = NULL;
2040 uint32_t visibility = 0;
2042 if (newVisibility == ILM_TRUE) {
2045 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2047 ivi_controller_surface_set_visibility(ctx_surf->controller,
2049 returnValue = ILM_SUCCESS;
2056 ILM_EXPORT ilmErrorTypes
2057 ilm_surfaceSetOpacity(t_ilm_surface surfaceId, t_ilm_float opacity)
2059 ilmErrorTypes returnValue = ILM_FAILED;
2060 struct ilm_control_context *ctx = sync_and_acquire_instance();
2061 struct surface_context *ctx_surf = NULL;
2062 wl_fixed_t opacity_fixed = 0;
2064 opacity_fixed = wl_fixed_from_double((double)opacity);
2065 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2067 ivi_controller_surface_set_opacity(ctx_surf->controller,
2069 returnValue = ILM_SUCCESS;
2076 ILM_EXPORT ilmErrorTypes
2077 ilm_surfaceGetOpacity(t_ilm_surface surfaceId, t_ilm_float *pOpacity)
2079 ilmErrorTypes returnValue = ILM_FAILED;
2080 struct ilm_control_context *ctx = sync_and_acquire_instance();
2082 if (pOpacity != NULL) {
2083 struct surface_context *ctx_surf = NULL;
2084 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2086 *pOpacity = ctx_surf->prop.opacity;
2087 returnValue = ILM_SUCCESS;
2095 ILM_EXPORT ilmErrorTypes
2096 ilm_SetKeyboardFocusOn(t_ilm_surface surfaceId)
2098 ilmErrorTypes returnValue = ILM_FAILED;
2100 returnValue = ILM_SUCCESS;
2104 ILM_EXPORT ilmErrorTypes
2105 ilm_GetKeyboardFocusSurfaceId(t_ilm_surface* pSurfaceId)
2107 ilmErrorTypes returnValue = ILM_FAILED;
2109 returnValue = ILM_SUCCESS;
2113 ILM_EXPORT ilmErrorTypes
2114 ilm_surfaceSetDestinationRectangle(t_ilm_surface surfaceId,
2115 t_ilm_int x, t_ilm_int y,
2116 t_ilm_int width, t_ilm_int height)
2118 ilmErrorTypes returnValue = ILM_FAILED;
2119 struct ilm_control_context *ctx = sync_and_acquire_instance();
2120 struct surface_context *ctx_surf = NULL;
2122 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2124 ivi_controller_surface_set_destination_rectangle(
2125 ctx_surf->controller,
2126 x, y, width, height);
2127 returnValue = ILM_SUCCESS;
2134 ILM_EXPORT ilmErrorTypes
2135 ilm_surfaceSetDimension(t_ilm_surface surfaceId, t_ilm_uint *pDimension)
2137 ilmErrorTypes returnValue = ILM_FAILED;
2138 struct ilm_control_context *ctx = sync_and_acquire_instance();
2140 if (pDimension != NULL) {
2141 struct surface_context *ctx_surf = NULL;
2142 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2144 uint32_t width = *pDimension;
2145 uint32_t height = *(pDimension + 1);
2146 ivi_controller_surface_set_destination_rectangle(
2147 ctx_surf->controller,
2148 ctx_surf->prop.destX, ctx_surf->prop.destY, width, height);
2149 returnValue = ILM_SUCCESS;
2157 ILM_EXPORT ilmErrorTypes
2158 ilm_surfaceGetPosition(t_ilm_surface surfaceId, t_ilm_uint *pPosition)
2160 ilmErrorTypes returnValue = ILM_FAILED;
2161 struct ilm_control_context *ctx = sync_and_acquire_instance();
2163 if (pPosition != NULL) {
2164 struct surface_context *ctx_surf = NULL;
2165 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2167 *pPosition = ctx_surf->prop.destX;
2168 *(pPosition + 1) = ctx_surf->prop.destY;
2169 returnValue = ILM_SUCCESS;
2177 ILM_EXPORT ilmErrorTypes
2178 ilm_surfaceSetPosition(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 int32_t destX = (int32_t)*pPosition;
2188 int32_t destY = (int32_t)*(pPosition + 1);
2189 ivi_controller_surface_set_destination_rectangle(
2190 ctx_surf->controller, destX, destY,
2191 ctx_surf->prop.destWidth, ctx_surf->prop.destHeight);
2192 returnValue = ILM_SUCCESS;
2200 ILM_EXPORT ilmErrorTypes
2201 ilm_surfaceSetOrientation(t_ilm_surface surfaceId,
2202 ilmOrientation orientation)
2204 ilmErrorTypes returnValue = ILM_FAILED;
2205 struct ilm_control_context *ctx = sync_and_acquire_instance();
2206 struct surface_context *ctx_surf = NULL;
2207 int32_t iviorientation = 0;
2210 switch(orientation) {
2212 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_0_DEGREES;
2215 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_90_DEGREES;
2217 case ILM_ONEHUNDREDEIGHTY:
2218 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_180_DEGREES;
2220 case ILM_TWOHUNDREDSEVENTY:
2221 iviorientation = IVI_CONTROLLER_SURFACE_ORIENTATION_270_DEGREES;
2224 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2228 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2229 if (ctx_surf == NULL) {
2230 returnValue = ILM_FAILED;
2234 ivi_controller_surface_set_orientation(ctx_surf->controller,
2237 returnValue = ILM_SUCCESS;
2244 ILM_EXPORT ilmErrorTypes
2245 ilm_surfaceGetOrientation(t_ilm_surface surfaceId,
2246 ilmOrientation *pOrientation)
2248 ilmErrorTypes returnValue = ILM_FAILED;
2249 struct ilm_control_context *ctx = sync_and_acquire_instance();
2251 if (pOrientation != NULL) {
2252 struct surface_context *ctx_surf = NULL;
2253 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2255 *pOrientation = ctx_surf->prop.orientation;
2256 returnValue = ILM_SUCCESS;
2264 ILM_EXPORT ilmErrorTypes
2265 ilm_surfaceGetPixelformat(t_ilm_layer surfaceId,
2266 ilmPixelFormat *pPixelformat)
2268 ilmErrorTypes returnValue = ILM_FAILED;
2269 struct ilm_control_context *ctx = sync_and_acquire_instance();
2271 if (pPixelformat != NULL) {
2272 struct surface_context *ctx_surf = NULL;
2273 ctx_surf = get_surface_context(&ctx->wl, surfaceId);
2275 *pPixelformat = ctx_surf->prop.pixelformat;
2276 returnValue = ILM_SUCCESS;
2284 ILM_EXPORT ilmErrorTypes
2285 ilm_surfaceSetChromaKey(t_ilm_surface surfaceId, t_ilm_int* pColor)
2293 ILM_EXPORT ilmErrorTypes
2294 ilm_displaySetRenderOrder(t_ilm_display display,
2295 t_ilm_layer *pLayerId, const t_ilm_uint number)
2297 ilmErrorTypes returnValue = ILM_FAILED;
2298 struct ilm_control_context *ctx = sync_and_acquire_instance();
2299 struct screen_context *ctx_scrn = NULL;
2301 ctx_scrn = get_screen_context_by_id(&ctx->wl, (uint32_t)display);
2302 if (ctx_scrn != NULL) {
2303 struct wl_array ids;
2304 wl_array_init(&ids);
2305 uint32_t *pids = wl_array_add(&ids, number * sizeof *pids);
2307 for (i = 0; i < number; i++) pids[i] = (uint32_t)pLayerId[i];
2308 ivi_controller_screen_set_render_order(ctx_scrn->controller, &ids);
2309 wl_array_release(&ids);
2310 returnValue = ILM_SUCCESS;
2317 ILM_EXPORT ilmErrorTypes
2318 ilm_takeScreenshot(t_ilm_uint screen, t_ilm_const_string filename)
2320 ilmErrorTypes returnValue = ILM_FAILED;
2321 struct ilm_control_context *ctx = sync_and_acquire_instance();
2322 struct screen_context *ctx_scrn = NULL;
2324 ctx_scrn = get_screen_context_by_id(&ctx->wl, (uint32_t)screen);
2325 if (ctx_scrn != NULL) {
2326 ivi_controller_screen_screenshot(ctx_scrn->controller,
2328 wl_display_flush(ctx->wl.display);
2329 returnValue = ILM_SUCCESS;
2336 ILM_EXPORT ilmErrorTypes
2337 ilm_takeLayerScreenshot(t_ilm_const_string filename, t_ilm_layer layerid)
2339 ilmErrorTypes returnValue = ILM_FAILED;
2340 struct ilm_control_context *ctx = sync_and_acquire_instance();
2341 struct layer_context *ctx_layer = NULL;
2343 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2344 &ctx->wl, (uint32_t)layerid);
2345 if (ctx_layer != NULL) {
2346 ivi_controller_layer_screenshot(ctx_layer->controller,
2348 wl_display_flush(ctx->wl.display);
2349 returnValue = ILM_SUCCESS;
2356 ILM_EXPORT ilmErrorTypes
2357 ilm_takeSurfaceScreenshot(t_ilm_const_string filename,
2358 t_ilm_surface surfaceid)
2360 ilmErrorTypes returnValue = ILM_FAILED;
2361 struct ilm_control_context *ctx = sync_and_acquire_instance();
2362 struct surface_context *ctx_surf = NULL;
2364 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceid);
2366 ivi_controller_surface_screenshot(ctx_surf->controller,
2368 wl_display_flush(ctx->wl.display);
2369 returnValue = ILM_SUCCESS;
2376 ILM_EXPORT ilmErrorTypes
2377 ilm_SetOptimizationMode(ilmOptimization id, ilmOptimizationMode mode)
2385 ILM_EXPORT ilmErrorTypes
2386 ilm_GetOptimizationMode(ilmOptimization id, ilmOptimizationMode* pMode)
2394 ILM_EXPORT ilmErrorTypes
2395 ilm_layerAddNotification(t_ilm_layer layer,
2396 layerNotificationFunc callback)
2398 ilmErrorTypes returnValue = ILM_FAILED;
2399 struct ilm_control_context *ctx = sync_and_acquire_instance();
2400 struct layer_context *ctx_layer = NULL;
2402 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2403 &ctx->wl, (uint32_t)layer);
2404 if (ctx_layer == NULL) {
2405 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2407 ctx_layer->notification = callback;
2409 returnValue = ILM_SUCCESS;
2416 ILM_EXPORT ilmErrorTypes
2417 ilm_layerRemoveNotification(t_ilm_layer layer)
2419 return ilm_layerAddNotification(layer, NULL);
2422 ILM_EXPORT ilmErrorTypes
2423 ilm_surfaceAddNotification(t_ilm_surface surface,
2424 surfaceNotificationFunc callback)
2426 ilmErrorTypes returnValue = ILM_FAILED;
2427 struct ilm_control_context *ctx = sync_and_acquire_instance();
2428 struct surface_context *ctx_surf = NULL;
2430 ctx_surf = (struct surface_context*)get_surface_context(
2431 &ctx->wl, (uint32_t)surface);
2432 if (ctx_surf == NULL) {
2433 if (callback != NULL) {
2434 callback((uint32_t)surface, NULL, ILM_NOTIFICATION_CONTENT_REMOVED);
2435 controller_listener_surface(ctx, ctx->wl.controller, (uint32_t)surface);
2436 ctx_surf = (struct surface_context*)get_surface_context(
2437 &ctx->wl, (uint32_t)surface);
2438 ctx_surf->is_surface_creation_noticed = false;
2442 if (ctx_surf == NULL) {
2443 returnValue = ILM_ERROR_INVALID_ARGUMENTS;
2446 ctx_surf->notification = callback;
2448 returnValue = ILM_SUCCESS;
2455 ILM_EXPORT ilmErrorTypes
2456 ilm_surfaceRemoveNotification(t_ilm_surface surface)
2458 return ilm_surfaceAddNotification(surface, NULL);
2461 ILM_EXPORT ilmErrorTypes
2462 ilm_getNativeHandle(t_ilm_uint pid, t_ilm_int *n_handle,
2463 t_ilm_nativehandle **p_handles)
2465 struct ilm_control_context *ctx = sync_and_acquire_instance();
2466 struct nativehandle_context *p_nh_ctx = NULL;
2471 wl_list_for_each(p_nh_ctx, &ctx->list_nativehandle, link)
2473 if (p_nh_ctx->pid == pid)
2477 (t_ilm_nativehandle*)malloc(sizeof(t_ilm_nativehandle));
2478 (*p_handles)[0] = p_nh_ctx->nativehandle;
2484 return (*n_handle > 0) ? ILM_SUCCESS : ILM_FAILED;
2487 ILM_EXPORT ilmErrorTypes
2488 ilm_getPropertiesOfSurface(t_ilm_uint surfaceID,
2489 struct ilmSurfaceProperties* pSurfaceProperties)
2491 ilmErrorTypes returnValue = ILM_FAILED;
2492 struct ilm_control_context *ctx = sync_and_acquire_instance();
2494 if (pSurfaceProperties != NULL) {
2495 struct surface_context *ctx_surf = NULL;
2497 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceID);
2498 if (ctx_surf != NULL) {
2500 *pSurfaceProperties = ctx_surf->prop;
2501 returnValue = ILM_SUCCESS;
2509 ILM_EXPORT ilmErrorTypes
2510 ilm_layerAddSurface(t_ilm_layer layerId,
2511 t_ilm_surface surfaceId)
2513 ilmErrorTypes returnValue = ILM_FAILED;
2514 struct ilm_control_context *ctx = sync_and_acquire_instance();
2515 struct layer_context *ctx_layer = NULL;
2516 struct surface_context *ctx_surf = NULL;
2518 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2519 &ctx->wl, (uint32_t)layerId);
2520 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2521 if ((ctx_layer != NULL) && (ctx_surf != NULL)) {
2522 ivi_controller_layer_add_surface(ctx_layer->controller,
2523 ctx_surf->controller);
2524 returnValue = ILM_SUCCESS;
2531 ILM_EXPORT ilmErrorTypes
2532 ilm_layerRemoveSurface(t_ilm_layer layerId,
2533 t_ilm_surface surfaceId)
2535 ilmErrorTypes returnValue = ILM_FAILED;
2536 struct ilm_control_context *ctx = sync_and_acquire_instance();
2537 struct layer_context *ctx_layer = NULL;
2538 struct surface_context *ctx_surf = NULL;
2540 ctx_layer = (struct layer_context*)wayland_controller_get_layer_context(
2541 &ctx->wl, (uint32_t)layerId);
2542 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2543 if ((ctx_layer != NULL) && (ctx_surf != NULL)) {
2544 ivi_controller_layer_remove_surface(ctx_layer->controller,
2545 ctx_surf->controller);
2546 returnValue = ILM_SUCCESS;
2553 ILM_EXPORT ilmErrorTypes
2554 ilm_surfaceGetDimension(t_ilm_surface surfaceId,
2555 t_ilm_uint *pDimension)
2557 ilmErrorTypes returnValue = ILM_FAILED;
2558 struct ilm_control_context *ctx = sync_and_acquire_instance();
2560 if (pDimension != NULL) {
2561 struct surface_context *ctx_surf = NULL;
2563 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2564 if (ctx_surf != NULL) {
2565 *pDimension = (t_ilm_uint)ctx_surf->prop.destWidth;
2566 *(pDimension + 1) = (t_ilm_uint)ctx_surf->prop.destHeight;
2567 returnValue = ILM_SUCCESS;
2575 ILM_EXPORT ilmErrorTypes
2576 ilm_surfaceGetVisibility(t_ilm_surface surfaceId,
2577 t_ilm_bool *pVisibility)
2579 ilmErrorTypes returnValue = ILM_FAILED;
2580 struct ilm_control_context *ctx = sync_and_acquire_instance();
2581 struct surface_context *ctx_surf = NULL;
2583 if (pVisibility != NULL) {
2584 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2585 if (ctx_surf != NULL) {
2586 *pVisibility = (t_ilm_bool)ctx_surf->prop.visibility;
2587 returnValue = ILM_SUCCESS;
2595 ILM_EXPORT ilmErrorTypes
2596 ilm_surfaceSetSourceRectangle(t_ilm_surface surfaceId,
2597 t_ilm_int x, t_ilm_int y,
2598 t_ilm_int width, t_ilm_int height)
2600 ilmErrorTypes returnValue = ILM_FAILED;
2601 struct ilm_control_context *ctx = sync_and_acquire_instance();
2602 struct surface_context *ctx_surf = NULL;
2604 ctx_surf = get_surface_context(&ctx->wl, (uint32_t)surfaceId);
2605 if (ctx_surf != NULL) {
2606 if (ctx_surf->controller != NULL) {
2607 ivi_controller_surface_set_source_rectangle(
2608 ctx_surf->controller,
2609 x, y, width, height);
2610 returnValue = ILM_SUCCESS;
2618 ILM_EXPORT ilmErrorTypes
2619 ilm_commitChanges(void)
2621 ilmErrorTypes returnValue = ILM_FAILED;
2622 struct ilm_control_context *ctx = sync_and_acquire_instance();
2624 if (ctx->wl.controller != NULL) {
2625 ivi_controller_commit_changes(ctx->wl.controller);
2627 if (display_roundtrip_queue(ctx->wl.display, ctx->wl.queue) != -1)
2629 returnValue = ILM_SUCCESS;