aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfonso S. Siciliano <asiciliano@FreeBSD.org>2024-05-16 13:24:49 +0000
committerAlfonso S. Siciliano <asiciliano@FreeBSD.org>2024-05-16 13:24:49 +0000
commitbe8846bd9e069f4a6bea3d769005bea96cf43990 (patch)
treef95c7bf7ccfdbc7ffcb90fe46c2dd95f76d32449
parente56a937c3e111672afff33346941fb618792308b (diff)
contrib/bsddialog: Import version 1.0.2vendor/bsddialog/1.0.2
Implicitly import also 1.0.1, both versions are for fixing and feature requests. Fixing: Change --mixedform behavior to fix a bsdinstall fault avoiding to change the command line in wlanconfig. Feature requests: * Add keys to navigate menus. * Add key to redraw dialogs. * Avoid to handle env NCURSES_NO_UTF8_ACS in PuTTY. See '2024-04-11 Version 1.0.2' and '2023-11-16 Version 1.0.1' in /usr/src/contrib/bsddialog/CHANGELOG for more detailed information. PR: 274472 Differential Revision: D42380
-rw-r--r--CHANGELOG32
-rw-r--r--LICENSE2
-rw-r--r--Makefile12
-rw-r--r--README.md27
-rw-r--r--examples_library/gauge.c2
-rw-r--r--examples_library/mixedgauge.c2
-rw-r--r--lib/barbox.c86
-rw-r--r--lib/bsddialog.337
-rw-r--r--lib/bsddialog.h4
-rw-r--r--lib/datebox.c53
-rw-r--r--lib/formbox.c43
-rw-r--r--lib/lib_util.c111
-rw-r--r--lib/lib_util.h9
-rw-r--r--lib/libbsddialog.c9
-rw-r--r--lib/menubox.c25
-rw-r--r--lib/messagebox.c15
-rw-r--r--lib/textbox.c34
-rw-r--r--lib/timebox.c17
-rw-r--r--utility/bsddialog.183
-rw-r--r--utility/bsddialog.c6
-rw-r--r--utility/util_builders.c72
-rw-r--r--utility/util_theme.c12
22 files changed, 469 insertions, 224 deletions
diff --git a/CHANGELOG b/CHANGELOG
index e6295768d906..0e75f847347d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,35 @@
+2024-04-11 Version 1.0.2
+
+ Utility:
+ improvements and changes for --form and --mixedform:
+ * add: <maxletters> 0 sets <maxletters> like <fieldlen>.
+ * add: <fieldlen> 0 sets <fieldlen> like <init> width and readonly.
+ * change: <maxletters> 0 was an error (remains error in lib).
+ * change: <fieldlen> 0 was an error (remains error in lib)
+ (<fieldlen> 0 and <init> "" is still an error.).
+
+ Library and implicitly utility:
+ * add: Ctrl-l to redraw dialog.
+ Request stable@freebsd.org January 2024.
+ * add: -, +, Ctrl-p, Ctrl-n for several dialogs.
+ +, - request for menus, private feature request.
+ Ctrl-p, Ctrl-n for menu, request hackers@freebsd.org February 2024.
+ * fix: escaped text ending with an escape symbol.
+ * change: truncate mixedgauge long (over the screen/minibars)
+ minilabels adding "...". As a result, avoid check-size error.
+ https://gitlab.com/alfix/bsddialog/-/issues/6.
+ * change: invert UP/DOWN keys to set a rangebox value.
+
+
+2023-11-16 Version 1.0.1
+
+ Library Internal Refactoring:
+ * add: arrow macro handlers.
+ * change: Box-drawing characters, from utf8 to wide chars to avoid to
+ handle "env NCURSES_NO_UTF8_ACS=1".
+ Request https://bugs.freebsd.org/274472,
+ Rationale https://reviews.freebsd.org/D42380.
+
2023-08-01 Version 1.0
Utility:
diff --git a/LICENSE b/LICENSE
index d19ad87fca1f..7b36a8dce42e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
BSD 2-Clause License
-Copyright (c) 2021-2023, Alfonso Sabato Siciliano
+Copyright (c) 2021-2024, Alfonso Sabato Siciliano
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
diff --git a/Makefile b/Makefile
index 884cfa1b3e60..e6ec9988c59d 100644
--- a/Makefile
+++ b/Makefile
@@ -3,8 +3,8 @@
#
# Written in 2023 by Alfonso Sabato Siciliano
-OUTPUT = bsddialog
-export VERSION=1.0
+OUTPUT = bsddialog
+export VERSION=1.0.2
.CURDIR ?= ${CURDIR}
LIBPATH = ${.CURDIR}/lib
LIBBSDDIALOG = ${LIBPATH}/libbsddialog.so
@@ -13,14 +13,14 @@ UTILITYPATH = ${.CURDIR}/utility
RM= rm -f
LN = ln -s -f
-### cli options ###
-# port/pkg Makefile: 'MAKE_ARGS = -DNORPATH'
+### command-line options ###
+# FreeBSD port Makefile: 'MAKE_ARGS = -DNORPATH'
NORPATH ?=
export DISABLERPATH=${NORPATH}
-# `make -DDEBUG`
-# `gmake DEBUG=1`
+# Debug: `make -DDEBUG` or `gmake DEBUG=1`
DEBUG ?=
export ENABLEDEBUG=${DEBUG}
+###################
all : ${OUTPUT}
diff --git a/README.md b/README.md
index f4846ec07745..a902f7fada7a 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# BSDDialog 1.0
+# BSDDialog 1.0.2
This project provides **bsddialog** and **libbsddialog**, an utility
and a library to build scripts and tools with TUI dialogs and widgets.
@@ -114,18 +114,27 @@ in the _Public Domain_ to build new projects:
## TODO and Ideas
- - menubar feature
- - key callback
- - Right-To-Left text
+ - menubar feature.
+ - key callback.
+ - Right-To-Left text.
- some terminal does not hide the cursor, move it bottom-right before to getch.
- - refactor backtitle: multiline, conf.backtitle, WINDOW \*dialog.backtitle.
- - refactor bottomdesc: WINDOW \*dialog.bottomdesc -> fix expandig screen.
- - accessibility https://wiki.freebsd.org/Accessibility/Wishlist/Base
+ - refactor backtitle: add WINDOW \*dialog.backtitle for multiline and fix expanding screen.
+ - refactor bottomdesc: add WINDOW \*dialog.bottomdesc to fix expandig screen.
+ - accessibility https://wiki.freebsd.org/Accessibility/Wishlist/Base.
- add bool conf.menu.depthlines.
- implement custom getopt\_long().
- refactor/redesign gauge().
- improve grey lines expanding terminal (maybe redrawwin() in hide\_dialog()).
- more restrictive strtol() and strtoul().
- implement global buttons handler.
- - add/move external tutorial.
- - implement menutype.min_on.
+ - doc: external tutorial, theming guide.
+ - implement menutype.min\_on.
+ - improve refresh at startup, avoid dialog refresh before drawing text.
+ - add debug API: bsddialog\_debug(y,x,refresh,"fmt",...).
+ - add mouse support.
+ - use alarm(2) for bsddialog\_pause.
+ - delete form fieldlen constraint, hide or truncate long field in little screens.
+ - improve --inputbox autosizing, consider also input length.
+ - fix --form "" 0 0 0 Label 1 0 Init 1 12 0 0 (with 0 editable field).
+ - fix --mixedform "" 0 0 0 Label 1 0 Init 1 12 0 0 2 (with 0 editable field).
+ - add *text* customization to --hmsg *help-message*
diff --git a/examples_library/gauge.c b/examples_library/gauge.c
index 3b38a80f3f2c..8ed1a8f57664 100644
--- a/examples_library/gauge.c
+++ b/examples_library/gauge.c
@@ -50,7 +50,7 @@ int main()
conf.title = "gauge";
rv = bsddialog_gauge(&conf, "Example", 7, 30, 0, fd[0], "SEP", "EOF");
bsddialog_end();
- if(rv == BSDDIALOG_ERROR)
+ if (rv == BSDDIALOG_ERROR)
printf("Error: %s\n", bsddialog_geterror());
return (0);
diff --git a/examples_library/mixedgauge.c b/examples_library/mixedgauge.c
index 7666867902fb..e74bb3512a9a 100644
--- a/examples_library/mixedgauge.c
+++ b/examples_library/mixedgauge.c
@@ -69,7 +69,7 @@ int main()
minipercs[12] = i * 10;
retval= bsddialog_mixedgauge(&conf, "Example", 20, 40,
50 + i * 5, NMINIBAR, minilabels, minipercs);
- if(retval == BSDDIALOG_ERROR)
+ if (retval == BSDDIALOG_ERROR)
exit_error();
sleep(1);
}
diff --git a/lib/barbox.c b/lib/barbox.c
index cd9fee836f8a..4feea20c6441 100644
--- a/lib/barbox.c
+++ b/lib/barbox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,11 +36,11 @@
#include "bsddialog_theme.h"
#include "lib_util.h"
-#define BARPADDING 2 /* widget border | BARPADDING | box bar */
+#define BARPADDING 2 /* Dialog border | BARPADDING | box bar */
#define BOXBORDERS 2
#define MIN_WBAR 15
#define MIN_WBOX (BARPADDING + BOXBORDERS + MIN_WBAR + BARPADDING)
-#define MIN_WMGBAR 18
+#define MIN_WMGBAR 18 /* Mixedgauge main bar */
#define MIN_WMGBOX (BARPADDING + BOXBORDERS + MIN_WMGBAR + BARPADDING)
#define HBOX 3
#define WBOX(d) ((d)->w - BORDERS - BARPADDING - BARPADDING)
@@ -206,12 +206,64 @@ bsddialog_gauge(struct bsddialog_conf *conf, const char *text, int rows,
}
/* Mixedgauge */
+static void
+mvwaddcstr(WINDOW *win, int y, int x, const char *mbstring, unsigned int cols)
+{
+ size_t charlen, n, w;
+ mbstate_t mbs;
+ const char *pmbstring;
+ wchar_t wch;
+
+ w = n = 0;
+ pmbstring = mbstring;
+ memset(&mbs, 0, sizeof(mbs));
+ while ((charlen = mbrlen(pmbstring, MB_CUR_MAX, &mbs)) != 0 &&
+ charlen != (size_t)-1 && charlen != (size_t)-2) {
+ mbtowc(&wch, pmbstring, charlen);
+ w += (wch == L'\t') ? TABSIZE : wcwidth(wch);
+ if (w > cols)
+ break;
+ pmbstring += charlen;
+ n += charlen;
+ }
+ mvwaddnstr(win, y, x, mbstring, n);
+ if(w > cols)
+ mvwaddstr(win, y, (x + cols) - 3, "...");
+}
+
+static int
+mixedgauge_size_position(struct dialog *d, int nminibars,
+ const char **minilabels, int *htext)
+{
+ int i, max_minibarlen;
+
+ max_minibarlen = 0;
+ for (i = 0; i < (int)nminibars; i++)
+ max_minibarlen = MAX(max_minibarlen,
+ (int)strcols(CHECK_STR(minilabels[i])));
+ max_minibarlen += 18; /* ' '<max_minibarlen>' ['13'] ' */
+ max_minibarlen = MAX(max_minibarlen, MIN_WMGBOX); /* mainbar */
+
+ if (set_widget_size(d->conf, d->rows, d->cols, &d->h, &d->w) != 0)
+ return (BSDDIALOG_ERROR);
+ if (set_widget_autosize(d->conf, d->rows, d->cols, &d->h, &d->w,
+ d->text, htext, &d->bs, nminibars + HBOX, max_minibarlen) != 0)
+ return (BSDDIALOG_ERROR);
+ if (widget_checksize(d->h, d->w, &d->bs, nminibars + HBOX,
+ MIN_WMGBOX) != 0)
+ return (BSDDIALOG_ERROR);
+ if (set_widget_position(d->conf, &d->y, &d->x, d->h, d->w) != 0)
+ return (BSDDIALOG_ERROR);
+
+ return (0);
+}
+
static int
do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
unsigned int mainperc, unsigned int nminibars, const char **minilabels,
int *minipercs, bool color)
{
- int i, miniperc, max_minibarlen;
+ int i, miniperc;
int ystext, htext;
int minicolor, red, green;
struct bar b;
@@ -223,17 +275,9 @@ do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
red = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_RED, BSDDIALOG_BOLD);
green = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_GREEN,BSDDIALOG_BOLD);
- max_minibarlen = 0;
- for (i = 0; i < (int)nminibars; i++)
- max_minibarlen = MAX(max_minibarlen,
- (int)strcols(CHECK_STR(minilabels[i])));
- max_minibarlen += 3 + 16; /* seps + [...] */
- max_minibarlen = MAX(max_minibarlen, MIN_WMGBOX); /* mainbar */
-
if (prepare_dialog(conf, text, rows, cols, &d) != 0)
return (BSDDIALOG_ERROR);
- if (dialog_size_position(&d, nminibars + HBOX, max_minibarlen,
- &htext) != 0)
+ if (mixedgauge_size_position(&d, nminibars, minilabels, &htext) != 0)
return (BSDDIALOG_ERROR);
if (draw_dialog(&d) != 0)
return (BSDDIALOG_ERROR);
@@ -249,7 +293,7 @@ do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
/* label */
if (color && miniperc >= 0)
wattron(d.widget, A_BOLD);
- mvwaddstr(d.widget, i+1, 2, CHECK_STR(minilabels[i]));
+ mvwaddcstr(d.widget, i+1, 2, CHECK_STR(minilabels[i]), d.w-20);
if (color && miniperc >= 0)
wattroff(d.widget, A_BOLD);
/* perc */
@@ -472,10 +516,12 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
}
break;
case '\t': /* TAB */
+ case KEY_CTRL('n'):
case KEY_RIGHT:
d.bs.curr = (d.bs.curr + 1) % d.bs.nbuttons;
DRAW_BUTTONS(d);
break;
+ case KEY_CTRL('p'):
case KEY_LEFT:
d.bs.curr--;
if (d.bs.curr < 0)
@@ -502,15 +548,17 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
currvalue = max;
b.toupdate = true;
break;
+ case '-':
case KEY_UP:
- if (currvalue < max) {
- currvalue++;
+ if (currvalue > min) {
+ currvalue--;
b.toupdate = true;
}
break;
+ case '+':
case KEY_DOWN:
- if (currvalue > min) {
- currvalue--;
+ if (currvalue < max) {
+ currvalue++;
b.toupdate = true;
}
break;
@@ -523,6 +571,7 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
if (rangebox_redraw(&d, &b, &bigchange) != 0)
return (BSDDIALOG_ERROR);
break;
+ case KEY_CTRL('l'):
case KEY_RESIZE:
if (rangebox_redraw(&d, &b, &bigchange) != 0)
return (BSDDIALOG_ERROR);
@@ -641,6 +690,7 @@ bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
if (pause_redraw(&d, &b) != 0)
return (BSDDIALOG_ERROR);
break;
+ case KEY_CTRL('l'):
case KEY_RESIZE:
if (pause_redraw(&d, &b) != 0)
return (BSDDIALOG_ERROR);
diff --git a/lib/bsddialog.3 b/lib/bsddialog.3
index 38885bfe3ea4..cbf1653a2aca 100644
--- a/lib/bsddialog.3
+++ b/lib/bsddialog.3
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+.\" Copyright (c) 2021-2024 Alfonso Sabato Siciliano
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 28, 2023
+.Dd March 16, 2024
.Dt BSDDIALOG 3
.Os
.Sh NAME
@@ -719,9 +719,8 @@ the loop ends reading
builds a dialog without buttons and returns instantly.
.Pp
.Fn bsddialog_menu
-builds a dialog to select an item from a list via SPACE or ENTER.
-An item is
-defined like:
+builds a dialog to select an item from a list via SPACE and ENTER.
+An item is defined like:
.Pp
.Bd -literal -offset indent -compact
struct bsddialog_menuitem {
@@ -878,14 +877,13 @@ and
.Fa max .
.Fa value
is the default value on startup and the selected value at exit.
-The current value is printed inside a bar, the keys UP, DOWN, HOME, END, PAGEUP
-and PAGEDOWN can change it.
+The current value is printed inside a bar.
.Pp
.Fn bsddialog_textbox
opens and prints
.Fa file .
-UP, DOWN, LEFT, RIGHT, HOME, END, PAGEUP and PAGEDOWN keys are available to
-navigate the file, TAB changes button.
+TAB key changes button.
+Extra keys 0, h, l, k, j are available to navigate the text.
.Dq OK
button is renamed
.Dq EXIT .
@@ -901,7 +899,24 @@ are default values on startup, selected time at exit.
.Fn bsddialog_yesno
provides a dialog for a
.Dq Yes-No Question ,
-the labels on buttons are Yes and No.
+the labels on buttons are
+.Dq Yes
+and
+.Dq No .
+.Ss Keys
+.Bl -tag -width Ds
+.It Ctrl-l
+Redraw the dialog.
+.It F1
+Refer to
+.Fa conf.key.f1_file
+and
+.Fa conf.key.f1_message .
+.It SPACE
+Select menu item.
+.It UP DOWN LEFT RIGHT - + HOME END PAGEUP PAGEDOWN Ctrl-p Ctrl-n TAB
+Navigate elements and set value, depending on the dialog.
+.El
.Ss Theme
The graphical properties are global to the library.
They are represented by
@@ -1089,7 +1104,7 @@ case BSDDIALOG_YES:
printf("Yes\\n");
break;
case BSDDIALOG_NO
- printf("NO\\n");
+ printf("No\\n");
break;
case BSDDIALOG_ERROR:
printf("Error: %s\\n", bsddialog_geterror());
diff --git a/lib/bsddialog.h b/lib/bsddialog.h
index d997036b1f9f..08fb25b8701c 100644
--- a/lib/bsddialog.h
+++ b/lib/bsddialog.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
#include <stdbool.h>
-#define LIBBSDDIALOG_VERSION "1.0"
+#define LIBBSDDIALOG_VERSION "1.0.2"
/* Return values */
#define BSDDIALOG_ERROR -1
diff --git a/lib/datebox.c b/lib/datebox.c
index 9f26b2d08093..ee955471799e 100644
--- a/lib/datebox.c
+++ b/lib/datebox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2022-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2022-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -120,7 +120,7 @@ init_date(unsigned int *year, unsigned int *month, unsigned int *day, int *yy,
if (*mm == 0)
*mm = 1;
*dd = (*day == 0) ? 1 : *day;
- if(*dd > month_days(*yy, *mm))
+ if (*dd > month_days(*yy, *mm))
*dd = month_days(*yy, *mm);
}
@@ -237,10 +237,8 @@ drawsquare(struct bsddialog_conf *conf, WINDOW *win, enum elevation elev,
if (focus) {
l = 2 + w%2;
wattron(win, t.dialog.arrowcolor);
- mvwhline(win, 0, w/2 - l/2,
- conf->ascii_lines ? '^' : ACS_UARROW, l);
- mvwhline(win, h-1, w/2 - l/2,
- conf->ascii_lines ? 'v' : ACS_DARROW, l);
+ mvwhline(win, 0, w/2 - l/2, UARROW(conf), l);
+ mvwhline(win, h-1, w/2 - l/2, DARROW(conf), l);
wattroff(win, t.dialog.arrowcolor);
}
@@ -267,10 +265,10 @@ print_calendar(struct bsddialog_conf *conf, WINDOW *win, int yy, int mm, int dd,
draw_borders(conf, win, RAISED);
if (active) {
wattron(win, t.dialog.arrowcolor);
- mvwhline(win, 0, 15, conf->ascii_lines ? '^' : ACS_UARROW, 4);
- mvwhline(win, h-1, 15, conf->ascii_lines ? 'v' : ACS_DARROW, 4);
- mvwvline(win, 3, 0, conf->ascii_lines ? '<' : ACS_LARROW, 3);
- mvwvline(win, 3, w-1, conf->ascii_lines ? '>' : ACS_RARROW, 3);
+ mvwhline(win, 0, 15, UARROW(conf), 4);
+ mvwhline(win, h-1, 15, DARROW(conf), 4);
+ mvwvline(win, 3, 0, LARROW(conf), 3);
+ mvwvline(win, 3, w-1, RARROW(conf), 3);
wattroff(win, t.dialog.arrowcolor);
}
@@ -402,6 +400,7 @@ bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
}
DRAW_BUTTONS(d);
break;
+ case KEY_CTRL('n'):
case KEY_RIGHT:
if (focusbuttons) {
d.bs.curr++;
@@ -418,6 +417,7 @@ bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
}
DRAW_BUTTONS(d);
break;
+ case KEY_CTRL('p'):
case KEY_LEFT:
if (focusbuttons) {
d.bs.curr--;
@@ -463,6 +463,28 @@ bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
datectl(DOWN_DAY, &yy, &mm, &dd);
}
break;
+ case '-':
+ if (focusbuttons) {
+ break;
+ } else if (sel == 0) {
+ datectl(UP_MONTH, &yy, &mm, &dd);
+ } else if (sel == 1) {
+ datectl(UP_YEAR, &yy, &mm, &dd);
+ } else { /* sel = 2 */
+ datectl(LEFT_DAY, &yy, &mm, &dd);
+ }
+ break;
+ case '+':
+ if (focusbuttons) {
+ break;
+ } else if (sel == 0) {
+ datectl(DOWN_MONTH, &yy, &mm, &dd);
+ } else if (sel == 1) {
+ datectl(DOWN_YEAR, &yy, &mm, &dd);
+ } else { /* sel = 2 */
+ datectl(RIGHT_DAY, &yy, &mm, &dd);
+ }
+ break;
case KEY_HOME:
datectl(UP_MONTH, &yy, &mm, &dd);
break;
@@ -484,6 +506,7 @@ bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
if (calendar_redraw(&d, yy_win, mm_win, dd_win) != 0)
return (BSDDIALOG_ERROR);
break;
+ case KEY_CTRL('l'):
case KEY_RESIZE:
if (calendar_redraw(&d, yy_win, mm_win, dd_win) != 0)
return (BSDDIALOG_ERROR);
@@ -628,8 +651,9 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
loop = false;
}
break;
- case KEY_RIGHT:
case '\t': /* TAB */
+ case KEY_CTRL('n'):
+ case KEY_RIGHT:
if (focusbuttons) {
d.bs.curr++;
focusbuttons = d.bs.curr < (int)d.bs.nbuttons ?
@@ -648,6 +672,7 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
}
DRAW_BUTTONS(d);
break;
+ case KEY_CTRL('p'):
case KEY_LEFT:
if (focusbuttons) {
d.bs.curr--;
@@ -665,6 +690,10 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
}
DRAW_BUTTONS(d);
break;
+ case '-':
+ if (focusbuttons == false)
+ datectl(di[sel].up, &yy, &mm, &dd);
+ break;
case KEY_UP:
if (focusbuttons) {
sel = 0;
@@ -675,6 +704,7 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
datectl(di[sel].up, &yy, &mm, &dd);
}
break;
+ case '+':
case KEY_DOWN:
if (focusbuttons)
break;
@@ -689,6 +719,7 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
if (datebox_redraw(&d, di) != 0)
return (BSDDIALOG_ERROR);
break;
+ case KEY_CTRL('l'):
case KEY_RESIZE:
if (datebox_redraw(&d, di) != 0)
return (BSDDIALOG_ERROR);
diff --git a/lib/formbox.c b/lib/formbox.c
index 5e80471c6974..ca473356e350 100644
--- a/lib/formbox.c
+++ b/lib/formbox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -82,7 +82,7 @@ struct privateform {
unsigned int viewrows; /* visible rows, real formheight */
unsigned int minviewrows; /* min viewrows, ylabel != yfield */
wchar_t securewch; /* wide char of conf.form.secure[mb]ch */
- unsigned int nitems; /* like API nkitems */
+ unsigned int nitems; /* like API nitems */
struct privateitem *pritems;
int sel; /* selected item in pritem, can be -1 */
bool hasbottomdesc; /* some item has bottomdesc */
@@ -101,12 +101,12 @@ build_privateform(struct bsddialog_conf*conf, unsigned int nitems,
/* checks */
CHECK_ARRAY(nitems, items);
for (i = 0; i < nitems; i++) {
- if (items[i].maxvaluelen == 0)
- RETURN_FMTERROR("item %u [0-%u] maxvaluelen = 0",
- i, nitems);
if (items[i].fieldlen == 0)
RETURN_FMTERROR("item %u [0-%u] fieldlen = 0",
i, nitems);
+ if (items[i].maxvaluelen == 0)
+ RETURN_FMTERROR("item %u [0-%u] maxvaluelen = 0",
+ i, nitems);
}
f->nitems = nitems;
@@ -114,7 +114,7 @@ build_privateform(struct bsddialog_conf*conf, unsigned int nitems,
insecurecursor = false;
if (conf->form.securembch != NULL) {
mbchsize = mblen(conf->form.securembch, MB_LEN_MAX);
- if(mbtowc(&f->securewch, conf->form.securembch, mbchsize) < 0)
+ if (mbtowc(&f->securewch, conf->form.securembch, mbchsize) < 0)
RETURN_ERROR("Cannot convert securembch to wchar_t");
insecurecursor = true;
} else if (conf->form.securech != '\0') {
@@ -346,7 +346,7 @@ static char* alloc_wstomb(wchar_t *wstr)
wctomb(mbch, wstr[i]);
nbytes += mblen(mbch, MB_LEN_MAX);
}
- if((mbstr = malloc(nbytes)) == NULL)
+ if ((mbstr = malloc(nbytes)) == NULL)
return (NULL);
wcstombs(mbstr, wstr, nbytes);
@@ -379,7 +379,7 @@ static void set_first_with_default(struct privateform *f, int *focusitem)
unsigned int i;
f->sel = -1;
- if(focusitem != NULL && *focusitem >=0 && *focusitem < (int)f->nitems)
+ if (focusitem != NULL && *focusitem >=0 && *focusitem < (int)f->nitems)
if (f->pritems[*focusitem].readonly == false) {
f->sel = *focusitem;
return;
@@ -535,12 +535,10 @@ static void update_formbox(struct bsddialog_conf *conf, struct privateform *f)
if (f->viewrows < f->h) {
wattron(f->box, t.dialog.arrowcolor);
if (f->y > 0)
- mvwhline(f->box, 0, (w / 2) - 2,
- conf->ascii_lines ? '^' : ACS_UARROW, 5);
+ mvwhline(f->box, 0, (w / 2) - 2, UARROW(conf), 5);
if (f->y + f->viewrows < f->h)
- mvwhline(f->box, h-1, (w / 2) - 2,
- conf->ascii_lines ? 'v' : ACS_DARROW, 5);
+ mvwhline(f->box, h-1, (w / 2) - 2, DARROW(conf), 5);
wattroff(f->box, t.dialog.arrowcolor);
}
}
@@ -750,7 +748,7 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
break;
case KEY_LEFT:
if (focusinform) {
- if(fieldctl(item, MOVE_CURSOR_LEFT))
+ if (fieldctl(item, MOVE_CURSOR_LEFT))
DRAWITEM_TRICK(&form, form.sel, true);
} else if (d.bs.curr > 0) {
d.bs.curr--;
@@ -762,7 +760,7 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
break;
case KEY_RIGHT:
if (focusinform) {
- if(fieldctl(item, MOVE_CURSOR_RIGHT))
+ if (fieldctl(item, MOVE_CURSOR_RIGHT))
DRAWITEM_TRICK(&form, form.sel, true);
} else if (d.bs.curr < (int) d.bs.nbuttons - 1) {
d.bs.curr++;
@@ -772,6 +770,7 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
switchfocus = true;
}
break;
+ case KEY_CTRL('p'):
case KEY_UP:
if (focusinform) {
next = previtem(form.nitems, form.pritems,
@@ -781,6 +780,7 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
switchfocus = true;
}
break;
+ case KEY_CTRL('n'):
case KEY_DOWN:
if (focusinform == false)
break;
@@ -808,20 +808,20 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
case 127: /* Backspace */
if (focusinform == false)
break;
- if(fieldctl(item, MOVE_CURSOR_LEFT))
- if(fieldctl(item, DEL_LETTER))
+ if (fieldctl(item, MOVE_CURSOR_LEFT))
+ if (fieldctl(item, DEL_LETTER))
DRAWITEM_TRICK(&form, form.sel, true);
break;
case KEY_DC:
if (focusinform == false)
break;
- if(fieldctl(item, DEL_LETTER))
+ if (fieldctl(item, DEL_LETTER))
DRAWITEM_TRICK(&form, form.sel, true);
break;
case KEY_HOME:
if (focusinform == false)
break;
- if(fieldctl(item, MOVE_CURSOR_BEGIN))
+ if (fieldctl(item, MOVE_CURSOR_BEGIN))
DRAWITEM_TRICK(&form, form.sel, true);
break;
case KEY_END:
@@ -842,6 +842,7 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
if (form_redraw(&d, &form, focusinform) != 0)
return (BSDDIALOG_ERROR);
break;
+ case KEY_CTRL('l'):
case KEY_RESIZE:
if (form_redraw(&d, &form, focusinform) != 0)
return (BSDDIALOG_ERROR);
@@ -857,10 +858,10 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
* because the cursor remains on the new letter,
* "if" and "while" update the positions.
*/
- if(insertch(item, input, form.securewch)) {
+ if (insertch(item, input, form.securewch)) {
fieldctl(item, MOVE_CURSOR_RIGHT);
/*
- * no if(fieldctl), update always
+ * no if (fieldctl), update always
* because it fails with maxletters.
*/
DRAWITEM_TRICK(&form, form.sel, true);
@@ -897,7 +898,7 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
DRAWITEM_TRICK(&form, form.sel, true);
changeitem = false;
}
- } /* end while(loop) */
+ } /* end while (loop) */
curs_set(0);
diff --git a/lib/lib_util.c b/lib/lib_util.c
index 9cfdd6f1a075..d673a1a74d72 100644
--- a/lib/lib_util.c
+++ b/lib/lib_util.c
@@ -983,41 +983,43 @@ void draw_borders(struct bsddialog_conf *conf, WINDOW *win, enum elevation elev)
{
int h, w;
int leftcolor, rightcolor;
- int ls, rs, ts, bs, tl, tr, bl, br, ltee, rtee;
+ cchar_t *ls, *rs, *ts, *bs, *tl, *tr, *bl, *br;
+ cchar_t hline, vline, corner;
if (conf->no_lines)
return;
if (conf->ascii_lines) {
- ls = rs = '|';
- ts = bs = '-';
- tl = tr = bl = br = ltee = rtee = '+';
+ setcchar(&hline, L"|", 0, 0, NULL);
+ ls = rs = &hline;
+ setcchar(&vline, L"-", 0, 0, NULL);
+ ts = bs = &vline;
+ setcchar(&corner, L"+", 0, 0, NULL);
+ tl = tr = bl = br = &corner;
} else {
- ls = rs = ACS_VLINE;
- ts = bs = ACS_HLINE;
- tl = ACS_ULCORNER;
- tr = ACS_URCORNER;
- bl = ACS_LLCORNER;
- br = ACS_LRCORNER;
- ltee = ACS_LTEE;
- rtee = ACS_RTEE;
+ ls = rs = WACS_VLINE;
+ ts = bs = WACS_HLINE;
+ tl = WACS_ULCORNER;
+ tr = WACS_URCORNER;
+ bl = WACS_LLCORNER;
+ br = WACS_LRCORNER;
}
getmaxyx(win, h, w);
- leftcolor = elev == RAISED ?
+ leftcolor = (elev == RAISED) ?
t.dialog.lineraisecolor : t.dialog.linelowercolor;
- rightcolor = elev == RAISED ?
+ rightcolor = (elev == RAISED) ?
t.dialog.linelowercolor : t.dialog.lineraisecolor;
wattron(win, leftcolor);
- wborder(win, ls, rs, ts, bs, tl, tr, bl, br);
+ wborder_set(win, ls, rs, ts, bs, tl, tr, bl, br);
wattroff(win, leftcolor);
wattron(win, rightcolor);
- mvwaddch(win, 0, w-1, tr);
- mvwvline(win, 1, w-1, rs, h-2);
- mvwaddch(win, h-1, w-1, br);
- mvwhline(win, h-1, 1, bs, w-2);
+ mvwadd_wch(win, 0, w-1, tr);
+ mvwvline_set(win, 1, w-1, rs, h-2);
+ mvwadd_wch(win, h-1, w-1, br);
+ mvwhline_set(win, h-1, 1, bs, w-2);
wattroff(win, rightcolor);
}
@@ -1126,30 +1128,31 @@ static void
print_string(WINDOW *win, int *rows, int cols, int *y, int *x, wchar_t *str,
bool color)
{
- int i, j, len, reallen, wc;
+ int charwidth, i, j, strlen, strwidth;
wchar_t ws[2];
ws[1] = L'\0';
- len = wcslen(str);
+ strlen = wcslen(str);
if (color) {
- reallen = 0;
+ strwidth = 0;
i=0;
- while (i < len) {
+ while (i < strlen) {
if (is_wtext_attr(str+i) == false) {
- reallen += wcwidth(str[i]);
+ strwidth += wcwidth(str[i]);
i++;
} else {
- i +=3 ;
+ i += 3;
}
}
} else
- reallen = wcswidth(str, len);
+ strwidth = wcswidth(str, strlen);
i = 0;
- while (i < len) {
- if (*x + reallen > cols) {
- *y = (*x != 0 ? *y+1 : *y);
+ while (i < strlen) {
+ if (*x + strwidth > cols) {
+ if (*x != 0)
+ *y = *y + 1;
if (*y >= *rows) {
*rows = *y + 1;
wresize(win, *rows, cols);
@@ -1157,21 +1160,22 @@ print_string(WINDOW *win, int *rows, int cols, int *y, int *x, wchar_t *str,
*x = 0;
}
j = *x;
- while (j < cols && i < len) {
+ while (i < strlen) {
if (color && check_set_wtext_attr(win, str+i)) {
i += 3;
- } else if (j + wcwidth(str[i]) > cols) {
- break;
- } else {
- /* inline mvwaddwch() for efficiency */
- ws[0] = str[i];
- mvwaddwstr(win, *y, j, ws);
- wc = wcwidth(str[i]);;
- reallen -= wc;
- j += wc;
- i++;
- *x = j;
+ continue;
}
+
+ charwidth = wcwidth(str[i]);
+ if (j + wcwidth(str[i]) > cols)
+ break;
+ /* inline mvwaddwch() for efficiency */
+ ws[0] = str[i];
+ mvwaddwstr(win, *y, j, ws);
+ strwidth -= charwidth;
+ j += charwidth;
+ *x = j;
+ i++;
}
}
}
@@ -1248,11 +1252,18 @@ print_textpad(struct bsddialog_conf *conf, WINDOW *pad, const char *text)
int draw_dialog(struct dialog *d)
{
- int wtitle, wbottomtitle, ts, ltee, rtee;
+ int wtitle, wbottomtitle;
+ cchar_t ts, ltee, rtee;
- ts = d->conf->ascii_lines ? '-' : ACS_HLINE;
- ltee = d->conf->ascii_lines ? '+' : ACS_LTEE;
- rtee = d->conf->ascii_lines ? '+' : ACS_RTEE;
+ if (d->conf->ascii_lines) {
+ setcchar(&ts, L"-", 0, 0, NULL);
+ setcchar(&ltee, L"+", 0, 0,NULL);
+ setcchar(&rtee, L"+", 0, 0, NULL);
+ } else {
+ ts = *WACS_HLINE;
+ ltee = *WACS_LTEE;
+ rtee = *WACS_RTEE;
+ }
if (d->conf->shadow) {
wclear(d->shadow);
@@ -1271,7 +1282,7 @@ int draw_dialog(struct dialog *d)
return (BSDDIALOG_ERROR);
if (t.dialog.delimtitle && d->conf->no_lines == false) {
wattron(d->widget, t.dialog.lineraisecolor);
- mvwaddch(d->widget, 0, d->w/2 - wtitle/2 -1, rtee);
+ mvwadd_wch(d->widget, 0, d->w/2 - wtitle/2 -1, &rtee);
wattroff(d->widget, t.dialog.lineraisecolor);
}
wattron(d->widget, t.dialog.titlecolor);
@@ -1279,7 +1290,7 @@ int draw_dialog(struct dialog *d)
wattroff(d->widget, t.dialog.titlecolor);
if (t.dialog.delimtitle && d->conf->no_lines == false) {
wattron(d->widget, t.dialog.lineraisecolor);
- waddch(d->widget, ltee);
+ wadd_wch(d->widget, &ltee);
wattroff(d->widget, t.dialog.lineraisecolor);
}
}
@@ -1287,12 +1298,12 @@ int draw_dialog(struct dialog *d)
if (d->bs.nbuttons > 0) {
if (d->conf->no_lines == false) {
wattron(d->widget, t.dialog.lineraisecolor);
- mvwaddch(d->widget, d->h-3, 0, ltee);
- mvwhline(d->widget, d->h-3, 1, ts, d->w-2);
+ mvwadd_wch(d->widget, d->h-3, 0, &ltee);
+ mvwhline_set(d->widget, d->h-3, 1, &ts, d->w-2);
wattroff(d->widget, t.dialog.lineraisecolor);
wattron(d->widget, t.dialog.linelowercolor);
- mvwaddch(d->widget, d->h-3, d->w-1, rtee);
+ mvwadd_wch(d->widget, d->h-3, d->w-1, &rtee);
wattroff(d->widget, t.dialog.linelowercolor);
}
draw_buttons(d);
diff --git a/lib/lib_util.h b/lib/lib_util.h
index 1a502147c441..526f65b4bfaa 100644
--- a/lib/lib_util.h
+++ b/lib/lib_util.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -62,14 +62,19 @@ extern bool hastermcolors;
RETURN_ERROR("*" #p " is NULL"); \
} while (0)
#define CHECK_ARRAY(nitem, a) do { \
- if(nitem > 0 && a == NULL) \
+ if (nitem > 0 && a == NULL) \
RETURN_FMTERROR(#nitem " is %d but *" #a " is NULL", nitem); \
} while (0)
/* widget utils */
+#define KEY_CTRL(c) (c & 037)
#define TEXTPAD(d, downnotext) rtextpad(d, 0, 0, 0, downnotext)
#define SCREENLINES (getmaxy(stdscr))
#define SCREENCOLS (getmaxx(stdscr))
#define CHECK_STR(s) (s == NULL ? "" : s)
+#define UARROW(c) (c->ascii_lines ? '^' : ACS_UARROW)
+#define DARROW(c) (c->ascii_lines ? 'v' : ACS_DARROW)
+#define LARROW(c) (c->ascii_lines ? '<' : ACS_LARROW)
+#define RARROW(c) (c->ascii_lines ? '>' : ACS_RARROW)
#define DRAW_BUTTONS(d) do { \
draw_buttons(&d); \
wnoutrefresh(d.widget); \
diff --git a/lib/libbsddialog.c b/lib/libbsddialog.c
index 755a469b126c..555d060ebcbd 100644
--- a/lib/libbsddialog.c
+++ b/lib/libbsddialog.c
@@ -107,9 +107,12 @@ int bsddialog_backtitle(struct bsddialog_conf *conf, const char *backtitle)
move(0, 1);
clrtoeol();
addstr(CHECK_STR(backtitle));
- if (conf->no_lines != true)
- mvhline(1, 1, conf->ascii_lines ? '-' : ACS_HLINE,
- SCREENCOLS - 2);
+ if (conf->no_lines != true) {
+ if (conf->ascii_lines)
+ mvhline(1, 1, '-', SCREENCOLS - 2);
+ else
+ mvhline_set(1, 1, WACS_HLINE, SCREENCOLS - 2);
+ }
refresh();
diff --git a/lib/menubox.c b/lib/menubox.c
index b6213aa8f997..896306b2881d 100644
--- a/lib/menubox.c
+++ b/lib/menubox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -183,7 +183,7 @@ set_return_on(struct privatemenu *m, struct bsddialog_menugroup *groups)
int i;
struct privateitem *pritem;
- for(i = 0; i < m->nitems; i++) {
+ for (i = 0; i < m->nitems; i++) {
if (m->pritems[i].type == SEPARATORMODE)
continue;
pritem = &m->pritems[i];
@@ -298,7 +298,7 @@ getnextshortcut(int npritems, struct privateitem *pritems, int abs, wint_t key)
static void drawseparators(struct bsddialog_conf *conf, struct privatemenu *m)
{
- int i, linech, realw, labellen;
+ int i, realw, labellen;
const char *desc, *name;
for (i = 0; i < m->nitems; i++) {
@@ -306,8 +306,10 @@ static void drawseparators(struct bsddialog_conf *conf, struct privatemenu *m)
continue;
if (conf->no_lines == false) {
wattron(m->pad, t.menu.desccolor);
- linech = conf->ascii_lines ? '-' : ACS_HLINE;
- mvwhline(m->pad, i, 0, linech, m->line);
+ if (conf->ascii_lines)
+ mvwhline(m->pad, i, 0, '-', m->line);
+ else
+ mvwhline_set(m->pad, i, 0, WACS_HLINE, m->line);
wattroff(m->pad, t.menu.desccolor);
}
name = m->pritems[i].name;
@@ -404,12 +406,10 @@ static void update_menubox(struct bsddialog_conf *conf, struct privatemenu *m)
if (m->nitems > (int)m->menurows) {
wattron(m->box, t.dialog.arrowcolor);
if (m->ypad > 0)
- mvwhline(m->box, 0, 2,
- conf->ascii_lines ? '^' : ACS_UARROW, 3);
+ mvwhline(m->box, 0, 2, UARROW(conf), 3);
if ((m->ypad + (int)m->menurows) < m->nitems)
- mvwhline(m->box, h-1, 2,
- conf->ascii_lines ? 'v' : ACS_DARROW, 3);
+ mvwhline(m->box, h-1, 2, DARROW(conf), 3);
mvwprintw(m->box, h-1, w-6, "%3d%%",
100 * (m->ypad + m->menurows) / m->nitems);
@@ -578,6 +578,7 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
if (mixedlist_redraw(&d, &m) != 0)
return (BSDDIALOG_ERROR);
break;
+ case KEY_CTRL('l'):
case KEY_RESIZE:
if (mixedlist_redraw(&d, &m) != 0)
return (BSDDIALOG_ERROR);
@@ -591,6 +592,8 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
next = getnext(m.nitems, m.pritems, -1);
changeitem = next != m.sel;
break;
+ case '-':
+ case KEY_CTRL('p'):
case KEY_UP:
next = getprev(m.pritems, m.sel);
changeitem = next != m.sel;
@@ -603,6 +606,8 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
next = getprev(m.pritems, m.nitems);
changeitem = next != m.sel;
break;
+ case '+':
+ case KEY_CTRL('n'):
case KEY_DOWN:
next = getnext(m.nitems, m.pritems, m.sel);
changeitem = next != m.sel;
@@ -665,7 +670,7 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
pnoutrefresh(m.pad, m.ypad, 0, m.ys, m.xs, m.ye, m.xe);
changeitem = false;
}
- } /* end while(loop) */
+ } /* end while (loop) */
set_return_on(&m, groups);
diff --git a/lib/messagebox.c b/lib/messagebox.c
index fc18ff8a61d2..5132b1b089b8 100644
--- a/lib/messagebox.c
+++ b/lib/messagebox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -87,7 +87,7 @@ static int message_draw(struct dialog *d, struct scroll *s)
s->printrows = d->h - BORDER - HBUTTONS - BORDER;
s->ypad = 0;
getmaxyx(d->textpad, s->htextpad, unused);
- unused++; /* fix unused error */
+ (void)unused; /* fix unused error */
return (0);
}
@@ -106,7 +106,7 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
return (BSDDIALOG_ERROR);
set_buttons(&d, true, oklabel, cancellabel);
s.htext = -1;
- if(message_draw(&d, &s) != 0)
+ if (message_draw(&d, &s) != 0)
return (BSDDIALOG_ERROR);
loop = true;
@@ -138,10 +138,14 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
d.bs.curr = d.bs.nbuttons - 1;
DRAW_BUTTONS(d);
break;
+ case '-':
+ case KEY_CTRL('p'):
case KEY_UP:
if (s.ypad > 0)
s.ypad--;
break;
+ case '+':
+ case KEY_CTRL('n'):
case KEY_DOWN:
if (s.ypad + s.printrows < s.htextpad)
s.ypad++;
@@ -166,11 +170,12 @@ do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
break;
if (f1help_dialog(d.conf) != 0)
return (BSDDIALOG_ERROR);
- if(message_draw(&d, &s) != 0)
+ if (message_draw(&d, &s) != 0)
return (BSDDIALOG_ERROR);
break;
+ case KEY_CTRL('l'):
case KEY_RESIZE:
- if(message_draw(&d, &s) != 0)
+ if (message_draw(&d, &s) != 0)
return (BSDDIALOG_ERROR);
break;
default:
diff --git a/lib/textbox.c b/lib/textbox.c
index edd58d0a820e..597dc6c8187b 100644
--- a/lib/textbox.c
+++ b/lib/textbox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -47,32 +47,33 @@ struct scrolltext {
static void updateborders(struct dialog *d, struct scrolltext *st)
{
- chtype arrowch, borderch;
+ chtype arrowch;
+ cchar_t borderch;
if (d->conf->no_lines)
- borderch = ' ';
+ setcchar(&borderch, L" ", 0, 0, NULL);
else if (d->conf->ascii_lines)
- borderch = '|';
+ setcchar(&borderch, L"|", 0, 0, NULL);
else
- borderch = ACS_VLINE;
+ borderch = *WACS_VLINE;
if (st->xpad > 0) {
- arrowch = d->conf->ascii_lines ? '<' : ACS_LARROW;
- arrowch |= t.dialog.arrowcolor;
+ arrowch = LARROW(d->conf) | t.dialog.arrowcolor;
+ mvwvline(d->widget, (d->h / 2) - 2, 0, arrowch, 4);
} else {
- arrowch = borderch;
- arrowch |= t.dialog.lineraisecolor;
+ wattron(d->widget, t.dialog.lineraisecolor);
+ mvwvline_set(d->widget, (d->h / 2) - 2, 0, &borderch, 4);
+ wattroff(d->widget, t.dialog.lineraisecolor);
}
- mvwvline(d->widget, (d->h / 2) - 2, 0, arrowch, 4);
if (st->xpad + d->w - 2 - st->margin < st->wpad) {
- arrowch = d->conf->ascii_lines ? '>' : ACS_RARROW;
- arrowch |= t.dialog.arrowcolor;
+ arrowch = RARROW(d->conf) | t.dialog.arrowcolor;
+ mvwvline(d->widget, (d->h / 2) - 2, d->w - 1, arrowch, 4);
} else {
- arrowch = borderch;
- arrowch |= t.dialog.linelowercolor;
+ wattron(d->widget, t.dialog.linelowercolor);
+ mvwvline_set(d->widget, (d->h / 2) - 2, d->w - 1, &borderch, 4);
+ wattroff(d->widget, t.dialog.linelowercolor);
}
- mvwvline(d->widget, (d->h / 2) - 2, d->w - 1, arrowch, 4);
if (st->hpad > d->h - 4) {
wattron(d->widget, t.dialog.arrowcolor);
@@ -181,7 +182,7 @@ bsddialog_textbox(struct bsddialog_conf *conf, const char *file, int rows,
while (loop) {
updateborders(&d, &st);
/*
- * Overflow multicolumn charchter right border:
+ * Trick, overflow multicolumn charchter right border:
* wnoutrefresh(widget);
* pnoutrefresh(pad, ypad, xpad, ys, xs, ye, xe);
* doupdate();
@@ -256,6 +257,7 @@ bsddialog_textbox(struct bsddialog_conf *conf, const char *file, int rows,
if (textbox_draw(&d, &st) != 0)
return (BSDDIALOG_ERROR);
break;
+ case KEY_CTRL('l'):
case KEY_RESIZE:
if (textbox_draw(&d, &st) != 0)
return (BSDDIALOG_ERROR);
diff --git a/lib/timebox.c b/lib/timebox.c
index d683f9552b50..1421cd7d2b81 100644
--- a/lib/timebox.c
+++ b/lib/timebox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -48,8 +48,8 @@ drawsquare(struct bsddialog_conf *conf, WINDOW *win, unsigned int value,
draw_borders(conf, win, LOWERED);
if (focus) {
wattron(win, t.dialog.arrowcolor);
- mvwhline(win, 0, 1, conf->ascii_lines ? '^' : ACS_UARROW, 2);
- mvwhline(win, 2, 1, conf->ascii_lines ? 'v' : ACS_DARROW, 2);
+ mvwhline(win, 0, 1, UARROW(conf), 2);
+ mvwhline(win, 2, 1, DARROW(conf), 2);
wattroff(win, t.dialog.arrowcolor);
}
@@ -142,8 +142,9 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
loop = false;
}
break;
- case KEY_RIGHT:
case '\t': /* TAB */
+ case KEY_CTRL('n'):
+ case KEY_RIGHT:
if (focusbuttons) {
d.bs.curr++;
focusbuttons = d.bs.curr < (int)d.bs.nbuttons ?
@@ -162,6 +163,7 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
}
DRAW_BUTTONS(d);
break;
+ case KEY_CTRL('p'):
case KEY_LEFT:
if (focusbuttons) {
d.bs.curr--;
@@ -179,6 +181,11 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
}
DRAW_BUTTONS(d);
break;
+ case '-':
+ if (focusbuttons == false)
+ c[sel].value = c[sel].value > 0 ?
+ c[sel].value - 1 : c[sel].max;
+ break;
case KEY_UP:
if (focusbuttons) {
sel = 0;
@@ -190,6 +197,7 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
c[sel].value - 1 : c[sel].max;
}
break;
+ case '+':
case KEY_DOWN:
if (focusbuttons)
break;
@@ -205,6 +213,7 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
if (timebox_redraw(&d, c) != 0)
return (BSDDIALOG_ERROR);
break;
+ case KEY_CTRL('l'):
case KEY_RESIZE:
if (timebox_redraw(&d, c) != 0)
return (BSDDIALOG_ERROR);
diff --git a/utility/bsddialog.1 b/utility/bsddialog.1
index 653f91a3f122..fac17ef114b4 100644
--- a/utility/bsddialog.1
+++ b/utility/bsddialog.1
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+.\" Copyright (c) 2021-2024 Alfonso Sabato Siciliano
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 25, 2023
+.Dd April 7, 2024
.Dt BSDDIALOG 1
.Os
.Sh NAME
@@ -438,6 +438,21 @@ timeout.
.It Fl Fl title Ar title
Dialog title.
.El
+.Ss Keys
+The following keys are available at runtime:
+.Bl -tag -width Ds
+.It Ctrl-l
+Redraw the dialog.
+.It F1
+See
+.Fl Fl hfile
+and
+.Fl Fl hmsg .
+.It SPACE
+Select menu item.
+.It UP DOWN LEFT RIGHT - + HOME END PAGEUP PAGEDOWN Ctrl-p Ctrl-n TAB
+Navigate elements and set value, depending on the dialog.
+.El
.Ss Dialogs
The following dialogs are available:
.Bl -tag -width Ds
@@ -472,20 +487,21 @@ and
a field to get the input at the position
.Ar yfield
and
-.Ar xfield
-with graphical length
-.Ar fieldlen ,
-.Ar maxletters
-is the maximum input length.
-The field can be customized, if
+.Ar xfield .
.Ar fieldlen
-is negative the field is read only and its absolute value is the field length.
-If
+is the field width, if negative is readonly and the width is the absolute value,
+if
+.Dv 0
+the field becomes readonly and its value is the
+.Ar init
+width.
.Ar maxletters
-is 0 it is the absolute value of
+is the maximum input length, if is
+.Dv 0
+its value is
.Ar fieldlen .
.Ar init
-is a default value.
+is the default value in the field.
.Ar formrows
is the graphical height of the list,
.Dv 0
@@ -509,7 +525,7 @@ Dialog to get a string in input,
.Ar init
is the default value.
.It Fl Fl menu Ar text Ar rows Ar cols Ar menurows Oo Ar name desc Oc ...
-Builds a menu to select an item from a list, Space key is equivalent to Enter.
+Builds a menu to select an item from a list, SPACE key is equivalent to ENTER.
An item has a
.Ar name
and a
@@ -526,19 +542,33 @@ at the position
.Ar ylabel
and
.Ar xlabel ,
-a field to get the input with graphical length
-.Ar fieldlen
-at the position
+a field to get the input at the position
.Ar yfield
and
-.Ar xfield ,
+.Ar xfield .
+.Ar fieldlen
+is the field width, if negative is readonly and the width is the absolute value,
+if
+.Dv 0
+the field becomes readonly and its value is the
+.Ar init
+width.
.Ar maxletters
-is the maximum input length,
+is the maximum input length, if is
+.Dv 0
+its value is
+.Ar fieldlen .
.Ar init
-is a default value,
+is the default value in the field.
.Ar flag
-can be 0 for normal field, 1 to hide the typed characters and 2 to set the
-field read only.
+can customize
+.Ar field :
+.Dv 0
+normal,
+.Dv 1
+hide typed characters,
+.Dv 2
+readonly.
.Ar formrows
is the graphical height of the list,
.Dv 0
@@ -581,7 +611,6 @@ otherwise
Dialog to diplay a message without the
.Dq Cancel
button.
-UP, DOWN, HOME, END, PAGEUP and PAGEDOWN keys are availble to scroll the text.
.It Fl Fl passwordbox Ar text Ar rows Ar cols Op Ar init
Dialog to get a password,
.Ar init
@@ -617,13 +646,12 @@ Dialog to select a value between
and
.Ar max ,
.Ar init
-is the default value, the keys UP, DOWN, HOME, END, PAGEUP and PAGEDOWN can
-change it.
+is the default value.
.It Fl Fl textbox Ar file Ar rows Ar cols
Opens and prints
.Ar file .
-UP, DOWN, LEFT, RIGHT, HOME, END, PAGEUP and PAGEDOWN keys are available to
-navigate the file, TAB changes button.
+TAB changes button.
+Extra keys 0, h, l, k, j are available to navigate the text.
.Dq OK
button is renamed
.Dq EXIT .
@@ -644,7 +672,6 @@ buttons are renamed
.Dq Yes
and
.Dq \&No .
-UP, DOWN, HOME, END, PAGEUP and PAGEDOWN keys are availble to scroll the text.
.El
.Sh ENVIRONMENT
The following environment variables take effect only on startup, other options
@@ -872,6 +899,8 @@ Options:
.Fl Fl version ,
.Fl Fl yes-label .
.Pp
+Keys: Ctrl-l, F1.
+.Pp
Dialogs:
.Fl Fl calendar ,
.Fl Fl checklist ,
diff --git a/utility/bsddialog.c b/utility/bsddialog.c
index d4d1fc3e0f3a..3ba21eadf7a3 100644
--- a/utility/bsddialog.c
+++ b/utility/bsddialog.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -140,7 +140,7 @@ static void getenv_exitcodes(void)
value = (int)strtol(envvalue, NULL, 10);
exitcodes[i].value = value;
/* ITEM_HELP follows HELP without explicit setting */
- if(i == BSDDIALOG_HELP + 1)
+ if (i == BSDDIALOG_HELP + 1)
exitcodes[BSDDIALOG_ITEM_HELP + 1].value = value;
}
}
@@ -242,7 +242,7 @@ int main(int argc, char *argv[argc])
if (opt.dialogbuilder == NULL)
break;
if (opt.backtitle != NULL)
- if(bsddialog_backtitle(&conf, opt.backtitle))
+ if (bsddialog_backtitle(&conf, opt.backtitle))
exit_error(false, bsddialog_geterror());
retval = opt.dialogbuilder(&conf, text, rows, cols, argc, argv,
&opt);
diff --git a/utility/util_builders.c b/utility/util_builders.c
index 2dfa20cb0f86..8c846819f4ee 100644
--- a/utility/util_builders.c
+++ b/utility/util_builders.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,6 +30,7 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
+#include <wchar.h>
#include <bsddialog.h>
#include <bsddialog_theme.h>
@@ -532,6 +533,29 @@ int treeview_builder(BUILDER_ARGS)
}
/* form */
+static unsigned int strcols(const char *string)
+{
+ int w;
+ unsigned int ncol;
+ size_t charlen, mb_cur_max;
+ wchar_t wch;
+ mbstate_t mbs;
+
+ mb_cur_max = MB_CUR_MAX;
+ ncol = 0;
+ memset(&mbs, 0, sizeof(mbs));
+ while ((charlen = mbrlen(string, mb_cur_max, &mbs)) != 0 &&
+ charlen != (size_t)-1 && charlen != (size_t)-2) {
+ if (mbtowc(&wch, string, mb_cur_max) < 0)
+ return (0);
+ if ((w = wcwidth(wch)) > 0)
+ ncol += w;
+ string += charlen;
+ }
+
+ return (ncol);
+}
+
static void
print_form_items(int output, int nitems, struct bsddialog_formitem *items,
int focusitem, struct options *opt)
@@ -551,7 +575,7 @@ print_form_items(int output, int nitems, struct bsddialog_formitem *items,
helpname = items[focusitem].bottomdesc;
dprintf(opt->output_fd, " %s", helpname);
}
- if(opt->help_print_items == false)
+ if (opt->help_print_items == false)
return;
dprintf(opt->output_fd, "\n");
}
@@ -564,7 +588,7 @@ print_form_items(int output, int nitems, struct bsddialog_formitem *items,
int form_builder(BUILDER_ARGS)
{
- int output, fieldlen, valuelen, focusitem;
+ int output, fieldlen, focusitem;
unsigned int i, j, flags, formheight, nitems, sizeitem;
struct bsddialog_formitem *items;
@@ -591,12 +615,16 @@ int form_builder(BUILDER_ARGS)
items[i].xfield = (u_int)strtoul(argv[j++], NULL, 10);
fieldlen = (int)strtol(argv[j++], NULL, 10);
- items[i].fieldlen = abs(fieldlen);
+ if (fieldlen == 0)
+ items[i].fieldlen = strcols(items[i].init);
+ else
+ items[i].fieldlen = abs(fieldlen);
- valuelen = (int)strtol(argv[j++], NULL, 10);
- items[i].maxvaluelen = valuelen == 0 ? abs(fieldlen) : valuelen;
+ items[i].maxvaluelen = (u_int)strtoul(argv[j++], NULL, 10);
+ if (items[i].maxvaluelen == 0)
+ items[i].maxvaluelen = items[i].fieldlen;
- flags = (fieldlen < 0 ? BSDDIALOG_FIELDREADONLY : 0);
+ flags = (fieldlen <= 0) ? BSDDIALOG_FIELDREADONLY : 0;
items[i].flags = flags;
items[i].bottomdesc = opt->item_bottomdesc ? argv[j++] : "";
@@ -643,7 +671,7 @@ int inputbox_builder(BUILDER_ARGS)
int mixedform_builder(BUILDER_ARGS)
{
- int output, focusitem;
+ int output, fieldlen, focusitem;
unsigned int i, j, formheight, nitems, sizeitem;
struct bsddialog_formitem *items;
@@ -662,16 +690,26 @@ int mixedform_builder(BUILDER_ARGS)
exit_error(false, "cannot allocate memory for form items");
j = 0;
for (i = 0; i < nitems; i++) {
- items[i].label = argv[j++];
- items[i].ylabel = (u_int)strtoul(argv[j++], NULL, 10);
- items[i].xlabel = (u_int)strtoul(argv[j++], NULL, 10);
- items[i].init = argv[j++];
- items[i].yfield = (u_int)strtoul(argv[j++], NULL, 10);
- items[i].xfield = (u_int)strtoul(argv[j++], NULL, 10);
- items[i].fieldlen = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].label = argv[j++];
+ items[i].ylabel = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].xlabel = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].init = argv[j++];
+ items[i].yfield = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].xfield = (u_int)strtoul(argv[j++], NULL, 10);
+ fieldlen = (int)strtol(argv[j++], NULL, 10);
+ if (fieldlen == 0)
+ items[i].fieldlen = strcols(items[i].init);
+ else
+ items[i].fieldlen = abs(fieldlen);
items[i].maxvaluelen = (u_int)strtoul(argv[j++], NULL, 10);
- items[i].flags = (u_int)strtoul(argv[j++], NULL, 10);
- items[i].bottomdesc = opt->item_bottomdesc ? argv[j++] : "";
+ if (items[i].maxvaluelen == 0)
+ items[i].maxvaluelen = items[i].fieldlen;
+
+ items[i].flags = (u_int)strtoul(argv[j++], NULL, 10);
+ if (fieldlen <= 0)
+ items[i].flags |= BSDDIALOG_FIELDREADONLY;
+
+ items[i].bottomdesc = opt->item_bottomdesc ? argv[j++] : "";
}
focusitem = -1;
diff --git a/utility/util_theme.c b/utility/util_theme.c
index c313d743252b..a95cadacc1b0 100644
--- a/utility/util_theme.c
+++ b/utility/util_theme.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2022-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2022-2024 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -166,7 +166,7 @@ void savetheme(const char *file)
exit_error(false,
"cannot save theme: %s", bsddialog_geterror());
- if(time(&clock) < 0)
+ if (time(&clock) < 0)
exit_error(false, "cannot save profile getting current time");
if ((fp = fopen(file, "w")) == NULL)
exit_error(false, "cannot open %s to save profile", file);
@@ -235,11 +235,11 @@ void loadtheme(const char *file, bool compatibility)
exit_error(false, "Cannot get current theme: %s",
bsddialog_geterror());
- if((fp = fopen(file, "r")) == NULL)
+ if ((fp = fopen(file, "r")) == NULL)
exit_error(false, "Cannot open theme \"%s\" file", file);
- while(fgets(line, BUFSIZ, fp) != NULL) {
- if(line[0] == '#' || line[0] == '\n')
+ while (fgets(line, BUFSIZ, fp) != NULL) {
+ if (line[0] == '#' || line[0] == '\n')
continue; /* superfluous, only for efficiency */
sscanf(line, "%s", name);
value = NULL; /* useless init, fix compiler warning */
@@ -322,7 +322,7 @@ void loadtheme(const char *file, bool compatibility)
fclose(fp);
- if(bsddialog_set_theme(&t) != BSDDIALOG_OK)
+ if (bsddialog_set_theme(&t) != BSDDIALOG_OK)
exit_error(false, bsddialog_geterror());
}