-- file: InitInteractor
-- edited by Brotz, August 31, 1982 10:39 AM
-- edited by Levin, April 14, 1981 3:41 PM
-- edited by Schroeder, Wednesday Nov. 5, 1980 2:59 pm PST
-- edited by Taft, May 10, 1983 6:11 PM

DIRECTORY
AltoDefs USING [PageSize],
ccD: FROM "ChollaCmdDefs" USING [BBoardCommand],
displayCommon USING [firstDCB, patchDCBPtr],
DMSTimeDefs USING [timeStringLength],
drD: FROM "LaurelDriverDefs" USING [videoBackground],
dsD: FROM "DisplayDefs" USING [DCB, DCBnil, DCBptr, GetPictureParameters,
GetStringWidth, lineHeight, ScreenXCoord, ScreenYCoord],
exD: FROM "ExceptionDefs" USING [SysBug],
inD: FROM "InteractorDefs" USING [AnswerCommand, BoundaryLineNbrTracker,
BoundaryPadNbrPtr, BoundaryPadNbrTracker, BracketsHouseRefresher,
CommandProcedure, CommandTracker, CopyCommand, DeleteCommand,
DisplayMessageCommand, ExceptionsTracker, FindCommand, ForwardCommand,
GetCommand, GetMailFileCommand, GetNewMailCommand, HardcopyCancelCommand,
HardcopyCommand, HardcopyConfirmCommand, House, HouseFixedEdgeType, HousePtr,
leftMargin, Line, LinePair, LinePtr, LoginCommand, maxBracketStringLength,
MoveDMCMBoundary, MoveMessageToFileCommand, MoveTOCDMBoundary, Nbr,
NbrPtr, NewFormCommand, NullCommand, PutCommand, QuitCommand, Region,
RegionPtr, RegionType, rightMargin, RunCommand, ScreenXCoord, ScreenYCoord,
SendCommand, SetCopiesCommand, SetDuplexCommand, SetOverrideFormCommand,
SetPasswordProtectedCommand, SetPrinterCommand, ShortenEditorMenuCommand,
SubstituteCommand, TextHouseRefresher, TextNbrTracker, ThumbLineNbrPtr,
ThumbLineNbrTracker, ThumbMessageNbr, ThumbTOC, TOCTracker, UndeleteCommand],
Inline USING [BITAND, COPY],
intCommon USING [answerCommandHouse, bboardCommandHouse, cmCommandNbr,
CMCommandRegion, CMRegion, cmTextNbr, cmThumbLineNbr, copyCommandHouse,
copyMenuSegment, deleteCommandHouse, deliverCommandHouse, disableWriting,
displayCommandHouse, dmcmBoundaryPadNbr, DMRegion, dmTextNbr,
dmThumbLineNbr, exceptionsRegion, findMenuSegment, forwardCommandHouse,
freePagesHouse, getCommandHouse, getPutMenuSegment, gvTestingMode,
hardcopyCommandHouse, hardcopyMenuSegment, isCholla, linePoolPtr, mailCommandNbr,
mailCommandRegion, mailFileBracketsHouse, mailFileCommandHouse,
moveToBracketsHouse, moveToCommandHouse, newFormCommandHouse,
newMailCommandHouse, newMessagesHouse, numScanLines, putCommandHouse,
quitCommandHouse, regions, runCommandHouse, runMenuSegment, substituteMenuSegment,
timeHouse, tocCommandNbr, TOCCommandRegion, tocdmBoundaryPadNbr, TOCRegion,
tocTextNbr, tocThumbLineNbr, undeleteCommandHouse, userBracketsHouse,
userCommandHouse, versionHouse],
lsD: FROM "LaurelStateDefs" USING [AllocateStateNode, AllocateStateString,
DefineStateSegment, PageCount, ReleaseStateSegment, StateSegment, SwapInStateSegment,
WriteStateSegment],
ovD: FROM "OverviewDefs" USING [GetVersionString],
String USING [AppendString, WordsForString];

InitInteractor: PROGRAM
IMPORTS ccD, disC: displayCommon, drD, dsD, exD, inD, Inline, intC: intCommon, lsD,
ovD, String
EXPORTS inD =

BEGIN
OPEN inD, lsD;

-- Global constants --

commandIndent: CARDINAL = 0;
interCommandSpacing: CARDINAL = 15;
preBracketSpacing: CARDINAL = 7;
maxCommandString: CARDINAL = 30;
endOfMessageString: STRING;

HouseType: TYPE = {command, brackets, text};


BuildScreenStructures: PUBLIC PROCEDURE =
-- Builds all data structures that support the display. All constant fields will be filled in;
-- actual x,y screen coordinates will not.
-- Side effects: intCommon region and house pointers are filled in. DisplayCommon firstDCB
-- is filled in to point to a spacer DCB, which in turn is linked to all other DCB’s.
BEGIN
-- Call each region builder in turn, linking the regions and their DCB’s in a chain.
rp: RegionPtr;
dcbPtr: dsD.DCBptr;
s: STRING ← "End of Message."L;

endOfMessageString ← lsD.AllocateStateString[s.length];
String.AppendString[endOfMessageString, s];

intC.linePoolPtr ← AllocateLinePool[];

disC.firstDCB ← dcbPtr ← NewDCB[];

rp ← intC.regions ← InitMailCommandRegion[];
dcbPtr ← dcbPtr.next ← rp.dcb;
rp ← rp.nextRegion ← InitTOCRegion[];
dcbPtr ← dcbPtr.next ← rp.dcb;
rp ← rp.nextRegion ← InitTOCCommandRegion[];
dcbPtr ← dcbPtr.next ← rp.dcb;
rp ← rp.nextRegion ← InitDMRegion[];
dcbPtr ← dcbPtr.next ← rp.dcb;
rp ← rp.nextRegion ← InitCMCommandRegion[];
dcbPtr ← dcbPtr.next ← rp.dcb;
rp ← rp.nextRegion ← InitCMRegion[];
dcbPtr ← dcbPtr.next ← rp.dcb;
rp ← rp.nextRegion ← InitExceptionsRegion[];
dcbPtr ← dcbPtr.next ← rp.dcb;

disC.patchDCBPtr ← NewDCB[];

BuildSwappableMenus[];
END; -- of BuildScreenStructures --


InitMailCommandRegion: PROCEDURE RETURNS [rp: RegionPtr] =
-- Allocates and partially fills in the mailCommandRegion.
BEGIN
np: NbrPtr ← intC.mailCommandNbr ← LOOPHOLE[InitMailCommandNbr[]];
np.nextNbr ← InitTOCThumbLineNbr[];
intC.mailCommandRegion ← rp ← MakeRegion[mailCommandRegion, np];
END; -- of InitMailCommandRegion --


InitTOCRegion: PROCEDURE RETURNS [rp: RegionPtr] =
-- Allocates and partially fills in the TOCRegion.
BEGIN
np: NbrPtr ← InitTOCTextNbr[];
intC.tocThumbLineNbr.np ← np;
intC.TOCRegion ← rp ← MakeRegion[tocRegion, np];
END; -- of InitTOCRegion --


InitTOCCommandRegion: PROCEDURE RETURNS [rp: RegionPtr] =
-- Allocates and partially fills in the TOCCommandRegion.
BEGIN
np: NbrPtr ← MakeBoundaryLineNbr[rightMargin - 16];
np.nextNbr ← InitTOCDMBoundaryPadNbr[];
np.nextNbr.nextNbr ← intC.tocCommandNbr ← LOOPHOLE[InitTOCCommandNbr[]];
np.nextNbr.nextNbr.nextNbr ← InitDMThumbLineNbr[];
intC.TOCCommandRegion ← rp ← MakeRegion[tocCommandRegion, np];
END; -- of InitTOCCommandRegion --


InitDMRegion: PROCEDURE RETURNS [rp: RegionPtr] =
-- Allocates and partially fills in the DMRegion.
BEGIN
np: NbrPtr ← InitDMTextNbr[];
intC.dmThumbLineNbr.np ← np;
intC.DMRegion ← rp ← MakeRegion[dmRegion, np];
END; -- of InitDMRegion --


InitCMCommandRegion: PROCEDURE RETURNS [rp: RegionPtr] =
-- Allocates and partially fills in the CMCommandRegion.
BEGIN
np: NbrPtr ← MakeBoundaryLineNbr[rightMargin - 16];
np.nextNbr ← InitDMCMBoundaryPadNbr[];
np.nextNbr.nextNbr ← intC.cmCommandNbr ← LOOPHOLE[InitCMCommandNbr[]];
np.nextNbr.nextNbr.nextNbr ← InitCMThumbLineNbr[];
intC.CMCommandRegion ← rp ← MakeRegion[cmCommandRegion, np];
END; -- of InitCMCommandRegion --


InitCMRegion: PROCEDURE RETURNS [rp: RegionPtr] =
-- Allocates and partially fills in the CMRegion.
BEGIN
np: NbrPtr ← InitCMTextNbr[];
intC.cmThumbLineNbr.np ← np;
intC.CMRegion ← rp ← MakeRegion[cmRegion, np];
END; -- of InitCMRegion --


InitExceptionsRegion: PROCEDURE RETURNS [rp: RegionPtr] =
-- Allocates and partially fills in the ExceptionsRegion.
BEGIN
np: NbrPtr ← MakeBoundaryLineNbr[rightMargin];
np.nextNbr ← InitExceptionsNbr[];
intC.exceptionsRegion ← rp ← MakeRegion[exceptionsRegion, np];
END; -- of InitExceptionsRegion --


MakeRegion: PROCEDURE [regionType: RegionType, nbrs: NbrPtr]
RETURNS [rp: RegionPtr] =
BEGIN
rp ← AllocateStateNode[SIZE[Region]];
rp↑ ← Region
[nextRegion: NIL, dcb: NewDCB[], regionType: regionType, topY: 0, bottomY: 0,
cursorShape: charArrow, nbrs: nbrs];
END; -- of MakeRegion --


MakeBoundaryLineNbr: PROCEDURE [right: dsD.ScreenXCoord] RETURNS [np: NbrPtr] =
-- Allocates and partially fills in a BoundaryLineNbr.
BEGIN
np ← AllocateStateNode[SIZE[boundaryLine Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: leftMargin,
rightX: right,
cursorShape: charArrow,
nbrVariant: boundaryLine[nbrTracker: BoundaryLineNbrTracker]];
END; -- of MakeBoundaryLineNbr --


InitTOCDMBoundaryPadNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in a BoundaryPadNbr.
BEGIN
np ← intC.tocdmBoundaryPadNbr ← MakeBoundaryPadNbr[MoveTOCDMBoundary];
END; -- of InitTOCDMBoundaryPadNbr --


InitDMCMBoundaryPadNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in a BoundaryPadNbr.
BEGIN
np ← intC.dmcmBoundaryPadNbr ← MakeBoundaryPadNbr[MoveDMCMBoundary];
END; -- of InitDMCMBoundaryPadNbr --


MakeBoundaryPadNbr: PROCEDURE
[command: PROCEDURE [BoundaryPadNbrPtr, ScreenYCoord]]
RETURNS [np: BoundaryPadNbrPtr] =
BEGIN
np ← AllocateStateNode[SIZE[boundaryPad Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: rightMargin - 16,
rightX: rightMargin,
cursorShape: charArrow,
nbrVariant: boundaryPad[command: command, nbrTracker: BoundaryPadNbrTracker]];
END; -- of MakeBoundaryPadNbr --


InitTOCThumbLineNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in a BoundaryLineNbr.
BEGIN
np ← intC.tocThumbLineNbr ← MakeThumbLineNbr[ThumbTOC, 4];
END; -- of InitTOCThumbLineNbr --


InitDMThumbLineNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in a BoundaryLineNbr.
BEGIN
np ← intC.dmThumbLineNbr ← MakeThumbLineNbr[ThumbMessageNbr];
END; -- of InitDMThumbPadNbr --


InitCMThumbLineNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in a BoundaryLineNbr.
BEGIN
np ← intC.cmThumbLineNbr ← MakeThumbLineNbr[ThumbMessageNbr];
END; -- of InitCMThumbPadNbr --


MakeThumbLineNbr: PROCEDURE
[command: PROCEDURE [ThumbLineNbrPtr, NbrPtr, ScreenXCoord], x: CARDINAL ← 0]
RETURNS [np: ThumbLineNbrPtr] =
BEGIN
np ← AllocateStateNode[SIZE[thumbLine Nbr]];
np↑ ← Nbr
[nextNbr: NIL, nLines: 0, topY: 0, bottomY: 0, leftX: leftMargin, rightX: rightMargin - 2,
cursorShape: charArrow,
nbrVariant: thumbLine[exists: FALSE, length: 0, start: 0, end: 0, selection: 0,
startX: leftMargin + x, endX: leftMargin + x, selectionX: leftMargin + x,
np: NIL, command: command, nbrTracker: ThumbLineNbrTracker]];
END; -- of MakeThumbLineNbr --


InitMailCommandNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in the MailCommandNbr.
BEGIN
h, hp: HousePtr;
houseLeftX, houseRightX: dsD.ScreenXCoord;
commandString, versionString, freeDiskPages: STRING;
testingModeString: STRING ← " GV Test Mode"L;

versionString ← ovD.GetVersionString[];
commandString ← AllocateStateString
[versionString.length
+ (IF intC.isCholla THEN 8 ELSE 10)
+ (IF intC.gvTestingMode THEN testingModeString.length ELSE 0)];
String.AppendString[commandString, IF intC.isCholla THEN "Cholla 1"L ELSE "Laurel 6.1"L];
String.AppendString[commandString, versionString];
IF intC.gvTestingMode THEN String.AppendString[commandString, testingModeString];
houseLeftX ← leftMargin;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, plainFace];
hp ← h ← intC.versionHouse ←
MakeHouse[houseType: text, leftX: houseLeftX, rightX: houseRightX, text: commandString];

-- timeHouse
houseRightX ← rightMargin;
houseLeftX ← houseRightX;
h ← h.nextHouse ← intC.timeHouse ←
MakeHouse[houseType: text, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[DMSTimeDefs.timeStringLength], fixedEdge: right];

commandString ← AllocateStateString[40]; -- length of "You have new mail."
commandString.length ← 0;
houseLeftX ← leftMargin;
houseRightX ← houseLeftX;
h ← h.nextHouse ← intC.newMessagesHouse ←
MakeHouse[houseType: text, leftX: houseLeftX, rightX: houseRightX,
text: commandString, lineNumber: 1];

IF intC.isCholla THEN
BEGIN
commandString ← "BBoard"L;
houseLeftX ← 280;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.bboardCommandHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length], lineNumber: 1,
command: ccD.BBoardCommand];
String.AppendString[h.text, commandString];
END;

-- free pages house
freeDiskPages ← " free disk pages"L;
commandString ← AllocateStateString[5]; -- length of "99999"
String.AppendString[commandString, " "L];
houseRightX ← rightMargin - dsD.GetStringWidth[freeDiskPages, plainFace];
houseLeftX ← houseRightX;
h ← h.nextHouse ← intC.freePagesHouse ←
MakeHouse[houseType: text, leftX: houseLeftX, rightX: houseRightX,
text: commandString, lineNumber: 1, fixedEdge: right];

-- free pages constant text house
commandString ← AllocateStateString[freeDiskPages.length];
String.AppendString[commandString, freeDiskPages];
h ← h.nextHouse ←
MakeHouse[houseType: text, leftX: rightMargin, rightX: rightMargin,
text: commandString, lineNumber: 1, fixedEdge: right];

commandString ← "User"L;
houseLeftX ← leftMargin + commandIndent;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.userCommandHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length], lineNumber: 2,
confirm: TRUE, command: LoginCommand];
String.AppendString[h.text, commandString];

houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
intC.userBracketsHouse ← h ← h.nextHouse ←
MakeHouse[houseType: brackets, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[maxBracketStringLength], lineNumber: 2];

commandString ← "New mail"L;
houseLeftX ← leftMargin + 165;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.newMailCommandHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length], lineNumber: 2, confirm: TRUE,
command: GetNewMailCommand];
String.AppendString[h.text, commandString];

commandString ← "Mail file"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.mailFileCommandHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length], lineNumber: 2,
confirm: TRUE, command: GetMailFileCommand];
String.AppendString[h.text, commandString];

houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
intC.mailFileBracketsHouse ← h ← h.nextHouse ←
MakeHouse[houseType: brackets, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[maxBracketStringLength], lineNumber: 2,
confirm: TRUE];

commandString ← "Quit"L;
houseRightX ← rightMargin;
houseLeftX ← houseRightX - dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.quitCommandHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length], lineNumber: 2,
confirm: TRUE, command: QuitCommand];
String.AppendString[h.text, commandString];

np ← MakeCommandNbr[hp];
END; -- of InitMailCommandNbr --


MakeHouse: PROCEDURE
[houseType: HouseType, leftX, rightX: ScreenXCoord, text: STRING,
lineNumber: CARDINAL ← 0, fixedEdge: HouseFixedEdgeType ← left,
confirm: BOOLEAN ← FALSE, indicDone: BOOLEAN ← TRUE,
usePicture: BOOLEAN ← FALSE, command: CommandProcedure ← NullCommand]
RETURNS [hp: HousePtr] =
BEGIN
hp ← AllocateStateNode[SIZE[House]];
hp↑ ← House
[nextHouse: NIL,
lineNumber: lineNumber,
topY: 0,
bottomY: 0,
leftX: leftX,
rightX: rightX,
text: text,
fixedEdge: fixedEdge,
typeface: IF houseType = command THEN boldFace ELSE plainFace,
needsConfirmation: confirm,
trackerIndicateDone: indicDone,
callable: houseType = command,
command: command,
houseRefresher: IF houseType = brackets THEN BracketsHouseRefresher
ELSE TextHouseRefresher];
END; -- of MakeHouse --


MakeCommandNbr: PROCEDURE [houses: HousePtr] RETURNS [np: NbrPtr] =
BEGIN
np ← AllocateStateNode[SIZE[command Nbr]];
np↑ ← Nbr
[nextNbr: NIL, nLines: 0, topY: 0, bottomY: 0, leftX: leftMargin, rightX: rightMargin,
cursorShape: charArrow,
nbrVariant: command[houses: houses, nbrTracker: CommandTracker]];
END; -- of MakeCommandNbr --


InitTOCTextNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in the TOCTextNbr.
BEGIN
line: LinePtr ← intC.linePoolPtr;
intC.linePoolPtr ← line.nextLine;
np ← intC.tocTextNbr ← AllocateStateNode[SIZE[tocText Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: 0,
rightX: rightMargin,
cursorShape: lineArrow,
nbrVariant: tocText
[lines: line,
firstLineOffScreen: line,
toc: NIL,
displayFormatted: TRUE,
haveToc: FALSE,
nbrTracker: TOCTracker]];
line.nextLine ← NIL;
line.y ← 0;
line.state ← empty;
line.linePair ← LinePair[0, 0];
END; -- of InitTOCTextNbr --


InitTOCCommandNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in the DMCommandNbr.
BEGIN
h, hp: HousePtr;
houseLeftX, houseRightX: ScreenXCoord;
commandString: STRING ← [maxCommandString];

commandString ← "Display"L;
houseLeftX ← leftMargin + commandIndent;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
hp ← h ← intC.displayCommandHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length],
command: DisplayMessageCommand];
String.AppendString[h.text, commandString];

commandString ← "Delete"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.deleteCommandHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length],
command: DeleteCommand];
String.AppendString[h.text, commandString];

commandString ← "Undelete"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.undeleteCommandHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length],
command: UndeleteCommand];
String.AppendString[h.text, commandString];

IF intC.disableWriting THEN
BEGIN
commandString ← ""L;
houseLeftX ← houseRightX;
END
ELSE BEGIN
commandString ← "Move to"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
END;
h ← h.nextHouse ← intC.moveToCommandHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length],
confirm: TRUE, command: MoveMessageToFileCommand];
String.AppendString[h.text, commandString];

IF intC.disableWriting THEN
{commandString ← NIL; houseLeftX ← houseRightX}
ELSE BEGIN
houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
commandString ← AllocateStateString[maxBracketStringLength];
END;
intC.moveToBracketsHouse ← h ← h.nextHouse ←
MakeHouse[houseType: brackets, leftX: houseLeftX, rightX: houseRightX,
text: IF intC.disableWriting THEN NIL ELSE AllocateStateString[maxBracketStringLength],
confirm: TRUE];
IF intC.disableWriting THEN h.houseRefresher ← TextHouseRefresher;

houseRightX ← rightMargin;
IF intC.disableWriting THEN {commandString ← ""L; houseLeftX ← houseRightX}
ELSE BEGIN
commandString ← "Hardcopy"L;
houseLeftX ← houseRightX - dsD.GetStringWidth[commandString, boldFace];
END;
intC.hardcopyCommandHouse ← h ← h.nextHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length],
confirm: TRUE, indicDone: FALSE, command: HardcopyCommand];
String.AppendString[h.text, commandString];

np ← MakeCommandNbr[hp];
END; -- of InitTOCCommandNbr --


InitDMTextNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in the DMTextNbr.
BEGIN
line: LinePtr ← intC.linePoolPtr;
intC.linePoolPtr ← line.nextLine;
np ← intC.dmTextNbr ← AllocateStateNode[SIZE[messageText Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: 0,
rightX: rightMargin,
cursorShape: charArrow,
nbrVariant: messageText
[haveMessage: FALSE,
editable: FALSE,
lines: line,
firstLineOffScreen: line,
message: NIL,
protectedFieldPtr: NIL,
insertionBuffer: NIL,
deletionBuffer: NIL,
endString: endOfMessageString,
nbrTracker: TextNbrTracker]];
line.nextLine ← NIL;
line.y ← 0;
line.state ← trailingBlankLine;
line.rightX ← leftMargin;
line.firstCharIndex ← 0;
END; -- of InitDMTextNbr --


InitCMCommandNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in the CMCommandNbr.
BEGIN
h, hp: HousePtr;
houseLeftX, houseRightX: dsD.ScreenXCoord;
commandString: STRING ← [maxCommandString];

commandString ← "New form"L;
houseLeftX ← leftMargin + commandIndent;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
hp ← h ← intC.newFormCommandHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length],
confirm: TRUE, command: NewFormCommand];
String.AppendString[h.text, commandString];

commandString ← "Answer"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.answerCommandHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length],
confirm: TRUE, command: AnswerCommand];
String.AppendString[h.text, commandString];

commandString ← "Forward"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.forwardCommandHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length],
confirm: TRUE, command: ForwardCommand];
String.AppendString[h.text, commandString];

commandString ← "Get"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
intC.getCommandHouse ← h ← h.nextHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length],
confirm: TRUE, command: GetCommand];
String.AppendString[h.text, commandString];

IF intC.disableWriting THEN {commandString ← ""L; houseLeftX ← houseRightX}
ELSE BEGIN
commandString ← "Put"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
END;
h ← h.nextHouse ← intC.putCommandHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length],
confirm: TRUE, command: PutCommand];
String.AppendString[h.text, commandString];

commandString ← "Copy"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
intC.copyCommandHouse ← h ← h.nextHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length],
confirm: TRUE, command: CopyCommand];
String.AppendString[h.text, commandString];

commandString ← "Run"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.runCommandHouse ←
MakeHouse[houseType: command, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length],
confirm: TRUE, indicDone: FALSE, command: RunCommand];
String.AppendString[h.text, commandString];

commandString ← "delivered"L;
houseRightX ← rightMargin;
houseLeftX ← houseRightX - dsD.GetStringWidth[commandString, italicFace];
h ← h.nextHouse ← intC.deliverCommandHouse ←
MakeHouse[houseType: text, leftX: houseLeftX, rightX: houseRightX,
text: AllocateStateString[commandString.length], fixedEdge: right,
confirm: TRUE, command: SendCommand];
h.typeface ← italicFace;

np ← MakeCommandNbr[hp];
END; -- of InitCMCommandNbr --


InitCMTextNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in the CMTextNbr.
BEGIN
line: LinePtr ← intC.linePoolPtr;
intC.linePoolPtr ← line.nextLine;
np ← intC.cmTextNbr ← AllocateStateNode[SIZE[messageText Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: 0,
rightX: rightMargin,
cursorShape: charArrow,
nbrVariant: messageText
[haveMessage: TRUE,
editable: TRUE,
lines: line,
firstLineOffScreen: line,
message: NIL,
protectedFieldPtr: NIL,
insertionBuffer: NIL,
deletionBuffer: NIL,
endString: endOfMessageString,
nbrTracker: TextNbrTracker]];
line.nextLine ← NIL;
line.y ← 0;
line.state ← endOfMessage;
line.rightX ← leftMargin;
line.firstCharIndex ← 0;
END; -- of InitCMTextNbr --


InitExceptionsNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in the ExceptionsNbr.
BEGIN
line: LinePtr ← intC.linePoolPtr;
intC.linePoolPtr ← line.nextLine;
np ← AllocateStateNode[SIZE[messageText Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: leftMargin,
rightX: rightMargin,
cursorShape: charArrow,
nbrVariant: messageText
[haveMessage: FALSE,
editable: FALSE,
lines: line,
firstLineOffScreen: line,
message: NIL,
protectedFieldPtr: NIL,
insertionBuffer: NIL,
deletionBuffer: NIL,
endString: NIL,
nbrTracker: ExceptionsTracker]];
line.nextLine ← NIL;
line.y ← 0;
line.state ← trailingBlankLine;
line.rightX ← leftMargin;
line.firstCharIndex ← 0;
END; -- of InitExceptionsNbr --


BuildSwappableMenus: PROCEDURE =
BEGIN
house: House;
houseLeftX, houseRightX: ScreenXCoord;
currentString: STRING;
bracketString: STRING ← [maxBracketStringLength];
base: POINTER;
nextSlot, segmentLimit: CARDINAL;
currentSegment: lsD.StateSegment;

InitSegment: PROCEDURE [seg: POINTER TO lsD.StateSegment, nPages: lsD.PageCount] =
BEGIN
seg↑ ← currentSegment ← lsD.DefineStateSegment[nPages];
base ← lsD.SwapInStateSegment[currentSegment];
nextSlot ← 0;
segmentLimit ← nPages * AltoDefs.PageSize;
END; -- of MakeSegment --

AddToSegment: PROCEDURE =
-- adds contents of house and s to the current segment;
BEGIN
IF nextSlot + SIZE[House] > segmentLimit THEN exD.SysBug[];
Inline.COPY[from: @house, nwords: SIZE[House], to: base + nextSlot];
nextSlot ← nextSlot + SIZE[House];
IF nextSlot + String.WordsForString[currentString.maxlength] > segmentLimit
THEN exD.SysBug[];
Inline.COPY[from: currentString,
nwords: String.WordsForString[currentString.maxlength],
to: base + nextSlot];
nextSlot ← nextSlot + String.WordsForString[currentString.maxlength];
END; -- of AddToSegment --

FinishSegment: PROCEDURE =
BEGIN
lsD.WriteStateSegment[currentSegment];
lsD.ReleaseStateSegment[currentSegment];
END; -- of FinishSegment --

InitSegment[@intC.hardcopyMenuSegment, 1];

currentString ← "Printer"L;
houseLeftX ← leftMargin;
houseRightX ← houseLeftX + dsD.GetStringWidth[currentString, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: boldFace,
needsConfirmation: FALSE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: SetPrinterCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];

currentString ← bracketString;
houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: BracketsHouseRefresher];
AddToSegment[];

currentString ← "Form"L;
houseLeftX ← leftMargin + 260;
houseRightX ← houseLeftX + dsD.GetStringWidth[currentString, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: boldFace,
needsConfirmation: FALSE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: SetOverrideFormCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];

currentString ← bracketString;
houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: BracketsHouseRefresher];
AddToSegment[];

currentString ← "Hardcopy"L;
houseLeftX ← intC.hardcopyCommandHouse.leftX;
houseRightX ← rightMargin;
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: FALSE,
callable: TRUE,
command: HardcopyConfirmCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];

currentString ← "Copies"L;
houseLeftX ← leftMargin;
houseRightX ← houseLeftX + dsD.GetStringWidth[currentString, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: boldFace,
needsConfirmation: FALSE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: SetCopiesCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];

currentString ← "99"L;
houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: BracketsHouseRefresher];
AddToSegment[];

currentString ← "Two sided"L;
houseLeftX ← leftMargin + 110;
houseRightX ← houseLeftX + dsD.GetStringWidth[currentString, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: boldFace,
needsConfirmation: FALSE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: SetDuplexCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];

currentString ← "Yes"L;
houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[3], -- length of "Yes" --
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: BracketsHouseRefresher];
AddToSegment[];

currentString ← "Private"L;
houseLeftX ← leftMargin + 260;
houseRightX ← houseLeftX + dsD.GetStringWidth[currentString, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: boldFace,
needsConfirmation: FALSE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: SetPasswordProtectedCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];

currentString ← "Yes"L;
houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[3], -- length of "Yes" --
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: BracketsHouseRefresher];
AddToSegment[];

currentString ← "Cancel"L;
houseRightX ← rightMargin;
houseLeftX ← houseRightX - dsD.GetStringWidth[currentString, boldFace];
house ← House
[nextHouse: LOOPHOLE[0],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: FALSE,
callable: TRUE,
command: HardcopyCancelCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];
FinishSegment[];

InitSegment[@intC.getPutMenuSegment, 1];

currentString ← "File name"L;
houseLeftX ← leftMargin;
houseRightX ← houseLeftX + dsD.GetStringWidth[currentString, italicFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: italicFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];

currentString ← bracketString;
houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: BracketsHouseRefresher];
AddToSegment[];

currentString ← ""L;
houseRightX ← rightMargin;
houseLeftX ← rightMargin - dsD.GetPictureParameters[resetMenuIcon].width;
house ← House
[nextHouse: LOOPHOLE[0],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
picture: resetMenuIcon,
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: FALSE,
callable: TRUE,
usePicture: TRUE,
command: ShortenEditorMenuCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];
FinishSegment[];

InitSegment[@intC.runMenuSegment, 1];

currentString ← "Program"L;
houseLeftX ← leftMargin;
houseRightX ← houseLeftX + dsD.GetStringWidth[currentString, italicFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: italicFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];

currentString ← bracketString;
houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: BracketsHouseRefresher];
AddToSegment[];

currentString ← ""L;
houseRightX ← rightMargin;
houseLeftX ← rightMargin - dsD.GetPictureParameters[resetMenuIcon].width;
house ← House
[nextHouse: LOOPHOLE[0],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
picture: resetMenuIcon,
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: FALSE,
callable: TRUE,
usePicture: TRUE,
command: ShortenEditorMenuCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];
FinishSegment[];

InitSegment[@intC.copyMenuSegment, 1];

currentString ← "from"L;
houseLeftX ← leftMargin;
houseRightX ← houseLeftX + dsD.GetStringWidth[currentString, italicFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: italicFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];

currentString ← bracketString;
houseLeftX ← houseRightX + 2;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: BracketsHouseRefresher];
AddToSegment[];

currentString ← "to"L;
houseLeftX ← leftMargin + 240;
houseRightX ← houseLeftX + dsD.GetStringWidth[currentString, italicFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: italicFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];

currentString ← bracketString;
houseLeftX ← houseRightX + 2;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: BracketsHouseRefresher];
AddToSegment[];

currentString ← ""L;
houseRightX ← rightMargin;
houseLeftX ← rightMargin - dsD.GetPictureParameters[resetMenuIcon].width;
house ← House
[nextHouse: LOOPHOLE[0],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
picture: resetMenuIcon,
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: FALSE,
callable: TRUE,
usePicture: TRUE,
command: ShortenEditorMenuCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];
FinishSegment[];

InitSegment[@intC.findMenuSegment, 1];

currentString ← "Find"L;
houseLeftX ← leftMargin;
houseRightX ← houseLeftX + dsD.GetStringWidth[currentString, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: FindCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];

currentString ← bracketString;
houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: BracketsHouseRefresher];
AddToSegment[];

currentString ← ""L;
houseRightX ← rightMargin;
houseLeftX ← rightMargin - dsD.GetPictureParameters[resetMenuIcon].width;
house ← House
[nextHouse: LOOPHOLE[0],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
picture: resetMenuIcon,
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: FALSE,
callable: TRUE,
usePicture: TRUE,
command: ShortenEditorMenuCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];
FinishSegment[];

InitSegment[@intC.substituteMenuSegment, 1];

currentString ← "Substitute"L;
houseLeftX ← leftMargin;
houseRightX ← houseLeftX + dsD.GetStringWidth[currentString, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: SubstituteCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];

currentString ← bracketString;
houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: BracketsHouseRefresher];
AddToSegment[];

currentString ← " for"L;
houseLeftX ← leftMargin + 210;
houseRightX ← houseLeftX + dsD.GetStringWidth[currentString, italicFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: italicFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: FindCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];

currentString ← bracketString;
houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
house ← House
[nextHouse: LOOPHOLE[1],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: BracketsHouseRefresher];
AddToSegment[];

currentString ← ""L;
houseRightX ← rightMargin;
houseLeftX ← rightMargin - dsD.GetPictureParameters[resetMenuIcon].width;
house ← House
[nextHouse: LOOPHOLE[0],
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: NIL,
picture: resetMenuIcon,
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: FALSE,
callable: TRUE,
usePicture: TRUE,
command: ShortenEditorMenuCommand,
houseRefresher: TextHouseRefresher];
AddToSegment[];
FinishSegment[];

END; -- of BuildSwappableMenus --


NewDCB: PROCEDURE RETURNS [dcbPtr: dsD.DCBptr] =
-- Returns a pointer to a newly allocated blank DCB.
BEGIN
dcbPtr ← Even[SIZE[dsD.DCB]];
dcbPtr↑ ← dsD.DCB
[next: dsD.DCBnil,
resolution: high,
background: drD.videoBackground,
indenting: 0,
width: 0,
bitmap: LOOPHOLE[0],
height: 0,
longBitmap: LOOPHOLE[LONG[0]]];
END; -- of NewDCB --


Even: PRIVATE PROCEDURE [nWords: CARDINAL] RETURNS [p: POINTER] =
-- Allocates nWords starting at an even address.
BEGIN
p ← AllocateStateNode[nWords + 1];
p ← p + Inline.BITAND[p, 1];
END; -- of Even --


AllocateLinePool: PRIVATE PROCEDURE RETURNS [line: LinePtr] =
-- Allocates enough lines to fill the screen as defined in dsD.numScanLines, links them
-- together and returns a pointer to the top of the chain.
BEGIN
node: LinePtr;
line ← NIL;
THROUGH [0 .. intC.numScanLines / dsD.lineHeight + 5) DO
node ← AllocateStateNode[SIZE[Line]];
node.nextLine ← line;
node.state ← trailingBlankLine;
node.rightX ← inD.leftMargin;
line ← node;
ENDLOOP;
END; -- of AllocateLinePool --


END. -- of InitInteractor --