diff options
Diffstat (limited to 'contrib')
| -rw-r--r-- | contrib/bsddialog/CHANGELOG | 10 | ||||
| -rw-r--r-- | contrib/bsddialog/Makefile | 2 | ||||
| -rw-r--r-- | contrib/bsddialog/README.md | 7 | ||||
| -rwxr-xr-x | contrib/bsddialog/examples_library/compile | 2 | ||||
| -rw-r--r-- | contrib/bsddialog/examples_library/slider.c | 44 | ||||
| -rw-r--r-- | contrib/bsddialog/examples_utility/slider.sh | 34 | ||||
| -rw-r--r-- | contrib/bsddialog/lib/Makefile | 2 | ||||
| -rw-r--r-- | contrib/bsddialog/lib/bsddialog.h | 8 | ||||
| -rw-r--r-- | contrib/bsddialog/lib/slider.c | 670 | ||||
| -rw-r--r-- | contrib/bsddialog/utility/bsddialog.1 | 6 | ||||
| -rw-r--r-- | contrib/bsddialog/utility/util.h | 1 | ||||
| -rw-r--r-- | contrib/bsddialog/utility/util_builders.c | 90 | ||||
| -rw-r--r-- | contrib/bsddialog/utility/util_cli.c | 11 | ||||
| -rw-r--r-- | contrib/tzcode/localtime.c | 12 | 
14 files changed, 859 insertions, 40 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/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  | 
