DIRECTORY Atom, CD, CDApplications, CDSimpleOps, CDCells, CDDraw, CDEvents, CDBasics, CDOps, CDOrient, CDValue, Rope USING [ROPE], SymTab; CDOpsImpl: CEDAR MONITOR IMPORTS Atom, CD, CDApplications, CDCells, CDSimpleOps, CDDraw, CDEvents, CDBasics, CDOps, CDOrient, CDValue, SymTab EXPORTS CDOps SHARES CD = BEGIN createEvent: CDEvents.EventRegistration=CDEvents.RegisterEventType[$CreateNewDesign]; resetDesignEvent: CDEvents.EventRegistration=CDEvents.RegisterEventType[$ResetDesign]; DelRec: TYPE = RECORD [ delayedList: LIST OF Remember_NIL, length: INT _ 0 ]; GetDelRec: PROC [design: CD.Design] RETURNS [REF DelRec] = BEGIN x: REF _ CDValue.Fetch[boundTo: design, key: $CDxDeleted, propagation: design]; IF x#NIL AND ISTYPE[x, REF DelRec] THEN RETURN [NARROW[x]] ELSE { dr: REF DelRec = NEW[DelRec_[NIL]]; CDValue.Store[design, $CDxDeleted, dr]; RETURN [dr] } END; Remember: TYPE = RECORD [area: CD.DesignRect, clear: BOOL]; InternalResetDesign: PROC[design: CD.Design] = BEGIN dummy: CD.ObPtr _ CDCells.CreateEmptyCell[]; dummy.size _ CDBasics.highposition; design.cellDirectory _ SymTab.Create[97]; design^.actual _ LIST[CD.PushRec[ dummyCell: CDApplications.NewApplicationI[ob: dummy], mightReplace: NIL, specific: NARROW[dummy.specificRef] ]]; END; CreateDesign: PUBLIC PROC [technology: CD.Technology] RETURNS [design: CD.Design] = BEGIN IF technology=NIL THEN ERROR CD.Error[callingError, "NIL technology"]; design _ NEW[CD.DesignRec]; design.technology _ technology; InternalResetDesign[design]; -- must not cause redraw since event not yet processed [] _ CDEvents.ProcessEvent[createEvent, design]; END; ResetDesign: PUBLIC PROC [design: CD.Design] = BEGIN InternalResetDesign[design]; [] _ CDEvents.ProcessEvent[resetDesignEvent, design]; CDValue.Store[design, $CDxDeleted, NIL]; Redraw[design]; END; RemoveApplication: PUBLIC PROC [design: CD.Design, aptr: CD.ApplicationPtr, draw: BOOL_TRUE] = BEGIN al: CD.ApplicationList _ CDOps.AppList[design]; IF al#NIL THEN IF al.first=aptr THEN CDOps.SetAppList[design, al.rest] ELSE FOR l: CD.ApplicationList _ al, l.rest WHILE l.rest#NIL DO IF l.rest.first=aptr THEN {l.rest_l.rest.rest; EXIT} ENDLOOP; IF draw THEN DelayedRedraw[design, CDApplications.ARectO[aptr]]; END; SelectNewMode: PROC[design: CD.Design] RETURNS [BOOL] = BEGIN mode: INT = CDValue.FetchInt[boundTo: design, key: $CDxSelectNewMode, propagation: technology, ifNotFound: 0]; RETURN [mode=1] END; AddAnObject: PUBLIC PROC[design: CD.Design, ob: CD.ObPtr, location: CD.DesignPosition, orientation: CD.Orientation] = BEGIN aptr: CD.ApplicationPtr; IF ob#NIL THEN { aptr _ CDApplications.NewApplicationI[ ob: ob, location: location, orientation: orientation ]; IF SelectNewMode[design] THEN { CDSimpleOps.DeselectAll[design]; aptr.selected _ TRUE; }; IncludeApplication[design, aptr]; } END; IncludeApplication: PUBLIC PROC [design: CD.Design, aptr: CD.ApplicationPtr, draw: BOOL_TRUE] = BEGIN IF aptr=NIL THEN ERROR CD.Error[callingError, "Include of NIL application"]; IF aptr.ob=NIL THEN ERROR CD.Error[callingError, "Include application with NIL object"]; CDOps.SetAppList[design, CONS[aptr, CDOps.AppList[design]]]; IF draw THEN DelayedRedraw[design, CDApplications.ARectO[aptr], TRUE]; END; IncludeApplicationList: PUBLIC PROC [design: CD.Design, al: CD.ApplicationList, draw: BOOL_TRUE] = BEGIN FOR list: CD.ApplicationList _ al, list.rest WHILE list#NIL DO IncludeApplication[design, list.first, draw]; ENDLOOP; END; Redraw: PUBLIC PROC [design: CD.Design, r: CD.DesignRect_CDOps.all, eraseFirst: BOOL_TRUE] = BEGIN CDDraw.InsertCommandAll[design, CDDraw.Comm[cmd: rect, erase: eraseFirst, rect: r, ref: NIL]]; END; CheckForShorten: PROC [dl: REF DelRec] = INLINE { IF dl.length>20 THEN { clear: BOOL _ FALSE; r: CD.DesignRect _ CDBasics.empty; FOR lst: LIST OF Remember _ dl.delayedList, lst.rest WHILE lst#NIL DO clear _ clear OR lst.first.clear; r _ CDBasics.Surround[r, lst.first.area] ENDLOOP; dl.delayedList _ LIST[Remember[area: r, clear: clear]]; dl.length _ 1 }; }; DelayedRedraw: PUBLIC ENTRY PROC [design: CD.Design, r: CD.DesignRect, eraseFirst: BOOL_TRUE] = BEGIN ENABLE UNWIND => NULL; IF design#NIL THEN { dl: REF DelRec = GetDelRec[design]; IF dl.delayedList=NIL THEN { dl.delayedList _ LIST[Remember[area: r, clear: eraseFirst]]; dl.length _ 1 } ELSE { list: LIST OF Remember _ dl.delayedList; DO IF CDBasics.Intersect[list.first.area, r] THEN { IF CDBasics.Inside[r, list.first.area] THEN { list.first.clear _ list.first.clear OR eraseFirst; RETURN } ELSE IF CDBasics.Inside[list.first.area, r] THEN { remember: LIST OF Remember _ list; eraseFirst _ list.first.clear OR eraseFirst; list.first.area _ r; WHILE list.rest#NIL DO IF CDBasics.Inside[list.rest.first.area, r] THEN { eraseFirst _ list.rest.first.clear OR eraseFirst; list.rest _ list.rest.rest; --does not change list -> keeps assertion3 dl.length _ dl.length-1; } ELSE list _ list.rest --since list.rest#NIL -> keeps assertion3 ENDLOOP; remember.first.clear _ eraseFirst; RETURN } }; IF list.rest#NIL THEN list_list.rest ELSE { list.rest _ LIST[Remember[area: r, clear: eraseFirst]]; dl.length _ dl.length+1; CheckForShorten[dl]; RETURN } ENDLOOP; } --of dl.delayedList#NIL } --of design#NIL END; DoTheDelayedRedraws: PUBLIC ENTRY PROC [design: CD.Design] = BEGIN ENABLE UNWIND => NULL; sq: REF DelRec = GetDelRec[design]; UNTIL sq.delayedList=NIL DO CDDraw.InsertCommandAll[design, CDDraw.Comm[ cmd: rect, erase: sq.delayedList.first.clear, rect: sq.delayedList.first.area, ref: NIL ]]; sq.delayedList _ sq.delayedList.rest ENDLOOP; sq.length _ 0; END; PrepareDepht: PROC [design: CD.Design, pr: CD.DrawRef] RETURNS [depht: INT_0] = INLINE BEGIN d: INT; FOR w: LIST OF CD.PushRec _ design^.actual, w.rest WHILE w#NIL DO depht _ depht+1; ENDLOOP; d _ depht; FOR w: LIST OF CD.PushRec _ design^.actual, w.rest WHILE w#NIL DO d _ d-1; pr.nesting.table[d] _ w.first.dummyCell; ENDLOOP; END; DrawDesign: PUBLIC PROC[design: CD.Design, pr: CD.DrawRef] = BEGIN depht: INT _ PrepareDepht[design, pr]; FOR w: LIST OF CD.PushRec _ design^.actual, w.rest WHILE w#NIL DO IF pr.stopFlag^ THEN EXIT; pr.nestDepth _ depht; pr.drawChild[w.first.dummyCell, [0, 0], CDOrient.original, pr]; depht _ depht-1; ENDLOOP; END; QuickDrawDesign: PUBLIC PROC[design: CD.Design, pr: CD.DrawRef] = BEGIN SomeCommon: PROC[ob: CD.ObPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] RETURNS [BOOLEAN] = INLINE BEGIN RETURN CDBasics.Intersect[CDOrient.RectAt[pos, ob.size, orient], pr.interestClip] END; DrawAndShowSelectionList: PROC [list: CD.ApplicationList, pr: CD.DrawRef] = BEGIN FOR w: CD.ApplicationList _ list, w.rest WHILE w#NIL DO IF SomeCommon[w.first.ob, w.first.location, w.first.orientation, pr] THEN BEGIN IF pr.stopFlag^ THEN EXIT; w.first.ob.p.quickDrawMe[w.first, w.first.location, w.first.orientation, pr]; IF w.first.selected THEN w.first.ob.p.showMeSelected[w.first, w.first.location, w.first.orientation, pr]; END; ENDLOOP; END; depht: INT _ PrepareDepht[design, pr]; pr.nestDepth _ depht; pr.setGround[pr: pr, pushedOut: FALSE]; DrawAndShowSelectionList[CDOps.AppList[design], pr]; IF pr.environment THEN { pr.setGround[pr: pr, pushedOut: TRUE]; FOR w: LIST OF CD.PushRec _ design^.actual.rest, w.rest WHILE w#NIL DO IF pr.stopFlag^ THEN EXIT; depht _ depht-1; pr.nestDepth _ depht; w.first.dummyCell.ob.p.quickDrawMe[w.first.dummyCell, [0, 0], CDOrient.original, pr]; ENDLOOP; } END; PointedApplication: PUBLIC PROC [design: CD.Design, pos: CD.DesignPosition] RETURNS [CD.ApplicationPtr] = BEGIN RETURN [ CDApplications.AplicationAt[CDOps.AppList[design], pos] ]; END; SelectedApplication: PUBLIC PROC [design: CD.Design] RETURNS [first: CD.ApplicationPtr_NIL, multiple: BOOL_FALSE] = BEGIN FOR w: CD.ApplicationList _ CDOps.AppList[design], w.rest WHILE w#NIL DO IF w.first.selected THEN IF first=NIL THEN first_w.first ELSE {multiple_TRUE; RETURN} ENDLOOP; END; Info: PUBLIC PROC[ob: CD.ObPtr] RETURNS [Rope.ROPE] = BEGIN IF ob=NIL THEN RETURN ["nil object"] ELSE IF ob.p.describe#NIL THEN RETURN [ob.p.describe[ob]] ELSE RETURN [Atom.GetPName[ob.p.objectType]] END; LayerName: PUBLIC PROC[lev: CD.Layer] RETURNS [Rope.ROPE] = BEGIN uniqueKey: ATOM = CD.LayerKey[lev]; IF uniqueKey=NIL THEN RETURN ["bad layer"]; RETURN [Atom.GetPName[uniqueKey]] END; ReOrderApplication: PUBLIC PROC [design: CD.Design, aptr: CD.ApplicationPtr] = BEGIN al: CD.ApplicationList _ CDOps.AppList[design]; found: BOOL _ FALSE; IF aptr=NIL THEN ERROR CD.Error[callingError, "Reorder of NIL application"]; WHILE al#NIL AND al.first=aptr DO {found_TRUE; al _ al.rest} ENDLOOP; IF al=NIL THEN { IF found THEN al_LIST[aptr] ELSE ERROR CD.Error[callingError, "Reorder of application not in design"]; } ELSE FOR l: CD.ApplicationList _ al, l.rest DO WHILE l.rest#NIL AND l.rest.first=aptr DO {found_TRUE; l.rest _ l.rest.rest} ENDLOOP; IF l.rest=NIL THEN { IF found THEN l.rest _ LIST[aptr] ELSE ERROR CD.Error[callingError, "Reorder of application not contained in design"]; EXIT } ENDLOOP; CDOps.SetAppList[design, al]; END; END. ˆCDOpsImpl.mesa (part of ChipNDale) Copyright c 1983, 1985 by Xerox Corporation. All rights reserved. by Christian Jacobi, July 12, 1983 10:56 am last edited by Christian Jacobi, April 11, 1985 3:22:55 pm PST Last Edited by: Beretta, July 1, 1985 4:20:10 pm PDT --is local since it does not cause a redraw --ASSERTION1: {list#NIL} --ASSERTION2: {no list rectangle is completely covered by an other one} --r is contained somewhere; we dont include it --it is unlikely that a small area is cleared and a big one not --assertion2 => no other elements could be removed --r contains an element; we remove this element and all others -- which are contained in r --it is unlikely that a small area is cleared and a big one not --remove all other element contained in r; to maintain assertion2 assert3: list#NIL -- drawDesign --first: returns ref to any selected application if there is one or more, otherwise nil. --multiple: more than one application is selected --on return: design has exactly one occurrence of aptr, and it is at the end. --(includes aptr if necessary and removes double occurences) -- l#NIL AND l.first#aptr holds at this point Ê‹˜šœ(™(Jšœ Ïmœ7™BJšœ-™-Jšœ?™?—J™4J˜šÏk ˜ Jšœ˜Jšžœ˜J˜Jšœ ˜ J˜J˜J˜ Jšœ ˜ Jšœ˜J˜ Jšœ˜Jšœžœžœ˜J˜J˜—šÏn œžœžœ˜Jšžœžœf˜tJšžœ˜ Jšžœžœ˜ —Jšž˜J˜UJ˜VJ˜šœžœžœ˜Jšœ žœžœ žœ˜"Jšœžœ˜J˜—J˜š Ÿ œžœ žœ žœžœ ˜:Jšž˜JšœžœI˜OJšžœžœžœžœžœ žœžœžœ˜:šžœ˜Jšœžœ žœ žœ˜#Jšœ'˜'Jšœžœ˜ J˜—Jšžœ˜J˜—Jš œ žœžœžœžœ˜;J˜šŸœžœ žœ ˜/Jšœ+™+Jšž˜Jšœžœ#˜,Jšœ#˜#J˜)šœžœžœ ˜!Jšœ5˜5Jšœžœ˜Jšœ žœ˜#J˜—Jšžœ˜—J˜š Ÿ œžœžœžœ žœ žœ ˜SJšž˜Jš žœ žœžœžœžœ'˜FJšœ žœžœ ˜J˜!JšœÏc6˜SJ˜1Jšžœ˜—J˜šŸ œžœžœ žœ ˜.Jšž˜Jšœ˜J˜6Jšœ#žœ˜(Jšœ˜Jšžœ˜J˜—šŸœžœžœ žœžœžœžœ˜^Jšž˜Jšœžœ)˜/šžœžœžœ˜Jšžœžœ"˜7šž˜š žœžœžœžœž˜:Jšžœžœžœ˜4Jšžœ˜———Jšžœžœ4˜@Jšžœ˜—J˜š Ÿ œžœ žœ žœžœ˜7Jšž˜Jšœžœe˜nJšžœ ˜Jšžœ˜—J˜šŸ œžœžœ žœ žœžœžœ˜uJšž˜Jšœžœ˜šžœžœžœ˜šœ&˜&Jšœ˜Jšœ˜Jšœ˜Jšœ˜—šžœžœ˜Jšœ ˜ Jšœžœ˜J˜—Jšœ!˜!J˜—Jšžœ˜J˜—š Ÿœž œ žœžœžœžœ˜_Jšž˜Jš žœžœžœžœžœ3˜LJš žœ žœžœžœžœ<˜XJšœžœ˜Jšœ-˜-Jšž˜—Jšžœ˜—J˜šŸœžœžœ žœ žœ#žœžœ˜\Jšž˜˜ Jšœ8žœ˜>—Jšžœ˜J˜—J˜šŸœžœžœ žœ˜1šžœžœ˜Jšœžœžœ˜Jšœžœ˜"š žœžœžœ%žœžœž˜EJšœžœ˜!Jšœ(˜(Jšžœ˜—Jšœžœ"˜7Jšœ ˜ J˜—J˜—J˜šŸ œžœžœžœ žœ žœžœžœ˜_šž˜Jšžœžœžœ˜—šžœžœžœ˜Jšœžœ˜#šžœžœžœ˜Jšœžœ'˜=Jšœ ˜ Jšœ˜—šžœ˜Jšœžœžœ˜(šž˜Jšœ™JšœG™Gšžœ(žœ˜0šžœ%žœ˜.J™.Jšœ?™?Jšœ$žœ ˜2Jšœ2™2Jšž˜J˜—šžœžœ%žœ˜2J™>J™Jšœ?™?Jšœ žœžœ˜"Jšœžœ ˜,Jšœ˜JšœA™Ašžœ žœž˜Jšœ™šžœ*žœ˜2Jšœ#žœ ˜1Jšœ *˜FJšœ˜J˜—Jšžœ )˜?Jšžœ˜—Jšœ"˜"Jšž˜J˜—J˜—Jšžœ žœžœ˜$šžœ˜Jšœ žœ'˜7Jšœ˜Jšœ˜Jšž˜J˜—Jšžœ˜—Jšœ ˜—Jšœ ˜—Jšžœ˜—J˜š Ÿœžœžœžœ žœ ˜<šž˜Jšžœžœžœ˜—Jšœžœ˜#šžœžœž˜šœ,˜,Jšœ ˜ Jšœ#˜#Jšœ!˜!Jšœž˜Jšœ˜—Jšœ$˜$Jšžœ˜—Jšœ˜Jšžœ˜—J˜š Ÿ œžœ žœ žœ žœ žœž˜VJšž˜Jšœžœ˜š žœžœžœžœ"žœžœž˜AJšœ˜Jšžœ˜—Jšœ ˜ š žœžœžœžœ"žœžœž˜AJšœ˜Jšœ(˜(Jšžœ˜—Jšžœ˜J˜—š Ÿ œžœžœ žœ žœ ˜JšœX™XJšœ1™1—Jšž˜š žœžœ1žœžœž˜Hšžœž˜Jšžœžœžœ˜Jšžœ žœžœ˜—Jšžœ˜—Jšžœ˜J˜—š Ÿœžœžœžœžœžœ˜5Jšž˜Jšžœžœžœžœ˜$Jš žœžœžœžœžœ˜:Jšžœžœ!˜,Jšžœ˜—J˜š Ÿ œžœžœžœžœžœ˜;Jšž˜Jšœ žœžœ˜#Jšžœ žœžœžœ˜,Jšžœ˜!Jšžœ˜—J˜š Ÿœžœžœ žœžœ˜NJšœN™NJ™