xref: /freebsd/contrib/bsddialog/utility/util_theme.c (revision a6d8be451f62d425b71a4874f7d4e133b9fb393c)
161ba55bcSBaptiste Daroussin /*-
261ba55bcSBaptiste Daroussin  * SPDX-License-Identifier: BSD-2-Clause
361ba55bcSBaptiste Daroussin  *
4*a6d8be45SAlfonso S. Siciliano  * Copyright (c) 2022-2024 Alfonso Sabato Siciliano
561ba55bcSBaptiste Daroussin  *
661ba55bcSBaptiste Daroussin  * Redistribution and use in source and binary forms, with or without
761ba55bcSBaptiste Daroussin  * modification, are permitted provided that the following conditions
861ba55bcSBaptiste Daroussin  * are met:
961ba55bcSBaptiste Daroussin  * 1. Redistributions of source code must retain the above copyright
1061ba55bcSBaptiste Daroussin  *    notice, this list of conditions and the following disclaimer.
1161ba55bcSBaptiste Daroussin  * 2. Redistributions in binary form must reproduce the above copyright
1261ba55bcSBaptiste Daroussin  *    notice, this list of conditions and the following disclaimer in the
1361ba55bcSBaptiste Daroussin  *    documentation and/or other materials provided with the distribution.
1461ba55bcSBaptiste Daroussin  *
1561ba55bcSBaptiste Daroussin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1661ba55bcSBaptiste Daroussin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1761ba55bcSBaptiste Daroussin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1861ba55bcSBaptiste Daroussin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1961ba55bcSBaptiste Daroussin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2061ba55bcSBaptiste Daroussin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2161ba55bcSBaptiste Daroussin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2261ba55bcSBaptiste Daroussin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2361ba55bcSBaptiste Daroussin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2461ba55bcSBaptiste Daroussin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2561ba55bcSBaptiste Daroussin  * SUCH DAMAGE.
2661ba55bcSBaptiste Daroussin  */
2761ba55bcSBaptiste Daroussin 
2861ba55bcSBaptiste Daroussin #include <sys/time.h>
2961ba55bcSBaptiste Daroussin 
3061ba55bcSBaptiste Daroussin #include <limits.h>
3161ba55bcSBaptiste Daroussin #include <stdio.h>
3261ba55bcSBaptiste Daroussin #include <stdlib.h>
3361ba55bcSBaptiste Daroussin #include <string.h>
3461ba55bcSBaptiste Daroussin #include <unistd.h>
3561ba55bcSBaptiste Daroussin #include <time.h>
3661ba55bcSBaptiste Daroussin 
3761ba55bcSBaptiste Daroussin #include <bsddialog.h>
3861ba55bcSBaptiste Daroussin #include <bsddialog_theme.h>
3961ba55bcSBaptiste Daroussin 
4061ba55bcSBaptiste Daroussin #include "util.h"
4161ba55bcSBaptiste Daroussin 
4261ba55bcSBaptiste Daroussin static struct bsddialog_theme t;
4361ba55bcSBaptiste Daroussin static char title[1024];
4461ba55bcSBaptiste Daroussin 
4561ba55bcSBaptiste Daroussin #define NPROPERTY  41
4661ba55bcSBaptiste Daroussin #define NCOLOR      8
4761ba55bcSBaptiste Daroussin #define NATTR       6
4861ba55bcSBaptiste Daroussin 
4961ba55bcSBaptiste Daroussin #define PROP_ERROR(name, error) do {                                           \
5061ba55bcSBaptiste Daroussin 	fclose(fp);                                                            \
5161ba55bcSBaptiste Daroussin 	exit_error(false, "%s for \"%s\"", error, name);                       \
5261ba55bcSBaptiste Daroussin } while (0)
5361ba55bcSBaptiste Daroussin 
5461ba55bcSBaptiste Daroussin enum typeproperty {
5561ba55bcSBaptiste Daroussin 	BOOL,
5661ba55bcSBaptiste Daroussin 	CHAR,
5761ba55bcSBaptiste Daroussin 	INT,
5861ba55bcSBaptiste Daroussin 	UINT,
5961ba55bcSBaptiste Daroussin 	COLOR,
6061ba55bcSBaptiste Daroussin 	COMPAT
6161ba55bcSBaptiste Daroussin };
6261ba55bcSBaptiste Daroussin 
6361ba55bcSBaptiste Daroussin struct property {
6461ba55bcSBaptiste Daroussin 	const char *comment;
6561ba55bcSBaptiste Daroussin 	const char *name;
6661ba55bcSBaptiste Daroussin 	enum typeproperty type;
6761ba55bcSBaptiste Daroussin 	void *value;
6861ba55bcSBaptiste Daroussin };
6961ba55bcSBaptiste Daroussin 
7061ba55bcSBaptiste Daroussin struct namevalue {
7161ba55bcSBaptiste Daroussin 	const char *name;
7261ba55bcSBaptiste Daroussin 	unsigned int value;
7361ba55bcSBaptiste Daroussin };
7461ba55bcSBaptiste Daroussin 
7561ba55bcSBaptiste Daroussin static struct namevalue color[NCOLOR] = {
7661ba55bcSBaptiste Daroussin 	{"black",   BSDDIALOG_BLACK},
7761ba55bcSBaptiste Daroussin 	{"red",     BSDDIALOG_RED},
7861ba55bcSBaptiste Daroussin 	{"green",   BSDDIALOG_GREEN},
7961ba55bcSBaptiste Daroussin 	{"yellow",  BSDDIALOG_YELLOW},
8061ba55bcSBaptiste Daroussin 	{"blue",    BSDDIALOG_BLUE},
8161ba55bcSBaptiste Daroussin 	{"magenta", BSDDIALOG_MAGENTA},
8261ba55bcSBaptiste Daroussin 	{"cyan",    BSDDIALOG_CYAN},
8361ba55bcSBaptiste Daroussin 	{"white",   BSDDIALOG_WHITE}
8461ba55bcSBaptiste Daroussin };
8561ba55bcSBaptiste Daroussin 
8661ba55bcSBaptiste Daroussin static struct namevalue attr[NATTR] = {
8761ba55bcSBaptiste Daroussin  	{"bold",       BSDDIALOG_BOLD},
8861ba55bcSBaptiste Daroussin 	{"reverse",    BSDDIALOG_REVERSE},
8961ba55bcSBaptiste Daroussin 	{"underline",  BSDDIALOG_UNDERLINE},
9061ba55bcSBaptiste Daroussin 	{"blink",      BSDDIALOG_BLINK},
9161ba55bcSBaptiste Daroussin 	{"halfbright", BSDDIALOG_HALFBRIGHT},
9261ba55bcSBaptiste Daroussin 	{"highlight",  BSDDIALOG_HIGHLIGHT}
9361ba55bcSBaptiste Daroussin };
9461ba55bcSBaptiste Daroussin 
9561ba55bcSBaptiste Daroussin static struct property p[NPROPERTY] = {
9661ba55bcSBaptiste Daroussin 	{"\n#Terminal\n", "theme.screen.color", COLOR, &t.screen.color},
9761ba55bcSBaptiste Daroussin 
9861ba55bcSBaptiste Daroussin 	{"\n# Shadow\n",
9961ba55bcSBaptiste Daroussin 	    "theme.shadow.color", COLOR, &t.shadow.color},
10061ba55bcSBaptiste Daroussin 	{"# shift down right from main widget\n",
10161ba55bcSBaptiste Daroussin 	    "theme.shadow.y", UINT, &t.shadow.y},
10261ba55bcSBaptiste Daroussin 	{"", "theme.shadow.x", UINT, &t.shadow.x},
10361ba55bcSBaptiste Daroussin 
10461ba55bcSBaptiste Daroussin 	{"\n# Main widget\n",
10561ba55bcSBaptiste Daroussin 	    "theme.dialog.color", COLOR, &t.dialog.color},
10661ba55bcSBaptiste Daroussin 	{"", "theme.dialog.delimtitle", BOOL, &t.dialog.delimtitle},
10761ba55bcSBaptiste Daroussin 	{"", "theme.dialog.titlecolor", COLOR, &t.dialog.titlecolor},
10861ba55bcSBaptiste Daroussin 	{"", "theme.dialog.lineraisecolor", COLOR, &t.dialog.lineraisecolor},
10961ba55bcSBaptiste Daroussin 	{"", "theme.dialog.linelowercolor", COLOR, &t.dialog.linelowercolor},
11061ba55bcSBaptiste Daroussin 	{"", "theme.dialog.bottomtitlecolor", COLOR,
11161ba55bcSBaptiste Daroussin 	    &t.dialog.bottomtitlecolor},
11261ba55bcSBaptiste Daroussin 	{"", "theme.dialog.arrowcolor", COLOR, &t.dialog.arrowcolor},
11361ba55bcSBaptiste Daroussin 
11461ba55bcSBaptiste Daroussin 	{"\n# Menus: --checklist, --menu, --radiolist\n"
11561ba55bcSBaptiste Daroussin 	    "# prefix [selector] shortcut name desc bottomdesc\n",
11661ba55bcSBaptiste Daroussin 	    "theme.menu.f_prefixcolor", COLOR, &t.menu.f_prefixcolor},
11761ba55bcSBaptiste Daroussin 	{"", "theme.menu.prefixcolor", COLOR, &t.menu.prefixcolor},
11861ba55bcSBaptiste Daroussin 	{"", "theme.menu.f_selectorcolor", COLOR, &t.menu.f_selectorcolor},
11961ba55bcSBaptiste Daroussin 	{"", "theme.menu.selectorcolor", COLOR, &t.menu.selectorcolor},
12061ba55bcSBaptiste Daroussin 	{"", "theme.menu.f_namecolor", COLOR, &t.menu.f_namecolor},
12161ba55bcSBaptiste Daroussin 	{"", "theme.menu.namecolor", COLOR, &t.menu.namecolor},
12261ba55bcSBaptiste Daroussin 	{"", "theme.menu.f_desccolor", COLOR, &t.menu.f_desccolor},
12361ba55bcSBaptiste Daroussin 	{"", "theme.menu.desccolor", COLOR, &t.menu.desccolor},
12461ba55bcSBaptiste Daroussin 	{"", "theme.menu.f_shortcutcolor", COLOR, &t.menu.f_shortcutcolor},
12561ba55bcSBaptiste Daroussin 	{"", "theme.menu.shortcutcolor", COLOR, &t.menu.shortcutcolor},
12661ba55bcSBaptiste Daroussin 	{"", "theme.menu.bottomdesccolor", COLOR, &t.menu.bottomdesccolor},
12761ba55bcSBaptiste Daroussin 	{"# bsddialog_menutype BSDDIALOG_SEPARATOR\n",
12861ba55bcSBaptiste Daroussin 	    "theme.menu.sepnamecolor", COLOR, &t.menu.sepnamecolor},
12961ba55bcSBaptiste Daroussin 	{"", "theme.menu.sepdesccolor", COLOR, &t.menu.sepdesccolor},
13061ba55bcSBaptiste Daroussin 
13161ba55bcSBaptiste Daroussin 	{"\n# Forms\n",
13261ba55bcSBaptiste Daroussin 	    "theme.form.f_fieldcolor", COLOR, &t.form.f_fieldcolor},
13361ba55bcSBaptiste Daroussin 	{"", "theme.form.fieldcolor", COLOR, &t.form.fieldcolor},
13461ba55bcSBaptiste Daroussin 	{"", "theme.form.readonlycolor", COLOR, &t.form.readonlycolor},
13561ba55bcSBaptiste Daroussin 	{"", "theme.form.bottomdesccolor", COLOR, &t.form.bottomdesccolor},
13661ba55bcSBaptiste Daroussin 
13761ba55bcSBaptiste Daroussin 	{"\n# Bar of --gauge, --mixedgauge, --pause, --rangebox\n",
13861ba55bcSBaptiste Daroussin 	    "theme.bar.f_color", COLOR, &t.bar.f_color},
13961ba55bcSBaptiste Daroussin 	{"", "theme.bar.color", COLOR, &t.bar.color},
14061ba55bcSBaptiste Daroussin 
14161ba55bcSBaptiste Daroussin 	{"\n# Buttons\n",
14261ba55bcSBaptiste Daroussin 	    "theme.button.minmargin", UINT, &t.button.minmargin},
14361ba55bcSBaptiste Daroussin 	{"", "theme.button.maxmargin", UINT, &t.button.maxmargin},
14461ba55bcSBaptiste Daroussin 	{"", "theme.button.leftdelim", CHAR, &t.button.leftdelim},
14561ba55bcSBaptiste Daroussin 	{"", "theme.button.rightdelim", CHAR, &t.button.rightdelim},
14661ba55bcSBaptiste Daroussin 	{"", "theme.button.f_delimcolor", COLOR, &t.button.f_delimcolor},
14761ba55bcSBaptiste Daroussin 	{"", "theme.button.delimcolor", COLOR, &t.button.delimcolor},
14861ba55bcSBaptiste Daroussin 	{"", "theme.button.f_color", COLOR, &t.button.f_color},
14961ba55bcSBaptiste Daroussin 	{"", "theme.button.color", COLOR, &t.button.color},
15061ba55bcSBaptiste Daroussin 	{"", "theme.button.f_shortcutcolor", COLOR, &t.button.f_shortcutcolor},
15161ba55bcSBaptiste Daroussin 	{"", "theme.button.shortcutcolor", COLOR, &t.button.shortcutcolor},
15261ba55bcSBaptiste Daroussin 
15361ba55bcSBaptiste Daroussin 	{"\n#Compatibility. Do not use, can be deleted\n",
15461ba55bcSBaptiste Daroussin 	    "use_shadow", COMPAT, NULL}
15561ba55bcSBaptiste Daroussin };
15661ba55bcSBaptiste Daroussin 
15761ba55bcSBaptiste Daroussin void savetheme(const char *file)
15861ba55bcSBaptiste Daroussin {
15961ba55bcSBaptiste Daroussin 	int i, j;
16061ba55bcSBaptiste Daroussin 	unsigned int flags;
16161ba55bcSBaptiste Daroussin 	enum bsddialog_color bg, fg;
16261ba55bcSBaptiste Daroussin 	time_t clock;
16361ba55bcSBaptiste Daroussin 	FILE *fp;
16461ba55bcSBaptiste Daroussin 
16561ba55bcSBaptiste Daroussin 	if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
16661ba55bcSBaptiste Daroussin 		exit_error(false,
16761ba55bcSBaptiste Daroussin 		    "cannot save theme: %s", bsddialog_geterror());
16861ba55bcSBaptiste Daroussin 
16961ba55bcSBaptiste Daroussin 	if (time(&clock) < 0)
17061ba55bcSBaptiste Daroussin 		exit_error(false, "cannot save profile getting current time");
17161ba55bcSBaptiste Daroussin 	if ((fp = fopen(file, "w")) == NULL)
17261ba55bcSBaptiste Daroussin 		exit_error(false, "cannot open %s to save profile", file);
17361ba55bcSBaptiste Daroussin 
17461ba55bcSBaptiste Daroussin 	fprintf(fp, "### bsddialog theme - %s\n", ctime(&clock));
17561ba55bcSBaptiste Daroussin 
17661ba55bcSBaptiste Daroussin 	fputs("# Colors: ", fp);
17761ba55bcSBaptiste Daroussin 	fputs("black red green yellow blue magenta cyan white.\n", fp);
17861ba55bcSBaptiste Daroussin 	fputs("# Attributes: ", fp);
17961ba55bcSBaptiste Daroussin 	fputs("bold reverse underline blink halfbright highlight.\n", fp);
18061ba55bcSBaptiste Daroussin 	fputs("# f_* refers to focus for an element with selected or ", fp);
18161ba55bcSBaptiste Daroussin 	fputs("unselected state.\n\n", fp);
18261ba55bcSBaptiste Daroussin 
18361ba55bcSBaptiste Daroussin 	fprintf(fp, "version %s\n", LIBBSDDIALOG_VERSION);
18461ba55bcSBaptiste Daroussin 
18561ba55bcSBaptiste Daroussin 	for (i = 0; i < NPROPERTY; i++) {
18661ba55bcSBaptiste Daroussin 		if (p[i].type == COMPAT)
18761ba55bcSBaptiste Daroussin 			continue;
18861ba55bcSBaptiste Daroussin 		fprintf(fp, "%s%s", p[i].comment, p[i].name);
18961ba55bcSBaptiste Daroussin 		switch (p[i].type) {
19061ba55bcSBaptiste Daroussin 		case CHAR:
19161ba55bcSBaptiste Daroussin 			fprintf(fp, " %c\n", *((char*)p[i].value));
19261ba55bcSBaptiste Daroussin 			break;
19361ba55bcSBaptiste Daroussin 		case INT:
19461ba55bcSBaptiste Daroussin 			fprintf(fp, " %d\n", *((int*)p[i].value));
19561ba55bcSBaptiste Daroussin 			break;
19661ba55bcSBaptiste Daroussin 		case UINT:
19761ba55bcSBaptiste Daroussin 			fprintf(fp, " %u\n", *((unsigned int*)p[i].value));
19861ba55bcSBaptiste Daroussin 			break;
19961ba55bcSBaptiste Daroussin 		case BOOL:
20061ba55bcSBaptiste Daroussin 			fprintf(fp, " %s\n",
20161ba55bcSBaptiste Daroussin 			    *((bool*)p[i].value) ? "true" : "false");
20261ba55bcSBaptiste Daroussin 			break;
20361ba55bcSBaptiste Daroussin 		case COLOR:
20461ba55bcSBaptiste Daroussin 			bsddialog_color_attrs(*(int*)p[i].value, &fg, &bg,
20561ba55bcSBaptiste Daroussin 			    &flags);
20661ba55bcSBaptiste Daroussin 			fprintf(fp, " %s %s", color[fg].name, color[bg].name);
20761ba55bcSBaptiste Daroussin 			for (j = 0; j < NATTR; j++)
20861ba55bcSBaptiste Daroussin 				if (flags & attr[j].value)
20961ba55bcSBaptiste Daroussin 					fprintf(fp, " %s", attr[j].name);
21061ba55bcSBaptiste Daroussin 			fputs("\n", fp);
21161ba55bcSBaptiste Daroussin 			break;
21261ba55bcSBaptiste Daroussin 		case COMPAT:
21361ba55bcSBaptiste Daroussin 			/* Do not save compat property for now */
21461ba55bcSBaptiste Daroussin 			break;
21561ba55bcSBaptiste Daroussin 		}
21661ba55bcSBaptiste Daroussin 	}
21761ba55bcSBaptiste Daroussin 
21861ba55bcSBaptiste Daroussin 	fclose(fp);
21961ba55bcSBaptiste Daroussin }
22061ba55bcSBaptiste Daroussin 
22161ba55bcSBaptiste Daroussin void loadtheme(const char *file, bool compatibility)
22261ba55bcSBaptiste Daroussin {
22361ba55bcSBaptiste Daroussin 	bool boolvalue;
22461ba55bcSBaptiste Daroussin 	char charvalue, *value;
22561ba55bcSBaptiste Daroussin 	char line[BUFSIZ], name[BUFSIZ], c1[BUFSIZ], c2[BUFSIZ];
22661ba55bcSBaptiste Daroussin 	int i, j, intvalue;
22761ba55bcSBaptiste Daroussin 	unsigned int uintvalue, flags;
22861ba55bcSBaptiste Daroussin 	enum bsddialog_color bg, fg;
22961ba55bcSBaptiste Daroussin 	FILE *fp;
23061ba55bcSBaptiste Daroussin 
23161ba55bcSBaptiste Daroussin 	if (bsddialog_hascolors() == false)
23261ba55bcSBaptiste Daroussin 		return;
23361ba55bcSBaptiste Daroussin 
23461ba55bcSBaptiste Daroussin 	if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
23561ba55bcSBaptiste Daroussin 		exit_error(false, "Cannot get current theme: %s",
23661ba55bcSBaptiste Daroussin 		    bsddialog_geterror());
23761ba55bcSBaptiste Daroussin 
23861ba55bcSBaptiste Daroussin 	if ((fp = fopen(file, "r")) == NULL)
23961ba55bcSBaptiste Daroussin 		exit_error(false, "Cannot open theme \"%s\" file", file);
24061ba55bcSBaptiste Daroussin 
24161ba55bcSBaptiste Daroussin 	while (fgets(line, BUFSIZ, fp) != NULL) {
24261ba55bcSBaptiste Daroussin 		if (line[0] == '#' || line[0] == '\n')
24361ba55bcSBaptiste Daroussin 			continue;  /* superfluous, only for efficiency */
24461ba55bcSBaptiste Daroussin 		sscanf(line, "%s", name);
24561ba55bcSBaptiste Daroussin 		value = NULL; /* useless init, fix compiler warning */
24661ba55bcSBaptiste Daroussin 		for (i = 0; i < NPROPERTY; i++) {
24761ba55bcSBaptiste Daroussin 			if (strcmp(name, p[i].name) == 0) {
24861ba55bcSBaptiste Daroussin 				value = &line[strlen(name)];
24961ba55bcSBaptiste Daroussin 				break;
25061ba55bcSBaptiste Daroussin 			}
25161ba55bcSBaptiste Daroussin 		}
25261ba55bcSBaptiste Daroussin 		if (i >= NPROPERTY) {
25361ba55bcSBaptiste Daroussin 			/* unknown name in property p[] */
25461ba55bcSBaptiste Daroussin 			if (strcmp(name, "version") == 0)
25561ba55bcSBaptiste Daroussin 				continue; /* nothing for now */
25661ba55bcSBaptiste Daroussin 			else if (compatibility)
25761ba55bcSBaptiste Daroussin 				continue; /* just ignore */
25861ba55bcSBaptiste Daroussin 			else
25961ba55bcSBaptiste Daroussin 				PROP_ERROR(name, "Unknown theme property name");
26061ba55bcSBaptiste Daroussin 		}
26161ba55bcSBaptiste Daroussin 		switch (p[i].type) {
26261ba55bcSBaptiste Daroussin 		case CHAR:
26361ba55bcSBaptiste Daroussin 			while (value[0] == ' ' || value[0] == '\n' ||
26461ba55bcSBaptiste Daroussin 			    value[0] == '\0')
26561ba55bcSBaptiste Daroussin 				value++;
26661ba55bcSBaptiste Daroussin 			if (sscanf(value, "%c", &charvalue) != 1)
26761ba55bcSBaptiste Daroussin 				PROP_ERROR(p[i].name, "Cannot get a char");
26861ba55bcSBaptiste Daroussin 			*((int*)p[i].value) = charvalue;
26961ba55bcSBaptiste Daroussin 			break;
27061ba55bcSBaptiste Daroussin 		case INT:
27161ba55bcSBaptiste Daroussin 			if (sscanf(value, "%d", &intvalue) != 1)
27261ba55bcSBaptiste Daroussin 				PROP_ERROR(p[i].name, "Cannot get a int");
27361ba55bcSBaptiste Daroussin 			*((int*)p[i].value) = intvalue;
27461ba55bcSBaptiste Daroussin 			break;
27561ba55bcSBaptiste Daroussin 		case UINT:
27661ba55bcSBaptiste Daroussin 			if (sscanf(value, "%u", &uintvalue) != 1)
27761ba55bcSBaptiste Daroussin 				PROP_ERROR(p[i].name, "Cannot get a uint");
27861ba55bcSBaptiste Daroussin 			*((unsigned int*)p[i].value) = uintvalue;
27961ba55bcSBaptiste Daroussin 			break;
28061ba55bcSBaptiste Daroussin 		case BOOL:
28161ba55bcSBaptiste Daroussin 			boolvalue = (strstr(value, "true") != NULL) ?
28261ba55bcSBaptiste Daroussin 			    true :false;
28361ba55bcSBaptiste Daroussin 			*((bool*)p[i].value) = boolvalue;
28461ba55bcSBaptiste Daroussin 			break;
28561ba55bcSBaptiste Daroussin 		case COLOR:
28661ba55bcSBaptiste Daroussin 			if (sscanf(value, "%s %s", c1, c2) != 2)
28761ba55bcSBaptiste Daroussin 				PROP_ERROR(p[i].name, "Cannot get 2 colors");
28861ba55bcSBaptiste Daroussin 			/* Foreground */
28961ba55bcSBaptiste Daroussin 			for (j = 0; j < NCOLOR ; j++)
29061ba55bcSBaptiste Daroussin 				if ((strstr(c1, color[j].name)) != NULL)
29161ba55bcSBaptiste Daroussin 					break;
29261ba55bcSBaptiste Daroussin 			if (j >= NCOLOR)
29361ba55bcSBaptiste Daroussin 				PROP_ERROR(p[i].name, "Bad foreground");
29461ba55bcSBaptiste Daroussin 			fg = color[j].value;
29561ba55bcSBaptiste Daroussin 			/* Background */
29661ba55bcSBaptiste Daroussin 			for (j = 0; j < NCOLOR ; j++)
29761ba55bcSBaptiste Daroussin 				if ((strstr(c2, color[j].name)) != NULL)
29861ba55bcSBaptiste Daroussin 					break;
29961ba55bcSBaptiste Daroussin 			if (j >= NCOLOR)
30061ba55bcSBaptiste Daroussin 				PROP_ERROR(p[i].name, "Bad background");
30161ba55bcSBaptiste Daroussin 			bg = color[j].value;
30261ba55bcSBaptiste Daroussin 			/* Flags */
30361ba55bcSBaptiste Daroussin 			flags = 0;
30461ba55bcSBaptiste Daroussin 			for (j = 0; j < NATTR; j++)
30561ba55bcSBaptiste Daroussin 				if (strstr(value, attr[j].name) != NULL)
30661ba55bcSBaptiste Daroussin 					flags |= attr[j].value;
30761ba55bcSBaptiste Daroussin 			*((int*)p[i].value) = bsddialog_color(fg, bg, flags);
30861ba55bcSBaptiste Daroussin 			break;
30961ba55bcSBaptiste Daroussin 		case COMPAT:
31061ba55bcSBaptiste Daroussin 			/*
31161ba55bcSBaptiste Daroussin 			 * usr.sbin/bsdconfig/share/dialog.subr:2255
31261ba55bcSBaptiste Daroussin 			 * uses this parameter to set NO_SHADOW.
31361ba55bcSBaptiste Daroussin 			 * Set t.shadow.[y|x] for compatibilty.
31461ba55bcSBaptiste Daroussin 			 */
31561ba55bcSBaptiste Daroussin 			if (strcmp(name, "use_shadow") == 0) {
31661ba55bcSBaptiste Daroussin 				 if (strcasestr(value, "off") != NULL)
31761ba55bcSBaptiste Daroussin 				 	t.shadow.y = t.shadow.x = 0;
31861ba55bcSBaptiste Daroussin 			}
31961ba55bcSBaptiste Daroussin 			break;
32061ba55bcSBaptiste Daroussin 		}
32161ba55bcSBaptiste Daroussin 	}
32261ba55bcSBaptiste Daroussin 
32361ba55bcSBaptiste Daroussin 	fclose(fp);
32461ba55bcSBaptiste Daroussin 
32561ba55bcSBaptiste Daroussin 	if (bsddialog_set_theme(&t) != BSDDIALOG_OK)
32661ba55bcSBaptiste Daroussin 		exit_error(false, bsddialog_geterror());
32761ba55bcSBaptiste Daroussin }
32861ba55bcSBaptiste Daroussin 
32961ba55bcSBaptiste Daroussin void setdeftheme(enum bsddialog_default_theme theme)
33061ba55bcSBaptiste Daroussin {
33161ba55bcSBaptiste Daroussin 	if (bsddialog_hascolors() == false)
33261ba55bcSBaptiste Daroussin 		return;
33361ba55bcSBaptiste Daroussin 	if (bsddialog_set_default_theme(theme) != BSDDIALOG_OK)
33461ba55bcSBaptiste Daroussin 		exit_error(false, bsddialog_geterror());
33561ba55bcSBaptiste Daroussin }
33661ba55bcSBaptiste Daroussin 
33761ba55bcSBaptiste Daroussin void startuptheme(void)
33861ba55bcSBaptiste Daroussin {
33961ba55bcSBaptiste Daroussin 	bool sep;
34061ba55bcSBaptiste Daroussin 	char *env, *file, *home, path[PATH_MAX];
34161ba55bcSBaptiste Daroussin 
34261ba55bcSBaptiste Daroussin 	env = getenv("NO_COLOR");
34361ba55bcSBaptiste Daroussin 	if (env != NULL && env[0] != '\0')
34461ba55bcSBaptiste Daroussin 		setdeftheme(BSDDIALOG_THEME_BLACKWHITE);
34561ba55bcSBaptiste Daroussin 
34661ba55bcSBaptiste Daroussin 	if ((home = getenv("HOME")) != NULL) {
34761ba55bcSBaptiste Daroussin 		sep = (strcmp(home, "/") == 0) ? false : true;
34861ba55bcSBaptiste Daroussin 
34961ba55bcSBaptiste Daroussin 		snprintf(path, PATH_MAX, "%s%s.bsddialog.conf",
35061ba55bcSBaptiste Daroussin 		    home, sep ? "/" : "");
35161ba55bcSBaptiste Daroussin 		if (access(path, F_OK) == 0)
35261ba55bcSBaptiste Daroussin 			loadtheme(path, false);
35361ba55bcSBaptiste Daroussin 
35461ba55bcSBaptiste Daroussin 		if ((file = getenv("BSDDIALOG_COMPATRC")) != NULL) {
35561ba55bcSBaptiste Daroussin 			snprintf(path, PATH_MAX, "%s%s%s",
35661ba55bcSBaptiste Daroussin 			    home, sep ? "/" : "", file);
35761ba55bcSBaptiste Daroussin 			if (access(path, F_OK) == 0)
35861ba55bcSBaptiste Daroussin 				loadtheme(path, true);
35961ba55bcSBaptiste Daroussin 		}
36061ba55bcSBaptiste Daroussin 	}
36161ba55bcSBaptiste Daroussin 	if ((file = getenv("BSDDIALOG_THEMEFILE")) != NULL) {
36261ba55bcSBaptiste Daroussin 		if (access(file, F_OK) == 0)
36361ba55bcSBaptiste Daroussin 			loadtheme(file, false);
36461ba55bcSBaptiste Daroussin 	}
36561ba55bcSBaptiste Daroussin }
36661ba55bcSBaptiste Daroussin 
36761ba55bcSBaptiste Daroussin void bikeshed(struct bsddialog_conf *conf)
36861ba55bcSBaptiste Daroussin {
36961ba55bcSBaptiste Daroussin 	int margin, i;
37061ba55bcSBaptiste Daroussin 	int colors[8] = {0, 0, 0, 0, 0, 0, 0, 0};
37161ba55bcSBaptiste Daroussin 	char delim[8] = {'[', '<', '(', '|', ']', '>', ')', '|'};
37261ba55bcSBaptiste Daroussin 	enum bsddialog_color col[6];
37361ba55bcSBaptiste Daroussin 	struct timeval tv;
37461ba55bcSBaptiste Daroussin 
37561ba55bcSBaptiste Daroussin 	/* theme */
37661ba55bcSBaptiste Daroussin 	if (bsddialog_get_theme(&t) != BSDDIALOG_OK)
37761ba55bcSBaptiste Daroussin 		exit_error(false, bsddialog_geterror());
37861ba55bcSBaptiste Daroussin 
37961ba55bcSBaptiste Daroussin 	gettimeofday(&tv, NULL);
38061ba55bcSBaptiste Daroussin 	srand(tv.tv_usec);
38161ba55bcSBaptiste Daroussin 	for (i = 0; i < 6; i++) {
38261ba55bcSBaptiste Daroussin 		do {
38361ba55bcSBaptiste Daroussin 			col[i] = rand() % 8;
38461ba55bcSBaptiste Daroussin 		} while (colors[col[i]] == 1);
38561ba55bcSBaptiste Daroussin 		colors[col[i]] = 1;
38661ba55bcSBaptiste Daroussin 	}
38761ba55bcSBaptiste Daroussin 
38861ba55bcSBaptiste Daroussin 	t.screen.color = bsddialog_color(col[4], col[3], 0);
38961ba55bcSBaptiste Daroussin 
39061ba55bcSBaptiste Daroussin 	t.shadow.color   = bsddialog_color(col[0], col[0], 0);
39161ba55bcSBaptiste Daroussin 	t.shadow.y       = 1,
39261ba55bcSBaptiste Daroussin 	t.shadow.x       = 2,
39361ba55bcSBaptiste Daroussin 
39461ba55bcSBaptiste Daroussin 	t.dialog.delimtitle       = (~rand() & 1) ? true : false;
39561ba55bcSBaptiste Daroussin 	t.dialog.titlecolor       = bsddialog_color(col[3], col[5], 0);
39661ba55bcSBaptiste Daroussin 	t.dialog.lineraisecolor   = bsddialog_color(col[0], col[5], 0);
39761ba55bcSBaptiste Daroussin 	t.dialog.linelowercolor   = bsddialog_color(col[0], col[5], 0);
39861ba55bcSBaptiste Daroussin 	t.dialog.color            = bsddialog_color(col[0], col[5], 0);
39961ba55bcSBaptiste Daroussin 	t.dialog.bottomtitlecolor = bsddialog_color(col[0], col[5], 0);
40061ba55bcSBaptiste Daroussin 	t.dialog.arrowcolor       = bsddialog_color(col[3], col[5], 0);
40161ba55bcSBaptiste Daroussin 
40261ba55bcSBaptiste Daroussin 	t.menu.f_prefixcolor   = bsddialog_color(col[5], col[3], 0);
40361ba55bcSBaptiste Daroussin 	t.menu.prefixcolor     = bsddialog_color(col[0], col[5], 0);
40461ba55bcSBaptiste Daroussin 	t.menu.f_selectorcolor = bsddialog_color(col[5], col[3], 0);
40561ba55bcSBaptiste Daroussin 	t.menu.selectorcolor   = bsddialog_color(col[0], col[5], 0);
40661ba55bcSBaptiste Daroussin 	t.menu.f_desccolor     = bsddialog_color(col[5], col[3], 0);
40761ba55bcSBaptiste Daroussin 	t.menu.desccolor       = bsddialog_color(col[0], col[5], 0);
40861ba55bcSBaptiste Daroussin 	t.menu.f_namecolor     = bsddialog_color(col[5], col[3], 0);
40961ba55bcSBaptiste Daroussin 	t.menu.namecolor       = bsddialog_color(col[3], col[5], 0);
41061ba55bcSBaptiste Daroussin 	t.menu.f_shortcutcolor = bsddialog_color(col[1], col[3], 0);
41161ba55bcSBaptiste Daroussin 	t.menu.shortcutcolor   = bsddialog_color(col[1], col[5], 0);
41261ba55bcSBaptiste Daroussin 	t.menu.bottomdesccolor = bsddialog_color(col[4], col[3], 0);
41361ba55bcSBaptiste Daroussin 	t.menu.sepnamecolor    = bsddialog_color(col[1], col[5], 0);
41461ba55bcSBaptiste Daroussin 	t.menu.sepdesccolor    = bsddialog_color(col[1], col[5], 0);
41561ba55bcSBaptiste Daroussin 
41661ba55bcSBaptiste Daroussin 	t.form.f_fieldcolor    = bsddialog_color(col[5], col[3], 0);
41761ba55bcSBaptiste Daroussin 	t.form.fieldcolor      = bsddialog_color(col[5], col[4], 0);
41861ba55bcSBaptiste Daroussin 	t.form.readonlycolor   = bsddialog_color(col[4], col[5], 0);
41961ba55bcSBaptiste Daroussin 	t.form.bottomdesccolor = bsddialog_color(col[4], col[3], 0);
42061ba55bcSBaptiste Daroussin 
42161ba55bcSBaptiste Daroussin 	t.bar.f_color = bsddialog_color(col[5], col[3], 0);
42261ba55bcSBaptiste Daroussin 	t.bar.color   = bsddialog_color(col[3], col[5], 0);
42361ba55bcSBaptiste Daroussin 
42461ba55bcSBaptiste Daroussin 	t.button.minmargin       = 1,
42561ba55bcSBaptiste Daroussin 	t.button.maxmargin       = 5,
42661ba55bcSBaptiste Daroussin 	i = rand() % 4;
42761ba55bcSBaptiste Daroussin 	t.button.leftdelim       = delim[i];
42861ba55bcSBaptiste Daroussin 	t.button.rightdelim      = delim[i + 4];
42961ba55bcSBaptiste Daroussin 	t.button.f_delimcolor    = bsddialog_color(col[5], col[3], 0);
43061ba55bcSBaptiste Daroussin 	t.button.delimcolor      = bsddialog_color(col[0], col[5], 0);
43161ba55bcSBaptiste Daroussin 	t.button.f_color         = bsddialog_color(col[2], col[3], 0);
43261ba55bcSBaptiste Daroussin 	t.button.color           = bsddialog_color(col[0], col[5], 0);
43361ba55bcSBaptiste Daroussin 	t.button.f_shortcutcolor = bsddialog_color(col[5], col[3], 0);
43461ba55bcSBaptiste Daroussin 	t.button.shortcutcolor   = bsddialog_color(col[1], col[5], 0);
43561ba55bcSBaptiste Daroussin 
43661ba55bcSBaptiste Daroussin 	if (bsddialog_set_theme(&t))
43761ba55bcSBaptiste Daroussin 		exit_error(false, bsddialog_geterror());
43861ba55bcSBaptiste Daroussin 
43961ba55bcSBaptiste Daroussin 	/* conf */
44061ba55bcSBaptiste Daroussin 	conf->button.always_active = (~rand() & 1) ? true : false;
44161ba55bcSBaptiste Daroussin 	if ((i = rand() % 3) != 0) /* default "d/m/y" */
44261ba55bcSBaptiste Daroussin 		conf->date.format = (i & 1) ? "m/d/y" : "y/m/d" ;
44361ba55bcSBaptiste Daroussin 	if (conf->title != NULL) {
44461ba55bcSBaptiste Daroussin 		memset(title, 0, 1024);
44561ba55bcSBaptiste Daroussin 		margin = rand() % 5;
44661ba55bcSBaptiste Daroussin 		memset(title, ' ', margin);
44761ba55bcSBaptiste Daroussin 		strcpy(title + margin, conf->title);
44861ba55bcSBaptiste Daroussin 		memset(title + strlen(title), ' ', margin);
44961ba55bcSBaptiste Daroussin 		conf->title = title;
45061ba55bcSBaptiste Daroussin 	}
45161ba55bcSBaptiste Daroussin }
452