RemoteTerminalDoc.tioga
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Last tweaked by Mike Spreitzer on July 14, 1992 10:24 am PDT
Willie-sue, April 21, 1988 12:08:30 pm PDT
Christian Jacobi, April 23, 1992 5:39 pm PDT
RemoteTerminal
CEDAR 7.0 — FOR INTERNAL XEROX USE ONLY
RemoteTerminal
Mike Spreitzer
© Copyright 1987, 1988 Xerox Corporation. All rights reserved.
Abstract: The RemoteTerminal package allows one Cedar machine to provide terminal services (mouse & keyboard input, screen output) for another.
Created by: Mike Spreitzer
Maintained by: Mike Spreitzer <Spreitzer.pa>
Keywords: Terminal, Remote Terminal, Remote Host, Terminal Location, Advice, X11
XEROX  Xerox Corporation
   Palo Alto Research Center
   3333 Coyote Hill Road
   Palo Alto, California 94304

For Internal Xerox Use Only
1. General Info
The Cedar Remote Terminal makes it possible for one machine (called the "terminal" machine, or the "server") act as a terminal for another (called the "host" machine, or the client). In the context of the HomeComputing project, the terminal machine would most usefully be at home, and the host machine in the office. Each of the four combinations of the Host and Terminal being PCedar and DCedar works.
In PCedar, there is a packaged world, RemoteViewersHostWorld, that contains all the Host side stuff; RemoteViewersHostWorld is like X11ViewersWorld and RawViewersWorld, differing in the way terminal services are acquired. Also, there is a RemoteViewersHost Commander Command; again, it is analogous to the RawViewers and X11Viewers commands. In DCedar, boot with the standard bootfile, using the J switch; this will do a full boot but use Remote.loadees instead of the usual Basic.Loadees. If you roll your own loadees, be sure to start from Remote.loadees, which you can find with `OpenR Remote.Loadees'. Alternatively, you can `Install RemoteViewersHost' (in a directory into which you've BroughtOver the public parts of RemoteViewersHost.DF). Rollbacks will screw you, because of a deadlock that occurs in the bootfile when trying to open a remote Simple Terminal to an ARPA location.
The terminal side can be loaded into any Cedar world.
In PCedar, the Host side of the Cedar Remote Terminal is implemented by the Cedar packages HostCoordination, ImagerSender, ViewerContexts, and RemoteViewersHost; the Terminal side is implemented by the Cedar packages TerminalCoordination, ImagerReciever, and RemoteViewersTerminalByViewer.
Hosts and Terminals
Each Host sends its output to a set of terminal locations. A terminal location is either undefined, local, or a remote terminal location. The undefined terminal location is used when a Host is not connected to any terminal. The local terminal location is not used in PCedar; in DCedar, it's used by a Host to indicate that the locally attached screen and keyboard are to be used. A remote terminal location consists of a machine and a pair of port numbers. The textual form of a remote terminal location is, in general, "<machine>-<protocol>:<control Port>&<viewers Port>"; the "&<viewers Port>" may be elided when the viewers port is 58811 (which it always is, at the moment); the ":<control Port>" may be elided when the control port is 58813 (which it always is, at the moment) and the <machine> and <protocol> contain no colons; the "-<protocol>" may be omitted when the protocol is ARPA (which is the only one supported, at the moment) and <machine> contains no dashes.
In DCedar, secondary terminal locations are not supported; the network requests to add secondary terminal locations, and all Host-side Commander commands, are not understood.
Each Host takes its input from a single terminal location. This is called the primary terminal location. Output goes to both the primary terminal location and the secondary terminal locations. A rudimentary form of floor control is available through a Commander command on the Host side.
A Cedar world with the Terminal side loaded can instantiate multiple Terminals; each Terminal serves at most one Host. There can be multiple Terminal worlds on a machine (in PCedar).
Each instantiated Terminal is either connected to a particular Host, or is unconnected. In PCedar, the textual specification of a Host is, in geneeral, "<machine>-<protocol>:<control Port>"; the ":<control Port>" may be elided when the control port is 58812 and the <machine> and <protocol> contain no colons; the "-<protocol>" may be omitted when the protocol is ARPA (which is the only one supported, at the moment) and <machine> contains no dashes. In DCedar, a host address is given as a protocol family followed by an address or name in brackets. Case is significant in the protocol family name. Examples are "pup[McCormick]", "pup[3#265#]", "xns[Tallahatchie]", "xns[0-003.2-857-435-576.]", "arpa[Skipjack]", and "arpa[13.0.12.200]".
There can now be multiple Host worlds on a machine (in PCedar). You can determine which control port a world is listening on by watching for a message of the form "At <date and time>, Host(Terminal) Control listening on TCP port XXX" from the host world as it starts up. Also, Host worlds register themselves with the Local Registry; you can query the Local Registry on a machine with the `lrls' UNIX command.
Even an unconnected Terminal maintains a window (either a Viewer or an X window). This is because a Terminal's window has buttons to control the Terminal's size, which should be set before a session begins because the Host side only notes the Terminal's size at the start of sessions.
Connections and Sessions
A Host side and Terminal side are said to be connected when (1) the Terminal side appears among the primary and secondary locations of the Host, and (2) one of the Terminals at the Terminal side is connected to the Host. The Host and Terminal software strives to keep conditions (1) and (2) either both true or both false, but disparities can arise nontheless (usually as a result of one side or the other terminating (in the UNIX sense)). There are commands to query and alter the connection state.
A session is an open network stream between a Host and a Terminal. Due to the vagaries of network streams, and some other things, many sessions may come and go for a single connection.
Access Controls
A Host will not accept a request that comes into its control port to change its primary location unless the primary location is currently undefined. Each host maintains a state bit called observers allowed. When this bit is false, a request that comes into the Hosts's control port to add a secondary terminal location will be rejected; when the observers allowed bit is true, such requests will be accepted. There are Commander commands to query and alter this bit.
The above is a terribly crude approximation to what we really want. Unfortunately, I'm not sure exactly what it is we really want. What kind of credentials (XNS, UNIX, Kerberos, ...) should we use? Should we strive to not send passwords in the clear over the network? (and if so, how?)
Using the RemoteTerminal/RemoteHost system for advising
With PCedar Host and Terminal, there is one way: make the advisee a secondary terminal location.
With DCedar Host and Terminal, there are two ways.
In the first way, the advisee sets the BOOLEAN variable RemoteViewersHost.cc to TRUE (after loading the Remote Host software, of course), and then uses the RemoteTerminal/RemoteHost system is used in the normal fashion. This involves the advisee idling, and the advisor remotely logging in to the advisee's machine. Because RemoteViewersHost.cc is TRUE, output goes to both screens, and the advisee can see what the advisor is doing.
The second way is a special perversion of the RemoteTerminal mechanisms, and does not involve changing who's logged in. Both the advisor and the advisee each issue a command to set up the advice session, and they both issue a command to close down the advice session. Checkpoints should not be made during advice sessions. An advise session is started by the advisor issuing the "Advise AdviseeMachine" command, and then the advisee issuing the "AdviceFrom AdvisorMachine" command, in that order. Note the spelling, and that the appropriate machine names have to be substituted. While this connection is being set up, the advisor may temporarily see a screen full of trash; more likely he will temporarily see a misleading screen (e.g., one that looks like his last use of the SimpleTerminal, which was probably to log in). During the advice session, the advisee also gets to see output on his screen, including cursor tracking. To close down the session, the "StopAdvise" command must be executed on the advisor's machine. To do this, the advisor must manually swap virtual terminals (with control-leftshift-rightshift) back to his native terminal, and issue the command. Also, the "RejectAdvice" command may optionally be executed on the advisee's machine, either before or after the advisor does "StopAdvise" (note that if it's done before, it must be done by the advisor, because he's the one driving the advisee's machine).
Terminal Styles
There is more than one way to implement a Terminal. In PCedar, there are two ways: by an X window (using the bitmap-oriented implementation for Imager contexts), and by a Cedar Viewer. In DCedar, there are two ways: by a Terminal.Virtual, and by a Cedar Viewer. A user must indicate which style of Terminal implementation is desired. This is done by issuing a command that both indicates the desired implementation style, and loads all the stuff necessary to be a Terminal side. In Cedar10, those commands are TerminalByX and TerminalByViewer; PCedar2, those commands are TerminalByX11 and TerminalByViewer; in DCedar, those commands are TerminalByVirtual and TerminalByViewer.
The TerminalByX style creates X windows whose application (in Cedar XTk terminology) is ``X11RemoteCedarTerminal''. You can thus control where the X window appears by issuing the command
% X11DefaultServer viewmachine:0.0
in the Terminal Cedar world, which will cause subsequent creations of the X window to appear on screen 0 of X server 0 on the machine named ``viewmachine''. You can elide the ``.0'' or the ``:0.0'', as those are the defaults. If you don't explicitly indicate the X server in Cedar, the UNIX environment variable DISPLAY will be consulted (this is standard behavior for X clients).
The TerminalByViewer style creates Cedar Viewers whose painting is synchronized with the Host's output in certain ways. Precisely, every time the Host invokes a context's DoWithBuffer method, the Terminal Viewer not finish a Paint until that DoWithBuffer is finished; also, no Paint will finish while there are buffer names that have been given to SaveBuffer but not yet DiscardBuffer. These synchronization restrictions exist because the Imager.Context method suite makes it impossible to efficiently layer Contexts without them. What this means to users is that a Terminal viewer will be locked for the duration of every: (1) use of a pop-up menu, and (2) repaint by Tioga of a line of a document.
Creating and Destroying Terminals
In PCedar2 and DCedar*, Remote Terminals respond to destruction by creating a new terminal. This is so you can set the size of the terminal before making a connection; you want to do this because the Host side only notes that Terminal's size at the beginning of a session.
In Cedar10, terminals are not automatically created when one is destroyed (nor when the relevant code is first run). Instead, the implementation-style-setting commands (TerminalByX, TerminalByViewer) cause an(other) terminal of the appropriate style to appear.
Terminal Size
In the Viewer and X terminal styles, there is a distinction made between the current size of the terminal window and "ideal" size of the "terminal". The latter is reported to the host as the size of the terminal; the former is under control of the appropriate window manager on the terminal machine.
The RemoteTerminal protocol only communicates the terminal size at the start of each session --- no changes can be reported to the host during a session.
You can specify the initial "ideal" size with Cedar User Profile entries:
RemoteTerminal.DefaultWidth: CARDINAL
RemoteTerminal.DefaultHeight: CARDINAL
The X style terminals are also sensitive to X resources. If you specify the "geometry" resource (with the usual format and interpretation) for a widget whose class name is "X11RemoteCedarTerminal", this will be used instead of the Cedar profile information.
If no preferences are specified in the profile, a style-dependent default choice will be made. For the X style, it is 100 pixels (in both dimensions) less than the terminal machine's screen size. For the Viewer style, it is 700 wide and 750 high.
Scrolling
The Viewer style terminals can have vertical scrolling disabled. This prevents the annoyance of accidentally scrolling the terminal when you just missed clicking at the left of the remote area. The Viewer style terminals have a button that toggles the ``scrollability'' state bit. It is labelled either ``-> Scrollable'' or ``-> Unscrollable'', depending on which transition would be caused by a click. The initial state can be specified in your Cedar User Profile:
RemoteTerminal.Scrollable: BOOLTRUE
Compression
The output stream will be compressed with the Fiala/Greene `B4K' method, iff both sides are willing. Both PCedar sides default to willing, and both DCedar sides default to unwilling. There are Commander commands to query and change whether each side is willing. When the Terminal is a D-machine wimpier than a Dorado, compression is not worth the trouble, even over a 9600-baud link. In all other cases, compression is worthwhile over a 9600-baud link. The compression factor varies from about 3 to about 10, depending on the Imager operations used and their arguments.
Screens and Color
In PCedar, a Terminal has one screen, which is either color or black-and-white, depdending on the X server or frame-buffer ultimately used; a Host also has one screen, and does not much know or care whether color is supported (there is one small exception, sometimes gotten wrong, for the background color for Viewer captions).
In DCedar, a Host has one or two screens: a main black-and-white one, and perhaps a secondary color one. The pixel depth, and color imaging method (dither, threshold), can be changed while a Cedar world is running. A TerminalByVirtual also has one or two screens; a TerminalByViewer has one screen.
If the Host and Terminal both have two screens, the Terminal tries to configure its second screen like the Host's. If the Host has multiple screens and the Terminal has one, all imaging is done on the one screen of the Terminal. If the Temrinal has more screens than the Host, the unneeded screens are not used.
Mouse Parameters
A DCedar host sends the fast-mouse parameters and screen escapes to the Terminal; a PCedar host does not. A DCedar Terminal obeys any received fast-mouse parameters and screen escapes; a PCedar Terminal ignores them.
PCedar Miscellania
Watch the SystemScript for informative and debugging messages.
DCedar Miscellania
The host machine will go idle whenever it doesn't know where its terminal is. In particular, whenever you hard-boot it, it doesn't know where its terminal is.
The location of the terminal can change only when the host is idle. While in idle, if a key is hit, the location becomes the local hardware. If, while idle, an offer of terminal services comes in over the network, it will be accepted.
In general, both sides (host and terminal) of this software try to show the appropriate screen to the user. If this fails, try manually swapping screens (with control-shift-shift).
You can disconnect by idling the host. The host will drop the connection if it misses communication with the terminal long enough for PUP streams to decide it's really gone (on the order of a minute); note that the host does not miss communication while it is doing low-level things like inloading and outloading memory (e.g., for a checkpoint, rollback, or boot). You can break the connection from the terminal side by issuing the "Disconnect" command.
You can do full boots, and use Iago, and make checkpoints, and all that stuff, remotely --- except when using ARPA (ie TCP/IP) protocols, due to misfeatures in the bootfile. The only things you can't do remotely are hit the physical boot button and hold down keys to indicate boot switches.
Viewers is automatically told to assume the size of the black-and-white display is that of the terminal's viewport.
Protocol Version Mismatches
There are three different network protocols involved in the RemoteTerminal system (TerminalCoordination, SimpleTerminal, and Viewers). All are subject to further development. To help avoid confusion, there is a little version checking done whenever such a network stream is opened. A version is a small integer (e.g., 10). Each side (host and terminal) knows the range of versions that it is willing to use, and the conversation begins with an exchange of these ranges. If there is any overlap, the conversation takes place in the highest version of the protocol that both sides are willing to use. If there is no overlap, the conversation terminates. If you're lucky, there'll be messages posted in the MessageWindows of the host and terminal explaining that this has happened, and giving the protocol version ranges that the two machines are willing to use. Knowing these ranges tells you how to fix the problem. Update one or both of the machines so there's some overlap in the versions they're willing to use. The latest versions of the host and terminal software are willing to speak the following versions:
Protocol  | Host | Terminal
Coordination  | [1..4] | [1..4]
Simple Terminal I/O | [1..1] | [1..1]
Viewers I/O  | [10..17] | [10..17]
On a running system, you can determine what versions the software you're running are willing to use by issuing the `HostVersions' and `TerminalVersions' commands.
Transport Chaos (DCedar only)
Things are chaotic. The Cedar packages have variants that don't use certain of the transport protocols. The CedarChest packages consult CommDriverRegistry and use whatever's available.
2. Examples
PCedar, single Terminal
Host (on machine named "augustus"):
unix% RemoteViewersHostWorld
... startup messages
Terminal:
unix% X11ViewersWorld
... startup messages; then, in a Commander:
% TerminalByX
... loading messages...
% RTConnectTo augustus
... use it; when done:
% RTDisconnect
%
PCedar, two-site collaboration
Host (on machine named "m1"):
m1% RemoteViewersHostWorld
... startup messages; then, in a Commander:
% RHAcceptObservers
Driving Terminal (on machine named "m2"):
m2% X11ViewersWorld
... startup messages; then, in a Commander:
% TerminalByX
... loading messages...
% RTConnectTo m1
... use it; when done:
% RTDisconnect
%
Observing Terminal (on machine named "m3"):
m3% RawViewersWorld
... startup messages; then, in a Commander:
% TerminalByViewer
... loading messages...
% RTObserve m1
... watch what happens; when bored:
% RTDisconnect
%
3. Terminal-Side Commands
name TerminalByViewer:
syntax
TerminalByViewer
description
Specifies an implementation style for remote terminals, and loads the Terminal side software. This style presents the remote Viewers world in a Viewer in the terminal world. The remote terminal viewer can be scrolled, but not scaled. The remote terminal viewer can be moved and resized. Due to the nature of the Imager interface, the remote terminal viewer cannot be scrolled, moved, or resized during the time that an Imager.DoWithBuffer operation or ImagerBackdoor.SaveBuffer* .. ImagerBackdoor.DiscardBuffer sequence is executing. The implementation ensures this restriction by holding the Viewers lock on the viewer during such operations. The only `normal' use of ImagerBackdoor.SaveBuffer* .. ImagerBackdoor.DiscardBuffer is pop-up menus of various kinds. Tioga paints each line with a Imager.DoWithBuffer operation. I'm not aware of other uses of these operations.
examples
% TerminalByViewer
stop/undo
Don't even try.
name TerminalByX: (not in DCedar)
syntax
TerminalByX
description
Specifies an implementation style for remote terminals, and loads the Terminal side software. This style presents the remote Viewers world in an X window, using the bitmap-oriented method of implementing Imager contexts on X. Available only in PCedar.
examples
% TerminalByX
stop/undo
Don't even try.
name TerminalByVirtual: (DCedar only)
syntax
TerminalByVirtual
description
Specifies an implementation style for remote terminals, and loads the Terminal side software. This style presents the remote Viewers world in a Terminal.Virtual, as is available only in DCedar.
examples
% TerminalByVirtual
stop/undo
Don't even try.
name RemoteTerminalConnectTo:
Aliases
RTConnectTo: RTCT:
syntax
RemoteTerminalConnectTo HostName*
description
Offer termial services to the given hosts. If accepted, the Host makes this Terminal its primary one, and clears its set of secondary terminal locations.
examples

% RemoteTerminalConnectTo augustus   -- in PCedar
% RemoteTerminalConnectTo arpa[augustus] -- in DCedar
stop/undo
Idling the Host machine or using the RemoteTerminalDisconnect command below will retract this offer.
name RemoteTerminalObserve: (PCedar only)
Aliases
RTObserve:
syntax
RemoteTerminalObserve HostName*
description
Ask the given Hosts to add this Terminal to their sets of secondary terminal locations. May or may not be accepted, depending on the Host's "observers allowed" state bit. Such requests are only understood by PCedar Hosts.
examples

% RTObserve augustus
stop/undo
The RemoteTerminalDisconnect command below will close connections.
name RemoteTerminalDisconnect:
Aliases
RTDisconnect: RTD:
syntax
RemoteTerminalDisconnect HostName*
description
Retract offer of termial services to the given hosts. If no hosts are given, all offers are retracted.
examples
% RemoteTerminalDisconnect
stop/undo
The RemoteTerminalConnectTo command can be used to make a new offer.
name See: (DCedar only)
syntax
See HostName
description
Currently, the RemoteTerminals software provides terminal services for a remote host on a local Terminal.Virtual (the things that you cycle through with control-shift-shift). The See command selects the Terminal.Virtual being used for the given host.
examples
% See arpa[Skipjack]
name ListHosts:
syntax
ListHosts
description
Lists the set of hosts that this machine is currently willing to provide terminal services for.
examples
% ListHosts
name TerminalVersions:
syntax
TerminalVersions
description
Lists the version ranges for the RemoteHost/RemoteTerminal protocols that this machine is willing to speak (as a Terminal).
examples
% TerminalVersions
TerminalCoordination: [1 .. 2]
Viewers: [10 .. 16]
SimpleTerminal: [1 .. 1]
name HostVersions: (DCedar only)
syntax
HostVersions
description
Lists the version ranges for the RemoteHost/RemoteTerminal protocols that this machine is willing to speak (as a Host).
examples
% HostVersions
TerminalCoordination: [1 .. 2]
Viewers: [10 .. 16]
SimpleTerminal: [1 .. 1]
name VersionsAtHost:
syntax
VersionsAtHost HostName
description
Lists the version ranges for the RemoteHost/RemoteTerminal protocols that the given host machine is willing to speak.
examples
% VersionsAtHost xns[Wasp]
"TerminalCoordination" 1 2; "Viewers" 10 16; "SimpleTerminal" 1 1;
name GetHostsTerminal:
syntax
GetHostsTerminal HostName
description
Reports what the given host thinks its terminal is.
examples
% GetHostsTerminal xns[Wasp]
stable"local"
name AdviceFrom: (DCedar only)
syntax
AdviceFrom HostName
description
Done on the advisee machine, in preparation for advice.
examples
% AdviceFrom xns[Wasp]
name RejectAdvice: (DCedar only)
syntax
RejectAdvice
description
Done on the advisee machine, to end an advice session.
examples
% RejectAdvice
name Advise: (DCedar only)
syntax
Advise HostName
description
Done on the advisor machine, to initiate an advice session.
examples
% Advise pup[Bennington]
name StopAdvise: (DCedar only)
syntax
StopAdvise HostName
description
Done on the advisor machine, to end an advice session.
examples
% StopAdvise pup[Bennington]
name RestartTerminalControlTcp:
syntax
RestartTerminalControlTcp
description
For use when the normal creation of the Terminal Control TCP listener failed; this command first destroys the existing listener, if any, and then tries again to create a listener. Destroying a listener doesn't affect any conversation already initiated.
examples
% RestartTerminalControlTcp
name RestartTerminalViewersTcp:
syntax
RestartTerminalViewersTcp
description
For use when the normal creation of the Terminal Viewers TCP listener failed; this command first destroys the existing listener, if any, and then tries again to create a listener. Destroying a listener doesn't affect any conversation already initiated.
examples
% RestartTerminalViewersTcp
4. Host-Side Commands (PCedar only)
name RemoteViewersHost:
syntax
RemoteViewersHost
description
Analogous to the RawViewers and X11Viewers commands. This command is issued in a Cedar world that doesn't yet have Viewers loaded. This command loads Viewers and the Host side. At most one Cedar world per machine should have the Host side stuff loaded. This command starts by setting the global Run default switches to "-o", so optimized code is preferred.
examples

% RemoteViewersHost
name RemoteViewersHostNoOpt:
syntax
RemoteViewersHostNoOpt
description
Like RemoteViewersHost, but sets the global Run default switches to "-~o" so that unoptimized code is preferred.
examples

% RemoteViewersHost
name HostVersions:
syntax
HostVersions
description
Lists the version ranges for the RemoteHost/RemoteTerminal protocols that this machine is willing to speak (as a Host).
examples
% HostVersions
TerminalCoordination: [1 .. 2]
Viewers: [10 .. 16]
SimpleTerminal: [1 .. 1]
name BePlainHost:
syntax
BePlainHost
description
Makes this Host side unwilling to use Fiala/Greene compression.
examples

% BePlainHost
name BeCodingHost:
syntax
BeCodingHost
description
Makes this Host side willing to use Fiala/Greene compression.
examples

% BeCodingHost
name RemoteHostGetLocState:
Aliases
RHGetLocState:
syntax
RemoteHostGetLocState
RHGetLocState
description
Lists the current primary and secondary terminal locations, and whether network-initiated requests to add secondary locations will be accepted.
examples

% RHGetLocState
Terminal locations are stable at "[primary: thema-ARPA:58813&58811, secondary: {}]"; net-initiated observers will be accepted.
%
name RemoteHostSelPrimary:
Aliases
RHSelPrimary:
syntax
RemoteHostSelPrimary <terminalLocation>
RHSelPrimary <terminalLocation>
description
Switches the primary location to the given one, which should be secondary before the command is issued. This is the way to exercise floor control.
examples

% RHGetLocState
Terminal locations are stable at "[primary: dipper-ARPA:58813&58811, secondary: {pewee-ARPA:58813&58811}]"; net-initiated observers will be accepted.
% RHSelPrimary pewee
Terminal locations are stable at "[primary: pewee-ARPA:58813&58811, secondary: {dipper-ARPA:58813&58811}]"; net-initiated observers will be accepted.
%
name RemoteHostAbandon:
Aliases
RHAbandon:
syntax
RemoteHostAbandon <terminalLocation>
RHAbandon <terminalLocation>
description
Ceases to use the given terminal location. If that location was primary, one of the secondary locations is arbirarily chosen and promoted to being primary; if there were no secondary locations, the primary location becomes undefined.
examples

% RHAbandon pewee
Terminal locations are stable at "[primary: undefined, secondary: {}]"; net-initiated observers will be rejected.
%
name RemoteHostAcceptObservers:
Aliases
RHAcceptObservers:
syntax
RemoteHostAcceptObservers
RHAcceptObservers
description
Set the "observers allowed" bit to true.
examples

% RHAcceptObservers
Terminal locations are stable at "[primary: thema-ARPA:58813&58811, secondary: {}]"; net-initiated observers will be accepted.
%
name RemoteHostRejectObservers:
Aliases
RHRejectObservers:
syntax
RemoteHostRejectObservers
RHRejectObservers
description
Set the "observers allowed" bit to false.
examples

% RHAcceptObservers
Terminal locations are stable at "[primary: thema-ARPA:58813&58811, secondary: {}]"; net-initiated observers will be rejected.
%
name RemoteHostSetPrimary:
Aliases
RHSetPrimary:
syntax
RemoteHostSetPrimary <terminalLocation>
RHSetPrimary <terminalLocation>
description
Sets the primary location to the given one, and clears the set of secondary locations. Does not contact the Terminal side's control port to alter the Terminal's connection state; thus, this command is not for normal use.
examples

% RHSetPrimary pewee
Terminal locations are stable at "[primary: pewee-ARPA:58813&58811, secondary: {}]"; net-initiated observers will be rejected.
%
name RemoteHostAddSecondary:
Aliases
RHAddSecondary:
syntax
RemoteHostAddSecondary <terminalLocation>
RHAddSecondary <terminalLocation>
description
Adds the given location to the set of secondary ones. Does not contact the Terminal side's control port to alter the Terminal's connection state; thus, this command is not for normal use.
examples

% RHAddSecondary pewee
Terminal locations are stable at "[primary: dipper-ARPA:58813&58811, secondary: {pewee-ARPA:58813&58811}]"; net-initiated observers will be rejected.
%
name RestartHostControlListeners:
syntax
RestartHostControlListeners
description
For use when the normal creation of the Host Control listenerd fails; this command first destroys any existing listeners, and then tries again to create the listeners. Destroying a listener doesn't affect any conversation already initiated.
examples
% RestartHostControlListeners
5. Monitoring
There are five sets of monitoring tools available for extracting information from the RemoteTerminal.
The first three use data collected by a special feature. When the host machine receives notice that a key has been depressed, it sends a special acknowledgement, which includes the time, back to the terminal machine. In this way, we get a time-stamped round-trip report.
Terminal Stats
Issuing the command `TerminalStats' (on the Terminal machine) displays three histograms of transit times for key-press events. One shows the distribution of `up-link' (terminal to host) transit times; another shows `down-link' transit times, and a third shows round-trip times. You can do all the usual Histogram things with them; try exploring the menu pop-up buttons and mouse clicks on the data area, if you refuse to read the Histograms document.
Transit History
Interpreting `← RemoteTerminal.ViewHistory[]' (on the Terminal machine) makes a typescript viewer with a `History' menu button. Hitting that menu button causes the details of the recent key-press event trips to be printed. Three times are printed: the time the key was depressed, the time that event was received on the Host, and the time the reply was received on the Terminal. Then the mouse position and the event itself are printed. If you aren't running sufficiently recent software on both sides, the mouse position and event itself will look boring. The trips are remembered in a fixed-size circular buffer. Left- and Middle- clicking the History button displays the trips since the last one displayed; Right-clicking displays all available trips.
Terminal Header Line
This is not optional. An area is reserved at the top of the terminal screen for display of certain information; the host machine thinks the terminal screen is correspondingly shorter than it actually is. The information displayed consists mainly of abstracts of the information presented by the transit time histograms and by the NetWatch tool; since this information is displayed on the terminal screen, it is not necessary to swap virtual terminals (which is painfully slow on certain kinds of machines) to see it. The information is updated every 15 seconds. Currently, the header line looks something like this:
15:51:36 Term=243#240#; rt min=0.35s max=10.85s avg=1.13s run avg=1.37s; link 2: rcv 37/3912 pkts, 00/123 bad, 00.0% run avg; rtr: 3/123, dup: 1/45, res: 0/0, rcv: 15/834, snd: 10/789
The first figure is the time at which the last sampling period ended. Next is an address of the terminal machine. Next comes a summary of the round trip times: the minimum, maximum, and average over the last sampling period (15 seconds), and a running average (0.95*old avg + 0.05*new avg). Then there is a summary of received packets on the "last network": its number (among nets connected directly to the terminal machine), the incremental/total number of packets received, the incremental/total number of them that had "bad" receive status, and a running average (same decay rate) of percentage of bad packets. Finally, there are some statistics from the stream (if it's PUP) for the Viewers protocol: the incremental/total number of retransmitted, received duplicates, resource limited, received, and sent packets.
ImagerSender Stats
The command `Install ImagerByteSenderMonitor' (on the Host machine) will create some displays concerned with the encoding of Imager operations. As this is unlikely to be interesting to random users, I won't bother describing it.
Host Spy
The command `HostSpy' (on the Host machine) will create some a display concerned with the detailed operation of the stream, similar to the information at the tail of the terminal header.
6. How It Works
There are a few interfaces introduced to deal with new concepts.
The terminal location
The interface for this is TerminalLocation. The location of the terminal of a Cedar workstation is now variable. It may be the local hardware (previously this was the only choice). It may be across a network (the interface claims to offer PUP, XNS, and ARPA network connections; in fact, only PUP is implemented). Or it may be undefined.
Providing terminal services
The interface for this is TerminalMultiServing. It deals with the question, ``what machines, if any, am I providing terminal services for across the network?''. An older interface, TerminalServing, is also supported for backward compatibility.
General issues for Hosts and Terminals
The HostAndTerminalOps interface, from the HostCoordination package, provides procedures for setting and querying the protocol version ranges supported. Ignore the GetChannel procedure.
Selecting the screen to show
There is this more basic interface, Terminal, that exports the abstraction of multiplexing multiple "virtual terminals" onto the one physical terminal (i.e., what's managed by the previous two interfaces). However, up till now there hasn't been a good way to get all clients of this interface to coordinate properly to get the right virtual terminal `selected' for display on the one physical terminal at the right time. Now there is. The idea is to associate a priority variable with each terminal; the one with the highest priority is displayed. I've made SimpleTerminal, Idle, and RemoteTerminal subscribe to this theory.
7. Organization
There are six package roles: {coordination, simple terminal I/O, and viewers I/O} on each of {Host, Terminal}. Here are the packages that fill them (they all live on Cedar, except those concerning Terminal or Viewers I/O --- they live on CedarChest):
   | Host  | Terminal
Coordination  | HostCoordination | TerminalCoordination
Simple Terminal I/O | RemoteSimpleHost | RemoteSimpleTerminal
Viewers I/O  | RemoteViewersHost | RemoteTerminal and
    RemoteViewersTerminalByVirtual
There is one DF for each Host role. The two most primitive (HostCoordination and RemoteSimpleHost) Host packages are built into the bootfile. The other, RemoteViewersHost, is loaded either by booting with the J switch (which means to use the `Remote.Loadees' instead of the `Basic.Loadees') or by issuing the command `Install RemoteViewersHost' (in a directory into which RemoteViewersHost has been BroughtOver).
On the terminal side, things are more complex, because I plan to have alternate implementations of how to be a terminal. RemoteTerminal is at the top of the Terminal side's pyramid; it currently has wired into it the fact that RemoteViewersTerminalByVirtual provides the (currently) only way to implement a Viewers terminal.
8. Details
6.1. Ports
pup/xns/arpa  | Host  | Terminal
Coordination  | 90/90/58812  | 91/91/58813
Simple Terminal I/O |   | 87/87/none(58810)
Viewers I/O  |   | 88/88/none(58811)
In PCedar, each side uses only one port. The protocol on the Host's port is:
2?3:
(^ passchar tv: VersionRange) || (Ë passchar hv: VersionRange);
MIN[tv.max, hv.max]=4 AND MAX[tv.min, hv.min]<=4
(
^ ('c | 'o) (proto: ROPE min,max: INT)* |
^ 'd |
^ ('q | 's)
) Ë reply
4:
(^ passchar tv: VersionRange) || (Ë passchar hv: VersionRange);
MIN[tv.max, hv.max]=4 AND MAX[tv.min, hv.min]<=4
(
^ ('c | 'o) Port (proto: ROPE min,max: INT)* |
^ 'd Port |
^ ('q | 's)
) Ë reply
The protocol on the Terminal's port is:
2?3:
(Ë passchar tv: VersionRange) || (^ passchar hv: VersionRange); (
MIN[tv.max, hv.max]=4 AND MAX[tv.min, hv.min]<=4
Ë 'D ^ reply |
Ë 's ^ (proto: ROPE min,max: INT)* |
Ë CHAR ^ "Bad command..." )
4:
(Ë passchar tv: VersionRange) || (^ passchar hv: VersionRange); (
MIN[tv.max, hv.max]=4 AND MAX[tv.min, hv.min]<=4
Ë 'D Port ^ reply |
Ë 'V Port ViewersStuff |
Ë 'S Port SimpleTerminalStuff |
Ë 's ^ (proto: ROPE min,max: INT)* |
Ë CHAR ^ "Bad command..." )
6.2. Protocol Versions
The Inscript/Viewers conversion is carried out via a protocol that is still somewhat under development. Consequently, we are concerned with versions of that protocol. Each conversation begins with both conversants sending a range (i.e., min and max) of versions they are willing to converse in. If there is any overlap, the conversation takes place in the highest version they both can handle. If there is no overlap, both conversants stop conversing.
There is a need to document protocols (oh boy!). Here are the rules of my notation. An expression of the form "a; b" indicates that b happens after a; "a | b" that either a happens or b happens; "a || b" indicates a and b happen in any order, even interleaved; "^ a" indicates that a is sent from the terminal to the host; "Ë a" indicates that a is sent from the host to the terminal; "l, m, ... n: T" describes data named l, m, ... n, each of type T; parentheses are used for grouping; "IF a THEN b ELSE c FI" means the obvious thing.
passchar: CHAR ~ CHAR.LAST;
VersionRange: TYPE ~ RECORD [max, min: BYTE];
Ctl7: TYPE ~ RECORD [willingToCode: {'C, 'P}, reject: {'R, 'A}];
TimeCtl: TYPE ~ {'T, 'N};
6:
(^ passchar tv: VersionRange) || (Ë passchar hv: VersionRange);
MIN[tv.max, hv.max]=6 AND MAX[tv.min, hv.min]<=6
(^ tReject: {'R, 'A}) || (Ë hctl: Ctl7);
If either reject is 'R, stop conversation.
The data conversation is now carried out. Iff hctl.willingToCode='C, the data going from the host to the terminal are compressed with the FG1C method.
7:
Differs from 6 in allowing the terminal to indicate willingness to use compression.
(^ passchar tv: VersionRange) || (Ë passchar hv: VersionRange);
MIN[tv.max, hv.max]=6 AND MAX[tv.min, hv.min]<=6
(^ tctl: Ctl7) || (Ë hctl: Ctl7);
If either reject is 'R, stop conversation.
The data conversation is now carried out. Iff both willingToCodes are 'C, the data going from the host to the terminal are compressed with the FG1C method.
8:
Differs from 7 in adding SetMouseGrain, SetFastMouseParms, and SetEscapes to the data conversation.
9:
Differs from 8 in the data conversation.
10:
Differs from 9 in the data conversation.
11:
Differs from 10 in the data conversation, by adding the timing probes & replies.
12:
Differs from 11 in that initial negotiation allows host to declare that it will be sending fine-grain timing in the imager operations.
(^ passchar tv: VersionRange) || (Ë passchar hv: VersionRange);
MIN[tv.max, hv.max]=12 AND MAX[tv.min, hv.min]<=12
(^ tctl: Ctl7) || (Ë hctl: Ctl7; TimeCtl);
If either reject is 'R, stop conversation.
The data conversation is now carried out. Iff both willingToCodes are 'C, the data going from the host to the terminal are compressed with the FG1C method. Iff the TimeCtl is 'T, fine-grain timing is included in the data conversation; otherwise the TimeCtl is 'N
13:
Differs from 12 in that timing probes and replies additionally carry mouse position and ActionBody.
16:
Differs from 15 in adding MousePosition as a kind of InterminalSetting.
17:
Differs from 16 in sending 32-bit integers in ViewTranslateI, MoveViewRectangle, RectangleI; SampleMap rep uses word size of 32 instead of 16; PA rep can handle any Xform in pa.m; {Send,Request}CutBuffer added to Imager protocol; SendCutBuffer added to Input protocol;