diff options
Diffstat (limited to 'contrib')
22 files changed, 872 insertions, 52 deletions
diff --git a/contrib/bsddialog/CHANGELOG b/contrib/bsddialog/CHANGELOG index 7800098644d7..503f70c73daa 100644 --- a/contrib/bsddialog/CHANGELOG +++ b/contrib/bsddialog/CHANGELOG @@ -1,3 +1,13 @@ +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: diff --git a/contrib/bsddialog/Makefile b/contrib/bsddialog/Makefile index 335b693470e6..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.5 +export VERSION=1.1 .CURDIR ?= ${CURDIR} LIBPATH = ${.CURDIR}/lib LIBBSDDIALOG = ${LIBPATH}/libbsddialog.so diff --git a/contrib/bsddialog/README.md b/contrib/bsddialog/README.md index 5a25109775fe..f7552c303c09 100644 --- a/contrib/bsddialog/README.md +++ b/contrib/bsddialog/README.md @@ -1,4 +1,4 @@ -# BSDDialog 1.0.5 +# 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 diff --git a/contrib/bsddialog/examples_library/compile b/contrib/bsddialog/examples_library/compile index 1a68313090f6..b5e08f740784 100755 --- a/contrib/bsddialog/examples_library/compile +++ b/contrib/bsddialog/examples_library/compile @@ -12,7 +12,7 @@ set -x libpath=../lib examples="menu checklist radiolist mixedlist theme infobox yesno msgbox \ -datebox form timebox rangebox pause calendar gauge mixedgauge textbox" +datebox form timebox rangebox pause calendar gauge mixedgauge textbox slider" rm -f $examples 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_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/Makefile b/contrib/bsddialog/lib/Makefile index c728541a9f7a..b5a3c1a8afc4 100644 --- a/contrib/bsddialog/lib/Makefile +++ b/contrib/bsddialog/lib/Makefile @@ -8,7 +8,7 @@ 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 diff --git a/contrib/bsddialog/lib/bsddialog.h b/contrib/bsddialog/lib/bsddialog.h index fc59071c6fa0..4b387d993363 100644 --- a/contrib/bsddialog/lib/bsddialog.h +++ b/contrib/bsddialog/lib/bsddialog.h @@ -30,7 +30,7 @@ #include <stdbool.h> -#define LIBBSDDIALOG_VERSION "1.0.5" +#define LIBBSDDIALOG_VERSION "1.1" /* Return values */ #define BSDDIALOG_ERROR -1 @@ -245,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/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/utility/bsddialog.1 b/contrib/bsddialog/utility/bsddialog.1 index 0ec2a96952bd..d03a4ce8881a 100644 --- a/contrib/bsddialog/utility/bsddialog.1 +++ b/contrib/bsddialog/utility/bsddialog.1 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd June 22, 2025 +.Dd June 24, 2025 .Dt BSDDIALOG 1 .Os .Sh NAME @@ -851,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/util.h b/contrib/bsddialog/utility/util.h index d1f7793c9755..5e5cba3f82f7 100644 --- a/contrib/bsddialog/utility/util.h +++ b/contrib/bsddialog/utility/util.h @@ -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 0a968d4319f9..9784b1a5e563 100644 --- a/contrib/bsddialog/utility/util_builders.c +++ b/contrib/bsddialog/utility/util_builders.c @@ -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].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); + 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) @@ -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 = ""; @@ -691,12 +691,12 @@ 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].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); + 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); @@ -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; @@ -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].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); + 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 01b6fc31f065..7e76ec84654f 100644 --- a/contrib/bsddialog/utility/util_cli.c +++ b/contrib/bsddialog/utility/util_cli.c @@ -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/pjdfstest/tests/ftruncate/12.t b/contrib/pjdfstest/tests/ftruncate/12.t index 98f3daeaf461..022f2cdae47a 100644 --- a/contrib/pjdfstest/tests/ftruncate/12.t +++ b/contrib/pjdfstest/tests/ftruncate/12.t @@ -22,7 +22,7 @@ EFBIG|EINVAL) ;; *) echo "not ok ${ntest}" - ntest=`expr ${ntest} + 1` + ntest=$((ntest + 1)) ;; esac expect 0 unlink ${n0} diff --git a/contrib/pjdfstest/tests/link/05.t b/contrib/pjdfstest/tests/link/05.t index 5a18c2103e1d..4641e3605efb 100644 --- a/contrib/pjdfstest/tests/link/05.t +++ b/contrib/pjdfstest/tests/link/05.t @@ -2,7 +2,7 @@ # vim: filetype=sh noexpandtab ts=8 sw=8 # $FreeBSD: head/tools/regression/pjdfstest/tests/link/05.t 211352 2010-08-15 21:24:17Z pjd $ -desc="link returns EMLINK if the link count of the file named by name1 would exceed 32767" +desc="link returns EMLINK if the link count of the file named by name1 would exceed {PC_LINK_MAX}" dir=`dirname $0` . ${dir}/../misc.sh @@ -16,19 +16,20 @@ n1=`namegen` n2=`namegen` expect 0 mkdir ${n0} 0755 -n=`mdconfig -a -n -t malloc -s 1m` || exit +n=`mdconfig -a -n -t malloc -s 2m` || exit newfs -i 1 /dev/md${n} >/dev/null || exit mount /dev/md${n} ${n0} || exit +link_max=`${fstest} pathconf ${n0} _PC_LINK_MAX` expect 0 create ${n0}/${n1} 0644 i=1 -while :; do +while [ ${i} -le ${link_max} ]; do link ${n0}/${n1} ${n0}/${i} >/dev/null 2>&1 if [ $? -ne 0 ]; then break fi - i=`expr $i + 1` + i=$((i + 1)) done -test_check $i -eq 32767 +test_check $i -eq ${link_max} expect EMLINK link ${n0}/${n1} ${n0}/${n2} diff --git a/contrib/pjdfstest/tests/link/15.t b/contrib/pjdfstest/tests/link/15.t index cb41ad503370..0dc7648df5cb 100644 --- a/contrib/pjdfstest/tests/link/15.t +++ b/contrib/pjdfstest/tests/link/15.t @@ -26,7 +26,7 @@ while :; do if [ $? -ne 0 ]; then break fi - i=`expr $i + 1` + i=$((i + 1)) done expect ENOSPC link ${n0}/${n1} ${n0}/${n2} umount /dev/md${n} diff --git a/contrib/pjdfstest/tests/mkdir/11.t b/contrib/pjdfstest/tests/mkdir/11.t index 118ca3af8896..f162f6d4eb86 100644 --- a/contrib/pjdfstest/tests/mkdir/11.t +++ b/contrib/pjdfstest/tests/mkdir/11.t @@ -24,7 +24,7 @@ while :; do if [ $? -ne 0 ]; then break fi - i=`expr $i + 1` + i=$((i + 1)) done expect ENOSPC mkdir ${n0}/${n1} 0755 umount /dev/md${n} diff --git a/contrib/pjdfstest/tests/mkfifo/11.t b/contrib/pjdfstest/tests/mkfifo/11.t index 39cfea4e40f7..73d4a5d09f30 100644 --- a/contrib/pjdfstest/tests/mkfifo/11.t +++ b/contrib/pjdfstest/tests/mkfifo/11.t @@ -24,7 +24,7 @@ while :; do if [ $? -ne 0 ]; then break fi - i=`expr $i + 1` + i=$((i + 1)) done expect ENOSPC mkfifo ${n0}/${n1} 0644 umount /dev/md${n} diff --git a/contrib/pjdfstest/tests/open/19.t b/contrib/pjdfstest/tests/open/19.t index 4bc2df2a4313..e3c5b35fd96b 100644 --- a/contrib/pjdfstest/tests/open/19.t +++ b/contrib/pjdfstest/tests/open/19.t @@ -24,7 +24,7 @@ while :; do if [ $? -ne 0 ]; then break fi - i=`expr $i + 1` + i=$((i + 1)) done expect ENOSPC open ${n0}/${i} O_RDONLY,O_CREAT 0644 umount /dev/md${n} diff --git a/contrib/pjdfstest/tests/symlink/11.t b/contrib/pjdfstest/tests/symlink/11.t index b1be674370ad..5d5e864674d6 100644 --- a/contrib/pjdfstest/tests/symlink/11.t +++ b/contrib/pjdfstest/tests/symlink/11.t @@ -24,7 +24,7 @@ while :; do if [ $? -ne 0 ]; then break fi - i=`expr $i + 1` + i=$((i + 1)) done expect ENOSPC symlink test ${n0}/${n1} umount /dev/md${n} diff --git a/contrib/pjdfstest/tests/truncate/12.t b/contrib/pjdfstest/tests/truncate/12.t index 98f3daeaf461..022f2cdae47a 100644 --- a/contrib/pjdfstest/tests/truncate/12.t +++ b/contrib/pjdfstest/tests/truncate/12.t @@ -22,7 +22,7 @@ EFBIG|EINVAL) ;; *) echo "not ok ${ntest}" - ntest=`expr ${ntest} + 1` + ntest=$((ntest + 1)) ;; esac expect 0 unlink ${n0} diff --git a/contrib/tzcode/localtime.c b/contrib/tzcode/localtime.c index 1668475ea646..58099d234e2b 100644 --- a/contrib/tzcode/localtime.c +++ b/contrib/tzcode/localtime.c @@ -1583,15 +1583,15 @@ tzdata_is_fresh(void) struct timespec now; if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) - return 0; + return 1; - if ((now.tv_sec - last_checked >= __tz_change_interval) || - (last_checked > now.tv_sec)) { + if (last_checked == 0 || last_checked > now.tv_sec || + now.tv_sec - last_checked >= __tz_change_interval) { last_checked = now.tv_sec; - return 1; + return 0; } - return 0; + return 1; } #endif /* DETECT_TZ_CHANGES */ @@ -1642,7 +1642,7 @@ tzset_unlocked_name(char const *name) ? lcl_is_set < 0 : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0) #ifdef DETECT_TZ_CHANGES - if (tzdata_is_fresh() == 0) + if (tzdata_is_fresh()) #endif /* DETECT_TZ_CHANGES */ return; # ifdef ALL_STATE |
