git: 0595e10ec773 - releng/15.0 - contrib/bsddialog: Import version 1.0.5

From: Alfonso S. Siciliano <asiciliano_at_FreeBSD.org>
Date: Tue, 04 Nov 2025 18:31:38 UTC
The branch releng/15.0 has been updated by asiciliano:

URL: https://cgit.FreeBSD.org/src/commit/?id=0595e10ec77383a3038c45fbd9fcdb6922c971fe

commit 0595e10ec77383a3038c45fbd9fcdb6922c971fe
Author:     Alfonso S. Siciliano <asiciliano@FreeBSD.org>
AuthorDate: 2025-10-09 15:39:10 +0000
Commit:     Alfonso S. Siciliano <asiciliano@FreeBSD.org>
CommitDate: 2025-11-04 18:30:32 +0000

    contrib/bsddialog: Import version 1.0.5
    
    Version for change and feature requests.
    
    * Improve documentation for --alternate-screen and --normal-screen.
      Request: https://bugs.freebsd.org/285459. (This PR is not about
      bsddialog itself but is used as an example for an official FreeBSD
      documentation request.)
    
    * Reduce the number of screen refreshes to improve performance over a
      115200 UART connection.
      Request: https://gitlab.com/alfix/bsddialog/-/issues/8.
    
    * Change textbox buttons to return distinct values (previously always
      returned OK).
      Request: https://reviews.freebsd.org/D48668; already committed in
      contrib/ 96a241a35905078bdc5d20bf25943cdb67758dea
    
    * Change forms navigation key behavior for ENTER and TAB.
      Request: https://bugs.freebsd.org/287592.
    
    Refer to /usr/src/contrib/bsddialog/CHANGELOG to know more.
    
    PR:             287592
    Reported by:    adrian
    Approved by:    re (cperciva)
    Sponsored by:   The FreeBSD Foundation
    
    Merge commit '653f765f05b8c7e3908ae92e9bf61522a50cefc9' into YYY
    
    (cherry picked from commit 3e42d7194bdcd4fbfd781518258f919d6ac803d3)
    (cherry picked from commit aa2fe36f5e4b3b907af2ea94945ae9cab7263d0c)
---
 contrib/bsddialog/.gitignore                 |  1 +
 contrib/bsddialog/CHANGELOG                  | 50 ++++++++++++++++++++-
 contrib/bsddialog/LICENSE                    |  2 +-
 contrib/bsddialog/Makefile                   | 13 +++++-
 contrib/bsddialog/README.md                  |  5 +--
 contrib/bsddialog/examples_library/compile   |  8 ++--
 contrib/bsddialog/examples_library/textbox.c | 38 ++++++++++++++++
 contrib/bsddialog/lib/GNUmakefile            | 19 +++++++-
 contrib/bsddialog/lib/Makefile               | 21 ++++++++-
 contrib/bsddialog/lib/barbox.c               | 37 ++++++++--------
 contrib/bsddialog/lib/bsddialog.3            | 16 +++++--
 contrib/bsddialog/lib/bsddialog.h            |  5 ++-
 contrib/bsddialog/lib/bsddialog_theme.h      |  2 +-
 contrib/bsddialog/lib/datebox.c              | 28 ++++++------
 contrib/bsddialog/lib/formbox.c              | 48 ++++++++++++++------
 contrib/bsddialog/lib/lib_util.c             |  3 +-
 contrib/bsddialog/lib/lib_util.h             |  4 +-
 contrib/bsddialog/lib/libbsddialog.c         | 14 +++++-
 contrib/bsddialog/lib/menubox.c              | 18 ++++----
 contrib/bsddialog/lib/messagebox.c           | 16 +++----
 contrib/bsddialog/lib/textbox.c              | 16 +++----
 contrib/bsddialog/lib/theme.c                |  6 +--
 contrib/bsddialog/lib/timebox.c              | 16 +++----
 contrib/bsddialog/utility/GNUmakefile        | 11 ++++-
 contrib/bsddialog/utility/Makefile           | 11 ++++-
 contrib/bsddialog/utility/bsddialog.1        | 21 ++++++---
 contrib/bsddialog/utility/bsddialog.c        |  2 +-
 contrib/bsddialog/utility/util.h             |  2 +-
 contrib/bsddialog/utility/util_builders.c    | 66 ++++++++++++++--------------
 contrib/bsddialog/utility/util_cli.c         |  2 +-
 contrib/bsddialog/utility/util_theme.c       |  4 +-
 31 files changed, 353 insertions(+), 152 deletions(-)

diff --git a/contrib/bsddialog/.gitignore b/contrib/bsddialog/.gitignore
index c8fc68ed8a0e..c9613d477f7f 100644
--- a/contrib/bsddialog/.gitignore
+++ b/contrib/bsddialog/.gitignore
@@ -21,6 +21,7 @@ examples_library/msgbox
 examples_library/pause
 examples_library/radiolist
 examples_library/rangebox
+examples_library/textbox
 examples_library/theme
 examples_library/timebox
 examples_library/yesno
diff --git a/contrib/bsddialog/CHANGELOG b/contrib/bsddialog/CHANGELOG
index a4cf4d01c077..7800098644d7 100644
--- a/contrib/bsddialog/CHANGELOG
+++ b/contrib/bsddialog/CHANGELOG
@@ -1,11 +1,57 @@
-2024-07-01 1.0.4
+2025-06-22 Version 1.0.5
+
+	Manual:
+	* fix: "User-friendly documentation for alternate screen"
+	  https://bugs.freebsd.org/285459.
+	  Improve bsddialog.1: --alternate-screen and --normal-screen.
+
+	NetBSD (tested on amd64) refactoring, no function changes:
+	* https://gitlab.com/alfix/bsddialog/-/merge_requests/4
+	  lib: include <stdarg.h> in lib_util.c.
+	* https://gitlab.com/alfix/bsddialog/-/merge_requests/5
+	  a call to curses' refresh() is performed, while a local
+	  variable is also called refresh.
+	* Makefiles: add install and uninstall targets (both GND and BSD)
+	  https://gitlab.com/alfix/bsddialog/-/merge_requests/3
+
+	MacOS (tested on amd64) refactoring, no function changes:
+	* https://gitlab.com/alfix/bsddialog/-/merge_requests/6
+	  utility: replace u_int with unsigned int.
+
+	Library:
+	* fix: useless refreshes, https://gitlab.com/alfix/bsddialog/-/issues/8:
+	  "It takes lot of time when running over a 115200 UART".
+	  Not fixed for bsddialog_gauge() because it has to be rewritten.
+	* change: bsddialog_backtitle() does not update the screen so the
+	  backtitle is not printed. To use if a dialog is built later.
+	  Rationale: see "115200 UART" problem above.
+	* add: bsddialog_backtitle_rf() to print a top title refreshing the
+	  screen like bsddialog_backtitle() was previously.
+	* change: forms, ENTER is also a navigation keys in forms fields.
+	  Request: https://bugs.freebsd.org/287592
+	  If conf.button.always_active is true the form is closes immediatly.
+
+	Library and implicitly utility:
+	* fix: textbox buttons returned values (was always OK).
+	  Thanks to https://reviews.freebsd.org/D48668.
+	* change: TAB is a navigation keys in forms. Previously it directly
+	  switched form-fields <-> buttons.
+	  Request: https://bugs.freebsd.org/287592
+
+	Utility:
+	* change: forms, ENTER is a also navigation keys in forms fields.
+	  Previously it directly closed the form except with --switch-buttons
+	  Request: https://bugs.freebsd.org/287592
+
+
+2024-07-01 Version 1.0.4
 
 	Utility internal refactoring (no functional change):
 	* change: rename an internal constant to avoid a future conflict
 	    because FreeBSD is changing headers files for _FORTIFY_SOURCE.
 	    Reported and fixed by Kyle Evans.
 
-2024-05-27 1.0.3
+2024-05-27 Version 1.0.3
 
 	Utility:
 	change: --form and --mixedform do not print field value to output fd if
diff --git a/contrib/bsddialog/LICENSE b/contrib/bsddialog/LICENSE
index 7b36a8dce42e..9ea4a4a62f4b 100644
--- a/contrib/bsddialog/LICENSE
+++ b/contrib/bsddialog/LICENSE
@@ -1,6 +1,6 @@
 BSD 2-Clause License
 
-Copyright (c) 2021-2024, Alfonso Sabato Siciliano
+Copyright (c) 2021-2025, 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/contrib/bsddialog/Makefile b/contrib/bsddialog/Makefile
index a6af8813a48e..335b693470e6 100644
--- a/contrib/bsddialog/Makefile
+++ b/contrib/bsddialog/Makefile
@@ -4,7 +4,7 @@
 # Written in 2023 by Alfonso Sabato Siciliano
 
 OUTPUT = bsddialog
-export VERSION=1.0.4
+export VERSION=1.0.5
 .CURDIR ?= ${CURDIR}
 LIBPATH = ${.CURDIR}/lib
 LIBBSDDIALOG = ${LIBPATH}/libbsddialog.so
@@ -22,7 +22,15 @@ DEBUG ?=
 export ENABLEDEBUG=${DEBUG}
 ###################
 
-all : ${OUTPUT}
+all: ${OUTPUT}
+
+install: all
+	${MAKE} -C ${LIBPATH} install
+	${MAKE} -C ${UTILITYPATH} install
+
+uninstall:
+	${MAKE} -C ${UTILITYPATH} uninstall
+	${MAKE} -C ${LIBPATH} uninstall
 
 ${OUTPUT}: ${LIBBSDDIALOG}
 	${MAKE} -C ${UTILITYPATH} LIBPATH=${LIBPATH}
@@ -36,3 +44,4 @@ clean:
 	${MAKE} -C ${UTILITYPATH} clean
 	${RM} ${OUTPUT} *.core
 
+.PHONY: all install uninstall clean
diff --git a/contrib/bsddialog/README.md b/contrib/bsddialog/README.md
index 7b9b6cf8e84d..5a25109775fe 100644
--- a/contrib/bsddialog/README.md
+++ b/contrib/bsddialog/README.md
@@ -1,4 +1,4 @@
-# BSDDialog 1.0.4
+# BSDDialog 1.0.5
 
 This project provides **bsddialog** and **libbsddialog**, an utility
 and a library to build scripts and tools with TUI dialogs and widgets.
@@ -129,7 +129,6 @@ in the _Public Domain_ to build new projects:
  - implement global buttons handler.
  - 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.
@@ -139,4 +138,4 @@ in the _Public Domain_ to build new projects:
  - 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*
  - check --passwordform *fieldlen* like --form and --mixedform.
-
+ - add manuals to Makefiles installe and uninstall targets.
diff --git a/contrib/bsddialog/examples_library/compile b/contrib/bsddialog/examples_library/compile
index 9025f35426d9..1a68313090f6 100755
--- a/contrib/bsddialog/examples_library/compile
+++ b/contrib/bsddialog/examples_library/compile
@@ -8,14 +8,16 @@
 # worldwide. This software is distributed without any warranty, see:
 #     <http://creativecommons.org/publicdomain/zero/1.0/>.
 
+set -x
+
 libpath=../lib
 examples="menu checklist radiolist mixedlist theme infobox yesno msgbox \
-	datebox form timebox rangebox pause calendar gauge mixedgauge"
+datebox form timebox rangebox pause calendar gauge mixedgauge textbox"
 
 rm -f $examples
 
 for e in $examples
 do
-	cc -g -Wall -Wextra -I$libpath ${e}.c -o $e -L$libpath -lbsddialog \
-	-Wl,-rpath=$libpath
+	cc -g -Wall -Wextra -I$libpath ${e}.c -o $e \
+	-Wl,-rpath=$libpath -L$libpath -lbsddialog
 done
diff --git a/contrib/bsddialog/examples_library/textbox.c b/contrib/bsddialog/examples_library/textbox.c
new file mode 100644
index 000000000000..2e76cbb97891
--- /dev/null
+++ b/contrib/bsddialog/examples_library/textbox.c
@@ -0,0 +1,38 @@
+/*-
+ * SPDX-License-Identifier: CC0-1.0
+ *
+ * Written in 2025 by Alfonso Sabato Siciliano.
+ * To the extent possible under law, the author has dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty, see:
+ *   <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include <bsddialog.h>
+#include <stdio.h>
+
+int main()
+{
+	int output;
+	struct bsddialog_conf conf;
+
+	if (bsddialog_init() == BSDDIALOG_ERROR) {
+		printf("Error: %s\n", bsddialog_geterror());
+		return (1);
+	}
+	bsddialog_initconf(&conf);
+	conf.title = "textbox";
+	output = bsddialog_textbox(&conf, "./textbox.c", 20, 80);
+	bsddialog_end();
+
+	switch (output) {
+	case BSDDIALOG_ERROR:
+		printf("Error %s\n", bsddialog_geterror());
+		return (1);
+	case BSDDIALOG_OK:
+		printf("[Exit]\n");
+		break;
+	}
+
+	return (0);
+}
diff --git a/contrib/bsddialog/lib/GNUmakefile b/contrib/bsddialog/lib/GNUmakefile
index 7c7a9bc25ee4..2cb060381a46 100644
--- a/contrib/bsddialog/lib/GNUmakefile
+++ b/contrib/bsddialog/lib/GNUmakefile
@@ -9,6 +9,7 @@ HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h
 SOURCES = barbox.c datebox.c formbox.c libbsddialog.c lib_util.c \
 	menubox.c messagebox.c textbox.c theme.c timebox.c
 OBJECTS = $(SOURCES:.c=.o)
+PREFIX = /usr/local
 
 ifneq ($(ENABLEDEBUG),)
 CFLAGS += -g
@@ -21,7 +22,21 @@ LIBFLAG = -shared
 RM = rm -f
 LN = ln -s -f
 
-all : $(LIBRARY)
+all: $(LIBRARY)
+
+install: all
+	${INSTALL} -m 0644 bsddialog.h ${DESTDIR}${PREFIX}/include/bsddialog.h
+	${INSTALL} -m 0644 bsddialog_progressview.h ${DESTDIR}${PREFIX}/include/bsddialog_progressview.h
+	${INSTALL} -m 0644 bsddialog_theme.h ${DESTDIR}${PREFIX}/include/bsddialog_theme.h
+	${INSTALL} -m 0755 ${LIBRARY_SO}.${VERSION} ${DESTDIR}${PREFIX}/lib/${LIBRARY_SO}.${VERSION}
+	${LN} ${LIBRARY_SO}.${VERSION} ${DESTDIR}${PREFIX}/lib/${LIBRARY_SO}
+
+uninstall:
+	${RM} ${DESTDIR}${PREFIX}/include/bsddialog.h
+	${RM} ${DESTDIR}${PREFIX}/include/bsddialog_progressview.h
+	${RM} ${DESTDIR}${PREFIX}/include/bsddialog_theme.h
+	${RM} ${DESTDIR}${PREFIX}/lib/${LIBRARY_SO}.${VERSION}
+	${RM} ${DESTDIR}${PREFIX}/lib/${LIBRARY_SO}
 
 $(LIBRARY): $(OBJECTS)
 	$(CC) $(LIBFLAG) $^ -o $(LIBRARY_SO).$(VERSION) $(LDFLAGS)
@@ -32,3 +47,5 @@ $(LIBRARY): $(OBJECTS)
 
 clean:
 	$(RM) $(LIBRARY_SO)* *.o *~
+
+.PHONY: all install uninstall ${LIBRARY} clean
diff --git a/contrib/bsddialog/lib/Makefile b/contrib/bsddialog/lib/Makefile
index 252b33f79848..c728541a9f7a 100644
--- a/contrib/bsddialog/lib/Makefile
+++ b/contrib/bsddialog/lib/Makefile
@@ -10,6 +10,7 @@ HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h
 SOURCES = barbox.c datebox.c formbox.c libbsddialog.c lib_util.c \
 	menubox.c messagebox.c textbox.c theme.c timebox.c
 OBJECTS = ${SOURCES:.c=.o}
+PREFIX = /usr/local
 
 .if defined(DEBUG)
 CFLAGS += -g
@@ -23,7 +24,23 @@ LDFLAGS += -fstack-protector-strong -shared -Wl,-x -Wl,--fatal-warnings \
 LN = ln -s -f
 RM = rm -f
 
-all : ${LIBRARY}
+all: ${LIBRARY}
+
+install: all
+	${INSTALL} -m 0644 bsddialog.h ${DESTDIR}${PREFIX}/include/bsddialog.h
+	${INSTALL} -m 0644 bsddialog_progressview.h ${DESTDIR}${PREFIX}/include/bsddialog_progressview.h
+	${INSTALL} -m 0644 bsddialog_theme.h ${DESTDIR}${PREFIX}/include/bsddialog_theme.h
+	${INSTALL} -m 0644 ${LIBRARY_A} ${DESTDIR}${PREFIX}/lib/${LIBRARY_A}
+	${INSTALL} -m 0755 ${LIBRARY_SO}.${VERSION} ${DESTDIR}${PREFIX}/lib/${LIBRARY_SO}.${VERSION}
+	${LN} ${LIBRARY_SO}.${VERSION} ${DESTDIR}${PREFIX}/lib/${LIBRARY_SO}
+
+uninstall:
+	${RM} ${DESTDIR}${PREFIX}/include/bsddialog.h
+	${RM} ${DESTDIR}${PREFIX}/include/bsddialog_progressview.h
+	${RM} ${DESTDIR}${PREFIX}/include/bsddialog_theme.h
+	${RM} ${DESTDIR}${PREFIX}/lib/${LIBRARY_A}
+	${RM} ${DESTDIR}${PREFIX}/lib/${LIBRARY_SO}.${VERSION}
+	${RM} ${DESTDIR}${PREFIX}/lib/${LIBRARY_SO}
 
 ${LIBRARY}: ${LIBRARY_SO} ${LIBRARY_A}
 
@@ -42,3 +59,5 @@ ${LIBRARY_A}: ${OBJECTS}
 
 clean:
 	${RM} ${LIBRARY_SO}* *.o *~ *.gz ${LIBRARY_A}
+
+.PHONY: all install uninstall ${LIBRARY} clean
diff --git a/contrib/bsddialog/lib/barbox.c b/contrib/bsddialog/lib/barbox.c
index 4feea20c6441..51f81ecbca68 100644
--- a/contrib/bsddialog/lib/barbox.c
+++ b/contrib/bsddialog/lib/barbox.c
@@ -1,7 +1,7 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
- * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2025 Alfonso Sabato Siciliano
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -371,7 +371,7 @@ bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
 	unsigned int i, mainperc, totaltodo;
 	float readforsec;
 	const char **minilabels;
-	time_t tstart, told, tnew, refresh;
+	time_t tstart, told, tnew, trefresh;
 
 	if ((minilabels = calloc(nminibar, sizeof(char*))) == NULL)
 		RETURN_ERROR("Cannot allocate memory for minilabels");
@@ -385,7 +385,7 @@ bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
 		minipercs[i] = minibar[i].status;
 	}
 
-	refresh = pvconf->refresh == 0 ? 0 : pvconf->refresh - 1;
+	trefresh = pvconf->refresh == 0 ? 0 : pvconf->refresh - 1;
 	retval = BSDDIALOG_OK;
 	i = 0;
 	update = true;
@@ -398,7 +398,7 @@ bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
 			mainperc = (bsddialog_total_progview * 100) / totaltodo;
 
 		time(&tnew);
-		if (update || tnew > told + refresh) {
+		if (update || tnew > told + trefresh) {
 			retval = do_mixedgauge(conf, text, rows, cols, mainperc,
 			    nminibar, minilabels, minipercs, true);
 			if (retval == BSDDIALOG_ERROR)
@@ -440,17 +440,18 @@ bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
 	return (retval);
 }
 
-static int rangebox_redraw(struct dialog *d, struct bar *b, int *bigchange)
+static int
+rangebox_redraw(struct dialog *d, bool redraw, struct bar *b, int *bigchange)
 {
-	if (d->built) {
+	if (redraw) {
 		hide_dialog(d);
 		refresh(); /* Important for decreasing screen */
 	}
 	if (dialog_size_position(d, HBOX, MIN_WBOX, NULL) != 0)
 		return (BSDDIALOG_ERROR);
-	if (draw_dialog(d) != 0)
+	if (draw_dialog(d) != 0) /* doupdate() in main loop */
 		return (BSDDIALOG_ERROR);
-	if (d->built)
+	if (redraw)
 		refresh(); /* Important to fix grey lines expanding screen */
 	TEXTPAD(d, HBOX + HBUTTONS);
 
@@ -490,7 +491,7 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
 		RETURN_ERROR("Cannot build WINDOW bar");
 	b.y = b.x = 1;
 	b.fmt = "%d";
-	if (rangebox_redraw(&d, &b, &bigchange) != 0)
+	if (rangebox_redraw(&d, false, &b, &bigchange) != 0)
 		return (BSDDIALOG_ERROR);
 
 	loop = true;
@@ -568,12 +569,12 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
 				break;
 			if (f1help_dialog(conf) != 0)
 				return (BSDDIALOG_ERROR);
-			if (rangebox_redraw(&d, &b, &bigchange) != 0)
+			if (rangebox_redraw(&d, true, &b, &bigchange) != 0)
 				return (BSDDIALOG_ERROR);
 			break;
 		case KEY_CTRL('l'):
 		case KEY_RESIZE:
-			if (rangebox_redraw(&d, &b, &bigchange) != 0)
+			if (rangebox_redraw(&d, true, &b, &bigchange) != 0)
 				return (BSDDIALOG_ERROR);
 			break;
 		default:
@@ -594,17 +595,17 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
 	return (retval);
 }
 
-static int pause_redraw(struct dialog *d, struct bar *b)
+static int pause_redraw(struct dialog *d, bool redraw, struct bar *b)
 {
-	if (d->built) {
+	if (redraw) {
 		hide_dialog(d);
 		refresh(); /* Important for decreasing screen */
 	}
 	if (dialog_size_position(d, HBOX, MIN_WBOX, NULL) != 0)
 		return (BSDDIALOG_ERROR);
-	if (draw_dialog(d) != 0)
+	if (draw_dialog(d) != 0) /* doupdate() in main loop */
 		return (BSDDIALOG_ERROR);
-	if (d->built)
+	if (redraw)
 		refresh(); /* Important to fix grey lines expanding screen */
 	TEXTPAD(d, HBOX + HBUTTONS);
 
@@ -633,7 +634,7 @@ bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
 		RETURN_ERROR("Cannot build WINDOW bar");
 	b.y = b.x = 1;
 	b.fmt = "%d";
-	if (pause_redraw(&d, &b) != 0)
+	if (pause_redraw(&d, false, &b) != 0)
 		return (BSDDIALOG_ERROR);
 
 	tout = *seconds;
@@ -687,12 +688,12 @@ bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
 				break;
 			if (f1help_dialog(conf) != 0)
 				return (BSDDIALOG_ERROR);
-			if (pause_redraw(&d, &b) != 0)
+			if (pause_redraw(&d, true, &b) != 0)
 				return (BSDDIALOG_ERROR);
 			break;
 		case KEY_CTRL('l'):
 		case KEY_RESIZE:
-			if (pause_redraw(&d, &b) != 0)
+			if (pause_redraw(&d, true, &b) != 0)
 				return (BSDDIALOG_ERROR);
 			break;
 		default:
diff --git a/contrib/bsddialog/lib/bsddialog.3 b/contrib/bsddialog/lib/bsddialog.3
index cbf1653a2aca..bbd756661a78 100644
--- a/contrib/bsddialog/lib/bsddialog.3
+++ b/contrib/bsddialog/lib/bsddialog.3
@@ -1,5 +1,5 @@
 .\"
-.\" Copyright (c) 2021-2024 Alfonso Sabato Siciliano
+.\" Copyright (c) 2021-2025 Alfonso Sabato Siciliano
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -22,11 +22,12 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd March 16, 2024
+.Dd June 22, 2025
 .Dt BSDDIALOG 3
 .Os
 .Sh NAME
 .Nm bsddialog_backtitle ,
+.Nm bsddialog_backtitle_rf ,
 .Nm bsddialog_calendar ,
 .Nm bsddialog_clear ,
 .Nm bsddialog_color ,
@@ -65,6 +66,8 @@
 .Ft int
 .Fn bsddialog_backtitle "struct bsddialog_conf *conf" "const char *backtitle"
 .Ft int
+.Fn bsddialog_backtitle_rf "struct bsddialog_conf *conf" "const char *backtitle"
+.Ft int
 .Fo bsddialog_calendar
 .Fa "struct bsddialog_conf *conf"
 .Fa "const char *text"
@@ -292,7 +295,7 @@ and before
 .Dv false
 otherwise.
 .Pp
-.Fn bsddialog_backtitle
+.Fn bsddialog_backtitle_rf
 prints
 .Fa backtitle
 on the top of the screen.
@@ -302,6 +305,11 @@ and
 .Fa conf.no_lines
 described later.
 .Pp
+.Fn bsddialog_backtitle
+is like
+.Fn bsddialog_backtitle_rf
+but it does not update the screen, using if a dialog is built later.
+.Pp
 .Fn bsddialog_error
 returns a string to describe the last error.
 The function should be called after a
@@ -902,7 +910,7 @@ provides a dialog for a
 the labels on buttons are
 .Dq Yes
 and
-.Dq No .
+.Dq &No .
 .Ss Keys
 .Bl -tag -width Ds
 .It Ctrl-l
diff --git a/contrib/bsddialog/lib/bsddialog.h b/contrib/bsddialog/lib/bsddialog.h
index fd0e2bc02580..fc59071c6fa0 100644
--- a/contrib/bsddialog/lib/bsddialog.h
+++ b/contrib/bsddialog/lib/bsddialog.h
@@ -1,7 +1,7 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
- * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2025 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.4"
+#define LIBBSDDIALOG_VERSION     "1.0.5"
 
 /* Return values */
 #define BSDDIALOG_ERROR          -1
@@ -179,6 +179,7 @@ int bsddialog_init_notheme(void);
 bool bsddialog_inmode(void);
 int bsddialog_end(void);
 int bsddialog_backtitle(struct bsddialog_conf *conf, const char *backtitle);
+int bsddialog_backtitle_rf(struct bsddialog_conf *conf, const char *backtitle);
 int bsddialog_initconf(struct bsddialog_conf *conf);
 void bsddialog_clear(unsigned int y);
 void bsddialog_refresh(void);
diff --git a/contrib/bsddialog/lib/bsddialog_theme.h b/contrib/bsddialog/lib/bsddialog_theme.h
index 2071896b61f0..77938c65b6ce 100644
--- a/contrib/bsddialog/lib/bsddialog_theme.h
+++ b/contrib/bsddialog/lib/bsddialog_theme.h
@@ -1,7 +1,7 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
- * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2025 Alfonso Sabato Siciliano
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/contrib/bsddialog/lib/datebox.c b/contrib/bsddialog/lib/datebox.c
index ee955471799e..66f36f5f4a99 100644
--- a/contrib/bsddialog/lib/datebox.c
+++ b/contrib/bsddialog/lib/datebox.c
@@ -1,7 +1,7 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
- * Copyright (c) 2022-2024 Alfonso Sabato Siciliano
+ * Copyright (c) 2022-2025 Alfonso Sabato Siciliano
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -296,20 +296,20 @@ print_calendar(struct bsddialog_conf *conf, WINDOW *win, int yy, int mm, int dd,
 }
 
 static int
-calendar_redraw(struct dialog *d, WINDOW *yy_win, WINDOW *mm_win,
+calendar_draw(struct dialog *d, bool redraw, WINDOW *yy_win, WINDOW *mm_win,
     WINDOW *dd_win)
 {
 	int ycal, xcal;
 
-	if (d->built) {
+	if (redraw) {
 		hide_dialog(d);
 		refresh(); /* Important for decreasing screen */
 	}
 	if (dialog_size_position(d, MINHCAL, MINWCAL, NULL) != 0)
 		return (BSDDIALOG_ERROR);
-	if (draw_dialog(d) != 0)
+	if (draw_dialog(d) != 0) /* doupdate in main loop */
 		return (BSDDIALOG_ERROR);
-	if (d->built)
+	if (redraw)
 		refresh(); /* Important to fix grey lines expanding screen */
 	TEXTPAD(d, MINHCAL + HBUTTONS);
 
@@ -354,7 +354,7 @@ bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
 	if ((dd_win = newwin(1, 1, 1, 1)) == NULL)
 		RETURN_ERROR("Cannot build WINDOW for dd");
 	wbkgd(dd_win, t.dialog.color);
-	if (calendar_redraw(&d, yy_win, mm_win, dd_win) != 0)
+	if (calendar_draw(&d, false, yy_win, mm_win, dd_win) != 0)
 		return (BSDDIALOG_ERROR);
 
 	sel = -1;
@@ -503,12 +503,12 @@ bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
 				break;
 			if (f1help_dialog(conf) != 0)
 				return (BSDDIALOG_ERROR);
-			if (calendar_redraw(&d, yy_win, mm_win, dd_win) != 0)
+			if (calendar_draw(&d, true, 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)
+			if (calendar_draw(&d, true, yy_win, mm_win, dd_win) != 0)
 				return (BSDDIALOG_ERROR);
 			break;
 		default:
@@ -533,11 +533,11 @@ bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows,
 	return (retval);
 }
 
-static int datebox_redraw(struct dialog *d, struct dateitem *di)
+static int datebox_draw(struct dialog *d, bool redraw, struct dateitem *di)
 {
 	int y, x;
 
-	if (d->built) {
+	if (redraw) {
 		hide_dialog(d);
 		refresh(); /* Important for decreasing screen */
 	}
@@ -545,7 +545,7 @@ static int datebox_redraw(struct dialog *d, struct dateitem *di)
 		return (BSDDIALOG_ERROR);
 	if (draw_dialog(d) != 0)
 		return (BSDDIALOG_ERROR);
-	if (d->built)
+	if (redraw)
 		refresh(); /* Important to fix grey lines expanding screen */
 	TEXTPAD(d, 3 /*windows*/ + HBUTTONS);
 
@@ -624,7 +624,7 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
 	set_buttons(&d, true, OK_LABEL, CANCEL_LABEL);
 	if (build_dateitem(conf->date.format, &yy, &mm, &dd, di) != 0)
 		return (BSDDIALOG_ERROR);
-	if (datebox_redraw(&d, di) != 0)
+	if (datebox_draw(&d, false, di) != 0)
 		return (BSDDIALOG_ERROR);
 
 	sel = -1;
@@ -716,12 +716,12 @@ bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
 				break;
 			if (f1help_dialog(conf) != 0)
 				return (BSDDIALOG_ERROR);
-			if (datebox_redraw(&d, di) != 0)
+			if (datebox_draw(&d, true, di) != 0)
 				return (BSDDIALOG_ERROR);
 			break;
 		case KEY_CTRL('l'):
 		case KEY_RESIZE:
-			if (datebox_redraw(&d, di) != 0)
+			if (datebox_draw(&d, true, di) != 0)
 				return (BSDDIALOG_ERROR);
 			break;
 		default:
diff --git a/contrib/bsddialog/lib/formbox.c b/contrib/bsddialog/lib/formbox.c
index ca473356e350..a072461c43e1 100644
--- a/contrib/bsddialog/lib/formbox.c
+++ b/contrib/bsddialog/lib/formbox.c
@@ -1,7 +1,7 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
- * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2025 Alfonso Sabato Siciliano
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -601,11 +601,11 @@ static int form_size_position(struct dialog *d, struct privateform *f)
 }
 
 static int
-form_redraw(struct dialog *d, struct privateform *f, bool focusinform)
+form_draw(struct dialog *d, bool redraw, struct privateform *f, bool focusinform)
 {
 	unsigned int i;
 
-	if (d->built) {
+	if (redraw) {
 		hide_dialog(d);
 		refresh(); /* Important for decreasing screen */
 	}
@@ -613,9 +613,9 @@ form_redraw(struct dialog *d, struct privateform *f, bool focusinform)
 	f->w = f->wmin;
 	if (form_size_position(d, f) != 0)
 		return (BSDDIALOG_ERROR);
-	if (draw_dialog(d) != 0)
+	if (draw_dialog(d) != 0) /* doupdate() in main loop */
 		return (BSDDIALOG_ERROR);
-	if (d->built)
+	if (redraw)
 		refresh(); /* Important to fix grey lines expanding screen */
 	TEXTPAD(d, 2 /* box borders */ + f->viewrows + HBUTTONS);
 
@@ -707,7 +707,7 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
 	}
 
 	form.formheight = formheight;
-	if (form_redraw(&d, &form, focusinform) != 0)
+	if (form_draw(&d, false, &form, focusinform) != 0)
 		return (BSDDIALOG_ERROR);
 
 	changeitem = switchfocus = false;
@@ -719,10 +719,16 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
 		switch(input) {
 		case KEY_ENTER:
 		case 10: /* Enter */
-			if (focusinform && conf->button.always_active == false)
-				break;
-			retval = BUTTONVALUE(d.bs);
-			loop = false;
+			if (focusinform && conf->button.always_active == false) {
+				next = nextitem(form.nitems, form.pritems, form.sel);
+				if (next > form.sel)
+					changeitem = true; /* needs next */
+				else
+					switchfocus = true;
+			} else {
+				retval = BUTTONVALUE(d.bs);
+				loop = false;
+			}
 			break;
 		case 27: /* Esc */
 			if (conf->key.enable_esc) {
@@ -732,7 +738,12 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
 			break;
 		case '\t': /* TAB */
 			if (focusinform) {
-				switchfocus = true;
+				next = nextitem(form.nitems, form.pritems,
+				    form.sel);
+				if (next > form.sel)
+					changeitem = true;  /* needs next */
+				else
+					switchfocus = true;
 			} else {
 				if (d.bs.curr + 1 < (int)d.bs.nbuttons) {
 					d.bs.curr++;
@@ -839,12 +850,12 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
 				retval = BSDDIALOG_ERROR;
 				loop = false;
 			}
-			if (form_redraw(&d, &form, focusinform) != 0)
+			if (form_draw(&d, true, &form, focusinform) != 0)
 				return (BSDDIALOG_ERROR);
 			break;
 		case KEY_CTRL('l'):
 		case KEY_RESIZE:
-			if (form_redraw(&d, &form, focusinform) != 0)
+			if (form_draw(&d, true, &form, focusinform) != 0)
 				return (BSDDIALOG_ERROR);
 			break;
 		default:
@@ -884,11 +895,20 @@ bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
 			    conf->button.always_active || !focusinform,
 			    !focusinform);
 			wnoutrefresh(d.widget);
-			DRAWITEM_TRICK(&form, form.sel, focusinform);
+			if (focusinform == false)
+				DRAWITEM_TRICK(&form, form.sel, false);
+			else {
+				next = firstitem(form.nitems, form.pritems);
+				if (next == form.sel)
+					DRAWITEM_TRICK(&form, form.sel, true);
+				else
+					changeitem = true;
+			}
 			switchfocus = false;
 		}
 
 		if (changeitem) {
+			/* useless after if(switchfocus) */
 			DRAWITEM_TRICK(&form, form.sel, false);
 			form.sel = next;
 			item = &form.pritems[form.sel];
diff --git a/contrib/bsddialog/lib/lib_util.c b/contrib/bsddialog/lib/lib_util.c
index d673a1a74d72..f042a2832eb9 100644
--- a/contrib/bsddialog/lib/lib_util.c
+++ b/contrib/bsddialog/lib/lib_util.c
@@ -1,7 +1,7 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
- * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2025 Alfonso Sabato Siciliano
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -25,6 +25,7 @@
  * SUCH DAMAGE.
  */
 
+#include <stdarg.h>
 #include <curses.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/contrib/bsddialog/lib/lib_util.h b/contrib/bsddialog/lib/lib_util.h
index 526f65b4bfaa..1adc34f3b80a 100644
--- a/contrib/bsddialog/lib/lib_util.h
+++ b/contrib/bsddialog/lib/lib_util.h
@@ -1,7 +1,7 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
- * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2025 Alfonso Sabato Siciliano
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -62,7 +62,7 @@ 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 */
diff --git a/contrib/bsddialog/lib/libbsddialog.c b/contrib/bsddialog/lib/libbsddialog.c
index 555d060ebcbd..cdb5e1e251dc 100644
--- a/contrib/bsddialog/lib/libbsddialog.c
+++ b/contrib/bsddialog/lib/libbsddialog.c
@@ -1,7 +1,7 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
- * Copyright (c) 2021-2023 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2025 Alfonso Sabato Siciliano
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -114,11 +114,21 @@ int bsddialog_backtitle(struct bsddialog_conf *conf, const char *backtitle)
 			mvhline_set(1, 1, WACS_HLINE, SCREENCOLS - 2);
 	}
 
-	refresh();
+	wnoutrefresh(stdscr);
 
 	return (BSDDIALOG_OK);
 }
 
+int bsddialog_backtitle_rf(struct bsddialog_conf *conf, const char *backtitle)
+{
+	int rv;
+
+	rv = bsddialog_backtitle(conf, backtitle);
+	doupdate();
+
+	return (rv);
+}
+
 bool bsddialog_inmode(void)
 {
 	return (in_bsddialog_mode);
diff --git a/contrib/bsddialog/lib/menubox.c b/contrib/bsddialog/lib/menubox.c
index 896306b2881d..e6e2e7e3e63e 100644
--- a/contrib/bsddialog/lib/menubox.c
+++ b/contrib/bsddialog/lib/menubox.c
@@ -1,7 +1,7 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
- * Copyright (c) 2021-2024 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2025 Alfonso Sabato Siciliano
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -391,7 +391,7 @@ drawitem(struct bsddialog_conf *conf, struct privatemenu *m, int y, bool focus)
 			attron(t.menu.bottomdesccolor);
 			addstr(pritem->bottomdesc);
 			attroff(t.menu.bottomdesccolor);
-			refresh();
+			wnoutrefresh(stdscr);
 		}
 	}
 }
@@ -454,18 +454,18 @@ static int menu_size_position(struct dialog *d, struct privatemenu *m)
 	return (0);
 }
 
-static int mixedlist_redraw(struct dialog *d, struct privatemenu *m)
+static int mixedlist_draw(struct dialog *d, bool redraw, struct privatemenu *m)
 {
-	if (d->built) {
+	if (redraw) {
 		hide_dialog(d);
 		refresh(); /* Important for decreasing screen */
 	}
 	m->menurows = m->apimenurows;
 	if (menu_size_position(d, m) != 0)
 		return (BSDDIALOG_ERROR);
-	if (draw_dialog(d) != 0)
+	if (draw_dialog(d) != 0) /* doupdate() in main loop */
 		return (BSDDIALOG_ERROR);
-	if (d->built)
+	if (redraw)
 		refresh(); /* Important to fix grey lines expanding screen */
 	TEXTPAD(d, 2/*bmenu*/ + m->menurows + HBUTTONS);
 
@@ -532,7 +532,7 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
 		drawitem(d.conf, &m, m.sel, true);
 	m.ypad = 0;
 	m.apimenurows = menurows;
-	if (mixedlist_redraw(&d, &m) != 0)
+	if (mixedlist_draw(&d, false, &m) != 0)
 		return (BSDDIALOG_ERROR);
 
 	changeitem = false;
@@ -575,12 +575,12 @@ do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
 				break;
 			if (f1help_dialog(conf) != 0)
 				return (BSDDIALOG_ERROR);
-			if (mixedlist_redraw(&d, &m) != 0)
+			if (mixedlist_draw(&d, true, &m) != 0)
 				return (BSDDIALOG_ERROR);
 			break;
 		case KEY_CTRL('l'):
*** 610 LINES SKIPPED ***