aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GNUMakefile6
-rw-r--r--LICENSE2
-rw-r--r--Makefile25
-rw-r--r--README.md159
-rw-r--r--bsddialog.1590
-rw-r--r--bsddialog.c1152
-rw-r--r--examples_library/buildlist.c44
-rw-r--r--examples_library/checklist.c41
-rwxr-xr-xexamples_library/compile15
-rw-r--r--examples_library/datebox.c18
-rw-r--r--examples_library/form.c34
-rw-r--r--examples_library/infobox.c21
-rw-r--r--examples_library/menu.c38
-rw-r--r--examples_library/mixedlist.c47
-rw-r--r--examples_library/msgbox.c32
-rw-r--r--examples_library/pause.c16
-rw-r--r--examples_library/radiolist.c38
-rw-r--r--examples_library/rangebox.c20
-rw-r--r--examples_library/sade.c56
-rw-r--r--examples_library/theme.c57
-rw-r--r--examples_library/timebox.c18
-rw-r--r--examples_library/treeview.c46
-rw-r--r--examples_library/yesno.c25
-rwxr-xr-xexamples_utility/buildlist.sh17
-rwxr-xr-xexamples_utility/checklist.sh4
-rwxr-xr-xexamples_utility/form.sh12
-rwxr-xr-xexamples_utility/gauge.sh32
-rwxr-xr-xexamples_utility/infobox.sh5
-rwxr-xr-xexamples_utility/inputbox.sh4
-rwxr-xr-xexamples_utility/menu.sh14
-rwxr-xr-xexamples_utility/mixedform.sh8
-rwxr-xr-xexamples_utility/mixedgauge.sh42
-rwxr-xr-xexamples_utility/msgbox.sh4
-rwxr-xr-xexamples_utility/passwordbox.sh2
-rwxr-xr-xexamples_utility/passwordform.sh12
-rwxr-xr-xexamples_utility/radiolist.sh14
-rwxr-xr-xexamples_utility/treeview.sh14
-rwxr-xr-xexamples_utility/yesno.sh4
-rw-r--r--lib/GNUMakefile8
-rw-r--r--lib/Makefile74
-rw-r--r--lib/barbox.c571
-rw-r--r--lib/bsddialog.3809
-rw-r--r--lib/bsddialog.h182
-rw-r--r--lib/bsddialog_progressview.h20
-rw-r--r--lib/bsddialog_theme.h23
-rw-r--r--lib/formbox.c255
-rw-r--r--lib/infobox.c93
-rw-r--r--lib/lib_util.c755
-rw-r--r--lib/lib_util.h86
-rw-r--r--lib/libbsddialog.c57
-rw-r--r--lib/menubox.c1079
-rw-r--r--lib/messagebox.c237
-rw-r--r--lib/textbox.c164
-rw-r--r--lib/theme.c48
-rw-r--r--lib/timebox.c343
55 files changed, 4003 insertions, 3489 deletions
diff --git a/GNUMakefile b/GNUMakefile
index 7480ae33ec21..69cec29d6a67 100644
--- a/GNUMakefile
+++ b/GNUMakefile
@@ -1,14 +1,14 @@
# PUBLIC DOMAIN - NO WARRANTY, see:
-# <http://creativecommons.org/publicdomain/zero/1.0/>
+# <http://creativecommons.org/publicdomain/zero/1.0/>
#
-# Written by Alfonso Sabato Siciliano
+# Written in 2021 by Alfonso Sabato Siciliano
OUTPUT= bsddialog
SOURCES= bsddialog.c
OBJECTS= $(SOURCES:.c=.o)
LIBPATH= ./lib
LIBBSDDIALOG= $(LIBPATH)/libbsddialog.so
-CFLAGS= -g -Wall -I$(LIBPATH)
+CFLAGS= -Wall -I$(LIBPATH)
LDFLAGS= -Wl,-rpath=$(LIBPATH) -L$(LIBPATH) -lbsddialog
RM = rm -f
diff --git a/LICENSE b/LICENSE
index 434f1782e537..f24be045375b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
BSD 2-Clause License
-Copyright (c) 2021, Alfonso Sabato Siciliano
+Copyright (c) 2021-2022, Alfonso Sabato Siciliano
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
diff --git a/Makefile b/Makefile
index 295aa927e4c5..2abfb9e27cd7 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
-# Any copyright is dedicated to the Public Domain, see:
+# PUBLIC DOMAIN - NO WARRANTY, see:
# <http://creativecommons.org/publicdomain/zero/1.0/>
#
-# Written by Alfonso Sabato Siciliano
+# Written in 2021 by Alfonso Sabato Siciliano
OUTPUT= bsddialog
SOURCES= bsddialog.c
@@ -9,8 +9,19 @@ OBJECTS= ${SOURCES:.c=.o}
LIBPATH= ${.CURDIR}/lib
LIBBSDDIALOG= ${LIBPATH}/libbsddialog.so
-CFLAGS= -Wall -I${LIBPATH}
-LDFLAGS= -Wl,-rpath=${LIBPATH} -L${LIBPATH} -lbsddialog
+CFLAGS+= -I${LIBPATH} -std=gnu99 -Wno-format-zero-length \
+-fstack-protector-strong -Wsystem-headers -Werror -Wall -Wno-format-y2k -W \
+-Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith \
+-Wno-uninitialized -Wno-pointer-sign -Wno-empty-body -Wno-string-plus-int \
+-Wno-unused-const-variable -Wno-tautological-compare -Wno-unused-value \
+-Wno-parentheses-equality -Wno-unused-function -Wno-enum-conversion \
+-Wno-unused-local-typedef -Wno-address-of-packed-member -Qunused-arguments
+# `make -DDEBUG`
+.if defined(DEBUG)
+CFLAGS= -g -Wall -I${LIBPATH}
+LIBDEBUG= -DDEBUG
+.endif
+LDFLAGS+= -Wl,-rpath=${LIBPATH} -L${LIBPATH} -lbsddialog
BINDIR= /usr/local/bin
MAN= ${OUTPUT}.1
@@ -26,11 +37,7 @@ ${OUTPUT}: ${LIBBSDDIALOG} ${OBJECTS}
${CC} ${LDFLAGS} ${OBJECTS} -o ${.PREFIX}
${LIBBSDDIALOG}:
-.if defined(PORTNCURSES)
- make -C ${LIBPATH} -DPORTNCURSES
-.else
- make -C ${LIBPATH}
-.endif
+ make -C ${LIBPATH} ${LIBDEBUG}
.c.o:
${CC} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
diff --git a/README.md b/README.md
index 31579f519ab6..17af3a0db8e5 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,21 @@
-# BSDDialog
+# BSDDialog 0.1
-**Work In Progress!**
This project provides **bsddialog** and **libbsddialog**, an utility and a
-library to build scripts and tools with *TUI Widgets*.
+library to build scripts and tools with TUI dialogs and widgets.
-Description:
+
+## Intro
+
+Briefly:
<https://www.freebsd.org/status/report-2021-04-2021-06/#_bsddialog_tui_widgets>
+Utility:
+<https://alfonsosiciliano.gitlab.io/posts/2021-12-07-bsddialog.html>
+
+Library:
+<https://alfonsosiciliano.gitlab.io/posts/2022-01-16-libbsddialog.html>
+
Screenshots:
<https://www.flickr.com/photos/alfonsosiciliano/albums/72157720215006074>
@@ -23,35 +31,39 @@ FreeBSD:
% ./bsddialog --msgbox "Hello World!" 8 20
```
-If you are using XFCE install
-[devel/ncurses](https://www.freshports.org/devel/ncurses/)
-
-```
-% sudo pkg install ncurses
-% git clone https://gitlab.com/alfix/bsddialog.git
-% cd bsddialog
-% make -DPORTNCURSES
-% ./bsddialog --msgbox "Hello World!" 8 20
-```
-
Output:
![screenshot](screenshot.png)
-Examples utility:
+## Utility
+
+**Dialogs:**
+
+--checklist, --datebox, --form, --gauge, --inputbox, --menu, --mixedform,
+--mixedgauge, --msgbox, --passwordbox, --passwordform, --pause, --radiolist,
+--rangebox, --textbox, --timebox, --treeview, --yesno.
+
+**Manual**
+
+ - [bsddialog(1)](https://alfonsosiciliano.gitlab.io/posts/2022-01-26-manual-bsddialog.html)
+
+
+**Examples**:
+
```
-% ./bsddialog --title msgbox --msgbox "Hello World!" 5 30
-% ./bsddialog --theme default --title msgbox --msgbox "Hello World!" 5 30
-% ./bsddialog --begin-y 2 --title yesno --yesno "Hello World!" 5 30
-% ./bsddialog --ascii-lines --pause "Hello World!" 8 50 5
-% ./bsddialog --checklist "Space to select" 0 0 0 Name1 Desc1 off Name2 Desc2 on Name3 Desc3 off
-% ./bsddialog --backtitle "TITLE" --title yesno --hline "bsddialog" --yesno "Hello World!" 5 25
-% ./bsddialog --extra-button --help-button --defaultno --yesno "Hello World!" 0 0
+% ./bsddialog --backtitle "TITLE" --title msgbox --msgbox "Hello World!" 5 30
+% ./bsddialog --theme blackwhite --title msgbox --msgbox "Hello World!" 5 30
+% ./bsddialog --begin-y 2 --default-no --title yesno --yesno "Hello World!" 5 30
+% ./bsddialog --ascii-lines --pause "Hello World!" 8 50 10
+% ./bsddialog --checklist "Space to select" 0 0 0 Name1 Desc1 off Name2 Desc2 on
+% ./bsddialog --title yesno --hline "bsddialog" --yesno "Hello World!" 5 25
+% ./bsddialog --extra-button --help-button --yesno "Hello World!" 0 0
```
-and
+
+and [Examples](https://gitlab.com/alfix/bsddialog/-/tree/main/examples_utility)
+in the _Public Domain_ to build new projects:
```
-% sh ./examples_utility/buildlist.sh
% sh ./examples_utility/checklist.sh
% sh ./examples_utility/form.sh
% sh ./examples_utility/gauge.sh
@@ -68,12 +80,26 @@ and
% sh ./examples_utility/yesno.sh
```
-Examples library:
+## Library
+
+**API**
+
+ - [bsddialog.h](https://gitlab.com/alfix/bsddialog/-/blob/main/lib/bsddialog.h)
+ - [bsddialog\_theme.h](https://gitlab.com/alfix/bsddialog/-/blob/main/lib/bsddialog_theme.h)
+
+
+**Manual**
+
+ - [bsddialog(3)](https://alfonsosiciliano.gitlab.io/posts/2022-01-15-manual-libbsddialog.html)
+
+
+**Examples**:
+
+[Examples](https://gitlab.com/alfix/bsddialog/-/tree/main/examples_library)
+in the _Public Domain_ to build new projects:
```
% cd examples_library
% sh compile
-% ./buildlist
-% ./compile
% ./datebox
% ./form
% ./infobox
@@ -83,85 +109,8 @@ Examples library:
% ./pause
% ./radiolist
% ./rangebox
-% ./sade
% ./theme
% ./timebox
-% ./treeview
% ./yesno
```
-
-Use Cases:
-
- - [portconfig](https://gitlab.com/alfix/portconfig)
-
-
-## Features
-
-**Common Options:**
-
---ascii-lines, --aspect *ratio* (for infobox, msgbox and yesno),
---backtitle *backtitle*, --begin-x *x* (--begin *y y*),
-(--begin *y x*), --cancel-label *string*, -clear (test with multiple widgets),
---colors, --date-format *format*, --default-button *string*, --defaultno,
---default-item *string*,
---exit-label *string*, --extra-button, --extra-label *string*,
---hfile *filename* (for completed widgets), --help, --help-button,
---help-label *string*, --help-status, --help-tags, --hline *string*, --ignore,
---insecure, --item-help, --max-input *size*, --no-cancel, --nocancel,
---no-label *string*, --no-items, --no-lines, --no-ok,
---nook, --no-shadow, --no-tags, --ok-label *string*, --output-fd *fd*,
---output-separator *string*, --print-version,
---print-size (todo move lib -> utility), --quoted (quotes all != dialog),
---print-maxsize, --shadow, --single-quoted (add --quote-with *ch*?),
---separator *string* (alias --output-separator *string*),
---separate-output (rename --separate-output-withnl?), --sleep *secs*, --stderr,
---stdout, --theme *string* ("bsddialog", "dialog", "blackwhite"),
---time-format *format*, --title *title*, --version, --yes-label *string*.
-
-**Widgets:**
- infobox (do not clear the screen), msgbox,
- yesno (dialog renames "yes/no" -> "ok/cancel" with --extra-button --help-button).
- checklist, radiolist, menu, mixedlist, treeview, textbox, mixedgauge, datebox,
- timebox, gauge, rangebox, pause.
-
-
- Without resize:
-
- form, inputbox, mixedform, passwordbox, passwordform.
-
-
- Without autosize, resize, F1:
-
- buildlist
-
-
-
-## TODO
-
-
-**Common Options:**
-
-| Option | Status | Note |
-| ---------------------------- | ----------- | ------------------------------- |
-| --cr-wrap | In progress | text |
-| --no-collapse | In progress | text |
-| --no-nl-expand | In progress | text |
-| --trim | In progress | text |
-
-
-To evaluate / Not planned in the short term / not in bsdinstall:
-
---create-rc *file*, --iso-week, --no-mouse, --print-text-only *str h w*,
---print-text-size *str h w*, --reorder, -scrollbar, --separate-widget *string*,
---size-err, --timeout *secs*,--trace *filename*, --visit-items,
---week-start *day*, --keep-tite, --keep-window, --last-key, --no-kill,
---column-separator *string*, --input-fd *fd*, --tab-correct, --tab-len *n*
-
-
-**Widgets:**
-
-To evaluate / Not planned in the short term:
-
-tailbox (textbox/fseek), tailboxbg, dselect, fselect, inputmenu, editbox,
-calendar (use datebox), prgbox, programbox, progressbox.
diff --git a/bsddialog.1 b/bsddialog.1
index bfee3229bd1f..c426c529e242 100644
--- a/bsddialog.1
+++ b/bsddialog.1
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 2021 Alfonso Sabato Siciliano
+.\" Copyright (c) 2021-2022 Alfonso Sabato Siciliano
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -22,45 +22,569 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd December 11, 2021
+.Dd January 26, 2022
.Dt BSDDIALOG 1
.Os
.Sh NAME
.Nm bsddialog
-.Nd terminal dialogs and widgets
+.Nd TUI dialogs
.Sh SYNOPSIS
-.Nm bsddialog
-.Fl -help
-.Nm bsddialog
-.Fl -version
-.Nm bsddialog
-.Op Fl Ar -common-opts
-.Fl Ar -widget
-.Fl Artext
-.Fl Arheight
-.Fl Arwidth
-.Op Fl Ar -widget-opts
+.Nm
+.Fl Fl help
+.Nm
+.Fl Fl version
+.Nm
+.Op Fl Fl common-opts
+.Fl Fl dialog
+.Ar text
+.Ar rows
+.Ar cols
+.Op Ar dialog-opts
.Sh DESCRIPTION
The
-.Nm BSDDialog
-is an utility to write a script with a Text User Interface. It can build
-dialogs and widgets: to show messages, to get input and to inform about a
-computation status.
-.\" .Sh ENVIRONMENT
-.\" For sections 1, 6, 7, and 8 only.
-.\" .Sh FILES
-.\" .Sh EXIT STATUS
-.\" For sections 1, 6, and 8 only.
-.\" .Sh EXAMPLES
-.\" .Sh DIAGNOSTICS
-.\" For sections 1, 4, 6, 7, 8, and 9 printf/stderr messages only.
+.Nm bsddialog
+utility builds Text User Interface dialogs and widgets: to display messages,
+to get input and to inform about a computation status.
+.Pp
+The options
+.Fl Fl help
+and
+.Fl Fl version
+print the list of options and the version, respectively, then exit.
+.Pp
+The following options are available for each dialog.
+.Ar text
+is a message printed inside the dialog, except for
+.Fl Fl textbox
+described later.
+.Ar rows
+and
+.Ar cols
+are the height and width, 0 for autosize and -1 for fullscreen.
+The possible input got from the user interface is printed to standard error.
+.Ss Common options
+The following options can change the default behavior of the utility and are
+common to some dialog.
+.Bl -tag -width Ds
+.It Fl Fl ascii-lines
+Ascii characters to draw lines.
+.It Fl Fl backtitle Ar backtitle
+Title on the top side of the screen.
+.It Fl Fl begin-x Ar x
+Dialog horizontal position, 0 is the left screen side, -1 center.
+.It Fl Fl begin-y Ar y
+Dialog vertical position, 0 is the top screen side, -1 center.
+.It Fl Fl cancel-label Ar label
+Label for the
+.Dq Cancel
+button.
+.It Fl Fl clear
+Hide the dialog at exit.
+.It Fl Fl colors
+Enable highlights for text, the following sequences are considered escapes:
+.Bl -column -compact
+.It Dq \eZ0
+black.
+.It Dq \eZ1
+red.
+.It Dq \eZ2
+green.
+.It Dq \eZ3
+yellow.
+.It Dq \eZ4
+blue.
+.It Dq \eZ5
+magenta.
+.It Dq \eZ6
+cyan.
+.It Dq \eZ7
+white.
+.It Dq \eZr
+reverse foreground and background colors.
+.It Dq \eZR
+disable reverse.
+.It Dq \eZb
+bold.
+.It Dq \eZB
+disable bold.
+.It Dq \eZu
+underline.
+.It Dq \eZU
+disable underline.
+.It Dq \eZn
+restore to normal text.
+.El
+.It Fl Fl cr-wrap
+Replace new line with a space in
+.Ar text .
+.It Fl Fl date-format Ar format
+String accepted by
+.Xr strftime 3
+to customize the output of
+.Fl Fl datebox .
+.It Fl Fl default-button Ar label
+Focus on the button with
+.Ar label
+on startup.
+.It Fl Fl default-item Ar name
+Focus on the item with
+.Ar name ,
+for Checklist, Menu, Radiolist and Treeview.
+.It Fl Fl default-no
+Focus on
+.Dq Cancel
+or
+.Dq \&No
+button on startup.
+.It Fl Fl defaultno
+Equivalent to
+.Fl Fl default-no .
+.It Fl Fl disable-esc
+Disable ESC key to quit.
+.It Fl Fl esc-cancelvalue
+Exits with the
+.Dq Cancel
+button value if the ESC key is pressed.
+.It Fl Fl exit-label Ar label
+Equivalent to
+.Fl Fl ok-label .
+.It Fl Fl extra-button
+Add a button with
+.Dq Extra
+label.
+.It Fl Fl extra-label Ar label
+Set
+.Ar label
+for the
+.Dq Extra
+button.
+.It Fl Fl generic-button1 Ar label
+Add a button with
+.Ar label .
+.It Fl Fl generic-button2 Ar label
+Add a button with
+.Ar label .
+.It Fl Fl help-button
+Add a button with
+.Dq Help
+label.
+.It Fl Fl help-label Ar label
+Set
+.Ar label
+for
+.Dq Help
+button.
+.It Fl Fl help-status
+Print also the selected items if the
+.Dq Help
+button is pressed.
+.It Fl Fl help-tags
+Print the name of the focused item if the Help button is pressed also
+with
+.Fl Fl item-help .
+.It Fl Fl hfile Ar filename
+Open
+.Ar filename
+in a Textbox if F1 key is pressed,
+.It Fl Fl hline Ar string
+Dialog subtitle.
+.It Fl Fl hmsg Ar string
+Open a Msgbox with
+.Ar string
+if the F1 key is pressed.
+.It Fl Fl ignore
+Do not exit with unknown options.
+.It Fl Fl insecure
+Print
+.Sq *
+to hide passwords while typing, default space
+.Sq " " .
+.It Fl Fl item-depth
+Specify a margin for items, available for Checklist, Menu and Radiolist.
+.It Fl Fl item-help
+Set a help string for each element of a Checklist, Form, Menu, Mixedform,
+Passwordform, Radiolist and Treeview to display at the bottom screen side.
+.It Fl Fl item-prefix
+Set a string to prefix each item of a Checklist, Menu, Radiolist or Treeview.
+.It Fl Fl max-input Ar size
+Maximum length of the input for
+.Fl Fl input-box
+ans
+.Fl Fl passwordbox ,
+default 2048.
+.It Fl Fl no-cancel
+Do not show
+.Dq Cancel
+button.
+.It Fl Fl no-collapse
+Do not replace a TAB character with a space in
+.Ar text .
+.It Fl Fl no-items
+Do not display items desciption, for Checklist, Menu, Radiolist or Treeview.
+.It Fl Fl no-label Ar label
+Equivalent to
+.Fl Fl cancel-label .
+.It Fl Fl no-lines
+Do not draw borders and lines.
+.It Fl Fl no-nl-expand
+do not consider the sequence
+.Dq \en
+like new line.
+.It Fl Fl no-ok
+Do not draw
+.Dq OK
+button.
+.It Fl Fl no-shadow
+No not draw the shadow of the dialog.
+.It Fl Fl no-tags
+Do not display items name, for Checklist, Menu and Radiolist.
+.It Fl Fl nocancel
+Equivalent to
+.Fl Fl no-cancel .
+.It Fl Fl nook
+Equivalent to
+.Fl Fl no-ok .
+.It Fl Fl ok-label Ar label
+Set
+.Ar label
+for
+.Dq OK
+button.
+.It Fl Fl output-fd Ar fd
+Print input from user interface to the specified file descriptor.
+.It Fl Fl output-separator Ar sep
+Set a sepator for the items in output, default whitespace.
+.It Fl Fl print-maxsize
+Screen size.
+.It Fl Fl print-size
+Print Dialog height and widget at exit.
+.It Fl Fl print-version
+Print version.
+.It Fl Fl quoted
+Quote items in output, default only when necessary.
+.It Fl Fl separate-output
+Separate selected items with a new line.
+.It Fl Fl separator Ar sep
+Equivalent to
+.Fl Fl output-separator .
+.It Fl Fl shadow
+Show a pseudo shadow for the dialog, enabled by default.
+.It Fl Fl single-quoted
+Use single quote for items in output.
+.It Fl Fl sleep Ar secs
+Wait
+.Ar secs
+seconds to close the dialog.
+.It Fl Fl stderr
+Print input from user interface to standand error, default.
+.It Fl Fl stdout
+Print input from user interface to standard output.
+.It Fl Fl tab-len Ar spaces
+Number of spaces to print a TAB in
+.Ar text .
+.It Fl Fl theme Ar theme
+Set a graphical style: blackwhite, bsddialog, default or dialog.
+.It Fl Fl time-format Ar format
+String accepted by
+.Xr strftime 3
+to customize the output of
+.Fl Fl timebox .
+.It Fl Fl title Ar title
+Dialog title.
+.It Fl Fl trim
+remove consecutive spaces in
+.Ar text .
+.It Fl Fl yes-label Ar label
+Equivalent to
+.Fl Fl ok-label .
+.El
+.Ss Dialogs
+The following dialogs are available:
+.Bl -tag -width Ds
+.It Fl Fl checklist Ar text Ar rows Ar cols Ar menurows Oo Ar name Ar desc \
+Ar status Oc ...
+Checklist to select some item from a list via the SPACE key.
+An item has a
+.Ar name ,
+.Ar desc
+and a default
+.Ar status
+specified by
+.Dq on
+or
+.Dq off .
+The names of the selected items are printed to standard error.
+.Ar menurows
+is the graphical height of the list, 0 for autosize.
+.It Fl Fl datebox Ar text Ar rows Ar cols Op Ar year Ar month Ar day
+Dialog to select a date.
+.It Fl Fl form Ar text Ar rows Ar cols Ar formrows Oo Ar label Ar ylabel \
+Ar xlabel Ar init Ar yfield Ar xfield Ar fieldlen Ar maxvaluelen Oc ...
+Dialog to get a list of strings via forms.
+A form has a
+.Ar label
+at the position
+.Ar ylabel
+and
+.Ar xlabel ,
+a field to get the input at the position
+.Ar yfield
+and
+.Ar xfield
+with graphical length
+.Ar fieldlen ,
+.Ar maxvaluelen
+is the maximum input length.
+The field can be customized, if
+.Ar fieldlen
+is 0 its length is the absolute value of
+.Ar maxvaluelen ,
+if
+.Ar maxvaluelen
+is negative the field is read only,
+.Ar init
+is a default value.
+.Ar formrows
+is the graphical height of the list, has to be at least the number of forms.
+.It Fl Fl gauge Ar text Ar rows Ar cols Op Ar percentage
+Dialog with a bar to shows
+.Ar percentage ,
+then it waits to read
+.Dq XXX
+from the standard input, then the first string replaces percentage and the
+following strings replace
+.Ar text
+until the next
+.Dq XXX ,
+the loop ends reading
+.Dv EOF .
+.It Fl Fl infobox Ar text Ar rows Ar cols
+Dialog without buttons to display a message and to exit immediately.
+.It Fl Fl inputbox Ar text Ar rows Ar cols Op Ar init
+Dialog to get a string in input,
+.Ar init
+is the default value.
+.It Fl Fl menu Ar text Ar rows Ar cols Ar menurows Oo Ar name desc Oc ...
+Builds a menu to select an item from a list.
+An item has a
+.Ar name
+and a
+.Ar desc .
+The name of the selected item is printed to standard error.
+.Ar menurows
+is the graphical height of the list, 0 for autosize.
+.It Fl Fl mixedform Ar text Ar rows Ar cols Ar formrows Oo Ar label Ar ylabel \
+Ar xlabel Ar init Ar yfield Ar xfield Ar fieldlen Ar maxvaluelen Ar flag Oc ...
+Dialog to get a list of strings via forms.
+A form has a
+.Ar label
+at the position
+.Ar ylabel
+and
+.Ar xlabel ,
+a field to get the input with graphical length
+.Ar fieldlen
+at the position
+.Ar yfield
+and
+.Ar xfield ,
+.Ar maxvaluelen
+is the maximum input length,
+.Ar init
+is a default value,
+.Ar flag
+can be 0 for normal field, 1 to hide the typed characters and 2 to set the
+field read only.
+.Ar formrows
+is the graphical height of the list, has to be at least the number of forms.
+.It Fl Fl mixedgauge Ar text Ar rows Ar cols Ar mainperc Oo Ar minilabel \
+Ar miniperc Oc ...
+Dialog to show a main bar to represent
+.Ar mainperc
+from 0 to 100 and some mini bar with a
+.Ar minilabel
+string and a
+.Ar miniperc
+with value from 0 and 100 or negative to print a descriptive string: -1
+.Dq Succeeded ,
+-2
+.Dq Failed ,
+-3
+.Dq Passed ,
+-4
+.Dq Completed ,
+-5
+.Dq Checked ,
+-6
+.Dq Done ,
+-7
+.Dq Skipped ,
+-8
+.Dq \&In Progress ,
+-9
+a blank line,
+-10
+.Dq N/A ,
+-11
+.Dq Pending .
+.It Fl Fl msgbox Ar text Ar rows Ar cols
+Dialog to diplay a message without the
+.Dq Cancel
+button.
+.It Fl Fl passwordbox Ar text Ar rows Ar cols Op Ar init
+Dialog to get a password,
+.Ar init
+is the default value.
+.It Fl Fl passwordform Ar text Ar rows Ar cols Ar formrows Oo Ar label \
+Ar ylabel Ar xlabel Ar init Ar yfield Ar xfield Ar fieldlen Ar valuelen Oc ...
+Dialog to get a list of passwords, equivalent to
+.Fl Fl form
+except typed characters are hidden.
+.It Fl Fl pause Ar text Ar rows Ar cols Ar seconds
+Dialog runs until the timeout in
+.Ar seconds
+expires or a button is pressed.
+.It Fl Fl radiolist Ar text Ar rows Ar cols Ar menurows Oo Ar name Ar desc \
+Ar status Oc ...
+Radiolist to select at most an item from a list via the SPACE key.
+An item has a
+.Ar name ,
+.Ar desc
+and a default
+.Ar status
+specified by
+.Dq on
+or
+.Dq off .
+The name of the selected item is printed to standard error.
+.Ar menurows
+is the graphical height of the list, 0 for autosize.
+.It Fl Fl rangebox Ar text Ar rows Ar cols Ar min Ar max Op Ar init
+Dialog to select a value between
+.Ar min
+and
+.Ar max ,
+.Ar init
+is the default value, the keys UP, DOWN, HOME, END, PAGEUP and PAGEDOWN can
+change it.
+.It Fl Fl textbox Ar file Ar rows Ar cols
+Opens and prints
+.Ar file
+the UP, DOWN, HOME, END, PAGEUP and PAGEDOWN keys are availble to navigate;
+.Dq OK
+button is renamed
+.Dq EXIT .
+.It Fl Fl timebox Ar text Ar rows Ar cols Op Ar hour Ar min Ar sec
+Dialog to select a time.
+.It Fl Fl treeview Ar text Ar rows Ar cols Ar menurows Oo Ar depth Ar name \
+Ar desc Ar status Oc ...
+Equivalent to Radiolist with
+.Fl Fl item-depth
+and
+.Fl Fl no-name .
+.It Fl Fl yesno Ar text Ar rows Ar cols
+.Dq Yes-No Question ,
+.Dq OK
+and
+.Dq Cancel
+buttons are renamed
+.Dq Yes
+and
+.Dq \&No .
+.El
+.Sh EXIT STATUS
+The
+.Nm
+utility exits 255 on unsuccessful, otherwise depending on the button or key
+pressed the following values can be returned:
+.Bl -column -compact
+.It 0
+.Dq OK ,
+.Dq Yes
+or
+.Dq Exit
+button.
+.It 1
+.Dq Cancel
+or
+.Dq \&No
+button.
+.It 2
+.Dq Help
+button.
+.It 3
+.Dq Extra
+button.
+.It 4
+Timeout.
+.It 5
+ESC key.
+.It 6
+Generic 1 button.
+.It 7
+Generic 2 button.
+.El
+.Sh EXAMPLES
+Backtitle, title and message:
+.Dl bsddialog --backtitle MESSAGE --title Msgbox --msgbox Message 0 0
+.Pp
+Yes-No Question and theme:
+.Dl bsddialog --theme blackwhite --yesno Question 10 30
+.Pp
+Checklist:
+.Dl bsddialog --checklist Checklist 0 0 3 N1 \&D1 off N2 D2 on N3 D3 off
+.Pp
+Mixedgauge:
+.Dl bsddialog --sleep 3 --mixedgauge Example 10 30 60 L1 "\(dq" -1" L2 30
+.Pp
+Form:
+.Dl bsddialog --form Form 0 0 2 L1: 1 1 X 1 5 20 25 L2: 2 1 X 2 5 20 25
+.Pp
+Gauge script:
+.Bd -literal -offset indent -compact
+i=1
+for c in A B C D E F G H
+do
+ sleep 1
+ echo XXX
+ echo "$(expr $(expr $i "*" 100) "/" 8)"
+ echo "[$i/8] Char: $c"
+ echo XXX
+ if [ $i -eq 8 ]
+ then
+ sleep 1
+ echo EOF
+ fi
+ i=`expr $i + 1`
+done | bsddialog --title Gauge --gauge "Starting..." 10 70
+.Ed
+.Pp
+Mixedgauge script:
+.Bd -literal -offset indent -compact
+perc=0
+while [ $perc -le 100 ]
+do
+ bsddialog --sleep 1 --title Mixedgauge \e
+ --mixedgauge "\enExample...\en" 0 0 $perc \e
+ "Hidden" " -9" \e
+ "Label 1" " -4" \e
+ "Label 2" " -4" \e
+ "Label 3" $perc
+
+ perc=`expr $perc + 20`
+done
+.Ed
.Sh SEE ALSO
.Xr bsddialog 3
-.\" .Sh HISTORY
-.\" .Sh AUTHORS
-.Sh CAVEATS
-autosize
-compatibility text
+.Sh HISTORY
+The
+.Nm bsddialog
+utility first appeared in
+.Fx 14.0 .
+.Sh AUTHORS
+.Nm bsddialog
+was written by
+.An Alfonso Sabato Siciliano Aq Mt alf.siciliano@gmail.com .
.Sh BUGS
-buildlist
-forms
+The forms do not resize the dialog after a terminal change and does not provides
+scrolling for items. \ No newline at end of file
diff --git a/bsddialog.c b/bsddialog.c
index aa87dec2962b..6bd11fd458b8 100644
--- a/bsddialog.c
+++ b/bsddialog.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,6 +28,8 @@
#include <sys/ioctl.h>
#include <getopt.h>
+#include <locale.h>
+#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -37,12 +39,11 @@
#include <bsddialog.h>
#include <bsddialog_theme.h>
-#define BSDDIALOG_VERSION "0.0.1"
+#define BSDDIALOG_VERSION "0.1"
enum OPTS {
/* Common options */
ASCII_LINES = '?' + 1,
- ASPECT_RATIO,
BACKTITLE,
BEGIN_X,
BEGIN_Y,
@@ -51,19 +52,24 @@ enum OPTS {
COLORS,
CR_WRAP,
DATE_FORMAT,
- DEFAULTNO,
DEFAULT_BUTTON,
DEFAULT_ITEM,
+ DEFAULT_NO,
+ DISABLE_ESC,
+ ESC_CANCELVALUE,
EXIT_LABEL,
EXTRA_BUTTON,
EXTRA_LABEL,
+ GENERIC_BUTTON1,
+ GENERIC_BUTTON2,
HELP,
HELP_BUTTON,
HELP_LABEL,
HELP_STATUS,
HELP_TAGS,
- HFILE,
+ HFILE,
HLINE,
+ HMSG,
IGNORE,
INSECURE,
ITEM_DEPTH,
@@ -71,16 +77,13 @@ enum OPTS {
ITEM_PREFIX,
MAX_INPUT,
NO_CANCEL,
- NOCANCEL,
NO_COLLAPSE,
NO_ITEMS,
- NO_LABEL,
NO_LINES,
NO_NL_EXPAND,
NO_OK,
- NOOK,
- NO_TAGS,
NO_SHADOW,
+ NO_TAGS,
OK_LABEL,
OUTPUT_FD,
OUTPUT_SEPARATOR,
@@ -89,20 +92,18 @@ enum OPTS {
PRINT_VERSION,
QUOTED,
SEPARATE_OUTPUT,
- SEPARATOR,
SHADOW,
SINGLE_QUOTED,
SLEEP,
STDERR,
STDOUT,
+ TAB_LEN,
THEME,
TIME_FORMAT,
TITLE,
TRIM,
VERSION,
- YES_LABEL,
- /* Widgets */
- BUILDLIST,
+ /* Dialogs */
CHECKLIST,
DATEBOX,
FORM,
@@ -121,277 +122,245 @@ enum OPTS {
TEXTBOX,
TIMEBOX,
TREEVIEW,
- YESNO,
+ YESNO
};
-/* libbsddialog does not support NULL string for now */
-static char *nostring = "";
/* Menus flags and options */
-static bool item_prefix_flag, item_bottomdesc_flag, item_output_sepnl_flag;
-static bool item_singlequote_flag, list_items_on_flag, item_tag_help_flag;
-static bool item_always_quote_flag, item_depth_flag;
-static char *item_output_sep_flag;
+static bool item_prefix_opt, item_bottomdesc_opt, item_output_sepnl_opt;
+static bool item_singlequote_opt, list_items_on_opt, item_tag_help_opt;
+static bool item_always_quote_opt, item_depth_opt;
+static char *item_output_sep_opt, *item_default_opt;
/* Time and calendar options */
-static char *date_fmt_flag, *time_fmt_flag;
+static char *date_fmt_opt, *time_fmt_opt;
/* Forms */
-static int max_input_form_flag;
+static int unsigned max_input_form_opt;
/* General flags and options */
-static int output_fd_flag;
-
-void usage(void);
-/* widgets */
-#define BUILDER_ARGS struct bsddialog_conf conf, char* text, int rows, \
- int cols, int argc, char **argv, char *errbuf
-int buildlist_builder(BUILDER_ARGS);
-int checklist_builder(BUILDER_ARGS);
-int datebox_builder(BUILDER_ARGS);
-int form_builder(BUILDER_ARGS);
-int gauge_builder(BUILDER_ARGS);
-int infobox_builder(BUILDER_ARGS);
-int inputbox_builder(BUILDER_ARGS);
-int menu_builder(BUILDER_ARGS);
-int mixedform_builder(BUILDER_ARGS);
-int mixedgauge_builder(BUILDER_ARGS);
-int msgbox_builder(BUILDER_ARGS);
-int passwordbox_builder(BUILDER_ARGS);
-int passwordform_builder(BUILDER_ARGS);
-int pause_builder(BUILDER_ARGS);
-int radiolist_builder(BUILDER_ARGS);
-int rangebox_builder(BUILDER_ARGS);
-int textbox_builder(BUILDER_ARGS);
-int timebox_builder(BUILDER_ARGS);
-int treeview_builder(BUILDER_ARGS);
-int yesno_builder(BUILDER_ARGS);
+static int output_fd_opt;
static void
custom_text(bool cr_wrap, bool no_collapse, bool no_nl_expand, bool trim,
- char *text, char *buf)
-{
- int i, j;
-
- i = j = 0;
- while (text[i] != '\0') {
- switch (text[i]) {
- case '\\':
- buf[j] = '\\';
- switch (text[i+1]) {
- case '\\':
- i++;
- break;
- case 'n':
- if (no_nl_expand) {
- j++;
- buf[j] = 'n';
- } else
- buf[j] = '\n';
- i++;
- break;
- case 't':
- if (no_collapse) {
- j++;
- buf[j] = 't';
- } else
- buf[j] = '\t';
- i++;
- break;
- }
- break;
- case '\n':
- buf[j] = cr_wrap ? ' ' : '\n';
- break;
- case '\t':
- buf[j] = no_collapse ? '\t' : ' ';
- break;
- default:
- buf[j] = text[i];
- }
- i++;
- j += (buf[j] == ' ' && trim && j > 0 && buf[j-1] == ' ') ?
- 0 : 1;
- }
- buf[j] = '\0';
-}
+ char *text, char *buf);
+
+static void sigint_handler(int sig);
-void usage(void)
+/* Dialogs */
+#define BUILDER_ARGS struct bsddialog_conf conf, char* text, int rows, \
+ int cols, int argc, char **argv, char *errbuf
+static int checklist_builder(BUILDER_ARGS);
+static int datebox_builder(BUILDER_ARGS);
+static int form_builder(BUILDER_ARGS);
+static int gauge_builder(BUILDER_ARGS);
+static int infobox_builder(BUILDER_ARGS);
+static int inputbox_builder(BUILDER_ARGS);
+static int menu_builder(BUILDER_ARGS);
+static int mixedform_builder(BUILDER_ARGS);
+static int mixedgauge_builder(BUILDER_ARGS);
+static int msgbox_builder(BUILDER_ARGS);
+static int passwordbox_builder(BUILDER_ARGS);
+static int passwordform_builder(BUILDER_ARGS);
+static int pause_builder(BUILDER_ARGS);
+static int radiolist_builder(BUILDER_ARGS);
+static int rangebox_builder(BUILDER_ARGS);
+static int textbox_builder(BUILDER_ARGS);
+static int timebox_builder(BUILDER_ARGS);
+static int treeview_builder(BUILDER_ARGS);
+static int yesno_builder(BUILDER_ARGS);
+
+static void usage(void)
{
-
- printf("usage: bsddialog --help\n"
- " bsddialog --version\n"
- " bsddialog [--<common-opts>] --<widget> <text> "
- "<height> <width> [--<widget-opts>]\n");
+ printf("usage: bsddialog --help\n");
+ printf(" bsddialog --version\n");
+ printf(" bsddialog [--<common-opts>] --<dialog> <text> <rows> "
+ "<cols> [--<dialog-opts>]\n");
printf("\n");
+
printf("Common Options:\n");
- printf("--ascii-lines, --aspect <ratio>, --backtitle <backtitle>, "
- "--begin-x <x>, --begin-y <y>, --cancel-label <string>, "
- "--clear, --colors, --date-format <format>, "
- "--default-button <label>, --defaultno, --default-item <name>,"
- "--exit-label <label>, --extra-button, --extra-label <label>,"
- "--hfile <filename>, --help-button, --help-label <label>, "
- "--help-status, --help-tags, --hline string, --ignore, "
- "--insecure, --item-depth, --item-help, --items-prefix, "
- "--max-input <size>, --no-cancel, --nocancel, "
- "--no-label <label>, --no-items, "
- "--no-lines, --no-ok, --nook, --no-shadow, --no-tags, "
- "--ok-label <label>, --output-fd <fd>, "
- "--output-separator <sep>, --print-version, --print-size, "
- "--quoted, --print-maxsize, --shadow, --single-quoted, "
- "--separator <sep>, --separate-output, --sleep <secs>, "
- "--stderr, --stdout, --theme <blackwhite|bsddialog|dialog>, "
- "--time-format <format>, --title <title>, "
- "--yes-label <string>.\n");
+ printf("--ascii-lines, --backtitle <backtitle>, --begin-x <x>, "
+ "--begin-y <y>, --cancel-label <label>, --clear, --colors, "
+ "--cr-wrap, --date-format <format>, --defaultno, "
+ "--default-button <label>, --default-no, --default-item <name>, "
+ "--disable-esc, --esc-cancelvalue, --exit-label <label>, "
+ "--extra-button, --extra-label <label>, "
+ "--generic-button1 <label>, --generic-button2 <label>, --help, "
+ "--help-button, --help-label <label>, --help-status, --help-tags, "
+ "--hfile <filename>, --hline <string>, --hmsg <string>, --ignore, "
+ "--insecure, --item-depth, --item-help, --items-prefix, "
+ "--max-input <size>, --no-cancel, --nocancel, --no-collapse, "
+ "--no-items, --no-label <label>, --no-lines, --no-nl-expand, "
+ "--no-ok, --nook, --no-shadow, --no-tags, --ok-label <label>, "
+ "--output-fd <fd>, --output-separator <sep>, --print-maxsize, "
+ "--print-size, --print-version, --quoted, --separate-output, "
+ "--separator <sep>, --shadow, --single-quoted, --sleep <secs>, "
+ "--stderr, --stdout, --tab-len <spaces>, "
+ "--theme <blackwhite|bsddialog|default|dialog>, "
+ "--time-format <format>, --title <title>, --trim, --version, "
+ "--yes-label <label>.\n");
printf("\n");
- printf("Widgets:\n");
- printf("--buildlist <text> <rows> <cols> <menurows> [<name> <desc> "
- "<on|off> ...]\n"
- "--checklist <text> <rows> <cols> <menurows> [<name> <desc> "
- "<on|off> ...]\n"
- "--datebox <text> <rows> <cols> [<yy> <mm> <dd>]\n"
- "--form <text> <rows> <cols> <formrows> [<label> <ylabel> "
- "<xlabel> <init> <yfield> <xfield> <fieldlen> <maxvalue> "
- "...]\n"
- "--gauge <text> <rows> <cols> [<perc\\n> [<text> ...] XXX "
- "...] EOF\n"
- "--infobox <text> <rows> <cols>\n"
- "--inputbox <text> <rows> <cols> [init]\n"
- "--menu <text> <rows> <cols> <menurows> [<name> <desc> ...]\n"
- "--mixedform <text> <rows> <cols> <formrows> [<label> <ylabel> "
- "<xlabe> <init> <yfield> <xfield> <fieldlen> <maxvalue> "
- "<0|1|2> ...]\n"
- "--mixedgauge <text> <rows> <cols> <mainperc> [<label> "
- "<01234567|-perc> ...]\n"
- "--msgbox <text> <rows> <cols>\n"
- "--passwordbox <text> <rows> <cols> [init]\n"
- "--passwordform <text> <rows> <cols> <formrows> [<label> "
- "<ylabel> <xlabe> <init> <yfield> <xfield> <fieldlen> "
- "<maxvalue> ...]\n"
- "--pause <text> <rows> <cols> <secs>\n"
- "--radiolist <text> <rows> <cols> <menurows> [<name> <desc> "
- "<on|off> ...]\n"
- "--rangebox <text> <rows> <cols> <min> <max> <default>\n"
- "--textbox <file> <rows> <cols>\n"
- "--timebox <text> <rows> <cols> [<hh> <mm> <ss>]\n"
- "--treeview <text> <rows> <cols> <menurows> [<depth> <name> "
- "<desc> <on|off> ...]\n"
- "--yesno <text> <rows> <cols>\n");
+
+ printf("Dialogs:\n");
+ printf("--checklist <text> <rows> <cols> <menurows> [<name> <desc> "
+ "<on|off>] ...\n");
+ printf("--datebox <text> <rows> <cols> [<yy> <mm> <dd>]\n");
+ printf("--form <text> <rows> <cols> <formrows> [<label> <ylabel> "
+ "<xlabel> <init> <yfield> <xfield> <fieldlen> <maxvaluelen>] "
+ "...\n");
+ printf("--gauge <text> <rows> <cols> [<perc>]\n");
+ printf("--infobox <text> <rows> <cols>\n");
+ printf("--inputbox <text> <rows> <cols> [init]\n");
+ printf("--menu <text> <rows> <cols> <menurows> [<name> <desc>] ...\n");
+ printf("--mixedform <text> <rows> <cols> <formrows> [<label> <ylabel> "
+ "<xlabel> <init> <yfield> <xfield> <fieldlen> <maxvaluelen> "
+ "<0|1|2>] ...\n");
+ printf("--mixedgauge <text> <rows> <cols> <mainperc> [<minilabel> "
+ "<miniperc>] ...\n");
+ printf("--msgbox <text> <rows> <cols>\n");
+ printf("--passwordbox <text> <rows> <cols> [init]\n");
+ printf("--passwordform <text> <rows> <cols> <formrows> [<label> "
+ "<ylabel> <xlabel> <init> <yfield> <xfield> <fieldlen> "
+ "<maxvaluelen>] ...\n");
+ printf("--pause <text> <rows> <cols> <secs>\n");
+ printf("--radiolist <text> <rows> <cols> <menurows> [<name> <desc> "
+ "<on|off>] ...\n");
+ printf("--rangebox <text> <rows> <cols> <min> <max> [<init>]\n");
+ printf("--textbox <file> <rows> <cols>\n");
+ printf("--timebox <text> <rows> <cols> [<hh> <mm> <ss>]\n");
+ printf("--treeview <text> <rows> <cols> <menurows> [<depth> <name> "
+ "<desc> <on|off>] ...\n");
+ printf("--yesno <text> <rows> <cols>\n");
+ printf("\n");
+
+ printf("See 'man 1 bsddialog' for more information.\n");
}
int main(int argc, char *argv[argc])
{
- char *text, *backtitle_flag, errorbuilder[1024];
+ bool cr_wrap_opt, no_collapse_opt, no_nl_expand_opt, trim_opt;
+ bool esc_cancelvalue_opt, ignore_opt, print_maxsize_opt;;
int input, rows, cols, output, getH, getW;
- int (*widgetbuilder)(BUILDER_ARGS) = NULL;
- bool ignore_flag, print_maxsize_flag;
+ int (*dialogbuilder)(BUILDER_ARGS) = NULL;
+ enum bsddialog_default_theme theme_opt;
+ char *text, *backtitle_opt, errorbuilder[1024];
struct winsize ws;
struct bsddialog_conf conf;
- enum bsddialog_default_theme theme_flag;
- bool cr_wrap_flag, no_collapse_flag, no_nl_expand_flag, trim_flag;
- bsddialog_initconf(&conf);
+ setlocale(LC_ALL, "");
- backtitle_flag = NULL;
- theme_flag = -1;
- output_fd_flag = STDERR_FILENO;
- print_maxsize_flag = false;
- ignore_flag = false;
+ bsddialog_initconf(&conf);
+ conf.key.enable_esc = true;
+ conf.menu.on_without_ok = true;
+ conf.form.value_without_ok = true;
+
+ backtitle_opt = NULL;
+ theme_opt = BSDDIALOG_THEME_DEFAULT;
+ output_fd_opt = STDERR_FILENO;
+ print_maxsize_opt = false;
+ ignore_opt = false;
errorbuilder[0] = '\0';
- cr_wrap_flag = no_collapse_flag = no_nl_expand_flag = trim_flag = false;
+ cr_wrap_opt = no_collapse_opt = no_nl_expand_opt = trim_opt = false;
+ esc_cancelvalue_opt = false;
+
+ item_output_sepnl_opt = item_singlequote_opt = false;
+ item_prefix_opt = item_bottomdesc_opt = item_depth_opt = false;
+ list_items_on_opt = item_tag_help_opt = false;
+ item_always_quote_opt = false;
+ item_output_sep_opt = NULL;
+ item_default_opt = NULL;
- item_output_sepnl_flag = item_singlequote_flag = false;
- item_prefix_flag = item_bottomdesc_flag = item_depth_flag = false;
- list_items_on_flag = item_tag_help_flag = false;
- item_always_quote_flag = false;
- item_output_sep_flag = NULL;
+ date_fmt_opt = time_fmt_opt = NULL;
- date_fmt_flag = time_fmt_flag = NULL;
-
- max_input_form_flag = 0;
+ max_input_form_opt = 0;
/* options descriptor */
struct option longopts[] = {
- /* common options */
- {"ascii-lines", no_argument, NULL, ASCII_LINES },
- {"aspect", required_argument, NULL, ASPECT_RATIO },
- {"backtitle", required_argument, NULL, BACKTITLE },
- {"begin-x", required_argument, NULL, BEGIN_X },
- {"begin-y", required_argument, NULL, BEGIN_Y },
- {"cancel-label", required_argument, NULL, CANCEL_LABEL },
- {"clear", no_argument, NULL, CLEAR },
- {"colors", no_argument, NULL, COLORS },
- {"cr-wrap", no_argument, NULL, CR_WRAP },
- {"date-format", required_argument, NULL, DATE_FORMAT },
- {"defaultno", no_argument, NULL, DEFAULTNO },
- {"default-button", required_argument, NULL, DEFAULT_BUTTON },
- {"default-item", required_argument, NULL, DEFAULT_ITEM },
- {"exit-label", required_argument, NULL, EXIT_LABEL },
- {"extra-button", no_argument, NULL, EXTRA_BUTTON },
- {"extra-label", required_argument, NULL, EXTRA_LABEL },
- {"help", no_argument, NULL, HELP },
- {"help-button", no_argument, NULL, HELP_BUTTON },
- {"help-label", required_argument, NULL, HELP_LABEL },
- {"help-status", no_argument, NULL, HELP_STATUS },
- {"help-tags", no_argument, NULL, HELP_TAGS },
- {"hfile", required_argument, NULL, HFILE },
- {"hline", required_argument, NULL, HLINE },
- {"ignore", no_argument, NULL, IGNORE },
- {"insecure", no_argument, NULL, INSECURE },
- {"item-depth", no_argument, NULL, ITEM_DEPTH },
- {"item-help", no_argument, NULL, ITEM_HELP },
- {"item-prefix", no_argument, NULL, ITEM_PREFIX },
- {"max-input", required_argument, NULL, MAX_INPUT },
- {"no-cancel", no_argument, NULL, NO_CANCEL },
- {"nocancel", no_argument, NULL, NOCANCEL },
- {"no-collapse", no_argument, NULL, NO_COLLAPSE },
- {"no-items", no_argument, NULL, NO_ITEMS },
- {"no-label", required_argument, NULL, NO_LABEL },
- {"no-lines", no_argument, NULL, NO_LINES },
- {"no-nl-expand", no_argument, NULL, NO_NL_EXPAND },
- {"no-ok", no_argument, NULL, NO_OK },
- {"nook ", no_argument, NULL, NOOK },
- {"no-tags", no_argument, NULL, NO_TAGS },
- {"no-shadow", no_argument, NULL, NO_SHADOW },
- {"ok-label", required_argument, NULL, OK_LABEL },
- {"output-fd", required_argument, NULL, OUTPUT_FD },
- {"separator", required_argument, NULL, SEPARATOR },
- {"output-separator",required_argument, NULL, OUTPUT_SEPARATOR },
- {"print-maxsize", no_argument, NULL, PRINT_MAXSIZE },
- {"print-size", no_argument, NULL, PRINT_SIZE },
- {"print-version", no_argument, NULL, PRINT_VERSION },
- {"quoted", no_argument, NULL, QUOTED },
- {"separate-output", no_argument, NULL, SEPARATE_OUTPUT },
- {"shadow", no_argument, NULL, SHADOW },
- {"single-quoted", no_argument, NULL, SINGLE_QUOTED },
- {"sleep", required_argument, NULL, SLEEP },
- {"stderr", no_argument, NULL, STDERR },
- {"stdout", no_argument, NULL, STDOUT },
- {"theme_flag", required_argument, NULL, THEME },
- {"time-format", required_argument, NULL, TIME_FORMAT },
- {"title", required_argument, NULL, TITLE },
- {"trim", no_argument, NULL, TRIM },
- {"version", no_argument, NULL, VERSION },
- {"yes-label", required_argument, NULL, YES_LABEL },
- /* Widgets */
- {"buildlist", no_argument, NULL, BUILDLIST },
- {"checklist", no_argument, NULL, CHECKLIST },
- {"datebox", no_argument, NULL, DATEBOX },
- {"form", no_argument, NULL, FORM },
- {"gauge", no_argument, NULL, GAUGE },
- {"infobox", no_argument, NULL, INFOBOX },
- {"inputbox", no_argument, NULL, INPUTBOX },
- {"menu", no_argument, NULL, MENU },
- {"mixedform", no_argument, NULL, MIXEDFORM },
- {"mixedgauge", no_argument, NULL, MIXEDGAUGE },
- {"msgbox", no_argument, NULL, MSGBOX },
- {"passwordbox", no_argument, NULL, PASSWORDBOX },
- {"passwordform", no_argument, NULL, PASSWORDFORM },
- {"pause", no_argument, NULL, PAUSE },
- {"radiolist", no_argument, NULL, RADIOLIST },
- {"rangebox", no_argument, NULL, RANGEBOX },
- {"textbox", no_argument, NULL, TEXTBOX },
- {"timebox", no_argument, NULL, TIMEBOX },
- {"treeview", no_argument, NULL, TREEVIEW },
- {"yesno", no_argument, NULL, YESNO },
- /* END */
- { NULL, 0, NULL, 0 }
+ /* common options */
+ {"ascii-lines", no_argument, NULL, ASCII_LINES},
+ {"backtitle", required_argument, NULL, BACKTITLE},
+ {"begin-x", required_argument, NULL, BEGIN_X},
+ {"begin-y", required_argument, NULL, BEGIN_Y},
+ {"cancel-label", required_argument, NULL, CANCEL_LABEL},
+ {"clear", no_argument, NULL, CLEAR},
+ {"colors", no_argument, NULL, COLORS},
+ {"cr-wrap", no_argument, NULL, CR_WRAP},
+ {"date-format", required_argument, NULL, DATE_FORMAT},
+ {"defaultno", no_argument, NULL, DEFAULT_NO},
+ {"default-button", required_argument, NULL, DEFAULT_BUTTON},
+ {"default-item", required_argument, NULL, DEFAULT_ITEM},
+ {"default-no", no_argument, NULL, DEFAULT_NO},
+ {"disable-esc", no_argument, NULL, DISABLE_ESC},
+ {"esc-cancelvalue", no_argument, NULL, ESC_CANCELVALUE},
+ {"exit-label", required_argument, NULL, EXIT_LABEL},
+ {"extra-button", no_argument, NULL, EXTRA_BUTTON},
+ {"extra-label", required_argument, NULL, EXTRA_LABEL},
+ {"generic-button1", required_argument, NULL, GENERIC_BUTTON1},
+ {"generic-button2", required_argument, NULL, GENERIC_BUTTON2},
+ {"help", no_argument, NULL, HELP},
+ {"help-button", no_argument, NULL, HELP_BUTTON},
+ {"help-label", required_argument, NULL, HELP_LABEL},
+ {"help-status", no_argument, NULL, HELP_STATUS},
+ {"help-tags", no_argument, NULL, HELP_TAGS},
+ {"hfile", required_argument, NULL, HFILE},
+ {"hline", required_argument, NULL, HLINE},
+ {"hmsg", required_argument, NULL, HMSG},
+ {"ignore", no_argument, NULL, IGNORE},
+ {"insecure", no_argument, NULL, INSECURE},
+ {"item-depth", no_argument, NULL, ITEM_DEPTH},
+ {"item-help", no_argument, NULL, ITEM_HELP},
+ {"item-prefix", no_argument, NULL, ITEM_PREFIX},
+ {"max-input", required_argument, NULL, MAX_INPUT},
+ {"no-cancel", no_argument, NULL, NO_CANCEL},
+ {"nocancel", no_argument, NULL, NO_CANCEL},
+ {"no-collapse", no_argument, NULL, NO_COLLAPSE},
+ {"no-items", no_argument, NULL, NO_ITEMS},
+ {"no-label", required_argument, NULL, CANCEL_LABEL},
+ {"no-lines", no_argument, NULL, NO_LINES},
+ {"no-nl-expand", no_argument, NULL, NO_NL_EXPAND},
+ {"no-ok", no_argument, NULL, NO_OK},
+ {"nook ", no_argument, NULL, NO_OK},
+ {"no-shadow", no_argument, NULL, NO_SHADOW},
+ {"no-tags", no_argument, NULL, NO_TAGS},
+ {"ok-label", required_argument, NULL, OK_LABEL},
+ {"output-fd", required_argument, NULL, OUTPUT_FD},
+ {"output-separator", required_argument, NULL, OUTPUT_SEPARATOR},
+ {"print-maxsize", no_argument, NULL, PRINT_MAXSIZE},
+ {"print-size", no_argument, NULL, PRINT_SIZE},
+ {"print-version", no_argument, NULL, PRINT_VERSION},
+ {"quoted", no_argument, NULL, QUOTED},
+ {"separate-output", no_argument, NULL, SEPARATE_OUTPUT},
+ {"separator", required_argument, NULL, OUTPUT_SEPARATOR},
+ {"shadow", no_argument, NULL, SHADOW},
+ {"single-quoted", no_argument, NULL, SINGLE_QUOTED},
+ {"sleep", required_argument, NULL, SLEEP},
+ {"stderr", no_argument, NULL, STDERR},
+ {"stdout", no_argument, NULL, STDOUT},
+ {"tab-len", required_argument, NULL, TAB_LEN},
+ {"theme", required_argument, NULL, THEME},
+ {"time-format", required_argument, NULL, TIME_FORMAT},
+ {"title", required_argument, NULL, TITLE},
+ {"trim", no_argument, NULL, TRIM},
+ {"version", no_argument, NULL, VERSION},
+ {"yes-label", required_argument, NULL, OK_LABEL},
+ /* Dialogs */
+ {"checklist", no_argument, NULL, CHECKLIST},
+ {"datebox", no_argument, NULL, DATEBOX},
+ {"form", no_argument, NULL, FORM},
+ {"gauge", no_argument, NULL, GAUGE},
+ {"infobox", no_argument, NULL, INFOBOX},
+ {"inputbox", no_argument, NULL, INPUTBOX},
+ {"menu", no_argument, NULL, MENU},
+ {"mixedform", no_argument, NULL, MIXEDFORM},
+ {"mixedgauge", no_argument, NULL, MIXEDGAUGE},
+ {"msgbox", no_argument, NULL, MSGBOX},
+ {"passwordbox", no_argument, NULL, PASSWORDBOX},
+ {"passwordform", no_argument, NULL, PASSWORDFORM},
+ {"pause", no_argument, NULL, PAUSE},
+ {"radiolist", no_argument, NULL, RADIOLIST},
+ {"rangebox", no_argument, NULL, RANGEBOX},
+ {"textbox", no_argument, NULL, TEXTBOX},
+ {"timebox", no_argument, NULL, TIMEBOX},
+ {"treeview", no_argument, NULL, TREEVIEW},
+ {"yesno", no_argument, NULL, YESNO},
+ /* END */
+ { NULL, 0, NULL, 0}
};
while ((input = getopt_long(argc, argv, "", longopts, NULL)) != -1) {
@@ -400,30 +369,23 @@ int main(int argc, char *argv[argc])
case ASCII_LINES:
conf.ascii_lines = true;
break;
- case ASPECT_RATIO:
- conf.aspect_ratio = atoi(optarg);
- if (conf.aspect_ratio < 1) {
- printf("Error: aspect cannot be < 1");
- return (BSDDIALOG_ERROR);
- }
- break;
case BACKTITLE:
- backtitle_flag = optarg;
+ backtitle_opt = optarg;
break;
case BEGIN_X:
- conf.x = atoi(optarg);
+ conf.x = (int)strtol(optarg, NULL, 10);
if (conf.x < BSDDIALOG_CENTER) {
- printf("Error: --begin-x %d, cannot be < %d",
+ printf("Error: --begin-x %d < %d",
conf.x, BSDDIALOG_CENTER);
- return (BSDDIALOG_ERROR);
+ return (255);
}
break;
case BEGIN_Y:
- conf.y = atoi(optarg);
+ conf.y = (int)strtol(optarg, NULL, 10);
if (conf.y < BSDDIALOG_CENTER) {
- printf("Error: --begin-y %d, cannot be < %d",
+ printf("Error: --begin-y %d < %d",
conf.y, BSDDIALOG_CENTER);
- return (BSDDIALOG_ERROR);
+ return (255);
}
break;
case CANCEL_LABEL:
@@ -433,25 +395,31 @@ int main(int argc, char *argv[argc])
conf.clear = true;
break;
case COLORS:
- conf.text.colors = true;
+ conf.text.highlight = true;
break;
case CR_WRAP:
- cr_wrap_flag = true;
+ cr_wrap_opt = true;
break;
case DATE_FORMAT:
- date_fmt_flag = optarg;
+ date_fmt_opt = optarg;
break;
case DEFAULT_BUTTON:
conf.button.default_label = optarg;
break;
case DEFAULT_ITEM:
- conf.menu.default_item = optarg;
+ item_default_opt = optarg;
break;
- case DEFAULTNO:
+ case DEFAULT_NO:
conf.button.default_cancel = true;
break;
+ case DISABLE_ESC:
+ conf.key.enable_esc = false;
+ break;
+ case ESC_CANCELVALUE:
+ esc_cancelvalue_opt = true;
+ break;
case EXIT_LABEL:
- conf.button.exit_label = optarg;
+ conf.button.ok_label = optarg;
break;
case EXTRA_BUTTON:
conf.button.with_extra = true;
@@ -459,6 +427,12 @@ int main(int argc, char *argv[argc])
case EXTRA_LABEL:
conf.button.extra_label = optarg;
break;
+ case GENERIC_BUTTON1:
+ conf.button.generic1_label = optarg;
+ break;
+ case GENERIC_BUTTON2:
+ conf.button.generic2_label = optarg;
+ break;
case HELP:
usage();
return (BSDDIALOG_OK);
@@ -469,10 +443,10 @@ int main(int argc, char *argv[argc])
conf.button.help_label = optarg;
break;
case HELP_STATUS:
- list_items_on_flag = true;
+ list_items_on_opt = true;
break;
case HELP_TAGS:
- item_tag_help_flag = true;
+ item_tag_help_opt = true;
break;
case HFILE:
conf.f1_file = optarg;
@@ -480,44 +454,42 @@ int main(int argc, char *argv[argc])
case HLINE:
conf.bottomtitle = optarg;
break;
+ case HMSG:
+ conf.f1_message = optarg;
+ break;
case IGNORE:
- ignore_flag = true;
+ ignore_opt = true;
break;
case INSECURE:
conf.form.securech = '*';
break;
case ITEM_DEPTH:
- item_depth_flag = true;
+ item_depth_opt = true;
break;
case ITEM_HELP:
- item_bottomdesc_flag = true;
+ item_bottomdesc_opt = true;
break;
case ITEM_PREFIX:
- item_prefix_flag = true;
+ item_prefix_opt = true;
break;
case MAX_INPUT:
- max_input_form_flag = atoi(optarg);
+ max_input_form_opt = (u_int)strtoul(optarg, NULL, 10);
break;
case NO_ITEMS:
conf.menu.no_desc = true;
break;
- case NOCANCEL:
case NO_CANCEL:
conf.button.without_cancel = true;
break;
case NO_COLLAPSE:
- no_collapse_flag = true;
- break;
- case NO_LABEL:
- conf.button.cancel_label = optarg;
+ no_collapse_opt = true;
break;
case NO_LINES:
conf.no_lines = true;
break;
case NO_NL_EXPAND:
- no_nl_expand_flag = true;
+ no_nl_expand_opt = true;
break;
- case NOOK:
case NO_OK:
conf.button.without_ok = true;
break;
@@ -531,17 +503,16 @@ int main(int argc, char *argv[argc])
conf.button.ok_label = optarg;
break;
case OUTPUT_FD:
- output_fd_flag = atoi(optarg);
+ output_fd_opt = (int)strtol(optarg, NULL, 10);
break;
- case SEPARATOR:
case OUTPUT_SEPARATOR:
- item_output_sep_flag = optarg;
+ item_output_sep_opt = optarg;
break;
case QUOTED:
- item_always_quote_flag = true;
+ item_always_quote_opt = true;
break;
case PRINT_MAXSIZE:
- print_maxsize_flag = true;
+ print_maxsize_opt = true;
break;
case PRINT_SIZE:
conf.get_height = &getH;;
@@ -551,127 +522,125 @@ int main(int argc, char *argv[argc])
printf("bsddialog version %s\n", BSDDIALOG_VERSION);
break;
case SEPARATE_OUTPUT:
- item_output_sepnl_flag = true;
+ item_output_sepnl_opt = true;
break;
case SHADOW:
conf.shadow = true;
break;
case SINGLE_QUOTED:
- item_singlequote_flag = true;
+ item_singlequote_opt = true;
break;
case SLEEP:
- conf.sleep = atoi(optarg);
+ conf.sleep = (u_int)strtoul(optarg, NULL, 10);
break;
case STDERR:
- output_fd_flag = STDERR_FILENO;
+ output_fd_opt = STDERR_FILENO;
break;
case STDOUT:
- output_fd_flag = STDOUT_FILENO;
+ output_fd_opt = STDOUT_FILENO;
+ break;
+ case TAB_LEN:
+ conf.text.tablen = (u_int)strtoul(optarg, NULL, 10);
break;
case THEME:
- if (strcmp(optarg, "bsddialog") == 0)
- theme_flag = BSDDIALOG_THEME_BSDDIALOG;
- else if (strcmp(optarg, "blackwhite") == 0)
- theme_flag = BSDDIALOG_THEME_BLACKWHITE;
- else if (strcmp(optarg, "dialog") == 0)
- theme_flag = BSDDIALOG_THEME_DIALOG;
+ if (strcasecmp(optarg, "bsddialog") == 0)
+ theme_opt = BSDDIALOG_THEME_BSDDIALOG;
+ else if (strcasecmp(optarg, "blackwhite") == 0)
+ theme_opt = BSDDIALOG_THEME_BLACKWHITE;
+ else if (strcasecmp(optarg, "default") == 0)
+ theme_opt = BSDDIALOG_THEME_DEFAULT;
+ else if (strcasecmp(optarg, "dialog") == 0)
+ theme_opt = BSDDIALOG_THEME_DIALOG;
else {
- printf("Unknown theme, possible values: ");
- printf("blackwhite, bsddialog, dialog");
- return (BSDDIALOG_ERROR);
+ printf("Error: unknown theme\n");
+ return (255);
}
break;
case TIME_FORMAT:
- time_fmt_flag = optarg;
+ time_fmt_opt = optarg;
break;
case TITLE:
conf.title = optarg;
break;
case TRIM:
- trim_flag = true;
+ trim_opt = true;
break;
case VERSION:
- printf("bsddialog %s (libbsddialog %s).\n",
+ printf("bsddialog %s (libbsddialog %s)\n",
BSDDIALOG_VERSION, LIBBSDDIALOG_VERSION);
return (BSDDIALOG_OK);
- case YES_LABEL:
- conf.button.ok_label = optarg;
- break;
- /* Widgets */
- case BUILDLIST:
- widgetbuilder = buildlist_builder;
- break;
+ /* Dialogs */
case CHECKLIST:
- widgetbuilder = checklist_builder;
+ dialogbuilder = checklist_builder;
break;
case DATEBOX:
- widgetbuilder = datebox_builder;
+ dialogbuilder = datebox_builder;
break;
case FORM:
- widgetbuilder = form_builder;
+ dialogbuilder = form_builder;
break;
case GAUGE:
- widgetbuilder = gauge_builder;
+ dialogbuilder = gauge_builder;
break;
case INFOBOX:
- widgetbuilder = infobox_builder;
+ dialogbuilder = infobox_builder;
break;
case INPUTBOX:
- widgetbuilder = inputbox_builder;
+ dialogbuilder = inputbox_builder;
break;
case MENU:
- widgetbuilder = menu_builder;
+ dialogbuilder = menu_builder;
break;
case MIXEDFORM:
- widgetbuilder = mixedform_builder;
+ dialogbuilder = mixedform_builder;
break;
case MIXEDGAUGE:
- widgetbuilder = mixedgauge_builder;
+ dialogbuilder = mixedgauge_builder;
break;
case MSGBOX:
- widgetbuilder = msgbox_builder;
+ dialogbuilder = msgbox_builder;
break;
case PAUSE:
- widgetbuilder = pause_builder;
+ dialogbuilder = pause_builder;
break;
case PASSWORDBOX:
- widgetbuilder = passwordbox_builder;
+ dialogbuilder = passwordbox_builder;
break;
case PASSWORDFORM:
- widgetbuilder = passwordform_builder;
+ dialogbuilder = passwordform_builder;
break;
case RADIOLIST:
- widgetbuilder = radiolist_builder;
+ dialogbuilder = radiolist_builder;
break;
case RANGEBOX:
- widgetbuilder = rangebox_builder;
+ dialogbuilder = rangebox_builder;
break;
case TEXTBOX:
- widgetbuilder = textbox_builder;
+ dialogbuilder = textbox_builder;
break;
case TIMEBOX:
- widgetbuilder = timebox_builder;
+ dialogbuilder = timebox_builder;
break;
case TREEVIEW:
- widgetbuilder = treeview_builder;
+ dialogbuilder = treeview_builder;
break;
case YESNO:
- widgetbuilder = yesno_builder;
+ dialogbuilder = yesno_builder;
break;
/* Error */
default:
- if (ignore_flag == true)
+ if (ignore_opt == true)
break;
usage();
- return (BSDDIALOG_ERROR);
+ return (255);
}
}
argc -= optind;
argv += optind;
- if (print_maxsize_flag) {
+ if (print_maxsize_opt) {
ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
- dprintf(output_fd_flag, "MaxSize: %d, %d\n",
+ dprintf(output_fd_opt, "Screen size: (%d - %d)\n",
ws.ws_row, ws.ws_col);
if (argc == 0)
return (BSDDIALOG_OK);
@@ -679,38 +648,43 @@ int main(int argc, char *argv[argc])
if (argc < 3) {
usage();
- return (BSDDIALOG_ERROR);
+ return (255);
}
- if (widgetbuilder == textbox_builder)
+ if (dialogbuilder == textbox_builder)
text = argv[0];
else {
- text = malloc(strlen(argv[0] + 1));
- custom_text(cr_wrap_flag, no_collapse_flag, no_nl_expand_flag,
- trim_flag, argv[0], text);
+ if ((text = malloc(strlen(argv[0]) + 1)) == NULL) {
+ printf("Error: cannot allocate memory for text\n");
+ return (255);
+ }
+ custom_text(cr_wrap_opt, no_collapse_opt, no_nl_expand_opt,
+ trim_opt, argv[0], text);
}
- rows = atoi(argv[1]);
- cols = atoi(argv[2]);
+ rows = (int)strtol(argv[1], NULL, 10);
+ cols = (int)strtol(argv[2], NULL, 10);
argc -= 3;
argv += 3;
/* bsddialog terminal mode */
- if(bsddialog_init() != 0) {
+ if (bsddialog_init() != 0) {
printf("Error: %s\n", bsddialog_geterror());
return (BSDDIALOG_ERROR);
}
- if (theme_flag >= 0)
- bsddialog_set_default_theme(theme_flag);
+ signal(SIGINT, sigint_handler);
+
+ if (theme_opt != BSDDIALOG_THEME_DEFAULT)
+ bsddialog_set_default_theme(theme_opt);
- if (backtitle_flag != NULL)
- bsddialog_backtitle(&conf, backtitle_flag);
+ if (backtitle_opt != NULL)
+ bsddialog_backtitle(&conf, backtitle_opt);
output = BSDDIALOG_OK;
- if (widgetbuilder != NULL)
- output = widgetbuilder(conf, text, rows, cols, argc, argv,
+ if (dialogbuilder != NULL)
+ output = dialogbuilder(conf, text, rows, cols, argc, argv,
errorbuilder);
- if (widgetbuilder != textbox_builder)
+ if (dialogbuilder != textbox_builder)
free(text);
bsddialog_end();
@@ -721,30 +695,90 @@ int main(int argc, char *argv[argc])
printf("Error: %s\n", errorbuilder);
else
printf("Error: %s\n", bsddialog_geterror());
+ return (255);
}
if (conf.get_height != NULL && conf.get_width != NULL)
- dprintf(output_fd_flag, "Widget size: (%d - %d)\n",
+ dprintf(output_fd_opt, "Dialog size: (%d - %d)\n",
*conf.get_height, *conf.get_width);
+ if (output == BSDDIALOG_ESC && esc_cancelvalue_opt)
+ output = BSDDIALOG_CANCEL;
+
return (output);
}
-/* Widgets */
+void sigint_handler(int sig)
+{
+ bsddialog_end();
+
+ exit(255);
+}
+void
+custom_text(bool cr_wrap, bool no_collapse, bool no_nl_expand, bool trim,
+ char *text, char *buf)
+{
+ int i, j;
+
+ i = j = 0;
+ while (text[i] != '\0') {
+ switch (text[i]) {
+ case '\\':
+ buf[j] = '\\';
+ switch (text[i+1]) {
+ case '\\':
+ i++;
+ break;
+ case 'n':
+ if (no_nl_expand) {
+ j++;
+ buf[j] = 'n';
+ } else
+ buf[j] = '\n';
+ i++;
+ break;
+ case 't':
+ if (no_collapse) {
+ j++;
+ buf[j] = 't';
+ } else
+ buf[j] = '\t';
+ i++;
+ break;
+ }
+ break;
+ case '\n':
+ buf[j] = cr_wrap ? ' ' : '\n';
+ break;
+ case '\t':
+ buf[j] = no_collapse ? '\t' : ' ';
+ break;
+ default:
+ buf[j] = text[i];
+ }
+ i++;
+ j += (buf[j] == ' ' && trim && j > 0 && buf[j-1] == ' ') ?
+ 0 : 1;
+ }
+ buf[j] = '\0';
+}
+
+/* Dialogs */
int gauge_builder(BUILDER_ARGS)
{
- int output, perc;
+ int output;
+ unsigned int perc;
if (argc > 0) {
- perc = argc > 0 ? atoi (argv[0]) : 0;
- perc = perc < 0 ? 0 : perc;
+ perc = argc > 0 ? (u_int)strtoul(argv[0], NULL, 10) : 0;
perc = perc > 100 ? 100 : perc;
}
else
perc = 0;
- output = bsddialog_gauge(&conf, text, rows, cols, perc);
+ output = bsddialog_gauge(&conf, text, rows, cols, perc, STDIN_FILENO,
+ "XXX");
return (output);
}
@@ -760,16 +794,16 @@ int infobox_builder(BUILDER_ARGS)
int mixedgauge_builder(BUILDER_ARGS)
{
- int i, output, mainperc, nminibars, *minipercs;
- char **minilabels;
+ int output, *minipercs;
+ unsigned int i, mainperc, nminibars;
+ const char **minilabels;
if (argc < 1 || (((argc-1) % 2) != 0) ) {
strcpy(errbuf, "bad --mixedgauge arguments\n");
return (BSDDIALOG_ERROR);
}
- mainperc = atoi(argv[0]);
- mainperc = mainperc < 0 ? 0 : mainperc;
+ mainperc = (u_int)strtoul(argv[0], NULL, 10);
mainperc = mainperc > 100 ? 100 : mainperc;
argc--;
argv++;
@@ -786,7 +820,7 @@ int mixedgauge_builder(BUILDER_ARGS)
for (i = 0; i < nminibars; i++) {
minilabels[i] = argv[i * 2];
- minipercs[i] = atoi(argv[i * 2 + 1]);
+ minipercs[i] = (int)strtol(argv[i * 2 + 1], NULL, 10);
}
output = bsddialog_mixedgauge(&conf, text, rows, cols, mainperc,
@@ -806,15 +840,16 @@ int msgbox_builder(BUILDER_ARGS)
int pause_builder(BUILDER_ARGS)
{
- int output, sec;
+ int output;
+ unsigned int secs;
if (argc < 1) {
- strcpy(errbuf, "not <seconds> argument for --pause\n");
+ strcpy(errbuf, "missing <seconds> for --pause\n");
return (BSDDIALOG_ERROR);
}
- sec = atoi(argv[0]);
- output = bsddialog_pause(&conf, text, rows, cols, sec);
+ secs = (u_int)strtoul(argv[0], NULL, 10);
+ output = bsddialog_pause(&conf, text, rows, cols, secs);
return (output);
}
@@ -829,11 +864,11 @@ int rangebox_builder(BUILDER_ARGS)
return (BSDDIALOG_ERROR);
}
- min = atoi(argv[0]);
- max = atoi(argv[1]);
-
+ min = (int)strtol(argv[0], NULL, 10);
+ max = (int)strtol(argv[1], NULL, 10);
+
if (argc > 2) {
- value = atoi(argv[2]);
+ value = (int)strtol(argv[2], NULL, 10);
value = value < min ? min : value;
value = value > max ? max : value;
}
@@ -842,7 +877,7 @@ int rangebox_builder(BUILDER_ARGS)
output = bsddialog_rangebox(&conf, text, rows, cols, min, max, &value);
- dprintf(output_fd_flag, "%d", value);
+ dprintf(output_fd_opt, "%d", value);
return (output);
}
@@ -880,28 +915,26 @@ int datebox_builder(BUILDER_ARGS)
mm = localtm->tm_mon + 1;
dd = localtm->tm_mday;
- /* --calendar text h w [year month day] */
if (argc == 3) {
- yy = atoi(argv[0]);
- mm = atoi(argv[1]);
- dd = atoi(argv[2]);
+ yy = (u_int)strtoul(argv[0], NULL, 10);
+ mm = (u_int)strtoul(argv[1], NULL, 10);
+ dd = (u_int)strtoul(argv[2], NULL, 10);
}
output = bsddialog_datebox(&conf, text, rows, cols, &yy, &mm, &dd);
if (output != BSDDIALOG_OK)
return (output);
- if (date_fmt_flag == NULL) {
- dprintf(output_fd_flag, "%u/%u/%u", yy, mm, dd);
- }
- else {
+ if (date_fmt_opt == NULL) {
+ dprintf(output_fd_opt, "%u/%u/%u", yy, mm, dd);
+ } else {
time(&cal);
localtm = localtime(&cal);
localtm->tm_year = yy - 1900;
localtm->tm_mon = mm;
localtm->tm_mday = dd;
- strftime(stringdate, 1024, date_fmt_flag, localtm);
- dprintf(output_fd_flag, "%s", stringdate);
+ strftime(stringdate, 1024, date_fmt_opt, localtm);
+ dprintf(output_fd_opt, "%s", stringdate);
}
return (output);
@@ -921,28 +954,26 @@ int timebox_builder(BUILDER_ARGS)
mm = localtm->tm_min;
ss = localtm->tm_sec;
- /* --timebox text h w [hour minute second] */
if (argc == 3) {
- hh = atoi(argv[0]);
- mm = atoi(argv[1]);
- ss = atoi(argv[2]);
+ hh = (u_int)strtoul(argv[0], NULL, 10);
+ mm = (u_int)strtoul(argv[1], NULL, 10);
+ ss = (u_int)strtoul(argv[2], NULL, 10);
}
output = bsddialog_timebox(&conf, text, rows, cols, &hh, &mm, &ss);
if (output != BSDDIALOG_OK)
return (output);
- if (time_fmt_flag == NULL) {
- dprintf(output_fd_flag, "%u:%u:%u", hh, mm, ss);
- }
- else {
+ if (time_fmt_opt == NULL) {
+ dprintf(output_fd_opt, "%u:%u:%u", hh, mm, ss);
+ } else {
time(&clock);
localtm = localtime(&clock);
localtm->tm_hour = hh;
localtm->tm_min = mm;
localtm->tm_sec = ss;
- strftime(stringtime, 1024, time_fmt_flag, localtm);
- dprintf(output_fd_flag, "%s", stringtime);
+ strftime(stringtime, 1024, time_fmt_opt, localtm);
+ dprintf(output_fd_opt, "%s", stringtime);
}
return (output);
@@ -952,35 +983,48 @@ int timebox_builder(BUILDER_ARGS)
static int
get_menu_items(char *errbuf, int argc, char **argv, bool setprefix,
bool setdepth, bool setname, bool setdesc, bool setstatus, bool sethelp,
- int *nitems, struct bsddialog_menuitem *items)
+ unsigned int *nitems, struct bsddialog_menuitem **items, int *focusitem)
{
- int i, j, sizeitem;
+ unsigned int i, j, sizeitem;
+
+ *focusitem = -1;
sizeitem = 0;
- if (setprefix) sizeitem++;
- if (setdepth) sizeitem++;
- if (setname) sizeitem++;
- if (setdesc) sizeitem++;
- if (setstatus) sizeitem++;
- if (sethelp) sizeitem++;
+ sizeitem += setprefix ? 1 : 0;
+ sizeitem += setdepth ? 1 : 0;
+ sizeitem += setname ? 1 : 0;
+ sizeitem += setdesc ? 1 : 0;
+ sizeitem += setstatus ? 1 : 0;
+ sizeitem += sethelp ? 1 : 0;
if ((argc % sizeitem) != 0) {
strcpy(errbuf, "bad number of arguments for this menu\n");
return (BSDDIALOG_ERROR);
}
-
*nitems = argc / sizeitem;
+
+ *items = calloc(*nitems, sizeof(struct bsddialog_menuitem));
+ if (items == NULL) {
+ strcpy(errbuf, "cannot allocate memory menu items\n");
+ return (BSDDIALOG_ERROR);
+ }
+
j = 0;
- for (i=0; i<*nitems; i++) {
- items[i].prefix = setprefix ? argv[j++] : nostring;
- items[i].depth = setdepth ? atoi(argv[j++]) : 0;
- items[i].name = setname ? argv[j++] : nostring;
- items[i].desc = setdesc ? argv[j++] : nostring;
+ for (i = 0; i < *nitems; i++) {
+ (*items)[i].prefix = setprefix ? argv[j++] : "";
+ (*items)[i].depth = setdepth ?
+ (u_int)strtoul(argv[j++], NULL, 0) : 0;
+ (*items)[i].name = setname ? argv[j++] : "";
+ (*items)[i].desc = setdesc ? argv[j++] : "";
if (setstatus)
- items[i].on = strcmp(argv[j++], "on") == 0 ?
+ (*items)[i].on = strcmp(argv[j++], "on") == 0 ?
true : false;
else
- items[i].on = false;
- items[i].bottomdesc = sethelp ? argv[j++] : nostring;
+ (*items)[i].on = false;
+ (*items)[i].bottomdesc = sethelp ? argv[j++] : "";
+
+ if (item_default_opt != NULL && *focusitem == -1)
+ if (strcmp((*items)[i].name, item_default_opt) == 0)
+ *focusitem = i;
}
return (BSDDIALOG_OK);
@@ -990,37 +1034,36 @@ static void
print_menu_items(struct bsddialog_conf *conf, int output, int nitems,
struct bsddialog_menuitem *items, int focusitem)
{
- int i;
bool sep, toquote;
- char *sepstr, quotech, *helpvalue;
+ int i;
+ char *sepstr, quotech;
+ const char *helpvalue;
sep = false;
- quotech = item_singlequote_flag ? '\'' : '"';
- sepstr = item_output_sep_flag != NULL ? item_output_sep_flag : " ";
+ quotech = item_singlequote_opt ? '\'' : '"';
+ sepstr = item_output_sep_opt != NULL ? item_output_sep_opt : " ";
if (output == BSDDIALOG_HELP && focusitem >= 0) {
- dprintf(output_fd_flag, "HELP ");
-
+ dprintf(output_fd_opt, "HELP ");
+
helpvalue = items[focusitem].name;
- if (item_bottomdesc_flag && item_tag_help_flag == false)
+ if (item_bottomdesc_opt && item_tag_help_opt == false)
helpvalue = items[focusitem].bottomdesc;
- toquote = item_always_quote_flag ||
+ toquote = item_always_quote_opt ||
strchr(helpvalue, ' ') != NULL;
if (toquote)
- dprintf(output_fd_flag, "%c", quotech);
- dprintf(output_fd_flag, "%s", helpvalue);
+ dprintf(output_fd_opt, "%c", quotech);
+ dprintf(output_fd_opt, "%s", helpvalue);
if (toquote)
- dprintf(output_fd_flag, "%c", quotech);
-
- if (list_items_on_flag == false)
- return;
-
+ dprintf(output_fd_opt, "%c", quotech);
+
sep = true;
}
- if (output != BSDDIALOG_OK && list_items_on_flag == false)
+ if (output != BSDDIALOG_OK &&
+ !(output == BSDDIALOG_HELP && list_items_on_opt))
return;
for (i = 0; i < nitems; i++) {
@@ -1028,65 +1071,39 @@ print_menu_items(struct bsddialog_conf *conf, int output, int nitems,
continue;
if (sep == true) {
- dprintf(output_fd_flag, "%s", sepstr);
- if (item_output_sepnl_flag)
- dprintf(output_fd_flag, "\n");
+ dprintf(output_fd_opt, "%s", sepstr);
+ if (item_output_sepnl_opt)
+ dprintf(output_fd_opt, "\n");
}
sep = true;
- toquote = item_always_quote_flag ||
+ toquote = item_always_quote_opt ||
strchr(items[i].name, ' ') != NULL;
if (toquote)
- dprintf(output_fd_flag, "%c", quotech);
- dprintf(output_fd_flag, "%s", items[i].name);
+ dprintf(output_fd_opt, "%c", quotech);
+ dprintf(output_fd_opt, "%s", items[i].name);
if (toquote)
- dprintf(output_fd_flag, "%c", quotech);
- }
-}
-
-int buildlist_builder(BUILDER_ARGS)
-{
- int output, menurows, nitems, focusitem;
- struct bsddialog_menuitem items[1024];
-
- if (argc < 1) {
- strcpy(errbuf, "<menurows> not provided");
- return (BSDDIALOG_ERROR);
+ dprintf(output_fd_opt, "%c", quotech);
}
-
- menurows = atoi(argv[0]);
-
- output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_flag, false,
- true, true, true, item_bottomdesc_flag, &nitems, items);
- if (output != 0)
- return (output);
-
- output = bsddialog_buildlist(&conf, text, rows, cols, menurows, nitems,
- items, &focusitem);
- if (output == BSDDIALOG_ERROR)
- return (BSDDIALOG_ERROR);
-
- print_menu_items(&conf, output, nitems, items, focusitem);
-
- return (output);
}
int checklist_builder(BUILDER_ARGS)
{
- int output, menurows, nitems, focusitem;
- struct bsddialog_menuitem items[1024];
+ int output, focusitem;
+ unsigned int menurows, nitems;
+ struct bsddialog_menuitem *items;
if (argc < 1) {
strcpy(errbuf, "<menurows> not provided");
return (BSDDIALOG_ERROR);
}
- menurows = atoi(argv[0]);
+ menurows = (u_int)strtoul(argv[0], NULL, 10);
- output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_flag,
- item_depth_flag, true, true, true, item_bottomdesc_flag, &nitems,
- items);
+ output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_opt,
+ item_depth_opt, true, true, true, item_bottomdesc_opt, &nitems,
+ &items, &focusitem);
if (output != 0)
return (output);
@@ -1095,24 +1112,27 @@ int checklist_builder(BUILDER_ARGS)
print_menu_items(&conf, output, nitems, items, focusitem);
+ free(items);
+
return (output);
}
int menu_builder(BUILDER_ARGS)
{
- int output, menurows, nitems, focusitem;
- struct bsddialog_menuitem items[1024];
+ int output, focusitem;
+ unsigned int menurows, nitems;
+ struct bsddialog_menuitem *items;
if (argc < 1) {
strcpy(errbuf, "<menurows> not provided");
return (BSDDIALOG_ERROR);
}
- menurows = atoi(argv[0]);
+ menurows = (u_int)strtoul(argv[0], NULL, 10);
- output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_flag,
- item_depth_flag, true, true, false, item_bottomdesc_flag, &nitems,
- items);
+ output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_opt,
+ item_depth_opt, true, true, false, item_bottomdesc_opt, &nitems,
+ &items, &focusitem);
if (output != 0)
return (output);
@@ -1121,24 +1141,27 @@ int menu_builder(BUILDER_ARGS)
print_menu_items(&conf, output, nitems, items, focusitem);
+ free(items);
+
return (output);
}
int radiolist_builder(BUILDER_ARGS)
{
- int output, menurows, nitems, focusitem;
- struct bsddialog_menuitem items[1024];
+ int output, focusitem;
+ unsigned int menurows, nitems;
+ struct bsddialog_menuitem *items;
if (argc < 1) {
strcpy(errbuf, "<menurows> not provided");
return (BSDDIALOG_ERROR);
}
- menurows = atoi(argv[0]);
+ menurows = (u_int)strtoul(argv[0], NULL, 10);
- output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_flag,
- item_depth_flag, true, true, true, item_bottomdesc_flag, &nitems,
- items);
+ output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_opt,
+ item_depth_opt, true, true, true, item_bottomdesc_opt, &nitems,
+ &items, &focusitem);
if (output != 0)
return (output);
@@ -1147,23 +1170,26 @@ int radiolist_builder(BUILDER_ARGS)
print_menu_items(&conf, output, nitems, items, focusitem);
+ free(items);
+
return (output);
}
int treeview_builder(BUILDER_ARGS)
{
- int output, menurows, nitems, focusitem;
- struct bsddialog_menuitem items[1024];
+ int output, focusitem;
+ unsigned int menurows, nitems;
+ struct bsddialog_menuitem *items;
if (argc < 1) {
strcpy(errbuf, "<menurows> not provided");
return (BSDDIALOG_ERROR);
}
- menurows = atoi(argv[0]);
+ menurows = (u_int)strtoul(argv[0], NULL, 10);
- output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_flag, true,
- true, true, true, item_bottomdesc_flag, &nitems, items);
+ output = get_menu_items(errbuf, argc-1, argv+1, item_prefix_opt, true,
+ true, true, true, item_bottomdesc_opt, &nitems, &items, &focusitem);
if (output != 0)
return (output);
@@ -1172,13 +1198,27 @@ int treeview_builder(BUILDER_ARGS)
output = bsddialog_radiolist(&conf, text, rows, cols, menurows, nitems,
items, &focusitem);
-
+
print_menu_items(&conf, output, nitems, items, focusitem);
+ free(items);
+
return (output);
}
/* FORM */
+static int
+alloc_formitems(int nitems, struct bsddialog_formitem **items, char *errbuf)
+{
+ *items = calloc(nitems, sizeof(struct bsddialog_formitem));
+ if (items == NULL) {
+ strcpy(errbuf, "cannot allocate memory for form items\n");
+ return (BSDDIALOG_ERROR);
+ }
+
+ return (BSDDIALOG_OK);
+}
+
static void
print_form_items(struct bsddialog_conf *conf, int output, int nitems,
struct bsddialog_formitem *items)
@@ -1188,52 +1228,58 @@ print_form_items(struct bsddialog_conf *conf, int output, int nitems,
if (output == BSDDIALOG_ERROR)
return;
- for (i=0; i < nitems; i++) {
- dprintf(output_fd_flag, "%s\n", items[i].value);
+ for (i = 0; i < nitems; i++) {
+ dprintf(output_fd_opt, "%s\n", items[i].value);
free(items[i].value);
}
}
int form_builder(BUILDER_ARGS)
{
- int i, output, formheight, nitems, fieldlen, valuelen;
- struct bsddialog_formitem items[1024];
- unsigned int flags = 0;
+ int output, fieldlen, valuelen;
+ unsigned int i, j, flags, formheight, nitems, sizeitem;
+ struct bsddialog_formitem *items;
- if (argc < 1 || (((argc-1) % 8) != 0) ) {
+ sizeitem = item_bottomdesc_opt ? 9 : 8;
+ if (argc < 1 || (((argc-1) % sizeitem) != 0)) {
strcpy(errbuf, "bad number of arguments for this form\n");
return (BSDDIALOG_ERROR);
}
- formheight = atoi(argv[0]);
+ formheight = (u_int)strtoul(argv[0], NULL, 10);
+ flags = 0;
argc--;
argv++;
- nitems = argc / 8;
- for (i=0; i<nitems; i++) {
- items[i].label = argv[8*i];
- items[i].ylabel = atoi(argv[8*i+1]);
- items[i].xlabel = atoi(argv[8*i+2]);
- items[i].init = argv[8*i+3];
- items[i].yfield = atoi(argv[8*i+4]);
- items[i].xfield = atoi(argv[8*i+5]);
-
- fieldlen = atoi(argv[8*i+6]);
+ nitems = argc / sizeitem;
+ if (alloc_formitems(nitems, &items, errbuf) != BSDDIALOG_OK)
+ return (BSDDIALOG_ERROR);
+ 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);
+
+ fieldlen = (int)strtol(argv[j++], NULL, 10);
items[i].fieldlen = abs(fieldlen);
- valuelen = atoi(argv[8*i+7]);
+ valuelen = (int)strtol(argv[j++], NULL, 10);
items[i].maxvaluelen = valuelen == 0 ? abs(fieldlen) : valuelen;
flags |= (fieldlen < 0 ? BSDDIALOG_FIELDREADONLY : 0);
items[i].flags = flags;
- items[i].bottomdesc = nostring;
+ items[i].bottomdesc = item_bottomdesc_opt ? argv[j++] : "";
}
output = bsddialog_form(&conf, text, rows, cols, formheight, nitems,
items);
print_form_items(&conf, output, nitems, items);
+ free(items);
return (output);
}
@@ -1250,9 +1296,9 @@ int inputbox_builder(BUILDER_ARGS)
item.yfield = 1;
item.xfield = 1;
item.fieldlen = cols > 4 ? cols-4 : 25;
- item.maxvaluelen = max_input_form_flag > 0 ? max_input_form_flag : 2048;
+ item.maxvaluelen = max_input_form_opt > 0 ? max_input_form_opt : 2048;
item.flags = 0;
- item.bottomdesc = nostring;
+ item.bottomdesc = "";
output = bsddialog_form(&conf, text, rows, cols, 1, 1, &item);
print_form_items(&conf, output, 1, &item);
@@ -1262,36 +1308,42 @@ int inputbox_builder(BUILDER_ARGS)
int mixedform_builder(BUILDER_ARGS)
{
- int i, output, formheight, nitems;
- struct bsddialog_formitem items[1024];
+ int output;
+ unsigned int i, j, formheight, nitems, sizeitem;
+ struct bsddialog_formitem *items;
- if (argc < 1 || (((argc-1) % 9) != 0) ) {
+ sizeitem = item_bottomdesc_opt ? 10 : 9;
+ if (argc < 1 || (((argc-1) % sizeitem) != 0)) {
strcpy(errbuf, "bad number of arguments for this form\n");
return (BSDDIALOG_ERROR);
}
- formheight = atoi(argv[0]);
-
+ formheight = (u_int)strtoul(argv[0], NULL, 10);
+
argc--;
argv++;
- nitems = argc / 9;
- for (i=0; i<nitems; i++) {
- items[i].label = argv[9*i];
- items[i].ylabel = atoi(argv[9*i+1]);
- items[i].xlabel = atoi(argv[9*i+2]);
- items[i].init = argv[9*i+3];
- items[i].yfield = atoi(argv[9*i+4]);
- items[i].xfield = atoi(argv[9*i+5]);
- items[i].fieldlen = atoi(argv[9*i+6]);
- items[i].maxvaluelen = atoi(argv[9*i+7]);
- items[i].flags = atoi(argv[9*i+8]);
- items[i].bottomdesc = nostring;
+ nitems = argc / sizeitem;
+ if (alloc_formitems(nitems, &items, errbuf) != BSDDIALOG_OK)
+ return (BSDDIALOG_ERROR);
+ j = 0;
+ for (i = 0; i < nitems; i++) {
+ items[i].label = argv[j++];
+ items[i].ylabel = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].xlabel = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].init = argv[j++];
+ items[i].yfield = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].xfield = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].fieldlen = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].maxvaluelen = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].flags = (u_int)strtoul(argv[j++], NULL, 10);
+ items[i].bottomdesc = item_bottomdesc_opt ? argv[j++] : "";
}
output = bsddialog_form(&conf, text, rows, cols, formheight, nitems,
items);
print_form_items(&conf, output, nitems, items);
+ free(items);
return (output);
}
@@ -1308,9 +1360,9 @@ int passwordbox_builder(BUILDER_ARGS)
item.yfield = 1;
item.xfield = 1;
item.fieldlen = cols > 4 ? cols-4 : 25;
- item.maxvaluelen = max_input_form_flag > 0 ? max_input_form_flag : 2048;
+ item.maxvaluelen = max_input_form_opt > 0 ? max_input_form_opt : 2048;
item.flags = BSDDIALOG_FIELDHIDDEN;
- item.bottomdesc = nostring;
+ item.bottomdesc = "";
output = bsddialog_form(&conf, text, rows, cols, 1, 1, &item);
print_form_items(&conf, output, 1, &item);
@@ -1320,44 +1372,50 @@ int passwordbox_builder(BUILDER_ARGS)
int passwordform_builder(BUILDER_ARGS)
{
- int i, output, formheight, nitems, fieldlen, valuelen;
- struct bsddialog_formitem items[1024];
- unsigned int flags = BSDDIALOG_FIELDHIDDEN;
+ int output, fieldlen, valuelen;
+ unsigned int i, j, flags, formheight, nitems, sizeitem;
+ struct bsddialog_formitem *items;
- if (argc < 1 || (((argc-1) % 8) != 0) ) {
+ sizeitem = item_bottomdesc_opt ? 9 : 8;
+ if (argc < 1 || (((argc-1) % sizeitem) != 0) ) {
strcpy(errbuf, "bad number of arguments for this form\n");
return (BSDDIALOG_ERROR);
}
- formheight = atoi(argv[0]);
-
+ formheight = (u_int)strtoul(argv[0], NULL, 10);
+ flags = BSDDIALOG_FIELDHIDDEN;
+
argc--;
argv++;
- nitems = argc / 8;
- for (i=0; i<nitems; i++) {
- items[i].label = argv[8*i];
- items[i].ylabel = atoi(argv[8*i+1]);
- items[i].xlabel = atoi(argv[8*i+2]);
- items[i].init = argv[8*i+3];
- items[i].yfield = atoi(argv[8*i+4]);
- items[i].xfield = atoi(argv[8*i+5]);
-
- fieldlen = atoi(argv[8*i+6]);
+ nitems = argc / sizeitem;
+ if (alloc_formitems(nitems, &items, errbuf) != BSDDIALOG_OK)
+ return (BSDDIALOG_ERROR);
+ 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);
+
+ fieldlen = (int)strtol(argv[j++], NULL, 10);
items[i].fieldlen = abs(fieldlen);
- valuelen = atoi(argv[8*i+7]);
+ valuelen = (int)strtol(argv[j++], NULL, 10);
items[i].maxvaluelen = valuelen == 0 ? abs(fieldlen) : valuelen;
flags |= (fieldlen < 0 ? BSDDIALOG_FIELDREADONLY : 0);
items[i].flags = flags;
- items[i].bottomdesc = nostring;
+ items[i].bottomdesc = item_bottomdesc_opt ? argv[j++] : "";
}
- output = bsddialog_form(&conf, text, rows, cols, formheight,
- nitems, items);
+ output = bsddialog_form(&conf, text, rows, cols, formheight, nitems,
+ items);
print_form_items(&conf, output, nitems, items);
+ free(items);
return (output);
}
diff --git a/examples_library/buildlist.c b/examples_library/buildlist.c
deleted file mode 100644
index 37c1e342ace5..000000000000
--- a/examples_library/buildlist.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-
- * SPDX-License-Identifier: CC0-1.0
- *
- * Written in 2021 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 <stdio.h>
-#include <string.h>
-
-#include <bsddialog.h>
-
-int main()
-{
- int i, output;
- struct bsddialog_conf conf;
- struct bsddialog_menuitem items[5] = {
- {"", false, 0, "Name 1", "Desc 1", "Bottom Desc 1"},
- {"", true, 0, "Name 2", "Desc 2", "Bottom Desc 2"},
- {"", false, 0, "Name 3", "Desc 3", "Bottom Desc 3"},
- {"", true, 0, "Name 4", "Desc 4", "Bottom Desc 4"},
- {"", false, 0, "Name 5", "Desc 5", "Bottom Desc 5"}
- };
-
- bsddialog_initconf(&conf);
- conf.title = "radiolist";
-
- if (bsddialog_init() < 0)
- return -1;
-
- output = bsddialog_buildlist(&conf, "Example", 15, 30, 5, 5, items, NULL);
-
- bsddialog_end();
-
- printf("Buildlist:\n");
- for (i=0; i<5; i++)
- printf(" [%c] %s\n", items[i].on ? 'X' : ' ', items[i].name);
-
-
- return output;
-}
diff --git a/examples_library/checklist.c b/examples_library/checklist.c
index d1c4a4db3597..7851383d0553 100644
--- a/examples_library/checklist.c
+++ b/examples_library/checklist.c
@@ -18,27 +18,38 @@ int main()
int i, output;
struct bsddialog_conf conf;
struct bsddialog_menuitem items[5] = {
- {"", true, 0, "Name 1", "Desc 1", "Bottom Desc 1"},
- {"", false, 0, "Name 2", "Desc 2", "Bottom Desc 2"},
- {"", true, 0, "Name 3", "Desc 3", "Bottom Desc 3"},
- {"", false, 0, "Name 4", "Desc 4", "Bottom Desc 4"},
- {"", true, 0, "Name 5", "Desc 5", "Bottom Desc 5"}
+ {"i", true, 0, "Name 1", "Desc 1", "Bottom Desc 1"},
+ {"ii", false, 0, "Name 2", "Desc 2", "Bottom Desc 2"},
+ {"iii", true, 0, "Name 3", "Desc 3", "Bottom Desc 3"},
+ {"iv", false, 0, "Name 4", "Desc 4", "Bottom Desc 4"},
+ {"v", true, 0, "Name 5", "Desc 5", "Bottom Desc 5"}
};
+ if (bsddialog_init() == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
bsddialog_initconf(&conf);
conf.title = "checklist";
-
- if (bsddialog_init() < 0)
- return -1;
-
- output = bsddialog_checklist(&conf, "Example", 15, 30, 5, 5, items, NULL);
+ output = bsddialog_checklist(&conf, "Example", 15, 30, 5, 5, items,
+ NULL);
bsddialog_end();
+ if (output == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
+ if (output == BSDDIALOG_CANCEL) {
+ printf("Cancel\n");
+ return (0);
+ }
+
printf("Checklist:\n");
- for (i=0; i<5; i++)
+ for (i = 0; i < 5; i++)
printf(" [%c] %s\n", items[i].on ? 'X' : ' ', items[i].name);
-
-
- return output;
-}
+
+ return (output);
+} \ No newline at end of file
diff --git a/examples_library/compile b/examples_library/compile
index 4427568a7f0f..945d906cd43c 100755
--- a/examples_library/compile
+++ b/examples_library/compile
@@ -1,10 +1,19 @@
#!/bin/sh
+#-
+# SPDX-License-Identifier: CC0-1.0
+#
+# Written in 2021 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/>.
libpath=../lib
-examples="buildlist menu treeview checklist radiolist mixedlist theme \
- infobox yesno msgbox datebox form timebox sade rangebox pause"
+examples="menu checklist radiolist mixedlist theme infobox yesno msgbox \
+ datebox form timebox rangebox pause"
for e in $examples
do
- cc -g -Wall -I$libpath ${e}.c -o $e -L$libpath -lbsddialog -Wl,-rpath=$libpath
+ cc -g -Wall -Wextra -I$libpath ${e}.c -o $e -L$libpath -lbsddialog \
+ -Wl,-rpath=$libpath
done
diff --git a/examples_library/datebox.c b/examples_library/datebox.c
index 4839c3dbd895..d2af7bd7fae0 100644
--- a/examples_library/datebox.c
+++ b/examples_library/datebox.c
@@ -28,24 +28,22 @@ int main()
mm = localtm->tm_mon + 1;
dd = localtm->tm_mday;
+ if (bsddialog_init() == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
bsddialog_initconf(&conf);
conf.title = "datebox";
conf.bottomtitle = "Press TAB and arrows";
-
- if (bsddialog_init() < 0)
- return -1;
-
output = bsddialog_datebox(&conf, "Example", 10, 50, &yy, &mm, &dd);
-
+
bsddialog_end();
switch (output) {
case BSDDIALOG_OK:
printf("Date: %u/%u/%u", yy, mm, dd);
break;
- case BSDDIALOG_ESC:
- printf("ESC\n");
- break;
case BSDDIALOG_CANCEL:
printf("Cancel");
break;
@@ -55,5 +53,5 @@ int main()
}
printf("\n");
- return output;
-}
+ return (output);
+} \ No newline at end of file
diff --git a/examples_library/form.c b/examples_library/form.c
index efb997f31d36..9bc7b0ccbe58 100644
--- a/examples_library/form.c
+++ b/examples_library/form.c
@@ -23,29 +23,37 @@ int main()
int i, output;
struct bsddialog_conf conf;
struct bsddialog_formitem items[3] = {
- {"Input:", 1, 1, "value", 1, 11, 30, 50, NULL, 0, "desc 1"},
- {"Input:", 2, 1, "read only", 2, 11, 30, 50, NULL, RO, "desc 2"},
- {"Password:", 3, 1, "", 3, 11, 30, 50, NULL, H, "desc 3"}
+ {"Input:", 1, 1, "value", 1, 11, 30, 50, NULL, 0, "desc 1"},
+ {"Input:", 2, 1, "read only", 2, 11, 30, 50, NULL, RO, "desc 2"},
+ {"Password:", 3, 1, "", 3, 11, 30, 50, NULL, H, "desc 3"}
};
+ if (bsddialog_init() == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
bsddialog_initconf(&conf);
conf.title = "form";
conf.form.securech = '*';
-
- if (bsddialog_init() < 0)
- return -1;
-
output = bsddialog_form(&conf, "Example", 10, 50, 3, 3, items);
bsddialog_end();
-
- if (output == BSDDIALOG_ERROR)
+
+ if (output == BSDDIALOG_ERROR) {
printf("Error: %s", bsddialog_geterror());
+ return (1);
+ }
+
+ if (output == BSDDIALOG_CANCEL) {
+ printf("Cancel\n");
+ return (0);
+ }
- for (i=0; i<3; i++) {
+ for (i = 0; i < 3; i++) {
printf("%s \"%s\"\n", items[i].label, items[i].value);
free(items[i].value);
}
-
- return output;
-}
+
+ return (output);
+} \ No newline at end of file
diff --git a/examples_library/infobox.c b/examples_library/infobox.c
index 74f34bba91e1..c022fa755fc6 100644
--- a/examples_library/infobox.c
+++ b/examples_library/infobox.c
@@ -18,15 +18,22 @@ 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 = "infobox";
-
- if (bsddialog_init() < 0)
- return -1;
-
- output = bsddialog_infobox(&conf, "Example", 7, 20);
+ conf.sleep = 3;
+ output = bsddialog_infobox(&conf, "Example\n(3 seconds)", 7, 20);
bsddialog_end();
- return output;
-}
+ if (output == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
+ return (output);
+} \ No newline at end of file
diff --git a/examples_library/menu.c b/examples_library/menu.c
index 59999dabd1e5..6a2abe2aaadb 100644
--- a/examples_library/menu.c
+++ b/examples_library/menu.c
@@ -18,27 +18,37 @@ int main()
int i, output;
struct bsddialog_conf conf;
struct bsddialog_menuitem items[5] = {
- {"", true, 0, "Name 1", "Desc 1", "Bottom Desc 1"},
- {"", false, 0, "Name 2", "Desc 2", "Bottom Desc 2"},
- {"", true, 0, "Name 3", "Desc 3", "Bottom Desc 3"},
- {"", false, 0, "Name 4", "Desc 4", "Bottom Desc 4"},
- {"", true, 0, "Name 5", "Desc 5", "Bottom Desc 5"}
+ {"I", true, 0, "Name 1", "Desc 1", "Bottom Desc 1"},
+ {"II", false, 0, "Name 2", "Desc 2", "Bottom Desc 2"},
+ {"III", true, 0, "Name 3", "Desc 3", "Bottom Desc 3"},
+ {"IV", false, 0, "Name 4", "Desc 4", "Bottom Desc 4"},
+ {"V", true, 0, "Name 5", "Desc 5", "Bottom Desc 5"}
};
+ if (bsddialog_init() == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
bsddialog_initconf(&conf);
conf.title = "menu";
-
- if (bsddialog_init() < 0)
- return -1;
-
output = bsddialog_menu(&conf, "Example", 15, 30, 5, 5, items, NULL);
bsddialog_end();
+ if (output == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
+ if (output == BSDDIALOG_CANCEL) {
+ printf("Cancel\n");
+ return (0);
+ }
+
printf("Menu:\n");
- for (i=0; i<5; i++)
+ for (i = 0; i < 5; i++)
printf(" [%c] %s\n", items[i].on ? 'X' : ' ', items[i].name);
-
-
- return output;
-}
+
+ return (output);
+} \ No newline at end of file
diff --git a/examples_library/mixedlist.c b/examples_library/mixedlist.c
index 2a4e9102164c..7f299218cb62 100644
--- a/examples_library/mixedlist.c
+++ b/examples_library/mixedlist.c
@@ -15,7 +15,8 @@
int main()
{
- int i, j, output;
+ int output;
+ unsigned int i, j;
struct bsddialog_conf conf;
struct bsddialog_menuitem item;
struct bsddialog_menuitem check[5] = {
@@ -41,30 +42,42 @@ int main()
{ BSDDIALOG_RADIOLIST, 5, radio }
};
- bsddialog_initconf(&conf);
- conf.title = "mixedmenu";
-
- if (bsddialog_init() < 0)
- return -1;
+ if (bsddialog_init() == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
- output = bsddialog_mixedlist(&conf, "dialog4ports", 20, 30, 11, 3, group,
- NULL,NULL);
+ bsddialog_initconf(&conf);
+ conf.title = "mixedlist";
+ output = bsddialog_mixedlist(&conf, "Example", 20, 30, 11, 3, group,
+ NULL, NULL);
bsddialog_end();
+ if (output == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
+ if (output == BSDDIALOG_CANCEL) {
+ printf("Cancel\n");
+ return (0);
+ }
+
printf("Mixedlist:\n");
- for (i=0; i<3; i++) {
- for (j=0; j<group[i].nitems; j++) {
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < group[i].nitems; j++) {
item = group[i].items[j];
if (group[i].type == BSDDIALOG_SEPARATOR)
printf("----- %s -----\n", item.name);
else if (group[i].type == BSDDIALOG_RADIOLIST)
- printf(" (%c) %s\n", item.on ? '*' : ' ', item.name);
- else /* BSDDIALOG_PORTCHECKLIST */
- printf(" [%c] %s\n", item.on ? 'X' : ' ', item.name);
+ printf(" (%c) %s\n",
+ item.on ? '*' : ' ', item.name);
+ else /* BSDDIALOG_CHECKLIST */
+ printf(" [%c] %s\n",
+ item.on ? 'X' : ' ', item.name);
}
}
-
-
- return output;
-}
+
+ return (output);
+} \ No newline at end of file
diff --git a/examples_library/msgbox.c b/examples_library/msgbox.c
index 487266745c65..32696894aa85 100644
--- a/examples_library/msgbox.c
+++ b/examples_library/msgbox.c
@@ -15,28 +15,28 @@
int main()
{
- int input;
+ int output;
struct bsddialog_conf conf;
- /* Configuration */
- bsddialog_initconf(&conf);
- conf.title = "msgbox";
-
- /* Run BSDDialog */
if (bsddialog_init() == BSDDIALOG_ERROR) {
printf("Error: %s\n", bsddialog_geterror());
- return -1;
+ return (1);
}
- input = bsddialog_msgbox(&conf, "Example", 7, 20);
+
+ bsddialog_initconf(&conf);
+ conf.title = "msgbox";
+ output = bsddialog_msgbox(&conf, "Example", 7, 20);
+
bsddialog_end();
- /* User Input */
- printf("User input: ");
- switch (input) {
- case BSDDIALOG_ERROR: printf("Error %s\n", bsddialog_geterror()); break;
- case BSDDIALOG_OK: printf("OK\n"); break;
- case BSDDIALOG_ESC: printf("ESC\n"); break;
+ switch (output) {
+ case BSDDIALOG_ERROR:
+ printf("Error %s\n", bsddialog_geterror());
+ break;
+ case BSDDIALOG_OK:
+ printf("OK\n");
+ break;
}
- return input;
-}
+ return (output);
+} \ No newline at end of file
diff --git a/examples_library/pause.c b/examples_library/pause.c
index eb693325a18d..62c35afb0192 100644
--- a/examples_library/pause.c
+++ b/examples_library/pause.c
@@ -18,12 +18,13 @@ 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 = "pause";
-
- if (bsddialog_init() < 0)
- return -1;
-
output = bsddialog_pause(&conf, "Example", 8, 50, 10);
bsddialog_end();
@@ -32,9 +33,6 @@ int main()
case BSDDIALOG_OK:
printf("OK\n");
break;
- case BSDDIALOG_ESC:
- printf("ESC\n");
- break;
case BSDDIALOG_CANCEL:
printf("Cancel\n");
break;
@@ -46,5 +44,5 @@ int main()
break;
}
- return output;
-}
+ return (output);
+} \ No newline at end of file
diff --git a/examples_library/radiolist.c b/examples_library/radiolist.c
index d4c93c3d406f..79da63ad749f 100644
--- a/examples_library/radiolist.c
+++ b/examples_library/radiolist.c
@@ -18,27 +18,37 @@ int main()
int i, output;
struct bsddialog_conf conf;
struct bsddialog_menuitem items[5] = {
- {"", true, 0, "Name 1", "Desc 1", "Bottom Desc 1"},
- {"", false, 0, "Name 2", "Desc 2", "Bottom Desc 2"},
- {"", true, 0, "Name 3", "Desc 3", "Bottom Desc 3"},
- {"", false, 0, "Name 4", "Desc 4", "Bottom Desc 4"},
- {"", true, 0, "Name 5", "Desc 5", "Bottom Desc 5"}
+ {"I", true, 0, "Name 1", "Desc 1", "Bottom Desc 1"},
+ {"II", false, 0, "Name 2", "Desc 2", "Bottom Desc 2"},
+ {"III", true, 0, "Name 3", "Desc 3", "Bottom Desc 3"},
+ {"IV", false, 0, "Name 4", "Desc 4", "Bottom Desc 4"},
+ {"V", true, 0, "Name 5", "Desc 5", "Bottom Desc 5"}
};
+ if (bsddialog_init() == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
bsddialog_initconf(&conf);
conf.title = "radiolist";
-
- if (bsddialog_init() < 0)
- return -1;
-
output = bsddialog_radiolist(&conf, "Example", 15, 30, 5, 5, items, NULL);
bsddialog_end();
+ if (output == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
+ if (output == BSDDIALOG_CANCEL) {
+ printf("Cancel\n");
+ return (0);
+ }
+
printf("Radiolist:\n");
- for (i=0; i<5; i++)
+ for (i = 0; i < 5; i++)
printf(" (%c) %s\n", items[i].on ? '*' : ' ', items[i].name);
-
-
- return output;
-}
+
+ return (output);
+} \ No newline at end of file
diff --git a/examples_library/rangebox.c b/examples_library/rangebox.c
index 624bd4e438e8..06a62cc4b858 100644
--- a/examples_library/rangebox.c
+++ b/examples_library/rangebox.c
@@ -18,18 +18,24 @@ int main()
int value, output;
struct bsddialog_conf conf;
+ if (bsddialog_init() == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
bsddialog_initconf(&conf);
conf.title = "rangebox";
-
- if (bsddialog_init() < 0)
- return -1;
-
value = 5;
output = bsddialog_rangebox(&conf, "Example", 8, 50, 0, 10, &value);
bsddialog_end();
- printf("Value: %d", value);
+ if (output == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
+ printf("Value: %d\n", value);
- return output;
-}
+ return (output);
+} \ No newline at end of file
diff --git a/examples_library/sade.c b/examples_library/sade.c
deleted file mode 100644
index 1c1d74e5a501..000000000000
--- a/examples_library/sade.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * SPDX-License-Identifier: CC0-1.0
- *
- * Written in 2021 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>
-#include <string.h>
-
-/* Figure 15 - https://docs.freebsd.org/en/books/handbook/bsdinstall/ */
-int main()
-{
- int i, output;
- struct bsddialog_conf conf;
- char *text = "Please review the disk setup. When complete, press the "
- "Finish button";
- struct bsddialog_menuitem items[5] = {
- {"", false, 0, "ada0", "16 GB GPT", ""},
- {"", false, 1, "ada0p1", "512 KB freebsd-boot", ""},
- {"", false, 1, "ada0p2", "15 GB freebsd-ufs", ""},
- {"", false, 1, "ada0p3", "819 MB freebsd-swap none", ""},
- {"", false, 0, "ada1", "16 GB", ""}
- };
-
- bsddialog_initconf(&conf);
-
- conf.title = "Partition Editor";
- conf.menu.shortcut_buttons = true;
- conf.menu.align_left = true;
- conf.button.ok_label = "Create";
- conf.button.with_extra = true;
- conf.button.extra_label = "Delete";
- conf.button.cancel_label = "Cancel";
- conf.button.with_help = true;
- conf.button.help_label = "Revert";
- conf.button.generic1_label = "Auto";
- conf.button.generic2_label = "Finish";
- conf.button.default_label = "Finish";
-
- if (bsddialog_init() == BSDDIALOG_ERROR)
- return (1);
- output = bsddialog_menu(&conf, text, 20, 0, 10, 5, items, NULL);
- bsddialog_end();
-
- printf("Menu:\n");
- for (i=0; i<5; i++)
- printf(" [%c] %s\n", items[i].on ? 'X' : ' ', items[i].name);
-
-
- return (output);
-}
diff --git a/examples_library/theme.c b/examples_library/theme.c
index 305692d39cff..fb09aa1d1b24 100644
--- a/examples_library/theme.c
+++ b/examples_library/theme.c
@@ -16,47 +16,60 @@
int main()
{
- int output;
+ int output, focusitem;
struct bsddialog_conf conf;
enum bsddialog_default_theme theme;
- struct bsddialog_menuitem items[4] = {
- {"", false, 0, "Dialog", "Current dialog theme", "BSDDIALOG_THEME_DIALOG" },
- {"", false, 0, "BSDDialog", "Future default theme", "BSDDIALOG_THEME_DEFAULT"},
- {"", false, 0, "BlackWhite","Black and White theme", "BSDDIALOG_THEME_BLACKWHITE"},
- {"", false, 0, "Quit", "Exit", "Quit or Cancel to exit" }
+ struct bsddialog_menuitem items[5] = {
+ {"", false, 0, "Default", "dialog-like",
+ "BSDDIALOG_THEME_DEFAULT" },
+ {"", false, 0, "Dialog", "dialog clone",
+ "BSDDIALOG_THEME_DIALOG" },
+ {"", false, 0, "BSDDialog", "new theme",
+ "BSDDIALOG_THEME_BSDDIALOG" },
+ {"", false, 0, "BlackWhite","black and white",
+ "BSDDIALOG_THEME_BLACKWHITE" },
+ {"", false, 0, "Quit", "Exit", "Quit or Cancel to exit" }
};
+ if (bsddialog_init() == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
bsddialog_initconf(&conf);
- conf.title = " Theme ";
-
- if (bsddialog_init() == BSDDIALOG_ERROR)
- return BSDDIALOG_ERROR;
- while (true) {
- bsddialog_backtitle(&conf, "Theme Example");
+ bsddialog_backtitle(&conf, "Theme Example");
- output = bsddialog_menu(&conf, "Choose theme", 15, 40, 4, 4, items, NULL);
+ conf.title = " Theme ";
+ focusitem = -1;
+ while (true) {
+ output = bsddialog_menu(&conf, "Choose theme", 15, 40, 5, 5,
+ items, &focusitem);
- if (output != BSDDIALOG_OK || items[3].on)
+ if (output != BSDDIALOG_OK || items[4].on)
break;
if (items[0].on) {
- theme = BSDDIALOG_THEME_DIALOG;
- conf.menu.default_item = items[0].name;
+ theme = BSDDIALOG_THEME_DEFAULT;
+ focusitem = 0;
}
else if (items[1].on) {
- theme = BSDDIALOG_THEME_BSDDIALOG;
- conf.menu.default_item = items[1].name;
+ theme = BSDDIALOG_THEME_DIALOG;
+ focusitem = 1;
}
else if (items[2].on) {
+ theme = BSDDIALOG_THEME_BSDDIALOG;
+ focusitem = 2;
+ }
+ else if (items[3].on) {
theme = BSDDIALOG_THEME_BLACKWHITE;
- conf.menu.default_item = items[2].name;
+ focusitem = 3;
}
bsddialog_set_default_theme(theme);
}
- bsddialog_end();
+ bsddialog_end();
- return output;
-}
+ return (output);
+} \ No newline at end of file
diff --git a/examples_library/timebox.c b/examples_library/timebox.c
index 117d45dcdb7b..6e3721ea9188 100644
--- a/examples_library/timebox.c
+++ b/examples_library/timebox.c
@@ -28,24 +28,22 @@ int main()
mm = localtm->tm_min;
ss = localtm->tm_sec;
+ if (bsddialog_init() == BSDDIALOG_ERROR) {
+ printf("Error: %s\n", bsddialog_geterror());
+ return (1);
+ }
+
bsddialog_initconf(&conf);
conf.title = "timebox";
conf.bottomtitle = "Press TAB and arrows";
-
- if (bsddialog_init() < 0)
- return -1;
-
output = bsddialog_timebox(&conf, "Example", 10, 50, &hh, &mm, &ss);
-
+
bsddialog_end();
switch (output) {
case BSDDIALOG_OK:
printf("Time: [%u:%u:%u]\n", hh, mm, ss);
break;
- case BSDDIALOG_ESC:
- printf("ESC\n");
- break;
case BSDDIALOG_CANCEL:
printf("Cancel\n");
break;
@@ -54,5 +52,5 @@ int main()
break;
}
- return output;
-}
+ return (output);
+} \ No newline at end of file
diff --git a/examples_library/treeview.c b/examples_library/treeview.c
deleted file mode 100644
index 7fa3d229adf9..000000000000
--- a/examples_library/treeview.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * SPDX-License-Identifier: CC0-1.0
- *
- * Written in 2021 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 <stdio.h>
-#include <string.h>
-
-#include <bsddialog.h>
-
-int main()
-{
- int i, output;
- struct bsddialog_conf conf;
- struct bsddialog_menuitem items[5] = {
- {"", false, 0, "Name 1", "Desc 1", "Bottom Desc 1"},
- {"", false, 1, "Name 2", "Desc 2", "Bottom Desc 2"},
- {"", false, 1, "Name 3", "Desc 3", "Bottom Desc 3"},
- {"", false, 2, "Name 4", "Desc 4", "Bottom Desc 4"},
- {"", false, 1, "Name 5", "Desc 5", "Bottom Desc 5"}
- };
-
- bsddialog_initconf(&conf);
- conf.title = "radiolist";
- conf.menu.no_name = true;
- conf.menu.align_left = true;
-
- if (bsddialog_init() < 0)
- return -1;
-
- output = bsddialog_radiolist(&conf, "Example", 15, 30, 5, 5, items, NULL);
-
- bsddialog_end();
-
- printf("Treeview:\n");
- for (i=0; i<5; i++)
- printf(" (%c) %s\n", items[i].on ? '*' : ' ', items[i].name);
-
-
- return output;
-}
diff --git a/examples_library/yesno.c b/examples_library/yesno.c
index 783fcf57cbb6..5a9c95edc849 100644
--- a/examples_library/yesno.c
+++ b/examples_library/yesno.c
@@ -18,15 +18,28 @@ 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 = "yesno";
-
- if (bsddialog_init() < 0)
- return -1;
-
output = bsddialog_yesno(&conf, "Example", 7, 25);
bsddialog_end();
- return output;
-}
+ switch (output) {
+ case BSDDIALOG_ERROR:
+ printf("Error %s\n", bsddialog_geterror());
+ break;
+ case BSDDIALOG_YES:
+ printf("YES\n");
+ break;
+ case BSDDIALOG_NO:
+ printf("NO\n");
+ break;
+ }
+
+ return (output);
+} \ No newline at end of file
diff --git a/examples_utility/buildlist.sh b/examples_utility/buildlist.sh
deleted file mode 100755
index cefeea8f3c51..000000000000
--- a/examples_utility/buildlist.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-#-
-# SPDX-License-Identifier: CC0-1.0
-#
-# Written in 2021 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/>.
-
-./bsddialog --title buildlist --buildlist "Hello World!" 15 40 5 \
- "Tag 1" "DESC 1 xyz" off \
- "Tag 2" "DESC 2 xyz" off \
- "Tag 3" "DESC 3 xyz" on \
- "Tag 4" "DESC 4 xyz" off \
- "Tag 5" "DESC 5 xyz" off \
- 2>out.txt ; cat out.txt ; rm out.txt
diff --git a/examples_utility/checklist.sh b/examples_utility/checklist.sh
index 5f9a17cb64b1..94eb2043a3ab 100755
--- a/examples_utility/checklist.sh
+++ b/examples_utility/checklist.sh
@@ -6,9 +6,9 @@
# 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/>.
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
-./bsddialog --title checklist --checklist "Hello World!" 15 30 5 \
+./bsddialog --title " checklist " --checklist "Hello World!" 15 30 5 \
"Tag 1" "DESC 1 xyz" on \
"Tag 2" "DESC 2 xyz" off \
"Tag 3" "DESC 3 xyz" on \
diff --git a/examples_utility/form.sh b/examples_utility/form.sh
index 5d6b6ee1b606..ad1b5d275d0d 100755
--- a/examples_utility/form.sh
+++ b/examples_utility/form.sh
@@ -6,14 +6,14 @@
# 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/>.
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
./bsddialog --title " form " --form "Hello World!" 12 40 5 \
- Label1: 1 1 Value1 1 9 18 25 \
- Label2: 2 1 Value2 2 9 18 25 \
- Label3: 3 1 Value3 3 9 18 25 \
- Label4: 4 1 Value4 4 9 18 25 \
- Label5: 5 1 Value5 5 9 18 25 \
+ Label1: 1 1 Value1 1 9 18 25 \
+ Label2: 2 1 Value2 2 9 18 25 \
+ Label3: 3 1 Value3 3 9 18 25 \
+ Label4: 4 1 Value4 4 9 18 25 \
+ Label5: 5 1 Value5 5 9 18 25 \
2>out.txt ; cat out.txt ; rm out.txt
diff --git a/examples_utility/gauge.sh b/examples_utility/gauge.sh
index 82d15655efe2..1665e04b4e8c 100755
--- a/examples_utility/gauge.sh
+++ b/examples_utility/gauge.sh
@@ -6,23 +6,23 @@
# 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/>.
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
-input="A B C D E F G"
-total=`echo $input | awk '{print split($0, a)}'`
-curr=1
-for i in $input
+characters="A B C D E F G"
+total=`echo $characters | awk '{print split($0, a)}'`
+i=1
+for c in $characters
do
sleep 1
- perc="$(expr $(expr $curr "*" 100 ) "/" $total )"
- echo XXX
- echo $perc
- echo "[$curr/$total] Input: $i"
- echo XXX
- if [ $curr -eq $total ]
- then
- echo EOF
- fi
- curr=`expr $curr + 1`
-done | ./bsddialog --title gauge --gauge "[0/$total] Starting..." 10 70 0
+ echo XXX
+ echo "$(expr $(expr $i "*" 100) "/" $total)"
+ echo "[$i/$total] Char: $c"
+ echo XXX
+ if [ $i -eq $total ]
+ then
+ sleep 1
+ echo EOF
+ fi
+ i=`expr $i + 1`
+done | ./bsddialog --title " gauge " --gauge "[0/$total] Starting..." 10 70
diff --git a/examples_utility/infobox.sh b/examples_utility/infobox.sh
index 468ecff826fd..75d14d10177a 100755
--- a/examples_utility/infobox.sh
+++ b/examples_utility/infobox.sh
@@ -6,7 +6,6 @@
# 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/>.
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
-
-./bsddialog --sleep 3 --title infobox --infobox "Hello World!\n3 seconds" 6 20
+./bsddialog --sleep 3 --title " infobox " --infobox "Hello World!\n3 secs" 6 20
diff --git a/examples_utility/inputbox.sh b/examples_utility/inputbox.sh
index 27073468a478..340500eaab1f 100755
--- a/examples_utility/inputbox.sh
+++ b/examples_utility/inputbox.sh
@@ -6,7 +6,7 @@
# 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/>.
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
-./bsddialog --title " inputbox " --inputbox "Hello World!" 12 40 init \
+./bsddialog --title " inputbox " --inputbox "Hello World!" 12 40 default \
2>out.txt ; cat out.txt ; rm out.txt
diff --git a/examples_utility/menu.sh b/examples_utility/menu.sh
index 66c9f54beb4c..fe56f4e079cf 100755
--- a/examples_utility/menu.sh
+++ b/examples_utility/menu.sh
@@ -6,12 +6,12 @@
# 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/>.
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
-./bsddialog --title menu --menu "Hello World!" 15 30 5 \
- "Tag 1" "DESC 1 xyz" \
- "Tag 2" "DESC 2 xyz" \
- "Tag 3" "DESC 3 xyz" \
- "Tag 4" "DESC 4 xyz" \
- "Tag 5" "DESC 5 xyz" \
+./bsddialog --title " menu " --menu "Hello World!" 15 30 5 \
+ "Tag 1" "DESC 1 xyz" \
+ "Tag 2" "DESC 2 xyz" \
+ "Tag 3" "DESC 3 xyz" \
+ "Tag 4" "DESC 4 xyz" \
+ "Tag 5" "DESC 5 xyz" \
2>out.txt ; cat out.txt ; rm out.txt
diff --git a/examples_utility/mixedform.sh b/examples_utility/mixedform.sh
index 6677c20781ad..303c1a63dd98 100755
--- a/examples_utility/mixedform.sh
+++ b/examples_utility/mixedform.sh
@@ -6,10 +6,10 @@
# 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/>.
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
./bsddialog --insecure --title " mixedform " --mixedform "Hello World!" 12 40 5 \
- Label: 1 1 Entry 1 11 18 25 0 \
- Label: 2 1 Read-Only 2 11 18 25 2 \
- Password: 3 1 Value2 3 11 18 25 1 \
+ Label: 11 Entry 1 11 18 25 0 \
+ Label: 21 Read-Only 2 11 18 25 2 \
+ Password: 31 "" 3 11 18 25 1 \
2>out.txt ; cat out.txt ; rm out.txt
diff --git a/examples_utility/mixedgauge.sh b/examples_utility/mixedgauge.sh
index bc0f91a1e506..735f8dc42922 100755
--- a/examples_utility/mixedgauge.sh
+++ b/examples_utility/mixedgauge.sh
@@ -6,29 +6,25 @@
# 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/>.
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
-
-input="A B C D E F G H"
-total=`echo $input | awk '{print split($0, a)}'`
-curr=1
-for i in $input
+perc=0
+while [ $perc -le 100 ]
do
- perc="$(expr $(expr $curr "*" 100 ) "/" $total )"
- curr=`expr $curr + 1`
- ./bsddialog --sleep 1 --title " mixedgauge " --mixedgauge "Example" 25 50 $perc \
- "Hidden!" 8 \
- "Label 1" 0 \
- "Label 2" 1 \
- "Label 3" 2 \
- "Label 4" 3 \
- "Label 5" 4 \
- "Label 6" 5 \
- "Label 7" 6 \
- "Label 8" 7 \
- "Label 9" 9 \
- "Label 10" 10 \
- "Label X" " -$perc"
- #sleep 1
-done
+ ./bsddialog --sleep 1 --title " mixedgauge " \
+ --mixedgauge "Example..." 20 45 $perc \
+ "(Hidden)" " -9" \
+ "Label 1" " -1" \
+ "Label 2" " -2" \
+ "Label 3" " -3" \
+ "Label 4" " -4" \
+ "Label 5" " -5" \
+ "Label 6" " -6" \
+ "Label 7" " -7" \
+ "Label 8" " -8" \
+ "Label 9" " -10" \
+ "Label 10" " -11" \
+ "Label X" $perc
+ perc=`expr $perc + 20`
+done
diff --git a/examples_utility/msgbox.sh b/examples_utility/msgbox.sh
index 49cb626f4055..9e14ed6cbba4 100755
--- a/examples_utility/msgbox.sh
+++ b/examples_utility/msgbox.sh
@@ -6,6 +6,6 @@
# 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/>.
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
-./bsddialog --title msgbox --msgbox "Hello World!" 6 20
+./bsddialog --title " msgbox " --msgbox "Hello World!" 6 20
diff --git a/examples_utility/passwordbox.sh b/examples_utility/passwordbox.sh
index 5c6a91e0f057..673491f64140 100755
--- a/examples_utility/passwordbox.sh
+++ b/examples_utility/passwordbox.sh
@@ -6,7 +6,7 @@
# 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/>.
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
./bsddialog --insecure --title " password " --passwordbox "Hello World!" 12 40 \
2>out.txt ; cat out.txt ; rm out.txt
diff --git a/examples_utility/passwordform.sh b/examples_utility/passwordform.sh
index 5cfe0b0fa0a1..658f1635dffc 100755
--- a/examples_utility/passwordform.sh
+++ b/examples_utility/passwordform.sh
@@ -6,12 +6,12 @@
# 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/>.
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
./bsddialog --insecure --title " passwordform " --passwordform "Example" 12 40 5 \
- Password1: 1 1 Value1 1 12 18 25 \
- Password2: 2 1 Value2 2 12 18 25 \
- Password3: 3 1 Value3 3 12 18 25 \
- Password4: 4 1 Value4 4 12 18 25 \
- Password5: 5 1 Value5 5 12 18 25 \
+ Password1: 1 1 "" 1 12 18 25 \
+ Password2: 2 1 "" 2 12 18 25 \
+ Password3: 3 1 "" 3 12 18 25 \
+ Password4: 4 1 "" 4 12 18 25 \
+ Password5: 5 1 "" 5 12 18 25 \
2>out.txt ; cat out.txt ; rm out.txt
diff --git a/examples_utility/radiolist.sh b/examples_utility/radiolist.sh
index c1c7724eb09d..2b4ce8d56809 100755
--- a/examples_utility/radiolist.sh
+++ b/examples_utility/radiolist.sh
@@ -6,12 +6,12 @@
# 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/>.
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
-./bsddialog --title radiolist --radiolist "Hello World!" 15 30 5 \
- "Tag 1" "DESC 1 xyz" off \
- "Tag 2" "DESC 2 xyz" off \
- "Tag 3" "DESC 3 xyz" on \
- "Tag 4" "DESC 4 xyz" off \
- "Tag 5" "DESC 5 xyz" off \
+./bsddialog --title " radiolist " --radiolist "Hello World!" 15 30 5 \
+ "Tag 1" "DESC 1 xyz" off \
+ "Tag 2" "DESC 2 xyz" off \
+ "Tag 3" "DESC 3 xyz" on \
+ "Tag 4" "DESC 4 xyz" off \
+ "Tag 5" "DESC 5 xyz" off \
2>out.txt ; cat out.txt ; rm out.txt
diff --git a/examples_utility/treeview.sh b/examples_utility/treeview.sh
index 5286de673a1d..3566c6812714 100755
--- a/examples_utility/treeview.sh
+++ b/examples_utility/treeview.sh
@@ -6,12 +6,12 @@
# 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/>.
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
-./bsddialog --title treeview --treeview "Hello World!" 15 40 5 \
- 0 "Tag 1" "DESC 1 xyz" off \
- 1 "Tag 2" "DESC 2 xyz" off \
- 2 "Tag 3" "DESC 3 xyz" on \
- 1 "Tag 4" "DESC 4 xyz" off \
- 1 "Tag 5" "DESC 5 xyz" off \
+./bsddialog --title " treeview " --treeview "Hello World!" 15 40 5 \
+ 0 "Tag 1" "DESC 1 xyz" off \
+ 1 "Tag 2" "DESC 2 xyz" off \
+ 2 "Tag 3" "DESC 3 xyz" on \
+ 1 "Tag 4" "DESC 4 xyz" off \
+ 1 "Tag 5" "DESC 5 xyz" off \
2>out.txt ; cat out.txt ; rm out.txt
diff --git a/examples_utility/yesno.sh b/examples_utility/yesno.sh
index 7d1d33530606..cfa082e8d24e 100755
--- a/examples_utility/yesno.sh
+++ b/examples_utility/yesno.sh
@@ -6,6 +6,6 @@
# 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/>.
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
-./bsddialog --title yesno --yesno "Hello World!" 6 25
+./bsddialog --title " yesno " --yesno "Hello World!" 6 25
diff --git a/lib/GNUMakefile b/lib/GNUMakefile
index 318b1218f9c0..842e03494b4c 100644
--- a/lib/GNUMakefile
+++ b/lib/GNUMakefile
@@ -1,17 +1,17 @@
# PUBLIC DOMAIN - NO WARRANTY, see:
-# <http://creativecommons.org/publicdomain/zero/1.0/>
+# <http://creativecommons.org/publicdomain/zero/1.0/>
#
# Written in 2021 by Alfonso Sabato Siciliano
-VERSION = 0.0.2
+VERSION = 0.1
LIBRARY = bsddialog
LIBRARY_SO = lib${LIBRARY:=.so}
HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h
SOURCES = barbox.c formbox.c infobox.c libbsddialog.c lib_util.c menubox.c \
messagebox.c textbox.c theme.c timebox.c
OBJECTS = $(SOURCES:.c=.o)
-CFLAGS = -g -Wall -Werror -fpic
-LDFLAGS = -lform -lncurses -ltinfo
+CFLAGS = -Wall -Werror -fpic
+LDFLAGS = -lformw -lncursesw -ltinfo
LIBFLAG = -shared
RM = rm -f
diff --git a/lib/Makefile b/lib/Makefile
index e8f3ab6aae02..d9f2ce8ed69b 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,56 +1,55 @@
-# Any copyright is dedicated to the Public Domain, see:
+# PUBLIC DOMAIN - NO WARRANTY, see:
# <http://creativecommons.org/publicdomain/zero/1.0/>
#
# Written in 2021 by Alfonso Sabato Siciliano
-VERSION = 0.0.2
+VERSION = 0.1
LIBRARY = bsddialog
LIBRARY_SO = lib${LIBRARY:=.so}
+LIBRARY_A = lib${LIBRARY:=.a}
HEADERS = bsddialog.h bsddialog_theme.h bsddialog_progressview.h
SOURCES = barbox.c formbox.c infobox.c libbsddialog.c lib_util.c menubox.c \
messagebox.c textbox.c theme.c timebox.c
-OBJECTS= ${SOURCES:.c=.o}
-CFLAGS = -I/usr/local/include -fPIC -Wall -Wextra
-LDFLAGS = -fstack-protector-strong -shared -Wl,-x -Wl,--fatal-warnings \
- -Wl,--warn-shared-textrel -Wl,-soname,${LIBRARY_SO}.${VERSION}
+OBJECTS = ${SOURCES:.c=.o}
+CFLAGS += -fPIC -Wall -Wextra
+LDFLAGS += -fstack-protector-strong -shared -Wl,-x -Wl,--fatal-warnings \
+ -Wl,--warn-shared-textrel -Wl,-soname,${LIBRARY_SO}.${VERSION} \
+ -L/usr/lib -lformw -lncursesw -ltinfow
.if defined(DEBUG)
# `make -DDEBUG`
-CFLAGS += -g
+CFLAGS = -g -fPIC -Wall -Wextra
.else
CFLAGS += -O2 -pipe -std=gnu99 -Wno-format-zero-length \
-fstack-protector-strong -Qunused-arguments
.endif
-.if defined(PORTNCURSES)
-# PORT ncurses `make -DPORTNCURSES`
-CFLAGS += -DPORTNCURSES -I/usr/local/include
-LDFLAGS += -L/usr/local/lib -lformw -lncursesw -ltinfow
-.else
-# BASE ncurses
-LDFLAGS += -L/usr/lib -lformw -lncursesw -ltinfow
-.endif
-
-INSTALL_PREFIX=/usr/local
+LOCALBASE = /usr/local
LN = ln -s -f
RM = rm -f
CP = cp
GZIP = gzip -cn
LDCONFIG = /sbin/ldconfig -m
-MAN= ${OUTPUT}.3
-GZIP= gzip -cn
-MANDIR= /usr/local/share/man/man3
-INSTALL= install
-RM= rm -f
+MAN = ${OUTPUT}.3
+GZIP = gzip -cn
+MANDIR = ${LOCALBASE}/share/man/man3
+INSTALL = install
+RM = rm -f
+
+all : man ${LIBRARY}
-#all : man ${LIBRARY}
-all : ${LIBRARY}
+${LIBRARY}: ${LIBRARY_SO} ${LIBRARY_A}
-${LIBRARY}: ${OBJECTS}
+${LIBRARY_SO}.${VERSION}: ${OBJECTS}
${CC} ${LDFLAGS} ${.ALLSRC} -o ${LIBRARY_SO}.${VERSION}
- # LN for devel
+
+${LIBRARY_SO}: ${LIBRARY_SO}.${VERSION}
${LN} ${LIBRARY_SO}.${VERSION} ${LIBRARY_SO}
+${LIBRARY_A}: ${OBJECTS}
+ ${AR} cr ${.TARGET} ${OBJECTS}
+ ${RANLIB} ${.TARGET}
+
.c.o:
${CC} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
@@ -58,19 +57,20 @@ man:
${GZIP} ${LIBRARY}.3 > ${LIBRARY}.3.gz
clean:
- ${RM} ${LIBRARY_SO}* *.o *~ *.gz
+ ${RM} ${LIBRARY_SO}* *.o *~ *.gz ${LIBRARY_A}
install:
- ${CP} ${LIBRARY}.h ${INSTALL_PREFIX}/include
- ${CP} ${LIBRARY_SO}.${VERSION} ${INSTALL_PREFIX}/lib/
- ${LN} ${INSTALL_PREFIX}/lib/${LIBRARY_SO}.${VERSION} ${INSTALL_PREFIX}/lib/${LIBRARY_SO}
- ${LDCONFIG} ${INSTALL_PREFIX}/lib
- ${CP} ${LIBRARY}.3.gz ${INSTALL_PREFIX}/man/man3/
+ ${INSTALL} -m 644 ${HEADERS} ${LOCALBASE}/include
+ ${INSTALL} -m 644 -s ${LIBRARY_SO}.${VERSION} ${LOCALBASE}/lib/
+ ${INSTALL} -l rs ${LOCALBASE}/lib/${LIBRARY_SO}.${VERSION} ${LOCALBASE}/lib/${LIBRARY_SO}
+ ${INSTALL} -m 644 ${LIBRARY_A} ${LOCALBASE}/lib
+ ${LDCONFIG} ${LOCALBASE}/lib
+ ${INSTALL} -m 644 ${LIBRARY}.3.gz ${MNADIR}
unistall:
- ${RM} ${INSTALL_PREFIX}/include/${LIBRARY}.h
- ${RM} ${INSTALL_PREFIX}/lib/${LIBRARY_SO}
- ${RM} ${INSTALL_PREFIX}/lib/${LIBRARY_SO}.${VERSION}
- ${LDCONFIG} ${INSTALL_PREFIX}/lib
- ${RM} ${INSTALL_PREFIX}/man/man3/${LIBRARY}.3.gz
+ ${RM} ${LOCALBASE}/include/${LIBRARY}*.h
+ ${RM} ${LOCALBASE}/lib/${LIBRARY_SO}
+ ${RM} ${LOCALBASE}/lib/${LIBRARY_SO}.${VERSION}
+ ${LDCONFIG} ${LOCALBASE}/lib
+ ${RM} ${MANDIR}/${LIBRARY}.3.gz
diff --git a/lib/barbox.c b/lib/barbox.c
index d67dfb953992..72000fad747c 100644
--- a/lib/barbox.c
+++ b/lib/barbox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,26 +28,19 @@
#include <sys/param.h>
#include <ctype.h>
-#ifdef PORTNCURSES
-#include <ncurses/ncurses.h>
-#else
-#include <ncurses.h>
-#endif
+#include <curses.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include <unistd.h>
#include "bsddialog.h"
#include "bsddialog_progressview.h"
-#include "lib_util.h"
#include "bsddialog_theme.h"
+#include "lib_util.h"
-#define BARMARGIN 3
-#define MINBARWIDTH 10
-#define MINWIDTH (VBORDERS + MINBARWIDTH + BARMARGIN * 2)
-#define MINHEIGHT 7 /* without text */
-
-/* "Bar": gauge - mixedgauge - rangebox - pause - progressview */
+#define BARPADDING 3
+#define MINBARWIDTH (15 + BARPADDING * 2)
bool bsddialog_interruptprogview;
bool bsddialog_abortprogview;
@@ -56,11 +49,11 @@ int bsddialog_total_progview;
extern struct bsddialog_theme t;
static void
-draw_perc_bar(WINDOW *win, int y, int x, int size, int perc, bool withlabel,
+draw_bar(WINDOW *win, int y, int x, int size, int perc, bool withlabel,
int label)
{
- char labelstr[128];
int i, blue_x, color;
+ char labelstr[128];
blue_x = (int)((perc*(size))/100);
@@ -77,7 +70,7 @@ draw_perc_bar(WINDOW *win, int y, int x, int size, int perc, bool withlabel,
else
sprintf(labelstr, "%3d%%", perc);
wmove(win, y, x + size/2 - 2);
- for (i=0; i < (int) strlen(labelstr); i++) {
+ for (i = 0; i < (int)strlen(labelstr); i++) {
color = (blue_x + 1 <= size/2 - (int)strlen(labelstr)/2 + i ) ?
t.bar.color : t.bar.f_color;
wattron(win, color);
@@ -88,49 +81,27 @@ draw_perc_bar(WINDOW *win, int y, int x, int size, int perc, bool withlabel,
static int
bar_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
- char *text, struct buttons *bs)
+ const char *text, struct buttons *bs)
{
- int maxword, maxline, nlines, buttonswidth;
-
- if (get_text_properties(conf, text, &maxword, &maxline, &nlines) != 0)
- return BSDDIALOG_ERROR;
+ int htext, wtext;
- buttonswidth = 0;
- if (bs != NULL) { /* gauge has not buttons */
- buttonswidth= bs->nbuttons * bs->sizebutton;
- if (bs->nbuttons > 0)
- buttonswidth += (bs->nbuttons-1) * t.button.space;
+ if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
+ if (text_size(conf, rows, cols, text, bs, 3, MINBARWIDTH,
+ &htext, &wtext) != 0)
+ return (BSDDIALOG_ERROR);
}
- if (cols == BSDDIALOG_AUTOSIZE) {
- *w = VBORDERS;
- /* buttons size */
- *w += buttonswidth;
- /* bar size */
- *w = MAX(*w, MINWIDTH);
- /* text size*/
- *w = MAX((int)(maxline + VBORDERS + t.text.hmargin * 2), *w);
- /* conf.auto_minwidth */
- *w = MAX(*w, (int)conf->auto_minwidth);
- /* avoid terminal overflow */
- *w = MIN(*w, widget_max_width(conf));
- }
+ if (cols == BSDDIALOG_AUTOSIZE)
+ *w = widget_min_width(conf, wtext, MINBARWIDTH, bs);
- if (rows == BSDDIALOG_AUTOSIZE) {
- *h = MINHEIGHT;
- if (maxword > 0)
- *h += 1;
- /* conf.auto_minheight */
- *h = MAX(*h, (int)conf->auto_minheight);
- /* avoid terminal overflow */
- *h = MIN(*h, widget_max_height(conf));
- }
+ if (rows == BSDDIALOG_AUTOSIZE)
+ *h = widget_min_height(conf, htext, 3 /* bar */, bs != NULL);
return (0);
}
static int
-bar_checksize(char *text, int rows, int cols, struct buttons *bs)
+bar_checksize(int rows, int cols, struct buttons *bs)
{
int minheight, minwidth;
@@ -140,200 +111,213 @@ bar_checksize(char *text, int rows, int cols, struct buttons *bs)
if (bs->nbuttons > 0)
minwidth += (bs->nbuttons-1) * t.button.space;
}
- minwidth = MAX(minwidth + VBORDERS, MINBARWIDTH);
+ minwidth = MAX(minwidth, MINBARWIDTH);
+ minwidth += VBORDERS;
- if (cols< minwidth)
- RETURN_ERROR("Few cols for this widget");
+ if (cols < minwidth)
+ RETURN_ERROR("Few cols to draw bar and/or buttons");
- minheight = MINHEIGHT + ((text != NULL && strlen(text) > 0) ? 1 : 0);
+ minheight = HBORDERS + 3;
+ if (bs != NULL)
+ minheight += 2;
if (rows < minheight)
- RETURN_ERROR("Few rows for this mixedgauge");
+ RETURN_ERROR("Few rows to draw bar");
- return 0;
+ return (0);
}
int
-bsddialog_gauge(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int perc)
+bsddialog_gauge(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int perc, int fd, const char *sep)
{
- WINDOW *widget, *textpad, *bar, *shadow;
- char input[2048], ntext[2048], *pntext;
- int y, x, h, w, htextpad;
bool mainloop;
+ int y, x, h, w, fd2;
+ FILE *input;
+ WINDOW *widget, *textpad, *bar, *shadow;
+ char inputbuf[2048], ntext[2048], *pntext;
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (bar_autosize(conf, rows, cols, &h, &w, text, NULL) != 0)
- return BSDDIALOG_ERROR;
- if (bar_checksize(text, h, w, NULL) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
+ if (bar_checksize(h, w, NULL) != 0)
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
- if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
- &textpad, &htextpad, text, false) != 0)
- return BSDDIALOG_ERROR;
+ if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, NULL,
+ false) != 0)
+ return (BSDDIALOG_ERROR);
bar = new_boxed_window(conf, y+h-4, x+3, 3, w-6, RAISED);
- mainloop = true;
+ mainloop = (fd < 0) ? false : true;
+
+ if (mainloop) {
+ fd2 = dup(fd);
+ input = fdopen(fd2, "r");
+ if (input == NULL)
+ RETURN_ERROR("Cannot build FILE* from fd");
+ } else
+ input = NULL;
+
while (mainloop) {
wrefresh(widget);
- prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-4,
- x+w-1-t.text.hmargin);
- draw_perc_bar(bar, 1, 1, w-8, perc, false, -1 /*unused*/);
+ prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-4,
+ x+w-1-TEXTHMARGIN);
+ draw_borders(conf, bar, 3, w-6, RAISED);
+ draw_bar(bar, 1, 1, w-8, perc, false, -1 /*unused*/);
wrefresh(bar);
while (true) {
- scanf("%s", input);
- if (strcmp(input,"EOF") == 0) {
+ fscanf(input, "%s", inputbuf);
+ if (strcmp(inputbuf,"EOF") == 0) {
mainloop = false;
break;
}
- if (strcmp(input,"XXX") == 0)
+ if (strcmp(inputbuf, sep) == 0)
break;
}
- scanf("%d", &perc);
+ if (mainloop == false)
+ break;
+ fscanf(input, "%d", &perc);
perc = perc < 0 ? 0 : perc;
perc = perc > 100 ? 100 : perc;
- htextpad = 1;
- wclear(textpad);
pntext = &ntext[0];
ntext[0] = '\0';
while (true) {
- scanf("%s", input);
- if (strcmp(input,"EOF") == 0) {
+ fscanf(input, "%s", inputbuf);
+ if (strcmp(inputbuf,"EOF") == 0) {
mainloop = false;
break;
}
- if (strcmp(input,"XXX") == 0)
+ if (strcmp(inputbuf, sep) == 0)
break;
+ strcpy(pntext, inputbuf);
+ pntext += strlen(inputbuf);
pntext[0] = ' ';
pntext++;
- strcpy(pntext, input);
- pntext += strlen(input);
}
- print_textpad(conf, textpad, &htextpad, w-2-t.text.hmargin*2,
- ntext);
+ if (update_dialog(conf, shadow, widget, y, x, h, w, textpad,
+ ntext, NULL, false) != 0)
+ return (BSDDIALOG_ERROR);
}
+ if (input != NULL)
+ fclose(input);
delwin(bar);
- end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
+ end_dialog(conf, shadow, widget, textpad);
- return BSDDIALOG_OK;
+ return (BSDDIALOG_OK);
}
-
/* Mixedgauge */
static int
-mixedgauge(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int mainperc, unsigned int nminibars, char **minilabels,
+do_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows, int cols,
+ unsigned int mainperc, unsigned int nminibars, const char **minilabels,
int *minipercs, bool color)
{
- WINDOW *widget, *textpad, *bar, *shadow;
- int i, output, miniperc, y, x, h, w, max_minbarlen;
- int maxword, maxline, nlines, htextpad, ypad;
+ int i, output, miniperc, y, x, h, w, ypad, max_minbarlen;
+ int htextpad, htext, wtext;
int colorperc, red, green;
+ WINDOW *widget, *textpad, *bar, *shadow;
char states[12][14] = {
- " Succeeded ", /* 0 */
- " Failed ", /* 1 */
- " Passed ", /* 2 */
- " Completed ", /* 3 */
- " Checked ", /* 4 */
- " Done ", /* 5 */
- " Skipped ", /* 6 */
- " In Progress ", /* 7 */
- "(blank) ", /* 8 */
- " N/A ", /* 9 */
- " Pending ", /* 10 */
- " UNKNOWN ", /* 10+ */
+ " Succeeded ", /* -1 */
+ " Failed ", /* -2 */
+ " Passed ", /* -3 */
+ " Completed ", /* -4 */
+ " Checked ", /* -5 */
+ " Done ", /* -6 */
+ " Skipped ", /* -7 */
+ " In Progress ", /* -8 */
+ "(blank) ", /* -9 */
+ " N/A ", /* -10 */
+ " Pending ", /* -11 */
+ " UNKNOWN ", /* < -11, no API */
};
red = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_RED, BSDDIALOG_BOLD);
green = bsddialog_color(BSDDIALOG_WHITE,BSDDIALOG_GREEN,BSDDIALOG_BOLD);
max_minbarlen = 0;
- for (i=0; i < (int)nminibars; i++)
+ for (i = 0; i < (int)nminibars; i++)
max_minbarlen = MAX(max_minbarlen, (int)strlen(minilabels[i]));
max_minbarlen += 3 + 16 /* seps + [...] or mainbar */;
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
/* mixedgauge autosize */
- if (get_text_properties(conf, text, &maxword, &maxline, &nlines) != 0)
- return BSDDIALOG_ERROR;
-
- if (cols == BSDDIALOG_AUTOSIZE) {
- w = max_minbarlen + HBORDERS;
- w = MAX(w, maxline + 4);
- w = MAX(w, (int)conf->auto_minwidth);
- w = MIN(w, widget_max_width(conf) - 1);
- }
- if (rows == BSDDIALOG_AUTOSIZE) {
- h = 5; /* borders + mainbar */
- h += nminibars;
- h += (strlen(text) > 0 ? 3 : 0);
- h = MAX(h, (int)conf->auto_minheight);
- h = MIN(h, widget_max_height(conf) -1);
+ if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
+ if (text_size(conf, rows, cols, text, NULL, nminibars + 3,
+ max_minbarlen, &htext, &wtext) != 0)
+ return (BSDDIALOG_ERROR);
}
+ if (cols == BSDDIALOG_AUTOSIZE)
+ w = widget_min_width(conf, wtext, max_minbarlen, NULL);
+ if (rows == BSDDIALOG_AUTOSIZE)
+ h = widget_min_height(conf, htext, nminibars + 3, false);
/* mixedgauge checksize */
if (w < max_minbarlen + 2)
RETURN_ERROR("Few cols for this mixedgauge");
- if (h < 5 + (int)nminibars + (strlen(text) > 0 ? 1 : 0))
+ if (h < 5 + (int)nminibars)
RETURN_ERROR("Few rows for this mixedgauge");
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
- output = new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w,
- RAISED, &textpad, &htextpad, text, false);
+ output = new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text,
+ NULL, false);
if (output == BSDDIALOG_ERROR)
- return output;
+ return (output);
/* mini bars */
- for (i=0; i < (int)nminibars; i++) {
+ for (i = 0; i < (int)nminibars; i++) {
miniperc = minipercs[i];
- if (miniperc == 8)
+ if (miniperc == BSDDIALOG_MG_BLANK)
continue;
/* label */
- if (color && (miniperc == 7 || miniperc < 0))
+ if (color && (miniperc >= 0))
wattron(widget, A_BOLD);
mvwaddstr(widget, i+1, 2, minilabels[i]);
wattroff(widget, A_BOLD);
/* perc */
- if (miniperc > 10)
+ if (miniperc < -11)
mvwaddstr(widget, i+1, w-2-15, states[11]);
- else if (miniperc >= 0 && miniperc <= 10) {
+ else if (miniperc < 0) {
mvwaddstr(widget, i+1, w-2-15, "[ ]");
- if (color && miniperc == 1) /* Failed */
+ colorperc = -1;
+ if (color && miniperc == BSDDIALOG_MG_FAILED)
colorperc = red;
- if (color && miniperc == 5) /* Done */
+ if (color && miniperc == BSDDIALOG_MG_DONE)
colorperc = green;
- if (color && (miniperc == 1 || miniperc == 5))
+ if (colorperc != -1)
wattron(widget, colorperc);
+ miniperc = abs(miniperc + 1);
mvwaddstr(widget, i+1, 1+w-2-15, states[miniperc]);
- if (color && (miniperc == 1 || miniperc == 5))
+ if (colorperc != -1)
wattroff(widget, colorperc);
}
- else { /* miniperc < 0 */
- miniperc = abs(miniperc);
+ else { /* miniperc >= 0 */
+ if (miniperc > 100)
+ miniperc = 100;
mvwaddstr(widget, i+1, w-2-15, "[ ]");
- draw_perc_bar(widget, i+1, 1+w-2-15, 13, miniperc,
- false, -1 /*unused*/);
+ draw_bar(widget, i+1, 1+w-2-15, 13, miniperc, false,
+ -1 /*unused*/);
}
}
wrefresh(widget);
- ypad = y + h - 5 - htextpad;
+ getmaxyx(textpad, htextpad, i /* unused */);
+ ypad = y + h - 4 - htextpad;
ypad = ypad < y+(int)nminibars ? y+nminibars : ypad;
prefresh(textpad, 0, 0, ypad, x+2, y+h-4, x+w-2);
-
+
/* main bar */
bar = new_boxed_window(conf, y+h -4, x+3, 3, w-6, RAISED);
-
- draw_perc_bar(bar, 1, 1, w-8, mainperc, false, -1 /*unused*/);
+
+ draw_bar(bar, 1, 1, w-8, mainperc, false, -1 /*unused*/);
wattron(bar, t.bar.color);
mvwaddstr(bar, 0, 2, "Overall Progress");
@@ -344,48 +328,46 @@ mixedgauge(struct bsddialog_conf *conf, char* text, int rows, int cols,
/* getch(); port ncurses shows nothing */
delwin(bar);
- end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
+ end_dialog(conf, shadow, widget, textpad);
- return BSDDIALOG_OK;
+ return (BSDDIALOG_OK);
}
int
-bsddialog_mixedgauge(struct bsddialog_conf *conf, char* text, int rows,
- int cols, unsigned int mainperc, unsigned int nminibars, char **minilabels,
- int *minipercs)
+bsddialog_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int mainperc, unsigned int nminibars,
+ const char **minilabels, int *minipercs)
{
int output;
- output = mixedgauge(conf, text, rows, cols, mainperc, nminibars,
+ output = do_mixedgauge(conf, text, rows, cols, mainperc, nminibars,
minilabels, minipercs, false);
return (output);
}
int
-bsddialog_progressview (struct bsddialog_conf *conf, char * text, int rows,
+bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
int cols, struct bsddialog_progviewconf *pvconf, unsigned int nminibar,
struct bsddialog_fileminibar *minibar)
{
- int perc, output;
- int *minipercs;
- unsigned int i;
- char **minilabels;
- unsigned int mainperc, totaltodo;
- time_t tstart, told, tnew, refresh;
bool update;
+ int perc, output, *minipercs;
+ unsigned int i, mainperc, totaltodo;
float readforsec;
+ const char **minilabels;
+ time_t tstart, told, tnew, refresh;
if ((minilabels = calloc(nminibar, sizeof(char*))) == NULL)
- RETURN_ERROR("Cannot allocate memory for minilabels\n");
+ RETURN_ERROR("Cannot allocate memory for minilabels");
if ((minipercs = calloc(nminibar, sizeof(int))) == NULL)
- RETURN_ERROR("Cannot allocate memory for minipercs\n");
+ RETURN_ERROR("Cannot allocate memory for minipercs");
totaltodo = 0;
- for(i=0; i<nminibar; i++) {
- totaltodo += minibar[i].size;
+ for (i = 0; i < nminibar; i++) {
+ totaltodo += minibar[i].size;
minilabels[i] = minibar[i].label;
- minipercs[i] = 10; /*Pending*/
+ minipercs[i] = minibar[i].status;
}
refresh = pvconf->refresh == 0 ? 0 : pvconf->refresh - 1;
@@ -402,15 +384,15 @@ bsddialog_progressview (struct bsddialog_conf *conf, char * text, int rows,
time(&tnew);
if (update || tnew > told + refresh) {
- output = mixedgauge(conf, text, rows, cols, mainperc,
+ output = do_mixedgauge(conf, text, rows, cols, mainperc,
nminibar, minilabels, minipercs, true);
if (output == BSDDIALOG_ERROR)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
- move(LINES-1, 2);
+ move(SCREENLINES - 1, 2);
clrtoeol();
- readforsec = ((tnew - tstart) == 0) ?
- 0 : bsddialog_total_progview / (float)(tnew - tstart);
+ readforsec = ((tnew - tstart) == 0) ? 0 :
+ bsddialog_total_progview / (float)(tnew - tstart);
printw(pvconf->fmtbottomstr, bsddialog_total_progview,
readforsec);
refresh();
@@ -421,22 +403,20 @@ bsddialog_progressview (struct bsddialog_conf *conf, char * text, int rows,
if (i >= nminibar)
break;
- if (minibar[i].status == 1) /* Failed*/
+ if (minibar[i].status == BSDDIALOG_MG_FAILED)
break;
perc = pvconf->callback(&minibar[i]);
- if (minibar[i].status == 5) {/* ||prec >= 100) Done */
- minipercs[i] = 5;
+ if (minibar[i].status == BSDDIALOG_MG_DONE) { /*||perc >= 100)*/
+ minipercs[i] = BSDDIALOG_MG_DONE;
update = true;
i++;
- } else if (minibar[i].status == 1 || perc < 0) { /* Failed */
- minipercs[i] = 1;
+ } else if (minibar[i].status == BSDDIALOG_MG_FAILED || perc < 0) {
+ minipercs[i] = BSDDIALOG_MG_FAILED;
update = true;
- } else if (perc == 0)
- minipercs[i] = 7; /* In progress */
- else /* perc > 0 */
- minipercs[i] = -(perc);
+ } else /* perc >= 0 */
+ minipercs[i] = perc;
}
free(minilabels);
@@ -445,14 +425,14 @@ bsddialog_progressview (struct bsddialog_conf *conf, char * text, int rows,
}
int
-bsddialog_rangebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
- int min, int max, int *value)
+bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, int min, int max, int *value)
{
- WINDOW *widget, *textpad, *bar, *shadow;
- int i, y, x, h, w, htextpad;
bool loop, buttupdate, barupdate;
+ int y, x, h, w;
int input, currvalue, output, sizebar, bigchange, positions;
float perc;
+ WINDOW *widget, *textpad, *bar, *shadow;
struct buttons bs;
if (value == NULL)
@@ -464,41 +444,41 @@ bsddialog_rangebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
currvalue = *value;
positions = max - min + 1;
- get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
- BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
+ get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0)
- return BSDDIALOG_ERROR;
- if (bar_checksize(text, h, w, &bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
+ if (bar_checksize(h, w, &bs) != 0)
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
- if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
- &textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
+ if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
+ true) != 0)
+ return (BSDDIALOG_ERROR);
- prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-7,
- x+w-1-t.text.hmargin);
+ doupdate();
- sizebar = w - HBORDERS - 2 - BARMARGIN * 2;
+ prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-7, x+w-1-TEXTHMARGIN);
+
+ sizebar = w - HBORDERS - 2 - BARPADDING * 2;
bigchange = MAX(1, sizebar/10);
- bar = new_boxed_window(conf, y + h - 6, x + 1 + BARMARGIN, 3,
+ bar = new_boxed_window(conf, y + h - 6, x + 1 + BARPADDING, 3,
sizebar + 2, RAISED);
loop = buttupdate = barupdate = true;
- while(loop) {
+ while (loop) {
if (buttupdate) {
- draw_buttons(widget, h-2, w, bs, true);
+ draw_buttons(widget, bs, true);
wrefresh(widget);
buttupdate = false;
}
if (barupdate) {
perc = ((float)(currvalue - min)*100) / (positions-1);
- draw_perc_bar(bar, 1, 1, sizebar, perc, true, currvalue);
+ draw_bar(bar, 1, 1, sizebar, perc, true, currvalue);
barupdate = false;
wrefresh(bar);
}
@@ -512,8 +492,10 @@ bsddialog_rangebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
loop = false;
break;
case 27: /* Esc */
- output = BSDDIALOG_ESC;
- loop = false;
+ if (conf->key.enable_esc) {
+ output = BSDDIALOG_ESC;
+ loop = false;
+ }
break;
case '\t': /* TAB */
bs.curr = (bs.curr + 1) % bs.nbuttons;
@@ -567,125 +549,108 @@ bsddialog_rangebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
if (conf->f1_file == NULL && conf->f1_message == NULL)
break;
if (f1help(conf) != 0)
- return BSDDIALOG_ERROR;
- /* No break! the terminal size can change */
+ return (BSDDIALOG_ERROR);
+ /* No break, screen size can change */
case KEY_RESIZE:
- hide_widget(y, x, h, w,conf->shadow);
-
- /*
- * Unnecessary, but, when the columns decrease the
- * following "refresh" seem not work
- */
+ /* Important for decreasing screen */
+ hide_widget(y, x, h, w, conf->shadow);
refresh();
-
+
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
- if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0)
- return BSDDIALOG_ERROR;
- if (bar_checksize(text, h, w, &bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
+ if (bar_autosize(conf, rows, cols, &h, &w, text,
+ &bs) != 0)
+ return (BSDDIALOG_ERROR);
+ if (bar_checksize(h, w, &bs) != 0)
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
-
- wclear(shadow);
- mvwin(shadow, y + t.shadow.h, x + t.shadow.w);
- wresize(shadow, h, w);
+ return (BSDDIALOG_ERROR);
- wclear(widget);
- mvwin(widget, y, x);
- wresize(widget, h, w);
+ if (update_dialog(conf, shadow, widget,y, x, h, w,
+ textpad, text, &bs, true) != 0)
+ return (BSDDIALOG_ERROR);
- htextpad = 1;
- wclear(textpad);
- wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2);
+ doupdate();
- sizebar = w - HBORDERS - 2 - BARMARGIN * 2;
+ sizebar = w - HBORDERS - 2 - BARPADDING * 2;
bigchange = MAX(1, sizebar/10);
wclear(bar);
- mvwin(bar, y + h - 6, x + 1 + BARMARGIN);
+ mvwin(bar, y + h - 6, x + 1 + BARPADDING);
wresize(bar, 3, sizebar + 2);
+ draw_borders(conf, bar, 3, sizebar+2, RAISED);
- if(update_widget_withtextpad(conf, shadow, widget, h, w,
- RAISED, textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
-
- prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-7,
- x+w-1-t.text.hmargin);
-
- draw_borders(conf, bar, 3, sizebar + 2, RAISED);
+ prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-7,
+ x+w-1-TEXTHMARGIN);
barupdate = true;
- buttupdate = true;
break;
default:
- for (i = 0; i < (int) bs.nbuttons; i++)
- if (tolower(input) == tolower((bs.label[i])[0])) {
- output = bs.value[i];
- loop = false;
+ if (shortcut_buttons(input, &bs)) {
+ output = bs.value[bs.curr];
+ loop = false;
}
}
}
delwin(bar);
- end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
+ end_dialog(conf, shadow, widget, textpad);
- return output;
+ return (output);
}
int
-bsddialog_pause(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int sec)
+bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int sec)
{
- WINDOW *widget, *textpad, *bar, *shadow;
- int i, output, y, x, h, w, htextpad;
bool loop, buttupdate, barupdate;
- int input, tout, sizebar;
+ int output, y, x, h, w, input, tout, sizebar;
float perc;
+ WINDOW *widget, *textpad, *bar, *shadow;
struct buttons bs;
- get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
- BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
+ get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0)
- return BSDDIALOG_ERROR;
- if (bar_checksize(text, h, w, &bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
+ if (bar_checksize(h, w, &bs) != 0)
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
- if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
- &textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
-
- prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-7,
- x+w-1-t.text.hmargin);
+ if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
+ true) != 0)
+ return (BSDDIALOG_ERROR);
+
+ doupdate();
- sizebar = w - HBORDERS - 2 - BARMARGIN * 2;
- bar = new_boxed_window(conf, y + h - 6, x + 1 + BARMARGIN, 3,
+ prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-7, x+w-1-TEXTHMARGIN);
+
+ sizebar = w - HBORDERS - 2 - BARPADDING * 2;
+ bar = new_boxed_window(conf, y + h - 6, x + 1 + BARPADDING, 3,
sizebar + 2, RAISED);
tout = sec;
nodelay(stdscr, TRUE);
timeout(1000);
loop = buttupdate = barupdate = true;
- while(loop) {
+ while (loop) {
if (barupdate) {
perc = (float)tout * 100 / sec;
- draw_perc_bar(bar, 1, 1, sizebar, perc, true, tout);
+ draw_bar(bar, 1, 1, sizebar, perc, true, tout);
barupdate = false;
wrefresh(bar);
}
if (buttupdate) {
- draw_buttons(widget, h-2, w, bs, true);
+ draw_buttons(widget, bs, true);
wrefresh(widget);
buttupdate = false;
}
input = getch();
- if(input < 0) { /* timeout */
+ if (input < 0) { /* timeout */
tout--;
if (tout < 0) {
output = BSDDIALOG_TIMEOUT;
@@ -703,8 +668,10 @@ bsddialog_pause(struct bsddialog_conf *conf, char* text, int rows, int cols,
loop = false;
break;
case 27: /* Esc */
- output = BSDDIALOG_ESC;
- loop = false;
+ if (conf->key.enable_esc) {
+ output = BSDDIALOG_ESC;
+ loop = false;
+ }
break;
case '\t': /* TAB */
bs.curr = (bs.curr + 1) % bs.nbuttons;
@@ -726,60 +693,44 @@ bsddialog_pause(struct bsddialog_conf *conf, char* text, int rows, int cols,
if (conf->f1_file == NULL && conf->f1_message == NULL)
break;
if (f1help(conf) != 0)
- return BSDDIALOG_ERROR;
- /* No break! the terminal size can change */
+ return (BSDDIALOG_ERROR);
+ /* No break, screen size can change */
case KEY_RESIZE:
- hide_widget(y, x, h, w,conf->shadow);
-
- /*
- * Unnecessary, but, when the columns decrease the
- * following "refresh" seem not work
- */
+ /* Important for decreasing screen */
+ hide_widget(y, x, h, w, conf->shadow);
refresh();
-
+
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
- if (bar_autosize(conf, rows, cols, &h, &w, text, &bs) != 0)
- return BSDDIALOG_ERROR;
- if (bar_checksize(text, h, w, &bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
+ if (bar_autosize(conf, rows, cols, &h, &w, text,
+ &bs) != 0)
+ return (BSDDIALOG_ERROR);
+ if (bar_checksize(h, w, &bs) != 0)
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
-
- wclear(shadow);
- mvwin(shadow, y + t.shadow.h, x + t.shadow.w);
- wresize(shadow, h, w);
+ return (BSDDIALOG_ERROR);
- wclear(widget);
- mvwin(widget, y, x);
- wresize(widget, h, w);
+ if (update_dialog(conf, shadow, widget,y, x, h, w,
+ textpad, text, &bs, true) != 0)
+ return (BSDDIALOG_ERROR);
- htextpad = 1;
- wclear(textpad);
- wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2);
+ doupdate();
- sizebar = w - HBORDERS - 2 - BARMARGIN * 2;
+ sizebar = w - HBORDERS - 2 - BARPADDING * 2;
wclear(bar);
- mvwin(bar, y + h - 6, x + 1 + BARMARGIN);
+ mvwin(bar, y + h - 6, x + 1 + BARPADDING);
wresize(bar, 3, sizebar + 2);
+ draw_borders(conf, bar, 3, sizebar+2, LOWERED);
- if(update_widget_withtextpad(conf, shadow, widget, h, w,
- RAISED, textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
-
- prefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-7,
- x+w-1-t.text.hmargin);
-
- draw_borders(conf, bar, 3, sizebar + 2, RAISED);
+ prefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-7,
+ x+w-1-TEXTHMARGIN);
barupdate = true;
- buttupdate = true;
break;
default:
- for (i = 0; i < (int) bs.nbuttons; i++)
- if (tolower(input) == tolower((bs.label[i])[0])) {
- output = bs.value[i];
- loop = false;
+ if (shortcut_buttons(input, &bs)) {
+ output = bs.value[bs.curr];
+ loop = false;
}
}
}
@@ -787,7 +738,7 @@ bsddialog_pause(struct bsddialog_conf *conf, char* text, int rows, int cols,
nodelay(stdscr, FALSE);
delwin(bar);
- end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
+ end_dialog(conf, shadow, widget, textpad);
- return output;
-}
+ return (output);
+} \ No newline at end of file
diff --git a/lib/bsddialog.3 b/lib/bsddialog.3
index 0264c29e4470..4139970626b5 100644
--- a/lib/bsddialog.3
+++ b/lib/bsddialog.3
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 2021 Alfonso Sabato Siciliano
+.\" Copyright (c) 2021-2022 Alfonso Sabato Siciliano
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -22,21 +22,20 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd December 16, 2021
+.Dd January 23, 2022
.Dt BSDDIALOG 3
.Os
.Sh NAME
.Nm bsddialog_backtitle ,
.Nm bsddialog_clearterminal ,
.Nm bsddialog_color ,
-.Nm bsddialog_buildlist ,
.Nm bsddialog_checklist ,
.Nm bsddialog_datebox ,
.Nm bsddialog_end ,
.Nm bsddialog_form ,
.Nm bsddialog_gauge ,
.Nm bsddialog_geterror ,
-.Nm bsddialog_get_theme
+.Nm bsddialog_get_theme ,
.Nm bsddialog_infobox ,
.Nm bsddialog_init ,
.Nm bsddialog_initconf ,
@@ -52,58 +51,21 @@
.Nm bsddialog_textbox ,
.Nm bsddialog_timebox ,
.Nm bsddialog_yesno
-.Nd terminal dialogs and widgets
+.Nd TUI dialogs
.Sh LIBRARY
.Lb libbsddialog
.Sh SYNOPSIS
.In bsddialog.h
-
-.Fd #define LIBBSDDIALOG_VERSION
-
-.Fd #define BSDDIALOG_ERROR
-.Fd #define BSDDIALOG_OK
-.Fd #define BSDDIALOG_YES
-.Fd #define BSDDIALOG_CANCEL
-.Fd #define BSDDIALOG_NO
-.Fd #define BSDDIALOG_HELP
-.Fd #define BSDDIALOG_EXTRA
-.Fd #define BSDDIALOG_ITEM_HELP
-.Fd #define BSDDIALOG_TIMEOUT
-.Fd #define BSDDIALOG_ESC
-.Fd #define BSDDIALOG_GENERIC1
-.Fd #define BSDDIALOG_GENERIC2
-
-.Fd #define BSDDIALOG_FULLSCREEN
-.Fd #define BSDDIALOG_AUTOSIZE
-.Fd #define BSDDIALOG_CENTER
-
-.Fd struct bsddialog_conf
-.Fd struct bsddialog_menuitem
-.Fd enum bsddialog_grouptype
-.Fd struct bsddialog_menugroup
-.Fd struct bsddialog_formitem
-
-.Ft int
-.Fn bsddialog_backtitle "struct bsddialog_conf *conf" "char *backtitle"
.Ft int
-.Fo bsddialog_buildlist
-.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
-.Fa "int rows"
-.Fa "int cols"
-.Fa "unsigned int menurows"
-.Fa "int nitems"
-.Fa "struct bsddialog_menuitem *items"
-.Fa "int *focusitem"
-.Fc
+.Fn bsddialog_backtitle "struct bsddialog_conf *conf" "const char *backtitle"
.Ft int
.Fo bsddialog_checklist
.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
+.Fa "const char *text"
.Fa "int rows"
.Fa "int cols"
.Fa "unsigned int menurows"
-.Fa "int nitems"
+.Fa "unsigned int nitems"
.Fa "struct bsddialog_menuitem *items"
.Fa "int *focusitem"
.Fc
@@ -112,7 +74,7 @@
.Ft int
.Fo bsddialog_datebox"
.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
+.Fa "const char *text"
.Fa "int rows"
.Fa "int cols"
.Fa "unsigned int *yy"
@@ -124,27 +86,29 @@
.Ft int
.Fo bsddialog_form
.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
+.Fa "const char *text"
.Fa "int rows"
.Fa "int cols"
-.Fa "unsigned int formheight"
+.Fa "unsigned int formrows"
.Fa "unsigned int nitems"
.Fa "struct bsddialog_formitem *items"
.Fc
.Ft int
.Fo bsddialog_gauge
.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
+.Fa "const char *text"
.Fa "int rows"
.Fa "int cols"
.Fa "unsigned int perc"
+.Fa "int fd"
+.Fa "const char *sep"
.Fc
.Ft const char *
.Fn bsddialog_geterror "void"
.Ft int
.Fo bsddialog_infobox
.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
+.Fa "const char *text"
.Fa "int rows"
.Fa "int cols"
.Fc
@@ -155,18 +119,18 @@
.Ft int
.Fo bsddialog_menu
.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
+.Fa "const char *text"
.Fa "int rows"
.Fa "int cols"
.Fa "unsigned int menurows"
-.Fa "int nitems"
+.Fa "unsigned int nitems"
.Fa "struct bsddialog_menuitem *items"
.Fa "int *focusitem"
.Fc
.Ft int
.Fo bsddialog_mixedgauge
.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
+.Fa "const char *text"
.Fa "int rows"
.Fa "int cols"
.Fa "unsigned int mainperc"
@@ -177,11 +141,11 @@
.Ft int
.Fo bsddialog_mixedlist
.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
+.Fa "const char *text"
.Fa "int rows"
.Fa "int cols"
.Fa "unsigned int menurows"
-.Fa "int ngroups"
+.Fa "unsigned int ngroups"
.Fa "struct bsddialog_menugroup *groups"
.Fa "int *focuslist"
.Fa "int *focusitem"
@@ -189,33 +153,33 @@
.Ft int
.Fo bsddialog_msgbox
.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
+.Fa "const char *text"
.Fa "int rows"
.Fa "int cols"
.Fc
.Ft int
.Fo bsddialog_pause
.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
+.Fa "const char *text"
.Fa "int rows"
.Fa "int cols"
-.Fa "unsigned int sec"
+.Fa "unsigned int seconds"
.Fc
.Ft int
.Fo bsddialog_radiolist
.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
+.Fa "const char *text"
.Fa "int rows"
.Fa "int cols"
.Fa "unsigned int menurows"
-.Fa "int nitems"
+.Fa "unsigned int nitems"
.Fa "struct bsddialog_menuitem *items"
.Fa "int *focusitem"
.Fc
.Ft int
.Fo bsddialog_rangebox
.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
+.Fa "const char *text"
.Fa "int rows"
.Fa "int cols"
.Fa "int min"
@@ -225,14 +189,14 @@
.Ft int
.Fo bsddialog_textbox
.Fa "struct bsddialog_conf *conf"
-.Fa "char* file"
+.Fa "const char *file"
.Fa "int rows"
.Fa "int cols"
.Fc
.Ft int
.Fo bsddialog_timebox
.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
+.Fa "const char *text"
.Fa "int rows"
.Fa "int cols"
.Fa "unsigned int *hh"
@@ -242,25 +206,15 @@
.Ft int
.Fo bsddialog_yesno
.Fa "struct bsddialog_conf *conf"
-.Fa "char* text"
+.Fa "const char *text"
.Fa "int rows"
.Fa "int cols"
.Fc
-
.In bsddialog_theme.h
-
-.Fd #define BSDDIALOG_BOLD
-.Fd #define BSDDIALOG_REVERSE
-.Fd #define BSDDIALOG_UNDERLINE
-
-.Fd enum bsddialog_color
-.Fd enum bsddialog_default_theme
-.Fd struct bsddialog_theme
-
.Ft int
.Fo bsddialog_color
-.Fa "enum bsddialog_color background"
.Fa "enum bsddialog_color foreground"
+.Fa "enum bsddialog_color background"
.Fa "unsigned int flags"
.Fc
.Ft int
@@ -271,40 +225,84 @@
.Fn bsddialog_set_theme "struct bsddialog_theme *theme"
.Sh DESCRIPTION
The
-.Nm BSDDialog
-library is an API to write a tools with a Text User Interface. It can build
-dialogs and widgets: to show messages, to get input and to inform about a
-computation status.
+.Nm bsddialog
+library provides an API to build Text User Interface dialogs and widgets: to
+display messages, to get input and to inform about a computation status.
+.Pp
+.Fn bsddialog_init
+initializes the library, the only functions that can be called before is
+.Fn bsddialog_initconf
+described later.
+After the initialization the input and output should be handled via the library
+API.
+.Fn bsddialog_end
+restores the screen like before
+.Fn bsddialog_init ,
+then it is not possible to use the library functions.
+.Pp
+.Fn bsddialog_error
+returns a string to describe the last error, it should be called after a
+.Dv BSDDIALOG_ERROR
+returned value.
+.Fn bsddialog_clearterminal
+clears the screen.
+.Fn bsddialog_backtitle
+prints
+.Fa backtitle
+on the top of the screen, it is possible to set
+.Fa conf.ascii_lines
+and
+.Fa conf.no_lines ;
+.Fa conf
+is described later.
+.Pp
+Each
+.Fa char*
+argument has to be a well terminated string, can be empty
+.Pq Dq
+but not
+.Dv NULL .
+.Ss Dialogs
+The dialogs have common arguments.
+.Fa text
+is a string printed inside the dialog.
+.Fa rows
+and
+.Fa cols
+are height and width, their value can be between 2 and the screen size,
+.Dv BSDDIALOG_AUTOSIZE
+or
+.Dv BSDDIALOG_FULLSCREEN .
+.Fa conf
+is a struct to customize the dialog, it does not set global properties to the
+library.
.Pp
.Bd -literal -offset indent -compact
-/* size and position */
-#define BSDDIALOG_FULLSCREEN -1
-#define BSDDIALOG_AUTOSIZE 0
-#define BSDDIALOG_CENTER -1
-
struct bsddialog_conf {
bool ascii_lines;
- unsigned int aspect_ratio;
unsigned int auto_minheight;
unsigned int auto_minwidth;
- char *bottomtitle;
+ const char *bottomtitle;
bool clear;
- char *f1_file;
- char *f1_message;
- int *get_height;
- int *get_width;
+ const char *f1_file;
+ const char *f1_message;
+ int *get_height;
+ int *get_width;
bool no_lines;
bool shadow;
unsigned int sleep;
- char *title;
- int y;
- int x;
+ const char *title;
+ int y;
+ int x;
+ struct {
+ bool enable_esc;
+ } key;
struct {
- bool colors;
+ bool highlight;
+ unsigned int tablen;
} text;
struct {
bool align_left;
- char *default_item;
bool no_desc;
bool no_name;
bool shortcut_buttons;
@@ -317,35 +315,238 @@ struct bsddialog_conf {
} form;
struct {
bool without_ok;
- char *ok_label;
+ const char *ok_label;
bool with_extra;
- char *extra_label;
+ const char *extra_label;
bool without_cancel;
- char *cancel_label;
+ const char *cancel_label;
bool default_cancel;
bool with_help;
- char *help_label;
- char *exit_label;
- char *generic1_label;
- char *generic2_label;
- char *default_label;
+ const char *help_label;
+ const char *generic1_label;
+ const char *generic2_label;
+ const char *default_label;
} button;
};
.Ed
.Pp
-
-.Ss Dialogs
+.Bl -column -compact
+.It Fa conf.ascii_lines
+ascii characters to draw lines, default wide characters.
+.It Fa conf.auto_minheight
+minimum height if
+.Fa rows
+is
+.Dv BSDDIALOG_AUTOSIZE .
+.It Fa conf.auto_minwidth
+minimum width if
+.Fa cols
+is
+.Dv BSDDIALOG_AUTOSIZE .
+.It Fa conf.bottomtitle
+subtitle at the dialog bottom side.
+.It Fa conf.clear
+hide the dialog at exit.
+.It Fa conf.f1_file
+file to open if F1 is pressed.
+.It Fa conf.f1_message
+message to display if F1 is pressed.
+.It Fa conf.get_height
+if not
+.Dv NULL
+is set like the dialog height.
+.It Fa conf.get_width
+if not
+.Dv NULL
+is set like the dialog width.
+.It Fa conf.no_lines
+not draw lines.
+.It Fa conf.shadow
+draw shadow.
+.It Fa conf.sleep
+wait before to return, the value is in seconds.
+.It Fa conf.title
+title at the top dialog side.
+.It Fa conf.y
+vertical position, 0 is top screen size, can be
+.Dv BSDDIALOG_CENTER .
+.It Fa conf.x
+horizontal position, 0 is left screen side, can be
+.Dv BSDDIALOG_CENTER .
+.El
+.Pp
+.Fa conf.key.enable_esc
+enables
+.Dv ESC
+key to close the dialog.
+.Pp
+.Fa conf.text.highlight
+enables highlights for
+.Fa text ,
+properly the following sequences are considered escapes:
+.Bl -column -compact
+.It Dq \eZ0
+black.
+.It Dq \eZ1
+red.
+.It Dq \eZ2
+green.
+.It Dq \eZ3
+yellow.
+.It Dq \eZ4
+blue.
+.It Dq \eZ5
+magenta.
+.It Dq \eZ6
+cyan.
+.It Dq \eZ7
+white.
+.It Dq \eZr
+reverse colors between foreground and background.
+.It Dq \eZR
+disable reverse.
+.It Dq \eZb
+bold.
+.It Dq \eZB
+disable bold.
+.It Dq \eZu
+underline.
+.It Dq \eZU
+disable underline.
+.It Dq \eZn
+disable each customization.
+.El
+.Fa conf.text.tablen
+tab length.
+.Pp
+.Bl -column -compact
+.It Fa conf.button.without_ok
+disable OK button.
+.It Fa conf.button.ok_label
+set label for OK button.
+.It Fa conf.button.with_extra
+add Extra button.
+.It Fa conf.button.extra_label
+set a label for Extra button.
+.It Fa conf.button.without_cancel
+disable Cancel button.
+.It Fa conf.button.cancel_label
+sets a label for Cancel button.
+.It Fa conf.button.default_cancel
+on startup focus on the Cancel button.
+.It Fa conf.button.with_help
+add Help button.
+.It Fa conf.button.help_label
+set a label for Help button.
+.It Fa conf.button.generic1_label
+add a button with the specified label.
+.It Fa conf.button.generic2_label
+add a button with the specified label.
+.It Fa conf.button.default_label
+focus on the button with the specified label.
+.El
+.Pp
+.Fn bsddialog_initconf
+initializes
+.Fa conf
+disabling each property, except
+.Fa conf.shadow
+to true,
+.Fa conf.y
+and
+.Fa conf.x
+to
+.Dv BSDDIALOG_CENTER .
+.Pp
+.Fn bsddialog_infobox
+builds a dialog without buttons and returns instantly.
+.Fn bsddialog_msgbox
+builds a dialog with OK button.
+.Fn bsddialog_yesno
+provides a dialog for a
+.Dq Yes-No Question ,
+the labels on buttons are Yes and No.
+.Pp
+.Fn bsddialog_pause
+builds a dialog waiting until the timeout in
+.Fa seconds
+expires or a button is pressed.
+.Pp
+.Fn bsddialog_datebox
+builds a dialog to select a date,
+.Fa yy ,
+.Fa mm ,
+and
+.Fa dd
+are default values on startup, selected date at exit.
+.Fn bsddialog_timebox
+builds a dialog to choose a time,
+.Fa hh ,
+.Fa mm ,
+and
+.Fa ss
+are default values on startup, selected time at exit.
+.Pp
+.Fn bsddialog_checklist ,
+.Fn bsddialog_menu
+and
+.Fn bsddialog_radiolist
+build dialogs to select some item from a list via the SPACE key, an item is
+defined like:
.Pp
.Bd -literal -offset indent -compact
struct bsddialog_menuitem {
- char *prefix;
+ const char *prefix;
bool on;
unsigned int depth;
- char *name;
- char *desc;
- char *bottomdesc;
+ const char *name;
+ const char *desc;
+ const char *bottomdesc;
};
-
+.Ed
+.Pp
+.Fa prefix ,
+.Fa name
+and
+.Fa desc
+are strings to describe the item and are printed on its row,
+.Fa bottomdesc
+is printed on the bottom side of the screen,
+.Fa depth
+is a margin between the
+.Fa prefix
+and
+.Fa name
+useful to implement a
+.Dq treeview,
+.Fa on
+is set to
+.Dv true
+if the item is selected,
+.Dv false
+otherwise.
+.Fa items
+is an array of items of
+.Fa nitem
+elements,
+.Fa menurows
+specifies the graphical fixed height of the list, if
+.Fa cols
+is set to
+.Dv BSDDIALOG_AUTOSIZE
+.Fa menurows
+specifies a maximum value.
+Finally, if not
+.Dv NULL ,
+.Fa focusitem
+specifies the default item on startup and the last focused item at exit, could
+be a negative value if no item is focused.
+.Pp
+.Fn bsddialog_mixedlist
+builds a dialog with collections of checklists, radiolists and separators.
+A collection is a set defined like:
+.Pp
+.Bd -literal -offset indent -compact
enum bsddialog_grouptype {
BSDDIALOG_CHECKLIST,
BSDDIALOG_RADIOLIST,
@@ -357,35 +558,185 @@ struct bsddialog_menugroup {
unsigned int nitems;
struct bsddialog_menuitem *items;
};
-
+.Ed
+.Pp
+.Fa groups
+is an array of sets of
+.Fa ngroups
+elements.
+.Fa menurows
+is the graphical height size for the list.
+If not
+.Dv NULL ,
+.Fa focuslist
+and
+.Fa focusitem
+specify the default item on startup and the last focused item at exit, could be
+a negative value if no item is focused.
+.Pp
+.Fn bsddialog_checklist ,
+.Fn bsddialog_menu ,
+.Fn bsddialog_mixedlist
+and
+.Fn bsddialog_radiolist
+can be costomizated by:
+.Bl -column -compact
+.It Fa conf.menu.align_left
+aligns items to left, default center.
+.It Fa conf.menu.no_desc
+hide description.
+.It Fa conf.menu.no_name
+hide names.
+.It Fa conf.menu.on_without_ok
+set items
+.Fa on
+also if the OK button is not pressed.
+.It Fa conf.menu.shortcut_buttons
+enable shortcut keys on buttons, default on items.
+.El
+.Pp
+.Fn bsddialog_form
+builds a dialog to display a list of items to get strings in input, an item is
+defined like:
+.Pp
+.Bd -literal -offset indent -compact
struct bsddialog_formitem {
- char *label;
+ const char *label;
unsigned int ylabel;
unsigned int xlabel;
- char *init;
+ const char *init;
unsigned int yfield;
unsigned int xfield;
unsigned int fieldlen;
unsigned int maxvaluelen;
- char *value; /* allocated memory */
-#define BSDDIALOG_FIELDHIDDEN 1U
-#define BSDDIALOG_FIELDREADONLY 2U
+ char *value;
+
unsigned int flags;
- char *bottomdesc;
+ const char *bottomdesc;
};
.Ed
.Pp
-
+.Fa label
+describes the request, it is printed at the position
+.Fa ylabel
+and
+.Fa xlabel .
+The field for the input is at the position
+.Fa yfield
+and
+.Fa xfield ,
+.Fa fieldlen
+is its graphical width, while
+.Fa maxvalelen
+is the maximum length of the input string,
+.Fa init
+is the default value.
+If the OK button is pressed
+.Fa value
+is the allocated memory with the current field string.
+.Fa flags
+is an OR value to set the
+.Dv BSDDIALOG_FIELDHIDDEN
+and
+.Dv BSDDIALOG_FIELDREADONLY
+flags for the field.
+.Fa bottomdesc
+is printed on the bottom side of the screen if the item is focused.
+.Fa items
+is an array of items of
+.Fa nitems
+elements,
+.Fa formrows
+specifies the graphical fixed height for the items list;
+.Fa ylabel
+and
+.Fa yfield
+have to be between 1 and
+.Fa formrows .
+.Pp
+.Fn bsddialog_form
+can be customized by:
+.Bl -column -compact
+.It Fa conf.form.securech
+charachter to hide the input
+with
+.Dv BSDDIALOG_FIELDHIDDEN .
+.It Fa conf.form.value_without_ok
+allocate memory and set
+.Fa value
+also if the OK button is not pressed.
+.El
+.Pp
+.Fn bsddialog_gauge
+builds a dialog with a bar to shows
+.Fa perc ,
+if the file descriptor
+.Fa fd
+is greater or equal to 0 the dialog waits to read
+.Fa separator
+from it, then the first string replaces
+.Fa perc
+and the following strings replace
+.Fa text
+until the next
+.Fa separator ,
+the loop ends reading
+.Dv EOF .
+.Pp
+.Fn bsddialog_mixedgauge
+draws a main bar with the
+.Fa mainperc
+percentage and
+.Fa nminibars
+each one with a
+.Fa minilabel
+and a
+.Fa miniperc
+with a value between 0 and 100 or
+.Dv BSDDIALOG_MG_SUCCEEDED ,
+.Dv BSDDIALOG_MG_FAILED ,
+.Dv BSDDIALOG_MG_PASSED ,
+.Dv BSDDIALOG_MG_COMPLETED ,
+.Dv BSDDIALOG_MG_CHECKED ,
+.Dv BSDDIALOG_MG_DONE ,
+.Dv BSDDIALOG_MG_SKIPPED ,
+.Dv BSDDIALOG_MG_INPROGRESS ,
+.Dv BSDDIALOG_MG_BLANK ,
+.Dv BSDDIALOG_MG_NA
+or
+.Dv BSDDIALOG_MG_PENDING
+to print a descriptive string.
+.Pp
+.Fn bsddialog_rangebox
+to select a value between
+.Fa min
+and
+.Fa max .
+.Fa value
+is the default value on startup and the selected value at exit.
+The current value is printed inside a bar, the keys UP, DOWN, HOME, END, PAGEUP
+and PAGEDOWN can change it.
+.Pp
+.Fn bsddialog_textbox
+opens and prints
+.Fa file
+in a dialog, the UP, DOWN, HOME, END, PAGEUP and PAGEDOWN keys are availble to
+navigate the file.
+OK button is renamed EXIT.
.Ss Theme
+The graphical properties are global to the library, they are represented by
+.Fa struct bsddialog_theme
+and can be customized at runtime via the
+.In bsddialog_theme.h
+API.
.Pp
.Bd -literal -offset indent -compact
-/* f_ focus/active element */
struct bsddialog_theme {
struct {
int color;
- } terminal;
+ } screen;
struct {
int color;
unsigned int h;
@@ -400,9 +751,6 @@ struct bsddialog_theme {
int bottomtitlecolor;
} dialog;
struct {
- unsigned int hmargin;
- } text;
- struct {
int arrowcolor;
int selectorcolor;
int f_namecolor;
@@ -435,84 +783,191 @@ struct bsddialog_theme {
int f_shortcutcolor;
} button;
};
-
-enum bsddialog_default_theme {
- BSDDIALOG_THEME_BLACKWHITE,
- BSDDIALOG_THEME_BSDDIALOG,
- BSDDIALOG_THEME_DEFAULT,
- BSDDIALOG_THEME_DIALOG,
-};
-
-enum bsddialog_color {
- BSDDIALOG_BLACK = 0,
- BSDDIALOG_RED,
- BSDDIALOG_GREEN,
- BSDDIALOG_YELLOW,
- BSDDIALOG_BLUE,
- BSDDIALOG_MAGENTA,
- BSDDIALOG_CYAN,
- BSDDIALOG_WHITE,
-};
-
-#define BSDDIALOG_BOLD 1U
-#define BSDDIALOG_REVERSE 2U
-#define BSDDIALOG_UNDERLINE 4U
.Ed
.Pp
-
+A member with the
+.Dq f_
+prefix refers to an element with focus.
+.Pp
+.Fn bsddialog_get_theme
+sets
+.Fa theme
+like the current theme.
+.Pp
+A color can be set by the value returned by
+.Fn bsddialog_color ,
+Possible values for
+.Fa background
+and
+.Fa foreground
+are:
+.Dv BSDDIALOG_BLACK ,
+.Dv BSDDIALOG_RED ,
+.Dv BSDDIALOG_GREEN ,
+.Dv BSDDIALOG_YELLOW ,
+.Dv BSDDIALOG_BLUE ,
+.Dv BSDDIALOG_MAGENTA ,
+.Dv BSDDIALOG_CYAN ,
+and
+.Dv BSDDIALOG_WHITE ,
+.Fa flags
+specifies OR-flags, possible values:
+.Dv BSDDIALOG_BOLD ,
+.Dv BSDDIALOG_REVERSE
+and
+.Dv BSDDIALOG_UNDERLINE .
+.Pp
+.Fn bsddialog_set_theme
+sets
+.Fa theme
+like current theme, the changes takes effect only for dialogs built after the
+call.
+.Pp
+The library provides predefined themes:
+.Dv BSDDIALOG_THEME_BLACKWHITE ,
+.Dv BSDDIALOG_THEME_BSDDIALOG ,
+.Dv BSDDIALOG_THEME_DEFAULT
+and
+.Dv BSDDIALOG_THEME_DIALOG ,
+they can be set via
+.Fn bsddialog_set_default_theme .
.Sh RETURN VALUES
-The sysctlmif_oidbyname(), sysctlmif_oidextendedbyname(),
- sysctlmif_name(), sysctlmif_desc(), sysctlmif_descbyname(),
- sysctlmif_label(), sysctlmif_labelbyname(), sysctlmif_fmt(),
- sysctlmif_fmtbyname(), sysctlmif_oidbyname0(), sysctlmif_oidbyname1(),
- sysctlmif_oidbyname2(), sysctlmif_oidbyname3(), sysctlmif_oidbyname4(),
- sysctlmif_oidbyname5(), sysctlmif_oidbyname6(), and
- sysctlmif_oidbyname7() functions return the value 0 if successful; other-
- wise the value -1 is returned and the global variable errno is set to in-
- dicate the error.
-
-
-functions return NULL upon error or a pointer to allo-
- cated memory for success.
-
-.Sh EXAMPLES
-Complete set of examples:
-.Lk https://gitlab.com/alfix/bsddialog/-/blob/main/examples_library/
+The functions return the value
+.Dv BSDDIALOG_ERROR
+if unsuccessful;
+otherwise, depending on the pressed button, the following values can be
+returned:
+.Dv BSDDIALOG_OK ,
+.Dv BSDDIALOG_CANCEL ,
+.Dv BSDDIALOG_HELP ,
+.Dv BSDDIALOG_EXTRA ,
+.Dv BSDDIALOG_GENERIC1
+or
+.Dv BSDDIALOG_GENERIC2 .
+.Dv BSDDIALOG_YES
+and
+.Dv BSDDIALOG_NO
+are aliases for
+.Dv BSDDIALOG_OK
+and
+.Dv BSDDIALOG_CANCEL ,
+respectively.
.Pp
-If installed:
-.Dl /usr/local/share/examples/libbsddialog
+The functions return
+.Dv BSDDIALOG_ESC
+if
+.Fa conf.key.enable_esc
+is enabled and the ESC key is pressed.
.Pp
-"Yes-No Question" Example:
+.Fn bsddialog_pause
+returns
+.Dv BSDDIALOG_TIMEOUT
+if the timeout expires.
+.Sh EXAMPLES
+.Dq Yes-No Question
+Example:
.Pp
.Bd -literal -offset indent -compact
int output;
struct bsddialog_conf conf;
-bsddialog_initconf(&conf);
-conf.title = "yesno";
if (bsddialog_init() == BSDDIALOG_ERROR)
return (1);
+bsddialog_initconf(&conf);
+conf.title = "yesno";
output = bsddialog_yesno(&conf, "Example", 7, 25);
bsddialog_end();
switch (output) {
case BSDDIALOG_YES:
- printf("OK\\n");
+ printf("Yes\\n");
break;
case BSDDIALOG_NO
printf("NO\\n");
break;
-case BSDDIALOG_ESC;
- printf("ESC\\n");
- break;
case BSDDIALOG_ERROR:
printf("Error: %s\\n", bsddialog_geterror());
}
.Ed
+.Pp
+Theme Example:
+.Pp
+.Bd -literal -offset indent -compact
+struct bsddialog_conf conf;
+struct bsddialog_theme theme;
+
+if (bsddialog_init() == BSDDIALOG_ERROR)
+
+bsddialog_initconf(&conf);
+bsddialog_msgbox(&conf, "Default theme", 7, 25);
+
+bsddialog_get_theme(&theme);
+theme.screen.color = bsddialog_color(BSDDIALOG_RED, BSDDIALOG_GREEN,
+ BSDDIALOG_BOLD);
+bsddialog_set_theme(&theme);
+bsddialog_backtitle(&conf, "Red foreground and Green background");
+bsddialog_msgbox(&conf, "Change screen color", 7, 25);
+
+bsddialog_set_default_theme(BSDDIALOG_THEME_BLACKWHITE);
+bsddialog_msgbox(&conf, "Black and White theme", 7, 25);
+
+bsddialog_end();
+.Ed
+.Pp
+Mixedlist Example:
+.Pp
+.Bd -literal -offset indent -compact
+unsigned int i, j;
+struct bsddialog_conf conf;
+struct bsddialog_menuitem item;
+struct bsddialog_menuitem check[2] = {
+ { "1", true, 0, "Name 1", "Desc 1", "Check Bottom Desc 1" },
+ { "2", false, 0, "Name 2", "Desc 2", "Check Bottom Desc 2" }
+};
+struct bsddialog_menuitem sep[1] = {
+ { "3", true, 0, "Radiolist", "(desc)", "" }
+};
+struct bsddialog_menuitem radio[5] = {
+ { "4", true, 0, "Name 1", "Desc 1", "Radio Bottom Desc 1" },
+ { "5", false, 0, "Name 2", "Desc 2", "Radio Bottom Desc 2" }
+};
+struct bsddialog_menugroup group[3] = {
+ { BSDDIALOG_CHECKLIST, 2, check },
+ { BSDDIALOG_SEPARATOR, 1, sep },
+ { BSDDIALOG_RADIOLIST, 2, radio }
+};
+
+bsddialog_init();
+bsddialog_initconf(&conf);
+bsddialog_mixedlist(&conf, "Example", 20, 30, 11, 3, group, NULL,
+ NULL);
+bsddialog_end();
+
+for (i = 0; i < 3; i++) {
+ for (j = 0; j < group[i].nitems; j++) {
+ item = group[i].items[j];
+ switch (item.type) {
+ case BSDDIALOG_SEPARATOR:
+ printf("---- %s ----\\n", item.name);
+ break;
+ case BSDDIALOG_RADIOLIST:
+ printf(" (%c) %s\\n",
+ item.on ? '*' : ' ', item.name);
+ break;
+ case BSDDIALOG_CHECKLIST:
+ printf(" [%c] %s\\n",
+ item.on ? 'X' : ' ', item.name);
+ break;
+ }
+ }
+}
+.Ed
.Sh SEE ALSO
-.Xr bsddialog 1
+.Xr bsddialog 1 ,
+.Xr curses 3 ,
+.Xr ncurses 3
.Sh HISTORY
The
.Nm bsddialog
@@ -522,9 +977,7 @@ library first appeared in
.Nm bsddialog
was written by
.An Alfonso Sabato Siciliano Aq Mt alf.siciliano@gmail.com .
-.Sh CAVEATS
-See
-.Xr bsddialog
.Sh BUGS
-See
-.Xr bsddialog 1
+.Fn bsddialog_form
+does not resize the dialog after a terminal resize and does not provide
+scrolling for items. \ No newline at end of file
diff --git a/lib/bsddialog.h b/lib/bsddialog.h
index 94342199439e..142713cc1ecf 100644
--- a/lib/bsddialog.h
+++ b/lib/bsddialog.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,83 +30,100 @@
#include <stdbool.h>
-#define LIBBSDDIALOG_VERSION "0.0.2"
+#define LIBBSDDIALOG_VERSION "0.1"
/* Exit status */
-#define BSDDIALOG_ERROR -1
-#define BSDDIALOG_OK 0
-#define BSDDIALOG_YES BSDDIALOG_OK
-#define BSDDIALOG_CANCEL 1
-#define BSDDIALOG_NO BSDDIALOG_CANCEL
-#define BSDDIALOG_HELP 2
-#define BSDDIALOG_EXTRA 3
-#define BSDDIALOG_TIMEOUT 4
-#define BSDDIALOG_ESC 5
-#define BSDDIALOG_GENERIC1 6
-#define BSDDIALOG_GENERIC2 7
+#define BSDDIALOG_ERROR -1
+#define BSDDIALOG_OK 0
+#define BSDDIALOG_YES BSDDIALOG_OK
+#define BSDDIALOG_CANCEL 1
+#define BSDDIALOG_NO BSDDIALOG_CANCEL
+#define BSDDIALOG_HELP 2
+#define BSDDIALOG_EXTRA 3
+#define BSDDIALOG_TIMEOUT 4
+#define BSDDIALOG_ESC 5
+#define BSDDIALOG_GENERIC1 6
+#define BSDDIALOG_GENERIC2 7
/* Size and position */
-#define BSDDIALOG_FULLSCREEN -1
-#define BSDDIALOG_AUTOSIZE 0
-#define BSDDIALOG_CENTER -1
+#define BSDDIALOG_FULLSCREEN -1
+#define BSDDIALOG_AUTOSIZE 0
+#define BSDDIALOG_CENTER -1
+
+/* Mixedgauge */
+#define BSDDIALOG_MG_SUCCEEDED -1
+#define BSDDIALOG_MG_FAILED -2
+#define BSDDIALOG_MG_PASSED -3
+#define BSDDIALOG_MG_COMPLETED -4
+#define BSDDIALOG_MG_CHECKED -5
+#define BSDDIALOG_MG_DONE -6
+#define BSDDIALOG_MG_SKIPPED -7
+#define BSDDIALOG_MG_INPROGRESS -8
+#define BSDDIALOG_MG_BLANK -9
+#define BSDDIALOG_MG_NA -10
+#define BSDDIALOG_MG_PENDING -11
+
+/* Form */
+#define BSDDIALOG_FIELDHIDDEN 1U
+#define BSDDIALOG_FIELDREADONLY 2U
struct bsddialog_conf {
bool ascii_lines;
- unsigned int aspect_ratio;
unsigned int auto_minheight;
unsigned int auto_minwidth;
- char *bottomtitle;
+ const char *bottomtitle;
bool clear;
- char *f1_file;
- char *f1_message;
- int *get_height;
- int *get_width;
+ const char *f1_file;
+ const char *f1_message;
+ int *get_height;
+ int *get_width;
bool no_lines;
bool shadow;
unsigned int sleep;
- char *title;
- int y;
- int x;
+ const char *title;
+ int y;
+ int x;
struct {
- bool colors;
+ bool enable_esc;
+ } key;
+ struct {
+ bool highlight;
+ unsigned int tablen;
} text;
struct {
bool align_left;
- char *default_item;
bool no_desc;
bool no_name;
+ bool on_without_ok;
bool shortcut_buttons;
} menu;
struct {
int securech;
- bool value_withcancel;
- bool value_withextra;
- bool value_withhelp;
+ bool value_without_ok;
} form;
struct {
bool without_ok;
- char *ok_label;
+ const char *ok_label;
bool with_extra;
- char *extra_label;
+ const char *extra_label;
bool without_cancel;
- char *cancel_label;
+ const char *cancel_label;
bool default_cancel;
bool with_help;
- char *help_label;
- char *exit_label;
- char *generic1_label;
- char *generic2_label;
- char *default_label;
+ const char *help_label;
+ const char *generic1_label;
+ const char *generic2_label;
+ const char *default_label;
} button;
};
struct bsddialog_menuitem {
- char *prefix;
+ const char *prefix;
bool on;
unsigned int depth;
- char *name;
- char *desc;
- char *bottomdesc;
+ const char *name;
+ const char *desc;
+ const char *bottomdesc;
};
enum bsddialog_grouptype {
@@ -122,96 +139,93 @@ struct bsddialog_menugroup {
};
struct bsddialog_formitem {
- char *label;
+ const char *label;
unsigned int ylabel;
unsigned int xlabel;
- char *init;
+ const char *init;
unsigned int yfield;
unsigned int xfield;
unsigned int fieldlen;
unsigned int maxvaluelen;
char *value;
-#define BSDDIALOG_FIELDHIDDEN 1U
-#define BSDDIALOG_FIELDREADONLY 2U
unsigned int flags;
- char *bottomdesc;
+ const char *bottomdesc;
};
int bsddialog_init(void);
int bsddialog_end(void);
-int bsddialog_backtitle(struct bsddialog_conf *conf, char *backtitle);
+int bsddialog_backtitle(struct bsddialog_conf *conf, const char *backtitle);
int bsddialog_initconf(struct bsddialog_conf *conf);
int bsddialog_clearterminal(void);
const char *bsddialog_geterror(void);
/* Dialogs */
int
-bsddialog_buildlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
- int *focusitem);
-
-int
-bsddialog_checklist(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
- int *focusitem);
+bsddialog_checklist(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int menurows, unsigned int nitems,
+ struct bsddialog_menuitem *items, int *focusitem);
int
-bsddialog_datebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int *yy, unsigned int *mm, unsigned int *dd);
+bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int *yy, unsigned int *mm, unsigned int *dd);
int
-bsddialog_form(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int formheight, unsigned int nitems,
+bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int formheight, unsigned int nitems,
struct bsddialog_formitem *items);
int
-bsddialog_gauge(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int perc);
+bsddialog_gauge(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int perc, int fd, const char *sep);
int
-bsddialog_infobox(struct bsddialog_conf *conf, char* text, int rows, int cols);
+bsddialog_infobox(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols);
int
-bsddialog_menu(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
- int *focusitem);
+bsddialog_menu(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int menurows, unsigned int nitems,
+ struct bsddialog_menuitem *items, int *focusitem);
int
-bsddialog_mixedgauge(struct bsddialog_conf *conf, char* text, int rows,
- int cols, unsigned int mainperc, unsigned int nminibars, char **minilabels,
- int *minipercs);
+bsddialog_mixedgauge(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int mainperc, unsigned int nminibars,
+ const char **minilabels, int *minipercs);
int
-bsddialog_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int ngroups, struct bsddialog_menugroup *groups,
- int *focuslist, int *focusitem);
+bsddialog_mixedlist(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int menurows, unsigned int ngroups,
+ struct bsddialog_menugroup *groups, int *focuslist, int *focusitem);
int
-bsddialog_msgbox(struct bsddialog_conf *conf, char* text, int rows, int cols);
+bsddialog_msgbox(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols);
int
-bsddialog_pause(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int sec);
+bsddialog_pause(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int seconds);
int
-bsddialog_radiolist(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
- int *focusitem);
+bsddialog_radiolist(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int menurows, unsigned int nitems,
+ struct bsddialog_menuitem *items, int *focusitem);
int
-bsddialog_rangebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
- int min, int max, int *value);
+bsddialog_rangebox(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, int min, int max, int *value);
int
-bsddialog_textbox(struct bsddialog_conf *conf, char* file, int rows, int cols);
+bsddialog_textbox(struct bsddialog_conf *conf, const char *file, int rows,
+ int cols);
int
-bsddialog_timebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int *hh, unsigned int *mm, unsigned int *ss);
+bsddialog_timebox(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int *hh, unsigned int *mm, unsigned int *ss);
int
-bsddialog_yesno(struct bsddialog_conf *conf, char* text, int rows, int cols);
+bsddialog_yesno(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols);
#endif
diff --git a/lib/bsddialog_progressview.h b/lib/bsddialog_progressview.h
index 453d46a242e6..0cd9368a1040 100644
--- a/lib/bsddialog_progressview.h
+++ b/lib/bsddialog_progressview.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,27 +28,33 @@
#ifndef _LIBBSDDIALOG_PROGRESSVIEW_H_
#define _LIBBSDDIALOG_PROGRESSVIEW_H_
+/*
+ * Undocumented API, DO NOT USE!
+ * Please consider this file private: it is used by bsdinstall/distextract,
+ * could be deleted or changed in the future.
+ */
+
extern bool bsddialog_interruptprogview;
extern bool bsddialog_abortprogview;
extern int bsddialog_total_progview;
struct bsddialog_fileminibar {
- char *path;
- char *label;
- int status; /* mixedgauge: 1 failed - 5 done - 7 in progress*/
+ const char *path;
+ const char *label;
+ int status; /* next if BSDDIALOG_MG_DONE or BSDDIALOG_MG_FAILED */
long long size;
long long read;
};
struct bsddialog_progviewconf {
- char *fmtbottomstr;
+ const char *fmtbottomstr;
unsigned int refresh; /* in seconds */
int (*callback)(struct bsddialog_fileminibar *minibar);
};
int
-bsddialog_progressview (struct bsddialog_conf *conf, char * text, int rows,
+bsddialog_progressview (struct bsddialog_conf *conf, const char *text, int rows,
int cols, struct bsddialog_progviewconf *pvconf, unsigned int nminibar,
struct bsddialog_fileminibar *minibar);
-#endif
+#endif \ No newline at end of file
diff --git a/lib/bsddialog_theme.h b/lib/bsddialog_theme.h
index 853eb5f9d864..65ba5f5e94e8 100644
--- a/lib/bsddialog_theme.h
+++ b/lib/bsddialog_theme.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,11 +28,15 @@
#ifndef _LIBBSDDIALOG_THEME_H_
#define _LIBBSDDIALOG_THEME_H_
-/* f_ focus/active element */
+/* color flags */
+#define BSDDIALOG_BOLD 1U
+#define BSDDIALOG_REVERSE 2U
+#define BSDDIALOG_UNDERLINE 4U
+
struct bsddialog_theme {
struct {
int color;
- } terminal;
+ } screen;
struct {
int color;
unsigned int h;
@@ -47,9 +51,6 @@ struct bsddialog_theme {
int bottomtitlecolor;
} dialog;
struct {
- unsigned int hmargin;
- } text;
- struct {
int arrowcolor;
int selectorcolor;
int f_namecolor;
@@ -87,7 +88,7 @@ enum bsddialog_default_theme {
BSDDIALOG_THEME_BLACKWHITE,
BSDDIALOG_THEME_BSDDIALOG,
BSDDIALOG_THEME_DEFAULT,
- BSDDIALOG_THEME_DIALOG,
+ BSDDIALOG_THEME_DIALOG
};
enum bsddialog_color {
@@ -98,13 +99,9 @@ enum bsddialog_color {
BSDDIALOG_BLUE,
BSDDIALOG_MAGENTA,
BSDDIALOG_CYAN,
- BSDDIALOG_WHITE,
+ BSDDIALOG_WHITE
};
-#define BSDDIALOG_BOLD 1U
-#define BSDDIALOG_REVERSE 2U
-#define BSDDIALOG_UNDERLINE 4U
-
int
bsddialog_color(enum bsddialog_color foreground,
enum bsddialog_color background, unsigned int flags);
@@ -112,4 +109,4 @@ int bsddialog_get_theme(struct bsddialog_theme *theme);
int bsddialog_set_default_theme(enum bsddialog_default_theme theme);
int bsddialog_set_theme(struct bsddialog_theme *theme);
-#endif
+#endif \ No newline at end of file
diff --git a/lib/formbox.c b/lib/formbox.c
index 3a5d8a49e359..ade1660c2645 100644
--- a/lib/formbox.c
+++ b/lib/formbox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,35 +28,29 @@
#include <sys/param.h>
#include <ctype.h>
-#ifdef PORTNCURSES
-#include <ncurses/form.h>
-#else
#include <form.h>
-#endif
#include <stdlib.h>
#include <string.h>
#include "bsddialog.h"
-#include "lib_util.h"
#include "bsddialog_theme.h"
+#include "lib_util.h"
-#define REDRAWFORM 14021986 /* magic number */
+#define REDRAWFORM 19860214 /* magic number */
#define ISFIELDHIDDEN(item) (item.flags & BSDDIALOG_FIELDHIDDEN)
#define ISFIELDREADONLY(item) (item.flags & BSDDIALOG_FIELDREADONLY)
-/* "Form": inputbox - passwordbox - form - passwordform - mixedform */
-
extern struct bsddialog_theme t;
-/* util struct for private buffer and view options */
+/* field_userptr for private buffer and view options */
struct myfield {
- int buflen;
+ int buflen;
char *buf;
- int pos;
- int maxpos;
+ int pos;
+ int maxpos;
bool secure;
- int securech;
- char *bottomdesc;
+ int securech;
+ const char *bottomdesc;
};
#define GETMYFIELD(field) ((struct myfield*)field_userptr(field))
#define GETMYFIELD2(form) ((struct myfield*)field_userptr(current_field(form)))
@@ -95,8 +89,7 @@ static void shiftleft(struct myfield *mf)
static void print_bottomdesc(struct myfield *mf)
{
-
- move(LINES-1, 2);
+ move(SCREENLINES - 1, 2);
clrtoeol();
if (mf->bottomdesc != NULL) {
addstr(mf->bottomdesc);
@@ -105,26 +98,18 @@ static void print_bottomdesc(struct myfield *mf)
}
int
-return_values(struct bsddialog_conf *conf, struct buttons bs, int nitems,
+return_values(struct bsddialog_conf *conf, int output, int nitems,
struct bsddialog_formitem *items, FORM *form, FIELD **cfield)
{
- int i, output;
+ int i;
struct myfield *mf;
- output = bs.value[bs.curr];
- if (output == BSDDIALOG_HELP && conf->form.value_withhelp == false)
- return output;
- if (output == BSDDIALOG_EXTRA && conf->form.value_withextra == false)
- return output;
- if (output == BSDDIALOG_CANCEL && conf->form.value_withcancel == false)
- return output;
- if (output == BSDDIALOG_GENERIC1 || output == BSDDIALOG_GENERIC2)
- return output;
-
- /* BSDDIALOG_OK */
+ if (output != BSDDIALOG_OK && conf->form.value_without_ok == false)
+ return (output);
+
form_driver(form, REQ_NEXT_FIELD);
form_driver(form, REQ_PREV_FIELD);
- for (i=0; i<nitems; i++) {
+ for (i = 0; i < nitems; i++) {
mf = GETMYFIELD(cfield[i]);
items[i].value = strdup(mf->buf);
if (items[i].value == NULL)
@@ -135,11 +120,11 @@ return_values(struct bsddialog_conf *conf, struct buttons bs, int nitems,
}
static int
-form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols,
- struct buttons bs, WINDOW *formwin, FORM *form, FIELD **cfield, int nitems,
+form_handler(struct bsddialog_conf *conf, WINDOW *widget, struct buttons bs,
+ WINDOW *formwin, FORM *form, FIELD **cfield, int nitems,
struct bsddialog_formitem *items)
{
- bool loop, buttupdate, informwin = true;
+ bool loop, buttupdate, informwin;
int i, input, output;
struct myfield *mf;
@@ -149,11 +134,15 @@ form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols,
form_driver(form, REQ_END_LINE);
mf->pos = MIN(mf->buflen, mf->maxpos);
curs_set(2);
+ informwin = true;
+
bs.curr = -1;
- loop = buttupdate = true;
- while(loop) {
+ buttupdate = true;
+
+ loop = true;
+ while (loop) {
if (buttupdate) {
- draw_buttons(widget, y, cols, bs, !informwin);
+ draw_buttons(widget, bs, !informwin);
wrefresh(widget);
buttupdate = false;
}
@@ -164,12 +153,16 @@ form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols,
case 10: /* Enter */
if (informwin)
break;
+ output = return_values(conf, bs.value[bs.curr], nitems,
+ items, form, cfield);
loop = false;
- output = return_values(conf, bs, nitems, items, form, cfield);
break;
case 27: /* Esc */
- output = BSDDIALOG_ESC;
- loop = false;
+ if (conf->key.enable_esc) {
+ output = return_values(conf, BSDDIALOG_ESC,
+ nitems, items, form, cfield);
+ loop = false;
+ }
break;
case '\t': /* TAB */
if (informwin) {
@@ -178,7 +171,7 @@ form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols,
curs_set(0);
} else {
bs.curr++;
- informwin = bs.curr >= (int) bs.nbuttons ?
+ informwin = bs.curr >= (int)bs.nbuttons ?
true : false;
if (informwin) {
curs_set(2);
@@ -248,7 +241,7 @@ form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols,
form_driver(form, REQ_DEL_PREV);
form_driver(form, REQ_BEG_LINE);
mf->pos = mf->pos - 1;
- for (i=0; i<mf->pos; i++)
+ for (i = 0; i < mf->pos; i++)
form_driver(form, REQ_NEXT_CHAR);
shiftleft(mf);
break;
@@ -262,16 +255,13 @@ form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols,
if (conf->f1_file == NULL && conf->f1_message == NULL)
break;
if (f1help(conf) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
/* No Break */
case KEY_RESIZE:
output = REDRAWFORM;
loop = false;
break;
default:
- /*
- * user input, add unicode chars to "public" buffer
- */
if (informwin) {
mf = GETMYFIELD2(form);
if (mf->secure)
@@ -281,14 +271,11 @@ form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols,
insertch(mf, input);
}
else {
- for (i = 0; i < (int) bs.nbuttons; i++) {
- if (tolower(input) ==
- tolower((bs.label[i])[0])) {
- bs.curr = i;
- output = return_values(conf, bs,
- nitems, items, form, cfield);
- loop = false;
- }
+ if (shortcut_buttons(input, &bs)) {
+ output = return_values(conf,
+ bs.value[bs.curr], nitems, items,
+ form, cfield);
+ loop = false;
}
}
break;
@@ -297,62 +284,47 @@ form_handler(struct bsddialog_conf *conf, WINDOW *widget, int y, int cols,
curs_set(0);
- return output;
+ return (output);
}
-static void
+static int
form_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
- char *text, int linelen, unsigned int *formheight, int nitems,
+ const char *text, int linelen, unsigned int *formheight, int nitems,
struct buttons bs)
{
- int textrow, menusize;
+ int htext, wtext, menusize;
- textrow = text != NULL && strlen(text) > 0 ? 1 : 0;
-
- if (cols == BSDDIALOG_AUTOSIZE) {
- *w = VBORDERS;
- /* buttons size */
- *w += bs.nbuttons * bs.sizebutton;
- *w += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0;
- /* line size */
- *w = MAX(*w, linelen + 3);
- /* conf.auto_minwidth */
- *w = MAX(*w, (int)conf->auto_minwidth);
- /*
- * avoid terminal overflow,
- * -1 fix false negative with big menu over the terminal and
- * autosize, for example "portconfig /usr/ports/www/apache24/".
- */
- *w = MIN(*w, widget_max_width(conf)-1);
+ if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
+ if (text_size(conf, rows, cols, text, &bs, *formheight + 2,
+ linelen + 2, &htext, &wtext) != 0)
+ return (BSDDIALOG_ERROR);
}
- if (rows == BSDDIALOG_AUTOSIZE) {
- *h = HBORDERS + 2 /* buttons */ + textrow;
+ if (cols == BSDDIALOG_AUTOSIZE)
+ *w = widget_min_width(conf, wtext, linelen + 2, &bs);
+ if (rows == BSDDIALOG_AUTOSIZE) {
if (*formheight == 0) {
- *h += nitems + 2;
- *h = MIN(*h, widget_max_height(conf));
- menusize = MIN(nitems + 2, *h - (HBORDERS + 2 + textrow));
- menusize -=2;
- *formheight = menusize < 0 ? 0 : menusize;
+ menusize = widget_max_height(conf) - HBORDERS -
+ 2 /*buttons*/ - htext;
+ menusize = MIN(menusize, nitems + 2);
+ *formheight = menusize - 2 < 0 ? 0 : menusize - 2;
}
- else /* h autosize with a fixed formheight */
- *h = *h + *formheight + 2;
+ else /* h autosize with fixed formheight */
+ menusize = *formheight + 2;
- /* conf.auto_minheight */
- *h = MAX(*h, (int)conf->auto_minheight);
- /* avoid terminal overflow */
- *h = MIN(*h, widget_max_height(conf));
- }
- else {
+ *h = widget_min_height(conf, htext, menusize, true);
+ } else {
if (*formheight == 0)
- *formheight = MIN(rows-6-textrow, nitems);
+ *formheight = MIN(rows-6-htext, nitems);
}
+
+ return (0);
}
static int
-form_checksize(int rows, int cols, char *text, int formheight, int nitems,
- struct buttons bs)
+form_checksize(int rows, int cols, const char *text, int formheight, int nitems,
+ unsigned int linelen, struct buttons bs)
{
int mincols, textrow, formrows;
@@ -360,40 +332,39 @@ form_checksize(int rows, int cols, char *text, int formheight, int nitems,
/* buttons */
mincols += bs.nbuttons * bs.sizebutton;
mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0;
- /* line, comment to permet some cols hidden */
- /* mincols = MAX(mincols, linelen); */
+ mincols = MAX(mincols, (int)linelen + 4);
if (cols < mincols)
- RETURN_ERROR("Few cols, width < size buttons or "\
- "labels + forms");
+ RETURN_ERROR("Few cols, width < size buttons or "
+ "forms (label + field)");
textrow = text != NULL && strlen(text) > 0 ? 1 : 0;
if (nitems > 0 && formheight == 0)
- RETURN_ERROR("fields > 0 but formheight == 0, probably "\
+ RETURN_ERROR("fields > 0 but formheight == 0, probably "
"terminal too small");
formrows = nitems > 0 ? 3 : 0;
if (rows < 2 + 2 + formrows + textrow)
RETURN_ERROR("Few lines for this menus");
- return 0;
+ return (0);
}
int
-bsddialog_form(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int formheight, unsigned int nitems,
+bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int formheight, unsigned int nitems,
struct bsddialog_formitem *items)
{
WINDOW *widget, *formwin, *textpad, *shadow;
- int i, output, color, y, x, h, w, htextpad;
+ int i, output, color, y, x, h, w;
FIELD **cfield;
FORM *form;
struct buttons bs;
struct myfield *myfields;
unsigned long maxline;
- /* disable form scrolling like dialog */
+ /* disable form scrolling */
if (formheight < nitems)
formheight = nitems;
@@ -409,7 +380,7 @@ bsddialog_form(struct bsddialog_conf *conf, char* text, int rows, int cols,
maxline = 0;
myfields = malloc(nitems * sizeof(struct myfield));
cfield = calloc(nitems + 1, sizeof(FIELD*));
- for (i=0; i < (int)nitems; i++) {
+ for (i = 0; i < (int)nitems; i++) {
cfield[i] = new_field(1, items[i].fieldlen, items[i].yfield-1,
items[i].xfield-1, 0, 0);
field_opts_off(cfield[i], O_STATIC);
@@ -417,7 +388,7 @@ bsddialog_form(struct bsddialog_conf *conf, char* text, int rows, int cols,
set_field_buffer(cfield[i], 0, items[i].init);
myfields[i].buf = malloc(items[i].maxvaluelen + 1);
- memset(myfields[i].buf, 0, items[i].maxvaluelen + 1); // end with '\0' for strdup
+ memset(myfields[i].buf, 0, items[i].maxvaluelen + 1);
strncpy(myfields[i].buf, items[i].init, items[i].maxvaluelen);
myfields[i].buflen = strlen(myfields[i].buf);
@@ -430,16 +401,15 @@ bsddialog_form(struct bsddialog_conf *conf, char* text, int rows, int cols,
field_opts_off(cfield[i], O_AUTOSKIP);
field_opts_off(cfield[i], O_BLANK);
- /* field_opts_off(field[i], O_BS_OVERLOAD); */
if (ISFIELDHIDDEN(items[i])) {
- /* field_opts_off(field[i], O_PUBLIC); old hidden */
myfields[i].secure = true;
myfields[i].securech = ' ';
if (conf->form.securech != '\0')
myfields[i].securech = conf->form.securech;
}
- else myfields[i].secure = false;
+ else
+ myfields[i].secure = false;
if (ISFIELDREADONLY(items[i])) {
field_opts_off(cfield[i], O_EDIT);
@@ -452,7 +422,7 @@ bsddialog_form(struct bsddialog_conf *conf, char* text, int rows, int cols,
set_field_back(cfield[i], color);
maxline = MAX(maxline, items[i].xlabel + strlen(items[i].label));
- maxline = MAX(maxline, items[i].xfield + items[i].fieldlen);
+ maxline = MAX(maxline, items[i].xfield + items[i].fieldlen - 1);
}
cfield[i] = NULL;
@@ -462,26 +432,26 @@ bsddialog_form(struct bsddialog_conf *conf, char* text, int rows, int cols,
set_field_fore(cfield[0], t.dialog.color);
set_field_back(cfield[0], t.dialog.color);
}
-
- get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
- BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
+
+ get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
- form_autosize(conf, rows, cols, &h, &w, text, maxline, &formheight,
- nitems, bs);
- if (form_checksize(h, w, text, formheight, nitems, bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
+ if (form_autosize(conf, rows, cols, &h, &w, text, maxline, &formheight,
+ nitems, bs) != 0)
+ return (BSDDIALOG_ERROR);
+ if (form_checksize(h, w, text, formheight, nitems, maxline, bs) != 0)
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
- if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
- &textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
+ if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
+ true) != 0)
+ return (BSDDIALOG_ERROR);
+
+ prefresh(textpad, 0, 0, y + 1, x + 1 + TEXTHMARGIN,
+ y + h - formheight, x + 1 + w - TEXTHMARGIN);
- prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin,
- y + h - formheight, x + 1 + w - t.text.hmargin);
-
formwin = new_boxed_window(conf, y + h - 3 - formheight -2, x +1,
formheight+2, w-2, LOWERED);
@@ -491,32 +461,35 @@ bsddialog_form(struct bsddialog_conf *conf, char* text, int rows, int cols,
set_form_sub(form, derwin(formwin, nitems, w-4, 1, 1));
post_form(form);
- for (i=0; i < (int)nitems; i++)
- mvwaddstr(formwin, items[i].ylabel, items[i].xlabel, items[i].label);
+ for (i = 0; i < (int)nitems; i++)
+ mvwaddstr(formwin, items[i].ylabel, items[i].xlabel,
+ items[i].label);
wrefresh(formwin);
do {
- output = form_handler(conf, widget, h-2, w, bs, formwin, form,
- cfield, nitems, items);
-
- if(update_widget_withtextpad(conf, shadow, widget, h, w,
- RAISED, textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
-
- draw_buttons(widget, h-2, w, bs, true);
+ output = form_handler(conf, widget, bs, formwin, form, cfield,
+ nitems, items);
+
+ if (update_dialog(conf, shadow, widget, y, x, h, w, textpad,
+ text, &bs, true) != 0)
+ return (BSDDIALOG_ERROR);
+
+ doupdate();
wrefresh(widget);
- prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin,
- y + h - formheight, x + 1 + w - t.text.hmargin);
+ prefresh(textpad, 0, 0, y + 1, x + 1 + TEXTHMARGIN,
+ y + h - formheight, x + 1 + w - TEXTHMARGIN);
draw_borders(conf, formwin, formheight+2, w-2, LOWERED);
- /* wrefresh(formwin); */
+ wrefresh(formwin);
+
+ refresh();
} while (output == REDRAWFORM);
unpost_form(form);
free_form(form);
- for (i=0; i < (int)nitems; i++) {
+ for (i = 0; i < (int)nitems; i++) {
free_field(cfield[i]);
free(myfields[i].buf);
}
@@ -524,7 +497,7 @@ bsddialog_form(struct bsddialog_conf *conf, char* text, int rows, int cols,
free(myfields);
delwin(formwin);
- end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
+ end_dialog(conf, shadow, widget, textpad);
- return output;
-}
+ return (output);
+} \ No newline at end of file
diff --git a/lib/infobox.c b/lib/infobox.c
index 7752d7eec190..4ded942fb300 100644
--- a/lib/infobox.c
+++ b/lib/infobox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,92 +27,73 @@
#include <sys/param.h>
-#ifdef PORTNCURSES
-#include <ncurses/ncurses.h>
-#else
-#include <ncurses.h>
-#endif
+#include <curses.h>
#include "bsddialog.h"
-#include "lib_util.h"
#include "bsddialog_theme.h"
-
-/* "Info": infobox */
-
-#define MIN_HEIGHT 3
+#include "lib_util.h"
extern struct bsddialog_theme t;
static int
-infobox_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
- char *text)
+infobox_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
+ int *w, const char *text)
{
- int maxword, maxline, nlines;
-
- if (get_text_properties(conf, text, &maxword, &maxline, &nlines) != 0)
- return BSDDIALOG_ERROR;
-
- if (cols == BSDDIALOG_AUTOSIZE) {
- /* text size */
- *w = maxline + VBORDERS + t.text.hmargin * 2;
- /* conf.auto_minwidth */
- *w = MAX(*w, (int)conf->auto_minwidth);
- /* avoid terminal overflow */
- *w = MIN(*w, widget_max_width(conf));
- }
+ int htext, wtext;
- if (rows == BSDDIALOG_AUTOSIZE) {
- *h = MIN_HEIGHT - 1;
- if (maxword > 0)
- *h += MIN(nlines, (int)(*w / GET_ASPECT_RATIO(conf)));
- *h = MAX(*h, MIN_HEIGHT);
- /* conf.auto_minheight */
- *h = MAX(*h, (int)conf->auto_minheight);
- /* avoid terminal overflow */
- *h = MIN(*h, widget_max_height(conf));
+ if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
+ if (text_size(conf, rows, cols, text, NULL, 0, SCREENCOLS/2,
+ &htext, &wtext) != 0)
+ return (BSDDIALOG_ERROR);
}
- return 0;
+ if (cols == BSDDIALOG_AUTOSIZE)
+ *w = widget_min_width(conf, wtext, 0, NULL);
+
+ if (rows == BSDDIALOG_AUTOSIZE)
+ *h = widget_min_height(conf, htext, 0, false);
+
+ return (0);
}
static int infobox_checksize(int rows, int cols)
{
+ if (cols < HBORDERS)
+ RETURN_ERROR("Few cols, infobox needs at least width 2");
- if (cols < HBORDERS + 1 + (int) t.text.hmargin * 2)
- RETURN_ERROR("Few cols, infobox needs at least width 3 + text "\
- "margins");
-
- if (rows < 3)
- RETURN_ERROR("Infobox needs at least height 3");
+ if (rows < VBORDERS)
+ RETURN_ERROR("Infobox needs at least height 2");
- return 0;
+ return (0);
}
+/* API */
int
-bsddialog_infobox(struct bsddialog_conf *conf, char* text, int rows, int cols)
+bsddialog_infobox(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols)
{
+ int y, x, h, w;
WINDOW *shadow, *widget, *textpad;
- int y, x, h, w, htextpad;
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (infobox_autosize(conf, rows, cols, &h, &w, text) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (infobox_checksize(h, w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
- if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
- &textpad, &htextpad, text, false) != 0)
- return BSDDIALOG_ERROR;
+ if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text,
+ NULL, false) != 0)
+ return (BSDDIALOG_ERROR);
- pnoutrefresh(textpad, 0, 0, y+1, x+1+t.text.hmargin, y+h-2, x+w-t.text.hmargin);
+ pnoutrefresh(textpad, 0, 0, y+1, x+1+TEXTHMARGIN, y+h-2,
+ x+w-TEXTHMARGIN);
doupdate();
- end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
+ end_dialog(conf, shadow, widget, textpad);
return (BSDDIALOG_OK);
-}
-
+} \ No newline at end of file
diff --git a/lib/lib_util.c b/lib/lib_util.c
index 81c2b7642aac..f7e6a2ae15ab 100644
--- a/lib/lib_util.c
+++ b/lib/lib_util.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,46 +27,42 @@
#include <sys/param.h>
-#ifdef PORTNCURSES
-#include <ncurses/ncurses.h>
-#else
-#include <ncurses.h>
-#endif
+#include <ctype.h>
+#include <curses.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "bsddialog.h"
-#include "lib_util.h"
#include "bsddialog_theme.h"
+#include "lib_util.h"
extern struct bsddialog_theme t;
-/* Error buffer */
+#define TABLEN 4 /* Default tab len */
+#define ERRBUFLEN 1024 /* Error buffer */
-#define ERRBUFLEN 1024
+/* Error */
static char errorbuffer[ERRBUFLEN];
const char *get_error_string(void)
{
- return errorbuffer;
+ return (errorbuffer);
}
void set_error_string(char *str)
{
-
strncpy(errorbuffer, str, ERRBUFLEN-1);
}
-/* cleaner */
+/* Clear */
int hide_widget(int y, int x, int h, int w, bool withshadow)
{
WINDOW *clear;
- /* no check: y, x, h and w are checked by the builders */
if ((clear = newwin(h, w, y + t.shadow.h, x + t.shadow.w)) == NULL)
RETURN_ERROR("Cannot hide the widget");
- wbkgd(clear, t.terminal.color);
+ wbkgd(clear, t.screen.color);
if (withshadow)
wrefresh(clear);
@@ -76,7 +72,7 @@ int hide_widget(int y, int x, int h, int w, bool withshadow)
delwin(clear);
- return 0;
+ return (0);
}
/* F1 help */
@@ -85,15 +81,14 @@ int f1help(struct bsddialog_conf *conf)
int output;
struct bsddialog_conf hconf;
- //memcpy(&hconf, conf, sizeof(struct bsddialog_conf));
bsddialog_initconf(&hconf);
- hconf.title = "HELP";
+ hconf.title = "HELP";
hconf.button.ok_label = "EXIT";
- hconf.clear = true;
- hconf.ascii_lines = conf->ascii_lines;
- hconf.no_lines = conf->no_lines;
- hconf.shadow = conf->shadow;
- hconf.text.colors = conf->text.colors;
+ hconf.clear = true;
+ hconf.ascii_lines = conf->ascii_lines;
+ hconf.no_lines = conf->no_lines;
+ hconf.shadow = conf->shadow;
+ hconf.text.highlight = conf->text.highlight;
output = BSDDIALOG_OK;
if (conf->f1_message != NULL)
@@ -106,9 +101,9 @@ int f1help(struct bsddialog_conf *conf)
}
/* Buttons */
-void
-draw_button(WINDOW *window, int y, int x, int size, char *text, bool selected,
- bool shortkey)
+static void
+draw_button(WINDOW *window, int y, int x, int size, const char *text,
+ bool selected, bool shortcut)
{
int i, color_arrows, color_shortkey, color_button;
@@ -126,7 +121,7 @@ draw_button(WINDOW *window, int y, int x, int size, char *text, bool selected,
mvwaddch(window, y, x, t.button.leftch);
wattroff(window, color_arrows);
wattron(window, color_button);
- for(i = 1; i < size - 1; i++)
+ for (i = 1; i < size - 1; i++)
waddch(window, ' ');
wattroff(window, color_button);
wattron(window, color_arrows);
@@ -138,7 +133,7 @@ draw_button(WINDOW *window, int y, int x, int size, char *text, bool selected,
mvwaddstr(window, y, x, text);
wattroff(window, color_button);
- if (shortkey) {
+ if (shortcut) {
wattron(window, color_shortkey);
mvwaddch(window, y, x, text[0]);
wattroff(window, color_shortkey);
@@ -146,56 +141,62 @@ draw_button(WINDOW *window, int y, int x, int size, char *text, bool selected,
}
void
-draw_buttons(WINDOW *window, int y, int cols, struct buttons bs, bool shortkey)
+draw_buttons(WINDOW *window, struct buttons bs, bool shortcut)
{
- int i, x, start_x;
+ int i, x, startx, y, rows, cols;
+
+ getmaxyx(window, rows, cols);
+ y = rows - 2;
- start_x = bs.sizebutton * bs.nbuttons + (bs.nbuttons - 1) * t.button.space;
- start_x = cols/2 - start_x/2;
+ startx = bs.sizebutton * bs.nbuttons + (bs.nbuttons-1) * t.button.space;
+ startx = cols/2 - startx/2;
for (i = 0; i < (int) bs.nbuttons; i++) {
x = i * (bs.sizebutton + t.button.space);
- draw_button(window, y, start_x + x, bs.sizebutton, bs.label[i],
- i == bs.curr, shortkey);
+ draw_button(window, y, startx + x, bs.sizebutton, bs.label[i],
+ i == bs.curr, shortcut);
}
}
void
get_buttons(struct bsddialog_conf *conf, struct buttons *bs, char *yesoklabel,
- char *extralabel, char *nocancellabel, char *helplabel)
+ char *nocancellabel)
{
int i;
-#define SIZEBUTTON 8
-#define DEFAULT_BUTTON_LABEL LABEL_ok_label
+#define SIZEBUTTON 8
+#define DEFAULT_BUTTON_LABEL BUTTON_OK_LABEL
#define DEFAULT_BUTTON_VALUE BSDDIALOG_OK
-
bs->nbuttons = 0;
bs->curr = 0;
bs->sizebutton = 0;
if (yesoklabel != NULL && conf->button.without_ok == false) {
- bs->label[0] = yesoklabel;
+ bs->label[0] = conf->button.ok_label != NULL ?
+ conf->button.ok_label : yesoklabel;
bs->value[0] = BSDDIALOG_OK;
bs->nbuttons += 1;
}
- if (extralabel != NULL && conf->button.with_extra) {
- bs->label[bs->nbuttons] = extralabel;
+ if (conf->button.with_extra) {
+ bs->label[bs->nbuttons] = conf->button.extra_label != NULL ?
+ conf->button.extra_label : "Extra";
bs->value[bs->nbuttons] = BSDDIALOG_EXTRA;
bs->nbuttons += 1;
}
if (nocancellabel != NULL && conf->button.without_cancel == false) {
- bs->label[bs->nbuttons] = nocancellabel;
+ bs->label[bs->nbuttons] = conf->button.cancel_label ?
+ conf->button.cancel_label : nocancellabel;
bs->value[bs->nbuttons] = BSDDIALOG_CANCEL;
if (conf->button.default_cancel)
bs->curr = bs->nbuttons;
bs->nbuttons += 1;
}
- if (helplabel != NULL && conf->button.with_help) {
- bs->label[bs->nbuttons] = helplabel;
+ if (conf->button.with_help) {
+ bs->label[bs->nbuttons] = conf->button.help_label != NULL ?
+ conf->button.help_label : "Help";
bs->value[bs->nbuttons] = BSDDIALOG_HELP;
bs->nbuttons += 1;
}
@@ -219,44 +220,61 @@ get_buttons(struct bsddialog_conf *conf, struct buttons *bs, char *yesoklabel,
}
if (conf->button.default_label != NULL) {
- for (i=0; i<(int)bs->nbuttons; i++) {
- if (strcmp(conf->button.default_label, bs->label[i]) == 0)
+ for (i = 0; i < (int)bs->nbuttons; i++) {
+ if (strcmp(conf->button.default_label,
+ bs->label[i]) == 0)
bs->curr = i;
}
}
bs->sizebutton = MAX(SIZEBUTTON - 2, strlen(bs->label[0]));
- for (i=1; i < (int) bs->nbuttons; i++)
+ for (i = 1; i < (int)bs->nbuttons; i++)
bs->sizebutton = MAX(bs->sizebutton, strlen(bs->label[i]));
bs->sizebutton += 2;
}
-/* Text */
-static bool is_ncurses_attr(char *text)
+bool shortcut_buttons(int key, struct buttons *bs)
{
+ bool match;
+ unsigned int i;
+
+ match = false;
+ for (i = 0; i < bs->nbuttons; i++) {
+ if (tolower(key) == tolower(bs->label[i][0])) {
+ bs->curr = i;
+ match = true;
+ break;
+ }
+ }
+ return (match);
+}
+
+/* Text */
+static bool is_text_attr(const char *text)
+{
if (strnlen(text, 3) < 3)
- return false;
+ return (false);
if (text[0] != '\\' || text[1] != 'Z')
- return false;
+ return (false);
return (strchr("nbBrRuU01234567", text[2]) == NULL ? false : true);
}
-static bool check_set_ncurses_attr(WINDOW *win, char *text)
+static bool check_set_text_attr(WINDOW *win, char *text)
{
-
- if (is_ncurses_attr(text) == false)
- return false;
+ if (is_text_attr(text) == false)
+ return (false);
if ((text[2] - '0') >= 0 && (text[2] - '0') < 8) {
- wattron(win, bsddialog_color( text[2] - '0', COLOR_WHITE, 0));
- return true;
+ wattron(win, bsddialog_color(text[2] - '0', COLOR_WHITE, 0));
+ return (true);
}
switch (text[2]) {
case 'n':
+ wattron(win, t.dialog.color);
wattrset(win, A_NORMAL);
break;
case 'b':
@@ -279,22 +297,20 @@ static bool check_set_ncurses_attr(WINDOW *win, char *text)
break;
}
- return true;
+ return (true);
}
static void
-print_str(WINDOW *win, int *rows, int *y, int *x, int cols, char *str, bool color)
+print_string(WINDOW *win, int *rows, int cols, int *y, int *x, char *str,
+ bool color)
{
int i, j, len, reallen;
- if(strlen(str) == 0)
- return;
-
len = reallen = strlen(str);
if (color) {
i=0;
while (i < len) {
- if (is_ncurses_attr(str+i))
+ if (is_text_attr(str+i))
reallen -= 3;
i++;
}
@@ -312,7 +328,7 @@ print_str(WINDOW *win, int *rows, int *y, int *x, int cols, char *str, bool colo
}
j = *x;
while (j < cols && i < len) {
- if (color && check_set_ncurses_attr(win, str+i)) {
+ if (color && check_set_text_attr(win, str+i)) {
i += 3;
} else {
mvwaddch(win, *y, j, str[i]);
@@ -325,77 +341,28 @@ print_str(WINDOW *win, int *rows, int *y, int *x, int cols, char *str, bool colo
}
}
-int
-get_text_properties(struct bsddialog_conf *conf, char *text, int *maxword,
- int *maxline, int *nlines)
-{
- int i, buflen, wordlen, linelen;
-
-
- buflen = strlen(text) + 1;
- *maxword = 0;
- wordlen = 0;
- for (i=0; i < buflen; i++) {
- if (text[i] == '\t' || text[i] == '\n' || text[i] == ' ' || text[i] == '\0')
- if (wordlen != 0) {
- *maxword = MAX(*maxword, wordlen);
- wordlen = 0;
- continue;
- }
- if (conf->text.colors && is_ncurses_attr(text + i))
- i += 3;
- else
- wordlen++;
- }
-
- *maxline = linelen = 0;
- *nlines = 1;
- for (i=0; i < buflen; i++) {
- switch (text[i]) {
- case '\n':
- *nlines = *nlines + 1;
- case '\0':
- *maxline = MAX(*maxline, linelen);
- linelen = 0;
- break;
- default:
- if (conf->text.colors && is_ncurses_attr(text + i))
- i += 3;
- else
- linelen++;
- }
- }
- if (*nlines == 1 && *maxline == 0)
- *nlines = 0;
-
- //free(buf);
-
- return 0;
-}
-
-int
-print_textpad(struct bsddialog_conf *conf, WINDOW *pad, int *rows, int cols,
- char *text)
+static int
+print_textpad(struct bsddialog_conf *conf, WINDOW *pad, const char *text)
{
- char *string;
- int i, j, x, y;
bool loop;
+ int i, j, z, rows, cols, x, y, tablen;
+ char *string;
if ((string = malloc(strlen(text) + 1)) == NULL)
RETURN_ERROR("Cannot build (analyze) text");
+ getmaxyx(pad, rows, cols);
+ tablen = (conf->text.tablen == 0) ? TABLEN : (int)conf->text.tablen;
+
i = j = x = y = 0;
loop = true;
while (loop) {
string[j] = text[i];
- if (string[j] == '\0' || string[j] == '\n' ||
- string[j] == '\t' || string[j] == ' ') {
- if (j != 0) {
- string[j] = '\0';
- print_str(pad, rows, &y, &x, cols, string,
- conf->text.colors);
- }
+ if (strchr("\n\t ", string[j]) != NULL || string[j] == '\0') {
+ string[j] = '\0';
+ print_string(pad, &rows, cols, &y, &x, string,
+ conf->text.highlight);
}
switch (text[i]) {
@@ -403,17 +370,17 @@ print_textpad(struct bsddialog_conf *conf, WINDOW *pad, int *rows, int cols,
loop = false;
break;
case '\n':
- j = -1;
x = 0;
y++;
+ j = -1;
break;
case '\t':
- for (j=0; j<4 /*tablen*/; j++) {
- x++;
+ for (z = 0; z < tablen; z++) {
if (x >= cols) {
x = 0;
y++;
}
+ x++;
}
j = -1;
break;
@@ -426,9 +393,9 @@ print_textpad(struct bsddialog_conf *conf, WINDOW *pad, int *rows, int cols,
j = -1;
}
- if (y >= *rows) { /* check for whitespaces */
- *rows = y + 1;
- wresize(pad, *rows, cols);
+ if (y >= rows) {
+ rows = y + 1;
+ wresize(pad, rows, cols);
}
j++;
@@ -437,44 +404,279 @@ print_textpad(struct bsddialog_conf *conf, WINDOW *pad, int *rows, int cols,
free(string);
- return 0;
+ return (0);
}
-/* autosize */
+/* Autosize */
+static int
+text_autosize(struct bsddialog_conf *conf, const char *text, int maxrows,
+ int mincols, bool increasecols, int *h, int *w)
+{
+ int i, j, z, x, y;
+ int tablen, wordlen, maxwordlen, nword, maxwords, line, maxwidth;
+ int *words;
+#define NL -1
+#define WS -2
+
+ maxwords = 1024;
+ if ((words = calloc(maxwords, sizeof(int))) == NULL)
+ RETURN_ERROR("Cannot alloc memory for text autosize");
+
+ tablen = (conf->text.tablen == 0) ? TABLEN : (int)conf->text.tablen;
+ maxwidth = widget_max_width(conf) - HBORDERS - TEXTHMARGINS;
+
+ nword = 0;
+ wordlen = 0;
+ maxwordlen = 0;
+ i=0;
+ while (true) {
+ if (conf->text.highlight && is_text_attr(text + i)) {
+ i += 3;
+ continue;
+ }
+
+ if (nword + tablen >= maxwords) {
+ maxwords += 1024;
+ if (realloc(words, maxwords * sizeof(int)) == NULL)
+ RETURN_ERROR("Cannot realloc memory for text "
+ "autosize");
+ }
+
+ if (text[i] == '\0') {
+ words[nword] = wordlen;
+ maxwordlen = MAX(wordlen, maxwordlen);
+ break;
+ }
+
+ if (strchr("\t\n ", text[i]) != NULL) {
+ maxwordlen = MAX(wordlen, maxwordlen);
+
+ if (wordlen != 0) {
+ words[nword] = wordlen;
+ nword++;
+ wordlen = 0;
+ }
+
+ if (text[i] == '\t') {
+ for (j = 0; j < tablen; j++)
+ words[nword + j] = 1;
+ nword += tablen;
+ } else {
+ words[nword] = text[i] == '\n' ? NL : WS;
+ nword++;
+ }
+ }
+ else
+ wordlen++;
+
+ i++;
+ }
+
+ if (increasecols) {
+ mincols = MAX(mincols, maxwordlen);
+ mincols = MAX(mincols,
+ (int)conf->auto_minwidth - HBORDERS - TEXTHMARGINS);
+ mincols = MIN(mincols, maxwidth);
+ }
+
+ while (true) {
+ x = 0;
+ y = 1;
+ line=0;
+ for (i = 0; i <= nword; i++) {
+ if (words[i] == NL) {
+ y++;
+ x = 0;
+ }
+ else if (words[i] == WS) {
+ x++;
+ if (x >= mincols) {
+ x = 0;
+ y++;
+ }
+ }
+ else {
+ if (words[i] + x <= mincols)
+ x += words[i];
+ else {
+ for (z = words[i]; z > 0; ) {
+ y++;
+ x = MIN(mincols, z);
+ z -= x;
+ }
+ }
+ }
+ line = MAX(line, x);
+ }
+
+ if (increasecols == false)
+ break;
+ if (y <= maxrows || mincols >= maxwidth)
+ break;
+ mincols++;
+ }
+
+ *h = (nword == 0 && words[0] == 0) ? 0 : y;
+ *w = MIN(mincols, line); /* wtext can be less than mincols */
+
+ free(words);
+
+ return (0);
+}
+
+int
+text_size(struct bsddialog_conf *conf, int rows, int cols, const char *text,
+ struct buttons *bs, int rowsnotext, int startwtext, int *htext, int *wtext)
+{
+ int wbuttons, maxhtext;
+ bool changewtext;
+
+ wbuttons = 0;
+ if (bs != NULL) {
+ wbuttons = bs->nbuttons * bs->sizebutton;
+ if (bs->nbuttons > 0)
+ wbuttons += (bs->nbuttons-1) * t.button.space;
+ }
+
+ if (cols == BSDDIALOG_AUTOSIZE) {
+ startwtext = MAX(startwtext, wbuttons - TEXTHMARGINS);
+ changewtext = true;
+ } else if (cols == BSDDIALOG_FULLSCREEN) {
+ startwtext = widget_max_width(conf) - VBORDERS - TEXTHMARGINS;
+ changewtext = false;
+ } else { /* fixed */
+ startwtext = cols - VBORDERS - TEXTHMARGINS;
+ changewtext = false;
+ }
+
+ if (rows == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_FULLSCREEN) {
+ maxhtext = widget_max_height(conf) - VBORDERS - rowsnotext;
+ if (bs != NULL)
+ maxhtext -= 2;
+ } else { /* fixed */
+ maxhtext = rows - VBORDERS - rowsnotext;
+ if (bs != NULL)
+ maxhtext -= 2;
+ }
+
+ if (startwtext <= 0 && changewtext)
+ startwtext = 1;
+ if (maxhtext <= 0 || startwtext <= 0) {
+ *htext = *wtext = 0;
+ return (0);
+ }
+
+ if (text_autosize(conf, text, maxhtext, startwtext, changewtext,
+ htext, wtext) != 0)
+ return (BSDDIALOG_ERROR);
+
+ return (0);
+}
-/*
- * max y, that is from 0 to LINES - 1 - t.shadowrows,
- * could not be max height but avoids problems with checksize
- */
int widget_max_height(struct bsddialog_conf *conf)
{
int maxheight;
- if ((maxheight = conf->shadow ? LINES - 1 - t.shadow.h : LINES - 1) <= 0)
- RETURN_ERROR("Terminal too small, LINES - shadow <= 0");
+ maxheight = conf->shadow ? SCREENLINES - t.shadow.h : SCREENLINES;
+ if (maxheight <= 0)
+ RETURN_ERROR("Terminal too small, screen lines - shadow <= 0");
- if (conf->y > 0)
- if ((maxheight -= conf->y) <=0)
- RETURN_ERROR("Terminal too small, LINES - shadow - y <= 0");
+ if (conf->y > 0) {
+ maxheight -= conf->y;
+ if (maxheight <= 0)
+ RETURN_ERROR("Terminal too small, screen lines - "
+ "shadow - y <= 0");
+ }
- return maxheight;
+ return (maxheight);
}
-/*
- * max x, that is from 0 to COLS - 1 - t.shadowcols,
- * * could not be max height but avoids problems with checksize
- */
int widget_max_width(struct bsddialog_conf *conf)
{
int maxwidth;
- if ((maxwidth = conf->shadow ? COLS - 1 - t.shadow.w : COLS - 1) <= 0)
- RETURN_ERROR("Terminal too small, COLS - shadow <= 0");
- if (conf->x > 0)
- if ((maxwidth -= conf->x) <=0)
- RETURN_ERROR("Terminal too small, COLS - shadow - x <= 0");
+ maxwidth = conf->shadow ? SCREENCOLS - t.shadow.w : SCREENCOLS;
+ if (maxwidth <= 0)
+ RETURN_ERROR("Terminal too small, screen cols - shadow <= 0");
+
+ if (conf->x > 0) {
+ maxwidth -= conf->x;
+ if (maxwidth <= 0)
+ RETURN_ERROR("Terminal too small, screen cols - shadow "
+ "- x <= 0");
+ }
+
+ return (maxwidth);
+}
+
+int
+widget_min_height(struct bsddialog_conf *conf, int htext, int minwidget,
+ bool withbuttons)
+{
+ int min;
+
+ min = 0;
+
+ /* buttons */
+ if (withbuttons)
+ min += 2; /* buttons and border */
+
+ /* text */
+ min += htext;
+
+ /* specific widget min height */
+ min += minwidget;
+
+ /* dialog borders */
+ min += HBORDERS;
+ /* conf.auto_minheight */
+ min = MAX(min, (int)conf->auto_minheight);
+ /* avoid terminal overflow */
+ min = MIN(min, widget_max_height(conf));
+
+ return (min);
+}
+
+int
+widget_min_width(struct bsddialog_conf *conf, int wtext, int minwidget,
+ struct buttons *bs)
+
+{
+ int min, delimtitle;
+
+ min = 0;
+
+ /* buttons */
+ if (bs != NULL) {
+ min += bs->nbuttons * bs->sizebutton;
+ min += bs->nbuttons > 0 ? (bs->nbuttons-1) * t.button.space : 0;
+ }
+
+ /* text */
+ if (wtext > 0)
+ min = MAX(min, wtext + TEXTHMARGINS);
+
+ /* specific widget min width */
+ min = MAX(min, minwidget);
+
+ /* title */
+ if (conf->title != NULL) {
+ delimtitle = t.dialog.delimtitle ? 2 : 0;
+ min = MAX(min, (int)strlen(conf->title) + 2 + delimtitle);
+ }
+
+ /* bottom title */
+ if (conf->bottomtitle != NULL)
+ min = MAX(min, (int)strlen(conf->bottomtitle) + 4);
+
+ /* dialog borders */
+ min += VBORDERS;
+ /* conf.auto_minwidth */
+ min = MAX(min, (int)conf->auto_minwidth);
+ /* avoid terminal overflow */
+ min = MIN(min, widget_max_width(conf));
- return maxwidth;
+ return (min);
}
int
@@ -483,7 +685,7 @@ set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w)
int maxheight, maxwidth;
if ((maxheight = widget_max_height(conf)) == BSDDIALOG_ERROR)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (rows == BSDDIALOG_FULLSCREEN)
*h = maxheight;
@@ -491,13 +693,13 @@ set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w)
RETURN_ERROR("Negative (less than -1) height");
else if (rows > BSDDIALOG_AUTOSIZE) {
if ((*h = rows) > maxheight)
- RETURN_ERROR("Height too big (> terminal height - "\
- "shadow");
+ RETURN_ERROR("Height too big (> terminal height - "
+ "shadow)");
}
/* rows == AUTOSIZE: each widget has to set its size */
if ((maxwidth = widget_max_width(conf)) == BSDDIALOG_ERROR)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (cols == BSDDIALOG_FULLSCREEN)
*w = maxwidth;
@@ -505,45 +707,45 @@ set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w)
RETURN_ERROR("Negative (less than -1) width");
else if (cols > BSDDIALOG_AUTOSIZE) {
if ((*w = cols) > maxwidth)
- RETURN_ERROR("Width too big (> terminal width - shadow)");
+ RETURN_ERROR("Width too big (> terminal width - "
+ "shadow)");
}
/* cols == AUTOSIZE: each widget has to set its size */
- return 0;
+ return (0);
}
int
set_widget_position(struct bsddialog_conf *conf, int *y, int *x, int h, int w)
{
-
if (conf->y == BSDDIALOG_CENTER)
- *y = LINES/2 - h/2;
+ *y = SCREENLINES/2 - (h + t.shadow.h)/2;
else if (conf->y < BSDDIALOG_CENTER)
RETURN_ERROR("Negative begin y (less than -1)");
- else if (conf->y >= LINES)
+ else if (conf->y >= SCREENLINES)
RETURN_ERROR("Begin Y under the terminal");
else
*y = conf->y;
- if ((*y + h + (conf->shadow ? (int) t.shadow.h : 0)) > LINES)
- RETURN_ERROR("The lower of the box under the terminal "\
+ if ((*y + h + (conf->shadow ? (int) t.shadow.h : 0)) > SCREENLINES)
+ RETURN_ERROR("The lower of the box under the terminal "
"(begin Y + height (+ shadow) > terminal lines)");
if (conf->x == BSDDIALOG_CENTER)
- *x = COLS/2 - w/2;
+ *x = SCREENCOLS/2 - (w + t.shadow.w)/2;
else if (conf->x < BSDDIALOG_CENTER)
RETURN_ERROR("Negative begin x (less than -1)");
- else if (conf->x >= COLS)
+ else if (conf->x >= SCREENCOLS)
RETURN_ERROR("Begin X over the right of the terminal");
else
*x = conf->x;
- if ((*x + w + (conf->shadow ? (int) t.shadow.w : 0)) > COLS)
- RETURN_ERROR("The right of the box over the terminal "\
+ if ((*x + w + (conf->shadow ? (int) t.shadow.w : 0)) > SCREENCOLS)
+ RETURN_ERROR("The right of the box over the terminal "
"(begin X + width (+ shadow) > terminal cols)");
- return 0;
+ return (0);
}
/* Widgets builders */
@@ -552,39 +754,40 @@ draw_borders(struct bsddialog_conf *conf, WINDOW *win, int rows, int cols,
enum elevation elev)
{
int leftcolor, rightcolor;
- int ls, rs, ts, bs, tl, tr, bl, br;
- int ltee, rtee;
-
- ls = rs = ACS_VLINE;
- ts = bs = ACS_HLINE;
- tl = ACS_ULCORNER;
- tr = ACS_URCORNER;
- bl = ACS_LLCORNER;
- br = ACS_LRCORNER;
- ltee = ACS_LTEE;
- rtee = ACS_RTEE;
-
- if (conf->no_lines == false) {
- if (conf->ascii_lines) {
- ls = rs = '|';
- ts = bs = '-';
- tl = tr = bl = br = ltee = rtee = '+';
- }
- leftcolor = elev == RAISED ?
- t.dialog.lineraisecolor : t.dialog.linelowercolor;
- rightcolor = elev == RAISED ?
- t.dialog.linelowercolor : t.dialog.lineraisecolor;
- wattron(win, leftcolor);
- wborder(win, ls, rs, ts, bs, tl, tr, bl, br);
- wattroff(win, leftcolor);
-
- wattron(win, rightcolor);
- mvwaddch(win, 0, cols-1, tr);
- mvwvline(win, 1, cols-1, rs, rows-2);
- mvwaddch(win, rows-1, cols-1, br);
- mvwhline(win, rows-1, 1, bs, cols-2);
- wattroff(win, rightcolor);
+ int ls, rs, ts, bs, tl, tr, bl, br, ltee, rtee;
+
+ if (conf->no_lines)
+ return;
+
+ if (conf->ascii_lines) {
+ ls = rs = '|';
+ ts = bs = '-';
+ tl = tr = bl = br = ltee = rtee = '+';
+ } else {
+ ls = rs = ACS_VLINE;
+ ts = bs = ACS_HLINE;
+ tl = ACS_ULCORNER;
+ tr = ACS_URCORNER;
+ bl = ACS_LLCORNER;
+ br = ACS_LRCORNER;
+ ltee = ACS_LTEE;
+ rtee = ACS_RTEE;
}
+
+ leftcolor = elev == RAISED ?
+ t.dialog.lineraisecolor : t.dialog.linelowercolor;
+ rightcolor = elev == RAISED ?
+ t.dialog.linelowercolor : t.dialog.lineraisecolor;
+ wattron(win, leftcolor);
+ wborder(win, ls, rs, ts, bs, tl, tr, bl, br);
+ wattroff(win, leftcolor);
+
+ wattron(win, rightcolor);
+ mvwaddch(win, 0, cols-1, tr);
+ mvwvline(win, 1, cols-1, rs, rows-2);
+ mvwaddch(win, rows-1, cols-1, br);
+ mvwhline(win, rows-1, 1, bs, cols-2);
+ wattroff(win, rightcolor);
}
WINDOW *
@@ -595,119 +798,113 @@ new_boxed_window(struct bsddialog_conf *conf, int y, int x, int rows, int cols,
if ((win = newwin(rows, cols, y, x)) == NULL) {
set_error_string("Cannot build boxed window");
- return NULL;
+ return (NULL);
}
wbkgd(win, t.dialog.color);
draw_borders(conf, win, rows, cols, elev);
- return win;
+ return (win);
}
-/*
- * `enum elevation elev` could be useless because it should be always RAISED,
- * to check at the end.
- */
static int
-draw_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *shadow,
- WINDOW *widget, int h, int w, enum elevation elev,
- WINDOW *textpad, int *htextpad, char *text, bool buttons)
+draw_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
+ WINDOW *textpad, const char *text, struct buttons *bs, bool shortcutbuttons)
{
- int ts, ltee, rtee;
- int colordelimtitle;
+ int h, w, ts, ltee, rtee;
ts = conf->ascii_lines ? '-' : ACS_HLINE;
ltee = conf->ascii_lines ? '+' : ACS_LTEE;
rtee = conf->ascii_lines ? '+' : ACS_RTEE;
- colordelimtitle = elev == RAISED ?
- t.dialog.lineraisecolor : t.dialog.linelowercolor;
+
+ getmaxyx(widget, h, w);
if (shadow != NULL)
wnoutrefresh(shadow);
- // move / resize now or the caller?
- draw_borders(conf, widget, h, w, elev);
+ draw_borders(conf, widget, h, w, RAISED);
if (conf->title != NULL) {
if (t.dialog.delimtitle && conf->no_lines == false) {
- wattron(widget, colordelimtitle);
- mvwaddch(widget, 0, w/2 - strlen(conf->title)/2 - 1, rtee);
- wattroff(widget, colordelimtitle);
+ wattron(widget, t.dialog.lineraisecolor);
+ mvwaddch(widget, 0, w/2-strlen(conf->title)/2-1, rtee);
+ wattroff(widget, t.dialog.lineraisecolor);
}
wattron(widget, t.dialog.titlecolor);
mvwaddstr(widget, 0, w/2 - strlen(conf->title)/2, conf->title);
wattroff(widget, t.dialog.titlecolor);
if (t.dialog.delimtitle && conf->no_lines == false) {
- wattron(widget, colordelimtitle);
+ wattron(widget, t.dialog.lineraisecolor);
waddch(widget, ltee);
- wattroff(widget, colordelimtitle);
+ wattroff(widget, t.dialog.lineraisecolor);
}
}
+ if (bs != NULL) {
+ if (conf->no_lines == false) {
+ wattron(widget, t.dialog.lineraisecolor);
+ mvwaddch(widget, h-3, 0, ltee);
+ mvwhline(widget, h-3, 1, ts, w-2);
+ wattroff(widget, t.dialog.lineraisecolor);
+
+ wattron(widget, t.dialog.linelowercolor);
+ mvwaddch(widget, h-3, w-1, rtee);
+ wattroff(widget, t.dialog.linelowercolor);
+ }
+ draw_buttons(widget, *bs, shortcutbuttons);
+ }
+
if (conf->bottomtitle != NULL) {
wattron(widget, t.dialog.bottomtitlecolor);
wmove(widget, h - 1, w/2 - strlen(conf->bottomtitle)/2 - 1);
- waddch(widget, '[');
+ waddch(widget, ' ');
waddstr(widget, conf->bottomtitle);
- waddch(widget, ']');
+ waddch(widget, ' ');
wattroff(widget, t.dialog.bottomtitlecolor);
}
- //if (textpad == NULL && text != NULL) /* no pad, text null for textbox */
- // print_text(conf, widget, 1, 2, w-3, text);
-
- if (buttons && conf->no_lines == false) {
- wattron(widget, t.dialog.lineraisecolor);
- mvwaddch(widget, h-3, 0, ltee);
- mvwhline(widget, h-3, 1, ts, w-2);
- wattroff(widget, t.dialog.lineraisecolor);
-
- wattron(widget, t.dialog.linelowercolor);
- mvwaddch(widget, h-3, w-1, rtee);
- wattroff(widget, t.dialog.linelowercolor);
- }
-
wnoutrefresh(widget);
- if (textpad == NULL)
- return 0; /* widget_init() ends */
+ if (textpad != NULL && text != NULL) /* textbox */
+ if (print_textpad(conf, textpad, text) !=0)
+ return (BSDDIALOG_ERROR);
- if (text != NULL) /* programbox etc */
- if (print_textpad(conf, textpad, htextpad,
- w - HBORDERS - t.text.hmargin * 2, text) !=0)
- return BSDDIALOG_ERROR;
-
- return 0;
+ return (0);
}
-/*
- * `enum elevation elev` could be useless because it should be always RAISED,
- * to check at the end.
- */
int
-update_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *shadow,
- WINDOW *widget, int h, int w, enum elevation elev,
- WINDOW *textpad, int *htextpad, char *text, bool buttons)
+update_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
+ int y, int x, int h, int w, WINDOW *textpad, const char *text,
+ struct buttons *bs, bool shortcutbuttons)
{
int error;
- /* nothing for now */
+ if (shadow != NULL) {
+ wclear(shadow);
+ mvwin(shadow, y + t.shadow.h, x + t.shadow.w);
+ wresize(shadow, h, w);
+ }
+
+ wclear(widget);
+ mvwin(widget, y, x);
+ wresize(widget, h, w);
+
+ if (textpad != NULL) {
+ wclear(textpad);
+ wresize(textpad, 1, w - HBORDERS - TEXTHMARGINS);
+ }
- error = draw_widget_withtextpad(conf, shadow, widget, h, w,
- elev, textpad, htextpad, text, buttons);
+ error = draw_dialog(conf, shadow, widget, textpad, text, bs,
+ shortcutbuttons);
- return error;
+ return (error);
}
-/*
- * `enum elevation elev` could be useless because it should be always RAISED,
- * to check at the end.
- */
int
-new_widget_withtextpad(struct bsddialog_conf *conf, WINDOW **shadow,
- WINDOW **widget, int y, int x, int h, int w, enum elevation elev,
- WINDOW **textpad, int *htextpad, char *text, bool buttons)
+new_dialog(struct bsddialog_conf *conf, WINDOW **shadow, WINDOW **widget, int y,
+ int x, int h, int w, WINDOW **textpad, const char *text, struct buttons *bs,
+ bool shortcutbuttons)
{
int error;
@@ -718,23 +915,16 @@ new_widget_withtextpad(struct bsddialog_conf *conf, WINDOW **shadow,
wbkgd(*shadow, t.shadow.color);
}
- if ((*widget = new_boxed_window(conf, y, x, h, w, elev)) == NULL) {
+ if ((*widget = new_boxed_window(conf, y, x, h, w, RAISED)) == NULL) {
if (conf->shadow)
delwin(*shadow);
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
}
- if (textpad == NULL) { /* widget_init() */
- error = draw_widget_withtextpad(conf, *shadow, *widget, h, w,
- elev, NULL, NULL, text, buttons);
- return error;
- }
-
- if (text != NULL) { /* programbox etc */
- *htextpad = 1;
- *textpad = newpad(*htextpad, w - HBORDERS - t.text.hmargin * 2);
+ if (textpad != NULL && text != NULL) { /* textbox */
+ *textpad = newpad(1, w - HBORDERS - TEXTHMARGINS);
if (*textpad == NULL) {
- delwin(*textpad);
+ delwin(*widget);
if (conf->shadow)
delwin(*shadow);
RETURN_ERROR("Cannot build the pad window for text");
@@ -742,19 +932,20 @@ new_widget_withtextpad(struct bsddialog_conf *conf, WINDOW **shadow,
wbkgd(*textpad, t.dialog.color);
}
- error = draw_widget_withtextpad(conf, *shadow, *widget, h, w, elev,
- *textpad, htextpad, text, buttons);
+ error = draw_dialog(conf, *shadow, *widget,
+ textpad == NULL ? NULL : *textpad, text, bs, shortcutbuttons);
- return error;
+ return (error);
}
void
-end_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *window, int h, int w,
- WINDOW *textpad, WINDOW *shadow)
+end_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
+ WINDOW *textpad)
{
- int y, x;
+ int y, x, h, w;
- getbegyx(window, y, x); /* for clear, add y & x to args? */
+ getbegyx(widget, y, x);
+ getmaxyx(widget, h, w);
if (conf->sleep > 0)
sleep(conf->sleep);
@@ -762,7 +953,7 @@ end_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *window, int h, int w
if (textpad != NULL)
delwin(textpad);
- delwin(window);
+ delwin(widget);
if (conf->shadow)
delwin(shadow);
@@ -774,4 +965,4 @@ end_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *window, int h, int w
*conf->get_height = h;
if (conf->get_width != NULL)
*conf->get_width = w;
-}
+} \ No newline at end of file
diff --git a/lib/lib_util.h b/lib/lib_util.h
index e9791b1894a7..a3ed2508cd49 100644
--- a/lib/lib_util.h
+++ b/lib/lib_util.h
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,21 +28,10 @@
#ifndef _LIBBSDDIALOG_UTIL_H_
#define _LIBBSDDIALOG_UTIL_H_
-/*
- * Utils to implement widgets - Internal library API - Dafult values
- */
-
-#define HBORDER 1
-#define HBORDERS (HBORDER + HBORDER)
-#define VBORDER 1
-#define VBORDERS (VBORDER + VBORDER)
-#define PADDING(p) (p)
-
-/* ncurses has not a Ctrl key macro */
-#define KEY_CTRL(x) ((x) & 0x1f)
-
-/* Set default aspect ratio to 9 */
-#define GET_ASPECT_RATIO(conf) (conf->aspect_ratio > 0 ? conf->aspect_ratio : 9)
+#define HBORDERS 2
+#define VBORDERS 2
+#define TEXTHMARGIN 1
+#define TEXTHMARGINS (TEXTHMARGIN + TEXTHMARGIN)
/* debug */
#define BSDDIALOG_DEBUG(y,x,fmt, ...) do { \
@@ -56,36 +45,29 @@ void set_error_string(char *string);
#define RETURN_ERROR(str) do { \
set_error_string(str); \
- return BSDDIALOG_ERROR; \
+ return (BSDDIALOG_ERROR); \
} while (0)
-/* Buttons */
-#define LABEL_cancel_label "Cancel"
-#define LABEL_exit_label "EXIT"
-#define LABEL_extra_label "Extra"
-#define LABEL_help_label "Help"
-#define LABEL_ok_label "OK"
-#define BUTTONLABEL(l) (conf->button.l != NULL ? conf->button.l : LABEL_ ##l)
-
-#define MAXBUTTONS 6 /* yes|ok + extra + no|cancel + help + 2 generics */
+/* buttons */
struct buttons {
unsigned int nbuttons;
- char *label[MAXBUTTONS];
+#define MAXBUTTONS 6 /* ok + extra + cancel + help + 2 generics */
+ const char *label[MAXBUTTONS];
int value[MAXBUTTONS];
int curr;
unsigned int sizebutton; /* including left and right delimiters */
};
+#define BUTTON_OK_LABEL "OK"
+#define BUTTON_CANCEL_LABEL "Cancel"
void
get_buttons(struct bsddialog_conf *conf, struct buttons *bs, char *yesoklabel,
- char *extralabel, char *nocancellabel, char *helplabel);
+ char *nocancellabel);
void
-draw_button(WINDOW *window, int y, int x, int size, char *text, bool selected,
- bool shortkey);
+draw_buttons(WINDOW *window, struct buttons bs, bool shortcut);
-void
-draw_buttons(WINDOW *window, int y, int cols, struct buttons bs, bool shortkey);
+bool shortcut_buttons(int key, struct buttons *bs);
/* help window with F1 key */
int f1help(struct bsddialog_conf *conf);
@@ -94,24 +76,32 @@ int f1help(struct bsddialog_conf *conf);
int hide_widget(int y, int x, int h, int w, bool withshadow);
/* (auto) size and (auto) position */
+#define SCREENLINES (getmaxy(stdscr))
+#define SCREENCOLS (getmaxx(stdscr))
+
int
-get_text_properties(struct bsddialog_conf *conf, char *text, int *maxword,
- int *maxline, int *nlines);
+text_size(struct bsddialog_conf *conf, int rows, int cols, const char *text,
+ struct buttons *bs, int rowsnotext, int startwtext, int *htext, int *wtext);
int widget_max_height(struct bsddialog_conf *conf);
int widget_max_width(struct bsddialog_conf *conf);
int
-set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w);
+widget_min_height(struct bsddialog_conf *conf, int htext, int minwidget,
+ bool withbuttons);
int
-set_widget_position(struct bsddialog_conf *conf, int *y, int *x, int h, int w);
+widget_min_width(struct bsddialog_conf *conf, int wtext, int minwidget,
+ struct buttons *bs);
+
+int
+set_widget_size(struct bsddialog_conf *conf, int rows, int cols, int *h,
+ int *w);
-/* widget builders */
int
-print_textpad(struct bsddialog_conf *conf, WINDOW *pad, int *rows, int cols,
- char *text);
+set_widget_position(struct bsddialog_conf *conf, int *y, int *x, int h, int w);
+/* widget builders */
enum elevation { RAISED, LOWERED };
void
@@ -123,17 +113,17 @@ new_boxed_window(struct bsddialog_conf *conf, int y, int x, int rows, int cols,
enum elevation elev);
int
-new_widget_withtextpad(struct bsddialog_conf *conf, WINDOW **shadow,
- WINDOW **widget, int y, int x, int h, int w, enum elevation elev,
- WINDOW **textpad, int *htextpad, char *text, bool buttons);
+new_dialog(struct bsddialog_conf *conf, WINDOW **shadow, WINDOW **widget, int y,
+ int x, int h, int w, WINDOW **textpad, const char *text, struct buttons *bs,
+ bool shortcutbuttons);
int
-update_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *shadow,
- WINDOW *widget, int h, int w, enum elevation elev, WINDOW *textpad,
- int *htextpad, char *text, bool buttons);
+update_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
+ int y, int x, int h, int w, WINDOW *textpad, const char *text,
+ struct buttons *bs, bool shortcutbuttons);
void
-end_widget_withtextpad(struct bsddialog_conf *conf, WINDOW *window, int h, int w,
- WINDOW *textpad, WINDOW *shadow);
+end_dialog(struct bsddialog_conf *conf, WINDOW *shadow, WINDOW *widget,
+ WINDOW *textpad);
-#endif
+#endif \ No newline at end of file
diff --git a/lib/libbsddialog.c b/lib/libbsddialog.c
index aea3b152adfd..65134eabe5f3 100644
--- a/lib/libbsddialog.c
+++ b/lib/libbsddialog.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,43 +25,26 @@
* SUCH DAMAGE.
*/
-#ifdef PORTNCURSES
-#include <ncurses/ncurses.h>
-#else
-#include <ncurses.h>
-#endif
+#include <curses.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "bsddialog.h"
-#include "lib_util.h"
#include "bsddialog_theme.h"
-
-/*
- * This file implements public functions not related to a specific dialog.
- * lib_utils.h/c: private functions to implement the library.
- * theme.h/c: public API related to themes.
- * Dialogs implementation:
- * infobox.c infobox
- * messgebox.c msgbox - yesno
- * menubox.c buildlist - checklist - menu - mixedlist - radiolist
- * formbox.c inputbox - passwordbox - form - passwordform - mixedform
- * barbox.c gauge - mixedgauge - rangebox - pause - progressview
- * textbox.c textbox
- * timebox.c timebox - calendar
- */
+#include "lib_util.h"
extern struct bsddialog_theme t;
int bsddialog_init(void)
{
int i, j, c, error;
+ enum bsddialog_default_theme theme;
set_error_string("");
- if(initscr() == NULL)
- RETURN_ERROR("Cannot init ncurses (initscr)");
+ if (initscr() == NULL)
+ RETURN_ERROR("Cannot init curses (initscr)");
error = OK;
error += keypad(stdscr, TRUE);
@@ -69,24 +52,25 @@ int bsddialog_init(void)
error += cbreak();
error += noecho();
curs_set(0);
- if(error != OK) {
+ if (error != OK) {
bsddialog_end();
- RETURN_ERROR("Cannot init ncurses (keypad and cursor)");
+ RETURN_ERROR("Cannot init curses (keypad and cursor)");
}
c = 1;
error += start_color();
- for (i=0; i<8; i++)
- for(j=0; j<8; j++) {
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++) {
error += init_pair(c, i, j);
c++;
}
- if(error != OK) {
- bsddialog_end();
- RETURN_ERROR("Cannot init ncurses (colors)");
- }
- if (bsddialog_set_default_theme(BSDDIALOG_THEME_DEFAULT) != 0) {
+ if (error == OK)
+ theme = BSDDIALOG_THEME_DEFAULT;
+ else
+ theme = BSDDIALOG_THEME_BLACKWHITE;
+
+ if (bsddialog_set_default_theme(theme) != 0) {
bsddialog_end();
return (BSDDIALOG_ERROR);
}
@@ -97,16 +81,17 @@ int bsddialog_init(void)
int bsddialog_end(void)
{
if (endwin() != OK)
- RETURN_ERROR("Cannot end ncurses (endwin)");
+ RETURN_ERROR("Cannot end curses (endwin)");
return (BSDDIALOG_OK);
}
-int bsddialog_backtitle(struct bsddialog_conf *conf, char *backtitle)
+int bsddialog_backtitle(struct bsddialog_conf *conf, const char *backtitle)
{
mvaddstr(0, 1, backtitle);
if (conf->no_lines != true)
- mvhline(1, 1, conf->ascii_lines ? '-' : ACS_HLINE, COLS-2);
+ mvhline(1, 1, conf->ascii_lines ? '-' : ACS_HLINE,
+ SCREENCOLS - 2);
refresh();
@@ -140,4 +125,4 @@ int bsddialog_clearterminal(void)
refresh();
return (BSDDIALOG_OK);
-}
+} \ No newline at end of file
diff --git a/lib/menubox.c b/lib/menubox.c
index c9fb182422ea..0d8e3b14521c 100644
--- a/lib/menubox.c
+++ b/lib/menubox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,19 +28,13 @@
#include <sys/param.h>
#include <ctype.h>
-#ifdef PORTNCURSES
-#include <ncurses/ncurses.h>
-#else
-#include <ncurses.h>
-#endif
+#include <curses.h>
+#include <stdlib.h>
#include <string.h>
-
#include "bsddialog.h"
-#include "lib_util.h"
#include "bsddialog_theme.h"
-
-/* "Menu": checklist - menu - mixedlist - radiolist - buildlist */
+#include "lib_util.h"
#define DEPTHSPACE 4
#define MIN_HEIGHT VBORDERS + 6 /* 2 buttons 1 text 3 menu */
@@ -48,7 +42,6 @@
extern struct bsddialog_theme t;
enum menumode {
- BUILDLISTMODE,
CHECKLISTMODE,
MENUMODE,
MIXEDLISTMODE,
@@ -69,267 +62,152 @@ struct lineposition {
unsigned int line;
};
-static int checkradiolist(int nitems, struct bsddialog_menuitem *items)
-{
- int i, error;
-
- error = 0;
- for (i=0; i<nitems; i++) {
- if (error > 0)
- items[i].on = false;
-
- if (items[i].on == true)
- error++;
- }
-
- return (error == 0 ? 0 : -1);
-}
-
-static int checkmenu(int nitems, struct bsddialog_menuitem *items) // useful?
-{
- int i, error;
-
- error = 0;
- for (i=0; i<nitems; i++) {
- if (items[i].on == true)
- error++;
-
- items[i].on = false;
- }
-
- return (error == 0 ? 0 : -1);
-}
+struct privateitem {
+ bool on;
+ int group;
+ int index;
+ enum menumode type;
+ struct bsddialog_menuitem *item;
+};
static void
-getfirst(int ngroups, struct bsddialog_menugroup *groups, int *abs, int *group,
- int *rel)
+set_on_output(struct bsddialog_conf *conf, int output, int ngroups,
+ struct bsddialog_menugroup *groups, struct privateitem *pritems)
{
- int i, a;
+ int i, j, abs;
+
+ if (output != BSDDIALOG_OK && !conf->menu.on_without_ok)
+ return;
- *abs = *rel = *group = -1;
- a = 0;
- for (i=0; i<ngroups; i++) {
+ for(i = abs = 0; i < ngroups; i++) {
if (groups[i].type == BSDDIALOG_SEPARATOR) {
- a += groups[i].nitems;
+ abs += groups[i].nitems;
continue;
}
- if (groups[i].nitems != 0) {
- *group = i;
- *abs = a;
- *rel = 0;
- break;
+
+ for(j = 0; j < (int)groups[i].nitems; j++) {
+ groups[i].items[j].on = pritems[abs].on;
+ abs++;
}
}
}
-static void
-getfirst_with_default(struct bsddialog_conf *conf, int ngroups,
- struct bsddialog_menugroup *groups, int *abs, int *group, int *rel)
+static int getprev(struct privateitem *pritems, int abs)
{
- int i, j, a;
- struct bsddialog_menuitem *item;
-
- getfirst(ngroups, groups, abs, group, rel);
- if (*abs < 0)
- return;
-
- a = *abs;
+ int i;
- for (i=*group; i<ngroups; i++) {
- if (groups[i].type == BSDDIALOG_SEPARATOR) {
- a += groups[i].nitems;
+ for (i = abs - 1; i >= 0; i--) {
+ if (pritems[i].type == SEPARATORMODE)
continue;
- }
- for (j = 0; j < (int) groups[i].nitems; j++) {
- item = &groups[i].items[j];
- if (conf->menu.default_item != NULL && item->name != NULL) {
- if (strcmp(item->name, conf->menu.default_item) == 0) {
- *abs = a;
- *group = i;
- *rel = j;
- return;
- }
- }
- a++;
- }
+ return (i);
}
+
+ return (abs);
}
-static void
-getlast(int totnitems, int ngroups, struct bsddialog_menugroup *groups,
- int *abs, int *group, int *rel)
+static int getnext(int npritems, struct privateitem *pritems, int abs)
{
- int i, a;
+ int i;
- a = totnitems - 1;
- for (i = ngroups-1; i>=0; i--) {
- if (groups[i].type == BSDDIALOG_SEPARATOR) {
- a -= groups[i].nitems;
+ for (i = abs + 1; i < npritems; i++) {
+ if (pritems[i].type == SEPARATORMODE)
continue;
- }
- if (groups[i].nitems != 0) {
- *group = i;
- *abs = a;
- *rel = groups[i].nitems - 1;
- break;
- }
+ return (i);
}
+
+ return (abs);
}
-static void
-getnext(int ngroups, struct bsddialog_menugroup *groups, int *abs, int *group,
- int *rel)
+static int
+getfirst_with_default(int npritems, struct privateitem *pritems, int ngroups,
+ struct bsddialog_menugroup *groups, int *focusgroup, int *focusitem)
{
- int i, a;
-
- if (*abs < 0 || *group < 0 || *rel < 0)
- return;
-
- if (*rel + 1 < (int) groups[*group].nitems) {
- *rel = *rel + 1;
- *abs = *abs + 1;
- return;
+ int i, abs;
+
+ if ((abs = getnext(npritems, pritems, -1)) < 0)
+ return (abs);
+
+ if (focusgroup == NULL || focusitem == NULL)
+ return (abs);
+ if (*focusgroup < 0 || *focusgroup >= ngroups)
+ return (abs);
+ if (groups[*focusgroup].type == BSDDIALOG_SEPARATOR)
+ return (abs);
+ if (*focusitem < 0 || *focusitem >= (int)groups[*focusgroup].nitems)
+ return (abs);
+
+ for (i = abs; i < npritems; i++) {
+ if (pritems[i].group == *focusgroup &&
+ pritems[i].index == *focusitem)
+ return (i);
}
- if (*group + 1 > ngroups)
- return;
-
- a = *abs;
- for (i = *group + 1; i < ngroups; i++) {
- if (groups[i].type == BSDDIALOG_SEPARATOR) {
- a += groups[i].nitems;
- continue;
- }
- if (groups[i].nitems != 0) {
- *group = i;
- *abs = a + 1;
- *rel = 0;
- break;
- }
- }
+ return (abs);
}
-static void
-getfastnext(int menurows, int ngroups, struct bsddialog_menugroup *groups,
- int *abs, int *group, int *rel)
+static int
+getfastnext(int menurows, int npritems, struct privateitem *pritems, int abs)
{
int a, start, i;
- start = *abs;
+ start = abs;
i = menurows;
do {
- a = *abs;
- getnext(ngroups, groups, abs, group, rel);
+ a = abs;
+ abs = getnext(npritems, pritems, abs);
i--;
- } while (*abs != a && *abs < start + menurows && i > 0);
-}
-
-static void
-getprev(struct bsddialog_menugroup *groups, int *abs, int *group, int *rel)
-{
- int i, a;
-
- if (*abs < 0 || *group < 0 || *rel < 0)
- return;
-
- if (*rel > 0) {
- *rel = *rel - 1;
- *abs = *abs - 1;
- return;
- }
-
- if (*group - 1 < 0)
- return;
+ } while (abs != a && abs < start + menurows && i > 0);
- a = *abs;
- for (i = *group - 1; i >= 0; i--) {
- if (groups[i].type == BSDDIALOG_SEPARATOR) {
- a -= (int) groups[i].nitems;
- continue;
- }
- if (groups[i].nitems != 0) {
- *group = i;
- *abs = a - 1;
- *rel = (int) groups[i].nitems - 1;
- break;
- }
- }
+ return (abs);
}
-static void
-getfastprev(int menurows, struct bsddialog_menugroup *groups, int *abs,
- int *group, int *rel)
+static int
+getfastprev(int menurows, struct privateitem *pritems, int abs)
{
int a, start, i;
- start = *abs;
+ start = abs;
i = menurows;
do {
- a = *abs;
- getprev(groups, abs, group, rel);
+ a = abs;
+ abs = getprev(pritems, abs);
i--;
- } while (*abs != a && *abs > start - menurows && i > 0);
+ } while (abs != a && abs > start - menurows && i > 0);
+
+ return (abs);
}
-static bool
-getnextshortcut(struct bsddialog_conf *conf, enum menumode mode, int ngroups,
- struct bsddialog_menugroup *groups, int *abs, int *group, int *rel,
- int key)
+static int
+getnextshortcut(struct bsddialog_conf *conf, int npritems,
+ struct privateitem *pritems, int abs, int key)
{
- int i, j, a, ch, ng, nr, na;
- bool mainloop;
-
- if (*abs < 0 || ngroups < 0 || *rel < 0 || mode == BUILDLISTMODE)
- return false;
+ int i, ch, next;
- na = a = -1;
- mainloop = true;
- for (i = 0; i < ngroups && mainloop; i++) {
- if (groups[i].type == BSDDIALOG_SEPARATOR) {
- a += groups[i].nitems;
+ next = -1;
+ for (i = 0; i < npritems; i++) {
+ if (pritems[i].type == SEPARATORMODE)
continue;
- }
- for (j = 0; j < (int)groups[i].nitems; j++) {
- a++;
- if (a == *abs)
- continue;
- if (conf->menu.no_name)
- ch = groups[i].items[j].desc[0];
- else
- ch = groups[i].items[j].name[0];
-
- if (ch == key) {
- if (a < *abs && na == -1) {
- na = a;
- ng = i;
- nr = j;
- }
- if (a > *abs) {
- na = a;
- ng = i;
- nr = j;
- mainloop = false;
- break;
- }
- }
- }
- }
+ if (conf->menu.no_name)
+ ch = pritems[i].item->desc[0];
+ else
+ ch = pritems[i].item->name[0];
+
+ if (ch == key) {
+ if (i > abs)
+ return (i);
- if (na != -1) {
- *abs = na;
- *group = ng;
- *rel = nr;
- return (true);
+ if (i < abs && next == -1)
+ next = i;
+ }
}
- return (false);
+ return (next != -1 ? next : abs);
}
static enum menumode
getmode(enum menumode mode, struct bsddialog_menugroup group)
{
-
if (mode == MIXEDLISTMODE) {
if (group.type == BSDDIALOG_SEPARATOR)
mode = SEPARATORMODE;
@@ -339,16 +217,25 @@ getmode(enum menumode mode, struct bsddialog_menugroup group)
mode = CHECKLISTMODE;
}
- return mode;
+ return (mode);
}
static void
drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
- struct bsddialog_menuitem item, enum menumode mode, struct lineposition pos,
- bool curr)
+ struct lineposition pos, struct privateitem *pritem, bool focus)
{
int colordesc, colorname, colorshortcut, linech;
- char *shortcut;
+ unsigned int depth;
+ enum menumode mode;
+ const char *prefix, *name, *desc, *bottomdesc, *shortcut;
+
+ prefix = pritem->item->prefix;
+ name = pritem->item->name;
+ depth = pritem->item->depth;
+ desc = pritem->item->desc;
+ bottomdesc = pritem->item->bottomdesc;
+
+ mode = pritem->type;
if (mode == SEPARATORMODE) {
if (conf->no_lines == false) {
@@ -357,140 +244,132 @@ drawitem(struct bsddialog_conf *conf, WINDOW *pad, int y,
mvwhline(pad, y, 0, linech, pos.line);
wattroff(pad, t.menu.desccolor);
}
- wmove(pad, y, pos.line/2 - (strlen(item.name)+strlen(item.desc))/2);
+ wmove(pad, y,
+ pos.line/2 - (strlen(name) + strlen(desc)) / 2 );
wattron(pad, t.menu.namesepcolor);
- waddstr(pad, item.name);
+ waddstr(pad, name);
wattroff(pad, t.menu.namesepcolor);
- if (strlen(item.name) > 0 && strlen(item.desc) > 0)
+ if (strlen(name) > 0 && strlen(desc) > 0)
waddch(pad, ' ');
wattron(pad, t.menu.descsepcolor);
- waddstr(pad, item.desc);
+ waddstr(pad, desc);
wattroff(pad, t.menu.descsepcolor);
return;
}
/* prefix */
- if (item.prefix != NULL && item.prefix[0] != '\0')
- mvwaddstr(pad, y, 0, item.prefix);
+ if (prefix != NULL && prefix[0] != '\0')
+ mvwaddstr(pad, y, 0, prefix);
/* selector */
wmove(pad, y, pos.xselector);
wattron(pad, t.menu.selectorcolor);
if (mode == CHECKLISTMODE)
- wprintw(pad, "[%c]", item.on ? 'X' : ' ');
+ wprintw(pad, "[%c]", pritem->on ? 'X' : ' ');
if (mode == RADIOLISTMODE)
- wprintw(pad, "(%c)", item.on ? '*' : ' ');
+ wprintw(pad, "(%c)", pritem->on ? '*' : ' ');
wattroff(pad, t.menu.selectorcolor);
/* name */
- colorname = curr ? t.menu.f_namecolor : t.menu.namecolor;
- if (mode != BUILDLISTMODE && conf->menu.no_name == false) {
+ colorname = focus ? t.menu.f_namecolor : t.menu.namecolor;
+ if (conf->menu.no_name == false) {
wattron(pad, colorname);
- mvwaddstr(pad, y, pos.xname + item.depth * DEPTHSPACE, item.name);
+ mvwaddstr(pad, y, pos.xname + depth * DEPTHSPACE, name);
wattroff(pad, colorname);
}
/* description */
- if (mode == BUILDLISTMODE) {
- if (curr == false)
- colordesc = item.on ? t.menu.namecolor : t.menu.desccolor;
- else
- colordesc = t.menu.f_namecolor;
- }
- else {
- if (conf->menu.no_name)
- colordesc = curr ? t.menu.f_namecolor : t.menu.namecolor;
- else
- colordesc = curr ? t.menu.f_desccolor : t.menu.desccolor;
- }
- if (mode == BUILDLISTMODE || conf->menu.no_desc == false) {
+ if (conf->menu.no_name)
+ colordesc = focus ? t.menu.f_namecolor : t.menu.namecolor;
+ else
+ colordesc = focus ? t.menu.f_desccolor : t.menu.desccolor;
+
+ if (conf->menu.no_desc == false) {
wattron(pad, colordesc);
if (conf->menu.no_name)
- mvwaddstr(pad, y, pos.xname + item.depth * DEPTHSPACE, item.desc);
+ mvwaddstr(pad, y, pos.xname + depth * DEPTHSPACE, desc);
else
- mvwaddstr(pad, y, pos.xdesc, item.desc);
+ mvwaddstr(pad, y, pos.xdesc, desc);
wattroff(pad, colordesc);
}
/* shortcut */
- if (mode != BUILDLISTMODE && conf->menu.shortcut_buttons == false) {
- colorshortcut = curr ? t.menu.f_shortcutcolor : t.menu.shortcutcolor;
+ if (conf->menu.shortcut_buttons == false) {
+ colorshortcut = focus ?
+ t.menu.f_shortcutcolor : t.menu.shortcutcolor;
wattron(pad, colorshortcut);
if (conf->menu.no_name)
- shortcut = item.desc;
+ shortcut = desc;
else
- shortcut = item.name;
- wmove(pad, y, pos.xname + item.depth * DEPTHSPACE);
+ shortcut = name;
+ wmove(pad, y, pos.xname + depth * DEPTHSPACE);
if (shortcut != NULL && shortcut[0] != '\0')
waddch(pad, shortcut[0]);
wattroff(pad, colorshortcut);
-}
+ }
/* bottom description */
- move(LINES-1, 2);
+ move(SCREENLINES - 1, 2);
clrtoeol();
- if (item.bottomdesc != NULL) {
- addstr(item.bottomdesc);
+ if (bottomdesc != NULL && focus) {
+ addstr(bottomdesc);
refresh();
}
}
-static void
+static int
menu_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
- char *text, int linelen, unsigned int *menurows, int nitems,
+ const char *text, int linelen, unsigned int *menurows, int nitems,
struct buttons bs)
{
- int textrow, menusize;
-
- textrow = text != NULL && strlen(text) > 0 ? 1 : 0;
-
- if (cols == BSDDIALOG_AUTOSIZE) {
- *w = VBORDERS;
- /* buttons size */
- *w += bs.nbuttons * bs.sizebutton;
- *w += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0;
- /* line size */
- *w = MAX(*w, linelen + 6);
- /* conf.auto_minwidth */
- *w = MAX(*w, (int)conf->auto_minwidth);
- /*
- * avoid terminal overflow,
- * -1 fix false negative with big menu over the terminal and
- * autosize, for example "portconfig /usr/ports/www/apache24/".
- */
- *w = MIN(*w, widget_max_width(conf)-1);
+ int htext, wtext, menusize, notext;
+
+ notext = 2;
+ if (*menurows == BSDDIALOG_AUTOSIZE) {
+ /* algo 1): grows vertically */
+ /* notext = 1; */
+ /* algo 2): grows horizontally, better with little terminals */
+ notext += nitems;
+ notext = MIN(notext, widget_max_height(conf) - HBORDERS - 3);
+ } else
+ notext += *menurows;
+
+ if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
+ if (text_size(conf, rows, cols, text, &bs, notext, linelen + 6,
+ &htext, &wtext) != 0)
+ return (BSDDIALOG_ERROR);
}
- if (rows == BSDDIALOG_AUTOSIZE) {
- *h = HBORDERS + 2 /* buttons */ + textrow;
+ if (cols == BSDDIALOG_AUTOSIZE)
+ *w = widget_min_width(conf, wtext, linelen + 6, &bs);
+ if (rows == BSDDIALOG_AUTOSIZE) {
if (*menurows == 0) {
- *h += nitems + 2;
- *h = MIN(*h, widget_max_height(conf));
- menusize = MIN(nitems + 2, *h - (HBORDERS + 2 + textrow));
- menusize -=2;
- *menurows = menusize < 0 ? 0 : menusize;
+ menusize = widget_max_height(conf) - HBORDERS -
+ 2 /*buttons*/ - htext;
+ menusize = MIN(menusize, nitems + 2);
+ *menurows = menusize - 2 < 0 ? 0 : menusize - 2;
}
- else /* h autosize with a fixed menurows */
- *h = *h + *menurows + 2;
-
- /* conf.auto_minheight */
- *h = MAX(*h, (int)conf->auto_minheight);
- /* avoid terminal overflow */
- *h = MIN(*h, widget_max_height(conf));
- /* avoid menurows overflow */
- /* manual: with rows=autosize menurows!=0 is maxmenurows */
- *menurows = MIN(*h - 6 - textrow, (int)*menurows);
- }
- else {
+ else /* h autosize with fixed menurows */
+ menusize = *menurows + 2;
+
+ *h = widget_min_height(conf, htext, menusize, true);
+ /*
+ * avoid menurows overflow and
+ * with rows=AUTOSIZE menurows!=0 becomes max-menurows
+ */
+ *menurows = MIN(*h - 6 - htext, (int)*menurows);
+ } else {
if (*menurows == 0)
- *menurows = MIN(rows-6-textrow, nitems);
+ *menurows = MIN(rows-6-htext, nitems);
}
+
+ return (0);
}
static int
-menu_checksize(int rows, int cols, char *text, int menurows, int nitems,
+menu_checksize(int rows, int cols, const char *text, int menurows, int nitems,
struct buttons bs)
{
int mincols, textrow, menusize;
@@ -499,24 +378,27 @@ menu_checksize(int rows, int cols, char *text, int menurows, int nitems,
/* buttons */
mincols += bs.nbuttons * bs.sizebutton;
mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0;
- /* line, comment to permet some cols hidden */
+ /*
+ * linelen check, comment to allow some hidden col otherwise portconfig
+ * could not show big menus like www/apache24
+ */
/* mincols = MAX(mincols, linelen); */
if (cols < mincols)
- RETURN_ERROR("Few cols, width < size buttons or "\
- "name+descripion of the items");
+ RETURN_ERROR("Few cols, width < size buttons or "
+ "name + descripion of the items");
textrow = text != NULL && strlen(text) > 0 ? 1 : 0;
if (nitems > 0 && menurows == 0)
- RETURN_ERROR("items > 0 but menurows == 0, probably terminal "\
+ RETURN_ERROR("items > 0 but menurows == 0, probably terminal "
"too small");
menusize = nitems > 0 ? 3 : 0;
if (rows < 2 + 2 + menusize + textrow)
RETURN_ERROR("Few lines for this menus");
- return 0;
+ return (0);
}
/* the caller has to call prefresh(menupad, ymenupad, 0, ys, xs, ye, xe); */
@@ -524,7 +406,6 @@ static void
update_menuwin(struct bsddialog_conf *conf, WINDOW *menuwin, int h, int w,
int totnitems, unsigned int menurows, int ymenupad)
{
-
draw_borders(conf, menuwin, h, w, LOWERED);
if (totnitems > (int) menurows) {
@@ -544,36 +425,30 @@ update_menuwin(struct bsddialog_conf *conf, WINDOW *menuwin, int h, int w,
}
static int
-do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, enum menumode mode, int ngroups,
+do_mixedlist(struct bsddialog_conf *conf, const char *text, int rows, int cols,
+ unsigned int menurows, enum menumode mode, unsigned int ngroups,
struct bsddialog_menugroup *groups, int *focuslist, int *focusitem)
{
+ bool loop, onetrue, movefocus, automenurows, shortcut_butts;
+ int i, j, y, x, h, w, output, input;
+ int ymenupad, ys, ye, xs, xe, abs, next, totnitems;
WINDOW *shadow, *widget, *textpad, *menuwin, *menupad;
- int i, j, y, x, h, w, htextpad, output, input;
- int ymenupad, ys, ye, xs, xe, abs, g, rel, totnitems;
- bool loop, automenurows, shortcut_buttons;
struct buttons bs;
- struct bsddialog_menuitem *item;
- enum menumode currmode;
struct lineposition pos = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ struct bsddialog_menuitem *item;
+ struct privateitem *pritems;
- shortcut_buttons = conf->menu.shortcut_buttons;
+ shortcut_butts = conf->menu.shortcut_buttons;
automenurows = menurows == BSDDIALOG_AUTOSIZE ? true : false;
totnitems = 0;
- for (i=0; i < ngroups; i++) {
- currmode = getmode(mode, groups[i]);
- if (currmode == RADIOLISTMODE)
- checkradiolist(groups[i].nitems, groups[i].items);
-
- if (currmode == MENUMODE)
- checkmenu(groups[i].nitems, groups[i].items);
-
- if (currmode == RADIOLISTMODE || currmode == CHECKLISTMODE)
+ for (i = 0; i < (int)ngroups; i++) {
+ if (getmode(mode, groups[i]) == RADIOLISTMODE ||
+ getmode(mode, groups[i]) == CHECKLISTMODE)
pos.selectorlen = 3;
- for (j=0; j < (int) groups[i].nitems; j++) {
+ for (j = 0; j < (int)groups[i].nitems; j++) {
totnitems++;
item = &groups[i].items[j];
@@ -583,7 +458,7 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
continue;
}
- pos.maxprefix = MAX(pos.maxprefix, strlen(item->prefix));
+ pos.maxprefix = MAX(pos.maxprefix,strlen(item->prefix));
pos.maxdepth = MAX(pos.maxdepth, item->depth);
pos.maxname = MAX(pos.maxname, strlen(item->name));
pos.maxdesc = MAX(pos.maxdesc, strlen(item->desc));
@@ -594,30 +469,33 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
pos.maxdepth *= DEPTHSPACE;
pos.xselector = pos.maxprefix + (pos.maxprefix != 0 ? 1 : 0);
- pos.xname = pos.xselector + pos.selectorlen + (pos.selectorlen > 0 ? 1 : 0);
+ pos.xname = pos.xselector + pos.selectorlen +
+ (pos.selectorlen > 0 ? 1 : 0);
pos.xdesc = pos.maxdepth + pos.xname + pos.maxname;
pos.xdesc += (pos.maxname != 0 ? 1 : 0);
pos.line = MAX(pos.maxsepstr + 3, pos.xdesc + pos.maxdesc);
- get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
- BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
+ get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
- menu_autosize(conf, rows, cols, &h, &w, text, pos.line, &menurows,
- totnitems, bs);
+ return (BSDDIALOG_ERROR);
+ if (menu_autosize(conf, rows, cols, &h, &w, text, pos.line, &menurows,
+ totnitems, bs) != 0)
+ return (BSDDIALOG_ERROR);
if (menu_checksize(h, w, text, menurows, totnitems, bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
+
+ if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
+ shortcut_butts) != 0)
+ return (BSDDIALOG_ERROR);
- if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
- &textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
+ doupdate();
- prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin,
- y + h - menurows, x + 1 + w - t.text.hmargin);
+ prefresh(textpad, 0, 0, y + 1, x + 1 + TEXTHMARGIN,
+ y + h - menurows, x + 1 + w - TEXTHMARGIN);
menuwin = new_boxed_window(conf, y + h - 5 - menurows, x + 2,
menurows+2, w-4, LOWERED);
@@ -625,138 +503,143 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
menupad = newpad(totnitems, pos.line);
wbkgd(menupad, t.dialog.color);
- ymenupad = 0;
- for (i=0; i<ngroups; i++) {
- currmode = getmode(mode, groups[i]);
- for (j=0; j < (int) groups[i].nitems; j++) {
+ if ((pritems = calloc(totnitems, sizeof (struct privateitem))) == NULL)
+ RETURN_ERROR("Cannot allocate memory for internal menu items");
+
+ abs = 0;
+ for (i = 0; i < (int)ngroups; i++) {
+ onetrue = false;
+ for (j = 0; j < (int)groups[i].nitems; j++) {
item = &groups[i].items[j];
- drawitem(conf, menupad, ymenupad, *item, currmode, pos,
- false);
- ymenupad++;
+
+ if (getmode(mode, groups[i]) == MENUMODE) {
+ pritems[abs].on = false;
+ } else if (getmode(mode, groups[i]) == RADIOLISTMODE) {
+ pritems[abs].on = onetrue ? false : item->on;
+ if (pritems[abs].on)
+ onetrue = true;
+ } else {
+ pritems[abs].on = item->on;
+ }
+ pritems[abs].group = i;
+ pritems[abs].index = j;
+ pritems[abs].type = getmode(mode, groups[i]);
+ pritems[abs].item = item;
+
+ drawitem(conf, menupad, abs, pos, &pritems[abs], false);
+ abs++;
}
}
- getfirst_with_default(conf, ngroups, groups, &abs, &g, &rel);
- currmode = getmode(mode, groups[g]);
- item = &groups[g].items[rel];
- drawitem(conf, menupad, abs, *item, currmode, pos, true);
+ abs = getfirst_with_default(totnitems, pritems, ngroups, groups,
+ focuslist, focusitem);
+ if (abs >= 0)
+ drawitem(conf, menupad, abs, pos, &pritems[abs], true);
ys = y + h - 5 - menurows + 1;
ye = y + h - 5 ;
if (conf->menu.align_left || (int)pos.line > w - 6) {
xs = x + 3;
xe = xs + w - 7;
- }
- else { /* center */
+ } else { /* center */
xs = x + 3 + (w-6)/2 - pos.line/2;
xe = xs + w - 5;
}
- ymenupad = 0; /* now ymenupad is pminrow for prefresh() */
+ ymenupad = 0;
if ((int)(ymenupad + menurows) - 1 < abs)
ymenupad = abs - menurows + 1;
- update_menuwin(conf, menuwin, menurows+2, w-4, totnitems, menurows, ymenupad);
+ update_menuwin(conf, menuwin, menurows+2, w-4, totnitems, menurows,
+ ymenupad);
wrefresh(menuwin);
prefresh(menupad, ymenupad, 0, ys, xs, ye, xe);
-
- draw_buttons(widget, h-2, w, bs, shortcut_buttons);
- wrefresh(widget);
+ movefocus = false;
loop = true;
- while(loop) {
+ while (loop) {
input = getch();
switch(input) {
case KEY_ENTER:
case 10: /* Enter */
output = bs.value[bs.curr];
- if (currmode == MENUMODE)
- item->on = true;
+ if (abs >= 0 && pritems[abs].type == MENUMODE)
+ pritems[abs].on = true;
+ set_on_output(conf, output, ngroups, groups, pritems);
loop = false;
break;
case 27: /* Esc */
- output = BSDDIALOG_ESC;
- loop = false;
+ if (conf->key.enable_esc) {
+ output = BSDDIALOG_ESC;
+ if (abs >= 0 && pritems[abs].type == MENUMODE)
+ pritems[abs].on = true;
+ set_on_output(conf, output, ngroups, groups,
+ pritems);
+ loop = false;
+ }
break;
case '\t': /* TAB */
bs.curr = (bs.curr + 1) % bs.nbuttons;
- draw_buttons(widget, h-2, w, bs, shortcut_buttons);
+ draw_buttons(widget, bs, shortcut_butts);
wrefresh(widget);
break;
case KEY_LEFT:
if (bs.curr > 0) {
bs.curr--;
- draw_buttons(widget, h-2, w, bs, shortcut_buttons);
+ draw_buttons(widget, bs, shortcut_butts);
wrefresh(widget);
}
break;
case KEY_RIGHT:
if (bs.curr < (int) bs.nbuttons - 1) {
bs.curr++;
- draw_buttons(widget, h-2, w, bs, shortcut_buttons);
+ draw_buttons(widget, bs, shortcut_butts);
wrefresh(widget);
}
break;
- case KEY_CTRL('E'): /* add conf->menu.extrahelpkey ? */
case KEY_F(1):
if (conf->f1_file == NULL && conf->f1_message == NULL)
break;
if (f1help(conf) != 0)
- return BSDDIALOG_ERROR;
- /* No break! the terminal size can change */
+ return (BSDDIALOG_ERROR);
+ /* No break, screen size can change */
case KEY_RESIZE:
- hide_widget(y, x, h, w,conf->shadow);
-
- /*
- * Unnecessary, but, when the columns decrease the
- * following "refresh" seem not work
- */
+ /* Important for decreasing screen */
+ hide_widget(y, x, h, w, conf->shadow);
refresh();
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
menurows = automenurows ? 0 : menurows;
- menu_autosize(conf, rows, cols, &h, &w, text, pos.line,
- &menurows, totnitems, bs);
- if (menu_checksize(h, w, text, menurows, totnitems, bs) != 0)
- return BSDDIALOG_ERROR;
+ if (menu_autosize(conf, rows, cols, &h, &w, text,
+ pos.line, &menurows, totnitems, bs) != 0)
+ return (BSDDIALOG_ERROR);
+ if (menu_checksize(h, w, text, menurows, totnitems,
+ bs) != 0)
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
-
- wclear(shadow);
- mvwin(shadow, y + t.shadow.h, x + t.shadow.w);
- wresize(shadow, h, w);
-
- wclear(widget);
- mvwin(widget, y, x);
- wresize(widget, h, w);
+ return (BSDDIALOG_ERROR);
- htextpad = 1;
- wclear(textpad);
- wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2);
+ if (update_dialog(conf, shadow, widget, y, x, h, w,
+ textpad, text, &bs, shortcut_butts) != 0)
+ return (BSDDIALOG_ERROR);
- if(update_widget_withtextpad(conf, shadow, widget, h, w,
- RAISED, textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
-
- draw_buttons(widget, h-2, w, bs, shortcut_buttons);
- wrefresh(widget);
+ doupdate();
- prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin,
- y + h - menurows, x + 1 + w - t.text.hmargin);
+ prefresh(textpad, 0, 0, y + 1, x + 1 + TEXTHMARGIN,
+ y + h - menurows, x + 1 + w - TEXTHMARGIN);
wclear(menuwin);
mvwin(menuwin, y + h - 5 - menurows, x + 2);
wresize(menuwin,menurows+2, w-4);
- update_menuwin(conf, menuwin, menurows+2, w-4, totnitems,
- menurows, ymenupad);
+ update_menuwin(conf, menuwin, menurows+2, w-4,
+ totnitems, menurows, ymenupad);
wrefresh(menuwin);
-
+
ys = y + h - 5 - menurows + 1;
ye = y + h - 5 ;
if (conf->menu.align_left || (int)pos.line > w - 6) {
xs = x + 3;
xe = xs + w - 7;
- }
- else { /* center */
+ } else { /* center */
xs = x + 3 + (w-6)/2 - pos.line/2;
xe = xs + w - 5;
}
@@ -774,385 +657,153 @@ do_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
continue;
switch(input) {
case KEY_HOME:
+ next = getnext(totnitems, pritems, -1);
+ movefocus = next != abs;
+ break;
case KEY_UP:
+ next = getprev(pritems, abs);
+ movefocus = next != abs;
+ break;
case KEY_PPAGE:
- if (abs == 0) /* useless, just to save cpu refresh */
- break;
- drawitem(conf, menupad, abs, *item, currmode, pos, false);
- if (input == KEY_HOME)
- getfirst(ngroups, groups, &abs, &g, &rel);
- else if (input == KEY_UP)
- getprev(groups, &abs, &g, &rel);
- else /* input == KEY_PPAGE*/
- getfastprev(menurows, groups, &abs, &g, &rel);
- item = &groups[g].items[rel];
- currmode= getmode(mode, groups[g]);
- drawitem(conf, menupad, abs, *item, currmode, pos, true);
- if (ymenupad > abs && ymenupad > 0)
- ymenupad = abs;
- update_menuwin(conf, menuwin, menurows+2, w-4, totnitems,
- menurows, ymenupad);
- wrefresh(menuwin);
- prefresh(menupad, ymenupad, 0, ys, xs, ye, xe);
+ next = getfastprev(menurows, pritems, abs);
+ movefocus = next != abs;
break;
case KEY_END:
+ next = getprev(pritems, totnitems);
+ movefocus = next != abs;
+ break;
case KEY_DOWN:
+ next = getnext(totnitems, pritems, abs);
+ movefocus = next != abs;
+ break;
case KEY_NPAGE:
- if (abs == totnitems -1)
- break; /* useless, just to save cpu refresh */
- drawitem(conf, menupad, abs, *item, currmode, pos, false);
- if (input == KEY_END)
- getlast(totnitems, ngroups, groups, &abs, &g, &rel);
- else if (input == KEY_DOWN)
- getnext(ngroups, groups, &abs, &g, &rel);
- else /* input == KEY_NPAGE*/
- getfastnext(menurows, ngroups, groups, &abs, &g, &rel);
- item = &groups[g].items[rel];
- currmode= getmode(mode, groups[g]);
- drawitem(conf, menupad, abs, *item, currmode, pos, true);
- if ((int)(ymenupad + menurows) <= abs)
- ymenupad = abs - menurows + 1;
- update_menuwin(conf, menuwin, menurows+2, w-4, totnitems,
- menurows, ymenupad);
- wrefresh(menuwin);
- prefresh(menupad, ymenupad, 0, ys, xs, ye, xe);
+ next = getfastnext(menurows, totnitems, pritems, abs);
+ movefocus = next != abs;
break;
case ' ': /* Space */
- if (currmode == MENUMODE)
+ if (pritems[abs].type == MENUMODE)
break;
- else if (currmode == CHECKLISTMODE)
- item->on = !item->on;
+ else if (pritems[abs].type == CHECKLISTMODE)
+ pritems[abs].on = !pritems[abs].on;
else { /* RADIOLISTMODE */
- for (i=0; i < (int) groups[g].nitems; i++)
- if (groups[g].items[i].on == true && i != rel) {
- groups[g].items[i].on = false;
- drawitem(conf, menupad,
- abs - rel + i, groups[g].items[i],
- currmode, pos, false);
+ for (i = abs - pritems[abs].index;
+ i < totnitems &&
+ pritems[i].group == pritems[abs].group;
+ i++) {
+ if (i != abs && pritems[i].on) {
+ pritems[i].on = false;
+ drawitem(conf, menupad, i, pos,
+ &pritems[i], false);
}
- item->on = !item->on;
+ }
+ pritems[abs].on = !pritems[abs].on;
}
- drawitem(conf, menupad, abs, *item, currmode, pos, true);
+ drawitem(conf, menupad, abs, pos, &pritems[abs], true);
prefresh(menupad, ymenupad, 0, ys, xs, ye, xe);
+ break;
default:
- if (shortcut_buttons) {
- for (i = 0; i < (int) bs.nbuttons; i++)
- if (tolower(input) == tolower((bs.label[i])[0])) {
- output = bs.value[i];
- if (currmode == MENUMODE)
- item->on = true;
- loop = false;
- }
+ if (shortcut_butts) {
+ if (shortcut_buttons(input, &bs)) {
+ output = bs.value[bs.curr];
+ if (pritems[abs].type == MENUMODE)
+ pritems[abs].on = true;
+ set_on_output(conf, output, ngroups,
+ groups, pritems);
+ loop = false;
+ }
break;
}
- drawitem(conf, menupad, abs, *item, currmode, pos, false);
- getnextshortcut(conf, currmode, ngroups, groups, &abs,
- &g, &rel, input);
- item = &groups[g].items[rel];
- currmode = getmode(mode, groups[g]);
- drawitem(conf, menupad, abs, *item, currmode, pos, true);
+ /* shourtcut items */
+ next = getnextshortcut(conf, totnitems, pritems, abs,
+ input);
+ movefocus = next != abs;
+ }
+
+ if (movefocus) {
+ drawitem(conf, menupad, abs, pos, &pritems[abs], false);
+ abs = next;
+ drawitem(conf, menupad, abs, pos, &pritems[abs], true);
if (ymenupad > abs && ymenupad > 0)
ymenupad = abs;
if ((int)(ymenupad + menurows) <= abs)
ymenupad = abs - menurows + 1;
- update_menuwin(conf, menuwin, menurows+2, w-4, totnitems,
- menurows, ymenupad);
+ update_menuwin(conf, menuwin, menurows+2, w-4,
+ totnitems, menurows, ymenupad);
wrefresh(menuwin);
prefresh(menupad, ymenupad, 0, ys, xs, ye, xe);
+ movefocus = false;
}
}
if (focuslist != NULL)
- *focuslist = g;
+ *focuslist = abs < 0 ? -1 : pritems[abs].group;
if (focusitem !=NULL)
- *focusitem = rel;
+ *focusitem = abs < 0 ? -1 : pritems[abs].index;
delwin(menupad);
delwin(menuwin);
- end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
+ end_dialog(conf, shadow, widget, textpad);
+ free(pritems);
- return output;
+ return (output);
}
-/*
- * API
- */
-
-int bsddialog_mixedlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int ngroups, struct bsddialog_menugroup *groups,
- int *focuslist, int *focusitem)
+/* API */
+int
+bsddialog_mixedlist(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int menurows, unsigned int ngroups,
+ struct bsddialog_menugroup *groups, int *focuslist, int *focusitem)
{
int output;
output = do_mixedlist(conf, text, rows, cols, menurows, MIXEDLISTMODE,
ngroups, groups, focuslist, focusitem);
- return output;
+ return (output);
}
int
-bsddialog_checklist(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
- int *focusitem)
+bsddialog_checklist(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int menurows, unsigned int nitems,
+ struct bsddialog_menuitem *items, int *focusitem)
{
- int output;
+ int output, focuslist = 0;
struct bsddialog_menugroup group = {
BSDDIALOG_CHECKLIST /* unused */, nitems, items};
output = do_mixedlist(conf, text, rows, cols, menurows, CHECKLISTMODE,
- 1, &group, NULL, focusitem);
+ 1, &group, &focuslist, focusitem);
- return output;
+ return (output);
}
int
-bsddialog_menu(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
- int *focusitem)
+bsddialog_menu(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int menurows, unsigned int nitems,
+ struct bsddialog_menuitem *items, int *focusitem)
{
- int output;
+ int output, focuslist = 0;
struct bsddialog_menugroup group = {
BSDDIALOG_CHECKLIST /* unused */, nitems, items};
output = do_mixedlist(conf, text, rows, cols, menurows, MENUMODE, 1,
- &group, NULL, focusitem);
+ &group, &focuslist, focusitem);
- return output;
+ return (output);
}
int
-bsddialog_radiolist(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
- int *focusitem)
+bsddialog_radiolist(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int menurows, unsigned int nitems,
+ struct bsddialog_menuitem *items, int *focusitem)
{
- int output;
+ int output, focuslist = 0;
struct bsddialog_menugroup group = {
BSDDIALOG_RADIOLIST /* unused */, nitems, items};
output = do_mixedlist(conf, text, rows, cols, menurows, RADIOLISTMODE,
- 1, &group, NULL, focusitem);
-
- return output;
-}
-
-/* todo */
-static int buildlist_autosize(int rows, int cols)
-{
-
- if (cols == BSDDIALOG_AUTOSIZE)
- RETURN_ERROR("Unimplemented cols autosize for buildlist");
-
- if (rows == BSDDIALOG_AUTOSIZE)
- RETURN_ERROR("Unimplemented rows autosize for buildlist");
-
- return 0;
-}
-
-/* to improve */
-static int
-buildlist_checksize(int rows, int cols, char *text, int menurows, int nitems,
- struct buttons bs)
-{
- int mincols, textrow, menusize;
-
- mincols = VBORDERS;
- /* buttons */
- mincols += bs.nbuttons * bs.sizebutton;
- mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0;
- /* line, comment to permet some cols hidden */
- /* mincols = MAX(mincols, linelen); */
+ 1, &group, &focuslist, focusitem);
- if (cols < mincols)
- RETURN_ERROR("Few cols, width < size buttons or "\
- "name+descripion of the items");
-
- textrow = text != NULL && strlen(text) > 0 ? 1 : 0;
-
- if (nitems > 0 && menurows == 0)
- RETURN_ERROR("items > 0 but menurows == 0, probably terminal "\
- "too small");
-
- menusize = nitems > 0 ? 3 : 0;
- if (rows < 2 + 2 + menusize + textrow)
- RETURN_ERROR("Few lines for this menus");
-
- return 0;
-}
-
-int
-bsddialog_buildlist(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int menurows, int nitems, struct bsddialog_menuitem *items,
- int *focusitem)
-{
- WINDOW *widget, *textpad, *leftwin, *leftpad, *rightwin, *rightpad, *shadow;
- int output, i, x, y, h, w, htextpad, input;
- bool loop, buttupdate, padsupdate, startleft;
- int nlefts, nrights, leftwinx, rightwinx, winsy, padscols, curr;
- enum side {LEFT, RIGHT} currV;
- int currH;
- struct buttons bs;
- struct lineposition pos = {0,0,0,0,0,0,0,0,0,0};
-
- startleft = false;
- for (i=0; i<nitems; i++) {
- pos.line = MAX(pos.line, strlen(items[i].desc));
- if (items[i].on == false)
- startleft = true;
- }
-
- get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
- BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
-
- if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
- if (buildlist_autosize(rows, cols) != 0)
- return BSDDIALOG_ERROR;
- if (buildlist_checksize(h, w, text, menurows, nitems, bs) != 0)
- return BSDDIALOG_ERROR;
- if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
-
- if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
- &textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
-
- prefresh(textpad, 0, 0, y + 1, x + 1 + t.text.hmargin,
- y + h - menurows, x + 1 + w - t.text.hmargin);
-
- winsy = y + h - 5 - menurows;
- leftwinx = x+2;
- leftwin = new_boxed_window(conf, winsy, leftwinx, menurows+2, (w-5)/2,
- LOWERED);
- rightwinx = x + w - 2 -(w-5)/2;
- rightwin = new_boxed_window(conf, winsy, rightwinx, menurows+2,
- (w-5)/2, LOWERED);
-
- wrefresh(leftwin);
- wrefresh(rightwin);
-
- padscols = (w-5)/2 - 2;
- leftpad = newpad(nitems, pos.line);
- rightpad = newpad(nitems, pos.line);
- wbkgd(leftpad, t.dialog.color);
- wbkgd(rightpad, t.dialog.color);
-
- currH = 0;
- currV = startleft ? LEFT : RIGHT;
- loop = buttupdate = padsupdate = true;
- while(loop) {
- if (buttupdate) {
- draw_buttons(widget, h-2, w, bs, true);
- wrefresh(widget);
- buttupdate = false;
- }
-
- if (padsupdate) {
- werase(leftpad);
- werase(rightpad);
- curr = -1;
- nlefts = nrights = 0;
- for (i=0; i<nitems; i++) {
- if (items[i].on == false) {
- if (currV == LEFT && currH == nlefts)
- curr = i;
- drawitem(conf, leftpad, nlefts, items[i],
- BUILDLISTMODE, pos, curr == i);
- nlefts++;
- } else {
- if (currV == RIGHT && currH == nrights)
- curr = i;
- drawitem(conf, rightpad, nrights, items[i],
- BUILDLISTMODE, pos, curr == i);
- nrights++;
- }
- }
- prefresh(leftpad, 0, 0, winsy+1, leftwinx+1,
- winsy+1+menurows, leftwinx + 1 + padscols);
- prefresh(rightpad, 0, 0, winsy+1, rightwinx+1,
- winsy+1+menurows, rightwinx + 1 + padscols);
- padsupdate = false;
- }
-
- input = getch();
- switch(input) {
- case KEY_ENTER:
- case 10: /* Enter */
- output = bs.value[bs.curr];
- loop = false;
- break;
- case 27: /* Esc */
- output = BSDDIALOG_ERROR;
- loop = false;
- break;
- case '\t': /* TAB */
- bs.curr = (bs.curr + 1) % bs.nbuttons;
- buttupdate = true;
- break;
- }
-
- if (nitems <= 0)
- continue;
-
- switch(input) {
- case KEY_LEFT:
- if (currV == RIGHT && nrights > 0) {
- currV = LEFT;
- currH = 0;
- padsupdate = true;
- }
- break;
- case KEY_RIGHT:
- if (currV == LEFT && nrights > 0) {
- currV = RIGHT;
- currH = 0;
- padsupdate = true;
- }
- break;
- case KEY_UP:
- currH = (currH > 0) ? currH - 1 : 0;
- padsupdate = true;
- break;
- case KEY_DOWN:
- if (currV == LEFT)
- currH = (currH < nlefts-1) ? currH +1 : currH;
- else
- currH = (currH < nrights-1)? currH +1 : currH;
- padsupdate = true;
- break;
- case ' ': /* Space */
- items[curr].on = ! items[curr].on;
- if (currV == LEFT) {
- if (nlefts > 1)
- currH = currH > 0 ? currH-1 : 0;
- else {
- currH = 0;
- currV = RIGHT;
- }
- } else {
- if (nrights > 1)
- currH = currH > 0 ? currH-1 : 0;
- else {
- currH = 0;
- currV = LEFT;
- }
- }
- padsupdate = true;
- break;
- default:
-
- break;
- }
- }
-
- if(focusitem != NULL)
- *focusitem = curr;
-
- delwin(leftpad);
- delwin(leftwin);
- delwin(rightpad);
- delwin(rightwin);
- end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
-
- return output;
-}
+ return (output);
+} \ No newline at end of file
diff --git a/lib/messagebox.c b/lib/messagebox.c
index 6fe775cfcbc9..edea7c41c18d 100644
--- a/lib/messagebox.c
+++ b/lib/messagebox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,60 +27,34 @@
#include <sys/param.h>
-#include <ctype.h>
-#ifdef PORTNCURSES
-#include <ncurses/ncurses.h>
-#else
-#include <ncurses.h>
-#endif
+#include <curses.h>
#include <string.h>
#include "bsddialog.h"
-#include "lib_util.h"
#include "bsddialog_theme.h"
-
-#define AUTO_WIDTH (COLS / 3U)
-/* at least 1 line text for its pad building in widget_withtextpad_init() */
-#define MIN_HEIGHT (HBORDERS + 2 /*buttons*/ + 1 /*text*/)
+#include "lib_util.h"
extern struct bsddialog_theme t;
static int
message_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
- int *w, char *text, struct buttons bs)
+ int *w, const char *text, struct buttons bs)
{
- int maxword, maxline, nlines, line;
-
- if (get_text_properties(conf, text, &maxword, &maxline, &nlines) != 0)
- return BSDDIALOG_ERROR;
-
- if (cols == BSDDIALOG_AUTOSIZE) {
- *w = VBORDERS;
- /* buttons size */
- *w += bs.nbuttons * bs.sizebutton;
- *w += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0;
- /* text size */
- line = MIN(maxline + VBORDERS + t.text.hmargin * 2, AUTO_WIDTH);
- line = MAX(line, (int) (maxword + VBORDERS + t.text.hmargin * 2));
- *w = MAX(*w, line);
- /* conf.auto_minwidth */
- *w = MAX(*w, (int)conf->auto_minwidth);
- /* avoid terminal overflow */
- *w = MIN(*w, widget_max_width(conf));
- }
+ int htext, wtext;
- if (rows == BSDDIALOG_AUTOSIZE) {
- *h = MIN_HEIGHT - 1;
- if (maxword > 0)
- *h += MAX(nlines, (int)(*w / GET_ASPECT_RATIO(conf)));
- *h = MAX(*h, MIN_HEIGHT);
- /* conf.auto_minheight */
- *h = MAX(*h, (int)conf->auto_minheight);
- /* avoid terminal overflow */
- *h = MIN(*h, widget_max_height(conf));
+ if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
+ if (text_size(conf, rows, cols, text, &bs, 0, SCREENCOLS/2,
+ &htext, &wtext) != 0)
+ return (BSDDIALOG_ERROR);
}
- return 0;
+ if (cols == BSDDIALOG_AUTOSIZE)
+ *w = widget_min_width(conf, wtext, 0, &bs);
+
+ if (rows == BSDDIALOG_AUTOSIZE)
+ *h = widget_min_height(conf, htext, 0, true);
+
+ return (0);
}
static int message_checksize(int rows, int cols, struct buttons bs)
@@ -92,182 +66,167 @@ static int message_checksize(int rows, int cols, struct buttons bs)
mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0;
if (cols < mincols)
- RETURN_ERROR("Few cols, Msgbox and Yesno need at least width "\
+ RETURN_ERROR("Few cols, Msgbox and Yesno need at least width "
"for borders, buttons and spaces between buttons");
- if (rows < MIN_HEIGHT)
- RETURN_ERROR("Msgbox and Yesno need at least height 5");
+ if (rows < HBORDERS + 2 /*buttons*/)
+ RETURN_ERROR("Msgbox and Yesno need at least height 4");
- return 0;
+ return (0);
}
static void
-buttonsupdate(WINDOW *widget, int h, int w, struct buttons bs)
+textupdate(WINDOW *widget, WINDOW *textpad, int htextpad, int ytextpad)
{
- draw_buttons(widget, h-2, w, bs, true);
- wnoutrefresh(widget);
-}
+ int y, x, h, w;
+
+ getbegyx(widget, y, x);
+ getmaxyx(widget, h, w);
-static void
-textupdate(WINDOW *widget, int y, int x, int h, int w, WINDOW *textpad,
- int htextpad, int textrow)
-{
if (htextpad > h - 4) {
mvwprintw(widget, h-3, w-6, "%3d%%",
- 100 * (textrow+h-4)/ htextpad);
+ 100 * (ytextpad+h-4)/ htextpad);
wnoutrefresh(widget);
}
- pnoutrefresh(textpad, textrow, 0, y+1, x+2, y+h-4, x+w-2);
+ pnoutrefresh(textpad, ytextpad, 0, y+1, x+2, y+h-4, x+w-2);
}
static int
-do_dialog(struct bsddialog_conf *conf, char *text, int rows, int cols,
+do_message(struct bsddialog_conf *conf, const char *text, int rows, int cols,
struct buttons bs)
{
- WINDOW *widget, *textpad, *shadow;
bool loop;
- int i, y, x, h, w, input, output, htextpad, textrow;
+ int y, x, h, w, input, output, ytextpad, htextpad, unused;
+ WINDOW *widget, *textpad, *shadow;
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (message_autosize(conf, rows, cols, &h, &w, text, bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (message_checksize(h, w, bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
- if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
- &textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
+ if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
+ true) != 0)
+ return (BSDDIALOG_ERROR);
- textrow = 0;
+ ytextpad = 0;
+ getmaxyx(textpad, htextpad, unused);
+ unused++; /* fix unused error */
+ textupdate(widget, textpad, htextpad, ytextpad);
loop = true;
- buttonsupdate(widget, h, w, bs);
- textupdate(widget, y, x, h, w, textpad, htextpad, textrow);
- while(loop) {
+ while (loop) {
doupdate();
input = getch();
switch (input) {
+ case KEY_ENTER:
case 10: /* Enter */
output = bs.value[bs.curr];
loop = false;
break;
case 27: /* Esc */
- output = BSDDIALOG_ESC;
- loop = false;
+ if (conf->key.enable_esc) {
+ output = BSDDIALOG_ESC;
+ loop = false;
+ }
break;
case '\t': /* TAB */
bs.curr = (bs.curr + 1) % bs.nbuttons;
- buttonsupdate(widget, h, w, bs);
+ draw_buttons(widget, bs, true);
+ wnoutrefresh(widget);
+ break;
+ case KEY_LEFT:
+ if (bs.curr > 0) {
+ bs.curr--;
+ draw_buttons(widget, bs, true);
+ wnoutrefresh(widget);
+ }
+ break;
+ case KEY_RIGHT:
+ if (bs.curr < (int)bs.nbuttons - 1) {
+ bs.curr++;
+ draw_buttons(widget, bs, true);
+ wnoutrefresh(widget);
+ }
break;
case KEY_F(1):
if (conf->f1_file == NULL && conf->f1_message == NULL)
break;
if (f1help(conf) != 0)
- return BSDDIALOG_ERROR;
- /* No break! the terminal size can change */
+ return (BSDDIALOG_ERROR);
+ /* No break, screen size can change */
case KEY_RESIZE:
- hide_widget(y, x, h, w,conf->shadow);
-
- /*
- * Unnecessary, but, when the columns decrease the
- * following "refresh" seem not work
- */
+ /* Important for decreasing screen */
+ hide_widget(y, x, h, w, conf->shadow);
refresh();
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
- if (message_autosize(conf, rows, cols, &h, &w, text, bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
+ if (message_autosize(conf, rows, cols, &h, &w, text,
+ bs) != 0)
+ return (BSDDIALOG_ERROR);
if (message_checksize(h, w, bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
- wclear(shadow);
- mvwin(shadow, y + t.shadow.h, x + t.shadow.w);
- wresize(shadow, h, w);
+ if (update_dialog(conf, shadow, widget, y, x, h, w,
+ textpad, text, &bs, true) != 0)
+ return (BSDDIALOG_ERROR);
- wclear(widget);
- mvwin(widget, y, x);
- wresize(widget, h, w);
-
- htextpad = 1;
- wclear(textpad);
- wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2);
-
- if(update_widget_withtextpad(conf, shadow, widget, h, w,
- RAISED, textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
-
- buttonsupdate(widget, h, w, bs);
- textupdate(widget, y, x, h, w, textpad, htextpad, textrow);
+ getmaxyx(textpad, htextpad, unused);
+ textupdate(widget, textpad, htextpad, ytextpad);
/* Important to fix grey lines expanding screen */
refresh();
break;
case KEY_UP:
- if (textrow == 0)
+ if (ytextpad == 0)
break;
- textrow--;
- textupdate(widget, y, x, h, w, textpad, htextpad, textrow);
+ ytextpad--;
+ textupdate(widget, textpad, htextpad, ytextpad);
break;
case KEY_DOWN:
- if (textrow + h - 4 >= htextpad)
+ if (ytextpad + h - 4 >= htextpad)
break;
- textrow++;
- textupdate(widget, y, x, h, w, textpad, htextpad, textrow);
- break;
- case KEY_LEFT:
- if (bs.curr > 0) {
- bs.curr--;
- buttonsupdate(widget, h, w, bs);
- }
- break;
- case KEY_RIGHT:
- if (bs.curr < (int) bs.nbuttons - 1) {
- bs.curr++;
- buttonsupdate(widget, h, w, bs);
- }
+ ytextpad++;
+ textupdate(widget, textpad, htextpad, ytextpad);
break;
default:
- for (i = 0; i < (int) bs.nbuttons; i++)
- if (tolower(input) == tolower(bs.label[i][0])) {
- output = bs.value[i];
- loop = false;
+ if (shortcut_buttons(input, &bs)) {
+ output = bs.value[bs.curr];
+ loop = false;
}
}
}
- end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
+ end_dialog(conf, shadow, widget, textpad);
- return output;
+ return (output);
}
/* API */
int
-bsddialog_msgbox(struct bsddialog_conf *conf, char* text, int rows, int cols)
+bsddialog_msgbox(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols)
{
struct buttons bs;
- get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
- NULL, BUTTONLABEL(help_label));
+ get_buttons(conf, &bs, BUTTON_OK_LABEL, NULL);
- return (do_dialog(conf, text, rows, cols, bs));
+ return (do_message(conf, text, rows, cols, bs));
}
int
-bsddialog_yesno(struct bsddialog_conf *conf, char* text, int rows, int cols)
+bsddialog_yesno(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols)
{
struct buttons bs;
- get_buttons(conf, &bs,
- conf->button.ok_label == NULL ? "Yes" : conf->button.ok_label,
- BUTTONLABEL(extra_label),
- conf->button.cancel_label == NULL ? "No" : conf->button.cancel_label,
- BUTTONLABEL(help_label));
+ get_buttons(conf, &bs, "Yes", "No");
- return (do_dialog(conf, text, rows, cols, bs));
-}
+ return (do_message(conf, text, rows, cols, bs));
+} \ No newline at end of file
diff --git a/lib/textbox.c b/lib/textbox.c
index 6dae6c81343b..9e242b9fb5ab 100644
--- a/lib/textbox.c
+++ b/lib/textbox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,57 +25,34 @@
* SUCH DAMAGE.
*/
-
#include <sys/param.h>
-#ifdef PORTNCURSES
-#include <ncurses/ncurses.h>
-#else
-#include <ncurses.h>
-#endif
+#include <curses.h>
#include <string.h>
#include "bsddialog.h"
-#include "lib_util.h"
#include "bsddialog_theme.h"
-
-/* "Text": textbox */
-
-#define BUTTON_TEXTBOX "EXIT"
+#include "lib_util.h"
extern struct bsddialog_theme t;
static void
-textbox_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w,
- int hpad, int wpad)
+textbox_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
+ int *w, int hpad, int wpad, struct buttons bs)
{
+ if (cols == BSDDIALOG_AUTOSIZE)
+ *w = widget_min_width(conf, 0, wpad, &bs);
- if (cols == BSDDIALOG_AUTOSIZE) {
- *w = VBORDERS;
- /* buttons size */
- *w += strlen(BUTTON_TEXTBOX) + 2 /* text delims*/;
- /* text size */
- *w = MAX(*w, wpad + VBORDERS);
- /* conf.auto_minwidth */
- *w = MAX(*w, (int)conf->auto_minwidth);
- /* avoid terminal overflow */
- *w = MIN(*w, widget_max_width(conf)-1); /* again -1, fix util.c */
- }
-
- if (rows == BSDDIALOG_AUTOSIZE) {
- *h = hpad + 4; /* HBORDERS + button border */
- /* conf.auto_minheight */
- *h = MAX(*h, (int)conf->auto_minheight);
- /* avoid terminal overflow */
- *h = MIN(*h, widget_max_height(conf));
- }
+ if (rows == BSDDIALOG_AUTOSIZE)
+ *h = widget_min_height(conf, 0, hpad, true);
}
-static int textbox_checksize(int rows, int cols, int hpad)
+static int
+textbox_checksize(int rows, int cols, int hpad, struct buttons bs)
{
int mincols;
- mincols = VBORDERS + strlen(BUTTON_TEXTBOX) + 2 /* text delims */;
+ mincols = VBORDERS + bs.sizebutton;
if (cols < mincols)
RETURN_ERROR("Few cols for the textbox");
@@ -83,18 +60,21 @@ static int textbox_checksize(int rows, int cols, int hpad)
if (rows < 4 /* HBORDERS + button*/ + (hpad > 0 ? 1 : 0))
RETURN_ERROR("Few rows for the textbox");
- return 0;
+ return (0);
}
+/* API */
int
-bsddialog_textbox(struct bsddialog_conf *conf, char* file, int rows, int cols)
+bsddialog_textbox(struct bsddialog_conf *conf, const char* file, int rows,
+ int cols)
{
- WINDOW *widget, *pad, *shadow;
- int i, input, y, x, h, w, hpad, wpad, ypad, xpad, ys, ye, xs, xe, printrows;
- char buf[BUFSIZ], *exitbutt;
- FILE *fp;
bool loop;
- int output;
+ int i, output, input;
+ int y, x, h, w, hpad, wpad, ypad, xpad, ys, ye, xs, xe, printrows;
+ char buf[BUFSIZ];
+ FILE *fp;
+ struct buttons bs;
+ WINDOW *shadow, *widget, *pad;
if ((fp = fopen(file, "r")) == NULL)
RETURN_ERROR("Cannot open file");
@@ -104,7 +84,7 @@ bsddialog_textbox(struct bsddialog_conf *conf, char* file, int rows, int cols)
pad = newpad(hpad, wpad);
wbkgd(pad, t.dialog.color);
i = 0;
- while(fgets(buf, BUFSIZ, fp) != NULL) {
+ while (fgets(buf, BUFSIZ, fp) != NULL) {
if ((int) strlen(buf) > wpad) {
wpad = strlen(buf);
wresize(pad, hpad, wpad);
@@ -118,23 +98,25 @@ bsddialog_textbox(struct bsddialog_conf *conf, char* file, int rows, int cols)
}
fclose(fp);
+ bs.nbuttons = 1;
+ bs.label[0] = "EXIT";
+ if (conf->button.ok_label != NULL)
+ bs.label[0] = conf->button.ok_label;
+ bs.value[0] = BSDDIALOG_OK;
+ bs.curr = 0;
+ bs.sizebutton = strlen(bs.label[0]) + 2;
+
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
- textbox_autosize(conf, rows, cols, &h, &w, hpad, wpad);
- if (textbox_checksize(h, w, hpad) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
+ textbox_autosize(conf, rows, cols, &h, &w, hpad, wpad, bs);
+ if (textbox_checksize(h, w, hpad, bs) != 0)
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
-
- if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
- NULL, NULL, NULL, true) != 0)
- return BSDDIALOG_ERROR;
-
- exitbutt = conf->button.exit_label == NULL ? BUTTON_TEXTBOX : conf->button.exit_label;
- draw_button(widget, h-2, (w-2)/2 - strlen(exitbutt)/2, strlen(exitbutt)+2,
- exitbutt, true, false);
+ return (BSDDIALOG_ERROR);
- wrefresh(widget);
+ if (new_dialog(conf, &shadow, &widget, y, x, h, w, NULL, NULL, &bs,
+ true) != 0)
+ return (BSDDIALOG_ERROR);
ys = y + 1;
xs = x + 1;
@@ -143,8 +125,10 @@ bsddialog_textbox(struct bsddialog_conf *conf, char* file, int rows, int cols)
ypad = xpad = 0;
printrows = h-4;
loop = true;
- while(loop) {
- prefresh(pad, ypad, xpad, ys, xs, ye, xe);
+ while (loop) {
+ wnoutrefresh(widget);
+ pnoutrefresh(pad, ypad, xpad, ys, xs, ye, xe);
+ doupdate();
input = getch();
switch(input) {
case KEY_ENTER:
@@ -153,8 +137,10 @@ bsddialog_textbox(struct bsddialog_conf *conf, char* file, int rows, int cols)
loop = false;
break;
case 27: /* Esc */
- output = BSDDIALOG_ESC;
- loop = false;
+ if (conf->key.enable_esc) {
+ output = BSDDIALOG_ESC;
+ loop = false;
+ }
break;
case KEY_HOME:
ypad = 0;
@@ -169,7 +155,8 @@ bsddialog_textbox(struct bsddialog_conf *conf, char* file, int rows, int cols)
break;
case KEY_NPAGE:
ypad += printrows;
- ypad = ypad + printrows > hpad ? hpad - printrows : ypad;
+ if (ypad + printrows > hpad)
+ ypad = hpad - printrows;
break;
case '0':
xpad = 0;
@@ -193,32 +180,21 @@ bsddialog_textbox(struct bsddialog_conf *conf, char* file, int rows, int cols)
if (conf->f1_file == NULL && conf->f1_message == NULL)
break;
if (f1help(conf) != 0)
- return BSDDIALOG_ERROR;
- /* No break! the terminal size can change */
+ return (BSDDIALOG_ERROR);
+ /* No break, screen size can change */
case KEY_RESIZE:
- hide_widget(y, x, h, w,conf->shadow);
-
- /*
- * Unnecessary, but, when the columns decrease the
- * following "refresh" seem not work
- */
+ /* Important for decreasing screen */
+ hide_widget(y, x, h, w, conf->shadow);
refresh();
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
- textbox_autosize(conf, rows, cols, &h, &w, hpad, wpad);
- if (textbox_checksize(h, w, hpad) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
+ textbox_autosize(conf, rows, cols, &h, &w, hpad, wpad,
+ bs);
+ if (textbox_checksize(h, w, hpad, bs) != 0)
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
-
- wclear(shadow);
- mvwin(shadow, y + t.shadow.h, x + t.shadow.w);
- wresize(shadow, h, w);
-
- wclear(widget);
- mvwin(widget, y, x);
- wresize(widget, h, w);
+ return (BSDDIALOG_ERROR);
ys = y + 1;
xs = x + 1;
@@ -227,22 +203,22 @@ bsddialog_textbox(struct bsddialog_conf *conf, char* file, int rows, int cols)
ypad = xpad = 0;
printrows = h - 4;
- if(update_widget_withtextpad(conf, shadow, widget, h, w,
- RAISED, NULL, NULL, NULL, true) != 0)
- return BSDDIALOG_ERROR;
-
- draw_button(widget, h-2, (w-2)/2 - strlen(exitbutt)/2,
- strlen(exitbutt)+2, exitbutt, true, false);
-
- wrefresh(widget); /* for button */
+ if (update_dialog(conf, shadow, widget, y, x, h, w,
+ NULL, NULL, &bs, true) != 0)
+ return (BSDDIALOG_ERROR);
/* Important to fix grey lines expanding screen */
refresh();
break;
+ default:
+ if (shortcut_buttons(input, &bs)) {
+ output = bs.value[bs.curr];
+ loop = false;
+ }
}
}
- end_widget_withtextpad(conf, widget, h, w, pad, shadow);
+ end_dialog(conf, shadow, widget, pad);
- return output;
-}
+ return (output);
+} \ No newline at end of file
diff --git a/lib/theme.c b/lib/theme.c
index 0948501e52ff..48eed6a8e598 100644
--- a/lib/theme.c
+++ b/lib/theme.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,15 +25,11 @@
* SUCH DAMAGE.
*/
-#ifdef PORTNCURSES
-#include <ncurses/ncurses.h>
-#else
-#include <ncurses.h>
-#endif
+#include <curses.h>
#include "bsddialog.h"
-#include "lib_util.h"
#include "bsddialog_theme.h"
+#include "lib_util.h"
#define GET_COLOR(bg, fg) (COLOR_PAIR(bg * 8 + fg +1))
@@ -42,7 +38,7 @@ struct bsddialog_theme t;
static struct bsddialog_theme bsddialogtheme = {
#define bgwidget COLOR_WHITE
#define bgcurr COLOR_YELLOW
- .terminal.color = GET_COLOR(COLOR_BLACK, COLOR_CYAN),
+ .screen.color = GET_COLOR(COLOR_BLACK, COLOR_CYAN),
.shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
.shadow.h = 1,
@@ -55,8 +51,6 @@ static struct bsddialog_theme bsddialogtheme = {
.dialog.color = GET_COLOR(COLOR_BLACK, bgwidget),
.dialog.bottomtitlecolor = GET_COLOR(COLOR_BLACK, bgwidget),
- .text.hmargin = 1,
-
.menu.arrowcolor = GET_COLOR(COLOR_YELLOW, bgwidget),
.menu.selectorcolor = GET_COLOR(COLOR_BLACK, bgwidget) | A_BOLD,
.menu.f_desccolor = GET_COLOR(COLOR_WHITE, bgcurr),
@@ -89,7 +83,7 @@ static struct bsddialog_theme bsddialogtheme = {
static struct bsddialog_theme blackwhite = {
#define fg COLOR_WHITE
#define bk COLOR_BLACK
- .terminal.color = GET_COLOR(fg, bk),
+ .screen.color = GET_COLOR(fg, bk),
.shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
.shadow.h = 1,
@@ -102,8 +96,6 @@ static struct bsddialog_theme blackwhite = {
.dialog.color = GET_COLOR(fg, bk),
.dialog.bottomtitlecolor = GET_COLOR(fg, bk),
- .text.hmargin = 1,
-
.menu.arrowcolor = GET_COLOR(fg, bk),
.menu.selectorcolor = GET_COLOR(fg, bk),
.menu.f_desccolor = GET_COLOR(fg, bk) | A_REVERSE,
@@ -134,7 +126,7 @@ static struct bsddialog_theme blackwhite = {
};
static struct bsddialog_theme dialogtheme = {
- .terminal.color = GET_COLOR(COLOR_CYAN, COLOR_BLUE) | A_BOLD,
+ .screen.color = GET_COLOR(COLOR_CYAN, COLOR_BLUE) | A_BOLD,
.shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
.shadow.h = 1,
@@ -147,18 +139,16 @@ static struct bsddialog_theme dialogtheme = {
.dialog.color = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
.dialog.bottomtitlecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD,
- .text.hmargin = 1,
-
.menu.arrowcolor = GET_COLOR(COLOR_GREEN, COLOR_WHITE),
- .menu.selectorcolor = GET_COLOR(COLOR_BLACK, bgwidget) | A_BOLD,
- .menu.f_desccolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
- .menu.desccolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD,
- .menu.f_namecolor = GET_COLOR(COLOR_YELLOW, COLOR_BLUE) | A_BOLD,
- .menu.namecolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD,
+ .menu.selectorcolor = GET_COLOR(COLOR_BLACK, bgwidget),
+ .menu.f_desccolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
+ .menu.desccolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
+ .menu.f_namecolor = GET_COLOR(COLOR_YELLOW, COLOR_BLUE),
+ .menu.namecolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE),
.menu.namesepcolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
.menu.descsepcolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
- .menu.f_shortcutcolor = GET_COLOR(COLOR_RED, COLOR_BLUE) | A_BOLD,
- .menu.shortcutcolor = GET_COLOR(COLOR_RED, COLOR_WHITE) | A_BOLD,
+ .menu.f_shortcutcolor = GET_COLOR(COLOR_RED, COLOR_BLUE),
+ .menu.shortcutcolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
.form.f_fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
.form.fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN) | A_BOLD,
@@ -181,11 +171,12 @@ static struct bsddialog_theme dialogtheme = {
static void
set_theme(struct bsddialog_theme *dst, struct bsddialog_theme *src)
{
+ dst->screen.color = src->screen.color;
+
dst->shadow.color = src->shadow.color;
dst->shadow.h = src->shadow.h;
dst->shadow.w = src->shadow.w;
- dst->terminal.color = src->terminal.color;
dst->dialog.delimtitle = src->dialog.delimtitle;
dst->dialog.titlecolor = src->dialog.titlecolor;
dst->dialog.lineraisecolor = src->dialog.lineraisecolor;
@@ -193,8 +184,6 @@ set_theme(struct bsddialog_theme *dst, struct bsddialog_theme *src)
dst->dialog.color = src->dialog.color;
dst->dialog.bottomtitlecolor = src->dialog.bottomtitlecolor;
- dst->text.hmargin = src->text.hmargin;
-
dst->menu.arrowcolor = src->menu.arrowcolor;
dst->menu.selectorcolor = src->menu.selectorcolor;
dst->menu.f_desccolor = src->menu.f_desccolor;
@@ -223,7 +212,7 @@ set_theme(struct bsddialog_theme *dst, struct bsddialog_theme *src)
dst->button.f_shortcutcolor = src->button.f_shortcutcolor;
dst->button.shortcutcolor = src->button.shortcutcolor;
- bkgd(dst->terminal.color);
+ bkgd(dst->screen.color);
refresh();
}
@@ -258,6 +247,9 @@ int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme)
if (newtheme == BSDDIALOG_THEME_DEFAULT) {
bsddialog_set_theme(&dialogtheme);
t.dialog.lineraisecolor = t.dialog.linelowercolor;
+ t.dialog.delimtitle = true;
+ t.button.leftch = '[';
+ t.button.rightch = ']';
}
else if (newtheme == BSDDIALOG_THEME_BSDDIALOG)
bsddialog_set_theme(&bsddialogtheme);
@@ -285,4 +277,4 @@ bsddialog_color(enum bsddialog_color foreground,
cursesflags |= A_UNDERLINE;
return (GET_COLOR(foreground, background) | cursesflags);
-}
+} \ No newline at end of file
diff --git a/lib/timebox.c b/lib/timebox.c
index 04e058448149..db1d4377d007 100644
--- a/lib/timebox.c
+++ b/lib/timebox.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (c) 2021 Alfonso Sabato Siciliano
+ * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,66 +28,41 @@
#include <sys/param.h>
#include <ctype.h>
-#ifdef PORTNCURSES
-#include <ncurses/ncurses.h>
-#else
-#include <ncurses.h>
-#endif
+#include <curses.h>
#include <string.h>
#include "bsddialog.h"
-#include "lib_util.h"
#include "bsddialog_theme.h"
+#include "lib_util.h"
-#define MINWDATE 25 /* 23 wins + 2 VBORDERS */
-#define MINWTIME 16 /*14 wins + 2 VBORDERS */
-#define MINHEIGHT 8 /* 2 for text */
-
-/* "Time": timebox - datebox */
+#define MINWDATE 23 /* 3 windows and their borders */
+#define MINWTIME 14 /* 3 windows and their borders */
extern struct bsddialog_theme t;
static int
datetime_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h,
- int *w, int minw, char *text, struct buttons bs)
+ int *w, int minw, const char *text, struct buttons bs)
{
- int maxword, maxline, nlines, line;
-
- if (get_text_properties(conf, text, &maxword, &maxline, &nlines) != 0)
- return BSDDIALOG_ERROR;
-
- if (cols == BSDDIALOG_AUTOSIZE) {
- *w = VBORDERS;
- /* buttons size */
- *w += bs.nbuttons * bs.sizebutton;
- *w += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0;
- /* text size */
- line = maxline + VBORDERS + t.text.hmargin * 2;
- line = MAX(line, (int) (maxword + VBORDERS + t.text.hmargin * 2));
- *w = MAX(*w, line);
- /* date windows */
- *w = MAX(*w, minw);
- /* conf.auto_minwidth */
- *w = MAX(*w, (int)conf->auto_minwidth);
- /* avoid terminal overflow */
- *w = MIN(*w, widget_max_width(conf) -1);
- }
+ int htext, wtext;
- if (rows == BSDDIALOG_AUTOSIZE) {
- *h = MINHEIGHT;
- if (maxword > 0)
- *h += MAX(nlines, (int)(*w / GET_ASPECT_RATIO(conf)));
- /* conf.auto_minheight */
- *h = MAX(*h, (int)conf->auto_minheight);
- /* avoid terminal overflow */
- *h = MIN(*h, widget_max_height(conf) -1);
+ if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) {
+ if (text_size(conf, rows, cols, text, &bs, 3, minw, &htext,
+ &wtext) != 0)
+ return (BSDDIALOG_ERROR);
}
- return 0;
+ if (cols == BSDDIALOG_AUTOSIZE)
+ *w = widget_min_width(conf, htext,minw, &bs);
+
+ if (rows == BSDDIALOG_AUTOSIZE)
+ *h = widget_min_height(conf, htext, 3 /* windows */, true);
+
+ return (0);
}
static int
-datetime_checksize(int rows, int cols, char *text, int minw, struct buttons bs)
+datetime_checksize(int rows, int cols, int minw, struct buttons bs)
{
int mincols;
@@ -99,19 +74,20 @@ datetime_checksize(int rows, int cols, char *text, int minw, struct buttons bs)
if (cols < mincols)
RETURN_ERROR("Few cols for this timebox/datebox");
- if (rows < MINHEIGHT + (strlen(text) > 0 ? 1 : 0))
- RETURN_ERROR("Few rows for this timebox/datebox");
+ if (rows < 7) /* 2 button + 2 borders + 3 windows */
+ RETURN_ERROR("Few rows for this timebox/datebox, at least 7");
- return 0;
+ return (0);
}
-int bsddialog_timebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int *hh, unsigned int *mm, unsigned int *ss)
+int
+bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows,
+ int cols, unsigned int *hh, unsigned int *mm, unsigned int *ss)
{
+ bool loop;
+ int i, input, output, y, x, h, w, sel;
WINDOW *widget, *textpad, *shadow;
- int i, input, output, y, x, h, w, sel, htextpad;
struct buttons bs;
- bool loop;
struct myclockstruct {
unsigned int max;
unsigned int value;
@@ -132,41 +108,38 @@ int bsddialog_timebox(struct bsddialog_conf *conf, char* text, int rows, int col
c[i].value = c[i].max;
}
- get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
- BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
+ get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
- if (datetime_autosize(conf, rows, cols, &h, &w, MINWTIME, text, bs) != 0)
- return BSDDIALOG_ERROR;
- if (datetime_checksize(h, w, text, MINWTIME, bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
+ if (datetime_autosize(conf, rows, cols, &h, &w, MINWTIME, text,
+ bs) != 0)
+ return (BSDDIALOG_ERROR);
+ if (datetime_checksize(h, w, MINWTIME, bs) != 0)
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
-
- if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
- &textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
-
- draw_buttons(widget, h-2, w, bs, true);
+ return (BSDDIALOG_ERROR);
- wrefresh(widget);
+ if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
+ true) != 0)
+ return (BSDDIALOG_ERROR);
- prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2);
+ pnoutrefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2);
+ doupdate();
- c[0].win = new_boxed_window(conf, y + h - 6, x + w/2 - 7, 3, 4, LOWERED);
+ c[0].win = new_boxed_window(conf, y+h-6, x + w/2 - 7, 3, 4, LOWERED);
mvwaddch(widget, h - 5, w/2 - 3, ':');
- c[1].win = new_boxed_window(conf, y + h - 6, x + w/2 - 2, 3, 4, LOWERED);
+ c[1].win = new_boxed_window(conf, y+h-6, x + w/2 - 2, 3, 4, LOWERED);
mvwaddch(widget, h - 5, w/2 + 2, ':');
- c[2].win = new_boxed_window(conf, y + h - 6, x + w/2 + 3, 3, 4, LOWERED);
+ c[2].win = new_boxed_window(conf, y+h-6, x + w/2 + 3, 3, 4, LOWERED);
wrefresh(widget);
sel = 0;
curs_set(2);
loop = true;
- while(loop) {
- for (i=0; i<3; i++) {
+ while (loop) {
+ for (i = 0; i < 3; i++) {
mvwprintw(c[i].win, 1, 1, "%2d", c[i].value);
wrefresh(c[i].win);
}
@@ -186,79 +159,61 @@ int bsddialog_timebox(struct bsddialog_conf *conf, char* text, int rows, int col
loop = false;
break;
case 27: /* Esc */
- output = BSDDIALOG_ESC;
- loop = false;
+ if (conf->key.enable_esc) {
+ output = BSDDIALOG_ESC;
+ loop = false;
+ }
break;
case '\t': /* TAB */
- sel = (sel + 1) % 3;
+ bs.curr = (bs.curr + 1) % bs.nbuttons;
+ draw_buttons(widget, bs, true);
+ wrefresh(widget);
break;
case KEY_LEFT:
- if (bs.curr > 0) {
- bs.curr--;
- draw_buttons(widget, h-2, w, bs, true);
- wrefresh(widget);
- }
+ sel = sel == 0 ? 2 : (sel - 1);
break;
case KEY_RIGHT:
- if (bs.curr < (int) bs.nbuttons - 1) {
- bs.curr++;
- draw_buttons(widget, h-2, w, bs, true);
- wrefresh(widget);
- }
+ sel = (sel + 1) % 3;
break;
case KEY_UP:
- c[sel].value = c[sel].value < c[sel].max ? c[sel].value + 1 : 0;
+ c[sel].value = c[sel].value < c[sel].max ?
+ c[sel].value + 1 : 0;
break;
case KEY_DOWN:
- c[sel].value = c[sel].value > 0 ? c[sel].value - 1 : c[sel].max;
+ c[sel].value = c[sel].value > 0 ?
+ c[sel].value - 1 : c[sel].max;
break;
case KEY_F(1):
if (conf->f1_file == NULL && conf->f1_message == NULL)
break;
curs_set(0);
if (f1help(conf) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
curs_set(2);
- /* No break! the terminal size can change */
+ /* No break, screen size can change */
case KEY_RESIZE:
- hide_widget(y, x, h, w,conf->shadow);
-
- /*
- * Unnecessary, but, when the columns decrease the
- * following "refresh" seem not work
- */
+ /* Important for decreasing screen */
+ hide_widget(y, x, h, w, conf->shadow);
refresh();
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
- if (datetime_autosize(conf, rows, cols, &h, &w, MINWTIME, text, bs) != 0)
- return BSDDIALOG_ERROR;
- if (datetime_checksize(h, w, text, MINWTIME, bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
+ if (datetime_autosize(conf, rows, cols, &h, &w,
+ MINWTIME, text, bs) != 0)
+ return (BSDDIALOG_ERROR);
+ if (datetime_checksize(h, w, MINWTIME, bs) != 0)
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
-
- wclear(shadow);
- mvwin(shadow, y + t.shadow.h, x + t.shadow.w);
- wresize(shadow, h, w);
+ return (BSDDIALOG_ERROR);
- wclear(widget);
- mvwin(widget, y, x);
- wresize(widget, h, w);
+ if (update_dialog(conf, shadow, widget, y, x, h, w,
+ textpad, text, &bs, true) != 0)
+ return (BSDDIALOG_ERROR);
- htextpad = 1;
- wclear(textpad);
- wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2);
+ doupdate();
- if(update_widget_withtextpad(conf, shadow, widget, h, w,
- RAISED, textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
-
mvwaddch(widget, h - 5, w/2 - 3, ':');
mvwaddch(widget, h - 5, w/2 + 2, ':');
-
- draw_buttons(widget, h-2, w, bs, true);
-
wrefresh(widget);
prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2);
@@ -282,31 +237,30 @@ int bsddialog_timebox(struct bsddialog_conf *conf, char* text, int rows, int col
refresh();
break;
default:
- for (i = 0; i < (int) bs.nbuttons; i++)
- if (tolower(input) == tolower((bs.label[i])[0])) {
- output = bs.value[i];
- loop = false;
+ if (shortcut_buttons(input, &bs)) {
+ output = bs.value[bs.curr];
+ loop = false;
}
}
}
curs_set(0);
- for (i=0; i<3; i++)
+ for (i = 0; i < 3; i++)
delwin(c[i].win);
- end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
+ end_dialog(conf, shadow, widget, textpad);
- return output;
+ return (output);
}
int
-bsddialog_datebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
- unsigned int *yy, unsigned int *mm, unsigned int *dd)
+bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows,
+ int cols, unsigned int *yy, unsigned int *mm, unsigned int *dd)
{
+ bool loop;
+ int i, input, output, y, x, h, w, sel;
WINDOW *widget, *textpad, *shadow;
- int i, input, output, y, x, h, w, sel, htextpad;
struct buttons bs;
- bool loop;
struct calendar {
int max;
int value;
@@ -348,44 +302,41 @@ bsddialog_datebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
if (c[2].value > c[2].max)
c[2].value = c[2].max;
- get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label),
- BUTTONLABEL(cancel_label), BUTTONLABEL(help_label));
+ get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL);
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
- if (datetime_autosize(conf, rows, cols, &h, &w, MINWDATE, text, bs) != 0)
- return BSDDIALOG_ERROR;
- if (datetime_checksize(h, w, text, MINWDATE, bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
+ if (datetime_autosize(conf, rows, cols, &h, &w, MINWDATE, text,
+ bs) != 0)
+ return (BSDDIALOG_ERROR);
+ if (datetime_checksize(h, w, MINWDATE, bs) != 0)
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
-
- if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED,
- &textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
-
- draw_buttons(widget, h-2, w, bs, true);
+ return (BSDDIALOG_ERROR);
- wrefresh(widget);
+ if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs,
+ true) != 0)
+ return (BSDDIALOG_ERROR);
- prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2);
+ pnoutrefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2);
+ doupdate();
- c[0].win = new_boxed_window(conf, y + h - 6, x + w/2 - 11, 3, 6, LOWERED);
+ c[0].win = new_boxed_window(conf, y+h-6, x + w/2 - 11, 3, 6, LOWERED);
mvwaddch(widget, h - 5, w/2 - 5, '/');
- c[1].win = new_boxed_window(conf, y + h - 6, x + w/2 - 4, 3, 11, LOWERED);
+ c[1].win = new_boxed_window(conf, y+h-6, x + w/2 - 4, 3, 11, LOWERED);
mvwaddch(widget, h - 5, w/2 + 7, '/');
- c[2].win = new_boxed_window(conf, y + h - 6, x + w/2 + 8, 3, 4, LOWERED);
-
+ c[2].win = new_boxed_window(conf, y+h-6, x + w/2 + 8, 3, 4, LOWERED);
+
wrefresh(widget);
sel = 2;
curs_set(2);
loop = true;
- while(loop) {
+ while (loop) {
mvwprintw(c[0].win, 1, 1, "%4d", c[0].value);
mvwprintw(c[1].win, 1, 1, "%9s", m[c[1].value-1].name);
mvwprintw(c[2].win, 1, 1, "%2d", c[2].value);
- for (i=0; i<3; i++) {
+ for (i = 0; i < 3; i++) {
wrefresh(c[i].win);
}
wmove(c[sel].win, 1, c[sel].x);
@@ -404,28 +355,25 @@ bsddialog_datebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
loop = false;
break;
case 27: /* Esc */
- output = BSDDIALOG_ESC;
- loop = false;
+ if (conf->key.enable_esc) {
+ output = BSDDIALOG_ESC;
+ loop = false;
+ }
break;
case '\t': /* TAB */
- sel = (sel + 1) % 3;
+ bs.curr = (bs.curr + 1) % bs.nbuttons;
+ draw_buttons(widget, bs, true);
+ wrefresh(widget);
break;
case KEY_LEFT:
- if (bs.curr > 0) {
- bs.curr--;
- draw_buttons(widget, h-2, w, bs, true);
- wrefresh(widget);
- }
+ sel = sel == 0 ? 2 : (sel - 1);
break;
case KEY_RIGHT:
- if (bs.curr < (int) bs.nbuttons - 1) {
- bs.curr++;
- draw_buttons(widget, h-2, w, bs, true);
- wrefresh(widget);
- }
+ sel = (sel + 1) % 3;
break;
case KEY_UP:
- c[sel].value = c[sel].value > 1 ? c[sel].value - 1 : c[sel].max ;
+ c[sel].value = c[sel].value > 1 ?
+ c[sel].value - 1 : c[sel].max ;
/* if mount change */
c[2].max = m[c[1].value -1].days;
/* if year change */
@@ -436,7 +384,8 @@ bsddialog_datebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
c[2].value = c[2].max;
break;
case KEY_DOWN:
- c[sel].value = c[sel].value < c[sel].max ? c[sel].value + 1 : 1;
+ c[sel].value = c[sel].value < c[sel].max ?
+ c[sel].value + 1 : 1;
/* if mount change */
c[2].max = m[c[1].value -1].days;
/* if year change */
@@ -451,48 +400,31 @@ bsddialog_datebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
break;
curs_set(0);
if (f1help(conf) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
curs_set(2);
- /* No break! the terminal size can change */
+ /* No break, screen size can change */
case KEY_RESIZE:
- hide_widget(y, x, h, w,conf->shadow);
-
- /*
- * Unnecessary, but, when the columns decrease the
- * following "refresh" seem not work
- */
+ /* Important for decreasing screen */
+ hide_widget(y, x, h, w, conf->shadow);
refresh();
if (set_widget_size(conf, rows, cols, &h, &w) != 0)
- return BSDDIALOG_ERROR;
- if (datetime_autosize(conf, rows, cols, &h, &w, MINWDATE, text, bs) != 0)
- return BSDDIALOG_ERROR;
- if (datetime_checksize(h, w, text, MINWDATE, bs) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
+ if (datetime_autosize(conf, rows, cols, &h, &w,
+ MINWDATE, text, bs) != 0)
+ return (BSDDIALOG_ERROR);
+ if (datetime_checksize(h, w, MINWDATE, bs) != 0)
+ return (BSDDIALOG_ERROR);
if (set_widget_position(conf, &y, &x, h, w) != 0)
- return BSDDIALOG_ERROR;
+ return (BSDDIALOG_ERROR);
- wclear(shadow);
- mvwin(shadow, y + t.shadow.h, x + t.shadow.w);
- wresize(shadow, h, w);
+ if (update_dialog(conf, shadow, widget, y, x, h, w,
+ textpad, text, &bs, true) != 0)
+ return (BSDDIALOG_ERROR);
+ doupdate();
- wclear(widget);
- mvwin(widget, y, x);
- wresize(widget, h, w);
-
- htextpad = 1;
- wclear(textpad);
- wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2);
-
- if(update_widget_withtextpad(conf, shadow, widget, h, w,
- RAISED, textpad, &htextpad, text, true) != 0)
- return BSDDIALOG_ERROR;
-
mvwaddch(widget, h - 5, w/2 - 5, '/');
mvwaddch(widget, h - 5, w/2 + 7, '/');
-
- draw_buttons(widget, h-2, w, bs, true);
-
wrefresh(widget);
prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2);
@@ -516,19 +448,18 @@ bsddialog_datebox(struct bsddialog_conf *conf, char* text, int rows, int cols,
refresh();
break;
default:
- for (i = 0; i < (int) bs.nbuttons; i++)
- if (tolower(input) == tolower((bs.label[i])[0])) {
- output = bs.value[i];
- loop = false;
+ if (shortcut_buttons(input, &bs)) {
+ output = bs.value[bs.curr];
+ loop = false;
}
}
}
curs_set(0);
- for (i=0; i<3; i++)
+ for (i = 0; i < 3; i++)
delwin(c[i].win);
- end_widget_withtextpad(conf, widget, h, w, textpad, shadow);
+ end_dialog(conf, shadow, widget, textpad);
- return output;
-}
+ return (output);
+} \ No newline at end of file