-- PrintStatus.mesa; edited by Johnsson, August 26, 1980 8:16 AM
-- converted to Laurel by Ken Pier, 23-Jul-81 15:25:53
-- last Edited by Ken Pier, September 2, 1981 5:22 PM

DIRECTORY
Ascii USING [CR, SP],
IODefs USING [WriteChar, WriteLine, WriteString],
PrintDefs USING [printerName, PError],
PupDefs USING [
GetFreePupBuffer, GetPupAddress, GetPupContentsBytes, PupAddress, PupBuffer,
PupNameTrouble, PupSocket, PupSocketDestroy, PupSocketID, PupSocketMake,
ReturnFreePupBuffer, SecondsToTocks, SetPupContentsBytes],
PupTypes USING [fillInSocketID, PupSocketID, PupType],
Storage USING [CopyString],
String USING [AppendChar, EqualStrings];

PrintStatus: PROGRAM
IMPORTS IODefs, PrintDefs, PupDefs, Storage, String EXPORTS PrintDefs =
BEGIN

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
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;
END;

GetStatus: PUBLIC PROCEDURE RETURNS [BOOLEAN] =
BEGIN OPEN PupDefs;
a, b: PupBuffer;
available: BOOLEAN ← TRUE;
socket: PupSocket;
remote: PupAddress;
remote.socket ← statusSocket;
IF PrintDefs.printerName = NIL THEN PrintDefs.PError[UserCmMixup];
GetPupAddress[
@remote, PrintDefs.printerName !
PupNameTrouble => {IODefs.WriteLine[e]; 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 {
IODefs.WriteString["No response from "L];
IODefs.WriteLine[PrintDefs.printerName]}
ELSE {
c: CHARACTER;
available ← a.pupWords[0] # 1;
FOR i: CARDINAL IN [2..GetPupContentsBytes[a]) DO
IODefs.WriteChar[c ← a.pupChars[i]]; ENDLOOP;
IF c # Ascii.CR THEN IODefs.WriteChar[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]; PupDefs.PupSocketDestroy[socket];
RETURN[available];
EXITS Fail => RETURN[FALSE];
END;

Capability: TYPE = {id, instance, duplex, color, mailbox};

printerCapabilities: ARRAY Capability OF BOOLEAN ← ALL[FALSE];
jobID: STRING ← NIL;

ParseProperties: PROCEDURE [p: 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 jobID ← Storage.CopyString[value]
ELSE printerCapabilities[j] ← value[0] = ’T;
EXIT};
ENDLOOP;
ENDLOOP;
END;

NullRequeue: PROCEDURE [UNSPECIFIED] = {};


END...