Virtual Terminal Creation/Selection
This interface provides a facility for multiplexing virtual terminals on a single physical terminal. The interface is designed for an arbitrary number of virtual terminals and is intended to be used to support debugging of new versions of terminal-handling code. This multiplexing facility has the following primary features:
1) The human user at the keyboard can cycle through the extant virtual terminals by a particular key combination (control-shift-shift). (This is equivalent to an implicit call of Select[NIL]; see below.)
2) A client program can select which virtual terminal is to be connected to the physical terminal, and can prevent a change of virtual terminal by clients or the user.
3) Clients may register procedures to be invoked whenever the virtual-to-physical terminal correspondence changes.
The implementation initially supplies a single virtual terminal, available through Current.
Virtual: TYPE ~ REF VirtualRep;
VirtualRep:
TYPE ~
RECORD[
characteristics of the black-and-white display (if any)
hasBlackAndWhiteDisplay: BOOL,
bwWidth: NAT,
bwHeight: NAT,
bwHasBorder: BOOL,
bwPixelsPerInch: REAL,
characteristics of the color display (if any)
hasColorDisplay: BOOL,
colorWidth: NAT,
colorHeight: NAT,
colorPixelsPerInch: REAL,
sound generator (if any)
hasSoundGenerator: BOOL,
implementation data
impl: REF VirtualImplRep
];
FrameBuffer: TYPE ~ REF FrameBufferRep;
FrameBufferRep:
TYPE ~
RECORD [
vm: CountedVM.Handle, -- virtual memory interval
base: LONG POINTER, -- starting address
wordsPerLine: NAT, -- words per scan line
bitsPerPixel: NAT, -- bits per pixel
width: NAT, -- width in pixels
height: NAT -- height in scan lines
];
CantDoIt: ERROR;
Create:
PROC
RETURNS [vt: Virtual];
... creates a new virtual terminal. If the hardware includes a black-and-white display, vt.hasBlackAndWhiteDisplay is TRUE and the border, screen dimensions, and resolution values are set to the characteristics of the hardware. Analogous remarks apply to the color display information in vt. The initial state of this terminal, in terms of the procedures below, is:
GetKeys[vt] = ALL[up]
GetMousePosition[vt] = [0,0]
GetBWCursorPosition[vt] = [0,0]
GetBWCursorPattern[vt] = ALL[0]
GetBWBitmapState[vt] = none
GetBWBackground[vt] = white
Errors: CantDoIt is raised if insufficient virtual memory exists to create the virtual terminal.
Select:
PROC [vt: Virtual ←
NIL];
... causes the indicated virtual terminal to be "connected" to the physical terminal.
That is, its keyboard, mouse, display(s) and cursor(s) interact directly with the hardware.
Select[NIL] selects the next terminal in a circular list of extant virtual terminals.
Errors: It is illegal to invoke Select from a SwapNotifier procedure.
Current:
PROC
RETURNS [Virtual];
... returns the identity of the presently selected virtual terminal.
Errors: It is illegal to invoke Current from a SwapNotifier procedure.
DisableKeyboardWatcher: PROC;
EnableKeyboardWatcher:
PROC;
Calling DisableKeyboardWatcher causes the keyboard combination (Control-Shift-Shift) that implicitly invokes Select[NIL] to have no effect until a matching call of EnableKeyboardWatcher occurs.
Errors: It is illegal to invoke these procedures from a SwapNotifier procedure.
SwapAction: TYPE ~ {coming, here, going, gone};
SwapNotifier: TYPE ~ PROC [vt: Virtual, action: SwapAction, clientData: REF];
RegisterNotifier:
PROC [vt: Virtual, notifier: SwapNotifier, clientData:
REF
ANY ←
NIL];
This procedure registers a client procedure with the specified virtual terminal. The registered procedure will be invoked whenever a swap of virtual terminals occurs, and 'clientData' will be passed to it as the last parameter. When a terminal swap occurs, the following client-visible steps occur:
1) Notifiers for current terminal are called with SwapAction[going].
2) Notifiers for the new terminal are called with SwapAction[coming].
3) The actual terminal swap occurs.
4) Notifiers for the former current terminal are called with SwapAction[gone].
5) Notifiers for the new current terminal are called with SwapAction[here].
The SwapNotifiers are invoked in the order of their registration in steps 2 and 5, and in the reverse order of their registration in steps 1 and 4.
RegisterNotifier makes no attempt to eliminate duplicate registrations; that is, multiple calls with identical 'notifier' and 'data' parameters will result in multiple invocations of 'notifier' with 'clientData'.
Unless otherwise noted, all the procedures in this interface may be invoked from a SwapNotifier.
Errors: It is illegal to invoke RegisterNotifier from a SwapNotifier procedure.
UnregisterNotifier:
PROC [vt: Virtual, notifier: SwapNotifier, clientData:
REF
ANY ←
NIL];
The specified SwapNotifier is disassociated from the specified virtual terminal. If it is not presently registered, UnregisterNotifier has no effect.
Errors: It is illegal to invoke UnregisterNotifier from a SwapNotifier procedure.
Black-and-White Display and Cursor
All of the procedures in this section are valid only if vt.hasBlackAndWhiteDisplay is TRUE.
Procedures that change the appearance of the display may be invoked whether or not the virtual terminal is presently selected, but their effect, if any, on the display can be observed only when the terminal is selected.
BitmapState:
TYPE ~ {none, allocated, displayed};
This state applies to both black-and-white and color display bitmaps.
SetBWBitmapState: PROC [vt: Virtual, new: BitmapState] RETURNS [old: BitmapState];
GetBWBitmapState:
PROC [vt: Virtual]
RETURNS [BitmapState];
... manages the virtual memory used for the black-and-white display's bitmap.
BitmapState[none] means that the display has no associated bitmap; if the virtual terminal is selected, the appearance of black-and-white screen is determined by the background value (see SetBWBackground and GetBWBackground below).
BitmapState[allocated] means that virtual memory has been allocated for the display's bitmap, but is not presently associated with the screen. That is, even if the virtual terminal is selected, the contents of the bitmap will not be displayed; it may, however, be accessed via GetBWFrame.
BitmapState[displayed] means that, when the specified virtual terminal is selected, its associated bitmap will appear on the black-and-white display. The background and border values (see below) will affect the appearance of the display.
If there is insufficient virtual memory to allocate a bitmap, the error CantDoIt is raised.
GetBWFrameBuffer:
PROC [vt: Virtual]
RETURNS [FrameBuffer];
... returns a description of the black-and-white display bitmap.
BWBackground:
TYPE ~ TerminalDefs.Background;
-- {white, black}
GetBWBackground: PROC [vt: Virtual] RETURNS [BWBackground];
SetBWBackground:
PROC [vt: Virtual, new: BWBackground]
RETURNS [old: BWBackground];
... controls the interpretation of bits in the black-and-white display's bitmap.
BWBackground[white] causes zeros in the bitmap to appear white and ones to appear black.
BWBackground[black] causes zeros in the bitmap to appear black and ones to appear white.
(A non-existent bitmap is equivalent to a bitmap containing all zeros.)
BWBorder:
TYPE ~ [0..256);
GetBWBorder: PROC [vt: Virtual] RETURNS [oddPairs, evenPairs: BWBorder];
SetBWBorder:
PROC [vt: Virtual, oddPairs, evenPairs: BWBorder];
... controls the appearance of the black-and-white display region not occupied by the bitmap.
GetBWCursorPosition:
PROC [vt: Virtual]
RETURNS [position: Position];
... returns the position of the cursor on vt's black-and-white display.
This position changes only as a result of calls on SetBWCursorPosition.
SetBWCursorPosition:
PROC [vt: Virtual, position: Position];
... sets the position of the cursor on vt's black-and-white display.
It is the responsibility of the client to clip the position, if desired, to ensure that the cursor remains on the visible area of the display.
BWCursorBitmap:
TYPE ~ TerminalDefs.Cursor;
GetBWCursorPattern:
PROC [vt: Virtual]
RETURNS [pattern: BWCursorBitmap];
... returns the bitmap for vt's black-and-white cursor.
This bitmap changes only as a result of calls on SetBWCursorPattern.
SetBWCursorPattern:
PROC [vt: Virtual, pattern: BWCursorBitmap];
... sets the bitmap for vt's black-and-white cursor.
WaitForBWVerticalRetrace:
PROC [vt: Virtual];
... waits until vt is selected, then waits until the next black-and-white display scan begins.
BlinkBWDisplay:
PROC [vt: Virtual];
... blinks the black-and-white display if vt is presently selected; otherwise, has no effect.
Color Display and Cursor
All of the procedures in this section are valid only if vt.hasColorDisplay is TRUE.
Procedures that change the appearance of the display may be invoked whether or not the virtual terminal is presently selected, but their effect, if any, on the display can be observed only when the terminal is selected.
ColorMode:
TYPE ~ ColorDisplayDefs.ColorMode;
full: BOOL, bitsPerPixelChannelA: [0..8], bitsPerPixelChannelB: [0..8]
ChannelValue: TYPE ~ ColorDisplayDefs.ChannelValue; -- [0..256)
ColorValue: TYPE ~ ColorDisplayDefs.ColorValue; -- [0..256)
ChannelsVisible: TYPE ~ ColorDisplayDefs.ChannelsVisible; -- {none, aOnly, bOnly, all}
GetColorBitmapState: PROC [vt: Virtual] RETURNS [BitmapState];
SetColorBitmapState:
PROC [vt: Virtual,
newState: BitmapState, newMode: ColorMode, newVisibility: ChannelsVisible]
RETURNS [oldState: BitmapState, oldMode: ColorMode, oldVisibility: ChannelsVisible];
These procedures manage the virtual memory used for the color display's frame buffers and colormap.
BitmapState[none] means that the display has no associated frame buffers; if the virtual terminal is selected, the color screen will appear black.
BitmapState[allocated] means that virtual memory has been allocated for the display's frame buffers and colormap, but is not presently associated with the screen. That is, even if the virtual terminal is selected, the contents of the frame buffers will not be displayed. They may be (indeed, they are expected to be) manipulated by software via GetColorFrameBufferA and GetColorFrameBufferB. Several arrangements of storage for the frame buffers and colormap are supported; the "newMode" parameter specifies the way in which the display will be used.
BitmapState[displayed] means that, when the specified virtual terminal is selected, its associated frame buffers will appear on the color display.
If newState = none, the mode and visibility settings are remembered (and can be accessed by GetColorMode and GetVisibility, respectively).
Note that there is there is no formal distinction between <newMode: displayed, newVisibility: none> and <newMode: allocated or none, newVisibility: all>. However, these two situtions have different performance characteristics. When newMode = displayed, the bitmap and colormap are pinned in memory; that is, the real memory they occupy cannot be stolen by the virtual memory machinery. In other modes, the bitmap and colormap (if any) can be swapped out. Therefore, <newMode: displayed, newVisibility: none> should be used only for short-term disabling of the display, since the bitmap and colormap remained pinned.
If SetColorBitmapState is invoked with newMode equal to the previous ColorMode, the previously allocated frame buffers and colormap (if any) are undisturbed.
Invoking SetColorBitmapState with newMode such that NOT LegalColorMode[vt, newMode] raises CantDoIt.
GetColorFrameBufferA: PROC [vt: Virtual] RETURNS [FrameBuffer];
GetColorFrameBufferB:
PROC [vt: Virtual]
RETURNS [FrameBuffer];
... returns a description of the specified color frame buffer.
LegalColorMode:
PROC [vt: Virtual, mode: ColorMode]
RETURNS [
BOOL];
... returns TRUE if the color display implements the indicated mode.
GetColorMode:
PROC [vt: Virtual]
RETURNS [ColorMode];
... returns the current ColorMode.
SetColorMode:
PROC [vt: Virtual, new: ColorMode]
RETURNS [old: ColorMode];
... equivalent to RETURN[SetColorBitmapState[vt, allocated, new, all].oldMode]
TurnOnColorDisplay:
PROC [vt: Virtual];
... equivalent to [] ← SetColorBitmapState[vt, displayed, GetColorMode[vt], all]
TurnOffColorDisplay:
PROC [vt: Virtual];
... equivalent to [] ← SetColorBitmapState[vt, allocated, GetColorMode[vt], all]
GetVisibility:
PROC [vt: Virtual]
RETURNS [ChannelsVisible];
... returns the current setting of ChannelsVisible.
SetVisibility:
PROC [vt: Virtual, visibility: ChannelsVisible];
... manipulates the visibility of the bitmaps accessed on the color channels. The effect of SetVisibility can be seen only when vt is selected and GetColorBitmapState[vt]=displayed, but it can be invoked in any state.
GetColor: PROC [vt: Virtual, aChannelValue, bChannelValue: ChannelValue ← 0]
RETURNS [red, green, blue: ColorValue];
SetColor:
PROC [vt: Virtual, aChannelValue, bChannelValue: ChannelValue ← 0,
red, green, blue: ColorValue];
These procedures are defined only if GetColorBitmapState[vt]#none and GetColorMode[vt].full is FALSE. They permit inspection and manipulation of the colormap.
GetRedMap: PROC [vt: Virtual, in: ChannelValue] RETURNS [out: ColorValue];
GetGreenMap: PROC [vt: Virtual, in: ChannelValue] RETURNS [out: ColorValue];
GetBlueMap: PROC [vt: Virtual, in: ChannelValue] RETURNS [out: ColorValue];
SetRedMap: PROC [vt: Virtual, in: ChannelValue, out: ColorValue];
SetGreenMap: PROC [vt: Virtual, in: ChannelValue, out: ColorValue];
SetBlueMap:
PROC [vt: Virtual, in: ChannelValue, out: ColorValue];
These procedures are defined only if GetColorBitmapState[vt]#none and GetColorMode[vt].full is TRUE. They support gamma correction.
GetColorCursorPosition:
PROC [vt: Virtual]
RETURNS [Position];
... returns the position of the virtual cursor associated with the color display on the specified virtual terminal. This position changes only as a result of calls on SetColorCursorPosition.
SetColorCursorPosition:
PROC [vt: Virtual, position: Position];
... sets the cursor position of the specified virtual terminal to the indicated value. This position will be reflected on the screen when the virtual terminal is next selected (or, if it is presently selected, immediately). It is the responsibility of the client to clip the position, if desired, to ensure that the cursor remains on the visible area of the display.
ColorCursorBitmap:
TYPE ~ TerminalDefs.Cursor;
Note: This type is presently defined in such a way that it is type-compatible with BWCursorBitmap. This is because the client is expected to treat the black-and-white and color cursors as a single logical entity, which moves between screens without being transformed. However, since the color cursor is implemented in software, it is not limited to a 16x16 bit array, as the black-and-white cursor is. We are willing to risk an interface change to make the two cursors different, since such a change will have more serious ramifications for the client than for us.
GetColorCursorPattern:
PROC [vt: Virtual]
RETURNS [pattern: ColorCursorBitmap];
... returns the bitmap of the virtual cursor associated with the color display on the specified virtual terminal. This bitmap changes only as a result of calls on SetColorCursorPattern.
SetColorCursorPattern:
PROC [vt: Virtual, pattern: ColorCursorBitmap];
... sets the cursor bitmap of the specified virtual terminal to the indicated value. This bitmap will be reflected on the screen when the virtual terminal is next selected (or, if it is presently selected, immediately).
ColorCursorPresentation: TYPE ~ {onesAreWhite, onesAreBlack};
GetColorCursorPresentation: PROC [vt: Virtual] RETURNS [ColorCursorPresentation];
SetColorCursorPresentation:
PROC [vt: Virtual, new: ColorCursorPresentation]
RETURNS [old: ColorCursorPresentation];
These procedures control the manner in which the cursor bitmap is presented on the color display. "onesAreWhite" means a one-bit in the ColorCursorBitmap is mapped to a color value of all ones (conventionally white) and a zero-bit is mapped to a color value of all zeros (conventionally black). "onesAreBlack" reverses this interpretation.
ColorCursorBitmapState: TYPE ~ {visible, invisible};
GetColorCursorState: PROC [vt: Virtual] RETURNS [ColorCursorBitmapState];
SetColorCursorState:
PROC [vt: Virtual, new: ColorCursorBitmapState]
RETURNS [old: ColorCursorBitmapState];
These procedures control the visibility of the cursor bitmap on the color display. When "visible", the cursor is displayed at the position determined by SetColorCursorPosition. When the state is "invisible", no cursor appears on the color display.
ModifyColorFrame:
PROC [vt: Virtual, action:
PROC,
xmin, ymin:
NAT ← 0, xmax, ymax:
NAT ←
NAT.
LAST];
... excludes the color cursor from the specified rectangle while calling action[].
The color cursor, when "visible", is merged into the color frame buffer(s) by software, which caches the frame buffer contents that lie "under" the cursor. If the cursor moves (as a result of SetColorCursorPosition), the frame buffer is restored to the cached value. To avoid interfering with the color cursor, clients that modify a color frame buffer should use ModifyColorFrame, specifying a rectangle that bounds the region being changed. As long as the cursor remains outside the specified rectangle, it will remain visible.