1*61ba55bcSBaptiste Daroussin /*- 2*61ba55bcSBaptiste Daroussin * SPDX-License-Identifier: BSD-2-Clause 3*61ba55bcSBaptiste Daroussin * 4*61ba55bcSBaptiste Daroussin * Copyright (c) 2022-2023 Alfonso Sabato Siciliano 5*61ba55bcSBaptiste Daroussin * 6*61ba55bcSBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 7*61ba55bcSBaptiste Daroussin * modification, are permitted provided that the following conditions 8*61ba55bcSBaptiste Daroussin * are met: 9*61ba55bcSBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright 10*61ba55bcSBaptiste Daroussin * notice, this list of conditions and the following disclaimer. 11*61ba55bcSBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright 12*61ba55bcSBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 13*61ba55bcSBaptiste Daroussin * documentation and/or other materials provided with the distribution. 14*61ba55bcSBaptiste Daroussin * 15*61ba55bcSBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*61ba55bcSBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*61ba55bcSBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*61ba55bcSBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*61ba55bcSBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*61ba55bcSBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*61ba55bcSBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*61ba55bcSBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*61ba55bcSBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*61ba55bcSBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*61ba55bcSBaptiste Daroussin * SUCH DAMAGE. 26*61ba55bcSBaptiste Daroussin */ 27*61ba55bcSBaptiste Daroussin 28*61ba55bcSBaptiste Daroussin #include <sys/time.h> 29*61ba55bcSBaptiste Daroussin 30*61ba55bcSBaptiste Daroussin #include <limits.h> 31*61ba55bcSBaptiste Daroussin #include <stdio.h> 32*61ba55bcSBaptiste Daroussin #include <stdlib.h> 33*61ba55bcSBaptiste Daroussin #include <string.h> 34*61ba55bcSBaptiste Daroussin #include <unistd.h> 35*61ba55bcSBaptiste Daroussin #include <time.h> 36*61ba55bcSBaptiste Daroussin 37*61ba55bcSBaptiste Daroussin #include <bsddialog.h> 38*61ba55bcSBaptiste Daroussin #include <bsddialog_theme.h> 39*61ba55bcSBaptiste Daroussin 40*61ba55bcSBaptiste Daroussin #include "util.h" 41*61ba55bcSBaptiste Daroussin 42*61ba55bcSBaptiste Daroussin static struct bsddialog_theme t; 43*61ba55bcSBaptiste Daroussin static char title[1024]; 44*61ba55bcSBaptiste Daroussin 45*61ba55bcSBaptiste Daroussin #define NPROPERTY 41 46*61ba55bcSBaptiste Daroussin #define NCOLOR 8 47*61ba55bcSBaptiste Daroussin #define NATTR 6 48*61ba55bcSBaptiste Daroussin 49*61ba55bcSBaptiste Daroussin #define PROP_ERROR(name, error) do { \ 50*61ba55bcSBaptiste Daroussin fclose(fp); \ 51*61ba55bcSBaptiste Daroussin exit_error(false, "%s for \"%s\"", error, name); \ 52*61ba55bcSBaptiste Daroussin } while (0) 53*61ba55bcSBaptiste Daroussin 54*61ba55bcSBaptiste Daroussin enum typeproperty { 55*61ba55bcSBaptiste Daroussin BOOL, 56*61ba55bcSBaptiste Daroussin CHAR, 57*61ba55bcSBaptiste Daroussin INT, 58*61ba55bcSBaptiste Daroussin UINT, 59*61ba55bcSBaptiste Daroussin COLOR, 60*61ba55bcSBaptiste Daroussin COMPAT 61*61ba55bcSBaptiste Daroussin }; 62*61ba55bcSBaptiste Daroussin 63*61ba55bcSBaptiste Daroussin struct property { 64*61ba55bcSBaptiste Daroussin const char *comment; 65*61ba55bcSBaptiste Daroussin const char *name; 66*61ba55bcSBaptiste Daroussin enum typeproperty type; 67*61ba55bcSBaptiste Daroussin void *value; 68*61ba55bcSBaptiste Daroussin }; 69*61ba55bcSBaptiste Daroussin 70*61ba55bcSBaptiste Daroussin struct namevalue { 71*61ba55bcSBaptiste Daroussin const char *name; 72*61ba55bcSBaptiste Daroussin unsigned int value; 73*61ba55bcSBaptiste Daroussin }; 74*61ba55bcSBaptiste Daroussin 75*61ba55bcSBaptiste Daroussin static struct namevalue color[NCOLOR] = { 76*61ba55bcSBaptiste Daroussin {"black", BSDDIALOG_BLACK}, 77*61ba55bcSBaptiste Daroussin {"red", BSDDIALOG_RED}, 78*61ba55bcSBaptiste Daroussin {"green", BSDDIALOG_GREEN}, 79*61ba55bcSBaptiste Daroussin {"yellow", BSDDIALOG_YELLOW}, 80*61ba55bcSBaptiste Daroussin {"blue", BSDDIALOG_BLUE}, 81*61ba55bcSBaptiste Daroussin {"magenta", BSDDIALOG_MAGENTA}, 82*61ba55bcSBaptiste Daroussin {"cyan", BSDDIALOG_CYAN}, 83*61ba55bcSBaptiste Daroussin {"white", BSDDIALOG_WHITE} 84*61ba55bcSBaptiste Daroussin }; 85*61ba55bcSBaptiste Daroussin 86*61ba55bcSBaptiste Daroussin static struct namevalue attr[NATTR] = { 87*61ba55bcSBaptiste Daroussin {"bold", BSDDIALOG_BOLD}, 88*61ba55bcSBaptiste Daroussin {"reverse", BSDDIALOG_REVERSE}, 89*61ba55bcSBaptiste Daroussin {"underline", BSDDIALOG_UNDERLINE}, 90*61ba55bcSBaptiste Daroussin {"blink", BSDDIALOG_BLINK}, 91*61ba55bcSBaptiste Daroussin {"halfbright", BSDDIALOG_HALFBRIGHT}, 92*61ba55bcSBaptiste Daroussin {"highlight", BSDDIALOG_HIGHLIGHT} 93*61ba55bcSBaptiste Daroussin }; 94*61ba55bcSBaptiste Daroussin 95*61ba55bcSBaptiste Daroussin static struct property p[NPROPERTY] = { 96*61ba55bcSBaptiste Daroussin {"\n#Terminal\n", "theme.screen.color", COLOR, &t.screen.color}, 97*61ba55bcSBaptiste Daroussin 98*61ba55bcSBaptiste Daroussin {"\n# Shadow\n", 99*61ba55bcSBaptiste Daroussin "theme.shadow.color", COLOR, &t.shadow.color}, 100*61ba55bcSBaptiste Daroussin {"# shift down right from main widget\n", 101*61ba55bcSBaptiste Daroussin "theme.shadow.y", UINT, &t.shadow.y}, 102*61ba55bcSBaptiste Daroussin {"", "theme.shadow.x", UINT, &t.shadow.x}, 103*61ba55bcSBaptiste Daroussin 104*61ba55bcSBaptiste Daroussin {"\n# Main widget\n", 105*61ba55bcSBaptiste Daroussin "theme.dialog.color", COLOR, &t.dialog.color}, 106*61ba55bcSBaptiste Daroussin {"", "theme.dialog.delimtitle", BOOL, &t.dialog.delimtitle}, 107*61ba55bcSBaptiste Daroussin {"", "theme.dialog.titlecolor", COLOR, &t.dialog.titlecolor}, 108*61ba55bcSBaptiste Daroussin {"", "theme.dialog.lineraisecolor", COLOR, &t.dialog.lineraisecolor}, 109*61ba55bcSBaptiste Daroussin {"", "theme.dialog.linelowercolor", COLOR, &t.dialog.linelowercolor}, 110*61ba55bcSBaptiste Daroussin {"", "theme.dialog.bottomtitlecolor", COLOR, 111*61ba55bcSBaptiste Daroussin &t.dialog.bottomtitlecolor}, 112*61ba55bcSBaptiste Daroussin {"", "theme.dialog.arrowcolor", COLOR, &t.dialog.arrowcolor}, 113*61ba55bcSBaptiste Daroussin 114*61ba55bcSBaptiste Daroussin {"\n# Menus: --checklist, --menu, --radiolist\n" 115*61ba55bcSBaptiste Daroussin "# prefix [selector] shortcut name desc bottomdesc\n", 116*61ba55bcSBaptiste Daroussin "theme.menu.f_prefixcolor", COLOR, &t.menu.f_prefixcolor}, 117*61ba55bcSBaptiste Daroussin {"", "theme.menu.prefixcolor", COLOR, &t.menu.prefixcolor}, 118*61ba55bcSBaptiste Daroussin {"", "theme.menu.f_selectorcolor", COLOR, &t.menu.f_selectorcolor}, 119*61ba55bcSBaptiste Daroussin {"", "theme.menu.selectorcolor", COLOR, &t.menu.selectorcolor}, 120*61ba55bcSBaptiste Daroussin {"", "theme.menu.f_namecolor", COLOR, &t.menu.f_namecolor}, 121*61ba55bcSBaptiste Daroussin {"", "theme.menu.namecolor", COLOR, &t.menu.namecolor}, 122*61ba55bcSBaptiste Daroussin {"", "theme.menu.f_desccolor", COLOR, &t.menu.f_desccolor}, 123*61ba55bcSBaptiste Daroussin {"", "theme.menu.desccolor", COLOR, &t.menu.desccolor}, 124*61ba55bcSBaptiste Daroussin {"", "theme.menu.f_shortcutcolor", COLOR, &t.menu.f_shortcutcolor}, 125*61ba55bcSBaptiste Daroussin {"", "theme.menu.shortcutcolor", COLOR, &t.menu.shortcutcolor}, 126*61ba55bcSBaptiste Daroussin {"", "theme.menu.bottomdesccolor", COLOR, &t.menu.bottomdesccolor}, 127*61ba55bcSBaptiste Daroussin {"# bsddialog_menutype BSDDIALOG_SEPARATOR\n", 128*61ba55bcSBaptiste Daroussin "theme.menu.sepnamecolor", COLOR, &t.menu.sepnamecolor}, 129*61ba55bcSBaptiste Daroussin {"", "theme.menu.sepdesccolor", COLOR, &t.menu.sepdesccolor}, 130*61ba55bcSBaptiste Daroussin 131*61ba55bcSBaptiste Daroussin {"\n# Forms\n", 132*61ba55bcSBaptiste Daroussin "theme.form.f_fieldcolor", COLOR, &t.form.f_fieldcolor}, 133*61ba55bcSBaptiste Daroussin {"", "theme.form.fieldcolor", COLOR, &t.form.fieldcolor}, 134*61ba55bcSBaptiste Daroussin {"", "theme.form.readonlycolor", COLOR, &t.form.readonlycolor}, 135*61ba55bcSBaptiste Daroussin {"", "theme.form.bottomdesccolor", COLOR, &t.form.bottomdesccolor}, 136*61ba55bcSBaptiste Daroussin 137*61ba55bcSBaptiste Daroussin {"\n# Bar of --gauge, --mixedgauge, --pause, --rangebox\n", 138*61ba55bcSBaptiste Daroussin "theme.bar.f_color", COLOR, &t.bar.f_color}, 139*61ba55bcSBaptiste Daroussin {"", "theme.bar.color", COLOR, &t.bar.color}, 140*61ba55bcSBaptiste Daroussin 141*61ba55bcSBaptiste Daroussin {"\n# Buttons\n", 142*61ba55bcSBaptiste Daroussin "theme.button.minmargin", UINT, &t.button.minmargin}, 143*61ba55bcSBaptiste Daroussin {"", "theme.button.maxmargin", UINT, &t.button.maxmargin}, 144*61ba55bcSBaptiste Daroussin {"", "theme.button.leftdelim", CHAR, &t.button.leftdelim}, 145*61ba55bcSBaptiste Daroussin {"", "theme.button.rightdelim", CHAR, &t.button.rightdelim}, 146*61ba55bcSBaptiste Daroussin {"", "theme.button.f_delimcolor", COLOR, &t.button.f_delimcolor}, 147*61ba55bcSBaptiste Daroussin {"", "theme.button.delimcolor", COLOR, &t.button.delimcolor}, 148*61ba55bcSBaptiste Daroussin {"", "theme.button.f_color", COLOR, &t.button.f_color}, 149*61ba55bcSBaptiste Daroussin {"", "theme.button.color", COLOR, &t.button.color}, 150*61ba55bcSBaptiste Daroussin {"", "theme.button.f_shortcutcolor", COLOR, &t.button.f_shortcutcolor}, 151*61ba55bcSBaptiste Daroussin {"", "theme.button.shortcutcolor", COLOR, &t.button.shortcutcolor}, 152*61ba55bcSBaptiste Daroussin 153*61ba55bcSBaptiste Daroussin {"\n#Compatibility. Do not use, can be deleted\n", 154*61ba55bcSBaptiste Daroussin "use_shadow", COMPAT, NULL} 155*61ba55bcSBaptiste Daroussin }; 156*61ba55bcSBaptiste Daroussin 157*61ba55bcSBaptiste Daroussin void savetheme(const char *file) 158*61ba55bcSBaptiste Daroussin { 159*61ba55bcSBaptiste Daroussin int i, j; 160*61ba55bcSBaptiste Daroussin unsigned int flags; 161*61ba55bcSBaptiste Daroussin enum bsddialog_color bg, fg; 162*61ba55bcSBaptiste Daroussin time_t clock; 163*61ba55bcSBaptiste Daroussin FILE *fp; 164*61ba55bcSBaptiste Daroussin 165*61ba55bcSBaptiste Daroussin if (bsddialog_get_theme(&t) != BSDDIALOG_OK) 166*61ba55bcSBaptiste Daroussin exit_error(false, 167*61ba55bcSBaptiste Daroussin "cannot save theme: %s", bsddialog_geterror()); 168*61ba55bcSBaptiste Daroussin 169*61ba55bcSBaptiste Daroussin if(time(&clock) < 0) 170*61ba55bcSBaptiste Daroussin exit_error(false, "cannot save profile getting current time"); 171*61ba55bcSBaptiste Daroussin if ((fp = fopen(file, "w")) == NULL) 172*61ba55bcSBaptiste Daroussin exit_error(false, "cannot open %s to save profile", file); 173*61ba55bcSBaptiste Daroussin 174*61ba55bcSBaptiste Daroussin fprintf(fp, "### bsddialog theme - %s\n", ctime(&clock)); 175*61ba55bcSBaptiste Daroussin 176*61ba55bcSBaptiste Daroussin fputs("# Colors: ", fp); 177*61ba55bcSBaptiste Daroussin fputs("black red green yellow blue magenta cyan white.\n", fp); 178*61ba55bcSBaptiste Daroussin fputs("# Attributes: ", fp); 179*61ba55bcSBaptiste Daroussin fputs("bold reverse underline blink halfbright highlight.\n", fp); 180*61ba55bcSBaptiste Daroussin fputs("# f_* refers to focus for an element with selected or ", fp); 181*61ba55bcSBaptiste Daroussin fputs("unselected state.\n\n", fp); 182*61ba55bcSBaptiste Daroussin 183*61ba55bcSBaptiste Daroussin fprintf(fp, "version %s\n", LIBBSDDIALOG_VERSION); 184*61ba55bcSBaptiste Daroussin 185*61ba55bcSBaptiste Daroussin for (i = 0; i < NPROPERTY; i++) { 186*61ba55bcSBaptiste Daroussin if (p[i].type == COMPAT) 187*61ba55bcSBaptiste Daroussin continue; 188*61ba55bcSBaptiste Daroussin fprintf(fp, "%s%s", p[i].comment, p[i].name); 189*61ba55bcSBaptiste Daroussin switch (p[i].type) { 190*61ba55bcSBaptiste Daroussin case CHAR: 191*61ba55bcSBaptiste Daroussin fprintf(fp, " %c\n", *((char*)p[i].value)); 192*61ba55bcSBaptiste Daroussin break; 193*61ba55bcSBaptiste Daroussin case INT: 194*61ba55bcSBaptiste Daroussin fprintf(fp, " %d\n", *((int*)p[i].value)); 195*61ba55bcSBaptiste Daroussin break; 196*61ba55bcSBaptiste Daroussin case UINT: 197*61ba55bcSBaptiste Daroussin fprintf(fp, " %u\n", *((unsigned int*)p[i].value)); 198*61ba55bcSBaptiste Daroussin break; 199*61ba55bcSBaptiste Daroussin case BOOL: 200*61ba55bcSBaptiste Daroussin fprintf(fp, " %s\n", 201*61ba55bcSBaptiste Daroussin *((bool*)p[i].value) ? "true" : "false"); 202*61ba55bcSBaptiste Daroussin break; 203*61ba55bcSBaptiste Daroussin case COLOR: 204*61ba55bcSBaptiste Daroussin bsddialog_color_attrs(*(int*)p[i].value, &fg, &bg, 205*61ba55bcSBaptiste Daroussin &flags); 206*61ba55bcSBaptiste Daroussin fprintf(fp, " %s %s", color[fg].name, color[bg].name); 207*61ba55bcSBaptiste Daroussin for (j = 0; j < NATTR; j++) 208*61ba55bcSBaptiste Daroussin if (flags & attr[j].value) 209*61ba55bcSBaptiste Daroussin fprintf(fp, " %s", attr[j].name); 210*61ba55bcSBaptiste Daroussin fputs("\n", fp); 211*61ba55bcSBaptiste Daroussin break; 212*61ba55bcSBaptiste Daroussin case COMPAT: 213*61ba55bcSBaptiste Daroussin /* Do not save compat property for now */ 214*61ba55bcSBaptiste Daroussin break; 215*61ba55bcSBaptiste Daroussin } 216*61ba55bcSBaptiste Daroussin } 217*61ba55bcSBaptiste Daroussin 218*61ba55bcSBaptiste Daroussin fclose(fp); 219*61ba55bcSBaptiste Daroussin } 220*61ba55bcSBaptiste Daroussin 221*61ba55bcSBaptiste Daroussin void loadtheme(const char *file, bool compatibility) 222*61ba55bcSBaptiste Daroussin { 223*61ba55bcSBaptiste Daroussin bool boolvalue; 224*61ba55bcSBaptiste Daroussin char charvalue, *value; 225*61ba55bcSBaptiste Daroussin char line[BUFSIZ], name[BUFSIZ], c1[BUFSIZ], c2[BUFSIZ]; 226*61ba55bcSBaptiste Daroussin int i, j, intvalue; 227*61ba55bcSBaptiste Daroussin unsigned int uintvalue, flags; 228*61ba55bcSBaptiste Daroussin enum bsddialog_color bg, fg; 229*61ba55bcSBaptiste Daroussin FILE *fp; 230*61ba55bcSBaptiste Daroussin 231*61ba55bcSBaptiste Daroussin if (bsddialog_hascolors() == false) 232*61ba55bcSBaptiste Daroussin return; 233*61ba55bcSBaptiste Daroussin 234*61ba55bcSBaptiste Daroussin if (bsddialog_get_theme(&t) != BSDDIALOG_OK) 235*61ba55bcSBaptiste Daroussin exit_error(false, "Cannot get current theme: %s", 236*61ba55bcSBaptiste Daroussin bsddialog_geterror()); 237*61ba55bcSBaptiste Daroussin 238*61ba55bcSBaptiste Daroussin if((fp = fopen(file, "r")) == NULL) 239*61ba55bcSBaptiste Daroussin exit_error(false, "Cannot open theme \"%s\" file", file); 240*61ba55bcSBaptiste Daroussin 241*61ba55bcSBaptiste Daroussin while(fgets(line, BUFSIZ, fp) != NULL) { 242*61ba55bcSBaptiste Daroussin if(line[0] == '#' || line[0] == '\n') 243*61ba55bcSBaptiste Daroussin continue; /* superfluous, only for efficiency */ 244*61ba55bcSBaptiste Daroussin sscanf(line, "%s", name); 245*61ba55bcSBaptiste Daroussin value = NULL; /* useless init, fix compiler warning */ 246*61ba55bcSBaptiste Daroussin for (i = 0; i < NPROPERTY; i++) { 247*61ba55bcSBaptiste Daroussin if (strcmp(name, p[i].name) == 0) { 248*61ba55bcSBaptiste Daroussin value = &line[strlen(name)]; 249*61ba55bcSBaptiste Daroussin break; 250*61ba55bcSBaptiste Daroussin } 251*61ba55bcSBaptiste Daroussin } 252*61ba55bcSBaptiste Daroussin if (i >= NPROPERTY) { 253*61ba55bcSBaptiste Daroussin /* unknown name in property p[] */ 254*61ba55bcSBaptiste Daroussin if (strcmp(name, "version") == 0) 255*61ba55bcSBaptiste Daroussin continue; /* nothing for now */ 256*61ba55bcSBaptiste Daroussin else if (compatibility) 257*61ba55bcSBaptiste Daroussin continue; /* just ignore */ 258*61ba55bcSBaptiste Daroussin else 259*61ba55bcSBaptiste Daroussin PROP_ERROR(name, "Unknown theme property name"); 260*61ba55bcSBaptiste Daroussin } 261*61ba55bcSBaptiste Daroussin switch (p[i].type) { 262*61ba55bcSBaptiste Daroussin case CHAR: 263*61ba55bcSBaptiste Daroussin while (value[0] == ' ' || value[0] == '\n' || 264*61ba55bcSBaptiste Daroussin value[0] == '\0') 265*61ba55bcSBaptiste Daroussin value++; 266*61ba55bcSBaptiste Daroussin if (sscanf(value, "%c", &charvalue) != 1) 267*61ba55bcSBaptiste Daroussin PROP_ERROR(p[i].name, "Cannot get a char"); 268*61ba55bcSBaptiste Daroussin *((int*)p[i].value) = charvalue; 269*61ba55bcSBaptiste Daroussin break; 270*61ba55bcSBaptiste Daroussin case INT: 271*61ba55bcSBaptiste Daroussin if (sscanf(value, "%d", &intvalue) != 1) 272*61ba55bcSBaptiste Daroussin PROP_ERROR(p[i].name, "Cannot get a int"); 273*61ba55bcSBaptiste Daroussin *((int*)p[i].value) = intvalue; 274*61ba55bcSBaptiste Daroussin break; 275*61ba55bcSBaptiste Daroussin case UINT: 276*61ba55bcSBaptiste Daroussin if (sscanf(value, "%u", &uintvalue) != 1) 277*61ba55bcSBaptiste Daroussin PROP_ERROR(p[i].name, "Cannot get a uint"); 278*61ba55bcSBaptiste Daroussin *((unsigned int*)p[i].value) = uintvalue; 279*61ba55bcSBaptiste Daroussin break; 280*61ba55bcSBaptiste Daroussin case BOOL: 281*61ba55bcSBaptiste Daroussin boolvalue = (strstr(value, "true") != NULL) ? 282*61ba55bcSBaptiste Daroussin true :false; 283*61ba55bcSBaptiste Daroussin *((bool*)p[i].value) = boolvalue; 284*61ba55bcSBaptiste Daroussin break; 285*61ba55bcSBaptiste Daroussin case COLOR: 286*61ba55bcSBaptiste Daroussin if (sscanf(value, "%s %s", c1, c2) != 2) 287*61ba55bcSBaptiste Daroussin PROP_ERROR(p[i].name, "Cannot get 2 colors"); 288*61ba55bcSBaptiste Daroussin /* Foreground */ 289*61ba55bcSBaptiste Daroussin for (j = 0; j < NCOLOR ; j++) 290*61ba55bcSBaptiste Daroussin if ((strstr(c1, color[j].name)) != NULL) 291*61ba55bcSBaptiste Daroussin break; 292*61ba55bcSBaptiste Daroussin if (j >= NCOLOR) 293*61ba55bcSBaptiste Daroussin PROP_ERROR(p[i].name, "Bad foreground"); 294*61ba55bcSBaptiste Daroussin fg = color[j].value; 295*61ba55bcSBaptiste Daroussin /* Background */ 296*61ba55bcSBaptiste Daroussin for (j = 0; j < NCOLOR ; j++) 297*61ba55bcSBaptiste Daroussin if ((strstr(c2, color[j].name)) != NULL) 298*61ba55bcSBaptiste Daroussin break; 299*61ba55bcSBaptiste Daroussin if (j >= NCOLOR) 300*61ba55bcSBaptiste Daroussin PROP_ERROR(p[i].name, "Bad background"); 301*61ba55bcSBaptiste Daroussin bg = color[j].value; 302*61ba55bcSBaptiste Daroussin /* Flags */ 303*61ba55bcSBaptiste Daroussin flags = 0; 304*61ba55bcSBaptiste Daroussin for (j = 0; j < NATTR; j++) 305*61ba55bcSBaptiste Daroussin if (strstr(value, attr[j].name) != NULL) 306*61ba55bcSBaptiste Daroussin flags |= attr[j].value; 307*61ba55bcSBaptiste Daroussin *((int*)p[i].value) = bsddialog_color(fg, bg, flags); 308*61ba55bcSBaptiste Daroussin break; 309*61ba55bcSBaptiste Daroussin case COMPAT: 310*61ba55bcSBaptiste Daroussin /* 311*61ba55bcSBaptiste Daroussin * usr.sbin/bsdconfig/share/dialog.subr:2255 312*61ba55bcSBaptiste Daroussin * uses this parameter to set NO_SHADOW. 313*61ba55bcSBaptiste Daroussin * Set t.shadow.[y|x] for compatibilty. 314*61ba55bcSBaptiste Daroussin */ 315*61ba55bcSBaptiste Daroussin if (strcmp(name, "use_shadow") == 0) { 316*61ba55bcSBaptiste Daroussin if (strcasestr(value, "off") != NULL) 317*61ba55bcSBaptiste Daroussin t.shadow.y = t.shadow.x = 0; 318*61ba55bcSBaptiste Daroussin } 319*61ba55bcSBaptiste Daroussin break; 320*61ba55bcSBaptiste Daroussin } 321*61ba55bcSBaptiste Daroussin } 322*61ba55bcSBaptiste Daroussin 323*61ba55bcSBaptiste Daroussin fclose(fp); 324*61ba55bcSBaptiste Daroussin 325*61ba55bcSBaptiste Daroussin if(bsddialog_set_theme(&t) != BSDDIALOG_OK) 326*61ba55bcSBaptiste Daroussin exit_error(false, bsddialog_geterror()); 327*61ba55bcSBaptiste Daroussin } 328*61ba55bcSBaptiste Daroussin 329*61ba55bcSBaptiste Daroussin void setdeftheme(enum bsddialog_default_theme theme) 330*61ba55bcSBaptiste Daroussin { 331*61ba55bcSBaptiste Daroussin if (bsddialog_hascolors() == false) 332*61ba55bcSBaptiste Daroussin return; 333*61ba55bcSBaptiste Daroussin if (bsddialog_set_default_theme(theme) != BSDDIALOG_OK) 334*61ba55bcSBaptiste Daroussin exit_error(false, bsddialog_geterror()); 335*61ba55bcSBaptiste Daroussin } 336*61ba55bcSBaptiste Daroussin 337*61ba55bcSBaptiste Daroussin void startuptheme(void) 338*61ba55bcSBaptiste Daroussin { 339*61ba55bcSBaptiste Daroussin bool sep; 340*61ba55bcSBaptiste Daroussin char *env, *file, *home, path[PATH_MAX]; 341*61ba55bcSBaptiste Daroussin 342*61ba55bcSBaptiste Daroussin env = getenv("NO_COLOR"); 343*61ba55bcSBaptiste Daroussin if (env != NULL && env[0] != '\0') 344*61ba55bcSBaptiste Daroussin setdeftheme(BSDDIALOG_THEME_BLACKWHITE); 345*61ba55bcSBaptiste Daroussin 346*61ba55bcSBaptiste Daroussin if ((home = getenv("HOME")) != NULL) { 347*61ba55bcSBaptiste Daroussin sep = (strcmp(home, "/") == 0) ? false : true; 348*61ba55bcSBaptiste Daroussin 349*61ba55bcSBaptiste Daroussin snprintf(path, PATH_MAX, "%s%s.bsddialog.conf", 350*61ba55bcSBaptiste Daroussin home, sep ? "/" : ""); 351*61ba55bcSBaptiste Daroussin if (access(path, F_OK) == 0) 352*61ba55bcSBaptiste Daroussin loadtheme(path, false); 353*61ba55bcSBaptiste Daroussin 354*61ba55bcSBaptiste Daroussin if ((file = getenv("BSDDIALOG_COMPATRC")) != NULL) { 355*61ba55bcSBaptiste Daroussin snprintf(path, PATH_MAX, "%s%s%s", 356*61ba55bcSBaptiste Daroussin home, sep ? "/" : "", file); 357*61ba55bcSBaptiste Daroussin if (access(path, F_OK) == 0) 358*61ba55bcSBaptiste Daroussin loadtheme(path, true); 359*61ba55bcSBaptiste Daroussin } 360*61ba55bcSBaptiste Daroussin } 361*61ba55bcSBaptiste Daroussin if ((file = getenv("BSDDIALOG_THEMEFILE")) != NULL) { 362*61ba55bcSBaptiste Daroussin if (access(file, F_OK) == 0) 363*61ba55bcSBaptiste Daroussin loadtheme(file, false); 364*61ba55bcSBaptiste Daroussin } 365*61ba55bcSBaptiste Daroussin } 366*61ba55bcSBaptiste Daroussin 367*61ba55bcSBaptiste Daroussin void bikeshed(struct bsddialog_conf *conf) 368*61ba55bcSBaptiste Daroussin { 369*61ba55bcSBaptiste Daroussin int margin, i; 370*61ba55bcSBaptiste Daroussin int colors[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 371*61ba55bcSBaptiste Daroussin char delim[8] = {'[', '<', '(', '|', ']', '>', ')', '|'}; 372*61ba55bcSBaptiste Daroussin enum bsddialog_color col[6]; 373*61ba55bcSBaptiste Daroussin struct timeval tv; 374*61ba55bcSBaptiste Daroussin 375*61ba55bcSBaptiste Daroussin /* theme */ 376*61ba55bcSBaptiste Daroussin if (bsddialog_get_theme(&t) != BSDDIALOG_OK) 377*61ba55bcSBaptiste Daroussin exit_error(false, bsddialog_geterror()); 378*61ba55bcSBaptiste Daroussin 379*61ba55bcSBaptiste Daroussin gettimeofday(&tv, NULL); 380*61ba55bcSBaptiste Daroussin srand(tv.tv_usec); 381*61ba55bcSBaptiste Daroussin for (i = 0; i < 6; i++) { 382*61ba55bcSBaptiste Daroussin do { 383*61ba55bcSBaptiste Daroussin col[i] = rand() % 8; 384*61ba55bcSBaptiste Daroussin } while (colors[col[i]] == 1); 385*61ba55bcSBaptiste Daroussin colors[col[i]] = 1; 386*61ba55bcSBaptiste Daroussin } 387*61ba55bcSBaptiste Daroussin 388*61ba55bcSBaptiste Daroussin t.screen.color = bsddialog_color(col[4], col[3], 0); 389*61ba55bcSBaptiste Daroussin 390*61ba55bcSBaptiste Daroussin t.shadow.color = bsddialog_color(col[0], col[0], 0); 391*61ba55bcSBaptiste Daroussin t.shadow.y = 1, 392*61ba55bcSBaptiste Daroussin t.shadow.x = 2, 393*61ba55bcSBaptiste Daroussin 394*61ba55bcSBaptiste Daroussin t.dialog.delimtitle = (~rand() & 1) ? true : false; 395*61ba55bcSBaptiste Daroussin t.dialog.titlecolor = bsddialog_color(col[3], col[5], 0); 396*61ba55bcSBaptiste Daroussin t.dialog.lineraisecolor = bsddialog_color(col[0], col[5], 0); 397*61ba55bcSBaptiste Daroussin t.dialog.linelowercolor = bsddialog_color(col[0], col[5], 0); 398*61ba55bcSBaptiste Daroussin t.dialog.color = bsddialog_color(col[0], col[5], 0); 399*61ba55bcSBaptiste Daroussin t.dialog.bottomtitlecolor = bsddialog_color(col[0], col[5], 0); 400*61ba55bcSBaptiste Daroussin t.dialog.arrowcolor = bsddialog_color(col[3], col[5], 0); 401*61ba55bcSBaptiste Daroussin 402*61ba55bcSBaptiste Daroussin t.menu.f_prefixcolor = bsddialog_color(col[5], col[3], 0); 403*61ba55bcSBaptiste Daroussin t.menu.prefixcolor = bsddialog_color(col[0], col[5], 0); 404*61ba55bcSBaptiste Daroussin t.menu.f_selectorcolor = bsddialog_color(col[5], col[3], 0); 405*61ba55bcSBaptiste Daroussin t.menu.selectorcolor = bsddialog_color(col[0], col[5], 0); 406*61ba55bcSBaptiste Daroussin t.menu.f_desccolor = bsddialog_color(col[5], col[3], 0); 407*61ba55bcSBaptiste Daroussin t.menu.desccolor = bsddialog_color(col[0], col[5], 0); 408*61ba55bcSBaptiste Daroussin t.menu.f_namecolor = bsddialog_color(col[5], col[3], 0); 409*61ba55bcSBaptiste Daroussin t.menu.namecolor = bsddialog_color(col[3], col[5], 0); 410*61ba55bcSBaptiste Daroussin t.menu.f_shortcutcolor = bsddialog_color(col[1], col[3], 0); 411*61ba55bcSBaptiste Daroussin t.menu.shortcutcolor = bsddialog_color(col[1], col[5], 0); 412*61ba55bcSBaptiste Daroussin t.menu.bottomdesccolor = bsddialog_color(col[4], col[3], 0); 413*61ba55bcSBaptiste Daroussin t.menu.sepnamecolor = bsddialog_color(col[1], col[5], 0); 414*61ba55bcSBaptiste Daroussin t.menu.sepdesccolor = bsddialog_color(col[1], col[5], 0); 415*61ba55bcSBaptiste Daroussin 416*61ba55bcSBaptiste Daroussin t.form.f_fieldcolor = bsddialog_color(col[5], col[3], 0); 417*61ba55bcSBaptiste Daroussin t.form.fieldcolor = bsddialog_color(col[5], col[4], 0); 418*61ba55bcSBaptiste Daroussin t.form.readonlycolor = bsddialog_color(col[4], col[5], 0); 419*61ba55bcSBaptiste Daroussin t.form.bottomdesccolor = bsddialog_color(col[4], col[3], 0); 420*61ba55bcSBaptiste Daroussin 421*61ba55bcSBaptiste Daroussin t.bar.f_color = bsddialog_color(col[5], col[3], 0); 422*61ba55bcSBaptiste Daroussin t.bar.color = bsddialog_color(col[3], col[5], 0); 423*61ba55bcSBaptiste Daroussin 424*61ba55bcSBaptiste Daroussin t.button.minmargin = 1, 425*61ba55bcSBaptiste Daroussin t.button.maxmargin = 5, 426*61ba55bcSBaptiste Daroussin i = rand() % 4; 427*61ba55bcSBaptiste Daroussin t.button.leftdelim = delim[i]; 428*61ba55bcSBaptiste Daroussin t.button.rightdelim = delim[i + 4]; 429*61ba55bcSBaptiste Daroussin t.button.f_delimcolor = bsddialog_color(col[5], col[3], 0); 430*61ba55bcSBaptiste Daroussin t.button.delimcolor = bsddialog_color(col[0], col[5], 0); 431*61ba55bcSBaptiste Daroussin t.button.f_color = bsddialog_color(col[2], col[3], 0); 432*61ba55bcSBaptiste Daroussin t.button.color = bsddialog_color(col[0], col[5], 0); 433*61ba55bcSBaptiste Daroussin t.button.f_shortcutcolor = bsddialog_color(col[5], col[3], 0); 434*61ba55bcSBaptiste Daroussin t.button.shortcutcolor = bsddialog_color(col[1], col[5], 0); 435*61ba55bcSBaptiste Daroussin 436*61ba55bcSBaptiste Daroussin if (bsddialog_set_theme(&t)) 437*61ba55bcSBaptiste Daroussin exit_error(false, bsddialog_geterror()); 438*61ba55bcSBaptiste Daroussin 439*61ba55bcSBaptiste Daroussin /* conf */ 440*61ba55bcSBaptiste Daroussin conf->button.always_active = (~rand() & 1) ? true : false; 441*61ba55bcSBaptiste Daroussin if ((i = rand() % 3) != 0) /* default "d/m/y" */ 442*61ba55bcSBaptiste Daroussin conf->date.format = (i & 1) ? "m/d/y" : "y/m/d" ; 443*61ba55bcSBaptiste Daroussin if (conf->title != NULL) { 444*61ba55bcSBaptiste Daroussin memset(title, 0, 1024); 445*61ba55bcSBaptiste Daroussin margin = rand() % 5; 446*61ba55bcSBaptiste Daroussin memset(title, ' ', margin); 447*61ba55bcSBaptiste Daroussin strcpy(title + margin, conf->title); 448*61ba55bcSBaptiste Daroussin memset(title + strlen(title), ' ', margin); 449*61ba55bcSBaptiste Daroussin conf->title = title; 450*61ba55bcSBaptiste Daroussin } 451*61ba55bcSBaptiste Daroussin } 452