DIRECTORY Carets USING [CaretId], CaretsExtras USING [], CedarProcess USING [SetPriority], Imager USING [Color, Context, MaskBits, SetColor], ImagerBackdoor USING [invert], Process USING [Detach, MsecToTicks, SetTimeout], ViewerClasses USING [Viewer], ViewerOps USING [UserToScreenCoords], ViewerPrivate USING [PaintScreen, Screen, ViewerScreen]; CaretsImpl: CEDAR MONITOR IMPORTS CedarProcess, Imager, ImagerBackdoor, Process, ViewerOps, ViewerPrivate EXPORTS Carets, CaretsExtras SHARES ViewerOps ~ BEGIN OPEN Carets; Viewer: TYPE ~ ViewerClasses.Viewer; Screen: TYPE ~ ViewerPrivate.Screen; timeOut: CONDITION; caretH: INTEGER = 6; caretW: INTEGER = 16; caretXOffset: CARDINAL = 8; CaretBits: TYPE ~ REF CaretBitsRep; CaretBitsRep: TYPE = ARRAY [0..caretH) OF WORD; xminCaret: INTEGER ~ -4; xmaxCaret: INTEGER ~ 3; yminCaret: INTEGER ~ -caretH; ymaxCaret: INTEGER ~ 0; pCaret: CaretBits ~ 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 ]]; sCaret: CaretBits ~ 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 ]]; Caret: TYPE ~ REF CaretRep; CaretRep: TYPE ~ RECORD[ bits: CaretBits _ 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 _ []]; SELECT id FROM primary => caret.bits _ pCaret; secondary => caret.bits _ sCaret; ENDCASE => ERROR; carets[id] _ caret; ENDLOOP; }; StartCaret: PUBLIC ENTRY PROC [viewer: Viewer, x, y: INTEGER, id: CaretId] = { ENABLE UNWIND => NULL; 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] = { ENABLE UNWIND => NULL; KillCaret[carets[id]]; }; StopCaretsInViewer: PUBLIC ENTRY PROC [viewer: Viewer] ~ { ENABLE UNWIND => NULL; 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] = { ENABLE UNWIND => NULL; 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] = { ENABLE UNWIND => NULL; 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 = { ENABLE UNWIND => NULL; 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] ~ { 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.MaskBits[context: context, base: LOOPHOLE[caret.bits], wordsPerLine: 1, sMin: 0, fMin: 0, sSize: caretH, fSize: caretW, tx: caret.sx-caretXOffset, ty: 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]; }; }; 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. ����CaretsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Doug Wyatt, May 8, 1985 10:19:01 am PDT Russ Atkinson (RRA) June 10, 1985 7:57:21 pm PDT Michael Plass, November 21, 1985 12:29:28 pm PST Puts the caret in the proper phase, unless suspended. �Ê£��˜�codešœ™Kšœ Ïmœ1™<K™'K™0K™0—K˜�šÏk ˜ Kšœžœ˜Kšœ žœ˜Kšœ žœ˜!Kšœžœ&˜2Kšœžœ ˜Kšœžœ#˜0Kšœžœ ˜Kšœ žœ˜%Kšœžœ%˜8—K˜�šÐbl œžœž˜KšžœH˜OKšžœ˜Kšžœ ˜Kšœžœžœ˜—K˜�Kšœžœ˜$Kšœžœ˜$K˜�Kšœ ž œ˜K˜�Kšœžœ˜Kšœžœ˜Kšœžœ˜K˜�Kšœžœžœ˜#Kš œžœžœ žœžœ˜/K˜�Kšœžœ˜Kšœžœ˜Kšœžœ˜šœžœ˜K˜�—šœžœ˜(Kšœ Ïc"˜+Kšœ "˜+Kšœ "˜+Kšœ "˜+Kšœ "˜+Kšœ "˜+K˜—K˜�šœžœ˜(Kšœ "˜+Kšœ "˜+Kšœ "˜+Kšœ "˜+Kšœ "˜+Kšœ "˜+K˜K˜�—Kšœžœžœ ˜šœ žœžœ˜Kšœžœ˜Kšœžœ ˜4Kšœžœ #˜6Kšœžœ >˜SKšœ žœž˜Kšœ˜K˜�—Kš œžœ žœ žœžœ˜*K˜�šÏn œžœžœ˜šžœ žœ ž˜Kšœžœ˜"šžœž˜K˜K˜!Kšžœžœ˜—K˜Kšžœ˜—K˜K˜�—š ¡ œžœžœžœžœ˜NKšžœžœžœ˜K˜Kšžœ žœžœžœ˜Kšœ ˜/Kšœžœ˜K˜Kšœ˜Kšœ˜Kšœ˜K˜�—š¡ œžœžœžœ˜.Kšžœžœžœ˜Kšœ˜Kšœ˜K˜�—š¡œžœžœžœ˜:Kšžœžœžœ˜šžœ žœ ž˜J˜Jšžœžœ˜-Kšžœ˜—Kšœ˜K˜�—Kšœžœ .˜KK˜�š ¡œžœžœžœžœ˜VKšœžœ0˜?šžœžœ˜Kšœ žœ˜$Kšœ˜Kšœ˜—Kšžœ ˜Kšœ˜K˜�—š¡œžœžœžœžœ žœžœ˜nKšžœžœžœ˜šžœ žœ ž˜Jšœ˜š žœžœžœžœ3žœ˜bKš žœ žœžœ žœžœ˜qKšœ˜—Kšœžœ˜Kšžœ˜—Kšžœžœ#˜4Kšœ˜K˜�—š¡ œžœžœžœ žœžœ˜;Kšžœžœžœ˜šžœ žœ ž˜J˜Jšžœžœžœžœ˜FKšžœ˜—K˜"Kšœ˜K˜�—Kšœžœžœ˜š¡œžœžœžœ˜#Kšžœžœžœ˜šžœžœ˜Kšœ"˜"Kšžœžœžœžœ˜6Kšœ˜—Kšœ˜K˜�—š ¡œžœžœžœžœ˜@š žœžœžœžœžœ˜3Kšœ˜šžœžœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœžœžœ˜:Kšœ˜Kšžœžœ)žœ˜KKšžœ˜ Kšœ˜—Kšžœžœžœ˜Kšœ˜—Kšžœžœžœ˜K˜K˜�—š¡œžœžœ˜-K˜š žœžœžœžœ$žœ˜MKšœB˜Bšœžœ˜5Kšœ0˜0Kšœ(žœy˜©Kšœžœ˜"K˜—KšžœžœžœO˜hKšœTžœ˜[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šžœ˜—�…—����þ�� µ��