+unsigned long
+name_to_color(char *colorname)
+{
+ Colormap cmap;
+ Status status;
+ XColor screen_def, exact_def;
+ unsigned long result = 0;
+ char cname[32] = "#";
+
+ cmap = DefaultColormap(display, screens[0].idx);
+ status = XAllocNamedColor(display, cmap, colorname,
+ &screen_def, &exact_def);
+ if (!status) {
+ strlcat(cname, colorname + 2, sizeof cname - 1);
+ status = XAllocNamedColor(display, cmap, cname, &screen_def,
+ &exact_def);
+ }
+ if (status)
+ result = screen_def.pixel;
+ else
+ fprintf(stderr, "color '%s' not found.\n", colorname);
+
+ return (result);
+}
+
+void
+setscreencolor(char *val, int i, int c)
+{
+ if (i > 0 && i <= ScreenCount(display)) {
+ screens[i - 1].c[c].color = name_to_color(val);
+ if ((screens[i - 1].c[c].name = strdup(val)) == NULL)
+ errx(1, "strdup");
+ } else if (i == -1) {
+ for (i = 0; i < ScreenCount(display); i++)
+ screens[i].c[c].color = name_to_color(val);
+ if ((screens[i - 1].c[c].name = strdup(val)) == NULL)
+ errx(1, "strdup");
+ } else
+ errx(1, "invalid screen index: %d out of bounds (maximum %d)\n",
+ i, ScreenCount(display));
+}
+
+int
+varmatch(char *var, char *name, int *index)
+{
+ char *p, buf[5];
+ int i;
+
+ i = strncmp(var, name, 255);
+ if (index == NULL)
+ return (i);
+
+ *index = -1;
+ if (i <= 0)
+ return (i);
+ p = var + strlen(name);
+ if (*p++ != '[')
+ return (i);
+ bzero(buf, sizeof buf);
+ i = 0;
+ while (isdigit(*p) && i < sizeof buf)
+ buf[i++] = *p++;
+ if (i == 0 || i >= sizeof buf || *p != ']')
+ return (1);
+ *index = strtonum(buf, 0, 99, NULL);
+ return (0);
+}
+
+/* conf file stuff */
+#define SWM_CONF_WS "\n= \t"
+#define SWM_CONF_FILE "scrotwm.conf"
+int
+conf_load(char *filename)
+{
+ FILE *config;
+ char *line, *cp, *var, *val;
+ size_t len, lineno = 0;
+ int i, sc;
+
+ DNPRINTF(SWM_D_MISC, "conf_load: filename %s\n", filename);
+
+ if (filename == NULL)
+ return (1);
+
+ if ((config = fopen(filename, "r")) == NULL)
+ return (1);
+
+ for (sc = ScreenCount(display);;) {
+ if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL)
+ if (feof(config))
+ break;
+ cp = line;
+ cp += (long)strspn(cp, SWM_CONF_WS);
+ if (cp[0] == '\0') {
+ /* empty line */
+ free(line);
+ continue;
+ }
+ if ((var = strsep(&cp, SWM_CONF_WS)) == NULL || cp == NULL)
+ break;
+ cp += (long)strspn(cp, SWM_CONF_WS);
+ if ((val = strsep(&cp, SWM_CONF_WS)) == NULL)
+ break;
+
+ DNPRINTF(SWM_D_MISC, "conf_load: %s=%s\n",var ,val);
+ switch (var[0]) {
+ case 'b':
+ if (!strncmp(var, "bar_enabled", strlen("bar_enabled")))
+ bar_enabled = atoi(val);
+ else if (!varmatch(var, "bar_border", &i))
+ setscreencolor(val, i, SWM_S_COLOR_BAR_BORDER);
+ else if (!varmatch(var, "bar_color", &i))
+ setscreencolor(val, i, SWM_S_COLOR_BAR);
+ else if (!varmatch(var, "bar_font_color", &i))
+ setscreencolor(val, i, SWM_S_COLOR_BAR_FONT);
+ else if (!strncmp(var, "bar_font", strlen("bar_font")))
+ asprintf(&bar_fonts[0], "%s", val);
+ else if (!strncmp(var, "bar_action", strlen("bar_action")))
+ asprintf(&bar_argv[0], "%s", val);
+ else
+ goto bad;
+ break;
+
+ case 'c':
+ if (!varmatch(var, "color_focus", &i))
+ setscreencolor(val, i, SWM_S_COLOR_FOCUS);
+ else if (!varmatch(var, "color_unfocus", &i))
+ setscreencolor(val, i, SWM_S_COLOR_UNFOCUS);
+ else if (!strncmp(var, "cycle_empty", strlen("cycle_empty")))
+ cycle_visible = atoi(val);
+ else if (!strncmp(var, "cycle_visible", strlen("cycle_visible")))
+ cycle_visible = atoi(val);
+ else
+ goto bad;
+ break;
+
+ case 'd':
+ if (!strncmp(var, "dialog_ratio",
+ strlen("dialog_ratio"))) {
+ dialog_ratio = atof(val);
+ if (dialog_ratio > 1.0 || dialog_ratio <= .3)
+ dialog_ratio = .6;
+ } else
+ goto bad;
+ break;
+
+ case 's':
+ if (!strncmp(var, "spawn_term", strlen("spawn_term")))
+ asprintf(&spawn_term[0], "%s", val); /* XXX args? */
+ break;
+ default:
+ goto bad;
+ }
+ free(line);
+ }
+
+ fclose(config);
+ return (0);
+
+bad:
+ errx(1, "invalid conf file entry: %s=%s", var, val);
+}
+
+void
+socket_setnonblock(int fd)
+{
+ int flags;
+
+ if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
+ err(1, "fcntl F_GETFL");
+ flags |= O_NONBLOCK;
+ if ((flags = fcntl(fd, F_SETFL, flags)) == -1)
+ err(1, "fcntl F_SETFL");
+}
+
+void
+bar_print(struct swm_region *r, char *s)
+{
+ XClearWindow(display, r->bar_window);
+ XSetForeground(display, bar_gc, r->s->c[SWM_S_COLOR_BAR_FONT].color);
+ XDrawString(display, r->bar_window, bar_gc, 4, bar_fs->ascent, s,
+ strlen(s));
+}
+
+void
+bar_extra_stop(void)
+{
+ if (bar_pipe[0]) {
+ close(bar_pipe[0]);
+ bzero(bar_pipe, sizeof bar_pipe);
+ }
+ if (bar_pid) {
+ kill(bar_pid, SIGTERM);
+ bar_pid = 0;
+ }
+ strlcpy(bar_ext, "", sizeof bar_ext);
+ bar_extra = 0;
+}
+