<> <> <> <> DIRECTORY Atom USING [GetPName], BasicTime, Booting USING [switches], Convert, FS USING [Delete, Error, FileInfo, StreamOpen], Imager, ImagerBitmapDevicePrivate, ImagerBrick, ImagerFont, ImagerPixelMap USING [Clear, PixelMap], Interpress USING [DoPage, LogProc, Open, Master], IO, IPMaster USING [Error], IPPrinterMain, IPPrinterQueue USING [DoRequest, LogMessage, Request], IPPrinterRemoteStream USING [Error, Read ], Process USING [Priority, SetPriority, GetPriority, priorityBackground, Detach], RavenDriver USING [ContextFromPixelMap, GetPrinterPixelMap, PrintFromPixelMap, RavenRegistration, RegisterStatusProc, SetRegistration, StatusProc, StatusType, WakeUp], Rope USING [Concat, ROPE], RuntimeError USING [UNCAUGHT], SystemVersion USING [release, bootFileDate], ThisMachine USING [Name]; IPPrinterMainImpl: MONITOR IMPORTS Atom, BasicTime, Booting, Convert, FS, Imager, ImagerFont, ImagerPixelMap, Interpress, IO, IPMaster, IPPrinterQueue, IPPrinterRemoteStream, Process, RavenDriver, Rope, RuntimeError, SystemVersion, ThisMachine EXPORTS IPPrinterMain ~ { ROPE: TYPE ~ Rope.ROPE; STREAM: TYPE ~ IO.STREAM; bitmap: ImagerPixelMap.PixelMap _ [0, 0, 0, 0, 0, 0, NIL]; PrinterParameters: TYPE ~ REF PrinterParametersRep; PrinterParametersRep: TYPE ~ RECORD [ fSize: REAL _ 11.0, -- The size of sheet on fast edge sSize: REAL _ 8.5, -- The size of sheet on the slow edge fDPI: CARDINAL _ 300, -- Fast edge dots per inch sDPI: CARDINAL _ 300, -- Slow edge dots per inch margins: RavenDriver.RavenRegistration _ [10, 1] ]; pp: PrinterParameters; buffer: REF TEXT _ NEW[TEXT[1000]]; tempFile: ROPE _ "[]<>Printer>Printer.tmp"; DoFile: PROC [request: IPPrinterQueue.Request, requestNumber: CARDINAL, abort: REF BOOLEAN] = { old: Process.Priority _ Process.GetPriority[]; Process.SetPriority[Process.priorityBackground]; {ENABLE RuntimeError.UNCAUGHT => {IPPrinterQueue.LogMessage["UNCAUGHT Error", requestNumber]; IF dontCatch THEN REJECT ELSE GOTO Out}; { ENABLE { IPPrinterRemoteStream.Error => { IPPrinterQueue.LogMessage[expl, requestNumber]; GOTO Out; }; FS.Error => { IPPrinterQueue.LogMessage[error.explanation, requestNumber]; GOTO Out; }; }; stream: IO.STREAM _ FS.StreamOpen[fileName: tempFile, accessOptions: create, createByteCount: 25600]; RavenDriver.WakeUp[]; PrintBreakPage[request]; IPPrinterQueue.LogMessage["Copying file", requestNumber]; IPPrinterRemoteStream.Read[request.fileName, request.requestor, request.requestorPassword, stream]; IPPrinterQueue.LogMessage["Starting Interpress master", requestNumber]; PrintInterpressFile[tempFile, requestNumber, abort, request.copies]; IPPrinterQueue.LogMessage["Deleting file", requestNumber]; FS.Delete[tempFile ! FS.Error => CONTINUE]; EXITS Out => { FS.Delete[tempFile ! FS.Error => CONTINUE]; Process.SetPriority[old]; RETURN; }; }; EXITS Out => { FS.Delete[tempFile ! FS.Error => CONTINUE]; Process.SetPriority[old]; RETURN; }; }; Process.SetPriority[old]; }; PrintBreakPage: PROC [request: IPPrinterQueue.Request] = 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; PrintAPage: ENTRY PROC[] = BEGIN ENABLE UNWIND => NULL; [error, status]_ RavenDriver.PrintFromPixelMap[bitmap]; END; bitmap _ RavenDriver.GetPrinterPixelMap[]; context _ RavenDriver.ContextFromPixelMap[bitmap]; ImagerPixelMap.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]]; Imager.ShowRope[context: context, rope: Rope.Concat["Interpress master: ", request.fileName]]; Imager.SetXY[context: context, p: [96, 338]]; Imager.ShowRope[context: context, rope: Rope.Concat["Creation Date: ", Convert.RopeFromTime[from: FS.FileInfo[name: request.fileName].created, start: years, end: seconds, includeDayOfWeek: TRUE, useAMPM: TRUE, includeZone: TRUE]]]; Imager.SetXY[context: context, p: [96, 314]]; Imager.ShowRope[context: context, rope: Rope.Concat["Printed by: ", request.requestor]]; Imager.SetXY[context: context, p: [96, 302]]; Imager.ShowRope[context: context, rope: Rope.Concat["Printing Date: ", request.requestTime]]; PrintAPage[]; IF status = error THEN { IPPrinterQueue.LogMessage[Rope.Concat[error, " while printing."]]; ERROR ABORTED; }; ImagerPixelMap.Clear[bitmap]; END; LogProc: Interpress.LogProc = TRUSTED { IPPrinterQueue.LogMessage[explanation]; }; PrintInterpressFile: PROC [fileName: ROPE, requestNumber: CARDINAL, abort: REF BOOLEAN, copies: INT] = { ENABLE { Imager.Error => { IPPrinterQueue.LogMessage[error.explanation, requestNumber]; ERROR ABORTED; }; IPMaster.Error => { IPPrinterQueue.LogMessage[Atom.GetPName[error.code], requestNumber]; IPPrinterQueue.LogMessage[error.explanation, requestNumber]; ERROR ABORTED; }; IO.EndOfStream, IO.Error => {IPPrinterQueue.LogMessage["Unknown IO Error", requestNumber]; ERROR ABORTED; }; }; status: RavenDriver.StatusType; error: ROPE; master: Interpress.Master; context: Imager.Context; PrintAPage: ENTRY PROC[] = BEGIN ENABLE UNWIND => NULL; [error, status]_ RavenDriver.PrintFromPixelMap[bitmap]; END; bitmap _ RavenDriver.GetPrinterPixelMap[]; context _ RavenDriver.ContextFromPixelMap[bitmap, fontTunerParms]; master _ Interpress.Open[fileName, LogProc]; IF master.pages = 1 THEN { -- reprint page 1 from the bitmap efficiently IF abort^ THEN ERROR ABORTED; IPPrinterQueue.LogMessage[IO.PutFR1["Started page %g", IO.card[1]], requestNumber]; ImagerPixelMap.Clear[bitmap]; Interpress.DoPage[master, 1, context, LogProc]; FOR i: INT IN [1 .. copies] DO IPPrinterQueue.LogMessage["Printing", requestNumber]; PrintAPage[]; IF status = error THEN { IPPrinterQueue.LogMessage[Rope.Concat[error, " while printing."], requestNumber]; 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 IF abort^ THEN ERROR ABORTED; IPPrinterQueue.LogMessage[IO.PutFR1["Started page %g", IO.card[i]], requestNumber]; ImagerPixelMap.Clear[bitmap]; Interpress.DoPage[master, i, context, LogProc]; IPPrinterQueue.LogMessage["Printing", requestNumber]; PrintAPage[]; IF status = error THEN { IPPrinterQueue.LogMessage[Rope.Concat[error, " while printing."], requestNumber]; ERROR ABORTED; }; ENDLOOP; ENDLOOP; }; IPPrinterQueue.LogMessage["All Done", requestNumber]; }; Main: PROC = { DO IPPrinterQueue.DoRequest[DoFile ! ABORTED => CONTINUE] ENDLOOP }; Status: RavenDriver.StatusProc = { IPPrinterQueue.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 [] = { 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]; IPPrinterQueue.LogMessage["Booted."]; Process.Detach[FORK Main[]]; RavenDriver.RegisterStatusProc[Status]; }; Init[]; }.