3 # include <sys/prctl.h>
6 # include <systemd/sd-daemon.h>
15 t1 = ecore_time_unix_get(); \
16 printf("ESTART: %1.5f [%1.5f] - %s\n", t1 - t0, t1 - t2, x); \
22 TRACE_DS_BEGIN(ESTART: %s, x); \
32 TRACE_DS_MARK(ESTART: %s, x); \
35 static double t0, t1, t2;
43 * i need to make more use of these when i'm baffled as to when something is
46 * void *(*__malloc_hook)(size_t size, const void *caller);
48 * void *(*__realloc_hook)(void *ptr, size_t size, const void *caller);
50 * void *(*__memalign_hook)(size_t alignment, size_t size,
51 * const void *caller);
53 * void (*__free_hook)(void *ptr, const void *caller);
55 * void (*__malloc_initialize_hook)(void);
57 * void (*__after_morecore_hook)(void);
60 static void my_init_hook(void);
61 static void my_free_hook(void *p, const void *caller);
63 static void (*old_free_hook)(void *ptr, const void *caller) = NULL;
64 void (*__free_hook)(void *ptr, const void *caller);
66 void (*__malloc_initialize_hook) (void) = my_init_hook;
70 old_free_hook = __free_hook;
71 __free_hook = my_free_hook;
74 //void *magicfree = NULL;
77 my_free_hook(void *p, const void *caller)
79 __free_hook = old_free_hook;
80 // if ((p) && (p == magicfree))
82 // printf("CAUGHT!!!!! %p ...\n", p);
86 __free_hook = my_free_hook;
90 /* local function prototypes */
91 static void _e_main_shutdown(int errcode);
92 static void _e_main_shutdown_push(int (*func)(void));
93 static void _e_main_parse_arguments(int argc, char **argv);
94 static Eina_Bool _e_main_cb_signal_exit(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED);
95 static Eina_Bool _e_main_cb_signal_hup(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED);
96 static Eina_Bool _e_main_cb_signal_user(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev);
97 static int _e_main_dirs_init(void);
98 static int _e_main_dirs_shutdown(void);
99 static int _e_main_path_init(void);
100 static int _e_main_path_shutdown(void);
101 static int _e_main_screens_init(void);
102 static int _e_main_screens_shutdown(void);
103 static void _e_main_desk_save(void);
104 static void _e_main_desk_restore(void);
105 static void _e_main_modules_load(Eina_Bool safe_mode);
106 static Eina_Bool _e_main_cb_idle_before(void *data EINA_UNUSED);
107 static Eina_Bool _e_main_cb_idle_after(void *data EINA_UNUSED);
108 static void _e_main_create_wm_ready(void);
109 static void _e_main_hooks_clean(void);
110 static void _e_main_hook_call(E_Main_Hook_Point hookpoint, void *data EINA_UNUSED);
112 /* local variables */
113 static Eina_Bool really_know = EINA_FALSE;
114 static Eina_Bool inloop = EINA_FALSE;
116 static int _e_main_lvl = 0;
117 static int(*_e_main_shutdown_func[MAX_LEVEL]) (void);
119 static Ecore_Idle_Enterer *_idle_before = NULL;
120 static Ecore_Idle_Enterer *_idle_after = NULL;
122 static Ecore_Event_Handler *mod_init_end = NULL;
124 static Eina_List *hooks = NULL;
126 static int _e_main_hooks_delete = 0;
127 static int _e_main_hooks_walking = 0;
129 static Eina_Inlist *_e_main_hooks[] =
131 [E_MAIN_HOOK_MODULE_LOAD_DONE] = NULL,
132 [E_MAIN_HOOK_E_INFO_READY] = NULL
135 /* external variables */
136 E_API Eina_Bool e_precache_end = EINA_FALSE;
137 E_API Eina_Bool good = EINA_FALSE;
138 E_API Eina_Bool evil = EINA_FALSE;
139 E_API Eina_Bool starting = EINA_TRUE;
140 E_API Eina_Bool stopping = EINA_FALSE;
141 E_API Eina_Bool restart = EINA_FALSE;
142 E_API Eina_Bool e_nopause = EINA_FALSE;
145 _xdg_check_str(const char *env, const char *str)
151 for (p = strstr(env, str); p; p++, p = strstr(p, str))
153 if ((!p[len]) || (p[len] == ':')) return EINA_TRUE;
159 _xdg_data_dirs_augment(void)
162 const char *p = e_prefix_get();
163 char newpath[4096], buf[4096];
167 s = e_util_env_get("XDG_DATA_DIRS");
170 Eina_Bool pfxdata, pfx;
172 pfxdata = !_xdg_check_str(s, e_prefix_data_get());
173 snprintf(newpath, sizeof(newpath), "%s/share", p);
174 pfx = !_xdg_check_str(s, newpath);
177 snprintf(buf, sizeof(buf), "%s%s%s%s%s",
178 pfxdata ? e_prefix_data_get() : "",
183 e_util_env_set("XDG_DATA_DIRS", buf);
189 snprintf(buf, sizeof(buf), "%s:%s/share:/usr/local/share:/usr/share", e_prefix_data_get(), p);
190 e_util_env_set("XDG_DATA_DIRS", buf);
193 s = e_util_env_get("XDG_CONFIG_DIRS");
194 snprintf(newpath, sizeof(newpath), "%s/etc/xdg", p);
197 if (!_xdg_check_str(s, newpath))
199 snprintf(buf, sizeof(buf), "%s:%s", newpath, s);
200 e_util_env_set("XDG_CONFIG_DIRS", buf);
206 snprintf(buf, sizeof(buf), "%s:/etc/xdg", newpath);
207 e_util_env_set("XDG_CONFIG_DIRS", buf);
210 s = e_util_env_get("XDG_RUNTIME_DIR");
217 snprintf(buf, sizeof(buf), "/tmp/xdg-XXXXXX");
219 if (!dir) dir = "/tmp";
222 e_util_env_set("XDG_RUNTIME_DIR", dir);
223 snprintf(buf, sizeof(buf), "%s/.e-deleteme", dir);
224 ecore_file_mkdir(buf);
228 /* set menu prefix so we get our e menu */
229 s = e_util_env_get("XDG_MENU_PREFIX");
233 e_util_env_set("XDG_MENU_PREFIX", "e-");
237 _e_main_subsystem_defer(void *data EINA_UNUSED)
242 TRACE_DS_BEGIN(MAIN:SUBSYSTEMS DEFER);
244 ecore_app_args_get(&argc, &argv);
246 /* try to init delayed subsystems */
248 TRACE_DS_BEGIN(MAIN:DEFERRED INTERNAL SUBSYSTEMS INIT);
250 TSB("[DEFERRED] DPMS Init");
253 e_error_message_show(_("Enlightenment cannot set up dpms.\n"));
256 TSE("[DEFERRED] DPMS Init Done");
257 _e_main_shutdown_push(e_dpms_shutdown);
259 TSB("[DEFERRED] Screens Init: win");
262 e_error_message_show(_("Enlightenment cannot setup elementary trap!\n"));
265 TSE("[DEFERRED] Screens Init: win Done");
267 TSB("[DEFERRED] E_Dnd Init");
270 e_error_message_show(_("Enlightenment cannot set up its dnd system.\n"));
273 TSE("[DEFERRED] E_Dnd Init Done");
274 _e_main_shutdown_push(e_dnd_shutdown);
276 TSB("[DEFERRED] E_Scale Init");
279 e_error_message_show(_("Enlightenment cannot set up its scale system.\n"));
282 TSE("[DEFERRED] E_Scale Init Done");
283 _e_main_shutdown_push(e_scale_shutdown);
285 TSB("[DEFERRED] E_Test_Helper Init");
286 e_test_helper_init();
287 _e_main_shutdown_push(e_test_helper_shutdown);
288 TSE("[DEFERRED] E_Test_Helper Done");
290 TSB("[DEFERRED] E_INFO_SERVER Init");
291 e_info_server_init();
292 _e_main_shutdown_push(e_info_server_shutdown);
293 TSE("[DEFERRED] E_INFO_SERVER Done");
296 TRACE_DS_BEGIN(MAIN:DEFERRED COMP JOB);
298 /* try to do deferred job of any subsystems*/
299 TSB("[DEFERRED] Compositor's deferred job");
300 e_comp_deferred_job();
301 TSE("[DEFERRED] Compositor's deferred job Done");
303 if (e_config->use_e_policy)
305 TSB("[DEFERRED] E_Policy's deferred job");
306 e_policy_deferred_job();
307 TSE("[DEFERRED] E_Policy's deferred job Done");
310 TSB("[DEFERRED] E_Module's deferred job");
311 e_module_deferred_job();
312 TSE("[DEFERRED] E_Module's deferred job Done");
316 return ECORE_CALLBACK_DONE;
322 _e_main_shutdown(-1);
323 return ECORE_CALLBACK_DONE;
327 _e_main_deferred_job_schedule(void *d EINA_UNUSED, int type EINA_UNUSED, void *ev EINA_UNUSED)
329 PRCTL("[Winsys] all modules loaded");
330 ecore_idler_add(_e_main_subsystem_defer, NULL);
331 return ECORE_CALLBACK_DONE;
334 /* externally accessible functions */
336 main(int argc, char **argv)
338 Eina_Bool safe_mode = EINA_FALSE;
339 double t = 0.0, tstart = 0.0;
340 char *s = NULL, *s1 = NULL, buff[32];
341 struct sigaction action;
344 # ifdef PR_SET_PTRACER
345 # ifdef PR_SET_PTRACER_ANY
346 prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY);
351 t0 = t1 = t2 = ecore_time_unix_get();
352 printf("ESTART(main) %1.5f\n", t0);
354 TRACE_DS_BEGIN(MAIN:BEGIN STARTUP);
355 TSB("Begin Startup");
356 PRCTL("[Winsys] start of main");
358 /* trap deadly bug signals and allow some form of sane recovery */
359 /* or ability to gdb attach and debug at this point - better than your */
360 /* wm/desktop vanishing and not knowing what happened */
362 /* don't install SIGBUS handler */
363 /* Wayland shm sets up a sigbus handler for catching invalid shm region */
364 /* access. If we setup our sigbus handler here, then the wl-shm sigbus */
365 /* handler will not function properly */
366 s = e_util_env_get("NOTIFY_SOCKET");
372 action.sa_sigaction = e_sigseg_act;
373 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
374 sigemptyset(&action.sa_mask);
375 sigaction(SIGSEGV, &action, NULL);
377 action.sa_sigaction = e_sigill_act;
378 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
379 sigemptyset(&action.sa_mask);
380 sigaction(SIGILL, &action, NULL);
382 action.sa_sigaction = e_sigfpe_act;
383 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
384 sigemptyset(&action.sa_mask);
385 sigaction(SIGFPE, &action, NULL);
387 action.sa_sigaction = e_sigabrt_act;
388 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
389 sigemptyset(&action.sa_mask);
390 sigaction(SIGABRT, &action, NULL);
391 TSE("Signal Trap Done");
394 t = ecore_time_unix_get();
395 s = e_util_env_get("E_START_TIME");
398 s1 = e_util_env_get("E_RESTART_OK");
400 E_FREE(s1); /* do nothing... */
404 * 1. E_RESTART_OK is not defined.
405 * 2. the diff time between this and previous start is less than 5 seconds.
408 if ((t - tstart) < 5.0) safe_mode = EINA_TRUE;
413 /* save start time to environment variable to calculate
414 * diff time at the next restart
417 snprintf(buff, sizeof(buff), "%1.1f", tstart);
418 e_util_env_set("E_START_TIME", buff);
420 s = e_util_env_get("E_START_MTRACK");
423 e_util_env_set("MTRACK", NULL);
429 e_error_message_show(_("Enlightenment cannot initialize Eina!\n"));
432 TSE("Eina Init Done");
433 _e_main_shutdown_push(eina_shutdown);
435 #ifdef OBJECT_HASH_CHECK
436 TSB("E_Object Hash Init");
437 e_object_hash_init();
438 TSE("E_Object Hash Init Done");
444 e_error_message_show(_("Enlightenment could not create a logging domain!\n"));
447 TSE("E_Log Init Done");
448 _e_main_shutdown_push(e_log_shutdown);
450 TSB("Determine Prefix");
451 if (!e_prefix_determine(argv[0]))
454 "ERROR: Enlightenment cannot determine it's installed\n"
455 " prefix from the system or argv[0].\n"
456 " This is because it is not on Linux AND has been\n"
457 " executed strangely. This is unusual.\n");
459 TSE("Determine Prefix Done");
461 /* for debugging by redirecting stdout of e to a log file to tail */
462 setvbuf(stdout, NULL, _IONBF, 0);
464 TSB("Parse Arguments");
465 _e_main_parse_arguments(argc, argv);
466 TSE("Parse Arguments Done");
468 /*** Initialize Core EFL Libraries We Need ***/
473 e_error_message_show(_("Enlightenment cannot initialize Eet!\n"));
476 TSE("Eet Init Done");
477 _e_main_shutdown_push(eet_shutdown);
479 /* Allow ecore to not load system modules.
480 * Without it ecore_init will block until dbus authentication
481 * and registration are complete.
483 ecore_app_no_system_modules();
488 e_error_message_show(_("Enlightenment cannot initialize Ecore!\n"));
491 TSE("Ecore Init Done");
492 _e_main_shutdown_push(ecore_shutdown);
497 e_error_message_show(_("Enlightenment cannot initialize EIO!\n"));
500 TSE("EIO Init Done");
501 _e_main_shutdown_push(eio_shutdown);
503 ecore_app_args_set(argc, (const char **)argv);
505 TSB("Ecore Event Handlers");
506 if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT,
507 _e_main_cb_signal_exit, NULL))
509 e_error_message_show(_("Enlightenment cannot set up an exit signal handler.\n"
510 "Perhaps you are out of memory?"));
513 if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_HUP,
514 _e_main_cb_signal_hup, NULL))
516 e_error_message_show(_("Enlightenment cannot set up a HUP signal handler.\n"
517 "Perhaps you are out of memory?"));
520 if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
521 _e_main_cb_signal_user, NULL))
523 e_error_message_show(_("Enlightenment cannot set up a USER signal handler.\n"
524 "Perhaps you are out of memory?"));
527 TSE("Ecore Event Handlers Done");
529 TSB("Ecore_File Init");
530 if (!ecore_file_init())
532 e_error_message_show(_("Enlightenment cannot initialize Ecore_File!\n"));
535 TSE("Ecore_File Init Done");
536 _e_main_shutdown_push(ecore_file_shutdown);
538 _idle_before = ecore_idle_enterer_before_add(_e_main_cb_idle_before, NULL);
540 TSB("XDG_DATA_DIRS Init");
541 _xdg_data_dirs_augment();
542 TSE("XDG_DATA_DIRS Init Done");
544 TSB("Ecore_Evas Init");
545 if (!ecore_evas_init())
547 e_error_message_show(_("Enlightenment cannot initialize Ecore_Evas!\n"));
550 TSE("Ecore_Evas Init Done");
552 /* e doesn't sync to compositor - it should be one */
553 ecore_evas_app_comp_sync_set(0);
558 e_error_message_show(_("Enlightenment cannot initialize Edje!\n"));
561 TSE("Edje Init Done");
562 _e_main_shutdown_push(edje_shutdown);
564 /*** Initialize E Subsystems We Need ***/
569 e_error_message_show(_("Enlightenment cannot set up user home path\n"));
572 TSE("E User Init Done");
573 _e_main_shutdown_push(e_user_shutdown);
575 TSB("E Directories Init");
576 /* setup directories we will be using for configurations storage etc. */
577 if (!_e_main_dirs_init())
579 e_error_message_show(_("Enlightenment cannot create directories in your home directory.\n"
580 "Perhaps you have no home directory or the disk is full?"));
583 TSE("E Directories Init Done");
584 _e_main_shutdown_push(_e_main_dirs_shutdown);
586 TSB("E_Config Init");
587 if (!e_config_init())
589 e_error_message_show(_("Enlightenment cannot set up its config system.\n"));
592 TSE("E_Config Init Done");
593 _e_main_shutdown_push(e_config_shutdown);
598 e_error_message_show(_("Enlightenment cannot set up its environment.\n"));
601 TSE("E_Env Init Done");
602 _e_main_shutdown_push(e_env_shutdown);
604 ecore_exe_run_priority_set(e_config->priority);
607 if (!_e_main_path_init())
609 e_error_message_show(_("Enlightenment cannot set up paths for finding files.\n"
610 "Perhaps you are out of memory?"));
613 TSE("E Paths Init Done");
614 _e_main_shutdown_push(_e_main_path_shutdown);
616 ecore_animator_frametime_set(1.0 / e_config->framerate);
621 e_error_message_show(_("Enlightenment cannot set up its theme system.\n"));
624 TSE("E_Theme Init Done");
625 _e_main_shutdown_push(e_theme_shutdown);
627 TSB("E_Actions Init");
628 if (!e_actions_init())
630 e_error_message_show(_("Enlightenment cannot set up its actions system.\n"));
633 TSE("E_Actions Init Done");
634 _e_main_shutdown_push(e_actions_shutdown);
636 /* these just add event handlers and can't fail
637 * timestamping them is dumb.
639 e_screensaver_preinit();
644 TRACE_DS_BEGIN(MAIN:WAIT /dev/dri/card0);
645 if (e_config->sleep_for_dri)
647 while(access("/dev/dri/card0", F_OK) != 0)
649 struct timespec req, rem;
651 req.tv_nsec = 50000000L;
652 nanosleep(&req, &rem);
657 e_module_event_init();
659 TSB("E_Pointer Init");
660 if (!e_pointer_init())
662 e_error_message_show(_("Enlightenment cannot set up its pointer system.\n"));
665 TSE("E_Pointer Init Done");
666 _e_main_shutdown_push(e_pointer_shutdown);
668 TRACE_DS_BEGIN(MAIN:SCREEN INIT);
670 if (!_e_main_screens_init())
672 e_error_message_show(_("Enlightenment set up window management for all the screens on your system\n"
673 "failed. Perhaps another window manager is running?\n"));
676 TSE("Screens Init Done");
677 _e_main_shutdown_push(_e_main_screens_shutdown);
680 if (e_config->eom_enable)
685 e_error_message_show(_("Enlightenment cannot set up eom.\n"));
688 TSE("Eom Init Done");
689 _e_main_shutdown_push(e_eom_shutdown);
692 TSB("E_Screensaver Init");
693 if (!e_screensaver_init())
695 e_error_message_show(_("Enlightenment cannot configure the X screensaver.\n"));
698 TSE("E_Screensaver Init Done");
699 _e_main_shutdown_push(e_screensaver_shutdown);
701 TSB("E_Comp Freeze");
703 TSE("E_Comp Freeze Done");
705 TSB("E_Grabinput Init");
706 if (!e_grabinput_init())
708 e_error_message_show(_("Enlightenment cannot set up its grab input handling system.\n"));
711 TSE("E_Grabinput Init Done");
712 _e_main_shutdown_push(e_grabinput_shutdown);
714 TS("E_Gesture Init");
716 _e_main_shutdown_push(e_gesture_shutdown);
718 ecore_event_handler_add(E_EVENT_MODULE_INIT_END, _e_main_deferred_job_schedule, NULL);
720 TSB("E_Module Init");
721 if (!e_module_init())
723 e_error_message_show(_("Enlightenment cannot set up its module system.\n"));
726 TSE("E_Module Init Done");
727 _e_main_shutdown_push(e_module_shutdown);
730 if (!e_mouse_update())
732 e_error_message_show(_("Enlightenment cannot configure the mouse settings.\n"));
735 TSE("E_Mouse Init Done");
740 e_error_message_show(_("Enlightenment cannot initialize the Icon Cache system.\n"));
743 TSE("E_Icon Init Done");
744 _e_main_shutdown_push(e_icon_shutdown);
746 if (e_config->use_e_policy)
748 TSB("E_Policy Init");
749 if (!e_policy_init())
751 e_error_message_show(_("Enlightenment cannot setup policy system!\n"));
754 TSE("E_Policy Init Done");
755 _e_main_shutdown_push(e_policy_shutdown);
758 TSB("E_Process Init");
759 if (!e_process_init())
761 e_error_message_show(_("Enlightenment cannot setup process managing system!\n"));
764 TSE("E_Process Init Done");
765 _e_main_shutdown_push(e_process_shutdown);
767 TSB("E_Security Init");
768 if (!e_security_init())
770 e_error_message_show(_("Enlightenment cannot setup security system!\n"));
773 TSE("E_Security Init Done");
774 _e_main_shutdown_push(e_security_shutdown);
777 _e_main_modules_load(safe_mode);
778 TSE("Load Modules Done");
782 TSE("E_Comp Thaw Done");
784 _idle_after = ecore_idle_enterer_add(_e_main_cb_idle_after, NULL);
786 starting = EINA_FALSE;
789 e_util_env_set("E_RESTART", "1");
791 TSM("MAIN LOOP AT LAST");
793 if (e_config->create_wm_ready)
794 _e_main_create_wm_ready();
799 TSM("[WM] Send start-up completion");
800 sd_notify(0, "READY=1");
802 TSM("[WM] Skip sending start-up completion. (no systemd)");
804 ecore_main_loop_begin();
808 ELOGF("COMP", "STOPPING enlightenment...", NULL, NULL);
809 stopping = EINA_TRUE;
812 e_comp_internal_save();
818 e_util_env_set("E_RESTART_OK", "1");
819 s = e_util_env_get("E_START_MTRACK");
822 e_util_env_set("MTRACK", "track");
835 _e_main_shutdown(-1);
839 e_main_ts(const char *str)
842 t1 = ecore_time_unix_get();
843 printf("ESTART: %1.5f [%1.5f] - %s\n", t1 - t0, t1 - t2, str);
850 e_main_ts_begin(const char *str)
852 TRACE_DS_BEGIN(ESTART: %s, str);
853 return e_main_ts(str);
857 e_main_ts_end(const char *str)
860 return e_main_ts(str);
863 /* local functions */
865 _e_main_shutdown(int errcode)
871 printf("E: Begin Shutdown Procedure!\n");
873 E_FREE_LIST(hooks, e_main_hook_del);
875 if (_idle_before) ecore_idle_enterer_del(_idle_before);
877 if (_idle_after) ecore_idle_enterer_del(_idle_after);
880 dir = e_util_env_get("XDG_RUNTIME_DIR");
883 char buf_env[PATH_MAX];
884 snprintf(buf_env, sizeof(buf_env), "%s", dir);
885 snprintf(buf, sizeof(buf), "%s/.e-deleteme", buf_env);
886 if (ecore_file_exists(buf)) ecore_file_recursive_rm(buf_env);
889 for (i = (_e_main_lvl - 1); i >= 0; i--)
890 (*_e_main_shutdown_func[i])();
891 #ifdef OBJECT_HASH_CHECK
892 e_object_hash_shutdown();
894 if (errcode < 0) exit(errcode);
898 _e_main_shutdown_push(int (*func)(void))
901 if (_e_main_lvl > MAX_LEVEL)
904 e_error_message_show("WARNING: too many init levels. MAX = %i\n",
908 _e_main_shutdown_func[_e_main_lvl - 1] = func;
912 _e_main_parse_arguments(int argc, char **argv)
916 /* handle some command-line parameters */
917 for (i = 1; i < argc; i++)
919 if (!strcmp(argv[i], "-good"))
923 printf("LA LA LA\n");
925 else if (!strcmp(argv[i], "-evil"))
929 printf("MUHAHAHAHHAHAHAHAHA\n");
931 else if (!strcmp(argv[i], "-psychotic"))
935 printf("MUHAHALALALALALALALA\n");
937 else if ((!strcmp(argv[i], "-profile")) && (i < (argc - 1)))
940 if (!getenv("E_CONF_PROFILE"))
941 e_util_env_set("E_CONF_PROFILE", argv[i]);
943 else if (!strcmp(argv[i], "-i-really-know-what-i-am-doing-and-accept-full-responsibility-for-it"))
944 really_know = EINA_TRUE;
945 else if (!strcmp(argv[i], "-nopause"))
946 e_nopause = EINA_TRUE;
947 else if ((!strcmp(argv[i], "-version")) ||
948 (!strcmp(argv[i], "--version")))
950 printf(_("Version: %s\n"), PACKAGE_VERSION);
951 _e_main_shutdown(-1);
953 else if ((!strcmp(argv[i], "-h")) ||
954 (!strcmp(argv[i], "-help")) ||
955 (!strcmp(argv[i], "--help")))
960 "\t-display DISPLAY\n"
961 "\t\tConnect to display named DISPLAY.\n"
962 "\t\tEG: -display :1.0\n"
963 "\t-fake-xinerama-screen WxH+X+Y\n"
964 "\t\tAdd a FAKE xinerama screen (instead of the real ones)\n"
965 "\t\tgiven the geometry. Add as many as you like. They all\n"
966 "\t\treplace the real xinerama screens, if any. This can\n"
967 "\t\tbe used to simulate xinerama.\n"
968 "\t\tEG: -fake-xinerama-screen 800x600+0+0 -fake-xinerama-screen 800x600+800+0\n"
969 "\t-profile CONF_PROFILE\n"
970 "\t\tUse the configuration profile CONF_PROFILE instead of the user selected default or just \"default\".\n"
976 "\t\tBe psychotic.\n"
977 "\t-i-really-know-what-i-am-doing-and-accept-full-responsibility-for-it\n"
978 "\t\tIf you need this help, you don't need this option.\n"
982 _e_main_shutdown(-1);
988 _e_main_cb_signal_exit(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
990 /* called on ctrl-c, kill (pid) (also SIGINT, SIGTERM and SIGQIT) */
991 ecore_main_loop_quit();
992 return ECORE_CALLBACK_RENEW;
996 _e_main_cb_signal_hup(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
999 ecore_main_loop_quit();
1000 return ECORE_CALLBACK_RENEW;
1004 _e_main_cb_signal_user(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev)
1006 Ecore_Event_Signal_User *e = ev;
1010 // E_Action *a = e_action_find("configuration");
1011 // if ((a) && (a->func.go)) a->func.go(NULL, NULL);
1013 else if (e->number == 2)
1015 // comp module has its own handler for this for enabling/disabling fps debug
1017 return ECORE_CALLBACK_RENEW;
1022 _e_main_dirs_init(void)
1024 if(getenv("E_CONF_RO"))
1030 const char *dirs[] =
1038 base = e_user_dir_get();
1039 if (ecore_file_mksubdirs(base, dirs) != sizeof(dirs) / sizeof(dirs[0]) - 1)
1041 e_error_message_show("Could not create one of the required "
1042 "subdirectories of '%s'\n", base);
1050 _e_main_dirs_shutdown(void)
1056 _e_main_path_init(void)
1060 /* setup data paths */
1061 path_data = e_path_new();
1064 e_error_message_show("Cannot allocate path for path_data\n");
1067 e_prefix_data_concat_static(buf, "data");
1068 e_path_default_path_append(path_data, buf);
1070 /* setup image paths */
1071 path_images = e_path_new();
1074 e_error_message_show("Cannot allocate path for path_images\n");
1077 e_user_dir_concat_static(buf, "/images");
1078 e_path_default_path_append(path_images, buf);
1079 e_prefix_data_concat_static(buf, "data/images");
1080 e_path_default_path_append(path_images, buf);
1082 /* setup font paths */
1083 path_fonts = e_path_new();
1086 e_error_message_show("Cannot allocate path for path_fonts\n");
1089 e_user_dir_concat_static(buf, "/fonts");
1090 e_path_default_path_append(path_fonts, buf);
1091 e_prefix_data_concat_static(buf, "data/fonts");
1092 e_path_default_path_append(path_fonts, buf);
1094 /* setup icon paths */
1095 path_icons = e_path_new();
1098 e_error_message_show("Cannot allocate path for path_icons\n");
1101 e_user_dir_concat_static(buf, "/icons");
1102 e_path_default_path_append(path_icons, buf);
1103 e_prefix_data_concat_static(buf, "data/icons");
1104 e_path_default_path_append(path_icons, buf);
1106 /* setup module paths */
1107 path_modules = e_path_new();
1110 e_error_message_show("Cannot allocate path for path_modules\n");
1113 e_user_dir_concat_static(buf, "/modules");
1114 e_path_default_path_append(path_modules, buf);
1115 snprintf(buf, sizeof(buf), "%s/enlightenment/modules", e_prefix_lib_get());
1116 e_path_default_path_append(path_modules, buf);
1117 /* FIXME: eventually this has to go - moduels should have installers that
1118 * add appropriate install paths (if not installed to user homedir) to
1119 * e's module search dirs
1121 snprintf(buf, sizeof(buf), "%s/enlightenment/modules_extra", e_prefix_lib_get());
1122 e_path_default_path_append(path_modules, buf);
1124 /* setup background paths */
1125 path_backgrounds = e_path_new();
1126 if (!path_backgrounds)
1128 e_error_message_show("Cannot allocate path for path_backgrounds\n");
1131 e_user_dir_concat_static(buf, "/backgrounds");
1132 e_path_default_path_append(path_backgrounds, buf);
1133 e_prefix_data_concat_static(buf, "data/backgrounds");
1134 e_path_default_path_append(path_backgrounds, buf);
1136 path_messages = e_path_new();
1139 e_error_message_show("Cannot allocate path for path_messages\n");
1142 e_user_dir_concat_static(buf, "/locale");
1143 e_path_default_path_append(path_messages, buf);
1144 e_path_default_path_append(path_messages, e_prefix_locale_get());
1150 _e_main_path_shutdown(void)
1154 e_object_del(E_OBJECT(path_data));
1159 e_object_del(E_OBJECT(path_images));
1164 e_object_del(E_OBJECT(path_fonts));
1169 e_object_del(E_OBJECT(path_icons));
1174 e_object_del(E_OBJECT(path_modules));
1175 path_modules = NULL;
1177 if (path_backgrounds)
1179 e_object_del(E_OBJECT(path_backgrounds));
1180 path_backgrounds = NULL;
1184 e_object_del(E_OBJECT(path_messages));
1185 path_messages = NULL;
1191 _e_main_screens_init(void)
1193 TSB("\tscreens: client");
1194 if (!e_client_init()) return 0;
1195 TSE("\tscreens: client Done");
1197 TSB("Compositor Init");
1198 PRCTL("[Winsys] start of compositor init");
1201 e_error_message_show(_("Enlightenment cannot create a compositor.\n"));
1202 _e_main_shutdown(-1);
1204 TSE("Compositor Init Done");
1206 PRCTL("[Winsys] end of compositor init");
1207 _e_main_desk_restore();
1213 _e_main_screens_shutdown(void)
1217 e_client_shutdown();
1226 _e_main_desk_save(void)
1229 char env[1024], name[1024];
1232 EINA_LIST_FOREACH(e_comp->zones, l, zone)
1234 snprintf(name, sizeof(name), "DESK_%d_%d", 0, zone->num);
1235 snprintf(env, sizeof(env), "%d,%d", zone->desk_x_current, zone->desk_y_current);
1236 e_util_env_set(name, env);
1241 _e_main_desk_restore(void)
1245 E_CLIENT_REVERSE_FOREACH(ec)
1246 if ((!e_client_util_ignored_get(ec)) && e_client_util_desk_visible(ec, e_desk_current_get(ec->zone)))
1248 ec->want_focus = ec->take_focus = 1;
1254 _e_main_modules_load_after(void *d EINA_UNUSED, int type EINA_UNUSED, void *ev EINA_UNUSED)
1256 E_FREE_FUNC(mod_init_end, ecore_event_handler_del);
1257 return ECORE_CALLBACK_RENEW;
1261 _e_main_modules_load(Eina_Bool safe_mode)
1264 e_module_all_load();
1270 crashmodule = getenv("E_MODULE_LOAD");
1271 if (crashmodule) m = e_module_new(crashmodule);
1273 if ((crashmodule) && (m))
1275 e_module_disable(m);
1276 e_object_del(E_OBJECT(m));
1278 e_error_message_show
1279 (_("Enlightenment crashed early on start and has<br>"
1280 "been restarted. There was an error loading the<br>"
1281 "module named: %s. This module has been disabled<br>"
1282 "and will not be loaded."), crashmodule);
1284 (_("Enlightenment crashed early on start and has been restarted"),
1285 _("Enlightenment crashed early on start and has been restarted.<br>"
1286 "There was an error loading the module named: %s<br><br>"
1287 "This module has been disabled and will not be loaded."), crashmodule);
1288 e_module_all_load();
1292 e_error_message_show
1293 (_("Enlightenment crashed early on start and has<br>"
1294 "been restarted. All modules have been disabled<br>"
1295 "and will not be loaded to help remove any problem<br>"
1296 "modules from your configuration. The module<br>"
1297 "configuration dialog should let you select your<br>"
1298 "modules again.\n"));
1300 (_("Enlightenment crashed early on start and has been restarted"),
1301 _("Enlightenment crashed early on start and has been restarted.<br>"
1302 "All modules have been disabled and will not be loaded to help<br>"
1303 "remove any problem modules from your configuration.<br><br>"
1304 "The module configuration dialog should let you select your<br>"
1307 mod_init_end = ecore_event_handler_add(E_EVENT_MODULE_INIT_END, _e_main_modules_load_after, NULL);
1312 _e_main_cb_idle_before(void *data EINA_UNUSED)
1314 e_client_idler_before();
1316 return ECORE_CALLBACK_RENEW;
1320 _e_main_cb_idle_after(void *data EINA_UNUSED)
1322 static int first_idle = 1;
1327 #ifdef E_RELEASE_BUILD
1332 e_precache_end = EINA_TRUE;
1335 if (first_idle++ < 60)
1339 e_precache_end = EINA_TRUE;
1343 return ECORE_CALLBACK_RENEW;
1347 _e_main_create_wm_ready(void)
1349 FILE *_wmready_checker = NULL;
1350 const char *path_wm_ready = "/run/.wm_ready";
1352 if (!e_util_file_realpath_check(path_wm_ready, EINA_TRUE))
1354 WRN("%s is maybe link, so delete it\n", path_wm_ready);
1357 _wmready_checker = fopen(path_wm_ready, "wb");
1358 if (_wmready_checker)
1360 TSM("[WM] WINDOW MANAGER is READY!!!");
1361 PRCTL("[Winsys] WINDOW MANAGER is READY!!!");
1362 fclose(_wmready_checker);
1364 /*TODO: Next lines should be removed. */
1365 FILE *_tmp_wm_ready_checker;
1367 _tmp_wm_ready_checker = fopen(path_wm_ready, "wb");
1369 if (_tmp_wm_ready_checker)
1371 TSM("[WM] temporary wm_ready path is created.");
1372 PRCTL("[Winsys] temporary wm_ready path is created.");
1373 fclose(_tmp_wm_ready_checker);
1377 TSM("[WM] temporary wm_ready path create failed.");
1378 PRCTL("[Winsys] temporary wm_ready path create failed.");
1383 TSM("[WM] WINDOW MANAGER is READY. BUT, failed to create .wm_ready file.");
1384 PRCTL("[Winsys] WINDOW MANAGER is READY. BUT, failed to create .wm_ready file.");
1389 _e_main_hooks_clean(void)
1395 for (x = 0; x < E_MAIN_HOOK_LAST; x++)
1396 EINA_INLIST_FOREACH_SAFE(_e_main_hooks[x], l, mh)
1398 if (!mh->delete_me) continue;
1399 _e_main_hooks[x] = eina_inlist_remove(_e_main_hooks[x],
1400 EINA_INLIST_GET(mh));
1406 _e_main_hook_call(E_Main_Hook_Point hookpoint, void *data EINA_UNUSED)
1410 _e_main_hooks_walking++;
1411 EINA_INLIST_FOREACH(_e_main_hooks[hookpoint], mh)
1413 if (mh->delete_me) continue;
1416 _e_main_hooks_walking--;
1417 if ((_e_main_hooks_walking == 0) && (_e_main_hooks_delete > 0))
1418 _e_main_hooks_clean();
1422 e_main_hook_add(E_Main_Hook_Point hookpoint, E_Main_Hook_Cb func, const void *data)
1426 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_MAIN_HOOK_LAST, NULL);
1427 mh = E_NEW(E_Main_Hook, 1);
1428 EINA_SAFETY_ON_NULL_RETURN_VAL(mh, NULL);
1429 mh->hookpoint = hookpoint;
1431 mh->data = (void*)data;
1432 _e_main_hooks[hookpoint] = eina_inlist_append(_e_main_hooks[hookpoint],
1433 EINA_INLIST_GET(mh));
1438 e_main_hook_del(E_Main_Hook *mh)
1441 if (_e_main_hooks_walking == 0)
1443 _e_main_hooks[mh->hookpoint] = eina_inlist_remove(_e_main_hooks[mh->hookpoint],
1444 EINA_INLIST_GET(mh));
1448 _e_main_hooks_delete++;
1452 e_main_hook_call(E_Main_Hook_Point hookpoint)
1454 if ((hookpoint < 0) || (hookpoint >= E_MAIN_HOOK_LAST)) return;
1456 _e_main_hook_call(hookpoint, NULL);