+/* conf file stuff */
+#define SWM_CONF_FILE "scrotwm.conf"
+
+enum { SWM_S_BAR_DELAY, SWM_S_BAR_ENABLED, SWM_S_CLOCK_ENABLED,
+ SWM_S_CYCLE_EMPTY, SWM_S_CYCLE_VISIBLE, SWM_S_SS_ENABLED,
+ SWM_S_TERM_WIDTH, SWM_S_TITLE_CLASS_ENABLED, SWM_S_TITLE_NAME_ENABLED,
+ SWM_S_BAR_FONT, SWM_S_BAR_ACTION, SWM_S_SPAWN_TERM, SWM_S_SS_APP,
+ SWM_S_DIALOG_RATIO };
+
+int
+setconfvalue(char *selector, char *value, int flags)
+{
+ switch (flags) {
+ case SWM_S_BAR_DELAY:
+ bar_delay = atoi(value);
+ break;
+ case SWM_S_BAR_ENABLED:
+ bar_enabled = atoi(value);
+ break;
+ case SWM_S_CLOCK_ENABLED:
+ clock_enabled = atoi(value);
+ break;
+ case SWM_S_CYCLE_EMPTY:
+ cycle_empty = atoi(value);
+ break;
+ case SWM_S_CYCLE_VISIBLE:
+ cycle_visible = atoi(value);
+ break;
+ case SWM_S_SS_ENABLED:
+ ss_enabled = atoi(value);
+ break;
+ case SWM_S_TERM_WIDTH:
+ term_width = atoi(value);
+ break;
+ case SWM_S_TITLE_CLASS_ENABLED:
+ title_class_enabled = atoi(value);
+ break;
+ case SWM_S_TITLE_NAME_ENABLED:
+ title_name_enabled = atoi(value);
+ break;
+ case SWM_S_BAR_FONT:
+ bar_fonts[0] = strdup(value);
+ break;
+ case SWM_S_BAR_ACTION:
+ bar_argv[0] = strdup(value);
+ break;
+ case SWM_S_SPAWN_TERM:
+ spawn_term[0] = strdup(value);
+ break;
+ case SWM_S_SS_APP:
+ spawn_screenshot[0] = strdup(value);
+ break;
+ case SWM_S_DIALOG_RATIO:
+ dialog_ratio = atof(value);
+ if (dialog_ratio > 1.0 || dialog_ratio <= .3)
+ dialog_ratio = .6;
+ break;
+ default:
+ return (0);
+ }
+ return (1);
+}
+
+int
+setconfmodkey(char *selector, char *value, int flags)
+{
+ if (!strncasecmp(value, "Mod1", strlen("Mod1")))
+ update_modkey(Mod1Mask);
+ else if (!strncasecmp(value, "Mod2", strlen("Mod2")))
+ update_modkey(Mod2Mask);
+ else if (!strncasecmp(value, "Mod3", strlen("Mod3")))
+ update_modkey(Mod3Mask);
+ else if (!strncasecmp(value, "Mod4", strlen("Mod4")))
+ update_modkey(Mod4Mask);
+ else
+ return (0);
+ return (1);
+}
+
+int
+setconfcolor(char *selector, char *value, int flags)
+{
+ setscreencolor(value, ((selector == NULL)?-1:atoi(selector)), flags);
+ return (1);
+}
+
+int
+setconfregion(char *selector, char *value, int flags)
+{
+ custom_region(value);
+ return (1);
+}
+
+/* config options */
+struct config_option {
+ char *optname;
+ int (*func)(char*, char*, int);
+ int funcflags;
+};
+struct config_option configopt[] = {
+ { "bar_enabled", setconfvalue, SWM_S_BAR_ENABLED },
+ { "bar_border", setconfcolor, SWM_S_COLOR_BAR_BORDER },
+ { "bar_color", setconfcolor, SWM_S_COLOR_BAR },
+ { "bar_font_color", setconfcolor, SWM_S_COLOR_BAR_FONT },
+ { "bar_font", setconfvalue, SWM_S_BAR_FONT },
+ { "bar_action", setconfvalue, SWM_S_BAR_ACTION },
+ { "bar_delay", setconfvalue, SWM_S_BAR_DELAY },
+ { "bind", setconfbinding, 0 },
+ { "clock_enabled", setconfvalue, SWM_S_CLOCK_ENABLED },
+ { "color_focus", setconfcolor, SWM_S_COLOR_FOCUS },
+ { "color_unfocus", setconfcolor, SWM_S_COLOR_UNFOCUS },
+ { "cycle_empty", setconfvalue, SWM_S_CYCLE_EMPTY },
+ { "cycle_visible", setconfvalue, SWM_S_CYCLE_VISIBLE },
+ { "dialog_ratio", setconfvalue, SWM_S_DIALOG_RATIO },
+ { "modkey", setconfmodkey, 0 },
+ { "quirk", setconfquirk, 0 },
+ { "region", setconfregion, 0 },
+ { "spawn_term", setconfvalue, SWM_S_SPAWN_TERM },
+ { "screenshot_enabled", setconfvalue, SWM_S_SS_ENABLED },
+ { "screenshot_app", setconfvalue, SWM_S_SS_APP },
+ { "term_width", setconfvalue, SWM_S_TERM_WIDTH },
+ { "title_class_enabled", setconfvalue, SWM_S_TITLE_CLASS_ENABLED },
+ { "title_name_enabled", setconfvalue, SWM_S_TITLE_NAME_ENABLED }
+};
+
+
+int
+conf_load(char *filename)
+{
+ FILE *config;
+ char *line, *cp, *optsub, *optval;
+ size_t linelen, lineno = 0;
+ int wordlen, i, optind;
+ struct config_option *opt;
+ if (filename == NULL)
+ return (0);
+ if ((config = fopen(filename, "r")) == NULL)
+ return (0);
+ while (!feof(config)) {
+ if ((line = fparseln(config, &linelen, &lineno, NULL, 0))
+ == NULL) {
+ if (ferror(config))
+ err(1, "%s", filename);
+ else
+ continue;
+ }
+ cp = line;
+ cp += strspn(cp, " \t\n"); /* eat whitespace */
+ if (cp[0] == '\0') {
+ /* empty line */
+ free(line);
+ continue;
+ }
+ /* get config option */
+ wordlen = strcspn(cp, "=[ \t\n");
+ if (!wordlen) {
+ warnx("%s: line %zd: no option found",
+ filename, lineno);
+ return (0);
+ }
+ optind = -1;
+ for (i = 0; i < LENGTH(configopt); i++) {
+ opt = &configopt[i];
+ if (!strncasecmp(cp, opt->optname, wordlen) &&
+ strlen(opt->optname) == wordlen) {
+ optind = i;
+ break;
+ }
+ }
+ if (optind == -1) {
+ warnx("%s: line %zd: unknown option %.*s",
+ filename, lineno, wordlen, cp);
+ return (0);
+ }
+ cp += wordlen;
+ cp += strspn(cp, " \t\n"); /* eat whitespace */
+ /* get [selector] if any */
+ optsub = NULL;
+ if (*cp == '[') {
+ cp++;
+ wordlen = strcspn(cp, "]");
+ if (!wordlen) {
+ warnx("%s: line %zd: syntax error",
+ filename, lineno);
+ return (0);
+ }
+ asprintf(&optsub, "%.*s", wordlen, cp);
+ cp += wordlen;
+ cp += strspn(cp, "] \t\n"); /* eat trailing */
+ }
+ cp += strspn(cp, "= \t\n"); /* eat trailing */
+ /* get RHS value */
+ optval = strdup(cp);
+ /* call function to deal with it all */
+ if (!configopt[optind].func(optsub, optval,
+ configopt[optind].funcflags))
+ errx(1, "%s: line %zd: invalid data for %s",
+ filename, lineno, configopt[optind].optname);
+ free(optval);
+ free(optsub);
+ free(line);
+ }
+ return (1);
+}
+