xref: /freebsd/contrib/bsddialog/lib/barbox.c (revision 61ba55bc)
1c76f0793SBaptiste Daroussin /*-
2c76f0793SBaptiste Daroussin  * SPDX-License-Identifier: BSD-2-Clause
3c76f0793SBaptiste Daroussin  *
4*61ba55bcSBaptiste Daroussin  * Copyright (c) 2021-2023 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 
28263660c0SAlfonso Siciliano #include <curses.h>
29d93b4d32SBaptiste Daroussin #include <stdlib.h>
30d93b4d32SBaptiste Daroussin #include <string.h>
31d93b4d32SBaptiste Daroussin #include <time.h>
32263660c0SAlfonso Siciliano #include <unistd.h>
33c76f0793SBaptiste Daroussin 
34c76f0793SBaptiste Daroussin #include "bsddialog.h"
35d93b4d32SBaptiste Daroussin #include "bsddialog_progressview.h"
36c76f0793SBaptiste Daroussin #include "bsddialog_theme.h"
37263660c0SAlfonso Siciliano #include "lib_util.h"
38c76f0793SBaptiste Daroussin 
39*61ba55bcSBaptiste Daroussin #define BARPADDING   2  /* widget border | BARPADDING | box bar */
40*61ba55bcSBaptiste Daroussin #define BOXBORDERS   2
41*61ba55bcSBaptiste Daroussin #define MIN_WBAR     15
42*61ba55bcSBaptiste Daroussin #define MIN_WBOX     (BARPADDING + BOXBORDERS + MIN_WBAR + BARPADDING)
43*61ba55bcSBaptiste Daroussin #define MIN_WMGBAR   18
44*61ba55bcSBaptiste Daroussin #define MIN_WMGBOX   (BARPADDING + BOXBORDERS + MIN_WMGBAR + BARPADDING)
45*61ba55bcSBaptiste Daroussin #define HBOX         3
46*61ba55bcSBaptiste Daroussin #define WBOX(d)      ((d)->w - BORDERS - BARPADDING - BARPADDING)
47*61ba55bcSBaptiste Daroussin #define WBAR(d)      (WBOX(d) - BOXBORDERS)
48d93b4d32SBaptiste Daroussin 
49d93b4d32SBaptiste Daroussin bool bsddialog_interruptprogview;
50d93b4d32SBaptiste Daroussin bool bsddialog_abortprogview;
51*61ba55bcSBaptiste Daroussin long long int bsddialog_total_progview;
52c76f0793SBaptiste Daroussin 
53*61ba55bcSBaptiste Daroussin static const char states[12][14] = {
54263660c0SAlfonso Siciliano 	"  Succeeded  ", /* -1  */
55263660c0SAlfonso Siciliano 	"   Failed    ", /* -2  */
56263660c0SAlfonso Siciliano 	"   Passed    ", /* -3  */
57263660c0SAlfonso Siciliano 	"  Completed  ", /* -4  */
58263660c0SAlfonso Siciliano 	"   Checked   ", /* -5  */
59263660c0SAlfonso Siciliano 	"    Done     ", /* -6  */
60263660c0SAlfonso Siciliano 	"   Skipped   ", /* -7  */
61263660c0SAlfonso Siciliano 	" In Progress ", /* -8  */
62263660c0SAlfonso Siciliano 	"(blank)      ", /* -9  */
63263660c0SAlfonso Siciliano 	"     N/A     ", /* -10 */
64263660c0SAlfonso Siciliano 	"   Pending   ", /* -11 */
65263660c0SAlfonso Siciliano 	"   UNKNOWN   ", /* < -11, no API */
66f499134dSBaptiste Daroussin };
67c76f0793SBaptiste Daroussin 
68*61ba55bcSBaptiste Daroussin struct bar {
69*61ba55bcSBaptiste Daroussin 	bool toupdate;
70*61ba55bcSBaptiste Daroussin 	WINDOW *win;
71*61ba55bcSBaptiste Daroussin 	int y;           /* bar y in win */
72*61ba55bcSBaptiste Daroussin 	int x;           /* bar x in win */
73*61ba55bcSBaptiste Daroussin 	int w;           /* width in win */
74*61ba55bcSBaptiste Daroussin 	int perc;        /* barlen = (w * perc) / 100 */
75*61ba55bcSBaptiste Daroussin 	const char* fmt; /* format for label */
76*61ba55bcSBaptiste Daroussin 	int label;       /* rangebox and pause perc!=label */
77*61ba55bcSBaptiste Daroussin };
78*61ba55bcSBaptiste Daroussin 
draw_bar(struct bar * b)79*61ba55bcSBaptiste Daroussin static void draw_bar(struct bar *b)
80*61ba55bcSBaptiste Daroussin {
81*61ba55bcSBaptiste Daroussin 	int barlen, xlabel;
82*61ba55bcSBaptiste Daroussin 	chtype ch;
83*61ba55bcSBaptiste Daroussin 	char label[128];
84*61ba55bcSBaptiste Daroussin 
85*61ba55bcSBaptiste Daroussin 	barlen = b->perc > 0 ? (b->perc * b->w) / 100 : 0;
86*61ba55bcSBaptiste Daroussin 
87*61ba55bcSBaptiste Daroussin 	ch = ' ' | t.bar.f_color;
88*61ba55bcSBaptiste Daroussin 	mvwhline(b->win, b->y, b->x, ch, barlen);
89*61ba55bcSBaptiste Daroussin 	ch = ' ' | t.bar.color;
90*61ba55bcSBaptiste Daroussin 	mvwhline(b->win, b->y, b->x + barlen, ch, b->w - barlen);
91*61ba55bcSBaptiste Daroussin 
92*61ba55bcSBaptiste Daroussin 	sprintf(label, b->fmt, b->label);
93*61ba55bcSBaptiste Daroussin 	xlabel = b->x + b->w/2 - (int)strlen(label)/2; /* 1-byte-char string */
94*61ba55bcSBaptiste Daroussin 	wattron(b->win, t.bar.color);   /* x+barlen < xlabel */
95*61ba55bcSBaptiste Daroussin 	mvwaddstr(b->win, b->y, xlabel, label);
96*61ba55bcSBaptiste Daroussin 	wattroff(b->win, t.bar.color);
97*61ba55bcSBaptiste Daroussin 	wattron(b->win, t.bar.f_color); /* x+barlen >= xlabel */
98*61ba55bcSBaptiste Daroussin 	mvwaddnstr(b->win, b->y, xlabel, label, MAX((b->x+barlen) - xlabel, 0));
99*61ba55bcSBaptiste Daroussin 	wattroff(b->win, t.bar.f_color);
100*61ba55bcSBaptiste Daroussin 
101*61ba55bcSBaptiste Daroussin 	if (b->toupdate)
102*61ba55bcSBaptiste Daroussin 		wnoutrefresh(b->win);
103*61ba55bcSBaptiste Daroussin 	b->toupdate = false;
104*61ba55bcSBaptiste Daroussin }
105*61ba55bcSBaptiste Daroussin 
update_barbox(struct dialog * d,struct bar * b,bool buttons)106*61ba55bcSBaptiste Daroussin static void update_barbox(struct dialog *d, struct bar *b, bool buttons)
107*61ba55bcSBaptiste Daroussin {
108*61ba55bcSBaptiste Daroussin 	int y;
109*61ba55bcSBaptiste Daroussin 
110*61ba55bcSBaptiste Daroussin 	y = d->y + d->h - BORDER - HBOX;
111*61ba55bcSBaptiste Daroussin 	if (buttons)
112*61ba55bcSBaptiste Daroussin 		y -= HBUTTONS;
113*61ba55bcSBaptiste Daroussin 	update_box(d->conf, b->win, y, d->x + BORDER + BARPADDING, HBOX,
114*61ba55bcSBaptiste Daroussin 	    WBOX(d), RAISED);
115*61ba55bcSBaptiste Daroussin }
116*61ba55bcSBaptiste Daroussin 
117*61ba55bcSBaptiste Daroussin int
bsddialog_gauge(struct bsddialog_conf * conf,const char * text,int rows,int cols,unsigned int perc,int fd,const char * sep,const char * end)118*61ba55bcSBaptiste Daroussin bsddialog_gauge(struct bsddialog_conf *conf, const char *text, int rows,
119*61ba55bcSBaptiste Daroussin     int cols, unsigned int perc, int fd, const char *sep, const char *end)
120*61ba55bcSBaptiste Daroussin {
121*61ba55bcSBaptiste Daroussin 	bool mainloop;
122*61ba55bcSBaptiste Daroussin 	int fd2;
123*61ba55bcSBaptiste Daroussin 	FILE *input;
124*61ba55bcSBaptiste Daroussin 	char inputbuf[2048], ntext[2048], *pntext;
125*61ba55bcSBaptiste Daroussin 	struct bar b;
126*61ba55bcSBaptiste Daroussin 	struct dialog d;
127*61ba55bcSBaptiste Daroussin 
128*61ba55bcSBaptiste Daroussin 	if (prepare_dialog(conf, text, rows, cols, &d) != 0)
129*61ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
130*61ba55bcSBaptiste Daroussin 	if ((b.win = newwin(1, 1, 1, 1)) == NULL)
131*61ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot build WINDOW bar");
132*61ba55bcSBaptiste Daroussin 	b.y = b.x = 1;
133*61ba55bcSBaptiste Daroussin 	b.fmt = "%3d%%";
134*61ba55bcSBaptiste Daroussin 
135*61ba55bcSBaptiste Daroussin 	input = NULL;
136*61ba55bcSBaptiste Daroussin 	if (fd >= 0) {
137*61ba55bcSBaptiste Daroussin 		CHECK_PTR(sep);
138*61ba55bcSBaptiste Daroussin 		CHECK_PTR(end);
139*61ba55bcSBaptiste Daroussin 
140*61ba55bcSBaptiste Daroussin 		fd2 = dup(fd);
141*61ba55bcSBaptiste Daroussin 		if ((input = fdopen(fd2, "r")) == NULL)
142*61ba55bcSBaptiste Daroussin 			RETURN_FMTERROR("Cannot build FILE* from fd %d", fd);
143*61ba55bcSBaptiste Daroussin 	}
144*61ba55bcSBaptiste Daroussin 
145*61ba55bcSBaptiste Daroussin 	perc = MIN(perc, 100);
146*61ba55bcSBaptiste Daroussin 	mainloop = true;
147*61ba55bcSBaptiste Daroussin 	while (mainloop) {
148*61ba55bcSBaptiste Daroussin 		if (d.built) {
149*61ba55bcSBaptiste Daroussin 			hide_dialog(&d);
150*61ba55bcSBaptiste Daroussin 			refresh(); /* Important for decreasing screen */
151*61ba55bcSBaptiste Daroussin 		}
152*61ba55bcSBaptiste Daroussin 		if (dialog_size_position(&d, HBOX, MIN_WBOX, NULL) != 0)
153*61ba55bcSBaptiste Daroussin 			return (BSDDIALOG_ERROR);
154*61ba55bcSBaptiste Daroussin 		if (draw_dialog(&d))
155*61ba55bcSBaptiste Daroussin 			return (BSDDIALOG_ERROR);
156*61ba55bcSBaptiste Daroussin 		if (d.built)
157*61ba55bcSBaptiste Daroussin 			refresh(); /* fix grey lines expanding screen */
158*61ba55bcSBaptiste Daroussin 		TEXTPAD(&d, HBOX);
159*61ba55bcSBaptiste Daroussin 		update_barbox(&d, &b, false);
160*61ba55bcSBaptiste Daroussin 		b.w = WBAR(&d);
161*61ba55bcSBaptiste Daroussin 		b.perc = b.label = perc;
162*61ba55bcSBaptiste Daroussin 		b.toupdate = true;
163*61ba55bcSBaptiste Daroussin 		draw_bar(&b);
164*61ba55bcSBaptiste Daroussin 		doupdate();
165*61ba55bcSBaptiste Daroussin 		if (input == NULL) /* that is fd < 0 */
166*61ba55bcSBaptiste Daroussin 			break;
167*61ba55bcSBaptiste Daroussin 
168*61ba55bcSBaptiste Daroussin 		while (true) {
169*61ba55bcSBaptiste Daroussin 			fscanf(input, "%s", inputbuf);
170*61ba55bcSBaptiste Daroussin 			if (strcmp(inputbuf, end) == 0) {
171*61ba55bcSBaptiste Daroussin 				mainloop = false;
172*61ba55bcSBaptiste Daroussin 				break;
173*61ba55bcSBaptiste Daroussin 			}
174*61ba55bcSBaptiste Daroussin 			if (strcmp(inputbuf, sep) == 0)
175*61ba55bcSBaptiste Daroussin 				break;
176*61ba55bcSBaptiste Daroussin 		}
177*61ba55bcSBaptiste Daroussin 		if (mainloop == false)
178*61ba55bcSBaptiste Daroussin 			break;
179*61ba55bcSBaptiste Daroussin 		fscanf(input, "%d", &perc);
180*61ba55bcSBaptiste Daroussin 		perc = MIN(perc, 100);
181*61ba55bcSBaptiste Daroussin 		pntext = &ntext[0];
182*61ba55bcSBaptiste Daroussin 		ntext[0] = '\0';
183*61ba55bcSBaptiste Daroussin 		while (true) {
184*61ba55bcSBaptiste Daroussin 			fscanf(input, "%s", inputbuf);
185*61ba55bcSBaptiste Daroussin 			if (strcmp(inputbuf, end) == 0) {
186*61ba55bcSBaptiste Daroussin 				mainloop = false;
187*61ba55bcSBaptiste Daroussin 				break;
188*61ba55bcSBaptiste Daroussin 			}
189*61ba55bcSBaptiste Daroussin 			if (strcmp(inputbuf, sep) == 0)
190*61ba55bcSBaptiste Daroussin 				break;
191*61ba55bcSBaptiste Daroussin 			strcpy(pntext, inputbuf);
192*61ba55bcSBaptiste Daroussin 			pntext += strlen(inputbuf); /* end string, no strlen */
193*61ba55bcSBaptiste Daroussin 			pntext[0] = ' ';
194*61ba55bcSBaptiste Daroussin 			pntext++;
195*61ba55bcSBaptiste Daroussin 		}
196*61ba55bcSBaptiste Daroussin 		pntext[0] = '\0';
197*61ba55bcSBaptiste Daroussin 		d.text = ntext;
198*61ba55bcSBaptiste Daroussin 	}
199*61ba55bcSBaptiste Daroussin 
200*61ba55bcSBaptiste Daroussin 	if (input != NULL)
201*61ba55bcSBaptiste Daroussin 		fclose(input);
202*61ba55bcSBaptiste Daroussin 	delwin(b.win);
203*61ba55bcSBaptiste Daroussin 	end_dialog(&d);
204*61ba55bcSBaptiste Daroussin 
205*61ba55bcSBaptiste Daroussin 	return (BSDDIALOG_OK);
206*61ba55bcSBaptiste Daroussin }
207*61ba55bcSBaptiste Daroussin 
208*61ba55bcSBaptiste Daroussin /* Mixedgauge */
209*61ba55bcSBaptiste Daroussin static int
do_mixedgauge(struct bsddialog_conf * conf,const char * text,int rows,int cols,unsigned int mainperc,unsigned int nminibars,const char ** minilabels,int * minipercs,bool color)210*61ba55bcSBaptiste Daroussin do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
211*61ba55bcSBaptiste Daroussin     unsigned int mainperc, unsigned int nminibars, const char **minilabels,
212*61ba55bcSBaptiste Daroussin     int *minipercs, bool color)
213*61ba55bcSBaptiste Daroussin {
214*61ba55bcSBaptiste Daroussin 	int i, miniperc, max_minibarlen;
215*61ba55bcSBaptiste Daroussin 	int ystext, htext;
216*61ba55bcSBaptiste Daroussin 	int minicolor, red, green;
217*61ba55bcSBaptiste Daroussin 	struct bar b;
218*61ba55bcSBaptiste Daroussin 	struct dialog d;
219*61ba55bcSBaptiste Daroussin 
220*61ba55bcSBaptiste Daroussin 	CHECK_ARRAY(nminibars, minilabels);
221*61ba55bcSBaptiste Daroussin 	CHECK_ARRAY(nminibars, minipercs);
222*61ba55bcSBaptiste Daroussin 
223d93b4d32SBaptiste Daroussin 	red   = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_RED,  BSDDIALOG_BOLD);
224d93b4d32SBaptiste Daroussin 	green = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_GREEN,BSDDIALOG_BOLD);
225d93b4d32SBaptiste Daroussin 
226*61ba55bcSBaptiste Daroussin 	max_minibarlen = 0;
2278c4f4028SBaptiste Daroussin 	for (i = 0; i < (int)nminibars; i++)
228*61ba55bcSBaptiste Daroussin 		max_minibarlen = MAX(max_minibarlen,
229*61ba55bcSBaptiste Daroussin 		    (int)strcols(CHECK_STR(minilabels[i])));
230*61ba55bcSBaptiste Daroussin 	max_minibarlen += 3 + 16; /* seps + [...] */
231*61ba55bcSBaptiste Daroussin 	max_minibarlen = MAX(max_minibarlen, MIN_WMGBOX); /* mainbar */
232f499134dSBaptiste Daroussin 
233*61ba55bcSBaptiste Daroussin 	if (prepare_dialog(conf, text, rows, cols, &d) != 0)
234263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
235*61ba55bcSBaptiste Daroussin 	if (dialog_size_position(&d, nminibars + HBOX, max_minibarlen,
236*61ba55bcSBaptiste Daroussin 	    &htext) != 0)
237263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
238*61ba55bcSBaptiste Daroussin 	if (draw_dialog(&d) != 0)
239263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
240f499134dSBaptiste Daroussin 
241c76f0793SBaptiste Daroussin 	/* mini bars */
242*61ba55bcSBaptiste Daroussin 	b.win = d.widget;
243*61ba55bcSBaptiste Daroussin 	b.x = 1 + d.w - 2 - 15;
244*61ba55bcSBaptiste Daroussin 	b.w = 13;
245*61ba55bcSBaptiste Daroussin 	b.fmt = "%3d%%";
246*61ba55bcSBaptiste Daroussin 	b.toupdate = false;
2478c4f4028SBaptiste Daroussin 	for (i = 0; i < (int)nminibars; i++) {
2488c4f4028SBaptiste Daroussin 		miniperc = minipercs[i];
249*61ba55bcSBaptiste Daroussin 		/* label */
250*61ba55bcSBaptiste Daroussin 		if (color && miniperc >= 0)
251*61ba55bcSBaptiste Daroussin 			wattron(d.widget, A_BOLD);
252*61ba55bcSBaptiste Daroussin 		mvwaddstr(d.widget, i+1, 2, CHECK_STR(minilabels[i]));
253*61ba55bcSBaptiste Daroussin 		if (color && miniperc >= 0)
254*61ba55bcSBaptiste Daroussin 			wattroff(d.widget, A_BOLD);
255*61ba55bcSBaptiste Daroussin 		/* perc */
256263660c0SAlfonso Siciliano 		if (miniperc == BSDDIALOG_MG_BLANK)
257c76f0793SBaptiste Daroussin 			continue;
258*61ba55bcSBaptiste Daroussin 		mvwaddstr(d.widget, i+1, d.w-2-15, "[             ]");
259*61ba55bcSBaptiste Daroussin 		if (miniperc >= 0) {
260*61ba55bcSBaptiste Daroussin 			b.y = i + 1;
261*61ba55bcSBaptiste Daroussin 			b.perc = b.label = MIN(miniperc, 100);
262*61ba55bcSBaptiste Daroussin 			draw_bar(&b);
263*61ba55bcSBaptiste Daroussin 		} else { /* miniperc < 0 */
264*61ba55bcSBaptiste Daroussin 			if (miniperc < BSDDIALOG_MG_PENDING)
265*61ba55bcSBaptiste Daroussin 				miniperc = -12; /* UNKNOWN */
266*61ba55bcSBaptiste Daroussin 			minicolor = t.dialog.color;
267263660c0SAlfonso Siciliano 			if (color && miniperc == BSDDIALOG_MG_FAILED)
268*61ba55bcSBaptiste Daroussin 				minicolor = red;
269*61ba55bcSBaptiste Daroussin 			else if (color && miniperc == BSDDIALOG_MG_DONE)
270*61ba55bcSBaptiste Daroussin 				minicolor = green;
271*61ba55bcSBaptiste Daroussin 			wattron(d.widget, minicolor);
272263660c0SAlfonso Siciliano 			miniperc = abs(miniperc + 1);
273*61ba55bcSBaptiste Daroussin 			mvwaddstr(d.widget, i+1, 1+d.w-2-15, states[miniperc]);
274*61ba55bcSBaptiste Daroussin 			wattroff(d.widget, minicolor);
275c76f0793SBaptiste Daroussin 		}
276c76f0793SBaptiste Daroussin 	}
277*61ba55bcSBaptiste Daroussin 	wnoutrefresh(d.widget);
278c76f0793SBaptiste Daroussin 
279*61ba55bcSBaptiste Daroussin 	/* text */
280*61ba55bcSBaptiste Daroussin 	ystext = MAX(d.h - BORDERS - htext - HBOX, (int)nminibars);
281*61ba55bcSBaptiste Daroussin 	rtextpad(&d, 0, 0, ystext, HBOX);
282c76f0793SBaptiste Daroussin 
283c76f0793SBaptiste Daroussin 	/* main bar */
284*61ba55bcSBaptiste Daroussin 	if ((b.win = newwin(1, 1, 1, 1)) == NULL)
285*61ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot build WINDOW bar");
286*61ba55bcSBaptiste Daroussin 	update_barbox(&d, &b, false);
287*61ba55bcSBaptiste Daroussin 	wattron(b.win, t.bar.color);
288*61ba55bcSBaptiste Daroussin 	mvwaddstr(b.win, 0, 2, "Overall Progress");
289*61ba55bcSBaptiste Daroussin 	wattroff(b.win, t.bar.color);
290c76f0793SBaptiste Daroussin 
291*61ba55bcSBaptiste Daroussin 	b.y = b.x = 1;
292*61ba55bcSBaptiste Daroussin 	b.w = WBAR(&d);
293*61ba55bcSBaptiste Daroussin 	b.fmt = "%3d%%";
294*61ba55bcSBaptiste Daroussin 	b.perc = b.label = MIN(mainperc, 100);
295*61ba55bcSBaptiste Daroussin 	b.toupdate = true;
296*61ba55bcSBaptiste Daroussin 	draw_bar(&b);
297f499134dSBaptiste Daroussin 
298*61ba55bcSBaptiste Daroussin 	doupdate();
299*61ba55bcSBaptiste Daroussin 	/* getch(); to test with "alternate mode" */
300c76f0793SBaptiste Daroussin 
301*61ba55bcSBaptiste Daroussin 	delwin(b.win);
302*61ba55bcSBaptiste Daroussin 	end_dialog(&d);
303c76f0793SBaptiste Daroussin 
304263660c0SAlfonso Siciliano 	return (BSDDIALOG_OK);
305c76f0793SBaptiste Daroussin }
306c76f0793SBaptiste Daroussin 
307c76f0793SBaptiste Daroussin int
bsddialog_mixedgauge(struct bsddialog_conf * conf,const char * text,int rows,int cols,unsigned int mainperc,unsigned int nminibars,const char ** minilabels,int * minipercs)308263660c0SAlfonso Siciliano bsddialog_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows,
309263660c0SAlfonso Siciliano     int cols, unsigned int mainperc, unsigned int nminibars,
310263660c0SAlfonso Siciliano     const char **minilabels, int *minipercs)
311d93b4d32SBaptiste Daroussin {
312b319d934SAlfonso S. Siciliano 	int retval;
313d93b4d32SBaptiste Daroussin 
314b319d934SAlfonso S. Siciliano 	retval = do_mixedgauge(conf, text, rows, cols, mainperc, nminibars,
315d93b4d32SBaptiste Daroussin 	    minilabels, minipercs, false);
316d93b4d32SBaptiste Daroussin 
317b319d934SAlfonso S. Siciliano 	return (retval);
318d93b4d32SBaptiste Daroussin }
319d93b4d32SBaptiste Daroussin 
320d93b4d32SBaptiste Daroussin int
bsddialog_progressview(struct bsddialog_conf * conf,const char * text,int rows,int cols,struct bsddialog_progviewconf * pvconf,unsigned int nminibar,struct bsddialog_fileminibar * minibar)321263660c0SAlfonso Siciliano bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
322d93b4d32SBaptiste Daroussin     int cols, struct bsddialog_progviewconf *pvconf, unsigned int nminibar,
323d93b4d32SBaptiste Daroussin     struct bsddialog_fileminibar *minibar)
324d93b4d32SBaptiste Daroussin {
325d93b4d32SBaptiste Daroussin 	bool update;
326b319d934SAlfonso S. Siciliano 	int perc, retval, *minipercs;
327263660c0SAlfonso Siciliano 	unsigned int i, mainperc, totaltodo;
328d93b4d32SBaptiste Daroussin 	float readforsec;
329263660c0SAlfonso Siciliano 	const char **minilabels;
330263660c0SAlfonso Siciliano 	time_t tstart, told, tnew, refresh;
331d93b4d32SBaptiste Daroussin 
332d93b4d32SBaptiste Daroussin 	if ((minilabels = calloc(nminibar, sizeof(char*))) == NULL)
333263660c0SAlfonso Siciliano 		RETURN_ERROR("Cannot allocate memory for minilabels");
334d93b4d32SBaptiste Daroussin 	if ((minipercs = calloc(nminibar, sizeof(int))) == NULL)
335263660c0SAlfonso Siciliano 		RETURN_ERROR("Cannot allocate memory for minipercs");
336d93b4d32SBaptiste Daroussin 
337d93b4d32SBaptiste Daroussin 	totaltodo = 0;
338d93b4d32SBaptiste Daroussin 	for (i = 0; i < nminibar; i++) {
339d93b4d32SBaptiste Daroussin 		totaltodo += minibar[i].size;
340d93b4d32SBaptiste Daroussin 		minilabels[i] = minibar[i].label;
341263660c0SAlfonso Siciliano 		minipercs[i] = minibar[i].status;
342d93b4d32SBaptiste Daroussin 	}
343d93b4d32SBaptiste Daroussin 
344d93b4d32SBaptiste Daroussin 	refresh = pvconf->refresh == 0 ? 0 : pvconf->refresh - 1;
345b319d934SAlfonso S. Siciliano 	retval = BSDDIALOG_OK;
346d93b4d32SBaptiste Daroussin 	i = 0;
347d93b4d32SBaptiste Daroussin 	update = true;
348d93b4d32SBaptiste Daroussin 	time(&told);
349d93b4d32SBaptiste Daroussin 	tstart = told;
350d93b4d32SBaptiste Daroussin 	while (!(bsddialog_interruptprogview || bsddialog_abortprogview)) {
351d93b4d32SBaptiste Daroussin 		if (bsddialog_total_progview == 0 || totaltodo == 0)
352d93b4d32SBaptiste Daroussin 			mainperc = 0;
353d93b4d32SBaptiste Daroussin 		else
354d93b4d32SBaptiste Daroussin 			mainperc = (bsddialog_total_progview * 100) / totaltodo;
355d93b4d32SBaptiste Daroussin 
356d93b4d32SBaptiste Daroussin 		time(&tnew);
357d93b4d32SBaptiste Daroussin 		if (update || tnew > told + refresh) {
358b319d934SAlfonso S. Siciliano 			retval = do_mixedgauge(conf, text, rows, cols, mainperc,
359d93b4d32SBaptiste Daroussin 			    nminibar, minilabels, minipercs, true);
360b319d934SAlfonso S. Siciliano 			if (retval == BSDDIALOG_ERROR)
361263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
362d93b4d32SBaptiste Daroussin 
363263660c0SAlfonso Siciliano 			move(SCREENLINES - 1, 2);
364d93b4d32SBaptiste Daroussin 			clrtoeol();
365263660c0SAlfonso Siciliano 			readforsec = ((tnew - tstart) == 0) ? 0 :
366263660c0SAlfonso Siciliano 			    bsddialog_total_progview / (float)(tnew - tstart);
367d93b4d32SBaptiste Daroussin 			printw(pvconf->fmtbottomstr, bsddialog_total_progview,
368d93b4d32SBaptiste Daroussin 			    readforsec);
369d93b4d32SBaptiste Daroussin 			refresh();
370d93b4d32SBaptiste Daroussin 
371d93b4d32SBaptiste Daroussin 			time(&told);
372d93b4d32SBaptiste Daroussin 			update = false;
373d93b4d32SBaptiste Daroussin 		}
374d93b4d32SBaptiste Daroussin 
375d93b4d32SBaptiste Daroussin 		if (i >= nminibar)
376d93b4d32SBaptiste Daroussin 			break;
377263660c0SAlfonso Siciliano 		if (minibar[i].status == BSDDIALOG_MG_FAILED)
378d93b4d32SBaptiste Daroussin 			break;
379d93b4d32SBaptiste Daroussin 
380d93b4d32SBaptiste Daroussin 		perc = pvconf->callback(&minibar[i]);
381d93b4d32SBaptiste Daroussin 
382263660c0SAlfonso Siciliano 		if (minibar[i].status == BSDDIALOG_MG_DONE) { /*||perc >= 100)*/
383263660c0SAlfonso Siciliano 			minipercs[i] = BSDDIALOG_MG_DONE;
384d93b4d32SBaptiste Daroussin 			update = true;
385d93b4d32SBaptiste Daroussin 			i++;
386*61ba55bcSBaptiste Daroussin 		} else if (minibar[i].status == BSDDIALOG_MG_FAILED ||
387*61ba55bcSBaptiste Daroussin 		    perc < 0) {
388263660c0SAlfonso Siciliano 			minipercs[i] = BSDDIALOG_MG_FAILED;
389d93b4d32SBaptiste Daroussin 			update = true;
390263660c0SAlfonso Siciliano 		} else /* perc >= 0 */
391263660c0SAlfonso Siciliano 			minipercs[i] = perc;
392d93b4d32SBaptiste Daroussin 	}
393d93b4d32SBaptiste Daroussin 
394d93b4d32SBaptiste Daroussin 	free(minilabels);
395d93b4d32SBaptiste Daroussin 	free(minipercs);
396b319d934SAlfonso S. Siciliano 	return (retval);
397d93b4d32SBaptiste Daroussin }
398d93b4d32SBaptiste Daroussin 
rangebox_redraw(struct dialog * d,struct bar * b,int * bigchange)399*61ba55bcSBaptiste Daroussin static int rangebox_redraw(struct dialog *d, struct bar *b, int *bigchange)
400*61ba55bcSBaptiste Daroussin {
401*61ba55bcSBaptiste Daroussin 	if (d->built) {
402*61ba55bcSBaptiste Daroussin 		hide_dialog(d);
403*61ba55bcSBaptiste Daroussin 		refresh(); /* Important for decreasing screen */
404*61ba55bcSBaptiste Daroussin 	}
405*61ba55bcSBaptiste Daroussin 	if (dialog_size_position(d, HBOX, MIN_WBOX, NULL) != 0)
406*61ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
407*61ba55bcSBaptiste Daroussin 	if (draw_dialog(d) != 0)
408*61ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
409*61ba55bcSBaptiste Daroussin 	if (d->built)
410*61ba55bcSBaptiste Daroussin 		refresh(); /* Important to fix grey lines expanding screen */
411*61ba55bcSBaptiste Daroussin 	TEXTPAD(d, HBOX + HBUTTONS);
412*61ba55bcSBaptiste Daroussin 
413*61ba55bcSBaptiste Daroussin 	b->w = WBAR(d);
414*61ba55bcSBaptiste Daroussin 	*bigchange = MAX(1, b->w  / 10);
415*61ba55bcSBaptiste Daroussin 	update_barbox(d, b, true);
416*61ba55bcSBaptiste Daroussin 	b->toupdate = true;
417*61ba55bcSBaptiste Daroussin 
418*61ba55bcSBaptiste Daroussin 	return (0);
419*61ba55bcSBaptiste Daroussin }
420*61ba55bcSBaptiste Daroussin 
421d93b4d32SBaptiste Daroussin int
bsddialog_rangebox(struct bsddialog_conf * conf,const char * text,int rows,int cols,int min,int max,int * value)422263660c0SAlfonso Siciliano bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
423263660c0SAlfonso Siciliano     int cols, int min, int max, int *value)
424c76f0793SBaptiste Daroussin {
425*61ba55bcSBaptiste Daroussin 	bool loop;
426*61ba55bcSBaptiste Daroussin 	int currvalue, retval, bigchange, positions;
427b319d934SAlfonso S. Siciliano 	wint_t input;
428*61ba55bcSBaptiste Daroussin 	struct bar b;
429*61ba55bcSBaptiste Daroussin 	struct dialog d;
430c76f0793SBaptiste Daroussin 
431*61ba55bcSBaptiste Daroussin 	CHECK_PTR(value);
432f499134dSBaptiste Daroussin 	if (min >= max)
433*61ba55bcSBaptiste Daroussin 		RETURN_FMTERROR("min (%d) >= max (%d)", min, max);
434*61ba55bcSBaptiste Daroussin 	if (*value < min)
435*61ba55bcSBaptiste Daroussin 		RETURN_FMTERROR("value (%d) < min (%d)", *value, min);
436*61ba55bcSBaptiste Daroussin 	if (*value > max)
437*61ba55bcSBaptiste Daroussin 		RETURN_FMTERROR("value (%d) > max (%d)", *value, max);
438f499134dSBaptiste Daroussin 
439f499134dSBaptiste Daroussin 	currvalue = *value;
440f499134dSBaptiste Daroussin 	positions = max - min + 1;
441c76f0793SBaptiste Daroussin 
442*61ba55bcSBaptiste Daroussin 	if (prepare_dialog(conf, text, rows, cols, &d) != 0)
443263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
444*61ba55bcSBaptiste Daroussin 	set_buttons(&d, true, OK_LABEL, CANCEL_LABEL);
445*61ba55bcSBaptiste Daroussin 	if ((b.win = newwin(1, 1, 1, 1)) == NULL)
446*61ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot build WINDOW bar");
447*61ba55bcSBaptiste Daroussin 	b.y = b.x = 1;
448*61ba55bcSBaptiste Daroussin 	b.fmt = "%d";
449*61ba55bcSBaptiste Daroussin 	if (rangebox_redraw(&d, &b, &bigchange) != 0)
450263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
451c76f0793SBaptiste Daroussin 
452*61ba55bcSBaptiste Daroussin 	loop = true;
453c76f0793SBaptiste Daroussin 	while (loop) {
454*61ba55bcSBaptiste Daroussin 		if (b.toupdate) {
455*61ba55bcSBaptiste Daroussin 			b.perc = ((float)(currvalue - min)*100) / (positions-1);
456*61ba55bcSBaptiste Daroussin 			b.label = currvalue;
457*61ba55bcSBaptiste Daroussin 			draw_bar(&b);
458f499134dSBaptiste Daroussin 		}
459*61ba55bcSBaptiste Daroussin 		doupdate();
460b319d934SAlfonso S. Siciliano 		if (get_wch(&input) == ERR)
461b319d934SAlfonso S. Siciliano 			continue;
462c76f0793SBaptiste Daroussin 		switch(input) {
463f499134dSBaptiste Daroussin 		case KEY_ENTER:
464f499134dSBaptiste Daroussin 		case 10: /* Enter */
465*61ba55bcSBaptiste Daroussin 			retval = BUTTONVALUE(d.bs);
466c76f0793SBaptiste Daroussin 			loop = false;
467c76f0793SBaptiste Daroussin 			break;
468c76f0793SBaptiste Daroussin 		case 27: /* Esc */
469263660c0SAlfonso Siciliano 			if (conf->key.enable_esc) {
470b319d934SAlfonso S. Siciliano 				retval = BSDDIALOG_ESC;
471c76f0793SBaptiste Daroussin 				loop = false;
472263660c0SAlfonso Siciliano 			}
473c76f0793SBaptiste Daroussin 			break;
474f499134dSBaptiste Daroussin 		case '\t': /* TAB */
475*61ba55bcSBaptiste Daroussin 		case KEY_RIGHT:
476*61ba55bcSBaptiste Daroussin 			d.bs.curr = (d.bs.curr + 1) % d.bs.nbuttons;
477*61ba55bcSBaptiste Daroussin 			DRAW_BUTTONS(d);
478c76f0793SBaptiste Daroussin 			break;
479c76f0793SBaptiste Daroussin 		case KEY_LEFT:
480*61ba55bcSBaptiste Daroussin 			d.bs.curr--;
481*61ba55bcSBaptiste Daroussin 			if (d.bs.curr < 0)
482*61ba55bcSBaptiste Daroussin 				 d.bs.curr = d.bs.nbuttons - 1;
483*61ba55bcSBaptiste Daroussin 			DRAW_BUTTONS(d);
484c76f0793SBaptiste Daroussin 			break;
485f499134dSBaptiste Daroussin 		case KEY_HOME:
486f499134dSBaptiste Daroussin 			currvalue = max;
487*61ba55bcSBaptiste Daroussin 			b.toupdate = true;
488f499134dSBaptiste Daroussin 			break;
489f499134dSBaptiste Daroussin 		case KEY_END:
490f499134dSBaptiste Daroussin 			currvalue = min;
491*61ba55bcSBaptiste Daroussin 			b.toupdate = true;
492f499134dSBaptiste Daroussin 			break;
493f499134dSBaptiste Daroussin 		case KEY_NPAGE:
494f499134dSBaptiste Daroussin 			currvalue -= bigchange;
495f499134dSBaptiste Daroussin 			if (currvalue < min)
496f499134dSBaptiste Daroussin 				currvalue = min;
497*61ba55bcSBaptiste Daroussin 			b.toupdate = true;
498f499134dSBaptiste Daroussin 			break;
499f499134dSBaptiste Daroussin 		case KEY_PPAGE:
500f499134dSBaptiste Daroussin 			currvalue += bigchange;
501f499134dSBaptiste Daroussin 			if (currvalue > max)
502f499134dSBaptiste Daroussin 				currvalue = max;
503*61ba55bcSBaptiste Daroussin 			b.toupdate = true;
504f499134dSBaptiste Daroussin 			break;
505c76f0793SBaptiste Daroussin 		case KEY_UP:
506c76f0793SBaptiste Daroussin 			if (currvalue < max) {
507c76f0793SBaptiste Daroussin 				currvalue++;
508*61ba55bcSBaptiste Daroussin 				b.toupdate = true;
509c76f0793SBaptiste Daroussin 			}
510c76f0793SBaptiste Daroussin 			break;
511c76f0793SBaptiste Daroussin 		case KEY_DOWN:
512c76f0793SBaptiste Daroussin 			if (currvalue > min) {
513c76f0793SBaptiste Daroussin 				currvalue--;
514*61ba55bcSBaptiste Daroussin 				b.toupdate = true;
515c76f0793SBaptiste Daroussin 			}
516c76f0793SBaptiste Daroussin 			break;
517f499134dSBaptiste Daroussin 		case KEY_F(1):
518bce40c02SAlfonso S. Siciliano 			if (conf->key.f1_file == NULL &&
519bce40c02SAlfonso S. Siciliano 			    conf->key.f1_message == NULL)
520f499134dSBaptiste Daroussin 				break;
521*61ba55bcSBaptiste Daroussin 			if (f1help_dialog(conf) != 0)
522263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
523*61ba55bcSBaptiste Daroussin 			if (rangebox_redraw(&d, &b, &bigchange) != 0)
524*61ba55bcSBaptiste Daroussin 				return (BSDDIALOG_ERROR);
525*61ba55bcSBaptiste Daroussin 			break;
526f499134dSBaptiste Daroussin 		case KEY_RESIZE:
527*61ba55bcSBaptiste Daroussin 			if (rangebox_redraw(&d, &b, &bigchange) != 0)
528263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
529f499134dSBaptiste Daroussin 			break;
530f499134dSBaptiste Daroussin 		default:
531*61ba55bcSBaptiste Daroussin 			if (shortcut_buttons(input, &d.bs)) {
532*61ba55bcSBaptiste Daroussin 				DRAW_BUTTONS(d);
533*61ba55bcSBaptiste Daroussin 				doupdate();
534*61ba55bcSBaptiste Daroussin 				retval = BUTTONVALUE(d.bs);
535f499134dSBaptiste Daroussin 				loop = false;
536f499134dSBaptiste Daroussin 			}
537c76f0793SBaptiste Daroussin 		}
538c76f0793SBaptiste Daroussin 	}
539c76f0793SBaptiste Daroussin 
540*61ba55bcSBaptiste Daroussin 	*value = currvalue;
541*61ba55bcSBaptiste Daroussin 
542*61ba55bcSBaptiste Daroussin 	delwin(b.win);
543*61ba55bcSBaptiste Daroussin 	end_dialog(&d);
544c76f0793SBaptiste Daroussin 
545b319d934SAlfonso S. Siciliano 	return (retval);
546c76f0793SBaptiste Daroussin }
547c76f0793SBaptiste Daroussin 
pause_redraw(struct dialog * d,struct bar * b)548*61ba55bcSBaptiste Daroussin static int pause_redraw(struct dialog *d, struct bar *b)
549*61ba55bcSBaptiste Daroussin {
550*61ba55bcSBaptiste Daroussin 	if (d->built) {
551*61ba55bcSBaptiste Daroussin 		hide_dialog(d);
552*61ba55bcSBaptiste Daroussin 		refresh(); /* Important for decreasing screen */
553*61ba55bcSBaptiste Daroussin 	}
554*61ba55bcSBaptiste Daroussin 	if (dialog_size_position(d, HBOX, MIN_WBOX, NULL) != 0)
555*61ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
556*61ba55bcSBaptiste Daroussin 	if (draw_dialog(d) != 0)
557*61ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
558*61ba55bcSBaptiste Daroussin 	if (d->built)
559*61ba55bcSBaptiste Daroussin 		refresh(); /* Important to fix grey lines expanding screen */
560*61ba55bcSBaptiste Daroussin 	TEXTPAD(d, HBOX + HBUTTONS);
561*61ba55bcSBaptiste Daroussin 
562*61ba55bcSBaptiste Daroussin 	b->w = WBAR(d);
563*61ba55bcSBaptiste Daroussin 	update_barbox(d, b, true);
564*61ba55bcSBaptiste Daroussin 	b->toupdate = true;
565*61ba55bcSBaptiste Daroussin 
566*61ba55bcSBaptiste Daroussin 	return (0);
567*61ba55bcSBaptiste Daroussin }
568*61ba55bcSBaptiste Daroussin 
569f499134dSBaptiste Daroussin int
bsddialog_pause(struct bsddialog_conf * conf,const char * text,int rows,int cols,unsigned int * seconds)570263660c0SAlfonso Siciliano bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
571*61ba55bcSBaptiste Daroussin     int cols, unsigned int *seconds)
572c76f0793SBaptiste Daroussin {
573*61ba55bcSBaptiste Daroussin 	bool loop;
574*61ba55bcSBaptiste Daroussin 	int retval, tout;
575b319d934SAlfonso S. Siciliano 	wint_t input;
576*61ba55bcSBaptiste Daroussin 	struct bar b;
577*61ba55bcSBaptiste Daroussin 	struct dialog d;
578c76f0793SBaptiste Daroussin 
579*61ba55bcSBaptiste Daroussin 	CHECK_PTR(seconds);
580*61ba55bcSBaptiste Daroussin 	if (prepare_dialog(conf, text, rows, cols, &d) != 0)
581263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
582*61ba55bcSBaptiste Daroussin 	set_buttons(&d, true, OK_LABEL, CANCEL_LABEL);
583*61ba55bcSBaptiste Daroussin 	if ((b.win = newwin(1, 1, 1, 1)) == NULL)
584*61ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot build WINDOW bar");
585*61ba55bcSBaptiste Daroussin 	b.y = b.x = 1;
586*61ba55bcSBaptiste Daroussin 	b.fmt = "%d";
587*61ba55bcSBaptiste Daroussin 	if (pause_redraw(&d, &b) != 0)
588263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
589f499134dSBaptiste Daroussin 
590*61ba55bcSBaptiste Daroussin 	tout = *seconds;
591c76f0793SBaptiste Daroussin 	nodelay(stdscr, TRUE);
592c76f0793SBaptiste Daroussin 	timeout(1000);
593*61ba55bcSBaptiste Daroussin 	loop = true;
594c76f0793SBaptiste Daroussin 	while (loop) {
595*61ba55bcSBaptiste Daroussin 		if (b.toupdate) {
596*61ba55bcSBaptiste Daroussin 			b.perc = (float)tout * 100 / *seconds;
597*61ba55bcSBaptiste Daroussin 			b.label = tout;
598*61ba55bcSBaptiste Daroussin 			draw_bar(&b);
599c76f0793SBaptiste Daroussin 		}
600*61ba55bcSBaptiste Daroussin 		doupdate();
601b319d934SAlfonso S. Siciliano 		if (get_wch(&input) == ERR) { /* timeout */
602f499134dSBaptiste Daroussin 			tout--;
603f499134dSBaptiste Daroussin 			if (tout < 0) {
604b319d934SAlfonso S. Siciliano 				retval = BSDDIALOG_TIMEOUT;
605c76f0793SBaptiste Daroussin 				break;
606c76f0793SBaptiste Daroussin 			}
607c76f0793SBaptiste Daroussin 			else {
608*61ba55bcSBaptiste Daroussin 				b.toupdate = true;
609c76f0793SBaptiste Daroussin 				continue;
610c76f0793SBaptiste Daroussin 			}
611c76f0793SBaptiste Daroussin 		}
612c76f0793SBaptiste Daroussin 		switch(input) {
613f499134dSBaptiste Daroussin 		case KEY_ENTER:
614f499134dSBaptiste Daroussin 		case 10: /* Enter */
615*61ba55bcSBaptiste Daroussin 			retval = BUTTONVALUE(d.bs);
616c76f0793SBaptiste Daroussin 			loop = false;
617c76f0793SBaptiste Daroussin 			break;
618c76f0793SBaptiste Daroussin 		case 27: /* Esc */
619263660c0SAlfonso Siciliano 			if (conf->key.enable_esc) {
620b319d934SAlfonso S. Siciliano 				retval = BSDDIALOG_ESC;
621c76f0793SBaptiste Daroussin 				loop = false;
622263660c0SAlfonso Siciliano 			}
623c76f0793SBaptiste Daroussin 			break;
624f499134dSBaptiste Daroussin 		case '\t': /* TAB */
625*61ba55bcSBaptiste Daroussin 		case KEY_RIGHT:
626*61ba55bcSBaptiste Daroussin 			d.bs.curr = (d.bs.curr + 1) % d.bs.nbuttons;
627*61ba55bcSBaptiste Daroussin 			DRAW_BUTTONS(d);
628c76f0793SBaptiste Daroussin 			break;
629c76f0793SBaptiste Daroussin 		case KEY_LEFT:
630*61ba55bcSBaptiste Daroussin 			d.bs.curr--;
631*61ba55bcSBaptiste Daroussin 			if (d.bs.curr < 0)
632*61ba55bcSBaptiste Daroussin 				 d.bs.curr = d.bs.nbuttons - 1;
633*61ba55bcSBaptiste Daroussin 			DRAW_BUTTONS(d);
634c76f0793SBaptiste Daroussin 			break;
635f499134dSBaptiste Daroussin 		case KEY_F(1):
636bce40c02SAlfonso S. Siciliano 			if (conf->key.f1_file == NULL &&
637bce40c02SAlfonso S. Siciliano 			    conf->key.f1_message == NULL)
638f499134dSBaptiste Daroussin 				break;
639*61ba55bcSBaptiste Daroussin 			if (f1help_dialog(conf) != 0)
640263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
641*61ba55bcSBaptiste Daroussin 			if (pause_redraw(&d, &b) != 0)
642*61ba55bcSBaptiste Daroussin 				return (BSDDIALOG_ERROR);
643*61ba55bcSBaptiste Daroussin 			break;
644f499134dSBaptiste Daroussin 		case KEY_RESIZE:
645*61ba55bcSBaptiste Daroussin 			if (pause_redraw(&d, &b) != 0)
646263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
647f499134dSBaptiste Daroussin 			break;
648f499134dSBaptiste Daroussin 		default:
649*61ba55bcSBaptiste Daroussin 			if (shortcut_buttons(input, &d.bs)) {
650*61ba55bcSBaptiste Daroussin 				DRAW_BUTTONS(d);
651*61ba55bcSBaptiste Daroussin 				doupdate();
652*61ba55bcSBaptiste Daroussin 				retval = BUTTONVALUE(d.bs);
653f499134dSBaptiste Daroussin 				loop = false;
654f499134dSBaptiste Daroussin 			}
655c76f0793SBaptiste Daroussin 		}
656c76f0793SBaptiste Daroussin 	}
657c76f0793SBaptiste Daroussin 	nodelay(stdscr, FALSE);
658c76f0793SBaptiste Daroussin 
659*61ba55bcSBaptiste Daroussin 	*seconds = MAX(tout, 0);
660*61ba55bcSBaptiste Daroussin 
661*61ba55bcSBaptiste Daroussin 	delwin(b.win);
662*61ba55bcSBaptiste Daroussin 	end_dialog(&d);
663c76f0793SBaptiste Daroussin 
664b319d934SAlfonso S. Siciliano 	return (retval);
665c76f0793SBaptiste Daroussin }
666