Moved from ports, arrow keys allowed to edit input,
back tab key understanded now
This commit is contained in:
parent
33c4dab4f5
commit
c8389f985d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/savio_lam/; revision=3430
339
gnu/usr.bin/dialog/COPYING
Normal file
339
gnu/usr.bin/dialog/COPYING
Normal file
@ -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.
|
11
gnu/usr.bin/dialog/Makefile
Normal file
11
gnu/usr.bin/dialog/Makefile
Normal file
@ -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"
|
161
gnu/usr.bin/dialog/README
Normal file
161
gnu/usr.bin/dialog/README
Normal file
@ -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)
|
32
gnu/usr.bin/dialog/TESTS/checklist
Executable file
32
gnu/usr.bin/dialog/TESTS/checklist
Executable file
@ -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
|
15
gnu/usr.bin/dialog/TESTS/infobox
Executable file
15
gnu/usr.bin/dialog/TESTS/infobox
Executable file
@ -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
|
26
gnu/usr.bin/dialog/TESTS/inputbox
Executable file
26
gnu/usr.bin/dialog/TESTS/inputbox
Executable file
@ -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
|
33
gnu/usr.bin/dialog/TESTS/menubox
Executable file
33
gnu/usr.bin/dialog/TESTS/menubox
Executable file
@ -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
|
14
gnu/usr.bin/dialog/TESTS/msgbox
Executable file
14
gnu/usr.bin/dialog/TESTS/msgbox
Executable file
@ -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
|
42
gnu/usr.bin/dialog/TESTS/textbox
Executable file
42
gnu/usr.bin/dialog/TESTS/textbox
Executable file
@ -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.$$
|
21
gnu/usr.bin/dialog/TESTS/yesno
Executable file
21
gnu/usr.bin/dialog/TESTS/yesno
Executable file
@ -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
|
349
gnu/usr.bin/dialog/checklist.c
Normal file
349
gnu/usr.bin/dialog/checklist.c
Normal file
@ -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() */
|
219
gnu/usr.bin/dialog/colors.h
Normal file
219
gnu/usr.bin/dialog/colors.h
Normal file
@ -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__ */
|
217
gnu/usr.bin/dialog/dialog.1
Normal file
217
gnu/usr.bin/dialog/dialog.1
Normal file
@ -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)
|
545
gnu/usr.bin/dialog/dialog.c
Normal file
545
gnu/usr.bin/dialog/dialog.c
Normal file
@ -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
|
231
gnu/usr.bin/dialog/dialog.h
Normal file
231
gnu/usr.bin/dialog/dialog.h
Normal file
@ -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);
|
||||
|
252
gnu/usr.bin/dialog/inputbox.c
Normal file
252
gnu/usr.bin/dialog/inputbox.c
Normal file
@ -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() */
|
310
gnu/usr.bin/dialog/menubox.c
Normal file
310
gnu/usr.bin/dialog/menubox.c
Normal file
@ -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() */
|
81
gnu/usr.bin/dialog/msgbox.c
Normal file
81
gnu/usr.bin/dialog/msgbox.c
Normal file
@ -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() */
|
353
gnu/usr.bin/dialog/radiolist.c
Normal file
353
gnu/usr.bin/dialog/radiolist.c
Normal file
@ -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() */
|
375
gnu/usr.bin/dialog/rc.c
Normal file
375
gnu/usr.bin/dialog/rc.c
Normal file
@ -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() */
|
223
gnu/usr.bin/dialog/rc.h
Normal file
223
gnu/usr.bin/dialog/rc.h
Normal file
@ -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);
|
709
gnu/usr.bin/dialog/textbox.c
Normal file
709
gnu/usr.bin/dialog/textbox.c
Normal file
@ -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() */
|
113
gnu/usr.bin/dialog/yesno.c
Normal file
113
gnu/usr.bin/dialog/yesno.c
Normal file
@ -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() */
|
Loading…
Reference in New Issue
Block a user