DunnToolImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, January 30, 1987 8:52:08 pm PST
DIRECTORY
Dunn, ChoiceButtons, Commander, CommandTool, Containers, Convert, IO, Menus,
MessageWindow, Rope, ViewerClasses, ViewerEvents, ViewerOps, ViewerTools;
DunnToolImpl: CEDAR PROGRAM
IMPORTS Dunn, ChoiceButtons, Commander, CommandTool, Containers, Convert, IO, Menus, MessageWindow, Rope, ViewerEvents, ViewerOps, ViewerTools
~ BEGIN
viewerOpened:  BOOLFALSE;         -- viewer takes precedence
cmdData:    Data;            -- inter-command continuity
Data: TYPE ~ RECORD[
handle:   Dunn.Handle ← NIL,       -- hardware handle
dubNum:   INT ← 1,            -- exposure dub number
work:    REF Toggler,          -- enable/disable toggle
mode:    REF Toggler,          -- sep/cmp toggle
type:    REF Toggler,          -- bw/color toggle
dub:    REF ChoiceButtons.PromptDataRec,   -- dub text prompt
cmd:    REF ChoiceButtons.PromptDataRec,   -- cmd text prompt
printStream:  IO.STREAM ← NIL,        -- error messages
destroyEvent: ViewerEvents.EventRegistration ← NIL  -- release Dunn upon Destroy
];
Toggler: TYPE ~ RECORD[       -- used by MakeToggle, ResetToggle & Toggle
viewer: ViewerClasses.Viewer,       -- viewer for menu
entry1: Menus.MenuEntry,        -- first menu entry
entry2: Menus.MenuEntry,        -- second menu entry
name1: Rope.ROPE,          -- first menu entry name
name2: Rope.ROPE,          -- second menu entry name
data:  REF ANY           -- client data
];
Err: PROC [rope: Rope.ROPE] ~ {
IF viewerOpened
THEN {
MessageWindow.Append[Rope.Concat["\t", rope], TRUE];
MessageWindow.Blink[];
}
ELSE IF cmdData.printStream # NIL THEN cmdData.printStream.PutF[rope];
};
MakeEntry: PUBLIC PROC [menu: Menus.Menu,
name: Rope.ROPE,
proc: Menus.ClickProc,
data: REF ANY] ~ {
Menus.AppendMenuEntry[
menu,
Menus.CreateEntry[name: name, proc: proc, clientData: data, fork: FALSE]];
};
MakeToggle: PUBLIC PROC [
viewer: ViewerClasses.Viewer,
rope1:  Rope.ROPE,
rope2:  Rope.ROPE,
proc1:  Menus.ClickProc,
proc2:  Menus.ClickProc,
data:  REF ANYNIL]
RETURNS [tog: REF Toggler ← NEW[Toggler]] ~ {
tog.viewer ← viewer;
tog.entry1 ← Menus.CreateEntry[name: tog.name1 ← rope1, proc: proc2, clientData: data];
tog.entry2 ← Menus.CreateEntry[name: tog.name2 ← rope2, proc: proc1, clientData: data];
tog.data ← data;
Menus.AppendMenuEntry[viewer.menu, tog.entry1];
};
ExchangeMenuEntries: PUBLIC PROC [
v: ViewerClasses.Viewer,
ent1, ent2: Menus.MenuEntry] ~ {
OPEN Menus;
ok: BOOLTRUE;
ReplaceMenuEntry[v.menu, ent1, ent2 ! targetNotFound => {ok ← FALSE; CONTINUE}];
IF ~ok THEN ReplaceMenuEntry[v.menu, ent2, ent1 ! targetNotFound => CONTINUE];
ViewerOps.PaintViewer[v, menu];
};
Toggle: PUBLIC PROC [t: REF Toggler] ~ {
ExchangeMenuEntries[t.viewer, t.entry1, t.entry2];
};
ResetToggle: PUBLIC PROC [tog: REF Toggler] ~ {
IF Menus.FindEntry[tog.viewer.menu, tog.name1] = NIL THEN Toggle[tog];
};
DunnViewer: PROC [handle: Dunn.Handle] RETURNS [BOOL] ~ {
viewer: ViewerClasses.Viewer;          -- main viewer
menu: Menus.Menu ← Menus.CreateMenu[];     -- main menu
data: REF Data ← NEW[Data];          -- client data for main menu
IF ~Dunn.HandleOK[handle] AND ~Dunn.HandleDisabled[handle] THEN RETURN[FALSE];
viewer ← Containers.Create[          -- first establish viewer
info: [
name: "Dunn",
openHeight: 63,
menu: menu,
iconic: TRUE,
column: right,
scrollable: FALSE],
paint: FALSE];
MakeEntry[viewer.menu, "Expose ", ExposeProc, data];
MakeEntry[viewer.menu, " Reset ", ResetProc, data];
data.work ← MakeToggle[viewer, "Enabled ", "Disabled", EnblProc, DsblProc, data];
data.type ← MakeToggle[viewer, "Color", " BW ", ColorProc, BWProc, data];
data.mode ← MakeToggle[viewer, "Composite", "Separate", CompProc, SepProc, data];
MakeEntry[viewer.menu, "Send-cmd", CmdProc, data];
data.dub ← ChoiceButtons.BuildTextPrompt[viewer: viewer, y: 0, title: "Dub: ", default: "1"];
data.cmd ← ChoiceButtons.BuildTextPrompt[viewer: viewer, y: 17, title: "Command: "];
data.destroyEvent ← ViewerEvents.RegisterEventProc[proc: Destroy, event: destroy];
data.handle ← handle;
IF ~handle.enable THEN Toggle[data.work];
ViewerOps.AddProp[viewer, $DunnToolViewer, data];
ViewerOps.OpenIcon[viewer];
RETURN[TRUE];
};
Destroy: ViewerEvents.EventProc ~ {
data: REF Data ← NARROW[ViewerOps.FetchProp[viewer, $DunnToolViewer]];
IF data = NIL THEN RETURN;
ViewerEvents.UnRegisterEventProc[proc: data.destroyEvent, event: destroy];
viewerOpened ← FALSE;
Dunn.Close[data.handle];
};
SetScannerSelection: PROC [viewer: ViewerClasses.Viewer, nullify: BOOL] ~ {
MessageWindow.Clear[];
IF nullify THEN ViewerTools.SetContents[viewer, ""];
ViewerTools.SetSelection[viewer];
};
GetData: PROC [clientData: REF ANY] RETURNS [REF Data] ~ {
MessageWindow.Clear[];
RETURN[NARROW[clientData]];
};
GetHandle: PROC [clientData: REF ANY] RETURNS [Dunn.Handle] ~ {
RETURN[GetData[clientData].handle];
};
ColorProc: Menus.ClickProc ~ {
IF ~Dunn.Color[GetHandle[clientData]] THEN Err["Color failed"]
ELSE Toggle[GetData[clientData].type];
};
BWProc: Menus.ClickProc ~ {
IF ~Dunn.BW[GetHandle[clientData]] THEN Err["BW failed"]
ELSE Toggle[GetData[clientData].type];
};
CompProc: Menus.ClickProc ~ {
IF ~Dunn.Composite[GetHandle[clientData]] THEN Err["Composite failed"]
ELSE Toggle[GetData[clientData].mode];
};
SepProc: Menus.ClickProc ~ {
IF ~Dunn.Separate[GetHandle[clientData]] THEN Err["Separate failed"]
ELSE Toggle[GetData[clientData].mode];
};
QuitProc: Menus.ClickProc ~ {
ViewerOps.DestroyViewer[NARROW[parent, ViewerClasses.Viewer]];
};
DsblProc: Menus.ClickProc ~ {
data: REF Data ← NARROW[clientData];
IF Dunn.HandleDisabled[data.handle] THEN RETURN;
data.handle.enable ← FALSE;
Toggle[data.work];
};
EnblProc: Menus.ClickProc ~ {
temp: Dunn.Handle;
data: REF Data ← NARROW[clientData];
IF ~Dunn.HandleOK[data.handle] THEN {
temp ← MsgReserve[];
IF Dunn.HandleOK[temp] THEN data.handle ← temp;
};
IF Dunn.HandleOK[data.handle] THEN {
data.handle.enable ← TRUE;
Toggle[data.work];
};
};
Enable: PROC RETURNS [handle: Dunn.Handle] ~ {
handle ← IF Dunn.HandleOK[cmdData.handle]
THEN cmdData.handle
ELSE MsgReserve[];
IF handle # NIL THEN handle.enable ← TRUE;
};
Disable: PROC RETURNS [handle: Dunn.Handle] ~ {
handle ← IF cmdData.handle # NIL
THEN cmdData.handle
ELSE NEW[Dunn.HandleRep];
handle.enable ← FALSE;
};
MsgReserve: PROC RETURNS [handle: Dunn.Handle] ~ {
msg: Rope.ROPE;
[handle, msg] ← Dunn.Reserve[];
IF msg # NIL THEN Err[Rope.Concat[msg, "Dunn not reserved.\n"]];
};
UpdateDubNum: PROC [data: REF Data] RETURNS [ok: BOOLTRUE] ~ {
num: INT;
selection: Rope.ROPE ← ViewerTools.GetContents[data.dub.textViewer];
IF selection.IsEmpty[] THEN {Err["Enter dub number"]; RETURN[FALSE]};
num ← Convert.IntFromRope[selection ! Convert.Error => {ok ← FALSE; CONTINUE }];
IF ~ok THEN Err[Rope.Concat["Bad dub number: ", selection]]
ELSE data.dubNum ← num;
};
ExposeProc: Menus.ClickProc ~ {
data: REF Data ← GetData[clientData];
IF UpdateDubNum[data] THEN FOR i: INT IN [0..data.dubNum) DO
MessageWindow.Append[IO.PutFR["\tExposing frame %g/%g",
IO.int[i+1], IO.int[data.dubNum]], TRUE];
IF ~Dunn.Expose[data.handle] THEN {
Err[Rope.Concat["Expose failed at frame ", Convert.RopeFromInt[i]]];
EXIT;
};
REPEAT FINISHED => MessageWindow.Append["\tExposure done", TRUE];
ENDLOOP;
};
ResetProc: Menus.ClickProc ~ {
data: REF Data ← GetData[clientData];
IF ~Dunn.Reset[data.handle] THEN Err["Reset failed"];
ResetToggle[data.mode];
ResetToggle[data.type];
ViewerTools.SetContents[data.dub.textViewer, "1"];
[] ← UpdateDubNum[data];
};
CmdProc: Menus.ClickProc ~ {
data: REF Data ← GetData[clientData];
selection: Rope.ROPE ← ViewerTools.GetContents[data.cmd.textViewer];
IF selection.IsEmpty[] THEN Err["Enter a command"]
ELSE DunnRopeCommand[data.handle, selection];
};
DunnRopeCommand: PROC [h: Dunn.Handle, rope: Rope.ROPE] ~ {
OPEN Dunn;
ok: BOOLTRUE;
Test: PROC [x: Rope.ROPE] RETURNS [BOOL] ~ {RETURN[rope.Equal[x, FALSE]]};
SELECT TRUE FROM
Test["videoInvertHigh"] =>   ok ← Cmd[h, cmdCode.videoInvertHigh];
Test["videoInvertLow"] =>   ok ← Cmd[h, cmdCode.videoInvertLow];
Test["readyTest"] =>     ok ← Cmd[h, cmdCode.readyTest];
Test["statusRequest"] =>    ok ← Cmd[h, cmdCode.statusRequest];
Test["expose8x5TimeReq"] =>  ok ← Cmd[h, cmdCode.expose8x5TimeReq];
Test["exposeAuxTimeReq"] =>  ok ← Cmd[h, cmdCode.exposeAuxTimeReq];
Test["exposeAdjFactorReq"] =>  ok ← Cmd[h, cmdCode.exposeAdjFactorReq];
Test["advAuxFrameCnt"] =>   ok ← Cmd[h, cmdCode.advAuxFrameCnt];
Test["reset8x10ExposeStat"] =>  ok ← Cmd[h, cmdCode.reset8x10ExposeStat];
Test["restoreFilterWheel"] =>   ok ← Cmd[h, cmdCode.restoreFilterWheel];
Test["recovDefaultVals"] =>   ok ← Cmd[h, cmdCode.recovDefaultVals];
Test["select8x10Mode"] =>    ok ← Cmd[h, cmdCode.select8x10Mode];
Test["selectAuxMode"] =>    ok ← Cmd[h, cmdCode.selectAuxMode];
Test["selectBW"] =>     ok ← Cmd[h, cmdCode.selectBW];
Test["selectColor"] =>     ok ← Cmd[h, cmdCode.selectColor];
Test["selectNrmSeqMode"] =>   ok ← Cmd[h, cmdCode.selectNrmSeqMode];
Test["selectSepSeqMode"] =>   ok ← Cmd[h, cmdCode.selectSepSeqMode];
Test["exposeSeq"] =>     ok ← Cmd[h, cmdCode.exposeSeq];
Test["selectVidAndExpose"] =>  ok ← Cmd[h, cmdCode.selectVidAndExpose];
Test["set8x10ExposeTimes"] =>   ok ← Cmd[h, cmdCode.set8x10ExposeTimes];
Test["setAuxExposeTimes"] =>   ok ← Cmd[h, cmdCode.setAuxExposeTimes];
Test["setExposeAdjFactors"] =>  ok ← Cmd[h, cmdCode.setExposeAdjFactors];
Test["openAuxShutter"] =>   ok ← Cmd[h, cmdCode.openAuxShutter];
Test["closeAuxShutter"] =>   ok ← Cmd[h, cmdCode.closeAuxShutter];
Test["unblankMonitor"] =>   ok ← Cmd[h, cmdCode.unblankMonitor];
Test["blankMonitor"] =>    ok ← Cmd[h, cmdCode.blankMonitor];
Test["selectVideoChannel"] =>  ok ← Cmd[h, cmdCode.selectVideoChannel];
Test["positionFilterWheel"] =>  ok ← Cmd[h, cmdCode.positionFilterWheel];
Test["immExposeNoVidSw"] =>  ok ← Cmd[h, cmdCode.immExposeNoVidSw];
Test["yAxisRasterCompOn"] =>  ok ← Cmd[h, cmdCode.yAxisRasterCompOn];
Test["yAxisRasterCompOff"] => ok ← Cmd[h, cmdCode.yAxisRasterCompOff];
Test["clearYAxisOffset"] =>   ok ← Cmd[h, cmdCode.clearYAxisOffset];
Test["stepYAxisOffset"] =>    ok ← Cmd[h, cmdCode.stepYAxisOffset];
Test["clearXAxisOffset"] =>   ok ← Cmd[h, cmdCode.clearXAxisOffset];
Test["stepXAxisOffset"] =>    ok ← Cmd[h, cmdCode.stepXAxisOffset];
Test["select35mmAuxCam"] =>  ok ← Cmd[h, cmdCode.select35mmAuxCam];
Test["select16mmAuxCam"] =>  ok ← Cmd[h, cmdCode.select16mmAuxCam];
Test["select4x5AuxCam"] =>   ok ← Cmd[h, cmdCode.select4x5AuxCam];
Test["selectSX70AuxCam"] =>   ok ← Cmd[h, cmdCode.selectSX70AuxCam];
Test["setNumPadChars"] =>   ok ← Cmd[h, cmdCode.setNumPadChars];
Test["resetAuxNoFilmStats"] => ok ← Cmd[h, cmdCode.resetAuxNoFilmStats];
Test["fastOn"] =>      ok ← Cmd[h, cmdCode.fastOn];
Test["fastOff"] =>      ok ← Cmd[h, cmdCode.fastOff];
ENDCASE => Err[Rope.Concat[rope, " is not a Dunn command"]];
IF ~ok THEN Err["Command failed"];
};
ParseCommand: PROC [argv: CommandTool.ArgumentVector] ~ {
Test: PROC [x: Rope.ROPE] RETURNS [BOOL] ~ {RETURN[argv[1].Equal[x, FALSE]]};
SELECT TRUE FROM
Test["quit"] => {Dunn.Close[cmdData.handle]; cmdData.handle ← NIL};
Test["reserve"] => cmdData.handle ← MsgReserve[];
Test["disable"] => cmdData.handle ← Disable[];
Test["enable"] => cmdData.handle ← Enable[];
cmdData.handle = NIL => Err["Please disable or reserve the Dunn.\n"];
Test["dub"] =>
IF argv.argc < 3
THEN Err["Dub requires an argument.\n"]
ELSE {
n: INT;
error: BOOLFALSE;
n ← Convert.IntFromRope[argv[2] ! Convert.Error => {error ← TRUE; CONTINUE}];
IF error THEN Err[IO.PutFR["Bad dub value: '%g'.\n", IO.rope[argv[2]]]]
ELSE Err[IO.PutFR["Dub set to %g.\n", IO.int[cmdData.dubNum ← n]]];
};
Test["command"] =>
IF argv.argc < 3
THEN Err["Command needs an argument.\n"]
ELSE DunnRopeCommand[cmdData.handle, argv[2]];
Test["reset"] =>
IF Dunn.Reset[cmdData.handle]
THEN cmdData.dubNum ← 1
ELSE Err["Reset failed"];
Test["composite"] =>
IF ~Dunn.Composite[cmdData.handle] THEN Err["Composite failed"];
Test["separate"] =>
IF ~Dunn.Separate[cmdData.handle] THEN Err["Normal failed"];
Test["color"] =>
IF ~Dunn.Color[cmdData.handle] THEN Err["Color failed"];
Test["bw"] =>
IF ~Dunn.BW[cmdData.handle] THEN Err["BW failed"];
Test["expose"] => {
FOR i: INT IN [0..cmdData.dubNum) DO
IF ~Dunn.Expose[cmdData.handle] THEN {
Err[IO.PutFR["Expose failed at number %g.\n", IO.int[i]]];
EXIT;
};
ENDLOOP;
};
Test["debugon"] => Dunn.DebugOn[cmdData.handle, cmdData.printStream];
Test["debugoff"] => Dunn.DebugOff[cmdData.handle];
ENDCASE => Err[IO.PutFR["'%g' is not a Dunn command.\n", IO.rope[argv[1]]]];
};
CommandProc: Commander.CommandProc ~ {
ok: BOOL;
argv: CommandTool.ArgumentVector ← CommandTool.Parse[cmd];
cmdData.printStream ← cmd.out;
IF viewerOpened THEN RETURN[$Failure, "Dunn viewer already opened."];
IF argv.argc > 1
THEN ParseCommand[argv]
ELSE {
IF Dunn.HandleOK[cmdData.handle] OR Dunn.HandleDisabled[cmdData.handle]
THEN ok ← DunnViewer[cmdData.handle]
ELSE ok ← DunnViewer[MsgReserve[]];
IF ok THEN {
viewerOpened ← TRUE;
cmdData.handle ← NIL;
};
};
};
dunnUsage: Rope.ROPE ~ "\nA program for operating the Dunn camera";
Commander.Register["///Commands/DunnTool", CommandProc, dunnUsage];
END.