DIRECTORY Atom USING [GetPName], CD, CDDraw, CDEvents, CDExtras, CDInline, CDOrient, CDPanel, CDProperties, CDSequencer USING [Command, CommandRec, QueueCommand], CDTechnology, CDValue, CDVPrivate, CDViewer, Cursors, Graphics, GraphicsOps, Icons USING [IconFlavor, NewIconFromFile], InputFocus USING [SetInputFocus], PrincOps USING [BBTableSpace], PrincOpsUtils, Process USING [Detach, Yield, priorityNormal, priorityBackground, SetPriority], Rope USING [ROPE, Concat], RuntimeError USING [UNCAUGHT], TerminalIO, TIPUser USING [TIPScreenCoords, RegisterTIPPredicate], UserProfile, ViewerClasses, ViewerEvents USING [EventProc, RegisterEventProc], ViewerOps USING [CreateViewer, RegisterViewerClass, PaintViewer, BlinkIcon, SetNewVersion]; CDVMain: CEDAR MONITOR IMPORTS Atom, CDDraw, CDEvents, CDExtras, CDInline, CDOrient, CDPanel, CDProperties, CDSequencer, CDTechnology, CDValue, CDViewer, CDVPrivate, Graphics, Icons, InputFocus, PrincOpsUtils, Process, Rope, RuntimeError, TerminalIO, TIPUser, UserProfile, ViewerEvents, ViewerOps EXPORTS CDVPrivate = BEGIN copyright: Rope.ROPE = "Copyright (C) 1984 by Xerox Corporation. All rights reserved\n"; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- terminalLock: BOOLEAN _ FALSE; TerminalLock: PROC [] = {terminalLock _ TRUE; viewerClassRec.cursor _ questionMark}; TerminalFree: PROC [] ={terminalLock _ FALSE; viewerClassRec.cursor _ myCursor}; coordSys: ViewerClasses.CoordSys = bottom; MyGraphicRef: TYPE = CDVPrivate.MyGraphicRef; viewerClassAtom: PUBLIC ATOM = $Chipndale; myCursor: Cursors.CursorType _ IF UserProfile.Boolean["Chipndale.NoCursor", FALSE] THEN blank ELSE textPointer; TrackRef: TYPE = REF TrackRecord; --type to force cursor tracking TrackRecord: TYPE = RECORD [ pos: CD.DesignPosition ]; ArrowRef: TYPE = REF ArrowRecord; --type to force drawing an arrow ArrowRecord: TYPE = RECORD [ apos: CD.DesignPosition ]; RepaintRectAreaRef: TYPE = REF RepaintRectArea; --type to force drawing a rectangular aera RepaintRectArea: TYPE = RECORD[ rect: CD.DesignRect _ CDInline.universe, erase: BOOL _ FALSE ]; tryToPaint: CONDITION; cursoredViewer: ViewerClasses.Viewer _ NIL; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ShowViewers: PROC [me: MyGraphicRef] = BEGIN OutlineViewer: PROC [me: MyGraphicRef, other: ViewerClasses.Viewer] = BEGIN otherMe: MyGraphicRef = NARROW[other.data]; r: CD.DesignRect = otherMe.deviceDrawRef.worldClip; p1: CD.Position = CDVPrivate.DesignToViewerPosition[me, [r.x1, r.y1]]; p2: CD.Position = CDVPrivate.DesignToViewerPosition[me, [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]; END; 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 END; PaintSignalNames: PROC [me: MyGraphicRef, r: CD.DesignRect] = BEGIN DrawCommentForViewers: PROC [pos: CD.DesignPosition, text: Rope.ROPE, me: MyGraphicRef] = BEGIN tc: Graphics.Context ~ Graphics.CopyContext[me.viewerContext]; p: CD.Position ~ CDVPrivate.DesignToViewerPosition[me, pos]; Graphics.SetColor[tc, Graphics.black]; Graphics.SetCP[tc, p.x, p.y]; IF coordSys=top THEN Graphics.Scale[tc, 1, -1]; Graphics.DrawRope[tc, text]; END; design: CD.Design = me.actualDesign; r _ CDInline.Intersection[r, me.deviceDrawRef.worldClip]; FOR w: CD.ApplicationList _ design^.actual.first.specific.contents, w.rest WHILE w#NIL DO IF CDInline.Intersect[CDOrient.RectAt[w.first.location, w.first.ob.size, w.first.orientation], r] THEN BEGIN x: REF _ CDProperties.GetPropFromApplication[from: w.first, prop: $SignalName]; IF x=NIL THEN x _ CDProperties.GetPropFromObject[from: w.first.ob, prop: $SignalName]; IF x#NIL THEN { IF me.deviceDrawRef.stopFlag^ THEN EXIT; IF ISTYPE[x, Rope.ROPE] THEN { signame: Rope.ROPE = NARROW[x]; DrawCommentForViewers[w.first.location, signame, me] } ELSE IF ISTYPE[x, ATOM] THEN { a: ATOM = NARROW[x]; signame: Rope.ROPE = Atom.GetPName[a]; DrawCommentForViewers[w.first.location, signame, me] } }; END ENDLOOP; END; ShowArrow: PUBLIC PROC [design: CD.Design, pos: CD.DesignPosition] = BEGIN DoIt: PROC [] = { FOR l: MyGraphicRef _ CDVPrivate.linkBase, l.link WHILE l#NIL DO IF design=l.actualDesign THEN { l.designRec.arowAt_pos; l.designRec.arrowOn_TRUE; RETURN } ENDLOOP }; DoIt[]; CDDraw.InsertCommandAll[design, CDDraw.Comm[cmd: ref, erase: FALSE, rect: [pos.x, pos.y, 0, 0], ref: $PutArrow]] END; RemoveArrow: PUBLIC PROC[design: CD.Design] = BEGIN FOR l: MyGraphicRef _ CDVPrivate.linkBase, l.link WHILE l#NIL DO IF design=l.actualDesign THEN { r: CD.Rect ~ l.arrowRect; l.designRec.arrowOn_FALSE; IF l.arrowIsOn THEN { l.arrowIsOn _ FALSE; CDDraw.InsertCommand[l.ct, CDDraw.Comm[cmd: rect, erase: TRUE, rect: r, ref: NIL]] } } ENDLOOP END; RePaint: ViewerClasses.PaintProc = BEGIN me: MyGraphicRef = NARROW[self.data]; TrackRefTrack: ENTRY PROC [me: MyGraphicRef, tr: TrackRef] = -- INLINE -- BEGIN ENABLE UNWIND => NULL; IF me.cursorInhibitations=0 THEN { IF me.onVC THEN me.usedCursor[me] ELSE { me.startVC _ me.designRec.startLC; me.firstHorizontalVC _ me.designRec.firstHLC; me.designRec.currentLevel _ CDTechnology.CurrentLevel[me.actualDesign]; me.defaultWidthVC _ me.designRec.widthLC _ CDTechnology.LevelWidth[me.actualDesign, me.designRec.currentLevel]; me.onVC _ TRUE; }; me.usedCursor _ me.designRec.outlineProcLC; me.stopVC _ tr.pos; me.usedCursor[me]; }; END; MonitoringRemoveTrack: ENTRY PROC[me: MyGraphicRef] = BEGIN ENABLE UNWIND => NULL; IF me.onVC THEN { me.usedCursor[me]; me.onVC _ FALSE; }; END; InternalRemoveTrack: PROC[me: MyGraphicRef] = BEGIN IF me.onVC THEN { me.usedCursor[me]; me.onVC _ FALSE; }; END; SetUpAndRedraw: ENTRY PROC[me: MyGraphicRef] = BEGIN ENABLE UNWIND => NULL; ConsiderRemoveTrack: INTERNAL PROC[me: MyGraphicRef] = -- INLINE -- BEGIN me.onVC _ FALSE; END; SetOffset: PROC [me: MyGraphicRef, pos: CD.DesignPosition] = BEGIN IF me.ngrid<1 THEN ERROR; me.noff.x _ pos.x/me.ngrid*me.ngrid; me.noff.y _ pos.y/me.ngrid*me.ngrid END; comm: CDDraw.Comm; SetOffset[me, me.noff]; -- adjust gridding; replace later by better algorithm ConsiderRemoveTrack[me]; me.deviceDrawRef _ CDVPrivate.CreateDrawInformation[me]; me.saveList _ NIL; CDDraw.ModifyCommandTable[me.actualDesign, me.ct, me.deviceDrawRef.worldClip]; comm.cmd _ all; comm.erase _ TRUE; -- to allow also black backgrounds set freely by colormap comm.rect _ me.deviceDrawRef.worldClip; CDDraw.InsertCommand[me.ct, comm]; END; PaintTemporaries: --ENTRY-- PROC [me: MyGraphicRef] = BEGIN END; IF self.destroyed THEN RETURN; me.viewerContext _ context; WITH whatChanged SELECT FROM tr: TrackRef => {TrackRefTrack[me, tr]}; -- monitored by Notify atom: ATOM => IF atom=$MonitoringRemoveTrack THEN MonitoringRemoveTrack[me] ELSE IF atom=$InternalRemoveTrack THEN InternalRemoveTrack[me] -- monitored by Notify and ProtectedRepaint ELSE IF atom=$BackGround THEN { CDVPrivate.RepaintBackground[me, CDInline.universe, FALSE];-- monitored by ProtectedRepaint } ELSE IF atom=$Temporaries THEN { -- monitored by ProtectedRepaint PaintTemporaries[me]; } ELSE IF atom=$ShowViewers THEN { -- monitored by ProtectedRepaint ShowViewers[me]; } ELSE IF atom=$SignalNames THEN { -- monitored by ProtectedRepaint PaintSignalNames[me, CDInline.universe]; } ELSE IF atom=$DrawSignalNames THEN { -- called from anywhere, not monitored CDDraw.InsertCommandAll[me.actualDesign, CDDraw.Comm[cmd: ref, erase: FALSE, rect: CDInline.universe, ref: $SignalNames]]; } ELSE ERROR; area: RepaintRectAreaRef => { -- monitored by ProtectedRepaint CDVPrivate.RepaintRectAreaInViewer[me, area.rect, area.erase]; }; arrow: ArrowRef => { -- monitored by ProtectedRepaint UnGridedScaleViewerToDesign: PROC [me: MyGraphicRef, v: LONG CARDINAL] RETURNS [CD.DesignNumber] = INLINE {RETURN [LOOPHOLE[(v*me.sA+me.sE-1)/me.sE, CD.DesignNumber]]}; arrowSize: CD.DesignNumber ~ MAX[UnGridedScaleViewerToDesign[me, 20], 1]; IF me.arrowIsOn AND me.arrowRect.x1=arrow.apos.x AND me.arrowRect.y1=arrow.apos.y THEN RETURN; IF me.arrowIsOn THEN { me.arrowIsOn_FALSE; CDVPrivate.RepaintRectAreaInViewer[me, me.arrowRect, TRUE]; }; me.arrowRect _ [arrow.apos.x, arrow.apos.y, arrow.apos.x+arrowSize, arrow.apos.y+arrowSize]; me.arrowIsOn _ TRUE; CDVPrivate.RepaintRectAreaInViewer[me, me.arrowRect, FALSE]; }; ENDCASE => IF whatChanged=NIL THEN SetUpAndRedraw [me] -- called from anywhere, not monitored ELSE ERROR; END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- EnableCursoring: ENTRY PROC[me: MyGraphicRef] = BEGIN me.cursorInhibitations _ me.cursorInhibitations-1; BROADCAST tryToPaint END; ProtectedRepaint: PROC[me: MyGraphicRef, clear: BOOL, whatChanged: REF ANY] = BEGIN ENABLE RuntimeError.UNCAUGHT => { EnableCursoring[me]; IF CDVPrivate.catchAnyWhichDeadlock THEN GOTO SomeError ELSE REJECT }; DisableCursoring: ENTRY PROC[me: MyGraphicRef] = BEGIN ENABLE { UNWIND => NULL; RuntimeError.UNCAUGHT => { IF me.cursorInhibitations>0 THEN me.cursorInhibitations _ me.cursorInhibitations-1; BROADCAST tryToPaint; IF CDVPrivate.catchAnyWhichDeadlock THEN GOTO SomeError ELSE REJECT; }; }; me.cursorInhibitations _ me.cursorInhibitations+1; WHILE me.cursorInhibitations>1 DO me.cursorInhibitations _ me.cursorInhibitations-1; WAIT tryToPaint; me.cursorInhibitations _ me.cursorInhibitations+1; ENDLOOP; IF me.onVC THEN ViewerOps.PaintViewer[me.viewer, client, FALSE, $InternalRemoveTrack]; EXITS SomeError => NULL; END; DisableCursoring[me]; ViewerOps.PaintViewer[me.viewer, client, clear, whatChanged]; EnableCursoring[me]; EXITS SomeError => NULL; END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ViewerProcess: PROC[me: MyGraphicRef] = BEGIN comm: CDDraw.Comm; bBTableSpace1, bBTableSpace2: PrincOps.BBTableSpace; TRUSTED {me.xBLT _ PrincOpsUtils.AlignedBBTable[@bBTableSpace1]}; TRUSTED {me.bBLT _ PrincOpsUtils.AlignedBBTable[@bBTableSpace2]}; IF me.running THEN ERROR; me.running _ TRUE; DO comm _ CDDraw.FetchCommand[me.ct]; SELECT comm.cmd FROM none => Process.Yield[]; rect => { paintArea: RepaintRectAreaRef _ NEW[RepaintRectArea_[comm.rect, comm.erase]]; IF me.hurryUp THEN TRUSTED {Process.SetPriority[Process.priorityNormal]}; ProtectedRepaint[me, FALSE, paintArea]; }; all => { paintArea: RepaintRectAreaRef _ NEW[RepaintRectArea_[comm.rect, TRUE]]; IF me.hurryUp THEN TRUSTED {Process.SetPriority[Process.priorityNormal]}; ProtectedRepaint[me, FALSE, paintArea]; }; ref => SELECT comm.ref FROM $BackGround => ProtectedRepaint[me, FALSE, $BackGround]; $PutArrow => { ap: ArrowRef _ NEW[ArrowRecord_[apos: [comm.rect.x1, comm.rect.y1]]]; ProtectedRepaint[me, FALSE, ap]; }; $SignalNames => ProtectedRepaint[me, FALSE, $SignalNames]; $ShowViewers => ProtectedRepaint[me, FALSE, $ShowViewers]; ENDCASE => ERROR; alldone => { ProtectedRepaint[me, FALSE, $Temporaries]; me.hurryUp _ FALSE; TRUSTED {Process.SetPriority[Process.priorityBackground]}; }; disapearforever => EXIT; ENDCASE => ERROR; ENDLOOP; me.running _ FALSE; me.ct _ NIL; me.actualDesign _ NIL; me.designRec _ NIL; TerminalIO.WriteRope["Viewer destroyed\n"]; END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- MonitoringRemoveCursor: PROC [me: MyGraphicRef] = -- INLINE -- BEGIN ViewerOps.PaintViewer[me.viewer, client, FALSE, $MonitoringRemoveTrack]; END; InternalRemoveCursor: PROC [me: MyGraphicRef] = -- INLINE -- BEGIN ViewerOps.PaintViewer[me.viewer, client, FALSE, $InternalRemoveTrack]; END; Notify: ViewerClasses.NotifyProc -- PROC [self: Viewer, input: LIST OF REF ANY] -- = BEGIN ENABLE { UNWIND => NULL; RuntimeError.UNCAUGHT => IF CDVPrivate.catchAnyWhichDeadlock THEN GOTO AnyErrorHappened ELSE REJECT; }; me: MyGraphicRef = NARROW[self.data]; mouse: CD.Position; LogicalTrack: PROC [me: MyGraphicRef, pos: CD.DesignPosition] = -- INLINE -- BEGIN IF NOT me.designRec.startLCValid THEN { me.designRec.startLC _ pos; me.designRec.startLCValid _ TRUE; } END; LogicalTrackOff: PROC [me: MyGraphicRef, pos: CD.DesignPosition] = BEGIN me.designRec.stopLC _ pos; me.designRec.startLCValid _ FALSE; END; CursorSwitch: PROC [me: MyGraphicRef] = BEGIN me.firstHorizontalVC _ me.designRec.firstHLC _ NOT me.designRec.firstHLC END; CheatLogicalStartTo: PROC [me: MyGraphicRef, pos: CD.DesignPosition] = BEGIN me.designRec.startLCValid _ FALSE; LogicalTrack[me, pos]; END; Track: PROC [me: MyGraphicRef] = -- INLINE -- BEGIN VisibleTrack: PROC [me: MyGraphicRef, pos: CD.DesignPosition] = -- INLINE -- BEGIN tr: TrackRef ~ NEW[TrackRecord]; tr.pos _ pos; ViewerOps.PaintViewer[me.viewer, client, FALSE, tr]; END; pos: CD.DesignPosition = CDVPrivate.ViewerToDesignPosition[me, mouse]; LogicalTrack[me, pos]; IF me.cursorInhibitations#0 THEN RETURN; VisibleTrack[me, pos] END; StopTrack: PROC [me: MyGraphicRef] = -- XXXX -- INLINE -- BEGIN pos: CD.DesignPosition = CDVPrivate.ViewerToDesignPosition[me, mouse]; LogicalTrackOff[me, pos]; MonitoringRemoveCursor[me]; CDVPrivate.SetCursorMode[me, cShadow]; END; AngleTrack: PROC [me: MyGraphicRef] = BEGIN newStartPosition: CD.DesignPosition; comm: CDSequencer.Command ~ NEW[CDSequencer.CommandRec]; StopTrack[me]; comm^ _ CDSequencer.CommandRec[ design: me.actualDesign, a: $ContinueWire, pos: me.designRec.stopLC, sPos: me.designRec.startLC, l: me.designRec.currentLevel, n: me.defaultWidthVC, b: me.designRec.firstHLC ]; newStartPosition _ IF me.designRec.firstHLC THEN [me.designRec.stopLC.x, me.designRec.startLC.y] ELSE [me.designRec.startLC.x, me.designRec.stopLC.y]; CDSequencer.QueueCommand[design: me.actualDesign, comm: comm]; CheatLogicalStartTo[me, newStartPosition]; CursorSwitch[me]; END; StopDrawing: PROC[me: MyGraphicRef] = BEGIN CDDraw.FlushCommands[me.ct] END; IF me.deviceDrawRef=NIL THEN { RETURN; -- silly system calls notify before first paint }; IF self#cursoredViewer THEN BEGIN tem: ViewerClasses.Viewer = cursoredViewer; IF tem#NIL AND tem.data#NIL THEN { temMe: MyGraphicRef = NARROW[tem.data]; MonitoringRemoveCursor[temMe]; }; cursoredViewer _ self; SetXMode[me, me.designRec.xMode] END; FOR input _ input, input.rest WHILE input # NIL DO WITH input.first SELECT FROM coords: TIPUser.TIPScreenCoords => { mouse.x _ coords.mouseX; mouse.y _ coords.mouseY }; atom: ATOM => IF atom=$Track THEN Track[me] ELSE BEGIN me.hurryUp _ TRUE; IF terminalLock THEN { IF atom#$Track AND atom#$StopTrack THEN ViewerOps.BlinkIcon[self]; RETURN }; InputFocus.SetInputFocus[self: self]; SELECT atom FROM $StopTrack => {StopTrack[me]}; $SwitchTrack => { MonitoringRemoveCursor[me]; CursorSwitch[me] }; $AngleTrack => {AngleTrack[me]}; $UseBoxTrack => { MonitoringRemoveCursor[me]; CDVPrivate.SetCursorMode[me, cBox]; }; $UseLTrack => { MonitoringRemoveCursor[me]; CDVPrivate.SetCursorMode[me, cLBox]; }; $UseArrowTrack => { MonitoringRemoveCursor[me]; CDVPrivate.SetCursorMode[me, cArrow]; }; $UsePosTrack => { MonitoringRemoveCursor[me]; CDVPrivate.SetCursorMode[me, cPos]; }; $UseDontTrack => { MonitoringRemoveCursor[me]; CDVPrivate.SetCursorMode[me, cDont]; }; $UseShadowTrack => { MonitoringRemoveCursor[me]; CDVPrivate.SetCursorMode[me, cShadow]; }; $SetXModeOn => SetXMode[me, TRUE]; $SetXModeOff => SetXMode[me, FALSE]; $WiringOn => SetXMode[me, TRUE]; $WiringOff => SetXMode[me, FALSE]; $SetStartOnMark => {CheatLogicalStartTo[me, me.designRec.mark]}; $SetMarkOnStart => {me.designRec.mark _ me.designRec.startLC}; $SetMarkOnStop => {me.designRec.mark _ me.designRec.stopLC}; $ShowMark => { --does NO StopTrack comm: CDSequencer.Command _ NEW[CDSequencer.CommandRec]; comm^ _ CDSequencer.CommandRec[ design: me.actualDesign, a: $ShowMark, pos: me.designRec.mark, sPos: me.designRec.mark, l: me.designRec.currentLevel, ref: me, n: me.defaultWidthVC, b: me.designRec.firstHLC ]; CDSequencer.QueueCommand[design: me.actualDesign, comm: comm] }; $StopDrawing => StopDrawing[me]; ENDCASE => { comm: CDSequencer.Command _ NEW[CDSequencer.CommandRec]; StopTrack[me]; comm^ _ CDSequencer.CommandRec[ design: me.actualDesign, a: atom, pos: me.designRec.stopLC, sPos: me.designRec.startLC, l: me.designRec.currentLevel, ref: me, n: me.defaultWidthVC, b: me.designRec.firstHLC ]; CDSequencer.QueueCommand[design: me.actualDesign, comm: comm]; }; END; ENDCASE; ENDLOOP; EXITS AnyErrorHappened => NULL; END; IsTheCursor: PROC [mode: CDVPrivate.CursorMode] RETURNS [yes: BOOL_FALSE] = -- INLINE -- BEGIN ENABLE RuntimeError.UNCAUGHT => {--must have not yet been initialized-- GOTO deny}; IF cursoredViewer#NIL THEN RETURN [NARROW[cursoredViewer.data, MyGraphicRef].designRec.modeLC=mode]; EXITS deny => RETURN [FALSE] END; IsLBox: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[cLBox]]}; IsBox: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[cBox]]}; IsArrow: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[cArrow]]}; IsPos: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[cPos]]}; IsDont: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[cDont]]}; IsShadow: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[cShadow]]}; IsOther: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[cOther]]}; IsXMode: PROC RETURNS [xMode: BOOL] = {xMode _ gXMode}; IsNotXMode: PROC RETURNS [notXMode: BOOL] = {notXMode _ ~ gXMode}; SetXMode: PROC [me: MyGraphicRef, xMode: BOOL] = BEGIN gXMode _ me.designRec.xMode _ xMode END; gXMode: BOOL _ FALSE; TechnologyName: PROC [t: CD.Technology] RETURNS [Rope.ROPE] = {RETURN [IF t.name#NIL THEN t.name ELSE Atom.GetPName[t.key]]}; CaptionText: PROC [design: CD.Design] RETURNS [Rope.ROPE] = BEGIN name: Rope.ROPE; IF design=NIL THEN RETURN["nil design"]; name _ Rope.Concat[(IF design.name#NIL THEN design.name ELSE "no name"), " ("]; name _ Rope.Concat[name, TechnologyName[design.technology]]; name _ Rope.Concat[name, ") cell: "]; name _ Rope.Concat[name, CDExtras.PushedCellName[design]]; RETURN [name] END; RepaintCaptions: CDEvents.EventProc = BEGIN name: Rope.ROPE = CaptionText[design]; FOR l: CDViewer.ViewerList _ CDViewer.ViewersOf[design], l.rest WHILE l#NIL DO me: MyGraphicRef = NARROW [l.first.data]; l.first.name _ name; ViewerOps.PaintViewer[l.first, caption]; IF event=$AfterPop OR (event=$AfterPush AND me.suppressOutsidePushedCell) THEN CDDraw.InsertCommand[me.ct, CDDraw.Comm[cmd: all, erase: TRUE, rect: CDInline.universe, ref: NIL]] ELSE IF (event=$AfterPush AND ~me.suppressOutsidePushedCell) THEN CDDraw.InsertCommand[me.ct, CDDraw.Comm[cmd: ref, erase: FALSE, rect: CDInline.universe, ref: $BackGround]] ENDLOOP; END; IconForDesign: PROC [design: CD.Design] RETURNS [Icons.IconFlavor] = BEGIN x: REF = CDValue.Fetch[boundTo: design, key: $Icon, propagation: global]; WITH x SELECT FROM ip: REF Icons.IconFlavor => RETURN [ip^]; ENDCASE => RETURN [Icons.IconFlavor[unInit]] END; CreateViewer: PUBLIC PROC[design: CD.Design] RETURNS [ViewerClasses.Viewer]= BEGIN b: CD.DesignRect _ CDExtras.BoundingBox[design]; me: MyGraphicRef = CDVPrivate.NewAndLink[design]; me.ct _ CDDraw.CreateCommandTable[me.actualDesign, [1, 1, 0, 0], me.stoprequest]; TRUSTED {Process.Detach[FORK ViewerProcess[me]]}; [] _ CDPanel.CreatePanel[design]; WHILE NOT me.running DO Process.Yield[] ENDLOOP; me.viewer _ ViewerOps.CreateViewer[ flavor: viewerClassAtom, info: [ name: CaptionText[design], scrollable: FALSE, icon: IconForDesign[design], iconic: UserProfile.Boolean["Chipndale.NewViewerIconic", FALSE], border: TRUE, tipTable: CDTechnology.GetTipTable[design.technology], -- XXX whats about errors? data: me ] ]; ViewerOps.SetNewVersion[me.viewer]; IF CDInline.NonEmpty[b] THEN CDViewer.ShowAndScale[me.viewer, b]; RETURN [me.viewer] END; Destroy: ViewerClasses.DestroyProc -- PROC [self: Viewer] -- = BEGIN me: MyGraphicRef ~ NARROW[self.data]; CDVPrivate.UnLink[me]; CDDraw.DestroyCommandTable[me.ct]; self.data _ NIL END; CallOnClose: ViewerEvents.EventProc = BEGIN me: MyGraphicRef ~ NARROW[viewer.data]; IF event#close THEN ERROR; CDDraw.ModifyCommandTable[me.actualDesign, me.ct, CDInline.empty]; END; NoteProfileChange: UserProfile.ProfileChangedProc = BEGIN myCursor _ IF UserProfile.Boolean["Chipndale.NoCursor", FALSE] THEN blank ELSE textPointer; END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- viewerClassRec: ViewerClasses.ViewerClass; Init: PROC [] = BEGIN chipndaleIcon: REF Icons.IconFlavor ~ NEW[Icons.IconFlavor_tool]; TerminalIO.AddLock[TerminalLock, TerminalFree]; viewerClassRec _ NEW[ViewerClasses.ViewerClassRec _ [ paint: RePaint, notify: Notify, destroy: Destroy, coordSys: coordSys, cursor: myCursor ]]; CDValue.EnregisterKey[key: $Icon]; chipndaleIcon^ _ Icons.NewIconFromFile["Chipndale.icons", 0 ! RuntimeError.UNCAUGHT => {CONTINUE}]; CDValue.Store[boundTo: NIL, key: $Icon, value: chipndaleIcon]; ViewerOps.RegisterViewerClass[viewerClassAtom, viewerClassRec]; [] _ ViewerEvents.RegisterEventProc[proc: CallOnClose, event: close, filter: viewerClassAtom, before: FALSE]; --XXX-- TIPUser.RegisterTIPPredicate[key: $ChipndaleWMode, p: IsXMode]; --XXX-- TIPUser.RegisterTIPPredicate[key: $ChipndaleNWMode, p: IsNotXMode]; TIPUser.RegisterTIPPredicate[key: $ChipndaleXMode, p: IsXMode]; TIPUser.RegisterTIPPredicate[key: $ChipndaleNXMode, p: IsNotXMode]; TIPUser.RegisterTIPPredicate[key: $ChipndaleLBoxCursor, p: IsLBox]; TIPUser.RegisterTIPPredicate[key: $ChipndaleBoxCursor, p: IsBox]; TIPUser.RegisterTIPPredicate[key: $ChipndaleArrowCursor, p: IsArrow]; TIPUser.RegisterTIPPredicate[key: $ChipndalePosCursor, p: IsPos]; TIPUser.RegisterTIPPredicate[key: $ChipndaleDontCursor, p: IsDont]; TIPUser.RegisterTIPPredicate[key: $ChipndaleShadowCursor, p: IsShadow]; TIPUser.RegisterTIPPredicate[key: $ChipndaleOtherCursor, p: IsOther]; TerminalIO.WriteRope["\nChipndale Version 16 for Cedar 5.2; July 13, 1984 10:25:58 am PDT\n\n"]; CDEvents.RegisterEventProc[$ResetDesign, RepaintCaptions]; CDEvents.RegisterEventProc[$RenameDesign, RepaintCaptions]; CDEvents.RegisterEventProc[$AfterPush, RepaintCaptions]; CDEvents.RegisterEventProc[$AfterPop, RepaintCaptions]; UserProfile.CallWhenProfileChanges[NoteProfileChange]; END; Init[]; END. -- remarks to the tip table ChipndaleXMode and ChipndaleNXMode must NOT be querried before the focus is set, because their handling assumes a current design ”CDVMain.mesa (part of Chipndale) by Ch. Jacobi June 24, 1983 3:33 pm last edited by Christian Jacobi February 17, 1984 12:15 pm -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --redraw single features; logically inside RePaint FillOut: PROC[me: MyGraphicRef, r: CD.DesignRect] = BEGIN p1, p2: CD.Position; r _ CDInline.Intersection[r, me.deviceDrawRef.worldClip]; p1 _ CDVPrivate.DesignToViewerPosition[me, [r.x1, r.y1]]; p2 _ CDVPrivate.DesignToViewerPosition[me, [r.x2, r.y2]]; Graphics.DrawBox[me.viewerContext, Graphics.Box[p1.x, p1.y, p2.x, p2.y]]; END; --ShowArrow --PROC [self: Viewer, context: Graphics.Context, whatChanged: REF ANY, clear: BOOL]-- --depending on whatChanged, the call must be monitored or need not --must be called within monitor lock; --called through Notify only, uses monitorlock from there --now me.onVC is true --must be called within monitor lock; --called throgh Notify and ProtectedRepaint only --called through anybody anytime; --reset viewer data and then sets up a buffered request for redrawing --call this if viewer gets cleared --sets me.noff such viewer origin is simultaneus a grid point; --remove this procedure when gridding is done better --SetUpAndRedraw --eg. former paints ticks --called through ProtectedRepaint only --RePaint --without necessary translation, without gridding, rounded up --this procedure is logically local to ProtectedRepaint; --but it must be callable in catch phrase --ProtectedRepaint --me.xBLT is a short pointer! (hardware) therefore must be local to some --procedure space. --removes visible cursor, if there is --monitores inside viewerpaintproc --removes visible cursor, if there is --logically local to (Modify and Notify) --assumes monitored correctly, is INTERNAL Modify: ViewerClasses.ModifyProc -- PROC [self: Viewer, change: ModifyAction] -- = -- not an ENTRY because logically called from inside NotifyProc -- (and I hope, with its monitorlock still set and very sequentially -- [hope wrong => program wrong!]) -- therefore: keep track with cursoredViewer, and check it. BEGIN ENABLE UNWIND => NULL; SELECT change FROM set, pop => { IF cursoredViewer#NIL THEN ERROR; cursoredViewer _ self; }; kill, push => { IF self#cursoredViewer THEN ERROR; RemoveCursor[NARROW[self.data, MyGraphicRef]]; cursoredViewer_NIL; }; ENDCASE => NULL; IF cursoredViewer#NIL THEN { me: MyGraphicRef = NARROW[cursoredViewer.data, MyGraphicRef]; SetXMode[me, me.designRec.xMode]; }; END; --ENTRY may be ommitted since sequential already be viewer package ??? --sorry; this really happens because: some data is set up by the first call --of the viewerpaint procedure; but sometime the Notify procedure is called first --we will not bother every call of Notify to check for that. --makes cursor logically available --makes cursor logically unavailable --makes cursor changing dirction of L bend --makes cursor logically changing position --uses intermediate level variable mouse --makes cursor visible --Track --uses intermediate level variable mouse --Notify --silly cedar viewer system allows calls of notify before --the first call to the paintprocedure happened; --but for here, some initializations happen in paintprocedure only -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROC [event: REF, design: CD.Design, x: REF] -- --repaint captions and sometimes the contents --must wait until me.xBLT is initialized by ViewerProcess --construct the Graphic Area -- PROC [event: REF, design: CD.Design, x: REF] RETURNS [dont: BOOL_FALSE] -- PROC [reason: ProfileChangeReason] --Define viewerclass and command --modify: Modify, -- x-mode --cursormodes TerminalIO.WriteRope[copyright]; ÊX˜Jšœ"™"Jšœ$™$Jšœ<™Jš˜J˜š œœœœ˜ZJš˜J˜>Jšœœ7˜™>Jšœ4™4Jš˜Jšœ œœ˜Jšœ$˜$Jšœ#˜#Jšœ˜—J˜Jšœ™Jšœ˜JšœŸ5˜MJ˜Jšœ8˜8Jšœœ˜J˜NJšœ˜Jšœ œŸ9˜MJ˜'J˜"Jšœ˜—J˜š œŸ œœ˜5Jšœ™JšœŸœ™&Jš˜Jšœ˜—J˜Jšœ ™ Jšœœœ˜J˜šœ œ˜Jšœ*Ÿ˜@šœœ˜Jšœœ˜=JšœœœŸ,˜jšœœ˜Jšœ4œŸ ˜[J˜—šœœœŸ ˜AJ˜J˜—šœœœŸ ˜AJšœ˜J˜—šœœœŸ ˜AJšœ(˜(J˜—šœœœŸ&˜K˜)Jšœœ/˜Q—Jšœ˜—Jšœœ˜ —šœŸ ˜>Jšœ>˜>J˜—šœŸ ˜5J˜š  œœœœœœ˜cJšœ=™=Jšœœœœ˜E—J˜Jšœ œœ)˜Išœœ˜1Jšœœœ˜-—šœœ˜Jšœ œ˜Jšœ5œ˜;J˜—J˜\Jšœœ˜Jšœ5œ˜Jšœ*˜*Jšœ˜Jšœ˜J˜—š  œœ˜%Jš˜Jšœ˜Jšœ˜—Jšœ˜Jšœ™šœœœ˜Jšœ9™9Jšœ0™0JšœB™BJšœŸ/˜7J˜—šœ˜Jš˜J˜+š œœœ œœ˜"Jšœœ ˜'Jšœ˜J˜—J˜Jšœ ˜ Jšœ˜—šœœ œ˜2šœ œ˜˜$J˜J˜J˜—šœœœ œ ˜0Jš˜Jšœ œ˜šœœ˜Jšœ œœ˜CJš˜J˜—J˜%šœ˜J˜˜Jšœ˜Jšœ˜J˜—J˜ šœ˜Jšœ˜Jšœ#˜#J˜—˜Jšœ˜Jšœ$˜$J˜—˜Jšœ˜Jšœ%˜%J˜—˜Jšœ˜Jšœ#˜#J˜—˜Jšœ˜Jšœ$˜$J˜—˜Jšœ˜Jšœ&˜&J˜—Jšœœ˜"Jšœœ˜$Jšœœ˜ Jšœœ˜"Jšœ@˜@Jšœ>˜>Jšœ<˜<šœŸ˜"Jšœœ˜8šœ˜J˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜J˜J˜Jšœ˜J˜—J˜=Jšœ˜—J˜ šœ˜ Jšœœ˜8J˜˜J˜J˜Jšœ˜Jšœ˜Jšœ˜J˜J˜Jšœ˜J˜—J˜>Jšœ˜—Jšœ˜—Jšœ˜——Jšœ˜—š˜Jšœœ˜—Jšœ˜J˜—Jšœ8™8š  œœœ œ˜KJš œ˜JšœœŸ&œœ˜Sšœœœ˜Jšœœ:˜I—š˜Jšœœœ˜—Jšœ˜—J˜Jš  œœœœœ˜Jš  œœœœœ˜:Jš  œœœœœ˜J˜J˜š œœœ œ˜%Jšœ˜—J˜š  œœœ œ˜+Jšœ˜J˜—š œœœ˜0Jš˜Jšœ#˜#Jšœ˜—Jšœœœ˜Jšœ8™8J˜š  œœœ œœ˜=Jš œœœœœœ˜?J˜—š   œœ œ œœ˜;Jš˜Jšœ œ˜Jšœœœœ˜(Jš œœ œœ œ˜QJ˜=J˜'J˜:Jšœ˜ Jšœ˜J˜—šžœ˜%Jšœ3™3Jšœ-™-Jš˜Jšœ œ˜&šœ=œœ˜OJšœœ˜)J˜J˜(šœœœœ˜OJšœ9œ œ˜b—šœœœ œ˜BJšœ9œ-˜k—Jšœ˜—Jšœ˜J˜—š  œœ œ œ˜EJš˜JšœœC˜Išœœ˜Jšœœœ˜)Jšœœ˜-—Jšœ˜—J˜š   œœœ œ œ˜MJš˜Jšœœ,˜1Jšœ1˜1J˜QJšœœ˜1J˜!Jšœ9™9Jšœœ œœ˜0Jšœ™˜#Jšœ˜˜J˜Jšœ œ˜J˜Jšœ9œ˜@Jšœœ˜ Jšœ7Ÿ˜QJ˜J˜—J˜—Jšœ#˜#Jšœœ%˜AJšœ ˜Jšœ˜—J˜šžœŸœ˜?Jš˜Jšœœ ˜%Jšœ˜J˜"Jšœ ˜Jšœ˜J˜—šž œ˜%Jšœœ œ œ œœœœ™JJš˜Jšœœ˜'Jšœ œœ˜JšœB˜BJšœ˜—J˜šžœ"˜3Jšœœ™%Jš˜Jš œ œ+œœœ ˜[Jšœ˜—J˜Jš ;˜;Jšœ ™ J˜J˜*J˜š œœ˜Jš˜Jšœœœ˜AJ˜/šœœ!˜5J˜J˜Jšœ™J˜J˜Jšœ˜J˜—Jšœ"˜"šœ<˜Jšœ?˜?Jšœfœ˜mJšœ ™ JšœG˜GJšœK˜KJšœ?˜?JšœC˜CJšœ ™ JšœC˜CJšœA˜AJšœE˜EJšœA˜AJšœC˜CJšœG˜GJšœE˜EJ˜cJšœ ™ J˜:J˜;J˜8J˜7Jšœ6˜6Jšœ˜—J˜Jšœ˜Jšœ˜J˜J˜J˜J˜Jšœ(žœ˜?Jšœ3žœ˜AJ˜—…—W"ƒ