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 inloop = EINA_FALSE;
114 static int _e_main_lvl = 0;
115 static int(*_e_main_shutdown_func[MAX_LEVEL]) (void);
117 static Ecore_Idle_Enterer *_idle_before = NULL;
118 static Ecore_Idle_Enterer *_idle_after = NULL;
120 static Eina_List *hooks = NULL;
122 static int _e_main_hooks_delete = 0;
123 static int _e_main_hooks_walking = 0;
125 static Eina_Inlist *_e_main_hooks[] =
127 [E_MAIN_HOOK_MODULE_LOAD_DONE] = NULL,
128 [E_MAIN_HOOK_E_INFO_READY] = NULL
131 /* external variables */
132 E_API Eina_Bool e_precache_end = EINA_FALSE;
133 E_API Eina_Bool good = EINA_FALSE;
134 E_API Eina_Bool evil = EINA_FALSE;
135 E_API Eina_Bool starting = EINA_TRUE;
136 E_API Eina_Bool stopping = EINA_FALSE;
137 E_API Eina_Bool e_nopause = EINA_FALSE;
140 _xdg_check_str(const char *env, const char *str)
146 for (p = strstr(env, str); p; p++, p = strstr(p, str))
148 if ((!p[len]) || (p[len] == ':')) return EINA_TRUE;
154 _xdg_data_dirs_augment(void)
157 const char *p = e_prefix_get();
158 char newpath[4096], buf[4096];
162 s = e_util_env_get("XDG_DATA_DIRS");
165 Eina_Bool pfxdata, pfx;
167 pfxdata = !_xdg_check_str(s, e_prefix_data_get());
168 snprintf(newpath, sizeof(newpath), "%s/share", p);
169 pfx = !_xdg_check_str(s, newpath);
172 snprintf(buf, sizeof(buf), "%s%s%s%s%s",
173 pfxdata ? e_prefix_data_get() : "",
178 e_util_env_set("XDG_DATA_DIRS", buf);
184 snprintf(buf, sizeof(buf), "%s:%s/share:/usr/local/share:/usr/share", e_prefix_data_get(), p);
185 e_util_env_set("XDG_DATA_DIRS", buf);
188 s = e_util_env_get("XDG_CONFIG_DIRS");
189 snprintf(newpath, sizeof(newpath), "%s/etc/xdg", p);
192 if (!_xdg_check_str(s, newpath))
194 snprintf(buf, sizeof(buf), "%s:%s", newpath, s);
195 e_util_env_set("XDG_CONFIG_DIRS", buf);
201 snprintf(buf, sizeof(buf), "%s:/etc/xdg", newpath);
202 e_util_env_set("XDG_CONFIG_DIRS", buf);
205 s = e_util_env_get("XDG_RUNTIME_DIR");
212 snprintf(buf, sizeof(buf), "/tmp/xdg-XXXXXX");
214 if (!dir) dir = "/tmp";
217 e_util_env_set("XDG_RUNTIME_DIR", dir);
218 snprintf(buf, sizeof(buf), "%s/.e-deleteme", dir);
219 ecore_file_mkdir(buf);
223 /* set menu prefix so we get our e menu */
224 s = e_util_env_get("XDG_MENU_PREFIX");
228 e_util_env_set("XDG_MENU_PREFIX", "e-");
232 _e_main_subsystem_defer(void *data EINA_UNUSED)
237 TRACE_DS_BEGIN(MAIN:SUBSYSTEMS DEFER);
239 ecore_app_args_get(&argc, &argv);
241 /* try to init delayed subsystems */
243 TRACE_DS_BEGIN(MAIN:DEFERRED INTERNAL SUBSYSTEMS INIT);
245 TSB("[DEFERRED] DPMS Init");
248 e_error_message_show(_("Enlightenment cannot set up dpms.\n"));
251 TSE("[DEFERRED] DPMS Init Done");
252 _e_main_shutdown_push(e_dpms_shutdown);
254 TSB("[DEFERRED] Screens Init: win");
257 e_error_message_show(_("Enlightenment cannot setup elementary trap!\n"));
260 TSE("[DEFERRED] Screens Init: win Done");
262 TSB("[DEFERRED] E_Dnd Init");
265 e_error_message_show(_("Enlightenment cannot set up its dnd system.\n"));
268 TSE("[DEFERRED] E_Dnd Init Done");
269 _e_main_shutdown_push(e_dnd_shutdown);
271 TSB("[DEFERRED] E_Scale Init");
274 e_error_message_show(_("Enlightenment cannot set up its scale system.\n"));
277 TSE("[DEFERRED] E_Scale Init Done");
278 _e_main_shutdown_push(e_scale_shutdown);
280 TSB("[DEFERRED] E_Test_Helper Init");
281 e_test_helper_init();
282 _e_main_shutdown_push(e_test_helper_shutdown);
283 TSE("[DEFERRED] E_Test_Helper Done");
285 TSB("[DEFERRED] E_INFO_SERVER Init");
286 e_info_server_init();
287 _e_main_shutdown_push(e_info_server_shutdown);
288 TSE("[DEFERRED] E_INFO_SERVER Done");
291 TRACE_DS_BEGIN(MAIN:DEFERRED COMP JOB);
293 /* try to do deferred job of any subsystems*/
294 TSB("[DEFERRED] Compositor's deferred job");
295 e_comp_deferred_job();
296 TSE("[DEFERRED] Compositor's deferred job Done");
298 if (e_config->use_e_policy)
300 TSB("[DEFERRED] E_Policy's deferred job");
301 e_policy_deferred_job();
302 TSE("[DEFERRED] E_Policy's deferred job Done");
305 TSB("[DEFERRED] E_Module's deferred job");
306 e_module_deferred_job();
307 TSE("[DEFERRED] E_Module's deferred job Done");
311 return ECORE_CALLBACK_DONE;
317 _e_main_shutdown(-1);
318 return ECORE_CALLBACK_DONE;
322 _e_main_deferred_job_schedule(void *d EINA_UNUSED, int type EINA_UNUSED, void *ev EINA_UNUSED)
324 PRCTL("[Winsys] all modules loaded");
325 ecore_idler_add(_e_main_subsystem_defer, NULL);
326 return ECORE_CALLBACK_DONE;
329 /* externally accessible functions */
331 main(int argc, char **argv)
334 struct sigaction action;
337 # ifdef PR_SET_PTRACER
338 # ifdef PR_SET_PTRACER_ANY
339 prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY);
344 t0 = t1 = t2 = ecore_time_unix_get();
345 printf("ESTART(main) %1.5f\n", t0);
347 TRACE_DS_BEGIN(MAIN:BEGIN STARTUP);
348 TSB("Begin Startup");
349 PRCTL("[Winsys] start of main");
351 /* trap deadly bug signals and allow some form of sane recovery */
352 /* or ability to gdb attach and debug at this point - better than your */
353 /* wm/desktop vanishing and not knowing what happened */
355 /* don't install SIGBUS handler */
356 /* Wayland shm sets up a sigbus handler for catching invalid shm region */
357 /* access. If we setup our sigbus handler here, then the wl-shm sigbus */
358 /* handler will not function properly */
359 s = e_util_env_get("NOTIFY_SOCKET");
365 action.sa_sigaction = e_sigseg_act;
366 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
367 sigemptyset(&action.sa_mask);
368 sigaction(SIGSEGV, &action, NULL);
370 action.sa_sigaction = e_sigill_act;
371 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
372 sigemptyset(&action.sa_mask);
373 sigaction(SIGILL, &action, NULL);
375 action.sa_sigaction = e_sigfpe_act;
376 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
377 sigemptyset(&action.sa_mask);
378 sigaction(SIGFPE, &action, NULL);
380 action.sa_sigaction = e_sigabrt_act;
381 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
382 sigemptyset(&action.sa_mask);
383 sigaction(SIGABRT, &action, NULL);
384 TSE("Signal Trap Done");
390 e_error_message_show(_("Enlightenment cannot initialize Eina!\n"));
393 TSE("Eina Init Done");
394 _e_main_shutdown_push(eina_shutdown);
396 #ifdef OBJECT_HASH_CHECK
397 TSB("E_Object Hash Init");
398 e_object_hash_init();
399 TSE("E_Object Hash Init Done");
405 e_error_message_show(_("Enlightenment could not create a logging domain!\n"));
408 TSE("E_Log Init Done");
409 _e_main_shutdown_push(e_log_shutdown);
411 TSB("Determine Prefix");
412 if (!e_prefix_determine(argv[0]))
415 "ERROR: Enlightenment cannot determine it's installed\n"
416 " prefix from the system or argv[0].\n"
417 " This is because it is not on Linux AND has been\n"
418 " executed strangely. This is unusual.\n");
420 TSE("Determine Prefix Done");
422 /* for debugging by redirecting stdout of e to a log file to tail */
423 setvbuf(stdout, NULL, _IONBF, 0);
425 TSB("Parse Arguments");
426 _e_main_parse_arguments(argc, argv);
427 TSE("Parse Arguments Done");
429 /*** Initialize Core EFL Libraries We Need ***/
434 e_error_message_show(_("Enlightenment cannot initialize Eet!\n"));
437 TSE("Eet Init Done");
438 _e_main_shutdown_push(eet_shutdown);
440 /* Allow ecore to not load system modules.
441 * Without it ecore_init will block until dbus authentication
442 * and registration are complete.
444 ecore_app_no_system_modules();
449 e_error_message_show(_("Enlightenment cannot initialize Ecore!\n"));
452 TSE("Ecore Init Done");
453 _e_main_shutdown_push(ecore_shutdown);
458 e_error_message_show(_("Enlightenment cannot initialize EIO!\n"));
461 TSE("EIO Init Done");
462 _e_main_shutdown_push(eio_shutdown);
464 ecore_app_args_set(argc, (const char **)argv);
466 TSB("Ecore Event Handlers");
467 if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT,
468 _e_main_cb_signal_exit, NULL))
470 e_error_message_show(_("Enlightenment cannot set up an exit signal handler.\n"
471 "Perhaps you are out of memory?"));
474 if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_HUP,
475 _e_main_cb_signal_hup, NULL))
477 e_error_message_show(_("Enlightenment cannot set up a HUP signal handler.\n"
478 "Perhaps you are out of memory?"));
481 if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
482 _e_main_cb_signal_user, NULL))
484 e_error_message_show(_("Enlightenment cannot set up a USER signal handler.\n"
485 "Perhaps you are out of memory?"));
488 TSE("Ecore Event Handlers Done");
490 TSB("Ecore_File Init");
491 if (!ecore_file_init())
493 e_error_message_show(_("Enlightenment cannot initialize Ecore_File!\n"));
496 TSE("Ecore_File Init Done");
497 _e_main_shutdown_push(ecore_file_shutdown);
499 _idle_before = ecore_idle_enterer_before_add(_e_main_cb_idle_before, NULL);
501 TSB("XDG_DATA_DIRS Init");
502 _xdg_data_dirs_augment();
503 TSE("XDG_DATA_DIRS Init Done");
505 TSB("Ecore_Evas Init");
506 if (!ecore_evas_init())
508 e_error_message_show(_("Enlightenment cannot initialize Ecore_Evas!\n"));
511 TSE("Ecore_Evas Init Done");
513 /* e doesn't sync to compositor - it should be one */
514 ecore_evas_app_comp_sync_set(0);
519 e_error_message_show(_("Enlightenment cannot initialize Edje!\n"));
522 TSE("Edje Init Done");
523 _e_main_shutdown_push(edje_shutdown);
525 /*** Initialize E Subsystems We Need ***/
530 e_error_message_show(_("Enlightenment cannot set up user home path\n"));
533 TSE("E User Init Done");
534 _e_main_shutdown_push(e_user_shutdown);
536 TSB("E Directories Init");
537 /* setup directories we will be using for configurations storage etc. */
538 if (!_e_main_dirs_init())
540 e_error_message_show(_("Enlightenment cannot create directories in your home directory.\n"
541 "Perhaps you have no home directory or the disk is full?"));
544 TSE("E Directories Init Done");
545 _e_main_shutdown_push(_e_main_dirs_shutdown);
547 TSB("E_Config Init");
548 if (!e_config_init())
550 e_error_message_show(_("Enlightenment cannot set up its config system.\n"));
553 TSE("E_Config Init Done");
554 _e_main_shutdown_push(e_config_shutdown);
559 e_error_message_show(_("Enlightenment cannot set up its environment.\n"));
562 TSE("E_Env Init Done");
563 _e_main_shutdown_push(e_env_shutdown);
565 ecore_exe_run_priority_set(e_config->priority);
568 if (!_e_main_path_init())
570 e_error_message_show(_("Enlightenment cannot set up paths for finding files.\n"
571 "Perhaps you are out of memory?"));
574 TSE("E Paths Init Done");
575 _e_main_shutdown_push(_e_main_path_shutdown);
577 ecore_animator_frametime_set(1.0 / e_config->framerate);
582 e_error_message_show(_("Enlightenment cannot set up its theme system.\n"));
585 TSE("E_Theme Init Done");
586 _e_main_shutdown_push(e_theme_shutdown);
588 TSB("E_Actions Init");
589 if (!e_actions_init())
591 e_error_message_show(_("Enlightenment cannot set up its actions system.\n"));
594 TSE("E_Actions Init Done");
595 _e_main_shutdown_push(e_actions_shutdown);
597 /* these just add event handlers and can't fail
598 * timestamping them is dumb.
600 e_screensaver_preinit();
605 TRACE_DS_BEGIN(MAIN:WAIT /dev/dri/card0);
606 if (e_config->sleep_for_dri)
608 while(access("/dev/dri/card0", F_OK) != 0)
610 struct timespec req, rem;
612 req.tv_nsec = 50000000L;
613 nanosleep(&req, &rem);
618 e_module_event_init();
620 TSB("E_Pointer Init");
621 if (!e_pointer_init())
623 e_error_message_show(_("Enlightenment cannot set up its pointer system.\n"));
626 TSE("E_Pointer Init Done");
627 _e_main_shutdown_push(e_pointer_shutdown);
629 TRACE_DS_BEGIN(MAIN:SCREEN INIT);
631 if (!_e_main_screens_init())
633 e_error_message_show(_("Enlightenment set up window management for all the screens on your system\n"
634 "failed. Perhaps another window manager is running?\n"));
637 TSE("Screens Init Done");
638 _e_main_shutdown_push(_e_main_screens_shutdown);
641 TSB("E_Keyrouter Init");
642 if (!e_keyrouter_init())
644 e_error_message_show(_("Enlightenment cannot set up its keyrouting system.\n"));
647 TSE("E_Keyrouter Init Done");
648 _e_main_shutdown_push(e_keyrouter_shutdown);
650 if (e_config->eom_enable)
655 e_error_message_show(_("Enlightenment cannot set up eom.\n"));
658 TSE("Eom Init Done");
659 _e_main_shutdown_push(e_eom_shutdown);
662 TSB("E_Screensaver Init");
663 if (!e_screensaver_init())
665 e_error_message_show(_("Enlightenment cannot configure the X screensaver.\n"));
668 TSE("E_Screensaver Init Done");
669 _e_main_shutdown_push(e_screensaver_shutdown);
671 TSB("E_Comp Freeze");
673 TSE("E_Comp Freeze Done");
675 TSB("E_Grabinput Init");
676 if (!e_grabinput_init())
678 e_error_message_show(_("Enlightenment cannot set up its grab input handling system.\n"));
681 TSE("E_Grabinput Init Done");
682 _e_main_shutdown_push(e_grabinput_shutdown);
684 TS("E_Gesture Init");
686 _e_main_shutdown_push(e_gesture_shutdown);
688 ecore_event_handler_add(E_EVENT_MODULE_INIT_END, _e_main_deferred_job_schedule, NULL);
690 TSB("E_Module Init");
691 if (!e_module_init())
693 e_error_message_show(_("Enlightenment cannot set up its module system.\n"));
696 TSE("E_Module Init Done");
697 _e_main_shutdown_push(e_module_shutdown);
700 if (!e_mouse_update())
702 e_error_message_show(_("Enlightenment cannot configure the mouse settings.\n"));
705 TSE("E_Mouse Init Done");
710 e_error_message_show(_("Enlightenment cannot initialize the Icon Cache system.\n"));
713 TSE("E_Icon Init Done");
714 _e_main_shutdown_push(e_icon_shutdown);
716 if (e_config->use_e_policy)
718 TSB("E_Policy Init");
719 if (!e_policy_init())
721 e_error_message_show(_("Enlightenment cannot setup policy system!\n"));
724 TSE("E_Policy Init Done");
725 _e_main_shutdown_push(e_policy_shutdown);
728 TSB("E_Process Init");
729 if (!e_process_init())
731 e_error_message_show(_("Enlightenment cannot setup process managing system!\n"));
734 TSE("E_Process Init Done");
735 _e_main_shutdown_push(e_process_shutdown);
737 TSB("E_Security Init");
738 if (!e_security_init())
740 e_error_message_show(_("Enlightenment cannot setup security system!\n"));
743 TSE("E_Security Init Done");
744 _e_main_shutdown_push(e_security_shutdown);
748 TSE("Load Modules Done");
752 TSE("E_Comp Thaw Done");
754 _idle_after = ecore_idle_enterer_add(_e_main_cb_idle_after, NULL);
756 starting = EINA_FALSE;
759 e_util_env_set("E_RESTART", "1");
761 TSM("MAIN LOOP AT LAST");
763 if (e_config->create_wm_ready)
764 _e_main_create_wm_ready();
769 TSM("[WM] Send start-up completion");
770 sd_notify(0, "READY=1");
772 TSM("[WM] Skip sending start-up completion. (no systemd)");
774 ecore_main_loop_begin();
778 ELOGF("COMP", "STOPPING enlightenment...", NULL, NULL);
779 stopping = EINA_TRUE;
782 e_comp_internal_save();
793 _e_main_shutdown(-1);
797 e_main_ts(const char *str)
800 t1 = ecore_time_unix_get();
801 printf("ESTART: %1.5f [%1.5f] - %s\n", t1 - t0, t1 - t2, str);
808 e_main_ts_begin(const char *str)
810 TRACE_DS_BEGIN(ESTART: %s, str);
811 return e_main_ts(str);
815 e_main_ts_end(const char *str)
818 return e_main_ts(str);
821 /* local functions */
823 _e_main_shutdown(int errcode)
829 printf("E: Begin Shutdown Procedure!\n");
831 E_FREE_LIST(hooks, e_main_hook_del);
833 if (_idle_before) ecore_idle_enterer_del(_idle_before);
835 if (_idle_after) ecore_idle_enterer_del(_idle_after);
838 dir = e_util_env_get("XDG_RUNTIME_DIR");
841 char buf_env[PATH_MAX];
842 snprintf(buf_env, sizeof(buf_env), "%s", dir);
843 snprintf(buf, sizeof(buf), "%s/.e-deleteme", buf_env);
844 if (ecore_file_exists(buf)) ecore_file_recursive_rm(buf_env);
847 for (i = (_e_main_lvl - 1); i >= 0; i--)
848 (*_e_main_shutdown_func[i])();
849 #ifdef OBJECT_HASH_CHECK
850 e_object_hash_shutdown();
852 if (errcode < 0) exit(errcode);
856 _e_main_shutdown_push(int (*func)(void))
859 if (_e_main_lvl > MAX_LEVEL)
862 e_error_message_show("WARNING: too many init levels. MAX = %i\n",
866 _e_main_shutdown_func[_e_main_lvl - 1] = func;
870 _e_main_parse_arguments(int argc, char **argv)
874 /* handle some command-line parameters */
875 for (i = 1; i < argc; i++)
877 if (!strcmp(argv[i], "-good"))
881 printf("LA LA LA\n");
883 else if (!strcmp(argv[i], "-evil"))
887 printf("MUHAHAHAHHAHAHAHAHA\n");
889 else if (!strcmp(argv[i], "-psychotic"))
893 printf("MUHAHALALALALALALALA\n");
895 else if ((!strcmp(argv[i], "-profile")) && (i < (argc - 1)))
898 if (!getenv("E_CONF_PROFILE"))
899 e_util_env_set("E_CONF_PROFILE", argv[i]);
901 else if (!strcmp(argv[i], "-nopause"))
902 e_nopause = EINA_TRUE;
903 else if ((!strcmp(argv[i], "-version")) ||
904 (!strcmp(argv[i], "--version")))
906 printf(_("Version: %s\n"), PACKAGE_VERSION);
907 _e_main_shutdown(-1);
909 else if ((!strcmp(argv[i], "-h")) ||
910 (!strcmp(argv[i], "-help")) ||
911 (!strcmp(argv[i], "--help")))
916 "\t-display DISPLAY\n"
917 "\t\tConnect to display named DISPLAY.\n"
918 "\t\tEG: -display :1.0\n"
919 "\t-fake-xinerama-screen WxH+X+Y\n"
920 "\t\tAdd a FAKE xinerama screen (instead of the real ones)\n"
921 "\t\tgiven the geometry. Add as many as you like. They all\n"
922 "\t\treplace the real xinerama screens, if any. This can\n"
923 "\t\tbe used to simulate xinerama.\n"
924 "\t\tEG: -fake-xinerama-screen 800x600+0+0 -fake-xinerama-screen 800x600+800+0\n"
925 "\t-profile CONF_PROFILE\n"
926 "\t\tUse the configuration profile CONF_PROFILE instead of the user selected default or just \"default\".\n"
932 "\t\tBe psychotic.\n"
933 "\t-i-really-know-what-i-am-doing-and-accept-full-responsibility-for-it\n"
934 "\t\tIf you need this help, you don't need this option.\n"
938 _e_main_shutdown(-1);
944 _e_main_cb_signal_exit(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
946 /* called on ctrl-c, kill (pid) (also SIGINT, SIGTERM and SIGQIT) */
947 ecore_main_loop_quit();
948 return ECORE_CALLBACK_RENEW;
952 _e_main_cb_signal_hup(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
954 ecore_main_loop_quit();
955 return ECORE_CALLBACK_RENEW;
959 _e_main_cb_signal_user(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev)
961 Ecore_Event_Signal_User *e = ev;
965 // E_Action *a = e_action_find("configuration");
966 // if ((a) && (a->func.go)) a->func.go(NULL, NULL);
968 else if (e->number == 2)
970 // comp module has its own handler for this for enabling/disabling fps debug
972 return ECORE_CALLBACK_RENEW;
977 _e_main_dirs_init(void)
979 if(getenv("E_CONF_RO"))
993 base = e_user_dir_get();
994 if (ecore_file_mksubdirs(base, dirs) != sizeof(dirs) / sizeof(dirs[0]) - 1)
996 e_error_message_show("Could not create one of the required "
997 "subdirectories of '%s'\n", base);
1005 _e_main_dirs_shutdown(void)
1011 _e_main_path_init(void)
1015 /* setup data paths */
1016 path_data = e_path_new();
1019 e_error_message_show("Cannot allocate path for path_data\n");
1022 e_prefix_data_concat_static(buf, "data");
1023 e_path_default_path_append(path_data, buf);
1025 /* setup image paths */
1026 path_images = e_path_new();
1029 e_error_message_show("Cannot allocate path for path_images\n");
1032 e_user_dir_concat_static(buf, "/images");
1033 e_path_default_path_append(path_images, buf);
1034 e_prefix_data_concat_static(buf, "data/images");
1035 e_path_default_path_append(path_images, buf);
1037 /* setup font paths */
1038 path_fonts = e_path_new();
1041 e_error_message_show("Cannot allocate path for path_fonts\n");
1044 e_user_dir_concat_static(buf, "/fonts");
1045 e_path_default_path_append(path_fonts, buf);
1046 e_prefix_data_concat_static(buf, "data/fonts");
1047 e_path_default_path_append(path_fonts, buf);
1049 /* setup icon paths */
1050 path_icons = e_path_new();
1053 e_error_message_show("Cannot allocate path for path_icons\n");
1056 e_user_dir_concat_static(buf, "/icons");
1057 e_path_default_path_append(path_icons, buf);
1058 e_prefix_data_concat_static(buf, "data/icons");
1059 e_path_default_path_append(path_icons, buf);
1061 /* setup module paths */
1062 path_modules = e_path_new();
1065 e_error_message_show("Cannot allocate path for path_modules\n");
1068 e_user_dir_concat_static(buf, "/modules");
1069 e_path_default_path_append(path_modules, buf);
1070 snprintf(buf, sizeof(buf), "%s/enlightenment/modules", e_prefix_lib_get());
1071 e_path_default_path_append(path_modules, buf);
1072 /* FIXME: eventually this has to go - moduels should have installers that
1073 * add appropriate install paths (if not installed to user homedir) to
1074 * e's module search dirs
1076 snprintf(buf, sizeof(buf), "%s/enlightenment/modules_extra", e_prefix_lib_get());
1077 e_path_default_path_append(path_modules, buf);
1079 /* setup background paths */
1080 path_backgrounds = e_path_new();
1081 if (!path_backgrounds)
1083 e_error_message_show("Cannot allocate path for path_backgrounds\n");
1086 e_user_dir_concat_static(buf, "/backgrounds");
1087 e_path_default_path_append(path_backgrounds, buf);
1088 e_prefix_data_concat_static(buf, "data/backgrounds");
1089 e_path_default_path_append(path_backgrounds, buf);
1091 path_messages = e_path_new();
1094 e_error_message_show("Cannot allocate path for path_messages\n");
1097 e_user_dir_concat_static(buf, "/locale");
1098 e_path_default_path_append(path_messages, buf);
1099 e_path_default_path_append(path_messages, e_prefix_locale_get());
1105 _e_main_path_shutdown(void)
1109 e_object_del(E_OBJECT(path_data));
1114 e_object_del(E_OBJECT(path_images));
1119 e_object_del(E_OBJECT(path_fonts));
1124 e_object_del(E_OBJECT(path_icons));
1129 e_object_del(E_OBJECT(path_modules));
1130 path_modules = NULL;
1132 if (path_backgrounds)
1134 e_object_del(E_OBJECT(path_backgrounds));
1135 path_backgrounds = NULL;
1139 e_object_del(E_OBJECT(path_messages));
1140 path_messages = NULL;
1146 _e_main_screens_init(void)
1148 TSB("\tscreens: client");
1149 if (!e_client_init()) return 0;
1150 TSE("\tscreens: client Done");
1152 TSB("Compositor Init");
1153 PRCTL("[Winsys] start of compositor init");
1156 e_error_message_show(_("Enlightenment cannot create a compositor.\n"));
1157 _e_main_shutdown(-1);
1159 TSE("Compositor Init Done");
1161 PRCTL("[Winsys] end of compositor init");
1162 _e_main_desk_restore();
1168 _e_main_screens_shutdown(void)
1172 e_client_shutdown();
1181 _e_main_desk_save(void)
1184 char env[1024], name[1024];
1187 EINA_LIST_FOREACH(e_comp->zones, l, zone)
1189 snprintf(name, sizeof(name), "DESK_%d_%d", 0, zone->num);
1190 snprintf(env, sizeof(env), "%d,%d", zone->desk_x_current, zone->desk_y_current);
1191 e_util_env_set(name, env);
1196 _e_main_desk_restore(void)
1200 E_CLIENT_REVERSE_FOREACH(ec)
1201 if ((!e_client_util_ignored_get(ec)) && e_client_util_desk_visible(ec, e_desk_current_get(ec->zone)))
1203 ec->want_focus = ec->take_focus = 1;
1209 _e_main_cb_idle_before(void *data EINA_UNUSED)
1211 e_client_idler_before();
1213 return ECORE_CALLBACK_RENEW;
1217 _e_main_cb_idle_after(void *data EINA_UNUSED)
1219 static int first_idle = 1;
1224 #ifdef E_RELEASE_BUILD
1229 e_precache_end = EINA_TRUE;
1232 if (first_idle++ < 60)
1236 e_precache_end = EINA_TRUE;
1240 return ECORE_CALLBACK_RENEW;
1244 _e_main_create_wm_ready(void)
1246 FILE *_wmready_checker = NULL;
1247 const char *path_wm_ready = "/run/.wm_ready";
1249 if (!e_util_file_realpath_check(path_wm_ready, EINA_TRUE))
1251 WRN("%s is maybe link, so delete it\n", path_wm_ready);
1254 _wmready_checker = fopen(path_wm_ready, "wb");
1255 if (_wmready_checker)
1257 TSM("[WM] WINDOW MANAGER is READY!!!");
1258 PRCTL("[Winsys] WINDOW MANAGER is READY!!!");
1259 fclose(_wmready_checker);
1261 /*TODO: Next lines should be removed. */
1262 FILE *_tmp_wm_ready_checker;
1264 _tmp_wm_ready_checker = fopen(path_wm_ready, "wb");
1266 if (_tmp_wm_ready_checker)
1268 TSM("[WM] temporary wm_ready path is created.");
1269 PRCTL("[Winsys] temporary wm_ready path is created.");
1270 fclose(_tmp_wm_ready_checker);
1274 TSM("[WM] temporary wm_ready path create failed.");
1275 PRCTL("[Winsys] temporary wm_ready path create failed.");
1280 TSM("[WM] WINDOW MANAGER is READY. BUT, failed to create .wm_ready file.");
1281 PRCTL("[Winsys] WINDOW MANAGER is READY. BUT, failed to create .wm_ready file.");
1286 _e_main_hooks_clean(void)
1292 for (x = 0; x < E_MAIN_HOOK_LAST; x++)
1293 EINA_INLIST_FOREACH_SAFE(_e_main_hooks[x], l, mh)
1295 if (!mh->delete_me) continue;
1296 _e_main_hooks[x] = eina_inlist_remove(_e_main_hooks[x],
1297 EINA_INLIST_GET(mh));
1303 _e_main_hook_call(E_Main_Hook_Point hookpoint, void *data EINA_UNUSED)
1307 _e_main_hooks_walking++;
1308 EINA_INLIST_FOREACH(_e_main_hooks[hookpoint], mh)
1310 if (mh->delete_me) continue;
1313 _e_main_hooks_walking--;
1314 if ((_e_main_hooks_walking == 0) && (_e_main_hooks_delete > 0))
1315 _e_main_hooks_clean();
1319 e_main_hook_add(E_Main_Hook_Point hookpoint, E_Main_Hook_Cb func, const void *data)
1323 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_MAIN_HOOK_LAST, NULL);
1324 mh = E_NEW(E_Main_Hook, 1);
1325 EINA_SAFETY_ON_NULL_RETURN_VAL(mh, NULL);
1326 mh->hookpoint = hookpoint;
1328 mh->data = (void*)data;
1329 _e_main_hooks[hookpoint] = eina_inlist_append(_e_main_hooks[hookpoint],
1330 EINA_INLIST_GET(mh));
1335 e_main_hook_del(E_Main_Hook *mh)
1338 if (_e_main_hooks_walking == 0)
1340 _e_main_hooks[mh->hookpoint] = eina_inlist_remove(_e_main_hooks[mh->hookpoint],
1341 EINA_INLIST_GET(mh));
1345 _e_main_hooks_delete++;
1349 e_main_hook_call(E_Main_Hook_Point hookpoint)
1351 if ((hookpoint < 0) || (hookpoint >= E_MAIN_HOOK_LAST)) return;
1353 _e_main_hook_call(hookpoint, NULL);