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.
26 #include "backgrounds.h"
38 #include "windowmatch.h"
40 #define MAX_E_CFG_VERSION 2 /* Max. supported configuration version */
43 SkipTillEnd(FILE * fs)
45 char s[FILEPATH_LEN_MAX];
48 while (GetLine(s, sizeof(s), fs))
51 fields = sscanf(s, "%i %i", &i1, &i2);
52 if (i1 == CONFIG_CLOSE)
54 if (i2 == CONFIG_OPEN)
59 #define LINE_BUFFER_SIZE 1024
61 * This function will get a single line from the file
62 * The string will be null terminated.
66 GetLine(char *s, int size, FILE * f)
68 static char *buffer = NULL;
69 static const char *bufptr = NULL;
70 char *so, ch, quote, escape;
76 buffer = EMALLOC(char, LINE_BUFFER_SIZE);
80 buffer[LINE_BUFFER_SIZE - 1] = '\0';
89 /* Get a line from the input file */
92 nr = fread(buffer, 1, LINE_BUFFER_SIZE - 1, f);
99 /* Split on ';' or '\n', handle quoting */
106 case ';': /* Line separator */
110 if (so == s) /* Skip empty lines */
112 *so = '\0'; /* Terminate and return */
114 case '\r': /* Ignore */
116 case '\\': /* Escape */
121 case '"': /* Quoting */
127 else if (quote == ch)
132 case ' ': /* Whitespace */
134 if (so == s) /* Skip leading whitespace */
136 case_char: /* Normal character */
158 /* Strip trailing whitespace */
163 if (ch != ' ' && ch != '\t')
169 if (EDebug(EDBUG_TYPE_CONFIG) > 1)
170 Eprintf("GetLine %s\n", s);
176 ConfigParseline1(char *str, char *s2, char **p2, char **p3)
178 int i1, len1, len2, fields;
183 fields = sscanf(str, "%i %n%4000s %n", &i1, &len1, s2, &len2);
185 *p2 = (len1) ? str + len1 : NULL;
187 *p3 = (len2) ? str + len2 : NULL;
193 else if (i1 == CONFIG_CLOSE || i1 == CONFIG_NEXT)
197 Alert(_("CONFIG: ignoring extra data in \"%s\"\n"), str);
200 else if (i1 != CONFIG_INVALID)
205 Alert(_("CONFIG: missing required data in \"%s\"\n"), str);
213 ConfigParseError(const char *where, const char *line)
215 Alert(_("Warning: unable to determine what to do with\n"
216 "the following text in the middle of current %s definition:\n"
217 "%s\nWill ignore and continue...\n"), where, line);
221 ConfigAlertLoad(const char *txt)
223 Alert(_("Warning: Configuration error in %s block.\n"
224 "Outcome is likely not good.\n"), txt);
228 ConfigFilePreparse(const char *src, const char *dst, const char *themepath)
230 char execline[FILEPATH_LEN_MAX];
231 const char *epp_path = ENLIGHTENMENT_BIN "/epp";
232 char *def_home, *def_user, *def_shell;
234 if (EDebug(EDBUG_TYPE_CONFIG))
235 Eprintf("ConfigFilePreparse %s -> %s\n", src, dst);
237 def_home = homedir(getuid());
238 def_user = username(getuid());
239 def_shell = usershell(getuid());
241 /* When themepath is NULL it shouldn't be used, but this is consistent
242 * with old behavior */
244 themepath = Mode.theme.path;
246 Esnprintf(execline, sizeof(execline), "%s " "-P " "-nostdinc " "-undef "
247 "-include %s/config/definitions " "-I%s " "-I%s/config "
248 "-D ENLIGHTENMENT_VERSION=%s " "-D ENLIGHTENMENT_ROOT=%s "
249 "-D ENLIGHTENMENT_BIN=%s "
250 "-D ENLIGHTENMENT_THEME=%s " "-D ECONFDIR=%s "
251 "-D ECACHEDIR=%s " "-D SCREEN_RESOLUTION_%ix%i=1 "
252 "-D SCREEN_WIDTH_%i=1 " "-D SCREEN_HEIGHT_%i=1 "
253 "-D SCREEN_DEPTH_%i=1 " "-D USER_NAME=%s " "-D HOME_DIR=%s "
256 epp_path, EDirRoot(), themepath, EDirRoot(),
257 e_wm_version, EDirRoot(), EDirBin(),
258 themepath, EDirUser(), EDirUserCache(),
259 WinGetW(VROOT), WinGetH(VROOT), WinGetW(VROOT), WinGetH(VROOT),
260 WinGetDepth(VROOT), def_user, def_home, def_shell, src, dst);
267 return exists(dst) ? 0 : 1;
270 /* Split the process of finding the file from the process of loading it */
272 ConfigFileRead(FILE * fs)
276 char s[FILEPATH_LEN_MAX];
279 while (GetLine(s, sizeof(s), fs))
281 i1 = i2 = CONFIG_INVALID;
282 fields = sscanf(s, "%i %i", &i1, &i2);
288 else if (i1 == CONFIG_VERSION)
293 else if (i1 == CONFIG_CLOSE)
297 Alert(_("CONFIG: ignoring extra data in \"%s\"\n"), s);
300 else if (i1 != CONFIG_INVALID)
304 Alert(_("CONFIG: missing required data in \"%s\"\n"), s);
309 if (i2 == CONFIG_OPEN)
311 if (e_cfg_ver > MAX_E_CFG_VERSION)
313 AlertX(_("Theme versioning ERROR"),
314 _("Restart with Defaults"), " ",
317 "The configuration for the theme you are running is\n"
318 "incompatible. It's config revision is %i.\n"
319 "It needs to be marked as being revision <= %i\n"
321 "Please contact the theme author or maintainer and\n"
322 "inform them that in order for their theme to function\n"
323 "with this version of Enlightenment, they have to\n"
324 "update it to the current settings, and then match\n"
325 "the revision number.\n" "\n"
326 "If the theme revision is higher than Enlightenment's\n"
327 "it may be that you haven't upgraded Enlightenment for\n"
328 "a while and this theme takes advantages of new\n"
329 "features in Enlightenment in new versions.\n"),
330 e_cfg_ver, MAX_E_CFG_VERSION);
331 SessionExit(EEXIT_THEME, "DEFAULT");
340 case CONFIG_IMAGECLASS:
341 err = ImageclassConfigLoad(fs);
343 ConfigAlertLoad("Image class");
346 err = TooltipConfigLoad(fs);
348 ConfigAlertLoad("Tooltip");
351 err = TextclassConfigLoad(fs);
353 ConfigAlertLoad("Text class");
356 err = MenuStyleConfigLoad(fs);
358 ConfigAlertLoad("Menu style");
361 err = MenuConfigLoad(fs);
363 ConfigAlertLoad("Menu");
366 err = BorderConfigLoad(fs);
368 ConfigAlertLoad("Border");
371 err = ButtonsConfigLoad(fs);
373 ConfigAlertLoad("Button");
376 err = BackgroundsConfigLoad(fs);
378 ConfigAlertLoad("Background");
380 case CONFIG_WINDOWMATCH:
381 err = WindowMatchConfigLoad(fs);
383 ConfigAlertLoad("Window match");
385 case CONFIG_COLORMOD:
387 case CONFIG_ACTIONCLASS:
388 err = AclassConfigLoad(fs);
390 ConfigAlertLoad("Action class");
392 case CONFIG_SLIDEOUT:
393 err = SlideoutsConfigLoad(fs);
395 ConfigAlertLoad("Slideout");
409 FindFilePath(const char *name, const char *path)
411 char s[FILEPATH_LEN_MAX];
416 len = Esnprintf(s, sizeof(s), "%s/%s", path, name);
427 return Estrdup(name);
433 FindFile(const char *file, const char *themepath)
435 char s[FILEPATH_LEN_MAX];
438 /* if absolute path - and file exists - return it */
441 p = FindFilePath(file, NULL);
446 /* look in ~/.e16 first */
447 p = FindFilePath(file, EDirUser());
453 /* look in theme dir */
454 p = FindFilePath(file, themepath);
459 /* look in system config dir */
460 Esnprintf(s, sizeof(s), "%s/config", EDirRoot());
461 p = FindFilePath(file, s);
465 /* not found.... NULL */
470 ThemeFileFind(const char *file)
472 return FindFile(file, Mode.theme.path);
476 ConfigFileFind(const char *name, const char *themepath, int pp)
478 char s[FILEPATH_LEN_MAX];
479 char *fullname, *file, *ppfile;
482 fullname = FindFile(name, themepath);
486 /* Quit if not preparsing */
490 /* The file exists. Now check the preparsed one. */
491 file = Estrdup(fullname);
492 for (i = 0; file[i]; i++)
496 Esnprintf(s, sizeof(s), "%s/cached/cfg/%s.preparsed", EDirUserCache(), file);
498 if (exists(s) && moddate(s) > moddate(fullname))
501 /* No preparesd file or source is newer. Do preparsing. */
502 err = ConfigFilePreparse(fullname, ppfile, themepath);
516 ConfigFileLoad(const char *name, const char *themepath,
517 int (*parse) (FILE * fs), int preparse)
523 if (EDebug(EDBUG_TYPE_CONFIG))
524 Eprintf("ConfigFileLoad %s\n", name);
526 file = ConfigFileFind(name, themepath, preparse);
530 fs = fopen(file, "r");
544 ThemeConfigLoad(void)
546 static const char *const config_files[] = {
559 char s[FILEPATH_LEN_MAX];
560 Progressbar *p = NULL;
566 Esnprintf(s, sizeof(s), "%s/", Mode.theme.path);
568 for (i = 0; i < (int)(sizeof(config_files) / sizeof(char *)); i++)
571 if (!Mode.wm.restart && Conf.startup.animate)
574 StartupWindowsCreate();
578 p = ProgressbarCreate(_("Enlightenment Starting..."), 400,
585 ConfigFileLoad(config_files[i], Mode.theme.path, ConfigFileRead, 1);
588 ProgressbarSet(p, (i * 100) /
589 (int)(sizeof(config_files) / sizeof(char *)));
593 ProgressbarDestroy(p);
595 /* Font mappings no longer needed */