xref: /freebsd-src/contrib/bsddialog/lib/lib_util.c (revision a6d8be451f62d425b71a4874f7d4e133b9fb393c)
1c76f0793SBaptiste Daroussin /*-
2c76f0793SBaptiste Daroussin  * SPDX-License-Identifier: BSD-2-Clause
3c76f0793SBaptiste Daroussin  *
461ba55bcSBaptiste 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 
3861ba55bcSBaptiste Daroussin /*
3961ba55bcSBaptiste Daroussin  * -1- Error and diagnostic
4061ba55bcSBaptiste Daroussin  *
4161ba55bcSBaptiste Daroussin  *	get_error_string();
4261ba55bcSBaptiste Daroussin  *	set_error_string();
4361ba55bcSBaptiste Daroussin  *	set_fmt_error_string();
4461ba55bcSBaptiste Daroussin  *
4561ba55bcSBaptiste Daroussin  * ----------------------------------------------------
4661ba55bcSBaptiste Daroussin  * -2- (Unicode) Multicolumn character strings
4761ba55bcSBaptiste Daroussin  *
4861ba55bcSBaptiste Daroussin  *	alloc_mbstows();
4961ba55bcSBaptiste Daroussin  *	mvwaddwch();
5061ba55bcSBaptiste Daroussin  *	str_props();
5161ba55bcSBaptiste Daroussin  *	strcols();
5261ba55bcSBaptiste Daroussin  *
5361ba55bcSBaptiste Daroussin  * ----------------------------------------------------
5461ba55bcSBaptiste Daroussin  * -3- Buttons
5561ba55bcSBaptiste Daroussin  *
5661ba55bcSBaptiste Daroussin  * [static] buttons_min_width();
5761ba55bcSBaptiste Daroussin  * [static] draw_button();
5861ba55bcSBaptiste Daroussin  *          draw_buttons();
5961ba55bcSBaptiste Daroussin  *          set_buttons(); (to call 1 time after prepare_dialog()).
6061ba55bcSBaptiste Daroussin  *          shortcut_buttons();
6161ba55bcSBaptiste Daroussin  *
6261ba55bcSBaptiste Daroussin  * ----------------------------------------------------
6361ba55bcSBaptiste Daroussin  * -4- (Auto) Sizing and (Auto) Position
6461ba55bcSBaptiste Daroussin  *
6561ba55bcSBaptiste Daroussin  * [static] widget_max_height(conf);
6661ba55bcSBaptiste Daroussin  * [static] widget_max_width(struct bsddialog_conf *conf)
6761ba55bcSBaptiste Daroussin  * [static] is_wtext_attr();
6861ba55bcSBaptiste Daroussin  * [static] text_properties();
6961ba55bcSBaptiste Daroussin  * [static] text_autosize();
7061ba55bcSBaptiste Daroussin  * [static] text_size();
7161ba55bcSBaptiste Daroussin  * [static] widget_min_height(conf, htext, hnotext, bool buttons);
7261ba55bcSBaptiste Daroussin  * [static] widget_min_width(conf, wtext, minw, buttons);
7361ba55bcSBaptiste Daroussin  *          set_widget_size();
7461ba55bcSBaptiste Daroussin  *          set_widget_autosize();  (not for all dialogs).
7561ba55bcSBaptiste Daroussin  *          widget_checksize();     (not for all dialogs).
7661ba55bcSBaptiste Daroussin  *          set_widget_position();
7761ba55bcSBaptiste Daroussin  *          dialog_size_position(struct dialog); (not for all dialogs).
7861ba55bcSBaptiste Daroussin  *
7961ba55bcSBaptiste Daroussin  * ----------------------------------------------------
8061ba55bcSBaptiste Daroussin  * -5- (Dialog) Widget components and utils
8161ba55bcSBaptiste Daroussin  *
8261ba55bcSBaptiste Daroussin  *	hide_dialog(struct dialog);
8361ba55bcSBaptiste Daroussin  *	f1help_dialog(conf);
8461ba55bcSBaptiste Daroussin  *	draw_borders(conf, win, elev);
8561ba55bcSBaptiste Daroussin  *	update_box(conf, win, y, x, h, w, elev);
8661ba55bcSBaptiste Daroussin  *	rtextpad(); (helper for pnoutrefresh(textpad)).
8761ba55bcSBaptiste Daroussin  *
8861ba55bcSBaptiste Daroussin  * ----------------------------------------------------
8961ba55bcSBaptiste Daroussin  * -6- Dialog init/build, update/draw, destroy
9061ba55bcSBaptiste Daroussin  *
9161ba55bcSBaptiste Daroussin  *          end_dialog(struct dialog);
9261ba55bcSBaptiste Daroussin  * [static] check_set_wtext_attr();
9361ba55bcSBaptiste Daroussin  * [static] print_string(); (word wrapping).
9461ba55bcSBaptiste Daroussin  * [static] print_textpad();
9561ba55bcSBaptiste Daroussin  *          draw_dialog(struct dialog);
9661ba55bcSBaptiste Daroussin  *          prepare_dialog(struct dialog);
9761ba55bcSBaptiste Daroussin  */
98c76f0793SBaptiste Daroussin 
9961ba55bcSBaptiste Daroussin /*
10061ba55bcSBaptiste Daroussin  * -1- Error and diagnostic
10161ba55bcSBaptiste Daroussin  */
10261ba55bcSBaptiste Daroussin #define ERRBUFLEN    1024
10361ba55bcSBaptiste Daroussin 
104c76f0793SBaptiste Daroussin static char errorbuffer[ERRBUFLEN];
105c76f0793SBaptiste Daroussin 
get_error_string(void)106c76f0793SBaptiste Daroussin const char *get_error_string(void)
107c76f0793SBaptiste Daroussin {
108263660c0SAlfonso Siciliano 	return (errorbuffer);
109c76f0793SBaptiste Daroussin }
110c76f0793SBaptiste Daroussin 
set_error_string(const char * str)111bce40c02SAlfonso S. Siciliano void set_error_string(const char *str)
112c76f0793SBaptiste Daroussin {
113c76f0793SBaptiste Daroussin 	strncpy(errorbuffer, str, ERRBUFLEN-1);
114c76f0793SBaptiste Daroussin }
115c76f0793SBaptiste Daroussin 
set_fmt_error_string(const char * fmt,...)11661ba55bcSBaptiste Daroussin void set_fmt_error_string(const char *fmt, ...)
11761ba55bcSBaptiste Daroussin {
11861ba55bcSBaptiste Daroussin    va_list arg_ptr;
11961ba55bcSBaptiste Daroussin 
12061ba55bcSBaptiste Daroussin    va_start(arg_ptr, fmt);
12161ba55bcSBaptiste Daroussin    vsnprintf(errorbuffer, ERRBUFLEN-1, fmt, arg_ptr);
12261ba55bcSBaptiste Daroussin    va_end(arg_ptr);
12361ba55bcSBaptiste Daroussin }
12461ba55bcSBaptiste Daroussin 
12561ba55bcSBaptiste Daroussin /*
12661ba55bcSBaptiste Daroussin  * -2- (Unicode) Multicolumn character strings
12761ba55bcSBaptiste Daroussin  */
alloc_mbstows(const char * mbstring)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 
mvwaddwch(WINDOW * w,int y,int x,wchar_t wch)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 
str_props(const char * mbstring,unsigned int * cols,bool * has_multi_col)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 
strcols(const char * mbstring)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 
21561ba55bcSBaptiste Daroussin /*
21661ba55bcSBaptiste Daroussin  * -3- Buttons
21761ba55bcSBaptiste Daroussin  */
buttons_min_width(struct buttons * bs)21861ba55bcSBaptiste Daroussin static int buttons_min_width(struct buttons *bs)
219c76f0793SBaptiste Daroussin {
22061ba55bcSBaptiste Daroussin 	unsigned int width;
221c76f0793SBaptiste Daroussin 
22261ba55bcSBaptiste Daroussin 	width = bs->nbuttons * bs->sizebutton;
22361ba55bcSBaptiste Daroussin 	if (bs->nbuttons > 0)
22461ba55bcSBaptiste Daroussin 		width += (bs->nbuttons - 1) * t.button.minmargin;
225c76f0793SBaptiste Daroussin 
22661ba55bcSBaptiste Daroussin 	return (width);
227c76f0793SBaptiste Daroussin }
228c76f0793SBaptiste Daroussin 
229263660c0SAlfonso Siciliano static void
draw_button(WINDOW * window,int y,int x,int size,const char * text,wchar_t first,bool selected,bool shortcut)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 
draw_buttons(struct dialog * d)26861ba55bcSBaptiste Daroussin void draw_buttons(struct dialog *d)
269c76f0793SBaptiste Daroussin {
27061ba55bcSBaptiste Daroussin 	int i, x, startx, y;
271b319d934SAlfonso S. Siciliano 	unsigned int newmargin, margin, wbuttons;
272c76f0793SBaptiste Daroussin 
27361ba55bcSBaptiste Daroussin 	y = d->h - 2;
274263660c0SAlfonso Siciliano 
27561ba55bcSBaptiste Daroussin 	newmargin = d->w - BORDERS - (d->bs.nbuttons * d->bs.sizebutton);
27661ba55bcSBaptiste 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;
28061ba55bcSBaptiste Daroussin 		wbuttons = buttons_min_width(&d->bs);
281b319d934SAlfonso S. Siciliano 	} else {
282b319d934SAlfonso S. Siciliano 		margin = newmargin;
28361ba55bcSBaptiste Daroussin 		wbuttons = d->bs.nbuttons * d->bs.sizebutton;
28461ba55bcSBaptiste Daroussin 		wbuttons += (d->bs.nbuttons + 1) * margin;
285b319d934SAlfonso S. Siciliano 	}
286c76f0793SBaptiste Daroussin 
28761ba55bcSBaptiste Daroussin 	startx = d->w/2 - wbuttons/2 + newmargin;
28861ba55bcSBaptiste Daroussin 	for (i = 0; i < (int)d->bs.nbuttons; i++) {
28961ba55bcSBaptiste Daroussin 		x = i * (d->bs.sizebutton + margin);
29061ba55bcSBaptiste Daroussin 		draw_button(d->widget, y, startx + x, d->bs.sizebutton,
29161ba55bcSBaptiste Daroussin 		    d->bs.label[i], d->bs.first[i],  i == d->bs.curr,
29261ba55bcSBaptiste Daroussin 		    d->bs.shortcut);
293c76f0793SBaptiste Daroussin 	}
294c76f0793SBaptiste Daroussin }
295c76f0793SBaptiste Daroussin 
296c76f0793SBaptiste Daroussin void
set_buttons(struct dialog * d,bool shortcut,const char * oklabel,const char * cancellabel)29761ba55bcSBaptiste Daroussin set_buttons(struct dialog *d, bool shortcut, const char *oklabel,
29861ba55bcSBaptiste Daroussin     const char *cancellabel)
299c76f0793SBaptiste Daroussin {
300c76f0793SBaptiste Daroussin 	int i;
301c76f0793SBaptiste Daroussin #define SIZEBUTTON              8
30261ba55bcSBaptiste Daroussin #define DEFAULT_BUTTON_LABEL	OK_LABEL
3038c4f4028SBaptiste Daroussin #define DEFAULT_BUTTON_VALUE	BSDDIALOG_OK
304b319d934SAlfonso S. Siciliano 	wchar_t first;
305c76f0793SBaptiste Daroussin 
30661ba55bcSBaptiste Daroussin 	d->bs.nbuttons = 0;
30761ba55bcSBaptiste Daroussin 	d->bs.curr = 0;
30861ba55bcSBaptiste Daroussin 	d->bs.sizebutton = 0;
30961ba55bcSBaptiste Daroussin 	d->bs.shortcut = shortcut;
310c76f0793SBaptiste Daroussin 
31161ba55bcSBaptiste Daroussin 	if (d->conf->button.left1_label != NULL) {
31261ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.left1_label;
31361ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_LEFT1;
31461ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
315c76f0793SBaptiste Daroussin 	}
316c76f0793SBaptiste Daroussin 
31761ba55bcSBaptiste Daroussin 	if (d->conf->button.left2_label != NULL) {
31861ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.left2_label;
31961ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_LEFT2;
32061ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
321c76f0793SBaptiste Daroussin 	}
322c76f0793SBaptiste Daroussin 
32361ba55bcSBaptiste Daroussin 	if (d->conf->button.left3_label != NULL) {
32461ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.left3_label;
32561ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_LEFT3;
32661ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
327c76f0793SBaptiste Daroussin 	}
328c76f0793SBaptiste Daroussin 
32961ba55bcSBaptiste Daroussin 	if (oklabel != NULL && d->conf->button.without_ok == false) {
33061ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.ok_label != NULL ?
33161ba55bcSBaptiste Daroussin 		    d->conf->button.ok_label : oklabel;
33261ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_OK;
33361ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
334c76f0793SBaptiste Daroussin 	}
335c76f0793SBaptiste Daroussin 
33661ba55bcSBaptiste Daroussin 	if (d->conf->button.with_extra) {
33761ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.extra_label != NULL ?
33861ba55bcSBaptiste Daroussin 		    d->conf->button.extra_label : "Extra";
33961ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_EXTRA;
34061ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
341f499134dSBaptiste Daroussin 	}
342f499134dSBaptiste Daroussin 
34361ba55bcSBaptiste Daroussin 	if (cancellabel != NULL && d->conf->button.without_cancel == false) {
34461ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.cancel_label ?
34561ba55bcSBaptiste Daroussin 		    d->conf->button.cancel_label : cancellabel;
34661ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_CANCEL;
34761ba55bcSBaptiste Daroussin 		if (d->conf->button.default_cancel)
34861ba55bcSBaptiste Daroussin 			d->bs.curr = d->bs.nbuttons;
34961ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
350f499134dSBaptiste Daroussin 	}
351f499134dSBaptiste Daroussin 
35261ba55bcSBaptiste Daroussin 	if (d->conf->button.with_help) {
35361ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.help_label != NULL ?
35461ba55bcSBaptiste Daroussin 		    d->conf->button.help_label : "Help";
35561ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_HELP;
35661ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
357c76f0793SBaptiste Daroussin 	}
358c76f0793SBaptiste Daroussin 
35961ba55bcSBaptiste Daroussin 	if (d->conf->button.right1_label != NULL) {
36061ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.right1_label;
36161ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_RIGHT1;
36261ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
363b319d934SAlfonso S. Siciliano 	}
364b319d934SAlfonso S. Siciliano 
36561ba55bcSBaptiste Daroussin 	if (d->conf->button.right2_label != NULL) {
36661ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.right2_label;
36761ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_RIGHT2;
36861ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
36961ba55bcSBaptiste Daroussin 	}
37061ba55bcSBaptiste Daroussin 
37161ba55bcSBaptiste Daroussin 	if (d->conf->button.right3_label != NULL) {
37261ba55bcSBaptiste Daroussin 		d->bs.label[d->bs.nbuttons] = d->conf->button.right3_label;
37361ba55bcSBaptiste Daroussin 		d->bs.value[d->bs.nbuttons] = BSDDIALOG_RIGHT3;
37461ba55bcSBaptiste Daroussin 		d->bs.nbuttons += 1;
37561ba55bcSBaptiste Daroussin 	}
37661ba55bcSBaptiste Daroussin 
37761ba55bcSBaptiste Daroussin 	if (d->bs.nbuttons == 0) {
37861ba55bcSBaptiste Daroussin 		d->bs.label[0] = DEFAULT_BUTTON_LABEL;
37961ba55bcSBaptiste Daroussin 		d->bs.value[0] = DEFAULT_BUTTON_VALUE;
38061ba55bcSBaptiste Daroussin 		d->bs.nbuttons = 1;
38161ba55bcSBaptiste Daroussin 	}
38261ba55bcSBaptiste Daroussin 
38361ba55bcSBaptiste Daroussin 	for (i = 0; i < (int)d->bs.nbuttons; i++) {
38461ba55bcSBaptiste Daroussin 		mbtowc(&first, d->bs.label[i], MB_CUR_MAX);
38561ba55bcSBaptiste Daroussin 		d->bs.first[i] = first;
38661ba55bcSBaptiste Daroussin 	}
38761ba55bcSBaptiste Daroussin 
38861ba55bcSBaptiste Daroussin 	if (d->conf->button.default_label != NULL) {
38961ba55bcSBaptiste Daroussin 		for (i = 0; i < (int)d->bs.nbuttons; i++) {
39061ba55bcSBaptiste Daroussin 			if (strcmp(d->conf->button.default_label,
39161ba55bcSBaptiste Daroussin 			    d->bs.label[i]) == 0)
39261ba55bcSBaptiste Daroussin 				d->bs.curr = i;
393c76f0793SBaptiste Daroussin 		}
394c76f0793SBaptiste Daroussin 	}
395c76f0793SBaptiste Daroussin 
39661ba55bcSBaptiste Daroussin 	d->bs.sizebutton = MAX(SIZEBUTTON - 2, strcols(d->bs.label[0]));
39761ba55bcSBaptiste Daroussin 	for (i = 1; i < (int)d->bs.nbuttons; i++)
39861ba55bcSBaptiste Daroussin 		d->bs.sizebutton = MAX(d->bs.sizebutton, strcols(d->bs.label[i]));
39961ba55bcSBaptiste Daroussin 	d->bs.sizebutton += 2;
400bce40c02SAlfonso S. Siciliano }
401bce40c02SAlfonso S. Siciliano 
shortcut_buttons(wint_t key,struct buttons * bs)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 
41961ba55bcSBaptiste Daroussin /*
42061ba55bcSBaptiste Daroussin  * -4- (Auto) Sizing and (Auto) Position
42161ba55bcSBaptiste Daroussin  */
widget_max_height(struct bsddialog_conf * conf)42261ba55bcSBaptiste Daroussin static int widget_max_height(struct bsddialog_conf *conf)
42361ba55bcSBaptiste Daroussin {
42461ba55bcSBaptiste Daroussin 	int maxheight;
42561ba55bcSBaptiste Daroussin 
42661ba55bcSBaptiste Daroussin 	maxheight = conf->shadow ? SCREENLINES - (int)t.shadow.y : SCREENLINES;
42761ba55bcSBaptiste Daroussin 	if (maxheight <= 0)
42861ba55bcSBaptiste Daroussin 		RETURN_ERROR("Terminal too small, screen lines - shadow <= 0");
42961ba55bcSBaptiste Daroussin 
43061ba55bcSBaptiste Daroussin 	if (conf->y != BSDDIALOG_CENTER && conf->auto_topmargin > 0)
43161ba55bcSBaptiste Daroussin 		RETURN_ERROR("conf.y > 0 and conf->auto_topmargin > 0");
43261ba55bcSBaptiste Daroussin 	else if (conf->y == BSDDIALOG_CENTER) {
43361ba55bcSBaptiste Daroussin 		maxheight -= conf->auto_topmargin;
43461ba55bcSBaptiste Daroussin 		if (maxheight <= 0)
43561ba55bcSBaptiste Daroussin 			RETURN_ERROR("Terminal too small, screen lines - top "
43661ba55bcSBaptiste Daroussin 			    "margins <= 0");
43761ba55bcSBaptiste Daroussin 	} else if (conf->y > 0) {
43861ba55bcSBaptiste Daroussin 		maxheight -= conf->y;
43961ba55bcSBaptiste Daroussin 		if (maxheight <= 0)
44061ba55bcSBaptiste Daroussin 			RETURN_ERROR("Terminal too small, screen lines - "
44161ba55bcSBaptiste Daroussin 			    "shadow - y <= 0");
44261ba55bcSBaptiste Daroussin 	}
44361ba55bcSBaptiste Daroussin 
44461ba55bcSBaptiste Daroussin 	maxheight -= conf->auto_downmargin;
44561ba55bcSBaptiste Daroussin 	if (maxheight <= 0)
44661ba55bcSBaptiste Daroussin 		RETURN_ERROR("Terminal too small, screen lines - Down margins "
44761ba55bcSBaptiste Daroussin 		    "<= 0");
44861ba55bcSBaptiste Daroussin 
44961ba55bcSBaptiste Daroussin 	return (maxheight);
45061ba55bcSBaptiste Daroussin }
45161ba55bcSBaptiste Daroussin 
widget_max_width(struct bsddialog_conf * conf)45261ba55bcSBaptiste Daroussin static int widget_max_width(struct bsddialog_conf *conf)
45361ba55bcSBaptiste Daroussin {
45461ba55bcSBaptiste Daroussin 	int maxwidth;
45561ba55bcSBaptiste Daroussin 
45661ba55bcSBaptiste Daroussin 	maxwidth = conf->shadow ? SCREENCOLS - (int)t.shadow.x : SCREENCOLS;
45761ba55bcSBaptiste Daroussin 	if (maxwidth <= 0)
45861ba55bcSBaptiste Daroussin 		RETURN_ERROR("Terminal too small, screen cols - shadow <= 0");
45961ba55bcSBaptiste Daroussin 
46061ba55bcSBaptiste Daroussin 	if (conf->x > 0) {
46161ba55bcSBaptiste Daroussin 		maxwidth -= conf->x;
46261ba55bcSBaptiste Daroussin 		if (maxwidth <= 0)
46361ba55bcSBaptiste Daroussin 			RETURN_ERROR("Terminal too small, screen cols - shadow "
46461ba55bcSBaptiste Daroussin 			    "- x <= 0");
46561ba55bcSBaptiste Daroussin 	}
46661ba55bcSBaptiste Daroussin 
46761ba55bcSBaptiste Daroussin 	return (maxwidth);
46861ba55bcSBaptiste Daroussin }
46961ba55bcSBaptiste Daroussin 
is_wtext_attr(const wchar_t * wtext)470b319d934SAlfonso S. Siciliano static bool is_wtext_attr(const wchar_t *wtext)
471263660c0SAlfonso Siciliano {
47261ba55bcSBaptiste Daroussin 	bool att;
47361ba55bcSBaptiste 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 
47961ba55bcSBaptiste Daroussin 	att = wcschr(L"nbBdDkKrRsSuU01234567", wtext[2]) == NULL ? false : true;
48061ba55bcSBaptiste Daroussin 
48161ba55bcSBaptiste 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
text_properties(struct bsddialog_conf * conf,const char * text,struct textproperties * tp)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++) {
52461ba55bcSBaptiste 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
text_autosize(struct bsddialog_conf * conf,struct textproperties * tp,int maxrows,int mincols,bool increasecols,int * h,int * w)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 
59861ba55bcSBaptiste 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,
60461ba55bcSBaptiste 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 
67761ba55bcSBaptiste Daroussin static int
text_size(struct bsddialog_conf * conf,int rows,int cols,const char * text,struct buttons * bs,int rowsnotext,int startwtext,int * htext,int * wtext)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;
68661ba55bcSBaptiste Daroussin 	if (bs->nbuttons > 0)
68761ba55bcSBaptiste Daroussin 		wbuttons = buttons_min_width(bs);
688263660c0SAlfonso Siciliano 
689b319d934SAlfonso S. Siciliano 	/* Rows */
690b319d934SAlfonso S. Siciliano 	if (rows == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_FULLSCREEN) {
69161ba55bcSBaptiste Daroussin 		maxhtext = widget_max_height(conf) - BORDERS - rowsnotext;
692b319d934SAlfonso S. Siciliano 	} else { /* fixed */
69361ba55bcSBaptiste Daroussin 		maxhtext = rows - BORDERS - rowsnotext;
694b319d934SAlfonso S. Siciliano 	}
69561ba55bcSBaptiste 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) {
70561ba55bcSBaptiste Daroussin 		startwtext = widget_max_width(conf) - BORDERS - TEXTHMARGINS;
706263660c0SAlfonso Siciliano 		changewtext = false;
707263660c0SAlfonso Siciliano 	} else { /* fixed */
70861ba55bcSBaptiste 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);
71861ba55bcSBaptiste Daroussin 	if (tp.nword > 0 && startwtext <= 0)
71961ba55bcSBaptiste Daroussin 		RETURN_FMTERROR("(fixed cols or fullscreen) "
72061ba55bcSBaptiste Daroussin 		    "needed at least %d cols to draw text",
72161ba55bcSBaptiste 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 
73261ba55bcSBaptiste Daroussin static int
widget_min_height(struct bsddialog_conf * conf,int htext,int hnotext,bool withbuttons)73361ba55bcSBaptiste Daroussin widget_min_height(struct bsddialog_conf *conf, int htext, int hnotext,
734263660c0SAlfonso Siciliano     bool withbuttons)
735263660c0SAlfonso Siciliano {
736263660c0SAlfonso Siciliano 	int min;
737263660c0SAlfonso Siciliano 
73861ba55bcSBaptiste Daroussin 	/* dialog borders */
73961ba55bcSBaptiste Daroussin 	min = BORDERS;
740263660c0SAlfonso Siciliano 
741263660c0SAlfonso Siciliano 	/* text */
742263660c0SAlfonso Siciliano 	min += htext;
743263660c0SAlfonso Siciliano 
74461ba55bcSBaptiste Daroussin 	/* specific widget lines without text */
74561ba55bcSBaptiste Daroussin 	min += hnotext;
746263660c0SAlfonso Siciliano 
74761ba55bcSBaptiste Daroussin 	/* buttons */
74861ba55bcSBaptiste Daroussin 	if (withbuttons)
74961ba55bcSBaptiste Daroussin 		min += HBUTTONS; /* buttons and their up-border */
75061ba55bcSBaptiste 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 
75761ba55bcSBaptiste Daroussin static int
widget_min_width(struct bsddialog_conf * conf,int wtext,int minwidget,struct buttons * bs)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 */
76761ba55bcSBaptiste Daroussin 	if (bs->nbuttons > 0)
76861ba55bcSBaptiste 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 */
79161ba55bcSBaptiste 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
set_widget_size(struct bsddialog_conf * conf,int rows,int cols,int * h,int * w)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
set_widget_autosize(struct bsddialog_conf * conf,int rows,int cols,int * h,int * w,const char * text,int * rowstext,struct buttons * bs,int hnotext,int minw)82961ba55bcSBaptiste Daroussin set_widget_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
83061ba55bcSBaptiste Daroussin     int *w, const char *text, int *rowstext, struct buttons *bs, int hnotext,
83161ba55bcSBaptiste Daroussin     int minw)
83261ba55bcSBaptiste Daroussin {
83361ba55bcSBaptiste Daroussin 	int htext, wtext;
83461ba55bcSBaptiste Daroussin 
83561ba55bcSBaptiste Daroussin 	if (rows == BSDDIALOG_AUTOSIZE || cols == BSDDIALOG_AUTOSIZE ||
83661ba55bcSBaptiste Daroussin 	    rowstext != NULL) {
83761ba55bcSBaptiste Daroussin 		if (text_size(conf, rows, cols, text, bs, hnotext, minw,
83861ba55bcSBaptiste Daroussin 		    &htext, &wtext) != 0)
83961ba55bcSBaptiste Daroussin 			return (BSDDIALOG_ERROR);
84061ba55bcSBaptiste Daroussin 		if (rowstext != NULL)
84161ba55bcSBaptiste Daroussin 			*rowstext = htext;
84261ba55bcSBaptiste Daroussin 	}
84361ba55bcSBaptiste Daroussin 
84461ba55bcSBaptiste Daroussin 	if (rows == BSDDIALOG_AUTOSIZE) {
84561ba55bcSBaptiste Daroussin 		*h = widget_min_height(conf, htext, hnotext, bs->nbuttons > 0);
84661ba55bcSBaptiste Daroussin 		*h = MIN(*h, widget_max_height(conf));
84761ba55bcSBaptiste Daroussin 	}
84861ba55bcSBaptiste Daroussin 
84961ba55bcSBaptiste Daroussin 	if (cols == BSDDIALOG_AUTOSIZE) {
85061ba55bcSBaptiste Daroussin 		*w = widget_min_width(conf, wtext, minw, bs);
85161ba55bcSBaptiste Daroussin 		*w = MIN(*w, widget_max_width(conf));
85261ba55bcSBaptiste Daroussin 	}
85361ba55bcSBaptiste Daroussin 
85461ba55bcSBaptiste Daroussin 	return (0);
85561ba55bcSBaptiste Daroussin }
85661ba55bcSBaptiste Daroussin 
widget_checksize(int h,int w,struct buttons * bs,int hnotext,int minw)85761ba55bcSBaptiste Daroussin int widget_checksize(int h, int w, struct buttons *bs, int hnotext, int minw)
85861ba55bcSBaptiste Daroussin {
85961ba55bcSBaptiste Daroussin 	int minheight, minwidth;
86061ba55bcSBaptiste Daroussin 
86161ba55bcSBaptiste Daroussin 	minheight = BORDERS + hnotext;
86261ba55bcSBaptiste Daroussin 	if (bs->nbuttons > 0)
86361ba55bcSBaptiste Daroussin 		minheight += HBUTTONS;
86461ba55bcSBaptiste Daroussin 	if (h < minheight)
86561ba55bcSBaptiste Daroussin 		RETURN_FMTERROR("Current rows: %d, needed at least: %d",
86661ba55bcSBaptiste Daroussin 		    h, minheight);
86761ba55bcSBaptiste Daroussin 
86861ba55bcSBaptiste Daroussin 	minwidth = 0;
86961ba55bcSBaptiste Daroussin 	if (bs->nbuttons > 0)
87061ba55bcSBaptiste Daroussin 		minwidth = buttons_min_width(bs);
87161ba55bcSBaptiste Daroussin 	minwidth = MAX(minwidth, minw);
87261ba55bcSBaptiste Daroussin 	minwidth += BORDERS;
87361ba55bcSBaptiste Daroussin 	if (w < minwidth)
87461ba55bcSBaptiste Daroussin 		RETURN_FMTERROR("Current cols: %d, nedeed at least %d",
87561ba55bcSBaptiste Daroussin 		    w, minwidth);
87661ba55bcSBaptiste Daroussin 
87761ba55bcSBaptiste Daroussin 	return (0);
87861ba55bcSBaptiste Daroussin }
87961ba55bcSBaptiste Daroussin 
88061ba55bcSBaptiste Daroussin int
set_widget_position(struct bsddialog_conf * conf,int * y,int * x,int h,int w)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 
dialog_size_position(struct dialog * d,int hnotext,int minw,int * htext)92161ba55bcSBaptiste Daroussin int dialog_size_position(struct dialog *d, int hnotext, int minw, int *htext)
922c76f0793SBaptiste Daroussin {
92361ba55bcSBaptiste Daroussin 	if (set_widget_size(d->conf, d->rows, d->cols, &d->h, &d->w) != 0)
92461ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
92561ba55bcSBaptiste Daroussin 	if (set_widget_autosize(d->conf, d->rows, d->cols, &d->h, &d->w,
92661ba55bcSBaptiste Daroussin 	    d->text, htext, &d->bs, hnotext, minw) != 0)
92761ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
92861ba55bcSBaptiste Daroussin 	if (widget_checksize(d->h, d->w, &d->bs, hnotext, minw) != 0)
92961ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
93061ba55bcSBaptiste Daroussin 	if (set_widget_position(d->conf, &d->y, &d->x, d->h, d->w) != 0)
93161ba55bcSBaptiste Daroussin 		return (BSDDIALOG_ERROR);
93261ba55bcSBaptiste Daroussin 
93361ba55bcSBaptiste Daroussin 	return (0);
93461ba55bcSBaptiste Daroussin }
93561ba55bcSBaptiste Daroussin 
93661ba55bcSBaptiste Daroussin /*
93761ba55bcSBaptiste Daroussin  * -5- Widget components and utilities
93861ba55bcSBaptiste Daroussin  */
hide_dialog(struct dialog * d)93961ba55bcSBaptiste Daroussin int hide_dialog(struct dialog *d)
94061ba55bcSBaptiste Daroussin {
94161ba55bcSBaptiste Daroussin 	WINDOW *clear;
94261ba55bcSBaptiste Daroussin 
94361ba55bcSBaptiste Daroussin 	if ((clear = newwin(d->h, d->w, d->y, d->x)) == NULL)
94461ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot hide the widget");
94561ba55bcSBaptiste Daroussin 	wbkgd(clear, t.screen.color);
94661ba55bcSBaptiste Daroussin 	wrefresh(clear);
94761ba55bcSBaptiste Daroussin 
94861ba55bcSBaptiste Daroussin 	if (d->conf->shadow) {
94961ba55bcSBaptiste Daroussin 		mvwin(clear, d->y + t.shadow.y, d->x + t.shadow.x);
95061ba55bcSBaptiste Daroussin 		wrefresh(clear);
95161ba55bcSBaptiste Daroussin 	}
95261ba55bcSBaptiste Daroussin 
95361ba55bcSBaptiste Daroussin 	delwin(clear);
95461ba55bcSBaptiste Daroussin 
95561ba55bcSBaptiste Daroussin 	return (0);
95661ba55bcSBaptiste Daroussin }
95761ba55bcSBaptiste Daroussin 
f1help_dialog(struct bsddialog_conf * conf)95861ba55bcSBaptiste Daroussin int f1help_dialog(struct bsddialog_conf *conf)
95961ba55bcSBaptiste Daroussin {
96061ba55bcSBaptiste Daroussin 	int output;
96161ba55bcSBaptiste Daroussin 	struct bsddialog_conf hconf;
96261ba55bcSBaptiste Daroussin 
96361ba55bcSBaptiste Daroussin 	bsddialog_initconf(&hconf);
96461ba55bcSBaptiste Daroussin 	hconf.title           = "HELP";
96561ba55bcSBaptiste Daroussin 	hconf.button.ok_label = "EXIT";
96661ba55bcSBaptiste Daroussin 	hconf.clear           = true;
96761ba55bcSBaptiste Daroussin 	hconf.ascii_lines     = conf->ascii_lines;
96861ba55bcSBaptiste Daroussin 	hconf.no_lines        = conf->no_lines;
96961ba55bcSBaptiste Daroussin 	hconf.shadow          = conf->shadow;
97061ba55bcSBaptiste Daroussin 	hconf.text.escape     = conf->text.escape;
97161ba55bcSBaptiste Daroussin 
97261ba55bcSBaptiste Daroussin 	output = BSDDIALOG_OK;
97361ba55bcSBaptiste Daroussin 	if (conf->key.f1_message != NULL)
97461ba55bcSBaptiste Daroussin 		output = bsddialog_msgbox(&hconf, conf->key.f1_message, 0, 0);
97561ba55bcSBaptiste Daroussin 
97661ba55bcSBaptiste Daroussin 	if (output != BSDDIALOG_ERROR && conf->key.f1_file != NULL)
97761ba55bcSBaptiste Daroussin 		output = bsddialog_textbox(&hconf, conf->key.f1_file, 0, 0);
97861ba55bcSBaptiste Daroussin 
97961ba55bcSBaptiste Daroussin 	return (output == BSDDIALOG_ERROR ? BSDDIALOG_ERROR : 0);
98061ba55bcSBaptiste Daroussin }
98161ba55bcSBaptiste Daroussin 
draw_borders(struct bsddialog_conf * conf,WINDOW * win,enum elevation elev)98261ba55bcSBaptiste Daroussin void draw_borders(struct bsddialog_conf *conf, WINDOW *win, enum elevation elev)
98361ba55bcSBaptiste Daroussin {
98461ba55bcSBaptiste Daroussin 	int h, w;
985c76f0793SBaptiste Daroussin 	int leftcolor, rightcolor;
986*a6d8be45SAlfonso S. Siciliano 	cchar_t *ls, *rs, *ts, *bs, *tl, *tr, *bl, *br;
987*a6d8be45SAlfonso S. Siciliano 	cchar_t hline, vline, corner;
988c76f0793SBaptiste Daroussin 
989263660c0SAlfonso Siciliano 	if (conf->no_lines)
990263660c0SAlfonso Siciliano 		return;
991263660c0SAlfonso Siciliano 
992263660c0SAlfonso Siciliano 	if (conf->ascii_lines) {
993*a6d8be45SAlfonso S. Siciliano 		setcchar(&hline, L"|", 0, 0, NULL);
994*a6d8be45SAlfonso S. Siciliano 		ls = rs = &hline;
995*a6d8be45SAlfonso S. Siciliano 		setcchar(&vline, L"-", 0, 0, NULL);
996*a6d8be45SAlfonso S. Siciliano 		ts = bs = &vline;
997*a6d8be45SAlfonso S. Siciliano 		setcchar(&corner, L"+", 0, 0, NULL);
998*a6d8be45SAlfonso S. Siciliano 		tl = tr = bl = br = &corner;
999263660c0SAlfonso Siciliano 	} else {
1000*a6d8be45SAlfonso S. Siciliano 		ls = rs = WACS_VLINE;
1001*a6d8be45SAlfonso S. Siciliano 		ts = bs = WACS_HLINE;
1002*a6d8be45SAlfonso S. Siciliano 		tl = WACS_ULCORNER;
1003*a6d8be45SAlfonso S. Siciliano 		tr = WACS_URCORNER;
1004*a6d8be45SAlfonso S. Siciliano 		bl = WACS_LLCORNER;
1005*a6d8be45SAlfonso S. Siciliano 		br = WACS_LRCORNER;
1006c76f0793SBaptiste Daroussin 	}
1007263660c0SAlfonso Siciliano 
100861ba55bcSBaptiste Daroussin 	getmaxyx(win, h, w);
1009*a6d8be45SAlfonso S. Siciliano 	leftcolor = (elev == RAISED) ?
10108c4f4028SBaptiste Daroussin 	    t.dialog.lineraisecolor : t.dialog.linelowercolor;
1011*a6d8be45SAlfonso S. Siciliano 	rightcolor = (elev == RAISED) ?
10128c4f4028SBaptiste Daroussin 	    t.dialog.linelowercolor : t.dialog.lineraisecolor;
101361ba55bcSBaptiste Daroussin 
1014c76f0793SBaptiste Daroussin 	wattron(win, leftcolor);
1015*a6d8be45SAlfonso S. Siciliano 	wborder_set(win, ls, rs, ts, bs, tl, tr, bl, br);
1016c76f0793SBaptiste Daroussin 	wattroff(win, leftcolor);
1017c76f0793SBaptiste Daroussin 
1018c76f0793SBaptiste Daroussin 	wattron(win, rightcolor);
1019*a6d8be45SAlfonso S. Siciliano 	mvwadd_wch(win, 0, w-1, tr);
1020*a6d8be45SAlfonso S. Siciliano 	mvwvline_set(win, 1, w-1, rs, h-2);
1021*a6d8be45SAlfonso S. Siciliano 	mvwadd_wch(win, h-1, w-1, br);
1022*a6d8be45SAlfonso S. Siciliano 	mvwhline_set(win, h-1, 1, bs, w-2);
1023c76f0793SBaptiste Daroussin 	wattroff(win, rightcolor);
1024c76f0793SBaptiste Daroussin }
1025c76f0793SBaptiste Daroussin 
102661ba55bcSBaptiste Daroussin void
update_box(struct bsddialog_conf * conf,WINDOW * win,int y,int x,int h,int w,enum elevation elev)102761ba55bcSBaptiste Daroussin update_box(struct bsddialog_conf *conf, WINDOW *win, int y, int x, int h, int w,
1028c76f0793SBaptiste Daroussin     enum elevation elev)
1029c76f0793SBaptiste Daroussin {
103061ba55bcSBaptiste Daroussin 	wclear(win);
103161ba55bcSBaptiste Daroussin 	wresize(win, h, w);
103261ba55bcSBaptiste Daroussin 	mvwin(win, y, x);
103361ba55bcSBaptiste Daroussin 	draw_borders(conf, win, elev);
1034c76f0793SBaptiste Daroussin }
1035c76f0793SBaptiste Daroussin 
103661ba55bcSBaptiste Daroussin void
rtextpad(struct dialog * d,int ytext,int xtext,int upnotext,int downnotext)103761ba55bcSBaptiste Daroussin rtextpad(struct dialog *d, int ytext, int xtext, int upnotext, int downnotext)
103861ba55bcSBaptiste Daroussin {
103961ba55bcSBaptiste Daroussin 	pnoutrefresh(d->textpad, ytext, xtext,
104061ba55bcSBaptiste Daroussin 	    d->y + BORDER + upnotext,
104161ba55bcSBaptiste Daroussin 	    d->x + BORDER + TEXTHMARGIN,
104261ba55bcSBaptiste Daroussin 	    d->y + d->h - 1 - downnotext - BORDER,
104361ba55bcSBaptiste Daroussin 	    d->x + d->w - TEXTHMARGIN - BORDER);
104461ba55bcSBaptiste Daroussin }
1045c76f0793SBaptiste Daroussin 
104661ba55bcSBaptiste Daroussin /*
104761ba55bcSBaptiste Daroussin  * -6- Dialog init/build, update/draw, destroy
104861ba55bcSBaptiste Daroussin  */
end_dialog(struct dialog * d)104961ba55bcSBaptiste Daroussin void end_dialog(struct dialog *d)
105061ba55bcSBaptiste Daroussin {
105161ba55bcSBaptiste Daroussin 	if (d->conf->sleep > 0)
105261ba55bcSBaptiste Daroussin 		sleep(d->conf->sleep);
1053c76f0793SBaptiste Daroussin 
105461ba55bcSBaptiste Daroussin 	delwin(d->textpad);
105561ba55bcSBaptiste Daroussin 	delwin(d->widget);
105661ba55bcSBaptiste Daroussin 	if (d->conf->shadow)
105761ba55bcSBaptiste Daroussin 		delwin(d->shadow);
105861ba55bcSBaptiste Daroussin 
105961ba55bcSBaptiste Daroussin 	if (d->conf->clear)
106061ba55bcSBaptiste Daroussin 		hide_dialog(d);
106161ba55bcSBaptiste Daroussin 
106261ba55bcSBaptiste Daroussin 	if (d->conf->get_height != NULL)
106361ba55bcSBaptiste Daroussin 		*d->conf->get_height = d->h;
106461ba55bcSBaptiste Daroussin 	if (d->conf->get_width != NULL)
106561ba55bcSBaptiste Daroussin 		*d->conf->get_width = d->w;
106661ba55bcSBaptiste Daroussin }
106761ba55bcSBaptiste Daroussin 
check_set_wtext_attr(WINDOW * win,wchar_t * wtext)106861ba55bcSBaptiste Daroussin static bool check_set_wtext_attr(WINDOW *win, wchar_t *wtext)
106961ba55bcSBaptiste Daroussin {
107061ba55bcSBaptiste Daroussin 	enum bsddialog_color bg;
107161ba55bcSBaptiste Daroussin 
107261ba55bcSBaptiste Daroussin 	if (is_wtext_attr(wtext) == false)
107361ba55bcSBaptiste Daroussin 		return (false);
107461ba55bcSBaptiste Daroussin 
107561ba55bcSBaptiste Daroussin 	if ((wtext[2] >= L'0') && (wtext[2] <= L'7')) {
107661ba55bcSBaptiste Daroussin 		bsddialog_color_attrs(t.dialog.color, NULL, &bg, NULL);
107761ba55bcSBaptiste Daroussin 		wattron(win, bsddialog_color(wtext[2] - L'0', bg, 0));
107861ba55bcSBaptiste Daroussin 		return (true);
107961ba55bcSBaptiste Daroussin 	}
108061ba55bcSBaptiste Daroussin 
108161ba55bcSBaptiste Daroussin 	switch (wtext[2]) {
108261ba55bcSBaptiste Daroussin 	case L'n':
108361ba55bcSBaptiste Daroussin 		wattron(win, t.dialog.color);
108461ba55bcSBaptiste Daroussin 		wattrset(win, A_NORMAL);
108561ba55bcSBaptiste Daroussin 		break;
108661ba55bcSBaptiste Daroussin 	case L'b':
108761ba55bcSBaptiste Daroussin 		wattron(win, A_BOLD);
108861ba55bcSBaptiste Daroussin 		break;
108961ba55bcSBaptiste Daroussin 	case L'B':
109061ba55bcSBaptiste Daroussin 		wattroff(win, A_BOLD);
109161ba55bcSBaptiste Daroussin 		break;
109261ba55bcSBaptiste Daroussin 	case L'd':
109361ba55bcSBaptiste Daroussin 		wattron(win, A_DIM);
109461ba55bcSBaptiste Daroussin 		break;
109561ba55bcSBaptiste Daroussin 	case L'D':
109661ba55bcSBaptiste Daroussin 		wattroff(win, A_DIM);
109761ba55bcSBaptiste Daroussin 		break;
109861ba55bcSBaptiste Daroussin 	case L'k':
109961ba55bcSBaptiste Daroussin 		wattron(win, A_BLINK);
110061ba55bcSBaptiste Daroussin 		break;
110161ba55bcSBaptiste Daroussin 	case L'K':
110261ba55bcSBaptiste Daroussin 		wattroff(win, A_BLINK);
110361ba55bcSBaptiste Daroussin 		break;
110461ba55bcSBaptiste Daroussin 	case L'r':
110561ba55bcSBaptiste Daroussin 		wattron(win, A_REVERSE);
110661ba55bcSBaptiste Daroussin 		break;
110761ba55bcSBaptiste Daroussin 	case L'R':
110861ba55bcSBaptiste Daroussin 		wattroff(win, A_REVERSE);
110961ba55bcSBaptiste Daroussin 		break;
111061ba55bcSBaptiste Daroussin 	case L's':
111161ba55bcSBaptiste Daroussin 		wattron(win, A_STANDOUT);
111261ba55bcSBaptiste Daroussin 		break;
111361ba55bcSBaptiste Daroussin 	case L'S':
111461ba55bcSBaptiste Daroussin 		wattroff(win, A_STANDOUT);
111561ba55bcSBaptiste Daroussin 		break;
111661ba55bcSBaptiste Daroussin 	case L'u':
111761ba55bcSBaptiste Daroussin 		wattron(win, A_UNDERLINE);
111861ba55bcSBaptiste Daroussin 		break;
111961ba55bcSBaptiste Daroussin 	case L'U':
112061ba55bcSBaptiste Daroussin 		wattroff(win, A_UNDERLINE);
112161ba55bcSBaptiste Daroussin 		break;
112261ba55bcSBaptiste Daroussin 	}
112361ba55bcSBaptiste Daroussin 
112461ba55bcSBaptiste Daroussin 	return (true);
112561ba55bcSBaptiste Daroussin }
112661ba55bcSBaptiste Daroussin 
112761ba55bcSBaptiste Daroussin static void
print_string(WINDOW * win,int * rows,int cols,int * y,int * x,wchar_t * str,bool color)112861ba55bcSBaptiste Daroussin print_string(WINDOW *win, int *rows, int cols, int *y, int *x, wchar_t *str,
112961ba55bcSBaptiste Daroussin     bool color)
113061ba55bcSBaptiste Daroussin {
1131*a6d8be45SAlfonso S. Siciliano 	int charwidth, i, j, strlen, strwidth;
113261ba55bcSBaptiste Daroussin 	wchar_t ws[2];
113361ba55bcSBaptiste Daroussin 
113461ba55bcSBaptiste Daroussin 	ws[1] = L'\0';
113561ba55bcSBaptiste Daroussin 
1136*a6d8be45SAlfonso S. Siciliano 	strlen = wcslen(str);
113761ba55bcSBaptiste Daroussin 	if (color) {
1138*a6d8be45SAlfonso S. Siciliano 		strwidth = 0;
113961ba55bcSBaptiste Daroussin 		i=0;
1140*a6d8be45SAlfonso S. Siciliano 		while (i < strlen) {
114161ba55bcSBaptiste Daroussin 			if (is_wtext_attr(str+i) == false) {
1142*a6d8be45SAlfonso S. Siciliano 				strwidth += wcwidth(str[i]);
114361ba55bcSBaptiste Daroussin 				i++;
114461ba55bcSBaptiste Daroussin 			} else {
114561ba55bcSBaptiste Daroussin 				i += 3;
114661ba55bcSBaptiste Daroussin 			}
114761ba55bcSBaptiste Daroussin 		}
114861ba55bcSBaptiste Daroussin 	} else
1149*a6d8be45SAlfonso S. Siciliano 		strwidth = wcswidth(str, strlen);
115061ba55bcSBaptiste Daroussin 
115161ba55bcSBaptiste Daroussin 	i = 0;
1152*a6d8be45SAlfonso S. Siciliano 	while (i < strlen) {
1153*a6d8be45SAlfonso S. Siciliano 		if (*x + strwidth > cols) {
1154*a6d8be45SAlfonso S. Siciliano 			if (*x != 0)
1155*a6d8be45SAlfonso S. Siciliano 				*y = *y + 1;
115661ba55bcSBaptiste Daroussin 			if (*y >= *rows) {
115761ba55bcSBaptiste Daroussin 				*rows = *y + 1;
115861ba55bcSBaptiste Daroussin 				wresize(win, *rows, cols);
115961ba55bcSBaptiste Daroussin 			}
116061ba55bcSBaptiste Daroussin 			*x = 0;
116161ba55bcSBaptiste Daroussin 		}
116261ba55bcSBaptiste Daroussin 		j = *x;
1163*a6d8be45SAlfonso S. Siciliano 		while (i < strlen) {
116461ba55bcSBaptiste Daroussin 			if (color && check_set_wtext_attr(win, str+i)) {
116561ba55bcSBaptiste Daroussin 				i += 3;
1166*a6d8be45SAlfonso S. Siciliano 				continue;
1167*a6d8be45SAlfonso S. Siciliano 			}
1168*a6d8be45SAlfonso S. Siciliano 
1169*a6d8be45SAlfonso S. Siciliano 			charwidth = wcwidth(str[i]);
1170*a6d8be45SAlfonso S. Siciliano 			if (j + wcwidth(str[i]) > cols)
117161ba55bcSBaptiste Daroussin 				break;
117261ba55bcSBaptiste Daroussin 			/* inline mvwaddwch() for efficiency */
117361ba55bcSBaptiste Daroussin 			ws[0] = str[i];
117461ba55bcSBaptiste Daroussin 			mvwaddwstr(win, *y, j, ws);
1175*a6d8be45SAlfonso S. Siciliano 			strwidth -= charwidth;
1176*a6d8be45SAlfonso S. Siciliano 			j += charwidth;
117761ba55bcSBaptiste Daroussin 			*x = j;
1178*a6d8be45SAlfonso S. Siciliano 			i++;
117961ba55bcSBaptiste Daroussin 		}
118061ba55bcSBaptiste Daroussin 	}
1181c76f0793SBaptiste Daroussin }
1182c76f0793SBaptiste Daroussin 
1183c76f0793SBaptiste Daroussin static int
print_textpad(struct bsddialog_conf * conf,WINDOW * pad,const char * text)118461ba55bcSBaptiste Daroussin print_textpad(struct bsddialog_conf *conf, WINDOW *pad, const char *text)
1185c76f0793SBaptiste Daroussin {
118661ba55bcSBaptiste Daroussin 	bool loop;
118761ba55bcSBaptiste Daroussin 	int i, j, z, rows, cols, x, y, tablen;
118861ba55bcSBaptiste Daroussin 	wchar_t *wtext, *string;
1189c76f0793SBaptiste Daroussin 
119061ba55bcSBaptiste Daroussin 	if ((wtext = alloc_mbstows(text)) == NULL)
119161ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot allocate/print text in wchar_t*");
1192263660c0SAlfonso Siciliano 
119361ba55bcSBaptiste Daroussin 	if ((string = calloc(wcslen(wtext) + 1, sizeof(wchar_t))) == NULL)
119461ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot build (analyze) text");
1195c76f0793SBaptiste Daroussin 
119661ba55bcSBaptiste Daroussin 	getmaxyx(pad, rows, cols);
119761ba55bcSBaptiste Daroussin 	tablen = (conf->text.tablen == 0) ? TABSIZE : (int)conf->text.tablen;
1198c76f0793SBaptiste Daroussin 
119961ba55bcSBaptiste Daroussin 	i = j = x = y = 0;
120061ba55bcSBaptiste Daroussin 	loop = true;
120161ba55bcSBaptiste Daroussin 	while (loop) {
120261ba55bcSBaptiste Daroussin 		string[j] = wtext[i];
1203c76f0793SBaptiste Daroussin 
120461ba55bcSBaptiste Daroussin 		if (wcschr(L"\n\t  ", string[j]) != NULL || string[j] == L'\0') {
120561ba55bcSBaptiste Daroussin 			string[j] = L'\0';
120661ba55bcSBaptiste Daroussin 			print_string(pad, &rows, cols, &y, &x, string,
120761ba55bcSBaptiste Daroussin 			    conf->text.escape);
120861ba55bcSBaptiste Daroussin 		}
120961ba55bcSBaptiste Daroussin 
121061ba55bcSBaptiste Daroussin 		switch (wtext[i]) {
121161ba55bcSBaptiste Daroussin 		case L'\0':
121261ba55bcSBaptiste Daroussin 			loop = false;
121361ba55bcSBaptiste Daroussin 			break;
121461ba55bcSBaptiste Daroussin 		case L'\n':
121561ba55bcSBaptiste Daroussin 			x = 0;
121661ba55bcSBaptiste Daroussin 			y++;
121761ba55bcSBaptiste Daroussin 			j = -1;
121861ba55bcSBaptiste Daroussin 			break;
121961ba55bcSBaptiste Daroussin 		case L'\t':
122061ba55bcSBaptiste Daroussin 			for (z = 0; z < tablen; z++) {
122161ba55bcSBaptiste Daroussin 				if (x >= cols) {
122261ba55bcSBaptiste Daroussin 					x = 0;
122361ba55bcSBaptiste Daroussin 					y++;
122461ba55bcSBaptiste Daroussin 				}
122561ba55bcSBaptiste Daroussin 				x++;
122661ba55bcSBaptiste Daroussin 			}
122761ba55bcSBaptiste Daroussin 			j = -1;
122861ba55bcSBaptiste Daroussin 			break;
122961ba55bcSBaptiste Daroussin 		case L' ':
123061ba55bcSBaptiste Daroussin 			x++;
123161ba55bcSBaptiste Daroussin 			if (x >= cols) {
123261ba55bcSBaptiste Daroussin 				x = 0;
123361ba55bcSBaptiste Daroussin 				y++;
123461ba55bcSBaptiste Daroussin 			}
123561ba55bcSBaptiste Daroussin 			j = -1;
123661ba55bcSBaptiste Daroussin 		}
123761ba55bcSBaptiste Daroussin 
123861ba55bcSBaptiste Daroussin 		if (y >= rows) {
123961ba55bcSBaptiste Daroussin 			rows = y + 1;
124061ba55bcSBaptiste Daroussin 			wresize(pad, rows, cols);
124161ba55bcSBaptiste Daroussin 		}
124261ba55bcSBaptiste Daroussin 
124361ba55bcSBaptiste Daroussin 		j++;
124461ba55bcSBaptiste Daroussin 		i++;
124561ba55bcSBaptiste Daroussin 	}
124661ba55bcSBaptiste Daroussin 
124761ba55bcSBaptiste Daroussin 	free(wtext);
124861ba55bcSBaptiste Daroussin 	free(string);
124961ba55bcSBaptiste Daroussin 
125061ba55bcSBaptiste Daroussin 	return (0);
125161ba55bcSBaptiste Daroussin }
125261ba55bcSBaptiste Daroussin 
draw_dialog(struct dialog * d)125361ba55bcSBaptiste Daroussin int draw_dialog(struct dialog *d)
125461ba55bcSBaptiste Daroussin {
1255*a6d8be45SAlfonso S. Siciliano 	int wtitle, wbottomtitle;
1256*a6d8be45SAlfonso S. Siciliano 	cchar_t ts, ltee, rtee;
125761ba55bcSBaptiste Daroussin 
1258*a6d8be45SAlfonso S. Siciliano 	if (d->conf->ascii_lines) {
1259*a6d8be45SAlfonso S. Siciliano 		setcchar(&ts, L"-", 0, 0, NULL);
1260*a6d8be45SAlfonso S. Siciliano 		setcchar(&ltee, L"+", 0, 0,NULL);
1261*a6d8be45SAlfonso S. Siciliano 		setcchar(&rtee, L"+", 0, 0, NULL);
1262*a6d8be45SAlfonso S. Siciliano 	} else {
1263*a6d8be45SAlfonso S. Siciliano 		ts = *WACS_HLINE;
1264*a6d8be45SAlfonso S. Siciliano 		ltee = *WACS_LTEE;
1265*a6d8be45SAlfonso S. Siciliano 		rtee = *WACS_RTEE;
1266*a6d8be45SAlfonso S. Siciliano 	}
126761ba55bcSBaptiste Daroussin 
126861ba55bcSBaptiste Daroussin 	if (d->conf->shadow) {
126961ba55bcSBaptiste Daroussin 		wclear(d->shadow);
127061ba55bcSBaptiste Daroussin 		wresize(d->shadow, d->h, d->w);
127161ba55bcSBaptiste Daroussin 		mvwin(d->shadow, d->y + t.shadow.y, d->x + t.shadow.x);
127261ba55bcSBaptiste Daroussin 		wnoutrefresh(d->shadow);
127361ba55bcSBaptiste Daroussin 	}
127461ba55bcSBaptiste Daroussin 
127561ba55bcSBaptiste Daroussin 	wclear(d->widget);
127661ba55bcSBaptiste Daroussin 	wresize(d->widget, d->h, d->w);
127761ba55bcSBaptiste Daroussin 	mvwin(d->widget, d->y, d->x);
127861ba55bcSBaptiste Daroussin 	draw_borders(d->conf, d->widget, RAISED);
127961ba55bcSBaptiste Daroussin 
128061ba55bcSBaptiste Daroussin 	if (d->conf->title != NULL) {
128161ba55bcSBaptiste Daroussin 		if ((wtitle = strcols(d->conf->title)) < 0)
1282b319d934SAlfonso S. Siciliano 			return (BSDDIALOG_ERROR);
128361ba55bcSBaptiste Daroussin 		if (t.dialog.delimtitle && d->conf->no_lines == false) {
128461ba55bcSBaptiste Daroussin 			wattron(d->widget, t.dialog.lineraisecolor);
1285*a6d8be45SAlfonso S. Siciliano 			mvwadd_wch(d->widget, 0, d->w/2 - wtitle/2 -1, &rtee);
128661ba55bcSBaptiste Daroussin 			wattroff(d->widget, t.dialog.lineraisecolor);
1287c76f0793SBaptiste Daroussin 		}
128861ba55bcSBaptiste Daroussin 		wattron(d->widget, t.dialog.titlecolor);
128961ba55bcSBaptiste Daroussin 		mvwaddstr(d->widget, 0, d->w/2 - wtitle/2, d->conf->title);
129061ba55bcSBaptiste Daroussin 		wattroff(d->widget, t.dialog.titlecolor);
129161ba55bcSBaptiste Daroussin 		if (t.dialog.delimtitle && d->conf->no_lines == false) {
129261ba55bcSBaptiste Daroussin 			wattron(d->widget, t.dialog.lineraisecolor);
1293*a6d8be45SAlfonso S. Siciliano 			wadd_wch(d->widget, &ltee);
129461ba55bcSBaptiste Daroussin 			wattroff(d->widget, t.dialog.lineraisecolor);
1295c76f0793SBaptiste Daroussin 		}
1296c76f0793SBaptiste Daroussin 	}
1297c76f0793SBaptiste Daroussin 
129861ba55bcSBaptiste Daroussin 	if (d->bs.nbuttons > 0) {
129961ba55bcSBaptiste Daroussin 		if (d->conf->no_lines == false) {
130061ba55bcSBaptiste Daroussin 			wattron(d->widget, t.dialog.lineraisecolor);
1301*a6d8be45SAlfonso S. Siciliano 			mvwadd_wch(d->widget, d->h-3, 0, &ltee);
1302*a6d8be45SAlfonso S. Siciliano 			mvwhline_set(d->widget, d->h-3, 1, &ts, d->w-2);
130361ba55bcSBaptiste Daroussin 			wattroff(d->widget, t.dialog.lineraisecolor);
1304c76f0793SBaptiste Daroussin 
130561ba55bcSBaptiste Daroussin 			wattron(d->widget, t.dialog.linelowercolor);
1306*a6d8be45SAlfonso S. Siciliano 			mvwadd_wch(d->widget, d->h-3, d->w-1, &rtee);
130761ba55bcSBaptiste Daroussin 			wattroff(d->widget, t.dialog.linelowercolor);
1308c76f0793SBaptiste Daroussin 		}
130961ba55bcSBaptiste Daroussin 		draw_buttons(d);
1310263660c0SAlfonso Siciliano 	}
1311263660c0SAlfonso Siciliano 
131261ba55bcSBaptiste Daroussin 	if (d->conf->bottomtitle != NULL) {
131361ba55bcSBaptiste Daroussin 		if ((wbottomtitle = strcols(d->conf->bottomtitle)) < 0)
1314b319d934SAlfonso S. Siciliano 			return (BSDDIALOG_ERROR);
131561ba55bcSBaptiste Daroussin 		wattron(d->widget, t.dialog.bottomtitlecolor);
131661ba55bcSBaptiste Daroussin 		wmove(d->widget, d->h - 1, d->w/2 - wbottomtitle/2 - 1);
131761ba55bcSBaptiste Daroussin 		waddch(d->widget, ' ');
131861ba55bcSBaptiste Daroussin 		waddstr(d->widget, d->conf->bottomtitle);
131961ba55bcSBaptiste Daroussin 		waddch(d->widget, ' ');
132061ba55bcSBaptiste Daroussin 		wattroff(d->widget, t.dialog.bottomtitlecolor);
1321263660c0SAlfonso Siciliano 	}
1322c76f0793SBaptiste Daroussin 
132361ba55bcSBaptiste Daroussin 	wnoutrefresh(d->widget);
1324c76f0793SBaptiste Daroussin 
132561ba55bcSBaptiste Daroussin 	wclear(d->textpad);
132661ba55bcSBaptiste Daroussin 	/* `infobox "" 0 2` fails but text is empty and textpad remains 1 1 */
132761ba55bcSBaptiste Daroussin 	wresize(d->textpad, 1, d->w - BORDERS - TEXTHMARGINS);
132861ba55bcSBaptiste Daroussin 
132961ba55bcSBaptiste Daroussin 	if (print_textpad(d->conf, d->textpad, d->text) != 0)
1330263660c0SAlfonso Siciliano 		return (BSDDIALOG_ERROR);
1331c76f0793SBaptiste Daroussin 
133261ba55bcSBaptiste Daroussin 	d->built = true;
133361ba55bcSBaptiste Daroussin 
1334263660c0SAlfonso Siciliano 	return (0);
1335c76f0793SBaptiste Daroussin }
1336c76f0793SBaptiste Daroussin 
1337c76f0793SBaptiste Daroussin int
prepare_dialog(struct bsddialog_conf * conf,const char * text,int rows,int cols,struct dialog * d)133861ba55bcSBaptiste Daroussin prepare_dialog(struct bsddialog_conf *conf, const char *text, int rows,
133961ba55bcSBaptiste Daroussin     int cols, struct dialog *d)
1340c76f0793SBaptiste Daroussin {
134161ba55bcSBaptiste Daroussin 	CHECK_PTR(conf);
1342c76f0793SBaptiste Daroussin 
134361ba55bcSBaptiste Daroussin 	d->built = false;
134461ba55bcSBaptiste Daroussin 	d->conf = conf;
134561ba55bcSBaptiste Daroussin 	d->rows = rows;
134661ba55bcSBaptiste Daroussin 	d->cols = cols;
134761ba55bcSBaptiste Daroussin 	d->text = CHECK_STR(text);
134861ba55bcSBaptiste Daroussin 	d->bs.nbuttons = 0;
134961ba55bcSBaptiste Daroussin 
135061ba55bcSBaptiste Daroussin 	if (d->conf->shadow) {
135161ba55bcSBaptiste Daroussin 		if ((d->shadow = newwin(1, 1, 1, 1)) == NULL)
135261ba55bcSBaptiste Daroussin 			RETURN_ERROR("Cannot build WINDOW shadow");
135361ba55bcSBaptiste Daroussin 		wbkgd(d->shadow, t.shadow.color);
1354c76f0793SBaptiste Daroussin 	}
1355c76f0793SBaptiste Daroussin 
135661ba55bcSBaptiste Daroussin 	if ((d->widget = newwin(1, 1, 1, 1)) == NULL)
135761ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot build WINDOW widget");
135861ba55bcSBaptiste Daroussin 	wbkgd(d->widget, t.dialog.color);
1359263660c0SAlfonso Siciliano 
136061ba55bcSBaptiste Daroussin 	/* fake for textpad */
136161ba55bcSBaptiste Daroussin 	if ((d->textpad = newpad(1, 1)) == NULL)
136261ba55bcSBaptiste Daroussin 		RETURN_ERROR("Cannot build the pad WINDOW for text");
136361ba55bcSBaptiste Daroussin 	wbkgd(d->textpad, t.dialog.color);
1364263660c0SAlfonso Siciliano 
136561ba55bcSBaptiste Daroussin 	return (0);
1366c76f0793SBaptiste Daroussin }