DIRECTORY CedarVersion USING [major, minor, patch], Convert USING [ValueToRope], Imager USING [black, Context, MaskIntRectangle, MaskCharacters, SetColor, SetCP, white], InputFocus USING [CaptureButtons, PopInputFocus, PushInputFocus, ReleaseButtons, SetInputFocus], IO USING [PutFR, time], MessageWindow, Process USING [MsecToTicks, Pause], Rope USING [Cat, Fetch, FromRefText, ROPE, Size, Substr], Runtime USING [GetBcdTime], TIPUser USING [InstantiateNewTIPTable], UserTerminal USING [BlinkDisplay], VFonts USING [defaultFont], ViewerClasses, ViewerLocks USING [CallUnderWriteLock, Wedged], ViewerOps USING [CreateViewer, PaintViewer, RegisterViewerClass], ViewerSpecs, WindowManager USING [UnWaitCursor, WaitCursor]; MessageWindowImpl: CEDAR MONITOR IMPORTS CedarVersion, Convert, Imager, IO, InputFocus, Process, Rope, Runtime, TIPUser, UserTerminal, VFonts, ViewerLocks, ViewerOps, WindowManager EXPORTS MessageWindow = BEGIN messageWindow: PUBLIC ViewerClasses.Viewer; mode: {none, input, confirm} _ none; ready: BOOLEAN _ FALSE; confirm: BOOLEAN; inputReady: CONDITION; empty: BOOLEAN _ TRUE; maxLength: INTEGER = 120; static: REF TEXT _ NEW[TEXT[maxLength]]; typein: REF TEXT _ NEW[TEXT[maxLength]]; Clear: PUBLIC PROC = { IF empty OR messageWindow=NIL OR mode#none THEN RETURN; ViewerLocks.CallUnderWriteLock[LockedClear, messageWindow ! ViewerLocks.Wedged => CONTINUE]}; LockedClear: PROC = { static.length _ typein.length _ 0; empty _ TRUE; ViewerOps.PaintViewer[viewer: messageWindow, hint: client, whatChanged: $Clear]}; Append: PUBLIC PROC [message: Rope.ROPE, clearFirst: BOOLEAN _ FALSE] = BEGIN LockedAppend: PROC = { IF clearFirst THEN static.length _ typein.length _ 0; FOR n: LONG INTEGER IN [0..Rope.Size[message]) DO IF static.length >= maxLength THEN EXIT; static[static.length] _ Rope.Fetch[message, n]; static.length _ static.length + 1; ENDLOOP; ViewerOps.PaintViewer[messageWindow, client, TRUE, $Append]; empty _ FALSE}; IF messageWindow=NIL OR mode#none THEN RETURN; ViewerLocks.CallUnderWriteLock[LockedAppend, messageWindow ! ViewerLocks.Wedged => CONTINUE]; END; Blink: PUBLIC PROC = BEGIN IF messageWindow=NIL THEN RETURN; THROUGH [0..6) DO ViewerOps.PaintViewer[messageWindow, client, FALSE, $Invert]; Process.Pause[Process.MsecToTicks[150]]; ENDLOOP; END; ReadFrom: PUBLIC ENTRY PROC RETURNS [message: Rope.ROPE] = BEGIN IF messageWindow=NIL OR mode#none THEN RETURN[""]; mode _ input; typein.length _ 0; InputFocus.PushInputFocus[messageWindow]; InputFocus.CaptureButtons[MessageWindowNotify, messageWindowClass.tipTable, messageWindow]; WindowManager.WaitCursor[typeKey]; UNTIL ready=TRUE DO WAIT inputReady; ENDLOOP; InputFocus.PopInputFocus[]; ready _ FALSE; mode _ none; WindowManager.UnWaitCursor[]; empty _ FALSE; RETURN[Rope.FromRefText[typein]]; END; nextInLine: CONDITION; Confirm: PUBLIC ENTRY PROC [prompt: Rope.ROPE _ NIL] RETURNS [BOOLEAN] = BEGIN string: Rope.ROPE _ Rope.Cat["LeftMouse=>Yes, right=>No: ",prompt]; WHILE mode#none DO WAIT nextInLine; ENDLOOP; -- wait in line InputFocus.CaptureButtons[MessageWindowNotify, messageWindowClass.tipTable, messageWindow]; InputFocus.SetInputFocus[]; mode _ confirm; typein.length _ 0; WindowManager.WaitCursor[confirm]; IF string#NIL THEN BEGIN static.length _ 0; FOR n: LONG INTEGER IN [0..Rope.Size[string]) DO IF static.length >= maxLength THEN ERROR; static[static.length] _ Rope.Fetch[string, n]; static.length _ static.length + 1; ENDLOOP; ViewerOps.PaintViewer[messageWindow, client, FALSE, $Append]; END; UNTIL ready=TRUE DO WAIT inputReady; ENDLOOP; InputFocus.ReleaseButtons[]; ready _ FALSE; WindowManager.UnWaitCursor[]; static.length _ 0; ViewerOps.PaintViewer[messageWindow, client, TRUE, $Clear]; empty _ FALSE; mode _ none; NOTIFY nextInLine; RETURN[confirm]; END; Destroy: PUBLIC PROC = BEGIN ERROR; -- no longer implemented END; PostReleaseVersion: PROC = BEGIN OPEN CedarVersion; FromCard: PROC [c: CARDINAL] RETURNS [Rope.ROPE] = INLINE {RETURN[Convert.ValueToRope[[unsigned[c, 10]]]]}; version: Rope.ROPE _ Rope.Cat[FromCard[major], ".", FromCard[minor]]; patchVersion: Rope.ROPE _ IF patch=0 THEN NIL ELSE Rope.Cat[".", FromCard[patch]]; timeLen: INT = 9; -- shortened to trim off time cedarLen: INT = 6+3+(IF patch=0 THEN 0 ELSE IF patch>9 THEN 3 ELSE 2)+12; cedarMsg: Rope.ROPE _ Rope.Cat["Cedar ", version, patchVersion, " release of %t"]; Append[Rope.Substr[IO.PutFR[cedarMsg, IO.time[Runtime.GetBcdTime[]]], 0, cedarLen+timeLen], TRUE]; Append[" ... "]; END; MessageWindowPaint: PRIVATE ViewerClasses.PaintProc = BEGIN OPEN Imager; IF whatChanged = $Invert THEN BEGIN SetColor[context, $XOR]; MaskIntRectangle[context, [0, 0, self.cw, self.ch]]; END ELSE BEGIN bottomOffset: REAL = 3; leftOffset: REAL = 2; IF ~clear THEN BEGIN SetColor[context, white]; MaskIntRectangle[context, [0, 0, self.cw, self.ch]]; SetColor[context, black]; END; SetCP[context, [leftOffset, bottomOffset]]; MaskCharacters[context, VFonts.defaultFont, static]; MaskCharacters[context, VFonts.defaultFont, typein] END; END; MessageWindowNotify: PRIVATE ENTRY ViewerClasses.NotifyProc = BEGIN FOR l: LIST OF REF ANY _ input, l.rest UNTIL l=NIL DO IF mode = input THEN WITH l.first SELECT FROM c: REF CHARACTER => IF c^=15C OR c^=33C THEN BEGIN ready _ TRUE; NOTIFY inputReady; END ELSE BEGIN IF c^=10C OR c^=01C OR c^=177C THEN BEGIN typein.length _ IF c^=177C THEN 0 ELSE MAX[typein.length, 1]-1; END ELSE BEGIN IF typein.length >= maxLength THEN ERROR; typein[typein.length] _ c^; typein.length _ typein.length + 1; END; ViewerOps.PaintViewer[messageWindow, client, FALSE, $Append]; END; ENDCASE => TRUSTED {UserTerminal.BlinkDisplay[]} ELSE IF mode=confirm THEN WITH l.first SELECT FROM c: REF CHARACTER => SELECT c^ FROM 'y,'Y,15C,33C => BEGIN ready _ confirm _ TRUE; NOTIFY inputReady; END; 'n,'N,177C => BEGIN confirm _ FALSE; ready _ TRUE; NOTIFY inputReady; END; ENDCASE => TRUSTED {UserTerminal.BlinkDisplay[]}; a: ATOM => SELECT a FROM $Yes => BEGIN ready _ confirm _ TRUE; NOTIFY inputReady; END; $No => BEGIN confirm _ FALSE; ready _ TRUE; NOTIFY inputReady; END; ENDCASE => TRUSTED {UserTerminal.BlinkDisplay[]}; ENDCASE => ERROR ELSE IF l.first=$Yes THEN LockedClear[]; ENDLOOP; END; MessageWindowModify: PRIVATE ENTRY ViewerClasses.ModifyProc = BEGIN END; messageWindowClass: ViewerClasses.ViewerClass _ NEW[ViewerClasses.ViewerClassRec _ [ paint: MessageWindowPaint, notify: MessageWindowNotify, modify: MessageWindowModify, tipTable: TIPUser.InstantiateNewTIPTable["/Indigo/CedarViewers/Viewers/MessageWindow.tip"] ]]; ViewerOps.RegisterViewerClass[$MessageWindow, messageWindowClass]; messageWindow _ ViewerOps.CreateViewer[$MessageWindow, [name: "MW", wy: ViewerSpecs.screenH-ViewerSpecs.messageWindowHeight, ww: ViewerSpecs.messageWindowWidth, wh: ViewerSpecs.messageWindowHeight, column: static] ]; PostReleaseVersion[]; END. fMessageWindowImpl.mesa; written by S. McGregor Edited by McGregor on August 4, 1983 11:22 am Last Edited by: Maxwell, February 14, 1983 10:22 am Last Edited by: Pausch, July 18, 1983 5:01 pm IF messageWindow#NIL THEN ViewerOps.DestroyViewer[messageWindow]; messageWindow _ NIL; [self: Viewer, change: ModifyAction] might want to start a caret someday Κ q– "cedar" style˜JšΟc.™.Jš-™-Jšœ3™3J™-J˜šΟk ˜ Jšœ žœ˜)Jšœžœ˜JšœžœL˜Xšœ žœ@˜PJ˜—Jšžœžœ˜J˜Jšœžœ˜#Jšœžœžœ˜9Jšœžœ˜Jšœžœ˜'Jšœ žœ˜"Jšœžœ˜J˜Jšœ žœ˜/Jšœ žœ2˜AJ˜ Jšœžœ˜/J˜—Jšœž ˜ J˜Jšžœ žœj˜“Jšžœ˜J˜Jšž˜J˜Jšœžœ˜+J˜J˜$Jšœžœžœ˜Jšœ žœ˜Jšœ ž œ˜J˜Jšœžœžœ˜J˜Jšœ žœ˜Jš œžœžœžœžœ ˜(Jš œžœžœžœžœ ˜(J˜šΟnœžœžœ˜Jš žœžœžœžœ žœžœ˜7šœ:˜:Jšœžœ˜#—šŸ œžœ˜Jšœ+žœ˜0JšœQ˜QJ˜J˜——š Ÿœžœžœžœžœžœž˜MšŸ œžœ˜Jšžœ žœ#˜5š žœžœžœžœž˜1Jšžœžœžœ˜(J˜/J˜"Jšžœ˜—Jšœ-žœ ˜