diff options
Diffstat (limited to 'contrib/bsddialog')
34 files changed, 1195 insertions, 175 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..503f70c73daa 100644 --- a/contrib/bsddialog/CHANGELOG +++ b/contrib/bsddialog/CHANGELOG @@ -1,11 +1,67 @@ -2024-07-01 1.0.4 +2025-08-15 Version 1.1 + + Library: + * add: bsddialog_slider(). + Thanks to https://gitlab.com/alfix/bsddialog/-/merge_requests/7 + + Utility: + * add: --slider dialog. + Thanks to https://gitlab.com/alfix/bsddialog/-/merge_requests/7 + +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..7eb5938ff291 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.1 .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..f7552c303c09 100644 --- a/contrib/bsddialog/README.md +++ b/contrib/bsddialog/README.md @@ -1,4 +1,4 @@ -# BSDDialog 1.0.4 +# BSDDialog 1.1 This project provides **bsddialog** and **libbsddialog**, an utility and a library to build scripts and tools with TUI dialogs and widgets. @@ -31,7 +31,8 @@ Output: --calendar, --checklist, --datebox, --form, --gauge, --infobox, --inputbox, --menu, --mixedform, --mixedgauge, --msgbox, --passwordbox, --passwordform, ---pause, --radiolist, --rangebox, --textbox, --timebox, --treeview, --yesno. +--pause, --radiolist, --rangebox, --slider, --textbox, --timebox, --treeview, +--yesno. **Manual** @@ -69,6 +70,7 @@ in the _Public Domain_ to build new projects: % sh ./examples_utility/pause.sh % sh ./examples_utility/radiolist.sh % sh ./examples_utility/rangebox.sh +% sh ./examples_utility/slider.sh % sh ./examples_utility/timebox.sh % sh ./examples_utility/yesno.sh ``` @@ -106,6 +108,7 @@ in the _Public Domain_ to build new projects: % ./pause % ./radiolist % ./rangebox +% ./slider % ./theme % ./timebox % ./yesno @@ -129,7 +132,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 +141,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..b5e08f740784 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 slider" 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/slider.c b/contrib/bsddialog/examples_library/slider.c new file mode 100644 index 000000000000..2292f0e8efed --- /dev/null +++ b/contrib/bsddialog/examples_library/slider.c @@ -0,0 +1,44 @@ +/*- + * 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; + unsigned long start, end, blocks[2][2]; + struct bsddialog_conf conf; + + start = 20; + end = 70; + blocks[0][0] = 5; + blocks[0][1] = 10; + blocks[1][0] = 80; + blocks[1][1] = 90; + + if (bsddialog_init() == BSDDIALOG_ERROR) { + printf("Error: %s\n", bsddialog_geterror()); + return (1); + } + bsddialog_initconf(&conf); + conf.title = "slider"; + + output = bsddialog_slider(&conf, "Example", 0, 0, "GiB", 100, &start, + &end, false, 2, blocks); + bsddialog_end(); + if (output == BSDDIALOG_ERROR) { + printf("Error: %s\n", bsddialog_geterror()); + return (1); + } + printf("Start: %lu, End: %lu\n", start, end); + + return (0); +} 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/examples_utility/slider.sh b/contrib/bsddialog/examples_utility/slider.sh new file mode 100644 index 000000000000..bd037e13c977 --- /dev/null +++ b/contrib/bsddialog/examples_utility/slider.sh @@ -0,0 +1,34 @@ +#!/bin/sh +#- +# SPDX-License-Identifier: CC0-1.0 +# +# Written in 2025 by Braulio Rivas. +# +# 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/>. + +: ${BSDDIALOG_ERROR=255} +: ${BSDDIALOG_OK=0} +: ${BSDDIALOG_CANCEL=1} +: ${BSDDIALOG_ESC=5} + +STARTEND=$(./bsddialog --slider "Choose a new partition location" 0 0 MiB \ + 30000 5000 6000 0 1000 3000 25000 30000 \ +3>&1 1>&2 2>&3 3>&-) + +case $? in + $BSDDIALOG_ERROR ) + exit 1 + ;; + $BSDDIALOG_ESC ) + echo "[ESC]" + ;; + $BSDDIALOG_CANCEL ) + echo "[Cancel]" + ;; + $BSDDIALOG_OK ) + echo "[OK] $STARTEND" + ;; +esac 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..b5a3c1a8afc4 100644 --- a/contrib/bsddialog/lib/Makefile +++ b/contrib/bsddialog/lib/Makefile @@ -8,8 +8,9 @@ LIBRARY_SO = lib${LIBRARY:=.so} LIBRARY_A = lib${LIBRARY:=.a} 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 + menubox.c messagebox.c slider.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..4b387d993363 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.1" /* 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); @@ -244,6 +245,12 @@ bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows, int cols, int min, int max, int *value); int +bsddialog_slider(struct bsddialog_conf *conf, const char *text, int rows, + int cols, const char *unit, unsigned long length, unsigned long *start, + unsigned long *end, bool resize, unsigned int nblocks, + unsigned long blocks[][2]); + +int bsddialog_textbox(struct bsddialog_conf *conf, const char *file, int rows, int cols); 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'): case KEY_RESIZE: - if (mixedlist_redraw(&d, &m) != 0) + if (mixedlist_draw(&d, true, &m) != 0) return (BSDDIALOG_ERROR); break; } diff --git a/contrib/bsddialog/lib/messagebox.c b/contrib/bsddialog/lib/messagebox.c index 5132b1b089b8..c3d4a20f5404 100644 --- a/contrib/bsddialog/lib/messagebox.c +++ b/contrib/bsddialog/lib/messagebox.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 @@ -69,19 +69,19 @@ static int message_size_position(struct dialog *d, int *htext) return (0); } -static int message_draw(struct dialog *d, struct scroll *s) +static int message_draw(struct dialog *d, bool redraw, struct scroll *s) { int unused; - if (d->built) { + if (redraw) { /* redraw: RESIZE or F1 */ hide_dialog(d); refresh(); /* Important for decreasing screen */ } if (message_size_position(d, &s->htext) != 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 */ s->printrows = d->h - BORDER - HBUTTONS - BORDER; @@ -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, false, &s) != 0) return (BSDDIALOG_ERROR); loop = true; @@ -170,12 +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, true, &s) != 0) return (BSDDIALOG_ERROR); break; case KEY_CTRL('l'): case KEY_RESIZE: - if (message_draw(&d, &s) != 0) + if (message_draw(&d, true, &s) != 0) return (BSDDIALOG_ERROR); break; default: diff --git a/contrib/bsddialog/lib/slider.c b/contrib/bsddialog/lib/slider.c new file mode 100644 index 000000000000..534253470849 --- /dev/null +++ b/contrib/bsddialog/lib/slider.c @@ -0,0 +1,670 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2025 Braulio Rivas + * + * 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. + */ + +#include <curses.h> +#include <stdlib.h> +#include <string.h> + +#include "bsddialog.h" +#include "bsddialog_theme.h" +#include "lib_util.h" + +#define MINHSLIDER 13 +#define MINWSLIDER 36 + +#define NULLWIN -1 +#define START_WIN 0 +#define END_WIN 1 +#define STEP_WIN 2 +#define SLIDER_WIN 3 +#define NWIN 4 + +enum operation { + MOVERIGHT, + MOVEFARRIGHT, + MOVEFASTRIGHT, + MOVELEFT, + MOVEFARLEFT, + MOVEFASTLEFT, + INCREASELEFT, + DECREASELEFT, + INCREASERIGHT, + DECREASERIGHT, + INCREASESTEP, + DECREASESTEP, +}; + +struct sliderctl { + enum operation op; + unsigned long (*spaces)[2]; + int nspaces; /* api unsigned, but segfault handlesliderctl():MOVELEFT */ + unsigned long length; + unsigned long *start; + unsigned long *end; + unsigned long step; +}; + +static int crashes(long x, long y, long a, long b) +{ + return ((x <= a && a <= y) || (x <= b && b <= y)); +} + +static int fits(long x, long y, long a, long b) +{ + return ((x <= a) && (b <= y)); +} + +static void handlesliderctl(struct sliderctl *sliderctl) +{ + int i, step, tmpstep; + unsigned long x, y, size, old_start, old_end; + signed long new_start, new_end; + + step = sliderctl->step; + old_start = *(sliderctl->start); + new_start = old_start; + old_end = *(sliderctl->end); + new_end = old_end; + size = old_end - old_start + 1; + + switch (sliderctl->op) { + case MOVERIGHT: + new_start = old_start + step; + new_end = old_end + step; + + for (i = 0; i < sliderctl->nspaces; i++) { + x = (sliderctl->spaces)[i][0]; + y = (sliderctl->spaces)[i][1]; + + if (crashes(x, y, new_start, new_end)) { + new_start = y + 1; + new_end = new_start + size - 1; + break; + } + } + break; + case MOVELEFT: + new_start = old_start - step; + new_end = old_end - step; + + for (i = sliderctl->nspaces - 1; i >= 0; i--) { + x = (sliderctl->spaces)[i][0]; + y = (sliderctl->spaces)[i][1]; + + if (crashes(x, y, new_start, new_end)) { + new_end = x - 1; + new_start = new_end - size + 1; + break; + } + } + break; + case INCREASELEFT: + new_start = old_start + step; + break; + case DECREASELEFT: + new_start = old_start - step; + for (i = 0; i < sliderctl->nspaces; i++) { + x = (sliderctl->spaces)[i][0]; + y = (sliderctl->spaces)[i][1]; + + if (crashes(x, y, new_start, new_end)) { + new_start = old_start; + break; + } + } + break; + case INCREASERIGHT: + new_end = old_end + step; + for (i = 0; i < sliderctl->nspaces; i++) { + x = (sliderctl->spaces)[i][0]; + y = (sliderctl->spaces)[i][1]; + + if (crashes(x, y, new_start, new_end)) { + new_end = old_end; + break; + } + } + break; + case DECREASERIGHT: + new_end = old_end - step; + break; + case MOVEFARLEFT: + new_start = 0; + new_end = size - 1; + for (i = 0; i < sliderctl->nspaces; i++) { + x = (sliderctl->spaces)[i][0]; + y = (sliderctl->spaces)[i][1]; + + if (crashes(x, y, new_start, new_end)) { + new_start = y + 1; + new_end = new_start + size - 1; + break; + } + } + break; + case MOVEFARRIGHT: + new_end = (sliderctl->length) - 1; + new_start = new_end - size + 1; + for (i = sliderctl->nspaces - 1; i >= 0; i--) { + x = (sliderctl->spaces)[i][0]; + y = (sliderctl->spaces)[i][1]; + + if (crashes(x, y, new_start, new_end)) { + new_end = x - 1; + new_start = new_end - size + 1; + break; + } + } + break; + case MOVEFASTLEFT: + if (size < 10) { + tmpstep = 1; + } else { + tmpstep = ((sliderctl->length) * 10) / 100; + } + new_start = old_start - tmpstep; + new_end = old_end - tmpstep; + + for (i = sliderctl->nspaces - 1; i >= 0; i--) { + x = (sliderctl->spaces)[i][0]; + y = (sliderctl->spaces)[i][1]; + + if (crashes(x, y, new_start, new_end)) { + new_end = x - 1; + new_start = new_end - size + 1; + break; + } + } + break; + case MOVEFASTRIGHT: + if (size < 10) { + tmpstep = 1; + } else { + tmpstep = ((sliderctl->length) * 10) / 100; + } + new_start = old_start + tmpstep; + new_end = old_end + tmpstep; + + for (i = 0; i < sliderctl->nspaces; i++) { + x = (sliderctl->spaces)[i][0]; + y = (sliderctl->spaces)[i][1]; + + if (crashes(x, y, new_start, new_end)) { + new_start = y + 1; + new_end = new_start + size - 1; + break; + } + } + break; + case INCREASESTEP: + ++step; + break; + case DECREASESTEP: + if (step > 1) { + --step; + } + break; + } + + if (fits(0, (sliderctl->length) - 1, new_start, new_end) != 1) { + new_start = old_start; + new_end = old_end; + } + + if (new_start > new_end) { + new_start = old_start; + new_end = old_end; + } + + sliderctl->step = step; + + *(sliderctl->start) = new_start; + *(sliderctl->end) = new_end; +} + +static void +drawsquare(struct bsddialog_conf *conf, WINDOW *win, enum elevation elev, + bool focus, const char *fmt, unsigned long value) +{ + int h, l, w; + + getmaxyx(win, h, w); + draw_borders(conf, win, elev); + if (focus) { + l = 2 + w % 2; + wattron(win, t.dialog.arrowcolor); + 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); + } + + if (focus) + wattron(win, t.menu.f_namecolor); + + mvwprintw(win, 1, 1, fmt, value); + + if (focus) + wattroff(win, t.menu.f_namecolor); + + wnoutrefresh(win); +} + +static void +print_slider(struct bsddialog_conf *conf, WINDOW *win, + unsigned long spaces[][2], int nspaces, unsigned long length, + unsigned long *start, unsigned long *end, bool active) +{ + int i, y, x, l, height, width; + unsigned long s, e; + chtype ch; + + getmaxyx(win, height, width); + wclear(win); + draw_borders(conf, win, RAISED); + + if (active) { + wattron(win, t.dialog.arrowcolor); + mvwvline(win, 1, 0, LARROW(conf), 1); + mvwvline(win, 1, width - 1, RARROW(conf), 1); + wattroff(win, t.dialog.arrowcolor); + } + + y = height / 2; + width -= 1; + + ch = ' ' | bsddialog_color(BSDDIALOG_RED, BSDDIALOG_RED, 0); + for (i = 0; i < nspaces; i++) { + s = spaces[i][0]; + e = spaces[i][1]; + + x = (s * width) / length; + l = ((e - s) * width) / length; + + if ((e - s) == 0) { + l = 0; + } else if (l == 0) { + l = 1; + } + + mvwhline(win, y, x + 1, ch, l); + } + + ch = ' ' | t.bar.f_color; + s = ((*start) * width) / length; + l = (((*end) - (*start)) * width) / length; + if ((*end - *start) == 0) { + l = 0; + } else if (l == 0) { + l = 1; + } + mvwhline(win, y, s + 1, ch, l); + + wnoutrefresh(win); +} + +static int +slider_draw(struct dialog *d, bool redraw, WINDOW *start_win, WINDOW *end_win, + WINDOW *size_win, WINDOW *step_win, WINDOW *slider_win, const char *unit) +{ + char *buf; + int yslider, xslider; + + if (redraw) { + hide_dialog(d); + refresh(); /* Important for decreasing screen */ + } + if (dialog_size_position(d, MINHSLIDER, MINWSLIDER, NULL) != 0) + return (BSDDIALOG_ERROR); + if (draw_dialog(d) != 0) /* doupdate in main loop */ + return (BSDDIALOG_ERROR); + if (redraw) + refresh(); /* Important to fix grey lines expanding screen */ + TEXTPAD(d, MINHSLIDER + HBUTTONS); + + yslider = d->y + d->h - 15; + xslider = d->x + d->w / 2 - 17; + asprintf(&buf, "Start (%s)", unit); + mvwaddstr(d->widget, d->h - 16, d->w / 2 - 17, buf); + free(buf); + update_box(d->conf, start_win, yslider, xslider, 3, 17, RAISED); + asprintf(&buf, "End (%s)", unit); + mvwaddstr(d->widget, d->h - 16, d->w / 2, buf); + free(buf); + update_box(d->conf, end_win, yslider, xslider + 17, 3, 17, RAISED); + asprintf(&buf, "Size (%s)", unit); + mvwaddstr(d->widget, d->h - 12, d->w / 2 - 17, buf); + free(buf); + update_box(d->conf, size_win, yslider + 4, xslider, 3, 17, RAISED); + asprintf(&buf, "Step (%s)", unit); + mvwaddstr(d->widget, d->h - 12, d->w / 2, buf); + free(buf); + update_box(d->conf, step_win, yslider + 4, xslider + 17, 3, 17, RAISED); + + update_box(d->conf, slider_win, yslider + 7, xslider, 3, 34, RAISED); + wnoutrefresh(d->widget); + + return (0); +} + +/* API */ +int +bsddialog_slider(struct bsddialog_conf *conf, const char *text, int rows, + int cols, const char *unit, unsigned long length, unsigned long *start, + unsigned long *end, bool resize, unsigned int nblocks, + unsigned long blocks[][2]) +{ + struct sliderctl ctl; + bool loop, focusbuttons; + int retval, sel; + wint_t input; + unsigned long size; + WINDOW *start_win, *end_win, *size_win, *step_win, *slider_win; + struct dialog dialog; + + CHECK_PTR(start); + CHECK_PTR(end); + + ctl.spaces = blocks; + ctl.nspaces = nblocks; + ctl.length = length; + ctl.start = start; + ctl.end = end; + ctl.step = 1; + + if (prepare_dialog(conf, text, rows, cols, &dialog) != 0) + return (BSDDIALOG_ERROR); + set_buttons(&dialog, true, OK_LABEL, CANCEL_LABEL); + + if ((start_win = newwin(1, 1, 1, 1)) == NULL) + RETURN_ERROR("Cannot build WINDOW for start"); + wbkgd(start_win, t.dialog.color); + + if ((end_win = newwin(1, 1, 1, 1)) == NULL) + RETURN_ERROR("Cannot build WINDOW for end"); + wbkgd(end_win, t.dialog.color); + + if ((step_win = newwin(1, 1, 1, 1)) == NULL) + RETURN_ERROR("Cannot build WINDOW for step"); + wbkgd(step_win, t.dialog.color); + + if ((size_win = newwin(1, 1, 1, 1)) == NULL) + RETURN_ERROR("Cannot build WINDOW for size"); + wbkgd(size_win, t.dialog.color); + + if ((slider_win = newwin(1, 1, 1, 1)) == NULL) + RETURN_ERROR("Cannot build WINDOW for slider"); + wbkgd(slider_win, t.dialog.color); + + if (slider_draw(&dialog, false, start_win, end_win, size_win, step_win, + slider_win, unit) != 0) + return (BSDDIALOG_ERROR); + + sel = NULLWIN; + loop = focusbuttons = true; + while (loop) { + size = *(ctl.end) - *(ctl.start) + 1; + drawsquare(conf, start_win, RAISED, sel == START_WIN, "%15lu", *start); + drawsquare(conf, end_win, RAISED, sel == END_WIN, "%15lu", *end); + drawsquare(conf, size_win, RAISED, 0, "%15lu", size); + drawsquare(conf, step_win, RAISED, sel == STEP_WIN, "%15d", ctl.step); + print_slider(conf, slider_win, blocks, nblocks, length, start, + end, sel == SLIDER_WIN); + doupdate(); + + if (get_wch(&input) == ERR) + continue; + switch (input) { + case KEY_ENTER: + case 10: /* Enter */ + if (focusbuttons || conf->button.always_active) { + retval = BUTTONVALUE(dialog.bs); + loop = false; + } + break; + case 27: /* Esc */ + if (conf->key.enable_esc) { + retval = BSDDIALOG_ESC; + loop = false; + } + break; + case '\t': /* TAB */ + if (focusbuttons) { + dialog.bs.curr++; + if (dialog.bs.curr >= (int)dialog.bs.nbuttons) { + focusbuttons = false; + sel = START_WIN; + dialog.bs.curr = + conf->button.always_active ? 0 : -1; + } + } else { + sel++; + if ((sel + 1) > NWIN) { + focusbuttons = true; + sel = NULLWIN; + dialog.bs.curr = 0; + } + } + DRAW_BUTTONS(dialog); + break; + case KEY_CTRL('n'): + case KEY_RIGHT: + if (focusbuttons) { + dialog.bs.curr++; + if (dialog.bs.curr >= (int)dialog.bs.nbuttons) { + focusbuttons = false; + sel = START_WIN; + dialog.bs.curr = + conf->button.always_active ? 0 : -1; + } + } else if (sel == SLIDER_WIN) { + ctl.op = MOVERIGHT; + handlesliderctl(&ctl); + } else { + sel++; + } + DRAW_BUTTONS(dialog); + break; + case KEY_CTRL('p'): + case KEY_LEFT: + if (focusbuttons) { + dialog.bs.curr--; + if (dialog.bs.curr < 0) { + focusbuttons = false; + sel = SLIDER_WIN; + dialog.bs.curr = + conf->button.always_active ? 0 : -1; + } + } else if (sel == SLIDER_WIN) { + ctl.op = MOVELEFT; + handlesliderctl(&ctl); + } else if (sel == END_WIN) { + sel = START_WIN; + } else { + focusbuttons = true; + sel = NULLWIN; + dialog.bs.curr = 0; + } + DRAW_BUTTONS(dialog); + break; + case KEY_UP: + if (focusbuttons) { + sel = SLIDER_WIN; + focusbuttons = false; + dialog.bs.curr = + conf->button.always_active ? 0 : -1; + DRAW_BUTTONS(dialog); + } else if (sel == START_WIN) { + if (resize) { + ctl.op = INCREASELEFT; + } else { + ctl.op = MOVERIGHT; + } + handlesliderctl(&ctl); + } else if (sel == END_WIN) { + if (resize) { + ctl.op = INCREASERIGHT; + } else { + ctl.op = MOVERIGHT; + } + handlesliderctl(&ctl); + } else if (sel == STEP_WIN) { + ctl.op = INCREASESTEP; + handlesliderctl(&ctl); + } + break; + case KEY_DOWN: + if (focusbuttons) { + break; + } else if (sel == START_WIN) { + if (resize) { + ctl.op = DECREASELEFT; + } else { + ctl.op = MOVELEFT; + } + handlesliderctl(&ctl); + } else if (sel == END_WIN) { + if (resize) { + ctl.op = DECREASERIGHT; + } else { + ctl.op = MOVELEFT; + } + handlesliderctl(&ctl); + } else if (sel == STEP_WIN) { + ctl.op = DECREASESTEP; + handlesliderctl(&ctl); + } + break; + case '-': + if (focusbuttons) { + break; + } else if (sel == START_WIN) { + if (resize) { + ctl.op = DECREASELEFT; + } else { + ctl.op = MOVELEFT; + } + handlesliderctl(&ctl); + } else if (sel == END_WIN) { + if (resize) { + ctl.op = DECREASERIGHT; + } else { + ctl.op = MOVELEFT; + } + handlesliderctl(&ctl); + } else if (sel == STEP_WIN) { + ctl.op = DECREASESTEP; + handlesliderctl(&ctl); + } + break; + case '+': + if (focusbuttons) { + break; + } else if (sel == START_WIN) { + if (resize) { + ctl.op = INCREASELEFT; + } else { + ctl.op = MOVERIGHT; + } + handlesliderctl(&ctl); + } else if (sel == END_WIN) { + if (resize) { + ctl.op = INCREASERIGHT; + } else { + ctl.op = MOVERIGHT; + } + handlesliderctl(&ctl); + } else if (sel == STEP_WIN) { + ctl.op = INCREASESTEP; + handlesliderctl(&ctl); + } + break; + case KEY_HOME: + if (focusbuttons) { + break; + } else if (sel == SLIDER_WIN) { + ctl.op = MOVEFARLEFT; + handlesliderctl(&ctl); + } + break; + case KEY_END: + if (focusbuttons) { + break; + } else if (sel == SLIDER_WIN) { + ctl.op = MOVEFARRIGHT; + handlesliderctl(&ctl); + } + break; + case KEY_PPAGE: + if (focusbuttons) { + break; + } else if (sel == SLIDER_WIN) { + ctl.op = MOVEFASTLEFT; + handlesliderctl(&ctl); + } + break; + case KEY_NPAGE: + if (focusbuttons) { + break; + } else if (sel == SLIDER_WIN) { + ctl.op = MOVEFASTRIGHT; + handlesliderctl(&ctl); + } + break; + case KEY_F(1): + if (conf->key.f1_file == NULL && + conf->key.f1_message == NULL) + break; + if (f1help_dialog(conf) != 0) + return (BSDDIALOG_ERROR); + if (slider_draw(&dialog, true, start_win, end_win, size_win, + step_win, slider_win, unit) != 0) + return (BSDDIALOG_ERROR); + break; + case KEY_CTRL('l'): + case KEY_RESIZE: + if (slider_draw(&dialog, true, start_win, end_win, size_win, + step_win, slider_win, unit) != 0) + return (BSDDIALOG_ERROR); + break; + default: + if (shortcut_buttons(input, &dialog.bs)) { + DRAW_BUTTONS(dialog); + doupdate(); + retval = BUTTONVALUE(dialog.bs); + loop = false; + } + } + } + + delwin(start_win); + delwin(end_win); + delwin(step_win); + delwin(slider_win); + end_dialog(&dialog); + + return (retval); +} diff --git a/contrib/bsddialog/lib/textbox.c b/contrib/bsddialog/lib/textbox.c index ca3eb69fff52..1f730e0d925b 100644 --- a/contrib/bsddialog/lib/textbox.c +++ b/contrib/bsddialog/lib/textbox.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 @@ -101,17 +101,17 @@ static int textbox_size_position(struct dialog *d, struct scrolltext *st) return (0); } -static int textbox_draw(struct dialog *d, struct scrolltext *st) +static int textbox_draw(struct dialog *d, bool redraw, struct scrolltext *st) { - if (d->built) { + if (redraw) { hide_dialog(d); refresh(); /* Important for decreasing screen */ } if (textbox_size_position(d, st) != 0) return (BSDDIALOG_ERROR); - if (draw_dialog(d) != 0) + if (draw_dialog(d) != 0) /* wrefresh() and prefresh() in main loop */ return (BSDDIALOG_ERROR); - if (d->built) + if (redraw) refresh(); /* Important to fix grey lines expanding screen */ st->ys = d->y + 1; @@ -175,7 +175,7 @@ bsddialog_textbox(struct bsddialog_conf *conf, const char *file, int rows, fclose(fp); set_tabsize(defaulttablen); /* reset because it is curses global */ - if (textbox_draw(&d, &st) != 0) + if (textbox_draw(&d, false, &st) != 0) return (BSDDIALOG_ERROR); loop = true; @@ -254,12 +254,12 @@ bsddialog_textbox(struct bsddialog_conf *conf, const char *file, int rows, break; if (f1help_dialog(conf) != 0) return (BSDDIALOG_ERROR); - if (textbox_draw(&d, &st) != 0) + if (textbox_draw(&d, true, &st) != 0) return (BSDDIALOG_ERROR); break; case KEY_CTRL('l'): case KEY_RESIZE: - if (textbox_draw(&d, &st) != 0) + if (textbox_draw(&d, true, &st) != 0) return (BSDDIALOG_ERROR); break; } diff --git a/contrib/bsddialog/lib/theme.c b/contrib/bsddialog/lib/theme.c index 04f85b2455fa..6c17d908324b 100644 --- a/contrib/bsddialog/lib/theme.c +++ b/contrib/bsddialog/lib/theme.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 @@ -217,7 +217,7 @@ int bsddialog_set_theme(struct bsddialog_theme *theme) { CHECK_PTR(theme); set_theme(&t, theme); - refresh(); + wnoutrefresh(stdscr); return (BSDDIALOG_OK); } @@ -239,7 +239,7 @@ int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme) "to use enum bsddialog_default_theme", newtheme); } - refresh(); + wnoutrefresh(stdscr); return (BSDDIALOG_OK); } diff --git a/contrib/bsddialog/lib/timebox.c b/contrib/bsddialog/lib/timebox.c index 1421cd7d2b81..603d5fa5d7a3 100644 --- a/contrib/bsddialog/lib/timebox.c +++ b/contrib/bsddialog/lib/timebox.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 @@ -62,19 +62,19 @@ drawsquare(struct bsddialog_conf *conf, WINDOW *win, unsigned int value, wnoutrefresh(win); } -static int timebox_redraw(struct dialog *d, struct clock *c) +static int timebox_draw(struct dialog *d, bool redraw, struct clock *c) { int y, x; - if (d->built) { + if (redraw) { hide_dialog(d); refresh(); /* Important for decreasing screen */ } if (dialog_size_position(d, HBOX, MINWTIME, NULL) != 0) return (BSDDIALOG_ERROR); - if (draw_dialog(d) != 0) + if (draw_dialog(d) != 0) /* doupdate() in mail loop */ return (BSDDIALOG_ERROR); - if (d->built) + if (redraw) refresh(); /* Important to fix grey lines expanding screen */ TEXTPAD(d, HBOX + HBUTTONS); @@ -117,7 +117,7 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows, wbkgd(c[i].win, t.dialog.color); c[i].value = MIN(c[i].value, c[i].max); } - if (timebox_redraw(&d, c) != 0) + if (timebox_draw(&d, false, c) != 0) return (BSDDIALOG_ERROR); sel = -1; @@ -210,12 +210,12 @@ bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows, break; if (f1help_dialog(conf) != 0) return (BSDDIALOG_ERROR); - if (timebox_redraw(&d, c) != 0) + if (timebox_draw(&d, true, c) != 0) return (BSDDIALOG_ERROR); break; case KEY_CTRL('l'): case KEY_RESIZE: - if (timebox_redraw(&d, c) != 0) + if (timebox_draw(&d, true, c) != 0) return (BSDDIALOG_ERROR); break; default: diff --git a/contrib/bsddialog/utility/GNUmakefile b/contrib/bsddialog/utility/GNUmakefile index 518ec0d912d6..600efc7aacf6 100644 --- a/contrib/bsddialog/utility/GNUmakefile +++ b/contrib/bsddialog/utility/GNUmakefile @@ -6,6 +6,7 @@ OUTPUT = bsddialog SOURCES = bsddialog.c util_builders.c util_cli.c util_theme.c OBJECTS = $(SOURCES:.c=.o) +PREFIX = /usr/local ifneq ($(ENABLEDEBUG),) CFLAGS += -g @@ -20,7 +21,13 @@ endif RM = rm -f -all : $(OUTPUT) +all: $(OUTPUT) + +install: all + ${INSTALL} -m 0755 ${OUTPUT} ${DESTDIR}${PREFIX}/bin/${OUTPUT} + +uninstall: + ${RM} ${DESTDIR}${PREFIX}/bin/${OUTPUT} $(OUTPUT): $(OBJECTS) $(CC) $^ -o $@ $(LDFLAGS) @@ -31,3 +38,5 @@ $(OUTPUT): $(OBJECTS) clean: $(RM) $(OUTPUT) *.o *~ + +.PHONY: all install uninstall clean diff --git a/contrib/bsddialog/utility/Makefile b/contrib/bsddialog/utility/Makefile index ab51b46a25be..e6cd541fded4 100644 --- a/contrib/bsddialog/utility/Makefile +++ b/contrib/bsddialog/utility/Makefile @@ -6,6 +6,7 @@ OUTPUT = bsddialog SOURCES = bsddialog.c util_builders.c util_cli.c util_theme.c OBJECTS = ${SOURCES:.c=.o} +PREFIX = /usr/local .if defined(DEBUG) CFLAGS += -g @@ -21,7 +22,13 @@ LDFLAGS += -ltinfow -Wl,-rpath=${LIBPATH} -L${LIBPATH} -lbsddialog INSTALL = install RM = rm -f -all : ${OUTPUT} +all: ${OUTPUT} + +install: all + ${INSTALL} -m 0755 ${OUTPUT} ${DESTDIR}${PREFIX}/bin/${OUTPUT} + +uninstall: + ${RM} ${DESTDIR}${PREFIX}/bin/${OUTPUT} ${OUTPUT}: ${OBJECTS} ${CC} ${LDFLAGS} ${OBJECTS} -o ${.PREFIX} @@ -31,3 +38,5 @@ ${OUTPUT}: ${OBJECTS} clean: ${RM} ${OUTPUT} *.o *~ *.core *.gz + +.PHONY: all install uninstall clean diff --git a/contrib/bsddialog/utility/bsddialog.1 b/contrib/bsddialog/utility/bsddialog.1 index 4586ba16020c..d03a4ce8881a 100644 --- a/contrib/bsddialog/utility/bsddialog.1 +++ b/contrib/bsddialog/utility/bsddialog.1 @@ -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,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 25, 2024 +.Dd June 24, 2025 .Dt BSDDIALOG 1 .Os .Sh NAME @@ -80,7 +80,14 @@ The following options can change the default behavior of the utility and are common to some dialog. .Bl -tag -width Ds .It Fl Fl alternate-screen -If available set alternate screen mode, see +Set alternate screen mode if the terminal and +.Xr curses 3 +provide it. +If enabled bsddialog draws to the alternate screen and restores the main screen +after exit. +See +.Dq smcup +in .Xr terminfo 5 . .It Fl Fl ascii-lines Ascii characters to draw lines. @@ -291,7 +298,11 @@ Set an exit code value for the .Dq Ok button. .It Fl Fl normal-screen -If available set normal screen mode, see +Set normal screen mode. +bsddialog does not restore the previous screen after exit. +See +.Dq rmcup +in .Xr terminfo 5 . .It Fl Fl output-fd Ar fd Print input from user interface to the specified file descriptor. @@ -737,7 +748,7 @@ Right1 generic button. .It 10 Right2 generic button. .It 11 -Right2 generic button. +Right3 generic button. .El .Sh EXAMPLES Backtitle, title and message: @@ -840,6 +851,10 @@ utility first appeared in was written by .An Alfonso Sabato Siciliano .Aq Mt asiciliano@FreeBSD.org . +.An Braulio Rivas +.Aq Mt brauliorivas@FreeBSD.org +implemented the slider dialog for the +.Dq GSoC 2025 Full Disk Administration Tool for FreeBSD . .Pp .Nm bsddialog provides also a subset of the functionality described in the diff --git a/contrib/bsddialog/utility/bsddialog.c b/contrib/bsddialog/utility/bsddialog.c index 3ba21eadf7a3..bce1d0ab8452 100644 --- a/contrib/bsddialog/utility/bsddialog.c +++ b/contrib/bsddialog/utility/bsddialog.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 diff --git a/contrib/bsddialog/utility/util.h b/contrib/bsddialog/utility/util.h index 2750c2ee6951..5e5cba3f82f7 100644 --- a/contrib/bsddialog/utility/util.h +++ b/contrib/bsddialog/utility/util.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 @@ -108,6 +108,7 @@ int passwordform_builder(BUILDER_ARGS); int pause_builder(BUILDER_ARGS); int radiolist_builder(BUILDER_ARGS); int rangebox_builder(BUILDER_ARGS); +int slider_builder(BUILDER_ARGS); int textbox_builder(BUILDER_ARGS); int timebox_builder(BUILDER_ARGS); int treeview_builder(BUILDER_ARGS); diff --git a/contrib/bsddialog/utility/util_builders.c b/contrib/bsddialog/utility/util_builders.c index 2e69994a0ec0..9784b1a5e563 100644 --- a/contrib/bsddialog/utility/util_builders.c +++ b/contrib/bsddialog/utility/util_builders.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 @@ -82,7 +82,7 @@ int gauge_builder(BUILDER_ARGS) perc = 0; if (argc == 1) { - perc = (u_int)strtoul(argv[0], NULL, 10); + perc = (unsigned int)strtoul(argv[0], NULL, 10); perc = perc > 100 ? 100 : perc; } else if (argc > 1) { error_args(opt->name, argc - 1, argv + 1); @@ -106,7 +106,7 @@ int mixedgauge_builder(BUILDER_ARGS) exit_error(true, "bad %s pair number [<minilabel> <miniperc>]", opt->name); - mainperc = (u_int)strtoul(argv[0], NULL, 10); + mainperc = (unsigned int)strtoul(argv[0], NULL, 10); mainperc = mainperc > 100 ? 100 : mainperc; argc--; argv++; @@ -138,7 +138,7 @@ int pause_builder(BUILDER_ARGS) if (argc > 1) error_args(opt->name, argc - 1, argv + 1); - secs = (u_int)strtoul(argv[0], NULL, 10); + secs = (unsigned int)strtoul(argv[0], NULL, 10); output = bsddialog_pause(conf, text, rows, cols, &secs); return (output); @@ -189,9 +189,9 @@ static int date(BUILDER_ARGS) error_args(opt->name, argc - 3, argv + 3); } else if (argc == 3) { /* lib checks/sets max and min */ - dd = (u_int)strtoul(argv[0], NULL, 10); - mm = (u_int)strtoul(argv[1], NULL, 10); - yy = (u_int)strtoul(argv[2], NULL, 10); + dd = (unsigned int)strtoul(argv[0], NULL, 10); + mm = (unsigned int)strtoul(argv[1], NULL, 10); + yy = (unsigned int)strtoul(argv[2], NULL, 10); } if (strcmp(opt->name, "--datebox") == 0) @@ -259,9 +259,9 @@ int timebox_builder(BUILDER_ARGS) if (argc > 3) { error_args("--timebox", argc - 3, argv + 3); } else if (argc == 3) { - hh = (u_int)strtoul(argv[0], NULL, 10); - mm = (u_int)strtoul(argv[1], NULL, 10); - ss = (u_int)strtoul(argv[2], NULL, 10); + hh = (unsigned int)strtoul(argv[0], NULL, 10); + mm = (unsigned int)strtoul(argv[1], NULL, 10); + ss = (unsigned int)strtoul(argv[2], NULL, 10); } output = bsddialog_timebox(conf, text, rows, cols, &hh, &mm, &ss); @@ -315,7 +315,7 @@ get_menu_items(int argc, char **argv, bool setprefix, bool setdepth, for (i = 0; i < *nitems; i++) { (*items)[i].prefix = setprefix ? argv[j++] : ""; (*items)[i].depth = setdepth ? - (u_int)strtoul(argv[j++], NULL, 0) : 0; + (unsigned int)strtoul(argv[j++], NULL, 0) : 0; (*items)[i].name = setname ? argv[j++] : ""; (*items)[i].desc = setdesc ? argv[j++] : ""; if (setstatus) { @@ -436,7 +436,7 @@ int checklist_builder(BUILDER_ARGS) if (argc < 1) exit_error(true, "--checklist missing <menurows>"); - menurows = (u_int)strtoul(argv[0], NULL, 10); + menurows = (unsigned int)strtoul(argv[0], NULL, 10); get_menu_items(argc-1, argv+1, opt->item_prefix, opt->item_depth, true, true, true, opt->item_bottomdesc, &nitems, &items, &focusitem, opt); @@ -461,7 +461,7 @@ int menu_builder(BUILDER_ARGS) if (argc < 1) exit_error(true, "--menu missing <menurows>"); - menurows = (u_int)strtoul(argv[0], NULL, 10); + menurows = (unsigned int)strtoul(argv[0], NULL, 10); get_menu_items(argc-1, argv+1, opt->item_prefix, opt->item_depth, true, true, false, opt->item_bottomdesc, &nitems, &items, &focusitem, @@ -487,7 +487,7 @@ int radiolist_builder(BUILDER_ARGS) if (argc < 1) exit_error(true, "--radiolist missing <menurows>"); - menurows = (u_int)strtoul(argv[0], NULL, 10); + menurows = (unsigned int)strtoul(argv[0], NULL, 10); get_menu_items(argc-1, argv+1, opt->item_prefix, opt->item_depth, true, true, true, opt->item_bottomdesc, &nitems, &items, &focusitem, opt); @@ -512,7 +512,7 @@ int treeview_builder(BUILDER_ARGS) if (argc < 1) exit_error(true, "--treeview missing <menurows>"); - menurows = (u_int)strtoul(argv[0], NULL, 10); + menurows = (unsigned int)strtoul(argv[0], NULL, 10); get_menu_items(argc-1, argv+1, opt->item_prefix, true, true, true, true, opt->item_bottomdesc, &nitems, &items, &focusitem, opt); @@ -595,7 +595,7 @@ int form_builder(BUILDER_ARGS) if (argc < 1) exit_error(true, "--form missing <formheight>"); - formheight = (u_int)strtoul(argv[0], NULL, 10); + formheight = (unsigned int)strtoul(argv[0], NULL, 10); argc--; argv++; @@ -608,12 +608,12 @@ int form_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].label = argv[j++]; + items[i].ylabel = (unsigned int)strtoul(argv[j++], NULL, 10); + items[i].xlabel = (unsigned int)strtoul(argv[j++], NULL, 10); + items[i].init = argv[j++]; + items[i].yfield = (unsigned int)strtoul(argv[j++], NULL, 10); + items[i].xfield = (unsigned int)strtoul(argv[j++], NULL, 10); fieldlen = (int)strtol(argv[j++], NULL, 10); if (fieldlen == 0) @@ -621,7 +621,7 @@ int form_builder(BUILDER_ARGS) else items[i].fieldlen = abs(fieldlen); - items[i].maxvaluelen = (u_int)strtoul(argv[j++], NULL, 10); + items[i].maxvaluelen = (unsigned int)strtoul(argv[j++], NULL, 10); if (items[i].maxvaluelen == 0) items[i].maxvaluelen = items[i].fieldlen; @@ -651,15 +651,15 @@ int inputbox_builder(BUILDER_ARGS) if (argc > 1) error_args("--inputbox", argc - 1, argv + 1); - item.label = ""; - item.ylabel = 0; - item.xlabel = 0; - item.init = argc > 0 ? argv[0] : ""; - item.yfield = 0; - item.xfield = 0; + item.label = ""; + item.ylabel = 0; + item.xlabel = 0; + item.init = argc > 0 ? argv[0] : ""; + item.yfield = 0; + item.xfield = 0; item.fieldlen = 1; item.maxvaluelen = opt->max_input_form; - item.flags = BSDDIALOG_FIELDNOCOLOR; + item.flags = BSDDIALOG_FIELDNOCOLOR; item.flags |= BSDDIALOG_FIELDCURSOREND; item.flags |= BSDDIALOG_FIELDEXTEND; item.bottomdesc = ""; @@ -678,7 +678,7 @@ int mixedform_builder(BUILDER_ARGS) if (argc < 1) exit_error(true, "--mixedform missing <formheight>"); - formheight = (u_int)strtoul(argv[0], NULL, 10); + formheight = (unsigned int)strtoul(argv[0], NULL, 10); argc--; argv++; @@ -691,22 +691,22 @@ 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].label = argv[j++]; + items[i].ylabel = (unsigned int)strtoul(argv[j++], NULL, 10); + items[i].xlabel = (unsigned int)strtoul(argv[j++], NULL, 10); + items[i].init = argv[j++]; + items[i].yfield = (unsigned int)strtoul(argv[j++], NULL, 10); + items[i].xfield = (unsigned 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].maxvaluelen = (unsigned int)strtoul(argv[j++], NULL, 10); if (items[i].maxvaluelen == 0) items[i].maxvaluelen = items[i].fieldlen; - items[i].flags = (u_int)strtoul(argv[j++], NULL, 10); + items[i].flags = (unsigned int)strtoul(argv[j++], NULL, 10); if (fieldlen <= 0) items[i].flags |= BSDDIALOG_FIELDREADONLY; @@ -737,13 +737,13 @@ int passwordbox_builder(BUILDER_ARGS) if (argc > 1) error_args("--passwordbox", argc - 1, argv + 1); - item.label = ""; - item.ylabel = 0; - item.xlabel = 0; - item.init = argc > 0 ? argv[0] : ""; - item.yfield = 0; - item.xfield = 0; - item.fieldlen = 1; + item.label = ""; + item.ylabel = 0; + item.xlabel = 0; + item.init = argc > 0 ? argv[0] : ""; + item.yfield = 0; + item.xfield = 0; + item.fieldlen = 1; item.maxvaluelen = opt->max_input_form; item.flags = BSDDIALOG_FIELDHIDDEN; item.flags |= BSDDIALOG_FIELDNOCOLOR; @@ -765,7 +765,7 @@ int passwordform_builder(BUILDER_ARGS) if (argc < 1) exit_error(true, "--passwordform missing <formheight>"); - formheight = (u_int)strtoul(argv[0], NULL, 10); + formheight = (unsigned int)strtoul(argv[0], NULL, 10); argc--; argv++; @@ -779,12 +779,12 @@ int passwordform_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].label = argv[j++]; + items[i].ylabel = (unsigned int)strtoul(argv[j++], NULL, 10); + items[i].xlabel = (unsigned int)strtoul(argv[j++], NULL, 10); + items[i].init = argv[j++]; + items[i].yfield = (unsigned int)strtoul(argv[j++], NULL, 10); + items[i].xfield = (unsigned int)strtoul(argv[j++], NULL, 10); fieldlen = (int)strtol(argv[j++], NULL, 10); items[i].fieldlen = abs(fieldlen); @@ -809,3 +809,41 @@ int passwordform_builder(BUILDER_ARGS) return (output); } + +int slider_builder(BUILDER_ARGS) +{ + bool resize; + int output; + char *unit; + unsigned int i, nblocks; + unsigned long length, start, end, (*blocks)[2]; + + if (argc < 5) + exit_error(true, "--slider requires: <unit> <lenght> <start> <end> <resize>"); + unit = argv[0]; + length = strtoul(argv[1], NULL, 10); + start = strtoul(argv[2], NULL, 10); + end = strtoul(argv[3], NULL, 10); + resize = strtoul(argv[4], NULL, 10) == 0 ? false : true; + + argc -= 5; + argv += 5; + if (argc & 1) + exit_error(true, "bad [<start_block> <end_block> ...] number"); + nblocks = argc / 2; + if ((blocks = malloc(nblocks * sizeof(*blocks))) == NULL) + exit_error(false, "Cannot allocate memory for blocks"); + for (i = 0; i < nblocks; i++) { + blocks[i][0] = strtoul(argv[2 * i], NULL, 10); + blocks[i][1] = strtoul(argv[2 * i + 1], NULL, 10); + } + + output = bsddialog_slider(conf, text, rows, cols, unit, length, &start, &end, + resize, nblocks, blocks); + free(blocks); + + if (output != BSDDIALOG_ERROR) + dprintf(opt->output_fd, "%lu %lu", start, end); + + return (output); +} diff --git a/contrib/bsddialog/utility/util_cli.c b/contrib/bsddialog/utility/util_cli.c index a70de36a699e..7e76ec84654f 100644 --- a/contrib/bsddialog/utility/util_cli.c +++ b/contrib/bsddialog/utility/util_cli.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 @@ -143,7 +143,8 @@ enum OPTS { TEXTBOX, TIMEBOX, TREEVIEW, - YESNO + YESNO, + SLIDER, }; /* options descriptor */ @@ -264,6 +265,7 @@ static struct option longopts[] = { {"pause", no_argument, NULL, PAUSE}, {"radiolist", no_argument, NULL, RADIOLIST}, {"rangebox", no_argument, NULL, RANGEBOX}, + {"slider", no_argument, NULL, SLIDER}, {"textbox", no_argument, NULL, TEXTBOX}, {"timebox", no_argument, NULL, TIMEBOX}, {"treeview", no_argument, NULL, TREEVIEW}, @@ -801,6 +803,13 @@ parseargs(int argc, char **argv, struct bsddialog_conf *conf, opt->name = "--rangebox"; opt->dialogbuilder = rangebox_builder; break; + case SLIDER: + if (opt->dialogbuilder != NULL) + exit_error(true, "%s and --slider without " + "--and-dialog", opt->name); + opt->name = "--slider"; + opt->dialogbuilder = slider_builder; + break; case TEXTBOX: if (opt->dialogbuilder != NULL) exit_error(true, "%s and --textbox without " diff --git a/contrib/bsddialog/utility/util_theme.c b/contrib/bsddialog/utility/util_theme.c index a95cadacc1b0..cca79e83b97d 100644 --- a/contrib/bsddialog/utility/util_theme.c +++ b/contrib/bsddialog/utility/util_theme.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 @@ -279,7 +279,7 @@ void loadtheme(const char *file, bool compatibility) break; case BOOL: boolvalue = (strstr(value, "true") != NULL) ? - true :false; + true : false; *((bool*)p[i].value) = boolvalue; break; case COLOR: |
