summaryrefslogtreecommitdiffstats
path: root/gnu/lib/libodialog
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2011-01-12 14:55:02 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2011-01-12 14:55:02 +0000
commit3d4e8889889e5e36302454225999f7e146d3219c (patch)
treefa315b999f531039df54ab7af8e99f7e8daad77c /gnu/lib/libodialog
parentb905920a72950a63c9782b4911d252bfac08db6e (diff)
downloadFreeBSD-src-3d4e8889889e5e36302454225999f7e146d3219c.zip
FreeBSD-src-3d4e8889889e5e36302454225999f7e146d3219c.tar.gz
Update dialog to version 20100428. This changes the license under which
dialog is distributed from GPLv2 to LGPLv2 and introduces a number of new features and a new and better libdialog API. The existing libdialog will be kept temporarily as libodialog for compatibility purposes until sade, sysinstall and tzsetup have been either updated or replaced. __FreeBSD_version is now 900030. Discussed on: -current Approved by: core Obtained from: http://invisible-island.net/dialog
Diffstat (limited to 'gnu/lib/libodialog')
-rw-r--r--gnu/lib/libodialog/CHANGES9
-rw-r--r--gnu/lib/libodialog/COPYING339
-rw-r--r--gnu/lib/libodialog/Makefile24
-rw-r--r--gnu/lib/libodialog/README8
-rw-r--r--gnu/lib/libodialog/TESTS/Makefile20
-rw-r--r--gnu/lib/libodialog/TESTS/check1.c83
-rw-r--r--gnu/lib/libodialog/TESTS/check2.c105
-rw-r--r--gnu/lib/libodialog/TESTS/check3.c92
-rw-r--r--gnu/lib/libodialog/TESTS/dselect.c41
-rw-r--r--gnu/lib/libodialog/TESTS/fselect.c44
-rw-r--r--gnu/lib/libodialog/TESTS/ftree1.c45
-rw-r--r--gnu/lib/libodialog/TESTS/ftree1.test73
-rw-r--r--gnu/lib/libodialog/TESTS/ftree2.c47
-rw-r--r--gnu/lib/libodialog/TESTS/ftree2.test73
-rw-r--r--gnu/lib/libodialog/TESTS/gauge.c41
-rw-r--r--gnu/lib/libodialog/TESTS/input1.c45
-rw-r--r--gnu/lib/libodialog/TESTS/input2.c47
-rw-r--r--gnu/lib/libodialog/TESTS/menu1.c96
-rw-r--r--gnu/lib/libodialog/TESTS/menu2.c96
-rw-r--r--gnu/lib/libodialog/TESTS/menu3.c107
-rw-r--r--gnu/lib/libodialog/TESTS/msg.c42
-rw-r--r--gnu/lib/libodialog/TESTS/prgbox.c41
-rw-r--r--gnu/lib/libodialog/TESTS/radio1.c71
-rw-r--r--gnu/lib/libodialog/TESTS/radio2.c89
-rw-r--r--gnu/lib/libodialog/TESTS/radio3.c98
-rw-r--r--gnu/lib/libodialog/TESTS/text.c41
-rw-r--r--gnu/lib/libodialog/TESTS/tree.c111
-rw-r--r--gnu/lib/libodialog/TESTS/yesno.c45
-rw-r--r--gnu/lib/libodialog/TODO36
-rw-r--r--gnu/lib/libodialog/checklist.c661
-rw-r--r--gnu/lib/libodialog/colors.h219
-rw-r--r--gnu/lib/libodialog/dialog.3842
-rw-r--r--gnu/lib/libodialog/dialog.h211
-rw-r--r--gnu/lib/libodialog/dialog.priv.h183
-rw-r--r--gnu/lib/libodialog/dir.c549
-rw-r--r--gnu/lib/libodialog/dir.h38
-rw-r--r--gnu/lib/libodialog/fselect.c402
-rw-r--r--gnu/lib/libodialog/gauge.c79
-rw-r--r--gnu/lib/libodialog/help.c194
-rw-r--r--gnu/lib/libodialog/inputbox.c190
-rw-r--r--gnu/lib/libodialog/kernel.c536
-rw-r--r--gnu/lib/libodialog/lineedit.c213
-rw-r--r--gnu/lib/libodialog/menubox.c469
-rw-r--r--gnu/lib/libodialog/msgbox.c346
-rw-r--r--gnu/lib/libodialog/notify.c53
-rw-r--r--gnu/lib/libodialog/prgbox.c152
-rw-r--r--gnu/lib/libodialog/radiolist.c628
-rw-r--r--gnu/lib/libodialog/raw_popen.c161
-rw-r--r--gnu/lib/libodialog/rc.c375
-rw-r--r--gnu/lib/libodialog/rc.h222
-rw-r--r--gnu/lib/libodialog/textbox.c699
-rw-r--r--gnu/lib/libodialog/tree.c1133
-rw-r--r--gnu/lib/libodialog/ui_objects.c829
-rw-r--r--gnu/lib/libodialog/ui_objects.h114
-rw-r--r--gnu/lib/libodialog/yesno.c169
55 files changed, 11676 insertions, 0 deletions
diff --git a/gnu/lib/libodialog/CHANGES b/gnu/lib/libodialog/CHANGES
new file mode 100644
index 0000000..1467a0e
--- /dev/null
+++ b/gnu/lib/libodialog/CHANGES
@@ -0,0 +1,9 @@
+- Added two variables to call to dialog_menu() to save the position
+ in the menu when choosing a menu-option.
+
+- Added dialog_fselect(), implements a fileselector dialog
+- Added ui-interface objects: Stringobject, Listobject and Buttonobject.
+ The fileselector dialog was built using these objects.
+- changed dialog_menu to use PGUP and PGDN
+- Added dialog_mesgbox, which display text given in a char buffer.
+-
diff --git a/gnu/lib/libodialog/COPYING b/gnu/lib/libodialog/COPYING
new file mode 100644
index 0000000..a43ea21
--- /dev/null
+++ b/gnu/lib/libodialog/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/gnu/lib/libodialog/Makefile b/gnu/lib/libodialog/Makefile
new file mode 100644
index 0000000..b03bb4a
--- /dev/null
+++ b/gnu/lib/libodialog/Makefile
@@ -0,0 +1,24 @@
+# Makefile for libdialog
+# $FreeBSD$
+
+.include <bsd.own.mk>
+
+LIB= odialog
+#MAN= NOMAN
+
+SHLIB_MAJOR= 7
+SRCS= kernel.c rc.c checklist.c inputbox.c menubox.c msgbox.c \
+ lineedit.c radiolist.c textbox.c yesno.c prgbox.c raw_popen.c \
+ fselect.c ui_objects.c dir.c notify.c help.c gauge.c tree.c
+
+CFLAGS+= -I${.CURDIR} -Wall -Wstrict-prototypes -DLOCALE
+
+DPADD= ${LIBNCURSES}
+LDADD= -lncurses
+
+.if ${MK_HTML} != "no"
+FILES= ${EXAMPLES:C;^;${.CURDIR}/TESTS/;}
+FILESDIR= ${SHAREDIR}/examples/libdialog
+.endif
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libodialog/README b/gnu/lib/libodialog/README
new file mode 100644
index 0000000..e5e6d56
--- /dev/null
+++ b/gnu/lib/libodialog/README
@@ -0,0 +1,8 @@
+This library was split out from the `dialog' program for use
+in C programs. For a list of interface functions, see dialog.h.
+For usage examples, see the `dialog' program sources in
+/usr/src/gnu/usr.bin/dialog.
+
+You can additionally use any ncurses functions after init_dialog().
+
+ Ache.
diff --git a/gnu/lib/libodialog/TESTS/Makefile b/gnu/lib/libodialog/TESTS/Makefile
new file mode 100644
index 0000000..65e3d71
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/Makefile
@@ -0,0 +1,20 @@
+# Really quick and evil Makefile for building all the tests. I wish that
+# bmake was friendlier to the concept of multiple progs/libs in the same
+# directory.
+#
+# $FreeBSD$
+
+PROGS= msg yesno prgbox gauge dselect fselect text menu1 menu2 menu3 \
+ input1 input2 check1 check2 check3 radio1 radio2 radio3 \
+ ftree1 ftree2 tree
+
+WARNS?= 2
+CFLAGS+= -Wall -Wstrict-prototypes
+LDFLAGS+= -ldialog
+
+all: ${PROGS}
+
+clean:
+ rm -f ${PROGS}
+
+.include <bsd.prog.mk>
diff --git a/gnu/lib/libodialog/TESTS/check1.c b/gnu/lib/libodialog/TESTS/check1.c
new file mode 100644
index 0000000..a2bec62
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/check1.c
@@ -0,0 +1,83 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Hook functions */
+
+static int
+getBool(dialogMenuItem *self)
+{
+ if (self->data && *((int *)self->data))
+ return TRUE;
+ return FALSE;
+}
+
+static int
+setBool(dialogMenuItem *self)
+{
+ if (self->data) {
+ *((int *)self->data) = !*((int *)self->data);
+ return DITEM_SUCCESS;
+ }
+ return DITEM_FAILURE;
+}
+
+static int german_book, italian_book, slang_book;
+
+static int
+clearBooks(dialogMenuItem *self)
+{
+ german_book = italian_book = slang_book = FALSE;
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+/* menu2 - A more advanced way of using checked and fire hooks to manipulate the backing-variables directly */
+/* prompt title checked fire sel data */
+static dialogMenuItem menu2[] = {
+ { "German", "Buy book on learning German", getBool, setBool, NULL, &german_book},
+ { "Italian", "Buy book on learning Italian", getBool, setBool, NULL, &italian_book },
+ { "Slang", "Buy book on commonly used insults", getBool, setBool, NULL, &slang_book },
+ { "Clear", "Clear book list", NULL, clearBooks, NULL, NULL, ' ', ' ', ' ' },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_checklist("this is a dialog_checklist() in action, test #1",
+ "this checklist menu shows off some of the straight-forward features\n"
+ "of the new menu system's check & fire dispatch hooks", -1, -1, 4, -4, menu2, NULL);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_checklist was %d (%d %d %d)\n", retval, german_book, italian_book, slang_book);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/check2.c b/gnu/lib/libodialog/TESTS/check2.c
new file mode 100644
index 0000000..3608261
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/check2.c
@@ -0,0 +1,105 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Hook functions */
+
+static int
+getBool(dialogMenuItem *self)
+{
+ if (self->data && *((int *)self->data))
+ return TRUE;
+ return FALSE;
+}
+
+static int
+setBool(dialogMenuItem *self)
+{
+ if (self->data) {
+ *((int *)self->data) = !*((int *)self->data);
+ return DITEM_SUCCESS;
+ }
+ return DITEM_FAILURE;
+}
+
+static int german_book, italian_book, slang_book;
+
+static int
+clearBooks(dialogMenuItem *self)
+{
+ german_book = italian_book = slang_book = FALSE;
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+static int
+buyBooks(dialogMenuItem *self)
+{
+ char foo[256];
+
+ if (german_book || italian_book || slang_book) {
+ strcpy(foo, "Ok, you're buying books on");
+ if (german_book)
+ strcat(foo, " german");
+ if (italian_book)
+ strcat(foo, " italian");
+ if (slang_book)
+ strcat(foo, " slang");
+ }
+ else
+ strcpy(foo, "You're not buying any books?");
+ dialog_mesgbox("This is a direct callback for the `Buy' button", foo, -1, -1);
+ return DITEM_SUCCESS;
+}
+
+/* menu3 - Look mom! We can finally use our own OK and Cancel buttons! */
+/* prompt title checked fire sel data */
+static dialogMenuItem menu3[] = {
+ { "Buy!", NULL, NULL, buyBooks }, /* New "OK" button */
+ { "No Way!", NULL, NULL, NULL }, /* New "Cancel" button */
+ { "German", "Buy books on learning German", getBool, setBool, NULL, &german_book },
+ { "Italian", "Buy books on learning Italian", getBool, setBool, NULL, &italian_book },
+ { "Slang", "Buy books on commonly used insults", getBool, setBool, NULL, &slang_book },
+ { "Clear", "Clear book list", NULL, clearBooks, NULL, NULL, ' ', ' ', ' ' },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_checklist("this is dialog_checklist() in action, test #2",
+ "Same as before, but now we relabel the buttons and override the OK action.",
+ -1, -1, 4, -4, menu3 + 2, (char *)TRUE);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_checklist was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/check3.c b/gnu/lib/libodialog/TESTS/check3.c
new file mode 100644
index 0000000..f117bd6
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/check3.c
@@ -0,0 +1,92 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Hook functions */
+
+static int
+getBool(dialogMenuItem *self)
+{
+ if (self->data && *((int *)self->data))
+ return TRUE;
+ return FALSE;
+}
+
+static int
+setBool(dialogMenuItem *self)
+{
+ if (self->data) {
+ *((int *)self->data) = !*((int *)self->data);
+ return DITEM_SUCCESS;
+ }
+ return DITEM_FAILURE;
+}
+
+static int german_book, italian_book, slang_book;
+static int spending;
+
+static int
+check(dialogMenuItem *self)
+{
+ return ((int)(intptr_t)self->data == spending);
+}
+
+static int
+spend(dialogMenuItem *self)
+{
+ spending = (int)(intptr_t)self->data;
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+/* menu4 - Show off a simulated compound menu (group at top is checklist, group at bottom radio) */
+/* prompt title checked fire sel, data lbra mark rbra */
+static dialogMenuItem menu4[] = {
+ { "German", "Buy books on learning German", getBool, setBool, NULL, &german_book },
+ { "Italian","Buy books on learning Italian", getBool, setBool, NULL, &italian_book },
+ { "Slang", "Buy books on commonly used insults", getBool, setBool, NULL, &slang_book },
+ { "-----", "----------------------------------", NULL, NULL, NULL, NULL, ' ', ' ', ' ' },
+ { "1000", "Spend $1,000", check, spend, NULL, (void *)1000, '(', '*', ')' },
+ { "500", "Spend $500", check, spend, NULL, (void *)500, '(', '*', ')' },
+ { "100", "Spend $100", check, spend, NULL, (void *)100, '(', '*', ')' },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+
+ init_dialog();
+
+
+ retval = dialog_checklist("this is dialog_checklist() in action, test #3",
+ "Now we show off some of the button 'styles' one can create.",
+ -1, -1, 7, -7, menu4, NULL);
+ dialog_clear();
+ fprintf(stderr, "spent $%d on %s%s%s books\n", spending, german_book ? " german" : "",
+ italian_book ? " italian" : "", slang_book ? " slang" : "");
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/dselect.c b/gnu/lib/libodialog/TESTS/dselect.c
new file mode 100644
index 0000000..1110379
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/dselect.c
@@ -0,0 +1,41 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_dselect(".", "*");
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_dselect was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/fselect.c b/gnu/lib/libodialog/TESTS/fselect.c
new file mode 100644
index 0000000..6cefaf3
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/fselect.c
@@ -0,0 +1,44 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ char *retval;
+
+ init_dialog();
+
+ retval = dialog_fselect(".", "*.[ch]");
+ dialog_clear();
+ if (retval)
+ fprintf(stderr, "returned value for dialog_fselect was %s\n", retval);
+ else
+ fprintf(stderr, "returned value for dialog_fselect was NULL\n");
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/ftree1.c b/gnu/lib/libodialog/TESTS/ftree1.c
new file mode 100644
index 0000000..f21e0e5
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/ftree1.c
@@ -0,0 +1,45 @@
+/*
+ * ftree1.c
+ *
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1998, Anatoly A. Orehovsky
+ *
+ * file ./ftree1.test with xterm widget tree from
+ * direct editres(1) dump needed !!!
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dialog.h>
+
+int
+main(int argc, char **argv)
+{
+ int retval;
+ unsigned char *tresult;
+
+ init_dialog();
+ retval = dialog_ftree("ftree1.test", '\t',
+ "ftree dialog box example",
+ "xterm widget tree from direct editres(1) dump",
+ -1, -1, 15,
+ &tresult);
+
+ dialog_update();
+
+ dialog_clear();
+
+ end_dialog();
+
+ if (!retval)
+ {
+ puts(tresult);
+ free(tresult);
+ }
+
+ exit(retval);
+}
diff --git a/gnu/lib/libodialog/TESTS/ftree1.test b/gnu/lib/libodialog/TESTS/ftree1.test
new file mode 100644
index 0000000..4a8f0fa
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/ftree1.test
@@ -0,0 +1,73 @@
+XTerm login
+ VendorShellExt shellext
+ VT100 vt100
+ SimpleMenu fontMenu
+ SmeBSB menuLabel
+ SmeBSB fontdefault
+ SmeBSB font1
+ SmeBSB font2
+ SmeBSB font3
+ SmeBSB font4
+ SmeBSB font5
+ SmeBSB font6
+ SmeBSB fontescape
+ SmeBSB fontsel
+ SimpleMenu mainMenu
+ SmeBSB menuLabel
+ SmeBSB securekbd
+ SmeBSB allowsends
+ SmeBSB redraw
+ SmeLine line1
+ SmeBSB 8-bit control
+ SmeBSB sun function-keys
+ SmeLine line2
+ SmeBSB suspend
+ SmeBSB continue
+ SmeBSB interrupt
+ SmeBSB hangup
+ SmeBSB terminate
+ SmeBSB kill
+ SmeLine line3
+ SmeBSB quit
+ SimpleMenu vtMenu
+ SmeBSB menuLabel
+ SmeBSB scrollbar
+ SmeBSB jumpscroll
+ SmeBSB reversevideo
+ SmeBSB autowrap
+ SmeBSB reversewrap
+ SmeBSB autolinefeed
+ SmeBSB appcursor
+ SmeBSB appkeypad
+ SmeBSB scrollkey
+ SmeBSB scrollttyoutput
+ SmeBSB allow132
+ SmeBSB cursesemul
+ SmeBSB visualbell
+ SmeBSB marginbell
+ SmeBSB altscreen
+ SmeLine line1
+ SmeBSB softreset
+ SmeBSB hardreset
+ SmeBSB clearsavedlines
+ SmeLine line2
+ SmeBSB tekshow
+ SmeBSB tekmode
+ SmeBSB vthide
+ TopLevelShell tektronix
+ VendorShellExt shellext
+ Tek4014 tek4014
+ SimpleMenu tekMenu
+ SmeBSB menuLabel
+ SmeBSB tektextlarge
+ SmeBSB tektext2
+ SmeBSB tektext3
+ SmeBSB tektextsmall
+ SmeLine line1
+ SmeBSB tekpage
+ SmeBSB tekreset
+ SmeBSB tekcopy
+ SmeLine line2
+ SmeBSB vtshow
+ SmeBSB vtmode
+ SmeBSB tekhide
diff --git a/gnu/lib/libodialog/TESTS/ftree2.c b/gnu/lib/libodialog/TESTS/ftree2.c
new file mode 100644
index 0000000..aa4663a
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/ftree2.c
@@ -0,0 +1,47 @@
+/*
+ * ftree2.c
+ *
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1998, Anatoly A. Orehovsky
+ *
+ * file ./ftree2.test with xterm widget tree from
+ * preprocess editres(1) dump needed !!!
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dialog.h>
+
+int
+main(int argc, char **argv)
+{
+ int retval;
+ unsigned char *tresult;
+
+ init_dialog();
+ use_helpfile("ftree2.test");
+ use_helpline("Press Arrows, Tab, Enter or F1");
+ retval = dialog_ftree("ftree2.test", '\t',
+ "ftree dialog box example",
+ "xterm widget tree from preprocess editres(1) dump",
+ -1, -1, 15,
+ &tresult);
+
+ dialog_update();
+
+ dialog_clear();
+
+ end_dialog();
+
+ if (!retval)
+ {
+ puts(tresult);
+ free(tresult);
+ }
+
+ exit(retval);
+}
diff --git a/gnu/lib/libodialog/TESTS/ftree2.test b/gnu/lib/libodialog/TESTS/ftree2.test
new file mode 100644
index 0000000..0850862
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/ftree2.test
@@ -0,0 +1,73 @@
+XTerm login
+XTerm login VendorShellExt shellext
+XTerm login VT100 vt100
+XTerm login SimpleMenu fontMenu
+XTerm login SimpleMenu fontMenu SmeBSB menuLabel
+XTerm login SimpleMenu fontMenu SmeBSB fontdefault
+XTerm login SimpleMenu fontMenu SmeBSB font1
+XTerm login SimpleMenu fontMenu SmeBSB font2
+XTerm login SimpleMenu fontMenu SmeBSB font3
+XTerm login SimpleMenu fontMenu SmeBSB font4
+XTerm login SimpleMenu fontMenu SmeBSB font5
+XTerm login SimpleMenu fontMenu SmeBSB font6
+XTerm login SimpleMenu fontMenu SmeBSB fontescape
+XTerm login SimpleMenu fontMenu SmeBSB fontsel
+XTerm login SimpleMenu mainMenu
+XTerm login SimpleMenu mainMenu SmeBSB menuLabel
+XTerm login SimpleMenu mainMenu SmeBSB securekbd
+XTerm login SimpleMenu mainMenu SmeBSB allowsends
+XTerm login SimpleMenu mainMenu SmeBSB redraw
+XTerm login SimpleMenu mainMenu SmeLine line1
+XTerm login SimpleMenu mainMenu SmeBSB 8-bit control
+XTerm login SimpleMenu mainMenu SmeBSB sun function-keys
+XTerm login SimpleMenu mainMenu SmeLine line2
+XTerm login SimpleMenu mainMenu SmeBSB suspend
+XTerm login SimpleMenu mainMenu SmeBSB continue
+XTerm login SimpleMenu mainMenu SmeBSB interrupt
+XTerm login SimpleMenu mainMenu SmeBSB hangup
+XTerm login SimpleMenu mainMenu SmeBSB terminate
+XTerm login SimpleMenu mainMenu SmeBSB kill
+XTerm login SimpleMenu mainMenu SmeLine line3
+XTerm login SimpleMenu mainMenu SmeBSB quit
+XTerm login SimpleMenu vtMenu
+XTerm login SimpleMenu vtMenu SmeBSB menuLabel
+XTerm login SimpleMenu vtMenu SmeBSB scrollbar
+XTerm login SimpleMenu vtMenu SmeBSB jumpscroll
+XTerm login SimpleMenu vtMenu SmeBSB reversevideo
+XTerm login SimpleMenu vtMenu SmeBSB autowrap
+XTerm login SimpleMenu vtMenu SmeBSB reversewrap
+XTerm login SimpleMenu vtMenu SmeBSB autolinefeed
+XTerm login SimpleMenu vtMenu SmeBSB appcursor
+XTerm login SimpleMenu vtMenu SmeBSB appkeypad
+XTerm login SimpleMenu vtMenu SmeBSB scrollkey
+XTerm login SimpleMenu vtMenu SmeBSB scrollttyoutput
+XTerm login SimpleMenu vtMenu SmeBSB allow132
+XTerm login SimpleMenu vtMenu SmeBSB cursesemul
+XTerm login SimpleMenu vtMenu SmeBSB visualbell
+XTerm login SimpleMenu vtMenu SmeBSB marginbell
+XTerm login SimpleMenu vtMenu SmeBSB altscreen
+XTerm login SimpleMenu vtMenu SmeLine line1
+XTerm login SimpleMenu vtMenu SmeBSB softreset
+XTerm login SimpleMenu vtMenu SmeBSB hardreset
+XTerm login SimpleMenu vtMenu SmeBSB clearsavedlines
+XTerm login SimpleMenu vtMenu SmeLine line2
+XTerm login SimpleMenu vtMenu SmeBSB tekshow
+XTerm login SimpleMenu vtMenu SmeBSB tekmode
+XTerm login SimpleMenu vtMenu SmeBSB vthide
+XTerm login TopLevelShell tektronix
+XTerm login TopLevelShell tektronix VendorShellExt shellext
+XTerm login TopLevelShell tektronix Tek4014 tek4014
+XTerm login SimpleMenu tekMenu
+XTerm login SimpleMenu tekMenu SmeBSB menuLabel
+XTerm login SimpleMenu tekMenu SmeBSB tektextlarge
+XTerm login SimpleMenu tekMenu SmeBSB tektext2
+XTerm login SimpleMenu tekMenu SmeBSB tektext3
+XTerm login SimpleMenu tekMenu SmeBSB tektextsmall
+XTerm login SimpleMenu tekMenu SmeLine line1
+XTerm login SimpleMenu tekMenu SmeBSB tekpage
+XTerm login SimpleMenu tekMenu SmeBSB tekreset
+XTerm login SimpleMenu tekMenu SmeBSB tekcopy
+XTerm login SimpleMenu tekMenu SmeLine line2
+XTerm login SimpleMenu tekMenu SmeBSB vtshow
+XTerm login SimpleMenu tekMenu SmeBSB vtmode
+XTerm login SimpleMenu tekMenu SmeBSB tekhide
diff --git a/gnu/lib/libodialog/TESTS/gauge.c b/gnu/lib/libodialog/TESTS/gauge.c
new file mode 100644
index 0000000..bf0cfc9
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/gauge.c
@@ -0,0 +1,41 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int i;
+
+ init_dialog();
+
+ for (i = 0; i <= 100; i++) {
+ dialog_gauge("Gas tank", "When this gets 100% full, you'd better yank out the nozzle!", 10, 1, 7, 70, i);
+ usleep(30000);
+ }
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/input1.c b/gnu/lib/libodialog/TESTS/input1.c
new file mode 100644
index 0000000..3751071
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/input1.c
@@ -0,0 +1,45 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+ unsigned char result[128];
+
+ init_dialog();
+
+ strcpy(result, "not this!");
+ retval = dialog_inputbox("this is dialog_inputbox() in action, test #1",
+ "Enter something really profound below, please.",
+ -1, -1, result);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_inputbox was %d (%s)\n", retval, result);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/input2.c b/gnu/lib/libodialog/TESTS/input2.c
new file mode 100644
index 0000000..827c052
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/input2.c
@@ -0,0 +1,47 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+ unsigned char result[128];
+
+ init_dialog();
+
+ result[0]='\0';
+ DialogInputAttrs |= DITEM_NO_ECHO;
+ retval = dialog_inputbox("this is dialog_inputbox() in action, test #2 (no echo)",
+ "Enter something really secret below, please.",
+ -1, -1, result);
+ DialogInputAttrs &= DITEM_NO_ECHO;
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_inputbox was %d (%s)\n", retval, result);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/menu1.c b/gnu/lib/libodialog/TESTS/menu1.c
new file mode 100644
index 0000000..640157a
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/menu1.c
@@ -0,0 +1,96 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Start of hook functions */
+static enum { nowhere, berlin, rome, ny } where;
+
+static int
+_menu1_berlin_action(dialogMenuItem *self)
+{
+ if (where == berlin) {
+ dialog_mesgbox("excuse me?", "But you're already *in* Berlin!", -1, -1);
+ }
+ else {
+ where = berlin;
+ dialog_mesgbox("whoosh!", "Welcome to Berlin! Have a beer!", -1, -1);
+ }
+ return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
+}
+
+static int
+_menu1_rome_action(dialogMenuItem *self)
+{
+ if (where == rome) {
+ dialog_mesgbox("The wine must be getting to you..", "You're already in Rome!", -1, -1);
+ }
+ else {
+ where = rome;
+ dialog_mesgbox("whoosh!", "Welcome to Rome! Have a coffee!", -1, -1);
+ }
+ return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
+}
+
+static int
+_menu1_ny_action(dialogMenuItem *self)
+{
+ if (where == ny) {
+ dialog_mesgbox("Say what?", "You're already there!", -1, -1);
+ }
+ else {
+ where = ny;
+ dialog_mesgbox("whoosh!", "Welcome to New York! Now go someplace else!", -1, -1);
+ }
+ return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
+}
+
+/* menu1 - show off the "fire" action hook */
+/* prompt title checked fire */
+static dialogMenuItem menu1[] = {
+ { "Berlin", "Go visit Germany's new capitol", NULL, _menu1_berlin_action },
+ { "Rome", "Go visit the Roman ruins", NULL, _menu1_rome_action },
+ { "New York", "Go visit the streets of New York", NULL, _menu1_ny_action },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_menu("this is dialog_menu() in action, test #1",
+ "this simple menu shows off some of the straight-forward features\n"
+ "of the new menu system's action dispatch hooks. Select Cancel to leave",
+ -1, -1, 3, -3, menu1, NULL, NULL, NULL);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_menu was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/menu2.c b/gnu/lib/libodialog/TESTS/menu2.c
new file mode 100644
index 0000000..1545cd8
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/menu2.c
@@ -0,0 +1,96 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Start of hook functions */
+static enum { nowhere, berlin, rome, ny } where;
+
+static int
+_menu1_berlin_action(dialogMenuItem *self)
+{
+ if (where == berlin)
+ dialog_mesgbox("excuse me?", "But you're already *in* Berlin!", -1, -1);
+ else {
+ where = berlin;
+ dialog_mesgbox("whoosh!", "Welcome to Berlin! Have a beer!", -1, -1);
+ }
+ return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
+}
+
+static int
+_menu1_rome_action(dialogMenuItem *self)
+{
+ if (where == rome)
+ dialog_mesgbox("The wine must be getting to you..", "You're already in Rome!", -1, -1);
+ else {
+ where = rome;
+ dialog_mesgbox("whoosh!", "Welcome to Rome! Have a coffee!", -1, -1);
+ }
+ return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
+}
+
+static int
+_menu1_ny_action(dialogMenuItem *self)
+{
+ if (where == ny)
+ dialog_mesgbox("Say what?", "You're already there!", -1, -1);
+ else {
+ where = ny;
+ dialog_mesgbox("whoosh!", "Welcome to New York! Now go someplace else!", -1, -1);
+ }
+ return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
+}
+
+/* menu1 - show off the "fire" action hook */
+/* prompt title checked fire */
+static dialogMenuItem menu1[] = {
+ { "Berlin", "Go visit Germany's new capitol", NULL, _menu1_berlin_action },
+ { "Rome", "Go visit the Roman ruins", NULL, _menu1_rome_action },
+ { "New York", "Go visit the streets of New York", NULL, _menu1_ny_action },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+
+ init_dialog();
+
+ use_helpfile("menu2.c");
+ use_helpline("Type F1 to view the source for this demo");
+ retval = dialog_menu("this is dialog_menu() in action, test #2",
+ "this simple menu shows off some of the straight-forward features\n"
+ "of the new menu system's action dispatch hooks as well as a helpline\n"
+ "and a helpfile. Select Cancel to leave",
+ -1, -1, 3, -3, menu1, NULL, NULL, NULL);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_menu was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/menu3.c b/gnu/lib/libodialog/TESTS/menu3.c
new file mode 100644
index 0000000..3a7a137
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/menu3.c
@@ -0,0 +1,107 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Hook functions */
+
+static int
+stop(dialogMenuItem *self)
+{
+ dialog_mesgbox("!", "I'm no idiot!", -1, -1);
+ return DITEM_SUCCESS;
+}
+
+static int
+maybe(dialogMenuItem *self)
+{
+ dialog_mesgbox("!", "I said don't rush me! I'm THINKING!", -1, -1);
+ return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
+}
+
+/* Dummy menu just to show of the ability */
+static char *insurance[] = {
+ "1,000,000", "Mondo insurance policy", "Off",
+ "5,000,000", "Mega insurance policy", "Off",
+ "10,000,000", "Friend! Most Favored customer!", "On"
+};
+
+static void
+preinsure(dialogMenuItem *self, int is_selected)
+{
+ if (is_selected) {
+ static WINDOW *w;
+
+ /* This has to be here first if you want to see selection traverse properly in the invoking menu */
+ refresh();
+
+ w = dupwin(newscr);
+ DialogX = 1;
+ DialogY = 13;
+ dialog_radiolist("How much insurance would you like to take out?",
+ "If you're really going to do this, we recommend some insurance\n"
+ "first! What kind of life insurance policy would you like?",
+ -1, -1, 3, 3, insurance, NULL);
+ touchwin(w);
+ wrefresh(w);
+ delwin(w);
+ }
+}
+
+/*
+ * Show a simple menu that puts up a sub menu when a certain item is traversed to
+ */
+
+/* prompt title checked fire sel */
+static dialogMenuItem doit[] = {
+ { "Rah!" },
+ { "No way!" },
+ { "Stop", "No, I'm not going to do that!", NULL, stop, NULL },
+ { "Maybe", "I'm still thinking about it, don't rush me!", NULL, maybe, NULL, },
+ { "Go", "Yes! Yes! I want to do it!", NULL, NULL, preinsure },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+
+ init_dialog();
+
+
+ DialogX = 5;
+ DialogY = 1;
+ retval = dialog_menu("Do you have the GUTS?",
+ "C'mon, macho man! Do you have what it takes to do something REALLY\n"
+ "dangerous and stupid? WHAT ARE YOU WAITING FOR?!",
+ -1, -1, 3, -3, doit + 2, (char *)TRUE, NULL, NULL);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_menu was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/msg.c b/gnu/lib/libodialog/TESTS/msg.c
new file mode 100644
index 0000000..c6f590f
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/msg.c
@@ -0,0 +1,42 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_msgbox("This is dialog_msgbox() in action with pause on", "Hi there. Please press return now.",
+ -1, -1, 1);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_msgbox was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/prgbox.c b/gnu/lib/libodialog/TESTS/prgbox.c
new file mode 100644
index 0000000..2da4611
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/prgbox.c
@@ -0,0 +1,41 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_prgbox("This is dialog_prgbox() in action with cal(1)", "cal", 14, 50, TRUE, TRUE);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_prgbox was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/radio1.c b/gnu/lib/libodialog/TESTS/radio1.c
new file mode 100644
index 0000000..c4eeffd
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/radio1.c
@@ -0,0 +1,71 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Hook functions */
+
+static int spending;
+
+static int
+check(dialogMenuItem *self)
+{
+ return ((int)(intptr_t)self->data == spending);
+}
+
+static int
+spend(dialogMenuItem *self)
+{
+ spending = (int)(intptr_t)self->data;
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+/* menu5 - Show a simple radiolist menu that inherits the radio appearance by default */
+/* prompt title checked fire sel data */
+static dialogMenuItem menu5[] = {
+ { "1000", "Spend $1,000", check, spend, NULL, (void *)1000 },
+ { "500", "Spend $500", check, spend, NULL, (void *)500 },
+ { "100", "Spend $100", check, spend, NULL, (void *)100 },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+
+ init_dialog();
+
+
+ retval = dialog_radiolist("this is dialog_radiolist() in action, test #1",
+ "this radio menu shows off some of the straight-forward features\n"
+ "of the new menu system's check & fire dispatch hooks", -1, -1, 3, -3, menu5, NULL);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_radiolist was %d (money set to %d)\n", retval, spending);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/radio2.c b/gnu/lib/libodialog/TESTS/radio2.c
new file mode 100644
index 0000000..15e353c
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/radio2.c
@@ -0,0 +1,89 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Hook functions */
+
+static char bachelor[10], bachelette[10];
+
+static int
+getBachelor(dialogMenuItem *self)
+{
+ return !strcmp(bachelor, self->prompt);
+}
+
+static int
+setBachelor(dialogMenuItem *self)
+{
+ strcpy(bachelor, self->prompt);
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+static int
+getBachelette(dialogMenuItem *self)
+{
+ return !strcmp(bachelette, self->prompt);
+}
+
+static int
+setBachelette(dialogMenuItem *self)
+{
+ strcpy(bachelette, self->prompt);
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+/* menu6- More complex radiolist menu that creates two groups in a single menu */
+/* prompt title checked fire */
+static dialogMenuItem menu6[] = {
+ { "Tom", "Tom's a dynamic shoe salesman from Tulsa, OK!", getBachelor, setBachelor },
+ { "Dick", "Dick's a retired engine inspector from McDonnell-Douglas!", getBachelor, setBachelor },
+ { "Harry", "Harry's a professional female impersonator from Las Vegas!", getBachelor, setBachelor },
+ { "-----", "----------------------------------", NULL, NULL, NULL, NULL, ' ', ' ', ' ' },
+ { "Jane", "Jane's a twice-divorced housewife from Moose, Oregon!", getBachelette, setBachelette },
+ { "Sally", "Sally's a shy Human Resources Manager for IBM!", getBachelette, setBachelette },
+ { "Mary", "Mary's an energetic serial killer on the lam!", getBachelette, setBachelette },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_radiolist("this is dialog_radiolist() in action, test #2",
+ "Welcome to \"The Love Blender!\" - America's favorite game show\n"
+ "where YOU, the contestant, get to choose which of these two\n"
+ "fine specimens of humanity will go home together, whether they\n"
+ "like it or not!", -1, -1, 7, -7, menu6, NULL);
+ dialog_clear();
+ fprintf(stderr, "I'm sure that %s and %s will be very happy together!\n", bachelor, bachelette);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/radio3.c b/gnu/lib/libodialog/TESTS/radio3.c
new file mode 100644
index 0000000..2175358
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/radio3.c
@@ -0,0 +1,98 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Hook functions */
+
+static int spending;
+
+static int
+check(dialogMenuItem *self)
+{
+ return ((int)(intptr_t)self->data == spending);
+}
+
+static int
+spend(dialogMenuItem *self)
+{
+ spending = (int)(intptr_t)self->data;
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+static void
+ask(dialogMenuItem *self, int is_selected)
+{
+ if (is_selected) {
+ char *str;
+
+ if (!strcmp(self->prompt, "1000"))
+ str = "You'd better ask both your parents first! ";
+ else if (!strcmp(self->prompt, "500"))
+ str = "You'd better at least ask your Dad! ";
+ else
+ str = "Yes, being frugal is probably a good idea!";
+ DialogX = 15;
+ DialogY = 17;
+ dialog_msgbox("Free Advice", str, -1, -1, 0);
+ }
+}
+
+/*
+ * menu5 - Show a simple radiolist menu that inherits the radio appearance by default and appears at
+ * a different location, leaving room for a msg box below it. This shows off the DialogX/DialogY extensions.
+ */
+
+/* prompt title checked fire sel data */
+static dialogMenuItem menu5[] = {
+ { "1000", "Spend $1,000", check, spend, ask, (void *)1000 },
+ { "500", "Spend $500", check, spend, ask, (void *)500 },
+ { "100", "Spend $100", check, spend, ask, (void *)100 },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+
+ init_dialog();
+
+
+ DialogX = 5;
+ DialogY = 1;
+ retval = dialog_radiolist("this is dialog_radiolist() in action, test #3",
+ "This radio menu shows off the ability to put dialog menus and other\n"
+ "controls at different locations, as well as the `selected' hook which\n"
+ "lets you follow the traversal of the selection bar as well as what's\n"
+ "selected.",
+ -1, -1, 3, -3, menu5, NULL);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_radiolist was %d (money set to %d)\n", retval, spending);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/text.c b/gnu/lib/libodialog/TESTS/text.c
new file mode 100644
index 0000000..e071937
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/text.c
@@ -0,0 +1,41 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_textbox("This is dialog_textbox() in action with /etc/passwd", "/etc/passwd", 10, 60);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_textbox was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TESTS/tree.c b/gnu/lib/libodialog/TESTS/tree.c
new file mode 100644
index 0000000..c69b52e
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/tree.c
@@ -0,0 +1,111 @@
+/*
+ * tree.c
+ *
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1998, Anatoly A. Orehovsky
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dialog.h>
+
+unsigned char *names[] = {
+ "/",
+ "/dev",
+ "/dev/fd",
+ "/tmp",
+ "/usr",
+ "/var",
+ "/home",
+ "/stand",
+ "/stand/etc",
+ "/stand/en_US.ISO8859-1",
+ "/stand/info",
+ "/stand/info/bin",
+ "/stand/info/des",
+ "/stand/info/games",
+ "/stand/info/manpages",
+ "/stand/info/proflibs",
+ "/stand/info/dict",
+ "/stand/info/info",
+ "/stand/info/src",
+ "/etc",
+ "/etc/gnats",
+ "/etc/kerberosIV",
+ "/etc/mtree",
+ "/etc/namedb",
+ "/etc/ppp",
+ "/etc/uucp",
+ "/etc/sliphome",
+ "/proc",
+ "/lkm",
+ "/mnt",
+ "/root",
+ "/sbin",
+ "/bin",
+ 0
+};
+
+unsigned char *names1[] = {
+ "a",
+ "a:b",
+ "a:b:c",
+ "a:d"
+};
+
+int
+main(int argc, char **argv)
+{
+ int retval;
+ unsigned char *tresult;
+ char comstr[BUFSIZ];
+
+ init_dialog();
+ do {
+ use_helpline("Press OK for listing directory");
+ retval = dialog_tree(names,
+ sizeof(names)/sizeof(unsigned char *) - 1,
+ '/',
+ "tree dialog box example",
+ "Typical find -x / -type d output",
+ -1, -1, 15,
+ &tresult);
+
+ if (retval)
+ break;
+
+ use_helpline(NULL);
+ (void)snprintf(comstr, sizeof(comstr),
+ "ls -CF %s", tresult);
+
+ retval = dialog_prgbox(
+ comstr,
+ comstr, 20, 60, TRUE, TRUE);
+
+ dialog_clear();
+
+ retval = dialog_tree(names1,
+ sizeof(names1)/sizeof(unsigned char *),
+ ':',
+ "tree dialog box example",
+ "Other tree",
+ -1, -1, 5,
+ &tresult);
+ if (!retval)
+ {
+ dialog_clear();
+ }
+ } while (!retval);
+
+ dialog_update();
+
+ dialog_clear();
+
+ end_dialog();
+
+ exit(retval);
+}
diff --git a/gnu/lib/libodialog/TESTS/yesno.c b/gnu/lib/libodialog/TESTS/yesno.c
new file mode 100644
index 0000000..647b51c
--- /dev/null
+++ b/gnu/lib/libodialog/TESTS/yesno.c
@@ -0,0 +1,45 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, char **argv)
+{
+ int rval1, rval2;
+
+ init_dialog();
+
+ rval1 = dialog_yesno("This is dialog_yesno() in action",
+ "Have you stopped deliberately putting bugs into your code?", -1, -1);
+ dialog_clear();
+ rval2 = dialog_noyes("This is dialog_noyes() in action",
+ "Have you stopped beating your wife?", -1, -1);
+ dialog_clear();
+ end_dialog();
+ fprintf(stderr, "returned value for dialog_yesno was %d\n", rval1);
+ fprintf(stderr, "returned value for dialog_noyes was %d\n", rval2);
+ return 0;
+}
diff --git a/gnu/lib/libodialog/TODO b/gnu/lib/libodialog/TODO
new file mode 100644
index 0000000..132a4a4
--- /dev/null
+++ b/gnu/lib/libodialog/TODO
@@ -0,0 +1,36 @@
+- cut off names in the listbox that are to long
+done 27Jan95
+ The current behaviour may not be desirable. When browsing through
+ long names these, when highlighted, will be shown with the first
+ characters cut off, when not highlighted the last characters will
+ be cut off.
+
+- look at behaviour of TAB key when browsing through directories.
+done 28Jan95
+
+- make sure the full name of the directory is written to the
+ "Directory:"-box
+done 28Jan95
+
+- mark current selections in listbox when initializing the listobject
+Idontknow
+- test and use Notify() when checking for error conditions
+ok
+- test overall
+- adapt color of buttons when changing focus to the button.
+done 28Jan95
+- add shade to dialog_fselect()-window
+done 29Jan95
+- add (nn%) indication to lists.
+done 30Jan95
+- add use_helpfile()
+done 13Feb95
+- add use_helpline()
+
+NOTE: apparently there is a bug (or a strange interaction between pkg_manage
+and dialog_textbox) in dialog_textbox. When I use this routine to display
+the helpfile in display_helpfile() the program gets mysterious segmentation
+faults and bus errors.
+I now use dialog_mesgbox, after I have read the file into a buffer.
+
+
diff --git a/gnu/lib/libodialog/checklist.c b/gnu/lib/libodialog/checklist.c
new file mode 100644
index 0000000..e349ca6
--- /dev/null
+++ b/gnu/lib/libodialog/checklist.c
@@ -0,0 +1,661 @@
+/*
+ * checklist.c -- implements the checklist box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * Substantial rennovation: 12/18/95, Jordan K. Hubbard
+ *
+ * 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/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dialog.h>
+#include "dialog.priv.h"
+
+
+static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int status, int choice, int selected, dialogMenuItem *me, int list_width, int item_x, int check_x);
+
+#define DREF(di, item) ((di) ? &((di)[(item)]) : NULL)
+
+/*
+ * 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 cnt, void *it, unsigned char *result)
+{
+ int i, j, x, y, cur_x, cur_y, old_x, old_y, box_x, box_y, key = 0, button,
+ choice, l, k, scroll, max_choice, item_no = 0, *status;
+ int redraw_menu = FALSE, cursor_reset = FALSE;
+ int rval = 0, onlist = 1, ok_space, cancel_space;
+ char okButton, cancelButton;
+ WINDOW *dialog, *list;
+ unsigned char **items = NULL;
+ dialogMenuItem *ditems;
+ int list_width, check_x, item_x;
+
+ /* Allocate space for storing item on/off status */
+ if ((status = alloca(sizeof(int) * abs(cnt))) == NULL) {
+ endwin();
+ fprintf(stderr, "\nCan't allocate memory in dialog_checklist().\n");
+ exit(-1);
+ }
+
+draw:
+ choice = scroll = button = 0;
+ /* Previous calling syntax, e.g. just a list of strings? */
+ if (cnt >= 0) {
+ items = it;
+ ditems = NULL;
+ item_no = cnt;
+ /* Initializes status */
+ for (i = 0; i < item_no; i++)
+ status[i] = !strcasecmp(items[i*3 + 2], "on");
+ }
+ /* It's the new specification format - fake the rest of the code out */
+ else {
+ item_no = abs(cnt);
+ ditems = it;
+ if (!items)
+ items = (unsigned char **)alloca((item_no * 3) * sizeof(unsigned char *));
+
+ /* Initializes status */
+ for (i = 0; i < item_no; i++) {
+ status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
+ items[i*3] = ditems[i].prompt;
+ items[i*3 + 1] = ditems[i].title;
+ items[i*3 + 2] = status[i] ? "on" : "off";
+ }
+ }
+ max_choice = MIN(list_height, item_no);
+
+ check_x = 0;
+ item_x = 0;
+ /* Find length of longest item in order to center checklist */
+ for (i = 0; i < item_no; i++) {
+ l = strlen(items[i*3]);
+ for (j = 0; j < item_no; j++) {
+ k = strlen(items[j*3 + 1]);
+ check_x = MAX(check_x, l + k + 6);
+ }
+ item_x = MAX(item_x, l);
+ }
+ if (height < 0)
+ height = strheight(prompt)+list_height+4+2;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i,j);
+ width = MAX(width,check_x+4)+4;
+ }
+ width = MAX(width,24);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* 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);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width, y, x);
+ return -1;
+ }
+ 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);
+ wmove(dialog, 1, 2);
+ print_autowrap(dialog, prompt, height - 1, width - 2, width, 1, 2, TRUE, FALSE);
+
+ 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);
+ if (list == NULL) {
+ delwin(dialog);
+ endwin();
+ fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", list_height, list_width,
+ y + box_y + 1, x + box_x + 1);
+ return -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 = (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, DREF(ditems, i), list_width, item_x, check_x);
+ wnoutrefresh(list);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+
+ display_helpline(dialog, height - 1, width);
+
+ x = width / 2 - 11;
+ y = height - 2;
+ /* Is this a fancy new style argument string where we get to override
+ * the buttons, or an old style one where they're fixed?
+ */
+ if (ditems && result) {
+ cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]);
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : FALSE);
+ okButton = toupper(ditems[OK_BUTTON].prompt[0]);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : TRUE);
+ }
+ else {
+ cancelButton = 'C';
+ print_button(dialog, "Cancel", y, x + 14, FALSE);
+ okButton = 'O';
+ print_button(dialog, " OK ", y, x, TRUE);
+ }
+ wnoutrefresh(dialog);
+ wmove(list, choice, check_x+1);
+ wrefresh(list);
+
+ /*
+ * XXX Black magic voodoo that allows printing to the checklist
+ * window. For some reason, if this "refresh" code is not in
+ * place, printing to the window from the selected callback
+ * prints "behind" the checklist window. There is probably a
+ * better way to do this.
+ */
+ draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, menubox_border_attr, menubox_attr);
+
+ for (i = 0; i < max_choice; i++)
+ print_item(list, items[i * 3], items[i * 3 + 1], status[i], i, i == choice, DREF(ditems, i), list_width, item_x, check_x);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+
+ wmove(list, choice, check_x+1);
+ wnoutrefresh(dialog);
+ wrefresh(list);
+ /* XXX Black magic XXX */
+
+ while (key != ESC) {
+ key = wgetch(dialog);
+
+ /* Shortcut to OK? */
+ if (toupper(key) == okButton) {
+ if (ditems) {
+ if (result && ditems[OK_BUTTON].fire) {
+ int st;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ st = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ }
+ }
+ else if (result) {
+ *result = '\0';
+ for (i = 0; i < item_no; i++) {
+ if (status[i]) {
+ strcat(result, items[i*3]);
+ strcat(result, "\n");
+ }
+ }
+ }
+ rval = 0;
+ key = ESC; /* Lemme out! */
+ break;
+ }
+
+ /* Shortcut to cancel? */
+ if (toupper(key) == cancelButton) {
+ if (ditems && result && ditems[CANCEL_BUTTON].fire) {
+ int st;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ st = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ wmove(dialog, cur_y, cur_x);
+ }
+ delwin(save);
+ }
+ rval = 1;
+ key = ESC; /* I gotta go! */
+ break;
+ }
+
+ /* Check if key pressed matches first character of any item tag in list */
+ for (i = 0; i < max_choice; i++)
+ if (key != ' ' && key < 0x100 && toupper(key) == toupper(items[(scroll+i)*3][0]))
+ break;
+
+ if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) ||
+ KEY_IS_UP(key) || KEY_IS_DOWN(key) || ((key == ' ' || key == '\n' ||
+ key == '\r') && onlist)) {
+
+ /* if moving from buttons to the list, reset and redraw buttons */
+ if (!onlist) {
+ onlist = 1;
+ button = 0;
+
+ if (ditems && result) {
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
+ }
+ else {
+ print_button(dialog, "Cancel", y, x + 14, button);
+ print_button(dialog, " OK ", y, x, !button);
+ }
+ wmove(list, choice, check_x+1);
+ wnoutrefresh(dialog);
+ wrefresh(list);
+ }
+
+ if (key >= '1' && key <= MIN('9', '0'+max_choice))
+ i = key - '1';
+
+ else if (KEY_IS_UP(key)) {
+ if (!choice) {
+ if (scroll) {
+ /* 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, DREF(ditems, scroll), list_width, item_x, check_x);
+ scrollok(list, TRUE);
+ wscrl(list, -1);
+ scrollok(list, FALSE);
+ }
+ scroll--;
+ print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0,
+ TRUE, DREF(ditems, scroll), list_width, item_x, check_x);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+ wmove(list, choice, check_x+1);
+ wnoutrefresh(dialog);
+ wrefresh(list);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice - 1;
+ }
+ else if (KEY_IS_DOWN(key)) {
+ if (choice == max_choice - 1) {
+ if (scroll + choice < item_no - 1) {
+ /* 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, DREF(ditems, scroll + max_choice - 1), list_width, item_x, check_x);
+ 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,
+ DREF(ditems, scroll + max_choice - 1), list_width, item_x, check_x);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+ wmove(list, choice, check_x+1);
+ wnoutrefresh(dialog);
+ wrefresh(list);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice + 1;
+ }
+ else if ((key == ' ' || key == '\n' || key == '\r') && onlist) { /* Toggle item status */
+ char lbra = 0, rbra = 0, mark = 0;
+
+ getyx(list, old_y, old_x); /* Save cursor position */
+
+ if (ditems) {
+ if (ditems[scroll + choice].fire) {
+ int st;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ st = ditems[scroll + choice].fire(&ditems[scroll + choice]); /* Call "fire" action */
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ if (st & DITEM_REDRAW) {
+ wclear(list);
+ for (i = 0; i < item_no; i++)
+ status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
+ 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, DREF(ditems, scroll + i), list_width, item_x, check_x);
+ }
+ wnoutrefresh(list);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4,
+ cur_x, cur_y);
+ wrefresh(dialog);
+ }
+ if (st & DITEM_LEAVE_MENU) {
+ /* Allow a fire action to take us out of the menu */
+ key = ESC;
+ rval = 0;
+ break;
+ }
+ else if (st & DITEM_RECREATE) {
+ delwin(list);
+ delwin(dialog);
+ dialog_clear();
+ goto draw;
+ }
+ }
+ status[scroll + choice] = ditems[scroll + choice].checked ?
+ ditems[scroll + choice].checked(&ditems[scroll + choice]) : FALSE;
+ lbra = ditems[scroll + choice].lbra;
+ rbra = ditems[scroll + choice].rbra;
+ mark = ditems[scroll + choice].mark;
+ }
+ else
+ status[scroll + choice] = !status[scroll + choice];
+ wmove(list, choice, check_x);
+ wattrset(list, check_selected_attr);
+ if (!lbra)
+ lbra = '[';
+ if (!rbra)
+ rbra = ']';
+ if (!mark)
+ mark = 'X';
+ wprintw(list, "%c%c%c", lbra, status[scroll + choice] ? mark : ' ', rbra);
+ wmove(list, old_y, old_x); /* Restore cursor to previous position */
+ wrefresh(list);
+ 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, DREF(ditems, scroll + choice), list_width, item_x, check_x);
+
+ /* Highlight new item */
+ choice = i;
+ print_item(list, items[(scroll + choice) * 3], items[(scroll + choice) * 3 + 1], status[scroll + choice], choice, TRUE, DREF(ditems, scroll + choice), list_width, item_x, check_x);
+ wmove(list, choice, check_x+1); /* Restore cursor to previous position */
+ wrefresh(list);
+ }
+ continue; /* wait for another key press */
+ }
+
+ switch (key) {
+ case KEY_PPAGE: /* can we go up? */
+ if (scroll > height - 4)
+ scroll -= (height-4);
+ else
+ scroll = 0;
+ redraw_menu = TRUE;
+ if (!onlist) {
+ onlist = 1;
+ button = 0;
+ }
+ break;
+
+ case KEY_NPAGE: /* can we go down a full page? */
+ if (scroll + list_height >= item_no-1 - list_height) {
+ scroll = item_no - list_height;
+ if (scroll < 0)
+ scroll = 0;
+ }
+ else
+ scroll += list_height;
+ redraw_menu = TRUE;
+ if (!onlist) {
+ onlist = 1;
+ button = 0;
+ }
+ break;
+
+ case KEY_HOME: /* go to the top */
+ scroll = 0;
+ choice = 0;
+ redraw_menu = TRUE;
+ cursor_reset = TRUE;
+ onlist = 1;
+ break;
+
+ case KEY_END: /* Go to the bottom */
+ scroll = item_no - list_height;
+ if (scroll < 0)
+ scroll = 0;
+ choice = max_choice - 1;
+ redraw_menu = TRUE;
+ cursor_reset = TRUE;
+ onlist = 1;
+ break;
+
+ case TAB:
+ case KEY_BTAB:
+ /* move to next component */
+ if (onlist) { /* on list, next is ok button */
+ onlist = 0;
+ if (ditems && result) {
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
+ ok_space = 1;
+ cancel_space = strlen(ditems[OK_BUTTON].prompt) + 6;
+ }
+ else {
+ print_button(dialog, "Cancel", y, x + 14, button);
+ print_button(dialog, " OK ", y, x, !button);
+ ok_space = 3;
+ cancel_space = 15;
+ }
+ if (button)
+ wmove(dialog, y, x + cancel_space);
+ else
+ wmove(dialog, y, x + ok_space);
+ wrefresh(dialog);
+ break;
+ }
+ else if (button) { /* on cancel button, next is list */
+ button = 0;
+ onlist = 1;
+ redraw_menu = TRUE;
+ break;
+ }
+ /* on ok button, next is cancel button, same as left/right case */
+
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ onlist = 0;
+ button = !button;
+ if (ditems && result) {
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
+ ok_space = 1;
+ cancel_space = strlen(ditems[OK_BUTTON].prompt) + 6;
+ }
+ else {
+ print_button(dialog, "Cancel", y, x + 14, button);
+ print_button(dialog, " OK ", y, x, !button);
+ ok_space = 3;
+ cancel_space = 15;
+ }
+ if (button)
+ wmove(dialog, y, x + cancel_space);
+ else
+ wmove(dialog, y, x + ok_space);
+ wrefresh(dialog);
+ break;
+
+ case ' ':
+ case '\n':
+ case '\r':
+ if (!onlist) {
+ if (ditems) {
+ if (result && ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire) {
+ int st;
+ WINDOW *save = dupwin(newscr);
+
+ st = ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ if (st == DITEM_FAILURE)
+ continue;
+ }
+ }
+ else if (result) {
+ *result = '\0';
+ for (i = 0; i < item_no; i++) {
+ if (status[i]) {
+ strcat(result, items[i*3]);
+ strcat(result, "\n");
+ }
+ }
+ }
+ rval = button;
+ key = ESC; /* Bail out! */
+ break;
+ }
+
+ /* Let me outta here! */
+ case ESC:
+ rval = -1;
+ break;
+
+ /* Help! */
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+
+ if (redraw_menu) {
+ getyx(list, old_y, old_x);
+ wclear(list);
+
+ /*
+ * Re-draw a box around the list items. It is required
+ * if amount of list items is smaller than height of listbox.
+ * Otherwise un-redrawn field will be filled with default
+ * screen attributes instead of dialog attributes.
+ */
+ draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, menubox_border_attr, menubox_attr);
+
+ 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, DREF(ditems, scroll + i), list_width, item_x, check_x);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+
+ /* redraw buttons to fix highlighting */
+ if (ditems && result) {
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
+ }
+ else {
+ print_button(dialog, "Cancel", y, x + 14, button);
+ print_button(dialog, " OK ", y, x, !button);
+ }
+ wnoutrefresh(dialog);
+ if (cursor_reset) {
+ wmove(list, choice, check_x+1);
+ cursor_reset = FALSE;
+ }
+ else {
+ wmove(list, old_y, old_x);
+ }
+ wrefresh(list);
+ redraw_menu = FALSE;
+ }
+ }
+ delwin(list);
+ delwin(dialog);
+ return rval;
+}
+
+
+/*
+ * Print list item
+ */
+static void
+print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int status, int choice, int selected, dialogMenuItem *me, int list_width, int item_x, int check_x)
+{
+ 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%c%c", me && me->lbra ? me->lbra : '[',
+ status ? me && me->mark ? me->mark : 'X' : ' ',
+ me && me->rbra ? me->rbra : ']');
+ 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);
+ /* If have a selection handler for this, call it */
+ if (me && me->selected) {
+ wrefresh(win);
+ me->selected(me, selected);
+ }
+}
+/* End of print_item() */
diff --git a/gnu/lib/libodialog/colors.h b/gnu/lib/libodialog/colors.h
new file mode 100644
index 0000000..7cea0a0
--- /dev/null
+++ b/gnu/lib/libodialog/colors.h
@@ -0,0 +1,219 @@
+/*
+ * colors.h -- color attribute definitions
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * Default color definitions
+ *
+ * *_FG = foreground
+ * *_BG = background
+ * *_HL = highlight?
+ */
+#define SCREEN_FG COLOR_CYAN
+#define SCREEN_BG COLOR_BLUE
+#define SCREEN_HL TRUE
+
+#define SHADOW_FG COLOR_BLACK
+#define SHADOW_BG COLOR_BLACK
+#define SHADOW_HL TRUE
+
+#define DIALOG_FG COLOR_BLACK
+#define DIALOG_BG COLOR_WHITE
+#define DIALOG_HL FALSE
+
+#define TITLE_FG COLOR_YELLOW
+#define TITLE_BG COLOR_WHITE
+#define TITLE_HL TRUE
+
+#define BORDER_FG COLOR_WHITE
+#define BORDER_BG COLOR_WHITE
+#define BORDER_HL TRUE
+
+#define BUTTON_ACTIVE_FG COLOR_WHITE
+#define BUTTON_ACTIVE_BG COLOR_BLUE
+#define BUTTON_ACTIVE_HL TRUE
+
+#define BUTTON_INACTIVE_FG COLOR_BLACK
+#define BUTTON_INACTIVE_BG COLOR_WHITE
+#define BUTTON_INACTIVE_HL FALSE
+
+#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE
+#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE
+#define BUTTON_KEY_ACTIVE_HL TRUE
+
+#define BUTTON_KEY_INACTIVE_FG COLOR_RED
+#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE
+#define BUTTON_KEY_INACTIVE_HL FALSE
+
+#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW
+#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE
+#define BUTTON_LABEL_ACTIVE_HL TRUE
+
+#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK
+#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE
+#define BUTTON_LABEL_INACTIVE_HL TRUE
+
+#define INPUTBOX_FG COLOR_BLACK
+#define INPUTBOX_BG COLOR_WHITE
+#define INPUTBOX_HL FALSE
+
+#define INPUTBOX_BORDER_FG COLOR_BLACK
+#define INPUTBOX_BORDER_BG COLOR_WHITE
+#define INPUTBOX_BORDER_HL FALSE
+
+#define SEARCHBOX_FG COLOR_BLACK
+#define SEARCHBOX_BG COLOR_WHITE
+#define SEARCHBOX_HL FALSE
+
+#define SEARCHBOX_TITLE_FG COLOR_YELLOW
+#define SEARCHBOX_TITLE_BG COLOR_WHITE
+#define SEARCHBOX_TITLE_HL TRUE
+
+#define SEARCHBOX_BORDER_FG COLOR_WHITE
+#define SEARCHBOX_BORDER_BG COLOR_WHITE
+#define SEARCHBOX_BORDER_HL TRUE
+
+#define POSITION_INDICATOR_FG COLOR_YELLOW
+#define POSITION_INDICATOR_BG COLOR_WHITE
+#define POSITION_INDICATOR_HL TRUE
+
+#define MENUBOX_FG COLOR_BLACK
+#define MENUBOX_BG COLOR_WHITE
+#define MENUBOX_HL FALSE
+
+#define MENUBOX_BORDER_FG COLOR_WHITE
+#define MENUBOX_BORDER_BG COLOR_WHITE
+#define MENUBOX_BORDER_HL TRUE
+
+#define ITEM_FG COLOR_BLACK
+#define ITEM_BG COLOR_WHITE
+#define ITEM_HL FALSE
+
+#define ITEM_SELECTED_FG COLOR_WHITE
+#define ITEM_SELECTED_BG COLOR_BLUE
+#define ITEM_SELECTED_HL TRUE
+
+#define TAG_FG COLOR_YELLOW
+#define TAG_BG COLOR_WHITE
+#define TAG_HL TRUE
+
+#define TAG_SELECTED_FG COLOR_YELLOW
+#define TAG_SELECTED_BG COLOR_BLUE
+#define TAG_SELECTED_HL TRUE
+
+#define TAG_KEY_FG COLOR_RED
+#define TAG_KEY_BG COLOR_WHITE
+#define TAG_KEY_HL TRUE
+
+#define TAG_KEY_SELECTED_FG COLOR_RED
+#define TAG_KEY_SELECTED_BG COLOR_BLUE
+#define TAG_KEY_SELECTED_HL TRUE
+
+#define CHECK_FG COLOR_BLACK
+#define CHECK_BG COLOR_WHITE
+#define CHECK_HL FALSE
+
+#define CHECK_SELECTED_FG COLOR_WHITE
+#define CHECK_SELECTED_BG COLOR_BLUE
+#define CHECK_SELECTED_HL TRUE
+
+#define UARROW_FG COLOR_GREEN
+#define UARROW_BG COLOR_WHITE
+#define UARROW_HL TRUE
+
+#define DARROW_FG COLOR_GREEN
+#define DARROW_BG COLOR_WHITE
+#define DARROW_HL TRUE
+
+/* End of default color definitions */
+
+#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
+#define COLOR_NAME_LEN 10
+#define COLOR_COUNT 8
+
+
+/*
+ * Global variables
+ */
+
+typedef struct {
+ unsigned char name[COLOR_NAME_LEN];
+ int value;
+} color_names_st;
+
+
+#ifdef __DIALOG_MAIN__
+
+/*
+ * For matching color names with color values
+ */
+color_names_st color_names[] = {
+ {"BLACK", COLOR_BLACK},
+ {"RED", COLOR_RED},
+ {"GREEN", COLOR_GREEN},
+ {"YELLOW", COLOR_YELLOW},
+ {"BLUE", COLOR_BLUE},
+ {"MAGENTA", COLOR_MAGENTA},
+ {"CYAN", COLOR_CYAN},
+ {"WHITE", COLOR_WHITE},
+}; /* color names */
+
+
+/*
+ * Table of color values
+ */
+int color_table[][3] = {
+ {SCREEN_FG, SCREEN_BG, SCREEN_HL },
+ {SHADOW_FG, SHADOW_BG, SHADOW_HL },
+ {DIALOG_FG, DIALOG_BG, DIALOG_HL },
+ {TITLE_FG, TITLE_BG, TITLE_HL },
+ {BORDER_FG, BORDER_BG, BORDER_HL },
+ {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL },
+ {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL },
+ {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL },
+ {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL },
+ {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL },
+ {BUTTON_LABEL_INACTIVE_FG,BUTTON_LABEL_INACTIVE_BG,BUTTON_LABEL_INACTIVE_HL},
+ {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL },
+ {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL },
+ {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL },
+ {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL },
+ {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL },
+ {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL },
+ {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL },
+ {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL },
+ {ITEM_FG, ITEM_BG, ITEM_HL },
+ {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL },
+ {TAG_FG, TAG_BG, TAG_HL },
+ {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL },
+ {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL },
+ {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL },
+ {CHECK_FG, CHECK_BG, CHECK_HL },
+ {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL },
+ {UARROW_FG, UARROW_BG, UARROW_HL },
+ {DARROW_FG, DARROW_BG, DARROW_HL },
+}; /* color_table */
+
+#else
+
+extern color_names_st color_names[];
+extern int color_table[][3];
+
+#endif /* __DIALOG_MAIN__ */
diff --git a/gnu/lib/libodialog/dialog.3 b/gnu/lib/libodialog/dialog.3
new file mode 100644
index 0000000..2e4b8fb
--- /dev/null
+++ b/gnu/lib/libodialog/dialog.3
@@ -0,0 +1,842 @@
+.\"
+.\" Copyright (c) 1995, Jordan Hubbard
+.\"
+.\" All rights reserved.
+.\"
+.\" This manual page may be used, modified, copied, distributed, and
+.\" sold, in both source and binary form provided that the above
+.\" copyright and these terms are retained, verbatim, as the first
+.\" lines of this file. Under no circumstances is the author
+.\" responsible for the proper functioning of the software described herein
+.\" nor does the author assume any responsibility for damages incurred with
+.\" its use.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd January 1, 2000
+.Dt DIALOG 3
+.Os
+.Sh NAME
+.Nm draw_shadow ,
+.Nm draw_box ,
+.Nm line_edit ,
+.Nm strheight ,
+.Nm strwidth ,
+.Nm dialog_create_rc ,
+.Nm dialog_yesno ,
+.Nm dialog_noyes ,
+.Nm dialog_prgbox ,
+.Nm dialog_msgbox ,
+.Nm dialog_textbox ,
+.Nm dialog_menu ,
+.Nm dialog_checklist ,
+.Nm dialog_radiolist ,
+.Nm dialog_inputbox ,
+.Nm dialog_clear_norefresh ,
+.Nm dialog_clear ,
+.Nm dialog_update ,
+.Nm dialog_fselect ,
+.Nm dialog_notify ,
+.Nm dialog_mesgbox ,
+.Nm dialog_gauge ,
+.Nm init_dialog ,
+.Nm end_dialog ,
+.Nm use_helpfile ,
+.Nm use_helpline ,
+.Nm get_helpline ,
+.Nm restore_helpline ,
+.Nm dialog_ftree ,
+.Nm dialog_tree
+.Nd provide a simple ncurses-based GUI interface
+.Sh SYNOPSIS
+.In dialog.h
+.Ft "void"
+.Fn draw_shadow "WINDOW *win" "int y" "int x" "int height" "int width"
+.Ft "void"
+.Fn draw_box "WINDOW *win" "int y" "int x" "int height" "int width" "chtype box" "chtype border"
+.Ft "int"
+.Fo line_edit
+.Fa "WINDOW *dialog"
+.Fa "int box_y"
+.Fa "int box_x"
+.Fa "int flen"
+.Fa "int box_width"
+.Fa "chtype attr"
+.Fa "int first"
+.Fa "unsigned char *result"
+.Fa "int attr_mask"
+.Fc
+.Ft "int"
+.Fn strheight "const char *p"
+.Ft "int"
+.Fn strwidth "const char *p"
+.Ft "void"
+.Fn dialog_create_rc "unsigned char *filename"
+.Ft "int"
+.Fn dialog_yesno "unsigned char *title" "unsigned char *prompt" "int height" "int width"
+.Ft "int"
+.Fn dialog_noyes "unsigned char *title" "unsigned char *prompt" "int height" "int width"
+.Ft "int"
+.Fn dialog_prgbox "unsigned char *title" "const unsigned char *line" "int height" "int width" "int pause" "int use_shell"
+.Ft "int"
+.Fn dialog_textbox "unsigned char *title" "unsigned char *file" "int height" "int width"
+.Ft "int"
+.Fo dialog_menu
+.Fa "unsigned char *title"
+.Fa "unsigned char *prompt"
+.Fa "int height"
+.Fa "int width"
+.Fa "int menu_height"
+.Fa "int cnt"
+.Fa "void *it"
+.Fa "unsigned char *result"
+.Fa "int *ch"
+.Fa "int *sc"
+.Fc
+.Ft "int"
+.Fn dialog_checklist "unsigned char *title" "unsigned char *prompt" "int height" "int width" "int list_height" "int cnt" "void *it" "unsigned char *result"
+.Ft "int"
+.Fn dialog_radiolist "unsigned char *title" "unsigned char *prompt" "int height" "int width" "int list_height" "int cnt" "void *it" "unsigned char *result"
+.Ft "int"
+.Fn dialog_inputbox "unsigned char *title" "unsigned char *prompt" "int height" "int width" "unsigned char *result"
+.Ft "char *"
+.Fn dialog_fselect "char *dir" "char *fmask"
+.Ft "int"
+.Fn dialog_dselect "char *dir" "char *fmask"
+.Ft "void"
+.Fn dialog_notify "char *msg"
+.Ft "int"
+.Fn dialog_mesgbox "unsigned char *title" "unsigned char *prompt" "int height" "int width"
+.Ft "void"
+.Fn dialog_gauge "char *title" "char *prompt" "int y" "int x" "int height" "int width" "int perc"
+.Ft "void"
+.Fn use_helpfile "char *hfile"
+.Ft "void"
+.Fn use_helpline "char *hline"
+.Ft "char *"
+.Fn get_helpline "void"
+.Ft "void"
+.Fn dialog_clear_norefresh "void"
+.Ft "void"
+.Fn dialog_clear "void"
+.Ft "void"
+.Fn dialog_update "void"
+.Ft "void"
+.Fn init_dialog "void"
+.Ft "void"
+.Fn end_dialog "void"
+.Ft "int"
+.Fn dialog_ftree "unsigned char *filename" "unsigned char FS" "unsigned char *title" "unsigned char *prompt" "int height" "int width" "int menu_height" "unsigned char **result"
+.Ft "int"
+.Fo dialog_tree
+.Fa "unsigned char **names"
+.Fa "int size"
+.Fa "unsigned char FS"
+.Fa "unsigned char *title"
+.Fa "unsigned char *prompt"
+.Fa "int height"
+.Fa "int width"
+.Fa "int menu_height"
+.Fa "unsigned char **result"
+.Fc
+.Sh DESCRIPTION
+The dialog library attempts to provide a fairly simplistic set of
+fixed-presentation menus, input boxes, gauges, file requestors and
+other general purpose GUI (a bit of a stretch, since it uses
+ncurses) objects.
+Since the library also had its roots in a
+shell-script writer's utility (see the
+.Xr dialog 1
+command), the
+early API was somewhat primitively based on strings being passed in or
+out and parsed.
+This API was later extended to take either the
+original arguments or arrays of
+.Va dialogMenuItem
+structures,
+giving the user much more control over the internal behavior of each
+control.
+The
+.Va dialogMenuItem
+structure internals are public:
+.Bd -literal -offset indent
+typedef struct _dmenu_item {
+ char *prompt;
+ char *title;
+ int (*checked)(struct _dmenu_item *self);
+ int (*fire)(struct _dmenu_item *self);
+ int (*selected)(struct _dmenu_item *self, int is_selected);
+ void *data;
+ char lbra, mark, rbra;
+ long aux;
+} dialogMenuItem;
+.Ed
+.Pp
+The
+.Dv prompt
+and
+.Dv title
+strings are pretty much self-explanatory,
+and the
+.Va checked
+and
+.Va fire
+function pointers provide optional
+display and action hooks (the
+.Dv data
+variable being available for
+the convenience of those hooks) when more tightly coupled feedback between
+a menu object and user code is required.
+The
+.Va selected
+hook also
+allows you to verify whether or not a given item is selected (the cursor is
+over it) for implementing pretty much any possible context-sensitive
+behavior.
+A number of clever tricks for simulating various kinds of item
+types can also be done by adjusting the values of
+.Va lbra
+(default: '['),
+.Va mark
+(default: '*' for radio menus, 'X' for check menus)
+and
+.Va rbra
+(default: ']') and declaring a reasonable
+.Va checked
+hook,
+which should return TRUE for the
+.Dq marked
+state and FALSE for
+.Dq unmarked .
+The
+.Va aux
+field is not used internally, and is available for miscellaneous usage.
+If an item has a
+.Va fire
+hook associated with it, it will also be called
+whenever the item is "toggled" in some way and should return one of the
+following codes:
+.Bd -literal -offset 4n
+#define DITEM_SUCCESS 0 /* Successful completion */
+#define DITEM_FAILURE 1 /* Failed to "fire" */
+.Ed
+.Pp
+The following flags are in the upper 16 bits of return status:
+.Bd -literal -offset 4n
+#define DITEM_LEAVE_MENU (1 << 16)
+#define DITEM_REDRAW (1 << 17)
+#define DITEM_RECREATE (1 << 18)
+#define DITEM_RESTORE (1 << 19)
+#define DITEM_CONTINUE (1 << 20)
+.Ed
+.Pp
+Two special globals also exist for putting a dialog at any arbitrary
+X,Y location (the early designers rather short-sightedly made no provisions
+for this).
+If set to zero, the default centering behavior will be in
+effect.
+.Pp
+Below is a short description of the various functions:
+.Pp
+The
+.Fn draw_shadow
+function draws a shadow in curses window
+.Va win
+using the dimensions of
+.Va x , y , width
+and
+.Va height .
+.Pp
+The
+.Fn draw_box
+function draws a bordered box using the dimensions of
+.Va x , y , width
+and
+.Va height .
+The attributes from
+.Va box
+and
+.Va border
+are used, if specified, while painting the box and border regions of the
+object.
+.Pp
+The
+.Fn line_edit
+function invokes a simple line editor with an edit box of dimensions
+.Va box_x , box_y
+and
+.Va box_width .
+The field length is constrained by
+.Va flen ,
+starting at the
+.Va first
+character specified and
+optionally displayed with character attributes
+.Va attr .
+The string being edited is stored in
+.Va result .
+Returns 0 on success, 1 on Cancel, and -1 on failure or ESC.
+.Pp
+The
+.Fn strheight
+function returns the height of string in
+.Va p ,
+counting newlines.
+.Pp
+The
+.Fn strwidth
+function returns the width of string in
+.Va p ,
+counting newlines.
+.Pp
+The
+.Fn dialog_create_rc
+function dumps dialog library settings into
+.Pa filename
+for later retrieval as defaults.
+Returns 0 on success, -1 on failure.
+.Pp
+The
+.Fn dialog_yesno
+function displays a text box using
+.Va title
+and
+.Va prompt
+strings of dimensions
+.Va height
+and
+.Va width .
+Also paint a pair of
+.Em Yes
+and
+.Em \&No
+buttons at the bottom.
+The default selection is
+.Em Yes .
+If the
+.Em Yes
+button is chosen, return FALSE.
+If
+.Em \&No ,
+return TRUE.
+.Pp
+The
+.Fn dialog_noyes
+function is the same as
+.Fn dialog_yesno ,
+except the default selection is
+.Em \&No .
+.Pp
+The
+.Fn dialog_prgbox
+function displays a text box of dimensions
+.Va height
+and
+.Va width
+containing the output of command
+.Va line .
+If
+.Va use_shell
+is TRUE,
+.Va line
+is passed as an argument to
+.Xr sh 1 ,
+otherwise it is simply passed to
+.Xr exec 3 .
+If
+.Va pause
+is TRUE, a final confirmation requestor will be put up when execution
+terminates.
+Returns 0 on success, -1 on failure.
+.Pp
+The
+.Fn dialog_textbox
+function displays a text box containing the contents of
+.Va file
+with dimensions of
+.Va height
+and
+.Va width .
+.Pp
+The
+.Fn dialog_menu
+function displays a menu of dimensions
+.Va height
+and
+.Va width
+with an optional internal menu height of
+.Va menu_height .
+The
+.Va cnt
+and
+.Va it
+arguments are of particular importance since they,
+together, determine which of the 2 available APIs to use.
+To use the
+older and traditional interface,
+.Va cnt
+should be a positive
+integer representing the number of string pointer pairs to find in
+.Va it
+(which should be of type
+.Ft char "**" ) ,
+the strings are
+expected to be in prompt and title order for each item and the
+.Va result
+parameter is expected to point to an array where the
+prompt string of the item selected will be copied.
+To use the newer
+interface,
+.Va cnt
+should be a
+.Va negative
+integer representing the number of
+.Va dialogMenuItem
+structures pointed to by
+.Va it
+(which should be of type
+.Vt dialogMenuItem "*" ) ,
+one structure per item.
+In the new interface, the
+.Va result
+variable is used as a simple boolean (not a pointer) and should be NULL if
+.Va it
+only points to menu items and the default OK and Cancel buttons are desired.
+If
+.Va result
+is non-NULL, then
+.Va it
+is actually expected to point 2 locations
+.Va past
+the start of the menu item list.
+.Va it
+is then expected to
+point to an item representing the Cancel button, from which the
+.Va prompt
+and
+.Va fire
+actions are used to override the default behavior, and
+.Va it
+to the same for the OK button.
+.Pp
+Using either API behavior, the
+.Va ch
+and
+.Va sc
+values may be passed in to preserve current
+item selection and scroll position values across calls.
+.Pp
+The
+.Fn dialog_checklist
+function displays a menu of dimensions
+.Va height
+and
+.Va width
+with an
+optional internal menu height of
+.Va list_height .
+The
+.Va cnt
+and
+.Va it
+arguments are of particular importance since they,
+together, determine which of the 2 available APIs to use.
+To use the
+older and traditional interface,
+.Va cnt
+should be a positive
+integer representing the number of string pointer tuples to find in
+.Va it
+(which should be of type
+.Ft "char **" ) ,
+the strings are
+expected to be in prompt, title and state ("on" or "off") order for
+each item and the
+.Va result
+parameter is expected to point to an
+array where the prompt string of the item(s) selected will be
+copied.
+To use the newer interface,
+.Va cnt
+should be a
+.Em negative
+integer representing the number of
+.Ft dialogMenuItem
+structures pointed to by
+.Va it
+(which should be of type
+.Ft "dialogMenuItem *" ) ,
+one structure per item.
+In the new interface,
+the
+.Va result
+variable is used as a simple boolean (not a pointer)
+and should be NULL if
+.Va it
+only points to menu items and the default OK and Cancel
+buttons are desired.
+If
+.Va result
+is non-NULL, then
+.Va it
+is actually expected to
+point 2 locations
+.Va past
+the start of the menu item list.
+.Va it
+is then expected to point to an item representing the Cancel
+button, from which the
+.Va prompt
+and
+.Va fire
+actions are used to override the default behavior, and
+.Va it
+to the same for the OK button.
+.Pp
+In the standard API model, the menu supports the selection of multiple items,
+each of which is marked with an `X' character to denote selection.
+When
+the OK button is selected, the prompt values for all items selected are
+concatenated into the
+.Va result
+string.
+.Pp
+In the new API model, it is not actually necessary to preserve
+"checklist" semantics at all since practically everything about how
+each item is displayed or marked as "selected" is fully configurable.
+You could have a single checklist menu that actually contained a group
+of items with "radio" behavior, "checklist" behavior and standard menu
+item behavior.
+The only reason to call
+.Fn dialog_checklist
+over
+.Fn dialog_radiolist
+in the new API model is to inherit the base
+behavior, you are no longer constrained by it.
+.Pp
+Returns 0 on success, 1 on Cancel, and -1 on failure or ESC.
+.Pp
+The
+.Fn dialog_radiolist
+function displays a menu of dimensions
+.Va height
+and
+.Va width
+with an
+optional internal menu height of
+.Va list_height .
+The
+.Va cnt
+and
+.Va it
+arguments are of particular importance since they,
+together, determine which of the 2 available APIs to use.
+To use the
+older and traditional interface,
+.Va cnt
+should be a positive
+integer representing the number of string pointer tuples to find in
+.Va it
+(which should be of type
+.Ft "char **" ) ,
+the strings are
+expected to be in prompt, title and state ("on" or "off") order for
+each item and the
+.Va result
+parameter is expected to point to an
+array where the prompt string of the item(s) selected will be
+copied.
+To use the newer interface,
+.Va cnt
+should be a
+.Dv negative
+integer representing the number of
+.Ft dialogMenuItem
+structures pointed to by
+.Va it
+(which should be of type
+.Ft "dialogMenuItem *" ,
+one structure per item.
+In the new interface,
+the
+.Va result
+variable is used as a simple boolean (not a pointer)
+and should be NULL if
+.Va it
+only points to menu items and the default OK and Cancel
+buttons are desired.
+If
+.Va result
+is non-NULL, then
+.Va it
+is actually expected to point 2 locations
+.Va past
+the start of the menu item list.
+.Va it
+is then expected to point to an item representing the Cancel
+button, from which the
+.Va prompt
+and
+.Va fire
+actions are used to override the default behavior, and
+.Va it
+does the same for the traditional OK button.
+.Pp
+In the standard API model, the menu supports the selection of only one
+of multiple items, the currently active item marked with an `*'
+character to denote selection.
+When the OK button is selected, the
+prompt value for this item is copied into the
+.Va result
+string.
+.Pp
+In the new API model, it is not actually necessary to preserve
+"radio button" semantics at all since practically everything about how
+each item is displayed or marked as "selected" is fully configurable.
+You could have a single radio menu that actually contained a group
+of items with "checklist" behavior, "radio" behavior and standard menu
+item behavior.
+The only reason to call
+.Fn dialog_radiolist
+over
+.Fn dialog_checklistlist
+in the new API model is to inherit the base
+behavior.
+.Pp
+Returns 0 on success, 1 on Cancel and -1 on failure or ESC.
+.Pp
+The
+.Fn dialog_inputbox
+function displays a single-line text input field in a box displaying
+.Va title
+and
+.Va prompt
+of dimensions
+.Va height
+and
+.Va width .
+The field entered is stored in
+.Va result .
+.Pp
+Returns 0 on success, -1 on failure or ESC.
+.Pp
+The
+.Fn dialog_fselect
+function brings up a file selector dialog starting at
+.Va dir
+and showing only those file names
+matching
+.Va fmask .
+.Pp
+Returns filename selected or NULL.
+.Pp
+The
+.Fn dialog_dselect
+function brings up a directory selector dialog starting at
+.Va dir
+and showing only those directory names
+matching
+.Va fmask .
+.Pp
+Returns directory name selected or NULL.
+.Pp
+The
+.Fn dialog_notify
+function brings up a generic "hey, you!" notifier dialog containing
+.Va msg .
+.Pp
+The
+.Fn dialog_mesgbox
+function displays a notifier dialog, but with more control over
+.Va title ,
+.Va prompt ,
+.Va width
+and
+.Va height .
+This object will also wait for user confirmation, unlike
+.Fn dialog_notify .
+.Pp
+Returns 0 on success, -1 on failure.
+.Pp
+The
+.Fn dialog_gauge
+function displays a horizontal bar-graph style gauge.
+A value of
+.Em 100
+for
+.Em perc
+constitutes a full gauge, a value of
+.Em 0
+an empty one.
+.Pp
+The
+.Fn use_helpfile
+function for any menu supporting context sensitive help, invokes the text box
+object on this file whenever the
+.Em F1
+key is pressed.
+.Pp
+The
+.Fn use_helpline
+function displays this line of helpful text below any menu being displayed.
+.Pp
+The
+.Fn get_helpline
+function gets the current value of the helpful text line.
+.Pp
+The
+.Fn dialog_clear_norefresh
+function clears the screen back to the dialog background color, but do not
+refresh the contents just yet.
+.Pp
+The
+.Fn dialog_clear
+function clears the screen back to the dialog background color immediately.
+.Pp
+The
+.Fn dialog_update
+function does any pending screen refreshes now.
+.Pp
+The
+.Fn init_dialog
+function initializes the dialog library (call this routine before any other
+dialog API calls).
+.Pp
+The
+.Fn end_dialog
+function shuts down the dialog library (call this if you need to get back to
+sanity).
+.Pp
+The
+.Fn dialog_ftree
+function shows a tree described by the data from the file
+.Pa filename .
+The data in the file should look like
+.Xr find 1
+output.
+For the
+.Xr find 1
+output, the field separator
+.Va FS
+will be
+.Dq \&/ .
+If
+.Va height
+and
+.Va width
+are positive numbers, they set the absolute
+size of the whole
+.Fn dialog_ftree
+box.
+If
+.Va height
+and
+.Va width
+are negative numbers, the size of the
+.Fn dialog_ftree
+box will be calculated automatically.
+.Va menu_height
+sets the height of the tree subwindow inside the
+.Fn dialog_ftree
+box and must be set.
+.Va title
+is shown centered on the upper border of the
+.Fn dialog_ftree
+box.
+.Va prompt
+is shown inside the
+.Fn dialog_ftree
+box above the tree subwindow and can contain
+.Ql \e\&n
+to split lines.
+One can navigate in
+the tree by pressing UP/DOWN or
+.Sm off
+.So \&+ Sc \&/ So \&- Sc ,
+.Sm on
+PG_UP/PG_DOWN or
+.Sm off
+.So b Sc \&/SPACE
+.Sm on
+and
+HOME/END or
+.Sm off
+.So g Sc \&/ So G Sc .
+.Sm on
+A leaf of the
+tree is selected by pressing TAB or LEFT/RIGHT the OK
+button and pressing ENTER.
+filename may contain data like
+.Xr find 1
+output, as well as like the output of
+.Xr find 1
+with
+.Fl d
+option.
+Some of the transient paths to the leaves of the tree may
+be absent.
+Such data is corrected when fed from filename.
+.Pp
+The function returns 0 and a pointer to the selected leaf (to the path to
+the leaf from the root of the tree) into result, if the OK button was
+selected.
+The memory allocated for the building of the tree is freed on
+exiting
+.Fn dialog_ftree .
+The memory for the result line should be freed
+later manually, if necessary.
+If the Cancel button was selected, the
+function returns 1.
+In case of exiting
+.Fn dialog_ftree
+on ESC, the function returns -1.
+.Pp
+The
+.Fn dialog_tree
+function returns the same results as
+.Fn dialog_ftree .
+If 0 is returned, result will contain a pointer from the array
+.Va names .
+.\" \fBdialog_tree\fR displays the tree very much like \fBdialog_ftree\fR does,
+.\" with some exceptions. The source data for the building of the tree is an
+.\" array \fBnames\fR of paths to the leaves (should be similar to \fBfind(1)\fR
+.\" output) of the size \fBsize\fR. However, there is no correction of data like
+.\" in \fBdialog_ftree\fR. Thus, to display a correct tree, the array must
+.\" already contain correct data. Besides, in each session every unique use of
+.\" \fBdialog_tree\fR is kept in memory, and later, when calling
+.\" \fBdialog_tree\fR with the same \fBnames\fR, \fBsize\fR, \fBFS\fR,
+.\" \fBheight\fR, \fBwidth\fR and \fBmenu_height\fR the position of the cursor
+.\" in the tree subwindow is restored.
+.Sh SEE ALSO
+.Xr dialog 1 ,
+.Xr ncurses 3
+.Sh HISTORY
+These functions appeared in
+.Fx 2.0
+as the
+.Xr dialog 1
+command and were soon split into a separate library
+and command by
+.An Andrey Chernov .
+.An Marc van Kempen
+implemented most of the extra controls and objects,
+.An Jordan Hubbard
+added the dialogMenuItem renovations and this man page and
+.An Anatoly A. Orehovsky
+implemented
+.Fn dialog_ftree
+and
+.Fn dialog_tree .
+.Sh AUTHORS
+.An -nosplit
+The primary author would appear to be
+.An Savio Lam Aq lam836@cs.cuhk.hk
+with contributions over the years by
+.An Stuart Herbert Aq S.Herbert@sheffield.ac.uk ,
+.An Marc van Kempen Aq wmbfmk@urc.tue.nl ,
+.An Andrey Chernov Aq ache@FreeBSD.org ,
+.An Jordan Hubbard Aq jkh@FreeBSD.org
+and
+.An Anatoly A. Orehovsky Aq tolik@mpeks.tomsk.su .
+.Sh BUGS
+Sure!
diff --git a/gnu/lib/libodialog/dialog.h b/gnu/lib/libodialog/dialog.h
new file mode 100644
index 0000000..369b139
--- /dev/null
+++ b/gnu/lib/libodialog/dialog.h
@@ -0,0 +1,211 @@
+#ifndef _DIALOG_H_INCLUDE
+#define _DIALOG_H_INCLUDE
+
+/*
+ * dialog.h -- common declarations for all dialog modules
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * Substantial rennovation: 12/18/95, Jordan K. Hubbard
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#define HAVE_NCURSES
+
+#ifdef HAVE_NCURSES
+#include <ncurses.h>
+
+#else
+
+#ifdef ultrix
+#include <cursesX.h>
+#else
+#include <curses.h>
+#endif
+
+#endif
+
+/* special return codes for `fire' actions */
+#define DITEM_STATUS(flag) ((flag) & 0x0000FFFF)
+#define DITEM_SUCCESS 0
+#define DITEM_FAILURE 1
+
+/* Flags - returned in upper 16 bits of return status */
+#define DITEM_LEAVE_MENU (1 << 16)
+#define DITEM_REDRAW (1 << 17)
+#define DITEM_RECREATE (1 << 18)
+#define DITEM_RESTORE (1 << 19)
+#define DITEM_CONTINUE (1 << 20)
+
+/* Attributes as used by entry fields right now */
+#define DITEM_NO_ECHO 0x0001
+
+
+/* negative offsets for buttons in item lists, if specified */
+#define OK_BUTTON -2
+#define CANCEL_BUTTON -1
+
+/* for use in describing more exotic behaviors */
+typedef struct _dmenu_item {
+ char *prompt;
+ char *title;
+ int (*checked)(struct _dmenu_item *self);
+ int (*fire)(struct _dmenu_item *self);
+ void (*selected)(struct _dmenu_item *self, int is_selected);
+ void *data;
+ char lbra, mark, rbra;
+ long aux;
+} dialogMenuItem;
+
+#define VERSION "0.4"
+#define MAX_LEN 4096
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+extern int DialogX, DialogY, DialogInputAttrs;
+
+/*
+ * 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
+
+extern chtype attributes[];
+
+#ifdef HAVE_NCURSES
+extern bool use_shadow;
+void draw_shadow(WINDOW *win, int y, int x, int height, int width);
+#endif
+void draw_box(WINDOW *win, int y, int x, int height, int width, chtype box, chtype border);
+int line_edit(WINDOW *dialog, int box_y, int box_x, int flen, int box_width, chtype attrs, int first, unsigned char *result, int attr_mask);
+int strheight(const char *p);
+int strwidth(const char *p);
+
+void dialog_create_rc(unsigned char *filename);
+int dialog_yesno(unsigned char *title, unsigned char *prompt, int height, int width);
+int dialog_noyes(unsigned char *title, unsigned char *prompt, int height, int width);
+int dialog_prgbox(unsigned char *title, const unsigned char *line, int height, int width, int pause, int use_shell);
+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, void *itptr, unsigned char *result, int *ch, int *sc);
+int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height,
+ int item_no, void *itptr, unsigned char *result);
+int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height,
+ int item_no, void *itptr, unsigned char *result);
+int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int width, unsigned char *result);
+void dialog_clear_norefresh(void);
+void dialog_clear(void);
+void dialog_update(void);
+void init_dialog(void);
+void end_dialog(void);
+
+/* Additions to libdialog */
+char *dialog_fselect(char *dir, char *fmask);
+int dialog_dselect(char *dir, char *fmask);
+void dialog_notify(char *msg);
+int dialog_mesgbox(unsigned char *title, unsigned char *prompt, int height, int width);
+void use_helpfile(char *helpfile);
+void use_helpline(char *helpline);
+char *get_helpline(void);
+void restore_helpline(char *helpline);
+void dialog_gauge(char *title, char *prompt, int y, int x, int height, int width, int perc);
+
+/*
+ * Display a tree menu from file
+ *
+ * filename - file with like find(1) output
+ * FS - fields separator
+ * title - title of dialog box
+ * prompt - prompt text into dialog box
+ * height - height of dialog box
+ * width - width of dialog box
+ * menu_height - height of menu box
+ * result - pointer to char array
+ *
+ * return values:
+ * -1 - ESC pressed
+ * 0 - Ok, result set (must be freed later)
+ * 1 - Cancel
+ */
+int dialog_ftree(unsigned char *filename, unsigned char FS,
+ unsigned char *title, unsigned char *prompt,
+ int height, int width, int menu_height,
+ unsigned char **result);
+
+/*
+ * Display a tree menu from array
+ *
+ * names - array with like find(1) output
+ * size - size of array
+ * FS - fields separator
+ * title - title of dialog box
+ * prompt - prompt text into dialog box
+ * height - height of dialog box
+ * width - width of dialog box
+ * menu_height - height of menu box
+ * result - pointer to char array
+ *
+ * return values:
+ * -1 - ESC pressed
+ * 0 - Ok, result set
+ * 1 - Cancel
+ */
+
+int dialog_tree(unsigned char **names, int size, unsigned char FS,
+ unsigned char *title, unsigned char *prompt,
+ int height, int width, int menu_height,
+ unsigned char **result);
+
+#endif /* _DIALOG_H_INCLUDE */
diff --git a/gnu/lib/libodialog/dialog.priv.h b/gnu/lib/libodialog/dialog.priv.h
new file mode 100644
index 0000000..06c01a5
--- /dev/null
+++ b/gnu/lib/libodialog/dialog.priv.h
@@ -0,0 +1,183 @@
+/*
+ * 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>
+#include <termios.h>
+
+#if defined(LOCALE)
+#include <locale.h>
+#endif
+
+
+/*
+ * Change these if you want
+ */
+#define USE_SHADOW TRUE
+#define USE_COLORS TRUE
+
+#define ESC 27
+#define TAB 9
+#define BUF_SIZE (10*1024)
+
+#ifndef MIN
+#define MIN(x,y) (x < y ? x : y)
+#endif
+#ifndef MAX
+#define MAX(x,y) (x > y ? x : y)
+#endif
+
+#ifndef ctrl
+#define ctrl(a) ((a) - 'a' + 1)
+#endif
+
+#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 */
+
+/* Travel key conventions */
+#define KEY_IS_UP(key) ((key) == KEY_UP || (key) == '-' || key == '\020' /* ^P */)
+#define KEY_IS_DOWN(key) ((key) == KEY_DOWN || (key) == '+' || key == '\016' /* ^N */)
+
+/*
+ * 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;
+#endif
+
+#endif /* __DIALOG_MAIN__ */
+
+
+
+#ifdef HAVE_NCURSES
+
+/*
+ * Function prototypes
+ */
+#ifdef __DIALOG_MAIN__
+
+extern int parse_rc(void);
+
+#endif /* __DIALOG_MAIN__ */
+
+#endif
+
+
+#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 height, int width, int maxwidth,
+ int y, int x, int center, int rawmode);
+void print_button(WINDOW *win, unsigned char *label, int y, int x, int selected);
+FILE *raw_popen(const char *program, char * const *argv, const char *type);
+int raw_pclose(FILE *iop);
+void display_helpfile(void);
+void display_helpline(WINDOW *w, int y, int width);
+void print_arrows(WINDOW *dialog, int scroll, int menu_height, int item_no, int box_x,
+ int box_y, int tag_x, int cur_x, int cur_y);
+
diff --git a/gnu/lib/libodialog/dir.c b/gnu/lib/libodialog/dir.c
new file mode 100644
index 0000000..5348c2f
--- /dev/null
+++ b/gnu/lib/libodialog/dir.c
@@ -0,0 +1,549 @@
+/****************************************************************************
+ *
+ * Program: dir.c
+ * Author: Marc van Kempen
+ * desc: Directory routines, sorting and reading
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ ****************************************************************************/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <unistd.h> /* XXX for _POSIX_VERSION ifdefs */
+
+#if !defined sgi && !defined _POSIX_VERSION
+#include <sys/dir.h>
+#endif
+#if defined __sun__
+#include <sys/dirent.h>
+#endif
+#if defined sgi || defined _POSIX_VERSION
+#include <dirent.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fnmatch.h>
+#include <sys/param.h>
+#include "dir.h"
+
+/****************************************************************************
+ *
+ * local prototypes
+ *
+ ****************************************************************************/
+
+void toggle_dotfiles(void);
+int show_dotfiles(void);
+int dir_alphasort(const void *d1, const void *d2);
+int dir_sizesort(const void *d1, const void *d2);
+int dir_datesort(const void *d1, const void *d2);
+int dir_extsort(const void *d1, const void *d2);
+
+/****************************************************************************
+ *
+ * global variables
+ *
+ ****************************************************************************/
+
+
+/* This is user-selectable, I've set them fixed for now however */
+
+void *_sort_func = dir_alphasort;
+static int _showdotfiles = TRUE;
+
+/****************************************************************************
+ *
+ * Functions
+ *
+ ****************************************************************************/
+
+int
+dir_select_nd(
+#if defined __linux__
+ const struct dirent *d
+#else
+ struct dirent *d
+#endif
+)
+/*
+ * desc: allways include a directory entry <d>, except
+ * for the current directory and other dot-files
+ * keep '..' however.
+ * pre: <d> points to a dirent
+ * post: returns TRUE if d->d_name != "." else FALSE
+ */
+{
+ if (strcmp(d->d_name, ".")==0 ||
+ (d->d_name[0] == '.' && strlen(d->d_name) > 1 && d->d_name[1] != '.')) {
+ return(FALSE);
+ } else {
+ return(TRUE);
+ }
+}/* dir_select_nd() */
+
+
+int
+dir_select(
+#ifdef __linux__
+ const struct dirent *d
+#else
+ struct dirent *d
+#endif
+)
+/*
+ * desc: allways include a directory entry <d>, except
+ * for the current directory
+ * pre: <d> points to a dirent
+ * post: returns TRUE if d->d_name != "." else FALSE
+ */
+{
+ if (strcmp(d->d_name, ".")==0) { /* don't include the current directory */
+ return(FALSE);
+ } else {
+ return(TRUE);
+ }
+} /* dir_select() */
+
+int
+dir_select_root_nd(
+#ifdef __linux__
+ const struct dirent *d
+#else
+ struct dirent *d
+#endif
+)
+/*
+ * desc: allways include a directory entry <d>, except
+ * for the current directory and the parent directory.
+ * Also skip any other dot-files.
+ * pre: <d> points to a dirent
+ * post: returns TRUE if d->d_name[0] != "." else FALSE
+ */
+{
+ if (d->d_name[0] == '.') { /* don't include the current directory */
+ return(FALSE); /* nor the parent directory */
+ } else {
+ return(TRUE);
+ }
+} /* dir_select_root_nd() */
+
+
+int
+dir_select_root(
+#ifdef __linux__
+ const struct dirent *d
+#else
+ struct dirent *d
+#endif
+)
+/*
+ * desc: allways include a directory entry <d>, except
+ * for the current directory and the parent directory
+ * pre: <d> points to a dirent
+ * post: returns TRUE if d->d_name[0] != "." else FALSE
+ */
+{
+ if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) {
+ return(FALSE);
+ } else {
+ return(TRUE);
+ }
+}/* dir_select_root() */
+
+
+#ifdef NO_ALPHA_SORT
+int
+alphasort(const void *d1, const void *d2)
+/*
+ * desc: a replacement for what should be in the library
+ */
+{
+ return(strcmp(((struct dirent *) d1)->d_name,
+ ((struct dirent *) d2)->d_name));
+} /* alphasort() */
+#endif
+
+int
+dir_alphasort(const void *d1, const void *d2)
+/*
+ * desc: compare d1 and d2, but put directories always first
+ * put '..' always on top
+ *
+ */
+{
+ DirList *f1 = ((DirList *) d1),
+ *f2 = ((DirList *) d2);
+ struct stat *s1 = &(f1->filestatus);
+ struct stat *s2 = &(f2->filestatus);
+
+ /* check for '..' */
+ if (strcmp(((DirList *) d1)->filename, "..") == 0) {
+ return(-1);
+ }
+ if (strcmp(((DirList *) d2)->filename, "..") == 0) {
+ return(1);
+ }
+
+ /* put directories first */
+ if ((s1->st_mode & S_IFDIR) && (s2->st_mode & S_IFDIR)) {
+ return(strcmp(f1->filename, f2->filename));
+ };
+ if (s1->st_mode & S_IFDIR) {
+ return(-1);
+ }
+ if (s2->st_mode & S_IFDIR) {
+ return(1);
+ }
+ return(strcmp(f1->filename, f2->filename));
+
+} /* dir_alphasort() */
+
+
+int
+dir_sizesort(const void *d1, const void *d2)
+/*
+ * desc: compare d1 and d2, but put directories always first
+ *
+ */
+{
+ DirList *f1 = ((DirList *) d1),
+ *f2 = ((DirList *) d2);
+ struct stat *s1 = &(f1->filestatus);
+ struct stat *s2 = &(f2->filestatus);
+
+ /* check for '..' */
+ if (strcmp(((DirList *) d1)->filename, "..") == 0) {
+ return(-1);
+ }
+ if (strcmp(((DirList *) d2)->filename, "..") == 0) {
+ return(1);
+ }
+
+ /* put directories first */
+ if ((s1->st_mode & S_IFDIR) && (s2->st_mode & S_IFDIR)) {
+ return(s1->st_size < s2->st_size ?
+ -1
+ :
+ s1->st_size >= s2->st_size);
+ };
+ if (s1->st_mode & S_IFDIR) {
+ return(-1);
+ }
+ if (s2->st_mode & S_IFDIR) {
+ return(1);
+ }
+ return(s1->st_size < s2->st_size ?
+ -1
+ :
+ s1->st_size >= s2->st_size);
+
+} /* dir_sizesort() */
+
+int
+dir_datesort(const void *d1, const void *d2)
+/*
+ * desc: compare d1 and d2 on date, but put directories always first
+ */
+{
+ DirList *f1 = ((DirList *) d1),
+ *f2 = ((DirList *) d2);
+ struct stat *s1 = &(f1->filestatus);
+ struct stat *s2 = &(f2->filestatus);
+
+
+ /* check for '..' */
+ if (strcmp(((DirList *) d1)->filename, "..") == 0) {
+ return(-1);
+ }
+ if (strcmp(((DirList *) d2)->filename, "..") == 0) {
+ return(1);
+ }
+
+ /* put directories first */
+ if ((s1->st_mode & S_IFDIR) && (s2->st_mode & S_IFDIR)) {
+ return(s1->st_mtime < s2->st_mtime ?
+ -1
+ :
+ s1->st_mtime >= s2->st_mtime);
+ };
+ if (s1->st_mode & S_IFDIR) {
+ return(-1);
+ }
+ if (s2->st_mode & S_IFDIR) {
+ return(1);
+ }
+ return(s1->st_mtime < s2->st_mtime ?
+ -1
+ :
+ s1->st_mtime >= s2->st_mtime);
+
+} /* dir_datesort() */
+
+
+int
+null_strcmp(char *s1, char *s2)
+/*
+ * desc: compare strings allowing NULL pointers
+ */
+{
+ if ((s1 == NULL) && (s2 == NULL)) {
+ return(0);
+ }
+ if (s1 == NULL) {
+ return(-1);
+ }
+ if (s2 == NULL) {
+ return(1);
+ }
+ return(strcmp(s1, s2));
+} /* null_strcmp() */
+
+
+int
+dir_extsort(const void *d1, const void *d2)
+/*
+ * desc: compare d1 and d2 on extension, but put directories always first
+ * extension = "the characters after the last dot in the filename"
+ * pre: d1 and d2 are pointers to DirList type records
+ * post: see code
+ */
+{
+ DirList *f1 = ((DirList *) d1),
+ *f2 = ((DirList *) d2);
+ struct stat *s1 = &(f1->filestatus);
+ struct stat *s2 = &(f2->filestatus);
+ char *ext1, *ext2;
+ int extf, ret;
+
+
+ /* check for '..' */
+ if (strcmp(((DirList *) d1)->filename, "..") == 0) {
+ return(-1);
+ }
+ if (strcmp(((DirList *) d2)->filename, "..") == 0) {
+ return(1);
+ }
+
+
+ /* find the first extension */
+
+ ext1 = f1->filename + strlen(f1->filename);
+ extf = FALSE;
+ while (!extf && (ext1 > f1->filename)) {
+ extf = (*--ext1 == '.');
+ }
+ if (!extf) {
+ ext1 = NULL;
+ } else {
+ ext1++;
+ }
+ /* ext1 == NULL if there's no "extension" else ext1 points */
+ /* to the first character of the extension string */
+
+ /* find the second extension */
+
+ ext2 = f2->filename + strlen(f2->filename);
+ extf = FALSE;
+ while (!extf && (ext2 > f2->filename)) {
+ extf = (*--ext2 == '.');
+ }
+ if (!extf) {
+ ext2 = NULL;
+ } else {
+ ext2++;
+ }
+ /* idem as for ext1 */
+
+ if ((s1->st_mode & S_IFDIR) && (s2->st_mode & S_IFDIR)) {
+ ret = null_strcmp(ext1, ext2);
+ if (ret == 0) {
+ return(strcmp(f1->filename, f2->filename));
+ } else {
+ return(ret);
+ }
+ };
+ if (s1->st_mode & S_IFDIR) {
+ return(-1);
+ }
+ if (s2->st_mode & S_IFDIR) {
+ return(1);
+ }
+ ret = null_strcmp(ext1, ext2);
+ if (ret == 0) {
+ return(strcmp(f1->filename, f2->filename));
+ } else {
+ return(ret);
+ }
+
+} /* dir_extsort() */
+
+
+void
+get_dir(char *dirname, char *fmask, DirList **dir, int *n)
+/*
+ * desc: get the files in the current directory
+ * pre: <dir> == NULL
+ * post: <dir> contains <n> dir-entries
+ */
+{
+ char cwd[MAXPATHLEN];
+ char buf[256];
+ struct dirent **dire;
+ struct stat status;
+ int i, j, nb;
+ long d;
+
+
+ getcwd(cwd, MAXPATHLEN);
+ if (strcmp(cwd, "/") == 0) { /* we are in the root directory */
+ if (show_dotfiles()) {
+ *n = scandir(dirname, &dire, dir_select_root, alphasort);
+ } else {
+ *n = scandir(dirname, &dire, dir_select_root_nd, alphasort);
+ }
+ } else {
+ if (show_dotfiles()) {
+ *n = scandir(dirname, &dire, dir_select, alphasort);
+ } else {
+ *n = scandir(dirname, &dire, dir_select_nd, alphasort);
+ }
+ }
+
+ /* There is the possibility that we have entered a directory */
+ /* which we are not allowed to read, scandir thus returning */
+ /* -1 for *n. */
+ /* Actually I should also check for lack of memory, but I'll */
+ /* let my application happily crash if this is the case */
+ /* Solution: */
+ /* manually insert the parent directory as the only */
+ /* directory entry, and return. */
+
+ if (*n == -1) {
+ *n = 1;
+ *dir = (DirList *) malloc(sizeof(DirList));
+ strcpy((*dir)[0].filename, "..");
+ lstat("..", &status);
+ (*dir)[0].filestatus = status;
+ (*dir)[0].link = FALSE;
+ return;
+ }
+
+ *dir = (DirList *) malloc( *n * sizeof(DirList) );
+ d = 0;
+ i = 0;
+ j = 0;
+ while (j<*n) {
+ lstat(dire[j]->d_name, &status);
+ /* check if this file is to be included */
+ /* always include directories, the rest is subject to fmask */
+ if (S_ISDIR(status.st_mode)
+ || fnmatch(fmask, dire[j]->d_name, FNM_NOESCAPE) != FNM_NOMATCH) {
+ strcpy((*dir)[i].filename, dire[j]->d_name);
+ (*dir)[i].filestatus = status;
+ if ((S_IFMT & status.st_mode) == S_IFLNK) { /* handle links */
+ (*dir)[i].link = TRUE;
+ stat(dire[j]->d_name, &status);
+ nb = readlink(dire[j]->d_name, buf, sizeof(buf) - 1);
+ if (nb == -1) {
+ printf("get_dir(): Error reading link: %s\n", dire[j]->d_name);
+ exit(-1);
+ } else {
+ (*dir)[i].linkname = malloc(sizeof(char) * nb + 1);
+ strncpy((*dir)[i].linkname, buf, nb);
+ (*dir)[i].linkname[nb] = 0;
+ }
+ (*dir)[i].filestatus = status;
+ } else {
+ (*dir)[i].link = FALSE;
+ (*dir)[i].linkname = NULL;
+ }
+ i++;
+ } else {
+ /* skip this entry */
+ }
+ j++;
+ }
+ *n = i;
+
+ /* sort the directory with the directory names on top */
+ qsort((*dir), *n, sizeof(DirList), _sort_func);
+
+ /* Free the allocated memory */
+ for (i=0; i<*n; i++) {
+ free(dire[i]);
+ }
+ free(dire);
+
+ return;
+}/* get_dir() */
+
+
+void
+FreeDir(DirList *d, int n)
+/*
+ * desc: free the dirlist d
+ * pre: d != NULL
+ * post: memory allocated to d has been released
+ */
+{
+ int i;
+
+ if (d) {
+ for (i=0; i<n; i++) {
+ if (d[i].linkname) {
+ free(d[i].linkname);
+ }
+ }
+ free(d);
+ } else {
+ printf("dir.c:FreeDir(): d == NULL\n");
+ exit(-1);
+ }
+
+ return;
+} /* FreeDir() */
+
+void
+toggle_dotfiles(void)
+/*
+ * desc: toggle visibility of dot-files
+ */
+{
+ _showdotfiles = !_showdotfiles;
+
+ return;
+} /* toggle_dotfiles() */
+
+int
+show_dotfiles(void)
+/*
+ * desc: return the value of _showdotfiles
+ */
+{
+ return(_showdotfiles);
+} /* show_dotfiles() */
+
+void
+set_dotfiles(int b)
+/*
+ * desc: set the value of _showdotfiles
+ */
+{
+ _showdotfiles = b;
+
+ return;
+} /* set_dotfiles() */
diff --git a/gnu/lib/libodialog/dir.h b/gnu/lib/libodialog/dir.h
new file mode 100644
index 0000000..eadc0c5
--- /dev/null
+++ b/gnu/lib/libodialog/dir.h
@@ -0,0 +1,38 @@
+/*
+ * include file for dir.c
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/dirent.h>
+
+typedef struct DirList { /* structure to hold the directory entries */
+ char filename[MAXNAMLEN]; /* together with the stat-info per file */
+ struct stat filestatus; /* filename, or the name to which it points */
+ int link; /* is it a link ? */
+ char *linkname; /* the name of the file the link points to */
+} DirList;
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+void get_dir(char *dirname, char *fmask, DirList **dir, int *n);
+void get_filenames(DirList *d, int n, char ***names, int *nf);
+void FreeDir(DirList *d, int n);
diff --git a/gnu/lib/libodialog/fselect.c b/gnu/lib/libodialog/fselect.c
new file mode 100644
index 0000000..6669edc
--- /dev/null
+++ b/gnu/lib/libodialog/fselect.c
@@ -0,0 +1,402 @@
+/*
+ * program: fselect.c
+ * author: Marc van Kempen (wmbfmk@urc.tue.nl)
+ * Desc: File selection routine
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <dialog.h>
+#include "ui_objects.h"
+#include "dir.h"
+#include "dialog.priv.h"
+
+/*
+ * Local prototypes
+ */
+
+char *dialog_dfselect(char *dir, char *fmask, int is_fselect);
+
+/*
+ * Functions
+ */
+
+void
+get_directories(DirList *d, int n, char ***names, int *nd)
+/*
+ * Desc: return the directorienames in <dir> as an array in
+ * <names>, the # of entries in <nd>, memory allocated
+ * to *names should be freed when done with it.
+ */
+{
+ int i;
+
+ /* count the directories, which are in front */
+ *nd = 0;
+ while ((*nd < n) && (S_ISDIR(d[*nd].filestatus.st_mode))) (*nd)++;
+ *names = (char **) malloc( *nd * sizeof(char *) );
+ for (i=0; i<*nd; i++) {
+ (*names)[i] = (char *) malloc( strlen(d[i].filename) + 1);
+ strcpy((*names)[i], d[i].filename);
+ }
+
+ return;
+} /* get_directories() */
+
+void
+get_filenames(DirList *d, int n, char ***names, int *nf)
+/*
+ * Desc: return the filenames in <dir> as an arry in
+ * <names>, the # of entries in <nf>, memory allocated
+ * to *names should be freed when done.
+ */
+{
+ int nd, i;
+
+ /* the # of regular files is the total # of files - # of directories */
+ /* count the # of directories */
+ nd = 0;
+ while ((nd < n) && (S_ISDIR(d[nd].filestatus.st_mode))) nd++;
+
+ *names = (char **) malloc( (n-nd) * sizeof(char *) );
+ *nf = n - nd;
+ for (i=0; i<*nf; i++) {
+ (*names)[i] = (char *) malloc( strlen(d[i+nd].filename) + 1);
+ strcpy((*names)[i], d[i+nd].filename);
+ }
+
+ return;
+} /* get_filenames() */
+
+void
+FreeNames(char **names, int n)
+/*
+ * Desc: free the space occupied by names
+ */
+{
+ int i;
+
+ /* free the space occupied by names */
+ for (i=0; i<n; i++) {
+ free(names[i]);
+ }
+ free(names);
+
+ return;
+} /* FreeNames() */
+
+int
+dialog_dselect_old(void)
+/*
+ * Desc: starting from the current directory,
+ * choose a new current directory
+ */
+{
+ DirList *d = NULL;
+ char **names, old_dir[MAXPATHLEN];
+ WINDOW *ds_win;
+ ButtonObj *okbut, *cancelbut;
+ ListObj *dirs_obj;
+ StringObj *dir_obj;
+ char o_dir[MAXPATHLEN];
+ struct ComposeObj *obj = NULL;
+ int n, nd, okbutton, cancelbutton,
+ quit, cancel, ret;
+
+ ds_win = newwin(LINES-8, COLS-30, 4, 15);
+ if (ds_win == NULL) {
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n",
+ LINES-8, COLS-30, 4, 15);
+ exit(1);
+ }
+ draw_box(ds_win, 0, 0, LINES-8, COLS-30, dialog_attr, border_attr);
+ wattrset(ds_win, dialog_attr);
+ mvwaddstr(ds_win, 0, (COLS-30)/2 - 9, " Directory Select ");
+ draw_shadow(stdscr, 4, 15, LINES-8, COLS-30);
+ display_helpline(ds_win, LINES-9, COLS-30);
+
+ /* the Directory string input field */
+ getcwd(o_dir, MAXPATHLEN);
+ dir_obj = NewStringObj(ds_win, "Directory:", o_dir, 1, 2, COLS-34, MAXPATHLEN-1);
+ AddObj(&obj, STRINGOBJ, (void *) dir_obj);
+
+ /* the list of directories */
+ get_dir(".", "*", &d, &n);
+ get_directories(d, n, &names, &nd);
+ dirs_obj = NewListObj(ds_win, "Directories:", names, o_dir, 5, 2,
+ LINES-15, COLS-48, nd);
+ AddObj(&obj, LISTOBJ, (void *) dirs_obj);
+
+ /* the Ok-button */
+ okbutton = FALSE;
+ okbut = NewButtonObj(ds_win, "Continue", &okbutton, 7, COLS-45);
+ AddObj(&obj, BUTTONOBJ, (void *) okbut);
+
+ /* the Cancel-button */
+ cancelbutton = FALSE;
+ cancelbut = NewButtonObj(ds_win, "Return", &cancelbutton, 11, COLS-44);
+ AddObj(&obj, BUTTONOBJ, (void *) cancelbut);
+
+ quit = FALSE;
+ cancel = FALSE;
+ strcpy(old_dir, o_dir);
+ while (!quit) {
+ ret = PollObj(&obj);
+ switch(ret) {
+ case SEL_BUTTON:
+ if (okbutton) {
+ quit = TRUE;
+ }
+ if (cancelbutton) {
+ quit = TRUE;
+ cancel = TRUE;
+ }
+ break;
+ case SEL_CR:
+ if (strcmp(old_dir, o_dir)) {
+ /* the directory was changed, cd into it */
+ if (chdir(o_dir)) {
+ dialog_notify("Could not change into directory");
+ strcpy(o_dir, old_dir);
+ } else {
+ getcwd(o_dir, MAXPATHLEN);
+ strcpy(old_dir, o_dir);
+ }
+ RefreshStringObj(dir_obj);
+ }
+ get_dir(".", "*", &d, &n);
+ FreeNames(names, nd);
+ get_directories(d, n, &names, &nd);
+ UpdateListObj(dirs_obj, names, nd);
+ if (((obj->prev)->obj == (void *) dirs_obj)) {
+ obj=obj->prev;
+ }
+ break;
+ case SEL_ESC:
+ quit = TRUE;
+ cancel = TRUE;
+ break;
+ case KEY_F(1):
+ display_helpfile();
+ break;
+ }
+ }
+
+ FreeNames(names, nd);
+ DelObj(obj);
+ delwin(ds_win);
+
+ return(cancel);
+
+} /* dialog_dselect() */
+
+int
+dialog_dselect(char *dir, char *fmask)
+/*
+ * Desc: Choose a directory
+ */
+{
+ if (dialog_dfselect(dir, fmask, FALSE)) {
+ return(FALSE); /* esc or cancel was pressed */
+ } else {
+ return(TRUE); /* directory was selected */
+ }
+} /* dialog_dselect() */
+
+char *
+dialog_fselect(char *dir, char *fmask)
+/*
+ * Desc: Choose a file from a directory
+ */
+{
+ return(dialog_dfselect(dir, fmask, TRUE));
+} /* dialog_fselect() */
+
+char *
+dialog_dfselect(char *dir, char *fmask, int is_fselect)
+/*
+ * Desc: choose a file from the directory <dir>, which
+ * initially display files with the mask <filemask>
+ * pre: <dir> is the initial directory
+ * only files corresponding to the mask <fmask> are displayed
+ * post: returns NULL if no file was selected
+ * else returns pointer to filename, space is allocated, should
+ * be freed after use.
+ */
+{
+ DirList *d = NULL;
+ char msg[512];
+ char **fnames, **dnames, *ret_name;
+ WINDOW *fs_win;
+ int n, nd, nf, ret;
+ StringObj *fm_obj, *dir_obj, *sel_obj;
+ char o_fm[255], o_dir[MAXPATHLEN], o_sel[MAXPATHLEN];
+ char old_fmask[255], old_dir[MAXPATHLEN];
+ ListObj *dirs_obj, *files_obj;
+ struct ComposeObj *obj = NULL, *o;
+ int quit, cancel;
+ ButtonObj *okbut_obj, *canbut_obj;
+ int ok_button, cancel_button;
+
+ if (chdir(dir)) {
+ sprintf(msg, "Could not move into specified directory: %s", dir);
+ dialog_notify(msg);
+ return(NULL);
+ }
+ getcwd(o_dir, MAXPATHLEN);
+
+ /* setup the fileselect-window and initialize its components */
+ fs_win = newwin(LINES-2, COLS-20, 1, 10);
+ if (fs_win == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n",
+ LINES-2, COLS-20, 2, 10);
+ exit(1);
+ }
+ draw_box(fs_win, 0, 0, LINES-2, COLS-20, dialog_attr, border_attr);
+ wattrset(fs_win, dialog_attr);
+ if (is_fselect) {
+ mvwaddstr(fs_win, 0, (COLS-20)/2 - 7, " File Select ");
+ } else {
+ mvwaddstr(fs_win, 0, (COLS-20)/2 - 9, " Directory Select ");
+ }
+ draw_shadow(stdscr, 1, 10, LINES-2, COLS-20);
+ display_helpline(fs_win, LINES-3, COLS-20);
+
+ /* Filemask entry */
+ strcpy(o_fm, fmask);
+ fm_obj = NewStringObj(fs_win, "Filemask:", o_fm, 1, 2, 19, 255);
+ AddObj(&obj, STRINGOBJ, (void *) fm_obj);
+
+ /* Directory entry */
+ dir_obj = NewStringObj(fs_win, "Directory:", o_dir, 1, 22, COLS-44, 255);
+ AddObj(&obj, STRINGOBJ, (void *) dir_obj);
+
+ /* Directory list */
+ get_dir(".", fmask, &d, &n); /* read the entire directory */
+ get_directories(d, n, &dnames, &nd); /* extract the dir-entries */
+ if (is_fselect) {
+ dirs_obj = NewListObj(fs_win, "Directories:", dnames, o_dir, 5, 2,
+ LINES-16, (COLS-20)/2-2, nd);
+ } else {
+ dirs_obj = NewListObj(fs_win, "Directories:", dnames, o_dir, 5, 2,
+ LINES-12, (COLS-20)/2-2, nd);
+ }
+ AddObj(&obj, LISTOBJ, (void *) dirs_obj);
+
+ /* Filenames list */
+ get_filenames(d, n, &fnames, &nf); /* extract the filenames */
+ if (is_fselect) {
+ files_obj = NewListObj(fs_win, "Files:", fnames, o_sel, 5, (COLS-20)/2+1,
+ LINES-16, (COLS-20)/2-3, nf);
+ } else {
+ files_obj = NewListObj(fs_win, "Files:", fnames, o_sel, 5, (COLS-20)/2+1,
+ LINES-12, (COLS-20)/2-3, nf);
+ }
+ AddObj(&obj, LISTOBJ, (void *) files_obj);
+
+ if (is_fselect) {
+ /* Selection entry */
+ o_sel[0] = '\0';
+ sel_obj = NewStringObj(fs_win, "Selection:", o_sel, LINES-10, 2, COLS-24, 255);
+ AddObj(&obj, STRINGOBJ, (void *) sel_obj);
+ }
+
+ /* Ok button */
+ ok_button = FALSE;
+ okbut_obj = NewButtonObj(fs_win, "Ok", &ok_button, LINES-6, 20);
+ AddObj(&obj, BUTTONOBJ, (void *) okbut_obj);
+
+ /* Cancel button */
+ cancel_button = FALSE;
+ canbut_obj = NewButtonObj(fs_win, "Cancel", &cancel_button, LINES-6, 30);
+ AddObj(&obj, BUTTONOBJ, (void *) canbut_obj);
+
+ /* Make sure all objects on the window are drawn */
+ wrefresh(fs_win);
+ keypad(fs_win, TRUE);
+
+ /* Start the reading */
+ o = obj;
+ strcpy(old_fmask, o_fm);
+ strcpy(old_dir, o_dir);
+ quit = FALSE;
+ cancel = FALSE;
+ while (!quit) {
+ ret = PollObj(&o);
+ switch(ret) {
+ case SEL_CR:
+ if (strcmp(old_fmask, o_fm) || strcmp(old_dir, o_dir)) {
+ /* reread directory and update the listobjects */
+ if (strcmp(old_dir, o_dir)) { /* dir entry was changed */
+ if (chdir(o_dir)) {
+ dialog_notify("Could not change into directory");
+ strcpy(o_dir, old_dir);
+ } else {
+ getcwd(o_dir, MAXPATHLEN);
+ strcpy(old_dir, o_dir);
+ }
+ RefreshStringObj(dir_obj);
+ } else { /* fmask entry was changed */
+ strcpy(old_fmask, o_fm);
+ }
+ get_dir(".", o_fm, &d, &n);
+ FreeNames(dnames, nd);
+ get_directories(d, n, &dnames, &nd);
+ UpdateListObj(dirs_obj, dnames, nd);
+ FreeNames(fnames, nf);
+ get_filenames(d, n, &fnames, &nf);
+ UpdateListObj(files_obj, fnames, nf);
+ if (((o->prev)->obj == (void *) dirs_obj)) {
+ o=o->prev;
+ }
+ }
+ break;
+ case SEL_BUTTON:
+ /* check which button was pressed */
+ if (ok_button) {
+ quit = TRUE;
+ }
+ if (cancel_button) {
+ quit = TRUE;
+ cancel = TRUE;
+ }
+ break;
+ case SEL_ESC:
+ quit = TRUE;
+ cancel = TRUE;
+ break;
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+ }
+ DelObj(obj);
+ FreeNames(dnames, nd);
+ FreeNames(fnames, nf);
+ delwin(fs_win);
+
+ if (cancel || (strlen(o_sel) == 0)) {
+ return(NULL);
+ } else {
+ ret_name = (char *) malloc( strlen(o_sel) + 1 );
+ strcpy(ret_name, o_sel);
+ return(ret_name);
+ }
+} /* dialog_fselect() */
+
diff --git a/gnu/lib/libodialog/gauge.c b/gnu/lib/libodialog/gauge.c
new file mode 100644
index 0000000..d8138f6
--- /dev/null
+++ b/gnu/lib/libodialog/gauge.c
@@ -0,0 +1,79 @@
+/*
+ * gauge.c
+ *
+ * progress indicator for libdialog
+ *
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "dialog.h"
+
+void
+dialog_gauge(char *title, char *prompt, int y, int x,
+ int height, int width, int perc)
+/*
+ * Desc: display a progress bar, progress indicated by <perc>
+ */
+{
+ WINDOW *gw;
+ int glen, i;
+ char percs[5];
+
+ gw = newwin(height, width, y, x);
+ if (!gw) {
+ fprintf(stderr, "dialog_gauge: Error creating window (%d, %d, %d, %d)",
+ height, width, y, x);
+ exit(-1);
+ }
+
+ draw_box(gw, 0, 0, height, width, dialog_attr, border_attr);
+ draw_shadow(stdscr, y, x, height, width);
+
+ wattrset(gw, title_attr);
+ if (title) {
+ wmove(gw, 0, (width - strlen(title))/2 - 1);
+ waddstr(gw, "[ ");
+ waddstr(gw, title);
+ waddstr(gw, " ]");
+ }
+ wattrset(gw, dialog_attr);
+ if (prompt) {
+ wmove(gw, 1, (width - strlen(prompt))/2 - 1);
+ waddstr(gw, prompt);
+ }
+
+ draw_box(gw, 2, 2, 3, width-4, dialog_attr, border_attr);
+ glen = (int) ((float) perc/100 * (width-6));
+
+ wattrset(gw, dialog_attr);
+ sprintf(percs, "%3d%%", perc);
+ wmove(gw, 5, width/2 - 2);
+ waddstr(gw, percs);
+
+ wattrset(gw, A_BOLD);
+ wmove(gw, 3, 3);
+ for (i=0; i<glen; i++) waddch(gw, ' ');
+
+ wrefresh(gw);
+ delwin(gw);
+
+ return;
+} /* dialog_gauge() */
+
diff --git a/gnu/lib/libodialog/help.c b/gnu/lib/libodialog/help.c
new file mode 100644
index 0000000..de49c6a
--- /dev/null
+++ b/gnu/lib/libodialog/help.c
@@ -0,0 +1,194 @@
+/***************************************************************
+ *
+ * Program: help.c
+ * Author: Marc van Kempen
+ * Desc: get help
+ *
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ ***************************************************************/
+
+#include <stdlib.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <dialog.h>
+
+static char _helpfilebuf[MAXPATHLEN];
+static char _helplinebuf[77]; /* limit the helpline to 76 characters */
+static char *_helpfile = NULL;
+static char *_helpline = NULL;
+
+/******************************************************************
+ *
+ * helpfile routines
+ *
+ ******************************************************************/
+
+void
+use_helpfile(char *hfile)
+/*
+ * desc: set the helpfile to be opened on pressing F1 to <helpfile>
+ */
+{
+ if (hfile != NULL) {
+ _helpfile = _helpfilebuf;
+ strcpy(_helpfile, hfile);
+ } else {
+ _helpfile = NULL;
+ }
+
+ return;
+} /* use_helpfile() */
+
+void
+display_helpfile(void)
+/*
+ * desc: display the current helpfile in a window
+ */
+{
+ WINDOW *w;
+ FILE *f;
+ struct stat sb;
+ char msg[80], *buf;
+ static int in_help = FALSE;
+ char *savehline = NULL;
+
+ if (in_help) return; /* dont call help when you're in help */
+
+ if (_helpfile != NULL) {
+ if ((w = dupwin(newscr)) == NULL) {
+ dialog_notify("No memory to dup previous screen\n");
+ return;
+ }
+ if ((f = fopen(_helpfile, "r")) == NULL) {
+ sprintf(msg, "Can't open helpfile : %s\n", _helpfile);
+ dialog_notify(msg);
+ return;
+ }
+ if (fstat(fileno(f), &sb)) {
+ sprintf(msg, "Can't stat helpfile : %s\n", _helpfile);
+ dialog_notify(msg);
+ return;
+ }
+ if ((buf = (char *) malloc( sb.st_size )) == NULL) {
+ sprintf(msg, "Could not malloc space for helpfile : %s\n", _helpfile);
+ dialog_notify(msg);
+ return;
+ }
+ if (fread(buf, 1, sb.st_size, f) != sb.st_size) {
+ sprintf(msg, "Could not read entire help file : %s", _helpfile);
+ dialog_notify(msg);
+ free(buf);
+ return;
+ }
+ buf[sb.st_size] = 0;
+ in_help = TRUE;
+ savehline = get_helpline();
+ use_helpline("Use arrowkeys, PgUp, PgDn, Home and End to move through text");
+ dialog_mesgbox("Online help", buf, LINES-4, COLS-4);
+ restore_helpline(savehline);
+ in_help = FALSE;
+ touchwin(w);
+ wrefresh(w);
+ delwin(w);
+ free(buf);
+ } else {
+ /* do nothing */
+ }
+
+ return;
+} /* display_helpfile() */
+
+
+/******************************************************************
+ *
+ * helpline routines
+ *
+ ******************************************************************/
+
+void
+use_helpline(char *hline)
+/*
+ * desc: set the helpline to printed in dialogs
+ */
+{
+ if (hline) {
+ _helpline = _helplinebuf;
+ if (strlen(hline) > 76) {
+ /* only display the first 76 characters in the helpline */
+ strncpy(_helpline, hline, 76);
+ _helpline[76] = 0;
+ } else {
+ strcpy(_helpline, hline);
+ }
+ } else {
+ _helpline = NULL;
+ }
+
+ return;
+} /* use_helpline() */
+
+void
+display_helpline(WINDOW *w, int y, int width)
+/*
+ * desc: display the helpline at the given coordinates <y, x> in the window <w>
+ */
+{
+ if (_helpline != NULL) {
+ if (strlen(_helpline) > width - 6) {
+ _helpline[width - 6] = 0;
+ }
+ wmove(w, y, (int) (width - strlen(_helpline)- 4) / 2);
+ wattrset(w, title_attr);
+ waddstr(w, "[ ");
+ waddstr(w, _helpline);
+ waddstr(w, " ]");
+ } else {
+ /* do nothing */
+ }
+
+ return;
+}
+
+char *
+get_helpline(void)
+/*
+ * desc: allocate new space, copy the helpline to it and return a pointer to it
+ */
+{
+ char *hlp;
+
+ if (_helpline) {
+ hlp = (char *) malloc( strlen(_helpline) + 1 );
+ strcpy(hlp, _helpline);
+ } else {
+ hlp = NULL;
+ }
+
+ return(hlp);
+} /* get_helpline() */
+
+void
+restore_helpline(char *helpline)
+/*
+ * Desc: set the helpline to <helpline> and free the space allocated to it
+ */
+{
+ use_helpline(helpline);
+ free(helpline);
+
+ return;
+} /* restore_helpline() */
diff --git a/gnu/lib/libodialog/inputbox.c b/gnu/lib/libodialog/inputbox.c
new file mode 100644
index 0000000..1f61ed5
--- /dev/null
+++ b/gnu/lib/libodialog/inputbox.c
@@ -0,0 +1,190 @@
+/*
+ * 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>
+#include "dialog.priv.h"
+
+
+/*
+ * Display a dialog box for inputing a string
+ */
+int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int width, unsigned char *result)
+{
+ int i, j, x, y, box_y, box_x, box_width, first,
+ key = 0, button = -1;
+ unsigned char instr[MAX_LEN+1];
+ WINDOW *dialog;
+
+ if (height < 0)
+ height = strheight(prompt)+2+4;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i,j) + 4;
+ }
+ width = MAX(width,24);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = DialogX ? DialogX : (COLS - width)/2;
+ y = DialogY ? DialogY : (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ exit(1);
+ }
+ 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);
+ wmove(dialog, 1, 2);
+ print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
+
+ /* 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);
+
+ display_helpline(dialog, height-1, width);
+
+ x = width/2-11;
+ y = height-2;
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+
+ first = 1;
+ strcpy(instr, result);
+ wattrset(dialog, dialog_attr);
+
+ while (key != ESC) {
+
+ if (button == -1) { /* Input box selected */
+ key = line_edit(dialog, box_y, box_x, -1, box_width, inputbox_attr, first, instr, DialogInputAttrs);
+ first = 0;
+ }
+ else
+ key = wgetch(dialog);
+
+ switch (key) {
+ case 'O':
+ case 'o':
+ delwin(dialog);
+ strcpy(result, 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);
+ 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);
+ break;
+ }
+ break;
+ case ' ':
+ case '\n':
+ case '\r':
+ delwin(dialog);
+ if (button < 1)
+ strcpy(result, instr);
+ return (button == -1 ? 0 : button);
+ case ESC:
+ break;
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+ }
+
+ delwin(dialog);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_inputbox() */
diff --git a/gnu/lib/libodialog/kernel.c b/gnu/lib/libodialog/kernel.c
new file mode 100644
index 0000000..9ed5eac
--- /dev/null
+++ b/gnu/lib/libodialog/kernel.c
@@ -0,0 +1,536 @@
+/*
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __DIALOG_MAIN__
+
+#include <dialog.h>
+#include <err.h>
+#include "dialog.priv.h"
+#ifdef HAVE_NCURSES
+#include "colors.h"
+#endif
+
+/* These are two "secret" globals that can be fiddled to make a dialog
+ * come up someplace other than a "centered" calculation for X,Y
+ */
+int DialogX, DialogY;
+
+/* This "secret" global allows you to change the behavior of an input field */
+int DialogInputAttrs;
+
+/*
+ * Do some initialization for dialog
+ */
+void init_dialog(void)
+{
+
+ if (issetugid()) {
+ errx(1, "libdialog is unsafe to use in setugid applications");
+ }
+
+#if defined(LOCALE)
+ (void) setlocale(LC_ALL, "");
+#endif
+
+#ifdef HAVE_NCURSES
+ if (parse_rc() == -1) /* Read the configuration file */
+ exit(-1);
+#endif
+
+ if (initscr() == NULL) { /* Init curses */
+ fprintf(stderr, "\nCurses initialization error.\n");
+ exit(-1);
+ }
+ keypad(stdscr, TRUE);
+ cbreak();
+ noecho();
+
+#ifdef HAVE_NCURSES
+ if (use_colors || use_shadow) /* Set up colors */
+ color_setup();
+#endif
+
+ /* Set screen to screen attribute */
+ dialog_clear_norefresh();
+ DialogX = DialogY = 0;
+}
+/* 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 height, int width, int maxwidth, int y, int x, int center, int rawmode)
+{
+ int cur_x, cur_y, i;
+ unsigned char tempstr[MAX_LEN+1], *word, *tempptr, *tempptr1;
+ chtype ostuff[132], attrs = 0, init_bottom = 0;
+
+ wsetscrreg(win, y, height);
+ getyx(win, cur_y, cur_x);
+
+ strncpy(tempstr, prompt, MAX_LEN);
+ tempstr[MAX_LEN] = '\0';
+ if ((!rawmode && strstr(tempstr, "\\n") != NULL) ||
+ (strchr(tempstr, '\n') != NULL)) { /* Prompt contains "\n" or '\n' */
+ word = tempstr;
+ while (1) {
+ tempptr = rawmode ? NULL : 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;
+ if (++cur_y > height) {
+ cur_y--;
+ if (!init_bottom) {
+ for (i = 0; i < x; i++)
+ ostuff[i] = mvwinch(win, cur_y, i);
+ for (i = width; i < maxwidth; i++)
+ ostuff[i] = mvwinch(win, cur_y, i);
+ attrs = getattrs(win);
+ init_bottom = 1;
+ }
+ scrollok(win, TRUE);
+ scroll(win);
+ scrollok(win, FALSE);
+ wmove(win, cur_y, 0);
+ for (i = 0; i < x; i++) {
+ wattrset(win, ostuff[i]&A_ATTRIBUTES);
+ waddch(win, ostuff[i]);
+ }
+ wattrset(win, attrs);
+ for ( ; i < width; i++)
+ waddch(win, ' ');
+ for ( ; i < maxwidth; i++) {
+ wattrset(win, ostuff[i]&A_ATTRIBUTES);
+ waddch(win, ostuff[i]);
+ }
+ wattrset(win, attrs);
+ wrefresh(win);
+ }
+ wmove(win, cur_y, cur_x = x);
+ }
+ waddstr(win, word);
+ }
+ else if (center && strlen(tempstr) <= width-x*2) { /* If prompt is short */
+ wmove(win, cur_y, (width - strlen(tempstr)) / 2);
+ waddstr(win, tempstr);
+ }
+ else if (!center && strlen(tempstr) <= width-cur_x) { /* If prompt is short */
+ waddstr(win, tempstr);
+ }
+ else {
+ char *p = tempstr;
+
+ /* Print prompt word by word, wrap around if necessary */
+ while ((word = strsep(&p, "\t\n ")) != NULL) {
+ int loop;
+ unsigned char sc;
+
+ if (*word == '\0')
+ continue;
+ do {
+ loop = 0;
+ if (cur_x+strlen(word) >= width+1) { /* wrap around to next line */
+ if (x+strlen(word) >= width+1) {
+ sc = word[width-cur_x-1];
+ word[width-cur_x-1] = '\0';
+ wmove(win, cur_y, cur_x);
+ waddstr(win, word);
+ word[width-cur_x-1] = sc;
+ word += width-cur_x-1;
+ getyx(win, cur_y, cur_x);
+ loop = 1;
+ }
+ cur_y++;
+ cur_x = x;
+ if (cur_y > height) {
+ cur_y--;
+ if (!init_bottom) {
+ for (i = 0; i < x; i++)
+ ostuff[i] = mvwinch(win, cur_y, i);
+ for (i = width; i < maxwidth; i++)
+ ostuff[i] = mvwinch(win, cur_y, i);
+ attrs = getattrs(win);
+ init_bottom = 1;
+ }
+ scrollok(win, TRUE);
+ scroll(win);
+ scrollok(win, FALSE);
+ wmove(win, cur_y, 0);
+ for (i = 0; i < x; i++) {
+ wattrset(win, ostuff[i]&A_ATTRIBUTES);
+ waddch(win, ostuff[i]);
+ }
+ wattrset(win, attrs);
+ for ( ; i < width; i++)
+ waddch(win, ' ');
+ for ( ; i < maxwidth; i++) {
+ wattrset(win, ostuff[i]&A_ATTRIBUTES);
+ waddch(win, ostuff[i]);
+ }
+ wattrset(win, attrs);
+ wrefresh(win);
+ }
+ }
+ }
+ while(loop);
+ 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, selected ? "[" : " ");
+ temp = strspn(label, " ");
+ label += temp;
+ 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_active_attr : button_inactive_attr);
+ waddstr(win, label+1);
+ waddstr(win, selected ? "]" : " ");
+ 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,sx,sy;
+ chtype attrs;
+
+ if (has_colors()) { /* Whether terminal supports color? */
+ getbegyx(win,sy,sx);
+ attrs = getattrs(win);
+ if (y+height < getmaxy(win)) {
+ /* small touch */
+ wattrset(win, A_INVIS);
+ wmove(win, y + height, x + 2);
+ for (i = 0; i < width; i++)
+ if (i+x+2 < getmaxx(win))
+ waddch(win, ' ');
+ /* end touch */
+ wattrset(win, shadow_attr);
+ wmove(win, y + height, x + 2);
+ for (i = 0; i < width; i++)
+ if (i+x+2 < getmaxx(win))
+ waddch(win, mvwinch(newscr, sy+y+height, sx+x+2+i) & A_CHARTEXT);
+ }
+ if (x+width < getmaxx(win)) {
+ for (i = y + 1; i < y + height + 1; i++) {
+ if (i < getmaxy(win)) {
+ /* small touch */
+ wattrset(win, A_INVIS);
+ wmove(win, i, x + width);
+ waddch(win, ' ');
+ if (x+width+1 < getmaxx(win))
+ waddch(win, ' ');
+ /* end touch */
+ wattrset(win, shadow_attr);
+ wmove(win, i, x + width);
+ waddch(win, mvwinch(newscr, sy+i, sx+x+width) & A_CHARTEXT);
+ if (x+width+1 < getmaxx(win))
+ waddch(win, mvwinch(newscr, sy+i, sx+x+width+1) & A_CHARTEXT);
+ }
+ }
+ }
+ wattrset(win, attrs);
+ wnoutrefresh(win);
+ }
+}
+/* End of draw_shadow() */
+#endif
+
+void dialog_clear_norefresh(void)
+{
+ attr_clear(stdscr, LINES, COLS, screen_attr);
+ touchwin(stdscr);
+ wnoutrefresh(stdscr);
+}
+
+void dialog_clear(void)
+{
+ dialog_clear_norefresh();
+ doupdate();
+}
+
+void dialog_update(void)
+{
+ refresh();
+}
+
+void end_dialog(void)
+{
+ endwin();
+}
+
+int strwidth(const char *p)
+{
+ int i = 0, len, incr;
+ const char *start, *s, *s1, *s2;
+
+ for (start = s = p; ; start = (s += incr)) {
+ s1 = strchr(s, '\n');
+ s2 = strstr(s, "\\n");
+ if (s2 == NULL)
+ s = s1;
+ else if (s1 == NULL)
+ s = s2;
+ else
+ s = MIN(s1, s2);
+ if (s == NULL)
+ break;
+ incr = 1 + (s == s2);
+ len = s - start;
+ if (len > i)
+ i = len;
+ }
+ len = strlen(start);
+ if (len > i)
+ i = len;
+ return i;
+}
+
+int strheight(const char *p)
+{
+ int i = 1, incr;
+ const char *s, *s1, *s2;
+
+ for (s = p; ; s += incr) {
+ s1 = strchr(s, '\n');
+ s2 = strstr(s, "\\n");
+ if (s2 == NULL)
+ s = s1;
+ else if (s1 == NULL)
+ s = s2;
+ else
+ s = MIN(s1, s2);
+ if (s == NULL)
+ break;
+ incr = 1 + (s == s2);
+ i++;
+ }
+ return i;
+}
+
+void print_arrows(WINDOW *dialog, int scroll, int menu_height, int item_no,
+ int box_x, int box_y, int tag_x, int cur_x, int cur_y)
+{
+ 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);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 1);
+ wattrset(dialog, scroll+menu_height < item_no ? darrow_attr : menubox_border_attr);
+ waddch(dialog, scroll+menu_height < item_no ? ACS_DARROW : ACS_HLINE);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 2);
+ waddch(dialog, scroll+menu_height < item_no ? '(' : ACS_HLINE);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 3);
+ waddch(dialog, scroll+menu_height < item_no ? '+' : ACS_HLINE);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 4);
+ waddch(dialog, scroll+menu_height < item_no ? ')' : ACS_HLINE);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+}
+
diff --git a/gnu/lib/libodialog/lineedit.c b/gnu/lib/libodialog/lineedit.c
new file mode 100644
index 0000000..7bfe0e0
--- /dev/null
+++ b/gnu/lib/libodialog/lineedit.c
@@ -0,0 +1,213 @@
+/*
+ * Changes Copyright (C) 1995 by Andrey A. Chernov, Moscow
+ *
+ * Original Copyright:
+ *
+ * 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 "dialog.priv.h"
+
+static void redraw_field(WINDOW *dialog, int box_y, int box_x, int flen, int box_width, unsigned char instr[], int input_x, int scroll, chtype attr, chtype old_attr, int fexit, int attr_mask);
+
+/*
+ * Line editor
+ */
+int line_edit(WINDOW* dialog, int box_y, int box_x, int flen, int box_width, chtype attr, int first, unsigned char *result, int attr_mask)
+{
+ int i, key;
+ chtype old_attr;
+ static int input_x, scroll;
+ static unsigned char instr[MAX_LEN+1];
+ unsigned char erase_char = erasechar();
+ unsigned char kill_char = killchar();
+#ifdef notyet
+ unsignec char werase_char = cur_term->Ottyb.c_cc[VWERASE];
+#endif
+
+ old_attr = getattrs(dialog);
+ keypad(dialog, TRUE);
+
+ if (first) {
+ memset(instr, 0, sizeof(instr));
+ strcpy(instr, result);
+ i = strlen(instr);
+/* input_x = i % box_width;*/
+ input_x = (i > box_width) ? box_width - 1 : i;
+/* scroll = i - input_x;*/
+ scroll = (i > box_width) ? i - box_width + 1: 0;
+ }
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE, attr_mask);
+
+ for (;;) {
+ wattrset(dialog, attr);
+ wrefresh(dialog);
+ key = wgetch(dialog);
+ switch (key) {
+ case ctrl('q'):
+ goto ret;
+ break;
+ case KEY_F(1):
+ display_helpfile();
+ break;
+ case TAB:
+ case KEY_BTAB:
+ case KEY_UP:
+ case KEY_DOWN:
+ case ESC:
+ case '\r':
+ case '\n':
+ for (i = strlen(instr) - 1; i >= scroll + input_x && instr[i] == ' '; i--)
+ instr[i] = '\0';
+ if (key == '\r')
+ key = '\n';
+ goto ret;
+ case '\025':
+ case '\030':
+ kill_it:
+ input_x = scroll = 0;
+ /* fall through */
+ case '\013':
+ case KEY_EOL:
+ memset(instr + scroll + input_x, '\0', sizeof(instr) - scroll - input_x);
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE, attr_mask);
+ continue;
+ case '\001':
+ case KEY_HOME:
+ input_x = scroll = 0;
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE, attr_mask);
+ continue;
+ case '\005':
+ case KEY_END:
+ for (i = strlen(instr) - 1; i >= scroll + input_x && instr[i] == ' '; i--)
+ instr[i] = '\0';
+ i++;
+ input_x = i % box_width;
+ scroll = i - input_x;
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE, attr_mask);
+ continue;
+ case '\002':
+ case KEY_LEFT:
+ if (input_x || scroll) {
+ if (!input_x) {
+ int oldscroll = scroll;
+ scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
+ input_x = oldscroll - 1 - scroll;
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE, attr_mask);
+ } else {
+ input_x--;
+ wmove(dialog, box_y, input_x + box_x);
+ }
+ } else
+ beep();
+ continue;
+ case '\006':
+ case KEY_RIGHT:
+ if ( scroll+input_x < MAX_LEN
+ && (flen < 0 || scroll+input_x < flen)
+ ) {
+ if (!instr[scroll+input_x])
+ instr[scroll+input_x] = ' ';
+ if (input_x == box_width-1) {
+ scroll++;
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE, attr_mask);
+ }
+ else {
+ wmove(dialog, box_y, input_x + box_x);
+ waddch(dialog, instr[scroll+input_x]);
+ input_x++;
+ }
+ } else
+ beep(); /* Alarm user about overflow */
+ continue;
+ case '\b':
+ case '\177':
+ case KEY_BACKSPACE:
+ erase_it:
+ if (input_x || scroll) {
+ i = strlen(instr);
+ memmove(instr+scroll+input_x-1, instr+scroll+input_x, i-(scroll+input_x)+1);
+ if (!input_x) {
+ int oldscroll = scroll;
+ scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
+ input_x = oldscroll - 1 - scroll;
+ } else
+ input_x--;
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE, attr_mask);
+ } else
+ beep();
+ continue;
+ case '\004':
+ case KEY_DC:
+ for (i = strlen(instr) - 1; i >= scroll + input_x && instr[i] == ' '; i--)
+ instr[i] = '\0';
+ i++;
+ if (i == 0) {
+ beep();
+ continue;
+ }
+ memmove(instr+scroll+input_x, instr+scroll+input_x+1, i-(scroll+input_x));
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE, attr_mask);
+ continue;
+ default:
+ if (CCEQ(key, erase_char))
+ goto erase_it;
+ if (CCEQ(key, kill_char))
+ goto kill_it;
+ if (key < 0x100 && isprint(key)) {
+ for (i = strlen(instr) - 1; i >= scroll + input_x && instr[i] == ' '; i--)
+ instr[i] = '\0';
+ i++;
+ if (i < MAX_LEN && (flen < 0 || scroll+input_x < flen)) {
+ if (flen < 0 || i < flen)
+ memmove(instr+scroll+input_x+1, instr+scroll+input_x, i-(scroll+input_x));
+ instr[scroll+input_x] = key;
+ if (input_x == box_width-1 && (flen < 0 || i < flen))
+ scroll++;
+ else
+ input_x++;
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE, attr_mask);
+ } else
+ beep(); /* Alarm user about overflow */
+ continue;
+ }
+ }
+ }
+ret:
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, TRUE, attr_mask);
+ wrefresh(dialog);
+ strcpy(result, instr);
+ return key;
+}
+
+static void
+redraw_field(WINDOW *dialog, int box_y, int box_x, int flen, int box_width, unsigned char instr[], int input_x, int scroll, chtype attr, chtype old_attr, int fexit, int attr_mask)
+{
+ int i, fix_len;
+
+ wattrset(dialog, fexit ? old_attr : attr);
+ wmove(dialog, box_y, box_x);
+ fix_len = flen >= 0 ? MIN(flen-scroll,box_width) : box_width;
+ for (i = 0; i < fix_len; i++)
+ waddch(dialog, instr[scroll+i] ? ((attr_mask & DITEM_NO_ECHO) ? '*' : instr[scroll+i]) : ' ');
+ wattrset(dialog, old_attr);
+ for ( ; i < box_width; i++)
+ waddch(dialog, instr[scroll+i] ? ((attr_mask & DITEM_NO_ECHO) ? '*' : instr[scroll+i]) : ' ');
+ wmove(dialog, box_y, input_x + box_x);
+}
diff --git a/gnu/lib/libodialog/menubox.c b/gnu/lib/libodialog/menubox.c
new file mode 100644
index 0000000..a01acd5
--- /dev/null
+++ b/gnu/lib/libodialog/menubox.c
@@ -0,0 +1,469 @@
+/*
+ * menubox.c -- implements the menu box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * Substantial rennovation: 12/18/95, Jordan K. Hubbard
+ *
+ * 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/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dialog.h>
+#include "dialog.priv.h"
+#include <err.h>
+#include <ncurses.h>
+
+static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int choice, int selected, dialogMenuItem *me, int menu_width, int tag_x, int item_x);
+
+#define DREF(di, item) ((di) ? &((di)[(item)]) : NULL)
+
+/*
+ * 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 cnt, void *it, unsigned char *result, int *ch, int *sc)
+{
+ int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button, choice,
+ l, k, scroll, max_choice, item_no, redraw_menu = FALSE;
+ char okButton, cancelButton;
+ int rval = 0, ok_space, cancel_space;
+ WINDOW *dialog, *menu;
+ unsigned char **items = NULL;
+ dialogMenuItem *ditems;
+ int menu_width, tag_x, item_x;
+
+draw:
+ choice = ch ? *ch : 0;
+ scroll = sc ? *sc : 0;
+ button = 0;
+
+ /* If item_no is a positive integer, use old item specification format */
+ if (cnt >= 0) {
+ items = it;
+ ditems = NULL;
+ item_no = cnt;
+ }
+ /* It's the new specification format - fake the rest of the code out */
+ else {
+ item_no = abs(cnt);
+ ditems = it;
+ if (!items)
+ items = (unsigned char **)alloca((item_no * 2) * sizeof(unsigned char *));
+
+ /* Initializes status */
+ for (i = 0; i < item_no; i++) {
+ items[i*2] = ditems[i].prompt;
+ items[i*2 + 1] = ditems[i].title;
+ }
+ }
+ max_choice = MIN(menu_height, item_no);
+
+ tag_x = 0;
+ item_x = 0;
+ /* Find length of longest item in order to center menu */
+ for (i = 0; i < item_no; i++) {
+ l = strlen(items[i * 2]);
+ for (j = 0; j < item_no; j++) {
+ k = strlen(items[j * 2 + 1]);
+ tag_x = MAX(tag_x, l + k + 2);
+ }
+ item_x = MAX(item_x, l);
+ }
+ if (height < 0)
+ height = strheight(prompt) + menu_height + 4 + 2;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i, j);
+ width = MAX(width, tag_x + 4) + 4;
+ }
+ width = MAX(width, 24);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = DialogX ? DialogX : (COLS - width) / 2;
+ y = DialogY ? DialogY : (LINES - height) / 2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height, width, y, x);
+ return -1;
+ }
+ 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);
+ wmove(dialog, 1, 2);
+ print_autowrap(dialog, prompt, height - 1, width - 2, width, 1, 2, TRUE, FALSE);
+
+ 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);
+ if (menu == NULL) {
+ delwin(dialog);
+ endwin();
+ fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", menu_height, menu_width,
+ y + box_y + 1, x + box_x + 1);
+ return -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 = menu_width > tag_x + 1 ? (menu_width - tag_x) / 2 : 1;
+ item_x = menu_width > item_x + 4 ? tag_x + item_x + 2 : menu_width - 3;
+
+ /* Print the menu */
+ for (i = 0; i < max_choice; i++)
+ print_item(menu, items[(scroll + i) * 2], items[(scroll + i) * 2 + 1], i, i == choice, DREF(ditems, scroll + i), menu_width, tag_x, item_x);
+ wnoutrefresh(menu);
+ print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, tag_x, cur_x, cur_y);
+
+ display_helpline(dialog, height - 1, width);
+
+ x = width / 2 - 11;
+ y = height - 2;
+
+ if (ditems && result) {
+ cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]);
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : FALSE);
+ okButton = toupper(ditems[OK_BUTTON].prompt[0]);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : TRUE);
+ }
+ else {
+ cancelButton = 'C';
+ print_button(dialog, "Cancel", y, x + 14, FALSE);
+ okButton = 'O';
+ print_button(dialog, " OK ", y, x, TRUE);
+ }
+
+ wrefresh(dialog);
+ while (key != ESC) {
+ key = wgetch(dialog);
+
+ /* Shortcut to OK? */
+ if (toupper(key) == okButton) {
+ if (ditems) {
+ if (result && ditems[OK_BUTTON].fire) {
+ int status;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ status = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
+ if (status & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ }
+ }
+ else if (result)
+ strcpy(result, items[(scroll + choice) * 2]);
+ rval = 0;
+ key = ESC; /* Punt! */
+ break;
+ }
+
+ /* Shortcut to cancel? */
+ if (toupper(key) == cancelButton) {
+ if (ditems && result && ditems[CANCEL_BUTTON].fire) {
+ int status;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ status = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]);
+ if (status & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ }
+ rval = 1;
+ key = ESC; /* Run away! */
+ break;
+ }
+
+ /* Check if key pressed matches first character of any item tag in menu */
+ for (i = 0; i < max_choice; i++)
+ if (key < 0x100 && key != ' ' && toupper(key) == toupper(items[(scroll + i) * 2][0]))
+ break;
+
+ if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) || KEY_IS_UP(key) || KEY_IS_DOWN(key)) {
+ if (key >= '1' && key <= MIN('9', '0'+max_choice))
+ i = key - '1';
+ else if (KEY_IS_UP(key)) {
+ if (!choice) {
+ if (scroll) {
+ /* 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, DREF(ditems, scroll), menu_width, tag_x, item_x);
+ scrollok(menu, TRUE);
+ wscrl(menu, -1);
+ scrollok(menu, FALSE);
+ }
+ scroll--;
+ print_item(menu, items[scroll * 2], items[scroll * 2 + 1], 0, TRUE, DREF(ditems, scroll), menu_width, tag_x, item_x);
+ wnoutrefresh(menu);
+ print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, tag_x, cur_x, cur_y);
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice - 1;
+ }
+ else if (KEY_IS_DOWN(key)) {
+ if (choice == max_choice - 1) {
+ if (scroll + choice < item_no - 1) {
+ /* 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, DREF(ditems, scroll + max_choice - 1), menu_width, tag_x, item_x);
+ 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, DREF(ditems, scroll + max_choice - 1), menu_width, tag_x, item_x);
+ wnoutrefresh(menu);
+ print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, tag_x, cur_x, cur_y);
+ 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, DREF(ditems, scroll + choice), menu_width, tag_x, item_x);
+
+ /* Highlight new item */
+ choice = i;
+ print_item(menu, items[(scroll + choice) * 2], items[(scroll + choice) * 2 + 1], choice, TRUE, DREF(ditems, scroll + choice), menu_width, tag_x, item_x);
+ wnoutrefresh(menu);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+
+ switch (key) {
+ case KEY_PPAGE:
+ if (scroll > height - 4) { /* can we go up? */
+ scroll -= (height - 4);
+ } else {
+ scroll = 0;
+ }
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_NPAGE:
+ if (scroll + menu_height >= item_no-1 - menu_height) { /* can we go down a full page? */
+ scroll = item_no - menu_height;
+ if (scroll < 0)
+ scroll = 0;
+ } else {
+ scroll += menu_height;
+ }
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_HOME:
+ scroll = 0;
+ choice = 0;
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_END:
+ scroll = item_no - menu_height;
+ if (scroll < 0)
+ scroll = 0;
+ choice = max_choice - 1;
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_BTAB:
+ case TAB:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ button = !button;
+ if (ditems && result) {
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
+ ok_space = 1;
+ cancel_space = strlen(ditems[OK_BUTTON].prompt) + 6;
+ }
+ else {
+ print_button(dialog, "Cancel", y, x + 14, button);
+ print_button(dialog, " OK ", y, x, !button);
+ ok_space = 3;
+ cancel_space = 15;
+ }
+ if (button)
+ wmove(dialog, y, x+cancel_space);
+ else
+ wmove(dialog, y, x+ok_space);
+ wrefresh(dialog);
+ break;
+
+ case ' ':
+ case '\r':
+ case '\n':
+ if (!button) {
+ /* A fire routine can do just about anything to the screen, so be prepared
+ to accept some hints as to what to do in the aftermath. */
+ if (ditems) {
+ if (ditems[scroll + choice].fire) {
+ int status;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ status = ditems[scroll + choice].fire(&ditems[scroll + choice]);
+ if (status & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ if (status & DITEM_CONTINUE)
+ continue;
+ else if (status & DITEM_LEAVE_MENU) {
+ /* Allow a fire action to take us out of the menu */
+ key = ESC;
+ break;
+ }
+ else if (status & DITEM_RECREATE) {
+ delwin(menu);
+ delwin(dialog);
+ dialog_clear();
+ goto draw;
+ }
+ }
+ }
+ else if (result)
+ strcpy(result, items[(scroll+choice)*2]);
+ }
+ rval = button;
+ key = ESC;
+ break;
+
+ case ESC:
+ rval = -1;
+ break;
+
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+
+ /* save info about menu item position */
+ if (ch)
+ *ch = choice;
+ if (sc)
+ *sc = scroll;
+
+ if (redraw_menu) {
+ for (i = 0; i < max_choice; i++) {
+ print_item(menu, items[(scroll + i) * 2], items[(scroll + i) * 2 + 1], i, i == choice, DREF(ditems, scroll + i), menu_width, tag_x, item_x);
+ }
+ wnoutrefresh(menu);
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, tag_x, cur_x, cur_y);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ redraw_menu = FALSE;
+ }
+ }
+ delwin(menu);
+ delwin(dialog);
+ return rval;
+}
+
+
+/*
+ * Print menu item
+ */
+static void
+print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int choice, int selected, dialogMenuItem *me, int menu_width, int tag_x, int item_x)
+{
+ int i;
+
+ if (tag == NULL)
+ errx(1, "bad parameter to print_item()\n");
+
+ /* 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);
+ waddnstr(win, tag + 1, item_x - tag_x - 3);
+ wmove(win, choice, item_x);
+ wattrset(win, selected ? item_selected_attr : item_attr);
+ waddnstr(win, item, menu_width - item_x - 1);
+ /* If have a selection handler for this, call it */
+ if (me && me->selected) {
+ wrefresh(win);
+ me->selected(me, selected);
+ }
+}
+/* End of print_item() */
diff --git a/gnu/lib/libodialog/msgbox.c b/gnu/lib/libodialog/msgbox.c
new file mode 100644
index 0000000..41d78c8
--- /dev/null
+++ b/gnu/lib/libodialog/msgbox.c
@@ -0,0 +1,346 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dialog.h>
+#include "dialog.priv.h"
+
+
+/* local prototypes */
+static int getnlines(unsigned char *buf);
+static void print_page(WINDOW *win, int height, int width, unsigned char *buf, int startline, int hscroll);
+static void print_perc(WINDOW *win, int y, int x, float p);
+
+
+/*
+ * 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, j, x, y, key = 0;
+ WINDOW *dialog;
+
+ if (height < 0)
+ height = strheight(prompt)+2+2*(!!pause);
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i,j)+4;
+ }
+ if (pause)
+ width = MAX(width,10);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = DialogX ? DialogX : (COLS - width)/2;
+ y = DialogY ? DialogY : (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ exit(1);
+ }
+ 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);
+ wmove(dialog, 1, 2);
+ print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
+
+ 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, ' ');
+ display_helpline(dialog, height-1, width);
+ print_button(dialog, " OK ", height-2, width/2-6, TRUE);
+ wrefresh(dialog);
+ while (key != ESC && key != '\n' && key != ' ' && key != '\r')
+ key = wgetch(dialog);
+ if (key == '\r')
+ key = '\n';
+ }
+ else {
+ key = '\n';
+ wrefresh(dialog);
+ }
+
+ delwin(dialog);
+ return (key == ESC ? -1 : 0);
+}
+/* End of dialog_msgbox() */
+
+int
+dialog_mesgbox(unsigned char *title, unsigned char *prompt, int height, int width)
+/*
+ * Desc: basically the same as dialog_msgbox, but ... can use PGUP, PGDN and
+ * arrowkeys to move around the text and pause is always enabled
+ */
+{
+ int i, j, x, y, key=0;
+ int theight, startline, hscroll, max_lines;
+ WINDOW *dialog;
+
+ if (height < 0)
+ height = strheight(prompt)+2+2;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i,j)+4;
+ }
+ width = MAX(width,10);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* 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);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ exit(1);
+ }
+ 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, 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, ' ');
+ display_helpline(dialog, height-1, width);
+ print_button(dialog, " OK ", height-2, width/2-6, TRUE);
+ wattrset(dialog, dialog_attr);
+
+ theight = height - 4;
+ startline = 0;
+ hscroll = 0;
+ max_lines = getnlines(prompt);
+ print_page(dialog, theight, width, prompt, startline, hscroll);
+ print_perc(dialog, height-3, width-9, (float) (startline+theight)/max_lines);
+ wmove(dialog, height-2, width/2-3);
+ wrefresh(dialog);
+ while ((key != ESC) && (key != '\n') && (key != '\r') && (key != ' ')) {
+ key = wgetch(dialog);
+ switch(key) {
+ case KEY_HOME:
+ startline=0;
+ hscroll=0;
+ break;
+ case KEY_END:
+ startline = max_lines - theight;
+ if (startline < 0) startline = 0;
+ break;
+ case '\020': /* ^P */
+ case KEY_UP:
+ if (startline > 0) startline--;
+ break;
+ case '\016': /* ^N */
+ case KEY_DOWN:
+ if (startline < max_lines - theight) startline++;
+ break;
+ case KEY_RIGHT:
+ hscroll+=5;
+ break;
+ case KEY_LEFT:
+ if (hscroll > 0) hscroll-=5;
+ if (hscroll < 0) hscroll =0;
+ break;
+ case KEY_PPAGE:
+ if (startline - height > 0) {
+ startline -= theight;
+ } else {
+ startline = 0;
+ }
+ break;
+ case KEY_NPAGE:
+ if (startline + theight < max_lines - theight) {
+ startline += theight;
+ } else {
+ startline = max_lines - theight;
+ if (startline < 0) startline = 0;
+ }
+ break;
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+ print_page(dialog, theight, width, prompt, startline, hscroll);
+ print_perc(dialog, height-3, width-9, (float) (startline+theight)/max_lines);
+ wmove(dialog, height-2, width/2-3);
+ wrefresh(dialog);
+ }
+
+ delwin(dialog);
+ return (key == ESC ? -1 : 0);
+
+} /* dialog_mesgbox() */
+
+static void
+print_perc(WINDOW *win, int y, int x, float p)
+/*
+ * Desc: print p as a percentage at the coordinates (y,x)
+ */
+{
+ char ps[10];
+
+ if (p>1.0) p=1.0;
+ sprintf(ps, "(%3d%%)", (int) (p*100));
+ wmove(win, y, x);
+ waddstr(win, ps);
+
+ return;
+} /* print_perc() */
+
+static int
+getnlines(unsigned char *buf)
+/*
+ * Desc: count the # of lines in <buf>
+ */
+{
+ int i = 0;
+
+ if (*buf)
+ i++;
+ while (*buf) {
+ if (*buf == '\n' || *buf == '\r')
+ i++;
+ buf++;
+ }
+ return(i);
+} /* getlines() */
+
+
+unsigned char *
+getline(unsigned char *buf, int n)
+/*
+ * Desc: return a pointer to the n'th line in <buf> or NULL if its
+ * not there
+ */
+{
+ int i;
+
+ if (n<0) {
+ return(NULL);
+ }
+
+ i=0;
+ while (*buf && i<n) {
+ if (*buf == '\n' || *buf == '\r') {
+ i++;
+ }
+ buf++;
+ }
+ if (i<n) {
+ return(NULL);
+ } else {
+ return(buf);
+ }
+} /* getline() */
+
+static void
+print_page(WINDOW *win, int height, int width, unsigned char *buf, int startline, int hscroll)
+/*
+ * Desc: Print a page of text in the current window, starting at line <startline>
+ * with a <horizontal> scroll of hscroll from buffer <buf>
+ */
+{
+ int i, j;
+ unsigned char *b;
+
+ b = getline(buf, startline);
+ for (i=0; i<height; i++) {
+ /* clear line */
+ wmove(win, 1+i, 1);
+ for (j=0; j<width-2; j++) waddnstr(win, " ", 1);
+ wmove(win, 1+i, 1);
+ j = 0;
+ /* scroll to the right */
+ while (*b && (*b != '\n') && (*b != '\r') && (j<hscroll)) {
+ b++;
+ j++;
+ }
+ /* print new line */
+ j = 0;
+ while (*b && (*b != '\n') && (*b != '\r') && (j<width-2)) {
+ waddnstr(win, b, 1);
+ if (*b != '\t') { /* check for tabs */
+ j++;
+ } else {
+ j = ((int) (j+1)/8 + 1) * 8 - 1;
+ }
+ b++;
+ }
+ while (*b && (*b != '\n') && (*b != '\r')) b++;
+ if (*b) b++; /* skip over '\n', if it exists */
+ }
+} /* print_page() */
+
+
+
+
diff --git a/gnu/lib/libodialog/notify.c b/gnu/lib/libodialog/notify.c
new file mode 100644
index 0000000..7fc22eb
--- /dev/null
+++ b/gnu/lib/libodialog/notify.c
@@ -0,0 +1,53 @@
+/*
+ * File: notify.c
+ * Author: Marc van Kempen
+ * Desc: display a notify box with a message
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dialog.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void
+dialog_notify(char *msg)
+/*
+ * Desc: display an error message
+ */
+{
+ char *tmphlp;
+ WINDOW *w;
+
+ w = dupwin(newscr);
+ if (w == NULL) {
+ endwin();
+ fprintf(stderr, "\ndupwin(newscr) failed, malloc memory corrupted\n");
+ exit(1);
+ }
+ tmphlp = get_helpline();
+ use_helpline("Press enter or space");
+ dialog_mesgbox("Message", msg, -1, -1);
+ restore_helpline(tmphlp);
+ touchwin(w);
+ wrefresh(w);
+ delwin(w);
+
+ return;
+
+} /* dialog_notify() */
+
diff --git a/gnu/lib/libodialog/prgbox.c b/gnu/lib/libodialog/prgbox.c
new file mode 100644
index 0000000..bcafacf
--- /dev/null
+++ b/gnu/lib/libodialog/prgbox.c
@@ -0,0 +1,152 @@
+/*
+ * prgbox.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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+#include <dialog.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include "dialog.priv.h"
+
+/*
+ * Display a message box. Program will pause and display an "OK" button
+ * if the parameter 'pause' is non-zero.
+ */
+int dialog_prgbox(unsigned char *title, const unsigned char *line, int height, int width, int pause, int use_shell)
+{
+ int i, x, y, key = 0;
+ WINDOW *dialog;
+ FILE *f;
+ const unsigned char *name;
+ unsigned char *s, buf[MAX_LEN];
+ int status;
+
+ if (height < 0 || width < 0) {
+ endwin();
+ fprintf(stderr, "\nAutosizing is impossible in dialog_prgbox().\n");
+ exit(-1);
+ }
+ width = MAX(width,10);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = DialogX ? DialogX : (COLS - width)/2;
+ y = DialogY ? DialogY : (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ exit(1);
+ }
+ 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);
+ wmove(dialog, 1, 2);
+
+ if (!use_shell) {
+ char cmdline[MAX_LEN];
+ char *av[51], **ap = av, *val, *p;
+
+ strcpy(cmdline, line);
+ p = cmdline;
+ while ((val = strsep(&p," \t")) != NULL) {
+ if (*val != '\0')
+ *ap++ = val;
+ }
+ *ap = NULL;
+ f = raw_popen(name = av[0], av, "r");
+ } else
+ f = raw_popen(name = line, NULL, "r");
+
+ status = -1;
+ if (f == NULL) {
+ err:
+ sprintf(buf, "%s: %s\n", name, strerror(errno));
+ prr:
+ print_autowrap(dialog, buf, height-(pause?3:1), width-2, width, 1, 2, FALSE, TRUE);
+ wrefresh(dialog);
+ } else {
+ while (fgets(buf, sizeof(buf), f) != NULL) {
+ i = strlen(buf);
+ if (buf[i-1] == '\n')
+ buf[i-1] = '\0';
+ s = buf;
+ while ((s = strchr(s, '\t')) != NULL)
+ *s++ = ' ';
+ print_autowrap(dialog, buf, height-(pause?3:1), width-2, width, 1, 2, FALSE, TRUE);
+ print_autowrap(dialog, "\n", height-(pause?3:1), width-2, width, 1, 2, FALSE, FALSE);
+ wrefresh(dialog);
+ }
+ if ((status = raw_pclose(f)) == -1)
+ goto err;
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 127) {
+ sprintf(buf, "%s: program not found\n", name);
+ goto prr;
+ }
+ }
+
+ 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, ' ');
+ display_helpline(dialog, height-1, width);
+ print_button(dialog, " OK ", height-2, width/2-6, TRUE);
+ wrefresh(dialog);
+ while (key != ESC && key != '\n' && key != ' ' && key != '\r')
+ key = wgetch(dialog);
+ if (key == '\r')
+ key = '\n';
+ }
+ else {
+ key = '\n';
+ wrefresh(dialog);
+ }
+
+ delwin(dialog);
+ return (status);
+}
+/* End of dialog_msgbox() */
diff --git a/gnu/lib/libodialog/radiolist.c b/gnu/lib/libodialog/radiolist.c
new file mode 100644
index 0000000..4b865a6
--- /dev/null
+++ b/gnu/lib/libodialog/radiolist.c
@@ -0,0 +1,628 @@
+/*
+ * radiolist.c -- implements the radiolist box
+ *
+ * AUTHOR: Stuart Herbert - S.Herbert@sheffield.ac.uk
+ * (from checklist.c by Savio Lam (lam836@cs.cuhk.hk))
+ *
+ * Substantial rennovation: 12/18/95, Jordan K. Hubbard
+ *
+ * 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/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dialog.h>
+#include "dialog.priv.h"
+
+
+static void print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected, dialogMenuItem *me);
+
+#define DREF(di, item) ((di) ? &((di)[(item)]) : NULL)
+
+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(unsigned char *title, unsigned char *prompt, int height, int width, int list_height,
+ int cnt, void *it, unsigned char *result)
+{
+ int i, j, x, y, cur_x, cur_y, old_x, old_y, box_x, box_y, key = 0, button,
+ choice, l, k, scroll, max_choice, *status, item_no = 0, was_on = 0;
+ int redraw_menu = FALSE, cursor_reset = FALSE;
+ int rval = 0, onlist = 1, ok_space, cancel_space;
+ char okButton, cancelButton;
+ WINDOW *dialog, *list;
+ unsigned char **items = NULL;
+ dialogMenuItem *ditems;
+
+ /* Allocate space for storing item on/off status */
+ if ((status = alloca(sizeof(int) * abs(cnt))) == NULL) {
+ endwin();
+ fprintf(stderr, "\nCan't allocate memory in dialog_radiolist().\n");
+ exit(-1);
+ }
+
+draw:
+ button = choice = scroll = 0;
+ /* Previous calling syntax, e.g. just a list of strings? */
+ if (cnt >= 0) {
+ items = it;
+ ditems = NULL;
+ item_no = cnt;
+ /* Initializes status */
+ for (i = 0; i < item_no; i++) {
+ status[i] = !strcasecmp(items[i*3 + 2], "on");
+ if (status[i]) {
+ if (was_on)
+ status[i] = FALSE;
+ else
+ was_on = 1;
+ }
+ }
+ }
+ /* It's the new specification format - fake the rest of the code out */
+ else {
+ item_no = abs(cnt);
+ ditems = it;
+ if (!items)
+ items = (unsigned char **)alloca((item_no * 3) * sizeof(unsigned char *));
+ /* Initializes status */
+ for (i = 0; i < item_no; i++) {
+ status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
+ if (status[i]) {
+ if (was_on)
+ status[i] = FALSE;
+ else
+ was_on = 1;
+ }
+ items[i*3] = ditems[i].prompt;
+ items[i*3 + 1] = ditems[i].title;
+ items[i*3 + 2] = status[i] ? "on" : "off";
+ }
+ }
+ max_choice = MIN(list_height, item_no);
+
+ check_x = 0;
+ item_x = 0;
+ /* Find length of longest item in order to center radiolist */
+ for (i = 0; i < item_no; i++) {
+ l = strlen(items[i * 3]);
+ for (j = 0; j < item_no; j++) {
+ k = strlen(items[j * 3 + 1]);
+ check_x = MAX(check_x, l + k + 6);
+ }
+ item_x = MAX(item_x, l);
+ }
+ if (height < 0)
+ height = strheight(prompt) + list_height + 4 + 2;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i, j);
+ width = MAX(width, check_x + 4) + 4;
+ }
+ width = MAX(width, 24);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = DialogX ? DialogX : (COLS - width) / 2;
+ y = DialogY ? DialogY : (LINES - height) / 2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height, width, y, x);
+ return -1;
+ }
+ 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);
+ wmove(dialog, 1, 2);
+ print_autowrap(dialog, prompt, height - 1, width - 2, width, 1, 2, TRUE, FALSE);
+
+ 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);
+ if (list == NULL) {
+ delwin(dialog);
+ endwin();
+ fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", list_height, list_width,
+ y + box_y + 1,x + box_x + 1);
+ return -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 = (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, DREF(ditems, i));
+ wnoutrefresh(list);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+
+ display_helpline(dialog, height-1, width);
+
+ x = width/ 2 - 11;
+ y = height - 2;
+ if (ditems && result) {
+ cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]);
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
+ ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : FALSE);
+ okButton = toupper(ditems[OK_BUTTON].prompt[0]);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
+ ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : TRUE);
+ }
+ else {
+ cancelButton = 'C';
+ print_button(dialog, "Cancel", y, x + 14, FALSE);
+ okButton = 'O';
+ print_button(dialog, " OK ", y, x, TRUE);
+ }
+ wnoutrefresh(dialog);
+ wmove(list, choice, check_x+1);
+ wrefresh(list);
+
+ while (key != ESC) {
+ key = wgetch(dialog);
+
+ /* See if its the short-cut to "OK" */
+ if (toupper(key) == okButton) {
+ if (ditems) {
+ if (result && ditems[OK_BUTTON].fire) {
+ int st;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ st = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ }
+ }
+ else if (result) {
+ *result = '\0';
+ for (i = 0; i < item_no; i++) {
+ if (status[i]) {
+ strcat(result, items[i*3]);
+ break;
+ }
+ }
+ }
+ rval = 0;
+ key = ESC;
+ break;
+ }
+
+ /* Shortcut to cancel */
+ if (toupper(key) == cancelButton) {
+ if (ditems && result && ditems[CANCEL_BUTTON].fire) {
+ int st;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ st = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ }
+ rval = 1;
+ key = ESC;
+ break;
+ }
+
+ /* Check if key pressed matches first character of any item tag in list */
+ for (i = 0; i < max_choice; i++)
+ if (key != ' ' && toupper(key) == toupper(items[(scroll + i) * 3][0]))
+ break;
+
+ if (i < max_choice || (key >= '1' && key <= MIN('9', '0' + max_choice)) ||
+ KEY_IS_UP(key) || KEY_IS_DOWN(key) || ((key == ' ' || key == '\r' || key == '\n') && onlist == 1)) {
+
+ /* if moving from buttons to the list, reset and redraw buttons */
+ if (!onlist) {
+ onlist = 1;
+ button = 0;
+
+ if (ditems && result ) {
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
+ ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
+ ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
+ }
+ else {
+ print_button(dialog, "Cancel", y, x + 14, button);
+ print_button(dialog, " OK ", y, x, !button);
+ }
+ }
+ wmove(list, choice, check_x+1);
+ wnoutrefresh(dialog);
+ wrefresh(list);
+
+ if (key >= '1' && key <= MIN('9', '0' + max_choice))
+ i = key - '1';
+ else if (KEY_IS_UP(key)) {
+ if (!choice) {
+ if (scroll) {
+ /* 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, DREF(ditems, scroll));
+ scrollok(list, TRUE);
+ wscrl(list, -1);
+ scrollok(list, FALSE);
+ }
+ scroll--;
+ print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0,
+ TRUE, DREF(ditems, scroll));
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+ wmove(list, choice, check_x+1);
+ wnoutrefresh(dialog);
+ wrefresh(list);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice - 1;
+ }
+ else if (KEY_IS_DOWN(key)) {
+ if (choice == max_choice - 1) {
+ if (scroll + choice < item_no - 1) {
+ /* 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, DREF(ditems, scroll + max_choice - 1));
+ 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, DREF(ditems, scroll + max_choice - 1));
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+ wmove(list, choice, check_x+1);
+ wnoutrefresh(dialog);
+ wrefresh(list);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice + 1;
+ }
+ else if ((key == ' ' || key == '\r' || key == '\n') && onlist) { /* Toggle item status */
+ getyx(list, old_y, old_x); /* Save cursor position */
+ if (status[scroll + choice])
+ continue;
+ else if (ditems) {
+ if (ditems[scroll + choice].fire) {
+ int st;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ st = ditems[scroll + choice].fire(&ditems[scroll + choice]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ if (st & DITEM_REDRAW) {
+ wclear(list);
+ for (i = 0; i < item_no; i++)
+ status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
+
+ 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,
+ DREF(ditems, scroll + i));
+ }
+/* wmove(list, old_y, old_x);*/ /* Restore cursor to previous position */
+/* wrefresh(list); */
+ }
+ if (st & DITEM_LEAVE_MENU) {
+ /* Allow a fire action to take us out of the menu */
+ key = ESC;
+ break;
+ }
+ else if (st & DITEM_RECREATE) {
+ delwin(list);
+ delwin(dialog);
+ dialog_clear();
+ goto draw;
+ }
+ }
+ for (i = 0; i < item_no; i++)
+ status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
+ }
+ else {
+ for (i = 0; i < item_no; i++)
+ status[i] = 0;
+ status[scroll + choice] = TRUE;
+ }
+ 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, DREF(ditems, scroll + i));
+ wmove(list, choice, check_x+1); /* Restore cursor position */
+ wrefresh(list);
+ continue; /* wait for another key press */
+ }
+
+ if (i != choice) {
+ /* De-highlight current item */
+ print_item(list, items[(scroll + choice) * 3], items[(scroll + choice) * 3 +1],
+ status[scroll + choice], choice, FALSE, DREF(ditems, scroll + choice));
+ /* Highlight new item */
+ choice = i;
+ print_item(list, items[(scroll + choice) * 3], items[(scroll + choice) * 3 + 1],
+ status[scroll + choice], choice, TRUE, DREF(ditems, scroll + choice));
+ wmove(list, choice, check_x+1); /* Restore cursor position */
+ wrefresh(list);
+ }
+ continue; /* wait for another key press */
+ }
+
+ switch (key) {
+ case KEY_PPAGE:
+ if (scroll > height-4) /* can we go up? */
+ scroll -= (height-4);
+ else
+ scroll = 0;
+ redraw_menu = TRUE;
+ if (!onlist) {
+ onlist = 1;
+ button = 0;
+ }
+ break;
+
+ case KEY_NPAGE:
+ if (scroll + list_height >= item_no-1 - list_height) { /* can we go down a full page? */
+ scroll = item_no - list_height;
+ if (scroll < 0)
+ scroll = 0;
+ }
+ else
+ scroll += list_height;
+ redraw_menu = TRUE;
+ if (!onlist) {
+ onlist = 1;
+ button = 0;
+ }
+ break;
+
+ case KEY_HOME:
+ scroll = 0;
+ choice = 0;
+ redraw_menu = TRUE;
+ cursor_reset = TRUE;
+ onlist = 1;
+ break;
+
+ case KEY_END:
+ scroll = item_no - list_height;
+ if (scroll < 0)
+ scroll = 0;
+ choice = max_choice - 1;
+ redraw_menu = TRUE;
+ cursor_reset = TRUE;
+ onlist = 1;
+ break;
+
+ case TAB:
+ case KEY_BTAB:
+ /* move to next component */
+ if (onlist) { /* on list, next is ok button */
+ onlist = 0;
+ if (ditems && result)
+ ok_space = 1;
+ else
+ ok_space = 3;
+ wmove(dialog, y, x + ok_space);
+ wrefresh(dialog);
+ break;
+ }
+ else if (button) { /* on cancel button, next is list */
+ button = 0;
+ onlist = 1;
+ redraw_menu = TRUE;
+ break;
+ }
+ /* on ok button, next is cancel button, same as left/right case */
+
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ onlist = 0;
+ button = !button;
+ if (ditems && result) {
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
+ ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
+ ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
+ ok_space = 1;
+ cancel_space = strlen(ditems[OK_BUTTON].prompt) + 6;
+ }
+ else {
+ print_button(dialog, "Cancel", y, x + 14, button);
+ print_button(dialog, " OK ", y, x, !button);
+ ok_space = 3;
+ cancel_space = 15;
+ }
+ if (button)
+ wmove(dialog, y, x + cancel_space);
+ else
+ wmove(dialog, y, x + ok_space);
+ wrefresh(dialog);
+ break;
+
+ case ' ':
+ case '\r':
+ case '\n':
+ if (!onlist) {
+ if (ditems) {
+ if (result && ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire) {
+ int st;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ st = ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ }
+ }
+ else if (result) {
+ *result = '\0';
+ for (i = 0; i < item_no; i++) {
+ if (status[i]) {
+ strcpy(result, items[i*3]);
+ break;
+ }
+ }
+ }
+ rval = button;
+ key = ESC;
+ break;
+ }
+
+ case ESC:
+ rval = -1;
+ break;
+
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+
+ if (redraw_menu) {
+ getyx(list, old_y, old_x);
+ wclear(list);
+ 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, DREF(ditems, scroll + i));
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+
+ /* redraw buttons to fix highlighting */
+ if (ditems && result) {
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
+ ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
+ ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
+ }
+ else {
+ print_button(dialog, "Cancel", y, x + 14, button);
+ print_button(dialog, " OK ", y, x, !button);
+ }
+ wnoutrefresh(dialog);
+ if (cursor_reset) {
+ wmove(list, choice, check_x+1);
+ cursor_reset = FALSE;
+ }
+ else {
+ wmove(list, old_y, old_x);
+ }
+ wrefresh(list);
+ redraw_menu = FALSE;
+ }
+ }
+
+ delwin(list);
+ delwin(dialog);
+ return rval; /* ESC pressed */
+}
+
+/*
+ * Print list item
+ */
+static void
+print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected, dialogMenuItem *me)
+{
+ 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%c%c", me && me->lbra ? me->lbra : '(',
+ status ? me && me->mark ? me->mark : '*' : ' ',
+ me && me->rbra ? me->rbra : ')');
+ 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);
+ /* If have a selection handler for this, call it */
+ if (me && me->selected) {
+ wrefresh(win);
+ me->selected(me, selected);
+ }
+}
+/* End of print_item() */
diff --git a/gnu/lib/libodialog/raw_popen.c b/gnu/lib/libodialog/raw_popen.c
new file mode 100644
index 0000000..163c09a
--- /dev/null
+++ b/gnu/lib/libodialog/raw_popen.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software written by Ken Arnold and
+ * published in UNIX Review, Vol. 6, No. 8.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)popen.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/wait.h>
+
+#include <signal.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <paths.h>
+
+static struct pid {
+ struct pid *next;
+ FILE *fp;
+ pid_t pid;
+} *pidlist;
+
+FILE *
+raw_popen(const char *program, char * const *argv, const char *type)
+{
+ struct pid *cur;
+ FILE *iop;
+ int pdes[2], pid;
+
+ if ((*type != 'r' && *type != 'w') || type[1])
+ return (NULL);
+
+ if ((cur = malloc(sizeof(struct pid))) == NULL)
+ return (NULL);
+
+ if (pipe(pdes) < 0) {
+ (void)free(cur);
+ return (NULL);
+ }
+
+ switch (pid = vfork()) {
+ case -1: /* Error. */
+ (void)close(pdes[0]);
+ (void)close(pdes[1]);
+ (void)free(cur);
+ return (NULL);
+ /* NOTREACHED */
+ case 0: /* Child. */
+ if (*type == 'r') {
+ if (pdes[1] != STDOUT_FILENO) {
+ (void)dup2(pdes[1], STDOUT_FILENO);
+ (void)close(pdes[1]);
+ }
+ (void) close(pdes[0]);
+ } else {
+ if (pdes[0] != STDIN_FILENO) {
+ (void)dup2(pdes[0], STDIN_FILENO);
+ (void)close(pdes[0]);
+ }
+ (void)close(pdes[1]);
+ }
+ if (argv == NULL)
+ execl(_PATH_BSHELL, "sh", "-c", program, (char *)NULL);
+ else
+ execvp(program, argv);
+ _exit(127);
+ /* NOTREACHED */
+ }
+
+ /* Parent; assume fdopen can't fail. */
+ if (*type == 'r') {
+ iop = fdopen(pdes[0], type);
+ (void)close(pdes[1]);
+ } else {
+ iop = fdopen(pdes[1], type);
+ (void)close(pdes[0]);
+ }
+
+ /* Link into list of file descriptors. */
+ cur->fp = iop;
+ cur->pid = pid;
+ cur->next = pidlist;
+ pidlist = cur;
+
+ return (iop);
+}
+
+/*
+ * pclose --
+ * Pclose returns -1 if stream is not associated with a `popened' command,
+ * if already `pclosed', or waitpid returns an error.
+ */
+int
+raw_pclose(FILE *iop)
+{
+ register struct pid *cur, *last;
+ int omask, pstat;
+ pid_t pid;
+
+ (void)fclose(iop);
+
+ /* Find the appropriate file pointer. */
+ for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
+ if (cur->fp == iop)
+ break;
+ if (cur == NULL)
+ return (-1);
+
+ /* Get the status of the process. */
+ omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
+ do {
+ pid = waitpid(cur->pid, (int *) &pstat, 0);
+ } while (pid == -1 && errno == EINTR);
+ (void)sigsetmask(omask);
+
+ /* Remove the entry from the linked list. */
+ if (last == NULL)
+ pidlist = cur->next;
+ else
+ last->next = cur->next;
+ free(cur);
+
+ return (pid == -1 ? -1 : pstat);
+}
diff --git a/gnu/lib/libodialog/rc.c b/gnu/lib/libodialog/rc.c
new file mode 100644
index 0000000..36631a6
--- /dev/null
+++ b/gnu/lib/libodialog/rc.c
@@ -0,0 +1,375 @@
+/*
+ * rc.c -- routines for processing the configuration file
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <dialog.h>
+#include "dialog.priv.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 dialog_create_rc(unsigned char *filename)
+{
+ int i;
+ FILE *rc_file;
+
+ if ((rc_file = fopen(filename, "wt")) == NULL) {
+ fprintf(stderr, "\nError opening file for writing in create_rc().\n");
+ exit(-1);
+ }
+
+ fprintf(rc_file, "#\
+\n# Run-time configuration file for dialog\
+\n#\
+\n# Automatically generated by \"dialog --create-rc <file>\"\
+\n#\
+\n#\
+\n# Types of values:\
+\n#\
+\n# Number - <number>\
+\n# String - \"string\"\
+\n# Boolean - <ON|OFF>\
+\n# Attribute - (foreground,background,highlight?)\
+\n#\n\n");
+
+ /* Print an entry for each configuration variable */
+ for (i = 0; i < VAR_COUNT; i++) {
+ fprintf(rc_file, "\n# %s\n", vars[i].comment); /* print comment */
+ switch (vars[i].type) {
+ case VAL_INT:
+ fprintf(rc_file, "%s = %d\n", vars[i].name, *((int *) vars[i].var));
+ break;
+ case VAL_STR:
+ fprintf(rc_file, "%s = \"%s\"\n", vars[i].name, (unsigned char *) vars[i].var);
+ break;
+ case VAL_BOOL:
+ fprintf(rc_file, "%s = %s\n", vars[i].name, *((bool *) vars[i].var) ? "ON" : "OFF");
+ break;
+ case VAL_ATTR:
+ fprintf(rc_file, "%s = %s\n", vars[i].name, attr_to_str(((int *) vars[i].var)[0], ((int *) vars[i].var)[1], ((int *) vars[i].var)[2]));
+ break;
+ }
+ }
+
+ fclose(rc_file);
+}
+/* End of create_rc() */
+
+
+/*
+ * Parse the configuration file and set up variables
+ */
+int parse_rc(void)
+{
+ int i, l = 1, parse, fg, bg, hl;
+ unsigned char str[MAX_LEN+1], *var, *value, *tempptr;
+ FILE *rc_file;
+
+ /*
+ *
+ * At start, 'dialog' determines the settings to use as follows:
+ *
+ * a) if environment variable DIALOGRC is set, it's value determines the
+ * name of the configuration file.
+ *
+ * b) if the file in (a) can't be found, use the file $HOME/.dialogrc
+ * as the configuration file.
+ *
+ * c) if the file in (b) can't be found, use compiled in defaults.
+ *
+ */
+
+ if ((tempptr = getenv("DIALOGRC")) != NULL)
+ rc_file = fopen(tempptr, "rt");
+
+ if (tempptr == NULL || rc_file == NULL) { /* step (a) failed? */
+ /* try step (b) */
+ if ((tempptr = getenv("HOME")) == NULL)
+ return 0; /* step (b) failed, use default values */
+
+ if (tempptr[0] == '\0' || lastch(tempptr) == '/')
+ sprintf(str, "%s%s", tempptr, DIALOGRC);
+ else
+ sprintf(str, "%s/%s", tempptr, DIALOGRC);
+
+ if ((rc_file = fopen(str, "rt")) == NULL)
+ return 0; /* step (b) failed, use default values */
+ }
+
+ /* Scan each line and set variables */
+ while (fgets(str, MAX_LEN, rc_file) != NULL) {
+ if (lastch(str) != '\n') { /* ignore rest of file if line too long */
+ fprintf(stderr, "\nParse error: line %d of configuration file too long.\n", l);
+ fclose(rc_file);
+ return -1; /* parse aborted */
+ }
+ else {
+ lastch(str) = '\0';
+ parse = parse_line(str, &var, &value); /* parse current line */
+
+ switch (parse) {
+ case LINE_BLANK: /* ignore blank lines and comments */
+ case LINE_COMMENT:
+ break;
+ case LINE_OK:
+ /* search table for matching config variable name */
+ for (i = 0; i < VAR_COUNT && strcmp(vars[i].name, var); i++);
+
+ if (i == VAR_COUNT) { /* no match */
+ fprintf(stderr, "\nParse error: unknown variable at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ else { /* variable found in table, set run time variables */
+ switch (vars[i].type) {
+ case VAL_INT:
+ *((int *) vars[i].var) = atoi(value);
+ break;
+ case VAL_STR:
+ if (!isquote(value[0]) || !isquote(lastch(value)) || strlen(value) < 2) {
+ fprintf(stderr, "\nParse error: string value expected at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ else {
+ /* remove the (") quotes */
+ value++;
+ lastch(value) = '\0';
+ strcpy((unsigned char *) vars[i].var, value);
+ }
+ break;
+ case VAL_BOOL:
+ if (!strcasecmp(value, "ON"))
+ *((bool *) vars[i].var) = TRUE;
+ else if (!strcasecmp(value, "OFF"))
+ *((bool *) vars[i].var) = FALSE;
+ else {
+ fprintf(stderr, "\nParse error: boolean value expected at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ break;
+ case VAL_ATTR:
+ if (str_to_attr(value, &fg, &bg, &hl) == -1) {
+ fprintf(stderr, "\nParse error: attribute value expected at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ ((int *) vars[i].var)[0] = fg;
+ ((int *) vars[i].var)[1] = bg;
+ ((int *) vars[i].var)[2] = hl;
+ break;
+ }
+ }
+ break;
+ case LINE_ERROR:
+ fprintf(stderr, "\nParse error: syntax error at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ }
+
+ l++; /* next line */
+ }
+
+ fclose(rc_file);
+ return 0; /* parse successful */
+}
+/* End of parse_rc() */
+
+
+/*
+ * Convert an attribute to a string representation like this:
+ *
+ * "(foreground,background,highlight)"
+ */
+static unsigned char *attr_to_str(int fg, int bg, int hl)
+{
+ int i;
+ static unsigned char str[MAX_LEN+1];
+
+ strcpy(str, "(");
+ /* foreground */
+ for (i = 0; fg != color_names[i].value; i++);
+ strcat(str, color_names[i].name);
+ strcat(str, ",");
+
+ /* background */
+ for (i = 0; bg != color_names[i].value; i++);
+ strcat(str, color_names[i].name);
+
+ /* highlight */
+ strcat(str, hl ? ",ON)" : ",OFF)");
+
+ return str;
+}
+/* End of attr_to_str() */
+
+
+/*
+ * Extract the foreground, background and highlight values from an attribute
+ * represented as a string in this form:
+ *
+ * "(foreground,background,highlight)"
+ */
+static int str_to_attr(unsigned char *str, int *fg, int *bg, int *hl)
+{
+ int i = 0, j, get_fg = 1;
+ unsigned char tempstr[MAX_LEN+1], *part;
+
+ if (str[0] != '(' || lastch(str) != ')')
+ return -1; /* invalid representation */
+
+ /* remove the parenthesis */
+ strcpy(tempstr, str + 1);
+ lastch(tempstr) = '\0';
+
+
+ /* get foreground and background */
+
+ while (1) {
+ /* skip white space before fg/bg string */
+ while (whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
+ if (tempstr[i] == '\0')
+ return -1; /* invalid representation */
+ part = tempstr + i; /* set 'part' to start of fg/bg string */
+
+ /* find end of fg/bg string */
+ while(!whitespace(tempstr[i]) && tempstr[i] != ',' && tempstr[i] != '\0') i++;
+
+ if (tempstr[i] == '\0')
+ return -1; /* invalid representation */
+ else if (whitespace(tempstr[i])) { /* not yet ',' */
+ tempstr[i++] = '\0';
+
+ /* skip white space before ',' */
+ while(whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
+
+ if (tempstr[i] != ',')
+ return -1; /* invalid representation */
+ }
+
+ tempstr[i++] = '\0'; /* skip the ',' */
+ for (j = 0; j < COLOR_COUNT && strcasecmp(part, color_names[j].name); j++);
+ if (j == COLOR_COUNT) /* invalid color name */
+ return -1;
+ if (get_fg) {
+ *fg = color_names[j].value;
+ get_fg = 0; /* next we have to get the background */
+ }
+ else {
+ *bg = color_names[j].value;
+ break;
+ }
+ } /* got foreground and background */
+
+
+ /* get highlight */
+
+ /* skip white space before highlight string */
+ while (whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
+ if (tempstr[i] == '\0')
+ return -1; /* invalid representation */
+ part = tempstr + i; /* set 'part' to start of highlight string */
+
+ /* trim trailing white space from highlight string */
+ i = strlen(part) - 1;
+ while(whitespace(part[i])) i--;
+ part[i+1] = '\0';
+
+ if (!strcasecmp(part, "ON"))
+ *hl = TRUE;
+ else if (!strcasecmp(part, "OFF"))
+ *hl = FALSE;
+ else
+ return -1; /* invalid highlight value */
+
+ return 0;
+}
+/* End of str_to_attr() */
+
+
+/*
+ * Parse a line in the configuration file
+ *
+ * Each line is of the form: "variable = value". On exit, 'var' will contain
+ * the variable name, and 'value' will contain the value string.
+ *
+ * Return values:
+ *
+ * LINE_BLANK - line is blank
+ * LINE_COMMENT - line is comment
+ * LINE_OK - line is ok
+ * LINE_ERROR - syntax error in line
+ */
+static int parse_line(unsigned char *line, unsigned char **var, unsigned char **value)
+{
+ int i = 0;
+
+ /* ignore white space at beginning of line */
+ while(whitespace(line[i]) && line[i] != '\0') i++;
+
+ if (line[i] == '\0') /* line is blank */
+ return LINE_BLANK;
+ else if (line[i] == '#') /* line is comment */
+ return LINE_COMMENT;
+ else if (line[i] == '=') /* variables names can't strart with a '=' */
+ return LINE_ERROR;
+
+ /* set 'var' to variable name */
+ *var = line + i++; /* skip to next character */
+
+ /* find end of variable name */
+ while(!whitespace(line[i]) && line[i] != '=' && line[i] != '\0') i++;
+
+ if (line[i] == '\0') /* syntax error */
+ return LINE_ERROR;
+ else if (line[i] == '=')
+ line[i++] = '\0';
+ else {
+ line[i++] = '\0';
+
+ /* skip white space before '=' */
+ while(whitespace(line[i]) && line[i] != '\0') i++;
+
+ if (line[i] != '=') /* syntax error */
+ return LINE_ERROR;
+ else
+ i++; /* skip the '=' */
+ }
+
+ /* skip white space after '=' */
+ while(whitespace(line[i]) && line[i] != '\0') i++;
+
+ if (line[i] == '\0')
+ return LINE_ERROR;
+ else
+ *value = line + i; /* set 'value' to value string */
+
+ /* trim trailing white space from 'value' */
+ i = strlen(*value) - 1;
+ while(whitespace((*value)[i])) i--;
+ (*value)[i+1] = '\0';
+
+ return LINE_OK; /* no syntax error in line */
+}
+/* End of parse_line() */
diff --git a/gnu/lib/libodialog/rc.h b/gnu/lib/libodialog/rc.h
new file mode 100644
index 0000000..fc19d03
--- /dev/null
+++ b/gnu/lib/libodialog/rc.h
@@ -0,0 +1,222 @@
+/*
+ * 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
+ */
+int parse_rc(void);
diff --git a/gnu/lib/libodialog/textbox.c b/gnu/lib/libodialog/textbox.c
new file mode 100644
index 0000000..19a13bb
--- /dev/null
+++ b/gnu/lib/libodialog/textbox.c
@@ -0,0 +1,699 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dialog.h>
+#include "dialog.priv.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;
+
+ if (height < 0 || width < 0) {
+ fprintf(stderr, "\nAutosizing is impossible in dialog_textbox().\n");
+ return(-1);
+ }
+
+ search_term[0] = '\0'; /* no search term entered yet */
+
+ /* Open input file for reading */
+ if ((fd = open(file, O_RDONLY)) == -1) {
+ fprintf(stderr, "\nCan't open input file <%s>in dialog_textbox().\n", file);
+ return(-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) {
+ fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
+ return(-1);
+ }
+ /* Restore file pointer to beginning of file after getting file size */
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ return(-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) {
+ fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+ return(-1);
+ }
+ buf[bytes_read] = '\0'; /* mark end of valid data */
+ page = buf; /* page is pointer to start of page to be displayed */
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = DialogX ? DialogX : (COLS - width)/2;
+ y = DialogY ? DialogY : (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ exit(1);
+ }
+ 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);
+ if (text == NULL) {
+ endwin();
+ fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", height-4,width-2,y+1,x+1);
+ exit(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, ' ');
+ }
+ display_helpline(dialog, height-1, width);
+
+ print_button(dialog, " OK ", height-2, width/2-6, 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 != '\r') && (key != ' ')) {
+ 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 '\020': /* ^P */
+ 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 '\016': /* ^N */
+ 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 'F': /* Next page */
+ case 'f':
+ 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;
+ case KEY_F(1):
+ display_helpfile();
+ break;
+ }
+ }
+
+ delwin(dialog);
+ free(buf);
+ close(fd);
+ return (key == ESC ? -1 : 0);
+}
+/* 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 x, y, key = 0, first,
+ 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 ");
+ wattrset(win, dialog_attr);
+
+ search_term[0] = '\0';
+
+ first = 1;
+ while (key != ESC) {
+ key = line_edit(win, y+1, x+1, -1, box_width-2, searchbox_attr, first, search_term, 0);
+ first = 0;
+ switch (key) {
+ case '\n':
+ if (search_term[0] != '\0')
+ return 0;
+ break;
+ case ESC:
+ break;
+ }
+ }
+
+ return -1; /* ESC pressed */
+}
+/* End of get_search_term() */
+
+
+/*
+ * Print current position
+ */
+static void print_position(WINDOW *win, int height, int width)
+{
+ int fpos, percent;
+
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in print_position().\n");
+ exit(-1);
+ }
+ wattrset(win, position_indicator_attr);
+ percent = !file_size ? 100 : ((fpos-bytes_read+page-buf)*100)/file_size;
+ wmove(win, height-3, width-9);
+ wprintw(win, "(%3d%%)", percent);
+}
+/* End of print_position() */
diff --git a/gnu/lib/libodialog/tree.c b/gnu/lib/libodialog/tree.c
new file mode 100644
index 0000000..ceacf05
--- /dev/null
+++ b/gnu/lib/libodialog/tree.c
@@ -0,0 +1,1133 @@
+/*
+ * tree.c -- implements the 'tree' interface element for libdialog
+ *
+ * Author: Anatoly A. Orehovsky (tolik@mpeks.tomsk.su)
+ *
+ * Copyright (c) 1997, Anatoly A. Orehovsky
+ * 09/28/98 - patched by Anatoly A. Orehovsky (smart_tree())
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdlib.h>
+#include <strings.h>
+#include <stdio.h>
+#include <dialog.h>
+#include "dialog.priv.h"
+#include <ncurses.h>
+
+/* static utils for make tree */
+struct leaf {
+ unsigned char *name; /* name of leaf */
+ unsigned char *branches; /* branches that going by leaf */
+ unsigned char slip; /* slip of leaf*/
+ int shift; /* shift relative root of tree */
+};
+
+static int mk_slip(struct leaf array[], int arr_size,
+ int number, int shift);
+
+/* make tree from file
+ *
+ * filename - name of file with like find(1) output
+ * p_names - pointer to array of strings
+ * p_size - pointer to size of array
+ * FS - fields separator
+ * p_array - pointer to array of leafs
+ *
+ * return values:
+ * 0 - ok and names by p_names, size by p_size, array by p_array set
+ * -1 - memory allocation error (errno set)
+ */
+
+static int mk_ftree(char *filename,
+ unsigned char ***p_names, int *p_size, unsigned char FS,
+ struct leaf **p_array);
+
+/* make tree from array
+ *
+ * names - array of strings
+ * size - size of array
+ * FS - fields separator
+ * p_array - pointer to array of leafs
+ *
+ * return values:
+ * 0 - ok and array by p_array set
+ * -1 - memory allocation error (errno set)
+ */
+
+static int mk_tree(unsigned char **names, int size, unsigned char FS,
+ struct leaf **p_array);
+
+/* free memory from tree (leafs)
+ *
+ * return values:
+ * nothing
+ */
+
+static void free_leafs(struct leaf *array, int size);
+
+/* free memory from source data for tree (names)
+ *
+ * return values:
+ * if 0 <= choice <= size - pointer to name from names,
+ * and memory for name not released (must be freed later)
+ * else - NULL (recomended choice -1 for it)
+ */
+
+static unsigned char *free_names(unsigned char **names,
+ int size, int choice);
+
+/* end of static utils for make tree */
+
+/* static utils for ftree */
+
+/* control struct for queue */
+struct queue {
+ int size; /* size of queue */
+ struct m_queue *first; /* begin of queue */
+ struct m_queue *last; /* end of queue */
+};
+
+/* queue member */
+struct m_queue {
+ void *pointer; /* queue member */
+ struct m_queue *next; /* next queue member */
+};
+
+/* init struct queue by zeros */
+static void init_queue(struct queue *queue);
+
+/* add pointer to queue */
+/* return - pointer or NULL if error */
+static void *p2_queue(struct queue *queue, void *pointer);
+
+/* get first from queue */
+/* return - pointer or NULL if queue is empty */
+static void *first_queue(struct queue *queue);
+
+/* make zero terminated array from queue */
+/* return - pointer to array or NULL if error */
+static void **q2arr(struct queue *queue, int depth);
+
+/* smart_tree (for like find(1) with -d flag output compliance) */
+/* return - not NULL or NULL if malloc error */
+static unsigned char *smart_tree(struct queue *queue, unsigned char FS,
+ unsigned char *current,
+ unsigned char *prev);
+
+/* end of static utils for ftree */
+
+/* static utils for saved_tree */
+
+/* saved values for unique tree */
+struct saved_tree {
+ unsigned char **names; /* names + */
+ int size; /* size + */
+ unsigned char FS; /* FS + */
+ int height; /* height + */
+ int width; /* width + */
+ int menu_height; /* menu_height - unique for treebox ? */
+ int ch; /* saved ch - choice */
+ int sc; /* saved sc - scroll */
+};
+
+/* search saved tree within queue */
+/* return - struct saved_tree * or NULL if not found */
+static struct saved_tree *search_saved_tree(struct queue *queue,
+ unsigned char **names,
+ int size,
+ unsigned char FS,
+ int height,
+ int width,
+ int menu_height);
+
+/* end of static utils for saved_tree */
+
+static void print_item(WINDOW *win, struct leaf item, int choice, int selected);
+
+static void print_position(WINDOW *win, int x, int y,
+ int cur_pos, int size);
+
+static int menu_width, item_x;
+
+static int dialog_treemenu(unsigned char *title, unsigned char *prompt,
+ int height, int width, int menu_height,
+ int item_no, struct leaf items[],
+ int *result,
+ int *ch, int *sc);
+
+/*
+ * Display a menu for choosing among a number of options
+ */
+static
+int dialog_treemenu(unsigned char *title, unsigned char *prompt,
+ int height, int width, int menu_height,
+ int item_no, struct leaf items[],
+ int *result,
+ int *ch, int *sc)
+{
+ int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
+ l, scroll = 0, max_choice, redraw_menu = FALSE;
+ WINDOW *dialog, *menu;
+
+ if (ch) /* restore menu item info */
+ choice = *ch;
+ if (sc)
+ scroll = *sc;
+
+ max_choice = MIN(menu_height, item_no);
+
+ item_x = 0;
+ /* Find length of longest item in order to center menu */
+ for (i = 0; i < item_no; i++) {
+ l = strlen(items[i].name) + strlen(items[i].branches) * 4 + 4;
+ item_x = MAX(item_x, l);
+ }
+
+ if (height < 0)
+ height = strheight(prompt)+menu_height+4+2;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i,j);
+ width = MAX(width,item_x+4)+4;
+ }
+ width = MAX(width,24);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* 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);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ exit(1);
+ }
+ 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);
+ wmove(dialog, 1, 2);
+ print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
+
+ 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);
+ if (menu == NULL) {
+ endwin();
+ fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", menu_height,menu_width,y+box_y+1,x+box_x+1);
+ exit(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);
+
+ item_x = 1;
+
+ /* Print the menu */
+ for (i = 0; i < max_choice; i++)
+ print_item(menu, items[(scroll+i)], i, i == choice);
+ wnoutrefresh(menu);
+ print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, item_x, cur_x, cur_y);
+ print_position(dialog, box_x+menu_width, box_y+menu_height, scroll+choice, item_no);
+
+ display_helpline(dialog, height-1, width);
+
+ 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 */
+
+ if (key == KEY_UP || key == KEY_DOWN || key == '-' || key == '+') {
+ 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)], 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], 0, FALSE);
+ scrollok(menu, TRUE);
+ wscrl(menu, -1);
+ scrollok(menu, FALSE);
+ }
+ scroll--;
+ print_item(menu, items[scroll], 0, TRUE);
+#endif
+ wnoutrefresh(menu);
+ print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, item_x, cur_x, cur_y);
+ print_position(dialog, box_x+menu_width, box_y+menu_height, scroll+choice, item_no);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous 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)], 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)], max_choice-1, FALSE);
+ scrollok(menu, TRUE);
+ scroll(menu);
+ scrollok(menu, FALSE);
+ }
+ scroll++;
+ print_item(menu, items[(scroll+max_choice-1)], max_choice-1, TRUE);
+#endif
+ wnoutrefresh(menu);
+ print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, item_x, cur_x, cur_y);
+ print_position(dialog, box_x+menu_width, box_y+menu_height, scroll+choice, item_no);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous 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)], choice, FALSE);
+
+ /* Highlight new item */
+ choice = i;
+ print_item(menu, items[(scroll+choice)], choice, TRUE);
+ wnoutrefresh(menu);
+ print_position(dialog, box_x+menu_width, box_y+menu_height, scroll+choice, item_no);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+
+ /* save info about menu item position */
+ if (ch)
+ *ch = choice;
+ if (sc)
+ *sc = scroll;
+
+ switch (key) {
+ case KEY_PPAGE:
+ case 'B' :
+ case 'b' :
+ if (scroll > menu_height) { /* can we go up? */
+ scroll -= (menu_height);
+ } else {
+ scroll = 0;
+ }
+ redraw_menu = TRUE;
+ break;
+ case KEY_NPAGE:
+ case 'F' :
+ case 'f' :
+ if (scroll + menu_height >= item_no-1 - menu_height) { /* can we go down a full page? */
+ scroll = item_no - menu_height;
+ if (scroll < 0) scroll = 0;
+ } else {
+ scroll += menu_height;
+ }
+ redraw_menu = TRUE;
+ break;
+ case KEY_HOME:
+ case 'g' :
+ scroll = 0;
+ choice = 0;
+ redraw_menu = TRUE;
+ break;
+ case KEY_END:
+ case 'G' :
+ scroll = item_no - menu_height;
+ if (scroll < 0) scroll = 0;
+ choice = max_choice - 1;
+ redraw_menu = TRUE;
+ break;
+ case 'O':
+ case 'o':
+ delwin(dialog);
+ *result = scroll+choice;
+ 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 '\r':
+ case '\n':
+ delwin(dialog);
+ if (!button)
+ *result = scroll+choice;
+ return button;
+ case ESC:
+ break;
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+ if (redraw_menu) {
+ for (i = 0; i < max_choice; i++) {
+ print_item(menu, items[(scroll+i)],
+ i, i == choice);
+ }
+ wnoutrefresh(menu);
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, item_x, cur_x, cur_y);
+ print_position(dialog, box_x+menu_width, box_y+menu_height, scroll+choice, item_no);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ redraw_menu = FALSE;
+ }
+ }
+
+ delwin(dialog);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_treemenu() */
+
+
+/*
+ * Print menu item
+ */
+static void print_item(WINDOW *win, struct leaf item, int choice, int selected)
+{
+ int i, j = menu_width - 2;
+ char *branches = item.branches;
+
+ /* 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, item_x);
+
+ while(*branches && j)
+ {
+ switch (*branches++) {
+ case ' ' : waddch(win, ' ');
+ break;
+ case '|' : waddch(win, ACS_VLINE);
+ }
+
+ j--;
+ i = 3;
+ while(i-- && j)
+ {
+ waddch(win, ' ');
+ j--;
+ }
+ }
+
+ if (j)
+ {
+ switch (item.slip) {
+ case '+' : waddch(win, ACS_LTEE);
+ break;
+ case '`' : waddch(win, ACS_LLCORNER);
+ }
+ j--;
+ }
+
+ i = 3;
+ while(i-- && j)
+ {
+ waddch(win, ACS_HLINE);
+ j--;
+ }
+
+ wattrset(win, selected ? item_selected_attr : item_attr);
+ if (j)
+ waddnstr(win, item.name, j);
+}
+/* End of print_item() */
+
+/*
+ * Print current position
+ */
+static void print_position(WINDOW *win, int x, int y,
+ int cur_pos, int size)
+{
+ int percent;
+
+ wattrset(win, position_indicator_attr);
+ percent = cur_pos == size - 1 ? 100 : (cur_pos * 100)/(size - 1);
+ wmove(win, y + 1, x - 6);
+ wprintw(win, "(%3d%%)", percent);
+}
+/* End of print_position() */
+
+/*
+ * Display a tree menu from file
+ *
+ * filename - file with like find(1) output
+ * FS - fields separator
+ * title - title of dialog box
+ * prompt - prompt text into dialog box
+ * height - height of dialog box
+ * width - width of dialog box
+ * menu_height - height of menu box
+ * result - pointer to char array
+ *
+ * return values:
+ * -1 - ESC pressed
+ * 0 - Ok, result set (must be freed later)
+ * 1 - Cancel
+ */
+
+int dialog_ftree(unsigned char *filename, unsigned char FS,
+ unsigned char *title, unsigned char *prompt,
+ int height, int width, int menu_height,
+ unsigned char **result)
+{
+ int retcode, choice, size;
+ struct leaf *items;
+ unsigned char **names;
+
+ if (mk_ftree(filename, &names, &size, FS, &items))
+ {
+ perror("dialog_ftree");
+ end_dialog();
+ exit(-1);
+ }
+
+ if (!size)
+ {
+ fprintf(stderr, "\ndialog_ftree: file %s is empty\n", filename);
+ end_dialog();
+ exit(-1);
+ }
+
+ retcode = dialog_treemenu(title, prompt, height, width, menu_height,
+ size, items, &choice, NULL, NULL);
+
+ free_leafs(items, size);
+
+ if (!retcode)
+ *result = free_names(names, size, choice);
+ else
+ (void)free_names(names, size, -1);
+
+ return retcode;
+}
+/* End of dialog_ftree() */
+
+/*
+ * Display a tree menu from array
+ *
+ * names - array with like find(1) output
+ * size - size of array
+ * FS - fields separator
+ * title - title of dialog box
+ * prompt - prompt text into dialog box
+ * height - height of dialog box
+ * width - width of dialog box
+ * menu_height - height of menu box
+ * result - pointer to char array
+ *
+ * return values:
+ * -1 - ESC pressed
+ * 0 - Ok, result set
+ * 1 - Cancel
+ */
+
+int dialog_tree(unsigned char **names, int size, unsigned char FS,
+ unsigned char *title, unsigned char *prompt,
+ int height, int width, int menu_height,
+ unsigned char **result)
+{
+ int retcode, choice;
+ struct leaf *items;
+ struct saved_tree *st;
+ static struct queue *q_saved_tree = NULL;
+
+ if (!size)
+ {
+ fprintf(stderr, "\ndialog_tree: source array is empty\n");
+ end_dialog();
+ exit(-1);
+ }
+
+ if (mk_tree(names, size, FS, &items))
+ {
+ perror("dialog_tree");
+ end_dialog();
+ exit(-1);
+ }
+
+/* is tree saved ? */
+ if (!(st = search_saved_tree(q_saved_tree, names,
+ size, FS,
+ height, width, menu_height))) {
+ if (!q_saved_tree) {
+ if (!(q_saved_tree =
+ calloc(sizeof (struct queue), 1))) {
+ perror("dialog_tree");
+ end_dialog();
+ exit(-1);
+ }
+ }
+
+ if (!(st = calloc(sizeof (struct saved_tree), 1))) {
+ perror("dialog_tree");
+ end_dialog();
+ exit(-1);
+ }
+
+ st->names = names;
+ st->size = size;
+ st->FS = FS;
+ st->height = height;
+ st->width = width;
+ st->menu_height = menu_height;
+
+ if (!p2_queue(q_saved_tree, st)) {
+ perror("dialog_tree");
+ end_dialog();
+ exit(-1);
+ }
+ }
+
+ retcode = dialog_treemenu(title, prompt, height, width, menu_height,
+ size, items, &choice,
+ &(st->ch), &(st->sc));
+
+ free_leafs(items, size);
+
+ if (!retcode)
+ *result = names[choice];
+
+ return retcode;
+}
+/* End of dialog_tree() */
+
+/* utils for ftree */
+
+/* init struct queue by zeros */
+static void
+init_queue(struct queue *queue)
+{
+ bzero((void *)queue, sizeof(struct queue));
+}
+
+/* add pointer to queue */
+/* return - pointer or NULL if error */
+static void *
+p2_queue(struct queue *queue, void *pointer)
+{
+ if (!queue)
+ return NULL;
+
+ if (!queue->first)
+ {
+ if (!(queue->first = queue->last =
+ calloc(1, sizeof(struct m_queue))))
+ return NULL;
+
+ }
+ else
+ {
+ if (!(queue->last->next =
+ calloc(1, sizeof(struct m_queue))))
+ return NULL;
+
+ queue->last = queue->last->next;
+ }
+
+ queue->size++;
+ return queue->last->pointer = pointer;
+}
+
+/* get first from queue */
+/* return - pointer or NULL if queue is empty */
+static void *
+first_queue(struct queue *queue)
+{
+ void *retval;
+ struct m_queue *new_first;
+
+ if (!queue ||
+ !queue->first ||
+ !queue->size)
+ return NULL;
+
+ retval = queue->first->pointer;
+ new_first = queue->first->next;
+ free(queue->first);
+ queue->first = new_first;
+ queue->size--;
+
+ return retval;
+
+}
+
+/* make zero terminated array from queue */
+/* return - pointer to array or NULL if error */
+static void **
+q2arr(struct queue *queue, int depth)
+{
+ void **mono, **end;
+
+ if (!queue ||
+ !queue->first ||
+ !queue->size)
+ return NULL;
+
+ /* memory allocation for array */
+ if (!(mono = end = malloc(depth * sizeof(void *) + 1)))
+ return NULL;
+
+ while(depth--)
+ {
+ if (!(*end++ = first_queue(queue)))
+ break;
+ }
+
+ *end = NULL;
+
+ return mono;
+
+}
+
+/*
+ * smart_tree (for like find(1) with -d flag output compliance)
+ *
+ * return values:
+ * NULL - malloc error
+ * not NULL - ok
+ *
+ */
+static
+unsigned char *
+smart_tree(struct queue *queue,
+ unsigned char FS,
+ unsigned char *current,
+ unsigned char *prev) {
+ unsigned char *pcurrent = current, *pprev = prev, *toqueue;
+ register char break_flag = 0;
+
+ while(*pcurrent && *pprev) {
+ if (*pcurrent == *pprev) {
+ pcurrent++;
+ pprev++;
+ }
+ else {
+ break_flag = 1;
+ break;
+ }
+ }
+
+ if (!*pprev || break_flag) {
+ if (*pcurrent == FS) {
+ pcurrent++;
+
+ if ((!*prev) && (*pcurrent)) {
+ unsigned char tchar = *pcurrent;
+
+ *pcurrent = '\0';
+ if (!(toqueue = strdup(current))) {
+ *pcurrent = tchar;
+ return NULL;
+ }
+ if (!p2_queue(queue, toqueue)) {
+ *pcurrent = tchar;
+ return NULL;
+ }
+ *pcurrent = tchar;
+ }
+ }
+
+ while(*pcurrent) {
+ if (*pcurrent == FS) {
+ *pcurrent = '\0';
+ if (!(toqueue = strdup(current))) {
+ *pcurrent = FS;
+ return NULL;
+ }
+ if (!p2_queue(queue, toqueue)) {
+ *pcurrent = FS;
+ return NULL;
+ }
+ *pcurrent = FS;
+ }
+ pcurrent++;
+ }
+ if (!p2_queue(queue, current))
+ return NULL;
+ }
+ return current;
+}
+
+/* end of utils for ftree */
+
+/* utils for make tree */
+
+/* if error - return -1 */
+static
+int
+mk_slip(struct leaf array[], int arr_size, int number, int shift)
+{
+ int t_number;
+ int t_shift;
+
+ if (number > arr_size - 1)
+ return number - 1;
+
+ t_shift = shift;
+
+ if (!(array[number].branches = calloc(1, t_shift + 1)))
+ return -1;
+
+ (void)memset(array[number].branches, ' ', t_shift);
+
+ t_number = number;
+
+ while (array[number].shift < array[t_number + 1].shift)
+ {
+ t_number = mk_slip(array, arr_size, t_number + 1, t_shift + 1);
+ if (t_number < 0)
+ return -1;
+ if (t_number == arr_size - 1)
+ break;
+ }
+
+ if (array[number].shift == array[t_number + 1].shift)
+ array[number].slip = '+';
+
+ if ((array[number].shift > array[t_number + 1].shift) ||
+ t_number == arr_size - 1)
+ array[number].slip = '`';
+
+ return t_number;
+
+} /* mk_slip() */
+
+/* make tree from file
+ *
+ * filename - name of file with like find(1) output
+ * p_names - pointer to array of strings
+ * p_size - pointer to size of array
+ * FS - fields separator
+ * p_array - pointer to array of leafs
+ *
+ * return values:
+ * 0 - ok and names by p_names, size by p_size, array by p_array set
+ * -1 - memory allocation error (errno set)
+ */
+
+static
+int
+mk_ftree(char *filename,
+ unsigned char ***p_names, int *p_size, unsigned char FS,
+ struct leaf **p_array)
+{
+ int NR; /* number of input records */
+ struct queue queue;
+ unsigned char *string, *sstring = "";
+ unsigned char **names;
+
+ FILE *input_file;
+
+ if (!(input_file = fopen(filename, "r")))
+ return -1;
+
+ init_queue(&queue);
+
+ if (!(string = malloc(BUFSIZ)))
+ return -1;
+
+ /* read input file into queue */
+ while(fgets(string, BUFSIZ, input_file))
+ {
+ if (strchr(string, '\n'))
+ *strchr(string, '\n') = '\0';
+
+ if (!(string = realloc(string, strlen(string) + 1)))
+ return -1;
+
+ if (!smart_tree(&queue, FS, string, sstring))
+ return -1;
+ sstring = string;
+
+ if (!(string = malloc(BUFSIZ)))
+ return -1;
+ } /* read input file into queue */
+
+ if (fclose(input_file) == EOF)
+ return -1;
+
+ if (!(NR = queue.size))
+ {
+ *p_size = 0;
+ return 0;
+ }
+
+ /* make array from queue */
+ if (!(names = (unsigned char **)q2arr(&queue, NR)))
+ return -1;
+
+ *p_names = names;
+ *p_size = NR;
+
+ /* make tree from array */
+ return mk_tree(names, NR, FS, p_array);
+
+} /* mk_ftree */
+
+/* make tree from array
+ *
+ * names - array of strings
+ * size - size of array
+ * FS - fields separator
+ * p_array - pointer to array of leafs
+ *
+ * return values:
+ * 0 - ok and array by p_array set
+ * -1 - memory allocation error (errno set)
+ */
+
+static
+int
+mk_tree(unsigned char **names, int size, unsigned char FS,
+ struct leaf **p_array)
+{
+ int i;
+ struct leaf *array;
+
+ /* make array of leafs */
+ if (!(array = calloc(size, sizeof(struct leaf))))
+ return -1;
+
+ /* init leafs */
+ for (i = 0; i < size; i++)
+ {
+ unsigned char *in_string, *name;
+ int shift = 0;
+
+ in_string = name = names[i];
+ while(*in_string)
+ {
+ if (*in_string == FS) {
+ if (!i && !*(in_string + 1))
+ name = in_string;
+ else
+ {
+ shift++;
+ name = in_string + 1;
+ }
+ }
+ in_string++;
+ }
+ array[i].name = name;
+ array[i].shift = shift;
+ array[i].slip = '\0';
+ array[i].branches = NULL;
+ } /* init leafs */
+
+ /* make slips */
+ for (i = 0;i < size; i++)
+ {
+ i = mk_slip(array, size, i, 0);
+ if (i < 0)
+ return -1;
+ } /* make slips */
+
+ /* make branches */
+ for (i = 1;i < size; i++)
+ {
+ unsigned char *src = array[i - 1].branches;
+ unsigned char *dst = array[i].branches;
+
+ while(*src && *dst)
+ *dst++ = *src++;
+
+ if (*dst)
+ switch (array[i - 1].slip) {
+ case '+' : *dst = '|';
+ break;
+ case '`' : *dst = ' ';
+ }
+ } /* make branches */
+
+ *p_array = array;
+ return 0;
+
+} /* mk_tree() */
+
+/* free memory from tree (leafs)
+ *
+ * return values:
+ * nothing
+ */
+
+static
+void
+free_leafs(struct leaf *array, int size)
+{
+ struct leaf *p_array = array;
+
+ while (size--)
+ free(array++->branches);
+
+ free(p_array);
+} /* free_leafs() */
+
+/* free memory from source data for tree (names)
+ *
+ * return values:
+ * if 0 <= choice <= size - pointer to name from names,
+ * and memory for name not released (must be freed later)
+ * else - NULL (recomended choice -1 for it)
+ */
+
+static
+unsigned char *
+free_names(unsigned char **names, int size, int choice)
+{
+ unsigned char *retval = NULL;
+ unsigned char **p_names = names;
+
+ while (size--)
+ {
+ if (!choice--)
+ retval = *names++;
+ else
+ free(*names++);
+ }
+ free(p_names);
+ return retval;
+} /* free_names() */
+
+/* end of utils for make tree */
+
+/* static utils for saved_tree */
+
+/* search saved tree within queue */
+/* return - struct *saved_tree or NULL if not found */
+static
+struct saved_tree *
+search_saved_tree(struct queue *queue, unsigned char **names, int size,
+ unsigned char FS,
+ int height, int width,
+ int menu_height)
+{
+ struct m_queue *member;
+ struct saved_tree *retval;
+
+ if (!queue || !names || !FS ||
+ !height || !width || !menu_height)
+ return NULL;
+
+ if (!(member = queue->first))
+ return NULL;
+
+ while (member->next) {
+ retval = member->pointer;
+ if ((names == retval->names) &&
+ (size == retval->size) &&
+ (FS == retval->FS) &&
+ (height == retval->height) &&
+ (width == retval->width) &&
+ (menu_height == retval->menu_height))
+ return retval;
+ member = member->next;
+ }
+ retval = member->pointer;
+ if ((names == retval->names) &&
+ (size == retval->size) &&
+ (FS == retval->FS) &&
+ (height == retval->height) &&
+ (width == retval->width) &&
+ (menu_height == retval->menu_height))
+ return retval;
+ return NULL;
+}
+
+/* end of static utils for saved_tree */
diff --git a/gnu/lib/libodialog/ui_objects.c b/gnu/lib/libodialog/ui_objects.c
new file mode 100644
index 0000000..dde1513
--- /dev/null
+++ b/gnu/lib/libodialog/ui_objects.c
@@ -0,0 +1,829 @@
+/*
+ * Program: objects.c
+ * Author: Marc van Kempen
+ * Desc: Implementation of UI-objects:
+ * - String input fields
+ * - List selection
+ * - Buttons
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ */
+
+#include <stdlib.h>
+#include <sys/param.h>
+#include <ncurses.h>
+#include <dialog.h>
+#include "dialog.priv.h"
+#include "ui_objects.h"
+
+#define ESC 27
+
+/***********************************************************************
+ *
+ * Obj routines
+ *
+ ***********************************************************************/
+
+void
+AddObj(ComposeObj **Obj, int objtype, void *obj)
+/*
+ * Desc: Add the object <obj> to the list of objects <Obj>
+ */
+{
+ if (*Obj == NULL) {
+ /* Create the root object */
+ *Obj = (ComposeObj *) malloc( sizeof(ComposeObj) );
+ if (!Obj) {
+ printf("AddObj: Error malloc'ing ComposeObj\n");
+ exit(-1);
+ }
+ (*Obj)->objtype = objtype;
+ (*Obj)->obj = obj;
+ (*Obj)->next = NULL;
+ (*Obj)->prev = NULL;
+ } else {
+ ComposeObj *o = *Obj;
+
+ /* create the next object */
+ while (o->next) o = (ComposeObj *) o->next;
+ o->next = (struct ComposeObj *) malloc( sizeof(ComposeObj) );
+ if (!o->next) {
+ printf("AddObj: Error malloc'ing o->next\n");
+ exit(-1);
+ }
+ o->next->objtype = objtype;
+ o->next->obj = obj;
+ o->next->next = NULL;
+ o->next->prev = o;
+ }
+
+ return;
+} /* AddObj() */
+
+void
+FreeObj(ComposeObj *Obj)
+/*
+ * Desc: free the memory occupied by *Obj
+ */
+{
+ ComposeObj *o = Obj;
+
+ o = Obj;
+ while (o) {
+ o = Obj->next;
+ free(Obj);
+ Obj = o;
+ }
+
+ return;
+} /* FreeObj() */
+
+
+int
+ReadObj(ComposeObj *Obj)
+/*
+ * Desc: navigate through the different objects calling their
+ * respective navigation routines as necessary
+ * Pre: Obj != NULL
+ */
+{
+ ComposeObj *o;
+ ComposeObj *last; /* the last object in the list */
+ int ret; /* the return value from the selection routine */
+
+ /* find the last object in the list */
+ last = Obj;
+ while (last->next) last = last->next;
+
+ ret = 0;
+ o = Obj;
+ while ((ret != SEL_BUTTON) && (ret != SEL_ESC)) {
+ switch(o->objtype) {
+ case STRINGOBJ:
+ ret = SelectStringObj((StringObj *) o->obj);
+ break;
+ case LISTOBJ:
+ ret = SelectListObj((ListObj *) o->obj);
+ break;
+ case BUTTONOBJ:
+ ret = SelectButtonObj((ButtonObj *) o->obj);
+ break;
+ }
+ switch(ret) {
+ case KEY_DOWN:
+ case SEL_CR:
+ case SEL_TAB: /* move to the next object in the list */
+ if (o->next != NULL) {
+ o = o->next; /* next object */
+ } else {
+ o = Obj; /* beginning of the list */
+ }
+ break;
+
+ case KEY_UP:
+ case SEL_BACKTAB: /* move to the previous object in the list */
+ if (o->prev != NULL) {
+ o = o->prev; /* previous object */
+ } else {
+ o = last; /* end of the list */
+ }
+ break;
+
+ case KEY_F(1): /* display help_file */
+ case '?':
+ display_helpfile();
+ break;
+ }
+ }
+
+ return(ret);
+
+} /* ReadObj() */
+
+
+int
+PollObj(ComposeObj **Obj)
+{
+ ComposeObj *last; /* the last object in the list */
+ ComposeObj *first; /* the first object in the list */
+ int ret; /* the return value from the selection routine */
+
+ /* find the last object in the list */
+ last = *Obj;
+ while (last->next) last = last->next;
+
+ /* find the first object in the list */
+ first = *Obj;
+ while (first->prev) first = first->prev;
+
+ ret = 0;
+ switch((*Obj)->objtype) {
+ case STRINGOBJ:
+ ret = SelectStringObj((StringObj *) (*Obj)->obj);
+ break;
+ case LISTOBJ:
+ ret = SelectListObj((ListObj *) (*Obj)->obj);
+ break;
+ case BUTTONOBJ:
+ ret = SelectButtonObj((ButtonObj *) (*Obj)->obj);
+ break;
+ }
+ switch(ret) {
+ case KEY_DOWN:
+ case SEL_CR:
+ case SEL_TAB: /* move to the next object in the list */
+ if ((*Obj)->next != NULL) {
+ *Obj = (*Obj)->next; /* next object */
+ } else {
+ *Obj = first; /* beginning of the list */
+ }
+ break;
+
+ case KEY_UP:
+ case SEL_BACKTAB: /* move to the previous object in the list */
+ if ((*Obj)->prev != NULL) {
+ *Obj = (*Obj)->prev; /* previous object */
+ } else {
+ *Obj = last; /* end of the list */
+ }
+ break;
+ }
+
+ return(ret);
+
+} /* PollObj() */
+
+
+void
+DelObj(ComposeObj *Obj)
+/*
+ * Desc: Free all objects
+ */
+{
+ ComposeObj *o;
+
+ o = Obj;
+ while (Obj != NULL) {
+ switch(Obj->objtype) {
+ case STRINGOBJ:
+ DelStringObj((StringObj *) Obj->obj);
+ break;
+ case LISTOBJ:
+ DelListObj((ListObj *) Obj->obj);
+ break;
+ case BUTTONOBJ:
+ DelButtonObj((ButtonObj *) Obj->obj);
+ break;
+ }
+ Obj = Obj->next;
+ }
+
+ FreeObj(o);
+} /* DelObj() */
+
+/***********************************************************************
+ *
+ * StringObj routines
+ *
+ ***********************************************************************/
+
+static void
+outstr(WINDOW *win, char *str, int attrs)
+{
+ if (attrs & DITEM_NO_ECHO) {
+ char *cpy;
+ int n = strlen(str);
+
+ cpy = alloca(n + 1);
+ memset(cpy, '*', n);
+ cpy[n] = '\0';
+ waddstr(win, cpy);
+ }
+ else
+ waddstr(win, str);
+}
+
+void
+RefreshStringObj(StringObj *so)
+/*
+ * Desc: redraw the object
+ */
+{
+ char tmp[512];
+
+ wmove(so->win, so->y, so->x+1);
+ wattrset(so->win, dialog_attr);
+ waddstr(so->win, so->title);
+
+ draw_box(so->win, so->y+1, so->x, 3, so->w, dialog_attr, border_attr);
+ wattrset(so->win, item_attr);
+ wmove(so->win, so->y+2, so->x+1);
+ if (strlen(so->s) > so->w-2) {
+ strncpy(tmp, (char *) so->s + strlen(so->s) - so->w + 2, so->w - 1);
+ outstr(so->win, tmp, so->attr_mask);
+ } else {
+ outstr(so->win, so->s, so->attr_mask);
+ }
+
+ return;
+} /* RefreshStringObj() */
+
+StringObj *
+NewStringObj(WINDOW *win, char *title, char *s, int y, int x, int w, int len)
+/*
+ * Desc: Initialize a new stringobj and return a pointer to it.
+ * Draw the object on the screen at the specified coordinates
+ */
+{
+ StringObj *so;
+
+ /* Initialize a new object */
+ so = (StringObj *) malloc( sizeof(StringObj) );
+ if (!so) {
+ printf("NewStringObj: Error malloc'ing StringObj\n");
+ exit(-1);
+ }
+ so->title = (char *) malloc( strlen(title) + 1);
+ if (!so->title) {
+ printf("NewStringObj: Error malloc'ing so->title\n");
+ exit(-1);
+ }
+ strcpy(so->title, title);
+ so->s = s;
+ strcpy(so->s, s);
+ so->x = x;
+ so->y = y;
+ so->w = w;
+ so->len = len;
+ so->win = win;
+ so->attr_mask = DialogInputAttrs; /* Grossly use a global to avoid changing API */
+
+ /* Draw it on the screen */
+ RefreshStringObj(so);
+
+ return(so);
+} /* NewStringObj() */
+
+int
+SelectStringObj(StringObj *so)
+/*
+ * Desc: get input using the info in <so>
+ */
+{
+ int key;
+ char tmp[so->len+1];
+
+ strcpy(tmp, so->s);
+ key = line_edit(so->win, so->y+2, so->x+1,
+ so->len, so->w-2, inputbox_attr, TRUE, tmp, so->attr_mask);
+ if ((key == '\n') || (key == '\r') || (key == '\t') || key == (KEY_BTAB) ) {
+ strcpy(so->s, tmp);
+ }
+ RefreshStringObj(so);
+ if (key == ESC) {
+ return(SEL_ESC);
+ }
+ if (key == '\t') {
+ return(SEL_TAB);
+ }
+ if ( (key == KEY_BTAB) || (key == KEY_F(2)) ) {
+ return(SEL_BACKTAB);
+ }
+ if ((key == '\n') || (key == '\r')) {
+ return(SEL_CR);
+ }
+ return(key);
+} /* SelectStringObj() */
+
+
+void
+DelStringObj(StringObj *so)
+/*
+ * Desc: Free the space occupied by <so>
+ */
+{
+ free(so->title);
+ free(so);
+
+ return;
+}
+
+/***********************************************************************
+ *
+ * ListObj routines
+ *
+ ***********************************************************************/
+
+void
+DrawNames(ListObj *lo)
+/*
+ * Desc: Just refresh the names, not the surrounding box and title
+ */
+{
+ int i, j, h, x, y;
+ char tmp[MAXPATHLEN];
+
+ x = lo->x + 1;
+ y = lo->y + 2;
+ h = lo->h - 2;
+ for (i=lo->scroll; i<lo->n && i<lo->scroll+h; i++) {
+ wmove(lo->win, y+i-lo->scroll, x);
+ if (lo->seld[i]) {
+ wattrset(lo->win, A_BOLD);
+ } else {
+ wattrset(lo->win, item_attr);
+ }
+ if (strlen(lo->name[i]) > lo->w-2) {
+ strncpy(tmp, lo->name[i], lo->w-2);
+ tmp[lo->w - 2] = 0;
+ waddstr(lo->win, tmp);
+ } else {
+ waddstr(lo->win, lo->name[i]);
+ for (j=strlen(lo->name[i]); j<lo->w-2; j++) waddstr(lo->win, " ");
+ }
+ }
+ wattrset(lo->win, item_attr);
+ while (i<lo->scroll+h) {
+ wmove(lo->win, y+i-lo->scroll, x);
+ for (j=0; j<lo->w-2; j++) waddstr(lo->win, " ");
+ i++;
+ }
+
+ return;
+} /* DrawNames() */
+
+void
+RefreshListObj(ListObj *lo)
+/*
+ * Desc: redraw the list object
+ */
+{
+ char perc[7];
+
+ /* setup the box */
+ wmove(lo->win, lo->y, lo->x+1);
+ wattrset(lo->win, dialog_attr);
+ waddstr(lo->win, lo->title);
+ draw_box(lo->win, lo->y+1, lo->x, lo->h, lo->w, dialog_attr, border_attr);
+
+ /* draw the names */
+ DrawNames(lo);
+
+ /* Draw % indication */
+ sprintf(perc, "(%3d%%)", MIN(100, (int) (100 * (lo->sel+lo->h-2) / MAX(1, lo->n))));
+ wmove(lo->win, lo->y + lo->h, lo->x + lo->w - 8);
+ wattrset(lo->win, dialog_attr);
+ waddstr(lo->win, perc);
+
+
+ return;
+} /* RefreshListObj() */
+
+ListObj *
+NewListObj(WINDOW *win, char *title, char **list, char *listelt, int y, int x,
+ int h, int w, int n)
+/*
+ * Desc: create a listobj, draw it on the screen and return a pointer to it.
+ */
+{
+ ListObj *lo;
+ int i;
+
+ /* Initialize a new object */
+ lo = (ListObj *) malloc( sizeof(ListObj) );
+ if (!lo) {
+ fprintf(stderr, "NewListObj: Error malloc'ing ListObj\n");
+ exit(-1);
+ }
+ lo->title = (char *) malloc( strlen(title) + 1);
+ if (!lo->title) {
+ fprintf(stderr, "NewListObj: Error malloc'ing lo->title\n");
+ exit(-1);
+ }
+ strcpy(lo->title, title);
+ lo->name = list;
+ if (n>0) {
+ lo->seld = (int *) malloc( n * sizeof(int) );
+ if (!lo->seld) {
+ fprintf(stderr, "NewListObj: Error malloc'ing lo->seld\n");
+ exit(-1);
+ }
+ for (i=0; i<n; i++) {
+ lo->seld[i] = FALSE;
+ }
+ } else {
+ lo->seld = NULL;
+ }
+ lo->y = y;
+ lo->x = x;
+ lo->w = w;
+ lo->h = h;
+ lo->n = n;
+ lo->scroll = 0;
+ lo->sel = 0;
+ lo->elt = listelt;
+ lo->win = win;
+
+ /* Draw the object on the screen */
+ RefreshListObj(lo);
+
+ return(lo);
+} /* NewListObj() */
+
+void
+UpdateListObj(ListObj *lo, char **list, int n)
+/*
+ * Desc: Update the list in the listobject with the provided list
+ * Pre: lo->name "has been freed"
+ * "(A i: 0<=i<lo->n: "lo->name[i] has been freed")"
+ */
+{
+ int i;
+
+ if (lo->seld) {
+ free(lo->seld);
+ }
+
+ /* Rewrite the list in the object */
+ lo->name = list;
+ if (n>0) {
+ lo->seld = (int *) malloc( n * sizeof(int) );
+ if (!lo->seld) {
+ fprintf(stderr, "UpdateListObj: Error malloc'ing lo->seld\n");
+ exit(-1);
+ }
+ for (i=0; i<n; i++) {
+ lo->seld[i] = FALSE;
+ }
+ } else {
+ lo->seld = NULL;
+ }
+ lo->n = n;
+ lo->scroll = 0;
+ lo->sel = 0;
+
+ /* Draw the object on the screen */
+ RefreshListObj(lo);
+
+ return;
+} /* UpdateListObj() */
+
+int
+SelectListObj(ListObj *lo)
+/*
+ * Desc: get a listname (or listnames), TAB to move on, or ESC ESC to exit
+ * Pre: lo->n >= 1
+ */
+{
+ int key, sel_x, sel_y, quit;
+ char tmp[MAXPATHLEN];
+ char perc[4];
+
+ sel_x = lo->x+1;
+ sel_y = lo->y + 2 + lo->sel - lo->scroll;
+
+ if (lo->n == 0) return(SEL_TAB);
+
+ keypad(lo->win, TRUE);
+
+ /* Draw current selection in inverse video */
+ wmove(lo->win, sel_y, sel_x);
+ wattrset(lo->win, item_selected_attr);
+ waddstr(lo->win, lo->name[lo->sel]);
+
+ key = wgetch(lo->win);
+ quit = FALSE;
+ while ((key != '\t') && (key != '\n') && (key != '\r')
+ && (key != ESC) && (key != KEY_F(1)) && (key != '?') && !quit) {
+ /* first draw current item in normal video */
+ wmove(lo->win, sel_y, sel_x);
+ if (lo->seld[lo->sel]) {
+ wattrset(lo->win, A_BOLD);
+ } else {
+ wattrset(lo->win, item_attr);
+ }
+ if (strlen(lo->name[lo->sel]) > lo->w - 2) {
+ strncpy(tmp, lo->name[lo->sel], lo->w - 2);
+ tmp[lo->w - 2] = 0;
+ waddstr(lo->win, tmp);
+ } else {
+ waddstr(lo->win, lo->name[lo->sel]);
+ }
+
+ switch (key) {
+ case KEY_DOWN:
+ case ctrl('n'):
+ if (sel_y < lo->y + lo->h-1) {
+ if (lo->sel < lo->n-1) {
+ sel_y++;
+ lo->sel++;
+ }
+ } else {
+ if (lo->sel < lo->n-1) {
+ lo->sel++;
+ lo->scroll++;
+ DrawNames(lo);
+ wrefresh(lo->win);
+ }
+ }
+ break;
+ case KEY_UP:
+ case ctrl('p'):
+ if (sel_y > lo->y+2) {
+ if (lo->sel > 0) {
+ sel_y--;
+ lo->sel--;
+ }
+ } else {
+ if (lo->sel > 0) {
+ lo->sel--;
+ lo->scroll--;
+ DrawNames(lo);
+ wrefresh(lo->win);
+ }
+ }
+ break;
+ case KEY_HOME:
+ case ctrl('a'):
+ lo->sel = 0;
+ lo->scroll = 0;
+ sel_y = lo->y + 2;
+ DrawNames(lo);
+ wrefresh(lo->win);
+ break;
+ case KEY_END:
+ case ctrl('e'):
+ if (lo->n < lo->h - 3) {
+ lo->sel = lo->n-1;
+ lo->scroll = 0;
+ sel_y = lo->y + 2 + lo->sel - lo->scroll;
+ } else {
+ /* more than one page of list */
+ lo->sel = lo->n-1;
+ lo->scroll = lo->n-1 - (lo->h-3);
+ sel_y = lo->y + 2 + lo->sel - lo->scroll;
+ DrawNames(lo);
+ wrefresh(lo->win);
+ }
+ break;
+ case KEY_NPAGE:
+ case ctrl('f'):
+ lo->sel += lo->h - 2;
+ if (lo->sel >= lo->n) lo->sel = lo->n - 1;
+ lo->scroll += lo->h - 2;
+ if (lo->scroll >= lo->n - 1) lo->scroll = lo->n - 1;
+ if (lo->scroll < 0) lo->scroll = 0;
+ sel_y = lo->y + 2 + lo->sel - lo->scroll;
+ DrawNames(lo);
+ wrefresh(lo->win);
+ break;
+ case KEY_PPAGE:
+ case ctrl('b'):
+ lo->sel -= lo->h - 2;
+ if (lo->sel < 0) lo->sel = 0;
+ lo->scroll -= lo->h - 2;
+ if (lo->scroll < 0) lo->scroll = 0;
+ sel_y = lo->y + 2 + lo->sel - lo->scroll;
+ DrawNames(lo);
+ wrefresh(lo->win);
+ break;
+ default:
+ quit = TRUE;
+ break;
+ }
+ /* Draw % indication */
+ sprintf(perc, "(%3d%%)", MIN(100, (int)
+ (100 * (lo->sel+lo->h - 2) / MAX(1, lo->n))));
+ wmove(lo->win, lo->y + lo->h, lo->x + lo->w - 8);
+ wattrset(lo->win, dialog_attr);
+ waddstr(lo->win, perc);
+
+ /* draw current item in inverse */
+ wmove(lo->win, sel_y, sel_x);
+ wattrset(lo->win, item_selected_attr);
+ if (strlen(lo->name[lo->sel]) > lo->w - 2) {
+ /* when printing in inverse video show the last characters in the */
+ /* name that will fit in the window */
+ strncpy(tmp,
+ lo->name[lo->sel] + strlen(lo->name[lo->sel]) - (lo->w - 2),
+ lo->w - 2);
+ tmp[lo->w - 2] = 0;
+ waddstr(lo->win, tmp);
+ } else {
+ waddstr(lo->win, lo->name[lo->sel]);
+ }
+ if (!quit) key = wgetch(lo->win);
+ }
+
+ if (key == ESC) {
+ return(SEL_ESC);
+ }
+ if (key == '\t') {
+ return(SEL_TAB);
+ }
+ if ((key == KEY_BTAB) || (key == ctrl('b'))) {
+ return(SEL_BACKTAB);
+ }
+ if ((key == '\n') || (key == '\r')) {
+ strcpy(lo->elt, lo->name[lo->sel]);
+ return(SEL_CR);
+ }
+ return(key);
+} /* SelectListObj() */
+
+void
+DelListObj(ListObj *lo)
+/*
+ * Desc: Free the space occupied by the listobject
+ */
+{
+ free(lo->title);
+ if (lo->seld != NULL) free(lo->seld);
+ free(lo);
+
+ return;
+} /* DelListObj() */
+
+void
+MarkCurrentListObj(ListObj *lo)
+/*
+ * Desc: mark the current item for the selection list
+ */
+{
+ lo->seld[lo->sel] = !(lo->seld[lo->sel]);
+ DrawNames(lo);
+
+ return;
+} /* MarkCurrentListObj() */
+
+void
+MarkAllListObj(ListObj *lo)
+/*
+ * Desc: mark all items
+ */
+{
+ int i;
+
+ for (i=0; i<lo->n; i++) {
+ lo->seld[i] = TRUE;
+ }
+ DrawNames(lo);
+
+ return;
+} /* MarkAllListObj() */
+
+void
+UnMarkAllListObj(ListObj *lo)
+/*
+ * Desc: unmark all items
+ */
+{
+ int i;
+
+ for (i=0; i<lo->n; i++) {
+ lo->seld[i] = FALSE;
+ }
+ DrawNames(lo);
+
+ return;
+} /* UnMarkAllListObj() */
+
+
+/***********************************************************************
+ *
+ * ButtonObj routines
+ *
+ ***********************************************************************/
+
+
+void
+RefreshButtonObj(ButtonObj *bo)
+/*
+ * Desc: redraw the button
+ */
+{
+ draw_box(bo->win, bo->y, bo->x, 3, bo->w, dialog_attr, border_attr);
+ print_button(bo->win, bo->title, bo->y+1, bo->x+2, FALSE);
+
+ return;
+} /* RefreshButtonObj() */
+
+ButtonObj *
+NewButtonObj(WINDOW *win, char *title, int *pushed, int y, int x)
+/*
+ * Desc: Create a new button object
+ */
+{
+ ButtonObj *bo;
+
+ bo = (ButtonObj *) malloc( sizeof(ButtonObj) );
+
+ bo->win = win;
+ bo->title = (char *) malloc( strlen(title) + 1);
+ strcpy(bo->title, title);
+ bo->x = x;
+ bo->y = y;
+ bo->w = strlen(title) + 6;
+ bo->h = 3;
+ bo->pushed = pushed;
+
+ RefreshButtonObj(bo);
+
+ return(bo);
+} /* NewButtonObj() */
+
+int
+SelectButtonObj(ButtonObj *bo)
+/*
+ * Desc: Wait for buttonpresses or TAB's to move on, or ESC ESC
+ */
+{
+ int key;
+
+ print_button(bo->win, bo->title, bo->y+1, bo->x+2, TRUE);
+ wmove(bo->win, bo->y+1, bo->x+(bo->w/2)-1);
+ key = wgetch(bo->win);
+ print_button(bo->win, bo->title, bo->y+1, bo->x+2, FALSE);
+ switch(key) {
+ case '\t':
+ return(SEL_TAB);
+ break;
+ case KEY_BTAB:
+ case ctrl('b'):
+ return(SEL_BACKTAB);
+ case '\n':
+ case '\r':
+ *(bo->pushed) = TRUE;
+ return(SEL_BUTTON);
+ break;
+ case ESC:
+ return(SEL_ESC);
+ break;
+ default:
+ return(key);
+ break;
+ }
+} /* SelectButtonObj() */
+
+void
+DelButtonObj(ButtonObj *bo)
+/*
+ * Desc: Free the space occupied by <bo>
+ */
+{
+ free(bo->title);
+ free(bo);
+
+ return;
+} /* DelButtonObj() */
diff --git a/gnu/lib/libodialog/ui_objects.h b/gnu/lib/libodialog/ui_objects.h
new file mode 100644
index 0000000..b30feb8
--- /dev/null
+++ b/gnu/lib/libodialog/ui_objects.h
@@ -0,0 +1,114 @@
+/*
+ * Author: Marc van Kempen
+ * Desc: include file for UI-objects
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ */
+
+#include "dialog.h"
+#include <ncurses.h>
+
+/***********************************************************************
+ *
+ * Defines
+ *
+ ***********************************************************************/
+
+#define ctrl(a) ((a) - 'a' + 1)
+
+/* the Object types */
+#define STRINGOBJ 1
+#define LISTOBJ 2
+#define BUTTONOBJ 3
+
+/* the return signals from the selection routines */
+/* 1000 and higher should avoid conflicts with keys pressed */
+#define SEL_CR 1001 /* return was pressed */
+#define SEL_ESC 1002 /* ESC pressed */
+#define SEL_TAB 1003 /* TAB pressed */
+#define SEL_BACKTAB 1004 /* SHIFT-TAB pressed */
+#define SEL_BUTTON 1005 /* a button was pressed */
+
+/***********************************************************************
+ *
+ * Typedefs
+ *
+ ***********************************************************************/
+
+typedef struct {
+ WINDOW *win; /* the window it's contained in */
+ char *title; /* the prompt for the input field */
+ char *s; /* initial value of the input field */
+ int x, y, w, len; /* the (y, x) position of the upperleft */
+ /* corner and the width <w> of the display */
+ /* and length <len> of the field */
+ int attr_mask; /* special attributes */
+} StringObj;
+
+typedef struct {
+ WINDOW *win; /* the windows it's contained in */
+ char *title; /* the title of the list */
+ char **name; /* the names of the list */
+ int *seld; /* the currently selected names */
+ char *elt; /* the current element in the list list[sel] */
+ int x, y, w, h, n; /* dimensions of list and # of elements (n) */
+ int scroll, sel; /* current position in the list */
+} ListObj;
+
+typedef struct {
+ WINDOW *win; /* the window it's contained in */
+ char *title; /* title for the button */
+ int x, y, w, h; /* its dimensions */
+ int *pushed; /* boolean that determines wether button was pushed */
+} ButtonObj;
+
+typedef struct ComposeObj {
+ int objtype;
+ void *obj;
+ struct ComposeObj *next, *prev;
+} ComposeObj;
+
+/**********************************************************************
+ *
+ * Prototypes
+ *
+ **********************************************************************/
+
+void RefreshStringObj(StringObj *so);
+StringObj *NewStringObj(WINDOW *win, char *title, char *s,
+ int y, int x, int w, int len);
+int SelectStringObj(StringObj *so);
+void DelStringObj(StringObj *so);
+
+void RefreshListObj(ListObj *lo);
+ListObj *NewListObj(WINDOW *win, char *title, char **list,
+ char *listelt, int y, int x, int h, int w, int n);
+void UpdateListObj(ListObj *lo, char **list, int n);
+int SelectListObj(ListObj *lo);
+void DelListObj(ListObj *obj);
+void MarkCurrentListObj(ListObj *lo);
+void MarkAllListObj(ListObj *lo);
+void UnMarkAllListObj(ListObj *lo);
+
+void RefreshButtonObj(ButtonObj *bo);
+ButtonObj *NewButtonObj(WINDOW *win, char *title, int *pushed,
+ int y, int x);
+int SelectButtonObj(ButtonObj *bo);
+void DelButtonObj(ButtonObj *bo);
+void AddObj(ComposeObj **Obj, int objtype, void *obj);
+void FreeObj(ComposeObj *Obj);
+int ReadObj(ComposeObj *Obj);
+int PollObj(ComposeObj **Obj);
+void DelObj(ComposeObj *Obj);
+
diff --git a/gnu/lib/libodialog/yesno.c b/gnu/lib/libodialog/yesno.c
new file mode 100644
index 0000000..24eb41a
--- /dev/null
+++ b/gnu/lib/libodialog/yesno.c
@@ -0,0 +1,169 @@
+/*
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dialog.h>
+#include "dialog.priv.h"
+
+/* Actual work function */
+static int dialog_yesno_proc(unsigned char *title, unsigned char *prompt,
+ int height, int width, int yesdefault);
+
+/*
+ * Display a dialog box with two buttons - Yes and No
+ */
+int
+dialog_yesno(unsigned char *title, unsigned char *prompt, int height, int width)
+{
+ return dialog_yesno_proc(title, prompt, height, width, TRUE);
+}
+
+/*
+ * Display a dialog box with two buttons - No and Yes
+ */
+int
+dialog_noyes(unsigned char *title, unsigned char *prompt, int height, int width)
+{
+ return dialog_yesno_proc(title, prompt, height, width, FALSE);
+}
+
+static int
+dialog_yesno_proc(unsigned char *title, unsigned char *prompt, int height, int width, int yesdefault)
+{
+ int i, j, x, y, key, button;
+ WINDOW *dialog;
+ char *tmphlp;
+
+ /* disable helpline */
+ tmphlp = get_helpline();
+ use_helpline(NULL);
+
+ if (height < 0)
+ height = strheight(prompt)+4;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i,j)+4;
+ }
+ width = MAX(width,23);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = DialogX ? DialogX : (COLS - width)/2;
+ y = DialogY ? DialogY : (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ exit(1);
+ }
+ 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);
+ wmove(dialog, 1, 2);
+ print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
+
+ display_helpline(dialog, height-1, width);
+
+ x = width/2-10;
+ y = height-2;
+
+ /* preset button 0 or 1 for YES or NO as the default */
+ key = 0;
+ button = !yesdefault;
+ while (key != ESC) {
+ print_button(dialog, " No ", y, x+13, button);
+ print_button(dialog, " Yes " , y, x, !button);
+ if (button)
+ wmove(dialog, y, x+16);
+ else
+ wmove(dialog, y, x+2);
+ wrefresh(dialog);
+
+ key = wgetch(dialog);
+ switch (key) {
+ case 'Y':
+ case 'y':
+ delwin(dialog);
+ restore_helpline(tmphlp);
+ return 0;
+ case 'N':
+ case 'n':
+ delwin(dialog);
+ restore_helpline(tmphlp);
+ return 1;
+ case KEY_BTAB:
+ case TAB:
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ button = !button;
+ /* redrawn at the loop's entry */
+ break;
+ case ' ':
+ case '\r':
+ case '\n':
+ delwin(dialog);
+ restore_helpline(tmphlp);
+ return button;
+ case ESC:
+ break;
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+ }
+
+ delwin(dialog);
+ restore_helpline(tmphlp);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_yesno() */
OpenPOWER on IntegriCloud