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
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_cleanup();
}

View File

@ -998,32 +998,47 @@ colorclass_list_cb(void)
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
* 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 */
EAPI_MAIN int
elm_main(int argc, char **argv)
* efl_main and not be static - must be a visible symbol with EAPI_MAIN infront */
EAPI_MAIN void
efl_main(void *data EINA_UNUSED,
const Eo_Event *ev)
{
Efl_Loop_Arguments *arge = ev->info;
Eina_Bool test_win_only = EINA_FALSE;
char *autorun = NULL;
struct elm_test *t = 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);
/* 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_lib_dir_set(PACKAGE_LIB_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
* the same name as the given param
* 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"
"$ elementary_test\n"
@ -1031,19 +1046,19 @@ elm_main(int argc, char **argv)
"$ elementary_test -to [TEST_NAME]\n\n"
"Examples:\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
* useful with elementary test. */
if ((!strcmp(argv[1], "--test-win-only")) ||
(!strcmp(argv[1], "-to")))
if ((!strcmp(eina_array_data_get(arge->argv, 1), "--test-win-only")) ||
(!strcmp(eina_array_data_get(arge->argv, 1), "-to")))
{
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);
/* put here any init specific to this app like parsing args etc. */
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)
free(t);
end:
eina_log_domain_unregister(_log_domain);
/* exit code */
return 0;
/* FIXME: Hum, no exit code anywhere anymore ? */
}
/* all elementary apps should use this. but it should be placed right after
* elm_main() */
ELM_MAIN()
* efl_main() */
EFL_MAIN()

View File

@ -71,12 +71,14 @@ extern EAPI double _elm_startup_time;
#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 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
/** @deprecated macro to be used after the elm_main() function.
* Do not define ELM_LIB_QUICKLAUNCH
* 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 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
/**************************************************************************/
@ -209,6 +211,11 @@ EAPI void elm_quicklaunch_seed(void);
*/
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
*/
@ -224,6 +231,12 @@ EAPI void elm_quicklaunch_cleanup(void);
*/
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
*/

View File

@ -842,6 +842,8 @@ static void *qr_handle = NULL;
#endif
static int (*qr_main)(int argc,
char **argv) = NULL;
static void (*qre_main)(void *data,
const Eo_Event *ev) = NULL;
EAPI Eina_Bool
elm_quicklaunch_prepare(int argc,
@ -932,6 +934,94 @@ elm_quicklaunch_prepare(int argc,
#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
elm_quicklaunch_fork(int argc,
char **argv,
@ -943,7 +1033,7 @@ elm_quicklaunch_fork(int argc,
pid_t child;
int ret;
if (!qr_main)
if (!qr_main && !qre_main)
{
int i;
char **args;
@ -1031,8 +1121,20 @@ elm_quicklaunch_fork(int argc,
ecore_app_args_set(argc, (const char **)argv);
if (_elm_config->atspi_mode != ELM_ATSPI_MODE_OFF)
_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;
#else
return EINA_FALSE;
@ -1071,6 +1173,25 @@ elm_quicklaunch_fallback(int argc,
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 *
elm_quicklaunch_exe_path_get(const char *exe, const char *cwd)
{