xref: /freebsd-src/contrib/bsddialog/lib/barbox.c (revision d93b4d32034df7cd70e80b496e8fe8c1bc57c629)
1c76f0793SBaptiste Daroussin /*-
2c76f0793SBaptiste Daroussin  * SPDX-License-Identifier: BSD-2-Clause
3c76f0793SBaptiste Daroussin  *
4c76f0793SBaptiste Daroussin  * Copyright (c) 2021 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>
31c76f0793SBaptiste Daroussin #ifdef PORTNCURSES
328c4f4028SBaptiste Daroussin #include <ncurses/ncurses.h>
33c76f0793SBaptiste Daroussin #else
348c4f4028SBaptiste Daroussin #include <ncurses.h>
35c76f0793SBaptiste Daroussin #endif
36*d93b4d32SBaptiste Daroussin #include <stdlib.h>
37*d93b4d32SBaptiste Daroussin #include <string.h>
38*d93b4d32SBaptiste Daroussin #include <time.h>
39c76f0793SBaptiste Daroussin 
40c76f0793SBaptiste Daroussin #include "bsddialog.h"
41*d93b4d32SBaptiste Daroussin #include "bsddialog_progressview.h"
42c76f0793SBaptiste Daroussin #include "lib_util.h"
43c76f0793SBaptiste Daroussin #include "bsddialog_theme.h"
44c76f0793SBaptiste Daroussin 
45f499134dSBaptiste Daroussin #define BARMARGIN	3
46f499134dSBaptiste Daroussin #define MINBARWIDTH	10
47f499134dSBaptiste Daroussin #define MINWIDTH	(VBORDERS + MINBARWIDTH + BARMARGIN * 2)
48f499134dSBaptiste Daroussin #define MINHEIGHT	7 /* without text */
49f499134dSBaptiste Daroussin 
50*d93b4d32SBaptiste Daroussin /* "Bar": gauge - mixedgauge - rangebox - pause - progressview */
51*d93b4d32SBaptiste Daroussin 
52*d93b4d32SBaptiste Daroussin bool bsddialog_interruptprogview;
53*d93b4d32SBaptiste Daroussin bool bsddialog_abortprogview;
54*d93b4d32SBaptiste Daroussin int  bsddialog_total_progview;
55c76f0793SBaptiste Daroussin 
56c76f0793SBaptiste Daroussin extern struct bsddialog_theme t;
57c76f0793SBaptiste Daroussin 
58c76f0793SBaptiste Daroussin static void
59f499134dSBaptiste Daroussin draw_perc_bar(WINDOW *win, int y, int x, int size, int perc, bool withlabel,
60f499134dSBaptiste Daroussin     int label)
61c76f0793SBaptiste Daroussin {
62c76f0793SBaptiste Daroussin 	char labelstr[128];
63c76f0793SBaptiste Daroussin 	int i, blue_x, color;
64c76f0793SBaptiste Daroussin 
65c76f0793SBaptiste Daroussin 	blue_x = (int)((perc*(size))/100);
66c76f0793SBaptiste Daroussin 
67c76f0793SBaptiste Daroussin 	wmove(win, y, x);
68c76f0793SBaptiste Daroussin 	for (i = 0; i < size; i++) {
69f499134dSBaptiste Daroussin 		color = (i <= blue_x) ? t.bar.f_color : t.bar.color;
70c76f0793SBaptiste Daroussin 		wattron(win, color);
71c76f0793SBaptiste Daroussin 		waddch(win, ' ');
72c76f0793SBaptiste Daroussin 		wattroff(win, color);
73c76f0793SBaptiste Daroussin 	}
74c76f0793SBaptiste Daroussin 
75c76f0793SBaptiste Daroussin 	if (withlabel)
76c76f0793SBaptiste Daroussin 		sprintf(labelstr, "%d", label);
77c76f0793SBaptiste Daroussin 	else
78c76f0793SBaptiste Daroussin 		sprintf(labelstr, "%3d%%", perc);
79c76f0793SBaptiste Daroussin 	wmove(win, y, x + size/2 - 2);
80c76f0793SBaptiste Daroussin 	for (i=0; i < (int) strlen(labelstr); i++) {
81f499134dSBaptiste Daroussin 		color = (blue_x + 1 <= size/2 - (int)strlen(labelstr)/2 + i ) ?
82f499134dSBaptiste Daroussin 		    t.bar.color : t.bar.f_color;
83c76f0793SBaptiste Daroussin 		wattron(win, color);
84c76f0793SBaptiste Daroussin 		waddch(win, labelstr[i]);
85c76f0793SBaptiste Daroussin 		wattroff(win, color);
86c76f0793SBaptiste Daroussin 	}
87c76f0793SBaptiste Daroussin }
88c76f0793SBaptiste Daroussin 
89f499134dSBaptiste Daroussin static int
90f499134dSBaptiste Daroussin bar_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
91f499134dSBaptiste Daroussin     char *text, struct buttons *bs)
92c76f0793SBaptiste Daroussin {
93f499134dSBaptiste Daroussin 	int maxword, maxline, nlines, buttonswidth;
94c76f0793SBaptiste Daroussin 
95f499134dSBaptiste Daroussin 	if (get_text_properties(conf, text, &maxword, &maxline, &nlines) != 0)
96f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
97c76f0793SBaptiste Daroussin 
98f499134dSBaptiste Daroussin 	buttonswidth = 0;
99f499134dSBaptiste Daroussin 	if (bs != NULL) { /* gauge has not buttons */
100f499134dSBaptiste Daroussin 		buttonswidth= bs->nbuttons * bs->sizebutton;
101f499134dSBaptiste Daroussin 		if (bs->nbuttons > 0)
102f499134dSBaptiste Daroussin 			buttonswidth += (bs->nbuttons-1) * t.button.space;
103f499134dSBaptiste Daroussin 	}
104c76f0793SBaptiste Daroussin 
105f499134dSBaptiste Daroussin 	if (cols == BSDDIALOG_AUTOSIZE) {
106f499134dSBaptiste Daroussin 		*w = VBORDERS;
107f499134dSBaptiste Daroussin 		/* buttons size */
108f499134dSBaptiste Daroussin 		*w += buttonswidth;
109f499134dSBaptiste Daroussin 		/* bar size */
110f499134dSBaptiste Daroussin 		*w = MAX(*w, MINWIDTH);
111f499134dSBaptiste Daroussin 		/* text size*/
112f499134dSBaptiste Daroussin 		*w = MAX((int)(maxline + VBORDERS + t.text.hmargin * 2), *w);
1138c4f4028SBaptiste Daroussin 		/* conf.auto_minwidth */
1148c4f4028SBaptiste Daroussin 		*w = MAX(*w, (int)conf->auto_minwidth);
115f499134dSBaptiste Daroussin 		/* avoid terminal overflow */
116f499134dSBaptiste Daroussin 		*w = MIN(*w, widget_max_width(conf));
117f499134dSBaptiste Daroussin 	}
118c76f0793SBaptiste Daroussin 
119f499134dSBaptiste Daroussin 	if (rows == BSDDIALOG_AUTOSIZE) {
120f499134dSBaptiste Daroussin 		*h = MINHEIGHT;
121f499134dSBaptiste Daroussin 		if (maxword > 0)
122f499134dSBaptiste Daroussin 			*h += 1;
1238c4f4028SBaptiste Daroussin 		/* conf.auto_minheight */
1248c4f4028SBaptiste Daroussin 		*h = MAX(*h, (int)conf->auto_minheight);
125f499134dSBaptiste Daroussin 		/* avoid terminal overflow */
126f499134dSBaptiste Daroussin 		*h = MIN(*h, widget_max_height(conf));
127f499134dSBaptiste Daroussin 	}
128f499134dSBaptiste Daroussin 
129f499134dSBaptiste Daroussin 	return (0);
130f499134dSBaptiste Daroussin }
131f499134dSBaptiste Daroussin 
132f499134dSBaptiste Daroussin static int
133f499134dSBaptiste Daroussin bar_checksize(char *text, int rows, int cols, struct buttons *bs)
134f499134dSBaptiste Daroussin {
135f499134dSBaptiste Daroussin 	int minheight, minwidth;
136f499134dSBaptiste Daroussin 
137f499134dSBaptiste Daroussin 	minwidth = 0;
138f499134dSBaptiste Daroussin 	if (bs != NULL) { /* gauge has not buttons */
139f499134dSBaptiste Daroussin 		minwidth = bs->nbuttons * bs->sizebutton;
140f499134dSBaptiste Daroussin 		if (bs->nbuttons > 0)
141f499134dSBaptiste Daroussin 			minwidth += (bs->nbuttons-1) * t.button.space;
142f499134dSBaptiste Daroussin 	}
143f499134dSBaptiste Daroussin 	minwidth = MAX(minwidth + VBORDERS, MINBARWIDTH);
144f499134dSBaptiste Daroussin 
145f499134dSBaptiste Daroussin 	if (cols< minwidth)
146f499134dSBaptiste Daroussin 		RETURN_ERROR("Few cols for this widget");
147f499134dSBaptiste Daroussin 
148f499134dSBaptiste Daroussin 	minheight = MINHEIGHT + ((text != NULL && strlen(text) > 0) ? 1 : 0);
149f499134dSBaptiste Daroussin 	if (rows < minheight)
150f499134dSBaptiste Daroussin 		RETURN_ERROR("Few rows for this mixedgauge");
151f499134dSBaptiste Daroussin 
152f499134dSBaptiste Daroussin 	return 0;
153f499134dSBaptiste Daroussin }
154f499134dSBaptiste Daroussin 
155f499134dSBaptiste Daroussin int
156f499134dSBaptiste Daroussin bsddialog_gauge(struct bsddialog_conf *conf, char* text, int rows, int cols,
157f499134dSBaptiste Daroussin     unsigned int perc)
158f499134dSBaptiste Daroussin {
159f499134dSBaptiste Daroussin 	WINDOW *widget, *textpad, *bar, *shadow;
160f499134dSBaptiste Daroussin 	char input[2048], ntext[2048], *pntext;
161f499134dSBaptiste Daroussin 	int y, x, h, w, htextpad;
162f499134dSBaptiste Daroussin 	bool mainloop;
163f499134dSBaptiste Daroussin 
164f499134dSBaptiste Daroussin 	if (set_widget_size(conf, rows, cols, &h, &w) != 0)
165f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
166f499134dSBaptiste Daroussin 	if (bar_autosize(conf, rows, cols, &h, &w, text, NULL) != 0)
167f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
168f499134dSBaptiste Daroussin 	if (bar_checksize(text, h, w, NULL) != 0)
169f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
170f499134dSBaptiste Daroussin 	if (set_widget_position(conf, &y, &x, h, w) != 0)
171f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
172f499134dSBaptiste Daroussin 
173f499134dSBaptiste Daroussin 	if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
174f499134dSBaptiste Daroussin 	    &textpad, &htextpad, text, false) != 0)
175f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
176f499134dSBaptiste Daroussin 
177f499134dSBaptiste Daroussin 	bar = new_boxed_window(conf, y+h-4, x+3, 3, w-6, RAISED);
178f499134dSBaptiste Daroussin 
179f499134dSBaptiste Daroussin 	mainloop = true;
180c76f0793SBaptiste Daroussin 	while (mainloop) {
181c76f0793SBaptiste Daroussin 		wrefresh(widget);
182f499134dSBaptiste Daroussin 		prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-4,
183f499134dSBaptiste Daroussin 		    x+w-1-t.text.hmargin);
184f499134dSBaptiste Daroussin 		draw_perc_bar(bar, 1, 1, w-8, perc, false, -1 /*unused*/);
185c76f0793SBaptiste Daroussin 		wrefresh(bar);
186c76f0793SBaptiste Daroussin 
187c76f0793SBaptiste Daroussin 		while (true) {
188c76f0793SBaptiste Daroussin 			scanf("%s", input);
189c76f0793SBaptiste Daroussin 			if (strcmp(input,"EOF") == 0) {
190c76f0793SBaptiste Daroussin 				mainloop = false;
191c76f0793SBaptiste Daroussin 				break;
192c76f0793SBaptiste Daroussin 			}
193c76f0793SBaptiste Daroussin 			if (strcmp(input,"XXX") == 0)
194c76f0793SBaptiste Daroussin 				break;
195c76f0793SBaptiste Daroussin 		}
196c76f0793SBaptiste Daroussin 		scanf("%d", &perc);
197c76f0793SBaptiste Daroussin 		perc = perc < 0 ? 0 : perc;
198c76f0793SBaptiste Daroussin 		perc = perc > 100 ? 100 : perc;
199f499134dSBaptiste Daroussin 		htextpad = 1;
200f499134dSBaptiste Daroussin 		wclear(textpad);
201f499134dSBaptiste Daroussin 		pntext = &ntext[0];
202f499134dSBaptiste Daroussin 		ntext[0] = '\0';
203c76f0793SBaptiste Daroussin 		while (true) {
204c76f0793SBaptiste Daroussin 			scanf("%s", input);
205c76f0793SBaptiste Daroussin 			if (strcmp(input,"EOF") == 0) {
206c76f0793SBaptiste Daroussin 				mainloop = false;
207c76f0793SBaptiste Daroussin 				break;
208c76f0793SBaptiste Daroussin 			}
209c76f0793SBaptiste Daroussin 			if (strcmp(input,"XXX") == 0)
210c76f0793SBaptiste Daroussin 				break;
211f499134dSBaptiste Daroussin 			pntext[0] = ' ';
212f499134dSBaptiste Daroussin 			pntext++;
213f499134dSBaptiste Daroussin 			strcpy(pntext, input);
214f499134dSBaptiste Daroussin 			pntext += strlen(input);
215c76f0793SBaptiste Daroussin 		}
216f499134dSBaptiste Daroussin 		print_textpad(conf, textpad, &htextpad, w-2-t.text.hmargin*2,
217f499134dSBaptiste Daroussin 		    ntext);
218c76f0793SBaptiste Daroussin 	}
219c76f0793SBaptiste Daroussin 
220c76f0793SBaptiste Daroussin 	delwin(bar);
221f499134dSBaptiste Daroussin 	end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
222c76f0793SBaptiste Daroussin 
2238c4f4028SBaptiste Daroussin 	return BSDDIALOG_OK;
224c76f0793SBaptiste Daroussin }
225c76f0793SBaptiste Daroussin 
226*d93b4d32SBaptiste Daroussin 
227*d93b4d32SBaptiste Daroussin /* Mixedgauge */
228*d93b4d32SBaptiste Daroussin static int
229*d93b4d32SBaptiste Daroussin mixedgauge(struct bsddialog_conf *conf, char* text, int rows, int cols,
230*d93b4d32SBaptiste Daroussin     unsigned int mainperc, unsigned int nminibars, char **minilabels,
231*d93b4d32SBaptiste Daroussin     int *minipercs, bool color)
232c76f0793SBaptiste Daroussin {
233f499134dSBaptiste Daroussin 	WINDOW *widget, *textpad, *bar, *shadow;
234f499134dSBaptiste Daroussin 	int i, output, miniperc, y, x, h, w, max_minbarlen;
235f499134dSBaptiste Daroussin 	int maxword, maxline, nlines, htextpad, ypad;
236*d93b4d32SBaptiste Daroussin 	int colorperc, red, green;
237*d93b4d32SBaptiste Daroussin 	char states[12][14] = {
238*d93b4d32SBaptiste Daroussin 	    "  Succeeded  ", /*  0  */
239*d93b4d32SBaptiste Daroussin 	    "   Failed    ", /*  1  */
240*d93b4d32SBaptiste Daroussin 	    "   Passed    ", /*  2  */
241*d93b4d32SBaptiste Daroussin 	    "  Completed  ", /*  3  */
242*d93b4d32SBaptiste Daroussin 	    "   Checked   ", /*  4  */
243*d93b4d32SBaptiste Daroussin 	    "    Done     ", /*  5  */
244*d93b4d32SBaptiste Daroussin 	    "   Skipped   ", /*  6  */
245*d93b4d32SBaptiste Daroussin 	    " In Progress ", /*  7  */
2468c4f4028SBaptiste Daroussin 	    "(blank)      ", /*  8  */
247*d93b4d32SBaptiste Daroussin 	    "     N/A     ", /*  9  */
248*d93b4d32SBaptiste Daroussin 	    "   Pending   ", /* 10  */
249*d93b4d32SBaptiste Daroussin 	    "   UNKNOWN   ", /* 10+ */
250f499134dSBaptiste Daroussin 	};
251c76f0793SBaptiste Daroussin 
252*d93b4d32SBaptiste Daroussin 	red   = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_RED,  BSDDIALOG_BOLD);
253*d93b4d32SBaptiste Daroussin 	green = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_GREEN,BSDDIALOG_BOLD);
254*d93b4d32SBaptiste Daroussin 
255f499134dSBaptiste Daroussin 	max_minbarlen = 0;
2568c4f4028SBaptiste Daroussin 	for (i=0; i < (int)nminibars; i++)
2578c4f4028SBaptiste Daroussin 		max_minbarlen = MAX(max_minbarlen, (int)strlen(minilabels[i]));
258f499134dSBaptiste Daroussin 	max_minbarlen += 3 + 16 /* seps + [...] or mainbar */;
259f499134dSBaptiste Daroussin 
260f499134dSBaptiste Daroussin 	if (set_widget_size(conf, rows, cols, &h, &w) != 0)
261f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
262f499134dSBaptiste Daroussin 
263f499134dSBaptiste Daroussin 	/* mixedgauge autosize */
264f499134dSBaptiste Daroussin 	if (get_text_properties(conf, text, &maxword, &maxline, &nlines) != 0)
265f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
266f499134dSBaptiste Daroussin 
267f499134dSBaptiste Daroussin 	if (cols == BSDDIALOG_AUTOSIZE) {
268f499134dSBaptiste Daroussin 		w = max_minbarlen + HBORDERS;
269*d93b4d32SBaptiste Daroussin 		w = MAX(w, maxline + 4);
2708c4f4028SBaptiste Daroussin 		w = MAX(w, (int)conf->auto_minwidth);
271f499134dSBaptiste Daroussin 		w = MIN(w, widget_max_width(conf) - 1);
272f499134dSBaptiste Daroussin 	}
273f499134dSBaptiste Daroussin 	if (rows == BSDDIALOG_AUTOSIZE) {
274f499134dSBaptiste Daroussin 		h = 5; /* borders + mainbar */
2758c4f4028SBaptiste Daroussin 		h += nminibars;
276f499134dSBaptiste Daroussin 		h += (strlen(text) > 0 ? 3 : 0);
2778c4f4028SBaptiste Daroussin 		h = MAX(h, (int)conf->auto_minheight);
278f499134dSBaptiste Daroussin 		h = MIN(h, widget_max_height(conf) -1);
279f499134dSBaptiste Daroussin 	}
280f499134dSBaptiste Daroussin 
281f499134dSBaptiste Daroussin 	/* mixedgauge checksize */
282f499134dSBaptiste Daroussin 	if (w < max_minbarlen + 2)
283f499134dSBaptiste Daroussin 		RETURN_ERROR("Few cols for this mixedgauge");
2848c4f4028SBaptiste Daroussin 	if (h < 5 + (int)nminibars + (strlen(text) > 0 ? 1 : 0))
285f499134dSBaptiste Daroussin 		RETURN_ERROR("Few rows for this mixedgauge");
286f499134dSBaptiste Daroussin 
287f499134dSBaptiste Daroussin 	if (set_widget_position(conf, &y, &x, h, w) != 0)
288f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
289f499134dSBaptiste Daroussin 
290f499134dSBaptiste Daroussin 	output = new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w,
291f499134dSBaptiste Daroussin 	    RAISED, &textpad, &htextpad, text, false);
292f499134dSBaptiste Daroussin 	if (output == BSDDIALOG_ERROR)
293f499134dSBaptiste Daroussin 		return output;
294c76f0793SBaptiste Daroussin 
295c76f0793SBaptiste Daroussin 	/* mini bars */
2968c4f4028SBaptiste Daroussin 	for (i=0; i < (int)nminibars; i++) {
2978c4f4028SBaptiste Daroussin 		miniperc = minipercs[i];
298c76f0793SBaptiste Daroussin 		if (miniperc == 8)
299c76f0793SBaptiste Daroussin 			continue;
300*d93b4d32SBaptiste Daroussin 		/* label */
301*d93b4d32SBaptiste Daroussin 		if (color && (miniperc == 7 || miniperc < 0))
302*d93b4d32SBaptiste Daroussin 			wattron(widget, A_BOLD);
3038c4f4028SBaptiste Daroussin 		mvwaddstr(widget, i+1, 2, minilabels[i]);
304*d93b4d32SBaptiste Daroussin 			wattroff(widget, A_BOLD);
305*d93b4d32SBaptiste Daroussin 		/* perc */
3068c4f4028SBaptiste Daroussin 		if (miniperc > 10)
3078c4f4028SBaptiste Daroussin 			mvwaddstr(widget, i+1, w-2-15, states[11]);
308*d93b4d32SBaptiste Daroussin 		else if (miniperc >= 0 && miniperc <= 10) {
309*d93b4d32SBaptiste Daroussin 			mvwaddstr(widget, i+1, w-2-15, "[             ]");
310*d93b4d32SBaptiste Daroussin 			if (color && miniperc == 1) /* Failed */
311*d93b4d32SBaptiste Daroussin 				colorperc = red;
312*d93b4d32SBaptiste Daroussin 			if (color && miniperc == 5) /* Done */
313*d93b4d32SBaptiste Daroussin 				colorperc = green;
314*d93b4d32SBaptiste Daroussin 			if (color && (miniperc == 1 || miniperc == 5))
315*d93b4d32SBaptiste Daroussin 				wattron(widget, colorperc);
316*d93b4d32SBaptiste Daroussin 			mvwaddstr(widget, i+1, 1+w-2-15, states[miniperc]);
317*d93b4d32SBaptiste Daroussin 			if (color && (miniperc == 1 || miniperc == 5))
318*d93b4d32SBaptiste Daroussin 				wattroff(widget, colorperc);
319*d93b4d32SBaptiste Daroussin 		}
3208c4f4028SBaptiste Daroussin 		else { /* miniperc < 0 */
321c76f0793SBaptiste Daroussin 			miniperc = abs(miniperc);
322f499134dSBaptiste Daroussin 			mvwaddstr(widget, i+1, w-2-15, "[             ]");
323f499134dSBaptiste Daroussin 			draw_perc_bar(widget, i+1, 1+w-2-15, 13, miniperc,
324c76f0793SBaptiste Daroussin 			    false, -1 /*unused*/);
325c76f0793SBaptiste Daroussin 		}
326c76f0793SBaptiste Daroussin 	}
327c76f0793SBaptiste Daroussin 
328f499134dSBaptiste Daroussin 	wrefresh(widget);
329f499134dSBaptiste Daroussin 	ypad =  y + h - 5 - htextpad;
3308c4f4028SBaptiste Daroussin 	ypad = ypad < y+(int)nminibars ? y+nminibars : ypad;
331f499134dSBaptiste Daroussin 	prefresh(textpad, 0, 0, ypad, x+2, y+h-4, x+w-2);
332c76f0793SBaptiste Daroussin 
333c76f0793SBaptiste Daroussin 	/* main bar */
334f499134dSBaptiste Daroussin 	bar = new_boxed_window(conf, y+h -4, x+3, 3, w-6, RAISED);
335c76f0793SBaptiste Daroussin 
336f499134dSBaptiste Daroussin 	draw_perc_bar(bar, 1, 1, w-8, mainperc, false, -1 /*unused*/);
337f499134dSBaptiste Daroussin 
338f499134dSBaptiste Daroussin 	wattron(bar, t.bar.color);
339c76f0793SBaptiste Daroussin 	mvwaddstr(bar, 0, 2, "Overall Progress");
340f499134dSBaptiste Daroussin 	wattroff(bar, t.bar.color);
341c76f0793SBaptiste Daroussin 
342c76f0793SBaptiste Daroussin 	wrefresh(bar);
343c76f0793SBaptiste Daroussin 
344f499134dSBaptiste Daroussin 	/* getch(); port ncurses shows nothing */
345c76f0793SBaptiste Daroussin 
346c76f0793SBaptiste Daroussin 	delwin(bar);
347f499134dSBaptiste Daroussin 	end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
348c76f0793SBaptiste Daroussin 
3498c4f4028SBaptiste Daroussin 	return BSDDIALOG_OK;
350c76f0793SBaptiste Daroussin }
351c76f0793SBaptiste Daroussin 
352c76f0793SBaptiste Daroussin int
353*d93b4d32SBaptiste Daroussin bsddialog_mixedgauge(struct bsddialog_conf *conf, char* text, int rows,
354*d93b4d32SBaptiste Daroussin     int cols, unsigned int mainperc, unsigned int nminibars, char **minilabels,
355*d93b4d32SBaptiste Daroussin     int *minipercs)
356*d93b4d32SBaptiste Daroussin {
357*d93b4d32SBaptiste Daroussin 	int output;
358*d93b4d32SBaptiste Daroussin 
359*d93b4d32SBaptiste Daroussin 	output = mixedgauge(conf, text, rows, cols, mainperc, nminibars,
360*d93b4d32SBaptiste Daroussin 	    minilabels, minipercs, false);
361*d93b4d32SBaptiste Daroussin 
362*d93b4d32SBaptiste Daroussin 	return (output);
363*d93b4d32SBaptiste Daroussin }
364*d93b4d32SBaptiste Daroussin 
365*d93b4d32SBaptiste Daroussin int
366*d93b4d32SBaptiste Daroussin bsddialog_progressview (struct bsddialog_conf *conf, char * text, int rows,
367*d93b4d32SBaptiste Daroussin     int cols, struct bsddialog_progviewconf *pvconf, unsigned int nminibar,
368*d93b4d32SBaptiste Daroussin     struct bsddialog_fileminibar *minibar)
369*d93b4d32SBaptiste Daroussin {
370*d93b4d32SBaptiste Daroussin 	int perc, output;
371*d93b4d32SBaptiste Daroussin 	int *minipercs;
372*d93b4d32SBaptiste Daroussin 	unsigned int i;
373*d93b4d32SBaptiste Daroussin 	char **minilabels;
374*d93b4d32SBaptiste Daroussin 	unsigned int mainperc, totaltodo;
375*d93b4d32SBaptiste Daroussin 	time_t tstart, told, tnew, refresh;
376*d93b4d32SBaptiste Daroussin 	bool update;
377*d93b4d32SBaptiste Daroussin 	float readforsec;
378*d93b4d32SBaptiste Daroussin 
379*d93b4d32SBaptiste Daroussin 	if ((minilabels = calloc(nminibar, sizeof(char*))) == NULL)
380*d93b4d32SBaptiste Daroussin 		RETURN_ERROR("Cannot allocate memory for minilabels\n");
381*d93b4d32SBaptiste Daroussin 	if ((minipercs = calloc(nminibar, sizeof(int))) == NULL)
382*d93b4d32SBaptiste Daroussin 		RETURN_ERROR("Cannot allocate memory for minipercs\n");
383*d93b4d32SBaptiste Daroussin 
384*d93b4d32SBaptiste Daroussin 	totaltodo = 0;
385*d93b4d32SBaptiste Daroussin 	for(i=0; i<nminibar; i++) {
386*d93b4d32SBaptiste Daroussin 		totaltodo     += minibar[i].size;
387*d93b4d32SBaptiste Daroussin 		minilabels[i] = minibar[i].label;
388*d93b4d32SBaptiste Daroussin 		minipercs[i]  = 10; /*Pending*/
389*d93b4d32SBaptiste Daroussin 	}
390*d93b4d32SBaptiste Daroussin 
391*d93b4d32SBaptiste Daroussin 	refresh = pvconf->refresh == 0 ? 0 : pvconf->refresh - 1;
392*d93b4d32SBaptiste Daroussin 	output = BSDDIALOG_OK;
393*d93b4d32SBaptiste Daroussin 	i = 0;
394*d93b4d32SBaptiste Daroussin 	update = true;
395*d93b4d32SBaptiste Daroussin 	time(&told);
396*d93b4d32SBaptiste Daroussin 	tstart = told;
397*d93b4d32SBaptiste Daroussin 	while (!(bsddialog_interruptprogview || bsddialog_abortprogview)) {
398*d93b4d32SBaptiste Daroussin 		if (bsddialog_total_progview == 0 || totaltodo == 0)
399*d93b4d32SBaptiste Daroussin 			mainperc = 0;
400*d93b4d32SBaptiste Daroussin 		else
401*d93b4d32SBaptiste Daroussin 			mainperc = (bsddialog_total_progview * 100) / totaltodo;
402*d93b4d32SBaptiste Daroussin 
403*d93b4d32SBaptiste Daroussin 		time(&tnew);
404*d93b4d32SBaptiste Daroussin 		if (update || tnew > told + refresh) {
405*d93b4d32SBaptiste Daroussin 			output = mixedgauge(conf, text, rows, cols, mainperc,
406*d93b4d32SBaptiste Daroussin 			    nminibar, minilabels, minipercs, true);
407*d93b4d32SBaptiste Daroussin 			if (output == BSDDIALOG_ERROR)
408*d93b4d32SBaptiste Daroussin 				return BSDDIALOG_ERROR;
409*d93b4d32SBaptiste Daroussin 
410*d93b4d32SBaptiste Daroussin 			move(LINES-1, 2);
411*d93b4d32SBaptiste Daroussin 			clrtoeol();
412*d93b4d32SBaptiste Daroussin 			readforsec = ((tnew - tstart) == 0) ?
413*d93b4d32SBaptiste Daroussin 			    0 : bsddialog_total_progview / (float)(tnew - tstart);
414*d93b4d32SBaptiste Daroussin 			printw(pvconf->fmtbottomstr, bsddialog_total_progview,
415*d93b4d32SBaptiste Daroussin 			    readforsec);
416*d93b4d32SBaptiste Daroussin 			refresh();
417*d93b4d32SBaptiste Daroussin 
418*d93b4d32SBaptiste Daroussin 			time(&told);
419*d93b4d32SBaptiste Daroussin 			update = false;
420*d93b4d32SBaptiste Daroussin 		}
421*d93b4d32SBaptiste Daroussin 
422*d93b4d32SBaptiste Daroussin 		if (i >= nminibar)
423*d93b4d32SBaptiste Daroussin 			break;
424*d93b4d32SBaptiste Daroussin 		if (minibar[i].status == 1) /* Failed*/
425*d93b4d32SBaptiste Daroussin 			break;
426*d93b4d32SBaptiste Daroussin 
427*d93b4d32SBaptiste Daroussin 		perc = pvconf->callback(&minibar[i]);
428*d93b4d32SBaptiste Daroussin 
429*d93b4d32SBaptiste Daroussin 		if (minibar[i].status == 5) {/* ||prec >= 100) Done */
430*d93b4d32SBaptiste Daroussin 			minipercs[i] = 5;
431*d93b4d32SBaptiste Daroussin 			update = true;
432*d93b4d32SBaptiste Daroussin 			i++;
433*d93b4d32SBaptiste Daroussin 		} else if (minibar[i].status == 1 || perc < 0) { /* Failed */
434*d93b4d32SBaptiste Daroussin 			minipercs[i] = 1;
435*d93b4d32SBaptiste Daroussin 			update = true;
436*d93b4d32SBaptiste Daroussin 		} else if (perc == 0)
437*d93b4d32SBaptiste Daroussin 			minipercs[i] = 7; /* In progress */
438*d93b4d32SBaptiste Daroussin 		else /* perc > 0 */
439*d93b4d32SBaptiste Daroussin 			minipercs[i] = -(perc);
440*d93b4d32SBaptiste Daroussin 	}
441*d93b4d32SBaptiste Daroussin 
442*d93b4d32SBaptiste Daroussin 	free(minilabels);
443*d93b4d32SBaptiste Daroussin 	free(minipercs);
444*d93b4d32SBaptiste Daroussin 	return (output);
445*d93b4d32SBaptiste Daroussin }
446*d93b4d32SBaptiste Daroussin 
447*d93b4d32SBaptiste Daroussin int
448f499134dSBaptiste Daroussin bsddialog_rangebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
449f499134dSBaptiste Daroussin     int min, int max, int *value)
450c76f0793SBaptiste Daroussin {
451f499134dSBaptiste Daroussin 	WINDOW *widget, *textpad, *bar, *shadow;
452f499134dSBaptiste Daroussin 	int i, y, x, h, w, htextpad;
453c76f0793SBaptiste Daroussin 	bool loop, buttupdate, barupdate;
454f499134dSBaptiste Daroussin 	int input, currvalue, output, sizebar, bigchange, positions;
455c76f0793SBaptiste Daroussin 	float perc;
456c76f0793SBaptiste Daroussin 	struct buttons bs;
457c76f0793SBaptiste Daroussin 
458f499134dSBaptiste Daroussin 	if (value == NULL)
459f499134dSBaptiste Daroussin 		RETURN_ERROR("*value cannot be NULL");
460c76f0793SBaptiste Daroussin 
461f499134dSBaptiste Daroussin 	if (min >= max)
462f499134dSBaptiste Daroussin 		RETURN_ERROR("min >= max");
463f499134dSBaptiste Daroussin 
464f499134dSBaptiste Daroussin 	currvalue = *value;
465f499134dSBaptiste Daroussin 	positions = max - min + 1;
466c76f0793SBaptiste Daroussin 
467c76f0793SBaptiste Daroussin 	get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
468c76f0793SBaptiste Daroussin 	    BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
469c76f0793SBaptiste Daroussin 
470f499134dSBaptiste Daroussin 	if (set_widget_size(conf, rows, cols, &h, &w) != 0)
471f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
472f499134dSBaptiste Daroussin 	if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0)
473f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
474f499134dSBaptiste Daroussin 	if (bar_checksize(text, h, w, &bs) != 0)
475f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
476f499134dSBaptiste Daroussin 	if (set_widget_position(conf, &y, &x, h, w) != 0)
477f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
478c76f0793SBaptiste Daroussin 
479f499134dSBaptiste Daroussin 	if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
480f499134dSBaptiste Daroussin 	    &textpad, &htextpad, text, true) != 0)
481f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
482f499134dSBaptiste Daroussin 
483f499134dSBaptiste Daroussin 	prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-7,
484f499134dSBaptiste Daroussin 			    x+w-1-t.text.hmargin);
485f499134dSBaptiste Daroussin 
486f499134dSBaptiste Daroussin 	sizebar = w - HBORDERS - 2 - BARMARGIN * 2;
487f499134dSBaptiste Daroussin 	bigchange = MAX(1, sizebar/10);
488f499134dSBaptiste Daroussin 
489f499134dSBaptiste Daroussin 	bar = new_boxed_window(conf, y + h - 6, x + 1 + BARMARGIN, 3,
490f499134dSBaptiste Daroussin 	    sizebar + 2, RAISED);
491f499134dSBaptiste Daroussin 
492c76f0793SBaptiste Daroussin 	loop = buttupdate = barupdate = true;
493c76f0793SBaptiste Daroussin 	while(loop) {
494f499134dSBaptiste Daroussin 		if (buttupdate) {
495f499134dSBaptiste Daroussin 			draw_buttons(widget, h-2, w, bs, true);
496f499134dSBaptiste Daroussin 			wrefresh(widget);
497f499134dSBaptiste Daroussin 			buttupdate = false;
498f499134dSBaptiste Daroussin 		}
499c76f0793SBaptiste Daroussin 		if (barupdate) {
500f499134dSBaptiste Daroussin 			perc = ((float)(currvalue - min)*100) / (positions-1);
501c76f0793SBaptiste Daroussin 			draw_perc_bar(bar, 1, 1, sizebar, perc, true, currvalue);
502c76f0793SBaptiste Daroussin 			barupdate = false;
503c76f0793SBaptiste Daroussin 			wrefresh(bar);
504c76f0793SBaptiste Daroussin 		}
505c76f0793SBaptiste Daroussin 
506c76f0793SBaptiste Daroussin 		input = getch();
507c76f0793SBaptiste Daroussin 		switch(input) {
508f499134dSBaptiste Daroussin 		case KEY_ENTER:
509f499134dSBaptiste Daroussin 		case 10: /* Enter */
510f499134dSBaptiste Daroussin 			output = bs.value[bs.curr];
511c76f0793SBaptiste Daroussin 			*value = currvalue;
512c76f0793SBaptiste Daroussin 			loop = false;
513c76f0793SBaptiste Daroussin 			break;
514c76f0793SBaptiste Daroussin 		case 27: /* Esc */
515c76f0793SBaptiste Daroussin 			output = BSDDIALOG_ESC;
516c76f0793SBaptiste Daroussin 			loop = false;
517c76f0793SBaptiste Daroussin 			break;
518f499134dSBaptiste Daroussin 		case '\t': /* TAB */
519c76f0793SBaptiste Daroussin 			bs.curr = (bs.curr + 1) % bs.nbuttons;
520c76f0793SBaptiste Daroussin 			buttupdate = true;
521c76f0793SBaptiste Daroussin 			break;
522c76f0793SBaptiste Daroussin 		case KEY_LEFT:
523c76f0793SBaptiste Daroussin 			if (bs.curr > 0) {
524c76f0793SBaptiste Daroussin 				bs.curr--;
525c76f0793SBaptiste Daroussin 				buttupdate = true;
526c76f0793SBaptiste Daroussin 			}
527c76f0793SBaptiste Daroussin 			break;
528c76f0793SBaptiste Daroussin 		case KEY_RIGHT:
529c76f0793SBaptiste Daroussin 			if (bs.curr < (int) bs.nbuttons - 1) {
530c76f0793SBaptiste Daroussin 				bs.curr++;
531c76f0793SBaptiste Daroussin 				buttupdate = true;
532c76f0793SBaptiste Daroussin 			}
533c76f0793SBaptiste Daroussin 			break;
534f499134dSBaptiste Daroussin 		case KEY_HOME:
535f499134dSBaptiste Daroussin 			currvalue = max;
536f499134dSBaptiste Daroussin 			barupdate = true;
537f499134dSBaptiste Daroussin 			break;
538f499134dSBaptiste Daroussin 		case KEY_END:
539f499134dSBaptiste Daroussin 			currvalue = min;
540f499134dSBaptiste Daroussin 			barupdate = true;
541f499134dSBaptiste Daroussin 			break;
542f499134dSBaptiste Daroussin 		case KEY_NPAGE:
543f499134dSBaptiste Daroussin 			currvalue -= bigchange;
544f499134dSBaptiste Daroussin 			if (currvalue < min)
545f499134dSBaptiste Daroussin 				currvalue = min;
546f499134dSBaptiste Daroussin 			barupdate = true;
547f499134dSBaptiste Daroussin 			break;
548f499134dSBaptiste Daroussin 		case KEY_PPAGE:
549f499134dSBaptiste Daroussin 			currvalue += bigchange;
550f499134dSBaptiste Daroussin 			if (currvalue > max)
551f499134dSBaptiste Daroussin 				currvalue = max;
552f499134dSBaptiste Daroussin 			barupdate = true;
553f499134dSBaptiste Daroussin 			break;
554c76f0793SBaptiste Daroussin 		case KEY_UP:
555c76f0793SBaptiste Daroussin 			if (currvalue < max) {
556c76f0793SBaptiste Daroussin 				currvalue++;
557c76f0793SBaptiste Daroussin 				barupdate = true;
558c76f0793SBaptiste Daroussin 			}
559c76f0793SBaptiste Daroussin 			break;
560c76f0793SBaptiste Daroussin 		case KEY_DOWN:
561c76f0793SBaptiste Daroussin 			if (currvalue > min) {
562c76f0793SBaptiste Daroussin 				currvalue--;
563c76f0793SBaptiste Daroussin 				barupdate = true;
564c76f0793SBaptiste Daroussin 			}
565c76f0793SBaptiste Daroussin 			break;
566f499134dSBaptiste Daroussin 		case KEY_F(1):
5678c4f4028SBaptiste Daroussin 			if (conf->f1_file == NULL && conf->f1_message == NULL)
568f499134dSBaptiste Daroussin 				break;
569f499134dSBaptiste Daroussin 			if (f1help(conf) != 0)
570f499134dSBaptiste Daroussin 				return BSDDIALOG_ERROR;
571f499134dSBaptiste Daroussin 			/* No break! the terminal size can change */
572f499134dSBaptiste Daroussin 		case KEY_RESIZE:
573f499134dSBaptiste Daroussin 			hide_widget(y, x, h, w,conf->shadow);
574f499134dSBaptiste Daroussin 
575f499134dSBaptiste Daroussin 			/*
576f499134dSBaptiste Daroussin 			 * Unnecessary, but, when the columns decrease the
577f499134dSBaptiste Daroussin 			 * following "refresh" seem not work
578f499134dSBaptiste Daroussin 			 */
579f499134dSBaptiste Daroussin 			refresh();
580f499134dSBaptiste Daroussin 
581f499134dSBaptiste Daroussin 			if (set_widget_size(conf, rows, cols, &h, &w) != 0)
582f499134dSBaptiste Daroussin 				return BSDDIALOG_ERROR;
583f499134dSBaptiste Daroussin 			if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0)
584f499134dSBaptiste Daroussin 				return BSDDIALOG_ERROR;
585f499134dSBaptiste Daroussin 			if (bar_checksize(text, h, w, &bs) != 0)
586f499134dSBaptiste Daroussin 				return BSDDIALOG_ERROR;
587f499134dSBaptiste Daroussin 			if (set_widget_position(conf, &y, &x, h, w) != 0)
588f499134dSBaptiste Daroussin 				return BSDDIALOG_ERROR;
589f499134dSBaptiste Daroussin 
590f499134dSBaptiste Daroussin 			wclear(shadow);
591f499134dSBaptiste Daroussin 			mvwin(shadow, y + t.shadow.h, x + t.shadow.w);
592f499134dSBaptiste Daroussin 			wresize(shadow, h, w);
593f499134dSBaptiste Daroussin 
594f499134dSBaptiste Daroussin 			wclear(widget);
595f499134dSBaptiste Daroussin 			mvwin(widget, y, x);
596f499134dSBaptiste Daroussin 			wresize(widget, h, w);
597f499134dSBaptiste Daroussin 
598f499134dSBaptiste Daroussin 			htextpad = 1;
599f499134dSBaptiste Daroussin 			wclear(textpad);
600f499134dSBaptiste Daroussin 			wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2);
601f499134dSBaptiste Daroussin 
602f499134dSBaptiste Daroussin 			sizebar = w - HBORDERS - 2 - BARMARGIN * 2;
603f499134dSBaptiste Daroussin 			bigchange = MAX(1, sizebar/10);
604f499134dSBaptiste Daroussin 			wclear(bar);
605f499134dSBaptiste Daroussin 			mvwin(bar, y + h - 6, x + 1 + BARMARGIN);
606f499134dSBaptiste Daroussin 			wresize(bar, 3, sizebar + 2);
607f499134dSBaptiste Daroussin 
608f499134dSBaptiste Daroussin 			if(update_widget_withtextpad(conf, shadow, widget, h, w,
609f499134dSBaptiste Daroussin 			    RAISED, textpad, &htextpad, text, true) != 0)
610f499134dSBaptiste Daroussin 				return BSDDIALOG_ERROR;
611f499134dSBaptiste Daroussin 
612f499134dSBaptiste Daroussin 			prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-7,
613f499134dSBaptiste Daroussin 			    x+w-1-t.text.hmargin);
614f499134dSBaptiste Daroussin 
615f499134dSBaptiste Daroussin 			draw_borders(conf, bar, 3, sizebar + 2, RAISED);
616f499134dSBaptiste Daroussin 
617f499134dSBaptiste Daroussin 			barupdate = true;
618f499134dSBaptiste Daroussin 			buttupdate = true;
619f499134dSBaptiste Daroussin 			break;
620f499134dSBaptiste Daroussin 		default:
621f499134dSBaptiste Daroussin 			for (i = 0; i < (int) bs.nbuttons; i++)
622f499134dSBaptiste Daroussin 				if (tolower(input) == tolower((bs.label[i])[0])) {
623f499134dSBaptiste Daroussin 					output = bs.value[i];
624f499134dSBaptiste Daroussin 					loop = false;
625f499134dSBaptiste Daroussin 			}
626c76f0793SBaptiste Daroussin 		}
627c76f0793SBaptiste Daroussin 	}
628c76f0793SBaptiste Daroussin 
629c76f0793SBaptiste Daroussin 	delwin(bar);
630f499134dSBaptiste Daroussin 	end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
631c76f0793SBaptiste Daroussin 
632c76f0793SBaptiste Daroussin 	return output;
633c76f0793SBaptiste Daroussin }
634c76f0793SBaptiste Daroussin 
635f499134dSBaptiste Daroussin int
636f499134dSBaptiste Daroussin bsddialog_pause(struct bsddialog_conf *conf, char* text, int rows, int cols,
637f499134dSBaptiste Daroussin     unsigned int sec)
638c76f0793SBaptiste Daroussin {
639f499134dSBaptiste Daroussin 	WINDOW *widget, *textpad, *bar, *shadow;
640f499134dSBaptiste Daroussin 	int i, output, y, x, h, w, htextpad;
641c76f0793SBaptiste Daroussin 	bool loop, buttupdate, barupdate;
642f499134dSBaptiste Daroussin 	int input, tout, sizebar;
643c76f0793SBaptiste Daroussin 	float perc;
644c76f0793SBaptiste Daroussin 	struct buttons bs;
645c76f0793SBaptiste Daroussin 
646c76f0793SBaptiste Daroussin 	get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
647c76f0793SBaptiste Daroussin 	    BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
648c76f0793SBaptiste Daroussin 
649f499134dSBaptiste Daroussin 	if (set_widget_size(conf, rows, cols, &h, &w) != 0)
650f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
651f499134dSBaptiste Daroussin 	if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0)
652f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
653f499134dSBaptiste Daroussin 	if (bar_checksize(text, h, w, &bs) != 0)
654f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
655f499134dSBaptiste Daroussin 	if (set_widget_position(conf, &y, &x, h, w) != 0)
656f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
657f499134dSBaptiste Daroussin 
658f499134dSBaptiste Daroussin 	if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
659f499134dSBaptiste Daroussin 	    &textpad, &htextpad, text, true) != 0)
660f499134dSBaptiste Daroussin 		return BSDDIALOG_ERROR;
661f499134dSBaptiste Daroussin 
662f499134dSBaptiste Daroussin 	prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-7,
663f499134dSBaptiste Daroussin 	    x+w-1-t.text.hmargin);
664f499134dSBaptiste Daroussin 
665f499134dSBaptiste Daroussin 	sizebar = w - HBORDERS - 2 - BARMARGIN * 2;
666f499134dSBaptiste Daroussin 	bar = new_boxed_window(conf, y + h - 6, x + 1 + BARMARGIN, 3,
667f499134dSBaptiste Daroussin 	    sizebar + 2, RAISED);
668f499134dSBaptiste Daroussin 
669f499134dSBaptiste Daroussin 	tout = sec;
670c76f0793SBaptiste Daroussin 	nodelay(stdscr, TRUE);
671c76f0793SBaptiste Daroussin 	timeout(1000);
672c76f0793SBaptiste Daroussin 	loop = buttupdate = barupdate = true;
673c76f0793SBaptiste Daroussin 	while(loop) {
674c76f0793SBaptiste Daroussin 		if (barupdate) {
675f499134dSBaptiste Daroussin 			perc = (float)tout * 100 / sec;
676f499134dSBaptiste Daroussin 			draw_perc_bar(bar, 1, 1, sizebar, perc, true, tout);
677c76f0793SBaptiste Daroussin 			barupdate = false;
678c76f0793SBaptiste Daroussin 			wrefresh(bar);
679c76f0793SBaptiste Daroussin 		}
680c76f0793SBaptiste Daroussin 
681c76f0793SBaptiste Daroussin 		if (buttupdate) {
682f499134dSBaptiste Daroussin 			draw_buttons(widget, h-2, w, bs, true);
683c76f0793SBaptiste Daroussin 			wrefresh(widget);
684c76f0793SBaptiste Daroussin 			buttupdate = false;
685c76f0793SBaptiste Daroussin 		}
686c76f0793SBaptiste Daroussin 
687c76f0793SBaptiste Daroussin 		input = getch();
688f499134dSBaptiste Daroussin 		if(input < 0) { /* timeout */
689f499134dSBaptiste Daroussin 			tout--;
690f499134dSBaptiste Daroussin 			if (tout < 0) {
691f499134dSBaptiste Daroussin 				output = BSDDIALOG_TIMEOUT;
692c76f0793SBaptiste Daroussin 				break;
693c76f0793SBaptiste Daroussin 			}
694c76f0793SBaptiste Daroussin 			else {
695c76f0793SBaptiste Daroussin 				barupdate = true;
696c76f0793SBaptiste Daroussin 				continue;
697c76f0793SBaptiste Daroussin 			}
698c76f0793SBaptiste Daroussin 		}
699c76f0793SBaptiste Daroussin 		switch(input) {
700f499134dSBaptiste Daroussin 		case KEY_ENTER:
701f499134dSBaptiste Daroussin 		case 10: /* Enter */
702f499134dSBaptiste Daroussin 			output = bs.value[bs.curr];
703c76f0793SBaptiste Daroussin 			loop = false;
704c76f0793SBaptiste Daroussin 			break;
705c76f0793SBaptiste Daroussin 		case 27: /* Esc */
706c76f0793SBaptiste Daroussin 			output = BSDDIALOG_ESC;
707c76f0793SBaptiste Daroussin 			loop = false;
708c76f0793SBaptiste Daroussin 			break;
709f499134dSBaptiste Daroussin 		case '\t': /* TAB */
710c76f0793SBaptiste Daroussin 			bs.curr = (bs.curr + 1) % bs.nbuttons;
711c76f0793SBaptiste Daroussin 			buttupdate = true;
712c76f0793SBaptiste Daroussin 			break;
713c76f0793SBaptiste Daroussin 		case KEY_LEFT:
714c76f0793SBaptiste Daroussin 			if (bs.curr > 0) {
715c76f0793SBaptiste Daroussin 				bs.curr--;
716c76f0793SBaptiste Daroussin 				buttupdate = true;
717c76f0793SBaptiste Daroussin 			}
718c76f0793SBaptiste Daroussin 			break;
719c76f0793SBaptiste Daroussin 		case KEY_RIGHT:
720c76f0793SBaptiste Daroussin 			if (bs.curr < (int) bs.nbuttons - 1) {
721c76f0793SBaptiste Daroussin 				bs.curr++;
722c76f0793SBaptiste Daroussin 				buttupdate = true;
723c76f0793SBaptiste Daroussin 			}
724c76f0793SBaptiste Daroussin 			break;
725f499134dSBaptiste Daroussin 		case KEY_F(1):
7268c4f4028SBaptiste Daroussin 			if (conf->f1_file == NULL && conf->f1_message == NULL)
727f499134dSBaptiste Daroussin 				break;
728f499134dSBaptiste Daroussin 			if (f1help(conf) != 0)
729f499134dSBaptiste Daroussin 				return BSDDIALOG_ERROR;
730f499134dSBaptiste Daroussin 			/* No break! the terminal size can change */
731f499134dSBaptiste Daroussin 		case KEY_RESIZE:
732f499134dSBaptiste Daroussin 			hide_widget(y, x, h, w,conf->shadow);
733f499134dSBaptiste Daroussin 
734f499134dSBaptiste Daroussin 			/*
735f499134dSBaptiste Daroussin 			 * Unnecessary, but, when the columns decrease the
736f499134dSBaptiste Daroussin 			 * following "refresh" seem not work
737f499134dSBaptiste Daroussin 			 */
738f499134dSBaptiste Daroussin 			refresh();
739f499134dSBaptiste Daroussin 
740f499134dSBaptiste Daroussin 			if (set_widget_size(conf, rows, cols, &h, &w) != 0)
741f499134dSBaptiste Daroussin 				return BSDDIALOG_ERROR;
742f499134dSBaptiste Daroussin 			if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0)
743f499134dSBaptiste Daroussin 				return BSDDIALOG_ERROR;
744f499134dSBaptiste Daroussin 			if (bar_checksize(text, h, w, &bs) != 0)
745f499134dSBaptiste Daroussin 				return BSDDIALOG_ERROR;
746f499134dSBaptiste Daroussin 			if (set_widget_position(conf, &y, &x, h, w) != 0)
747f499134dSBaptiste Daroussin 				return BSDDIALOG_ERROR;
748f499134dSBaptiste Daroussin 
749f499134dSBaptiste Daroussin 			wclear(shadow);
750f499134dSBaptiste Daroussin 			mvwin(shadow, y + t.shadow.h, x + t.shadow.w);
751f499134dSBaptiste Daroussin 			wresize(shadow, h, w);
752f499134dSBaptiste Daroussin 
753f499134dSBaptiste Daroussin 			wclear(widget);
754f499134dSBaptiste Daroussin 			mvwin(widget, y, x);
755f499134dSBaptiste Daroussin 			wresize(widget, h, w);
756f499134dSBaptiste Daroussin 
757f499134dSBaptiste Daroussin 			htextpad = 1;
758f499134dSBaptiste Daroussin 			wclear(textpad);
759f499134dSBaptiste Daroussin 			wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2);
760f499134dSBaptiste Daroussin 
761f499134dSBaptiste Daroussin 			sizebar = w - HBORDERS - 2 - BARMARGIN * 2;
762f499134dSBaptiste Daroussin 			wclear(bar);
763f499134dSBaptiste Daroussin 			mvwin(bar, y + h - 6, x + 1 + BARMARGIN);
764f499134dSBaptiste Daroussin 			wresize(bar, 3, sizebar + 2);
765f499134dSBaptiste Daroussin 
766f499134dSBaptiste Daroussin 			if(update_widget_withtextpad(conf, shadow, widget, h, w,
767f499134dSBaptiste Daroussin 			    RAISED, textpad, &htextpad, text, true) != 0)
768f499134dSBaptiste Daroussin 				return BSDDIALOG_ERROR;
769f499134dSBaptiste Daroussin 
770f499134dSBaptiste Daroussin 			prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-7,
771f499134dSBaptiste Daroussin 			    x+w-1-t.text.hmargin);
772f499134dSBaptiste Daroussin 
773f499134dSBaptiste Daroussin 			draw_borders(conf, bar, 3, sizebar + 2, RAISED);
774f499134dSBaptiste Daroussin 
775f499134dSBaptiste Daroussin 			barupdate = true;
776f499134dSBaptiste Daroussin 			buttupdate = true;
777f499134dSBaptiste Daroussin 			break;
778f499134dSBaptiste Daroussin 		default:
779f499134dSBaptiste Daroussin 			for (i = 0; i < (int) bs.nbuttons; i++)
780f499134dSBaptiste Daroussin 				if (tolower(input) == tolower((bs.label[i])[0])) {
781f499134dSBaptiste Daroussin 					output = bs.value[i];
782f499134dSBaptiste Daroussin 					loop = false;
783f499134dSBaptiste Daroussin 			}
784c76f0793SBaptiste Daroussin 		}
785c76f0793SBaptiste Daroussin 	}
786c76f0793SBaptiste Daroussin 
787c76f0793SBaptiste Daroussin 	nodelay(stdscr, FALSE);
788c76f0793SBaptiste Daroussin 
789c76f0793SBaptiste Daroussin 	delwin(bar);
790f499134dSBaptiste Daroussin 	end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
791c76f0793SBaptiste Daroussin 
792c76f0793SBaptiste Daroussin 	return output;
793c76f0793SBaptiste Daroussin }
794