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