IPPrinterMainImpl.mesa
Copyright Ó 1985, 1986, 1987 by Xerox Corporation. All rights reserved.
Tim Diebert: January 29, 1987 8:43:32 am PST
Rick Beach, June 30, 1986 4:50:43 pm PDT
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 TEXTNEW[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.STREAMFS.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.STREAMIO.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: ROPENIL; -- "[Cedar]<CedarChest6.1>FontTune>Simple0";
dontCatch: BOOLFALSE;
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: STREAMNIL;
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: STREAMNIL; sMargin, fMargin: CARDINAL;
IF Booting.switches[z] THEN fontTunerParms ← "[Cedar]<CedarChest6.1>FontTune>Simple0";
The font tuner adds .fontTune
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[];
}.