+ }
+ /* not found: add */
+ if (quirks_size == 0 || quirks == NULL) {
+ quirks_size = 4;
+ DNPRINTF(SWM_D_QUIRK, "setquirk: init list %d\n", quirks_size);
+ quirks = malloc((size_t)quirks_size * sizeof(struct quirk));
+ if (!quirks) {
+ fprintf(stderr, "setquirk: malloc failed\n");
+ perror(" failed");
+ quit(NULL, NULL);
+ }
+ } else if (quirks_length == quirks_size) {
+ quirks_size *= 2;
+ DNPRINTF(SWM_D_QUIRK, "setquirk: grow list %d\n", quirks_size);
+ quirks = realloc(quirks, (size_t)quirks_size * sizeof(struct quirk));
+ if (!quirks) {
+ fprintf(stderr, "setquirk: realloc failed\n");
+ perror(" failed");
+ quit(NULL, NULL);
+ }
+ }
+ if (quirks_length < quirks_size) {
+ DNPRINTF(SWM_D_QUIRK, "setquirk: add %d\n", quirks_length);
+ j = quirks_length++;
+ quirks[j].class = strdup(class);
+ quirks[j].name = strdup(name);
+ quirks[j].quirk = quirk;
+ } else {
+ fprintf(stderr, "quirks array problem?\n");
+ if (!quirks) {
+ fprintf(stderr, "quirks array problem!\n");
+ quit(NULL, NULL);
+ }
+ }
+}
+
+int
+setconfquirk(char *selector, char *value, int flags)
+{
+ char *cp, *class, *name;
+ int retval;
+ unsigned long quirks;
+ if (selector == NULL)
+ return (0);
+ if ((cp = strchr(selector, ':')) == NULL)
+ return (0);
+ *cp = '\0';
+ class = selector;
+ name = cp + 1;
+ if ((retval = parsequirks(value, &quirks)) == 0)
+ setquirk(class, name, quirks);
+ return (retval);
+}
+
+void
+setup_quirks(void)
+{
+ setquirk("MPlayer", "xv", SWM_Q_FLOAT | SWM_Q_FULLSCREEN);
+ setquirk("OpenOffice.org 2.4", "VCLSalFrame", SWM_Q_FLOAT);
+ setquirk("OpenOffice.org 3.0", "VCLSalFrame", SWM_Q_FLOAT);
+ setquirk("Firefox-bin", "firefox-bin", SWM_Q_TRANSSZ);
+ setquirk("Firefox", "Dialog", SWM_Q_FLOAT);
+ setquirk("Gimp", "gimp", SWM_Q_FLOAT | SWM_Q_ANYWHERE);
+ setquirk("XTerm", "xterm", SWM_Q_XTERM_FONTADJ);
+ setquirk("xine", "Xine Window", SWM_Q_FLOAT | SWM_Q_ANYWHERE);
+ setquirk("Xitk", "Xitk Combo", SWM_Q_FLOAT | SWM_Q_ANYWHERE);
+ setquirk("xine", "xine Panel", SWM_Q_FLOAT | SWM_Q_ANYWHERE);
+ setquirk("Xitk", "Xine Window", SWM_Q_FLOAT | SWM_Q_ANYWHERE);
+ setquirk("xine", "xine Video Fullscreen Window", SWM_Q_FULLSCREEN | SWM_Q_FLOAT);
+ setquirk("pcb", "pcb", SWM_Q_FLOAT);
+}
+
+/* conf file stuff */
+#define SWM_CONF_FILE "scrotwm.conf"
+
+enum { SWM_S_BAR_DELAY, SWM_S_BAR_ENABLED, SWM_S_STACK_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_STACK_ENABLED:
+ stack_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:
+ free(bar_fonts[0]);
+ if ((bar_fonts[0] = strdup(value)) == NULL)
+ err(1, "setconfvalue: bar_font");
+ break;
+ case SWM_S_BAR_ACTION:
+ free(bar_argv[0]);
+ if ((bar_argv[0] = strdup(value)) == NULL)
+ err(1, "setconfvalue: bar_action");
+ break;
+ case SWM_S_SPAWN_TERM:
+ free(spawn_term[0]);
+ if ((spawn_term[0] = strdup(value)) == NULL)
+ err(1, "setconfvalue: spawn_term");
+ break;
+ case SWM_S_SS_APP:
+ break;
+ case SWM_S_DIALOG_RATIO:
+ dialog_ratio = atof(value);
+ if (dialog_ratio > 1.0 || dialog_ratio <= .3)
+ dialog_ratio = .6;
+ break;
+ default:
+ return (1);
+ }
+ return (0);
+}
+
+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 (1);
+ return (0);
+}
+
+int
+setconfcolor(char *selector, char *value, int flags)
+{
+ setscreencolor(value, ((selector == NULL)?-1:atoi(selector)), flags);
+ return (0);
+}
+
+int
+setconfregion(char *selector, char *value, int flags)
+{
+ custom_region(value);
+ return (0);
+}
+
+/* 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 },
+ { "stack_enabled", setconfvalue, SWM_S_STACK_ENABLED },
+ { "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 },
+ { "program", setconfspawn, 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;
+
+ DNPRINTF(SWM_D_CONF, "conf_load begin\n");
+
+ if (filename == NULL) {
+ fprintf(stderr, "conf_load: no filename\n");
+ return (1);
+ }
+ if ((config = fopen(filename, "r")) == NULL) {
+ warn("conf_load: fopen");
+ return (1);