TUIPEER Porting Notes
Compile the screen/keyboard library
The first step is to compile the library and test programs in the 'fsp'
directory. This should be the only source you need to hack for a port.
(Except possibly socket.cc).
This library is ANSI C code. The library uses 'terminfo' rather
than curses due to various limitations in the latter.
You should define STDIO_WORKS for tuipeer. A bug in most STDIO
libraries prevents
receiving signals without garbaging the display. However, tuipeer does
not use signals, and the workaround may not be compatible with your unix.
The README in that directory says:
- You should be able to make 'test' and 'testkey'.
- Most port hacking should be confined to "hackterm.h".
- 'test' will draw some X's and O's and slide them around. Press SPACE
between each screen.
- 'testkey' will print the keycode for each function key you press.
ESC should get you out - unless VTIME is broken on your system. It has
been on every system I've ever used, but I report it right away and
it gets fixed after a year or so. Don't worry, I have a work around
for VTIME in tuipeer - it is only used for ambiguous prefixes. AIX VTIME
is still broken and ambiguous prefixes don't work very well over telnet
connections even when VTIME works.
(I really should use select or nap to time ambiguous prefixes.)
I you find you have serious hacking to do, you should read the
design of the fsp package. If you can't
get the fsp implementation to work, the pcurses directory has an
implementation built on standard curses. This may work better for you -
especially if you use the "ncurses" package from GNU. It is also
entirely feasible to roll your own implementation of pscreen.
Playing with TERMINFO
If your terminfo doesn't support all the function keys on your terminal,
the secho
utility (in the fsp directory) will be helpful.
It echoes the raw bytes that
your keyboard sends in a printable form.
Look at INFO and vidattr.c for an outline of how fsp uses terminfo
entries - esp. attributes, which are poorly supported in curses.
Look at the keytable for a list
of function keys interpreted by tuipeer.
The fsp pscreen implementation recognizes a special keyword for the
acsc
string in terminfo. Setting acsc=IBMPC
tells fsp to use the full IBMPC character set for the terminal - rather
than the vt100 based map which is usually supplied.
As an example, here is a terminfo for the
Win95 HyperTerminal that I use on AIX.
Compile the C++ tui window library
Make libb++.a in the 'lib' directory. This is standard C++.
It uses some libg++ classes, e.g. String. I used GNU C++ 2.7.2.
You might need to adjust include files in lib/socket.cc
.
Also, look at lib/getkey.cc
. There is an #ifdef _AIX
that selects the name of _filbuf
in your stdio implementation.
This is needed to "hook" _filbuf
for event processing when
reading the keyboard.
Build the tuipeer program
The remainder of the code is standard C++ - except that it uses a few
classes from libg++
- notably String
. I used
GNU C++ 2.7.2.
Try it out!
Ensure that the bmsi.tui package is in your CLASSPATH. Ensure that
the tuipeer program is in your PATH.
java -Dawt.toolkit=bmsi.tui.TUIKit \
-Dbmsi.tuipeer='tuipeer -a -s5,5' \
bmsi.tui.TestFrame
You can create a script to set these properties automatically if
desired (see below).
How the Java code connects to the C++ code
The RemoteToolkit ctor sets up the connection with a client. There are
three variations:
- If the bmsi.tuipeer property is set, the default ctor execs that command.
Since Runtime.exec redirects all of stdin,stdout,stderr whether or not you use
getInputStream/getOutputStream, the ctor creates a private port and passes
the port number to the client as a -p command arg. I add the bmsi.tuipeer
property to the java script so that I can start a JVM with an AWT program
from the command line:
case "$prog" in
*java) eval exec $DEBUG_PROG $prog \
-Dawt.toolkit=bmsi.tui.TUIKit \
-Dbmsi.tuipeer=\'tuipeer -a ${TUIARG:-"-s5,5"} \' \
'"$@"'
esac
eval exec $DEBUG_PROG $prog $opts '"$@"'
- The login package, or other server type code, obtains a socket connection,
e.g. by listening for a connection from a client, and passes the socket to
the RemoteToolkit ctor that takes a Socket.
- Invoking RemoteToolkit.main connects the RemoteToolkit to stdin and stdout.
This is for an arrangement where inetd loads the JVM. I don't use this
method anymore. I wonder if it still works :-)