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