TermVT.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. {
  2. TernVT 0.6
  3. ===============
  4. Por Tito Hinostroza 09/09/2014
  5. * Se elimina el evento OnRefreshLine(). Se elimina el tipo TtsRefreshLine.
  6. * Se cambia nombre del evento OnAddLine
  7. * Se agrega el evento OnLineCompleted(), para detectar líneas agregadas completas.
  8. * Se elimina el evento OnRefreshAll().
  9. * Se hace público "Busy", para poder controlar el estado de ocupado.
  10. Descripción
  11. ============
  12. Define a un terminal tipo VT100, como una matriz de caracteres. Solo se implementan las
  13. secuencias de escape básicas. No se implementa opción de coloreado o atributos de texto.
  14. Los caracteres de pantalla se almacenan en el arreglo de cadenas buf[] y se trata como
  15. si fuera una matriz de cracteres. No se almacena más que la pantalla actual.
  16. El terminal se debe crear instanciando la clase TTermVT100.
  17. Los datos se esperan que lleguen en bloques, a través de AddData().
  18. Para mostrar el contenido del terminal, se puede leer el arreglo buf[], de forma periódica,
  19. o cada vez que se genera el evento OnRefreshLines().
  20. Pero la forma más eficiente de manejar el refresco de la pantalla es través de los
  21. eventos: OnRefreshLines() y OnScrollLines().
  22. OnRefreshLines(), Sirven para refrescar lineas individuales o rangos de líneas,
  23. cuando hay cambios. El evento OnScrollLines(), se genera cuando hay un desplazamiento
  24. del contenido del terminal.
  25. Por Tito Hinostroza 27/06/2014 }
  26. unit TermVT;
  27. {$mode objfpc}{$H+}
  28. interface
  29. uses
  30. Classes, SysUtils, LCLProc;
  31. const
  32. MAX_HEIGHT_TS = 100; //cantidad máxima de filas
  33. MAX_WIDTH_TS = 32767; //cantidad máxima de columnas
  34. type
  35. Ttslin = string; //línea
  36. TtsGrid = array[1..MAX_HEIGHT_TS] of Ttslin;
  37. //Tipo de secuencia de escape actual
  38. tEscSequence = (EscSeqOpenBrk, //secuencia ESC[
  39. EscSeqCharSet, //secuencias ESC( ESC) ESC* ESC+
  40. EscSeqCommand //secuencia ESC]
  41. );
  42. //Define el comportamiento de los caracteres de salto de línea (CR y LF)
  43. TBehaveChar = (tbcNone, //sin función, se ignora
  44. tbcNewLine, //es caracter de salto
  45. tbcNormal //es caracter normal (CR o LF)
  46. );
  47. //tipos para eventos
  48. TtsRefreshLines = procedure(fIni, fFin: integer) of object;
  49. TtsScrollLines = procedure of object;
  50. TtsRecSysComm = procedure(info: string) of object;
  51. TtsLineCompleted= procedure(const lineCompleted: string) of object;
  52. // TCursorEvent = procedure(x,y: integer);
  53. { TTermVT100 }
  54. TTermVT100 = class
  55. public
  56. height : integer; //alto real de pantalla
  57. width : integer; //ancho real de pantalla
  58. buf : TtsGrid; //grilla de pantalla
  59. linesAdded: Integer; //líneas agregadas, después de cada llamada a AddData()
  60. Busy : boolean; //bandera de ocupado
  61. //eventos para refrescar pantalla
  62. OnRefreshLines : TtsRefreshLines; //Solicita refrescar un rango de líneas
  63. OnScrollLines : TtsScrollLines; //Indica que se ha agregado una línea al terminal
  64. //eventos adicionales
  65. OnRecSysComm : TtsRecSysComm; //Se ha recibido imformación del sistema
  66. OnLineCompleted: TtsLineCompleted; //Indica que se acaba de agregar una línea completa
  67. // OnChangeCursor: TCursorEvent; //Cambia posición del cursor
  68. ProcEscape : boolean; //Indica si se debe reconocer las secuencias de escape
  69. bhvCR : TBehaveChar; //Comportamiento de CR
  70. bhvLF : TBehaveChar; //Comportamiento de LF
  71. procedure SetCurX(AValue: integer);
  72. procedure SetCurY(AValue: integer);
  73. procedure SetCursor(x, y: integer);
  74. procedure Clear; //Limpia pantalla actual
  75. procedure AddData(const cad: PChar);
  76. private
  77. fCurX, fCurY : integer; //posición del cursor
  78. SavecurX, SavecurY: integer; //para guardar el cursor
  79. EscString : string; //para almacenar la secuencia de escape
  80. //banderas de estado
  81. InEscape : boolean; //en una secuencia de escape
  82. CurEscSeq : tEscSequence; //tipo de secuencia de escape actual
  83. minModified: Integer; //CurY mínimo que se modifica
  84. maxModified: Integer; //CurY máximo que se modifica
  85. procedure eraseChar(const n: integer);
  86. procedure eraseBack;
  87. procedure eraseBOL;
  88. procedure eraseBOS;
  89. procedure eraseEOL;
  90. procedure eraseEOS;
  91. procedure eraseLINE;
  92. procedure ExecSeqCharSet(c: char);
  93. procedure ExecSeqCommand(c: char);
  94. procedure ExecSeqOpenBrk(c: char);
  95. procedure escapeProcess(c: char);
  96. procedure Scroll; //Desplaza la pantalla, dejando la última línea en blanco
  97. procedure CursorRet;
  98. procedure CursorDown;
  99. procedure CursorRight;
  100. public
  101. function CurXY: TPoint;
  102. property CurX: integer read FCurX;
  103. property CurY: integer read FCurY;
  104. public
  105. constructor Create; //Constructor
  106. destructor Destroy; override; //Limpia los buffers
  107. end;
  108. implementation
  109. { TTermVT100 }
  110. function TTermVT100.CurXY: TPoint;
  111. //Devuelve las coordenadas del cursor.
  112. begin
  113. Result.x:=CurX;
  114. Result.y:=CurY;
  115. end;
  116. procedure TTermVT100.SetCurX(AValue: integer);
  117. begin
  118. if Avalue<1 then Avalue:=1; //protección
  119. if fCurX=AValue then Exit; //sin cambio
  120. fCurX:=AValue;
  121. //dispara evento
  122. // if OnChangeCursor<>nil then OnChangeCursor(CurX,CurY);
  123. end;
  124. procedure TTermVT100.SetCurY(AValue: integer);
  125. begin
  126. if Avalue<1 then Avalue:=1; //protección
  127. if fCurY=AValue then Exit; //sin cambio
  128. fCurY:=AValue;
  129. //dispara evento
  130. // if OnChangeCursor<>nil then OnChangeCursor(CurX,CurY);
  131. end;
  132. procedure TTermVT100.SetCursor(x,y:integer);
  133. //Fija las coordenadas del cursor
  134. begin
  135. if x<1 then x:=1; //protección
  136. if y<1 then y:=1; //protección
  137. if (CurX = x) and (CurY = y) then exit;
  138. //hubo cambio
  139. fCurX := x;
  140. fCurY := y;
  141. //dispara evento
  142. // if OnChangeCursor<>nil then OnChangeCursor(CurX,CurY);
  143. end;
  144. procedure TTermVT100.eraseLINE;
  145. //Borra la línea actual
  146. begin
  147. buf[CurY] := '';
  148. End;
  149. procedure TTermVT100.Clear;
  150. //Llena las celdas con espacios en blanco
  151. var
  152. i: Integer;
  153. begin
  154. for i := 1 to height do
  155. buf[i] := '';
  156. SetCursor(1,1); //Fija cursor
  157. end;
  158. procedure TTermVT100.eraseBOL;
  159. //Borra desde el inicio de la línea hasta la posición actual del cursor
  160. var
  161. i: Integer;
  162. begin
  163. //llena con espacios
  164. for i:=1 to fCurX do
  165. buf[CurY][i] := ' ';
  166. End;
  167. procedure TTermVT100.eraseEOL;
  168. //Borra desde el cursor hasta el fin de la línea
  169. begin
  170. //llena con espacios
  171. setlength(buf[CurY],CurX-1); //trunca
  172. End;
  173. procedure TTermVT100.eraseBack;
  174. //Borra desde el cursor un carcteres hacia atrás.
  175. begin
  176. if fCurX<2 then exit; //no se puede eliminar
  177. dec(fCurX);
  178. delete(buf[CurY],fCurX, 1);
  179. End;
  180. procedure TTermVT100.eraseChar(const n: integer);
  181. //Borra desde el cursor un "n" hacia adelante.
  182. begin
  183. if fCurX<2 then exit; //no se puede eliminar
  184. delete(buf[CurY],fCurX, n);
  185. End;
  186. procedure TTermVT100.eraseBOS;
  187. //Borra desde el inicio de la pantalla hasta la posición actual del cursor.
  188. var i: Integer;
  189. begin
  190. eraseBOL; //borra en línea actual
  191. If (CurY > 1) Then begin
  192. For i := 1 To CurY do
  193. buf[i] := '';
  194. End;
  195. End;
  196. procedure TTermVT100.eraseEOS;
  197. //Borra desde el cursor hasta el fin de la pantalla
  198. var i : Integer;
  199. begin
  200. //caso especial
  201. If (curX = 1) And (curY = 1) Then begin
  202. Clear; exit;
  203. end;
  204. //caso normal
  205. eraseEOL; //borra en línea actual
  206. If (CurY <> height) Then begin
  207. For i := CurY + 1 To height do
  208. buf[i] := '';
  209. End;
  210. End;
  211. procedure TTermVT100.Scroll;
  212. var
  213. i: Integer;
  214. begin
  215. if minModified = 1 then begin
  216. //Este es un caso extremo porque se va a perder la línea 1, que ha sido modificada.
  217. //Primero deberíamos actualizarla en la salida, por si la desea registrar.
  218. OnRefreshLines(1,1);
  219. linesAdded := -1; //para que pase a 0, cuando se incremente
  220. //ahora ya podemos desplazar
  221. end;
  222. //mueve las líneas
  223. for i := 1 to height-1 do
  224. buf[i] := buf[i+1];
  225. //Mueve cursor
  226. // Dec(CurY);
  227. //limpia la línea final
  228. buf[height] := '';
  229. inc(linesAdded);
  230. //dispara evento
  231. // if OnChangeCursor<>nil then OnChangeCursor(CurX,CurY);
  232. if OnScrollLines <> nil then begin
  233. OnScrollLines; //para que se agregue una línea
  234. end;
  235. //actualiza las variables de modificación
  236. dec(minModified);
  237. if minModified<1 then begin //protección
  238. minModified := 1;
  239. end;
  240. maxModified := height; //para que considere la línea agregada
  241. end;
  242. procedure TTermVT100.CursorRet;
  243. //Salta a la siguiente línea
  244. begin
  245. if CurY>=height then begin
  246. //está en la línea final
  247. Scroll;
  248. SetCursor(1,height)
  249. end else begin
  250. SetCursor(1,CurY+1)
  251. end;
  252. end;
  253. procedure TTermVT100.CursorDown;
  254. //Desplaza el cursor abajo
  255. begin
  256. if CurY>=height then begin
  257. //Está en la línea final
  258. Scroll;
  259. SetCurY(height);
  260. end else begin
  261. //caso normal
  262. SetCurY(CurY+1);
  263. end;
  264. end;
  265. procedure TTermVT100.CursorRight;
  266. //Desplaza el cursor abajo
  267. begin
  268. if CurX>=width then begin
  269. CursorRet;
  270. end else begin
  271. SetCurX(CurX+1);
  272. end;
  273. end;
  274. procedure TTermVT100.AddData(const cad: PChar);
  275. {Recibe una serie de caracteres y los agrega a la pantalla en la posición actual
  276. del terminal hasta encontrar el caracter #0. Reconoce algunas secuencias de escape,
  277. pero ignora las que cambian la apariencia del texto.}
  278. procedure CurReturn;
  279. {Ejecuta un salto de línea}
  280. var
  281. tmp: Ttslin;
  282. begin
  283. if OnLineCompleted <> nil then begin //hay evento que generar
  284. tmp := buf[CurY]; //guarda cadena que se termina de editar
  285. CursorRet;
  286. OnLineCompleted(tmp); //dispara evento
  287. end else begin //sin evento
  288. CursorRet;
  289. end;
  290. end;
  291. procedure CurMovDown;
  292. {Mueve el cursor una posición}
  293. var
  294. tmp: Ttslin;
  295. begin
  296. if OnLineCompleted <> nil then begin //hay evento que generar
  297. tmp := buf[CurY]; //guarda cadena que se termina de editar
  298. CursorDown;
  299. OnLineCompleted(tmp); //dispara evento
  300. end else begin //sin evento
  301. CursorDown;
  302. end;
  303. end;
  304. var
  305. i: Integer;
  306. largo: Integer;
  307. begin
  308. i:=0;
  309. Busy := true;
  310. linesAdded := 0; //iniica bandera
  311. minModified := CurY; //inicia
  312. maxModified := CurY; //inicia
  313. while cad[i]<>#0 do begin
  314. if ProcEscape and InEscape then begin //en modo escape
  315. escapeProcess(cad[i]);
  316. inc(i);
  317. end else begin
  318. case cad[i] of
  319. #13:begin //salto de línea CR
  320. case bhvCR of
  321. tbcNone : ; //sin acción
  322. tbcNewLine: CurReturn;
  323. tbcNormal : SetCurX(1); //retorno de carro
  324. end;
  325. inc(i);
  326. end;
  327. #10: begin //salto LF
  328. case bhvLF of
  329. tbcNone : ; //sin acción
  330. tbcNewLine: CurReturn;
  331. tbcNormal : begin //siguiente línea
  332. CurMovDown;
  333. end;
  334. end;
  335. inc(i); //ignora
  336. end;
  337. #7: begin //bell
  338. beep;
  339. inc(i);
  340. end;
  341. #8: begin //bacspace
  342. eraseBack;
  343. inc(i);
  344. end;
  345. #27: begin //secuencia de escape
  346. InEscape := true;
  347. inc(i); //pasa al siguiente caracter
  348. end;
  349. else //caracter normal
  350. //debugln(cad[i]);
  351. //procesa
  352. if CurX = length(buf[CurY])+1 then begin
  353. //este es el caso más común, escribir en siguiente caracter
  354. setlength(buf[CurY],curX); //hace crecer la cadena
  355. buf[CurY][CurX] := cad[i]; //escribe caracter
  356. end else if CurX <= length(buf[CurY]) then begin
  357. //esta antes del final de la cadena
  358. buf[CurY][CurX] := cad[i]; //escribe caracter sin temor
  359. end else begin
  360. //está más allá del final de la cadena + 1
  361. largo := length(buf[CurY]);
  362. buf[CurY]+= space(CurX-largo-1); //agrega espacios
  363. setlength(buf[CurY],curX); //hace crecer la cadena
  364. buf[CurY][CurX] := cad[i]; //escribe caracter
  365. end;
  366. // CursorRight; //mueve cursor
  367. if CurX>=width then begin //salto por límite horizontal
  368. CursorRet;
  369. end else begin
  370. SetCurX(CurX+1);
  371. end;
  372. inc(i);
  373. //actualiza la primera y última fila modificada
  374. if CurY<minModified then minModified := CurY;
  375. if CurY>maxModified then maxModified := CurY;
  376. end;
  377. end;
  378. end;
  379. //Llama a evento selectivo de refresco de pantalla
  380. if OnRefreshLines<>nil then OnRefreshLines(minModified, maxModified);
  381. Busy := false;
  382. end;
  383. procedure TTermVT100.escapeProcess(c: char);
  384. begin
  385. If EscString = '' Then begin
  386. //Es el primer caracter (después de ESC). Se ejecuta solo una vez por secuencia.
  387. CurEscSeq := EscSeqOpenBrk; //por defecto termina en alfabético
  388. Case c of
  389. //Verifica si es una secuencia de escape corta (de dos caracteres)
  390. #8: begin //embedded backspace
  391. SetCurX(curX - 1);
  392. InEscape := False;
  393. end;
  394. '7': begin //save cursor
  395. SavecurX := CurX;
  396. SavecurY := CurY;
  397. InEscape := False;
  398. end;
  399. '8': begin //restore cursor
  400. SetCursor(SavecurX, SavecurY);
  401. InEscape := False;
  402. end;
  403. 'c':; //look at VSIreset()
  404. 'D': begin //cursor down
  405. SetCurY(CurY+1);
  406. InEscape := False;
  407. end;
  408. 'E': begin //next line
  409. SetCursor(1, curY + 1);
  410. InEscape := False;
  411. end;
  412. 'H': begin //set tab
  413. Debugln('Secuencia no soportada ESC-H');
  414. InEscape := False;
  415. end;
  416. 'I': begin //look at bp_ESC_I()
  417. InEscape := False;
  418. end;
  419. 'M': begin //cursor up
  420. SetCurY(CurY-1);
  421. InEscape := False;
  422. end;
  423. 'Z': begin //send ident
  424. InEscape := False;
  425. end;
  426. //Secuencias que terminan con otros caracteres
  427. '[':begin
  428. CurEscSeq := EscSeqOpenBrk; //termina en alfabético
  429. end;
  430. '(',')','*','+': begin
  431. CurEscSeq := EscSeqCharSet; //termina con cualquier caracter alfanumérico
  432. end;
  433. ']':begin
  434. CurEscSeq := EscSeqCommand; //termina con #7
  435. end;
  436. Else
  437. //Invalid start of escape sequence
  438. Debugln('Secuencia desconocida: ' + c);
  439. InEscape := False;
  440. Exit;
  441. End;
  442. End;
  443. //Verifica si la secuencia de escape actual temina
  444. If (CurEscSeq = EscSeqOpenBrk) and (c in ['a'..'z','A'..'Z']) Then begin //termina en alfabético
  445. //Se completó la secuencia de escape.
  446. ExecSeqOpenBrk(c);
  447. InEscape := False;
  448. EscString := '';
  449. end else If (CurEscSeq = EscSeqCharSet) and (c in ['a'..'z','A'..'Z','0'..'9']) Then begin
  450. //Se completó la secuencia de escape.
  451. ExecSeqCharSet(c);
  452. InEscape := False;
  453. EscString := '';
  454. end else If (CurEscSeq = EscSeqCommand) and (c = #7) Then begin //termina con #7
  455. //Se completó la secuencia de escape.
  456. ExecSeqCommand(c);
  457. InEscape := False;
  458. EscString := '';
  459. end else begin //no termina la secuencia aún
  460. EscString += c; //acumula secuencia
  461. exit;
  462. End;
  463. end;
  464. procedure TTermVT100.ExecSeqCharSet(c: char);
  465. //Ejecuta las secuencias de escape ESC( ESC) ESC* ESC+.
  466. //"c" es el último caracter capturado.
  467. begin
  468. //Debugln('ESC:' + EscString + c);
  469. end;
  470. procedure TTermVT100.ExecSeqCommand(c: char);
  471. //Ejecuta las secuencias de escape ESC].
  472. //"c" es el último caracter capturado.
  473. var
  474. EscString0: String;
  475. begin
  476. //Debugln('ESC:' + EscString + c);
  477. EscString0 := copy(EscString,2,length(EscString)); //quita primer caracter
  478. if copy(EscString0,1,2) = '0;' then begin //ESC ] 0;
  479. if OnRecSysComm<> nil then OnRecSysComm(copy(EscString0,3,100));
  480. end;
  481. end;
  482. procedure TTermVT100.ExecSeqOpenBrk(c: char);
  483. //Ejecuta la secuencia de escape ESC[. "c" es el último caracter capturado.
  484. var
  485. EscString0: string; //para almacenar la secuencia de escape
  486. yDiff: Integer;
  487. xDiff: Integer;
  488. cY: Integer;
  489. cX: Integer;
  490. function GetParamN(var s: string): integer;
  491. //Extrae un parámetro numérico de la cadena
  492. var
  493. i: SizeInt;
  494. begin
  495. if s='' then exit(0); //caso cadena nula
  496. i := Pos(';', s);
  497. if i = 0 then begin
  498. Result := StrToInt(s);
  499. s := '';
  500. end else begin
  501. Result := StrToInt(copy(s, 1, i - 1));
  502. s := copy(s, i + 1, length(s));
  503. end;
  504. end;
  505. begin
  506. //Debugln('ESC:' + EscString + c);
  507. EscString0 := copy(EscString,2,length(EscString)); //quita primer caracter
  508. //El último caracter, indicará el tipo de comando.
  509. Case c of
  510. 'A': begin // A ==> move cursor up
  511. yDiff := GetParamN(EscString0);
  512. If yDiff = 0 Then yDiff := 1;
  513. SetCurY(curY - yDiff);
  514. end;
  515. 'B': begin // B ==> move cursor down
  516. yDiff := GetParamN(EscString0);
  517. If yDiff = 0 Then yDiff := 1;
  518. SetCurY(curY + yDiff);
  519. end;
  520. 'C': begin // C ==> move cursor right
  521. xDiff := GetParamN(EscString0);
  522. If xDiff = 0 Then xDiff := 1;
  523. SetCurX(curX + xDiff);
  524. end;
  525. 'D': begin // D ==> move cursor left
  526. xDiff := GetParamN(EscString0);
  527. If xDiff = 0 Then xDiff := 1;
  528. SetCurX(curX - xDiff);
  529. end;
  530. 'H','f': begin //Goto cursor position indicated by escape sequence
  531. if (EscString0='') or (EscString0=';') then begin
  532. SetCursor(1, 1);
  533. end else begin //coordinates indicated
  534. cY := GetParamN(EscString0);
  535. cX := StrToInt(EscString0);
  536. SetCursor(cX, cY);
  537. end;
  538. end;
  539. 'J': begin //Erase screen
  540. if EscString0='' then begin
  541. eraseEOS;
  542. end else begin
  543. Case StrToInt(EscString0) of
  544. 0: eraseEOS; //Borrar hasta el final de la pantalla
  545. 1: eraseBOS; //Borra pantalla antes del cursor
  546. 2: Clear;
  547. End;
  548. end;
  549. end;
  550. 'K': begin //Erase line
  551. if EscString0='' then begin
  552. eraseEOL;
  553. end else begin
  554. Case STrToInt(EscString0) of
  555. 0: eraseEOL; //borra hasta el final de la línea
  556. 1: eraseBOL; //borra hasta el cursor
  557. 2: eraseLINE;
  558. End;
  559. end;
  560. end;
  561. 'P': begin //ESC[ Pn P Delete Pn characters, to left
  562. //Debugln(EscString+c);
  563. yDiff := GetParamN(EscString0);
  564. eraseChar(yDiff);
  565. end;
  566. 'g': begin //clear tabs
  567. // Dim tY As Integer
  568. Debugln('Secuencia no soportada ESC-g');
  569. // For tY = 0 To 19
  570. // tab_table(tY) = 0
  571. // Next tY
  572. end;
  573. 'h': begin //Set mode
  574. end;
  575. 'i': begin // print mode
  576. end;
  577. 'l': begin //Reset mode
  578. end;
  579. 'm': begin //text attributes sequence
  580. end;
  581. 'r': begin //scrolling region
  582. Debugln('Secuencia no soportada ESC-r');
  583. end;
  584. 's': begin //Save cursor position
  585. SavecurX := CurX;
  586. SavecurY := CurY;
  587. end;
  588. 'u': begin //restore cursor position
  589. SetCursor(SavecurX, SavecurY);
  590. end;
  591. Else
  592. Debugln(EscString+c);
  593. End;
  594. end;
  595. constructor TTermVT100.Create;
  596. var
  597. i: Integer;
  598. begin
  599. //limpia las líneas
  600. for i := 1 to MAX_HEIGHT_TS do
  601. buf[i] := '';
  602. SetCursor(1,1);
  603. EscString := '';
  604. //tamaño por defecto
  605. width := 120;
  606. height := 25;
  607. Clear; //limpia
  608. ProcEscape := true; //para que reconozca (no necesariamente ejecutarlas) las secuencias de escape
  609. bhvCR := tbcNewLine;
  610. bhvLF := tbcNone;
  611. //inicia bandera de ocupado
  612. Busy := false;
  613. end;
  614. destructor TTermVT100.Destroy;
  615. begin
  616. inherited Destroy;
  617. end;
  618. end.