elementary: introduce EFL_MAIN and rely on Eo_Event to call the initialisation function.

FIXME: Find a way to return an exit value. Maybe on efl_loop_quit ?
This commit is contained in:
Cedric BAIL 2016-06-24 15:32:21 -07:00
parent 61e5c9b8f0
commit 9bc1ad102a
4 changed files with 172 additions and 29 deletions

View File

@ -151,7 +151,10 @@ handle_run(int fd, unsigned long bytes)
} }
} }
#endif #endif
elm_quicklaunch_prepare(argc, argv, cwd); // Try new form before trying old form
if (!efl_quicklaunch_prepare(argc, argv, cwd))
elm_quicklaunch_prepare(argc, argv, cwd);
elm_quicklaunch_fork(argc, argv, cwd, post_fork, NULL); elm_quicklaunch_fork(argc, argv, cwd, post_fork, NULL);
elm_quicklaunch_cleanup(); elm_quicklaunch_cleanup();
} }

View File

@ -998,32 +998,47 @@ colorclass_list_cb(void)
return ret; return ret;
} }
static void
_main_loop_death(void *data EINA_UNUSED,
const Eo_Event *ev EINA_UNUSED)
{
struct elm_test *t;
EINA_LIST_FREE(tests, t)
free(t);
eina_log_domain_unregister(_log_domain);
}
/* this is your elementary main function - it MUST be called IMMEDIATELY /* this is your elementary main function - it MUST be called IMMEDIATELY
* after elm_init() and MUST be passed argc and argv, and MUST be called * after elm_init() and MUST be passed argc and argv, and MUST be called
* elm_main and not be static - must be a visible symbol with EAPI_MAIN infront */ * efl_main and not be static - must be a visible symbol with EAPI_MAIN infront */
EAPI_MAIN int EAPI_MAIN void
elm_main(int argc, char **argv) efl_main(void *data EINA_UNUSED,
const Eo_Event *ev)
{ {
Efl_Loop_Arguments *arge = ev->info;
Eina_Bool test_win_only = EINA_FALSE; Eina_Bool test_win_only = EINA_FALSE;
char *autorun = NULL; char *autorun = NULL;
struct elm_test *t = NULL;
_log_domain = eina_log_domain_register("elementary_test", NULL); _log_domain = eina_log_domain_register("elementary_test", NULL);
eo_event_callback_add(ev->object, EO_EVENT_DEL, _main_loop_death, NULL);
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED); elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
/* tell elm about our app so it can figure out where to get files */ /* tell elm about our app so it can figure out where to get files */
elm_app_compile_bin_dir_set(PACKAGE_BIN_DIR); elm_app_compile_bin_dir_set(PACKAGE_BIN_DIR);
elm_app_compile_lib_dir_set(PACKAGE_LIB_DIR); elm_app_compile_lib_dir_set(PACKAGE_LIB_DIR);
elm_app_compile_data_dir_set(PACKAGE_DATA_DIR); elm_app_compile_data_dir_set(PACKAGE_DATA_DIR);
elm_app_info_set(elm_main, "elementary", "images/logo.png"); elm_app_info_set(efl_main, "elementary", "images/logo.png");
/* if called with a single argument try to autorun a test with /* if called with a single argument try to autorun a test with
* the same name as the given param * the same name as the given param
* ex: elementary_test "Box Vert 2" */ * ex: elementary_test "Box Vert 2" */
if (argc == 2) if (eina_array_count(arge->argv) == 2)
{ {
if (!strcmp(argv[1], "--help")) if (!strcmp(eina_array_data_get(arge->argv, 1), "--help"))
{ {
printf("Usages:\n" printf("Usages:\n"
"$ elementary_test\n" "$ elementary_test\n"
@ -1031,19 +1046,19 @@ elm_main(int argc, char **argv)
"$ elementary_test -to [TEST_NAME]\n\n" "$ elementary_test -to [TEST_NAME]\n\n"
"Examples:\n" "Examples:\n"
"$ elementary_test -to Button\n\n"); "$ elementary_test -to Button\n\n");
goto end; return;
} }
autorun = argv[1]; autorun = eina_array_data_get(arge->argv, 1);
} }
else if (argc == 3) else if (eina_array_count(arge->argv) == 3)
{ {
/* Just a workaround to make the shot module more /* Just a workaround to make the shot module more
* useful with elementary test. */ * useful with elementary test. */
if ((!strcmp(argv[1], "--test-win-only")) || if ((!strcmp(eina_array_data_get(arge->argv, 1), "--test-win-only")) ||
(!strcmp(argv[1], "-to"))) (!strcmp(eina_array_data_get(arge->argv, 1), "-to")))
{ {
test_win_only = EINA_TRUE; test_win_only = EINA_TRUE;
autorun = argv[2]; autorun = eina_array_data_get(arge->argv, 2);
} }
} }
@ -1051,18 +1066,9 @@ elm_main(int argc, char **argv)
elm_color_class_list_cb_set(colorclass_list_cb); elm_color_class_list_cb_set(colorclass_list_cb);
/* put here any init specific to this app like parsing args etc. */ /* put here any init specific to this app like parsing args etc. */
my_win_main(autorun, test_win_only); /* create main window */ my_win_main(autorun, test_win_only); /* create main window */
elm_run(); /* and run the program now and handle all events etc. */
/* if the mainloop that elm_run() runs exist - we exit the app */
EINA_LIST_FREE(tests, t) /* FIXME: Hum, no exit code anywhere anymore ? */
free(t);
end:
eina_log_domain_unregister(_log_domain);
/* exit code */
return 0;
} }
/* all elementary apps should use this. but it should be placed right after /* all elementary apps should use this. but it should be placed right after
* elm_main() */ * efl_main() */
ELM_MAIN() EFL_MAIN()

View File

@ -71,12 +71,14 @@ extern EAPI double _elm_startup_time;
#ifndef ELM_LIB_QUICKLAUNCH #ifndef ELM_LIB_QUICKLAUNCH
#define ELM_MAIN() int main(int argc, char **argv) { int ret; _elm_startup_time = ecore_time_unix_get(); elm_init(argc, argv); ret = elm_main(argc, argv); elm_shutdown(); return ret; } /**< macro to be used after the elm_main() function */ #define ELM_MAIN() int main(int argc, char **argv) { int ret; _elm_startup_time = ecore_time_unix_get(); elm_init(argc, argv); ret = elm_main(argc, argv); elm_shutdown(); return ret; } /**< macro to be used after the elm_main() function */
#define EFL_MAIN() int main(int argc, char **argv) { int ret = 0; _elm_startup_time = ecore_time_unix_get(); elm_init(argc, argv); eo_event_callback_add(ecore_main_loop_get(), EFL_LOOP_EVENT_ARGUMENTS, efl_main, NULL); elm_run(); elm_shutdown(); return ret; }
#else #else
/** @deprecated macro to be used after the elm_main() function. /** @deprecated macro to be used after the elm_main() function.
* Do not define ELM_LIB_QUICKLAUNCH * Do not define ELM_LIB_QUICKLAUNCH
* Compile your programs with -fpie and -pie -rdynamic instead, to generate a single binary (linkable executable). * Compile your programs with -fpie and -pie -rdynamic instead, to generate a single binary (linkable executable).
*/ */
#define ELM_MAIN() int main(int argc, char **argv) { int ret; _elm_startup_time = ecore_time_unix_get(); ret = elm_quicklaunch_fallback(argc, argv); elm_shutdown(); return ret; } #define ELM_MAIN() int main(int argc, char **argv) { int ret; _elm_startup_time = ecore_time_unix_get(); ret = elm_quicklaunch_fallback(argc, argv); elm_shutdown(); return ret; }
#define EFL_MAIN() int main(int argc, char **argv) { int ret = 0; _elm_startup_time = ecore_time_unix_get(); efl_quicklaunch_fallback(argc, argv); elm_shutdown(); return ret; }
#endif #endif
/**************************************************************************/ /**************************************************************************/
@ -209,6 +211,11 @@ EAPI void elm_quicklaunch_seed(void);
*/ */
EAPI Eina_Bool elm_quicklaunch_prepare(int argc, char **argv, const char *cwd); EAPI Eina_Bool elm_quicklaunch_prepare(int argc, char **argv, const char *cwd);
/**
* Exposed symbol used only by macros and should not be used by apps
*/
EAPI Eina_Bool efl_quicklaunch_prepare(int argc, char **argv, const char *cwd);
/** /**
* Exposed symbol used only by macros and should not be used by apps * Exposed symbol used only by macros and should not be used by apps
*/ */
@ -224,6 +231,12 @@ EAPI void elm_quicklaunch_cleanup(void);
*/ */
EAPI int elm_quicklaunch_fallback(int argc, char **argv); EAPI int elm_quicklaunch_fallback(int argc, char **argv);
/**
* Exposed symbol used only by macros and should not be used by apps
*/
EAPI Eina_Bool efl_quicklaunch_fallback(int argc, char **argv);
/** /**
* Exposed symbol used only by macros and should not be used by apps * Exposed symbol used only by macros and should not be used by apps
*/ */

View File

@ -842,6 +842,8 @@ static void *qr_handle = NULL;
#endif #endif
static int (*qr_main)(int argc, static int (*qr_main)(int argc,
char **argv) = NULL; char **argv) = NULL;
static void (*qre_main)(void *data,
const Eo_Event *ev) = NULL;
EAPI Eina_Bool EAPI Eina_Bool
elm_quicklaunch_prepare(int argc, elm_quicklaunch_prepare(int argc,
@ -932,6 +934,94 @@ elm_quicklaunch_prepare(int argc,
#endif #endif
} }
EAPI Eina_Bool
efl_quicklaunch_prepare(int argc,
char **argv,
const char *cwd)
{
#ifdef HAVE_FORK
char *exe, *exe2, *p;
char *exename;
if (argc <= 0 || argv == NULL) return EINA_FALSE;
exe = elm_quicklaunch_exe_path_get(argv[0], cwd);
if (!exe)
{
ERR("requested quicklaunch binary '%s' does not exist\n", argv[0]);
return EINA_FALSE;
}
exe2 = malloc(strlen(exe) + 1 + 7 + strlen(LIBEXT));
strcpy(exe2, exe);
p = strrchr(exe2, '/');
if (p) p++;
else p = exe2;
exename = alloca(strlen(p) + 1);
strcpy(exename, p);
*p = 0;
strcat(p, "../lib/");
strcat(p, exename);
strcat(p, LIBEXT);
if (access(exe2, R_OK | X_OK) != 0)
ELM_SAFE_FREE(exe2, free);
/* Try linking to executable first. Works with PIE files. */
qr_handle = dlopen(exe, RTLD_NOW | RTLD_GLOBAL);
if (qr_handle)
{
INF("dlopen('%s') = %p", exe, qr_handle);
qre_main = dlsym(qr_handle, "efl_main");
if (qre_main)
{
INF("dlsym(%p, 'elm_main') = %p", qr_handle, qre_main);
free(exe2);
free(exe);
return EINA_TRUE;
}
dlclose(qr_handle);
qr_handle = NULL;
}
if (!exe2)
{
WRN("not quicklauncher capable: '%s'", exe);
free(exe);
return EINA_FALSE;
}
free(exe);
/* Open companion .so file.
* Support for legacy quicklaunch apps with separate library.
*/
qr_handle = dlopen(exe2, RTLD_NOW | RTLD_GLOBAL);
if (!qr_handle)
{
fprintf(stderr, "dlerr: %s\n", dlerror());
WRN("dlopen('%s') failed: %s", exe2, dlerror());
free(exe2);
return EINA_FALSE;
}
INF("dlopen('%s') = %p", exe2, qr_handle);
qre_main = dlsym(qr_handle, "efl_main");
INF("dlsym(%p, 'elm_main') = %p", qr_handle, qre_main);
if (!qre_main)
{
WRN("not quicklauncher capable: no efl_main in '%s'", exe2);
dlclose(qr_handle);
qr_handle = NULL;
free(exe2);
return EINA_FALSE;
}
free(exe2);
return EINA_TRUE;
#else
(void)argc;
(void)argv;
(void)cwd;
return EINA_FALSE;
#endif
}
EAPI Eina_Bool EAPI Eina_Bool
elm_quicklaunch_fork(int argc, elm_quicklaunch_fork(int argc,
char **argv, char **argv,
@ -943,7 +1033,7 @@ elm_quicklaunch_fork(int argc,
pid_t child; pid_t child;
int ret; int ret;
if (!qr_main) if (!qr_main && !qre_main)
{ {
int i; int i;
char **args; char **args;
@ -1031,8 +1121,20 @@ elm_quicklaunch_fork(int argc,
ecore_app_args_set(argc, (const char **)argv); ecore_app_args_set(argc, (const char **)argv);
if (_elm_config->atspi_mode != ELM_ATSPI_MODE_OFF) if (_elm_config->atspi_mode != ELM_ATSPI_MODE_OFF)
_elm_atspi_bridge_init(); _elm_atspi_bridge_init();
ret = qr_main(argc, argv);
exit(ret); if (qre_main)
{
eo_event_callback_add(ecore_main_loop_get(), EFL_LOOP_EVENT_ARGUMENTS, qre_main, NULL);
elm_run();
elm_shutdown();
// FIXME: get value back from the main loop quit ?
exit(0);
}
else
{
ret = qr_main(argc, argv);
exit(ret);
}
return EINA_TRUE; return EINA_TRUE;
#else #else
return EINA_FALSE; return EINA_FALSE;
@ -1071,6 +1173,25 @@ elm_quicklaunch_fallback(int argc,
return ret; return ret;
} }
EAPI Eina_Bool
efl_quicklaunch_fallback(int argc,
char **argv)
{
/* int ret; */
char cwd[PATH_MAX];
elm_quicklaunch_init(argc, argv);
elm_quicklaunch_sub_init(argc, argv);
if (efl_quicklaunch_prepare(argc, argv, getcwd(cwd, sizeof(cwd))))
{
eo_event_callback_add(ecore_main_loop_get(), EFL_LOOP_EVENT_ARGUMENTS, qre_main, NULL);
elm_run();
// FIXME: get value back from the main loop quit ?
return EINA_TRUE;
}
return EINA_FALSE;
}
EAPI char * EAPI char *
elm_quicklaunch_exe_path_get(const char *exe, const char *cwd) elm_quicklaunch_exe_path_get(const char *exe, const char *cwd)
{ {