xref: /freebsd/contrib/bsddialog/utility/util_theme.c (revision 61ba55bcf70f2340f9c943c9571113b3fd8eda69)
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