<> <> <> <> DIRECTORY CD, CDLayers, CDSequencer, CDViewerBackdoor, CDVPrivate, CDVScale, Imager, ImagerBackdoor, InputFocus, RuntimeError, PrincOpsUtils, Process, TIPUser, ViewerClasses; CDVSomeCursors: CEDAR PROGRAM IMPORTS CDLayers, CDSequencer, CDVPrivate, CDViewerBackdoor, CDVScale, Imager, ImagerBackdoor, InputFocus, PrincOpsUtils, Process, RuntimeError, TIPUser = BEGIN ViewerPos2: PROC [me: CDVPrivate.VRef] RETURNS [CD.Position] = INLINE { RETURN [CDVScale.DesignToViewerPosition[me.scale, me.stopVC]]; }; ViewerPos1: PROC [me: CDVPrivate.VRef] RETURNS [CD.Position] = INLINE { RETURN [CDVScale.DesignToViewerPosition[me.scale, me.startVC]]; }; DefaultCursor: PROC[me: CDVPrivate.VRef] = { p2: CD.Position = ViewerPos2[me]; CDVPrivate.InvertArea[me, p2.x-8, p2.y, p2.x+8, p2.y]; CDVPrivate.InvertArea[me, p2.x, p2.y-8, p2.x, p2.y+8]; }; ArrowCursor: PROC [me: CDVPrivate.VRef] = { p1: CD.Position = ViewerPos1[me]; p2: CD.Position = ViewerPos2[me]; Imager.SetColor[me.viewContext, ImagerBackdoor.invert]; Imager.MaskVector[me.viewContext, [p1.x, p1.y], [p2.x, p2.y]]; }; PseudoArrowCursor: PROC [me: CDVPrivate.VRef] = { ENABLE RuntimeError.UNCAUGHT => { IF CDVPrivate.ShallContinue[me, TRUE, "cursor"] THEN GOTO oops; }; p1: CD.Position = ViewerPos1[me]; p2: CD.Position = ViewerPos2[me]; CDVPrivate.InvertArea[me, p1.x, p1.y, p1.x, p2.y]; CDVPrivate.InvertArea[me, p1.x, p2.y, p2.x, p2.y]; EXITS oops => NULL; }; RectCursor: PROC[me: CDVPrivate.VRef] = { ENABLE RuntimeError.UNCAUGHT => { IF CDVPrivate.ShallContinue[me, TRUE, "cursor"] THEN GOTO oops; }; p1: CD.Position = ViewerPos1[me]; p2: CD.Position = ViewerPos2[me]; CDVPrivate.InvertArea[me, p1.x, p1.y, p1.x, p2.y]; CDVPrivate.InvertArea[me, p1.x, p2.y, p2.x, p2.y]; CDVPrivate.InvertArea[me, p2.x, p2.y, p2.x, p1.y]; CDVPrivate.InvertArea[me, p2.x, p1.y, p1.x, p1.y]; EXITS oops => NULL; }; LCursor: PROC[me: CDVPrivate.VRef] = { ENABLE RuntimeError.UNCAUGHT => { IF CDVPrivate.ShallContinue[me, TRUE, "cursor"] THEN GOTO oops; }; yi, yo, xi, xo: INT; --i=inner, o=outer, if p1 considered center wireWidth: CD.Number = MAX[CDVScale.DesignToViewerScalar[me.scale, me.defaultWidthVC], 1]; p1: CD.Position = ViewerPos1[me]; p2: CD.Position = ViewerPos2[me]; IF me.firstHorizontalVC THEN { IF p2.x<=p1.x AND p2.x>=p1.x-wireWidth AND (p2.yp1.y+wireWidth) THEN { -- sorry, only vertical, p2.x ignored CDVPrivate.InvertArea[me, p1.x, p2.y, p1.x, p1.y]; CDVPrivate.InvertArea[me, p1.x, p1.y, p1.x+wireWidth, p1.y]; CDVPrivate.InvertArea[me, p1.x+wireWidth, p1.y, p1.x+wireWidth, p2.y]; CDVPrivate.InvertArea[me, p1.x+wireWidth, p2.y, p1.x, p2.y]; RETURN }; IF p2.x>=p1.x THEN {xi _ p2.x; xo _ xi+wireWidth} ELSE {xo _ p2.x; xi _ xo+wireWidth}; IF p2.yp1.y+wireWidth THEN { -- L shaped, up CDVPrivate.InvertArea[me, p1.x, p1.y, xo, p1.y]; CDVPrivate.InvertArea[me, xo, p1.y, xo, p2.y]; CDVPrivate.InvertArea[me, xo, p2.y, xi, p2.y]; CDVPrivate.InvertArea[me, xi, p2.y, xi, p1.y+wireWidth]; CDVPrivate.InvertArea[me, xi, p1.y+wireWidth, p1.x, p1.y+wireWidth]; CDVPrivate.InvertArea[me, p1.x, p1.y+wireWidth, p1.x, p1.y]; RETURN }; <<-- only horizontal>> CDVPrivate.InvertArea[me, p1.x, p1.y, p2.x, p1.y]; CDVPrivate.InvertArea[me, p2.x, p1.y, p2.x, p1.y+wireWidth]; CDVPrivate.InvertArea[me, p2.x, p1.y+wireWidth, p1.x, p1.y+wireWidth]; CDVPrivate.InvertArea[me, p1.x, p1.y+wireWidth, p1.x, p1.y]; } ELSE -- NOT me.firstHorizontalVC -- { IF p2.y<=p1.y AND p2.y>=p1.y-wireWidth AND (p2.xp1.x+wireWidth) THEN { -- sorry, only horizontal, p2.y ignored CDVPrivate.InvertArea[me, p2.x, p1.y, p1.x, p1.y]; CDVPrivate.InvertArea[me, p1.x, p1.y, p1.x, p1.y+wireWidth]; CDVPrivate.InvertArea[me, p1.x, p1.y+wireWidth, p2.x, p1.y+wireWidth]; CDVPrivate.InvertArea[me, p2.x, p1.y+wireWidth, p2.x, p1.y]; RETURN }; IF p2.y>=p1.y THEN {yi _ p2.y; yo _ yi+wireWidth} ELSE {yo _ p2.y; yi _ yo+wireWidth}; IF p2.xp1.x+wireWidth THEN { -- L shaped, right CDVPrivate.InvertArea[me, p1.x, p1.y, p1.x, yo]; CDVPrivate.InvertArea[me, p1.x, yo, p2.x, yo]; CDVPrivate.InvertArea[me, p2.x, yo, p2.x, yi]; CDVPrivate.InvertArea[me, p2.x, yi, p1.x+wireWidth, yi]; CDVPrivate.InvertArea[me, p1.x+wireWidth, yi, p1.x+wireWidth, p1.y]; CDVPrivate.InvertArea[me, p1.x+wireWidth, p1.y, p1.x, p1.y]; RETURN }; -- only vertical CDVPrivate.InvertArea[me, p1.x, p1.y, p1.x, p2.y]; CDVPrivate.InvertArea[me, p1.x, p2.y, p1.x+wireWidth, p2.y]; CDVPrivate.InvertArea[me, p1.x+wireWidth, p2.y, p1.x+wireWidth, p1.y]; CDVPrivate.InvertArea[me, p1.x+wireWidth, p1.y, p1.x, p1.y]; }; EXITS oops => NULL; }; UseWireCursor: CDViewerBackdoor.FurtherNotifyProc = { l: CD.Layer = CDLayers.CurrentLayer[me.actualDesign]; w: CD.Number = CDLayers.LayerWidth[me.actualDesign, l]; me.designRec.outlineProcLC _ IF w>0 THEN LCursor ELSE RectCursor; me.designRec.usedCursor _ $wire; }; UseRectCursor: CDViewerBackdoor.FurtherNotifyProc = { me.designRec.usedCursor _ mode; me.designRec.outlineProcLC _ RectCursor }; UseArrowCursor: CDViewerBackdoor.FurtherNotifyProc = { me.designRec.usedCursor _ mode; me.designRec.outlineProcLC _ ArrowCursor }; UsePseudoArrowCursor: CDViewerBackdoor.FurtherNotifyProc = { me.designRec.usedCursor _ mode; me.designRec.outlineProcLC _ PseudoArrowCursor }; UseDefaultCursor: CDViewerBackdoor.FurtherNotifyProc = { me.designRec.usedCursor _ NIL; me.designRec.outlineProcLC _ DefaultCursor }; DoThePartialAdvance: CDViewerBackdoor.FurtherNotifyProc = { UseWireCursor[me, $wire]; IF me.designRec.firstHLC THEN me.designRec.startLC.x _ me.designRec.stopLC.x ELSE me.designRec.startLC.y _ me.designRec.stopLC.y; me.designRec.firstHLC _ NOT me.designRec.firstHLC; me.designRec.startLCValid _ TRUE; }; DoFlipCursor: CDViewerBackdoor.FurtherNotifyProc = { UseWireCursor[me, $wire]; me.designRec.firstHLC _ NOT me.designRec.firstHLC }; IsTheCursor: PROC [usedCursor: REF] RETURNS [yes: BOOL_FALSE] = INLINE { ENABLE RuntimeError.UNCAUGHT => {--must have not yet been initialized-- GOTO deny}; IF CDVPrivate.cursoredCDViewer#NIL THEN RETURN [NARROW[CDVPrivate.cursoredCDViewer.data, CDVPrivate.VRef].designRec.usedCursor=usedCursor]; EXITS deny => RETURN [FALSE] }; IsWire: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[$wire]]}; IsRect: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[$rect]]}; IsArrow: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[$arrow]]}; IsDefault: PROC RETURNS [BOOL] = {RETURN [IsTheCursor[NIL]]}; NoFocus: PROC RETURNS [BOOL_TRUE] = { <<--returns true when the cursored viewer is different from the focused viewer>> ENABLE RuntimeError.UNCAUGHT => GOTO Oops; focus: InputFocus.Focus _ InputFocus.GetInputFocus[]; RETURN [focus=NIL OR CDVPrivate.cursoredCDViewer#focus.owner] EXITS Oops => RETURN }; SetXModeOn: CDViewerBackdoor.FurtherNotifyProc = { me.designRec.xMode _ TRUE }; SetXModeOff: CDViewerBackdoor.FurtherNotifyProc = { me.designRec.xMode _ FALSE }; SetMarkOnStart: CDViewerBackdoor.FurtherNotifyProc = { me.designRec.mark _ me.designRec.startLC }; SetMarkOnStop: CDViewerBackdoor.FurtherNotifyProc = { me.designRec.mark _ me.designRec.stopLC }; SetStartOnMark: CDViewerBackdoor.FurtherNotifyProc = { me.designRec.startLC _ me.designRec.startLC; me.designRec.startLCValid _ TRUE; }; ShowMark: CDViewerBackdoor.FurtherNotifyProc = { <<--handled specially because we do not call stoptrack>> comm: CDSequencer.Command = NEW[CDSequencer.CommandRec _ CDSequencer.CommandRec[ design: me.actualDesign, key: $ShowMark, pos: me.designRec.mark, sPos: me.designRec.mark, l: me.designRec.currentLayer, ref: me, n: me.defaultWidthVC, b: me.designRec.firstHLC ] ]; TRUSTED {Process.Detach[FORK CDSequencer.ExecuteCommand[design: me.actualDesign, comm: comm] ]} }; CursoredDesignXMode: PROC [] RETURNS [xmode: BOOL_FALSE] = { ENABLE RuntimeError.UNCAUGHT => {--not yet initialized-- GOTO skip}; IF CDVPrivate.cursoredCDViewer#NIL THEN WITH CDVPrivate.cursoredCDViewer.data SELECT FROM gr: CDVPrivate.VRef => xmode _ gr.designRec.xMode ENDCASE => NULL; EXITS skip => NULL }; IsXMode: PROC RETURNS [xMode: BOOL] = { xMode _ CursoredDesignXMode[] }; IsNotXMode: PROC RETURNS [notXMode: BOOL] = { notXMode _ ~ CursoredDesignXMode[] }; CDViewerBackdoor.InstallFurtherNotify[NIL, UseDefaultCursor]; --overwrites the default CDViewerBackdoor.InstallFurtherNotify[$wire, UseWireCursor]; CDViewerBackdoor.InstallFurtherNotify[$rect, UseRectCursor]; IF PrincOpsUtils.VERSION[].machineType=dorado THEN CDViewerBackdoor.InstallFurtherNotify[$arrow, UseArrowCursor] ELSE CDViewerBackdoor.InstallFurtherNotify[$arrow, UsePseudoArrowCursor]; CDViewerBackdoor.InstallFurtherNotify[$default, UseDefaultCursor]; CDViewerBackdoor.InstallFurtherNotify[$PartialWireAdvance, DoThePartialAdvance]; CDViewerBackdoor.InstallFurtherNotify[$FlipWire, DoFlipCursor]; TIPUser.RegisterTIPPredicate[key: $ChipndaleWireCursor, p: IsWire]; TIPUser.RegisterTIPPredicate[key: $ChipndaleRectCursor, p: IsRect]; TIPUser.RegisterTIPPredicate[key: $ChipndaleArrowCursor, p: IsArrow]; TIPUser.RegisterTIPPredicate[key: $ChipndaleDefaultCursor, p: IsDefault]; TIPUser.RegisterTIPPredicate[key: $ChipndaleNoFocus, p: NoFocus]; CDViewerBackdoor.InstallFurtherNotify[$SetXModeOn, SetXModeOn]; CDViewerBackdoor.InstallFurtherNotify[$SetXModeOff, SetXModeOff]; CDViewerBackdoor.InstallFurtherNotify[$SetMarkOnStart, SetMarkOnStart]; CDViewerBackdoor.InstallFurtherNotify[$SetMarkOnStop, SetMarkOnStop]; CDViewerBackdoor.InstallFurtherNotify[$SetStartOnMark, SetStartOnMark]; CDViewerBackdoor.InstallFurtherNotify[$ShowMark, ShowMark]; TIPUser.RegisterTIPPredicate[key: $ChipndaleXMode, p: IsXMode]; TIPUser.RegisterTIPPredicate[key: $ChipndaleNXMode, p: IsNotXMode]; END.