Connections.cs
上传用户:szltgg
上传日期:2019-05-16
资源大小:604k
文件大小:12k
源码类别:

Telnet服务器

开发平台:

C#

  1. /*
  2. * Copyright (c) 2005 Poderosa Project, All Rights Reserved.
  3. * $Id: Connections.cs,v 1.2 2005/04/20 08:45:46 okajima Exp $
  4. */
  5. using System;
  6. using ThTimer = System.Threading.Timer;
  7. using System.Windows.Forms;
  8. using System.Collections;
  9. using System.Diagnostics;
  10. using Poderosa;
  11. using Poderosa.Text;
  12. using Poderosa.Terminal;
  13. using Poderosa.Communication;
  14. namespace Poderosa.Connection
  15. {
  16. /// <summary>
  17. /// 傾僾儕働乕僔儑儞慡懱偱偺僐僱僋僔儑儞偺儕僗僩偲丄偦傟偑偳偺儁僀儞偵娭楢晅偗傜傟偰偄傞偐傪娗棟偡傞
  18. /// </summary>
  19. public class Connections : IEnumerable {
  20. //愙懕傪奐偄偨弴偵奿擺偝傟傞ConnectionTag攝楍
  21. private ArrayList _connections;
  22. private int _activeIndex;
  23. //Active側媡弴偵奿擺偝傟傞攝楍
  24. private ArrayList _activatedOrder;
  25. private KeepAlive _keepAlive;
  26. internal Connections() {
  27. _connections = new ArrayList();
  28. _activeIndex = -1;
  29. _keepAlive = new KeepAlive();
  30. _activatedOrder = new ArrayList();
  31. }
  32. internal KeepAlive KeepAlive {
  33. get {
  34. return _keepAlive;
  35. }
  36. }
  37. public void Add(ConnectionTag t) {
  38. Debug.Assert(t!=null);
  39. t.PositionIndex = GEnv.Frame.PositionForNextConnection;
  40. t.PreservedPositionIndex = t.PositionIndex;
  41. _connections.Add(t);
  42. _activatedOrder.Add(t);
  43. }
  44. internal void Remove(TerminalConnection con) {
  45. int i = IndexOf(con);
  46. if(i==-1) return; //杮摉偼偙偆偄偆偺偼傛傠偟偔側偄偑
  47. ConnectionTag ct = this.TagAt(i);
  48. _connections.RemoveAt(i);
  49. _activatedOrder.Remove(ct);
  50. _activeIndex = Math.Min(_activeIndex, _connections.Count-1);
  51. }
  52. public void Replace(ConnectionTag old, ConnectionTag ct) {
  53. int i = IndexOf(old);
  54. Debug.Assert(i!=-1);
  55. _connections[i] = ct;
  56. i = _activatedOrder.IndexOf(old);
  57. Debug.Assert(i!=-1);
  58. _activatedOrder[i] = ct;
  59. }
  60. public void Clear() {
  61. _connections.Clear();
  62. _activatedOrder.Clear();
  63. _activeIndex = -1;
  64. }
  65. public void CloseAllConnections() {
  66. ArrayList target = new ArrayList(_connections); //儘乕僇儖僐僺乕傪嶌傜側偄偲旕摨婜偵僐儗僋僔儑儞偑曄峏偝傟偐偹側偄
  67. foreach(ConnectionTag ct in target) {
  68. ct.Connection.Close();
  69. ct.IsTerminated = true;
  70. }
  71. }
  72. public ArrayList GetSnapshot() {
  73. return new ArrayList(_connections);
  74. }
  75. public int Count {
  76. get {
  77. return _connections.Count;
  78. }
  79. }
  80. public bool LiveConnectionsExist {
  81. get {
  82. foreach(ConnectionTag ct in _connections)
  83. if(!ct.Connection.IsClosed) return true;
  84. return false;
  85. }
  86. }
  87. public IEnumerator GetEnumerator() {
  88. return _connections.GetEnumerator();
  89. }
  90. public IEnumerable OrderedConnections {
  91. get {
  92. ArrayList t = new ArrayList(_activatedOrder);
  93. t.Reverse();
  94. return t;
  95. }
  96. }
  97. public int ActiveIndex {
  98. get {
  99. return _activeIndex;
  100. }
  101. }
  102. public void BringToActivationOrderTop(ConnectionTag ct) {
  103. _activeIndex = _connections.IndexOf(ct);
  104. _activatedOrder.Remove(ct);
  105. _activatedOrder.Add(ct);
  106. }
  107. public TerminalConnection ActiveConnection {
  108. get {
  109. if(_activeIndex==-1)
  110. return null;
  111. else
  112. return TagAt(_activeIndex).Connection;
  113. }
  114. }
  115. //positionIndex偑堦抳偟丄excluding偱偼側偄拞偱師偵Active偵側傞岓曗傪曉偡丅側偗傟偽null
  116. public ConnectionTag GetCandidateOfActivation(int positionIndex, ConnectionTag excluding) {
  117. for(int i=_activatedOrder.Count-1; i>=0; i--) {
  118. ConnectionTag ct = (ConnectionTag)_activatedOrder[i];
  119. if(ct.PositionIndex==positionIndex && ct!=excluding) return ct;
  120. }
  121. return null;
  122. }
  123. //Preserved側傗偮傪傒偰寛掕
  124. public ConnectionTag GetCandidateOfLocation(int positionIndex, ConnectionTag excluding) {
  125. for(int i=_activatedOrder.Count-1; i>=0; i--) {
  126. ConnectionTag ct = (ConnectionTag)_activatedOrder[i];
  127. if(ct.PreservedPositionIndex==positionIndex && ct!=excluding) return ct;
  128. }
  129. return null;
  130. }
  131. public ConnectionTag ActiveTag {
  132. get {
  133. if(_activeIndex==-1)
  134. return null;
  135. else
  136. return TagAt(_activeIndex);
  137. }
  138. }
  139. public ConnectionTag TagAt(int index) {
  140. return (ConnectionTag)_connections[index];
  141. }
  142. public ConnectionTag FindTag(TerminalConnection con) {
  143. foreach(ConnectionTag t in _connections) {
  144. if(t.Connection==con) return t;
  145. }
  146. return null;
  147. }
  148. public int IndexOf(TerminalConnection con) {
  149. int i = 0;
  150. foreach(ConnectionTag t in _connections) {
  151. if(t.Connection==con) return i;
  152. i++;
  153. }
  154. return -1;
  155. }
  156. public int IndexOf(ConnectionTag tag) {
  157. int i = 0;
  158. foreach(ConnectionTag t in _connections) {
  159. if(t==tag) return i;
  160. i++;
  161. }
  162. return -1;
  163. }
  164. public ConnectionTag NextConnection(ConnectionTag c) {
  165. int i = IndexOf(c);
  166. return TagAt(i==_connections.Count-1? 0 : i+1);
  167. }
  168. public ConnectionTag PrevConnection(ConnectionTag c) {
  169. int i = IndexOf(c);
  170. return TagAt(i==0? _connections.Count-1 : i-1);
  171. }
  172. public void Reorder(int index, int newindex) {
  173. ConnectionTag ct = (ConnectionTag)_connections[index];
  174. _connections.RemoveAt(index);
  175. _connections.Insert(newindex, ct);
  176. if(_activeIndex==index) _activeIndex = newindex;
  177. }
  178. public ConnectionTag FirstMatch(TagCondition cond) {
  179. foreach(ConnectionTag ct in _connections) {
  180. if(cond(ct)) return ct;
  181. }
  182. return null;
  183. }
  184. internal void Dump() {
  185. Debug.WriteLine("Connection List");
  186. foreach(ConnectionTag ct in _connections) {
  187. Debug.WriteLine(String.Format("pos={0} close={1} pane={2} visible={3}", ct.PositionIndex, ct.Connection.IsClosed, (ct.Pane!=null), (ct.Pane!=null && ct.Pane.FakeVisible)));
  188. if(ct.Pane!=null) Debug.Assert(ct.Pane.Connection == ct.Connection);
  189. }
  190. }
  191. }
  192. public delegate bool TagCondition(ConnectionTag pane);
  193. //Invalidate偵昁梫側僷儔儊乕僞
  194. internal class InvalidateParam {
  195. private Delegate _delegate;
  196. private object[] _param;
  197. private bool _set;
  198. public void Set(Delegate d, object[] p) {
  199. _delegate = d;
  200. _param = p;
  201. _set = true;
  202. }
  203. public void Reset() {
  204. _set = false;
  205. }
  206. public void InvokeFor(Control c) {
  207. if(_set) c.Invoke(_delegate, _param);
  208. }
  209. }
  210. //愙懕偵懳偟偰娭楢晅偗傞僨乕僞
  211.     [Serializable]
  212. public class ConnectionTag {
  213. private TerminalConnection _connection;
  214. private Control _tabButton; //僞僽偺拞偵擖傞儃僞儞
  215. private TerminalPane _pane; //儁僀儞丅旕昞帵偺偲偒偼null
  216. private TerminalDocument _document;
  217. private ITerminal _terminal;
  218. private TerminalDataReceiver _receiver;
  219. private RenderProfile _renderProfile;
  220. private IModalTerminalTask _modalTerminalTask;
  221. private Process _childProcess;
  222. private InvalidateParam _invalidateParam;
  223. //僂傿儞僪僂偺昞帵梡僥僉僗僩
  224. internal string _windowTitle; //儂僗僩OSC僔乕働儞僗偱巜掕偝傟偨僞僀僩儖
  225. private bool _terminated;
  226. private int _positionIndex;
  227. private int _preservedPositionIndex; //Single儌乕僪偵側偭偨偲偒偺偨傔偺戅旔梡
  228. private ThTimer _timer;
  229. public ConnectionTag(TerminalConnection c) {
  230. _connection = c;
  231. _pane = null;
  232. _invalidateParam = new InvalidateParam();
  233. _tabButton = null;
  234. _document = new TerminalDocument(_connection);
  235. _receiver = new TerminalDataReceiver(this);
  236. _terminated = false;
  237. _timer = null;
  238. _windowTitle = "";
  239. //null偺偲偒偼僨僼僅儖僩僾儘僼傽僀儖傪巊偆
  240. _renderProfile = c.Param.RenderProfile;
  241. //VT100巜掕偱傕xterm僔乕働儞僗傪憲偭偰偔傞傾僾儕働乕僔儑儞偑屻傪偨偨側偄偺偱
  242. _terminal = new XTerm(this, new JapaneseCharDecoder(_connection));
  243. /*
  244. if(c.Param.TerminalType==TerminalType.XTerm || c.Param.TerminalType==TerminalType.KTerm)
  245. _terminal = new XTerm(this, new JapaneseCharDecoder(_connection));
  246. else
  247. _terminal = new VT100Terminal(this, new JapaneseCharDecoder(_connection));
  248. */
  249. GEnv.Connections.KeepAlive.SetTimerToConnectionTag(this);
  250. }
  251. //僪僉儏儊儞僩峏怴捠抦 庴怣僗儗僢僪偱偺幚峴側偺偱拲堄
  252. public interface IEventReceiver {
  253. void OnUpdate();
  254. void OnDisconnect();
  255. }
  256. private IEventReceiver _eventReceiver;
  257. public IEventReceiver EventReceiver {
  258. get {
  259. return _eventReceiver;
  260. }
  261. set {
  262. _eventReceiver = value;
  263. }
  264. }
  265. public IModalTerminalTask ModalTerminalTask {
  266. get {
  267. return _modalTerminalTask;
  268. }
  269. set {
  270. _modalTerminalTask = value;
  271. }
  272. }
  273. public Process ChildProcess {
  274. get {
  275. return _childProcess;
  276. }
  277. set {
  278. _childProcess = value;
  279. }
  280. }
  281. internal InvalidateParam InvalidateParam {
  282. get {
  283. return _invalidateParam;
  284. }
  285. }   
  286. public string WindowTitle {
  287. get {
  288. return _windowTitle;
  289. }
  290. set {
  291. _windowTitle = value;
  292. }
  293. }
  294. public string FormatTabText() {
  295. string t = _connection.Param.Caption;
  296. if(t==null || t.Length==0) t = _connection.Param.ShortDescription;
  297. if(_connection.IsClosed) t += GEnv.Strings.GetString("Caption.ConnectionTag.Disconnected");
  298. if(_modalTerminalTask!=null) t += "("+_modalTerminalTask.Caption+")";
  299. return t;
  300. }
  301. //Frame偺僉儍僾僔儑儞梡暥帤楍
  302. public string FormatFrameText() {
  303. string t = FormatTabText();
  304. if(_windowTitle.Length!=0 && _connection.Param.Caption!=_windowTitle) //TabCaption傪WindowTitle偵堦抳偝偣傞僆僾僔儑儞傪巊偭偰偄傞偲烼摡偟偔側傞偺偱堎側傞偲偒偺傒昞帵
  305. t += "[" + _windowTitle + "]";
  306. return t;
  307. }
  308. public Control Button {
  309. get {
  310. return _tabButton;
  311. }
  312. set {
  313. _tabButton = value;
  314. }
  315. }
  316. public TerminalDocument Document {
  317. get {
  318. return _document;
  319. }
  320. }
  321. public TerminalConnection Connection {
  322. get {
  323. return _connection;
  324. }
  325. }
  326. public TerminalPane AttachedPane {
  327. get {
  328. return _pane;
  329. }
  330. }
  331. public ITerminal Terminal {
  332. get {
  333. return _terminal;
  334. }
  335. }
  336. public TerminalDataReceiver Receiver {
  337. get {
  338. return _receiver;
  339. }
  340. }
  341.         
  342. public RenderProfile RenderProfile {
  343. get {
  344. return _renderProfile;
  345. }
  346. set {
  347. _renderProfile = value;
  348. _connection.Param.RenderProfile = value;
  349. }
  350. }
  351. internal RenderProfile GetCurrentRenderProfile() {
  352. return _renderProfile==null? GEnv.DefaultRenderProfile : _renderProfile;
  353. }
  354. internal TerminalPane Pane {
  355. get {
  356. return _pane;
  357. }
  358. set {
  359. _pane = value;
  360. }
  361. }
  362. internal ThTimer Timer {
  363. get {
  364. return _timer;
  365. }
  366. set {
  367. _timer = value;
  368. }
  369. }
  370. internal void NotifyUpdate() {
  371. if(_pane!=null)
  372. _pane.DataArrived();
  373. _terminal.SignalData();
  374. if(_eventReceiver!=null)
  375. _eventReceiver.OnUpdate();
  376. }
  377. internal void NotifyDisconnect() {
  378. if(_eventReceiver!=null)
  379. _eventReceiver.OnDisconnect();
  380. }
  381. public int PositionIndex {
  382. get {
  383. return _positionIndex;
  384. }
  385. set {
  386. _positionIndex = value;
  387. }
  388. }
  389. public int PreservedPositionIndex {
  390. get {
  391. return _preservedPositionIndex;
  392. }
  393. set {
  394. _preservedPositionIndex = value;
  395. }
  396. }
  397. public bool IsTerminated {
  398. get {
  399. return _terminated;
  400. }
  401. set {
  402. _terminated = value;
  403. if(value && _childProcess!=null) {
  404. try {
  405. //_childProcess.Kill(); 幚偼Kill偡傞偲傑偢偄bash巆棷偱傑偢偄
  406. _childProcess = null;
  407. }
  408. catch(Exception) { //婛偵僜働僢僩愗抐偵婲場偡傟偽椺奜偵側傞偙偲傕偁傞偐傕偟傟側偄
  409. }
  410. }
  411. if(value) GEnv.Connections.KeepAlive.ClearTimerToConnectionTag(this);
  412. }
  413. }
  414. public void ImportProperties(ConnectionTag src) {
  415. _renderProfile = src.RenderProfile;
  416. _positionIndex = src.PositionIndex;
  417. _preservedPositionIndex = src.PreservedPositionIndex;
  418. if(src.Button!=null)
  419. src.Button.Tag = this;
  420. _tabButton = src.Button;
  421. }
  422. }
  423. }