DIRECTORY Atom, Basics, CD, CDBasics, CDDefaultProcs, CDDirectory, CDEvents, CDLayers, CDPrivate, CDProperties, Imager, IO, PrincOps, RefTab, Rope, SafeStorage; CDImpl: CEDAR MONITOR IMPORTS Atom, Basics, CD, CDDefaultProcs, CDDirectory, CDEvents, CDLayers, CDProperties, IO, RefTab, Rope, SafeStorage EXPORTS CD, CDPrivate SHARES CDLayers, CDPrivate = BEGIN Error: PUBLIC ERROR[ec: CD.ErrorCode _ programming, explanation: Rope.ROPE _ NIL] = CODE; permanent: ZONE = SafeStorage.GetPermanentZone[]; layers: PUBLIC REF ARRAY CD.Layer OF CDPrivate.LayerRef = permanent.NEW[ARRAY CD.Layer OF CDPrivate.LayerRef]; registerTechEvent: CDEvents.EventRegistration = CDEvents.RegisterEventType[$RegisterTechnology]; pureTechRegistration: RefTab.Ref = RefTab.Create[]; -- contains technologies allTechRegistration: RefTab.Ref = RefTab.Create[]; PrivateTRef: TYPE = REF PrivateTRep; PrivateTRep: PUBLIC TYPE = RECORD [ objectRegisterTab: RefTab.Ref, -- contains object types layerKeyTab: RefTab.Ref -- contains Layers ]; nilTechnologyPrivate: PrivateTRef = NEW[PrivateTRep _ [ objectRegisterTab: RefTab.Create[], --for technology dependant objects it contains NIL layerKeyTab: RefTab.Create[] ]]; RegisterObjectClass: PUBLIC PROC [objectType: ATOM, class: CD.ObjectClassRec, inherit: REF_NIL] RETURNS [CD.ObjectClass] = { done: BOOL; c: CD.ObjectClass = permanent.NEW[CD.ObjectClassRec_class]; c.properties _ CD.InitPropRef[]; WITH inherit SELECT FROM oc: CD.ObjectClass => c.parent _ oc; a: ATOM => { oc: CD.ObjectClass _ FetchObjectClass[a, c.technology]; IF oc=NIL THEN ERROR CD.Error[missingRegistration]; c.parent _ oc; }; ENDCASE => IF inherit#NIL THEN ERROR CD.Error[calling]; IF objectType#NIL THEN c.objectType _ objectType; IF c.drawMe=NIL THEN c.drawMe _ CDDefaultProcs.DrawMe; IF c.quickDrawMe=NIL THEN c.quickDrawMe _ CDDefaultProcs.QuickDrawMe; IF c.showMeSelected=NIL THEN c.showMeSelected _ CDDefaultProcs.ShowMeSelected; IF c.hitInside=NIL THEN c.hitInside _ CDDefaultProcs.HitInside; IF c.interestRect=NIL THEN c.interestRect _ CDDefaultProcs.InterestRect; IF c.describe=NIL THEN c.describe _ CDDefaultProcs.Describe; IF c.technology=NIL THEN done _ RefTab.Insert[nilTechnologyPrivate.objectRegisterTab, objectType, c] ELSE { techPriv: PrivateTRef = c.technology.cdPriv; objectRegisterTab: RefTab.Ref = techPriv.objectRegisterTab; globFound: BOOL; x: REF; [globFound, x] _ RefTab.Fetch[nilTechnologyPrivate.objectRegisterTab, objectType]; IF globFound AND x#NIL THEN done _ FALSE ELSE { [] _ RefTab.Insert[nilTechnologyPrivate.objectRegisterTab, objectType, NIL]; done _ RefTab.Insert[objectRegisterTab, objectType, c]; -- technology register } }; IF ~done THEN ERROR Error[doubleRegistration]; RETURN [c] }; FetchObjectClass: PUBLIC PROC [objectType: REF, technology: CD.Technology_NIL] RETURNS [CD.ObjectClass] = { x: REF; class: CD.ObjectClass _ NIL; found: BOOL _ FALSE; IF technology#NIL THEN { -- search in technology table techPriv: PrivateTRef = technology.cdPriv; [found, x] _ RefTab.Fetch[techPriv.objectRegisterTab, objectType]; }; IF NOT found THEN { -- search in global table [found, x] _ RefTab.Fetch[nilTechnologyPrivate.objectRegisterTab, objectType]; }; IF found THEN class _ NARROW[x]; RETURN [class] }; lastLayer: CD.Layer _ 6; InitiateLayer: PROC [layer: CD.Layer, technology: CD.Technology_NIL, uniqueKey: ATOM] = { techPriv: PrivateTRef; layers[layer].technology _ technology; layers[layer].uniqueKey _ uniqueKey; CDLayers.MakePaint[layer]; IF technology=NIL THEN techPriv _ nilTechnologyPrivate ELSE { techPriv _ technology.cdPriv; technology.usedLayers _ CONS[layer, technology.usedLayers] }; [] _ RefTab.Insert[techPriv.layerKeyTab, uniqueKey, layers[layer]]; }; ConvertLayer: PUBLIC ENTRY PROC [technology: CD.Technology, uniqueKey: ATOM, into: CD.Layer] = { ENABLE UNWIND => NULL; techPriv: PrivateTRef; IF uniqueKey=NIL OR uniqueKey=$NIL THEN RETURN WITH ERROR Error[calling, "bad uniqueKey"]; -- avoid problems with NIL as ATOM; any IO routine might use $NIL instead IF technology=NIL THEN techPriv _ nilTechnologyPrivate ELSE techPriv _ technology.cdPriv; [] _ RefTab.Insert[techPriv.layerKeyTab, uniqueKey, layers[into]]; }; NewLayer: PUBLIC ENTRY PROC [technology: CD.Technology_NIL, uniqueKey: ATOM] RETURNS [CD.Layer] = { ENABLE UNWIND => NULL; IF uniqueKey=NIL OR uniqueKey=$NIL THEN RETURN WITH ERROR Error[calling, "bad uniqueKey"]; -- avoid problems with NIL as ATOM; any IO routine might use $NIL instead IF lastLayer>=CD.layerNum-1 THEN RETURN WITH ERROR Error[noResource, "too many layers requested; (probably too many different technologies used)"]; lastLayer _ lastLayer+1; InitiateLayer[lastLayer, technology, uniqueKey]; RETURN [lastLayer] }; FetchLayer: PUBLIC PROC [t: CD.Technology, uniqueKey: ATOM] RETURNS [CD.Layer] = { found: BOOL_FALSE; l: CD.Layer _ CD.errorLayer; x: REF; IF t#NIL THEN { techPriv: PrivateTRef = t.cdPriv; [found: found, val: x] _ RefTab.Fetch[techPriv.layerKeyTab, uniqueKey]; }; IF ~found THEN { [found: found, val: x] _ RefTab.Fetch[nilTechnologyPrivate.layerKeyTab, uniqueKey]; }; IF found THEN l _ NARROW[x, CDPrivate.LayerRef].number; RETURN [l] }; LayerTechnology: PUBLIC PROC [l: CD.Layer] RETURNS [CD.Technology] = { RETURN [layers[l].technology]; }; LayerKey: PUBLIC PROC [l: CD.Layer] RETURNS [ATOM] = { RETURN [layers[l].uniqueKey]; }; CreateDrawRef: PUBLIC PROC [inf: CD.DrawInformation] RETURNS [dr: CD.DrawRef] = { dr _ NEW[CD.DrawInformation _ inf]; dr.properties _ NEW[CD.PropList_NIL]; IF dr.drawChild=NIL THEN dr.drawChild_CDDefaultProcs.DrawChild; IF dr.drawChildSel=NIL THEN dr.drawChildSel_CDDefaultProcs.DrawChildSel; IF dr.drawRect=NIL THEN dr.drawRect_CDDefaultProcs.DrawRect; IF dr.drawOutLine=NIL THEN dr.drawOutLine_CDDefaultProcs.ContextOutLine; IF dr.drawContext=NIL THEN dr.drawContext_CDDefaultProcs.DrawContext; IF dr.drawComment=NIL THEN dr.drawComment_CDDefaultProcs.DrawComment; IF dr.stopFlag=NIL THEN dr.stopFlag_NEW[BOOL_FALSE]; IF dr.priorityChecker=NIL THEN dr.priorityChecker _ CDDefaultProcs.IgnorePriority; IF dr.setGround=NIL THEN dr.setGround _ CDDefaultProcs.IgnoreGround; }; RegisterTechnology: PUBLIC PROC [key: ATOM, name: Rope.ROPE, lambda: CD.Number] RETURNS [CD.Technology] = { t: CD.Technology = permanent.NEW[CD.TechnologyRep_[ properties: CD.InitPropRef[], key: key, name: IF name#NIL THEN name ELSE Atom.GetPName[key], lambda: lambda, usedLayers: NIL, cdPriv: permanent.NEW[PrivateTRep _ [RefTab.Create[], RefTab.Create[]]] ]]; IF ~RefTab.Insert[allTechRegistration, key, t] THEN { Error[doubleRegistration, "technology exist already"]; }; [] _ RefTab.Insert[pureTechRegistration, key, t]; [] _ CDEvents.ProcessEvent[eventRegistration: registerTechEvent, design: NIL, x: t]; RETURN[t] }; DesignName: PUBLIC PROC [design: CD.Design_NIL] RETURNS [r: Rope.ROPE] = { IF design=NIL THEN RETURN ["NIL design"] ELSE { r _ design.name; IF Rope.IsEmpty[r] THEN TRUSTED { r _ IO.PutFR["no name [%g]", [cardinal[LOOPHOLE[design, CARD]]]] }; } }; Describe: PUBLIC PROC [ob: CD.Object, readOnlyInstProps: CD.PropList_NIL, design: CD.Design, verbosity: NAT_0] RETURNS [r: Rope.ROPE_NIL] = { Cat: PROC [x: Rope.ROPE] = { IF r=NIL THEN r _ x ELSE r _ Rope.Cat[r, " ", x] }; name: Rope.ROPE _ NIL; addr: Rope.ROPE _ NIL; IF ob=NIL THEN RETURN ["nil object"]; IF design#NIL THEN name _ CDDirectory.Name[ob, design]; IF name#NIL THEN r _ Rope.Cat["""", name, """"] ELSE IF verbosity>0 AND ob.class#NIL AND ob.class.composed THEN r _ addr _ IO.PutFR["[%g]", [cardinal[LOOPHOLE[ob]]]]; IF ob.class=NIL THEN {Cat["bad object"]; RETURN}; IF ob.class.describe#NIL THEN Cat[ob.class.describe[ob, readOnlyInstProps, verbosity]]; IF Rope.IsEmpty[r] THEN SELECT TRUE FROM ob.class.description#NIL => r _ ob.class.description; ob.class.objectType#NIL => r _ Atom.GetPName[ob.class.objectType]; ENDCASE => r _ "object has bad class"; IF verbosity>0 THEN { hint: Rope.ROPE _ NIL; WITH CDProperties.GetObjectProp[ob, $Describe] SELECT FROM n: Rope.ROPE => hint _ n; a: ATOM => hint _ Atom.GetPName[a]; ENDCASE => NULL; IF hint#NIL AND ~Rope.Equal[hint, name] THEN Cat[Rope.Cat["[hint: ", hint, "]"]]; IF ~ob.class.describesSignal THEN WITH CDProperties.GetListProp[readOnlyInstProps, $SignalName] SELECT FROM n: Rope.ROPE => Cat[n]; a: ATOM => Cat[Atom.GetPName[a]]; ENDCASE => NULL; IF addr=NIL THEN IF verbosity>2 OR ~ob.class.composed THEN IF verbosity>3 OR ob.class.composed THEN r _ IO.PutFR["%g [%g]", [rope[r]], [cardinal[LOOPHOLE[ob]]]]; }; }; ConvertTechnologyKey: PUBLIC PROC [technology: CD.Technology, oldKey: ATOM] = { IF technology=NIL THEN Error[calling]; IF ~RefTab.Insert[allTechRegistration, oldKey, technology] THEN { Error[doubleRegistration, "technology key exist already"]; }; }; FetchTechnology: PUBLIC PROC [key: ATOM] RETURNS [tech: CD.Technology] = { RETURN [NARROW[RefTab.Fetch[allTechRegistration, key].val]] }; EnumerateTechnologies: PUBLIC PROC [proc: CD.TechnologyEnumerator] RETURNS [quit: BOOL] = { Action: RefTab.EachPairAction = { quit _ proc[NARROW[val]] }; quit _ RefTab.Pairs[pureTechRegistration, Action]; }; DEnumProc: TYPE = PROC [p: CDPrivate.DesignEnumerator] RETURNS [BOOL]; dEnumerators: LIST OF DEnumProc_NIL; EnumDesigns: PUBLIC PROC [p: CDPrivate.DesignEnumerator] RETURNS [quit: BOOL_FALSE] = { seen: RefTab.Ref _ RefTab.Create[5]; Inner: CDPrivate.DesignEnumerator = { IF RefTab.Insert[seen, design, design] THEN quit _ p[design] }; FOR el: LIST OF DEnumProc _ dEnumerators, el.rest WHILE el#NIL AND ~quit DO quit _ el.first[Inner]; ENDLOOP; }; InstallDesignEnumerator: PUBLIC ENTRY PROC [enum: DEnumProc] = { IF enum#NIL THEN dEnumerators _ CONS[enum, dEnumerators]; }; GetGrid: PUBLIC PROC [design: CD.Design, hint: REF_NIL] RETURNS [g: CD.Number_1] = { IF getGrid#NIL THEN g _ getGrid[design, hint]; }; getGrid: PROC [design: CD.Design, hint: REF_NIL] RETURNS [CD.Number] _ DefaultGetGrid; DefaultGetGrid: PROC [design: CD.Design, hint: REF_NIL] RETURNS [CD.Number] = { RETURN [design.technology.lambda] }; InstallGetGrid: PUBLIC PROC [g: PROC [design: CD.Design, hint: REF_NIL] RETURNS [CD.Number]] = { IF g#NIL THEN getGrid _ g; }; Hash: PUBLIC PROC [x: REF] RETURNS [h: CARDINAL] = { Munch: PROC [REF] RETURNS [CARDINAL] = TRUSTED MACHINE CODE { PrincOps.zXOR; }; WITH x SELECT FROM ob: CD.Object => { h _ Munch[ob.class]; h _ Basics.BITXOR[h, ((ob.bbox.x2-ob.bbox.x1) MOD 100B)*1000B]; h _ Basics.BITXOR[h, ((ob.bbox.y2-ob.bbox.y1) MOD 1000B)*100B]; h _ Basics.BITXOR[h, ob.layer]; }; ENDCASE => h _ Munch[x]; }; Equal: PUBLIC PROC[x, y: REF] RETURNS [BOOL] = { ob1: CD.Object = NARROW[x]; ob2: CD.Object = NARROW[y]; RETURN [ ob1.class=ob2.class AND ob1.bbox=ob2.bbox AND ob1.layer=ob2.layer AND CD.InterestRect[ob1]=CD.InterestRect[ob2] ] }; blueLayer, redLayer, greenLayer, yellowLayer, grayLayer: CD.Layer; IF registerTechEvent=NIL THEN ERROR; FOR l: CD.Layer IN CD.Layer DO layers[l] _ permanent.NEW[CDPrivate.LayerRec _ [ properties: CD.InitPropRef[], number: l ]]; layers[l].globalUniqueKey _ layers[l]; ENDLOOP; InitiateLayer[CD.undefLayer, NIL, $undefLayer]; CDLayers.MakeAbstract[CD.undefLayer]; InitiateLayer[CD.shadeLayer, NIL, $shadeLayer]; InitiateLayer[CD.errorLayer, NIL, $errorLayer]; CDLayers.MakeSuppressIR[CD.errorLayer]; InitiateLayer[CD.backgroundLayer, NIL, $backGround]; CDLayers.MakeAbstract[CD.backgroundLayer]; InitiateLayer[CD.outlineLayer, NIL, $outline]; InitiateLayer[CD.selectionLayer, NIL, $selection]; InitiateLayer[CD.commentLayer, NIL, $comment]; blueLayer _ NewLayer[NIL, $blue]; redLayer _ NewLayer[NIL, $red]; greenLayer _ NewLayer[NIL, $green]; yellowLayer _ NewLayer[NIL, $yellow]; grayLayer _ NewLayer[NIL, $gray]; END. JCDImpl.mesa (part of ChipNDale) Copyright c 1983, 1987 by Xerox Corporation. All rights reserved. Created by: Christian Jacobi, June 24, 1983 5:07 pm Last Edited by: Christian Jacobi, March 30, 1987 11:35:53 am PST --assume everithing gets correct even if all references are lost, --don't care about memory area, hint only --all real technology keys are in stored in both RefTab's --the convert technology keys are stored only in allTechRegistration --This allows enumeration to return each technology just once, independent of convert names --still check if it might be global --global register it used per technology --may find it but have NIL value: then is technologydependant --Helps conversion when layers are renamed --not ENTRY since RefTab.Insert does necessary monitoring and CDEvents.ProcessEvent --is dangerous ʼ˜codešœ!™!Kšœ Ïmœ7™BKšœ4™4K™@—K˜šÏk ˜ Kšœ˜Kšœž˜Kšžœ˜K˜ K˜K˜ K˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜K˜ —K˜šÏnœžœžœ˜Kšžœžœ_˜wKšžœžœ ˜Kšžœ˜—Kšž˜K˜Kš œžœžœžœ,žœžœžœ˜Yšœ žœ#˜2KšœB™BKšœ)™)—K˜š œžœžœžœžœžœ˜:Kš œ žœžœžœžœ˜5—K˜K˜`K˜Kšœ4Ïc˜Lšœ3˜3Kšœ9™9KšœG™GKšœ^™^—K˜Kšœ žœžœ ˜$šœ žœžœžœ˜#Kšœ ˜7Kšœ ˜*K˜K˜K˜—šœ$žœ˜7Kšœ$ 3˜WKšœ˜Kšœ˜—K˜K˜šŸœžœžœžœ%žœžœžœžœ˜|Kšœžœ˜ Kšœžœžœžœ˜;Kšœ ˜ šžœ žœž˜Kšœžœ˜$šœžœ˜ Kšœžœ1˜7Kš žœžœžœžœžœ˜3Kšœ˜Kšœ˜—Kš žœžœ žœžœžœžœ˜7—Kšžœ žœžœ˜1Kšžœ žœžœ"˜6Kšžœžœžœ,˜EKšžœžœžœ2˜NKšžœ žœžœ(˜?Kšžœžœžœ.˜HKšžœ žœžœ&˜<šžœžœžœ˜KšœK˜K—šž˜Kšœ,˜,K˜;Kšœ žœ˜Kšœžœ˜šœS˜SKšœ#™#—Kš žœ žœžœžœž˜(šžœ˜šœGžœ˜MKšœ(™(—Kšœ8 ˜NKšž˜—Kšžœ˜—Kšžœžœžœ˜.Kšžœ˜ Kšžœ˜K˜—šŸœžœžœžœžœ žœžœžœ˜kKšœžœ˜Kšœžœžœ˜Kšœžœžœ˜šžœ žœžœ ˜6Kšœ*˜*K˜BKšœ˜—šžœžœžœ ˜-KšœN˜NKšœ=™=Kšœ˜—Kšžœžœ žœ˜ Kšžœ˜Kšœ˜K˜—Kšœ žœ ˜K˜š Ÿ œžœ žœžœ žœ žœ˜YKšœ˜Kšœ&˜&Kšœ$˜$Kšœ˜Kšžœ žœžœ ˜6šžœ˜K˜Kšœžœ˜:K˜—KšœC˜CKšœ˜—K˜šŸ œžœžœžœžœžœžœ ˜`Kšœ*™*Kšžœžœžœ˜Kšœ˜Kšžœ žœžœžœžœžœžœ" I˜¤Kšžœ žœžœ ˜6Kšžœ˜"KšœB˜BKšœ˜—K˜šŸœžœžœžœžœ žœ žœžœžœ ˜cKšžœžœžœ˜šžœ žœžœžœ˜(Kšžœžœžœ"˜3Kš I˜I—šžœ žœ žœ˜!Kšžœžœžœa˜r—K˜Kšœ0˜0Kšžœ ˜Kšœ˜—K˜šŸ œžœžœžœžœžœžœ ˜RKšœžœžœ˜Kšœžœ žœ ˜Kšœžœ˜šžœžœžœ˜Kšœ!˜!KšœG˜GKšœ˜—šžœžœ˜KšœS˜SK˜—Kšžœžœžœ˜7Kšžœ˜ Kšœ˜K˜—šŸœžœžœžœ˜FKšžœ˜Kšœ˜—K˜š Ÿœžœžœžœžœžœ˜6Kšžœ˜Kšœ˜—K˜š Ÿ œžœžœžœžœžœ ˜QKšœžœžœ˜#Kšœžœžœ žœ˜%Kšžœžœžœ'˜?Kšžœžœžœ-˜HKšžœ žœžœ%˜