DIRECTORY Ascii, Atom, CharDisplays, EditedStream, IO, IOClasses, List, Rope, ViewerClasses, ViewerIO; CharDisplaysImpl: CEDAR PROGRAM IMPORTS Atom, EditedStream, IO, IOClasses, List, Rope, ViewerIO EXPORTS CharDisplays = {OPEN CharDisplays; REFTEXT: TYPE = REF TEXT; DisplayDestroyed: PUBLIC ERROR [cd: CharDisplay] = CODE; unchangeableClient: PUBLIC Client _ NEW [ClientRep _ [DontChangeDetails, NIL]]; DontChangeDetails: PROC [Client, CharDisplay, DisplayDetails] RETURNS [BOOL] ~ {RETURN [FALSE]}; classes: List.AList _ NIL; GetClass: PUBLIC PROC [name: ROPE] RETURNS [cdc: CharDisplayClass] = { a: ATOM _ Atom.MakeAtom[name]; cdc _ NARROW[List.Assoc[key: a, aList: classes]]; IF cdc#NIL AND NOT name.Equal[cdc.name] THEN ERROR; }; RegClass: PUBLIC PROC [cdc: CharDisplayClass] = { a: ATOM _ Atom.MakeAtom[cdc.name]; classes _ List.PutAssoc[key: a, val: cdc, aList: classes]; }; EnumerateClasses: PUBLIC PROC [Consume: PROC [CharDisplayClass]] ~ { FOR cl: List.AList _ classes, cl.rest WHILE cl#NIL DO cdc: CharDisplayClass ~ NARROW[cl.first.val]; Consume[cdc]; ENDLOOP; RETURN}; Create: PUBLIC PROC [class: CharDisplayClass, client: Client, name, tipTableName: ROPE _ NIL, det: DisplayDetails _ [], initData: REF ANY _ NIL] RETURNS [cd: CharDisplay] = { cd _ NEW [CharDisplayRep _ [class: class, client: client, name: name, tipTableName: tipTableName, det: det]]; class.Init[cd, initData]; }; debuggingDisplay: CharDisplayClass _ NEW [CharDisplayClassRep _ [ name: "Debug", Init: DInit, ChangeDetails: SimplyChange, DeleteChar: DDeleteChar, TakeChar: DTakeChar, CursorMove: DCursorMove, Line: DLine, ClearTo: DClearTo, ClearAll: DClearAll, SetEmph: DSetEmph, Emphasize: DEmphasize, SetFont: DSetFont, Beep: DBeep, Destroyed: DDestroyed]]; DebuggingDisplay: TYPE = REF DebuggingDisplayRep; DebuggingDisplayRep: TYPE = RECORD [ fromD, toD: IO.STREAM _ NIL, charsOnLine: NAT _ 0 ]; DInit: PROC [cd: CharDisplay, initData: REF ANY] = { dd: DebuggingDisplay _ NEW [DebuggingDisplayRep _ []]; cd.otherInstanceData _ dd; [dd.fromD, dd.toD] _ ViewerIO.CreateViewerStreams[name: cd.name, editedStream: FALSE]; cd.fromDisplay _ dd.fromD; cd.viewer _ ViewerIO.GetViewerFromStream[dd.fromD]; EditedStream.SetEcho[dd.fromD, NIL]; }; SimplyChange: PUBLIC PROC [cd: CharDisplay, new: DisplayDetails] = { IF new.lines # cd.det.lines OR new.columns # cd.det.columns THEN ERROR; IF new.autoMarginsVariable # cd.det.autoMarginsVariable OR new.scrollsVariable # cd.det.scrollsVariable THEN ERROR; IF new.autoMargins # cd.det.autoMargins THEN { IF NOT cd.det.autoMarginsVariable THEN ERROR; cd.det.autoMargins _ new.autoMargins}; IF new.scrolls # cd.det.scrolls THEN { IF NOT cd.det.scrollsVariable THEN ERROR; cd.det.scrolls _ new.scrolls}; }; DDeleteChar: PROC [cd: CharDisplay] = { dd: DebuggingDisplay = NARROW[cd.otherInstanceData]; {ENABLE IO.Error => IF ec = StreamClosed AND stream = dd.toD THEN ERROR DisplayDestroyed[cd]; dd.toD.PutRope[""]; NoteDelta[dd, 4]; }}; DTakeChar: PROC [cd: CharDisplay, char: CHAR, insert: BOOL _ FALSE] = { dd: DebuggingDisplay = NARROW[cd.otherInstanceData]; {ENABLE IO.Error => IF ec = StreamClosed AND stream = dd.toD THEN ERROR DisplayDestroyed[cd]; IF insert THEN {dd.toD.PutChar['_]; NoteDelta[dd, 1]}; SELECT char FROM IN [Ascii.SP .. Ascii.DEL) => {dd.toD.PutChar[char]; NoteDelta[dd, 1]}; ENDCASE => {dd.toD.PutF["<%h>", IO.char[char]]; NoteDelta[dd, 4]}; MoveDCursor[cd, 0, 1, TRUE, TRUE, TRUE, FALSE]; }}; DCursorMove: PROC [cd: CharDisplay, line, col: INT, relative: BOOL _ FALSE, doLine, doCol: BOOL _ TRUE] = {MoveDCursor[cd, line, col, relative, doLine, doCol, TRUE]}; MoveDCursor: PROC [cd: CharDisplay, line, col: INT, relative, doLine, doCol, report: BOOL _ FALSE] = { dd: DebuggingDisplay = NARROW[cd.otherInstanceData]; {ENABLE IO.Error => IF ec = StreamClosed AND stream = dd.toD THEN ERROR DisplayDestroyed[cd]; IF report THEN { msg: ROPE _ IF relative THEN "", IO.int[col]] ELSE ".>"]; dd.toD.PutRope[msg]; dd.toD.PutRope["\n"]; dd.charsOnLine _ 0; }; IF relative THEN {line _ line + cd.line; col _ col + cd.col}; IF NOT doLine THEN line _ cd.line; IF NOT doCol THEN col _ cd.col; IF cd.det.autoMargins THEN { dl: INT _ col / cd.det.columns; line _ line + dl; col _ col - dl * cd.det.columns; WHILE col < 0 DO col _ col + cd.det.columns; line _ line - 1 ENDLOOP; } ELSE col _ MAX[MIN[col, cd.det.columns-1], 0]; IF line < 0 THEN line _ 0; IF cd.det.scrolls THEN line _ MIN[line, cd.det.lines-1] ELSE line _ line MOD cd.det.lines; cd.line _ line; cd.col _ col; }}; DLine: PROC [cd: CharDisplay, insert: BOOL] = { dd: DebuggingDisplay = NARROW[cd.otherInstanceData]; {ENABLE IO.Error => IF ec = StreamClosed AND stream = dd.toD THEN ERROR DisplayDestroyed[cd]; msg: ROPE _ IF insert THEN "" ELSE ""; dd.toD.PutRope[msg]; NoteDelta[dd, msg.Length[]]; }}; DClearTo: PROC [cd: CharDisplay, where: Where] = { dd: DebuggingDisplay = NARROW[cd.otherInstanceData]; {ENABLE IO.Error => IF ec = StreamClosed AND stream = dd.toD THEN ERROR DisplayDestroyed[cd]; msg: ROPE _ SELECT where FROM EndOfLine => "", EndOfScreen => "", ENDCASE => ERROR; dd.toD.PutF[msg]; NoteDelta[dd, msg.Length[]]; }}; DClearAll: PROC [cd: CharDisplay] = { dd: DebuggingDisplay = NARROW[cd.otherInstanceData]; {ENABLE IO.Error => IF ec = StreamClosed AND stream = dd.toD THEN ERROR DisplayDestroyed[cd]; dd.toD.PutF[""]; NoteDelta[dd, 11]; }}; DSetEmph: PROC [cd: CharDisplay, emph: Emph, on: BOOL] = { dd: DebuggingDisplay = NARROW[cd.otherInstanceData]; {ENABLE IO.Error => IF ec = StreamClosed AND stream = dd.toD THEN ERROR DisplayDestroyed[cd]; msg: ROPE _ IO.PutFR["<%g %g>", IO.rope[EmphNames[emph]], IO.bool[on]]; dd.toD.PutF[msg]; NoteDelta[dd, msg.Length[]]; }}; DEmphasize: PROC [cd: CharDisplay, emph: Emph, on: BOOL] = { dd: DebuggingDisplay = NARROW[cd.otherInstanceData]; {ENABLE IO.Error => IF ec = StreamClosed AND stream = dd.toD THEN ERROR DisplayDestroyed[cd]; msg: ROPE _ IO.PutFR["<%g %g@>", IO.rope[EmphNames[emph]], IO.bool[on]]; dd.toD.PutRope[msg]; NoteDelta[dd, msg.Length[]]; }}; DSetFont: PROC [cd: CharDisplay, font: ROPE] = { dd: DebuggingDisplay = NARROW[cd.otherInstanceData]; {ENABLE IO.Error => IF ec = StreamClosed AND stream = dd.toD THEN ERROR DisplayDestroyed[cd]; msg: ROPE _ IO.PutFR["", IO.rope[font]]; dd.toD.PutRope[msg]; NoteDelta[dd, msg.Length[]]; }}; DBeep: PROC [cd: CharDisplay] = { dd: DebuggingDisplay = NARROW[cd.otherInstanceData]; {ENABLE IO.Error => IF ec = StreamClosed AND stream = dd.toD THEN ERROR DisplayDestroyed[cd]; dd.toD.PutF[""]; NoteDelta[dd, 7]; }}; DDestroyed: PROC [cd: CharDisplay] RETURNS [b: BOOL] = { dd: DebuggingDisplay = NARROW[cd.otherInstanceData]; b _ cd.viewer.destroyed; }; EmphNames: ARRAY Emph OF ROPE _ [ underline: "underline", bold: "bold", italic: "italic", inverse: "inverse"]; lineLength: NAT _ 95; NoteDelta: PROC [dd: DebuggingDisplay, dc: INT] = { dd.charsOnLine _ dd.charsOnLine + dc; IF dd.charsOnLine > lineLength THEN { dd.toD.PutRope["\n"]; dd.charsOnLine _ 0}; }; Split: PUBLIC PROC [l: CharDisplayList, client: Client, name: ROPE _ NIL] RETURNS [s: CharDisplay] = { s _ Create[class: splitClass, client: client, name: name, initData: l]; }; splitClass: CharDisplayClass _ NEW [CharDisplayClassRep _ [ name: "Split", Init: SInit, TakeChar: STakeChar, CursorMove: SCursorMove, ClearAll: SClearAll]]; SInit: PROC [cd: CharDisplay, initData: REF ANY] = { l: CharDisplayList _ NARROW[initData]; cd.otherInstanceData _ l; cd.fromDisplay _ NIL; FOR l _ l, l.rest WHILE l # NIL DO cd.fromDisplay _ IF cd.fromDisplay = NIL THEN l.first.fromDisplay ELSE IOClasses.CreateCatInputStream[cd.fromDisplay, l.first.fromDisplay]; ENDLOOP; }; STakeChar: PROC [cd: CharDisplay, char: CHAR, insert: BOOL _ FALSE] = { l: CharDisplayList _ NARROW[cd.otherInstanceData]; FOR l _ l, l.rest WHILE l # NIL DO l.first.class.TakeChar[l.first, char, insert]; cd.line _ l.first.line; cd.col _ l.first.col; ENDLOOP}; SCursorMove: PROC [cd: CharDisplay, line, col: INT, relative: BOOL _ FALSE, doLine, doCol: BOOL _ TRUE] = { l: CharDisplayList _ NARROW[cd.otherInstanceData]; FOR l _ l, l.rest WHILE l # NIL DO l.first.class.CursorMove[l.first, line, col, relative, doLine, doCol]; cd.line _ l.first.line; cd.col _ l.first.col; ENDLOOP}; SClearAll: PROC [cd: CharDisplay] = { l: CharDisplayList _ NARROW[cd.otherInstanceData]; FOR l _ l, l.rest WHILE l # NIL DO l.first.class.ClearAll[l.first]; cd.line _ l.first.line; cd.col _ l.first.col; ENDLOOP}; RegClass[debuggingDisplay]; RegClass[splitClass]; }. –CharDisplaysImpl.Mesa Last Edited by: Spreitzer, January 11, 1986 3:48:39 pm PST Last tweaked by Mike Spreitzer on April 4, 1990 9:54:27 am PDT ส ธ– "cedar" style˜Icode™™:K™>—K˜Kšฯk œ*œ1˜fK˜šะbxœœ˜Kšœœ!˜?Kšœ ˜K˜Kšœœ˜K˜Kšœœœœ˜K˜Kšะblœœœœ˜8K˜Kšœœ œ"œ˜OK˜šฯnœœ'œœ˜LKšœœœ˜—K˜Kšœœ˜K˜š  œœœœœ˜FKšœœ˜Kšœœ%˜1Kš œœœœœœ˜3K˜—K˜š œœœ˜1Kšœœ˜"Kšœ:˜:K˜—K˜š  œœœ œœ˜Dšœ#œœ˜5Kšœœ˜-Kšœ ˜ Kšœ˜—Kšœ˜—K˜š œœœ?œœ&œœœœ˜ฎKšœœe˜mK˜K˜—K˜šœ%œ˜AK˜K˜ K˜Kšœ˜K˜K˜Kšœ ˜ Kšœ˜K˜Kšœ˜Kšœ˜K˜Kšœ ˜ Kšœ˜—K˜Kšœœœ˜1šœœœ˜$Kšœ œœœ˜Kšœ œ˜K˜—K˜š œœœœ˜4Kšœœ˜6Kšœ˜KšœOœ˜VKšœ˜Kšœ3˜3Kšœœ˜$K˜—K˜š  œœœ+˜DKšœœœœ˜GKšœ6œ.œœ˜sšœ&œ˜.Kšœœœœ˜-Kšœ&˜&—šœœ˜&Kšœœœœ˜)Kšœ˜—K˜—K˜š  œœ˜'Kšœœ˜4Kš œœœ œœœœ˜]K˜K˜K˜—K˜š   œœœ œœ˜GKšœœ˜4Kš œœœ œœœœ˜]Kšœœ(˜6šœ˜Kšœœ œ.˜GKšœœ ˜B—Kš œœœœœ˜/K˜—K˜š  œœœ œœœœ˜iKšœ5œ˜<—K˜š   œœœ#œœ˜fKšœœ˜4Kš œœœ œœœœ˜]šœœ˜Kš œœœ œ œ ˜5Kš œœœœœ œ˜FKš œœœœœ œ˜DK˜K˜K˜K˜—Kšœ œ-˜=Kšœœœ˜"Kšœœœ˜šœœ˜Kšœœ˜K˜Kšœ ˜ Kšœ œ-œ˜EK˜—Kšœœœ˜.Kšœ œ ˜Kš œœœœ œ˜ZK˜K˜ K˜—K˜š œœœ˜/Kšœœ˜4Kš œœœ œœœœ˜]Kš œœœœœ˜@K˜K˜K˜—K˜š œœ$˜2Kšœœ˜4Kš œœœ œœœœ˜]šœœœ˜Kšœ˜Kšœ˜Kšœœ˜—K˜K˜K˜—K˜š  œœ˜%Kšœœ˜4Kš œœœ œœœœ˜]K˜K˜K˜—K˜š œœ#œ˜:Kšœœ˜4Kš œœœ œœœœ˜]Kš œœœœœ ˜GK˜K˜K˜—K˜š  œœ#œ˜