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