#include "private.h" #ifdef HAVE_PO #include #endif #include #include #include "main.h" #include "win.h" #include "termio.h" #include "termpty.h" #include "config.h" #include "controls.h" #include "media.h" #include "theme.h" #include "ipc.h" #include "sel.h" #include "miniview.h" #include "gravatar.h" #include "keyin.h" int terminology_starting_up; int _log_domain = -1; Eina_Bool multisense_available = EINA_TRUE; static Config *_main_config = NULL; static void _set_instance_theme(Ipc_Instance *inst) { char path[PATH_MAX]; char theme_name[PATH_MAX]; const char *theme_path = (const char *)&path; if (!inst->theme) return; if (eina_str_has_suffix(inst->theme, ".edj")) eina_strlcpy(theme_name, inst->theme, sizeof(theme_name)); else snprintf(theme_name, sizeof(theme_name), "%s.edj", inst->theme); if (strchr(theme_name, '/')) eina_strlcpy(path, theme_name, sizeof(path)); else theme_path = theme_path_get(theme_name); eina_stringshare_replace(&(inst->config->theme), theme_path); inst->config->temporary = EINA_TRUE; } #define IPC_INSTANCE_OPT_UNSET 0xff static void _configure_instance(Ipc_Instance *inst) { Config *config = inst->config; _set_instance_theme(inst); if (inst->colorscheme) { eina_stringshare_replace(&(config->color_scheme_name), inst->colorscheme); config_compute_color_scheme(config); config->temporary = EINA_TRUE; } if (inst->background) { eina_stringshare_replace(&(config->background), inst->background); config->temporary = EINA_TRUE; } if (inst->font) { char *p = strchr(inst->font, '/'); if (p) { int sz; char *fname = alloca(p - inst->font + 1); strncpy(fname, inst->font, p - inst->font); fname[p - inst->font] = '\0'; sz = atoi(p+1); if (sz > 0) inst->config->font.size = sz; eina_stringshare_replace(&(inst->config->font.name), fname); inst->config->font.bitmap = EINA_FALSE; } else { char buf[4096], *file; Eina_List *files; int n = strlen(inst->font); Eina_Bool found = EINA_FALSE; snprintf(buf, sizeof(buf), "%s/fonts", elm_app_data_dir_get()); files = ecore_file_ls(buf); EINA_LIST_FREE(files, file) { if (n > 0) { if (!strncasecmp(file, inst->font, n)) { n = -1; eina_stringshare_replace(&(inst->config->font.name), file); inst->config->font.bitmap = EINA_TRUE; found = EINA_TRUE; } } free(file); } if (!found) { ERR("font '%s' not found in %s", inst->font, buf); } } config->font_set = EINA_TRUE; config->temporary = EINA_TRUE; } if (inst->login_shell != IPC_INSTANCE_OPT_UNSET) { inst->config->login_shell = inst->login_shell; inst->config->temporary = EINA_TRUE; } if (inst->xterm_256color) { inst->config->xterm_256color = EINA_TRUE; inst->config->temporary = EINA_TRUE; } if (inst->video_mute != IPC_INSTANCE_OPT_UNSET) { config->mute = inst->video_mute; config->temporary = EINA_TRUE; } if (inst->cursor_blink != IPC_INSTANCE_OPT_UNSET) { config->disable_cursor_blink = !inst->cursor_blink; config->temporary = EINA_TRUE; } if (inst->visual_bell != IPC_INSTANCE_OPT_UNSET) { config->disable_visual_bell = !inst->visual_bell; config->temporary = EINA_TRUE; } if (inst->active_links != IPC_INSTANCE_OPT_UNSET) { config->active_links = !!inst->active_links; config->active_links_email = inst->config->active_links; config->active_links_file = inst->config->active_links; config->active_links_url = inst->config->active_links; config->active_links_escape = inst->config->active_links; config->temporary = EINA_TRUE; } } static void _check_multisense(void) { int enabled; Eina_Bool setting = edje_audio_channel_mute_get(EDJE_CHANNEL_EFFECT); /* older versions of efl have no capability for determining whether multisense support * is available * to check, attempt to set mute on a channel and check the value: if the value has not been * set then the multisense codepath is disabled * * this is a no-op in either case, as the function only sets an internal variable and returns */ for (enabled = 0; enabled < 2; enabled++) { edje_audio_channel_mute_set(EDJE_CHANNEL_EFFECT, enabled); if (enabled != edje_audio_channel_mute_get(EDJE_CHANNEL_EFFECT)) multisense_available = EINA_FALSE; } edje_audio_channel_mute_set(EDJE_CHANNEL_EFFECT, setting); } Config * main_config_get(void) { return _main_config; } static void main_ipc_new(Ipc_Instance *inst) { Win *wn; Term *term; Config *config; int pargc = 0, nargc, i; char **pargv = NULL, **nargv = NULL, geom[256]; Evas_Object *win; if (inst->startup_id) { char buf[4096]; snprintf(buf, sizeof(buf), "DESKTOP_STARTUP_ID=%s", inst->startup_id); putenv(strdup(buf)); } ecore_app_args_get(&pargc, &pargv); nargc = 1; if (inst->cd) nargc += 2; if (inst->background) nargc += 2; if (inst->name) nargc += 2; if (inst->role) nargc += 2; if (inst->title) nargc += 2; if (inst->font) nargc += 2; if (inst->startup_split) nargc += 2; if ((inst->pos) || (inst->w > 0) || (inst->h > 0)) nargc += 2; if (inst->login_shell) nargc += 1; if (inst->fullscreen) nargc += 1; if (inst->iconic) nargc += 1; if (inst->borderless) nargc += 1; if (inst->override) nargc += 1; if (inst->maximized) nargc += 1; if (inst->hold) nargc += 1; if (inst->nowm) nargc += 1; if (inst->xterm_256color) nargc += 1; if (inst->active_links) nargc += 1; if (inst->video_mute) nargc += 1; if (inst->cursor_blink) nargc += 1; if (inst->visual_bell) nargc += 1; if (inst->cmd) nargc += 2; if (inst->theme) nargc += 2; if (inst->colorscheme) nargc += 2; nargv = calloc(nargc + 1, sizeof(char *)); if (!nargv) return; i = 0; nargv[i++] = pargv[0]; if (inst->cd) { nargv[i++] = "-d"; nargv[i++] = (char *)inst->cd; } if (inst->background) { nargv[i++] = "-b"; nargv[i++] = (char *)inst->background; } if (inst->name) { nargv[i++] = "-n"; nargv[i++] = (char *)inst->name; } if (inst->theme) { nargv[i++] = "-t"; nargv[i++] = (char *)inst->theme; } if (inst->colorscheme) { nargv[i++] = "--colorscheme"; nargv[i++] = (char *)inst->colorscheme; } if (inst->role) { nargv[i++] = "-r"; nargv[i++] = (char *)inst->role; } if (inst->title) { nargv[i++] = "-T"; nargv[i++] = (char *)inst->title; } if (inst->font) { nargv[i++] = "-f"; nargv[i++] = (char *)inst->font; } if (inst->startup_split) { nargv[i++] = "-S"; nargv[i++] = (char *)inst->startup_split; } if ((inst->pos) || (inst->w > 0) || (inst->h > 0)) { if (!inst->pos) snprintf(geom, sizeof(geom), "%ix%i", inst->w, inst->h); else { if ((inst->w > 0) && (inst->h > 0)) { if (inst->x >= 0) { if (inst->y >= 0) snprintf(geom, sizeof(geom), "%ix%i+%i+%i", inst->w, inst->h, inst->x, inst->y); else snprintf(geom, sizeof(geom), "%ix%i+%i%i", inst->w, inst->h, inst->x, inst->y); } else { if (inst->y >= 0) snprintf(geom, sizeof(geom), "%ix%i%i+%i", inst->w, inst->h, inst->x, inst->y); else snprintf(geom, sizeof(geom), "%ix%i%i%i", inst->w, inst->h, inst->x, inst->y); } } else { if (inst->x >= 0) { if (inst->y >= 0) snprintf(geom, sizeof(geom), "+%i+%i", inst->x, inst->y); else snprintf(geom, sizeof(geom), "+%i%i", inst->x, inst->y); } else { if (inst->y >= 0) snprintf(geom, sizeof(geom), "%i+%i", inst->x, inst->y); else snprintf(geom, sizeof(geom), "%i%i", inst->x, inst->y); } } } nargv[i++] = "-g"; nargv[i++] = geom; } if ((inst->login_shell != IPC_INSTANCE_OPT_UNSET) && (inst->login_shell != 0)) { nargv[i++] = "-l"; } if (inst->fullscreen) { nargv[i++] = "-F"; } if (inst->iconic) { nargv[i++] = "-I"; } if (inst->borderless) { nargv[i++] = "-B"; } if (inst->override) { nargv[i++] = "-O"; } if (inst->maximized) { nargv[i++] = "-M"; } if (inst->hold) { nargv[i++] = "-H"; } if (inst->nowm) { nargv[i++] = "-W"; } if (inst->xterm_256color) { nargv[i++] = "-2"; } if ((inst->active_links != IPC_INSTANCE_OPT_UNSET) && (inst->active_links != 0)) { nargv[i++] = "--active-links"; } if (inst->cmd) { nargv[i++] = "-e"; nargv[i++] = (char *)inst->cmd; } if ((inst->video_mute != IPC_INSTANCE_OPT_UNSET) && (inst->video_mute != 0)) { nargv[i++] = "-m"; } if ((inst->cursor_blink != IPC_INSTANCE_OPT_UNSET) && (inst->cursor_blink != 0)) { nargv[i++] = "-c"; } if ((inst->visual_bell != IPC_INSTANCE_OPT_UNSET) && (inst->visual_bell != 0)) { nargv[i++] = "-G"; } ecore_app_args_set(nargc, (const char **)nargv); wn = win_new(inst->name, inst->role, inst->title, inst->icon_name, _main_config, inst->fullscreen, inst->iconic, inst->borderless, inst->override, inst->maximized); if (!wn) { CRITICAL(_("Could not create window")); ecore_app_args_set(pargc, (const char **)pargv); free(nargv); return; } win = win_evas_object_get(wn); config = win_config_get(wn); inst->config = config; _configure_instance(inst); if (inst->w <= 0) inst->w = 80; if (inst->h <= 0) inst->h = 24; term = term_new(wn, config, inst->cmd, inst->login_shell, inst->cd, inst->w, inst->h, inst->hold, inst->title); if (!term) { CRITICAL(_("Could not create terminal widget")); win_free(wn); ecore_app_args_set(pargc, (const char **)pargv); free(nargv); return; } if (win_term_set(wn, term) < 0) return; main_trans_update(); main_media_update(config); if (inst->pos) { int screen_w, screen_h; elm_win_screen_size_get(win, NULL, NULL, &screen_w, &screen_h); if (inst->x < 0) inst->x = screen_w + inst->x; if (inst->y < 0) inst->y = screen_h + inst->y; evas_object_move(win, inst->x, inst->y); } win_sizing_handle(wn); evas_object_show(win_evas_object_get(wn)); if (inst->nowm) ecore_evas_focus_set (ecore_evas_ecore_evas_get(evas_object_evas_get(win)), 1); ecore_app_args_set(pargc, (const char **)pargv); free(nargv); unsetenv("DESKTOP_STARTUP_ID"); } static Ecore_Getopt options = { PACKAGE_NAME, "%prog [options]", PACKAGE_VERSION, gettext_noop("(C) 2012-%d Carsten Haitzler and others"), "BSD 2-Clause", gettext_noop("Terminal emulator written with Enlightenment Foundation Libraries"), EINA_TRUE, { ECORE_GETOPT_STORE_STR ('b', "background", gettext_noop("Use the named file as a background wallpaper")), ECORE_GETOPT_STORE_STR ('d', "current-directory", gettext_noop("Change to directory for execution of terminal command")), ECORE_GETOPT_BREAK_STR ('e', "exec", gettext_noop("Command to execute. Defaults to $SHELL (or passwd shell or /bin/sh)")), ECORE_GETOPT_STORE_STR ('t', "theme", gettext_noop("Use the named edje theme or path to theme file")), ECORE_GETOPT_STORE_STR ('C', "colorscheme", gettext_noop("Use the named color scheme")), ECORE_GETOPT_STORE_STR ('g', "geometry", gettext_noop("Terminal geometry to use (eg 80x24 or 80x24+50+20 etc.)")), ECORE_GETOPT_STORE_STR ('n', "name", gettext_noop("Set window name")), ECORE_GETOPT_STORE_STR ('r', "role", gettext_noop("Set window role")), ECORE_GETOPT_STORE_STR ('T', "title", gettext_noop("Set window title")), ECORE_GETOPT_STORE_STR ('i', "icon-name", gettext_noop("Set icon name")), ECORE_GETOPT_STORE_STR ('f', "font", gettext_noop("Set font (NAME/SIZE for scalable, NAME for bitmap)")), ECORE_GETOPT_STORE_STR ('S', "split", gettext_noop("Split the terminal window." " 'v' for vertical and 'h' for horizontal." " Can be used multiple times. eg -S vhvv or --split hv" " More description available on the man page")), ECORE_GETOPT_STORE_BOOL('l', "login", gettext_noop("Run the shell as a login shell")), ECORE_GETOPT_STORE_BOOL('m', "video-mute", gettext_noop("Set mute mode for video playback")), ECORE_GETOPT_STORE_BOOL('c', "cursor-blink", gettext_noop("Set cursor blink mode")), ECORE_GETOPT_STORE_BOOL('G', "visual-bell", gettext_noop("Set visual bell mode")), ECORE_GETOPT_STORE_TRUE('F', "fullscreen", gettext_noop("Go into the fullscreen mode from the start")), ECORE_GETOPT_STORE_TRUE('I', "iconic", gettext_noop("Start iconified")), ECORE_GETOPT_STORE_TRUE('B', "borderless", gettext_noop("Start borderless")), ECORE_GETOPT_STORE_TRUE('O', "override", gettext_noop("Start as a override-redirect window")), ECORE_GETOPT_STORE_TRUE('M', "maximized", gettext_noop("Start maximized")), ECORE_GETOPT_STORE_TRUE('W', "nowm", gettext_noop("Terminology is run without a window manager")), ECORE_GETOPT_STORE_TRUE('H', "hold", gettext_noop("Do not exit when the command process exits")), ECORE_GETOPT_STORE_TRUE('s', "single", gettext_noop("Force single executable if multi-instance is enabled")), ECORE_GETOPT_STORE_TRUE('2', "256color", gettext_noop("Set TERM to 'xterm-256color' instead of 'xterm'")), ECORE_GETOPT_STORE_DOUBLE('\0', "scale", gettext_noop("Set scaling factor")), ECORE_GETOPT_STORE_BOOL('\0', "active-links", gettext_noop("Highlight links")), ECORE_GETOPT_STORE_BOOL('\0', "no-wizard", gettext_noop("Do not display wizard on start up")), ECORE_GETOPT_VERSION ('V', "version"), ECORE_GETOPT_COPYRIGHT ('\0', "copyright"), ECORE_GETOPT_LICENSE ('L', "license"), ECORE_GETOPT_HELP ('h', "help"), ECORE_GETOPT_SENTINEL } }; #if ENABLE_NLS static void _translate_options(void) { options.copyright = eina_stringshare_printf(gettext(options.copyright), 2020); Ecore_Getopt_Desc *desc = (Ecore_Getopt_Desc *) options.descs; while ((desc->shortname != '\0') || (desc->longname) || (desc->action == ECORE_GETOPT_ACTION_CATEGORY)) { if (desc->help) { switch (desc->action) { case ECORE_GETOPT_ACTION_VERSION: desc->help = _("show program version"); break; case ECORE_GETOPT_ACTION_COPYRIGHT: desc->help = _("show copyright"); break; case ECORE_GETOPT_ACTION_LICENSE: desc->help = _("show license"); break; case ECORE_GETOPT_ACTION_HELP: desc->help = _("show this message"); break; default: desc->help = gettext(desc->help); } } desc++; } } #endif #if defined(BINARY_TYFUZZ) || defined(BINARY_TYTEST) static void _log_void(const Eina_Log_Domain *_d EINA_UNUSED, Eina_Log_Level level EINA_UNUSED, const char *_file EINA_UNUSED, const char *_fnc EINA_UNUSED, int _line EINA_UNUSED, const char *fmt EINA_UNUSED, void *_data EINA_UNUSED, va_list args EINA_UNUSED) { } #endif static void _start(Ipc_Instance *instance, Eina_Bool need_scale_wizard) { Win *wn; Evas_Object *win; Term *term; Config *config; wn = win_new(instance->name, instance->role, instance->title, instance->icon_name, instance->config, instance->fullscreen, instance->iconic, instance->borderless, instance->override, instance->maximized); // set an env so terminal apps can detect they are in terminology :) putenv("TERMINOLOGY=1"); config_del(instance->config); config = NULL; if (!wn) { CRITICAL(_("Could not create window")); goto exit; } config = win_config_get(wn); term = term_new(wn, config, instance->cmd, instance->login_shell, instance->cd, instance->w, instance->h, instance->hold, instance->title); if (!term) { CRITICAL(_("Could not create terminal widget")); config = NULL; goto exit; } if (win_term_set(wn, term) < 0) { goto exit; } main_trans_update(); main_media_update(config); win_sizing_handle(wn); win = win_evas_object_get(wn); evas_object_show(win); if (instance->startup_split) { unsigned int i = 0; Term *next = term; for (i = 0; i < strlen(instance->startup_split); i++) { char *cmd = NULL; if (instance->startup_split[i] == 'v') { cmd = eina_list_data_get(instance->cmds); split_vertically(term_termio_get(next), cmd); instance->cmds = eina_list_remove_list(instance->cmds, instance->cmds); } else if (instance->startup_split[i] == 'h') { cmd = eina_list_data_get(instance->cmds); split_horizontally(term_termio_get(next), cmd); instance->cmds = eina_list_remove_list(instance->cmds, instance->cmds); } else if (instance->startup_split[i] == '-') next = term_next_get(next); else { CRITICAL(_("invalid argument found for option -S/--split." " See --help")); goto end; } } } if (instance->pos) { int screen_w, screen_h; elm_win_screen_size_get(win, NULL, NULL, &screen_w, &screen_h); if (instance->x < 0) instance->x = screen_w + instance->x; if (instance->y < 0) instance->y = screen_h + instance->y; evas_object_move(win, instance->x, instance->y); } if (instance->nowm) ecore_evas_focus_set(ecore_evas_ecore_evas_get( evas_object_evas_get(win)), 1); controls_init(); if (need_scale_wizard) win_scale_wizard(win, term); terminology_starting_up = EINA_FALSE; end: return; exit: ecore_main_loop_quit(); } struct Instance_Add { Ipc_Instance *instance; char **argv; Eina_Bool result; Eina_Bool timedout; Eina_Bool done; pthread_mutex_t lock; }; static void _instance_add_free(struct Instance_Add *add) { if (!add) return; pthread_mutex_destroy(&add->lock); free(add); } static void * _instance_sleep(void *data) { struct Instance_Add *add = data; Eina_Bool timedout = EINA_FALSE; sleep(2); pthread_mutex_lock(&add->lock); if (!add->done) timedout = add->timedout = EINA_TRUE; pthread_mutex_unlock(&add->lock); if (timedout) { /* ok, we waited 2 seconds without any answer, * remove the unix socket and restart terminology from scratch in a * better state */ ipc_instance_conn_free(); errno = 0; execv(add->argv[0], add->argv); ERR("execv failed on '%s': %s", add->argv[0], strerror(errno)); } else { _instance_add_free(add); } return NULL; } static Eina_Bool _instance_add_waiter(Ipc_Instance *instance, char **argv) { struct Instance_Add *add; Eina_Bool timedout = EINA_FALSE; Eina_Bool result = EINA_TRUE; pthread_t thr; add = calloc(1, sizeof(*add)); if (!add) return EINA_FALSE; add->instance = instance; add->argv = argv; pthread_mutex_init(&add->lock, NULL); pthread_create(&thr, NULL, &_instance_sleep, add); /* If the unix socket is stalled, this might block */ result = ipc_instance_add(add->instance); pthread_mutex_lock(&add->lock); /* Hoora, it did not block! */ add->done = EINA_TRUE; if (add->timedout) { timedout = add->timedout = EINA_TRUE; result = EINA_FALSE; } pthread_mutex_unlock(&add->lock); if (timedout) _instance_add_free(add); return result; } static Eina_Bool _start_multi(Ipc_Instance *instance, char **argv, Eina_Bool need_scale_wizard) { int remote_try = 0; do { if (_instance_add_waiter(instance, argv)) { goto exit; } /* Could not start a new window remotely, * let's start our own server */ ipc_instance_new_func_set(main_ipc_new); if (ipc_serve()) { goto normal_start; } else { DBG("IPC server: failure"); } remote_try++; } while (remote_try <= 1); normal_start: _start(instance, need_scale_wizard); return EINA_FALSE; exit: return EINA_TRUE; } EAPI_MAIN int elm_main(int argc, char **argv) { char *geometry = NULL; Eina_Bool quit_option = EINA_FALSE; Eina_Bool single = EINA_FALSE; Eina_Bool no_wizard = EINA_FALSE; Eina_Bool cmd_options = EINA_FALSE; double scale = -1.0; /* unset */ Ipc_Instance instance = { .login_shell = IPC_INSTANCE_OPT_UNSET, .active_links = IPC_INSTANCE_OPT_UNSET, .video_mute = IPC_INSTANCE_OPT_UNSET, .cursor_blink = IPC_INSTANCE_OPT_UNSET, .visual_bell = IPC_INSTANCE_OPT_UNSET, .startup_id = getenv("DESKTOP_STARTUP_ID"), .w = 1, .h = 1, }; Ecore_Getopt_Value values[] = { ECORE_GETOPT_VALUE_STR(instance.background), /* -b, --background */ ECORE_GETOPT_VALUE_STR(instance.cd), /* -d, --current-directory */ ECORE_GETOPT_VALUE_BOOL(cmd_options), /* -e, --exec */ ECORE_GETOPT_VALUE_STR(instance.theme), /* -t, --theme */ ECORE_GETOPT_VALUE_STR(instance.colorscheme), /* -C, --colorscheme */ ECORE_GETOPT_VALUE_STR(geometry), /* -g, --geometry */ ECORE_GETOPT_VALUE_STR(instance.name), /* -n, --name */ ECORE_GETOPT_VALUE_STR(instance.role), /* -r, --role */ ECORE_GETOPT_VALUE_STR(instance.title), /* -T, --title */ ECORE_GETOPT_VALUE_STR(instance.icon_name), /* -i, --icon-name */ ECORE_GETOPT_VALUE_STR(instance.font), /* -f, --font */ ECORE_GETOPT_VALUE_STR(instance.startup_split), /* -S, --split */ ECORE_GETOPT_VALUE_BOOL(instance.login_shell), /* -l, --login */ ECORE_GETOPT_VALUE_BOOL(instance.video_mute), /* -m, --video-mute */ ECORE_GETOPT_VALUE_BOOL(instance.cursor_blink), /* -c, --cursor-blink */ ECORE_GETOPT_VALUE_BOOL(instance.visual_bell), /* -G, --visual-bell */ ECORE_GETOPT_VALUE_BOOL(instance.fullscreen), /* -F, --fullscreen */ ECORE_GETOPT_VALUE_BOOL(instance.iconic), /* -I, --iconic */ ECORE_GETOPT_VALUE_BOOL(instance.borderless), /* -B, --borderless */ ECORE_GETOPT_VALUE_BOOL(instance.override), /* -O, --override */ ECORE_GETOPT_VALUE_BOOL(instance.maximized), /* -M, --maximized */ ECORE_GETOPT_VALUE_BOOL(instance.nowm), /* -W, --nowm */ ECORE_GETOPT_VALUE_BOOL(instance.hold), /* -H, --hold */ ECORE_GETOPT_VALUE_BOOL(single), /* -s, --single */ ECORE_GETOPT_VALUE_BOOL(instance.xterm_256color), /* -2, --256color */ ECORE_GETOPT_VALUE_DOUBLE(scale), /* --scale */ ECORE_GETOPT_VALUE_BOOL(instance.active_links), /* --active-links */ ECORE_GETOPT_VALUE_BOOL(no_wizard), /* --no-wizard */ ECORE_GETOPT_VALUE_BOOL(quit_option), /* -v, --version */ ECORE_GETOPT_VALUE_BOOL(quit_option), /* --copyright */ ECORE_GETOPT_VALUE_BOOL(quit_option), /* -L, --license */ ECORE_GETOPT_VALUE_BOOL(quit_option), /* -h, --help */ ECORE_GETOPT_VALUE_NONE }; int args, retval = EXIT_SUCCESS; Eina_Bool size_set = EINA_FALSE; Eina_Bool need_scale_wizard = utils_need_scale_wizard(); terminology_starting_up = EINA_TRUE; #if defined(BINARY_TYFUZZ) || defined(BINARY_TYTEST) eina_log_print_cb_set(_log_void, NULL); #endif elm_config_item_select_on_focus_disabled_set(EINA_TRUE); elm_language_set(""); elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED); 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); #if ENABLE_NLS elm_app_compile_locale_set(LOCALEDIR); #endif elm_app_info_set(elm_main, "terminology", "themes/default.edj"); #if ENABLE_NLS bindtextdomain(PACKAGE, elm_app_locale_dir_get()); textdomain(PACKAGE); _translate_options(); #else options.copyright = "(C) 2012-2020 Carsten Haitzler and others"; #endif _log_domain = eina_log_domain_register("terminology", NULL); if (_log_domain < 0) { EINA_LOG_CRIT(_("Could not create logging domain '%s'"), "terminology"); elm_shutdown(); return EXIT_FAILURE; } config_init(); colors_init(); _main_config = config_load(); if (key_bindings_load(_main_config) < 0) { CRITICAL(_("Could not initialize key bindings")); retval = EXIT_FAILURE; goto end; } ecore_con_init(); ecore_con_url_init(); ipc_init(); instance.config = config_fork(_main_config); args = ecore_getopt_parse(&options, values, argc, argv); if (args < 0) { CRITICAL(_("Could not parse command line options")); retval = EXIT_FAILURE; goto end; } if (scale > 0.0) { elm_config_scale_set(scale); elm_config_all_flush(); instance.config->temporary = EINA_TRUE; } if (no_wizard) need_scale_wizard = EINA_FALSE; if (quit_option) goto end; if (cmd_options) { int i; if (args == argc) { CRITICAL(_("option %s requires an argument!"), argv[args-1]); CRITICAL(_("invalid options found. See --help")); goto end; } if (instance.startup_split) { for(i = args+1; i < argc; i++) instance.cmds = eina_list_append(instance.cmds, argv[i]); instance.cmd = argv[args]; } else { Eina_Strbuf *strb; strb = eina_strbuf_new(); eina_strbuf_append(strb, argv[args]); for(i = args+1; i < argc; i++) { eina_strbuf_append_char(strb, ' '); eina_strbuf_append(strb, argv[i]); } instance.cmd = eina_strbuf_string_steal(strb); eina_strbuf_free(strb); } } _check_multisense(); _configure_instance(&instance); if (geometry) { if (sscanf(geometry,"%ix%i+%i+%i", &instance.w, &instance.h, &instance.x, &instance.y) == 4) { instance.pos = EINA_TRUE; size_set = EINA_TRUE; } else if (sscanf(geometry,"%ix%i-%i+%i", &instance.w, &instance.h, &instance.x, &instance.y) == 4) { instance.x = -instance.x; instance.pos = EINA_TRUE; size_set = EINA_TRUE; } else if (sscanf(geometry,"%ix%i-%i-%i", &instance.w, &instance.h, &instance.x, &instance.y) == 4) { instance.x = -instance.x; instance.y = -instance.y; instance.pos = EINA_TRUE; size_set = EINA_TRUE; } else if (sscanf(geometry,"%ix%i+%i-%i", &instance.w, &instance.h, &instance.x, &instance.y) == 4) { instance.y = -instance.y; instance.pos = EINA_TRUE; size_set = EINA_TRUE; } else if (sscanf(geometry,"%ix%i", &instance.w, &instance.h) == 2) { size_set = EINA_TRUE; } else if (sscanf(geometry,"+%i+%i", &instance.x, &instance.y) == 2) { instance.pos = EINA_TRUE; } else if (sscanf(geometry,"-%i+%i", &instance.x, &instance.y) == 2) { instance.x = -instance.x; instance.pos = EINA_TRUE; } else if (sscanf(geometry,"+%i-%i", &instance.x, &instance.y) == 2) { instance.y = -instance.y; instance.pos = EINA_TRUE; } else if (sscanf(geometry,"-%i-%i", &instance.x, &instance.y) == 2) { instance.x = -instance.x; instance.y = -instance.y; instance.pos = EINA_TRUE; } } if (!size_set) { if (instance.config->custom_geometry) { instance.w = instance.config->cg_width; instance.h = instance.config->cg_height; } else { instance.w = 80; instance.h = 24; } } elm_theme_extension_add(NULL, theme_path_get("default.edj")); elm_theme_overlay_add(NULL, config_theme_path_get(instance.config)); if (instance.login_shell == IPC_INSTANCE_OPT_UNSET) instance.login_shell = instance.config->login_shell; if ((!single) && (instance.config->multi_instance)) { char cwdbuf[4096]; if (!instance.cd) instance.cd = getcwd(cwdbuf, sizeof(cwdbuf)); if (_start_multi(&instance, argv, need_scale_wizard)) goto end; } else { _start(&instance, need_scale_wizard); } elm_run(); ecore_con_url_shutdown(); ecore_con_shutdown(); instance.config = NULL; end: if (instance.config) { config_del(instance.config); instance.config = NULL; } ipc_shutdown(); termpty_shutdown(); miniview_shutdown(); gravatar_shutdown(); windows_free(); config_del(_main_config); key_bindings_shutdown(); colors_shutdown(); config_shutdown(); controls_shutdown(); eina_log_domain_unregister(_log_domain); _log_domain = -1; #if ENABLE_NLS eina_stringshare_del(options.copyright); #endif elm_shutdown(); return retval; } ELM_MAIN()