DIRECTORY Carets, CedarProcess USING [SetPriority], Imager USING [Color, Context, MaskBitmap, SetColor], ImagerBackdoor USING [invert], ImagerSample USING [SampleMap, UnsafeNewSampleMap], Process USING [Detach, MsecToTicks, SetTimeout], ViewerClasses USING [Viewer], ViewerOps USING [UserToScreenCoords], ViewerPrivate USING [PaintScreen, Screen, ViewerScreen]; CaretsImpl: CEDAR MONITOR IMPORTS CedarProcess, Imager, ImagerBackdoor, ImagerSample, Process, ViewerOps, ViewerPrivate EXPORTS Carets, ViewerPrivate SHARES ViewerOps ~ BEGIN OPEN Carets; CaretId: TYPE ~ Carets.CaretId; Viewer: TYPE ~ ViewerClasses.Viewer; Screen: TYPE ~ ViewerPrivate.Screen; timeOut: CONDITION; caretH: INTEGER = 6; caretW: INTEGER = 16; caretXOffset: CARDINAL = 8; xminCaret: INTEGER ~ -4; xmaxCaret: INTEGER ~ 3; yminCaret: INTEGER ~ -caretH; ymaxCaret: INTEGER ~ 0; CaretBits: TYPE ~ REF CaretBitsRep; CaretBitsRep: TYPE = PACKED ARRAY [0..caretH) OF CARD16; caretBits: ARRAY CaretId OF CaretBits ¬ [ primary: NEW[CaretBitsRep ¬ [ 000400B, -- 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 001600B, -- 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 003700B, -- 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 003300B, -- 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 006140B, -- 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 004040B -- 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 ]], secondary: NEW[CaretBitsRep ¬ [ 000400B, -- 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 001200B, -- 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 002100B, -- 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 002100B, -- 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 004040B, -- 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 004040B -- 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 ]] ]; SampleMapFromCaretBits: PROC [bits: CaretBits] RETURNS [ImagerSample.SampleMap] ~ TRUSTED { RETURN [ImagerSample.UnsafeNewSampleMap[ box: [min: [s: 0, f: 0], max: [s: caretH, f: caretW]], bitsPerSample: 1, bitsPerLine: BITS[CARD16], base: [word: LOOPHOLE[bits], bit: 0], ref: bits, words: WORDS[CaretBitsRep] ]]; }; Caret: TYPE ~ REF CaretRep; CaretRep: TYPE ~ RECORD[ bitmap: ImagerSample.SampleMap ¬ NIL, viewer: Viewer ¬ NIL, -- viewer containing the caret x, y: INTEGER ¬ 0, -- position in viewer's client area sx, sy: INTEGER ¬ 0, -- position on screen (recomputed when caret becomes visible). visible: BOOL ¬ FALSE ]; carets: ARRAY CaretId OF Caret ¬ ALL[NIL]; InitCarets: ENTRY PROC ~ { FOR id: CaretId IN CaretId DO caret: Caret ~ NEW[CaretRep ¬ []]; caret.bitmap ¬ SampleMapFromCaretBits[caretBits[id]]; carets[id] ¬ caret; ENDLOOP; }; StartCaret: PUBLIC ENTRY PROC [viewer: Viewer, x, y: INTEGER, id: CaretId] = { caret: Caret ~ carets[id]; IF viewer = NIL THEN RETURN; KillCaret[caret]; -- kill off old visible caret x ¬ MIN[x, viewer.cw]; caret.viewer ¬ viewer; caret.x ¬ x; caret.y ¬ y; PhaseCarets[]; }; StopCaret: PUBLIC ENTRY PROC [id: CaretId] = { KillCaret[carets[id]]; }; StopCaretsInViewer: PUBLIC ENTRY PROC [viewer: Viewer] ~ { FOR id: CaretId IN CaretId DO caret: Caret ~ carets[id]; IF caret.viewer=viewer THEN KillCaret[caret]; ENDLOOP; }; caretHoldCount: INTEGER ¬ 0; -- number of requests pending to suspend caret DoWithoutCarets: PUBLIC PROC [sx, sy, w, h: INTEGER, screen: Screen, action: PROC] = { suspended: BOOL ¬ SuspendCaretsInsideBox[sx, sy, w, h, screen]; IF suspended THEN { action[ ! UNWIND => ResumeCarets[]]; ResumeCarets[]; } ELSE action[]; }; SuspendCaretsInsideBox: ENTRY PROC [x, y, w, h: INTEGER, screen: Screen] RETURNS [suspended: BOOL ¬ FALSE] = { FOR id: CaretId IN CaretId DO caret: Caret ~ carets[id]; IF caret.viewer#NIL AND caret.visible AND ViewerPrivate.ViewerScreen[caret.viewer] = screen THEN { IF caret.sx IN [x-xmaxCaret..x+w-xminCaret) AND caret.sy IN [y-ymaxCaret..y+h-yminCaret) THEN InvertCaret[caret]; }; suspended ¬ TRUE; ENDLOOP; IF suspended THEN caretHoldCount ¬ caretHoldCount+1; }; SuspendCarets: PUBLIC ENTRY PROC[visible: BOOL ¬ FALSE] = { FOR id: CaretId IN CaretId DO caret: Caret ~ carets[id]; IF caret.viewer#NIL AND caret.visible#visible THEN InvertCaret[caret]; ENDLOOP; caretHoldCount ¬ caretHoldCount+1; }; lazy: BOOL ¬ TRUE; ResumeCarets: PUBLIC ENTRY PROC = { IF caretHoldCount>0 THEN { caretHoldCount ¬ caretHoldCount-1; IF NOT lazy AND caretHoldCount = 0 THEN PhaseCarets[]; }; }; Visible: PROC [viewer: Viewer, x, y: INTEGER] RETURNS [BOOL] ~ { IF x IN[0..viewer.cw) AND y IN[0..viewer.ch) THEN { parent: Viewer ~ viewer.parent; IF parent#NIL THEN { px: INTEGER ¬ x+viewer.cx; py: INTEGER ¬ y+viewer.cy; top: BOOL ~ (parent#NIL AND parent.class.topDownCoordSys); px ¬ px+viewer.wx; IF top THEN py ¬ py+(parent.ch-viewer.wy-viewer.wh) ELSE py ¬ py+viewer.wy; RETURN[Visible[parent, px, py]]; } ELSE RETURN[TRUE]; } ELSE RETURN[FALSE]; }; InvertCaret: INTERNAL PROC [caret: Caret] ~ { ENABLE ANY => GOTO Oops; --ChJ, October 24, 1991 viewer: Viewer ~ caret.viewer; IF viewer#NIL AND (caret.visible OR Visible[viewer, caret.x, caret.y]) THEN { screen: ViewerPrivate.Screen ~ ViewerPrivate.ViewerScreen[viewer]; invertCaretAction: PROC [context: Imager.Context] ~ { Imager.SetColor[context, ImagerBackdoor.invert]; Imager.MaskBitmap[context: context, bitmap: caret.bitmap, referencePoint: [f: caretXOffset, s: 0], position: [caret.sx, caret.sy]]; caret.visible ¬ NOT caret.visible; }; IF NOT caret.visible THEN [caret.sx, caret.sy] ¬ ViewerOps.UserToScreenCoords[viewer, caret.x, caret.y]; ViewerPrivate.PaintScreen[screen: screen, action: invertCaretAction, suspendCarets: FALSE]; }; EXITS Oops => {} }; KillCaret: INTERNAL PROC [caret: Caret] ~ { IF caret.viewer=NIL THEN RETURN; IF caret.visible THEN InvertCaret[caret]; caret.viewer ¬ NIL; }; caretPhase: BOOL ¬ FALSE; -- Master ticker for carets; inverts twice a second. PhaseCarets: INTERNAL PROC ~ { FOR id: CaretId IN CaretId DO caret: Caret ~ carets[id]; IF caret.viewer#NIL AND caret.visible # caretPhase AND caretHoldCount=0 THEN InvertCaret[caret]; ENDLOOP; }; CaretProcess: ENTRY PROC = { ENABLE UNWIND => NULL; suspended: BOOL ¬ FALSE; TRUSTED {Process.SetTimeout[@timeOut, Process.MsecToTicks[500]]}; CedarProcess.SetPriority[foreground]; DO WAIT timeOut; caretPhase ¬ NOT caretPhase; PhaseCarets[]; ENDLOOP; }; InitCarets[]; TRUSTED {Process.Detach[FORK CaretProcess]}; -- start the blinker END. N CaretsImpl.mesa Copyright Σ 1985, 1986, 1991 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) June 10, 1985 7:57:21 pm PDT Michael Plass, November 21, 1985 12:29:28 pm PST Doug Wyatt, December 16, 1986 3:45:54 pm PST Pier, November 18, 1988 5:07:29 pm PST Bier, January 9, 1989 1:53:50 pm PST Christian Jacobi, October 24, 1991 5:46 pm PDT Willie-s, October 29, 1991 6:16 pm PST KAP for PCedar November 18, 1988 KAP for PCedar November 18, 1988 < NULL; ChJ: protected InvertCaret>> < NULL; ChJ: protected InvertCaret>> < NULL; ChJ: protected InvertCaret>> < NULL; ChJ: protected InvertCaret>> < NULL; ChJ: protected InvertCaret>> < NULL; ChJ: protected InvertCaret>> Puts the caret in the proper phase, unless suspended. Κ •NewlineDelimiter –(cedarcode) style™codešœ™Kšœ Οeœ=™HK™0K™0K™,K™&K™$K™.K™&—K˜šΟk ˜ Kšœ˜Kšœ žœ˜!Kšœžœ(˜4Kšœžœ ˜Kšœ žœ!˜3Kšœžœ#˜0Kšœžœ ˜Kšœ žœ˜%Kšœžœ%˜8—K˜šΠbl œžœž˜KšžœV˜]Kšžœ˜Kšžœ ˜Kšœžœžœ˜—K˜Kšœ žœ˜Kšœžœ˜$Kšœžœ˜$K˜Kšœ ž œ˜K˜Kšœžœ˜Kšœžœ˜Kšœžœ˜K˜Kšœ žœ˜Kšœ žœ˜Kšœ žœ ˜šœ žœ˜K˜—Kšœ žœžœ˜#Kšœ ™ Kš œžœžœžœ žœžœ˜8K˜šœ žœ žœ˜)šœ žœ˜Kšœ Οc"˜+Kšœ  "˜+Kšœ  "˜+Kšœ  "˜+Kšœ  "˜+Kšœ  "˜+K˜—šœ žœ˜Kšœ  "˜+Kšœ  "˜+Kšœ  "˜+Kšœ  "˜+Kšœ  "˜+Kšœ  "˜+K˜—˜K˜——šΟnœžœžœžœ˜[Kšœ ™ šžœ"˜(Kšœ7˜7Kšœžœžœžœ˜SKšœžœ˜%Kšœ˜—K˜K˜—Kšœžœžœ ˜šœ žœžœ˜Kšœ!žœ˜%Kšœžœ ˜4Kšœžœ #˜6Kšœžœ >˜SKšœ žœž˜Kšœ˜K˜—Kš œžœ žœ žœžœ˜*K˜š‘ œžœžœ˜šžœ žœ ž˜Kšœžœ˜"Kšœ5˜5K˜Kšžœ˜—K˜K˜—š ‘ œžœžœžœžœ˜NKšœ5™5K˜Kšžœ žœžœžœ˜Kšœ ˜/Kšœžœ˜K˜Kšœ˜Kšœ˜Kšœ˜K˜—š‘ œžœžœžœ˜.Kšœ5™5Kšœ˜Kšœ˜K˜—š‘œžœžœžœ˜:Kšœ5™5šžœ žœ ž˜K˜Kšžœžœ˜-Kšžœ˜—Kšœ˜K˜—Kšœžœ .˜KK˜š ‘œžœžœžœžœ˜VKšœ žœ0˜?šžœ žœ˜Kšœ žœ˜$Kšœ˜Kšœ˜—Kšžœ ˜Kšœ˜K˜—š‘œžœžœžœžœ žœžœ˜nKšœ5™5šžœ žœ ž˜Kšœ˜š žœžœžœžœ3žœ˜bKš žœ žœžœ žœžœ˜qKšœ˜—Kšœ žœ˜Kšžœ˜—Kšžœ žœ#˜4Kšœ˜K˜—š ‘ œžœžœžœ žœžœ˜;Kšœ5™5šžœ žœ ž˜K˜Kšžœžœžœžœ˜FKšžœ˜—K˜"Kšœ˜K˜—Kšœžœžœ˜š‘ œžœžœžœ˜#Kšœ5™5šžœžœ˜Kšœ"˜"Kšžœžœžœžœ˜6Kšœ˜—Kšœ˜K˜—š ‘œžœžœžœžœ˜@š žœžœžœžœžœ˜3Kšœ˜šžœžœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ žœžœ˜:Kšœ˜Kšžœžœ)žœ˜KKšžœ˜ Kšœ˜—Kšžœžœžœ˜Kšœ˜—Kšžœžœžœ˜K˜K˜—š‘ œžœžœ˜-Kšžœžœžœ ˜1K˜š žœžœžœžœ$žœ˜MKšœB˜Bšœžœ˜5Kšœ0˜0Kšœƒ˜ƒKšœžœ˜"K˜—KšžœžœžœO˜hKšœTžœ˜[K˜—Kšžœ ˜Kšœ˜K˜—š‘ œžœžœ˜+Kšžœžœžœžœ˜ Kšžœžœ˜)Kšœžœ˜Kšœ˜K˜—Kšœ žœžœ 4˜Oš‘ œžœžœ˜Kšœ5™5šžœ žœ ž˜Kšœ˜Kš žœžœžœžœžœ˜`Kšžœ˜—Kšœ˜K˜—š‘ œžœžœ˜Kšžœžœžœ˜Kšœ žœžœ˜Kšžœ:˜AK˜%šž˜Kšžœ ˜ Kšœ žœ ˜Kšœ˜Kšžœ˜—Kšœ˜K˜—K˜ Kšžœžœ ˜AK˜Kšžœ˜—…—$v