xref: /freebsd-src/contrib/bsddialog/lib/lib_util.c (revision f499134dd403eeeba8283e2640e2654c8da62430)
1c76f0793SBaptiste Daroussin /*-
2c76f0793SBaptiste Daroussin  * SPDX-License-Identifier: BSD-2-Clause
3c76f0793SBaptiste Daroussin  *
4c76f0793SBaptiste Daroussin  * Copyright (c) 2021 Alfonso Sabato Siciliano
5c76f0793SBaptiste Daroussin  *
6c76f0793SBaptiste Daroussin  * Redistribution and use in source and binary forms, with or without
7c76f0793SBaptiste Daroussin  * modification, are permitted provided that the following conditions
8c76f0793SBaptiste Daroussin  * are met:
9c76f0793SBaptiste Daroussin  * 1. Redistributions of source code must retain the above copyright
10c76f0793SBaptiste Daroussin  *    notice, this list of conditions and the following disclaimer.
11c76f0793SBaptiste Daroussin  * 2. Redistributions in binary form must reproduce the above copyright
12c76f0793SBaptiste Daroussin  *    notice, this list of conditions and the following disclaimer in the
13c76f0793SBaptiste Daroussin  *    documentation and/or other materials provided with the distribution.
14c76f0793SBaptiste Daroussin  *
15c76f0793SBaptiste Daroussin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16c76f0793SBaptiste Daroussin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17c76f0793SBaptiste Daroussin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18c76f0793SBaptiste Daroussin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19c76f0793SBaptiste Daroussin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20c76f0793SBaptiste Daroussin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21c76f0793SBaptiste Daroussin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22c76f0793SBaptiste Daroussin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23c76f0793SBaptiste Daroussin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24c76f0793SBaptiste Daroussin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25c76f0793SBaptiste Daroussin  * SUCH DAMAGE.
26c76f0793SBaptiste Daroussin  */
27c76f0793SBaptiste Daroussin 
28c76f0793SBaptiste Daroussin #include <sys/param.h>
29c76f0793SBaptiste Daroussin 
30c76f0793SBaptiste Daroussin #include <stdlib.h>
31c76f0793SBaptiste Daroussin #include <string.h>
32c76f0793SBaptiste Daroussin #include <unistd.h>
33c76f0793SBaptiste Daroussin 
34c76f0793SBaptiste Daroussin #ifdef PORTNCURSES
35c76f0793SBaptiste Daroussin #include <ncurses/curses.h>
36c76f0793SBaptiste Daroussin #else
37c76f0793SBaptiste Daroussin #include <curses.h>
38c76f0793SBaptiste Daroussin #endif
39c76f0793SBaptiste Daroussin 
40c76f0793SBaptiste Daroussin #include "bsddialog.h"
41c76f0793SBaptiste Daroussin #include "lib_util.h"
42c76f0793SBaptiste Daroussin #include "bsddialog_theme.h"
43c76f0793SBaptiste Daroussin 
44c76f0793SBaptiste Daroussin extern struct bsddialog_theme t;
45c76f0793SBaptiste Daroussin 
46c76f0793SBaptiste Daroussin /* Error buffer */
47c76f0793SBaptiste Daroussin 
48c76f0793SBaptiste Daroussin #define ERRBUFLEN 1024
49c76f0793SBaptiste Daroussin static char errorbuffer[ERRBUFLEN];
50c76f0793SBaptiste Daroussin 
51c76f0793SBaptiste Daroussin const char *get_error_string(void)
52c76f0793SBaptiste Daroussin {
53c76f0793SBaptiste Daroussin 	return errorbuffer;
54c76f0793SBaptiste Daroussin }
55c76f0793SBaptiste Daroussin 
56c76f0793SBaptiste Daroussin void set_error_string(char *str)
57c76f0793SBaptiste Daroussin {
58c76f0793SBaptiste Daroussin 
59c76f0793SBaptiste Daroussin 	strncpy(errorbuffer, str, ERRBUFLEN-1);
60c76f0793SBaptiste Daroussin }
61c76f0793SBaptiste Daroussin 
62c76f0793SBaptiste Daroussin /* cleaner */
63c76f0793SBaptiste Daroussin int hide_widget(int y, int x, int h, int w, bool withshadow)
64c76f0793SBaptiste Daroussin {
65c76f0793SBaptiste Daroussin 	WINDOW *clear;
66c76f0793SBaptiste Daroussin 
67c76f0793SBaptiste Daroussin 	/* no check: y, x, h and w are checked by the builders */
68*f499134dSBaptiste Daroussin 	if ((clear = newwin(h, w, y + t.shadow.h, x + t.shadow.w)) == NULL)
69c76f0793SBaptiste Daroussin 		RETURN_ERROR("Cannot hide the widget");
70*f499134dSBaptiste Daroussin 	wbkgd(clear, t.terminal.color);
71c76f0793SBaptiste Daroussin 
72c76f0793SBaptiste Daroussin 	if (withshadow)
73c76f0793SBaptiste Daroussin 		wrefresh(clear);
74c76f0793SBaptiste Daroussin 
75c76f0793SBaptiste Daroussin 	mvwin(clear, y, x);
76c76f0793SBaptiste Daroussin 	wrefresh(clear);
77c76f0793SBaptiste Daroussin 
78c76f0793SBaptiste Daroussin 	delwin(clear);
79c76f0793SBaptiste Daroussin 
80c76f0793SBaptiste Daroussin 	return 0;
81c76f0793SBaptiste Daroussin }
82c76f0793SBaptiste Daroussin 
83c76f0793SBaptiste Daroussin /* F1 help */
84*f499134dSBaptiste Daroussin int f1help(struct bsddialog_conf *conf)
85c76f0793SBaptiste Daroussin {
86*f499134dSBaptiste Daroussin 	char *file = conf->hfile;
87*f499134dSBaptiste Daroussin 	char *title = conf->title;
88c76f0793SBaptiste Daroussin 	int output;
89c76f0793SBaptiste Daroussin 
90*f499134dSBaptiste Daroussin 	conf->hfile = NULL;
91*f499134dSBaptiste Daroussin 	conf->clear = true;
92*f499134dSBaptiste Daroussin 	conf->y = BSDDIALOG_CENTER;
93*f499134dSBaptiste Daroussin 	conf->x = BSDDIALOG_CENTER;
94*f499134dSBaptiste Daroussin 	conf->title = "HELP";
95*f499134dSBaptiste Daroussin 	conf->sleep = 0;
96c76f0793SBaptiste Daroussin 
97c76f0793SBaptiste Daroussin 	output = bsddialog_textbox(conf, file, BSDDIALOG_AUTOSIZE,
98c76f0793SBaptiste Daroussin 	    BSDDIALOG_AUTOSIZE);
99*f499134dSBaptiste Daroussin 	conf->hfile = file;
100*f499134dSBaptiste Daroussin 	conf->title = title;
101c76f0793SBaptiste Daroussin 
102c76f0793SBaptiste Daroussin 	return output;
103c76f0793SBaptiste Daroussin }
104c76f0793SBaptiste Daroussin 
105c76f0793SBaptiste Daroussin /* Buttons */
106c76f0793SBaptiste Daroussin void
107c76f0793SBaptiste Daroussin draw_button(WINDOW *window, int y, int x, int size, char *text, bool selected,
108c76f0793SBaptiste Daroussin     bool shortkey)
109c76f0793SBaptiste Daroussin {
110c76f0793SBaptiste Daroussin 	int i, color_arrows, color_shortkey, color_button;
111c76f0793SBaptiste Daroussin 
112c76f0793SBaptiste Daroussin 	if (selected) {
113*f499134dSBaptiste Daroussin 		color_arrows = t.button.f_delimcolor;
114*f499134dSBaptiste Daroussin 		color_shortkey = t.button.f_shortcutcolor;
115*f499134dSBaptiste Daroussin 		color_button = t.button.f_color;
116c76f0793SBaptiste Daroussin 	} else {
117*f499134dSBaptiste Daroussin 		color_arrows = t.button.delimcolor;
118*f499134dSBaptiste Daroussin 		color_shortkey = t.button.shortcutcolor;
119*f499134dSBaptiste Daroussin 		color_button = t.button.color;
120c76f0793SBaptiste Daroussin 	}
121c76f0793SBaptiste Daroussin 
122c76f0793SBaptiste Daroussin 	wattron(window, color_arrows);
123*f499134dSBaptiste Daroussin 	mvwaddch(window, y, x, t.button.leftch);
124c76f0793SBaptiste Daroussin 	wattroff(window, color_arrows);
125c76f0793SBaptiste Daroussin 	wattron(window, color_button);
126c76f0793SBaptiste Daroussin 	for(i = 1; i < size - 1; i++)
127c76f0793SBaptiste Daroussin 		waddch(window, ' ');
128c76f0793SBaptiste Daroussin 	wattroff(window, color_button);
129c76f0793SBaptiste Daroussin 	wattron(window, color_arrows);
130*f499134dSBaptiste Daroussin 	mvwaddch(window, y, x + i, t.button.rightch);
131c76f0793SBaptiste Daroussin 	wattroff(window, color_arrows);
132c76f0793SBaptiste Daroussin 
133c76f0793SBaptiste Daroussin 	x = x + 1 + ((size - 2 - strlen(text))/2);
134c76f0793SBaptiste Daroussin 	wattron(window, color_button);
135c76f0793SBaptiste Daroussin 	mvwaddstr(window, y, x, text);
136c76f0793SBaptiste Daroussin 	wattroff(window, color_button);
137c76f0793SBaptiste Daroussin 
138c76f0793SBaptiste Daroussin 	if (shortkey) {
139c76f0793SBaptiste Daroussin 		wattron(window, color_shortkey);
140c76f0793SBaptiste Daroussin 		mvwaddch(window, y, x, text[0]);
141c76f0793SBaptiste Daroussin 		wattroff(window, color_shortkey);
142c76f0793SBaptiste Daroussin 	}
143c76f0793SBaptiste Daroussin }
144c76f0793SBaptiste Daroussin 
145c76f0793SBaptiste Daroussin void
146c76f0793SBaptiste Daroussin draw_buttons(WINDOW *window, int y, int cols, struct buttons bs, bool shortkey)
147c76f0793SBaptiste Daroussin {
148c76f0793SBaptiste Daroussin 	int i, x, start_x;
149c76f0793SBaptiste Daroussin 
150*f499134dSBaptiste Daroussin 	start_x = bs.sizebutton * bs.nbuttons + (bs.nbuttons - 1) * t.button.space;
151c76f0793SBaptiste Daroussin 	start_x = cols/2 - start_x/2;
152c76f0793SBaptiste Daroussin 
153c76f0793SBaptiste Daroussin 	for (i = 0; i < (int) bs.nbuttons; i++) {
154*f499134dSBaptiste Daroussin 		x = i * (bs.sizebutton + t.button.space);
155c76f0793SBaptiste Daroussin 		draw_button(window, y, start_x + x, bs.sizebutton, bs.label[i],
156c76f0793SBaptiste Daroussin 		    i == bs.curr, shortkey);
157c76f0793SBaptiste Daroussin 	}
158c76f0793SBaptiste Daroussin }
159c76f0793SBaptiste Daroussin 
160c76f0793SBaptiste Daroussin void
161*f499134dSBaptiste Daroussin get_buttons(struct bsddialog_conf *conf, struct buttons *bs, char *yesoklabel,
162c76f0793SBaptiste Daroussin     char *extralabel, char *nocancellabel, char *helplabel)
163c76f0793SBaptiste Daroussin {
164c76f0793SBaptiste Daroussin 	int i;
165c76f0793SBaptiste Daroussin #define SIZEBUTTON  8
166c76f0793SBaptiste Daroussin #define DEFAULT_BUTTON_LABEL	LABEL_ok_label
167c76f0793SBaptiste Daroussin #define DEFAULT_BUTTON_VALUE	BSDDIALOG_YESOK
168c76f0793SBaptiste Daroussin 
169c76f0793SBaptiste Daroussin 
170c76f0793SBaptiste Daroussin 	bs->nbuttons = 0;
171c76f0793SBaptiste Daroussin 	bs->curr = 0;
172c76f0793SBaptiste Daroussin 	bs->sizebutton = 0;
173c76f0793SBaptiste Daroussin 
174*f499134dSBaptiste Daroussin 	if (yesoklabel != NULL && conf->button.no_ok == false) {
175c76f0793SBaptiste Daroussin 		bs->label[0] = yesoklabel;
176c76f0793SBaptiste Daroussin 		bs->value[0] = BSDDIALOG_YESOK;
177c76f0793SBaptiste Daroussin 		bs->nbuttons += 1;
178c76f0793SBaptiste Daroussin 	}
179c76f0793SBaptiste Daroussin 
180*f499134dSBaptiste Daroussin 	if (extralabel != NULL && conf->button.extra_button) {
181c76f0793SBaptiste Daroussin 		bs->label[bs->nbuttons] = extralabel;
182c76f0793SBaptiste Daroussin 		bs->value[bs->nbuttons] = BSDDIALOG_EXTRA;
183c76f0793SBaptiste Daroussin 		bs->nbuttons += 1;
184c76f0793SBaptiste Daroussin 	}
185c76f0793SBaptiste Daroussin 
186*f499134dSBaptiste Daroussin 	if (nocancellabel != NULL && conf->button.no_cancel == false) {
187c76f0793SBaptiste Daroussin 		bs->label[bs->nbuttons] = nocancellabel;
188c76f0793SBaptiste Daroussin 		bs->value[bs->nbuttons] = BSDDIALOG_NOCANCEL;
189*f499134dSBaptiste Daroussin 		if (conf->button.defaultno)
190c76f0793SBaptiste Daroussin 			bs->curr = bs->nbuttons;
191c76f0793SBaptiste Daroussin 		bs->nbuttons += 1;
192c76f0793SBaptiste Daroussin 	}
193c76f0793SBaptiste Daroussin 
194*f499134dSBaptiste Daroussin 	if (helplabel != NULL && conf->button.help_button) {
195c76f0793SBaptiste Daroussin 		bs->label[bs->nbuttons] = helplabel;
196c76f0793SBaptiste Daroussin 		bs->value[bs->nbuttons] = BSDDIALOG_HELP;
197c76f0793SBaptiste Daroussin 		bs->nbuttons += 1;
198c76f0793SBaptiste Daroussin 	}
199c76f0793SBaptiste Daroussin 
200*f499134dSBaptiste Daroussin 	if (conf->button.generic1_label != NULL) {
201*f499134dSBaptiste Daroussin 		bs->label[bs->nbuttons] = conf->button.generic1_label;
202*f499134dSBaptiste Daroussin 		bs->value[bs->nbuttons] = BSDDIALOG_GENERIC1;
203*f499134dSBaptiste Daroussin 		bs->nbuttons += 1;
204*f499134dSBaptiste Daroussin 	}
205*f499134dSBaptiste Daroussin 
206*f499134dSBaptiste Daroussin 	if (conf->button.generic2_label != NULL) {
207*f499134dSBaptiste Daroussin 		bs->label[bs->nbuttons] = conf->button.generic2_label;
208*f499134dSBaptiste Daroussin 		bs->value[bs->nbuttons] = BSDDIALOG_GENERIC2;
209*f499134dSBaptiste Daroussin 		bs->nbuttons += 1;
210*f499134dSBaptiste Daroussin 	}
211*f499134dSBaptiste Daroussin 
212c76f0793SBaptiste Daroussin 	if (bs->nbuttons == 0) {
213c76f0793SBaptiste Daroussin 		bs->label[0] = DEFAULT_BUTTON_LABEL;
214c76f0793SBaptiste Daroussin 		bs->value[0] = DEFAULT_BUTTON_VALUE;
215c76f0793SBaptiste Daroussin 		bs->nbuttons = 1;
216c76f0793SBaptiste Daroussin 	}
217c76f0793SBaptiste Daroussin 
218*f499134dSBaptiste Daroussin 	if (conf->button.default_label != NULL) {
219c76f0793SBaptiste Daroussin 		for (i=0; i<(int)bs->nbuttons; i++) {
220*f499134dSBaptiste Daroussin 			if (strcmp(conf->button.default_label, bs->label[i]) == 0)
221c76f0793SBaptiste Daroussin 				bs->curr = i;
222c76f0793SBaptiste Daroussin 		}
223c76f0793SBaptiste Daroussin 	}
224c76f0793SBaptiste Daroussin 
225c76f0793SBaptiste Daroussin 	bs->sizebutton = MAX(SIZEBUTTON - 2, strlen(bs->label[0]));
226c76f0793SBaptiste Daroussin 	for (i=1; i < (int) bs->nbuttons; i++)
227c76f0793SBaptiste Daroussin 		bs->sizebutton = MAX(bs->sizebutton, strlen(bs->label[i]));
228c76f0793SBaptiste Daroussin 	bs->sizebutton += 2;
229c76f0793SBaptiste Daroussin }
230c76f0793SBaptiste Daroussin 
231c76f0793SBaptiste Daroussin /* Text */
232*f499134dSBaptiste Daroussin static bool is_ncurses_attr(char *text)
233*f499134dSBaptiste Daroussin {
234c76f0793SBaptiste Daroussin 
235*f499134dSBaptiste Daroussin 	if (strnlen(text, 3) < 3)
236*f499134dSBaptiste Daroussin 		return false;
237*f499134dSBaptiste Daroussin 
238*f499134dSBaptiste Daroussin 	if (text[0] != '\\' || text[1] != 'Z')
239*f499134dSBaptiste Daroussin 		return false;
240*f499134dSBaptiste Daroussin 
241*f499134dSBaptiste Daroussin 	return (strchr("nbBrRuU01234567", text[2]) == NULL ? false : true);
242*f499134dSBaptiste Daroussin }
243c76f0793SBaptiste Daroussin 
244c76f0793SBaptiste Daroussin static bool check_set_ncurses_attr(WINDOW *win, char *text)
245c76f0793SBaptiste Daroussin {
246c76f0793SBaptiste Daroussin 
247*f499134dSBaptiste Daroussin 	if (is_ncurses_attr(text) == false)
248c76f0793SBaptiste Daroussin 		return false;
249c76f0793SBaptiste Daroussin 
250*f499134dSBaptiste Daroussin 	if ((text[2] - '0') >= 0 && (text[2] - '0') < 8) {
251*f499134dSBaptiste Daroussin 		wattron(win, bsddialog_color( text[2] - '0', COLOR_WHITE) );
252c76f0793SBaptiste Daroussin 		return true;
253c76f0793SBaptiste Daroussin 	}
254c76f0793SBaptiste Daroussin 
255c76f0793SBaptiste Daroussin 	switch (text[2]) {
256c76f0793SBaptiste Daroussin 	case 'n':
257c76f0793SBaptiste Daroussin 		wattrset(win, A_NORMAL);
258c76f0793SBaptiste Daroussin 		break;
259c76f0793SBaptiste Daroussin 	case 'b':
260c76f0793SBaptiste Daroussin 		wattron(win, A_BOLD);
261c76f0793SBaptiste Daroussin 		break;
262c76f0793SBaptiste Daroussin 	case 'B':
263c76f0793SBaptiste Daroussin 		wattroff(win, A_BOLD);
264c76f0793SBaptiste Daroussin 		break;
265c76f0793SBaptiste Daroussin 	case 'r':
266c76f0793SBaptiste Daroussin 		wattron(win, A_REVERSE);
267c76f0793SBaptiste Daroussin 		break;
268c76f0793SBaptiste Daroussin 	case 'R':
269c76f0793SBaptiste Daroussin 		wattroff(win, A_REVERSE);
270c76f0793SBaptiste Daroussin 		break;
271c76f0793SBaptiste Daroussin 	case 'u':
272c76f0793SBaptiste Daroussin 		wattron(win, A_UNDERLINE);
273c76f0793SBaptiste Daroussin 		break;
274c76f0793SBaptiste Daroussin 	case 'U':
275c76f0793SBaptiste Daroussin 		wattroff(win, A_UNDERLINE);
276c76f0793SBaptiste Daroussin 		break;
277c76f0793SBaptiste Daroussin 	}
278c76f0793SBaptiste Daroussin 
279c76f0793SBaptiste Daroussin 	return true;
280c76f0793SBaptiste Daroussin }
281c76f0793SBaptiste Daroussin 
282c76f0793SBaptiste Daroussin static void
283c76f0793SBaptiste Daroussin print_str(WINDOW *win, int *rows, int *y, int *x, int cols, char *str, bool color)
284c76f0793SBaptiste Daroussin {
285c76f0793SBaptiste Daroussin 	int i, j, len, reallen;
286c76f0793SBaptiste Daroussin 
287c76f0793SBaptiste Daroussin 	if(strlen(str) == 0)
288c76f0793SBaptiste Daroussin 		return;
289c76f0793SBaptiste Daroussin 
290c76f0793SBaptiste Daroussin 	len = reallen = strlen(str);
291c76f0793SBaptiste Daroussin 	if (color) {
292c76f0793SBaptiste Daroussin 		i=0;
293c76f0793SBaptiste Daroussin 		while (i < len) {
294c76f0793SBaptiste Daroussin 			if (is_ncurses_attr(str+i))
295c76f0793SBaptiste Daroussin 				reallen -= 3;
296c76f0793SBaptiste Daroussin 			i++;
297c76f0793SBaptiste Daroussin 		}
298c76f0793SBaptiste Daroussin 	}
299c76f0793SBaptiste Daroussin 
300c76f0793SBaptiste Daroussin 	i = 0;
301c76f0793SBaptiste Daroussin 	while (i < len) {
302c76f0793SBaptiste Daroussin 		if (*x + reallen > cols) {
303c76f0793SBaptiste Daroussin 			*y = (*x != 0 ? *y+1 : *y);
304c76f0793SBaptiste Daroussin 			if (*y >= *rows) {
305c76f0793SBaptiste Daroussin 				*rows = *y + 1;
306c76f0793SBaptiste Daroussin 				wresize(win, *rows, cols);
307c76f0793SBaptiste Daroussin 			}
308c76f0793SBaptiste Daroussin 			*x = 0;
309c76f0793SBaptiste Daroussin 		}
310c76f0793SBaptiste Daroussin 		j = *x;
311c76f0793SBaptiste Daroussin 		while (j < cols && i < len) {
312c76f0793SBaptiste Daroussin 			if (color && check_set_ncurses_attr(win, str+i)) {
313c76f0793SBaptiste Daroussin 				i += 3;
314c76f0793SBaptiste Daroussin 			} else {
315c76f0793SBaptiste Daroussin 				mvwaddch(win, *y, j, str[i]);
316c76f0793SBaptiste Daroussin 				i++;
317c76f0793SBaptiste Daroussin 				reallen--;
318c76f0793SBaptiste Daroussin 				j++;
319c76f0793SBaptiste Daroussin 				*x = j;
320c76f0793SBaptiste Daroussin 			}
321c76f0793SBaptiste Daroussin 		}
322c76f0793SBaptiste Daroussin 	}
323c76f0793SBaptiste Daroussin }
324c76f0793SBaptiste Daroussin 
325*f499134dSBaptiste Daroussin static void prepare_text(struct bsddialog_conf *conf, char *text, char *buf)
326c76f0793SBaptiste Daroussin {
327c76f0793SBaptiste Daroussin 	int i, j;
328c76f0793SBaptiste Daroussin 
329c76f0793SBaptiste Daroussin 	i = j = 0;
330c76f0793SBaptiste Daroussin 	while (text[i] != '\0') {
331c76f0793SBaptiste Daroussin 		switch (text[i]) {
332c76f0793SBaptiste Daroussin 		case '\\':
333c76f0793SBaptiste Daroussin 			buf[j] = '\\';
334c76f0793SBaptiste Daroussin 			switch (text[i+1]) {
335c76f0793SBaptiste Daroussin 			case '\\':
336c76f0793SBaptiste Daroussin 				i++;
337c76f0793SBaptiste Daroussin 				break;
338c76f0793SBaptiste Daroussin 			case 'n':
339*f499134dSBaptiste Daroussin 				if (conf->text.no_nl_expand) {
340c76f0793SBaptiste Daroussin 					j++;
341c76f0793SBaptiste Daroussin 					buf[j] = 'n';
342c76f0793SBaptiste Daroussin 				} else
343c76f0793SBaptiste Daroussin 					buf[j] = '\n';
344c76f0793SBaptiste Daroussin 				i++;
345c76f0793SBaptiste Daroussin 				break;
346c76f0793SBaptiste Daroussin 			case 't':
347*f499134dSBaptiste Daroussin 				if (conf->text.no_collapse) {
348c76f0793SBaptiste Daroussin 					j++;
349c76f0793SBaptiste Daroussin 					buf[j] = 't';
350c76f0793SBaptiste Daroussin 				} else
351c76f0793SBaptiste Daroussin 					buf[j] = '\t';
352c76f0793SBaptiste Daroussin 				i++;
353c76f0793SBaptiste Daroussin 				break;
354c76f0793SBaptiste Daroussin 			}
355c76f0793SBaptiste Daroussin 			break;
356c76f0793SBaptiste Daroussin 		case '\n':
357*f499134dSBaptiste Daroussin 			buf[j] = conf->text.cr_wrap ? ' ' : '\n';
358c76f0793SBaptiste Daroussin 			break;
359c76f0793SBaptiste Daroussin 		case '\t':
360*f499134dSBaptiste Daroussin 			buf[j] = conf->text.no_collapse ? '\t' : ' ';
361c76f0793SBaptiste Daroussin 			break;
362c76f0793SBaptiste Daroussin 		default:
363c76f0793SBaptiste Daroussin 			buf[j] = text[i];
364c76f0793SBaptiste Daroussin 		}
365c76f0793SBaptiste Daroussin 		i++;
366*f499134dSBaptiste Daroussin 		j += (buf[j] == ' ' && conf->text.trim && j > 0 && buf[j-1] == ' ') ?
367c76f0793SBaptiste Daroussin 		    0 : 1;
368c76f0793SBaptiste Daroussin 	}
369c76f0793SBaptiste Daroussin 	buf[j] = '\0';
370c76f0793SBaptiste Daroussin }
371c76f0793SBaptiste Daroussin 
372c76f0793SBaptiste Daroussin int
373*f499134dSBaptiste Daroussin get_text_properties(struct bsddialog_conf *conf, char *text, int *maxword,
374c76f0793SBaptiste Daroussin     int *maxline, int *nlines)
375c76f0793SBaptiste Daroussin {
376c76f0793SBaptiste Daroussin 	char *buf;
377c76f0793SBaptiste Daroussin 	int i, buflen, wordlen, linelen;
378c76f0793SBaptiste Daroussin 
379c76f0793SBaptiste Daroussin 	if ((buf = malloc(strlen(text) + 1)) == NULL)
380c76f0793SBaptiste Daroussin 		RETURN_ERROR("Cannot building a buffer to find the properties "\
381c76f0793SBaptiste Daroussin 		    "of the text properties");
382c76f0793SBaptiste Daroussin 
383c76f0793SBaptiste Daroussin 	prepare_text(conf, text, buf);
384c76f0793SBaptiste Daroussin 
385c76f0793SBaptiste Daroussin 	buflen = strlen(buf) + 1;
386c76f0793SBaptiste Daroussin 	*maxword = 0;
387c76f0793SBaptiste Daroussin 	wordlen = 0;
388c76f0793SBaptiste Daroussin 	for (i=0; i < buflen; i++) {
389c76f0793SBaptiste Daroussin 		if (buf[i] == '\t' || buf[i] == '\n' || buf[i] == ' ' || buf[i] == '\0')
390c76f0793SBaptiste Daroussin 			if (wordlen != 0) {
391c76f0793SBaptiste Daroussin 				*maxword = MAX(*maxword, wordlen);
392c76f0793SBaptiste Daroussin 				wordlen = 0;
393c76f0793SBaptiste Daroussin 				continue;
394c76f0793SBaptiste Daroussin 			}
395*f499134dSBaptiste Daroussin 		if (conf->text.colors && is_ncurses_attr(buf + i))
396c76f0793SBaptiste Daroussin 			i += 3;
397c76f0793SBaptiste Daroussin 		else
398c76f0793SBaptiste Daroussin 			wordlen++;
399c76f0793SBaptiste Daroussin 	}
400c76f0793SBaptiste Daroussin 
401c76f0793SBaptiste Daroussin 	*maxline = linelen = 0;
402c76f0793SBaptiste Daroussin 	*nlines = 1;
403c76f0793SBaptiste Daroussin 	for (i=0; i < buflen; i++) {
404c76f0793SBaptiste Daroussin 		switch (buf[i]) {
405c76f0793SBaptiste Daroussin 		case '\n':
406c76f0793SBaptiste Daroussin 			*nlines = *nlines + 1;
407c76f0793SBaptiste Daroussin 		case '\0':
408c76f0793SBaptiste Daroussin 			*maxline = MAX(*maxline, linelen);
409c76f0793SBaptiste Daroussin 			linelen = 0;
410c76f0793SBaptiste Daroussin 			break;
411c76f0793SBaptiste Daroussin 		default:
412*f499134dSBaptiste Daroussin 			if (conf->text.colors && is_ncurses_attr(buf + i))
413c76f0793SBaptiste Daroussin 				i += 3;
414c76f0793SBaptiste Daroussin 			else
415c76f0793SBaptiste Daroussin 				linelen++;
416c76f0793SBaptiste Daroussin 		}
417c76f0793SBaptiste Daroussin 	}
418c76f0793SBaptiste Daroussin 	if (*nlines == 1 && *maxline == 0)
419c76f0793SBaptiste Daroussin 		*nlines = 0;
420c76f0793SBaptiste Daroussin 
421c76f0793SBaptiste Daroussin 	free(buf);
422c76f0793SBaptiste Daroussin 
423c76f0793SBaptiste Daroussin 	return 0;
424c76f0793SBaptiste Daroussin }
425c76f0793SBaptiste Daroussin 
426*f499134dSBaptiste Daroussin int
427*f499134dSBaptiste Daroussin print_textpad(struct bsddialog_conf *conf, WINDOW *pad, int *rows, int cols,
428*f499134dSBaptiste Daroussin     char *text)
429c76f0793SBaptiste Daroussin {
430c76f0793SBaptiste Daroussin 	char *buf, *string;
431c76f0793SBaptiste Daroussin 	int i, j, x, y;
432c76f0793SBaptiste Daroussin 	bool loop;
433c76f0793SBaptiste Daroussin 
434c76f0793SBaptiste Daroussin 	if ((buf = malloc(strlen(text) + 1)) == NULL)
435c76f0793SBaptiste Daroussin 		RETURN_ERROR("Cannot build (analyze) text");
436c76f0793SBaptiste Daroussin 
437c76f0793SBaptiste Daroussin 	prepare_text(conf, text, buf);
438c76f0793SBaptiste Daroussin 
439c76f0793SBaptiste Daroussin 	if ((string = malloc(strlen(text) + 1)) == NULL) {
440c76f0793SBaptiste Daroussin 		free(buf);
441c76f0793SBaptiste Daroussin 		RETURN_ERROR("Cannot build (analyze) text");
442c76f0793SBaptiste Daroussin 	}
443c76f0793SBaptiste Daroussin 	i = j = x = y = 0;
444c76f0793SBaptiste Daroussin 	loop = true;
445c76f0793SBaptiste Daroussin 	while (loop) {
446c76f0793SBaptiste Daroussin 		string[j] = buf[i];
447c76f0793SBaptiste Daroussin 
448c76f0793SBaptiste Daroussin 		if (string[j] == '\0' || string[j] == '\n' ||
449c76f0793SBaptiste Daroussin 		    string[j] == '\t' || string[j] == ' ') {
450c76f0793SBaptiste Daroussin 			if (j != 0) {
451c76f0793SBaptiste Daroussin 				string[j] = '\0';
452*f499134dSBaptiste Daroussin 				print_str(pad, rows, &y, &x, cols, string, conf->text.colors);
453c76f0793SBaptiste Daroussin 			}
454c76f0793SBaptiste Daroussin 		}
455c76f0793SBaptiste Daroussin 
456c76f0793SBaptiste Daroussin 		switch (buf[i]) {
457c76f0793SBaptiste Daroussin 		case '\0':
458c76f0793SBaptiste Daroussin 			loop = false;
459c76f0793SBaptiste Daroussin 			break;
460c76f0793SBaptiste Daroussin 		case '\n':
461c76f0793SBaptiste Daroussin 			j = -1;
462c76f0793SBaptiste Daroussin 			x = 0;
463c76f0793SBaptiste Daroussin 			y++;
464c76f0793SBaptiste Daroussin 			break;
465c76f0793SBaptiste Daroussin 		case '\t':
466c76f0793SBaptiste Daroussin 			for (j=0; j<4 /*tablen*/; j++) {
467c76f0793SBaptiste Daroussin 				x++;
468c76f0793SBaptiste Daroussin 				if (x >= cols) {
469c76f0793SBaptiste Daroussin 					x = 0;
470c76f0793SBaptiste Daroussin 					y++;
471c76f0793SBaptiste Daroussin 				}
472c76f0793SBaptiste Daroussin 			}
473c76f0793SBaptiste Daroussin 			j = -1;
474c76f0793SBaptiste Daroussin 			break;
475c76f0793SBaptiste Daroussin 		case ' ':
476c76f0793SBaptiste Daroussin 			x++;
477c76f0793SBaptiste Daroussin 			if (x >= cols) {
478c76f0793SBaptiste Daroussin 				x = 0;
479c76f0793SBaptiste Daroussin 				y++;
480c76f0793SBaptiste Daroussin 			}
481c76f0793SBaptiste Daroussin 			j = -1;
482c76f0793SBaptiste Daroussin 		}
483c76f0793SBaptiste Daroussin 
484c76f0793SBaptiste Daroussin 		if (y >= *rows) { /* check for whitespaces */
485c76f0793SBaptiste Daroussin 			*rows = y + 1;
486c76f0793SBaptiste Daroussin 			wresize(pad, *rows, cols);
487c76f0793SBaptiste Daroussin 		}
488c76f0793SBaptiste Daroussin 
489c76f0793SBaptiste Daroussin 		j++;
490c76f0793SBaptiste Daroussin 		i++;
491c76f0793SBaptiste Daroussin 	}
492c76f0793SBaptiste Daroussin 
493c76f0793SBaptiste Daroussin 	free(string);
494c76f0793SBaptiste Daroussin 	free(buf);
495c76f0793SBaptiste Daroussin 
496c76f0793SBaptiste Daroussin 	return 0;
497c76f0793SBaptiste Daroussin }
498c76f0793SBaptiste Daroussin 
499c76f0793SBaptiste Daroussin /* autosize */
500c76f0793SBaptiste Daroussin 
501c76f0793SBaptiste Daroussin /*
502c76f0793SBaptiste Daroussin  * max y, that is from 0 to LINES - 1 - t.shadowrows,
503c76f0793SBaptiste Daroussin  * could not be max height but avoids problems with checksize
504c76f0793SBaptiste Daroussin  */
505*f499134dSBaptiste Daroussin int widget_max_height(struct bsddialog_conf *conf)
506c76f0793SBaptiste Daroussin {
507c76f0793SBaptiste Daroussin 	int maxheight;
508c76f0793SBaptiste Daroussin 
509*f499134dSBaptiste Daroussin 	if ((maxheight = conf->shadow ? LINES - 1 - t.shadow.h : LINES - 1) <= 0)
510c76f0793SBaptiste Daroussin 		RETURN_ERROR("Terminal too small, LINES - shadow <= 0");
511c76f0793SBaptiste Daroussin 
512*f499134dSBaptiste Daroussin 	if (conf->y > 0)
513*f499134dSBaptiste Daroussin 		if ((maxheight -= conf->y) <=0)
514c76f0793SBaptiste Daroussin 			RETURN_ERROR("Terminal too small, LINES - shadow - y <= 0");
515c76f0793SBaptiste Daroussin 
516c76f0793SBaptiste Daroussin 	return maxheight;
517c76f0793SBaptiste Daroussin }
518c76f0793SBaptiste Daroussin 
519c76f0793SBaptiste Daroussin /*
520c76f0793SBaptiste Daroussin  * max x, that is from 0 to COLS - 1 - t.shadowcols,
521c76f0793SBaptiste Daroussin  *  * could not be max height but avoids problems with checksize
522c76f0793SBaptiste Daroussin  */
523*f499134dSBaptiste Daroussin int widget_max_width(struct bsddialog_conf *conf)
524c76f0793SBaptiste Daroussin {
525c76f0793SBaptiste Daroussin 	int maxwidth;
526c76f0793SBaptiste Daroussin 
527*f499134dSBaptiste Daroussin 	if ((maxwidth = conf->shadow ? COLS - 1 - t.shadow.w : COLS - 1)  <= 0)
528c76f0793SBaptiste Daroussin 		RETURN_ERROR("Terminal too small, COLS - shadow <= 0");
529*f499134dSBaptiste Daroussin 	if (conf->x > 0)
530*f499134dSBaptiste Daroussin 		if ((maxwidth -= conf->x) <=0)
531c76f0793SBaptiste Daroussin 			RETURN_ERROR("Terminal too small, COLS - shadow - x <= 0");
532c76f0793SBaptiste Daroussin 
533c76f0793SBaptiste Daroussin 	return maxwidth;
534c76f0793SBaptiste Daroussin }
535c76f0793SBaptiste Daroussin 
536c76f0793SBaptiste Daroussin int
537*f499134dSBaptiste Daroussin set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w)
538c76f0793SBaptiste Daroussin {
539c76f0793SBaptiste Daroussin 	int maxheight, maxwidth;
540c76f0793SBaptiste Daroussin 
541c76f0793SBaptiste Daroussin 	if ((maxheight = widget_max_height(conf)) == BSDDIALOG_ERROR)
542c76f0793SBaptiste Daroussin 		return BSDDIALOG_ERROR;
543c76f0793SBaptiste Daroussin 
544c76f0793SBaptiste Daroussin 	if (rows == BSDDIALOG_FULLSCREEN)
545c76f0793SBaptiste Daroussin 		*h = maxheight;
546c76f0793SBaptiste Daroussin 	else if (rows < BSDDIALOG_FULLSCREEN)
547c76f0793SBaptiste Daroussin 		RETURN_ERROR("Negative (less than -1) height");
548c76f0793SBaptiste Daroussin 	else if (rows > BSDDIALOG_AUTOSIZE) {
549c76f0793SBaptiste Daroussin 		if ((*h = rows) > maxheight)
550c76f0793SBaptiste Daroussin 			RETURN_ERROR("Height too big (> terminal height - "\
551c76f0793SBaptiste Daroussin 			    "shadow");
552c76f0793SBaptiste Daroussin 	}
553c76f0793SBaptiste Daroussin 	/* rows == AUTOSIZE: each widget has to set its size */
554c76f0793SBaptiste Daroussin 
555c76f0793SBaptiste Daroussin 	if ((maxwidth = widget_max_width(conf)) == BSDDIALOG_ERROR)
556c76f0793SBaptiste Daroussin 		return BSDDIALOG_ERROR;
557c76f0793SBaptiste Daroussin 
558c76f0793SBaptiste Daroussin 	if (cols == BSDDIALOG_FULLSCREEN)
559c76f0793SBaptiste Daroussin 		*w = maxwidth;
560c76f0793SBaptiste Daroussin 	else if (cols < BSDDIALOG_FULLSCREEN)
561c76f0793SBaptiste Daroussin 		RETURN_ERROR("Negative (less than -1) width");
562c76f0793SBaptiste Daroussin 	else if (cols > BSDDIALOG_AUTOSIZE) {
563c76f0793SBaptiste Daroussin 		if ((*w = cols) > maxwidth)
564c76f0793SBaptiste Daroussin 			RETURN_ERROR("Width too big (> terminal width - shadow)");
565c76f0793SBaptiste Daroussin 	}
566c76f0793SBaptiste Daroussin 	/* cols == AUTOSIZE: each widget has to set its size */
567c76f0793SBaptiste Daroussin 
568c76f0793SBaptiste Daroussin 	return 0;
569c76f0793SBaptiste Daroussin }
570c76f0793SBaptiste Daroussin 
571c76f0793SBaptiste Daroussin int
572*f499134dSBaptiste Daroussin set_widget_position(struct bsddialog_conf *conf, int *y, int *x, int h, int w)
573c76f0793SBaptiste Daroussin {
574c76f0793SBaptiste Daroussin 
575*f499134dSBaptiste Daroussin 	if (conf->y == BSDDIALOG_CENTER)
576c76f0793SBaptiste Daroussin 		*y = LINES/2 - h/2;
577*f499134dSBaptiste Daroussin 	else if (conf->y < BSDDIALOG_CENTER)
578c76f0793SBaptiste Daroussin 		RETURN_ERROR("Negative begin y (less than -1)");
579*f499134dSBaptiste Daroussin 	else if (conf->y >= LINES)
580c76f0793SBaptiste Daroussin 		RETURN_ERROR("Begin Y under the terminal");
581c76f0793SBaptiste Daroussin 	else
582*f499134dSBaptiste Daroussin 		*y = conf->y;
583c76f0793SBaptiste Daroussin 
584*f499134dSBaptiste Daroussin 	if ((*y + h + (conf->shadow ? (int) t.shadow.h : 0)) > LINES)
585c76f0793SBaptiste Daroussin 		RETURN_ERROR("The lower of the box under the terminal "\
586c76f0793SBaptiste Daroussin 		    "(begin Y + height (+ shadow) > terminal lines)");
587c76f0793SBaptiste Daroussin 
588c76f0793SBaptiste Daroussin 
589*f499134dSBaptiste Daroussin 	if (conf->x == BSDDIALOG_CENTER)
590c76f0793SBaptiste Daroussin 		*x = COLS/2 - w/2;
591*f499134dSBaptiste Daroussin 	else if (conf->x < BSDDIALOG_CENTER)
592c76f0793SBaptiste Daroussin 		RETURN_ERROR("Negative begin x (less than -1)");
593*f499134dSBaptiste Daroussin 	else if (conf->x >= COLS)
594c76f0793SBaptiste Daroussin 		RETURN_ERROR("Begin X over the right of the terminal");
595c76f0793SBaptiste Daroussin 	else
596*f499134dSBaptiste Daroussin 		*x = conf->x;
597c76f0793SBaptiste Daroussin 
598*f499134dSBaptiste Daroussin 	if ((*x + w + (conf->shadow ? (int) t.shadow.w : 0)) > COLS)
599c76f0793SBaptiste Daroussin 		RETURN_ERROR("The right of the box over the terminal "\
600c76f0793SBaptiste Daroussin 		    "(begin X + width (+ shadow) > terminal cols)");
601c76f0793SBaptiste Daroussin 
602c76f0793SBaptiste Daroussin 	return 0;
603c76f0793SBaptiste Daroussin }
604c76f0793SBaptiste Daroussin 
605c76f0793SBaptiste Daroussin /* Widgets builders */
606c76f0793SBaptiste Daroussin void
607*f499134dSBaptiste Daroussin draw_borders(struct bsddialog_conf *conf, WINDOW *win, int rows, int cols,
608c76f0793SBaptiste Daroussin     enum elevation elev)
609c76f0793SBaptiste Daroussin {
610c76f0793SBaptiste Daroussin 	int leftcolor, rightcolor;
611c76f0793SBaptiste Daroussin 	int ls, rs, ts, bs, tl, tr, bl, br;
612c76f0793SBaptiste Daroussin 	int ltee, rtee;
613c76f0793SBaptiste Daroussin 
614c76f0793SBaptiste Daroussin 	ls = rs = ACS_VLINE;
615c76f0793SBaptiste Daroussin 	ts = bs = ACS_HLINE;
616c76f0793SBaptiste Daroussin 	tl = ACS_ULCORNER;
617c76f0793SBaptiste Daroussin 	tr = ACS_URCORNER;
618c76f0793SBaptiste Daroussin 	bl = ACS_LLCORNER;
619c76f0793SBaptiste Daroussin 	br = ACS_LRCORNER;
620c76f0793SBaptiste Daroussin 	ltee = ACS_LTEE;
621c76f0793SBaptiste Daroussin 	rtee = ACS_RTEE;
622c76f0793SBaptiste Daroussin 
623*f499134dSBaptiste Daroussin 	if (conf->no_lines == false) {
624*f499134dSBaptiste Daroussin 		if (conf->ascii_lines) {
625c76f0793SBaptiste Daroussin 			ls = rs = '|';
626c76f0793SBaptiste Daroussin 			ts = bs = '-';
627c76f0793SBaptiste Daroussin 			tl = tr = bl = br = ltee = rtee = '+';
628c76f0793SBaptiste Daroussin 		}
629*f499134dSBaptiste Daroussin 		leftcolor  = elev == RAISED ? t.widget.lineraisecolor : t.widget.linelowercolor;
630*f499134dSBaptiste Daroussin 		rightcolor = elev == RAISED ? t.widget.linelowercolor : t.widget.lineraisecolor;
631c76f0793SBaptiste Daroussin 		wattron(win, leftcolor);
632c76f0793SBaptiste Daroussin 		wborder(win, ls, rs, ts, bs, tl, tr, bl, br);
633c76f0793SBaptiste Daroussin 		wattroff(win, leftcolor);
634c76f0793SBaptiste Daroussin 
635c76f0793SBaptiste Daroussin 		wattron(win, rightcolor);
636c76f0793SBaptiste Daroussin 		mvwaddch(win, 0, cols-1, tr);
637c76f0793SBaptiste Daroussin 		mvwvline(win, 1, cols-1, rs, rows-2);
638c76f0793SBaptiste Daroussin 		mvwaddch(win, rows-1, cols-1, br);
639c76f0793SBaptiste Daroussin 		mvwhline(win, rows-1, 1, bs, cols-2);
640c76f0793SBaptiste Daroussin 		wattroff(win, rightcolor);
641c76f0793SBaptiste Daroussin 	}
642c76f0793SBaptiste Daroussin }
643c76f0793SBaptiste Daroussin 
644c76f0793SBaptiste Daroussin WINDOW *
645*f499134dSBaptiste Daroussin new_boxed_window(struct bsddialog_conf *conf, int y, int x, int rows, int cols,
646c76f0793SBaptiste Daroussin     enum elevation elev)
647c76f0793SBaptiste Daroussin {
648c76f0793SBaptiste Daroussin 	WINDOW *win;
649c76f0793SBaptiste Daroussin 
650c76f0793SBaptiste Daroussin 	if ((win = newwin(rows, cols, y, x)) == NULL) {
651c76f0793SBaptiste Daroussin 		set_error_string("Cannot build boxed window");
652c76f0793SBaptiste Daroussin 		return NULL;
653c76f0793SBaptiste Daroussin 	}
654c76f0793SBaptiste Daroussin 
655*f499134dSBaptiste Daroussin 	wbkgd(win, t.widget.color);
656c76f0793SBaptiste Daroussin 
657c76f0793SBaptiste Daroussin 	draw_borders(conf, win, rows, cols, elev);
658c76f0793SBaptiste Daroussin 
659c76f0793SBaptiste Daroussin 	return win;
660c76f0793SBaptiste Daroussin }
661c76f0793SBaptiste Daroussin 
662c76f0793SBaptiste Daroussin /*
663c76f0793SBaptiste Daroussin  * `enum elevation elev` could be useless because it should be always RAISED,
664c76f0793SBaptiste Daroussin  * to check at the end.
665c76f0793SBaptiste Daroussin  */
666c76f0793SBaptiste Daroussin static int
667*f499134dSBaptiste Daroussin draw_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *shadow,
668c76f0793SBaptiste Daroussin     WINDOW *widget, int h, int w, enum elevation elev,
669c76f0793SBaptiste Daroussin     WINDOW *textpad, int *htextpad, char *text, bool buttons)
670c76f0793SBaptiste Daroussin {
671c76f0793SBaptiste Daroussin 	int ts, ltee, rtee;
672c76f0793SBaptiste Daroussin 	int colorsurroundtitle;
673c76f0793SBaptiste Daroussin 
674*f499134dSBaptiste Daroussin 	ts = conf->ascii_lines ? '-' : ACS_HLINE;
675*f499134dSBaptiste Daroussin 	ltee = conf->ascii_lines ? '+' : ACS_LTEE;
676*f499134dSBaptiste Daroussin 	rtee = conf->ascii_lines ? '+' : ACS_RTEE;
677*f499134dSBaptiste Daroussin 	colorsurroundtitle = elev == RAISED ? t.widget.lineraisecolor : t.widget.linelowercolor;
678c76f0793SBaptiste Daroussin 
679c76f0793SBaptiste Daroussin 	if (shadow != NULL)
680c76f0793SBaptiste Daroussin 		wnoutrefresh(shadow);
681c76f0793SBaptiste Daroussin 
682c76f0793SBaptiste Daroussin 	// move / resize now or the caller?
683c76f0793SBaptiste Daroussin 	draw_borders(conf, widget, h, w, elev);
684c76f0793SBaptiste Daroussin 
685*f499134dSBaptiste Daroussin 	if (conf->title != NULL) {
686*f499134dSBaptiste Daroussin 		if (t.widget.delimtitle && conf->no_lines == false) {
687c76f0793SBaptiste Daroussin 			wattron(widget, colorsurroundtitle);
688*f499134dSBaptiste Daroussin 			mvwaddch(widget, 0, w/2 - strlen(conf->title)/2 - 1, rtee);
689c76f0793SBaptiste Daroussin 			wattroff(widget, colorsurroundtitle);
690c76f0793SBaptiste Daroussin 		}
691*f499134dSBaptiste Daroussin 		wattron(widget, t.widget.titlecolor);
692*f499134dSBaptiste Daroussin 		mvwaddstr(widget, 0, w/2 - strlen(conf->title)/2, conf->title);
693*f499134dSBaptiste Daroussin 		wattroff(widget, t.widget.titlecolor);
694*f499134dSBaptiste Daroussin 		if (t.widget.delimtitle && conf->no_lines == false) {
695c76f0793SBaptiste Daroussin 			wattron(widget, colorsurroundtitle);
696c76f0793SBaptiste Daroussin 			waddch(widget, ltee);
697c76f0793SBaptiste Daroussin 			wattroff(widget, colorsurroundtitle);
698c76f0793SBaptiste Daroussin 		}
699c76f0793SBaptiste Daroussin 	}
700c76f0793SBaptiste Daroussin 
701*f499134dSBaptiste Daroussin 	if (conf->hline != NULL) {
702*f499134dSBaptiste Daroussin 		wattron(widget, t.widget.bottomtitlecolor);
703*f499134dSBaptiste Daroussin 		wmove(widget, h - 1, w/2 - strlen(conf->hline)/2 - 1);
704c76f0793SBaptiste Daroussin 		waddch(widget, '[');
705*f499134dSBaptiste Daroussin 		waddstr(widget, conf->hline);
706c76f0793SBaptiste Daroussin 		waddch(widget, ']');
707*f499134dSBaptiste Daroussin 		wattroff(widget, t.widget.bottomtitlecolor);
708c76f0793SBaptiste Daroussin 	}
709c76f0793SBaptiste Daroussin 
710*f499134dSBaptiste Daroussin 	//if (textpad == NULL && text != NULL) /* no pad, text null for textbox */
711*f499134dSBaptiste Daroussin 	//	print_text(conf, widget, 1, 2, w-3, text);
712c76f0793SBaptiste Daroussin 
713*f499134dSBaptiste Daroussin 	if (buttons && conf->no_lines == false) {
714*f499134dSBaptiste Daroussin 		wattron(widget, t.widget.lineraisecolor);
715c76f0793SBaptiste Daroussin 		mvwaddch(widget, h-3, 0, ltee);
716c76f0793SBaptiste Daroussin 		mvwhline(widget, h-3, 1, ts, w-2);
717*f499134dSBaptiste Daroussin 		wattroff(widget, t.widget.lineraisecolor);
718c76f0793SBaptiste Daroussin 
719*f499134dSBaptiste Daroussin 		wattron(widget, t.widget.linelowercolor);
720c76f0793SBaptiste Daroussin 		mvwaddch(widget, h-3, w-1, rtee);
721*f499134dSBaptiste Daroussin 		wattroff(widget, t.widget.linelowercolor);
722c76f0793SBaptiste Daroussin 	}
723c76f0793SBaptiste Daroussin 
724c76f0793SBaptiste Daroussin 	wnoutrefresh(widget);
725c76f0793SBaptiste Daroussin 
726c76f0793SBaptiste Daroussin 	if (textpad == NULL)
727c76f0793SBaptiste Daroussin 		return 0; /* widget_init() ends */
728c76f0793SBaptiste Daroussin 
729c76f0793SBaptiste Daroussin 	if (text != NULL) /* programbox etc */
730c76f0793SBaptiste Daroussin 		if (print_textpad(conf, textpad, htextpad,
731*f499134dSBaptiste Daroussin 		    w - HBORDERS - t.text.hmargin * 2, text) !=0)
732c76f0793SBaptiste Daroussin 			return BSDDIALOG_ERROR;
733c76f0793SBaptiste Daroussin 
734c76f0793SBaptiste Daroussin 	return 0;
735c76f0793SBaptiste Daroussin }
736c76f0793SBaptiste Daroussin 
737c76f0793SBaptiste Daroussin /*
738c76f0793SBaptiste Daroussin  * `enum elevation elev` could be useless because it should be always RAISED,
739c76f0793SBaptiste Daroussin  * to check at the end.
740c76f0793SBaptiste Daroussin  */
741c76f0793SBaptiste Daroussin int
742*f499134dSBaptiste Daroussin update_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *shadow,
743c76f0793SBaptiste Daroussin     WINDOW *widget, int h, int w, enum elevation elev,
744c76f0793SBaptiste Daroussin     WINDOW *textpad, int *htextpad, char *text, bool buttons)
745c76f0793SBaptiste Daroussin {
746c76f0793SBaptiste Daroussin 	int error;
747c76f0793SBaptiste Daroussin 
748c76f0793SBaptiste Daroussin 	/* nothing for now */
749c76f0793SBaptiste Daroussin 
750c76f0793SBaptiste Daroussin 	error =  draw_widget_withtextpad(conf, shadow, widget, h, w,
751c76f0793SBaptiste Daroussin 	    elev, textpad, htextpad, text, buttons);
752c76f0793SBaptiste Daroussin 
753c76f0793SBaptiste Daroussin 	return error;
754c76f0793SBaptiste Daroussin }
755c76f0793SBaptiste Daroussin 
756c76f0793SBaptiste Daroussin /*
757c76f0793SBaptiste Daroussin  * `enum elevation elev` could be useless because it should be always RAISED,
758c76f0793SBaptiste Daroussin  * to check at the end.
759c76f0793SBaptiste Daroussin  */
760c76f0793SBaptiste Daroussin int
761*f499134dSBaptiste Daroussin new_widget_withtextpad(struct bsddialog_conf *conf, WINDOW **shadow,
762c76f0793SBaptiste Daroussin     WINDOW **widget, int y, int x, int h, int w, enum elevation elev,
763c76f0793SBaptiste Daroussin     WINDOW **textpad, int *htextpad, char *text, bool buttons)
764c76f0793SBaptiste Daroussin {
765c76f0793SBaptiste Daroussin 	int error;
766c76f0793SBaptiste Daroussin 
767*f499134dSBaptiste Daroussin 	if (conf->shadow) {
768*f499134dSBaptiste Daroussin 		*shadow = newwin(h, w, y + t.shadow.h, x + t.shadow.w);
769c76f0793SBaptiste Daroussin 		if (*shadow == NULL)
770c76f0793SBaptiste Daroussin 			RETURN_ERROR("Cannot build shadow");
771*f499134dSBaptiste Daroussin 		wbkgd(*shadow, t.shadow.color);
772c76f0793SBaptiste Daroussin 	}
773c76f0793SBaptiste Daroussin 
774c76f0793SBaptiste Daroussin 	if ((*widget = new_boxed_window(conf, y, x, h, w, elev)) == NULL) {
775*f499134dSBaptiste Daroussin 		if (conf->shadow)
776c76f0793SBaptiste Daroussin 			delwin(*shadow);
777c76f0793SBaptiste Daroussin 		return BSDDIALOG_ERROR;
778c76f0793SBaptiste Daroussin 	}
779c76f0793SBaptiste Daroussin 
780c76f0793SBaptiste Daroussin 	if (textpad == NULL) { /* widget_init() */
781c76f0793SBaptiste Daroussin 		error =  draw_widget_withtextpad(conf, *shadow, *widget, h, w,
782c76f0793SBaptiste Daroussin 		    elev, NULL, NULL, text, buttons);
783c76f0793SBaptiste Daroussin 		return error;
784c76f0793SBaptiste Daroussin 	}
785c76f0793SBaptiste Daroussin 
786c76f0793SBaptiste Daroussin 	if (text != NULL) { /* programbox etc */
787c76f0793SBaptiste Daroussin 		*htextpad = 1;
788*f499134dSBaptiste Daroussin 		*textpad = newpad(*htextpad, w - HBORDERS - t.text.hmargin * 2);
789c76f0793SBaptiste Daroussin 		if (*textpad == NULL) {
790c76f0793SBaptiste Daroussin 			delwin(*textpad);
791*f499134dSBaptiste Daroussin 			if (conf->shadow)
792c76f0793SBaptiste Daroussin 				delwin(*shadow);
793c76f0793SBaptiste Daroussin 			RETURN_ERROR("Cannot build the pad window for text");
794c76f0793SBaptiste Daroussin 		}
795*f499134dSBaptiste Daroussin 		wbkgd(*textpad, t.widget.color);
796c76f0793SBaptiste Daroussin 	}
797c76f0793SBaptiste Daroussin 
798c76f0793SBaptiste Daroussin 	error =  draw_widget_withtextpad(conf, *shadow, *widget, h, w, elev,
799c76f0793SBaptiste Daroussin 	    *textpad, htextpad, text, buttons);
800c76f0793SBaptiste Daroussin 
801c76f0793SBaptiste Daroussin 	return error;
802c76f0793SBaptiste Daroussin }
803c76f0793SBaptiste Daroussin 
804c76f0793SBaptiste Daroussin void
805*f499134dSBaptiste Daroussin end_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *window, int h, int w,
806c76f0793SBaptiste Daroussin     WINDOW *textpad, WINDOW *shadow)
807c76f0793SBaptiste Daroussin {
808c76f0793SBaptiste Daroussin 	int y, x;
809c76f0793SBaptiste Daroussin 
810c76f0793SBaptiste Daroussin 	getbegyx(window, y, x); /* for clear, add y & x to args? */
811c76f0793SBaptiste Daroussin 
812*f499134dSBaptiste Daroussin 	if (conf->sleep > 0)
813*f499134dSBaptiste Daroussin 		sleep(conf->sleep);
814c76f0793SBaptiste Daroussin 
815c76f0793SBaptiste Daroussin 	if (textpad != NULL)
816c76f0793SBaptiste Daroussin 		delwin(textpad);
817c76f0793SBaptiste Daroussin 
818c76f0793SBaptiste Daroussin 	delwin(window);
819c76f0793SBaptiste Daroussin 
820*f499134dSBaptiste Daroussin 	if (conf->shadow)
821c76f0793SBaptiste Daroussin 		delwin(shadow);
822c76f0793SBaptiste Daroussin 
823*f499134dSBaptiste Daroussin 	if (conf->clear)
824c76f0793SBaptiste Daroussin 		hide_widget(y, x, h, w, shadow != NULL);
825c76f0793SBaptiste Daroussin 
826*f499134dSBaptiste Daroussin 	if (conf->get_height != NULL)
827*f499134dSBaptiste Daroussin 		*conf->get_height = h;
828*f499134dSBaptiste Daroussin 	if (conf->get_width != NULL)
829*f499134dSBaptiste Daroussin 		*conf->get_width = w;
830c76f0793SBaptiste Daroussin }
831