+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);
+}
+
+/* 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;
+
+ DNPRINTF(SWM_D_MISC, "conf_load: filename %s\n", filename);
+
+ if (filename == NULL)
+ return (1);
+
+ if ((config = fopen(filename, "r")) == NULL)
+ return (1);
+
+ for (;;) {
+ 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 (!strncmp(var, "bar_border",
+ strlen("bar_border")))
+ for (i = 0; i < ScreenCount(display); i++)
+ screens[i].bar_border = name_to_color(val);
+ else if (!strncmp(var, "bar_color",
+ strlen("bar_color")))
+ for (i = 0; i < ScreenCount(display); i++)
+ screens[i].bar_color = name_to_color(val);
+ else if (!strncmp(var, "bar_font_color",
+ strlen("bar_font_color")))
+ for (i = 0; i < ScreenCount(display); i++)
+ screens[i].bar_font_color = name_to_color(val);
+ else if (!strncmp(var, "bar_font", strlen("bar_font")))
+ asprintf(&bar_fonts[0], "%s", val);
+ else
+ goto bad;
+ break;
+
+ case 'c':
+ if (!strncmp(var, "color_focus", strlen("color_focus")))
+ for (i = 0; i < ScreenCount(display); i++)
+ screens[i].color_focus = name_to_color(val);
+ else if (!strncmp(var, "color_unfocus",
+ strlen("color_unfocus")))
+ for (i = 0; i < ScreenCount(display); i++)
+ screens[i].color_unfocus = name_to_color(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
+bar_print(struct swm_region *r)
+{
+ time_t tmt;
+ struct tm tm;
+
+ if (bar_enabled == 0)
+ return;
+
+ /* clear old text */
+ XSetForeground(display, bar_gc, r->s->bar_color);
+ XDrawString(display, r->bar_window,
+ bar_gc, 4, bar_fs->ascent, bar_text, strlen(bar_text));
+
+ /* draw new text */
+ time(&tmt);
+ localtime_r(&tmt, &tm);
+ strftime(bar_text, sizeof bar_text, "%a %b %d %R %Z %Y", &tm);
+ XSetForeground(display, bar_gc, r->s->bar_font_color);
+ XDrawString(display, r->bar_window, bar_gc, 4,
+ bar_fs->ascent, bar_text, strlen(bar_text));
+ XSync(display, False);
+
+ alarm(60);
+}
+
+void
+bar_signal(int sig)
+{
+ /* XXX yeah yeah byte me */
+ if (cur_focus)
+ bar_print(cur_focus->ws->r);
+}
+
+void
+bar_toggle(union arg *args)
+{
+ struct swm_region *r;
+ int i, j;
+
+ DNPRINTF(SWM_D_MISC, "bar_toggle\n");
+
+ if (bar_enabled) {
+ for (i = 0; i < ScreenCount(display); i++)
+ TAILQ_FOREACH(r, &screens[i].rl, entry)
+ XUnmapWindow(display, r->bar_window);
+ } else {
+ for (i = 0; i < ScreenCount(display); i++)
+ TAILQ_FOREACH(r, &screens[i].rl, entry)
+ XMapRaised(display, r->bar_window);
+ }
+ bar_enabled = !bar_enabled;
+ XSync(display, False);
+ for (i = 0; i < ScreenCount(display); i++)
+ for (j = 0; j < SWM_WS_MAX; j++)
+ screens[i].ws[j].restack = 1;
+
+ stack();
+ /* must be after stack */
+ for (i = 0; i < ScreenCount(display); i++)
+ TAILQ_FOREACH(r, &screens[i].rl, entry)
+ bar_print(r);
+}
+
+void
+bar_setup(struct swm_region *r)
+{
+ int i;
+
+ for (i = 0; bar_fonts[i] != NULL; i++) {
+ bar_fs = XLoadQueryFont(display, bar_fonts[i]);
+ if (bar_fs)
+ break;
+ }
+ if (bar_fonts[i] == NULL)
+ errx(1, "couldn't load font");
+ bar_height = bar_fs->ascent + bar_fs->descent + 3;
+
+ r->bar_window = XCreateSimpleWindow(display,
+ r->s->root, X(r), Y(r), WIDTH(r), bar_height - 2,
+ 1, r->s->bar_border, r->s->bar_color);
+ bar_gc = XCreateGC(display, r->bar_window, 0, &bar_gcv);
+ XSetFont(display, bar_gc, bar_fs->fid);
+ XSelectInput(display, r->bar_window, VisibilityChangeMask);
+ if (bar_enabled)
+ XMapRaised(display, r->bar_window);
+ DNPRINTF(SWM_D_MISC, "bar_setup: bar_window %lu\n", r->bar_window);
+
+ if (signal(SIGALRM, bar_signal) == SIG_ERR)
+ err(1, "could not install bar_signal");
+ bar_print(r);
+}
+
+void
+config_win(struct ws_win *win)
+{
+ XConfigureEvent ce;
+
+ DNPRINTF(SWM_D_MISC, "config_win: win %lu x %d y %d w %d h %d\n",
+ win->id, win->g.x, win->g.y, win->g.w, win->g.h);
+ ce.type = ConfigureNotify;
+ ce.display = display;
+ ce.event = win->id;
+ ce.window = win->id;
+ ce.x = win->g.x;
+ ce.y = win->g.y;
+ ce.width = win->g.w;
+ ce.height = win->g.h;
+ ce.border_width = 1; /* XXX store this! */
+ ce.above = None;
+ ce.override_redirect = False;
+ XSendEvent(display, win->id, False, StructureNotifyMask, (XEvent *)&ce);
+}
+
+int
+count_win(struct workspace *ws, int count_transient)
+{
+ struct ws_win *win;
+ int count = 0;
+
+ TAILQ_FOREACH(win, &ws->winlist, entry) {
+ if (count_transient == 0 && win->floating)
+ continue;
+ if (count_transient == 0 && win->transient)
+ continue;
+ count++;
+ }
+ DNPRINTF(SWM_D_MISC, "count_win: %d\n", count);
+
+ return (count);
+}
+