move X idle flusher to comp_x
[platform/upstream/enlightenment.git] / src / bin / e_main.c
1 #include "e.h"
2 #ifdef __linux__
3 # include <sys/prctl.h>
4 #endif
5
6 #define MAX_LEVEL 80
7
8 #define TS_DO
9 #ifdef TS_DO
10 # define TS(x)                                                    \
11   {                                                               \
12      t1 = ecore_time_unix_get();                                  \
13      printf("ESTART: %1.5f [%1.5f] - %s\n", t1 - t0, t1 - t2, x); \
14      t2 = t1;                                                     \
15   }
16 static double t0, t1, t2;
17 #else
18 # define TS(x)
19 #endif
20
21 /*
22  * i need to make more use of these when i'm baffled as to when something is
23  * up. other hooks:
24  *
25  *      void *(*__malloc_hook)(size_t size, const void *caller);
26  *
27  *      void *(*__realloc_hook)(void *ptr, size_t size, const void *caller);
28  *
29  *      void *(*__memalign_hook)(size_t alignment, size_t size,
30  *                               const void *caller);
31  *
32  *      void (*__free_hook)(void *ptr, const void *caller);
33  *
34  *      void (*__malloc_initialize_hook)(void);
35  *
36  *      void (*__after_morecore_hook)(void);
37  *
38
39    static void my_init_hook(void);
40    static void my_free_hook(void *p, const void *caller);
41
42    static void (*old_free_hook)(void *ptr, const void *caller) = NULL;
43    void (*__free_hook)(void *ptr, const void *caller);
44
45    void (*__malloc_initialize_hook) (void) = my_init_hook;
46    static void
47    my_init_hook(void)
48    {
49    old_free_hook = __free_hook;
50    __free_hook = my_free_hook;
51    }
52
53    //void *magicfree = NULL;
54
55    static void
56    my_free_hook(void *p, const void *caller)
57    {
58    __free_hook = old_free_hook;
59    //   if ((p) && (p == magicfree))
60    //     {
61    //   printf("CAUGHT!!!!! %p ...\n", p);
62    //   abort();
63    //     }
64    free(p);
65    __free_hook = my_free_hook;
66    }
67  */
68
69 /* local function prototypes */
70 static void      _e_main_shutdown(int errcode);
71 static void      _e_main_shutdown_push(int (*func)(void));
72 static void      _e_main_parse_arguments(int argc, char **argv);
73 static Eina_Bool _e_main_cb_signal_exit(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED);
74 static Eina_Bool _e_main_cb_signal_hup(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED);
75 static Eina_Bool _e_main_cb_signal_user(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev);
76 static int       _e_main_dirs_init(void);
77 static int       _e_main_dirs_shutdown(void);
78 static int       _e_main_path_init(void);
79 static int       _e_main_path_shutdown(void);
80 static void      _e_main_test_formats(void);
81 static int       _e_main_screens_init(void);
82 static int       _e_main_screens_shutdown(void);
83 static void      _e_main_desk_save(void);
84 static void      _e_main_desk_restore(void);
85 static void      _e_main_efreet_paths_init(void);
86 static void      _e_main_modules_load(Eina_Bool safe_mode);
87 static Eina_Bool _e_main_cb_idle_before(void *data EINA_UNUSED);
88 static Eina_Bool _e_main_cb_idle_after(void *data EINA_UNUSED);
89 static Eina_Bool _e_main_cb_startup_fake_end(void *data EINA_UNUSED);
90
91 /* local variables */
92 static Eina_Bool really_know = EINA_FALSE;
93 static Eina_Bool locked = EINA_FALSE;
94 static Eina_Bool inloop = EINA_FALSE;
95 static jmp_buf x_fatal_buff;
96
97 static int _e_main_lvl = 0;
98 static int(*_e_main_shutdown_func[MAX_LEVEL]) (void);
99
100 static Ecore_Idle_Enterer *_idle_before = NULL;
101 static Ecore_Idle_Enterer *_idle_after = NULL;
102
103 static Ecore_Event_Handler *mod_init_end = NULL;
104
105 /* external variables */
106 E_API Eina_Bool e_precache_end = EINA_FALSE;
107 E_API Eina_Bool x_fatal = EINA_FALSE;
108 E_API Eina_Bool good = EINA_FALSE;
109 E_API Eina_Bool evil = EINA_FALSE;
110 E_API Eina_Bool starting = EINA_TRUE;
111 E_API Eina_Bool stopping = EINA_FALSE;
112 E_API Eina_Bool restart = EINA_FALSE;
113 E_API Eina_Bool e_nopause = EINA_FALSE;
114 EINTERN const char *e_first_frame = NULL;
115 EINTERN double e_first_frame_start_time = -1;
116
117 static Eina_Bool
118 _xdg_check_str(const char *env, const char *str)
119 {
120    const char *p;
121    size_t len;
122
123    len = strlen(str);
124    for (p = strstr(env, str); p; p++, p = strstr(p, str))
125      {
126         if ((!p[len]) || (p[len] == ':')) return EINA_TRUE;
127      }
128    return EINA_FALSE;
129 }
130
131 static void
132 _xdg_data_dirs_augment(void)
133 {
134    const char *s;
135    const char *p = e_prefix_get();
136    char newpath[4096], buf[4096];
137
138    if (!p) return;
139
140    s = getenv("XDG_DATA_DIRS");
141    if (s)
142      {
143         Eina_Bool pfxdata, pfx;
144
145         pfxdata = !_xdg_check_str(s, e_prefix_data_get());
146         snprintf(newpath, sizeof(newpath), "%s/share", p);
147         pfx = !_xdg_check_str(s, newpath);
148         if (pfxdata || pfx)
149           {
150              snprintf(buf, sizeof(buf), "%s%s%s%s%s",
151                pfxdata ? e_prefix_data_get() : "",
152                pfxdata ? ":" : "",
153                pfx ? newpath : "",
154                pfx ? ":" : "",
155                s);
156              e_util_env_set("XDG_DATA_DIRS", buf);
157           }
158      }
159    else
160      {
161         snprintf(buf, sizeof(buf), "%s:%s/share:/usr/local/share:/usr/share", e_prefix_data_get(), p);
162         e_util_env_set("XDG_DATA_DIRS", buf);
163      }
164
165    s = getenv("XDG_CONFIG_DIRS");
166    snprintf(newpath, sizeof(newpath), "%s/etc/xdg", p);
167    if (s)
168      {
169         if (!_xdg_check_str(s, newpath))
170           {
171              snprintf(buf, sizeof(buf), "%s:%s", newpath, s);
172              e_util_env_set("XDG_CONFIG_DIRS", buf);
173           }
174      }
175    else
176      {
177         snprintf(buf, sizeof(buf), "%s:/etc/xdg", newpath);
178         e_util_env_set("XDG_CONFIG_DIRS", buf);
179      }
180
181    if (!getenv("XDG_RUNTIME_DIR"))
182      {
183         const char *dir;
184
185         snprintf(buf, sizeof(buf), "/tmp/xdg-XXXXXX");
186         dir = mkdtemp(buf);
187         if (!dir) dir = "/tmp";
188         else
189           {
190              e_util_env_set("XDG_RUNTIME_DIR", dir);
191              snprintf(buf, sizeof(buf), "%s/.e-deleteme", dir);
192              ecore_file_mkdir(buf);
193           }
194      }
195
196    /* set menu prefix so we get our e menu */
197    if (!getenv("XDG_MENU_PREFIX"))
198      {
199         e_util_env_set("XDG_MENU_PREFIX", "e-");
200      }
201 }
202
203 static Eina_Bool
204 _e_main_shelf_init_job(void *data EINA_UNUSED)
205 {
206    e_shelf_config_update();
207    return ECORE_CALLBACK_CANCEL;
208 }
209
210 /* externally accessible functions */
211 int
212 main(int argc, char **argv)
213 {
214    Eina_Bool nostartup = EINA_FALSE;
215    Eina_Bool safe_mode = EINA_FALSE;
216    Eina_Bool after_restart = EINA_FALSE;
217    Eina_Bool waslocked = EINA_FALSE;
218    double t = 0.0, tstart = 0.0;
219    char *s = NULL, buff[32];
220    struct sigaction action;
221
222 #ifdef __linux__
223 # ifdef PR_SET_PTRACER
224 #  ifdef PR_SET_PTRACER_ANY
225    prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY);
226 #  endif
227 # endif
228 #endif
229    
230 #ifdef TS_DO
231    t0 = t1 = t2 = ecore_time_unix_get();
232 #endif
233    TS("Begin Startup");
234
235    /* trap deadly bug signals and allow some form of sane recovery */
236    /* or ability to gdb attach and debug at this point - better than your */
237    /* wm/desktop vanishing and not knowing what happened */
238    if (!getenv("NOTIFY_SOCKET"))
239      {
240         TS("Signal Trap");
241         action.sa_sigaction = e_sigseg_act;
242         action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
243         sigemptyset(&action.sa_mask);
244         sigaction(SIGSEGV, &action, NULL);
245
246         action.sa_sigaction = e_sigill_act;
247         action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
248         sigemptyset(&action.sa_mask);
249         sigaction(SIGILL, &action, NULL);
250
251         action.sa_sigaction = e_sigfpe_act;
252         action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
253         sigemptyset(&action.sa_mask);
254         sigaction(SIGFPE, &action, NULL);
255
256 #ifndef HAVE_WAYLAND_ONLY
257         action.sa_sigaction = e_sigbus_act;
258         action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
259         sigemptyset(&action.sa_mask);
260         sigaction(SIGBUS, &action, NULL);
261 #endif
262
263         action.sa_sigaction = e_sigabrt_act;
264         action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
265         sigemptyset(&action.sa_mask);
266         sigaction(SIGABRT, &action, NULL);
267         TS("Signal Trap Done");
268      }
269
270    t = ecore_time_unix_get();
271    s = getenv("E_START_TIME");
272    if ((s) && (!getenv("E_RESTART_OK")))
273      {
274         tstart = atof(s);
275         if ((t - tstart) < 5.0) safe_mode = EINA_TRUE;
276      }
277    tstart = t;
278    snprintf(buff, sizeof(buff), "%1.1f", tstart);
279    e_util_env_set("E_START_TIME", buff);
280
281    if (getenv("E_START_MTRACK"))
282      e_util_env_set("MTRACK", NULL);
283    TS("Eina Init");
284    if (!eina_init())
285      {
286         e_error_message_show(_("Enlightenment cannot initialize Eina!\n"));
287         _e_main_shutdown(-1);
288      }
289    _e_main_shutdown_push(eina_shutdown);
290    if (!e_log_init())
291      {
292         e_error_message_show(_("Enlightenment could not create a logging domain!\n"));
293         _e_main_shutdown(-1);
294      }
295 #ifdef TS_DO
296 #undef TS
297 # define TS(x)                                                    \
298   {                                                               \
299      t1 = ecore_time_unix_get();                                  \
300      printf("ESTART: %1.5f [%1.5f] - %s\n", t1 - t0, t1 - t2, x); \
301      t2 = t1;                                                     \
302   }
303 #endif
304    TS("Eina Init Done");
305    _e_main_shutdown_push(e_log_shutdown);
306
307    TS("Determine Prefix");
308    if (!e_prefix_determine(argv[0]))
309      {
310         fprintf(stderr,
311                 "ERROR: Enlightenment cannot determine it's installed\n"
312                 "       prefix from the system or argv[0].\n"
313                 "       This is because it is not on Linux AND has been\n"
314                 "       executed strangely. This is unusual.\n");
315      }
316    TS("Determine Prefix Done");
317
318    /* for debugging by redirecting stdout of e to a log file to tail */
319    setvbuf(stdout, NULL, _IONBF, 0);
320
321    TS("Environment Variables");
322    if (getenv("E_RESTART")) after_restart = EINA_TRUE;
323    if (getenv("DESKTOP_STARTUP_ID"))
324      e_util_env_set("DESKTOP_STARTUP_ID", NULL);
325    e_util_env_set("E_RESTART_OK", NULL);
326    e_util_env_set("PANTS", "ON");
327    e_util_env_set("DESKTOP", "Enlightenment");
328    TS("Environment Variables Done");
329
330    TS("Parse Arguments");
331    _e_main_parse_arguments(argc, argv);
332    TS("Parse Arguments Done");
333
334    /*** Initialize Core EFL Libraries We Need ***/
335
336    TS("Eet Init");
337    if (!eet_init())
338      {
339         e_error_message_show(_("Enlightenment cannot initialize Eet!\n"));
340         _e_main_shutdown(-1);
341      }
342    TS("Eet Init Done");
343    _e_main_shutdown_push(eet_shutdown);
344
345    TS("Ecore Init");
346    if (!ecore_init())
347      {
348         e_error_message_show(_("Enlightenment cannot initialize Ecore!\n"));
349         _e_main_shutdown(-1);
350      }
351    TS("Ecore Init Done");
352    _e_main_shutdown_push(ecore_shutdown);
353
354    e_first_frame = getenv("E_FIRST_FRAME");
355    if (e_first_frame && (!e_first_frame[0]))
356      e_first_frame = NULL;
357    else
358      e_first_frame_start_time = ecore_time_get();
359
360    TS("EIO Init");
361    if (!eio_init())
362      {
363         e_error_message_show(_("Enlightenment cannot initialize EIO!\n"));
364         _e_main_shutdown(-1);
365      }
366    TS("EIO Init Done");
367    _e_main_shutdown_push(eio_shutdown);
368
369    ecore_app_args_set(argc, (const char **)argv);
370
371    TS("Ecore Event Handlers");
372    if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT,
373                                 _e_main_cb_signal_exit, NULL))
374      {
375         e_error_message_show(_("Enlightenment cannot set up an exit signal handler.\n"
376                                "Perhaps you are out of memory?"));
377         _e_main_shutdown(-1);
378      }
379    if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_HUP,
380                                 _e_main_cb_signal_hup, NULL))
381      {
382         e_error_message_show(_("Enlightenment cannot set up a HUP signal handler.\n"
383                                "Perhaps you are out of memory?"));
384         _e_main_shutdown(-1);
385      }
386    if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
387                                 _e_main_cb_signal_user, NULL))
388      {
389         e_error_message_show(_("Enlightenment cannot set up a USER signal handler.\n"
390                                "Perhaps you are out of memory?"));
391         _e_main_shutdown(-1);
392      }
393    TS("Ecore Event Handlers Done");
394
395    TS("Ecore_File Init");
396    if (!ecore_file_init())
397      {
398         e_error_message_show(_("Enlightenment cannot initialize Ecore_File!\n"));
399         _e_main_shutdown(-1);
400      }
401    TS("Ecore_File Init Done");
402    _e_main_shutdown_push(ecore_file_shutdown);
403
404    TS("Ecore_Con Init");
405    if (!ecore_con_init())
406      {
407         e_error_message_show(_("Enlightenment cannot initialize Ecore_Con!\n"));
408         _e_main_shutdown(-1);
409      }
410    TS("Ecore_Con Init Done");
411    _e_main_shutdown_push(ecore_con_shutdown);
412
413    TS("Ecore_Ipc Init");
414    if (!ecore_ipc_init())
415      {
416         e_error_message_show(_("Enlightenment cannot initialize Ecore_Ipc!\n"));
417         _e_main_shutdown(-1);
418      }
419    TS("Ecore_Ipc Init Done");
420    _e_main_shutdown_push(ecore_ipc_shutdown);
421
422    _idle_before = ecore_idle_enterer_before_add(_e_main_cb_idle_before, NULL);
423
424    _xdg_data_dirs_augment();
425
426    TS("Ecore_Evas Init");
427    if (!ecore_evas_init())
428      {
429         e_error_message_show(_("Enlightenment cannot initialize Ecore_Evas!\n"));
430         _e_main_shutdown(-1);
431      }
432    TS("Ecore_Evas Init Done");
433 //   _e_main_shutdown_push(ecore_evas_shutdown);
434
435    TS("Elementary Init");
436    if (!elm_init(argc, argv))
437      {
438         e_error_message_show(_("Enlightenment cannot initialize Elementary!\n"));
439         _e_main_shutdown(-1);
440      }
441    TS("Elementary Init Done");
442    //_e_main_shutdown_push(elm_shutdown);
443
444    TS("Emotion Init");
445    if (!emotion_init())
446      {
447         e_error_message_show(_("Enlightenment cannot initialize Emotion!\n"));
448         _e_main_shutdown(-1);
449      }
450    TS("Emotion Init Done");
451    _e_main_shutdown_push((void *)emotion_shutdown);
452
453    /* e doesn't sync to compositor - it should be one */
454    ecore_evas_app_comp_sync_set(0);
455
456    TS("Ecore_Evas Engine Check");
457 #ifdef HAVE_WAYLAND_ONLY
458    if (!ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_WAYLAND_SHM))
459      {
460         e_error_message_show(_("Enlightenment found ecore_evas doesn't support the Wayland SHM\n"
461                                "rendering in Evas. Please check your installation of Evas and\n"
462                                 "Ecore and check they support the Wayland SHM rendering engine."));
463         _e_main_shutdown(-1);
464      }
465 #else
466    if (!ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_SOFTWARE_XCB))
467      {
468         if (!ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_SOFTWARE_XLIB))
469           {
470              e_error_message_show(_("Enlightenment found ecore_evas doesn't support the Software X11\n"
471                                     "rendering in Evas. Please check your installation of Evas and\n"
472                                     "Ecore and check they support the Software X11 rendering engine."));
473              _e_main_shutdown(-1);
474           }
475      }
476 #endif
477    if (!ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_SOFTWARE_BUFFER))
478      {
479         e_error_message_show(_("Enlightenment found ecore_evas doesn't support the Software Buffer\n"
480                                "rendering in Evas. Please check your installation of Evas and\n"
481                                "Ecore and check they support the Software Buffer rendering engine."));
482         _e_main_shutdown(-1);
483      }
484    TS("Ecore_Evas Engine Check Done");
485
486    TS("Edje Init");
487    if (!edje_init())
488      {
489         e_error_message_show(_("Enlightenment cannot initialize Edje!\n"));
490         _e_main_shutdown(-1);
491      }
492    TS("Edje Init Done");
493    _e_main_shutdown_push(edje_shutdown);
494    edje_freeze();
495
496    /*** Initialize E Subsystems We Need ***/
497
498    TS("E Intl Init");
499    if (!e_intl_init())
500      {
501         e_error_message_show(_("Enlightenment cannot initialize E_Intl!\n"));
502         _e_main_shutdown(-1);
503      }
504    TS("E Intl Init Done");
505    _e_main_shutdown_push(e_intl_shutdown);
506
507 #ifndef HAVE_WAYLAND_ONLY
508    /* init white box of death alert */
509    TS("E_Alert Init");
510    if (!e_alert_init())
511      {
512         e_error_message_show(_("Enlightenment cannot initialize its emergency alert system.\n"
513                                "Have you set your DISPLAY variable?"));
514         _e_main_shutdown(-1);
515      }
516    TS("E_Alert Init Done");
517    _e_main_shutdown_push(e_alert_shutdown);
518 #endif
519
520    TS("E_Configure Init");
521    e_configure_init();
522    TS("E_Configure Init Done");
523
524    TS("E Directories Init");
525    /* setup directories we will be using for configurations storage etc. */
526    if (!_e_main_dirs_init())
527      {
528         e_error_message_show(_("Enlightenment cannot create directories in your home directory.\n"
529                                "Perhaps you have no home directory or the disk is full?"));
530         _e_main_shutdown(-1);
531      }
532    TS("E Directories Init Done");
533    _e_main_shutdown_push(_e_main_dirs_shutdown);
534
535    TS("E_Filereg Init");
536    if (!e_filereg_init())
537      {
538         e_error_message_show(_("Enlightenment cannot set up its file registry system.\n"));
539         _e_main_shutdown(-1);
540      }
541    TS("E_Filereg Init Done");
542    _e_main_shutdown_push(e_filereg_shutdown);
543
544    TS("E_Config Init");
545    if (!e_config_init())
546      {
547         e_error_message_show(_("Enlightenment cannot set up its config system.\n"));
548         _e_main_shutdown(-1);
549      }
550    TS("E_Config Init Done");
551    _e_main_shutdown_push(e_config_shutdown);
552
553    TS("E_Env Init");
554    if (!e_env_init())
555      {
556         e_error_message_show(_("Enlightenment cannot set up its environment.\n"));
557         _e_main_shutdown(-1);
558      }
559    TS("E_Env Init Done");
560    _e_main_shutdown_push(e_env_shutdown);
561
562    efreet_desktop_environment_set(e_config->desktop_environment);
563    e_util_env_set("E_ICON_THEME", e_config->icon_theme);
564    ecore_exe_run_priority_set(e_config->priority);
565    locked |= e_config->desklock_start_locked;
566
567    s = getenv("E_DESKLOCK_LOCKED");
568    if ((s) && (!strcmp(s, "locked"))) waslocked = EINA_TRUE;
569
570    TS("E Paths Init");
571    if (!_e_main_path_init())
572      {
573         e_error_message_show(_("Enlightenment cannot set up paths for finding files.\n"
574                                "Perhaps you are out of memory?"));
575         _e_main_shutdown(-1);
576      }
577    TS("E Paths Init Done");
578    _e_main_shutdown_push(_e_main_path_shutdown);
579
580    TS("E_Ipc Init");
581    if (!e_ipc_init()) _e_main_shutdown(-1);
582    TS("E_Ipc Init Done");
583    _e_main_shutdown_push(e_ipc_shutdown);
584
585    edje_frametime_set(1.0 / e_config->framerate);
586
587    TS("E_Font Init");
588    if (!e_font_init())
589      {
590         e_error_message_show(_("Enlightenment cannot set up its font system.\n"));
591         _e_main_shutdown(-1);
592      }
593    TS("E_Font Init Done");
594    _e_main_shutdown_push(e_font_shutdown);
595
596    TS("E_Font Apply");
597    e_font_apply();
598    TS("E_Font Apply Done");
599
600    TS("E_Theme Init");
601    if (!e_theme_init())
602      {
603         e_error_message_show(_("Enlightenment cannot set up its theme system.\n"));
604         _e_main_shutdown(-1);
605      }
606    TS("E_Theme Init Done");
607    _e_main_shutdown_push(e_theme_shutdown);
608
609    TS("E_Moveresize Init");
610    e_moveresize_init();
611    TS("E_Moveresize Init Done");
612    _e_main_shutdown_push(e_moveresize_shutdown);
613
614    if (e_config->show_splash)
615      e_init_status_set(_("Setup Message Bus"));
616    TS("E_Msgbus Init");
617    if (e_msgbus_init())
618      _e_main_shutdown_push(e_msgbus_shutdown);
619    TS("E_Msgbus Init Done");
620
621    TS("Efreet Init");
622    if (!efreet_init())
623      {
624         e_error_message_show(_("Enlightenment cannot initialize the FDO desktop system.\n"
625                                "Perhaps you lack permissions on ~/.cache/efreet or are\n"
626                                "out of memory or disk space?"));
627         _e_main_shutdown(-1);
628      }
629    TS("Efreet Init Done");
630    _e_main_shutdown_push(efreet_shutdown);
631
632    if (e_config->show_splash)
633      e_init_status_set(_("Starting International Support"));
634    TS("E_Intl Post Init");
635    if (!e_intl_post_init())
636      {
637         e_error_message_show(_("Enlightenment cannot set up its intl system.\n"));
638         _e_main_shutdown(-1);
639      }
640    TS("E_Intl Post Init Done");
641    _e_main_shutdown_push(e_intl_post_shutdown);
642
643    e_screensaver_preinit();
644
645    if (e_config->show_splash)
646      e_init_status_set(_("Setup Actions"));
647    TS("E_Actions Init");
648    if (!e_actions_init())
649      {
650         e_error_message_show(_("Enlightenment cannot set up its actions system.\n"));
651         _e_main_shutdown(-1);
652      }
653    TS("E_Actions Init Done");
654    _e_main_shutdown_push(e_actions_shutdown);
655
656    /* these just add event handlers and can't fail
657     * timestamping them is dumb.
658     */
659    e_zone_init();
660    e_desk_init();
661    e_exehist_init();
662
663    if (e_config->show_splash)
664      e_init_status_set(_("Setup Powersave Modes"));
665    TS("E_Powersave Init");
666    if (!e_powersave_init())
667      {
668         e_error_message_show(_("Enlightenment cannot set up its powersave modes.\n"));
669         _e_main_shutdown(-1);
670      }
671    TS("E_Powersave Init Done");
672    _e_main_shutdown_push(e_powersave_shutdown);
673
674    if (e_config->show_splash)
675      e_init_status_set(_("Setup Screensaver"));
676    TS("E_Screensaver Init");
677    if (!e_screensaver_init())
678      {
679         e_error_message_show(_("Enlightenment cannot configure the X screensaver.\n"));
680         _e_main_shutdown(-1);
681      }
682    TS("E_Screensaver Init Done");
683    _e_main_shutdown_push(e_screensaver_shutdown);
684
685    if (e_config->show_splash)
686      e_init_status_set(_("Setup Screens"));
687    TS("Screens Init");
688    if (!_e_main_screens_init())
689      {
690         e_error_message_show(_("Enlightenment set up window management for all the screens on your system\n"
691                                "failed. Perhaps another window manager is running?\n"));
692         _e_main_shutdown(-1);
693      }
694    TS("Screens Init Done");
695    _e_main_shutdown_push(_e_main_screens_shutdown);
696    e_screensaver_force_update();
697
698    TS("E_Pointer Init");
699    if (!e_pointer_init())
700      {
701         e_error_message_show(_("Enlightenment cannot set up its pointer system.\n"));
702         _e_main_shutdown(-1);
703      }
704    TS("E_Pointer Init Done");
705    _e_main_shutdown_push(e_pointer_shutdown);
706    e_menu_init();
707
708    TS("E_Scale Init");
709    if (!e_scale_init())
710      {
711         e_error_message_show(_("Enlightenment cannot set up its scale system.\n"));
712         _e_main_shutdown(-1);
713      }
714    TS("E_Scale Init Done");
715    _e_main_shutdown_push(e_scale_shutdown);
716
717    if (e_config->show_splash)
718      {
719         TS("E_Splash Init");
720         if (!e_init_init())
721           {
722              e_error_message_show(_("Enlightenment cannot set up its init screen.\n"));
723              _e_main_shutdown(-1);
724           }
725         TS("E_Splash Init Done");
726         _e_main_shutdown_push(e_init_shutdown);
727      }
728    if (!((!e_config->show_splash) || (after_restart)))
729      e_init_show();
730
731    if (!really_know)
732      {
733         TS("Test File Format Support");
734         _e_main_test_formats();
735         TS("Test File Format Support Done");
736      }
737    else
738      {
739         efreet_icon_extension_add(".svg");
740         efreet_icon_extension_add(".jpg");
741         efreet_icon_extension_add(".png");
742         efreet_icon_extension_add(".edj");
743      }
744
745    if (e_config->show_splash)
746      e_init_status_set(_("Setup ACPI"));
747    TS("E_Acpi Init");
748    e_acpi_init();
749    TS("E_Acpi Init Done");
750    _e_main_shutdown_push(e_acpi_shutdown);
751
752    if (e_config->show_splash)
753      e_init_status_set(_("Setup Backlight"));
754    TS("E_Backlight Init");
755    if (!e_backlight_init())
756      {
757         e_error_message_show(_("Enlightenment cannot configure the backlight.\n"));
758         _e_main_shutdown(-1);
759      }
760    TS("E_Backlight Init Done");
761
762    if (e_config->show_splash)
763      e_init_status_set(_("Setup DPMS"));
764    TS("E_Dpms Init");
765    if (!e_dpms_init())
766      {
767         e_error_message_show(_("Enlightenment cannot configure the DPMS settings.\n"));
768         _e_main_shutdown(-1);
769      }
770    TS("E_Dpms Init Done");
771    _e_main_shutdown_push(e_dpms_shutdown);
772
773    if (e_config->show_splash)
774      e_init_status_set(_("Setup Desklock"));
775    TS("E_Desklock Init");
776    if (!e_desklock_init())
777      {
778         e_error_message_show(_("Enlightenment cannot set up its desk locking system.\n"));
779         _e_main_shutdown(-1);
780      }
781    TS("E_Desklock Init Done");
782    _e_main_shutdown_push(e_desklock_shutdown);
783
784    if (waslocked || (locked && ((!after_restart) || (!getenv("E_DESKLOCK_UNLOCKED")))))
785      e_desklock_show(EINA_TRUE);
786
787    if (e_config->show_splash)
788      e_init_status_set(_("Setup Paths"));
789    TS("Efreet Paths");
790    _e_main_efreet_paths_init();
791    TS("Efreet Paths Done");
792
793    if (e_config->show_splash)
794      e_init_status_set(_("Setup System Controls"));
795    TS("E_Sys Init");
796    if (!e_sys_init())
797      {
798         e_error_message_show(_("Enlightenment cannot initialize the System Command system.\n"));
799         _e_main_shutdown(-1);
800      }
801    TS("E_Sys Init Done");
802    _e_main_shutdown_push(e_sys_shutdown);
803
804    if (e_config->show_splash)
805      e_init_status_set(_("Setup Execution System"));
806    TS("E_Exec Init");
807    if (!e_exec_init())
808      {
809         e_error_message_show(_("Enlightenment cannot set up its exec system.\n"));
810         _e_main_shutdown(-1);
811      }
812    TS("E_Exec Init Done");
813
814    TS("E_Comp Freeze");
815    e_comp_all_freeze();
816    TS("E_Comp Freeze Done");
817
818    if (e_config->show_splash)
819      e_init_status_set(_("Setup Filemanager"));
820    TS("E_Fm2 Init");
821    if (!e_fm2_init())
822      {
823         e_error_message_show(_("Enlightenment cannot initialize the File manager.\n"));
824         _e_main_shutdown(-1);
825      }
826    TS("E_Fm2 Init Done");
827    _e_main_shutdown_push(e_fm2_shutdown);
828
829    if (e_config->show_splash)
830      e_init_status_set(_("Setup Message System"));
831    TS("E_Msg Init");
832    if (!e_msg_init())
833      {
834         e_error_message_show(_("Enlightenment cannot set up its msg system.\n"));
835         _e_main_shutdown(-1);
836      }
837    TS("E_Msg Init Done");
838    _e_main_shutdown_push(e_msg_shutdown);
839
840    if (e_config->show_splash)
841      e_init_status_set(_("Setup Grab Input Handling"));
842    TS("E_Grabinput Init");
843    if (!e_grabinput_init())
844      {
845         e_error_message_show(_("Enlightenment cannot set up its grab input handling system.\n"));
846         _e_main_shutdown(-1);
847      }
848    TS("E_Grabinput Init Done");
849    _e_main_shutdown_push(e_grabinput_shutdown);
850
851    if (e_config->show_splash)
852      e_init_status_set(_("Setup Modules"));
853    TS("E_Module Init");
854    if (!e_module_init())
855      {
856         e_error_message_show(_("Enlightenment cannot set up its module system.\n"));
857         _e_main_shutdown(-1);
858      }
859    TS("E_Module Init Done");
860    _e_main_shutdown_push(e_module_shutdown);
861
862    if (e_config->show_splash)
863      e_init_status_set(_("Setup Remembers"));
864    TS("E_Remember Init");
865    if (!e_remember_init(after_restart ? E_STARTUP_RESTART : E_STARTUP_START))
866      {
867         e_error_message_show(_("Enlightenment cannot setup remember settings.\n"));
868         _e_main_shutdown(-1);
869      }
870    TS("E_Remember Init Done");
871    _e_main_shutdown_push(e_remember_shutdown);
872
873    if (e_config->show_splash)
874      e_init_status_set(_("Setup Gadcon"));
875    TS("E_Gadcon Init");
876    if (!e_gadcon_init())
877      {
878         e_error_message_show(_("Enlightenment cannot set up its gadget control system.\n"));
879         _e_main_shutdown(-1);
880      }
881    TS("E_Gadcon Init Done");
882    _e_main_shutdown_push(e_gadcon_shutdown);
883
884    if (e_config->show_splash)
885      e_init_status_set(_("Setup Toolbars"));
886    TS("E_Toolbar Init");
887    if (!e_toolbar_init())
888      {
889         e_error_message_show(_("Enlightenment cannot set up its toolbars.\n"));
890         _e_main_shutdown(-1);
891      }
892    TS("E_Toolbar Init Done");
893    _e_main_shutdown_push(e_toolbar_shutdown);
894
895    if (e_config->show_splash)
896      e_init_status_set(_("Setup Wallpaper"));
897    TS("E_Bg Init");
898    if (!e_bg_init())
899      {
900         e_error_message_show(_("Enlightenment cannot set up its desktop background system.\n"));
901         _e_main_shutdown(-1);
902      }
903    TS("E_Bg Init Done");
904    _e_main_shutdown_push(e_bg_shutdown);
905
906    if (e_config->show_splash)
907      e_init_status_set(_("Setup Mouse"));
908    TS("E_Mouse Init");
909    if (!e_mouse_update())
910      {
911         e_error_message_show(_("Enlightenment cannot configure the mouse settings.\n"));
912         _e_main_shutdown(-1);
913      }
914    TS("E_Mouse Init Done");
915
916    if (e_config->show_splash)
917      e_init_status_set(_("Setup Bindings"));
918    TS("E_Bindings Init");
919    if (!e_bindings_init())
920      {
921         e_error_message_show(_("Enlightenment cannot set up its bindings system.\n"));
922         _e_main_shutdown(-1);
923      }
924    TS("E_Bindings Init Done");
925    _e_main_shutdown_push(e_bindings_shutdown);
926
927    if (e_config->show_splash)
928      e_init_status_set(_("Setup Thumbnailer"));
929    TS("E_Thumb Init");
930    if (!e_thumb_init())
931      {
932         e_error_message_show(_("Enlightenment cannot initialize the Thumbnailing system.\n"));
933         _e_main_shutdown(-1);
934      }
935    TS("E_Thumb Init Done");
936    _e_main_shutdown_push(e_thumb_shutdown);
937
938    TS("E_Icon Init");
939    if (!e_icon_init())
940      {
941         e_error_message_show(_("Enlightenment cannot initialize the Icon Cache system.\n"));
942         _e_main_shutdown(-1);
943      }
944    TS("E_Icon Init Done");
945    _e_main_shutdown_push(e_icon_shutdown);
946
947    TS("E_Update Init");
948    if (!e_update_init())
949      {
950         e_error_message_show(_("Enlightenment cannot initialize the Update system.\n"));
951         _e_main_shutdown(-1);
952      }
953    TS("E_Update Init Done");
954    _e_main_shutdown_push(e_update_shutdown);
955
956    if (e_config->show_splash)
957      e_init_status_set(_("Setup Desktop Environment"));
958    TS("E_Deskenv Init");
959    if (!e_deskenv_init())
960      {
961         e_error_message_show(_("Enlightenment cannot initialize its desktop environment.\n"));
962         _e_main_shutdown(-1);
963      }
964    TS("E_Deskenv Init Done");
965    _e_main_shutdown_push(e_deskenv_shutdown);
966
967    if (e_config->show_splash)
968      e_init_status_set(_("Setup File Ordering"));
969    TS("E_Order Init");
970    if (!e_order_init())
971      {
972         e_error_message_show(_("Enlightenment cannot set up its order file system.\n"));
973         _e_main_shutdown(-1);
974      }
975    TS("E_Order Init Done");
976    _e_main_shutdown_push(e_order_shutdown);
977
978    TS("E_Comp_Canvas Keys Grab");
979    e_comp_canvas_keys_grab();
980    TS("E_Comp_Canvas Keys Grab Done");
981
982    if (e_config->show_splash)
983      e_init_status_set(_("Load Modules"));
984    TS("Load Modules");
985    _e_main_modules_load(safe_mode);
986    TS("Load Modules Done");
987
988    TS("Run Startup Apps");
989    if (!nostartup)
990      {
991         if (after_restart)
992           e_startup(E_STARTUP_RESTART);
993         else
994           e_startup(E_STARTUP_START);
995      }
996    TS("Run Startup Apps Done");
997
998    if (e_config->show_splash && (!after_restart))
999      ecore_timer_add(2.0, _e_main_cb_startup_fake_end, NULL);
1000
1001    TS("E_Comp Thaw");
1002    e_comp_all_thaw();
1003    TS("E_Comp Thaw Done");
1004
1005    TS("E_Test Init");
1006    e_test();
1007    TS("E_Test Done");
1008
1009    if (e_config->show_splash)
1010      e_init_status_set(_("Setup Shelves"));
1011    TS("E_Shelf Init");
1012    if (!e_shelf_init())
1013      {
1014         e_error_message_show(_("Enlightenment cannot set up its module system.\n"));
1015         _e_main_shutdown(-1);
1016      }
1017    TS("E_Shelf Init Done");
1018
1019    ecore_idle_enterer_before_add(_e_main_shelf_init_job, NULL);
1020
1021    _idle_after = ecore_idle_enterer_add(_e_main_cb_idle_after, NULL);
1022
1023    if (e_config->show_splash)
1024      e_init_status_set(_("Almost Done"));
1025
1026    starting = EINA_FALSE;
1027    inloop = EINA_TRUE;
1028
1029    e_util_env_set("E_RESTART", "1");
1030
1031    TS("MAIN LOOP AT LAST");
1032    if (!setjmp(x_fatal_buff))
1033      ecore_main_loop_begin();
1034    else
1035      CRI("FATAL: X Died. Connection gone. Abbreviated Shutdown\n");
1036
1037    inloop = EINA_FALSE;
1038    stopping = EINA_TRUE;
1039
1040    //if (!x_fatal) e_canvas_idle_flush();
1041
1042    e_config_save_flush();
1043    _e_main_desk_save();
1044    e_remember_internal_save();
1045    e_comp_internal_save();
1046
1047    _e_main_shutdown(0);
1048
1049    if (restart)
1050      {
1051         e_util_env_set("E_RESTART_OK", "1");
1052         if (getenv("E_START_MTRACK"))
1053           e_util_env_set("MTRACK", "track");
1054         ecore_app_restart();
1055      }
1056
1057    e_prefix_shutdown();
1058
1059    return 0;
1060 }
1061
1062 E_API double
1063 e_main_ts(const char *str)
1064 {
1065    double ret;
1066    t1 = ecore_time_unix_get();
1067    printf("ESTART: %1.5f [%1.5f] - %s\n", t1 - t0, t1 - t2, str);
1068    ret = t1 - t2;
1069    t2 = t1;
1070    return ret;
1071 }
1072
1073 /* local functions */
1074 static void
1075 _e_main_shutdown(int errcode)
1076 {
1077    int i = 0;
1078    char buf[PATH_MAX];
1079    const char *dir;
1080
1081    printf("E: Begin Shutdown Procedure!\n");
1082
1083    if (_idle_before) ecore_idle_enterer_del(_idle_before);
1084    _idle_before = NULL;
1085    if (_idle_after) ecore_idle_enterer_del(_idle_after);
1086    _idle_after = NULL;
1087
1088    dir = getenv("XDG_RUNTIME_DIR");
1089    if (dir)
1090      {
1091         snprintf(buf, sizeof(buf), "%s/.e-deleteme", dir);
1092         if (ecore_file_exists(buf)) ecore_file_recursive_rm(dir);
1093      }
1094    for (i = (_e_main_lvl - 1); i >= 0; i--)
1095      (*_e_main_shutdown_func[i])();
1096    if (errcode < 0) exit(errcode);
1097 }
1098
1099 static void
1100 _e_main_shutdown_push(int (*func)(void))
1101 {
1102    _e_main_lvl++;
1103    if (_e_main_lvl > MAX_LEVEL)
1104      {
1105         _e_main_lvl--;
1106         e_error_message_show("WARNING: too many init levels. MAX = %i\n",
1107                              MAX_LEVEL);
1108         return;
1109      }
1110    _e_main_shutdown_func[_e_main_lvl - 1] = func;
1111 }
1112
1113 static void
1114 _e_main_parse_arguments(int argc, char **argv)
1115 {
1116    char *s = NULL;
1117    int i = 0;
1118
1119    /* handle some command-line parameters */
1120    for (i = 1; i < argc; i++)
1121      {
1122         if ((!strcmp(argv[i], "-display")) && (i < (argc - 1)))
1123           {
1124              i++;
1125              e_util_env_set("DISPLAY", argv[i]);
1126           }
1127         else if ((!strcmp(argv[i], "-fake-xinerama-screen")) && (i < (argc - 1)))
1128           {
1129              int x, y, w, h;
1130
1131              i++;
1132              if (sscanf(argv[i], "%ix%i+%i+%i", &w, &h, &x, &y) == 4)
1133                e_xinerama_fake_screen_add(x, y, w, h);
1134           }
1135         else if (!strcmp(argv[i], "-good"))
1136           {
1137              good = EINA_TRUE;
1138              evil = EINA_FALSE;
1139              printf("LA LA LA\n");
1140           }
1141         else if (!strcmp(argv[i], "-evil"))
1142           {
1143              good = EINA_FALSE;
1144              evil = EINA_TRUE;
1145              printf("MUHAHAHAHHAHAHAHAHA\n");
1146           }
1147         else if (!strcmp(argv[i], "-psychotic"))
1148           {
1149              good = EINA_TRUE;
1150              evil = EINA_TRUE;
1151              printf("MUHAHALALALALALALALA\n");
1152           }
1153         else if ((!strcmp(argv[i], "-profile")) && (i < (argc - 1)))
1154           {
1155              i++;
1156              if (!getenv("E_CONF_PROFILE"))
1157                e_util_env_set("E_CONF_PROFILE", argv[i]);
1158           }
1159         else if (!strcmp(argv[i], "-i-really-know-what-i-am-doing-and-accept-full-responsibility-for-it"))
1160           really_know = EINA_TRUE;
1161         else if (!strcmp(argv[i], "-locked"))
1162           locked = EINA_TRUE;
1163         else if (!strcmp(argv[i], "-nopause"))
1164           e_nopause = EINA_TRUE;
1165         else if ((!strcmp(argv[i], "-version")) ||
1166                  (!strcmp(argv[i], "--version")))
1167           {
1168              printf(_("Version: %s\n"), PACKAGE_VERSION);
1169              _e_main_shutdown(-1);
1170           }
1171         else if ((!strcmp(argv[i], "-h")) ||
1172                  (!strcmp(argv[i], "-help")) ||
1173                  (!strcmp(argv[i], "--help")))
1174           {
1175              printf
1176                (_(
1177                  "Options:\n"
1178                  "\t-display DISPLAY\n"
1179                  "\t\tConnect to display named DISPLAY.\n"
1180                  "\t\tEG: -display :1.0\n"
1181                  "\t-fake-xinerama-screen WxH+X+Y\n"
1182                  "\t\tAdd a FAKE xinerama screen (instead of the real ones)\n"
1183                  "\t\tgiven the geometry. Add as many as you like. They all\n"
1184                  "\t\treplace the real xinerama screens, if any. This can\n"
1185                  "\t\tbe used to simulate xinerama.\n"
1186                  "\t\tEG: -fake-xinerama-screen 800x600+0+0 -fake-xinerama-screen 800x600+800+0\n"
1187                  "\t-profile CONF_PROFILE\n"
1188                  "\t\tUse the configuration profile CONF_PROFILE instead of the user selected default or just \"default\".\n"
1189                  "\t-good\n"
1190                  "\t\tBe good.\n"
1191                  "\t-evil\n"
1192                  "\t\tBe evil.\n"
1193                  "\t-psychotic\n"
1194                  "\t\tBe psychotic.\n"
1195                  "\t-locked\n"
1196                  "\t\tStart with desklock on, so password will be asked.\n"
1197                  "\t-i-really-know-what-i-am-doing-and-accept-full-responsibility-for-it\n"
1198                  "\t\tIf you need this help, you don't need this option.\n"
1199                  "\t-version\n"
1200                  )
1201                );
1202              _e_main_shutdown(-1);
1203           }
1204      }
1205
1206    /* fix up DISPLAY to be :N.0 if no .screen is in it */
1207    s = getenv("DISPLAY");
1208    if (s)
1209      {
1210         char *p, buff[4096];
1211
1212         if (!(p = strrchr(s, ':')))
1213           {
1214              snprintf(buff, sizeof(buff), "%s:0.0", s);
1215              e_util_env_set("DISPLAY", buff);
1216           }
1217         else
1218           {
1219              if (!strrchr(p, '.'))
1220                {
1221                   snprintf(buff, sizeof(buff), "%s.0", s);
1222                   e_util_env_set("DISPLAY", buff);
1223                }
1224           }
1225      }
1226
1227    /* we want to have been launched by enlightenment_start. there is a very */
1228    /* good reason we want to have been launched this way, thus check */
1229    if (!getenv("E_START"))
1230      {
1231         e_error_message_show(_("You are executing enlightenment directly. This is\n"
1232                                "bad. Please do not execute the \"enlightenment\"\n"
1233                                "binary. Use the \"enlightenment_start\" launcher. It\n"
1234                                "will handle setting up environment variables, paths,\n"
1235                                "and launching any other required services etc.\n"
1236                                "before enlightenment itself begins running.\n"));
1237         _e_main_shutdown(-1);
1238      }
1239 }
1240
1241 EINTERN void
1242 _e_main_cb_x_fatal(void *data EINA_UNUSED)
1243 {
1244    e_error_message_show("Lost X Connection.\n");
1245    ecore_main_loop_quit();
1246    if (!x_fatal)
1247      {
1248         x_fatal = EINA_TRUE;
1249         if (inloop) longjmp(x_fatal_buff, -99);
1250      }
1251 }
1252
1253 static Eina_Bool
1254 _e_main_cb_signal_exit(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
1255 {
1256    /* called on ctrl-c, kill (pid) (also SIGINT, SIGTERM and SIGQIT) */
1257    e_sys_action_do(E_SYS_EXIT, NULL);
1258    return ECORE_CALLBACK_RENEW;
1259 }
1260
1261 static Eina_Bool
1262 _e_main_cb_signal_hup(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
1263 {
1264    e_sys_action_do(E_SYS_RESTART, NULL);
1265    return ECORE_CALLBACK_RENEW;
1266 }
1267
1268 static Eina_Bool
1269 _e_main_cb_signal_user(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev)
1270 {
1271    Ecore_Event_Signal_User *e = ev;
1272
1273    if (e->number == 1)
1274      {
1275 //        E_Action *a = e_action_find("configuration");
1276 //        if ((a) && (a->func.go)) a->func.go(NULL, NULL);
1277      }
1278    else if (e->number == 2)
1279      {
1280         // comp module has its own handler for this for enabling/disabling fps debug
1281      }
1282    return ECORE_CALLBACK_RENEW;
1283
1284 }
1285
1286 static int
1287 _e_main_dirs_init(void)
1288 {
1289    const char *base;
1290    const char *dirs[] =
1291    {
1292       "images",
1293       "fonts",
1294       "themes",
1295       "icons",
1296       "backgrounds",
1297       "applications",
1298       "applications/menu",
1299       "applications/menu/favorite",
1300       "applications/menu/all",
1301       "applications/bar",
1302       "applications/bar/default",
1303       "applications/startup",
1304       "applications/restart",
1305       "applications/trash",
1306       "applications/desk-lock",
1307       "applications/desk-unlock",
1308       "modules",
1309       "config",
1310       "locale",
1311       "input_methods",
1312       NULL
1313    };
1314
1315    base = e_user_dir_get();
1316    if (ecore_file_mksubdirs(base, dirs) != sizeof(dirs) / sizeof(dirs[0]) - 1)
1317      {
1318         e_error_message_show("Could not create one of the required "
1319                              "subdirectories of '%s'\n", base);
1320         return 0;
1321      }
1322
1323    return 1;
1324 }
1325
1326 static int
1327 _e_main_dirs_shutdown(void)
1328 {
1329    return 1;
1330 }
1331
1332 static int
1333 _e_main_path_init(void)
1334 {
1335    char buf[PATH_MAX];
1336
1337    /* setup data paths */
1338    path_data = e_path_new();
1339    if (!path_data)
1340      {
1341         e_error_message_show("Cannot allocate path for path_data\n");
1342         return 0;
1343      }
1344    e_prefix_data_concat_static(buf, "data");
1345    e_path_default_path_append(path_data, buf);
1346    e_path_user_path_set(path_data, &(e_config->path_append_data));
1347
1348    /* setup image paths */
1349    path_images = e_path_new();
1350    if (!path_images)
1351      {
1352         e_error_message_show("Cannot allocate path for path_images\n");
1353         return 0;
1354      }
1355    e_user_dir_concat_static(buf, "/images");
1356    e_path_default_path_append(path_images, buf);
1357    e_prefix_data_concat_static(buf, "data/images");
1358    e_path_default_path_append(path_images, buf);
1359    e_path_user_path_set(path_images, &(e_config->path_append_images));
1360
1361    /* setup font paths */
1362    path_fonts = e_path_new();
1363    if (!path_fonts)
1364      {
1365         e_error_message_show("Cannot allocate path for path_fonts\n");
1366         return 0;
1367      }
1368    e_user_dir_concat_static(buf, "/fonts");
1369    e_path_default_path_append(path_fonts, buf);
1370    e_prefix_data_concat_static(buf, "data/fonts");
1371    e_path_default_path_append(path_fonts, buf);
1372    e_path_user_path_set(path_fonts, &(e_config->path_append_fonts));
1373
1374    /* setup icon paths */
1375    path_icons = e_path_new();
1376    if (!path_icons)
1377      {
1378         e_error_message_show("Cannot allocate path for path_icons\n");
1379         return 0;
1380      }
1381    e_user_dir_concat_static(buf, "/icons");
1382    e_path_default_path_append(path_icons, buf);
1383    e_prefix_data_concat_static(buf, "data/icons");
1384    e_path_default_path_append(path_icons, buf);
1385    e_path_user_path_set(path_icons, &(e_config->path_append_icons));
1386
1387    /* setup module paths */
1388    path_modules = e_path_new();
1389    if (!path_modules)
1390      {
1391         e_error_message_show("Cannot allocate path for path_modules\n");
1392         return 0;
1393      }
1394    e_user_dir_concat_static(buf, "/modules");
1395    e_path_default_path_append(path_modules, buf);
1396    snprintf(buf, sizeof(buf), "%s/enlightenment/modules", e_prefix_lib_get());
1397    e_path_default_path_append(path_modules, buf);
1398    /* FIXME: eventually this has to go - moduels should have installers that
1399     * add appropriate install paths (if not installed to user homedir) to
1400     * e's module search dirs
1401     */
1402    snprintf(buf, sizeof(buf), "%s/enlightenment/modules_extra", e_prefix_lib_get());
1403    e_path_default_path_append(path_modules, buf);
1404    e_path_user_path_set(path_modules, &(e_config->path_append_modules));
1405
1406    /* setup background paths */
1407    path_backgrounds = e_path_new();
1408    if (!path_backgrounds)
1409      {
1410         e_error_message_show("Cannot allocate path for path_backgrounds\n");
1411         return 0;
1412      }
1413    e_user_dir_concat_static(buf, "/backgrounds");
1414    e_path_default_path_append(path_backgrounds, buf);
1415    e_prefix_data_concat_static(buf, "data/backgrounds");
1416    e_path_default_path_append(path_backgrounds, buf);
1417    e_path_user_path_set(path_backgrounds, &(e_config->path_append_backgrounds));
1418
1419    path_messages = e_path_new();
1420    if (!path_messages)
1421      {
1422         e_error_message_show("Cannot allocate path for path_messages\n");
1423         return 0;
1424      }
1425    e_user_dir_concat_static(buf, "/locale");
1426    e_path_default_path_append(path_messages, buf);
1427    e_path_default_path_append(path_messages, e_prefix_locale_get());
1428    e_path_user_path_set(path_messages, &(e_config->path_append_messages));
1429
1430    return 1;
1431 }
1432
1433 static int
1434 _e_main_path_shutdown(void)
1435 {
1436    if (path_data)
1437      {
1438         e_object_del(E_OBJECT(path_data));
1439         path_data = NULL;
1440      }
1441    if (path_images)
1442      {
1443         e_object_del(E_OBJECT(path_images));
1444         path_images = NULL;
1445      }
1446    if (path_fonts)
1447      {
1448         e_object_del(E_OBJECT(path_fonts));
1449         path_fonts = NULL;
1450      }
1451    if (path_icons)
1452      {
1453         e_object_del(E_OBJECT(path_icons));
1454         path_icons = NULL;
1455      }
1456    if (path_modules)
1457      {
1458         e_object_del(E_OBJECT(path_modules));
1459         path_modules = NULL;
1460      }
1461    if (path_backgrounds)
1462      {
1463         e_object_del(E_OBJECT(path_backgrounds));
1464         path_backgrounds = NULL;
1465      }
1466    if (path_messages)
1467      {
1468         e_object_del(E_OBJECT(path_messages));
1469         path_messages = NULL;
1470      }
1471    return 1;
1472 }
1473
1474 static void
1475 _e_main_test_formats(void)
1476 {
1477    Evas *evas;
1478    Ecore_Evas *ee;
1479    Evas_Object *im, *txt;
1480    Evas_Coord tw, th;
1481    char buff[PATH_MAX];
1482
1483    if (e_config->show_splash)
1484      e_init_status_set(_("Testing Format Support"));
1485
1486    if (!(ee = ecore_evas_buffer_new(1, 1)))
1487      {
1488         e_error_message_show(_("Enlightenment found Evas can't create a buffer canvas. Please check\n"
1489                                "Evas has Software Buffer engine support.\n"));
1490         _e_main_shutdown(-1);
1491      }
1492    evas = ecore_evas_get(ee);
1493    im = evas_object_image_add(evas);
1494
1495    e_prefix_data_concat_static(buff, "data/images/test.svg");
1496    evas_object_image_file_set(im, buff, NULL);
1497    if (evas_object_image_load_error_get(im) != EVAS_LOAD_ERROR_NONE)
1498      {
1499         e_error_message_show(_("Enlightenment found Evas can't load SVG files. "
1500                                "Check Evas has SVG loader support.\n"));
1501      }
1502    else
1503      efreet_icon_extension_add(".svg");
1504
1505    e_prefix_data_concat_static(buff, "data/images/test.jpg");
1506    evas_object_image_file_set(im, buff, NULL);
1507    if (evas_object_image_load_error_get(im) != EVAS_LOAD_ERROR_NONE)
1508      {
1509         e_error_message_show(_("Enlightenment found Evas can't load JPEG files. "
1510                                "Check Evas has JPEG loader support.\n"));
1511         _e_main_shutdown(-1);
1512      }
1513    efreet_icon_extension_add(".jpg");
1514
1515    e_prefix_data_concat_static(buff, "data/images/test.png");
1516    evas_object_image_file_set(im, buff, NULL);
1517    if (evas_object_image_load_error_get(im) != EVAS_LOAD_ERROR_NONE)
1518      {
1519         e_error_message_show(_("Enlightenment found Evas can't load PNG files. "
1520                                "Check Evas has PNG loader support.\n"));
1521         _e_main_shutdown(-1);
1522      }
1523    efreet_icon_extension_add(".png");
1524
1525    e_prefix_data_concat_static(buff, "data/images/test.edj");
1526    evas_object_image_file_set(im, buff, "images/0");
1527    if (evas_object_image_load_error_get(im) != EVAS_LOAD_ERROR_NONE)
1528      {
1529         e_error_message_show(_("Enlightenment found Evas can't load EET files. "
1530                                "Check Evas has EET loader support.\n"));
1531         _e_main_shutdown(-1);
1532      }
1533    efreet_icon_extension_add(".edj");
1534
1535    evas_object_del(im);
1536
1537    txt = evas_object_text_add(evas);
1538    evas_object_text_font_set(txt, "Sans", 10);
1539    evas_object_text_text_set(txt, "Hello");
1540    evas_object_geometry_get(txt, NULL, NULL, &tw, &th);
1541    if ((tw <= 0) && (th <= 0))
1542      {
1543         e_error_message_show(_("Enlightenment found Evas can't load the 'Sans' font. Check Evas has fontconfig\n"
1544                                "support and system fontconfig defines a 'Sans' font.\n"));
1545         _e_main_shutdown(-1);
1546      }
1547    evas_object_del(txt);
1548    ecore_evas_free(ee);
1549 }
1550
1551 static int
1552 _e_main_screens_init(void)
1553 {
1554    TS("\tscreens: client");
1555    if (!e_client_init()) return 0;
1556    TS("\tscreens: win");
1557    if (!e_win_init()) return 0;
1558 #ifndef HAVE_WAYLAND_ONLY
1559    TS("E_Xkb Init");
1560    if (!e_xkb_init())
1561      {
1562         e_error_message_show(_("Enlightenment cannot setup XKB Keyboard layouts.\n"));
1563         _e_main_shutdown(-1);
1564      }
1565    TS("E_Xkb Init Done");
1566 #endif
1567
1568    TS("Compositor Init");
1569    if (!e_comp_init())
1570      {
1571         e_error_message_show(_("Enlightenment cannot create a compositor.\n"));
1572         _e_main_shutdown(-1);
1573      }
1574
1575    _e_main_desk_restore();
1576
1577 #ifndef HAVE_WAYLAND_ONLY
1578    if (e_config->show_splash)
1579      e_init_status_set(_("Setup DND"));
1580    TS("E_Dnd Init");
1581    if (!e_dnd_init())
1582      {
1583         e_error_message_show(_("Enlightenment cannot set up its dnd system.\n"));
1584         _e_main_shutdown(-1);
1585      }
1586    TS("E_Dnd Init Done");
1587    _e_main_shutdown_push(e_dnd_shutdown);
1588 #endif
1589
1590    return 1;
1591 }
1592
1593 static int
1594 _e_main_screens_shutdown(void)
1595 {
1596    e_win_shutdown();
1597    e_menu_shutdown();
1598    e_shelf_shutdown();
1599    e_comp_shutdown();
1600    e_client_shutdown();
1601    e_exehist_shutdown();
1602    e_backlight_shutdown();
1603    e_exec_shutdown();
1604
1605    e_desk_shutdown();
1606    e_zone_shutdown();
1607    return 1;
1608 }
1609
1610 static void
1611 _e_main_desk_save(void)
1612 {
1613    const Eina_List *l;
1614    char env[1024], name[1024];
1615    E_Zone *zone;
1616
1617    EINA_LIST_FOREACH(e_comp->zones, l, zone)
1618      {
1619         snprintf(name, sizeof(name), "DESK_%d_%d", 0, zone->num);
1620         snprintf(env, sizeof(env), "%d,%d", zone->desk_x_current, zone->desk_y_current);
1621         e_util_env_set(name, env);
1622      }
1623 }
1624
1625 static void
1626 _e_main_desk_restore(void)
1627 {
1628    const Eina_List *l;
1629    E_Zone *zone;
1630    char *env;
1631    char name[1024];
1632
1633    EINA_LIST_FOREACH(e_comp->zones, l, zone)
1634      {
1635         E_Desk *desk;
1636         int desk_x, desk_y;
1637
1638         snprintf(name, sizeof(name), "DESK_%d_%d", 0, zone->num);
1639         env = getenv(name);
1640         if (!env) continue;
1641         if (!sscanf(env, "%d,%d", &desk_x, &desk_y)) continue;
1642         desk = e_desk_at_xy_get(zone, desk_x, desk_y);
1643         if (!desk) continue;
1644         e_desk_show(desk);
1645      }
1646 }
1647
1648 static void
1649 _e_main_efreet_paths_init(void)
1650 {
1651    Eina_List **list;
1652
1653    if ((list = efreet_icon_extra_list_get()))
1654      {
1655         char buff[PATH_MAX];
1656
1657         e_user_dir_concat_static(buff, "icons");
1658         *list = eina_list_prepend(*list, (void *)eina_stringshare_add(buff));
1659         e_prefix_data_concat_static(buff, "data/icons");
1660         *list = eina_list_prepend(*list, (void *)eina_stringshare_add(buff));
1661      }
1662 }
1663
1664 static Eina_Bool
1665 _e_main_modules_load_after(void *d EINA_UNUSED, int type EINA_UNUSED, void *ev EINA_UNUSED)
1666 {
1667    e_int_config_modules(NULL, NULL);
1668    E_FREE_FUNC(mod_init_end, ecore_event_handler_del);
1669    return ECORE_CALLBACK_RENEW;
1670 }
1671
1672 static void
1673 _e_main_modules_load(Eina_Bool safe_mode)
1674 {
1675    if (!safe_mode)
1676      e_module_all_load();
1677    else
1678      {
1679         E_Module *m;
1680         char *crashmodule;
1681
1682         crashmodule = getenv("E_MODULE_LOAD");
1683         if (crashmodule) m = e_module_new(crashmodule);
1684
1685         if ((crashmodule) && (m))
1686           {
1687              e_module_disable(m);
1688              e_object_del(E_OBJECT(m));
1689
1690              e_error_message_show
1691                (_("Enlightenment crashed early on start and has<br>"
1692                   "been restarted. There was an error loading the<br>"
1693                   "module named: %s. This module has been disabled<br>"
1694                   "and will not be loaded."), crashmodule);
1695              e_util_dialog_show
1696                (_("Enlightenment crashed early on start and has been restarted"),
1697                _("Enlightenment crashed early on start and has been restarted.<br>"
1698                  "There was an error loading the module named: %s<br><br>"
1699                  "This module has been disabled and will not be loaded."), crashmodule);
1700              e_module_all_load();
1701           }
1702         else
1703           {
1704              e_error_message_show
1705                (_("Enlightenment crashed early on start and has<br>"
1706                   "been restarted. All modules have been disabled<br>"
1707                   "and will not be loaded to help remove any problem<br>"
1708                   "modules from your configuration. The module<br>"
1709                   "configuration dialog should let you select your<br>"
1710                   "modules again.\n"));
1711              e_util_dialog_show
1712                (_("Enlightenment crashed early on start and has been restarted"),
1713                _("Enlightenment crashed early on start and has been restarted.<br>"
1714                  "All modules have been disabled and will not be loaded to help<br>"
1715                  "remove any problem modules from your configuration.<br><br>"
1716                  "The module configuration dialog should let you select your<br>"
1717                  "modules again."));
1718           }
1719         mod_init_end = ecore_event_handler_add(E_EVENT_MODULE_INIT_END, _e_main_modules_load_after, NULL);
1720      }
1721 }
1722
1723 static Eina_Bool
1724 _e_main_cb_idle_before(void *data EINA_UNUSED)
1725 {
1726    e_menu_idler_before();
1727    e_client_idler_before();
1728    e_pointer_idler_before();
1729    edje_thaw();
1730    return ECORE_CALLBACK_RENEW;
1731 }
1732
1733 static Eina_Bool
1734 _e_main_cb_idle_after(void *data EINA_UNUSED)
1735 {
1736    static int first_idle = 1;
1737
1738    eet_clearcache();
1739    edje_freeze();
1740
1741 #ifdef E_RELEASE_BUILD
1742    if (first_idle)
1743      {
1744         TS("SLEEP");
1745         first_idle = 0;
1746         e_precache_end = EINA_TRUE;
1747      }
1748 #else
1749    if (first_idle++ < 60)
1750      {
1751         TS("SLEEP");
1752         if (!first_idle)
1753           e_precache_end = EINA_TRUE;
1754      }
1755 #endif
1756
1757    return ECORE_CALLBACK_RENEW;
1758 }
1759
1760 static Eina_Bool
1761 _e_main_cb_startup_fake_end(void *data EINA_UNUSED)
1762 {
1763    e_init_hide();
1764    return ECORE_CALLBACK_CANCEL;
1765 }