DIRECTORY Atom, CD, CDBasics, CDDefaultProcs, CDDrawQueue, CDCells, CDEnvironment, CDEvents, CDInstances, CDOps, CDPanel, CDProperties, CDSequencer, CDValue, CDViewer, CDViewerBackdoor, CDViewerInternals, CDVPrivate, CDVScale, Imager, ImagerSample USING [MapFromFrameBuffer, Move, nullFunction], InterminalBackdoor USING [terminal], IO, PopUpSelection, Process, Rope, SF USING [Vec], Terminal, TerminalIO, UserProfile, VFonts, ViewerClasses USING [Viewer], ViewerOps USING [PaintViewer, GetViewer, SetViewer, OpenIcon, BlinkIcon]; CDVCommands: CEDAR PROGRAM IMPORTS Atom, CD, CDBasics, CDDefaultProcs, CDDrawQueue, CDCells, CDEnvironment, CDEvents, CDInstances, CDOps, CDPanel, CDProperties, CDSequencer, CDValue, CDViewer, CDViewerBackdoor, CDVPrivate, CDVScale, Imager, ImagerSample, InterminalBackdoor, IO, PopUpSelection, Process, Rope, Terminal, TerminalIO, UserProfile, ViewerOps, VFonts EXPORTS CDViewerInternals SHARES CDVPrivate = BEGIN VRef: TYPE = CDVPrivate.VRef; DoWithVRef: PROC [comm: CDSequencer.Command, proc: PROC[vRef: VRef]] = { v: ViewerClasses.Viewer _ CDViewer.GetViewer[comm]; IF v=NIL THEN TerminalIO.PutRope["failed: no viewer\n"] ELSE WITH v.data SELECT FROM vRef: VRef => IF ~vRef.viewer.destroyed THEN proc[vRef]; ENDCASE => NULL; }; AddCR: PROC [r: Rope.ROPE] RETURNS [Rope.ROPE] = { ml: INT _ Rope.Length[r]; IF Rope.Fetch[r, ml-1]#'\n THEN RETURN[Rope.Concat[r, "\n"]]; RETURN [r]; }; MsgAndVRef: PROC [comm: CDSequencer.Command, msg: Rope.ROPE] RETURNS [vRef: VRef_NIL] = { v: ViewerClasses.Viewer _ CDViewer.GetViewer[comm]; TerminalIO.PutRope[AddCR[msg]]; IF v=NIL THEN TerminalIO.PutRope[" failed: no viewer\n"] ELSE WITH v.data SELECT FROM vr: VRef => IF ~vr.viewer.destroyed THEN vRef _ vr ELSE TerminalIO.PutRope[" failed: viewer destroyed\n"]; ENDCASE => TerminalIO.PutRope[" failed: no ChipNDale viewer\n"]; }; Repaint: PROC [v: REF] = { WITH v SELECT FROM vRef: VRef => { CDDrawQueue.Flush[vRef.ct]; CDDrawQueue.QueueInsertDrawCommand[vRef.ct, CDDrawQueue.Request[$changeScale, CDBasics.universe]]; CDDrawQueue.QueueInsertDrawCommand[vRef.ct, CDDrawQueue.Request[$redraw, CDBasics.universe]]; }; viewer: ViewerClasses.Viewer => Repaint[viewer.data]; comm: CDSequencer.Command => Repaint[comm.ref]; ENDCASE => NULL; }; SaveScale: PUBLIC PROC [viewer: ViewerClasses.Viewer] = { IF viewer#NIL THEN WITH viewer.data SELECT FROM vRef: VRef => CDProperties.PutProp[vRef.properties, $CDxSavedScale, NEW[CDVScale.ScaleRec _ vRef.scale]]; ENDCASE => NULL; }; RestoreScale: PUBLIC PROC [viewer: ViewerClasses.Viewer] = { IF viewer#NIL THEN WITH viewer.data SELECT FROM vRef: VRef => { GetScale: PROC [key: ATOM] RETURNS [CDVScale.ScaleRec] = { WITH CDProperties.GetProp[vRef.properties, key] SELECT FROM sr: REF CDVScale.ScaleRec => RETURN [sr^]; ENDCASE => RETURN [CDVScale.MakeScale[]]; }; scale: CDVScale.ScaleRec _ GetScale[$CDxSavedScale]; CDDrawQueue.Flush[vRef.ct]; IF vRef.scale.off=scale.off AND vRef.scale.nscale=scale.nscale THEN scale _ GetScale[$CDxSecondaryScale]; CDProperties.PutProp[vRef.properties, $CDxSecondaryScale, NEW[CDVScale.ScaleRec _ vRef.scale]]; vRef.intendedScale _ CDVScale.MakeScale[off: scale.off, nscale: scale.nscale, grid: vRef.scale.grid]; Repaint[vRef]; }; ENDCASE => NULL; }; WriteLnScale: PROC [v: REF] = { TerminalIO.PutRope["\n"]; }; ChangeScale: PROC [vRef: VRef, newScale: INT] = { newScale _ MIN[MAX[0, newScale], CDVScale.scaleNum-1]; IF vRef.scale.nscale = newScale THEN TerminalIO.PutRope["no scale change"] ELSE { oldDesignCenterOffset, newDesignCenterOffset: CD.Position; viewerCenterOffset: CD.Position _ [vRef.viewer.cw/2, vRef.viewer.ch/2]; off: CD.Position _ vRef.scale.off; dscale: CDVScale.ScaleRec; CDDrawQueue.Flush[vRef.ct]; TerminalIO.PutRope["change scale"]; dscale _ CDVScale.MakeScale[nscale: vRef.scale.nscale, grid: vRef.scale.grid]; oldDesignCenterOffset _ CDVScale.ViewerToDesignPosition[dscale, viewerCenterOffset]; dscale _ CDVScale.MakeScale[nscale: newScale, grid: vRef.scale.grid]; newDesignCenterOffset _ CDVScale.ViewerToDesignPosition[dscale, viewerCenterOffset]; off _ CDBasics.SubPoints[ CDBasics.AddPoints[off, oldDesignCenterOffset], newDesignCenterOffset ]; dscale _ CDVScale.MakeScale[off: off, nscale: newScale, grid: vRef.scale.grid]; vRef.intendedScale _ dscale; Repaint[vRef]; }; WriteLnScale[vRef.viewer]; }; ScaleUp: PROC [comm: CDSequencer.Command] = { Do: PROC[vRef: VRef] = { i: INT _ vRef.scale.nscale; i _ IF i>0 THEN i-1 ELSE 0; ChangeScale[vRef, i]; }; DoWithVRef[comm, Do] }; ScaleDown: PROC [comm: CDSequencer.Command] = { Do: PROC[vRef: VRef] = {ChangeScale[vRef, vRef.scale.nscale+1]}; DoWithVRef[comm, Do] }; MoveScreenCmd: PROC [comm: CDSequencer.Command] ~ { Do: PROC[vRef: VRef] = { CDDrawQueue.QueueInsertDrawCommand[vRef.ct, CDDrawQueue.Request[$fastMoveScreen, [x1: comm.pos.x-comm.sPos.x, y1: comm.pos.y-comm.sPos.y, x2: 0, y2: 0]]]; }; TerminalIO.PutRope["move window\n"]; DoWithVRef[comm, Do] }; GCD: PROC [ m, n: INT ] RETURNS [ INT ] = { r: INT; SELECT m FROM <0 => m _ -m; ENDCASE => NULL; SELECT n FROM <0 => n _ -n; >0 => NULL; ENDCASE => RETURN[m]; r _ m MOD n; WHILE r>0 DO m _ n; n _ r; r _ m MOD n; ENDLOOP; RETURN[n]; }; DoMoveScreen: CDViewerBackdoor.FurtherPaintProc ~ { ProtectedAction: PROC [vRef: VRef] ~ { FrameBaseOfViewerRect: PROC [r: CD.Rect] RETURNS [SF.Vec] ~ INLINE { RETURN [[ s: vRef.frame.height-vRef.viewer.wy-r.y2, f: vRef.viewer.wx+r.x1 ]]; }; Blit: PROC [] ~ { -- Move bits around ImagerSample.Move[ map: ImagerSample.MapFromFrameBuffer[vRef.frame], dstMin: FrameBaseOfViewerRect[dstBltRect], srcMin: FrameBaseOfViewerRect[srcBltRect], size: [s: srcBltRect.y2-srcBltRect.y1, f: srcBltRect.x2-srcBltRect.x1], function: ImagerSample.nullFunction]; }; WillRepaint: PROC [vr: CD.Rect--viewer coordinates--] ~ { toRepaint _ CONS [CD.Rect[ x1: CDVScale.UngriddedViewerToDesignScalar[vRef.intendedScale, vr.x1]+vRef.intendedScale.off.x-1, y1: CDVScale.UngriddedViewerToDesignScalar[vRef.intendedScale, vr.y1]+vRef.intendedScale.off.y-1, x2: CDVScale.UngriddedViewerToDesignScalar[vRef.intendedScale, vr.x2]+vRef.intendedScale.off.x+1, y2: CDVScale.UngriddedViewerToDesignScalar[vRef.intendedScale, vr.y2]+vRef.intendedScale.off.y+1 ], toRepaint]; }; clientRect, srcBltRect, dstBltRect: CD.Rect; offset: CD.Position; IF vRef.scale.nscale#vRef.intendedScale.nscale OR vRef.scale.off=vRef.intendedScale.off THEN RETURN; -- do a regular redraw clientRect _ [x1: vRef.viewer.cx, y1: vRef.viewer.cy, x2: vRef.viewer.cx+vRef.viewer.cw, y2: vRef.viewer.cy+vRef.viewer.ch]; -- viewer client rect in viewer coords offset _ CDVScale.DesignToViewerPosition[vRef.intendedScale, vRef.scale.off]; dstBltRect _ CDBasics.Intersection[clientRect, CDBasics.MoveRect[clientRect, offset]]; srcBltRect _ CDBasics.MoveRect[dstBltRect, CDBasics.NegOffset[offset]]; IF vRef.display=bw THEN Blit[] ELSE Terminal.ModifyColorFrame[vt: InterminalBackdoor.terminal, action: Blit]; CDBasics.DecomposeRect[r: clientRect, test: dstBltRect, outside: WillRepaint]; }; -- End of ProtectedAction toRepaint: LIST OF CD.Rect _ NIL; -- when NIL, means repaint all, erase and paint each rect req: REF CDDrawQueue.Request _ NARROW[key]; scale: CDVScale.ScaleRec _ me.scale; off: CD.Position; mod: CD.Number; mod _ MAX[CDVScale.ViewerToDesignScalar[scale, 4], 1]; IF scale.grid>1 THEN mod _ mod/GCD[mod, scale.grid]*scale.grid; off _ [scale.off.x-req.rect.x1/mod*mod, scale.off.y-req.rect.y1/mod*mod]; me.intendedScale _ CDVScale.MakeScale[off: off, nscale: scale.nscale, grid: scale.grid]; CDDrawQueue.Flush[me.ct]; CDVPrivate.DoInsideMonitor[ProtectedAction, me]; IF toRepaint=NIL THEN { -- cannot do a fast move, do a repaint and quit. CDDrawQueue.QueueInsertDrawCommand[me.ct, CDDrawQueue.Request[$changeScale, CDBasics.universe]]; RETURN; }; CDVPrivate.ResetDrawScale[me]; WHILE toRepaint#NIL DO CDVPrivate.RepaintBackground[me, toRepaint.first, TRUE]; --immediate CDDrawQueue.QueueInsertDrawCommand[me.ct, CDDrawQueue.Request[$redraw, toRepaint.first]];--delayed toRepaint _ toRepaint.rest; ENDLOOP; }; GetViewerInt: PROC [viewer: ViewerClasses.Viewer, at: ATOM] RETURNS [i: INT _ -1] = { WITH ViewerOps.GetViewer[viewer, at] SELECT FROM ri: REF INT => i _ ri^; ENDCASE => NULL; }; GridComm: PROC [comm: CDSequencer.Command] = { GridRope: PROC [v: ViewerClasses.Viewer] RETURNS [r: Rope.ROPE] = { r _ CDOps.LambdaRope[GetViewerInt[viewer, $Grid], lambda] }; g: INT _ -1; lambda: INT _ comm.design.technology.lambda; viewer: ViewerClasses.Viewer _ CDViewer.GetViewer[comm]; IF viewer=NIL THEN TerminalIO.PutRope["no viewer\n"] ELSE { IF comm.key=$GridDouble THEN g _ GetViewerInt[viewer, $Grid]*2 ELSE IF comm.key=$GridHalf THEN g _ GetViewerInt[viewer, $Grid]/2 ELSE { TerminalIO.PutF1["grid command (current grid = %g)\n", [rope[GridRope[viewer]]]]; SELECT PopUpSelection.Request[ choice: LIST[" 1", " 2", " 4", " 8", "16", "1/2", "default", "type lambda", "type int", "move selected to grid", "TICKS"], header: "grid", headerDoc: "grid = distance used for snapping the cursor"] FROM 1 => g _ lambda; 2 => g _ 2*lambda; 3 => g _ 4*lambda; 4 => g _ 8*lambda; 5 => g _ 16*lambda; 6 => g _ lambda/2; 7 => g _ CDValue.FetchInt[boundTo: CDViewer.DesignOf[viewer], key: $CDxInitGrid, propagation: global]; 8 => g _ MIN[INT[2600/lambda], TerminalIO.RequestInt["grid: "]]*lambda; 9 => g _ MIN[INT[2600], TerminalIO.RequestInt["grid: "]]; 10 => {MoveToGridComm[comm]; RETURN}; 11 => {CDSequencer.ExecuteCommand[key: $TicksInfo, comm: comm]; RETURN}; ENDCASE => g _ -1; }; IF g>0 AND g<=2600 THEN { ViewerOps.SetViewer[viewer: viewer, data: NEW[INT_g], op: $Grid]; TerminalIO.PutF1[" grid set to %g \n", IO.rope[CDOps.LambdaRope[g, lambda]]]; } ELSE TerminalIO.PutRope[" failed \n"]; }; }; ChangeGridComm: PROC [comm: CDSequencer.Command] = { viewer: ViewerClasses.Viewer _ CDViewer.GetViewer[comm]; }; SetSimplificationComm: PROC[comm: CDSequencer.Command] = { Do: PROC[vRef: VRef] = { n: INT; CDDrawQueue.Flush[vRef.ct]; n _ PopUpSelection.Request[ choice: LIST["very simplified", "simplified", "standard", "detailed", "very detailed", "show all"], header: "viewer simplification treshold", headerDoc: "the viewer simplification treshold is multiplied with the cell simplification treshold" ]; SELECT n FROM 1 => vRef.suppressFactorForCells _ 0.4; 2 => vRef.suppressFactorForCells _ 0.7; 3 => vRef.suppressFactorForCells _ 1; 4 => vRef.suppressFactorForCells _ 1.6; 5 => vRef.suppressFactorForCells _ 2.6; 6 => vRef.suppressFactorForCells _ 0; ENDCASE => RETURN; Repaint[vRef] }; TerminalIO.PutRope["set viewer simplification threshold\n"]; DoWithVRef[comm, Do] }; InstanceNames: PROC [comm: CDSequencer.Command] = { v: ViewerClasses.Viewer ~ CDViewer.GetViewer[comm]; TerminalIO.PutRope["display instance names\n"]; IF v#NIL THEN ViewerOps.PaintViewer[v, client, FALSE, $DrawInstanceNames] }; SignalNames: PROC [comm: CDSequencer.Command] = { v: ViewerClasses.Viewer = CDViewer.GetViewer[comm]; TerminalIO.PutRope["display signal names\n"]; IF v#NIL THEN ViewerOps.PaintViewer[v, client, FALSE, $DrawSignalNames] }; GetOppositViewer: PROC [comm: CDSequencer.Command] RETURNS [ViewerClasses.Viewer] = { vl: CDViewer.ViewerList = CDViewer.ViewersOf[comm.design]; viewer: ViewerClasses.Viewer = CDViewer.GetViewer[comm]; onColor: BOOL = (viewer=NIL OR viewer.column=color); FOR l: CDViewer.ViewerList _ vl, l.rest WHILE l#NIL DO IF ~l.first.iconic THEN IF (l.first.column=color)#onColor THEN RETURN [l.first]; ENDLOOP; FOR l: CDViewer.ViewerList _ vl, l.rest WHILE l#NIL DO IF ~l.first.iconic THEN IF l.first.column#viewer.column THEN RETURN [l.first]; ENDLOOP; FOR l: CDViewer.ViewerList _ vl, l.rest WHILE l#NIL DO IF ~l.first.iconic THEN IF l.first#viewer THEN RETURN [l.first]; ENDLOOP; RETURN [viewer]; }; ShowRectX: PROC [comm: CDSequencer.Command] = { SmallScale: PROC [comm: CDSequencer.Command] RETURNS [BOOL] = { min: CD.Number = 30; RETURN [min>ABS[comm.pos.x-comm.sPos.x] AND min>ABS[comm.pos.y-comm.sPos.y]] }; viewer: ViewerClasses.Viewer ~ GetOppositViewer[comm]; TerminalIO.PutRope["position a viewer\n"]; IF viewer#NIL THEN IF SmallScale[comm] THEN CDViewer.ShowPosition[viewer: viewer, pos: comm.sPos] ELSE CDViewer.ShowAndScale[viewer: viewer, rect: CDBasics.ToRect[comm.pos, comm.sPos]]; }; RestoreViewComm: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["restore previous scale\n"]; RestoreScale[CDViewer.GetViewer[comm]]; }; ShowRect: PROC [comm: CDSequencer.Command] = { viewer: ViewerClasses.Viewer ~ CDViewer.GetViewer[comm]; TerminalIO.PutRope["scale viewer"]; SaveScale[viewer]; IF comm.pos=comm.sPos THEN CDViewer.ShowPosition[viewer, comm.pos] ELSE CDViewer.ShowAndScale[viewer, CDBasics.ToRect[comm.pos, comm.sPos]]; WriteLnScale[viewer]; }; ResetScaleComm: PROC [comm: CDSequencer.Command] = { ResetScaleAll: PROC [viewer: ViewerClasses.Viewer] = { b: CD.Rect; TerminalIO.PutRope["reset scale (view all)"]; b _ CDOps.BoundingBox[CDViewer.DesignOf[viewer]]; IF CDBasics.NonEmpty[b] THEN CDViewer.ShowAndScale[viewer, b]; WriteLnScale[viewer]; }; viewer: ViewerClasses.Viewer _ CDViewer.GetViewer[comm]; IF viewer#NIL THEN { SaveScale[viewer]; ResetScaleAll[viewer]; }; }; ResetScaleToSelectedComm: PROC [comm: CDSequencer.Command] = { viewer: ViewerClasses.Viewer = CDViewer.GetViewer[comm]; TerminalIO.PutRope["reset scale to selection"]; IF viewer#NIL THEN { b: CD.Rect _ CDInstances.BoundingRectO[list: CDOps.InstList[comm.design], selectedOnly: TRUE]; IF CDBasics.NonEmpty[b] THEN { SaveScale[viewer]; CDViewer.ShowAndScale[viewer: viewer, rect: b]; WriteLnScale[viewer]; RETURN; }; }; TerminalIO.PutRope[" no selection\n"]; }; ResetScaleToPushedComm: PROC [comm: CDSequencer.Command] = { viewer: ViewerClasses.Viewer = CDViewer.GetViewer[comm]; IF viewer#NIL THEN { b: CD.Rect; SaveScale[viewer]; TerminalIO.PutRope["reset scale (to view all of pushed cell)"]; b _ CDInstances.BoundingRectO[list: CDOps.InstList[comm.design], selectedOnly: FALSE]; IF CDBasics.NonEmpty[b] THEN CDViewer.ShowAndScale[viewer, b]; WriteLnScale[viewer]; }; }; ShowViewersComm: PROC [comm: CDSequencer.Command] = { Do: PROC[vRef: VRef] = { CDDrawQueue.QueueInsertDrawCommand[vRef.ct, CDDrawQueue.Request[$ShowViewers, CDBasics.universe]]; }; TerminalIO.PutRope["show viewers\n"]; DoWithVRef[comm, Do] }; SplitViewer: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope["split viewer\n"]; [] _ CDViewer.CreateViewer[comm.design, FALSE] }; SetCellSimplification: PROC [comm: CDSequencer.Command] = { Do: PROC[vRef: VRef] = { scale: CDVScale.ScaleRec _ vRef.scale; FOR l: CD.InstanceList _ CDOps.InstList[comm.design], l.rest WHILE l#NIL DO IF l.first.selected AND CDCells.IsCell[l.first.ob] THEN { simplifyOn: CD.Number _ CDVScale.DesignToViewerScalar[scale, l.first.ob.bbox.y2-l.first.ob.bbox.y1]; CDCells.SetSimplificationTreshhold[l.first.ob, simplifyOn, TRUE]; CDOps.RedrawInstance[comm.design, l.first]; }; ENDLOOP; }; TerminalIO.PutRope["put visibility threshold to current scale\n"]; DoWithVRef[comm, Do] }; EnforcePanel: PROC [comm: CDSequencer.Command] = { v: ViewerClasses.Viewer; TerminalIO.PutRope["enforce a control panel\n"]; v _ CDPanel.Create[comm.design]; IF v#NIL THEN { IF v.iconic THEN ViewerOps.OpenIcon[v] ELSE ViewerOps.BlinkIcon[v, 1, 1, 200] }; }; FontSubstOnComm: PROC [comm: CDSequencer.Command] = { vRef: VRef _ MsgAndVRef[comm, "viewer drawmode: substitute tioga fonts"]; IF vRef#NIL THEN { vRef.fontSubstitution _ TRUE; CDProperties.PutProp[comm.design, $CDxSubstituteFonts, $TRUE]; Repaint[vRef]; }; }; FontSubstOffComm: PROC [comm: CDSequencer.Command] = { vRef: VRef _ MsgAndVRef[comm, "viewer drawmode: don't substitute tioga fonts"]; IF vRef#NIL THEN { vRef.fontSubstitution _ FALSE; CDProperties.PutProp[comm.design, $CDxSubstituteFonts, NIL]; Repaint[vRef]; }; }; DrawEnvComm: PROC [comm: CDSequencer.Command] = { vRef: VRef _ MsgAndVRef[comm, "viewer drawmode: draw environment of pushed cells"]; IF vRef#NIL THEN { vRef.environment _ TRUE; CDProperties.PutProp[comm.design, $CDxDrawEnvironment, NIL]; Repaint[vRef]; }; }; DontDrawEnvComm: PROC [comm: CDSequencer.Command] = { vRef: VRef _ MsgAndVRef[comm, "viewer drawmode: don't draw environment of pushed cells"]; IF vRef#NIL THEN { vRef.environment _ FALSE; CDProperties.PutProp[comm.design, $CDxDrawEnvironment, $FALSE]; Repaint[vRef]; }; }; DrawSymbolicsComm: PROC [comm: CDSequencer.Command] = { vRef: VRef _ MsgAndVRef[comm, "viewer drawmode: draw symbolic objects"]; IF vRef#NIL THEN { vRef.symbolics _ TRUE; CDProperties.PutProp[comm.design, $CDxDrawSymbolics, NIL]; Repaint[vRef]; }; }; DontDrawSymbolicsComm: PROC [comm: CDSequencer.Command] = { vRef: VRef _ MsgAndVRef[comm, "viewer drawmode: don't draw symbolic objects"]; IF vRef#NIL THEN { vRef.symbolics _ FALSE; CDProperties.PutProp[comm.design, $CDxDrawSymbolics, $FALSE]; Repaint[vRef]; }; }; DrawBordersComm: PROC [comm: CDSequencer.Command] = { vRef: VRef _ MsgAndVRef[comm, "viewer drawmode: draw with borders"]; IF vRef#NIL THEN { vRef.borders _ TRUE; CDProperties.PutProp[comm.design, $CDxSkipBorder, $FALSE]; Repaint[vRef]; }; }; DontDrawBordersComm: PROC [comm: CDSequencer.Command] = { vRef: VRef _ MsgAndVRef[comm, "viewer drawmode: don't draw borders"]; IF vRef#NIL THEN { vRef.borders _ FALSE; CDProperties.PutProp[comm.design, $CDxSkipBorder, NIL]; Repaint[vRef]; }; }; CheckEdited: PROC [design: CD.Design] = { IF design#NIL THEN { edited: BOOL _ design.edited; FOR vl: CDViewer.ViewerList _ CDViewer.ViewersOf[design], vl.rest WHILE vl#NIL DO IF vl.first.newVersion#edited THEN { vl.first.newVersion _ edited; ViewerOps.PaintViewer[vl.first, caption] }; ENDLOOP } }; CheckEditedEvent: CDEvents.EventProc = { TRUSTED {Process.Detach[FORK CheckEdited[design]]}; }; NoteProfileChange: UserProfile.ProfileChangedProc = { IF reason=edit THEN { FOR vl: CDViewer.ViewerList _ CDViewer.ViewersOf[NIL], vl.rest WHILE vl#NIL DO d: CD.Design _ CDViewer.DesignOf[vl.first]; IF d#NIL THEN vl.first.tipTable _ CDEnvironment.GetTipTable[d]; ENDLOOP }; }; MoveToGridComm: PROC [comm: CDSequencer.Command] = { selCnt, movCnt: INT _ 0; grid: CD.Number _ CDOps.GetGrid[comm.design, comm]; TerminalIO.PutRope["move (interest rect) to grid positions;"]; IF grid<1 THEN {TerminalIO.PutRope["failed: bad grid value"]; RETURN}; FOR l: CD.InstanceList _ CDOps.InstList[comm.design], l.rest WHILE l#NIL DO IF l.first.selected THEN { pos: CD.Position _ CDBasics.BaseOfRect[CDInstances.InstRectI[l.first]]; gridded: CD.Position _ [(pos.x)/grid*grid, (pos.y)/grid*grid]; selCnt _ selCnt+1; IF gridded#pos THEN { CDSequencer.MarkChanged[comm.design]; CDOps.RedrawInstance[comm.design, l.first]; l.first.trans.off _ CDBasics.AddPoints[l.first.trans.off, CDBasics.SubPoints[gridded, pos]]; CDOps.RedrawInstance[comm.design, l.first, FALSE]; movCnt _ movCnt+1; }; }; ENDLOOP; TerminalIO.PutF[" %g selected, %g moved objects\n", [integer[selCnt]], [integer[movCnt]]]; }; ShowViewers: CDViewerBackdoor.FurtherPaintProc = { OutlineViewer: PROC [me: CDVPrivate.VRef, other: ViewerClasses.Viewer] = { otherMe: CDVPrivate.VRef = NARROW[other.data]; r: CD.Rect = otherMe.dClip; p1: CD.Position = CDVScale.DesignToViewerPosition[me.scale, [r.x1, r.y1]]; p2: CD.Position = CDVScale.DesignToViewerPosition[me.scale, [r.x2, r.y2]]; CDVPrivate.InvertArea[me, p1.x, p1.y, p1.x+1, p2.y]; CDVPrivate.InvertArea[me, p1.x, p2.y, p2.x, p2.y+1]; CDVPrivate.InvertArea[me, p2.x, p2.y, p2.x+1, p1.y]; CDVPrivate.InvertArea[me, p2.x, p1.y, p1.x, p1.y+1]; }; FOR l: CDViewer.ViewerList _ CDViewer.ViewersOf[me.actualDesign], l.rest WHILE l#NIL DO IF ~l.first.iconic AND l.first#me.viewer THEN OutlineViewer[me: me, other: l.first]; ENDLOOP }; PaintSignalNames: CDViewerBackdoor.FurtherPaintProc = { PaintProperties[me, $SignalName] }; PaintInstanceNames: CDViewerBackdoor.FurtherPaintProc = { PaintProperties[me, $InstanceName] }; IgnoreContext: CD.DrawContextProc = {}; PaintProperties: PROC [me: CDVPrivate.VRef, key: ATOM] = { nameDevice: REF NameDevice _ NEW[NameDevice_[propKey: key, vPriv: me]]; internalPr: CD.DrawRef = CD.CreateDrawRef[[ design: me.actualDesign, interestClip: me.dClip, devicePrivate: nameDevice, drawChild: NamedDrawChild, drawRect: CDDefaultProcs.IgnoreRect, drawContext: IgnoreContext, stopFlag: me.stoprequest ]]; Imager.SetColor[me.viewContext, Imager.black]; Imager.SetFont[me.viewContext, defaultFont]; CDOps.DrawDesign[me.actualDesign, internalPr]; }; NameDevice: TYPE = RECORD [propKey: ATOM, vPriv: CDVPrivate.VRef]; defaultFont: Imager.Font = VFonts.DefaultFont[]; NamedDrawChild: CD.DrawProc = { dev: REF NameDevice = NARROW[pr.devicePrivate]; text: Rope.ROPE _ NIL; ob.class.drawMe[pr, ob, trans, readOnlyInstProps]; WITH CDProperties.GetListProp[readOnlyInstProps, dev.propKey] SELECT FROM r: Rope.ROPE => text _ r; a: ATOM => text _ Atom.GetPName[a]; ENDCASE => NULL; IF text#NIL THEN { r: CD.Rect _ CDBasics.MapRect[CD.InterestRect[ob], trans]; p: CD.Position _ CDVScale.DesignToViewerPosition[dev.vPriv.scale, CDBasics.BaseOfRect[r]]; Imager.SetXY[dev.vPriv.viewContext, [p.x+1, p.y+1]]; Imager.SetColor[dev.vPriv.viewContext, Imager.black]; Imager.SetFont[dev.vPriv.viewContext, defaultFont]; Imager.ShowRope[dev.vPriv.viewContext, text]; }; }; DrawSignalNames: CDViewerBackdoor.FurtherPaintProc = { CDDrawQueue.QueueInsertDrawCommand[me.ct, [$SignalNames, CDBasics.universe]]; }; DrawInstanceNames: CDViewerBackdoor.FurtherPaintProc = { CDDrawQueue.QueueInsertDrawCommand[me.ct, [$InstanceNames, CDBasics.universe]]; }; UserProfile.CallWhenProfileChanges[NoteProfileChange]; CDPanel.Button[tech: NIL, button: [text: "stop"], command: $AbortCommand, queue: dontQueue, topLine: TRUE]; CDPanel.Button[tech: NIL, button: [text: "split"], proc: SplitViewer, queue: dontQueue, topLine: TRUE]; CDSequencer.ImplementCommand[$ScaleLessDetail, ScaleDown,, dontQueue]; CDSequencer.ImplementCommand[$ScaleMoreDetail, ScaleUp,, dontQueue]; CDSequencer.ImplementCommand[$MoveScreen, MoveScreenCmd,, dontQueue]; CDSequencer.ImplementCommand[$DisplayNames, SignalNames,, doQueue]; CDSequencer.ImplementCommand[$DisplayInstanceNames, InstanceNames,, doQueue]; CDSequencer.ImplementCommand[$ShowRectX, ShowRectX,, dontQueue]; CDSequencer.ImplementCommand[$ShowRect, ShowRect,, dontQueue]; CDSequencer.ImplementCommand[$ResetScaleAll, ResetScaleComm,, dontQueue]; CDSequencer.ImplementCommand[$ResetScaleTop, ResetScaleToPushedComm,, dontQueue]; CDSequencer.ImplementCommand[$ResetScaleSel, ResetScaleToSelectedComm,, dontQueue]; CDSequencer.ImplementCommand[$DisplayViewers, ShowViewersComm,, doQueue]; CDSequencer.ImplementCommand[$SplitViewer, SplitViewer,, dontQueue]; CDSequencer.ImplementCommand[$GridInfo, GridComm,, doQueue]; CDSequencer.ImplementCommand[$GridDouble, GridComm,, doQueue]; CDSequencer.ImplementCommand[$GridHalf, GridComm,, doQueue]; CDSequencer.ImplementCommand[$SetSimplification, SetSimplificationComm,, dontQueue]; CDSequencer.ImplementCommand[$RestoreScale, RestoreViewComm,, dontQueue]; CDSequencer.ImplementCommand[$SetCellSimplification, SetCellSimplification]; CDSequencer.ImplementCommand[$EnforcePanel, EnforcePanel,, doQueue]; CDSequencer.ImplementCommand[$ViewFSub, FontSubstOnComm,, dontQueue]; CDSequencer.ImplementCommand[$ViewNFSub, FontSubstOffComm,, dontQueue]; CDSequencer.ImplementCommand[$ViewEnv, DrawEnvComm,, dontQueue]; CDSequencer.ImplementCommand[$ViewNEnv, DontDrawEnvComm,, dontQueue]; CDSequencer.ImplementCommand[$ViewSym, DrawSymbolicsComm,, dontQueue]; CDSequencer.ImplementCommand[$ViewNSym, DontDrawSymbolicsComm,, dontQueue]; CDSequencer.ImplementCommand[$ViewBord, DrawBordersComm,, dontQueue]; CDSequencer.ImplementCommand[$ViewNBord, DontDrawBordersComm,, dontQueue]; CDSequencer.ImplementCommand[$MoveToGrid, MoveToGridComm, NIL, doQueue]; CDEvents.RegisterEventProc[event: $AfterOutput, proc: CheckEditedEvent]; CDEvents.RegisterEventProc[event: $CheckEdited, proc: CheckEditedEvent]; CDViewerBackdoor.InstallFurtherPaint[keyValue: $ShowViewers, proc: ShowViewers]; CDViewerBackdoor.InstallFurtherPaint[keyValue: $SignalNames, proc: PaintSignalNames]; CDViewerBackdoor.InstallFurtherPaint[keyValue: $InstanceNames, proc: PaintInstanceNames]; CDViewerBackdoor.InstallFurtherPaint[keyValue: $DrawSignalNames, proc: DrawSignalNames]; CDViewerBackdoor.InstallFurtherPaint[keyValue: $DrawInstanceNames, proc: DrawInstanceNames]; CDViewerBackdoor.InstallFurtherPaint[keyValue: $fastMoveScreen, proc: DoMoveScreen]; END. ΰCDVCommands.mesa (part of ChipNDale) Copyright c 1983, 1986, 1987 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, June 29, 1983 4:44 pm Last Edited by: Christian Jacobi, April 1, 1987 8:05:54 pm PST Some procedures by: Jean-Marc Frailong, June 3, 1987 12:30:59 pm PDT --Utilities and public --if r does not already has a CR --NO SaveScale[viewer]; it is better to have one fixed point We don't really write the scale number because the scale is changed asynchrounously and we don't really know when its done. WITH v SELECT FROM vRef: VRef => TerminalIO.PutF1[" (scale: %g)\n", IO.int[vRef.scale.nscale]]; viewer: ViewerClasses.Viewer => WriteLnScale[viewer.data]; comm: CDSequencer.Command => WriteLnScale[comm.ref]; ENDCASE => TerminalIO.PutRope["\n"]; SimpleMoveScreen: PROC [comm: CDSequencer.Command] = { Do: PROC[vRef: VRef] = { off: CD.Position; CDDrawQueue.Flush[vRef.ct]; off.x _ vRef.scale.off.x-(comm.pos.x-comm.sPos.x); off.y _ vRef.scale.off.y-(comm.pos.y-comm.sPos.y); vRef.intendedScale _ CDVScale.MakeScale[off: off,nscale: vRef.scale.nscale,grid: vRef.scale.grid]; Repaint[vRef]; }; TerminalIO.PutRope["move window\n"]; DoWithVRef[comm, Do] }; Queue a special paint request as result of the move command. Do NOT flush the queue since display might be uncomplete if repaint is interrupted now. Does the repainting associated to MoveScreenCmd. The algorithm is as follows: - Flush the queue (required because of ordering problems....) - Under VRef monitor, do: - check that the scale did not change and the offset is non-null. Quit if so. - compute offset in viewer coordinates - compute area of viewer that is part of the old and new view as the intersection between the viewer's client area and the same offsetted (dstBltRect), translate result back by the offset to get srcBltRect - Blit the right area (under Terminal lock to suppress cursor if color display) - Enumerate the rectangles of the viewer client space that need repaint, convert them back conservatively to CD coordinates - If the move could not be done fast, re-queue a regular redraw (a null move results in a full repaint to undo any wedging that might occur) and return - Set the new scale in effect - For each rectangle that needs repaint, erase it and queue a redraw command. The erasing is done first to make the display look cleaner to the user... The rectangles are erased twice, but this is necessary to avoid some wedging (pop out of cell and move fast immediately) Contains all the actions that need the VRef to be invariant. This is a conceptually part of the CDVDraw module. Convert a rectangle in viewer coordinates to its base in frame coordinates (origin at top...) Convert a viewer coordinates rectangle into a design coordinates rectangle guaranteed to be larger when mapped back, and insert it in the repaint list. Check that fast redraw is possible and consistent Compute the correct rectangles for the bit blit Do the bit-blit, while removing cursor if on color display Compute the screen rectangles that need repaint, convert them back to CD coordinates and queue them for execution Fix offset to keep stipples matching Update scale information in all concerned parties... Repaint the missing parts --gets viewer on different screen if possible, --else different viewer, if possible... --monitored by ProtectedRepaint --monitored by ProtectedRepaint --monitored by ProtectedRepaint -- called from anywhere, not monitored -- called from anywhere, not monitored --protected procedures --unprotected procedures Κq– "cedar" style˜codešœ&™&Kšœ Οmœ=™HKšœ3™3Kšœ>™>KšœD™DK˜—šΟk ˜ Kšœž˜Kšžœ˜K˜ Kšœ˜Kšœ ˜ K˜Kšœ˜K˜ K˜ Kšœ˜K˜Kšœ ˜ Kšœ ˜ Kšœ˜K˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ žœ*˜Kšžœžœžœ"˜Ašžœ˜KšœQ˜Qšžœ˜Kšœžœo˜{Kšœ˜Kšœ;ž˜?K˜K˜K˜K˜K˜K˜Kšœf˜fKšœ žœžœ7˜GKšœ žœžœ)˜9Kšœžœ˜%Kšœ@žœ˜HKšžœ ˜K˜——šžœžœ žœ˜Kšœ*žœžœ˜AKšœ)žœ$˜OK˜—Kšžœ$˜(K˜—Kšœ˜K˜—šŸœžœ ˜4Kšœ8˜8K˜K˜—K˜šŸœžœ˜:šŸœžœ˜Kšœžœ˜Kšœ˜šœ˜KšœžœW˜cKšœ)˜)Kšœc˜cK˜—šžœž˜ Kšœ'˜'Kšœ(˜(Kšœ&˜&Kšœ'˜'Kšœ'˜'Kšœ%˜%Kšžœžœ˜—Kšœ ˜ K˜—Kšœ<˜Kšœ˜Kšœ˜K˜—Kšœ8˜8šžœžœžœ˜Kšœ˜Kšœ˜K˜—Kšœ˜—K˜š€œžœ ˜>Kšœ8˜8Kšœ/˜/šžœžœžœ˜KšœžœSžœ˜^šžœžœ˜Kšœ˜Kšœ/˜/Kšœ˜Kšžœ˜K˜—K˜—Kšœ'˜'Kšœ˜—K˜š€œžœ ˜Kšœ˜K˜—Kšœ˜—K˜š€œžœ ˜5šŸœžœ˜Kšœc˜cKšœ˜—Kšœ%˜%Kšœ˜Kšœ˜—K˜š€ œžœ ˜1Kšœ%˜%Kšœ(žœ˜.Kšœ˜—K˜šŸœžœ ˜;šŸœžœ˜Kšœ&˜&š žœžœ4žœžœž˜Kšžœžœžœ˜9Kšœ žœV˜dKšœ;žœ˜AKšœ+˜+Kšœ˜—Kšžœ˜—Kšœ˜—KšœC˜CKšœ˜Kšœ˜—K˜šŸ œžœ ˜2Kšœ˜Kšœ0˜0Kšœ ˜ šžœžœžœ˜Kšžœ žœ˜&Kšžœ"˜&K˜—Kšœ˜K˜—šŸœžœ ˜5KšœI˜Išžœžœžœ˜Kšœžœ˜Kšœ>˜>Kšœ˜K˜—Kšœ˜—K˜šŸœžœ ˜6KšœO˜Ošžœžœžœ˜Kšœžœ˜Kšœ7žœ˜˜>Kšžœžœ0žœ˜Fš žœžœ4žœžœž˜Kšžœžœ˜Kšœžœ@˜GKšœ žœ3˜>Kšœ˜šžœ žœ˜Kšœ%˜%Kšœ+˜+Kšœ\˜\Kšœ+žœ˜2Kšœ˜Kšœ˜—Kšœ˜—Kšžœ˜—Kšœ[˜[Kšœ˜—K˜š€ œ'˜2Kšœ™K˜šŸ œžœ7˜JKšœžœ ˜.Kšœžœ˜KšœžœD˜JKšœžœD˜JKšœ4˜4Kšœ4˜4Kšœ4˜4Kšœ4˜4Kšœ˜—K˜šžœFžœžœž˜WKšžœžœžœ'˜TKšž˜—Kšœ˜—K˜K˜š€œ'˜7Kšœ™Kšœ ˜ Kšœ˜—K˜š€œ'˜9Kšœ™Kšœ"˜"Kšœ˜—K˜KšŸ œžœ˜'K˜šŸœžœžœ˜:Kšœ žœžœ'˜Gšœ žœ žœ˜+Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ$˜$Kšœ˜Kšœ˜Kšœ˜—Kšœ.˜.Kšœ,˜,Kšœ.˜.Kšœ˜—K™Kšœ žœžœ žœ˜BKšœ0˜0K˜šŸœ˜Kšœžœžœ˜/Kšœ žœžœ˜Kšœ2˜2šžœ:žœž˜IKšœžœ ˜Kšœžœ˜#Kšžœžœ˜—šžœžœžœ˜Kšœžœ5˜:KšœžœU˜ZKšœ4˜4Kšœ5˜5Kšœ3˜3Kšœ-˜-Kšœ˜—Kšœ˜K˜—š€œ'˜6Kšœ&™&KšœM˜MKšœ˜K˜—š€œ'˜8Kšœ&™&KšœO˜OKšœ˜—K˜K˜K˜K˜Kšœ6˜6KšœžœMžœ˜kKšœžœIžœ˜gKšœF˜FKšœD˜DKšœE˜EKšœC˜CKšœM˜MKšœ@˜@Kšœ>˜>KšœI˜IKšœQ˜QKšœS˜SKšœI˜IKšœD˜DKšœ<˜˜>Kšœ<˜