DIRECTORY BiScrollers USING [BiScroller, ClientDataOf, QuaBiScroller, QuaViewer], Commander USING [CommandProc, Register], CommandTool USING [ArgumentVector, Failed, Parse, StarExpansion], Cursors USING [CursorArray, CursorType, NewCursor], FileNames USING [CurrentWorkingDirectory, ResolveRelativePath, Directory], Geom2D USING [Rect, Vec, ExtremaOfRect, Transform, id], ImagerTransformation USING [PostTranslate], Process USING [Detach, MsecToTicks, SetTimeout], Real USING [FixI], Rope USING [Concat, Length, ROPE], ViewerOps USING [PaintViewer], TIPUser USING [InstantiateNewTIPTable, TIPTable], ViewerClasses USING [DestroyProc, Viewer], SilBiScrollers, SilFile, SilDisplay, SilDisplayUtils, SilKernel, SilUserInput ; SilKernelImpl: CEDAR MONITOR IMPORTS BiScrollers, Cursors, Commander, CommandTool, FileNames, Geom2D, ImagerTransformation, Process, SilFile, ViewerOps, Real, Rope, SilBiScrollers, SilDisplay, SilKernel, SilUserInput, SilDisplayUtils, TIPUser EXPORTS SilKernel = BEGIN SilData: TYPE = SilKernel.SilData; maxInstances: NAT _ 0; --keep non-decreasing count for viewer naming numberOfSilInstances: NAT _ 0; caretTimeout: CONDITION; SilDataList: TYPE = LIST OF SilData; silDatas: SilDataList _ NIL; --list of all sil's in the world SilError: PUBLIC ERROR [explain: SilKernel.SilErrorType] = CODE; InitSil: PROC [] = { MakeSilClass[]; SilFile.InitSil[]; SilDisplay.InitSil[]; }; StartSilInstance: PUBLIC ENTRY PROC [fileName: Rope.ROPE] = { data: SilData _ NEW[SilKernel.SilDataObject]; viewer: ViewerClasses.Viewer _ SilDisplay.InitSilDisplayInstance[data, fileName, maxInstances ! SilKernel.SilError => GOTO NotFound]; silDatas _ CONS[data, silDatas]; -- save models for repainting if fonts change TRUSTED {Process.Detach [FORK SilMain[data, viewer] ]}; IF numberOfSilInstances = 0 THEN TRUSTED {Process.Detach [FORK Carets[] ]}; numberOfSilInstances _ numberOfSilInstances + 1; maxInstances _ maxInstances + 1; EXITS NotFound => NULL; }; RepaintSilViewers: PUBLIC ENTRY PROC = { fudge: REAL = 10.0; -- fudge factor for EraseArea needed to catch all descenders in fonts xMin, yMin, xMax, yMax: INTEGER _ 0; rect: Geom2D.Rect _ [0.0, 0.0, 0.0, 0.0]; FOR d: SilDataList _ silDatas, d.rest UNTIL d=NIL DO IF d.first.mainProcessShouldStop THEN LOOP; -- already deleted Sil viewer rect _ SilDisplayUtils.BoundingBoxOfModel[dData: d.first.displayData, model: d.first.model, mapArea: FALSE]; -- Returns RECORD [x, y, w, h: REAL] FOR s: SilFile.SilObject _ SilFile.GetObjectList[d.first.model, fgnd], s.rest UNTIL s=NIL DO IF s.first.font IN SilFile.InternalPresetFonts THEN { [xMin: , yMin: , xMax: xMax, yMax: yMax] _ SilDisplayUtils.BoundingBoxOfObject[d.first.model, s.first]; s.first.xMax _ s.first.xMin+xMax; s.first.yMax _ s.first.yMin+yMax; }; ENDLOOP; IF NOT SilUserInput.GetBiScroller[d.first.uiData].QuaViewer[].parent.iconic THEN { SilUserInput.Enque[[EraseArea[Real.FixI[rect.x-fudge], Real.FixI[rect.y-fudge], Real.FixI[rect.x+rect.w+fudge], Real.FixI[rect.y+rect.h+fudge]]], d.first.uiData]; rect _ SilDisplayUtils.BoundingBoxOfModel[dData: d.first.displayData, model: d.first.model, mapArea: FALSE]; --get NEW bounding box, which has changed due to new fonts SilUserInput.Enque[[MergeArea[Real.FixI[rect.x-fudge], Real.FixI[rect.y-fudge], Real.FixI[rect.x+rect.w+fudge], Real.FixI[rect.y+rect.h+fudge]]], d.first.uiData]; }; ENDLOOP; SilFile.EvaluateSelection[]; }; SilMain: PROC [data: SilData, viewer: ViewerClasses.Viewer] = { WHILE NOT data.mainProcessShouldStop DO IF SilUserInput.InputAvailable[data.uiData] THEN IF NOT viewer.parent.iconic THEN ViewerOps.PaintViewer[viewer: viewer, hint: client, clearClient: FALSE, whatChanged: $UserInput] ELSE NULL ELSE IF SilUserInput.ShouldChangeCaret[data.uiData] THEN { IF NOT viewer.parent.iconic THEN ViewerOps.PaintViewer[viewer: viewer, hint: client, clearClient: FALSE, whatChanged: $Carets]; SilUserInput.CaretHasChanged[data.uiData]; } ELSE IF SilDisplay.NeedRebuild[data.displayData] THEN IF NOT viewer.parent.iconic THEN ViewerOps.PaintViewer[viewer: viewer, hint: client, clearClient: FALSE, whatChanged: $Rebuild] ELSE SilDisplay.CancelRebuild[data.displayData] ELSE SilUserInput.AwaitUserInput[data.uiData]; ENDLOOP; }; Carets: PROC [] = { --Carets is forked so is not an ENTRY Proc quarterSec: INTEGER = 250; --(msecs) SetCaretBlinkInterval[quarterSec]; WHILE numberOfSilInstances > 0 DO RestCaret[]; SilDisplay.CaretBlink[]; ENDLOOP; }; SetCaretBlinkInterval: ENTRY PROC [msecs: INTEGER] = { ENABLE UNWIND => NULL; TRUSTED {Process.SetTimeout[@caretTimeout, Process.MsecToTicks[msecs]];}; }; RestCaret: ENTRY PROC [] = { ENABLE UNWIND => NULL; WAIT caretTimeout; }; SilDestroy: ViewerClasses.DestroyProc = { SilEntryDestroy[self: self]; }; SilEntryDestroy: ENTRY PROC [self: ViewerClasses.Viewer] = { data: SilData _ NARROW[BiScrollers.QuaBiScroller[self].ClientDataOf[]]; data.mainProcessShouldStop _ TRUE; SilUserInput.DestroyUserInput[data.uiData]; numberOfSilInstances _ numberOfSilInstances - 1; }; SilExtremaProc: PROC [clientData: REF ANY, direction: Geom2D.Vec] RETURNS [min, max: Geom2D.Vec] --BiScrollers.ExtremaProc-- = { data: SilData _ NARROW[clientData]; area: Geom2D.Rect; area _ SilDisplayUtils.BoundingBoxOfModel[dData: data.displayData, model: data.model, mapArea: TRUE]; [min, max] _ Geom2D.ExtremaOfRect[r: area, n: direction]; }; SilBasicTransformProc: PROC [bs: BiScrollers.BiScroller] RETURNS [t: Geom2D.Transform] --BiScrollers.TransformGenerator-- = { iv: ViewerClasses.Viewer _ bs.style.QuaViewer[bs: bs, inner: TRUE]; t _ Geom2D.id.PostTranslate[[0, iv.ch]]; }; MakeSilClass: PROC [] = { myCursorBits: Cursors.CursorArray = [177700B, 177600B, 177400B, 177000B, 177400B, 177600B, 177700B, 167740B, 143760B, 101770B, 774B, 376B, 177B, 76B, 34B, 10B]; myCursor: Cursors.CursorType _ Cursors.NewCursor[myCursorBits]; tipTable: TIPUser.TIPTable _ TIPUser.InstantiateNewTIPTable["Sil.tip"]; SilUserInput.InitTipTable[tipTable]; SilBiScrollers.silClass _ SilBiScrollers.bsStyle.NewBiScrollerClass [[flavor: $Sil, extrema: SilExtremaProc, notify: SilUserInput.SilNotify, paint: SilDisplay.SilPaintProc, --call SilPaint when viewer needs to be repainted modify: SilUserInput.SilModifyInputFocus, --Call when input focus is taken destroy: SilDestroy, finish: LIST[$Exit], save: SilDisplay.SilSaveProc, tipTable: tipTable, cursor: myCursor, mayStretch: FALSE, offsetsMustBeIntegers: TRUE, preferIntegerCoefficients: TRUE, -- integer coefficients in transform vanilla: SilBasicTransformProc, --proc which provides the basic transform for BiScrollers preserve: [X: 0, Y: 1] --this specifies point that stays fixed when viewer size changes ]]; }; StartSilCommand: Commander.CommandProc = { argv: CommandTool.ArgumentVector; name, dir: Rope.ROPE; CommandTool.StarExpansion[cmd]; argv _ CommandTool.Parse[cmd ! CommandTool.Failed => CONTINUE; ]; IF argv = NIL THEN RETURN[$Failure, "Sil initialization procedure is confused"]; IF argv.argc < 2 THEN { --Sil called with no file name given. StartSilInstance[fileName: ""]; RETURN; }; FOR i: NAT IN [1..argv.argc) DO --open a sil window on each file given name _ FileNames.ResolveRelativePath[argv[i]]; dir _ FileNames.Directory[name]; IF Rope.Length[dir] = 0 THEN name _ Rope.Concat[FileNames.CurrentWorkingDirectory[], name]; StartSilInstance[fileName: name]; ENDLOOP; }; InitSil[]; Commander.Register[key: "Sil", proc: StartSilCommand, doc: "Create a Window Sil Instance" ]; END. 8SilKernelImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Tracy Larrabee: March 28, 1984 7:38:21 pm PST Last Edited by Ken Pier, August 22, 1985 4:17:15 pm PDT This file contains the top level procedures for the functioning of Sil. There are global initialization procedures, an init procedure that happens once per sil instance, some procedures which manage sil carets, and SilMain - the procedure that keeps a sil instance painting and accepting commands. keep the number of instances so we know when to fire up a cursor blinking process (see StartSilInstance, below). A global condition variable for the blinking of the carets Initialize background datastructures which will be used by all Sil instances. Prepare for the eventual creation of Sil viewers: Initialize All the Sil Library data structures: Initialize everything that will be needed to start a bare Sil open on fileName (the fileName may be an empty rope). ViewerOps.PaintViewer[viewer, all]; -- InitSilDisplayInstance paints viewer immediately before This routine is called after swapping fonts between display and printing fonts. Since there is only one font set for all Sil viewers, all viewers are erased, their string bounding boxes recalculated, and then they are repainted with the new fonts. Next loop recalculates string bounding boxes with new font metrics now fix up the selection bounds as well the PaintProc actually processes the user input !! viewer is the ButtonedContainer which contains the BiScroller; viewer.parent is the Abutter which contains everything Set information which will cause the carets (the mark and the origin) to blink appropriately until the destroy proc tells us that we neednt do it anymore. Make it so the carets will blink every msecs milliseconds. Pause for the appropriate time so that the carets will blink pleasingly. [self: Viewer] Perform the correct actions upon destruction of a Sil instance. Called when viewer is destroyed. This proc is required by BiScrollers to return the extremes of the displayed data in this model Make client <0,0> appear at the upper left corner of viewer. Set up things so Viewers will know which procedures to call after interesting event. [cmd: Handle] When Sil is run, the library data structures will be initialized and the sil command will be registered with the system. ΚΕ˜code™Kšœ Οmœ1™<—K™-™7K™K™ͺ—K™šΟk ˜ šœ ž˜Kšœ5˜5—šœ ž˜K˜—šœ žœ˜Kšœ/˜/—šœž˜ K˜%—šœ ž˜K˜:—Kšœžœ+˜7šœž˜K˜—šœž˜ K˜"—šœž˜ Kšœ˜—šœž˜ Kšœžœ˜—šœ žœ˜Kšœ˜—šœžœ˜Kšœ#˜#—šœžœ˜Kšœ˜—Kšœ˜Kšœ˜K˜ K˜K˜ K˜ Kšœ˜—K˜šΟb œžœž˜KšžœΞ˜ΥKšžœ žœ˜—K˜Kšœ žœ˜"KšœžœΟc-˜Dšœžœ˜Kšœp™p—šœž œ˜Kšœ:™:—Kšœ ž œžœ ˜$Kšœžœ  ˜=K˜šŸœžœžœ$žœ˜@K˜—šΟnœžœ˜K™MK˜K™1K˜K™/K˜K˜K˜K˜—š‘œžœž œžœ˜=K™sK™Kšœžœ˜-Kšœvžœ ˜…Kšœ^™^Kšœ žœ -˜NKšžœžœ˜7šžœž˜ Kšžœžœ ˜*—Kšœ0˜0Kšœ ˜ šž˜Kšœ žœ˜—K˜K˜—š‘œžœžœžœ˜(K™χK™Kšœžœ  E˜YKšœžœ˜$Kšœ)˜)šžœ#žœžœž˜4Kšžœžœžœ ˜IKšœežœ $˜‘K™BšžœKžœžœž˜\šžœžœžœ˜5Kšœg˜gKšœ!˜!Kšœ!˜!K˜—Kšžœ˜—šžœžœFžœ˜RKšœ’˜’Kšœežœ :˜§Kšœ’˜’K˜—Kšžœ˜—K™'K˜K˜K˜—š‘œžœ1˜?Kš ¨™¨K˜šžœžœž˜'šžœ*žœ˜1Kš žœžœžœBžœžœž˜‹—šžœžœ-žœ˜:KšžœžœžœBžœ˜Kšœ*˜*K˜—šžœžœ*žœ˜6Kš žœžœžœBžœžœ+˜―—šžœ˜Kšœ)˜)——Kšžœ˜K˜K˜—š‘œžœ *˜>K™šK™Kšœ žœ  ˜$Kšœ"˜"šžœžœ˜"K˜ Kšœ˜Kšžœ˜—K˜K˜—š‘œžœžœ žœ˜6K™:K™šžœžœžœ˜KšžœB˜I—Kšœ˜K˜—š‘ œž œ˜K™Hšžœžœžœ˜Kšžœ˜—K˜K˜—š‘ œ ˜*Kšœ™Kšœ˜K˜K™—š‘œž œ!˜=KšœR™RK™ K™Kšœžœ1˜GKšœžœ˜"Kšœ+˜+Kšœ0˜0K˜K˜—š ‘œžœžœžœžœ œ˜€K™_Kšœžœ ˜#Kšœ˜Kšœ_žœ˜eKšœ9˜9K˜K˜—š‘œžœžœ "œ˜}Kšœ=žœ˜C˜(K™<—K˜K˜—š‘ œžœ˜KšœV™VK™K˜ K˜?KšœG˜GKšœ$˜$šœ˜šœ)˜)Kšœ˜Kšœ˜K˜Kšœ  1˜QKšœ*  ˜JK˜Kšœžœ˜K˜Kšœ˜Kšœ˜Kšœ žœ˜Kšœžœ˜Kšœžœ $˜EKšœ  9˜YKšœ žœžœ @˜XKšœ˜——K˜K˜—šŸœ˜*Kšœ ™ K™Kšœ!˜!Kšœžœ˜Kšœ˜Kšœ5žœ˜AKšžœžœžœžœ7˜Pšžœžœ %˜=Kšœ˜Kšžœ˜K˜—š žœžœžœžœ &˜FKšœ.˜.Kšœ ˜ Kšžœžœ?˜[Kšœ!˜!Kšžœ˜—K˜K˜—K™Kšœx™xK™KšŸ ˜ šŸ5˜5KšŸ&˜&K˜—Kšžœ˜—…—,.)