1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2021 Alfonso Sabato Siciliano
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #ifdef PORTNCURSES
29 #include <ncurses/curses.h>
30 #else
31 #include <curses.h>
32 #endif
33 
34 #include "bsddialog.h"
35 #include "lib_util.h"
36 #include "bsddialog_theme.h"
37 
38 #define GET_COLOR(bg, fg) (COLOR_PAIR(bg * 8 + fg +1))
39 
40 struct bsddialog_theme t;
41 
42 static struct bsddialog_theme bsddialogtheme = {
43 #define bgwidget  COLOR_WHITE
44 #define bgcurr    COLOR_YELLOW
45 	.shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
46 	.shadow.h     = 1,
47 	.shadow.w     = 2,
48 
49 	.terminal.color          = GET_COLOR(COLOR_BLACK, COLOR_CYAN),
50 	.widget.delimtitle       = true,
51 	.widget.titlecolor       = GET_COLOR(COLOR_YELLOW, bgwidget),
52 	.widget.lineraisecolor   = GET_COLOR(COLOR_BLACK,  bgwidget),
53 	.widget.linelowercolor   = GET_COLOR(COLOR_BLACK,  bgwidget),
54 	.widget.color            = GET_COLOR(COLOR_BLACK,  bgwidget),
55 	.widget.bottomtitlecolor = GET_COLOR(COLOR_BLACK,  bgwidget),
56 
57 	.text.hmargin = 1,
58 
59 	.menu.arrowcolor   = GET_COLOR(COLOR_YELLOW, bgwidget),
60 	.menu.f_desccolor  = GET_COLOR(COLOR_WHITE,  bgcurr),
61 	.menu.desccolor    = GET_COLOR(COLOR_BLACK,  bgwidget),
62 	.menu.f_namecolor  = GET_COLOR(COLOR_BLACK,  bgcurr),
63 	.menu.namecolor    = GET_COLOR(COLOR_YELLOW, bgwidget),
64 	.menu.namesepcolor = GET_COLOR(COLOR_YELLOW, bgwidget),
65 	.menu.descsepcolor = GET_COLOR(COLOR_YELLOW, bgwidget),
66 
67 	.form.f_fieldcolor  = GET_COLOR(COLOR_WHITE,  COLOR_BLUE),
68 	.form.fieldcolor    = GET_COLOR(COLOR_WHITE,  COLOR_CYAN),
69 	.form.readonlycolor = GET_COLOR(COLOR_CYAN,COLOR_WHITE),
70 
71 	.bar.f_color = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
72 	.bar.color   = GET_COLOR(COLOR_BLUE,  COLOR_WHITE),
73 
74 	.button.space        = 3,
75 	.button.leftch       = '[',
76 	.button.rightch      = ']',
77 	.button.f_delimcolor = GET_COLOR(COLOR_WHITE,  bgcurr),
78 	.button.delimcolor   = GET_COLOR(COLOR_BLACK,  bgwidget),
79 	.button.f_color      = GET_COLOR(COLOR_WHITE,  bgcurr)    | A_UNDERLINE,
80 	.button.color        = GET_COLOR(COLOR_BLACK,  bgwidget)  | A_UNDERLINE,
81 	.button.f_shortcutcolor = GET_COLOR(COLOR_BLACK, bgcurr)  | A_UNDERLINE,
82 	.button.shortcutcolor = GET_COLOR(COLOR_YELLOW, bgwidget) | A_UNDERLINE
83 };
84 
85 static struct bsddialog_theme blackwhite = {
86 #define bk  COLOR_BLACK
87 #define fg  COLOR_WHITE
88 	.shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
89 	.shadow.h     = 1,
90 	.shadow.w     = 2,
91 
92 	.terminal.color          = GET_COLOR(fg, bk),
93 	.widget.delimtitle       = true,
94 	.widget.titlecolor       = GET_COLOR(fg, bk),
95 	.widget.lineraisecolor   = GET_COLOR(fg, bk),
96 	.widget.linelowercolor   = GET_COLOR(fg, bk),
97 	.widget.color            = GET_COLOR(fg, bk),
98 	.widget.bottomtitlecolor = GET_COLOR(fg, bk),
99 
100 	.text.hmargin = 1,
101 
102 	.menu.arrowcolor   = GET_COLOR(fg, bk),
103 	.menu.f_desccolor  = GET_COLOR(fg, bk) | A_REVERSE,
104 	.menu.desccolor    = GET_COLOR(fg, bk),
105 	.menu.f_namecolor  = GET_COLOR(fg, bk) | A_REVERSE,
106 	.menu.namecolor    = GET_COLOR(fg, bk),
107 	.menu.namesepcolor = GET_COLOR(fg, bk),
108 	.menu.descsepcolor = GET_COLOR(fg, bk),
109 
110 	.form.f_fieldcolor  = GET_COLOR(fg, bk) | A_REVERSE,
111 	.form.fieldcolor    = GET_COLOR(fg, bk),
112 	.form.readonlycolor = GET_COLOR(fg, bk),
113 
114 	.bar.f_color = GET_COLOR(fg, bk) | A_REVERSE,
115 	.bar.color   = GET_COLOR(fg, bk),
116 
117 	.button.space           = 3,
118 	.button.leftch          = '[',
119 	.button.rightch         = ']',
120 	.button.f_delimcolor    = GET_COLOR(fg, bk),
121 	.button.delimcolor      = GET_COLOR(fg, bk),
122 	.button.f_color         = GET_COLOR(fg, bk) | A_UNDERLINE | A_REVERSE,
123 	.button.color           = GET_COLOR(fg, bk) | A_UNDERLINE,
124 	.button.f_shortcutcolor = GET_COLOR(fg, bk) | A_UNDERLINE | A_REVERSE,
125 	.button.shortcutcolor   = GET_COLOR(fg, bk) | A_UNDERLINE
126 };
127 
128 static struct bsddialog_theme dialogtheme = {
129 	.shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
130 	.shadow.h     = 1,
131 	.shadow.w     = 2,
132 
133 	.terminal.color          = GET_COLOR(COLOR_CYAN,  COLOR_BLUE)  | A_BOLD,
134 	.widget.delimtitle       = false,
135 	.widget.titlecolor       = GET_COLOR(COLOR_BLUE,  COLOR_WHITE) | A_BOLD,
136 	.widget.lineraisecolor   = GET_COLOR(COLOR_WHITE, COLOR_WHITE) | A_BOLD,
137 	.widget.linelowercolor   = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD,
138 	.widget.color            = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
139 	.widget.bottomtitlecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD,
140 
141 	.text.hmargin = 1,
142 
143 	.menu.arrowcolor   = GET_COLOR(COLOR_GREEN, COLOR_WHITE),
144 	.menu.f_desccolor  = GET_COLOR(COLOR_WHITE, COLOR_BLUE)  | A_BOLD,
145 	.menu.desccolor    = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD,
146 	.menu.f_namecolor  = GET_COLOR(COLOR_YELLOW,COLOR_BLUE)  | A_BOLD,
147 	.menu.namecolor    = GET_COLOR(COLOR_BLUE,  COLOR_WHITE) | A_BOLD,
148 	.menu.namesepcolor = GET_COLOR(COLOR_RED,   COLOR_WHITE),
149 	.menu.descsepcolor = GET_COLOR(COLOR_RED,   COLOR_WHITE),
150 
151 	.form.f_fieldcolor  = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
152 	.form.fieldcolor    = GET_COLOR(COLOR_WHITE, COLOR_CYAN) | A_BOLD,
153 	.form.readonlycolor = GET_COLOR(COLOR_CYAN,  COLOR_WHITE)| A_BOLD,
154 
155 	.bar.f_color = GET_COLOR(COLOR_WHITE, COLOR_BLUE)  | A_BOLD,
156 	.bar.color   = GET_COLOR(COLOR_BLUE,  COLOR_WHITE) | A_BOLD,
157 
158 	.button.space           = 3,
159 	.button.leftch          = '<',
160 	.button.rightch         = '>',
161 	.button.f_delimcolor    = GET_COLOR(COLOR_WHITE,  COLOR_BLUE)  | A_BOLD,
162 	.button.delimcolor      = GET_COLOR(COLOR_BLACK,  COLOR_WHITE),
163 	.button.f_color         = GET_COLOR(COLOR_YELLOW, COLOR_BLUE)  | A_BOLD,
164 	.button.color           = GET_COLOR(COLOR_BLACK,  COLOR_WHITE),
165 	.button.f_shortcutcolor = GET_COLOR(COLOR_WHITE,  COLOR_BLUE)  | A_BOLD,
166 	.button.shortcutcolor   = GET_COLOR(COLOR_RED,    COLOR_WHITE) | A_BOLD
167 };
168 
bsddialog_set_theme(struct bsddialog_theme newtheme)169 void bsddialog_set_theme(struct bsddialog_theme newtheme)
170 {
171 	t.shadow.color = newtheme.shadow.color;
172 	t.shadow.h     = newtheme.shadow.h;
173 	t.shadow.w     = newtheme.shadow.w;
174 
175 	t.terminal.color          = newtheme.terminal.color;
176 	t.widget.delimtitle       = newtheme.widget.delimtitle;
177 	t.widget.titlecolor       = newtheme.widget.titlecolor;
178 	t.widget.lineraisecolor   = newtheme.widget.lineraisecolor;
179 	t.widget.linelowercolor   = newtheme.widget.linelowercolor;
180 	t.widget.color            = newtheme.widget.color;
181 	t.widget.bottomtitlecolor = newtheme.widget.bottomtitlecolor;
182 
183 	t.text.hmargin = newtheme.text.hmargin;
184 
185 	t.menu.arrowcolor   = newtheme.menu.arrowcolor;
186 	t.menu.f_desccolor  = newtheme.menu.f_desccolor;
187 	t.menu.desccolor    = newtheme.menu.desccolor;
188 	t.menu.f_namecolor  = newtheme.menu.f_namecolor;
189 	t.menu.namecolor    = newtheme.menu.namecolor;
190 	t.menu.namesepcolor = newtheme.menu.namesepcolor;
191 	t.menu.descsepcolor = newtheme.menu.descsepcolor;
192 
193 	t.form.f_fieldcolor  = newtheme.form.f_fieldcolor;
194 	t.form.fieldcolor    = newtheme.form.fieldcolor;
195 	t.form.readonlycolor = newtheme.form.readonlycolor;
196 
197 	t.bar.f_color = newtheme.bar.f_color;
198 	t.bar.color   = newtheme.bar.color;
199 
200 	t.button.space           = newtheme.button.space;
201 	t.button.leftch          = newtheme.button.leftch;
202 	t.button.rightch         = newtheme.button.rightch;
203 	t.button.f_delimcolor    = newtheme.button.f_delimcolor;
204 	t.button.delimcolor      = newtheme.button.delimcolor;
205 	t.button.f_color         = newtheme.button.f_color;
206 	t.button.color           = newtheme.button.color;
207 	t.button.f_shortcutcolor = newtheme.button.f_shortcutcolor;
208 	t.button.shortcutcolor   = newtheme.button.shortcutcolor;
209 
210 	bkgd(t.terminal.color);
211 
212 	refresh();
213 }
214 
bsddialog_set_default_theme(enum bsddialog_default_theme newtheme)215 int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme)
216 {
217 
218 	if (newtheme == BSDDIALOG_THEME_DEFAULT)
219 		bsddialog_set_theme(dialogtheme);
220 	else if (newtheme == BSDDIALOG_THEME_BSDDIALOG)
221 		bsddialog_set_theme(bsddialogtheme);
222 	else if (newtheme == BSDDIALOG_THEME_BLACKWHITE)
223 		bsddialog_set_theme(blackwhite);
224 	else if (newtheme == BSDDIALOG_THEME_DIALOG)
225 		bsddialog_set_theme(dialogtheme);
226 	else
227 		RETURN_ERROR("Unknow default theme");
228 
229 	return 0;
230 }
231 
232 int
bsddialog_color(enum bsddialog_color background,enum bsddialog_color foreground)233 bsddialog_color(enum bsddialog_color background,
234     enum bsddialog_color foreground)
235 {
236 
237 	return GET_COLOR(background, foreground);
238 }
239 
bsddialog_get_theme()240 struct bsddialog_theme bsddialog_get_theme()
241 {
242 
243 	return t;
244 }
245