<> <> <> DIRECTORY Atom USING [GetPName], BasicTime, Booting USING [switches], FS USING [Delete, Error, StreamOpen], Imager, ImagerFont, ImagerSample USING [Clear, RasterSampleMap], Interpress USING [DoPage, LogProc, Open, Master], IO, IPMaster USING [Error], PrintingP4V3, Process USING [Priority, SetPriority, GetPriority, priorityBackground], RavenDriver USING [ContextFromSampleMap, GetPrinterSampleMap, PrintFromSampleMap, PrintingError, RavenRegistration, RegisterStatusProc, SetRegistration, StatusProc, StatusType, WakeUp], Rope USING [Concat, ROPE], RuntimeError USING [UNCAUGHT], SystemVersion USING [release, bootFileDate], ThisMachine USING [Name], XNSPSMessages USING [LogMessage], XNSPSPrint; XNSPSPrintImpl: CEDAR MONITOR IMPORTS Atom, BasicTime, Booting, FS, Imager, ImagerFont, ImagerSample, Interpress, IO, IPMaster, Process, RavenDriver, Rope, RuntimeError, SystemVersion, ThisMachine, XNSPSMessages EXPORTS XNSPSPrint ~ { OPEN PrintingP4V3; ROPE: TYPE ~ Rope.ROPE; STREAM: TYPE ~ IO.STREAM; bitmap: ImagerSample.RasterSampleMap _ NIL; PrinterParameters: TYPE ~ REF PrinterParametersRep; PrinterParametersRep: TYPE ~ RECORD [ margins: RavenDriver.RavenRegistration _ [10, 1] ]; pp: PrinterParameters; buffer: REF TEXT _ NEW[TEXT[1000]]; FindCopyCount: PROC [po: PrintingP4V3.PrintOptions] RETURNS [copies: CARDINAL] = TRUSTED BEGIN FOR i: CARDINAL IN [0 .. po.length) DO option: Option _ po.body[i]; WITH option: option SELECT FROM copyCount => {copies _ option.copyCount}; ENDCASE => NULL; ENDLOOP; END; PrintFile: PUBLIC PROC [id: PrintingP4V3.RequestID, fileName: ROPE, printAttributes: PrintingP4V3.PrintAttributes, printOptions: PrintingP4V3.PrintOptions] RETURNS [ok: BOOL] = { old: Process.Priority _ Process.GetPriority[]; copies: CARDINAL _ FindCopyCount[printOptions]; Process.SetPriority[Process.priorityBackground]; {ENABLE RuntimeError.UNCAUGHT => {XNSPSMessages.LogMessage["UNCAUGHT Error", id]; IF dontCatch THEN REJECT ELSE GOTO Out}; { ENABLE { FS.Error => { XNSPSMessages.LogMessage[error.explanation, id]; GOTO Out; }; }; TRUSTED {RavenDriver.WakeUp[]}; PrintBreakPage[printAttributes]; XNSPSMessages.LogMessage["Starting Interpress master", id]; PrintInterpressFile[id, fileName, printOptions, copies]; XNSPSMessages.LogMessage["Deleting file", id]; FS.Delete[fileName ! FS.Error => CONTINUE]; EXITS Out => { FS.Delete[fileName ! FS.Error => CONTINUE]; Process.SetPriority[old]; RETURN[FALSE]; }; }; EXITS Out => { FS.Delete[fileName ! FS.Error => CONTINUE]; Process.SetPriority[old]; RETURN[FALSE]; }; }; Process.SetPriority[old]; RETURN [TRUE]; }; FindPrintStuff: PROC [pa: PrintingP4V3.PrintAttributes] RETURNS [printObjectName, printObjectCreateDate, senderName: ROPE _ NIL] = TRUSTED BEGIN FOR i: CARDINAL IN [0 .. pa.length) DO option: Attribute _ pa.body[i]; WITH option: option SELECT FROM printObjectName => {printObjectName _ option.printObjectName}; printObjectCreateDate => { time: BasicTime.GMT; time _ BasicTime.FromNSTime[option.printObjectCreateDate ! BasicTime.OutOfRange => {time _ BasicTime.earliestGMT; CONTINUE}]; IF LOOPHOLE[time, INT] < LOOPHOLE[BasicTime.earliestGMT, INT] THEN time _ BasicTime.earliestGMT; printObjectCreateDate _ IO.PutR1[IO.time[time]]; }; senderName => {senderName _ option.senderName}; ENDCASE => NULL; ENDLOOP; END; PrintBreakPage: PROC [pa: PrintingP4V3.PrintAttributes] = BEGIN CedarVersion: PROC RETURNS [v: ROPE] ~ { out: IO.STREAM _ IO.ROS[]; IO.PutF[out, "Cedar %g.%g", [integer[SystemVersion.release.major]], [integer[SystemVersion.release.minor]]]; IF SystemVersion.release.patch # 0 THEN IO.PutF1[out, ".%g", [integer[SystemVersion.release.patch]]]; IO.PutF1[out, " of %t\n", [time[BasicTime.FromPupTime[SystemVersion.bootFileDate]]]]; v _ IO.RopeFromROS[out]; IO.Close[out]; }; CornerLogo: SAFE PROC ~ CHECKED { CenterRope: SAFE PROC [context: Imager.Context, name: ROPE, size: REAL, r: ROPE, x, y: REAL] ~ CHECKED { font: ImagerFont.Font _ ImagerFont.Scale[ImagerFont.Find[name], size]; box: ImagerFont.Extents _ ImagerFont.RopeBoundingBox[font: font, rope: r]; height: REAL _ box.descent + box.ascent; length: REAL _ box.leftExtent + box.rightExtent; Imager.SetXY[context: context, p: [x-length/2, y-height/2]]; Imager.SetFont[context: context, font: font]; Imager.ShowRope[context: context, rope: r]; }; Imager.TranslateT[context: context, t: [8.5*Imager.pointsPerInch, 11.0*Imager.pointsPerInch]]; Imager.RotateT[context: context, a: -45.0]; Imager.TranslateT[context: context, t: [0, -300]]; Imager.SetColor[context: context, color: Imager.black]; Imager.MaskRectangle[context: context, r: [-1000, 0, 10000, 10000]]; Imager.SetColor[context: context, color: Imager.white]; Imager.MaskRectangle[context: context, r: [-1000, 152, 10000, 8]]; Imager.MaskRectangle[context: context, r: [-1000, 104, 10000, 16]]; Imager.MaskRectangle[context: context, r: [-1000, 56, 10000, 24]]; Imager.MaskRectangle[context: context, r: [-1000, 8, 10000, 32]]; CenterRope[context, "Xerox/PressFonts/Logo-mrr", 40.0, "XEROX", 0, 180]; CenterRope[context, "Xerox/PressFonts/Classic-brr", 24.0, "INTERPRESS 3.0", 0, 136]; CenterRope[context, "Xerox/PressFonts/Classic-brr", 20.0, "Development Environment", 0, 96]; }; context: Imager.Context; font: ImagerFont.Font; error: ROPE; status: RavenDriver.StatusType; printObjectName, printObjectCreateDate, senderName: ROPE; PrintAPage: ENTRY PROC[] = TRUSTED BEGIN ENABLE UNWIND => NULL; [error, status]_ RavenDriver.PrintFromSampleMap[bitmap ! RavenDriver.PrintingError => RETRY]; END; TRUSTED {bitmap _ RavenDriver.GetPrinterSampleMap[]; context _ RavenDriver.ContextFromSampleMap[bitmap]}; ImagerSample.Clear[bitmap]; Imager.ScaleT[context: context, s: Imager.metersPerPoint]; Imager.DoSave[context: context, action: CornerLogo]; font _ ImagerFont.Scale[ImagerFont.Find["Xerox/PressFonts/Classic-mrr"], 10.0]; Imager.SetFont[context: context, font: font]; Imager.SetXY[context: context, p: [96, 386]]; Imager.ShowRope[context: context, rope: Rope.Concat["Printer: ", ThisMachine.Name[]]]; Imager.SetXY[context: context, p: [96, 374]]; Imager.ShowRope[context: context, rope: Rope.Concat["Software Version: ", CedarVersion[]]]; Imager.SetXY[context: context, p: [96, 350]]; [printObjectName, printObjectCreateDate, senderName] _ FindPrintStuff[pa]; Imager.ShowRope[context: context, rope: Rope.Concat["Interpress master: ", printObjectName]]; Imager.SetXY[context: context, p: [96, 338]]; Imager.ShowRope[context: context, rope: Rope.Concat["Creation Date: ", printObjectCreateDate]]; Imager.SetXY[context: context, p: [96, 314]]; Imager.ShowRope[context: context, rope: Rope.Concat["Printed by: ", senderName]]; Imager.SetXY[context: context, p: [96, 302]]; Imager.ShowRope[context: context, rope: Rope.Concat["Printing Date: ", IO.PutR1[IO.time[]]]]; PrintAPage[]; IF status = error THEN { XNSPSMessages.LogMessage[Rope.Concat[error, " while printing."]]; ERROR ABORTED; }; ImagerSample.Clear[bitmap]; END; LogProc: Interpress.LogProc = TRUSTED { <> XNSPSMessages.LogMessage[explanation]; }; PrintInterpressFile: PROC [id: PrintingP4V3.RequestID, fileName: ROPE, printOptions: PrintingP4V3.PrintOptions, copies: INT] = { ENABLE { Imager.Error => { XNSPSMessages.LogMessage[error.explanation, id]; ERROR ABORTED; }; IPMaster.Error => { XNSPSMessages.LogMessage[Atom.GetPName[error.code], id]; XNSPSMessages.LogMessage[error.explanation, id]; ERROR ABORTED; }; IO.EndOfStream, IO.Error => {XNSPSMessages.LogMessage["Unknown IO Error", id]; ERROR ABORTED; }; }; status: RavenDriver.StatusType; error: ROPE; master: Interpress.Master; context: Imager.Context; PrintAPage: ENTRY PROC[] = TRUSTED BEGIN ENABLE UNWIND => NULL; [error, status]_ RavenDriver.PrintFromSampleMap[bitmap ! RavenDriver.PrintingError => RETRY]; END; TRUSTED {bitmap _ RavenDriver.GetPrinterSampleMap[]; context _ RavenDriver.ContextFromSampleMap[bitmap, fontTunerParms]}; master _ Interpress.Open[fileName, LogProc]; IF master.pages = 1 THEN { -- reprint page 1 from the bitmap efficiently XNSPSMessages.LogMessage[IO.PutFR1["Started page %g", IO.card[1]], id]; ImagerSample.Clear[bitmap]; Interpress.DoPage[master, 1, context, LogProc]; FOR i: INT IN [1 .. copies] DO XNSPSMessages.LogMessage["Printing", id]; PrintAPage[]; IF status = error THEN { XNSPSMessages.LogMessage[Rope.Concat[error, " while printing."], id]; ERROR ABORTED; }; ENDLOOP; } ELSE { -- struggle through interpretting each page in collation order. . . FOR j: INT IN [1 .. copies] DO FOR i: INT IN [1 .. master.pages] DO XNSPSMessages.LogMessage[IO.PutFR1["Started page %g", IO.card[i]], id]; ImagerSample.Clear[bitmap]; Interpress.DoPage[master, i, context, LogProc]; XNSPSMessages.LogMessage["Printing", id]; PrintAPage[]; IF status = error THEN { XNSPSMessages.LogMessage[Rope.Concat[error, " while printing."], id]; ERROR ABORTED; }; ENDLOOP; ENDLOOP; }; XNSPSMessages.LogMessage["All Done", id]; }; Status: RavenDriver.StatusProc = { XNSPSMessages.LogMessage[status]; }; fontTunerParms: ROPE _ NIL; -- "[Cedar]FontTune>Simple0"; dontCatch: BOOL _ FALSE; GetMargins: PUBLIC ENTRY SAFE PROC [] RETURNS [sMargin, fMargin: CARDINAL] = TRUSTED BEGIN ENABLE UNWIND => NULL; RETURN [pp.margins.short, pp.margins.long]; END; SetMargins: PUBLIC ENTRY SAFE PROC [sMargin, fMargin: CARDINAL] = TRUSTED BEGIN ENABLE UNWIND => NULL; s: STREAM _ NIL; IF sMargin NOT IN [1..30] THEN sMargin _ 10; IF fMargin NOT IN [10..43] THEN fMargin _ 1; pp.margins.short _ sMargin; pp.margins.long _ fMargin; s _ FS.StreamOpen[fileName: "///PrinterParameters.DontDeleteMe", accessOptions: create ! FS.Error => CONTINUE]; IF s # NIL THEN BEGIN IO.PutF[s, "%g %g\n", IO.card[sMargin], IO.card[fMargin]]; IO.Close[s]; END; RavenDriver.SetRegistration[pp.margins]; END; Init: ENTRY PROC [] = TRUSTED { ENABLE UNWIND => NULL; s: STREAM _ NIL; sMargin, fMargin: CARDINAL; IF Booting.switches[z] THEN fontTunerParms _ "[Cedar]FontTune>Simple0"; <> IF Booting.switches[y] THEN dontCatch _ TRUE; pp _ NEW [PrinterParametersRep _ [margins: [10, 1]]]; BEGIN s _ FS.StreamOpen[fileName: "///PrinterParameters.DontDeleteMe", accessOptions: read ! FS.Error => CONTINUE]; IF s # NIL THEN BEGIN ENABLE IO.Error => GOTO Out; sMargin _ IO.GetCard[s]; fMargin _ IO.GetCard[s]; IO.Close[s]; IF sMargin NOT IN [1..30] THEN sMargin _ 1; IF fMargin NOT IN [10..43] THEN fMargin _ 10; pp.margins.short _ sMargin; pp.margins.long _ fMargin; END; EXITS Out => NULL; END; RavenDriver.SetRegistration[pp.margins]; XNSPSMessages.LogMessage["Booted."]; <> RavenDriver.RegisterStatusProc[Status]; }; Init[]; }.