e_scale: make an internal header
[platform/upstream/enlightenment.git] / src / bin / e_main.c
index 276d404..6b15f81 100644 (file)
@@ -1,7 +1,20 @@
 #include "e.h"
+#include "e_actions_intern.h"
+#include "e_test_helper_intern.h"
+#include "e_user_intern.h"
+#include "e_utils_intern.h"
+#include "e_theme_intern.h"
+#include "e_signals_intern.h"
+#include "e_security_intern.h"
+#include "e_screensaver_intern.h"
+#include "e_scale_intern.h"
+
 #ifdef __linux__
 # include <sys/prctl.h>
 #endif
+#ifdef HAVE_SYSTEMD
+# include <systemd/sd-daemon.h>
+#endif
 
 #define MAX_LEVEL 80
 
      printf("ESTART: %1.5f [%1.5f] - %s\n", t1 - t0, t1 - t2, x); \
      t2 = t1;                                                     \
   }
+
+# define TSB(x)                                                  \
+  do {                                                           \
+     TRACE_DS_BEGIN(ESTART: %s, x);                              \
+     TS(x);                                                      \
+  } while (0)
+# define TSE(x)                                                  \
+  do {                                                           \
+     TRACE_DS_END();                                             \
+     TS(x);                                                      \
+  } while (0)
+# define TSM(x)                                                  \
+  do {                                                           \
+     TRACE_DS_MARK(ESTART: %s, x);                               \
+     TS(x);                                                      \
+  } while (0)
 static double t0, t1, t2;
 #else
 # define TS(x)
+# define TSB(x)
+# define TSE(x)
+# define TSM(x)
 #endif
 /*
  * i need to make more use of these when i'm baffled as to when something is
@@ -71,7 +103,6 @@ static void      _e_main_shutdown_push(int (*func)(void));
 static void      _e_main_parse_arguments(int argc, char **argv);
 static Eina_Bool _e_main_cb_signal_exit(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED);
 static Eina_Bool _e_main_cb_signal_hup(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED);
-static Eina_Bool _e_main_cb_signal_user(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev);
 static int       _e_main_dirs_init(void);
 static int       _e_main_dirs_shutdown(void);
 static int       _e_main_path_init(void);
@@ -80,35 +111,34 @@ static int       _e_main_screens_init(void);
 static int       _e_main_screens_shutdown(void);
 static void      _e_main_desk_save(void);
 static void      _e_main_desk_restore(void);
-static void      _e_main_modules_load(Eina_Bool safe_mode);
 static Eina_Bool _e_main_cb_idle_before(void *data EINA_UNUSED);
 static Eina_Bool _e_main_cb_idle_after(void *data EINA_UNUSED);
 static void      _e_main_create_wm_ready(void);
+static void      _e_main_hooks_clean(void);
+static void      _e_main_hook_call(E_Main_Hook_Point hookpoint, void *data EINA_UNUSED);
 
 /* local variables */
-static Eina_Bool really_know = EINA_FALSE;
-static Eina_Bool inloop = EINA_FALSE;
-static jmp_buf x_fatal_buff;
-
 static int _e_main_lvl = 0;
 static int(*_e_main_shutdown_func[MAX_LEVEL]) (void);
 
 static Ecore_Idle_Enterer *_idle_before = NULL;
 static Ecore_Idle_Enterer *_idle_after = NULL;
 
-static Ecore_Event_Handler *mod_init_end = NULL;
+static Eina_List *hooks = NULL;
+
+static int _e_main_hooks_delete = 0;
+static int _e_main_hooks_walking = 0;
+
+static Eina_Inlist *_e_main_hooks[] =
+{
+   [E_MAIN_HOOK_MODULE_LOAD_DONE] = NULL,
+   [E_MAIN_HOOK_E_INFO_READY] = NULL,
+   [E_MAIN_HOOK_POST_CLIENT_IDLER_BEFORE] = NULL
+};
 
 /* external variables */
-E_API Eina_Bool e_precache_end = EINA_FALSE;
-E_API Eina_Bool x_fatal = EINA_FALSE;
-E_API Eina_Bool good = EINA_FALSE;
-E_API Eina_Bool evil = EINA_FALSE;
 E_API Eina_Bool starting = EINA_TRUE;
 E_API Eina_Bool stopping = EINA_FALSE;
-E_API Eina_Bool restart = EINA_FALSE;
-E_API Eina_Bool e_nopause = EINA_FALSE;
-EINTERN const char *e_first_frame = NULL;
-EINTERN double e_first_frame_start_time = -1;
 
 static Eina_Bool
 _xdg_check_str(const char *env, const char *str)
@@ -127,13 +157,13 @@ _xdg_check_str(const char *env, const char *str)
 static void
 _xdg_data_dirs_augment(void)
 {
-   const char *s;
+   char *s;
    const char *p = e_prefix_get();
-   char newpath[4096], buf[4096];
+   char newpath[PATH_MAX], buf[PATH_MAX + PATH_MAX + 200];
 
    if (!p) return;
 
-   s = getenv("XDG_DATA_DIRS");
+   s = e_util_env_get("XDG_DATA_DIRS");
    if (s)
      {
         Eina_Bool pfxdata, pfx;
@@ -151,6 +181,7 @@ _xdg_data_dirs_augment(void)
                s);
              e_util_env_set("XDG_DATA_DIRS", buf);
           }
+        E_FREE(s);
      }
    else
      {
@@ -158,7 +189,7 @@ _xdg_data_dirs_augment(void)
         e_util_env_set("XDG_DATA_DIRS", buf);
      }
 
-   s = getenv("XDG_CONFIG_DIRS");
+   s = e_util_env_get("XDG_CONFIG_DIRS");
    snprintf(newpath, sizeof(newpath), "%s/etc/xdg", p);
    if (s)
      {
@@ -167,6 +198,7 @@ _xdg_data_dirs_augment(void)
              snprintf(buf, sizeof(buf), "%s:%s", newpath, s);
              e_util_env_set("XDG_CONFIG_DIRS", buf);
           }
+        E_FREE(s);
      }
    else
      {
@@ -174,7 +206,10 @@ _xdg_data_dirs_augment(void)
         e_util_env_set("XDG_CONFIG_DIRS", buf);
      }
 
-   if (!getenv("XDG_RUNTIME_DIR"))
+   s = e_util_env_get("XDG_RUNTIME_DIR");
+   if (s)
+     E_FREE(s);
+   else
      {
         const char *dir;
 
@@ -190,92 +225,87 @@ _xdg_data_dirs_augment(void)
      }
 
    /* set menu prefix so we get our e menu */
-   if (!getenv("XDG_MENU_PREFIX"))
-     {
-        e_util_env_set("XDG_MENU_PREFIX", "e-");
-     }
+   s = e_util_env_get("XDG_MENU_PREFIX");
+   if (s)
+     E_FREE(s);
+   else
+     e_util_env_set("XDG_MENU_PREFIX", "e-");
 }
 
 static Eina_Bool
 _e_main_subsystem_defer(void *data EINA_UNUSED)
 {
-   int argc;
-   char **argv;
-
    TRACE_DS_BEGIN(MAIN:SUBSYSTEMS DEFER);
 
-   ecore_app_args_get(&argc, &argv);
-
    /* try to init delayed subsystems */
 
    TRACE_DS_BEGIN(MAIN:DEFERRED INTERNAL SUBSYSTEMS INIT);
 
-   TS("[DEFERRED] Screens Init: win");
-   if (!e_win_init())
+   TSB("[DEFERRED] DPMS Init");
+   if (!e_dpms_init())
      {
-        e_error_message_show(_("Enlightenment cannot setup elementary trap!\n"));
-        TRACE_DS_END();
-        _e_main_shutdown(-1);
+        e_error_message_show(_("Enlightenment cannot set up dpms.\n"));
+        goto failed;
      }
-   TS("[DEFERRED] Screens Init: win Done");
+   TSE("[DEFERRED] DPMS Init Done");
+   _e_main_shutdown_push(e_dpms_shutdown);
 
-   TS("[DEFERRED] E_Dnd Init");
+   TSB("[DEFERRED] E_Dnd Init");
    if (!e_dnd_init())
      {
         e_error_message_show(_("Enlightenment cannot set up its dnd system.\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("[DEFERRED] E_Dnd Init Done");
+   TSE("[DEFERRED] E_Dnd Init Done");
    _e_main_shutdown_push(e_dnd_shutdown);
 
-   TS("[DEFERRED] E_Scale Init");
+   TSB("[DEFERRED] E_Scale Init");
    if (!e_scale_init())
      {
         e_error_message_show(_("Enlightenment cannot set up its scale system.\n"));
-        TRACE_DS_END();
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("[DEFERRED] E_Scale Init Done");
+   TSE("[DEFERRED] E_Scale Init Done");
    _e_main_shutdown_push(e_scale_shutdown);
 
-   TS("[DEFERRED] E_Test_Helper Init");
+   TSB("[DEFERRED] E_Test_Helper Init");
    e_test_helper_init();
    _e_main_shutdown_push(e_test_helper_shutdown);
-   TS("[DEFERRED] E_Test_Helper Done");
+   TSE("[DEFERRED] E_Test_Helper Done");
 
-   TS("[DEFERRED] E_INFO_SERVER Init");
+   TSB("[DEFERRED] E_INFO_SERVER Init");
    e_info_server_init();
    _e_main_shutdown_push(e_info_server_shutdown);
-   TS("[DEFERRED] E_INFO_SERVER Done");
+   TSE("[DEFERRED] E_INFO_SERVER Done");
 
    TRACE_DS_END();
    TRACE_DS_BEGIN(MAIN:DEFERRED COMP JOB);
 
    /* try to do deferred job of any subsystems*/
-   TS("[DEFERRED] Compositor's deferred job");
+   TSB("[DEFERRED] Compositor's deferred job");
    e_comp_deferred_job();
-   TS("[DEFERRED] Compositor's deferred job Done");
+   TSE("[DEFERRED] Compositor's deferred job Done");
 
-   TRACE_DS_END();
    if (e_config->use_e_policy)
      {
-        TRACE_DS_BEGIN(MAIN:DEFERRED POLICY JOB);
-
-        TS("[DEFERRED] E_Policy's deferred job");
+        TSB("[DEFERRED] E_Policy's deferred job");
         e_policy_deferred_job();
-        TS("[DEFERRED] E_Policy's deferred job Done");
-
-        TRACE_DS_END();
+        TSE("[DEFERRED] E_Policy's deferred job Done");
      }
-   TRACE_DS_BEGIN(MAIN:DEFERRED MODULE JOB);
 
-   TS("[DEFERRED] E_Module's deferred job");
+   TSB("[DEFERRED] E_Module's deferred job");
    e_module_deferred_job();
-   TS("[DEFERRED] E_Module's deferred job Done");
+   TSE("[DEFERRED] E_Module's deferred job Done");
 
    TRACE_DS_END();
    TRACE_DS_END();
+   return ECORE_CALLBACK_DONE;
 
+failed:
+   TSE("INIT FAILED");
+   TRACE_DS_END();
+   TRACE_DS_END();
+   _e_main_shutdown(-1);
    return ECORE_CALLBACK_DONE;
 }
 
@@ -291,9 +321,7 @@ _e_main_deferred_job_schedule(void *d EINA_UNUSED, int type EINA_UNUSED, void *e
 int
 main(int argc, char **argv)
 {
-   Eina_Bool safe_mode = EINA_FALSE;
-   double t = 0.0, tstart = 0.0;
-   char *s = NULL, buff[32];
+   char *s = NULL;
    struct sigaction action;
 
 #ifdef __linux__
@@ -303,12 +331,21 @@ main(int argc, char **argv)
 #  endif
 # endif
 #endif
+
+#ifdef TIZEN_TEST_GCOV
+   setenv("GCOV_PREFIX", "/tmp", 1);
+#endif
+
+   /* for debugging by redirecting stdout & stderr of e to a log file to tail */
+   setvbuf(stdout, NULL, _IONBF, 0);
+   setvbuf(stderr, NULL, _IONBF, 0);
+
 #ifdef TS_DO
    t0 = t1 = t2 = ecore_time_unix_get();
    printf("ESTART(main) %1.5f\n", t0);
 #endif
    TRACE_DS_BEGIN(MAIN:BEGIN STARTUP);
-   TS("Begin Startup");
+   TSB("Begin Startup");
    PRCTL("[Winsys] start of main");
 
    /* trap deadly bug signals and allow some form of sane recovery */
@@ -319,9 +356,12 @@ main(int argc, char **argv)
    /* Wayland shm sets up a sigbus handler for catching invalid shm region */
    /* access. If we setup our sigbus handler here, then the wl-shm sigbus */
    /* handler will not function properly */
-   if (!getenv("NOTIFY_SOCKET"))
+   s = e_util_env_get("NOTIFY_SOCKET");
+   if (s)
+     E_FREE(s);
+   else
      {
-        TS("Signal Trap");
+        TSB("Signal Trap");
         action.sa_sigaction = e_sigseg_act;
         action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
         sigemptyset(&action.sa_mask);
@@ -341,47 +381,34 @@ main(int argc, char **argv)
         action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
         sigemptyset(&action.sa_mask);
         sigaction(SIGABRT, &action, NULL);
-        TS("Signal Trap Done");
+        TSE("Signal Trap Done");
      }
 
-   t = ecore_time_unix_get();
-   s = getenv("E_START_TIME");
-   if ((s) && (!getenv("E_RESTART_OK")))
-     {
-        tstart = atof(s);
-        if ((t - tstart) < 5.0) safe_mode = EINA_TRUE;
-     }
-   tstart = t;
-   snprintf(buff, sizeof(buff), "%1.1f", tstart);
-   e_util_env_set("E_START_TIME", buff);
-
-   if (getenv("E_START_MTRACK"))
-     e_util_env_set("MTRACK", NULL);
-   TS("Eina Init");
+   TSB("Eina Init");
    if (!eina_init())
      {
         e_error_message_show(_("Enlightenment cannot initialize Eina!\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("Eina Init Done");
+   TSE("Eina Init Done");
    _e_main_shutdown_push(eina_shutdown);
 
 #ifdef OBJECT_HASH_CHECK
-   TS("E_Object Hash Init");
+   TSB("E_Object Hash Init");
    e_object_hash_init();
-   TS("E_Object Hash Init Done");
+   TSE("E_Object Hash Init Done");
 #endif
 
-   TS("E_Log Init");
+   TSB("E_Log Init");
    if (!e_log_init())
      {
         e_error_message_show(_("Enlightenment could not create a logging domain!\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("E_Log Init Done");
+   TSE("E_Log Init Done");
    _e_main_shutdown_push(e_log_shutdown);
 
-   TS("Determine Prefix");
+   TSB("Determine Prefix");
    if (!e_prefix_determine(argv[0]))
      {
         fprintf(stderr,
@@ -390,24 +417,21 @@ main(int argc, char **argv)
                 "       This is because it is not on Linux AND has been\n"
                 "       executed strangely. This is unusual.\n");
      }
-   TS("Determine Prefix Done");
+   TSE("Determine Prefix Done");
 
-   /* for debugging by redirecting stdout of e to a log file to tail */
-   setvbuf(stdout, NULL, _IONBF, 0);
-
-   TS("Parse Arguments");
+   TSB("Parse Arguments");
    _e_main_parse_arguments(argc, argv);
-   TS("Parse Arguments Done");
+   TSE("Parse Arguments Done");
 
    /*** Initialize Core EFL Libraries We Need ***/
 
-   TS("Eet Init");
+   TSB("Eet Init");
    if (!eet_init())
      {
         e_error_message_show(_("Enlightenment cannot initialize Eet!\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("Eet Init Done");
+   TSE("Eet Init Done");
    _e_main_shutdown_push(eet_shutdown);
 
    /* Allow ecore to not load system modules.
@@ -416,152 +440,148 @@ main(int argc, char **argv)
     */
    ecore_app_no_system_modules();
 
-   TS("Ecore Init");
+   TSB("Ecore Init");
    if (!ecore_init())
      {
         e_error_message_show(_("Enlightenment cannot initialize Ecore!\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("Ecore Init Done");
+   TSE("Ecore Init Done");
    _e_main_shutdown_push(ecore_shutdown);
 
-   e_first_frame = getenv("E_FIRST_FRAME");
-   if (e_first_frame && e_first_frame[0])
-     e_first_frame_start_time = ecore_time_get();
-   else
-     e_first_frame = NULL;
-
-   TS("EIO Init");
+   TSB("EIO Init");
    if (!eio_init())
      {
         e_error_message_show(_("Enlightenment cannot initialize EIO!\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("EIO Init Done");
+   TSE("EIO Init Done");
    _e_main_shutdown_push(eio_shutdown);
 
-   ecore_app_args_set(argc, (const char **)argv);
-
-   TS("Ecore Event Handlers");
+   TSB("Ecore Event Handlers");
    if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT,
                                 _e_main_cb_signal_exit, NULL))
      {
         e_error_message_show(_("Enlightenment cannot set up an exit signal handler.\n"
                                "Perhaps you are out of memory?"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
    if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_HUP,
                                 _e_main_cb_signal_hup, NULL))
      {
         e_error_message_show(_("Enlightenment cannot set up a HUP signal handler.\n"
                                "Perhaps you are out of memory?"));
-        _e_main_shutdown(-1);
-     }
-   if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
-                                _e_main_cb_signal_user, NULL))
-     {
-        e_error_message_show(_("Enlightenment cannot set up a USER signal handler.\n"
-                               "Perhaps you are out of memory?"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("Ecore Event Handlers Done");
+   TSE("Ecore Event Handlers Done");
 
-   TS("Ecore_File Init");
+   TSB("Ecore_File Init");
    if (!ecore_file_init())
      {
         e_error_message_show(_("Enlightenment cannot initialize Ecore_File!\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("Ecore_File Init Done");
+   TSE("Ecore_File Init Done");
    _e_main_shutdown_push(ecore_file_shutdown);
 
+   TSB("E_Util_File_Monitor Init");
+   e_util_file_monitor_init();
+   TSE("E_Util_File_Monitor Init Done");
+   _e_main_shutdown_push(e_util_file_monitor_shutdown);
+
    _idle_before = ecore_idle_enterer_before_add(_e_main_cb_idle_before, NULL);
 
-   TS("XDG_DATA_DIRS Init");
+   TSB("XDG_DATA_DIRS Init");
    _xdg_data_dirs_augment();
-   TS("XDG_DATA_DIRS Init Done");
+   TSE("XDG_DATA_DIRS Init Done");
 
-   TS("Ecore_Evas Init");
+   TSB("Ecore_Evas Init");
    if (!ecore_evas_init())
      {
         e_error_message_show(_("Enlightenment cannot initialize Ecore_Evas!\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("Ecore_Evas Init Done");
+   TSE("Ecore_Evas Init Done");
 
-   /* e doesn't sync to compositor - it should be one */
-   ecore_evas_app_comp_sync_set(0);
-
-   TS("Edje Init");
+   TSB("Edje Init");
    if (!edje_init())
      {
         e_error_message_show(_("Enlightenment cannot initialize Edje!\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("Edje Init Done");
+   TSE("Edje Init Done");
    _e_main_shutdown_push(edje_shutdown);
 
    /*** Initialize E Subsystems We Need ***/
 
-   TS("E Directories Init");
+   TSB("E User Init");
+   if (!e_user_init())
+     {
+        e_error_message_show(_("Enlightenment cannot set up user home path\n"));
+        goto failed;
+     }
+   TSE("E User Init Done");
+   _e_main_shutdown_push(e_user_shutdown);
+
+   TSB("E Directories Init");
    /* setup directories we will be using for configurations storage etc. */
    if (!_e_main_dirs_init())
      {
         e_error_message_show(_("Enlightenment cannot create directories in your home directory.\n"
                                "Perhaps you have no home directory or the disk is full?"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("E Directories Init Done");
+   TSE("E Directories Init Done");
    _e_main_shutdown_push(_e_main_dirs_shutdown);
 
-   TS("E_Config Init");
+   TSB("E_Config Init");
    if (!e_config_init())
      {
         e_error_message_show(_("Enlightenment cannot set up its config system.\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("E_Config Init Done");
+   TSE("E_Config Init Done");
    _e_main_shutdown_push(e_config_shutdown);
 
-   TS("E_Env Init");
+   TSB("E_Env Init");
    if (!e_env_init())
      {
         e_error_message_show(_("Enlightenment cannot set up its environment.\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("E_Env Init Done");
+   TSE("E_Env Init Done");
    _e_main_shutdown_push(e_env_shutdown);
 
    ecore_exe_run_priority_set(e_config->priority);
 
-   TS("E Paths Init");
+   TSB("E Paths Init");
    if (!_e_main_path_init())
      {
         e_error_message_show(_("Enlightenment cannot set up paths for finding files.\n"
                                "Perhaps you are out of memory?"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("E Paths Init Done");
+   TSE("E Paths Init Done");
    _e_main_shutdown_push(_e_main_path_shutdown);
 
    ecore_animator_frametime_set(1.0 / e_config->framerate);
 
-   TS("E_Theme Init");
+   TSB("E_Theme Init");
    if (!e_theme_init())
      {
         e_error_message_show(_("Enlightenment cannot set up its theme system.\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("E_Theme Init Done");
+   TSE("E_Theme Init Done");
    _e_main_shutdown_push(e_theme_shutdown);
 
-   TS("E_Actions Init");
+   TSB("E_Actions Init");
    if (!e_actions_init())
      {
         e_error_message_show(_("Enlightenment cannot set up its actions system.\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("E_Actions Init Done");
+   TSE("E_Actions Init Done");
    _e_main_shutdown_push(e_actions_shutdown);
 
    /* these just add event handlers and can't fail
@@ -570,7 +590,7 @@ main(int argc, char **argv)
    e_screensaver_preinit();
    e_zone_init();
    e_desk_init();
-   e_slot_init();
+   e_magnifier_init();
 
    TRACE_DS_BEGIN(MAIN:WAIT /dev/dri/card0);
    if (e_config->sleep_for_dri)
@@ -585,125 +605,192 @@ main(int argc, char **argv)
      }
    TRACE_DS_END();
 
-   TS("E_Pointer Init");
+   TSB("E_Msg Init");
+   if (!e_msg_init())
+     {
+        e_error_message_show(_("Enlightenment cannot set up its msg system."));
+        goto failed;
+     }
+   TSE("E_Msg Init Done");
+   _e_main_shutdown_push(e_msg_shutdown);
+
+   e_module_event_init();
+
+   TSB("E_Pointer Init");
    if (!e_pointer_init())
      {
         e_error_message_show(_("Enlightenment cannot set up its pointer system.\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("E_Pointer Init Done");
+   TSE("E_Pointer Init Done");
    _e_main_shutdown_push(e_pointer_shutdown);
 
    TRACE_DS_BEGIN(MAIN:SCREEN INIT);
-   TS("Screens Init");
+   TSB("Screens Init");
    if (!_e_main_screens_init())
      {
         e_error_message_show(_("Enlightenment set up window management for all the screens on your system\n"
                                "failed. Perhaps another window manager is running?\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("Screens Init Done");
+   TSE("Screens Init Done");
    _e_main_shutdown_push(_e_main_screens_shutdown);
    TRACE_DS_END();
 
-   TS("E_Screensaver Init");
+   TSB("E_Devicemgr Init");
+   if (!e_devicemgr_init())
+     {
+        e_error_message_show(_("Enlightenment cannot set up its device_manager system.\n"));
+        goto failed;
+     }
+   TSE("E_Devicemgr Init Done");
+   _e_main_shutdown_push(e_devicemgr_shutdown);
+
+   TSB("E_Keyrouter Init");
+   if (!e_keyrouter_init())
+     {
+        e_error_message_show(_("Enlightenment cannot set up its keyrouting system.\n"));
+        goto failed;
+     }
+   TSE("E_Keyrouter Init Done");
+   _e_main_shutdown_push(e_keyrouter_shutdown);
+
+   if (e_config->eom_enable)
+     {
+        TSB("Eom Init");
+        if (!e_eom_init())
+          {
+             e_error_message_show(_("Enlightenment cannot set up eom.\n"));
+             goto failed;
+          }
+        TSE("Eom Init Done");
+        _e_main_shutdown_push(e_eom_shutdown);
+     }
+
+   TSB("E_Screensaver Init");
    if (!e_screensaver_init())
      {
         e_error_message_show(_("Enlightenment cannot configure the X screensaver.\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("E_Screensaver Init Done");
+   TSE("E_Screensaver Init Done");
    _e_main_shutdown_push(e_screensaver_shutdown);
 
-   TS("E_Comp Freeze");
+   TSB("E_Comp Freeze");
    e_comp_all_freeze();
-   TS("E_Comp Freeze Done");
+   TSE("E_Comp Freeze Done");
 
-   TS("E_Grabinput Init");
+   TSB("E_Grabinput Init");
    if (!e_grabinput_init())
      {
         e_error_message_show(_("Enlightenment cannot set up its grab input handling system.\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("E_Grabinput Init Done");
+   TSE("E_Grabinput Init Done");
    _e_main_shutdown_push(e_grabinput_shutdown);
 
+   TS("E_Gesture Init");
+   e_gesture_init();
+   _e_main_shutdown_push(e_gesture_shutdown);
+
    ecore_event_handler_add(E_EVENT_MODULE_INIT_END, _e_main_deferred_job_schedule, NULL);
 
-   TS("E_Module Init");
+   TSB("E_Module Init");
    if (!e_module_init())
      {
         e_error_message_show(_("Enlightenment cannot set up its module system.\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("E_Module Init Done");
+   TSE("E_Module Init Done");
    _e_main_shutdown_push(e_module_shutdown);
 
-   TS("E_Mouse Init");
+   TSB("E_Mouse Init");
    if (!e_mouse_update())
      {
         e_error_message_show(_("Enlightenment cannot configure the mouse settings.\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("E_Mouse Init Done");
+   TSE("E_Mouse Init Done");
 
-   TS("E_Icon Init");
+   TSB("E_Icon Init");
    if (!e_icon_init())
      {
         e_error_message_show(_("Enlightenment cannot initialize the Icon Cache system.\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("E_Icon Init Done");
+   TSE("E_Icon Init Done");
    _e_main_shutdown_push(e_icon_shutdown);
 
    if (e_config->use_e_policy)
      {
-        TS("E_Policy Init");
+        TSB("E_Policy Init");
         if (!e_policy_init())
           {
              e_error_message_show(_("Enlightenment cannot setup policy system!\n"));
-             _e_main_shutdown(-1);
+             goto failed;
           }
-        TS("E_Policy Init Done");
+        TSE("E_Policy Init Done");
         _e_main_shutdown_push(e_policy_shutdown);
      }
 
-   TS("E_Process Init");
+   TSB("E_Process Init");
    if (!e_process_init())
      {
         e_error_message_show(_("Enlightenment cannot setup process managing system!\n"));
-        _e_main_shutdown(-1);
+        goto failed;
      }
-   TS("E_Process Init Done");
+   TSE("E_Process Init Done");
    _e_main_shutdown_push(e_process_shutdown);
 
-   TS("Load Modules");
-   _e_main_modules_load(safe_mode);
-   TS("Load Modules Done");
+   TSB("E_Security Init");
+   if (!e_security_init())
+     {
+        e_error_message_show(_("Enlightenment cannot setup security system!\n"));
+        goto failed;
+     }
+   TSE("E_Security Init Done");
+   _e_main_shutdown_push(e_security_shutdown);
+
+   TSB("Load Modules");
+   e_module_all_load();
+   TSE("Load Modules Done");
 
-   TS("E_Comp Thaw");
+   TSB("E_Comp Thaw");
    e_comp_all_thaw();
-   TS("E_Comp Thaw Done");
+   TSE("E_Comp Thaw Done");
+
+   if (e_config->use_thread_max_cpu)
+     {
+        int cpus;
+
+        cpus = eina_cpu_count();
+        if (cpus >= 1)
+          {
+             TSM("Set ecore thread max");
+             ecore_thread_max_set(cpus);
+          }
+     }
 
    _idle_after = ecore_idle_enterer_add(_e_main_cb_idle_after, NULL);
 
    starting = EINA_FALSE;
-   inloop = EINA_TRUE;
-
-   e_util_env_set("E_RESTART", "1");
 
-   TS("MAIN LOOP AT LAST");
+   TSM("MAIN LOOP AT LAST");
 
    if (e_config->create_wm_ready)
      _e_main_create_wm_ready();
 
    TRACE_DS_END();
-   if (!setjmp(x_fatal_buff))
-     ecore_main_loop_begin();
-   else
-     CRI("FATAL: X Died. Connection gone. Abbreviated Shutdown\n");
 
-   inloop = EINA_FALSE;
+#ifdef HAVE_SYSTEMD
+   TSM("[WM] Send start-up completion");
+   sd_notify(0, "READY=1");
+#else
+   TSM("[WM] Skip sending start-up completion. (no systemd)");
+#endif
+   ecore_main_loop_begin();
+
+   ELOGF("COMP", "STOPPING enlightenment...", NULL);
    stopping = EINA_TRUE;
 
    _e_main_desk_save();
@@ -711,17 +798,14 @@ main(int argc, char **argv)
 
    _e_main_shutdown(0);
 
-   if (restart)
-     {
-        e_util_env_set("E_RESTART_OK", "1");
-        if (getenv("E_START_MTRACK"))
-          e_util_env_set("MTRACK", "track");
-        ecore_app_restart();
-     }
-
    e_prefix_shutdown();
 
    return 0;
+
+failed:
+   TSE("INIT FAILED");
+   TRACE_DS_END();
+   _e_main_shutdown(-1);
 }
 
 E_API double
@@ -735,28 +819,45 @@ e_main_ts(const char *str)
    return ret;
 }
 
+E_API double
+e_main_ts_begin(const char *str)
+{
+   TRACE_DS_BEGIN(ESTART: %s, str);
+   return e_main_ts(str);
+}
+
+E_API double
+e_main_ts_end(const char *str)
+{
+   TRACE_DS_END();
+   return e_main_ts(str);
+}
+
 /* local functions */
 static void
 _e_main_shutdown(int errcode)
 {
    int i = 0;
    char buf[PATH_MAX];
-   const char *dir;
+   char *dir;
 
    printf("E: Begin Shutdown Procedure!\n");
 
+   E_FREE_LIST(hooks, e_main_hook_del);
+
    if (_idle_before) ecore_idle_enterer_del(_idle_before);
    _idle_before = NULL;
    if (_idle_after) ecore_idle_enterer_del(_idle_after);
    _idle_after = NULL;
 
-   dir = getenv("XDG_RUNTIME_DIR");
+   dir = e_util_env_get("XDG_RUNTIME_DIR");
    if (dir)
      {
-        char buf_env[PATH_MAX];
+        char buf_env[PATH_MAX - 12];
         snprintf(buf_env, sizeof(buf_env), "%s", dir);
         snprintf(buf, sizeof(buf), "%s/.e-deleteme", buf_env);
         if (ecore_file_exists(buf)) ecore_file_recursive_rm(buf_env);
+        E_FREE(dir);
      }
    for (i = (_e_main_lvl - 1); i >= 0; i--)
      (*_e_main_shutdown_func[i])();
@@ -788,34 +889,12 @@ _e_main_parse_arguments(int argc, char **argv)
    /* handle some command-line parameters */
    for (i = 1; i < argc; i++)
      {
-        if (!strcmp(argv[i], "-good"))
-          {
-             good = EINA_TRUE;
-             evil = EINA_FALSE;
-             printf("LA LA LA\n");
-          }
-        else if (!strcmp(argv[i], "-evil"))
-          {
-             good = EINA_FALSE;
-             evil = EINA_TRUE;
-             printf("MUHAHAHAHHAHAHAHAHA\n");
-          }
-        else if (!strcmp(argv[i], "-psychotic"))
-          {
-             good = EINA_TRUE;
-             evil = EINA_TRUE;
-             printf("MUHAHALALALALALALALA\n");
-          }
-        else if ((!strcmp(argv[i], "-profile")) && (i < (argc - 1)))
+        if ((!strcmp(argv[i], "-profile")) && (i < (argc - 1)))
           {
              i++;
              if (!getenv("E_CONF_PROFILE"))
                e_util_env_set("E_CONF_PROFILE", argv[i]);
           }
-        else if (!strcmp(argv[i], "-i-really-know-what-i-am-doing-and-accept-full-responsibility-for-it"))
-          really_know = EINA_TRUE;
-        else if (!strcmp(argv[i], "-nopause"))
-          e_nopause = EINA_TRUE;
         else if ((!strcmp(argv[i], "-version")) ||
                  (!strcmp(argv[i], "--version")))
           {
@@ -829,25 +908,8 @@ _e_main_parse_arguments(int argc, char **argv)
              printf
                (_(
                  "Options:\n"
-                 "\t-display DISPLAY\n"
-                 "\t\tConnect to display named DISPLAY.\n"
-                 "\t\tEG: -display :1.0\n"
-                 "\t-fake-xinerama-screen WxH+X+Y\n"
-                 "\t\tAdd a FAKE xinerama screen (instead of the real ones)\n"
-                 "\t\tgiven the geometry. Add as many as you like. They all\n"
-                 "\t\treplace the real xinerama screens, if any. This can\n"
-                 "\t\tbe used to simulate xinerama.\n"
-                 "\t\tEG: -fake-xinerama-screen 800x600+0+0 -fake-xinerama-screen 800x600+800+0\n"
                  "\t-profile CONF_PROFILE\n"
                  "\t\tUse the configuration profile CONF_PROFILE instead of the user selected default or just \"default\".\n"
-                 "\t-good\n"
-                 "\t\tBe good.\n"
-                 "\t-evil\n"
-                 "\t\tBe evil.\n"
-                 "\t-psychotic\n"
-                 "\t\tBe psychotic.\n"
-                 "\t-i-really-know-what-i-am-doing-and-accept-full-responsibility-for-it\n"
-                 "\t\tIf you need this help, you don't need this option.\n"
                  "\t-version\n"
                  )
                );
@@ -856,18 +918,6 @@ _e_main_parse_arguments(int argc, char **argv)
      }
 }
 
-EINTERN void
-_e_main_cb_x_fatal(void *data EINA_UNUSED)
-{
-   e_error_message_show("Lost X Connection.\n");
-   ecore_main_loop_quit();
-   if (!x_fatal)
-     {
-        x_fatal = EINA_TRUE;
-        if (inloop) longjmp(x_fatal_buff, -99);
-     }
-}
-
 static Eina_Bool
 _e_main_cb_signal_exit(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
 {
@@ -879,32 +929,18 @@ _e_main_cb_signal_exit(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev
 static Eina_Bool
 _e_main_cb_signal_hup(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
 {
-   restart = 1;
    ecore_main_loop_quit();
    return ECORE_CALLBACK_RENEW;
 }
 
-static Eina_Bool
-_e_main_cb_signal_user(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev)
+static int
+_e_main_dirs_init(void)
 {
-   Ecore_Event_Signal_User *e = ev;
-
-   if (e->number == 1)
+   if(getenv("E_CONF_RO"))
      {
-//        E_Action *a = e_action_find("configuration");
-//        if ((a) && (a->func.go)) a->func.go(NULL, NULL);
+        return 1;
      }
-   else if (e->number == 2)
-     {
-        // comp module has its own handler for this for enabling/disabling fps debug
-     }
-   return ECORE_CALLBACK_RENEW;
-
-}
 
-static int
-_e_main_dirs_init(void)
-{
    const char *base;
    const char *dirs[] =
    {
@@ -1069,16 +1105,18 @@ _e_main_path_shutdown(void)
 static int
 _e_main_screens_init(void)
 {
-   TS("\tscreens: client");
+   TSB("\tscreens: client");
    if (!e_client_init()) return 0;
+   TSE("\tscreens: client Done");
 
-   TS("Compositor Init");
+   TSB("Compositor Init");
    PRCTL("[Winsys] start of compositor init");
    if (!e_comp_init())
      {
         e_error_message_show(_("Enlightenment cannot create a compositor.\n"));
         _e_main_shutdown(-1);
      }
+   TSE("Compositor Init Done");
 
    PRCTL("[Winsys] end of compositor init");
    _e_main_desk_restore();
@@ -1089,11 +1127,10 @@ _e_main_screens_init(void)
 static int
 _e_main_screens_shutdown(void)
 {
-   e_win_shutdown();
    e_comp_shutdown();
    e_client_shutdown();
 
-   e_slot_shutdown();
+   e_magnifier_shutdown();
    e_desk_shutdown();
    e_zone_shutdown();
    return 1;
@@ -1117,99 +1154,27 @@ _e_main_desk_save(void)
 static void
 _e_main_desk_restore(void)
 {
-   const Eina_List *l;
-   E_Zone *zone;
    E_Client *ec;
-   char *env;
-   char name[1024];
-
-   EINA_LIST_FOREACH(e_comp->zones, l, zone)
-     {
-        E_Desk *desk;
-        int desk_x, desk_y;
-        char buf_e[64];
-
-        snprintf(name, sizeof(name), "DESK_%d_%d", 0, zone->num);
-        env = getenv(name);
-        if (!env) continue;
-        snprintf(buf_e, sizeof(buf_e), "%s", env);
-        if (!sscanf(buf_e, "%d,%d", &desk_x, &desk_y)) continue;
-        desk = e_desk_at_xy_get(zone, desk_x, desk_y);
-        if (!desk) continue;
-        e_desk_show(desk);
-     }
+   E_Zone *zone;
 
    E_CLIENT_REVERSE_FOREACH(ec)
-     if ((!e_client_util_ignored_get(ec)) && e_client_util_desk_visible(ec, e_desk_current_get(ec->zone)))
-       {
-          ec->want_focus = ec->take_focus = 1;
-          break;
-       }
-}
-
-static Eina_Bool
-_e_main_modules_load_after(void *d EINA_UNUSED, int type EINA_UNUSED, void *ev EINA_UNUSED)
-{
-   E_FREE_FUNC(mod_init_end, ecore_event_handler_del);
-   return ECORE_CALLBACK_RENEW;
-}
-
-static void
-_e_main_modules_load(Eina_Bool safe_mode)
-{
-   if (!safe_mode)
-     e_module_all_load();
-   else
      {
-        E_Module *m;
-        char *crashmodule;
-
-        crashmodule = getenv("E_MODULE_LOAD");
-        if (crashmodule) m = e_module_new(crashmodule);
-
-        if ((crashmodule) && (m))
-          {
-             e_module_disable(m);
-             e_object_del(E_OBJECT(m));
-
-             e_error_message_show
-               (_("Enlightenment crashed early on start and has<br>"
-                  "been restarted. There was an error loading the<br>"
-                  "module named: %s. This module has been disabled<br>"
-                  "and will not be loaded."), crashmodule);
-             e_util_dialog_show
-               (_("Enlightenment crashed early on start and has been restarted"),
-               _("Enlightenment crashed early on start and has been restarted.<br>"
-                 "There was an error loading the module named: %s<br><br>"
-                 "This module has been disabled and will not be loaded."), crashmodule);
-             e_module_all_load();
-          }
-        else
+        zone = e_comp_zone_find_by_ec(ec);
+        if ((!e_client_util_ignored_get(ec)) && e_desk_has_ec(e_desk_current_get(zone), ec))
           {
-             e_error_message_show
-               (_("Enlightenment crashed early on start and has<br>"
-                  "been restarted. All modules have been disabled<br>"
-                  "and will not be loaded to help remove any problem<br>"
-                  "modules from your configuration. The module<br>"
-                  "configuration dialog should let you select your<br>"
-                  "modules again.\n"));
-             e_util_dialog_show
-               (_("Enlightenment crashed early on start and has been restarted"),
-               _("Enlightenment crashed early on start and has been restarted.<br>"
-                 "All modules have been disabled and will not be loaded to help<br>"
-                 "remove any problem modules from your configuration.<br><br>"
-                 "The module configuration dialog should let you select your<br>"
-                 "modules again."));
+             ec->want_focus = ec->take_focus = 1;
+             break;
           }
-        mod_init_end = ecore_event_handler_add(E_EVENT_MODULE_INIT_END, _e_main_modules_load_after, NULL);
      }
 }
 
 static Eina_Bool
 _e_main_cb_idle_before(void *data EINA_UNUSED)
 {
-   e_client_idler_before();
+   e_comp_idler_before();
+   _e_main_hook_call(E_MAIN_HOOK_POST_CLIENT_IDLER_BEFORE, NULL);
    edje_thaw();
+
    return ECORE_CALLBACK_RENEW;
 }
 
@@ -1221,21 +1186,11 @@ _e_main_cb_idle_after(void *data EINA_UNUSED)
    eet_clearcache();
    edje_freeze();
 
-#ifdef E_RELEASE_BUILD
    if (first_idle)
      {
-        TS("SLEEP");
+        TSM("SLEEP");
         first_idle = 0;
-        e_precache_end = EINA_TRUE;
      }
-#else
-   if (first_idle++ < 60)
-     {
-        TS("SLEEP");
-        if (!first_idle)
-          e_precache_end = EINA_TRUE;
-     }
-#endif
 
    return ECORE_CALLBACK_RENEW;
 }
@@ -1244,33 +1199,111 @@ static void
 _e_main_create_wm_ready(void)
 {
    FILE *_wmready_checker = NULL;
+   const char *path_wm_ready = "/run/.wm_ready";
 
-   _wmready_checker = fopen("/run/.wm_ready", "wb");
+   if (!e_util_file_realpath_check(path_wm_ready, EINA_TRUE))
+     {
+        WRN("%s is maybe link, so delete it\n", path_wm_ready);
+     }
+
+   _wmready_checker = fopen(path_wm_ready, "wb");
    if (_wmready_checker)
      {
-        TS("[WM] WINDOW MANAGER is READY!!!");
+        TSM("[WM] WINDOW MANAGER is READY!!!");
         PRCTL("[Winsys] WINDOW MANAGER is READY!!!");
         fclose(_wmready_checker);
 
         /*TODO: Next lines should be removed. */
         FILE *_tmp_wm_ready_checker;
-        _tmp_wm_ready_checker = fopen("/tmp/.wm_ready", "wb");
+
+        _tmp_wm_ready_checker = fopen(path_wm_ready, "wb");
 
         if (_tmp_wm_ready_checker)
           {
-             TS("[WM] temporary wm_ready path is created.");
+             TSM("[WM] temporary wm_ready path is created.");
              PRCTL("[Winsys] temporary wm_ready path is created.");
              fclose(_tmp_wm_ready_checker);
           }
         else
           {
-             TS("[WM] temporary wm_ready path create failed.");
+             TSM("[WM] temporary wm_ready path create failed.");
              PRCTL("[Winsys] temporary wm_ready path create failed.");
           }
      }
    else
      {
-        TS("[WM] WINDOW MANAGER is READY. BUT, failed to create .wm_ready file.");
+        TSM("[WM] WINDOW MANAGER is READY. BUT, failed to create .wm_ready file.");
         PRCTL("[Winsys] WINDOW MANAGER is READY. BUT, failed to create .wm_ready file.");
      }
 }
+
+static void
+_e_main_hooks_clean(void)
+{
+   Eina_Inlist *l;
+   E_Main_Hook *mh;
+   unsigned int x;
+
+   for (x = 0; x < E_MAIN_HOOK_LAST; x++)
+     EINA_INLIST_FOREACH_SAFE(_e_main_hooks[x], l, mh)
+       {
+          if (!mh->delete_me) continue;
+          _e_main_hooks[x] = eina_inlist_remove(_e_main_hooks[x],
+                                                EINA_INLIST_GET(mh));
+          free(mh);
+       }
+}
+
+static void
+_e_main_hook_call(E_Main_Hook_Point hookpoint, void *data EINA_UNUSED)
+{
+   E_Main_Hook *mh;
+
+   _e_main_hooks_walking++;
+   EINA_INLIST_FOREACH(_e_main_hooks[hookpoint], mh)
+     {
+        if (mh->delete_me) continue;
+        mh->func(mh->data);
+     }
+   _e_main_hooks_walking--;
+   if ((_e_main_hooks_walking == 0) && (_e_main_hooks_delete > 0))
+     _e_main_hooks_clean();
+}
+
+E_API E_Main_Hook *
+e_main_hook_add(E_Main_Hook_Point hookpoint, E_Main_Hook_Cb func, const void *data)
+{
+   E_Main_Hook *mh;
+
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_MAIN_HOOK_LAST, NULL);
+   mh = E_NEW(E_Main_Hook, 1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(mh, NULL);
+   mh->hookpoint = hookpoint;
+   mh->func = func;
+   mh->data = (void*)data;
+   _e_main_hooks[hookpoint] = eina_inlist_append(_e_main_hooks[hookpoint],
+                                                 EINA_INLIST_GET(mh));
+   return mh;
+}
+
+E_API void
+e_main_hook_del(E_Main_Hook *mh)
+{
+   mh->delete_me = 1;
+   if (_e_main_hooks_walking == 0)
+     {
+        _e_main_hooks[mh->hookpoint] = eina_inlist_remove(_e_main_hooks[mh->hookpoint],
+                                                          EINA_INLIST_GET(mh));
+        free(mh);
+     }
+   else
+     _e_main_hooks_delete++;
+}
+
+E_API void
+e_main_hook_call(E_Main_Hook_Point hookpoint)
+{
+   if ((hookpoint < 0) || (hookpoint >= E_MAIN_HOOK_LAST)) return;
+
+   _e_main_hook_call(hookpoint, NULL);
+}