wansi.pas 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1996-2000 by Berczi Gabor
  5. ANSI support
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {.$DEFINE DEBUG}
  13. unit WANSI;
  14. interface
  15. uses Objects,Drivers,
  16. {$ifdef WITH_CRT}
  17. Crt,
  18. {$endif WITH_CRT}
  19. Dos,Views,App;
  20. const
  21. {$ifndef WITH_CRT}
  22. { Foreground and background color constants }
  23. Black = 0;
  24. Blue = 1;
  25. Green = 2;
  26. Cyan = 3;
  27. Red = 4;
  28. Magenta = 5;
  29. Brown = 6;
  30. LightGray = 7;
  31. { Foreground color constants }
  32. DarkGray = 8;
  33. LightBlue = 9;
  34. LightGreen = 10;
  35. LightCyan = 11;
  36. LightRed = 12;
  37. LightMagenta = 13;
  38. Yellow = 14;
  39. White = 15;
  40. { Add-in for blinking }
  41. Blink = 128;
  42. {$endif not WITH_CRT}
  43. ANSIMaxParamLen = 30; { max ANSI escape sequence length }
  44. ANSICurPosStackSize = 20; { max number of cursor positions stored at the same time }
  45. Esc = #27;
  46. MaxVideoLine = 65520 div (2*MaxViewWidth); { maximum number of lines that fit in 64K }
  47. { BoundCheck constants }
  48. bc_MinX = 1;
  49. bc_MinY = 2;
  50. bc_MaxX = 4;
  51. bc_MaxY = 8;
  52. bc_X = bc_MinX or bc_MaxX;
  53. bc_Y = bc_MinY or bc_MaxY;
  54. bc_Min = bc_MinX or bc_MinY;
  55. bc_Max = bc_MaxX or bc_MaxY;
  56. bc_All = bc_X or bc_Y;
  57. type
  58. TANSIParam = string[ANSIMaxParamLen];
  59. PHookProc = ^THookProc;
  60. THookProc = procedure (S: string);
  61. PConsoleObject = ^TConsoleObject;
  62. TConsoleObject = object(TObject)
  63. CurPos : TPoint;
  64. Size : TPoint;
  65. TextAttr : byte;
  66. BoldOn : boolean;
  67. BlinkOn : boolean;
  68. BoundChecks: byte;
  69. LineWrapping: boolean;
  70. ReplyHook : PHookProc;
  71. KeyHook : PHookProc;
  72. WriteHook : PHookProc;
  73. constructor Init(AReplyHook, AKeyHook, AWriteHook: PHookProc);
  74. procedure Home; virtual;
  75. procedure ClrScr; virtual;
  76. procedure FillScreen(B: byte); virtual;
  77. procedure ClrEol; virtual;
  78. procedure GotoXY(X,Y: integer); virtual;
  79. procedure Write(S: string); virtual;
  80. procedure WriteLn(S: string); virtual;
  81. procedure WriteChar(C: char); virtual;
  82. procedure DelLine(LineCount: integer); virtual;
  83. procedure InsLine(LineCount: integer); virtual;
  84. procedure HighVideo; virtual;
  85. procedure BlinkVideo; virtual;
  86. procedure NoBlinkVideo; virtual;
  87. procedure NormVideo; virtual;
  88. procedure LowVideo; virtual;
  89. procedure TextBackground(Color: byte); virtual;
  90. procedure TextColor(Color: byte); virtual;
  91. function WhereX: integer; virtual;
  92. function WhereY: integer; virtual;
  93. procedure CursorOn; virtual;
  94. procedure CursorOff; virtual;
  95. procedure UpdateCursor; virtual;
  96. { --- Hook procedures --- }
  97. procedure Reply(S: string); virtual;
  98. procedure PutKey(S: string); virtual;
  99. destructor Done; virtual;
  100. private
  101. procedure ProcessChar(C: char); virtual;
  102. end;
  103. PANSIConsole = ^TANSIConsole;
  104. TANSIConsole = object(TConsoleObject)
  105. ANSIParam : TANSIParam;
  106. ANSILevel : byte;
  107. ANSICurPosStack : array[1..ANSICurPosStackSize] of TPoint;
  108. ANSICurPosStackPtr : byte;
  109. constructor Init(AReplyHook, AKeyHook, AWriteHook: PHookProc);
  110. procedure ProcessChar(C: char); virtual;
  111. function GetANSIParam: integer; virtual;
  112. { --- ANSI functions --- }
  113. procedure PushCurPos; virtual;
  114. procedure PopCurPos; virtual;
  115. procedure CursorUp(LineCount: integer); virtual;
  116. procedure CursorDown(LineCount: integer); virtual;
  117. procedure CursorForward(CharCount: integer); virtual;
  118. procedure CursorBack(CharCount: integer); virtual;
  119. procedure SetAttr(Color: integer); virtual;
  120. end;
  121. {$ifdef WITH_CRT}
  122. PCrtConsole = ^TCrtConsole;
  123. TCrtConsole = object(TANSIConsole)
  124. constructor Init(AReplyHook, AKeyHook, AWriteHook: PHookProc);
  125. procedure CursorOn; virtual;
  126. procedure CursorOff; virtual;
  127. procedure ClrScr; virtual;
  128. procedure ClrEol; virtual;
  129. procedure WriteChar(C: char); virtual;
  130. procedure DelLine(LineCount: integer); virtual;
  131. procedure InsLine(LineCount: integer); virtual;
  132. procedure UpdateCursor; virtual;
  133. procedure TextBackground(Color: byte); virtual;
  134. procedure TextColor(Color: byte); virtual;
  135. end;
  136. {$endif WITH_CRT}
  137. PANSIView = ^TANSIView;
  138. PANSIViewConsole = ^TANSIViewConsole;
  139. TANSIViewConsole = object(TANSIConsole)
  140. Owner : PANSIView;
  141. constructor Init(AOwner: PANSIView);
  142. procedure CursorOn; virtual;
  143. procedure CursorOff; virtual;
  144. procedure ClrScr; virtual;
  145. procedure ClrEol; virtual;
  146. procedure WriteChar(C: char); virtual;
  147. procedure DelLine(LineCount: integer); virtual;
  148. procedure InsLine(LineCount: integer); virtual;
  149. procedure UpdateCursor; virtual;
  150. procedure GotoXY(X,Y: integer); virtual;
  151. end;
  152. TVideoBuf = array[0..MaxViewWidth*MaxVideoLine] of word;
  153. TANSIView = object(TScroller)
  154. Console : PANSIViewConsole;
  155. Buffer : TVideoBuf;
  156. LockCount : word;
  157. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar:PScrollBar);
  158. function LoadFile(const FileName: string): boolean;
  159. procedure Draw; virtual;
  160. destructor Done; virtual;
  161. procedure Write(S: string); virtual;
  162. procedure WriteLn(S: string); virtual;
  163. procedure Lock; virtual;
  164. procedure UnLock; virtual;
  165. procedure ChangeBounds(var Bounds: TRect); virtual;
  166. procedure HandleEvent(var Event: TEvent); virtual;
  167. private
  168. end;
  169. PANSIBackground = ^TANSIBackground;
  170. PANSIBackgroundConsole = ^TANSIBackgroundConsole;
  171. TANSIBackgroundConsole = object(TANSIConsole)
  172. Owner : PANSIBackground;
  173. constructor Init(AOwner: PANSIBackground);
  174. procedure CursorOn; virtual;
  175. procedure CursorOff; virtual;
  176. procedure ClrScr; virtual;
  177. procedure ClrEol; virtual;
  178. procedure WriteChar(C: char); virtual;
  179. procedure DelLine(LineCount: integer); virtual;
  180. procedure InsLine(LineCount: integer); virtual;
  181. procedure UpdateCursor; virtual;
  182. procedure GotoXY(X,Y: integer); virtual;
  183. end;
  184. TANSIBackground = object(TBackground)
  185. Console : PANSIBackgroundConsole;
  186. Buffer : TVideoBuf;
  187. LockCount : word;
  188. constructor Init(var Bounds: TRect);
  189. function LoadFile(const FileName: string): boolean;
  190. procedure Draw; virtual;
  191. destructor Done; virtual;
  192. procedure Write(S: string); virtual;
  193. procedure WriteLn(S: string); virtual;
  194. procedure Lock; virtual;
  195. procedure UnLock; virtual;
  196. procedure ChangeBounds(var Bounds: TRect); virtual;
  197. procedure HandleEvent(var Event: TEvent); virtual;
  198. private
  199. end;
  200. implementation
  201. uses WUtils;
  202. constructor TConsoleObject.Init(AReplyHook, AKeyHook, AWriteHook: PHookProc);
  203. begin
  204. inherited Init;
  205. ReplyHook:=AReplyHook; KeyHook:=AKeyHook; WriteHook:=AWriteHook;
  206. BoundChecks:=bc_All; LineWrapping:=true;
  207. TextColor(LightGray); TextBackground(Black);
  208. NormVideo;
  209. ClrScr;
  210. end;
  211. procedure TConsoleObject.Home;
  212. begin
  213. GotoXY(1,1);
  214. end;
  215. procedure TConsoleObject.ClrScr;
  216. begin
  217. Abstract;
  218. end;
  219. procedure TConsoleObject.FillScreen(B: byte);
  220. var X,Y: integer;
  221. S : string;
  222. begin
  223. GotoXY(1,1);
  224. for Y:=1 to Size.Y do
  225. begin
  226. S:='';
  227. for X:=1 to Size.X do S:=S+chr(B);
  228. WriteLn(S);
  229. end;
  230. end;
  231. procedure TConsoleObject.ClrEol;
  232. begin
  233. Abstract;
  234. end;
  235. procedure TConsoleObject.GotoXY(X,Y: integer);
  236. begin
  237. if (BoundChecks and bc_MinX)<>0 then X:=Max(X,1);
  238. if (BoundChecks and bc_MaxX)<>0 then
  239. if LineWrapping then while (X>Size.X) and (Size.X<>0)
  240. do begin
  241. Inc(Y);
  242. X:=X-Size.X;
  243. end
  244. else X:=Min(X,Size.X);
  245. if (BoundChecks and bc_MinY)<>0 then Y:=Max(Y,1);
  246. if (BoundChecks and bc_MaxY)<>0 then Y:=Min(Y,Size.Y);
  247. CurPos.X:=X; CurPos.Y:=Y;
  248. UpdateCursor;
  249. end;
  250. procedure TConsoleObject.ProcessChar(C: char);
  251. begin
  252. WriteChar(C);
  253. end;
  254. procedure TConsoleObject.WriteChar(C: char);
  255. begin
  256. Abstract;
  257. end;
  258. procedure TConsoleObject.Write(S: string); {assembler;
  259. asm
  260. push ds
  261. lds si, S
  262. lodsb
  263. xor ah, ah
  264. mov cx, ax
  265. @loop:
  266. or cx, cx
  267. je @exitloop
  268. lodsb
  269. pop ds
  270. push ax
  271. call ProcessChar
  272. push ds
  273. dec cx
  274. jmp @loop
  275. @exitloop:
  276. pop ds
  277. end;}
  278. var Len: byte;
  279. I : byte;
  280. begin
  281. Len:=length(S);
  282. for I:=1 to Len do ProcessChar(S[I]);
  283. end;
  284. procedure TConsoleObject.WriteLn(S: string);
  285. begin
  286. Write(S+#10);
  287. end;
  288. procedure TConsoleObject.DelLine(LineCount: integer);
  289. begin
  290. Abstract;
  291. end;
  292. procedure TConsoleObject.InsLine(LineCount: integer);
  293. begin
  294. Abstract;
  295. end;
  296. procedure TConsoleObject.NormVideo;
  297. begin
  298. BoldOn:=false; BlinkOn:=false;
  299. TextColor(LightGray);
  300. TextBackground(Black);
  301. end;
  302. procedure TConsoleObject.BlinkVideo;
  303. begin
  304. BlinkOn:=true;
  305. TextBackground(TextAttr shr 4);
  306. end;
  307. procedure TConsoleObject.NoBlinkVideo;
  308. begin
  309. BlinkOn:=false;
  310. TextBackground(TextAttr shr 4);
  311. end;
  312. procedure TConsoleObject.HighVideo;
  313. begin
  314. BoldOn:=true;
  315. TextColor(TextAttr);
  316. end;
  317. procedure TConsoleObject.LowVideo;
  318. begin
  319. BoldOn:=false;
  320. TextColor(TextAttr);
  321. end;
  322. procedure TConsoleObject.TextBackground(Color: byte);
  323. begin
  324. if BlinkOn=false then TextAttr:=TextAttr and $7f;
  325. TextAttr:=(TextAttr and $0f) or (Color shl 4) or byte(BlinkOn)*$80;
  326. end;
  327. procedure TConsoleObject.TextColor(Color: byte);
  328. begin
  329. if BoldOn=false then TextAttr:=TextAttr and not $08;
  330. TextAttr:=((TextAttr and $f0) or (Color and $0f) or byte(BoldOn)*$08);
  331. end;
  332. function TConsoleObject.WhereX: integer;
  333. begin
  334. WhereX:=CurPos.X;
  335. end;
  336. function TConsoleObject.WhereY: integer;
  337. begin
  338. WhereY:=CurPos.Y;
  339. end;
  340. procedure TConsoleObject.CursorOn;
  341. begin
  342. Abstract;
  343. end;
  344. procedure TConsoleObject.CursorOff;
  345. begin
  346. Abstract;
  347. end;
  348. procedure TConsoleObject.UpdateCursor;
  349. begin
  350. Abstract;
  351. end;
  352. procedure TConsoleObject.Reply(S: string);
  353. begin
  354. if ReplyHook<>nil then ReplyHook^(S);
  355. end;
  356. procedure TConsoleObject.PutKey(S: string);
  357. begin
  358. if KeyHook<>nil then KeyHook^(S);
  359. end;
  360. destructor TConsoleObject.Done;
  361. begin
  362. inherited Done;
  363. end;
  364. {$ifdef WITH_CRT}
  365. constructor TCrtConsole.Init(AReplyHook, AKeyHook, AWriteHook: PHookProc);
  366. begin
  367. inherited Init(AReplyHook, AKeyHook, AWriteHook);
  368. Size.X:=Lo(Crt.WindMax); Size.Y:=Hi(Crt.WindMax);
  369. end;
  370. procedure TCrtConsole.CursorOn;
  371. begin
  372. end;
  373. procedure TCrtConsole.CursorOff;
  374. begin
  375. end;
  376. procedure TCrtConsole.ClrScr;
  377. begin
  378. Crt.ClrScr;
  379. GotoXY(Crt.WhereX,Crt.WhereY);
  380. end;
  381. procedure TCrtConsole.ClrEol;
  382. begin
  383. Crt.ClrEol;
  384. GotoXY(Crt.WhereX,Crt.WhereY);
  385. end;
  386. procedure TCrtConsole.WriteChar(C: char);
  387. {var OK: boolean;}
  388. begin
  389. { OK:=((C>=#32) and (WhereX<Size.X)) or (C<#32);
  390. if OK then
  391. begin}
  392. System.Write(C);
  393. GotoXY(Crt.WhereX,Crt.WhereY);
  394. { end
  395. else Inc(CurPos.X);}
  396. end;
  397. procedure TCrtConsole.DelLine(LineCount: integer);
  398. var I: integer;
  399. begin
  400. for I:=1 to LineCount do Crt.DelLine;
  401. end;
  402. procedure TCrtConsole.InsLine(LineCount: integer);
  403. var I: integer;
  404. begin
  405. for I:=1 to LineCount do Crt.InsLine;
  406. end;
  407. procedure TCrtConsole.UpdateCursor;
  408. begin
  409. Crt.GotoXY(CurPos.X,CurPos.Y);
  410. end;
  411. procedure TCrtConsole.TextBackground(Color: byte);
  412. begin
  413. inherited TextBackground(Color);
  414. Crt.TextAttr:=TextAttr;
  415. end;
  416. procedure TCrtConsole.TextColor(Color: byte);
  417. begin
  418. inherited TextColor(Color);
  419. Crt.TextAttr:=TextAttr;
  420. end;
  421. {$endif WITH_CRT}
  422. constructor TANSIConsole.Init(AReplyHook, AKeyHook, AWriteHook: PHookProc);
  423. begin
  424. inherited Init(AReplyHook, AKeyHook, AWriteHook);
  425. BoundChecks:=bc_MaxX;
  426. ANSIParam:=''; ANSILevel:=0; ANSICurPosStackPtr:=0;
  427. end;
  428. procedure TANSIConsole.ProcessChar(C: char);
  429. var SkipThis : boolean;
  430. ANSIDone : boolean;
  431. X,Y,Z : integer;
  432. begin
  433. SkipThis:=false;
  434. if C=Esc then begin ANSILevel:=1; SkipThis:=true; end else
  435. if (ANSILevel=1) then
  436. begin
  437. ANSILevel:=0;
  438. case C of
  439. '[' : begin ANSILevel:=2; SkipThis:=true; end;
  440. end;
  441. end;
  442. if SkipThis=false then
  443. if (ANSILevel=2)
  444. then begin
  445. ANSIDone:=true;
  446. case C of
  447. 'H','f' : if ANSIParam='' then GotoXY(1,1) else
  448. begin
  449. X:=WhereX; Y:=WhereY;
  450. Z:=Pos(';',ANSIParam);
  451. if Z=0
  452. then Y:=GetANSIParam
  453. else if Z=1 then X:=GetANSIParam
  454. else begin Y:=GetANSIParam; X:=GetANSIParam; end;
  455. GotoXY(X,Y);
  456. end;
  457. 'A' : if ANSIParam='' then CursorUp(1)
  458. else CursorUp(GetANSIParam);
  459. 'B' : if ANSIParam='' then CursorDown(1)
  460. else CursorDown(GetANSIParam);
  461. 'C' : if ANSIParam='' then CursorForward(1)
  462. else CursorForward(GetANSIParam);
  463. 'D' : if ANSIParam='' then CursorBack(1)
  464. else CursorBack(GetANSIParam);
  465. 's' : if ANSIParam='' then PushCurPos;
  466. 'u' : if ANSIParam='' then PopCurPos;
  467. 'J' : if ANSIParam='2' then begin ANSIParam:=''; ClrScr; end
  468. else FillScreen(GetANSIParam);
  469. 'K' : if ANSIParam='' then ClrEol;
  470. 'L' : if ANSIParam='' then InsLine(1)
  471. else InsLine(GetANSIParam);
  472. 'M' : if ANSIParam='' then DelLine(1)
  473. else DelLine(GetANSIParam);
  474. 'm' : while ANSIParam<>'' do SetAttr(GetANSIParam);
  475. else begin ANSIParam:=ANSIParam+C; ANSIDone:=false; end;
  476. end;
  477. if ANSIDone then
  478. begin
  479. {$IFDEF DEBUG}
  480. if ANSIParam<>'' then RunError(240);
  481. {$ENDIF}
  482. ANSIParam:=''; ANSILevel:=0;
  483. end;
  484. end
  485. else begin
  486. WriteChar(C);
  487. if C=#10 then WriteChar(#13);
  488. end;
  489. end;
  490. function TANSIConsole.GetANSIParam: integer;
  491. var P: byte;
  492. I,C: integer;
  493. begin
  494. P:=Pos(';',ANSIParam);
  495. if P=0 then P:=length(ANSIParam)+1;
  496. Val(copy(ANSIParam,1,P-1),I,C);
  497. if C<>0 then I:=0;
  498. Delete(ANSIParam,1,P);
  499. GetANSIParam:=I;
  500. end;
  501. procedure TANSIConsole.CursorUp(LineCount: integer);
  502. begin
  503. GotoXY(WhereX,WhereY-LineCount);
  504. end;
  505. procedure TANSIConsole.CursorDown(LineCount: integer);
  506. begin
  507. GotoXY(WhereX,WhereY+LineCount);
  508. end;
  509. procedure TANSIConsole.CursorForward(CharCount: integer);
  510. var X, Y: integer;
  511. begin
  512. X:=WhereX; Y:=WhereY;
  513. X:=X+CharCount;
  514. while (X>Size.X) do
  515. begin Inc(Y); Dec(X,Size.X); end;
  516. GotoXY(X,Y);
  517. end;
  518. procedure TANSIConsole.CursorBack(CharCount: integer);
  519. var X, Y: integer;
  520. begin
  521. X:=WhereX; Y:=WhereY;
  522. X:=X-CharCount;
  523. while (X<1) do begin Dec(Y); Inc(X,Size.X); end;
  524. GotoXY(X,Y);
  525. end;
  526. procedure TANSIConsole.PushCurPos;
  527. begin
  528. if ANSICurPosStackPtr=ANSICurPosStackSize then Exit;
  529. Inc(ANSICurPosStackPtr);
  530. ANSICurPosStack[ANSICurPosStackPtr].X:=WhereX;
  531. ANSICurPosStack[ANSICurPosStackPtr].Y:=WhereY;
  532. end;
  533. procedure TANSIConsole.PopCurPos;
  534. begin
  535. if ANSICurPosStackPtr=0 then Exit;
  536. GotoXY(ANSICurPosStack[ANSICurPosStackPtr].X,ANSICurPosStack[ANSICurPosStackPtr].Y);
  537. Dec(ANSICurPosStackPtr);
  538. end;
  539. procedure TANSIConsole.SetAttr(Color: integer);
  540. const ColorTab : array[0..7] of byte =
  541. (Black,Red,Green,Brown,Blue,Magenta,Cyan,LightGray);
  542. begin
  543. case Color of
  544. 0 : NormVideo;
  545. 1 : HighVideo;
  546. 5 : BlinkVideo;
  547. 7,27 : TextAttr:=(TextAttr shl 4) or (TextAttr shr 4);
  548. 8 : TextColor(TextAttr shr 4);
  549. 21,22 : LowVideo;
  550. 25 : NoBlinkVideo;
  551. 30..37 : TextColor(ColorTab[Color-30]);
  552. 40..47 : TextBackground(ColorTab[Color-40]);
  553. (* else {$IFDEF DEBUG}begin system.writeln('Unknown attr : ',Color); Halt; end{$ENDIF};*)
  554. end;
  555. end;
  556. constructor TANSIViewConsole.Init(AOwner: PANSIView);
  557. begin
  558. if AOwner=nil then Fail;
  559. inherited Init(nil,nil,nil);
  560. Owner:=AOwner;
  561. Size:=Owner^.Size;
  562. end;
  563. procedure TANSIViewConsole.CursorOn;
  564. begin
  565. Owner^.ShowCursor;
  566. end;
  567. procedure TANSIViewConsole.CursorOff;
  568. begin
  569. Owner^.HideCursor;
  570. end;
  571. procedure TANSIViewConsole.ClrScr;
  572. var X,Y: word;
  573. Pos: longint;
  574. begin
  575. GotoXY(1,1);
  576. if Owner<>nil then
  577. for X:=0 to MaxViewWidth-1 do for Y:=0 to Size.Y-1 do
  578. begin
  579. Pos:=(Owner^.Delta.Y*MaxViewWidth)+X+Y*MaxViewWidth;
  580. Owner^.Buffer[Pos]:=32+256*word(TextAttr);
  581. end;
  582. end;
  583. procedure TANSIViewConsole.ClrEol;
  584. var X,Y: word;
  585. Pos: longint;
  586. begin
  587. if Owner<>nil then
  588. begin
  589. Y:=CurPos.Y;
  590. for X:=CurPos.X to MaxViewWidth-1 do
  591. begin
  592. Pos:=(Owner^.Delta.Y*MaxViewWidth)+X+Y*MaxViewWidth;
  593. Owner^.Buffer[Pos]:=32+256*word(TextAttr);
  594. end;
  595. end;
  596. end;
  597. procedure TANSIViewConsole.WriteChar(C: char);
  598. var Pos: longint;
  599. begin
  600. case C of
  601. #8 : begin
  602. CursorBack(1);
  603. Pos:=(CurPos.Y-1)*MaxViewWidth+(WhereX-1);
  604. Owner^.Buffer[Pos]:=ord(' ')+256*word(TextAttr);
  605. end;
  606. #0..#7,#9,
  607. #11..#12,
  608. #14..#31,
  609. #32..#255
  610. : begin
  611. Pos:=(CurPos.Y-1)*MaxViewWidth+(WhereX-1);
  612. Owner^.Buffer[Pos]:=ord(C)+256*word(TextAttr);
  613. GotoXY(WhereX+1,WhereY);
  614. end;
  615. #10 :
  616. GotoXY(WhereX,WhereY+1);
  617. #13 :
  618. GotoXY(1,WhereY);
  619. else {$IFDEF DEBUG}RunError(241){$ENDIF};
  620. end;
  621. end;
  622. procedure TANSIViewConsole.DelLine(LineCount: integer);
  623. begin
  624. Abstract;
  625. end;
  626. procedure TANSIViewConsole.InsLine(LineCount: integer);
  627. begin
  628. Abstract;
  629. end;
  630. procedure TANSIViewConsole.UpdateCursor;
  631. begin
  632. if Owner<>nil then
  633. if Owner^.LockCount=0 then Owner^.SetCursor(WhereX-1,WhereY-1);
  634. end;
  635. procedure TANSIViewConsole.GotoXY(X,Y: integer);
  636. var W: word;
  637. begin
  638. if Owner<>nil then
  639. while Y>MaxVideoLine do
  640. begin
  641. Move(Owner^.Buffer[MaxViewWidth],Owner^.Buffer,SizeOf(Owner^.Buffer)-(MaxViewWidth*2));
  642. W:=(MaxViewWidth*MaxVideoLine)-1-(MaxViewWidth);
  643. FillChar(Owner^.Buffer[W],MaxViewWidth*2,0);
  644. Dec(Y);
  645. end;
  646. inherited GotoXY(X,Y);
  647. end;
  648. constructor TANSIView.Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
  649. PScrollBar);
  650. begin
  651. inherited Init(Bounds,AHScrollBar,AVScrollBar);
  652. LockCount:=0; Options:=Options or ofTopSelect;
  653. GrowMode:=gfGrowHiX or gfGrowHiY;
  654. SetLimit({MaxViewWidth}80,MaxVideoLine);
  655. New(Console, Init(@Self));
  656. Console^.Size.X:=80; Console^.Size.Y:=25;
  657. Console^.ClrScr;
  658. Console^.CursorOn;
  659. end;
  660. function TANSIView.LoadFile(const FileName: string): boolean;
  661. var S: PBufStream;
  662. OK: boolean;
  663. B: array[0..1023] of char;
  664. I,FragSize: integer;
  665. begin
  666. {$I-}
  667. New(S, Init(FileName, stOpenRead, 4096));
  668. OK:=Assigned(S);
  669. while OK and (S^.Status=stOK) do
  670. begin
  671. FragSize:=Min(Sizeof(B),S^.GetSize-S^.GetPos);
  672. if FragSize=0 then Break;
  673. S^.Read(B,FragSize);
  674. OK:=(S^.Status=stOK);
  675. if OK then
  676. for I:=0 to FragSize-1 do
  677. self.Write(B[I]);
  678. end;
  679. if Assigned(S) then Dispose(S, Done); S:=nil;
  680. {$I+}
  681. LoadFile:=OK;
  682. end;
  683. procedure TANSIView.Draw;
  684. var I: integer;
  685. Pos: longint;
  686. X,Y: integer;
  687. begin
  688. if LockCount<>0 then Exit;
  689. for I:=0 to Size.Y-1 do
  690. begin
  691. Pos:=Delta.X+(Delta.Y+I)*MaxViewWidth;
  692. WriteLine(0,I,Size.X,1,Buffer[Pos]);
  693. end;
  694. if Console=nil then Exit;
  695. X:=Console^.WhereX-Delta.X; Y:=Console^.WhereY-Delta.Y;
  696. if (X<0) or (Y<0) or (X>Size.X-1) or (Y>Size.X-1)
  697. then HideCursor
  698. else begin
  699. ShowCursor;
  700. SetCursor(X-1,Y-1);
  701. end;
  702. end;
  703. procedure TANSIView.Write(S: string);
  704. begin
  705. Console^.Write(S);
  706. DrawView;
  707. end;
  708. procedure TANSIView.WriteLn(S: string);
  709. begin
  710. Console^.WriteLn(S);
  711. DrawView;
  712. end;
  713. procedure TANSIView.Lock;
  714. begin
  715. Inc(LockCount);
  716. end;
  717. procedure TANSIView.UnLock;
  718. begin
  719. Dec(LockCount);
  720. if LockCount=0 then DrawView;
  721. end;
  722. procedure TANSIView.ChangeBounds(var Bounds: TRect);
  723. begin
  724. inherited ChangeBounds(Bounds);
  725. { Console^.Size.X:=Size.X; Console^.Size.Y:=Size.Y;}
  726. end;
  727. procedure TANSIView.HandleEvent(var Event: TEvent);
  728. begin
  729. inherited HandleEvent(Event);
  730. { if Event.What=evKeyDown then
  731. begin
  732. if VScrollBar<>nil then VScrollBar^.HandleEvent(Event);
  733. if HScrollBar<>nil then HScrollBar^.HandleEvent(Event);
  734. end;}
  735. end;
  736. destructor TANSIView.Done;
  737. begin
  738. Dispose(Console, Done);
  739. inherited Done;
  740. end;
  741. constructor TANSIBackgroundConsole.Init(AOwner: PANSIBackground);
  742. begin
  743. if AOwner=nil then Fail;
  744. inherited Init(nil,nil,nil);
  745. Owner:=AOwner;
  746. Size:=Owner^.Size;
  747. end;
  748. procedure TANSIBackgroundConsole.CursorOn;
  749. begin
  750. Owner^.ShowCursor;
  751. end;
  752. procedure TANSIBackgroundConsole.CursorOff;
  753. begin
  754. Owner^.HideCursor;
  755. end;
  756. procedure TANSIBackgroundConsole.ClrScr;
  757. var X,Y: word;
  758. Pos: longint;
  759. begin
  760. GotoXY(1,1);
  761. if Owner<>nil then
  762. for X:=0 to MaxViewWidth-1 do
  763. for Y:=0 to Size.Y-1 do
  764. begin
  765. Pos:=X+Y*MaxViewWidth;
  766. Owner^.Buffer[Pos]:=32+256*word(TextAttr);
  767. end;
  768. end;
  769. procedure TANSIBackgroundConsole.ClrEol;
  770. var X,Y: word;
  771. Pos: longint;
  772. begin
  773. if Owner<>nil then
  774. begin
  775. Y:=CurPos.Y;
  776. for X:=CurPos.X to MaxViewWidth-1 do
  777. begin
  778. Pos:=X+Y*MaxViewWidth;
  779. Owner^.Buffer[Pos]:=32+256*word(TextAttr);
  780. end;
  781. end;
  782. end;
  783. procedure TANSIBackgroundConsole.WriteChar(C: char);
  784. var Pos: longint;
  785. begin
  786. case C of
  787. #8 : begin
  788. CursorBack(1);
  789. Pos:=(CurPos.Y-1)*MaxViewWidth+(WhereX-1);
  790. Owner^.Buffer[Pos]:=ord(' ')+256*word(TextAttr);
  791. end;
  792. #0..#7,#9,
  793. #11..#12,
  794. #14..#31,
  795. #32..#255
  796. : begin
  797. Pos:=(CurPos.Y-1)*MaxViewWidth+(WhereX-1);
  798. Owner^.Buffer[Pos]:=ord(C)+256*word(TextAttr);
  799. GotoXY(WhereX+1,WhereY);
  800. end;
  801. #10 :
  802. GotoXY(WhereX,WhereY+1);
  803. #13 :
  804. GotoXY(1,WhereY);
  805. else {$IFDEF DEBUG}RunError(241){$ENDIF};
  806. end;
  807. end;
  808. procedure TANSIBackgroundConsole.DelLine(LineCount: integer);
  809. begin
  810. Abstract;
  811. end;
  812. procedure TANSIBackgroundConsole.InsLine(LineCount: integer);
  813. begin
  814. Abstract;
  815. end;
  816. procedure TANSIBackgroundConsole.UpdateCursor;
  817. begin
  818. if Owner<>nil then
  819. if Owner^.LockCount=0 then Owner^.SetCursor(WhereX-1,WhereY-1);
  820. end;
  821. procedure TANSIBackgroundConsole.GotoXY(X,Y: integer);
  822. var W: word;
  823. begin
  824. if Owner<>nil then
  825. while Y>MaxVideoLine do
  826. begin
  827. Move(Owner^.Buffer[MaxViewWidth],Owner^.Buffer,SizeOf(Owner^.Buffer)-(MaxViewWidth*2));
  828. W:=(MaxViewWidth*MaxVideoLine)-1-(MaxViewWidth);
  829. FillChar(Owner^.Buffer[W],MaxViewWidth*2,0);
  830. Dec(Y);
  831. end;
  832. inherited GotoXY(X,Y);
  833. end;
  834. constructor TANSIBackground.Init(var Bounds: TRect);
  835. begin
  836. inherited Init(Bounds,' ');
  837. LockCount:=0;
  838. GrowMode:=gfGrowHiX or gfGrowHiY;
  839. New(Console, Init(@Self));
  840. Console^.Size.X:=132; Console^.Size.Y:=50;
  841. Console^.ClrScr;
  842. Console^.CursorOn;
  843. end;
  844. function TANSIBackground.LoadFile(const FileName: string): boolean;
  845. var S: PBufStream;
  846. OK: boolean;
  847. B: array[0..1023] of char;
  848. I,FragSize: integer;
  849. begin
  850. {$I-}
  851. New(S, Init(FileName, stOpenRead, 4096));
  852. OK:=Assigned(S);
  853. while OK and (S^.Status=stOK) do
  854. begin
  855. FragSize:=Min(Sizeof(B),S^.GetSize-S^.GetPos);
  856. if FragSize=0 then Break;
  857. S^.Read(B,FragSize);
  858. OK:=(S^.Status=stOK);
  859. if OK then
  860. for I:=0 to FragSize-1 do
  861. self.Write(B[I]);
  862. end;
  863. if Assigned(S) then Dispose(S, Done); S:=nil;
  864. {$I+}
  865. LoadFile:=OK;
  866. end;
  867. procedure TANSIBackground.Draw;
  868. var I: integer;
  869. Pos: longint;
  870. X,Y: integer;
  871. begin
  872. if LockCount<>0 then Exit;
  873. for I:=0 to Size.Y-1 do
  874. begin
  875. Pos:=I*MaxViewWidth;
  876. WriteLine(0,I,Size.X,1,Buffer[Pos]);
  877. end;
  878. if Console=nil then Exit;
  879. X:=Console^.WhereX; Y:=Console^.WhereY;
  880. if (X<0) or (Y<0) or (X>Size.X-1) or (Y>Size.X-1)
  881. then HideCursor
  882. else begin
  883. ShowCursor;
  884. SetCursor(X-1,Y-1);
  885. end;
  886. end;
  887. procedure TANSIBackground.Write(S: string);
  888. begin
  889. Console^.Write(S);
  890. DrawView;
  891. end;
  892. procedure TANSIBackground.WriteLn(S: string);
  893. begin
  894. Console^.WriteLn(S);
  895. DrawView;
  896. end;
  897. procedure TANSIBackground.Lock;
  898. begin
  899. Inc(LockCount);
  900. end;
  901. procedure TANSIBackground.UnLock;
  902. begin
  903. Dec(LockCount);
  904. if LockCount=0 then DrawView;
  905. end;
  906. procedure TANSIBackground.ChangeBounds(var Bounds: TRect);
  907. begin
  908. inherited ChangeBounds(Bounds);
  909. { Console^.Size.X:=Size.X; Console^.Size.Y:=Size.Y;}
  910. end;
  911. procedure TANSIBackground.HandleEvent(var Event: TEvent);
  912. begin
  913. inherited HandleEvent(Event);
  914. { if Event.What=evKeyDown then
  915. begin
  916. if VScrollBar<>nil then VScrollBar^.HandleEvent(Event);
  917. if HScrollBar<>nil then HScrollBar^.HandleEvent(Event);
  918. end;}
  919. end;
  920. destructor TANSIBackground.Done;
  921. begin
  922. Dispose(Console, Done);
  923. inherited Done;
  924. end;
  925. END.
  926. {
  927. $Log $
  928. }