xref: /freebsd-src/contrib/bsddialog/lib/lib_util.c (revision 61ba55bcf70f2340f9c943c9571113b3fd8eda69)
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 <unistd.h>
32b319d934SAlfonso S. Siciliano #include <wctype.h>
33c76f0793SBaptiste Daroussin 
34c76f0793SBaptiste Daroussin #include "bsddialog.h"
35c76f0793SBaptiste Daroussin #include "bsddialog_theme.h"
36263660c0SAlfonso Siciliano #include "lib_util.h"
37c76f0793SBaptiste Daroussin 
38*61ba55bcSBaptiste Daroussin /*
39*61ba55bcSBaptiste Daroussin  * -1- Error and diagnostic
40*61ba55bcSBaptiste Daroussin  *
41*61ba55bcSBaptiste Daroussin  *	get_error_string();
42*61ba55bcSBaptiste Daroussin  *	set_error_string();
43*61ba55bcSBaptiste Daroussin  *	set_fmt_error_string();
44*61ba55bcSBaptiste Daroussin  *
45*61ba55bcSBaptiste Daroussin  * ----------------------------------------------------
46*61ba55bcSBaptiste Daroussin  * -2- (Unicode) Multicolumn character strings
47*61ba55bcSBaptiste Daroussin  *
48*61ba55bcSBaptiste Daroussin  *	alloc_mbstows();
49*61ba55bcSBaptiste Daroussin  *	mvwaddwch();
50*61ba55bcSBaptiste Daroussin  *	str_props();
51*61ba55bcSBaptiste Daroussin  *	strcols();
52*61ba55bcSBaptiste Daroussin  *
53*61ba55bcSBaptiste Daroussin  * ----------------------------------------------------
54*61ba55bcSBaptiste Daroussin  * -3- Buttons
55*61ba55bcSBaptiste Daroussin  *
56*61ba55bcSBaptiste Daroussin  * [static] buttons_min_width();
57*61ba55bcSBaptiste Daroussin  * [static] draw_button();
58*61ba55bcSBaptiste Daroussin  *          draw_buttons();
59*61ba55bcSBaptiste Daroussin  *          set_buttons(); (to call 1 time after prepare_dialog()).
60*61ba55bcSBaptiste Daroussin  *          shortcut_buttons();
61*61ba55bcSBaptiste Daroussin  *
62*61ba55bcSBaptiste Daroussin  * ----------------------------------------------------
63*61ba55bcSBaptiste Daroussin  * -4- (Auto) Sizing and (Auto) Position
64*61ba55bcSBaptiste Daroussin  *
65*61ba55bcSBaptiste Daroussin  * [static] widget_max_height(conf);
66*61ba55bcSBaptiste Daroussin  * [static] widget_max_width(struct bsddialog_conf *conf)
67*61ba55bcSBaptiste Daroussin  * [static] is_wtext_attr();
68*61ba55bcSBaptiste Daroussin  * [static] text_properties();
69*61ba55bcSBaptiste Daroussin  * [static] text_autosize();
70*61ba55bcSBaptiste Daroussin  * [static] text_size();
71*61ba55bcSBaptiste Daroussin  * [static] widget_min_height(conf, htext, hnotext, bool buttons);
72*61ba55bcSBaptiste Daroussin  * [static] widget_min_width(conf, wtext, minw, buttons);
73*61ba55bcSBaptiste Daroussin  *          set_widget_size();
74*61ba55bcSBaptiste Daroussin  *          set_widget_autosize();  (not for all dialogs).
75*61ba55bcSBaptiste Daroussin  *          widget_checksize();     (not for all dialogs).
76*61ba55bcSBaptiste Daroussin  *          set_widget_position();
77*61ba55bcSBaptiste Daroussin  *          dialog_size_position(struct dialog); (not for all dialogs).
78*61ba55bcSBaptiste Daroussin  *
79*61ba55bcSBaptiste Daroussin  * ----------------------------------------------------
80*61ba55bcSBaptiste Daroussin  * -5- (Dialog) Widget components and utils
81*61ba55bcSBaptiste Daroussin  *
82*61ba55bcSBaptiste Daroussin  *	hide_dialog(struct dialog);
83*61ba55bcSBaptiste Daroussin  *	f1help_dialog(conf);
84*61ba55bcSBaptiste Daroussin  *	draw_borders(conf, win, elev);
85*61ba55bcSBaptiste Daroussin  *	update_box(conf, win, y, x, h, w, elev);
86*61ba55bcSBaptiste Daroussin  *	rtextpad(); (helper for pnoutrefresh(textpad)).
87*61ba55bcSBaptiste Daroussin  *
88*61ba55bcSBaptiste Daroussin  * ----------------------------------------------------
89*61ba55bcSBaptiste Daroussin  * -6- Dialog init/build, update/draw, destroy
90*61ba55bcSBaptiste Daroussin  *
91*61ba55bcSBaptiste Daroussin  *          end_dialog(struct dialog);
92*61ba55bcSBaptiste Daroussin  * [static] check_set_wtext_attr();
93*61ba55bcSBaptiste Daroussin  * [static] print_string(); (word wrapping).
94*61ba55bcSBaptiste Daroussin  * [static] print_textpad();
95*61ba55bcSBaptiste Daroussin  *          draw_dialog(struct dialog);
96*61ba55bcSBaptiste Daroussin  *          prepare_dialog(struct dialog);
97*61ba55bcSBaptiste Daroussin  */
98c76f0793SBaptiste Daroussin 
99*61ba55bcSBaptiste Daroussin /*
100*61ba55bcSBaptiste Daroussin  * -1- Error and diagnostic
101*61ba55bcSBaptiste Daroussin  */
102*61ba55bcSBaptiste Daroussin #define ERRBUFLEN    1024
103*61ba55bcSBaptiste Daroussin 
104c76f0793SBaptiste Daroussin static char errorbuffer[ERRBUFLEN];
105c76f0793SBaptiste Daroussin 
106c76f0793SBaptiste Daroussin const char *get_error_string(void)
107c76f0793SBaptiste Daroussin {
108263660c0SAlfonso Siciliano 	return (errorbuffer);
109c76f0793SBaptiste Daroussin }
110c76f0793SBaptiste Daroussin 
111bce40c02SAlfonso S. Siciliano void set_error_string(const char *str)
112c76f0793SBaptiste Daroussin {
113c76f0793SBaptiste Daroussin 	strncpy(errorbuffer, str, ERRBUFLEN-1);
114c76f0793SBaptiste Daroussin }
115c76f0793SBaptiste Daroussin 
116*61ba55bcSBaptiste Daroussin void set_fmt_error_string(const char *fmt, ...)
117*61ba55bcSBaptiste Daroussin {
118*61ba55bcSBaptiste Daroussin    va_list arg_ptr;
119*61ba55bcSBaptiste Daroussin 
120*61ba55bcSBaptiste Daroussin    va_start(arg_ptr, fmt);
121*61ba55bcSBaptiste Daroussin    vsnprintf(errorbuffer, ERRBUFLEN-1, fmt, arg_ptr);
122*61ba55bcSBaptiste Daroussin    va_end(arg_ptr);
123*61ba55bcSBaptiste Daroussin }
124*61ba55bcSBaptiste Daroussin 
125*61ba55bcSBaptiste Daroussin /*
126*61ba55bcSBaptiste Daroussin  * -2- (Unicode) Multicolumn character strings
127*61ba55bcSBaptiste Daroussin  */
128b319d934SAlfonso S. Siciliano wchar_t* alloc_mbstows(const char *mbstring)
129b319d934SAlfonso S. Siciliano {
130b319d934SAlfonso S. Siciliano 	size_t charlen, nchar;
131b319d934SAlfonso S. Siciliano 	mbstate_t mbs;
132b319d934SAlfonso S. Siciliano 	const char *pmbstring;
133b319d934SAlfonso S. Siciliano 	wchar_t *wstring;
134b319d934SAlfonso S. Siciliano 
135b319d934SAlfonso S. Siciliano 	nchar = 1;
136b319d934SAlfonso S. Siciliano 	pmbstring = mbstring;
137b319d934SAlfonso S. Siciliano 	memset(&mbs, 0, sizeof(mbs));
138b319d934SAlfonso S. Siciliano 	while ((charlen = mbrlen(pmbstring, MB_CUR_MAX, &mbs)) != 0 &&
139b319d934SAlfonso S. Siciliano 	    charlen != (size_t)-1 && charlen != (size_t)-2) {
140b319d934SAlfonso S. Siciliano 		pmbstring += charlen;
141b319d934SAlfonso S. Siciliano 		nchar++;
142b319d934SAlfonso S. Siciliano 	}
143b319d934SAlfonso S. Siciliano 
144b319d934SAlfonso S. Siciliano 	if ((wstring = calloc(nchar, sizeof(wchar_t))) == NULL)
145b319d934SAlfonso S. Siciliano 		return (NULL);
146b319d934SAlfonso S. Siciliano 	mbstowcs(wstring, mbstring, nchar);
147b319d934SAlfonso S. Siciliano 
148b319d934SAlfonso S. Siciliano 	return (wstring);
149b319d934SAlfonso S. Siciliano }
150b319d934SAlfonso S. Siciliano 
151b319d934SAlfonso S. Siciliano void mvwaddwch(WINDOW *w, int y, int x, wchar_t wch)
152b319d934SAlfonso S. Siciliano {
153b319d934SAlfonso S. Siciliano 	wchar_t ws[2];
154b319d934SAlfonso S. Siciliano 
155b319d934SAlfonso S. Siciliano 	ws[0] = wch;
156b319d934SAlfonso S. Siciliano 	ws[1] = L'\0';
157b319d934SAlfonso S. Siciliano 	mvwaddwstr(w, y, x, ws);
158b319d934SAlfonso S. Siciliano }
159b319d934SAlfonso S. Siciliano 
160b319d934SAlfonso S. Siciliano int str_props(const char *mbstring, unsigned int *cols, bool *has_multi_col)
161b319d934SAlfonso S. Siciliano {
162b319d934SAlfonso S. Siciliano 	bool multicol;
163b319d934SAlfonso S. Siciliano 	int w;
164b319d934SAlfonso S. Siciliano 	unsigned int ncol;
165b319d934SAlfonso S. Siciliano 	size_t charlen, mb_cur_max;
166b319d934SAlfonso S. Siciliano 	wchar_t wch;
167b319d934SAlfonso S. Siciliano 	mbstate_t mbs;
168b319d934SAlfonso S. Siciliano 
169b319d934SAlfonso S. Siciliano 	multicol = false;
170b319d934SAlfonso S. Siciliano 	mb_cur_max = MB_CUR_MAX;
171b319d934SAlfonso S. Siciliano 	ncol = 0;
172b319d934SAlfonso S. Siciliano 	memset(&mbs, 0, sizeof(mbs));
173b319d934SAlfonso S. Siciliano 	while ((charlen = mbrlen(mbstring, mb_cur_max, &mbs)) != 0 &&
174b319d934SAlfonso S. Siciliano 	    charlen != (size_t)-1 && charlen != (size_t)-2) {
175b319d934SAlfonso S. Siciliano 		if (mbtowc(&wch, mbstring, mb_cur_max) < 0)
176b319d934SAlfonso S. Siciliano 			return (-1);
177b319d934SAlfonso S. Siciliano 		w = (wch == L'\t') ? TABSIZE : wcwidth(wch);
178b319d934SAlfonso S. Siciliano 		ncol += (w < 0) ? 0 : w;
179b319d934SAlfonso S. Siciliano 		if (w > 1 && wch != L'\t')
180b319d934SAlfonso S. Siciliano 			multicol = true;
181b319d934SAlfonso S. Siciliano 		mbstring += charlen;
182b319d934SAlfonso S. Siciliano 	}
183b319d934SAlfonso S. Siciliano 
184b319d934SAlfonso S. Siciliano 	if (cols != NULL)
185b319d934SAlfonso S. Siciliano 		*cols = ncol;
186b319d934SAlfonso S. Siciliano 	if (has_multi_col != NULL)
187b319d934SAlfonso S. Siciliano 		*has_multi_col = multicol;
188b319d934SAlfonso S. Siciliano 
189b319d934SAlfonso S. Siciliano 	return (0);
190b319d934SAlfonso S. Siciliano }
191b319d934SAlfonso S. Siciliano 
192b319d934SAlfonso S. Siciliano unsigned int strcols(const char *mbstring)
193b319d934SAlfonso S. Siciliano {
194b319d934SAlfonso S. Siciliano 	int w;
195b319d934SAlfonso S. Siciliano 	unsigned int ncol;
196b319d934SAlfonso S. Siciliano 	size_t charlen, mb_cur_max;
197b319d934SAlfonso S. Siciliano 	wchar_t wch;
198b319d934SAlfonso S. Siciliano 	mbstate_t mbs;
199b319d934SAlfonso S. Siciliano 
200b319d934SAlfonso S. Siciliano 	mb_cur_max = MB_CUR_MAX;
201b319d934SAlfonso S. Siciliano 	ncol = 0;
202b319d934SAlfonso S. Siciliano 	memset(&mbs, 0, sizeof(mbs));
203b319d934SAlfonso S. Siciliano 	while ((charlen = mbrlen(mbstring, mb_cur_max, &mbs)) != 0 &&
204b319d934SAlfonso S. Siciliano 	    charlen != (size_t)-1 && charlen != (size_t)-2) {
205b319d934SAlfonso S. Siciliano 		if (mbtowc(&wch, mbstring, mb_cur_max) < 0)
206b319d934SAlfonso S. Siciliano 			return (0);
207b319d934SAlfonso S. Siciliano 		w = (wch == L'\t') ? TABSIZE : wcwidth(wch);
208b319d934SAlfonso S. Siciliano 		ncol += (w < 0) ? 0 : w;
209b319d934SAlfonso S. Siciliano 		mbstring += charlen;
210b319d934SAlfonso S. Siciliano 	}
211b319d934SAlfonso S. Siciliano 
212b319d934SAlfonso S. Siciliano 	return (ncol);
213b319d934SAlfonso S. Siciliano }
214b319d934SAlfonso S. Siciliano 
215*61ba55bcSBaptiste Daroussin /*
216*61ba55bcSBaptiste Daroussin  * -3- Buttons
217*61ba55bcSBaptiste Daroussin  */
218*61ba55bcSBaptiste Daroussin static int buttons_min_width(struct buttons *bs)
219c76f0793SBaptiste Daroussin {
220*61ba55bcSBaptiste Daroussin 	unsigned int width;
221c76f0793SBaptiste Daroussin 
222*61ba55bcSBaptiste Daroussin 	width = bs->nbuttons * bs->sizebutton;
223*61ba55bcSBaptiste Daroussin 	if (bs->nbuttons > 0)
224*61ba55bcSBaptiste Daroussin 		width += (bs->nbuttons - 1) * t.button.minmargin;
225c76f0793SBaptiste Daroussin 
226*61ba55bcSBaptiste Daroussin 	return (width);
227c76f0793SBaptiste Daroussin }
228c76f0793SBaptiste Daroussin 
229263660c0SAlfonso Siciliano static void
230263660c0SAlfonso Siciliano draw_button(WINDOW *window, int y, int x, int size, const char *text,
231b319d934SAlfonso S. Siciliano     wchar_t first, bool selected, bool shortcut)
232c76f0793SBaptiste Daroussin {
233c76f0793SBaptiste Daroussin 	int i, color_arrows, color_shortkey, color_button;
234c76f0793SBaptiste Daroussin 
235c76f0793SBaptiste Daroussin 	if (selected) {
236f499134dSBaptiste Daroussin 		color_arrows = t.button.f_delimcolor;
237f499134dSBaptiste Daroussin 		color_shortkey = t.button.f_shortcutcolor;
238f499134dSBaptiste Daroussin 		color_button = t.button.f_color;
239c76f0793SBaptiste Daroussin 	} else {
240f499134dSBaptiste Daroussin 		color_arrows = t.button.delimcolor;
241f499134dSBaptiste Daroussin 		color_shortkey = t.button.shortcutcolor;
242f499134dSBaptiste Daroussin 		color_button = t.button.color;
243c76f0793SBaptiste Daroussin 	}
244c76f0793SBaptiste Daroussin 
245c76f0793SBaptiste Daroussin 	wattron(window, color_arrows);
246bce40c02SAlfonso S. Siciliano 	mvwaddch(window, y, x, t.button.leftdelim);
247c76f0793SBaptiste Daroussin 	wattroff(window, color_arrows);
248c76f0793SBaptiste Daroussin 	wattron(window, color_button);
249c76f0793SBaptiste Daroussin 	for (i = 1; i < size - 1; i++)
250c76f0793SBaptiste Daroussin 		waddch(window, ' ');
251c76f0793SBaptiste Daroussin 	wattroff(window, color_button);
252c76f0793SBaptiste Daroussin 	wattron(window, color_arrows);
253bce40c02SAlfonso S. Siciliano 	mvwaddch(window, y, x + i, t.button.rightdelim);
254c76f0793SBaptiste Daroussin 	wattroff(window, color_arrows);
255c76f0793SBaptiste Daroussin 
256b319d934SAlfonso S. Siciliano 	x = x + 1 + ((size - 2 - strcols(text))/2);
257c76f0793SBaptiste Daroussin 	wattron(window, color_button);
258c76f0793SBaptiste Daroussin 	mvwaddstr(window, y, x, text);
259c76f0793SBaptiste Daroussin 	wattroff(window, color_button);
260c76f0793SBaptiste Daroussin 
261263660c0SAlfonso Siciliano 	if (shortcut) {
262c76f0793SBaptiste Daroussin 		wattron(window, color_shortkey);
263b319d934SAlfonso S. Siciliano 		mvwaddwch(window, y, x, first);
264c76f0793SBaptiste Daroussin 		wattroff(window, color_shortkey);
265c76f0793SBaptiste Daroussin 	}
266c76f0793SBaptiste Daroussin }
267c76f0793SBaptiste Daroussin 
268*61ba55bcSBaptiste Daroussin void draw_buttons(struct dialog *d)
269c76f0793SBaptiste Daroussin {
270*61ba55bcSBaptiste Daroussin 	int i, x, startx, y;
271b319d934SAlfonso S. Siciliano 	unsigned int newmargin, margin, wbuttons;
272c76f0793SBaptiste Daroussin 
273*61ba55bcSBaptiste Daroussin 	y = d->h - 2;
274263660c0SAlfonso Siciliano 
275*61ba55bcSBaptiste Daroussin 	newmargin = d->w - BORDERS - (d->bs.nbuttons * d->bs.sizebutton);
276*61ba55bcSBaptiste Daroussin 	newmargin /= (d->bs.nbuttons + 1);
277b319d934SAlfonso S. Siciliano 	newmargin = MIN(newmargin, t.button.maxmargin);
278b319d934SAlfonso S. Siciliano 	if (newmargin == 0) {
279b319d934SAlfonso S. Siciliano 		margin = t.button.minmargin;
280*61ba55bcSBaptiste Daroussin 		wbuttons = buttons_min_width(&d->bs);
281b319d934SAlfonso S. Siciliano 	} else {
282b319d934SAlfonso S. Siciliano 		margin = newmargin;
283*61ba55bcSBaptiste Daroussin 		wbuttons = d->bs.nbuttons * d->bs.sizebutton;
284*61ba55bcSBaptiste Daroussin 		wbuttons += (d->bs.nbuttons + 1) * margin;
285b319d934SAlfonso S. Siciliano 	}
286c76f0793SBaptiste Daroussin 
287*61ba55bcSBaptiste Daroussin 	startx = d->w/2 - wbuttons/2 + newmargin;
288*61ba55bcSBaptiste Daroussin 	for (i = 0; i < (int)d->bs.nbuttons; i++) {
289*61ba55bcSBaptiste Daroussin 		x = i * (d->bs.sizebutton + margin);
290*61ba55bcSBaptiste Daroussin 		draw_button(d->widget, y, startx + x, d->bs.sizebutton,
291*61ba55bcSBaptiste Daroussin 		    d->bs.label[i], d->bs.first[i],  i == d->bs.curr,
292*61ba55bcSBaptiste Daroussin 		    d->bs.shortcut);
293c76f0793SBaptiste Daroussin 	}
294c76f0793SBaptiste Daroussin }
295c76f0793SBaptiste Daroussin 
296c76f0793SBaptiste Daroussin void
297*61ba55bcSBaptiste Daroussin set_buttons(struct dialog *d, bool shortcut, const char *oklabel,
298*61ba55bcSBaptiste Daroussin     const char *cancellabel)
299c76f0793SBaptiste Daroussin {
300c76f0793SBaptiste Daroussin 	int i;
301c76f0793SBaptiste Daroussin #define SIZEBUTTON              8
302*61ba55bcSBaptiste Daroussin #define DEFAULT_BUTTON_LABEL	OK_LABEL
3038c4f4028SBaptiste Daroussin #define DEFAULT_BUTTON_VALUE	BSDDIALOG_OK
304b319d934SAlfonso S. Siciliano 	wchar_t first;
305c76f0793SBaptiste Daroussin 
306*61ba55bcSBaptiste Daroussin 	d->bs.nbuttons = 0;
307*61ba55bcSBaptiste Daroussin 	d->bs.curr = 0;
308*61ba55bcSBaptiste Daroussin 	d->bs.sizebutton = 0;
309*61ba55bcSBaptiste Daroussin 	d->bs.shortcut = shortcut;
310c76f0793SBaptiste Daroussin 
311*61ba55bcSBaptiste Daroussin 	if (d->conf->button.left1_label != NULL) {
312*61ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.left1_label;
313*61ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_LEFT1;
314*61ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
315c76f0793SBaptiste Daroussin 	}
316c76f0793SBaptiste Daroussin 
317*61ba55bcSBaptiste Daroussin 	if (d->conf->button.left2_label != NULL) {
318*61ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.left2_label;
319*61ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_LEFT2;
320*61ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
321c76f0793SBaptiste Daroussin 	}
322c76f0793SBaptiste Daroussin 
323*61ba55bcSBaptiste Daroussin 	if (d->conf->button.left3_label != NULL) {
324*61ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.left3_label;
325*61ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_LEFT3;
326*61ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
327c76f0793SBaptiste Daroussin 	}
328c76f0793SBaptiste Daroussin 
329*61ba55bcSBaptiste Daroussin 	if (oklabel != NULL && d->conf->button.without_ok == false) {
330*61ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.ok_label != NULL ?
331*61ba55bcSBaptiste Daroussin 		    d->conf->button.ok_label : oklabel;
332*61ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_OK;
333*61ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
334c76f0793SBaptiste Daroussin 	}
335c76f0793SBaptiste Daroussin 
336*61ba55bcSBaptiste Daroussin 	if (d->conf->button.with_extra) {
337*61ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.extra_label != NULL ?
338*61ba55bcSBaptiste Daroussin 		    d->conf->button.extra_label : "Extra";
339*61ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_EXTRA;
340*61ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
341f499134dSBaptiste Daroussin 	}
342f499134dSBaptiste Daroussin 
343*61ba55bcSBaptiste Daroussin 	if (cancellabel != NULL && d->conf->button.without_cancel == false) {
344*61ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.cancel_label ?
345*61ba55bcSBaptiste Daroussin 		    d->conf->button.cancel_label : cancellabel;
346*61ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_CANCEL;
347*61ba55bcSBaptiste Daroussin 		if (d->conf->button.default_cancel)
348*61ba55bcSBaptiste Daroussin 			d->bs.curr = d->bs.nbuttons;
349*61ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
350f499134dSBaptiste Daroussin 	}
351f499134dSBaptiste Daroussin 
352*61ba55bcSBaptiste Daroussin 	if (d->conf->button.with_help) {
353*61ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.help_label != NULL ?
354*61ba55bcSBaptiste Daroussin 		    d->conf->button.help_label : "Help";
355*61ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_HELP;
356*61ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
357c76f0793SBaptiste Daroussin 	}
358c76f0793SBaptiste Daroussin 
359*61ba55bcSBaptiste Daroussin 	if (d->conf->button.right1_label != NULL) {
360*61ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.right1_label;
361*61ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_RIGHT1;
362*61ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
363b319d934SAlfonso S. Siciliano 	}
364b319d934SAlfonso S. Siciliano 
365*61ba55bcSBaptiste Daroussin 	if (d->conf->button.right2_label != NULL) {
366*61ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.right2_label;
367*61ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_RIGHT2;
368*61ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
369*61ba55bcSBaptiste Daroussin 	}
370*61ba55bcSBaptiste Daroussin 
371*61ba55bcSBaptiste Daroussin 	if (d->conf->button.right3_label != NULL) {
372*61ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.right3_label;
373*61ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_RIGHT3;
374*61ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
375*61ba55bcSBaptiste Daroussin 	}
376*61ba55bcSBaptiste Daroussin 
377*61ba55bcSBaptiste Daroussin 	if (d->bs.nbuttons == 0) {
378*61ba55bcSBaptiste Daroussin 		d->bs.label[0] = DEFAULT_BUTTON_LABEL;
379*61ba55bcSBaptiste Daroussin 		d->bs.value[0] = DEFAULT_BUTTON_VALUE;
380*61ba55bcSBaptiste Daroussin 		d->bs.nbuttons = 1;
381*61ba55bcSBaptiste Daroussin 	}
382*61ba55bcSBaptiste Daroussin 
383*61ba55bcSBaptiste Daroussin 	for (i = 0; i < (int)d->bs.nbuttons; i++) {
384*61ba55bcSBaptiste Daroussin 		mbtowc(&first, d->bs.label[i], MB_CUR_MAX);
385*61ba55bcSBaptiste Daroussin 		d->bs.first[i] = first;
386*61ba55bcSBaptiste Daroussin 	}
387*61ba55bcSBaptiste Daroussin 
388*61ba55bcSBaptiste Daroussin 	if (d->conf->button.default_label != NULL) {
389*61ba55bcSBaptiste Daroussin 		for (i = 0; i < (int)d->bs.nbuttons; i++) {
390*61ba55bcSBaptiste Daroussin 			if (strcmp(d->conf->button.default_label,
391*61ba55bcSBaptiste Daroussin 			    d->bs.label[i]) == 0)
392*61ba55bcSBaptiste Daroussin 				d->bs.curr = i;
393c76f0793SBaptiste Daroussin 		}
394c76f0793SBaptiste Daroussin 	}
395c76f0793SBaptiste Daroussin 
396*61ba55bcSBaptiste Daroussin 	d->bs.sizebutton = MAX(SIZEBUTTON - 2, strcols(d->bs.label[0]));
397*61ba55bcSBaptiste Daroussin 	for (i = 1; i < (int)d->bs.nbuttons; i++)
398*61ba55bcSBaptiste Daroussin 		d->bs.sizebutton = MAX(d->bs.sizebutton, strcols(d->bs.label[i]));
399*61ba55bcSBaptiste Daroussin 	d->bs.sizebutton += 2;
400bce40c02SAlfonso S. Siciliano }
401bce40c02SAlfonso S. Siciliano 
402b319d934SAlfonso S. Siciliano bool shortcut_buttons(wint_t key, struct buttons *bs)
403f499134dSBaptiste Daroussin {
404263660c0SAlfonso Siciliano 	bool match;
405263660c0SAlfonso Siciliano 	unsigned int i;
406c76f0793SBaptiste Daroussin 
407263660c0SAlfonso Siciliano 	match = false;
408263660c0SAlfonso Siciliano 	for (i = 0; i < bs->nbuttons; i++) {
409b319d934SAlfonso S. Siciliano 		if (towlower(key) == towlower(bs->first[i])) {
410263660c0SAlfonso Siciliano 			bs->curr = i;
411263660c0SAlfonso Siciliano 			match = true;
412263660c0SAlfonso Siciliano 			break;
413263660c0SAlfonso Siciliano 		}
414263660c0SAlfonso Siciliano 	}
415263660c0SAlfonso Siciliano 
416263660c0SAlfonso Siciliano 	return (match);
417263660c0SAlfonso Siciliano }
418263660c0SAlfonso Siciliano 
419*61ba55bcSBaptiste Daroussin /*
420*61ba55bcSBaptiste Daroussin  * -4- (Auto) Sizing and (Auto) Position
421*61ba55bcSBaptiste Daroussin  */
422*61ba55bcSBaptiste Daroussin static int widget_max_height(struct bsddialog_conf *conf)
423*61ba55bcSBaptiste Daroussin {
424*61ba55bcSBaptiste Daroussin 	int maxheight;
425*61ba55bcSBaptiste Daroussin 
426*61ba55bcSBaptiste Daroussin 	maxheight = conf->shadow ? SCREENLINES - (int)t.shadow.y : SCREENLINES;
427*61ba55bcSBaptiste Daroussin 	if (maxheight <= 0)
428*61ba55bcSBaptiste Daroussin 		RETURN_ERROR("Terminal too small, screen lines - shadow <= 0");
429*61ba55bcSBaptiste Daroussin 
430*61ba55bcSBaptiste Daroussin 	if (conf->y != BSDDIALOG_CENTER && conf->auto_topmargin > 0)
431*61ba55bcSBaptiste Daroussin 		RETURN_ERROR("conf.y > 0 and conf->auto_topmargin > 0");
432*61ba55bcSBaptiste Daroussin 	else if (conf->y == BSDDIALOG_CENTER) {
433*61ba55bcSBaptiste Daroussin 		maxheight -= conf->auto_topmargin;
434*61ba55bcSBaptiste Daroussin 		if (maxheight <= 0)
435*61ba55bcSBaptiste Daroussin 			RETURN_ERROR("Terminal too small, screen lines - top "
436*61ba55bcSBaptiste Daroussin 			    "margins <= 0");
437*61ba55bcSBaptiste Daroussin 	} else if (conf->y > 0) {
438*61ba55bcSBaptiste Daroussin 		maxheight -= conf->y;
439*61ba55bcSBaptiste Daroussin 		if (maxheight <= 0)
440*61ba55bcSBaptiste Daroussin 			RETURN_ERROR("Terminal too small, screen lines - "
441*61ba55bcSBaptiste Daroussin 			    "shadow - y <= 0");
442*61ba55bcSBaptiste Daroussin 	}
443*61ba55bcSBaptiste Daroussin 
444*61ba55bcSBaptiste Daroussin 	maxheight -= conf->auto_downmargin;
445*61ba55bcSBaptiste Daroussin 	if (maxheight <= 0)
446*61ba55bcSBaptiste Daroussin 		RETURN_ERROR("Terminal too small, screen lines - Down margins "
447*61ba55bcSBaptiste Daroussin 		    "<= 0");
448*61ba55bcSBaptiste Daroussin 
449*61ba55bcSBaptiste Daroussin 	return (maxheight);
450*61ba55bcSBaptiste Daroussin }
451*61ba55bcSBaptiste Daroussin 
452*61ba55bcSBaptiste Daroussin static int widget_max_width(struct bsddialog_conf *conf)
453*61ba55bcSBaptiste Daroussin {
454*61ba55bcSBaptiste Daroussin 	int maxwidth;
455*61ba55bcSBaptiste Daroussin 
456*61ba55bcSBaptiste Daroussin 	maxwidth = conf->shadow ? SCREENCOLS - (int)t.shadow.x : SCREENCOLS;
457*61ba55bcSBaptiste Daroussin 	if (maxwidth <= 0)
458*61ba55bcSBaptiste Daroussin 		RETURN_ERROR("Terminal too small, screen cols - shadow <= 0");
459*61ba55bcSBaptiste Daroussin 
460*61ba55bcSBaptiste Daroussin 	if (conf->x > 0) {
461*61ba55bcSBaptiste Daroussin 		maxwidth -= conf->x;
462*61ba55bcSBaptiste Daroussin 		if (maxwidth <= 0)
463*61ba55bcSBaptiste Daroussin 			RETURN_ERROR("Terminal too small, screen cols - shadow "
464*61ba55bcSBaptiste Daroussin 			    "- x <= 0");
465*61ba55bcSBaptiste Daroussin 	}
466*61ba55bcSBaptiste Daroussin 
467*61ba55bcSBaptiste Daroussin 	return (maxwidth);
468*61ba55bcSBaptiste Daroussin }
469*61ba55bcSBaptiste Daroussin 
470b319d934SAlfonso S. Siciliano static bool is_wtext_attr(const wchar_t *wtext)
471263660c0SAlfonso Siciliano {
472*61ba55bcSBaptiste Daroussin 	bool att;
473*61ba55bcSBaptiste Daroussin 
474b319d934SAlfonso S. Siciliano 	if (wcsnlen(wtext, 3) < 3)
475263660c0SAlfonso Siciliano 		return (false);
476b319d934SAlfonso S. Siciliano 	if (wtext[0] != L'\\' || wtext[1] != L'Z')
477263660c0SAlfonso Siciliano 		return (false);
478f499134dSBaptiste Daroussin 
479*61ba55bcSBaptiste Daroussin 	att = wcschr(L"nbBdDkKrRsSuU01234567", wtext[2]) == NULL ? false : true;
480*61ba55bcSBaptiste Daroussin 
481*61ba55bcSBaptiste Daroussin 	return (att);
482f499134dSBaptiste Daroussin }
483c76f0793SBaptiste Daroussin 
484263660c0SAlfonso Siciliano #define NL  -1
485263660c0SAlfonso Siciliano #define WS  -2
486b319d934SAlfonso S. Siciliano #define TB  -3
487b319d934SAlfonso S. Siciliano 
488b319d934SAlfonso S. Siciliano struct textproperties {
489b319d934SAlfonso S. Siciliano 	int nword;
490b319d934SAlfonso S. Siciliano 	int *words;
491b319d934SAlfonso S. Siciliano 	uint8_t *wletters;
492b319d934SAlfonso S. Siciliano 	int maxwordcols;
493b319d934SAlfonso S. Siciliano 	int maxline;
494b319d934SAlfonso S. Siciliano 	bool hasnewline;
495b319d934SAlfonso S. Siciliano };
496b319d934SAlfonso S. Siciliano 
497b319d934SAlfonso S. Siciliano static int
498b319d934SAlfonso S. Siciliano text_properties(struct bsddialog_conf *conf, const char *text,
499b319d934SAlfonso S. Siciliano     struct textproperties *tp)
500b319d934SAlfonso S. Siciliano {
501b319d934SAlfonso S. Siciliano 	int i, l, currlinecols, maxwords, wtextlen, tablen, wordcols;
502b319d934SAlfonso S. Siciliano 	wchar_t *wtext;
503b319d934SAlfonso S. Siciliano 
504b319d934SAlfonso S. Siciliano 	tablen = (conf->text.tablen == 0) ? TABSIZE : (int)conf->text.tablen;
505c76f0793SBaptiste Daroussin 
506263660c0SAlfonso Siciliano 	maxwords = 1024;
507b319d934SAlfonso S. Siciliano 	if ((tp->words = calloc(maxwords, sizeof(int))) == NULL)
508263660c0SAlfonso Siciliano 		RETURN_ERROR("Cannot alloc memory for text autosize");
509263660c0SAlfonso Siciliano 
510b319d934SAlfonso S. Siciliano 	if ((wtext = alloc_mbstows(text)) == NULL)
511b319d934SAlfonso S. Siciliano 		RETURN_ERROR("Cannot allocate/autosize text in wchar_t*");
512b319d934SAlfonso S. Siciliano 	wtextlen = wcslen(wtext);
513b319d934SAlfonso S. Siciliano 	if ((tp->wletters = calloc(wtextlen, sizeof(uint8_t))) == NULL)
514b319d934SAlfonso S. Siciliano 		RETURN_ERROR("Cannot allocate wletters for text autosizing");
515263660c0SAlfonso Siciliano 
516b319d934SAlfonso S. Siciliano 	tp->nword = 0;
517b319d934SAlfonso S. Siciliano 	tp->maxline = 0;
518b319d934SAlfonso S. Siciliano 	tp->maxwordcols = 0;
519b319d934SAlfonso S. Siciliano 	tp->hasnewline = false;
520b319d934SAlfonso S. Siciliano 	currlinecols = 0;
521b319d934SAlfonso S. Siciliano 	wordcols = 0;
522b319d934SAlfonso S. Siciliano 	l = 0;
523b319d934SAlfonso S. Siciliano 	for (i = 0; i < wtextlen; i++) {
524*61ba55bcSBaptiste Daroussin 		if (conf->text.escape && is_wtext_attr(wtext + i)) {
525b319d934SAlfonso S. Siciliano 			i += 2; /* +1 for update statement */
526263660c0SAlfonso Siciliano 			continue;
527263660c0SAlfonso Siciliano 		}
528263660c0SAlfonso Siciliano 
529b319d934SAlfonso S. Siciliano 		if (tp->nword + 1 >= maxwords) {
530263660c0SAlfonso Siciliano 			maxwords += 1024;
531b319d934SAlfonso S. Siciliano 			tp->words = realloc(tp->words, maxwords * sizeof(int));
532b319d934SAlfonso S. Siciliano 			if (tp->words == NULL)
533263660c0SAlfonso Siciliano 				RETURN_ERROR("Cannot realloc memory for text "
534263660c0SAlfonso Siciliano 				    "autosize");
535263660c0SAlfonso Siciliano 		}
536263660c0SAlfonso Siciliano 
537b319d934SAlfonso S. Siciliano 		if (wcschr(L"\t\n  ", wtext[i]) != NULL) {
538b319d934SAlfonso S. Siciliano 			tp->maxwordcols = MAX(wordcols, tp->maxwordcols);
539b319d934SAlfonso S. Siciliano 
540b319d934SAlfonso S. Siciliano 			if (wordcols != 0) {
541b319d934SAlfonso S. Siciliano 				/* line */
542b319d934SAlfonso S. Siciliano 				currlinecols += wordcols;
543b319d934SAlfonso S. Siciliano 				/* word */
544b319d934SAlfonso S. Siciliano 				tp->words[tp->nword] = wordcols;
545b319d934SAlfonso S. Siciliano 				tp->nword += 1;
546b319d934SAlfonso S. Siciliano 				wordcols = 0;
547b319d934SAlfonso S. Siciliano 			}
548b319d934SAlfonso S. Siciliano 
549b319d934SAlfonso S. Siciliano 			switch (wtext[i]) {
550b319d934SAlfonso S. Siciliano 			case L'\t':
551b319d934SAlfonso S. Siciliano 				/* line */
552b319d934SAlfonso S. Siciliano 				currlinecols += tablen;
553b319d934SAlfonso S. Siciliano 				/* word */
554b319d934SAlfonso S. Siciliano 				tp->words[tp->nword] = TB;
555b319d934SAlfonso S. Siciliano 				break;
556b319d934SAlfonso S. Siciliano 			case L'\n':
557b319d934SAlfonso S. Siciliano 				/* line */
558b319d934SAlfonso S. Siciliano 				tp->hasnewline = true;
559b319d934SAlfonso S. Siciliano 				tp->maxline = MAX(tp->maxline, currlinecols);
560b319d934SAlfonso S. Siciliano 				currlinecols = 0;
561b319d934SAlfonso S. Siciliano 				/* word */
562b319d934SAlfonso S. Siciliano 				tp->words[tp->nword] = NL;
563b319d934SAlfonso S. Siciliano 				break;
564b319d934SAlfonso S. Siciliano 			case L' ':
565b319d934SAlfonso S. Siciliano 				/* line */
566b319d934SAlfonso S. Siciliano 				currlinecols += 1;
567b319d934SAlfonso S. Siciliano 				/* word */
568b319d934SAlfonso S. Siciliano 				tp->words[tp->nword] = WS;
569263660c0SAlfonso Siciliano 				break;
570263660c0SAlfonso Siciliano 			}
571b319d934SAlfonso S. Siciliano 			tp->nword += 1;
572263660c0SAlfonso Siciliano 		} else {
573b319d934SAlfonso S. Siciliano 			tp->wletters[l] = wcwidth(wtext[i]);
574b319d934SAlfonso S. Siciliano 			wordcols += tp->wletters[l];
575b319d934SAlfonso S. Siciliano 			l++;
576263660c0SAlfonso Siciliano 		}
577263660c0SAlfonso Siciliano 	}
578b319d934SAlfonso S. Siciliano 	/* word */
579b319d934SAlfonso S. Siciliano 	if (wordcols != 0) {
580b319d934SAlfonso S. Siciliano 		tp->words[tp->nword] = wordcols;
581b319d934SAlfonso S. Siciliano 		tp->nword += 1;
582b319d934SAlfonso S. Siciliano 		tp->maxwordcols = MAX(wordcols, tp->maxwordcols);
583b319d934SAlfonso S. Siciliano 	}
584b319d934SAlfonso S. Siciliano 	/* line */
585b319d934SAlfonso S. Siciliano 	tp->maxline = MAX(tp->maxline, currlinecols);
586263660c0SAlfonso Siciliano 
587b319d934SAlfonso S. Siciliano 	free(wtext);
588b319d934SAlfonso S. Siciliano 
589b319d934SAlfonso S. Siciliano 	return (0);
590263660c0SAlfonso Siciliano }
591263660c0SAlfonso Siciliano 
592b319d934SAlfonso S. Siciliano static int
593b319d934SAlfonso S. Siciliano text_autosize(struct bsddialog_conf *conf, struct textproperties *tp,
594b319d934SAlfonso S. Siciliano     int maxrows, int mincols, bool increasecols, int *h, int *w)
595b319d934SAlfonso S. Siciliano {
596b319d934SAlfonso S. Siciliano 	int i, j, x, y, z, l, line, maxwidth, tablen;
597b319d934SAlfonso S. Siciliano 
598*61ba55bcSBaptiste Daroussin 	maxwidth = widget_max_width(conf) - BORDERS - TEXTHMARGINS;
599b319d934SAlfonso S. Siciliano 	tablen = (conf->text.tablen == 0) ? TABSIZE : (int)conf->text.tablen;
600b319d934SAlfonso S. Siciliano 
601263660c0SAlfonso Siciliano 	if (increasecols) {
602b319d934SAlfonso S. Siciliano 		mincols = MAX(mincols, tp->maxwordcols);
603263660c0SAlfonso Siciliano 		mincols = MAX(mincols,
604*61ba55bcSBaptiste Daroussin 		    (int)conf->auto_minwidth - BORDERS - TEXTHMARGINS);
605263660c0SAlfonso Siciliano 		mincols = MIN(mincols, maxwidth);
606263660c0SAlfonso Siciliano 	}
607263660c0SAlfonso Siciliano 
608263660c0SAlfonso Siciliano 	while (true) {
609263660c0SAlfonso Siciliano 		x = 0;
610263660c0SAlfonso Siciliano 		y = 1;
611263660c0SAlfonso Siciliano 		line=0;
612b319d934SAlfonso S. Siciliano 		l = 0;
613b319d934SAlfonso S. Siciliano 		for (i = 0; i < tp->nword; i++) {
614b319d934SAlfonso S. Siciliano 			switch (tp->words[i]) {
615b319d934SAlfonso S. Siciliano 			case TB:
616b319d934SAlfonso S. Siciliano 				for (j = 0; j < tablen; j++) {
617b319d934SAlfonso S. Siciliano 					if (x >= mincols) {
618b319d934SAlfonso S. Siciliano 						x = 0;
619b319d934SAlfonso S. Siciliano 						y++;
620b319d934SAlfonso S. Siciliano 					}
621b319d934SAlfonso S. Siciliano 				x++;
622b319d934SAlfonso S. Siciliano 				}
623b319d934SAlfonso S. Siciliano 				break;
624b319d934SAlfonso S. Siciliano 			case NL:
625263660c0SAlfonso Siciliano 				y++;
626263660c0SAlfonso Siciliano 				x = 0;
627b319d934SAlfonso S. Siciliano 				break;
628b319d934SAlfonso S. Siciliano 			case WS:
629263660c0SAlfonso Siciliano 				x++;
630263660c0SAlfonso Siciliano 				if (x >= mincols) {
631263660c0SAlfonso Siciliano 					x = 0;
632263660c0SAlfonso Siciliano 					y++;
633263660c0SAlfonso Siciliano 				}
634b319d934SAlfonso S. Siciliano 				break;
635b319d934SAlfonso S. Siciliano 			default:
636b319d934SAlfonso S. Siciliano 				if (tp->words[i] + x <= mincols) {
637b319d934SAlfonso S. Siciliano 					x += tp->words[i];
638b319d934SAlfonso S. Siciliano 					for (z = 0 ; z != tp->words[i]; l++ )
639b319d934SAlfonso S. Siciliano 						z += tp->wletters[l];
640b319d934SAlfonso S. Siciliano 				} else if (tp->words[i] <= mincols) {
641263660c0SAlfonso Siciliano 					y++;
642b319d934SAlfonso S. Siciliano 					x = tp->words[i];
643b319d934SAlfonso S. Siciliano 					for (z = 0 ; z != tp->words[i]; l++ )
644b319d934SAlfonso S. Siciliano 						z += tp->wletters[l];
645b319d934SAlfonso S. Siciliano 				} else {
646b319d934SAlfonso S. Siciliano 					for (j = tp->words[i]; j > 0; ) {
647b319d934SAlfonso S. Siciliano 						y = (x == 0) ? y : y + 1;
648b319d934SAlfonso S. Siciliano 						z = 0;
649b319d934SAlfonso S. Siciliano 						while (z != j && z < mincols) {
650b319d934SAlfonso S. Siciliano 							z += tp->wletters[l];
651b319d934SAlfonso S. Siciliano 							l++;
652b319d934SAlfonso S. Siciliano 						}
653b319d934SAlfonso S. Siciliano 						x = z;
654b319d934SAlfonso S. Siciliano 						line = MAX(line, x);
655b319d934SAlfonso S. Siciliano 						j -= z;
656263660c0SAlfonso Siciliano 					}
657263660c0SAlfonso Siciliano 				}
658263660c0SAlfonso Siciliano 			}
659263660c0SAlfonso Siciliano 			line = MAX(line, x);
660263660c0SAlfonso Siciliano 		}
661263660c0SAlfonso Siciliano 
662263660c0SAlfonso Siciliano 		if (increasecols == false)
663263660c0SAlfonso Siciliano 			break;
664b319d934SAlfonso S. Siciliano 		if (mincols >= maxwidth)
665b319d934SAlfonso S. Siciliano 			break;
666b319d934SAlfonso S. Siciliano 		if (line >= y * (int)conf->text.cols_per_row && y <= maxrows)
667263660c0SAlfonso Siciliano 			break;
668263660c0SAlfonso Siciliano 		mincols++;
669263660c0SAlfonso Siciliano 	}
670263660c0SAlfonso Siciliano 
671b319d934SAlfonso S. Siciliano 	*h = (tp->nword == 0) ? 0 : y;
672263660c0SAlfonso Siciliano 	*w = MIN(mincols, line); /* wtext can be less than mincols */
673263660c0SAlfonso Siciliano 
674263660c0SAlfonso Siciliano 	return (0);
675263660c0SAlfonso Siciliano }
676263660c0SAlfonso Siciliano 
677*61ba55bcSBaptiste Daroussin static int
678263660c0SAlfonso Siciliano text_size(struct bsddialog_conf *conf, int rows, int cols, const char *text,
679263660c0SAlfonso Siciliano     struct buttons *bs, int rowsnotext, int startwtext, int *htext, int *wtext)
680263660c0SAlfonso Siciliano {
681263660c0SAlfonso Siciliano 	bool changewtext;
682b319d934SAlfonso S. Siciliano 	int wbuttons, maxhtext;
683b319d934SAlfonso S. Siciliano 	struct textproperties tp;
684263660c0SAlfonso Siciliano 
685263660c0SAlfonso Siciliano 	wbuttons = 0;
686*61ba55bcSBaptiste Daroussin 	if (bs->nbuttons > 0)
687*61ba55bcSBaptiste Daroussin 		wbuttons = buttons_min_width(bs);
688263660c0SAlfonso Siciliano 
689b319d934SAlfonso S. Siciliano 	/* Rows */
690b319d934SAlfonso S. Siciliano 	if (rows == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_FULLSCREEN) {
691*61ba55bcSBaptiste Daroussin 		maxhtext = widget_max_height(conf) - BORDERS - rowsnotext;
692b319d934SAlfonso S. Siciliano 	} else { /* fixed */
693*61ba55bcSBaptiste Daroussin 		maxhtext = rows - BORDERS - rowsnotext;
694b319d934SAlfonso S. Siciliano 	}
695*61ba55bcSBaptiste Daroussin 	if (bs->nbuttons > 0)
696b319d934SAlfonso S. Siciliano 		maxhtext -= 2;
697b319d934SAlfonso S. Siciliano 	if (maxhtext <= 0)
698b319d934SAlfonso S. Siciliano 		maxhtext = 1; /* text_autosize() computes always htext */
699b319d934SAlfonso S. Siciliano 
700b319d934SAlfonso S. Siciliano 	/* Cols */
701263660c0SAlfonso Siciliano 	if (cols == BSDDIALOG_AUTOSIZE) {
702263660c0SAlfonso Siciliano 		startwtext = MAX(startwtext, wbuttons - TEXTHMARGINS);
703263660c0SAlfonso Siciliano 		changewtext = true;
704263660c0SAlfonso Siciliano 	} else if (cols == BSDDIALOG_FULLSCREEN) {
705*61ba55bcSBaptiste Daroussin 		startwtext = widget_max_width(conf) - BORDERS - TEXTHMARGINS;
706263660c0SAlfonso Siciliano 		changewtext = false;
707263660c0SAlfonso Siciliano 	} else { /* fixed */
708*61ba55bcSBaptiste Daroussin 		startwtext = cols - BORDERS - TEXTHMARGINS;
709263660c0SAlfonso Siciliano 		changewtext = false;
710263660c0SAlfonso Siciliano 	}
711263660c0SAlfonso Siciliano 
712263660c0SAlfonso Siciliano 	if (startwtext <= 0 && changewtext)
713263660c0SAlfonso Siciliano 		startwtext = 1;
714263660c0SAlfonso Siciliano 
715b319d934SAlfonso S. Siciliano 	/* Sizing calculation */
716b319d934SAlfonso S. Siciliano 	if (text_properties(conf, text, &tp) != 0)
717b319d934SAlfonso S. Siciliano 		return (BSDDIALOG_ERROR);
718*61ba55bcSBaptiste Daroussin 	if (tp.nword > 0 && startwtext <= 0)
719*61ba55bcSBaptiste Daroussin 		RETURN_FMTERROR("(fixed cols or fullscreen) "
720*61ba55bcSBaptiste Daroussin 		    "needed at least %d cols to draw text",
721*61ba55bcSBaptiste Daroussin 		    BORDERS + TEXTHMARGINS + 1);
722b319d934SAlfonso S. Siciliano 	if (text_autosize(conf, &tp, maxhtext, startwtext, changewtext, htext,
723b319d934SAlfonso S. Siciliano 	    wtext) != 0)
724263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
725263660c0SAlfonso Siciliano 
726b319d934SAlfonso S. Siciliano 	free(tp.words);
727b319d934SAlfonso S. Siciliano 	free(tp.wletters);
728b319d934SAlfonso S. Siciliano 
729263660c0SAlfonso Siciliano 	return (0);
730263660c0SAlfonso Siciliano }
731263660c0SAlfonso Siciliano 
732*61ba55bcSBaptiste Daroussin static int
733*61ba55bcSBaptiste Daroussin widget_min_height(struct bsddialog_conf *conf, int htext, int hnotext,
734263660c0SAlfonso Siciliano     bool withbuttons)
735263660c0SAlfonso Siciliano {
736263660c0SAlfonso Siciliano 	int min;
737263660c0SAlfonso Siciliano 
738*61ba55bcSBaptiste Daroussin 	/* dialog borders */
739*61ba55bcSBaptiste Daroussin 	min = BORDERS;
740263660c0SAlfonso Siciliano 
741263660c0SAlfonso Siciliano 	/* text */
742263660c0SAlfonso Siciliano 	min += htext;
743263660c0SAlfonso Siciliano 
744*61ba55bcSBaptiste Daroussin 	/* specific widget lines without text */
745*61ba55bcSBaptiste Daroussin 	min += hnotext;
746263660c0SAlfonso Siciliano 
747*61ba55bcSBaptiste Daroussin 	/* buttons */
748*61ba55bcSBaptiste Daroussin 	if (withbuttons)
749*61ba55bcSBaptiste Daroussin 		min += HBUTTONS; /* buttons and their up-border */
750*61ba55bcSBaptiste Daroussin 
751263660c0SAlfonso Siciliano 	/* conf.auto_minheight */
752263660c0SAlfonso Siciliano 	min = MAX(min, (int)conf->auto_minheight);
753263660c0SAlfonso Siciliano 
754263660c0SAlfonso Siciliano 	return (min);
755263660c0SAlfonso Siciliano }
756263660c0SAlfonso Siciliano 
757*61ba55bcSBaptiste Daroussin static int
758263660c0SAlfonso Siciliano widget_min_width(struct bsddialog_conf *conf, int wtext, int minwidget,
759263660c0SAlfonso Siciliano     struct buttons *bs)
760263660c0SAlfonso Siciliano 
761263660c0SAlfonso Siciliano {
762b319d934SAlfonso S. Siciliano 	int min, delimtitle, wbottomtitle, wtitle;
763263660c0SAlfonso Siciliano 
764263660c0SAlfonso Siciliano 	min = 0;
765263660c0SAlfonso Siciliano 
766263660c0SAlfonso Siciliano 	/* buttons */
767*61ba55bcSBaptiste Daroussin 	if (bs->nbuttons > 0)
768*61ba55bcSBaptiste Daroussin 		min += buttons_min_width(bs);
769263660c0SAlfonso Siciliano 
770263660c0SAlfonso Siciliano 	/* text */
771263660c0SAlfonso Siciliano 	if (wtext > 0)
772263660c0SAlfonso Siciliano 		min = MAX(min, wtext + TEXTHMARGINS);
773263660c0SAlfonso Siciliano 
774263660c0SAlfonso Siciliano 	/* specific widget min width */
775263660c0SAlfonso Siciliano 	min = MAX(min, minwidget);
776263660c0SAlfonso Siciliano 
777263660c0SAlfonso Siciliano 	/* title */
778263660c0SAlfonso Siciliano 	if (conf->title != NULL) {
779263660c0SAlfonso Siciliano 		delimtitle = t.dialog.delimtitle ? 2 : 0;
780b319d934SAlfonso S. Siciliano 		wtitle = strcols(conf->title);
781b319d934SAlfonso S. Siciliano 		min = MAX(min, wtitle + 2 + delimtitle);
782263660c0SAlfonso Siciliano 	}
783263660c0SAlfonso Siciliano 
784263660c0SAlfonso Siciliano 	/* bottom title */
785b319d934SAlfonso S. Siciliano 	if (conf->bottomtitle != NULL) {
786b319d934SAlfonso S. Siciliano 		wbottomtitle = strcols(conf->bottomtitle);
787b319d934SAlfonso S. Siciliano 		min = MAX(min, wbottomtitle + 4);
788b319d934SAlfonso S. Siciliano 	}
789263660c0SAlfonso Siciliano 
790263660c0SAlfonso Siciliano 	/* dialog borders */
791*61ba55bcSBaptiste Daroussin 	min += BORDERS;
792263660c0SAlfonso Siciliano 	/* conf.auto_minwidth */
793263660c0SAlfonso Siciliano 	min = MAX(min, (int)conf->auto_minwidth);
794263660c0SAlfonso Siciliano 
795263660c0SAlfonso Siciliano 	return (min);
796c76f0793SBaptiste Daroussin }
797c76f0793SBaptiste Daroussin 
798c76f0793SBaptiste Daroussin int
799f499134dSBaptiste Daroussin set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w)
800c76f0793SBaptiste Daroussin {
801c76f0793SBaptiste Daroussin 	int maxheight, maxwidth;
802c76f0793SBaptiste Daroussin 
803c76f0793SBaptiste Daroussin 	if ((maxheight = widget_max_height(conf)) == BSDDIALOG_ERROR)
804263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
805c76f0793SBaptiste Daroussin 
806c76f0793SBaptiste Daroussin 	if (rows == BSDDIALOG_FULLSCREEN)
807c76f0793SBaptiste Daroussin 		*h = maxheight;
808c76f0793SBaptiste Daroussin 	else if (rows < BSDDIALOG_FULLSCREEN)
809c76f0793SBaptiste Daroussin 		RETURN_ERROR("Negative (less than -1) height");
81084823cc7SAlfonso S. Siciliano 	else if (rows > BSDDIALOG_AUTOSIZE) /* fixed rows */
81184823cc7SAlfonso S. Siciliano 		*h = MIN(rows, maxheight); /* rows is at most maxheight */
812c76f0793SBaptiste Daroussin 	/* rows == AUTOSIZE: each widget has to set its size */
813c76f0793SBaptiste Daroussin 
814c76f0793SBaptiste Daroussin 	if ((maxwidth = widget_max_width(conf)) == BSDDIALOG_ERROR)
815263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
816c76f0793SBaptiste Daroussin 
817c76f0793SBaptiste Daroussin 	if (cols == BSDDIALOG_FULLSCREEN)
818c76f0793SBaptiste Daroussin 		*w = maxwidth;
819c76f0793SBaptiste Daroussin 	else if (cols < BSDDIALOG_FULLSCREEN)
820c76f0793SBaptiste Daroussin 		RETURN_ERROR("Negative (less than -1) width");
82184823cc7SAlfonso S. Siciliano 	else if (cols > BSDDIALOG_AUTOSIZE) /* fixed cols */
82284823cc7SAlfonso S. Siciliano 		*w = MIN(cols, maxwidth); /* cols is at most maxwidth */
823c76f0793SBaptiste Daroussin 	/* cols == AUTOSIZE: each widget has to set its size */
824c76f0793SBaptiste Daroussin 
825263660c0SAlfonso Siciliano 	return (0);
826c76f0793SBaptiste Daroussin }
827c76f0793SBaptiste Daroussin 
828c76f0793SBaptiste Daroussin int
829*61ba55bcSBaptiste Daroussin set_widget_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
830*61ba55bcSBaptiste Daroussin     int *w, const char *text, int *rowstext, struct buttons *bs, int hnotext,
831*61ba55bcSBaptiste Daroussin     int minw)
832*61ba55bcSBaptiste Daroussin {
833*61ba55bcSBaptiste Daroussin 	int htext, wtext;
834*61ba55bcSBaptiste Daroussin 
835*61ba55bcSBaptiste Daroussin 	if (rows == BSDDIALOG_AUTOSIZE || cols == BSDDIALOG_AUTOSIZE ||
836*61ba55bcSBaptiste Daroussin 	    rowstext != NULL) {
837*61ba55bcSBaptiste Daroussin 		if (text_size(conf, rows, cols, text, bs, hnotext, minw,
838*61ba55bcSBaptiste Daroussin 		    &htext, &wtext) != 0)
839*61ba55bcSBaptiste Daroussin 			return (BSDDIALOG_ERROR);
840*61ba55bcSBaptiste Daroussin 		if (rowstext != NULL)
841*61ba55bcSBaptiste Daroussin 			*rowstext = htext;
842*61ba55bcSBaptiste Daroussin 	}
843*61ba55bcSBaptiste Daroussin 
844*61ba55bcSBaptiste Daroussin 	if (rows == BSDDIALOG_AUTOSIZE) {
845*61ba55bcSBaptiste Daroussin 		*h = widget_min_height(conf, htext, hnotext, bs->nbuttons > 0);
846*61ba55bcSBaptiste Daroussin 		*h = MIN(*h, widget_max_height(conf));
847*61ba55bcSBaptiste Daroussin 	}
848*61ba55bcSBaptiste Daroussin 
849*61ba55bcSBaptiste Daroussin 	if (cols == BSDDIALOG_AUTOSIZE) {
850*61ba55bcSBaptiste Daroussin 		*w = widget_min_width(conf, wtext, minw, bs);
851*61ba55bcSBaptiste Daroussin 		*w = MIN(*w, widget_max_width(conf));
852*61ba55bcSBaptiste Daroussin 	}
853*61ba55bcSBaptiste Daroussin 
854*61ba55bcSBaptiste Daroussin 	return (0);
855*61ba55bcSBaptiste Daroussin }
856*61ba55bcSBaptiste Daroussin 
857*61ba55bcSBaptiste Daroussin int widget_checksize(int h, int w, struct buttons *bs, int hnotext, int minw)
858*61ba55bcSBaptiste Daroussin {
859*61ba55bcSBaptiste Daroussin 	int minheight, minwidth;
860*61ba55bcSBaptiste Daroussin 
861*61ba55bcSBaptiste Daroussin 	minheight = BORDERS + hnotext;
862*61ba55bcSBaptiste Daroussin 	if (bs->nbuttons > 0)
863*61ba55bcSBaptiste Daroussin 		minheight += HBUTTONS;
864*61ba55bcSBaptiste Daroussin 	if (h < minheight)
865*61ba55bcSBaptiste Daroussin 		RETURN_FMTERROR("Current rows: %d, needed at least: %d",
866*61ba55bcSBaptiste Daroussin 		    h, minheight);
867*61ba55bcSBaptiste Daroussin 
868*61ba55bcSBaptiste Daroussin 	minwidth = 0;
869*61ba55bcSBaptiste Daroussin 	if (bs->nbuttons > 0)
870*61ba55bcSBaptiste Daroussin 		minwidth = buttons_min_width(bs);
871*61ba55bcSBaptiste Daroussin 	minwidth = MAX(minwidth, minw);
872*61ba55bcSBaptiste Daroussin 	minwidth += BORDERS;
873*61ba55bcSBaptiste Daroussin 	if (w < minwidth)
874*61ba55bcSBaptiste Daroussin 		RETURN_FMTERROR("Current cols: %d, nedeed at least %d",
875*61ba55bcSBaptiste Daroussin 		    w, minwidth);
876*61ba55bcSBaptiste Daroussin 
877*61ba55bcSBaptiste Daroussin 	return (0);
878*61ba55bcSBaptiste Daroussin }
879*61ba55bcSBaptiste Daroussin 
880*61ba55bcSBaptiste Daroussin int
881f499134dSBaptiste Daroussin set_widget_position(struct bsddialog_conf *conf, int *y, int *x, int h, int w)
882c76f0793SBaptiste Daroussin {
883b319d934SAlfonso S. Siciliano 	int hshadow = conf->shadow ? (int)t.shadow.y : 0;
884b319d934SAlfonso S. Siciliano 	int wshadow = conf->shadow ? (int)t.shadow.x : 0;
885b319d934SAlfonso S. Siciliano 
886b319d934SAlfonso S. Siciliano 	if (conf->y == BSDDIALOG_CENTER) {
887b319d934SAlfonso S. Siciliano 		*y = SCREENLINES/2 - (h + hshadow)/2;
888b319d934SAlfonso S. Siciliano 		if (*y < (int)conf->auto_topmargin)
889b319d934SAlfonso S. Siciliano 			*y = conf->auto_topmargin;
890b319d934SAlfonso S. Siciliano 		if (*y + h + hshadow > SCREENLINES - (int)conf->auto_downmargin)
891b319d934SAlfonso S. Siciliano 			*y = SCREENLINES - h - hshadow - conf->auto_downmargin;
892b319d934SAlfonso S. Siciliano 	}
893f499134dSBaptiste Daroussin 	else if (conf->y < BSDDIALOG_CENTER)
894c76f0793SBaptiste Daroussin 		RETURN_ERROR("Negative begin y (less than -1)");
895263660c0SAlfonso Siciliano 	else if (conf->y >= SCREENLINES)
896c76f0793SBaptiste Daroussin 		RETURN_ERROR("Begin Y under the terminal");
897c76f0793SBaptiste Daroussin 	else
898f499134dSBaptiste Daroussin 		*y = conf->y;
899c76f0793SBaptiste Daroussin 
900b319d934SAlfonso S. Siciliano 	if (*y + h + hshadow > SCREENLINES)
901263660c0SAlfonso Siciliano 		RETURN_ERROR("The lower of the box under the terminal "
902c76f0793SBaptiste Daroussin 		    "(begin Y + height (+ shadow) > terminal lines)");
903c76f0793SBaptiste Daroussin 
904c76f0793SBaptiste Daroussin 
905f499134dSBaptiste Daroussin 	if (conf->x == BSDDIALOG_CENTER)
906b319d934SAlfonso S. Siciliano 		*x = SCREENCOLS/2 - (w + wshadow)/2;
907f499134dSBaptiste Daroussin 	else if (conf->x < BSDDIALOG_CENTER)
908c76f0793SBaptiste Daroussin 		RETURN_ERROR("Negative begin x (less than -1)");
909263660c0SAlfonso Siciliano 	else if (conf->x >= SCREENCOLS)
910c76f0793SBaptiste Daroussin 		RETURN_ERROR("Begin X over the right of the terminal");
911c76f0793SBaptiste Daroussin 	else
912f499134dSBaptiste Daroussin 		*x = conf->x;
913c76f0793SBaptiste Daroussin 
914b319d934SAlfonso S. Siciliano 	if ((*x + w + wshadow) > SCREENCOLS)
915263660c0SAlfonso Siciliano 		RETURN_ERROR("The right of the box over the terminal "
916c76f0793SBaptiste Daroussin 		    "(begin X + width (+ shadow) > terminal cols)");
917c76f0793SBaptiste Daroussin 
918263660c0SAlfonso Siciliano 	return (0);
919c76f0793SBaptiste Daroussin }
920c76f0793SBaptiste Daroussin 
921*61ba55bcSBaptiste Daroussin int dialog_size_position(struct dialog *d, int hnotext, int minw, int *htext)
922c76f0793SBaptiste Daroussin {
923*61ba55bcSBaptiste Daroussin 	if (set_widget_size(d->conf, d->rows, d->cols, &d->h, &d->w) != 0)
924*61ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
925*61ba55bcSBaptiste Daroussin 	if (set_widget_autosize(d->conf, d->rows, d->cols, &d->h, &d->w,
926*61ba55bcSBaptiste Daroussin 	    d->text, htext, &d->bs, hnotext, minw) != 0)
927*61ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
928*61ba55bcSBaptiste Daroussin 	if (widget_checksize(d->h, d->w, &d->bs, hnotext, minw) != 0)
929*61ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
930*61ba55bcSBaptiste Daroussin 	if (set_widget_position(d->conf, &d->y, &d->x, d->h, d->w) != 0)
931*61ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
932*61ba55bcSBaptiste Daroussin 
933*61ba55bcSBaptiste Daroussin 	return (0);
934*61ba55bcSBaptiste Daroussin }
935*61ba55bcSBaptiste Daroussin 
936*61ba55bcSBaptiste Daroussin /*
937*61ba55bcSBaptiste Daroussin  * -5- Widget components and utilities
938*61ba55bcSBaptiste Daroussin  */
939*61ba55bcSBaptiste Daroussin int hide_dialog(struct dialog *d)
940*61ba55bcSBaptiste Daroussin {
941*61ba55bcSBaptiste Daroussin 	WINDOW *clear;
942*61ba55bcSBaptiste Daroussin 
943*61ba55bcSBaptiste Daroussin 	if ((clear = newwin(d->h, d->w, d->y, d->x)) == NULL)
944*61ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot hide the widget");
945*61ba55bcSBaptiste Daroussin 	wbkgd(clear, t.screen.color);
946*61ba55bcSBaptiste Daroussin 	wrefresh(clear);
947*61ba55bcSBaptiste Daroussin 
948*61ba55bcSBaptiste Daroussin 	if (d->conf->shadow) {
949*61ba55bcSBaptiste Daroussin 		mvwin(clear, d->y + t.shadow.y, d->x + t.shadow.x);
950*61ba55bcSBaptiste Daroussin 		wrefresh(clear);
951*61ba55bcSBaptiste Daroussin 	}
952*61ba55bcSBaptiste Daroussin 
953*61ba55bcSBaptiste Daroussin 	delwin(clear);
954*61ba55bcSBaptiste Daroussin 
955*61ba55bcSBaptiste Daroussin 	return (0);
956*61ba55bcSBaptiste Daroussin }
957*61ba55bcSBaptiste Daroussin 
958*61ba55bcSBaptiste Daroussin int f1help_dialog(struct bsddialog_conf *conf)
959*61ba55bcSBaptiste Daroussin {
960*61ba55bcSBaptiste Daroussin 	int output;
961*61ba55bcSBaptiste Daroussin 	struct bsddialog_conf hconf;
962*61ba55bcSBaptiste Daroussin 
963*61ba55bcSBaptiste Daroussin 	bsddialog_initconf(&hconf);
964*61ba55bcSBaptiste Daroussin 	hconf.title           = "HELP";
965*61ba55bcSBaptiste Daroussin 	hconf.button.ok_label = "EXIT";
966*61ba55bcSBaptiste Daroussin 	hconf.clear           = true;
967*61ba55bcSBaptiste Daroussin 	hconf.ascii_lines     = conf->ascii_lines;
968*61ba55bcSBaptiste Daroussin 	hconf.no_lines        = conf->no_lines;
969*61ba55bcSBaptiste Daroussin 	hconf.shadow          = conf->shadow;
970*61ba55bcSBaptiste Daroussin 	hconf.text.escape     = conf->text.escape;
971*61ba55bcSBaptiste Daroussin 
972*61ba55bcSBaptiste Daroussin 	output = BSDDIALOG_OK;
973*61ba55bcSBaptiste Daroussin 	if (conf->key.f1_message != NULL)
974*61ba55bcSBaptiste Daroussin 		output = bsddialog_msgbox(&hconf, conf->key.f1_message, 0, 0);
975*61ba55bcSBaptiste Daroussin 
976*61ba55bcSBaptiste Daroussin 	if (output != BSDDIALOG_ERROR && conf->key.f1_file != NULL)
977*61ba55bcSBaptiste Daroussin 		output = bsddialog_textbox(&hconf, conf->key.f1_file, 0, 0);
978*61ba55bcSBaptiste Daroussin 
979*61ba55bcSBaptiste Daroussin 	return (output == BSDDIALOG_ERROR ? BSDDIALOG_ERROR : 0);
980*61ba55bcSBaptiste Daroussin }
981*61ba55bcSBaptiste Daroussin 
982*61ba55bcSBaptiste Daroussin void draw_borders(struct bsddialog_conf *conf, WINDOW *win, enum elevation elev)
983*61ba55bcSBaptiste Daroussin {
984*61ba55bcSBaptiste Daroussin 	int h, w;
985c76f0793SBaptiste Daroussin 	int leftcolor, rightcolor;
986263660c0SAlfonso Siciliano 	int ls, rs, ts, bs, tl, tr, bl, br, ltee, rtee;
987c76f0793SBaptiste Daroussin 
988263660c0SAlfonso Siciliano 	if (conf->no_lines)
989263660c0SAlfonso Siciliano 		return;
990263660c0SAlfonso Siciliano 
991263660c0SAlfonso Siciliano 	if (conf->ascii_lines) {
992263660c0SAlfonso Siciliano 		ls = rs = '|';
993263660c0SAlfonso Siciliano 		ts = bs = '-';
994263660c0SAlfonso Siciliano 		tl = tr = bl = br = ltee = rtee = '+';
995263660c0SAlfonso Siciliano 	} else {
996c76f0793SBaptiste Daroussin 		ls = rs = ACS_VLINE;
997c76f0793SBaptiste Daroussin 		ts = bs = ACS_HLINE;
998c76f0793SBaptiste Daroussin 		tl = ACS_ULCORNER;
999c76f0793SBaptiste Daroussin 		tr = ACS_URCORNER;
1000c76f0793SBaptiste Daroussin 		bl = ACS_LLCORNER;
1001c76f0793SBaptiste Daroussin 		br = ACS_LRCORNER;
1002c76f0793SBaptiste Daroussin 		ltee = ACS_LTEE;
1003c76f0793SBaptiste Daroussin 		rtee = ACS_RTEE;
1004c76f0793SBaptiste Daroussin 	}
1005263660c0SAlfonso Siciliano 
1006*61ba55bcSBaptiste Daroussin 	getmaxyx(win, h, w);
10078c4f4028SBaptiste Daroussin 	leftcolor = elev == RAISED ?
10088c4f4028SBaptiste Daroussin 	    t.dialog.lineraisecolor : t.dialog.linelowercolor;
10098c4f4028SBaptiste Daroussin 	rightcolor = elev == RAISED ?
10108c4f4028SBaptiste Daroussin 	    t.dialog.linelowercolor : t.dialog.lineraisecolor;
1011*61ba55bcSBaptiste Daroussin 
1012c76f0793SBaptiste Daroussin 	wattron(win, leftcolor);
1013c76f0793SBaptiste Daroussin 	wborder(win, ls, rs, ts, bs, tl, tr, bl, br);
1014c76f0793SBaptiste Daroussin 	wattroff(win, leftcolor);
1015c76f0793SBaptiste Daroussin 
1016c76f0793SBaptiste Daroussin 	wattron(win, rightcolor);
1017*61ba55bcSBaptiste Daroussin 	mvwaddch(win, 0, w-1, tr);
1018*61ba55bcSBaptiste Daroussin 	mvwvline(win, 1, w-1, rs, h-2);
1019*61ba55bcSBaptiste Daroussin 	mvwaddch(win, h-1, w-1, br);
1020*61ba55bcSBaptiste Daroussin 	mvwhline(win, h-1, 1, bs, w-2);
1021c76f0793SBaptiste Daroussin 	wattroff(win, rightcolor);
1022c76f0793SBaptiste Daroussin }
1023c76f0793SBaptiste Daroussin 
1024*61ba55bcSBaptiste Daroussin void
1025*61ba55bcSBaptiste Daroussin update_box(struct bsddialog_conf *conf, WINDOW *win, int y, int x, int h, int w,
1026c76f0793SBaptiste Daroussin     enum elevation elev)
1027c76f0793SBaptiste Daroussin {
1028*61ba55bcSBaptiste Daroussin 	wclear(win);
1029*61ba55bcSBaptiste Daroussin 	wresize(win, h, w);
1030*61ba55bcSBaptiste Daroussin 	mvwin(win, y, x);
1031*61ba55bcSBaptiste Daroussin 	draw_borders(conf, win, elev);
1032c76f0793SBaptiste Daroussin }
1033c76f0793SBaptiste Daroussin 
1034*61ba55bcSBaptiste Daroussin void
1035*61ba55bcSBaptiste Daroussin rtextpad(struct dialog *d, int ytext, int xtext, int upnotext, int downnotext)
1036*61ba55bcSBaptiste Daroussin {
1037*61ba55bcSBaptiste Daroussin 	pnoutrefresh(d->textpad, ytext, xtext,
1038*61ba55bcSBaptiste Daroussin 	    d->y + BORDER + upnotext,
1039*61ba55bcSBaptiste Daroussin 	    d->x + BORDER + TEXTHMARGIN,
1040*61ba55bcSBaptiste Daroussin 	    d->y + d->h - 1 - downnotext - BORDER,
1041*61ba55bcSBaptiste Daroussin 	    d->x + d->w - TEXTHMARGIN - BORDER);
1042*61ba55bcSBaptiste Daroussin }
1043c76f0793SBaptiste Daroussin 
1044*61ba55bcSBaptiste Daroussin /*
1045*61ba55bcSBaptiste Daroussin  * -6- Dialog init/build, update/draw, destroy
1046*61ba55bcSBaptiste Daroussin  */
1047*61ba55bcSBaptiste Daroussin void end_dialog(struct dialog *d)
1048*61ba55bcSBaptiste Daroussin {
1049*61ba55bcSBaptiste Daroussin 	if (d->conf->sleep > 0)
1050*61ba55bcSBaptiste Daroussin 		sleep(d->conf->sleep);
1051c76f0793SBaptiste Daroussin 
1052*61ba55bcSBaptiste Daroussin 	delwin(d->textpad);
1053*61ba55bcSBaptiste Daroussin 	delwin(d->widget);
1054*61ba55bcSBaptiste Daroussin 	if (d->conf->shadow)
1055*61ba55bcSBaptiste Daroussin 		delwin(d->shadow);
1056*61ba55bcSBaptiste Daroussin 
1057*61ba55bcSBaptiste Daroussin 	if (d->conf->clear)
1058*61ba55bcSBaptiste Daroussin 		hide_dialog(d);
1059*61ba55bcSBaptiste Daroussin 
1060*61ba55bcSBaptiste Daroussin 	if (d->conf->get_height != NULL)
1061*61ba55bcSBaptiste Daroussin 		*d->conf->get_height = d->h;
1062*61ba55bcSBaptiste Daroussin 	if (d->conf->get_width != NULL)
1063*61ba55bcSBaptiste Daroussin 		*d->conf->get_width = d->w;
1064*61ba55bcSBaptiste Daroussin }
1065*61ba55bcSBaptiste Daroussin 
1066*61ba55bcSBaptiste Daroussin static bool check_set_wtext_attr(WINDOW *win, wchar_t *wtext)
1067*61ba55bcSBaptiste Daroussin {
1068*61ba55bcSBaptiste Daroussin 	enum bsddialog_color bg;
1069*61ba55bcSBaptiste Daroussin 
1070*61ba55bcSBaptiste Daroussin 	if (is_wtext_attr(wtext) == false)
1071*61ba55bcSBaptiste Daroussin 		return (false);
1072*61ba55bcSBaptiste Daroussin 
1073*61ba55bcSBaptiste Daroussin 	if ((wtext[2] >= L'0') && (wtext[2] <= L'7')) {
1074*61ba55bcSBaptiste Daroussin 		bsddialog_color_attrs(t.dialog.color, NULL, &bg, NULL);
1075*61ba55bcSBaptiste Daroussin 		wattron(win, bsddialog_color(wtext[2] - L'0', bg, 0));
1076*61ba55bcSBaptiste Daroussin 		return (true);
1077*61ba55bcSBaptiste Daroussin 	}
1078*61ba55bcSBaptiste Daroussin 
1079*61ba55bcSBaptiste Daroussin 	switch (wtext[2]) {
1080*61ba55bcSBaptiste Daroussin 	case L'n':
1081*61ba55bcSBaptiste Daroussin 		wattron(win, t.dialog.color);
1082*61ba55bcSBaptiste Daroussin 		wattrset(win, A_NORMAL);
1083*61ba55bcSBaptiste Daroussin 		break;
1084*61ba55bcSBaptiste Daroussin 	case L'b':
1085*61ba55bcSBaptiste Daroussin 		wattron(win, A_BOLD);
1086*61ba55bcSBaptiste Daroussin 		break;
1087*61ba55bcSBaptiste Daroussin 	case L'B':
1088*61ba55bcSBaptiste Daroussin 		wattroff(win, A_BOLD);
1089*61ba55bcSBaptiste Daroussin 		break;
1090*61ba55bcSBaptiste Daroussin 	case L'd':
1091*61ba55bcSBaptiste Daroussin 		wattron(win, A_DIM);
1092*61ba55bcSBaptiste Daroussin 		break;
1093*61ba55bcSBaptiste Daroussin 	case L'D':
1094*61ba55bcSBaptiste Daroussin 		wattroff(win, A_DIM);
1095*61ba55bcSBaptiste Daroussin 		break;
1096*61ba55bcSBaptiste Daroussin 	case L'k':
1097*61ba55bcSBaptiste Daroussin 		wattron(win, A_BLINK);
1098*61ba55bcSBaptiste Daroussin 		break;
1099*61ba55bcSBaptiste Daroussin 	case L'K':
1100*61ba55bcSBaptiste Daroussin 		wattroff(win, A_BLINK);
1101*61ba55bcSBaptiste Daroussin 		break;
1102*61ba55bcSBaptiste Daroussin 	case L'r':
1103*61ba55bcSBaptiste Daroussin 		wattron(win, A_REVERSE);
1104*61ba55bcSBaptiste Daroussin 		break;
1105*61ba55bcSBaptiste Daroussin 	case L'R':
1106*61ba55bcSBaptiste Daroussin 		wattroff(win, A_REVERSE);
1107*61ba55bcSBaptiste Daroussin 		break;
1108*61ba55bcSBaptiste Daroussin 	case L's':
1109*61ba55bcSBaptiste Daroussin 		wattron(win, A_STANDOUT);
1110*61ba55bcSBaptiste Daroussin 		break;
1111*61ba55bcSBaptiste Daroussin 	case L'S':
1112*61ba55bcSBaptiste Daroussin 		wattroff(win, A_STANDOUT);
1113*61ba55bcSBaptiste Daroussin 		break;
1114*61ba55bcSBaptiste Daroussin 	case L'u':
1115*61ba55bcSBaptiste Daroussin 		wattron(win, A_UNDERLINE);
1116*61ba55bcSBaptiste Daroussin 		break;
1117*61ba55bcSBaptiste Daroussin 	case L'U':
1118*61ba55bcSBaptiste Daroussin 		wattroff(win, A_UNDERLINE);
1119*61ba55bcSBaptiste Daroussin 		break;
1120*61ba55bcSBaptiste Daroussin 	}
1121*61ba55bcSBaptiste Daroussin 
1122*61ba55bcSBaptiste Daroussin 	return (true);
1123*61ba55bcSBaptiste Daroussin }
1124*61ba55bcSBaptiste Daroussin 
1125*61ba55bcSBaptiste Daroussin static void
1126*61ba55bcSBaptiste Daroussin print_string(WINDOW *win, int *rows, int cols, int *y, int *x, wchar_t *str,
1127*61ba55bcSBaptiste Daroussin     bool color)
1128*61ba55bcSBaptiste Daroussin {
1129*61ba55bcSBaptiste Daroussin 	int i, j, len, reallen, wc;
1130*61ba55bcSBaptiste Daroussin 	wchar_t ws[2];
1131*61ba55bcSBaptiste Daroussin 
1132*61ba55bcSBaptiste Daroussin 	ws[1] = L'\0';
1133*61ba55bcSBaptiste Daroussin 
1134*61ba55bcSBaptiste Daroussin 	len = wcslen(str);
1135*61ba55bcSBaptiste Daroussin 	if (color) {
1136*61ba55bcSBaptiste Daroussin 		reallen = 0;
1137*61ba55bcSBaptiste Daroussin 		i=0;
1138*61ba55bcSBaptiste Daroussin 		while (i < len) {
1139*61ba55bcSBaptiste Daroussin 			if (is_wtext_attr(str+i) == false) {
1140*61ba55bcSBaptiste Daroussin 				reallen += wcwidth(str[i]);
1141*61ba55bcSBaptiste Daroussin 				i++;
1142*61ba55bcSBaptiste Daroussin 			} else {
1143*61ba55bcSBaptiste Daroussin 				i +=3 ;
1144*61ba55bcSBaptiste Daroussin 			}
1145*61ba55bcSBaptiste Daroussin 		}
1146*61ba55bcSBaptiste Daroussin 	} else
1147*61ba55bcSBaptiste Daroussin 		reallen = wcswidth(str, len);
1148*61ba55bcSBaptiste Daroussin 
1149*61ba55bcSBaptiste Daroussin 	i = 0;
1150*61ba55bcSBaptiste Daroussin 	while (i < len) {
1151*61ba55bcSBaptiste Daroussin 		if (*x + reallen > cols) {
1152*61ba55bcSBaptiste Daroussin 			*y = (*x != 0 ? *y+1 : *y);
1153*61ba55bcSBaptiste Daroussin 			if (*y >= *rows) {
1154*61ba55bcSBaptiste Daroussin 				*rows = *y + 1;
1155*61ba55bcSBaptiste Daroussin 				wresize(win, *rows, cols);
1156*61ba55bcSBaptiste Daroussin 			}
1157*61ba55bcSBaptiste Daroussin 			*x = 0;
1158*61ba55bcSBaptiste Daroussin 		}
1159*61ba55bcSBaptiste Daroussin 		j = *x;
1160*61ba55bcSBaptiste Daroussin 		while (j < cols && i < len) {
1161*61ba55bcSBaptiste Daroussin 			if (color && check_set_wtext_attr(win, str+i)) {
1162*61ba55bcSBaptiste Daroussin 				i += 3;
1163*61ba55bcSBaptiste Daroussin 			} else if (j + wcwidth(str[i]) > cols) {
1164*61ba55bcSBaptiste Daroussin 				break;
1165*61ba55bcSBaptiste Daroussin 			} else {
1166*61ba55bcSBaptiste Daroussin 				/* inline mvwaddwch() for efficiency */
1167*61ba55bcSBaptiste Daroussin 				ws[0] = str[i];
1168*61ba55bcSBaptiste Daroussin 				mvwaddwstr(win, *y, j, ws);
1169*61ba55bcSBaptiste Daroussin 				wc = wcwidth(str[i]);;
1170*61ba55bcSBaptiste Daroussin 				reallen -= wc;
1171*61ba55bcSBaptiste Daroussin 				j += wc;
1172*61ba55bcSBaptiste Daroussin 				i++;
1173*61ba55bcSBaptiste Daroussin 				*x = j;
1174*61ba55bcSBaptiste Daroussin 			}
1175*61ba55bcSBaptiste Daroussin 		}
1176*61ba55bcSBaptiste Daroussin 	}
1177c76f0793SBaptiste Daroussin }
1178c76f0793SBaptiste Daroussin 
1179c76f0793SBaptiste Daroussin static int
1180*61ba55bcSBaptiste Daroussin print_textpad(struct bsddialog_conf *conf, WINDOW *pad, const char *text)
1181c76f0793SBaptiste Daroussin {
1182*61ba55bcSBaptiste Daroussin 	bool loop;
1183*61ba55bcSBaptiste Daroussin 	int i, j, z, rows, cols, x, y, tablen;
1184*61ba55bcSBaptiste Daroussin 	wchar_t *wtext, *string;
1185c76f0793SBaptiste Daroussin 
1186*61ba55bcSBaptiste Daroussin 	if ((wtext = alloc_mbstows(text)) == NULL)
1187*61ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot allocate/print text in wchar_t*");
1188263660c0SAlfonso Siciliano 
1189*61ba55bcSBaptiste Daroussin 	if ((string = calloc(wcslen(wtext) + 1, sizeof(wchar_t))) == NULL)
1190*61ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot build (analyze) text");
1191c76f0793SBaptiste Daroussin 
1192*61ba55bcSBaptiste Daroussin 	getmaxyx(pad, rows, cols);
1193*61ba55bcSBaptiste Daroussin 	tablen = (conf->text.tablen == 0) ? TABSIZE : (int)conf->text.tablen;
1194c76f0793SBaptiste Daroussin 
1195*61ba55bcSBaptiste Daroussin 	i = j = x = y = 0;
1196*61ba55bcSBaptiste Daroussin 	loop = true;
1197*61ba55bcSBaptiste Daroussin 	while (loop) {
1198*61ba55bcSBaptiste Daroussin 		string[j] = wtext[i];
1199c76f0793SBaptiste Daroussin 
1200*61ba55bcSBaptiste Daroussin 		if (wcschr(L"\n\t  ", string[j]) != NULL || string[j] == L'\0') {
1201*61ba55bcSBaptiste Daroussin 			string[j] = L'\0';
1202*61ba55bcSBaptiste Daroussin 			print_string(pad, &rows, cols, &y, &x, string,
1203*61ba55bcSBaptiste Daroussin 			    conf->text.escape);
1204*61ba55bcSBaptiste Daroussin 		}
1205*61ba55bcSBaptiste Daroussin 
1206*61ba55bcSBaptiste Daroussin 		switch (wtext[i]) {
1207*61ba55bcSBaptiste Daroussin 		case L'\0':
1208*61ba55bcSBaptiste Daroussin 			loop = false;
1209*61ba55bcSBaptiste Daroussin 			break;
1210*61ba55bcSBaptiste Daroussin 		case L'\n':
1211*61ba55bcSBaptiste Daroussin 			x = 0;
1212*61ba55bcSBaptiste Daroussin 			y++;
1213*61ba55bcSBaptiste Daroussin 			j = -1;
1214*61ba55bcSBaptiste Daroussin 			break;
1215*61ba55bcSBaptiste Daroussin 		case L'\t':
1216*61ba55bcSBaptiste Daroussin 			for (z = 0; z < tablen; z++) {
1217*61ba55bcSBaptiste Daroussin 				if (x >= cols) {
1218*61ba55bcSBaptiste Daroussin 					x = 0;
1219*61ba55bcSBaptiste Daroussin 					y++;
1220*61ba55bcSBaptiste Daroussin 				}
1221*61ba55bcSBaptiste Daroussin 				x++;
1222*61ba55bcSBaptiste Daroussin 			}
1223*61ba55bcSBaptiste Daroussin 			j = -1;
1224*61ba55bcSBaptiste Daroussin 			break;
1225*61ba55bcSBaptiste Daroussin 		case L' ':
1226*61ba55bcSBaptiste Daroussin 			x++;
1227*61ba55bcSBaptiste Daroussin 			if (x >= cols) {
1228*61ba55bcSBaptiste Daroussin 				x = 0;
1229*61ba55bcSBaptiste Daroussin 				y++;
1230*61ba55bcSBaptiste Daroussin 			}
1231*61ba55bcSBaptiste Daroussin 			j = -1;
1232*61ba55bcSBaptiste Daroussin 		}
1233*61ba55bcSBaptiste Daroussin 
1234*61ba55bcSBaptiste Daroussin 		if (y >= rows) {
1235*61ba55bcSBaptiste Daroussin 			rows = y + 1;
1236*61ba55bcSBaptiste Daroussin 			wresize(pad, rows, cols);
1237*61ba55bcSBaptiste Daroussin 		}
1238*61ba55bcSBaptiste Daroussin 
1239*61ba55bcSBaptiste Daroussin 		j++;
1240*61ba55bcSBaptiste Daroussin 		i++;
1241*61ba55bcSBaptiste Daroussin 	}
1242*61ba55bcSBaptiste Daroussin 
1243*61ba55bcSBaptiste Daroussin 	free(wtext);
1244*61ba55bcSBaptiste Daroussin 	free(string);
1245*61ba55bcSBaptiste Daroussin 
1246*61ba55bcSBaptiste Daroussin 	return (0);
1247*61ba55bcSBaptiste Daroussin }
1248*61ba55bcSBaptiste Daroussin 
1249*61ba55bcSBaptiste Daroussin int draw_dialog(struct dialog *d)
1250*61ba55bcSBaptiste Daroussin {
1251*61ba55bcSBaptiste Daroussin 	int wtitle, wbottomtitle, ts, ltee, rtee;
1252*61ba55bcSBaptiste Daroussin 
1253*61ba55bcSBaptiste Daroussin 	ts   = d->conf->ascii_lines ? '-' : ACS_HLINE;
1254*61ba55bcSBaptiste Daroussin 	ltee = d->conf->ascii_lines ? '+' : ACS_LTEE;
1255*61ba55bcSBaptiste Daroussin 	rtee = d->conf->ascii_lines ? '+' : ACS_RTEE;
1256*61ba55bcSBaptiste Daroussin 
1257*61ba55bcSBaptiste Daroussin 	if (d->conf->shadow) {
1258*61ba55bcSBaptiste Daroussin 		wclear(d->shadow);
1259*61ba55bcSBaptiste Daroussin 		wresize(d->shadow, d->h, d->w);
1260*61ba55bcSBaptiste Daroussin 		mvwin(d->shadow, d->y + t.shadow.y, d->x + t.shadow.x);
1261*61ba55bcSBaptiste Daroussin 		wnoutrefresh(d->shadow);
1262*61ba55bcSBaptiste Daroussin 	}
1263*61ba55bcSBaptiste Daroussin 
1264*61ba55bcSBaptiste Daroussin 	wclear(d->widget);
1265*61ba55bcSBaptiste Daroussin 	wresize(d->widget, d->h, d->w);
1266*61ba55bcSBaptiste Daroussin 	mvwin(d->widget, d->y, d->x);
1267*61ba55bcSBaptiste Daroussin 	draw_borders(d->conf, d->widget, RAISED);
1268*61ba55bcSBaptiste Daroussin 
1269*61ba55bcSBaptiste Daroussin 	if (d->conf->title != NULL) {
1270*61ba55bcSBaptiste Daroussin 		if ((wtitle = strcols(d->conf->title)) < 0)
1271b319d934SAlfonso S. Siciliano 			return (BSDDIALOG_ERROR);
1272*61ba55bcSBaptiste Daroussin 		if (t.dialog.delimtitle && d->conf->no_lines == false) {
1273*61ba55bcSBaptiste Daroussin 			wattron(d->widget, t.dialog.lineraisecolor);
1274*61ba55bcSBaptiste Daroussin 			mvwaddch(d->widget, 0, d->w/2 - wtitle/2 -1, rtee);
1275*61ba55bcSBaptiste Daroussin 			wattroff(d->widget, t.dialog.lineraisecolor);
1276c76f0793SBaptiste Daroussin 		}
1277*61ba55bcSBaptiste Daroussin 		wattron(d->widget, t.dialog.titlecolor);
1278*61ba55bcSBaptiste Daroussin 		mvwaddstr(d->widget, 0, d->w/2 - wtitle/2, d->conf->title);
1279*61ba55bcSBaptiste Daroussin 		wattroff(d->widget, t.dialog.titlecolor);
1280*61ba55bcSBaptiste Daroussin 		if (t.dialog.delimtitle && d->conf->no_lines == false) {
1281*61ba55bcSBaptiste Daroussin 			wattron(d->widget, t.dialog.lineraisecolor);
1282*61ba55bcSBaptiste Daroussin 			waddch(d->widget, ltee);
1283*61ba55bcSBaptiste Daroussin 			wattroff(d->widget, t.dialog.lineraisecolor);
1284c76f0793SBaptiste Daroussin 		}
1285c76f0793SBaptiste Daroussin 	}
1286c76f0793SBaptiste Daroussin 
1287*61ba55bcSBaptiste Daroussin 	if (d->bs.nbuttons > 0) {
1288*61ba55bcSBaptiste Daroussin 		if (d->conf->no_lines == false) {
1289*61ba55bcSBaptiste Daroussin 			wattron(d->widget, t.dialog.lineraisecolor);
1290*61ba55bcSBaptiste Daroussin 			mvwaddch(d->widget, d->h-3, 0, ltee);
1291*61ba55bcSBaptiste Daroussin 			mvwhline(d->widget, d->h-3, 1, ts, d->w-2);
1292*61ba55bcSBaptiste Daroussin 			wattroff(d->widget, t.dialog.lineraisecolor);
1293c76f0793SBaptiste Daroussin 
1294*61ba55bcSBaptiste Daroussin 			wattron(d->widget, t.dialog.linelowercolor);
1295*61ba55bcSBaptiste Daroussin 			mvwaddch(d->widget, d->h-3, d->w-1, rtee);
1296*61ba55bcSBaptiste Daroussin 			wattroff(d->widget, t.dialog.linelowercolor);
1297c76f0793SBaptiste Daroussin 		}
1298*61ba55bcSBaptiste Daroussin 		draw_buttons(d);
1299263660c0SAlfonso Siciliano 	}
1300263660c0SAlfonso Siciliano 
1301*61ba55bcSBaptiste Daroussin 	if (d->conf->bottomtitle != NULL) {
1302*61ba55bcSBaptiste Daroussin 		if ((wbottomtitle = strcols(d->conf->bottomtitle)) < 0)
1303b319d934SAlfonso S. Siciliano 			return (BSDDIALOG_ERROR);
1304*61ba55bcSBaptiste Daroussin 		wattron(d->widget, t.dialog.bottomtitlecolor);
1305*61ba55bcSBaptiste Daroussin 		wmove(d->widget, d->h - 1, d->w/2 - wbottomtitle/2 - 1);
1306*61ba55bcSBaptiste Daroussin 		waddch(d->widget, ' ');
1307*61ba55bcSBaptiste Daroussin 		waddstr(d->widget, d->conf->bottomtitle);
1308*61ba55bcSBaptiste Daroussin 		waddch(d->widget, ' ');
1309*61ba55bcSBaptiste Daroussin 		wattroff(d->widget, t.dialog.bottomtitlecolor);
1310263660c0SAlfonso Siciliano 	}
1311c76f0793SBaptiste Daroussin 
1312*61ba55bcSBaptiste Daroussin 	wnoutrefresh(d->widget);
1313c76f0793SBaptiste Daroussin 
1314*61ba55bcSBaptiste Daroussin 	wclear(d->textpad);
1315*61ba55bcSBaptiste Daroussin 	/* `infobox "" 0 2` fails but text is empty and textpad remains 1 1 */
1316*61ba55bcSBaptiste Daroussin 	wresize(d->textpad, 1, d->w - BORDERS - TEXTHMARGINS);
1317*61ba55bcSBaptiste Daroussin 
1318*61ba55bcSBaptiste Daroussin 	if (print_textpad(d->conf, d->textpad, d->text) != 0)
1319263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
1320c76f0793SBaptiste Daroussin 
1321*61ba55bcSBaptiste Daroussin 	d->built = true;
1322*61ba55bcSBaptiste Daroussin 
1323263660c0SAlfonso Siciliano 	return (0);
1324c76f0793SBaptiste Daroussin }
1325c76f0793SBaptiste Daroussin 
1326c76f0793SBaptiste Daroussin int
1327*61ba55bcSBaptiste Daroussin prepare_dialog(struct bsddialog_conf *conf, const char *text, int rows,
1328*61ba55bcSBaptiste Daroussin     int cols, struct dialog *d)
1329c76f0793SBaptiste Daroussin {
1330*61ba55bcSBaptiste Daroussin 	CHECK_PTR(conf);
1331c76f0793SBaptiste Daroussin 
1332*61ba55bcSBaptiste Daroussin 	d->built = false;
1333*61ba55bcSBaptiste Daroussin 	d->conf = conf;
1334*61ba55bcSBaptiste Daroussin 	d->rows = rows;
1335*61ba55bcSBaptiste Daroussin 	d->cols = cols;
1336*61ba55bcSBaptiste Daroussin 	d->text = CHECK_STR(text);
1337*61ba55bcSBaptiste Daroussin 	d->bs.nbuttons = 0;
1338*61ba55bcSBaptiste Daroussin 
1339*61ba55bcSBaptiste Daroussin 	if (d->conf->shadow) {
1340*61ba55bcSBaptiste Daroussin 		if ((d->shadow = newwin(1, 1, 1, 1)) == NULL)
1341*61ba55bcSBaptiste Daroussin 			RETURN_ERROR("Cannot build WINDOW shadow");
1342*61ba55bcSBaptiste Daroussin 		wbkgd(d->shadow, t.shadow.color);
1343c76f0793SBaptiste Daroussin 	}
1344c76f0793SBaptiste Daroussin 
1345*61ba55bcSBaptiste Daroussin 	if ((d->widget = newwin(1, 1, 1, 1)) == NULL)
1346*61ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot build WINDOW widget");
1347*61ba55bcSBaptiste Daroussin 	wbkgd(d->widget, t.dialog.color);
1348263660c0SAlfonso Siciliano 
1349*61ba55bcSBaptiste Daroussin 	/* fake for textpad */
1350*61ba55bcSBaptiste Daroussin 	if ((d->textpad = newpad(1, 1)) == NULL)
1351*61ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot build the pad WINDOW for text");
1352*61ba55bcSBaptiste Daroussin 	wbkgd(d->textpad, t.dialog.color);
1353263660c0SAlfonso Siciliano 
1354*61ba55bcSBaptiste Daroussin 	return (0);
1355c76f0793SBaptiste Daroussin }