--LispToolImpl.mesa
--Created by
--   JFung.PASA	  	20-Sep-83 10:10:02

--last edited by
--   JFung.PASA	   	18-Jan-84 12:31:45



DIRECTORY

     CmFile,
     Cursor USING [Set],
     Display,
     Event,
     EventTypes USING [deactivate],
     Exec,
     File,
     FileTransfer,
     Format USING [StringProc],
     FormSW USING [
          AllocateItemDescriptor, ClientItemsProcType, CommandItem, Destroy,
          Display, DisplayItem, Enumerated, EnumeratedNotifyProcType,
          EnumeratedItem, FindItem, FreeHintsProcType, ItemHandle, line0, line1,
          line2, line3, newLine, NumberItem, MenuProcType, ProcType, SetTagPlaces,
          StringItem],
     Heap USING [systemZone],
     LispToolOps,
     Process USING [Pause, SecondsToTicks],
     Put USING [CR, Line, LongDecimal, LongString, Text],
     Runtime USING [GetBcdTime],
     String,
     StringLookUp USING [noMatch, TableDesc],
     Supervisor USING [
          AddDependency, AgentProcedure, CreateSubsystem, EnumerationAborted,
          RemoveDependency, SubsystemHandle],
     TemporaryBooting USING [BootButton, BootFromVolume],
     Time USING [Append, Unpack],
     Token,
     Tool USING [
          Create, Destroy, MakeFileSW, MakeFormSW, MakeMsgSW, MakeSWsProc,
          UnusedLogName],
     ToolDriver USING [Address, NoteSWs, RemoveSWs],
     ToolWindow USING [Activate, Deactivate, DisplayProcType, TransitionProcType],
     UserInput USING [
          ClearInputFocusOnMatch, CreatePeriodicNotify, PeriodicProcType,
          WaitForConfirmation, WaitNoButtons],
     Version USING [Append],
     Volume,
     Window USING [
          BitmapPlace, Box, GetBox, GetChild, GetDisplayProc, GetParent, Handle,
          SetDisplayProc, Stack, ValidateTree];



LispToolImpl: PROGRAM
     IMPORTS
          CmFile, Cursor, Display, Event, Exec, FormSW, Heap, LispToolOps, Process,
          Put, Runtime, String, Supervisor, TemporaryBooting, Time, Token, Tool,
          ToolDriver, ToolWindow, UserInput, Version, Volume, Window

     EXPORTS LispToolOps =


     BEGIN OPEN ILT: LispToolOps;

     debug: BOOLEAN ← FALSE;
     floppyWH: Window.Handle ← NIL;
     toolData: PUBLIC ILT.DataHandle ← NIL;
     windowHandle: PUBLIC Window.Handle ← NIL;
     NSFileName: LONG STRING ← 	"[Server:Domain:Org]<Directory><SubDirectories>FileName.sysout"L;
     IFSFileName: LONG STRING ← 	"[Server]<Directory><SubDirectories>FileName.sysout"L;
     
     active: BOOLEAN ← FALSE;

     <<     agent: Supervisor.SubsystemHandle = Supervisor.CreateSubsystem[
          CheckDeactivate];
	>>
     formDisplay: ToolWindow.DisplayProcType ← NIL;
     indicatorBox: Window.Box = [[10, 10], [16, 16]];
     volume: Volume.ID ← Volume.nullID;


     CheckDeactivate: Supervisor.AgentProcedure =
          BEGIN
          ENABLE UNWIND => NULL;
          IF event = EventTypes.deactivate AND ILT.windowHandle # NIL
               AND ILT.windowHandle = eventData AND ILT.toolData.busy THEN
               BEGIN
               Put.Line[
                    ILT.toolData.msgSW,
                    "The tool is busy:  aborting deactivation"L];
               ERROR Supervisor.EnumerationAborted;
               END;
          END;  --CheckDeactivate



     ClearCommandSubwindow: PUBLIC PROCEDURE =
          BEGIN
          item: FormSW.ItemHandle;

          FOR i: CARDINAL ← 0, i + 1 UNTIL
               (item ← FormSW.FindItem[toolData.commandSW, i]) = NIL DO
               item.flags.invisible ← TRUE ENDLOOP;
          FormSW.Display[toolData.commandSW];
          toolData.indicator ← left;
          --formDisplay ← Window.GetDisplayProc[toolData.commandSW];
          formDisplay ← Window.SetDisplayProc[toolData.commandSW, DisplayEmpty];
          END;  --ClearCommandSubwindow



     ClearFileSubwindow: PUBLIC PROCEDURE =
          BEGIN
          item: FormSW.ItemHandle;

          FOR i: CARDINAL ← 0, i + 1 UNTIL
               (item ← FormSW.FindItem[toolData.fileSW, i]) = NIL DO
               item.flags.invisible ← TRUE ENDLOOP;
          FormSW.Display[ILT.toolData.fileSW];
          --formDisplay ← Window.GetDisplayProc[toolData.fileSW];
          END;  --ClearFileSubwindow


     ClearMsgSubwindow: PUBLIC PROCEDURE =
          BEGIN
          item: FormSW.ItemHandle;

          FOR i: CARDINAL ← 0, i + 1 UNTIL
               (item ← FormSW.FindItem[ILT.toolData.msgSW, i]) = NIL DO
               item.flags.invisible ← TRUE ENDLOOP;
          FormSW.Display[ILT.toolData.msgSW];
          --formDisplay ← Window.GetDisplayProc[ILT.toolData.msgSW];
          END;  --ClearMsgSubwindow



     ClearSubWindows: PROCEDURE =
          BEGIN
          --ClearFileSubwindow;
          ClearMsgSubwindow;
          END;  --ClearSubWindows


     ClientTransition: ToolWindow.TransitionProcType =
          -- This procedure is called whenever the system determines that this
          -- Tool's state is undergoing a user invoked transition.
          -- In this Example we demonstrate a technique that minimizes the memory
          -- requirements for a Tool that is inactive.
          BEGIN
          SELECT TRUE FROM
               old = inactive =>
                    BEGIN
                    IF ILT.toolData = NIL THEN
                         ILT.toolData ← Heap.systemZone.NEW[ILT.Data ← []];
                    ProcessUserDotCM[];
                    active ← TRUE;
                    END;
               new = inactive =>
                    BEGIN
                    <<Supervisor.RemoveDependency[
                        client: agent, implementor: Event.toolWindow];
			>>
                    IF ILT.toolData # NIL THEN
                         BEGIN
                         FormSW.Destroy[ILT.toolData.paramSW];
                         FormSW.Destroy[ILT.toolData.commandSW];
                         Heap.systemZone.FREE[@ILT.toolData];
                         END;
                    --ToolDriver.RemoveSWs[tool: "LispTool"L];
                    active ← FALSE;
                    END;
               ENDCASE
          END;  --ClientTransition




     Confirm: PUBLIC PROCEDURE RETURNS [okay: BOOLEAN] =
          BEGIN
          Cursor.Set[mouseRed];
          [, okay] ← UserInput.WaitForConfirmation[];
          Cursor.Set[textPointer];
          UserInput.WaitNoButtons[];
          END;  --Confirm



     DisplayCommandSubwindow: PUBLIC PROCEDURE =
          BEGIN OPEN FormSW;
          item: FormSW.ItemHandle;

          toolData.indicator ← off;
          [] ← Window.SetDisplayProc[toolData.commandSW, formDisplay];
          FormSW.Display[toolData.commandSW];
          FOR i: CARDINAL ← 0, i + 1 UNTIL
               (item ← FormSW.FindItem[toolData.commandSW, i]) = NIL DO
               item.flags.invisible ← FALSE ENDLOOP;

          FormSW.Display[toolData.commandSW];
          END;  --DisplayCommandSubwindow



     DisplayEmpty: PUBLIC ToolWindow.DisplayProcType =
          BEGIN
          ENABLE UNWIND => NULL;
          IF ~toolData.busy THEN RETURN;
          --Display.White[window, [[0, 0], window.GetBox[].dims]];
          DisplayIndicator[window];
          END;  --DisplayEmpty


     DisplayFile: PUBLIC PROCEDURE[] =
          BEGIN
          
          IF debug THEN {
               Put.Line[toolData.fileSW, "DisplayFile...."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };

          IF toolData.fileServer = IFS THEN
               toolData.filePathName ← String.CopyToNewString[
                    s: IFSFileName,
                    z: Heap.systemZone]
          ELSE
               toolData.filePathName ← String.CopyToNewString[
                    s: NSFileName,
                    z: Heap.systemZone];
          FormSW.DisplayItem[toolData.paramSW, 2];
          END;  --DisplayFile




     DisplayFileSize: PUBLIC PROCEDURE [size: File.PageCount] =
          BEGIN

          IF debug THEN {
               Put.Line[toolData.fileSW, "DisplayFileSize...."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          toolData.vMemSize ← size;
          IF debug THEN {
               Put.LongDecimal[toolData.fileSW, toolData.vMemSize];
               Process.Pause[Process.SecondsToTicks[5]];
               };

          FormSW.DisplayItem[toolData.paramSW, 4];
          END;  --DisplayFileSize


     <<
     DisplayIndicator: ToolWindow.DisplayProcType =
          BEGIN
          pattern: ARRAY [0..1] OF ARRAY [0..8) OF WORD;
          left: WORD = 177400B;
          right: WORD = 000377B;
          SELECT toolData.indicator FROM
               left =>
                    BEGIN
                    pattern ← [ALL[left], ALL[right]];
                    Display.Bitmap[
                         window: window, box: indicatorBox,
                         address: [word: @pattern, bit: 0], bitmapBitWidth: 16];
                    END;
               right =>
                    BEGIN
                    pattern ← [ALL[right], ALL[left]];
                    Display.Bitmap[
                         window: window, box: indicatorBox,
                         address: [word: @pattern, bit: 0], bitmapBitWidth: 16];
                    END;
               ENDCASE;
          END;  --DisplayIndicator
>>

     --taken from StarFileTool

     DisplayIndicator: PUBLIC ToolWindow.DisplayProcType = {
          pattern: ARRAY [0..1] OF ARRAY [0..8) OF WORD;
          SELECT toolData.indicator FROM
               left => {
                    pattern ← [
                         [
                         111000B, 052000B, 034000B, 177000B, 034000B, 052000B,
                         111000B, 000000B], [
                         000222B, 000124B, 000070B, 000376B, 000070B, 000124B,
                         000222B, 000000B]];
                    Display.Bitmap[
                         window, indicatorBox, [@pattern, , 0], 16,
                         Display.replaceFlags]};
               right => {
                    pattern ← [
                         [
                         000222B, 000124B, 000070B, 000376B, 000070B, 000124B,
                         000222B, 000000B], [
                         111000B, 052000B, 034000B, 177000B, 034000B, 052000B,
                         111000B, 000000B]];
                    Display.Bitmap[
                         window, indicatorBox, [@pattern, , 0], 16,
                         Display.replaceFlags]};
               ENDCASE};  --DisplayIndicator



     DoInstall: UserInput.PeriodicProcType =
          BEGIN
          ClearSubWindows;
          IF debug THEN {
               Put.Line[toolData.fileSW, "Start Install ....."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          GetVolumeName[];
          IF Confirm[] THEN
               BEGIN
               ILT.LoginProc[];
               ClearCommandSubwindow;
               DisplayIndicator[toolData.commandSW];
               toolData.busy ← TRUE;
               ILT.InstallProc[toolData.volName];
               toolData.busy ← FALSE;
               DisplayCommandSubwindow;
               END;
          IF debug THEN {
               Put.Line[toolData.fileSW, "Install Done ....."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          END;  --DoInstall





     FormSWEraseProc: FormSW.ProcType =
          BEGIN
          toolData.busy ← TRUE;
          ClearSubWindows;
          IF debug THEN {
               Put.Line[toolData.fileSW, "Start Erase Proc....."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          GetVolumeName[];
          IF Confirm[] THEN
               BEGIN
               ILT.EraseProc[toolData.volName];
               ILT.toolData.vMemSize ← 0;
               ILT.SetVMemFileSize[0];
               DisplayFileSize[0];
               END;
          ILT.toolData.busy ← FALSE;
          END;  --FormSWEraseProc




     FormSWFloppyProc: FormSW.ProcType =
          BEGIN
          IF debug THEN {
               Put.Line[toolData.fileSW, "FormSWFloppyDup...."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          Put.Line[toolData.fileSW, "To Be Implemented."L];
          --ILT.FloppyStuff[];
          END;  --FormSWFloppyProc




     FormSWHelpProc: FormSW.ProcType =
          BEGIN
          toolData.busy ← TRUE;
          ClearSubWindows;
          IF debug THEN {
               Put.Line[toolData.fileSW, "FormSWHelpProc...."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          ILT.DisplayWriteUp;
          ILT.toolData.busy ← FALSE;
          END;  --FormSWHelpProc


     FormSWInstallProc: FormSW.ProcType =
          BEGIN
          [] ← UserInput.CreatePeriodicNotify[
               proc: DoInstall, window: sw, rate: 0];
          END;  --FormSWInstallProc



     FormSWLoginProc: FormSW.ProcType =
          BEGIN
          toolData.busy ← TRUE;
          ClearSubWindows;
          IF debug THEN {
               Put.Line[toolData.fileSW, "Start Login Proc....."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          ILT.LoginProc[];
          toolData.busy ← FALSE;
          END;  --FormSWLoginProc


     FormSWRemoteBoot: FormSW.ProcType =
          BEGIN
          IF debug THEN {
               Put.Line[toolData.fileSW, "FormSWRemoteBoot...."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };

          ILT.BootStuff[];
          END;  --FormSWRemoteBoot


     FormSWQuitProc: FormSW.ProcType =
          BEGIN
          --v: Volume.ID;
          all: Volume.TypeSet = [
               normal: TRUE, debugger: TRUE, debuggerDebugger: TRUE];

          IF debug THEN {
               Put.Line[toolData.fileSW, "Quit Proc..."L];
               --Process.Pause[Process.SecondsToTicks[5]];
               };
          [] ← ToolWindow.Deactivate[windowHandle];

          --FOR v ← Volume.GetNext[Volume.nullID, all], Volume.GetNext[v, all] WHILE
          -- v ~= Volume.systemID DO ENDLOOP;
          --UserInput.ClearInputFocusOnMatch[windowHandle];
          --TemporaryBooting.BootFromVolume[v];
          END;  --FormSWQuitProc


     FormSWScavengeProc: FormSW.ProcType =
          BEGIN
          toolData.busy ← TRUE;
          ClearSubWindows;
          IF debug THEN {
               Put.Line[ILT.toolData.fileSW, "Scavenge Proc..."L];
               --Process.Pause[Process.SecondsToTicks[5]];
               };
          GetVolumeName[];
          IF Confirm[] THEN ILT.ScavengeProc[toolData.volName];
          toolData.busy ← FALSE;
          END;  --FormSWScavengeProc



     FormSWSetFileSize: FormSW.ProcType =
          BEGIN
          toolData.busy ← TRUE;
          ClearSubWindows;

          IF debug THEN {
               Put.Line[toolData.fileSW, "Start SetFileSize....."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          Put.Text[toolData.fileSW, "VMem size = "L];
          Put.LongDecimal[toolData.fileSW, toolData.vMemSize];
          Put.CR[toolData.fileSW];
          IF Confirm[] THEN ILT.SetVMemFileSize[toolData.vMemSize];
          toolData.busy ← FALSE;
          END;  --FormSWSetFileSize



     FormSWSetProc: FormSW.ProcType =
          BEGIN
          toolData.busy ← TRUE;
          ClearSubWindows;
          IF debug THEN {
               Put.Line[toolData.fileSW, "SetVolume Proc..."L];
               --Process.Pause[Process.SecondsToTicks[5]];
               };
          GetVolumeName[];
          IF Confirm[] THEN [] ← ILT.SetVolumeProc[toolData.volName];
          toolData.busy ← FALSE;
          END;


     FormSWStartProc: FormSW.ProcType =
          BEGIN
          ClearSubWindows;
          IF debug THEN {
               Put.Line[toolData.fileSW, "TemporaryBooting..."L];
               --Process.Pause[Process.SecondsToTicks[5]];
               };
          GetVolumeName[];
          IF Confirm[] THEN
               IF ILT.SetVolumeProc[toolData.volName] THEN
                    TemporaryBooting.BootButton[];
          END;  --FormSWStartProc



     FormSWVolHintsProc: FormSW.MenuProcType =
          BEGIN
          RETURN[
               hints: DESCRIPTOR[
               @ILT.toolData.volHints[0], ILT.toolData.volHints.length],
                    freeHintsProc: HintsNoLongerBusy, replace: TRUE];

          END;


     HintsNoLongerBusy: FormSW.FreeHintsProcType =
          BEGIN
          size: File.PageCount;

          ClearMsgSubwindow;
          size ← ILT.GetFileSize[];
          DisplayFileSize[size];
          ILT.toolData.busy ← FALSE;
          END;  --HintsNoLongerBusy



     GetVolumeName: PROCEDURE[] =
          BEGIN
          Put.Text[ILT.toolData.fileSW, "Volume = "L];
          Put.LongString[ILT.toolData.fileSW, ILT.toolData.volName];
          Put.CR[ILT.toolData.fileSW];
          END;  --GetVolumeName



     Init: PROCEDURE =
          BEGIN
          --h: Exec.Handle;
          --execWrite: Format.StringProc ← Exec.OutputProc[h];
          --execWrite["Creating tool window.."L]; 
          --Process.Pause[Process.SecondsToTicks[5]];
          Exec.AddCommand["LispTool.~"L, LispTool, Unload];
          END;  --Init


     <<InvertIndicator: FileTransfer.ClientProc =
          BEGIN
          ENABLE UNWIND => NULL;
          IF ~ILT.toolData.busy THEN RETURN;
          SELECT ILT.toolData.indicator FROM
               left => ILT.toolData.indicator ← right;
               off, right => ILT.toolData.indicator ← left;
               ENDCASE;
          Display.Invert[ILT.toolData.commandSW, indicatorBox];
          END;  --InvertIndicator
	  >>


     --taken from StarFileTool
     InvertIndicator: PUBLIC PROC [] =
          BEGIN
          ENABLE UNWIND => NULL;
          pattern: ARRAY [0..1] OF ARRAY [0..8) OF WORD;

          IF ~toolData.busy THEN RETURN;
          SELECT toolData.indicator FROM
               left => {
                    pattern ← [
                         [
                         000222B, 000124B, 000070B, 000376B, 000070B, 000124B,
                         000222B, 000000B], [
                         111000B, 052000B, 034000B, 177000B, 034000B, 052000B,
                         111000B, 000000B]];
                    Display.Bitmap[
                         toolData.commandSW, indicatorBox, [@pattern, , 0], 16,
                         Display.replaceFlags];
                    toolData.indicator ← right};
               right => {
                    pattern ← [
                         [
                         111000B, 052000B, 034000B, 177000B, 034000B, 052000B,
                         111000B, 000000B], [
                         000222B, 000124B, 000070B, 000376B, 000070B, 000124B,
                         000222B, 000000B]];
                    Display.Bitmap[
                         toolData.commandSW, indicatorBox, [@pattern, , 0], 16,
                         Display.replaceFlags];
                    toolData.indicator ← left};
               off => toolData.indicator ← left;
               ENDCASE;
          END;



     ListLogicalVolumes: PUBLIC PROC RETURNS [nVols: CARDINAL] =
          BEGIN
          i: CARDINAL;

          s: STRING ← [80];
          v: Volume.ID;
          all: Volume.TypeSet = [
               normal: TRUE, debugger: TRUE, debuggerDebugger: TRUE];

          IF toolData.volName # NIL THEN RETURN;
          -- First, count the logical volumes.
          nVols ← 0;
          FOR v ← Volume.GetNext[Volume.nullID, all], Volume.GetNext[v, all] WHILE
               v ~= Volume.nullID DO nVols ← nVols + 1; ENDLOOP;

          -- Now build up the table
          toolData.volHints ← Heap.systemZone.NEW[ILT .VolHints[nVols]];
          FOR i IN [0..nVols) DO
               v ← Volume.GetNext[v, all];
               Volume.GetLabelString[v, s];
               toolData.volHints[i] ← String.CopyToNewString[s, Heap.systemZone];
               ENDLOOP;

          END;  --ListLogicalVolumes



     LispTool: Exec.ExecProc =
          BEGIN
          execWrite: Format.StringProc ← Exec.OutputProc[h];
          --execWrite["Creating tool window.."L]; 
          --Process.Pause[Process.SecondsToTicks[5]];
          IF (ILT.windowHandle # NIL) AND ~active THEN
               ToolWindow.Activate[ILT.windowHandle]
          ELSE ILT.windowHandle ← MakeTool[];
          END;  --LispTool



     LispToolActivate: PUBLIC PROCEDURE =
          BEGIN
          IF windowHandle = NIL THEN windowHandle ← MakeTool[];
          ToolWindow.Activate[windowHandle];
          Window.Stack[
               windowHandle, Window.GetChild[
               Window.GetParent[windowHandle]]];  -- top me
          Window.ValidateTree[];
          END;  --LispToolActivate




     MakeCommands: FormSW.ClientItemsProcType =
          BEGIN OPEN FormSW;

          tabs: ARRAY [0..5) OF CARDINAL ← [0, 20, 40, 60, 75];
          nItems: CARDINAL = 9;
          items ← AllocateItemDescriptor[nItems];

          items[0] ← CommandItem[
               tag: "Install File"L, place: newLine, proc: FormSWInstallProc];

          items[1] ← CommandItem[tag: "Start Volume"L, proc: FormSWStartProc];

          items[2] ← CommandItem[tag: "Set VMem Size"L, proc: FormSWSetFileSize];

          <<          items[3] ← CommandItem[tag: "Set Vol Password"L, proc: FormSWHelpProc];
>>

          items[3] ← CommandItem[tag: "Floppy"L, proc: FormSWFloppyProc];


          items[4] ← CommandItem[tag: "Help"L, proc: FormSWHelpProc];

          items[5] ← CommandItem[
               tag: "Erase Volume"L, place: newLine, proc: FormSWEraseProc];

          items[6] ← CommandItem[
               tag: "Scavenge Volume"L, proc: FormSWScavengeProc];

          items[7] ← CommandItem[tag: "Remote Boot"L, proc: FormSWRemoteBoot];

          items[8] ← CommandItem[tag: "Quit"L, proc: FormSWQuitProc];

          SetTagPlaces[items, DESCRIPTOR[tabs], FALSE];
          RETURN[items, TRUE];
          END;  --MakeCommands



     MakeParams: FormSW.ClientItemsProcType =
          BEGIN OPEN FormSW;

          i, nVols: CARDINAL;
          tabs: ARRAY [0..4) OF CARDINAL ← [0, 40, 60, 75];
          nItems: CARDINAL = 9;

          docForm: ARRAY [0..2) OF Enumerated ← [
               ["General"L, ILT.DocType[general]], [
               "ErrorMsg"L, ILT.DocType[errorMsg]]];

          serverForm: ARRAY [0..2) OF Enumerated ← [
               ["IFS"L, ILT.ServerType[IFS]], ["NS"L, ILT.ServerType[NS]]];

          items ← AllocateItemDescriptor[nItems];
          nVols ← ListLogicalVolumes[];

          String.Copy[toolData.volName, toolData.volHints[0]];
          FOR i IN [0..nVols) DO
               IF String.Equivalent[toolData.volHints[i], "Lisp"L] THEN
                    BEGIN
                    String.Replace[
                         @toolData.volName, toolData.volHints[i], Heap.systemZone];
                    EXIT;
                    END;
               ENDLOOP;


          items[0] ← EnumeratedItem[
               tag: "Doc."L, place: newLine, z: Heap.systemZone, feedback: all,
               value: @ILT.toolData.docType, copyChoices: TRUE,
               choices: DESCRIPTOR[docForm]];

          items[1] ← EnumeratedItem[
               tag: "File Server"L, z: Heap.systemZone, feedback: all,
               value: @ILT.toolData.fileServer, copyChoices: TRUE,
               proc: ServerNotifyProc, choices: DESCRIPTOR[serverForm]];


          items[2] ← StringItem[
               tag: "File"L, place: newLine, string: @ILT.toolData.filePathName,
               inHeap: TRUE];

          items[3] ← StringItem[
               tag: "Volume Menu"L, place: newLine, string: @ILT.toolData.volName,
               inHeap: TRUE, menuProc: FormSWVolHintsProc];

          <<         items[3] ← StringItem[
               tag: "Volume Password"L, string: @ILT.toolData.userPassword,
               inHeap: TRUE, feedback: password];
>>
          items[4] ← NumberItem[
               tag: "VMem Size (Pages) "L, value: @ILT.toolData.vMemSize];

          items[5] ← StringItem[
               tag: "User"L, place: newLine, string: @ILT.toolData.userName,
               inHeap: TRUE];

          items[6] ← StringItem[
               tag: "Password"L, string: @ILT.toolData.userPassword, inHeap: TRUE,
               feedback: password];

          items[7] ← StringItem[
               tag: "Domain"L, place: newLine, string: @ILT.toolData.domainName,
               inHeap: TRUE];

          items[8] ← StringItem[
               tag: "Organization"L, string: @ILT.toolData.organizationName,
               inHeap: TRUE];

          SetTagPlaces[items, DESCRIPTOR[tabs], FALSE];
          RETURN[items, TRUE]
          END;  --MakeParams




     MakeSWs: Tool.MakeSWsProc =
          BEGIN
          size: File.PageCount;

          logName: STRING ← [40];
          addresses: ARRAY [0..4) OF ToolDriver.Address;

          Tool.UnusedLogName[unused: logName, root: "InstallLispTool.log"L];
          ILT.toolData.msgSW ← Tool.MakeMsgSW[window: window, lines: 2];

          ILT.toolData.paramSW ← Tool.MakeFormSW[
               window: window, formProc: MakeParams];
          ILT.toolData.commandSW ← Tool.MakeFormSW[
               window: window, formProc: MakeCommands];

          ILT.toolData.fileSW ← Tool.MakeFileSW[window: window, name: logName];
          size ← ILT.GetFileSize[];
          DisplayFileSize[size];
          DisplayFile[];

          --Supervisor.AddDependency[client: agent, implementor: Event.toolWindow];

          -- do the ToolDriver stuff
          addresses ← [
               [name: "msgSW"L, sw: ILT.toolData.msgSW],
               --[name: "formSW"L, sw: ILT.toolData.formSW],
               [name: "ParamSW"L, sw: ILT.toolData.paramSW], [
               name: "CmdSW"L, sw: ILT.toolData.commandSW], [
               name: "fileSW"L, sw: ILT.toolData.fileSW]];
          ToolDriver.NoteSWs[tool: "LispTool"L, subwindows: DESCRIPTOR[addresses]];

          END;  --MakeSWs




     MakeTool: PROCEDURE RETURNS [wh: Window.Handle] =
          BEGIN
          heraldName: STRING ← [80];

          String.AppendString[heraldName, "XSIS:Xerox Install Lisp Tool"L];
          String.AppendString[heraldName, " of "L];
          Time.Append[heraldName, Time.Unpack[Runtime.GetBcdTime[]]];
          heraldName.length ← heraldName.length - 3;  -- gun the seconds
          String.AppendString[heraldName, " on Pilot Version "L];
          Version.Append[heraldName];

          RETURN[
               Tool.Create[
                    makeSWsProc: MakeSWs, initialState: default,
                    clientTransition: ClientTransition, name: heraldName,
                    tinyName1: "Install"L, tinyName2: "LispTool"L]]
          END;  --MakeTool



     ProcessUserDotCM: PROCEDURE =
          BEGIN
          CMOption: TYPE = MACHINE DEPENDENT{
               Domain, User, Password, NSFile, IFSFile, Org,
               noMatch(StringLookUp.noMatch)};
          DefinedOption: TYPE = CMOption [Domain..Org];
          cmOptionTable: ARRAY DefinedOption OF LONG STRING ← [
               Domain: "Domain"L, User: "User"L, Password: "Password"L,
               Org: "Organization"L, NSFile: "NSLisp", IFSFile: "PUPLisp"];
          cmIndex: CMOption;

          CheckType: PROCEDURE [h: CmFile.Handle, table: StringLookUp.TableDesc]
               RETURNS [index: CARDINAL] = CmFile.NextValue;

          MyNextValue: PROCEDURE [
               h: CmFile.Handle,
               table: LONG DESCRIPTOR FOR ARRAY DefinedOption OF LONG STRING]
               RETURNS [index: CMOption] = LOOPHOLE[CheckType];

          cmFile: CmFile.Handle ← CmFile.UserDotCmOpen[
               ! CmFile.Error => IF code = fileNotFound THEN GOTO return];

          IF CmFile.FindSection[cmFile, "System"L] THEN
               DO
                    SELECT
                    (cmIndex ← MyNextValue[
                         h: cmFile, table: DESCRIPTOR[cmOptionTable] !
                         CmFile.TableError => RESUME ]) FROM
                         noMatch => EXIT;

                         User =>
                              BEGIN
                              value: LONG STRING = Token.Item[cmFile];
                              toolData.userName ← String.CopyToNewString[
                                   s: value, z: Heap.systemZone];
			       [] ← Token.FreeTokenString[value];
                              END;

                         Password =>
                              BEGIN
                              value: LONG STRING = Token.Item[cmFile];
                              toolData.userPassword ← String.CopyToNewString[
                                   s: value, z: Heap.systemZone];
                              [] ← Token.FreeTokenString[value];
                              END;

                         Domain =>
                              BEGIN
                              value: LONG STRING = Token.Item[cmFile];
                              toolData.domainName ← String.CopyToNewString[
                                   s: value, z: Heap.systemZone];
                              [] ← Token.FreeTokenString[value];
                              END;
  
                         Org =>
                              BEGIN
                              value: LONG STRING ← Token.Item[cmFile];
                              toolData.organizationName ←
                                   String.CopyToNewString[
                                   s: value, z: Heap.systemZone];
                              [] ← Token.FreeTokenString[value];
                              END;
			      
			 NSFile =>
                              BEGIN
                              value: LONG STRING ← Token.Item[cmFile];
                              String.Copy[
                                   NSFileName, value];
                              [] ← Token.FreeTokenString[value];
                              END;
			      
			 IFSFile =>
                              BEGIN
                              value: LONG STRING ← Token.Item[cmFile];
                              IFSFileName ←
                                   String.CopyToNewString[
                                   s: value, z: Heap.systemZone];
                              [] ← Token.FreeTokenString[value];
                              END;
                       ENDCASE;
                    ENDLOOP;

          [] ← CmFile.Close[cmFile];
          EXITS return => NULL;
          END;  --ProcessUserDotCM



     ServerNotifyProc: FormSW.EnumeratedNotifyProcType =
          BEGIN
          IF debug THEN {
               Put.Line[toolData.fileSW, "ServerNotifyProc...."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };

          DisplayFile[];
          END;  --ServerNotifyProc



     Unload: Exec.ExecProc =
          BEGIN
          IF ILT.windowHandle # NIL THEN Tool.Destroy[ILT.windowHandle];
          ILT.windowHandle ← NIL;
          [] ← Exec.RemoveCommand[h, "LispTool.~"L];
          END;  --Unload



     -- Mainline code

     Init[];

     END...LispToolImpl