xref: /freebsd/contrib/bsddialog/lib/barbox.c (revision a6d8be451f62d425b71a4874f7d4e133b9fb393c)
1c76f0793SBaptiste Daroussin /*-
2c76f0793SBaptiste Daroussin  * SPDX-License-Identifier: BSD-2-Clause
3c76f0793SBaptiste Daroussin  *
4*a6d8be45SAlfonso S. Siciliano  * Copyright (c) 2021-2024 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*a6d8be45SAlfonso S. Siciliano #define BARPADDING   2  /* Dialog border | BARPADDING | box bar */
4061ba55bcSBaptiste Daroussin #define BOXBORDERS   2
4161ba55bcSBaptiste Daroussin #define MIN_WBAR     15
4261ba55bcSBaptiste Daroussin #define MIN_WBOX     (BARPADDING + BOXBORDERS + MIN_WBAR + BARPADDING)
43*a6d8be45SAlfonso S. Siciliano #define MIN_WMGBAR   18 /* Mixedgauge main bar */
4461ba55bcSBaptiste Daroussin #define MIN_WMGBOX   (BARPADDING + BOXBORDERS + MIN_WMGBAR + BARPADDING)
4561ba55bcSBaptiste Daroussin #define HBOX         3
4661ba55bcSBaptiste Daroussin #define WBOX(d)      ((d)->w - BORDERS - BARPADDING - BARPADDING)
4761ba55bcSBaptiste Daroussin #define WBAR(d)      (WBOX(d) - BOXBORDERS)
48d93b4d32SBaptiste Daroussin 
49d93b4d32SBaptiste Daroussin bool bsddialog_interruptprogview;
50d93b4d32SBaptiste Daroussin bool bsddialog_abortprogview;
5161ba55bcSBaptiste Daroussin long long int bsddialog_total_progview;
52c76f0793SBaptiste Daroussin 
5361ba55bcSBaptiste 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 
6861ba55bcSBaptiste Daroussin struct bar {
6961ba55bcSBaptiste Daroussin 	bool toupdate;
7061ba55bcSBaptiste Daroussin 	WINDOW *win;
7161ba55bcSBaptiste Daroussin 	int y;           /* bar y in win */
7261ba55bcSBaptiste Daroussin 	int x;           /* bar x in win */
7361ba55bcSBaptiste Daroussin 	int w;           /* width in win */
7461ba55bcSBaptiste Daroussin 	int perc;        /* barlen = (w * perc) / 100 */
7561ba55bcSBaptiste Daroussin 	const char* fmt; /* format for label */
7661ba55bcSBaptiste Daroussin 	int label;       /* rangebox and pause perc!=label */
7761ba55bcSBaptiste Daroussin };
7861ba55bcSBaptiste Daroussin 
7961ba55bcSBaptiste Daroussin static void draw_bar(struct bar *b)
8061ba55bcSBaptiste Daroussin {
8161ba55bcSBaptiste Daroussin 	int barlen, xlabel;
8261ba55bcSBaptiste Daroussin 	chtype ch;
8361ba55bcSBaptiste Daroussin 	char label[128];
8461ba55bcSBaptiste Daroussin 
8561ba55bcSBaptiste Daroussin 	barlen = b->perc > 0 ? (b->perc * b->w) / 100 : 0;
8661ba55bcSBaptiste Daroussin 
8761ba55bcSBaptiste Daroussin 	ch = ' ' | t.bar.f_color;
8861ba55bcSBaptiste Daroussin 	mvwhline(b->win, b->y, b->x, ch, barlen);
8961ba55bcSBaptiste Daroussin 	ch = ' ' | t.bar.color;
9061ba55bcSBaptiste Daroussin 	mvwhline(b->win, b->y, b->x + barlen, ch, b->w - barlen);
9161ba55bcSBaptiste Daroussin 
9261ba55bcSBaptiste Daroussin 	sprintf(label, b->fmt, b->label);
9361ba55bcSBaptiste Daroussin 	xlabel = b->x + b->w/2 - (int)strlen(label)/2; /* 1-byte-char string */
9461ba55bcSBaptiste Daroussin 	wattron(b->win, t.bar.color);   /* x+barlen < xlabel */
9561ba55bcSBaptiste Daroussin 	mvwaddstr(b->win, b->y, xlabel, label);
9661ba55bcSBaptiste Daroussin 	wattroff(b->win, t.bar.color);
9761ba55bcSBaptiste Daroussin 	wattron(b->win, t.bar.f_color); /* x+barlen >= xlabel */
9861ba55bcSBaptiste Daroussin 	mvwaddnstr(b->win, b->y, xlabel, label, MAX((b->x+barlen) - xlabel, 0));
9961ba55bcSBaptiste Daroussin 	wattroff(b->win, t.bar.f_color);
10061ba55bcSBaptiste Daroussin 
10161ba55bcSBaptiste Daroussin 	if (b->toupdate)
10261ba55bcSBaptiste Daroussin 		wnoutrefresh(b->win);
10361ba55bcSBaptiste Daroussin 	b->toupdate = false;
10461ba55bcSBaptiste Daroussin }
10561ba55bcSBaptiste Daroussin 
10661ba55bcSBaptiste Daroussin static void update_barbox(struct dialog *d, struct bar *b, bool buttons)
10761ba55bcSBaptiste Daroussin {
10861ba55bcSBaptiste Daroussin 	int y;
10961ba55bcSBaptiste Daroussin 
11061ba55bcSBaptiste Daroussin 	y = d->y + d->h - BORDER - HBOX;
11161ba55bcSBaptiste Daroussin 	if (buttons)
11261ba55bcSBaptiste Daroussin 		y -= HBUTTONS;
11361ba55bcSBaptiste Daroussin 	update_box(d->conf, b->win, y, d->x + BORDER + BARPADDING, HBOX,
11461ba55bcSBaptiste Daroussin 	    WBOX(d), RAISED);
11561ba55bcSBaptiste Daroussin }
11661ba55bcSBaptiste Daroussin 
11761ba55bcSBaptiste Daroussin int
11861ba55bcSBaptiste Daroussin bsddialog_gauge(struct bsddialog_conf *conf, const char *text, int rows,
11961ba55bcSBaptiste Daroussin     int cols, unsigned int perc, int fd, const char *sep, const char *end)
12061ba55bcSBaptiste Daroussin {
12161ba55bcSBaptiste Daroussin 	bool mainloop;
12261ba55bcSBaptiste Daroussin 	int fd2;
12361ba55bcSBaptiste Daroussin 	FILE *input;
12461ba55bcSBaptiste Daroussin 	char inputbuf[2048], ntext[2048], *pntext;
12561ba55bcSBaptiste Daroussin 	struct bar b;
12661ba55bcSBaptiste Daroussin 	struct dialog d;
12761ba55bcSBaptiste Daroussin 
12861ba55bcSBaptiste Daroussin 	if (prepare_dialog(conf, text, rows, cols, &d) != 0)
12961ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
13061ba55bcSBaptiste Daroussin 	if ((b.win = newwin(1, 1, 1, 1)) == NULL)
13161ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot build WINDOW bar");
13261ba55bcSBaptiste Daroussin 	b.y = b.x = 1;
13361ba55bcSBaptiste Daroussin 	b.fmt = "%3d%%";
13461ba55bcSBaptiste Daroussin 
13561ba55bcSBaptiste Daroussin 	input = NULL;
13661ba55bcSBaptiste Daroussin 	if (fd >= 0) {
13761ba55bcSBaptiste Daroussin 		CHECK_PTR(sep);
13861ba55bcSBaptiste Daroussin 		CHECK_PTR(end);
13961ba55bcSBaptiste Daroussin 
14061ba55bcSBaptiste Daroussin 		fd2 = dup(fd);
14161ba55bcSBaptiste Daroussin 		if ((input = fdopen(fd2, "r")) == NULL)
14261ba55bcSBaptiste Daroussin 			RETURN_FMTERROR("Cannot build FILE* from fd %d", fd);
14361ba55bcSBaptiste Daroussin 	}
14461ba55bcSBaptiste Daroussin 
14561ba55bcSBaptiste Daroussin 	perc = MIN(perc, 100);
14661ba55bcSBaptiste Daroussin 	mainloop = true;
14761ba55bcSBaptiste Daroussin 	while (mainloop) {
14861ba55bcSBaptiste Daroussin 		if (d.built) {
14961ba55bcSBaptiste Daroussin 			hide_dialog(&d);
15061ba55bcSBaptiste Daroussin 			refresh(); /* Important for decreasing screen */
15161ba55bcSBaptiste Daroussin 		}
15261ba55bcSBaptiste Daroussin 		if (dialog_size_position(&d, HBOX, MIN_WBOX, NULL) != 0)
15361ba55bcSBaptiste Daroussin 			return (BSDDIALOG_ERROR);
15461ba55bcSBaptiste Daroussin 		if (draw_dialog(&d))
15561ba55bcSBaptiste Daroussin 			return (BSDDIALOG_ERROR);
15661ba55bcSBaptiste Daroussin 		if (d.built)
15761ba55bcSBaptiste Daroussin 			refresh(); /* fix grey lines expanding screen */
15861ba55bcSBaptiste Daroussin 		TEXTPAD(&d, HBOX);
15961ba55bcSBaptiste Daroussin 		update_barbox(&d, &b, false);
16061ba55bcSBaptiste Daroussin 		b.w = WBAR(&d);
16161ba55bcSBaptiste Daroussin 		b.perc = b.label = perc;
16261ba55bcSBaptiste Daroussin 		b.toupdate = true;
16361ba55bcSBaptiste Daroussin 		draw_bar(&b);
16461ba55bcSBaptiste Daroussin 		doupdate();
16561ba55bcSBaptiste Daroussin 		if (input == NULL) /* that is fd < 0 */
16661ba55bcSBaptiste Daroussin 			break;
16761ba55bcSBaptiste Daroussin 
16861ba55bcSBaptiste Daroussin 		while (true) {
16961ba55bcSBaptiste Daroussin 			fscanf(input, "%s", inputbuf);
17061ba55bcSBaptiste Daroussin 			if (strcmp(inputbuf, end) == 0) {
17161ba55bcSBaptiste Daroussin 				mainloop = false;
17261ba55bcSBaptiste Daroussin 				break;
17361ba55bcSBaptiste Daroussin 			}
17461ba55bcSBaptiste Daroussin 			if (strcmp(inputbuf, sep) == 0)
17561ba55bcSBaptiste Daroussin 				break;
17661ba55bcSBaptiste Daroussin 		}
17761ba55bcSBaptiste Daroussin 		if (mainloop == false)
17861ba55bcSBaptiste Daroussin 			break;
17961ba55bcSBaptiste Daroussin 		fscanf(input, "%d", &perc);
18061ba55bcSBaptiste Daroussin 		perc = MIN(perc, 100);
18161ba55bcSBaptiste Daroussin 		pntext = &ntext[0];
18261ba55bcSBaptiste Daroussin 		ntext[0] = '\0';
18361ba55bcSBaptiste Daroussin 		while (true) {
18461ba55bcSBaptiste Daroussin 			fscanf(input, "%s", inputbuf);
18561ba55bcSBaptiste Daroussin 			if (strcmp(inputbuf, end) == 0) {
18661ba55bcSBaptiste Daroussin 				mainloop = false;
18761ba55bcSBaptiste Daroussin 				break;
18861ba55bcSBaptiste Daroussin 			}
18961ba55bcSBaptiste Daroussin 			if (strcmp(inputbuf, sep) == 0)
19061ba55bcSBaptiste Daroussin 				break;
19161ba55bcSBaptiste Daroussin 			strcpy(pntext, inputbuf);
19261ba55bcSBaptiste Daroussin 			pntext += strlen(inputbuf); /* end string, no strlen */
19361ba55bcSBaptiste Daroussin 			pntext[0] = ' ';
19461ba55bcSBaptiste Daroussin 			pntext++;
19561ba55bcSBaptiste Daroussin 		}
19661ba55bcSBaptiste Daroussin 		pntext[0] = '\0';
19761ba55bcSBaptiste Daroussin 		d.text = ntext;
19861ba55bcSBaptiste Daroussin 	}
19961ba55bcSBaptiste Daroussin 
20061ba55bcSBaptiste Daroussin 	if (input != NULL)
20161ba55bcSBaptiste Daroussin 		fclose(input);
20261ba55bcSBaptiste Daroussin 	delwin(b.win);
20361ba55bcSBaptiste Daroussin 	end_dialog(&d);
20461ba55bcSBaptiste Daroussin 
20561ba55bcSBaptiste Daroussin 	return (BSDDIALOG_OK);
20661ba55bcSBaptiste Daroussin }
20761ba55bcSBaptiste Daroussin 
20861ba55bcSBaptiste Daroussin /* Mixedgauge */
209*a6d8be45SAlfonso S. Siciliano static void
210*a6d8be45SAlfonso S. Siciliano mvwaddcstr(WINDOW *win, int y, int x, const char *mbstring, unsigned int cols)
211*a6d8be45SAlfonso S. Siciliano {
212*a6d8be45SAlfonso S. Siciliano 	size_t charlen, n, w;
213*a6d8be45SAlfonso S. Siciliano 	mbstate_t mbs;
214*a6d8be45SAlfonso S. Siciliano 	const char *pmbstring;
215*a6d8be45SAlfonso S. Siciliano 	wchar_t wch;
216*a6d8be45SAlfonso S. Siciliano 
217*a6d8be45SAlfonso S. Siciliano 	w = n = 0;
218*a6d8be45SAlfonso S. Siciliano 	pmbstring = mbstring;
219*a6d8be45SAlfonso S. Siciliano 	memset(&mbs, 0, sizeof(mbs));
220*a6d8be45SAlfonso S. Siciliano 	while ((charlen = mbrlen(pmbstring, MB_CUR_MAX, &mbs)) != 0 &&
221*a6d8be45SAlfonso S. Siciliano 	    charlen != (size_t)-1 && charlen != (size_t)-2) {
222*a6d8be45SAlfonso S. Siciliano 		mbtowc(&wch, pmbstring, charlen);
223*a6d8be45SAlfonso S. Siciliano 		w += (wch == L'\t') ? TABSIZE : wcwidth(wch);
224*a6d8be45SAlfonso S. Siciliano 		if (w > cols)
225*a6d8be45SAlfonso S. Siciliano 			break;
226*a6d8be45SAlfonso S. Siciliano 		pmbstring += charlen;
227*a6d8be45SAlfonso S. Siciliano 		n += charlen;
228*a6d8be45SAlfonso S. Siciliano 	}
229*a6d8be45SAlfonso S. Siciliano 	mvwaddnstr(win, y, x, mbstring, n);
230*a6d8be45SAlfonso S. Siciliano 	if(w > cols)
231*a6d8be45SAlfonso S. Siciliano 		mvwaddstr(win, y, (x + cols) - 3, "...");
232*a6d8be45SAlfonso S. Siciliano }
233*a6d8be45SAlfonso S. Siciliano 
234*a6d8be45SAlfonso S. Siciliano static int
235*a6d8be45SAlfonso S. Siciliano mixedgauge_size_position(struct dialog *d, int nminibars,
236*a6d8be45SAlfonso S. Siciliano     const char **minilabels, int *htext)
237*a6d8be45SAlfonso S. Siciliano {
238*a6d8be45SAlfonso S. Siciliano 	int i, max_minibarlen;
239*a6d8be45SAlfonso S. Siciliano 
240*a6d8be45SAlfonso S. Siciliano 	max_minibarlen = 0;
241*a6d8be45SAlfonso S. Siciliano 	for (i = 0; i < (int)nminibars; i++)
242*a6d8be45SAlfonso S. Siciliano 		max_minibarlen = MAX(max_minibarlen,
243*a6d8be45SAlfonso S. Siciliano 		    (int)strcols(CHECK_STR(minilabels[i])));
244*a6d8be45SAlfonso S. Siciliano 	max_minibarlen += 18; /* ' '<max_minibarlen>' ['13'] ' */
245*a6d8be45SAlfonso S. Siciliano 	max_minibarlen = MAX(max_minibarlen, MIN_WMGBOX); /* mainbar */
246*a6d8be45SAlfonso S. Siciliano 
247*a6d8be45SAlfonso S. Siciliano 	if (set_widget_size(d->conf, d->rows, d->cols, &d->h, &d->w) != 0)
248*a6d8be45SAlfonso S. Siciliano 		return (BSDDIALOG_ERROR);
249*a6d8be45SAlfonso S. Siciliano 	if (set_widget_autosize(d->conf, d->rows, d->cols, &d->h, &d->w,
250*a6d8be45SAlfonso S. Siciliano 	    d->text, htext, &d->bs, nminibars + HBOX, max_minibarlen) != 0)
251*a6d8be45SAlfonso S. Siciliano 		return (BSDDIALOG_ERROR);
252*a6d8be45SAlfonso S. Siciliano 	if (widget_checksize(d->h, d->w, &d->bs, nminibars + HBOX,
253*a6d8be45SAlfonso S. Siciliano 	    MIN_WMGBOX) != 0)
254*a6d8be45SAlfonso S. Siciliano 		return (BSDDIALOG_ERROR);
255*a6d8be45SAlfonso S. Siciliano 	if (set_widget_position(d->conf, &d->y, &d->x, d->h, d->w) != 0)
256*a6d8be45SAlfonso S. Siciliano 		return (BSDDIALOG_ERROR);
257*a6d8be45SAlfonso S. Siciliano 
258*a6d8be45SAlfonso S. Siciliano 	return (0);
259*a6d8be45SAlfonso S. Siciliano }
260*a6d8be45SAlfonso S. Siciliano 
26161ba55bcSBaptiste Daroussin static int
26261ba55bcSBaptiste Daroussin do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
26361ba55bcSBaptiste Daroussin     unsigned int mainperc, unsigned int nminibars, const char **minilabels,
26461ba55bcSBaptiste Daroussin     int *minipercs, bool color)
26561ba55bcSBaptiste Daroussin {
266*a6d8be45SAlfonso S. Siciliano 	int i, miniperc;
26761ba55bcSBaptiste Daroussin 	int ystext, htext;
26861ba55bcSBaptiste Daroussin 	int minicolor, red, green;
26961ba55bcSBaptiste Daroussin 	struct bar b;
27061ba55bcSBaptiste Daroussin 	struct dialog d;
27161ba55bcSBaptiste Daroussin 
27261ba55bcSBaptiste Daroussin 	CHECK_ARRAY(nminibars, minilabels);
27361ba55bcSBaptiste Daroussin 	CHECK_ARRAY(nminibars, minipercs);
27461ba55bcSBaptiste Daroussin 
275d93b4d32SBaptiste Daroussin 	red   = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_RED,  BSDDIALOG_BOLD);
276d93b4d32SBaptiste Daroussin 	green = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_GREEN,BSDDIALOG_BOLD);
277d93b4d32SBaptiste Daroussin 
27861ba55bcSBaptiste Daroussin 	if (prepare_dialog(conf, text, rows, cols, &d) != 0)
279263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
280*a6d8be45SAlfonso S. Siciliano 	if (mixedgauge_size_position(&d, nminibars, minilabels, &htext) != 0)
281263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
28261ba55bcSBaptiste Daroussin 	if (draw_dialog(&d) != 0)
283263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
284f499134dSBaptiste Daroussin 
285c76f0793SBaptiste Daroussin 	/* mini bars */
28661ba55bcSBaptiste Daroussin 	b.win = d.widget;
28761ba55bcSBaptiste Daroussin 	b.x = 1 + d.w - 2 - 15;
28861ba55bcSBaptiste Daroussin 	b.w = 13;
28961ba55bcSBaptiste Daroussin 	b.fmt = "%3d%%";
29061ba55bcSBaptiste Daroussin 	b.toupdate = false;
2918c4f4028SBaptiste Daroussin 	for (i = 0; i < (int)nminibars; i++) {
2928c4f4028SBaptiste Daroussin 		miniperc = minipercs[i];
29361ba55bcSBaptiste Daroussin 		/* label */
29461ba55bcSBaptiste Daroussin 		if (color && miniperc >= 0)
29561ba55bcSBaptiste Daroussin 			wattron(d.widget, A_BOLD);
296*a6d8be45SAlfonso S. Siciliano 		mvwaddcstr(d.widget, i+1, 2, CHECK_STR(minilabels[i]), d.w-20);
29761ba55bcSBaptiste Daroussin 		if (color && miniperc >= 0)
29861ba55bcSBaptiste Daroussin 			wattroff(d.widget, A_BOLD);
29961ba55bcSBaptiste Daroussin 		/* perc */
300263660c0SAlfonso Siciliano 		if (miniperc == BSDDIALOG_MG_BLANK)
301c76f0793SBaptiste Daroussin 			continue;
30261ba55bcSBaptiste Daroussin 		mvwaddstr(d.widget, i+1, d.w-2-15, "[             ]");
30361ba55bcSBaptiste Daroussin 		if (miniperc >= 0) {
30461ba55bcSBaptiste Daroussin 			b.y = i + 1;
30561ba55bcSBaptiste Daroussin 			b.perc = b.label = MIN(miniperc, 100);
30661ba55bcSBaptiste Daroussin 			draw_bar(&b);
30761ba55bcSBaptiste Daroussin 		} else { /* miniperc < 0 */
30861ba55bcSBaptiste Daroussin 			if (miniperc < BSDDIALOG_MG_PENDING)
30961ba55bcSBaptiste Daroussin 				miniperc = -12; /* UNKNOWN */
31061ba55bcSBaptiste Daroussin 			minicolor = t.dialog.color;
311263660c0SAlfonso Siciliano 			if (color && miniperc == BSDDIALOG_MG_FAILED)
31261ba55bcSBaptiste Daroussin 				minicolor = red;
31361ba55bcSBaptiste Daroussin 			else if (color && miniperc == BSDDIALOG_MG_DONE)
31461ba55bcSBaptiste Daroussin 				minicolor = green;
31561ba55bcSBaptiste Daroussin 			wattron(d.widget, minicolor);
316263660c0SAlfonso Siciliano 			miniperc = abs(miniperc + 1);
31761ba55bcSBaptiste Daroussin 			mvwaddstr(d.widget, i+1, 1+d.w-2-15, states[miniperc]);
31861ba55bcSBaptiste Daroussin 			wattroff(d.widget, minicolor);
319c76f0793SBaptiste Daroussin 		}
320c76f0793SBaptiste Daroussin 	}
32161ba55bcSBaptiste Daroussin 	wnoutrefresh(d.widget);
322c76f0793SBaptiste Daroussin 
32361ba55bcSBaptiste Daroussin 	/* text */
32461ba55bcSBaptiste Daroussin 	ystext = MAX(d.h - BORDERS - htext - HBOX, (int)nminibars);
32561ba55bcSBaptiste Daroussin 	rtextpad(&d, 0, 0, ystext, HBOX);
326c76f0793SBaptiste Daroussin 
327c76f0793SBaptiste Daroussin 	/* main bar */
32861ba55bcSBaptiste Daroussin 	if ((b.win = newwin(1, 1, 1, 1)) == NULL)
32961ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot build WINDOW bar");
33061ba55bcSBaptiste Daroussin 	update_barbox(&d, &b, false);
33161ba55bcSBaptiste Daroussin 	wattron(b.win, t.bar.color);
33261ba55bcSBaptiste Daroussin 	mvwaddstr(b.win, 0, 2, "Overall Progress");
33361ba55bcSBaptiste Daroussin 	wattroff(b.win, t.bar.color);
334c76f0793SBaptiste Daroussin 
33561ba55bcSBaptiste Daroussin 	b.y = b.x = 1;
33661ba55bcSBaptiste Daroussin 	b.w = WBAR(&d);
33761ba55bcSBaptiste Daroussin 	b.fmt = "%3d%%";
33861ba55bcSBaptiste Daroussin 	b.perc = b.label = MIN(mainperc, 100);
33961ba55bcSBaptiste Daroussin 	b.toupdate = true;
34061ba55bcSBaptiste Daroussin 	draw_bar(&b);
341f499134dSBaptiste Daroussin 
34261ba55bcSBaptiste Daroussin 	doupdate();
34361ba55bcSBaptiste Daroussin 	/* getch(); to test with "alternate mode" */
344c76f0793SBaptiste Daroussin 
34561ba55bcSBaptiste Daroussin 	delwin(b.win);
34661ba55bcSBaptiste Daroussin 	end_dialog(&d);
347c76f0793SBaptiste Daroussin 
348263660c0SAlfonso Siciliano 	return (BSDDIALOG_OK);
349c76f0793SBaptiste Daroussin }
350c76f0793SBaptiste Daroussin 
351c76f0793SBaptiste Daroussin int
352263660c0SAlfonso Siciliano bsddialog_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows,
353263660c0SAlfonso Siciliano     int cols, unsigned int mainperc, unsigned int nminibars,
354263660c0SAlfonso Siciliano     const char **minilabels, int *minipercs)
355d93b4d32SBaptiste Daroussin {
356b319d934SAlfonso S. Siciliano 	int retval;
357d93b4d32SBaptiste Daroussin 
358b319d934SAlfonso S. Siciliano 	retval = do_mixedgauge(conf, text, rows, cols, mainperc, nminibars,
359d93b4d32SBaptiste Daroussin 	    minilabels, minipercs, false);
360d93b4d32SBaptiste Daroussin 
361b319d934SAlfonso S. Siciliano 	return (retval);
362d93b4d32SBaptiste Daroussin }
363d93b4d32SBaptiste Daroussin 
364d93b4d32SBaptiste Daroussin int
365263660c0SAlfonso Siciliano bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
366d93b4d32SBaptiste Daroussin     int cols, struct bsddialog_progviewconf *pvconf, unsigned int nminibar,
367d93b4d32SBaptiste Daroussin     struct bsddialog_fileminibar *minibar)
368d93b4d32SBaptiste Daroussin {
369d93b4d32SBaptiste Daroussin 	bool update;
370b319d934SAlfonso S. Siciliano 	int perc, retval, *minipercs;
371263660c0SAlfonso Siciliano 	unsigned int i, mainperc, totaltodo;
372d93b4d32SBaptiste Daroussin 	float readforsec;
373263660c0SAlfonso Siciliano 	const char **minilabels;
374263660c0SAlfonso Siciliano 	time_t tstart, told, tnew, refresh;
375d93b4d32SBaptiste Daroussin 
376d93b4d32SBaptiste Daroussin 	if ((minilabels = calloc(nminibar, sizeof(char*))) == NULL)
377263660c0SAlfonso Siciliano 		RETURN_ERROR("Cannot allocate memory for minilabels");
378d93b4d32SBaptiste Daroussin 	if ((minipercs = calloc(nminibar, sizeof(int))) == NULL)
379263660c0SAlfonso Siciliano 		RETURN_ERROR("Cannot allocate memory for minipercs");
380d93b4d32SBaptiste Daroussin 
381d93b4d32SBaptiste Daroussin 	totaltodo = 0;
382d93b4d32SBaptiste Daroussin 	for (i = 0; i < nminibar; i++) {
383d93b4d32SBaptiste Daroussin 		totaltodo += minibar[i].size;
384d93b4d32SBaptiste Daroussin 		minilabels[i] = minibar[i].label;
385263660c0SAlfonso Siciliano 		minipercs[i] = minibar[i].status;
386d93b4d32SBaptiste Daroussin 	}
387d93b4d32SBaptiste Daroussin 
388d93b4d32SBaptiste Daroussin 	refresh = pvconf->refresh == 0 ? 0 : pvconf->refresh - 1;
389b319d934SAlfonso S. Siciliano 	retval = BSDDIALOG_OK;
390d93b4d32SBaptiste Daroussin 	i = 0;
391d93b4d32SBaptiste Daroussin 	update = true;
392d93b4d32SBaptiste Daroussin 	time(&told);
393d93b4d32SBaptiste Daroussin 	tstart = told;
394d93b4d32SBaptiste Daroussin 	while (!(bsddialog_interruptprogview || bsddialog_abortprogview)) {
395d93b4d32SBaptiste Daroussin 		if (bsddialog_total_progview == 0 || totaltodo == 0)
396d93b4d32SBaptiste Daroussin 			mainperc = 0;
397d93b4d32SBaptiste Daroussin 		else
398d93b4d32SBaptiste Daroussin 			mainperc = (bsddialog_total_progview * 100) / totaltodo;
399d93b4d32SBaptiste Daroussin 
400d93b4d32SBaptiste Daroussin 		time(&tnew);
401d93b4d32SBaptiste Daroussin 		if (update || tnew > told + refresh) {
402b319d934SAlfonso S. Siciliano 			retval = do_mixedgauge(conf, text, rows, cols, mainperc,
403d93b4d32SBaptiste Daroussin 			    nminibar, minilabels, minipercs, true);
404b319d934SAlfonso S. Siciliano 			if (retval == BSDDIALOG_ERROR)
405263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
406d93b4d32SBaptiste Daroussin 
407263660c0SAlfonso Siciliano 			move(SCREENLINES - 1, 2);
408d93b4d32SBaptiste Daroussin 			clrtoeol();
409263660c0SAlfonso Siciliano 			readforsec = ((tnew - tstart) == 0) ? 0 :
410263660c0SAlfonso Siciliano 			    bsddialog_total_progview / (float)(tnew - tstart);
411d93b4d32SBaptiste Daroussin 			printw(pvconf->fmtbottomstr, bsddialog_total_progview,
412d93b4d32SBaptiste Daroussin 			    readforsec);
413d93b4d32SBaptiste Daroussin 			refresh();
414d93b4d32SBaptiste Daroussin 
415d93b4d32SBaptiste Daroussin 			time(&told);
416d93b4d32SBaptiste Daroussin 			update = false;
417d93b4d32SBaptiste Daroussin 		}
418d93b4d32SBaptiste Daroussin 
419d93b4d32SBaptiste Daroussin 		if (i >= nminibar)
420d93b4d32SBaptiste Daroussin 			break;
421263660c0SAlfonso Siciliano 		if (minibar[i].status == BSDDIALOG_MG_FAILED)
422d93b4d32SBaptiste Daroussin 			break;
423d93b4d32SBaptiste Daroussin 
424d93b4d32SBaptiste Daroussin 		perc = pvconf->callback(&minibar[i]);
425d93b4d32SBaptiste Daroussin 
426263660c0SAlfonso Siciliano 		if (minibar[i].status == BSDDIALOG_MG_DONE) { /*||perc >= 100)*/
427263660c0SAlfonso Siciliano 			minipercs[i] = BSDDIALOG_MG_DONE;
428d93b4d32SBaptiste Daroussin 			update = true;
429d93b4d32SBaptiste Daroussin 			i++;
43061ba55bcSBaptiste Daroussin 		} else if (minibar[i].status == BSDDIALOG_MG_FAILED ||
43161ba55bcSBaptiste Daroussin 		    perc < 0) {
432263660c0SAlfonso Siciliano 			minipercs[i] = BSDDIALOG_MG_FAILED;
433d93b4d32SBaptiste Daroussin 			update = true;
434263660c0SAlfonso Siciliano 		} else /* perc >= 0 */
435263660c0SAlfonso Siciliano 			minipercs[i] = perc;
436d93b4d32SBaptiste Daroussin 	}
437d93b4d32SBaptiste Daroussin 
438d93b4d32SBaptiste Daroussin 	free(minilabels);
439d93b4d32SBaptiste Daroussin 	free(minipercs);
440b319d934SAlfonso S. Siciliano 	return (retval);
441d93b4d32SBaptiste Daroussin }
442d93b4d32SBaptiste Daroussin 
44361ba55bcSBaptiste Daroussin static int rangebox_redraw(struct dialog *d, struct bar *b, int *bigchange)
44461ba55bcSBaptiste Daroussin {
44561ba55bcSBaptiste Daroussin 	if (d->built) {
44661ba55bcSBaptiste Daroussin 		hide_dialog(d);
44761ba55bcSBaptiste Daroussin 		refresh(); /* Important for decreasing screen */
44861ba55bcSBaptiste Daroussin 	}
44961ba55bcSBaptiste Daroussin 	if (dialog_size_position(d, HBOX, MIN_WBOX, NULL) != 0)
45061ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
45161ba55bcSBaptiste Daroussin 	if (draw_dialog(d) != 0)
45261ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
45361ba55bcSBaptiste Daroussin 	if (d->built)
45461ba55bcSBaptiste Daroussin 		refresh(); /* Important to fix grey lines expanding screen */
45561ba55bcSBaptiste Daroussin 	TEXTPAD(d, HBOX + HBUTTONS);
45661ba55bcSBaptiste Daroussin 
45761ba55bcSBaptiste Daroussin 	b->w = WBAR(d);
45861ba55bcSBaptiste Daroussin 	*bigchange = MAX(1, b->w  / 10);
45961ba55bcSBaptiste Daroussin 	update_barbox(d, b, true);
46061ba55bcSBaptiste Daroussin 	b->toupdate = true;
46161ba55bcSBaptiste Daroussin 
46261ba55bcSBaptiste Daroussin 	return (0);
46361ba55bcSBaptiste Daroussin }
46461ba55bcSBaptiste Daroussin 
465d93b4d32SBaptiste Daroussin int
466263660c0SAlfonso Siciliano bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
467263660c0SAlfonso Siciliano     int cols, int min, int max, int *value)
468c76f0793SBaptiste Daroussin {
46961ba55bcSBaptiste Daroussin 	bool loop;
47061ba55bcSBaptiste Daroussin 	int currvalue, retval, bigchange, positions;
471b319d934SAlfonso S. Siciliano 	wint_t input;
47261ba55bcSBaptiste Daroussin 	struct bar b;
47361ba55bcSBaptiste Daroussin 	struct dialog d;
474c76f0793SBaptiste Daroussin 
47561ba55bcSBaptiste Daroussin 	CHECK_PTR(value);
476f499134dSBaptiste Daroussin 	if (min >= max)
47761ba55bcSBaptiste Daroussin 		RETURN_FMTERROR("min (%d) >= max (%d)", min, max);
47861ba55bcSBaptiste Daroussin 	if (*value < min)
47961ba55bcSBaptiste Daroussin 		RETURN_FMTERROR("value (%d) < min (%d)", *value, min);
48061ba55bcSBaptiste Daroussin 	if (*value > max)
48161ba55bcSBaptiste Daroussin 		RETURN_FMTERROR("value (%d) > max (%d)", *value, max);
482f499134dSBaptiste Daroussin 
483f499134dSBaptiste Daroussin 	currvalue = *value;
484f499134dSBaptiste Daroussin 	positions = max - min + 1;
485c76f0793SBaptiste Daroussin 
48661ba55bcSBaptiste Daroussin 	if (prepare_dialog(conf, text, rows, cols, &d) != 0)
487263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
48861ba55bcSBaptiste Daroussin 	set_buttons(&d, true, OK_LABEL, CANCEL_LABEL);
48961ba55bcSBaptiste Daroussin 	if ((b.win = newwin(1, 1, 1, 1)) == NULL)
49061ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot build WINDOW bar");
49161ba55bcSBaptiste Daroussin 	b.y = b.x = 1;
49261ba55bcSBaptiste Daroussin 	b.fmt = "%d";
49361ba55bcSBaptiste Daroussin 	if (rangebox_redraw(&d, &b, &bigchange) != 0)
494263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
495c76f0793SBaptiste Daroussin 
49661ba55bcSBaptiste Daroussin 	loop = true;
497c76f0793SBaptiste Daroussin 	while (loop) {
49861ba55bcSBaptiste Daroussin 		if (b.toupdate) {
49961ba55bcSBaptiste Daroussin 			b.perc = ((float)(currvalue - min)*100) / (positions-1);
50061ba55bcSBaptiste Daroussin 			b.label = currvalue;
50161ba55bcSBaptiste Daroussin 			draw_bar(&b);
502f499134dSBaptiste Daroussin 		}
50361ba55bcSBaptiste Daroussin 		doupdate();
504b319d934SAlfonso S. Siciliano 		if (get_wch(&input) == ERR)
505b319d934SAlfonso S. Siciliano 			continue;
506c76f0793SBaptiste Daroussin 		switch(input) {
507f499134dSBaptiste Daroussin 		case KEY_ENTER:
508f499134dSBaptiste Daroussin 		case 10: /* Enter */
50961ba55bcSBaptiste Daroussin 			retval = BUTTONVALUE(d.bs);
510c76f0793SBaptiste Daroussin 			loop = false;
511c76f0793SBaptiste Daroussin 			break;
512c76f0793SBaptiste Daroussin 		case 27: /* Esc */
513263660c0SAlfonso Siciliano 			if (conf->key.enable_esc) {
514b319d934SAlfonso S. Siciliano 				retval = BSDDIALOG_ESC;
515c76f0793SBaptiste Daroussin 				loop = false;
516263660c0SAlfonso Siciliano 			}
517c76f0793SBaptiste Daroussin 			break;
518f499134dSBaptiste Daroussin 		case '\t': /* TAB */
519*a6d8be45SAlfonso S. Siciliano 		case KEY_CTRL('n'):
52061ba55bcSBaptiste Daroussin 		case KEY_RIGHT:
52161ba55bcSBaptiste Daroussin 			d.bs.curr = (d.bs.curr + 1) % d.bs.nbuttons;
52261ba55bcSBaptiste Daroussin 			DRAW_BUTTONS(d);
523c76f0793SBaptiste Daroussin 			break;
524*a6d8be45SAlfonso S. Siciliano 		case KEY_CTRL('p'):
525c76f0793SBaptiste Daroussin 		case KEY_LEFT:
52661ba55bcSBaptiste Daroussin 			d.bs.curr--;
52761ba55bcSBaptiste Daroussin 			if (d.bs.curr < 0)
52861ba55bcSBaptiste Daroussin 				 d.bs.curr = d.bs.nbuttons - 1;
52961ba55bcSBaptiste Daroussin 			DRAW_BUTTONS(d);
530c76f0793SBaptiste Daroussin 			break;
531f499134dSBaptiste Daroussin 		case KEY_HOME:
532f499134dSBaptiste Daroussin 			currvalue = max;
53361ba55bcSBaptiste Daroussin 			b.toupdate = true;
534f499134dSBaptiste Daroussin 			break;
535f499134dSBaptiste Daroussin 		case KEY_END:
536f499134dSBaptiste Daroussin 			currvalue = min;
53761ba55bcSBaptiste Daroussin 			b.toupdate = true;
538f499134dSBaptiste Daroussin 			break;
539f499134dSBaptiste Daroussin 		case KEY_NPAGE:
540f499134dSBaptiste Daroussin 			currvalue -= bigchange;
541f499134dSBaptiste Daroussin 			if (currvalue < min)
542f499134dSBaptiste Daroussin 				currvalue = min;
54361ba55bcSBaptiste Daroussin 			b.toupdate = true;
544f499134dSBaptiste Daroussin 			break;
545f499134dSBaptiste Daroussin 		case KEY_PPAGE:
546f499134dSBaptiste Daroussin 			currvalue += bigchange;
547f499134dSBaptiste Daroussin 			if (currvalue > max)
548f499134dSBaptiste Daroussin 				currvalue = max;
54961ba55bcSBaptiste Daroussin 			b.toupdate = true;
550f499134dSBaptiste Daroussin 			break;
551*a6d8be45SAlfonso S. Siciliano 		case '-':
552c76f0793SBaptiste Daroussin 		case KEY_UP:
553*a6d8be45SAlfonso S. Siciliano 			if (currvalue > min) {
554*a6d8be45SAlfonso S. Siciliano 				currvalue--;
55561ba55bcSBaptiste Daroussin 				b.toupdate = true;
556c76f0793SBaptiste Daroussin 			}
557c76f0793SBaptiste Daroussin 			break;
558*a6d8be45SAlfonso S. Siciliano 		case '+':
559c76f0793SBaptiste Daroussin 		case KEY_DOWN:
560*a6d8be45SAlfonso S. Siciliano 			if (currvalue < max) {
561*a6d8be45SAlfonso S. Siciliano 				currvalue++;
56261ba55bcSBaptiste Daroussin 				b.toupdate = true;
563c76f0793SBaptiste Daroussin 			}
564c76f0793SBaptiste Daroussin 			break;
565f499134dSBaptiste Daroussin 		case KEY_F(1):
566bce40c02SAlfonso S. Siciliano 			if (conf->key.f1_file == NULL &&
567bce40c02SAlfonso S. Siciliano 			    conf->key.f1_message == NULL)
568f499134dSBaptiste Daroussin 				break;
56961ba55bcSBaptiste Daroussin 			if (f1help_dialog(conf) != 0)
570263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
57161ba55bcSBaptiste Daroussin 			if (rangebox_redraw(&d, &b, &bigchange) != 0)
57261ba55bcSBaptiste Daroussin 				return (BSDDIALOG_ERROR);
57361ba55bcSBaptiste Daroussin 			break;
574*a6d8be45SAlfonso S. Siciliano 		case KEY_CTRL('l'):
575f499134dSBaptiste Daroussin 		case KEY_RESIZE:
57661ba55bcSBaptiste Daroussin 			if (rangebox_redraw(&d, &b, &bigchange) != 0)
577263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
578f499134dSBaptiste Daroussin 			break;
579f499134dSBaptiste Daroussin 		default:
58061ba55bcSBaptiste Daroussin 			if (shortcut_buttons(input, &d.bs)) {
58161ba55bcSBaptiste Daroussin 				DRAW_BUTTONS(d);
58261ba55bcSBaptiste Daroussin 				doupdate();
58361ba55bcSBaptiste Daroussin 				retval = BUTTONVALUE(d.bs);
584f499134dSBaptiste Daroussin 				loop = false;
585f499134dSBaptiste Daroussin 			}
586c76f0793SBaptiste Daroussin 		}
587c76f0793SBaptiste Daroussin 	}
588c76f0793SBaptiste Daroussin 
58961ba55bcSBaptiste Daroussin 	*value = currvalue;
59061ba55bcSBaptiste Daroussin 
59161ba55bcSBaptiste Daroussin 	delwin(b.win);
59261ba55bcSBaptiste Daroussin 	end_dialog(&d);
593c76f0793SBaptiste Daroussin 
594b319d934SAlfonso S. Siciliano 	return (retval);
595c76f0793SBaptiste Daroussin }
596c76f0793SBaptiste Daroussin 
59761ba55bcSBaptiste Daroussin static int pause_redraw(struct dialog *d, struct bar *b)
59861ba55bcSBaptiste Daroussin {
59961ba55bcSBaptiste Daroussin 	if (d->built) {
60061ba55bcSBaptiste Daroussin 		hide_dialog(d);
60161ba55bcSBaptiste Daroussin 		refresh(); /* Important for decreasing screen */
60261ba55bcSBaptiste Daroussin 	}
60361ba55bcSBaptiste Daroussin 	if (dialog_size_position(d, HBOX, MIN_WBOX, NULL) != 0)
60461ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
60561ba55bcSBaptiste Daroussin 	if (draw_dialog(d) != 0)
60661ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
60761ba55bcSBaptiste Daroussin 	if (d->built)
60861ba55bcSBaptiste Daroussin 		refresh(); /* Important to fix grey lines expanding screen */
60961ba55bcSBaptiste Daroussin 	TEXTPAD(d, HBOX + HBUTTONS);
61061ba55bcSBaptiste Daroussin 
61161ba55bcSBaptiste Daroussin 	b->w = WBAR(d);
61261ba55bcSBaptiste Daroussin 	update_barbox(d, b, true);
61361ba55bcSBaptiste Daroussin 	b->toupdate = true;
61461ba55bcSBaptiste Daroussin 
61561ba55bcSBaptiste Daroussin 	return (0);
61661ba55bcSBaptiste Daroussin }
61761ba55bcSBaptiste Daroussin 
618f499134dSBaptiste Daroussin int
619263660c0SAlfonso Siciliano bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
62061ba55bcSBaptiste Daroussin     int cols, unsigned int *seconds)
621c76f0793SBaptiste Daroussin {
62261ba55bcSBaptiste Daroussin 	bool loop;
62361ba55bcSBaptiste Daroussin 	int retval, tout;
624b319d934SAlfonso S. Siciliano 	wint_t input;
62561ba55bcSBaptiste Daroussin 	struct bar b;
62661ba55bcSBaptiste Daroussin 	struct dialog d;
627c76f0793SBaptiste Daroussin 
62861ba55bcSBaptiste Daroussin 	CHECK_PTR(seconds);
62961ba55bcSBaptiste Daroussin 	if (prepare_dialog(conf, text, rows, cols, &d) != 0)
630263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
63161ba55bcSBaptiste Daroussin 	set_buttons(&d, true, OK_LABEL, CANCEL_LABEL);
63261ba55bcSBaptiste Daroussin 	if ((b.win = newwin(1, 1, 1, 1)) == NULL)
63361ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot build WINDOW bar");
63461ba55bcSBaptiste Daroussin 	b.y = b.x = 1;
63561ba55bcSBaptiste Daroussin 	b.fmt = "%d";
63661ba55bcSBaptiste Daroussin 	if (pause_redraw(&d, &b) != 0)
637263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
638f499134dSBaptiste Daroussin 
63961ba55bcSBaptiste Daroussin 	tout = *seconds;
640c76f0793SBaptiste Daroussin 	nodelay(stdscr, TRUE);
641c76f0793SBaptiste Daroussin 	timeout(1000);
64261ba55bcSBaptiste Daroussin 	loop = true;
643c76f0793SBaptiste Daroussin 	while (loop) {
64461ba55bcSBaptiste Daroussin 		if (b.toupdate) {
64561ba55bcSBaptiste Daroussin 			b.perc = (float)tout * 100 / *seconds;
64661ba55bcSBaptiste Daroussin 			b.label = tout;
64761ba55bcSBaptiste Daroussin 			draw_bar(&b);
648c76f0793SBaptiste Daroussin 		}
64961ba55bcSBaptiste Daroussin 		doupdate();
650b319d934SAlfonso S. Siciliano 		if (get_wch(&input) == ERR) { /* timeout */
651f499134dSBaptiste Daroussin 			tout--;
652f499134dSBaptiste Daroussin 			if (tout < 0) {
653b319d934SAlfonso S. Siciliano 				retval = BSDDIALOG_TIMEOUT;
654c76f0793SBaptiste Daroussin 				break;
655c76f0793SBaptiste Daroussin 			}
656c76f0793SBaptiste Daroussin 			else {
65761ba55bcSBaptiste Daroussin 				b.toupdate = true;
658c76f0793SBaptiste Daroussin 				continue;
659c76f0793SBaptiste Daroussin 			}
660c76f0793SBaptiste Daroussin 		}
661c76f0793SBaptiste Daroussin 		switch(input) {
662f499134dSBaptiste Daroussin 		case KEY_ENTER:
663f499134dSBaptiste Daroussin 		case 10: /* Enter */
66461ba55bcSBaptiste Daroussin 			retval = BUTTONVALUE(d.bs);
665c76f0793SBaptiste Daroussin 			loop = false;
666c76f0793SBaptiste Daroussin 			break;
667c76f0793SBaptiste Daroussin 		case 27: /* Esc */
668263660c0SAlfonso Siciliano 			if (conf->key.enable_esc) {
669b319d934SAlfonso S. Siciliano 				retval = BSDDIALOG_ESC;
670c76f0793SBaptiste Daroussin 				loop = false;
671263660c0SAlfonso Siciliano 			}
672c76f0793SBaptiste Daroussin 			break;
673f499134dSBaptiste Daroussin 		case '\t': /* TAB */
67461ba55bcSBaptiste Daroussin 		case KEY_RIGHT:
67561ba55bcSBaptiste Daroussin 			d.bs.curr = (d.bs.curr + 1) % d.bs.nbuttons;
67661ba55bcSBaptiste Daroussin 			DRAW_BUTTONS(d);
677c76f0793SBaptiste Daroussin 			break;
678c76f0793SBaptiste Daroussin 		case KEY_LEFT:
67961ba55bcSBaptiste Daroussin 			d.bs.curr--;
68061ba55bcSBaptiste Daroussin 			if (d.bs.curr < 0)
68161ba55bcSBaptiste Daroussin 				 d.bs.curr = d.bs.nbuttons - 1;
68261ba55bcSBaptiste Daroussin 			DRAW_BUTTONS(d);
683c76f0793SBaptiste Daroussin 			break;
684f499134dSBaptiste Daroussin 		case KEY_F(1):
685bce40c02SAlfonso S. Siciliano 			if (conf->key.f1_file == NULL &&
686bce40c02SAlfonso S. Siciliano 			    conf->key.f1_message == NULL)
687f499134dSBaptiste Daroussin 				break;
68861ba55bcSBaptiste Daroussin 			if (f1help_dialog(conf) != 0)
689263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
69061ba55bcSBaptiste Daroussin 			if (pause_redraw(&d, &b) != 0)
69161ba55bcSBaptiste Daroussin 				return (BSDDIALOG_ERROR);
69261ba55bcSBaptiste Daroussin 			break;
693*a6d8be45SAlfonso S. Siciliano 		case KEY_CTRL('l'):
694f499134dSBaptiste Daroussin 		case KEY_RESIZE:
69561ba55bcSBaptiste Daroussin 			if (pause_redraw(&d, &b) != 0)
696263660c0SAlfonso Siciliano 				return (BSDDIALOG_ERROR);
697f499134dSBaptiste Daroussin 			break;
698f499134dSBaptiste Daroussin 		default:
69961ba55bcSBaptiste Daroussin 			if (shortcut_buttons(input, &d.bs)) {
70061ba55bcSBaptiste Daroussin 				DRAW_BUTTONS(d);
70161ba55bcSBaptiste Daroussin 				doupdate();
70261ba55bcSBaptiste Daroussin 				retval = BUTTONVALUE(d.bs);
703f499134dSBaptiste Daroussin 				loop = false;
704f499134dSBaptiste Daroussin 			}
705c76f0793SBaptiste Daroussin 		}
706c76f0793SBaptiste Daroussin 	}
707c76f0793SBaptiste Daroussin 	nodelay(stdscr, FALSE);
708c76f0793SBaptiste Daroussin 
70961ba55bcSBaptiste Daroussin 	*seconds = MAX(tout, 0);
71061ba55bcSBaptiste Daroussin 
71161ba55bcSBaptiste Daroussin 	delwin(b.win);
71261ba55bcSBaptiste Daroussin 	end_dialog(&d);
713c76f0793SBaptiste Daroussin 
714b319d934SAlfonso S. Siciliano 	return (retval);
715c76f0793SBaptiste Daroussin }
716