DIRECTORY CD, CDCells, CDColors, CDCommandOps, CDDrawQueue, CDEvents, CDBasics, CDPanel, CDProperties, CDSequencer USING [Command, CommandRec, ExecuteCommand], CDTipEtc, CDLayers, CDValue, CDVFurtherPainters, CDVPrivate, CDViewer, CDViewerBase, CDVScale, Cursors, DebuggerSwap USING [WorryCallDebugger], InputFocus USING [SetInputFocus], List, PrincOps USING [BBTableSpace], PrincOpsUtils, Process USING [Detach, Yield], CedarProcess USING [SetPriority, Priority], Rope USING [ROPE, Cat], RuntimeError USING [UNCAUGHT], SafeStorage USING [ReclaimCollectibleObjects], TerminalIO, TIPUser USING [TIPScreenCoords], UserProfile, ViewerClasses, ViewerEvents USING [EventProc, RegisterEventProc], ViewerOps USING [CreateViewer, RegisterViewerClass, PaintViewer, BlinkIcon, EnumProc, EnumerateViewers], WindowManager USING [colorDisplayOn]; CDVMain: CEDAR MONITOR IMPORTS CedarProcess, CD, CDCells, CDColors, CDCommandOps, CDDrawQueue, CDEvents, CDBasics, CDPanel, CDProperties, CDVFurtherPainters, CDVScale, CDSequencer, CDTipEtc, CDLayers, CDValue, CDViewer, CDViewerBase, CDVPrivate, DebuggerSwap, InputFocus, List, PrincOpsUtils, Process, Rope, RuntimeError, SafeStorage, TerminalIO, UserProfile, ViewerEvents, ViewerOps, WindowManager EXPORTS CDVPrivate SHARES CDVFurtherPainters, TerminalIO, CDDrawQueue = BEGIN greeting: Rope.ROPE = "ChipNDale Version 2.3 for Cedar 6.1 "; date: Rope.ROPE = "May 22, 1986"; copyRight: Rope.ROPE = "\nCopyright (C) 1984, 1986 by Xerox Corporation. All rights reserved.\n\n"; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- notSupportedColorMode: PUBLIC ERROR = CODE; putNewViewerOnColor: BOOL _ TRUE; allVRefs: PUBLIC LIST OF VRef _ NIL; catchCritical, catchWedging: BOOL _ TRUE; errorRef: REF _ NIL; errorMsg: Rope.ROPE _ NIL; useForShallContinue: CDVPrivate.DebugProc _ DefaultDebug; UseDebug: PUBLIC PROC [proc: CDVPrivate.DebugProc] = { useForShallContinue _ proc }; DefaultDebug: PROC [ref: REF, wedge: BOOL, msg: Rope.ROPE] RETURNS [shallCont: BOOL] = { errorRef _ ref; errorMsg _ msg; shallCont _ catchCritical OR (wedge AND catchWedging); IF ~shallCont THEN DebuggerSwap.WorryCallDebugger["ChipNDale wedge"]; }; ShallContinue: PUBLIC PROC [ref: REF_NIL, wedge: BOOL_FALSE, msg: Rope.ROPE_NIL] RETURNS [yes: BOOL_TRUE] = { sc: CDVPrivate.DebugProc _ useForShallContinue; IF sc#NIL THEN yes _ sc[ref, wedge, msg]; }; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- viewerClassAtom: ATOM = $ChipNDale; VRef: TYPE = CDVPrivate.VRef; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- terminalLock: BOOL _ FALSE; TerminalLock: PROC [] = { terminalLock _ TRUE; viewerClassRec.cursor _ cursorWhileInput }; TerminalFree: PROC [] ={ terminalLock _ FALSE; SetCursor[] }; TrackRef: TYPE = REF TrackRecord; TrackRecord: TYPE = RECORD [ pos: CD.Position ]; track: TrackRef _ NIL; GetTrackRef: PROC [p: CD.Position] RETURNS [t: TrackRef] = INLINE { t _ track; track _ NIL; IF t=NIL THEN t _ NEW[TrackRecord]; t.pos _ p }; DisposeTrackRef: PROC [t: TrackRef] = INLINE { track _ t }; RepaintRectAreaRef: TYPE = REF RepaintRectArea; RepaintRectArea: TYPE = RECORD[ rect: CD.Rect _ CDBasics.universe, erase: BOOL _ FALSE ]; tryToPaint: CONDITION; viewerClassRec: ViewerClasses.ViewerClass _ NEW[ViewerClasses.ViewerClassRec _ [ paint: PaintViewer, notify: NotifyViewer, modify: ModifyViewer, destroy: DestroyViewer, set: CDViewerBase.SetProc, get: CDViewerBase.GetProc, cursor: cursorNoFocus ]]; cursoredCDViewer: PUBLIC ViewerClasses.Viewer _ NIL; inputFocussedViewer: ViewerClasses.Viewer _ NIL; lastInputFocussedViewer: ViewerClasses.Viewer _ NIL; cursorWithFocus: Cursors.CursorType = textPointer; cursorNoFocus: Cursors.CursorType = pointDown; cursorWhileInput: Cursors.CursorType = questionMark; SetCursor: PROC [] = INLINE { viewerClassRec.cursor _ IF terminalLock THEN cursorWhileInput ELSE IF cursoredCDViewer=inputFocussedViewer THEN cursorWithFocus ELSE cursorNoFocus; }; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- LastViewer: PUBLIC PROC [] RETURNS [ViewerClasses.Viewer] = BEGIN RETURN [lastInputFocussedViewer] END; SetUpAndRedraw: ENTRY PROC[me: VRef] = BEGIN ENABLE UNWIND => NULL; IF me=NIL THEN RETURN WITH ERROR CD.Error[]; CDDrawQueue.Flush[me.ct]; me.onVC _ FALSE; --erasing viewer automaticaly makes cursor invisible CDVPrivate.CreateDrawInformation[me]; CDDrawQueue.ChangeClipArea[me.ct, me.dClip]; CDDrawQueue.QueueInsertDrawCommand[me.ct, CDDrawQueue.Request[$redraw, CDBasics.universe]]; END; PaintViewer: ViewerClasses.PaintProc = BEGIN ENABLE { CDVPrivate.notSupportedColorMode => GOTO oops; RuntimeError.UNCAUGHT => IF ShallContinue[self, TRUE, "CDVMain.PV"] THEN GOTO oops ELSE REJECT; }; me: VRef = NARROW[self.data]; TrackRefTrack: ENTRY PROC [me: VRef, 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.currentLayer _ CDLayers.CurrentLayer[me.actualDesign]; me.defaultWidthVC _ me.designRec.widthLC _ CDLayers.LayerWidth[me.actualDesign, me.designRec.currentLayer]; me.onVC _ TRUE; }; me.usedCursor _ me.designRec.outlineProcLC; me.stopVC _ tr.pos; me.usedCursor[me]; }; DisposeTrackRef[tr]; END; RemoveTrack: ENTRY PROC[me: VRef] = INLINE BEGIN ENABLE UNWIND => NULL; IF me.onVC THEN { me.usedCursor[me]; me.onVC _ FALSE; }; END; IF self.destroyed THEN RETURN; me.viewContext _ context; WITH whatChanged SELECT FROM tr: TrackRef => TrackRefTrack[me, tr]; -- called by NotifyViewer atom: ATOM => { IF atom=$RemoveTrack THEN RemoveTrack[me] ELSE CDVFurtherPainters.CallFurther[me, atom]; -- called from anywhere, maybe not protected }; area: RepaintRectAreaRef => -- protected by ProtectedRepaint CDVPrivate.RepaintRectAreaInViewer[me, area.rect, area.erase]; ENDCASE => { IF whatChanged=NIL THEN { IF me.viewer#self THEN RETURN; --initialization not finished SetUpAndRedraw[me] -- called from anywhere, maybe not protected } ELSE CDVFurtherPainters.CallFurther[me, whatChanged]; } EXITS oops => NULL; END; Flushed: CDVFurtherPainters.FurtherPaintProc = -- PROC [me: CDVPrivate.VRef, key: REF] BEGIN CDDrawQueue.Flush[me.ct]; me.scale _ me.intendedScale; SetUpAndRedraw[me]; END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- EnableCursoring: ENTRY PROC[me: VRef] = INLINE BEGIN ENABLE UNWIND => NULL; me.cursorInhibitations _ me.cursorInhibitations-1; BROADCAST tryToPaint END; ProtectedRepaint: PROC[me: VRef, whatChanged: REF ANY] = BEGIN ENABLE RuntimeError.UNCAUGHT => { EnableCursoring[me]; IF ShallContinue[me, TRUE, "CDVMain.PR"] THEN GOTO oops ELSE REJECT }; DisableCursoring: ENTRY PROC[me: VRef] RETURNS [mustRemoveCursor: BOOL] = INLINE BEGIN ENABLE UNWIND => NULL; me.cursorInhibitations _ me.cursorInhibitations+1; WHILE me.cursorInhibitations>1 DO me.cursorInhibitations _ me.cursorInhibitations-1; WAIT tryToPaint; me.cursorInhibitations _ me.cursorInhibitations+1; ENDLOOP; mustRemoveCursor _ me.onVC; END; IF DisableCursoring[me].mustRemoveCursor THEN RemoveCursor[me]; ViewerOps.PaintViewer[me.viewer, client, FALSE, whatChanged ! RuntimeError.UNCAUGHT => IF ShallContinue[me, TRUE, "CDVMain.PR2"] THEN CONTINUE ]; EnableCursoring[me]; EXITS oops => NULL; END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ViewerProcess: PROC[me: VRef] = BEGIN comm: REF CDDrawQueue.Request = NEW[CDDrawQueue.Request]; bBTableSpace1, bBTableSpace2: PrincOps.BBTableSpace; IF me.running THEN ERROR; TRUSTED { me.pBBptr _ PrincOpsUtils.AlignedBBTable[@bBTableSpace1]; me.xBBptr _ PrincOpsUtils.AlignedBBTable[@bBTableSpace2]; }; me.running _ TRUE; DO comm^ _ CDDrawQueue.FetchCommand[me.ct]; SELECT comm.key FROM $redraw => { paintArea: RepaintRectAreaRef = NEW[RepaintRectArea_[comm.rect, TRUE]]; ProtectedRepaint[me, paintArea]; }; $draw => { paintArea: RepaintRectAreaRef = NEW[RepaintRectArea_[comm.rect, FALSE]]; ProtectedRepaint[me, paintArea]; }; CDDrawQueue.queueEmpty => { ProtectedRepaint[me, $Temporaries]; CedarProcess.SetPriority[CedarProcess.Priority[background]]; SafeStorage.ReclaimCollectibleObjects[suspendMe: FALSE]; }; CDDrawQueue.finishedForEver => EXIT; ENDCASE => ProtectedRepaint[me, comm]; ENDLOOP; TerminalIO.WriteRope["Viewer destroyed\n"]; me.running _ FALSE; me.ct _ NIL; me.actualDesign _ NIL; me.deviceDrawRef _ NIL; me.painterList _ NIL; me.properties _ NIL; END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- SlowDown: PROC [v: ViewerClasses.Viewer] = BEGIN IF v#NIL THEN WITH v.data SELECT FROM me: VRef => { me.hurryUp _ FALSE; me.slowDown _ TRUE; me.check _ TRUE; me.deviceDrawRef.checkPriority _ TRUE; }; ENDCASE => NULL; END; SpeedUp: PROC [v: ViewerClasses.Viewer] = BEGIN IF v#NIL THEN WITH v.data SELECT FROM me: VRef => { me.slowDown _ FALSE; me.hurryUp _ TRUE; me.check _ TRUE; me.deviceDrawRef.checkPriority _ TRUE; }; ENDCASE => NULL; END; RemoveCursor: PROC [me: VRef] = INLINE BEGIN IF me.onVC THEN ViewerOps.PaintViewer[me.viewer, client, FALSE, $RemoveTrack ! RuntimeError.UNCAUGHT => IF ShallContinue[me, TRUE, "CDVMain.RC"] THEN CONTINUE ]; END; ModifyViewer: ViewerClasses.ModifyProc = -- PROC [self: Viewer, change: ModifyAction] BEGIN ENABLE UNWIND => NULL; SELECT change FROM set, pop => lastInputFocussedViewer _ inputFocussedViewer _ self; kill, push => inputFocussedViewer _ NIL; ENDCASE => NULL; SetCursor[]; END; NotifyViewer: ViewerClasses.NotifyProc = -- PROC [self: Viewer, input: LIST OF REF ANY] BEGIN ENABLE RuntimeError.UNCAUGHT => IF ShallContinue[self, TRUE, "CDVMain.Notify"] THEN GOTO oops ELSE REJECT; me: VRef = NARROW[self.data]; mouse: CD.Position _ [0, 0]; --initialize, there are crazy tiptables. LogicalTrack: PROC [me: VRef, pos: CD.Position] = INLINE BEGIN IF NOT me.designRec.startLCValid THEN { me.designRec.startLC _ pos; me.designRec.startLCValid _ TRUE; } END; LogicalTrackOff: PROC [me: VRef, pos: CD.Position] = INLINE BEGIN me.designRec.stopLC _ pos; me.designRec.startLCValid _ FALSE; END; Track: PROC [me: VRef] = INLINE BEGIN VisibleTrack: PROC [me: VRef, pos: CD.Position] = INLINE BEGIN ViewerOps.PaintViewer[me.viewer, client, FALSE, GetTrackRef[pos] ]; END; pos: CD.Position = CDVScale.ViewerToDesignPosition[me.scale, mouse]; LogicalTrack[me, pos]; IF me.cursorInhibitations=0 THEN VisibleTrack[me, pos]; END; StopTrack: PROC [me: VRef] = BEGIN pos: CD.Position = CDVScale.ViewerToDesignPosition[me.scale, mouse]; me.hurryUp _ TRUE; LogicalTrackOff[me, pos]; RemoveCursor[me]; CDVPrivate.SetCursorMode[me, NIL]; END; IF self#cursoredCDViewer THEN { tem: ViewerClasses.Viewer = cursoredCDViewer; IF me.deviceDrawRef=NIL THEN { RETURN }; IF tem#NIL AND tem.data#NIL THEN RemoveCursor[NARROW[tem.data, VRef]]; cursoredCDViewer _ self; SetCursor[]; }; WHILE input#NIL DO WITH input.first SELECT FROM atom: ATOM => { IF atom=$Track THEN Track[me] ELSE IF atom=$StopTrack THEN StopTrack[me] ELSE IF terminalLock THEN { IF atom#$UseCursor THEN ViewerOps.BlinkIcon[viewer: self, millisecondsPerBlink: 100]; RETURN; } ELSE { IF self#inputFocussedViewer THEN { SlowDown[inputFocussedViewer]; InputFocus.SetInputFocus[self]; SpeedUp[self]; IF atom=$CloseReSelectOnlyP THEN RETURN; }; IF atom=$UseCursor THEN { --command involving 2 atoms RemoveCursor[me]; input _ input.rest; IF input=NIL THEN RETURN; CDVPrivate.SetCursorMode[me, input.first] } ELSE { -- all other (standard) commands StopTrack[me]; TRUSTED {Process.Detach[ FORK CDSequencer.ExecuteCommand[ design: me.actualDesign, comm: NEW[CDSequencer.CommandRec _ CDSequencer.CommandRec[ design: me.actualDesign, key: atom, pos: me.designRec.stopLC, sPos: me.designRec.startLC, l: me.designRec.currentLayer, ref: me, n: me.defaultWidthVC, b: me.designRec.firstHLC ]] ] ]}; }; }; }; coords: TIPUser.TIPScreenCoords => { mouse.x _ MIN[MAX[coords.mouseX, 0], me.viewer.cw-1]; mouse.y _ MIN[MAX[coords.mouseY, 0], me.viewer.ch-1]; }; ENDCASE => NULL; input _ input.rest ENDLOOP; EXITS oops => NULL; END; Caption: PROC [design: CD.Design] RETURNS [Rope.ROPE] = BEGIN IF design=NIL THEN RETURN["nil design"] ELSE RETURN [Rope.Cat[ (IF design.name#NIL THEN design.name ELSE "no name"), " (", design.technology.name, ") cell: ", CDCells.PushedCellName[design] ]] END; CDEventHappened: CDEvents.EventProc = BEGIN name: Rope.ROPE = Caption[design]; FOR l: CDViewer.ViewerList _ CDViewer.ViewersOf[design], l.rest WHILE l#NIL DO me: VRef = NARROW[l.first.data]; l.first.name _ name; ViewerOps.PaintViewer[l.first, caption]; IF event=$AfterPop OR event=$AfterPush THEN { CDDrawQueue.QueueInsertDrawCommand[me.ct, CDDrawQueue.Request[$redraw, CDBasics.universe]] } ENDLOOP; END; IsNewVersion: PROC [design: CD.Design] RETURNS [newVersion: BOOL_FALSE] = BEGIN vList: CDViewer.ViewerList _ CDViewer.ViewersOf[design]; IF vList=NIL THEN RETURN [ CDValue.Fetch[design, $CDxNewVersion]=$T ]; FOR vl: CDViewer.ViewerList _ vList, vl.rest WHILE vl#NIL DO IF vl.first.newVersion THEN { CDValue.Store[design, $CDxNewVersion, $T]; RETURN [TRUE] } ENDLOOP; CDValue.Store[design, $CDxNewVersion, NIL]; END; CreateViewer: PUBLIC PROC[design: CD.Design] RETURNS [v: ViewerClasses.Viewer]= BEGIN bb: CD.Rect = CDCommandOps.BoundingBox[design, FALSE]; me: VRef = New[design]; TRUSTED {Process.Detach[FORK ViewerProcess[me]]}; [] _ CDPanel.CreatePanel[design]; WHILE NOT me.running DO Process.Yield[] ENDLOOP; v _ me.viewer _ ViewerOps.CreateViewer[ flavor: viewerClassAtom, info: [ name: Caption[design], scrollable: FALSE, icon: CDTipEtc.GetIcon[design], iconic: FALSE, column: ColumnForNewViewer[], tipTable: CDTipEtc.GetTipTable[design], newVersion: IsNewVersion[design], data: me ], paint: TRUE --sorry, must check elsewhere for this case, otherwise viewerpackage blusters ]; me.dClip _ CDVScale.GetClipRecord[me.intendedScale, v.cw, v.ch]; IF CDBasics.NonEmpty[bb] THEN { CDViewer.ShowAndScale[v, bb]; CDDrawQueue.Flush[me.ct]; --I don't trust me me.scale _ me.intendedScale; me.dClip _ CDVScale.GetClipRecord[me.intendedScale, v.cw, v.ch]; }; CDDrawQueue.Flush[me.ct]; --I don't trust me CDDrawQueue.ChangeClipArea[me.ct, me.dClip]; ViewerOps.PaintViewer[v, all]; EnableCursoring[me]; Include[me]; END; ColumnForNewViewer: PROC [] RETURNS [col: ViewerClasses.Column_left] = BEGIN colorDisplayEmpty: BOOL _ TRUE; CheckColorScreen: ViewerOps.EnumProc = {-- PROC [v: Viewer] RETURNS [BOOL _ TRUE] IF v.column=color AND ~v.iconic AND ~v.offDeskTop THEN RETURN [colorDisplayEmpty _ FALSE] }; IF WindowManager.colorDisplayOn AND putNewViewerOnColor THEN { ViewerOps.EnumerateViewers[CheckColorScreen]; IF colorDisplayEmpty THEN col _ color } END; DestroyViewer: ViewerClasses.DestroyProc = BEGIN vRef: VRef ~ NARROW[self.data]; CDValue.Store[vRef.actualDesign, $CDxNewVersion, (IF self.newVersion THEN $T ELSE NIL)]; Destroy[vRef]; self.data _ NIL; END; ViewerCorDEvent: ViewerEvents.EventProc = BEGIN vRef: VRef ~ NARROW[viewer.data]; CDDrawQueue.ChangeClipArea[vRef.ct, CDBasics.empty]; END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- New: PUBLIC ENTRY PROC [design: CD.Design] RETURNS [me: VRef_NIL] = BEGIN ENABLE UNWIND => NULL; NewScale: PROC [design: CD.Design] RETURNS [CDVScale.ScaleRec] = BEGIN scale: INT = CDValue.FetchInt[boundTo: design, key: $CDxInitScale, propagation: global, ifNotFound: 6]; grid: INT = CDValue.FetchInt[boundTo: design, key: $CDxInitGrid, propagation: global, ifNotFound: design.technology.lambda]; RETURN [ CDVScale.MakeScale[ nscale: MIN[MAX[scale, 0], CDVScale.scaleNum-1], grid: MIN[MAX[grid, 0], 512], off: [0, 0] ]]; END; InitDesignRec: PROC [me: VRef] = BEGIN FOR l: LIST OF VRef _ allVRefs, l.rest WHILE l#NIL DO IF me.actualDesign=l.first.actualDesign THEN { me.designRec _ l.first.designRec; RETURN }; ENDLOOP; me.designRec _ NEW[CDVPrivate.VPrivatePerDesign _ [ outlineProcLC: CDVPrivate.DefaultOutLine, currentLayer: CD.errorLayer ]]; CDVPrivate.SetCursorMode[me, NIL]; END; InitVRef: PROC [design: CD.Design] RETURNS [me: VRef] = BEGIN b: REF BOOL = NEW[BOOL_FALSE]; me _ NEW[CDVPrivate.VRec _ [ actualDesign: design, ct: CDDrawQueue.Create[design, b, CDBasics.empty], scale: NewScale[design], dClip: CDBasics.empty, intendedScale: NewScale[design], stoprequest: b, environment: CDProperties.GetDesignProp[design, $CDxDrawEnvironment]#$FALSE, symbolics: CDProperties.GetDesignProp[design, $CDxDrawSymbolics]#$FALSE, borders: CDProperties.GetDesignProp[design, $CDxSkipBorder]=$FALSE, personalColors: CDColors.globalColors, cursorInhibitations: 1, --disabled, not yet ready properties: CD.InitPropRef[] ]]; InitDesignRec[me]; END; me _ InitVRef[design]; END; Include: ENTRY PROC [me: VRef] = { allVRefs _ CONS[me, allVRefs]; }; Destroy: PUBLIC ENTRY PROC [me: VRef] = TRUSTED BEGIN ENABLE UNWIND => NULL; IF me#NIL THEN { allVRefs _ LOOPHOLE[List.DRemove[ref: me, list: LOOPHOLE[allVRefs]]]; CDDrawQueue.Destroy[me.ct]; } END; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- NoteProfileChange: UserProfile.ProfileChangedProc = BEGIN catchCritical _ UserProfile.Boolean["ChipNDale.CatchLowLevelErrors", TRUE]; catchWedging _ catchCritical OR UserProfile.Boolean["ChipNDale.CatchErrorsWhichCauseDeadlock", TRUE]; putNewViewerOnColor _ UserProfile.Boolean["ChipNDale.FirstViewerOnColor", TRUE]; END; UserProfile.CallWhenProfileChanges[NoteProfileChange]; TerminalIO.AddLock[TerminalLock, TerminalFree]; CDVFurtherPainters.InstallFurtherPaint[keyValue: $changeScale, proc: Flushed]; CDVFurtherPainters.InstallFurtherPaint[keyValue: $flushed, proc: Flushed]; CDEvents.RegisterEventProc[$ResetDesign, CDEventHappened]; CDEvents.RegisterEventProc[$RenameDesign, CDEventHappened]; CDEvents.RegisterEventProc[$AfterPush, CDEventHappened]; CDEvents.RegisterEventProc[$AfterPop, CDEventHappened]; ViewerOps.RegisterViewerClass[viewerClassAtom, viewerClassRec]; [] _ ViewerEvents.RegisterEventProc[proc: ViewerCorDEvent, event: close, filter: viewerClassAtom, before: TRUE]; [] _ ViewerEvents.RegisterEventProc[proc: ViewerCorDEvent, event: destroy, filter: viewerClassAtom, before: TRUE]; TerminalIO.WriteRopes[greeting, date, copyRight]; END. ®CDVMain.mesa (part of ChipNDale) Copyright c 1983, 1986 by Xerox Corporation. All rights reserved. Ch. Jacobi, June 24, 1983 3:33 pm last edited by Christian Jacobi, May 22, 1986 3:17:13 pm PDT gbb April 8, 1986 5:46:39 pm PST --monitoring rule: aquire the ViewerLock first, the monitor's entry lock only after. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- types used for parameters to the viewer paint procedure --TrackRef: type to force cursor tracking --the Get and Dispose proc's are a hack to reduce the memory allocator's work --may be called by viewers NotifyViewer proc only; monitored through viewers NotifyViewer proc --RepaintRectAreaRef: type to force drawing a rectangular aera -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --logically inside the viewer's paint proc; --reset viewer data and then sets up a buffered request for redrawing -- erase to allow also backgrounds of arbitrary patterns or colors --PROC [self: Viewer, context: Imager.Context, whatChanged: REF ANY, clear: BOOL] --depending on whatChanged, the call must be protected or need not. --Never call with modules entry monitor lock set. --me ABSOLUTELY never NIL {proc is local} --Proof hints: me.onVC initialized false; me.usedCursor not accessed outside -- CDVMains monitorlock (use Grep) --now me.onVC is true --me ABSOLUTELY never NIL {proc is local} --PaintViewer --here it would have trapped if me=NIL -- logicaly local to viewers paint proc (PaintViewer) --logically local to ProtectedRepaint and initialization-- --me never nil-- --logically local to ProtectedRepaint --is outside to make callable from catch-phrase and initialization --does: --remove cursor and disables any cursoring process --let only one client come through --Caller must guarantee me#NIL (Use find; {proc neither exported nor assigned to variable}) --and enters protected region. --me never nil; guaranteed from caller {proc is local} --ProtectedRepaint --me.fooBBptr is a short pointer! (hardware) therefore must be local to some procedure space. --do the garbage collection now, when not to much else is to do, --and also all the allocations of the drawing can be freed --order important --order important --removes visible cursor, if there is --monitores inside viewerpaintproc -- ENTRY ommitted since sequential already by viewer package --makes cursor logically available --makes cursor logically unavailable --uses intermediate layer variable mouse --makes cursor visible --Track --uses intermediate layer variable mouse --NotifyViewer --silly Cedar Viewer package allows calls of notify before --the first call to the paint procedure happened; --but in ChipNDale, some initializations happens in paintprocedure only. --luckily at that time cursoredCDViewer#self; so here is the only --place to check. -- range test, -- [some crazy tiptables use coords without having had a mouse action first] -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- PROC [event: REF, design: CD.Design, x: REF] -- repaint captions and sometimes the contents --redraw everything, because -- after pop: cell change may have propagated -- after push: background features must be redrawn greyish --must wait until me.fooBBLT is initialized by ViewerProcess paint: FALSE --important: me.viewer is initialized only after return --but redraw does not yet come through... (clip area empty!) --selects colordisplay if it is on and free -- PROC [viewer: Viewer, event: ViewerEvent, before: BOOL] RETURNS [abort: BOOL _ FALSE] --New --all critical work is done in procedures, so UNWIND really should work -- PROC [reason: ProfileChangeReason] gbb April 4, 1986 6:26:26 pm PST Changed first line written in Terminal. Êâ˜codešœ"™"Kšœ Ïmœ7™BKšœ"™"Kšœ=™=K™ —K˜šÏk ˜ Kšžœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ K˜ K˜ K˜Kšœ ˜ Kšœ žœ'˜8K˜ Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ K˜Kšœ'˜'Kšœ žœ˜!Kšœ˜Kšœ žœ˜Kšœ˜Kšœžœ˜Kšœ žœ˜+Kšœžœžœ˜Kšœ žœžœ˜Kšœ žœ˜.Kšœ ˜ Kšœžœ˜ Kšœ ˜ Kšœ˜Kšœ žœ ˜2Kšœ žœY˜hKšœžœ˜%—K˜šÐblœžœžœ˜KšœT™Tšžœ˜Kšœð˜ð—Kšžœ ˜Kšžœ.˜4—Kšž˜K˜Kšœžœ-˜@Kšœ žœ˜!KšœžœP˜dK˜KšÏcœ œ œ œ œ œ œ œ ˜5K˜Kšœžœžœžœ˜+Kšœžœžœ˜!K˜Kš œ žœžœžœžœ˜$K˜Kšœžœžœ˜)Kšœ žœžœ˜Kšœžœžœ˜Kšœ9˜9K˜šÏnœž œ!˜6Kšœ˜Kšœ˜K˜—š¡ œžœžœ žœ žœžœ žœ˜XJšœ˜Jšœ˜Jšœžœžœ˜6šžœ ž˜Jšœ2˜2—J˜—K˜š¡ œžœžœžœžœ žœžœ žœžœžœžœžœ˜mJšœ/˜/Jšžœžœžœ˜)J˜—K˜Kš œ œ œ œ œ œ œ œ ˜5K˜Kšœžœ˜#Kšœžœ˜K˜Kš œ œ œ œ œ œ œ œ ˜5K˜Kšœžœžœ˜K˜š¡ œžœ˜Kšœžœ˜Kšœ(˜(Kšœ˜—K˜š¡ œžœ˜Kšœž˜Kšœ ˜ Kšœ˜—K˜Kšœ2™2K™:K˜Kšœ)™)˜Kšœ žœžœ˜"šœ žœžœ˜Kšœžœ ˜K˜—K˜KšœN™NKšœžœ˜K˜š ¡ œžœžœ žœžœ˜CKšœ^™^Kšœžœ˜Kš žœžœžœžœžœ˜#Kšœ ˜ K˜—K˜š¡œžœžœ˜.Kšœ ˜ K˜—K˜—Kšœ?™?˜Kšœžœžœ˜0šœžœžœ˜Kšœžœ˜"Kšœžœž˜K˜——K™Kšœ2™2K˜Kšœ ž œ˜K˜šœ,žœ!˜PKšœ˜Kšœ˜Kšœ˜K˜Kšœ˜Kšœ˜Kšœ˜K˜—K™Kšœ2™2K˜Kšœžœžœ˜4Kšœ,žœ˜0Kšœ0žœ˜4˜Kšœ2˜2Kšœ.˜.Kšœ4˜4—K˜š¡ œžœžœ˜šœ˜Kšžœžœ˜%Kšžœžœ&žœ˜AKšžœ˜—K˜—K˜Kšœ5˜5K˜š¡ œžœžœžœ˜;Kšž˜Kšžœ˜ Kšžœ˜—K˜K˜š¡œžœžœ ˜'Kšœ+™+K™EKšžœžœžœžœ˜Kšžœžœžœžœžœžœžœ ˜,Kšœ˜Kšœ žœ 4˜FKšœ%˜%šœ,˜,KšœB™B—Kšœ[˜[Kšžœ˜—K˜šÏb œ˜&KšœQ™QKšœC™CKšœ1™1šž˜šžœ˜Kšœ$žœ˜.šœ žœ˜Kš žœžœžœžœžœžœ˜F—K˜——Kšœ žœ ˜K˜š¡ œžœžœžœ˜=Kšœ)™)Kšžœžœžœžœ˜šžœžœ˜"KšœM™MKšœ"™"Kšžœ žœ˜!šžœ˜Kšœ"˜"Kšœ.˜.KšœC˜Cšœ*˜*Kšœ@˜@—Kšœ žœ˜K˜—Kšœ™Kšœ+˜+Kšœ˜K˜K˜—Kšœ˜Kšžœ˜K˜—š¡ œžœžœ ž˜*Kšœ*™*Kšžœžœžœžœ˜šžœ žœ˜K˜Kšœ žœ˜K˜—Kšžœ˜—K˜Kšœ ™ Kšžœžœžœ˜šœ˜Kšœ  ™&—šžœ žœž˜Kšœ' ˜@šœžœ˜Kšžœžœ˜)Kšžœ+ ,˜[K˜—šœ  ˜˜>—šžœ˜ šžœ žœžœ˜Kšžœžœžœ ˜˜>—Kšž˜Kšœ˜—šžœ˜šžœžœ˜"Kšœ˜Kšœ˜Kšœ˜Kšžœžœžœ˜)K˜—šžœžœ ˜5Kšœ˜Kš œžœžœžœžœ˜.Kšœ)˜)K˜—šžœ  ˜'K˜šžœ˜šžœ˜ Kšœ˜šœžœ1˜:K˜K˜ Kšœ˜Kšœ˜Kšœ˜K˜K˜Kšœ˜Kšœ˜—Kšœ˜—Kšœ˜—Kšœ˜—Kšœ˜—K˜—˜$Kšœ™KšœM™MKšœ žœžœ%˜6Kšœ žœžœ$˜5K˜—Kšžœžœ˜—Kšœ˜Kšžœ˜—Kšžœ žœ˜Kšžœ˜—K˜Kšœ8™8K˜š ¡œžœ žœ žœžœ˜7Kšž˜Kšžœžœžœžœ˜'šžœžœ ˜Kš œžœ žœžœ žœ ˜6Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšžœ˜K˜—š¢œ˜%Kšœ0™0Kšœ.™.Kšž˜Kšœ žœ˜"šžœ=žœžœž˜NKšœ žœ˜ K˜K˜(šžœžœžœ˜.Kšœ™Kšœ.™.Kšœ;™;KšœZ˜ZK˜—Kšžœ˜—Kšžœ˜K˜—š ¡ œžœ žœ žœžœžœ˜IKšž˜Kšœ8˜8Kšžœžœžœžœ.˜Fšžœ*žœžœž˜<šžœžœ˜Kšœ*˜*Kšžœžœ˜ K˜—Kšžœ˜—Kšœ&žœ˜+Kšžœ˜—K˜š ¡ œžœžœ žœ žœ˜PKšž˜Kšœžœ)žœ˜7Kšœ˜Kšžœžœ˜1K˜!Kšœ<™