[comp.sources.amiga] v02i035: VT100 R2.7

doc@s.cc.purdue.edu (Craig Norborg) (10/03/87)

DBW and I have been exchanging e-mail about R2.7.  2 items came up WRT
bugs in the new version:

*  Swapping BS with DEL from an init file doesn't work quite right.
*  I believe that the old "file locking" bug is still with us.  In my
   attempt to move the requester I think I may have overlooked
   incorporating the fix into the code I was working from.


Tony Sumrall acs@amdahl.com <=> amdahl!acs

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# Xshar: Extended Shell Archiver.
# This is part  1 out of  3.
# This archive created: Sat Oct  3 01:36:26 1987
# By: Craig Norborg (Purdue University Computing Center)
#	Run the following text with /bin/sh to create:
#	Logon
#	Makefile
#	README
#	Xfer
#	vt100.doc
#	window.c
cat << \SHAR_EOF > Logon
DIAL:
	DELAY 3
	SEND "ATdt555-1221^M"
	ON "CONNECT" GOTO CONN
	DELAY 20
	SEND " "
	DELAY 1
#
	SEND "ATdt555-1222^M"
	ON "CONNECT" GOTO CONN
	DELAY 20
	SEND " "
	DELAY 1
#
	SEND "ATdt555-1223^M"
	ON "CONNECT" GOTO CONN
	DELAY 20
	SEND " "
	DELAY 1
#
	SEND "ATdt555-1224^M"
	ON "CONNECT" GOTO CONN
	DELAY 20
	SEND " "
	DELAY 1
	GOTO DIAL
#
CONN:
#   Send CRs till I get a login: prompt.
	SEND ^M
	ON "login:" GOTO LOGIN
	DELAY 3
	GOTO CONN
LOGIN:
#  Send my username and my "password", reply to first prompt.
	SEND "acs^M"
	WAIT "assword:"
	SEND "mypass^M"
	WAIT "#?"
	SEND "1^M"
	WAIT "=> "
#  Go to the source directory and send EVERYTHING then get off.
	SEND "cd vt100src/rel2.7^M"
	WAIT "=> "
	SEND "wermit^M"
	WAIT "mit>"
	SEND "send *^M"
	KR
	DELAY 5
	SEND "ex^M"
	WAIT "=> "
	SEND "logoff^M"
	WAIT "NO CARRIER"
	SEND "ATH^M"
	EXIT VT100

SHAR_EOF
cat << \SHAR_EOF > Makefile
######################################################################
#
# Makefile to build vt100 terminal emulator
#
#	v2.7 870825 ACS - See the README file
#	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
#	v2.5 870214 DBW - more additions (see readme file)
#	v2.4 861214 DBW - lots of fixes/additions (see readme file)
#	v2.3 861101 DBW - minor bug fixes
#	v2.2 861012 DBW	- more of the same
#	v2.1 860915 DBW - new features (see README)
#	     860823 DBW - Integrated and rewrote lots of code
#	v2.0 860809 DBW	- Major release.. LOTS of changes
# 	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
# 	v1.0 860712 DBW	- First version released
#
#
# Don't forget to define the right compiler (MANX or LATTICE) in VT100.H
#
######################################################################

OBJS	= vt100.o init.o window.o xmodem.o remote.o \
	  kermit.o script.o expand.o

vt100	: vt100.syms $(OBJS)
	ln -o vt100 $(OBJS) -lc

vt100-w	: vt100.syms $(OBJS)
	ln -w -o vt100-w $(OBJS) -lc

vt100.syms : vt100.h
	cc -A +Hvt100.syms vt100.h

vt100.o	: vt100.c
	cc +Ivt100.syms vt100.c

init.o	: init.c
	cc +Ivt100.syms init.c

window.o : window.c
	cc +Ivt100.syms window.c

xmodem.o : xmodem.c
	cc +Ivt100.syms xmodem.c

remote.o : remote.c
	cc +Ivt100.syms remote.c

kermit.o : kermit.c
	cc +Ivt100.syms kermit.c

script.o : script.c
	cc +Ivt100.syms script.c

expand.o : expand.c
	cc +Ivt100.syms expand.c
SHAR_EOF
cat << \SHAR_EOF > README
This archive contains a vt100 emulator with KERMIT and XMODEM file
transfer protocols.  Original work by Dave Wecker, V2.7 by Tony Sumrall.

Thanks:
-------
	To everyone who sent in code and suggestions!

Releases:
---------
	v2.7 870825 ACS - See Release Notes.
	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
	v2.5 870214 DBW - more additions (see readme file)
	v2.4 861214 DBW - lots of fixes/additions
	v2.3 861101 DBW - minor bug fixes
	v2.2 861012 DBW - more of the same
 	v2.1 860915 DBW - new features (see README)
	v2.0 860823 DBW - Major rewrite
	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
	v1.0 860712 DBW	- First version released

Usage:
------
	Please read VT100.DOC for usage information and examples.

Release Notes:
--------------
v2.7 870825 ACS - Requester is only used for input.  A new window (the
	  Info/Xfer Status window) now shows what used to go there and the
	  requester now comes up in this window.  The window is sizable,
	  draggable, closeable and front-to-backable; when re-opened it
	  will appear in its last location with its last dimensions.  The
	  window ignores input but will become active when it's first
	  displayed as well as when a requester is put up in it.  To
	  cancel a transfer request, first ensure that the mail VT100
	  windiw is active then hit ESC in it.
	- KERMIT mode has been hardened and wildcarded files can be sent
	  to a KERMIT that is *not* in server mode.  E.g. you may say
	  RECEIVE to your host's KERMIT then send Foo* -- all files
	  starting with Foo in the current directory will be sent.
	- New command line switches -i and +i.  -I says don't use an init
	  file, +i file says use "file".  User may also specify script
	  files on the command line which will be executed in sequence.
	- New init file command SHORTCUT.  See vt100.doc.
	- Nagging bug: On 2nd and subsequent uses of the requester, the
	  1st character of the last use is redisplayed.  Intuition bug?
v2.6 870227 DBW - bug fixes for all the stuff in v2.5
	- Input requestors are now self selecting (ignore comment in 2.5)
	- Added a BS<->DEL menu item and startup option (SWAP ON/OFF)
	- Renamed dopen/dnext/dclose to diropen/dirnext/dirclose for LATTICE
	- Added a CONVERT option that tells whether KERMIT should downcase
	- MAJOR CHANGE: re write the INPUT/SCRIPT commands, see VT100.DOC
	- Fixed a major problem with Set Directory causing LOCK conflicts
	- Moved the Title up 1 pixel so that it doesn't get cut off anymore
	- I've included the font code.  It looks for an env variable named
	  "font" (yes, lowercase) and, if found, uses that font for its
	  test.  If you don't like it you may wanna remove it.  I was gonna
	  ifdef it but I ran out of time.  Remember that there's a PD set
	  cmd to allow Lattice users to set env vars.

v2.5 870214 DBW - more additions (see readme file)
	- All prompting now done through a string requester/gadget.
	  NOTE: YOU MUST SELECT THE INPUT STRING OF THE REQUESTER BEFORE
		YOU CAN TYPE A RESPONSE.
	- Local echo mode added (half duplex for Carolyn)
	- BEEP command added to SCRIPT
	- New menu/init/script items:
		CLEAR SCREEN	- clears the screen
	 	ECHO		- turns on/off half duplex mode
		WRAP		- turns on/off autowrap on long lines
		NUMKEY		- turns on/off numeric keypad mode
		APPCUR		- turns on/off application cursor mode
	- Rewrote toasc() to use qualifier field (no more getting the
	  keyboard "stuck")
	- Fixed locking of directories (should now run under workbench ok)
	- Cleaned up VT100.H to really check includes on compile
	- Setting font explicitly to TOPAZ 8 (no more dumb assumptions)

v2.4 861214 DBW - lots of fixes/additions
	- Beep should now work under Lattice
	- CreatePort now passes longs (as it should always have)
	- Nested comments in KERMIT.C removed
	- Beep volume of 0 (DisplayBeep) now works
	- snum[] declaration in KERMIT.C fixed
	- multi_xfer is now void and return fixed (in kermit)
	- "." can no longer get "stuck" as the break key

	- RIGHT-AMIGA-keys have been added for most menu items
	- The ALT key is now an EIGHTth bit shifter
	- Control-@, Control-2, Control-space send the NULL character
	- Control-6 now sends Control-^
	- Control-- and Control-? now sends Control-_
	- Cursor application mode (<esc>[?1h and <esc>[?1l) now work
	- XMODEM now masks the eighth bit if parity is other than NONE

v2.3 861101 DBW - minor bug fixes:
	- added p_wbcolors to allow workbench colors on custom screen
	  (In the init file you can specify WBCOLORS to be NO (use color
	   definitions in INIT FILE or VT100.H) or YES (use WORKBENCH
	   colors for everything)).
	- "$" now sends a kermit-bye (like it says in VT100.DOC).
	- made window/screen heights more reasonable
	- Added ANSI insert line and delete line (<csi><num>L and
	  <csi><num>M) to speed up various editors (like emacs).
	  NOTE: This is NOT a VT100 sequence (new extension).
	- ctrl-space now also sends a null (along with ^@ and ^`)
	- RAWKEY fixed in WINDOW.C
	- p_wrap fixed in WINDOW.C
	- removed WRDMAX from VT100.H
	- fixed exit with no params in SCRIPT.C
	- fixed parity comparisons in KERMIT.C
	- init file [n+1] changed to [nplus1] to make Lattice happy.
	- cursoron(), cursoroff() changed to one routine cursorflip().
	- long lines shortened to less than 80 characters (for gateways).
	- blanks following exit (or comments) now work in scripts.

v2.2 861012 DBW - more of the same:
	- The INIT file "exit" can now chain to a script
	- The SCRIPT command "exit" can now chain to another script
	- Hangup menu item now works.
	- Autowrap can now be set from VT100.H, VT100.INIT (<esc>[?7h l)
	- Control-G is now handled with an audible beep
	- Script now used "^chr" to send control characters
	- The graphics "box" character (a) was added
	- Control-@ and Control-` now send the NULL character
	- Alternate color for BOLD has been re-instated by popular demand
	- Menus have been cleaned up.
	- Lattice compilation cleaned up.
	- No more wordsize parameter since PARITY takes care of all cases
	- Function keys can now call scripts
	- Double shift keys are now handled correctly.
	- Version has been added to the title bar (for bug reports).

v2.1 860915 DBW - new features / bug fixes
	- Now identifies as a VT100 (including the response to <esc>Z)
	- Cursor color now gets read in as hex (instead of decimal)
	- REPORTMOUSE taken out of definitions (not needed)
	- XON/XOFF now being handled by the device driver instead of me
	- Literal escape characters have been replaced with \033
	- At init time the user can now specify the input BUFFER size
	  (typically between 512 and 2048 bytes) depending on baud rate
	- Script files are now case insensitive for commands
	- XMODEM now turns off the driver XON/XOFF during transfers
	- Graphic rendition now done by the OS instead of me.
	- Initialization files are now searched for in S: instead of C:
	- Forward GOTO bug fixed in the script package.
	- Keypad can now be used in both numeric and application mode
	- General purpose cleanup() routine added for all exits.
	- Utility menu added (sendbreak, hangup, change directory).
	  NOTE: hangup is not implemented yet.
	- Full wild card support in file transfers (see vt100.doc).
	- Kermit cleaned up with better filename handling (from host).
	- Script now has CD (changed directory) and SB (send break) commands
	- Added Parity and Wordsize choices in VT100.H, VT100.INIT, menu
	  and scripts. (Generates parity from a table).
	- Added 8th bit quoting in KERMIT when using 7 bit words (ODD or
	  EVEN parity).
	- Break time can be set from VT100.H, VT100.INIT or a script file.
	- Transfer mode (image or CRLF) can now be set from a script file.
	- Control characters in escape sequences now act like a true VT100.
	- F10 now works from init files.
	- Right (or Left) AMIGA with period (".") sends a BREAK to the host
	  from the keyboard.
	- XMODEM status kept down to one line for a file transfer.

v2.0 860823 DBW	- Major rewrite:
	- Emulator now compiles under either MANX or LATTICE by defining
	  the appropriate compiler type in VT100.H.
	- Sped up code to an effective baud rate of (about) 8k. This means
	  that clear text at 4800 baud should be no problem.
	- Added XON/XOFF generation so that characters should not get lost
	  any more at 9600 baud (when receiving clear text).
	- Got rid of all command line switches and environment variables.
	  Instead upon invocation the program searches first for any file
	  named on the command line, then looks for VT100.INIT in the
	  current directory and finally searches for C:VT100.INIT.
	  All parameters can be set in the init file, and a sample VT100.INIT
	  is provided in VT100.DOC that shows all possible options.
	- All parameters that are set by VT100.INIT are defined in VT100.H
	  (variables starting with "p_"). This allows you to compile your
	  own defaults into the code.
	- You can now set the number of lines (for all you EMACS freaks :-).
	  On an interlaced screen this gives you upto a 48 line terminal.
	- WORKBENCH colors are NEVER touched.
	- In an attempt to keep the size down, the color palette menu item
	  has been removed (current). Code is about 36K in size with a
	  run time image (using workbench screen) of about 88k.
	- Many bugs fixed including reverse scrolling with descenders,
	  reverse video at end of line, clearing with scrolling regions,
		... and 20 or more others.
	- File capture now no longer sends the filename to the host.
	- BOLD (<esc>[1m) has now been added by using an additional color
	  when you specify a depth of 2 (instead of 1) bitplane.
	- UNDERLINE (<esc>[4m) has now been added.
	- The handling of remote (host) escape sequences has been completly
	  re-written (thanks to Dawn Banks for all the work).
	- Function keys (and shifted function keys) can now be bound to
	  arbitrary strings (Jim Ravan gets his macros). See VT100.DOC
	  for details.
	- Cursor has no been reduced to the size of a normal character for
	  easier readability.
	- XMODEM has been improved (by Steve Drew) to use a timer device
	  (for timeouts) and to abort immediately if the user types <ESC>.
	- KERMIT has been completely re-written and appears to work fine,
	  thanks to the efforts of Steve Drew.
	- New menu item allows script file support. Module written by
	  Steve Drew. See VT100.DOC for details.

Known problems:
---------------
	none

Suggestions/bug fixes not implemented (as of yet):
--------------------------------------------------
	- Custom screen should use a borderless backdrop window
	- Quit from keyboard should be supported (for above)
	- Automatic maximum sizing of window should happen
	- Screen should be resizable
	- AT TIME should be implemented in scripts (besides DELAY)
	- Kermit should create sub directories (when necessary)
	- Use the system keymap
	- Use a disk font for graphic character set
	- Allow the mouse to be sent to the host (for various EMACSs)
	- Kermit VM/CMS (IBM) protocol support

Installation:
-------------
	The files in this archive may be extracted by the bourne shell
	(/bin/sh) or the shar program using the "unshar switch (-u)",
	contact me if you need a copy of this version of shar.

	REMEMBER: Set the correct compiler definition in VT100.H

Files:
------
	README		- this file
	vt100.doc	- documentation for the terminal emulator
	makefile	- make file for the emulator (under MANX AZTEC-C)
	vt100.h		- include file used by all other modules
	window.c	- manager for window and keyboard
	vt100.c		- main module, handles menus
	remote.c	- handle remote characters (vt100 emulation)
	kermit.c	- kermit protocol (to transfer text files on VMS
			  select the CRLF option on the transfer mode menu,
			  otherwise use image mode).
	init.c		- startup code
	xmodem.c	- xmodem protocol that understands AMIGA binary and
			  text file formats (automatically).
	script.c	- script control package
	expand.c	- filename expansion (wildcards) and dir setting

Contact:
--------
Please send bugs/comments/suggestions/praise for V2.7 to:

	Tony Sumrall at USENET: acs@amdahl.com
SHAR_EOF
cat << \SHAR_EOF > Xfer
# Wait for my $PS1 then invoke my version of Kermit.
	WAIT "=> "
	SEND "wermit^M"
	WAIT "t>"
# Send all files beginning with "make" in the current directory.
	SEND "send make*^M"
	DELAY 3
	KR
	ON "t>" GOTO DONE
# Send a CR every so often.  When we get the Kermit prompt we're done.
WAITFORIT:
	DELAY 3
	SEND "^M"
	GOTO WAITFORIT
DONE:
	SEND "ex^M"
	EXIT
SHAR_EOF
cat << \SHAR_EOF > vt100.doc
This is the documentation file for the VT100 terminal emulator originally
by Dave Wecker.  Version 2.7 is by Tony Sumrall.  I can be reached  on
USENET => acs@amdahl.com

Dave can be reached via:

	Dave Wecker at	ENET:	COOKIE::WECKER
			ARPA:	wecker%cookie.dec.com@decwrl.dec.com
			USENET:	{decvax|decwrl}!cookie.dec.com!wecker
			SNAIL:	Dave Wecker
				115 Palm Springs Drive
				Colorado Springs, CO  80908

Note that Dave had NOTHING to do with this release.  Don't bother him with
problem in my code.


MANY pieces of code/suggestions have been sent in..

	thanks to all!

Program startup:
----------------
	1> vt100 [-i | +i initfile] [ scriptfile ... ]

                - -i option means don't look for an init file; +i means
                  look for an init file of this name.  The search for the
                  init file will be the current directory then S:.  Of
                  course you can always override this by saying C:file if
                  you like.  The format for the init file is described
                  later in this document.

		- The init file controls the setting of initial defaults
		  and screen and macro definitions.

		- If none of the files (listed above) are found, the
		  built-in defaults (defined in VT100.C as variables,
		  beginning with "p_") are used.

		- All commands are either menu or script based. Scripts
		  are described below.

Menus (Commands in parenthesis are default keyboard bindings: Right-Amiga-chr):
-----------------------------------------------------------------------
File 	  			- file transfers
	Ascii Capture		- Begin/end a script of the current session
	Ascii Send		- Type a file to the host
	Xmodem Receive	(A-V)	- Receive a file using XMODEM protocol
	Xmodem Send	(A-^)	- Send    a file using XMODEM protocol
	Kermit Get	(A-G)	- Receive files from a host KERMIT SERVER
	Kermit Receive	(A-R)	- Receive files from a host KERMIT
	Kermit Send	(A-S)	- Send    files to   a host KERMIT [SERVER]
	Kermit Bye	(A-B)	- Terminate a host KERMIT SERVER
Comm Setup			- Setup communications
	Baud Rate		- Set the terminal baud rate
		300
		1200	(A-L)
		2400	(A-H)
		4800
		9600
	Parity			- Type of parity
		NONE 	(A-X)
		MARK
		SPACE
		EVEN	(A-E)
		ODD	(A-O)
	Xfer Mode
		Image	(A-I)	- Send files verbatim (for UNIX hosts or
				  binary files)
		Text	(A-T)	- Send CR LF as line terminator and strip
				  CR on received files (VMS text).
		Convert		- Should KERMIT convert fnames to lower case
Script				- Script commands
	Execute Macro		- Start up an asynchronous script file
	Abort Execution		- Terminate a script file
Utility   			- Utility commands
	Send Break	(A-.)	- send a break to the host
	Hang Up			- close line (not implemented yet)
	Change Dir	(A-D)	- change the local directory (for transfers)
	Clear Scrn		- clear the screen (initial state)
	Echo			- turn on/off half duplex mode
	Wrap		(A-W)	- turn on/off long line wrapping mode
	Num Key		(A-K)	- turn on/off numeric keypad mode
	App Cur		(A-C)	- turn on/off application cursor mode
	BS<->DEL	(A-Z)	- swap backspace and delete keys

Keypad mapping (in application keypad mode):
--------------------------------------------

		AMIGA		VT100		comments
		-------		-------		---------------------------
		0-9	==	0-9
		.	==	.
		ENTER	==	ENTER		(basically, flip the bottom
		-	==	,		 2 keys up to get a VT100)
		HELP	==	-		(only free key around)
		f1-f4	==	PF1-PF4		(or any rebinding you do)
		arrows	==	arrows

Note:	Right AMIGA key in conjunction with a period (".")
	will send a break to the host.

	CTRL in conjunction with an at-sign ("@") a two ("2") or a
	space (" ") will send a NULL to the host.

	CTRL in conjunction with a six  ("6") will send a CTRL-^
	CTRL in conjunction with a dash ("-") or question mark ("?")
		will send a CTRL-_ to the host.

Multi file Xfers:
-----------------
The VT100 emulator supports multiple file transfers. This is
specified by using a comma (",") between file names when using XMODEM
or KERMIT. (NOTE: host XMODEM's normally CANNOT support multiple file
transfers).

When specifying a file name to recieve by default the directory path
is stripped off of the filename when sent to the host but is kept for the
local file spec. eg:

        receive file: ram:file.txt,df1:newfile.bin,$

will ask the server for file.txt and put it in ram:, and get
newfile.bin and put it on df1: (see explanation of "$" below). If you
do a single file transfer you will get another prompt for the remote
name e.g.:

        receive file: ram:file.txt
        remote file name [file.txt]:  userdisk1:wantfile.txt

The same rules apply to sending multiple files therefore if you are
doing multi file transfers make sure the host server is connected to
the desired directory.

In addition KERMIT supports wildcards:
    * = any number of characters
    ? = any single character
Examples:
	send:	*.c,*.h,*.doc
	get:	*.c,*.h,$

Note that in this release, wilcarded files may be sent to a KERMIT that is
*not* in server mode (e.g. you can say "RECEIVE" to the host KERMIT and
send *.c files successfully).

KERMIT receive is now smart enough to use the host filename so no
filename needs to be specified on the AMIGA's side (see the CONVERT option).

Initialization and Script file operation:
-----------------------------------------
An initialization file (as described in the "Program Startup" section)
may contain any of the commands shown below that have the word INIT in
their description below. Commands that are available from scripts have
the word SCRIPT in the descriptions below. All commands may be abbreviated
to 3 letters and are case insensitive.

The script file can be invoked by selecting 'execute file' from the
script menu. At any time you can abort the script file by selecting
'Abort Execution'. You may also invoke a script from a function key if
the first character of the function key definition is the KEYSCRIPT
character (e.g., define F5 as "~df1:foo.script").

During the time script file is running the terminal emulation is still
active and you may type simulataneous to the script file. This may be
desired if your script file is WAITing for a string or is DELAYing for
a period of time etc.

Initialization and Script file Commands:
----------------------------------------
#	Commented line					(INIT,SCRIPT)
   Format:
	# This line is a comment
------------------------------------------------------------
APPCUR	Set the application cursor mode			(INIT,SCRIPT)
   Format:
	APPCUR	ON/OFF or YES/NO
------------------------------------------------------------
ASCII_SEND Send an ascii file to the host.		(SCRIPT)
   Format:
	(same format as CAPTURE)
------------------------------------------------------------
BACKGROUND Define a background color			(INIT)
   Format:
	BACKGROUND hex		three digit hex number
   Example:
	BACKGROUND F00		bright red background
------------------------------------------------------------
BAUD 	Set baud rate					(INIT,SCRIPT)
   Format:
	BAUD rate		Sets the baud rate for send/receive
   Example:
	BAUD 2400		Sets the baud rate at 2400 baud
------------------------------------------------------------
BEEP	Beep at the console				(SCRIPT)
   Format:
	BEEP
------------------------------------------------------------
BOLD 	Define a color for bold				(INIT)
   Format:
	(same as BACKGROUND)
------------------------------------------------------------
BREAK	Set the break time (for an SB command)		(INIT,SCRIPT)
   Format:
	BREAK value		Value is in micro-seconds
   Example:
	BREAK 750000
------------------------------------------------------------
BUFFER 	Set transmission buffer size			(INIT)
   Format:
	BUFFER n		Number of bytes to buffer
   Example:
	BUFFER 512
------------------------------------------------------------
CAPTURE	To start/stop ascii file capture.		(SCRIPT)
   Format:
	CAPTURE	file		Start ascii capturing
	CAPTURE			End ascii capturing
------------------------------------------------------------
CD 	To change the local directory			(SCRIPT)
   Format:
	CD	newdir		set a new directory for file transfers
   Example:
	CD	DF1:foo/bar	set the directory as specified
------------------------------------------------------------
CONVERT	Tell KERMIT whether or not to convert filenames	(INIT,SCRIPT)
   Format:
	CONVERT	ON/OFF or YES/NO
   Example:
	CONVERT	ON		Filenames will be down cased
------------------------------------------------------------
CURSOR 	Define a color for the cursor			(INIT)
   Format:
	(same as BACKGROUND)
------------------------------------------------------------
DELAY 	Suspends script file for a specified time	(SCRIPT)
   Format:        
        DELAY 	n		Suspends execution for n seconds
   Example:
	DELAY	2		Suspends for 2 seconds
------------------------------------------------------------
DEPTH 	Define the depth of the window/screen		(INIT)
   Format:
	DEPTH n		Number of planes in window/screen
   Example:
	DEPTH 1		Minimum depth
	DEPTH 2		Same as Workbench
------------------------------------------------------------
ECHO	Turn on/off local echo				(INIT,SCRIPT)
   Format:
	ECHO	ON/OFF or YES/NO
   Example:
	ECHO	ON		Half duplex mode
------------------------------------------------------------
EXIT	Ends execution of the current script file.	(INIT,SCRIPT)
   Format:
	EXIT			Exit the current script/init file
	EXIT VT100		Exit vt100 program (from SCRIPT only)
	EXIT newscript		Exit this file and start up newscript
   Example:
	EXIT DF1:FOO.BAR	Exit the current file and start FOO.BAR
------------------------------------------------------------
F	Define a function key				(INIT,SCRIPT)
   Format:
	F n string		Define Function key n to be string
   Example:				(see SEND for string format)
	F 1 "dir^M"		Define F1 is the string dir<cr>
	F 11 "help"		Define Shifted F1 as the string help
	F 20 ^C			Define Shifted F10 as a control-C
------------------------------------------------------------
FOREGROUND Define a color for the foreground		(INIT)
   Format:
	(same as BACKGROUND)
------------------------------------------------------------
GOTO	Jumps to a different part of the script file.	(SCRIPT)
   Format:
	GOTO label		Jumps to a line beginning with label:
				Jumps may be forward or backward.
   Example:
	FOO:			Sets up a label
	...
	GOTO FOO		Jumps to FOO
------------------------------------------------------------
INTERLACE Turn on/off interlace				(INIT)
   Format:
	INTERLACE ON/OFF or YES/NO
   Example:
	INTERLACE ON		Use interlacing
------------------------------------------------------------
KB  	Send a BYE packet to a host KERMIT server.	(SCRIPT)
   Format:
	KB 			Shut down server.
------------------------------------------------------------
KEYSCRIPT Define a new keyscript character		(INIT,SCRIPT)
   Format:
	KEYSCRIPT hex		New character in hex
   Example:
	KEYSCRIPT 7E		Use "~" as the new character
------------------------------------------------------------
KG  	Gets files from host.				(SCRIPT)
   Format:
	(same format as KS)	 Get from server
------------------------------------------------------------
KR  	Receives a file from kermit host.		(SCRIPT)
   Format:
	(same format as KS)	 Not from a server
------------------------------------------------------------
KS  	Sends files via kermit to the host.		(SCRIPT)
   Format:
	KS file			Send one file
	KS file1,file2,...	Send multiple files
	KS file1,file2,...,$	Send multiple files and shut down server
   Example:
	KS foo.bar		sends foo.bar (note no quoting is used)
	KS foo1,foo2,foo3	sends three files
	KS foo1,foo2,foo3,$	sends three files and shuts down server
------------------------------------------------------------
LINES	Define number of lines in the window		(INIT)
   Format:
	LINES n
   Example:
	LINES 24		Maximum for non-interlace
	LINES 48		Maximum for interlaced
------------------------------------------------------------
MODE	Set a transfer mode for KERMIT to use		(INIT,SCRIPT)
   Format:
	MODE type		type of transfers to perform
   Example:
	MODE IMAGE		image mode transfers
	MODE CRLF		<CR><LF> text transfers (VMS Kermit).
------------------------------------------------------------
NUMKEY	Numeric keypad mode				(INIT,SCRIPT)
   Format:
	NUMKEY	ON/OFF or YES/NO
   Example:
	NUMKEY	ON		Keypad is pure numbers
------------------------------------------------------------
ON	Peforms a command every time string is received	(SCRIPT)
   Format:
        ON      "string"  cmd	Execute cmd when string is received.
				Only one ON string may be installed at a
				time.

  				If cmd is a GOTO and we were previously
				WAITing for a string the WAIT is aborted and
				execution resumes at the new label.

              			If cmd is not SEND and we were previously
				DELAYing, then the DELAY is aborted and the
				cmd is executed, followed by the next command
				after the DELAY.

				If cmd is a SEND and we were previously
				DELAYing, then the DELAY is continued.
   Example:
        ON  "LOSS CARRIER" GOTO RESTART
				If modem drops carrier, try to redial
        ON  "--more--" SEND " "
				Send a space every time --more-- is received
------------------------------------------------------------
PARITY	Sets the parity					(INIT,SCRIPT)
   Format:
	PARITY	type		Set the parity type
   Example:
	PARITY	NONE		no parity
	PARITY	MARK		mark parity
	PARITY	SPACE		space parity
	PARITY	ODD		odd parity
	PARITY	EVEN		even parity
------------------------------------------------------------
SB	Sends a break character to the host		(SCRIPT)
   Format:			Note that any pending character to send
	SB				is aborted by this call
------------------------------------------------------------
SCREEN	Define the screen type				(INIT)
   Format:
	SCREEN type		type of screen to use
   Example:
	SCREEN WORKBENCH	use the workbench screen
	SCREEN CUSTOM		use a custom screen
------------------------------------------------------------
SEND 	Sends a string or character to the host.	(SCRIPT)
   Format:
	SEND    "string"	Sends a string to the host. Beginning and
				ending double quotes (") are required. A
				carat (^) may be used to send control chars.
				Two carats transmits a carat character.
        SEND    chr           	Sends a single character.
        SEND    ^chr   	    	Sends a single control character. The chr
				is NOT case sensitve
   Example:
	SEND	"mail"		Send the string mail
	SEND    "dir^M"		Send the string dir followed by a <CR>
	SEND	a		Send the letter a
	SEND	^C		Send a control C
	SEND	"abc^^def"	Send the string abc^def
	SEND	^^		Send a control-uparrow
	SEND	"		Send the '"' character
------------------------------------------------------------
SHORTCUT set a new shortcut command key          (INIT)
   Format:
	SHORTCUT cmd key        Sets key "key" to be the shortcut key for
                                script command "cmd".  A null key will
                                cause no shortcut to be available for this
                                command (menu-option).  Cmd may be one of
                                the following:
			  >> File items:   <<
    CAP     - ascii capture on/off     ASC     - ascii send
    XR      - xmodem receive file      XS      - xmodem send file
    KG      - kermit get file          KR      - kermit receive file
    KS      - kermit send file         KB      - kermit bye (for server)
			  >> Comm items:   <<
    300     - Set Baud 300             1200    - Set Baud 1200
    2400    - Set Baud 2400            4800    - Set Baud 4800
    9600    - Set Baud 9600            NONE    - Set Parity none
    MARK    - Set Parity mark          SPACE   - Set Parity space
    EVEN    - Set Parity even          ODD     - Set Parity odd
    IMAGE   - KERMIT transfer mode     TEXT    - KERMIT transfer mode
    CONVERT - KERMIT transfer mode
			  >> Script items: <<
    EXECUTE - execute macro            ABORT   - abort macro
			  >> Util items:   <<
    SB      - send break               HANG    - hang up
    CD      - change directory         CLEAR   - clear screen
    ECH     - turn echo on or off      WRAP    - turn wrap on or off
    NUMKEY  - turn numeric kpad on/off APP     - turn app. cursor on/off
    CON     - convert bs to del        SWAP    - Swap BS and DEL

   Example:
	SHORTCUT ASC Q          set Right-Amiga-Q to be the shortcut for
                                ASCII_SEND.
	SHORTCUT XS             removes the shortcut key for sending via
                                XMODEM protocol
------------------------------------------------------------
SWAP 	Swap the meanings of backspace and delete keys	(INIT,SCRIPT)
   Format:
	SWAP ON/OFF or YES/NO
   Example:
	SWAP NO		Use standard definitions
------------------------------------------------------------
VOLUME	Set the BELL volume				(INIT)
   Format:
	VOLUME n
   Example:
	VOLUME 0		Use a visual bell
	VOLUME 64		Use a loud audible bell
------------------------------------------------------------
WAIT 	Suspends until a certain string is received.	(SCRIPT)
   Format:
	WAIT	"string"	Same rules for string as SEND
	WAIT			Enter an endless wait. Usually used after
				some "ON" commands have been set up. Can
				still be aborted via the script menu.
   Example:
        WAIT    "User:"    	Waits for the string User:
------------------------------------------------------------
WBCOLORS Force usage of workbench colors		(INIT)
   Format:
	WBCOLORS ON/OFF or YES/NO
   Example:
	WBCOLORS YES		Workbebch colors will be used for all
------------------------------------------------------------
WRAP	Set long line wrapping				(INIT,SCRIPT)
   Format:
	WRAP	ON/OFF or YES/NO
   Example:
	WRAP	ON		Long lines will wrap
------------------------------------------------------------
XR  	Receives a file via XMODEM.			(SCRIPT)
   Format:
	(same format as KS)
------------------------------------------------------------
XS  	Sends a file via XMODEM.			(SCRIPT)
   Format:
	(same format as KS)
------------------------------------------------------------


----------------------------
Initialization file example:
----------------------------

#####################################################################
#
#	VT100 sample initialization file
#       v2.7 870825 ACS
#
# Hash mark at the beginning of a line denotes a comment.
# White space (space(s) or tab(s)) delimit fields.
# Case ignored except for function key bindings.
#
# All items in this file overide variables of the same name in VT100.C
# (all variables in vt100.c have a "p_" prepended to them)
#
#####################################################################
#
APPCUR		ON		# Application keypad mode is being used
BACKGROUND	000		# Colors are in hex RGB from 000 to FFF
BAUD		2400		# Anything after required fields is ignored
BOLD		a00		# Color for bold highlighting (in custom)
BREAK		750000		# Break time in micro-seconds
BUFFER		512		# 512 <= Input buffer size <= 2048
CONVERT		ON		# KERMIT should downcase host names
CURSOR		00a		# Color for cursor (in custom screen)
DEPTH		1		# number of bit planes to use (1 or 2)
ECHO		OFF		# Full duplex mode in use
FOREGROUND	950		# Colors are only used on the custom screen
INTERLACE	ON		# ON for CUSTOM or interlaced workbench
KEYSCRIPT	7E		# Hex value for script introducer
LINES		48		# normal <= 24 interlaced <= 48
MODE		CRLF		# IMAGE or CRLF (for KERMIT transfers)
NUMKEY		ON		# The keypad should be numeric
PARITY		NONE		# NONE (= 8 bit), MARK, SPACE, ODD or EVEN
SCREEN		CUSTOM		# may be CUSTOM or WORKBENCH
SWAP		OFF		# Don't Swap the Back-space and Delete keys
VOLUME		64		# Beep Volume (0 = Visual Beep)
WBCOLORS	YES		# ignore custom colors and use defaults
WRAP		OFF		# Auto wrap ON or OFF
#   Remove the shortcut key for the CD command.  No comment on next line
# as it will be taken as the shortcut key.
SHORTCUT        CD
#
# Function bindings (strings to type when any of F1 - F10 are pressed)
#	f <num>		= function key
#	f <num>+10	= shifted function key
#
# The string specified must be the same format as the SEND command:
#	^	= control next character
#	^^	= up arrow
#
# Sample control characters:
#	^[	= escape	^M	= carriage return
#	^J	= line feed	^L	= form feed
#
# If the first character of the string is a script introducer
# (KEYSCRIPT) then the string is interpreted as a script filename
# to be executed when the key is pressed.
#
# Examples of bindings:
#
f 1	"^[OP"			# f1-f4 = PF1 - PF4 on a VT100
f 2	"^[OQ"
f 3	"^[OR"
f 4	"^[OS"
#
# f5,6,7 = scripts to execute (assuming that KEYSCRIPT = '~' = 0x7E)
#
f 5	"~df1:vt100_source/dialwork.script"
f 6	"~df1:vt100_source/sendvt100.script"
f 7	"~df1:vt100_source/getpics.script"
#
f 8	"MAIL^M"		# Reads my mail (note embedded <CR>)
f 9	"NOTE^M"		# Reads conferences
f 11    "ATdt415-595-2479^M"    # dials the FAUG BBS
#
# all done with init, now execute script as startup sequence
#
exit df1:vt100_source/dialwork.script

--------------------
Script file example:
--------------------

###################################################################
# Script to dial work (dialwork.script)
#	v2.6	870222	DBW
###################################################################
#
# Make sure that we have all the parameters we want
#
	DELAY	2
	BAUD	2400
	PARITY	NONE
	MODE	CRLF
	BREAK	750000
	SB
#
# First get the modem's attention:
#
Start:
	DELAY 1
	ON "Ready" GOTO Dial
	SEND ^B
	DELAY 2
	GOTO Start
#
# Now dial the 2400 baud line to work:
#
Dial:
	ON "Attached" GOTO Login
	SEND "$2400!"
	DELAY 30
	GOTO Start
#
# We got attached, so keep hitting return until the Gandalf terminal
# handler wakes up:
#
Login:
	ON "enter" GOTO Gandalf
	DELAY 1
	SEND ^M
	GOTO Login
#
# Now connect from the Gandalf to the terminal server (ts2):
# (when it asks for a password I need to type the password 
# manually here)
#
Gandalf:
	DELAY 2
	SEND "ts2^M"
	WAIT "class start"
#
# Keep sending <CR>'s until the LAT prompts for a username:
#
WaitLat:
	DELAY 2
	ON "username>" GOTO Lat
	SEND ^M
	GOTO WaitLat
#
# Tell the LAT that it's me, and connect to the "cookie cluster"
# (my host systems). Tell the cluster my user name.
# (when it asks for a password I need to type the password
# manually here)
#
Lat:
	SEND "wecker^M"
	DELAY 1
	SEND "connect cookie^M"
	WAIT "Username:"
	SEND "WECKER^M"
	WAIT "at home"
	SEND "^M^Mn^M"
#
# Got through all the LOGIN garbage, so let's do some work.
#
	WAIT "$ "
#
# All done so stop:
#
	EXIT
SHAR_EOF
cat << \SHAR_EOF > window.c
/****************************************************
 * vt100 emulator - window/keyboard support
 *
 *	v2.7 870825 ACS - Provide an info/status window rather than using
 *			  req().  Better error handling.
 *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
 *	v2.5 870214 DBW - more additions (see readme file)
 *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
 *	v2.3 861101 DBW - minor bug fixes
 *	v2.2 861012 DBW - more of the same
 *	v2.1 860915 DBW - new features (see README)
 *	     860823 DBW - Integrated and rewrote lots of code
 *	v2.0 860809 DBW - Major rewrite
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 ****************************************************/

#include "vt100.h"

/* keyboard definitions for toasc() */
static char keys[75] = {
    '`','1','2','3','4','5','6','7','8','9','0','-' ,
    '=','\\', 0, '0','q','w','e','r','t','y','u','i','o' ,
    'p','[',']', 0, '1','2','3','a','s','d','f','g','h' ,
    'j','k','l',';','\'', 0, 0, '4','5','6', 0, 'z','x','c','v',
    'b','n','m',44,'.','/', 0, '.','7','8','9',' ',8,
    '\t',13,13,27,127,0,0,0,'-' } ;
    
/* For InfoMsg...may be changed by a NEWSIZE msg in vt100.c */
int reqminx,	/* Min value for x in reqwindow (pixels) */
    reqmaxx,	/* Max value for x in reqwindow (pixels) */
    reqmaxlen,	/* Max # chars in reqwindow */
    reqminy,	/* Min value for y in reqwindow (scan lines) */	
    reqmaxy,	/* Max value for y in reqwindow (scan lines) */
    reqfudge;	/* Clear space between border and start of 1st char */
int reqy;	/* Current pixel location in reqwindow */

void ReqNewSize(), OpenReqWindow();

/***************************************************
 *  function to swap the use of backspace and delete
 ***************************************************/

void swap_bs_del()
    {
    if (p_bs_del)   p_bs_del = 0;
    else	    p_bs_del = 1;

    keys[0x41] =    p_bs_del ? 127 : 8;
    keys[0x46] =    p_bs_del ? 8 : 127;
    }

/*************************************************
 *  function to get file name (via a requestor)
 *************************************************/
void req(prmpt,name,getinp)
char *prmpt,*name;
int  getinp;
    {
    ULONG class;
    USHORT position, RemoveGadget();
    unsigned int code, qual;
    int  lprmpt, lname;
    struct IntuiMessage *Msg;

    if(reqwinup == 0)
	OpenReqWindow();
    
    if(!getinp) {
    	InfoMsg2Line(prmpt, name);
    	return;
    }

    lprmpt = strlen(prmpt);
    lname = strlen(name);

    /* Don't use strings longer than what we've provided space for. */
    if(lprmpt > (MAXGADSTR-1)) {
	emits("Prompt too long - truncated.\n");
	lprmpt = MAXGADSTR-1;
    }
    if(lname > (MAXGADSTR-1)) {
	emits("Name too long - truncated.\n");
	lname = MAXGADSTR-1;
    }

    if (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
	class = Msg->Class;
	ReplyMsg(Msg);
	if(class == REQCLEAR)
	    numreqs = 0;
	if(class == NEWSIZE)
	    ReqNewSize(reqwindow->Height, reqwindow->Width);
    }

    /* Make sure the prompt gets updated */
    if (numreqs == 1 && strcmp(Prompt,prmpt) != 0) {
	EndRequest(&myrequest,reqwindow);
	do {
		Wait(1L << reqwindow->UserPort->mp_SigBit);
		while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
			class = Msg->Class;
			ReplyMsg(Msg);
			if(class == NEWSIZE)
			    ReqNewSize(reqwindow->Height, reqwindow->Width);
		}
	} while (class != REQCLEAR);
	numreqs = 0;
	}

    /* copy in a prompt and a default */
    strncpy(Prompt,prmpt,lprmpt); Prompt[lprmpt+1] = '\0';
    strncpy(InpBuf,name,lname); InpBuf[lname+1] = '\0';

    if (numreqs == 1) {		/* If there is a requester... reuse it */
    	RefreshGadgets(&mystrgad, reqwindow, &myrequest);
    	Delay(2L);
    }
    else {			/* otherwise create it */
	while(numreqs != 1) {
            if (Request(&myrequest, reqwindow) == 0) {
		emits("ERROR - CAN'T CREATE REQUESTOR FOR:\n");
		emits(Prompt); emit('\n'); emits(InpBuf); emit('\n');
		return;
	    }
	    else numreqs = 1;

	    do {
		Wait(1L << reqwindow->UserPort->mp_SigBit);
		while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
		    class = Msg->Class;
		    ReplyMsg(Msg);
		    if(class == REQCLEAR)
			numreqs = 0;
		    if(class == NEWSIZE)
			ReqNewSize(reqwindow->Height, reqwindow->Width);
		}
	    } while (class != REQSET);
	} /* end while numreqs != 0 */
    } /* end else */

    /* if we don't want input, we're done */
    if (getinp == 0 || numreqs == 0) return;

    if((reqwindow->Flags & WINDOWACTIVE) != WINDOWACTIVE) {
    	WindowToFront(reqwindow);
	ActivateWindow(reqwindow);
	do {
	    Wait(1L << reqwindow->UserPort->mp_SigBit);
	    while(Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
		class = Msg->Class;
		ReplyMsg(Msg);
		if(class == NEWSIZE)
		    ReqNewSize(reqwindow->Height, reqwindow->Width);
	    }
	} while (class != ACTIVEWINDOW);
    }
    
    /* here is where we pre-select the gadget   */
    if (!ActivateGadget(&mystrgad,reqwindow,&myrequest)) {

	/* wait for his/her hands to get off the keyboard (Amiga-key) */
	Delay(20L);
	while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
	    ReplyMsg(Msg);
	    if(class == NEWSIZE)
		ReqNewSize(reqwindow->Height, reqwindow->Width);
	}

	/* try once more before giving up... */
	ActivateGadget(&mystrgad,reqwindow,&myrequest);
	}

    /* wait for input to show up */
    while (1) {
	if ((NewMessage = (struct IntuiMessage *)
		GetMsg(reqwindow->UserPort)) == FALSE) {
	    Wait(1L<<reqwindow->UserPort->mp_SigBit);
	    continue;
	    }
	class = NewMessage->Class;
	ReplyMsg(NewMessage);

	/* the requestor got terminated... yea!! */
	if (class == REQCLEAR) break;

	if(class == NEWSIZE)
	    ReqNewSize(reqwindow->Height, reqwindow->Width);
	    
	/* maybe this is a menu item to handle */
/*	if (class == MENUPICK) handle_menupick(class,code); */
	}

    /* all done, so return the result */
    numreqs = 0;
    strcpy(name,InpBuf);
    }

/*************************************************
*  function to print a string
*************************************************/
void emits(string)
char string[];
    {
    int i;
    char c;

    i=0;
    while (string[i] != 0)
	{
	c=string[i];
	if (c == 10) emit(13);
	emit(c);
	i += 1;
	}
    }

/*************************************************
*  function to output ascii chars to window
*************************************************/
void emit(c)
char c;
    {
    static char wrap_flag = 0;	/* are we at column 80? */

    c &= 0x7F;
    switch( c )
	{
	case '\t':
	x += 64 - ((x-MINX) % 64);
	break;

	case 10:  /* lf */
	y += 8;
	break;

	case 13:  /* cr */
	x = MINX;
	break;

	case 8:   /* backspace */
	x -= 8;
	if (x < MINX) x = MINX;
	break;

	case 12:     /* page */
	x = MINX;
	y = MINY;
	SetAPen(mywindow->RPort,0L);
	RectFill(mywindow->RPort,(long)MINX,
	    (long)(MINY-7),(long)(MAXX+7),(long)(MAXY+1));
	SetAPen(mywindow->RPort,1L);
	break;

	case 7:     /* bell */
	if (p_volume == 0) DisplayBeep(NULL);
	else {
	    BeginIO(&Audio_Request);
	    WaitIO(&Audio_Request);
	    }
	break;

	default:
	if (c < ' ' || c > '~') break;
	if (p_wrap && wrap_flag && x >= MAXX) {
	    x = MINX;
	    y += 8;
	    if (y > MAXY) {
		y = MAXY;
		ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
		    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
		}
	    }
	Move(mywindow->RPort,(long)x,(long)y);

	if (curmode&FSF_BOLD) {
	    if (p_depth > 1) {
		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
		SetSoftStyle(mywindow->RPort,(long)curmode,253L);
		}
	    else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
	    }
	else SetSoftStyle(mywindow->RPort,(long)curmode,255L);

	if (curmode&FSF_REVERSE) {
	    SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
	    Text(mywindow->RPort,&c,1L);
	    SetDrMd(mywindow->RPort,(long)JAM2);
	    }
	else Text(mywindow->RPort,&c,1L);

	if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
	x += 8;
	} /* end of switch */

    if (y > MAXY) {
	y = MAXY;
	x = MINX;
	ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
	    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
	}
    if (x > MAXX) {
	wrap_flag = 1;
	x = MAXX;
	}
    else wrap_flag = 0;
    }

/*************************************************
*  function to output ascii chars to window (batched)
*************************************************/
void emitbatch(la,lookahead)
int la;
char *lookahead;
    {
    int i;

    Move(mywindow->RPort,(long)x,(long)y);
    i = x / 8;
    if (i+la >= maxcol) {
	if (p_wrap == 0) la = maxcol - i;
	else {
	    lookahead[la] = 0;
	    emits(lookahead);
	    return;
	    }
	}
    if (curmode&FSF_BOLD) {
	if (p_depth > 1) {
	    SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
	    SetSoftStyle(mywindow->RPort,(long)curmode,253L);
	    }
	else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
	}
    else SetSoftStyle(mywindow->RPort,(long)curmode,255L);

    if (curmode&FSF_REVERSE) {
	SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
	Text(mywindow->RPort,lookahead,(long)la);
	SetDrMd(mywindow->RPort,(long)JAM2);
	}
    else Text(mywindow->RPort,lookahead,(long)la);
    if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
    x += (8 * la);
    }

/******************************
* Manipulate cursor
******************************/
void cursorflip()
    {
    SetDrMd(mywindow->RPort,(long)COMPLEMENT);
    SetAPen(mywindow->RPort,3L);
    RectFill(mywindow->RPort,
	(long)(x-1),(long)(y-6),(long)(x+8),(long)(y+1));
    SetAPen(mywindow->RPort,1L);
    SetDrMd(mywindow->RPort,(long)JAM2);
    }

/************************************************
*  function to take raw key data and convert it
*  into ascii chars
**************************************************/
int toasc(code,qual,local)
unsigned int code,qual;
int local;
    {
    unsigned int ctrl,shift,capsl,amiga,alt;
    char c = 0, keypad = 0;
    char *ptr;

    ctrl    = qual & IEQUALIFIER_CONTROL;
    capsl   = qual & IEQUALIFIER_CAPSLOCK;
    amiga   = qual & (IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND);
    shift   = qual & (IEQUALIFIER_LSHIFT   | IEQUALIFIER_RSHIFT);
    alt	    = qual & (IEQUALIFIER_LALT     | IEQUALIFIER_RALT);

    switch ( code )
	{
	case 98:
	case 226:
	case 99:
	case 227:
	case 96:
	case 97:
	case 224:
	case 225:
	case 100:
	case 101:
	case 228:
	case 229:
	case 102:
	case 103:
	case 230:
	case 231:   c = 0; break; /* ctrl, shift, capsl, amiga, or alt */

	case 0x50:
	case 0x51:
	case 0x52:
	case 0x53:
	case 0x54:
	case 0x55:
	case 0x56:
	case 0x57:
	case 0x58:
	case 0x59:  c = 0;
		    if (shift)	ptr = p_F[code - 0x50];
		    else	ptr = p_f[code - 0x50];
		    if (!script_on && *ptr == p_keyscript)
			    script_start(++ptr);
		    else    sendstring(ptr);
		    break;
	case 0x0f: c = (p_keyapp) ? 'p' : '0'; keypad = TRUE; break;
	case 0x1d: c = (p_keyapp) ? 'q' : '1'; keypad = TRUE; break;
	case 0x1e: c = (p_keyapp) ? 'r' : '2'; keypad = TRUE; break;
	case 0x1f: c = (p_keyapp) ? 's' : '3'; keypad = TRUE; break;
	case 0x2d: c = (p_keyapp) ? 't' : '4'; keypad = TRUE; break;
	case 0x2e: c = (p_keyapp) ? 'u' : '5'; keypad = TRUE; break;
	case 0x2f: c = (p_keyapp) ? 'v' : '6'; keypad = TRUE; break;
	case 0x3d: c = (p_keyapp) ? 'w' : '7'; keypad = TRUE; break;
	case 0x3e: c = (p_keyapp) ? 'x' : '8'; keypad = TRUE; break;
	case 0x3f: c = (p_keyapp) ? 'y' : '9'; keypad = TRUE; break;
	case 0x43: c = (p_keyapp) ? 'M' : 13 ; keypad = TRUE; break;
	case 0x4a: c = (p_keyapp) ? 'l' : '-'; keypad = TRUE; break;
	case 0x5f: sendstring("\033Om") ;break;
	case 0x3c: c = (p_keyapp) ? 'n' : '.'; keypad = TRUE; break;
	case 0x4c:
	case 0x4d:
	case 0x4e:
	case 0x4f: sendchar(27);            /* cursor keys */
		   if (p_curapp) sendchar('O');
		   else sendchar('[');
		   sendchar(code - 11);
		   break;

	default:
	if (code < 75) c = keys[code];
	else c = 0;
	}

    if (keypad) {
	if (p_keyapp) sendstring("\033O");
	sendchar(c);
	return(0);
	}

    /* add modifiers to the keys */

    if (c != 0) {
	if (shift) {
	    if ((c <= 'z') && (c >= 'a')) c -= 32;
	    else
	    switch( c ) {
		case '[':  c = '{'; break;
		case ']':  c = '}'; break;
		case '\\': c = '|'; break;
		case '\'': c = '"'; break;
		case ';':  c = ':'; break;
		case '/':  c = '?'; break;
		case '.':  c = '>'; break;
		case ',':  c = '<'; break;
		case '`':  c = '~'; break;
		case '=':  c = '+'; break;
		case '-':  c = '_'; break;
		case '1':  c = '!'; break;
		case '2':  c = '@'; break;
		case '3':  c = '#'; break;
		case '4':  c = '$'; break;
		case '5':  c = '%'; break;
		case '6':  c = '^'; break;
		case '7':  c = '&'; break;
		case '8':  c = '*'; break;
		case '9':  c = '('; break;
		case '0':  c = ')'; break;
		default:            break;
		}
	    }
	else if (capsl && (c <= 'z') && (c >= 'a')) c -= 32;
	}
    if (ctrl) {
	if (c > '`' && c <= 127) c -= 96;
	else if (c > '@' && c <= '_') c -= 64;
	else if (c == '6') c = 30;
	else if (c == '-' || c == '?') c = 31;
	}
    if (ctrl && (c == '@' || c == '2' || c == ' ')) {
	if (!local) sendchar(alt?128:0);
	c = 0;
	}
    else if (c != 0 && (!local)) sendchar(alt?c+128:c);
    return((int)c);
    }

void
KillReq()
{
    struct IntuiMessage *Msg;
    ULONG class;
    
    if(numreqs != 0) {
	EndRequest(&myrequest,reqwindow);
	do {
		Wait(1L << reqwindow->UserPort->mp_SigBit);
		while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
			class = Msg->Class;
			ReplyMsg(Msg);
		}
	} while (class != REQCLEAR);
	numreqs = 0;
    }

    if(reqwinup) {
    	/* First, clear out all pending messages */
	while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
	    class = Msg->Class;
	    ReplyMsg(Msg);
	}
	NewReqWindow.LeftEdge = reqwindow->LeftEdge;	/* Remember ...	  */
	NewReqWindow.TopEdge = reqwindow->TopEdge;	/* ...where...	  */
	NewReqWindow.Width = reqwindow->Width;		/* ...the user... */
	NewReqWindow.Height = reqwindow->Height;	/* ...put it.	  */
	CloseWindow(reqwindow); /* Now we can close the window */
	reqwinup = 0;
    }
}

void
InfoMsg2Line(header, msg)
char *header, *msg;
{
    ScrollInfoMsg(1);
    InfoMsgNoScroll(header);
    ScrollInfoMsg(1);
    InfoMsgNoScroll(msg);
    ScrollInfoMsg(1);
}

void
InfoMsg1Line(msg)
char *msg;
{
    ScrollInfoMsg(1);
    InfoMsgNoScroll(msg);
    ScrollInfoMsg(1);
}

/*   Output the specified data to the "info" window  */
void
ScrollInfoMsg(lines)
int lines;
{
/*  ULONG class;
    struct IntuiMessage *Msg; */
    int pixels = lines << 3;
    
    if(!reqwinup)
	OpenReqWindow();

/*  if(Msg=(struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
	class = Msg->Class;
	ReplyMsg(Msg);
	if(class == NEWSIZE)
	    ReqNewSize(reqwindow->Height, reqwindow->Width);
    } */

    if ( (reqy += pixels) > reqmaxy) {
	reqy = reqmaxy;
	if(pixels > 0)
	    ScrollRaster(reqwindow->RPort, 0L, (LONG)pixels,
		(LONG)reqminx,
		(LONG)reqminy,
		(LONG)(reqmaxx+7),
		(LONG)(reqmaxy+7));
/* Was:		(LONG)(wp->Width - wp->BorderRight),
		(LONG)(wp->Height - wp->BorderBottom)); */
    }
}

void
InfoMsgNoScroll(msg)
char *msg;
{
    LONG msglen = strlen(msg);

    if(msglen > reqmaxlen)
	msglen = reqmaxlen;

    ScrollInfoMsg(0);	/* Ensure that the msg willbe visible */

    /*  Position the pen at the baseline of the character (7 scan lines
    ** into it). */
    Move(reqwindow->RPort, (LONG)reqminx, (LONG)(reqy+6));
    Text(reqwindow->RPort, msg, msglen);
}

void
ReqNewSize(height, width)
SHORT height, width;
{
    register struct Window *wp = reqwindow;
    int oldmaxy;

    /*   Compute min and max for x and y coordinates.  Note that for y the
    ** value is for the *top* of the character, not the baseline.  Text()
    ** uses a baseline value and so it must be adjusted prior to the call
    ** (characters are assumed to occupy an 8x8 matrix with the baseline at
    ** 7).  When computing the max values, calculate them so that we will
    ** sufficient room for an entire character. */
    oldmaxy = reqmaxy;
    reqminy = wp->BorderTop + reqfudge;
    reqmaxy = (((height - reqminy - wp->BorderBottom) >> 3) << 3)
		+ (reqminy-8);
    reqminx = wp->BorderLeft + reqfudge;
    reqmaxx = (((width - reqminx - wp->BorderRight) >> 3) << 3)
		+ (reqminx-8);
    reqmaxlen = (reqmaxx+7) / 8;
    if(oldmaxy > reqmaxy) { /* Clean up the bottom of the window */
	int temp = height - wp->BorderBottom - reqmaxy;
	
	ScrollRaster(wp->RPort, 0L, (LONG)temp,
	(LONG)reqminx,
	(LONG)reqmaxy,
	(LONG)(width - wp->BorderRight),
	(LONG)(height - wp->BorderBottom));
    }
}

void
OpenReqWindow()
{
    struct IntuiMessage *Msg;
    ULONG class;
    void ReqNewSize();
    
    reqwindow = OpenWindow(&NewReqWindow);
    do {
	Wait(1L << reqwindow->UserPort->mp_SigBit);
	while(Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
	    class = Msg->Class;
	    ReplyMsg(Msg);
	}
    } while (class != ACTIVEWINDOW);
    reqfudge = 0;	/* Leave 0 pixels/scan lines between border and char */
    ReqNewSize(reqwindow->Height, reqwindow->Width);
    reqy = reqminy;	/* Top of character set by ReqNewSize() */
    reqwinup = 1;
}
SHAR_EOF