-- ALEDisp.mesa -- Edited by Sweet, September 29, 1980 2:43 PM DIRECTORY ALEOps, DisplayDefs USING [DestroyDisplay], Inline, KeyDefs USING [KeyBits, Keys], MiscDefs USING [DestroyFakeModule], SegmentDefs, Storage USING [Node], StringDefs, UserTerminal USING [SetState], UserTerminalOps USING [SetBitmapBox, StartUserTerminal], Window, WindowFont, WindowOps; ALEDisp: PROGRAM IMPORTS ALEOps, DisplayDefs, Inline, MiscDefs, SegmentDefs, Storage, StringDefs, UserTerminal, UserTerminalOps, Window, WindowFont EXPORTS ALEOps = BEGIN OPEN ALEOps; feedbackWindow, frameWindow, pictureWindow: PUBLIC Window.Handle; originWindow, sourceWindow, destWindow, upperWindow, lowerWindow: PUBLIC Window.Handle; upperIn, lowerIn: BOOLEAN ← FALSE; MarksOut: PUBLIC PROC = BEGIN IF ~originWindow.notInTree THEN Window.RemoveFromTree[originWindow]; IF ~sourceWindow.notInTree THEN Window.RemoveFromTree[sourceWindow]; IF ~destWindow.notInTree THEN Window.RemoveFromTree[destWindow]; IF upperWindow.notInTree THEN upperIn ← FALSE ELSE {upperIn ← TRUE; Window.RemoveFromTree[upperWindow]}; IF lowerWindow.notInTree THEN lowerIn ← FALSE ELSE {lowerIn ← TRUE; Window.RemoveFromTree[lowerWindow]}; END; MarksIn: PUBLIC PROC = BEGIN IF originWindow.notInTree THEN {originWindow.sibling ← NIL; Window.InsertIntoTree[originWindow]}; IF destWindow.notInTree THEN {destWindow.sibling ← originWindow; Window.InsertIntoTree[destWindow]}; IF sourceWindow.notInTree THEN BEGIN sourceWindow.sibling ← destWindow; Window.InsertIntoTree[sourceWindow]; END; IF lowerIn AND lowerWindow.notInTree THEN BEGIN lowerWindow.sibling ← sourceWindow; Window.InsertIntoTree[lowerWindow]; END; IF upperIn AND upperWindow.notInTree THEN BEGIN upperWindow.sibling ← IF lowerIn THEN lowerWindow ELSE sourceWindow; Window.InsertIntoTree[upperWindow]; END; END; originValueBox, sourceValueBox, destValueBox, textBox: PUBLIC Window.Box; Disjoint: PUBLIC PROC [b1, b2: POINTER TO Window.Box] RETURNS [BOOLEAN] = BEGIN IF b1.place.x + b1.dims.w < b2.place.x OR b1.place.y + b1.dims.h < b2.place.y OR b2.place.x + b2.dims.w < b1.place.x OR b2.place.y + b2.dims.h < b1.place.y THEN RETURN [TRUE]; RETURN [FALSE]; END; Inside: PUBLIC PROC [place: Window.Place, box: POINTER TO Window.Box] RETURNS [BOOLEAN] = BEGIN RETURN [(place.x - box.place.x) IN [0..box.dims.w] AND (place.y - box.place.y) IN [0..box.dims.h]]; END; ZoomDetail: PUBLIC PROC [pos1, pos2: APosition] = BEGIN mag: [0..4]; upper, lower: APosition; xDist, yDist: ADistance; cplace: Window.Place; upper ← [x: MIN[pos1.x, pos2.x], y: MIN[pos1.y, pos2.y]]; lower ← [x: MAX[pos1.x, pos2.x], y: MAX[pos1.y, pos2.y]]; IF ~upperWindow.notInTree THEN Window.RemoveFromTree[upperWindow]; IF ~lowerWindow.notInTree THEN Window.RemoveFromTree[lowerWindow]; cornerPos ← ARoundToInch[upper]; mag ← state.minMagnify; xDist ← lower.x - cornerPos.x; yDist ← lower.y - cornerPos.y; WHILE mag < 4 AND DotsForADistance[xDist, mag+1] <= FrameBox.dims.w AND DotsForADistance[yDist, mag+1] <= FrameBox.dims.h DO mag ← mag + 1; ENDLOOP; IF mag # state.magnify THEN Window.InvalidateBox[pictureWindow, [PicturePlace[cornerPos], FrameBox.dims]]; state.magnify ← mag; cplace ← PicturePlace[cornerPos]; Window.Slide[pictureWindow, [x: -cplace.x, y: -cplace.y]]; ASetOriginPos[GetOriginPos[FALSE]]; ASetSourcePos[Absolute[GetSourcePos[FALSE]]]; ASetDestPos[Absolute[GetDestPos[FALSE]]]; END; SlideCorner: PUBLIC PROC [pos: APosition] = BEGIN cplace: Window.Place; IF ~upperWindow.notInTree THEN Window.RemoveFromTree[upperWindow]; cornerPos ← ARoundToInch[pos]; cplace ← PicturePlace[cornerPos]; Window.Slide[pictureWindow, [x: -cplace.x, y: -cplace.y]]; ASetOriginPos[GetOriginPos[FALSE]]; ASetSourcePos[Absolute[GetSourcePos[FALSE]]]; ASetDestPos[Absolute[GetDestPos[FALSE]]]; END; ZoomGlobal: PUBLIC PROC = BEGIN IF state.magnify # state.minMagnify THEN Window.DisplayWhite[pictureWindow, [[0,0], FrameBox.dims]]; Window.Slide[pictureWindow, [0,0]]; cornerPos ← [0,0]; IF state.magnify # state.minMagnify THEN Window.InvalidateBox[pictureWindow, [[0,0], FrameBox.dims]]; state.magnify ← state.minMagnify; ASetOriginPos[GetOriginPos[FALSE]]; ASetSourcePos[Absolute[GetSourcePos[FALSE]]]; ASetDestPos[Absolute[GetDestPos[FALSE]]]; END; DisplayFeedback: PROC [window: Window.Handle] = BEGIN window.clearingNotRequired ← TRUE; Window.EnumerateInvalidBoxes[window, DisplayFeedbackBox]; END; Whiten: PROC [window: Window.Handle] = BEGIN DoIt: PROC [window: Window.Handle, box: Window.Box] RETURNS [Window.Box] = {Window.DisplayWhite[window, box]; RETURN[box]}; Window.EnumerateInvalidBoxes[window, DoIt]; END; DisplayFeedbackBox: PROC [window: Window.Handle, box: Window.Box] RETURNS [Window.Box] = BEGIN StripeBox: Window.Box ← [ [x: 0, y: FeedbackBox.dims.h-2], [w: FeedbackBox.dims.w, h: 1]]; IF ~Disjoint[@box, @originValueBox] THEN DisplayOriginValue[]; IF ~Disjoint[@box, @sourceValueBox] THEN DisplaySourceValue[]; IF ~Disjoint[@box, @destValueBox] THEN DisplayDestValue[]; IF ~Disjoint[@box, @StripeBox] THEN Window.DisplayBlack[window, StripeBox]; IF ~Disjoint[@box, @textBox] THEN PaintText[]; RETURN [[[0,0], window.box.dims]]; END; DisplayOriginValue: PROC = BEGIN Window.DisplayData[ window: feedbackWindow, box: [[x: -3, y: iconY], [16, 16]], data: @Cursors[origin], wpl: 1, bbop: replace]; PaintValue[[x: 11 + 5, y: textY], LOOPHOLE[GetOriginPos[TRUE]]]; END; DisplaySourceValue: PROC = BEGIN Window.DisplayData[ window: feedbackWindow, box: [[x: sourceValueBox.place.x-1, y: iconY], [16, 16]], data: @Cursors[source], wpl: 1, bbop: replace]; PaintValue[[x: sourceValueBox.place.x+8+5, y: textY], GetSourcePos[TRUE]]; END; DisplayDestValue: PROC = BEGIN Window.DisplayData[ window: feedbackWindow, box: [[x: destValueBox.place.x-8, y: iconY], [16, 16]], data: @Cursors[dest], wpl: 1, bbop: replace]; PaintValue[[x: destValueBox.place.x+8+5, y: textY], GetDestPos[TRUE]]; END; PaintValue: PROC [place: Window.Place, pos: RPosition] = BEGIN OPEN StringDefs; s: STRING ← [25]; AppendString[s, "x:"L]; AppendDistance[s, pos.x]; AppendString[s, " y:"L]; AppendDistance[s, pos.y]; [] ← Window.DisplayString[ window: feedbackWindow, s: s, place: place, bbop: replace]; END; AppendDistance: PROC [s: STRING, dist: ADistance] = BEGIN ns: STRING ← [10]; a, i: LONG CARDINAL; f: CARDINAL; a ← ABS[dist]; i ← a / 16; f ← CARDINAL[Inline.LowHalf[a]] MOD 16; StringDefs.AppendLongDecimal[ns, IF dist > 0 THEN i ELSE -LOOPHOLE[i, LONG INTEGER]]; THROUGH [ns.length..4) DO StringDefs.AppendChar[s, ' ] ENDLOOP; StringDefs.AppendString[s, ns]; IF f = 0 THEN StringDefs.AppendString[s, " "L] ELSE BEGIN StringDefs.AppendChar[s, '-]; ns.length ← 0; StringDefs.AppendDecimal[ns, f]; IF ns.length < 2 THEN StringDefs.AppendChar[s, ' ]; StringDefs.AppendString[s, ns]; END; END; textY, iconY, valueHeight: INTEGER; DisplayPicture: PROC [window: Window.Handle] = BEGIN Window.EnumerateInvalidBoxes[window, DisplayPictureBox]; IF state.displayTicks THEN DisplayBoxTicks[TRUE]; END; DisplayPictureBox: PROC [window: Window.Handle, box: Window.Box] RETURNS [Window.Box] = BEGIN aBox: ABox ← ABoxForBox[box]; keys: POINTER TO KeyDefs.KeyBits = KeyDefs.Keys; ThisPoint: PointScan = BEGIN IF pth.selected THEN BEGIN pBox: Window.Box ← BoxForPoint[p]; IF ~Disjoint[@pBox, @box] THEN BEGIN pPlace: Window.Place = PicturePlace[pth.pos]; Window.DisplayData[ window: pictureWindow, box: [[pPlace.x-8, pPlace.y-8], [16, 16]], data: @Cursors[selPt], wpl: 1]; END; END; END; ThisLine: LineScan = BEGIN DisplayLine[l, BoxForLine[l]]; RETURN[FALSE]; END; ThisLabel: LabelScan = BEGIN labelBox: Window.Box ← BoxForLabel[lb]; IF ~Disjoint[@labelBox, @box] THEN PaintLabel[lb]; RETURN[FALSE]; END; [] ← LinesInABox[@aBox, ThisLine]; IF state.showingLabels THEN [] ← AllLabels[ThisLabel]; [] ← SelectedPoints[ThisPoint]; RETURN [box]; END; tickSpace: ARRAY [-3..4] OF ADistance = [ 16*128, 16*96, 16*48, 16*24, 16*12, 16*6, 16*3, 8*3]; Triple: TYPE = RECORD [a,b,c: CARDINAL]; tickMarks: ARRAY [0..12] OF Triple ← ALL[[100000B, 200B, 0]]; DisplayBoxTicks: PUBLIC PROC [on: BOOLEAN] = BEGIN space: ADistance = tickSpace[state.magnify]; cPlace: Window.Place = PicturePlace[cornerPos]; rcp: RPosition = Relative[cornerPos]; rft: RPosition = [ x: ((rcp.x)/space)*space, y: ((rcp.y)/space) * space]; tickStart: Window.Place ← PicturePlace[Absolute[rft]]; tbox: Window.Box ← [ tickStart, [w: FrameBox.dims.w + cPlace.x - tickStart.x, h: 1]]; lastY: INTEGER = cPlace.y + FrameBox.dims.h; WHILE tbox.place.y < lastY DO Window.DisplayData[ window: pictureWindow, data: BASE[tickMarks], bbop: IF on THEN paint ELSE erase, wpl: 40, box: tbox]; tbox.place.y ← tbox.place.y + 24; ENDLOOP; END; DisplayOrigin: PROC [window: Window.Handle] = BEGIN Window.DisplayOffsetData[ window: window, box: [[0,0], window.box.dims], data: @Cursors[origin] + 3, wpl: 1, offset: 3, bbop: replace]; END; DisplaySource: PROC [window: Window.Handle] = BEGIN Window.DisplayOffsetData[ window: window, box: [[0,0], window.box.dims], data: @Cursors[source] + 4, wpl: 1, offset: 1, bbop: replace]; END; DisplayDest: PROC [window: Window.Handle] = BEGIN Window.DisplayOffsetData[ window: window, box: [[0,0], window.box.dims], data: @Cursors[dest] + 4, wpl: 1, offset: 8, bbop: replace]; END; DisplayUpper: PROC [window: Window.Handle] = BEGIN Window.DisplayOffsetData[ window: window, box: [[0,0], window.box.dims], data: @Cursors[upper] + 8, wpl: 1, offset: 8, bbop: replace]; END; DisplayLower: PROC [window: Window.Handle] = BEGIN Window.DisplayOffsetData[ window: window, box: [[0,0], window.box.dims], data: @Cursors[lower] + 1, wpl: 1, offset: 1, bbop: replace]; END; root: Window.Object ← []; StartDisplay: PUBLIC PROC = BEGIN DisplayDefs.DestroyDisplay[]; UserTerminalOps.StartUserTerminal[FALSE]; Window.DefineRoot[window: @root, grey:, bitmapExists: FALSE]; [] ← UserTerminalOps.SetBitmapBox[BitmapBox]; [] ← UserTerminal.SetState[off]; Window.DefineRoot[window: @root, grey:[0,0,0,0], bitmapExists: TRUE]; [] ← UserTerminal.SetState[on]; LoadFont[]; feedbackWindow ← Storage.Node[SIZE[Window.Object]]; frameWindow ← Storage.Node[SIZE[Window.Object]]; pictureWindow ← Storage.Node[SIZE[Window.Object]]; originWindow ← Storage.Node[ SIZE[Window.Object] + SIZE[Window.MinusLandBitmapUnder]] + SIZE[Window.MinusLandBitmapUnder]; sourceWindow ← Storage.Node[ SIZE[Window.Object] + SIZE[Window.MinusLandBitmapUnder]] + SIZE[Window.MinusLandBitmapUnder]; destWindow ← Storage.Node[ SIZE[Window.Object] + SIZE[Window.MinusLandBitmapUnder]] + SIZE[Window.MinusLandBitmapUnder]; upperWindow ← Storage.Node[ SIZE[Window.Object] + SIZE[Window.MinusLandBitmapUnder]] + SIZE[Window.MinusLandBitmapUnder]; lowerWindow ← Storage.Node[ SIZE[Window.Object] + SIZE[Window.MinusLandBitmapUnder]] + SIZE[Window.MinusLandBitmapUnder]; feedbackWindow↑ ← [ parent: Window.rootWindow, sibling: frameWindow, box: FeedbackBox, display: DisplayFeedback, boxesCount: one]; frameWindow↑ ← [ parent: Window.rootWindow, child: pictureWindow, box: FrameBox, display: Whiten]; pictureWindow↑ ← [ parent: frameWindow, child: originWindow, boxesCount: one, box: PictureBox, display: DisplayPicture]; originWindow↑ ← [ parent: pictureWindow, box: originBox, display: DisplayOrigin, underVariant: TRUE, clearingNotRequired: TRUE, boxesCount: none]; [] ← Window.SetBitmapUnder[ originWindow, Storage.Node[Window.WordsForBitmapUnder[originWindow]]]; sourceWindow↑ ← [ parent: pictureWindow, box: sourceBox, display: DisplaySource, underVariant: TRUE, clearingNotRequired: TRUE, boxesCount: none]; [] ← Window.SetBitmapUnder[ sourceWindow, Storage.Node[Window.WordsForBitmapUnder[sourceWindow]]]; destWindow↑ ← [ parent: pictureWindow, box: destBox, display: DisplayDest, underVariant: TRUE, clearingNotRequired: TRUE, boxesCount: none]; [] ← Window.SetBitmapUnder[ destWindow, Storage.Node[Window.WordsForBitmapUnder[destWindow]]]; upperWindow↑ ← [ parent: pictureWindow, box: upperBox, display: DisplayUpper, underVariant: TRUE, clearingNotRequired: TRUE, boxesCount: none]; [] ← Window.SetBitmapUnder[ upperWindow, Storage.Node[Window.WordsForBitmapUnder[sourceWindow]]]; lowerWindow↑ ← [ parent: pictureWindow, box: lowerBox, display: DisplayLower, underVariant: TRUE, clearingNotRequired: TRUE, boxesCount: none]; [] ← Window.SetBitmapUnder[ lowerWindow, Storage.Node[Window.WordsForBitmapUnder[destWindow]]]; -- get ready to display pos values textY ← 2; iconY ← textY + WindowFont.FontHeight[]/2 - 8; valueHeight ← MAX[WindowFont.FontHeight[], 11]; originValueBox ← [ [x: 0, y: 0], [w: FeedbackBox.dims.w/3, h: valueHeight]]; sourceValueBox ← [ [x: FeedbackBox.dims.w/3, y: 0], [w: FeedbackBox.dims.w/3, h: valueHeight]]; destValueBox ← [ [x: (2*FeedbackBox.dims.w)/3, y: 0], [w: FeedbackBox.dims.w/3, h: valueHeight]]; textBox ← [ [x: 0, y: valueHeight + 1], [w: FeedbackBox.dims.w, h: WindowFont.FontHeight[]]]; Window.InsertIntoTree[frameWindow]; Window.InsertIntoTree[feedbackWindow]; Window.ValidateTree[]; END; fontAscent, smallFontAscent, largeFontAscent: PUBLIC INTEGER; smallFont, largeFont: PUBLIC WindowFont.Handle; LoadFont: PROC = BEGIN OPEN SegmentDefs; font: WindowFont.Handle ← Storage.Node[SIZE[WindowFont.Object]]; fsb: WindowOps.Strike; fseg: FileSegmentHandle ← MiscDefs.DestroyFakeModule[ LOOPHOLE[ALEOps.Gacha10]].seg; MakeSwappedIn[seg: fseg, info: HardUp]; font.address ← fsb ← SegmentAddress[fseg]; fontAscent ← fsb.body.ascent; font.swapper ← NIL; WindowFont.Initialize[font]; WindowFont.SetDefault[font]; font ← Storage.Node[SIZE[WindowFont.Object]]; fseg ← MiscDefs.DestroyFakeModule[ LOOPHOLE[ALEOps.Helvetica8]].seg; MakeSwappedIn[seg: fseg, info: HardUp]; font.address ← fsb ← SegmentAddress[fseg]; smallFontAscent ← fsb.body.ascent; font.swapper ← NIL; WindowFont.Initialize[font]; smallFont ← font; font ← Storage.Node[SIZE[WindowFont.Object]]; fseg ← MiscDefs.DestroyFakeModule[ LOOPHOLE[ALEOps.Helvetica14]].seg; MakeSwappedIn[seg: fseg, info: HardUp]; font.address ← fsb ← SegmentAddress[fseg]; largeFontAscent ← fsb.body.ascent; font.swapper ← NIL; WindowFont.Initialize[font]; largeFont ← font; SetupLand[]; END; END.