-- 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...