DunnImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, January 30, 1987 11:45:26 pm PST
DIRECTORY DicentraRS232CAsync, ColorTrixBasics, ColorTrixMap, Dunn, Imager, ImagerColorMap, ImagerSmooth, IO, InterminalBackdoor, MessageWindow, Process, Rope, Terminal, ThisMachine;
DunnImpl: CEDAR PROGRAM
IMPORTS DicentraRS232CAsync, ColorTrixBasics, ColorTrixMap, Imager, ImagerSmooth, IO, InterminalBackdoor, MessageWindow, Process, Rope, ThisMachine 
EXPORTS Dunn
~ BEGIN
OPEN Dunn;
null:    CHAR ~ '\000;
defaultHost:  ROPE ~ "York";
defaultDisplay: ROPE ~ "Reprisal";
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] = CODE;
SnapperError:  PUBLIC ERROR [msg: ROPE] ~ CODE;
Simulate: PUBLIC PROC RETURNS [Handle] ~ {
RETURN[NEW[HandleRec ← [simulate: FALSE]]];
};
Open: PUBLIC PROC [host, display: ROPENIL] RETURNS [handle: Handle] ~ {
IF host = NIL THEN host ← defaultHost;
IF display = NIL THEN display ← defaultDisplay;
handle ← NEW [HandleRec];
IF Rope.Equal[ThisMachine.Name[], display, FALSE] THEN {
MessageWindow.Append[" Opening connection.."];
handle.simulate ← FALSE;
handle.stream ← DicentraRS232CAsync.CreateStream[host: host !
IO.Error, IO.EndOfStream => ERROR OpenFailed;
DicentraRS232CAsync.CommError => ERROR OpenFailed;
DicentraRS232CAsync.CommBusy => ERROR InUse[currentUser];
];
MessageWindow.Append[" Open"];
}
ELSE {
handle.simulate ← TRUE;
MessageWindow.Append[" Simulation"];
};
};
Close: PUBLIC PROC [handle: Handle] ~ {
IF NOT handle.simulate THEN {
MessageWindow.Append[" Closing"];
IO.Flush[handle.stream];
IO.Close[handle.stream];
};
MessageWindow.Append[" Done"];
};
Cmd: PUBLIC PROC [handle: Handle, cmd: cmdCode] RETURNS [BOOL] ~ {
IF NOT handle.simulate THEN {
IO.PutChar[handle.stream, LOOPHOLE[cmd, CHAR]];
IO.Flush[handle.stream];
RETURN[CheckReady[handle.stream]];
};
RETURN[TRUE];
};
CheckReady: PROC [s: STREAM] RETURNS [ok: BOOLTRUE] ~ {
IO.PutChar[s, LOOPHOLE[cmdCode[readyTest], CHAR]];
IO.Flush[s];
IF IO.GetChar[s] # 'R THEN {
MessageWindow.Append[" Not Ready"];
RETURN [FALSE];
};
IF IO.GetChar[s] # '\n THEN {
MessageWindow.Append[" Not OK"];
RETURN [FALSE];
};
};
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]];
};
colorAtom: ARRAY ImagerColorMap.Gun OF ATOM ~ [$Red, $Green, $Blue];
Snapper: PUBLIC PROC [action: PROC[Context], pixelUnits: BOOLFALSE,
color: BOOLTRUE, smooth: BOOLTRUE] ~ {
handle: Handle;
vt: Terminal.Virtual ← InterminalBackdoor.terminal;
cd: 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 ← Open[];
DrawAndExpose[ ! UNWIND => {Close[handle]}];
Close[handle];
};
END.
..
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];
};
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];
};
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];
};
Reserve: PUBLIC PROC RETURNS [handle: Handle ← NIL, errorMsg: 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;
};
};
DebugOff: PUBLIC PROC [handle: Handle] ~ {
IF handle # NIL THEN handle.debug ← NIL;
};
DebugOn: PUBLIC PROC [handle: Handle, stream: 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;
};