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