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