add shot_topvwins to enlightenment_info
[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_x_flusher(void *data __UNUSED__);
88 static Eina_Bool _e_main_cb_idle_before(void *data __UNUSED__);
89 static Eina_Bool _e_main_cb_idle_after(void *data __UNUSED__);
90 static Eina_Bool _e_main_cb_startup_fake_end(void *data __UNUSED__);
91
92 /* local variables */
93 static Eina_Bool really_know = EINA_FALSE;
94 static Eina_Bool locked = EINA_FALSE;
95 static Eina_Bool inloop = EINA_FALSE;
96 static jmp_buf x_fatal_buff;
97
98 static int _e_main_lvl = 0;
99 static int(*_e_main_shutdown_func[MAX_LEVEL]) (void);
100
101 static Ecore_Idle_Enterer *_idle_before = NULL;
102 static Ecore_Idle_Enterer *_idle_after = NULL;
103 static Ecore_Idle_Enterer *_idle_flush = NULL;
104
105 static Ecore_Event_Handler *mod_init_end = NULL;
106
107 /* external variables */
108 EAPI Eina_Bool e_precache_end = EINA_FALSE;
109 EAPI Eina_Bool x_fatal = EINA_FALSE;
110 EAPI Eina_Bool good = EINA_FALSE;
111 EAPI Eina_Bool evil = EINA_FALSE;
112 EAPI Eina_Bool starting = EINA_TRUE;
113 EAPI Eina_Bool stopping = EINA_FALSE;
114 EAPI Eina_Bool restart = EINA_FALSE;
115 EAPI Eina_Bool e_nopause = EINA_FALSE;
116 EINTERN const char *e_first_frame = NULL;
117 EINTERN double e_first_frame_start_time = -1;
118
119 static Eina_Bool
120 _xdg_check_str(const char *env, const char *str)
121 {
122    const char *p;
123    size_t len;
124
125    len = strlen(str);
126    for (p = strstr(env, str); p; p++, p = strstr(p, str))
127      {
128         if ((!p[len]) || (p[len] == ':')) return EINA_TRUE;
129      }
130    return EINA_FALSE;
131 }
132
133 static void
134 _xdg_data_dirs_augment(void)
135 {
136    const char *s;
137    const char *p = e_prefix_get();
138    char newpath[4096], buf[4096];
139
140    if (!p) return;
141
142    s = getenv("XDG_DATA_DIRS");
143    if (s)
144      {
145         Eina_Bool pfxdata, pfx;
146
147         pfxdata = !_xdg_check_str(s, e_prefix_data_get());
148         snprintf(newpath, sizeof(newpath), "%s/share", p);
149         pfx = !_xdg_check_str(s, newpath);
150         if (pfxdata || pfx)
151           {
152              snprintf(buf, sizeof(buf), "%s%s%s%s%s",
153                pfxdata ? e_prefix_data_get() : "",
154                pfxdata ? ":" : "",
155                pfx ? newpath : "",
156                pfx ? ":" : "",
157                s);
158              e_util_env_set("XDG_DATA_DIRS", buf);
159           }
160      }
161    else
162      {
163         snprintf(buf, sizeof(buf), "%s:%s/share:/usr/local/share:/usr/share", e_prefix_data_get(), p);
164         e_util_env_set("XDG_DATA_DIRS", buf);
165      }
166
167    s = getenv("XDG_CONFIG_DIRS");
168    snprintf(newpath, sizeof(newpath), "%s/etc/xdg", p);
169    if (s)
170      {
171         if (!_xdg_check_str(s, newpath))
172           {
173              snprintf(buf, sizeof(buf), "%s:%s", newpath, s);
174              e_util_env_set("XDG_CONFIG_DIRS", buf);
175           }
176      }
177    else
178      {
179         snprintf(buf, sizeof(buf), "%s:/etc/xdg", newpath);
180         e_util_env_set("XDG_CONFIG_DIRS", buf);
181      }
182
183    if (!getenv("XDG_RUNTIME_DIR"))
184      {
185         const char *dir;
186
187         snprintf(buf, sizeof(buf), "/tmp/xdg-XXXXXX");
188         dir = mkdtemp(buf);
189         if (!dir) dir = "/tmp";
190         else
191           {
192              e_util_env_set("XDG_RUNTIME_DIR", dir);
193              snprintf(buf, sizeof(buf), "%s/.e-deleteme", dir);
194              ecore_file_mkdir(buf);
195           }
196      }
197
198    /* set menu prefix so we get our e menu */
199    if (!getenv("XDG_MENU_PREFIX"))
200      {
201         e_util_env_set("XDG_MENU_PREFIX", "e-");
202      }
203 }
204
205 static Eina_Bool
206 _e_main_shelf_init_job(void *data EINA_UNUSED)
207 {
208    e_shelf_config_update();
209    return ECORE_CALLBACK_CANCEL;
210 }
211
212 /* externally accessible functions */
213 int
214 main(int argc, char **argv)
215 {
216    Eina_Bool nostartup = EINA_FALSE;
217    Eina_Bool safe_mode = EINA_FALSE;
218    Eina_Bool after_restart = EINA_FALSE;
219    Eina_Bool waslocked = EINA_FALSE;
220    double t = 0.0, tstart = 0.0;
221    char *s = NULL, buff[32];
222    struct sigaction action;
223
224 #ifdef __linux__
225 # ifdef PR_SET_PTRACER
226 #  ifdef PR_SET_PTRACER_ANY
227    prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY);
228 #  endif
229 # endif
230 #endif
231    
232 #ifdef TS_DO
233    t0 = t1 = t2 = ecore_time_unix_get();
234 #endif
235    TS("Begin Startup");
236
237    /* trap deadly bug signals and allow some form of sane recovery */
238    /* or ability to gdb attach and debug at this point - better than your */
239    /* wm/desktop vanishing and not knowing what happened */
240    if (!getenv("NOTIFY_SOCKET"))
241      {
242         TS("Signal Trap");
243         action.sa_sigaction = e_sigseg_act;
244         action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
245         sigemptyset(&action.sa_mask);
246         sigaction(SIGSEGV, &action, NULL);
247
248         action.sa_sigaction = e_sigill_act;
249         action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
250         sigemptyset(&action.sa_mask);
251         sigaction(SIGILL, &action, NULL);
252
253         action.sa_sigaction = e_sigfpe_act;
254         action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
255         sigemptyset(&action.sa_mask);
256         sigaction(SIGFPE, &action, NULL);
257
258 #ifndef HAVE_WAYLAND_ONLY
259         action.sa_sigaction = e_sigbus_act;
260         action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
261         sigemptyset(&action.sa_mask);
262         sigaction(SIGBUS, &action, NULL);
263 #endif
264
265         action.sa_sigaction = e_sigabrt_act;
266         action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
267         sigemptyset(&action.sa_mask);
268         sigaction(SIGABRT, &action, NULL);
269         TS("Signal Trap Done");
270      }
271
272    t = ecore_time_unix_get();
273    s = getenv("E_START_TIME");
274    if ((s) && (!getenv("E_RESTART_OK")))
275      {
276         tstart = atof(s);
277         if ((t - tstart) < 5.0) safe_mode = EINA_TRUE;
278      }
279    tstart = t;
280    snprintf(buff, sizeof(buff), "%1.1f", tstart);
281    e_util_env_set("E_START_TIME", buff);
282
283    if (getenv("E_START_MTRACK"))
284      e_util_env_set("MTRACK", NULL);
285    TS("Eina Init");
286    if (!eina_init())
287      {
288         e_error_message_show(_("Enlightenment cannot initialize Eina!\n"));
289         _e_main_shutdown(-1);
290      }
291    _e_main_shutdown_push(eina_shutdown);
292    if (!e_log_init())
293      {
294         e_error_message_show(_("Enlightenment could not create a logging domain!\n"));
295         _e_main_shutdown(-1);
296      }
297 #ifdef TS_DO
298 #undef TS
299 # define TS(x)                                                    \
300   {                                                               \
301      t1 = ecore_time_unix_get();                                  \
302      printf("ESTART: %1.5f [%1.5f] - %s\n", t1 - t0, t1 - t2, x); \
303      t2 = t1;                                                     \
304   }
305 #endif
306    TS("Eina Init Done");
307    _e_main_shutdown_push(e_log_shutdown);
308
309    TS("Determine Prefix");
310    if (!e_prefix_determine(argv[0]))
311      {
312         fprintf(stderr,
313                 "ERROR: Enlightenment cannot determine it's installed\n"
314                 "       prefix from the system or argv[0].\n"
315                 "       This is because it is not on Linux AND has been\n"
316                 "       executed strangely. This is unusual.\n");
317      }
318    TS("Determine Prefix Done");
319
320    /* for debugging by redirecting stdout of e to a log file to tail */
321    setvbuf(stdout, NULL, _IONBF, 0);
322
323    TS("Environment Variables");
324    if (getenv("E_RESTART")) after_restart = EINA_TRUE;
325    if (getenv("DESKTOP_STARTUP_ID"))
326      e_util_env_set("DESKTOP_STARTUP_ID", NULL);
327    e_util_env_set("E_RESTART_OK", NULL);
328    e_util_env_set("PANTS", "ON");
329    e_util_env_set("DESKTOP", "Enlightenment-0.17.0");
330    TS("Environment Variables Done");
331
332    TS("Parse Arguments");
333    _e_main_parse_arguments(argc, argv);
334    TS("Parse Arguments Done");
335
336    /*** Initialize Core EFL Libraries We Need ***/
337
338    TS("Eet Init");
339    if (!eet_init())
340      {
341         e_error_message_show(_("Enlightenment cannot initialize Eet!\n"));
342         _e_main_shutdown(-1);
343      }
344    TS("Eet Init Done");
345    _e_main_shutdown_push(eet_shutdown);
346
347    TS("Ecore Init");
348    if (!ecore_init())
349      {
350         e_error_message_show(_("Enlightenment cannot initialize Ecore!\n"));
351         _e_main_shutdown(-1);
352      }
353    TS("Ecore Init Done");
354    _e_main_shutdown_push(ecore_shutdown);
355
356    e_first_frame = getenv("E_FIRST_FRAME");
357    if (e_first_frame && (!e_first_frame[0]))
358      e_first_frame = NULL;
359    else
360      e_first_frame_start_time = ecore_time_get();
361
362    TS("EIO Init");
363    if (!eio_init())
364      {
365         e_error_message_show(_("Enlightenment cannot initialize EIO!\n"));
366         _e_main_shutdown(-1);
367      }
368    TS("EIO Init Done");
369    _e_main_shutdown_push(eio_shutdown);
370
371    ecore_app_args_set(argc, (const char **)argv);
372
373    TS("Ecore Event Handlers");
374    if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT,
375                                 _e_main_cb_signal_exit, NULL))
376      {
377         e_error_message_show(_("Enlightenment cannot set up an exit signal handler.\n"
378                                "Perhaps you are out of memory?"));
379         _e_main_shutdown(-1);
380      }
381    if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_HUP,
382                                 _e_main_cb_signal_hup, NULL))
383      {
384         e_error_message_show(_("Enlightenment cannot set up a HUP signal handler.\n"
385                                "Perhaps you are out of memory?"));
386         _e_main_shutdown(-1);
387      }
388    if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
389                                 _e_main_cb_signal_user, NULL))
390      {
391         e_error_message_show(_("Enlightenment cannot set up a USER signal handler.\n"
392                                "Perhaps you are out of memory?"));
393         _e_main_shutdown(-1);
394      }
395    TS("Ecore Event Handlers Done");
396
397    TS("Ecore_File Init");
398    if (!ecore_file_init())
399      {
400         e_error_message_show(_("Enlightenment cannot initialize Ecore_File!\n"));
401         _e_main_shutdown(-1);
402      }
403    TS("Ecore_File Init Done");
404    _e_main_shutdown_push(ecore_file_shutdown);
405
406    TS("Ecore_Con Init");
407    if (!ecore_con_init())
408      {
409         e_error_message_show(_("Enlightenment cannot initialize Ecore_Con!\n"));
410         _e_main_shutdown(-1);
411      }
412    TS("Ecore_Con Init Done");
413    _e_main_shutdown_push(ecore_con_shutdown);
414
415    TS("Ecore_Ipc Init");
416    if (!ecore_ipc_init())
417      {
418         e_error_message_show(_("Enlightenment cannot initialize Ecore_Ipc!\n"));
419         _e_main_shutdown(-1);
420      }
421    TS("Ecore_Ipc Init Done");
422    _e_main_shutdown_push(ecore_ipc_shutdown);
423
424    _idle_before = ecore_idle_enterer_before_add(_e_main_cb_idle_before, NULL);
425
426    _xdg_data_dirs_augment();
427
428    TS("Ecore_Evas Init");
429    if (!ecore_evas_init())
430      {
431         e_error_message_show(_("Enlightenment cannot initialize Ecore_Evas!\n"));
432         _e_main_shutdown(-1);
433      }
434    TS("Ecore_Evas Init Done");
435 //   _e_main_shutdown_push(ecore_evas_shutdown);
436
437    TS("Elementary Init");
438    if (!elm_init(argc, argv))
439      {
440         e_error_message_show(_("Enlightenment cannot initialize Elementary!\n"));
441         _e_main_shutdown(-1);
442      }
443    TS("Elementary Init Done");
444    //_e_main_shutdown_push(elm_shutdown);
445
446    TS("Emotion Init");
447    if (!emotion_init())
448      {
449         e_error_message_show(_("Enlightenment cannot initialize Emotion!\n"));
450         _e_main_shutdown(-1);
451      }
452    TS("Emotion Init Done");
453    _e_main_shutdown_push((void *)emotion_shutdown);
454
455    /* e doesn't sync to compositor - it should be one */
456    ecore_evas_app_comp_sync_set(0);
457
458    TS("Ecore_Evas Engine Check");
459 #ifdef HAVE_WAYLAND_ONLY
460    if (!ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_WAYLAND_SHM))
461      {
462         e_error_message_show(_("Enlightenment found ecore_evas doesn't support the Wayland SHM\n"
463                                "rendering in Evas. Please check your installation of Evas and\n"
464                                 "Ecore and check they support the Wayland SHM rendering engine."));
465         _e_main_shutdown(-1);
466      }
467 #else
468    if (!ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_SOFTWARE_XCB))
469      {
470         if (!ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_SOFTWARE_XLIB))
471           {
472              e_error_message_show(_("Enlightenment found ecore_evas doesn't support the Software X11\n"
473                                     "rendering in Evas. Please check your installation of Evas and\n"
474                                     "Ecore and check they support the Software X11 rendering engine."));
475              _e_main_shutdown(-1);
476           }
477      }
478 #endif
479    if (!ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_SOFTWARE_BUFFER))
480      {
481         e_error_message_show(_("Enlightenment found ecore_evas doesn't support the Software Buffer\n"
482                                "rendering in Evas. Please check your installation of Evas and\n"
483                                "Ecore and check they support the Software Buffer rendering engine."));
484         _e_main_shutdown(-1);
485      }
486    TS("Ecore_Evas Engine Check Done");
487
488    TS("Edje Init");
489    if (!edje_init())
490      {
491         e_error_message_show(_("Enlightenment cannot initialize Edje!\n"));
492         _e_main_shutdown(-1);
493      }
494    TS("Edje Init Done");
495    _e_main_shutdown_push(edje_shutdown);
496    edje_freeze();
497
498    /*** Initialize E Subsystems We Need ***/
499
500    TS("E Intl Init");
501    if (!e_intl_init())
502      {
503         e_error_message_show(_("Enlightenment cannot initialize E_Intl!\n"));
504         _e_main_shutdown(-1);
505      }
506    TS("E Intl Init Done");
507    _e_main_shutdown_push(e_intl_shutdown);
508
509 #ifndef HAVE_WAYLAND_ONLY
510    /* init white box of death alert */
511    TS("E_Alert Init");
512    if (!e_alert_init())
513      {
514         e_error_message_show(_("Enlightenment cannot initialize its emergency alert system.\n"
515                                "Have you set your DISPLAY variable?"));
516         _e_main_shutdown(-1);
517      }
518    TS("E_Alert Init Done");
519    _e_main_shutdown_push(e_alert_shutdown);
520 #endif
521
522    TS("E_Configure Init");
523    e_configure_init();
524    TS("E_Configure Init Done");
525
526    TS("E Directories Init");
527    /* setup directories we will be using for configurations storage etc. */
528    if (!_e_main_dirs_init())
529      {
530         e_error_message_show(_("Enlightenment cannot create directories in your home directory.\n"
531                                "Perhaps you have no home directory or the disk is full?"));
532         _e_main_shutdown(-1);
533      }
534    TS("E Directories Init Done");
535    _e_main_shutdown_push(_e_main_dirs_shutdown);
536
537    TS("E_Filereg Init");
538    if (!e_filereg_init())
539      {
540         e_error_message_show(_("Enlightenment cannot set up its file registry system.\n"));
541         _e_main_shutdown(-1);
542      }
543    TS("E_Filereg Init Done");
544    _e_main_shutdown_push(e_filereg_shutdown);
545
546    TS("E_Config Init");
547    if (!e_config_init())
548      {
549         e_error_message_show(_("Enlightenment cannot set up its config system.\n"));
550         _e_main_shutdown(-1);
551      }
552    TS("E_Config Init Done");
553    _e_main_shutdown_push(e_config_shutdown);
554
555    TS("E_Env Init");
556    if (!e_env_init())
557      {
558         e_error_message_show(_("Enlightenment cannot set up its environment.\n"));
559         _e_main_shutdown(-1);
560      }
561    TS("E_Env Init Done");
562    _e_main_shutdown_push(e_env_shutdown);
563
564    efreet_desktop_environment_set(e_config->desktop_environment);
565    e_util_env_set("E_ICON_THEME", e_config->icon_theme);
566    ecore_exe_run_priority_set(e_config->priority);
567    locked |= e_config->desklock_start_locked;
568
569    s = getenv("E_DESKLOCK_LOCKED");
570    if ((s) && (!strcmp(s, "locked"))) waslocked = EINA_TRUE;
571
572    TS("E Paths Init");
573    if (!_e_main_path_init())
574      {
575         e_error_message_show(_("Enlightenment cannot set up paths for finding files.\n"
576                                "Perhaps you are out of memory?"));
577         _e_main_shutdown(-1);
578      }
579    TS("E Paths Init Done");
580    _e_main_shutdown_push(_e_main_path_shutdown);
581
582    TS("E_Ipc Init");
583    if (!e_ipc_init()) _e_main_shutdown(-1);
584    TS("E_Ipc Init Done");
585    _e_main_shutdown_push(e_ipc_shutdown);
586
587    edje_frametime_set(1.0 / e_config->framerate);
588
589    TS("E_Font Init");
590    if (!e_font_init())
591      {
592         e_error_message_show(_("Enlightenment cannot set up its font system.\n"));
593         _e_main_shutdown(-1);
594      }
595    TS("E_Font Init Done");
596    _e_main_shutdown_push(e_font_shutdown);
597
598    TS("E_Font Apply");
599    e_font_apply();
600    TS("E_Font Apply Done");
601
602    TS("E_Theme Init");
603    if (!e_theme_init())
604      {
605         e_error_message_show(_("Enlightenment cannot set up its theme system.\n"));
606         _e_main_shutdown(-1);
607      }
608    TS("E_Theme Init Done");
609    _e_main_shutdown_push(e_theme_shutdown);
610
611    TS("E_Moveresize Init");
612    e_moveresize_init();
613    TS("E_Moveresize Init Done");
614    _e_main_shutdown_push(e_moveresize_shutdown);
615
616    if (e_config->show_splash)
617      e_init_status_set(_("Setup Message Bus"));
618    TS("E_Msgbus Init");
619    if (e_msgbus_init())
620      _e_main_shutdown_push(e_msgbus_shutdown);
621    TS("E_Msgbus Init Done");
622
623    TS("Efreet Init");
624    if (!efreet_init())
625      {
626         e_error_message_show(_("Enlightenment cannot initialize the FDO desktop system.\n"
627                                "Perhaps you lack permissions on ~/.cache/efreet or are\n"
628                                "out of memory or disk space?"));
629         _e_main_shutdown(-1);
630      }
631    TS("Efreet Init Done");
632    _e_main_shutdown_push(efreet_shutdown);
633
634    if (e_config->show_splash)
635      e_init_status_set(_("Starting International Support"));
636    TS("E_Intl Post Init");
637    if (!e_intl_post_init())
638      {
639         e_error_message_show(_("Enlightenment cannot set up its intl system.\n"));
640         _e_main_shutdown(-1);
641      }
642    TS("E_Intl Post Init Done");
643    _e_main_shutdown_push(e_intl_post_shutdown);
644
645    e_screensaver_preinit();
646
647    if (e_config->show_splash)
648      e_init_status_set(_("Setup Actions"));
649    TS("E_Actions Init");
650    if (!e_actions_init())
651      {
652         e_error_message_show(_("Enlightenment cannot set up its actions system.\n"));
653         _e_main_shutdown(-1);
654      }
655    TS("E_Actions Init Done");
656    _e_main_shutdown_push(e_actions_shutdown);
657
658    /* these just add event handlers and can't fail
659     * timestamping them is dumb.
660     */
661    e_zone_init();
662    e_desk_init();
663    e_exehist_init();
664
665    if (e_config->show_splash)
666      e_init_status_set(_("Setup Powersave Modes"));
667    TS("E_Powersave Init");
668    if (!e_powersave_init())
669      {
670         e_error_message_show(_("Enlightenment cannot set up its powersave modes.\n"));
671         _e_main_shutdown(-1);
672      }
673    TS("E_Powersave Init Done");
674    _e_main_shutdown_push(e_powersave_shutdown);
675
676    if (e_config->show_splash)
677      e_init_status_set(_("Setup Screensaver"));
678    TS("E_Screensaver Init");
679    if (!e_screensaver_init())
680      {
681         e_error_message_show(_("Enlightenment cannot configure the X screensaver.\n"));
682         _e_main_shutdown(-1);
683      }
684    TS("E_Screensaver Init Done");
685    _e_main_shutdown_push(e_screensaver_shutdown);
686
687    if (e_config->show_splash)
688      e_init_status_set(_("Setup Screens"));
689    TS("Screens Init");
690    if (!_e_main_screens_init())
691      {
692         e_error_message_show(_("Enlightenment set up window management for all the screens on your system\n"
693                                "failed. Perhaps another window manager is running?\n"));
694         _e_main_shutdown(-1);
695      }
696    TS("Screens Init Done");
697    _e_main_shutdown_push(_e_main_screens_shutdown);
698    e_screensaver_force_update();
699
700    TS("E_Pointer Init");
701    if (!e_pointer_init())
702      {
703         e_error_message_show(_("Enlightenment cannot set up its pointer system.\n"));
704         _e_main_shutdown(-1);
705      }
706    TS("E_Pointer Init Done");
707    _e_main_shutdown_push(e_pointer_shutdown);
708    e_menu_init();
709
710    TS("E_Scale Init");
711    if (!e_scale_init())
712      {
713         e_error_message_show(_("Enlightenment cannot set up its scale system.\n"));
714         _e_main_shutdown(-1);
715      }
716    TS("E_Scale Init Done");
717    _e_main_shutdown_push(e_scale_shutdown);
718
719    if (e_config->show_splash)
720      {
721         TS("E_Splash Init");
722         if (!e_init_init())
723           {
724              e_error_message_show(_("Enlightenment cannot set up its init screen.\n"));
725              _e_main_shutdown(-1);
726           }
727         TS("E_Splash Init Done");
728         _e_main_shutdown_push(e_init_shutdown);
729      }
730    if (!((!e_config->show_splash) || (after_restart)))
731      e_init_show();
732
733    if (!really_know)
734      {
735         TS("Test File Format Support");
736         _e_main_test_formats();
737         TS("Test File Format Support Done");
738      }
739    else
740      {
741         efreet_icon_extension_add(".svg");
742         efreet_icon_extension_add(".jpg");
743         efreet_icon_extension_add(".png");
744         efreet_icon_extension_add(".edj");
745      }
746
747    if (e_config->show_splash)
748      e_init_status_set(_("Setup ACPI"));
749    TS("E_Acpi Init");
750    e_acpi_init();
751    TS("E_Acpi Init Done");
752    _e_main_shutdown_push(e_acpi_shutdown);
753
754    if (e_config->show_splash)
755      e_init_status_set(_("Setup Backlight"));
756    TS("E_Backlight Init");
757    if (!e_backlight_init())
758      {
759         e_error_message_show(_("Enlightenment cannot configure the backlight.\n"));
760         _e_main_shutdown(-1);
761      }
762    TS("E_Backlight Init Done");
763
764    if (e_config->show_splash)
765      e_init_status_set(_("Setup DPMS"));
766    TS("E_Dpms Init");
767    if (!e_dpms_init())
768      {
769         e_error_message_show(_("Enlightenment cannot configure the DPMS settings.\n"));
770         _e_main_shutdown(-1);
771      }
772    TS("E_Dpms Init Done");
773    _e_main_shutdown_push(e_dpms_shutdown);
774
775    if (e_config->show_splash)
776      e_init_status_set(_("Setup Desklock"));
777    TS("E_Desklock Init");
778    if (!e_desklock_init())
779      {
780         e_error_message_show(_("Enlightenment cannot set up its desk locking system.\n"));
781         _e_main_shutdown(-1);
782      }
783    TS("E_Desklock Init Done");
784    _e_main_shutdown_push(e_desklock_shutdown);
785
786    if (waslocked || (locked && ((!after_restart) || (!getenv("E_DESKLOCK_UNLOCKED")))))
787      e_desklock_show(EINA_TRUE);
788
789    if (e_config->show_splash)
790      e_init_status_set(_("Setup Paths"));
791    TS("Efreet Paths");
792    _e_main_efreet_paths_init();
793    TS("Efreet Paths Done");
794
795    if (e_config->show_splash)
796      e_init_status_set(_("Setup System Controls"));
797    TS("E_Sys Init");
798    if (!e_sys_init())
799      {
800         e_error_message_show(_("Enlightenment cannot initialize the System Command system.\n"));
801         _e_main_shutdown(-1);
802      }
803    TS("E_Sys Init Done");
804    _e_main_shutdown_push(e_sys_shutdown);
805
806    if (e_config->show_splash)
807      e_init_status_set(_("Setup Execution System"));
808    TS("E_Exec Init");
809    if (!e_exec_init())
810      {
811         e_error_message_show(_("Enlightenment cannot set up its exec system.\n"));
812         _e_main_shutdown(-1);
813      }
814    TS("E_Exec Init Done");
815
816    TS("E_Comp Freeze");
817    e_comp_all_freeze();
818    TS("E_Comp Freeze Done");
819
820    if (e_config->show_splash)
821      e_init_status_set(_("Setup Filemanager"));
822    TS("E_Fm2 Init");
823    if (!e_fm2_init())
824      {
825         e_error_message_show(_("Enlightenment cannot initialize the File manager.\n"));
826         _e_main_shutdown(-1);
827      }
828    TS("E_Fm2 Init Done");
829    _e_main_shutdown_push(e_fm2_shutdown);
830
831    if (e_config->show_splash)
832      e_init_status_set(_("Setup Message System"));
833    TS("E_Msg Init");
834    if (!e_msg_init())
835      {
836         e_error_message_show(_("Enlightenment cannot set up its msg system.\n"));
837         _e_main_shutdown(-1);
838      }
839    TS("E_Msg Init Done");
840    _e_main_shutdown_push(e_msg_shutdown);
841
842    if (e_config->show_splash)
843      e_init_status_set(_("Setup Grab Input Handling"));
844    TS("E_Grabinput Init");
845    if (!e_grabinput_init())
846      {
847         e_error_message_show(_("Enlightenment cannot set up its grab input handling system.\n"));
848         _e_main_shutdown(-1);
849      }
850    TS("E_Grabinput Init Done");
851    _e_main_shutdown_push(e_grabinput_shutdown);
852
853    if (e_config->show_splash)
854      e_init_status_set(_("Setup Modules"));
855    TS("E_Module Init");
856    if (!e_module_init())
857      {
858         e_error_message_show(_("Enlightenment cannot set up its module system.\n"));
859         _e_main_shutdown(-1);
860      }
861    TS("E_Module Init Done");
862    _e_main_shutdown_push(e_module_shutdown);
863
864    if (e_config->show_splash)
865      e_init_status_set(_("Setup Remembers"));
866    TS("E_Remember Init");
867    if (!e_remember_init(after_restart ? E_STARTUP_RESTART : E_STARTUP_START))
868      {
869         e_error_message_show(_("Enlightenment cannot setup remember settings.\n"));
870         _e_main_shutdown(-1);
871      }
872    TS("E_Remember Init Done");
873    _e_main_shutdown_push(e_remember_shutdown);
874
875    if (e_config->show_splash)
876      e_init_status_set(_("Setup Color Classes"));
877    TS("E_Color_Class Init");
878    if (!e_color_class_init())
879      {
880         e_error_message_show(_("Enlightenment cannot set up its color class system.\n"));
881         _e_main_shutdown(-1);
882      }
883    TS("E_Color_Class Init Done");
884    _e_main_shutdown_push(e_color_class_shutdown);
885
886    if (e_config->show_splash)
887      e_init_status_set(_("Setup Gadcon"));
888    TS("E_Gadcon Init");
889    if (!e_gadcon_init())
890      {
891         e_error_message_show(_("Enlightenment cannot set up its gadget control system.\n"));
892         _e_main_shutdown(-1);
893      }
894    TS("E_Gadcon Init Done");
895    _e_main_shutdown_push(e_gadcon_shutdown);
896
897    if (e_config->show_splash)
898      e_init_status_set(_("Setup Toolbars"));
899    TS("E_Toolbar Init");
900    if (!e_toolbar_init())
901      {
902         e_error_message_show(_("Enlightenment cannot set up its toolbars.\n"));
903         _e_main_shutdown(-1);
904      }
905    TS("E_Toolbar Init Done");
906    _e_main_shutdown_push(e_toolbar_shutdown);
907
908    if (e_config->show_splash)
909      e_init_status_set(_("Setup Wallpaper"));
910    TS("E_Bg Init");
911    if (!e_bg_init())
912      {
913         e_error_message_show(_("Enlightenment cannot set up its desktop background system.\n"));
914         _e_main_shutdown(-1);
915      }
916    TS("E_Bg Init Done");
917    _e_main_shutdown_push(e_bg_shutdown);
918
919    if (e_config->show_splash)
920      e_init_status_set(_("Setup Mouse"));
921    TS("E_Mouse Init");
922    if (!e_mouse_update())
923      {
924         e_error_message_show(_("Enlightenment cannot configure the mouse settings.\n"));
925         _e_main_shutdown(-1);
926      }
927    TS("E_Mouse Init Done");
928
929    if (e_config->show_splash)
930      e_init_status_set(_("Setup Bindings"));
931    TS("E_Bindings Init");
932    if (!e_bindings_init())
933      {
934         e_error_message_show(_("Enlightenment cannot set up its bindings system.\n"));
935         _e_main_shutdown(-1);
936      }
937    TS("E_Bindings Init Done");
938    _e_main_shutdown_push(e_bindings_shutdown);
939
940    if (e_config->show_splash)
941      e_init_status_set(_("Setup Thumbnailer"));
942    TS("E_Thumb Init");
943    if (!e_thumb_init())
944      {
945         e_error_message_show(_("Enlightenment cannot initialize the Thumbnailing system.\n"));
946         _e_main_shutdown(-1);
947      }
948    TS("E_Thumb Init Done");
949    _e_main_shutdown_push(e_thumb_shutdown);
950
951    TS("E_Icon Init");
952    if (!e_icon_init())
953      {
954         e_error_message_show(_("Enlightenment cannot initialize the Icon Cache system.\n"));
955         _e_main_shutdown(-1);
956      }
957    TS("E_Icon Init Done");
958    _e_main_shutdown_push(e_icon_shutdown);
959
960    TS("E_Update Init");
961    if (!e_update_init())
962      {
963         e_error_message_show(_("Enlightenment cannot initialize the Update system.\n"));
964         _e_main_shutdown(-1);
965      }
966    TS("E_Update Init Done");
967    _e_main_shutdown_push(e_update_shutdown);
968
969    if (e_config->show_splash)
970      e_init_status_set(_("Setup Desktop Environment"));
971    TS("E_Deskenv Init");
972    if (!e_deskenv_init())
973      {
974         e_error_message_show(_("Enlightenment cannot initialize its desktop environment.\n"));
975         _e_main_shutdown(-1);
976      }
977    TS("E_Deskenv Init Done");
978    _e_main_shutdown_push(e_deskenv_shutdown);
979
980    if (e_config->show_splash)
981      e_init_status_set(_("Setup File Ordering"));
982    TS("E_Order Init");
983    if (!e_order_init())
984      {
985         e_error_message_show(_("Enlightenment cannot set up its order file system.\n"));
986         _e_main_shutdown(-1);
987      }
988    TS("E_Order Init Done");
989    _e_main_shutdown_push(e_order_shutdown);
990
991    TS("Add Idler For X Flush");
992    _idle_flush = ecore_idle_enterer_add(_e_main_cb_x_flusher, NULL);
993    TS("Add Idler For X Flush Done");
994
995    TS("E_Manager Keys Grab");
996    e_managers_keys_grab();
997    TS("E_Manager Keys Grab Done");
998
999    if (e_config->show_splash)
1000      e_init_status_set(_("Load Modules"));
1001    TS("Load Modules");
1002    _e_main_modules_load(safe_mode);
1003    TS("Load Modules Done");
1004
1005    TS("Run Startup Apps");
1006    if (!nostartup)
1007      {
1008         if (after_restart)
1009           e_startup(E_STARTUP_RESTART);
1010         else
1011           e_startup(E_STARTUP_START);
1012      }
1013    TS("Run Startup Apps Done");
1014
1015    if (e_config->show_splash && (!after_restart))
1016      ecore_timer_add(2.0, _e_main_cb_startup_fake_end, NULL);
1017
1018    TS("E_Comp Thaw");
1019    e_comp_all_thaw();
1020    TS("E_Comp Thaw Done");
1021
1022    TS("E_Test Init");
1023    e_test();
1024    TS("E_Test Done");
1025
1026    TS("E_Test_Helper Init");
1027    e_test_helper_init();
1028    _e_main_shutdown_push(e_test_helper_shutdown);
1029    TS("E_Test_Helper Done");
1030
1031    TS("E_INFO_SERVER Init");
1032    e_info_server_init();
1033    _e_main_shutdown_push(e_info_server_shutdown);
1034    TS("E_INFO_SERVER Done");
1035
1036    if (e_config->show_splash)
1037      e_init_status_set(_("Setup Shelves"));
1038    TS("E_Shelf Init");
1039    if (!e_shelf_init())
1040      {
1041         e_error_message_show(_("Enlightenment cannot set up its module system.\n"));
1042         _e_main_shutdown(-1);
1043      }
1044    TS("E_Shelf Init Done");
1045
1046    ecore_idle_enterer_before_add(_e_main_shelf_init_job, NULL);
1047
1048    _idle_after = ecore_idle_enterer_add(_e_main_cb_idle_after, NULL);
1049
1050    if (e_config->show_splash)
1051      e_init_status_set(_("Almost Done"));
1052
1053    starting = EINA_FALSE;
1054    inloop = EINA_TRUE;
1055
1056    e_util_env_set("E_RESTART", "1");
1057
1058    TS("MAIN LOOP AT LAST");
1059    if (!setjmp(x_fatal_buff))
1060      ecore_main_loop_begin();
1061    else
1062      CRI("FATAL: X Died. Connection gone. Abbreviated Shutdown\n");
1063
1064    inloop = EINA_FALSE;
1065    stopping = EINA_TRUE;
1066
1067    //if (!x_fatal) e_canvas_idle_flush();
1068
1069    e_config_save_flush();
1070    _e_main_desk_save();
1071    e_remember_internal_save();
1072    e_comp_internal_save();
1073
1074    _e_main_shutdown(0);
1075
1076    if (restart)
1077      {
1078         e_util_env_set("E_RESTART_OK", "1");
1079         if (getenv("E_START_MTRACK"))
1080           e_util_env_set("MTRACK", "track");
1081         ecore_app_restart();
1082      }
1083
1084    e_prefix_shutdown();
1085
1086    return 0;
1087 }
1088
1089 EAPI double
1090 e_main_ts(const char *str)
1091 {
1092    double ret;
1093    t1 = ecore_time_unix_get();
1094    printf("ESTART: %1.5f [%1.5f] - %s\n", t1 - t0, t1 - t2, str);
1095    ret = t1 - t2;
1096    t2 = t1;
1097    return ret;
1098 }
1099
1100 /* local functions */
1101 static void
1102 _e_main_shutdown(int errcode)
1103 {
1104    int i = 0;
1105    char buf[PATH_MAX];
1106    const char *dir;
1107
1108    printf("E: Begin Shutdown Procedure!\n");
1109
1110    if (_idle_before) ecore_idle_enterer_del(_idle_before);
1111    _idle_before = NULL;
1112    if (_idle_after) ecore_idle_enterer_del(_idle_after);
1113    _idle_after = NULL;
1114    if (_idle_flush) ecore_idle_enterer_del(_idle_flush);
1115    _idle_flush = NULL;
1116
1117    dir = getenv("XDG_RUNTIME_DIR");
1118    if (dir)
1119      {
1120         snprintf(buf, sizeof(buf), "%s/.e-deleteme", dir);
1121         if (ecore_file_exists(buf)) ecore_file_recursive_rm(dir);
1122      }
1123    for (i = (_e_main_lvl - 1); i >= 0; i--)
1124      (*_e_main_shutdown_func[i])();
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    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
1664         snprintf(name, sizeof(name), "DESK_%d_%d", e_comp->num, zone->num);
1665         env = getenv(name);
1666         if (!env) continue;
1667         if (!sscanf(env, "%d,%d", &desk_x, &desk_y)) continue;
1668         desk = e_desk_at_xy_get(zone, desk_x, desk_y);
1669         if (!desk) continue;
1670         e_desk_show(desk);
1671      }
1672 }
1673
1674 static void
1675 _e_main_efreet_paths_init(void)
1676 {
1677    Eina_List **list;
1678
1679    if ((list = efreet_icon_extra_list_get()))
1680      {
1681         char buff[PATH_MAX];
1682
1683         e_user_dir_concat_static(buff, "icons");
1684         *list = eina_list_prepend(*list, (void *)eina_stringshare_add(buff));
1685         e_prefix_data_concat_static(buff, "data/icons");
1686         *list = eina_list_prepend(*list, (void *)eina_stringshare_add(buff));
1687      }
1688 }
1689
1690 static Eina_Bool
1691 _e_main_modules_load_after(void *d EINA_UNUSED, int type EINA_UNUSED, void *ev EINA_UNUSED)
1692 {
1693    e_int_config_modules(NULL, NULL);
1694    E_FREE_FUNC(mod_init_end, ecore_event_handler_del);
1695    return ECORE_CALLBACK_RENEW;
1696 }
1697
1698 static void
1699 _e_main_modules_load(Eina_Bool safe_mode)
1700 {
1701    if (!safe_mode)
1702      e_module_all_load();
1703    else
1704      {
1705         E_Module *m;
1706         char *crashmodule;
1707
1708         crashmodule = getenv("E_MODULE_LOAD");
1709         if (crashmodule) m = e_module_new(crashmodule);
1710
1711         if ((crashmodule) && (m))
1712           {
1713              e_module_disable(m);
1714              e_object_del(E_OBJECT(m));
1715
1716              e_error_message_show
1717                (_("Enlightenment crashed early on start and has<br>"
1718                   "been restarted. There was an error loading the<br>"
1719                   "module named: %s. This module has been disabled<br>"
1720                   "and will not be loaded."), crashmodule);
1721              e_util_dialog_show
1722                (_("Enlightenment crashed early on start and has been restarted"),
1723                _("Enlightenment crashed early on start and has been restarted.<br>"
1724                  "There was an error loading the module named: %s<br><br>"
1725                  "This module has been disabled and will not be loaded."), crashmodule);
1726              e_module_all_load();
1727           }
1728         else
1729           {
1730              e_error_message_show
1731                (_("Enlightenment crashed early on start and has<br>"
1732                   "been restarted. All modules have been disabled<br>"
1733                   "and will not be loaded to help remove any problem<br>"
1734                   "modules from your configuration. The module<br>"
1735                   "configuration dialog should let you select your<br>"
1736                   "modules again.\n"));
1737              e_util_dialog_show
1738                (_("Enlightenment crashed early on start and has been restarted"),
1739                _("Enlightenment crashed early on start and has been restarted.<br>"
1740                  "All modules have been disabled and will not be loaded to help<br>"
1741                  "remove any problem modules from your configuration.<br><br>"
1742                  "The module configuration dialog should let you select your<br>"
1743                  "modules again."));
1744           }
1745         mod_init_end = ecore_event_handler_add(E_EVENT_MODULE_INIT_END, _e_main_modules_load_after, NULL);
1746      }
1747 }
1748
1749 static Eina_Bool
1750 _e_main_cb_idle_before(void *data __UNUSED__)
1751 {
1752    e_menu_idler_before();
1753    e_client_idler_before();
1754    e_pointer_idler_before();
1755    edje_thaw();
1756    return ECORE_CALLBACK_RENEW;
1757 }
1758
1759 static Eina_Bool
1760 _e_main_cb_idle_after(void *data __UNUSED__)
1761 {
1762    static int first_idle = 1;
1763
1764    edje_freeze();
1765
1766 #ifdef E_RELEASE_BUILD
1767    if (first_idle)
1768      {
1769         TS("SLEEP");
1770         first_idle = 0;
1771         e_precache_end = EINA_TRUE;
1772      }
1773 #else
1774    if (first_idle++ < 60)
1775      {
1776         TS("SLEEP");
1777         if (!first_idle)
1778           e_precache_end = EINA_TRUE;
1779      }
1780 #endif
1781
1782    return ECORE_CALLBACK_RENEW;
1783 }
1784
1785 static Eina_Bool
1786 _e_main_cb_x_flusher(void *data __UNUSED__)
1787 {
1788    eet_clearcache();
1789 #ifndef HAVE_WAYLAND_ONLY
1790    if (e_comp->comp_type == E_PIXMAP_TYPE_X)
1791      ecore_x_flush();
1792 #endif
1793    return ECORE_CALLBACK_RENEW;
1794 }
1795
1796 static Eina_Bool
1797 _e_main_cb_startup_fake_end(void *data __UNUSED__)
1798 {
1799    e_init_hide();
1800    return ECORE_CALLBACK_CANCEL;
1801 }