-- Straw0.mesa -- Written by Joe Maleson -- Last changed by Doug Wyatt, April 8, 1981 5:52 PM DIRECTORY AltoFileDefs, DiscoDefs USING [Lookup, LookupList, TransferBytes], DisplayListDefs, GraphicsDefs, ImageDefs, InlineDefs USING [COPY], IODefs USING [WriteLine, WriteString, ReadID, Rubout], MagicDefs, MiscDefs, Mopcodes, PressDefs USING [PressPage, ReleasePressPage, PressFileDescriptor, InitPressFileDescriptor, PutPressPage, ClosePressFile, PressObject, PressFilePointers, PressFont, ELShowDots, ELShowDotsOpaque, OpenPressFileFromFP, ReadPressPage, ReleasePressFilePointers], Real USING [InitReals], SegmentDefs, StrawDefs, StreamDefs, StringDefs, SystemDefs, XMAllocDefs; (635)\f1 119f0 2f1 24f0 2f1 10f0 2f1 14f0 2f1 16f0 2f1 13f0 2f1 10f0 2f1 24f0 2f1 24f0 2f1 11f0 2f1 6f0 2f1 7f0 2f1 10f0 2f1 11f0 2f1 9f0 2f1 27f0 2f1 16f0 2f1 19f0 2f1 25f0 2f1 12f0 2f1 14f0 2f1 11f0 2f1 19f0 2f1 9f0 2f1 10f0 2f1 16f0 2f1 21f0 2f1 13f0 2f1 25f0 2f1 23f0 2f1 12f0 2f1 10f0 2f1 11f0 2f1 11f0 2f1 11f0 2f1 Straw0: PROGRAM IMPORTS DiscoDefs,DisplayListDefs,GraphicsDefs,MagicDefs,PressDefs,Real, StrawDefs,XMAllocDefs,ImageDefs,InlineDefs,IODefs,MiscDefs, StringDefs,SegmentDefs,SystemDefs EXPORTS StrawDefs = BEGIN OPEN DiscoDefs,InlineDefs, IODefs, StrawDefs; \f1b6B27f0 1f1 15f0 1f1 12f0 1f1 9f0 1f1 9f0 1f1 38f0 1f1 10f0 1f1 6f0 1f1 8f0 1f1 12f0 1f1 Buttons: TYPE = MACHINE DEPENDENT RECORD [ KeyPadAndGarbage: [0..10000B), Red: [0..1], Blue: [0..1], Yellow: [0..1] ]; triState: TYPE = {empty,singleFile,multiFile}; MouseButtons: POINTER TO Buttons = LOOPHOLE[177030B]; CursorX: POINTER TO CARDINAL = LOOPHOLE[426B]; CursorY: POINTER TO CARDINAL = LOOPHOLE[427B]; CursorBits: POINTER TO ARRAY [0..15] OF CARDINAL = LOOPHOLE[431B]; Cursor: GraphicsDefs.Bitmap _ [bank: 0,nWords: 1,nBits:16,nLines:16, bits:LOOPHOLE[CursorBits],nBitsPerPixel:1,portraitMode:TRUE,scaleFactor:10]; ArrowCursor: GraphicsDefs.Bitmap _ [bank: 0,nWords: 1,nBits: 16,nLines: 16, bits:,nBitsPerPixel:1,portraitMode:TRUE,scaleFactor:10]; HourGlassCursor: GraphicsDefs.Bitmap _ [bank: 0,nWords: 1,nBits: 16,nLines: 16,bits:,nBitsPerPixel:1,portraitMode:TRUE,scaleFactor:10]; Screen: POINTER TO GraphicsDefs.Bitmap; \f1 177b12B42b7B40b7B40b10B57b6B410b6B bitsPerInch: CARDINAL _ 72; micasPerInch: CARDINAL = 2540; dispXOff: CARDINAL _ 0; dispYOff: CARDINAL _ 0; GridSize: CARDINAL _ 0; DCBHead: POINTER TO CARDINAL = LOOPHOLE[420B]; nextDCB: POINTER TO ARRAY[0..3] OF UNSPECIFIED _ LOOPHOLE[DCBHead^]; nScanLines: CARDINAL _ 808; DCBtop: POINTER TO ARRAY[0..3] OF CARDINAL _ nextDCB; pfp: PressDefs.PressFilePointers; needRelease: BOOLEAN _ FALSE; pressNames: POINTER TO ARRAY [0..0) OF STRING; nFiles: CARDINAL _ 0; pressFiles: POINTER TO DiscoDefs.LookupList _ DiscoDefs.Lookup["*.press"]; font: POINTER TO GraphicsDefs.StrikeFont _ GraphicsDefs.GetStrikeHandle["SysFont"]; nPages: CARDINAL; displayPage: CARDINAL; pressPage: PressDefs.PressPage; ScreenState: triState _ empty; Main: PROCEDURE = BEGIN p: POINTER TO LookupList; --mem defs TotalPagesForXMem: CARDINAL = 400; nXMemBlocks: CARDINAL = 4; PagesPerXMemBlock: CARDINAL = TotalPagesForXMem/nXMemBlocks; ArrowBits: ARRAY [0..15] OF CARDINAL; HourGlassBits: ARRAY [0..15] OF CARDINAL _ [ 177777B, 100001B, 040002B, 034034B, 017170B, 007660B, 003740B, 001700B, 001100B, 002440B, 004220B, 010610B, 021704B, 047762B, 177777B, 177777B ]; IF pressFiles=NIL THEN RETURN; -- DKW COPY[from: Cursor.bits,nwords: 16,to: @ArrowBits]; ArrowCursor.bits _ LOOPHOLE[@ArrowBits]; HourGlassCursor.bits _ LOOPHOLE[@HourGlassBits]; UNTIL nextDCB[0] = 0 DO nScanLines _ nScanLines - nextDCB[3]*2; nextDCB _ LOOPHOLE[nextDCB[0]]; ENDLOOP; nScanLines _ nScanLines - nextDCB[3]*2; pressPage.leftX _ pressPage.bottomY _ 77777B; pressPage.rightX _ pressPage.topY _ 0; pressPage.ObjectList _ NIL; pressPage.FontDir _ ALL[NIL]; p_pressFiles; UNTIL p = NIL DO nFiles _ nFiles + 1;p _ p.link;ENDLOOP; pressNames _ SystemDefs.AllocateHeapNode[nFiles]; p_pressFiles;nFiles _ 0; UNTIL p = NIL DO pressNames[nFiles] _ p.name; nFiles _ nFiles + 1; p _ p.link; ENDLOOP; --now, initialize mem --LongDefs.InitMachineType[]; //needed for Alto compatible XMAlloc stuff --AltoMicrocodeDefs.LoadRam[]; //ditto THROUGH [1..nXMemBlocks] DO OPEN SegmentDefs; ENABLE InsufficientVM => EXIT; XMAllocDefs.AddToXMZone[LongDataSegmentAddress[NewDataSegment[ DefaultXMBase,PagesPerXMemBlock]],PagesPerXMemBlock*256]; ENDLOOP; GraphicsDefs.SetXMAlloc[XMAllocDefs.Allocate,XMAllocDefs.Free]; Screen _ GraphicsDefs.TurnOnGraphics[]; nextDCB _ LOOPHOLE[DCBHead^]; SelectFile[]; AddFile[]; --menu-less edit IODefs.WriteLine["Straw of October 20, 1980"]; StrawDefs.EditDisplayList[]; ImageDefs.StopMesa[]; DO --edit loop BEGIN commandIndex: CARDINAL; newFile: CARDINAL = 0; addFile: CARDINAL = newFile+1; writeFile: CARDINAL = addFile+1; edit: CARDINAL = writeFile+1; quit: CARDINAL = edit+1; nextPage: CARDINAL = quit+1; commandNames: ARRAY [0..nextPage] OF STRING _ ["New File","Add File","Write File","Edit","Quit","Next Page"]; nCommands: CARDINAL _ nextPage; IF (nPages > displayPage) AND (ScreenState = singleFile) THEN nCommands _ nCommands+1; DO --get user command commandIndex _ MagicDefs.Menu[nCommands,LOOPHOLE[@commandNames],font]; IF commandIndex IN [0..nCommands) THEN EXIT; ENDLOOP; SELECT commandIndex FROM newFile,nextPage => BEGIN NewPage[]; IF commandIndex = newFile THEN BEGIN Refresh[]; SelectFile[]; END ELSE displayPage _ displayPage+1; AddFile[]; END; addFile => BEGIN SelectFile[]; AddFile[]; END; edit => StrawDefs.EditDisplayList[]; writeFile => WriteFile[]; quit => ImageDefs.StopMesa[]; ENDCASE; END; ENDLOOP; --edit loop END; SelectFile: PUBLIC PROCEDURE = BEGIN pressIndex: CARDINAL _ 177777B; p: POINTER TO LookupList; IF needRelease THEN BEGIN PressDefs.ReleasePressFilePointers[@pfp]; END; needRelease _ TRUE; DO pressIndex _ MagicDefs.Menu[nFiles,LOOPHOLE[pressNames],font]; IF pressIndex IN [0..nFiles) THEN EXIT; ENDLOOP; WaitCursor[]; p _ pressFiles; THROUGH [1..pressIndex] DO p _ p.link;ENDLOOP; nPages _ PressDefs.OpenPressFileFromFP[@p.fp,@pfp]; NormalCursor[]; --get page number from user, and display it IF nPages > 99 THEN MiscDefs.CallDebugger["too many pages"]; IF nPages = 1 THEN displayPage _ 1 ELSE BEGIN i: CARDINAL; numbers: ARRAY [0..100) OF STRING; FOR i IN [0..nPages) DO numbers[i] _ SystemDefs.AllocateHeapString[2]; StringDefs.AppendDecimal[numbers[i],i+1]; ENDLOOP; DO displayPage_MagicDefs.Menu[nPages,LOOPHOLE[@numbers],font]+1; IF displayPage IN [1..nPages] THEN EXIT; ENDLOOP; FOR i IN [0..nPages) DO SystemDefs.FreeHeapString[numbers[i]]; ENDLOOP; END; --select displayPage END; AddFile: PUBLIC PROCEDURE = BEGIN obj,savedObj: POINTER TO PressDefs.PressObject; WaitCursor[]; --add new page to pressPage savedObj _ pressPage.ObjectList; pressPage.ObjectList _ NIL; PressDefs.ReadPressPage[@pfp,displayPage,@pressPage]; DisplayPressPage[@pressPage]; obj _ pressPage.ObjectList; UNTIL obj.link = NIL DO obj _ obj.link; ENDLOOP; obj.link _ savedObj; IF ScreenState = empty THEN ScreenState _ singleFile ELSE ScreenState _ multiFile; NormalCursor[]; END; NewPage: PUBLIC PROCEDURE = BEGIN i: CARDINAL; displayList: POINTER TO ARRAY [0..0) OF POINTER TO StrawDefs.EntityBox _ LOOPHOLE[DisplayListDefs.GetDisplayListHandle[]]; ReLinkPressPage[@pressPage]; --free storage allocated by ReadDirs FOR i DECREASING IN [0..DisplayListDefs.GetDisplayCount[]) DO ReleaseEntityBox[displayList[i],FALSE]; ENDLOOP; DisplayListDefs.ResetDisplayCount[]; PressDefs.ReleasePressPage[@pressPage]; pressPage.leftX _ pressPage.bottomY _ 77777B; pressPage.rightX _ pressPage.topY _ 0; pressPage.ObjectList _ NIL; pressPage.FontDir _ ALL[NIL]; --and grab them heap pages WHILE SystemDefs.PruneHeap[] DO ENDLOOP; ScreenState _ empty; END; WriteFile: PUBLIC PROCEDURE = BEGIN pfp: PressDefs.PressFileDescriptor; pressStr: STRING _ [40]; GetString[pressStr,"Press file name: "]; IF pressStr.length # 0 THEN BEGIN WaitCursor[]; ReLinkPressPage[@pressPage]; PressDefs.InitPressFileDescriptor[@pfp,pressStr]; PressDefs.PutPressPage[@pfp,@pressPage]; PressDefs.ClosePressFile[@pfp]; DiscoDefs.TransferBytes[dp:NIL,nBytes:0,data:NIL,free:TRUE]; --invalidate cache NormalCursor[]; END; END; WaitCursor: PUBLIC PROCEDURE = BEGIN GraphicsDefs.ReplaceBitmap[@HourGlassCursor,0,0,@Cursor]; END; NormalCursor: PUBLIC PROCEDURE = BEGIN GraphicsDefs.ReplaceBitmap[@ArrowCursor,0,0,@Cursor]; END; Refresh: PUBLIC PROCEDURE = BEGIN i,x,y: CARDINAL; b: POINTER TO GraphicsDefs.Box; displayList: POINTER TO ARRAY [0..0) OF POINTER TO GraphicsDefs.Box _ DisplayListDefs.GetDisplayListHandle[]; GraphicsDefs.EraseArea[0,0,608,808]; IF GridSize # 0 THEN BEGIN dotLine: GraphicsDefs.Bitmap _ Screen^; dotLine.nLines _ 1; FOR x _ 0,x+GridSize UNTIL x > dotLine.nBits DO GraphicsDefs.PutPoint[x,0];ENDLOOP; FOR y _ GridSize,y+GridSize UNTIL y > Screen.nLines DO GraphicsDefs.PutBitmap[@dotLine,0,y,Screen]; ENDLOOP; END; FOR i IN [0..DisplayListDefs.GetDisplayCount[]) DO b _ displayList[i]; GraphicsDefs.DisplayBox[b,b.displayX,b.displayY]; GraphicsDefs.ReleaseBox[b]; ENDLOOP; END; GetFont: PUBLIC PROCEDURE [n: CARDINAL] RETURNS [strike: POINTER TO GraphicsDefs.StrikeFont,mode: GraphicsDefs.textMode,width: POINTER TO ARRAY CHARACTER [0C..377C] OF INTEGER,index: CARDINAL] = BEGIN font: POINTER TO PressDefs.PressFont _ pressPage.FontDir[n]; fontName: STRING _ [40]; StringDefs.AppendString[fontName,font.Family]; StringDefs.AppendDecimal[fontName,font.PointSize]; strike _ GraphicsDefs.GetStrikeHandle[fontName]; IF strike = NIL THEN strike _ GraphicsDefs.GetStrikeHandle["SysFont"]; RETURN[strike,font.Face,font.Widths,n]; END; GetNum: PUBLIC PROCEDURE [prompt: STRING] RETURNS [CARDINAL] = BEGIN ENABLE StringDefs.InvalidNumber => RETRY; s: STRING _ [40]; GetString[s,prompt]; IF s.length = 0 THEN RETURN[0]; RETURN[StringDefs.StringToDecimal[s]]; END; GetNumWithDefault: PUBLIC PROCEDURE [prompt: STRING,default: CARDINAL] RETURNS [CARDINAL]= BEGIN ENABLE StringDefs.InvalidNumber => RETRY; s: STRING _ [40]; defaultString: STRING _ [8]; StringDefs.AppendDecimal[defaultString,default]; GetStringWithDefault[s,prompt,defaultString]; RETURN[StringDefs.StringToDecimal[s]]; END; GetStringWithDefault: PUBLIC PROCEDURE [s,prompt,default: STRING] = BEGIN OPEN StringDefs; newPrompt: STRING _ [80]; AppendString[to: newPrompt,from: prompt]; AppendString[to: newPrompt,from: "["]; AppendString[to: newPrompt,from: default]; AppendString[to: newPrompt,from: "]"]; GetString[s,newPrompt]; IF s.length = 0 THEN AppendString[to: s,from: default]; END; GetString: PUBLIC PROCEDURE [s,prompt: STRING] = BEGIN heightDCB: TYPE = RECORD [ longBit: BOOLEAN, height: [0..100000B) ]; h: POINTER TO heightDCB _ @nextDCB[3]; normalLen: heightDCB _ nextDCB[3]; IF nextDCB # NIL THEN BEGIN h.height _ MIN[h.height,nScanLines/2]; nextDCB[0] _ DCBtop; END; BEGIN ENABLE Rubout => RETRY; WriteLine[""]; WriteString[prompt]; ReadID[s]; END; --of ENABLE IF nextDCB # NIL THEN BEGIN h^ _ normalLen; nextDCB[0] _ 0; END; END; ReLinkPressPage: PROCEDURE[pressPage: POINTER TO PressDefs.PressPage] = BEGIN displayList: POINTER TO ARRAY [0..0) OF POINTER TO StrawDefs.EntityBox _ LOOPHOLE[DisplayListDefs.GetDisplayListHandle[]]; nItems: CARDINAL _ DisplayListDefs.GetDisplayCount[]; d: POINTER TO StrawDefs.EntityBox; i: CARDINAL; --first, discard invisible items FOR i DECREASING IN [0..nItems) DO d _ displayList[i]; IF (INTEGER[d.Box.displayX] < 0) OR (INTEGER[d.Box.displayY] < 0) OR (d.Box.displayX > Screen.nBits) OR (d.Box.displayY > Screen.nLines) THEN ReleaseEntityBox[d,TRUE]; ENDLOOP; nItems _ DisplayListDefs.GetDisplayCount[]; IF nItems = 0 THEN pressPage.ObjectList _ NIL ELSE BEGIN pressPage.ObjectList _ displayList[0].Object; FOR i IN [0..nItems-1) DO displayList[i].Object.link _ displayList[i+1].Object; ENDLOOP; displayList[nItems-1].Object.link _ NIL; END; END; ReleaseEntityBox: PUBLIC PROCEDURE [eBox: POINTER TO StrawDefs.EntityBox,erase: BOOLEAN] = BEGIN currentBox: POINTER TO GraphicsDefs.Box _ LOOPHOLE[eBox]; do: POINTER TO StrawDefs.DotObject _ LOOPHOLE[eBox]; GraphicsDefs.DestroyBox[currentBox,FALSE]; IF eBox.Object.command IN [PressDefs.ELShowDots..PressDefs.ELShowDotsOpaque] THEN BEGIN IF do.DotsData.fileName # NIL THEN SystemDefs.FreeHeapString[do.DotsData.fileName]; END; --erase=FALSE implies that Object will be released by ReleasePressPage IF erase THEN BEGIN SystemDefs.FreeHeapNode[eBox.Object]; DisplayListDefs.DeleteDisplayItem[currentBox]; RestoreGrid[currentBox]; END ELSE GraphicsDefs.ReleaseBox[currentBox]; SystemDefs.FreeHeapNode[currentBox]; END; SetGrid: PUBLIC PROCEDURE = BEGIN GridSize _ GetNum["Dot spacing (72 = 1 inch): "]; Refresh[]; END; RestoreGrid: PUBLIC PROCEDURE [currentBox: POINTER TO GraphicsDefs.Box] = BEGIN IF GridSize = 0 THEN RETURN; BEGIN x1: CARDINAL _ currentBox.displayX - (currentBox.displayX MOD GridSize); x2: CARDINAL _ currentBox.displayX + currentBox.boxBitmap.nBits; y1: CARDINAL _ currentBox.displayY; y2: CARDINAL _ y1 + currentBox.boxBitmap.nLines; x,y: CARDINAL; IF INTEGER[x2] < 0 OR INTEGER[y2] < 0 THEN RETURN; IF INTEGER[x1] < 0 THEN x1 _ 0; IF INTEGER[y1] < 0 THEN y1 _ 0; FOR y _ (y1-(y1 MOD GridSize)),y+GridSize UNTIL y > y2 DO FOR x _ x1,x+GridSize UNTIL x > x2 DO GraphicsDefs.PutPoint[x,y];ENDLOOP; ENDLOOP; END; END; MakeLongPointer: PROCEDURE [ptr: POINTER,bank: UNSPECIFIED] RETURNS [LONG POINTER] = MACHINE CODE BEGIN END; Real.InitReals[]; Main[]; END. \f1b11B18b12B20b8B16b8B636b4B46b135B1000f0 2f1 40f0 3f1 29f0 2f1 5f0 1f1 27f0 52f1 123f0 1f1 9f0 1f1 63f0 2f1 97b64B5b47B1000b10B1012b7B471b7B662b9B447b10B92b12B88b7B692b7B546b6B222b17B309b20B346b9B463b15B869b16B721b7B93b12B626b15B