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:

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:
  1. 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 '"$@"'                     
    

  2. 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.
  3. 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 :-)