DIRECTORY Imager USING [black, Context, MaskRectangleI, SetColor, white], Terminal USING [Virtual, Current, FrameBuffer, BWCursorBitmap, GetBWFrameBuffer, SetBWCursorPattern, ColorCursorBitmap, GetColorFrameBufferA, SetColorCursorPattern, SetColorCursorPresentation], ViewerClasses USING [Viewer], SilFile, SilDisplayCursors, SilDisplayInternal, SilDisplayUtils, SilKernel, SilUserInput, ImagerPixelMap, ImagerOps, PrincOps ; SilDisplayCursorsImpl: CEDAR MONITOR IMPORTS Imager, Terminal, SilUserInput, SilDisplayUtils, SilFile, ImagerPixelMap, ImagerOps EXPORTS SilDisplayCursors, SilKernel = BEGIN OPEN SilFile; SilData: TYPE = SilKernel.SilData; SilDisplayData: TYPE = REF SilDisplayDataRec; SilDisplayDataRec: PUBLIC TYPE = SilDisplayInternal.SilDisplayDataRec; SilModel: TYPE = SilFile.SilModel; SilUIData: TYPE = SilKernel.SilUIData; markWidth: NAT _ 2; markLength: NAT _ 6; originWidth: NAT _ 4; originLength: NAT _ 2; defaultTicSpacing: NAT = 16; originBlackNow: BOOL; dataOfOriginViewer: SilData; originX: INTEGER; originY: INTEGER; oldOriginNeedsCleared: BOOL; dataOfOldOriginViewer: SilData; oldOriginX: INTEGER; oldOriginY: INTEGER; markBlackNow: BOOL; dataOfMarkViewer: SilData; markX: INTEGER; markY: INTEGER; oldMarkNeedsCleared: BOOL; dataOfOldMarkViewer: SilData; oldMarkX: INTEGER; oldMarkY: INTEGER; dataOfCurrentSelection: SilData; SilCursorsInit: PUBLIC ENTRY PROC [] = { originBlackNow _ FALSE; dataOfOriginViewer_ NIL; originX _ 0; originY _ 0; oldOriginNeedsCleared _ FALSE; dataOfOldOriginViewer _ NIL; oldOriginX _ 0; oldOriginY _ 0; markBlackNow _ FALSE; dataOfMarkViewer _ NIL; markX _ 0; markY _ 0; oldMarkNeedsCleared _ FALSE; dataOfOldMarkViewer _ NIL; oldMarkX _ 0; oldMarkY _ 0; dataOfCurrentSelection _ NIL; }; SilCursorsBlink: PUBLIC ENTRY PROC [] = { IF dataOfOriginViewer # NIL THEN IF SilUserInput.HasInputFocus[] OR originBlackNow THEN SilUserInput.SetCaretChange[dataOfOriginViewer.uiData]; IF dataOfMarkViewer # NIL THEN IF SilUserInput.HasInputFocus[] OR markBlackNow THEN SilUserInput.SetCaretChange[dataOfMarkViewer.uiData]; }; SilCaretSize: PUBLIC ENTRY PROC [newMarkWidth, newMarkLength, newOriginWidth, newOriginLength: NAT] = { markWidth _ newMarkWidth; markLength _ newMarkLength; originWidth _ newOriginWidth; originLength _ newOriginLength; }; SilCaretPaint: PUBLIC ENTRY PROC [data: SilData, ctx: Imager.Context] = { IF oldMarkNeedsCleared AND dataOfOldMarkViewer = data THEN { Imager.SetColor[ctx, Imager.white]; Imager.MaskRectangleI[ctx, oldMarkX, oldMarkY, markWidth, markLength]; SilDisplayUtils.MergeRebuild[data.displayData, data.model, oldMarkX, oldMarkY, oldMarkX + markWidth, oldMarkY + markLength]; oldMarkNeedsCleared _ FALSE; }; IF oldOriginNeedsCleared AND dataOfOldOriginViewer = data THEN { Imager.SetColor[ctx, Imager.white]; Imager.MaskRectangleI[ctx, oldOriginX, oldOriginY, originWidth, originLength]; SilDisplayUtils.MergeRebuild[data.displayData, data.model, oldOriginX, oldOriginY, oldOriginX + originWidth, oldOriginY + originLength]; oldOriginNeedsCleared _ FALSE; }; IF dataOfMarkViewer = data THEN { IF dataOfOriginViewer = data THEN originBlackNow _ markBlackNow;--blink in phase if possible IF markBlackNow THEN Imager.SetColor[ctx, Imager.white] ELSE Imager.SetColor[ctx, Imager.black]; markBlackNow _ NOT markBlackNow; Imager.MaskRectangleI[ctx, markX, markY, markWidth, markLength]; }; IF dataOfOriginViewer = data THEN { IF originBlackNow THEN Imager.SetColor[ctx, Imager.white] ELSE Imager.SetColor[ctx, Imager.black]; originBlackNow _ NOT originBlackNow; Imager.MaskRectangleI[ctx, originX, originY, originWidth, originLength]; }; }; AquireAndDisableTheMark: PUBLIC ENTRY PROC [data: SilData, ctx: Imager.Context _ NIL] = { TurnOffTheMark[data, ctx]; dataOfMarkViewer _ data; SilUserInput.GetInputFocus[data.uiData]; }; TurnOffTheMark: INTERNAL PROC [data: SilData, ctx: Imager.Context _ NIL] = { dataOfOldMarkViewer _ dataOfMarkViewer; oldMarkX _ markX; oldMarkY _ markY; IF dataOfMarkViewer # data AND dataOfMarkViewer # NIL THEN { oldMarkNeedsCleared _ TRUE; SilUserInput.SetCaretChange[dataOfOldMarkViewer.uiData]; } ELSE IF ctx # NIL THEN { Imager.SetColor[ctx, Imager.white]; Imager.MaskRectangleI[ctx, markX, markY, markWidth, markLength]; SilDisplayUtils.MergeRebuild[data.displayData, data.model, markX, markY, markX + markWidth, markY + markLength]; }; }; AquireAndDisableTheOrigin: PUBLIC ENTRY PROC [data: SilData, ctx: Imager.Context _ NIL] = { TurnOffTheOrigin[data, ctx]; dataOfOriginViewer _ data; IF NOT SilUserInput.HasInputFocus[] THEN SilUserInput.GetInputFocus[data.uiData]; }; TurnOffTheOrigin: INTERNAL PROC [data: SilData, ctx: Imager.Context _ NIL] = { dataOfOldOriginViewer _ dataOfOriginViewer; oldOriginX _ originX; oldOriginY _ originY; IF dataOfOriginViewer # data AND dataOfOriginViewer # NIL THEN { oldOriginNeedsCleared _ TRUE; SilUserInput.SetCaretChange[dataOfOldOriginViewer.uiData]; } ELSE IF ctx # NIL THEN { Imager.SetColor[ctx, Imager.white]; Imager.MaskRectangleI[ctx, originX, originY, originWidth, originLength]; SilDisplayUtils.MergeRebuild[data.displayData, data.model, originX, originY, originX + originWidth, originY + originLength]; }; }; CheckSelectionWindow: PUBLIC ENTRY PROC [data: SilData] = { IF data # dataOfCurrentSelection AND dataOfCurrentSelection # NIL THEN { sSel: SilSelection _ SilFile.GetSelection[]; xMin: INTEGER _ sSel.xMin; yMin: INTEGER _ sSel.yMin; xMax: INTEGER _ sSel.xMax; yMax: INTEGER _ sSel.yMax; SilFile.DeselectAll[]; SilDisplayUtils.MergeRebuild[ dData: dataOfCurrentSelection.displayData, model: dataOfCurrentSelection.model, xMin: xMin, yMin: yMin, xMax: xMax, yMax: yMax ]; }; dataOfCurrentSelection _ data; }; MoveOriginToMark: PUBLIC ENTRY PROC [data: SilData, ctx: Imager.Context _ NIL] = { TurnOffTheOrigin[data, ctx]; dataOfOriginViewer _ dataOfMarkViewer; originX _ markX; originY _ markY; SilUserInput.SetCaretChange[dataOfMarkViewer.uiData]; }; InterchangeMarkAndOrigin: PUBLIC ENTRY PROC [data: SilData, ctx: Imager.Context _ NIL] = { oMarkX: INTEGER _ markX; oMarkY: INTEGER _ markY; oDataOfMarkViewer: SilData _ dataOfMarkViewer; oDataOfOriginViewer: SilData _ dataOfOriginViewer; TurnOffTheOrigin[data, ctx]; TurnOffTheMark[data, ctx]; markX _ originX; markY _ originY; dataOfMarkViewer _ oDataOfOriginViewer; originX _ oMarkX; originY _ oMarkY; dataOfOriginViewer _ oDataOfMarkViewer; SilUserInput.GetInputFocus[dataOfMarkViewer.uiData]; SilUserInput.SetCaretChange[dataOfMarkViewer.uiData]; SilUserInput.SetCaretChange[dataOfOriginViewer.uiData]; }; DeleteAndEraseSelection: PUBLIC ENTRY PROC [data: SilData, ctx: Imager.Context _ NIL, cache: BOOL _ FALSE] = { fudge: INTEGER = 10; -- fudge factor for EraseArea needed to catch all descenders in fonts sSel: SilSelection _ SilFile.GetSelection[]; xMin: INTEGER _ sSel.xMin; yMin: INTEGER _ sSel.yMin; xMax: INTEGER _ sSel.xMax; yMax: INTEGER _ sSel.yMax; IF dataOfCurrentSelection # NIL AND sSel.objects # NIL THEN { SilUserInput.Enque[[MarkAsEdited[]], dataOfCurrentSelection.uiData]; IF data = dataOfCurrentSelection THEN { FOR s: SilObject _ sSel.objects, s.first.selectObj WHILE s # sSel.lastObject DO SilDisplayUtils.PaintObject[data.model, s.first, erase, ctx];--UNselect all objects ENDLOOP; } ELSE SilUserInput.Enque[[EraseArea[xMin-fudge, yMin-fudge, xMax+fudge, yMax+fudge]], dataOfCurrentSelection.uiData]; SilFile.DeleteAndCacheSelection[cache: cache]; SilDisplayUtils.MergeRebuild[ dataOfCurrentSelection.displayData, dataOfCurrentSelection.model, xMin-fudge, yMin-fudge, xMax+fudge, yMax+fudge ]; }; dataOfCurrentSelection _ NIL; SilDisplayUtils.ChangeCommandLineData[data: data, ctx: ctx, change: Selections, intArg1: 0]; }; DeselectAndRedraw: PUBLIC ENTRY PROC [] = { sSel: SilSelection _ SilFile.GetSelection[]; xMin: INTEGER _ sSel.xMin; yMin: INTEGER _ sSel.yMin; xMax: INTEGER _ sSel.xMax; yMax: INTEGER _ sSel.yMax; SilFile.DeselectAll[]; IF dataOfCurrentSelection # NIL AND sSel.objects # NIL THEN SilDisplayUtils.MergeRebuild[ dataOfCurrentSelection.displayData, dataOfCurrentSelection.model, xMin, yMin, xMax, yMax ]; dataOfCurrentSelection _ NIL; }; InitiateNewSelection: PUBLIC ENTRY PROC [data: SilData] = { dataOfCurrentSelection _ data; }; MouseAndMarkInSameWindow: PUBLIC ENTRY PROC [data: SilData] RETURNS [BOOL] = { RETURN[data = dataOfMarkViewer]; }; MouseAndOriginInSameWindow: PUBLIC ENTRY PROC [data: SilData] RETURNS [BOOL] = { RETURN[data = dataOfOriginViewer]; }; MouseAndSelectionInSameWindow: PUBLIC ENTRY PROC [data: SilData] RETURNS [BOOL] = { RETURN[data = dataOfCurrentSelection]; }; MarkAndOriginInSameWindow: PUBLIC ENTRY PROC [] RETURNS [BOOL] = { RETURN[dataOfOriginViewer = dataOfMarkViewer]; }; MarkAndSelectionInSameWindow: PUBLIC ENTRY PROC [] RETURNS [BOOL] = { RETURN[dataOfCurrentSelection = dataOfMarkViewer]; }; OriginAndSelectionInSameWindow: PUBLIC ENTRY PROC [] RETURNS [BOOL] = { RETURN[dataOfCurrentSelection = dataOfOriginViewer]; }; DisableRopeInput: PUBLIC ENTRY PROC [data: SilData, ctx: Imager.Context _ NIL] = { IF data = dataOfMarkViewer THEN SilDisplayUtils.AbortRopeInput[data, markX, markY, ctx]; }; SetMarkX: PUBLIC ENTRY PROC [mX: INTEGER] = { markX _ mX }; SetMarkY: PUBLIC ENTRY PROC [mY: INTEGER] = { markY _ mY; }; SetOriginX: PUBLIC ENTRY PROC [ oX: INTEGER] = { originX _ oX }; SetOriginY: PUBLIC ENTRY PROC [oY: INTEGER] = { originY _ oY; }; GetMarkX: PUBLIC ENTRY PROC [] RETURNS [mX: INTEGER] = { mX _ markX }; GetMarkY: PUBLIC ENTRY PROC [] RETURNS [mY: INTEGER] = { mY _ markY; }; GetOriginX: PUBLIC ENTRY PROC [] RETURNS [oX: INTEGER] = { oX _ originX }; GetOriginY: PUBLIC ENTRY PROC [] RETURNS [oY: INTEGER] = { oY _ originY; }; GetBoundingBoxOfLast2Marks: PUBLIC ENTRY PROC [data: SilData] RETURNS [legalBox: BOOL _ TRUE, xMin, yMin, xMax, yMax: INTEGER _ 0] = { IF dataOfMarkViewer # data OR dataOfOldMarkViewer # data THEN { legalBox _ FALSE; RETURN; }; IF oldMarkX < markX THEN { xMin _ oldMarkX; xMax _ markX; } ELSE { xMin _ markX; xMax _ oldMarkX; }; IF oldMarkY < markY THEN { yMin _ oldMarkY; yMax _ markY; } ELSE { yMin _ markY; yMax _ oldMarkY; }; }; BitmapToCursor: PUBLIC PROC [x, y: NAT, viewer: ViewerClasses.Viewer] = TRUSTED { vt: Terminal.Virtual = Terminal.Current[]; IF viewer.column#color THEN { --viewer on BW display dr: ImagerPixelMap.DeviceRectangle _ [sMin: MAX[(vt.bwHeight-y),0], fMin: x, sSize: 16, fSize: 16]; cursorBitmapRef: REF Terminal.BWCursorBitmap _ NEW[Terminal.BWCursorBitmap]; screenPMap: ImagerPixelMap.PixelMap _ ImagerOps.PixelMapFromFrameBuffer[frameBuffer: Terminal.GetBWFrameBuffer[vt]]; cursorPMap: ImagerPixelMap.PixelMap _ ImagerPixelMap.Create[lgBitsPerPixel: 0, bounds: [sMin: 0, fMin: 0, sSize: 16, fSize: 16]]; cursorPMap.refRep.ref _ cursorBitmapRef; cursorPMap.refRep.pointer _ LOOPHOLE[cursorBitmapRef]; screenPMap _ ImagerPixelMap.SetWindow[p: screenPMap, bounds: dr]; cursorPMap.sOrigin _ screenPMap.sMin; cursorPMap.fOrigin _ screenPMap.fMin; ImagerPixelMap.Transfer[dest: cursorPMap, source: screenPMap, function: [null,null]]; IF cursorBitmapRef^=ALL[0] THEN RETURN; Terminal.SetBWCursorPattern[vt: vt, pattern: cursorBitmapRef^]; } ELSE { --viewer on color display Bit: TYPE = [0..1]; screenSMin: INTEGER _ MAX[(vt.colorHeight-y),0]; cursorBitmapRef: REF Terminal.ColorCursorBitmap _ NEW[Terminal.ColorCursorBitmap]; cursorBitmapArray: LONG POINTER TO PACKED ARRAY [0..0) OF Bit _ LOOPHOLE[cursorBitmapRef]; screenPMap: ImagerPixelMap.PixelMap _ ImagerOps.PixelMapFromFrameBuffer[frameBuffer: Terminal.GetColorFrameBufferA[vt]]; [] _ Terminal.SetColorCursorPresentation[vt: vt, new: onesAreBlack]; FOR i: INTEGER IN [0..256) DO cursorBitmapArray[i] _ IF ImagerPixelMap.GetPixel[screenPMap, screenSMin+(i/16), x+(i MOD 16)]=255 THEN 0 ELSE 1; ENDLOOP; IF cursorBitmapRef^=ALL[0] THEN RETURN; Terminal.SetColorCursorPattern[vt: vt, pattern: cursorBitmapRef^]; }; }; END. "SilDisplayCursorsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Tracy Larrabee: March 29, 1984 1:26:12 pm PST Last Edited by Ken Pier, August 22, 1985 5:07:21 pm PDT A module implementing the control of the carets and the input focus. GLOBAL VARIABLES: Information about the state of the carets: Keep data about the viewer with current selection in case we need to talk to that viewer Initialize the behavior of the Sil Carets Keep data about the viewer with current selection in case we need to talk to that viewer Make sure that all the appropriate Sil Instances know to blink their carets. Only blink the carets if Sil has the input focus. This mght produce 2 calls to the same viewer, but this is OK For this window, blink the carets which should be blinking. Turn off the mark, wherever it is, and make sure the system knows the correct window for the mark to be in. Make sure we have the input focus. Turn off the mark, wherever it is. Turn off the origin, wherever it is, and make sure the system knows the correct window for the origin to be in. Turn off the origin, wherever it is. Make sure that if data is not the current selection window it is safe to change selection windows. Move the origin to the mark Move the mark to the origin and the origin to the mark Delete the selection. Deselect and Redraw the elements which used to be selected. Set the current Selection Window. True if data is same window as window where mark is. True if data is same window as window where origin is. True if data is same window as window where selection is. True if mark is same window as window where origin is. True if mark is same window as window where selection is. True if origin is same window as window where selection is. Make sure that any textual input with respect to the current window is stopped. Set the Mark's position. Set the Mark's position. Set the Origin's position. Set the Origin's position. Get the Mark's position. Get the Mark's position. Get the Origin's position. Get the Origin's position. Return the bounding box for the last 2 marks in this window. Transfer the 16x16 bitmap with mark as upper left origin to the terminal cursor bitmap x, y in screen coordinates Now, execute a magic line of code which sets up the cursorPMap origin to "match" the screenPMap origin Κ β˜codešœ™Kšœ Οmœ1™<—K™-™7K™—K™DK˜šΟk ˜ šœž˜ Kšœ2˜2—šœ ž˜Kšœ²˜²—Kšœžœ ˜K˜Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ K˜ Kšœ˜K˜ Kšœ˜Kšœ˜—K˜šΟbœžœžœ˜%KšžœU˜\Kšžœ žœžœ ˜<—K˜Kšœ žœ˜"Kšœžœžœ˜-Kšœžœžœ(˜FKšœ žœ˜"Kšœ žœ˜&K˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ˜Kšœžœ˜Kšœžœ˜K˜šŸ™K™*—Kšœžœ˜Kšœ˜Kšœ žœ˜Kšœ žœ˜Kšœžœ˜Kšœ˜Kšœ žœ˜Kšœ žœ˜Kšœžœ˜Kšœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœ˜Kšœ žœ˜šœ žœ˜K™X—Kšœ ˜ K˜šΟnœžœžœžœ˜(Kšœ)™)K˜Kšœžœ˜Kšœžœ˜Kšœ ˜ Kšœ ˜ Kšœžœ˜Kšœžœ˜Kšœ˜Kšœ˜K˜Kšœžœ˜Kšœžœ˜Kšœ ˜ Kšœ ˜ Kšœžœ˜Kšœžœ˜Kšœ˜šœ ˜ K™X—Kšœžœ˜Kšœ˜K˜—š œžœžœžœ˜)K™LKšœ1™1Kšœ<™