TermEmCmds:
CEDAR
PROGRAM
IMPORTS CharDisplays, Commander, CommandTool, DisplayControllers, EmTermCap, FS, IO, Menus, MessageWindow, Protocols, Rope, TermCaps, ViewerOps, ViewerTools
= {OPEN CharDisplays, DisplayControllers, TermCaps;
Protocol: TYPE = Protocols.Protocol;
Conversation: TYPE = Protocols.Conversation;
AtomList: TYPE = EmTermCap.AtomList;
TermDataList: TYPE = LIST OF TermData;
TermData: TYPE = REF TermDataRep;
TermDataRep:
TYPE =
RECORD [
term: Term,
cp: ControlProgram,
det: DisplayDetails,
ungrokked: AtomList];
termDatas: TermDataList ← NIL;
Em: TYPE = REF EmRep;
EmRep:
TYPE =
RECORD [
tc: TermCap,
td: TermData,
dc: DisplayController,
p: Protocol,
c: Conversation];
installationDirectory: ROPE ← CommandTool.CurrentWorkingDirectory[];
lastEm: Em ← NIL;
GetTermData:
PROC [term: Term]
RETURNS [td: TermData] = {
tdl: TermDataList;
FOR tdl ← termDatas, tdl.rest
WHILE tdl #
NIL
DO
IF tdl.first.term = term THEN EXIT;
ENDLOOP;
IF tdl =
NIL
THEN {
cp: ControlProgram;
det: DisplayDetails;
ungrokked: AtomList;
[cp, det, ungrokked] ← EmTermCap.MakeTermController[term, TRUE];
td ← NEW [TermDataRep ← [term, cp, det, ungrokked]];
termDatas ← CONS[td, termDatas];
}
ELSE td ← tdl.first;
};
MakeEm:
PROC [cmd: Commander.Handle]
RETURNS [result:
REF ←
NIL, msg:
ROPE ←
NIL] = {
termcapFile: ROPE ← "UnixTermcap";
termName: ROPE ← "vt52";
displayClass: ROPE ← "Tioga";
protocolName: ROPE ← "PupChat";
serverName: ROPE ← NIL;
em: Em;
termCap: TermCap;
term: Term;
cdc: CharDisplayClass;
cd: CharDisplay ← NIL;
dc: DisplayController ← NIL;
td: TermData;
p: Protocol;
i: INT ← 1;
argv: CommandTool.ArgumentVector ← CommandTool.Parse[cmd];
WHILE i < argv.argc
DO
IF argv[i].Length[] > 0
AND argv[i].Fetch[0] = '-
AND i+1 = argv.argc
THEN {
cmd.out.PutF["Missing %g --- assuming default\n", IO.rope[argv[i]]];
EXIT};
SELECT
TRUE
FROM
argv[i].Equal["-termcap"] => {termcapFile ← argv[i+1]; i ← i+2};
argv[i].Equal["-term"] => {termName ← argv[i+1]; i ← i+2};
argv[i].Equal["-display"] => {displayClass ← argv[i+1]; i ← i+2};
argv[i].Equal["-protocol"] => {protocolName ← argv[i+1]; i ← i+2};
argv[i].Equal["-host"] => {serverName ← argv[i+1]; i ← i+2};
argv[i].Fetch[0] = '- => RETURN [$Failure, Rope.Cat["Unrecognized switch: %g", argv[i]]]
ENDCASE => {serverName ← argv[i]; i ← i+1};
ENDLOOP;
termCap ← TermCaps.GetTermCap[termcapFile, installationDirectory];
IF termCap = NIL THEN RETURN [$Failed, IO.PutFR["Couldn't find termcap file %g", IO.rope[termcapFile]]];
term ← TermCaps.GetTerm[termCap, termName];
IF term = NIL THEN RETURN [$Failed, IO.PutFR["Couldn't find terminal %g", IO.rope[termName]]];
td ← GetTermData[term];
cdc ← CharDisplays.GetClass[displayClass];
IF cdc = NIL THEN RETURN [$Failed, IO.PutFR["Couldn't find display class %g", IO.rope[displayClass]]];
p ← Protocols.GetProtocol[protocolName];
IF p = NIL THEN RETURN [$Failed, IO.PutFR["Couldn't find protocol %g", IO.rope[protocolName]]];
cd ← CharDisplays.Create[class: cdc, det: td.det];
dc ← DisplayControllers.Create[cd, td.cp];
em ← NEW [EmRep ← [termCap, td, dc, p]];
IF dc.cd.viewer #
NIL
THEN {
m: Menus.Menu ← em.dc.cd.viewer.menu;
oldLines: Menus.MenuLine ← m.GetNumberOfLines[];
m.ChangeNumberOfLines[oldLines+1];
m.AppendMenuEntry[Menus.CreateEntry["Connect", Connect, em], oldLines];
m.AppendMenuEntry[Menus.CreateEntry["Disconnect", Disconnect, em], oldLines];
SetName[em, NIL];
};
lastEm ← em;
IF serverName.Length[] > 0 THEN ConnectWork[em, serverName];
};
SetName:
PROC [em: Em, serverName:
ROPE] = {
fullTermcapFile: ROPE;
tcp: FS.ComponentPositions;
termcapName: ROPE;
[fullTermcapFile, tcp, ] ← FS.ExpandName[em.tc.fileID.gName];
termcapName ← fullTermcapFile.Substr[start: tcp.base.start, len: tcp.base.length];
em.dc.cd.viewer.name ← IO.PutFR["%g of %g; %g; %g", IO.rope[em.td.term.bestName], IO.rope[termcapName], IO.rope[em.dc.cd.class.name], IO.rope[em.p.name]];
IF serverName # NIL THEN em.dc.cd.viewer.name ← serverName.Cat["; ", em.dc.cd.viewer.name];
ViewerOps.PaintViewer[em.dc.cd.viewer, all];
};
Connect:
PROC [parent:
REF
ANY, clientData:
REF
ANY ←
NIL, mouseButton: Menus.MouseButton ← red, shift, control:
BOOL ←
FALSE]
--Menus.MenusProc-- = {
em: Em ← NARROW[clientData];
serverName: ROPE ← ViewerTools.GetSelectionContents[];
ConnectWork[em, serverName];
};
ConnectWork:
PROC [em: Em, serverName:
ROPE] = {
IF em.c #
NIL
THEN {
MessageWindow.Append["Already connected!", TRUE];
}
ELSE {
em.c ← em.p.Connect[serverName: serverName, fromClient: em.dc.fromDisplay, toClient: em.dc.toDisplay, noteDisconnect: NoteDisconnect, clientData: em];
SetName[em, serverName];
};
};
Disconnect:
PROC [parent:
REF
ANY, clientData:
REF
ANY ←
NIL, mouseButton: Menus.MouseButton ← red, shift, control:
BOOL ←
FALSE]
--Menus.MenusProc-- = {
em: Em ← NARROW[clientData];
IF em.c #
NIL
THEN {
em.p.Disconnect[em.c];
}
ELSE {
MessageWindow.Append["Already disconnected!", TRUE];
};
};
NoteDisconnect:
PROC [clientData:
REF
ANY] = {
em: Em ← NARROW[clientData];
SetName[em, NIL];
em.c ← NIL;
};
Commander.Register[key: "TermEm", proc: MakeEm, doc: "Make a terminal emulator"];
}.