<> <> <> <> DIRECTORY BasicTime USING [Update, GetUniversalID, GMT, SecondsSinceEpoch], DecomposerControl USING [DocumentInProgress, FreeDecomposeObject, NoticeNewFonts, Start, Stop, Stopped], ForwardingControl USING [Start, Stop, Stopped], Heap USING [FreeNode, MakeNode], MarkerControl USING [EngineSpecific], MergeControl USING [Start, Stop, Stopped], MsgOps USING [FilingErrToMsg], NSDataStream USING [Abort, Aborted, Handle, OperateOnSource, Source, SourceStream], <> <> <> <> PaperHandling USING [TwoPaperSizes], PaperTypes USING [PaperMMDimension, PaperSize], PaperTypesExtras USING [nullPaper], PrincOps USING [BYTE], PrintQueue USING [CopyStringIn, CopyQueueObject, LocateHandle, maxFaxPhoneNos, maxPhoneNoLength, nilQueueObjectHandle, ObjectStatus, Previous, QueueObject, QueueObjectHandle, QueueStage, Requeue], PrintQueueExtras USING [GetQueueObject], Process USING [Detach], <> PSCommand USING [allDocuments, DocumentAttributes, DocumentAttrRecord, DocumentFilter, DocumentID, DocumentParameters, DocumentProc, DocumentStatus, Error, ErrorRecord, FaxTransmitData, noDocuments, nullDocumentID, SimpleDocStatus], PSCommandInternal USING [commandHeap, currentCondition, fontsNoticed, markerProcs, RotateFonts90, state, stateSpace, testPatternsNoticed], PSState USING [SpoolerState], PSVolume USING [GetDefaultSession], QueueControl USING [WaitAbortQueueEmpty], QueueFile USING [CreateError, CreateTempFile, Delete, InsufficientPages, MakePermanent], Space USING [ForceOut], SpoolControl USING [ConnectionClosed, Error, ErrorTypes, FilterConnection, Start, Stop, Stopped, Suspend], Stream USING [Delete], String USING [AppendDecimal, AppendLongDecimal], TestPattern USING [CatalogTPs], Time USING [Append, AppendCurrent, Unpack]; PSCommandAImpl: CEDAR PROGRAM IMPORTS BasicTime, DecomposerControl, ForwardingControl, Heap, MergeControl, MsgOps, NSDataStream, NSFile, NSPrintCourier, NSString, PrincOps, PrintQueue, PrintQueueExtras, Process, PSAsyncMsg, PSCommand, PSCommandInternal, PSVolume, QueueControl, QueueFile, Space, SpoolControl, Stream, String, TestPattern, Time EXPORTS PSCommand, PSCommandInternal SHARES SpoolControl = BEGIN OPEN PSCommandInternal; session: NSFile.Session = PSVolume.GetDefaultSession[]; nsNil: NSString.String = NSString.nullString; <> QueueObjectFilter: TYPE = RECORD [ id: PSCommand.DocumentID _ PSCommand.nullDocumentID, name: NSString.String _ nsNil, sender: NSString.String _ nsNil, status: PACKED ARRAY PrintQueue.ObjectStatus OF BOOLEAN _ ALL[FALSE]]; Error: PUBLIC ERROR [problem: PSCommand.ErrorRecord] = CODE; <<*********************************>> <> <<*********************************>> <<********************************* >> <> <<*********************************>> Enqueue: PUBLIC PROCEDURE [document: NSDataStream.Source, parameters: PSCommand.DocumentParameters] RETURNS [documentID: PSCommand.DocumentID] = BEGIN beginSpoolDate: BasicTime.GMT _ BasicTime.Update[]; file: NSFile.Handle; attris: ARRAY [0..1) OF NSFile.Attribute _ [[position[NSFile.lastPosition]]]; qOH: PrintQueue.QueueObjectHandle; why: PSCommand.ErrorRecord; HandleNSFileFailure: PROCEDURE [qOH: PrintQueue.QueueObjectHandle, error: NSFile.ErrorRecord] = BEGIN IF state.spoolerTrace # none THEN BEGIN nsFileFailure: NSString.String = Str["--File Transfer Failed: <1>"L]; stringArray: ARRAY [0..1) OF NSString.String; DisplayInitialSpoolInfo[qOH]; [stringArray[0],] _ MsgOps.FilingErrToMsg[error]; PSAsyncMsg.ExpandArrayAndPutString[nsFileFailure, DESCRIPTOR[stringArray]]; END; qOH.currentStatus _ spoolFailure; qOH.fileID _ QueueFile.Delete[qOH.fileID, file]; [] _ PrintQueue.Requeue[qOH: qOH, fromQueue: spooling, toQueue: aborted]; END; --HandleNSFileFailure BEGIN SpoolControl.FilterConnection[! SpoolControl.Error => { why _ ConvertSpoolControlError[type]; GOTO SpoolControlError}]; [file, qOH] _ CreateSpoolFile[parameters ! UNWIND => SpoolControl.ConnectionClosed[]]; EXITS SpoolControlError => { NSDataStream.OperateOnSource[document, AbortAndDeleteSourceStream]; ERROR PSCommand.Error[why]; }; END; NSFile.Replace[file, document, , session ! NSFile.Error => {SpoolControl.ConnectionClosed[]; HandleNSFileFailure[qOH, error]; REJECT}]; SpoolControl.ConnectionClosed[]; QueueFile.MakePermanent[file, DESCRIPTOR[attris] ! NSFile.Error => {HandleNSFileFailure[qOH, error]; REJECT}]; Process.Detach[FORK CompleteEnqueue[qOH, file, beginSpoolDate]]; --finish up queuing without keeping the client waiting RETURN[qOH.uid]; END; --Enqueue ListDocuments: PUBLIC SAFE PROCEDURE [proc: PSCommand.DocumentProc, filter: PSCommand.DocumentFilter _ PSCommand.allDocuments] = <> <> BEGIN continue: BOOLEAN _ TRUE; qObjFilter: QueueObjectFilter _ []; scratchQOH: PrintQueue.QueueObjectHandle _ NIL; scratchDocAttributes: PSCommand.DocumentAttributes _ NIL; scratchFaxMitData: LONG DESCRIPTOR FOR ARRAY OF PSCommand.FaxTransmitData _ DESCRIPTOR[NIL, 0]; IF filter = PSCommand.noDocuments THEN RETURN; QObjFilterFromClientFilter[@filter, @qObjFilter]; <> scratchQOH _ PrintQueueExtras.GetQueueObject[commandHeap]; scratchDocAttributes _ commandHeap.NEW[PSCommand.DocumentAttrRecord.fax495]; --allocate enough space for the largest variant scratchFaxMitData _ DESCRIPTOR[Heap.MakeNode[ commandHeap, SIZE[PSCommand.FaxTransmitData] * PrintQueue.maxFaxPhoneNos], PrintQueue.maxFaxPhoneNos]; BEGIN --extra begin/end for exits statement at end of proc <> IF filter = PSCommand.allDocuments THEN BEGIN --list all queues noOfQueues: CARDINAL = 18; queueStage: ARRAY [0..noOfQueues) OF PrintQueue.QueueStage _ [ spooling, spooledNormal, bannerOnly, tpSpooled, decomposing, decomposed, tpDecomposed, retransmit, marking, marked, merging, merged, tpMerged, forwarding, forwarded, aborted, temp, inactive]; FOR i: CARDINAL IN [0..noOfQueues) DO continue _ ListQueueStage[ queueStage[i], proc, qObjFilter, scratchQOH, scratchDocAttributes, scratchFaxMitData]; IF NOT continue THEN GOTO Done; ENDLOOP; END ELSE BEGIN --List queue stages corresponding to statuses specified: <> IF filter.status[pending] THEN BEGIN noOfQueues: CARDINAL = 4; queueStage: ARRAY [0..noOfQueues) OF PrintQueue.QueueStage _ [ spooling, spooledNormal, bannerOnly, tpSpooled]; FOR i: CARDINAL IN [0..noOfQueues) DO continue _ ListQueueStage[ queueStage[i], proc, qObjFilter, scratchQOH, scratchDocAttributes, scratchFaxMitData]; IF NOT continue THEN GOTO Done; ENDLOOP; END; <> IF filter.status[inProgress] THEN BEGIN noOfQueues: CARDINAL = 9; queueStage: ARRAY [0..noOfQueues) OF PrintQueue.QueueStage _ [ decomposing, decomposed, tpDecomposed, retransmit, marking, merging, merged, tpMerged, forwarding]; FOR i: CARDINAL IN [0..noOfQueues) DO continue _ ListQueueStage[ queueStage[i], proc, qObjFilter, scratchQOH, scratchDocAttributes, scratchFaxMitData]; IF NOT continue THEN GOTO Done; ENDLOOP; END; <> IF filter.status[completed] OR filter.status[rejected] OR filter.status[aborted] OR filter.status[canceled] THEN BEGIN noOfQueues: CARDINAL = 4; queueStage: ARRAY [0..noOfQueues) OF PrintQueue.QueueStage _ [ marked, forwarded, aborted, inactive]; FOR i: CARDINAL IN [0..noOfQueues) DO continue _ ListQueueStage[ queueStage[i], proc, qObjFilter, scratchQOH, scratchDocAttributes, scratchFaxMitData]; IF NOT continue THEN GOTO Done; ENDLOOP; END; END; EXITS Done => NULL; END; commandHeap.FREE[@scratchQOH]; commandHeap.FREE[@scratchDocAttributes]; Heap.FreeNode[commandHeap, BASE[scratchFaxMitData]]; END; --ListDocuments CancelDocument: PUBLIC PROCEDURE [documentID: PSCommand.DocumentID] RETURNS [status: PSCommand.DocumentStatus] = BEGIN <> <> qOH: PrintQueue.QueueObjectHandle; queueStage: PrintQueue.QueueStage; [qOH, queueStage] _ PrintQueue.LocateHandle[documentID]; IF qOH = PrintQueue.nilQueueObjectHandle THEN ERROR Error[[documentNotFound[]]]; SELECT queueStage FROM spooledNormal, bannerOnly, decomposed, merged, tpSpooled, tpDecomposed, tpMerged => BEGIN [] _ PrintQueue.Requeue[qOH: qOH, fromQueue: queueStage, toQueue: temp]; qOH.currentStatus _ canceledInQueue; [] _ PrintQueue.Requeue[qOH: qOH, fromQueue: temp, toQueue: aborted]; QueueControl.WaitAbortQueueEmpty[]; END; retransmit => BEGIN [] _ PrintQueue.Requeue[qOH: qOH, fromQueue: queueStage, toQueue: temp]; qOH.currentStatus _ faxCanceled; WITH q: qOH SELECT FROM fax495 => FOR p: CARDINAL IN [0..q.phoneNoCount) DO q.transmitData[p].queuedForRetry _ FALSE; ENDLOOP; ENDCASE; [] _ PrintQueue.Requeue[qOH: qOH, fromQueue: temp, toQueue: aborted]; QueueControl.WaitAbortQueueEmpty[]; END; decomposing => BEGIN state.internalControl.formatterEnabled _ FALSE; DecomposerControl.Stop[status: canceledInDecomposer]; [] _ DecomposerControl.Stopped[wait]; QueueControl.WaitAbortQueueEmpty[]; state.internalControl.formatterEnabled _ TRUE; IF state.clientControl.formatterEnabled THEN DecomposerControl.Start[]; END; marking => BEGIN state.internalControl.markerEnabled _ FALSE; WITH q: qOH SELECT FROM fax495 => markerProcs.stop[status: faxCanceled]; ENDCASE => markerProcs.stop[status: canceledInMarker]; [] _ markerProcs.stopped[wait]; QueueControl.WaitAbortQueueEmpty[]; state.internalControl.markerEnabled _ TRUE; IF state.clientControl.markerEnabled THEN markerProcs.start[]; END; merging => BEGIN state.internalControl.markerEnabled _ FALSE; MergeControl.Stop[status: canceledInMerger]; [] _ MergeControl.Stopped[wait]; QueueControl.WaitAbortQueueEmpty[]; state.internalControl.markerEnabled _ TRUE; IF state.clientControl.markerEnabled THEN MergeControl.Start[]; END; forwarding => BEGIN state.internalControl.markerEnabled _ FALSE; ForwardingControl.Stop[status: canceledInForwarder]; [] _ ForwardingControl.Stopped[wait]; QueueControl.WaitAbortQueueEmpty[]; state.internalControl.markerEnabled _ TRUE; IF state.clientControl.markerEnabled THEN ForwardingControl.Start[]; END; ENDCASE; RETURN[DocumentStatusFromQObjStatus[qOH]]; END; --CancelDocument <<**************************************** >> <> <<****************************************>> Start: PUBLIC PROCEDURE = BEGIN <> IF currentCondition = stopped THEN BEGIN currentCondition _ starting; IF state.mode.current # repair THEN BEGIN EnableQueuing[]; EnablePrinting[]; IF state.option = raven THEN --don't reference markerProcs if printing option = feps9700 WITH m: markerProcs SELECT FROM raven => m.wakeupEngine[]; --Marker checks to be sure engine build is compatible. ENDCASE; state.mode.returnTo _ state.mode.current _ normal; END ELSE state.mode.returnTo _ normal; NSPrintCourier.ExportRemoteProgram[]; Space.ForceOut[stateSpace]; currentCondition _ started; END; END; --StartPrintService Stop: PUBLIC PROCEDURE = BEGIN <> IF currentCondition = started THEN BEGIN currentCondition _ stopping; IF state.mode.current # repair THEN BEGIN DisableQueuing[]; DisablePrinting[]; IF state.option = raven THEN --don't reference markerProcs if printing option = feps9700 WITH m: markerProcs SELECT FROM raven => m.dozeoffEngine[]; --Marker checks to be sure engine build is compatible. ENDCASE; state.mode.current _ state.mode.returnTo _ shutDown; END ELSE state.mode.returnTo _ shutDown; NSPrintCourier.UnexportRemoteProgram[]; Space.ForceOut[stateSpace]; currentCondition _ stopped; <> END; END; --StopPrintService StartPrinting: PUBLIC PROCEDURE [user: NSName.Name] = BEGIN IF state.clientControl.formatterEnabled THEN RETURN; IF state.option = bansheeDl THEN <> <> PSCommandInternal.RotateFonts90[]; IF NOT fontsNoticed THEN BEGIN DecomposerControl.NoticeNewFonts[ ! DecomposerControl.DocumentInProgress => ERROR Error[[documentInProgress[]]]]; fontsNoticed _ TRUE; END; IF NOT testPatternsNoticed THEN BEGIN TestPattern.CatalogTPs[]; testPatternsNoticed _ TRUE; END; state.clientControl.formatterEnabled _ state.clientControl.markerEnabled _ TRUE; IF state.internalControl.markerEnabled THEN BEGIN DecomposerControl.Start[]; IF state.option = feps9700 THEN BEGIN MergeControl.Start[]; ForwardingControl.Start[]; END ELSE markerProcs.start[]; END; state.lastUserToStartPrinting.length _ 0; IF user.local.length > 0 THEN state.lastUserToStartPrinting _ NSString.AppendString[ to: state.lastUserToStartPrinting, from: user.local ! NSString.StringBoundsFault => CONTINUE]; Space.ForceOut[stateSpace]; END; --StartPrinting StopPrinting: PUBLIC PROCEDURE [user: NSName.Name, reason: NSString.String _ NSString.nullString] = BEGIN abortedCount: LONG CARDINAL _ state.docsAborted.total; IF NOT state.clientControl.formatterEnabled THEN RETURN; state.clientControl.formatterEnabled _ state.clientControl.markerEnabled _ FALSE; IF state.internalControl.markerEnabled THEN StopPrintingInternal[]; state.lastUserToStopPrinting.length _ 0; state.lastStopPrintingReason.length _ 0; IF user.local.length > 0 THEN state.lastUserToStopPrinting _ NSString.AppendString[ to: state.lastUserToStopPrinting, from: user.local ! NSString.StringBoundsFault => CONTINUE]; IF reason.length > 0 THEN state.lastStopPrintingReason _ NSString.AppendString[ to: state.lastStopPrintingReason, from: reason ! NSString.StringBoundsFault => CONTINUE]; Space.ForceOut[stateSpace]; END; --StopPrinting StartQueuing: PUBLIC PROCEDURE [user: NSName.Name] = BEGIN IF state.clientControl.spooler = enabled THEN RETURN; state.clientControl.spooler _ enabled; IF state.internalControl.spooler = enabled THEN SpoolControl.Start[]; state.lastUserToStartQueuing.length _ 0; IF user.local.length > 0 THEN state.lastUserToStartQueuing _ NSString.AppendString[ to: state.lastUserToStartQueuing, from: user.local ! NSString.StringBoundsFault => CONTINUE]; Space.ForceOut[stateSpace]; END; --StartQueuing StopQueuing: PUBLIC PROCEDURE [user: NSName.Name, reason: NSString.String _ NSString.nullString] = BEGIN IF state.clientControl.spooler # enabled THEN RETURN; state.clientControl.spooler _ disabled; IF state.internalControl.spooler = enabled THEN BEGIN SpoolControl.Stop[aborted]; [] _ SpoolControl.Stopped[wait]; END; state.lastUserToStopQueuing.length _ 0; state.lastStopQueuingReason.length _ 0; IF user.local.length > 0 THEN state.lastUserToStopQueuing _ NSString.AppendString[ to: state.lastUserToStopQueuing, from: user.local ! NSString.StringBoundsFault => CONTINUE]; IF reason.length > 0 THEN state.lastStopQueuingReason _ NSString.AppendString[ to: state.lastStopQueuingReason, from: reason ! NSString.StringBoundsFault => CONTINUE]; Space.ForceOut[stateSpace]; END; --StopQueuing ShutDownEngine: PUBLIC PROCEDURE = BEGIN WITH s: state SELECT FROM raven => IF s.engineBuild > b1 THEN WITH m: markerProcs SELECT FROM raven => m.dozeoffEngine[]; ENDCASE => ERROR --Marker procs engine type disagrees with state record. ELSE ERROR Error[[incompatiblePrintingOption[]]]; ENDCASE => ERROR Error[[incompatiblePrintingOption[]]]; END; --ShutdownEngine WakeUpEngine: PUBLIC PROCEDURE = BEGIN WITH s: state SELECT FROM raven => IF s.engineBuild > b1 THEN WITH m: markerProcs SELECT FROM raven => m.wakeupEngine[]; ENDCASE => ERROR --Marker procs engine type disagrees with state record. ELSE ERROR Error[[incompatiblePrintingOption[]]]; ENDCASE => ERROR Error[[incompatiblePrintingOption[]]]; END; --WakeupEngine <> EnablePrinting: PUBLIC PROCEDURE = BEGIN IF state.internalControl.formatterEnabled THEN RETURN; state.internalControl.formatterEnabled _ state.internalControl.markerEnabled _ TRUE; IF state.clientControl.markerEnabled THEN BEGIN DecomposerControl.Start[]; IF state.option = feps9700 THEN BEGIN MergeControl.Start[]; ForwardingControl.Start[]; END ELSE markerProcs.start[]; END; Space.ForceOut[stateSpace]; END; --EnablePrinting DisablePrinting: PUBLIC PROCEDURE = BEGIN IF NOT state.internalControl.formatterEnabled THEN RETURN; state.internalControl.formatterEnabled _ state.internalControl.markerEnabled _ FALSE; IF state.clientControl.markerEnabled THEN StopPrintingInternal[]; Space.ForceOut[stateSpace]; END; --DisablePrinting EnableQueuing: PUBLIC PROCEDURE = BEGIN IF state.internalControl.spooler = enabled THEN RETURN; state.internalControl.spooler _ enabled; IF state.clientControl.spooler = enabled THEN SpoolControl.Start[]; Space.ForceOut[stateSpace]; END; --EnableQueuing DisableQueuing: PUBLIC PROCEDURE [reason: PSState.SpoolerState _ disabled] = BEGIN IF state.internalControl.spooler # enabled THEN RETURN; state.internalControl.spooler _ reason; IF state.clientControl.spooler = enabled THEN BEGIN IF reason = disabledForMarking THEN SpoolControl.Suspend[] ELSE SpoolControl.Stop[aborted]; [] _ SpoolControl.Stopped[wait]; END; Space.ForceOut[stateSpace]; END; --DisableQueuing <> <> AbortAndDeleteSourceStream: PROCEDURE [stream: NSDataStream.SourceStream] = BEGIN NSDataStream.Abort[stream]; Stream.Delete[stream ! NSDataStream.Aborted => CONTINUE]; END; --AbortAndDeleteSourceStream CompleteEnqueue: PROCEDURE [qOH: PrintQueue.QueueObjectHandle, file: NSFile.Handle, beginSpoolDate: BasicTime.GMT] = BEGIN <<--This procedure does a few final things with the qOH before putting it on the spooled queue. It is forked by Enqueue so that Enqueue's client is not kept hanging any longer than necessary.-->> selection: NSFile.Selections _ NSFile.noSelections; attribute: NSFile.Attributes _ NSFile.GetAttributesRecord[]; IF state.spoolerTrace # none THEN DisplayInitialSpoolInfo[qOH]; <> selection.interpreted[dataSize] _ TRUE; NSFile.GetAttributes[file, selection, attribute, session]; qOH.fileSize _ attribute.dataSize; NSFile.Close[file, session]; NSFile.ReleaseAttributesRecord[attribute]; qOH.fileQueuedDate _ BasicTime.Update[]; qOH.currentStatus _ spooled; [] _ PrintQueue.Requeue[qOH: qOH, fromQueue: spooling, toQueue: spooledNormal]; IF state.spoolerTrace = verbose THEN DisplayFinalSpoolInfo[qOH, beginSpoolDate]; <> IF state.option = raven THEN WITH m: markerProcs SELECT FROM raven => WITH d: m.status[].engine SELECT FROM raven => IF d.raven IN [aboutToDozeOff..fuserUnderTemperature] THEN m.wakeupEngine[]; ENDCASE => ERROR; ENDCASE => ERROR; END; -- of CompleteEnqueue CopyDocParametersToQueueObject: PROCEDURE [qOH: PrintQueue.QueueObjectHandle, parms: PSCommand.DocumentParameters] = BEGIN timeLength: CARDINAL = 18; timeString: LONG STRING _ [timeLength]; qOH.fileName.length _ 0; qOH.localFileName.length _ 0; IF parms.name # NSString.nullString THEN BEGIN PrintQueue.CopyStringIn[qOH, parms.name, fileName]; PrintQueue.CopyStringIn[qOH, parms.name, localFileName]; END; <> Time.AppendCurrent[timeString]; qOH.localFileName _ NSString.AppendString[qOH.localFileName, Str[timeString] ! NSString.StringBoundsFault => CONTINUE]; qOH.fileCreateDate _ parms.createDate; IF parms.senderName # NSString.nullString THEN PrintQueue.CopyStringIn[qOH, parms.senderName, sender]; qOH.fileSize _ parms.size; IF parms.recipientName # NSString.nullString THEN PrintQueue.CopyStringIn[qOH, parms.recipientName, recipient]; IF parms.message # NSString.nullString THEN PrintQueue.CopyStringIn[qOH, parms.message, operatorMsg]; qOH.numberCopies _ parms.copyCount; <<--This is a kludge where we check for page number zero which is not allowed. (It is documented in Printing Protocol standard that page numbers start at 1.) The decomposer will act strangely if you give it page number zero. Since OS 5.0 Star used to send first PageToPrint=0, we need to have the kludge in for a while for backward compatibility. An AR has been submitted against Viewpoint and is expected to be fixed.>> <> IF parms.firstPageToPrint = 0 OR parms.lastPageToPrint = 0 THEN BEGIN <> qOH.firstPageToPrint _ 1; qOH.lastPageToPrint _ LAST[CARDINAL]; END ELSE BEGIN qOH.firstPageToPrint _ parms.firstPageToPrint; qOH.lastPageToPrint _ parms.lastPageToPrint; END; qOH.paper _ parms.paper; qOH.staple _ parms.staple; qOH.twoSided _ parms.twoSided; qOH.priority _ LOOPHOLE[parms.priority]; qOH.releaseKey _ parms.releaseKey; WITH s: state SELECT FROM bansheeDl => BEGIN dStatus: MarkerControl.EngineSpecific _ markerProcs.status[].engine; WITH d: dStatus SELECT FROM bansheeDl => BEGIN IF parms.paper = PaperTypesExtras.nullPaper THEN qOH.paper _ d.paper; --Default to currently loaded paper size if size not specified IF qOH.paper # d.paper THEN PSCommand.Error[[enqueue[mediumUnavailable]]]; END; ENDCASE => ERROR; END; d1 => BEGIN dStatus: MarkerControl.EngineSpecific _ markerProcs.status[].engine; WITH d: dStatus SELECT FROM d1 => BEGIN IF parms.paper = PaperTypesExtras.nullPaper THEN qOH.paper.knownSize _ d.paperSize; --Default to currently loaded paper size if size not specified IF qOH.paper.knownSize # d.paperSize THEN PSCommand.Error[[enqueue[mediumUnavailable]]]; END; ENDCASE => ERROR; END; fax295 => BEGIN SELECT s.paperWidth FROM PaperTypes.PaperMMDimension[letter].short => BEGIN --Paper width is for letter/legal paper. IF parms.paper = PaperTypesExtras.nullPaper THEN qOH.paper.knownSize _ letter; --Default to letter if size not specified IF qOH.paper.knownSize = a4 THEN qOH.paper.knownSize _ legal; --Allow a4 documents to be printed on legal paper IF qOH.paper.knownSize # letter AND qOH.paper.knownSize # legal THEN PSCommand.Error[[enqueue[mediumUnavailable]]]; END; PaperTypes.PaperMMDimension[a4].short => BEGIN --Paper width is for a4 paper. IF parms.paper = PaperTypesExtras.nullPaper THEN qOH.paper.knownSize _ a4; --Default to a4 if size not specified IF qOH.paper.knownSize # a4 THEN PSCommand.Error[[enqueue[mediumUnavailable]]]; END; ENDCASE => ERROR; --Paper width is other than letter/legal or a4??? END; fax495 => BEGIN SELECT s.paperWidth FROM PaperTypes.PaperMMDimension[letter].short => BEGIN --Paper width is for letter/legal paper. IF parms.paper = PaperTypesExtras.nullPaper THEN qOH.paper.knownSize _ letter; --Default to letter if size not specified IF qOH.paper.knownSize = a4 THEN qOH.paper.knownSize _ legal; --Allow a4 documents to be printed on legal paper IF qOH.paper.knownSize # letter AND qOH.paper.knownSize # legal THEN PSCommand.Error[[enqueue[mediumUnavailable]]]; END; PaperTypes.PaperMMDimension[a4].short => BEGIN --Paper width is for a4 paper. IF parms.paper = PaperTypesExtras.nullPaper THEN qOH.paper.knownSize _ a4; --Default to a4 if size not specified IF qOH.paper.knownSize # a4 THEN PSCommand.Error[[enqueue[mediumUnavailable]]]; END; ENDCASE => ERROR; --Paper width is other than letter/legal or a4??? IF parms.message # NSString.nullString THEN GetFaxDataFromString[parms.message, qOH] ELSE --If no message, do a local print. WITH q: qOH SELECT FROM fax495 => q.localPrintStatus _ queued; ENDCASE => ERROR; END; feps9700 => BEGIN IF parms.paper = PaperTypesExtras.nullPaper THEN qOH.paper.knownSize _ IF s.paperSupply.size1 # letter AND s.paperSupply.size2 # letter THEN s.paperSupply.size1 ELSE letter; IF qOH.paper.knownSize # s.paperSupply.size1 AND qOH.paper.knownSize # s.paperSupply.size2 THEN PSCommand.Error[[enqueue[mediumUnavailable]]]; END; fx3500 => BEGIN dStatus: MarkerControl.EngineSpecific _ markerProcs.status[].engine; WITH d: dStatus SELECT FROM fx3500 => BEGIN IF parms.paper = PaperTypesExtras.nullPaper THEN qOH.paper.knownSize _ IF d.paperSupply.size1 # a4 AND d.paperSupply.size2 # a4 THEN d.paperSupply.size1 ELSE a4; IF qOH.paper.knownSize # d.paperSupply.size1 AND qOH.paper.knownSize # d.paperSupply.size2 THEN PSCommand.Error[[enqueue[mediumUnavailable]]]; END; ENDCASE => ERROR; END; raven => BEGIN IF parms.paper = PaperTypesExtras.nullPaper THEN qOH.paper.knownSize _ IF s.paperSupply.size1 # letter AND s.paperSupply.size2 # letter THEN s.paperSupply.size1 ELSE letter; IF qOH.paper.knownSize # s.paperSupply.size1 AND qOH.paper.knownSize # s.paperSupply.size2 THEN PSCommand.Error[[enqueue[mediumUnavailable]]]; END; ENDCASE => ERROR; --unknown printing option? END; --CopyDocParametersToQueueObject ConvertSpoolControlError: PROCEDURE [sType: SpoolControl.ErrorTypes] RETURNS [error: PSCommand.ErrorRecord] = BEGIN RETURN [SELECT sType FROM busy => [enqueue[busySpooling]], spoolingDisabled => [enqueue[spoolingDisabled]], tooManyConnections => [enqueue[tooManyClients]], spoolFull => [enqueue[spoolingQueueFull]], ENDCASE => ERROR] END; --ConvertSpoolControlError CreateSpoolFile: PROCEDURE [docParameters: PSCommand.DocumentParameters] RETURNS [file: NSFile.Handle _ NSFile.nullHandle, qOH: PrintQueue.QueueObjectHandle _ PrintQueue.nilQueueObjectHandle] = BEGIN createFileError: PSCommand.ErrorRecord; BEGIN fileBytes: LONG CARDINAL; qOH _ PrintQueue.Requeue[fromQueue: inactive, toQueue: spooling]; qOH.currentStatus _ PrintQueue.ObjectStatus[spooling]; CopyDocParametersToQueueObject[qOH, docParameters ! PSCommand.Error => { IF state.spoolerTrace # none THEN PSAsyncMsg.PutMesaString[" **PSCommand.Error[[enqueue[mediumUnavailable]]]"L]; qOH.currentStatus _ PrintQueue.ObjectStatus[spoolFailure]; [] _ PrintQueue.Requeue[qOH: qOH, fromQueue: spooling, toQueue: aborted]; REJECT}]; fileBytes _ IF qOH.fileSize = 0 THEN 20 ELSE qOH.fileSize; [qOH.fileID, file] _ QueueFile.CreateTempFile[qOH.localFileName, fileBytes ! QueueFile.CreateError => {createFileError _ [enqueue[other]]; GOTO Error}; QueueFile.InsufficientPages => {createFileError _ [insufficientSpace[]]; GOTO Error};]; qOH.uid _ BasicTime.GetUniversalID[]; EXITS Error => BEGIN qOH.currentStatus _ PrintQueue.ObjectStatus[spoolFailure]; [] _ PrintQueue.Requeue[qOH: qOH, fromQueue: spooling, toQueue: aborted]; PSCommand.Error[createFileError]; END; END; END; --CreateSpoolFile GetFaxDataFromString: PROCEDURE [ string: NSString.String, qOH: PrintQueue.QueueObjectHandle] = BEGIN WITH q: qOH SELECT FROM fax495 => BEGIN endOfParse: BOOLEAN _ FALSE; startParseIndex, --index of string char where parsing should begin stopParseIndex, --index of string char where parsing should end (past last legal char) actualLength, --actual number of legal phone number chars found for a given phone number parseIndex, --current string char being looked at during parse phoneNos, --number of phone numbers found phoneNoIndex --index into queue object phone number array where next phone number goes : CARDINAL _ 0; chset: PrincOps.BYTE _ 0; char: NSString.Character; msgLength: CARDINAL _ string.length; chsetChangeMarker: PrincOps.BYTE = 377B; delimiter: NSString.Character = [0, 57B]; --slash char '/ blank: NSString.Character = [0, 40B]; comma: NSString.Character = [0, 54B]; letterL: NSString.Character = [0, 114B]; minActualLength: CARDINAL = 2; --min # of actual phone number chars allowed maxActualLength: CARDINAL = 27; --max # of actual phone number chars allowed EndOfParse: SIGNAL = CODE; ParseError: ERROR = CODE; ActualPhoneNoChar: PROC [c: NSString.Character] RETURNS [BOOLEAN] = BEGIN SELECT c FROM [0, 60B]--0--, [0, 61B]--1--, [0, 62B]--2--, [0, 63B]--3--, [0, 64B]--4--, [0, 65B]--5--, [0, 66B]--6--, [0, 67B]--7--, [0, 70B]--8--, [0, 71B]--9--, [0, 120B]--P--, [0, 52B]--*--, [0, 43B]--#-- => RETURN [TRUE]; ENDCASE => RETURN [FALSE]; END; --ActualPhoneNoChar GetNextChar: PROCEDURE RETURNS [NSString.Character] = BEGIN code: PrincOps.BYTE; ValidCharacter: PROC [c: NSString.Character] RETURNS [BOOLEAN] = BEGIN SELECT c FROM [0, 60B]--0--, [0, 61B]--1--, [0, 62B]--2--, [0, 63B]--3--, [0, 64B]--4--, [0, 65B]--5--, [0, 66B]--6--, [0, 67B]--7--, [0, 70B]--8--, [0, 71B]--9--, [0, 55B]--minus--, [0, 50B]--leftParen--, [0, 51B]--rightParen--, [0, 120B]--P--, [0, 52B]--*--, [0, 43B]--#--, [41B, 76B]--hyphen--, blank, comma, letterL => RETURN [TRUE]; ENDCASE => RETURN [FALSE]; END; --ValidCharacter IF parseIndex >= stopParseIndex THEN SIGNAL EndOfParse; code _ string.bytes[parseIndex]; IF code = chsetChangeMarker THEN BEGIN IF (parseIndex _ parseIndex + 1) >= msgLength THEN ERROR ParseError; chset _ string.bytes[parseIndex]; IF (parseIndex _ parseIndex + 1) >= msgLength THEN ERROR ParseError; code _ string.bytes[parseIndex]; END; parseIndex _ parseIndex + 1; IF NOT ValidCharacter[[chset, code]] THEN ERROR ParseError; RETURN[[chset, code]]; END; --GetNextChar LookForSinglePhoneNo: PROCEDURE = BEGIN chset _ parseIndex _ 0; stopParseIndex _ msgLength; q.localPrintStatus _ null; q.phoneNoCount _ 1; q.transmitData _ ALL[]; q.transmitData[0].status _ queued; q.transmitData[0].phoneNumber _ [ bytes: LOOPHOLE[@q.transmitData[0].phoneNumberBody], length: 0, maxlength: PrintQueue.maxPhoneNoLength]; actualLength _ 0; char _ GetNextChar[! EndOfParse, ParseError => GOTO localPrint]; UNTIL char = comma OR char = letterL --letter L no allowed in phone number OR q.transmitData[0].phoneNumber.length >= q.transmitData[0].phoneNumber.maxlength DO q.transmitData[0].phoneNumber _ NSString.AppendCharacter[q.transmitData[0].phoneNumber, char]; IF ActualPhoneNoChar[char] THEN actualLength _ actualLength + 1; char _ GetNextChar[! EndOfParse => IF actualLength < minActualLength OR actualLength > maxActualLength THEN GOTO localPrint ELSE GOTO finished; ParseError => GOTO localPrint]; ENDLOOP; IF actualLength < minActualLength OR actualLength > maxActualLength THEN GOTO localPrint; DO IF char # blank THEN GOTO localPrint; char _ GetNextChar[! EndOfParse => GOTO finished; ParseError => GOTO localPrint]; ENDLOOP; EXITS finished => NULL; localPrint => BEGIN q.localPrintStatus _ queued; q.phoneNoCount _ 0; q.transmitData _ ALL[]; END; END; --LookForSinglePhoneNo BEGIN IF msgLength = 0 THEN {q.localPrintStatus _ queued; GOTO done}; parseIndex _ NSString.ScanForCharacter[delimiter, string]; IF parseIndex = LAST[CARDINAL] THEN --no slash found GOTO lookForSinglePhoneNo; IF NOT NSString.EqualCharacter[delimiter, string, parseIndex + 1] THEN --second slash not found GOTO lookForSinglePhoneNo; startParseIndex _ parseIndex + 2; parseIndex _ NSString.ScanForCharacter[delimiter, string, startParseIndex]; IF parseIndex = LAST[CARDINAL] THEN --no slash found GOTO lookForSinglePhoneNo; IF NOT NSString.EqualCharacter[delimiter, string, parseIndex + 1] THEN --second slash not found GOTO lookForSinglePhoneNo; stopParseIndex _ parseIndex; parseIndex _ startParseIndex; DO --Look for leading blanks or commas and letter L for local print. char _ GetNextChar[! EndOfParse, ParseError => GOTO lookForSinglePhoneNo]; SELECT char FROM letterL => BEGIN q.localPrintStatus _ queued; <> char _ GetNextChar[! EndOfParse => GOTO done; ParseError => GOTO lookForSinglePhoneNo]; UNTIL char = comma DO IF char # blank THEN GOTO lookForSinglePhoneNo; char _ GetNextChar[! EndOfParse => GOTO done; ParseError => GOTO lookForSinglePhoneNo]; ENDLOOP; EXIT; END; blank, comma => LOOP; ENDCASE => EXIT; ENDLOOP; DO --Look for phone numbers. <> UNTIL char # blank AND char # comma DO char _ GetNextChar[! EndOfParse => IF q.localPrintStatus = queued OR q.phoneNoCount > 0 THEN GOTO done ELSE GOTO lookForSinglePhoneNo; ParseError => GOTO lookForSinglePhoneNo]; ENDLOOP; phoneNos _ phoneNos + 1; actualLength _ 0; <> UNTIL char = comma OR char = letterL --letter L is valid only as local print indicator at beginning of string. OR q.transmitData[phoneNoIndex].phoneNumber.length >= q.transmitData[phoneNoIndex].phoneNumber.maxlength DO q.transmitData[phoneNoIndex].phoneNumber _ NSString.AppendCharacter[q.transmitData[phoneNoIndex].phoneNumber, char]; IF ActualPhoneNoChar[char] THEN actualLength _ actualLength + 1; char _ GetNextChar[! EndOfParse => IF actualLength < minActualLength OR actualLength > maxActualLength THEN GOTO lookForSinglePhoneNo ELSE GOTO done; ParseError => GOTO lookForSinglePhoneNo]; ENDLOOP; phoneNoIndex _ phoneNoIndex + 1; IF actualLength < minActualLength OR actualLength > maxActualLength THEN GOTO lookForSinglePhoneNo; IF phoneNos >= PrintQueue.maxFaxPhoneNos THEN GOTO done; UNTIL char = comma DO --Char should be a comma (or a blank before comma) or else phone number to too long IF char # blank THEN GOTO lookForSinglePhoneNo; --Phone number was too long or an L was found. char _ GetNextChar[! EndOfParse => GOTO done; ParseError => GOTO lookForSinglePhoneNo]; ENDLOOP; ENDLOOP; EXITS done => IF phoneNos > 0 THEN BEGIN FOR i: CARDINAL IN [0..phoneNos) DO q.transmitData[i].status _ queued; ENDLOOP; q.phoneNoCount _ phoneNos; END; lookForSinglePhoneNo => LookForSinglePhoneNo[]; END; END; ENDCASE; END; --GetFaxDataFromString <> DisplayInitialSpoolInfo: PROCEDURE [qOH: PrintQueue.QueueObjectHandle] = BEGIN nsPrintRequest: NSString.String = Str["--Print Request by <1>"L]; nsFile: NSString.String = Str["--File: <1>"L]; PSAsyncMsg.Expand1AndPutString[nsPrintRequest, qOH.sender]; PSAsyncMsg.Expand1AndPutString[nsFile, qOH.fileName]; END; -- DisplayInitialSpoolInfo DisplayFinalSpoolInfo: PROCEDURE [qOH: PrintQueue.QueueObjectHandle, beginSpoolDate: BasicTime.GMT] = BEGIN nsComplete: NSString.String = Str["--File transfer took <1> seconds; completed: <2>"]; nsCopiesAndLength: NSString.String = Str["--Copies: <1>; BYTE Length: <2>"L]; stringArray: ARRAY [0..2) OF NSString.String; spoolTime: LONG CARDINAL _ BasicTime.SecondsSinceEpoch[qOH.fileQueuedDate] - BasicTime.SecondsSinceEpoch[beginSpoolDate]; sTime: LONG STRING _ [10]; sDate: LONG STRING _ [20]; sCopies: LONG STRING _ [10]; sLength: LONG STRING _ [15]; String.AppendLongDecimal[sTime, spoolTime]; stringArray[0] _ Str[sTime]; Time.Append[sDate, Time.Unpack[qOH.fileQueuedDate]]; stringArray[1] _ Str[sDate]; PSAsyncMsg.ExpandArrayAndPutString[nsComplete, DESCRIPTOR[stringArray]]; String.AppendDecimal[sCopies, qOH.numberCopies]; String.AppendLongDecimal[sLength, qOH.fileSize]; stringArray[0] _ Str[sCopies]; stringArray[1] _ Str[sLength]; PSAsyncMsg.ExpandArrayAndPutString[nsCopiesAndLength, DESCRIPTOR[stringArray]]; END; -- DisplayFinalSpoolInfo <<*********************************-->> <> DocumentStatusFromQObjStatus: PROCEDURE [qOH: PrintQueue.QueueObjectHandle] RETURNS [PSCommand.DocumentStatus] = BEGIN RETURN[SELECT qOH.currentStatus FROM restart => [pending[restart]], spooling => [pending[spooling]], spooled => [pending[spooled]], decomposing => [inProgress[decomposing]], decomposed => [inProgress[decomposed]], marking => [inProgress[marking]], printed => [completed[printed]], merging => [inProgress[merging]], merged => [inProgress[merged]], forwarding => [inProgress[forwarding]], forwarded => [completed[forwarded]], canceledInDecomposer => [canceled[canceledInDecomposer]], canceledInMarker => [canceled[canceledInMarker]], canceledInMerger => [canceled[canceledInMerger]], canceledInForwarder => [canceled[canceledInForwarder]], canceledInQueue => [canceled[canceledInQueue]], spoolFailure => [rejected[spoolFailure]], decomposeFailure => [aborted[decomposeFailure]], markFailure => [aborted[markFailure]], mergeFailure => [aborted[mergeFailure]], forwardFailure => [aborted[forwardFailure]], sysRestartInSpooler => [aborted[sysRestartInSpooler]], sysRestartInDecomposer => [aborted[sysRestartInDecomposer]], sysRestartInMarker => [aborted[sysRestartInMarker]], sysRestartInMerger => [aborted[sysRestartInMerger]], sysRestartInForwarder => [aborted[sysRestartInForwarder]], sysRestartInQueue => [aborted[sysRestartInQueue]], faxInProgress => [inProgress[faxStatus]], faxCompleted => [completed[faxStatus]], faxCanceled => [canceled[faxStatus]], faxAborted => [aborted[faxStatus]], ENDCASE => [unknown[]]]; END; --DocumentStatusFromQObjStatus IDFilterOk: PROCEDURE [filterID, qObjID: PSCommand.DocumentID] RETURNS [BOOLEAN] = BEGIN <> IF filterID = PSCommand.nullDocumentID THEN RETURN[TRUE] ELSE BEGIN IF filterID = qObjID THEN RETURN[TRUE] ELSE RETURN[FALSE]; END; END; --IDFilterOk ListQueueStage: PROCEDURE [ queueStage: PrintQueue.QueueStage, proc: PSCommand.DocumentProc, filter: QueueObjectFilter, scratchQOH: PrintQueue.QueueObjectHandle, scratchDocAttributes: PSCommand.DocumentAttributes, scratchFaxMitData: LONG DESCRIPTOR FOR ARRAY OF PSCommand.FaxTransmitData] RETURNS [continue: BOOLEAN _ TRUE] = BEGIN <> qOH, nextQOH: PrintQueue.QueueObjectHandle; CopyDocumentAttributes: PROCEDURE = BEGIN <> PrintQueue.CopyQueueObject[fromQOH: qOH, toQOH: scratchQOH]; SELECT scratchQOH.option FROM bansheeDl => scratchDocAttributes^ _ [optionDependent: bansheeDl[]]; d1 => scratchDocAttributes^ _ [optionDependent: d1[]]; fax295 => scratchDocAttributes^ _ [optionDependent: fax295[]]; fax495 => scratchDocAttributes^ _ [optionDependent: fax495[]]; feps9700 => scratchDocAttributes^ _ [optionDependent: feps9700[]]; fx3500 => scratchDocAttributes^ _ [optionDependent: fx3500[]]; raven => scratchDocAttributes^ _ [optionDependent: raven[]]; ENDCASE => ERROR; scratchDocAttributes.id _ scratchQOH.uid; scratchDocAttributes.name _ scratchQOH.fileName; scratchDocAttributes.sender _ scratchQOH.sender; scratchDocAttributes.recipient _ scratchQOH.recipient; scratchDocAttributes.errorMessage _ scratchQOH.errorMsg; scratchDocAttributes.status _ DocumentStatusFromQObjStatus[scratchQOH]; scratchDocAttributes.priority _ LOOPHOLE[scratchQOH.priority]; --PrintQueue.Priority = NSPrint.PriorityHint scratchDocAttributes.sourceSystemElement _ scratchQOH.sourceSystemElement; scratchDocAttributes.sizeInBytes _ scratchQOH.fileSize; scratchDocAttributes.pagesDecomposed _ scratchQOH.platesDecomposed; scratchDocAttributes.numberOfCopies _ scratchQOH.numberCopies; scratchDocAttributes.dateReceived _ scratchQOH.fileCreateDate; scratchDocAttributes.secondsInFormatter _ scratchQOH.decomposeTime; scratchDocAttributes.completionDate _ scratchQOH.completionDate; WITH q: scratchQOH SELECT FROM fax495 => --Copy fax specific data. WITH d: scratchDocAttributes SELECT FROM fax495 => BEGIN OPEN d.faxStatus; localPrint _ LOOPHOLE[q.localPrintStatus]; localPrintCompletionDate _ q.localPrintCompletionDate; phoneNumberCount _ q.phoneNoCount; FOR i: CARDINAL IN [0..q.phoneNoCount) DO scratchFaxMitData[i].phoneNumber _ q.transmitData[i].phoneNumber; scratchFaxMitData[i].transmit _ LOOPHOLE[q.transmitData[i].status]; scratchFaxMitData[i].retryCount _ q.transmitData[i].retryCount; scratchFaxMitData[i].willRetry _ q.transmitData[i].queuedForRetry; scratchFaxMitData[i].completionDate _ q.transmitData[i].completionDate; scratchFaxMitData[i].phoneCallElapsedTime _ q.transmitData[i].elapsedTime; scratchFaxMitData[i].errorCode _ q.transmitData[i].errorCode; ENDLOOP; transmitData _ DESCRIPTOR[BASE[scratchFaxMitData], q.phoneNoCount]; END; ENDCASE => ERROR; --Printing option types types disagree ENDCASE; END; --CopyDocumentAttributes qOH _ PrintQueue.Previous[fromQueue: queueStage]; --get last (i.e. newest) document from queue stage <> UNTIL qOH = PrintQueue.nilQueueObjectHandle DO nextQOH _ PrintQueue.Previous[qOH: qOH, fromQueue: queueStage]; --get next older doc from queue stage <> IF filter.status[qOH.currentStatus] --If the document has an acceptable queue object status-- THEN IF StringFilterOk[filter.sender, qOH.sender] THEN IF StringFilterOk[filter.name, qOH.fileName] THEN IF IDFilterOk[filter.id, qOH.uid] THEN BEGIN <> <> CopyDocumentAttributes[]; continue _ proc[scratchDocAttributes]; IF NOT continue THEN RETURN; END; qOH _ nextQOH; ENDLOOP; END; --ListQueueStage QObjFilterFromClientFilter: PROCEDURE [clientFilter: LONG POINTER TO PSCommand.DocumentFilter, qObjFilter: LONG POINTER TO QueueObjectFilter] = BEGIN qObjFilter.id _ clientFilter.id; qObjFilter.name _ clientFilter.name; qObjFilter.sender _ clientFilter.sender; qObjFilter.status _ ALL[FALSE]; FOR s: PSCommand.SimpleDocStatus IN PSCommand.SimpleDocStatus DO IF clientFilter.status[s] THEN SELECT s FROM pending => qObjFilter.status[restart] _ qObjFilter.status[spooling] _ qObjFilter.status[spooled] _ TRUE; inProgress => qObjFilter.status[decomposing] _ qObjFilter.status[decomposed] _ qObjFilter.status[marking] _ qObjFilter.status[merging] _ qObjFilter.status[merged] _ qObjFilter.status[forwarding] _ qObjFilter.status[faxInProgress] _ TRUE; completed => qObjFilter.status[printed] _ qObjFilter.status[forwarded] _ qObjFilter.status[faxCompleted] _ TRUE; completedWithWarnings => NULL; unknown => NULL; rejected => qObjFilter.status[spoolFailure] _ TRUE; aborted => qObjFilter.status[decomposeFailure] _ qObjFilter.status[markFailure] _ qObjFilter.status[mergeFailure] _ qObjFilter.status[forwardFailure] _ qObjFilter.status[sysRestartInSpooler] _ qObjFilter.status[sysRestartInDecomposer] _ qObjFilter.status[sysRestartInMarker] _ qObjFilter.status[sysRestartInMerger] _ qObjFilter.status[sysRestartInForwarder] _ qObjFilter.status[sysRestartInQueue] _ qObjFilter.status[faxAborted] _ TRUE; canceled => qObjFilter.status[canceledInQueue] _ qObjFilter.status[canceledInDecomposer] _ qObjFilter.status[canceledInMarker] _ qObjFilter.status[canceledInMerger] _ qObjFilter.status[canceledInForwarder] _ qObjFilter.status[faxCanceled] _ TRUE; held => NULL; ENDCASE; ENDLOOP; END; --QObjFilterFromClientFilter StringFilterOk: PROCEDURE [filterString, qObjString: NSString.String] RETURNS [BOOLEAN] = BEGIN <> IF filterString = nsNil THEN RETURN[TRUE] ELSE RETURN[NSString.EquivalentStrings[filterString, qObjString]]; END; --StringFilterOk <<*********************************-->> <> RequeueDecomposedDocs: PROCEDURE [fromQueue: PrintQueue.QueueStage] = BEGIN qOH: PrintQueue.QueueObjectHandle _ PrintQueue.Requeue[ fromQueue: fromQueue, toQueue: spooledNormal, position: front]; UNTIL qOH = PrintQueue.nilQueueObjectHandle DO IF qOH.printObjectHandle # NIL THEN DecomposerControl.FreeDecomposeObject[qOH.uid]; qOH.printObjectHandle _ NIL; qOH.currentStatus _ restart; qOH _ PrintQueue.Requeue[ fromQueue: fromQueue, toQueue: spooledNormal, position: front]; ENDLOOP; END; --RequeueDecomposedDocs StopPrintingInternal: PROCEDURE = BEGIN --retry all docs in progress <> <> IF state.option = feps9700 THEN BEGIN ForwardingControl.Stop[status: merged]; MergeControl.Stop[status: restart]; END ELSE markerProcs.stop[status: restart]; DecomposerControl.Stop[status: restart]; RequeueDecomposedDocs[fromQueue: retransmit]; RequeueDecomposedDocs[fromQueue: decomposed]; [] _ DecomposerControl.Stopped[wait]; IF state.option = feps9700 THEN BEGIN [] _ ForwardingControl.Stopped[wait]; [] _ MergeControl.Stopped[wait]; END ELSE [] _ markerProcs.stopped[wait]; END; --StopPrintingInternal Str: PROCEDURE [s: LONG STRING] RETURNS [ns: NSString.String] = INLINE BEGIN RETURN[NSString.StringFromMesaString[s]] END; END. --PSCommandAImpl LOG when/who/what ****EARLIER LOG ENTRIES DELETED. See archived version from 8.0. 6-Sep-84 12:58:10 - Jacks - Updated to 9.0 PS interfaces; removed code for aps5; added code for banshee, fax295 and feps9700. 20-Sep-84 13:49:31 - Jacks - Moved the waking up of a dozing raven to Enqueue from DecomposerControlImpl proc. 26-Oct-84 15:03:04 - Jacks - Added code for feps9700. 16-Nov-84 17:19:58 - Jacks - Updated to second round 9.0 interfaces; made use of MiscUtilities. 3-Dec-84 15:59:51 - Jacks - Added call to RotateFonts90 to StartPrinting. 15-Jan-85 15:25:13 - Jacks - Now save staple and twoSided options when present in NSPrint call (CopyPrintOptionsToQueueObject). 18-Jan-85 14:52:40 - Jacks - In StopPrintingInternal: now stop the decomposer before requeuing decomposed docs which eliminates a timing window which allowed an occasional document to end up on the decomposed queue when printing was stopped. 13-Feb-85 15:03:01 - Jacks - FOR 10.0: Removed this module's dependence on NSPrint. Now raise PSCommandExtras.ErrorX instead of NSPrint.Error. Implemented new EnqueueX proc, temporarily defined in PSCommandExtras. 28-Feb-85 10:09:23 - Jacks - Now call RotateFonts90 every time in StartPrinting if the engine is bansheeDl to check if any fonts need to be rotated. 12-Mar-85 11:20:02 - Jacks - Put call to GetFaxDataFromString into CopyDocParametersToQueueObject. 18-Jun-85 15:12:15 - Jacks - Added copyright notice; updated to PS Euclid interfaces. 26-Jun-85 9:55:55 - Jacks - Added d1 specific code to select stmts. 3-Jul-85 9:28:17 - Jacks - Got rid of fax canceled/aborted kludge. 19-Jul-85 11:31:56 - Jacks - Converted to XMessage and QueueFile; created CompleteEnqueue. 7-Aug-85 10:57:36 - Jacks - Updated to 10.0 DecomposerControl.FreeDecomposeObject; made use of NSFile.GetAttributesRecord. 15-Aug-85 16:46:48 - Jacks - Put in kludge for firstPageToPrint or lastPageToPrint = 0. 26-Aug-85 10:37:08 - Jacks - Made QueueObjectFilter status a PACKED ARRAY. 10-Sep-85 15:04:12 - Jacks - Got queueObject, documentAttrRecord and faxMitData out of local frame in ListQueueStage; ListDocuments temporarily exported by PSCommandExtras; default d1 and banshee paper size to what is currently loaded. 24-Sep-85 14:04:34 - Jacks - Put PSCommandExtras stuff into PSCommand. 15-Oct-85 9:41:06 - Jacks - Copy new fax errorCode in CopyDocumentAttributes; improved paper size defaulting in CopyDocParametersToQueueObject. 6-Nov-85 10:17:53 - Jacks - Catch DecomposerControl.DocumentInProgress in StartPrinting. 22-Apr-86 14:07:14 - Jacks - RequeueDecomposedDocs always requeues to front of spooledNormal queue. 1-May-86 17:11:26 - Jacks - Fixed space leak in ListDocuments by adding GOTO stmts. 11-Jun-86 14:03:22 - Jacks - Again fixed space leak in ListDocuments.