This commit was generated by cvs2svn to compensate for changes in r174996,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
parent
ca7562e9c2
commit
45ed6d05ba
@ -1,38 +0,0 @@
|
||||
#! /bin/sh
|
||||
# mkinstalldirs --- make directory hierarchy
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1993-05-16
|
||||
# Last modified: 1994-03-25
|
||||
# Public domain
|
||||
#
|
||||
|
||||
errstatus=0
|
||||
umask 022
|
||||
|
||||
for file in ${1+"$@"} ; do
|
||||
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
|
||||
shift
|
||||
|
||||
pathcomp=
|
||||
for d in ${1+"$@"} ; do
|
||||
pathcomp="$pathcomp$d"
|
||||
case "$pathcomp" in
|
||||
-* ) pathcomp=./$pathcomp ;;
|
||||
esac
|
||||
|
||||
if test ! -d "$pathcomp"; then
|
||||
echo "mkdir $pathcomp" 1>&2
|
||||
case "$pathcomp" in
|
||||
[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]: )
|
||||
;; # DOSISH systems
|
||||
* ) mkdir "$pathcomp" || errstatus=$? ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
pathcomp="$pathcomp/"
|
||||
done
|
||||
done
|
||||
|
||||
exit $errstatus
|
||||
|
||||
# mkinstalldirs ends here
|
@ -1,340 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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
|
||||
|
||||
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) <year> <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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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) year 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.
|
@ -1,49 +0,0 @@
|
||||
|
||||
Current history:
|
||||
|
||||
2006/11/25 Fixes for ncurses tparm() prototype.
|
||||
2006/06/24 1.02 Modify to support ncurses extended string capabilities.
|
||||
2003/10/18 1.01 Fix some logic in pad.c, improve bce test.
|
||||
2003/09/20 Modified to allow running from compiled-in terminfo.
|
||||
2001/10/20 Make menu titles agree with descriptions.
|
||||
2000/03/04 Fix a few spelling errors
|
||||
1999/09/04 Minor fix to build/link on BeOS
|
||||
1999/05/16 Minor fix to build/link on CLIX
|
||||
1999/05/09 Update to build/link on NeXT
|
||||
1999/04/17 Update to work with ncurses 5.0 beta1 (TERMTYPE struct)
|
||||
1999/02/07 Build with ncurses 4.2 981219 (renamed function)
|
||||
1998/01/09 1.00 First release under GPL
|
||||
1997/12/24 0.02 First version that requires ncurses
|
||||
1997/10/29 0.01 Second beta release to the ncurses mailing list.
|
||||
1997/10/06 0.00 First beta release to the ncurses mailing list.
|
||||
|
||||
Ancient history: TACK -- the terminfo action checker
|
||||
|
||||
The purpose of this program is to verify the correctness of
|
||||
terminfos and to calculate the pads needed for each capability.
|
||||
This program is not designed to test curses and therefore uses
|
||||
as little of curses as possible.
|
||||
|
||||
This program was originally called TED. In 1991 it was
|
||||
released to USENET in comp.sources. TED was originally written to
|
||||
test both terminfos and termcaps. The original intent was to
|
||||
create a terminfo editor. This code fell quite short of its goal.
|
||||
Tests were controlled by command line switches and editing was done
|
||||
with pen and paper.
|
||||
|
||||
In 1995 Eric S. Raymond got interested in the program and added
|
||||
a first cut at making the program menu driven. He also converted
|
||||
the code from K&R C to an ANSI/POSIX-conforming C. He re-christened
|
||||
the program TAC (Terminfo Action Checker). Eric also wrote a man
|
||||
page for TAC.
|
||||
|
||||
In 1997 I decided to dust off the code and make it easier to
|
||||
use by the novice. I totally rewrote the menu system and added
|
||||
the editing features I originally planned for TED. I also did
|
||||
a total rewrite of the code that does the timings. In the process
|
||||
of rewriting the code I changed it to be more tightly coupled
|
||||
with ncurses. By this time someone had taken the name TAC so
|
||||
I re-christened the program TACK.
|
||||
|
||||
Daniel Weaver
|
||||
<danw@znyx.com>
|
@ -1,211 +0,0 @@
|
||||
# $Id: Makefile.in,v 1.38 2006/12/17 15:58:32 tom Exp $
|
||||
##############################################################################
|
||||
# Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. #
|
||||
# #
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a #
|
||||
# copy of this software and associated documentation files (the "Software"), #
|
||||
# to deal in the Software without restriction, including without limitation #
|
||||
# the rights to use, copy, modify, merge, publish, distribute, distribute #
|
||||
# with modifications, sublicense, and/or sell copies of the Software, and to #
|
||||
# permit persons to whom the Software is furnished to do so, subject to the #
|
||||
# following conditions: #
|
||||
# #
|
||||
# The above copyright notice and this permission notice shall be included in #
|
||||
# all copies or substantial portions of the Software. #
|
||||
# #
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL #
|
||||
# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER #
|
||||
# DEALINGS IN THE SOFTWARE. #
|
||||
# #
|
||||
# Except as contained in this notice, the name(s) of the above copyright #
|
||||
# holders shall not be used in advertising or otherwise to promote the sale, #
|
||||
# use or other dealings in this Software without prior written #
|
||||
# authorization. #
|
||||
##############################################################################
|
||||
# Makefile for tack
|
||||
#
|
||||
# The variable 'srcdir' refers to the source-distribution, and can be set with
|
||||
# the configure script by "--srcdir=DIR".
|
||||
#
|
||||
# The rules are organized to produce the libraries for the configured models,
|
||||
# and the programs with the configured default model.
|
||||
|
||||
# turn off _all_ suffix rules; we'll generate our own
|
||||
.SUFFIXES:
|
||||
|
||||
SHELL = /bin/sh
|
||||
THIS = Makefile
|
||||
|
||||
CF_MFLAGS = @cf_cv_makeflags@
|
||||
@SET_MAKE@
|
||||
|
||||
x = @EXEEXT@
|
||||
o = .@OBJEXT@
|
||||
|
||||
MODEL = ../@DFT_OBJ_SUBDIR@
|
||||
DESTDIR = @DESTDIR@
|
||||
srcdir = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
datadir = @datadir@
|
||||
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIBTOOL_CLEAN = @LIB_CLEAN@
|
||||
LIBTOOL_COMPILE = @LIB_COMPILE@
|
||||
LIBTOOL_LINK = @LIB_LINK@
|
||||
LIBTOOL_INSTALL = @LIB_INSTALL@
|
||||
LIBTOOL_UNINSTALL = @LIB_UNINSTALL@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROG = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
AWK = @AWK@
|
||||
LN_S = @LN_S@
|
||||
|
||||
CC = @CC@
|
||||
CPP = @CPP@
|
||||
CFLAGS = @CFLAGS@
|
||||
|
||||
INCDIR = $(srcdir)/../include
|
||||
CPPFLAGS = -DHAVE_CONFIG_H -I../tack -I$(srcdir) @CPPFLAGS@
|
||||
|
||||
CCFLAGS = $(CPPFLAGS) $(CFLAGS)
|
||||
|
||||
CFLAGS_LIBTOOL = $(CCFLAGS)
|
||||
CFLAGS_NORMAL = $(CCFLAGS)
|
||||
CFLAGS_DEBUG = $(CCFLAGS) @CC_G_OPT@ -DTRACE
|
||||
CFLAGS_PROFILE = $(CCFLAGS) -pg
|
||||
CFLAGS_SHARED = $(CCFLAGS) @CC_SHARED_OPTS@
|
||||
|
||||
CFLAGS_DEFAULT = $(CFLAGS_@DFT_UPR_MODEL@)
|
||||
|
||||
REL_VERSION = @cf_cv_rel_version@
|
||||
ABI_VERSION = @cf_cv_abi_version@
|
||||
LOCAL_LIBDIR = @top_builddir@/lib
|
||||
|
||||
LD = @LD@
|
||||
LINK = @LINK_PROGS@ $(LIBTOOL_LINK) $(CC)
|
||||
LDFLAGS = @EXTRA_LDFLAGS@ \
|
||||
@TINFO_ARGS@ @LDFLAGS@ @LD_MODEL@ @LIBS@
|
||||
|
||||
LDFLAGS_LIBTOOL = $(LDFLAGS) $(CFLAGS_LIBTOOL)
|
||||
LDFLAGS_NORMAL = $(LDFLAGS) $(CFLAGS_NORMAL)
|
||||
LDFLAGS_DEBUG = $(LDFLAGS) $(CFLAGS_DEBUG)
|
||||
LDFLAGS_PROFILE = $(LDFLAGS) $(CFLAGS_PROFILE)
|
||||
LDFLAGS_SHARED = $(LDFLAGS) $(CFLAGS_SHARED) @LD_SHARED_OPTS@
|
||||
|
||||
LDFLAGS_DEFAULT = $(LDFLAGS_@DFT_UPR_MODEL@)
|
||||
|
||||
LINT = @LINT@
|
||||
LINT_OPTS = @LINT_OPTS@
|
||||
LINT_LIBS = -lncurses@LIB_SUFFIX@ @LIBS@
|
||||
|
||||
PROGS = tack$x
|
||||
|
||||
# Default library, for linking applications
|
||||
DEPS_CURSES = ../lib/@LIB_PREFIX@ncurses@DFT_DEP_SUFFIX@
|
||||
|
||||
################################################################################
|
||||
all: $(PROGS)
|
||||
|
||||
sources:
|
||||
|
||||
install: install.tack
|
||||
uninstall: uninstall.tack
|
||||
|
||||
# this line simplifies the configure-script
|
||||
libs \
|
||||
install.libs \
|
||||
uninstall.libs:
|
||||
|
||||
EDITARGS = $(DESTDIR)$(mandir) $(srcdir) $(srcdir)/*.[0-9]*
|
||||
|
||||
install.tack: $(PROGS) \
|
||||
$(DESTDIR)$(bindir) \
|
||||
$(DESTDIR)$(mandir)
|
||||
$(LIBTOOL_INSTALL) $(INSTALL_PROG) tack$x $(DESTDIR)$(bindir)/tack$x
|
||||
sh ../edit_man.sh normal installing $(EDITARGS)
|
||||
|
||||
uninstall.tack:
|
||||
-@$(LIBTOOL_UNINSTALL) rm -f $(DESTDIR)$(bindir)/tack$x
|
||||
-sh ../edit_man.sh normal removing $(EDITARGS)
|
||||
|
||||
$(DESTDIR)$(bindir) \
|
||||
$(DESTDIR)$(mandir) :
|
||||
sh $(srcdir)/../mkinstalldirs $@
|
||||
|
||||
#
|
||||
# Rules for building tack
|
||||
#
|
||||
|
||||
DEPS_TACK = \
|
||||
$(MODEL)/ansi$o \
|
||||
$(MODEL)/charset$o \
|
||||
$(MODEL)/color$o \
|
||||
$(MODEL)/control$o \
|
||||
$(MODEL)/crum$o \
|
||||
$(MODEL)/edit$o \
|
||||
$(MODEL)/fun$o \
|
||||
$(MODEL)/init$o \
|
||||
$(MODEL)/menu$o \
|
||||
$(MODEL)/modes$o \
|
||||
$(MODEL)/output$o \
|
||||
$(MODEL)/pad$o \
|
||||
$(MODEL)/scan$o \
|
||||
$(MODEL)/sync$o \
|
||||
$(MODEL)/sysdep$o \
|
||||
$(MODEL)/tack$o
|
||||
|
||||
tack$x: $(DEPS_TACK) $(DEPS_CURSES)
|
||||
@ECHO_LINK@ $(LINK) $(DEPS_TACK) $(LDFLAGS_DEFAULT) -o $@
|
||||
|
||||
#
|
||||
# Utility productions start here
|
||||
#
|
||||
|
||||
tags:
|
||||
ctags *.[ch]
|
||||
|
||||
@MAKE_UPPER_TAGS@TAGS:
|
||||
@MAKE_UPPER_TAGS@ etags *.[ch]
|
||||
|
||||
mostlyclean ::
|
||||
-rm -f core tags TAGS *~ *.bak *.i *.atac trace
|
||||
|
||||
clean :: mostlyclean
|
||||
-sh -c "if test -n '$x' ; then $(MAKE) clean x=''; fi"
|
||||
-rm -f $(PROGS)
|
||||
-rm -rf .libs
|
||||
|
||||
distclean :: clean
|
||||
-rm -f Makefile
|
||||
|
||||
realclean :: distclean
|
||||
|
||||
tack.tar: Makefile.in modules *.[ch] tack.1 HISTORY COPYING
|
||||
tar -cvf tack.tar Makefile.in modules *.[ch] tack.1 HISTORY COPYING
|
||||
|
||||
# These rules are used to allow "make -n" to work on a clean directory-tree
|
||||
../include/hashsize.h \
|
||||
../include/parametrized.h \
|
||||
../include/term.h :
|
||||
cd ../include; $(MAKE) $(CF_MFLAGS)
|
||||
|
||||
$(DEPS_CURSES) :
|
||||
cd ../ncurses; $(MAKE) $(CF_MFLAGS)
|
||||
|
||||
lint:
|
||||
$(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/*.c $(LINT_LIBS)
|
||||
|
||||
###############################################################################
|
||||
# The remainder of this file is automatically generated during configuration
|
||||
###############################################################################
|
@ -1,14 +0,0 @@
|
||||
-- $Id: README,v 1.2 2000/03/12 02:39:12 Daniel.Weaver Exp $
|
||||
|
||||
The 'tack' program is a diagnostic that is designed to create and
|
||||
verify the correctness of terminfo's. This program can be used to
|
||||
create new terminal descriptions that are not included in the standard
|
||||
release. Although 'tack' is distributed with ncurses, it is not an
|
||||
integral part of ncurses. It may be removed from the release without
|
||||
limiting the usefulness of ncurses on those terminals described in the
|
||||
terminfo data base. The best way to remove 'tack' from the build is
|
||||
to delete or rename the 'tack' directory before running the configure
|
||||
script.
|
||||
|
||||
Unlike most of ncurses the 'tack' program is covered under the GNU
|
||||
Public License.
|
@ -1,854 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <tack.h>
|
||||
|
||||
MODULE_ID("$Id: ansi.c,v 1.10 2005/09/17 19:49:16 tom Exp $")
|
||||
|
||||
/*
|
||||
* Standalone tests for ANSI terminals. Three entry points:
|
||||
* test_ansi_graphics(), test_ansi_reports() and test_ansi_sgr().
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Test ANSI status reports
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ASCII control characters */
|
||||
#define A_DC1 0x11 /* Control Q */
|
||||
#define A_DC3 0x13 /* Control S */
|
||||
#define A_ESC 0x1b
|
||||
#define A_DCS 0x90
|
||||
#define A_CSI 0x9b
|
||||
#define A_ST 0x9c
|
||||
|
||||
#define MAX_MODES 256
|
||||
|
||||
static char default_bank[] = "\033(B\017";
|
||||
static int private_use, ape, terminal_class;
|
||||
static short ansi_value[256];
|
||||
static unsigned char ansi_buf[512], pack_buf[512];
|
||||
|
||||
struct ansi_reports {
|
||||
int lvl, final;
|
||||
const char *text;
|
||||
const char *request;
|
||||
};
|
||||
|
||||
static struct ansi_reports report_list[] = {
|
||||
{0, 'c', "(DA) Primary device attributes", "\033[0c"},
|
||||
{1, 0, "(DSR) Terminal status", "\033[5n"},
|
||||
{1, 'R', "(DSR) Cursor position", "\033[6n"},
|
||||
{62, 0, "(DA) Secondary device attributes", "\033[>0c"},
|
||||
{62, 0, "(DSR) Printer status", "\033[?15n"},
|
||||
{62, 0, "(DSR) Function key definition", "\033[?25n"},
|
||||
{62, 0, "(DSR) Keyboard language", "\033[?26n"},
|
||||
{63, 0, "(DECRQSS) Data destination", "\033P$q$}\033\\"},
|
||||
{63, 0, "(DECRQSS) Status line type", "\033P$q$~\033\\"},
|
||||
{63, 0, "(DECRQSS) Erase attribute", "\033P$q\"q\033\\"},
|
||||
{63, 0, "(DECRQSS) Personality", "\033P$q\"p\033\\"},
|
||||
{63, 0, "(DECRQSS) Top and bottom margins", "\033P$qr\033\\"},
|
||||
{63, 0, "(DECRQSS) Character attributes", "\033P$qm\033\\"},
|
||||
{63, 0, "(DECRQSS) Illegal request", "\033P$q@\033\\"},
|
||||
{63, 0, "(DECRQUPSS) User pref supplemental set", "\033[&u"},
|
||||
{63, 0, "(DECRQPSR) Cursor information", "\033[1$w"},
|
||||
{63, 0, "(DECRQPSR) Tab stop information", "\033[2$w"},
|
||||
{64, 0, "(DA) Tertiary device attributes", "\033[=0c"},
|
||||
{64, 0, "(DSR) Extended cursor position", "\033[?6n"},
|
||||
{64, 0, "(DSR) Macro space", "\033[?62n"},
|
||||
{64, 0, "(DSR) Memory checksum", "\033[?63n"},
|
||||
{64, 0, "(DSR) Data integrity", "\033[?75n"},
|
||||
{64, 0, "(DSR) Multiple session status", "\033[?85n"},
|
||||
{64, 0, "(DECRQSS) Attribute change extent", "\033P$q*x\033\\"},
|
||||
{64, 0, "(DECRQSS) Columns per page", "\033P$q$|\033\\"},
|
||||
{64, 0, "(DECRQSS) Lines per page", "\033P$qt\033\\"},
|
||||
{64, 0, "(DECRQSS) Lines per screen", "\033P$q*|\033\\"},
|
||||
{64, 0, "(DECRQSS) Left and right margins", "\033P$qs\033\\"},
|
||||
{64, 0, "(DECRQSS) Local functions", "\033P$q+q\033\\"},
|
||||
{64, 0, "(DECRQSS) Local function key control", "\033P$q=}\033\\"},
|
||||
{64, 0, "(DECRQSS) Select modifier key reporting", "\033P$q+r\033\\"},
|
||||
{64, 0, "(DECRQDE) Window report", "\033[\"v"},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
struct request_control {
|
||||
const char *text;
|
||||
const char *expect;
|
||||
const char *request;
|
||||
const char *set_mode;
|
||||
const char *reset_mode;
|
||||
};
|
||||
|
||||
/* Request control function selection or setting */
|
||||
static const struct request_control rqss[] = {
|
||||
{"Data sent to screen", "0", "$}", "\033[0$}", 0},
|
||||
{"Data sent to disabled status line", "0", "$}", 0, 0},
|
||||
{"\033[0$~\033[1$}", "\033[0$}", 0, 0, 0},
|
||||
{"Data sent to enabled status line", "1", "$}", 0, 0},
|
||||
{"\033[2$~\033[1$}", "\033[0$}", 0, 0, 0},
|
||||
{"Disable status line", "0", "$~", "\033[0$~", 0},
|
||||
{"Top status line", "1", "$~", "\033[1$~", 0},
|
||||
{"Bottom status line", "2", "$~", "\033[2$~", 0},
|
||||
{"Erasable character", "0", "\"q", "\033[0\"q", 0},
|
||||
{"Nonerasable character", "1", "\"q", "\033[1\"q", "\033[0\"q"},
|
||||
{"Top and bottom margins", "3;10", "r", "\0337\033[3;10r", 0},
|
||||
{"\033[r\0338", 0, 0, 0, 0},
|
||||
{"Top and bottom margins", "default", "r", "\0337\033[r", "\0338"},
|
||||
{"Character attributes, dim, bold", "1", "m", "\033[2;1m", "\033[m"},
|
||||
{"Character attributes, bold, dim", "2", "m", "\033[1;2m", "\033[m"},
|
||||
{"Character attributes, under, rev", "4;7", "m", "\033[4;7m", "\033[m"},
|
||||
{"Character attributes, color", "35;42", "m", "\033[35;42m", "\033[m"},
|
||||
{"All character attributes", "", "m", "\033[1;2;3;4;5;6;7;8;9m", 0},
|
||||
{"\033[m", 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** read_ansi()
|
||||
**
|
||||
** read an ANSI status report from terminal
|
||||
*/
|
||||
static void
|
||||
read_ansi(void)
|
||||
{
|
||||
int ch, i, j, last_escape;
|
||||
|
||||
fflush(stdout);
|
||||
read_key((char *)ansi_buf, sizeof(ansi_buf));
|
||||
/* Throw away control characters inside CSI sequences.
|
||||
Convert two character 7-bit sequences into 8-bit sequences. */
|
||||
for (i = j = last_escape = 0; (ch = ansi_buf[i]) != 0; i++) {
|
||||
if (ch == A_ESC) {
|
||||
if (last_escape == A_ESC) {
|
||||
pack_buf[j++] = A_ESC;
|
||||
}
|
||||
last_escape = A_ESC;
|
||||
} else
|
||||
if (last_escape == A_ESC && ch >= '@' && ch <= '_') {
|
||||
pack_buf[j++] = last_escape = ch + 0x40;
|
||||
} else
|
||||
if (last_escape != A_CSI || (ch > 0x20 && ch != 0x80)) {
|
||||
if (last_escape == A_ESC) {
|
||||
pack_buf[j++] = A_ESC;
|
||||
}
|
||||
if (ch > 0x80 && ch < 0xa0) {
|
||||
last_escape = ch;
|
||||
}
|
||||
pack_buf[j++] = ch;
|
||||
}
|
||||
}
|
||||
if (last_escape == A_ESC) {
|
||||
pack_buf[j++] = A_ESC;
|
||||
}
|
||||
pack_buf[j] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** valid_mode(expected)
|
||||
**
|
||||
** read a terminal mode status report and parse the result
|
||||
** Return TRUE if we got the expected terminating character.
|
||||
*/
|
||||
static int
|
||||
valid_mode(int expected)
|
||||
{
|
||||
unsigned char *s;
|
||||
int ch, terminator;
|
||||
|
||||
read_ansi();
|
||||
|
||||
ape = 0;
|
||||
ch = UChar(pack_buf[0]);
|
||||
ansi_value[0] = 0;
|
||||
if (ch != A_CSI && ch != A_DCS)
|
||||
return FALSE;
|
||||
|
||||
s = pack_buf + 1;
|
||||
private_use = 0;
|
||||
if ((*s >= '<') & (*s <= '?')) {
|
||||
private_use = *s++;
|
||||
}
|
||||
terminator = 0;
|
||||
for (; (ch = *s); s++) {
|
||||
if (ch >= '0' && ch <= '9')
|
||||
ansi_value[ape] = ansi_value[ape] * 10 + ch - '0';
|
||||
else if (ch == ';' || ch == ':')
|
||||
ansi_value[++ape] = 0;
|
||||
else if (ch >= '<' && ch <= '?')
|
||||
private_use = ch;
|
||||
else if (ch >= ' ')
|
||||
terminator = (terminator << 8) | ch;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return terminator == expected;
|
||||
}
|
||||
|
||||
/*
|
||||
** read_reports()
|
||||
**
|
||||
** read all the reports in the ANSI report structure
|
||||
*/
|
||||
static int
|
||||
read_reports(void)
|
||||
{
|
||||
int i, j, k, tc, vcr, lc;
|
||||
char *s;
|
||||
const char *t;
|
||||
|
||||
lc = 5;
|
||||
terminal_class = tc = 0;
|
||||
for (i = 0; report_list[i].text; i++, lc++) {
|
||||
if (terminal_class < report_list[i].lvl &&
|
||||
tc < report_list[i].lvl) {
|
||||
put_crlf();
|
||||
menu_prompt();
|
||||
ptext("/status [q] > ");
|
||||
j = wait_here();
|
||||
if (j != 'n' && j != 'N')
|
||||
return 0;
|
||||
tc = report_list[i].lvl;
|
||||
lc = 1;
|
||||
} else if (lc + 2 >= lines) {
|
||||
put_crlf();
|
||||
ptext("Hit any key to continue ");
|
||||
(void) wait_here();
|
||||
lc = 1;
|
||||
}
|
||||
sprintf(temp, "%s (%s) ", report_list[i].text,
|
||||
expand_command(report_list[i].request));
|
||||
ptext(temp);
|
||||
for (j = strlen(temp); j < 49; j++)
|
||||
putchp(' ');
|
||||
tc_putp(report_list[i].request);
|
||||
vcr = 0;
|
||||
if (report_list[i].final == 0) {
|
||||
read_ansi();
|
||||
} else if (valid_mode(report_list[i].final))
|
||||
switch (report_list[i].final) {
|
||||
case 'c':
|
||||
terminal_class = ansi_value[0];
|
||||
break;
|
||||
case 'R':
|
||||
vcr = TRUE;
|
||||
break;
|
||||
}
|
||||
j = UChar(pack_buf[0]);
|
||||
if (j != A_CSI && j != A_DCS) {
|
||||
put_crlf();
|
||||
t = "*** The above request gives illegal response ***";
|
||||
ptext(t);
|
||||
for (j = strlen(t); j < 49; j++)
|
||||
putchp(' ');
|
||||
}
|
||||
s = expand((const char *)ansi_buf);
|
||||
if (char_count + expand_chars >= columns) {
|
||||
put_str("\r\n ");
|
||||
lc++;
|
||||
}
|
||||
putln(s);
|
||||
if (vcr) { /* find out how big the screen is */
|
||||
tc_putp(report_list[i].request);
|
||||
if (!valid_mode('R'))
|
||||
continue;
|
||||
j = ansi_value[0];
|
||||
k = ansi_value[1];
|
||||
tc_putp("\033[255B\033[255C\033[6n");
|
||||
if (!valid_mode('R'))
|
||||
continue;
|
||||
sprintf(temp, "\033[%d;%dH", j, k);
|
||||
tc_putp(temp);
|
||||
ptext("(DSR) Screen size (CSI 6 n)");
|
||||
for (j = char_count; j < 50; j++)
|
||||
putchp(' ');
|
||||
sprintf(temp, "%d x %d", ansi_value[1], ansi_value[0]);
|
||||
ptextln(temp);
|
||||
|
||||
}
|
||||
}
|
||||
menu_prompt();
|
||||
ptext("/status r->repeat test, <return> to continue > ");
|
||||
return wait_here();
|
||||
}
|
||||
|
||||
/*
|
||||
** request_cfss()
|
||||
**
|
||||
** Request Control function selection or settings
|
||||
*/
|
||||
static int
|
||||
request_cfss(void)
|
||||
{
|
||||
int i, j, k, l, ch;
|
||||
char *s;
|
||||
|
||||
put_clear();
|
||||
ptextln("Request Expected Received");
|
||||
put_crlf();
|
||||
for (i = 0; rqss[i].text; i++) {
|
||||
ptext(rqss[i].text);
|
||||
j = strlen(rqss[i].text) + strlen(rqss[i].expect);
|
||||
putchp(' ');
|
||||
for (j++; j < 40; j++)
|
||||
putchp(' ');
|
||||
ptext(rqss[i].expect);
|
||||
putchp(' ');
|
||||
tc_putp(rqss[i].set_mode);
|
||||
sprintf(temp, "\033P$q%s\033\\", rqss[i].request);
|
||||
tc_putp(temp);
|
||||
read_ansi();
|
||||
tc_putp(rqss[i].reset_mode);
|
||||
putchp(' ');
|
||||
for (j = 0; ansi_buf[j]; j++) {
|
||||
if (ansi_buf[j] == 'r') {
|
||||
for (k = j++; (ch = UChar(ansi_buf[k])) != 0; k++)
|
||||
if (ch == A_ESC) {
|
||||
break;
|
||||
} else if (ch == A_ST) {
|
||||
break;
|
||||
}
|
||||
ansi_buf[k] = '\0';
|
||||
s = expand((const char *)&ansi_buf[j]);
|
||||
if (char_count + expand_chars >= columns)
|
||||
put_str("\r\n ");
|
||||
put_str(s);
|
||||
}
|
||||
}
|
||||
put_crlf();
|
||||
}
|
||||
/* calculate the valid attributes */
|
||||
ptext("Valid attributes: 0");
|
||||
j = 0;
|
||||
for (i = 1; i < 20; i++) {
|
||||
sprintf(temp, "\033[0;%dm\033P$qm\033\\", i);
|
||||
tc_putp(temp);
|
||||
(void) valid_mode('m');
|
||||
if (ape > 0) {
|
||||
j = i;
|
||||
sprintf(temp, "\033[0m; %d", i);
|
||||
tc_putp(temp);
|
||||
}
|
||||
}
|
||||
put_crlf();
|
||||
/* calculate how many parameters can be sent */
|
||||
ptext("Max number of parameters: ");
|
||||
sprintf(temp, "%dm\033P$qm\033\\", j);
|
||||
l = -1;
|
||||
if (j > 0)
|
||||
for (l = 1; l < 33; l++) {
|
||||
tc_putp("\033[0");
|
||||
for (ch = 1; ch <= l; ch++)
|
||||
put_this(';');
|
||||
tc_putp(temp);
|
||||
(void) valid_mode('m');
|
||||
if (ape == 0)
|
||||
break;
|
||||
}
|
||||
tc_putp("\033[m");
|
||||
if (l >= 0) {
|
||||
sprintf(temp, "%d", l);
|
||||
ptext(temp);
|
||||
} else
|
||||
ptext("unknown");
|
||||
put_crlf();
|
||||
return wait_here();
|
||||
}
|
||||
|
||||
/*
|
||||
** mode_display(puc, mode, initial, set, reset)
|
||||
**
|
||||
** print the mode display entry
|
||||
*/
|
||||
static void
|
||||
mode_display(const char *p, int n, int c, char s, char r)
|
||||
{
|
||||
int k;
|
||||
|
||||
sprintf(temp, "%s%d (%c, %c, %c)", p, n, c, s, r);
|
||||
k = strlen(temp);
|
||||
if (char_count + k >= columns)
|
||||
put_crlf();
|
||||
for (; k < 14; k++)
|
||||
putchp(' ');
|
||||
put_str(temp);
|
||||
}
|
||||
|
||||
/*
|
||||
** terminal_state()
|
||||
**
|
||||
** test DECRQM status reports
|
||||
*/
|
||||
static void
|
||||
terminal_state(void)
|
||||
{
|
||||
static const char *puc[] = {"", "<", "=", ">", "?", 0};
|
||||
|
||||
int i, j, k, l, modes_found;
|
||||
char *s;
|
||||
char buf[256], tms[256];
|
||||
int mode_puc[MAX_MODES], mode_number[MAX_MODES];
|
||||
char set_value[MAX_MODES], reset_value[MAX_MODES];
|
||||
char current_value[MAX_MODES];
|
||||
|
||||
ptext("Testing terminal mode status. (CSI 0 $ p)");
|
||||
tc_putp("\033[0$p");
|
||||
modes_found = 0;
|
||||
tms[0] = '\0';
|
||||
if (valid_mode(('$' << 8) | 'y')) {
|
||||
for (i = 0; puc[i]; i++) {
|
||||
put_crlf();
|
||||
if (i) {
|
||||
sprintf(temp, "Private use: %c", puc[i][0]);
|
||||
} else {
|
||||
strcpy(temp, "Standard modes:");
|
||||
}
|
||||
k = strlen(temp);
|
||||
ptext(temp);
|
||||
for (j = 0; j < (int) sizeof(buf); buf[j++] = ' ')
|
||||
;
|
||||
for (j = l = 0; j < 255 && j - l < 50; j++) {
|
||||
sprintf(temp, "\033[%s%d$p", puc[i], j);
|
||||
tc_putp(temp);
|
||||
if (!valid_mode(('$' << 8) | 'y')) {
|
||||
/* not valid, save terminating value */
|
||||
s = expand((const char *)ansi_buf);
|
||||
sprintf(tms, "%s%s%d %s ", tms,
|
||||
puc[i], j, s);
|
||||
break;
|
||||
}
|
||||
if (private_use != puc[i][0])
|
||||
break;
|
||||
if (ansi_value[0] != j)
|
||||
break;
|
||||
if (ansi_value[1]) {
|
||||
l = j;
|
||||
if (k > 70) {
|
||||
buf[k] = '\0';
|
||||
put_crlf();
|
||||
ptextln(buf);
|
||||
for (k = 0; k < (int) sizeof(buf);) {
|
||||
buf[k++] = ' ';
|
||||
}
|
||||
k = 0;
|
||||
}
|
||||
sprintf(temp, " %d", j);
|
||||
ptext(temp);
|
||||
k += strlen(temp);
|
||||
buf[k - 1] = ansi_value[1] + '0';
|
||||
if (modes_found >= MAX_MODES)
|
||||
continue;
|
||||
current_value[modes_found] =
|
||||
ansi_value[1] + '0';
|
||||
/* some modes never return */
|
||||
if ((i == 0 && j == 13) /* control execution */
|
||||
|| (puc[i][0] == '?' && j == 2)) /* VT52 */
|
||||
set_value[modes_found] =
|
||||
reset_value[modes_found] = '-';
|
||||
else
|
||||
set_value[modes_found] =
|
||||
reset_value[modes_found] = ' ';
|
||||
mode_puc[modes_found] = i;
|
||||
mode_number[modes_found++] = j;
|
||||
}
|
||||
}
|
||||
buf[k] = '\0';
|
||||
if (buf[k - 1] != ' ') {
|
||||
put_crlf();
|
||||
ptext(buf);
|
||||
}
|
||||
}
|
||||
|
||||
if ((i = modes_found) != 0) {
|
||||
put_crlf();
|
||||
put_crlf();
|
||||
if (tms[0]) {
|
||||
ptextln(tms);
|
||||
}
|
||||
ptext("Hit 'Y' to test mode set/reset states: ");
|
||||
i = wait_here();
|
||||
}
|
||||
if (i == 'y' || i == 'Y')
|
||||
while (1) {
|
||||
#ifdef STATUSFIX
|
||||
FILE *fp;
|
||||
|
||||
#ifdef TEDANSI
|
||||
fp = fopen("ted.ansi", "w");
|
||||
#else
|
||||
fp = fopen("/dev/console", "w");
|
||||
#endif
|
||||
#endif
|
||||
for (i = j = 0; j < modes_found; j = ++i >> 1) {
|
||||
if (set_value[j] == '-')
|
||||
continue;
|
||||
k = (current_value[j] ^ i) & 1;
|
||||
sprintf(temp, "\033[%s%d%c\033[%s%d$p",
|
||||
puc[mode_puc[j]], mode_number[j],
|
||||
k ? 'l' : 'h',
|
||||
puc[mode_puc[j]], mode_number[j]);
|
||||
#ifdef STATUSFIX
|
||||
if (fp) {
|
||||
fprintf(fp, "%s\n", expand(temp));
|
||||
fflush(fp);
|
||||
}
|
||||
#endif
|
||||
tc_putp(temp);
|
||||
if (!valid_mode(('$' << 8) | 'y'))
|
||||
continue;
|
||||
if (k) {
|
||||
reset_value[j] = ansi_value[1] + '0';
|
||||
} else {
|
||||
set_value[j] = ansi_value[1] + '0';
|
||||
}
|
||||
}
|
||||
put_str("\033[30l"); /* added for GORT bug
|
||||
(WY-185) */
|
||||
#ifdef STATUSFIX
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
#endif
|
||||
tty_set();
|
||||
/* print the results */
|
||||
put_clear();
|
||||
putln("mode (initial, set, reset)");
|
||||
for (j = 0; j < modes_found; j++) {
|
||||
mode_display(puc[mode_puc[j]], mode_number[j],
|
||||
current_value[j], set_value[j], reset_value[j]);
|
||||
}
|
||||
ptext("\n\nHit 'R' to repeat test. 'S' to sort results: ");
|
||||
i = wait_here();
|
||||
if (i == 's' || i == 'S') { /* print the same stuff,
|
||||
sorted by
|
||||
current_value */
|
||||
put_crlf();
|
||||
for (i = '1'; i <= '4'; i++) {
|
||||
for (j = 0; j < modes_found; j++) {
|
||||
if (current_value[j] == i)
|
||||
mode_display(puc[mode_puc[j]],
|
||||
mode_number[j], current_value[j],
|
||||
set_value[j], reset_value[j]);
|
||||
}
|
||||
}
|
||||
ptext("\n\nHit 'R' to repeat test: ");
|
||||
i = wait_here();
|
||||
}
|
||||
if (i != 'r' && i != 'R')
|
||||
break;
|
||||
tty_raw(1, char_mask);
|
||||
}
|
||||
} else {
|
||||
tty_set();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** ansi_report_help()
|
||||
**
|
||||
** Display the informational data for the ANSI report test.
|
||||
*/
|
||||
static void
|
||||
ansi_report_help(void)
|
||||
{
|
||||
ptext("Begin ANSI status report testing. ");
|
||||
ptext(" Parity bit set will be displayed in reverse video. ");
|
||||
ptext(" If the terminal hangs, hit any alphabetic key. ");
|
||||
ptextln(" Use n to continue testing. Use q to quit.");
|
||||
put_crlf();
|
||||
}
|
||||
|
||||
/*
|
||||
** test_ansi_reports()
|
||||
**
|
||||
** Test the ANSI status report functions
|
||||
*/
|
||||
void
|
||||
tools_status(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
int i;
|
||||
|
||||
put_clear();
|
||||
ansi_report_help();
|
||||
tty_raw(1, char_mask);
|
||||
|
||||
do {
|
||||
i = read_reports();
|
||||
if (i != 'r' && i != 'R') {
|
||||
*ch = i;
|
||||
return;
|
||||
}
|
||||
} while (i);
|
||||
|
||||
if (terminal_class >= 63) {
|
||||
do {
|
||||
i = request_cfss();
|
||||
} while (i == 'r' || i == 'R');
|
||||
*ch = i;
|
||||
terminal_state();
|
||||
} else {
|
||||
tty_set();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** display_sgr()
|
||||
**
|
||||
** Test a range of ANSI sgr attributes
|
||||
** puc -> Private Use Character
|
||||
*/
|
||||
static void
|
||||
display_sgr(int puc)
|
||||
{
|
||||
int k;
|
||||
|
||||
temp[0] = puc;
|
||||
temp[1] = '\0';
|
||||
for (k = 0; k < 80; k++) {
|
||||
if (char_count + 8 > 80)
|
||||
put_crlf();
|
||||
else if (char_count + 8 > columns)
|
||||
put_crlf();
|
||||
else if (k > 0)
|
||||
printf(" ");
|
||||
printf("\033[%s%dmMode %2d\033[0m", temp, k, k);
|
||||
char_count += 8;
|
||||
if (puc == '\0') {
|
||||
if (k == 19)
|
||||
printf("\033[10m");
|
||||
if (k == 39)
|
||||
printf("\033[37m");
|
||||
if (k == 49)
|
||||
printf("\033[40m");
|
||||
}
|
||||
}
|
||||
put_crlf();
|
||||
if (puc == '<')
|
||||
printf("\033[<1m");
|
||||
else if (puc)
|
||||
printf("\033[%s0m", temp);
|
||||
set_attr(0);
|
||||
}
|
||||
|
||||
/*
|
||||
** print_sgr20(on, off)
|
||||
**
|
||||
** print the sgr line for sgr20()
|
||||
*/
|
||||
static void
|
||||
print_sgr20(int on, int off)
|
||||
{
|
||||
if (char_count > columns - 13) {
|
||||
put_crlf();
|
||||
} else if (char_count) {
|
||||
put_str(" ");
|
||||
}
|
||||
char_count += 11;
|
||||
printf("%d/%d \033[%dmon\033[%dm off\033[0m", on, off, on, off);
|
||||
}
|
||||
|
||||
/*
|
||||
** sgr20(void)
|
||||
**
|
||||
** display the enter/exit attributes 1-9 and 20-29
|
||||
*/
|
||||
static void
|
||||
sgr20(void)
|
||||
{
|
||||
int k;
|
||||
|
||||
put_crlf();
|
||||
ptextln("Test enter/exit attributes 1-9 and 21-29.");
|
||||
for (k = 1; k < 10; k++) {
|
||||
print_sgr20(k, k + 20);
|
||||
}
|
||||
print_sgr20(1, 22); /* bold */
|
||||
print_sgr20(2, 22); /* dim */
|
||||
print_sgr20(8, 22); /* blank */
|
||||
printf("\033[0m");
|
||||
set_attr(0);
|
||||
}
|
||||
|
||||
/*
|
||||
** tools_sgr(testlist, state, ch)
|
||||
**
|
||||
** Run the ANSI graphics rendition mode tool
|
||||
** Return the last character typed.
|
||||
*/
|
||||
void
|
||||
tools_sgr(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
int k;
|
||||
|
||||
put_clear();
|
||||
for (k = 0;;) {
|
||||
display_sgr(k);
|
||||
put_crlf();
|
||||
menu_prompt();
|
||||
ptext("/sgr Enter =><?r [<cr>] > ");
|
||||
k = wait_here();
|
||||
if ((k == 'r') || (k == 'R')) {
|
||||
k = 0;
|
||||
} else if ((k < '<') || (k > '?')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
sgr20();
|
||||
|
||||
put_newlines(2);
|
||||
*ch = REQUEST_PROMPT;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Test ANSI graphics
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
** select_bank(bank)
|
||||
**
|
||||
** select a graphics character set for ANSI terminals
|
||||
*/
|
||||
static void
|
||||
select_bank(char *bank)
|
||||
{
|
||||
tc_putp(bank);
|
||||
switch (bank[1] & 3) {
|
||||
case 0:
|
||||
putchp('O' & 0x1f); /* control O */
|
||||
break;
|
||||
case 1:
|
||||
putchp('N' & 0x1f); /* control N */
|
||||
tc_putp("\033~");
|
||||
break;
|
||||
case 2:
|
||||
tc_putp("\033n\033}");
|
||||
break;
|
||||
case 3:
|
||||
tc_putp("\033o\033|");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** show_characters(bank, bias)
|
||||
**
|
||||
** print the ANSI graphics characters
|
||||
*/
|
||||
static void
|
||||
show_characters(char *bank, int bias)
|
||||
{
|
||||
int i;
|
||||
|
||||
sprintf(temp, "G%d GL ", bank[1] & 3);
|
||||
ptext(temp);
|
||||
select_bank(bank);
|
||||
for (i = ' '; i < 0x80; i++) {
|
||||
if (char_count >= columns ||
|
||||
(i != ' ' && (i & 31) == 0))
|
||||
put_str("\n ");
|
||||
putchp(i + bias);
|
||||
}
|
||||
select_bank(default_bank);
|
||||
put_str(" DEL <");
|
||||
select_bank(bank);
|
||||
putchp(0x7f + bias);
|
||||
select_bank(default_bank);
|
||||
putchp('>');
|
||||
put_crlf();
|
||||
put_crlf();
|
||||
}
|
||||
|
||||
|
||||
/* ANSI graphics test
|
||||
94 96 character sets
|
||||
G0 ( ,
|
||||
G1 ) -
|
||||
G2 * .
|
||||
G3 + /
|
||||
|
||||
Standard Definitions
|
||||
A UK
|
||||
B US ASCII
|
||||
|
||||
Dec extended definitions
|
||||
0 Special graphics
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
** tools_charset(testlist, state, ch)
|
||||
**
|
||||
** Run the ANSI alt-charset mode tool
|
||||
*/
|
||||
void
|
||||
tools_charset(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *chp GCC_UNUSED)
|
||||
{
|
||||
int j, ch;
|
||||
char bank[32];
|
||||
|
||||
put_clear();
|
||||
ptext("Enter the bank ()*+,-./ followed by the character set");
|
||||
ptext(" 0123456789:;<=>? for private use, and");
|
||||
ptextln(" @A...Z[\\]^_`a...z{|}~ for standard sets.");
|
||||
strcpy(bank, "\033)0");
|
||||
for (; bank[0];) {
|
||||
put_crlf();
|
||||
show_characters(bank, 0);
|
||||
|
||||
/* G0 will not print in GR */
|
||||
if (bank[1] & 3) {
|
||||
show_characters(bank, 0x80);
|
||||
}
|
||||
ptext("bank+set> ");
|
||||
for (j = 1; (ch = getchp(char_mask)); j++) {
|
||||
if (ch == EOF)
|
||||
break;
|
||||
putchp(ch);
|
||||
if (j == 1 && ch > '/')
|
||||
j++;
|
||||
bank[j] = ch;
|
||||
if (ch < ' ' || ch > '/')
|
||||
break;
|
||||
if (j + 1 >= (int) sizeof(bank))
|
||||
break;
|
||||
}
|
||||
if (j == 1)
|
||||
break;
|
||||
if (bank[j] < '0' || bank[j] > '~')
|
||||
break;
|
||||
bank[j + 1] = '\0';
|
||||
}
|
||||
put_crlf();
|
||||
}
|
@ -1,711 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997-2000 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <tack.h>
|
||||
|
||||
MODULE_ID("$Id: charset.c,v 1.11 2006/11/26 00:13:36 tom Exp $")
|
||||
|
||||
/*
|
||||
Menu definitions for alternate character set and SGR tests.
|
||||
*/
|
||||
|
||||
static void charset_bel(struct test_list *t, int *state, int *ch);
|
||||
static void charset_flash(struct test_list *t, int *state, int *ch);
|
||||
static void charset_civis(struct test_list *t, int *state, int *ch);
|
||||
static void charset_cvvis(struct test_list *t, int *state, int *ch);
|
||||
static void charset_cnorm(struct test_list *t, int *state, int *ch);
|
||||
static void charset_hs(struct test_list *t, int *state, int *ch);
|
||||
static void charset_status(struct test_list *t, int *state, int *ch);
|
||||
static void charset_dsl(struct test_list *t, int *state, int *ch);
|
||||
static void charset_enacs(struct test_list *t, int *state, int *ch);
|
||||
static void charset_smacs(struct test_list *t, int *state, int *ch);
|
||||
static void charset_attributes(struct test_list *t, int *state, int *ch);
|
||||
static void charset_sgr(struct test_list *t, int *state, int *ch);
|
||||
|
||||
struct test_list acs_test_list[] = {
|
||||
{0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu},
|
||||
{MENU_NEXT, 3, "bel", 0, 0, charset_bel, 0},
|
||||
{MENU_NEXT, 3, "flash", 0, 0, charset_flash, 0},
|
||||
{MENU_NEXT, 3, "civis", 0, 0, charset_civis, 0},
|
||||
{MENU_NEXT, 3, "cvvis", 0, 0, charset_cvvis, 0},
|
||||
{MENU_NEXT, 3, "cnorm", 0, 0, charset_cnorm, 0},
|
||||
{MENU_NEXT, 3, "hs", 0, 0, charset_hs, 0},
|
||||
{MENU_NEXT, 3, "tsl) (fsl) (wsl", "hs", 0, charset_status, 0},
|
||||
{MENU_NEXT, 3, "dsl", "hs", 0, charset_dsl, 0},
|
||||
{MENU_NEXT, 0, "acsc) (enacs) (smacs) (rmacs", 0, 0, charset_enacs, 0},
|
||||
{MENU_NEXT, 0, "smacs) (rmacs", 0, 0, charset_smacs, 0},
|
||||
{MENU_NEXT, 11, 0, 0, 0, charset_attributes, 0},
|
||||
{MENU_NEXT, 11, "sgr) (sgr0", "ma", 0, charset_sgr, 0},
|
||||
{MENU_LAST, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
const struct mode_list alt_modes[] = {
|
||||
{"normal", "(sgr0)", "(sgr0)", 1},
|
||||
{"standout", "(smso)", "(rmso)", 2},
|
||||
{"underline", "(smul)", "(rmul)", 4},
|
||||
{"reverse", "(rev)", "(sgr0)", 8},
|
||||
{"blink", "(blink)", "(sgr0)", 16},
|
||||
{"dim", "(dim)", "(sgr0)", 32},
|
||||
{"bold", "(bold)", "(sgr0)", 64},
|
||||
{"invis", "(invis)", "(sgr0)", 128},
|
||||
{"protect", "(prot)", "(sgr0)", 256},
|
||||
{"altcharset", "(smacs)", "(rmacs)", 512}
|
||||
};
|
||||
|
||||
/* On many terminals the underline attribute is the last scan line.
|
||||
This is OK unless the following line is reverse video.
|
||||
Then the underline attribute does not show up. The following map
|
||||
will reorder the display so that the underline attribute will
|
||||
show up. */
|
||||
const int mode_map[10] = {0, 1, 3, 4, 5, 6, 7, 8, 9, 2};
|
||||
|
||||
struct graphics_pair {
|
||||
unsigned char c;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static struct graphics_pair glyph[] = {
|
||||
{'+', "arrow pointing right"},
|
||||
{',', "arrow pointing left"},
|
||||
{'.', "arrow pointing down"},
|
||||
{'0', "solid square block"},
|
||||
{'i', "lantern symbol"},
|
||||
{'-', "arrow pointing up"},
|
||||
{'`', "diamond"},
|
||||
{'a', "checker board (stipple)"},
|
||||
{'f', "degree symbol"},
|
||||
{'g', "plus/minus"},
|
||||
{'h', "board of squares"},
|
||||
{'j', "lower right corner"},
|
||||
{'k', "upper right corner"},
|
||||
{'l', "upper left corner"},
|
||||
{'m', "lower left corner"},
|
||||
{'n', "plus"},
|
||||
{'o', "scan line 1"},
|
||||
{'p', "scan line 3"},
|
||||
{'q', "horizontal line"},
|
||||
{'r', "scan line 7"},
|
||||
{'s', "scan line 9"},
|
||||
{'t', "left tee (|-)"},
|
||||
{'u', "right tee (-|)"},
|
||||
{'v', "bottom tee(_|_)"},
|
||||
{'w', "top tee (T)"},
|
||||
{'x', "vertical line"},
|
||||
{'y', "less/equal"},
|
||||
{'z', "greater/equal"},
|
||||
{'{', "Pi"},
|
||||
{'|', "not equal"},
|
||||
{'}', "UK pound sign"},
|
||||
{'~', "bullet"},
|
||||
{'\0', "\0"}
|
||||
};
|
||||
|
||||
/*
|
||||
** charset_hs(test_list, status, ch)
|
||||
**
|
||||
** (hs) test Has status line
|
||||
*/
|
||||
static void
|
||||
charset_hs(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (has_status_line != 1) {
|
||||
ptext("(hs) Has-status line is not defined. ");
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** charset_status(test_list, status, ch)
|
||||
**
|
||||
** (tsl) (fsl) (wsl) test Status line
|
||||
*/
|
||||
static void
|
||||
charset_status(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i, max;
|
||||
char *s;
|
||||
static char m[] = "*** status line *** 123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.";
|
||||
|
||||
if (has_status_line != 1) {
|
||||
return;
|
||||
}
|
||||
put_clear();
|
||||
max = width_status_line == -1 ? columns : width_status_line;
|
||||
sprintf(temp, "Terminal has status line of %d characters", max);
|
||||
ptextln(temp);
|
||||
|
||||
put_str("This line s");
|
||||
s = TPARM_1(to_status_line, 0);
|
||||
tc_putp(s);
|
||||
for (i = 0; i < max; i++)
|
||||
putchp(m[i]);
|
||||
tc_putp(from_status_line);
|
||||
putln("hould not be broken.");
|
||||
ptextln("If the previous line is not a complete sentence then (tsl) to-status-line, (fsl) from-status-line, or (wsl) width-of-status-line is incorrect." );
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** charset_dsl(test_list, status, ch)
|
||||
**
|
||||
** (dsl) test Disable status line
|
||||
*/
|
||||
static void
|
||||
charset_dsl(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (has_status_line != 1) {
|
||||
return;
|
||||
}
|
||||
if (dis_status_line) {
|
||||
ptextln("Disable status line (dsl)");
|
||||
tc_putp(dis_status_line);
|
||||
ptext("If you can still see the status line then (dsl) disable-status-line has failed. ");
|
||||
} else {
|
||||
ptext("(dsl) Disable-status-line is not defined. ");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
eat_cookie(void)
|
||||
{ /* put a blank if this is not a magic cookie
|
||||
terminal */
|
||||
if (magic_cookie_glitch < 1)
|
||||
putchp(' ');
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
put_mode(char *s)
|
||||
{ /* send the attribute string (with or without
|
||||
% execution) */
|
||||
tc_putp(TPARM_0(s)); /* allow % execution */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_attr(int a)
|
||||
{ /* set the attribute from the bits in a */
|
||||
int i, b[32];
|
||||
|
||||
if (magic_cookie_glitch > 0) {
|
||||
char_count += magic_cookie_glitch;
|
||||
}
|
||||
if (a == 0 && exit_attribute_mode) {
|
||||
put_mode(exit_attribute_mode);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < 31; i++) {
|
||||
b[i] = (a >> i) & 1;
|
||||
}
|
||||
tc_putp(TPARM_9(set_attributes, b[1], b[2], b[3], b[4], b[5],
|
||||
b[6], b[7], b[8], b[9]));
|
||||
}
|
||||
|
||||
/*
|
||||
** charset_sgr(test_list, status, ch)
|
||||
**
|
||||
** (sgr) test Set Graphics Rendition
|
||||
*/
|
||||
static void
|
||||
charset_sgr(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!set_attributes) {
|
||||
ptext("(sgr) Set-graphics-rendition is not defined. ");
|
||||
generic_done_message(t, state, ch);
|
||||
return;
|
||||
}
|
||||
if (!exit_attribute_mode) {
|
||||
ptextln("(sgr0) Set-graphics-rendition-zero is not defined.");
|
||||
/* go ahead and test anyway */
|
||||
}
|
||||
ptext("Test video attributes (sgr)");
|
||||
|
||||
for (i = 0; i < (int) (sizeof(alt_modes) / sizeof(struct mode_list));
|
||||
i++) {
|
||||
put_crlf();
|
||||
sprintf(temp, "%d %-20s", i, alt_modes[i].name);
|
||||
put_str(temp);
|
||||
set_attr(alt_modes[i].number);
|
||||
sprintf(temp, "%s", alt_modes[i].name);
|
||||
put_str(temp);
|
||||
set_attr(0);
|
||||
}
|
||||
|
||||
putln("\n\nDouble mode test");
|
||||
for (i = 0; i <= 9; i++) {
|
||||
sprintf(temp, " %2d ", mode_map[i]);
|
||||
put_str(temp);
|
||||
}
|
||||
for (i = 0; i <= 9; i++) {
|
||||
put_crlf();
|
||||
sprintf(temp, "%d", mode_map[i]);
|
||||
put_str(temp);
|
||||
for (j = 0; j <= 9; j++) {
|
||||
eat_cookie();
|
||||
set_attr((1 << mode_map[i]) | (1 << mode_map[j]));
|
||||
put_str("Aa");
|
||||
set_attr(0);
|
||||
if (j < 9)
|
||||
eat_cookie();
|
||||
}
|
||||
}
|
||||
put_crlf();
|
||||
|
||||
#ifdef max_attributes
|
||||
if (max_attributes >= 0) {
|
||||
sprintf(temp, "(ma) Maximum attributes %d ", max_attributes);
|
||||
ptext(temp);
|
||||
}
|
||||
#endif
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** test_one_attr(mode-number, begin-string, end-string)
|
||||
**
|
||||
** Display one attribute line.
|
||||
*/
|
||||
static void
|
||||
test_one_attr(
|
||||
int n,
|
||||
char *begin_mode,
|
||||
char *end_mode)
|
||||
{
|
||||
int i;
|
||||
|
||||
sprintf(temp, "%-10s %s ", alt_modes[n].name, alt_modes[n].begin_mode);
|
||||
ptext(temp);
|
||||
for (; char_count < 19;) {
|
||||
putchp(' ');
|
||||
}
|
||||
if (begin_mode) {
|
||||
putchp('.');
|
||||
put_mode(begin_mode);
|
||||
put_str(alt_modes[n].name);
|
||||
for (i = strlen(alt_modes[n].name); i < 13; i++) {
|
||||
putchp(' ');
|
||||
}
|
||||
if (end_mode) {
|
||||
put_mode(end_mode);
|
||||
sprintf(temp, ". %s", alt_modes[n].end_mode);
|
||||
} else {
|
||||
set_attr(0);
|
||||
strcpy(temp, ". (sgr)");
|
||||
}
|
||||
ptextln(temp);
|
||||
} else {
|
||||
for (i = 0; i < magic_cookie_glitch; i++)
|
||||
putchp('*');
|
||||
put_str("*** missing ***");
|
||||
for (i = 0; i < magic_cookie_glitch; i++)
|
||||
putchp('*');
|
||||
put_crlf();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** charset_attributes(test_list, status, ch)
|
||||
**
|
||||
** Test SGR
|
||||
*/
|
||||
static void
|
||||
charset_attributes(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
putln("Test video attributes");
|
||||
test_one_attr(1, enter_standout_mode, exit_standout_mode);
|
||||
test_one_attr(2, enter_underline_mode, exit_underline_mode);
|
||||
test_one_attr(9, enter_alt_charset_mode, exit_alt_charset_mode);
|
||||
if (!exit_attribute_mode && !set_attributes) {
|
||||
ptextln("(sgr0) exit attribute mode is not defined.");
|
||||
generic_done_message(t, state, ch);
|
||||
return;
|
||||
}
|
||||
test_one_attr(3, enter_reverse_mode, exit_attribute_mode);
|
||||
test_one_attr(4, enter_blink_mode, exit_attribute_mode);
|
||||
test_one_attr(5, enter_dim_mode, exit_attribute_mode);
|
||||
test_one_attr(6, enter_bold_mode, exit_attribute_mode);
|
||||
test_one_attr(7, enter_secure_mode, exit_attribute_mode);
|
||||
test_one_attr(8, enter_protected_mode, exit_attribute_mode);
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
#define GLYPHS 256
|
||||
|
||||
/*
|
||||
** charset_smacs(test_list, status, ch)
|
||||
**
|
||||
** display all possible acs characters
|
||||
** (smacs) (rmacs)
|
||||
*/
|
||||
static void
|
||||
charset_smacs(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i, c;
|
||||
|
||||
if (enter_alt_charset_mode) {
|
||||
put_clear();
|
||||
ptextln("The following characters are available. (smacs) (rmacs)");
|
||||
for (i = ' '; i <= '`'; i += 32) {
|
||||
put_crlf();
|
||||
put_mode(exit_alt_charset_mode);
|
||||
for (c = 0; c < 32; c++) {
|
||||
putchp(c + i);
|
||||
}
|
||||
put_crlf();
|
||||
put_mode(enter_alt_charset_mode);
|
||||
for (c = 0; c < 32; c++) {
|
||||
putchp(c + i);
|
||||
}
|
||||
put_mode(exit_alt_charset_mode);
|
||||
put_crlf();
|
||||
}
|
||||
put_mode(exit_alt_charset_mode);
|
||||
put_crlf();
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_acs(
|
||||
int attr)
|
||||
{ /* alternate character set */
|
||||
int i, j;
|
||||
char valid_glyph[GLYPHS];
|
||||
char acs_table[GLYPHS];
|
||||
static unsigned char vt100[] = "`afgjklmnopqrstuvwxyz{|}~";
|
||||
|
||||
line_count = 0;
|
||||
for (i = 0; i < GLYPHS; i++) {
|
||||
valid_glyph[i] = FALSE;
|
||||
acs_table[i] = i;
|
||||
}
|
||||
if (acs_chars) {
|
||||
sprintf(temp, "Alternate character set map: %s",
|
||||
expand(acs_chars));
|
||||
putln(temp);
|
||||
for (i = 0; acs_chars[i]; i += 2) {
|
||||
if (acs_chars[i + 1] == 0) {
|
||||
break;
|
||||
}
|
||||
for (j = 0;; j++) {
|
||||
if (glyph[j].c == (unsigned char) acs_chars[i]) {
|
||||
acs_table[glyph[j].c] = acs_chars[i + 1];
|
||||
valid_glyph[glyph[j].c] = TRUE;
|
||||
break;
|
||||
}
|
||||
if (glyph[j].name[0] == '\0') {
|
||||
if (isgraph(UChar(acs_chars[i]))) {
|
||||
sprintf(temp, " %c",
|
||||
acs_chars[i]);
|
||||
} else {
|
||||
sprintf(temp, " 0x%02x",
|
||||
UChar(acs_chars[i]));
|
||||
}
|
||||
strcpy(&temp[5], " *** has no mapping ***");
|
||||
putln(temp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ptextln("acs_chars not defined (acsc)");
|
||||
/* enable the VT-100 graphics characters (default) */
|
||||
for (i = 0; vt100[i]; i++) {
|
||||
valid_glyph[vt100[i]] = TRUE;
|
||||
}
|
||||
}
|
||||
if (attr) {
|
||||
set_attr(attr);
|
||||
}
|
||||
_nc_init_acs(); /* puts 'ena_acs' and incidentally links acs_map[] */
|
||||
for (i = 0; glyph[i].name[0]; i++) {
|
||||
if (valid_glyph[glyph[i].c]) {
|
||||
put_mode(enter_alt_charset_mode);
|
||||
put_this(acs_table[glyph[i].c]);
|
||||
char_count++;
|
||||
put_mode(exit_alt_charset_mode);
|
||||
if (magic_cookie_glitch >= 1) {
|
||||
sprintf(temp, " %-30.30s", glyph[i].name);
|
||||
put_str(temp);
|
||||
if (char_count + 33 >= columns)
|
||||
put_crlf();
|
||||
} else {
|
||||
sprintf(temp, " %-24.24s", glyph[i].name);
|
||||
put_str(temp);
|
||||
if (char_count + 26 >= columns)
|
||||
put_crlf();
|
||||
}
|
||||
if (line_count >= lines) {
|
||||
(void) wait_here();
|
||||
put_clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (char_count > 1) {
|
||||
put_crlf();
|
||||
}
|
||||
#ifdef ACS_ULCORNER
|
||||
maybe_wait(5);
|
||||
put_mode(enter_alt_charset_mode);
|
||||
put_that(ACS_ULCORNER);
|
||||
put_that(ACS_TTEE);
|
||||
put_that(ACS_URCORNER);
|
||||
put_that(ACS_ULCORNER);
|
||||
put_that(ACS_HLINE);
|
||||
put_that(ACS_URCORNER);
|
||||
char_count += 6;
|
||||
put_mode(exit_alt_charset_mode);
|
||||
put_crlf();
|
||||
put_mode(enter_alt_charset_mode);
|
||||
put_that(ACS_LTEE);
|
||||
put_that(ACS_PLUS);
|
||||
put_that(ACS_RTEE);
|
||||
put_that(ACS_VLINE);
|
||||
if (magic_cookie_glitch >= 1)
|
||||
put_this(' ');
|
||||
else {
|
||||
put_mode(exit_alt_charset_mode);
|
||||
put_this(' ');
|
||||
put_mode(enter_alt_charset_mode);
|
||||
}
|
||||
put_that(ACS_VLINE);
|
||||
char_count += 6;
|
||||
put_mode(exit_alt_charset_mode);
|
||||
put_str(" Here are 2 boxes");
|
||||
put_crlf();
|
||||
put_mode(enter_alt_charset_mode);
|
||||
put_that(ACS_LLCORNER);
|
||||
put_that(ACS_BTEE);
|
||||
put_that(ACS_LRCORNER);
|
||||
put_that(ACS_LLCORNER);
|
||||
put_that(ACS_HLINE);
|
||||
put_that(ACS_LRCORNER);
|
||||
char_count += 6;
|
||||
put_mode(exit_alt_charset_mode);
|
||||
put_crlf();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** charset_bel(test_list, status, ch)
|
||||
**
|
||||
** (bel) test Bell
|
||||
*/
|
||||
static void
|
||||
charset_bel(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (bell) {
|
||||
ptextln("Testing bell (bel)");
|
||||
tc_putp(bell);
|
||||
ptext("If you did not hear the Bell then (bel) has failed. ");
|
||||
} else {
|
||||
ptext("(bel) Bell is not defined. ");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** charset_flash(test_list, status, ch)
|
||||
**
|
||||
** (flash) test Visual bell
|
||||
*/
|
||||
static void
|
||||
charset_flash(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (flash_screen) {
|
||||
ptextln("Testing visual bell (flash)");
|
||||
tc_putp(flash_screen);
|
||||
ptext("If you did not see the screen flash then (flash) has failed. ");
|
||||
} else {
|
||||
ptext("(flash) Flash is not defined. ");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** charset_civis(test_list, status, ch)
|
||||
**
|
||||
** (civis) test Cursor invisible
|
||||
*/
|
||||
static void
|
||||
charset_civis(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (cursor_normal) {
|
||||
if (cursor_invisible) {
|
||||
ptext("(civis) Turn off the cursor. ");
|
||||
tc_putp(cursor_invisible);
|
||||
ptext("If you can still see the cursor then (civis) has failed. ");
|
||||
} else {
|
||||
ptext("(civis) Cursor-invisible is not defined. ");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
tc_putp(cursor_normal);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** charset_cvvis(test_list, status, ch)
|
||||
**
|
||||
** (cvvis) test Cursor very visible
|
||||
*/
|
||||
static void
|
||||
charset_cvvis(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (cursor_normal) {
|
||||
if (cursor_visible) {
|
||||
ptext("(cvvis) Make cursor very visible. ");
|
||||
tc_putp(cursor_visible);
|
||||
ptext("If the cursor is not very visible then (cvvis) has failed. ");
|
||||
} else {
|
||||
ptext("(cvvis) Cursor-very-visible is not defined. ");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
tc_putp(cursor_normal);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** charset_cnorm(test_list, status, ch)
|
||||
**
|
||||
** (cnorm) test Cursor normal
|
||||
*/
|
||||
static void
|
||||
charset_cnorm(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (cursor_normal) {
|
||||
ptext("(cnorm) Normal cursor. ");
|
||||
tc_putp(cursor_normal);
|
||||
ptext("If the cursor is not normal then (cnorm) has failed. ");
|
||||
} else {
|
||||
ptext("(cnorm) Cursor-normal is not defined. ");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** charset_enacs(test_list, status, ch)
|
||||
**
|
||||
** test Alternate character set mode and alternate characters
|
||||
** (acsc) (enacs) (smacs) (rmacs)
|
||||
*/
|
||||
static void
|
||||
charset_enacs(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int c, i;
|
||||
|
||||
if (enter_alt_charset_mode || acs_chars) {
|
||||
c = 0;
|
||||
while (1) {
|
||||
put_clear();
|
||||
/*
|
||||
for terminals that use separate fonts for
|
||||
attributes (such as X windows) the line
|
||||
drawing characters must be checked for
|
||||
each font.
|
||||
*/
|
||||
if (c >= '0' && c <= '9') {
|
||||
test_acs(alt_modes[c - '0'].number);
|
||||
set_attr(0);
|
||||
} else {
|
||||
test_acs(0);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
ptextln("[r] to repeat, [012345789] to test with attributes on, [?] for a list of attributes, anything else to go to next test. ");
|
||||
generic_done_message(t, state, ch);
|
||||
if (*ch != '?') {
|
||||
break;
|
||||
}
|
||||
for (i = 0; i <= 9; i++) {
|
||||
sprintf(temp, " %d %s %s", i, alt_modes[i].begin_mode,
|
||||
alt_modes[i].name);
|
||||
ptextln(temp);
|
||||
}
|
||||
}
|
||||
if (*ch >= '0' && *ch <= '9') {
|
||||
c = *ch;
|
||||
} else
|
||||
if (*ch != 'r') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ptext("(smacs) Enter-alt-char-set-mode and (acsc) Alternate-char-set are not defined. ");
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** charset_can_test()
|
||||
**
|
||||
** Initialize the can_test data base
|
||||
*/
|
||||
void
|
||||
charset_can_test(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 9; i++) {
|
||||
can_test(alt_modes[i].begin_mode, FLAG_CAN_TEST);
|
||||
can_test(alt_modes[i].end_mode, FLAG_CAN_TEST);
|
||||
}
|
||||
}
|
@ -1,769 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <tack.h>
|
||||
|
||||
MODULE_ID("$Id: color.c,v 1.7 2006/11/26 00:14:25 tom Exp $")
|
||||
|
||||
/*
|
||||
* Color terminal tests. Has only one entry point: test_color().
|
||||
*/
|
||||
|
||||
static void color_check(struct test_list *, int *, int *);
|
||||
static void color_setf(struct test_list *, int *, int *);
|
||||
static void color_matrix(struct test_list *, int *, int *);
|
||||
static void color_ncv(struct test_list *, int *, int *);
|
||||
static void color_ccc(struct test_list *, int *, int *);
|
||||
static void color_bce(struct test_list *, int *, int *);
|
||||
|
||||
struct test_list color_test_list[] = {
|
||||
{0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu},
|
||||
{MENU_NEXT, 2, "colors) (pairs", 0, 0, color_check, 0},
|
||||
{MENU_NEXT, 12, "setf) (setb) (scp", 0, 0, color_setf, 0},
|
||||
{MENU_NEXT, 24, "op", 0, 0, color_matrix, 0},
|
||||
{MENU_NEXT, 16, "ncv", 0, 0, color_ncv, 0},
|
||||
{MENU_NEXT, 0, "bce", 0, 0, color_bce, 0},
|
||||
{MENU_NEXT | MENU_CLEAR, 0, "ccc) (initc) (initp", "hls op oc", 0, color_ccc, 0},
|
||||
{MENU_LAST, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
#ifndef COLOR_BLACK
|
||||
#define COLOR_BLACK 0
|
||||
#define COLOR_BLUE 1
|
||||
#define COLOR_GREEN 2
|
||||
#define COLOR_CYAN 3
|
||||
#define COLOR_RED 4
|
||||
#define COLOR_MAGENTA 5
|
||||
#define COLOR_YELLOW 6
|
||||
#define COLOR_WHITE 7
|
||||
#endif
|
||||
|
||||
struct color_table {
|
||||
const char *name;
|
||||
int index;
|
||||
int r, g, b;
|
||||
int h, l, s;
|
||||
};
|
||||
|
||||
static struct color_table def_colors[8] = {
|
||||
{"black ", COLOR_BLACK, 0, 0, 0, 0, 0, 0},
|
||||
{"blue ", COLOR_BLUE, 0, 0, 1000, 330, 50, 100},
|
||||
{"green ", COLOR_GREEN, 0, 1000, 0, 240, 50, 100},
|
||||
{"cyan ", COLOR_CYAN, 0, 1000, 1000, 300, 50, 100},
|
||||
{"red ", COLOR_RED, 1000, 0, 0, 120, 50, 100},
|
||||
{"magenta", COLOR_MAGENTA, 1000, 0, 1000, 60, 50, 100},
|
||||
{"yellow ", COLOR_YELLOW, 1000, 1000, 0, 180, 50, 100},
|
||||
{"white ", COLOR_WHITE, 1000, 1000, 1000, 0, 100, 0}
|
||||
};
|
||||
|
||||
#define MAX_PAIR 256
|
||||
static int fg_color[MAX_PAIR] = {COLOR_BLACK, COLOR_BLUE, COLOR_GREEN,
|
||||
COLOR_CYAN, COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE};
|
||||
static int bg_color[MAX_PAIR] = {COLOR_BLACK, COLOR_BLACK, COLOR_BLACK,
|
||||
COLOR_BLACK, COLOR_BLACK, COLOR_BLACK, COLOR_BLACK, COLOR_BLACK};
|
||||
static int pairs_used = 8;
|
||||
static int a_bright_color, bright_value;
|
||||
static int cookie_monster, color_step, colors_per_line;
|
||||
static int R, G, B;
|
||||
|
||||
static void reset_colors(void)
|
||||
{
|
||||
tc_putp(orig_colors);
|
||||
tc_putp(TPARM_0(orig_pair));
|
||||
}
|
||||
|
||||
static int
|
||||
color_trans(int c)
|
||||
{ /* translate or load the color */
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pairs_used; i++) {
|
||||
if (fg_color[i] == c) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (!can_change) {
|
||||
return 0;
|
||||
}
|
||||
if (pairs_used > max_colors || pairs_used >= MAX_PAIR) {
|
||||
pairs_used = 0;
|
||||
ptextln("Ran out of colors");
|
||||
}
|
||||
fg_color[pairs_used] = c;
|
||||
bg_color[pairs_used] = c;
|
||||
if (hue_lightness_saturation) {
|
||||
tc_putp(TPARM_4(initialize_color, pairs_used,
|
||||
def_colors[c].h, def_colors[c].l, def_colors[c].s));
|
||||
} else {
|
||||
tc_putp(TPARM_4(initialize_color, pairs_used,
|
||||
def_colors[c].r, def_colors[c].g, def_colors[c].b));
|
||||
}
|
||||
return pairs_used++;
|
||||
}
|
||||
|
||||
static void
|
||||
new_color(
|
||||
int fg,
|
||||
int bg,
|
||||
int hungry)
|
||||
{ /* change the color to fg and bg. */
|
||||
int i;
|
||||
|
||||
if (hungry) {
|
||||
eat_cookie();
|
||||
}
|
||||
if (set_a_foreground) {
|
||||
/* set ANSI color (setaf) (setab) */
|
||||
tc_putp(TPARM_1(set_a_foreground, fg));
|
||||
tc_putp(TPARM_1(set_a_background, bg));
|
||||
} else if (set_foreground) {
|
||||
/* make sure black is zero */
|
||||
(void) color_trans(COLOR_BLACK);
|
||||
tc_putp(TPARM_1(set_foreground, color_trans(fg)));
|
||||
tc_putp(TPARM_1(set_background, color_trans(bg)));
|
||||
} else { /* set color pair */
|
||||
for (i = 0; i < pairs_used; i++) {
|
||||
if (fg_color[i] == fg && bg_color[i] == bg) {
|
||||
tc_putp(TPARM_1(set_color_pair, i));
|
||||
if (hungry) {
|
||||
eat_cookie();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!can_change) {
|
||||
/* try to set just the foreground */
|
||||
for (i = pairs_used - 1; i; i--) {
|
||||
if (fg_color[i] == fg)
|
||||
break;
|
||||
}
|
||||
tc_putp(TPARM_1(set_color_pair, i));
|
||||
if (hungry) {
|
||||
eat_cookie();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (pairs_used > max_pairs || pairs_used >= MAX_PAIR) {
|
||||
pairs_used = 0;
|
||||
ptextln("Ran out of color pairs");
|
||||
}
|
||||
fg_color[pairs_used] = fg;
|
||||
bg_color[pairs_used] = bg;
|
||||
if (hue_lightness_saturation) {
|
||||
tc_putp(TPARM_7(initialize_pair, pairs_used,
|
||||
def_colors[fg].h, def_colors[fg].l, def_colors[fg].s,
|
||||
def_colors[bg].h, def_colors[bg].l, def_colors[bg].s));
|
||||
} else {
|
||||
tc_putp(TPARM_7(initialize_pair, pairs_used,
|
||||
def_colors[fg].r, def_colors[fg].g, def_colors[fg].b,
|
||||
def_colors[bg].r, def_colors[bg].g, def_colors[bg].b));
|
||||
}
|
||||
tc_putp(TPARM_1(set_color_pair, pairs_used));
|
||||
pairs_used++;
|
||||
}
|
||||
if (hungry) {
|
||||
eat_cookie();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_color_step(void)
|
||||
{ /* set the color_step for the (ccc) display */
|
||||
int i;
|
||||
|
||||
for (i = 2; i < 1000; i++) {
|
||||
if ((i * i * i) >= max_colors) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
color_step = 1000 / (i - 1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rgb_2_hls(int r, int g, int b, int *h, int *l, int *s)
|
||||
{ /* convert RGB to HLS system */
|
||||
int min, max, t;
|
||||
|
||||
if ((min = g < r ? g : r) > b) {
|
||||
min = b;
|
||||
}
|
||||
if ((max = g > r ? g : r) < b) {
|
||||
max = b;
|
||||
}
|
||||
|
||||
/* calculate lightness */
|
||||
*l = (min + max) / 20;
|
||||
|
||||
if (min == max) { /* black, white and all shades of gray */
|
||||
*h = 0;
|
||||
*s = 0;
|
||||
return;
|
||||
}
|
||||
/* calculate saturation */
|
||||
if (*l < 50) {
|
||||
*s = ((max - min) * 100) / (max + min);
|
||||
} else {
|
||||
*s = ((max - min) * 100) / (2000 - max - min);
|
||||
}
|
||||
|
||||
/* calculate hue */
|
||||
if (r == max) {
|
||||
t = 120 + ((g - b) * 60) / (max - min);
|
||||
} else if (g == max) {
|
||||
t = 240 + ((b - r) * 60) / (max - min);
|
||||
} else {
|
||||
t = 360 + ((r - g) * 60) / (max - min);
|
||||
}
|
||||
*h = t % 360;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
send_color(int p, int r, int g, int b)
|
||||
{ /* send the initialize_color (initc) command */
|
||||
int h, l, s;
|
||||
|
||||
if (hue_lightness_saturation) {
|
||||
rgb_2_hls(r, g, b, &h, &l, &s);
|
||||
tc_putp(TPARM_4(initialize_color, p, h, l, s));
|
||||
} else {
|
||||
tc_putp(TPARM_4(initialize_color, p, r, g, b));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
send_pair(int p, int fr, int fg, int fb, int br, int bg, int bb)
|
||||
{ /* send the initialize_pair (initp) command */
|
||||
int fh, fl, fs, bh, bl, bs;
|
||||
|
||||
if (hue_lightness_saturation) {
|
||||
rgb_2_hls(fr, fg, fb, &fh, &fl, &fs);
|
||||
rgb_2_hls(br, bg, bb, &bh, &bl, &bs);
|
||||
tc_putp(TPARM_7(initialize_pair, p, fh, fl, fs, bh, bl, bs));
|
||||
} else {
|
||||
tc_putp(TPARM_7(initialize_pair, p, fr, fg, fb, bb, bg, bb));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
load_palette(int n)
|
||||
{ /* load the color palette */
|
||||
int rgb;
|
||||
|
||||
for (;;) {
|
||||
if (pairs_used >= n) {
|
||||
return FALSE;
|
||||
}
|
||||
if (set_a_foreground || set_foreground) {
|
||||
if (pairs_used >= max_colors) {
|
||||
return FALSE;
|
||||
}
|
||||
send_color(pairs_used, R, G, B);
|
||||
rgb = R + G + B;
|
||||
if (rgb > bright_value) {
|
||||
bright_value = rgb;
|
||||
a_bright_color = pairs_used;
|
||||
}
|
||||
} else {
|
||||
if (pairs_used >= max_pairs) {
|
||||
return FALSE;
|
||||
}
|
||||
if (pairs_used == 0) {
|
||||
send_pair(pairs_used, 1000, 1000, 1000, R, G, B);
|
||||
} else {
|
||||
send_pair(pairs_used, R, G, B, R, G, B);
|
||||
}
|
||||
}
|
||||
pairs_used++;
|
||||
if ((B += color_step) > 1000) {
|
||||
B = 0;
|
||||
if ((G += color_step) > 1000) {
|
||||
G = 0;
|
||||
if ((R += color_step) > 1000) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
rainbow(int n)
|
||||
{ /* print the programmable color display */
|
||||
int i, c, d, palette_full, initial_pair;
|
||||
static const struct {
|
||||
const char *name;
|
||||
char ch;
|
||||
} splat[] = {
|
||||
{"Bg normal", ' '},
|
||||
{"Fg normal", ' '},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
if ((set_a_foreground || set_foreground)
|
||||
? pairs_used >= max_colors
|
||||
: pairs_used >= max_pairs) {
|
||||
ptext("New palette: ");
|
||||
(void) wait_here();
|
||||
initial_pair = pairs_used = 1;
|
||||
bright_value = 0;
|
||||
} else if (line_count + 3 >= lines) {
|
||||
ptext("Go: ");
|
||||
(void) wait_here();
|
||||
put_clear();
|
||||
initial_pair = pairs_used = 1;
|
||||
bright_value = 0;
|
||||
n++;
|
||||
} else {
|
||||
initial_pair = pairs_used;
|
||||
n += initial_pair;
|
||||
}
|
||||
palette_full = load_palette(n);
|
||||
for (d = 0; splat[d].name; d++) {
|
||||
c = splat[d].ch;
|
||||
if (d == 1) {
|
||||
put_mode(enter_reverse_mode);
|
||||
}
|
||||
for (i = initial_pair; i < n; i++) {
|
||||
if (i >= pairs_used) {
|
||||
break;
|
||||
}
|
||||
if (set_a_foreground) {
|
||||
if (i >= max_colors) {
|
||||
break;
|
||||
}
|
||||
tc_putp(TPARM_1(set_a_foreground, i));
|
||||
tc_putp(TPARM_1(set_a_background, i));
|
||||
} else if (set_foreground) {
|
||||
if (i >= max_colors) {
|
||||
break;
|
||||
}
|
||||
tc_putp(TPARM_1(set_foreground, i));
|
||||
tc_putp(TPARM_1(set_background, i));
|
||||
} else {
|
||||
if (i >= max_pairs) {
|
||||
break;
|
||||
}
|
||||
tc_putp(TPARM_1(set_color_pair, i));
|
||||
}
|
||||
putchp(c);
|
||||
}
|
||||
if (d == 1) {
|
||||
put_mode(exit_attribute_mode);
|
||||
}
|
||||
if (set_a_foreground) {
|
||||
tc_putp(TPARM_1(set_a_foreground, a_bright_color));
|
||||
tc_putp(TPARM_1(set_a_background, 0));
|
||||
} else if (set_foreground) {
|
||||
tc_putp(TPARM_1(set_foreground, a_bright_color));
|
||||
tc_putp(TPARM_1(set_background, 0));
|
||||
} else {
|
||||
tc_putp(TPARM_1(set_color_pair, 0));
|
||||
}
|
||||
put_str(" ");
|
||||
put_str(splat[d].name);
|
||||
put_crlf();
|
||||
}
|
||||
return palette_full;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ncv_display(int m)
|
||||
{ /* print the no_color_video (ncv) test line */
|
||||
putchp('0' + m);
|
||||
putchp(' ');
|
||||
eat_cookie();
|
||||
set_attr(1 << m);
|
||||
sprintf(temp, "%-11s", alt_modes[m].name);
|
||||
put_str(temp);
|
||||
|
||||
new_color(COLOR_BLUE, COLOR_BLACK, TRUE);
|
||||
put_str("blue");
|
||||
|
||||
new_color(COLOR_BLACK, COLOR_GREEN, TRUE);
|
||||
put_str("green");
|
||||
|
||||
new_color(COLOR_WHITE, COLOR_BLACK, TRUE);
|
||||
put_str(alt_modes[m].name);
|
||||
eat_cookie();
|
||||
set_attr(0);
|
||||
reset_colors();
|
||||
put_crlf();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dump_colors(void)
|
||||
{ /* display the colors in some esthetic
|
||||
pattern */
|
||||
static int xmap[8] = {0, 3, 4, 7, 1, 2, 5, 6};
|
||||
int i, j, k, xi, xj, width, p, cs;
|
||||
int found_one;
|
||||
|
||||
cs = color_step <= 125 ? 125 : color_step;
|
||||
width = (1000 / cs) + 1;
|
||||
for (xi = 0; xi < 16; xi++) {
|
||||
i = (xi & 8) ? xi ^ 15 : xi;
|
||||
R = i * cs;
|
||||
if (R <= 1000) {
|
||||
found_one = FALSE;
|
||||
for (xj = 0; xj < 32; xj++) {
|
||||
j = ((xj & 8) ? xj ^ 15 : xj) & 7;
|
||||
k = xmap[((xi >> 1) & 4) + (xj >> 3)];
|
||||
G = j * cs;
|
||||
B = k * cs;
|
||||
if (G <= 1000 && B <= 1000) {
|
||||
p = (k * width + j) * width + i;
|
||||
if (set_a_background) {
|
||||
if (p >= max_colors) {
|
||||
continue;
|
||||
}
|
||||
send_color(p, R, G, B);
|
||||
tc_putp(TPARM_1(set_a_background, p));
|
||||
} else if (set_background) {
|
||||
if (p >= max_colors) {
|
||||
continue;
|
||||
}
|
||||
send_color(p, R, G, B);
|
||||
tc_putp(TPARM_1(set_background, p));
|
||||
} else {
|
||||
if (p >= max_pairs) {
|
||||
continue;
|
||||
}
|
||||
send_pair(p, R, G, B, R, G, B);
|
||||
tc_putp(TPARM_1(set_color_pair, p));
|
||||
}
|
||||
found_one = TRUE;
|
||||
putchp(' ');
|
||||
putchp(' ');
|
||||
}
|
||||
}
|
||||
if (found_one) {
|
||||
put_crlf();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** color_check(test_list, status, ch)
|
||||
**
|
||||
** test (colors) and (pairs)
|
||||
*/
|
||||
static void
|
||||
color_check(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (max_colors <= 0 && max_pairs <= 0) {
|
||||
ptext("This is not a color terminal; (colors) and (pairs) are missing. ");
|
||||
*state |= MENU_STOP;
|
||||
} else {
|
||||
sprintf(temp, "This terminal can display %d colors and %d color pairs. (colors) (pairs)",
|
||||
max_colors, max_pairs);
|
||||
ptextln(temp);
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** color_setf(test_list, status, ch)
|
||||
**
|
||||
** test (setf) (setb) and (scp)
|
||||
*/
|
||||
static void
|
||||
color_setf(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (max_colors <= 0 && max_pairs <= 0) {
|
||||
ptext("This is not a color terminal; (colors) and (pairs) are missing. ");
|
||||
generic_done_message(t, state, ch);
|
||||
*state |= MENU_STOP;
|
||||
return;
|
||||
}
|
||||
if ((set_a_foreground == NULL || set_a_background == NULL)
|
||||
&& (set_foreground == NULL || set_background == NULL)
|
||||
&& set_color_pair == NULL) {
|
||||
ptextln("Both set foreground (setaf/setf) and set color pair (scp) are not present.");
|
||||
if (!set_a_background || !set_background) {
|
||||
ptextln("(setab/setb) set background not present");
|
||||
}
|
||||
ptext("These must be defined for color testing. ");
|
||||
generic_done_message(t, state, ch);
|
||||
*state |= MENU_STOP;
|
||||
return;
|
||||
}
|
||||
/* initialize the color palette */
|
||||
pairs_used = max_colors >= 8 ? 8 : max_colors;
|
||||
reset_colors();
|
||||
new_color(COLOR_WHITE, COLOR_BLACK, FALSE);
|
||||
|
||||
ptextln("(setf) (setb) (scp) The following colors are predefined:");
|
||||
ptextln("\n Foreground Background");
|
||||
put_crlf();
|
||||
j = max_colors > 8 ? 8 : max_colors;
|
||||
/*
|
||||
* the black on white test is the same as the white on black test.
|
||||
*/
|
||||
for (i = 1; i < j; i++) {
|
||||
putchp('0' + def_colors[i].index);
|
||||
putchp(' ');
|
||||
sprintf(temp, " %s ", def_colors[i].name);
|
||||
|
||||
new_color(def_colors[i].index, COLOR_BLACK, TRUE);
|
||||
put_str(temp);
|
||||
|
||||
new_color(COLOR_BLACK, COLOR_BLACK, TRUE);
|
||||
put_str(" ");
|
||||
|
||||
new_color(COLOR_BLACK, def_colors[i].index, TRUE);
|
||||
put_str(temp);
|
||||
|
||||
new_color(COLOR_WHITE, COLOR_BLACK, FALSE);
|
||||
put_crlf();
|
||||
}
|
||||
reset_colors();
|
||||
put_crlf();
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** color_matrix(test_list, status, ch)
|
||||
**
|
||||
** test (pairs) (op)
|
||||
*/
|
||||
static void
|
||||
color_matrix(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i, j, matrix_size, matrix_area, brightness;
|
||||
|
||||
matrix_size = max_colors > 8 ? 8 : max_colors;
|
||||
|
||||
sprintf(temp, "(pairs) There are %d color pairs.", max_pairs);
|
||||
ptextln(temp);
|
||||
|
||||
for ( ; matrix_size; matrix_size--) {
|
||||
if (matrix_size * matrix_size <= max_pairs) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
matrix_area = matrix_size * matrix_size;
|
||||
for (brightness = 0; brightness < 2; brightness++) {
|
||||
put_crlf();
|
||||
sprintf(temp,
|
||||
"%dx%d matrix of foreground/background colors, bright *o%s*",
|
||||
matrix_size, matrix_size, brightness ? "n" : "ff");
|
||||
put_str(temp);
|
||||
|
||||
put_str("\n ");
|
||||
for (i = 0; i < matrix_size; i++) {
|
||||
(void) sprintf(temp, "%-8s", def_colors[i].name);
|
||||
put_str(temp);
|
||||
}
|
||||
for (j = 0; j < matrix_area; j++) {
|
||||
if (j % matrix_size == 0) {
|
||||
reset_colors();
|
||||
put_crlf();
|
||||
if (brightness) {
|
||||
tc_putp(exit_attribute_mode);
|
||||
}
|
||||
(void) sprintf(temp, "%-8s", def_colors[j / matrix_size].name);
|
||||
put_str(temp);
|
||||
if (brightness) {
|
||||
put_mode(enter_bold_mode);
|
||||
}
|
||||
}
|
||||
new_color(def_colors[j % matrix_size].index,
|
||||
def_colors[j / matrix_size].index,
|
||||
FALSE);
|
||||
put_str(" Hello ");
|
||||
}
|
||||
reset_colors();
|
||||
if (brightness) {
|
||||
tc_putp(exit_attribute_mode);
|
||||
}
|
||||
put_crlf();
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** color_ncv(test_list, status, ch)
|
||||
**
|
||||
** test (ncv)
|
||||
*/
|
||||
static void
|
||||
color_ncv(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (no_color_video == -1) {
|
||||
/* I have no idea what this means */
|
||||
return;
|
||||
}
|
||||
sprintf(temp, "According to no_color_video (ncv) which is %d, the following attributes should work correctly with color.", no_color_video);
|
||||
ptextln(temp);
|
||||
put_crlf();
|
||||
set_attr(0);
|
||||
ncv_display(0);
|
||||
for (i = 1; i <= 9; i++) {
|
||||
if (((no_color_video >> (mode_map[i] - 1)) & 1) == 0) {
|
||||
ncv_display(mode_map[i]);
|
||||
}
|
||||
}
|
||||
if (no_color_video & 0x3ff) {
|
||||
ptextln("\nThe following attributes should not work correctly with color. (ncv)\n");
|
||||
for (i = 1; i <= 9; i++) {
|
||||
if ((no_color_video >> (mode_map[i] - 1)) & 1) {
|
||||
ncv_display(mode_map[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
reset_colors();
|
||||
put_crlf();
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** color_bce(test_list, status, ch)
|
||||
**
|
||||
** test (bce) background color erase
|
||||
*/
|
||||
static void
|
||||
color_bce(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
new_color(COLOR_CYAN, COLOR_BLUE, FALSE);
|
||||
put_clear();
|
||||
put_newlines(2);
|
||||
reset_colors();
|
||||
ptextln("If the two lines above are blue then back_color_erase (bce) should be true.");
|
||||
sprintf(temp, "(bce) is %s in the data base.", back_color_erase ? "true" : "false");
|
||||
ptextln(temp);
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** color_ccc(test_list, status, ch)
|
||||
**
|
||||
** test (ccc) color palette test (oc) (op) (initc) (initp)
|
||||
*/
|
||||
static void
|
||||
color_ccc(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!can_change) {
|
||||
ptextln("Terminal can not change colors (ccc)");
|
||||
generic_done_message(t, state, ch);
|
||||
return;
|
||||
}
|
||||
reset_colors();
|
||||
pairs_used = 0;
|
||||
new_color(COLOR_WHITE, COLOR_BLACK, FALSE);
|
||||
sprintf(temp, "Reloading colors (init%c) using %s method",
|
||||
set_foreground ? 'c' : 'p',
|
||||
hue_lightness_saturation ? "HLS" : "RGB");
|
||||
ptextln(temp);
|
||||
put_crlf();
|
||||
j = max_colors > 7 ? 7 : max_colors;
|
||||
/* redisplay the above test with reinitialized colors */
|
||||
/* If these colors don't look right to you... */
|
||||
for (i = 0; i < j; i++) {
|
||||
sprintf(temp, " %s ", def_colors[i ^ 7].name);
|
||||
|
||||
new_color(i ^ 7, COLOR_BLACK, TRUE);
|
||||
put_str(temp);
|
||||
|
||||
new_color(COLOR_BLACK, COLOR_BLACK, TRUE);
|
||||
put_str(" ");
|
||||
|
||||
new_color(COLOR_BLACK, i ^ 7, TRUE);
|
||||
put_str(temp);
|
||||
|
||||
new_color(COLOR_WHITE, COLOR_BLACK, FALSE);
|
||||
put_crlf();
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
if (*ch != 0 && *ch != 'n') {
|
||||
reset_colors();
|
||||
return;
|
||||
}
|
||||
|
||||
pairs_used = 0;
|
||||
cookie_monster = 0;
|
||||
if (magic_cookie_glitch > 0) {
|
||||
cookie_monster =
|
||||
((set_a_foreground || set_foreground)
|
||||
? magic_cookie_glitch : 0) +
|
||||
((set_a_background || set_background)
|
||||
? magic_cookie_glitch : 0) +
|
||||
(set_color_pair ? magic_cookie_glitch : 0);
|
||||
}
|
||||
set_color_step();
|
||||
colors_per_line = max_colors > max_pairs
|
||||
? max_pairs : max_colors;
|
||||
j = (columns - 14) / (cookie_monster + 1);
|
||||
if (colors_per_line > j) {
|
||||
colors_per_line = (j / i) * i;
|
||||
}
|
||||
sprintf(temp, "RGB color step %d, cookies %d", color_step,
|
||||
cookie_monster);
|
||||
ptextln(temp);
|
||||
|
||||
R = G = B = 0;
|
||||
pairs_used = 0;
|
||||
for (;;) {
|
||||
if (rainbow(colors_per_line)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
if (*ch != 0 && *ch != 'n') {
|
||||
reset_colors();
|
||||
return;
|
||||
}
|
||||
dump_colors();
|
||||
reset_colors();
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
@ -1,664 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <tack.h>
|
||||
|
||||
#if HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
MODULE_ID("$Id: control.c,v 1.9 2006/06/24 21:27:53 tom Exp $")
|
||||
|
||||
/* terminfo test program control subroutines */
|
||||
|
||||
#if HAVE_GETTIMEOFDAY
|
||||
#define MY_TIMER struct timeval
|
||||
#else
|
||||
#define MY_TIMER time_t
|
||||
#endif
|
||||
|
||||
/* globals */
|
||||
int test_complete; /* counts number of tests completed */
|
||||
|
||||
char txt_longer_test_time[80]; /* +) use longer time */
|
||||
char txt_shorter_test_time[80]; /* -) use shorter time */
|
||||
static int pad_test_duration = 1; /* number of seconds for a pad test */
|
||||
int auto_pad_mode; /* run the time tests */
|
||||
int no_alarm_event; /* TRUE if the alarm has not gone off yet */
|
||||
unsigned long usec_run_time; /* length of last test in microseconds */
|
||||
static MY_TIMER stop_watch[MAX_TIMERS]; /* Hold the start timers */
|
||||
|
||||
char txt_longer_augment[80]; /* >) use bigger augment */
|
||||
char txt_shorter_augment[80]; /* <) use smaller augment */
|
||||
|
||||
/* caps under test data base */
|
||||
int tt_delay_max; /* max number of milliseconds we can delay */
|
||||
int tt_delay_used; /* number of milliseconds consumed in delay */
|
||||
const char *tt_cap[TT_MAX]; /* value of string */
|
||||
int tt_affected[TT_MAX]; /* lines or columns effected (repetition factor) */
|
||||
int tt_count[TT_MAX]; /* Number of times sent */
|
||||
int tt_delay[TT_MAX]; /* Number of milliseconds delay */
|
||||
int ttp; /* number of entries used */
|
||||
|
||||
/* Saved value of the above data base */
|
||||
const char *tx_cap[TT_MAX]; /* value of string */
|
||||
int tx_affected[TT_MAX]; /* lines or columns effected (repetition factor) */
|
||||
int tx_count[TT_MAX]; /* Number of times sent */
|
||||
int tx_index[TT_MAX]; /* String index */
|
||||
int tx_delay[TT_MAX]; /* Number of milliseconds delay */
|
||||
int txp; /* number of entries used */
|
||||
int tx_characters; /* printing characters sent by test */
|
||||
unsigned long tx_cps; /* characters per second */
|
||||
static struct test_list *tx_source; /* The test that generated this data */
|
||||
|
||||
#define RESULT_BLOCK 1024
|
||||
static int blocks; /* number of result blocks available */
|
||||
static struct test_results *results; /* pointer to next available */
|
||||
static struct test_results **pads; /* save pad results here */
|
||||
|
||||
static void
|
||||
alloc_arrays(void)
|
||||
{
|
||||
if (pads == 0) {
|
||||
pads = (struct test_results **)calloc(MAX_STRINGS, sizeof(struct test_results *));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** event_start(number)
|
||||
**
|
||||
** Begin the stopwatch at the current time-of-day.
|
||||
*/
|
||||
void
|
||||
event_start(int n)
|
||||
{
|
||||
#if HAVE_GETTIMEOFDAY
|
||||
(void) gettimeofday(&stop_watch[n], (struct timezone *)0);
|
||||
#else
|
||||
stop_watch[n] = time((time_t *)0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** event_time(number)
|
||||
**
|
||||
** Return the number of milliseconds since this stop watch began.
|
||||
*/
|
||||
long
|
||||
event_time(int n)
|
||||
{
|
||||
#if HAVE_GETTIMEOFDAY
|
||||
MY_TIMER current_time;
|
||||
|
||||
(void) gettimeofday(¤t_time, (struct timezone *)0);
|
||||
return ((current_time.tv_sec - stop_watch[n].tv_sec) * 1000000)
|
||||
+ current_time.tv_usec - stop_watch[n].tv_usec;
|
||||
#else
|
||||
return (time((time_t *)0) - stop_watch[n]) * 1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Execution control for string capability tests
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
** get_next_block()
|
||||
**
|
||||
** Get a results block for pad test data.
|
||||
*/
|
||||
static struct test_results *
|
||||
get_next_block(void)
|
||||
{
|
||||
if (blocks <= 0) {
|
||||
results = (struct test_results *)
|
||||
malloc(sizeof(struct test_results) * RESULT_BLOCK);
|
||||
if (!results) {
|
||||
ptextln("Malloc failed");
|
||||
return (struct test_results *) 0;
|
||||
}
|
||||
blocks = RESULT_BLOCK;
|
||||
}
|
||||
blocks--;
|
||||
return results++;
|
||||
}
|
||||
|
||||
/*
|
||||
** set_augment_txt()
|
||||
**
|
||||
** Initialize the augment menu selections
|
||||
*/
|
||||
void
|
||||
set_augment_txt(void)
|
||||
{
|
||||
sprintf(txt_longer_augment,
|
||||
">) Change lines/characters effected to %d", augment << 1);
|
||||
sprintf(txt_shorter_augment,
|
||||
"<) Change lines/characters effected to %d", augment >> 1);
|
||||
}
|
||||
|
||||
void
|
||||
control_init(void)
|
||||
{
|
||||
sprintf(txt_longer_test_time, "+) Change test time to %d seconds",
|
||||
pad_test_duration + 1);
|
||||
sprintf(txt_shorter_test_time, "-) Change test time to %d seconds",
|
||||
pad_test_duration - 1);
|
||||
set_augment_txt();
|
||||
}
|
||||
|
||||
/*
|
||||
** msec_cost(cap, affected-count)
|
||||
**
|
||||
** Return the number of milliseconds delay needed by the cap.
|
||||
*/
|
||||
int
|
||||
msec_cost(
|
||||
const char *const cap,
|
||||
int affcnt)
|
||||
{
|
||||
int dec, value, total, star, ch;
|
||||
const char *cp;
|
||||
|
||||
if (!cap) {
|
||||
return 0;
|
||||
}
|
||||
total = 0;
|
||||
for (cp = cap; *cp; cp++) {
|
||||
if (*cp == '$' && cp[1] == '<') {
|
||||
star = 1;
|
||||
value = dec = 0;
|
||||
for (cp += 2; (ch = *cp); cp++) {
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
value = value * 10 + (ch - '0');
|
||||
dec *= 10;
|
||||
} else
|
||||
if (ch == '.') {
|
||||
dec = 1;
|
||||
} else
|
||||
if (ch == '*') {
|
||||
star = affcnt;
|
||||
} else
|
||||
if (ch == '>') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dec > 1) {
|
||||
total += (value * star) / dec;
|
||||
} else {
|
||||
total += (value * star);
|
||||
}
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/*
|
||||
** liberated(cap)
|
||||
**
|
||||
** Return the cap without padding
|
||||
*/
|
||||
char *
|
||||
liberated(char *cap)
|
||||
{
|
||||
static char cb[1024];
|
||||
char *ts, *ls;
|
||||
|
||||
cb[0] = '\0';
|
||||
ls = NULL;
|
||||
if (cap) {
|
||||
for (ts = cb; (*ts = *cap); ++cap) {
|
||||
if (*cap == '$' && cap[1] == '<') {
|
||||
ls = ts;
|
||||
}
|
||||
++ts;
|
||||
if (*cap == '>') {
|
||||
if (ls) {
|
||||
ts = ls;
|
||||
ls = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cb;
|
||||
}
|
||||
|
||||
/*
|
||||
** page_loop()
|
||||
**
|
||||
** send CR/LF or go home and bump letter
|
||||
*/
|
||||
void
|
||||
page_loop(void)
|
||||
{
|
||||
if (line_count + 2 >= lines) {
|
||||
NEXT_LETTER;
|
||||
go_home();
|
||||
} else {
|
||||
put_crlf();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** skip_pad_test(test-list-entry, state, ch, text)
|
||||
**
|
||||
** Print the start test line. Handle start up commands.
|
||||
** Return TRUE if a return is requested.
|
||||
*/
|
||||
int
|
||||
skip_pad_test(
|
||||
struct test_list *test,
|
||||
int *state,
|
||||
int *ch,
|
||||
const char *text)
|
||||
{
|
||||
char rep_text[16];
|
||||
|
||||
while(1) {
|
||||
if (text) {
|
||||
ptext(text);
|
||||
}
|
||||
if ((test->flags & MENU_LC_MASK)) {
|
||||
sprintf(rep_text, " *%d", augment);
|
||||
ptext(rep_text);
|
||||
}
|
||||
ptext(" [n] > ");
|
||||
*ch = wait_here();
|
||||
if (*ch == 's') {
|
||||
/* Skip is converted to next */
|
||||
*ch = 'n';
|
||||
return TRUE;
|
||||
}
|
||||
if (*ch == 'q') {
|
||||
/* Quit is converted to help */
|
||||
*ch = '?';
|
||||
return TRUE;
|
||||
}
|
||||
if (*ch == '\r' || *ch == '\n' || *ch == 'n' || *ch == 'r') {
|
||||
/* this is the only response that allows the test to run */
|
||||
*ch = 0;
|
||||
}
|
||||
if (subtest_menu(pad_test_list, state, ch)) {
|
||||
continue;
|
||||
}
|
||||
return (*ch != 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** pad_done_message(test_list)
|
||||
**
|
||||
** Print the Done message and request input.
|
||||
*/
|
||||
void
|
||||
pad_done_message(
|
||||
struct test_list *test,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int default_action = 0;
|
||||
char done_message[128];
|
||||
char rep_text[16];
|
||||
|
||||
while (1) {
|
||||
if ((test->flags & MENU_LC_MASK)) {
|
||||
sprintf(rep_text, "*%d", augment);
|
||||
} else {
|
||||
rep_text[0] = '\0';
|
||||
}
|
||||
if (test->caps_done) {
|
||||
sprintf(done_message, "(%s)%s Done ", test->caps_done,
|
||||
rep_text);
|
||||
ptext(done_message);
|
||||
} else {
|
||||
if (rep_text[0]) {
|
||||
ptext(rep_text);
|
||||
ptext(" ");
|
||||
}
|
||||
ptext("Done ");
|
||||
}
|
||||
if (debug_level & 2) {
|
||||
dump_test_stats(test, state, ch);
|
||||
} else {
|
||||
*ch = wait_here();
|
||||
}
|
||||
if (*ch == '\r' || *ch == '\n') {
|
||||
*ch = default_action;
|
||||
return;
|
||||
}
|
||||
if (*ch == 's' || *ch == 'n') {
|
||||
*ch = 0;
|
||||
return;
|
||||
}
|
||||
if (strchr(pad_repeat_test, *ch)) {
|
||||
/* default action is now repeat */
|
||||
default_action = 'r';
|
||||
}
|
||||
if (subtest_menu(pad_test_list, state, ch)) {
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** sliding_scale(dividend, factor, divisor)
|
||||
**
|
||||
** Return (dividend * factor) / divisor
|
||||
*/
|
||||
int
|
||||
sliding_scale(
|
||||
int dividend,
|
||||
int factor,
|
||||
unsigned long divisor)
|
||||
{
|
||||
double d = dividend;
|
||||
|
||||
if (divisor) {
|
||||
d = (d * (double) factor) / (double) divisor;
|
||||
return (int) (d + 0.5);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** pad_test_startup()
|
||||
**
|
||||
** Do the stuff needed to begin a test.
|
||||
*/
|
||||
void
|
||||
pad_test_startup(
|
||||
int do_clear)
|
||||
{
|
||||
if (do_clear) {
|
||||
put_clear();
|
||||
}
|
||||
repeats = augment;
|
||||
raw_characters_sent = 0;
|
||||
test_complete = ttp = char_count = tt_delay_used = 0;
|
||||
letter = letters[letter_number = 0];
|
||||
if (pad_test_duration <= 0) {
|
||||
pad_test_duration = 1;
|
||||
}
|
||||
tt_delay_max = pad_test_duration * 1000;
|
||||
set_alarm_clock(pad_test_duration);
|
||||
event_start(TIME_TEST);
|
||||
}
|
||||
|
||||
/*
|
||||
** still_testing()
|
||||
**
|
||||
** This function is called to see if the test loop should be terminated.
|
||||
*/
|
||||
int
|
||||
still_testing(void)
|
||||
{
|
||||
fflush(stdout);
|
||||
test_complete++;
|
||||
return EXIT_CONDITION;
|
||||
}
|
||||
|
||||
/*
|
||||
** pad_test_shutdown()
|
||||
**
|
||||
** Do the stuff needed to end a test.
|
||||
*/
|
||||
void
|
||||
pad_test_shutdown(
|
||||
struct test_list *t,
|
||||
int crlf)
|
||||
{
|
||||
int i;
|
||||
int counts; /* total counts */
|
||||
int ss; /* Save string index */
|
||||
int cpo; /* characters per operation */
|
||||
int delta; /* difference in characters */
|
||||
int bogus; /* Time is inaccurate */
|
||||
struct test_results *r; /* Results of current test */
|
||||
int ss_index[TT_MAX]; /* String index */
|
||||
|
||||
alloc_arrays();
|
||||
if (tty_can_sync == SYNC_TESTED) {
|
||||
bogus = tty_sync_error();
|
||||
} else {
|
||||
bogus = 1;
|
||||
}
|
||||
usec_run_time = event_time(TIME_TEST);
|
||||
tx_source = t;
|
||||
tx_characters = raw_characters_sent;
|
||||
tx_cps = sliding_scale(tx_characters, 1000000, usec_run_time);
|
||||
|
||||
/* save the data base */
|
||||
for (txp = ss = counts = 0; txp < ttp; txp++) {
|
||||
tx_cap[txp] = tt_cap[txp];
|
||||
tx_count[txp] = tt_count[txp];
|
||||
tx_delay[txp] = tt_delay[txp];
|
||||
tx_affected[txp] = tt_affected[txp];
|
||||
tx_index[txp] = get_string_cap_byvalue(tt_cap[txp]);
|
||||
if (tx_index[txp] >= 0) {
|
||||
if (cap_match(t->caps_done, strnames[tx_index[txp]])) {
|
||||
ss_index[ss++] = txp;
|
||||
counts += tx_count[txp];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (crlf) {
|
||||
put_crlf();
|
||||
}
|
||||
if (counts == 0 || tty_cps == 0 || bogus) {
|
||||
/* nothing to do */
|
||||
return;
|
||||
}
|
||||
/* calculate the suggested pad times */
|
||||
delta = usec_run_time - sliding_scale(tx_characters, 1000000, tty_cps);
|
||||
if (delta < 0) {
|
||||
/* probably should bump tx_characters */
|
||||
delta = 0;
|
||||
}
|
||||
cpo = delta / counts;
|
||||
for (i = 0; i < ss; i++) {
|
||||
if (!(r = get_next_block())) {
|
||||
return;
|
||||
}
|
||||
r->next = pads[tx_index[ss_index[i]]];
|
||||
pads[tx_index[ss_index[i]]] = r;
|
||||
r->test = t;
|
||||
r->reps = tx_affected[ss_index[i]];
|
||||
r->delay = cpo;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** show_cap_results(index)
|
||||
**
|
||||
** Display the previous results
|
||||
*/
|
||||
static void
|
||||
show_cap_results(
|
||||
int x)
|
||||
{
|
||||
struct test_results *r; /* a result */
|
||||
int delay;
|
||||
|
||||
alloc_arrays();
|
||||
if ((r = pads[x])) {
|
||||
sprintf(temp, "(%s)", strnames[x]);
|
||||
ptext(temp);
|
||||
while (r) {
|
||||
sprintf(temp, "$<%d>", r->delay / 1000);
|
||||
put_columns(temp, (int) strlen(temp), 10);
|
||||
r = r->next;
|
||||
}
|
||||
r = pads[x];
|
||||
while (r) {
|
||||
if (r->reps > 1) {
|
||||
delay = r->delay / (r->reps * 100);
|
||||
sprintf(temp, "$<%d.%d*>", delay / 10, delay % 10);
|
||||
put_columns(temp, (int) strlen(temp), 10);
|
||||
}
|
||||
r = r->next;
|
||||
}
|
||||
put_crlf();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** dump_test_stats(test_list, status, ch)
|
||||
**
|
||||
** Dump the statistics about the last test
|
||||
*/
|
||||
void
|
||||
dump_test_stats(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i, j;
|
||||
char tbuf[32];
|
||||
int x[32];
|
||||
|
||||
put_crlf();
|
||||
if (tx_source && tx_source->caps_done) {
|
||||
cap_index(tx_source->caps_done, x);
|
||||
if (x[0] >= 0) {
|
||||
sprintf(temp, "Caps summary for (%s)",
|
||||
tx_source->caps_done);
|
||||
ptextln(temp);
|
||||
for (i = 0; x[i] >= 0; i++) {
|
||||
show_cap_results(x[i]);
|
||||
}
|
||||
put_crlf();
|
||||
}
|
||||
}
|
||||
sprintf(tbuf, "%011lu", usec_run_time);
|
||||
sprintf(temp, "Test time: %lu.%s, characters per second %lu, characters %d",
|
||||
usec_run_time / 1000000UL, &tbuf[5], tx_cps, tx_characters);
|
||||
ptextln(temp);
|
||||
for (i = 0; i < txp; i++) {
|
||||
if ((j = get_string_cap_byvalue(tx_cap[i])) >= 0) {
|
||||
sprintf(tbuf, "(%s)", strnames[j]);
|
||||
} else {
|
||||
strcpy(tbuf, "(?)");
|
||||
}
|
||||
sprintf(temp, "%8d %3d $<%3d> %8s %s",
|
||||
tx_count[i], tx_affected[i], tx_delay[i],
|
||||
tbuf, expand(tx_cap[i]));
|
||||
putln(temp);
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** longer_test_time(test_list, status, ch)
|
||||
**
|
||||
** Extend the number of seconds for each test.
|
||||
*/
|
||||
void
|
||||
longer_test_time(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
pad_test_duration += 1;
|
||||
sprintf(txt_longer_test_time, "+) Change test time to %d seconds",
|
||||
pad_test_duration + 1);
|
||||
sprintf(txt_shorter_test_time, "-) Change test time to %d seconds",
|
||||
pad_test_duration - 1);
|
||||
sprintf(temp, "Tests will run for %d seconds", pad_test_duration);
|
||||
ptext(temp);
|
||||
*ch = REQUEST_PROMPT;
|
||||
}
|
||||
|
||||
/*
|
||||
** shorter_test_time(test_list, status, ch)
|
||||
**
|
||||
** Shorten the number of seconds for each test.
|
||||
*/
|
||||
void
|
||||
shorter_test_time(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
if (pad_test_duration > 1) {
|
||||
pad_test_duration -= 1;
|
||||
sprintf(txt_longer_test_time, "+) Change test time to %d seconds",
|
||||
pad_test_duration + 1);
|
||||
sprintf(txt_shorter_test_time, "-) Change test time to %d seconds",
|
||||
pad_test_duration - 1);
|
||||
}
|
||||
sprintf(temp, "Tests will run for %d second%s", pad_test_duration,
|
||||
pad_test_duration > 1 ? "s" : "");
|
||||
ptext(temp);
|
||||
*ch = REQUEST_PROMPT;
|
||||
}
|
||||
|
||||
/*
|
||||
** longer_augment(test_list, status, ch)
|
||||
**
|
||||
** Lengthen the number of lines/characters effected
|
||||
*/
|
||||
void
|
||||
longer_augment(
|
||||
struct test_list *t,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
augment <<= 1;
|
||||
set_augment_txt();
|
||||
if (augment_test) {
|
||||
t = augment_test;
|
||||
}
|
||||
sprintf(temp, "The pad tests will effect %d %s.", augment,
|
||||
((t->flags & MENU_LC_MASK) == MENU_lines) ?
|
||||
"lines" : "characters");
|
||||
ptextln(temp);
|
||||
*ch = REQUEST_PROMPT;
|
||||
}
|
||||
|
||||
/*
|
||||
** shorter_augment(test_list, status, ch)
|
||||
**
|
||||
** Shorten the number of lines/characters effected
|
||||
*/
|
||||
void
|
||||
shorter_augment(
|
||||
struct test_list *t,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
if (augment > 1) {
|
||||
/* don't let the augment go to zero */
|
||||
augment >>= 1;
|
||||
}
|
||||
set_augment_txt();
|
||||
if (augment_test) {
|
||||
t = augment_test;
|
||||
}
|
||||
sprintf(temp, "The pad tests will effect %d %s.", augment,
|
||||
((t->flags & MENU_LC_MASK) == MENU_lines) ?
|
||||
"lines" : "characters");
|
||||
ptextln(temp);
|
||||
*ch = REQUEST_PROMPT;
|
||||
}
|
@ -1,426 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <tack.h>
|
||||
|
||||
MODULE_ID("$Id: crum.c,v 1.5 2006/11/26 00:15:02 tom Exp $")
|
||||
|
||||
/*
|
||||
* Test cursor movement.
|
||||
*/
|
||||
|
||||
static void crum_clear(struct test_list *t, int *state, int *ch);
|
||||
static void crum_home(struct test_list *t, int *state, int *ch);
|
||||
static void crum_ll(struct test_list *t, int *state, int *ch);
|
||||
static void crum_move(struct test_list *t, int *state, int *ch);
|
||||
static void crum_os(struct test_list *t, int *state, int *ch);
|
||||
|
||||
static char crum_text[5][80];
|
||||
|
||||
struct test_list crum_test_list[] = {
|
||||
{0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu},
|
||||
{MENU_NEXT, 0, "clear", 0, 0, crum_clear, 0},
|
||||
{MENU_NEXT, 0, "home", 0, 0, crum_home, 0},
|
||||
{MENU_NEXT, 0, "ll", 0, 0, crum_ll, 0},
|
||||
{MENU_NEXT, 0, crum_text[0], "home cuu1", 0, crum_move, 0},
|
||||
{MENU_NEXT + 1, 0, crum_text[1], "cub1 cud1 cuf1 cuu1", 0, crum_move, 0},
|
||||
{MENU_NEXT + 2, 0, crum_text[2], "cub cud cuf cuu", 0, crum_move, 0},
|
||||
{MENU_NEXT + 3, 0, crum_text[3], "vpa hpa", 0, crum_move, 0},
|
||||
{MENU_NEXT + 4, 0, crum_text[4], "cup", 0, crum_move, 0},
|
||||
{MENU_NEXT, 0, "cup", "os", 0, crum_os, 0},
|
||||
{MENU_LAST, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
** move_to(from-row, from-column, to-row, to-column, selection)
|
||||
**
|
||||
** move the cursor from (rf, cf) to (rt, ct) using sel
|
||||
*/
|
||||
static void
|
||||
move_to(
|
||||
int rf,
|
||||
int cf,
|
||||
int rt,
|
||||
int ct,
|
||||
int sel)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (sel & 16) { /* use (cup) */
|
||||
s = TPARM_2(cursor_address, rt, ct);
|
||||
tputs(s, lines, tc_putch);
|
||||
return;
|
||||
}
|
||||
if (sel & 8) { /* use (hpa) (vpa) */
|
||||
if (column_address) {
|
||||
s = TPARM_1(column_address, ct);
|
||||
tputs(s, 1, tc_putch);
|
||||
cf = ct;
|
||||
}
|
||||
if (row_address) {
|
||||
s = TPARM_1(row_address, rt);
|
||||
tputs(s, 1, tc_putch);
|
||||
rf = rt;
|
||||
}
|
||||
}
|
||||
if (sel & 4) { /* parameterized relative cursor movement */
|
||||
if (parm_right_cursor)
|
||||
if (cf < ct) {
|
||||
s = TPARM_1(parm_right_cursor, ct - cf);
|
||||
tputs(s, ct - cf, tc_putch);
|
||||
cf = ct;
|
||||
}
|
||||
if (parm_left_cursor)
|
||||
if (cf > ct) {
|
||||
s = TPARM_1(parm_left_cursor, cf - ct);
|
||||
tputs(s, cf - ct, tc_putch);
|
||||
cf = ct;
|
||||
}
|
||||
if (parm_down_cursor)
|
||||
if (rf < rt) {
|
||||
s = TPARM_1(parm_down_cursor, rt - rf);
|
||||
tputs(s, rt - rf, tc_putch);
|
||||
rf = rt;
|
||||
}
|
||||
if (parm_up_cursor)
|
||||
if (rf > rt) {
|
||||
s = TPARM_1(parm_up_cursor, rf - rt);
|
||||
tputs(s, rf - rt, tc_putch);
|
||||
rf = rt;
|
||||
}
|
||||
}
|
||||
if (sel & 2) {
|
||||
if (cursor_left)
|
||||
while (cf > ct) {
|
||||
tc_putp(cursor_left);
|
||||
cf--;
|
||||
}
|
||||
/*
|
||||
do vertical motion next. Just in case cursor_down has a
|
||||
side effect of changing the column. This could happen if
|
||||
the tty handler translates NL to CRNL.
|
||||
*/
|
||||
if (cursor_down)
|
||||
while (rf < rt) {
|
||||
tc_putp(cursor_down);
|
||||
rf++;
|
||||
}
|
||||
if (cursor_up)
|
||||
while (rf > rt) {
|
||||
tc_putp(cursor_up);
|
||||
rf--;
|
||||
}
|
||||
if (cursor_right)
|
||||
while (cf < ct) {
|
||||
tc_putp(cursor_right);
|
||||
cf++;
|
||||
}
|
||||
}
|
||||
/* last chance */
|
||||
if (rf > rt) {
|
||||
if (can_go_home) { /* a bit drastic but ... */
|
||||
go_home();
|
||||
cf = 0;
|
||||
rf = 0;
|
||||
} else if (cursor_up) {
|
||||
while (rf > rt) {
|
||||
tc_putp(cursor_up);
|
||||
rf--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ct == 0 && rt > rf) {
|
||||
put_crlf();
|
||||
cf = 0;
|
||||
rf++;
|
||||
}
|
||||
if (ct == 0 && cf != 0) {
|
||||
put_cr();
|
||||
cf = 0;
|
||||
}
|
||||
while (rf < rt) {
|
||||
put_lf();
|
||||
rf++;
|
||||
}
|
||||
while (cf > ct) {
|
||||
put_str("\b");
|
||||
cf--;
|
||||
}
|
||||
if (cursor_right) {
|
||||
while (cf < ct) {
|
||||
tc_putp(cursor_right);
|
||||
cf++;
|
||||
}
|
||||
} else {
|
||||
/* go ahead and trash my display */
|
||||
while (cf < ct) {
|
||||
putchp(' ');
|
||||
cf++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** display_it(selection, text)
|
||||
**
|
||||
** print the display using sel
|
||||
*/
|
||||
static void
|
||||
display_it(
|
||||
int sel,
|
||||
char *txt)
|
||||
{
|
||||
int i, done_line;
|
||||
|
||||
put_clear();
|
||||
go_home();
|
||||
put_newlines(2);
|
||||
ptextln(" The top line should be alternating <'s and >'s");
|
||||
ptextln(" The left side should be alternating A's and V's");
|
||||
ptext(" Testing ");
|
||||
ptext(txt);
|
||||
put_cr();
|
||||
|
||||
/* horizontal */
|
||||
move_to(done_line = line_count, 0, 0, 2, sel);
|
||||
for (i = 4; i < columns - 2; i += 2) {
|
||||
putchp('>');
|
||||
move_to(0, i - 1, 0, i, sel);
|
||||
}
|
||||
putchp('>');
|
||||
i -= 2;
|
||||
move_to(0, i + 1, 0, i - 1, sel);
|
||||
for (; i > 2; i -= 2) {
|
||||
putchp('<');
|
||||
move_to(0, i, 0, i - 3, sel);
|
||||
}
|
||||
putchp('<');
|
||||
|
||||
/* vertical */
|
||||
move_to(0, 2, 0, 0, sel);
|
||||
for (i = 2; i < lines - 1; i += 2) {
|
||||
putchp('V');
|
||||
move_to(i - 2, 1, i, 0, sel);
|
||||
}
|
||||
putchp('V');
|
||||
i -= 2;
|
||||
move_to(i, 1, i + 1, 0, sel);
|
||||
for (; i > 0; i -= 2) {
|
||||
putchp('A');
|
||||
move_to(i + 1, 1, i - 1, 0, sel);
|
||||
}
|
||||
putchp('A');
|
||||
move_to(i + 1, 1, 0, 0, sel); /* go home first */
|
||||
move_to(0, 0, done_line + 1, 3, sel);
|
||||
put_str(txt);
|
||||
put_str(" Done. ");
|
||||
}
|
||||
|
||||
/*
|
||||
** crum_clear(test_list, status, ch)
|
||||
**
|
||||
** (clear) test Clear screen
|
||||
*/
|
||||
static void
|
||||
crum_clear(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (clear_screen) {
|
||||
for (i = lines; i > 1; i--) {
|
||||
putln("garbage");
|
||||
}
|
||||
put_clear();
|
||||
ptextln("This line should start in the home position.");
|
||||
ptext("The rest of the screen should be clear. ");
|
||||
} else {
|
||||
ptextln("(clear) Clear screen is not defined. ");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** crum_home(test_list, status, ch)
|
||||
**
|
||||
** (home) test Home cursor
|
||||
*/
|
||||
static void
|
||||
crum_home(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (cursor_home) {
|
||||
put_clear();
|
||||
put_newlines(lines / 2);
|
||||
go_home();
|
||||
put_crlf();
|
||||
ptext("The bottom line should have text.");
|
||||
go_home();
|
||||
put_newlines(lines - 1);
|
||||
ptext("This line is on the bottom.");
|
||||
go_home();
|
||||
ptextln("This line starts in the home position.");
|
||||
put_crlf();
|
||||
} else {
|
||||
ptextln("(home) Home cursor is not defined. ");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** crum_ll(test_list, status, ch)
|
||||
**
|
||||
** (ll) test Last line
|
||||
*/
|
||||
static void
|
||||
crum_ll(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
/*
|
||||
(ll) may be simulated with (cup). Don't complain if (cup) is present.
|
||||
*/
|
||||
if (cursor_to_ll) {
|
||||
put_clear();
|
||||
put_str("This line could be anywhere.");
|
||||
tc_putp(cursor_to_ll);
|
||||
ptext("This line should be on the bottom");
|
||||
go_home();
|
||||
put_crlf();
|
||||
} else
|
||||
if (cursor_address) {
|
||||
return;
|
||||
} else {
|
||||
ptextln("(ll) Move to last line is not defined. ");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** crum_move(test_list, status, ch)
|
||||
**
|
||||
** (*) test all cursor move commands
|
||||
*/
|
||||
static void
|
||||
crum_move(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
char buf[80];
|
||||
int n;
|
||||
|
||||
switch (n = (t->flags & 15)) {
|
||||
case 0:
|
||||
sprintf(buf, " (cr) (nel) (cub1)%s",
|
||||
cursor_home ? " (home)" : (cursor_up ? " (cuu1)" : ""));
|
||||
break;
|
||||
case 1:
|
||||
sprintf(buf, "%s%s%s%s", cursor_left ? " (cub1)" : "",
|
||||
cursor_down ? " (cud1)" : "", cursor_right ? " (cuf1)" : "",
|
||||
cursor_up ? " (cuu1)" : "");
|
||||
if (buf[0] == '\0') {
|
||||
ptext(" (cub1) (cud1) (cuf1) (cuu1) not defined.");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
sprintf(buf, "%s%s%s%s", parm_left_cursor ? " (cub)" : "",
|
||||
parm_down_cursor ? " (cud)" : "",
|
||||
parm_right_cursor ? " (cuf)" : "",
|
||||
parm_up_cursor ? " (cuu)" : "");
|
||||
if (buf[0] == '\0') {
|
||||
ptext(" (cub) (cud) (cuf) (cuu) not defined.");
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
sprintf(buf, "%s%s", row_address ? " (vpa)" : "",
|
||||
column_address ? " (hpa)" : "");
|
||||
if (buf[0] == '\0') {
|
||||
ptext(" (vpa) (hpa) not defined.");
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (!cursor_address) {
|
||||
ptext(" (cup) not defined. ");
|
||||
generic_done_message(t, state, ch);
|
||||
return;
|
||||
}
|
||||
strcpy(buf, " (cup)");
|
||||
break;
|
||||
}
|
||||
if (buf[0] == '\0') {
|
||||
put_str(" Done. ");
|
||||
} else {
|
||||
can_test(buf, FLAG_TESTED);
|
||||
strcpy(crum_text[n], &buf[2]);
|
||||
crum_text[n][strlen(buf) - 3] = '\0';
|
||||
|
||||
display_it(1 << n, buf);
|
||||
}
|
||||
*ch = wait_here();
|
||||
if (*ch != 'r') {
|
||||
put_clear();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** crum_os(test_list, status, ch)
|
||||
**
|
||||
** (cup) test Cursor position on overstrike terminals
|
||||
*/
|
||||
static void
|
||||
crum_os(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cursor_address && over_strike) {
|
||||
put_clear();
|
||||
for (i = 0; i < columns - 2; i++) {
|
||||
tc_putch('|');
|
||||
}
|
||||
for (i = 1; i < lines - 2; i++) {
|
||||
put_crlf();
|
||||
tc_putch('_');
|
||||
}
|
||||
for (i = 0; i < columns - 2; i++) {
|
||||
tputs(TPARM_2(cursor_address, 0, i), lines, tc_putch);
|
||||
tc_putch('+');
|
||||
}
|
||||
for (i = 0; i < lines - 2; i++) {
|
||||
tputs(TPARM_2(cursor_address, i, 0), lines, tc_putch);
|
||||
tc_putch(']');
|
||||
tc_putch('_');
|
||||
}
|
||||
go_home();
|
||||
put_newlines(3);
|
||||
ptext(" All the characters should look the same. ");
|
||||
generic_done_message(t, state, ch);
|
||||
put_clear();
|
||||
}
|
||||
}
|
@ -1,992 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <tack.h>
|
||||
#include <time.h>
|
||||
#include <tic.h>
|
||||
|
||||
MODULE_ID("$Id: edit.c,v 1.11 2006/06/24 21:22:42 tom Exp $")
|
||||
|
||||
/*
|
||||
* Terminfo edit features
|
||||
*/
|
||||
static void show_info(struct test_list *, int *, int *);
|
||||
static void show_value(struct test_list *, int *, int *);
|
||||
static void show_untested(struct test_list *, int *, int *);
|
||||
static void show_changed(struct test_list *, int *, int *);
|
||||
|
||||
#define SHOW_VALUE 1
|
||||
#define SHOW_EDIT 2
|
||||
#define SHOW_DELETE 3
|
||||
|
||||
struct test_list edit_test_list[] = {
|
||||
{MENU_CLEAR, 0, 0, 0, "i) display current terminfo", show_info, 0},
|
||||
{0, 0, 0, 0, "w) write the current terminfo to a file", save_info, 0},
|
||||
{SHOW_VALUE, 3, 0, 0, "v) show value of a selected cap", show_value, 0},
|
||||
{SHOW_EDIT, 4, 0, 0, "e) edit value of a selected cap", show_value, 0},
|
||||
{SHOW_DELETE, 3, 0, 0, "d) delete string", show_value, 0},
|
||||
{0, 3, 0, 0, "m) show caps that have been modified", show_changed, 0},
|
||||
{MENU_CLEAR + FLAG_CAN_TEST, 0, 0, 0, "c) show caps that can be tested", show_report, 0},
|
||||
{MENU_CLEAR + FLAG_TESTED, 0, 0, 0, "t) show caps that have been tested", show_report, 0},
|
||||
{MENU_CLEAR + FLAG_FUNCTION_KEY, 0, 0, 0, "f) show a list of function keys", show_report, 0},
|
||||
{MENU_CLEAR, 0, 0, 0, "u) show caps defined that can not be tested", show_untested, 0},
|
||||
{MENU_LAST, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static char change_pad_text[MAX_CHANGES][80];
|
||||
static struct test_list change_pad_list[MAX_CHANGES] = {
|
||||
{MENU_LAST, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static void build_change_menu(struct test_menu *);
|
||||
static void change_one_entry(struct test_list *, int *, int *);
|
||||
|
||||
struct test_menu change_pad_menu = {
|
||||
0, 'q', 0,
|
||||
"Select cap name", "change", 0,
|
||||
build_change_menu, change_pad_list, 0, 0, 0
|
||||
};
|
||||
|
||||
static TERMTYPE original_term; /* terminal type description */
|
||||
|
||||
static char flag_boolean[BOOLCOUNT]; /* flags for booleans */
|
||||
static char flag_numerics[NUMCOUNT]; /* flags for numerics */
|
||||
static char *flag_strings; /* flags for strings */
|
||||
static int *label_strings;
|
||||
static int xon_index; /* Subscript for (xon) */
|
||||
static int xon_shadow;
|
||||
|
||||
static int start_display; /* the display has just started */
|
||||
static int display_lines; /* number of lines displayed */
|
||||
|
||||
static void
|
||||
alloc_arrays(void)
|
||||
{
|
||||
if (flag_strings == 0) {
|
||||
label_strings = (int *)calloc(MAX_STRINGS, sizeof(int));
|
||||
flag_strings = (char *)calloc(MAX_STRINGS, sizeof(char));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** send_info_string(str)
|
||||
**
|
||||
** Return the terminfo string prefixed by the correct separator
|
||||
*/
|
||||
static void
|
||||
send_info_string(
|
||||
const char *str,
|
||||
int *ch)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (display_lines == -1) {
|
||||
return;
|
||||
}
|
||||
len = strlen(str);
|
||||
if (len + char_count + 3 >= columns) {
|
||||
if (start_display == 0) {
|
||||
put_str(",");
|
||||
}
|
||||
put_crlf();
|
||||
if (++display_lines > lines) {
|
||||
ptext("-- more -- ");
|
||||
*ch = wait_here();
|
||||
if (*ch == 'q') {
|
||||
display_lines = -1;
|
||||
return;
|
||||
}
|
||||
display_lines = 0;
|
||||
}
|
||||
if (len >= columns) {
|
||||
/* if the terminal does not (am) then this loses */
|
||||
if (columns) {
|
||||
display_lines += ((strlen(str) + 3) / columns) + 1;
|
||||
}
|
||||
put_str(" ");
|
||||
put_str(str);
|
||||
start_display = 0;
|
||||
return;
|
||||
}
|
||||
ptext(" ");
|
||||
} else
|
||||
if (start_display == 0) {
|
||||
ptext(", ");
|
||||
} else {
|
||||
ptext(" ");
|
||||
}
|
||||
ptext(str);
|
||||
start_display = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** show_info(test_list, status, ch)
|
||||
**
|
||||
** Display the current terminfo
|
||||
*/
|
||||
static void
|
||||
show_info(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
int i;
|
||||
char buf[1024];
|
||||
|
||||
display_lines = 1;
|
||||
start_display = 1;
|
||||
for (i = 0; i < BOOLCOUNT; i++) {
|
||||
if ((i == xon_index) ? xon_shadow : CUR Booleans[i]) {
|
||||
send_info_string(boolnames[i], ch);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NUMCOUNT; i++) {
|
||||
if (CUR Numbers[i] >= 0) {
|
||||
sprintf(buf, "%s#%d", numnames[i], CUR Numbers[i]);
|
||||
send_info_string(buf, ch);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_STRINGS; i++) {
|
||||
if (CUR Strings[i]) {
|
||||
sprintf(buf, "%s=%s", STR_NAME(i),
|
||||
print_expand(CUR Strings[i]));
|
||||
send_info_string(buf, ch);
|
||||
}
|
||||
}
|
||||
put_newlines(2);
|
||||
*ch = REQUEST_PROMPT;
|
||||
}
|
||||
|
||||
/*
|
||||
** save_info_string(str, fp)
|
||||
**
|
||||
** Write the terminfo string prefixed by the correct separator
|
||||
*/
|
||||
static void
|
||||
save_info_string(
|
||||
const char *str,
|
||||
FILE *fp)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = strlen(str);
|
||||
if (len + display_lines >= 77) {
|
||||
if (display_lines > 0) {
|
||||
(void) fprintf(fp, "\n\t");
|
||||
}
|
||||
display_lines = 8;
|
||||
} else
|
||||
if (display_lines > 0) {
|
||||
(void) fprintf(fp, " ");
|
||||
display_lines++;
|
||||
} else {
|
||||
(void) fprintf(fp, "\t");
|
||||
display_lines = 8;
|
||||
}
|
||||
(void) fprintf(fp, "%s,", str);
|
||||
display_lines += len + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** save_info(test_list, status, ch)
|
||||
**
|
||||
** Write the current terminfo to a file
|
||||
*/
|
||||
void
|
||||
save_info(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i;
|
||||
FILE *fp;
|
||||
time_t now;
|
||||
char buf[1024];
|
||||
|
||||
if ((fp = fopen(tty_basename, "w")) == (FILE *) NULL) {
|
||||
(void) sprintf(temp, "can't open: %s", tty_basename);
|
||||
ptextln(temp);
|
||||
generic_done_message(t, state, ch);
|
||||
return;
|
||||
}
|
||||
time(&now);
|
||||
/* Note: ctime() returns a newline at the end of the string */
|
||||
(void) fprintf(fp, "# Terminfo created by TACK for TERM=%s on %s",
|
||||
tty_basename, ctime(&now));
|
||||
(void) fprintf(fp, "%s|%s,\n", tty_basename, longname());
|
||||
|
||||
display_lines = 0;
|
||||
for (i = 0; i < BOOLCOUNT; i++) {
|
||||
if (i == xon_index ? xon_shadow : CUR Booleans[i]) {
|
||||
save_info_string(boolnames[i], fp);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NUMCOUNT; i++) {
|
||||
if (CUR Numbers[i] >= 0) {
|
||||
sprintf(buf, "%s#%d", numnames[i], CUR Numbers[i]);
|
||||
save_info_string(buf, fp);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_STRINGS; i++) {
|
||||
if (CUR Strings[i]) {
|
||||
sprintf(buf, "%s=%s", STR_NAME(i),
|
||||
_nc_tic_expand(CUR Strings[i], TRUE, TRUE));
|
||||
save_info_string(buf, fp);
|
||||
}
|
||||
}
|
||||
(void) fprintf(fp, "\n");
|
||||
(void) fclose(fp);
|
||||
sprintf(temp, "Terminfo saved as file: %s", tty_basename);
|
||||
ptextln(temp);
|
||||
}
|
||||
|
||||
/*
|
||||
** show_value(test_list, status, ch)
|
||||
**
|
||||
** Display the value of a selected cap
|
||||
*/
|
||||
static void
|
||||
show_value(
|
||||
struct test_list *t,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
struct name_table_entry const *nt;
|
||||
char *s;
|
||||
int n, op, b;
|
||||
char buf[1024];
|
||||
char tmp[1024];
|
||||
|
||||
ptext("enter name: ");
|
||||
read_string(buf, 80);
|
||||
if (buf[0] == '\0' || buf[1] == '\0') {
|
||||
*ch = buf[0];
|
||||
return;
|
||||
}
|
||||
if (line_count + 2 >= lines) {
|
||||
put_clear();
|
||||
}
|
||||
op = t->flags & 255;
|
||||
if ((nt = _nc_find_entry(buf, _nc_info_hash_table))) {
|
||||
switch (nt->nte_type) {
|
||||
case BOOLEAN:
|
||||
if (op == SHOW_DELETE) {
|
||||
if (nt->nte_index == xon_index) {
|
||||
xon_shadow = 0;
|
||||
} else {
|
||||
CUR Booleans[nt->nte_index] = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
b = nt->nte_index == xon_index ? xon_shadow :
|
||||
CUR Booleans[nt->nte_index];
|
||||
sprintf(temp, "boolean %s %s", buf,
|
||||
b ? "True" : "False");
|
||||
break;
|
||||
case STRING:
|
||||
if (op == SHOW_DELETE) {
|
||||
CUR Strings[nt->nte_index] = (char *) 0;
|
||||
return;
|
||||
}
|
||||
if (CUR Strings[nt->nte_index]) {
|
||||
sprintf(temp, "string %s %s", buf,
|
||||
expand(CUR Strings[nt->nte_index]));
|
||||
} else {
|
||||
sprintf(temp, "undefined string %s", buf);
|
||||
}
|
||||
break;
|
||||
case NUMBER:
|
||||
if (op == SHOW_DELETE) {
|
||||
CUR Numbers[nt->nte_index] = -1;
|
||||
return;
|
||||
}
|
||||
sprintf(temp, "numeric %s %d", buf,
|
||||
CUR Numbers[nt->nte_index]);
|
||||
break;
|
||||
default:
|
||||
sprintf(temp, "unknown");
|
||||
break;
|
||||
}
|
||||
ptextln(temp);
|
||||
} else {
|
||||
sprintf(temp, "Cap not found: %s", buf);
|
||||
ptextln(temp);
|
||||
return;
|
||||
}
|
||||
if (op != SHOW_EDIT) {
|
||||
return;
|
||||
}
|
||||
if (nt->nte_type == BOOLEAN) {
|
||||
ptextln("Value flipped");
|
||||
if (nt->nte_index == xon_index) {
|
||||
xon_shadow = !xon_shadow;
|
||||
} else {
|
||||
CUR Booleans[nt->nte_index] = !CUR Booleans[nt->nte_index];
|
||||
}
|
||||
return;
|
||||
}
|
||||
ptextln("Enter new value");
|
||||
read_string(buf, sizeof(buf));
|
||||
|
||||
switch (nt->nte_type) {
|
||||
case STRING:
|
||||
_nc_reset_input((FILE *) 0, buf);
|
||||
_nc_trans_string(tmp, tmp + sizeof(tmp));
|
||||
s = (char *)malloc(strlen(tmp) + 1);
|
||||
strcpy(s, tmp);
|
||||
CUR Strings[nt->nte_index] = s;
|
||||
sprintf(temp, "new string value %s", nt->nte_name);
|
||||
ptextln(temp);
|
||||
ptextln(expand(CUR Strings[nt->nte_index]));
|
||||
break;
|
||||
case NUMBER:
|
||||
if (sscanf(buf, "%d", &n) == 1) {
|
||||
CUR Numbers[nt->nte_index] = n;
|
||||
sprintf(temp, "new numeric value %s %d",
|
||||
nt->nte_name, n);
|
||||
ptextln(temp);
|
||||
} else {
|
||||
sprintf(temp, "Illegal number: %s", buf);
|
||||
ptextln(temp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** get_string_cap_byname(name, long_name)
|
||||
**
|
||||
** Given a cap name, find the value
|
||||
** Errors are quietly ignored.
|
||||
*/
|
||||
char *
|
||||
get_string_cap_byname(
|
||||
const char *name,
|
||||
const char **long_name)
|
||||
{
|
||||
struct name_table_entry const *nt;
|
||||
|
||||
if ((nt = _nc_find_entry(name, _nc_info_hash_table))) {
|
||||
if (nt->nte_type == STRING) {
|
||||
*long_name = strfnames[nt->nte_index];
|
||||
return (CUR Strings[nt->nte_index]);
|
||||
}
|
||||
}
|
||||
*long_name = "??";
|
||||
return (char *) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** get_string_cap_byvalue(value)
|
||||
**
|
||||
** Given a capability string, find its position in the data base.
|
||||
** Return the index or -1 if not found.
|
||||
*/
|
||||
int
|
||||
get_string_cap_byvalue(
|
||||
const char *value)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (value) {
|
||||
for (i = 0; i < MAX_STRINGS; i++) {
|
||||
if (CUR Strings[i] == value) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
/* search for translated strings */
|
||||
for (i = 0; i < TM_last; i++) {
|
||||
if (TM_string[i].value == value) {
|
||||
return TM_string[i].index;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
** show_changed(test_list, status, ch)
|
||||
**
|
||||
** Display a list of caps that have been changed.
|
||||
*/
|
||||
static void
|
||||
show_changed(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
int i, header = 1, v;
|
||||
const char *a;
|
||||
const char *b;
|
||||
static char title[] = " old value cap new value";
|
||||
char abuf[1024];
|
||||
|
||||
for (i = 0; i < BOOLCOUNT; i++) {
|
||||
v = (i == xon_index) ? xon_shadow : CUR Booleans[i];
|
||||
if (original_term.Booleans[i] != v) {
|
||||
if (header) {
|
||||
ptextln(title);
|
||||
header = 0;
|
||||
}
|
||||
sprintf(temp, "%30d %6s %d",
|
||||
original_term.Booleans[i], boolnames[i], v);
|
||||
ptextln(temp);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NUMCOUNT; i++) {
|
||||
if (original_term.Numbers[i] != CUR Numbers[i]) {
|
||||
if (header) {
|
||||
ptextln(title);
|
||||
header = 0;
|
||||
}
|
||||
sprintf(temp, "%30d %6s %d",
|
||||
original_term.Numbers[i], numnames[i],
|
||||
CUR Numbers[i]);
|
||||
ptextln(temp);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_STRINGS; i++) {
|
||||
a = original_term.Strings[i] ? original_term.Strings[i] : "";
|
||||
b = CUR Strings[i] ? CUR Strings[i] : "";
|
||||
if (strcmp(a, b)) {
|
||||
if (header) {
|
||||
ptextln(title);
|
||||
header = 0;
|
||||
}
|
||||
strcpy(abuf, _nc_tic_expand(a, TRUE, TRUE));
|
||||
sprintf(temp, "%30s %6s %s", abuf, STR_NAME(i),
|
||||
_nc_tic_expand(b, TRUE, TRUE));
|
||||
putln(temp);
|
||||
}
|
||||
}
|
||||
if (header) {
|
||||
ptextln("No changes");
|
||||
}
|
||||
put_crlf();
|
||||
*ch = REQUEST_PROMPT;
|
||||
}
|
||||
|
||||
/*
|
||||
** user_modified()
|
||||
**
|
||||
** Return TRUE if the user has modified the terminfo
|
||||
*/
|
||||
int
|
||||
user_modified(void)
|
||||
{
|
||||
const char *a, *b;
|
||||
int i, v;
|
||||
|
||||
for (i = 0; i < BOOLCOUNT; i++) {
|
||||
v = (i == xon_index) ? xon_shadow : CUR Booleans[i];
|
||||
if (original_term.Booleans[i] != v) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NUMCOUNT; i++) {
|
||||
if (original_term.Numbers[i] != CUR Numbers[i]) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_STRINGS; i++) {
|
||||
a = original_term.Strings[i] ? original_term.Strings[i] : "";
|
||||
b = CUR Strings[i] ? CUR Strings[i] : "";
|
||||
if (strcmp(a, b)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Maintain the list of capabilities that can be tested
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
** mark_cap(name, flag)
|
||||
**
|
||||
** Mark the cap data base with the flag provided.
|
||||
*/
|
||||
static void
|
||||
mark_cap(
|
||||
char *name,
|
||||
int flag)
|
||||
{
|
||||
struct name_table_entry const *nt;
|
||||
|
||||
alloc_arrays();
|
||||
if ((nt = _nc_find_entry(name, _nc_info_hash_table))) {
|
||||
switch (nt->nte_type) {
|
||||
case BOOLEAN:
|
||||
flag_boolean[nt->nte_index] |= flag;
|
||||
break;
|
||||
case STRING:
|
||||
flag_strings[nt->nte_index] |= flag;
|
||||
break;
|
||||
case NUMBER:
|
||||
flag_numerics[nt->nte_index] |= flag;
|
||||
break;
|
||||
default:
|
||||
sprintf(temp, "unknown cap type (%s)", name);
|
||||
ptextln(temp);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
sprintf(temp, "Cap not found: %s", name);
|
||||
ptextln(temp);
|
||||
(void) wait_here();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** can_test(name-list, flags)
|
||||
**
|
||||
** Scan the name list and get the names.
|
||||
** Enter each name into the can-test data base.
|
||||
** <space> ( and ) may be used as separators.
|
||||
*/
|
||||
void
|
||||
can_test(
|
||||
const char *s,
|
||||
int flags)
|
||||
{
|
||||
int ch, j;
|
||||
char name[32];
|
||||
|
||||
if (s) {
|
||||
for (j = 0; (name[j] = ch = *s); s++) {
|
||||
if (ch == ' ' || ch == ')' || ch == '(') {
|
||||
if (j) {
|
||||
name[j] = '\0';
|
||||
mark_cap(name, flags);
|
||||
}
|
||||
j = 0;
|
||||
} else {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if (j) {
|
||||
mark_cap(name, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** cap_index(name-list, index-list)
|
||||
**
|
||||
** Scan the name list and return a list of indexes.
|
||||
** <space> ( and ) may be used as separators.
|
||||
** This list is terminated with -1.
|
||||
*/
|
||||
void
|
||||
cap_index(
|
||||
const char *s,
|
||||
int *inx)
|
||||
{
|
||||
struct name_table_entry const *nt;
|
||||
int ch, j;
|
||||
char name[32];
|
||||
|
||||
if (s) {
|
||||
for (j = 0; ; s++) {
|
||||
name[j] = ch = *s;
|
||||
if (ch == ' ' || ch == ')' || ch == '(' || ch == 0) {
|
||||
if (j) {
|
||||
name[j] = '\0';
|
||||
if ((nt = _nc_find_entry(name,
|
||||
_nc_info_hash_table)) &&
|
||||
(nt->nte_type == STRING)) {
|
||||
*inx++ = nt->nte_index;
|
||||
}
|
||||
}
|
||||
if (ch == 0) {
|
||||
break;
|
||||
}
|
||||
j = 0;
|
||||
} else {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
*inx = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
** cap_match(name-list, cap)
|
||||
**
|
||||
** Scan the name list and see if the cap is in the list.
|
||||
** Return TRUE if we find an exact match.
|
||||
** <space> ( and ) may be used as separators.
|
||||
*/
|
||||
int
|
||||
cap_match(
|
||||
const char *names,
|
||||
const char *cap)
|
||||
{
|
||||
char *s;
|
||||
int c, l, t;
|
||||
|
||||
if (names) {
|
||||
l = strlen(cap);
|
||||
while ((s = strstr(names, cap))) {
|
||||
c = (names == s) ? 0 : *(s - 1);
|
||||
t = s[l];
|
||||
if ((c == 0 || c == ' ' || c == '(') &&
|
||||
(t == 0 || t == ' ' || t == ')')) {
|
||||
return TRUE;
|
||||
}
|
||||
if (t == 0) {
|
||||
break;
|
||||
}
|
||||
names = s + l;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
** show_report(test_list, status, ch)
|
||||
**
|
||||
** Display a list of caps that can be tested
|
||||
*/
|
||||
void
|
||||
show_report(
|
||||
struct test_list *t,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
int i, j, nc, flag;
|
||||
const char *s;
|
||||
const char **nx = malloc(BOOLCOUNT + NUMCOUNT + MAX_STRINGS);
|
||||
|
||||
alloc_arrays();
|
||||
flag = t->flags & 255;
|
||||
nc = 0;
|
||||
for (i = 0; i < BOOLCOUNT; i++) {
|
||||
if (flag_boolean[i] & flag) {
|
||||
nx[nc++] = boolnames[i];
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NUMCOUNT; i++) {
|
||||
if (flag_numerics[i] & flag) {
|
||||
nx[nc++] = numnames[i];
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_STRINGS; i++) {
|
||||
if (flag_strings[i] & flag) {
|
||||
nx[nc++] = STR_NAME(i);
|
||||
}
|
||||
}
|
||||
/* sort */
|
||||
for (i = 0; i < nc - 1; i++) {
|
||||
for (j = i + 1; j < nc; j++) {
|
||||
if (strcmp(nx[i], nx[j]) > 0) {
|
||||
s = nx[i];
|
||||
nx[i] = nx[j];
|
||||
nx[j] = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flag & FLAG_FUNCTION_KEY) {
|
||||
ptextln("The following function keys can be tested:");
|
||||
} else
|
||||
if (flag & FLAG_CAN_TEST) {
|
||||
ptextln("The following capabilities can be tested:");
|
||||
} else
|
||||
if (flag & FLAG_TESTED) {
|
||||
ptextln("The following capabilities have been tested:");
|
||||
}
|
||||
put_crlf();
|
||||
for (i = 0; i < nc; i++) {
|
||||
sprintf(temp, "%s ", nx[i]);
|
||||
ptext(temp);
|
||||
}
|
||||
put_newlines(1);
|
||||
*ch = REQUEST_PROMPT;
|
||||
free (nx);
|
||||
}
|
||||
|
||||
/*
|
||||
** show_untested(test_list, status, ch)
|
||||
**
|
||||
** Display a list of caps that are defined but cannot be tested.
|
||||
** Don't bother to sort this list.
|
||||
*/
|
||||
static void
|
||||
show_untested(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
int i;
|
||||
|
||||
alloc_arrays();
|
||||
ptextln("Caps that are defined but cannot be tested:");
|
||||
for (i = 0; i < BOOLCOUNT; i++) {
|
||||
if (flag_boolean[i] == 0 && CUR Booleans[i]) {
|
||||
sprintf(temp, "%s ", boolnames[i]);
|
||||
ptext(temp);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NUMCOUNT; i++) {
|
||||
if (flag_numerics[i] == 0 && CUR Numbers[i] >= 0) {
|
||||
sprintf(temp, "%s ", numnames[i]);
|
||||
ptext(temp);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_STRINGS; i++) {
|
||||
if (flag_strings[i] == 0 && CUR Strings[i]) {
|
||||
sprintf(temp, "%s ", STR_NAME(i));
|
||||
ptext(temp);
|
||||
}
|
||||
}
|
||||
put_newlines(1);
|
||||
*ch = REQUEST_PROMPT;
|
||||
}
|
||||
|
||||
/*
|
||||
** edit_init()
|
||||
**
|
||||
** Initialize the function key data base
|
||||
*/
|
||||
void
|
||||
edit_init(void)
|
||||
{
|
||||
int i, j, lc;
|
||||
char *lab;
|
||||
struct name_table_entry const *nt;
|
||||
|
||||
alloc_arrays();
|
||||
|
||||
_nc_copy_termtype(&original_term, &cur_term->type);
|
||||
for (i = 0; i < BOOLCOUNT; i++) {
|
||||
original_term.Booleans[i] = CUR Booleans[i];
|
||||
}
|
||||
for (i = 0; i < NUMCOUNT; i++) {
|
||||
original_term.Numbers[i] = CUR Numbers[i];
|
||||
}
|
||||
/* scan for labels */
|
||||
for (i = lc = 0; i < MAX_STRINGS; i++) {
|
||||
original_term.Strings[i] = CUR Strings[i];
|
||||
if (strncmp(STR_NAME(i), "lf", 2) == 0) {
|
||||
flag_strings[i] |= FLAG_LABEL;
|
||||
if (CUR Strings[i]) {
|
||||
label_strings[lc++] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* scan for function keys */
|
||||
for (i = 0; i < MAX_STRINGS; i++) {
|
||||
const char *this_name = STR_NAME(i);
|
||||
if ((this_name[0] == 'k') && strcmp(this_name, "kmous")) {
|
||||
flag_strings[i] |= FLAG_FUNCTION_KEY;
|
||||
lab = (char *) 0;
|
||||
for (j = 0; j < lc; j++) {
|
||||
if (!strcmp(this_name,
|
||||
STR_NAME(label_strings[j]))) {
|
||||
lab = CUR Strings[label_strings[j]];
|
||||
break;
|
||||
}
|
||||
}
|
||||
enter_key(this_name, CUR Strings[i], lab);
|
||||
}
|
||||
}
|
||||
/* Lookup the translated strings */
|
||||
for (i = 0; i < TM_last; i++) {
|
||||
if ((nt = _nc_find_entry(TM_string[i].name,
|
||||
_nc_info_hash_table)) && (nt->nte_type == STRING)) {
|
||||
TM_string[i].index = nt->nte_index;
|
||||
} else {
|
||||
sprintf(temp, "TM_string lookup failed for: %s",
|
||||
TM_string[i].name);
|
||||
ptextln(temp);
|
||||
}
|
||||
}
|
||||
if ((nt = _nc_find_entry("xon", _nc_info_hash_table)) != 0) {
|
||||
xon_index = nt->nte_index;
|
||||
}
|
||||
xon_shadow = xon_xoff;
|
||||
free(label_strings);
|
||||
}
|
||||
|
||||
/*
|
||||
** change_one_entry(test_list, status, ch)
|
||||
**
|
||||
** Change the padding on the selected cap
|
||||
*/
|
||||
static void
|
||||
change_one_entry(
|
||||
struct test_list *test,
|
||||
int *state,
|
||||
int *chp)
|
||||
{
|
||||
struct name_table_entry const *nt;
|
||||
int i, j, x, star, slash, v, dot, ch;
|
||||
const char *s;
|
||||
char *t, *p;
|
||||
const char *current_string;
|
||||
char buf[1024];
|
||||
char pad[1024];
|
||||
|
||||
i = test->flags & 255;
|
||||
if (i == 255) {
|
||||
/* read the cap name from the user */
|
||||
ptext("enter name: ");
|
||||
read_string(pad, 32);
|
||||
if (pad[0] == '\0' || pad[1] == '\0') {
|
||||
*chp = pad[0];
|
||||
return;
|
||||
}
|
||||
if ((nt = _nc_find_entry(pad, _nc_info_hash_table)) &&
|
||||
(nt->nte_type == STRING)) {
|
||||
x = nt->nte_index;
|
||||
current_string = CUR Strings[x];
|
||||
} else {
|
||||
sprintf(temp, "%s is not a string capability", pad);
|
||||
ptext(temp);
|
||||
generic_done_message(test, state, chp);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
x = tx_index[i];
|
||||
current_string = tx_cap[i];
|
||||
strcpy(pad, STR_NAME(x));
|
||||
}
|
||||
if (!current_string) {
|
||||
ptextln("That string is not currently defined. Please enter a new value, including the padding delay:");
|
||||
read_string(buf, sizeof(buf));
|
||||
_nc_reset_input((FILE *) 0, buf);
|
||||
_nc_trans_string(pad, pad + sizeof(pad));
|
||||
t = (char *)malloc(strlen(pad) + 1);
|
||||
strcpy(t, pad);
|
||||
CUR Strings[x] = t;
|
||||
sprintf(temp, "new string value %s", STR_NAME(x));
|
||||
ptextln(temp);
|
||||
ptextln(expand(t));
|
||||
return;
|
||||
}
|
||||
sprintf(buf, "Current value: (%s) %s", pad, _nc_tic_expand(current_string, TRUE, TRUE));
|
||||
putln(buf);
|
||||
ptextln("Enter new pad. 0 for no pad. CR for no change.");
|
||||
read_string(buf, 32);
|
||||
if (buf[0] == '\0' || (buf[1] == '\0' && isalpha(UChar(buf[0])))) {
|
||||
*chp = buf[0];
|
||||
return;
|
||||
}
|
||||
star = slash = FALSE;
|
||||
for (j = v = dot = 0; (ch = buf[j]); j++) {
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
v = ch - '0' + v * 10;
|
||||
if (dot) {
|
||||
dot++;
|
||||
}
|
||||
} else if (ch == '*') {
|
||||
star = TRUE;
|
||||
} else if (ch == '/') {
|
||||
slash = TRUE;
|
||||
} else if (ch == '.') {
|
||||
dot = 1;
|
||||
} else {
|
||||
sprintf(temp, "Illegal character: %c", ch);
|
||||
ptextln(temp);
|
||||
ptext("General format: 99.9*/ ");
|
||||
generic_done_message(test, state, chp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (dot > 2) {
|
||||
v /= 10;
|
||||
dot--;
|
||||
}
|
||||
if (dot == 2) {
|
||||
sprintf(pad, "%d.%d%s%s", v / 10, v % 10,
|
||||
star ? "*" : "", slash ? "/" : "");
|
||||
} else {
|
||||
sprintf(pad, "%d%s%s",
|
||||
v, star ? "*" : "", slash ? "/" : "");
|
||||
}
|
||||
s = current_string;
|
||||
t = buf;
|
||||
for (v = 0; (ch = *t = *s++); t++) {
|
||||
if (v == '$' && ch == '<') {
|
||||
while ((ch = *s++) && (ch != '>'));
|
||||
for (p = pad; (*++t = *p++); );
|
||||
*t++ = '>';
|
||||
while ((*t++ = *s++));
|
||||
pad[0] = '\0';
|
||||
break;
|
||||
}
|
||||
v = ch;
|
||||
}
|
||||
if (pad[0]) {
|
||||
sprintf(t, "$<%s>", pad);
|
||||
}
|
||||
if ((t = (char *)malloc(strlen(buf) + 1))) {
|
||||
strcpy(t, buf);
|
||||
CUR Strings[x] = t;
|
||||
if (i != 255) {
|
||||
tx_cap[i] = t;
|
||||
}
|
||||
}
|
||||
generic_done_message(test, state, chp);
|
||||
}
|
||||
|
||||
/*
|
||||
** build_change_menu(menu_list)
|
||||
**
|
||||
** Build the change pad menu list
|
||||
*/
|
||||
static void
|
||||
build_change_menu(
|
||||
struct test_menu *m)
|
||||
{
|
||||
int i, j, k;
|
||||
char *s;
|
||||
|
||||
for (i = j = 0; i < txp; i++) {
|
||||
if ((k = tx_index[i]) >= 0) {
|
||||
s = _nc_tic_expand(tx_cap[i], TRUE, TRUE);
|
||||
s[40] = '\0';
|
||||
sprintf(change_pad_text[j], "%c) (%s) %s",
|
||||
'a' + j, STR_NAME(k), s);
|
||||
change_pad_list[j].flags = i;
|
||||
change_pad_list[j].lines_needed = 4;
|
||||
change_pad_list[j].menu_entry = change_pad_text[j];
|
||||
change_pad_list[j].test_procedure = change_one_entry;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
strcpy(change_pad_text[j], "z) enter name");
|
||||
change_pad_list[j].flags = 255;
|
||||
change_pad_list[j].lines_needed = 4;
|
||||
change_pad_list[j].menu_entry = change_pad_text[j];
|
||||
change_pad_list[j].test_procedure = change_one_entry;
|
||||
j++;
|
||||
change_pad_list[j].flags = MENU_LAST;
|
||||
if (m->menu_title) {
|
||||
put_crlf();
|
||||
ptextln(m->menu_title);
|
||||
}
|
||||
}
|
@ -1,925 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <tack.h>
|
||||
|
||||
MODULE_ID("$Id: fun.c,v 1.9 2006/11/26 00:15:53 tom Exp $")
|
||||
|
||||
/*
|
||||
* Test the function keys on the terminal. The code for echo tests
|
||||
* lives here too.
|
||||
*/
|
||||
|
||||
static void funkey_keys(struct test_list *, int *, int *);
|
||||
static void funkey_meta(struct test_list *, int *, int *);
|
||||
static void funkey_label(struct test_list *, int *, int *);
|
||||
static void funkey_prog(struct test_list *, int *, int *);
|
||||
static void funkey_local(struct test_list *, int *, int *);
|
||||
|
||||
struct test_list funkey_test_list[] = {
|
||||
{0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu},
|
||||
{MENU_CLEAR + FLAG_FUNCTION_KEY, 0, 0, 0, "f) show a list of function keys", show_report, 0},
|
||||
{MENU_NEXT | MENU_CLEAR, 0, "smkx) (rmkx", 0,
|
||||
"k) test function keys", funkey_keys, 0},
|
||||
{MENU_NEXT, 10, "km", "smm rmm", 0, funkey_meta, 0},
|
||||
{MENU_NEXT, 8, "nlab) (smln) (pln) (rmln", "lw lh", 0, funkey_label, 0},
|
||||
{MENU_NEXT, 2, "pfx", 0, 0, funkey_prog, 0},
|
||||
{MENU_NEXT, 2, "pfloc", 0, 0, funkey_local, 0},
|
||||
{MENU_LAST, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static void printer_on(struct test_list *, int *, int *);
|
||||
static void printer_mc0(struct test_list *, int *, int *);
|
||||
|
||||
struct test_list printer_test_list[] = {
|
||||
{0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu},
|
||||
{MENU_NEXT | MENU_CLEAR, 0, "mc4) (mc5) (mc5i", 0, 0, printer_on, 0},
|
||||
{MENU_NEXT | MENU_CLEAR, 0, "mc0", 0, 0, printer_mc0, 0},
|
||||
{MENU_LAST, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* local definitions */
|
||||
static const char **fk_name;
|
||||
static char **fkval;
|
||||
static char **fk_label; /* function key labels (if any) */
|
||||
static int *fk_tested;
|
||||
static int num_strings = 0;
|
||||
|
||||
static int fkmax = 1; /* length of longest key */
|
||||
static int got_labels = 0; /* true if we have some labels */
|
||||
static int key_count = 0;
|
||||
static int end_state;
|
||||
|
||||
/* unknown function keys */
|
||||
#define MAX_FK_UNK 50
|
||||
static char *fk_unknown[MAX_FK_UNK];
|
||||
static int fk_length[MAX_FK_UNK];
|
||||
static int funk;
|
||||
|
||||
/*
|
||||
* Initialize arrays that depend on the actual number of strings.
|
||||
*/
|
||||
static void
|
||||
alloc_strings(void)
|
||||
{
|
||||
if (num_strings != MAX_STRINGS) {
|
||||
num_strings = MAX_STRINGS;
|
||||
fk_name = (const char **)calloc(num_strings, sizeof(const char *));
|
||||
fkval = (char **)calloc(num_strings, sizeof(char *));
|
||||
fk_label = (char **)calloc(num_strings, sizeof(char *));
|
||||
fk_tested = (int *)calloc(num_strings, sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** keys_tested(first-time, show-help, hex-output)
|
||||
**
|
||||
** Display a list of the keys not tested.
|
||||
*/
|
||||
static void
|
||||
keys_tested(
|
||||
int first_time,
|
||||
int show_help,
|
||||
int hex_output)
|
||||
{
|
||||
int i, l;
|
||||
char outbuf[256];
|
||||
|
||||
alloc_strings();
|
||||
put_clear();
|
||||
tty_set();
|
||||
flush_input();
|
||||
if (got_labels) {
|
||||
putln("Function key labels:");
|
||||
for (i = 0; i < key_count; ++i) {
|
||||
if (fk_label[i]) {
|
||||
sprintf(outbuf, "%s %s",
|
||||
fk_name[i] ? fk_name[i] : "??", fk_label[i]);
|
||||
put_columns(outbuf, (int) strlen(outbuf), 16);
|
||||
}
|
||||
}
|
||||
put_newlines(2);
|
||||
}
|
||||
if (funk) {
|
||||
putln("The following keys are not defined:");
|
||||
for (i = 0; i < funk; ++i) {
|
||||
put_columns(fk_unknown[i], fk_length[i], 16);
|
||||
}
|
||||
put_mode(exit_attribute_mode);
|
||||
put_newlines(2);
|
||||
}
|
||||
if (first_time) {
|
||||
putln("The following keys are defined:");
|
||||
} else {
|
||||
putln("The following keys have not been tested:");
|
||||
}
|
||||
if (scan_mode) {
|
||||
for (i = 0; scan_down[i]; i++) {
|
||||
if (!scan_tested[i]) {
|
||||
if (hex_output) {
|
||||
strcpy(outbuf, hex_expand_to(scan_down[i], 3));
|
||||
} else {
|
||||
strcpy(outbuf, expand(scan_down[i]));
|
||||
}
|
||||
l = expand_chars;
|
||||
if (hex_output) {
|
||||
strcat(outbuf, hex_expand_to(scan_up[i], 3));
|
||||
} else {
|
||||
strcat(outbuf, expand(scan_up[i]));
|
||||
}
|
||||
expand_chars += l;
|
||||
l = strlen(scan_name[i]);
|
||||
if (((char_count + 16) & ~15) +
|
||||
((expand_chars + 7) & ~7) + l >= columns) {
|
||||
put_crlf();
|
||||
} else
|
||||
if (char_count + 24 > columns) {
|
||||
put_crlf();
|
||||
} else if (char_count) {
|
||||
putchp(' ');
|
||||
}
|
||||
put_columns(outbuf, expand_chars, 16);
|
||||
put_columns(scan_name[i], l, 8);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < key_count; i++) {
|
||||
if (!fk_tested[i]) {
|
||||
if (hex_output) {
|
||||
strcpy(outbuf, hex_expand_to(fkval[i], 3));
|
||||
} else {
|
||||
strcpy(outbuf, expand(fkval[i]));
|
||||
}
|
||||
l = strlen(fk_name[i]);
|
||||
if (((char_count + 16) & ~15) +
|
||||
((expand_chars + 7) & ~7) + l >= columns) {
|
||||
put_crlf();
|
||||
} else
|
||||
if (char_count + 24 > columns) {
|
||||
put_crlf();
|
||||
} else
|
||||
if (char_count) {
|
||||
putchp(' ');
|
||||
}
|
||||
put_columns(outbuf, expand_chars, 16);
|
||||
put_columns(fk_name[i], l, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
put_newlines(2);
|
||||
if (show_help) {
|
||||
ptextln("Hit any function key. Type 'end' to quit. Type ? to update the display.");
|
||||
put_crlf();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** enter_key(name, value, label)
|
||||
**
|
||||
** Enter a function key into the data base
|
||||
*/
|
||||
void
|
||||
enter_key(
|
||||
const char *name,
|
||||
char *value,
|
||||
char *lab)
|
||||
{
|
||||
int j;
|
||||
|
||||
alloc_strings();
|
||||
if (value) {
|
||||
j = strlen(value);
|
||||
fkmax = fkmax > j ? fkmax : j;
|
||||
/* do not permit duplicates */
|
||||
for (j = 0; j < key_count; j++) {
|
||||
if (!strcmp(fk_name[j], name)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
fkval[key_count] = value;
|
||||
fk_tested[key_count] = 0;
|
||||
fk_label[key_count] = lab;
|
||||
fk_name[key_count++] = name;
|
||||
if (lab) {
|
||||
got_labels = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fresh_line(void)
|
||||
{ /* clear the line for a new function key line */
|
||||
if (over_strike) {
|
||||
put_crlf();
|
||||
} else {
|
||||
put_cr();
|
||||
if (clr_eol) {
|
||||
tc_putp(clr_eol);
|
||||
} else {
|
||||
put_str(" \r");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
end_funky(int ch)
|
||||
{ /* return true if this is the end */
|
||||
switch (ch) {
|
||||
case 'e':
|
||||
case 'E':
|
||||
end_state = 'e';
|
||||
break;
|
||||
case 'n':
|
||||
case 'N':
|
||||
if (end_state == 'e') {
|
||||
end_state = 'n';
|
||||
} else {
|
||||
end_state = 0;
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
case 'D':
|
||||
if (end_state == 'n') {
|
||||
end_state = 'd';
|
||||
} else {
|
||||
end_state = 0;
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
case 'L':
|
||||
if (end_state == 'l') {
|
||||
end_state = '?';
|
||||
} else {
|
||||
end_state = 'l';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
end_state = 0;
|
||||
break;
|
||||
}
|
||||
return end_state == 'd';
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
found_match(char *s, int hx, int cc)
|
||||
{ /* return true if this string is a match */
|
||||
int j, f;
|
||||
char outbuf[256];
|
||||
|
||||
alloc_strings();
|
||||
if (!*s) {
|
||||
return 0;
|
||||
}
|
||||
if (scan_mode) {
|
||||
for (j = f = 0; scan_down[j]; j++) {
|
||||
if (scan_length[j] == 0) {
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(s, scan_down[j], scan_length[j])) {
|
||||
if (!f) { /* first match */
|
||||
put_cr();
|
||||
if (hx) {
|
||||
put_str(hex_expand_to(s, 10));
|
||||
} else {
|
||||
put_str(expand_to(s, 10));
|
||||
}
|
||||
f = 1;
|
||||
}
|
||||
(void) end_funky(scan_name[j][0]);
|
||||
put_str(" ");
|
||||
put_str(scan_name[j]);
|
||||
scan_tested[j] = 1;
|
||||
s += scan_length[j];
|
||||
if (strncmp(s, scan_up[j], scan_length[j])) {
|
||||
put_str(" scan down");
|
||||
} else {
|
||||
s += scan_length[j];
|
||||
}
|
||||
if (!*s) {
|
||||
break;
|
||||
}
|
||||
j = -1;
|
||||
}
|
||||
if (!strncmp(s, scan_up[j], scan_length[j])) {
|
||||
if (!f) { /* first match */
|
||||
put_cr();
|
||||
if (hx) {
|
||||
put_str(hex_expand_to(s, 10));
|
||||
} else {
|
||||
put_str(expand_to(s, 10));
|
||||
}
|
||||
f = 1;
|
||||
}
|
||||
put_str(" ");
|
||||
put_str(scan_name[j]);
|
||||
put_str(" scan up");
|
||||
s += scan_length[j];
|
||||
if (!*s) {
|
||||
break;
|
||||
}
|
||||
j = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (j = f = 0; j < key_count; j++) {
|
||||
if (!strcmp(s, fkval[j])) {
|
||||
if (!f) { /* first match */
|
||||
put_cr();
|
||||
if (hx) {
|
||||
put_str(hex_expand_to(s, 10));
|
||||
} else {
|
||||
put_str(expand_to(s, 10));
|
||||
}
|
||||
f = 1;
|
||||
}
|
||||
sprintf(outbuf, " (%s)", fk_name[j]);
|
||||
put_str(outbuf);
|
||||
if (fk_label[j]) {
|
||||
sprintf(outbuf, " <%s>", fk_label[j]);
|
||||
put_str(outbuf);
|
||||
}
|
||||
fk_tested[j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (end_state == '?') {
|
||||
keys_tested(0, 1, hx);
|
||||
tty_raw(cc, char_mask);
|
||||
end_state = 0;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
found_exit(char *keybuf, int hx, int cc)
|
||||
{ /* return true if the user wants to exit */
|
||||
int j, k;
|
||||
char *s;
|
||||
|
||||
|
||||
if (scan_mode) {
|
||||
if (*keybuf == '\0') {
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
/* break is a special case */
|
||||
if (*keybuf == '\0') {
|
||||
fresh_line();
|
||||
tty_set();
|
||||
ptext("Hit X to exit: ");
|
||||
if (wait_here() == 'X') {
|
||||
return TRUE;
|
||||
}
|
||||
keys_tested(0, 1, hx);
|
||||
tty_raw(cc, char_mask);
|
||||
return FALSE;
|
||||
}
|
||||
/* is this the end? */
|
||||
for (k = 0; (j = (keybuf[k] & STRIP_PARITY)); k++) {
|
||||
if (end_funky(j)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
j = TRUE; /* does he need an updated list? */
|
||||
for (k = 0; keybuf[k]; k++) {
|
||||
j &= (keybuf[k] & STRIP_PARITY) == '?';
|
||||
}
|
||||
if (j || end_state == '?') {
|
||||
keys_tested(0, 1, hx);
|
||||
tty_raw(cc, char_mask);
|
||||
end_state = 0;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
put_cr();
|
||||
if (hx) {
|
||||
s = hex_expand_to(keybuf, 10);
|
||||
} else {
|
||||
s = expand_to(keybuf, 10);
|
||||
}
|
||||
sprintf(temp, "%s Unknown", s);
|
||||
put_str(temp);
|
||||
for (j = 0; j < MAX_FK_UNK; j++) {
|
||||
if (j == funk) {
|
||||
fk_length[funk] = expand_chars;
|
||||
if ((fk_unknown[funk] = (char *)malloc(strlen(s) + 1))) {
|
||||
strcpy(fk_unknown[funk++], s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (fk_length[j] == expand_chars) {
|
||||
if (!strcmp(fk_unknown[j], s)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
** funkey_keys(test_list, status, ch)
|
||||
**
|
||||
** Test function keys
|
||||
*/
|
||||
static void
|
||||
funkey_keys(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
char keybuf[256];
|
||||
|
||||
if (keypad_xmit) {
|
||||
tc_putp(keypad_xmit);
|
||||
}
|
||||
keys_tested(1, 1, hex_out); /* also clears screen */
|
||||
keybuf[0] = '\0';
|
||||
end_state = 0;
|
||||
if (scan_mode) {
|
||||
fkmax = scan_max;
|
||||
}
|
||||
tty_raw(0, char_mask);
|
||||
while (end_state != 'd') {
|
||||
read_key(keybuf, sizeof(keybuf));
|
||||
fresh_line();
|
||||
if (found_match(keybuf, hex_out, 0)) {
|
||||
continue;
|
||||
}
|
||||
if (found_exit(keybuf, hex_out, 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (keypad_local) {
|
||||
tc_putp(keypad_local);
|
||||
}
|
||||
keys_tested(0, 0, hex_out);
|
||||
ptext("Function key test ");
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
int
|
||||
tty_meta_prep(void)
|
||||
{ /* print a warning before the meta key test */
|
||||
if (not_a_tty) {
|
||||
return 0;
|
||||
}
|
||||
if (initial_stty_query(TTY_8_BIT)) {
|
||||
return 0;
|
||||
}
|
||||
ptext("The meta key test must be run with the");
|
||||
ptext(" terminal set for 8 data bits. Two stop bits");
|
||||
ptext(" may also be needed for correct display. I will");
|
||||
ptext(" transmit 8 bit data but if the terminal is set for");
|
||||
ptextln(" 7 bit data, garbage may appear on the screen.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** funkey_meta(test_list, status, ch)
|
||||
**
|
||||
** Test meta key (km) (smm) (rmm)
|
||||
*/
|
||||
static void
|
||||
funkey_meta(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i, j, k, len;
|
||||
char outbuf[256];
|
||||
|
||||
if (has_meta_key) {
|
||||
put_crlf();
|
||||
if (char_mask != ALLOW_PARITY) {
|
||||
if (tty_meta_prep()) {
|
||||
ptext("\nHit any key to continue > ");
|
||||
(void) wait_here();
|
||||
put_crlf();
|
||||
}
|
||||
}
|
||||
ptext("Begin meta key test. (km) (smm) (rmm) Hit any key");
|
||||
ptext(" with the meta key. The character will be");
|
||||
ptext(" displayed in hex. If the meta key is working");
|
||||
ptext(" then the most significant bit will be set. Type");
|
||||
ptextln(" 'end' to exit.");
|
||||
tty_raw(1, ALLOW_PARITY);
|
||||
tc_putp(meta_on);
|
||||
|
||||
for (i = j = k = len = 0; i != 'e' || j != 'n' || k != 'd';) {
|
||||
i = j;
|
||||
j = k;
|
||||
k = getchp(ALLOW_PARITY);
|
||||
if (k == EOF) {
|
||||
break;
|
||||
}
|
||||
if ((len += 3) >= columns) {
|
||||
put_crlf();
|
||||
len = 3;
|
||||
}
|
||||
sprintf(outbuf, "%02X ", k);
|
||||
put_str(outbuf);
|
||||
k &= STRIP_PARITY;
|
||||
}
|
||||
tc_putp(meta_off);
|
||||
put_crlf();
|
||||
tty_set();
|
||||
put_crlf();
|
||||
} else {
|
||||
ptext("(km) Has-meta-key is not set. ");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** funkey_label(test_list, status, ch)
|
||||
**
|
||||
** Test labels (nlab) (smln) (pln) (rmln) (lw) (lh)
|
||||
*/
|
||||
static void
|
||||
funkey_label(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i;
|
||||
char outbuf[256];
|
||||
|
||||
if (num_labels == -1) {
|
||||
ptextln("Your terminal has no labels. (nlab)");
|
||||
} else {
|
||||
sprintf(temp, "Your terminal has %d labels (nlab) that are %d characters wide (lw) and %d lines high (lh)",
|
||||
num_labels, label_width, label_height);
|
||||
ptext(temp);
|
||||
ptextln(" Testing (smln) (pln) (rmln)");
|
||||
if (label_on) {
|
||||
tc_putp(label_on);
|
||||
}
|
||||
if (label_width <= 0) {
|
||||
label_width = sizeof(outbuf) - 1;
|
||||
}
|
||||
for (i = 1; i <= num_labels; i++) {
|
||||
sprintf(outbuf, "L%d..............................", i);
|
||||
outbuf[label_width] = '\0';
|
||||
tc_putp(TPARM_2(plab_norm, i, outbuf));
|
||||
}
|
||||
if (label_off) {
|
||||
ptext("Hit any key to remove the labels: ");
|
||||
(void) wait_here();
|
||||
tc_putp(label_off);
|
||||
}
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** funkey_prog(test_list, status, ch)
|
||||
**
|
||||
** Test program function keys (pfx)
|
||||
*/
|
||||
static void
|
||||
funkey_prog(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i, fk;
|
||||
char mm[256];
|
||||
|
||||
fk = 1; /* use function key 1 for now */
|
||||
if (pkey_xmit) {
|
||||
/* test program function key */
|
||||
sprintf(temp,
|
||||
"(pfx) Set function key %d to transmit abc\\n", fk);
|
||||
ptextln(temp);
|
||||
tc_putp(TPARM_2(pkey_xmit, fk, "abc\n"));
|
||||
sprintf(temp, "Hit function key %d\n", fk);
|
||||
ptextln(temp);
|
||||
for (i = 0; i < 4; ++i)
|
||||
mm[i] = getchp(STRIP_PARITY);
|
||||
mm[i] = '\0';
|
||||
put_crlf();
|
||||
if (mm[0] != 'a' || mm[1] != 'b' || mm[2] != 'c') {
|
||||
sprintf(temp, "Error string received was: %s", expand(mm));
|
||||
ptextln(temp);
|
||||
} else {
|
||||
putln("Thank you\n");
|
||||
}
|
||||
flush_input();
|
||||
if (key_f1) {
|
||||
tc_putp(TPARM_2(pkey_xmit, fk, key_f1));
|
||||
}
|
||||
} else {
|
||||
ptextln("Function key transmit (pfx), not present.");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** funkey_local(test_list, status, ch)
|
||||
**
|
||||
** Test program local function keys (pfloc)
|
||||
*/
|
||||
static void
|
||||
funkey_local(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int fk;
|
||||
|
||||
fk = 1;
|
||||
if (pkey_local) {
|
||||
/* test local function key */
|
||||
sprintf(temp,
|
||||
"(pfloc) Set function key %d to execute a clear and print \"Done!\"", fk);
|
||||
ptextln(temp);
|
||||
sprintf(temp, "%sDone!", liberated(clear_screen));
|
||||
tc_putp(TPARM_2(pkey_local, fk, temp));
|
||||
sprintf(temp, "Hit function key %d. Then hit return.", fk);
|
||||
ptextln(temp);
|
||||
(void) wait_here();
|
||||
flush_input();
|
||||
if (key_f1 && pkey_xmit) {
|
||||
tc_putp(TPARM_2(pkey_xmit, fk, key_f1));
|
||||
}
|
||||
} else {
|
||||
ptextln("Function key execute local (pfloc), not present.");
|
||||
}
|
||||
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** printer_on(test_list, status, ch)
|
||||
**
|
||||
** Test printer on/off (mc4) (mc5) (mc5i)
|
||||
*/
|
||||
static void
|
||||
printer_on(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (!prtr_on || !prtr_off) {
|
||||
ptextln("Printer on/off missing. (mc5) (mc4)");
|
||||
} else if (prtr_silent) {
|
||||
ptextln("Your printer is silent. (mc5i) is set.");
|
||||
tc_putp(prtr_on);
|
||||
ptextln("This line should be on the printer but not your screen. (mc5)");
|
||||
tc_putp(prtr_off);
|
||||
ptextln("This line should be only on the screen. (mc4)");
|
||||
} else {
|
||||
ptextln("Your printer is not silent. (mc5i) is reset.");
|
||||
tc_putp(prtr_on);
|
||||
ptextln("This line should be on the printer and the screen. (mc5)");
|
||||
tc_putp(prtr_off);
|
||||
ptextln("This line should only be on the screen. (mc4)");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** printer_mc0(test_list, status, ch)
|
||||
**
|
||||
** Test screen print (mc0)
|
||||
*/
|
||||
static void
|
||||
printer_mc0(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (print_screen) {
|
||||
ptext("I am going to send the contents of the screen to");
|
||||
ptext(" the printer, then wait for a keystroke from you.");
|
||||
ptext(" All of the text that appears on the screen");
|
||||
ptextln(" should be printed. (mc0)");
|
||||
tc_putp(print_screen);
|
||||
} else {
|
||||
ptext("(mc0) Print-screen is not present. ");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
line_pattern(void)
|
||||
{ /* put up a pattern that will help count the
|
||||
number of lines */
|
||||
int i, j;
|
||||
|
||||
put_clear();
|
||||
if (over_strike) {
|
||||
for (i = 0; i < 100; i++) {
|
||||
if (i) {
|
||||
put_crlf();
|
||||
}
|
||||
for (j = i / 10; j; j--) {
|
||||
put_this(' ');
|
||||
}
|
||||
put_this('0' + ((i + 1) % 10));
|
||||
}
|
||||
} else /* I assume it will scroll */ {
|
||||
for (i = 100; i; i--) {
|
||||
sprintf(temp, "\r\n%d", i);
|
||||
put_str(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
column_pattern(void)
|
||||
{ /* put up a pattern that will help count the
|
||||
number of columns */
|
||||
int i, j;
|
||||
|
||||
put_clear();
|
||||
for (i = 0; i < 20; i++) {
|
||||
for (j = 1; j < 10; j++) {
|
||||
put_this('0' + j);
|
||||
}
|
||||
put_this('.');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** report_help()
|
||||
**
|
||||
** Print the help text for the echo tests
|
||||
*/
|
||||
static void
|
||||
report_help(int crx)
|
||||
{
|
||||
ptextln("The following commands may also be entered:");
|
||||
ptextln(" clear clear screen.");
|
||||
ptextln(" columns print a test pattern to help count screen width.");
|
||||
ptextln(" lines print a test pattern to help count screen length.");
|
||||
ptextln(" end exit.");
|
||||
ptextln(" echo redisplay last report.");
|
||||
if (crx) {
|
||||
ptextln(" hex redisplay last report in hex.");
|
||||
} else {
|
||||
ptextln(" hex toggle hex display mode.");
|
||||
}
|
||||
ptextln(" help display this list.");
|
||||
ptextln(" high toggle forced high bit (0x80).");
|
||||
ptextln(" scan toggle scan mode.");
|
||||
ptextln(" one echo one character after <cr> or <lf> as is. (report mode)");
|
||||
ptextln(" two echo two characters after <cr> or <lf> as is.");
|
||||
ptextln(" all echo all characters after <cr> or <lf> as is. (echo mode)");
|
||||
}
|
||||
|
||||
/*
|
||||
** tools_report(testlist, state, ch)
|
||||
**
|
||||
** Run the echo tool and report tool
|
||||
*/
|
||||
void
|
||||
tools_report(
|
||||
struct test_list *t,
|
||||
int *state GCC_UNUSED,
|
||||
int *pch GCC_UNUSED)
|
||||
{
|
||||
int i, j, ch, crp, crx, high_bit, save_scan_mode, hex_display;
|
||||
char buf[1024];
|
||||
char txt[8];
|
||||
|
||||
hex_display = hex_out;
|
||||
put_clear();
|
||||
if ((crx = (t->flags & 255)) == 1) {
|
||||
ptext("Characters after a CR or LF will be echoed as");
|
||||
ptextln(" is. All other characters will be expanded.");
|
||||
report_help(crx);
|
||||
} else { /* echo test */
|
||||
ptextln("Begin echo test.");
|
||||
report_help(crx);
|
||||
}
|
||||
memset(txt, 0, sizeof(txt));
|
||||
save_scan_mode = scan_mode;
|
||||
tty_raw(1, char_mask);
|
||||
for (i = crp = high_bit = 0;;) {
|
||||
ch = getchp(char_mask);
|
||||
if (ch == EOF) {
|
||||
break;
|
||||
}
|
||||
if (i >= (int) sizeof(buf) - 1) {
|
||||
i = 0;
|
||||
}
|
||||
buf[i++] = ch;
|
||||
buf[i] = '\0';
|
||||
for (j = 0; j < (int) sizeof(txt) - 1; j++) {
|
||||
txt[j] = txt[j + 1];
|
||||
}
|
||||
txt[sizeof(txt) - 1] = ch & STRIP_PARITY;
|
||||
if (crx == 0) { /* echo test */
|
||||
if (hex_display) {
|
||||
ptext(hex_expand_to(&buf[i - 1], 3));
|
||||
} else {
|
||||
tc_putch(ch | high_bit);
|
||||
}
|
||||
} else /* status report test */
|
||||
if (ch == '\n' || ch == '\r') {
|
||||
put_crlf();
|
||||
crp = 0;
|
||||
} else if (crp++ < crx) {
|
||||
tc_putch(ch | high_bit);
|
||||
} else {
|
||||
put_str(expand(&buf[i - 1]));
|
||||
}
|
||||
if (!strncmp(&txt[sizeof(txt) - 7], "columns", 7)) {
|
||||
column_pattern();
|
||||
buf[i = 0] = '\0';
|
||||
crp = 0;
|
||||
}
|
||||
if (!strncmp(&txt[sizeof(txt) - 5], "lines", 5)) {
|
||||
line_pattern();
|
||||
buf[i = 0] = '\0';
|
||||
crp = 0;
|
||||
}
|
||||
if (!strncmp(&txt[sizeof(txt) - 5], "clear", 5)) {
|
||||
put_clear();
|
||||
buf[i = 0] = '\0';
|
||||
crp = 0;
|
||||
}
|
||||
if (!strncmp(&txt[sizeof(txt) - 4], "high", 4)) {
|
||||
high_bit ^= 0x80;
|
||||
if (high_bit) {
|
||||
ptextln("\nParity bit set");
|
||||
} else {
|
||||
ptextln("\nParity bit reset");
|
||||
}
|
||||
}
|
||||
if (!strncmp(&txt[sizeof(txt) - 4], "help", 4)) {
|
||||
put_crlf();
|
||||
report_help(crx);
|
||||
}
|
||||
if (!strncmp(&txt[sizeof(txt) - 4], "echo", 4)) {
|
||||
/* display the last status report */
|
||||
/* clear bypass condition on Tek terminals */
|
||||
put_crlf();
|
||||
if (i >= 4) {
|
||||
buf[i -= 4] = '\0';
|
||||
}
|
||||
put_str(expand(buf));
|
||||
}
|
||||
if (save_scan_mode &&
|
||||
!strncmp(&txt[sizeof(txt) - 4], "scan", 4)) {
|
||||
/* toggle scan mode */
|
||||
scan_mode = !scan_mode;
|
||||
}
|
||||
if (!strncmp(&txt[sizeof(txt) - 3], "end", 3))
|
||||
break;
|
||||
if (!strncmp(&txt[sizeof(txt) - 3], "hex", 3)) {
|
||||
if (crx) {
|
||||
/* display the last status report in hex */
|
||||
/* clear bypass condition on Tek terminals */
|
||||
put_crlf();
|
||||
if (i >= 3) {
|
||||
buf[i -= 3] = '\0';
|
||||
}
|
||||
put_str(hex_expand_to(buf, 3));
|
||||
} else {
|
||||
hex_display = !hex_display;
|
||||
}
|
||||
}
|
||||
if (!strncmp(&txt[sizeof(txt) - 3], "two", 3))
|
||||
crx = 2;
|
||||
if (!strncmp(&txt[sizeof(txt) - 3], "one", 3))
|
||||
crx = 1;
|
||||
if (!strncmp(&txt[sizeof(txt) - 3], "all", 3))
|
||||
crx = 0;
|
||||
}
|
||||
scan_mode = save_scan_mode;
|
||||
put_crlf();
|
||||
tty_set();
|
||||
if (crx) {
|
||||
ptextln("End of status report test.");
|
||||
} else {
|
||||
ptextln("End of echo test.");
|
||||
}
|
||||
}
|
@ -1,316 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
/* initialization and wrapup code */
|
||||
|
||||
#include <tack.h>
|
||||
|
||||
MODULE_ID("$Id: init.c,v 1.7 2006/11/26 00:16:01 tom Exp $")
|
||||
|
||||
#if NCURSES_VERSION_MAJOR >= 5 || NCURSES_VERSION_PATCH >= 981219
|
||||
#define _nc_get_curterm(p) _nc_get_tty_mode(p)
|
||||
#endif
|
||||
|
||||
FILE *debug_fp;
|
||||
char temp[1024];
|
||||
char tty_basename[64];
|
||||
|
||||
void
|
||||
put_name(const char *cap, const char *name)
|
||||
{ /* send the cap name followed by the cap */
|
||||
if (cap) {
|
||||
ptext(name);
|
||||
tc_putp(cap);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
report_cap(const char *tag, const char *s)
|
||||
{ /* expand the cap or print *** missing *** */
|
||||
int i;
|
||||
|
||||
ptext(tag);
|
||||
for (i = char_count; i < 13; i++) {
|
||||
putchp(' ');
|
||||
}
|
||||
put_str(" = ");
|
||||
if (s) {
|
||||
putln(expand(s));
|
||||
} else {
|
||||
putln("*** missing ***");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
reset_init(void)
|
||||
{ /* send the reset and init strings */
|
||||
int i;
|
||||
|
||||
ptext("Terminal reset");
|
||||
i = char_count;
|
||||
put_name(reset_1string, " (rs1)");
|
||||
put_name(reset_2string, " (rs2)");
|
||||
/* run the reset file */
|
||||
if (reset_file && reset_file[0]) {
|
||||
FILE *fp;
|
||||
int ch;
|
||||
|
||||
can_test("rf", FLAG_TESTED);
|
||||
if ((fp = fopen(reset_file, "r"))) { /* send the reset file */
|
||||
sprintf(temp, " (rf) %s", reset_file);
|
||||
ptextln(temp);
|
||||
while (1) {
|
||||
ch = getc(fp);
|
||||
if (ch == EOF)
|
||||
break;
|
||||
put_this(ch);
|
||||
}
|
||||
fclose(fp);
|
||||
} else {
|
||||
sprintf(temp, "\nCannot open reset file (rf) %s", reset_file);
|
||||
ptextln(temp);
|
||||
}
|
||||
}
|
||||
put_name(reset_3string, " (rs3)");
|
||||
if (i != char_count) {
|
||||
put_crlf();
|
||||
}
|
||||
ptext(" init");
|
||||
put_name(init_1string, " (is1)");
|
||||
put_name(init_2string, " (is2)");
|
||||
if (set_tab && clear_all_tabs && init_tabs != 8) {
|
||||
put_crlf();
|
||||
tc_putp(clear_all_tabs);
|
||||
for (char_count = 0; char_count < columns; char_count++) {
|
||||
put_this(' ');
|
||||
if ((char_count & 7) == 7) {
|
||||
tc_putp(set_tab);
|
||||
}
|
||||
}
|
||||
put_cr();
|
||||
}
|
||||
/* run the initialization file */
|
||||
if (init_file && init_file[0]) {
|
||||
FILE *fp;
|
||||
int ch;
|
||||
|
||||
can_test("if", FLAG_TESTED);
|
||||
if ((fp = fopen(init_file, "r"))) { /* send the init file */
|
||||
sprintf(temp, " (if) %s", init_file);
|
||||
ptextln(temp);
|
||||
while (1) {
|
||||
ch = getc(fp);
|
||||
if (ch == EOF)
|
||||
break;
|
||||
put_this(ch);
|
||||
}
|
||||
fclose(fp);
|
||||
} else {
|
||||
sprintf(temp, "\nCannot open init file (if) %s", init_file);
|
||||
ptextln(temp);
|
||||
}
|
||||
}
|
||||
if (init_prog) {
|
||||
can_test("iprog", FLAG_TESTED);
|
||||
(void) system(init_prog);
|
||||
}
|
||||
put_name(init_3string, " (is3)");
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
** display_basic()
|
||||
**
|
||||
** display the basic terminal definitions
|
||||
*/
|
||||
void
|
||||
display_basic(void)
|
||||
{
|
||||
put_str("Name: ");
|
||||
putln(ttytype);
|
||||
|
||||
report_cap("\\r ^M (cr)", carriage_return);
|
||||
report_cap("\\n ^J (ind)", scroll_forward);
|
||||
report_cap("\\b ^H (cub1)", cursor_left);
|
||||
report_cap("\\t ^I (ht)", tab);
|
||||
/* report_cap("\\f ^L (ff)", form_feed); */
|
||||
if (newline) {
|
||||
/* OK if missing */
|
||||
report_cap(" (nel)", newline);
|
||||
}
|
||||
report_cap(" (clear)", clear_screen);
|
||||
if (!cursor_home && cursor_address) {
|
||||
report_cap("(cup) (home)", TPARM_2(cursor_address, 0, 0));
|
||||
} else {
|
||||
report_cap(" (home)", cursor_home);
|
||||
}
|
||||
#ifdef user9
|
||||
report_cap("ENQ (u9)", user9);
|
||||
#endif
|
||||
#ifdef user8
|
||||
report_cap("ACK (u8)", user8);
|
||||
#endif
|
||||
|
||||
sprintf(temp, "\nTerminal size: %d x %d. Baud rate: %u. Frame size: %d.%d",
|
||||
columns, lines,
|
||||
tty_baud_rate,
|
||||
tty_frame_size >> 1,
|
||||
(tty_frame_size & 1) * 5);
|
||||
putln(temp);
|
||||
}
|
||||
|
||||
/*
|
||||
** curses_setup(exec_name)
|
||||
**
|
||||
** Startup ncurses
|
||||
*/
|
||||
void
|
||||
curses_setup(
|
||||
char *exec_name)
|
||||
{
|
||||
int status;
|
||||
static TERMTYPE term;
|
||||
char tty_filename[2048];
|
||||
|
||||
tty_init();
|
||||
|
||||
/**
|
||||
See if the terminal is in the terminfo data base. This call has
|
||||
two useful benefits, 1) it returns the filename of the terminfo entry,
|
||||
and 2) it searches only terminfo's. This allows us to abort before
|
||||
ncurses starts scanning the termcap file.
|
||||
**/
|
||||
if ((status = _nc_read_entry(tty_basename, tty_filename, &term)) == 0) {
|
||||
const TERMTYPE *fallback = _nc_fallback(tty_basename);
|
||||
|
||||
if (fallback) {
|
||||
term = *fallback;
|
||||
sprintf(tty_filename, "(fallback)%s", tty_basename);
|
||||
status = 1;
|
||||
} else {
|
||||
fprintf(stderr, "Terminal not found: TERM=%s\n", tty_basename);
|
||||
show_usage(exec_name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (status == -1) {
|
||||
fprintf(stderr, "Terminfo database is inaccessible\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
This call will load the terminfo data base and set the cur-term
|
||||
variable. Only terminals that actually exist will get here so its
|
||||
OK to ignore errors. This is a good thing since ncurses does not
|
||||
permit (os) or (gn) to be set.
|
||||
**/
|
||||
setupterm(tty_basename, 1, &status);
|
||||
|
||||
/**
|
||||
Get the current terminal definitions. This must be done before
|
||||
getting the baudrate.
|
||||
**/
|
||||
_nc_get_curterm(&cur_term->Nttyb);
|
||||
tty_baud_rate = baudrate();
|
||||
tty_cps = (tty_baud_rate << 1) / tty_frame_size;
|
||||
|
||||
/* set up the defaults */
|
||||
replace_mode = TRUE;
|
||||
scan_mode = 0;
|
||||
char_count = 0;
|
||||
select_delay_type = debug_level = 0;
|
||||
char_mask = (meta_on && meta_on[0] == '\0') ? ALLOW_PARITY : STRIP_PARITY;
|
||||
/* Don't change the XON/XOFF modes yet. */
|
||||
select_xon_xoff = initial_stty_query(TTY_XON_XOFF) ? 1 : needs_xon_xoff;
|
||||
|
||||
fflush(stdout); /* flush any output */
|
||||
tty_set();
|
||||
|
||||
go_home(); /* set can_go_home */
|
||||
put_clear(); /* set can_clear_screen */
|
||||
|
||||
if (send_reset_init) {
|
||||
reset_init();
|
||||
}
|
||||
|
||||
/*
|
||||
I assume that the reset and init strings may not have the correct
|
||||
pads. (Because that part of the test comes much later.) Because
|
||||
of this, I allow the terminal some time to catch up.
|
||||
*/
|
||||
fflush(stdout); /* waste some time */
|
||||
sleep(1); /* waste more time */
|
||||
charset_can_test();
|
||||
can_test("lines cols cr nxon rf if iprog rmp smcup rmcup", FLAG_CAN_TEST);
|
||||
edit_init(); /* initialize the edit data base */
|
||||
|
||||
if (send_reset_init && enter_ca_mode) {
|
||||
tc_putp(enter_ca_mode);
|
||||
put_clear(); /* just in case we switched pages */
|
||||
}
|
||||
put_crlf();
|
||||
ptext("Using terminfo from: ");
|
||||
ptextln(tty_filename);
|
||||
put_crlf();
|
||||
|
||||
if (tty_can_sync == SYNC_NEEDED) {
|
||||
verify_time();
|
||||
}
|
||||
|
||||
display_basic();
|
||||
}
|
||||
|
||||
/*
|
||||
** bye_kids(exit-condition)
|
||||
**
|
||||
** Shutdown the terminal, clear the signals, and exit
|
||||
*/
|
||||
void
|
||||
bye_kids(int n)
|
||||
{ /* reset the tty and exit */
|
||||
ignoresig();
|
||||
if (send_reset_init) {
|
||||
if (exit_ca_mode) {
|
||||
tc_putp(exit_ca_mode);
|
||||
}
|
||||
if (initial_stty_query(TTY_XON_XOFF)) {
|
||||
if (enter_xon_mode) {
|
||||
tc_putp(enter_xon_mode);
|
||||
}
|
||||
} else if (exit_xon_mode) {
|
||||
tc_putp(exit_xon_mode);
|
||||
}
|
||||
}
|
||||
if (debug_fp) {
|
||||
fclose(debug_fp);
|
||||
}
|
||||
if (log_fp) {
|
||||
fclose(log_fp);
|
||||
}
|
||||
tty_reset();
|
||||
fclose(stdin);
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
if (not_a_tty)
|
||||
sleep(1);
|
||||
exit(n);
|
||||
}
|
@ -1,421 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <tack.h>
|
||||
|
||||
MODULE_ID("$Id: menu.c,v 1.3 2005/09/17 19:49:16 tom Exp $")
|
||||
|
||||
/*
|
||||
Menu control
|
||||
*/
|
||||
|
||||
static void test_byname(struct test_menu *, int *, int *);
|
||||
|
||||
struct test_list *augment_test;
|
||||
char prompt_string[80]; /* menu prompt storage */
|
||||
|
||||
/*
|
||||
** menu_prompt()
|
||||
**
|
||||
** Print the menu prompt string.
|
||||
*/
|
||||
void
|
||||
menu_prompt(void)
|
||||
{
|
||||
ptext(&prompt_string[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
** menu_test_loop(test-structure, state, control-character)
|
||||
**
|
||||
** This function implements the repeat test function.
|
||||
*/
|
||||
static void
|
||||
menu_test_loop(
|
||||
struct test_list *test,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int nch, p;
|
||||
|
||||
if ((test->flags & MENU_REP_MASK) && (augment_test != test)) {
|
||||
/* set the augment variable (first time only) */
|
||||
p = (test->flags >> 8) & 15;
|
||||
if ((test->flags & MENU_REP_MASK) == MENU_LM1) {
|
||||
augment = lines - 1;
|
||||
} else
|
||||
if ((test->flags & MENU_ONE_MASK) == MENU_ONE) {
|
||||
augment = 1;
|
||||
} else
|
||||
if ((test->flags & MENU_LC_MASK) == MENU_lines) {
|
||||
augment = lines * p / 10;
|
||||
} else
|
||||
if ((test->flags & MENU_LC_MASK) == MENU_columns) {
|
||||
augment = columns * p / 10;
|
||||
} else {
|
||||
augment = 1;
|
||||
}
|
||||
augment_test = test;
|
||||
set_augment_txt();
|
||||
}
|
||||
do {
|
||||
if ((test->flags | *state) & MENU_CLEAR) {
|
||||
put_clear();
|
||||
} else
|
||||
if (line_count + test->lines_needed >= lines) {
|
||||
put_clear();
|
||||
}
|
||||
nch = 0;
|
||||
if (test->test_procedure) {
|
||||
/* The procedure takes precedence so I can pass
|
||||
the menu entry as an argument.
|
||||
*/
|
||||
can_test(test->caps_done, FLAG_TESTED);
|
||||
can_test(test->caps_tested, FLAG_TESTED);
|
||||
test->test_procedure(test, state, &nch);
|
||||
} else
|
||||
if (test->sub_menu) {
|
||||
/* nested menu's */
|
||||
menu_display(test->sub_menu, &nch);
|
||||
*state = 0;
|
||||
if (nch == 'q' || nch == 's') {
|
||||
/* Quit and skip are killed here */
|
||||
nch = '?';
|
||||
}
|
||||
} else {
|
||||
break; /* cya */
|
||||
}
|
||||
if (nch == '\r' || nch == '\n' || nch == 'n') {
|
||||
nch = 0;
|
||||
break;
|
||||
}
|
||||
} while (nch == 'r');
|
||||
*ch = nch;
|
||||
}
|
||||
|
||||
/*
|
||||
** menu_display(menu-structure, flags)
|
||||
**
|
||||
** This function implements menu control.
|
||||
*/
|
||||
void
|
||||
menu_display(
|
||||
struct test_menu *menu,
|
||||
int *last_ch)
|
||||
{
|
||||
int test_state = 0, run_standard_tests;
|
||||
int hot_topic, ch = 0, nch = 0;
|
||||
struct test_list *mt;
|
||||
struct test_list *repeat_tests = 0;
|
||||
int repeat_state = 0;
|
||||
int prompt_length;
|
||||
|
||||
prompt_length = strlen(prompt_string);
|
||||
if (menu->ident) {
|
||||
sprintf(&prompt_string[prompt_length], "/%s", menu->ident);
|
||||
}
|
||||
hot_topic = menu->default_action;
|
||||
run_standard_tests = menu->standard_tests ?
|
||||
menu->standard_tests[0] : -1;
|
||||
if (!last_ch) {
|
||||
last_ch = &ch;
|
||||
}
|
||||
while (1) {
|
||||
if (ch == 0) {
|
||||
/* Display the menu */
|
||||
put_crlf();
|
||||
if (menu->menu_function) {
|
||||
/*
|
||||
this function may be used to restrict menu
|
||||
entries. If used it must print the title.
|
||||
*/
|
||||
menu->menu_function(menu);
|
||||
} else
|
||||
if (menu->menu_title) {
|
||||
ptextln(menu->menu_title);
|
||||
}
|
||||
for (mt = menu->tests; (mt->flags & MENU_LAST) == 0; mt++) {
|
||||
if (mt->menu_entry) {
|
||||
ptext(" ");
|
||||
ptextln(mt->menu_entry);
|
||||
}
|
||||
}
|
||||
if (menu->standard_tests) {
|
||||
ptext(" ");
|
||||
ptextln(menu->standard_tests);
|
||||
ptextln(" r) repeat test");
|
||||
ptextln(" s) skip to next test");
|
||||
}
|
||||
ptextln(" q) quit");
|
||||
ptextln(" ?) help");
|
||||
}
|
||||
if (ch == 0 || ch == REQUEST_PROMPT) {
|
||||
put_crlf();
|
||||
ptext(&prompt_string[1]);
|
||||
if (hot_topic) {
|
||||
ptext(" [");
|
||||
putchp(hot_topic);
|
||||
ptext("]");
|
||||
}
|
||||
ptext(" > ");
|
||||
/* read a character */
|
||||
ch = wait_here();
|
||||
}
|
||||
if (ch == '\r' || ch == '\n') {
|
||||
ch = hot_topic;
|
||||
}
|
||||
if (ch == 'q') {
|
||||
break;
|
||||
}
|
||||
if (ch == '?') {
|
||||
ch = 0;
|
||||
continue;
|
||||
}
|
||||
nch = ch;
|
||||
ch = 0;
|
||||
/* Run one of the standard tests (by request) */
|
||||
for (mt = menu->tests; (mt->flags & MENU_LAST) == 0; mt++) {
|
||||
if (mt->menu_entry && (nch == mt->menu_entry[0])) {
|
||||
if (mt->flags & MENU_MENU) {
|
||||
test_byname(menu, &test_state, &nch);
|
||||
} else {
|
||||
menu_test_loop(mt, &test_state, &nch);
|
||||
}
|
||||
ch = nch;
|
||||
if ((mt->flags & MENU_COMPLETE) && ch == 0) {
|
||||
/* top level */
|
||||
hot_topic = 'q';
|
||||
ch = '?';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (menu->standard_tests && nch == 'r') {
|
||||
menu->resume_tests = repeat_tests;
|
||||
test_state = repeat_state;
|
||||
nch = run_standard_tests;
|
||||
}
|
||||
if (nch == run_standard_tests) {
|
||||
if (!(mt = menu->resume_tests)) {
|
||||
mt = menu->tests;
|
||||
}
|
||||
if (mt->flags & MENU_LAST) {
|
||||
mt = menu->tests;
|
||||
}
|
||||
/* Run the standard test suite */
|
||||
for ( ; (mt->flags & MENU_LAST) == 0; ) {
|
||||
if ((mt->flags & MENU_NEXT) == MENU_NEXT) {
|
||||
repeat_tests = mt;
|
||||
repeat_state = test_state;
|
||||
nch = run_standard_tests;
|
||||
menu_test_loop(mt, &test_state, &nch);
|
||||
if (nch != 0 && nch != 'n') {
|
||||
ch = nch;
|
||||
break;
|
||||
}
|
||||
if (test_state & MENU_STOP) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
mt++;
|
||||
}
|
||||
if (ch == 0) {
|
||||
ch = hot_topic;
|
||||
}
|
||||
menu->resume_tests = mt;
|
||||
menu->resume_state = test_state;
|
||||
menu->resume_char = ch;
|
||||
|
||||
if (ch == run_standard_tests) {
|
||||
/* pop up a level */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*last_ch = ch;
|
||||
prompt_string[prompt_length] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
** generic_done_message(test_list)
|
||||
**
|
||||
** Print the Done message and request input.
|
||||
*/
|
||||
void
|
||||
generic_done_message(
|
||||
struct test_list *test,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
char done_message[128];
|
||||
|
||||
if (test->caps_done) {
|
||||
sprintf(done_message, "(%s) Done ", test->caps_done);
|
||||
ptext(done_message);
|
||||
} else {
|
||||
ptext("Done ");
|
||||
}
|
||||
*ch = wait_here();
|
||||
if (*ch == '\r' || *ch == '\n' || *ch == 'n') {
|
||||
*ch = 0;
|
||||
}
|
||||
if (*ch == 's') {
|
||||
*state |= MENU_STOP;
|
||||
*ch = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** menu_clear_screen(test, state, ch)
|
||||
**
|
||||
** Just clear the screen.
|
||||
*/
|
||||
void
|
||||
menu_clear_screen(
|
||||
struct test_list *test GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch GCC_UNUSED)
|
||||
{
|
||||
put_clear();
|
||||
}
|
||||
|
||||
/*
|
||||
** menu_reset_init(test, state, ch)
|
||||
**
|
||||
** Send the reset and init strings.
|
||||
*/
|
||||
void
|
||||
menu_reset_init(
|
||||
struct test_list *test GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch GCC_UNUSED)
|
||||
{
|
||||
reset_init();
|
||||
put_crlf();
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_menu(test, state, ch)
|
||||
**
|
||||
** Scan the menu looking for something to execute
|
||||
** Return TRUE if we found anything.
|
||||
*/
|
||||
int
|
||||
subtest_menu(
|
||||
struct test_list *test,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
struct test_list *mt;
|
||||
|
||||
if (*ch) {
|
||||
for (mt = test; (mt->flags & MENU_LAST) == 0; mt++) {
|
||||
if (mt->menu_entry && (*ch == mt->menu_entry[0])) {
|
||||
*ch = 0;
|
||||
menu_test_loop(mt, state, ch);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
** menu_can_scan(menu-structure)
|
||||
**
|
||||
** Recursively scan the menu tree and find which cap names can be tested.
|
||||
*/
|
||||
void
|
||||
menu_can_scan(
|
||||
const struct test_menu *menu)
|
||||
{
|
||||
struct test_list *mt;
|
||||
|
||||
for (mt = menu->tests; (mt->flags & MENU_LAST) == 0; mt++) {
|
||||
can_test(mt->caps_done, FLAG_CAN_TEST);
|
||||
can_test(mt->caps_tested, FLAG_CAN_TEST);
|
||||
if (!(mt->test_procedure)) {
|
||||
if (mt->sub_menu) {
|
||||
menu_can_scan(mt->sub_menu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** menu_search(menu-structure, cap)
|
||||
**
|
||||
** Recursively search the menu tree and execute any tests that use cap.
|
||||
*/
|
||||
static void
|
||||
menu_search(
|
||||
struct test_menu *menu,
|
||||
int *state,
|
||||
int *ch,
|
||||
char *cap)
|
||||
{
|
||||
struct test_list *mt;
|
||||
int nch;
|
||||
|
||||
for (mt = menu->tests; (mt->flags & MENU_LAST) == 0; mt++) {
|
||||
nch = 0;
|
||||
if (cap_match(mt->caps_done, cap)
|
||||
|| cap_match(mt->caps_tested, cap)) {
|
||||
menu_test_loop(mt, state, &nch);
|
||||
}
|
||||
if (!(mt->test_procedure)) {
|
||||
if (mt->sub_menu) {
|
||||
menu_search(mt->sub_menu, state, &nch, cap);
|
||||
}
|
||||
}
|
||||
if (*state & MENU_STOP) {
|
||||
break;
|
||||
}
|
||||
if (nch != 0 && nch != 'n') {
|
||||
*ch = nch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** test_byname(menu, state, ch)
|
||||
**
|
||||
** Get a cap name then run all tests that use that cap.
|
||||
*/
|
||||
static void
|
||||
test_byname(
|
||||
struct test_menu *menu,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
int test_state = 0;
|
||||
char cap[32];
|
||||
|
||||
if (tty_can_sync == SYNC_NOT_TESTED) {
|
||||
verify_time();
|
||||
}
|
||||
ptext("enter name: ");
|
||||
read_string(cap, sizeof(cap));
|
||||
if (cap[0]) {
|
||||
menu_search(menu, &test_state, ch, cap);
|
||||
}
|
||||
*ch = '?';
|
||||
}
|
@ -1,913 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <tack.h>
|
||||
|
||||
MODULE_ID("$Id: modes.c,v 1.3 2006/11/26 00:16:21 tom Exp $")
|
||||
|
||||
/*
|
||||
* Tests boolean flags and terminal modes.
|
||||
*/
|
||||
static void subtest_os(struct test_list *, int *, int *);
|
||||
static void subtest_rmam(struct test_list *, int *, int *);
|
||||
static void subtest_smam(struct test_list *, int *, int *);
|
||||
static void subtest_am(struct test_list *, int *, int *);
|
||||
static void subtest_ul(struct test_list *, int *, int *);
|
||||
static void subtest_uc(struct test_list *, int *, int *);
|
||||
static void subtest_bw(struct test_list *, int *, int *);
|
||||
static void subtest_xenl(struct test_list *, int *, int *);
|
||||
static void subtest_eo(struct test_list *, int *, int *);
|
||||
static void subtest_xmc(struct test_list *, int *, int *);
|
||||
static void subtest_xhp(struct test_list *, int *, int *);
|
||||
static void subtest_mir(struct test_list *, int *, int *);
|
||||
static void subtest_msgr(struct test_list *, int *, int *);
|
||||
static void subtest_tbc(struct test_list *, int *, int *);
|
||||
static void subtest_xt(struct test_list *, int *, int *);
|
||||
static void subtest_hts(struct test_list *, int *, int *);
|
||||
static void subtest_cbt(struct test_list *, int *, int *);
|
||||
static void subtest_in(struct test_list *, int *, int *);
|
||||
static void subtest_dadb(struct test_list *, int *, int *);
|
||||
|
||||
struct test_list mode_test_list[] = {
|
||||
{0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu},
|
||||
{MENU_NEXT, 3, "os", 0, 0, subtest_os, 0},
|
||||
{MENU_NEXT, 1, "rmam", 0, 0, subtest_rmam, 0},
|
||||
{MENU_NEXT, 1, "smam", 0, 0, subtest_smam, 0},
|
||||
{MENU_NEXT, 1, "am", 0, 0, subtest_am, 0},
|
||||
{MENU_NEXT, 3, "ul", 0, 0, subtest_ul, 0},
|
||||
{MENU_NEXT, 3, "uc", 0, 0, subtest_uc, 0},
|
||||
{MENU_NEXT, 3, "bw", 0, 0, subtest_bw, 0},
|
||||
{MENU_NEXT, 4, "xenl", 0, 0, subtest_xenl, 0},
|
||||
{MENU_NEXT, 3, "eo", 0, 0, subtest_eo, 0},
|
||||
{MENU_NEXT, 3, "xmc", 0, 0, subtest_xmc, 0},
|
||||
{MENU_NEXT, 3, "xhp", 0, 0, subtest_xhp, 0},
|
||||
{MENU_NEXT, 6, "mir", 0, 0, subtest_mir, 0},
|
||||
{MENU_NEXT, 6, "msgr", 0, 0, subtest_msgr, 0},
|
||||
{MENU_NEXT | MENU_CLEAR, 0, "tbc", "it", 0, subtest_tbc, 0},
|
||||
{MENU_NEXT | MENU_CLEAR, 0, "hts", "it", 0, subtest_hts, 0},
|
||||
{MENU_NEXT, 4, "xt", "it", 0, subtest_xt, 0},
|
||||
{MENU_NEXT, 1, "cbt", "it", 0, subtest_cbt, 0},
|
||||
{MENU_NEXT, 6, "in", 0, 0, subtest_in, 0},
|
||||
{MENU_NEXT, 1, "da) (db", 0, 0, subtest_dadb, 0},
|
||||
{MENU_LAST, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
** subtest_os(test_list, status, ch)
|
||||
**
|
||||
** test over strike mode (os)
|
||||
*/
|
||||
static void
|
||||
subtest_os(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
ptext("(os) should be true, not false.");
|
||||
put_cr();
|
||||
ptextln("(os) should be false.");
|
||||
sprintf(temp, "(os) over-strike is %s in the data base. ",
|
||||
over_strike ? "true" : "false");
|
||||
ptext(temp);
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_rmam(test_list, status, ch)
|
||||
**
|
||||
** test exit automatic margins mode (rmam)
|
||||
*/
|
||||
static void
|
||||
subtest_rmam(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int j;
|
||||
|
||||
if (!exit_am_mode) {
|
||||
ptext("(rmam) not present. ");
|
||||
} else
|
||||
if (!can_go_home) {
|
||||
ptext("(rmam) not tested, no way to home cursor. ");
|
||||
} else
|
||||
if (over_strike) {
|
||||
put_clear();
|
||||
go_home();
|
||||
tc_putp(exit_am_mode);
|
||||
ptext("\n(rmam) will reset (am)");
|
||||
go_home();
|
||||
for (j = 0; j < columns; j++)
|
||||
put_this(' ');
|
||||
ptext("(rmam) will not reset (am)");
|
||||
go_home();
|
||||
put_newlines(2);
|
||||
} else {
|
||||
put_clear();
|
||||
go_home();
|
||||
tc_putp(exit_am_mode);
|
||||
ptext("\n(rmam) will reset (am)");
|
||||
go_home();
|
||||
for (j = 0; j < columns; j++)
|
||||
put_this(' ');
|
||||
ptext("(rmam) will not reset (am) ");
|
||||
go_home();
|
||||
put_str(" ");
|
||||
go_home();
|
||||
put_newlines(2);
|
||||
}
|
||||
ptext("Exit-automatic-margins ");
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_smam(test_list, status, ch)
|
||||
**
|
||||
** test enter automatic margins mode (smam)
|
||||
*/
|
||||
static void
|
||||
subtest_smam(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!enter_am_mode) {
|
||||
ptext("(smam) not present. ");
|
||||
} else
|
||||
if (!can_go_home) {
|
||||
ptext("(smam) not tested, no way to home cursor. ");
|
||||
} else
|
||||
if (over_strike) {
|
||||
put_clear();
|
||||
go_home();
|
||||
tc_putp(enter_am_mode);
|
||||
ptext("\n(smam) will ");
|
||||
i = char_count;
|
||||
ptext("not set (am)");
|
||||
go_home();
|
||||
for (j = -i; j < columns; j++)
|
||||
put_this(' ');
|
||||
put_str("@@@");
|
||||
put_newlines(2);
|
||||
} else {
|
||||
put_clear();
|
||||
go_home();
|
||||
tc_putp(enter_am_mode);
|
||||
ptext("\n(smam) will not set (am)");
|
||||
go_home();
|
||||
for (j = 0; j < columns; j++)
|
||||
put_this(' ');
|
||||
ptext("(smam) will set (am) ");
|
||||
go_home();
|
||||
put_str(" ");
|
||||
put_newlines(2);
|
||||
}
|
||||
ptext("Enter-automatic-margins ");
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_am(test_list, status, ch)
|
||||
**
|
||||
** test automatic margins (am)
|
||||
*/
|
||||
static void
|
||||
subtest_am(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!can_go_home) {
|
||||
ptextln("(am) not tested, no way to home cursor. ");
|
||||
} else
|
||||
if (over_strike) {
|
||||
put_clear();
|
||||
go_home();
|
||||
ptext("\n(am) should ");
|
||||
i = char_count;
|
||||
ptext("not be set");
|
||||
go_home();
|
||||
for (j = -i; j < columns; j++)
|
||||
put_this(' ');
|
||||
put_str("@@@");
|
||||
go_home();
|
||||
put_newlines(2);
|
||||
sprintf(temp, "(am) is %s in the data base",
|
||||
auto_right_margin ? "true" : "false");
|
||||
ptextln(temp);
|
||||
} else {
|
||||
put_clear();
|
||||
go_home();
|
||||
ptext("\n(am) should not be set");
|
||||
go_home();
|
||||
for (j = 0; j < columns; j++)
|
||||
put_this(' ');
|
||||
ptext("(am) should be set ");
|
||||
go_home();
|
||||
put_str(" \n\n");
|
||||
sprintf(temp, "(am) is %s in the data base",
|
||||
auto_right_margin ? "true" : "false");
|
||||
ptextln(temp);
|
||||
}
|
||||
ptext("Automatic-right-margin ");
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/* Note: uprint() sends underscore back-space character, and
|
||||
ucprint() sends character back-space underscore. */
|
||||
|
||||
/*
|
||||
** uprint(string)
|
||||
**
|
||||
** underline string for (ul) test
|
||||
*/
|
||||
static void
|
||||
uprint(const char *s)
|
||||
{
|
||||
if (s) {
|
||||
while (*s) {
|
||||
put_str("_\b");
|
||||
putchp(*s++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** ucprint(string)
|
||||
**
|
||||
** underline string for (uc) test
|
||||
*/
|
||||
static void
|
||||
ucprint(const char *s)
|
||||
{
|
||||
if (s) {
|
||||
while (*s) {
|
||||
putchp(*s++);
|
||||
putchp('\b');
|
||||
tc_putp(underline_char);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_ul(test_list, status, ch)
|
||||
**
|
||||
** test transparent underline (ul)
|
||||
*/
|
||||
static void
|
||||
subtest_ul(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (!over_strike) {
|
||||
/* (ul) is used only if (os) is reset */
|
||||
put_crlf();
|
||||
sprintf(temp, "This text should %sbe underlined.",
|
||||
transparent_underline ? "" : "not ");
|
||||
uprint(temp);
|
||||
put_crlf();
|
||||
ptextln("If the above line is not underlined the (ul) should be false.");
|
||||
sprintf(temp, "(ul) Transparent-underline is %s in the data base",
|
||||
transparent_underline ? "true" : "false");
|
||||
ptextln(temp);
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_uc(test_list, status, ch)
|
||||
**
|
||||
** test underline character (uc)
|
||||
*/
|
||||
static void
|
||||
subtest_uc(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (!over_strike) {
|
||||
if (underline_char) {
|
||||
ucprint("This text should be underlined.");
|
||||
put_crlf();
|
||||
ptextln("If the above text is not underlined the (uc) has failed.");
|
||||
ptext("Underline-character ");
|
||||
} else {
|
||||
ptext("(uc) underline-character is not defined. ");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_bw(test_list, status, ch)
|
||||
**
|
||||
** test auto left margin (bw)
|
||||
*/
|
||||
static void
|
||||
subtest_bw(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (over_strike) {
|
||||
/* test (bw) */
|
||||
ptext("\n(bw) should ");
|
||||
i = char_count;
|
||||
ptextln("not be set.");
|
||||
for (j = i; j < columns; j++)
|
||||
put_str("\b");
|
||||
put_str("@@@");
|
||||
put_crlf();
|
||||
sprintf(temp, "(bw) Auto-left-margin is %s in the data base",
|
||||
auto_left_margin ? "true" : "false");
|
||||
ptextln(temp);
|
||||
} else {
|
||||
/* test (bw) */
|
||||
ptextln("(bw) should not be set.");
|
||||
for (i = 12; i < columns; i++)
|
||||
put_str("\b");
|
||||
if (delete_character) {
|
||||
for (i = 0; i < 4; i++)
|
||||
tc_putp(delete_character);
|
||||
} else {
|
||||
put_str(" ");
|
||||
}
|
||||
put_crlf();
|
||||
sprintf(temp, "(bw) Auto-left-margin is %s in the data base",
|
||||
auto_left_margin ? "true" : "false");
|
||||
ptextln(temp);
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_tbc(test_list, status, ch)
|
||||
**
|
||||
** test clear tabs (tbc)
|
||||
*/
|
||||
static void
|
||||
subtest_tbc(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int tabat; /* the tab spacing we end up with */
|
||||
int i;
|
||||
|
||||
if (clear_all_tabs && !set_tab) {
|
||||
ptext("(tbc) Clear-all-tabs is defined but (hts) set-tab is not. ");
|
||||
ptext("Once the tabs are cleared there is no way to set them. ");
|
||||
} else
|
||||
if (clear_all_tabs) {
|
||||
tabat = set_tab ? 8 : init_tabs;
|
||||
tc_putp(clear_all_tabs);
|
||||
ptext("Clear tabs (tbc)");
|
||||
go_home();
|
||||
put_crlf();
|
||||
putchp('\t');
|
||||
putchp('T');
|
||||
go_home();
|
||||
put_newlines(2);
|
||||
for (i = 0; i < columns; i++) {
|
||||
if (i == tabat) {
|
||||
putchp('T');
|
||||
} else {
|
||||
putchp('.');
|
||||
}
|
||||
}
|
||||
go_home();
|
||||
ptext("\n\n\nIf the above two lines have T's in the same column then (tbc) has failed. ");
|
||||
} else {
|
||||
ptext("(tbc) Clear-all-tabs is not defined. ");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_hts(test_list, status, ch)
|
||||
**
|
||||
** (ht) and set tabs with (hts)
|
||||
*/
|
||||
static void
|
||||
subtest_hts(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int tabat; /* the tab spacing we end up with */
|
||||
int i;
|
||||
|
||||
tabat = init_tabs;
|
||||
if (set_tab) {
|
||||
ptext("Tabs set with (hts)");
|
||||
put_crlf();
|
||||
for (i = 1; i < columns; i++) {
|
||||
if (i % 8 == 1) {
|
||||
tc_putp(set_tab);
|
||||
}
|
||||
putchp(' ');
|
||||
}
|
||||
tabat = 8;
|
||||
} else {
|
||||
sprintf(temp, "(hts) Set-tabs not defined. (it) Initial-tabs at %d", init_tabs);
|
||||
ptext(temp);
|
||||
}
|
||||
go_home();
|
||||
put_newlines(2);
|
||||
if (tabat <= 0) {
|
||||
tabat = 8;
|
||||
}
|
||||
for (i = tabat; i < columns; i += tabat) {
|
||||
putchp('\t');
|
||||
putchp('T');
|
||||
}
|
||||
go_home();
|
||||
put_newlines(3);
|
||||
for (i = 1; i < columns; i++) {
|
||||
putchp('.');
|
||||
}
|
||||
go_home();
|
||||
put_newlines(3);
|
||||
for (i = tabat; i < columns; i += tabat) {
|
||||
putchp('\t');
|
||||
putchp('T');
|
||||
}
|
||||
go_home();
|
||||
put_newlines(4);
|
||||
putchp('.');
|
||||
for (i = 2; i < columns; i++) {
|
||||
if (i % tabat == 1) {
|
||||
putchp('T');
|
||||
} else {
|
||||
putchp('.');
|
||||
}
|
||||
}
|
||||
go_home();
|
||||
put_newlines(5);
|
||||
if (set_tab) {
|
||||
ptextln("If the last two lines are not the same then (hts) has failed.");
|
||||
} else
|
||||
if (init_tabs > 0) {
|
||||
ptextln("If the last two lines are not the same then (it) is wrong.");
|
||||
} else {
|
||||
ptextln("If the last two lines are the same then maybe you do have tabs and (it) should be changed.");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_xt(test_list, status, ch)
|
||||
**
|
||||
** (xt) glitch
|
||||
*/
|
||||
static void
|
||||
subtest_xt(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int tabat; /* the tab spacing we end up with */
|
||||
int cc;
|
||||
|
||||
tabat = set_tab ? 8 : init_tabs;
|
||||
if (!over_strike && (tabat > 0)) {
|
||||
ptext("(xt) should not ");
|
||||
put_cr();
|
||||
ptext("(xt) should");
|
||||
cc = char_count;
|
||||
while (cc < 16) {
|
||||
putchp('\t');
|
||||
cc = ((cc / tabat) + 1) * tabat;
|
||||
}
|
||||
putln("be set.");
|
||||
sprintf(temp, "(xt) Destructive-tab is %s in the data base.",
|
||||
dest_tabs_magic_smso ? "true" : "false");
|
||||
ptextln(temp);
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_cbt(test_list, status, ch)
|
||||
**
|
||||
** (cbt) back tab
|
||||
*/
|
||||
static void
|
||||
subtest_cbt(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (back_tab) {
|
||||
put_clear();
|
||||
ptext("Back-tab (cbt)");
|
||||
go_home();
|
||||
put_crlf();
|
||||
for (i = 1; i < columns; i++) {
|
||||
putchp(' ');
|
||||
}
|
||||
for (i = 0; i < columns; i += 8) {
|
||||
tc_putp(back_tab);
|
||||
putchp('T');
|
||||
tc_putp(back_tab);
|
||||
}
|
||||
go_home();
|
||||
put_newlines(2);
|
||||
for (i = 1; i < columns; i++) {
|
||||
if (i % 8 == 1) {
|
||||
putchp('T');
|
||||
} else {
|
||||
putchp(' ');
|
||||
}
|
||||
}
|
||||
go_home();
|
||||
put_newlines(3);
|
||||
ptextln("The preceding two lines should be the same.");
|
||||
} else {
|
||||
ptextln("(cbt) Back-tab not present");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_xenl(test_list, status, ch)
|
||||
**
|
||||
** (xenl) eat newline glitch
|
||||
*/
|
||||
static void
|
||||
subtest_xenl(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
if (over_strike) {
|
||||
/* test (xenl) on overstrike terminals */
|
||||
if (!can_go_home || !can_clear_screen) {
|
||||
ptextln("(xenl) Newline-glitch not tested, can't home cursor and clear.");
|
||||
generic_done_message(t, state, ch);
|
||||
return;
|
||||
}
|
||||
put_clear();
|
||||
/*
|
||||
this test must be done in raw mode. Otherwise UNIX will
|
||||
translate CR to CRLF.
|
||||
*/
|
||||
if (stty_query(TTY_OUT_TRANS))
|
||||
tty_raw(1, char_mask);
|
||||
ptext("\nreset (xenl). Does ");
|
||||
i = char_count;
|
||||
put_str("not ignore CR, does ");
|
||||
k = char_count;
|
||||
put_str("not ignore LF");
|
||||
go_home();
|
||||
for (j = 0; j < columns; j++)
|
||||
put_this(' ');
|
||||
put_cr();
|
||||
for (j = 0; j < i; j++)
|
||||
putchp(' ');
|
||||
put_str("@@@\n@@");
|
||||
go_home();
|
||||
for (j = 0; j < columns; j++)
|
||||
put_this(' ');
|
||||
put_lf();
|
||||
for (j = 0; j < k; j++)
|
||||
putchp(' ');
|
||||
put_str("@@@\r@@");
|
||||
tty_set();
|
||||
go_home();
|
||||
put_newlines(4);
|
||||
sprintf(temp, "(xenl) Newline-glitch is %s in the data base",
|
||||
eat_newline_glitch ? "true" : "false");
|
||||
ptextln(temp);
|
||||
} else {
|
||||
/* test (xenl) when (os) is reset */
|
||||
if (!can_go_home) {
|
||||
ptextln("(xenl) Newline-glitch not tested, can't home cursor");
|
||||
generic_done_message(t, state, ch);
|
||||
return;
|
||||
}
|
||||
/* (xenl) test */
|
||||
put_clear();
|
||||
/*
|
||||
this test must be done in raw mode. Otherwise
|
||||
UNIX will translate CR to CRLF.
|
||||
*/
|
||||
if (stty_query(TTY_OUT_TRANS))
|
||||
tty_raw(1, char_mask);
|
||||
for (j = 0; j < columns; j++)
|
||||
put_this(' ');
|
||||
put_cr();
|
||||
ptext("(xenl) should be set. Does not ignore CR");
|
||||
go_home();
|
||||
put_crlf();
|
||||
for (j = 0; j < columns; j++)
|
||||
put_this(' ');
|
||||
put_lf(); /* test (cud1) */
|
||||
ptext("(xenl) should be set. Ignores (cud1)");
|
||||
go_home();
|
||||
put_newlines(3);
|
||||
if (scroll_forward && cursor_down &&
|
||||
strcmp(scroll_forward, cursor_down)) {
|
||||
for (j = 0; j < columns; j++)
|
||||
put_this(' ');
|
||||
put_ind(); /* test (ind) */
|
||||
ptext("(xenl) should be set. Ignores (ind)");
|
||||
go_home();
|
||||
put_newlines(5);
|
||||
}
|
||||
tty_set();
|
||||
ptextln("If you don't see text above telling you to set it, (xenl) should be false");
|
||||
sprintf(temp, "(xenl) Newline-glitch is %s in the data base",
|
||||
eat_newline_glitch ? "true" : "false");
|
||||
ptextln(temp);
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_eo(test_list, status, ch)
|
||||
**
|
||||
** (eo) erase overstrike
|
||||
*/
|
||||
static void
|
||||
subtest_eo(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (transparent_underline || over_strike || underline_char) {
|
||||
ptext("(eo) should ");
|
||||
if (underline_char) {
|
||||
ucprint("not");
|
||||
} else {
|
||||
uprint("not");
|
||||
}
|
||||
put_cr();
|
||||
ptextln("(eo) should be set");
|
||||
sprintf(temp, "\n(eo) Erase-overstrike is %s in the data base",
|
||||
erase_overstrike ? "true" : "false");
|
||||
ptextln(temp);
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_xmc(test_list, status, ch)
|
||||
**
|
||||
** (xmc) magic cookie glitch
|
||||
*/
|
||||
static void
|
||||
subtest_xmc(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (enter_standout_mode) {
|
||||
sprintf(temp, "\n(xmc) Magic-cookie-glitch is %d in the data base", magic_cookie_glitch);
|
||||
ptextln(temp);
|
||||
j = magic_cookie_glitch * 8;
|
||||
for (i = 0; i < j; i++) {
|
||||
put_str(" ");
|
||||
}
|
||||
ptextln(" These two lines should line up.");
|
||||
if (j > 0) {
|
||||
char_count += j;
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
put_mode(enter_standout_mode);
|
||||
putchp(' ');
|
||||
put_mode(exit_standout_mode);
|
||||
putchp(' ');
|
||||
}
|
||||
ptextln("These two lines should line up.");
|
||||
ptext("If they don't line up then (xmc) magic-cookie-glitch should be greater than zero. ");
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_xhp(test_list, status, ch)
|
||||
**
|
||||
** (xhp) erase does not clear standout mode
|
||||
*/
|
||||
static void
|
||||
subtest_xhp(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (enter_standout_mode) {
|
||||
put_crlf();
|
||||
put_mode(enter_standout_mode);
|
||||
put_str("Stand out");
|
||||
put_mode(exit_standout_mode);
|
||||
put_cr();
|
||||
ptextln("If any part of this line is standout then (xhp) should be set.");
|
||||
sprintf(temp, "(xhp) Erase-standout-glitch is %s in the data base",
|
||||
ceol_standout_glitch ? "true" : "false");
|
||||
ptextln(temp);
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_mir(test_list, status, ch)
|
||||
**
|
||||
** (mir) move in insert mode
|
||||
*/
|
||||
static void
|
||||
subtest_mir(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i;
|
||||
char *s;
|
||||
|
||||
if (enter_insert_mode && exit_insert_mode && cursor_address) {
|
||||
put_clear();
|
||||
i = line_count;
|
||||
put_str("\nXXX\nXXX\nXXX\nXXX");
|
||||
tc_putp(enter_insert_mode);
|
||||
s = TPARM_2(cursor_address, i + 1, 0);
|
||||
tputs(s, lines, tc_putch);
|
||||
putchp('X');
|
||||
s = TPARM_2(cursor_address, i + 2, 1);
|
||||
tputs(s, lines, tc_putch);
|
||||
putchp('X');
|
||||
s = TPARM_2(cursor_address, i + 3, 2);
|
||||
tputs(s, lines, tc_putch);
|
||||
putchp('X');
|
||||
s = TPARM_2(cursor_address, i + 4, 3);
|
||||
tputs(s, lines, tc_putch);
|
||||
putchp('X');
|
||||
tc_putp(exit_insert_mode);
|
||||
put_newlines(2);
|
||||
ptextln("If you see a 4 by 4 block of X's then (mir) should be true.");
|
||||
sprintf(temp, "(mir) Move-in-insert-mode is %s in the data base",
|
||||
move_insert_mode ? "true" : "false");
|
||||
ptextln(temp);
|
||||
} else {
|
||||
ptext("(mir) Move-in-insert-mode not tested, ");
|
||||
if (!enter_insert_mode) {
|
||||
ptext("(smir) ");
|
||||
}
|
||||
if (!exit_insert_mode) {
|
||||
ptext("(rmir) ");
|
||||
}
|
||||
if (!cursor_address) {
|
||||
ptext("(cup) ");
|
||||
}
|
||||
ptext("not present. ");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_msgr(test_list, status, ch)
|
||||
**
|
||||
** (msgr) move in sgr mode
|
||||
*/
|
||||
static void
|
||||
subtest_msgr(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cursor_address &&
|
||||
((enter_standout_mode && exit_standout_mode) ||
|
||||
(enter_alt_charset_mode && exit_alt_charset_mode))) {
|
||||
put_crlf();
|
||||
i = line_count + 1;
|
||||
tputs(TPARM_2(cursor_address, i, 0), lines, tc_putch);
|
||||
put_mode(enter_alt_charset_mode);
|
||||
put_crlf();
|
||||
/*
|
||||
some versions of the wy-120 can not clear lines or
|
||||
screen when in alt charset mode. If (el) and (ed)
|
||||
are defined then I can test them. If they are not
|
||||
defined then they can not break (msgr)
|
||||
*/
|
||||
tc_putp(clr_eos);
|
||||
tc_putp(clr_eol);
|
||||
put_mode(exit_alt_charset_mode);
|
||||
put_mode(enter_standout_mode);
|
||||
putchp('X');
|
||||
tputs(TPARM_2(cursor_address, i + 2, 1), lines, tc_putch);
|
||||
putchp('X');
|
||||
tputs(TPARM_2(cursor_address, i + 3, 2), lines, tc_putch);
|
||||
putchp('X');
|
||||
tputs(TPARM_2(cursor_address, i + 4, 3), lines, tc_putch);
|
||||
putchp('X');
|
||||
put_mode(exit_standout_mode);
|
||||
put_crlf();
|
||||
tc_putp(clr_eos); /* OK if missing */
|
||||
put_crlf();
|
||||
ptextln("If you see a diagonal line of standout X's then (msgr) should be true. If any of the blanks are standout then (msgr) should be false.");
|
||||
sprintf(temp, "(msgr) Move-in-SGR-mode is %s in the data base",
|
||||
move_standout_mode ? "true" : "false");
|
||||
ptextln(temp);
|
||||
} else {
|
||||
ptextln("(smso) (rmso) (smacs) (rmacs) missing; (msgr) Move-in-SGR-mode not tested.");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_in(test_list, status, ch)
|
||||
**
|
||||
** (in) insert null glitch
|
||||
*/
|
||||
static void
|
||||
subtest_in(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (enter_insert_mode && exit_insert_mode) {
|
||||
ptextln("\nTesting (in) with (smir) and (rmir)");
|
||||
putln("\tIf these two lines line up ...");
|
||||
put_str("\tIf these two lines line up ...");
|
||||
put_cr();
|
||||
tc_putp(enter_insert_mode);
|
||||
putchp(' ');
|
||||
tc_putp(exit_insert_mode);
|
||||
ptext("\nthen (in) should be set. ");
|
||||
sprintf(temp,
|
||||
"(in) Insert-null-glitch is %s in the data base.",
|
||||
insert_null_glitch ? "true" : "false");
|
||||
ptextln(temp);
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** subtest_dadb(test_list, status, ch)
|
||||
**
|
||||
** (da) (db) data above, (db) data below
|
||||
*/
|
||||
static void
|
||||
subtest_dadb(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
if (can_clear_screen && scroll_reverse && scroll_forward) {
|
||||
put_clear();
|
||||
if (scroll_reverse)
|
||||
ptext("(da) Data-above should be set\r");
|
||||
home_down();
|
||||
if (scroll_forward)
|
||||
ptext("(db) Data-below should be set\r");
|
||||
tc_putp(scroll_forward);
|
||||
go_home();
|
||||
tc_putp(scroll_reverse);
|
||||
tc_putp(scroll_reverse);
|
||||
home_down();
|
||||
tc_putp(scroll_forward);
|
||||
go_home();
|
||||
ptextln("\n\n\n\n\nIf the top line is blank then (da) should be false.");
|
||||
ptextln("If the bottom line is blank then (db) should be false.");
|
||||
sprintf(temp, "\n(da) Data-above is %s, and (db) Data-below is %s, in the data base.",
|
||||
memory_above ? "true" : "false",
|
||||
memory_below ? "true" : "false");
|
||||
ptextln(temp);
|
||||
line_count = lines;
|
||||
} else {
|
||||
ptextln("(da) Data-above, (db) Data-below not tested, scrolls or (clear) is missing.");
|
||||
}
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
##############################################################################
|
||||
# Copyright (c) 1998-1999,2006 Free Software Foundation, Inc. #
|
||||
# #
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a #
|
||||
# copy of this software and associated documentation files (the "Software"), #
|
||||
# to deal in the Software without restriction, including without limitation #
|
||||
# the rights to use, copy, modify, merge, publish, distribute, distribute #
|
||||
# with modifications, sublicense, and/or sell copies of the Software, and to #
|
||||
# permit persons to whom the Software is furnished to do so, subject to the #
|
||||
# following conditions: #
|
||||
# #
|
||||
# The above copyright notice and this permission notice shall be included in #
|
||||
# all copies or substantial portions of the Software. #
|
||||
# #
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL #
|
||||
# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER #
|
||||
# DEALINGS IN THE SOFTWARE. #
|
||||
# #
|
||||
# Except as contained in this notice, the name(s) of the above copyright #
|
||||
# holders shall not be used in advertising or otherwise to promote the sale, #
|
||||
# use or other dealings in this Software without prior written #
|
||||
# authorization. #
|
||||
##############################################################################
|
||||
# $Id: modules,v 1.5 2006/04/22 22:37:18 tom Exp $
|
||||
@ base
|
||||
ansi progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
||||
charset progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
||||
color progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
||||
control progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
||||
crum progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
||||
edit progs $(srcdir) $(srcdir)/tack.h ../include/term.h $(INCDIR)/tic.h
|
||||
fun progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
||||
init progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
||||
menu progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
||||
modes progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
||||
output progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
||||
pad progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
||||
scan progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
||||
sync progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
||||
sysdep progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
||||
tack progs $(srcdir) $(srcdir)/tack.h ../include/term.h
|
@ -1,818 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
/* screen formatting and I/O utility functions */
|
||||
|
||||
#include <tack.h>
|
||||
#include <time.h>
|
||||
|
||||
MODULE_ID("$Id: output.c,v 1.11 2006/11/26 00:16:49 tom Exp $")
|
||||
|
||||
/* globals */
|
||||
long char_sent; /* number of characters sent */
|
||||
int char_count; /* counts characters */
|
||||
int line_count; /* counts line feeds */
|
||||
int expand_chars; /* length of expand() string */
|
||||
int replace_mode; /* used to output replace mode padding */
|
||||
int can_go_home; /* TRUE if we can fashion a home command */
|
||||
int can_clear_screen; /* TRUE if we can somehow clear the screen */
|
||||
int raw_characters_sent; /* Total output characters */
|
||||
static int log_count; /* Number of characters on a log line */
|
||||
|
||||
/* translate mode default strings */
|
||||
#define TM_carriage_return TM_string[0].value
|
||||
#define TM_cursor_down TM_string[1].value
|
||||
#define TM_scroll_forward TM_string[2].value
|
||||
#define TM_newline TM_string[3].value
|
||||
#define TM_cursor_left TM_string[4].value
|
||||
#define TM_bell TM_string[5].value
|
||||
#define TM_form_feed TM_string[6].value
|
||||
#define TM_tab TM_string[7].value
|
||||
|
||||
struct default_string_list TM_string[TM_last] = {
|
||||
{"cr", "\r", 0},
|
||||
{"cud1", "\n", 0},
|
||||
{"ind", "\n", 0},
|
||||
{"nel", "\r\n", 0},
|
||||
{"cub1", "\b", 0},
|
||||
{"bel", "\007", 0},
|
||||
{"ff", "\f", 0},
|
||||
{"ht", "\t", 0}
|
||||
};
|
||||
|
||||
static const char *c0[32] = {
|
||||
"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK",
|
||||
"BEL", "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
|
||||
"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
|
||||
"CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
|
||||
};
|
||||
|
||||
static const char *c1[32] = {
|
||||
"", "", "", "", "IND", "NEL", "SSA", "ESA",
|
||||
"HTS", "HTJ", "VTS", "PLD", "PLU", "RI", "SS2", "SS3",
|
||||
"DCS", "PU1", "PU2", "STS", "CCH", "MW", "SPA", "EPA",
|
||||
"", "", "", "CSI", "ST", "OSC", "PM", "APC"
|
||||
};
|
||||
|
||||
int
|
||||
getnext(int mask)
|
||||
{ /* get the next character without scan mode
|
||||
conversion */
|
||||
int ch;
|
||||
unsigned char buf;
|
||||
|
||||
tc_putp(req_for_input);
|
||||
fflush(stdout);
|
||||
if (nodelay_read)
|
||||
while (1) {
|
||||
ch = read(fileno(stdin), &buf, 1);
|
||||
if (ch == -1)
|
||||
return EOF;
|
||||
if (ch == 1)
|
||||
return buf;
|
||||
}
|
||||
ch = getchar();
|
||||
if (ch == EOF)
|
||||
return EOF;
|
||||
return ch & mask;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
getchp(int mask)
|
||||
{ /* read a character with scan mode conversion */
|
||||
if (scan_mode) {
|
||||
tc_putp(req_for_input);
|
||||
fflush(stdout);
|
||||
return scan_key();
|
||||
} else
|
||||
return getnext(mask);
|
||||
}
|
||||
|
||||
/*
|
||||
** tc_putch(c)
|
||||
**
|
||||
** Output one character
|
||||
*/
|
||||
int
|
||||
tc_putch(int c)
|
||||
{
|
||||
char_sent++;
|
||||
raw_characters_sent++;
|
||||
putchar(c);
|
||||
if ((raw_characters_sent & 31) == 31) {
|
||||
fflush(stdout);
|
||||
}
|
||||
if (log_fp) {
|
||||
/* terminal output logging */
|
||||
c = UChar(c);
|
||||
if (c < 32) {
|
||||
fprintf(log_fp, "<%s>", c0[c]);
|
||||
log_count += 5;
|
||||
} else
|
||||
if (c < 127) {
|
||||
fprintf(log_fp, "%c", c);
|
||||
log_count += 1;
|
||||
} else {
|
||||
fprintf(log_fp, "<%02x>", c);
|
||||
log_count += 4;
|
||||
}
|
||||
if (c == '\n' || log_count >= 80) {
|
||||
fprintf(log_fp, "\n");
|
||||
log_count = 0;
|
||||
}
|
||||
}
|
||||
return (c);
|
||||
}
|
||||
|
||||
/*
|
||||
** tt_tputs(string, reps)
|
||||
**
|
||||
** Output a string with tputs() translation.
|
||||
** Use this function inside timing tests.
|
||||
*/
|
||||
void
|
||||
tt_tputs(const char *string, int reps)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (string) {
|
||||
for (i = 0; i < TT_MAX; i++) {
|
||||
if (i >= ttp) {
|
||||
tt_cap[i] = string;
|
||||
tt_affected[i] = reps;
|
||||
tt_count[i] = 1;
|
||||
tt_delay[i] = msec_cost(string, reps);
|
||||
ttp++;
|
||||
break;
|
||||
}
|
||||
if (string == tt_cap[i] && reps == tt_affected[i]) {
|
||||
tt_count[i]++;
|
||||
tt_delay_used += tt_delay[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
(void) tputs(string, reps, tc_putch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** tt_putp(string)
|
||||
**
|
||||
** Output a string with tputs() translation.
|
||||
** Use this function inside timing tests.
|
||||
*/
|
||||
void
|
||||
tt_putp(const char *string)
|
||||
{
|
||||
tt_tputs(string, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
** tt_putparm(string, reps, arg1, arg2)
|
||||
**
|
||||
** Send tt_tputs(tparm(string, args1, arg2), reps)
|
||||
** Use this function inside timing tests.
|
||||
*/
|
||||
void
|
||||
tt_putparm(
|
||||
NCURSES_CONST char *string,
|
||||
int reps,
|
||||
int arg1,
|
||||
int arg2)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (string) {
|
||||
for (i = 0; i < TT_MAX; i++) {
|
||||
if (i >= ttp) {
|
||||
tt_cap[i] = string;
|
||||
tt_affected[i] = reps;
|
||||
tt_count[i] = 1;
|
||||
tt_delay[i] = msec_cost(string, reps);
|
||||
ttp++;
|
||||
break;
|
||||
}
|
||||
if (string == tt_cap[i] && reps == tt_affected[i]) {
|
||||
tt_count[i]++;
|
||||
tt_delay_used += tt_delay[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
(void) tputs(TPARM_2((NCURSES_CONST char *)string, arg1, arg2), reps, tc_putch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** tc_putp(string)
|
||||
**
|
||||
** Output a string with tputs() translation.
|
||||
** Use this function instead of putp() so we can track
|
||||
** the actual number of characters sent.
|
||||
*/
|
||||
int
|
||||
tc_putp(const char *string)
|
||||
{
|
||||
return tputs(string, 1, tc_putch);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
put_this(int c)
|
||||
{ /* output one character (with padding) */
|
||||
tc_putch(c);
|
||||
if (char_padding && replace_mode)
|
||||
tt_putp(char_padding);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
put_cr(void)
|
||||
{
|
||||
if (translate_mode && carriage_return) {
|
||||
tt_putp(carriage_return);
|
||||
} else {
|
||||
tt_putp(TM_carriage_return);
|
||||
}
|
||||
char_count = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
put_lf(void)
|
||||
{ /* send a linefeed (only works in RAW or
|
||||
CBREAK mode) */
|
||||
if (translate_mode && cursor_down) {
|
||||
tt_putp(cursor_down);
|
||||
} else {
|
||||
tt_putp(TM_cursor_down);
|
||||
}
|
||||
line_count++;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
put_ind(void)
|
||||
{ /* scroll forward (only works in RAW or
|
||||
CBREAK mode) */
|
||||
if (translate_mode && scroll_forward) {
|
||||
tt_putp(scroll_forward);
|
||||
} else {
|
||||
tt_putp(TM_scroll_forward);
|
||||
}
|
||||
line_count++;
|
||||
}
|
||||
|
||||
/*
|
||||
** put_crlf()
|
||||
**
|
||||
** Send (nel) or <cr> <lf>
|
||||
*/
|
||||
void
|
||||
put_crlf(void)
|
||||
{
|
||||
if (translate_mode && newline) {
|
||||
tt_putp(newline);
|
||||
} else {
|
||||
tt_putp(TM_newline);
|
||||
}
|
||||
char_count = 0;
|
||||
line_count++;
|
||||
}
|
||||
|
||||
/*
|
||||
** put_new_lines(count)
|
||||
**
|
||||
** Send a number of newlines. (nel)
|
||||
*/
|
||||
void
|
||||
put_newlines(int n)
|
||||
{
|
||||
while (n-- > 0) {
|
||||
put_crlf();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** putchp(character)
|
||||
**
|
||||
** Send one character to the terminal.
|
||||
** This function does translation of control characters.
|
||||
*/
|
||||
void
|
||||
putchp(int c)
|
||||
{
|
||||
switch (c) {
|
||||
case '\b':
|
||||
if (translate_mode && cursor_left) {
|
||||
tt_putp(cursor_left);
|
||||
} else {
|
||||
tt_putp(TM_cursor_left);
|
||||
}
|
||||
char_count--;
|
||||
break;
|
||||
case 7:
|
||||
if (translate_mode && bell) {
|
||||
tt_putp(bell);
|
||||
} else {
|
||||
tt_putp(TM_bell);
|
||||
}
|
||||
break;
|
||||
case '\f':
|
||||
if (translate_mode && form_feed) {
|
||||
tt_putp(form_feed);
|
||||
} else {
|
||||
tt_putp(TM_form_feed);
|
||||
}
|
||||
char_count = 0;
|
||||
line_count++;
|
||||
break;
|
||||
case '\n':
|
||||
put_crlf();
|
||||
break;
|
||||
case '\r':
|
||||
put_cr();
|
||||
break;
|
||||
case '\t':
|
||||
if (translate_mode && tab) {
|
||||
tt_putp(tab);
|
||||
} else {
|
||||
tt_putp(TM_tab);
|
||||
}
|
||||
char_count = ((char_count / 8) + 1) * 8;
|
||||
break;
|
||||
default:
|
||||
put_this(c);
|
||||
char_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
put_str(const char *s)
|
||||
{ /* send the string to the terminal */
|
||||
for (; *s; putchp(*s++));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
putln(const char *s)
|
||||
{ /* output a string followed by a CR LF */
|
||||
for (; *s; putchp(*s++));
|
||||
put_crlf();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
put_columns(const char *s, int len, int w)
|
||||
{ /* put out s in column format */
|
||||
int l;
|
||||
|
||||
if (char_count + w > columns) {
|
||||
put_crlf();
|
||||
}
|
||||
l = char_count % w;
|
||||
if (l) {
|
||||
while (l < w) {
|
||||
putchp(' ');
|
||||
l++;
|
||||
}
|
||||
}
|
||||
if (char_count && char_count + len >= columns) {
|
||||
put_crlf();
|
||||
}
|
||||
l = char_count;
|
||||
put_str(s);
|
||||
char_count = l + len;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** ptext(string)
|
||||
**
|
||||
** Output a string but do not assume the terminal will wrap to a
|
||||
** new line. Break the line at a word boundary then send a CR LF.
|
||||
** This is more esthetic on 40 column terminals.
|
||||
*/
|
||||
void
|
||||
ptext(const char *s)
|
||||
{
|
||||
const char *t;
|
||||
|
||||
while (*s) {
|
||||
for (t = s + 1; *t > ' '; t++);
|
||||
if ((char_count != 0) && ((t - s) + char_count >= columns)) {
|
||||
put_crlf();
|
||||
while (*s == ' ')
|
||||
s++;
|
||||
}
|
||||
while (s < t) {
|
||||
putchp(*s++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
put_dec(char *f, int i)
|
||||
{ /* print a line with a decimal number in it */
|
||||
char tm[128];
|
||||
|
||||
sprintf(tm, f, i / 10, i % 10);
|
||||
ptext(tm);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
three_digit(char *tx, int i)
|
||||
{ /* convert the decimal number to a string of
|
||||
at least 3 digits */
|
||||
if (i < 1000)
|
||||
sprintf(tx, "%d.%d", i / 10, i % 10);
|
||||
else
|
||||
sprintf(tx, "%d", i / 10);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ptextln(const char *s)
|
||||
{ /* print the text using ptext() then add a CR
|
||||
LF */
|
||||
ptext(s);
|
||||
put_crlf();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
expand_one(int ch, char **v)
|
||||
{ /* expand one character */
|
||||
char *t = *v;
|
||||
|
||||
if (ch & 0x80) { /* dump it in octal (yuck) */
|
||||
*t++ = '\\';
|
||||
*t++ = '0' + ((ch >> 6) & 3);
|
||||
*t++ = '0' + ((ch >> 3) & 7);
|
||||
*t++ = '0' + (ch & 7);
|
||||
expand_chars += 4;
|
||||
} else if (ch == 127) { /* DEL */
|
||||
*t++ = '^';
|
||||
*t++ = '?';
|
||||
expand_chars += 2;
|
||||
} else if (ch >= ' ') {
|
||||
*t++ = ch;
|
||||
expand_chars++;
|
||||
} else { /* control characters */
|
||||
*t++ = '^';
|
||||
*t++ = ch + '@';
|
||||
expand_chars += 2;
|
||||
}
|
||||
*v = t;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
expand(const char *s)
|
||||
{ /* convert the string to printable form */
|
||||
static char buf[4096];
|
||||
char *t, *v;
|
||||
int ch;
|
||||
|
||||
if (magic_cookie_glitch <= 0 && exit_attribute_mode) {
|
||||
v = enter_reverse_mode;
|
||||
} else {
|
||||
v = NULL;
|
||||
}
|
||||
expand_chars = 0;
|
||||
t = buf;
|
||||
if (s) {
|
||||
for (; (ch = *s); s++) {
|
||||
if ((ch & 0x80) && v) { /* print it in reverse video
|
||||
mode */
|
||||
strcpy(t, liberated(TPARM_0(v)));
|
||||
for (; *t; t++);
|
||||
expand_one(ch & 0x7f, &t);
|
||||
strcpy(t, liberated(TPARM_0(exit_attribute_mode)));
|
||||
for (; *t; t++);
|
||||
} else {
|
||||
expand_one(ch, &t);
|
||||
}
|
||||
}
|
||||
}
|
||||
*t = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
print_expand(char *s)
|
||||
{ /* convert the string to 7-bit printable form */
|
||||
static char buf[4096];
|
||||
char *t;
|
||||
int ch;
|
||||
|
||||
expand_chars = 0;
|
||||
t = buf;
|
||||
if (s) {
|
||||
for (; (ch = *s); s++) {
|
||||
expand_one(ch, &t);
|
||||
}
|
||||
}
|
||||
*t = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
expand_to(char *s, int l)
|
||||
{ /* expand s to length l */
|
||||
char *t;
|
||||
|
||||
for (s = t = expand(s); *t; t++);
|
||||
for (; expand_chars < l; expand_chars++) {
|
||||
*t++ = ' ';
|
||||
}
|
||||
*t = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
hex_expand_to(char *s, int l)
|
||||
{ /* expand s to length l in hex */
|
||||
static char buf[4096];
|
||||
char *t;
|
||||
|
||||
for (t = buf; *s; s++) {
|
||||
sprintf(t, "%02X ", UChar(*s));
|
||||
t += 3;
|
||||
if (t - buf > (int) sizeof(buf) - 4) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (; t - buf < l;) {
|
||||
*t++ = ' ';
|
||||
}
|
||||
*t = '\0';
|
||||
expand_chars = t - buf;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
expand_command(const char *c)
|
||||
{ /* expand an ANSI escape sequence */
|
||||
static char buf[256];
|
||||
int i, j, ch;
|
||||
char *s;
|
||||
|
||||
s = buf;
|
||||
for (i = FALSE; (ch = UChar(*c)) != 0; c++) {
|
||||
if (i) {
|
||||
*s++ = ' ';
|
||||
}
|
||||
i = TRUE;
|
||||
if (ch < 32) {
|
||||
j = UChar(c[1]);
|
||||
if (ch == '\033' && j >= '@' && j <= '_') {
|
||||
ch = j - '@';
|
||||
c++;
|
||||
for (j = 0; (*s = c1[ch][j++]); s++);
|
||||
} else
|
||||
for (j = 0; (*s = c0[ch][j++]); s++);
|
||||
} else {
|
||||
*s++ = ch;
|
||||
j = UChar(c[1]);
|
||||
if (ch >= '0' && ch <= '9' &&
|
||||
j >= '0' && j <= '9') {
|
||||
i = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
*s = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
** go_home()
|
||||
**
|
||||
** Move the cursor to the home position
|
||||
*/
|
||||
void
|
||||
go_home(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cursor_home)
|
||||
tt_putp(cursor_home);
|
||||
else if (cursor_address)
|
||||
tt_putparm(cursor_address, lines, 0, 0);
|
||||
else if (row_address) { /* use (vpa) */
|
||||
put_cr();
|
||||
tt_putparm(row_address, 1, 0, 0);
|
||||
} else if (cursor_up && cursor_to_ll) {
|
||||
tt_putp(cursor_to_ll);
|
||||
for (i = 1; i < lines; i++) {
|
||||
tt_putp(cursor_up);
|
||||
}
|
||||
} else {
|
||||
can_go_home = FALSE;
|
||||
return;
|
||||
}
|
||||
char_count = line_count = 0;
|
||||
can_go_home = TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
home_down(void)
|
||||
{ /* move the cursor to the lower left hand
|
||||
corner */
|
||||
int i;
|
||||
|
||||
if (cursor_to_ll)
|
||||
tt_putp(cursor_to_ll);
|
||||
else if (cursor_address)
|
||||
tt_putparm(cursor_address, lines, lines - 1, 0);
|
||||
else if (row_address) { /* use (vpa) */
|
||||
put_cr();
|
||||
tt_putparm(row_address, 1, lines - 1, 0);
|
||||
} else if (cursor_down && cursor_home) {
|
||||
tt_putp(cursor_home);
|
||||
for (i = 1; i < lines; i++)
|
||||
tt_putp(cursor_down);
|
||||
} else
|
||||
return;
|
||||
char_count = 0;
|
||||
line_count = lines - 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
put_clear(void)
|
||||
{ /* clear the screen */
|
||||
int i;
|
||||
|
||||
if (clear_screen)
|
||||
tt_tputs(clear_screen, lines);
|
||||
else if (clr_eos && can_go_home) {
|
||||
go_home();
|
||||
tt_tputs(clr_eos, lines);
|
||||
} else if (scroll_forward && !over_strike && (can_go_home || cursor_up)) {
|
||||
/* clear the screen by scrolling */
|
||||
put_cr();
|
||||
if (cursor_to_ll) {
|
||||
tt_putp(cursor_to_ll);
|
||||
} else if (cursor_address) {
|
||||
tt_putparm(cursor_address, lines, lines - 1, 0);
|
||||
} else if (row_address) {
|
||||
tt_putparm(row_address, 1, lines - 1, 0);
|
||||
} else {
|
||||
for (i = 1; i < lines; i++) {
|
||||
tt_putp(scroll_forward);
|
||||
}
|
||||
}
|
||||
for (i = 1; i < lines; i++) {
|
||||
tt_putp(scroll_forward);
|
||||
}
|
||||
if (can_go_home) {
|
||||
go_home();
|
||||
} else {
|
||||
for (i = 1; i < lines; i++) {
|
||||
tt_putp(cursor_up);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
can_clear_screen = FALSE;
|
||||
return;
|
||||
}
|
||||
char_count = line_count = 0;
|
||||
can_clear_screen = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
** wait_here()
|
||||
**
|
||||
** read one character from the input stream
|
||||
** If the terminal is not in RAW mode then this function will
|
||||
** wait for a <cr> or <lf>.
|
||||
*/
|
||||
int
|
||||
wait_here(void)
|
||||
{
|
||||
char ch, cc[64];
|
||||
char message[16];
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < (int) sizeof(cc); i++) {
|
||||
cc[i] = ch = getchp(STRIP_PARITY);
|
||||
if (ch == '\r' || ch == '\n') {
|
||||
put_crlf();
|
||||
char_sent = 0;
|
||||
return cc[i ? i - 1 : 0];
|
||||
}
|
||||
if (ch >= ' ') {
|
||||
if (stty_query(TTY_CHAR_MODE)) {
|
||||
put_crlf();
|
||||
char_sent = 0;
|
||||
return ch;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (ch == 023) { /* Control S */
|
||||
/* ignore control S, but tell me about it */
|
||||
while (ch == 023 || ch == 021) {
|
||||
ch = getchp(STRIP_PARITY);
|
||||
if (i < (int) sizeof(cc))
|
||||
cc[++i] = ch;
|
||||
}
|
||||
put_str("\nThe terminal sent a ^S -");
|
||||
for (j = 0; j <= i; j++) {
|
||||
sprintf(message, " %02X", cc[j] & 0xFF);
|
||||
put_str(message);
|
||||
}
|
||||
put_crlf();
|
||||
i = -1;
|
||||
} else if (ch != 021) { /* Not Control Q */
|
||||
/* could be abort character */
|
||||
spin_flush();
|
||||
if (tty_can_sync == SYNC_TESTED) {
|
||||
(void) tty_sync_error();
|
||||
} else {
|
||||
put_str("\n? ");
|
||||
}
|
||||
}
|
||||
}
|
||||
return '?';
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** read_string(buffer, length)
|
||||
**
|
||||
** Read a string of characters from the input stream.
|
||||
*/
|
||||
void
|
||||
read_string(
|
||||
char *buf,
|
||||
int length)
|
||||
{
|
||||
int ch, i;
|
||||
|
||||
for (i = 0; i < length - 1; ) {
|
||||
ch = getchp(STRIP_PARITY);
|
||||
if (ch == '\r' || ch == '\n') {
|
||||
break;
|
||||
}
|
||||
if (ch == '\b' || ch == 127) {
|
||||
if (i) {
|
||||
putchp('\b');
|
||||
putchp(' ');
|
||||
putchp('\b');
|
||||
i--;
|
||||
}
|
||||
} else {
|
||||
buf[i++] = ch;
|
||||
putchp(ch);
|
||||
}
|
||||
}
|
||||
buf[i] = '\0';
|
||||
put_crlf();
|
||||
char_sent = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** maybe_wait(lines)
|
||||
**
|
||||
** wait if near the end of the screen, then clear screen
|
||||
*/
|
||||
void
|
||||
maybe_wait(int n)
|
||||
{
|
||||
if (line_count + n >= lines) {
|
||||
if (char_sent != 0) {
|
||||
ptext("Go? ");
|
||||
(void) wait_here();
|
||||
}
|
||||
put_clear();
|
||||
} else {
|
||||
put_crlf();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,264 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
/* scan mode keyboard support */
|
||||
|
||||
#include <tack.h>
|
||||
|
||||
MODULE_ID("$Id: scan.c,v 1.5 2005/09/17 19:49:16 tom Exp $")
|
||||
|
||||
unsigned scan_max; /* length of longest scan code */
|
||||
char **scan_up, **scan_down, **scan_name;
|
||||
unsigned *scan_tested, *scan_length;
|
||||
static unsigned *scan_value;
|
||||
|
||||
static int shift_state;
|
||||
static char *str;
|
||||
static int debug_char_count;
|
||||
|
||||
#define SHIFT_KEY 0x100
|
||||
#define CONTROL_KEY 0x200
|
||||
#define META_KEY 0x400
|
||||
#define CAPS_LOCK 0x800
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
unsigned type;
|
||||
} scan_special[] = {
|
||||
{"<shift>", SHIFT_KEY},
|
||||
{"<left shift>", SHIFT_KEY},
|
||||
{"<right shift>", SHIFT_KEY},
|
||||
{"<control>", CONTROL_KEY},
|
||||
{"<left control>", CONTROL_KEY},
|
||||
{"<right control>", CONTROL_KEY},
|
||||
{"<meta>", META_KEY},
|
||||
{"<left meta>", META_KEY},
|
||||
{"<right meta>", META_KEY},
|
||||
{"<caps lock>", CAPS_LOCK},
|
||||
{"<tab>", '\t'},
|
||||
{"<space>", ' '},
|
||||
{"<return>", '\r'},
|
||||
{"<linefeed>", '\n'},
|
||||
{"<formfeed>", '\f'},
|
||||
{"<backspace>", '\b'},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static void
|
||||
scan_blanks(void)
|
||||
{ /* scan past the white space */
|
||||
while (*str == ' ' || *str == '\t')
|
||||
str++;
|
||||
}
|
||||
|
||||
static char *
|
||||
smash(void)
|
||||
{ /* convert a string to hex */
|
||||
char *s, *t;
|
||||
int ch, i, j;
|
||||
|
||||
t = s = str;
|
||||
for (i = 0; (ch = *str); str++) {
|
||||
if (ch >= '0' && ch <= '9')
|
||||
j = ch - '0';
|
||||
else if (ch >= 'a' && ch <= 'f')
|
||||
j = 10 - 'a' + ch;
|
||||
else if (ch >= 'A' && ch <= 'F')
|
||||
j = 10 - 'A' + ch;
|
||||
else if (ch == ' ' || ch == '\t')
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
if (i) {
|
||||
*s |= j;
|
||||
s++;
|
||||
} else
|
||||
*s = j << 4;
|
||||
i ^= 1;
|
||||
}
|
||||
*s = '\0';
|
||||
return t;
|
||||
}
|
||||
|
||||
void
|
||||
scan_init(char *fn)
|
||||
{ /* read the scan mode key definitions */
|
||||
char *s, *sl;
|
||||
FILE *fp;
|
||||
int ch, i, j;
|
||||
unsigned len;
|
||||
char home[512];
|
||||
|
||||
if ((str = getenv("HOME")))
|
||||
strcpy(home, str);
|
||||
else
|
||||
home[0] = '\0';
|
||||
fp = NULL;
|
||||
if ((str = getenv("KEYBOARD"))) {
|
||||
if (!(fp = fopen(str, "r")) && home[0]) {
|
||||
sprintf(temp, "%s/.scan.%s", home, str);
|
||||
fp = fopen(temp, "r");
|
||||
}
|
||||
}
|
||||
if (!fp) {
|
||||
sprintf(temp, ".scan.%s", fn);
|
||||
fp = fopen(temp, "r");
|
||||
}
|
||||
if (!fp && home[0]) {
|
||||
sprintf(temp, "%s/.scan.%s", home, fn);
|
||||
fp = fopen(temp, "r");
|
||||
}
|
||||
if (!fp) {
|
||||
ptext("Unable to open scanfile: ");
|
||||
ptextln(temp);
|
||||
bye_kids(1);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
scan file format:
|
||||
|
||||
<down value> <up value> <name>
|
||||
|
||||
values are in hex. <name> may be any string of characters
|
||||
|
||||
*/
|
||||
scan_up = (char **) malloc(sizeof(char *) * MAX_SCAN);
|
||||
scan_down = (char **) malloc(sizeof(char *) * MAX_SCAN);
|
||||
scan_name = (char **) malloc(sizeof(char *) * MAX_SCAN);
|
||||
scan_tested = (unsigned *) malloc(sizeof(unsigned *) * MAX_SCAN);
|
||||
scan_length = (unsigned *) malloc(sizeof(unsigned *) * MAX_SCAN);
|
||||
scan_value = (unsigned *) malloc(sizeof(unsigned *) * MAX_SCAN);
|
||||
scan_up[0] = scan_down[0] = scan_name[0] = (char *) 0;
|
||||
str = (char *) malloc(4096); /* buffer space */
|
||||
sl = str + 4000; /* an upper limit */
|
||||
scan_max = 1;
|
||||
for (i = 0;;) {
|
||||
for (s = str; (ch = getc(fp)) != EOF;) {
|
||||
if (ch == '\n' || ch == '\r')
|
||||
break;
|
||||
*s++ = ch;
|
||||
}
|
||||
*s++ = '\0';
|
||||
if (ch == EOF)
|
||||
break;
|
||||
if (*str == '#' || *str == '\0')
|
||||
continue;
|
||||
scan_down[i] = smash();
|
||||
scan_blanks();
|
||||
scan_up[i] = smash();
|
||||
scan_blanks();
|
||||
scan_name[i] = str;
|
||||
|
||||
scan_length[i] = strlen(scan_down[i]);
|
||||
len = strlen(scan_up[i]) + scan_length[i];
|
||||
if (len > scan_max)
|
||||
scan_max = len;
|
||||
|
||||
scan_value[i] = UChar(scan_name[i][0]);
|
||||
if (scan_name[i][1]) /* multi-character name */
|
||||
for (j = 0; scan_special[j].name; j++) {
|
||||
if (!strcmp(scan_name[i], scan_special[j].name)) {
|
||||
scan_value[i] = scan_special[j].type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
if (str > sl) {
|
||||
str = (char *) malloc(4096);
|
||||
sl = str + 4000;
|
||||
} else
|
||||
str = s;
|
||||
}
|
||||
fclose(fp);
|
||||
#ifdef notdef
|
||||
for (i = 0; scan_down[i]; i++) {
|
||||
put_str(hex_expand_to(scan_down[i], 3));
|
||||
put_str(hex_expand_to(scan_up[i], 3));
|
||||
put_str(" ");
|
||||
put_str(scan_name[i]);
|
||||
put_crlf();
|
||||
}
|
||||
(void) wait_here();
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
scan_key(void)
|
||||
{ /* read a key and translate scan mode to
|
||||
ASCII */
|
||||
unsigned i;
|
||||
int j, ch;
|
||||
char buf[64];
|
||||
|
||||
for (i = 1;; i++) {
|
||||
ch = getchar();
|
||||
if (ch == EOF)
|
||||
return EOF;
|
||||
if (debug_fp) {
|
||||
fprintf(debug_fp, "%02X ", ch);
|
||||
debug_char_count += 3;
|
||||
if (debug_char_count > 72) {
|
||||
fprintf(debug_fp, "\n");
|
||||
debug_char_count = 0;
|
||||
}
|
||||
}
|
||||
buf[i - 1] = ch;
|
||||
buf[i] = '\0';
|
||||
if (buf[0] & 0x80) { /* scan up */
|
||||
for (j = 0; scan_up[j]; j++) {
|
||||
if (i == scan_length[j] &&
|
||||
!strcmp(buf, scan_up[j])) {
|
||||
i = 0;
|
||||
shift_state &= ~scan_value[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (j = 0; scan_down[j]; j++) {
|
||||
if (i == scan_length[j] && !strcmp(buf, scan_down[j])) {
|
||||
i = 0;
|
||||
shift_state |= scan_value[j];
|
||||
ch = scan_value[j];
|
||||
if (ch == CAPS_LOCK)
|
||||
shift_state ^= SHIFT_KEY;
|
||||
if (ch >= 256)
|
||||
break;
|
||||
if (shift_state & SHIFT_KEY) {
|
||||
if (ch >= 0x60)
|
||||
ch -= 0x20;
|
||||
else if (ch >= 0x30 && ch <= 0x3f)
|
||||
ch -= 0x10;
|
||||
}
|
||||
if (shift_state & CONTROL_KEY) {
|
||||
if ((ch | 0x20) >= 0x60 &&
|
||||
(ch | 0x20) <= 0x7f)
|
||||
ch = (ch | 0x20) - 0x60;
|
||||
}
|
||||
if (shift_state & META_KEY)
|
||||
ch |= 0x80;
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
if (i > scan_max)
|
||||
i = 1;
|
||||
}
|
||||
}
|
@ -1,436 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <tack.h>
|
||||
#include <time.h>
|
||||
|
||||
MODULE_ID("$Id: sync.c,v 1.9 2006/05/06 20:45:48 tom Exp $")
|
||||
|
||||
/* terminal-synchronization and performance tests */
|
||||
|
||||
static void sync_home(struct test_list *, int *, int *);
|
||||
static void sync_lines(struct test_list *, int *, int *);
|
||||
static void sync_clear(struct test_list *, int *, int *);
|
||||
static void sync_summary(struct test_list *, int *, int *);
|
||||
|
||||
static struct test_list sync_test_list[] = {
|
||||
{MENU_NEXT, 0, 0, 0, "b) baud rate test", sync_home, 0},
|
||||
{MENU_NEXT, 0, 0, 0, "l) scroll performance", sync_lines, 0},
|
||||
{MENU_NEXT, 0, 0, 0, "c) clear screen performance", sync_clear, 0},
|
||||
{MENU_NEXT, 0, 0, 0, "p) summary of results", sync_summary, 0},
|
||||
{0, 0, 0, 0, txt_longer_test_time, longer_test_time, 0},
|
||||
{0, 0, 0, 0, txt_shorter_test_time, shorter_test_time, 0},
|
||||
{MENU_LAST, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
struct test_menu sync_menu = {
|
||||
0, 'n', 0,
|
||||
"Performance tests", "perf", "n) run standard tests",
|
||||
sync_test, sync_test_list, 0, 0, 0
|
||||
};
|
||||
|
||||
int tty_can_sync; /* TRUE if tty_sync_error() returned FALSE */
|
||||
static int tty_newline_rate; /* The number of newlines per second */
|
||||
static int tty_clear_rate; /* The number of clear-screens per second */
|
||||
unsigned long tty_cps; /* The number of characters per second */
|
||||
|
||||
#define TTY_ACK_SIZE 64
|
||||
|
||||
static int ACK_terminator; /* terminating ACK character */
|
||||
static int ACK_length; /* length of ACK string */
|
||||
static const char *tty_ENQ; /* enquire string */
|
||||
static char tty_ACK[TTY_ACK_SIZE]; /* ACK response, set by tty_sync_error() */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Terminal synchronization.
|
||||
*
|
||||
* These functions handle the messy business of enq-ack handshaking
|
||||
* for timing purposes.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int
|
||||
tty_sync_error(void)
|
||||
{
|
||||
int ch, trouble, ack;
|
||||
|
||||
trouble = FALSE;
|
||||
for (;;) {
|
||||
tt_putp(tty_ENQ); /* send ENQ */
|
||||
ch = getnext(STRIP_PARITY);
|
||||
event_start(TIME_SYNC); /* start the timer */
|
||||
|
||||
/*
|
||||
The timer doesn't start until we get the first character.
|
||||
After that I expect to get the remaining characters of
|
||||
the acknowledge string in a short period of time. If
|
||||
that is not true then these characters are coming from
|
||||
the user and we need to send the ENQ sequence out again.
|
||||
*/
|
||||
for (ack = 0; ; ) {
|
||||
if (ack < TTY_ACK_SIZE - 2) {
|
||||
tty_ACK[ack] = ch;
|
||||
tty_ACK[ack + 1] = '\0';
|
||||
}
|
||||
if (ch == ACK_terminator) {
|
||||
return trouble;
|
||||
}
|
||||
if (++ack >= ACK_length) {
|
||||
return trouble;
|
||||
}
|
||||
ch = getnext(STRIP_PARITY);
|
||||
if (event_time(TIME_SYNC) > 400000) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
set_attr(0); /* just in case */
|
||||
put_crlf();
|
||||
if (trouble) {
|
||||
/* The terminal won't sync. Life is not good. */
|
||||
return TRUE;
|
||||
}
|
||||
put_str(" -- sync -- ");
|
||||
trouble = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** flush_input()
|
||||
**
|
||||
** Throw away any output.
|
||||
*/
|
||||
void
|
||||
flush_input(void)
|
||||
{
|
||||
if (tty_can_sync == SYNC_TESTED && ACK_terminator >= 0) {
|
||||
(void) tty_sync_error();
|
||||
} else {
|
||||
spin_flush();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** probe_enq_ok()
|
||||
**
|
||||
** does the terminal do enq/ack handshaking?
|
||||
*/
|
||||
static void
|
||||
probe_enq_ok(void)
|
||||
{
|
||||
int tc, len, ulen;
|
||||
|
||||
put_str("Testing ENQ/ACK, standby...");
|
||||
fflush(stdout);
|
||||
can_test("u8 u9", FLAG_TESTED);
|
||||
|
||||
#ifdef user9
|
||||
tty_ENQ = user9 ? user9 : "\005";
|
||||
#else
|
||||
tty_ENQ = "\005";
|
||||
#endif
|
||||
tc_putp(tty_ENQ);
|
||||
event_start(TIME_SYNC); /* start the timer */
|
||||
read_key(tty_ACK, TTY_ACK_SIZE - 1);
|
||||
|
||||
if (event_time(TIME_SYNC) > 400000 || tty_ACK[0] == '\0') {
|
||||
/* These characters came from the user. Sigh. */
|
||||
tty_can_sync = SYNC_FAILED;
|
||||
ptext("\nThis program expects the ENQ sequence to be");
|
||||
ptext(" answered with the ACK character. This will help");
|
||||
ptext(" the program reestablish synchronization when");
|
||||
ptextln(" the terminal is overrun with data.");
|
||||
ptext("\nENQ sequence from (u9): ");
|
||||
putln(expand(tty_ENQ));
|
||||
ptext("ACK received: ");
|
||||
putln(expand(tty_ACK));
|
||||
#ifdef user8
|
||||
len = user8 ? strlen(user8) : 0;
|
||||
#else
|
||||
len = 0;
|
||||
#endif
|
||||
sprintf(temp, "Length of ACK %d. Expected length of ACK %d.",
|
||||
(int) strlen(tty_ACK), len);
|
||||
ptextln(temp);
|
||||
#ifdef user8
|
||||
if (len) {
|
||||
temp[0] = user8[len - 1];
|
||||
temp[1] = '\0';
|
||||
ptext("Terminating character found in (u8): ");
|
||||
putln(expand(temp));
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
tty_can_sync = SYNC_TESTED;
|
||||
if ((len = strlen(tty_ACK)) == 1) {
|
||||
/* single character acknowledge string */
|
||||
ACK_terminator = tty_ACK[0];
|
||||
ACK_length = 4096;
|
||||
return;
|
||||
}
|
||||
tc = tty_ACK[len - 1];
|
||||
#ifdef user8
|
||||
if (user8) {
|
||||
ulen = strlen(user8);
|
||||
if (tc == user8[ulen - 1]) {
|
||||
/* ANSI style acknowledge string */
|
||||
ACK_terminator = tc;
|
||||
ACK_length = 4096;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* fixed length acknowledge string */
|
||||
ACK_length = len;
|
||||
ACK_terminator = -2;
|
||||
}
|
||||
|
||||
/*
|
||||
** verify_time()
|
||||
**
|
||||
** verify that the time tests are ready to run.
|
||||
** If the baud rate is not set then compute it.
|
||||
*/
|
||||
void
|
||||
verify_time(void)
|
||||
{
|
||||
int status, ch;
|
||||
|
||||
if (tty_can_sync == SYNC_FAILED) {
|
||||
return;
|
||||
}
|
||||
probe_enq_ok();
|
||||
put_crlf();
|
||||
if (tty_can_sync == SYNC_TESTED) {
|
||||
put_crlf();
|
||||
if (ACK_terminator >= 0) {
|
||||
ptext("ACK terminating character: ");
|
||||
temp[0] = ACK_terminator;
|
||||
temp[1] = '\0';
|
||||
ptextln(expand(temp));
|
||||
} else {
|
||||
sprintf(temp, "Fixed length ACK, %d characters",
|
||||
ACK_length);
|
||||
ptextln(temp);
|
||||
}
|
||||
}
|
||||
if (tty_baud_rate == 0) {
|
||||
sync_home(&sync_test_list[0], &status, &ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Terminal performance tests
|
||||
*
|
||||
* Find out how fast the terminal can:
|
||||
* 1) accept characters
|
||||
* 2) scroll the screen
|
||||
* 3) clear the screen
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
** sync_home(test_list, status, ch)
|
||||
**
|
||||
** Baudrate test
|
||||
*/
|
||||
static void
|
||||
sync_home(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int j, k;
|
||||
unsigned long rate;
|
||||
|
||||
if (!cursor_home && !cursor_address && !row_address) {
|
||||
ptext("Terminal can not home cursor. ");
|
||||
generic_done_message(t, state, ch);
|
||||
return;
|
||||
}
|
||||
if (skip_pad_test(t, state, ch,
|
||||
"(home) Start baudrate search")) {
|
||||
return;
|
||||
}
|
||||
pad_test_startup(1);
|
||||
do {
|
||||
go_home();
|
||||
for (j = 1; j < lines; j++) {
|
||||
for (k = 0; k < columns; k++) {
|
||||
if (k & 0xF) {
|
||||
put_this(letter);
|
||||
} else {
|
||||
put_this('.');
|
||||
}
|
||||
}
|
||||
SLOW_TERMINAL_EXIT;
|
||||
}
|
||||
NEXT_LETTER;
|
||||
} while(still_testing());
|
||||
pad_test_shutdown(t, auto_right_margin == 0);
|
||||
/* note: tty_frame_size is the real framesize times two.
|
||||
This takes care of half bits. */
|
||||
rate = (tx_cps * tty_frame_size) >> 1;
|
||||
if (rate > tty_baud_rate) {
|
||||
tty_baud_rate = rate;
|
||||
}
|
||||
if (tx_cps > tty_cps) {
|
||||
tty_cps = tx_cps;
|
||||
}
|
||||
sprintf(temp, "%lu characters per second. Baudrate %d ", tx_cps, j);
|
||||
ptext(temp);
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** sync_lines(test_list, status, ch)
|
||||
**
|
||||
** How many newlines/second?
|
||||
*/
|
||||
static void
|
||||
sync_lines(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int j;
|
||||
|
||||
if (skip_pad_test(t, state, ch,
|
||||
"(nel) Start scroll performance test")) {
|
||||
return;
|
||||
}
|
||||
pad_test_startup(0);
|
||||
repeats = 100;
|
||||
do {
|
||||
sprintf(temp, "%d", test_complete);
|
||||
put_str(temp);
|
||||
put_newlines(repeats);
|
||||
} while(still_testing());
|
||||
pad_test_shutdown(t, 0);
|
||||
j = sliding_scale(tx_count[0], 1000000, usec_run_time);
|
||||
if (j > tty_newline_rate) {
|
||||
tty_newline_rate = j;
|
||||
}
|
||||
sprintf(temp, "%d linefeeds per second. ", j);
|
||||
ptext(temp);
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** sync_clear(test_list, status, ch)
|
||||
**
|
||||
** How many clear-screens/second?
|
||||
*/
|
||||
static void
|
||||
sync_clear(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
int j;
|
||||
|
||||
if (!clear_screen) {
|
||||
ptext("Terminal can not clear-screen. ");
|
||||
generic_done_message(t, state, ch);
|
||||
return;
|
||||
}
|
||||
if (skip_pad_test(t, state, ch,
|
||||
"(clear) Start clear-screen performance test")) {
|
||||
return;
|
||||
}
|
||||
pad_test_startup(0);
|
||||
repeats = 20;
|
||||
do {
|
||||
sprintf(temp, "%d", test_complete);
|
||||
put_str(temp);
|
||||
for (j = 0; j < repeats; j++) {
|
||||
put_clear();
|
||||
}
|
||||
} while(still_testing());
|
||||
pad_test_shutdown(t, 0);
|
||||
j = sliding_scale(tx_count[0], 1000000, usec_run_time);
|
||||
if (j > tty_clear_rate) {
|
||||
tty_clear_rate = j;
|
||||
}
|
||||
sprintf(temp, "%d clear-screens per second. ", j);
|
||||
ptext(temp);
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** sync_summary(test_list, status, ch)
|
||||
**
|
||||
** Print out the test results.
|
||||
*/
|
||||
static void
|
||||
sync_summary(
|
||||
struct test_list *t,
|
||||
int *state,
|
||||
int *ch)
|
||||
{
|
||||
char size[32];
|
||||
|
||||
put_crlf();
|
||||
ptextln("Terminal size characters/sec linefeeds/sec clears/sec");
|
||||
sprintf(size, "%dx%d", columns, lines);
|
||||
sprintf(temp, "%-10s%-11s%11lu %11d %11d", tty_basename, size,
|
||||
tty_cps, tty_newline_rate, tty_clear_rate);
|
||||
ptextln(temp);
|
||||
generic_done_message(t, state, ch);
|
||||
}
|
||||
|
||||
/*
|
||||
** sync_test(menu)
|
||||
**
|
||||
** Run at the beginning of the pad tests and function key tests
|
||||
*/
|
||||
void
|
||||
sync_test(
|
||||
struct test_menu *menu)
|
||||
{
|
||||
control_init();
|
||||
if (tty_can_sync == SYNC_NOT_TESTED) {
|
||||
verify_time();
|
||||
}
|
||||
if (menu->menu_title) {
|
||||
put_crlf();
|
||||
ptextln(menu->menu_title);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** sync_handshake(test_list, status, ch)
|
||||
**
|
||||
** Test or retest the ENQ/ACK handshake
|
||||
*/
|
||||
void
|
||||
sync_handshake(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch GCC_UNUSED)
|
||||
{
|
||||
tty_can_sync = SYNC_NOT_TESTED;
|
||||
verify_time();
|
||||
}
|
@ -1,504 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
/*
|
||||
* Operating system dependent functions. We assume the POSIX API.
|
||||
* Note: on strict-POSIX systems (including BSD/OS) the select_delay_type
|
||||
* global has no effect.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <ncurses_cfg.h>
|
||||
#endif
|
||||
#include <signal.h> /* include before curses.h to work around glibc bug */
|
||||
|
||||
#include <tack.h>
|
||||
|
||||
#include <term.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(__BEOS__)
|
||||
#undef false
|
||||
#undef true
|
||||
#include <OS.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SELECT
|
||||
#if HAVE_SYS_TIME_H && HAVE_SYS_TIME_SELECT
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#if HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
MODULE_ID("$Id: sysdep.c,v 1.15 2005/09/17 19:49:16 tom Exp $")
|
||||
|
||||
#if DECL_ERRNO
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#ifdef TERMIOS
|
||||
#define PUT_TTY(fd, buf) tcsetattr(fd, TCSAFLUSH, buf)
|
||||
#else
|
||||
#define PUT_TTY(fd, buf) stty(fd, buf)
|
||||
#endif
|
||||
|
||||
/* globals */
|
||||
int tty_frame_size; /* asynch frame size times 2 */
|
||||
unsigned tty_baud_rate; /* baud rate - bits per second */
|
||||
int not_a_tty; /* TRUE if output is not a tty (i.e. pipe) */
|
||||
int nodelay_read; /* TRUE if NDELAY is set */
|
||||
|
||||
#ifdef TERMIOS
|
||||
#define TTY_IS_NOECHO !(new_modes.c_lflag & ECHO)
|
||||
#define TTY_IS_OUT_TRANS (new_modes.c_oflag & OPOST)
|
||||
#define TTY_IS_CHAR_MODE !(new_modes.c_lflag & ICANON)
|
||||
#define TTY_WAS_CS8 ((old_modes.c_cflag & CSIZE) == CS8)
|
||||
#define TTY_WAS_XON_XOFF (old_modes.c_iflag & (IXON|IXOFF))
|
||||
#else
|
||||
#define TTY_IS_NOECHO !(new_modes.sg_flags & (ECHO))
|
||||
#define TTY_IS_OUT_TRANS (new_modes.sg_flags & (CRMOD))
|
||||
#define TTY_IS_CHAR_MODE (new_modes.sg_flags & (RAW|CBREAK))
|
||||
#define TTY_WAS_CS8 (old_modes.sg_flags & (PASS8))
|
||||
#define TTY_WAS_XON_XOFF (old_modes.sg_flags & (TANDEM|MDMBUF|DECCTQ))
|
||||
#endif
|
||||
|
||||
static TTY old_modes, new_modes;
|
||||
|
||||
void catchsig(void);
|
||||
|
||||
/*
|
||||
* These are a sneaky way of conditionalizing bit unsets so strict-POSIX
|
||||
* systems won't see them.
|
||||
*/
|
||||
#ifndef XCASE
|
||||
#define XCASE 0
|
||||
#endif
|
||||
#ifndef OLCUC
|
||||
#define OLCUC 0
|
||||
#endif
|
||||
#ifndef IUCLC
|
||||
#define IUCLC 0
|
||||
#endif
|
||||
#ifndef TABDLY
|
||||
#define TABDLY 0
|
||||
#endif
|
||||
#ifndef IXANY
|
||||
#define IXANY 0
|
||||
#endif
|
||||
|
||||
void
|
||||
tty_raw(int minch GCC_UNUSED, int mask)
|
||||
{ /* set tty to raw noecho */
|
||||
new_modes = old_modes;
|
||||
#ifdef TERMIOS
|
||||
#if HAVE_SELECT
|
||||
new_modes.c_cc[VMIN] = 1;
|
||||
#else
|
||||
new_modes.c_cc[VMIN] = minch;
|
||||
#endif
|
||||
new_modes.c_cc[VTIME] = 2;
|
||||
new_modes.c_lflag &=
|
||||
~(ISIG | ICANON | XCASE | ECHO | ECHOE | ECHOK | ECHONL);
|
||||
#ifdef LOBLK
|
||||
new_modes.c_lflag &= ~LOBLK;
|
||||
#endif
|
||||
new_modes.c_oflag &= ~(OPOST | OLCUC | TABDLY);
|
||||
if (mask == ALLOW_PARITY) {
|
||||
new_modes.c_cflag &= ~(CSIZE | PARENB | HUPCL);
|
||||
new_modes.c_cflag |= CS8;
|
||||
}
|
||||
new_modes.c_iflag &=
|
||||
~(IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP | INLCR | IGNCR | ICRNL |
|
||||
IUCLC | IXON | IXANY | IXOFF);
|
||||
#else
|
||||
new_modes.sg_flags |= RAW;
|
||||
#endif
|
||||
if (not_a_tty)
|
||||
return;
|
||||
PUT_TTY(fileno(stdin), &new_modes);
|
||||
}
|
||||
|
||||
void
|
||||
tty_set(void)
|
||||
{ /* set tty to special modes */
|
||||
new_modes = old_modes;
|
||||
#ifdef TERMIOS
|
||||
new_modes.c_cc[VMIN] = 1;
|
||||
new_modes.c_cc[VTIME] = 1;
|
||||
new_modes.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL);
|
||||
#if defined(ONLCR) && defined(OCRNL) && defined(ONLRET) && defined(OFILL)
|
||||
new_modes.c_oflag &= ~(ONLCR | OCRNL | ONLRET | OFILL);
|
||||
#else
|
||||
new_modes.c_oflag &= ~(OPOST);
|
||||
#endif
|
||||
if (char_mask == ALLOW_PARITY)
|
||||
new_modes.c_iflag &= ~ISTRIP;
|
||||
switch (select_xon_xoff) {
|
||||
case 0:
|
||||
new_modes.c_iflag &= ~(IXON | IXOFF);
|
||||
break;
|
||||
case 1:
|
||||
#if defined(sequent) && sequent
|
||||
/* the sequent System V emulation is broken */
|
||||
new_modes = old_modes;
|
||||
new_modes.c_cc[VEOL] = 6; /* control F (ACK) */
|
||||
#endif
|
||||
new_modes.c_iflag |= IXON | IXOFF;
|
||||
break;
|
||||
}
|
||||
switch (select_delay_type) {
|
||||
case 0:
|
||||
#ifdef NLDLY
|
||||
new_modes.c_oflag &=
|
||||
~(NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY);
|
||||
#endif /* NLDLY */
|
||||
break;
|
||||
case 1:
|
||||
#ifdef NLDLY
|
||||
new_modes.c_oflag &=
|
||||
~(NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY);
|
||||
#endif /* NLDLY */
|
||||
#ifdef NL1
|
||||
new_modes.c_oflag |= NL1 | CR2;
|
||||
#endif /* NL1 */
|
||||
break;
|
||||
}
|
||||
if (!(new_modes.c_oflag & (unsigned long) ~OPOST))
|
||||
new_modes.c_oflag &= (unsigned long) ~OPOST;
|
||||
#else
|
||||
new_modes.sg_flags |= RAW;
|
||||
if (not_a_tty)
|
||||
return;
|
||||
#endif
|
||||
PUT_TTY(fileno(stdin), &new_modes);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tty_reset(void)
|
||||
{ /* reset the tty to the original modes */
|
||||
fflush(stdout);
|
||||
if (not_a_tty)
|
||||
return;
|
||||
PUT_TTY(fileno(stdin), &old_modes);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tty_init(void)
|
||||
{ /* ATT terminal init */
|
||||
#if defined(F_GETFL) && defined(O_NDELAY)
|
||||
int flags;
|
||||
|
||||
flags = fcntl(fileno(stdin), F_GETFL, 0);
|
||||
nodelay_read = flags & O_NDELAY;
|
||||
#else
|
||||
nodelay_read = FALSE;
|
||||
#endif
|
||||
not_a_tty = FALSE;
|
||||
if (GET_TTY(fileno(stdin), &old_modes) == -1) {
|
||||
if (errno == ENOTTY) {
|
||||
tty_frame_size = 20;
|
||||
not_a_tty = TRUE;
|
||||
return;
|
||||
}
|
||||
printf("tcgetattr error: %d\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
/* if TAB3 is set then setterm() wipes out tabs (ht) */
|
||||
new_modes = old_modes;
|
||||
#ifdef TERMIOS
|
||||
#ifdef TABDLY
|
||||
new_modes.c_oflag &= ~TABDLY;
|
||||
#endif /* TABDLY */
|
||||
#endif
|
||||
if (PUT_TTY(fileno(stdin), &new_modes) == -1) {
|
||||
printf("tcsetattr error: %d\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
#ifdef sequent
|
||||
/* the sequent ATT emulation is broken soooo. */
|
||||
old_modes.c_cflag &= ~(CSIZE | CSTOPB);
|
||||
old_modes.c_cflag |= CS7 | PARENB;
|
||||
#endif
|
||||
catchsig();
|
||||
#ifdef TERMIOS
|
||||
switch (old_modes.c_cflag & CSIZE) {
|
||||
#if defined(CS5) && (CS5 != 0)
|
||||
case CS5:
|
||||
tty_frame_size = 10;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CS6) && (CS6 != 0)
|
||||
case CS6:
|
||||
tty_frame_size = 12;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CS7) && (CS7 != 0)
|
||||
case CS7:
|
||||
tty_frame_size = 14;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CS8) && (CS8 != 0)
|
||||
case CS8:
|
||||
tty_frame_size = 16;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
tty_frame_size += 2 +
|
||||
((old_modes.c_cflag & PARENB) ? 2 : 0) +
|
||||
((old_modes.c_cflag & CSTOPB) ? 4 : 2);
|
||||
#else
|
||||
tty_frame_size = 6 +
|
||||
(old_modes.sg_flags & PASS8) ? 16 : 14;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** stty_query(question)
|
||||
**
|
||||
** Does the current driver settings have this property?
|
||||
*/
|
||||
int
|
||||
stty_query(int q)
|
||||
{
|
||||
switch (q) {
|
||||
case TTY_NOECHO:
|
||||
return TTY_IS_NOECHO;
|
||||
case TTY_OUT_TRANS:
|
||||
return TTY_IS_OUT_TRANS;
|
||||
case TTY_CHAR_MODE:
|
||||
return TTY_IS_CHAR_MODE;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
** initial_stty_query(question)
|
||||
**
|
||||
** Did the initial driver settings have this property?
|
||||
*/
|
||||
int
|
||||
initial_stty_query(int q)
|
||||
{
|
||||
switch (q) {
|
||||
case TTY_8_BIT:
|
||||
return TTY_WAS_CS8;
|
||||
case TTY_XON_XOFF:
|
||||
return TTY_WAS_XON_XOFF;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#if HAVE_SELECT && defined(FD_ZERO)
|
||||
static int
|
||||
char_ready(void)
|
||||
{
|
||||
int n;
|
||||
fd_set ifds;
|
||||
struct timeval tv;
|
||||
|
||||
FD_ZERO(&ifds);
|
||||
FD_SET(fileno(stdin), &ifds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 200000;
|
||||
n = select(fileno(stdin)+1, &ifds, NULL, NULL, &tv);
|
||||
return (n != 0);
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef FIONREAD
|
||||
int
|
||||
char_ready(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/* the following loop has to be tuned for each computer */
|
||||
for (j = 0; j < 1000; j++) {
|
||||
ioctl(fileno(stdin), FIONREAD, &i);
|
||||
if (i)
|
||||
return i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
#else
|
||||
#if defined(__BEOS__)
|
||||
int
|
||||
char_ready(void)
|
||||
{
|
||||
int n = 0;
|
||||
int howmany = ioctl(0, 'ichr', &n);
|
||||
return (howmany >= 0 && n > 0);
|
||||
}
|
||||
#else
|
||||
#define char_ready() 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
** spin_flush()
|
||||
**
|
||||
** Wait for the input stream to stop.
|
||||
** Throw away all input characters.
|
||||
*/
|
||||
void
|
||||
spin_flush(void)
|
||||
{
|
||||
unsigned char buf[64];
|
||||
|
||||
fflush(stdout);
|
||||
event_start(TIME_FLUSH); /* start the timer */
|
||||
do {
|
||||
if (char_ready()) {
|
||||
(void) read(fileno(stdin), &buf, sizeof(buf));
|
||||
}
|
||||
} while (event_time(TIME_FLUSH) < 400000);
|
||||
}
|
||||
|
||||
/*
|
||||
** read_key(input-buffer, length-of-buffer)
|
||||
**
|
||||
** read one function key from the input stream.
|
||||
** A null character is converted to 0x80.
|
||||
*/
|
||||
void
|
||||
read_key(char *buf, int max)
|
||||
{
|
||||
int got, ask, i, l;
|
||||
char *s;
|
||||
|
||||
*buf = '\0';
|
||||
s = buf;
|
||||
fflush(stdout);
|
||||
/* ATT unix may return 0 or 1, Berkeley Unix should be 1 */
|
||||
while (read(fileno(stdin), s, 1) == 0);
|
||||
++s;
|
||||
--max;
|
||||
while (max > 0 && (ask = char_ready())) {
|
||||
if (ask > max) {
|
||||
ask = max;
|
||||
}
|
||||
if ((got = read(fileno(stdin), s, (unsigned) ask))) {
|
||||
s += got;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
max -= got;
|
||||
}
|
||||
*s = '\0';
|
||||
l = s - buf;
|
||||
for (s = buf, i = 0; i < l; i++) {
|
||||
if ((*s & 0x7f) == 0) {
|
||||
/* convert nulls to 0x80 */
|
||||
*(unsigned char *)s = 128;
|
||||
} else {
|
||||
/* strip high order bits (if any) */
|
||||
*s &= char_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ignoresig(void)
|
||||
{
|
||||
/* ignore signals */
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGQUIT, SIG_IGN);
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
signal(SIGALRM, SIG_IGN);
|
||||
}
|
||||
|
||||
/*
|
||||
onintr( )
|
||||
|
||||
is the interrupt handling routine onintr turns off interrupts while doing
|
||||
clean-up
|
||||
|
||||
onintr always exits fatally
|
||||
*/
|
||||
|
||||
|
||||
static RETSIGTYPE
|
||||
onintr(int sig GCC_UNUSED)
|
||||
{
|
||||
ignoresig();
|
||||
tty_reset();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
catchsig( )
|
||||
|
||||
set up to field interrupts (via function onintr( )) so that if interrupted
|
||||
we can restore the correct terminal modes
|
||||
|
||||
catchsig simply returns
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
catchsig(void)
|
||||
{
|
||||
if ((signal(SIGINT, SIG_IGN)) == SIG_DFL)
|
||||
signal(SIGINT, onintr);
|
||||
|
||||
if ((signal(SIGHUP, SIG_IGN)) == SIG_DFL)
|
||||
signal(SIGHUP, onintr);
|
||||
|
||||
if ((signal(SIGQUIT, SIG_IGN)) == SIG_DFL)
|
||||
signal(SIGQUIT, onintr);
|
||||
|
||||
if ((signal(SIGTERM, SIG_IGN)) == SIG_DFL)
|
||||
signal(SIGTERM, onintr);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
** alarm_event(sig)
|
||||
**
|
||||
** Come here for an alarm event
|
||||
*/
|
||||
static void
|
||||
alarm_event(
|
||||
int sig GCC_UNUSED)
|
||||
{
|
||||
no_alarm_event = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** set_alarm_clock(seconds)
|
||||
**
|
||||
** Set the alarm clock to fire in <seconds>
|
||||
*/
|
||||
void
|
||||
set_alarm_clock(
|
||||
int seconds)
|
||||
{
|
||||
signal(SIGALRM, alarm_event);
|
||||
no_alarm_event = 1;
|
||||
(void) alarm((unsigned) seconds);
|
||||
}
|
@ -1,340 +0,0 @@
|
||||
.\"***************************************************************************
|
||||
.\" Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. *
|
||||
.\" *
|
||||
.\" Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
.\" copy of this software and associated documentation files (the *
|
||||
.\" "Software"), to deal in the Software without restriction, including *
|
||||
.\" without limitation the rights to use, copy, modify, merge, publish, *
|
||||
.\" distribute, distribute with modifications, sublicense, and/or sell *
|
||||
.\" copies of the Software, and to permit persons to whom the Software is *
|
||||
.\" furnished to do so, subject to the following conditions: *
|
||||
.\" *
|
||||
.\" The above copyright notice and this permission notice shall be included *
|
||||
.\" in all copies or substantial portions of the Software. *
|
||||
.\" *
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
|
||||
.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
||||
.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
|
||||
.\" IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
|
||||
.\" DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
|
||||
.\" OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
|
||||
.\" THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
.\" *
|
||||
.\" Except as contained in this notice, the name(s) of the above copyright *
|
||||
.\" holders shall not be used in advertising or otherwise to promote the *
|
||||
.\" sale, use or other dealings in this Software without prior written *
|
||||
.\" authorization. *
|
||||
.\"***************************************************************************
|
||||
.\"
|
||||
.\" $Id: tack.1,v 1.3 2006/04/22 22:26:55 tom Exp $
|
||||
.TH tack 1M ""
|
||||
.ds n 5
|
||||
.ds d @TERMINFO@
|
||||
.SH NAME
|
||||
\fBtack\fR - \fIterminfo\fR action checker
|
||||
.SH SYNOPSIS
|
||||
\fBtack\fR [-itV] [term]
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
The \fBtack\fR program has three purposes:
|
||||
(1) to help you build a new terminfo entry describing an unknown terminal,
|
||||
(2) to test the correctness of an existing entry, and
|
||||
(3) to develop the correct pad timings needed to ensure that screen updates
|
||||
don't fall behind the incoming data stream.
|
||||
.PP
|
||||
\fBTack\fR presents a series of screen-painting and interactive
|
||||
tests in ways which are intended to make any mismatches between the
|
||||
terminfo entry and reality visually obvious.
|
||||
\fBTack\fR also provides tools that can help in understanding how
|
||||
the terminal operates.
|
||||
.SS OPTIONS
|
||||
.TP
|
||||
.I "\-i"
|
||||
Usually \fBtack\fR will send the reset and init strings to the terminal
|
||||
when the program starts up. The \fI-i\fR option will inhibit the
|
||||
terminal initialization.
|
||||
.TP
|
||||
.I "\-t"
|
||||
Tell \fBtack\fR to override the terminfo settings for basic terminal
|
||||
functions. When this option is set \fBtack\fR will translate
|
||||
(cr) to \\r, (cud1) to \\n, (ind) to \\n, (nel) to \\r\\n,
|
||||
(cub1) to \\b, (bel) to \\007, (ff) to \\f and (ht) to \\t.
|
||||
.TP
|
||||
.I "\-V"
|
||||
Display the version information and exit.
|
||||
.TP
|
||||
.I "term"
|
||||
Terminfo terminal name to be tested. If not present then the $TERM
|
||||
environment variable will be used.
|
||||
.SH OVERVIEW
|
||||
Since \fBtack\fR is designed to test terminfo's it is not possible
|
||||
to rely on the correctness of the terminfo data base. Because of this
|
||||
the menuing system used with \fBtack\fR is vary primitive. When a
|
||||
menu is printed it will scroll the entire screen. To compensate
|
||||
for this verbose menu system \fBtack\fR permits menu selection
|
||||
type ahead.
|
||||
If you already know what action you would like \fBtack\fR to perform
|
||||
then you can enter that value immediately and avoid the menu display.
|
||||
When in doubt the question mark (?) is a good character to type.
|
||||
A carriage return will execute the default action. These default
|
||||
actions are designed to run all the standard tests.
|
||||
.PP
|
||||
When \fBtack\fR first comes up it will display some basic information
|
||||
about the terminal. Take some time to verify this information.
|
||||
If it is wrong many of the subsequent tests will fail. The most
|
||||
important item is the screen size. If the screen size is wrong there
|
||||
is no point in proceeding. (home) and (clear) are also critical
|
||||
to the success of subsequent tests. The values of (cr) (ind)
|
||||
(cub1) and (ht) may effect the tests if they are defined incorrectly.
|
||||
If they are undefined \fBtack\fR will set them to reasonable defaults.
|
||||
The last two entries on the display are the enquire and acknowledge strings.
|
||||
These strings are taken from the user strings (u9) and (u8).
|
||||
.PP
|
||||
By now you must be wondering why the terminfo names are enclosed
|
||||
in parenthesis. This has no profound meaning other than it makes
|
||||
them stand out. The \fBtack\fR program uses this convention any time
|
||||
it displays a terminfo name. Remember \fBtack\fR is designed to
|
||||
rely on as little of the terminfo entry as possible.
|
||||
.SH CREATING NEW ENTRIES
|
||||
\fBTack\fR has a number of tools that are designed to help gather
|
||||
information about the terminal. Although these functions are not
|
||||
dependent on terminal type, you may wish to execute \fBtack\fR
|
||||
with options \fI\-it\fR. This will turn off initialization
|
||||
and default the standard entries.
|
||||
.PP
|
||||
These tools may be reached from the main menu by selecting
|
||||
the 'tools' entry.
|
||||
.PP
|
||||
\fBEcho tool\fR: All data typed from the keyboard will be echoed back
|
||||
to the terminal. Control characters are not translated to the up arrow format
|
||||
but are sent as control characters. This allows you to test an escape
|
||||
sequence and see what it actually does. You may also elect to
|
||||
\fBenable hex output on echo tool\fR this will echo the characters in
|
||||
hexadecimal. Once the test is running you may enter the 'lines'
|
||||
or 'columns' keywords which will display a pattern that will help
|
||||
you determine your screen size. A complete list of keywords will
|
||||
be displayed when the test starts. Type 'help' to redisplay
|
||||
the list of available commands.
|
||||
.PP
|
||||
\fBReply tool\fR: This tool acts much like the echo tool, but
|
||||
control characters that are sent from the terminal more than one character
|
||||
after a carriage return will be expanded to the up arrow format. For example
|
||||
on a standard ANSI terminal you may type:
|
||||
|
||||
CR ESC [ c
|
||||
|
||||
and the response will be echoed as something like:
|
||||
|
||||
^[ [ ? 6 c
|
||||
.PP
|
||||
\fBANSI sgr display\fR: This test assumes you have an ANSI terminal. It
|
||||
goes through attribute numbers 0 to 79, displaying each in turn and using that
|
||||
SGR number to write the text. This shows you which of the SGR
|
||||
modes are actually implemented by the terminal. Note: some terminals (such as
|
||||
Tektronix color) use the private use characters to augment the functionality of
|
||||
the SGR command. These private use characters may be interjected into the
|
||||
escape sequence by typing the character ( <, =, >, ? ) after the original
|
||||
display has been shown.
|
||||
.PP
|
||||
\fBANSI status reports\fR: This test queries the terminal in standard
|
||||
ANSI/VT-100 fashion. The results of this test may help
|
||||
determine what options are supported by your terminal.
|
||||
.PP
|
||||
\fBANSI character sets\fR: This test displays the character sets
|
||||
available on a ANSI/VT-100 style terminal.
|
||||
Character sets on a real VT-100 terminal are usually defined
|
||||
with smacs=\\E(0 and rmacs=\\E(B. The first character after the
|
||||
escape defines the font bank. The second character defines the
|
||||
character set. This test allows you to view any of the possible
|
||||
combinations. Private use character sets are defined by the digits.
|
||||
Standard character sets are located in the alphabetic range.
|
||||
.SH VERIFYING AN EXISTING ENTRY
|
||||
.PP
|
||||
You can verify the correctness of an entry with the `begin testing'
|
||||
function. This entry is the default action and will be chosen
|
||||
if you hit carriage return (or enter). This will bring up a
|
||||
secondary menu that allows you to select more specific tests.
|
||||
.PP
|
||||
The general philosophy of the program is, for each capability, to send an
|
||||
appropriate test pattern to the terminal then send a description of
|
||||
what the user should expect. Occasionally (as when checking function-key
|
||||
capabilities) the program will ask you to enter input for it to check.
|
||||
.PP
|
||||
If the test fails then you have the option of dynamically changing
|
||||
the terminfo entry and re-running the test. This is done with
|
||||
the 'edit terminfo' menu item. The edit submenu allows you to change
|
||||
the offending terminfo entry and immediately retest the capability.
|
||||
The edit menu lets you do other things with the terminfo, such as;
|
||||
display the entire terminfo entry,
|
||||
display which caps have been tested and display which caps cannot
|
||||
be tested. This menu also allows you to write the newly modified
|
||||
terminfo to disc. If you have made any modifications to the
|
||||
terminfo \fBtack\fR will ask you if you want to save the file
|
||||
to disc before it exits. The filename will be the same as the terminal name.
|
||||
After the program exits you can run the tic(1M) compiler on the
|
||||
new terminfo to install it in the terminfo data base.
|
||||
.PP
|
||||
.SH CORRECTING PAD TIMINGS
|
||||
.SS Theory of Overruns and Padding
|
||||
.PP
|
||||
Some terminals require significant amounts of time (that is, more than one
|
||||
transmitted-character interval) to do screen updates that change large
|
||||
portions of the screen, such as screen clears, line insertions,
|
||||
line deletions, and scrolls (including scrolls triggered by line feeds
|
||||
or a write to the lowest, right-hand-most cell of the screen).
|
||||
.PP
|
||||
If the computer continues to send characters to the terminal while one
|
||||
of these time-consuming operations is going on, the screen may be garbled.
|
||||
Since the length of a character transmission time varies inversely with
|
||||
transmission speed in cps, entries which function at lower speeds may
|
||||
break at higher speeds.
|
||||
.PP
|
||||
Similar problems result if the host machine is simply sending characters at a
|
||||
sustained rate faster than the terminal can buffer and process them. In either
|
||||
case, when the terminal cannot process them and can't tell the host to stop
|
||||
soon enough, it will just drop them. The dropped characters could be text,
|
||||
escape sequences or the escape character itself, causing some really
|
||||
strange-looking displays. This kind of glitch is called an \fIoverrun\fR.
|
||||
.PP
|
||||
In terminfo entries, you can attach a \fBpad time\fR to each string capability
|
||||
that is a number of milliseconds to delay after sending it. This will give
|
||||
the terminal time to catch up and avoid overruns.
|
||||
.PP
|
||||
If you are running a software terminal emulator, or you are on an X pseudo-tty,
|
||||
or your terminal is on an RS-232C line which correctly handles RTS/CTS
|
||||
hardware flow control, then pads are not strictly necessary. However, some
|
||||
display packages (such as ncurses(3X)) use the pad counts to calculate
|
||||
the fastest way to implement certain functions.
|
||||
For example: scrolling the screen may be faster than deleting the top line.
|
||||
.PP
|
||||
One common way to avoid overruns is with XON/XOFF handshaking.
|
||||
But even this handshake may have problems at high baud rates.
|
||||
This is a result of the way XON/XOFF works. The terminal tells
|
||||
the host to stop with an XOFF. When the host gets this character, it stops
|
||||
sending. However, there is a small amount of time between the stop request and
|
||||
the actual stop. During this window, the terminal must continue to accept
|
||||
characters even though it has told the host to stop. If the terminal sends
|
||||
the stop request too late, then its internal buffer will overflow. If it sends
|
||||
the stop character too early, then the terminal is not getting the most
|
||||
efficient use out of its internal buffers. In a real application at high baud
|
||||
rates, a terminal could get a dozen or more characters before the host gets
|
||||
around to suspending transmission. Connecting the terminal over a network
|
||||
will make the problem much worse.
|
||||
.PP
|
||||
(RTS/CTS handshaking does not have this problem because the UARTs are
|
||||
signal-connected and the "stop flow" is done at the lowest level, without
|
||||
software intervention).
|
||||
.PP
|
||||
.SS Timing your terminal
|
||||
.PP
|
||||
In order to get accurate timings from your terminal \fBtack\fR
|
||||
needs to know when the terminal has finished processing all the
|
||||
characters that were sent. This requires a different type of handshaking
|
||||
than the XON/XOFF that is supported by most terminals. \fBTack\fR
|
||||
needs to send a request to the terminal and wait for its reply.
|
||||
Many terminals will respond with an ACK when they receive an ENQ.
|
||||
This is the preferred method since the sequence is short.
|
||||
ANSI/VT-100 style terminals can mimic this handshake with the
|
||||
escape sequence that requests 'primary device attributes'.
|
||||
|
||||
ESC [ c
|
||||
|
||||
The terminal will respond with a sequence like:
|
||||
|
||||
ESC [ ? 1 ; 0 c
|
||||
|
||||
\fBTack\fR assumes that (u9) is the enquire sequence and that (u8) is the
|
||||
acknowledge string. A VT-100 style terminal could set u9=\\E[c
|
||||
and u8=\\E[?1;0c.
|
||||
Acknowledge strings fall into two categories.
|
||||
1) Strings with a unique terminating character and,
|
||||
2) strings of fixed length.
|
||||
The acknowledge string for the VT-100 is of the first type since
|
||||
it always ends with the letter 'c'. Some Tektronics terminals
|
||||
have fixed length acknowledge strings. \fBTack\fR supports both
|
||||
types of strings by scanning for the terminating character until
|
||||
the length of the expected acknowledge string has arrived.
|
||||
(u8) should be set to some typical acknowledge that will be
|
||||
returned when (u9) is sent.
|
||||
.PP
|
||||
\fBTack\fR will test this sequence before running any of the pad
|
||||
tests or the function key tests. \fBTack\fR will ask you the following:
|
||||
|
||||
Hit lower case g to start testing...
|
||||
|
||||
After it sends this message it will send the enquire string.
|
||||
It will then read characters from the terminal until it sees the
|
||||
letter g.
|
||||
.PP
|
||||
.SS Testing and Repairing Pad Timings
|
||||
.PP
|
||||
The pad timings in distributed terminfo entries are often incorrect. One
|
||||
major motivation for this program is to make it relatively easy to tune these
|
||||
timings.
|
||||
.PP
|
||||
You can verify and edit the pad timings for a terminal with
|
||||
the `test string capabilities'
|
||||
function (this is also part of the `normal test sequence' function).
|
||||
.PP
|
||||
The key to determining pad times is to find out the effective baud rate of
|
||||
the terminal. The effective baud rate determines the number of characters
|
||||
per second that the terminal can accept without either handshaking or
|
||||
losing data. This rate is frequently less than the nominal cps rate on the
|
||||
RS-232 line.
|
||||
.PP
|
||||
\fBTack\fR uses the effective baud rate to judge the duration of the test and
|
||||
how much a particular escape sequence will perturb the terminal.
|
||||
.PP
|
||||
Each pad test has two associated variables that can be tweaked to help verify
|
||||
the correctness of the pad timings. One is the pad test length. The other is
|
||||
the pad multiplier, which is used if the pad prefix includes `*'. In curses
|
||||
use, it is often the first parameter of the capability (if there is one).
|
||||
For a capability like (dch) or (il) this will be the number of character
|
||||
positions or lines affected, respectively.
|
||||
.PP
|
||||
\fBTack\fR will run the pad tests and display the results to the terminal.
|
||||
On capabilities that have multipliers \fBtack\fR will not tell you
|
||||
if the pad needs the multiplier or not. You must make this decision
|
||||
yourself by rerunning the test with a different multiplier.
|
||||
If the padding changes in proportion to the multiplier than the
|
||||
multiplier is required. If the multiplier has little or no effect on
|
||||
the suggested padding then the multiplier is not needed.
|
||||
Some capabilities will take several runs to get a good feel for
|
||||
the correct values. You may wish to make the test longer
|
||||
to get more accurate results. System load will also effect the
|
||||
results (a heavily loaded system will not stress the
|
||||
terminal as much, possibly leading to pad timings that are too short).
|
||||
.PP
|
||||
.SH NOTE
|
||||
The tests done at the beginning of the program are assumed to be correct later
|
||||
in the code. In particular, \fBtack\fR displays the number of lines and
|
||||
columns indicated in the terminfo entry as part of its initial output.
|
||||
If these values are wrong a large number of tests will fail or give incorrect
|
||||
results.
|
||||
.SH FILES
|
||||
.TP 12
|
||||
tack.log
|
||||
If logging is enabled then all characters written to the terminal
|
||||
will also be written to the log file. This gives you the ability
|
||||
to see how the tests were performed. This feature is disabled by default.
|
||||
.TP 12
|
||||
.I "term"
|
||||
If you make changes to the terminfo entry \fBtack\fR will save
|
||||
the new terminfo to a file. The file will have the same name
|
||||
as the terminal name.
|
||||
.SH SEE ALSO
|
||||
\fBterminfo\fR(\*n), \fBncurses\fR(3X), \fBtic\fR(1M), \fBinfocmp\fR(1M).
|
||||
You should also have the documentation supplied by the terminal
|
||||
manufacturer.
|
||||
.SH BUGS
|
||||
If the screen size is incorrect, many of the tests will fail.
|
||||
.SH AUTHOR
|
||||
Concept, design, and original implementation by
|
||||
Daniel Weaver <danw@znyx.com>. Portions of the code and
|
||||
documentation are by Eric S. Raymond <esr@snark.thyrsus.com>.
|
||||
.\"#
|
||||
.\"# The following sets edit modes for GNU EMACS
|
||||
.\"# Local Variables:
|
||||
.\"# mode:nroff
|
||||
.\"# fill-column:79
|
||||
.\"# End:
|
@ -1,603 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <tack.h>
|
||||
|
||||
MODULE_ID("$Id: tack.c,v 1.4 2005/09/17 19:49:16 tom Exp $")
|
||||
|
||||
/*
|
||||
This program is designed to test terminfo, not curses. Therefore
|
||||
I have used as little of curses as possible.
|
||||
|
||||
Pads associated with the following capabilities are used to set
|
||||
delay times in the handler: (cr), (ind), (cub1), (ff), (tab).
|
||||
|
||||
I use the (nxon) capability to set the tty handler with/without
|
||||
xon/xoff. If (smxon)/(rmxon) is defined I will change the terminal
|
||||
too.
|
||||
|
||||
(xon) inhibits the sending of delay characters in putp().
|
||||
If the terminal is defined with no padding then the (xon) boolean
|
||||
is a don't care. In this case I recommend that it be reset.
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Option processing
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* options and modes */
|
||||
int debug_level; /* debugging level */
|
||||
int translate_mode; /* translate tab, bs, cr, lf, ff */
|
||||
int scan_mode; /* use scan codes */
|
||||
int char_mask; /* either 0xFF else 0x7F, eight bit data mask */
|
||||
int select_delay_type; /* set handler delays for <cr><lf> */
|
||||
int select_xon_xoff; /* TTY driver XON/XOFF mode select */
|
||||
int hex_out; /* Display output in hex */
|
||||
int send_reset_init; /* Send the reset and initialization strings */
|
||||
FILE *log_fp; /* Terminal logfile */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Menu definitions
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void tools_hex_echo(struct test_list *, int *, int *);
|
||||
static void tools_debug(struct test_list *, int *, int *);
|
||||
|
||||
static char hex_echo_menu_entry[80];
|
||||
|
||||
static struct test_list tools_test_list[] = {
|
||||
{0, 0, 0, 0, "s) ANSI status reports", tools_status, 0},
|
||||
{0, 0, 0, 0, "g) ANSI SGR modes (bold, underline, reverse)", tools_sgr, 0},
|
||||
{0, 0, 0, 0, "c) ANSI character sets", tools_charset, 0},
|
||||
{0, 0, 0, 0, hex_echo_menu_entry, tools_hex_echo, 0},
|
||||
{0, 0, 0, 0, "e) echo tool", tools_report, 0},
|
||||
{1, 0, 0, 0, "r) reply tool", tools_report, 0},
|
||||
{0, 0, 0, 0, "p) performance testing", 0, &sync_menu},
|
||||
{0, 0, 0, 0, "i) send reset and init", menu_reset_init, 0},
|
||||
{0, 0, "u8) (u9", 0, "u) test ENQ/ACK handshake", sync_handshake, 0},
|
||||
{0, 0, 0, 0, "d) change debug level", tools_debug, 0},
|
||||
{MENU_LAST, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static struct test_menu tools_menu = {
|
||||
0, 'q', 0, "Tools Menu", "tools",
|
||||
0, 0, tools_test_list, 0, 0, 0
|
||||
};
|
||||
|
||||
static void tty_width(struct test_list *, int *, int *);
|
||||
static void tty_delay(struct test_list *, int *, int *);
|
||||
static void tty_xon(struct test_list *, int *, int *);
|
||||
static void tty_trans(struct test_list *, int *, int *);
|
||||
static void tty_show_state(struct test_menu *);
|
||||
|
||||
static char tty_width_menu[80];
|
||||
static char tty_delay_menu[80];
|
||||
static char tty_xon_menu[80];
|
||||
static char tty_trans_menu[80];
|
||||
static char enable_xon_xoff[] = {"x) enable xon/xoff"};
|
||||
static char disable_xon_xoff[] = {"x) disable xon/xoff"};
|
||||
|
||||
static struct test_list tty_test_list[] = {
|
||||
{0, 0, 0, 0, tty_width_menu, tty_width, 0},
|
||||
{0, 0, 0, 0, tty_delay_menu, tty_delay, 0},
|
||||
{0, 0, 0, 0, tty_xon_menu, tty_xon, 0},
|
||||
{0, 0, 0, 0, tty_trans_menu, tty_trans, 0},
|
||||
{MENU_LAST, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static struct test_menu tty_menu = {
|
||||
0, 'q', 0, "Terminal and driver configuration",
|
||||
"tty", 0,
|
||||
tty_show_state, tty_test_list, 0, 0, 0
|
||||
};
|
||||
|
||||
struct test_menu edit_menu = {
|
||||
0, 'q', 0, "Edit terminfo menu",
|
||||
"edit", 0,
|
||||
0, edit_test_list, 0, 0, 0
|
||||
};
|
||||
|
||||
static struct test_menu mode_menu = {
|
||||
0, 'n', 0, "Test modes and glitches:",
|
||||
"mode", "n) run standard tests",
|
||||
0, mode_test_list, 0, 0, 0
|
||||
};
|
||||
|
||||
static struct test_menu acs_menu = {
|
||||
0, 'n', 0,
|
||||
"Test alternate character set and graphics rendition:",
|
||||
"acs", "n) run standard tests",
|
||||
0, acs_test_list, 0, 0, 0
|
||||
};
|
||||
|
||||
static struct test_menu color_menu = {
|
||||
0, 'n', 0,
|
||||
"Test color:",
|
||||
"color", "n) run standard tests",
|
||||
0, color_test_list, 0, 0, 0
|
||||
};
|
||||
|
||||
static struct test_menu crum_menu = {
|
||||
0, 'n', 0,
|
||||
"Test cursor movement:",
|
||||
"move", "n) run standard tests",
|
||||
0, crum_test_list, 0, 0, 0
|
||||
};
|
||||
|
||||
static struct test_menu funkey_menu = {
|
||||
0, 'n', 0,
|
||||
"Test function keys:",
|
||||
"fkey", "n) run standard tests",
|
||||
sync_test, funkey_test_list, 0, 0, 0
|
||||
};
|
||||
|
||||
static struct test_menu printer_menu = {
|
||||
0, 'n', 0,
|
||||
"Test printer:",
|
||||
"printer", "n) run standard tests",
|
||||
0, printer_test_list, 0, 0, 0
|
||||
};
|
||||
|
||||
static void pad_gen(struct test_list *, int *, int *);
|
||||
|
||||
static struct test_menu pad_menu = {
|
||||
0, 'n', 0,
|
||||
"Test padding and string capabilities:",
|
||||
"pad", "n) run standard tests",
|
||||
sync_test, pad_test_list, 0, 0, 0
|
||||
};
|
||||
|
||||
static struct test_list normal_test_list[] = {
|
||||
{0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu},
|
||||
{0, 0, 0, 0, "i) send reset and init", menu_reset_init, 0},
|
||||
{MENU_NEXT, 0, 0, 0, "x) test modes and glitches", 0, &mode_menu},
|
||||
{MENU_NEXT, 0, 0, 0, "a) test alternate character set and graphic rendition", 0, &acs_menu},
|
||||
{MENU_NEXT, 0, 0, 0, "c) test color", 0, &color_menu},
|
||||
{MENU_NEXT, 0, 0, 0, "m) test cursor movement", 0, &crum_menu},
|
||||
{MENU_NEXT, 0, 0, 0, "f) test function keys", 0, &funkey_menu},
|
||||
{MENU_NEXT, 0, 0, 0, "p) test padding and string capabilities", 0, &pad_menu},
|
||||
{0, 0, 0, 0, "P) test printer", 0, &printer_menu},
|
||||
{MENU_MENU, 0, 0, 0, "/) test a specific capability", 0, 0},
|
||||
{0, 0, 0, 0, "t) auto generate pad delays", pad_gen, &pad_menu},
|
||||
{0, 0, "u8) (u9", 0, 0, sync_handshake, 0},
|
||||
{MENU_LAST, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
static struct test_menu normal_menu = {
|
||||
0, 'n', 0, "Main test menu",
|
||||
"test", "n) run standard tests",
|
||||
0, normal_test_list, 0, 0, 0
|
||||
};
|
||||
|
||||
static void start_tools(struct test_list *, int *, int *);
|
||||
static void start_modes(struct test_list *, int *, int *);
|
||||
static void start_basic(struct test_list *, int *, int *);
|
||||
static void start_log(struct test_list *, int *, int *);
|
||||
|
||||
static char logging_menu_entry[80] = "l) start logging";
|
||||
|
||||
static struct test_list start_test_list[] = {
|
||||
{0, 0, 0, 0, "b) display basic information", start_basic, 0},
|
||||
{0, 0, 0, 0, "m) change modes", start_modes, 0},
|
||||
{0, 0, 0, 0, "t) tools", start_tools, 0},
|
||||
{MENU_COMPLETE, 0, 0, 0, "n) begin testing", 0, &normal_menu},
|
||||
{0, 0, 0, 0, logging_menu_entry, start_log, 0},
|
||||
{MENU_LAST, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
static struct test_menu start_menu = {
|
||||
0, 'n', 0, "Main Menu", "tack", 0,
|
||||
0, start_test_list, 0, 0, 0
|
||||
};
|
||||
|
||||
static struct test_list write_terminfo_list[] = {
|
||||
{0, 0, 0, 0, "w) write the current terminfo to a file", save_info, 0},
|
||||
{MENU_LAST, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Menu command interpretation.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
** tools_hex_echo(testlist, state, ch)
|
||||
**
|
||||
** Flip the hex echo flag.
|
||||
*/
|
||||
static void
|
||||
tools_hex_echo(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch GCC_UNUSED)
|
||||
{
|
||||
if (hex_out) {
|
||||
hex_out = FALSE;
|
||||
strcpy(hex_echo_menu_entry,
|
||||
"h) enable hex output on echo tool");
|
||||
} else {
|
||||
hex_out = TRUE;
|
||||
strcpy(hex_echo_menu_entry,
|
||||
"h) disable hex output on echo tool");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** tools_debug(testlist, state, ch)
|
||||
**
|
||||
** Change the debug level.
|
||||
*/
|
||||
static void
|
||||
tools_debug(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
ptext("Enter a new value: ");
|
||||
read_string(buf, sizeof(buf));
|
||||
if (buf[0]) {
|
||||
sscanf(buf, "%d", &debug_level);
|
||||
}
|
||||
sprintf(temp, "Debug level is now %d", debug_level);
|
||||
ptext(temp);
|
||||
*ch = REQUEST_PROMPT;
|
||||
}
|
||||
|
||||
/*
|
||||
** start_tools(testlist, state, ch)
|
||||
**
|
||||
** Run the generic test tools
|
||||
*/
|
||||
static void
|
||||
start_tools(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch GCC_UNUSED)
|
||||
{
|
||||
if (hex_out) {
|
||||
strcpy(hex_echo_menu_entry,
|
||||
"h) disable hex output on echo tool");
|
||||
} else {
|
||||
strcpy(hex_echo_menu_entry,
|
||||
"h) enable hex output on echo tool");
|
||||
}
|
||||
menu_display(&tools_menu, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** tty_show_state()
|
||||
**
|
||||
** Display the current state on the tty driver settings
|
||||
*/
|
||||
static void
|
||||
tty_show_state(
|
||||
struct test_menu *menu GCC_UNUSED)
|
||||
{
|
||||
put_crlf();
|
||||
(void) sprintf(temp,
|
||||
"Accepting %d bits, UNIX delays %d, XON/XOFF %sabled, speed %u, translate %s, scan-code mode %s.",
|
||||
(char_mask == ALLOW_PARITY) ? 8 : 7,
|
||||
select_delay_type,
|
||||
select_xon_xoff ? "en" : "dis",
|
||||
tty_baud_rate,
|
||||
translate_mode ? "on" : "off",
|
||||
scan_mode ? "on" : "off");
|
||||
ptextln(temp);
|
||||
put_crlf();
|
||||
}
|
||||
|
||||
/*
|
||||
** tty_width(testlist, state, ch)
|
||||
**
|
||||
** Change the character width
|
||||
*/
|
||||
static void
|
||||
tty_width(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch GCC_UNUSED)
|
||||
{
|
||||
if (char_mask == STRIP_PARITY) {
|
||||
char_mask = ALLOW_PARITY;
|
||||
strcpy(tty_width_menu, "7) treat terminal as 7-bit");
|
||||
} else {
|
||||
char_mask = STRIP_PARITY;
|
||||
strcpy(tty_width_menu, "8) treat terminal as 8-bit");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** tty_delay(testlist, state, ch)
|
||||
**
|
||||
** Change the delay for <cr><lf> in the TTY driver
|
||||
*/
|
||||
static void
|
||||
tty_delay(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch GCC_UNUSED)
|
||||
{
|
||||
if (select_delay_type) {
|
||||
select_delay_type = FALSE;
|
||||
strcpy(tty_delay_menu,
|
||||
"d) enable UNIX tty driver delays for <cr><lf>");
|
||||
} else {
|
||||
select_delay_type = TRUE;
|
||||
strcpy(tty_delay_menu,
|
||||
"d) disable UNIX tty driver delays for <cr><lf>");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** tty_xon(testlist, state, ch)
|
||||
**
|
||||
** Change the XON/XOFF flags in the TTY driver
|
||||
*/
|
||||
static void
|
||||
tty_xon(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch GCC_UNUSED)
|
||||
{
|
||||
if (select_xon_xoff) {
|
||||
if (needs_xon_xoff) {
|
||||
ptextln("This terminal is marked as needing XON/XOFF protocol with (nxon)");
|
||||
}
|
||||
if (exit_xon_mode) {
|
||||
tc_putp(exit_xon_mode);
|
||||
}
|
||||
xon_xoff = select_xon_xoff = FALSE;
|
||||
strcpy(tty_xon_menu, enable_xon_xoff);
|
||||
} else {
|
||||
if (enter_xon_mode) {
|
||||
tc_putp(enter_xon_mode);
|
||||
}
|
||||
xon_xoff = select_xon_xoff = TRUE;
|
||||
strcpy(tty_xon_menu, disable_xon_xoff);
|
||||
}
|
||||
tty_set();
|
||||
}
|
||||
|
||||
/*
|
||||
** tty_trans(testlist, state, ch)
|
||||
**
|
||||
** Change the translation mode for special characters
|
||||
*/
|
||||
static void
|
||||
tty_trans(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch GCC_UNUSED)
|
||||
{
|
||||
if (translate_mode) {
|
||||
translate_mode = FALSE;
|
||||
strcpy(tty_trans_menu,
|
||||
"t) use terminfo values for \\b\\f\\n\\r\\t");
|
||||
} else {
|
||||
translate_mode = TRUE;
|
||||
strcpy(tty_trans_menu,
|
||||
"t) override terminfo values for \\b\\f\\n\\r\\t");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** pad_gen(testlist, state, ch)
|
||||
**
|
||||
** Menu function for automatic pad generation
|
||||
*/
|
||||
static void
|
||||
pad_gen(
|
||||
struct test_list *t,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
control_init();
|
||||
if (tty_can_sync == SYNC_NOT_TESTED) {
|
||||
verify_time();
|
||||
}
|
||||
auto_pad_mode = TRUE;
|
||||
menu_display(t->sub_menu, ch);
|
||||
auto_pad_mode = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
** start_modes(testlist, state, ch)
|
||||
**
|
||||
** Change the TTY modes
|
||||
*/
|
||||
static void
|
||||
start_modes(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch GCC_UNUSED)
|
||||
{
|
||||
|
||||
if (select_delay_type) {
|
||||
strcpy(tty_delay_menu,
|
||||
"d) disable UNIX tty driver delays for <cr><lf>");
|
||||
} else {
|
||||
strcpy(tty_delay_menu,
|
||||
"d) enable UNIX tty driver delays for <cr><lf>");
|
||||
}
|
||||
if (char_mask == ALLOW_PARITY) {
|
||||
strcpy(tty_width_menu,
|
||||
"7) treat terminal as 7-bit");
|
||||
} else {
|
||||
strcpy(tty_width_menu,
|
||||
"8) treat terminal as 8-bit");
|
||||
}
|
||||
if (select_xon_xoff) {
|
||||
strcpy(tty_xon_menu, disable_xon_xoff);
|
||||
} else {
|
||||
strcpy(tty_xon_menu, enable_xon_xoff);
|
||||
}
|
||||
if (translate_mode) {
|
||||
strcpy(tty_trans_menu,
|
||||
"t) override terminfo values for \\b\\f\\n\\r\\t");
|
||||
} else {
|
||||
strcpy(tty_trans_menu,
|
||||
"t) use terminfo values for \\b\\f\\n\\r\\t");
|
||||
}
|
||||
menu_display(&tty_menu, 0);
|
||||
tty_set();
|
||||
}
|
||||
|
||||
/*
|
||||
** start_basic(testlist, state, ch)
|
||||
**
|
||||
** Display basic terminal information
|
||||
*/
|
||||
static void
|
||||
start_basic(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch)
|
||||
{
|
||||
display_basic();
|
||||
*ch = REQUEST_PROMPT;
|
||||
}
|
||||
|
||||
/*
|
||||
** start_log(testlist, state, ch)
|
||||
**
|
||||
** Start/stop in logging function
|
||||
*/
|
||||
static void
|
||||
start_log(
|
||||
struct test_list *t GCC_UNUSED,
|
||||
int *state GCC_UNUSED,
|
||||
int *ch GCC_UNUSED)
|
||||
{
|
||||
if (logging_menu_entry[5] == 'a') {
|
||||
ptextln("The log file will capture all characters sent to the terminal.");
|
||||
if ((log_fp = fopen("tack.log", "w"))) {
|
||||
ptextln("Start logging to file: tack.log");
|
||||
strcpy(logging_menu_entry, "l) stop logging");
|
||||
} else {
|
||||
ptextln("File open error: tack.log");
|
||||
}
|
||||
} else {
|
||||
if (log_fp) {
|
||||
fclose(log_fp);
|
||||
log_fp = 0;
|
||||
}
|
||||
ptextln("Terminal output logging stopped.");
|
||||
strcpy(logging_menu_entry, "l) start logging");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** show_usage()
|
||||
**
|
||||
** Tell the user how its done.
|
||||
*/
|
||||
void
|
||||
show_usage(
|
||||
char *name)
|
||||
{
|
||||
(void) fprintf(stderr, "usage: %s [-itV] [term]\n", name);
|
||||
}
|
||||
|
||||
/*
|
||||
** print_version()
|
||||
**
|
||||
** Print version and other useful information.
|
||||
*/
|
||||
void
|
||||
print_version(void)
|
||||
{
|
||||
printf("tack version %d.%02d\n", MAJOR_VERSION, MINOR_VERSION);
|
||||
printf("Copyright (C) 1997 Free Software Foundation, Inc.\n");
|
||||
printf("Tack comes with NO WARRANTY, to the extent permitted by law.\n");
|
||||
printf("You may redistribute copies of Tack under the terms of the\n");
|
||||
printf("GNU General Public License. For more information about\n");
|
||||
printf("these matters, see the file named COPYING.\n");
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Main sequence
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int i, j;
|
||||
char *term_variable;
|
||||
|
||||
/* scan the option flags */
|
||||
send_reset_init = TRUE;
|
||||
translate_mode = FALSE;
|
||||
term_variable = getenv("TERM");
|
||||
tty_can_sync = SYNC_NOT_TESTED;
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
for (j = 1; argv[i][j]; j++) {
|
||||
switch (argv[i][j]) {
|
||||
case 'V':
|
||||
print_version();
|
||||
return (1);
|
||||
case 'i':
|
||||
send_reset_init = FALSE;
|
||||
break;
|
||||
case 't':
|
||||
translate_mode = FALSE;
|
||||
break;
|
||||
default:
|
||||
show_usage(argv[0]);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
term_variable = argv[i];
|
||||
}
|
||||
}
|
||||
(void) strcpy(tty_basename, term_variable);
|
||||
|
||||
curses_setup(argv[0]);
|
||||
|
||||
menu_can_scan(&normal_menu); /* extract which caps can be tested */
|
||||
menu_display(&start_menu, 0);
|
||||
|
||||
if (user_modified()) {
|
||||
sprintf(temp, "Hit y to save changes to file: %s ? ",
|
||||
tty_basename);
|
||||
ptext(temp);
|
||||
if (wait_here() == 'y') {
|
||||
save_info(write_terminfo_list, &i, &j);
|
||||
}
|
||||
}
|
||||
|
||||
put_str("\nTerminal test complete\n");
|
||||
bye_kids(0);
|
||||
return (0);
|
||||
}
|
@ -1,428 +0,0 @@
|
||||
/*
|
||||
** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
**
|
||||
** This file is part of TACK.
|
||||
**
|
||||
** TACK 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, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** TACK 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 TACK; see the file COPYING. If not, write to
|
||||
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
** Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* $Id: tack.h,v 1.16 2006/11/25 23:45:00 tom Exp $ */
|
||||
|
||||
#ifndef NCURSES_TACK_H_incl
|
||||
#define NCURSES_TACK_H_incl 1
|
||||
|
||||
/* terminfo action checker include file */
|
||||
|
||||
#define MAJOR_VERSION 1
|
||||
#define MINOR_VERSION 1
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <ncurses_cfg.h>
|
||||
#else
|
||||
#define RETSIGTYPE void
|
||||
#define GCC_UNUSED /*nothing*/
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
#define HAVE_SELECT 1
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
#define HAVE_SYS_TIME_SELECT 1
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <curses.h>
|
||||
#include <term_entry.h>
|
||||
#include <nc_tparm.h>
|
||||
|
||||
#if USE_RCS_IDS
|
||||
#define MODULE_ID(id) static const char Ident[] = id;
|
||||
#else
|
||||
#define MODULE_ID(id) /*nothing*/
|
||||
#endif
|
||||
|
||||
#if !HAVE_STRSTR
|
||||
extern char *_nc_strstr(const char *, const char *);
|
||||
#define strstr(h,n) _nc_strstr(h,n)
|
||||
#endif
|
||||
|
||||
#define CUR_TP (&(cur_term->type))
|
||||
#define MAX_STRINGS NUM_STRINGS(CUR_TP)
|
||||
#define STR_NAME(n) ExtStrname(CUR_TP,n,strnames)
|
||||
|
||||
#define UChar(c) ((unsigned char)(c))
|
||||
|
||||
extern FILE *log_fp;
|
||||
extern FILE *debug_fp;
|
||||
extern int debug_level;
|
||||
extern char temp[];
|
||||
extern char tty_basename[];
|
||||
extern char tty_shortname[];
|
||||
|
||||
#define SYNC_FAILED 0
|
||||
#define SYNC_TESTED 1
|
||||
#define SYNC_NOT_TESTED 2
|
||||
#define SYNC_NEEDED 3
|
||||
|
||||
extern int tty_can_sync;
|
||||
extern int total_pads_sent; /* count pad characters sent */
|
||||
extern int total_caps_sent; /* count caps sent */
|
||||
extern int total_printing_characters; /* count printing characters sent */
|
||||
extern int no_alarm_event; /* TRUE if the alarm has not gone off yet */
|
||||
extern unsigned long usec_run_time; /* length of last test in microseconds */
|
||||
extern int raw_characters_sent; /* Total output characters */
|
||||
|
||||
/* Stopwatch event timers */
|
||||
#define TIME_TEST 0
|
||||
#define TIME_SYNC 1
|
||||
#define TIME_FLUSH 2
|
||||
#define MAX_TIMERS 3
|
||||
|
||||
/* definitions for pad.c */
|
||||
|
||||
#define EXIT_CONDITION (no_alarm_event && (tt_delay_used < tt_delay_max))
|
||||
#define SLOW_TERMINAL_EXIT if (!test_complete && !EXIT_CONDITION) { break; }
|
||||
#define CAP_NOT_FOUND if (auto_pad_mode) return
|
||||
|
||||
extern char letters[26+1];
|
||||
#define NEXT_LETTER letter = letters[letter_number =\
|
||||
letters[letter_number + 1] ? letter_number + 1 : 0]
|
||||
|
||||
extern int test_complete; /* counts number of tests completed */
|
||||
extern char letter;
|
||||
extern int letter_number;
|
||||
extern int augment, repeats;
|
||||
extern long char_sent;
|
||||
extern const char *pad_repeat_test; /* commands that force repeat */
|
||||
|
||||
extern int replace_mode;
|
||||
extern int char_count, line_count, expand_chars;
|
||||
extern int can_go_home, can_clear_screen;
|
||||
|
||||
extern int translate_mode, scan_mode;
|
||||
extern int auto_pad_mode; /* TRUE for auto time tests */
|
||||
extern int char_mask;
|
||||
extern int hex_out; /* Display output in hex */
|
||||
|
||||
/* Parity bit macros */
|
||||
#define STRIP_PARITY 0x7f
|
||||
#define ALLOW_PARITY 0xff
|
||||
|
||||
/* select_delay_type: 0 -> reset all delays
|
||||
1 -> force long delays
|
||||
2 -> do not change the delays */
|
||||
extern int select_delay_type;
|
||||
|
||||
/* select_xon_xoff: 0 -> reset xon/xoff
|
||||
1 -> set xon/xoff
|
||||
2 -> do not change xon/xoff */
|
||||
extern int select_xon_xoff;
|
||||
|
||||
extern int tty_frame_size;
|
||||
extern unsigned tty_baud_rate;
|
||||
extern unsigned long tty_cps; /* The number of characters per second */
|
||||
extern int not_a_tty, nodelay_read;
|
||||
extern int send_reset_init;
|
||||
|
||||
/* definitions for stty_query() and initial_stty_query() */
|
||||
#define TTY_CHAR_MODE 0
|
||||
#define TTY_NOECHO 1
|
||||
#define TTY_OUT_TRANS 2
|
||||
#define TTY_8_BIT 3
|
||||
#define TTY_XON_XOFF 4
|
||||
|
||||
/* scan code definitions */
|
||||
#define MAX_SCAN 256
|
||||
|
||||
/* translate mode default strings */
|
||||
struct default_string_list {
|
||||
const char *name; /* terminfo name */
|
||||
const char *value; /* value of default string */
|
||||
int index; /* index into the strfname[] array */
|
||||
};
|
||||
|
||||
#define TM_last 8
|
||||
extern struct default_string_list TM_string[TM_last];
|
||||
|
||||
/* attribute structure definition */
|
||||
struct mode_list {
|
||||
const char *name;
|
||||
const char *begin_mode;
|
||||
const char *end_mode;
|
||||
int number;
|
||||
};
|
||||
|
||||
extern const struct mode_list alt_modes[];
|
||||
extern const int mode_map[];
|
||||
|
||||
/* Test data base */
|
||||
|
||||
#define FLAG_CAN_TEST 1
|
||||
#define FLAG_TESTED 2
|
||||
#define FLAG_LABEL 4
|
||||
#define FLAG_FUNCTION_KEY 8
|
||||
|
||||
/* caps under test data base */
|
||||
|
||||
#define TT_MAX 8
|
||||
#define MAX_CHANGES (TT_MAX+2)
|
||||
|
||||
extern int tt_delay_max; /* max number of milliseconds we can delay */
|
||||
extern int tt_delay_used; /* number of milliseconds consumed in delay */
|
||||
extern const char *tt_cap[TT_MAX]; /* value of string */
|
||||
extern int tt_affected[TT_MAX]; /* lines or columns effected (repetition
|
||||
factor) */
|
||||
extern int tt_count[TT_MAX]; /* Number of times sent */
|
||||
extern int tt_delay[TT_MAX]; /* Number of milliseconds delay */
|
||||
extern int ttp; /* number of entries used */
|
||||
|
||||
extern const char *tx_cap[TT_MAX]; /* value of string */
|
||||
extern int tx_affected[TT_MAX]; /* lines or columns effected (repetition
|
||||
factor) */
|
||||
extern int tx_count[TT_MAX]; /* Number of times sent */
|
||||
extern int tx_delay[TT_MAX]; /* Number of milliseconds delay */
|
||||
extern int tx_index[TT_MAX]; /* String index */
|
||||
extern int txp; /* number of entries used */
|
||||
extern int tx_characters; /* printing characters sent by test */
|
||||
extern unsigned long tx_cps; /* characters per second */
|
||||
|
||||
/*
|
||||
Menu control for tack.
|
||||
*/
|
||||
|
||||
struct test_results {
|
||||
struct test_results *next; /* point to next entry */
|
||||
struct test_list *test; /* Test which got these results */
|
||||
int reps; /* repeat count */
|
||||
int delay; /* delay times 10 */
|
||||
};
|
||||
|
||||
struct test_list {
|
||||
int flags; /* Test description flags */
|
||||
int lines_needed; /* Lines needed for test (0->no action) */
|
||||
const char *caps_done; /* Caps shown in Done message */
|
||||
const char *caps_tested; /* Other caps also being tested */
|
||||
const char *menu_entry; /* Menu entry text (optional) */
|
||||
/* Function that does testing */
|
||||
void (*test_procedure)(struct test_list *, int *, int *);
|
||||
struct test_menu *sub_menu; /* Nested sub-menu */
|
||||
};
|
||||
|
||||
struct test_menu {
|
||||
int flags; /* Menu feature flag */
|
||||
int default_action; /* Default command if <cr> <lf> entered */
|
||||
const char *menu_text; /* Describe this test_menu */
|
||||
const char *menu_title; /* Title for the menu */
|
||||
const char *ident; /* short menu name */
|
||||
const char *standard_tests; /* Standard test text */
|
||||
/* print current settings (optional) */
|
||||
void (*menu_function)(struct test_menu *);
|
||||
struct test_list *tests; /* Pointer to the menu/function pairs */
|
||||
struct test_list *resume_tests; /* Standard test resume point */
|
||||
int resume_state; /* resume state of test group */
|
||||
int resume_char; /* resume ch of test group */
|
||||
};
|
||||
|
||||
|
||||
/* menu flags */
|
||||
#define MENU_100c 0x00001a00 /* Augment 100% of columns */
|
||||
#define MENU_90c 0x00001900 /* Augment 90% of columns */
|
||||
#define MENU_80c 0x00001800 /* Augment 80% of columns */
|
||||
#define MENU_70c 0x00001700 /* Augment 70% of columns */
|
||||
#define MENU_60c 0x00001600 /* Augment 60% of columns */
|
||||
#define MENU_50c 0x00001500 /* Augment 50% of columns */
|
||||
#define MENU_40c 0x00001400 /* Augment 40% of columns */
|
||||
#define MENU_30c 0x00001300 /* Augment 30% of columns */
|
||||
#define MENU_20c 0x00001200 /* Augment 20% of columns */
|
||||
#define MENU_10c 0x00001100 /* Augment 10% of columns */
|
||||
#define MENU_LM1 0x00002e00 /* Augment lines - 1 */
|
||||
#define MENU_100l 0x00002a00 /* Augment 100% of lines */
|
||||
#define MENU_90l 0x00002900 /* Augment 90% of lines */
|
||||
#define MENU_50l 0x00002500 /* Augment 50% of lines */
|
||||
#define MENU_lines 0x00002000 /* Augment of lines */
|
||||
#define MENU_columns 0x00001000 /* Augment of columns */
|
||||
#define MENU_LC_MASK 0x00003000 /* Augment mask for lines and columns */
|
||||
#define MENU_1L 0x00002f00 /* Augment == one */
|
||||
#define MENU_1C 0x00001f00 /* Augment == one */
|
||||
#define MENU_ONE 0x00000f00 /* Augment == one */
|
||||
#define MENU_ONE_MASK 0x00000f00 /* Augment == one mask */
|
||||
#define MENU_REP_MASK 0x00003f00 /* Augment mask */
|
||||
|
||||
#define MENU_CLEAR 0x00010000 /* clear screen */
|
||||
#define MENU_INIT 0x00020000 /* Initialization function */
|
||||
#define MENU_NEXT 0x00040000 /* Next test in sequence */
|
||||
#define MENU_LAST 0x00080000 /* End of menu list */
|
||||
#define MENU_STOP 0x00100000 /* Stop testing next-in-sequence */
|
||||
#define MENU_COMPLETE 0x00200000 /* Test complete after this */
|
||||
#define MENU_MENU 0x00400000 /* Pass the menu name not test name */
|
||||
|
||||
#define REQUEST_PROMPT 256
|
||||
|
||||
/* tack.c */
|
||||
extern struct test_menu edit_menu;
|
||||
extern void show_usage(char *);
|
||||
extern void print_version(void);
|
||||
|
||||
/* output.c */
|
||||
extern char *expand(const char *);
|
||||
extern char *expand_command(const char *);
|
||||
extern char *expand_to(char *, int);
|
||||
extern char *hex_expand_to(char *, int);
|
||||
extern char *print_expand(char *);
|
||||
extern int getchp(int);
|
||||
extern int getnext(int);
|
||||
extern int tc_putch(int);
|
||||
extern int tc_putp(const char *);
|
||||
extern int wait_here(void);
|
||||
extern void go_home(void);
|
||||
extern void home_down(void);
|
||||
extern void maybe_wait(int);
|
||||
extern void ptext(const char *);
|
||||
extern void ptextln(const char *);
|
||||
extern void put_clear(void);
|
||||
extern void put_columns(const char *, int, int);
|
||||
extern void put_cr(void);
|
||||
extern void put_crlf(void);
|
||||
extern void put_dec(char *, int);
|
||||
extern void put_ind(void);
|
||||
extern void put_lf(void);
|
||||
extern void put_newlines(int);
|
||||
extern void put_str(const char *);
|
||||
extern void put_this(int);
|
||||
extern void putchp(int);
|
||||
extern void putln(const char *);
|
||||
extern void read_string(char *, int);
|
||||
extern void three_digit(char *, int);
|
||||
extern void tt_putp(const char *);
|
||||
extern void tt_putparm(NCURSES_CONST char *, int, int, int);
|
||||
extern void tt_tputs(const char *, int);
|
||||
|
||||
#define put_that(n) put_this((int) (n))
|
||||
|
||||
/* control.c */
|
||||
extern struct test_list color_test_list[];
|
||||
extern char *liberated(char *);
|
||||
extern char txt_longer_augment[80];
|
||||
extern char txt_longer_test_time[80];
|
||||
extern char txt_shorter_augment[80];
|
||||
extern char txt_shorter_test_time[80];
|
||||
extern int msec_cost(const char *const, int);
|
||||
extern int skip_pad_test(struct test_list *, int *, int *, const char *);
|
||||
extern int sliding_scale(int, int, unsigned long);
|
||||
extern int still_testing(void);
|
||||
extern long event_time(int);
|
||||
extern void control_init(void);
|
||||
extern void dump_test_stats(struct test_list *, int *, int *);
|
||||
extern void event_start(int);
|
||||
extern void longer_augment(struct test_list *, int *, int *);
|
||||
extern void longer_test_time(struct test_list *, int *, int *);
|
||||
extern void pad_test_shutdown(struct test_list *, int);
|
||||
extern void pad_test_startup(int);
|
||||
extern void page_loop(void);
|
||||
extern void set_augment_txt(void);
|
||||
extern void shorter_augment(struct test_list *, int *, int *);
|
||||
extern void shorter_test_time(struct test_list *, int *, int *);
|
||||
|
||||
/* charset.c */
|
||||
extern struct test_list acs_test_list[];
|
||||
extern void set_attr(int);
|
||||
extern void eat_cookie(void);
|
||||
extern void put_mode(char *);
|
||||
|
||||
/* crum.c */
|
||||
extern struct test_list crum_test_list[];
|
||||
|
||||
/* ansi.c */
|
||||
extern void tools_status(struct test_list *, int *, int *);
|
||||
extern void tools_charset(struct test_list *, int *, int *);
|
||||
extern void tools_sgr(struct test_list *, int *, int *);
|
||||
|
||||
/* edit.c */
|
||||
extern struct test_menu change_pad_menu;
|
||||
extern struct test_list edit_test_list[];
|
||||
extern char *get_string_cap_byname(const char *, const char **);
|
||||
extern int cap_match(const char *names, const char *cap);
|
||||
extern int get_string_cap_byvalue(const char *);
|
||||
extern int user_modified(void);
|
||||
extern void can_test(const char *, int);
|
||||
extern void cap_index(const char *, int *);
|
||||
extern void edit_init(void);
|
||||
extern void save_info(struct test_list *, int *, int *);
|
||||
extern void show_report(struct test_list *, int *, int *);
|
||||
|
||||
/* fun.c */
|
||||
extern struct test_list funkey_test_list[];
|
||||
extern struct test_list printer_test_list[];
|
||||
extern void enter_key(const char *, char *, char *);
|
||||
extern int tty_meta_prep(void);
|
||||
extern void tools_report(struct test_list *, int *, int *);
|
||||
|
||||
/* init.c */
|
||||
extern void reset_init(void);
|
||||
extern void display_basic(void);
|
||||
extern void put_name(const char *, const char *);
|
||||
extern void charset_can_test(void);
|
||||
extern void curses_setup(char *);
|
||||
extern void bye_kids(int);
|
||||
|
||||
/* scan.c */
|
||||
extern char **scan_up, **scan_down, **scan_name;
|
||||
extern int scan_key(void);
|
||||
extern unsigned scan_max; /* length of longest scan code */
|
||||
extern unsigned *scan_tested, *scan_length;
|
||||
extern void scan_init(char *fn);
|
||||
|
||||
/* sysdep.c */
|
||||
extern int initial_stty_query(int);
|
||||
extern int stty_query(int);
|
||||
extern void ignoresig(void);
|
||||
extern void read_key(char *, int);
|
||||
extern void set_alarm_clock(int);
|
||||
extern void spin_flush(void);
|
||||
extern void tty_init(void);
|
||||
extern void tty_raw(int, int);
|
||||
extern void tty_reset(void);
|
||||
extern void tty_set(void);
|
||||
|
||||
/* menu.c */
|
||||
extern char prompt_string[80]; /* menu prompt storage */
|
||||
extern int subtest_menu(struct test_list *, int *, int *);
|
||||
extern struct test_list *augment_test;
|
||||
extern void generic_done_message(struct test_list *, int *, int *);
|
||||
extern void menu_can_scan(const struct test_menu *);
|
||||
extern void menu_clear_screen(struct test_list *, int *, int *);
|
||||
extern void menu_display(struct test_menu *, int *);
|
||||
extern void menu_prompt(void);
|
||||
extern void menu_reset_init(struct test_list *, int *, int *);
|
||||
extern void pad_done_message(struct test_list *, int *, int *);
|
||||
|
||||
/* modes.c */
|
||||
extern struct test_list mode_test_list[];
|
||||
|
||||
/* pad.c */
|
||||
extern struct test_list pad_test_list[];
|
||||
|
||||
/* sync.c */
|
||||
extern struct test_menu sync_menu;
|
||||
extern int tty_sync_error(void);
|
||||
extern void flush_input(void);
|
||||
extern void sync_handshake(struct test_list *, int *, int *);
|
||||
extern void sync_test(struct test_menu *);
|
||||
extern void verify_time(void);
|
||||
|
||||
#endif /* NCURSES_TACK_H_incl */
|
Loading…
Reference in New Issue
Block a user