<> <> <> DIRECTORY Buttons, ColorDisplayHeadDorado, Containers, IO, Labels, Menus, MessageWindow, MonitorToolButtons, MonitorToolOps, Rope, Rules, Commander, VFonts, ViewerOps, ViewerTools, WindowManager ; MonitorToolImpl: CEDAR PROGRAM IMPORTS Buttons, Containers, ColorDisplayHeadDorado, IO, Labels, Menus, MessageWindow, MonitorToolButtons, MonitorToolOps, Rules, Commander, VFonts, ViewerOps, ViewerTools, WindowManager SHARES MonitorToolOps, ColorDisplayHeadDorado = BEGIN OPEN MTB: MonitorToolButtons; entryHeight: CARDINAL = 15; -- how tall to make each line of items entryVSpace: CARDINAL = 6; -- vertical leading space between lines entryHSpace: CARDINAL = 10; -- horizontal space between items in a line entryTabSpace: CARDINAL _ 36*3; -- horizontal tab between items in a line ruleHeight: CARDINAL _ 4; resultWidth: CARDINAL = 12*VFonts.CharWidth['0];-- 12 digits worth of width <<>> <> defaultScreenWidth: Rope.ROPE = "1024"; defaultScreenHeight: Rope.ROPE = "768"; defaultRefresh: Rope.ROPE = "35"; defaultHBlank: Rope.ROPE = "6"; defaultVBlank: Rope.ROPE = "850"; defaultBPP: Rope.ROPE = "8"; MakeMonitorTool: Commander.CommandProc = TRUSTED { myRule: Rules.Rule; myMenu: Menus.Menu _ Menus.CreateMenu[]; my: MTB.Handle _ NEW[MTB.MTViewerRec]; Menus.AppendMenuEntry[ -- add command to the menu menu: myMenu, entry: Menus.CreateEntry[ name: "Calculate", -- name of the command proc: CalculateProc, -- MenuProc associated with command clientData: my ] ]; Menus.AppendMenuEntry[ -- add command to the menu menu: myMenu, entry: Menus.CreateEntry[ name: "Set", -- name of the command proc: SetParametersProc, -- MenuProc associated with command clientData: my ] ]; Menus.AppendMenuEntry[ -- add command to the menu menu: myMenu, entry: Menus.CreateEntry[ name: "TurnOff", -- name of the command proc: TurnOffProc, -- MenuProc associated with command clientData: my ] ]; Menus.AppendMenuEntry[ -- add command to the menu menu: myMenu, entry: Menus.CreateEntry[ name: "NTSC", -- name of the command proc: NTSCProc, -- MenuProc associated with command clientData: my ] ]; my.container _ Containers.Create[info: [-- construct the outer container name: "MonitorTool", -- name displayed in the caption iconic: FALSE, -- so tool won't be iconic (small) when first created column: left, -- initially in the left column menu: myMenu, -- displaying our menu command scrollable: TRUE ]]; -- allow scrolling contents my.screenWidth _ MakeEntryViewer[handle: my, buttonName: "screen width", labelName: "visible pixels", proc: MTB.ScreenWidth, initialData: defaultScreenWidth]; my.screenHeight _ MakeEntryViewer[handle: my, buttonName: "screen height", labelName: "visible pixels", proc: MTB.ScreenHeight, initialData: defaultScreenHeight]; my.refresh _ MakeEntryViewer[handle: my, buttonName: "refresh rate", labelName: "frames per second", proc: MTB.Refresh, initialData: defaultRefresh]; my.hBlank _ MakeEntryViewer[handle: my, buttonName: "hBlank time", labelName: "microseconds", proc: MTB.HBlank, initialData: defaultHBlank]; my.vBlank _ MakeEntryViewer[handle: my, buttonName: "vBlank time", labelName: "microseconds", proc: MTB.VBlank, initialData: defaultVBlank]; my.bpp _ MakeEntryViewer[handle: my, buttonName: "bits per pixel", labelName: "{1,2,4,8,24}", proc: MTB.BitsPerPixel, initialData: defaultBPP]; my.height _ my.height + entryHeight+ entryVSpace; --space down myRule _ Rules.Create[info: [parent: my.container, wx: my.screenWidth.button.wx, wy: my.height, ww: my.container.ww-my.screenWidth.button.wx*2, wh: ruleHeight]]; my.height _ my.height + ruleHeight+ entryVSpace; --space down Containers.ChildXBound[my.container, myRule]; <<--now create output viewers>> my.fieldTime _ MakeResultViewer[handle: my, leftLabelName: "field time", rightLabelName: "milliseconds"]; my.fieldFreq _ MakeResultViewer[handle: my, leftLabelName: "field freq", rightLabelName: "Hz"]; my.lineTime _ MakeResultViewer[handle: my, leftLabelName: "line time", rightLabelName: "microseconds"]; my.lineFreq _ MakeResultViewer[handle: my, leftLabelName: "line freq", rightLabelName: "KHz"]; my.pixelTime _ MakeResultViewer[handle: my, leftLabelName: "pixel time", rightLabelName: "nanoseconds"]; my.pixelFreq _ MakeResultViewer[handle: my, leftLabelName: "pixel freq", rightLabelName: "MHz"]; my.MUL _ MakeResultViewer[handle: my, leftLabelName: "MUL", rightLabelName: "[0..255]"]; my.DIV _ MakeResultViewer[handle: my, leftLabelName: "DIV", rightLabelName: "[0..15]"]; my.vControl _ MakeResultViewer[handle: my, leftLabelName: "vertical ctrl", rightLabelName: "", entryheight: 4*entryHeight, entrywidth: 3*resultWidth]; my.hControl _ MakeResultViewer[handle: my, leftLabelName: "horizontal ctrl", rightLabelName: "", entryheight: 4*entryHeight, entrywidth: 3*resultWidth]; <> CalculateProc[parent: NIL, clientData: my]; MessageWindow.Append[message: "Default Parameters for 1024x768 Monitor", clearFirst: TRUE]; ViewerOps.SetOpenHeight[my.container, my.height]; -- hint our desired height ViewerOps.PaintViewer[my.container, all]; -- reflect above change }; TurnOffProc: Menus.MenuProc = TRUSTED { WindowManager.StopColorViewers[]; }; NTSCProc: Menus.MenuProc = TRUSTED { <> <> <> mp: MonitorToolOps.MonitorParam; bpp: LONG CARDINAL; full: BOOLEAN_FALSE; my: MTB.Handle _ NARROW[clientData]; {--for catch phrases bpp _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.bpp.input]] ! IO.SyntaxError => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.bpp.button.name, clearFirst: FALSE]; GOTO error};]; SELECT bpp FROM 24 => full_TRUE; 8,4,2,1 => NULL; ENDCASE => { MessageWindow.Append[message: "Input Value Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.bpp.button.name, clearFirst: FALSE]; GOTO error; }; <> mp _ NEW[MonitorToolOps.MonitorParamRec _ [ hRes: 640, vRes: 480, vc: [VBtoVS: 3, VStoVS: 3, VStoVB: 20B, VisibleLines: 240], hc: [HRamMaxAddr: 909, HBLeadLength: 12, HSTrailAddr: 56, HBTrailLength: 202], cc: [zero: 5, mul: 115, div: 14], lmarg: 474, truePixelFreq: 0, truePixelTime: 0]]; MonitorToolOps.SetMonitorParams[bpp: bpp, mp: mp]; IF NOT full THEN { --bpp#24 ColorDisplayHeadDorado.achan.pixelsPerLine_2777B; ColorDisplayHeadDorado.achan.scan.res_half; }; MessageWindow.Append[message: "Note: NTSC REQUIRES LATE MODEL HARDWARE", clearFirst: TRUE]; MessageWindow.Blink[]; MessageWindow.Blink[]; EXITS error => NULL; }; --for catch phrases }; SetParametersProc: Menus.MenuProc = TRUSTED { <> <> <<>> OPEN MTOps: MonitorToolOps; my: MTB.Handle _ NARROW[clientData]; sw, sh, refresh, bpp: LONG CARDINAL; hBlank, vBlank: REAL; mp: MTOps.MonitorParam; { --for catch phrases sw _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.screenWidth.input]] ! IO.SyntaxError => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.screenWidth.button.name, clearFirst: FALSE]; GOTO error};]; sh _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.screenHeight.input]] ! IO.SyntaxError => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.screenHeight.button.name, clearFirst: FALSE]; GOTO error};]; refresh _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.refresh.input]] ! IO.SyntaxError => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.refresh.button.name, clearFirst: FALSE]; GOTO error};]; bpp _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.bpp.input]] ! IO.SyntaxError => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.bpp.button.name, clearFirst: FALSE]; GOTO error};]; hBlank _ 1E-6* IO.GetReal[IO.RIS[ViewerTools.GetContents[my.hBlank.input]] ! IO.SyntaxError => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.hBlank.button.name, clearFirst: FALSE]; GOTO error};]; vBlank _ 1E-6* IO.GetReal[IO.RIS[ViewerTools.GetContents[my.vBlank.input]] ! IO.SyntaxError => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.vBlank.button.name, clearFirst: FALSE]; GOTO error};]; mp _ MTOps.DoMonitorParams[sw,sh,refresh,hBlank,vBlank]; MTOps.SetMonitorParams[bpp, mp]; EXITS error => NULL; }; --for catch phrases }; CalculateProc: Menus.MenuProc = TRUSTED { OPEN MTOps: MonitorToolOps; my: MTB.Handle _ NARROW[clientData]; sw, sh, refresh, bpp: LONG CARDINAL; hBlank, vBlank: REAL; mp: MTOps.MonitorParam; { --for catch phrases sw _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.screenWidth.input]] ! IO.SyntaxError => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.screenWidth.button.name, clearFirst: FALSE]; GOTO error};]; sh _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.screenHeight.input]] ! IO.SyntaxError => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.screenHeight.button.name, clearFirst: FALSE]; GOTO error};]; refresh _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.refresh.input]] ! IO.SyntaxError => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.refresh.button.name, clearFirst: FALSE]; GOTO error};]; bpp _ IO.GetCard[IO.RIS[ViewerTools.GetContents[my.bpp.input]] ! IO.SyntaxError => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.bpp.button.name, clearFirst: FALSE]; GOTO error};]; hBlank _ 1E-6* IO.GetReal[IO.RIS[ViewerTools.GetContents[my.hBlank.input]] ! IO.SyntaxError => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.hBlank.button.name, clearFirst: FALSE]; GOTO error};]; vBlank _ 1E-6* IO.GetReal[IO.RIS[ViewerTools.GetContents[my.vBlank.input]] ! IO.SyntaxError => { MessageWindow.Append[message: "Input Syntax Error in ", clearFirst: TRUE]; MessageWindow.Append[message: my.vBlank.button.name, clearFirst: FALSE]; GOTO error};]; EXITS error => RETURN; }; --for catch phrases mp _ MTOps.DoMonitorParams[sw,sh,refresh,hBlank,vBlank]; Labels.Set[label: my.fieldTime.data, value: IO.PutFR[format: "%g", v1: IO.real[1E3*MTOps.fieldTime]]]; Labels.Set[label: my.fieldFreq.data, value: IO.PutFR[format: "%g", v1: IO.real[MTOps.fieldFreq]]]; Labels.Set[label: my.lineTime.data, value: IO.PutFR[format: "%g", v1: IO.real[1E6*MTOps.trueLinetime]]]; Labels.Set[label: my.lineFreq.data, value: IO.PutFR[format: "%g", v1: IO.real[1E-3*MTOps.trueLinefreq]]]; Labels.Set[label: my.pixelTime.data, value: IO.PutFR[format: "%g", v1: IO.real[1E9*MTOps.truePixeltime]]]; Labels.Set[label: my.pixelFreq.data, value: IO.PutFR[format: "%g", v1: IO.real[1E-6*MTOps.truePixelfreq]]]; Labels.Set[label: my.MUL.data, value: IO.PutFR[format: "%g", v1: IO.card[MTOps.trueMul]]]; Labels.Set[label: my.DIV.data, value: IO.PutFR[format: "%g", v1: IO.card[MTOps.trueDiv]]]; ViewerTools.EnableUserEdits[my.hControl.data]; ViewerTools.SetContents[viewer: my.hControl.data, contents: IO.PutFR[format: "HRamMaxAddr: %g\nHBlankLeadLength: %g\nHSTrailAddr: %g\nHBTrailLength: %g", v1: IO.card[MTOps.hRamMaxAddr], v2: IO.card[MTOps.hBLeadLength], v3: IO.card[MTOps.hSTrailAddr], v4: IO.card[MTOps.hBTrailLength]]]; ViewerTools.InhibitUserEdits[my.hControl.data]; ViewerTools.EnableUserEdits[my.vControl.data]; ViewerTools.SetContents[viewer: my.vControl.data, contents: IO.PutFR[format: "VBtoVSLines: %g\nVStoVSLines: %g\nVStoVBLines: %g\nVisibleLines: %g", v1: IO.card[MTOps.vbToVS], v2: IO.card[MTOps.vsToVS], v3: IO.card[MTOps.vsToVB], v4: IO.card[MTOps.visibleLines]]]; ViewerTools.InhibitUserEdits[my.vControl.data]; }; MakeEntryViewer: PROCEDURE [handle: MTB.Handle, buttonName: Rope.ROPE, labelName: Rope.ROPE, proc: Buttons.ButtonProc, initialData: Rope.ROPE] RETURNS [ev: MTB.EntryViewer] = { <<--adds an entry viewer with a button, text viewer, and suffix label to the container>> ev _ NEW[MTB.EntryViewerRec]; ev.button_ Buttons.Create[ info: [ name: buttonName, wy: handle.height, -- default the width so that it will be computed for us -- wh: entryHeight, -- specify rather than defaulting so line is uniform parent: handle.container, border: FALSE ], proc: proc, clientData: handle]; -- this will be passed to our button proc ev.input _ ViewerTools.MakeNewTextViewer[ [ parent: handle.container, wx: entryTabSpace, wy: handle.height+2, ww: 12*VFonts.CharWidth['0], -- 12 digits worth of width wh: entryHeight, data: initialData, -- initial contents scrollable: FALSE, border: TRUE]]; ev.units _ Labels.Create[ [ name: labelName, wx: ev.input.wx + ev.input.ww + entryHSpace, wy: handle.height, <<--default ww>> wh: entryHeight, parent: handle.container, border: FALSE]]; handle.height _ handle.height + entryHeight+ entryVSpace; --space down for next guy }; MakeResultViewer: PROCEDURE [handle: MTB.Handle, leftLabelName, rightLabelName: Rope.ROPE, entryheight: CARDINAL _ entryHeight, entrywidth: CARDINAL _ resultWidth]RETURNS [rv: MTB.ResultViewer] = { <<--adds a result viewer with a label, text viewer, and units to the container>> initialData: Rope.ROPE = " ????? "; rv _ NEW[MTB.ResultViewerRec]; rv.left _ Labels.Create[ [ name: leftLabelName, wy: handle.height, -- default the width so that it will be computed for us -- wh: entryHeight, parent: handle.container, scrollable: FALSE, border: FALSE]]; rv.data _ ViewerTools.MakeNewTextViewer[ [ data: initialData, wx: entryTabSpace, wy: handle.height, ww: entrywidth, wh: entryheight, scrollable: FALSE, parent: handle.container, border: TRUE]]; rv.right _ Labels.Create[ [ name: rightLabelName, wx: rv.data.wx + rv.data.ww + entryHSpace, wy: handle.height, <<--default ww>> wh: entryHeight, parent: handle.container, scrollable: FALSE, border: FALSE]]; handle.height _ handle.height + entryheight+ entryVSpace; --space down for next guy }; Commander.Register[key: "MonitorTool", proc: MakeMonitorTool, doc: "Create a color monitor control tool" ]; [ ] _ MakeMonitorTool[NIL]; -- and create an instance END.