diff options
author | Alfonso Siciliano <alfsiciliano@gmail.com> | 2021-12-21 15:06:19 +0000 |
---|---|---|
committer | Baptiste Daroussin <bapt@FreeBSD.org> | 2021-12-21 15:06:19 +0000 |
commit | 77a55d2c3b4dd48a9a608736a9ba7ebce700bae1 (patch) | |
tree | 98d3835aeace3bd88e80c39b5de09dd45e42dcd9 | |
parent | e41955dd2d8635cfbab61acb8ad338e7d9f3e7da (diff) |
bsddialog: import snapshot 0.0.2vendor/bsddialog/0.0.2
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | bsddialog.1 | 32 | ||||
-rw-r--r-- | bsddialog.c | 38 | ||||
-rw-r--r-- | examples_library/sade.c | 42 | ||||
-rwxr-xr-x | examples_utility/mixedgauge.sh | 2 | ||||
-rw-r--r-- | lib/GNUMakefile | 4 | ||||
-rw-r--r-- | lib/Makefile | 37 | ||||
-rw-r--r-- | lib/barbox.c | 169 | ||||
-rw-r--r-- | lib/bsddialog.3 | 562 | ||||
-rw-r--r-- | lib/bsddialog.h | 17 | ||||
-rw-r--r-- | lib/bsddialog_progressview.h | 54 | ||||
-rw-r--r-- | lib/bsddialog_theme.h | 4 | ||||
-rw-r--r-- | lib/formbox.c | 135 | ||||
-rw-r--r-- | lib/lib_util.c | 7 | ||||
-rw-r--r-- | lib/lib_util.h | 7 | ||||
-rw-r--r-- | lib/libbsddialog.c | 30 | ||||
-rw-r--r-- | lib/menubox.c | 4 | ||||
-rw-r--r-- | lib/messagebox.c | 48 | ||||
-rw-r--r-- | lib/textbox.c | 3 | ||||
-rw-r--r-- | lib/theme.c | 8 | ||||
-rw-r--r-- | lib/timebox.c | 3 |
21 files changed, 949 insertions, 260 deletions
diff --git a/.gitignore b/.gitignore index ee80e5f5a073..557ad3300d1f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ bsddialog *.o *~ +*.a examples_library/buildlist examples_library/checklist examples_library/datebox @@ -22,4 +23,4 @@ lib/libbsddialog.so* BSDDIALOG.geany BSDDIALOG.tags *.core -bsdinstall/* +freebsd-lab/ diff --git a/bsddialog.1 b/bsddialog.1 index 2846b77547a9..bfee3229bd1f 100644 --- a/bsddialog.1 +++ b/bsddialog.1 @@ -27,15 +27,25 @@ .Os .Sh NAME .Nm bsddialog -.Nd build dialogs and widgets with a TUI +.Nd terminal dialogs and widgets .Sh SYNOPSIS .Nm bsddialog -.Op Fl options -.Ar +.Fl -help +.Nm bsddialog +.Fl -version +.Nm bsddialog +.Op Fl Ar -common-opts +.Fl Ar -widget +.Fl Artext +.Fl Arheight +.Fl Arwidth +.Op Fl Ar -widget-opts .Sh DESCRIPTION The -.Nm -utility processes files ... +.Nm BSDDialog +is an utility to write a script with a Text User Interface. It can build +dialogs and widgets: to show messages, to get input and to inform about a +computation status. .\" .Sh ENVIRONMENT .\" For sections 1, 6, 7, and 8 only. .\" .Sh FILES @@ -44,9 +54,13 @@ utility processes files ... .\" .Sh EXAMPLES .\" .Sh DIAGNOSTICS .\" For sections 1, 4, 6, 7, 8, and 9 printf/stderr messages only. -.\" .Sh SEE ALSO -.\" .Xr foobar 1 +.Sh SEE ALSO +.Xr bsddialog 3 .\" .Sh HISTORY .\" .Sh AUTHORS -.\" .Sh CAVEATS -.\" .Sh BUGS +.Sh CAVEATS +autosize +compatibility text +.Sh BUGS +buildlist +forms diff --git a/bsddialog.c b/bsddialog.c index 6fc0d834a1ad..aa87dec2962b 100644 --- a/bsddialog.c +++ b/bsddialog.c @@ -66,6 +66,7 @@ enum OPTS { HLINE, IGNORE, INSECURE, + ITEM_DEPTH, ITEM_HELP, ITEM_PREFIX, MAX_INPUT, @@ -128,7 +129,7 @@ static char *nostring = ""; /* Menus flags and options */ static bool item_prefix_flag, item_bottomdesc_flag, item_output_sepnl_flag; static bool item_singlequote_flag, list_items_on_flag, item_tag_help_flag; -static bool item_always_quote_flag; +static bool item_always_quote_flag, item_depth_flag; static char *item_output_sep_flag; /* Time and calendar options */ static char *date_fmt_flag, *time_fmt_flag; @@ -227,8 +228,9 @@ void usage(void) "--exit-label <label>, --extra-button, --extra-label <label>," "--hfile <filename>, --help-button, --help-label <label>, " "--help-status, --help-tags, --hline string, --ignore, " - "--insecure, --item-help, --items-prefix, --max-input <size>, " - "--no-cancel, --nocancel, --no-label <label>, --no-items, " + "--insecure, --item-depth, --item-help, --items-prefix, " + "--max-input <size>, --no-cancel, --nocancel, " + "--no-label <label>, --no-items, " "--no-lines, --no-ok, --nook, --no-shadow, --no-tags, " "--ok-label <label>, --output-fd <fd>, " "--output-separator <sep>, --print-version, --print-size, " @@ -271,8 +273,6 @@ void usage(void) "--treeview <text> <rows> <cols> <menurows> [<depth> <name> " "<desc> <on|off> ...]\n" "--yesno <text> <rows> <cols>\n"); - - } int main(int argc, char *argv[argc]) @@ -297,7 +297,7 @@ int main(int argc, char *argv[argc]) cr_wrap_flag = no_collapse_flag = no_nl_expand_flag = trim_flag = false; item_output_sepnl_flag = item_singlequote_flag = false; - item_prefix_flag = item_bottomdesc_flag = false; + item_prefix_flag = item_bottomdesc_flag = item_depth_flag = false; list_items_on_flag = item_tag_help_flag = false; item_always_quote_flag = false; item_output_sep_flag = NULL; @@ -334,6 +334,7 @@ int main(int argc, char *argv[argc]) {"hline", required_argument, NULL, HLINE }, {"ignore", no_argument, NULL, IGNORE }, {"insecure", no_argument, NULL, INSECURE }, + {"item-depth", no_argument, NULL, ITEM_DEPTH }, {"item-help", no_argument, NULL, ITEM_HELP }, {"item-prefix", no_argument, NULL, ITEM_PREFIX }, {"max-input", required_argument, NULL, MAX_INPUT }, @@ -485,6 +486,9 @@ int main(int argc, char *argv[argc]) case INSECURE: conf.form.securech = '*'; break; + case ITEM_DEPTH: + item_depth_flag = true; + break; case ITEM_HELP: item_bottomdesc_flag = true; break; @@ -1080,8 +1084,9 @@ int checklist_builder(BUILDER_ARGS) menurows = atoi(argv[0]); - output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_flag, false, - true, true, true, item_bottomdesc_flag, &nitems, items); + output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_flag, + item_depth_flag, true, true, true, item_bottomdesc_flag, &nitems, + items); if (output != 0) return (output); @@ -1105,8 +1110,9 @@ int menu_builder(BUILDER_ARGS) menurows = atoi(argv[0]); - output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_flag, false, - true, true, false, item_bottomdesc_flag, &nitems, items); + output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_flag, + item_depth_flag, true, true, false, item_bottomdesc_flag, &nitems, + items); if (output != 0) return (output); @@ -1130,8 +1136,9 @@ int radiolist_builder(BUILDER_ARGS) menurows = atoi(argv[0]); - output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_flag, false, - true, true, true, item_bottomdesc_flag, &nitems, items); + output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_flag, + item_depth_flag, true, true, true, item_bottomdesc_flag, &nitems, + items); if (output != 0) return (output); @@ -1220,6 +1227,8 @@ int form_builder(BUILDER_ARGS) flags |= (fieldlen < 0 ? BSDDIALOG_FIELDREADONLY : 0); items[i].flags = flags; + + items[i].bottomdesc = nostring; } output = bsddialog_form(&conf, text, rows, cols, formheight, nitems, @@ -1243,6 +1252,7 @@ int inputbox_builder(BUILDER_ARGS) item.fieldlen = cols > 4 ? cols-4 : 25; item.maxvaluelen = max_input_form_flag > 0 ? max_input_form_flag : 2048; item.flags = 0; + item.bottomdesc = nostring; output = bsddialog_form(&conf, text, rows, cols, 1, 1, &item); print_form_items(&conf, output, 1, &item); @@ -1276,6 +1286,7 @@ int mixedform_builder(BUILDER_ARGS) items[i].fieldlen = atoi(argv[9*i+6]); items[i].maxvaluelen = atoi(argv[9*i+7]); items[i].flags = atoi(argv[9*i+8]); + items[i].bottomdesc = nostring; } output = bsddialog_form(&conf, text, rows, cols, formheight, nitems, @@ -1299,6 +1310,7 @@ int passwordbox_builder(BUILDER_ARGS) item.fieldlen = cols > 4 ? cols-4 : 25; item.maxvaluelen = max_input_form_flag > 0 ? max_input_form_flag : 2048; item.flags = BSDDIALOG_FIELDHIDDEN; + item.bottomdesc = nostring; output = bsddialog_form(&conf, text, rows, cols, 1, 1, &item); print_form_items(&conf, output, 1, &item); @@ -1339,6 +1351,8 @@ int passwordform_builder(BUILDER_ARGS) flags |= (fieldlen < 0 ? BSDDIALOG_FIELDREADONLY : 0); items[i].flags = flags; + + items[i].bottomdesc = nostring; } output = bsddialog_form(&conf, text, rows, cols, formheight, diff --git a/examples_library/sade.c b/examples_library/sade.c index a159ab2afc0b..1c1d74e5a501 100644 --- a/examples_library/sade.c +++ b/examples_library/sade.c @@ -8,16 +8,17 @@ * <http://creativecommons.org/publicdomain/zero/1.0/>. */ +#include <bsddialog.h> #include <stdio.h> #include <string.h> -#include <bsddialog.h> - /* Figure 15 - https://docs.freebsd.org/en/books/handbook/bsdinstall/ */ int main() { int i, output; struct bsddialog_conf conf; + char *text = "Please review the disk setup. When complete, press the " + "Finish button"; struct bsddialog_menuitem items[5] = { {"", false, 0, "ada0", "16 GB GPT", ""}, {"", false, 1, "ada0p1", "512 KB freebsd-boot", ""}, @@ -25,34 +26,25 @@ int main() {"", false, 1, "ada0p3", "819 MB freebsd-swap none", ""}, {"", false, 0, "ada1", "16 GB", ""} }; - + bsddialog_initconf(&conf); - conf.title = "Partition Editor"; - char *text = "Please review the disk setup. When complete, press the "\ - "Finish button"; - - conf.menu.align_left = true; - conf.button.ok_label = "Create"; - - conf.button.with_extra = true; - conf.button.extra_label = "Delete"; - - conf.button.cancel_label = "Cancel"; - - conf.button.with_help = true; - conf.button.help_label = "Revert"; - + conf.title = "Partition Editor"; + conf.menu.shortcut_buttons = true; + conf.menu.align_left = true; + conf.button.ok_label = "Create"; + conf.button.with_extra = true; + conf.button.extra_label = "Delete"; + conf.button.cancel_label = "Cancel"; + conf.button.with_help = true; + conf.button.help_label = "Revert"; conf.button.generic1_label = "Auto"; conf.button.generic2_label = "Finish"; + conf.button.default_label = "Finish"; - conf.button.default_label= "Finish"; - - if (bsddialog_init() < 0) - return -1; - + if (bsddialog_init() == BSDDIALOG_ERROR) + return (1); output = bsddialog_menu(&conf, text, 20, 0, 10, 5, items, NULL); - bsddialog_end(); printf("Menu:\n"); @@ -60,5 +52,5 @@ int main() printf(" [%c] %s\n", items[i].on ? 'X' : ' ', items[i].name); - return output; + return (output); } diff --git a/examples_utility/mixedgauge.sh b/examples_utility/mixedgauge.sh index ce867973859a..bc0f91a1e506 100755 --- a/examples_utility/mixedgauge.sh +++ b/examples_utility/mixedgauge.sh @@ -28,7 +28,7 @@ do "Label 8" 7 \ "Label 9" 9 \ "Label 10" 10 \ - "Label X" " -$perc" + "Label X" " -$perc" #sleep 1 done diff --git a/lib/GNUMakefile b/lib/GNUMakefile index 045b58828a07..318b1218f9c0 100644 --- a/lib/GNUMakefile +++ b/lib/GNUMakefile @@ -3,10 +3,10 @@ # # Written in 2021 by Alfonso Sabato Siciliano -VERSION = 0.1 +VERSION = 0.0.2 LIBRARY = bsddialog LIBRARY_SO = lib${LIBRARY:=.so} -HEADERS = bsddialog.h bsddialog_theme.h +HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h SOURCES = barbox.c formbox.c infobox.c libbsddialog.c lib_util.c menubox.c \ messagebox.c textbox.c theme.c timebox.c OBJECTS = $(SOURCES:.c=.o) diff --git a/lib/Makefile b/lib/Makefile index 08d8db5191dc..e8f3ab6aae02 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -3,44 +3,43 @@ # # Written in 2021 by Alfonso Sabato Siciliano -VERSION = 0.0.1 +VERSION = 0.0.2 LIBRARY = bsddialog LIBRARY_SO = lib${LIBRARY:=.so} -HEADERS = bsddialog.h bsddialog_theme.h +HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h SOURCES = barbox.c formbox.c infobox.c libbsddialog.c lib_util.c menubox.c \ messagebox.c textbox.c theme.c timebox.c OBJECTS= ${SOURCES:.c=.o} -FBSDFLAGS= -O2 -pipe -std=gnu99 -Wno-format-zero-length \ - -fstack-protector-strong -Qunused-arguments -CFLAGS = -fPIC -Wall -Wextra +CFLAGS = -I/usr/local/include -fPIC -Wall -Wextra +LDFLAGS = -fstack-protector-strong -shared -Wl,-x -Wl,--fatal-warnings \ + -Wl,--warn-shared-textrel -Wl,-soname,${LIBRARY_SO}.${VERSION} + .if defined(DEBUG) +# `make -DDEBUG` CFLAGS += -g .else -CFLAGS += ${FBSDFLAGS} +CFLAGS += -O2 -pipe -std=gnu99 -Wno-format-zero-length \ + -fstack-protector-strong -Qunused-arguments .endif -LDFLAGS = -fstack-protector-strong -shared -Wl,-x -Wl,--fatal-warnings \ - -Wl,--warn-shared-textrel -Wl,-soname,${LIBRARY_SO}.${VERSION} - -INSTALL_PREFIX=/usr/local -LN = ln -s -f -RM = rm -f -CP = cp -GZIP = gzip -cn -LDCONFIG = /sbin/ldconfig -m .if defined(PORTNCURSES) -# PORT ncurses `make -DPORTNCURSES` +# PORT ncurses `make -DPORTNCURSES` CFLAGS += -DPORTNCURSES -I/usr/local/include -LDFLAGS += -L/usr/local/lib -lform -lncurses -ltinfo +LDFLAGS += -L/usr/local/lib -lformw -lncursesw -ltinfow .else # BASE ncurses -LDFLAGS += -L/usr/lib -lform -lncurses -ltinfo +LDFLAGS += -L/usr/lib -lformw -lncursesw -ltinfow .endif +INSTALL_PREFIX=/usr/local +LN = ln -s -f +RM = rm -f +CP = cp +GZIP = gzip -cn +LDCONFIG = /sbin/ldconfig -m MAN= ${OUTPUT}.3 GZIP= gzip -cn MANDIR= /usr/local/share/man/man3 - INSTALL= install RM= rm -f diff --git a/lib/barbox.c b/lib/barbox.c index da4f0b72c1d6..d67dfb953992 100644 --- a/lib/barbox.c +++ b/lib/barbox.c @@ -28,16 +28,17 @@ #include <sys/param.h> #include <ctype.h> -#include <stdlib.h> -#include <string.h> - #ifdef PORTNCURSES #include <ncurses/ncurses.h> #else #include <ncurses.h> #endif +#include <stdlib.h> +#include <string.h> +#include <time.h> #include "bsddialog.h" +#include "bsddialog_progressview.h" #include "lib_util.h" #include "bsddialog_theme.h" @@ -46,7 +47,11 @@ #define MINWIDTH (VBORDERS + MINBARWIDTH + BARMARGIN * 2) #define MINHEIGHT 7 /* without text */ -/* "Bar": gauge - mixedgauge - rangebox - pause */ +/* "Bar": gauge - mixedgauge - rangebox - pause - progressview */ + +bool bsddialog_interruptprogview; +bool bsddialog_abortprogview; +int bsddialog_total_progview; extern struct bsddialog_theme t; @@ -218,29 +223,35 @@ bsddialog_gauge(struct bsddialog_conf *conf, char* text, int rows, int cols, return BSDDIALOG_OK; } -int -bsddialog_mixedgauge(struct bsddialog_conf *conf, char* text, int rows, - int cols, unsigned int mainperc, unsigned int nminibars, char **minilabels, - int *minipercs) + +/* Mixedgauge */ +static int +mixedgauge(struct bsddialog_conf *conf, char* text, int rows, int cols, + unsigned int mainperc, unsigned int nminibars, char **minilabels, + int *minipercs, bool color) { WINDOW *widget, *textpad, *bar, *shadow; int i, output, miniperc, y, x, h, w, max_minbarlen; int maxword, maxline, nlines, htextpad, ypad; - char states[12][16] = { - "[ Succeeded ]", /* 0 */ - "[ Failed ]", /* 1 */ - "[ Passed ]", /* 2 */ - "[ Completed ]", /* 3 */ - "[ Checked ]", /* 4 */ - "[ Done ]", /* 5 */ - "[ Skipped ]", /* 6 */ - "[ In Progress ]", /* 7 */ - "(blank) ", /* 8 */ - "[ N/A ]", /* 9 */ - "[ Pending ]", /* 10 */ - "[ UNKNOWN ]", /* 10+ */ + int colorperc, red, green; + char states[12][14] = { + " Succeeded ", /* 0 */ + " Failed ", /* 1 */ + " Passed ", /* 2 */ + " Completed ", /* 3 */ + " Checked ", /* 4 */ + " Done ", /* 5 */ + " Skipped ", /* 6 */ + " In Progress ", /* 7 */ + "(blank) ", /* 8 */ + " N/A ", /* 9 */ + " Pending ", /* 10 */ + " UNKNOWN ", /* 10+ */ }; + red = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_RED, BSDDIALOG_BOLD); + green = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_GREEN,BSDDIALOG_BOLD); + max_minbarlen = 0; for (i=0; i < (int)nminibars; i++) max_minbarlen = MAX(max_minbarlen, (int)strlen(minilabels[i])); @@ -255,7 +266,7 @@ bsddialog_mixedgauge(struct bsddialog_conf *conf, char* text, int rows, if (cols == BSDDIALOG_AUTOSIZE) { w = max_minbarlen + HBORDERS; - w = MAX(max_minbarlen, maxline + 4); + w = MAX(w, maxline + 4); w = MAX(w, (int)conf->auto_minwidth); w = MIN(w, widget_max_width(conf) - 1); } @@ -286,11 +297,26 @@ bsddialog_mixedgauge(struct bsddialog_conf *conf, char* text, int rows, miniperc = minipercs[i]; if (miniperc == 8) continue; + /* label */ + if (color && (miniperc == 7 || miniperc < 0)) + wattron(widget, A_BOLD); mvwaddstr(widget, i+1, 2, minilabels[i]); + wattroff(widget, A_BOLD); + /* perc */ if (miniperc > 10) mvwaddstr(widget, i+1, w-2-15, states[11]); - else if (miniperc >= 0 && miniperc <= 10) - mvwaddstr(widget, i+1, w-2-15, states[miniperc]); + else if (miniperc >= 0 && miniperc <= 10) { + mvwaddstr(widget, i+1, w-2-15, "[ ]"); + if (color && miniperc == 1) /* Failed */ + colorperc = red; + if (color && miniperc == 5) /* Done */ + colorperc = green; + if (color && (miniperc == 1 || miniperc == 5)) + wattron(widget, colorperc); + mvwaddstr(widget, i+1, 1+w-2-15, states[miniperc]); + if (color && (miniperc == 1 || miniperc == 5)) + wattroff(widget, colorperc); + } else { /* miniperc < 0 */ miniperc = abs(miniperc); mvwaddstr(widget, i+1, w-2-15, "[ ]"); @@ -324,6 +350,101 @@ bsddialog_mixedgauge(struct bsddialog_conf *conf, char* text, int rows, } int +bsddialog_mixedgauge(struct bsddialog_conf *conf, char* text, int rows, + int cols, unsigned int mainperc, unsigned int nminibars, char **minilabels, + int *minipercs) +{ + int output; + + output = mixedgauge(conf, text, rows, cols, mainperc, nminibars, + minilabels, minipercs, false); + + return (output); +} + +int +bsddialog_progressview (struct bsddialog_conf *conf, char * text, int rows, + int cols, struct bsddialog_progviewconf *pvconf, unsigned int nminibar, + struct bsddialog_fileminibar *minibar) +{ + int perc, output; + int *minipercs; + unsigned int i; + char **minilabels; + unsigned int mainperc, totaltodo; + time_t tstart, told, tnew, refresh; + bool update; + float readforsec; + + if ((minilabels = calloc(nminibar, sizeof(char*))) == NULL) + RETURN_ERROR("Cannot allocate memory for minilabels\n"); + if ((minipercs = calloc(nminibar, sizeof(int))) == NULL) + RETURN_ERROR("Cannot allocate memory for minipercs\n"); + + totaltodo = 0; + for(i=0; i<nminibar; i++) { + totaltodo += minibar[i].size; + minilabels[i] = minibar[i].label; + minipercs[i] = 10; /*Pending*/ + } + + refresh = pvconf->refresh == 0 ? 0 : pvconf->refresh - 1; + output = BSDDIALOG_OK; + i = 0; + update = true; + time(&told); + tstart = told; + while (!(bsddialog_interruptprogview || bsddialog_abortprogview)) { + if (bsddialog_total_progview == 0 || totaltodo == 0) + mainperc = 0; + else + mainperc = (bsddialog_total_progview * 100) / totaltodo; + + time(&tnew); + if (update || tnew > told + refresh) { + output = mixedgauge(conf, text, rows, cols, mainperc, + nminibar, minilabels, minipercs, true); + if (output == BSDDIALOG_ERROR) + return BSDDIALOG_ERROR; + + move(LINES-1, 2); + clrtoeol(); + readforsec = ((tnew - tstart) == 0) ? + 0 : bsddialog_total_progview / (float)(tnew - tstart); + printw(pvconf->fmtbottomstr, bsddialog_total_progview, + readforsec); + refresh(); + + time(&told); + update = false; + } + + if (i >= nminibar) + break; + if (minibar[i].status == 1) /* Failed*/ + break; + + perc = pvconf->callback(&minibar[i]); + + if (minibar[i].status == 5) {/* ||prec >= 100) Done */ + minipercs[i] = 5; + update = true; + i++; + } else if (minibar[i].status == 1 || perc < 0) { /* Failed */ + minipercs[i] = 1; + update = true; + } else if (perc == 0) + minipercs[i] = 7; /* In progress */ + else /* perc > 0 */ + minipercs[i] = -(perc); + } + + free(minilabels); + free(minipercs); + return (output); +} + +int bsddialog_rangebox(struct bsddialog_conf *conf, char* text, int rows, int cols, int min, int max, int *value) { diff --git a/lib/bsddialog.3 b/lib/bsddialog.3 index 7e1238f38e52..0264c29e4470 100644 --- a/lib/bsddialog.3 +++ b/lib/bsddialog.3 @@ -1,42 +1,530 @@ -.Dd $Mdocdate$ -.Dt PROGNAME section +.\" +.\" Copyright (c) 2021 Alfonso Sabato Siciliano +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd December 16, 2021 +.Dt BSDDIALOG 3 .Os .Sh NAME -.Nm progname -.Nd one line about what it does -.\" .Sh LIBRARY -.\" For sections 2, 3, and 9 only. -.\" Not used in OpenBSD. +.Nm bsddialog_backtitle , +.Nm bsddialog_clearterminal , +.Nm bsddialog_color , +.Nm bsddialog_buildlist , +.Nm bsddialog_checklist , +.Nm bsddialog_datebox , +.Nm bsddialog_end , +.Nm bsddialog_form , +.Nm bsddialog_gauge , +.Nm bsddialog_geterror , +.Nm bsddialog_get_theme +.Nm bsddialog_infobox , +.Nm bsddialog_init , +.Nm bsddialog_initconf , +.Nm bsddialog_menu , +.Nm bsddialog_mixedgauge , +.Nm bsddialog_mixedlist , +.Nm bsddialog_msgbox , +.Nm bsddialog_pause , +.Nm bsddialog_radiolist , +.Nm bsddialog_rangebox , +.Nm bsddialog_set_theme , +.Nm bsddialog_set_default_theme , +.Nm bsddialog_textbox , +.Nm bsddialog_timebox , +.Nm bsddialog_yesno +.Nd terminal dialogs and widgets +.Sh LIBRARY +.Lb libbsddialog .Sh SYNOPSIS -.Nm progname -.Op Fl options -.Ar +.In bsddialog.h + +.Fd #define LIBBSDDIALOG_VERSION + +.Fd #define BSDDIALOG_ERROR +.Fd #define BSDDIALOG_OK +.Fd #define BSDDIALOG_YES +.Fd #define BSDDIALOG_CANCEL +.Fd #define BSDDIALOG_NO +.Fd #define BSDDIALOG_HELP +.Fd #define BSDDIALOG_EXTRA +.Fd #define BSDDIALOG_ITEM_HELP +.Fd #define BSDDIALOG_TIMEOUT +.Fd #define BSDDIALOG_ESC +.Fd #define BSDDIALOG_GENERIC1 +.Fd #define BSDDIALOG_GENERIC2 + +.Fd #define BSDDIALOG_FULLSCREEN +.Fd #define BSDDIALOG_AUTOSIZE +.Fd #define BSDDIALOG_CENTER + +.Fd struct bsddialog_conf +.Fd struct bsddialog_menuitem +.Fd enum bsddialog_grouptype +.Fd struct bsddialog_menugroup +.Fd struct bsddialog_formitem + +.Ft int +.Fn bsddialog_backtitle "struct bsddialog_conf *conf" "char *backtitle" +.Ft int +.Fo bsddialog_buildlist +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fa "unsigned int menurows" +.Fa "int nitems" +.Fa "struct bsddialog_menuitem *items" +.Fa "int *focusitem" +.Fc +.Ft int +.Fo bsddialog_checklist +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fa "unsigned int menurows" +.Fa "int nitems" +.Fa "struct bsddialog_menuitem *items" +.Fa "int *focusitem" +.Fc +.Ft int +.Fn bsddialog_clearterminal "void" +.Ft int +.Fo bsddialog_datebox" +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fa "unsigned int *yy" +.Fa "unsigned int *mm" +.Fa "unsigned int *dd" +.Fc +.Ft int +.Fn bsddialog_end "void" +.Ft int +.Fo bsddialog_form +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fa "unsigned int formheight" +.Fa "unsigned int nitems" +.Fa "struct bsddialog_formitem *items" +.Fc +.Ft int +.Fo bsddialog_gauge +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fa "unsigned int perc" +.Fc +.Ft const char * +.Fn bsddialog_geterror "void" +.Ft int +.Fo bsddialog_infobox +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fc +.Ft int +.Fn bsddialog_init "void" +.Ft int +.Fn bsddialog_initconf "struct bsddialog_conf *conf" +.Ft int +.Fo bsddialog_menu +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fa "unsigned int menurows" +.Fa "int nitems" +.Fa "struct bsddialog_menuitem *items" +.Fa "int *focusitem" +.Fc +.Ft int +.Fo bsddialog_mixedgauge +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fa "unsigned int mainperc" +.Fa "unsigned int nminibars" +.Fa "char **minilabels" +.Fa "int *minipercs" +.Fc +.Ft int +.Fo bsddialog_mixedlist +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fa "unsigned int menurows" +.Fa "int ngroups" +.Fa "struct bsddialog_menugroup *groups" +.Fa "int *focuslist" +.Fa "int *focusitem" +.Fc +.Ft int +.Fo bsddialog_msgbox +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fc +.Ft int +.Fo bsddialog_pause +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fa "unsigned int sec" +.Fc +.Ft int +.Fo bsddialog_radiolist +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fa "unsigned int menurows" +.Fa "int nitems" +.Fa "struct bsddialog_menuitem *items" +.Fa "int *focusitem" +.Fc +.Ft int +.Fo bsddialog_rangebox +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fa "int min" +.Fa "int max" +.Fa "int *value" +.Fc +.Ft int +.Fo bsddialog_textbox +.Fa "struct bsddialog_conf *conf" +.Fa "char* file" +.Fa "int rows" +.Fa "int cols" +.Fc +.Ft int +.Fo bsddialog_timebox +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fa "unsigned int *hh" +.Fa "unsigned int *mm" +.Fa "unsigned int *ss" +.Fc +.Ft int +.Fo bsddialog_yesno +.Fa "struct bsddialog_conf *conf" +.Fa "char* text" +.Fa "int rows" +.Fa "int cols" +.Fc + +.In bsddialog_theme.h + +.Fd #define BSDDIALOG_BOLD +.Fd #define BSDDIALOG_REVERSE +.Fd #define BSDDIALOG_UNDERLINE + +.Fd enum bsddialog_color +.Fd enum bsddialog_default_theme +.Fd struct bsddialog_theme + +.Ft int +.Fo bsddialog_color +.Fa "enum bsddialog_color background" +.Fa "enum bsddialog_color foreground" +.Fa "unsigned int flags" +.Fc +.Ft int +.Fn bsddialog_get_theme "struct bsddialog_theme *theme" +.Ft int +.Fn bsddialog_set_default_theme "enum bsddialog_default_theme theme" +.Ft int +.Fn bsddialog_set_theme "struct bsddialog_theme *theme" .Sh DESCRIPTION The -.Nm -utility processes files ... -.\" .Sh CONTEXT -.\" For section 9 functions only. -.\" .Sh IMPLEMENTATION NOTES -.\" Not used in OpenBSD. -.\" .Sh RETURN VALUES -.\" For sections 2, 3, and 9 function return values only. -.\" .Sh ENVIRONMENT -.\" For sections 1, 6, 7, and 8 only. -.\" .Sh FILES -.\" .Sh EXIT STATUS -.\" For sections 1, 6, and 8 only. -.\" .Sh EXAMPLES -.\" .Sh DIAGNOSTICS -.\" For sections 1, 4, 6, 7, 8, and 9 printf/stderr messages only. -.\" .Sh ERRORS -.\" For sections 2, 3, 4, and 9 errno settings only. -.\" .Sh SEE ALSO -.\" .Xr foobar 1 -.\" .Sh STANDARDS -.\" .Sh HISTORY -.\" .Sh AUTHORS -.\" .Sh CAVEATS -.\" .Sh BUGS -.\" .Sh SECURITY CONSIDERATIONS -.\" Not used in OpenBSD. +.Nm BSDDialog +library is an API to write a tools with a Text User Interface. It can build +dialogs and widgets: to show messages, to get input and to inform about a +computation status. +.Pp +.Bd -literal -offset indent -compact +/* size and position */ +#define BSDDIALOG_FULLSCREEN -1 +#define BSDDIALOG_AUTOSIZE 0 +#define BSDDIALOG_CENTER -1 + +struct bsddialog_conf { + bool ascii_lines; + unsigned int aspect_ratio; + unsigned int auto_minheight; + unsigned int auto_minwidth; + char *bottomtitle; + bool clear; + char *f1_file; + char *f1_message; + int *get_height; + int *get_width; + bool no_lines; + bool shadow; + unsigned int sleep; + char *title; + int y; + int x; + struct { + bool colors; + } text; + struct { + bool align_left; + char *default_item; + bool no_desc; + bool no_name; + bool shortcut_buttons; + } menu; + struct { + int securech; + bool value_withcancel; + bool value_withextra; + bool value_withhelp; + } form; + struct { + bool without_ok; + char *ok_label; + bool with_extra; + char *extra_label; + bool without_cancel; + char *cancel_label; + bool default_cancel; + bool with_help; + char *help_label; + char *exit_label; + char *generic1_label; + char *generic2_label; + char *default_label; + } button; +}; +.Ed +.Pp + +.Ss Dialogs +.Pp +.Bd -literal -offset indent -compact +struct bsddialog_menuitem { + char *prefix; + bool on; + unsigned int depth; + char *name; + char *desc; + char *bottomdesc; +}; + +enum bsddialog_grouptype { + BSDDIALOG_CHECKLIST, + BSDDIALOG_RADIOLIST, + BSDDIALOG_SEPARATOR, +}; + +struct bsddialog_menugroup { + enum bsddialog_grouptype type; + unsigned int nitems; + struct bsddialog_menuitem *items; +}; + +struct bsddialog_formitem { + char *label; + unsigned int ylabel; + unsigned int xlabel; + + char *init; + unsigned int yfield; + unsigned int xfield; + unsigned int fieldlen; + unsigned int maxvaluelen; + char *value; /* allocated memory */ +#define BSDDIALOG_FIELDHIDDEN 1U +#define BSDDIALOG_FIELDREADONLY 2U + unsigned int flags; + + char *bottomdesc; +}; +.Ed +.Pp + +.Ss Theme +.Pp +.Bd -literal -offset indent -compact +/* f_ focus/active element */ +struct bsddialog_theme { + struct { + int color; + } terminal; + struct { + int color; + unsigned int h; + unsigned int w; + } shadow; + struct { + int color; + bool delimtitle; + int titlecolor; + int lineraisecolor; + int linelowercolor; + int bottomtitlecolor; + } dialog; + struct { + unsigned int hmargin; + } text; + struct { + int arrowcolor; + int selectorcolor; + int f_namecolor; + int namecolor; + int f_desccolor; + int desccolor; + int namesepcolor; + int descsepcolor; + int f_shortcutcolor; + int shortcutcolor; + } menu; + struct { + int f_fieldcolor; + int fieldcolor; + int readonlycolor; + } form; + struct { + int f_color; + int color; + } bar; + struct { + unsigned int space; + int leftch; + int rightch; + int delimcolor; + int f_delimcolor; + int color; + int f_color; + int shortcutcolor; + int f_shortcutcolor; + } button; +}; + +enum bsddialog_default_theme { + BSDDIALOG_THEME_BLACKWHITE, + BSDDIALOG_THEME_BSDDIALOG, + BSDDIALOG_THEME_DEFAULT, + BSDDIALOG_THEME_DIALOG, +}; + +enum bsddialog_color { + BSDDIALOG_BLACK = 0, + BSDDIALOG_RED, + BSDDIALOG_GREEN, + BSDDIALOG_YELLOW, + BSDDIALOG_BLUE, + BSDDIALOG_MAGENTA, + BSDDIALOG_CYAN, + BSDDIALOG_WHITE, +}; + +#define BSDDIALOG_BOLD 1U +#define BSDDIALOG_REVERSE 2U +#define BSDDIALOG_UNDERLINE 4U +.Ed +.Pp + +.Sh RETURN VALUES +The sysctlmif_oidbyname(), sysctlmif_oidextendedbyname(), + sysctlmif_name(), sysctlmif_desc(), sysctlmif_descbyname(), + sysctlmif_label(), sysctlmif_labelbyname(), sysctlmif_fmt(), + sysctlmif_fmtbyname(), sysctlmif_oidbyname0(), sysctlmif_oidbyname1(), + sysctlmif_oidbyname2(), sysctlmif_oidbyname3(), sysctlmif_oidbyname4(), + sysctlmif_oidbyname5(), sysctlmif_oidbyname6(), and + sysctlmif_oidbyname7() functions return the value 0 if successful; other- + wise the value -1 is returned and the global variable errno is set to in- + dicate the error. + + +functions return NULL upon error or a pointer to allo- + cated memory for success. + +.Sh EXAMPLES +Complete set of examples: +.Lk https://gitlab.com/alfix/bsddialog/-/blob/main/examples_library/ +.Pp +If installed: +.Dl /usr/local/share/examples/libbsddialog +.Pp +"Yes-No Question" Example: +.Pp +.Bd -literal -offset indent -compact +int output; +struct bsddialog_conf conf; + +bsddialog_initconf(&conf); +conf.title = "yesno"; +if (bsddialog_init() == BSDDIALOG_ERROR) + return (1); + +output = bsddialog_yesno(&conf, "Example", 7, 25); + +bsddialog_end(); + +switch (output) { +case BSDDIALOG_YES: + printf("OK\\n"); + break; +case BSDDIALOG_NO + printf("NO\\n"); + break; +case BSDDIALOG_ESC; + printf("ESC\\n"); + break; +case BSDDIALOG_ERROR: + printf("Error: %s\\n", bsddialog_geterror()); +} +.Ed +.Sh SEE ALSO +.Xr bsddialog 1 +.Sh HISTORY +The +.Nm bsddialog +library first appeared in +.Fx 14.0 . +.Sh AUTHORS +.Nm bsddialog +was written by +.An Alfonso Sabato Siciliano Aq Mt alf.siciliano@gmail.com . +.Sh CAVEATS +See +.Xr bsddialog +.Sh BUGS +See +.Xr bsddialog 1 diff --git a/lib/bsddialog.h b/lib/bsddialog.h index 29b9b5240706..94342199439e 100644 --- a/lib/bsddialog.h +++ b/lib/bsddialog.h @@ -30,7 +30,7 @@ #include <stdbool.h> -#define LIBBSDDIALOG_VERSION "0.0.1" +#define LIBBSDDIALOG_VERSION "0.0.2" /* Exit status */ #define BSDDIALOG_ERROR -1 @@ -40,13 +40,12 @@ #define BSDDIALOG_NO BSDDIALOG_CANCEL #define BSDDIALOG_HELP 2 #define BSDDIALOG_EXTRA 3 -#define BSDDIALOG_ITEM_HELP 4 -#define BSDDIALOG_TIMEOUT 5 -#define BSDDIALOG_ESC 6 -#define BSDDIALOG_GENERIC1 7 -#define BSDDIALOG_GENERIC2 8 +#define BSDDIALOG_TIMEOUT 4 +#define BSDDIALOG_ESC 5 +#define BSDDIALOG_GENERIC1 6 +#define BSDDIALOG_GENERIC2 7 -/* size and position */ +/* Size and position */ #define BSDDIALOG_FULLSCREEN -1 #define BSDDIALOG_AUTOSIZE 0 #define BSDDIALOG_CENTER -1 @@ -132,7 +131,7 @@ struct bsddialog_formitem { unsigned int xfield; unsigned int fieldlen; unsigned int maxvaluelen; - char *value; /* allocated memory */ + char *value; #define BSDDIALOG_FIELDHIDDEN 1U #define BSDDIALOG_FIELDREADONLY 2U unsigned int flags; @@ -147,7 +146,7 @@ int bsddialog_initconf(struct bsddialog_conf *conf); int bsddialog_clearterminal(void); const char *bsddialog_geterror(void); -/* widgets */ +/* Dialogs */ int bsddialog_buildlist(struct bsddialog_conf *conf, char* text, int rows, int cols, unsigned int menurows, int nitems, struct bsddialog_menuitem *items, diff --git a/lib/bsddialog_progressview.h b/lib/bsddialog_progressview.h new file mode 100644 index 000000000000..453d46a242e6 --- /dev/null +++ b/lib/bsddialog_progressview.h @@ -0,0 +1,54 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2021 Alfonso Sabato Siciliano + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _LIBBSDDIALOG_PROGRESSVIEW_H_ +#define _LIBBSDDIALOG_PROGRESSVIEW_H_ + +extern bool bsddialog_interruptprogview; +extern bool bsddialog_abortprogview; +extern int bsddialog_total_progview; + +struct bsddialog_fileminibar { + char *path; + char *label; + int status; /* mixedgauge: 1 failed - 5 done - 7 in progress*/ + long long size; + long long read; +}; + +struct bsddialog_progviewconf { + char *fmtbottomstr; + unsigned int refresh; /* in seconds */ + int (*callback)(struct bsddialog_fileminibar *minibar); +}; + +int +bsddialog_progressview (struct bsddialog_conf *conf, char * text, int rows, + int cols, struct bsddialog_progviewconf *pvconf, unsigned int nminibar, + struct bsddialog_fileminibar *minibar); + +#endif diff --git a/lib/bsddialog_theme.h b/lib/bsddialog_theme.h index d20985e66b18..853eb5f9d864 100644 --- a/lib/bsddialog_theme.h +++ b/lib/bsddialog_theme.h @@ -106,8 +106,8 @@ enum bsddialog_color { #define BSDDIALOG_UNDERLINE 4U int -bsddialog_color(enum bsddialog_color background, - enum bsddialog_color foreground, unsigned int flags); +bsddialog_color(enum bsddialog_color foreground, + enum bsddialog_color background, unsigned int flags); int bsddialog_get_theme(struct bsddialog_theme *theme); int bsddialog_set_default_theme(enum bsddialog_default_theme theme); int bsddialog_set_theme(struct bsddialog_theme *theme); diff --git a/lib/formbox.c b/lib/formbox.c index fd497174a7ce..3a5d8a49e359 100644 --- a/lib/formbox.c +++ b/lib/formbox.c @@ -28,14 +28,13 @@ #include <sys/param.h> #include <ctype.h> -#include <stdlib.h> -#include <string.h> - #ifdef PORTNCURSES #include <ncurses/form.h> #else #include <form.h> #endif +#include <stdlib.h> +#include <string.h> #include "bsddialog.h" #include "lib_util.h" @@ -51,10 +50,10 @@ extern struct bsddialog_theme t; /* util struct for private buffer and view options */ struct myfield { - int len; + int buflen; char *buf; int pos; - int size; + int maxpos; bool secure; int securech; char *bottomdesc; @@ -66,30 +65,32 @@ static void insertch(struct myfield *mf, int ch) { int i; - if (mf->len == mf->size) + if (mf->buflen > mf->maxpos) return; - for (i=mf->len-1; i>=mf->pos; i--) { + for (i = mf->buflen; i >= mf->pos; i--) { mf->buf[i+1] = mf->buf[i]; } mf->buf[mf->pos] = ch; mf->pos += 1; - mf->len += 1; - mf->buf[mf->len] = '\0'; + if (mf->pos > mf->maxpos) + mf->pos = mf->maxpos; + mf->buflen += 1; + mf->buf[mf->buflen] = '\0'; } static void shiftleft(struct myfield *mf) { int i, last; - for (i=mf->pos; i<mf->len; i++) { + for (i = mf->pos; i < mf->buflen -1; i++) { mf->buf[i] = mf->buf[i+1]; } - last = mf->len > 0 ? mf->len -1 : 0; + last = mf->buflen > 0 ? mf->buflen -1 : 0; mf->buf[last] = '\0'; - mf->len = last; + mf->buflen = last; } static void print_bottomdesc(struct myfield *mf) @@ -103,6 +104,36 @@ static void print_bottomdesc(struct myfield *mf) } } +int +return_values(struct bsddialog_conf *conf, struct buttons bs, int nitems, + struct bsddialog_formitem *items, FORM *form, FIELD **cfield) +{ + int i, output; + struct myfield *mf; + + output = bs.value[bs.curr]; + if (output == BSDDIALOG_HELP && conf->form.value_withhelp == false) + return output; + if (output == BSDDIALOG_EXTRA && conf->form.value_withextra == false) + return output; + if (output == BSDDIALOG_CANCEL && conf->form.value_withcancel == false) + return output; + if (output == BSDDIALOG_GENERIC1 || output == BSDDIALOG_GENERIC2) + return output; + + /* BSDDIALOG_OK */ + form_driver(form, REQ_NEXT_FIELD); + form_driver(form, REQ_PREV_FIELD); + for (i=0; i<nitems; i++) { + mf = GETMYFIELD(cfield[i]); + items[i].value = strdup(mf->buf); + if (items[i].value == NULL) + RETURN_ERROR("Cannot allocate memory for form value"); + } + + return (output); +} + static int form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols, struct buttons bs, WINDOW *formwin, FORM *form, FIELD **cfield, int nitems, @@ -112,15 +143,14 @@ form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols, int i, input, output; struct myfield *mf; - curs_set(2); - pos_form_cursor(form); - loop = buttupdate = true; - bs.curr = -1; - form_driver(form, REQ_END_LINE); - form_driver(form, REQ_END_LINE); mf = GETMYFIELD2(form); print_bottomdesc(mf); - mf->pos = mf->len; + pos_form_cursor(form); + form_driver(form, REQ_END_LINE); + mf->pos = MIN(mf->buflen, mf->maxpos); + curs_set(2); + bs.curr = -1; + loop = buttupdate = true; while(loop) { if (buttupdate) { draw_buttons(widget, y, cols, bs, !informwin); @@ -135,30 +165,7 @@ form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols, if (informwin) break; loop = false; - output = bs.value[bs.curr]; - if (output == BSDDIALOG_HELP && - conf->form.value_withhelp == false) - break; - if (output == BSDDIALOG_EXTRA && - conf->form.value_withextra == false) - break; - if (output == BSDDIALOG_CANCEL && - conf->form.value_withcancel == false) - break; - if (output == BSDDIALOG_GENERIC1 || - output == BSDDIALOG_GENERIC2) - break; - - /* BSDDIALOG_OK */ - form_driver(form, REQ_NEXT_FIELD); - form_driver(form, REQ_PREV_FIELD); - for (i=0; i<nitems; i++) { - mf = GETMYFIELD(cfield[i]); - items[i].value = strdup(mf->buf); - if (items[i].value == NULL) - RETURN_ERROR("Cannot allocate memory " - "for form value"); - } + output = return_values(conf, bs, nitems, items, form, cfield); break; case 27: /* Esc */ output = BSDDIALOG_ESC; @@ -196,7 +203,7 @@ form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols, case KEY_RIGHT: if (informwin) { mf = GETMYFIELD2(form); - if (mf->pos >= mf->len) + if (mf->pos >= mf->buflen) break; mf->pos += 1; form_driver(form, REQ_NEXT_CHAR); @@ -216,7 +223,7 @@ form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols, form_driver(form, REQ_END_LINE); mf = GETMYFIELD2(form); print_bottomdesc(mf); - mf->pos = mf->len; + mf->pos = MIN(mf->buflen, mf->maxpos); set_field_fore(current_field(form), t.form.f_fieldcolor); set_field_back(current_field(form), t.form.f_fieldcolor); break; @@ -229,7 +236,7 @@ form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols, form_driver(form, REQ_END_LINE); mf = GETMYFIELD2(form); print_bottomdesc(mf); - mf->pos = mf->len; + mf->pos = MIN(mf->buflen, mf->maxpos); set_field_fore(current_field(form), t.form.f_fieldcolor); set_field_back(current_field(form), t.form.f_fieldcolor); break; @@ -239,14 +246,16 @@ form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols, if (mf->pos <= 0) break; form_driver(form, REQ_DEL_PREV); - mf = GETMYFIELD2(form); - mf->pos -= 1; + form_driver(form, REQ_BEG_LINE); + mf->pos = mf->pos - 1; + for (i=0; i<mf->pos; i++) + form_driver(form, REQ_NEXT_CHAR); shiftleft(mf); break; case KEY_DC: form_driver(form, REQ_DEL_CHAR); mf = GETMYFIELD2(form); - if (mf->len-1 >= mf->pos) + if (mf->pos < mf->buflen) shiftleft(mf); break; case KEY_F(1): @@ -275,7 +284,9 @@ form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols, for (i = 0; i < (int) bs.nbuttons; i++) { if (tolower(input) == tolower((bs.label[i])[0])) { - output = bs.value[i]; + bs.curr = i; + output = return_values(conf, bs, + nitems, items, form, cfield); loop = false; } } @@ -386,6 +397,15 @@ bsddialog_form(struct bsddialog_conf *conf, char* text, int rows, int cols, if (formheight < nitems) formheight = nitems; + for (i = 0; i < (int)nitems; i++) { + if (items[i].maxvaluelen == 0) + RETURN_ERROR("maxvaluelen cannot be zero"); + if (items[i].fieldlen == 0) + RETURN_ERROR("fieldlen cannot be zero"); + if (items[i].fieldlen > items[i].maxvaluelen) + RETURN_ERROR("fieldlen cannot be > maxvaluelen"); + } + maxline = 0; myfields = malloc(nitems * sizeof(struct myfield)); cfield = calloc(nitems + 1, sizeof(FIELD*)); @@ -396,12 +416,15 @@ bsddialog_form(struct bsddialog_conf *conf, char* text, int rows, int cols, set_max_field(cfield[i], items[i].maxvaluelen); set_field_buffer(cfield[i], 0, items[i].init); - myfields[i].pos = strlen(items[i].init); - myfields[i].len = strlen(items[i].init); - myfields[i].size = items[i].maxvaluelen; - myfields[i].buf = malloc(myfields[i].size); - memset(myfields[i].buf, 0, myfields[i].size); - strcpy(myfields[i].buf, items[i].init); + myfields[i].buf = malloc(items[i].maxvaluelen + 1); + memset(myfields[i].buf, 0, items[i].maxvaluelen + 1); // end with '\0' for strdup + strncpy(myfields[i].buf, items[i].init, items[i].maxvaluelen); + + myfields[i].buflen = strlen(myfields[i].buf); + + myfields[i].maxpos = items[i].maxvaluelen -1; + myfields[i].pos = MIN(myfields[i].buflen, myfields[i].maxpos); + myfields[i].bottomdesc = items[i].bottomdesc; set_field_userptr(cfield[i], &myfields[i]); diff --git a/lib/lib_util.c b/lib/lib_util.c index b9bb29ba58cf..81c2b7642aac 100644 --- a/lib/lib_util.c +++ b/lib/lib_util.c @@ -27,15 +27,14 @@ #include <sys/param.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - #ifdef PORTNCURSES #include <ncurses/ncurses.h> #else #include <ncurses.h> #endif +#include <stdlib.h> +#include <string.h> +#include <unistd.h> #include "bsddialog.h" #include "lib_util.h" diff --git a/lib/lib_util.h b/lib/lib_util.h index 2c552a36c6a9..e9791b1894a7 100644 --- a/lib/lib_util.h +++ b/lib/lib_util.h @@ -32,8 +32,11 @@ * Utils to implement widgets - Internal library API - Dafult values */ -#define HBORDERS 2 -#define VBORDERS 2 +#define HBORDER 1 +#define HBORDERS (HBORDER + HBORDER) +#define VBORDER 1 +#define VBORDERS (VBORDER + VBORDER) +#define PADDING(p) (p) /* ncurses has not a Ctrl key macro */ #define KEY_CTRL(x) ((x) & 0x1f) diff --git a/lib/libbsddialog.c b/lib/libbsddialog.c index a3cbe6bf9748..aea3b152adfd 100644 --- a/lib/libbsddialog.c +++ b/lib/libbsddialog.c @@ -25,15 +25,14 @@ * SUCH DAMAGE. */ -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - #ifdef PORTNCURSES #include <ncurses/ncurses.h> #else #include <ncurses.h> #endif +#include <stdlib.h> +#include <string.h> +#include <unistd.h> #include "bsddialog.h" #include "lib_util.h" @@ -41,14 +40,14 @@ /* * This file implements public functions not related to a specific dialog. - * utils.h/c: private functions to implement the library. + * lib_utils.h/c: private functions to implement the library. * theme.h/c: public API related to themes. * Dialogs implementation: * infobox.c infobox * messgebox.c msgbox - yesno * menubox.c buildlist - checklist - menu - mixedlist - radiolist * formbox.c inputbox - passwordbox - form - passwordform - mixedform - * barbox.c gauge - mixedgauge - rangebox - pause + * barbox.c gauge - mixedgauge - rangebox - pause - progressview * textbox.c textbox * timebox.c timebox - calendar */ @@ -57,13 +56,14 @@ extern struct bsddialog_theme t; int bsddialog_init(void) { - int i, j, c = 1, error = OK; + int i, j, c, error; set_error_string(""); if(initscr() == NULL) RETURN_ERROR("Cannot init ncurses (initscr)"); + error = OK; error += keypad(stdscr, TRUE); nl(); error += cbreak(); @@ -74,6 +74,7 @@ int bsddialog_init(void) RETURN_ERROR("Cannot init ncurses (keypad and cursor)"); } + c = 1; error += start_color(); for (i=0; i<8; i++) for(j=0; j<8; j++) { @@ -90,39 +91,35 @@ int bsddialog_init(void) return (BSDDIALOG_ERROR); } - return (0); + return (BSDDIALOG_OK); } int bsddialog_end(void) { - if (endwin() != OK) RETURN_ERROR("Cannot end ncurses (endwin)"); - return (0); + return (BSDDIALOG_OK); } int bsddialog_backtitle(struct bsddialog_conf *conf, char *backtitle) { - mvaddstr(0, 1, backtitle); if (conf->no_lines != true) mvhline(1, 1, conf->ascii_lines ? '-' : ACS_HLINE, COLS-2); refresh(); - return (0); + return (BSDDIALOG_OK); } const char *bsddialog_geterror(void) { - return (get_error_string()); } int bsddialog_initconf(struct bsddialog_conf *conf) { - if (conf == NULL) RETURN_ERROR("conf is NULL"); if (sizeof(*conf) != sizeof(struct bsddialog_conf)) @@ -133,15 +130,14 @@ int bsddialog_initconf(struct bsddialog_conf *conf) conf->x = BSDDIALOG_CENTER; conf->shadow = true; - return (0); + return (BSDDIALOG_OK); } int bsddialog_clearterminal(void) { - if (clear() != OK) RETURN_ERROR("Cannot clear the terminal"); refresh(); - return (0); + return (BSDDIALOG_OK); } diff --git a/lib/menubox.c b/lib/menubox.c index 147fa66c8c27..c9fb182422ea 100644 --- a/lib/menubox.c +++ b/lib/menubox.c @@ -28,13 +28,13 @@ #include <sys/param.h> #include <ctype.h> -#include <string.h> - #ifdef PORTNCURSES #include <ncurses/ncurses.h> #else #include <ncurses.h> #endif +#include <string.h> + #include "bsddialog.h" #include "lib_util.h" diff --git a/lib/messagebox.c b/lib/messagebox.c index e2b91e1bdc5c..6fe775cfcbc9 100644 --- a/lib/messagebox.c +++ b/lib/messagebox.c @@ -28,33 +28,26 @@ #include <sys/param.h> #include <ctype.h> -#include <string.h> - #ifdef PORTNCURSES #include <ncurses/ncurses.h> #else #include <ncurses.h> #endif +#include <string.h> #include "bsddialog.h" #include "lib_util.h" #include "bsddialog_theme.h" -/* "Message": msgbox - yesno */ - #define AUTO_WIDTH (COLS / 3U) -/* - * Min height = 5: 2 up & down borders + 2 label & up border buttons + 1 line - * for text, at least 1 line is important for widget_withtextpad_init() to avoid - * "Cannot build the pad window for text". - */ -#define MIN_HEIGHT 5 +/* at least 1 line text for its pad building in widget_withtextpad_init() */ +#define MIN_HEIGHT (HBORDERS + 2 /*buttons*/ + 1 /*text*/) extern struct bsddialog_theme t; static int -message_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w, - char *text, struct buttons bs) +message_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, + int *w, char *text, struct buttons bs) { int maxword, maxline, nlines, line; @@ -109,9 +102,9 @@ static int message_checksize(int rows, int cols, struct buttons bs) } static void -buttonsupdate(WINDOW *widget, int h, int w, struct buttons bs, bool shortkey) +buttonsupdate(WINDOW *widget, int h, int w, struct buttons bs) { - draw_buttons(widget, h-2, w, bs, shortkey); + draw_buttons(widget, h-2, w, bs, true); wnoutrefresh(widget); } @@ -119,7 +112,6 @@ static void textupdate(WINDOW *widget, int y, int x, int h, int w, WINDOW *textpad, int htextpad, int textrow) { - if (htextpad > h - 4) { mvwprintw(widget, h-3, w-6, "%3d%%", 100 * (textrow+h-4)/ htextpad); @@ -130,8 +122,8 @@ textupdate(WINDOW *widget, int y, int x, int h, int w, WINDOW *textpad, } static int -do_widget(struct bsddialog_conf *conf, char *text, int rows, int cols, - struct buttons bs, bool shortkey) +do_dialog(struct bsddialog_conf *conf, char *text, int rows, int cols, + struct buttons bs) { WINDOW *widget, *textpad, *shadow; bool loop; @@ -152,7 +144,7 @@ do_widget(struct bsddialog_conf *conf, char *text, int rows, int cols, textrow = 0; loop = true; - buttonsupdate(widget, h, w, bs, shortkey); + buttonsupdate(widget, h, w, bs); textupdate(widget, y, x, h, w, textpad, htextpad, textrow); while(loop) { doupdate(); @@ -168,7 +160,7 @@ do_widget(struct bsddialog_conf *conf, char *text, int rows, int cols, break; case '\t': /* TAB */ bs.curr = (bs.curr + 1) % bs.nbuttons; - buttonsupdate(widget, h, w, bs, shortkey); + buttonsupdate(widget, h, w, bs); break; case KEY_F(1): if (conf->f1_file == NULL && conf->f1_message == NULL) @@ -210,7 +202,7 @@ do_widget(struct bsddialog_conf *conf, char *text, int rows, int cols, RAISED, textpad, &htextpad, text, true) != 0) return BSDDIALOG_ERROR; - buttonsupdate(widget, h, w, bs, shortkey); + buttonsupdate(widget, h, w, bs); textupdate(widget, y, x, h, w, textpad, htextpad, textrow); /* Important to fix grey lines expanding screen */ @@ -231,21 +223,18 @@ do_widget(struct bsddialog_conf *conf, char *text, int rows, int cols, case KEY_LEFT: if (bs.curr > 0) { bs.curr--; - buttonsupdate(widget, h, w, bs, shortkey); + buttonsupdate(widget, h, w, bs); } break; case KEY_RIGHT: if (bs.curr < (int) bs.nbuttons - 1) { bs.curr++; - buttonsupdate(widget, h, w, bs, shortkey); + buttonsupdate(widget, h, w, bs); } break; default: - if (shortkey == false) - break; - for (i = 0; i < (int) bs.nbuttons; i++) - if (tolower(input) == tolower((bs.label[i])[0])) { + if (tolower(input) == tolower(bs.label[i][0])) { output = bs.value[i]; loop = false; } @@ -258,16 +247,15 @@ do_widget(struct bsddialog_conf *conf, char *text, int rows, int cols, } /* API */ - int bsddialog_msgbox(struct bsddialog_conf *conf, char* text, int rows, int cols) { struct buttons bs; get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), - NULL /* nocancel */, BUTTONLABEL(help_label)); + NULL, BUTTONLABEL(help_label)); - return (do_widget(conf, text, rows, cols, bs, true)); + return (do_dialog(conf, text, rows, cols, bs)); } int @@ -281,5 +269,5 @@ bsddialog_yesno(struct bsddialog_conf *conf, char* text, int rows, int cols) conf->button.cancel_label == NULL ? "No" : conf->button.cancel_label, BUTTONLABEL(help_label)); - return (do_widget(conf, text, rows, cols, bs, true)); + return (do_dialog(conf, text, rows, cols, bs)); } diff --git a/lib/textbox.c b/lib/textbox.c index 22dd21470c3a..6dae6c81343b 100644 --- a/lib/textbox.c +++ b/lib/textbox.c @@ -28,13 +28,12 @@ #include <sys/param.h> -#include <string.h> - #ifdef PORTNCURSES #include <ncurses/ncurses.h> #else #include <ncurses.h> #endif +#include <string.h> #include "bsddialog.h" #include "lib_util.h" diff --git a/lib/theme.c b/lib/theme.c index 3bcd8ee8fc53..0948501e52ff 100644 --- a/lib/theme.c +++ b/lib/theme.c @@ -87,8 +87,8 @@ static struct bsddialog_theme bsddialogtheme = { }; static struct bsddialog_theme blackwhite = { -#define bk COLOR_BLACK #define fg COLOR_WHITE +#define bk COLOR_BLACK .terminal.color = GET_COLOR(fg, bk), .shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK), @@ -272,8 +272,8 @@ int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme) } int -bsddialog_color(enum bsddialog_color background, - enum bsddialog_color foreground, unsigned int flags) +bsddialog_color(enum bsddialog_color foreground, + enum bsddialog_color background, unsigned int flags) { unsigned int cursesflags = 0; @@ -284,5 +284,5 @@ bsddialog_color(enum bsddialog_color background, if (flags & BSDDIALOG_UNDERLINE) cursesflags |= A_UNDERLINE; - return (GET_COLOR(background, foreground) | cursesflags); + return (GET_COLOR(foreground, background) | cursesflags); } diff --git a/lib/timebox.c b/lib/timebox.c index 2597cbf0c152..04e058448149 100644 --- a/lib/timebox.c +++ b/lib/timebox.c @@ -27,13 +27,12 @@ #include <sys/param.h> +#include <ctype.h> #ifdef PORTNCURSES #include <ncurses/ncurses.h> #else #include <ncurses.h> #endif - -#include <ctype.h> #include <string.h> #include "bsddialog.h" |