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 Eina_Bool _e_main_cb_idle_before(void *data EINA_UNUSED);
106 static Eina_Bool _e_main_cb_idle_after(void *data EINA_UNUSED);
107 static void _e_main_create_wm_ready(void);
108 static void _e_main_hooks_clean(void);
109 static void _e_main_hook_call(E_Main_Hook_Point hookpoint, void *data EINA_UNUSED);
111 /* local variables */
112 static Eina_Bool really_know = EINA_FALSE;
113 static Eina_Bool inloop = EINA_FALSE;
115 static int _e_main_lvl = 0;
116 static int(*_e_main_shutdown_func[MAX_LEVEL]) (void);
118 static Ecore_Idle_Enterer *_idle_before = NULL;
119 static Ecore_Idle_Enterer *_idle_after = NULL;
121 static Eina_List *hooks = NULL;
123 static int _e_main_hooks_delete = 0;
124 static int _e_main_hooks_walking = 0;
126 static Eina_Inlist *_e_main_hooks[] =
128 [E_MAIN_HOOK_MODULE_LOAD_DONE] = NULL,
129 [E_MAIN_HOOK_E_INFO_READY] = NULL
132 /* external variables */
133 E_API Eina_Bool e_precache_end = EINA_FALSE;
134 E_API Eina_Bool good = EINA_FALSE;
135 E_API Eina_Bool evil = EINA_FALSE;
136 E_API Eina_Bool starting = EINA_TRUE;
137 E_API Eina_Bool stopping = EINA_FALSE;
138 E_API Eina_Bool e_nopause = EINA_FALSE;
141 _xdg_check_str(const char *env, const char *str)
147 for (p = strstr(env, str); p; p++, p = strstr(p, str))
149 if ((!p[len]) || (p[len] == ':')) return EINA_TRUE;
155 _xdg_data_dirs_augment(void)
158 const char *p = e_prefix_get();
159 char newpath[4096], buf[4096];
163 s = e_util_env_get("XDG_DATA_DIRS");
166 Eina_Bool pfxdata, pfx;
168 pfxdata = !_xdg_check_str(s, e_prefix_data_get());
169 snprintf(newpath, sizeof(newpath), "%s/share", p);
170 pfx = !_xdg_check_str(s, newpath);
173 snprintf(buf, sizeof(buf), "%s%s%s%s%s",
174 pfxdata ? e_prefix_data_get() : "",
179 e_util_env_set("XDG_DATA_DIRS", buf);
185 snprintf(buf, sizeof(buf), "%s:%s/share:/usr/local/share:/usr/share", e_prefix_data_get(), p);
186 e_util_env_set("XDG_DATA_DIRS", buf);
189 s = e_util_env_get("XDG_CONFIG_DIRS");
190 snprintf(newpath, sizeof(newpath), "%s/etc/xdg", p);
193 if (!_xdg_check_str(s, newpath))
195 snprintf(buf, sizeof(buf), "%s:%s", newpath, s);
196 e_util_env_set("XDG_CONFIG_DIRS", buf);
202 snprintf(buf, sizeof(buf), "%s:/etc/xdg", newpath);
203 e_util_env_set("XDG_CONFIG_DIRS", buf);
206 s = e_util_env_get("XDG_RUNTIME_DIR");
213 snprintf(buf, sizeof(buf), "/tmp/xdg-XXXXXX");
215 if (!dir) dir = "/tmp";
218 e_util_env_set("XDG_RUNTIME_DIR", dir);
219 snprintf(buf, sizeof(buf), "%s/.e-deleteme", dir);
220 ecore_file_mkdir(buf);
224 /* set menu prefix so we get our e menu */
225 s = e_util_env_get("XDG_MENU_PREFIX");
229 e_util_env_set("XDG_MENU_PREFIX", "e-");
233 _e_main_subsystem_defer(void *data EINA_UNUSED)
238 TRACE_DS_BEGIN(MAIN:SUBSYSTEMS DEFER);
240 ecore_app_args_get(&argc, &argv);
242 /* try to init delayed subsystems */
244 TRACE_DS_BEGIN(MAIN:DEFERRED INTERNAL SUBSYSTEMS INIT);
246 TSB("[DEFERRED] DPMS Init");
249 e_error_message_show(_("Enlightenment cannot set up dpms.\n"));
252 TSE("[DEFERRED] DPMS Init Done");
253 _e_main_shutdown_push(e_dpms_shutdown);
255 TSB("[DEFERRED] Screens Init: win");
258 e_error_message_show(_("Enlightenment cannot setup elementary trap!\n"));
261 TSE("[DEFERRED] Screens Init: win Done");
263 TSB("[DEFERRED] E_Dnd Init");
266 e_error_message_show(_("Enlightenment cannot set up its dnd system.\n"));
269 TSE("[DEFERRED] E_Dnd Init Done");
270 _e_main_shutdown_push(e_dnd_shutdown);
272 TSB("[DEFERRED] E_Scale Init");
275 e_error_message_show(_("Enlightenment cannot set up its scale system.\n"));
278 TSE("[DEFERRED] E_Scale Init Done");
279 _e_main_shutdown_push(e_scale_shutdown);
281 TSB("[DEFERRED] E_Test_Helper Init");
282 e_test_helper_init();
283 _e_main_shutdown_push(e_test_helper_shutdown);
284 TSE("[DEFERRED] E_Test_Helper Done");
286 TSB("[DEFERRED] E_INFO_SERVER Init");
287 e_info_server_init();
288 _e_main_shutdown_push(e_info_server_shutdown);
289 TSE("[DEFERRED] E_INFO_SERVER Done");
292 TRACE_DS_BEGIN(MAIN:DEFERRED COMP JOB);
294 /* try to do deferred job of any subsystems*/
295 TSB("[DEFERRED] Compositor's deferred job");
296 e_comp_deferred_job();
297 TSE("[DEFERRED] Compositor's deferred job Done");
299 if (e_config->use_e_policy)
301 TSB("[DEFERRED] E_Policy's deferred job");
302 e_policy_deferred_job();
303 TSE("[DEFERRED] E_Policy's deferred job Done");
306 TSB("[DEFERRED] E_Module's deferred job");
307 e_module_deferred_job();
308 TSE("[DEFERRED] E_Module's deferred job Done");
312 return ECORE_CALLBACK_DONE;
318 _e_main_shutdown(-1);
319 return ECORE_CALLBACK_DONE;
323 _e_main_deferred_job_schedule(void *d EINA_UNUSED, int type EINA_UNUSED, void *ev EINA_UNUSED)
325 PRCTL("[Winsys] all modules loaded");
326 ecore_idler_add(_e_main_subsystem_defer, NULL);
327 return ECORE_CALLBACK_DONE;
330 /* externally accessible functions */
332 main(int argc, char **argv)
335 struct sigaction action;
338 # ifdef PR_SET_PTRACER
339 # ifdef PR_SET_PTRACER_ANY
340 prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY);
345 t0 = t1 = t2 = ecore_time_unix_get();
346 printf("ESTART(main) %1.5f\n", t0);
348 TRACE_DS_BEGIN(MAIN:BEGIN STARTUP);
349 TSB("Begin Startup");
350 PRCTL("[Winsys] start of main");
352 /* trap deadly bug signals and allow some form of sane recovery */
353 /* or ability to gdb attach and debug at this point - better than your */
354 /* wm/desktop vanishing and not knowing what happened */
356 /* don't install SIGBUS handler */
357 /* Wayland shm sets up a sigbus handler for catching invalid shm region */
358 /* access. If we setup our sigbus handler here, then the wl-shm sigbus */
359 /* handler will not function properly */
360 s = e_util_env_get("NOTIFY_SOCKET");
366 action.sa_sigaction = e_sigseg_act;
367 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
368 sigemptyset(&action.sa_mask);
369 sigaction(SIGSEGV, &action, NULL);
371 action.sa_sigaction = e_sigill_act;
372 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
373 sigemptyset(&action.sa_mask);
374 sigaction(SIGILL, &action, NULL);
376 action.sa_sigaction = e_sigfpe_act;
377 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
378 sigemptyset(&action.sa_mask);
379 sigaction(SIGFPE, &action, NULL);
381 action.sa_sigaction = e_sigabrt_act;
382 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
383 sigemptyset(&action.sa_mask);
384 sigaction(SIGABRT, &action, NULL);
385 TSE("Signal Trap Done");
391 e_error_message_show(_("Enlightenment cannot initialize Eina!\n"));
394 TSE("Eina Init Done");
395 _e_main_shutdown_push(eina_shutdown);
397 #ifdef OBJECT_HASH_CHECK
398 TSB("E_Object Hash Init");
399 e_object_hash_init();
400 TSE("E_Object Hash Init Done");
406 e_error_message_show(_("Enlightenment could not create a logging domain!\n"));
409 TSE("E_Log Init Done");
410 _e_main_shutdown_push(e_log_shutdown);
412 TSB("Determine Prefix");
413 if (!e_prefix_determine(argv[0]))
416 "ERROR: Enlightenment cannot determine it's installed\n"
417 " prefix from the system or argv[0].\n"
418 " This is because it is not on Linux AND has been\n"
419 " executed strangely. This is unusual.\n");
421 TSE("Determine Prefix Done");
423 /* for debugging by redirecting stdout of e to a log file to tail */
424 setvbuf(stdout, NULL, _IONBF, 0);
426 TSB("Parse Arguments");
427 _e_main_parse_arguments(argc, argv);
428 TSE("Parse Arguments Done");
430 /*** Initialize Core EFL Libraries We Need ***/
435 e_error_message_show(_("Enlightenment cannot initialize Eet!\n"));
438 TSE("Eet Init Done");
439 _e_main_shutdown_push(eet_shutdown);
441 /* Allow ecore to not load system modules.
442 * Without it ecore_init will block until dbus authentication
443 * and registration are complete.
445 ecore_app_no_system_modules();
450 e_error_message_show(_("Enlightenment cannot initialize Ecore!\n"));
453 TSE("Ecore Init Done");
454 _e_main_shutdown_push(ecore_shutdown);
459 e_error_message_show(_("Enlightenment cannot initialize EIO!\n"));
462 TSE("EIO Init Done");
463 _e_main_shutdown_push(eio_shutdown);
465 ecore_app_args_set(argc, (const char **)argv);
467 TSB("Ecore Event Handlers");
468 if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT,
469 _e_main_cb_signal_exit, NULL))
471 e_error_message_show(_("Enlightenment cannot set up an exit signal handler.\n"
472 "Perhaps you are out of memory?"));
475 if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_HUP,
476 _e_main_cb_signal_hup, NULL))
478 e_error_message_show(_("Enlightenment cannot set up a HUP signal handler.\n"
479 "Perhaps you are out of memory?"));
482 if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
483 _e_main_cb_signal_user, NULL))
485 e_error_message_show(_("Enlightenment cannot set up a USER signal handler.\n"
486 "Perhaps you are out of memory?"));
489 TSE("Ecore Event Handlers Done");
491 TSB("Ecore_File Init");
492 if (!ecore_file_init())
494 e_error_message_show(_("Enlightenment cannot initialize Ecore_File!\n"));
497 TSE("Ecore_File Init Done");
498 _e_main_shutdown_push(ecore_file_shutdown);
500 _idle_before = ecore_idle_enterer_before_add(_e_main_cb_idle_before, NULL);
502 TSB("XDG_DATA_DIRS Init");
503 _xdg_data_dirs_augment();
504 TSE("XDG_DATA_DIRS Init Done");
506 TSB("Ecore_Evas Init");
507 if (!ecore_evas_init())
509 e_error_message_show(_("Enlightenment cannot initialize Ecore_Evas!\n"));
512 TSE("Ecore_Evas Init Done");
514 /* e doesn't sync to compositor - it should be one */
515 ecore_evas_app_comp_sync_set(0);
520 e_error_message_show(_("Enlightenment cannot initialize Edje!\n"));
523 TSE("Edje Init Done");
524 _e_main_shutdown_push(edje_shutdown);
526 /*** Initialize E Subsystems We Need ***/
531 e_error_message_show(_("Enlightenment cannot set up user home path\n"));
534 TSE("E User Init Done");
535 _e_main_shutdown_push(e_user_shutdown);
537 TSB("E Directories Init");
538 /* setup directories we will be using for configurations storage etc. */
539 if (!_e_main_dirs_init())
541 e_error_message_show(_("Enlightenment cannot create directories in your home directory.\n"
542 "Perhaps you have no home directory or the disk is full?"));
545 TSE("E Directories Init Done");
546 _e_main_shutdown_push(_e_main_dirs_shutdown);
548 TSB("E_Config Init");
549 if (!e_config_init())
551 e_error_message_show(_("Enlightenment cannot set up its config system.\n"));
554 TSE("E_Config Init Done");
555 _e_main_shutdown_push(e_config_shutdown);
560 e_error_message_show(_("Enlightenment cannot set up its environment.\n"));
563 TSE("E_Env Init Done");
564 _e_main_shutdown_push(e_env_shutdown);
566 ecore_exe_run_priority_set(e_config->priority);
569 if (!_e_main_path_init())
571 e_error_message_show(_("Enlightenment cannot set up paths for finding files.\n"
572 "Perhaps you are out of memory?"));
575 TSE("E Paths Init Done");
576 _e_main_shutdown_push(_e_main_path_shutdown);
578 ecore_animator_frametime_set(1.0 / e_config->framerate);
583 e_error_message_show(_("Enlightenment cannot set up its theme system.\n"));
586 TSE("E_Theme Init Done");
587 _e_main_shutdown_push(e_theme_shutdown);
589 TSB("E_Actions Init");
590 if (!e_actions_init())
592 e_error_message_show(_("Enlightenment cannot set up its actions system.\n"));
595 TSE("E_Actions Init Done");
596 _e_main_shutdown_push(e_actions_shutdown);
598 /* these just add event handlers and can't fail
599 * timestamping them is dumb.
601 e_screensaver_preinit();
606 TRACE_DS_BEGIN(MAIN:WAIT /dev/dri/card0);
607 if (e_config->sleep_for_dri)
609 while(access("/dev/dri/card0", F_OK) != 0)
611 struct timespec req, rem;
613 req.tv_nsec = 50000000L;
614 nanosleep(&req, &rem);
619 e_module_event_init();
621 TSB("E_Pointer Init");
622 if (!e_pointer_init())
624 e_error_message_show(_("Enlightenment cannot set up its pointer system.\n"));
627 TSE("E_Pointer Init Done");
628 _e_main_shutdown_push(e_pointer_shutdown);
630 TRACE_DS_BEGIN(MAIN:SCREEN INIT);
632 if (!_e_main_screens_init())
634 e_error_message_show(_("Enlightenment set up window management for all the screens on your system\n"
635 "failed. Perhaps another window manager is running?\n"));
638 TSE("Screens Init Done");
639 _e_main_shutdown_push(_e_main_screens_shutdown);
642 TSB("E_Keyrouter Init");
643 if (!e_keyrouter_init())
645 e_error_message_show(_("Enlightenment cannot set up its keyrouting system.\n"));
648 TSE("E_Keyrouter Init Done");
649 _e_main_shutdown_push(e_keyrouter_shutdown);
651 if (e_config->eom_enable)
656 e_error_message_show(_("Enlightenment cannot set up eom.\n"));
659 TSE("Eom Init Done");
660 _e_main_shutdown_push(e_eom_shutdown);
663 TSB("E_Screensaver Init");
664 if (!e_screensaver_init())
666 e_error_message_show(_("Enlightenment cannot configure the X screensaver.\n"));
669 TSE("E_Screensaver Init Done");
670 _e_main_shutdown_push(e_screensaver_shutdown);
672 TSB("E_Comp Freeze");
674 TSE("E_Comp Freeze Done");
676 TSB("E_Grabinput Init");
677 if (!e_grabinput_init())
679 e_error_message_show(_("Enlightenment cannot set up its grab input handling system.\n"));
682 TSE("E_Grabinput Init Done");
683 _e_main_shutdown_push(e_grabinput_shutdown);
685 TS("E_Gesture Init");
687 _e_main_shutdown_push(e_gesture_shutdown);
689 ecore_event_handler_add(E_EVENT_MODULE_INIT_END, _e_main_deferred_job_schedule, NULL);
691 TSB("E_Module Init");
692 if (!e_module_init())
694 e_error_message_show(_("Enlightenment cannot set up its module system.\n"));
697 TSE("E_Module Init Done");
698 _e_main_shutdown_push(e_module_shutdown);
701 if (!e_mouse_update())
703 e_error_message_show(_("Enlightenment cannot configure the mouse settings.\n"));
706 TSE("E_Mouse Init Done");
711 e_error_message_show(_("Enlightenment cannot initialize the Icon Cache system.\n"));
714 TSE("E_Icon Init Done");
715 _e_main_shutdown_push(e_icon_shutdown);
717 if (e_config->use_e_policy)
719 TSB("E_Policy Init");
720 if (!e_policy_init())
722 e_error_message_show(_("Enlightenment cannot setup policy system!\n"));
725 TSE("E_Policy Init Done");
726 _e_main_shutdown_push(e_policy_shutdown);
729 TSB("E_Process Init");
730 if (!e_process_init())
732 e_error_message_show(_("Enlightenment cannot setup process managing system!\n"));
735 TSE("E_Process Init Done");
736 _e_main_shutdown_push(e_process_shutdown);
738 TSB("E_Security Init");
739 if (!e_security_init())
741 e_error_message_show(_("Enlightenment cannot setup security system!\n"));
744 TSE("E_Security Init Done");
745 _e_main_shutdown_push(e_security_shutdown);
749 TSE("Load Modules Done");
753 TSE("E_Comp Thaw Done");
755 _idle_after = ecore_idle_enterer_add(_e_main_cb_idle_after, NULL);
757 starting = EINA_FALSE;
760 e_util_env_set("E_RESTART", "1");
762 TSM("MAIN LOOP AT LAST");
764 if (e_config->create_wm_ready)
765 _e_main_create_wm_ready();
770 TSM("[WM] Send start-up completion");
771 sd_notify(0, "READY=1");
773 TSM("[WM] Skip sending start-up completion. (no systemd)");
775 ecore_main_loop_begin();
779 ELOGF("COMP", "STOPPING enlightenment...", NULL, NULL);
780 stopping = EINA_TRUE;
783 e_comp_internal_save();
794 _e_main_shutdown(-1);
798 e_main_ts(const char *str)
801 t1 = ecore_time_unix_get();
802 printf("ESTART: %1.5f [%1.5f] - %s\n", t1 - t0, t1 - t2, str);
809 e_main_ts_begin(const char *str)
811 TRACE_DS_BEGIN(ESTART: %s, str);
812 return e_main_ts(str);
816 e_main_ts_end(const char *str)
819 return e_main_ts(str);
822 /* local functions */
824 _e_main_shutdown(int errcode)
830 printf("E: Begin Shutdown Procedure!\n");
832 E_FREE_LIST(hooks, e_main_hook_del);
834 if (_idle_before) ecore_idle_enterer_del(_idle_before);
836 if (_idle_after) ecore_idle_enterer_del(_idle_after);
839 dir = e_util_env_get("XDG_RUNTIME_DIR");
842 char buf_env[PATH_MAX];
843 snprintf(buf_env, sizeof(buf_env), "%s", dir);
844 snprintf(buf, sizeof(buf), "%s/.e-deleteme", buf_env);
845 if (ecore_file_exists(buf)) ecore_file_recursive_rm(buf_env);
848 for (i = (_e_main_lvl - 1); i >= 0; i--)
849 (*_e_main_shutdown_func[i])();
850 #ifdef OBJECT_HASH_CHECK
851 e_object_hash_shutdown();
853 if (errcode < 0) exit(errcode);
857 _e_main_shutdown_push(int (*func)(void))
860 if (_e_main_lvl > MAX_LEVEL)
863 e_error_message_show("WARNING: too many init levels. MAX = %i\n",
867 _e_main_shutdown_func[_e_main_lvl - 1] = func;
871 _e_main_parse_arguments(int argc, char **argv)
875 /* handle some command-line parameters */
876 for (i = 1; i < argc; i++)
878 if (!strcmp(argv[i], "-good"))
882 printf("LA LA LA\n");
884 else if (!strcmp(argv[i], "-evil"))
888 printf("MUHAHAHAHHAHAHAHAHA\n");
890 else if (!strcmp(argv[i], "-psychotic"))
894 printf("MUHAHALALALALALALALA\n");
896 else if ((!strcmp(argv[i], "-profile")) && (i < (argc - 1)))
899 if (!getenv("E_CONF_PROFILE"))
900 e_util_env_set("E_CONF_PROFILE", argv[i]);
902 else if (!strcmp(argv[i], "-i-really-know-what-i-am-doing-and-accept-full-responsibility-for-it"))
903 really_know = EINA_TRUE;
904 else if (!strcmp(argv[i], "-nopause"))
905 e_nopause = EINA_TRUE;
906 else if ((!strcmp(argv[i], "-version")) ||
907 (!strcmp(argv[i], "--version")))
909 printf(_("Version: %s\n"), PACKAGE_VERSION);
910 _e_main_shutdown(-1);
912 else if ((!strcmp(argv[i], "-h")) ||
913 (!strcmp(argv[i], "-help")) ||
914 (!strcmp(argv[i], "--help")))
919 "\t-display DISPLAY\n"
920 "\t\tConnect to display named DISPLAY.\n"
921 "\t\tEG: -display :1.0\n"
922 "\t-fake-xinerama-screen WxH+X+Y\n"
923 "\t\tAdd a FAKE xinerama screen (instead of the real ones)\n"
924 "\t\tgiven the geometry. Add as many as you like. They all\n"
925 "\t\treplace the real xinerama screens, if any. This can\n"
926 "\t\tbe used to simulate xinerama.\n"
927 "\t\tEG: -fake-xinerama-screen 800x600+0+0 -fake-xinerama-screen 800x600+800+0\n"
928 "\t-profile CONF_PROFILE\n"
929 "\t\tUse the configuration profile CONF_PROFILE instead of the user selected default or just \"default\".\n"
935 "\t\tBe psychotic.\n"
936 "\t-i-really-know-what-i-am-doing-and-accept-full-responsibility-for-it\n"
937 "\t\tIf you need this help, you don't need this option.\n"
941 _e_main_shutdown(-1);
947 _e_main_cb_signal_exit(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
949 /* called on ctrl-c, kill (pid) (also SIGINT, SIGTERM and SIGQIT) */
950 ecore_main_loop_quit();
951 return ECORE_CALLBACK_RENEW;
955 _e_main_cb_signal_hup(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
957 ecore_main_loop_quit();
958 return ECORE_CALLBACK_RENEW;
962 _e_main_cb_signal_user(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev)
964 Ecore_Event_Signal_User *e = ev;
968 // E_Action *a = e_action_find("configuration");
969 // if ((a) && (a->func.go)) a->func.go(NULL, NULL);
971 else if (e->number == 2)
973 // comp module has its own handler for this for enabling/disabling fps debug
975 return ECORE_CALLBACK_RENEW;
980 _e_main_dirs_init(void)
982 if(getenv("E_CONF_RO"))
996 base = e_user_dir_get();
997 if (ecore_file_mksubdirs(base, dirs) != sizeof(dirs) / sizeof(dirs[0]) - 1)
999 e_error_message_show("Could not create one of the required "
1000 "subdirectories of '%s'\n", base);
1008 _e_main_dirs_shutdown(void)
1014 _e_main_path_init(void)
1018 /* setup data paths */
1019 path_data = e_path_new();
1022 e_error_message_show("Cannot allocate path for path_data\n");
1025 e_prefix_data_concat_static(buf, "data");
1026 e_path_default_path_append(path_data, buf);
1028 /* setup image paths */
1029 path_images = e_path_new();
1032 e_error_message_show("Cannot allocate path for path_images\n");
1035 e_user_dir_concat_static(buf, "/images");
1036 e_path_default_path_append(path_images, buf);
1037 e_prefix_data_concat_static(buf, "data/images");
1038 e_path_default_path_append(path_images, buf);
1040 /* setup font paths */
1041 path_fonts = e_path_new();
1044 e_error_message_show("Cannot allocate path for path_fonts\n");
1047 e_user_dir_concat_static(buf, "/fonts");
1048 e_path_default_path_append(path_fonts, buf);
1049 e_prefix_data_concat_static(buf, "data/fonts");
1050 e_path_default_path_append(path_fonts, buf);
1052 /* setup icon paths */
1053 path_icons = e_path_new();
1056 e_error_message_show("Cannot allocate path for path_icons\n");
1059 e_user_dir_concat_static(buf, "/icons");
1060 e_path_default_path_append(path_icons, buf);
1061 e_prefix_data_concat_static(buf, "data/icons");
1062 e_path_default_path_append(path_icons, buf);
1064 /* setup module paths */
1065 path_modules = e_path_new();
1068 e_error_message_show("Cannot allocate path for path_modules\n");
1071 e_user_dir_concat_static(buf, "/modules");
1072 e_path_default_path_append(path_modules, buf);
1073 snprintf(buf, sizeof(buf), "%s/enlightenment/modules", e_prefix_lib_get());
1074 e_path_default_path_append(path_modules, buf);
1075 /* FIXME: eventually this has to go - moduels should have installers that
1076 * add appropriate install paths (if not installed to user homedir) to
1077 * e's module search dirs
1079 snprintf(buf, sizeof(buf), "%s/enlightenment/modules_extra", e_prefix_lib_get());
1080 e_path_default_path_append(path_modules, buf);
1082 /* setup background paths */
1083 path_backgrounds = e_path_new();
1084 if (!path_backgrounds)
1086 e_error_message_show("Cannot allocate path for path_backgrounds\n");
1089 e_user_dir_concat_static(buf, "/backgrounds");
1090 e_path_default_path_append(path_backgrounds, buf);
1091 e_prefix_data_concat_static(buf, "data/backgrounds");
1092 e_path_default_path_append(path_backgrounds, buf);
1094 path_messages = e_path_new();
1097 e_error_message_show("Cannot allocate path for path_messages\n");
1100 e_user_dir_concat_static(buf, "/locale");
1101 e_path_default_path_append(path_messages, buf);
1102 e_path_default_path_append(path_messages, e_prefix_locale_get());
1108 _e_main_path_shutdown(void)
1112 e_object_del(E_OBJECT(path_data));
1117 e_object_del(E_OBJECT(path_images));
1122 e_object_del(E_OBJECT(path_fonts));
1127 e_object_del(E_OBJECT(path_icons));
1132 e_object_del(E_OBJECT(path_modules));
1133 path_modules = NULL;
1135 if (path_backgrounds)
1137 e_object_del(E_OBJECT(path_backgrounds));
1138 path_backgrounds = NULL;
1142 e_object_del(E_OBJECT(path_messages));
1143 path_messages = NULL;
1149 _e_main_screens_init(void)
1151 TSB("\tscreens: client");
1152 if (!e_client_init()) return 0;
1153 TSE("\tscreens: client Done");
1155 TSB("Compositor Init");
1156 PRCTL("[Winsys] start of compositor init");
1159 e_error_message_show(_("Enlightenment cannot create a compositor.\n"));
1160 _e_main_shutdown(-1);
1162 TSE("Compositor Init Done");
1164 PRCTL("[Winsys] end of compositor init");
1165 _e_main_desk_restore();
1171 _e_main_screens_shutdown(void)
1175 e_client_shutdown();
1184 _e_main_desk_save(void)
1187 char env[1024], name[1024];
1190 EINA_LIST_FOREACH(e_comp->zones, l, zone)
1192 snprintf(name, sizeof(name), "DESK_%d_%d", 0, zone->num);
1193 snprintf(env, sizeof(env), "%d,%d", zone->desk_x_current, zone->desk_y_current);
1194 e_util_env_set(name, env);
1199 _e_main_desk_restore(void)
1203 E_CLIENT_REVERSE_FOREACH(ec)
1204 if ((!e_client_util_ignored_get(ec)) && e_client_util_desk_visible(ec, e_desk_current_get(ec->zone)))
1206 ec->want_focus = ec->take_focus = 1;
1212 _e_main_cb_idle_before(void *data EINA_UNUSED)
1214 e_client_idler_before();
1216 return ECORE_CALLBACK_RENEW;
1220 _e_main_cb_idle_after(void *data EINA_UNUSED)
1222 static int first_idle = 1;
1227 #ifdef E_RELEASE_BUILD
1232 e_precache_end = EINA_TRUE;
1235 if (first_idle++ < 60)
1239 e_precache_end = EINA_TRUE;
1243 return ECORE_CALLBACK_RENEW;
1247 _e_main_create_wm_ready(void)
1249 FILE *_wmready_checker = NULL;
1250 const char *path_wm_ready = "/run/.wm_ready";
1252 if (!e_util_file_realpath_check(path_wm_ready, EINA_TRUE))
1254 WRN("%s is maybe link, so delete it\n", path_wm_ready);
1257 _wmready_checker = fopen(path_wm_ready, "wb");
1258 if (_wmready_checker)
1260 TSM("[WM] WINDOW MANAGER is READY!!!");
1261 PRCTL("[Winsys] WINDOW MANAGER is READY!!!");
1262 fclose(_wmready_checker);
1264 /*TODO: Next lines should be removed. */
1265 FILE *_tmp_wm_ready_checker;
1267 _tmp_wm_ready_checker = fopen(path_wm_ready, "wb");
1269 if (_tmp_wm_ready_checker)
1271 TSM("[WM] temporary wm_ready path is created.");
1272 PRCTL("[Winsys] temporary wm_ready path is created.");
1273 fclose(_tmp_wm_ready_checker);
1277 TSM("[WM] temporary wm_ready path create failed.");
1278 PRCTL("[Winsys] temporary wm_ready path create failed.");
1283 TSM("[WM] WINDOW MANAGER is READY. BUT, failed to create .wm_ready file.");
1284 PRCTL("[Winsys] WINDOW MANAGER is READY. BUT, failed to create .wm_ready file.");
1289 _e_main_hooks_clean(void)
1295 for (x = 0; x < E_MAIN_HOOK_LAST; x++)
1296 EINA_INLIST_FOREACH_SAFE(_e_main_hooks[x], l, mh)
1298 if (!mh->delete_me) continue;
1299 _e_main_hooks[x] = eina_inlist_remove(_e_main_hooks[x],
1300 EINA_INLIST_GET(mh));
1306 _e_main_hook_call(E_Main_Hook_Point hookpoint, void *data EINA_UNUSED)
1310 _e_main_hooks_walking++;
1311 EINA_INLIST_FOREACH(_e_main_hooks[hookpoint], mh)
1313 if (mh->delete_me) continue;
1316 _e_main_hooks_walking--;
1317 if ((_e_main_hooks_walking == 0) && (_e_main_hooks_delete > 0))
1318 _e_main_hooks_clean();
1322 e_main_hook_add(E_Main_Hook_Point hookpoint, E_Main_Hook_Cb func, const void *data)
1326 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_MAIN_HOOK_LAST, NULL);
1327 mh = E_NEW(E_Main_Hook, 1);
1328 EINA_SAFETY_ON_NULL_RETURN_VAL(mh, NULL);
1329 mh->hookpoint = hookpoint;
1331 mh->data = (void*)data;
1332 _e_main_hooks[hookpoint] = eina_inlist_append(_e_main_hooks[hookpoint],
1333 EINA_INLIST_GET(mh));
1338 e_main_hook_del(E_Main_Hook *mh)
1341 if (_e_main_hooks_walking == 0)
1343 _e_main_hooks[mh->hookpoint] = eina_inlist_remove(_e_main_hooks[mh->hookpoint],
1344 EINA_INLIST_GET(mh));
1348 _e_main_hooks_delete++;
1352 e_main_hook_call(E_Main_Hook_Point hookpoint)
1354 if ((hookpoint < 0) || (hookpoint >= E_MAIN_HOOK_LAST)) return;
1356 _e_main_hook_call(hookpoint, NULL);