xref: /freebsd-src/contrib/bsddialog/lib/barbox.c (revision 263660c061ac76d449cbca7bdd0db2ecdfad76d9)
1c76f0793SBaptiste Daroussin /*-
2c76f0793SBaptiste Daroussin  * SPDX-License-Identifier: BSD-2-Clause
3c76f0793SBaptiste Daroussin  *
4*263660c0SAlfonso Siciliano  * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
5c76f0793SBaptiste Daroussin  *
6c76f0793SBaptiste Daroussin  * Redistribution and use in source and binary forms, with or without
7c76f0793SBaptiste Daroussin  * modification, are permitted provided that the following conditions
8c76f0793SBaptiste Daroussin  * are met:
9c76f0793SBaptiste Daroussin  * 1. Redistributions of source code must retain the above copyright
10c76f0793SBaptiste Daroussin  *    notice, this list of conditions and the following disclaimer.
11c76f0793SBaptiste Daroussin  * 2. Redistributions in binary form must reproduce the above copyright
12c76f0793SBaptiste Daroussin  *    notice, this list of conditions and the following disclaimer in the
13c76f0793SBaptiste Daroussin  *    documentation and/or other materials provided with the distribution.
14c76f0793SBaptiste Daroussin  *
15c76f0793SBaptiste Daroussin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16c76f0793SBaptiste Daroussin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17c76f0793SBaptiste Daroussin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18c76f0793SBaptiste Daroussin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19c76f0793SBaptiste Daroussin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20c76f0793SBaptiste Daroussin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21c76f0793SBaptiste Daroussin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22c76f0793SBaptiste Daroussin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23c76f0793SBaptiste Daroussin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24c76f0793SBaptiste Daroussin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25c76f0793SBaptiste Daroussin  * SUCH DAMAGE.
26c76f0793SBaptiste Daroussin  */
27c76f0793SBaptiste Daroussin 
28f499134dSBaptiste Daroussin #include <sys/param.h>
29f499134dSBaptiste Daroussin 
30f499134dSBaptiste Daroussin #include <ctype.h>
31*263660c0SAlfonso Siciliano #include <curses.h>
32d93b4d32SBaptiste Daroussin #include <stdlib.h>
33d93b4d32SBaptiste Daroussin #include <string.h>
34d93b4d32SBaptiste Daroussin #include <time.h>
35*263660c0SAlfonso Siciliano #include <unistd.h>
36c76f0793SBaptiste Daroussin 
37c76f0793SBaptiste Daroussin #include "bsddialog.h"
38d93b4d32SBaptiste Daroussin #include "bsddialog_progressview.h"
39c76f0793SBaptiste Daroussin #include "bsddialog_theme.h"
40*263660c0SAlfonso Siciliano #include "lib_util.h"
41c76f0793SBaptiste Daroussin 
42*263660c0SAlfonso Siciliano #define BARPADDING    3
43*263660c0SAlfonso Siciliano #define MINBARWIDTH   (15 + BARPADDING * 2)
44d93b4d32SBaptiste Daroussin 
45d93b4d32SBaptiste Daroussin bool bsddialog_interruptprogview;
46d93b4d32SBaptiste Daroussin bool bsddialog_abortprogview;
47d93b4d32SBaptiste Daroussin int  bsddialog_total_progview;
48c76f0793SBaptiste Daroussin 
49c76f0793SBaptiste Daroussin extern struct bsddialog_theme t;
50c76f0793SBaptiste Daroussin 
51c76f0793SBaptiste Daroussin static void
52*263660c0SAlfonso Siciliano draw_bar(WINDOW *win, int y, int x, int size, int perc, bool withlabel,
53f499134dSBaptiste Daroussin     int label)
54c76f0793SBaptiste Daroussin {
55c76f0793SBaptiste Daroussin 	int i, blue_x, color;
56*263660c0SAlfonso Siciliano 	char labelstr[128];
57c76f0793SBaptiste Daroussin 
58c76f0793SBaptiste Daroussin 	blue_x = (int)((perc*(size))/100);
59c76f0793SBaptiste Daroussin 
60c76f0793SBaptiste Daroussin 	wmove(win, y, x);
61c76f0793SBaptiste Daroussin 	for (i = 0; i < size; i++) {
62f499134dSBaptiste Daroussin 		color = (i <= blue_x) ? t.bar.f_color : t.bar.color;
63c76f0793SBaptiste Daroussin 		wattron(win, color);
64c76f0793SBaptiste Daroussin 		waddch(win, ' ');
65c76f0793SBaptiste Daroussin 		wattroff(win, color);
66c76f0793SBaptiste Daroussin 	}
67c76f0793SBaptiste Daroussin 
68c76f0793SBaptiste Daroussin 	if (withlabel)
69c76f0793SBaptiste Daroussin 		sprintf(labelstr, "%d", label);
70c76f0793SBaptiste Daroussin 	else
71c76f0793SBaptiste Daroussin 		sprintf(labelstr, "%3d%%", perc);
72c76f0793SBaptiste Daroussin 	wmove(win, y, x + size/2 - 2);
73c76f0793SBaptiste Daroussin 	for (i = 0; i < (int)strlen(labelstr); i++) {
74f499134dSBaptiste Daroussin 		color = (blue_x + 1 <= size/2 - (int)strlen(labelstr)/2 + i ) ?
75f499134dSBaptiste Daroussin 		    t.bar.color : t.bar.f_color;
76c76f0793SBaptiste Daroussin 		wattron(win, color);
77c76f0793SBaptiste Daroussin 		waddch(win, labelstr[i]);
78c76f0793SBaptiste Daroussin 		wattroff(win, color);
79c76f0793SBaptiste Daroussin 	}
80c76f0793SBaptiste Daroussin }
81c76f0793SBaptiste Daroussin 
82f499134dSBaptiste Daroussin static int
83f499134dSBaptiste Daroussin bar_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
84*263660c0SAlfonso Siciliano     const char *text, struct buttons *bs)
85c76f0793SBaptiste Daroussin {
86*263660c0SAlfonso Siciliano 	int htext, wtext;
87c76f0793SBaptiste Daroussin 
88*263660c0SAlfonso Siciliano 	if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
89*263660c0SAlfonso Siciliano 		if (text_size(conf, rows, cols, text, bs, 3, MINBARWIDTH,
90*263660c0SAlfonso Siciliano 		    &htext, &wtext) != 0)
91*263660c0SAlfonso Siciliano 			return (BSDDIALOG_ERROR);
92f499134dSBaptiste Daroussin 	}
93c76f0793SBaptiste Daroussin 
94*263660c0SAlfonso Siciliano 	if (cols == BSDDIALOG_AUTOSIZE)
95*263660c0SAlfonso Siciliano 		*w = widget_min_width(conf, wtext, MINBARWIDTH, bs);
96c76f0793SBaptiste Daroussin 
97*263660c0SAlfonso Siciliano 	if (rows == BSDDIALOG_AUTOSIZE)
98*263660c0SAlfonso Siciliano 		*h = widget_min_height(conf, htext, 3 /* bar */, bs != NULL);
99f499134dSBaptiste Daroussin 
100f499134dSBaptiste Daroussin 	return (0);
101f499134dSBaptiste Daroussin }
102f499134dSBaptiste Daroussin 
103f499134dSBaptiste Daroussin static int
104*263660c0SAlfonso Siciliano bar_checksize(int rows, int cols, struct buttons *bs)
105f499134dSBaptiste Daroussin {
106f499134dSBaptiste Daroussin 	int minheight, minwidth;
107f499134dSBaptiste Daroussin 
108f499134dSBaptiste Daroussin 	minwidth = 0;
109f499134dSBaptiste Daroussin 	if (bs != NULL) { /* gauge has not buttons */
110f499134dSBaptiste Daroussin 		minwidth = bs->nbuttons * bs->sizebutton;
111f499134dSBaptiste Daroussin 		if (bs->nbuttons > 0)
112f499134dSBaptiste Daroussin 			minwidth += (bs->nbuttons-1) * t.button.space;
113f499134dSBaptiste Daroussin 	}
114*263660c0SAlfonso Siciliano 	minwidth = MAX(minwidth, MINBARWIDTH);
115*263660c0SAlfonso Siciliano 	minwidth += VBORDERS;
116f499134dSBaptiste Daroussin 
117f499134dSBaptiste Daroussin 	if (cols < minwidth)
118*263660c0SAlfonso Siciliano 		RETURN_ERROR("Few cols to draw bar and/or buttons");
119f499134dSBaptiste Daroussin 
120*263660c0SAlfonso Siciliano 	minheight = HBORDERS + 3;
121*263660c0SAlfonso Siciliano 	if (bs != NULL)
122*263660c0SAlfonso Siciliano 		minheight += 2;
123f499134dSBaptiste Daroussin 	if (rows < minheight)
124*263660c0SAlfonso Siciliano 		RETURN_ERROR("Few rows to draw bar");
125f499134dSBaptiste Daroussin 
126*263660c0SAlfonso Siciliano 	return (0);
127f499134dSBaptiste Daroussin }
128f499134dSBaptiste Daroussin 
129f499134dSBaptiste Daroussin int
130*263660c0SAlfonso Siciliano bsddialog_gauge(struct bsddialog_conf *conf, const char *text, int rows,
131*263660c0SAlfonso Siciliano     int cols, unsigned int perc, int fd, const char *sep)
132f499134dSBaptiste Daroussin {
133f499134dSBaptiste Daroussin 	bool mainloop;
134*263660c0SAlfonso Siciliano 	int y, x, h, w, fd2;
135*263660c0SAlfonso Siciliano 	FILE *input;
136*263660c0SAlfonso Siciliano 	WINDOW *widget, *textpad, *bar, *shadow;
137*263660c0SAlfonso Siciliano 	char inputbuf[2048], ntext[2048], *pntext;
138f499134dSBaptiste Daroussin 
139f499134dSBaptiste Daroussin 	if (set_widget_size(conf, rows, cols, &h, &w) != 0)
140*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
141f499134dSBaptiste Daroussin 	if (bar_autosize(conf, rows, cols, &h, &w, text, NULL) != 0)
142*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
143*263660c0SAlfonso Siciliano 	if (bar_checksize(h, w, NULL) != 0)
144*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
145f499134dSBaptiste Daroussin 	if (set_widget_position(conf, &y, &x, h, w) != 0)
146*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
147f499134dSBaptiste Daroussin 
148*263660c0SAlfonso Siciliano 	if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, NULL,
149*263660c0SAlfonso Siciliano 	    false) != 0)
150*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
151f499134dSBaptiste Daroussin 
152f499134dSBaptiste Daroussin 	bar = new_boxed_window(conf, y+h-4, x+3, 3, w-6, RAISED);
153f499134dSBaptiste Daroussin 
154*263660c0SAlfonso Siciliano 	mainloop = (fd < 0) ? false : true;
155*263660c0SAlfonso Siciliano 
156*263660c0SAlfonso Siciliano 	if (mainloop) {
157*263660c0SAlfonso Siciliano 		fd2 = dup(fd);
158*263660c0SAlfonso Siciliano 		input = fdopen(fd2, "r");
159*263660c0SAlfonso Siciliano 		if (input == NULL)
160*263660c0SAlfonso Siciliano 			RETURN_ERROR("Cannot build FILE* from fd");
161*263660c0SAlfonso Siciliano 	} else
162*263660c0SAlfonso Siciliano 		input = NULL;
163*263660c0SAlfonso Siciliano 
164c76f0793SBaptiste Daroussin 	while (mainloop) {
165c76f0793SBaptiste Daroussin 		wrefresh(widget);
166*263660c0SAlfonso Siciliano 		prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-4,
167*263660c0SAlfonso Siciliano 		    x+w-1-TEXTHMARGIN);
168*263660c0SAlfonso Siciliano 		draw_borders(conf, bar, 3, w-6, RAISED);
169*263660c0SAlfonso Siciliano 		draw_bar(bar, 1, 1, w-8, perc, false, -1 /*unused*/);
170c76f0793SBaptiste Daroussin 		wrefresh(bar);
171c76f0793SBaptiste Daroussin 
172c76f0793SBaptiste Daroussin 		while (true) {
173*263660c0SAlfonso Siciliano 			fscanf(input, "%s", inputbuf);
174*263660c0SAlfonso Siciliano 			if (strcmp(inputbuf,"EOF") == 0) {
175c76f0793SBaptiste Daroussin 				mainloop = false;
176c76f0793SBaptiste Daroussin 				break;
177c76f0793SBaptiste Daroussin 			}
178*263660c0SAlfonso Siciliano 			if (strcmp(inputbuf, sep) == 0)
179c76f0793SBaptiste Daroussin 				break;
180c76f0793SBaptiste Daroussin 		}
181*263660c0SAlfonso Siciliano 		if (mainloop == false)
182*263660c0SAlfonso Siciliano 			break;
183*263660c0SAlfonso Siciliano 		fscanf(input, "%d", &perc);
184c76f0793SBaptiste Daroussin 		perc = perc < 0 ? 0 : perc;
185c76f0793SBaptiste Daroussin 		perc = perc > 100 ? 100 : perc;
186f499134dSBaptiste Daroussin 		pntext = &ntext[0];
187f499134dSBaptiste Daroussin 		ntext[0] = '\0';
188c76f0793SBaptiste Daroussin 		while (true) {
189*263660c0SAlfonso Siciliano 			fscanf(input, "%s", inputbuf);
190*263660c0SAlfonso Siciliano 			if (strcmp(inputbuf,"EOF") == 0) {
191c76f0793SBaptiste Daroussin 				mainloop = false;
192c76f0793SBaptiste Daroussin 				break;
193c76f0793SBaptiste Daroussin 			}
194*263660c0SAlfonso Siciliano 			if (strcmp(inputbuf, sep) == 0)
195c76f0793SBaptiste Daroussin 				break;
196*263660c0SAlfonso Siciliano 			strcpy(pntext, inputbuf);
197*263660c0SAlfonso Siciliano 			pntext += strlen(inputbuf);
198f499134dSBaptiste Daroussin 			pntext[0] = ' ';
199f499134dSBaptiste Daroussin 			pntext++;
200c76f0793SBaptiste Daroussin 		}
201*263660c0SAlfonso Siciliano 		if (update_dialog(conf, shadow, widget, y, x, h, w, textpad,
202*263660c0SAlfonso Siciliano 		    ntext, NULL, false) != 0)
203*263660c0SAlfonso Siciliano 			return (BSDDIALOG_ERROR);
204c76f0793SBaptiste Daroussin 	}
205c76f0793SBaptiste Daroussin 
206*263660c0SAlfonso Siciliano 	if (input != NULL)
207*263660c0SAlfonso Siciliano 		fclose(input);
208c76f0793SBaptiste Daroussin 	delwin(bar);
209*263660c0SAlfonso Siciliano 	end_dialog(conf, shadow, widget, textpad);
210c76f0793SBaptiste Daroussin 
211*263660c0SAlfonso Siciliano 	return (BSDDIALOG_OK);
212c76f0793SBaptiste Daroussin }
213c76f0793SBaptiste Daroussin 
214d93b4d32SBaptiste Daroussin /* Mixedgauge */
215d93b4d32SBaptiste Daroussin static int
216*263660c0SAlfonso Siciliano do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
217*263660c0SAlfonso Siciliano     unsigned int mainperc, unsigned int nminibars, const char **minilabels,
218d93b4d32SBaptiste Daroussin     int *minipercs, bool color)
219c76f0793SBaptiste Daroussin {
220*263660c0SAlfonso Siciliano 	int i, output, miniperc, y, x, h, w, ypad, max_minbarlen;
221*263660c0SAlfonso Siciliano 	int htextpad, htext, wtext;
222d93b4d32SBaptiste Daroussin 	int colorperc, red, green;
223*263660c0SAlfonso Siciliano 	WINDOW *widget, *textpad, *bar, *shadow;
224d93b4d32SBaptiste Daroussin 	char states[12][14] = {
225*263660c0SAlfonso Siciliano 		"  Succeeded  ", /* -1  */
226*263660c0SAlfonso Siciliano 		"   Failed    ", /* -2  */
227*263660c0SAlfonso Siciliano 		"   Passed    ", /* -3  */
228*263660c0SAlfonso Siciliano 		"  Completed  ", /* -4  */
229*263660c0SAlfonso Siciliano 		"   Checked   ", /* -5  */
230*263660c0SAlfonso Siciliano 		"    Done     ", /* -6  */
231*263660c0SAlfonso Siciliano 		"   Skipped   ", /* -7  */
232*263660c0SAlfonso Siciliano 		" In Progress ", /* -8  */
233*263660c0SAlfonso Siciliano 		"(blank)      ", /* -9  */
234*263660c0SAlfonso Siciliano 		"     N/A     ", /* -10 */
235*263660c0SAlfonso Siciliano 		"   Pending   ", /* -11 */
236*263660c0SAlfonso Siciliano 		"   UNKNOWN   ", /* < -11, no API */
237f499134dSBaptiste Daroussin 	};
238c76f0793SBaptiste Daroussin 
239d93b4d32SBaptiste Daroussin 	red   = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_RED,  BSDDIALOG_BOLD);
240d93b4d32SBaptiste Daroussin 	green = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_GREEN,BSDDIALOG_BOLD);
241d93b4d32SBaptiste Daroussin 
242f499134dSBaptiste Daroussin 	max_minbarlen = 0;
2438c4f4028SBaptiste Daroussin 	for (i = 0; i < (int)nminibars; i++)
2448c4f4028SBaptiste Daroussin 		max_minbarlen = MAX(max_minbarlen, (int)strlen(minilabels[i]));
245f499134dSBaptiste Daroussin 	max_minbarlen += 3 + 16 /* seps + [...] or mainbar */;
246f499134dSBaptiste Daroussin 
247f499134dSBaptiste Daroussin 	if (set_widget_size(conf, rows, cols, &h, &w) != 0)
248*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
249f499134dSBaptiste Daroussin 
250f499134dSBaptiste Daroussin 	/* mixedgauge autosize */
251*263660c0SAlfonso Siciliano 	if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
252*263660c0SAlfonso Siciliano 		if (text_size(conf, rows, cols, text, NULL, nminibars + 3,
253*263660c0SAlfonso Siciliano 		    max_minbarlen, &htext, &wtext) != 0)
254*263660c0SAlfonso Siciliano 			return (BSDDIALOG_ERROR);
255f499134dSBaptiste Daroussin 	}
256*263660c0SAlfonso Siciliano 	if (cols == BSDDIALOG_AUTOSIZE)
257*263660c0SAlfonso Siciliano 		w = widget_min_width(conf, wtext, max_minbarlen, NULL);
258*263660c0SAlfonso Siciliano 	if (rows == BSDDIALOG_AUTOSIZE)
259*263660c0SAlfonso Siciliano 		h = widget_min_height(conf, htext, nminibars + 3, false);
260f499134dSBaptiste Daroussin 
261f499134dSBaptiste Daroussin 	/* mixedgauge checksize */
262f499134dSBaptiste Daroussin 	if (w < max_minbarlen + 2)
263f499134dSBaptiste Daroussin 		RETURN_ERROR("Few cols for this mixedgauge");
264*263660c0SAlfonso Siciliano 	if (h < 5 + (int)nminibars)
265f499134dSBaptiste Daroussin 		RETURN_ERROR("Few rows for this mixedgauge");
266f499134dSBaptiste Daroussin 
267f499134dSBaptiste Daroussin 	if (set_widget_position(conf, &y, &x, h, w) != 0)
268*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
269f499134dSBaptiste Daroussin 
270*263660c0SAlfonso Siciliano 	output = new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text,
271*263660c0SAlfonso Siciliano 	    NULL, false);
272f499134dSBaptiste Daroussin 	if (output == BSDDIALOG_ERROR)
273*263660c0SAlfonso Siciliano 		return (output);
274c76f0793SBaptiste Daroussin 
275c76f0793SBaptiste Daroussin 	/* mini bars */
2768c4f4028SBaptiste Daroussin 	for (i = 0; i < (int)nminibars; i++) {
2778c4f4028SBaptiste Daroussin 		miniperc = minipercs[i];
278*263660c0SAlfonso Siciliano 		if (miniperc == BSDDIALOG_MG_BLANK)
279c76f0793SBaptiste Daroussin 			continue;
280d93b4d32SBaptiste Daroussin 		/* label */
281*263660c0SAlfonso Siciliano 		if (color && (miniperc >= 0))
282d93b4d32SBaptiste Daroussin 			wattron(widget, A_BOLD);
2838c4f4028SBaptiste Daroussin 		mvwaddstr(widget, i+1, 2, minilabels[i]);
284d93b4d32SBaptiste Daroussin 			wattroff(widget, A_BOLD);
285d93b4d32SBaptiste Daroussin 		/* perc */
286*263660c0SAlfonso Siciliano 		if (miniperc < -11)
2878c4f4028SBaptiste Daroussin 			mvwaddstr(widget, i+1, w-2-15, states[11]);
288*263660c0SAlfonso Siciliano 		else if (miniperc < 0) {
289d93b4d32SBaptiste Daroussin 			mvwaddstr(widget, i+1, w-2-15, "[             ]");
290*263660c0SAlfonso Siciliano 			colorperc = -1;
291*263660c0SAlfonso Siciliano 			if (color && miniperc == BSDDIALOG_MG_FAILED)
292d93b4d32SBaptiste Daroussin 				colorperc = red;
293*263660c0SAlfonso Siciliano 			if (color && miniperc == BSDDIALOG_MG_DONE)
294d93b4d32SBaptiste Daroussin 				colorperc = green;
295*263660c0SAlfonso Siciliano 			if (colorperc != -1)
296d93b4d32SBaptiste Daroussin 				wattron(widget, colorperc);
297*263660c0SAlfonso Siciliano 			miniperc = abs(miniperc + 1);
298d93b4d32SBaptiste Daroussin 			mvwaddstr(widget, i+1, 1+w-2-15, states[miniperc]);
299*263660c0SAlfonso Siciliano 			if (colorperc != -1)
300d93b4d32SBaptiste Daroussin 				wattroff(widget, colorperc);
301d93b4d32SBaptiste Daroussin 		}
302*263660c0SAlfonso Siciliano 		else { /* miniperc >= 0 */
303*263660c0SAlfonso Siciliano 			if (miniperc > 100)
304*263660c0SAlfonso Siciliano 				miniperc = 100;
305f499134dSBaptiste Daroussin 			mvwaddstr(widget, i+1, w-2-15, "[             ]");
306*263660c0SAlfonso Siciliano 			draw_bar(widget, i+1, 1+w-2-15, 13, miniperc, false,
307*263660c0SAlfonso Siciliano 			    -1 /*unused*/);
308c76f0793SBaptiste Daroussin 		}
309c76f0793SBaptiste Daroussin 	}
310c76f0793SBaptiste Daroussin 
311f499134dSBaptiste Daroussin 	wrefresh(widget);
312*263660c0SAlfonso Siciliano 	getmaxyx(textpad, htextpad, i /* unused */);
313*263660c0SAlfonso Siciliano 	ypad =  y + h - 4 - htextpad;
3148c4f4028SBaptiste Daroussin 	ypad = ypad < y+(int)nminibars ? y+nminibars : ypad;
315f499134dSBaptiste Daroussin 	prefresh(textpad, 0, 0, ypad, x+2, y+h-4, x+w-2);
316c76f0793SBaptiste Daroussin 
317c76f0793SBaptiste Daroussin 	/* main bar */
318f499134dSBaptiste Daroussin 	bar = new_boxed_window(conf, y+h -4, x+3, 3, w-6, RAISED);
319c76f0793SBaptiste Daroussin 
320*263660c0SAlfonso Siciliano 	draw_bar(bar, 1, 1, w-8, mainperc, false, -1 /*unused*/);
321f499134dSBaptiste Daroussin 
322f499134dSBaptiste Daroussin 	wattron(bar, t.bar.color);
323c76f0793SBaptiste Daroussin 	mvwaddstr(bar, 0, 2, "Overall Progress");
324f499134dSBaptiste Daroussin 	wattroff(bar, t.bar.color);
325c76f0793SBaptiste Daroussin 
326c76f0793SBaptiste Daroussin 	wrefresh(bar);
327c76f0793SBaptiste Daroussin 
328f499134dSBaptiste Daroussin 	/* getch(); port ncurses shows nothing */
329c76f0793SBaptiste Daroussin 
330c76f0793SBaptiste Daroussin 	delwin(bar);
331*263660c0SAlfonso Siciliano 	end_dialog(conf, shadow, widget, textpad);
332c76f0793SBaptiste Daroussin 
333*263660c0SAlfonso Siciliano 	return (BSDDIALOG_OK);
334c76f0793SBaptiste Daroussin }
335c76f0793SBaptiste Daroussin 
336c76f0793SBaptiste Daroussin int
337*263660c0SAlfonso Siciliano bsddialog_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows,
338*263660c0SAlfonso Siciliano     int cols, unsigned int mainperc, unsigned int nminibars,
339*263660c0SAlfonso Siciliano     const char **minilabels, int *minipercs)
340d93b4d32SBaptiste Daroussin {
341d93b4d32SBaptiste Daroussin 	int output;
342d93b4d32SBaptiste Daroussin 
343*263660c0SAlfonso Siciliano 	output = do_mixedgauge(conf, text, rows, cols, mainperc, nminibars,
344d93b4d32SBaptiste Daroussin 	    minilabels, minipercs, false);
345d93b4d32SBaptiste Daroussin 
346d93b4d32SBaptiste Daroussin 	return (output);
347d93b4d32SBaptiste Daroussin }
348d93b4d32SBaptiste Daroussin 
349d93b4d32SBaptiste Daroussin int
350*263660c0SAlfonso Siciliano bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
351d93b4d32SBaptiste Daroussin     int cols, struct bsddialog_progviewconf *pvconf, unsigned int nminibar,
352d93b4d32SBaptiste Daroussin     struct bsddialog_fileminibar *minibar)
353d93b4d32SBaptiste Daroussin {
354d93b4d32SBaptiste Daroussin 	bool update;
355*263660c0SAlfonso Siciliano 	int perc, output, *minipercs;
356*263660c0SAlfonso Siciliano 	unsigned int i, mainperc, totaltodo;
357d93b4d32SBaptiste Daroussin 	float readforsec;
358*263660c0SAlfonso Siciliano 	const char **minilabels;
359*263660c0SAlfonso Siciliano 	time_t tstart, told, tnew, refresh;
360d93b4d32SBaptiste Daroussin 
361d93b4d32SBaptiste Daroussin 	if ((minilabels = calloc(nminibar, sizeof(char*))) == NULL)
362*263660c0SAlfonso Siciliano 		RETURN_ERROR("Cannot allocate memory for minilabels");
363d93b4d32SBaptiste Daroussin 	if ((minipercs = calloc(nminibar, sizeof(int))) == NULL)
364*263660c0SAlfonso Siciliano 		RETURN_ERROR("Cannot allocate memory for minipercs");
365d93b4d32SBaptiste Daroussin 
366d93b4d32SBaptiste Daroussin 	totaltodo = 0;
367d93b4d32SBaptiste Daroussin 	for (i = 0; i < nminibar; i++) {
368d93b4d32SBaptiste Daroussin 		totaltodo += minibar[i].size;
369d93b4d32SBaptiste Daroussin 		minilabels[i] = minibar[i].label;
370*263660c0SAlfonso Siciliano 		minipercs[i] = minibar[i].status;
371d93b4d32SBaptiste Daroussin 	}
372d93b4d32SBaptiste Daroussin 
373d93b4d32SBaptiste Daroussin 	refresh = pvconf->refresh == 0 ? 0 : pvconf->refresh - 1;
374d93b4d32SBaptiste Daroussin 	output = BSDDIALOG_OK;
375d93b4d32SBaptiste Daroussin 	i = 0;
376d93b4d32SBaptiste Daroussin 	update = true;
377d93b4d32SBaptiste Daroussin 	time(&told);
378d93b4d32SBaptiste Daroussin 	tstart = told;
379d93b4d32SBaptiste Daroussin 	while (!(bsddialog_interruptprogview || bsddialog_abortprogview)) {
380d93b4d32SBaptiste Daroussin 		if (bsddialog_total_progview == 0 || totaltodo == 0)
381d93b4d32SBaptiste Daroussin 			mainperc = 0;
382d93b4d32SBaptiste Daroussin 		else
383d93b4d32SBaptiste Daroussin 			mainperc = (bsddialog_total_progview * 100) / totaltodo;
384d93b4d32SBaptiste Daroussin 
385d93b4d32SBaptiste Daroussin 		time(&tnew);
386d93b4d32SBaptiste Daroussin 		if (update || tnew > told + refresh) {
387*263660c0SAlfonso Siciliano 			output = do_mixedgauge(conf, text, rows, cols, mainperc,
388d93b4d32SBaptiste Daroussin 			    nminibar, minilabels, minipercs, true);
389d93b4d32SBaptiste Daroussin 			if (output == BSDDIALOG_ERROR)
390*263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
391d93b4d32SBaptiste Daroussin 
392*263660c0SAlfonso Siciliano 			move(SCREENLINES - 1, 2);
393d93b4d32SBaptiste Daroussin 			clrtoeol();
394*263660c0SAlfonso Siciliano 			readforsec = ((tnew - tstart) == 0) ? 0 :
395*263660c0SAlfonso Siciliano 			    bsddialog_total_progview / (float)(tnew - tstart);
396d93b4d32SBaptiste Daroussin 			printw(pvconf->fmtbottomstr, bsddialog_total_progview,
397d93b4d32SBaptiste Daroussin 			    readforsec);
398d93b4d32SBaptiste Daroussin 			refresh();
399d93b4d32SBaptiste Daroussin 
400d93b4d32SBaptiste Daroussin 			time(&told);
401d93b4d32SBaptiste Daroussin 			update = false;
402d93b4d32SBaptiste Daroussin 		}
403d93b4d32SBaptiste Daroussin 
404d93b4d32SBaptiste Daroussin 		if (i >= nminibar)
405d93b4d32SBaptiste Daroussin 			break;
406*263660c0SAlfonso Siciliano 		if (minibar[i].status == BSDDIALOG_MG_FAILED)
407d93b4d32SBaptiste Daroussin 			break;
408d93b4d32SBaptiste Daroussin 
409d93b4d32SBaptiste Daroussin 		perc = pvconf->callback(&minibar[i]);
410d93b4d32SBaptiste Daroussin 
411*263660c0SAlfonso Siciliano 		if (minibar[i].status == BSDDIALOG_MG_DONE) { /*||perc >= 100)*/
412*263660c0SAlfonso Siciliano 			minipercs[i] = BSDDIALOG_MG_DONE;
413d93b4d32SBaptiste Daroussin 			update = true;
414d93b4d32SBaptiste Daroussin 			i++;
415*263660c0SAlfonso Siciliano 		} else if (minibar[i].status == BSDDIALOG_MG_FAILED || perc < 0) {
416*263660c0SAlfonso Siciliano 			minipercs[i] = BSDDIALOG_MG_FAILED;
417d93b4d32SBaptiste Daroussin 			update = true;
418*263660c0SAlfonso Siciliano 		} else /* perc >= 0 */
419*263660c0SAlfonso Siciliano 			minipercs[i] = perc;
420d93b4d32SBaptiste Daroussin 	}
421d93b4d32SBaptiste Daroussin 
422d93b4d32SBaptiste Daroussin 	free(minilabels);
423d93b4d32SBaptiste Daroussin 	free(minipercs);
424d93b4d32SBaptiste Daroussin 	return (output);
425d93b4d32SBaptiste Daroussin }
426d93b4d32SBaptiste Daroussin 
427d93b4d32SBaptiste Daroussin int
428*263660c0SAlfonso Siciliano bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
429*263660c0SAlfonso Siciliano     int cols, int min, int max, int *value)
430c76f0793SBaptiste Daroussin {
431c76f0793SBaptiste Daroussin 	bool loop, buttupdate, barupdate;
432*263660c0SAlfonso Siciliano 	int y, x, h, w;
433f499134dSBaptiste Daroussin 	int input, currvalue, output, sizebar, bigchange, positions;
434c76f0793SBaptiste Daroussin 	float perc;
435*263660c0SAlfonso Siciliano 	WINDOW *widget, *textpad, *bar, *shadow;
436c76f0793SBaptiste Daroussin 	struct buttons bs;
437c76f0793SBaptiste Daroussin 
438f499134dSBaptiste Daroussin 	if (value == NULL)
439f499134dSBaptiste Daroussin 		RETURN_ERROR("*value cannot be NULL");
440c76f0793SBaptiste Daroussin 
441f499134dSBaptiste Daroussin 	if (min >= max)
442f499134dSBaptiste Daroussin 		RETURN_ERROR("min >= max");
443f499134dSBaptiste Daroussin 
444f499134dSBaptiste Daroussin 	currvalue = *value;
445f499134dSBaptiste Daroussin 	positions = max - min + 1;
446c76f0793SBaptiste Daroussin 
447*263660c0SAlfonso Siciliano 	get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
448c76f0793SBaptiste Daroussin 
449f499134dSBaptiste Daroussin 	if (set_widget_size(conf, rows, cols, &h, &w) != 0)
450*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
451f499134dSBaptiste Daroussin 	if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0)
452*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
453*263660c0SAlfonso Siciliano 	if (bar_checksize(h, w, &bs) != 0)
454*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
455f499134dSBaptiste Daroussin 	if (set_widget_position(conf, &y, &x, h, w) != 0)
456*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
457c76f0793SBaptiste Daroussin 
458*263660c0SAlfonso Siciliano 	if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
459*263660c0SAlfonso Siciliano 	    true) != 0)
460*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
461f499134dSBaptiste Daroussin 
462*263660c0SAlfonso Siciliano 	doupdate();
463f499134dSBaptiste Daroussin 
464*263660c0SAlfonso Siciliano 	prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-7, x+w-1-TEXTHMARGIN);
465*263660c0SAlfonso Siciliano 
466*263660c0SAlfonso Siciliano 	sizebar = w - HBORDERS - 2 - BARPADDING * 2;
467f499134dSBaptiste Daroussin 	bigchange = MAX(1, sizebar/10);
468f499134dSBaptiste Daroussin 
469*263660c0SAlfonso Siciliano 	bar = new_boxed_window(conf, y + h - 6, x + 1 + BARPADDING, 3,
470f499134dSBaptiste Daroussin 	    sizebar + 2, RAISED);
471f499134dSBaptiste Daroussin 
472c76f0793SBaptiste Daroussin 	loop = buttupdate = barupdate = true;
473c76f0793SBaptiste Daroussin 	while (loop) {
474f499134dSBaptiste Daroussin 		if (buttupdate) {
475*263660c0SAlfonso Siciliano 			draw_buttons(widget, bs, true);
476f499134dSBaptiste Daroussin 			wrefresh(widget);
477f499134dSBaptiste Daroussin 			buttupdate = false;
478f499134dSBaptiste Daroussin 		}
479c76f0793SBaptiste Daroussin 		if (barupdate) {
480f499134dSBaptiste Daroussin 			perc = ((float)(currvalue - min)*100) / (positions-1);
481*263660c0SAlfonso Siciliano 			draw_bar(bar, 1, 1, sizebar, perc, true, currvalue);
482c76f0793SBaptiste Daroussin 			barupdate = false;
483c76f0793SBaptiste Daroussin 			wrefresh(bar);
484c76f0793SBaptiste Daroussin 		}
485c76f0793SBaptiste Daroussin 
486c76f0793SBaptiste Daroussin 		input = getch();
487c76f0793SBaptiste Daroussin 		switch(input) {
488f499134dSBaptiste Daroussin 		case KEY_ENTER:
489f499134dSBaptiste Daroussin 		case 10: /* Enter */
490f499134dSBaptiste Daroussin 			output = bs.value[bs.curr];
491c76f0793SBaptiste Daroussin 			*value = currvalue;
492c76f0793SBaptiste Daroussin 			loop = false;
493c76f0793SBaptiste Daroussin 			break;
494c76f0793SBaptiste Daroussin 		case 27: /* Esc */
495*263660c0SAlfonso Siciliano 			if (conf->key.enable_esc) {
496c76f0793SBaptiste Daroussin 				output = BSDDIALOG_ESC;
497c76f0793SBaptiste Daroussin 				loop = false;
498*263660c0SAlfonso Siciliano 			}
499c76f0793SBaptiste Daroussin 			break;
500f499134dSBaptiste Daroussin 		case '\t': /* TAB */
501c76f0793SBaptiste Daroussin 			bs.curr = (bs.curr + 1) % bs.nbuttons;
502c76f0793SBaptiste Daroussin 			buttupdate = true;
503c76f0793SBaptiste Daroussin 			break;
504c76f0793SBaptiste Daroussin 		case KEY_LEFT:
505c76f0793SBaptiste Daroussin 			if (bs.curr > 0) {
506c76f0793SBaptiste Daroussin 				bs.curr--;
507c76f0793SBaptiste Daroussin 				buttupdate = true;
508c76f0793SBaptiste Daroussin 			}
509c76f0793SBaptiste Daroussin 			break;
510c76f0793SBaptiste Daroussin 		case KEY_RIGHT:
511c76f0793SBaptiste Daroussin 			if (bs.curr < (int) bs.nbuttons - 1) {
512c76f0793SBaptiste Daroussin 				bs.curr++;
513c76f0793SBaptiste Daroussin 				buttupdate = true;
514c76f0793SBaptiste Daroussin 			}
515c76f0793SBaptiste Daroussin 			break;
516f499134dSBaptiste Daroussin 		case KEY_HOME:
517f499134dSBaptiste Daroussin 			currvalue = max;
518f499134dSBaptiste Daroussin 			barupdate = true;
519f499134dSBaptiste Daroussin 			break;
520f499134dSBaptiste Daroussin 		case KEY_END:
521f499134dSBaptiste Daroussin 			currvalue = min;
522f499134dSBaptiste Daroussin 			barupdate = true;
523f499134dSBaptiste Daroussin 			break;
524f499134dSBaptiste Daroussin 		case KEY_NPAGE:
525f499134dSBaptiste Daroussin 			currvalue -= bigchange;
526f499134dSBaptiste Daroussin 			if (currvalue < min)
527f499134dSBaptiste Daroussin 				currvalue = min;
528f499134dSBaptiste Daroussin 			barupdate = true;
529f499134dSBaptiste Daroussin 			break;
530f499134dSBaptiste Daroussin 		case KEY_PPAGE:
531f499134dSBaptiste Daroussin 			currvalue += bigchange;
532f499134dSBaptiste Daroussin 			if (currvalue > max)
533f499134dSBaptiste Daroussin 				currvalue = max;
534f499134dSBaptiste Daroussin 			barupdate = true;
535f499134dSBaptiste Daroussin 			break;
536c76f0793SBaptiste Daroussin 		case KEY_UP:
537c76f0793SBaptiste Daroussin 			if (currvalue < max) {
538c76f0793SBaptiste Daroussin 				currvalue++;
539c76f0793SBaptiste Daroussin 				barupdate = true;
540c76f0793SBaptiste Daroussin 			}
541c76f0793SBaptiste Daroussin 			break;
542c76f0793SBaptiste Daroussin 		case KEY_DOWN:
543c76f0793SBaptiste Daroussin 			if (currvalue > min) {
544c76f0793SBaptiste Daroussin 				currvalue--;
545c76f0793SBaptiste Daroussin 				barupdate = true;
546c76f0793SBaptiste Daroussin 			}
547c76f0793SBaptiste Daroussin 			break;
548f499134dSBaptiste Daroussin 		case KEY_F(1):
5498c4f4028SBaptiste Daroussin 			if (conf->f1_file == NULL && conf->f1_message == NULL)
550f499134dSBaptiste Daroussin 				break;
551f499134dSBaptiste Daroussin 			if (f1help(conf) != 0)
552*263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
553*263660c0SAlfonso Siciliano 			/* No break, screen size can change */
554f499134dSBaptiste Daroussin 		case KEY_RESIZE:
555*263660c0SAlfonso Siciliano 			/* Important for decreasing screen */
556f499134dSBaptiste Daroussin 			hide_widget(y, x, h, w, conf->shadow);
557f499134dSBaptiste Daroussin 			refresh();
558f499134dSBaptiste Daroussin 
559f499134dSBaptiste Daroussin 			if (set_widget_size(conf, rows, cols, &h, &w) != 0)
560*263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
561*263660c0SAlfonso Siciliano 			if (bar_autosize(conf, rows, cols, &h, &w, text,
562*263660c0SAlfonso Siciliano 			    &bs) != 0)
563*263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
564*263660c0SAlfonso Siciliano 			if (bar_checksize(h, w, &bs) != 0)
565*263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
566f499134dSBaptiste Daroussin 			if (set_widget_position(conf, &y, &x, h, w) != 0)
567*263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
568f499134dSBaptiste Daroussin 
569*263660c0SAlfonso Siciliano 			if (update_dialog(conf, shadow, widget,y, x, h, w,
570*263660c0SAlfonso Siciliano 			    textpad, text, &bs, true) != 0)
571*263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
572f499134dSBaptiste Daroussin 
573*263660c0SAlfonso Siciliano 			doupdate();
574f499134dSBaptiste Daroussin 
575*263660c0SAlfonso Siciliano 			sizebar = w - HBORDERS - 2 - BARPADDING * 2;
576f499134dSBaptiste Daroussin 			bigchange = MAX(1, sizebar/10);
577f499134dSBaptiste Daroussin 			wclear(bar);
578*263660c0SAlfonso Siciliano 			mvwin(bar, y + h - 6, x + 1 + BARPADDING);
579f499134dSBaptiste Daroussin 			wresize(bar, 3, sizebar + 2);
580f499134dSBaptiste Daroussin 			draw_borders(conf, bar, 3, sizebar+2, RAISED);
581f499134dSBaptiste Daroussin 
582*263660c0SAlfonso Siciliano 			prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-7,
583*263660c0SAlfonso Siciliano 			    x+w-1-TEXTHMARGIN);
584*263660c0SAlfonso Siciliano 
585f499134dSBaptiste Daroussin 			barupdate = true;
586f499134dSBaptiste Daroussin 			break;
587f499134dSBaptiste Daroussin 		default:
588*263660c0SAlfonso Siciliano 			if (shortcut_buttons(input, &bs)) {
589*263660c0SAlfonso Siciliano 				output = bs.value[bs.curr];
590f499134dSBaptiste Daroussin 				loop = false;
591f499134dSBaptiste Daroussin 			}
592c76f0793SBaptiste Daroussin 		}
593c76f0793SBaptiste Daroussin 	}
594c76f0793SBaptiste Daroussin 
595c76f0793SBaptiste Daroussin 	delwin(bar);
596*263660c0SAlfonso Siciliano 	end_dialog(conf, shadow, widget, textpad);
597c76f0793SBaptiste Daroussin 
598*263660c0SAlfonso Siciliano 	return (output);
599c76f0793SBaptiste Daroussin }
600c76f0793SBaptiste Daroussin 
601f499134dSBaptiste Daroussin int
602*263660c0SAlfonso Siciliano bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
603*263660c0SAlfonso Siciliano     int cols, unsigned int sec)
604c76f0793SBaptiste Daroussin {
605c76f0793SBaptiste Daroussin 	bool loop, buttupdate, barupdate;
606*263660c0SAlfonso Siciliano 	int output, y, x, h, w, input, tout, sizebar;
607c76f0793SBaptiste Daroussin 	float perc;
608*263660c0SAlfonso Siciliano 	WINDOW *widget, *textpad, *bar, *shadow;
609c76f0793SBaptiste Daroussin 	struct buttons bs;
610c76f0793SBaptiste Daroussin 
611*263660c0SAlfonso Siciliano 	get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
612c76f0793SBaptiste Daroussin 
613f499134dSBaptiste Daroussin 	if (set_widget_size(conf, rows, cols, &h, &w) != 0)
614*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
615f499134dSBaptiste Daroussin 	if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0)
616*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
617*263660c0SAlfonso Siciliano 	if (bar_checksize(h, w, &bs) != 0)
618*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
619f499134dSBaptiste Daroussin 	if (set_widget_position(conf, &y, &x, h, w) != 0)
620*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
621f499134dSBaptiste Daroussin 
622*263660c0SAlfonso Siciliano 	if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
623*263660c0SAlfonso Siciliano 	    true) != 0)
624*263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
625f499134dSBaptiste Daroussin 
626*263660c0SAlfonso Siciliano 	doupdate();
627f499134dSBaptiste Daroussin 
628*263660c0SAlfonso Siciliano 	prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-7, x+w-1-TEXTHMARGIN);
629*263660c0SAlfonso Siciliano 
630*263660c0SAlfonso Siciliano 	sizebar = w - HBORDERS - 2 - BARPADDING * 2;
631*263660c0SAlfonso Siciliano 	bar = new_boxed_window(conf, y + h - 6, x + 1 + BARPADDING, 3,
632f499134dSBaptiste Daroussin 	    sizebar + 2, RAISED);
633f499134dSBaptiste Daroussin 
634f499134dSBaptiste Daroussin 	tout = sec;
635c76f0793SBaptiste Daroussin 	nodelay(stdscr, TRUE);
636c76f0793SBaptiste Daroussin 	timeout(1000);
637c76f0793SBaptiste Daroussin 	loop = buttupdate = barupdate = true;
638c76f0793SBaptiste Daroussin 	while (loop) {
639c76f0793SBaptiste Daroussin 		if (barupdate) {
640f499134dSBaptiste Daroussin 			perc = (float)tout * 100 / sec;
641*263660c0SAlfonso Siciliano 			draw_bar(bar, 1, 1, sizebar, perc, true, tout);
642c76f0793SBaptiste Daroussin 			barupdate = false;
643c76f0793SBaptiste Daroussin 			wrefresh(bar);
644c76f0793SBaptiste Daroussin 		}
645c76f0793SBaptiste Daroussin 
646c76f0793SBaptiste Daroussin 		if (buttupdate) {
647*263660c0SAlfonso Siciliano 			draw_buttons(widget, bs, true);
648c76f0793SBaptiste Daroussin 			wrefresh(widget);
649c76f0793SBaptiste Daroussin 			buttupdate = false;
650c76f0793SBaptiste Daroussin 		}
651c76f0793SBaptiste Daroussin 
652c76f0793SBaptiste Daroussin 		input = getch();
653f499134dSBaptiste Daroussin 		if (input < 0) { /* timeout */
654f499134dSBaptiste Daroussin 			tout--;
655f499134dSBaptiste Daroussin 			if (tout < 0) {
656f499134dSBaptiste Daroussin 				output = BSDDIALOG_TIMEOUT;
657c76f0793SBaptiste Daroussin 				break;
658c76f0793SBaptiste Daroussin 			}
659c76f0793SBaptiste Daroussin 			else {
660c76f0793SBaptiste Daroussin 				barupdate = true;
661c76f0793SBaptiste Daroussin 				continue;
662c76f0793SBaptiste Daroussin 			}
663c76f0793SBaptiste Daroussin 		}
664c76f0793SBaptiste Daroussin 		switch(input) {
665f499134dSBaptiste Daroussin 		case KEY_ENTER:
666f499134dSBaptiste Daroussin 		case 10: /* Enter */
667f499134dSBaptiste Daroussin 			output = bs.value[bs.curr];
668c76f0793SBaptiste Daroussin 			loop = false;
669c76f0793SBaptiste Daroussin 			break;
670c76f0793SBaptiste Daroussin 		case 27: /* Esc */
671*263660c0SAlfonso Siciliano 			if (conf->key.enable_esc) {
672c76f0793SBaptiste Daroussin 				output = BSDDIALOG_ESC;
673c76f0793SBaptiste Daroussin 				loop = false;
674*263660c0SAlfonso Siciliano 			}
675c76f0793SBaptiste Daroussin 			break;
676f499134dSBaptiste Daroussin 		case '\t': /* TAB */
677c76f0793SBaptiste Daroussin 			bs.curr = (bs.curr + 1) % bs.nbuttons;
678c76f0793SBaptiste Daroussin 			buttupdate = true;
679c76f0793SBaptiste Daroussin 			break;
680c76f0793SBaptiste Daroussin 		case KEY_LEFT:
681c76f0793SBaptiste Daroussin 			if (bs.curr > 0) {
682c76f0793SBaptiste Daroussin 				bs.curr--;
683c76f0793SBaptiste Daroussin 				buttupdate = true;
684c76f0793SBaptiste Daroussin 			}
685c76f0793SBaptiste Daroussin 			break;
686c76f0793SBaptiste Daroussin 		case KEY_RIGHT:
687c76f0793SBaptiste Daroussin 			if (bs.curr < (int) bs.nbuttons - 1) {
688c76f0793SBaptiste Daroussin 				bs.curr++;
689c76f0793SBaptiste Daroussin 				buttupdate = true;
690c76f0793SBaptiste Daroussin 			}
691c76f0793SBaptiste Daroussin 			break;
692f499134dSBaptiste Daroussin 		case KEY_F(1):
6938c4f4028SBaptiste Daroussin 			if (conf->f1_file == NULL && conf->f1_message == NULL)
694f499134dSBaptiste Daroussin 				break;
695f499134dSBaptiste Daroussin 			if (f1help(conf) != 0)
696*263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
697*263660c0SAlfonso Siciliano 			/* No break, screen size can change */
698f499134dSBaptiste Daroussin 		case KEY_RESIZE:
699*263660c0SAlfonso Siciliano 			/* Important for decreasing screen */
700f499134dSBaptiste Daroussin 			hide_widget(y, x, h, w, conf->shadow);
701f499134dSBaptiste Daroussin 			refresh();
702f499134dSBaptiste Daroussin 
703f499134dSBaptiste Daroussin 			if (set_widget_size(conf, rows, cols, &h, &w) != 0)
704*263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
705*263660c0SAlfonso Siciliano 			if (bar_autosize(conf, rows, cols, &h, &w, text,
706*263660c0SAlfonso Siciliano 			    &bs) != 0)
707*263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
708*263660c0SAlfonso Siciliano 			if (bar_checksize(h, w, &bs) != 0)
709*263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
710f499134dSBaptiste Daroussin 			if (set_widget_position(conf, &y, &x, h, w) != 0)
711*263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
712f499134dSBaptiste Daroussin 
713*263660c0SAlfonso Siciliano 			if (update_dialog(conf, shadow, widget,y, x, h, w,
714*263660c0SAlfonso Siciliano 			    textpad, text, &bs, true) != 0)
715*263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
716f499134dSBaptiste Daroussin 
717*263660c0SAlfonso Siciliano 			doupdate();
718f499134dSBaptiste Daroussin 
719*263660c0SAlfonso Siciliano 			sizebar = w - HBORDERS - 2 - BARPADDING * 2;
720f499134dSBaptiste Daroussin 			wclear(bar);
721*263660c0SAlfonso Siciliano 			mvwin(bar, y + h - 6, x + 1 + BARPADDING);
722f499134dSBaptiste Daroussin 			wresize(bar, 3, sizebar + 2);
723*263660c0SAlfonso Siciliano 			draw_borders(conf, bar, 3, sizebar+2, LOWERED);
724f499134dSBaptiste Daroussin 
725*263660c0SAlfonso Siciliano 			prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-7,
726*263660c0SAlfonso Siciliano 			    x+w-1-TEXTHMARGIN);
727f499134dSBaptiste Daroussin 
728f499134dSBaptiste Daroussin 			barupdate = true;
729f499134dSBaptiste Daroussin 			break;
730f499134dSBaptiste Daroussin 		default:
731*263660c0SAlfonso Siciliano 			if (shortcut_buttons(input, &bs)) {
732*263660c0SAlfonso Siciliano 				output = bs.value[bs.curr];
733f499134dSBaptiste Daroussin 				loop = false;
734f499134dSBaptiste Daroussin 			}
735c76f0793SBaptiste Daroussin 		}
736c76f0793SBaptiste Daroussin 	}
737c76f0793SBaptiste Daroussin 
738c76f0793SBaptiste Daroussin 	nodelay(stdscr, FALSE);
739c76f0793SBaptiste Daroussin 
740c76f0793SBaptiste Daroussin 	delwin(bar);
741*263660c0SAlfonso Siciliano 	end_dialog(conf, shadow, widget, textpad);
742c76f0793SBaptiste Daroussin 
743*263660c0SAlfonso Siciliano 	return (output);
744c76f0793SBaptiste Daroussin }