-- file DisplayControl.Mesa -- last edited by Sandman, July 1, 1980 10:10 AM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY AltoDisplay USING [DCBchainHead, DCBnil], AltoFileDefs USING [FP], DirectoryDefs USING [EnumerateDirectory], DisplayDefs USING [ BlinkCursor, DeleteDisplayData, DisplayOff, DisplayOn, GetTypeScript, InitDisplay, SetFont, SetTypeScript], FontDefs USING [CreateFont, FontHandle], FrameDefs USING [GlobalFrame, SelfDestruct, UnNew], ImageDefs USING [ AddCleanupProcedure, AddFileRequest, AllReasons, CleanupItem, CleanupProcedure, FileRequest, RemoveCleanupProcedure], ProcessDefs USING [InitializeCondition, MsecToTicks, SetTimeout], SDDefs USING [sAddFileRequest, SD], SegmentDefs USING [ Append, DefaultBase, DefaultPages, DeleteFileSegment, FileHandle, FileSegmentHandle, InsertFile, NewFile, NewFileSegment, Read, ReleaseFile, UnlockFile, Write], StreamDefs USING [ CloseDiskStream, CreateByteStream, GetIndex, OpenDiskStream, SetIndex, StreamError, StreamHandle, StreamIndex, TruncateDiskStream], StringDefs USING [EquivalentString], Storage USING [Node, CopyString, Free, FreeString]; DisplayControl: MONITOR IMPORTS DirectoryDefs, DisplayDefs, FrameDefs, FontDefs, ImageDefs, ProcessDefs, SegmentDefs, StreamDefs, StringDefs, Storage EXPORTS DisplayDefs = BEGIN Data: TYPE = RECORD [ font: FontDefs.FontHandle, fontseg: SegmentDefs.FileSegmentHandle, initialize, useTypescript, imaging, stopCursor: BOOLEAN, cursorWait: CONDITION, cursorProcess: PUBLIC PROCESS, cleanupitem: ImageDefs.CleanupItem, requests: POINTER TO Requests]; Requests: TYPE = RECORD [mesafont, sysfont, typescript: ImageDefs.FileRequest]; data: POINTER TO Data; CreateRequests: PROCEDURE = BEGIN OPEN SegmentDefs, Storage; requests: POINTER TO Requests _ Node[SIZE[Requests]]; requests.mesafont _ [link: NIL, file:, access: Read, name: CopyString["MesaFont.al."L]]; requests.sysfont _ [link: @requests.mesafont, file:, access: Read, name: CopyString["SysFont.al."L]]; requests.typescript _ [link: @requests.sysfont, file:, access: Read + Write + Append, name: CopyString["Mesa.Typescript."L]]; data.requests _ requests; RETURN END; DeleteRequests: PROCEDURE = BEGIN OPEN Storage; FreeString[data.requests.mesafont.name]; FreeString[data.requests.sysfont.name]; FreeString[data.requests.typescript.name]; Free[data.requests]; RETURN END; CreateData: PROCEDURE = BEGIN OPEN ImageDefs, data; data _ Storage.Node[SIZE[Data]]; cleanupitem _ [link:, mask: AllReasons, proc: Cleanup]; initialize _ useTypescript _ stopCursor _ TRUE; ProcessDefs.InitializeCondition[@cursorWait, ProcessDefs.MsecToTicks[450]]; RETURN END; DeleteData: PROCEDURE = BEGIN ImageDefs.RemoveCleanupProcedure[@data.cleanupitem]; Storage.Free[data]; RETURN END; Cleanup: ImageDefs.CleanupProcedure = BEGIN OPEN ImageDefs, data; file: SegmentDefs.FileHandle; i: CARDINAL; si: StreamDefs.StreamIndex; ts: StreamDefs.StreamHandle _ DisplayDefs.GetTypeScript[]; SELECT why FROM Finish, Abort, Save => BEGIN IF why # Save THEN AltoDisplay.DCBchainHead^ _ AltoDisplay.DCBnil; IF ~initialize AND ts # NIL THEN BEGIN StreamDefs.TruncateDiskStream[ts]; DisplayDefs.SetTypeScript[NIL]; END; IF why = Save AND ~initialize THEN BEGIN DisplayDefs.DisplayOff[black]; font.destroy[font]; SegmentDefs.DeleteFileSegment[fontseg]; END; IF why # Save THEN RETURN; CreateRequests[]; imaging _ SDDefs.SD[SDDefs.sAddFileRequest] # 0; requests.mesafont.file _ NIL; IF imaging THEN ImageDefs.AddFileRequest[@requests.mesafont]; requests.sysfont.file _ NIL; IF imaging THEN ImageDefs.AddFileRequest[@requests.sysfont]; requests.typescript.file _ NIL; IF imaging AND useTypescript THEN ImageDefs.AddFileRequest[@requests.typescript]; END; Restore => BEGIN OPEN SegmentDefs; IF (file _ requests.mesafont.file) = NIL THEN file _ requests.sysfont.file ELSE BEGIN f: FileHandle = requests.sysfont.file; UnlockFile[f]; ReleaseFile[f]; END; fontseg _ NewFileSegment[file, DefaultBase, DefaultPages, Read]; font _ FontDefs.CreateFont[fontseg]; IF initialize THEN BEGIN initialize _ FALSE; DisplayDefs.InitDisplay[24, 14, 20, font] END ELSE BEGIN DisplayDefs.SetFont[font]; DisplayDefs.DisplayOn[] END; IF ~useTypescript THEN BEGIN DeleteRequests[]; RETURN END; IF (file _ requests.typescript.file) = NIL THEN file _ NewFile[requests.typescript.name, Read + Write + Append]; DisplayDefs.SetTypeScript[ StreamDefs.CreateByteStream[file, Read + Write + Append]]; DeleteRequests[]; END; Checkpoint => BEGIN IF ts # NIL THEN StreamDefs.CloseDiskStream[ts]; DisplayDefs.DisplayOff[white]; END; Continue => BEGIN DisplayDefs.DisplayOn[]; IF ts # NIL THEN StreamDefs.OpenDiskStream[ts]; END; Restart => BEGIN OPEN StreamDefs; DisplayDefs.DisplayOn[]; IF ts # NIL THEN BEGIN OpenDiskStream[ts ! StreamError => IF error = StreamEnd THEN RESUME ]; ts.reset[ts] END; END; InLd => IF ts # NIL THEN StreamDefs.OpenDiskStream[ts]; OutLd => BEGIN OPEN StreamDefs; IF ts = NIL THEN RETURN; si _ GetIndex[ts]; ts.put[ts, 15C]; FOR i IN [0..9) DO ts.put[ts, '~] ENDLOOP; SetIndex[ts, si]; CloseDiskStream[ts]; END; ENDCASE; RETURN END; Cursor: ENTRY PROCEDURE = BEGIN OPEN data; timer: POINTER TO INTEGER _ LOOPHOLE[430B]; blinktime: INTEGER; ProcessDefs.SetTimeout[@cursorWait, ProcessDefs.MsecToTicks[450]]; DO -- forever IF blinktime - timer^ ~IN [0..13] THEN BEGIN [] _ DisplayDefs.BlinkCursor[]; blinktime _ timer^ + 13 END; IF stopCursor THEN EXIT; WAIT cursorWait; ENDLOOP; RETURN END; StartCursor: PUBLIC ENTRY PROCEDURE = BEGIN OPEN data; IF ~stopCursor THEN RETURN; stopCursor _ FALSE; cursorProcess _ FORK Cursor[]; RETURN END; PokeCursorProcess: PUBLIC ENTRY PROCEDURE RETURNS [BOOLEAN] = BEGIN OPEN data; IF stopCursor THEN RETURN[FALSE]; NOTIFY cursorWait; stopCursor _ TRUE; RETURN[TRUE] END; StopCursor: PUBLIC PROCEDURE = BEGIN OPEN data; IF PokeCursorProcess[] THEN JOIN cursorProcess; RETURN END; DestroyDisplay: PUBLIC PROCEDURE = BEGIN OPEN FrameDefs; StopCursor[]; DisplayDefs.DisplayOff[white]; Cleanup[Finish]; data.font.destroy[data.font]; DisplayDefs.DeleteDisplayData[]; UnNew[GlobalFrame[FontDefs.CreateFont]]; UnNew[GlobalFrame[DisplayDefs.SetTypeScript]]; DeleteData[]; SelfDestruct[]; RETURN END; -- file requests ProcessFileRequests: PROCEDURE [rHead: POINTER TO ImageDefs.FileRequest] = BEGIN OPEN AltoFileDefs; checkone: PROCEDURE [fp: POINTER TO FP, dname: STRING] RETURNS [BOOLEAN] = BEGIN r: POINTER TO ImageDefs.FileRequest; prev: POINTER TO ImageDefs.FileRequest _ NIL; FOR r _ rHead, r.link UNTIL r = NIL DO IF StringDefs.EquivalentString[dname, r.name] THEN BEGIN IF r.file = NIL THEN r.file _ SegmentDefs.InsertFile[fp, r.access] ELSE r.file.fp _ fp^; IF prev = NIL THEN rHead _ r.link ELSE prev.link _ r.link; END ELSE prev _ r; ENDLOOP; RETURN[rHead = NIL] END; DirectoryDefs.EnumerateDirectory[checkone]; END; CreateData[]; ImageDefs.AddCleanupProcedure[@data.cleanupitem]; Cleanup[Save]; IF data.imaging THEN STOP ELSE ProcessFileRequests[@data.requests.typescript]; Cleanup[Restore]; StartCursor[]; END...