-- file: IntPress.Mesa -- edited by Brotz, January 28, 1981 5:40 PM -- edited by Schroeder, 28-Oct-80 11:17:06 DIRECTORY Ascii, csD: FROM "CoreStreamDefs", DMSTimeDefs, EFTPDefs, exD: FROM "ExceptionDefs", Inline, intCommon: FROM "IntCommon", LaurelHardcopyDefs, lsD: FROM "LaurelStateDefs", ovD: FROM "OverviewDefs", PupDefs, PupTypes, Stream, StringDefs, TimeDefs; IntPress: PROGRAM IMPORTS csD, DMSTimeDefs, EFTPDefs, exD, Inline, intC: intCommon, LaurelHardcopyDefs, lsD, PupDefs, StringDefs, TimeDefs EXPORTS LaurelHardcopyDefs = PUBLIC BEGIN OPEN LaurelHardcopyDefs; nPressFilePages: CARDINAL = 240; pressStream: csD.StreamHandle; nPressBufferPages: CARDINAL = 2; partDirectoryStream: csD.StreamHandle; nPartDirectoryBufferPages: CARDINAL = 2; entityListStream: csD.StreamHandle; nEntityListBufferPages: CARDINAL = 1; dlStartPosition: csD.Position; who: PupDefs.PupAddress; WriteCommandAndMica: PROCEDURE [com: Byte, val: Mica] = BEGIN q, r: CARDINAL; [q, r] _ Inline.DIVMOD[val, 400B]; WriteEntityByte[com]; WriteEntityByte[q]; WriteEntityByte[r]; END; -- of WriteCommandAndMica -- WriteEntityByte: PROCEDURE [val: Byte] = INLINE {csD.Write[entityListStream, val]}; WritePressByte: PROCEDURE [val: Byte] = INLINE {csD.Write[pressStream, val]}; WritePressString: PROCEDURE [string: STRING, nChars: CARDINAL] = BEGIN length: CARDINAL = MIN[string.length, nChars]; i: CARDINAL; WritePressByte[length]; FOR i IN [0 .. length) DO WritePressByte[LOOPHOLE[string[i]]]; ENDLOOP; THROUGH [length .. nChars) DO WritePressByte[0]; ENDLOOP; END; -- of WritePressString -- AdvancePressStreamToNextPage: PROCEDURE RETURNS[incr:CARDINAL] = BEGIN p: csD.Position = csD.GetPosition[pressStream]; incr _ ((512 - Inline.LowHalf[p MOD 512]) MOD 512); csD.SetPosition[pressStream, p+incr]; END; --of AdvancPressStreamToNextPage-- InitPressPage: PROCEDURE = -- Initializes state variables. BEGIN dlStartPosition _ csD.GetPosition[pressStream]; END; -- of InitPressPage -- FinishPressPage: PROCEDURE = -- Completes the current page part by pushing out the entity list onto the pressStream and -- by adding a new entry to the part directory. BEGIN partDirectoryEntry: PartDirectoryEntry; entityTrailer: EntityTrailer _ EntityTrailer [entityType: 0, fontSet: 0, beginByteHigh: 0, beginByteLow: 0, byteLengthHigh: 0, byteLengthLow: Inline.LowHalf[csD.GetPosition[pressStream] - dlStartPosition], ye: 0, xe: 0, left: 0, bottom: 0, width: 8 * inch + inch/2, height: 11 * inch, entityLength: Inline.LowHalf[(csD.GetPosition[entityListStream] + 1) / 2 + SIZE[EntityTrailer]]]; IF csD.GetPosition[pressStream] MOD 2 = 1 THEN WritePressByte[377B]; WritePressByte[0]; WritePressByte[0]; IF csD.GetPosition[entityListStream] MOD 2 = 1 THEN WriteEntityByte[377B]; csD.SetPosition[entityListStream,0]; csD.StreamCopy[entityListStream, pressStream, csD.GetLength[entityListStream]]; csD.WriteBlock[pressStream, LOOPHOLE[@entityTrailer], 0, 2*SIZE[EntityTrailer]]; csD.Reset[entityListStream]; partDirectoryEntry _ PartDirectoryEntry [partType: 0, recordStart: Inline.LowHalf[dlStartPosition/512], nRecords: 0, -- fill in later -- entityListPadding: AdvancePressStreamToNextPage[]/2]; partDirectoryEntry.nRecords _ Inline.LowHalf[(csD.GetPosition[pressStream] - dlStartPosition)/512]; csD.WriteBlock[partDirectoryStream, LOOPHOLE[@partDirectoryEntry], 0, SIZE[PartDirectoryEntry]]; END; -- of FinishPressPage -- FinishPressFile: PROCEDURE [chunk: CARDINAL] = -- Completes the press file by pushing out the font directory, the part directory, and the -- document directory. BEGIN partDirStartPosition: csD.Position; pressFileName: STRING _ "Mail, part x"L; userNameString: STRING _ [31]; timeString: STRING _ [39]; -- don't change this limit! i: CARDINAL; pt: DMSTimeDefs.PackedTime; fontDirectory: FontDirectory; documentDirectoryHeader: DocumentDirectoryHeader; partDirectoryEntry: PartDirectoryEntry _ PartDirectoryEntry [partType: 1, recordStart: Inline.LowHalf[csD.GetPosition[pressStream]/512], nRecords: intC.fontDirectorySegment.pages, entityListPadding: 177777B]; fontDirectory _ lsD.SwapInStateSegment[intC.fontDirectorySegment]; csD.WriteBlock[pressStream, LOOPHOLE[fontDirectory], 0, SIZE[FontDirectoryRec] * 2]; lsD.ReleaseStateSegment[intC.fontDirectorySegment]; [] _ AdvancePressStreamToNextPage[]; partDirStartPosition _ csD.GetPosition[pressStream]; csD.WriteBlock[partDirectoryStream, LOOPHOLE[@partDirectoryEntry], 0, SIZE[PartDirectoryEntry]]; csD.SetPosition[partDirectoryStream, 0]; csD.StreamCopy[partDirectoryStream, pressStream, csD.GetLength[partDirectoryStream]]; [] _ AdvancePressStreamToNextPage[]; documentDirectoryHeader _ DocumentDirectoryHeader[ generalPassword: 27183, nRecordsInFile: Inline.LowHalf[csD.GetPosition[pressStream]/512] + 1, nParts: Inline.LowHalf[csD.GetLength[partDirectoryStream] / SIZE[PartDirectoryEntry]], partDirectoryStartRecord: Inline.LowHalf[partDirStartPosition/512], nRecordsInPartDirectory: Inline.LowHalf[(csD.GetPosition[pressStream] - partDirStartPosition)/512], obsoleteBackPointer: 0, unused1: DMSTimeDefs.currentTime.highbits, unused2: DMSTimeDefs.currentTime.lowbits, firstCopy: 1, lastCopy: intC.hardCopies]; csD.Reset[partDirectoryStream]; csD.WriteBlock[pressStream, LOOPHOLE[@documentDirectoryHeader], 0, SIZE[DocumentDirectoryHeader] * 2]; THROUGH [20 .. 256) DO WritePressByte[377B]; ENDLOOP; IF chunk = 1 THEN pressFileName.length _ 4 ELSE {pressFileName.length _ 12; pressFileName[11] _ '0 + chunk MOD 10}; WritePressString[pressFileName, 51]; userNameString.length _ 0; FOR i IN [0 .. intC.hardcopyUserName.length) DO IF intC.hardcopyUserName[i] = '$ THEN StringDefs.AppendString[userNameString, intC.user.name ! StringDefs.StringBoundsFault => EXIT] ELSE StringDefs.AppendChar[userNameString, intC.hardcopyUserName[i] ! StringDefs.StringBoundsFault => EXIT]; ENDLOOP; WritePressString[userNameString, 31]; pt.lc _ TimeDefs.CurrentDayTime[]; DMSTimeDefs.MapPackedTimeToTimeZoneString[pt, timeString]; WritePressString[timeString, 39]; THROUGH [380 .. 512) DO WritePressByte[0]; ENDLOOP; END; -- of FinishPressFile -- PrintPressString: PROCEDURE [string: STRING, fontNumber: CARDINAL, x, y: Mica, segTable: POINTER TO LineSegmentTable] = -- Puts string into the press file entity list and data list. BEGIN start, end: CARDINAL _ 0; PrintSubString: PROCEDURE [x, y: Mica, start, length: CARDINAL] = BEGIN IF length = 0 THEN RETURN; WriteCommandAndMica[setXCom, x]; WriteCommandAndMica[setYCom, y]; -- output string data csD.WriteBlock[pressStream, LOOPHOLE[@string.text], start, length]; -- output string description IF length <= 32 THEN WriteEntityByte[showCharactersShortCom + length - 1] ELSE {WriteEntityByte[showCharactersCom]; WriteEntityByte[length]}; END; -- of PrintSubString -- IF segTable = NIL THEN PrintSubString[x, y, 0, string.length] ELSE FOR i: CARDINAL IN [0 .. 12) UNTIL end = string.length DO start _ end; end _ segTable[i + 1].index; PrintSubString[segTable[i].x, y, start, end - start]; ENDLOOP; END; -- of PrintPressString -- SetCurrentPressFont: PROCEDURE [font: FontNumber] = -- Sets font in the press file entity list. BEGIN WriteEntityByte[fontCom + font]; WriteEntityByte[setSpaceXCom]; WriteEntityByte[0]; WriteEntityByte[widthTable[font][Ascii.SP]]; END; -- of SetCurrentPressFont -- -- ************************ -- Press File Transmission -- ************************ FindPrinter: PROCEDURE RETURNS [error: ovD.ErrorCode] = -- Locates printer to which press file will be sent. Returns ok if found, cantConnect if not. BEGIN error _ ovD.ok; who _ [ , , PupTypes.eftpReceiveSoc]; PupDefs.GetPupAddress[@who, intC.hardcopyHost ! PupDefs.PupNameTrouble => BEGIN exD.DisplayBothExceptionLines[NIL, exD.cantFindPrinter, e, exD.nil]; error _ ovD.cantConnect; CONTINUE END]; END; -- of FindPrinter -- TimeToSend: PROCEDURE RETURNS [BOOLEAN] = -- Returns TRUE iff press file exceeds maximum length. BEGIN RETURN[csD.GetPosition[pressStream]/512 > nPressFilePages]; END; -- of TimeToSend -- SendPressFile: PROCEDURE = -- Uses EFTP to send the current press file to the current hardcopy host. BEGIN OPEN EFTPDefs, StringDefs; bytesInPressStream: csD.Position = csD.GetPosition[pressStream]; utilityString: STRING _ [80]; BEGIN -- block for error exits EFTPOpenForSending[who ! EFTPTimeOut => BEGIN exD.DisplayBothExceptionLines[NIL, exD.printerNotRespond, NIL, exD.cancelHardcopy, FALSE]; CheckForAbort[ ! AbortHardcopy => GO TO AbortSend]; -- sees DEL (or CANCEL) on second timeout RESUME END; EFTPTroubleSending => IF e = eftpReceiverBusyAbort THEN BEGIN exD.DisplayBothExceptionLines[s, exD.printerBusy, NIL, exD.cancelHardcopy, FALSE]; CheckForAbort[ ! AbortHardcopy => GO TO AbortSend]; -- sees DEL (or CANCEL) on second signal RETRY END ELSE BEGIN exD.GetExceptionString[exD.cannotConnectToPrinter, utilityString]; AppendString[utilityString, intC.hardcopyHost]; IF s ~= NIL AND s.length > 0 THEN BEGIN AppendString[utilityString, ": "L]; AppendString[utilityString, s]; END; exD.DisplayBothExceptionLines[utilityString, exD.nil, NIL, exD.hardcopyCanceled]; GO TO KillSend END ]; exD.GetExceptionString[exD.transmissionTo, utilityString]; AppendString[utilityString, intC.hardcopyHost]; exD.AppendExceptionString[exD.proceeding, utilityString]; exD.DisplayExceptionStringOnLine[utilityString, 1]; BEGIN ENABLE BEGIN EFTPTimeOut => BEGIN exD.DisplayBothExceptionLines[NIL, exD.printerTimeout, NIL, exD.hardcopyCanceled]; GO TO KillSend END; EFTPTroubleSending => BEGIN exD.GetExceptionString[exD.printerTrouble, utilityString]; IF s # NIL THEN AppendString[utilityString, s ! StringBoundsFault => CONTINUE]; exD.DisplayBothExceptionLines[utilityString, exD.nil, NIL, exD.hardcopyCanceled]; GO TO KillSend END END; IF intC.twoSidedPrinting THEN SendSpruceString["((DUPLEX TRUE))"L]; IF intC.passwordPrinting THEN BEGIN string: STRING _ [60]; StringDefs.AppendString[string, "((HOLD "L]; StringDefs.AppendString[string, intC.user.password]; StringDefs.AppendString[string, "))"L]; SendSpruceString[string]; END; csD.SetPosition[pressStream, 0]; csD.ReadStream[pressStream, bytesInPressStream, SendPressStreamBlock]; csD.SetPosition[pressStream, 0]; CheckForAbort[ ! AbortHardcopy => GO TO AbortSend]; EFTPFinishSending[]; END; RETURN; EXITS KillSend => aborted _ laurel; AbortSend => NULL; END; EFTPAbortSending[""L]; ERROR AbortHardcopy END; -- of SendPressFile -- SendPressStreamBlock: PROCEDURE[s: Stream.Block] = {EFTPDefs.EFTPSendBlock[Inline.LowHalf[s.blockPointer+s.startIndex/2], s.stopIndexPlusOne-s.startIndex]}; SendSpruceString: PROCEDURE [s: STRING] = BEGIN hackArray: POINTER TO ARRAY [0 .. 1] OF CARDINAL _ LOOPHOLE[s]; length, maxLength: CARDINAL; length _ hackArray[0]; maxLength _ hackArray[1]; hackArray[0] _ 125314B; hackArray[1] _ 170377B; EFTPDefs.EFTPSendBlock[hackArray, 2 * StringDefs.WordsForString[length]]; hackArray[0] _ length; hackArray[1] _ maxLength; END; -- of SendSpruceString -- OpenPressStreams: PROCEDURE = -- Opens streams used during press file construction. BEGIN pressStream _ csD.OpenFromName["Swatee"L,intC.user, byte, write, nPressBufferPages]; partDirectoryStream _ csD.Open[NIL, word, write, nPartDirectoryBufferPages]; entityListStream _ csD.Open[NIL, byte, write, nEntityListBufferPages]; END; -- of OpenPressStreams -- ClosePressStreams: PROCEDURE = -- Closes streams used during press file construction. BEGIN csD.Destroy[entityListStream]; csD.Destroy[partDirectoryStream]; csD.Destroy[pressStream]; END; -- of ClosePressStreams -- END. -- of IntPress -- z19932(635)\f1