DIRECTORY Carets, CaretsExtras USING [], Imager USING [Context, MaskPixel, PixelArray, SetColor], ImagerOps USING [XOR], Process USING [Detach, MsecToTicks, SetTimeout], ViewerClasses USING [Viewer], ViewerExtras USING [PaintClient]; CaretsImpl: CEDAR MONITOR IMPORTS Imager, ImagerOps, Process, ViewerExtras EXPORTS Carets, CaretsExtras = BEGIN OPEN Carets; timeOut: CONDITION; caretH: INTEGER = 6; caretW: INTEGER = 16; caretXOffset: CARDINAL = 8; CaretArray: TYPE = ARRAY [0..caretH) OF WORD; pCaretArray: CaretArray _ [ 000400B, -- 0000000100000000 001600B, -- 0000001110000000 003700B, -- 0000011111000000 003300B, -- 0000011011000000 006140B, -- 0000110001100000 004040B -- 0000100000100000 ]; sCaretArray: CaretArray _ [ 000400B, -- 0000000100000000 001200B, -- 0000001010000000 002100B, -- 0000010001000000 002100B, -- 0000010001000000 004040B, -- 0000100000100000 004040B -- 0000100000100000 ]; pCaret: Imager.PixelArray _ NIL; sCaret: Imager.PixelArray _ NIL; pX, pY, sX, sY: INTEGER; pDark, sDark: BOOLEAN _ FALSE; pCaretViewer, sCaretViewer: PUBLIC ViewerClasses.Viewer; StartCaret: PUBLIC ENTRY PROC[viewer: ViewerClasses.Viewer, x, y: INTEGER, id: CaretId] = { 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 _ pX; y _ pY}; secondary => {x _ sX; y _ sY}; ENDCASE; x _ MIN[x, viewer.cw]; SELECT id FROM primary => { pX _ x; pY _ y; pCaretViewer _ viewer; }; secondary => { sX _ x; sY _ y; sCaretViewer _ viewer; }; ENDCASE; }; 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; SuspendVisibleCarets: PUBLIC ENTRY PROC = BEGIN -- exported to CaretsExtras ENABLE UNWIND => NULL; IF NOT pDark AND pCaretViewer#NIL THEN InvertCaret[primary]; IF NOT 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 SELECT id FROM primary => { IF (~kill OR pDark) AND pCaretViewer#NIL THEN { action: PROC[context: Imager.Context] ~ { Imager.SetColor[context, ImagerOps.XOR]; Imager.MaskPixel[context, pCaret]; }; ViewerExtras.PaintClient[pCaretViewer, action]; pDark _ ~pDark; }; IF kill THEN pCaretViewer _ NIL; }; secondary => { action: PROC[context: Imager.Context] ~ { Imager.SetColor[context, ImagerOps.XOR]; Imager.MaskPixel[context, sCaret]; }; IF (~kill OR sDark) AND sCaretViewer#NIL THEN { ViewerExtras.PaintClient[sCaretViewer, action]; sDark _ ~sDark; }; IF kill THEN sCaretViewer _ NIL; }; ENDCASE; 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; TRUSTED {Process.Detach[FORK CaretProcess]}; -- start the blinker END. πCaretsImpl.mesa Copyright c 1983, 1984 Xerox Corporation. All rights reserved. Edited by McGregor on May 31, 1983 11:18 am Last Edited by: Maxwell, May 19, 1983 1:24 pm Last Edited by: Paul Rovner, June 15, 1983 4:57 pm Doug Wyatt, September 4, 1984 11:54:07 am PDT TRUSTED { Imager.MaskBits[context: context, x: pX-caretXOffset, y: pY, base: @pCaret, wpl: 1, fMin: 0, sMin: 0, fSize: caretW, sSize: caretH] }; Screw the NOTIFY; CaretProcess will eventually wake up and notice new caret Κ„– "Mesa" style˜šΟc™Jšœ Οmœœ/™?Jš+™+J™-J™2J™-—J˜šΟk ˜ J˜Jšœ Ÿœ˜JšœŸœ,˜8Jšœ ŸœŸœ˜JšœŸœ#˜0JšœŸœ ˜Jšœ Ÿœ˜!J˜—Jšœ Ÿ ˜JšŸœ)˜0JšŸœ˜JšœŸœŸœ˜J˜Jšœ Ÿ œ˜J˜JšœŸœ˜JšœŸœ˜JšœŸœ˜J˜Jš œ ŸœŸœ ŸœŸœ˜-J˜šœ˜J˜J˜J˜J˜J˜J˜J˜J˜—šœ˜J˜J˜J˜J˜J˜J˜J˜J˜—JšœŸœ˜ JšœŸœ˜ J˜šŸœ?™FJšœI™IJ™—JšœŸœ˜JšœŸœŸœ˜JšœŸœ˜8J˜š Οn œŸœŸœŸœ%Ÿœ˜[JšŸœŸœŸœ˜JšŸœ ŸœŸœŸœ˜JšœŸœ˜4J˜š Ÿœ Ÿœ ŸœŸœŸœ2˜aJšœ˜Jšœ˜JšŸœ˜J˜—JšœŸœ˜šŸœŸ˜Jšœ6˜6Jšœ8˜8JšŸœ˜J˜—JšK™KJšœ˜J˜—š   œŸœŸœŸœŸ˜2JšŸœŸœŸœ˜JšœŸœ˜JšŸœ˜J˜—JšœŸœ.˜KJ˜š   œŸœŸœŸœŸ˜(JšŸœŸœŸœ˜JšŸœŸœŸœŸœ˜8JšŸœŸœŸœŸœ˜:J˜"JšŸœ˜J˜—š  œŸœŸœŸœŸœ˜KJšŸœŸœŸœ˜Jš ŸœŸœŸœŸœŸœ˜J˜"JšŸœ˜J˜—š   œŸœŸœŸœŸ˜'JšŸœŸœŸœ˜JšœŸœ˜*JšŸœ˜J˜—š   œŸœŸœŸœŸœŸ˜DšŸœŸ˜˜ š ŸœŸœŸœŸœŸœ˜/šœŸœ˜)Jšœ#Ÿœ˜(J˜"J˜—Jšœ/˜/J˜Jšœ˜—JšŸœŸœŸœ˜ J˜—˜šœŸœ˜)Jšœ#Ÿœ˜(J˜"J˜—š ŸœŸœŸœŸœŸœ˜/Jšœ/˜/J˜Jšœ˜—JšŸœŸœŸœ˜ J˜—JšŸœ˜—JšŸœ˜J˜—š  œŸœŸœŸ˜ JšŸœŸœŸœ˜JšŸœ:˜AšŸœŸœ ˜JšŸœŸœŸœ ˜+JšŸœŸœŸœ˜.JšŸœŸœŸœ˜0JšŸœ˜—JšŸœ˜J˜—JšŸœŸœ˜AJ˜JšŸœ˜J˜J˜—…— pδ