Added "display" property for overlay video sink 38/98138/1
authorVolodymyr Brynza <v.brynza@samsung.com>
Tue, 8 Nov 2016 11:50:05 +0000 (13:50 +0200)
committereunhae choi <eunhae1.choi@samsung.com>
Wed, 16 Nov 2016 08:10:58 +0000 (00:10 -0800)
Change-Id: I6ba4212c81ed0e32a3a4c68369f9f206547425ee
Signed-off-by: Volodymyr Brynza <v.brynza@samsung.com>
(cherry picked from commit 754fdcc29b9e958dc221e68eaee2c9546ad635ab)

CMakeLists.txt
include/media_streamer.h
include/media_streamer_priv.h
packaging/capi-media-streamer.spec
src/media_streamer_node.c
test/CMakeLists.txt
test/media_streamer_test.c

index c87ed3057a21896004636384adcb70b5ad9e4b28..01c07030ff7d4801a282d30459b63bfb71dddd77 100644 (file)
@@ -10,8 +10,8 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX})
 SET(INC_DIR include)
 INCLUDE_DIRECTORIES(${INC_DIR})
 
-SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser bundle libtbm gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 cynara-client capi-system-info")
-SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 cynara-client capi-system-info")
+SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser bundle libtbm gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore elementary")
+SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore evas elementary")
 
 INCLUDE(FindPkgConfig)
 pkg_check_modules(${fw_name} REQUIRED ${dependents})
@@ -100,4 +100,3 @@ ADD_CUSTOM_COMMAND(
 )
 
 ENDIF(UNIX)
-
index fec5ae318c1cf309e5c6ac9b770301f5d04bab59..f011fe4def68402ea0793e8a3845733c7aaed4b5 100644 (file)
@@ -337,6 +337,15 @@ typedef enum {
  */
 #define MEDIA_STREAMER_PARAM_DISPLAY_GEOMETRY_METHOD "display-geometry-method"
 
+/**
+ * @brief Definition for display parameter of sink node.
+ * @details It is a object to draw video frame on.
+ *          Data type is Pointer.
+ * @since_tizen 3.0
+ * @see media_streamer_node_get_params
+ */
+#define MEDIA_STREAMER_PARAM_DISPLAY "display"
+
 /**
  * @brief Definition for visible parameter of sink node
  * @details Draws screen or blacks out.
index c559c1a896538c026d71f34998ab8ce7b0859ef0..8ffe1c470d0165eb67d646c5492d30512ff26ee6 100755 (executable)
@@ -132,6 +132,15 @@ typedef struct {
        void *callbacks_structure;
 } media_streamer_node_s;
 
+typedef struct _media_streamer_wl_info_s {
+       int parent_id;
+       int window_x;
+       int window_y;
+       int window_width;
+       int window_height;
+       void *evas_obj;
+} media_streamer_wl_info_s;
+
 /* Private functions definition */
 
 /**
index 85986b0be781984664bb7ac95970fc7e2ee20f27..716fcb813eee288c804ada3e323b8b20c491bcd7 100644 (file)
@@ -22,6 +22,13 @@ BuildRequires:  pkgconfig(iniparser)
 BuildRequires:  pkgconfig(bundle)
 BuildRequires:  pkgconfig(cynara-client)
 BuildRequires:  pkgconfig(capi-system-info)
+#BuildRequires:  pkgconfig(libtbm)
+BuildRequires:  pkgconfig(tizen-extension-client)
+BuildRequires:  pkgconfig(elementary)
+BuildRequires:  pkgconfig(ecore)
+BuildRequires:  pkgconfig(evas)
+BuildRequires:  pkgconfig(ecore-wayland)
+BuildRequires:  pkgconfig(appcore-efl)
 
 %description
 A MediaStreamer library in Tizen Native API.
index ec58cf264be823bfd4f96da1d1fe42ca636c62ff..874afa91f72848fc1cb0402528ff9b1fed35a91a 100644 (file)
 #include <media_streamer_gst.h>
 #include <cynara-client.h>
 #include <system_info.h>
+#include <Elementary.h>
+#include <Evas.h>
+#include <Ecore_Wayland.h>
+#include <tizen-extension-client-protocol.h>
+#include <gst/video/videooverlay.h>
 
 #define SMACK_LABEL_LEN 255
 #define DEFAULT_URI_SCHEME_LENGTH 10
@@ -45,6 +50,7 @@ param_s param_table[] = {
        {MEDIA_STREAMER_PARAM_ROTATE, "rotate"},
        {MEDIA_STREAMER_PARAM_FLIP, "flip"},
        {MEDIA_STREAMER_PARAM_DISPLAY_GEOMETRY_METHOD, "display-geometry-method"},
+       {MEDIA_STREAMER_PARAM_DISPLAY, "display"},
        {MEDIA_STREAMER_PARAM_VISIBLE, "visible"},
        {MEDIA_STREAMER_PARAM_HOST, "host"},
        {MEDIA_STREAMER_PARAM_SEGMENT_LOCATION, "location"},
@@ -762,7 +768,7 @@ static void _src_node_prepare(const GValue *item, gpointer user_data)
        GstElement *found_element = NULL;
 
        if (__ms_src_need_typefind(src_pad)) {
-               __ms_find_type(ms_streamer, src_element);
+               __ms_find_type(ms_streamer,src_element);
                MS_SAFE_UNREF(src_element);
        } else {
                /* Check the source element`s pad type */
@@ -795,8 +801,7 @@ static void _src_node_prepare(const GValue *item, gpointer user_data)
        MS_SAFE_UNREF(src_pad);
 }
 
-static gboolean demux_find(gpointer key, gpointer value, gpointer user_data)
-{
+static gboolean demux_find(gpointer key, gpointer value, gpointer user_data) {
        return g_strrstr((char *)key, "demux") != NULL;
 }
 
@@ -1108,6 +1113,242 @@ int __ms_node_get_param_value(media_streamer_node_s *node, param_s *param, char
        return ret;
 }
 
+static void __global(void *data, struct wl_registry *registry,
+       uint32_t name, const char *interface, uint32_t version)
+{
+       struct tizen_surface **tz_surface = NULL;
+
+       if (!data) {
+               LOGE("NULL data");
+               return;
+       }
+
+       tz_surface = (struct tizen_surface **)data;
+
+       if (!interface) {
+               LOGW("NULL interface");
+               return;
+       }
+
+       if (strcmp(interface, "tizen_surface") == 0) {
+               LOGD("binding tizen surface for wayland");
+
+               *tz_surface = wl_registry_bind(registry, name, &tizen_surface_interface, version);
+               if (*tz_surface == NULL)
+                       LOGE("failed to bind");
+
+               LOGD("done");
+       }
+
+       return;
+}
+
+static void __global_remove(void *data, struct wl_registry *wl_registry, uint32_t name)
+{
+       LOGD("enter");
+       return;
+}
+
+static const struct wl_registry_listener _media_streamer_wl_registry_listener = {
+       __global,
+       __global_remove
+};
+
+void __parent_id_getter(void *data, struct tizen_resource *tizen_resource, uint32_t id)
+{
+       if (!data) {
+               LOGE("NULL data");
+               return;
+       }
+
+       *((unsigned int *)data) = id;
+
+       LOGD("[CLIENT] got parent_id [%u] from server", id);
+
+       return;
+}
+
+static const struct tizen_resource_listener _media_streamer_tz_resource_listener = {
+       __parent_id_getter
+};
+
+int _media_streamer_get_wl_info(Evas_Object *obj, media_streamer_wl_info_s *wl_info)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+       Ecore_Wl_Window *window = NULL;
+       struct wl_display *display = NULL;
+       struct wl_display *display_wrapper = NULL;
+       struct wl_surface *surface = NULL;
+       struct wl_registry *registry = NULL;
+       struct wl_event_queue *queue = NULL;
+       struct tizen_surface *tz_surface = NULL;
+       struct tizen_resource *tz_resource = NULL;
+
+       if (!obj || !wl_info) {
+               LOGE("NULL parameter %p %p", obj, wl_info);
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       window = elm_win_wl_window_get(obj);
+       if (!window) {
+               LOGE("failed to get wayland window");
+               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+               goto _DONE;
+       }
+
+       surface = (struct wl_surface *)ecore_wl_window_surface_get(window);
+       if (!surface) {
+               LOGE("failed to get wayland surface");
+               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+               goto _DONE;
+       }
+
+       display = (struct wl_display *)ecore_wl_display_get();
+       if (!display) {
+               LOGE("failed to get wayland display");
+               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+               goto _DONE;
+       }
+
+       display_wrapper = wl_proxy_create_wrapper(display);
+       if (!display_wrapper) {
+               LOGE("failed to create wl display wrapper");
+               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+               goto _DONE;
+       }
+
+       queue = wl_display_create_queue(display);
+       if (!queue) {
+               LOGE("failed to create wl display queue");
+               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+               goto _DONE;
+       }
+
+       wl_proxy_set_queue((struct wl_proxy *)display_wrapper, queue);
+
+       registry = wl_display_get_registry(display_wrapper);
+       if (!registry) {
+               LOGE("failed to get wayland registry");
+               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+               goto _DONE;
+       }
+
+       wl_registry_add_listener(registry, &_media_streamer_wl_registry_listener, &tz_surface);
+
+       wl_display_dispatch_queue(display, queue);
+       wl_display_roundtrip_queue(display, queue);
+
+       if (!tz_surface) {
+               LOGE("failed to get tizen surface");
+               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+               goto _DONE;
+       }
+
+       /* Get parent_id which is unique in a entire systemw. */
+       tz_resource = tizen_surface_get_tizen_resource(tz_surface, surface);
+       if (!tz_resource) {
+               LOGE("failed to get tizen resurce");
+               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+               goto _DONE;
+       }
+
+       wl_info->parent_id = 0;
+
+       tizen_resource_add_listener(tz_resource, &_media_streamer_tz_resource_listener, &wl_info->parent_id);
+
+       wl_display_roundtrip_queue(display, queue);
+
+       if (wl_info->parent_id > 0) {
+               int rotation = 0;
+               Ecore_Evas *ecore_evas = NULL;
+               ret = MEDIA_STREAMER_ERROR_NONE;
+
+               wl_info->evas_obj = obj;
+
+               evas_object_geometry_get(obj, &wl_info->window_x, &wl_info->window_y,
+                       &wl_info->window_width, &wl_info->window_height);
+
+               ecore_evas = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
+               if (ecore_evas) {
+                       rotation = ecore_evas_rotation_get(ecore_evas);
+                       if (rotation == 90 || rotation == 270) {
+                               int temp = wl_info->window_width;
+
+                               LOGD("swap width and height %d, %d", wl_info->window_width, wl_info->window_height);
+
+                               wl_info->window_width = wl_info->window_height;
+                               wl_info->window_height = temp;
+                       }
+               } else {
+                       LOGW("failed to get ecore_evas.. skip rotation check");
+               }
+
+               LOGD("evas object : %p, rotation : %d, parent id : %u, window : %d,%d,%dx%d",
+                       wl_info->evas_obj, rotation, wl_info->parent_id,
+                       wl_info->window_x, wl_info->window_y,
+                       wl_info->window_width, wl_info->window_height);
+       } else {
+               ret = MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+               LOGE("failed to get parent id");
+       }
+
+_DONE:
+       if (tz_surface) {
+               tizen_surface_destroy(tz_surface);
+               tz_surface = NULL;
+       }
+
+       if (tz_resource) {
+               tizen_resource_destroy(tz_resource);
+               tz_resource = NULL;
+       }
+
+       if (registry) {
+               wl_registry_destroy(registry);
+               registry = NULL;
+       }
+
+       if (queue) {
+               wl_event_queue_destroy(queue);
+               queue = NULL;
+       }
+
+       if (display_wrapper) {
+               wl_proxy_wrapper_destroy(display_wrapper);
+               display_wrapper = NULL;
+       }
+
+       return ret;
+}
+
+/**
+ * @brief Set display for video sink.
+ *
+ * @sinse_tizen 3.0
+ */
+int __ms_node_set_display(media_streamer_node_s *ms_node, const char *param_value)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+       Evas_Object *obj = NULL;
+       media_streamer_wl_info_s wl_info;
+
+       obj = (Evas_Object *)param_value;
+
+       /* get wayland parent id */
+       if (_media_streamer_get_wl_info(obj, &wl_info) != MEDIA_STREAMER_ERROR_NONE) {
+               LOGE("failed to get wayland info");
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       LOGD("wayland global surface id : %d", wl_info.parent_id);
+
+       gst_video_overlay_set_wl_window_wl_surface_id(GST_VIDEO_OVERLAY(ms_node->gst_element), (guintptr)wl_info.parent_id);
+       gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(ms_node->gst_element),
+               wl_info.window_x, wl_info.window_y, wl_info.window_width, wl_info.window_height);
+
+       return ret;
+}
+
 int __ms_node_set_param_value(media_streamer_node_s *ms_node, param_s *param, const char *param_value)
 {
        ms_retvm_if(!ms_node || !param || !param_value,  MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "Handle is NULL");
@@ -1163,6 +1404,8 @@ int __ms_node_set_param_value(media_streamer_node_s *ms_node, param_s *param, co
                g_object_set(ms_node->gst_element, param->origin_name, (int)strtol(param_value, NULL, 10), NULL);
        else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_DISPLAY_GEOMETRY_METHOD))
                g_object_set(ms_node->gst_element, param->origin_name, (int)strtol(param_value, NULL, 10), NULL);
+       else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_DISPLAY))
+               ret = __ms_node_set_display(ms_node, param_value);
        else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_VISIBLE))
                g_object_set(ms_node->gst_element, param->origin_name, !g_ascii_strcasecmp(param_value, "true"), NULL);
        else if (!g_strcmp0(param->param_name, MEDIA_STREAMER_PARAM_HOST))
index 9cf83852c5935569419a0cbc1c2dbc7e434c84a9..e6a8af0c790fd83a9892ed92e6829a16cb5aaa6b 100755 (executable)
@@ -6,7 +6,7 @@ INCLUDE_DIRECTORIES(../include)
 link_directories(${CMAKE_SOURCE_DIR}/../)
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(${fw_test} REQUIRED glib-2.0)
+pkg_check_modules(${fw_test} REQUIRED glib-2.0 elementary evas ecore appcore-efl)
 FOREACH(flag ${${fw_test}_CFLAGS})
     SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
index 0f1b6d55dfccc72cd738df33cce082b97227b299..309a1340c6c7c56fb6f6f73d58845a94c6bea3c2 100644 (file)
 
 #include <glib.h>
 #include <glib/gprintf.h>
+#include <Ecore.h>
+#include <Elementary.h>
+#include <appcore-efl.h>
 
 #include <media_streamer.h>
 
+#ifdef PACKAGE
+#undef PACKAGE
+#endif
+#define PACKAGE "media_streamer_test"
+
 typedef enum {
        MENU_STATE_UNKNOWN = 0,
        MENU_STATE_MAIN_MENU,
@@ -113,8 +121,6 @@ media_streamer_node_h g_nodes[MAX_NODES_COUNT] = { 0, };
 int g_node_counter = 0;
 #define APPEND_NODE(x) {g_nodes[g_node_counter++] = x; }
 
-GMainLoop *g_loop;
-
 gchar *g_broadcast_address = NULL;
 int g_seek_pos = 0;
 int g_time = 0;
@@ -140,6 +146,24 @@ media_format_h afmt_aenc = NULL;
 media_format_h tsfmt = NULL;
 media_format_h qtfmt = NULL;
 
+static int app_create(void *data);
+static int app_terminate(void *data);
+
+struct _appdata {
+       Evas_Object *win;
+       Evas_Object *eo;
+       Evas_Object *bg;
+       Evas_Object *rect;
+};
+typedef struct _appdata appdata;
+
+struct appcore_ops ops = {
+       .create = app_create,
+       .terminate = app_terminate,
+};
+
+appdata ad;
+
 static void streamer_error_cb(media_streamer_h streamer, media_streamer_error_e error, void *user_data)
 {
        g_print("Media Streamer posted error [%d] \n", error);
@@ -417,6 +441,7 @@ static void _create_file_playing()
        media_streamer_node_h video_sink = NULL;
        media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY, &video_sink);
        media_streamer_node_add(current_media_streamer, video_sink);
+       media_streamer_node_set_param(video_sink, MEDIA_STREAMER_PARAM_DISPLAY, (void*)ad.win);
        APPEND_NODE(video_sink);
 
        /*********************** audiosink *********************************** */
@@ -444,6 +469,7 @@ static void _create_file_sub_playing()
        media_streamer_node_h video_sink = NULL;
        media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY, &video_sink);
        media_streamer_node_add(current_media_streamer, video_sink);
+       media_streamer_node_set_param(video_sink, MEDIA_STREAMER_PARAM_DISPLAY, (void*)ad.win);
        APPEND_NODE(video_sink);
 
        /*********************** audiosink *********************************** */
@@ -475,6 +501,7 @@ static void _create_http_playing()
        media_streamer_node_h video_sink = NULL;
        media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY, &video_sink);
        media_streamer_node_add(current_media_streamer, video_sink);
+       media_streamer_node_set_param(video_sink, MEDIA_STREAMER_PARAM_DISPLAY, (void*)ad.win);
        APPEND_NODE(video_sink);
 
        /*********************** audiosink *********************************** */
@@ -612,6 +639,7 @@ static void _create_rtp_client(media_streamer_node_h rtp_bin)
                media_streamer_node_h video_sink = NULL;
                media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY, &video_sink);
                media_streamer_node_add(current_media_streamer, video_sink);
+               media_streamer_node_set_param(video_sink, MEDIA_STREAMER_PARAM_DISPLAY, (void*)ad.win);
                APPEND_NODE(video_sink);
 
                /* ====================Linking Video Client=========================== */
@@ -660,6 +688,7 @@ static void _create_rtp_client_autoplug(media_streamer_node_h rtp_bin)
                media_streamer_node_h video_sink = NULL;
                media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY, &video_sink);
                media_streamer_node_add(current_media_streamer, video_sink);
+               media_streamer_node_set_param(video_sink, MEDIA_STREAMER_PARAM_DISPLAY, (void*)ad.win);
                APPEND_NODE(video_sink);
 
                g_print("== success client_autoplug video part \n");
@@ -775,6 +804,7 @@ static void _create_adaptive_playing()
        media_streamer_node_h video_sink = NULL;
        media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY, &video_sink);
        media_streamer_node_add(current_media_streamer, video_sink);
+       media_streamer_node_set_param(video_sink, MEDIA_STREAMER_PARAM_DISPLAY, (void*)ad.win);
        APPEND_NODE(video_sink);
 
        /*********************** audiosink *********************************** */
@@ -812,6 +842,7 @@ static void _create_adaptive_playing_manual()
        media_streamer_node_h video_sink = NULL;
        media_streamer_node_create_sink(MEDIA_STREAMER_NODE_SINK_TYPE_OVERLAY, &video_sink);
        media_streamer_node_add(current_media_streamer, video_sink);
+       media_streamer_node_set_param(video_sink, MEDIA_STREAMER_PARAM_DISPLAY, (void*)ad.win);
        APPEND_NODE(video_sink);
 
        /*********************** audiosink *********************************** */
@@ -950,7 +981,7 @@ void reset_current_menu_state(void)
 void quit()
 {
        reset_current_menu_state();
-       g_main_loop_quit(g_loop);
+       elm_exit();
 }
 
 static void display_getting_ip_menu(void)
@@ -1696,19 +1727,107 @@ gboolean input(GIOChannel *channel)
        return TRUE;
 }
 
+static int app_create(void *data)
+{
+       appdata *app_data = data;
+       int w = 0;
+       int h = 0;
+       Evas_Object *win = NULL;
+       Evas_Object *eo = NULL;
+       Evas_Object *bg = NULL;
+       Evas_Object *rect = NULL;
+
+       if (app_data == NULL) {
+               g_print("\t\nappdata is NULL\n");
+               return 0;
+       }
+
+       /* use gl backend */
+       elm_config_accel_preference_set("opengl");
+
+       win = elm_win_add(NULL, PACKAGE, ELM_WIN_BASIC);
+       if (win) {
+               elm_win_title_set(win, PACKAGE);
+               elm_win_borderless_set(win, EINA_TRUE);
+               elm_win_screen_size_get(win, NULL, NULL, &w, &h);
+               g_print("\n\tscreen size %dx%d\n\n", w, h);
+               evas_object_resize(win, w, h);
+               elm_win_autodel_set(win, EINA_TRUE);
+               elm_win_alpha_set(win, EINA_TRUE);
+       } else {
+               g_print("\n\tfailed to get window\n\n");
+               return 1;
+       }
+
+       bg = elm_bg_add(win);
+       if (bg) {
+               elm_win_resize_object_add(win, bg);
+               evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+               evas_object_show(bg);
+       } else {
+               g_print("\n\tfailed to get elm bg\n\n");
+               return 1;
+       }
+
+       rect = evas_object_rectangle_add(evas_object_evas_get(win));
+       if (rect) {
+               evas_object_color_set(rect, 0, 0, 0, 0);
+               evas_object_render_op_set(rect, EVAS_RENDER_COPY);
+       } else {
+               g_print("\n\tfailed to get rectangle\n\n");
+               return 1;
+       }
+
+       elm_win_resize_object_add(win, rect);
+       evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+       evas_object_show(rect);
+
+       /* Create evas image object for EVAS surface */
+       eo = evas_object_image_add(evas_object_evas_get(win));
+       evas_object_image_size_set(eo, w, h);
+       evas_object_image_fill_set(eo, 0, 0, w, h);
+       evas_object_resize(eo, w, h);
+       evas_object_show(eo);
+
+       elm_win_activate(win);
+       evas_object_show(win);
+
+       app_data->win = win;
+       app_data->eo = eo;
+
+       display_menu();
+
+       return 0;
+}
+
+static int app_terminate(void *data)
+{
+       appdata *app_data = data;
+
+       if (app_data == NULL) {
+               g_print("\n\tappdata is NULL\n");
+               return 0;
+       }
+
+       return 0;
+}
+
 int main(int argc, char **argv)
 {
+       int bret;
+
        GIOChannel *stdin_channel;
        stdin_channel = g_io_channel_unix_new(0);
        g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
        g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc) input, NULL);
 
-       display_menu();
+       memset(&ad, 0x0, sizeof(appdata));
+       ops.data = &ad;
+
+       bret = appcore_efl_main(PACKAGE, &argc, &argv, &ops);
 
-       g_loop = g_main_loop_new(NULL, FALSE);
-       g_main_loop_run(g_loop);
+       g_print("\n\treturn appcore_efl : %d\n\n", bret);
 
-       g_main_loop_unref(g_loop);
        g_io_channel_unref(stdin_channel);
        return 0;
 }