Make all dialog box available from C programs via functions calls
This commit is contained in:
parent
5df7296441
commit
3728ed9c8f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/savio_lam/; revision=3515
339
gnu/lib/libdialog/COPYING
Normal file
339
gnu/lib/libdialog/COPYING
Normal file
@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
17
gnu/lib/libdialog/Makefile
Normal file
17
gnu/lib/libdialog/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
# Makefile for libdialog
|
||||
# $Id: Makefile,v 1.2 1994/10/09 00:46:16 pst Exp $
|
||||
|
||||
LIB= dialog
|
||||
SRCS= kernel.c rc.c checklist.c inputbox.c menubox.c msgbox.c \
|
||||
radiolist.c textbox.c yesno.c
|
||||
|
||||
CFLAGS+= -Wall -Wstrict-prototypes -DHAVE_NCURSES -DLOCALE
|
||||
|
||||
SHARED_LDADD+= -lncurses -lmytinfo
|
||||
|
||||
beforeinstall:
|
||||
-cd ${.CURDIR}; cmp -s dialog.h ${DESTDIR}/usr/include/dialog.h || \
|
||||
install -c -o ${BINOWN} -g ${BINGRP} -m 444 dialog.h \
|
||||
${DESTDIR}/usr/include
|
||||
|
||||
.include <bsd.lib.mk>
|
7
gnu/lib/libdialog/README
Normal file
7
gnu/lib/libdialog/README
Normal file
@ -0,0 +1,7 @@
|
||||
This library splitted out from 'dialog' program for use inside
|
||||
C-programs. For interface function list see dialog.h.
|
||||
For usage examples see 'dialog' program sources itself into
|
||||
/usr/src/gnu/usr.bin/dialog.
|
||||
You can additionly use any ncurses functions after init_dialog().
|
||||
|
||||
Ache.
|
357
gnu/lib/libdialog/checklist.c
Normal file
357
gnu/lib/libdialog/checklist.c
Normal file
@ -0,0 +1,357 @@
|
||||
/*
|
||||
* checklist.c -- implements the checklist box
|
||||
*
|
||||
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "dialog.priv.h"
|
||||
#include <dialog.h>
|
||||
|
||||
|
||||
static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int status, int choice, int selected);
|
||||
|
||||
|
||||
static int list_width, check_x, item_x;
|
||||
|
||||
|
||||
/*
|
||||
* Display a dialog box with a list of options that can be turned on or off
|
||||
*/
|
||||
int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result)
|
||||
{
|
||||
int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
|
||||
scroll = 0, max_choice, *status;
|
||||
WINDOW *dialog, *list;
|
||||
|
||||
/* Allocate space for storing item on/off status */
|
||||
if ((status = malloc(sizeof(int)*item_no)) == NULL) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nCan't allocate memory in dialog_checklist().\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* Initializes status */
|
||||
for (i = 0; i < item_no; i++)
|
||||
status[i] = !strcasecmp(items[i*3 + 2], "on");
|
||||
|
||||
max_choice = MIN(list_height, item_no);
|
||||
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width)/2;
|
||||
y = (LINES - height)/2;
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
if (use_shadow)
|
||||
draw_shadow(stdscr, y, x, height, width);
|
||||
#endif
|
||||
dialog = newwin(height, width, y, x);
|
||||
keypad(dialog, TRUE);
|
||||
|
||||
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
|
||||
wattrset(dialog, border_attr);
|
||||
wmove(dialog, height-3, 0);
|
||||
waddch(dialog, ACS_LTEE);
|
||||
for (i = 0; i < width-2; i++)
|
||||
waddch(dialog, ACS_HLINE);
|
||||
wattrset(dialog, dialog_attr);
|
||||
waddch(dialog, ACS_RTEE);
|
||||
wmove(dialog, height-2, 1);
|
||||
for (i = 0; i < width-2; i++)
|
||||
waddch(dialog, ' ');
|
||||
|
||||
if (title != NULL) {
|
||||
wattrset(dialog, title_attr);
|
||||
wmove(dialog, 0, (width - strlen(title))/2 - 1);
|
||||
waddch(dialog, ' ');
|
||||
waddstr(dialog, title);
|
||||
waddch(dialog, ' ');
|
||||
}
|
||||
wattrset(dialog, dialog_attr);
|
||||
print_autowrap(dialog, prompt, width, 1, 3);
|
||||
|
||||
list_width = width-6;
|
||||
getyx(dialog, cur_y, cur_x);
|
||||
box_y = cur_y + 1;
|
||||
box_x = (width - list_width)/2 - 1;
|
||||
|
||||
/* create new window for the list */
|
||||
list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
|
||||
keypad(list, TRUE);
|
||||
|
||||
/* draw a box around the list items */
|
||||
draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr);
|
||||
|
||||
check_x = 0;
|
||||
item_x = 0;
|
||||
/* Find length of longest item in order to center checklist */
|
||||
for (i = 0; i < item_no; i++) {
|
||||
check_x = MAX(check_x, strlen(items[i*3]) + strlen(items[i*3 + 1]) + 6);
|
||||
item_x = MAX(item_x, strlen(items[i*3]));
|
||||
}
|
||||
check_x = (list_width - check_x) / 2;
|
||||
item_x = check_x + item_x + 6;
|
||||
|
||||
/* Print the list */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(list, items[i*3], items[i*3 + 1], status[i], i, i == choice);
|
||||
wnoutrefresh(list);
|
||||
|
||||
if (list_height < item_no) {
|
||||
wattrset(dialog, darrow_attr);
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
|
||||
waddch(dialog, ACS_DARROW);
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
|
||||
waddstr(dialog, "(+)");
|
||||
}
|
||||
|
||||
x = width/2-11;
|
||||
y = height-2;
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
wrefresh(dialog);
|
||||
|
||||
while (key != ESC) {
|
||||
key = wgetch(dialog);
|
||||
/* Check if key pressed matches first character of any item tag in list */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
if (key < 0x100 && toupper(key) == toupper(items[(scroll+i)*3][0]))
|
||||
break;
|
||||
|
||||
if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) ||
|
||||
key == KEY_UP || key == KEY_DOWN || key == ' ' ||
|
||||
key == '+' || key == '-' ) {
|
||||
if (key >= '1' && key <= MIN('9', '0'+max_choice))
|
||||
i = key - '1';
|
||||
else if (key == KEY_UP || key == '-') {
|
||||
if (!choice) {
|
||||
if (scroll) {
|
||||
#ifdef BROKEN_WSCRL
|
||||
/* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
|
||||
violation when scrolling windows of height = 4, so scrolling is not
|
||||
used for now */
|
||||
scroll--;
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
/* Reprint list to scroll down */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice);
|
||||
|
||||
#else
|
||||
|
||||
/* Scroll list down */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
if (list_height > 1) {
|
||||
/* De-highlight current first item before scrolling down */
|
||||
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, FALSE);
|
||||
scrollok(list, TRUE);
|
||||
wscrl(list, -1);
|
||||
scrollok(list, FALSE);
|
||||
}
|
||||
scroll--;
|
||||
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE);
|
||||
#endif
|
||||
wnoutrefresh(list);
|
||||
|
||||
/* print the up/down arrows */
|
||||
wmove(dialog, box_y, box_x + check_x + 5);
|
||||
wattrset(dialog, scroll ? uarrow_attr : menubox_attr);
|
||||
waddch(dialog, scroll ? ACS_UARROW : ACS_HLINE);
|
||||
wmove(dialog, box_y, box_x + check_x + 6);
|
||||
waddch(dialog, scroll ? '(' : ACS_HLINE);
|
||||
wmove(dialog, box_y, box_x + check_x + 7);
|
||||
waddch(dialog, scroll ? '-' : ACS_HLINE);
|
||||
wmove(dialog, box_y, box_x + check_x + 8);
|
||||
waddch(dialog, scroll ? ')' : ACS_HLINE);
|
||||
wattrset(dialog, darrow_attr);
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
|
||||
waddch(dialog, ACS_DARROW);
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
|
||||
waddch(dialog, '(');
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 7);
|
||||
waddch(dialog, '+');
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 8);
|
||||
waddch(dialog, ')');
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
continue; /* wait for another key press */
|
||||
}
|
||||
else
|
||||
i = choice - 1;
|
||||
}
|
||||
else if (key == KEY_DOWN || key == '+') {
|
||||
if (choice == max_choice - 1) {
|
||||
if (scroll+choice < item_no-1) {
|
||||
#ifdef BROKEN_WSCRL
|
||||
/* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
|
||||
violation when scrolling windows of height = 4, so scrolling is not
|
||||
used for now */
|
||||
scroll++;
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
/* Reprint list to scroll up */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice);
|
||||
|
||||
#else
|
||||
|
||||
/* Scroll list up */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
if (list_height > 1) {
|
||||
/* De-highlight current last item before scrolling up */
|
||||
print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1], status[scroll+max_choice-1], max_choice-1, FALSE);
|
||||
scrollok(list, TRUE);
|
||||
scroll(list);
|
||||
scrollok(list, FALSE);
|
||||
}
|
||||
scroll++;
|
||||
print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1], status[scroll+max_choice-1], max_choice-1, TRUE);
|
||||
#endif
|
||||
wnoutrefresh(list);
|
||||
|
||||
/* print the up/down arrows */
|
||||
wattrset(dialog, uarrow_attr);
|
||||
wmove(dialog, box_y, box_x + check_x + 5);
|
||||
waddch(dialog, ACS_UARROW);
|
||||
wmove(dialog, box_y, box_x + check_x + 6);
|
||||
waddstr(dialog, "(-)");
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
|
||||
wattrset(dialog, scroll+choice < item_no-1 ? darrow_attr : menubox_border_attr);
|
||||
waddch(dialog, scroll+choice < item_no-1 ? ACS_DARROW : ACS_HLINE);
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
|
||||
waddch(dialog, scroll+choice < item_no-1 ? '(' : ACS_HLINE);
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 7);
|
||||
waddch(dialog, scroll+choice < item_no-1 ? '+' : ACS_HLINE);
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 8);
|
||||
waddch(dialog, scroll+choice < item_no-1 ? ')' : ACS_HLINE);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
continue; /* wait for another key press */
|
||||
}
|
||||
else
|
||||
i = choice + 1;
|
||||
}
|
||||
else if (key == ' ') { /* Toggle item status */
|
||||
status[scroll+choice] = !status[scroll+choice];
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
wmove(list, choice, check_x);
|
||||
wattrset(list, check_selected_attr);
|
||||
wprintw(list, "[%c]", status[scroll+choice] ? 'X' : ' ');
|
||||
wnoutrefresh(list);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
|
||||
wrefresh(dialog);
|
||||
continue; /* wait for another key press */
|
||||
}
|
||||
|
||||
if (i != choice) {
|
||||
/* De-highlight current item */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, FALSE);
|
||||
|
||||
/* Highlight new item */
|
||||
choice = i;
|
||||
print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, TRUE);
|
||||
wnoutrefresh(list);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
continue; /* wait for another key press */
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case 'O':
|
||||
case 'o':
|
||||
delwin(dialog);
|
||||
*result = '\0';
|
||||
for (i = 0; i < item_no; i++)
|
||||
if (status[i]) {
|
||||
strcat(result, items[i*3]);
|
||||
strcat(result, "\n");
|
||||
}
|
||||
free(status);
|
||||
return 0;
|
||||
case 'C':
|
||||
case 'c':
|
||||
delwin(dialog);
|
||||
free(status);
|
||||
return 1;
|
||||
case TAB:
|
||||
case KEY_BTAB:
|
||||
case KEY_LEFT:
|
||||
case KEY_RIGHT:
|
||||
if (!button) {
|
||||
button = 1; /* Indicates "Cancel" button is selected */
|
||||
print_button(dialog, " OK ", y, x, FALSE);
|
||||
print_button(dialog, "Cancel", y, x+14, TRUE);
|
||||
}
|
||||
else {
|
||||
button = 0; /* Indicates "OK" button is selected */
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
}
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
case ' ':
|
||||
case '\n':
|
||||
delwin(dialog);
|
||||
if (!button) {
|
||||
*result = '\0';
|
||||
for (i = 0; i < item_no; i++)
|
||||
if (status[i]) {
|
||||
strcat(result, items[i*3]);
|
||||
strcat(result, "\n");
|
||||
}
|
||||
}
|
||||
free(status);
|
||||
return button;
|
||||
case ESC:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delwin(dialog);
|
||||
free(status);
|
||||
return -1; /* ESC pressed */
|
||||
}
|
||||
/* End of dialog_checklist() */
|
||||
|
||||
|
||||
/*
|
||||
* Print list item
|
||||
*/
|
||||
static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int status, int choice, int selected)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Clear 'residue' of last item */
|
||||
wattrset(win, menubox_attr);
|
||||
wmove(win, choice, 0);
|
||||
for (i = 0; i < list_width; i++)
|
||||
waddch(win, ' ');
|
||||
wmove(win, choice, check_x);
|
||||
wattrset(win, selected ? check_selected_attr : check_attr);
|
||||
wprintw(win, "[%c]", status ? 'X' : ' ');
|
||||
wattrset(win, menubox_attr);
|
||||
waddch(win, ' ');
|
||||
wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
|
||||
waddch(win, tag[0]);
|
||||
wattrset(win, selected ? tag_selected_attr : tag_attr);
|
||||
waddstr(win, tag + 1);
|
||||
wmove(win, choice, item_x);
|
||||
wattrset(win, selected ? item_selected_attr : item_attr);
|
||||
waddstr(win, item);
|
||||
}
|
||||
/* End of print_item() */
|
219
gnu/lib/libdialog/colors.h
Normal file
219
gnu/lib/libdialog/colors.h
Normal file
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* colors.h -- color attribute definitions
|
||||
*
|
||||
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Default color definitions
|
||||
*
|
||||
* *_FG = foreground
|
||||
* *_BG = background
|
||||
* *_HL = highlight?
|
||||
*/
|
||||
#define SCREEN_FG COLOR_CYAN
|
||||
#define SCREEN_BG COLOR_BLUE
|
||||
#define SCREEN_HL TRUE
|
||||
|
||||
#define SHADOW_FG COLOR_BLACK
|
||||
#define SHADOW_BG COLOR_BLACK
|
||||
#define SHADOW_HL TRUE
|
||||
|
||||
#define DIALOG_FG COLOR_BLACK
|
||||
#define DIALOG_BG COLOR_WHITE
|
||||
#define DIALOG_HL FALSE
|
||||
|
||||
#define TITLE_FG COLOR_YELLOW
|
||||
#define TITLE_BG COLOR_WHITE
|
||||
#define TITLE_HL TRUE
|
||||
|
||||
#define BORDER_FG COLOR_WHITE
|
||||
#define BORDER_BG COLOR_WHITE
|
||||
#define BORDER_HL TRUE
|
||||
|
||||
#define BUTTON_ACTIVE_FG COLOR_WHITE
|
||||
#define BUTTON_ACTIVE_BG COLOR_BLUE
|
||||
#define BUTTON_ACTIVE_HL TRUE
|
||||
|
||||
#define BUTTON_INACTIVE_FG COLOR_BLACK
|
||||
#define BUTTON_INACTIVE_BG COLOR_WHITE
|
||||
#define BUTTON_INACTIVE_HL FALSE
|
||||
|
||||
#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE
|
||||
#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE
|
||||
#define BUTTON_KEY_ACTIVE_HL TRUE
|
||||
|
||||
#define BUTTON_KEY_INACTIVE_FG COLOR_RED
|
||||
#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE
|
||||
#define BUTTON_KEY_INACTIVE_HL FALSE
|
||||
|
||||
#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW
|
||||
#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE
|
||||
#define BUTTON_LABEL_ACTIVE_HL TRUE
|
||||
|
||||
#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK
|
||||
#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE
|
||||
#define BUTTON_LABEL_INACTIVE_HL TRUE
|
||||
|
||||
#define INPUTBOX_FG COLOR_BLACK
|
||||
#define INPUTBOX_BG COLOR_WHITE
|
||||
#define INPUTBOX_HL FALSE
|
||||
|
||||
#define INPUTBOX_BORDER_FG COLOR_BLACK
|
||||
#define INPUTBOX_BORDER_BG COLOR_WHITE
|
||||
#define INPUTBOX_BORDER_HL FALSE
|
||||
|
||||
#define SEARCHBOX_FG COLOR_BLACK
|
||||
#define SEARCHBOX_BG COLOR_WHITE
|
||||
#define SEARCHBOX_HL FALSE
|
||||
|
||||
#define SEARCHBOX_TITLE_FG COLOR_YELLOW
|
||||
#define SEARCHBOX_TITLE_BG COLOR_WHITE
|
||||
#define SEARCHBOX_TITLE_HL TRUE
|
||||
|
||||
#define SEARCHBOX_BORDER_FG COLOR_WHITE
|
||||
#define SEARCHBOX_BORDER_BG COLOR_WHITE
|
||||
#define SEARCHBOX_BORDER_HL TRUE
|
||||
|
||||
#define POSITION_INDICATOR_FG COLOR_YELLOW
|
||||
#define POSITION_INDICATOR_BG COLOR_WHITE
|
||||
#define POSITION_INDICATOR_HL TRUE
|
||||
|
||||
#define MENUBOX_FG COLOR_BLACK
|
||||
#define MENUBOX_BG COLOR_WHITE
|
||||
#define MENUBOX_HL FALSE
|
||||
|
||||
#define MENUBOX_BORDER_FG COLOR_WHITE
|
||||
#define MENUBOX_BORDER_BG COLOR_WHITE
|
||||
#define MENUBOX_BORDER_HL TRUE
|
||||
|
||||
#define ITEM_FG COLOR_BLACK
|
||||
#define ITEM_BG COLOR_WHITE
|
||||
#define ITEM_HL FALSE
|
||||
|
||||
#define ITEM_SELECTED_FG COLOR_WHITE
|
||||
#define ITEM_SELECTED_BG COLOR_BLUE
|
||||
#define ITEM_SELECTED_HL TRUE
|
||||
|
||||
#define TAG_FG COLOR_YELLOW
|
||||
#define TAG_BG COLOR_WHITE
|
||||
#define TAG_HL TRUE
|
||||
|
||||
#define TAG_SELECTED_FG COLOR_YELLOW
|
||||
#define TAG_SELECTED_BG COLOR_BLUE
|
||||
#define TAG_SELECTED_HL TRUE
|
||||
|
||||
#define TAG_KEY_FG COLOR_RED
|
||||
#define TAG_KEY_BG COLOR_WHITE
|
||||
#define TAG_KEY_HL TRUE
|
||||
|
||||
#define TAG_KEY_SELECTED_FG COLOR_RED
|
||||
#define TAG_KEY_SELECTED_BG COLOR_BLUE
|
||||
#define TAG_KEY_SELECTED_HL TRUE
|
||||
|
||||
#define CHECK_FG COLOR_BLACK
|
||||
#define CHECK_BG COLOR_WHITE
|
||||
#define CHECK_HL FALSE
|
||||
|
||||
#define CHECK_SELECTED_FG COLOR_WHITE
|
||||
#define CHECK_SELECTED_BG COLOR_BLUE
|
||||
#define CHECK_SELECTED_HL TRUE
|
||||
|
||||
#define UARROW_FG COLOR_GREEN
|
||||
#define UARROW_BG COLOR_WHITE
|
||||
#define UARROW_HL TRUE
|
||||
|
||||
#define DARROW_FG COLOR_GREEN
|
||||
#define DARROW_BG COLOR_WHITE
|
||||
#define DARROW_HL TRUE
|
||||
|
||||
/* End of default color definitions */
|
||||
|
||||
#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
|
||||
#define COLOR_NAME_LEN 10
|
||||
#define COLOR_COUNT 8
|
||||
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned char name[COLOR_NAME_LEN];
|
||||
int value;
|
||||
} color_names_st;
|
||||
|
||||
|
||||
#ifdef __DIALOG_MAIN__
|
||||
|
||||
/*
|
||||
* For matching color names with color values
|
||||
*/
|
||||
color_names_st color_names[] = {
|
||||
{"BLACK", COLOR_BLACK},
|
||||
{"RED", COLOR_RED},
|
||||
{"GREEN", COLOR_GREEN},
|
||||
{"YELLOW", COLOR_YELLOW},
|
||||
{"BLUE", COLOR_BLUE},
|
||||
{"MAGENTA", COLOR_MAGENTA},
|
||||
{"CYAN", COLOR_CYAN},
|
||||
{"WHITE", COLOR_WHITE},
|
||||
}; /* color names */
|
||||
|
||||
|
||||
/*
|
||||
* Table of color values
|
||||
*/
|
||||
int color_table[][3] = {
|
||||
{SCREEN_FG, SCREEN_BG, SCREEN_HL },
|
||||
{SHADOW_FG, SHADOW_BG, SHADOW_HL },
|
||||
{DIALOG_FG, DIALOG_BG, DIALOG_HL },
|
||||
{TITLE_FG, TITLE_BG, TITLE_HL },
|
||||
{BORDER_FG, BORDER_BG, BORDER_HL },
|
||||
{BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL },
|
||||
{BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL },
|
||||
{BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL },
|
||||
{BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL },
|
||||
{BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL },
|
||||
{BUTTON_LABEL_INACTIVE_FG,BUTTON_LABEL_INACTIVE_BG,BUTTON_LABEL_INACTIVE_HL},
|
||||
{INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL },
|
||||
{INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL },
|
||||
{SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL },
|
||||
{SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL },
|
||||
{SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL },
|
||||
{POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL },
|
||||
{MENUBOX_FG, MENUBOX_BG, MENUBOX_HL },
|
||||
{MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL },
|
||||
{ITEM_FG, ITEM_BG, ITEM_HL },
|
||||
{ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL },
|
||||
{TAG_FG, TAG_BG, TAG_HL },
|
||||
{TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL },
|
||||
{TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL },
|
||||
{TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL },
|
||||
{CHECK_FG, CHECK_BG, CHECK_HL },
|
||||
{CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL },
|
||||
{UARROW_FG, UARROW_BG, UARROW_HL },
|
||||
{DARROW_FG, DARROW_BG, DARROW_HL },
|
||||
}; /* color_table */
|
||||
|
||||
#else
|
||||
|
||||
extern color_names_st color_names[];
|
||||
extern int color_table[][3];
|
||||
|
||||
#endif /* __DIALOG_MAIN__ */
|
35
gnu/lib/libdialog/dialog.h
Normal file
35
gnu/lib/libdialog/dialog.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define VERSION "0.4"
|
||||
#define MAX_LEN 2048
|
||||
|
||||
void dialog_create_rc(unsigned char *filename);
|
||||
int dialog_yesno(unsigned char *title, unsigned char *prompt, int height, int width);
|
||||
int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int width, int pause);
|
||||
int dialog_textbox(unsigned char *title, unsigned char *file, int height, int width);
|
||||
int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height, int item_no, unsigned char **items, unsigned char *result);
|
||||
int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result);
|
||||
int dialog_radiolist(char *title, char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result);
|
||||
int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int width, unsigned char *result);
|
||||
void dialog_clear(void);
|
||||
void dialog_update(void);
|
||||
void init_dialog(void);
|
||||
void end_dialog(void);
|
218
gnu/lib/libdialog/dialog.priv.h
Normal file
218
gnu/lib/libdialog/dialog.priv.h
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* dialog.h -- common declarations for all dialog modules
|
||||
*
|
||||
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
#include <ncurses.h>
|
||||
|
||||
#else
|
||||
|
||||
#ifdef ultrix
|
||||
#include <cursesX.h>
|
||||
#else
|
||||
#include <curses.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(LOCALE)
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Change these if you want
|
||||
*/
|
||||
#define USE_SHADOW TRUE
|
||||
#define USE_COLORS TRUE
|
||||
|
||||
#define ESC 27
|
||||
#define TAB 9
|
||||
#define BUF_SIZE (10*1024)
|
||||
#define MIN(x,y) (x < y ? x : y)
|
||||
#define MAX(x,y) (x > y ? x : y)
|
||||
|
||||
#ifndef HAVE_NCURSES
|
||||
#ifndef ACS_ULCORNER
|
||||
#define ACS_ULCORNER '+'
|
||||
#endif
|
||||
#ifndef ACS_LLCORNER
|
||||
#define ACS_LLCORNER '+'
|
||||
#endif
|
||||
#ifndef ACS_URCORNER
|
||||
#define ACS_URCORNER '+'
|
||||
#endif
|
||||
#ifndef ACS_LRCORNER
|
||||
#define ACS_LRCORNER '+'
|
||||
#endif
|
||||
#ifndef ACS_HLINE
|
||||
#define ACS_HLINE '-'
|
||||
#endif
|
||||
#ifndef ACS_VLINE
|
||||
#define ACS_VLINE '|'
|
||||
#endif
|
||||
#ifndef ACS_LTEE
|
||||
#define ACS_LTEE '+'
|
||||
#endif
|
||||
#ifndef ACS_RTEE
|
||||
#define ACS_RTEE '+'
|
||||
#endif
|
||||
#ifndef ACS_UARROW
|
||||
#define ACS_UARROW '^'
|
||||
#endif
|
||||
#ifndef ACS_DARROW
|
||||
#define ACS_DARROW 'v'
|
||||
#endif
|
||||
#endif /* HAVE_NCURSES */
|
||||
|
||||
|
||||
/*
|
||||
* Attribute names
|
||||
*/
|
||||
#define screen_attr attributes[0]
|
||||
#define shadow_attr attributes[1]
|
||||
#define dialog_attr attributes[2]
|
||||
#define title_attr attributes[3]
|
||||
#define border_attr attributes[4]
|
||||
#define button_active_attr attributes[5]
|
||||
#define button_inactive_attr attributes[6]
|
||||
#define button_key_active_attr attributes[7]
|
||||
#define button_key_inactive_attr attributes[8]
|
||||
#define button_label_active_attr attributes[9]
|
||||
#define button_label_inactive_attr attributes[10]
|
||||
#define inputbox_attr attributes[11]
|
||||
#define inputbox_border_attr attributes[12]
|
||||
#define searchbox_attr attributes[13]
|
||||
#define searchbox_title_attr attributes[14]
|
||||
#define searchbox_border_attr attributes[15]
|
||||
#define position_indicator_attr attributes[16]
|
||||
#define menubox_attr attributes[17]
|
||||
#define menubox_border_attr attributes[18]
|
||||
#define item_attr attributes[19]
|
||||
#define item_selected_attr attributes[20]
|
||||
#define tag_attr attributes[21]
|
||||
#define tag_selected_attr attributes[22]
|
||||
#define tag_key_attr attributes[23]
|
||||
#define tag_key_selected_attr attributes[24]
|
||||
#define check_attr attributes[25]
|
||||
#define check_selected_attr attributes[26]
|
||||
#define uarrow_attr attributes[27]
|
||||
#define darrow_attr attributes[28]
|
||||
|
||||
/* number of attributes */
|
||||
#define ATTRIBUTE_COUNT 29
|
||||
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
#ifdef __DIALOG_MAIN__
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
|
||||
/* use colors by default? */
|
||||
bool use_colors = USE_COLORS;
|
||||
|
||||
/* shadow dialog boxes by default?
|
||||
Note that 'use_shadow' implies 'use_colors' */
|
||||
bool use_shadow = USE_SHADOW;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Attribute values, default is for mono display
|
||||
*/
|
||||
chtype attributes[] = {
|
||||
A_NORMAL, /* screen_attr */
|
||||
A_NORMAL, /* shadow_attr */
|
||||
A_REVERSE, /* dialog_attr */
|
||||
A_REVERSE, /* title_attr */
|
||||
A_REVERSE, /* border_attr */
|
||||
A_BOLD, /* button_active_attr */
|
||||
A_DIM, /* button_inactive_attr */
|
||||
A_UNDERLINE, /* button_key_active_attr */
|
||||
A_UNDERLINE, /* button_key_inactive_attr */
|
||||
A_NORMAL, /* button_label_active_attr */
|
||||
A_NORMAL, /* button_label_inactive_attr */
|
||||
A_REVERSE, /* inputbox_attr */
|
||||
A_REVERSE, /* inputbox_border_attr */
|
||||
A_REVERSE, /* searchbox_attr */
|
||||
A_REVERSE, /* searchbox_title_attr */
|
||||
A_REVERSE, /* searchbox_border_attr */
|
||||
A_REVERSE, /* position_indicator_attr */
|
||||
A_REVERSE, /* menubox_attr */
|
||||
A_REVERSE, /* menubox_border_attr */
|
||||
A_REVERSE, /* item_attr */
|
||||
A_NORMAL, /* item_selected_attr */
|
||||
A_REVERSE, /* tag_attr */
|
||||
A_REVERSE, /* tag_selected_attr */
|
||||
A_NORMAL, /* tag_key_attr */
|
||||
A_BOLD, /* tag_key_selected_attr */
|
||||
A_REVERSE, /* check_attr */
|
||||
A_REVERSE, /* check_selected_attr */
|
||||
A_REVERSE, /* uarrow_attr */
|
||||
A_REVERSE /* darrow_attr */
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
extern bool use_colors;
|
||||
extern bool use_shadow;
|
||||
#endif
|
||||
|
||||
extern chtype attributes[];
|
||||
|
||||
#endif /* __DIALOG_MAIN__ */
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
*/
|
||||
#ifdef __DIALOG_MAIN__
|
||||
|
||||
extern 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 width, int y, int x);
|
||||
void print_button(WINDOW *win, unsigned char *label, int y, int x, int selected);
|
||||
void draw_box(WINDOW *win, int y, int x, int height, int width, chtype box, chtype border);
|
||||
#ifdef HAVE_NCURSES
|
||||
void draw_shadow(WINDOW *win, int y, int x, int height, int width);
|
||||
#endif
|
||||
|
281
gnu/lib/libdialog/inputbox.c
Normal file
281
gnu/lib/libdialog/inputbox.c
Normal file
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* 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.priv.h"
|
||||
#include <dialog.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, x, y, box_y, box_x, box_width,
|
||||
input_x = 0, scroll = 0, key = 0, button = -1;
|
||||
unsigned char instr[MAX_LEN+1];
|
||||
WINDOW *dialog;
|
||||
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width)/2;
|
||||
y = (LINES - height)/2;
|
||||
|
||||
memset(instr, 0, sizeof(instr));
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
if (use_shadow)
|
||||
draw_shadow(stdscr, y, x, height, width);
|
||||
#endif
|
||||
dialog = newwin(height, width, y, x);
|
||||
keypad(dialog, TRUE);
|
||||
|
||||
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
|
||||
wattrset(dialog, border_attr);
|
||||
wmove(dialog, height-3, 0);
|
||||
waddch(dialog, ACS_LTEE);
|
||||
for (i = 0; i < width-2; i++)
|
||||
waddch(dialog, ACS_HLINE);
|
||||
wattrset(dialog, dialog_attr);
|
||||
waddch(dialog, ACS_RTEE);
|
||||
wmove(dialog, height-2, 1);
|
||||
for (i = 0; i < width-2; i++)
|
||||
waddch(dialog, ' ');
|
||||
|
||||
if (title != NULL) {
|
||||
wattrset(dialog, title_attr);
|
||||
wmove(dialog, 0, (width - strlen(title))/2 - 1);
|
||||
waddch(dialog, ' ');
|
||||
waddstr(dialog, title);
|
||||
waddch(dialog, ' ');
|
||||
}
|
||||
wattrset(dialog, dialog_attr);
|
||||
print_autowrap(dialog, prompt, width, 1, 3);
|
||||
|
||||
/* Draw the input field box */
|
||||
box_width = width-6;
|
||||
getyx(dialog, y, x);
|
||||
box_y = y + 2;
|
||||
box_x = (width - box_width)/2;
|
||||
draw_box(dialog, y+1, box_x-1, 3, box_width+2, border_attr, dialog_attr);
|
||||
|
||||
x = width/2-11;
|
||||
y = height-2;
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
|
||||
wmove(dialog, box_y, box_x);
|
||||
wrefresh(dialog);
|
||||
while (key != ESC) {
|
||||
key = wgetch(dialog);
|
||||
|
||||
if (button == -1) { /* Input box selected */
|
||||
switch (key) {
|
||||
case TAB:
|
||||
case KEY_BTAB:
|
||||
case KEY_UP:
|
||||
case KEY_DOWN:
|
||||
break;
|
||||
case KEY_HOME:
|
||||
input_x = scroll = 0;
|
||||
wmove(dialog, box_y, box_x);
|
||||
for (i = 0; i < box_width; i++)
|
||||
waddch(dialog, instr[i] ? instr[i] : ' ');
|
||||
wmove(dialog, box_y, box_x);
|
||||
wrefresh(dialog);
|
||||
continue;
|
||||
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;
|
||||
wmove(dialog, box_y, box_x);
|
||||
for (i = 0; i < box_width; i++)
|
||||
waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
|
||||
wmove(dialog, box_y, input_x + box_x);
|
||||
wrefresh(dialog);
|
||||
continue;
|
||||
case KEY_LEFT:
|
||||
if (input_x || scroll) {
|
||||
wattrset(dialog, inputbox_attr);
|
||||
if (!input_x) {
|
||||
int oldscroll = scroll;
|
||||
scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
|
||||
wmove(dialog, box_y, box_x);
|
||||
for (i = 0; i < box_width; i++)
|
||||
waddch(dialog, instr[scroll+input_x+i] ? instr[scroll+input_x+i] : ' ');
|
||||
input_x = oldscroll - 1 - scroll;
|
||||
}
|
||||
else
|
||||
input_x--;
|
||||
wmove(dialog, box_y, input_x + box_x);
|
||||
wrefresh(dialog);
|
||||
}
|
||||
continue;
|
||||
case KEY_RIGHT:
|
||||
if (scroll+input_x < MAX_LEN) {
|
||||
wattrset(dialog, inputbox_attr);
|
||||
if (!instr[scroll+input_x])
|
||||
instr[scroll+input_x] = ' ';
|
||||
if (input_x == box_width-1) {
|
||||
scroll++;
|
||||
wmove(dialog, box_y, box_x);
|
||||
for (i = 0; i < box_width; i++)
|
||||
waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
|
||||
wmove(dialog, box_y, box_x + box_width - 1);
|
||||
}
|
||||
else {
|
||||
wmove(dialog, box_y, input_x + box_x);
|
||||
waddch(dialog, instr[scroll+input_x]);
|
||||
input_x++;
|
||||
}
|
||||
wrefresh(dialog);
|
||||
} else
|
||||
flash(); /* Alarm user about overflow */
|
||||
continue;
|
||||
case KEY_BACKSPACE:
|
||||
case KEY_DC:
|
||||
if (input_x || scroll) {
|
||||
i = strlen(instr);
|
||||
memmove(instr+scroll+input_x-1, instr+scroll+input_x, i-scroll+input_x+1);
|
||||
wattrset(dialog, inputbox_attr);
|
||||
if (!input_x) {
|
||||
int oldscroll = scroll;
|
||||
scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
|
||||
wmove(dialog, box_y, box_x);
|
||||
for (i = 0; i < box_width; i++)
|
||||
waddch(dialog, instr[scroll+input_x+i] ? instr[scroll+input_x+i] : ' ');
|
||||
input_x = oldscroll - 1 - scroll;
|
||||
}
|
||||
else
|
||||
input_x--;
|
||||
wmove(dialog, box_y, input_x + box_x);
|
||||
for (i = input_x; i < box_width; i++)
|
||||
waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
|
||||
wmove(dialog, box_y, input_x + box_x);
|
||||
wrefresh(dialog);
|
||||
}
|
||||
continue;
|
||||
default:
|
||||
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) {
|
||||
memmove(instr+scroll+input_x+1, instr+scroll+input_x, i-scroll+input_x);
|
||||
wattrset(dialog, inputbox_attr);
|
||||
instr[scroll+input_x] = key;
|
||||
if (input_x == box_width-1) {
|
||||
scroll++;
|
||||
wmove(dialog, box_y, box_x);
|
||||
for (i = 0; i < box_width-1; i++)
|
||||
waddch(dialog, instr[scroll+i]);
|
||||
}
|
||||
else {
|
||||
wmove(dialog, box_y, input_x + box_x);
|
||||
for (i = input_x; i < box_width; i++)
|
||||
waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
|
||||
wmove(dialog, box_y, ++input_x + box_x);
|
||||
}
|
||||
wrefresh(dialog);
|
||||
} else
|
||||
flash(); /* Alarm user about overflow */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
wmove(dialog, box_y, box_x + input_x);
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
case 1:
|
||||
button = 0; /* Indicates "OK" button is selected */
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TAB:
|
||||
case KEY_DOWN:
|
||||
case KEY_RIGHT:
|
||||
switch (button) {
|
||||
case -1:
|
||||
button = 0; /* Indicates "OK" button is selected */
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
case 0:
|
||||
button = 1; /* Indicates "Cancel" button is selected */
|
||||
print_button(dialog, " OK ", y, x, FALSE);
|
||||
print_button(dialog, "Cancel", y, x+14, TRUE);
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
case 1:
|
||||
button = -1; /* Indicates input box is selected */
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
wmove(dialog, box_y, box_x + input_x);
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ' ':
|
||||
case '\n':
|
||||
delwin(dialog);
|
||||
for (i = strlen(instr) - 1; i >= scroll + input_x && instr[i] == ' '; i--)
|
||||
instr[i] = '\0';
|
||||
if (button < 1)
|
||||
strcpy(result, instr);
|
||||
return (button == -1 ? 0 : button);
|
||||
case ESC:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delwin(dialog);
|
||||
return -1; /* ESC pressed */
|
||||
}
|
||||
/* End of dialog_inputbox() */
|
330
gnu/lib/libdialog/kernel.c
Normal file
330
gnu/lib/libdialog/kernel.c
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
* dialog - Display simple dialog boxes from shell scripts
|
||||
*
|
||||
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
*
|
||||
* 17/12/93 - Version 0.1 released.
|
||||
*
|
||||
* 19/12/93 - menu will now scroll if there are more items than can fit
|
||||
* on the screen.
|
||||
* - added 'checklist', a dialog box with a list of options that
|
||||
* can be turned on or off. A list of options that are on is
|
||||
* returned on exit.
|
||||
*
|
||||
* 20/12/93 - Version 0.15 released.
|
||||
*
|
||||
* 29/12/93 - Incorporated patch from Patrick J. Volkerding
|
||||
* (volkerdi@mhd1.moorhead.msus.edu) that made these changes:
|
||||
* - increased MAX_LEN to 2048
|
||||
* - added 'infobox', equivalent to a message box without pausing
|
||||
* - added option '--clear' that will clear the screen
|
||||
* - Explicit line breaking when printing prompt text can be
|
||||
* invoked by real newline '\n' besides the string "\n"
|
||||
* - an optional parameter '--title <string>' can be used to
|
||||
* specify a title string for the dialog box
|
||||
*
|
||||
* 03/01/94 - added 'textbox', a dialog box for displaying text from a file.
|
||||
* - Version 0.2 released.
|
||||
*
|
||||
* 04/01/94 - some fixes and improvements for 'textbox':
|
||||
* - fixed a bug that will cause a segmentation violation when a
|
||||
* line is longer than MAX_LEN characters. Lines will now be
|
||||
* truncated if they are longer than MAX_LEN characters.
|
||||
* - removed wrefresh() from print_line(). This will increase
|
||||
* efficiency of print_page() which calls print_line().
|
||||
* - display current position in the form of percentage into file.
|
||||
* - Version 0.21 released.
|
||||
*
|
||||
* 05/01/94 - some changes for faster screen update.
|
||||
*
|
||||
* 07/01/94 - much more flexible color settings. Can use all 16 colors
|
||||
* (8 normal, 8 highlight) of the Linux console.
|
||||
*
|
||||
* 08/01/94 - added run-time configuration using configuration file.
|
||||
*
|
||||
* 09/01/94 - some minor bug fixes and cleanups for menubox, checklist and
|
||||
* textbox.
|
||||
*
|
||||
* 11/01/94 - added a man page.
|
||||
*
|
||||
* 13/01/94 - some changes for easier porting to other Unix systems (tested
|
||||
* on Ultrix, SunOS and HPUX)
|
||||
* - Version 0.3 released.
|
||||
*
|
||||
* 08/06/94 - Patches by Stuart Herbert - S.Herbert@shef.ac.uk
|
||||
* Fixed attr_clear and the textbox stuff to work with ncurses 1.8.5
|
||||
* Fixed the wordwrap routine - it'll actually wrap properly now
|
||||
* Added a more 3D look to everything - having your own rc file could
|
||||
* prove 'interesting' to say the least :-)
|
||||
* Added radiolist option
|
||||
* - Version 0.4 released.
|
||||
*/
|
||||
|
||||
#define __DIALOG_MAIN__
|
||||
|
||||
#include "dialog.priv.h"
|
||||
#include <dialog.h>
|
||||
#ifdef HAVE_NCURSES
|
||||
#include "colors.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Do some initialization for dialog
|
||||
*/
|
||||
void init_dialog(void)
|
||||
{
|
||||
#if defined(LOCALE)
|
||||
(void) setlocale(LC_ALL, "");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
if (parse_rc() == -1) /* Read the configuration file */
|
||||
exit(-1);
|
||||
#endif
|
||||
|
||||
initscr(); /* Init curses */
|
||||
keypad(stdscr, TRUE);
|
||||
cbreak();
|
||||
noecho();
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
if (use_colors || use_shadow) /* Set up colors */
|
||||
color_setup();
|
||||
#endif
|
||||
|
||||
/* Set screen to screen attribute */
|
||||
attr_clear(stdscr, LINES, COLS, screen_attr);
|
||||
wnoutrefresh(stdscr);
|
||||
}
|
||||
/* End of init_dialog() */
|
||||
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
/*
|
||||
* Setup for color display
|
||||
*/
|
||||
void color_setup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (has_colors()) { /* Terminal supports color? */
|
||||
start_color();
|
||||
|
||||
/* Initialize color pairs */
|
||||
for (i = 0; i < ATTRIBUTE_COUNT; i++)
|
||||
init_pair(i+1, color_table[i][0], color_table[i][1]);
|
||||
|
||||
/* Setup color attributes */
|
||||
for (i = 0; i < ATTRIBUTE_COUNT; i++)
|
||||
attributes[i] = C_ATTR(color_table[i][2], i+1);
|
||||
}
|
||||
}
|
||||
/* End of color_setup() */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Set window to attribute 'attr'
|
||||
*/
|
||||
void attr_clear(WINDOW *win, int height, int width, chtype attr)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
wattrset(win, attr); /* Set window to attribute 'attr' */
|
||||
for (i = 0; i < height; i++) {
|
||||
wmove(win, i, 0);
|
||||
for (j = 0; j < width; j++)
|
||||
waddch(win, ' ');
|
||||
}
|
||||
}
|
||||
/* End of attr_clear() */
|
||||
|
||||
|
||||
/*
|
||||
* Print a string of text in a window, automatically wrap around to the
|
||||
* next line if the string is too long to fit on one line. Note that the
|
||||
* string may contain "\n" to represent a newline character or the real
|
||||
* newline '\n', but in that case, auto wrap around will be disabled.
|
||||
*/
|
||||
void print_autowrap(WINDOW *win, unsigned char *prompt, int width, int y, int x)
|
||||
{
|
||||
int first = 1, cur_x, cur_y;
|
||||
unsigned char tempstr[MAX_LEN+1], *word, *tempptr, *tempptr1;
|
||||
|
||||
strcpy(tempstr, prompt);
|
||||
if ((strstr(tempstr, "\\n") != NULL) ||
|
||||
(strchr(tempstr, '\n') != NULL)) { /* Prompt contains "\n" or '\n' */
|
||||
word = tempstr;
|
||||
cur_y = y;
|
||||
wmove(win, cur_y, x);
|
||||
while (1) {
|
||||
tempptr = strstr(word, "\\n");
|
||||
tempptr1 = strchr(word, '\n');
|
||||
if (tempptr == NULL && tempptr1 == NULL)
|
||||
break;
|
||||
else if (tempptr == NULL) { /* No more "\n" */
|
||||
tempptr = tempptr1;
|
||||
tempptr[0] = '\0';
|
||||
}
|
||||
else if (tempptr1 == NULL) { /* No more '\n' */
|
||||
tempptr[0] = '\0';
|
||||
tempptr++;
|
||||
}
|
||||
else { /* Prompt contains both "\n" and '\n' */
|
||||
if (strlen(tempptr)-2 < strlen(tempptr1)-1) {
|
||||
tempptr = tempptr1;
|
||||
tempptr[0] = '\0';
|
||||
}
|
||||
else {
|
||||
tempptr[0] = '\0';
|
||||
tempptr++;
|
||||
}
|
||||
}
|
||||
|
||||
waddstr(win, word);
|
||||
word = tempptr + 1;
|
||||
wmove(win, ++cur_y, x);
|
||||
}
|
||||
waddstr(win, word);
|
||||
}
|
||||
else if (strlen(tempstr) <= width-x*2) { /* If prompt is short */
|
||||
wmove(win, y, (width - strlen(tempstr)) / 2);
|
||||
waddstr(win, tempstr);
|
||||
}
|
||||
else {
|
||||
cur_x = x;
|
||||
cur_y = y;
|
||||
/* Print prompt word by word, wrap around if necessary */
|
||||
while ((word = strtok(first ? tempstr : NULL, " ")) != NULL) {
|
||||
if (first) /* First iteration */
|
||||
first = 0;
|
||||
if (cur_x+strlen(word) >= width) { /* wrap around to next line */
|
||||
cur_y++;
|
||||
cur_x = x;
|
||||
}
|
||||
wmove(win, cur_y, cur_x);
|
||||
waddstr(win, word);
|
||||
getyx(win, cur_y, cur_x);
|
||||
cur_x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* End of print_autowrap() */
|
||||
|
||||
|
||||
/*
|
||||
* Print a button
|
||||
*/
|
||||
void print_button(WINDOW *win, unsigned char *label, int y, int x, int selected)
|
||||
{
|
||||
int i, temp;
|
||||
|
||||
wmove(win, y, x);
|
||||
wattrset(win, selected ? button_active_attr : button_inactive_attr);
|
||||
waddstr(win, "<");
|
||||
temp = strspn(label, " ");
|
||||
label += temp;
|
||||
wattrset(win, selected ? button_label_active_attr : button_label_inactive_attr);
|
||||
for (i = 0; i < temp; i++)
|
||||
waddch(win, ' ');
|
||||
wattrset(win, selected ? button_key_active_attr : button_key_inactive_attr);
|
||||
waddch(win, label[0]);
|
||||
wattrset(win, selected ? button_label_active_attr : button_label_inactive_attr);
|
||||
waddstr(win, label+1);
|
||||
wattrset(win, selected ? button_active_attr : button_inactive_attr);
|
||||
waddstr(win, ">");
|
||||
wmove(win, y, x+temp+1);
|
||||
}
|
||||
/* End of print_button() */
|
||||
|
||||
|
||||
/*
|
||||
* Draw a rectangular box with line drawing characters
|
||||
*/
|
||||
void draw_box(WINDOW *win, int y, int x, int height, int width, chtype box, chtype border)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
wattrset(win, 0);
|
||||
for (i = 0; i < height; i++) {
|
||||
wmove(win, y + i, x);
|
||||
for (j = 0; j < width; j++)
|
||||
if (!i && !j)
|
||||
waddch(win, border | ACS_ULCORNER);
|
||||
else if (i == height-1 && !j)
|
||||
waddch(win, border | ACS_LLCORNER);
|
||||
else if (!i && j == width-1)
|
||||
waddch(win, box | ACS_URCORNER);
|
||||
else if (i == height-1 && j == width-1)
|
||||
waddch(win, box | ACS_LRCORNER);
|
||||
else if (!i)
|
||||
waddch(win, border | ACS_HLINE);
|
||||
else if (i == height-1)
|
||||
waddch(win, box | ACS_HLINE);
|
||||
else if (!j)
|
||||
waddch(win, border | ACS_VLINE);
|
||||
else if (j == width-1)
|
||||
waddch(win, box | ACS_VLINE);
|
||||
else
|
||||
waddch(win, box | ' ');
|
||||
}
|
||||
}
|
||||
/* End of draw_box() */
|
||||
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
/*
|
||||
* Draw shadows along the right and bottom edge to give a more 3D look
|
||||
* to the boxes
|
||||
*/
|
||||
void draw_shadow(WINDOW *win, int y, int x, int height, int width)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (has_colors()) { /* Whether terminal supports color? */
|
||||
wattrset(win, shadow_attr);
|
||||
wmove(win, y + height, x + 2);
|
||||
for (i = 0; i < width; i++)
|
||||
waddch(win, winch(win) & A_CHARTEXT);
|
||||
for (i = y + 1; i < y + height + 1; i++) {
|
||||
wmove(win, i, x + width);
|
||||
waddch(win, winch(win) & A_CHARTEXT);
|
||||
waddch(win, winch(win) & A_CHARTEXT);
|
||||
}
|
||||
wnoutrefresh(win);
|
||||
}
|
||||
}
|
||||
/* End of draw_shadow() */
|
||||
#endif
|
||||
|
||||
void dialog_clear(void)
|
||||
{
|
||||
attr_clear(stdscr, LINES, COLS, screen_attr);
|
||||
}
|
||||
|
||||
void dialog_update(void)
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
|
||||
void end_dialog(void)
|
||||
{
|
||||
endwin();
|
||||
}
|
311
gnu/lib/libdialog/menubox.c
Normal file
311
gnu/lib/libdialog/menubox.c
Normal file
@ -0,0 +1,311 @@
|
||||
/*
|
||||
* menubox.c -- implements the menu box
|
||||
*
|
||||
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "dialog.priv.h"
|
||||
#include <dialog.h>
|
||||
|
||||
|
||||
static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int choice, int selected);
|
||||
|
||||
|
||||
static int menu_width, tag_x, item_x;
|
||||
|
||||
|
||||
/*
|
||||
* Display a menu for choosing among a number of options
|
||||
*/
|
||||
int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height, int item_no, unsigned char **items, unsigned char *result)
|
||||
{
|
||||
int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
|
||||
scroll = 0, max_choice;
|
||||
WINDOW *dialog, *menu;
|
||||
|
||||
max_choice = MIN(menu_height, item_no);
|
||||
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width)/2;
|
||||
y = (LINES - height)/2;
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
if (use_shadow)
|
||||
draw_shadow(stdscr, y, x, height, width);
|
||||
#endif
|
||||
dialog = newwin(height, width, y, x);
|
||||
keypad(dialog, TRUE);
|
||||
|
||||
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
|
||||
wattrset(dialog, border_attr);
|
||||
wmove(dialog, height-3, 0);
|
||||
waddch(dialog, ACS_LTEE);
|
||||
for (i = 0; i < width-2; i++)
|
||||
waddch(dialog, ACS_HLINE);
|
||||
wattrset(dialog, dialog_attr);
|
||||
waddch(dialog, ACS_RTEE);
|
||||
wmove(dialog, height-2, 1);
|
||||
for (i = 0; i < width-2; i++)
|
||||
waddch(dialog, ' ');
|
||||
|
||||
if (title != NULL) {
|
||||
wattrset(dialog, title_attr);
|
||||
wmove(dialog, 0, (width - strlen(title))/2 - 1);
|
||||
waddch(dialog, ' ');
|
||||
waddstr(dialog, title);
|
||||
waddch(dialog, ' ');
|
||||
}
|
||||
wattrset(dialog, dialog_attr);
|
||||
print_autowrap(dialog, prompt, width, 1, 3);
|
||||
|
||||
menu_width = width-6;
|
||||
getyx(dialog, cur_y, cur_x);
|
||||
box_y = cur_y + 1;
|
||||
box_x = (width - menu_width)/2 - 1;
|
||||
|
||||
/* create new window for the menu */
|
||||
menu = subwin(dialog, menu_height, menu_width, y + box_y + 1, x + box_x + 1);
|
||||
keypad(menu, TRUE);
|
||||
|
||||
/* draw a box around the menu items */
|
||||
draw_box(dialog, box_y, box_x, menu_height+2, menu_width+2, menubox_border_attr, menubox_attr);
|
||||
|
||||
tag_x = 0;
|
||||
item_x = 0;
|
||||
/* Find length of longest item in order to center menu */
|
||||
for (i = 0; i < item_no; i++) {
|
||||
tag_x = MAX(tag_x, strlen(items[i*2]) + strlen(items[i*2 + 1]) + 2);
|
||||
item_x = MAX(item_x, strlen(items[i*2]));
|
||||
}
|
||||
tag_x = (menu_width - tag_x) / 2;
|
||||
item_x = tag_x + item_x + 2;
|
||||
|
||||
/* Print the menu */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(menu, items[i*2], items[i*2 + 1], i, i == choice);
|
||||
wnoutrefresh(menu);
|
||||
|
||||
if (menu_height < item_no) {
|
||||
wattrset(dialog, darrow_attr);
|
||||
wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 1);
|
||||
waddch(dialog, ACS_DARROW);
|
||||
wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 2);
|
||||
waddstr(dialog,"(+)");
|
||||
}
|
||||
|
||||
x = width/2-11;
|
||||
y = height-2;
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
wrefresh(dialog);
|
||||
|
||||
while (key != ESC) {
|
||||
key = wgetch(dialog);
|
||||
/* Check if key pressed matches first character of any item tag in menu */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
if (key < 0x100 && toupper(key) == toupper(items[(scroll+i)*2][0]))
|
||||
break;
|
||||
|
||||
if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) ||
|
||||
key == KEY_UP || key == KEY_DOWN || key == '-' || key == '+') {
|
||||
if (key >= '1' && key <= MIN('9', '0'+max_choice))
|
||||
i = key - '1';
|
||||
else if (key == KEY_UP || key == '-') {
|
||||
if (!choice) {
|
||||
if (scroll) {
|
||||
#ifdef BROKEN_WSCRL
|
||||
/* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
|
||||
violation when scrolling windows of height = 4, so scrolling is not
|
||||
used for now */
|
||||
scroll--;
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
/* Reprint menu to scroll down */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(menu, items[(scroll+i)*2], items[(scroll+i)*2 + 1], i, i == choice);
|
||||
|
||||
#else
|
||||
|
||||
/* Scroll menu down */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
if (menu_height > 1) {
|
||||
/* De-highlight current first item before scrolling down */
|
||||
print_item(menu, items[scroll*2], items[scroll*2 + 1], 0, FALSE);
|
||||
scrollok(menu, TRUE);
|
||||
wscrl(menu, -1);
|
||||
scrollok(menu, FALSE);
|
||||
}
|
||||
scroll--;
|
||||
print_item(menu, items[scroll*2], items[scroll*2 + 1], 0, TRUE);
|
||||
#endif
|
||||
wnoutrefresh(menu);
|
||||
|
||||
/* print the up/down arrows */
|
||||
wmove(dialog, box_y, box_x + tag_x + 1);
|
||||
wattrset(dialog, scroll ? uarrow_attr : menubox_attr);
|
||||
waddch(dialog, scroll ? ACS_UARROW : ACS_HLINE);
|
||||
wmove(dialog, box_y, box_x + tag_x + 2);
|
||||
waddch(dialog, scroll ? '(' : ACS_HLINE);
|
||||
wmove(dialog, box_y, box_x + tag_x + 3);
|
||||
waddch(dialog, scroll ? '-' : ACS_HLINE);
|
||||
wmove(dialog, box_y, box_x + tag_x + 4);
|
||||
waddch(dialog, scroll ? ')' : ACS_HLINE);
|
||||
wattrset(dialog, darrow_attr);
|
||||
wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 1);
|
||||
waddch(dialog, ACS_DARROW);
|
||||
wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 2);
|
||||
waddstr(dialog,"(+)");
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
continue; /* wait for another key press */
|
||||
}
|
||||
else
|
||||
i = choice - 1;
|
||||
}
|
||||
else if (key == KEY_DOWN || key == '+')
|
||||
if (choice == max_choice - 1) {
|
||||
if (scroll+choice < item_no-1) {
|
||||
#ifdef BROKEN_WSCRL
|
||||
/* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
|
||||
violation when scrolling windows of height = 4, so scrolling is not
|
||||
used for now */
|
||||
scroll++;
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
/* Reprint menu to scroll up */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(menu, items[(scroll+i)*2], items[(scroll+i)*2 + 1], i, i == choice);
|
||||
|
||||
#else
|
||||
|
||||
/* Scroll menu up */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
if (menu_height > 1) {
|
||||
/* De-highlight current last item before scrolling up */
|
||||
print_item(menu, items[(scroll+max_choice-1)*2], items[(scroll+max_choice-1)*2 + 1], max_choice-1, FALSE);
|
||||
scrollok(menu, TRUE);
|
||||
scroll(menu);
|
||||
scrollok(menu, FALSE);
|
||||
}
|
||||
scroll++;
|
||||
print_item(menu, items[(scroll+max_choice-1)*2], items[(scroll+max_choice-1)*2 + 1], max_choice-1, TRUE);
|
||||
#endif
|
||||
wnoutrefresh(menu);
|
||||
|
||||
/* print the up/down arrows */
|
||||
wattrset(dialog, uarrow_attr);
|
||||
wmove(dialog, box_y, box_x + tag_x + 1);
|
||||
waddch(dialog, ACS_UARROW);
|
||||
wmove(dialog, box_y, box_x + tag_x + 2);
|
||||
waddstr(dialog,"(-)");
|
||||
wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 1);
|
||||
wattrset(dialog, scroll+choice < item_no-1 ? darrow_attr : menubox_border_attr);
|
||||
waddch(dialog, scroll+choice < item_no-1 ? ACS_DARROW : ACS_HLINE);
|
||||
wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 2);
|
||||
waddch(dialog, scroll+choice < item_no-1 ? '(' : ACS_HLINE);
|
||||
wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 3);
|
||||
waddch(dialog, scroll+choice < item_no-1 ? '+' : ACS_HLINE);
|
||||
wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 4);
|
||||
waddch(dialog, scroll+choice < item_no-1 ? ')' : ACS_HLINE);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
continue; /* wait for another key press */
|
||||
}
|
||||
else
|
||||
i = choice + 1;
|
||||
|
||||
if (i != choice) {
|
||||
/* De-highlight current item */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
print_item(menu, items[(scroll+choice)*2], items[(scroll+choice)*2 + 1], choice, FALSE);
|
||||
|
||||
/* Highlight new item */
|
||||
choice = i;
|
||||
print_item(menu, items[(scroll+choice)*2], items[(scroll+choice)*2 + 1], choice, TRUE);
|
||||
wnoutrefresh(menu);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
continue; /* wait for another key press */
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case 'O':
|
||||
case 'o':
|
||||
delwin(dialog);
|
||||
strcpy(result, items[(scroll+choice)*2]);
|
||||
return 0;
|
||||
case 'C':
|
||||
case 'c':
|
||||
delwin(dialog);
|
||||
return 1;
|
||||
case KEY_BTAB:
|
||||
case TAB:
|
||||
case KEY_LEFT:
|
||||
case KEY_RIGHT:
|
||||
if (!button) {
|
||||
button = 1; /* Indicates "Cancel" button is selected */
|
||||
print_button(dialog, " OK ", y, x, FALSE);
|
||||
print_button(dialog, "Cancel", y, x+14, TRUE);
|
||||
}
|
||||
else {
|
||||
button = 0; /* Indicates "OK" button is selected */
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
}
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
case ' ':
|
||||
case '\n':
|
||||
delwin(dialog);
|
||||
if (!button)
|
||||
strcpy(result, items[(scroll+choice)*2]);
|
||||
return button;
|
||||
case ESC:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delwin(dialog);
|
||||
return -1; /* ESC pressed */
|
||||
}
|
||||
/* End of dialog_menu() */
|
||||
|
||||
|
||||
/*
|
||||
* Print menu item
|
||||
*/
|
||||
static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int choice, int selected)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Clear 'residue' of last item */
|
||||
wattrset(win, menubox_attr);
|
||||
wmove(win, choice, 0);
|
||||
for (i = 0; i < menu_width; i++)
|
||||
waddch(win, ' ');
|
||||
wmove(win, choice, tag_x);
|
||||
wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
|
||||
waddch(win, tag[0]);
|
||||
wattrset(win, selected ? tag_selected_attr : tag_attr);
|
||||
waddstr(win, tag + 1);
|
||||
wmove(win, choice, item_x);
|
||||
wattrset(win, selected ? item_selected_attr : item_attr);
|
||||
waddstr(win, item);
|
||||
}
|
||||
/* End of print_item() */
|
82
gnu/lib/libdialog/msgbox.c
Normal file
82
gnu/lib/libdialog/msgbox.c
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* msgbox.c -- implements the message box and info box
|
||||
*
|
||||
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "dialog.priv.h"
|
||||
#include <dialog.h>
|
||||
|
||||
|
||||
/*
|
||||
* Display a message box. Program will pause and display an "OK" button
|
||||
* if the parameter 'pause' is non-zero.
|
||||
*/
|
||||
int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int width, int pause)
|
||||
{
|
||||
int i, x, y, key = 0;
|
||||
WINDOW *dialog;
|
||||
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width)/2;
|
||||
y = (LINES - height)/2;
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
if (use_shadow)
|
||||
draw_shadow(stdscr, y, x, height, width);
|
||||
#endif
|
||||
dialog = newwin(height, width, y, x);
|
||||
keypad(dialog, TRUE);
|
||||
|
||||
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
|
||||
|
||||
if (title != NULL) {
|
||||
wattrset(dialog, title_attr);
|
||||
wmove(dialog, 0, (width - strlen(title))/2 - 1);
|
||||
waddch(dialog, ' ');
|
||||
waddstr(dialog, title);
|
||||
waddch(dialog, ' ');
|
||||
}
|
||||
wattrset(dialog, dialog_attr);
|
||||
print_autowrap(dialog, prompt, width-2, 1, 2);
|
||||
|
||||
if (pause) {
|
||||
wattrset(dialog, border_attr);
|
||||
wmove(dialog, height-3, 0);
|
||||
waddch(dialog, ACS_LTEE);
|
||||
for (i = 0; i < width-2; i++)
|
||||
waddch(dialog, ACS_HLINE);
|
||||
wattrset(dialog, dialog_attr);
|
||||
waddch(dialog, ACS_RTEE);
|
||||
wmove(dialog, height-2, 1);
|
||||
for (i = 0; i < width-2; i++)
|
||||
waddch(dialog, ' ');
|
||||
print_button(dialog, " OK ", height-2, width/2-4, TRUE);
|
||||
wrefresh(dialog);
|
||||
while (key != ESC && key != '\n' && key != ' ')
|
||||
key = wgetch(dialog);
|
||||
}
|
||||
else {
|
||||
key = '\n';
|
||||
wrefresh(dialog);
|
||||
}
|
||||
|
||||
delwin(dialog);
|
||||
return (key == ESC ? -1 : 0);
|
||||
}
|
||||
/* End of dialog_msgbox() */
|
368
gnu/lib/libdialog/radiolist.c
Normal file
368
gnu/lib/libdialog/radiolist.c
Normal file
@ -0,0 +1,368 @@
|
||||
/*
|
||||
* radiolist.c -- implements the radiolist box
|
||||
*
|
||||
* AUTHOR: Stuart Herbert - S.Herbert@sheffield.ac.uk
|
||||
* (from checklist.c by Savio Lam (lam836@cs.cuhk.hk))
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "dialog.priv.h"
|
||||
#include <dialog.h>
|
||||
|
||||
|
||||
static void print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected);
|
||||
|
||||
|
||||
static int list_width, check_x, item_x;
|
||||
|
||||
|
||||
/*
|
||||
* Display a dialog box with a list of options that can be turned on or off
|
||||
*/
|
||||
int dialog_radiolist(char *title, char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result)
|
||||
{
|
||||
int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
|
||||
scroll = 0, max_choice, *status, was_on = 0;
|
||||
WINDOW *dialog, *list;
|
||||
|
||||
/* Allocate space for storing item on/off status */
|
||||
if ((status = malloc(sizeof(int)*item_no)) == NULL) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nCan't allocate memory in dialog_radiolist().\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* Initializes status */
|
||||
for (i = 0; i < item_no; i++) {
|
||||
status[i] = !strcasecmp(items[i*3 + 2], "on");
|
||||
if (status[i])
|
||||
if (was_on) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nOnly one status can be ON in dialog_radiolist().\n");
|
||||
exit(-1);
|
||||
} else
|
||||
was_on = 1;
|
||||
}
|
||||
max_choice = MIN(list_height, item_no);
|
||||
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width)/2;
|
||||
y = (LINES - height)/2;
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
if (use_shadow)
|
||||
draw_shadow(stdscr, y, x, height, width);
|
||||
#endif
|
||||
dialog = newwin(height, width, y, x);
|
||||
keypad(dialog, TRUE);
|
||||
|
||||
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
|
||||
wattrset(dialog, border_attr);
|
||||
wmove(dialog, height-3, 0);
|
||||
waddch(dialog, ACS_LTEE);
|
||||
for (i = 0; i < width-2; i++)
|
||||
waddch(dialog, ACS_HLINE);
|
||||
wattrset(dialog, dialog_attr);
|
||||
waddch(dialog, ACS_RTEE);
|
||||
wmove(dialog, height-2, 1);
|
||||
for (i = 0; i < width-2; i++)
|
||||
waddch(dialog, ' ');
|
||||
|
||||
if (title != NULL) {
|
||||
wattrset(dialog, title_attr);
|
||||
wmove(dialog, 0, (width - strlen(title))/2 - 1);
|
||||
waddch(dialog, ' ');
|
||||
waddstr(dialog, title);
|
||||
waddch(dialog, ' ');
|
||||
}
|
||||
wattrset(dialog, dialog_attr);
|
||||
print_autowrap(dialog, prompt, width, 1, 3);
|
||||
|
||||
list_width = width-6;
|
||||
getyx(dialog, cur_y, cur_x);
|
||||
box_y = cur_y + 1;
|
||||
box_x = (width - list_width)/2 - 1;
|
||||
|
||||
/* create new window for the list */
|
||||
list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
|
||||
keypad(list, TRUE);
|
||||
|
||||
/* draw a box around the list items */
|
||||
draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr);
|
||||
|
||||
check_x = 0;
|
||||
item_x = 0;
|
||||
/* Find length of longest item in order to center radiolist */
|
||||
for (i = 0; i < item_no; i++) {
|
||||
check_x = MAX(check_x, strlen(items[i*3]) + strlen(items[i*3 + 1]) + 6);
|
||||
item_x = MAX(item_x, strlen(items[i*3]));
|
||||
}
|
||||
check_x = (list_width - check_x) / 2;
|
||||
item_x = check_x + item_x + 6;
|
||||
|
||||
/* Print the list */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(list, items[i*3], items[i*3 + 1], status[i], i, i == choice);
|
||||
wnoutrefresh(list);
|
||||
|
||||
if (list_height < item_no) {
|
||||
wattrset(dialog, darrow_attr);
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
|
||||
waddch(dialog, ACS_DARROW);
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
|
||||
waddstr(dialog, "(+)");
|
||||
}
|
||||
|
||||
x = width/2-11;
|
||||
y = height-2;
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
wrefresh(dialog);
|
||||
|
||||
while (key != ESC) {
|
||||
key = wgetch(dialog);
|
||||
/* Check if key pressed matches first character of any item tag in list */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
if (toupper(key) == toupper(items[(scroll+i)*3][0]))
|
||||
break;
|
||||
|
||||
if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) ||
|
||||
key == KEY_UP || key == KEY_DOWN || key == ' ' ||
|
||||
key == '+' || key == '-' ) {
|
||||
if (key >= '1' && key <= MIN('9', '0'+max_choice))
|
||||
i = key - '1';
|
||||
else if (key == KEY_UP || key == '-') {
|
||||
if (!choice) {
|
||||
if (scroll) {
|
||||
#ifdef BROKEN_WSCRL
|
||||
/* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
|
||||
violation when scrolling windows of height = 4, so scrolling is not
|
||||
used for now */
|
||||
scroll--;
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
/* Reprint list to scroll down */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice);
|
||||
|
||||
#else
|
||||
|
||||
/* Scroll list down */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
if (list_height > 1) {
|
||||
/* De-highlight current first item before scrolling down */
|
||||
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, FALSE);
|
||||
scrollok(list, TRUE);
|
||||
wscrl(list, -1);
|
||||
scrollok(list, FALSE);
|
||||
}
|
||||
scroll--;
|
||||
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE);
|
||||
#endif
|
||||
wnoutrefresh(list);
|
||||
|
||||
/* print the up/down arrows */
|
||||
wmove(dialog, box_y, box_x + check_x + 5);
|
||||
wattrset(dialog, scroll ? uarrow_attr : menubox_attr);
|
||||
waddch(dialog, scroll ? ACS_UARROW : ACS_HLINE);
|
||||
wmove(dialog, box_y, box_x + check_x + 6);
|
||||
waddch(dialog, scroll ? '(' : ACS_HLINE);
|
||||
wmove(dialog, box_y, box_x + check_x + 7);
|
||||
waddch(dialog, scroll ? '-' : ACS_HLINE);
|
||||
wmove(dialog, box_y, box_x + check_x + 8);
|
||||
waddch(dialog, scroll ? ')' : ACS_HLINE);
|
||||
wattrset(dialog, darrow_attr);
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
|
||||
waddch(dialog, ACS_DARROW);
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
|
||||
waddch(dialog, '(');
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 7);
|
||||
waddch(dialog, '+');
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 8);
|
||||
waddch(dialog, ')');
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
continue; /* wait for another key press */
|
||||
}
|
||||
else
|
||||
i = choice - 1;
|
||||
}
|
||||
else if (key == KEY_DOWN || key == '+') {
|
||||
if (choice == max_choice - 1) {
|
||||
if (scroll+choice < item_no-1) {
|
||||
#ifdef BROKEN_WSCRL
|
||||
/* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
|
||||
violation when scrolling windows of height = 4, so scrolling is not
|
||||
used for now */
|
||||
scroll++;
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
/* Reprint list to scroll up */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice);
|
||||
|
||||
#else
|
||||
|
||||
/* Scroll list up */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
if (list_height > 1) {
|
||||
/* De-highlight current last item before scrolling up */
|
||||
print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1], status[scroll+max_choice-1], max_choice-1, FALSE);
|
||||
scrollok(list, TRUE);
|
||||
scroll(list);
|
||||
scrollok(list, FALSE);
|
||||
}
|
||||
scroll++;
|
||||
print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1], status[scroll+max_choice-1], max_choice-1, TRUE);
|
||||
#endif
|
||||
wnoutrefresh(list);
|
||||
|
||||
/* print the up/down arrows */
|
||||
wattrset(dialog, uarrow_attr);
|
||||
wmove(dialog, box_y, box_x + check_x + 5);
|
||||
waddch(dialog, ACS_UARROW);
|
||||
wmove(dialog, box_y, box_x + check_x + 6);
|
||||
waddstr(dialog, "(-)");
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
|
||||
wattrset(dialog, scroll+choice < item_no-1 ? darrow_attr : menubox_border_attr);
|
||||
waddch(dialog, scroll+choice < item_no-1 ? ACS_DARROW : ACS_HLINE);
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
|
||||
waddch(dialog, scroll+choice < item_no-1 ? '(' : ACS_HLINE);
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 7);
|
||||
waddch(dialog, scroll+choice < item_no-1 ? '+' : ACS_HLINE);
|
||||
wmove(dialog, box_y + list_height + 1, box_x + check_x + 8);
|
||||
waddch(dialog, scroll+choice < item_no-1 ? ')' : ACS_HLINE);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
continue; /* wait for another key press */
|
||||
}
|
||||
else
|
||||
i = choice + 1;
|
||||
}
|
||||
else if (key == ' ') { /* Toggle item status */
|
||||
if (!status[scroll+choice])
|
||||
{
|
||||
for (i=0; i<item_no; i++)
|
||||
status[i]=0;
|
||||
status[scroll+choice]=1;
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
for (i = 0; i < max_choice; i++)
|
||||
print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice);
|
||||
wnoutrefresh(list);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
continue; /* wait for another key press */
|
||||
}
|
||||
|
||||
if (i != choice) {
|
||||
/* De-highlight current item */
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 +1], status[scroll+choice], choice, FALSE);
|
||||
/* Highlight new item */
|
||||
choice = i;
|
||||
print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, TRUE);
|
||||
wnoutrefresh(list);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
continue; /* wait for another key press */
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case 'O':
|
||||
case 'o':
|
||||
delwin(dialog);
|
||||
*result = '\0';
|
||||
for (i = 0; i < item_no; i++)
|
||||
if (status[i]) {
|
||||
strcpy(result, items[i*3]);
|
||||
break;
|
||||
}
|
||||
free(status);
|
||||
return 0;
|
||||
case 'C':
|
||||
case 'c':
|
||||
delwin(dialog);
|
||||
free(status);
|
||||
return 1;
|
||||
case KEY_BTAB:
|
||||
case TAB:
|
||||
case KEY_LEFT:
|
||||
case KEY_RIGHT:
|
||||
if (!button) {
|
||||
button = 1; /* Indicates "Cancel" button is selected */
|
||||
print_button(dialog, " OK ", y, x, FALSE);
|
||||
print_button(dialog, "Cancel", y, x+14, TRUE);
|
||||
}
|
||||
else {
|
||||
button = 0; /* Indicates "OK" button is selected */
|
||||
print_button(dialog, "Cancel", y, x+14, FALSE);
|
||||
print_button(dialog, " OK ", y, x, TRUE);
|
||||
}
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
case ' ':
|
||||
case '\n':
|
||||
delwin(dialog);
|
||||
if (!button) {
|
||||
*result = '\0';
|
||||
for (i = 0; i < item_no; i++)
|
||||
if (status[i]) {
|
||||
strcpy(result, items[i*3]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(status);
|
||||
return button;
|
||||
case ESC:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delwin(dialog);
|
||||
free(status);
|
||||
return -1; /* ESC pressed */
|
||||
}
|
||||
/* End of dialog_radiolist() */
|
||||
|
||||
|
||||
/*
|
||||
* Print list item
|
||||
*/
|
||||
static void print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Clear 'residue' of last item */
|
||||
wattrset(win, menubox_attr);
|
||||
wmove(win, choice, 0);
|
||||
for (i = 0; i < list_width; i++)
|
||||
waddch(win, ' ');
|
||||
wmove(win, choice, check_x);
|
||||
wattrset(win, selected ? check_selected_attr : check_attr);
|
||||
wprintw(win, "(%c)", status ? '*' : ' ');
|
||||
wattrset(win, menubox_attr);
|
||||
waddch(win, ' ');
|
||||
wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
|
||||
waddch(win, tag[0]);
|
||||
wattrset(win, selected ? tag_selected_attr : tag_attr);
|
||||
waddstr(win, tag + 1);
|
||||
wmove(win, choice, item_x);
|
||||
wattrset(win, selected ? item_selected_attr : item_attr);
|
||||
waddstr(win, item);
|
||||
}
|
||||
/* End of print_item() */
|
375
gnu/lib/libdialog/rc.c
Normal file
375
gnu/lib/libdialog/rc.c
Normal file
@ -0,0 +1,375 @@
|
||||
/*
|
||||
* rc.c -- routines for processing the configuration file
|
||||
*
|
||||
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "dialog.priv.h"
|
||||
#include <dialog.h>
|
||||
#include "colors.h"
|
||||
#include "rc.h"
|
||||
|
||||
|
||||
static unsigned char *attr_to_str(int fg, int bg, int hl);
|
||||
static int str_to_attr(unsigned char *str, int *fg, int *bg, int *hl);
|
||||
static int parse_line(unsigned char *line, unsigned char **var, unsigned char **value);
|
||||
|
||||
|
||||
/*
|
||||
* Create the configuration file
|
||||
*/
|
||||
void 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() */
|
222
gnu/lib/libdialog/rc.h
Normal file
222
gnu/lib/libdialog/rc.h
Normal file
@ -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);
|
710
gnu/lib/libdialog/textbox.c
Normal file
710
gnu/lib/libdialog/textbox.c
Normal file
@ -0,0 +1,710 @@
|
||||
/*
|
||||
* textbox.c -- implements the text box
|
||||
*
|
||||
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "dialog.priv.h"
|
||||
#include <dialog.h>
|
||||
|
||||
|
||||
static void back_lines(int n);
|
||||
static void print_page(WINDOW *win, int height, int width);
|
||||
static void print_line(WINDOW *win, int row, int width);
|
||||
static unsigned char *get_line(void);
|
||||
static int get_search_term(WINDOW *win, unsigned char *search_term, int height, int width);
|
||||
static void print_position(WINDOW *win, int height, int width);
|
||||
|
||||
|
||||
static int hscroll = 0, fd, file_size, bytes_read, begin_reached = 1,
|
||||
end_reached = 0, page_length;
|
||||
static unsigned char *buf, *page;
|
||||
|
||||
|
||||
/*
|
||||
* Display text from a file in a dialog box.
|
||||
*/
|
||||
int dialog_textbox(unsigned char *title, unsigned char *file, int height, int width)
|
||||
{
|
||||
int i, x, y, cur_x, cur_y, fpos, key = 0, dir, temp, temp1;
|
||||
#ifdef HAVE_NCURSES
|
||||
int passed_end;
|
||||
#endif
|
||||
unsigned char search_term[MAX_LEN+1], *tempptr, *found;
|
||||
WINDOW *dialog, *text;
|
||||
|
||||
search_term[0] = '\0'; /* no search term entered yet */
|
||||
|
||||
/* Open input file for reading */
|
||||
if ((fd = open(file, O_RDONLY)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nCan't open input file in dialog_textbox().\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* Get file size. Actually, 'file_size' is the real file size - 1,
|
||||
since it's only the last byte offset from the beginning */
|
||||
if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* Restore file pointer to beginning of file after getting file size */
|
||||
if (lseek(fd, 0, SEEK_SET) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* Allocate space for read buffer */
|
||||
if ((buf = malloc(BUF_SIZE+1)) == NULL) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n");
|
||||
exit(-1);
|
||||
}
|
||||
if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError reading file in dialog_textbox().\n");
|
||||
exit(-1);
|
||||
}
|
||||
buf[bytes_read] = '\0'; /* mark end of valid data */
|
||||
page = buf; /* page is pointer to start of page to be displayed */
|
||||
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width)/2;
|
||||
y = (LINES - height)/2;
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
if (use_shadow)
|
||||
draw_shadow(stdscr, y, x, height, width);
|
||||
#endif
|
||||
dialog = newwin(height, width, y, x);
|
||||
keypad(dialog, TRUE);
|
||||
|
||||
/* Create window for text region, used for scrolling text */
|
||||
/* text = newwin(height-4, width-2, y+1, x+1); */
|
||||
text = subwin(dialog, height-4, width-2, y+1, x+1);
|
||||
keypad(text, TRUE);
|
||||
|
||||
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
|
||||
|
||||
wattrset(dialog, border_attr);
|
||||
wmove(dialog, height-3, 0);
|
||||
waddch(dialog, ACS_LTEE);
|
||||
for (i = 0; i < width-2; i++)
|
||||
waddch(dialog, ACS_HLINE);
|
||||
wattrset(dialog, dialog_attr);
|
||||
waddch(dialog, ACS_RTEE);
|
||||
wmove(dialog, height-2, 1);
|
||||
for (i = 0; i < width-2; i++)
|
||||
waddch(dialog, ' ');
|
||||
|
||||
if (title != NULL) {
|
||||
wattrset(dialog, title_attr);
|
||||
wmove(dialog, 0, (width - strlen(title))/2 - 1);
|
||||
waddch(dialog, ' ');
|
||||
waddstr(dialog, title);
|
||||
waddch(dialog, ' ');
|
||||
}
|
||||
print_button(dialog, " EXIT ", height-2, width/2-4, TRUE);
|
||||
wnoutrefresh(dialog);
|
||||
getyx(dialog, cur_y, cur_x); /* Save cursor position */
|
||||
|
||||
/* Print first page of text */
|
||||
attr_clear(text, height-4, width-2, dialog_attr);
|
||||
print_page(text, height-4, width-2);
|
||||
print_position(dialog, height, width);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
|
||||
while ((key != ESC) && (key != '\n')) {
|
||||
key = wgetch(dialog);
|
||||
switch (key) {
|
||||
case 'E': /* Exit */
|
||||
case 'e':
|
||||
delwin(dialog);
|
||||
free(buf);
|
||||
close(fd);
|
||||
return 0;
|
||||
case 'g': /* First page */
|
||||
case KEY_HOME:
|
||||
if (!begin_reached) {
|
||||
begin_reached = 1;
|
||||
/* First page not in buffer? */
|
||||
if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (fpos > bytes_read) { /* Yes, we have to read it in */
|
||||
if (lseek(fd, 0, SEEK_SET) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
|
||||
exit(-1);
|
||||
}
|
||||
if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError reading file in dialog_textbox().\n");
|
||||
exit(-1);
|
||||
}
|
||||
buf[bytes_read] = '\0';
|
||||
}
|
||||
page = buf;
|
||||
print_page(text, height-4, width-2);
|
||||
print_position(dialog, height, width);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
break;
|
||||
case 'G': /* Last page */
|
||||
#ifdef HAVE_NCURSES
|
||||
case KEY_END:
|
||||
#endif
|
||||
end_reached = 1;
|
||||
/* Last page not in buffer? */
|
||||
if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (fpos < file_size) { /* Yes, we have to read it in */
|
||||
if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
|
||||
exit(-1);
|
||||
}
|
||||
if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError reading file in dialog_textbox().\n");
|
||||
exit(-1);
|
||||
}
|
||||
buf[bytes_read] = '\0';
|
||||
}
|
||||
page = buf + bytes_read;
|
||||
back_lines(height-4);
|
||||
print_page(text, height-4, width-2);
|
||||
print_position(dialog, height, width);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
case 'K': /* Previous line */
|
||||
case 'k':
|
||||
case KEY_UP:
|
||||
if (!begin_reached) {
|
||||
back_lines(page_length+1);
|
||||
#ifdef HAVE_NCURSES
|
||||
/* We don't call print_page() here but use scrolling to ensure
|
||||
faster screen update. However, 'end_reached' and 'page_length'
|
||||
should still be updated, and 'page' should point to start of
|
||||
next page. This is done by calling get_line() in the following
|
||||
'for' loop. */
|
||||
scrollok(text, TRUE);
|
||||
wscrl(text, -1); /* Scroll text region down one line */
|
||||
scrollok(text, FALSE);
|
||||
page_length = 0;
|
||||
passed_end = 0;
|
||||
for (i = 0; i < height-4; i++) {
|
||||
if (!i) {
|
||||
print_line(text, 0, width-2); /* print first line of page */
|
||||
wnoutrefresh(text);
|
||||
}
|
||||
else
|
||||
get_line(); /* Called to update 'end_reached' and 'page' */
|
||||
if (!passed_end)
|
||||
page_length++;
|
||||
if (end_reached && !passed_end)
|
||||
passed_end = 1;
|
||||
}
|
||||
#else
|
||||
print_page(text, height-4, width-2);
|
||||
#endif
|
||||
print_position(dialog, height, width);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
break;
|
||||
case 'B': /* Previous page */
|
||||
case 'b':
|
||||
case KEY_PPAGE:
|
||||
if (!begin_reached) {
|
||||
back_lines(page_length + height-4);
|
||||
print_page(text, height-4, width-2);
|
||||
print_position(dialog, height, width);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
break;
|
||||
case 'J': /* Next line */
|
||||
case 'j':
|
||||
case KEY_DOWN:
|
||||
if (!end_reached) {
|
||||
begin_reached = 0;
|
||||
scrollok(text, TRUE);
|
||||
scroll(text); /* Scroll text region up one line */
|
||||
scrollok(text, FALSE);
|
||||
print_line(text, height-5, width-2);
|
||||
#ifndef HAVE_NCURSES
|
||||
wmove(text, height-5, 0);
|
||||
waddch(text, ' ');
|
||||
wmove(text, height-5, width-3);
|
||||
waddch(text, ' ');
|
||||
#endif
|
||||
wnoutrefresh(text);
|
||||
print_position(dialog, height, width);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
break;
|
||||
case ' ': /* Next page */
|
||||
case KEY_NPAGE:
|
||||
if (!end_reached) {
|
||||
begin_reached = 0;
|
||||
print_page(text, height-4, width-2);
|
||||
print_position(dialog, height, width);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
break;
|
||||
case '0': /* Beginning of line */
|
||||
case 'H': /* Scroll left */
|
||||
case 'h':
|
||||
case KEY_LEFT:
|
||||
if (hscroll > 0) {
|
||||
if (key == '0')
|
||||
hscroll = 0;
|
||||
else
|
||||
hscroll--;
|
||||
/* Reprint current page to scroll horizontally */
|
||||
back_lines(page_length);
|
||||
print_page(text, height-4, width-2);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
break;
|
||||
case 'L': /* Scroll right */
|
||||
case 'l':
|
||||
case KEY_RIGHT:
|
||||
if (hscroll < MAX_LEN) {
|
||||
hscroll++;
|
||||
/* Reprint current page to scroll horizontally */
|
||||
back_lines(page_length);
|
||||
print_page(text, height-4, width-2);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
break;
|
||||
case '/': /* Forward search */
|
||||
case 'n': /* Repeat forward search */
|
||||
case '?': /* Backward search */
|
||||
case 'N': /* Repeat backward search */
|
||||
/* set search direction */
|
||||
dir = (key == '/' || key == 'n') ? 1 : 0;
|
||||
if (dir ? !end_reached : !begin_reached) {
|
||||
if (key == 'n' || key == 'N') {
|
||||
if (search_term[0] == '\0') { /* No search term yet */
|
||||
fprintf(stderr, "\a"); /* beep */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else /* Get search term from user */
|
||||
if (get_search_term(text, search_term, height-4, width-2) == -1) {
|
||||
/* ESC pressed in get_search_term(). Reprint page to clear box */
|
||||
wattrset(text, dialog_attr);
|
||||
back_lines(page_length);
|
||||
print_page(text, height-4, width-2);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
}
|
||||
/* Save variables for restoring in case search term can't be found */
|
||||
tempptr = page;
|
||||
temp = begin_reached;
|
||||
temp1 = end_reached;
|
||||
if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
|
||||
exit(-1);
|
||||
}
|
||||
fpos -= bytes_read;
|
||||
/* update 'page' to point to next (previous) line before
|
||||
forward (backward) searching */
|
||||
back_lines(dir ? page_length-1 : page_length+1);
|
||||
found = NULL;
|
||||
if (dir) /* Forward search */
|
||||
while((found = strstr(get_line(), search_term)) == NULL) {
|
||||
if (end_reached)
|
||||
break;
|
||||
}
|
||||
else /* Backward search */
|
||||
while((found = strstr(get_line(), search_term)) == NULL) {
|
||||
if (begin_reached)
|
||||
break;
|
||||
back_lines(2);
|
||||
}
|
||||
if (found == NULL) { /* not found */
|
||||
fprintf(stderr, "\a"); /* beep */
|
||||
/* Restore program state to that before searching */
|
||||
if (lseek(fd, fpos, SEEK_SET) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
|
||||
exit(-1);
|
||||
}
|
||||
if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError reading file in dialog_textbox().\n");
|
||||
exit(-1);
|
||||
}
|
||||
buf[bytes_read] = '\0';
|
||||
page = tempptr;
|
||||
begin_reached = temp;
|
||||
end_reached = temp1;
|
||||
/* move 'page' to point to start of current page in order to
|
||||
re-print current page. Note that 'page' always points to
|
||||
start of next page, so this is necessary */
|
||||
back_lines(page_length);
|
||||
}
|
||||
else /* Search term found */
|
||||
back_lines(1);
|
||||
/* Reprint page */
|
||||
wattrset(text, dialog_attr);
|
||||
print_page(text, height-4, width-2);
|
||||
if (found != NULL)
|
||||
print_position(dialog, height, width);
|
||||
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
|
||||
wrefresh(dialog);
|
||||
}
|
||||
else /* no need to find */
|
||||
fprintf(stderr, "\a"); /* beep */
|
||||
break;
|
||||
case ESC:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delwin(dialog);
|
||||
free(buf);
|
||||
close(fd);
|
||||
return -1; /* ESC pressed */
|
||||
}
|
||||
/* End of dialog_textbox() */
|
||||
|
||||
|
||||
/*
|
||||
* Go back 'n' lines in text file. Called by dialog_textbox().
|
||||
* 'page' will be updated to point to the desired line in 'buf'.
|
||||
*/
|
||||
static void back_lines(int n)
|
||||
{
|
||||
int i, fpos;
|
||||
|
||||
begin_reached = 0;
|
||||
/* We have to distinguish between end_reached and !end_reached since at end
|
||||
of file, the line is not ended by a '\n'. The code inside 'if' basically
|
||||
does a '--page' to move one character backward so as to skip '\n' of the
|
||||
previous line */
|
||||
if (!end_reached) {
|
||||
/* Either beginning of buffer or beginning of file reached? */
|
||||
if (page == buf) {
|
||||
if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in back_lines().\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (fpos > bytes_read) { /* Not beginning of file yet */
|
||||
/* We've reached beginning of buffer, but not beginning of file yet,
|
||||
so read previous part of file into buffer. Note that we only
|
||||
move backward for BUF_SIZE/2 bytes, but not BUF_SIZE bytes to
|
||||
avoid re-reading again in print_page() later */
|
||||
/* Really possible to move backward BUF_SIZE/2 bytes? */
|
||||
if (fpos < BUF_SIZE/2 + bytes_read) {
|
||||
/* No, move less then */
|
||||
if (lseek(fd, 0, SEEK_SET) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in back_lines().\n");
|
||||
exit(-1);
|
||||
}
|
||||
page = buf + fpos - bytes_read;
|
||||
}
|
||||
else { /* Move backward BUF_SIZE/2 bytes */
|
||||
if (lseek(fd, -(BUF_SIZE/2 + bytes_read), SEEK_CUR) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in back_lines().\n");
|
||||
exit(-1);
|
||||
}
|
||||
page = buf + BUF_SIZE/2;
|
||||
}
|
||||
if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError reading file in back_lines().\n");
|
||||
exit(-1);
|
||||
}
|
||||
buf[bytes_read] = '\0';
|
||||
}
|
||||
else { /* Beginning of file reached */
|
||||
begin_reached = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (*(--page) != '\n') { /* '--page' here */
|
||||
/* Something's wrong... */
|
||||
endwin();
|
||||
fprintf(stderr, "\nInternal error in back_lines().\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Go back 'n' lines */
|
||||
for (i = 0; i < n; i++)
|
||||
do {
|
||||
if (page == buf) {
|
||||
if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in back_lines().\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (fpos > bytes_read) {
|
||||
/* Really possible to move backward BUF_SIZE/2 bytes? */
|
||||
if (fpos < BUF_SIZE/2 + bytes_read) {
|
||||
/* No, move less then */
|
||||
if (lseek(fd, 0, SEEK_SET) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in back_lines().\n");
|
||||
exit(-1);
|
||||
}
|
||||
page = buf + fpos - bytes_read;
|
||||
}
|
||||
else { /* Move backward BUF_SIZE/2 bytes */
|
||||
if (lseek(fd, -(BUF_SIZE/2 + bytes_read), SEEK_CUR) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in back_lines().\n");
|
||||
exit(-1);
|
||||
}
|
||||
page = buf + BUF_SIZE/2;
|
||||
}
|
||||
if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError reading file in back_lines().\n");
|
||||
exit(-1);
|
||||
}
|
||||
buf[bytes_read] = '\0';
|
||||
}
|
||||
else { /* Beginning of file reached */
|
||||
begin_reached = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} while (*(--page) != '\n');
|
||||
page++;
|
||||
}
|
||||
/* End of back_lines() */
|
||||
|
||||
|
||||
/*
|
||||
* Print a new page of text. Called by dialog_textbox().
|
||||
*/
|
||||
static void print_page(WINDOW *win, int height, int width)
|
||||
{
|
||||
int i, passed_end = 0;
|
||||
|
||||
page_length = 0;
|
||||
for (i = 0; i < height; i++) {
|
||||
print_line(win, i, width);
|
||||
if (!passed_end)
|
||||
page_length++;
|
||||
if (end_reached && !passed_end)
|
||||
passed_end = 1;
|
||||
}
|
||||
wnoutrefresh(win);
|
||||
}
|
||||
/* End of print_page() */
|
||||
|
||||
|
||||
/*
|
||||
* Print a new line of text. Called by dialog_textbox() and print_page().
|
||||
*/
|
||||
static void print_line(WINDOW *win, int row, int width)
|
||||
{
|
||||
int i, y, x;
|
||||
unsigned char *line;
|
||||
|
||||
line = get_line();
|
||||
line += MIN(strlen(line),hscroll); /* Scroll horizontally */
|
||||
wmove(win, row, 0); /* move cursor to correct line */
|
||||
waddch(win,' ');
|
||||
#ifdef HAVE_NCURSES
|
||||
waddnstr(win, line, MIN(strlen(line),width-2));
|
||||
#else
|
||||
line[MIN(strlen(line),width-2)] = '\0';
|
||||
waddstr(win, line);
|
||||
#endif
|
||||
|
||||
getyx(win, y, x);
|
||||
/* Clear 'residue' of previous line */
|
||||
for (i = 0; i < width-x; i++)
|
||||
waddch(win, ' ');
|
||||
}
|
||||
/* End of print_line() */
|
||||
|
||||
|
||||
/*
|
||||
* Return current line of text. Called by dialog_textbox() and print_line().
|
||||
* 'page' should point to start of current line before calling, and will be
|
||||
* updated to point to start of next line.
|
||||
*/
|
||||
static unsigned char *get_line(void)
|
||||
{
|
||||
int i = 0, fpos;
|
||||
static unsigned char line[MAX_LEN+1];
|
||||
|
||||
end_reached = 0;
|
||||
while (*page != '\n') {
|
||||
if (*page == '\0') { /* Either end of file or end of buffer reached */
|
||||
if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in get_line().\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (fpos < file_size) { /* Not end of file yet */
|
||||
/* We've reached end of buffer, but not end of file yet, so read next
|
||||
part of file into buffer */
|
||||
if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError reading file in get_line().\n");
|
||||
exit(-1);
|
||||
}
|
||||
buf[bytes_read] = '\0';
|
||||
page = buf;
|
||||
}
|
||||
else {
|
||||
if (!end_reached)
|
||||
end_reached = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (i < MAX_LEN)
|
||||
line[i++] = *(page++);
|
||||
else {
|
||||
if (i == MAX_LEN) /* Truncate lines longer than MAX_LEN characters */
|
||||
line[i++] = '\0';
|
||||
page++;
|
||||
}
|
||||
}
|
||||
if (i <= MAX_LEN)
|
||||
line[i] = '\0';
|
||||
if (!end_reached)
|
||||
page++; /* move pass '\n' */
|
||||
|
||||
return line;
|
||||
}
|
||||
/* End of get_line() */
|
||||
|
||||
|
||||
/*
|
||||
* Display a dialog box and get the search term from user
|
||||
*/
|
||||
static int get_search_term(WINDOW *win, unsigned char *search_term, int height, int width)
|
||||
{
|
||||
int i, x, y, input_x = 0, scroll = 0, key = 0,
|
||||
box_height = 3, box_width = 30;
|
||||
|
||||
x = (width - box_width)/2;
|
||||
y = (height - box_height)/2;
|
||||
#ifdef HAVE_NCURSES
|
||||
if (use_shadow)
|
||||
draw_shadow(win, y, x, box_height, box_width);
|
||||
#endif
|
||||
draw_box(win, y, x, box_height, box_width, dialog_attr, searchbox_border_attr);
|
||||
wattrset(win, searchbox_title_attr);
|
||||
wmove(win, y, x+box_width/2-4);
|
||||
waddstr(win, " Search ");
|
||||
|
||||
box_width -= 2;
|
||||
wmove(win, y+1, x+1);
|
||||
wrefresh(win);
|
||||
search_term[0] = '\0';
|
||||
wattrset(win, searchbox_attr);
|
||||
while (key != ESC) {
|
||||
key = wgetch(win);
|
||||
switch (key) {
|
||||
case '\n':
|
||||
if (search_term[0] != '\0')
|
||||
return 0;
|
||||
break;
|
||||
case KEY_BACKSPACE:
|
||||
if (input_x || scroll) {
|
||||
if (!input_x) {
|
||||
scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
|
||||
wmove(win, y+1, x+1);
|
||||
for (i = 0; i < box_width; i++)
|
||||
waddch(win, search_term[scroll+input_x+i] ?
|
||||
search_term[scroll+input_x+i] : ' ');
|
||||
input_x = strlen(search_term) - scroll;
|
||||
}
|
||||
else
|
||||
input_x--;
|
||||
search_term[scroll+input_x] = '\0';
|
||||
wmove(win, y+1, input_x + x+1);
|
||||
waddch(win, ' ');
|
||||
wmove(win, y+1, input_x + x+1);
|
||||
wrefresh(win);
|
||||
}
|
||||
break;
|
||||
case ESC:
|
||||
break;
|
||||
default:
|
||||
if (isprint(key))
|
||||
if (scroll+input_x < MAX_LEN) {
|
||||
search_term[scroll+input_x] = key;
|
||||
search_term[scroll+input_x+1] = '\0';
|
||||
if (input_x == box_width-1) {
|
||||
scroll++;
|
||||
wmove(win, y+1, x+1);
|
||||
for (i = 0; i < box_width-1; i++)
|
||||
waddch(win, search_term[scroll+i]);
|
||||
}
|
||||
else {
|
||||
wmove(win, y+1, input_x++ + x+1);
|
||||
waddch(win, key);
|
||||
}
|
||||
wrefresh(win);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1; /* ESC pressed */
|
||||
}
|
||||
/* End of get_search_term() */
|
||||
|
||||
|
||||
/*
|
||||
* Print current position
|
||||
*/
|
||||
static void print_position(WINDOW *win, int height, int width)
|
||||
{
|
||||
int fpos, percent;
|
||||
|
||||
if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
|
||||
endwin();
|
||||
fprintf(stderr, "\nError moving file pointer in print_position().\n");
|
||||
exit(-1);
|
||||
}
|
||||
wattrset(win, position_indicator_attr);
|
||||
percent = !file_size ? 100 : ((fpos-bytes_read+page-buf)*100)/file_size;
|
||||
wmove(win, height-3, width-9);
|
||||
wprintw(win, "(%3d%%)", percent);
|
||||
}
|
||||
/* End of print_position() */
|
114
gnu/lib/libdialog/yesno.c
Normal file
114
gnu/lib/libdialog/yesno.c
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* yesno.c -- implements the yes/no box
|
||||
*
|
||||
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "dialog.priv.h"
|
||||
#include <dialog.h>
|
||||
|
||||
|
||||
/*
|
||||
* Display a dialog box with two buttons - Yes and No
|
||||
*/
|
||||
int dialog_yesno(unsigned char *title, unsigned char * prompt, int height, int width)
|
||||
{
|
||||
int i, x, y, key = 0, button = 0;
|
||||
WINDOW *dialog;
|
||||
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width)/2;
|
||||
y = (LINES - height)/2;
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
if (use_shadow)
|
||||
draw_shadow(stdscr, y, x, height, width);
|
||||
#endif
|
||||
dialog = newwin(height, width, y, x);
|
||||
keypad(dialog, TRUE);
|
||||
|
||||
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
|
||||
wattrset(dialog, border_attr);
|
||||
wmove(dialog, height-3, 0);
|
||||
waddch(dialog, ACS_LTEE);
|
||||
for (i = 0; i < width-2; i++)
|
||||
waddch(dialog, ACS_HLINE);
|
||||
wattrset(dialog, dialog_attr);
|
||||
waddch(dialog, ACS_RTEE);
|
||||
wmove(dialog, height-2, 1);
|
||||
for (i = 0; i < width-2; i++)
|
||||
waddch(dialog, ' ');
|
||||
|
||||
if (title != NULL) {
|
||||
wattrset(dialog, title_attr);
|
||||
wmove(dialog, 0, (width - strlen(title))/2 - 1);
|
||||
waddch(dialog, ' ');
|
||||
waddstr(dialog, title);
|
||||
waddch(dialog, ' ');
|
||||
}
|
||||
wattrset(dialog, dialog_attr);
|
||||
print_autowrap(dialog, prompt, width, 1, 3);
|
||||
|
||||
x = width/2-10;
|
||||
y = height-2;
|
||||
print_button(dialog, " No ", y, x+13, FALSE);
|
||||
print_button(dialog, " Yes ", y, x, TRUE);
|
||||
wrefresh(dialog);
|
||||
|
||||
while (key != ESC) {
|
||||
key = wgetch(dialog);
|
||||
switch (key) {
|
||||
case 'Y':
|
||||
case 'y':
|
||||
delwin(dialog);
|
||||
return 0;
|
||||
case 'N':
|
||||
case 'n':
|
||||
delwin(dialog);
|
||||
return 1;
|
||||
case KEY_BTAB:
|
||||
case TAB:
|
||||
case KEY_UP:
|
||||
case KEY_DOWN:
|
||||
case KEY_LEFT:
|
||||
case KEY_RIGHT:
|
||||
if (!button) {
|
||||
button = 1; /* Indicates "No" button is selected */
|
||||
print_button(dialog, " Yes ", y, x, FALSE);
|
||||
print_button(dialog, " No ", y, x+13, TRUE);
|
||||
}
|
||||
else {
|
||||
button = 0; /* Indicates "Yes" button is selected */
|
||||
print_button(dialog, " No ", y, x+13, FALSE);
|
||||
print_button(dialog, " Yes ", y, x, TRUE);
|
||||
}
|
||||
wrefresh(dialog);
|
||||
break;
|
||||
case ' ':
|
||||
case '\n':
|
||||
delwin(dialog);
|
||||
return button;
|
||||
case ESC:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delwin(dialog);
|
||||
return -1; /* ESC pressed */
|
||||
}
|
||||
/* End of dialog_yesno() */
|
Loading…
Reference in New Issue
Block a user