2 * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3 * Copyright (C) 2004-2009 Kim Woelders
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies of the Software, its documentation and marketing & publicity
14 * materials, and acknowledgment shall be given in the documentation, materials
15 * and software packages that this Software was used.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41 #include <sys/utsname.h>
45 const char e_wm_name[] = "e16";
46 const char e_wm_version[] = VERSION;
51 static int EoptGet(int argc, char **argv);
52 static void EoptHelp(void);
53 static void ECheckEprog(const char *name);
54 static void EDirUserSet(const char *dir);
55 static void EConfNameSet(const char *dir);
56 static void EDirUserCacheSet(const char *dir);
57 static void EDirsSetup(void);
58 static void RunInitPrograms(void);
60 static int eoptind = 0;
61 const char *eoptarg = NULL;
71 static const EOpt Eopts[] = {
72 {'d', 1, "display", "display", "Set display"},
73 {'f', 0, "fast", NULL, "Fast startup"},
74 {'h', 0, "help", NULL, "Show help"},
75 {'m', 1, NULL, NULL, NULL},
76 {'p', 1, "config-prefix", "prefix", "Configuration file name prefix"},
77 {'P', 1, "econfdir", "path", "Set user configuration directory"},
78 {'Q', 1, "ecachedir", "path", "Set user cache directory"},
79 {'s', 1, "single", "screen", "Run only on given screen"},
80 {'S', 1, "sm-client-id", "session id", "Set session manager ID"},
81 {'t', 1, "theme", "name", "Select theme"},
82 {'v', 0, "verbose", NULL, "Show additional info"},
83 {'V', 0, "version", NULL, "Show version"},
84 {'w', 1, "window", "WxH", "Run in window"},
85 {'X', 1, NULL, NULL, NULL},
89 main(int argc, char **argv)
93 const char *str, *dstr;
95 /* This function runs all the setup for startup, and then
96 * proceeds into the primary event loop at the end.
99 /* Init state variable struct */
100 memset(&Mode, 0, sizeof(EMode));
103 Mode.wm.pid = getpid();
104 Mode.wm.exec_name = argv[0];
107 Mode.mode = MODE_NONE;
113 str = getenv("EDEBUG");
116 str = getenv("EDEBUG_COREDUMP");
118 Mode.wm.coredump = 1;
119 str = getenv("EDEBUG_EXIT");
121 Mode.debug_exit = atoi(str);
123 str = getenv("ECONFNAME");
126 str = getenv("ECONFDIR");
129 str = getenv("ECACHEDIR");
131 EDirUserCacheSet(str);
133 srand((unsigned int)time(NULL));
136 Mode.wm.machine_name = Estrdup(ubuf.nodename);
137 if (!Mode.wm.machine_name)
138 Mode.wm.machine_name = Estrdup("localhost");
140 /* Now we're going to interpret any of the commandline parameters
141 * that are passed to it -- Well, at least the ones that we
145 Mode.theme.path = NULL;
148 for (loop = 1; loop;)
150 ch = EoptGet(argc, argv);
154 Eprintf("Opt: %c: %d - %s\n", ch, eoptind, eoptarg);
160 printf("e16: Ignoring: ");
161 for (i = eoptind; i < argc; i++)
162 printf("%s ", argv[i]);
177 EConfNameSet(eoptarg);
180 EDirUserSet(eoptarg);
183 EDirUserCacheSet(eoptarg);
187 Dpy.screen = strtoul(eoptarg, NULL, 10);
193 Mode.theme.path = Estrdup(eoptarg);
196 printf("%s %s\n", e_wm_name, e_wm_version);
200 EDebugSet(EDBUG_TYPE_VERBOSE, 1);
203 sscanf(eoptarg, "%dx%d", &Mode.wm.win_w, &Mode.wm.win_h);
208 #ifdef USE_EXT_INIT_WIN
210 ExtInitWinSet(strtoul(eoptarg, NULL, 0));
216 Mode.wm.master_screen = strtoul(eoptarg, NULL, 10);
221 SignalsSetup(); /* Install signal handlers */
223 SetupX(dstr); /* This is where the we fork per screen */
224 /* X is now running, and we have forked per screen */
226 /* So far nothing should rely on a selected settings or theme. */
227 ConfigurationLoad(); /* Load settings */
229 /* Initialise internationalisation */
236 /* The theme path must now be available for config file loading. */
239 /* Set the Environment variables */
240 Esetenv("EVERSION", e_wm_version);
241 Esetenv("EROOT", EDirRoot());
242 Esetenv("EBIN", EDirBin());
243 Esetenv("ECONFDIR", EDirUser());
244 Esetenv("ECACHEDIR", EDirUserCache());
245 Esetenv("ETHEME", Mode.theme.path);
247 /* Move elsewhere? */
261 ModulesSignal(ESIGNAL_INIT, NULL);
269 /* Do initial configuration */
270 ModulesSignal(ESIGNAL_CONFIGURE, NULL);
272 /* Set root window cursor */
273 ECsrApply(ECSR_ROOT, WinGetXwin(VROOT));
275 #ifdef USE_EXT_INIT_WIN
276 /* Kill the E process owning the "init window" */
280 /* let's make sure we set this up and go to our desk anyways */
281 DeskGoto(DesksGetCurrent());
285 for (i = 0; i < Mode.wm.child_count; i++)
286 kill(Mode.wm.children[i], SIGCONT);
289 ModulesSignal(ESIGNAL_START, NULL);
298 if (!Mode.wm.restart)
299 StartupWindowsOpen();
301 Conf.startup.firsttime = 0;
302 Mode.wm.save_ok = Conf.autosave;
306 /* The primary event loop */
309 SessionExit(EEXIT_QUIT, NULL);
319 if (EDebug(EDBUG_TYPE_SESSION))
320 Eprintf("EExit(%d)\n", exitcode);
325 GrabPointerRelease();
326 XAllowEvents(disp, AsyncBoth, CurrentTime);
328 /* XSetInputFocus(disp, None, RevertToParent, CurrentTime); */
329 /* I think this is a better way to release the grabs: (felix) */
330 XSetInputFocus(disp, PointerRoot, RevertToPointerRoot, CurrentTime);
331 ESelectInput(VROOT, 0);
337 for (i = 0; i < Mode.wm.child_count; i++)
338 kill(Mode.wm.children[i], SIGINT);
349 * Command line parsing.
350 * Not entirely standard compliant, but close enough.
353 EoptGet(int argc, char **argv)
377 for (i = 0; i < sizeof(Eopts) / sizeof(EOpt); i++)
384 if (!eopt->sopt || eopt->sopt != s[0])
404 len = strlen(eopt->lopt);
405 if (strncmp(eopt->lopt, s, len))
413 eoptarg = s + len + 1;
420 if (!eopt->arg || eoptarg)
423 if (eoptind >= argc - 1)
424 return '?'; /* Missing param */
427 eoptarg = argv[eoptind];
438 printf("e16 options:\n");
439 for (i = 0; i < sizeof(Eopts) / sizeof(EOpt); i++)
445 Esnprintf(buf, sizeof(buf), "--%s <%s>", eopt->lopt, eopt->oarg);
447 Esnprintf(buf, sizeof(buf), "--%s", eopt->lopt);
448 printf(" -%c %-30s\t%s\n", eopt->sopt, buf, eopt->desc);
455 char buf[FILEPATH_LEN_MAX];
457 Esnprintf(buf, sizeof(buf), "%s/edox", EDirBin());
460 Esnprintf(buf, sizeof(buf), "%s/E-docs/MAIN", EDirRoot());
464 Esnprintf(buf, sizeof(buf), "%s/edox %s/E-docs", EDirBin(), EDirRoot());
465 execApplication(buf, 0);
471 char buf[FILEPATH_LEN_MAX];
473 Esnprintf(buf, sizeof(buf), "%s/scripts/e_gen_menu", EDirRoot());
474 execApplication(buf, EXEC_SET_LANG);
478 RunInitPrograms(void)
480 if (Mode.wm.session_start)
481 SessionHelper(ESESSION_INIT);
483 SessionHelper(ESESSION_START);
485 if (Mode.firsttime && Mode.wm.master)
495 return ENLIGHTENMENT_BIN;
501 return ENLIGHTENMENT_ROOT;
505 EConfNameSet(const char *name)
507 Efree(Mode.conf.name);
508 Mode.conf.name = Estrdup(name);
509 Esetenv("ECONFNAME", Mode.conf.name);
513 EDirUserSet(const char *dir)
515 if (!strcmp(dir, EDirUser()))
517 Efree(Mode.conf.dir);
518 Mode.conf.dir = Estrdup(dir);
522 EDirUserCacheSet(const char *dir)
524 if (!strcmp(dir, EDirUser()))
526 Efree(Mode.conf.cache_dir);
527 Mode.conf.cache_dir = Estrdup(dir);
531 EConfNameDefault(void)
539 return (Mode.conf.name) ? Mode.conf.name : EConfNameDefault();
545 static char *user_dir = NULL;
546 char *home, buf[4096];
549 return Mode.conf.dir;
554 home = homedir(getuid());
555 Esnprintf(buf, sizeof(buf), "%s/.e16", home);
557 user_dir = Estrdup(buf);
565 if (Mode.conf.cache_dir)
566 return Mode.conf.cache_dir;
573 static unsigned int n_calls = 0;
575 Esnprintf(s, 1024, "%s/TMP_%d_%d", EDirUser(), getpid(), n_calls++);
579 EDirCheck(const char *dir)
581 if (file_test(dir, EFILE_DIR | EPERM_RWX))
584 Alert(_("%s must be a directory in which you have\n"
585 "read, write, and execute permission.\n"), dir);
590 EDirMake(const char *base, const char *name)
594 Esnprintf(s, sizeof(s), "%s/%s", base, name);
604 char s[1024], ss[1024], *home;
606 home = homedir(getuid());
613 Esnprintf(s, sizeof(s), "%s", EDirUser());
618 Esnprintf(ss, sizeof(ss), "%s.old", EDirUser());
628 Esnprintf(s, sizeof(s), "%s/menus", EDirUser());
629 Mode.firsttime = !exists(s);
631 EDirMake(EDirUser(), "themes");
632 EDirMake(EDirUser(), "backgrounds");
633 EDirMake(EDirUser(), "menus");
635 EDirMake(EDirUserCache(), "cached");
636 EDirMake(EDirUserCache(), "cached/cfg");
640 * The user control config is called "~/.e16/e_config-$DISPLAY"
641 * The client data appends ".clients" onto this filename and the snapshot data
642 * appends ".snapshots".
647 static char *def_prefix = NULL;
654 Esnprintf(buf, sizeof(buf), "%s/%s-%d", EDirUser(), EConfName(),
656 else if (Mode.wm.window)
657 Esnprintf(buf, sizeof(buf), "%s/%s-window", EDirUser(),
660 Esnprintf(buf, sizeof(buf), "%s/%s-%s", EDirUser(), EConfNameDefault(),
662 def_prefix = Estrdup(buf);
664 for (s = def_prefix; (s = strchr(s, ':')) != NULL; *s = '-')
671 ECheckEprog(const char *name)
675 Esnprintf(s, sizeof(s), "%s/%s", EDirBin(), name);
679 Alert(_("!!!!!!!! ERROR ERROR ERROR ERROR !!!!!!!!\n" "\n"
680 "Enlightenment's utility executable cannot be found at:\n"
682 "This is a fatal error and Enlightenment will cease to run.\n"
683 "Please rectify this situation and ensure it is installed\n"
685 "The reason this could be missing is due to badly created\n"
686 "packages, someone manually deleting that program or perhaps\n"
687 "an error in installing Enlightenment.\n"), s);
693 Alert(_("!!!!!!!! ERROR ERROR ERROR ERROR !!!!!!!!\n" "\n"
694 "Enlightenment's utility executable is not able to be executed:\n"
696 "This is a fatal error and Enlightenment will cease to run.\n"
697 "Please rectify this situation and ensure it is installed\n"