DunnImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, April 25, 1986 12:49:47 pm PST
DIRECTORY DicentraRS232CAsync, ColorTrixBasics, ColorTrixMap, Dunn, Imager, ImagerColorMap, ImagerSmooth, IO, InterminalBackdoor, Process, Rope, Terminal;
DunnImpl: CEDAR PROGRAM
IMPORTS DicentraRS232CAsync, ColorTrixBasics, ColorTrixMap, Imager, ImagerSmooth, IO, InterminalBackdoor, Process, Rope
EXPORTS Dunn
~ {
OPEN Dunn;
Double check abort code is working; eliminate timeouts. Cf: JamIDunn.df.
null:   CHAR ~ '\000;
defaultHost: Rope.ROPE ~ "York";
time:   RECORD [short, med, long: INT] ← [10, 60, 120];  -- timeouts in seconds
TOKEN:  TYPE = RECORD [ok: BOOL, ch: CHAR];
NYBBLE:  TYPE = MACHINE DEPENDENT RECORD [hibits: [0..17b], bit3, bit2, bit1, bit0: BOOL];
OpenFailed: PUBLIC ERROR = CODE;
InUse:   PUBLIC ERROR [user: Rope.ROPE] = CODE;
SnapperError: PUBLIC ERROR [msg: Rope.ROPE] ~ CODE;
Reserve: PUBLIC PROC RETURNS [handle: Handle ← NIL, errorMsg: Rope.ROPENIL] ~ {
open, sync, film, io : BOOLFALSE;
handle ← Open[!
OpenFailed => {errorMsg ← "Can't open Dunn. "; CONTINUE};
InUse => {
errorMsg ← Rope.Cat["Dunn in use by ", user.Substr[0, user.SkipTo[0, "+"]], ". "];
CONTINUE
}
];
IF errorMsg = NIL THEN {
[open, sync, film, io] ← Status[handle];
IF NOT open THEN errorMsg ← Rope.Concat[errorMsg, "Not opened. "];
IF NOT sync THEN errorMsg ← Rope.Concat[errorMsg, "No sync. "];
IF NOT film THEN errorMsg ← Rope.Concat[errorMsg, "No film. "];
IF NOT io  THEN errorMsg ← Rope.Concat[errorMsg, "IO error. "];
};
IF errorMsg # NIL THEN {
IF open THEN Close[handle];        -- refuse Dunn operations
handle ← NIL;
};
};
Pretend: PUBLIC PROC RETURNS [handle: Handle ← NEW[Dunn.HandleRep]] ~ {
handle.enable ← FALSE;
};
Open: PUBLIC PROC [host: Rope.ROPENIL] RETURNS [handle: Handle] ~ {
IF host = NIL THEN host ← defaultHost;
handle ← NEW [HandleRep];
handle.enable ← TRUE;
handle.stream ← DicentraRS232CAsync.CreateStream[host: host !
IO.Error, IO.EndOfStream => ERROR OpenFailed;
DicentraRS232CAsync.CommError => ERROR OpenFailed;
DicentraRS232CAsync.CommBusy => ERROR InUse[currentUser];
];
};
HandleOK: PUBLIC PROC [handle: Handle] RETURNS [BOOL] ~ {
RETURN[handle # NIL AND handle.stream # NIL];
};
HandleDisabled: PUBLIC PROC [handle: Handle] RETURNS [BOOL] ~ {
RETURN[handle # NIL AND NOT handle.enable];
};
Close: PUBLIC PROC [handle: Handle] ~ {
IF NOT HandleOK[handle] THEN RETURN;
IO.Flush[handle.stream];
IO.Close[handle.stream --, TRUE-- ];
handle.stream ← NIL;
};
ReadToken: PROC [h: Handle, timer: INT ← time.med] RETURNS [t: TOKEN ← [TRUE, null]] ~ {
waited: BOOLFALSE;
FOR i: INT ← 1, i+1 DO
IF i > timer THEN {
t.ok ← FALSE;
IF waited THEN h.debug.PutF["\n"];
RETURN
};
IF IO.CharsAvail[h.stream] # 0 THEN EXIT;
IF h.debug # NIL THEN {waited ← TRUE; h.debug.PutF["wait... "]};
Process.Pause[Process.SecondsToTicks[1]];
ENDLOOP;
IF waited THEN h.debug.PutF["\n"];
t.ch ← IO.GetChar[h.stream ! IO.EndOfStream => t.ok ← FALSE];
};
Status: PUBLIC PROC [handle: Handle] RETURNS [open, sync, film, io: BOOLTRUE] ~ {
Check: PROC RETURNS[BOOL] ~ {
IO.PutChar[handle.stream, LOOPHOLE[cmdCode[statusRequest], CHAR]];
IO.Flush[handle.stream];
t ← ReadToken[handle, time.short]; IF NOT t.ok THEN RETURN[FALSE];
n ← LOOPHOLE[t.ch, NYBBLE];
t ← ReadToken[handle, time.short]; IF NOT t.ok THEN RETURN[FALSE];
t ← ReadToken[handle, time.short]; IF NOT t.ok THEN RETURN[FALSE];
t ← ReadToken[handle, time.short]; IF NOT t.ok OR t.ch # '\n THEN RETURN[FALSE];
RETURN[TRUE];
};
t: TOKEN;
n: NYBBLE;
IF HandleDisabled[handle] THEN RETURN;
IF NOT HandleOK[handle] THEN RETURN[open: FALSE];
THROUGH [0..10] DO
IF Check[] THEN RETURN[sync: NOT n.bit0, film: NOT n.bit3];
IO.Flush[handle.stream];
IO.Reset[handle.stream];
ENDLOOP;
RETURN[io: FALSE];
};
Cmd: PUBLIC PROC [handle: Handle, cmd: cmdCode] RETURNS [BOOLTRUE] ~ {
Check: PROC RETURNS[BOOL] ~ {
IO.PutChar[handle.stream, LOOPHOLE[cmdCode[readyTest], CHAR]];
IO.Flush[handle.stream];
t ← ReadToken[handle]; IF NOT t.ok OR t.ch # 'R THEN RETURN[FALSE];
t ← ReadToken[handle]; IF NOT t.ok OR t.ch # '\n THEN RETURN[FALSE];
RETURN[TRUE];
};
t: TOKEN;
IF HandleDisabled[handle] THEN RETURN;
IF NOT Ready[handle] THEN RETURN[FALSE];
IO.PutChar[handle.stream, LOOPHOLE[cmd, CHAR]];       -- send command
THROUGH [0..10] DO
IF Check[] THEN RETURN[TRUE];
IO.Flush[handle.stream];
IO.Reset[handle.stream];
ENDLOOP;
RETURN[FALSE];
};
Status: PUBLIC PROC [handle: Handle] RETURNS [open, sync, film, io: BOOLTRUE] ~ {
n: NYBBLE;
IF HandleDisabled[handle] THEN RETURN;
IF NOT HandleOK[handle] THEN RETURN[open: FALSE];
IO.PutChar[handle.stream, LOOPHOLE[cmdCode[statusRequest], CHAR]];
IO.Flush[handle.stream];
n ← LOOPHOLE[IO.GetChar[handle.stream], NYBBLE];
[] ← IO.GetChar[handle.stream];
[] ← IO.GetChar[handle.stream];
IF IO.GetChar[handle.stream] # '\n THEN RETURN[io: FALSE];
RETURN[sync: NOT n.bit0, film: NOT n.bit3];
};
Ready: PUBLIC PROC [handle: Handle] RETURNS [BOOL] ~ {
IF HandleDisabled[handle] THEN RETURN[FALSE];
IO.PutChar[handle.stream, LOOPHOLE[cmdCode[readyTest], CHAR]];
IO.Flush[handle.stream];
IF IO.GetChar[handle.stream] # 'R THEN RETURN[FALSE];
RETURN[IO.GetChar[handle.stream] = '\n];
};
Cmd: PUBLIC PROC [handle: Handle, cmd: cmdCode] RETURNS [BOOL] ~ {
IF HandleDisabled[handle] THEN RETURN[TRUE];
IF NOT Ready[handle] THEN RETURN[FALSE];
IO.PutChar[handle.stream, LOOPHOLE[cmd, CHAR]];       -- send command
RETURN[TRUE];
};
Expose: PUBLIC PROC [handle: Handle] RETURNS [BOOL] ~ {
RETURN Cmd[handle, exposeSeq]
};
Composite: PUBLIC PROC [handle: Handle] RETURNS [BOOL] ~ {
RETURN [Cmd[handle, selectNrmSeqMode]]
};
Separate: PUBLIC PROC [handle: Handle] RETURNS [BOOL] ~ {
RETURN [Cmd[handle, selectSepSeqMode]]
};
Color: PUBLIC PROC [handle: Handle] RETURNS [BOOL] ~ {
RETURN [Cmd[handle, selectColor]]
};
BW: PUBLIC PROC [handle: Handle] RETURNS [BOOL] ~ {
RETURN [Cmd[handle, selectBW]]
};
Reset: PUBLIC PROC [handle: Handle] RETURNS [BOOL] ~ {
RETURN[
Cmd[handle, restoreFilterWheel] AND
Cmd[handle, closeAuxShutter] AND
Composite[handle] AND
Color[handle]];
};
DebugOff: PUBLIC PROC [handle: Handle] ~ {
IF handle # NIL THEN handle.debug ← NIL;
};
DebugOn: PUBLIC PROC [handle: Handle, stream: IO.STREAM] ~ {
IF handle # NIL THEN handle.debug ← stream;
};
Enable: PUBLIC PROC [handle: Handle] ~ {
IF handle # NIL THEN handle.enable ← TRUE;
};
Disable: PUBLIC PROC [handle: Handle] ~ {
IF handle # NIL THEN handle.enable ← FALSE;
};
colorAtom: ARRAY ImagerColorMap.Gun OF ATOM ~ [$Red, $Green, $Blue];
Snapper: PUBLIC PROC [action: PROC[Imager.Context], pixelUnits: BOOLFALSE,
color: BOOLTRUE, smooth: BOOLTRUE] ~ {
err: Rope.ROPE;
handle: Dunn.Handle;
vt: Terminal.Virtual ← InterminalBackdoor.terminal;
cd: Imager.Context ~ IF smooth OR color
THEN ColorTrixBasics.InitCd[smooth, pixelUnits, FALSE]
ELSE ColorTrixBasics.InitCd[gray, pixelUnits, FALSE];
DrawAndExpose: PROC ~ {
saveAction: PROC ~ {action[cd]};
IF color THEN {
IF NOT Separate[handle] THEN ERROR SnapperError["Dunn mode failure."];
FOR gun: ImagerColorMap.Gun IN ImagerColorMap.Gun DO
ImagerSmooth.SetComponent[cd, colorAtom[gun]];
ColorTrixBasics.ClearVt[vt, 255];
Process.CheckForAbort[];
ColorTrixMap.PrimaryOnly[gun];
Imager.DoSaveAll[cd, saveAction];
IF NOT Expose[handle] THEN ERROR SnapperError["Dunn expose failure."];
ENDLOOP;
}
ELSE {
ColorTrixBasics.ClearVt[vt, 255];
Process.CheckForAbort[];
Imager.DoSaveAll[cd, saveAction];
IF NOT Expose[handle] THEN ERROR SnapperError["Dunn expose failure."];
};
};
[handle, err] ← Reserve[];
IF err # NIL THEN ERROR SnapperError[Rope.Concat[err, "Dunn not reserved."]];
DrawAndExpose[ ! UNWIND => {Close[handle]}];
Close[handle];
};
}.