-- PrintStatus.mesa; edited by Johnsson, 17-Apr-81 9:16:01
-- edited by Paul Rovner, 6-Jan-82 19:13:18
-- edited by Warren Teitelman, 8-Mar-82 13:11:53
DIRECTORY
Ascii USING [CR, SP],
IO USING [char, rope, string, Put, PutRope, PutChar],
LongString USING [AppendString],
LongStorage USING [CopyString, FreeString],
PrintOps USING [printerName, out],
PupDefs USING [
GetFreePupBuffer, GetPupAddress, GetPupContentsBytes, PupAddress, PupBuffer,
PupNameTrouble, PupPackageMake, PupSocket, PupSocketID, PupSocketMake,
ReturnFreePupBuffer, SecondsToTocks, SetPupContentsBytes],
PupTypes USING [fillInSocketID, PupSocketID, PupType],
String USING [AppendChar, EqualStrings]
;
PrintStatus: PROGRAM
IMPORTS LongString, LongStorage, PrintOps, PupDefs, String, IO
EXPORTS PrintOps =
BEGIN OPEN IO;
printerStatusSocket: CARDINAL = 21B;
printerStatusRequest: PupTypes.PupType = LOOPHOLE[200B];
printerStatusReply: PupTypes.PupType = LOOPHOLE[201B];
printerCapabilityRequest: PupTypes.PupType = LOOPHOLE[202B];
printerCapabilityReply: PupTypes.PupType = LOOPHOLE[203B];
printerJobStatusRequest: PupTypes.PupType = LOOPHOLE[204B];
printerJobStatusReply: PupTypes.PupType = LOOPHOLE[205B];
statusSocket: PupDefs.PupSocketID = [0, printerStatusSocket];
havePrinter: BOOLEAN ← FALSE;
Ask: PROCEDURE [
printer: PupDefs.PupSocket, q: PupDefs.PupBuffer, atype: PupTypes.PupType]
RETURNS [a: PupDefs.PupBuffer] =
BEGIN
THROUGH [0..2) DO
printer.put[q];
DO
a ← printer.get[];
IF a = NIL THEN EXIT;
IF a.pupType = atype AND a.pupID = q.pupID THEN RETURN;
PupDefs.ReturnFreePupBuffer[a];
ENDLOOP;
ENDLOOP;
END;
GetStatus: PUBLIC PROCEDURE RETURNS [BOOLEAN] =
BEGIN OPEN PupDefs;
a, b: PupBuffer;
available: BOOLEAN ← TRUE;
socket: PupSocket;
remote: PupAddress;
printerName: STRING = [40];
remote.socket ← statusSocket;
IF PrintOps.printerName = NIL OR PrintOps.printerName.length = 0 THEN
{PrintOps.out.PutRope["No printer host name!"]; GOTO Fail};
PupPackageMake[];
LongString.AppendString[printerName, PrintOps.printerName];
GetPupAddress[
@remote, printerName !
PupNameTrouble => {PrintOps.out.Put[string[e], char['\n]];
GOTO Fail}];
socket ← PupSocketMake[PupTypes.fillInSocketID, remote, SecondsToTocks[1]];
b ← GetFreePupBuffer[];
b.requeueProcedure ← NullRequeue;
b.pupType ← printerStatusRequest;
SetPupContentsBytes[b, 0];
a ← Ask[socket, b, printerStatusReply];
IF a = NIL THEN PrintOps.out.Put[rope["No response from "], string[printerName], char['\n]]
ELSE {
c: CHARACTER;
available ← a.pupWords[0] # 1;
FOR i: CARDINAL IN [2..GetPupContentsBytes[a]) DO
PrintOps.out.PutChar[c ← a.pupChars[i]]; ENDLOOP;
IF c # Ascii.CR THEN PrintOps.out.PutChar[Ascii.CR];
ReturnFreePupBuffer[a];
IF available THEN {
b.pupType ← printerCapabilityRequest;
a ← Ask[socket, b, printerCapabilityReply];
IF a # NIL THEN
{ParseProperties[@a.pupChars]; ReturnFreePupBuffer[a]}}};
ReturnFreePupBuffer[b];
RETURN[available];
EXITS Fail => RETURN[FALSE];
END;
Capability: TYPE = {id, instance, duplex, color, mailbox};
printerCapabilities: ARRAY Capability OF BOOLEAN ← ALL[FALSE];
jobID: LONG STRING ← NIL;
ParseProperties: PROCEDURE [p: LONG POINTER TO PACKED ARRAY [0..0) OF CHARACTER] =
BEGIN OPEN String;
capabilityStrings: ARRAY Capability OF STRING =
["ID"L, "PRINT-INSTANCE"L, "DUPLEX"L, "COLOR"L, "MAILBOX"L];
property: STRING = [40];
value: STRING = [40];
i: CARDINAL ← 1;
DO
IF p[i] = '( THEN i ← i + 1 ELSE EXIT;
property.length ← value.length ← 0;
WHILE p[i] # Ascii.SP DO AppendChar[property, p[i]]; i ← i + 1 ENDLOOP;
i ← i + 1;
WHILE p[i] # ') DO AppendChar[value, p[i]]; i ← i + 1 ENDLOOP;
i ← i + 1;
FOR j: Capability IN Capability DO
IF EqualStrings[property, capabilityStrings[j]] THEN{
IF j = id THEN {LongStorage.FreeString[jobID]; jobID ← LongStorage.CopyString[value]}
ELSE printerCapabilities[j] ← value[0] = 'T;
EXIT};
ENDLOOP;
ENDLOOP;
END;
NullRequeue: PROCEDURE [LONG POINTER] = {};
END...