DIRECTORY Carets, ColorWorld USING [NewContext], Graphics USING [Context, NewContext, SetCP, SetPaintMode], GraphicsOps USING [BitmapRef, BitmapRep, DrawBitmap], Process USING [Detach, MsecToTicks, SetTimeout], ViewerClasses USING [Viewer], ViewerOps USING [UserToScreenCoords]; CaretsImpl: CEDAR MONITOR IMPORTS ColorWorld, Graphics, GraphicsOps, Process, ViewerOps EXPORTS Carets = BEGIN OPEN Carets; StartCaret: PUBLIC ENTRY PROC [viewer: ViewerClasses.Viewer, x, y: INTEGER, id: CaretId] = BEGIN ENABLE UNWIND => NULL; IF viewer = NIL THEN RETURN; InvertCaret[id, TRUE]; -- kill off old visible caret IF x =-10000 AND y =-10000 THEN SELECT id FROM -- special reset for ViewerBLTImpl to move viewers primary => {x _ pViewerX; y _ pViewerY}; secondary => {x _ sViewerX; y _ sViewerY}; ENDCASE; x _ MIN[x, viewer.cw]; IF id=primary THEN { pViewerX _ x; pViewerY _ y; [pCaretX, pCaretY] _ViewerOps.UserToScreenCoords[pCaretViewer _ viewer, x, y]} ELSE { sViewerX _ x; sViewerY _ y; [sCaretX, sCaretY] _ ViewerOps.UserToScreenCoords[sCaretViewer _ viewer, x, y]}; END; StopCaret: PUBLIC ENTRY PROC [id: CaretId] = BEGIN ENABLE UNWIND => NULL; InvertCaret[id, TRUE]; END; caretHoldCount: INTEGER _ 0; -- number of requests pending to suspend caret SuspendCarets: PUBLIC ENTRY PROC = BEGIN ENABLE UNWIND => NULL; IF pDark AND pCaretViewer#NIL THEN InvertCaret[primary]; IF sDark AND sCaretViewer#NIL THEN InvertCaret[secondary]; caretHoldCount _ caretHoldCount+1; END; ResumeCarets: PUBLIC ENTRY PROC = BEGIN ENABLE UNWIND => NULL; caretHoldCount _ MAX[0, caretHoldCount-1]; END; InvertCaret: INTERNAL PROC [id: CaretId, kill: BOOL _ FALSE] = BEGIN context: Graphics.Context _ screen; IF id=primary THEN BEGIN IF (~kill OR pDark) AND pCaretViewer#NIL THEN BEGIN IF pCaretViewer.column=color THEN BEGIN IF colorScreen=NIL THEN InitColorCaret; context _ colorScreen; END; Graphics.SetCP[context, pCaretX-caretXOffset, pCaretY]; GraphicsOps.DrawBitmap[context, pCaret, caretW, caretH]; pDark _ ~pDark; END; IF kill THEN pCaretViewer _ NIL; END ELSE BEGIN IF (~kill OR sDark) AND sCaretViewer#NIL THEN BEGIN IF sCaretViewer.column=color THEN BEGIN IF colorScreen=NIL THEN InitColorCaret; context _ colorScreen; END; Graphics.SetCP[context, sCaretX-caretXOffset, sCaretY]; GraphicsOps.DrawBitmap[context, sCaret, caretW, caretH]; sDark _ ~sDark; END; IF kill THEN sCaretViewer _ NIL; END; END; CaretProcess: ENTRY PROC = BEGIN ENABLE UNWIND => NULL; TRUSTED {Process.SetTimeout[@timeOut, Process.MsecToTicks[500]]}; DO WAIT timeOut; IF caretHoldCount#0 THEN LOOP; -- suspended IF pCaretViewer#NIL THEN InvertCaret[primary]; IF sCaretViewer#NIL THEN InvertCaret[secondary]; ENDLOOP; END; InitColorCaret: PROC = BEGIN colorScreen _ ColorWorld.NewContext[]; [] _ Graphics.SetPaintMode[colorScreen, invert]; END; timeOut: CONDITION; caretH: INTEGER = 6; caretW: INTEGER = 16; caretXOffset: CARDINAL = 8; CaretArray : TYPE = ARRAY [0..caretH) OF UNSPECIFIED; pCaretX, pCaretY, sCaretX, sCaretY: INTEGER; pViewerX, pViewerY, sViewerX, sViewerY: INTEGER; pDark, sDark: BOOLEAN _ FALSE; pCaretViewer, sCaretViewer: PUBLIC ViewerClasses.Viewer; screen: Graphics.Context _ Graphics.NewContext[]; colorScreen: Graphics.Context; pCaret: GraphicsOps.BitmapRef _ NEW[GraphicsOps.BitmapRep _ [base: NEW[CaretArray _ [ 000400B, 001600B, 003700B, 003300B, 006140B, 004040B ]], raster: (caretW+15)/16, width: caretW, height: caretH ]]; sCaret: GraphicsOps.BitmapRef _ NEW[GraphicsOps.BitmapRep _ [base: NEW[CaretArray _ [ 000400B, 001200B, 002100B, 002100B, 004040B, 004040B ]], raster: (caretW+15)/16, width: caretW, height: caretH ]]; [] _ Graphics.SetPaintMode[screen, invert]; TRUSTED {Process.Detach[FORK CaretProcess]}; -- start the blinker END. ΎCaretsImpl.mesa; Edited by McGregor on May 31, 1983 11:18 am Last Edited by: Maxwell, May 19, 1983 1:24 pm Screw the NOTIFY; CaretProcess will eventually wake up and notice new caret Κv– "Mesa" style˜JšΟc<™