summaryrefslogtreecommitdiffstats
path: root/gnu
diff options
context:
space:
mode:
Diffstat (limited to 'gnu')
-rw-r--r--gnu/usr.bin/dialog/COPYING339
-rw-r--r--gnu/usr.bin/dialog/Makefile11
-rw-r--r--gnu/usr.bin/dialog/README161
-rwxr-xr-xgnu/usr.bin/dialog/TESTS/checklist32
-rwxr-xr-xgnu/usr.bin/dialog/TESTS/infobox15
-rwxr-xr-xgnu/usr.bin/dialog/TESTS/inputbox26
-rwxr-xr-xgnu/usr.bin/dialog/TESTS/menubox33
-rwxr-xr-xgnu/usr.bin/dialog/TESTS/msgbox14
-rwxr-xr-xgnu/usr.bin/dialog/TESTS/textbox42
-rwxr-xr-xgnu/usr.bin/dialog/TESTS/yesno21
-rw-r--r--gnu/usr.bin/dialog/checklist.c349
-rw-r--r--gnu/usr.bin/dialog/colors.h219
-rw-r--r--gnu/usr.bin/dialog/dialog.1217
-rw-r--r--gnu/usr.bin/dialog/dialog.c545
-rw-r--r--gnu/usr.bin/dialog/dialog.h231
-rw-r--r--gnu/usr.bin/dialog/inputbox.c252
-rw-r--r--gnu/usr.bin/dialog/menubox.c310
-rw-r--r--gnu/usr.bin/dialog/msgbox.c81
-rw-r--r--gnu/usr.bin/dialog/radiolist.c353
-rw-r--r--gnu/usr.bin/dialog/rc.c375
-rw-r--r--gnu/usr.bin/dialog/rc.h223
-rw-r--r--gnu/usr.bin/dialog/textbox.c709
-rw-r--r--gnu/usr.bin/dialog/yesno.c113
23 files changed, 4671 insertions, 0 deletions
diff --git a/gnu/usr.bin/dialog/COPYING b/gnu/usr.bin/dialog/COPYING
new file mode 100644
index 0000000..a43ea21
--- /dev/null
+++ b/gnu/usr.bin/dialog/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/gnu/usr.bin/dialog/Makefile b/gnu/usr.bin/dialog/Makefile
new file mode 100644
index 0000000..47e7a38
--- /dev/null
+++ b/gnu/usr.bin/dialog/Makefile
@@ -0,0 +1,11 @@
+PROG= dialog
+MAN1= dialog.1
+
+CFLAGS+= -Wall -Wstrict-prototypes -DHAVE_NCURSES -DLOCALE
+DPADD= $(LIBNCURSES) $(LIBMYTINFO)
+LDADD= -lncurses -lmytinfo
+
+SRCS = dialog.c rc.c checklist.c inputbox.c menubox.c msgbox.c \
+radiolist.c textbox.c yesno.c
+
+.include "bsd.prog.mk"
diff --git a/gnu/usr.bin/dialog/README b/gnu/usr.bin/dialog/README
new file mode 100644
index 0000000..975bdac
--- /dev/null
+++ b/gnu/usr.bin/dialog/README
@@ -0,0 +1,161 @@
+
+ dialog - Display dialog boxes in shell script (version 0.3)
+ ===========================================================
+
+This is a program that will enable you to present a variety of questions or
+display messages using dialog boxes from a shell script. Currently, these
+types of dialog boxes are implemented: yes/no box, menu box, input box,
+message box, text box, info box, checklist box. The idea of writing this
+program came from the fact that most questions asked in a shell script (and
+many interactive programs as well) can be classified into these few types:
+
+
+ 1) One that requires the user to answer either yes or no.
+
+ 2) One that presents a number of options for the user to choose.
+
+ 3) One that requires the user to input a string.
+
+ 4) One that displays a message and optionally wait for a key press
+ before continuing.
+
+ 5) One that presents a list of options that can be turned on or off.
+
+
+The program 'dialog' can, say for example, be called in a shell script to
+present the first type of questions like this:
+
+
+ if dialog --yesno <question text> <height> <width>
+ then
+ ...
+ fi
+
+
+ e.g. if dialog --yesno "Do you want to continue?" 7 51
+ then
+ echo "Continuing..."
+ else
+ echo "Aborting..."
+ fi
+
+
+I've included a sample shell script for each type of boxes in the directory
+samples. The program requires ncurses to compile. Running 'dialog' without
+arguments will display the usage.
+
+
+
+FEATURES
+--------
+
+ * Friendly dialog box interface with buttons, etc.
+
+ * Auto wrap around of question text if it's too long to fit on
+ one line.
+
+ * "\n" can be inserted in question text to control line breaking
+ explicitly. The real newline character '\n' can also be used.
+
+ * run-time configruation of color settings and other options using
+ a configuration file.
+
+
+
+WHAT'S NEW SINCE VERSION 0.21?
+------------------------------
+
+ * some changes for faster screen update.
+
+ * much more flexible color settings. Can use all 16 colors
+ (8 normal, 8 highlight) of the Linux console.
+
+ * added run-time configuration using configuration file.
+
+ * some minor bug fixes and cleanups for menubox, checklist and
+ textbox.
+
+ * added a man page.
+
+ * some changes for easier porting to other Unix systems (tested
+ on Ultrix, SunOS and HPUX)
+
+
+
+INSTALLATION
+------------
+
+ 1. cd ./src
+
+ 2. Go to step 3 if your system has ncurses (e.g. Linux).
+ Edit Makefile and remove -DHAVE_NCURSES from DEFS. Also
+ remove rc.c from SRCS and rc.o from OBJS. Change LIBS as
+ appropriate (Usually, it should be '-lcurses -ltermcap').
+ Go to step 6.
+
+ 3. Edit Makefile and remove -DBROKEN_WSCRL from DEFS if you
+ are using ncurses 1.8.3 or newer. Menu scrolling should
+ be faster. DON'T REMOVE IT IF YOU ARE NOT USING AT LEAST
+ VERSION 1.8.3 OF NCURSES.
+
+ 4. Edit dialog.h and change USE_SHADOW to FALSE if you don't
+ want shadowed dialog boxes. Also change USE_COLORS to
+ FALSE if you don't want colors. Note that 'dialog' will
+ check if the terminal supports colors, and will use mono
+ settings if it doesn't, so USE_COLORS won't do any harm
+ even if you have a mono display. Also note that USE_SHADOW
+ implies USE_COLORS. These two options can be changed at
+ run-time using the run-time configuration file (see below).
+
+ 5. Edit colors.h to change default color definitions if you
+ don't like the defaults. These are only compiled in defaults,
+ you can change them at run-time using the run-time
+ configuration file.
+
+ 6. 'make depend; make install' will compile and install the
+ binaries in /usr/local/bin (change BINDIR in Makefile if
+ you want to install elsewhere).
+
+ 7. 'make install.man' will install the man page to
+ /usr/local/man (change MANDIR in Makefile if you want to
+ install elsewhere).
+
+ 8. You can then try the sample shell scripts in the samples
+ directory (make sure the environment variable DIALOG is
+ not set, the scripts use it to find the dialog binary, if
+ it's not set, "../src/dialog" will be used).
+
+ 9. Don't forget to mail me (mail address at end of this file)
+ if you find any bugs, have some good color settings to
+ contribute or just want to tell me that you like it, Don't
+ mail me if you don't like it :-)
+
+
+
+RUN-TIME CONFIGURATION
+----------------------
+
+ 1. Create a sample configuration file by typing:
+
+ "dialog --create-rc <file>"
+
+ 2. At start, 'dialog' determines the settings to use as follows:
+
+ a) if environment variable DIALOGRC is set, it's value
+ determines the name of the configuration file.
+
+ b) if the file in (a) can't be found, use the file
+ $HOME/.dialogrc as the configuration file.
+
+ c) if the file in (b) can't be found, use compiled in
+ defaults.
+
+ 3. Edit the sample configuration file and copy it to some place
+ that 'dialog' can find, as stated in step 2 above.
+
+
+
+
+Comments and bug reports welcome.
+
+- Savio Lam (lam836@cs.cuhk.hk)
diff --git a/gnu/usr.bin/dialog/TESTS/checklist b/gnu/usr.bin/dialog/TESTS/checklist
new file mode 100755
index 0000000..38fdc35
--- /dev/null
+++ b/gnu/usr.bin/dialog/TESTS/checklist
@@ -0,0 +1,32 @@
+#!/bin/sh
+DIALOG=${DIALOG=/usr/bin/dialog}
+
+$DIALOG --title "CHECKLIST BOX" --clear \
+ --checklist "Hi, this is a checklist box. You can use this to \n\
+present a list of choices which can be turned on or \n\
+off. If there are more items than can fit on the \n\
+screen, the list will be scrolled. You can use the \n\
+UP/DOWN arrow keys, the first letter of the choice as a \n\
+hot key, or the number keys 1-9 to choose an option. \n\
+Press SPACE to toggle an option on/off. \n\n\
+ Which of the following are fruits?" 20 61 5 \
+ "Apple" "It's an apple." off \
+ "Dog" "No, that's not my dog." ON \
+ "Orange" "Yeah, that's juicy." off \
+ "Cat" "No, never put a dog and a cat together!" oN \
+ "Fish" "Cats like fish." On \
+ "Lemon" "You know how it tastes." on 2> /tmp/checklist.tmp.$$
+
+retval=$?
+
+choice=`cat /tmp/checklist.tmp.$$`
+rm -f /tmp/checklist.tmp.$$
+
+case $retval in
+ 0)
+ echo "'$choice' chosen.";;
+ 1)
+ echo "Cancel pressed.";;
+ 255)
+ echo "ESC pressed.";;
+esac
diff --git a/gnu/usr.bin/dialog/TESTS/infobox b/gnu/usr.bin/dialog/TESTS/infobox
new file mode 100755
index 0000000..764dc08
--- /dev/null
+++ b/gnu/usr.bin/dialog/TESTS/infobox
@@ -0,0 +1,15 @@
+#!/bin/sh
+DIALOG=${DIALOG=/usr/bin/dialog}
+
+$DIALOG --title "INFO BOX" \
+ --infobox "Hi, this is an information box. It is
+different from a message box in that it will
+not pause waiting for input after displaying
+the message. The pause here is only introduced
+by the sleep command, not by dialog.
+
+You have 10 seconds to read this..." 10 52
+
+stty -echo
+sleep 10
+stty echo
diff --git a/gnu/usr.bin/dialog/TESTS/inputbox b/gnu/usr.bin/dialog/TESTS/inputbox
new file mode 100755
index 0000000..e04756a
--- /dev/null
+++ b/gnu/usr.bin/dialog/TESTS/inputbox
@@ -0,0 +1,26 @@
+#!/bin/sh
+DIALOG=${DIALOG=/usr/bin/dialog}
+
+$DIALOG --title "INPUT BOX" --clear \
+ --inputbox "Hi, this is an input dialog box. You can use \n\
+this to ask questions that require the user \n\
+to input a string as the answer. You can \n\
+input strings of length longer than the \n\
+width of the input box, in that case, the \n\
+input field will be automatically scrolled. \n\
+You can use BACKSPACE to correct errors. \n\n\
+Try inputing your name below:" 16 51 2> /tmp/inputbox.tmp.$$
+
+retval=$?
+
+input=`cat /tmp/inputbox.tmp.$$`
+rm -f /tmp/inputbox.tmp.$$
+
+case $retval in
+ 0)
+ echo "Input string is '$input'";;
+ 1)
+ echo "Cancel pressed.";;
+ 255)
+ echo "ESC pressed.";;
+esac
diff --git a/gnu/usr.bin/dialog/TESTS/menubox b/gnu/usr.bin/dialog/TESTS/menubox
new file mode 100755
index 0000000..4883c7c
--- /dev/null
+++ b/gnu/usr.bin/dialog/TESTS/menubox
@@ -0,0 +1,33 @@
+#!/bin/sh
+DIALOG=${DIALOG=/usr/bin/dialog}
+
+$DIALOG --clear --title "MENU BOX" \
+ --menu "Hi, this is a menu box. You can use this to \n\
+present a list of choices for the user to \n\
+choose. If there are more items than can fit \n\
+on the screen, the menu will be scrolled. \n\
+You can use the UP/DOWN arrow keys, the first \n\
+letter of the choice as a hot key, or the \n\
+number keys 1-9 to choose an option.\n\
+Try it now!\n\n\
+ Choose the OS you like:" 20 59 4 \
+ "FreeBSD 2.0" "A Real Operating System for Real Users" \
+ "Linux" "Another free Unix Clone for 386/486" \
+ "OS/2" "IBM OS/2" \
+ "WIN NT" "Microsoft Windows NT" \
+ "PCDOS" "IBM PC DOS" \
+ "MSDOS" "Microsoft DOS" 2> /tmp/menu.tmp.$$
+
+retval=$?
+
+choice=`cat /tmp/menu.tmp.$$`
+rm -f /tmp/menu.tmp.$$
+
+case $retval in
+ 0)
+ echo "'$choice' chosen.";;
+ 1)
+ echo "Cancel pressed.";;
+ 255)
+ echo "ESC pressed.";;
+esac
diff --git a/gnu/usr.bin/dialog/TESTS/msgbox b/gnu/usr.bin/dialog/TESTS/msgbox
new file mode 100755
index 0000000..58dae15
--- /dev/null
+++ b/gnu/usr.bin/dialog/TESTS/msgbox
@@ -0,0 +1,14 @@
+#!/bin/sh
+DIALOG=${DIALOG=/usr/bin/dialog}
+
+$DIALOG --title "MESSAGE BOX" --clear \
+ --msgbox "Hi, this is a simple message box. You can use this to \
+ display any message you like. The box will remain until \
+ you press the ENTER key." 10 41
+
+case $? in
+ 0)
+ echo "OK";;
+ 255)
+ echo "ESC pressed.";;
+esac
diff --git a/gnu/usr.bin/dialog/TESTS/textbox b/gnu/usr.bin/dialog/TESTS/textbox
new file mode 100755
index 0000000..ed7c2d9
--- /dev/null
+++ b/gnu/usr.bin/dialog/TESTS/textbox
@@ -0,0 +1,42 @@
+#!/bin/sh
+DIALOG=${DIALOG=/usr/bin/dialog}
+
+cat << EOF > /tmp/textbox.tmp.$$
+Hi, this is a text dialog box. It can be used to display text from a file.
+The file should not contain any 'tab' characters, so you should 'expand'
+the file first if it contains 'tab' characters.
+
+It's like a simple text file viewer, with these keys implemented:
+
+PGDN/SPACE - Move down one page
+PGUP/'b' - Move up one page
+DOWN/'j' - Move down one line
+UP/'k' - Move up one line
+LEFT/'h' - Scroll left
+RIGHT/'l' - Scroll right
+'0' - Move to beginning of line
+HOME/'g' - Move to beginning of file
+END/'G' - Move to end of file
+'/' - Forward search
+'?' - Backward search
+'n' - Repeat last search (forward)
+'N' - Repeat last search (backward)
+
+
+The following is a sample text file:
+
+
+EOF
+
+cat ../COPYING | expand >> /tmp/textbox.tmp.$$
+
+$DIALOG --clear --title "TEXT BOX" --textbox "/tmp/textbox.tmp.$$" 22 77
+
+case $? in
+ 0)
+ echo "OK";;
+ 255)
+ echo "EXIT choosed.";;
+esac
+
+rm -f /tmp/textbox.tmp.$$
diff --git a/gnu/usr.bin/dialog/TESTS/yesno b/gnu/usr.bin/dialog/TESTS/yesno
new file mode 100755
index 0000000..2282893
--- /dev/null
+++ b/gnu/usr.bin/dialog/TESTS/yesno
@@ -0,0 +1,21 @@
+#!/bin/sh
+DIALOG=${DIALOG=/usr/bin/dialog}
+
+$DIALOG --title "YES/NO BOX" --clear \
+ --yesno "Hi, this is a yes/no dialog box. You can use this to ask \
+ questions that have an answer of either yes or no. \
+ BTW, do you notice that long lines will be automatically \
+ wrapped around so that they can fit in the box? You can \
+ also control line breaking explicitly by inserting \
+ 'backslash n' at any place you like, but in this case, \
+ auto wrap around will be disabled and you will have to \
+ control line breaking yourself." 15 61
+
+case $? in
+ 0)
+ echo "Yes chosen.";;
+ 1)
+ echo "No chosen.";;
+ 255)
+ echo "ESC pressed.";;
+esac
diff --git a/gnu/usr.bin/dialog/checklist.c b/gnu/usr.bin/dialog/checklist.c
new file mode 100644
index 0000000..f522ae1
--- /dev/null
+++ b/gnu/usr.bin/dialog/checklist.c
@@ -0,0 +1,349 @@
+/*
+ * checklist.c -- implements the checklist box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "dialog.h"
+
+
+static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int status, int choice, int selected);
+
+
+static int list_width, check_x, item_x;
+
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ */
+int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int item_no, unsigned char **items)
+{
+ int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
+ scroll = 0, max_choice, *status;
+ WINDOW *dialog, *list;
+
+ /* Allocate space for storing item on/off status */
+ if ((status = malloc(sizeof(int)*item_no)) == NULL) {
+ endwin();
+ fprintf(stderr, "\nCan't allocate memory in dialog_checklist().\n");
+ exit(-1);
+ }
+ /* Initializes status */
+ for (i = 0; i < item_no; i++)
+ status[i] = !strcasecmp(items[i*3 + 2], "on");
+
+ max_choice = MIN(list_height, item_no);
+
+ /* center dialog box on screen */
+ x = (COLS - width)/2;
+ y = (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ keypad(dialog, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ wattrset(dialog, dialog_attr);
+ print_autowrap(dialog, prompt, width, 1, 3);
+
+ list_width = width-6;
+ getyx(dialog, cur_y, cur_x);
+ box_y = cur_y + 1;
+ box_x = (width - list_width)/2 - 1;
+
+ /* create new window for the list */
+ list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
+ keypad(list, TRUE);
+
+ /* draw a box around the list items */
+ draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr);
+
+ check_x = 0;
+ item_x = 0;
+ /* Find length of longest item in order to center checklist */
+ for (i = 0; i < item_no; i++) {
+ check_x = MAX(check_x, strlen(items[i*3]) + strlen(items[i*3 + 1]) + 6);
+ item_x = MAX(item_x, strlen(items[i*3]));
+ }
+ check_x = (list_width - check_x) / 2;
+ item_x = check_x + item_x + 6;
+
+ /* Print the list */
+ for (i = 0; i < max_choice; i++)
+ print_item(list, items[i*3], items[i*3 + 1], status[i], i, i == choice);
+ wnoutrefresh(list);
+
+ if (list_height < item_no) {
+ wattrset(dialog, darrow_attr);
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
+ waddch(dialog, ACS_DARROW);
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
+ waddstr(dialog, "(+)");
+ }
+
+ x = width/2-11;
+ y = height-2;
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+ wrefresh(dialog);
+
+ while (key != ESC) {
+ key = wgetch(dialog);
+ /* Check if key pressed matches first character of any item tag in list */
+ for (i = 0; i < max_choice; i++)
+ if (key < 0x100 && toupper(key) == toupper(items[(scroll+i)*3][0]))
+ break;
+
+ if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) ||
+ key == KEY_UP || key == KEY_DOWN || key == ' ' ||
+ key == '+' || key == '-' ) {
+ if (key >= '1' && key <= MIN('9', '0'+max_choice))
+ i = key - '1';
+ else if (key == KEY_UP || key == '-') {
+ if (!choice) {
+ if (scroll) {
+#ifdef BROKEN_WSCRL
+ /* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
+ violation when scrolling windows of height = 4, so scrolling is not
+ used for now */
+ scroll--;
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ /* Reprint list to scroll down */
+ for (i = 0; i < max_choice; i++)
+ print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice);
+
+#else
+
+ /* Scroll list down */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ if (list_height > 1) {
+ /* De-highlight current first item before scrolling down */
+ print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, FALSE);
+ scrollok(list, TRUE);
+ wscrl(list, -1);
+ scrollok(list, FALSE);
+ }
+ scroll--;
+ print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE);
+#endif
+ wnoutrefresh(list);
+
+ /* print the up/down arrows */
+ wmove(dialog, box_y, box_x + check_x + 5);
+ wattrset(dialog, scroll ? uarrow_attr : menubox_attr);
+ waddch(dialog, scroll ? ACS_UARROW : ACS_HLINE);
+ wmove(dialog, box_y, box_x + check_x + 6);
+ waddch(dialog, scroll ? '(' : ACS_HLINE);
+ wmove(dialog, box_y, box_x + check_x + 7);
+ waddch(dialog, scroll ? '-' : ACS_HLINE);
+ wmove(dialog, box_y, box_x + check_x + 8);
+ waddch(dialog, scroll ? ')' : ACS_HLINE);
+ wattrset(dialog, darrow_attr);
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
+ waddch(dialog, ACS_DARROW);
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
+ waddch(dialog, '(');
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 7);
+ waddch(dialog, '+');
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 8);
+ waddch(dialog, ')');
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice - 1;
+ }
+ else if (key == KEY_DOWN || key == '+') {
+ if (choice == max_choice - 1) {
+ if (scroll+choice < item_no-1) {
+#ifdef BROKEN_WSCRL
+ /* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
+ violation when scrolling windows of height = 4, so scrolling is not
+ used for now */
+ scroll++;
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ /* Reprint list to scroll up */
+ for (i = 0; i < max_choice; i++)
+ print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice);
+
+#else
+
+ /* Scroll list up */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ if (list_height > 1) {
+ /* De-highlight current last item before scrolling up */
+ print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1], status[scroll+max_choice-1], max_choice-1, FALSE);
+ scrollok(list, TRUE);
+ scroll(list);
+ scrollok(list, FALSE);
+ }
+ scroll++;
+ print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1], status[scroll+max_choice-1], max_choice-1, TRUE);
+#endif
+ wnoutrefresh(list);
+
+ /* print the up/down arrows */
+ wattrset(dialog, uarrow_attr);
+ wmove(dialog, box_y, box_x + check_x + 5);
+ waddch(dialog, ACS_UARROW);
+ wmove(dialog, box_y, box_x + check_x + 6);
+ waddstr(dialog, "(-)");
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
+ wattrset(dialog, scroll+choice < item_no-1 ? darrow_attr : menubox_border_attr);
+ waddch(dialog, scroll+choice < item_no-1 ? ACS_DARROW : ACS_HLINE);
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
+ waddch(dialog, scroll+choice < item_no-1 ? '(' : ACS_HLINE);
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 7);
+ waddch(dialog, scroll+choice < item_no-1 ? '+' : ACS_HLINE);
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 8);
+ waddch(dialog, scroll+choice < item_no-1 ? ')' : ACS_HLINE);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice + 1;
+ }
+ else if (key == ' ') { /* Toggle item status */
+ status[scroll+choice] = !status[scroll+choice];
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ wmove(list, choice, check_x);
+ wattrset(list, check_selected_attr);
+ wprintw(list, "[%c]", status[scroll+choice] ? 'X' : ' ');
+ wnoutrefresh(list);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ continue; /* wait for another key press */
+ }
+
+ if (i != choice) {
+ /* De-highlight current item */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, FALSE);
+
+ /* Highlight new item */
+ choice = i;
+ print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, TRUE);
+ wnoutrefresh(list);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+
+ switch (key) {
+ case 'O':
+ case 'o':
+ delwin(dialog);
+ for (i = 0; i < item_no; i++)
+ if (status[i])
+ fprintf(stderr, "\"%s\" ", items[i*3]);
+ free(status);
+ return 0;
+ case 'C':
+ case 'c':
+ delwin(dialog);
+ free(status);
+ return 1;
+ case TAB:
+ case KEY_BTAB:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ if (!button) {
+ button = 1; /* Indicates "Cancel" button is selected */
+ print_button(dialog, " OK ", y, x, FALSE);
+ print_button(dialog, "Cancel", y, x+14, TRUE);
+ }
+ else {
+ button = 0; /* Indicates "OK" button is selected */
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+ }
+ wrefresh(dialog);
+ break;
+ case ' ':
+ case '\n':
+ delwin(dialog);
+ if (!button)
+ for (i = 0; i < item_no; i++)
+ if (status[i])
+ fprintf(stderr, "\"%s\" ", items[i*3]);
+ free(status);
+ return button;
+ case ESC:
+ break;
+ }
+ }
+
+ delwin(dialog);
+ free(status);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_checklist() */
+
+
+/*
+ * Print list item
+ */
+static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int status, int choice, int selected)
+{
+ int i;
+
+ /* Clear 'residue' of last item */
+ wattrset(win, menubox_attr);
+ wmove(win, choice, 0);
+ for (i = 0; i < list_width; i++)
+ waddch(win, ' ');
+ wmove(win, choice, check_x);
+ wattrset(win, selected ? check_selected_attr : check_attr);
+ wprintw(win, "[%c]", status ? 'X' : ' ');
+ wattrset(win, menubox_attr);
+ waddch(win, ' ');
+ wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
+ waddch(win, tag[0]);
+ wattrset(win, selected ? tag_selected_attr : tag_attr);
+ waddstr(win, tag + 1);
+ wmove(win, choice, item_x);
+ wattrset(win, selected ? item_selected_attr : item_attr);
+ waddstr(win, item);
+}
+/* End of print_item() */
diff --git a/gnu/usr.bin/dialog/colors.h b/gnu/usr.bin/dialog/colors.h
new file mode 100644
index 0000000..7cea0a0
--- /dev/null
+++ b/gnu/usr.bin/dialog/colors.h
@@ -0,0 +1,219 @@
+/*
+ * colors.h -- color attribute definitions
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * Default color definitions
+ *
+ * *_FG = foreground
+ * *_BG = background
+ * *_HL = highlight?
+ */
+#define SCREEN_FG COLOR_CYAN
+#define SCREEN_BG COLOR_BLUE
+#define SCREEN_HL TRUE
+
+#define SHADOW_FG COLOR_BLACK
+#define SHADOW_BG COLOR_BLACK
+#define SHADOW_HL TRUE
+
+#define DIALOG_FG COLOR_BLACK
+#define DIALOG_BG COLOR_WHITE
+#define DIALOG_HL FALSE
+
+#define TITLE_FG COLOR_YELLOW
+#define TITLE_BG COLOR_WHITE
+#define TITLE_HL TRUE
+
+#define BORDER_FG COLOR_WHITE
+#define BORDER_BG COLOR_WHITE
+#define BORDER_HL TRUE
+
+#define BUTTON_ACTIVE_FG COLOR_WHITE
+#define BUTTON_ACTIVE_BG COLOR_BLUE
+#define BUTTON_ACTIVE_HL TRUE
+
+#define BUTTON_INACTIVE_FG COLOR_BLACK
+#define BUTTON_INACTIVE_BG COLOR_WHITE
+#define BUTTON_INACTIVE_HL FALSE
+
+#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE
+#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE
+#define BUTTON_KEY_ACTIVE_HL TRUE
+
+#define BUTTON_KEY_INACTIVE_FG COLOR_RED
+#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE
+#define BUTTON_KEY_INACTIVE_HL FALSE
+
+#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW
+#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE
+#define BUTTON_LABEL_ACTIVE_HL TRUE
+
+#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK
+#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE
+#define BUTTON_LABEL_INACTIVE_HL TRUE
+
+#define INPUTBOX_FG COLOR_BLACK
+#define INPUTBOX_BG COLOR_WHITE
+#define INPUTBOX_HL FALSE
+
+#define INPUTBOX_BORDER_FG COLOR_BLACK
+#define INPUTBOX_BORDER_BG COLOR_WHITE
+#define INPUTBOX_BORDER_HL FALSE
+
+#define SEARCHBOX_FG COLOR_BLACK
+#define SEARCHBOX_BG COLOR_WHITE
+#define SEARCHBOX_HL FALSE
+
+#define SEARCHBOX_TITLE_FG COLOR_YELLOW
+#define SEARCHBOX_TITLE_BG COLOR_WHITE
+#define SEARCHBOX_TITLE_HL TRUE
+
+#define SEARCHBOX_BORDER_FG COLOR_WHITE
+#define SEARCHBOX_BORDER_BG COLOR_WHITE
+#define SEARCHBOX_BORDER_HL TRUE
+
+#define POSITION_INDICATOR_FG COLOR_YELLOW
+#define POSITION_INDICATOR_BG COLOR_WHITE
+#define POSITION_INDICATOR_HL TRUE
+
+#define MENUBOX_FG COLOR_BLACK
+#define MENUBOX_BG COLOR_WHITE
+#define MENUBOX_HL FALSE
+
+#define MENUBOX_BORDER_FG COLOR_WHITE
+#define MENUBOX_BORDER_BG COLOR_WHITE
+#define MENUBOX_BORDER_HL TRUE
+
+#define ITEM_FG COLOR_BLACK
+#define ITEM_BG COLOR_WHITE
+#define ITEM_HL FALSE
+
+#define ITEM_SELECTED_FG COLOR_WHITE
+#define ITEM_SELECTED_BG COLOR_BLUE
+#define ITEM_SELECTED_HL TRUE
+
+#define TAG_FG COLOR_YELLOW
+#define TAG_BG COLOR_WHITE
+#define TAG_HL TRUE
+
+#define TAG_SELECTED_FG COLOR_YELLOW
+#define TAG_SELECTED_BG COLOR_BLUE
+#define TAG_SELECTED_HL TRUE
+
+#define TAG_KEY_FG COLOR_RED
+#define TAG_KEY_BG COLOR_WHITE
+#define TAG_KEY_HL TRUE
+
+#define TAG_KEY_SELECTED_FG COLOR_RED
+#define TAG_KEY_SELECTED_BG COLOR_BLUE
+#define TAG_KEY_SELECTED_HL TRUE
+
+#define CHECK_FG COLOR_BLACK
+#define CHECK_BG COLOR_WHITE
+#define CHECK_HL FALSE
+
+#define CHECK_SELECTED_FG COLOR_WHITE
+#define CHECK_SELECTED_BG COLOR_BLUE
+#define CHECK_SELECTED_HL TRUE
+
+#define UARROW_FG COLOR_GREEN
+#define UARROW_BG COLOR_WHITE
+#define UARROW_HL TRUE
+
+#define DARROW_FG COLOR_GREEN
+#define DARROW_BG COLOR_WHITE
+#define DARROW_HL TRUE
+
+/* End of default color definitions */
+
+#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
+#define COLOR_NAME_LEN 10
+#define COLOR_COUNT 8
+
+
+/*
+ * Global variables
+ */
+
+typedef struct {
+ unsigned char name[COLOR_NAME_LEN];
+ int value;
+} color_names_st;
+
+
+#ifdef __DIALOG_MAIN__
+
+/*
+ * For matching color names with color values
+ */
+color_names_st color_names[] = {
+ {"BLACK", COLOR_BLACK},
+ {"RED", COLOR_RED},
+ {"GREEN", COLOR_GREEN},
+ {"YELLOW", COLOR_YELLOW},
+ {"BLUE", COLOR_BLUE},
+ {"MAGENTA", COLOR_MAGENTA},
+ {"CYAN", COLOR_CYAN},
+ {"WHITE", COLOR_WHITE},
+}; /* color names */
+
+
+/*
+ * Table of color values
+ */
+int color_table[][3] = {
+ {SCREEN_FG, SCREEN_BG, SCREEN_HL },
+ {SHADOW_FG, SHADOW_BG, SHADOW_HL },
+ {DIALOG_FG, DIALOG_BG, DIALOG_HL },
+ {TITLE_FG, TITLE_BG, TITLE_HL },
+ {BORDER_FG, BORDER_BG, BORDER_HL },
+ {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL },
+ {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL },
+ {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL },
+ {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL },
+ {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL },
+ {BUTTON_LABEL_INACTIVE_FG,BUTTON_LABEL_INACTIVE_BG,BUTTON_LABEL_INACTIVE_HL},
+ {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL },
+ {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL },
+ {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL },
+ {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL },
+ {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL },
+ {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL },
+ {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL },
+ {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL },
+ {ITEM_FG, ITEM_BG, ITEM_HL },
+ {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL },
+ {TAG_FG, TAG_BG, TAG_HL },
+ {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL },
+ {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL },
+ {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL },
+ {CHECK_FG, CHECK_BG, CHECK_HL },
+ {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL },
+ {UARROW_FG, UARROW_BG, UARROW_HL },
+ {DARROW_FG, DARROW_BG, DARROW_HL },
+}; /* color_table */
+
+#else
+
+extern color_names_st color_names[];
+extern int color_table[][3];
+
+#endif /* __DIALOG_MAIN__ */
diff --git a/gnu/usr.bin/dialog/dialog.1 b/gnu/usr.bin/dialog/dialog.1
new file mode 100644
index 0000000..3ab1119
--- /dev/null
+++ b/gnu/usr.bin/dialog/dialog.1
@@ -0,0 +1,217 @@
+.TH DIALOG 1 "10 January 1994"
+.SH NAME
+dialog \- display dialog boxes from shell scripts
+.SH SYNOPSIS
+.B dialog --clear
+.br
+.BI "dialog --create-rc " file
+.br
+.B dialog
+[
+.B \-\-title
+.I title
+]
+[
+.B \-\-clear
+]
+.B box-options
+.SH DESCRIPTION
+.B Dialog
+is a program that will let you to present a variety of questions or
+display messages using dialog boxes from a shell script. Currently,
+these types of dialog boxes are implemented:
+.LP
+.BR yes/no " box," " menu" " box," " input" " box,"
+.BR message " box," " text" " box," " info" " box, and"
+.BR checklist " box."
+.SH OPTIONS
+.TP
+.B \-\-clear
+The screen will be cleared to the
+.BR "screen attribute" " on exit."
+.TP
+.BI \-\-create-rc " file"
+.RB "Since " dialog " supports run-time configuration,"
+this can be used to dump a sample configuration file to the file specified
+by
+.IR file "."
+.TP
+.BI \-\-title " title"
+Specifies a
+.I title
+string to be displayed at the top of the dialog box.
+.TP
+.B Box Options
+.TP
+.BI \-\-yesno " text height width"
+.RB A " yes/no" " dialog box of size"
+.I height
+rows by
+.I width
+columns will be displayed. The string specified by
+.I text
+is displayed inside the dialog box. If this string is too long to be fitted
+in one line, it will be automatically divided into multiple lines at
+appropriate places. The
+.I text
+string may also contain the sub-string
+.I
+"\en"
+or newline characters
+.I `\en\'
+to control line breaking explicitly. This dialog box is useful for
+asking questions that require the user to answer either yes or no.
+.RB "The dialog box has a" " Yes" " button and a " No
+button, in which the user can switch between by pressing the
+.IR TAB " key."
+.TP
+.BI \-\-msgbox " text height width"
+.RB A " message" " box is very similar to a" " yes/no" " box."
+The only difference between a
+.B message
+box and a
+.B yes/no
+box is that a
+.B message
+box has only a single
+.B OK
+button. You can use this dialog box to display any message you like.
+After reading the message, the user can press the
+.I ENTER
+key so that
+.B dialog
+will exit and the calling shell script can continue its operation.
+.TP
+.BI \-\-infobox " text height width"
+.RB An " info" " box is basically a" " message" " box."
+However, in this case,
+.B dialog
+will exit immediately after displaying the message to the user. The
+screen is not cleared when
+.B dialog
+exits, so that the message will remain on the screen until the calling
+shell script clears it later. This is useful when you want to inform
+the user that some operations are carrying on that may require some
+time to finish.
+.TP
+.BI \-\-inputbox " text height width"
+.RB "An " input " box is useful when you want to ask questions that"
+require the user to input a string as the answer. When inputing the
+string, the
+.I BACKSPACE
+key can be used to correct typing errors. If the input string is longer than
+can be fitted in the dialog box, the input field will be scrolled. On exit,
+the input string will be printed on
+.IR stderr "."
+.TP
+.BI \-\-textbox " file height width"
+.RB A " text" " box lets you display the contents of a text file in a"
+dialog box. It is like a simple text file viewer. The user can move
+through the file by using the
+.IR UP/DOWN ", " PGUP/PGDN
+.RI and " HOME/END" " keys available on most keyboards."
+If the lines are too long to be displayed in the box, the
+.I LEFT/RIGHT
+keys can be used to scroll the text region horizontally. For more
+convenience, forward and backward searching functions are also provided.
+.IP "\fB\-\-menu \fItext height width menu-height \fR[ \fItag item \fR] \fI..."
+As its name suggests, a
+.B menu
+box is a dialog box that can be used to present a list of choices in
+the form of a menu for the user to choose. Each menu entry consists of a
+.IR tag " string and an " item " string. The"
+.I tag
+gives the entry a name to distinguish it from the other entries in the
+menu. The
+.I item
+is a short description of the option that the entry represents. The
+user can move between the menu entries by pressing the
+.I UP/DOWN
+keys, the first letter of the
+.I tag
+as a hot-key, or the number keys
+.IR 1-9 ". There are"
+.I menu-height
+entries displayed in the menu at one time, but the menu will be
+scrolled if there are more entries than that. When
+.B dialog
+exits, the
+.I tag
+of the chosen menu entry will be printed on
+.IR stderr "."
+.IP "\fB\-\-checklist \fItext height width list-height \fR[ \fItag item status \fR] \fI..."
+.RB "A " checklist " box is similar to a " menu " box in that there are"
+multiple entries presented in the form of a menu. Instead of choosing
+one entry among the entries, each entry can be turned on or off by the
+user. The initial on/off state of each entry is specified by
+.IR status "."
+On exit, a list of the
+.I tag
+strings of those entries that are turned on will be printed on
+.IR stderr "."
+.SH "RUN-TIME CONFIGURATION"
+.TP 4
+1.
+Create a sample configuration file by typing:
+.LP
+.in +1i
+"dialog --create-rc <file>"
+.TP 4
+2.
+At start,
+.B dialog
+determines the settings to use as follows:
+.RS
+.TP 4
+a)
+if environment variable
+.B DIALOGRC
+is set, it's value determines the name of the configuration file.
+.TP 4
+b)
+if the file in (a) can't be found, use the file
+.I $HOME/.dialogrc
+as the configuration file.
+.TP 4
+c)
+if the file in (b) can't be found, use compiled in defaults.
+.RE
+.TP 4
+3.
+Edit the sample configuration file and copy it to some place that
+.B dialog
+can find, as stated in step 2 above.
+.SH ENVIROMENT
+.TP 15
+.B DIALOGRC
+Define this variable if you want to specify the name of the configuration file
+to use.
+.SH FILES
+.TP 20
+.I $HOME/.dialogrc
+default configuration file
+.SH DIAGNOSTICS
+Exit status is 0 if
+.BR dialog " is exited by pressing the " Yes " or " OK
+button, and 1 if the
+.BR No " or " Cancel
+button is pressed. Otherwise, if errors occur inside
+.B dialog
+or
+.B dialog
+is exited by pressing the
+.I ESC
+key, the exit status is -1.
+.SH BUGS
+Text files containing
+.I tab
+characters may cause problems with
+.B text
+box.
+.I Tab
+characters in text files must first be expanded to spaces before being
+.RB "displayed by " text " box."
+.TP
+Screen update is too slow.
+.SH AUTHOR
+Savio Lam (lam836@cs.cuhk.hk)
diff --git a/gnu/usr.bin/dialog/dialog.c b/gnu/usr.bin/dialog/dialog.c
new file mode 100644
index 0000000..1d710bd
--- /dev/null
+++ b/gnu/usr.bin/dialog/dialog.c
@@ -0,0 +1,545 @@
+/*
+ * dialog - Display simple dialog boxes from shell scripts
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * HISTORY:
+ *
+ * 17/12/93 - Version 0.1 released.
+ *
+ * 19/12/93 - menu will now scroll if there are more items than can fit
+ * on the screen.
+ * - added 'checklist', a dialog box with a list of options that
+ * can be turned on or off. A list of options that are on is
+ * returned on exit.
+ *
+ * 20/12/93 - Version 0.15 released.
+ *
+ * 29/12/93 - Incorporated patch from Patrick J. Volkerding
+ * (volkerdi@mhd1.moorhead.msus.edu) that made these changes:
+ * - increased MAX_LEN to 2048
+ * - added 'infobox', equivalent to a message box without pausing
+ * - added option '--clear' that will clear the screen
+ * - Explicit line breaking when printing prompt text can be
+ * invoked by real newline '\n' besides the string "\n"
+ * - an optional parameter '--title <string>' can be used to
+ * specify a title string for the dialog box
+ *
+ * 03/01/94 - added 'textbox', a dialog box for displaying text from a file.
+ * - Version 0.2 released.
+ *
+ * 04/01/94 - some fixes and improvements for 'textbox':
+ * - fixed a bug that will cause a segmentation violation when a
+ * line is longer than MAX_LEN characters. Lines will now be
+ * truncated if they are longer than MAX_LEN characters.
+ * - removed wrefresh() from print_line(). This will increase
+ * efficiency of print_page() which calls print_line().
+ * - display current position in the form of percentage into file.
+ * - Version 0.21 released.
+ *
+ * 05/01/94 - some changes for faster screen update.
+ *
+ * 07/01/94 - much more flexible color settings. Can use all 16 colors
+ * (8 normal, 8 highlight) of the Linux console.
+ *
+ * 08/01/94 - added run-time configuration using configuration file.
+ *
+ * 09/01/94 - some minor bug fixes and cleanups for menubox, checklist and
+ * textbox.
+ *
+ * 11/01/94 - added a man page.
+ *
+ * 13/01/94 - some changes for easier porting to other Unix systems (tested
+ * on Ultrix, SunOS and HPUX)
+ * - Version 0.3 released.
+ *
+ * 08/06/94 - Patches by Stuart Herbert - S.Herbert@shef.ac.uk
+ * Fixed attr_clear and the textbox stuff to work with ncurses 1.8.5
+ * Fixed the wordwrap routine - it'll actually wrap properly now
+ * Added a more 3D look to everything - having your own rc file could
+ * prove 'interesting' to say the least :-)
+ * Added radiolist option
+ * - Version 0.4 released.
+ */
+
+
+#define __DIALOG_MAIN__
+
+
+#include "dialog.h"
+#ifdef HAVE_NCURSES
+#include "colors.h"
+#endif
+
+
+int main(int argc, unsigned char *argv[])
+{
+ int offset = 0, clear_screen = 0, end_common_opts = 0, retval;
+ unsigned char *title = NULL;
+
+#if defined(LOCALE)
+ (void) setlocale(LC_ALL, "");
+#endif
+
+ if (argc < 2) {
+ Usage(argv[0]);
+ exit(-1);
+ }
+ else if (!strcmp(argv[1], "--create-rc")) {
+#ifdef HAVE_NCURSES
+ if (argc != 3) {
+ Usage(argv[0]);
+ exit(-1);
+ }
+ create_rc(argv[2]);
+ return 0;
+#else
+ fprintf(stderr, "\nThis option is currently unsupported on your system.\n");
+ return -1;
+#endif
+ }
+
+ while (offset < argc-1 && !end_common_opts) { /* Common options */
+ if (!strcmp(argv[offset+1], "--title")) {
+ if (argc-offset < 3 || title != NULL) { /* No two "--title" please! */
+ Usage(argv[0]);
+ exit(-1);
+ }
+ else {
+ title = argv[offset+2];
+ offset += 2;
+ }
+ }
+ else if (!strcmp(argv[offset+1], "--clear")) {
+ if (clear_screen) { /* Hey, "--clear" can't appear twice! */
+ Usage(argv[0]);
+ exit(-1);
+ }
+ else if (argc == 2) { /* we only want to clear the screen */
+ init_dialog();
+ refresh(); /* init_dialog() will clear the screen for us */
+ endwin();
+ return 0;
+ }
+ else {
+ clear_screen = 1;
+ offset++;
+ }
+ }
+ else /* no more common options */
+ end_common_opts = 1;
+ }
+
+ if (argc-1 == offset) { /* no more options */
+ Usage(argv[0]);
+ exit(-1);
+ }
+
+ /* Box options */
+
+ if (!strcmp(argv[offset+1], "--yesno")) {
+ if (argc-offset != 5) {
+ Usage(argv[0]);
+ exit(-1);
+ }
+ init_dialog();
+ retval = dialog_yesno(title, argv[offset+2], atoi(argv[offset+3]),
+ atoi(argv[offset+4]));
+
+ if (clear_screen) { /* clear screen before exit */
+ attr_clear(stdscr, LINES, COLS, screen_attr);
+ refresh();
+ }
+ endwin();
+ return retval;
+ }
+ else if (!strcmp(argv[offset+1], "--msgbox")) {
+ if (argc-offset != 5) {
+ Usage(argv[0]);
+ exit(-1);
+ }
+ init_dialog();
+ retval = dialog_msgbox(title, argv[offset+2], atoi(argv[offset+3]),
+ atoi(argv[offset+4]), 1);
+
+ if (clear_screen) { /* clear screen before exit */
+ attr_clear(stdscr, LINES, COLS, screen_attr);
+ refresh();
+ }
+ endwin();
+ return retval;
+ }
+ else if (!strcmp(argv[offset+1], "--infobox")) {
+ if (argc-offset != 5) {
+ Usage(argv[0]);
+ exit(-1);
+ }
+ init_dialog();
+ retval = dialog_msgbox(title, argv[offset+2], atoi(argv[offset+3]),
+ atoi(argv[offset+4]), 0);
+
+ if (clear_screen) { /* clear screen before exit */
+ attr_clear(stdscr, LINES, COLS, screen_attr);
+ refresh();
+ }
+ endwin();
+ return retval;
+ }
+ else if (!strcmp(argv[offset+1], "--textbox")) {
+ if (argc-offset != 5) {
+ Usage(argv[0]);
+ exit(-1);
+ }
+ init_dialog();
+ retval = dialog_textbox(title, argv[offset+2], atoi(argv[offset+3]),
+ atoi(argv[offset+4]));
+
+ if (clear_screen) { /* clear screen before exit */
+ attr_clear(stdscr, LINES, COLS, screen_attr);
+ refresh();
+ }
+ endwin();
+ return retval;
+ }
+ else if (!strcmp(argv[offset+1], "--menu")) {
+ if (argc-offset < 8 || ((argc-offset) % 2)) {
+ Usage(argv[0]);
+ exit(-1);
+ }
+ init_dialog();
+ retval = dialog_menu(title, argv[offset+2], atoi(argv[offset+3]),
+ atoi(argv[offset+4]), atoi(argv[offset+5]),
+ (argc-offset-6)/2, argv+offset + 6);
+
+ if (clear_screen) { /* clear screen before exit */
+ attr_clear(stdscr, LINES, COLS, screen_attr);
+ refresh();
+ }
+ endwin();
+ return retval;
+ }
+ else if (!strcmp(argv[offset+1], "--checklist")) {
+ if (argc-offset < 9 || ((argc-offset-6) % 3)) {
+ Usage(argv[0]);
+ exit(-1);
+ }
+ init_dialog();
+ retval = dialog_checklist(title, argv[offset+2], atoi(argv[offset+3]),
+ atoi(argv[offset+4]), atoi(argv[offset+5]),
+ (argc-offset-6)/3, argv+offset + 6);
+
+ if (clear_screen) { /* clear screen before exit */
+ attr_clear(stdscr, LINES, COLS, screen_attr);
+ refresh();
+ }
+ endwin();
+ return retval;
+ }
+ else if (!strcmp(argv[offset+1], "--radiolist")) {
+ if (argc-offset < 9 || ((argc-offset-6) % 3)) {
+ Usage(argv[0]);
+ exit(-1);
+ }
+ init_dialog();
+ retval = dialog_radiolist(title, argv[offset+2], atoi(argv[offset+3]),
+ atoi(argv[offset+4]), atoi(argv[offset+5]),
+ (argc-offset-6)/3, argv+offset + 6);
+
+ if (clear_screen) { /* clear screen before exit */
+ attr_clear(stdscr, LINES, COLS, screen_attr);
+ refresh();
+ }
+ endwin();
+ return retval;
+ }
+ else if (!strcmp(argv[offset+1], "--inputbox")) {
+ if (argc-offset != 5) {
+ Usage(argv[0]);
+ exit(-1);
+ }
+ init_dialog();
+ retval = dialog_inputbox(title, argv[offset+2], atoi(argv[offset+3]),
+ atoi(argv[offset+4]));
+
+ if (clear_screen) { /* clear screen before exit */
+ attr_clear(stdscr, LINES, COLS, screen_attr);
+ refresh();
+ }
+ endwin();
+ return retval;
+ }
+
+ Usage(argv[0]);
+ exit(-1);
+}
+/* End of main() */
+
+
+/*
+ * Print program usage
+ */
+void Usage(unsigned char *name)
+{
+ fprintf(stderr, "\
+\ndialog version 0.3, by Savio Lam (lam836@cs.cuhk.hk).\
+\n patched to version %s by Stuart Herbert (S.Herbert@shef.ac.uk)\
+\n\
+\n* Display dialog boxes from shell scripts *\
+\n\
+\nUsage: %s --clear\
+\n %s --create-rc <file>\
+\n %s [--title <title>] [--clear] <Box options>\
+\n\
+\nBox options:\
+\n\
+\n --yesno <text> <height> <width>\
+\n --msgbox <text> <height> <width>\
+\n --infobox <text> <height> <width>\
+\n --inputbox <text> <height> <width>\
+\n --textbox <file> <height> <width>\
+\n --menu <text> <height> <width> <menu height> <tag1> <item1>...\
+\n --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
+\n --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\n", VERSION, name, name, name);
+}
+/* End of Usage() */
+
+
+/*
+ * Do some initialization for dialog
+ */
+void init_dialog(void)
+{
+#ifdef HAVE_NCURSES
+ if (parse_rc() == -1) /* Read the configuration file */
+ exit(-1);
+#endif
+
+ initscr(); /* Init curses */
+ keypad(stdscr, TRUE);
+ cbreak();
+ noecho();
+
+#ifdef HAVE_NCURSES
+ if (use_colors || use_shadow) /* Set up colors */
+ color_setup();
+#endif
+
+ /* Set screen to screen attribute */
+ attr_clear(stdscr, LINES, COLS, screen_attr);
+ wnoutrefresh(stdscr);
+}
+/* End of init_dialog() */
+
+
+#ifdef HAVE_NCURSES
+/*
+ * Setup for color display
+ */
+void color_setup(void)
+{
+ int i;
+
+ if (has_colors()) { /* Terminal supports color? */
+ start_color();
+
+ /* Initialize color pairs */
+ for (i = 0; i < ATTRIBUTE_COUNT; i++)
+ init_pair(i+1, color_table[i][0], color_table[i][1]);
+
+ /* Setup color attributes */
+ for (i = 0; i < ATTRIBUTE_COUNT; i++)
+ attributes[i] = C_ATTR(color_table[i][2], i+1);
+ }
+}
+/* End of color_setup() */
+#endif
+
+
+/*
+ * Set window to attribute 'attr'
+ */
+void attr_clear(WINDOW *win, int height, int width, chtype attr)
+{
+ int i, j;
+
+ wattrset(win, attr); /* Set window to attribute 'attr' */
+ for (i = 0; i < height; i++) {
+ wmove(win, i, 0);
+ for (j = 0; j < width; j++)
+ waddch(win, ' ');
+ }
+}
+/* End of attr_clear() */
+
+
+/*
+ * Print a string of text in a window, automatically wrap around to the
+ * next line if the string is too long to fit on one line. Note that the
+ * string may contain "\n" to represent a newline character or the real
+ * newline '\n', but in that case, auto wrap around will be disabled.
+ */
+void print_autowrap(WINDOW *win, unsigned char *prompt, int width, int y, int x)
+{
+ int first = 1, cur_x, cur_y;
+ unsigned char tempstr[MAX_LEN+1], *word, *tempptr, *tempptr1;
+
+ strcpy(tempstr, prompt);
+ if ((strstr(tempstr, "\\n") != NULL) ||
+ (strchr(tempstr, '\n') != NULL)) { /* Prompt contains "\n" or '\n' */
+ word = tempstr;
+ cur_y = y;
+ wmove(win, cur_y, x);
+ while (1) {
+ tempptr = strstr(word, "\\n");
+ tempptr1 = strchr(word, '\n');
+ if (tempptr == NULL && tempptr1 == NULL)
+ break;
+ else if (tempptr == NULL) { /* No more "\n" */
+ tempptr = tempptr1;
+ tempptr[0] = '\0';
+ }
+ else if (tempptr1 == NULL) { /* No more '\n' */
+ tempptr[0] = '\0';
+ tempptr++;
+ }
+ else { /* Prompt contains both "\n" and '\n' */
+ if (strlen(tempptr)-2 < strlen(tempptr1)-1) {
+ tempptr = tempptr1;
+ tempptr[0] = '\0';
+ }
+ else {
+ tempptr[0] = '\0';
+ tempptr++;
+ }
+ }
+
+ waddstr(win, word);
+ word = tempptr + 1;
+ wmove(win, ++cur_y, x);
+ }
+ waddstr(win, word);
+ }
+ else if (strlen(tempstr) <= width-x*2) { /* If prompt is short */
+ wmove(win, y, (width - strlen(tempstr)) / 2);
+ waddstr(win, tempstr);
+ }
+ else {
+ cur_x = x;
+ cur_y = y;
+ /* Print prompt word by word, wrap around if necessary */
+ while ((word = strtok(first ? tempstr : NULL, " ")) != NULL) {
+ if (first) /* First iteration */
+ first = 0;
+ if (cur_x+strlen(word) >= width) { /* wrap around to next line */
+ cur_y++;
+ cur_x = x;
+ }
+ wmove(win, cur_y, cur_x);
+ waddstr(win, word);
+ getyx(win, cur_y, cur_x);
+ cur_x++;
+ }
+ }
+}
+/* End of print_autowrap() */
+
+
+/*
+ * Print a button
+ */
+void print_button(WINDOW *win, unsigned char *label, int y, int x, int selected)
+{
+ int i, temp;
+
+ wmove(win, y, x);
+ wattrset(win, selected ? button_active_attr : button_inactive_attr);
+ waddstr(win, "<");
+ temp = strspn(label, " ");
+ label += temp;
+ wattrset(win, selected ? button_label_active_attr : button_label_inactive_attr);
+ for (i = 0; i < temp; i++)
+ waddch(win, ' ');
+ wattrset(win, selected ? button_key_active_attr : button_key_inactive_attr);
+ waddch(win, label[0]);
+ wattrset(win, selected ? button_label_active_attr : button_label_inactive_attr);
+ waddstr(win, label+1);
+ wattrset(win, selected ? button_active_attr : button_inactive_attr);
+ waddstr(win, ">");
+ wmove(win, y, x+temp+1);
+}
+/* End of print_button() */
+
+
+/*
+ * Draw a rectangular box with line drawing characters
+ */
+void draw_box(WINDOW *win, int y, int x, int height, int width, chtype box, chtype border)
+{
+ int i, j;
+
+ wattrset(win, 0);
+ for (i = 0; i < height; i++) {
+ wmove(win, y + i, x);
+ for (j = 0; j < width; j++)
+ if (!i && !j)
+ waddch(win, border | ACS_ULCORNER);
+ else if (i == height-1 && !j)
+ waddch(win, border | ACS_LLCORNER);
+ else if (!i && j == width-1)
+ waddch(win, box | ACS_URCORNER);
+ else if (i == height-1 && j == width-1)
+ waddch(win, box | ACS_LRCORNER);
+ else if (!i)
+ waddch(win, border | ACS_HLINE);
+ else if (i == height-1)
+ waddch(win, box | ACS_HLINE);
+ else if (!j)
+ waddch(win, border | ACS_VLINE);
+ else if (j == width-1)
+ waddch(win, box | ACS_VLINE);
+ else
+ waddch(win, box | ' ');
+ }
+}
+/* End of draw_box() */
+
+
+#ifdef HAVE_NCURSES
+/*
+ * Draw shadows along the right and bottom edge to give a more 3D look
+ * to the boxes
+ */
+void draw_shadow(WINDOW *win, int y, int x, int height, int width)
+{
+ int i;
+
+ if (has_colors()) { /* Whether terminal supports color? */
+ wattrset(win, shadow_attr);
+ wmove(win, y + height, x + 2);
+ for (i = 0; i < width; i++)
+ waddch(win, winch(win) & A_CHARTEXT);
+ for (i = y + 1; i < y + height + 1; i++) {
+ wmove(win, i, x + width);
+ waddch(win, winch(win) & A_CHARTEXT);
+ waddch(win, winch(win) & A_CHARTEXT);
+ }
+ wnoutrefresh(win);
+ }
+}
+/* End of draw_shadow() */
+#endif
diff --git a/gnu/usr.bin/dialog/dialog.h b/gnu/usr.bin/dialog/dialog.h
new file mode 100644
index 0000000..849961f
--- /dev/null
+++ b/gnu/usr.bin/dialog/dialog.h
@@ -0,0 +1,231 @@
+/*
+ * dialog.h -- common declarations for all dialog modules
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_NCURSES
+#include <ncurses.h>
+
+#else
+
+#ifdef ultrix
+#include <cursesX.h>
+#else
+#include <curses.h>
+#endif
+
+#endif
+
+#if defined(LOCALE)
+#include <locale.h>
+#endif
+
+/*
+ * Change these if you want
+ */
+#define USE_SHADOW TRUE
+#define USE_COLORS TRUE
+
+#define VERSION "0.4"
+#define ESC 27
+#define TAB 9
+#define MAX_LEN 2048
+#define BUF_SIZE (10*1024)
+#define MIN(x,y) (x < y ? x : y)
+#define MAX(x,y) (x > y ? x : y)
+
+#ifndef HAVE_NCURSES
+#ifndef ACS_ULCORNER
+#define ACS_ULCORNER '+'
+#endif
+#ifndef ACS_LLCORNER
+#define ACS_LLCORNER '+'
+#endif
+#ifndef ACS_URCORNER
+#define ACS_URCORNER '+'
+#endif
+#ifndef ACS_LRCORNER
+#define ACS_LRCORNER '+'
+#endif
+#ifndef ACS_HLINE
+#define ACS_HLINE '-'
+#endif
+#ifndef ACS_VLINE
+#define ACS_VLINE '|'
+#endif
+#ifndef ACS_LTEE
+#define ACS_LTEE '+'
+#endif
+#ifndef ACS_RTEE
+#define ACS_RTEE '+'
+#endif
+#ifndef ACS_UARROW
+#define ACS_UARROW '^'
+#endif
+#ifndef ACS_DARROW
+#define ACS_DARROW 'v'
+#endif
+#endif /* HAVE_NCURSES */
+
+
+/*
+ * Attribute names
+ */
+#define screen_attr attributes[0]
+#define shadow_attr attributes[1]
+#define dialog_attr attributes[2]
+#define title_attr attributes[3]
+#define border_attr attributes[4]
+#define button_active_attr attributes[5]
+#define button_inactive_attr attributes[6]
+#define button_key_active_attr attributes[7]
+#define button_key_inactive_attr attributes[8]
+#define button_label_active_attr attributes[9]
+#define button_label_inactive_attr attributes[10]
+#define inputbox_attr attributes[11]
+#define inputbox_border_attr attributes[12]
+#define searchbox_attr attributes[13]
+#define searchbox_title_attr attributes[14]
+#define searchbox_border_attr attributes[15]
+#define position_indicator_attr attributes[16]
+#define menubox_attr attributes[17]
+#define menubox_border_attr attributes[18]
+#define item_attr attributes[19]
+#define item_selected_attr attributes[20]
+#define tag_attr attributes[21]
+#define tag_selected_attr attributes[22]
+#define tag_key_attr attributes[23]
+#define tag_key_selected_attr attributes[24]
+#define check_attr attributes[25]
+#define check_selected_attr attributes[26]
+#define uarrow_attr attributes[27]
+#define darrow_attr attributes[28]
+
+/* number of attributes */
+#define ATTRIBUTE_COUNT 29
+
+
+/*
+ * Global variables
+ */
+#ifdef __DIALOG_MAIN__
+
+#ifdef HAVE_NCURSES
+
+/* use colors by default? */
+bool use_colors = USE_COLORS;
+
+/* shadow dialog boxes by default?
+ Note that 'use_shadow' implies 'use_colors' */
+bool use_shadow = USE_SHADOW;
+
+#endif
+
+
+/*
+ * Attribute values, default is for mono display
+ */
+chtype attributes[] = {
+ A_NORMAL, /* screen_attr */
+ A_NORMAL, /* shadow_attr */
+ A_REVERSE, /* dialog_attr */
+ A_REVERSE, /* title_attr */
+ A_REVERSE, /* border_attr */
+ A_BOLD, /* button_active_attr */
+ A_DIM, /* button_inactive_attr */
+ A_UNDERLINE, /* button_key_active_attr */
+ A_UNDERLINE, /* button_key_inactive_attr */
+ A_NORMAL, /* button_label_active_attr */
+ A_NORMAL, /* button_label_inactive_attr */
+ A_REVERSE, /* inputbox_attr */
+ A_REVERSE, /* inputbox_border_attr */
+ A_REVERSE, /* searchbox_attr */
+ A_REVERSE, /* searchbox_title_attr */
+ A_REVERSE, /* searchbox_border_attr */
+ A_REVERSE, /* position_indicator_attr */
+ A_REVERSE, /* menubox_attr */
+ A_REVERSE, /* menubox_border_attr */
+ A_REVERSE, /* item_attr */
+ A_NORMAL, /* item_selected_attr */
+ A_REVERSE, /* tag_attr */
+ A_REVERSE, /* tag_selected_attr */
+ A_NORMAL, /* tag_key_attr */
+ A_BOLD, /* tag_key_selected_attr */
+ A_REVERSE, /* check_attr */
+ A_REVERSE, /* check_selected_attr */
+ A_REVERSE, /* uarrow_attr */
+ A_REVERSE /* darrow_attr */
+};
+
+#else
+
+#ifdef HAVE_NCURSES
+extern bool use_colors;
+extern bool use_shadow;
+#endif
+
+extern chtype attributes[];
+
+#endif /* __DIALOG_MAIN__ */
+
+
+
+#ifdef HAVE_NCURSES
+
+/*
+ * Function prototypes
+ */
+#ifdef __DIALOG_MAIN__
+
+extern void create_rc(unsigned char *filename);
+extern int parse_rc(void);
+
+#endif /* __DIALOG_MAIN__ */
+
+#endif
+
+
+void Usage(unsigned char *name);
+void init_dialog(void);
+#ifdef HAVE_NCURSES
+void color_setup(void);
+#endif
+void attr_clear(WINDOW *win, int height, int width, chtype attr);
+void print_autowrap(WINDOW *win, unsigned char *prompt, int width, int y, int x);
+void print_button(WINDOW *win, unsigned char *label, int y, int x, int selected);
+void draw_box(WINDOW *win, int y, int x, int height, int width, chtype box, chtype border);
+#ifdef HAVE_NCURSES
+void draw_shadow(WINDOW *win, int y, int x, int height, int width);
+#endif
+
+int dialog_yesno(unsigned char *title, unsigned char *prompt, int height, int width);
+int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int width, int pause);
+int dialog_textbox(unsigned char *title, unsigned char *file, int height, int width);
+int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height, int item_no, unsigned char **items);
+int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int item_no, unsigned char **items);
+int dialog_radiolist(char *title, char *prompt, int height, int width, int list_height, int item_no, unsigned char **items);
+int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int width);
+
diff --git a/gnu/usr.bin/dialog/inputbox.c b/gnu/usr.bin/dialog/inputbox.c
new file mode 100644
index 0000000..fe91613
--- /dev/null
+++ b/gnu/usr.bin/dialog/inputbox.c
@@ -0,0 +1,252 @@
+/*
+ * inputbox.c -- implements the input box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "dialog.h"
+
+
+/*
+ * Display a dialog box for inputing a string
+ */
+int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int width)
+{
+ int i, x, y, box_y, box_x, box_width,
+ input_x = 0, scroll = 0, key = 0, button = -1;
+ unsigned char instr[MAX_LEN+1];
+ WINDOW *dialog;
+
+ /* center dialog box on screen */
+ x = (COLS - width)/2;
+ y = (LINES - height)/2;
+
+ memset(instr, 0, sizeof(instr));
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ keypad(dialog, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ wattrset(dialog, dialog_attr);
+ print_autowrap(dialog, prompt, width, 1, 3);
+
+ /* Draw the input field box */
+ box_width = width-6;
+ getyx(dialog, y, x);
+ box_y = y + 2;
+ box_x = (width - box_width)/2;
+ draw_box(dialog, y+1, box_x-1, 3, box_width+2, border_attr, dialog_attr);
+
+ x = width/2-11;
+ y = height-2;
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+
+ wmove(dialog, box_y, box_x);
+ wrefresh(dialog);
+ while (key != ESC) {
+ key = wgetch(dialog);
+
+ if (button == -1) { /* Input box selected */
+ switch (key) {
+ case TAB:
+ case KEY_BTAB:
+ case KEY_UP:
+ case KEY_DOWN:
+ break;
+ case KEY_LEFT:
+ if (input_x || scroll) {
+ wattrset(dialog, inputbox_attr);
+ if (!input_x) {
+ scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
+ wmove(dialog, box_y, box_x);
+ for (i = 0; i < box_width; i++)
+ waddch(dialog, instr[scroll+input_x+i] ? instr[scroll+input_x+i] : ' ');
+ input_x = strlen(instr) - scroll;
+ }
+ else
+ input_x--;
+ i = strlen(instr);
+ while (i-1 >= scroll+input_x && instr[i-1] == ' ')
+ instr[--i] = '\0';
+ wmove(dialog, box_y, input_x + box_x);
+ wrefresh(dialog);
+ }
+ continue;
+ case KEY_RIGHT:
+ if (scroll+input_x < MAX_LEN) {
+ wattrset(dialog, inputbox_attr);
+ if (!instr[scroll+input_x])
+ instr[scroll+input_x] = ' ';
+ if (input_x == box_width-1) {
+ scroll++;
+ wmove(dialog, box_y, box_x);
+ for (i = 0; i < box_width-1; i++)
+ waddch(dialog, instr[scroll+i]);
+ }
+ else {
+ wmove(dialog, box_y, input_x + box_x);
+ waddch(dialog, instr[scroll+input_x]);
+ input_x++;
+ }
+ wrefresh(dialog);
+ } else
+ flash(); /* Alarm user about overflow */
+ continue;
+ case KEY_BACKSPACE:
+ if (input_x || scroll) {
+ wattrset(dialog, inputbox_attr);
+ if (!input_x) {
+ scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
+ wmove(dialog, box_y, box_x);
+ for (i = 0; i < box_width; i++)
+ waddch(dialog, instr[scroll+input_x+i] ? instr[scroll+input_x+i] : ' ');
+ input_x = strlen(instr) - scroll;
+ }
+ else
+ input_x--;
+ instr[scroll+input_x] = ' ';
+ wmove(dialog, box_y, input_x + box_x);
+ waddch(dialog, ' ');
+ wmove(dialog, box_y, input_x + box_x);
+ wrefresh(dialog);
+ i = strlen(instr);
+ while (i-1 >= scroll+input_x && instr[i-1] == ' ')
+ instr[--i] = '\0';
+ }
+ continue;
+ default:
+ if (key < 0x100 && isprint(key)) {
+ if (scroll+input_x < MAX_LEN) {
+ wattrset(dialog, inputbox_attr);
+ instr[scroll+input_x] = key;
+ instr[scroll+input_x+1] = '\0';
+ if (input_x == box_width-1) {
+ scroll++;
+ wmove(dialog, box_y, box_x);
+ for (i = 0; i < box_width-1; i++)
+ waddch(dialog, instr[scroll+i]);
+ }
+ else {
+ wmove(dialog, box_y, input_x++ + box_x);
+ waddch(dialog, key);
+ }
+ wrefresh(dialog);
+ } else
+ flash(); /* Alarm user about overflow */
+ continue;
+ }
+ }
+ }
+
+ switch (key) {
+ case 'O':
+ case 'o':
+ delwin(dialog);
+ fprintf(stderr, instr);
+ return 0;
+ case 'C':
+ case 'c':
+ delwin(dialog);
+ return 1;
+ case KEY_UP:
+ case KEY_LEFT:
+ case KEY_BTAB:
+ switch (button) {
+ case -1:
+ button = 1; /* Indicates "Cancel" button is selected */
+ print_button(dialog, " OK ", y, x, FALSE);
+ print_button(dialog, "Cancel", y, x+14, TRUE);
+ wrefresh(dialog);
+ break;
+ case 0:
+ button = -1; /* Indicates input box is selected */
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+ wmove(dialog, box_y, box_x + input_x);
+ wrefresh(dialog);
+ break;
+ case 1:
+ button = 0; /* Indicates "OK" button is selected */
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+ wrefresh(dialog);
+ break;
+ }
+ break;
+ case TAB:
+ case KEY_DOWN:
+ case KEY_RIGHT:
+ switch (button) {
+ case -1:
+ button = 0; /* Indicates "OK" button is selected */
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+ wrefresh(dialog);
+ break;
+ case 0:
+ button = 1; /* Indicates "Cancel" button is selected */
+ print_button(dialog, " OK ", y, x, FALSE);
+ print_button(dialog, "Cancel", y, x+14, TRUE);
+ wrefresh(dialog);
+ break;
+ case 1:
+ button = -1; /* Indicates input box is selected */
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+ wmove(dialog, box_y, box_x + input_x);
+ wrefresh(dialog);
+ break;
+ }
+ break;
+ case ' ':
+ case '\n':
+ delwin(dialog);
+ fprintf(stderr, instr);
+ return (button == -1 ? 0 : button);
+ case ESC:
+ break;
+ }
+ }
+
+ delwin(dialog);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_inputbox() */
diff --git a/gnu/usr.bin/dialog/menubox.c b/gnu/usr.bin/dialog/menubox.c
new file mode 100644
index 0000000..e393c6c
--- /dev/null
+++ b/gnu/usr.bin/dialog/menubox.c
@@ -0,0 +1,310 @@
+/*
+ * menubox.c -- implements the menu box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "dialog.h"
+
+
+static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int choice, int selected);
+
+
+static int menu_width, tag_x, item_x;
+
+
+/*
+ * Display a menu for choosing among a number of options
+ */
+int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height, int item_no, unsigned char **items)
+{
+ int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
+ scroll = 0, max_choice;
+ WINDOW *dialog, *menu;
+
+ max_choice = MIN(menu_height, item_no);
+
+ /* center dialog box on screen */
+ x = (COLS - width)/2;
+ y = (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ keypad(dialog, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ wattrset(dialog, dialog_attr);
+ print_autowrap(dialog, prompt, width, 1, 3);
+
+ menu_width = width-6;
+ getyx(dialog, cur_y, cur_x);
+ box_y = cur_y + 1;
+ box_x = (width - menu_width)/2 - 1;
+
+ /* create new window for the menu */
+ menu = subwin(dialog, menu_height, menu_width, y + box_y + 1, x + box_x + 1);
+ keypad(menu, TRUE);
+
+ /* draw a box around the menu items */
+ draw_box(dialog, box_y, box_x, menu_height+2, menu_width+2, menubox_border_attr, menubox_attr);
+
+ tag_x = 0;
+ item_x = 0;
+ /* Find length of longest item in order to center menu */
+ for (i = 0; i < item_no; i++) {
+ tag_x = MAX(tag_x, strlen(items[i*2]) + strlen(items[i*2 + 1]) + 2);
+ item_x = MAX(item_x, strlen(items[i*2]));
+ }
+ tag_x = (menu_width - tag_x) / 2;
+ item_x = tag_x + item_x + 2;
+
+ /* Print the menu */
+ for (i = 0; i < max_choice; i++)
+ print_item(menu, items[i*2], items[i*2 + 1], i, i == choice);
+ wnoutrefresh(menu);
+
+ if (menu_height < item_no) {
+ wattrset(dialog, darrow_attr);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 1);
+ waddch(dialog, ACS_DARROW);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 2);
+ waddstr(dialog,"(+)");
+ }
+
+ x = width/2-11;
+ y = height-2;
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+ wrefresh(dialog);
+
+ while (key != ESC) {
+ key = wgetch(dialog);
+ /* Check if key pressed matches first character of any item tag in menu */
+ for (i = 0; i < max_choice; i++)
+ if (key < 0x100 && toupper(key) == toupper(items[(scroll+i)*2][0]))
+ break;
+
+ if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) ||
+ key == KEY_UP || key == KEY_DOWN || key == '-' || key == '+') {
+ if (key >= '1' && key <= MIN('9', '0'+max_choice))
+ i = key - '1';
+ else if (key == KEY_UP || key == '-') {
+ if (!choice) {
+ if (scroll) {
+#ifdef BROKEN_WSCRL
+ /* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
+ violation when scrolling windows of height = 4, so scrolling is not
+ used for now */
+ scroll--;
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ /* Reprint menu to scroll down */
+ for (i = 0; i < max_choice; i++)
+ print_item(menu, items[(scroll+i)*2], items[(scroll+i)*2 + 1], i, i == choice);
+
+#else
+
+ /* Scroll menu down */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ if (menu_height > 1) {
+ /* De-highlight current first item before scrolling down */
+ print_item(menu, items[scroll*2], items[scroll*2 + 1], 0, FALSE);
+ scrollok(menu, TRUE);
+ wscrl(menu, -1);
+ scrollok(menu, FALSE);
+ }
+ scroll--;
+ print_item(menu, items[scroll*2], items[scroll*2 + 1], 0, TRUE);
+#endif
+ wnoutrefresh(menu);
+
+ /* print the up/down arrows */
+ wmove(dialog, box_y, box_x + tag_x + 1);
+ wattrset(dialog, scroll ? uarrow_attr : menubox_attr);
+ waddch(dialog, scroll ? ACS_UARROW : ACS_HLINE);
+ wmove(dialog, box_y, box_x + tag_x + 2);
+ waddch(dialog, scroll ? '(' : ACS_HLINE);
+ wmove(dialog, box_y, box_x + tag_x + 3);
+ waddch(dialog, scroll ? '-' : ACS_HLINE);
+ wmove(dialog, box_y, box_x + tag_x + 4);
+ waddch(dialog, scroll ? ')' : ACS_HLINE);
+ wattrset(dialog, darrow_attr);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 1);
+ waddch(dialog, ACS_DARROW);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 2);
+ waddstr(dialog,"(+)");
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice - 1;
+ }
+ else if (key == KEY_DOWN || key == '+')
+ if (choice == max_choice - 1) {
+ if (scroll+choice < item_no-1) {
+#ifdef BROKEN_WSCRL
+ /* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
+ violation when scrolling windows of height = 4, so scrolling is not
+ used for now */
+ scroll++;
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ /* Reprint menu to scroll up */
+ for (i = 0; i < max_choice; i++)
+ print_item(menu, items[(scroll+i)*2], items[(scroll+i)*2 + 1], i, i == choice);
+
+#else
+
+ /* Scroll menu up */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ if (menu_height > 1) {
+ /* De-highlight current last item before scrolling up */
+ print_item(menu, items[(scroll+max_choice-1)*2], items[(scroll+max_choice-1)*2 + 1], max_choice-1, FALSE);
+ scrollok(menu, TRUE);
+ scroll(menu);
+ scrollok(menu, FALSE);
+ }
+ scroll++;
+ print_item(menu, items[(scroll+max_choice-1)*2], items[(scroll+max_choice-1)*2 + 1], max_choice-1, TRUE);
+#endif
+ wnoutrefresh(menu);
+
+ /* print the up/down arrows */
+ wattrset(dialog, uarrow_attr);
+ wmove(dialog, box_y, box_x + tag_x + 1);
+ waddch(dialog, ACS_UARROW);
+ wmove(dialog, box_y, box_x + tag_x + 2);
+ waddstr(dialog,"(-)");
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 1);
+ wattrset(dialog, scroll+choice < item_no-1 ? darrow_attr : menubox_border_attr);
+ waddch(dialog, scroll+choice < item_no-1 ? ACS_DARROW : ACS_HLINE);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 2);
+ waddch(dialog, scroll+choice < item_no-1 ? '(' : ACS_HLINE);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 3);
+ waddch(dialog, scroll+choice < item_no-1 ? '+' : ACS_HLINE);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 4);
+ waddch(dialog, scroll+choice < item_no-1 ? ')' : ACS_HLINE);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice + 1;
+
+ if (i != choice) {
+ /* De-highlight current item */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ print_item(menu, items[(scroll+choice)*2], items[(scroll+choice)*2 + 1], choice, FALSE);
+
+ /* Highlight new item */
+ choice = i;
+ print_item(menu, items[(scroll+choice)*2], items[(scroll+choice)*2 + 1], choice, TRUE);
+ wnoutrefresh(menu);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+
+ switch (key) {
+ case 'O':
+ case 'o':
+ delwin(dialog);
+ fprintf(stderr, items[(scroll+choice)*2]);
+ return 0;
+ case 'C':
+ case 'c':
+ delwin(dialog);
+ return 1;
+ case KEY_BTAB:
+ case TAB:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ if (!button) {
+ button = 1; /* Indicates "Cancel" button is selected */
+ print_button(dialog, " OK ", y, x, FALSE);
+ print_button(dialog, "Cancel", y, x+14, TRUE);
+ }
+ else {
+ button = 0; /* Indicates "OK" button is selected */
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+ }
+ wrefresh(dialog);
+ break;
+ case ' ':
+ case '\n':
+ delwin(dialog);
+ if (!button)
+ fprintf(stderr, items[(scroll+choice)*2]);
+ return button;
+ case ESC:
+ break;
+ }
+ }
+
+ delwin(dialog);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_menu() */
+
+
+/*
+ * Print menu item
+ */
+static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int choice, int selected)
+{
+ int i;
+
+ /* Clear 'residue' of last item */
+ wattrset(win, menubox_attr);
+ wmove(win, choice, 0);
+ for (i = 0; i < menu_width; i++)
+ waddch(win, ' ');
+ wmove(win, choice, tag_x);
+ wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
+ waddch(win, tag[0]);
+ wattrset(win, selected ? tag_selected_attr : tag_attr);
+ waddstr(win, tag + 1);
+ wmove(win, choice, item_x);
+ wattrset(win, selected ? item_selected_attr : item_attr);
+ waddstr(win, item);
+}
+/* End of print_item() */
diff --git a/gnu/usr.bin/dialog/msgbox.c b/gnu/usr.bin/dialog/msgbox.c
new file mode 100644
index 0000000..7fe6ae2
--- /dev/null
+++ b/gnu/usr.bin/dialog/msgbox.c
@@ -0,0 +1,81 @@
+/*
+ * msgbox.c -- implements the message box and info box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "dialog.h"
+
+
+/*
+ * Display a message box. Program will pause and display an "OK" button
+ * if the parameter 'pause' is non-zero.
+ */
+int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int width, int pause)
+{
+ int i, x, y, key = 0;
+ WINDOW *dialog;
+
+ /* center dialog box on screen */
+ x = (COLS - width)/2;
+ y = (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ keypad(dialog, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ wattrset(dialog, dialog_attr);
+ print_autowrap(dialog, prompt, width-2, 1, 2);
+
+ if (pause) {
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+ print_button(dialog, " OK ", height-2, width/2-4, TRUE);
+ wrefresh(dialog);
+ while (key != ESC && key != '\n' && key != ' ')
+ key = wgetch(dialog);
+ }
+ else {
+ key = '\n';
+ wrefresh(dialog);
+ }
+
+ delwin(dialog);
+ return (key == ESC ? -1 : 0);
+}
+/* End of dialog_msgbox() */
diff --git a/gnu/usr.bin/dialog/radiolist.c b/gnu/usr.bin/dialog/radiolist.c
new file mode 100644
index 0000000..5125924
--- /dev/null
+++ b/gnu/usr.bin/dialog/radiolist.c
@@ -0,0 +1,353 @@
+/*
+ * radiolist.c -- implements the radiolist box
+ *
+ * AUTHOR: Stuart Herbert - S.Herbert@sheffield.ac.uk
+ * (from checklist.c by Savio Lam (lam836@cs.cuhk.hk))
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "dialog.h"
+
+
+static void print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected);
+
+
+static int list_width, check_x, item_x;
+
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ */
+int dialog_radiolist(char *title, char *prompt, int height, int width, int list_height, int item_no, unsigned char **items)
+{
+ int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
+ scroll = 0, max_choice, *status;
+ WINDOW *dialog, *list;
+
+ /* Allocate space for storing item on/off status */
+ if ((status = malloc(sizeof(int)*item_no)) == NULL) {
+ endwin();
+ fprintf(stderr, "\nCan't allocate memory in dialog_radiolist().\n");
+ exit(-1);
+ }
+ /* Initializes status */
+ for (i = 0; i < item_no; i++)
+ status[i] = !strcasecmp(items[i*3 + 2], "on");
+
+ max_choice = MIN(list_height, item_no);
+
+ /* center dialog box on screen */
+ x = (COLS - width)/2;
+ y = (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ keypad(dialog, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ wattrset(dialog, dialog_attr);
+ print_autowrap(dialog, prompt, width, 1, 3);
+
+ list_width = width-6;
+ getyx(dialog, cur_y, cur_x);
+ box_y = cur_y + 1;
+ box_x = (width - list_width)/2 - 1;
+
+ /* create new window for the list */
+ list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
+ keypad(list, TRUE);
+
+ /* draw a box around the list items */
+ draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr);
+
+ check_x = 0;
+ item_x = 0;
+ /* Find length of longest item in order to center radiolist */
+ for (i = 0; i < item_no; i++) {
+ check_x = MAX(check_x, strlen(items[i*3]) + strlen(items[i*3 + 1]) + 6);
+ item_x = MAX(item_x, strlen(items[i*3]));
+ }
+ check_x = (list_width - check_x) / 2;
+ item_x = check_x + item_x + 6;
+
+ /* Print the list */
+ for (i = 0; i < max_choice; i++)
+ print_item(list, items[i*3], items[i*3 + 1], status[i], i, i == choice);
+ wnoutrefresh(list);
+
+ if (list_height < item_no) {
+ wattrset(dialog, darrow_attr);
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
+ waddch(dialog, ACS_DARROW);
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
+ waddstr(dialog, "(+)");
+ }
+
+ x = width/2-11;
+ y = height-2;
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+ wrefresh(dialog);
+
+ while (key != ESC) {
+ key = wgetch(dialog);
+ /* Check if key pressed matches first character of any item tag in list */
+ for (i = 0; i < max_choice; i++)
+ if (toupper(key) == toupper(items[(scroll+i)*3][0]))
+ break;
+
+ if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) ||
+ key == KEY_UP || key == KEY_DOWN || key == ' ' ||
+ key == '+' || key == '-' ) {
+ if (key >= '1' && key <= MIN('9', '0'+max_choice))
+ i = key - '1';
+ else if (key == KEY_UP || key == '-') {
+ if (!choice) {
+ if (scroll) {
+#ifdef BROKEN_WSCRL
+ /* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
+ violation when scrolling windows of height = 4, so scrolling is not
+ used for now */
+ scroll--;
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ /* Reprint list to scroll down */
+ for (i = 0; i < max_choice; i++)
+ print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice);
+
+#else
+
+ /* Scroll list down */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ if (list_height > 1) {
+ /* De-highlight current first item before scrolling down */
+ print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, FALSE);
+ scrollok(list, TRUE);
+ wscrl(list, -1);
+ scrollok(list, FALSE);
+ }
+ scroll--;
+ print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE);
+#endif
+ wnoutrefresh(list);
+
+ /* print the up/down arrows */
+ wmove(dialog, box_y, box_x + check_x + 5);
+ wattrset(dialog, scroll ? uarrow_attr : menubox_attr);
+ waddch(dialog, scroll ? ACS_UARROW : ACS_HLINE);
+ wmove(dialog, box_y, box_x + check_x + 6);
+ waddch(dialog, scroll ? '(' : ACS_HLINE);
+ wmove(dialog, box_y, box_x + check_x + 7);
+ waddch(dialog, scroll ? '-' : ACS_HLINE);
+ wmove(dialog, box_y, box_x + check_x + 8);
+ waddch(dialog, scroll ? ')' : ACS_HLINE);
+ wattrset(dialog, darrow_attr);
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
+ waddch(dialog, ACS_DARROW);
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
+ waddch(dialog, '(');
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 7);
+ waddch(dialog, '+');
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 8);
+ waddch(dialog, ')');
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice - 1;
+ }
+ else if (key == KEY_DOWN || key == '+') {
+ if (choice == max_choice - 1) {
+ if (scroll+choice < item_no-1) {
+#ifdef BROKEN_WSCRL
+ /* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
+ violation when scrolling windows of height = 4, so scrolling is not
+ used for now */
+ scroll++;
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ /* Reprint list to scroll up */
+ for (i = 0; i < max_choice; i++)
+ print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice);
+
+#else
+
+ /* Scroll list up */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ if (list_height > 1) {
+ /* De-highlight current last item before scrolling up */
+ print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1], status[scroll+max_choice-1], max_choice-1, FALSE);
+ scrollok(list, TRUE);
+ scroll(list);
+ scrollok(list, FALSE);
+ }
+ scroll++;
+ print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1], status[scroll+max_choice-1], max_choice-1, TRUE);
+#endif
+ wnoutrefresh(list);
+
+ /* print the up/down arrows */
+ wattrset(dialog, uarrow_attr);
+ wmove(dialog, box_y, box_x + check_x + 5);
+ waddch(dialog, ACS_UARROW);
+ wmove(dialog, box_y, box_x + check_x + 6);
+ waddstr(dialog, "(-)");
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
+ wattrset(dialog, scroll+choice < item_no-1 ? darrow_attr : menubox_border_attr);
+ waddch(dialog, scroll+choice < item_no-1 ? ACS_DARROW : ACS_HLINE);
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
+ waddch(dialog, scroll+choice < item_no-1 ? '(' : ACS_HLINE);
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 7);
+ waddch(dialog, scroll+choice < item_no-1 ? '+' : ACS_HLINE);
+ wmove(dialog, box_y + list_height + 1, box_x + check_x + 8);
+ waddch(dialog, scroll+choice < item_no-1 ? ')' : ACS_HLINE);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice + 1;
+ }
+ else if (key == ' ') { /* Toggle item status */
+ if (!status[scroll+choice])
+ {
+ for (i=0; i<item_no; i++)
+ status[i]=0;
+ status[scroll+choice]=1;
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ for (i = 0; i < max_choice; i++)
+ print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice);
+ wnoutrefresh(list);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+
+ if (i != choice) {
+ /* De-highlight current item */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 +1], status[scroll+choice], choice, FALSE);
+ /* Highlight new item */
+ choice = i;
+ print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, TRUE);
+ wnoutrefresh(list);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+
+ switch (key) {
+ case 'O':
+ case 'o':
+ delwin(dialog);
+ for (i = 0; i < item_no; i++)
+ if (status[i])
+ fprintf(stderr, "%s", items[i*3]);
+ free(status);
+ return 0;
+ case 'C':
+ case 'c':
+ delwin(dialog);
+ free(status);
+ return 1;
+ case KEY_BTAB:
+ case TAB:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ if (!button) {
+ button = 1; /* Indicates "Cancel" button is selected */
+ print_button(dialog, " OK ", y, x, FALSE);
+ print_button(dialog, "Cancel", y, x+14, TRUE);
+ }
+ else {
+ button = 0; /* Indicates "OK" button is selected */
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+ }
+ wrefresh(dialog);
+ break;
+ case ' ':
+ case '\n':
+ delwin(dialog);
+ if (!button)
+ for (i = 0; i < item_no; i++)
+ if (status[i])
+ fprintf(stderr, items[i*3]);
+ free(status);
+ return button;
+ case ESC:
+ break;
+ }
+ }
+
+ delwin(dialog);
+ free(status);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_radiolist() */
+
+
+/*
+ * Print list item
+ */
+static void print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected)
+{
+ int i;
+
+ /* Clear 'residue' of last item */
+ wattrset(win, menubox_attr);
+ wmove(win, choice, 0);
+ for (i = 0; i < list_width; i++)
+ waddch(win, ' ');
+ wmove(win, choice, check_x);
+ wattrset(win, selected ? check_selected_attr : check_attr);
+ wprintw(win, "(%c)", status ? '*' : ' ');
+ wattrset(win, menubox_attr);
+ waddch(win, ' ');
+ wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
+ waddch(win, tag[0]);
+ wattrset(win, selected ? tag_selected_attr : tag_attr);
+ waddstr(win, tag + 1);
+ wmove(win, choice, item_x);
+ wattrset(win, selected ? item_selected_attr : item_attr);
+ waddstr(win, item);
+}
+/* End of print_item() */
diff --git a/gnu/usr.bin/dialog/rc.c b/gnu/usr.bin/dialog/rc.c
new file mode 100644
index 0000000..46add74
--- /dev/null
+++ b/gnu/usr.bin/dialog/rc.c
@@ -0,0 +1,375 @@
+/*
+ * rc.c -- routines for processing the configuration file
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "dialog.h"
+#include "colors.h"
+#include "rc.h"
+
+
+static unsigned char *attr_to_str(int fg, int bg, int hl);
+static int str_to_attr(unsigned char *str, int *fg, int *bg, int *hl);
+static int parse_line(unsigned char *line, unsigned char **var, unsigned char **value);
+
+
+/*
+ * Create the configuration file
+ */
+void create_rc(unsigned char *filename)
+{
+ int i;
+ FILE *rc_file;
+
+ if ((rc_file = fopen(filename, "wt")) == NULL) {
+ fprintf(stderr, "\nError opening file for writing in create_rc().\n");
+ exit(-1);
+ }
+
+ fprintf(rc_file, "#\
+\n# Run-time configuration file for dialog\
+\n#\
+\n# Automatically generated by \"dialog --create-rc <file>\"\
+\n#\
+\n#\
+\n# Types of values:\
+\n#\
+\n# Number - <number>\
+\n# String - \"string\"\
+\n# Boolean - <ON|OFF>\
+\n# Attribute - (foreground,background,highlight?)\
+\n#\n\n");
+
+ /* Print an entry for each configuration variable */
+ for (i = 0; i < VAR_COUNT; i++) {
+ fprintf(rc_file, "\n# %s\n", vars[i].comment); /* print comment */
+ switch (vars[i].type) {
+ case VAL_INT:
+ fprintf(rc_file, "%s = %d\n", vars[i].name, *((int *) vars[i].var));
+ break;
+ case VAL_STR:
+ fprintf(rc_file, "%s = \"%s\"\n", vars[i].name, (unsigned char *) vars[i].var);
+ break;
+ case VAL_BOOL:
+ fprintf(rc_file, "%s = %s\n", vars[i].name, *((bool *) vars[i].var) ? "ON" : "OFF");
+ break;
+ case VAL_ATTR:
+ fprintf(rc_file, "%s = %s\n", vars[i].name, attr_to_str(((int *) vars[i].var)[0], ((int *) vars[i].var)[1], ((int *) vars[i].var)[2]));
+ break;
+ }
+ }
+
+ fclose(rc_file);
+}
+/* End of create_rc() */
+
+
+/*
+ * Parse the configuration file and set up variables
+ */
+int parse_rc(void)
+{
+ int i, l = 1, parse, fg, bg, hl;
+ unsigned char str[MAX_LEN+1], *var, *value, *tempptr;
+ FILE *rc_file;
+
+ /*
+ *
+ * At start, 'dialog' determines the settings to use as follows:
+ *
+ * a) if environment variable DIALOGRC is set, it's value determines the
+ * name of the configuration file.
+ *
+ * b) if the file in (a) can't be found, use the file $HOME/.dialogrc
+ * as the configuration file.
+ *
+ * c) if the file in (b) can't be found, use compiled in defaults.
+ *
+ */
+
+ if ((tempptr = getenv("DIALOGRC")) != NULL)
+ rc_file = fopen(tempptr, "rt");
+
+ if (tempptr == NULL || rc_file == NULL) { /* step (a) failed? */
+ /* try step (b) */
+ if ((tempptr = getenv("HOME")) == NULL)
+ return 0; /* step (b) failed, use default values */
+
+ if (tempptr[0] == '\0' || lastch(tempptr) == '/')
+ sprintf(str, "%s%s", tempptr, DIALOGRC);
+ else
+ sprintf(str, "%s/%s", tempptr, DIALOGRC);
+
+ if ((rc_file = fopen(str, "rt")) == NULL)
+ return 0; /* step (b) failed, use default values */
+ }
+
+ /* Scan each line and set variables */
+ while (fgets(str, MAX_LEN, rc_file) != NULL) {
+ if (lastch(str) != '\n') { /* ignore rest of file if line too long */
+ fprintf(stderr, "\nParse error: line %d of configuration file too long.\n", l);
+ fclose(rc_file);
+ return -1; /* parse aborted */
+ }
+ else {
+ lastch(str) = '\0';
+ parse = parse_line(str, &var, &value); /* parse current line */
+
+ switch (parse) {
+ case LINE_BLANK: /* ignore blank lines and comments */
+ case LINE_COMMENT:
+ break;
+ case LINE_OK:
+ /* search table for matching config variable name */
+ for (i = 0; i < VAR_COUNT && strcmp(vars[i].name, var); i++);
+
+ if (i == VAR_COUNT) { /* no match */
+ fprintf(stderr, "\nParse error: unknown variable at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ else { /* variable found in table, set run time variables */
+ switch (vars[i].type) {
+ case VAL_INT:
+ *((int *) vars[i].var) = atoi(value);
+ break;
+ case VAL_STR:
+ if (!isquote(value[0]) || !isquote(lastch(value)) || strlen(value) < 2) {
+ fprintf(stderr, "\nParse error: string value expected at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ else {
+ /* remove the (") quotes */
+ value++;
+ lastch(value) = '\0';
+ strcpy((unsigned char *) vars[i].var, value);
+ }
+ break;
+ case VAL_BOOL:
+ if (!strcasecmp(value, "ON"))
+ *((bool *) vars[i].var) = TRUE;
+ else if (!strcasecmp(value, "OFF"))
+ *((bool *) vars[i].var) = FALSE;
+ else {
+ fprintf(stderr, "\nParse error: boolean value expected at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ break;
+ case VAL_ATTR:
+ if (str_to_attr(value, &fg, &bg, &hl) == -1) {
+ fprintf(stderr, "\nParse error: attribute value expected at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ ((int *) vars[i].var)[0] = fg;
+ ((int *) vars[i].var)[1] = bg;
+ ((int *) vars[i].var)[2] = hl;
+ break;
+ }
+ }
+ break;
+ case LINE_ERROR:
+ fprintf(stderr, "\nParse error: syntax error at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ }
+
+ l++; /* next line */
+ }
+
+ fclose(rc_file);
+ return 0; /* parse successful */
+}
+/* End of parse_rc() */
+
+
+/*
+ * Convert an attribute to a string representation like this:
+ *
+ * "(foreground,background,highlight)"
+ */
+static unsigned char *attr_to_str(int fg, int bg, int hl)
+{
+ int i;
+ static unsigned char str[MAX_LEN+1];
+
+ strcpy(str, "(");
+ /* foreground */
+ for (i = 0; fg != color_names[i].value; i++);
+ strcat(str, color_names[i].name);
+ strcat(str, ",");
+
+ /* background */
+ for (i = 0; bg != color_names[i].value; i++);
+ strcat(str, color_names[i].name);
+
+ /* highlight */
+ strcat(str, hl ? ",ON)" : ",OFF)");
+
+ return str;
+}
+/* End of attr_to_str() */
+
+
+/*
+ * Extract the foreground, background and highlight values from an attribute
+ * represented as a string in this form:
+ *
+ * "(foreground,background,highlight)"
+ */
+static int str_to_attr(unsigned char *str, int *fg, int *bg, int *hl)
+{
+ int i = 0, j, get_fg = 1;
+ unsigned char tempstr[MAX_LEN+1], *part;
+
+ if (str[0] != '(' || lastch(str) != ')')
+ return -1; /* invalid representation */
+
+ /* remove the parenthesis */
+ strcpy(tempstr, str + 1);
+ lastch(tempstr) = '\0';
+
+
+ /* get foreground and background */
+
+ while (1) {
+ /* skip white space before fg/bg string */
+ while (whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
+ if (tempstr[i] == '\0')
+ return -1; /* invalid representation */
+ part = tempstr + i; /* set 'part' to start of fg/bg string */
+
+ /* find end of fg/bg string */
+ while(!whitespace(tempstr[i]) && tempstr[i] != ',' && tempstr[i] != '\0') i++;
+
+ if (tempstr[i] == '\0')
+ return -1; /* invalid representation */
+ else if (whitespace(tempstr[i])) { /* not yet ',' */
+ tempstr[i++] = '\0';
+
+ /* skip white space before ',' */
+ while(whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
+
+ if (tempstr[i] != ',')
+ return -1; /* invalid representation */
+ }
+
+ tempstr[i++] = '\0'; /* skip the ',' */
+ for (j = 0; j < COLOR_COUNT && strcasecmp(part, color_names[j].name); j++);
+ if (j == COLOR_COUNT) /* invalid color name */
+ return -1;
+ if (get_fg) {
+ *fg = color_names[j].value;
+ get_fg = 0; /* next we have to get the background */
+ }
+ else {
+ *bg = color_names[j].value;
+ break;
+ }
+ } /* got foreground and background */
+
+
+ /* get highlight */
+
+ /* skip white space before highlight string */
+ while (whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
+ if (tempstr[i] == '\0')
+ return -1; /* invalid representation */
+ part = tempstr + i; /* set 'part' to start of highlight string */
+
+ /* trim trailing white space from highlight string */
+ i = strlen(part) - 1;
+ while(whitespace(part[i])) i--;
+ part[i+1] = '\0';
+
+ if (!strcasecmp(part, "ON"))
+ *hl = TRUE;
+ else if (!strcasecmp(part, "OFF"))
+ *hl = FALSE;
+ else
+ return -1; /* invalid highlight value */
+
+ return 0;
+}
+/* End of str_to_attr() */
+
+
+/*
+ * Parse a line in the configuration file
+ *
+ * Each line is of the form: "variable = value". On exit, 'var' will contain
+ * the variable name, and 'value' will contain the value string.
+ *
+ * Return values:
+ *
+ * LINE_BLANK - line is blank
+ * LINE_COMMENT - line is comment
+ * LINE_OK - line is ok
+ * LINE_ERROR - syntax error in line
+ */
+static int parse_line(unsigned char *line, unsigned char **var, unsigned char **value)
+{
+ int i = 0;
+
+ /* ignore white space at beginning of line */
+ while(whitespace(line[i]) && line[i] != '\0') i++;
+
+ if (line[i] == '\0') /* line is blank */
+ return LINE_BLANK;
+ else if (line[i] == '#') /* line is comment */
+ return LINE_COMMENT;
+ else if (line[i] == '=') /* variables names can't strart with a '=' */
+ return LINE_ERROR;
+
+ /* set 'var' to variable name */
+ *var = line + i++; /* skip to next character */
+
+ /* find end of variable name */
+ while(!whitespace(line[i]) && line[i] != '=' && line[i] != '\0') i++;
+
+ if (line[i] == '\0') /* syntax error */
+ return LINE_ERROR;
+ else if (line[i] == '=')
+ line[i++] = '\0';
+ else {
+ line[i++] = '\0';
+
+ /* skip white space before '=' */
+ while(whitespace(line[i]) && line[i] != '\0') i++;
+
+ if (line[i] != '=') /* syntax error */
+ return LINE_ERROR;
+ else
+ i++; /* skip the '=' */
+ }
+
+ /* skip white space after '=' */
+ while(whitespace(line[i]) && line[i] != '\0') i++;
+
+ if (line[i] == '\0')
+ return LINE_ERROR;
+ else
+ *value = line + i; /* set 'value' to value string */
+
+ /* trim trailing white space from 'value' */
+ i = strlen(*value) - 1;
+ while(whitespace((*value)[i])) i--;
+ (*value)[i+1] = '\0';
+
+ return LINE_OK; /* no syntax error in line */
+}
+/* End of parse_line() */
diff --git a/gnu/usr.bin/dialog/rc.h b/gnu/usr.bin/dialog/rc.h
new file mode 100644
index 0000000..225ff6d
--- /dev/null
+++ b/gnu/usr.bin/dialog/rc.h
@@ -0,0 +1,223 @@
+/*
+ * rc.h -- declarations for configuration file processing
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#define DIALOGRC ".dialogrc"
+#define VAR_LEN 30
+#define COMMENT_LEN 70
+
+/* Types of values */
+#define VAL_INT 0
+#define VAL_STR 1
+#define VAL_BOOL 2
+#define VAL_ATTR 3
+
+/* Type of line in configuration file */
+#define LINE_BLANK 2
+#define LINE_COMMENT 1
+#define LINE_OK 0
+#define LINE_ERROR -1
+
+/* number of configuration variables */
+#define VAR_COUNT (sizeof(vars) / sizeof(vars_st))
+
+/* check if character is white space */
+#define whitespace(c) (c == ' ' || c == '\t')
+
+/* check if character is string quoting characters */
+#define isquote(c) (c == '"' || c == '\'')
+
+/* get last character of string */
+#define lastch(str) str[strlen(str)-1]
+
+/*
+ * Configuration variables
+ */
+typedef struct {
+ unsigned char name[VAR_LEN]; /* name of configuration variable as in DIALOGRC */
+ void *var; /* address of actually variable to change */
+ int type; /* type of value */
+ unsigned char comment[COMMENT_LEN]; /* comment to put in "rc" file */
+} vars_st;
+
+vars_st vars[] = {
+ { "use_shadow",
+ &use_shadow,
+ VAL_BOOL,
+ "Shadow dialog boxes? This also turns on color." },
+
+ { "use_colors",
+ &use_colors,
+ VAL_BOOL,
+ "Turn color support ON or OFF" },
+
+ { "screen_color",
+ color_table[0],
+ VAL_ATTR,
+ "Screen color" },
+
+ { "shadow_color",
+ color_table[1],
+ VAL_ATTR,
+ "Shadow color" },
+
+ { "dialog_color",
+ color_table[2],
+ VAL_ATTR,
+ "Dialog box color" },
+
+ { "title_color",
+ color_table[3],
+ VAL_ATTR,
+ "Dialog box title color" },
+
+ { "border_color",
+ color_table[4],
+ VAL_ATTR,
+ "Dialog box border color" },
+
+ { "button_active_color",
+ color_table[5],
+ VAL_ATTR,
+ "Active button color" },
+
+ { "button_inactive_color",
+ color_table[6],
+ VAL_ATTR,
+ "Inactive button color" },
+
+ { "button_key_active_color",
+ color_table[7],
+ VAL_ATTR,
+ "Active button key color" },
+
+ { "button_key_inactive_color",
+ color_table[8],
+ VAL_ATTR,
+ "Inactive button key color" },
+
+ { "button_label_active_color",
+ color_table[9],
+ VAL_ATTR,
+ "Active button label color" },
+
+ { "button_label_inactive_color",
+ color_table[10],
+ VAL_ATTR,
+ "Inactive button label color" },
+
+ { "inputbox_color",
+ color_table[11],
+ VAL_ATTR,
+ "Input box color" },
+
+ { "inputbox_border_color",
+ color_table[12],
+ VAL_ATTR,
+ "Input box border color" },
+
+ { "searchbox_color",
+ color_table[13],
+ VAL_ATTR,
+ "Search box color" },
+
+ { "searchbox_title_color",
+ color_table[14],
+ VAL_ATTR,
+ "Search box title color" },
+
+ { "searchbox_border_color",
+ color_table[15],
+ VAL_ATTR,
+ "Search box border color" },
+
+ { "position_indicator_color",
+ color_table[16],
+ VAL_ATTR,
+ "File position indicator color" },
+
+ { "menubox_color",
+ color_table[17],
+ VAL_ATTR,
+ "Menu box color" },
+
+ { "menubox_border_color",
+ color_table[18],
+ VAL_ATTR,
+ "Menu box border color" },
+
+ { "item_color",
+ color_table[19],
+ VAL_ATTR,
+ "Item color" },
+
+ { "item_selected_color",
+ color_table[20],
+ VAL_ATTR,
+ "Selected item color" },
+
+ { "tag_color",
+ color_table[21],
+ VAL_ATTR,
+ "Tag color" },
+
+ { "tag_selected_color",
+ color_table[22],
+ VAL_ATTR,
+ "Selected tag color" },
+
+ { "tag_key_color",
+ color_table[23],
+ VAL_ATTR,
+ "Tag key color" },
+
+ { "tag_key_selected_color",
+ color_table[24],
+ VAL_ATTR,
+ "Selected tag key color" },
+
+ { "check_color",
+ color_table[25],
+ VAL_ATTR,
+ "Check box color" },
+
+ { "check_selected_color",
+ color_table[26],
+ VAL_ATTR,
+ "Selected check box color" },
+
+ { "uarrow_color",
+ color_table[27],
+ VAL_ATTR,
+ "Up arrow color" },
+
+ { "darrow_color",
+ color_table[28],
+ VAL_ATTR,
+ "Down arrow color" }
+}; /* vars */
+
+
+
+/*
+ * Routines to process configuration file
+ */
+void create_rc(unsigned char *filename);
+int parse_rc(void);
diff --git a/gnu/usr.bin/dialog/textbox.c b/gnu/usr.bin/dialog/textbox.c
new file mode 100644
index 0000000..23e1283
--- /dev/null
+++ b/gnu/usr.bin/dialog/textbox.c
@@ -0,0 +1,709 @@
+/*
+ * textbox.c -- implements the text box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "dialog.h"
+
+
+static void back_lines(int n);
+static void print_page(WINDOW *win, int height, int width);
+static void print_line(WINDOW *win, int row, int width);
+static unsigned char *get_line(void);
+static int get_search_term(WINDOW *win, unsigned char *search_term, int height, int width);
+static void print_position(WINDOW *win, int height, int width);
+
+
+static int hscroll = 0, fd, file_size, bytes_read, begin_reached = 1,
+ end_reached = 0, page_length;
+static unsigned char *buf, *page;
+
+
+/*
+ * Display text from a file in a dialog box.
+ */
+int dialog_textbox(unsigned char *title, unsigned char *file, int height, int width)
+{
+ int i, x, y, cur_x, cur_y, fpos, key = 0, dir, temp, temp1;
+#ifdef HAVE_NCURSES
+ int passed_end;
+#endif
+ unsigned char search_term[MAX_LEN+1], *tempptr, *found;
+ WINDOW *dialog, *text;
+
+ search_term[0] = '\0'; /* no search term entered yet */
+
+ /* Open input file for reading */
+ if ((fd = open(file, O_RDONLY)) == -1) {
+ endwin();
+ fprintf(stderr, "\nCan't open input file in dialog_textbox().\n");
+ exit(-1);
+ }
+ /* Get file size. Actually, 'file_size' is the real file size - 1,
+ since it's only the last byte offset from the beginning */
+ if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
+ exit(-1);
+ }
+ /* Restore file pointer to beginning of file after getting file size */
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit(-1);
+ }
+ /* Allocate space for read buffer */
+ if ((buf = malloc(BUF_SIZE+1)) == NULL) {
+ endwin();
+ fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n");
+ exit(-1);
+ }
+ if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+ exit(-1);
+ }
+ buf[bytes_read] = '\0'; /* mark end of valid data */
+ page = buf; /* page is pointer to start of page to be displayed */
+
+ /* center dialog box on screen */
+ x = (COLS - width)/2;
+ y = (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ keypad(dialog, TRUE);
+
+ /* Create window for text region, used for scrolling text */
+/* text = newwin(height-4, width-2, y+1, x+1); */
+ text = subwin(dialog, height-4, width-2, y+1, x+1);
+ keypad(text, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ print_button(dialog, " EXIT ", height-2, width/2-4, TRUE);
+ wnoutrefresh(dialog);
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+
+ /* Print first page of text */
+ attr_clear(text, height-4, width-2, dialog_attr);
+ print_page(text, height-4, width-2);
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+
+ while ((key != ESC) && (key != '\n')) {
+ key = wgetch(dialog);
+ switch (key) {
+ case 'E': /* Exit */
+ case 'e':
+ delwin(dialog);
+ free(buf);
+ close(fd);
+ return 0;
+ case 'g': /* First page */
+ case KEY_HOME:
+ if (!begin_reached) {
+ begin_reached = 1;
+ /* First page not in buffer? */
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit(-1);
+ }
+ if (fpos > bytes_read) { /* Yes, we have to read it in */
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit(-1);
+ }
+ if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+ exit(-1);
+ }
+ buf[bytes_read] = '\0';
+ }
+ page = buf;
+ print_page(text, height-4, width-2);
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ break;
+ case 'G': /* Last page */
+#ifdef HAVE_NCURSES
+ case KEY_END:
+#endif
+ end_reached = 1;
+ /* Last page not in buffer? */
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit(-1);
+ }
+ if (fpos < file_size) { /* Yes, we have to read it in */
+ if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit(-1);
+ }
+ if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+ exit(-1);
+ }
+ buf[bytes_read] = '\0';
+ }
+ page = buf + bytes_read;
+ back_lines(height-4);
+ print_page(text, height-4, width-2);
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ break;
+ case 'K': /* Previous line */
+ case 'k':
+ case KEY_UP:
+ if (!begin_reached) {
+ back_lines(page_length+1);
+#ifdef HAVE_NCURSES
+ /* We don't call print_page() here but use scrolling to ensure
+ faster screen update. However, 'end_reached' and 'page_length'
+ should still be updated, and 'page' should point to start of
+ next page. This is done by calling get_line() in the following
+ 'for' loop. */
+ scrollok(text, TRUE);
+ wscrl(text, -1); /* Scroll text region down one line */
+ scrollok(text, FALSE);
+ page_length = 0;
+ passed_end = 0;
+ for (i = 0; i < height-4; i++) {
+ if (!i) {
+ print_line(text, 0, width-2); /* print first line of page */
+ wnoutrefresh(text);
+ }
+ else
+ get_line(); /* Called to update 'end_reached' and 'page' */
+ if (!passed_end)
+ page_length++;
+ if (end_reached && !passed_end)
+ passed_end = 1;
+ }
+#else
+ print_page(text, height-4, width-2);
+#endif
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ break;
+ case 'B': /* Previous page */
+ case 'b':
+ case KEY_PPAGE:
+ if (!begin_reached) {
+ back_lines(page_length + height-4);
+ print_page(text, height-4, width-2);
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ break;
+ case 'J': /* Next line */
+ case 'j':
+ case KEY_DOWN:
+ if (!end_reached) {
+ begin_reached = 0;
+ scrollok(text, TRUE);
+ scroll(text); /* Scroll text region up one line */
+ scrollok(text, FALSE);
+ print_line(text, height-5, width-2);
+#ifndef HAVE_NCURSES
+ wmove(text, height-5, 0);
+ waddch(text, ' ');
+ wmove(text, height-5, width-3);
+ waddch(text, ' ');
+#endif
+ wnoutrefresh(text);
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ break;
+ case ' ': /* Next page */
+ case KEY_NPAGE:
+ if (!end_reached) {
+ begin_reached = 0;
+ print_page(text, height-4, width-2);
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ break;
+ case '0': /* Beginning of line */
+ case 'H': /* Scroll left */
+ case 'h':
+ case KEY_LEFT:
+ if (hscroll > 0) {
+ if (key == '0')
+ hscroll = 0;
+ else
+ hscroll--;
+ /* Reprint current page to scroll horizontally */
+ back_lines(page_length);
+ print_page(text, height-4, width-2);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ break;
+ case 'L': /* Scroll right */
+ case 'l':
+ case KEY_RIGHT:
+ if (hscroll < MAX_LEN) {
+ hscroll++;
+ /* Reprint current page to scroll horizontally */
+ back_lines(page_length);
+ print_page(text, height-4, width-2);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ break;
+ case '/': /* Forward search */
+ case 'n': /* Repeat forward search */
+ case '?': /* Backward search */
+ case 'N': /* Repeat backward search */
+ /* set search direction */
+ dir = (key == '/' || key == 'n') ? 1 : 0;
+ if (dir ? !end_reached : !begin_reached) {
+ if (key == 'n' || key == 'N') {
+ if (search_term[0] == '\0') { /* No search term yet */
+ fprintf(stderr, "\a"); /* beep */
+ break;
+ }
+ }
+ else /* Get search term from user */
+ if (get_search_term(text, search_term, height-4, width-2) == -1) {
+ /* ESC pressed in get_search_term(). Reprint page to clear box */
+ wattrset(text, dialog_attr);
+ back_lines(page_length);
+ print_page(text, height-4, width-2);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ break;
+ }
+ /* Save variables for restoring in case search term can't be found */
+ tempptr = page;
+ temp = begin_reached;
+ temp1 = end_reached;
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit(-1);
+ }
+ fpos -= bytes_read;
+ /* update 'page' to point to next (previous) line before
+ forward (backward) searching */
+ back_lines(dir ? page_length-1 : page_length+1);
+ found = NULL;
+ if (dir) /* Forward search */
+ while((found = strstr(get_line(), search_term)) == NULL) {
+ if (end_reached)
+ break;
+ }
+ else /* Backward search */
+ while((found = strstr(get_line(), search_term)) == NULL) {
+ if (begin_reached)
+ break;
+ back_lines(2);
+ }
+ if (found == NULL) { /* not found */
+ fprintf(stderr, "\a"); /* beep */
+ /* Restore program state to that before searching */
+ if (lseek(fd, fpos, SEEK_SET) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit(-1);
+ }
+ if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+ exit(-1);
+ }
+ buf[bytes_read] = '\0';
+ page = tempptr;
+ begin_reached = temp;
+ end_reached = temp1;
+ /* move 'page' to point to start of current page in order to
+ re-print current page. Note that 'page' always points to
+ start of next page, so this is necessary */
+ back_lines(page_length);
+ }
+ else /* Search term found */
+ back_lines(1);
+ /* Reprint page */
+ wattrset(text, dialog_attr);
+ print_page(text, height-4, width-2);
+ if (found != NULL)
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ else /* no need to find */
+ fprintf(stderr, "\a"); /* beep */
+ break;
+ case ESC:
+ break;
+ }
+ }
+
+ delwin(dialog);
+ free(buf);
+ close(fd);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_textbox() */
+
+
+/*
+ * Go back 'n' lines in text file. Called by dialog_textbox().
+ * 'page' will be updated to point to the desired line in 'buf'.
+ */
+static void back_lines(int n)
+{
+ int i, fpos;
+
+ begin_reached = 0;
+ /* We have to distinguish between end_reached and !end_reached since at end
+ of file, the line is not ended by a '\n'. The code inside 'if' basically
+ does a '--page' to move one character backward so as to skip '\n' of the
+ previous line */
+ if (!end_reached) {
+ /* Either beginning of buffer or beginning of file reached? */
+ if (page == buf) {
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in back_lines().\n");
+ exit(-1);
+ }
+ if (fpos > bytes_read) { /* Not beginning of file yet */
+ /* We've reached beginning of buffer, but not beginning of file yet,
+ so read previous part of file into buffer. Note that we only
+ move backward for BUF_SIZE/2 bytes, but not BUF_SIZE bytes to
+ avoid re-reading again in print_page() later */
+ /* Really possible to move backward BUF_SIZE/2 bytes? */
+ if (fpos < BUF_SIZE/2 + bytes_read) {
+ /* No, move less then */
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in back_lines().\n");
+ exit(-1);
+ }
+ page = buf + fpos - bytes_read;
+ }
+ else { /* Move backward BUF_SIZE/2 bytes */
+ if (lseek(fd, -(BUF_SIZE/2 + bytes_read), SEEK_CUR) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in back_lines().\n");
+ exit(-1);
+ }
+ page = buf + BUF_SIZE/2;
+ }
+ if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError reading file in back_lines().\n");
+ exit(-1);
+ }
+ buf[bytes_read] = '\0';
+ }
+ else { /* Beginning of file reached */
+ begin_reached = 1;
+ return;
+ }
+ }
+ if (*(--page) != '\n') { /* '--page' here */
+ /* Something's wrong... */
+ endwin();
+ fprintf(stderr, "\nInternal error in back_lines().\n");
+ exit(-1);
+ }
+ }
+
+ /* Go back 'n' lines */
+ for (i = 0; i < n; i++)
+ do {
+ if (page == buf) {
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in back_lines().\n");
+ exit(-1);
+ }
+ if (fpos > bytes_read) {
+ /* Really possible to move backward BUF_SIZE/2 bytes? */
+ if (fpos < BUF_SIZE/2 + bytes_read) {
+ /* No, move less then */
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in back_lines().\n");
+ exit(-1);
+ }
+ page = buf + fpos - bytes_read;
+ }
+ else { /* Move backward BUF_SIZE/2 bytes */
+ if (lseek(fd, -(BUF_SIZE/2 + bytes_read), SEEK_CUR) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in back_lines().\n");
+ exit(-1);
+ }
+ page = buf + BUF_SIZE/2;
+ }
+ if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError reading file in back_lines().\n");
+ exit(-1);
+ }
+ buf[bytes_read] = '\0';
+ }
+ else { /* Beginning of file reached */
+ begin_reached = 1;
+ return;
+ }
+ }
+ } while (*(--page) != '\n');
+ page++;
+}
+/* End of back_lines() */
+
+
+/*
+ * Print a new page of text. Called by dialog_textbox().
+ */
+static void print_page(WINDOW *win, int height, int width)
+{
+ int i, passed_end = 0;
+
+ page_length = 0;
+ for (i = 0; i < height; i++) {
+ print_line(win, i, width);
+ if (!passed_end)
+ page_length++;
+ if (end_reached && !passed_end)
+ passed_end = 1;
+ }
+ wnoutrefresh(win);
+}
+/* End of print_page() */
+
+
+/*
+ * Print a new line of text. Called by dialog_textbox() and print_page().
+ */
+static void print_line(WINDOW *win, int row, int width)
+{
+ int i, y, x;
+ unsigned char *line;
+
+ line = get_line();
+ line += MIN(strlen(line),hscroll); /* Scroll horizontally */
+ wmove(win, row, 0); /* move cursor to correct line */
+ waddch(win,' ');
+#ifdef HAVE_NCURSES
+ waddnstr(win, line, MIN(strlen(line),width-2));
+#else
+ line[MIN(strlen(line),width-2)] = '\0';
+ waddstr(win, line);
+#endif
+
+ getyx(win, y, x);
+ /* Clear 'residue' of previous line */
+ for (i = 0; i < width-x; i++)
+ waddch(win, ' ');
+}
+/* End of print_line() */
+
+
+/*
+ * Return current line of text. Called by dialog_textbox() and print_line().
+ * 'page' should point to start of current line before calling, and will be
+ * updated to point to start of next line.
+ */
+static unsigned char *get_line(void)
+{
+ int i = 0, fpos;
+ static unsigned char line[MAX_LEN+1];
+
+ end_reached = 0;
+ while (*page != '\n') {
+ if (*page == '\0') { /* Either end of file or end of buffer reached */
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in get_line().\n");
+ exit(-1);
+ }
+ if (fpos < file_size) { /* Not end of file yet */
+ /* We've reached end of buffer, but not end of file yet, so read next
+ part of file into buffer */
+ if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError reading file in get_line().\n");
+ exit(-1);
+ }
+ buf[bytes_read] = '\0';
+ page = buf;
+ }
+ else {
+ if (!end_reached)
+ end_reached = 1;
+ break;
+ }
+ }
+ else
+ if (i < MAX_LEN)
+ line[i++] = *(page++);
+ else {
+ if (i == MAX_LEN) /* Truncate lines longer than MAX_LEN characters */
+ line[i++] = '\0';
+ page++;
+ }
+ }
+ if (i <= MAX_LEN)
+ line[i] = '\0';
+ if (!end_reached)
+ page++; /* move pass '\n' */
+
+ return line;
+}
+/* End of get_line() */
+
+
+/*
+ * Display a dialog box and get the search term from user
+ */
+static int get_search_term(WINDOW *win, unsigned char *search_term, int height, int width)
+{
+ int i, x, y, input_x = 0, scroll = 0, key = 0,
+ box_height = 3, box_width = 30;
+
+ x = (width - box_width)/2;
+ y = (height - box_height)/2;
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(win, y, x, box_height, box_width);
+#endif
+ draw_box(win, y, x, box_height, box_width, dialog_attr, searchbox_border_attr);
+ wattrset(win, searchbox_title_attr);
+ wmove(win, y, x+box_width/2-4);
+ waddstr(win, " Search ");
+
+ box_width -= 2;
+ wmove(win, y+1, x+1);
+ wrefresh(win);
+ search_term[0] = '\0';
+ wattrset(win, searchbox_attr);
+ while (key != ESC) {
+ key = wgetch(win);
+ switch (key) {
+ case '\n':
+ if (search_term[0] != '\0')
+ return 0;
+ break;
+ case KEY_BACKSPACE:
+ if (input_x || scroll) {
+ if (!input_x) {
+ scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
+ wmove(win, y+1, x+1);
+ for (i = 0; i < box_width; i++)
+ waddch(win, search_term[scroll+input_x+i] ?
+ search_term[scroll+input_x+i] : ' ');
+ input_x = strlen(search_term) - scroll;
+ }
+ else
+ input_x--;
+ search_term[scroll+input_x] = '\0';
+ wmove(win, y+1, input_x + x+1);
+ waddch(win, ' ');
+ wmove(win, y+1, input_x + x+1);
+ wrefresh(win);
+ }
+ break;
+ case ESC:
+ break;
+ default:
+ if (isprint(key))
+ if (scroll+input_x < MAX_LEN) {
+ search_term[scroll+input_x] = key;
+ search_term[scroll+input_x+1] = '\0';
+ if (input_x == box_width-1) {
+ scroll++;
+ wmove(win, y+1, x+1);
+ for (i = 0; i < box_width-1; i++)
+ waddch(win, search_term[scroll+i]);
+ }
+ else {
+ wmove(win, y+1, input_x++ + x+1);
+ waddch(win, key);
+ }
+ wrefresh(win);
+ }
+ }
+ }
+
+ return -1; /* ESC pressed */
+}
+/* End of get_search_term() */
+
+
+/*
+ * Print current position
+ */
+static void print_position(WINDOW *win, int height, int width)
+{
+ int fpos, percent;
+
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in print_position().\n");
+ exit(-1);
+ }
+ wattrset(win, position_indicator_attr);
+ percent = !file_size ? 100 : ((fpos-bytes_read+page-buf)*100)/file_size;
+ wmove(win, height-3, width-9);
+ wprintw(win, "(%3d%%)", percent);
+}
+/* End of print_position() */
diff --git a/gnu/usr.bin/dialog/yesno.c b/gnu/usr.bin/dialog/yesno.c
new file mode 100644
index 0000000..7a9806d
--- /dev/null
+++ b/gnu/usr.bin/dialog/yesno.c
@@ -0,0 +1,113 @@
+/*
+ * yesno.c -- implements the yes/no box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "dialog.h"
+
+
+/*
+ * Display a dialog box with two buttons - Yes and No
+ */
+int dialog_yesno(unsigned char *title, unsigned char * prompt, int height, int width)
+{
+ int i, x, y, key = 0, button = 0;
+ WINDOW *dialog;
+
+ /* center dialog box on screen */
+ x = (COLS - width)/2;
+ y = (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ keypad(dialog, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ wattrset(dialog, dialog_attr);
+ print_autowrap(dialog, prompt, width, 1, 3);
+
+ x = width/2-10;
+ y = height-2;
+ print_button(dialog, " No ", y, x+13, FALSE);
+ print_button(dialog, " Yes ", y, x, TRUE);
+ wrefresh(dialog);
+
+ while (key != ESC) {
+ key = wgetch(dialog);
+ switch (key) {
+ case 'Y':
+ case 'y':
+ delwin(dialog);
+ return 0;
+ case 'N':
+ case 'n':
+ delwin(dialog);
+ return 1;
+ case KEY_BTAB:
+ case TAB:
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ if (!button) {
+ button = 1; /* Indicates "No" button is selected */
+ print_button(dialog, " Yes ", y, x, FALSE);
+ print_button(dialog, " No ", y, x+13, TRUE);
+ }
+ else {
+ button = 0; /* Indicates "Yes" button is selected */
+ print_button(dialog, " No ", y, x+13, FALSE);
+ print_button(dialog, " Yes ", y, x, TRUE);
+ }
+ wrefresh(dialog);
+ break;
+ case ' ':
+ case '\n':
+ delwin(dialog);
+ return button;
+ case ESC:
+ break;
+ }
+ }
+
+ delwin(dialog);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_yesno() */
OpenPOWER on IntegriCloud