DIRECTORY Carets USING [ResumeCarets, SuspendCarets], Cursors USING [InvertCursor], InputFocus USING [GetInputFocus, SetInputFocus], Menus USING [CopyMenu, Menu], Process USING [GetPriority, Priority, priorityForeground, SetPriority], RefTab USING [Create, Fetch, Ref, Store], Rope USING [Compare, ROPE], RTOS USING [GetCurrent, RegisterCedarProcess, UnregisterCedarProcess], TIPUser USING [TIPScreenCoords], ViewerEvents USING [ProcessEvent], ViewerOps, ViewerLocks, ViewerClasses, ViewerSpecs, WindowManager USING [colorDisplayOn], WindowManagerPrivate; ViewerOpsImplB: CEDAR PROGRAM IMPORTS Carets, Cursors, InputFocus, Menus, Process, RefTab, Rope, RTOS, ViewerEvents, ViewerLocks, ViewerOps, WindowManager, WindowManagerPrivate EXPORTS ViewerOps SHARES Menus, ViewerEvents = BEGIN OPEN ViewerClasses, ViewerSpecs, ViewerOps, WindowManager; classTable: RefTab.Ref _ RefTab.Create[mod:50]; -- hold viewer classes RegisterViewerClass: PUBLIC PROC [flavor: ViewerFlavor, class: ViewerClass] = { class.flavor _ flavor; [] _ RefTab.Store[classTable, flavor, class]}; FetchViewerClass: PUBLIC PROC [flavor: ViewerFlavor] RETURNS [ViewerClass] = {IF flavor = $TypeScript THEN flavor _ $Typescript; RETURN[NARROW[RefTab.Fetch[classTable, flavor].val]]}; EnumerateViewers: PUBLIC PROC [enum: EnumProc] = BEGIN FOR c: Column DECREASING IN Column DO -- decreasing so will try static viewers last v: Viewer _ WindowManagerPrivate.rootViewerTree[c]; next: Viewer; UNTIL v=NIL DO next _ v.sibling; IF ~enum[v] THEN RETURN; v _ next; ENDLOOP; ENDLOOP; END; EnumerateChildren: PUBLIC PROC [viewer: Viewer, enum: EnumProc] = BEGIN v: Viewer _ viewer.child; next: Viewer; WHILE v#NIL DO next _ v.sibling; EnumerateChildren[v, enum]; IF ~enum[v] THEN RETURN; v _ next; ENDLOOP; END; FindViewer: PUBLIC PROC [name: Rope.ROPE] RETURNS [viewer: Viewer] = BEGIN MatchName: EnumProc = BEGIN IF Rope.Compare[name, v.name, FALSE]=equal THEN BEGIN viewer _ v; RETURN[FALSE]; END ELSE RETURN[TRUE]; END; EnumerateViewers[MatchName]; END; SaveViewer: PUBLIC PROC [viewer: Viewer] = BEGIN list: LIST OF Viewer; LockedStart: PROC = { FOR v: Viewer _ viewer, v.link DO v.saveInProgress _ TRUE; PaintViewer[v, caption, FALSE]; list _ CONS[v, list]; IF v.link = NIL OR v.link = viewer THEN EXIT; ENDLOOP}; LockedStop: PROC = { FOR saved: LIST OF Viewer _ list, saved.rest UNTIL saved = NIL DO v: Viewer = saved.first; IF v.destroyed THEN LOOP; v.newVersion _ v.newFile _ v.saveInProgress _ FALSE; PaintViewer[v, caption, FALSE]; [] _ ViewerEvents.ProcessEvent[save, v, FALSE]; ENDLOOP}; FOR v: Viewer _ viewer, v.link DO IF ViewerEvents.ProcessEvent[save, v, TRUE].abort THEN RETURN; IF v.link = NIL OR v.link = viewer THEN EXIT; ENDLOOP; LockedStart[]; IF viewer.class.save#NIL THEN viewer.class.save[viewer]; LockedStop[]; END; RestoreViewer: PUBLIC PROC [viewer: Viewer] = BEGIN DoOne: PROC [v: Viewer] = INLINE BEGIN KillInputFocus[v]; IF v.class.init # NIL THEN v.class.init[v]; v.newVersion _ v.newFile _ FALSE; PaintViewer[v, all]; END; DoOne[viewer]; IF viewer.link#NIL THEN FOR v: Viewer _ viewer.link, v.link UNTIL v=viewer DO DoOne[v]; ENDLOOP; END; KillInputFocus: PROC [viewer: Viewer] = BEGIN focus: Viewer _ InputFocus.GetInputFocus[].owner; WHILE focus # NIL DO IF focus # viewer THEN focus _ focus.parent ELSE {InputFocus.SetInputFocus[]; EXIT}; ENDLOOP; END; SetMenu: PUBLIC PROC [viewer: Viewer, menu: Menus.Menu, paint: BOOL _ TRUE] = BEGIN sameSize: BOOL = (menu#NIL AND viewer.menu#NIL AND viewer.menu.linesUsed=menu.linesUsed); IF viewer.iconic THEN paint _ FALSE; IF viewer.parent#NIL THEN ERROR; viewer.menu _ IF menu=NIL THEN NIL ELSE Menus.CopyMenu[menu]; IF ~sameSize AND paint THEN EstablishViewerPosition[viewer, viewer.wx, viewer.wy, viewer.ww, viewer.wh]; IF paint THEN PaintViewer[viewer, IF sameSize THEN menu ELSE all]; END; IndicateNewVersion: PUBLIC PROC [viewer: Viewer] = BEGIN link1, link2: Viewer; LockedNewVersion: PROC = { FOR v: Viewer _ viewer, v.link DO v.newVersion _ TRUE; PaintViewer[v, caption]; [] _ ViewerEvents.ProcessEvent[edit, v, FALSE]; IF v.link = NIL OR v.link = viewer THEN EXIT; ENDLOOP}; FOR v: Viewer _ viewer, v.link DO IF ViewerEvents.ProcessEvent[edit, v, TRUE].abort THEN RETURN; IF v.link = NIL OR v.link = viewer THEN EXIT; ENDLOOP; IF viewer # NIL THEN link1 _ viewer.link; IF link1 # NIL THEN link2 _ link1.link; ViewerLocks.CallUnderReadLocks[LockedNewVersion, viewer, link1, link2]; END; SetNewFile: PUBLIC PROC [viewer: Viewer] = BEGIN DoOne: PROC [v: Viewer] = BEGIN v.newFile _ TRUE; PaintViewer[v, caption]; END; DoOne[viewer]; IF viewer.link#NIL THEN FOR v: Viewer _ viewer.link, v.link UNTIL v=viewer DO DoOne[v]; ENDLOOP; END; SetOpenHeight: PUBLIC PROC [viewer: Viewer, clientHeight: INTEGER] = BEGIN overhead: INTEGER _ captionHeight + (IF viewer.border THEN windowBorderSize ELSE 0); IF viewer.menu#NIL THEN overhead _ overhead+(viewer.menu.linesUsed*menuHeight)+menuBarHeight; viewer.openHeight _ clientHeight+overhead; END; SaveAllEdits: PUBLIC PROC = BEGIN old: Process.Priority = Process.GetPriority[]; Save: EnumProc = BEGIN Cursors.InvertCursor[]; IF (v.newVersion OR v.newFile) AND v.class.save # NIL THEN v.class.save[v, TRUE ! ANY => CONTINUE]; v.newVersion _ v.newFile _ FALSE; IF v.icon=dirtyDocument THEN v.icon _ document; IF v.link#NIL THEN FOR t: Viewer _ v.link, t.link UNTIL t=v DO t.newVersion _ t.newFile _ FALSE; ENDLOOP; Cursors.InvertCursor[]; RETURN[TRUE]; END; IF old>Process.priorityForeground THEN TRUSTED BEGIN -- called from CoPilot Process.SetPriority[Process.priorityForeground]; RTOS.RegisterCedarProcess[RTOS.GetCurrent[]]; END; EnumerateViewers[Save]; IF old>Process.priorityForeground THEN TRUSTED BEGIN -- called from CoPilot RTOS.UnregisterCedarProcess[RTOS.GetCurrent[]]; Process.SetPriority[old]; END; END; PaintEverything: PUBLIC PROC = BEGIN OPEN Process; ResetPaintCache[]; Carets.SuspendCarets[]; GreyScreen[0, 0, 9999, 9999, FALSE, FALSE]; ComputeColumn[static]; ComputeColumn[left]; ComputeColumn[right]; IF WindowManager.colorDisplayOn THEN ComputeColumn[color]; WaitForPaintingToFinish[]; Carets.ResumeCarets[]; END; UserToScreenCoords: PUBLIC PROC [self: Viewer, vx, vy: INTEGER _ 0] RETURNS [sx, sy: INTEGER] = BEGIN invert: BOOL; UNTIL self=NIL DO -- compute enclosing viewer offsets invert _ IF self.parent=NIL THEN self.class.coordSys=top ELSE self.class.coordSys#self.parent.class.coordSys; vx _ vx + self.cx; IF invert THEN vy _ Top2Bottom[self, vy]; vy _ vy + self.cy; self _ self.parent; ENDLOOP; RETURN [vx, vy]; END; MouseInViewer: PUBLIC PROC [tsc: TIPUser.TIPScreenCoords] RETURNS [viewer: Viewer, client: BOOL] = BEGIN ENABLE UNWIND => NULL; x: INTEGER _ tsc.mouseX; y: INTEGER _ tsc.mouseY; invert: BOOL; TopLevelHit: PROC RETURNS [Viewer] = BEGIN FOR c: Column DECREASING IN Column DO FOR v: Viewer _ WindowManagerPrivate.rootViewerTree[c], v.sibling UNTIL v=NIL DO IF ViewerHit[v] THEN RETURN[v]; ENDLOOP; REPEAT FINISHED => RETURN[NIL]; ENDLOOP; END; ViewerHit: PROC [v: Viewer] RETURNS [BOOL] = INLINE {RETURN[x IN [v.wx..v.wx+v.ww) AND y IN [v.wy..v.wy+v.wh) AND (IF tsc.color THEN (v.column=color AND ~v.iconic) ELSE (v.column#color OR v.iconic))]}; Client: PROC RETURNS [BOOL] = INLINE {RETURN[y IN [viewer.cy..viewer.cy+viewer.ch) AND x IN [viewer.cx..viewer.cx+viewer.cw)]}; CheckViewersChildren: PROC [v: Viewer] RETURNS [BOOL] = BEGIN ex, ey: INTEGER; EmbeddedViewerHit: PROC [v: Viewer] RETURNS [BOOL] = INLINE {RETURN[ex IN [v.wx..v.wx+v.ww) AND ey IN [v.wy..v.wy+v.wh)]}; ex _ x - v.cx; ey _ y - v.cy; invert _ IF v.parent=NIL THEN v.class.coordSys=top ELSE v.class.coordSys#v.parent.class.coordSys; IF invert THEN ey _ Bottom2Top[v, ey]; FOR v _ v.child, v.sibling UNTIL v=NIL DO IF EmbeddedViewerHit[v] THEN BEGIN x _ ex; y _ ey; viewer _ v; RETURN[TRUE]; END; ENDLOOP; RETURN[FALSE]; END; IF (viewer _ TopLevelHit[]) = NIL THEN RETURN [NIL, FALSE]; IF viewer.child#NIL AND ~viewer.iconic AND Client[] THEN WHILE viewer.child#NIL AND CheckViewersChildren[viewer] DO ENDLOOP; client _ Client[]; invert _ IF viewer.parent=NIL THEN client AND viewer.class.coordSys=top ELSE viewer.class.coordSys#viewer.parent.class.coordSys; tsc.mouseX _ x - (IF client THEN viewer.cx ELSE viewer.wx); y _ y - (IF client THEN viewer.cy ELSE viewer.wy); tsc.mouseY _ IF ~invert THEN y ELSE IF client THEN Top2Bottom[viewer, y] ELSE viewer.wh-y; END; END . . . ΰViewerOpsImplB.mesa; Written by Maxwell Edited by Maxwell, May 18, 1983 9:19 am let the Viewer package know about a new class of viewer. class information from an existing viewer class. Safe in that caller can move the enumerated viewer in the tree in which case all viewers get seen at least once Not called under locks so viewers can be saved when the column is locked. poor man's crash recovery embedded frames are client info relative overwrite screen coords record Κ Ξ– "cedar" style˜JšΟc'™'J™'J™šΟk ˜ Jšœžœ˜+Jšœžœ˜Jšœ žœ ˜0Jšœžœ˜Jšœžœ:˜GJšœžœ˜)Jšœžœ žœ˜Jšžœžœ<˜FJšœžœ˜ Jšœ žœ˜"J˜ J˜ J˜J˜ Jšœžœ˜%J˜J˜—Jšœž ˜J˜Jšžœ<žœK˜’Jšžœ ˜Jšžœ˜J˜Jšžœžœ6˜@J˜šœ0˜GJ˜—šΟnœžœžœ/˜OJ˜J˜.Jš8™8J˜—šŸœžœžœžœ˜LJšœžœžœ˜3Jšžœžœ)˜6Jš0™0—J™šŸœžœžœž˜6Jšo™oš žœ ž œžœžœ-˜SJšœ3˜3J˜ šžœžœž˜J˜Jšžœ žœžœ˜J˜ Jšžœ˜—Jšžœ˜—Jšžœ˜J˜—šŸœžœžœ$ž˜GJ˜Jšœ ž˜ šžœžœž˜J˜J˜Jšžœ žœžœ˜J˜ Jšžœ˜—Jšžœ˜J˜—š Ÿ œžœžœ žœžœž˜Jšœž˜šžœžœžœž˜5J˜ Jšžœžœ˜Jšž˜—Jšžœžœžœ˜Jšžœ˜—J˜Jšžœ˜—J™šŸ œžœžœž˜0Jšœžœžœ˜šŸ œžœ˜šžœž˜!Jšœžœ˜Jšœžœ˜Jšœžœ ˜Jš žœ žœžœžœžœ˜-Jšžœ˜ ——šŸ œžœ˜š žœžœžœžœ žœž˜AJšœ˜Jšžœ žœžœ˜Jšœ.žœ˜4Jšœžœ˜Jšœ(žœ˜/Jšžœ˜ J˜——šžœž˜!Jšžœ$žœžœžœ˜>Jš žœ žœžœžœžœ˜-Jšžœ˜—J˜JšœI™IJšœ˜Jšžœžœžœ˜8Jšœ ˜ J˜Jšžœ˜J˜—šŸ œžœžœž˜3šŸœžœžœž˜&Jšœ˜Jšžœžœžœ˜+Jšœžœ˜!J˜Jšžœ˜—J˜šžœ žœž˜Jšžœ!žœ žœ žœ˜H—Jšžœ˜J˜—šŸœžœž˜-Jšœ1˜1šžœ žœž˜šžœžœ˜+Jšžœžœ˜(—Jšžœ˜—Jšžœ˜—J˜š Ÿœžœžœ+žœžœž˜Sš œ žœ žœžœ žœž˜2J˜&—Jšžœžœ žœ˜$Jšžœžœžœžœ˜ Jš œžœžœžœžœžœ˜=šžœ žœž˜J˜L—Jš žœžœžœ žœžœ˜BJšžœ˜J˜—šŸœžœžœž˜8J˜šŸœžœ˜šžœž˜!Jšœžœ˜J˜Jšœ(žœ˜/Jš žœ žœžœžœžœ˜-Jšžœ˜ —J˜—šžœž˜!Jšžœ$žœžœžœ˜>Jš žœ žœžœžœžœ˜-Jšžœ˜—J˜Jšžœ žœžœ˜)Jšžœ žœžœ˜'J˜JšœG˜GJšžœ˜J˜—šŸ œžœžœž˜0šŸœžœž˜Jšœ žœ˜J˜Jšžœ˜—J˜šžœ žœž˜Jšžœ!žœ žœ žœ˜H—Jšžœ˜J˜—š Ÿ œžœžœ žœž˜JJš œ žœžœžœžœ˜Tšžœ žœžœ ˜"J˜:—J˜*Jšžœ˜—J˜šŸ œžœžœž˜!Jš™J˜.šœž˜J˜šžœžœ žœž˜5Jšžœžœžœžœ˜-—Jšœžœ˜!Jšžœžœ˜/š žœžœžœžœžœž˜>Jšœžœ˜!Jšžœ˜—J˜Jšžœžœ˜ Jšžœ˜—šžœ žœž œ˜KJšœ0˜0Jšžœžœ˜-Jšžœ˜—J˜šžœ žœž œ˜KJšžœžœ˜/Jšœ˜Jšžœ˜—Jšžœ˜J˜—š Ÿœžœžœžœžœ ˜2J˜J˜Jšœžœžœ˜+Jšœ˜J˜J˜Jšžœžœ˜:J˜J˜Jšžœ˜J˜—šŸœžœžœžœ˜CJšžœ žœž˜!Jšœžœ˜ šžœžœžœ#˜5šœ žœ žœžœ˜8Jšžœ0˜4—J˜Jšžœžœ˜)J˜J˜Jšžœ˜—Jšžœ ˜Jšžœ˜J˜—šŸ œžœžœ˜9Jšžœžœž˜.Jšžœžœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜ J˜šŸ œžœžœ ž˜*šžœ ž œžœž˜%šžœ?žœžœž˜PJšžœžœžœ˜Jšžœ˜—Jšžœžœžœžœ˜Jšžœ˜—Jšžœ˜—J˜š Ÿ œžœ žœžœž˜3š œžœžœžœžœž˜=Jš œžœ žœžœ žœžœ˜WJ˜——š Ÿœžœžœžœž˜$šœžœžœ"ž˜1Jšœžœ$˜(J˜——š Ÿœžœ žœžœž˜=Jšœžœ˜J˜š Ÿœžœ žœžœž˜;Jš œžœžœžœžœ˜>J˜—J˜J˜šœ žœ žœžœ˜2Jšžœ*˜.—Jšžœžœ˜&J˜šžœžœžœž˜)šžœžœž˜"Jš(™(J˜J˜J˜ Jšžœžœ˜ Jšžœ˜—Jšžœ˜—Jšžœžœ˜Jšžœ˜J˜—Jš žœžœžœžœžœžœ˜;J˜š žœžœžœžœ žœžœž˜OJšžœžœžœ˜,J˜—J˜š œ žœžœžœžœ˜GJšžœ4˜8J˜—Jš™Jšœžœžœ žœ ˜;Jšœ žœžœ žœ ˜2Jš œ žœ žœžœžœžœžœ ˜ZJ˜Jšžœ˜—J˜Jšžœ˜ —…— ά/Š