-- file: InitInteractor
-- edited by Brotz, April 9, 1981 2:08 PM
-- edited by Levin, April 14, 1981 3:41 PM
-- edited by Schroeder, Wednesday Nov. 5, 1980 2:59 pm PST

DIRECTORY
AltoDefs,
displayCommon: FROM "DisplayCommon",
DMSTimeDefs,
drD: FROM "LaurelDriverDefs",
dsD: FROM "DisplayDefs",
exD: FROM "ExceptionDefs",
inD: FROM "InteractorDefs",
Inline,
intCommon: FROM "IntCommon",
lsD: FROM "LaurelStateDefs",
ovD: FROM "OverviewDefs",
String;

InitInteractor: PROGRAM
IMPORTS 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;


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 ← AllocateStateNode[SIZE[Region]];
rp↑ ← Region
[nextRegion: NIL,
dcb: NewDCB[],
regionType: mailCommandRegion,
topY: 0,
bottomY: 0,
cursorShape: bullsEye,
nbrs: np];
END; -- of InitMailCommandRegion --


InitTOCRegion: PROCEDURE RETURNS [rp: RegionPtr] =
-- Allocates and partially fills in the TOCRegion.
BEGIN
np: NbrPtr ← InitTOCTextNbr[];
intC.TOCRegion ← rp ← AllocateStateNode[SIZE[Region]];
rp↑ ← Region
[nextRegion: NIL,
dcb: NewDCB[],
regionType: tocRegion,
topY: 0,
bottomY: 0,
cursorShape: bullsEye,
nbrs: np];
END; -- of InitTOCRegion --


InitTOCCommandRegion: PROCEDURE RETURNS [rp: RegionPtr] =
-- Allocates and partially fills in the TOCCommandRegion.
BEGIN
np: NbrPtr ← InitBoundaryLineNbr[rightMargin - 16, bullsEye];
np.nextNbr ← InitTOCDMBoundaryPadNbr[];
np.nextNbr.nextNbr ← intC.tocCommandNbr ← LOOPHOLE[InitTOCCommandNbr[]];
np.nextNbr.nextNbr.nextNbr ← InitDMThumbLineNbr[];
intC.TOCCommandRegion ← rp ← AllocateStateNode[SIZE[Region]];
rp↑ ← Region
[nextRegion: NIL,
dcb: NewDCB[],
regionType: tocCommandRegion,
topY: 0,
bottomY: 0,
cursorShape: bullsEye,
nbrs: np];
END; -- of InitTOCCommandRegion --


InitDMRegion: PROCEDURE RETURNS [rp: RegionPtr] =
-- Allocates and partially fills in the DMRegion.
BEGIN
np: NbrPtr ← InitDMTextNbr[];
intC.DMRegion ← rp ← AllocateStateNode[SIZE[Region]];
rp↑ ← Region
[nextRegion: NIL,
dcb: NewDCB[],
regionType: dmRegion,
topY: 0,
bottomY: 0,
cursorShape: charArrow,
nbrs: np];
END; -- of InitDMRegion --


InitCMCommandRegion: PROCEDURE RETURNS [rp: RegionPtr] =
-- Allocates and partially fills in the CMCommandRegion.
BEGIN
np: NbrPtr ← InitBoundaryLineNbr[rightMargin - 16, bullsEye];
np.nextNbr ← InitDMCMBoundaryPadNbr[];
np.nextNbr.nextNbr ← intC.cmCommandNbr ← LOOPHOLE[InitCMCommandNbr[]];
np.nextNbr.nextNbr.nextNbr ← InitCMThumbLineNbr[];
intC.CMCommandRegion ← rp ← AllocateStateNode[SIZE[Region]];
rp↑ ← Region
[nextRegion: NIL,
dcb: NewDCB[],
regionType: cmCommandRegion,
topY: 0,
bottomY: 0,
cursorShape: bullsEye,
nbrs: np];
END; -- of InitCMCommandRegion --


InitCMRegion: PROCEDURE RETURNS [rp: RegionPtr] =
-- Allocates and partially fills in the CMRegion.
BEGIN
np: NbrPtr ← InitCMTextNbr[];
intC.CMRegion ← rp ← AllocateStateNode[SIZE[Region]];
rp↑ ← Region
[nextRegion: NIL,
dcb: NewDCB[],
regionType: cmRegion,
topY: 0,
bottomY: 0,
cursorShape: charArrow,
nbrs: np];
END; -- of InitCMRegion --


InitExceptionsRegion: PROCEDURE RETURNS [rp: RegionPtr] =
-- Allocates and partially fills in the ExceptionsRegion.
BEGIN
np: NbrPtr ← InitBoundaryLineNbr[rightMargin, charArrow];
np.nextNbr ← InitExceptionsNbr[];
intC.exceptionsRegion ← rp ← AllocateStateNode[SIZE[Region]];
rp↑ ← Region
[nextRegion: NIL,
dcb: NewDCB[],
regionType: exceptionsRegion,
topY: 0,
bottomY: 0,
cursorShape: charArrow,
nbrs: np];
END; -- of InitExceptionsRegion --


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


InitTOCDMBoundaryPadNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in a BoundaryPadNbr.
BEGIN
np ← intC.tocdmBoundaryPadNbr ← AllocateStateNode[SIZE[Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: rightMargin - 16,
rightX: rightMargin,
cursorShape: scroll,
nbrVariant: boundaryPad
[command: MoveTOCDMBoundary,
nbrTracker: BoundaryPadNbrTracker]];
END; -- of InitTOCDMBoundaryPadNbr --


InitDMCMBoundaryPadNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in a BoundaryPadNbr.
BEGIN
np ← intC.dmcmBoundaryPadNbr ← AllocateStateNode[SIZE[Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: rightMargin - 16,
rightX: rightMargin,
cursorShape: scroll,
nbrVariant: boundaryPad
[command: MoveDMCMBoundary,
nbrTracker: BoundaryPadNbrTracker]];
END; -- of InitDMCMBoundaryPadNbr --


InitTOCThumbLineNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in a BoundaryLineNbr.
BEGIN
np ← intC.tocThumbLineNbr ← AllocateStateNode[SIZE[Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: leftMargin,
rightX: rightMargin - 2,
cursorShape: bullsEye,
nbrVariant: thumbLine
[exists: FALSE,
length: 0,
start: 0,
end: 0,
selection: 0,
startX: leftMargin+4,
endX: leftMargin+4,
selectionX: leftMargin+4,
command: ThumbTOC,
nbrTracker: ThumbLineNbrTracker]];
END; -- of InitTOCThumbPadNbr --


InitDMThumbLineNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in a BoundaryLineNbr.
BEGIN
np ← intC.dmThumbLineNbr ← AllocateStateNode[SIZE[Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: leftMargin,
rightX: rightMargin - 2,
cursorShape: bullsEye,
nbrVariant: thumbLine
[exists: FALSE,
length: 0,
start: 0,
end: 0,
selection: 0,
startX: leftMargin,
endX: leftMargin,
selectionX: leftMargin,
command: ThumbDM,
nbrTracker: ThumbLineNbrTracker]];
END; -- of InitDMThumbPadNbr --


InitCMThumbLineNbr: PROCEDURE RETURNS [np: NbrPtr] =
-- Allocates and partially fills in a BoundaryLineNbr.
BEGIN
np ← intC.cmThumbLineNbr ← AllocateStateNode[SIZE[Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: leftMargin,
rightX: rightMargin - 2,
cursorShape: bullsEye,
nbrVariant: thumbLine
[exists: FALSE,
length: 0,
start: 0,
end: 0,
selection: 0,
startX: leftMargin,
endX: leftMargin,
selectionX: leftMargin,
command: ThumbCM,
nbrTracker: ThumbLineNbrTracker]];
END; -- of InitCMThumbPadNbr --


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.gvTestingMode THEN testingModeString.length ELSE 0)];
String.AppendString[commandString, versionString];
IF intC.gvTestingMode THEN String.AppendString[commandString, testingModeString];
houseLeftX ← leftMargin;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, plainFace];
hp ← h ← intC.versionHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: commandString,
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: TextHouseRefresher];

-- timeHouse
houseRightX ← rightMargin;
houseLeftX ← houseRightX;
h ← h.nextHouse ← intC.timeHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[DMSTimeDefs.timeStringLength],
fixedEdge: right,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: TextHouseRefresher];

commandString ← AllocateStateString[40]; -- length of "You have new mail."
commandString.length ← 0;
houseLeftX ← leftMargin;
houseRightX ← houseLeftX;
h ← h.nextHouse ← intC.newMessagesHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: commandString,
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: TextHouseRefresher];

-- free pages house
freeDiskPages ← " free disk pages"L;
commandString ← AllocateStateString[5]; -- length of "99999"
String.AppendString[commandString, " "];
houseRightX ← rightMargin - dsD.GetStringWidth[freeDiskPages, plainFace];
houseLeftX ← houseRightX;
h ← h.nextHouse ← intC.freePagesHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: commandString,
fixedEdge: right,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: TextHouseRefresher];

-- free pages constant text house
commandString ← AllocateStateString[freeDiskPages.length];
String.AppendString[commandString, freeDiskPages];
houseRightX ← rightMargin;
houseLeftX ← houseRightX;
h ← h.nextHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 1,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: commandString,
fixedEdge: right,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: TextHouseRefresher];

commandString ← "User"L;
houseLeftX ← leftMargin + commandIndent;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.userCommandHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 2,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: LoginCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
intC.userBracketsHouse ← h ← h.nextHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 2,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[maxBracketStringLength],
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: BracketsHouseRefresher];

commandString ← "New mail"L;
houseLeftX ← leftMargin + 165;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.newMailCommandHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 2,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: FALSE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: GetNewMailCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

commandString ← "Mail file"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.mailFileCommandHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 2,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: GetMailFileCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
intC.mailFileBracketsHouse ← h ← h.nextHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 2,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[maxBracketStringLength],
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: BracketsHouseRefresher];

commandString ← "Quit"L;
houseRightX ← rightMargin;
houseLeftX ← houseRightX - dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.quitCommandHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 2,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: QuitCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

np ← AllocateStateNode[SIZE[Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: leftMargin,
rightX: rightMargin,
cursorShape: bullsEye,
nbrVariant: command
[houses: hp,
nbrTracker: CommandTracker]];
END; -- of InitMailCommandNbr --


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[Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: 0,
rightX: rightMargin,
cursorShape: lineArrow,
nbrVariant: tocText
[lines: line,
firstLineOffScreen: line,
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 ← AllocateStateNode[SIZE[House]];
hp↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: FALSE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: DisplayMessageCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

commandString ← "Delete"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.deleteCommandHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: FALSE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: DeleteCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

commandString ← "Undelete"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.undeleteCommandHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: FALSE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: UndeleteCommand,
houseRefresher: TextHouseRefresher];
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 ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: MoveMessageToFileCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

IF intC.disableWriting THEN
BEGIN
commandString ← NIL;
houseLeftX ← houseRightX;
END
ELSE BEGIN
houseLeftX ← houseRightX + preBracketSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth["{}"L, boldFace];
commandString ← AllocateStateString[maxBracketStringLength];
END;
intC.moveToBracketsHouse ← h ← h.nextHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: commandString,
fixedEdge: left,
typeface: plainFace,
needsConfirmation: FALSE,
trackerIndicateDone: FALSE,
callable: FALSE,
command: NullCommand,
houseRefresher: IF intC.disableWriting THEN TextHouseRefresher
ELSE BracketsHouseRefresher];

houseRightX ← rightMargin;
IF intC.disableWriting THEN
BEGIN
commandString ← ""L;
houseLeftX ← houseRightX;
END
ELSE BEGIN
commandString ← "Hardcopy"L;
houseLeftX ← houseRightX - dsD.GetStringWidth[commandString, boldFace];
END;
intC.hardcopyCommandHouse ← h ← h.nextHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: FALSE,
callable: TRUE,
command: HardcopyCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

np ← AllocateStateNode[SIZE[Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: leftMargin,
rightX: rightMargin,
cursorShape: bullsEye,
nbrVariant: command
[houses: hp,
nbrTracker: CommandTracker]];
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[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 ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: NewFormCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

commandString ← "Answer"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.answerCommandHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: AnswerCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

commandString ← "Forward"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.forwardCommandHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: ForwardCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

commandString ← "Get"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
intC.getCommandHouse ← h ← h.nextHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: GetCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

IF intC.disableWriting THEN
BEGIN
commandString ← ""L;
houseLeftX ← houseRightX;
END
ELSE BEGIN
commandString ← "Put"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
END;
h ← h.nextHouse ← intC.putCommandHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: PutCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

commandString ← "Copy"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
intC.copyCommandHouse ← h ← h.nextHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: TRUE,
callable: TRUE,
command: CopyCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

commandString ← "Run"L;
houseLeftX ← houseRightX + interCommandSpacing;
houseRightX ← houseLeftX + dsD.GetStringWidth[commandString, boldFace];
h ← h.nextHouse ← intC.runCommandHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: left,
typeface: boldFace,
needsConfirmation: TRUE,
trackerIndicateDone: FALSE,
callable: TRUE,
command: RunCommand,
houseRefresher: TextHouseRefresher];
String.AppendString[h.text, commandString];

commandString ← "delivered";
houseRightX ← rightMargin;
houseLeftX ← houseRightX - dsD.GetStringWidth[commandString, italicFace];
h ← h.nextHouse ← intC.deliverCommandHouse ← AllocateStateNode[SIZE[House]];
h↑ ← House
[nextHouse: NIL,
lineNumber: 0,
topY: 0,
bottomY: 0,
leftX: houseLeftX,
rightX: houseRightX,
text: AllocateStateString[commandString.length],
fixedEdge: right,
typeface: italicFace,
needsConfirmation: TRUE, -- was FALSE
trackerIndicateDone: TRUE,
callable: FALSE,
command: SendCommand,
houseRefresher: TextHouseRefresher];

np ← AllocateStateNode[SIZE[Nbr]];
np↑ ← Nbr
[nextNbr: NIL,
nLines: 0,
topY: 0,
bottomY: 0,
leftX: leftMargin,
rightX: rightMargin,
cursorShape: bullsEye,
nbrVariant: command
[houses: hp,
nbrTracker: CommandTracker]];
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[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[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];
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 .. dsD.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 --