1c76f0793SBaptiste Daroussin /*- 2c76f0793SBaptiste Daroussin * SPDX-License-Identifier: BSD-2-Clause 3c76f0793SBaptiste Daroussin * 4*263660c0SAlfonso Siciliano * Copyright (c) 2021-2022 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 30*263660c0SAlfonso Siciliano #include <ctype.h> 31*263660c0SAlfonso Siciliano #include <curses.h> 32d93b4d32SBaptiste Daroussin #include <stdlib.h> 33d93b4d32SBaptiste Daroussin #include <string.h> 34d93b4d32SBaptiste Daroussin #include <unistd.h> 35c76f0793SBaptiste Daroussin 36c76f0793SBaptiste Daroussin #include "bsddialog.h" 37c76f0793SBaptiste Daroussin #include "bsddialog_theme.h" 38*263660c0SAlfonso Siciliano #include "lib_util.h" 39c76f0793SBaptiste Daroussin 40c76f0793SBaptiste Daroussin extern struct bsddialog_theme t; 41c76f0793SBaptiste Daroussin 42*263660c0SAlfonso Siciliano #define TABLEN 4 /* Default tab len */ 43*263660c0SAlfonso Siciliano #define ERRBUFLEN 1024 /* Error buffer */ 44c76f0793SBaptiste Daroussin 45*263660c0SAlfonso Siciliano /* Error */ 46c76f0793SBaptiste Daroussin static char errorbuffer[ERRBUFLEN]; 47c76f0793SBaptiste Daroussin 48c76f0793SBaptiste Daroussin const char *get_error_string(void) 49c76f0793SBaptiste Daroussin { 50*263660c0SAlfonso Siciliano return (errorbuffer); 51c76f0793SBaptiste Daroussin } 52c76f0793SBaptiste Daroussin 53c76f0793SBaptiste Daroussin void set_error_string(char *str) 54c76f0793SBaptiste Daroussin { 55c76f0793SBaptiste Daroussin strncpy(errorbuffer, str, ERRBUFLEN-1); 56c76f0793SBaptiste Daroussin } 57c76f0793SBaptiste Daroussin 58*263660c0SAlfonso Siciliano /* Clear */ 59c76f0793SBaptiste Daroussin int hide_widget(int y, int x, int h, int w, bool withshadow) 60c76f0793SBaptiste Daroussin { 61c76f0793SBaptiste Daroussin WINDOW *clear; 62c76f0793SBaptiste Daroussin 63f499134dSBaptiste Daroussin if ((clear = newwin(h, w, y + t.shadow.h, x + t.shadow.w)) == NULL) 64c76f0793SBaptiste Daroussin RETURN_ERROR("Cannot hide the widget"); 65*263660c0SAlfonso Siciliano wbkgd(clear, t.screen.color); 66c76f0793SBaptiste Daroussin 67c76f0793SBaptiste Daroussin if (withshadow) 68c76f0793SBaptiste Daroussin wrefresh(clear); 69c76f0793SBaptiste Daroussin 70c76f0793SBaptiste Daroussin mvwin(clear, y, x); 71c76f0793SBaptiste Daroussin wrefresh(clear); 72c76f0793SBaptiste Daroussin 73c76f0793SBaptiste Daroussin delwin(clear); 74c76f0793SBaptiste Daroussin 75*263660c0SAlfonso Siciliano return (0); 76c76f0793SBaptiste Daroussin } 77c76f0793SBaptiste Daroussin 78c76f0793SBaptiste Daroussin /* F1 help */ 79f499134dSBaptiste Daroussin int f1help(struct bsddialog_conf *conf) 80c76f0793SBaptiste Daroussin { 81c76f0793SBaptiste Daroussin int output; 828c4f4028SBaptiste Daroussin struct bsddialog_conf hconf; 83c76f0793SBaptiste Daroussin 848c4f4028SBaptiste Daroussin bsddialog_initconf(&hconf); 858c4f4028SBaptiste Daroussin hconf.title = "HELP"; 868c4f4028SBaptiste Daroussin hconf.button.ok_label = "EXIT"; 878c4f4028SBaptiste Daroussin hconf.clear = true; 888c4f4028SBaptiste Daroussin hconf.ascii_lines = conf->ascii_lines; 898c4f4028SBaptiste Daroussin hconf.no_lines = conf->no_lines; 908c4f4028SBaptiste Daroussin hconf.shadow = conf->shadow; 91*263660c0SAlfonso Siciliano hconf.text.highlight = conf->text.highlight; 92c76f0793SBaptiste Daroussin 938c4f4028SBaptiste Daroussin output = BSDDIALOG_OK; 948c4f4028SBaptiste Daroussin if (conf->f1_message != NULL) 958c4f4028SBaptiste Daroussin output = bsddialog_msgbox(&hconf, conf->f1_message, 0, 0); 96c76f0793SBaptiste Daroussin 978c4f4028SBaptiste Daroussin if (output != BSDDIALOG_ERROR && conf->f1_file != NULL) 988c4f4028SBaptiste Daroussin output = bsddialog_textbox(&hconf, conf->f1_file, 0, 0); 998c4f4028SBaptiste Daroussin 1008c4f4028SBaptiste Daroussin return (output == BSDDIALOG_ERROR ? BSDDIALOG_ERROR : 0); 101c76f0793SBaptiste Daroussin } 102c76f0793SBaptiste Daroussin 103c76f0793SBaptiste Daroussin /* Buttons */ 104*263660c0SAlfonso Siciliano static void 105*263660c0SAlfonso Siciliano draw_button(WINDOW *window, int y, int x, int size, const char *text, 106*263660c0SAlfonso Siciliano bool selected, bool shortcut) 107c76f0793SBaptiste Daroussin { 108c76f0793SBaptiste Daroussin int i, color_arrows, color_shortkey, color_button; 109c76f0793SBaptiste Daroussin 110c76f0793SBaptiste Daroussin if (selected) { 111f499134dSBaptiste Daroussin color_arrows = t.button.f_delimcolor; 112f499134dSBaptiste Daroussin color_shortkey = t.button.f_shortcutcolor; 113f499134dSBaptiste Daroussin color_button = t.button.f_color; 114c76f0793SBaptiste Daroussin } else { 115f499134dSBaptiste Daroussin color_arrows = t.button.delimcolor; 116f499134dSBaptiste Daroussin color_shortkey = t.button.shortcutcolor; 117f499134dSBaptiste Daroussin color_button = t.button.color; 118c76f0793SBaptiste Daroussin } 119c76f0793SBaptiste Daroussin 120c76f0793SBaptiste Daroussin wattron(window, color_arrows); 121f499134dSBaptiste Daroussin mvwaddch(window, y, x, t.button.leftch); 122c76f0793SBaptiste Daroussin wattroff(window, color_arrows); 123c76f0793SBaptiste Daroussin wattron(window, color_button); 124c76f0793SBaptiste Daroussin for (i = 1; i < size - 1; i++) 125c76f0793SBaptiste Daroussin waddch(window, ' '); 126c76f0793SBaptiste Daroussin wattroff(window, color_button); 127c76f0793SBaptiste Daroussin wattron(window, color_arrows); 128f499134dSBaptiste Daroussin mvwaddch(window, y, x + i, t.button.rightch); 129c76f0793SBaptiste Daroussin wattroff(window, color_arrows); 130c76f0793SBaptiste Daroussin 131c76f0793SBaptiste Daroussin x = x + 1 + ((size - 2 - strlen(text))/2); 132c76f0793SBaptiste Daroussin wattron(window, color_button); 133c76f0793SBaptiste Daroussin mvwaddstr(window, y, x, text); 134c76f0793SBaptiste Daroussin wattroff(window, color_button); 135c76f0793SBaptiste Daroussin 136*263660c0SAlfonso Siciliano if (shortcut) { 137c76f0793SBaptiste Daroussin wattron(window, color_shortkey); 138c76f0793SBaptiste Daroussin mvwaddch(window, y, x, text[0]); 139c76f0793SBaptiste Daroussin wattroff(window, color_shortkey); 140c76f0793SBaptiste Daroussin } 141c76f0793SBaptiste Daroussin } 142c76f0793SBaptiste Daroussin 143c76f0793SBaptiste Daroussin void 144*263660c0SAlfonso Siciliano draw_buttons(WINDOW *window, struct buttons bs, bool shortcut) 145c76f0793SBaptiste Daroussin { 146*263660c0SAlfonso Siciliano int i, x, startx, y, rows, cols; 147c76f0793SBaptiste Daroussin 148*263660c0SAlfonso Siciliano getmaxyx(window, rows, cols); 149*263660c0SAlfonso Siciliano y = rows - 2; 150*263660c0SAlfonso Siciliano 151*263660c0SAlfonso Siciliano startx = bs.sizebutton * bs.nbuttons + (bs.nbuttons-1) * t.button.space; 152*263660c0SAlfonso Siciliano startx = cols/2 - startx/2; 153c76f0793SBaptiste Daroussin 154c76f0793SBaptiste Daroussin for (i = 0; i < (int) bs.nbuttons; i++) { 155f499134dSBaptiste Daroussin x = i * (bs.sizebutton + t.button.space); 156*263660c0SAlfonso Siciliano draw_button(window, y, startx + x, bs.sizebutton, bs.label[i], 157*263660c0SAlfonso Siciliano i == bs.curr, shortcut); 158c76f0793SBaptiste Daroussin } 159c76f0793SBaptiste Daroussin } 160c76f0793SBaptiste Daroussin 161c76f0793SBaptiste Daroussin void 162f499134dSBaptiste Daroussin get_buttons(struct bsddialog_conf *conf, struct buttons *bs, char *yesoklabel, 163*263660c0SAlfonso Siciliano char *nocancellabel) 164c76f0793SBaptiste Daroussin { 165c76f0793SBaptiste Daroussin int i; 166c76f0793SBaptiste Daroussin #define SIZEBUTTON 8 167*263660c0SAlfonso Siciliano #define DEFAULT_BUTTON_LABEL BUTTON_OK_LABEL 1688c4f4028SBaptiste Daroussin #define DEFAULT_BUTTON_VALUE BSDDIALOG_OK 169c76f0793SBaptiste Daroussin 170c76f0793SBaptiste Daroussin bs->nbuttons = 0; 171c76f0793SBaptiste Daroussin bs->curr = 0; 172c76f0793SBaptiste Daroussin bs->sizebutton = 0; 173c76f0793SBaptiste Daroussin 1748c4f4028SBaptiste Daroussin if (yesoklabel != NULL && conf->button.without_ok == false) { 175*263660c0SAlfonso Siciliano bs->label[0] = conf->button.ok_label != NULL ? 176*263660c0SAlfonso Siciliano conf->button.ok_label : yesoklabel; 1778c4f4028SBaptiste Daroussin bs->value[0] = BSDDIALOG_OK; 178c76f0793SBaptiste Daroussin bs->nbuttons += 1; 179c76f0793SBaptiste Daroussin } 180c76f0793SBaptiste Daroussin 181*263660c0SAlfonso Siciliano if (conf->button.with_extra) { 182*263660c0SAlfonso Siciliano bs->label[bs->nbuttons] = conf->button.extra_label != NULL ? 183*263660c0SAlfonso Siciliano conf->button.extra_label : "Extra"; 184c76f0793SBaptiste Daroussin bs->value[bs->nbuttons] = BSDDIALOG_EXTRA; 185c76f0793SBaptiste Daroussin bs->nbuttons += 1; 186c76f0793SBaptiste Daroussin } 187c76f0793SBaptiste Daroussin 1888c4f4028SBaptiste Daroussin if (nocancellabel != NULL && conf->button.without_cancel == false) { 189*263660c0SAlfonso Siciliano bs->label[bs->nbuttons] = conf->button.cancel_label ? 190*263660c0SAlfonso Siciliano conf->button.cancel_label : nocancellabel; 1918c4f4028SBaptiste Daroussin bs->value[bs->nbuttons] = BSDDIALOG_CANCEL; 1928c4f4028SBaptiste Daroussin if (conf->button.default_cancel) 193c76f0793SBaptiste Daroussin bs->curr = bs->nbuttons; 194c76f0793SBaptiste Daroussin bs->nbuttons += 1; 195c76f0793SBaptiste Daroussin } 196c76f0793SBaptiste Daroussin 197*263660c0SAlfonso Siciliano if (conf->button.with_help) { 198*263660c0SAlfonso Siciliano bs->label[bs->nbuttons] = conf->button.help_label != NULL ? 199*263660c0SAlfonso Siciliano conf->button.help_label : "Help"; 200c76f0793SBaptiste Daroussin bs->value[bs->nbuttons] = BSDDIALOG_HELP; 201c76f0793SBaptiste Daroussin bs->nbuttons += 1; 202c76f0793SBaptiste Daroussin } 203c76f0793SBaptiste Daroussin 204f499134dSBaptiste Daroussin if (conf->button.generic1_label != NULL) { 205f499134dSBaptiste Daroussin bs->label[bs->nbuttons] = conf->button.generic1_label; 206f499134dSBaptiste Daroussin bs->value[bs->nbuttons] = BSDDIALOG_GENERIC1; 207f499134dSBaptiste Daroussin bs->nbuttons += 1; 208f499134dSBaptiste Daroussin } 209f499134dSBaptiste Daroussin 210f499134dSBaptiste Daroussin if (conf->button.generic2_label != NULL) { 211f499134dSBaptiste Daroussin bs->label[bs->nbuttons] = conf->button.generic2_label; 212f499134dSBaptiste Daroussin bs->value[bs->nbuttons] = BSDDIALOG_GENERIC2; 213f499134dSBaptiste Daroussin bs->nbuttons += 1; 214f499134dSBaptiste Daroussin } 215f499134dSBaptiste Daroussin 216c76f0793SBaptiste Daroussin if (bs->nbuttons == 0) { 217c76f0793SBaptiste Daroussin bs->label[0] = DEFAULT_BUTTON_LABEL; 218c76f0793SBaptiste Daroussin bs->value[0] = DEFAULT_BUTTON_VALUE; 219c76f0793SBaptiste Daroussin bs->nbuttons = 1; 220c76f0793SBaptiste Daroussin } 221c76f0793SBaptiste Daroussin 222f499134dSBaptiste Daroussin if (conf->button.default_label != NULL) { 223c76f0793SBaptiste Daroussin for (i = 0; i < (int)bs->nbuttons; i++) { 224*263660c0SAlfonso Siciliano if (strcmp(conf->button.default_label, 225*263660c0SAlfonso Siciliano bs->label[i]) == 0) 226c76f0793SBaptiste Daroussin bs->curr = i; 227c76f0793SBaptiste Daroussin } 228c76f0793SBaptiste Daroussin } 229c76f0793SBaptiste Daroussin 230c76f0793SBaptiste Daroussin bs->sizebutton = MAX(SIZEBUTTON - 2, strlen(bs->label[0])); 231c76f0793SBaptiste Daroussin for (i = 1; i < (int)bs->nbuttons; i++) 232c76f0793SBaptiste Daroussin bs->sizebutton = MAX(bs->sizebutton, strlen(bs->label[i])); 233c76f0793SBaptiste Daroussin bs->sizebutton += 2; 234c76f0793SBaptiste Daroussin } 235c76f0793SBaptiste Daroussin 236*263660c0SAlfonso Siciliano bool shortcut_buttons(int key, struct buttons *bs) 237f499134dSBaptiste Daroussin { 238*263660c0SAlfonso Siciliano bool match; 239*263660c0SAlfonso Siciliano unsigned int i; 240c76f0793SBaptiste Daroussin 241*263660c0SAlfonso Siciliano match = false; 242*263660c0SAlfonso Siciliano for (i = 0; i < bs->nbuttons; i++) { 243*263660c0SAlfonso Siciliano if (tolower(key) == tolower(bs->label[i][0])) { 244*263660c0SAlfonso Siciliano bs->curr = i; 245*263660c0SAlfonso Siciliano match = true; 246*263660c0SAlfonso Siciliano break; 247*263660c0SAlfonso Siciliano } 248*263660c0SAlfonso Siciliano } 249*263660c0SAlfonso Siciliano 250*263660c0SAlfonso Siciliano return (match); 251*263660c0SAlfonso Siciliano } 252*263660c0SAlfonso Siciliano 253*263660c0SAlfonso Siciliano /* Text */ 254*263660c0SAlfonso Siciliano static bool is_text_attr(const char *text) 255*263660c0SAlfonso Siciliano { 256f499134dSBaptiste Daroussin if (strnlen(text, 3) < 3) 257*263660c0SAlfonso Siciliano return (false); 258f499134dSBaptiste Daroussin 259f499134dSBaptiste Daroussin if (text[0] != '\\' || text[1] != 'Z') 260*263660c0SAlfonso Siciliano return (false); 261f499134dSBaptiste Daroussin 262f499134dSBaptiste Daroussin return (strchr("nbBrRuU01234567", text[2]) == NULL ? false : true); 263f499134dSBaptiste Daroussin } 264c76f0793SBaptiste Daroussin 265*263660c0SAlfonso Siciliano static bool check_set_text_attr(WINDOW *win, char *text) 266c76f0793SBaptiste Daroussin { 267*263660c0SAlfonso Siciliano if (is_text_attr(text) == false) 268*263660c0SAlfonso Siciliano return (false); 269c76f0793SBaptiste Daroussin 270f499134dSBaptiste Daroussin if ((text[2] - '0') >= 0 && (text[2] - '0') < 8) { 2718c4f4028SBaptiste Daroussin wattron(win, bsddialog_color(text[2] - '0', COLOR_WHITE, 0)); 272*263660c0SAlfonso Siciliano return (true); 273c76f0793SBaptiste Daroussin } 274c76f0793SBaptiste Daroussin 275c76f0793SBaptiste Daroussin switch (text[2]) { 276c76f0793SBaptiste Daroussin case 'n': 277*263660c0SAlfonso Siciliano wattron(win, t.dialog.color); 278c76f0793SBaptiste Daroussin wattrset(win, A_NORMAL); 279c76f0793SBaptiste Daroussin break; 280c76f0793SBaptiste Daroussin case 'b': 281c76f0793SBaptiste Daroussin wattron(win, A_BOLD); 282c76f0793SBaptiste Daroussin break; 283c76f0793SBaptiste Daroussin case 'B': 284c76f0793SBaptiste Daroussin wattroff(win, A_BOLD); 285c76f0793SBaptiste Daroussin break; 286c76f0793SBaptiste Daroussin case 'r': 287c76f0793SBaptiste Daroussin wattron(win, A_REVERSE); 288c76f0793SBaptiste Daroussin break; 289c76f0793SBaptiste Daroussin case 'R': 290c76f0793SBaptiste Daroussin wattroff(win, A_REVERSE); 291c76f0793SBaptiste Daroussin break; 292c76f0793SBaptiste Daroussin case 'u': 293c76f0793SBaptiste Daroussin wattron(win, A_UNDERLINE); 294c76f0793SBaptiste Daroussin break; 295c76f0793SBaptiste Daroussin case 'U': 296c76f0793SBaptiste Daroussin wattroff(win, A_UNDERLINE); 297c76f0793SBaptiste Daroussin break; 298c76f0793SBaptiste Daroussin } 299c76f0793SBaptiste Daroussin 300*263660c0SAlfonso Siciliano return (true); 301c76f0793SBaptiste Daroussin } 302c76f0793SBaptiste Daroussin 303c76f0793SBaptiste Daroussin static void 304*263660c0SAlfonso Siciliano print_string(WINDOW *win, int *rows, int cols, int *y, int *x, char *str, 305*263660c0SAlfonso Siciliano bool color) 306c76f0793SBaptiste Daroussin { 307c76f0793SBaptiste Daroussin int i, j, len, reallen; 308c76f0793SBaptiste Daroussin 309c76f0793SBaptiste Daroussin len = reallen = strlen(str); 310c76f0793SBaptiste Daroussin if (color) { 311c76f0793SBaptiste Daroussin i=0; 312c76f0793SBaptiste Daroussin while (i < len) { 313*263660c0SAlfonso Siciliano if (is_text_attr(str+i)) 314c76f0793SBaptiste Daroussin reallen -= 3; 315c76f0793SBaptiste Daroussin i++; 316c76f0793SBaptiste Daroussin } 317c76f0793SBaptiste Daroussin } 318c76f0793SBaptiste Daroussin 319c76f0793SBaptiste Daroussin i = 0; 320c76f0793SBaptiste Daroussin while (i < len) { 321c76f0793SBaptiste Daroussin if (*x + reallen > cols) { 322c76f0793SBaptiste Daroussin *y = (*x != 0 ? *y+1 : *y); 323c76f0793SBaptiste Daroussin if (*y >= *rows) { 324c76f0793SBaptiste Daroussin *rows = *y + 1; 325c76f0793SBaptiste Daroussin wresize(win, *rows, cols); 326c76f0793SBaptiste Daroussin } 327c76f0793SBaptiste Daroussin *x = 0; 328c76f0793SBaptiste Daroussin } 329c76f0793SBaptiste Daroussin j = *x; 330c76f0793SBaptiste Daroussin while (j < cols && i < len) { 331*263660c0SAlfonso Siciliano if (color && check_set_text_attr(win, str+i)) { 332c76f0793SBaptiste Daroussin i += 3; 333c76f0793SBaptiste Daroussin } else { 334c76f0793SBaptiste Daroussin mvwaddch(win, *y, j, str[i]); 335c76f0793SBaptiste Daroussin i++; 336c76f0793SBaptiste Daroussin reallen--; 337c76f0793SBaptiste Daroussin j++; 338c76f0793SBaptiste Daroussin *x = j; 339c76f0793SBaptiste Daroussin } 340c76f0793SBaptiste Daroussin } 341c76f0793SBaptiste Daroussin } 342c76f0793SBaptiste Daroussin } 343c76f0793SBaptiste Daroussin 344*263660c0SAlfonso Siciliano static int 345*263660c0SAlfonso Siciliano print_textpad(struct bsddialog_conf *conf, WINDOW *pad, const char *text) 346c76f0793SBaptiste Daroussin { 347c76f0793SBaptiste Daroussin bool loop; 348*263660c0SAlfonso Siciliano int i, j, z, rows, cols, x, y, tablen; 349*263660c0SAlfonso Siciliano char *string; 350c76f0793SBaptiste Daroussin 3518c4f4028SBaptiste Daroussin if ((string = malloc(strlen(text) + 1)) == NULL) 352c76f0793SBaptiste Daroussin RETURN_ERROR("Cannot build (analyze) text"); 353c76f0793SBaptiste Daroussin 354*263660c0SAlfonso Siciliano getmaxyx(pad, rows, cols); 355*263660c0SAlfonso Siciliano tablen = (conf->text.tablen == 0) ? TABLEN : (int)conf->text.tablen; 356*263660c0SAlfonso Siciliano 357c76f0793SBaptiste Daroussin i = j = x = y = 0; 358c76f0793SBaptiste Daroussin loop = true; 359c76f0793SBaptiste Daroussin while (loop) { 3608c4f4028SBaptiste Daroussin string[j] = text[i]; 361c76f0793SBaptiste Daroussin 362*263660c0SAlfonso Siciliano if (strchr("\n\t ", string[j]) != NULL || string[j] == '\0') { 363c76f0793SBaptiste Daroussin string[j] = '\0'; 364*263660c0SAlfonso Siciliano print_string(pad, &rows, cols, &y, &x, string, 365*263660c0SAlfonso Siciliano conf->text.highlight); 366c76f0793SBaptiste Daroussin } 367c76f0793SBaptiste Daroussin 3688c4f4028SBaptiste Daroussin switch (text[i]) { 369c76f0793SBaptiste Daroussin case '\0': 370c76f0793SBaptiste Daroussin loop = false; 371c76f0793SBaptiste Daroussin break; 372c76f0793SBaptiste Daroussin case '\n': 373c76f0793SBaptiste Daroussin x = 0; 374c76f0793SBaptiste Daroussin y++; 375*263660c0SAlfonso Siciliano j = -1; 376c76f0793SBaptiste Daroussin break; 377c76f0793SBaptiste Daroussin case '\t': 378*263660c0SAlfonso Siciliano for (z = 0; z < tablen; z++) { 379c76f0793SBaptiste Daroussin if (x >= cols) { 380c76f0793SBaptiste Daroussin x = 0; 381c76f0793SBaptiste Daroussin y++; 382c76f0793SBaptiste Daroussin } 383*263660c0SAlfonso Siciliano x++; 384c76f0793SBaptiste Daroussin } 385c76f0793SBaptiste Daroussin j = -1; 386c76f0793SBaptiste Daroussin break; 387c76f0793SBaptiste Daroussin case ' ': 388c76f0793SBaptiste Daroussin x++; 389c76f0793SBaptiste Daroussin if (x >= cols) { 390c76f0793SBaptiste Daroussin x = 0; 391c76f0793SBaptiste Daroussin y++; 392c76f0793SBaptiste Daroussin } 393c76f0793SBaptiste Daroussin j = -1; 394c76f0793SBaptiste Daroussin } 395c76f0793SBaptiste Daroussin 396*263660c0SAlfonso Siciliano if (y >= rows) { 397*263660c0SAlfonso Siciliano rows = y + 1; 398*263660c0SAlfonso Siciliano wresize(pad, rows, cols); 399c76f0793SBaptiste Daroussin } 400c76f0793SBaptiste Daroussin 401c76f0793SBaptiste Daroussin j++; 402c76f0793SBaptiste Daroussin i++; 403c76f0793SBaptiste Daroussin } 404c76f0793SBaptiste Daroussin 405c76f0793SBaptiste Daroussin free(string); 406c76f0793SBaptiste Daroussin 407*263660c0SAlfonso Siciliano return (0); 408c76f0793SBaptiste Daroussin } 409c76f0793SBaptiste Daroussin 410*263660c0SAlfonso Siciliano /* Autosize */ 411*263660c0SAlfonso Siciliano static int 412*263660c0SAlfonso Siciliano text_autosize(struct bsddialog_conf *conf, const char *text, int maxrows, 413*263660c0SAlfonso Siciliano int mincols, bool increasecols, int *h, int *w) 414*263660c0SAlfonso Siciliano { 415*263660c0SAlfonso Siciliano int i, j, z, x, y; 416*263660c0SAlfonso Siciliano int tablen, wordlen, maxwordlen, nword, maxwords, line, maxwidth; 417*263660c0SAlfonso Siciliano int *words; 418*263660c0SAlfonso Siciliano #define NL -1 419*263660c0SAlfonso Siciliano #define WS -2 420c76f0793SBaptiste Daroussin 421*263660c0SAlfonso Siciliano maxwords = 1024; 422*263660c0SAlfonso Siciliano if ((words = calloc(maxwords, sizeof(int))) == NULL) 423*263660c0SAlfonso Siciliano RETURN_ERROR("Cannot alloc memory for text autosize"); 424*263660c0SAlfonso Siciliano 425*263660c0SAlfonso Siciliano tablen = (conf->text.tablen == 0) ? TABLEN : (int)conf->text.tablen; 426*263660c0SAlfonso Siciliano maxwidth = widget_max_width(conf) - HBORDERS - TEXTHMARGINS; 427*263660c0SAlfonso Siciliano 428*263660c0SAlfonso Siciliano nword = 0; 429*263660c0SAlfonso Siciliano wordlen = 0; 430*263660c0SAlfonso Siciliano maxwordlen = 0; 431*263660c0SAlfonso Siciliano i=0; 432*263660c0SAlfonso Siciliano while (true) { 433*263660c0SAlfonso Siciliano if (conf->text.highlight && is_text_attr(text + i)) { 434*263660c0SAlfonso Siciliano i += 3; 435*263660c0SAlfonso Siciliano continue; 436*263660c0SAlfonso Siciliano } 437*263660c0SAlfonso Siciliano 438*263660c0SAlfonso Siciliano if (nword + tablen >= maxwords) { 439*263660c0SAlfonso Siciliano maxwords += 1024; 440*263660c0SAlfonso Siciliano if (realloc(words, maxwords * sizeof(int)) == NULL) 441*263660c0SAlfonso Siciliano RETURN_ERROR("Cannot realloc memory for text " 442*263660c0SAlfonso Siciliano "autosize"); 443*263660c0SAlfonso Siciliano } 444*263660c0SAlfonso Siciliano 445*263660c0SAlfonso Siciliano if (text[i] == '\0') { 446*263660c0SAlfonso Siciliano words[nword] = wordlen; 447*263660c0SAlfonso Siciliano maxwordlen = MAX(wordlen, maxwordlen); 448*263660c0SAlfonso Siciliano break; 449*263660c0SAlfonso Siciliano } 450*263660c0SAlfonso Siciliano 451*263660c0SAlfonso Siciliano if (strchr("\t\n ", text[i]) != NULL) { 452*263660c0SAlfonso Siciliano maxwordlen = MAX(wordlen, maxwordlen); 453*263660c0SAlfonso Siciliano 454*263660c0SAlfonso Siciliano if (wordlen != 0) { 455*263660c0SAlfonso Siciliano words[nword] = wordlen; 456*263660c0SAlfonso Siciliano nword++; 457*263660c0SAlfonso Siciliano wordlen = 0; 458*263660c0SAlfonso Siciliano } 459*263660c0SAlfonso Siciliano 460*263660c0SAlfonso Siciliano if (text[i] == '\t') { 461*263660c0SAlfonso Siciliano for (j = 0; j < tablen; j++) 462*263660c0SAlfonso Siciliano words[nword + j] = 1; 463*263660c0SAlfonso Siciliano nword += tablen; 464*263660c0SAlfonso Siciliano } else { 465*263660c0SAlfonso Siciliano words[nword] = text[i] == '\n' ? NL : WS; 466*263660c0SAlfonso Siciliano nword++; 467*263660c0SAlfonso Siciliano } 468*263660c0SAlfonso Siciliano } 469*263660c0SAlfonso Siciliano else 470*263660c0SAlfonso Siciliano wordlen++; 471*263660c0SAlfonso Siciliano 472*263660c0SAlfonso Siciliano i++; 473*263660c0SAlfonso Siciliano } 474*263660c0SAlfonso Siciliano 475*263660c0SAlfonso Siciliano if (increasecols) { 476*263660c0SAlfonso Siciliano mincols = MAX(mincols, maxwordlen); 477*263660c0SAlfonso Siciliano mincols = MAX(mincols, 478*263660c0SAlfonso Siciliano (int)conf->auto_minwidth - HBORDERS - TEXTHMARGINS); 479*263660c0SAlfonso Siciliano mincols = MIN(mincols, maxwidth); 480*263660c0SAlfonso Siciliano } 481*263660c0SAlfonso Siciliano 482*263660c0SAlfonso Siciliano while (true) { 483*263660c0SAlfonso Siciliano x = 0; 484*263660c0SAlfonso Siciliano y = 1; 485*263660c0SAlfonso Siciliano line=0; 486*263660c0SAlfonso Siciliano for (i = 0; i <= nword; i++) { 487*263660c0SAlfonso Siciliano if (words[i] == NL) { 488*263660c0SAlfonso Siciliano y++; 489*263660c0SAlfonso Siciliano x = 0; 490*263660c0SAlfonso Siciliano } 491*263660c0SAlfonso Siciliano else if (words[i] == WS) { 492*263660c0SAlfonso Siciliano x++; 493*263660c0SAlfonso Siciliano if (x >= mincols) { 494*263660c0SAlfonso Siciliano x = 0; 495*263660c0SAlfonso Siciliano y++; 496*263660c0SAlfonso Siciliano } 497*263660c0SAlfonso Siciliano } 498*263660c0SAlfonso Siciliano else { 499*263660c0SAlfonso Siciliano if (words[i] + x <= mincols) 500*263660c0SAlfonso Siciliano x += words[i]; 501*263660c0SAlfonso Siciliano else { 502*263660c0SAlfonso Siciliano for (z = words[i]; z > 0; ) { 503*263660c0SAlfonso Siciliano y++; 504*263660c0SAlfonso Siciliano x = MIN(mincols, z); 505*263660c0SAlfonso Siciliano z -= x; 506*263660c0SAlfonso Siciliano } 507*263660c0SAlfonso Siciliano } 508*263660c0SAlfonso Siciliano } 509*263660c0SAlfonso Siciliano line = MAX(line, x); 510*263660c0SAlfonso Siciliano } 511*263660c0SAlfonso Siciliano 512*263660c0SAlfonso Siciliano if (increasecols == false) 513*263660c0SAlfonso Siciliano break; 514*263660c0SAlfonso Siciliano if (y <= maxrows || mincols >= maxwidth) 515*263660c0SAlfonso Siciliano break; 516*263660c0SAlfonso Siciliano mincols++; 517*263660c0SAlfonso Siciliano } 518*263660c0SAlfonso Siciliano 519*263660c0SAlfonso Siciliano *h = (nword == 0 && words[0] == 0) ? 0 : y; 520*263660c0SAlfonso Siciliano *w = MIN(mincols, line); /* wtext can be less than mincols */ 521*263660c0SAlfonso Siciliano 522*263660c0SAlfonso Siciliano free(words); 523*263660c0SAlfonso Siciliano 524*263660c0SAlfonso Siciliano return (0); 525*263660c0SAlfonso Siciliano } 526*263660c0SAlfonso Siciliano 527*263660c0SAlfonso Siciliano int 528*263660c0SAlfonso Siciliano text_size(struct bsddialog_conf *conf, int rows, int cols, const char *text, 529*263660c0SAlfonso Siciliano struct buttons *bs, int rowsnotext, int startwtext, int *htext, int *wtext) 530*263660c0SAlfonso Siciliano { 531*263660c0SAlfonso Siciliano int wbuttons, maxhtext; 532*263660c0SAlfonso Siciliano bool changewtext; 533*263660c0SAlfonso Siciliano 534*263660c0SAlfonso Siciliano wbuttons = 0; 535*263660c0SAlfonso Siciliano if (bs != NULL) { 536*263660c0SAlfonso Siciliano wbuttons = bs->nbuttons * bs->sizebutton; 537*263660c0SAlfonso Siciliano if (bs->nbuttons > 0) 538*263660c0SAlfonso Siciliano wbuttons += (bs->nbuttons-1) * t.button.space; 539*263660c0SAlfonso Siciliano } 540*263660c0SAlfonso Siciliano 541*263660c0SAlfonso Siciliano if (cols == BSDDIALOG_AUTOSIZE) { 542*263660c0SAlfonso Siciliano startwtext = MAX(startwtext, wbuttons - TEXTHMARGINS); 543*263660c0SAlfonso Siciliano changewtext = true; 544*263660c0SAlfonso Siciliano } else if (cols == BSDDIALOG_FULLSCREEN) { 545*263660c0SAlfonso Siciliano startwtext = widget_max_width(conf) - VBORDERS - TEXTHMARGINS; 546*263660c0SAlfonso Siciliano changewtext = false; 547*263660c0SAlfonso Siciliano } else { /* fixed */ 548*263660c0SAlfonso Siciliano startwtext = cols - VBORDERS - TEXTHMARGINS; 549*263660c0SAlfonso Siciliano changewtext = false; 550*263660c0SAlfonso Siciliano } 551*263660c0SAlfonso Siciliano 552*263660c0SAlfonso Siciliano if (rows == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_FULLSCREEN) { 553*263660c0SAlfonso Siciliano maxhtext = widget_max_height(conf) - VBORDERS - rowsnotext; 554*263660c0SAlfonso Siciliano if (bs != NULL) 555*263660c0SAlfonso Siciliano maxhtext -= 2; 556*263660c0SAlfonso Siciliano } else { /* fixed */ 557*263660c0SAlfonso Siciliano maxhtext = rows - VBORDERS - rowsnotext; 558*263660c0SAlfonso Siciliano if (bs != NULL) 559*263660c0SAlfonso Siciliano maxhtext -= 2; 560*263660c0SAlfonso Siciliano } 561*263660c0SAlfonso Siciliano 562*263660c0SAlfonso Siciliano if (startwtext <= 0 && changewtext) 563*263660c0SAlfonso Siciliano startwtext = 1; 564*263660c0SAlfonso Siciliano if (maxhtext <= 0 || startwtext <= 0) { 565*263660c0SAlfonso Siciliano *htext = *wtext = 0; 566*263660c0SAlfonso Siciliano return (0); 567*263660c0SAlfonso Siciliano } 568*263660c0SAlfonso Siciliano 569*263660c0SAlfonso Siciliano if (text_autosize(conf, text, maxhtext, startwtext, changewtext, 570*263660c0SAlfonso Siciliano htext, wtext) != 0) 571*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 572*263660c0SAlfonso Siciliano 573*263660c0SAlfonso Siciliano return (0); 574*263660c0SAlfonso Siciliano } 575*263660c0SAlfonso Siciliano 576f499134dSBaptiste Daroussin int widget_max_height(struct bsddialog_conf *conf) 577c76f0793SBaptiste Daroussin { 578c76f0793SBaptiste Daroussin int maxheight; 579c76f0793SBaptiste Daroussin 580*263660c0SAlfonso Siciliano maxheight = conf->shadow ? SCREENLINES - t.shadow.h : SCREENLINES; 581*263660c0SAlfonso Siciliano if (maxheight <= 0) 582*263660c0SAlfonso Siciliano RETURN_ERROR("Terminal too small, screen lines - shadow <= 0"); 583c76f0793SBaptiste Daroussin 584*263660c0SAlfonso Siciliano if (conf->y > 0) { 585*263660c0SAlfonso Siciliano maxheight -= conf->y; 586*263660c0SAlfonso Siciliano if (maxheight <= 0) 587*263660c0SAlfonso Siciliano RETURN_ERROR("Terminal too small, screen lines - " 588*263660c0SAlfonso Siciliano "shadow - y <= 0"); 589c76f0793SBaptiste Daroussin } 590c76f0793SBaptiste Daroussin 591*263660c0SAlfonso Siciliano return (maxheight); 592*263660c0SAlfonso Siciliano } 593*263660c0SAlfonso Siciliano 594f499134dSBaptiste Daroussin int widget_max_width(struct bsddialog_conf *conf) 595c76f0793SBaptiste Daroussin { 596c76f0793SBaptiste Daroussin int maxwidth; 597c76f0793SBaptiste Daroussin 598*263660c0SAlfonso Siciliano maxwidth = conf->shadow ? SCREENCOLS - t.shadow.w : SCREENCOLS; 599*263660c0SAlfonso Siciliano if (maxwidth <= 0) 600*263660c0SAlfonso Siciliano RETURN_ERROR("Terminal too small, screen cols - shadow <= 0"); 601c76f0793SBaptiste Daroussin 602*263660c0SAlfonso Siciliano if (conf->x > 0) { 603*263660c0SAlfonso Siciliano maxwidth -= conf->x; 604*263660c0SAlfonso Siciliano if (maxwidth <= 0) 605*263660c0SAlfonso Siciliano RETURN_ERROR("Terminal too small, screen cols - shadow " 606*263660c0SAlfonso Siciliano "- x <= 0"); 607*263660c0SAlfonso Siciliano } 608*263660c0SAlfonso Siciliano 609*263660c0SAlfonso Siciliano return (maxwidth); 610*263660c0SAlfonso Siciliano } 611*263660c0SAlfonso Siciliano 612*263660c0SAlfonso Siciliano int 613*263660c0SAlfonso Siciliano widget_min_height(struct bsddialog_conf *conf, int htext, int minwidget, 614*263660c0SAlfonso Siciliano bool withbuttons) 615*263660c0SAlfonso Siciliano { 616*263660c0SAlfonso Siciliano int min; 617*263660c0SAlfonso Siciliano 618*263660c0SAlfonso Siciliano min = 0; 619*263660c0SAlfonso Siciliano 620*263660c0SAlfonso Siciliano /* buttons */ 621*263660c0SAlfonso Siciliano if (withbuttons) 622*263660c0SAlfonso Siciliano min += 2; /* buttons and border */ 623*263660c0SAlfonso Siciliano 624*263660c0SAlfonso Siciliano /* text */ 625*263660c0SAlfonso Siciliano min += htext; 626*263660c0SAlfonso Siciliano 627*263660c0SAlfonso Siciliano /* specific widget min height */ 628*263660c0SAlfonso Siciliano min += minwidget; 629*263660c0SAlfonso Siciliano 630*263660c0SAlfonso Siciliano /* dialog borders */ 631*263660c0SAlfonso Siciliano min += HBORDERS; 632*263660c0SAlfonso Siciliano /* conf.auto_minheight */ 633*263660c0SAlfonso Siciliano min = MAX(min, (int)conf->auto_minheight); 634*263660c0SAlfonso Siciliano /* avoid terminal overflow */ 635*263660c0SAlfonso Siciliano min = MIN(min, widget_max_height(conf)); 636*263660c0SAlfonso Siciliano 637*263660c0SAlfonso Siciliano return (min); 638*263660c0SAlfonso Siciliano } 639*263660c0SAlfonso Siciliano 640*263660c0SAlfonso Siciliano int 641*263660c0SAlfonso Siciliano widget_min_width(struct bsddialog_conf *conf, int wtext, int minwidget, 642*263660c0SAlfonso Siciliano struct buttons *bs) 643*263660c0SAlfonso Siciliano 644*263660c0SAlfonso Siciliano { 645*263660c0SAlfonso Siciliano int min, delimtitle; 646*263660c0SAlfonso Siciliano 647*263660c0SAlfonso Siciliano min = 0; 648*263660c0SAlfonso Siciliano 649*263660c0SAlfonso Siciliano /* buttons */ 650*263660c0SAlfonso Siciliano if (bs != NULL) { 651*263660c0SAlfonso Siciliano min += bs->nbuttons * bs->sizebutton; 652*263660c0SAlfonso Siciliano min += bs->nbuttons > 0 ? (bs->nbuttons-1) * t.button.space : 0; 653*263660c0SAlfonso Siciliano } 654*263660c0SAlfonso Siciliano 655*263660c0SAlfonso Siciliano /* text */ 656*263660c0SAlfonso Siciliano if (wtext > 0) 657*263660c0SAlfonso Siciliano min = MAX(min, wtext + TEXTHMARGINS); 658*263660c0SAlfonso Siciliano 659*263660c0SAlfonso Siciliano /* specific widget min width */ 660*263660c0SAlfonso Siciliano min = MAX(min, minwidget); 661*263660c0SAlfonso Siciliano 662*263660c0SAlfonso Siciliano /* title */ 663*263660c0SAlfonso Siciliano if (conf->title != NULL) { 664*263660c0SAlfonso Siciliano delimtitle = t.dialog.delimtitle ? 2 : 0; 665*263660c0SAlfonso Siciliano min = MAX(min, (int)strlen(conf->title) + 2 + delimtitle); 666*263660c0SAlfonso Siciliano } 667*263660c0SAlfonso Siciliano 668*263660c0SAlfonso Siciliano /* bottom title */ 669*263660c0SAlfonso Siciliano if (conf->bottomtitle != NULL) 670*263660c0SAlfonso Siciliano min = MAX(min, (int)strlen(conf->bottomtitle) + 4); 671*263660c0SAlfonso Siciliano 672*263660c0SAlfonso Siciliano /* dialog borders */ 673*263660c0SAlfonso Siciliano min += VBORDERS; 674*263660c0SAlfonso Siciliano /* conf.auto_minwidth */ 675*263660c0SAlfonso Siciliano min = MAX(min, (int)conf->auto_minwidth); 676*263660c0SAlfonso Siciliano /* avoid terminal overflow */ 677*263660c0SAlfonso Siciliano min = MIN(min, widget_max_width(conf)); 678*263660c0SAlfonso Siciliano 679*263660c0SAlfonso Siciliano return (min); 680c76f0793SBaptiste Daroussin } 681c76f0793SBaptiste Daroussin 682c76f0793SBaptiste Daroussin int 683f499134dSBaptiste Daroussin set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w) 684c76f0793SBaptiste Daroussin { 685c76f0793SBaptiste Daroussin int maxheight, maxwidth; 686c76f0793SBaptiste Daroussin 687c76f0793SBaptiste Daroussin if ((maxheight = widget_max_height(conf)) == BSDDIALOG_ERROR) 688*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 689c76f0793SBaptiste Daroussin 690c76f0793SBaptiste Daroussin if (rows == BSDDIALOG_FULLSCREEN) 691c76f0793SBaptiste Daroussin *h = maxheight; 692c76f0793SBaptiste Daroussin else if (rows < BSDDIALOG_FULLSCREEN) 693c76f0793SBaptiste Daroussin RETURN_ERROR("Negative (less than -1) height"); 694c76f0793SBaptiste Daroussin else if (rows > BSDDIALOG_AUTOSIZE) { 695c76f0793SBaptiste Daroussin if ((*h = rows) > maxheight) 696*263660c0SAlfonso Siciliano RETURN_ERROR("Height too big (> terminal height - " 697*263660c0SAlfonso Siciliano "shadow)"); 698c76f0793SBaptiste Daroussin } 699c76f0793SBaptiste Daroussin /* rows == AUTOSIZE: each widget has to set its size */ 700c76f0793SBaptiste Daroussin 701c76f0793SBaptiste Daroussin if ((maxwidth = widget_max_width(conf)) == BSDDIALOG_ERROR) 702*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 703c76f0793SBaptiste Daroussin 704c76f0793SBaptiste Daroussin if (cols == BSDDIALOG_FULLSCREEN) 705c76f0793SBaptiste Daroussin *w = maxwidth; 706c76f0793SBaptiste Daroussin else if (cols < BSDDIALOG_FULLSCREEN) 707c76f0793SBaptiste Daroussin RETURN_ERROR("Negative (less than -1) width"); 708c76f0793SBaptiste Daroussin else if (cols > BSDDIALOG_AUTOSIZE) { 709c76f0793SBaptiste Daroussin if ((*w = cols) > maxwidth) 710*263660c0SAlfonso Siciliano RETURN_ERROR("Width too big (> terminal width - " 711*263660c0SAlfonso Siciliano "shadow)"); 712c76f0793SBaptiste Daroussin } 713c76f0793SBaptiste Daroussin /* cols == AUTOSIZE: each widget has to set its size */ 714c76f0793SBaptiste Daroussin 715*263660c0SAlfonso Siciliano return (0); 716c76f0793SBaptiste Daroussin } 717c76f0793SBaptiste Daroussin 718c76f0793SBaptiste Daroussin int 719f499134dSBaptiste Daroussin set_widget_position(struct bsddialog_conf *conf, int *y, int *x, int h, int w) 720c76f0793SBaptiste Daroussin { 721f499134dSBaptiste Daroussin if (conf->y == BSDDIALOG_CENTER) 722*263660c0SAlfonso Siciliano *y = SCREENLINES/2 - (h + t.shadow.h)/2; 723f499134dSBaptiste Daroussin else if (conf->y < BSDDIALOG_CENTER) 724c76f0793SBaptiste Daroussin RETURN_ERROR("Negative begin y (less than -1)"); 725*263660c0SAlfonso Siciliano else if (conf->y >= SCREENLINES) 726c76f0793SBaptiste Daroussin RETURN_ERROR("Begin Y under the terminal"); 727c76f0793SBaptiste Daroussin else 728f499134dSBaptiste Daroussin *y = conf->y; 729c76f0793SBaptiste Daroussin 730*263660c0SAlfonso Siciliano if ((*y + h + (conf->shadow ? (int) t.shadow.h : 0)) > SCREENLINES) 731*263660c0SAlfonso Siciliano RETURN_ERROR("The lower of the box under the terminal " 732c76f0793SBaptiste Daroussin "(begin Y + height (+ shadow) > terminal lines)"); 733c76f0793SBaptiste Daroussin 734c76f0793SBaptiste Daroussin 735f499134dSBaptiste Daroussin if (conf->x == BSDDIALOG_CENTER) 736*263660c0SAlfonso Siciliano *x = SCREENCOLS/2 - (w + t.shadow.w)/2; 737f499134dSBaptiste Daroussin else if (conf->x < BSDDIALOG_CENTER) 738c76f0793SBaptiste Daroussin RETURN_ERROR("Negative begin x (less than -1)"); 739*263660c0SAlfonso Siciliano else if (conf->x >= SCREENCOLS) 740c76f0793SBaptiste Daroussin RETURN_ERROR("Begin X over the right of the terminal"); 741c76f0793SBaptiste Daroussin else 742f499134dSBaptiste Daroussin *x = conf->x; 743c76f0793SBaptiste Daroussin 744*263660c0SAlfonso Siciliano if ((*x + w + (conf->shadow ? (int) t.shadow.w : 0)) > SCREENCOLS) 745*263660c0SAlfonso Siciliano RETURN_ERROR("The right of the box over the terminal " 746c76f0793SBaptiste Daroussin "(begin X + width (+ shadow) > terminal cols)"); 747c76f0793SBaptiste Daroussin 748*263660c0SAlfonso Siciliano return (0); 749c76f0793SBaptiste Daroussin } 750c76f0793SBaptiste Daroussin 751c76f0793SBaptiste Daroussin /* Widgets builders */ 752c76f0793SBaptiste Daroussin void 753f499134dSBaptiste Daroussin draw_borders(struct bsddialog_conf *conf, WINDOW *win, int rows, int cols, 754c76f0793SBaptiste Daroussin enum elevation elev) 755c76f0793SBaptiste Daroussin { 756c76f0793SBaptiste Daroussin int leftcolor, rightcolor; 757*263660c0SAlfonso Siciliano int ls, rs, ts, bs, tl, tr, bl, br, ltee, rtee; 758c76f0793SBaptiste Daroussin 759*263660c0SAlfonso Siciliano if (conf->no_lines) 760*263660c0SAlfonso Siciliano return; 761*263660c0SAlfonso Siciliano 762*263660c0SAlfonso Siciliano if (conf->ascii_lines) { 763*263660c0SAlfonso Siciliano ls = rs = '|'; 764*263660c0SAlfonso Siciliano ts = bs = '-'; 765*263660c0SAlfonso Siciliano tl = tr = bl = br = ltee = rtee = '+'; 766*263660c0SAlfonso Siciliano } else { 767c76f0793SBaptiste Daroussin ls = rs = ACS_VLINE; 768c76f0793SBaptiste Daroussin ts = bs = ACS_HLINE; 769c76f0793SBaptiste Daroussin tl = ACS_ULCORNER; 770c76f0793SBaptiste Daroussin tr = ACS_URCORNER; 771c76f0793SBaptiste Daroussin bl = ACS_LLCORNER; 772c76f0793SBaptiste Daroussin br = ACS_LRCORNER; 773c76f0793SBaptiste Daroussin ltee = ACS_LTEE; 774c76f0793SBaptiste Daroussin rtee = ACS_RTEE; 775c76f0793SBaptiste Daroussin } 776*263660c0SAlfonso Siciliano 7778c4f4028SBaptiste Daroussin leftcolor = elev == RAISED ? 7788c4f4028SBaptiste Daroussin t.dialog.lineraisecolor : t.dialog.linelowercolor; 7798c4f4028SBaptiste Daroussin rightcolor = elev == RAISED ? 7808c4f4028SBaptiste Daroussin t.dialog.linelowercolor : t.dialog.lineraisecolor; 781c76f0793SBaptiste Daroussin wattron(win, leftcolor); 782c76f0793SBaptiste Daroussin wborder(win, ls, rs, ts, bs, tl, tr, bl, br); 783c76f0793SBaptiste Daroussin wattroff(win, leftcolor); 784c76f0793SBaptiste Daroussin 785c76f0793SBaptiste Daroussin wattron(win, rightcolor); 786c76f0793SBaptiste Daroussin mvwaddch(win, 0, cols-1, tr); 787c76f0793SBaptiste Daroussin mvwvline(win, 1, cols-1, rs, rows-2); 788c76f0793SBaptiste Daroussin mvwaddch(win, rows-1, cols-1, br); 789c76f0793SBaptiste Daroussin mvwhline(win, rows-1, 1, bs, cols-2); 790c76f0793SBaptiste Daroussin wattroff(win, rightcolor); 791c76f0793SBaptiste Daroussin } 792c76f0793SBaptiste Daroussin 793c76f0793SBaptiste Daroussin WINDOW * 794f499134dSBaptiste Daroussin new_boxed_window(struct bsddialog_conf *conf, int y, int x, int rows, int cols, 795c76f0793SBaptiste Daroussin enum elevation elev) 796c76f0793SBaptiste Daroussin { 797c76f0793SBaptiste Daroussin WINDOW *win; 798c76f0793SBaptiste Daroussin 799c76f0793SBaptiste Daroussin if ((win = newwin(rows, cols, y, x)) == NULL) { 800c76f0793SBaptiste Daroussin set_error_string("Cannot build boxed window"); 801*263660c0SAlfonso Siciliano return (NULL); 802c76f0793SBaptiste Daroussin } 803c76f0793SBaptiste Daroussin 8048c4f4028SBaptiste Daroussin wbkgd(win, t.dialog.color); 805c76f0793SBaptiste Daroussin 806c76f0793SBaptiste Daroussin draw_borders(conf, win, rows, cols, elev); 807c76f0793SBaptiste Daroussin 808*263660c0SAlfonso Siciliano return (win); 809c76f0793SBaptiste Daroussin } 810c76f0793SBaptiste Daroussin 811c76f0793SBaptiste Daroussin static int 812*263660c0SAlfonso Siciliano draw_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget, 813*263660c0SAlfonso Siciliano WINDOW *textpad, const char *text, struct buttons *bs, bool shortcutbuttons) 814c76f0793SBaptiste Daroussin { 815*263660c0SAlfonso Siciliano int h, w, ts, ltee, rtee; 816c76f0793SBaptiste Daroussin 817f499134dSBaptiste Daroussin ts = conf->ascii_lines ? '-' : ACS_HLINE; 818f499134dSBaptiste Daroussin ltee = conf->ascii_lines ? '+' : ACS_LTEE; 819f499134dSBaptiste Daroussin rtee = conf->ascii_lines ? '+' : ACS_RTEE; 820*263660c0SAlfonso Siciliano 821*263660c0SAlfonso Siciliano getmaxyx(widget, h, w); 822c76f0793SBaptiste Daroussin 823c76f0793SBaptiste Daroussin if (shadow != NULL) 824c76f0793SBaptiste Daroussin wnoutrefresh(shadow); 825c76f0793SBaptiste Daroussin 826*263660c0SAlfonso Siciliano draw_borders(conf, widget, h, w, RAISED); 827c76f0793SBaptiste Daroussin 828f499134dSBaptiste Daroussin if (conf->title != NULL) { 8298c4f4028SBaptiste Daroussin if (t.dialog.delimtitle && conf->no_lines == false) { 830*263660c0SAlfonso Siciliano wattron(widget, t.dialog.lineraisecolor); 831f499134dSBaptiste Daroussin mvwaddch(widget, 0, w/2-strlen(conf->title)/2-1, rtee); 832*263660c0SAlfonso Siciliano wattroff(widget, t.dialog.lineraisecolor); 833c76f0793SBaptiste Daroussin } 8348c4f4028SBaptiste Daroussin wattron(widget, t.dialog.titlecolor); 835f499134dSBaptiste Daroussin mvwaddstr(widget, 0, w/2 - strlen(conf->title)/2, conf->title); 8368c4f4028SBaptiste Daroussin wattroff(widget, t.dialog.titlecolor); 8378c4f4028SBaptiste Daroussin if (t.dialog.delimtitle && conf->no_lines == false) { 838*263660c0SAlfonso Siciliano wattron(widget, t.dialog.lineraisecolor); 839c76f0793SBaptiste Daroussin waddch(widget, ltee); 840*263660c0SAlfonso Siciliano wattroff(widget, t.dialog.lineraisecolor); 841c76f0793SBaptiste Daroussin } 842c76f0793SBaptiste Daroussin } 843c76f0793SBaptiste Daroussin 844*263660c0SAlfonso Siciliano if (bs != NULL) { 845*263660c0SAlfonso Siciliano if (conf->no_lines == false) { 8468c4f4028SBaptiste Daroussin wattron(widget, t.dialog.lineraisecolor); 847c76f0793SBaptiste Daroussin mvwaddch(widget, h-3, 0, ltee); 848c76f0793SBaptiste Daroussin mvwhline(widget, h-3, 1, ts, w-2); 8498c4f4028SBaptiste Daroussin wattroff(widget, t.dialog.lineraisecolor); 850c76f0793SBaptiste Daroussin 8518c4f4028SBaptiste Daroussin wattron(widget, t.dialog.linelowercolor); 852c76f0793SBaptiste Daroussin mvwaddch(widget, h-3, w-1, rtee); 8538c4f4028SBaptiste Daroussin wattroff(widget, t.dialog.linelowercolor); 854c76f0793SBaptiste Daroussin } 855*263660c0SAlfonso Siciliano draw_buttons(widget, *bs, shortcutbuttons); 856*263660c0SAlfonso Siciliano } 857*263660c0SAlfonso Siciliano 858*263660c0SAlfonso Siciliano if (conf->bottomtitle != NULL) { 859*263660c0SAlfonso Siciliano wattron(widget, t.dialog.bottomtitlecolor); 860*263660c0SAlfonso Siciliano wmove(widget, h - 1, w/2 - strlen(conf->bottomtitle)/2 - 1); 861*263660c0SAlfonso Siciliano waddch(widget, ' '); 862*263660c0SAlfonso Siciliano waddstr(widget, conf->bottomtitle); 863*263660c0SAlfonso Siciliano waddch(widget, ' '); 864*263660c0SAlfonso Siciliano wattroff(widget, t.dialog.bottomtitlecolor); 865*263660c0SAlfonso Siciliano } 866c76f0793SBaptiste Daroussin 867c76f0793SBaptiste Daroussin wnoutrefresh(widget); 868c76f0793SBaptiste Daroussin 869*263660c0SAlfonso Siciliano if (textpad != NULL && text != NULL) /* textbox */ 870*263660c0SAlfonso Siciliano if (print_textpad(conf, textpad, text) !=0) 871*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 872c76f0793SBaptiste Daroussin 873*263660c0SAlfonso Siciliano return (0); 874c76f0793SBaptiste Daroussin } 875c76f0793SBaptiste Daroussin 876c76f0793SBaptiste Daroussin int 877*263660c0SAlfonso Siciliano update_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget, 878*263660c0SAlfonso Siciliano int y, int x, int h, int w, WINDOW *textpad, const char *text, 879*263660c0SAlfonso Siciliano struct buttons *bs, bool shortcutbuttons) 880c76f0793SBaptiste Daroussin { 881c76f0793SBaptiste Daroussin int error; 882c76f0793SBaptiste Daroussin 883*263660c0SAlfonso Siciliano if (shadow != NULL) { 884*263660c0SAlfonso Siciliano wclear(shadow); 885*263660c0SAlfonso Siciliano mvwin(shadow, y + t.shadow.h, x + t.shadow.w); 886*263660c0SAlfonso Siciliano wresize(shadow, h, w); 887c76f0793SBaptiste Daroussin } 888c76f0793SBaptiste Daroussin 889*263660c0SAlfonso Siciliano wclear(widget); 890*263660c0SAlfonso Siciliano mvwin(widget, y, x); 891*263660c0SAlfonso Siciliano wresize(widget, h, w); 892*263660c0SAlfonso Siciliano 893*263660c0SAlfonso Siciliano if (textpad != NULL) { 894*263660c0SAlfonso Siciliano wclear(textpad); 895*263660c0SAlfonso Siciliano wresize(textpad, 1, w - HBORDERS - TEXTHMARGINS); 896*263660c0SAlfonso Siciliano } 897*263660c0SAlfonso Siciliano 898*263660c0SAlfonso Siciliano error = draw_dialog(conf, shadow, widget, textpad, text, bs, 899*263660c0SAlfonso Siciliano shortcutbuttons); 900*263660c0SAlfonso Siciliano 901*263660c0SAlfonso Siciliano return (error); 902*263660c0SAlfonso Siciliano } 903*263660c0SAlfonso Siciliano 904c76f0793SBaptiste Daroussin int 905*263660c0SAlfonso Siciliano new_dialog(struct bsddialog_conf *conf, WINDOW **shadow, WINDOW **widget, int y, 906*263660c0SAlfonso Siciliano int x, int h, int w, WINDOW **textpad, const char *text, struct buttons *bs, 907*263660c0SAlfonso Siciliano bool shortcutbuttons) 908c76f0793SBaptiste Daroussin { 909c76f0793SBaptiste Daroussin int error; 910c76f0793SBaptiste Daroussin 911f499134dSBaptiste Daroussin if (conf->shadow) { 912f499134dSBaptiste Daroussin *shadow = newwin(h, w, y + t.shadow.h, x + t.shadow.w); 913c76f0793SBaptiste Daroussin if (*shadow == NULL) 914c76f0793SBaptiste Daroussin RETURN_ERROR("Cannot build shadow"); 915f499134dSBaptiste Daroussin wbkgd(*shadow, t.shadow.color); 916c76f0793SBaptiste Daroussin } 917c76f0793SBaptiste Daroussin 918*263660c0SAlfonso Siciliano if ((*widget = new_boxed_window(conf, y, x, h, w, RAISED)) == NULL) { 919f499134dSBaptiste Daroussin if (conf->shadow) 920c76f0793SBaptiste Daroussin delwin(*shadow); 921*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 922c76f0793SBaptiste Daroussin } 923c76f0793SBaptiste Daroussin 924*263660c0SAlfonso Siciliano if (textpad != NULL && text != NULL) { /* textbox */ 925*263660c0SAlfonso Siciliano *textpad = newpad(1, w - HBORDERS - TEXTHMARGINS); 926c76f0793SBaptiste Daroussin if (*textpad == NULL) { 927*263660c0SAlfonso Siciliano delwin(*widget); 928f499134dSBaptiste Daroussin if (conf->shadow) 929c76f0793SBaptiste Daroussin delwin(*shadow); 930c76f0793SBaptiste Daroussin RETURN_ERROR("Cannot build the pad window for text"); 931c76f0793SBaptiste Daroussin } 9328c4f4028SBaptiste Daroussin wbkgd(*textpad, t.dialog.color); 933c76f0793SBaptiste Daroussin } 934c76f0793SBaptiste Daroussin 935*263660c0SAlfonso Siciliano error = draw_dialog(conf, *shadow, *widget, 936*263660c0SAlfonso Siciliano textpad == NULL ? NULL : *textpad, text, bs, shortcutbuttons); 937c76f0793SBaptiste Daroussin 938*263660c0SAlfonso Siciliano return (error); 939c76f0793SBaptiste Daroussin } 940c76f0793SBaptiste Daroussin 941c76f0793SBaptiste Daroussin void 942*263660c0SAlfonso Siciliano end_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget, 943*263660c0SAlfonso Siciliano WINDOW *textpad) 944c76f0793SBaptiste Daroussin { 945*263660c0SAlfonso Siciliano int y, x, h, w; 946c76f0793SBaptiste Daroussin 947*263660c0SAlfonso Siciliano getbegyx(widget, y, x); 948*263660c0SAlfonso Siciliano getmaxyx(widget, h, w); 949c76f0793SBaptiste Daroussin 950f499134dSBaptiste Daroussin if (conf->sleep > 0) 951f499134dSBaptiste Daroussin sleep(conf->sleep); 952c76f0793SBaptiste Daroussin 953c76f0793SBaptiste Daroussin if (textpad != NULL) 954c76f0793SBaptiste Daroussin delwin(textpad); 955c76f0793SBaptiste Daroussin 956*263660c0SAlfonso Siciliano delwin(widget); 957c76f0793SBaptiste Daroussin 958f499134dSBaptiste Daroussin if (conf->shadow) 959c76f0793SBaptiste Daroussin delwin(shadow); 960c76f0793SBaptiste Daroussin 961f499134dSBaptiste Daroussin if (conf->clear) 962c76f0793SBaptiste Daroussin hide_widget(y, x, h, w, shadow != NULL); 963c76f0793SBaptiste Daroussin 964f499134dSBaptiste Daroussin if (conf->get_height != NULL) 965f499134dSBaptiste Daroussin *conf->get_height = h; 966f499134dSBaptiste Daroussin if (conf->get_width != NULL) 967f499134dSBaptiste Daroussin *conf->get_width = w; 968c76f0793SBaptiste Daroussin }