From: Sangchul Lee Date: Thu, 21 Jul 2022 06:29:54 +0000 (+0900) Subject: Add capi-media-webrtc-test-headless package X-Git-Tag: submit/tizen/20220725.023109^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2aeb5325ce19c8fe2fec3315bd21e91624c794df;p=platform%2Fcore%2Fapi%2Fwebrtc.git Add capi-media-webrtc-test-headless package New test binary named 'webrtc_test_headless' is exported by this package without UI and esplusplayer libraries dependencies. [Version] 0.3.162 [Issue Type] Packaging Change-Id: Ifa0dfc951d6e608c62016a923ede1bec2edd82e4 Signed-off-by: Sangchul Lee --- diff --git a/packaging/capi-media-webrtc-test-headless.manifest b/packaging/capi-media-webrtc-test-headless.manifest new file mode 100644 index 00000000..155e3bfd --- /dev/null +++ b/packaging/capi-media-webrtc-test-headless.manifest @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 32ebc383..f3bd2f51 100644 --- a/packaging/capi-media-webrtc.spec +++ b/packaging/capi-media-webrtc.spec @@ -1,6 +1,6 @@ Name: capi-media-webrtc Summary: A WebRTC library in Tizen Native API -Version: 0.3.161 +Version: 0.3.162 Release: 0 Group: Multimedia/API License: Apache-2.0 @@ -8,6 +8,7 @@ URL: http://source.tizen.org Source0: %{name}-%{version}.tar.gz Source1001: %{name}.manifest Source1002: %{name}-test.manifest +Source1003: %{name}-test-headless.manifest BuildRequires: cmake BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(glib-2.0) @@ -57,6 +58,14 @@ Requires: %{name} = %{version}-%{release} %description test Testsuite of Tizen Native WebRTC API. +%package test-headless +Summary: Testsuite of Tizen Native WebRTC API (For headless target) +Group: Multimedia/Development +Requires: %{name} = %{version}-%{release} + +%description test-headless +Testsuite of Tizen Native WebRTC API for headless target. + %if 0%{?gcov:1} %package gcov Summary: Line Coverage files @@ -70,6 +79,7 @@ Collection of files related to line coverage using gcov. %setup -q cp %{SOURCE1001} . cp %{SOURCE1002} . +cp %{SOURCE1003} . %build export CFLAGS+=" -DSYSCONFDIR=\\\"%{_hal_sysconfdir}\\\"" @@ -134,6 +144,11 @@ find . -name '*.gcno' -exec cp --parents '{}' "$gcno_obj_dir" ';' %{_bindir}/webrtc_test %license LICENSE.APLv2 +%files test-headless +%manifest %{name}-test-headless.manifest +%{_bindir}/webrtc_test_headless +%license LICENSE.APLv2 + %if 0%{?gcov:1} %files gcov %{_datadir}/gcov/obj/* diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0474a349..bcbe7458 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -12,6 +12,7 @@ IF(TIZEN_FEATURE_ESPP) ELSE() pkg_check_modules(${fw_test} REQUIRED glib-2.0 appcore-efl elementary libsoup-2.4) ENDIF() + FOREACH(flag ${${fw_test}_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) @@ -29,6 +30,7 @@ IF(TIZEN_FEATURE_ESPP) ELSE() LIST(REMOVE_ITEM src_list "webrtc_test_espp") ENDIF() +LIST(REMOVE_ITEM src_list "webrtc_test_non_ui") MESSAGE("Target sources in ./test/") FOREACH(src ${src_list}) @@ -38,3 +40,33 @@ ENDFOREACH() ADD_EXECUTABLE(${test_name} ${src_list}) TARGET_LINK_LIBRARIES(${test_name} capi-media-webrtc ${${fw_test}_LDFLAGS}) INSTALL(TARGETS ${test_name} DESTINATION bin) + +#For headless test binary + +SET(fw_test_headless "${fw_name}-test-headless") +SET(test_name_headless "webrtc_test_headless") + +INCLUDE(FindPkgConfig) +pkg_check_modules(${fw_test_headless} REQUIRED glib-2.0 libsoup-2.4) + +FOREACH(flag ${${fw_test_headless}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +FOREACH(src ${sources}) + GET_FILENAME_COMPONENT(src_name ${src} NAME_WE) + LIST(APPEND src_list_headless "${src_name}") +ENDFOREACH() + +LIST(REMOVE_ITEM src_list_headless "webrtc_test_espp") +LIST(REMOVE_ITEM src_list_headless "webrtc_test_ui") + +MESSAGE("Target sources for headless in ./test/") +FOREACH(src ${src_list_headless}) + MESSAGE(" - ${src}") +ENDFOREACH() + +ADD_EXECUTABLE(${test_name_headless} ${src_list_headless}) +TARGET_LINK_LIBRARIES(${test_name_headless} capi-media-webrtc ${${fw_test_headless}_LDFLAGS}) +INSTALL(TARGETS ${test_name_headless} DESTINATION bin) + diff --git a/test/webrtc_test.c b/test/webrtc_test.c index a9708e73..1b475ead 100644 --- a/test/webrtc_test.c +++ b/test/webrtc_test.c @@ -21,13 +21,9 @@ #include #include #include +#include #include -#ifdef PACKAGE -#undef PACKAGE -#endif -#define PACKAGE "webrtc_test" - #ifdef LOG_TAG #undef LOG_TAG #endif @@ -35,7 +31,6 @@ #define MAX_EXPECTED_SIZE 1024 * 1024 * 1024 #define USE_GSTBUFFER_WITHOUT_COPY true -#define FONT_SIZE 30 const char *g_server_status_str[] = { [SERVER_STATUS_DISCONNECTED] = "DISCONNECTED", @@ -87,165 +82,6 @@ appdata_s *get_appdata(void) return &g_ad; } -static void win_del(void *data, Evas_Object *obj, void *event) -{ - elm_exit(); -} - -static Evas_Object *create_win(const char *name, int *w, int *h) -{ - Evas_Object *eo; - - if (!w || !h) { - g_printerr("w[%p] or h[%p] is NULL\n", w, h); - return NULL; - } - - eo = elm_win_add(NULL, name, ELM_WIN_BASIC); - if (!eo) { - g_printerr("eo is NULL\n"); - return NULL; - } - - elm_win_title_set(eo, name); - elm_win_borderless_set(eo, EINA_TRUE); - evas_object_smart_callback_add(eo, "delete,request", win_del, NULL); - elm_win_screen_size_get(eo, NULL, NULL, w, h); - g_print("eo[%p], window size: %d x %d\n", eo, *w, *h); - evas_object_resize(eo, *w, *h); - elm_win_autodel_set(eo, EINA_TRUE); - elm_win_alpha_set(eo, EINA_TRUE); - - return eo; -} - -static Evas_Object *create_image_object(Evas_Object *eo_parent) -{ - Evas_Object *eo = NULL; - Evas *evas; - - if (!eo_parent) - return NULL; - - evas = evas_object_evas_get(eo_parent); - eo = evas_object_image_add(evas); - - g_print("image eo[%p]\n", eo); - - return eo; -} - -static Evas_Object *create_text_object(Evas_Object *eo_parent) -{ - Evas_Object *eo = NULL; - Evas *evas; - - if (!eo_parent) - return NULL; - - evas = evas_object_evas_get(eo_parent); - eo = evas_object_text_add(evas); - - g_print("text eo[%p]\n", eo); - - return eo; -} - -void create_render_rect_and_bg(Evas_Object *win) -{ - RET_IF(!win, "win is NULL"); - Evas_Object *bg, *rect; - - bg = elm_bg_add(win); - elm_win_resize_object_add(win, bg); - evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_show(bg); - - rect = evas_object_rectangle_add(evas_object_evas_get(win)); - RET_IF(!rect, "rect is NULL"); - - evas_object_color_set(rect, 0, 0, 0, 0); - evas_object_render_op_set(rect, EVAS_RENDER_COPY); - - elm_win_resize_object_add(win, rect); - evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_show(rect); - evas_object_show(win); -} - -static int app_create(void *data) -{ - appdata_s *ad = data; - Evas_Object *win = NULL; - int i; - Evas_Object **eo; - - ad->menu_items = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); - for (i = 0; g_menu_infos[i].cmd != NULL; i++) { - if (g_strcmp0(g_menu_infos[i].cmd, "none") == 0) - continue; - if (!g_hash_table_insert(ad->menu_items, (gpointer)g_menu_infos[i].cmd, &g_menu_infos[i])) { - g_printerr("should not be reached here, cmd[%s] already exist", g_menu_infos[i].cmd); - continue; - } - } - - /* use gl backend */ - elm_config_accel_preference_set("opengl"); - - /* create window */ - win = create_win(PACKAGE, &ad->win_width, &ad->win_height); - if (win == NULL) - return -1; - ad->win = win; - ad->win_id = win; - create_render_rect_and_bg(ad->win); - - /* Create evas image object for EVAS surface. - * _________________________________________ * - * | eo (mine) | eo (remote0) | * - * |____________________|____________________| * - * | eo (remote1) | eo (remote2) | * - * |____________________|____________________| */ - for (i = 0; i < MAX_CONNECTION_LEN + 1; i++) { - eo = (i == 0) ? &g_ad.eo_mine : &g_ad.conns[i - 1].render.eo; - *eo = create_image_object(ad->win); - if (!*eo) { - g_print("failed to create evas image object\n"); - continue; - } - evas_object_image_size_set(*eo, ad->win_width / 2, ad->win_height / 2); - evas_object_image_fill_set(*eo, 0, 0, ad->win_width / 2, ad->win_height / 2); - evas_object_resize(*eo, ad->win_width / 2, ad->win_height / 2); - evas_object_move(*eo, (i % 2) * (ad->win_width / 2), (i / 2) * (ad->win_height / 2)); - } - elm_win_activate(win); - evas_object_show(win); - - return 0; -} - -static void __render_text_message(Evas_Object **eo, int i, const char *text) -{ - if (*eo) { - evas_object_hide(*eo); - evas_object_del(*eo); - } - - *eo = create_text_object(g_ad.win); - if (!*eo) { - g_print("failed to create evas text object\n"); - return; - } - evas_object_text_style_set(*eo, EVAS_TEXT_STYLE_PLAIN); - evas_object_text_font_set(*eo, "Courier", FONT_SIZE); - evas_object_text_text_set(*eo, text); - evas_object_color_set(*eo, 255, 255, 255, 255); - evas_object_resize(*eo, g_ad.win_width / 2, FONT_SIZE * 2); - evas_object_move(*eo, (i % 2) * (g_ad.win_width / 2), ((i / 2) * (g_ad.win_height / 2)) + ((g_ad.win_height / 2) - (FONT_SIZE * 2))); - evas_object_show(*eo); -} - typedef struct _idle_userdata { connection_s *conn; char *message; @@ -260,7 +96,8 @@ static gboolean __idle_cb(gpointer user_data) return G_SOURCE_REMOVE; conn = data->conn; - __render_text_message(&conn->render.text_eo, conn->index + 1, data->message); + + _render_text_message(&conn->render.text_eo, conn->index + 1, data->message); free (data->message); return G_SOURCE_REMOVE; @@ -275,45 +112,6 @@ static void __render_text_message_in_idle(connection_s *conn, const char *text) g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __idle_cb, data, g_free); } -static int app_terminate(void *data) -{ - appdata_s *ad = data; - int i; - - for (i = 0; i < MAX_CONNECTION_LEN; i++) { - if (g_ad.conns[i].render.eo) { - evas_object_del(g_ad.conns[i].render.eo); - g_ad.conns[i].render.eo = NULL; - } - if (g_ad.conns[i].render.text_eo) { - evas_object_del(g_ad.conns[i].render.text_eo); - g_ad.conns[i].render.text_eo = NULL; - } - } - - if (g_ad.eo_mine) { - evas_object_del(g_ad.eo_mine); - g_ad.eo_mine = NULL; - } - - if (ad->win_id) { - evas_object_del(ad->win_id); - ad->win_id = NULL; - } - - ad->win = NULL; - - g_hash_table_destroy(ad->menu_items); - ad->menu_items = NULL; - - return 0; -} - -struct appcore_ops ops = { - .create = app_create, - .terminate = app_terminate, -}; - static void __disconnect_signal(GObject *obj, gulong signal_id) { RET_IF(!obj, "obj is NULL"); @@ -1079,8 +877,6 @@ static void _webrtc_media_source_unset_video_loopback(int index, unsigned int so ret = webrtc_media_source_unset_video_loopback(g_ad.conns[index].webrtc, source_id); RET_IF(ret != WEBRTC_ERROR_NONE, "ret[0x%x]", ret); - evas_object_hide(g_ad.eo_mine); - g_print("webrtc_media_source_unset_video_loopback() success, source_id[%u]\n", source_id); } @@ -1132,7 +928,7 @@ static void _webrtc_data_channel_send_string(const char *string, bool send_as_by } } if (g_ad.conns[i].render.loopback_track_id > 0) - __render_text_message(&g_ad.text_eo_mine, 0, string_with_peer_id); + _render_text_message(&g_ad.text_eo_mine, 0, string_with_peer_id); } g_free(string_with_peer_id); @@ -1144,8 +940,9 @@ static void _webrtc_data_channel_send_file(int index, const char *file_path) int ret = WEBRTC_ERROR_NONE; int i; struct stat st; - gchar *expected_name; - gchar *expected_size; + g_autofree gchar *expected_name = NULL; + g_autofree gchar *base_name = NULL; + g_autofree gchar *expected_size = NULL; ssize_t read_size; unsigned long long sum_size; char buffer[BUFFER_SIZE] = {0, }; @@ -1170,8 +967,9 @@ static void _webrtc_data_channel_send_file(int index, const char *file_path) /* NOTE that logic regarding sending file size and name before sending data may differ from application implementations. * Here we use two magic string - 'expected name:' and 'expected size:' */ + base_name = g_path_get_basename((const gchar *)file_path); expected_size = g_strdup_printf("expected size:%llu", (unsigned long long)st.st_size); - expected_name = g_strdup_printf("expected name:%s", basename((char *)file_path)); + expected_name = g_strdup_printf("expected name:%s", base_name); ret = webrtc_data_channel_send_string(g_ad.conns[index].channels[i], expected_size); if (ret != WEBRTC_ERROR_NONE) @@ -1185,9 +983,6 @@ static void _webrtc_data_channel_send_file(int index, const char *file_path) else g_print("webrtc_data_channel_send_string() success, string[%s]\n", expected_name); - g_free(expected_size); - g_free(expected_name); - sum_size = 0; while ((read_size = read(fd, buffer, BUFFER_SIZE)) > 0) { sum_size += read_size; @@ -2153,12 +1948,12 @@ static void __track_added_cb(webrtc_h webrtc, webrtc_media_type_e type, unsigned if (type == WEBRTC_MEDIA_TYPE_VIDEO) { if (!g_ad.validate_encoded_frame_cb) { g_print("Video track is added, set display - display_type[%d], display[%p]\n", - conn->render.display_type, conn->render.display_type == WEBRTC_DISPLAY_TYPE_OVERLAY ? g_ad.win_id : conn->render.eo); + conn->render.display_type, conn->render.display_type == WEBRTC_DISPLAY_TYPE_OVERLAY ? g_ad.win : conn->render.eo); #ifdef TIZEN_FEATURE_ESPP if (conn->render.espp.handle) { conn->render.espp.video_track_preparing = true; if (conn->render.display_type == WEBRTC_DISPLAY_TYPE_OVERLAY) - esplusplayer_set_display(conn->render.espp.handle, ESPLUSPLAYER_DISPLAY_TYPE_OVERLAY, g_ad.win_id); + esplusplayer_set_display(conn->render.espp.handle, ESPLUSPLAYER_DISPLAY_TYPE_OVERLAY, g_ad.win); else if (conn->render.display_type == WEBRTC_DISPLAY_TYPE_EVAS) esplusplayer_set_display(conn->render.espp.handle, ESPLUSPLAYER_DISPLAY_TYPE_EVAS, conn->render.eo); else @@ -2167,7 +1962,7 @@ static void __track_added_cb(webrtc_h webrtc, webrtc_media_type_e type, unsigned #endif { if (conn->render.display_type == WEBRTC_DISPLAY_TYPE_OVERLAY) - webrtc_set_display(webrtc, id, WEBRTC_DISPLAY_TYPE_OVERLAY, g_ad.win_id); + webrtc_set_display(webrtc, id, WEBRTC_DISPLAY_TYPE_OVERLAY, g_ad.win); else if (conn->render.display_type == WEBRTC_DISPLAY_TYPE_EVAS) webrtc_set_display(webrtc, id, WEBRTC_DISPLAY_TYPE_EVAS, conn->render.eo); else @@ -3774,7 +3569,7 @@ void quit_program(void) g_print("quit program\n"); g_ad.menu_status = CURRENT_STATUS_TERMINATE; - elm_exit(); + _app_stop(); } static bool interpret_main_menu_cmd(char *cmd) @@ -4660,6 +4455,27 @@ out: g_timeout_add(100, timeout_menu_display_cb, 0); } +static void get_menu_items(void) +{ + int i; + + g_ad.menu_items = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); + for (i = 0; g_menu_infos[i].cmd != NULL; i++) { + if (g_strcmp0(g_menu_infos[i].cmd, "none") == 0) + continue; + if (!g_hash_table_insert(get_appdata()->menu_items, (gpointer)g_menu_infos[i].cmd, &g_menu_infos[i])) { + g_printerr("should not be reached here, cmd[%s] already exist", g_menu_infos[i].cmd); + continue; + } + } +} + +static void free_menu_items(void) +{ + g_hash_table_destroy(g_ad.menu_items); + g_ad.menu_items = NULL; +} + static gboolean input_watch_cb(GIOChannel *channel, GIOCondition condition, gpointer data) { GIOStatus status; @@ -4681,8 +4497,8 @@ static gboolean input_watch_cb(GIOChannel *channel, GIOCondition condition, gpoi static void print_usage() { - printf("Usage : "); - printf("webrtc_test [option]\n\n" + g_print("Usage : "); + g_print("webrtc_test [option]\n\n" " -p, --proxy proxy URL to use (e.g. http://123.123.123.123:8080)\n" " -l, --launch-signaling-server port to be used for private signaling server (e.g. 8080)\n" " -c, --connect-signaling-server signaling server URL:PORT to connect (e.g. wss://123.123.123.123:8443, 192.168.1.123:8080)\n" @@ -4703,10 +4519,10 @@ static int option_launch_signaling_server(int port) static int option_connect_signaling_server(char *url) { g_auto(GStrv) str_arr = g_strsplit((const gchar *)optarg, ":", 2); - printf("%s %s\n", str_arr[0], str_arr[1]); + g_print("%s %s\n", str_arr[0], str_arr[1]); if (g_str_has_prefix(str_arr[0], "wss") || g_str_has_prefix(str_arr[0], "ws")) { if (_setting_uri(g_ad.signaling_server.public.url, optarg) == -1) { - printf("invalid port number\n"); + g_print("invalid port number\n"); return -1; } if (_connect_signaling_server() == -1) @@ -4726,7 +4542,6 @@ int main(int argc, char *argv[]) g_io_add_watch(stdin_channel, G_IO_IN, input_watch_cb, NULL); memset(&g_ad, 0x0, sizeof(appdata_s)); - ops.data = &g_ad; while (1) { int opt; @@ -4751,7 +4566,7 @@ int main(int argc, char *argv[]) break; case 'l': { if (atoi(optarg) == 0) { - printf("invalid port number\n"); + g_print("invalid port number\n"); goto out; } if (option_launch_signaling_server(atoi(optarg)) == -1) @@ -4776,6 +4591,11 @@ out: } displaymenu(); + get_menu_items(); - return appcore_efl_main(PACKAGE, &argc, &argv, &ops); + _app_start(&argc, argv); + + free_menu_items(); + + return 0; } diff --git a/test/webrtc_test_non_ui.c b/test/webrtc_test_non_ui.c new file mode 100644 index 00000000..d1d6a34f --- /dev/null +++ b/test/webrtc_test_non_ui.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "webrtc_test_priv.h" + +static GMainLoop *g_mainloop; + +void _render_text_message(void **eo, int i, const char *text) +{ + g_print("it might be a headless target, skip showing message[%s]\n", text); +} + +void _app_start(int *argc, char **argv) +{ + g_mainloop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(g_mainloop); + g_print("g_main_loop_run() returned\n"); + g_main_loop_unref(g_mainloop); +} + +void _app_stop(void) +{ + g_main_loop_quit(g_mainloop); +} \ No newline at end of file diff --git a/test/webrtc_test_priv.h b/test/webrtc_test_priv.h index add569a8..bf51f607 100644 --- a/test/webrtc_test_priv.h +++ b/test/webrtc_test_priv.h @@ -24,8 +24,6 @@ #ifdef TIZEN_FEATURE_ESPP #include #endif -#include -#include #include #include #include @@ -222,8 +220,8 @@ typedef struct _connection_s { struct { sound_stream_info_h stream_info; webrtc_display_type_e display_type; - Evas_Object *eo; - Evas_Object *text_eo; + void *eo; + void *text_eo; unsigned int loopback_track_id; #ifdef TIZEN_FEATURE_ESPP struct { @@ -280,12 +278,11 @@ typedef struct { int menu_status; int input_count; - Evas_Object *win; int win_width; int win_height; - Evas_Object *win_id; - Evas_Object *eo_mine; - Evas_Object *text_eo_mine; + void *win; + void *eo_mine; + void *text_eo_mine; connection_s conns[MAX_CONNECTION_LEN]; signaling_server_s signaling_server; @@ -325,6 +322,9 @@ void _espp_deinit(int index); void _espp_submit_packet(connection_s *conn, media_packet_h packet, webrtc_media_type_e type); bool _espp_prepare_and_start(connection_s *conn, media_packet_h packet, webrtc_media_type_e type); #endif +void _render_text_message(void **eo, int i, const char *text); +void _app_start(int *argc, char **argv); +void _app_stop(void); #ifdef __cplusplus } diff --git a/test/webrtc_test_ui.c b/test/webrtc_test_ui.c new file mode 100644 index 00000000..b4c64db8 --- /dev/null +++ b/test/webrtc_test_ui.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "webrtc_test_priv.h" +#include +#include + +#ifdef PACKAGE +#undef PACKAGE +#endif +#define PACKAGE "webrtc_test" +#define FONT_SIZE 30 + +static void win_del(void *data, Evas_Object *obj, void *event) +{ + elm_exit(); +} + +static Evas_Object *create_win(const char *name, int *w, int *h) +{ + Evas_Object *eo; + + if (!w || !h) { + g_printerr("w[%p] or h[%p] is NULL\n", w, h); + return NULL; + } + + eo = elm_win_add(NULL, name, ELM_WIN_BASIC); + if (!eo) { + g_printerr("eo is NULL\n"); + return NULL; + } + + elm_win_title_set(eo, name); + elm_win_borderless_set(eo, EINA_TRUE); + evas_object_smart_callback_add(eo, "delete,request", win_del, NULL); + elm_win_screen_size_get(eo, NULL, NULL, w, h); + g_print("eo[%p], window size: %d x %d\n", eo, *w, *h); + evas_object_resize(eo, *w, *h); + elm_win_autodel_set(eo, EINA_TRUE); + elm_win_alpha_set(eo, EINA_TRUE); + + return eo; +} + +static Evas_Object *create_image_object(Evas_Object *eo_parent) +{ + Evas_Object *eo = NULL; + Evas *evas; + + if (!eo_parent) + return NULL; + + evas = evas_object_evas_get(eo_parent); + eo = evas_object_image_add(evas); + + g_print("image eo[%p]\n", eo); + + return eo; +} + +static Evas_Object *create_text_object(Evas_Object *eo_parent) +{ + Evas_Object *eo = NULL; + Evas *evas; + + if (!eo_parent) + return NULL; + + evas = evas_object_evas_get(eo_parent); + eo = evas_object_text_add(evas); + + g_print("text eo[%p]\n", eo); + + return eo; +} + +static void create_render_rect_and_bg(Evas_Object *win) +{ + RET_IF(!win, "win is NULL"); + Evas_Object *bg, *rect; + + bg = elm_bg_add(win); + elm_win_resize_object_add(win, bg); + evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(bg); + + rect = evas_object_rectangle_add(evas_object_evas_get(win)); + RET_IF(!rect, "rect is NULL"); + + evas_object_color_set(rect, 0, 0, 0, 0); + evas_object_render_op_set(rect, EVAS_RENDER_COPY); + + elm_win_resize_object_add(win, rect); + evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(rect); + evas_object_show(win); +} + +static int app_create(void *data) +{ + appdata_s *ad = data; + Evas_Object *win = NULL; + Evas_Object **eo; + int i; + + /* use gl backend */ + elm_config_accel_preference_set("opengl"); + + /* create window */ + win = create_win(PACKAGE, &ad->win_width, &ad->win_height); + if (win == NULL) + return -1; + ad->win = win; + create_render_rect_and_bg(ad->win); + + /* Create evas image object for EVAS surface. + * _________________________________________ * + * | eo (mine) | eo (remote0) | * + * |____________________|____________________| * + * | eo (remote1) | eo (remote2) | * + * |____________________|____________________| */ + for (i = 0; i < MAX_CONNECTION_LEN + 1; i++) { + eo = (i == 0) ? (Evas_Object **)&ad->eo_mine : (Evas_Object **)&ad->conns[i - 1].render.eo; + *eo = create_image_object(ad->win); + if (!*eo) { + g_print("failed to create evas image object\n"); + continue; + } + evas_object_image_size_set(*eo, ad->win_width / 2, ad->win_height / 2); + evas_object_image_fill_set(*eo, 0, 0, ad->win_width / 2, ad->win_height / 2); + evas_object_resize(*eo, ad->win_width / 2, ad->win_height / 2); + evas_object_move(*eo, (i % 2) * (ad->win_width / 2), (i / 2) * (ad->win_height / 2)); + } + elm_win_activate(win); + evas_object_show(win); + + return 0; +} + +static int app_terminate(void *data) +{ + appdata_s *ad = data; + int i; + + for (i = 0; i < MAX_CONNECTION_LEN; i++) { + if (ad->conns[i].render.eo) { + evas_object_del(ad->conns[i].render.eo); + ad->conns[i].render.eo = NULL; + } + if (ad->conns[i].render.text_eo) { + evas_object_del(ad->conns[i].render.text_eo); + ad->conns[i].render.text_eo = NULL; + } + } + + if (ad->eo_mine) { + evas_object_del(ad->eo_mine); + ad->eo_mine = NULL; + } + + if (ad->win) { + evas_object_del(ad->win); + ad->win = NULL; + } + + ad->win = NULL; + + return 0; +} + +struct appcore_ops ops = { + .create = app_create, + .terminate = app_terminate, +}; + +void _render_text_message(void **eo, int i, const char *text) +{ + Evas_Object **_eo = (Evas_Object **)eo; + if (*_eo) { + evas_object_hide(*_eo); + evas_object_del(*_eo); + } + + *_eo = create_text_object(get_appdata()->win); + if (!*_eo) { + g_print("failed to create evas text object\n"); + return; + } + evas_object_text_style_set(*_eo, EVAS_TEXT_STYLE_PLAIN); + evas_object_text_font_set(*_eo, "Courier", FONT_SIZE); + evas_object_text_text_set(*_eo, text); + evas_object_color_set(*_eo, 255, 255, 255, 255); + evas_object_resize(*_eo, get_appdata()->win_width / 2, FONT_SIZE * 2); + evas_object_move(*_eo, (i % 2) * (get_appdata()->win_width / 2), ((i / 2) * (get_appdata()->win_height / 2)) + ((get_appdata()->win_height / 2) - (FONT_SIZE * 2))); + evas_object_show(*_eo); +} + +void _app_start(int *argc, char **argv) +{ + int ret; + + ops.data = get_appdata(); + ret = appcore_efl_main(PACKAGE, argc, &argv, &ops); + g_print("appcore_efl_main() returned %d\n", ret); +} + +void _app_stop(void) +{ + elm_exit(); +} \ No newline at end of file