crt.pp 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993-98 by Michael Van Canneyt and Peter Vreman,
  5. members of the Free Pascal development team.
  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. unit Crt;
  13. Interface
  14. Const
  15. { Controlling consts }
  16. Flushing=false; {if true then don't buffer output}
  17. { CRT modes }
  18. BW40 = 0; { 40x25 B/W on Color Adapter }
  19. CO40 = 1; { 40x25 Color on Color Adapter }
  20. BW80 = 2; { 80x25 B/W on Color Adapter }
  21. CO80 = 3; { 80x25 Color on Color Adapter }
  22. Mono = 7; { 80x25 on Monochrome Adapter }
  23. Font8x8 = 256; { Add-in for ROM font }
  24. { Mode constants for 3.0 compatibility }
  25. C40 = CO40;
  26. C80 = CO80;
  27. { Foreground and background color constants }
  28. Black = 0;
  29. Blue = 1;
  30. Green = 2;
  31. Cyan = 3;
  32. Red = 4;
  33. Magenta = 5;
  34. Brown = 6;
  35. LightGray = 7;
  36. { Foreground color constants }
  37. DarkGray = 8;
  38. LightBlue = 9;
  39. LightGreen = 10;
  40. LightCyan = 11;
  41. LightRed = 12;
  42. LightMagenta = 13;
  43. Yellow = 14;
  44. White = 15;
  45. { Add-in for blinking }
  46. Blink = 128;
  47. {Other Defaults}
  48. TextAttr : Byte = $07;
  49. LastMode : Word = 3;
  50. WindMin : Word = $0;
  51. WindMax : Word = $184f;
  52. var
  53. CheckBreak,
  54. CheckEOF,
  55. CheckSnow,
  56. DirectVideo: Boolean;
  57. Const
  58. ScreenHeight : longint=25;
  59. ScreenWidth : longint=80;
  60. ConsoleMaxX=1024;
  61. ConsoleMaxY=1024;
  62. Type
  63. TCharAttr=packed record
  64. ch : char;
  65. attr : byte;
  66. end;
  67. TConsoleBuf=Array[0..ConsoleMaxX*ConsoleMaxY-1] of TCharAttr;
  68. PConsoleBuf=^TConsoleBuf;
  69. var
  70. ConsoleBuf : PConsoleBuf;
  71. Procedure AssignCrt(Var F: Text);
  72. Function KeyPressed: Boolean;
  73. Function ReadKey: Char;
  74. Procedure TextMode(Mode: Integer);
  75. Procedure Window(X1, Y1, X2, Y2: Byte);
  76. Procedure GoToXy(X: Byte; Y: Byte);
  77. Function WhereX: Byte;
  78. Function WhereY: Byte;
  79. Procedure ClrScr;
  80. Procedure ClrEol;
  81. Procedure InsLine;
  82. Procedure DelLine;
  83. Procedure TextColor(Color: Byte);
  84. Procedure TextBackground(Color: Byte);
  85. Procedure LowVideo;
  86. Procedure HighVideo;
  87. Procedure NormVideo;
  88. Procedure Delay(DTime: Word);
  89. Procedure Sound(Hz: Word);
  90. Procedure NoSound;
  91. { extra }
  92. procedure CursorBig;
  93. procedure CursorOn;
  94. procedure CursorOff;
  95. Implementation
  96. uses Linux;
  97. {
  98. The definitions of TextRec and FileRec are in separate files.
  99. }
  100. {$i textrec.inc}
  101. Const
  102. OldTextAttr : byte = $07;
  103. Var
  104. CurrX,CurrY : Byte;
  105. ExitSave : Pointer;
  106. Redir : boolean; { is the output being redirected (not a TTY) }
  107. {*****************************************************************************
  108. Some Handy Functions Not in the System.PP
  109. *****************************************************************************}
  110. Function Str(l:longint):string;
  111. {
  112. Return a String of the longint
  113. }
  114. var
  115. hstr : string[32];
  116. begin
  117. System.Str(l,hstr);
  118. Str:=hstr;
  119. end;
  120. Function Max(l1,l2:longint):longint;
  121. {
  122. Return the maximum of l1 and l2
  123. }
  124. begin
  125. if l1>l2 then
  126. Max:=l1
  127. else
  128. Max:=l2;
  129. end;
  130. Function Min(l1,l2:longint):longint;
  131. {
  132. Return the minimum of l1 and l2
  133. }
  134. begin
  135. if l1<l2 then
  136. Min:=l1
  137. else
  138. Min:=l2;
  139. end;
  140. {*****************************************************************************
  141. Optimal AnsiString Conversion Routines
  142. *****************************************************************************}
  143. Function XY2Ansi(x,y,ox,oy:longint):String;
  144. {
  145. Returns a string with the escape sequences to go to X,Y on the screen
  146. }
  147. Begin
  148. if y=oy then
  149. begin
  150. if x=ox then
  151. begin
  152. XY2Ansi:='';
  153. exit;
  154. end;
  155. if x=1 then
  156. begin
  157. XY2Ansi:=#13;
  158. exit;
  159. end;
  160. if x>ox then
  161. begin
  162. XY2Ansi:=#27'['+Str(x-ox)+'C';
  163. exit;
  164. end
  165. else
  166. begin
  167. XY2Ansi:=#27'['+Str(ox-x)+'D';
  168. exit;
  169. end;
  170. end;
  171. if x=ox then
  172. begin
  173. if y>oy then
  174. begin
  175. XY2Ansi:=#27'['+Str(y-oy)+'B';
  176. exit;
  177. end
  178. else
  179. begin
  180. XY2Ansi:=#27'['+Str(oy-y)+'A';
  181. exit;
  182. end;
  183. end;
  184. if (x=1) and (oy+1=y) then
  185. XY2Ansi:=#13#10
  186. else
  187. XY2Ansi:=#27'['+Str(y)+';'+Str(x)+'H';
  188. End;
  189. const
  190. AnsiTbl : string[8]='04261537';
  191. Function Attr2Ansi(Attr,OAttr:longint):string;
  192. {
  193. Convert Attr to an Ansi String, the Optimal code is calculate
  194. with use of the old OAttr
  195. }
  196. var
  197. hstr : string[16];
  198. OFg,OBg,Fg,Bg : longint;
  199. procedure AddSep(ch:char);
  200. begin
  201. if length(hstr)>0 then
  202. hstr:=hstr+';';
  203. hstr:=hstr+ch;
  204. end;
  205. begin
  206. if Attr=OAttr then
  207. begin
  208. Attr2Ansi:='';
  209. exit;
  210. end;
  211. Hstr:='';
  212. Fg:=Attr and $f;
  213. Bg:=Attr shr 4;
  214. OFg:=Attr and $f;
  215. OBg:=Attr shr 4;
  216. if (OFg<>7) or (Fg=7) or ((OFg>7) and (Fg<8)) or ((OBg>7) and (Bg<8)) then
  217. begin
  218. hstr:='0';
  219. OFg:=7;
  220. OBg:=0;
  221. end;
  222. if (Fg>7) and (OFg<8) then
  223. begin
  224. AddSep('1');
  225. OFg:=OFg or 8;
  226. end;
  227. if (Bg and 8)<>(OBg and 8) then
  228. begin
  229. AddSep('5');
  230. OBg:=OBg or 8;
  231. end;
  232. if (Fg<>OFg) then
  233. begin
  234. AddSep('3');
  235. hstr:=hstr+AnsiTbl[(Fg and 7)+1];
  236. end;
  237. if (Bg<>OBg) then
  238. begin
  239. AddSep('4');
  240. hstr:=hstr+AnsiTbl[(Bg and 7)+1];
  241. end;
  242. if hstr='0' then
  243. hstr:='';
  244. Attr2Ansi:=#27'['+hstr+'m';
  245. end;
  246. Function Ansi2Attr(Const HStr:String;oattr:longint):longint;
  247. {
  248. Convert an Escape sequence to an attribute value, uses Oattr as the last
  249. color written
  250. }
  251. var
  252. i,j : longint;
  253. begin
  254. i:=2;
  255. if (Length(HStr)<3) or (Hstr[1]<>#27) or (Hstr[2]<>'[') then
  256. i:=255;
  257. while (i<length(Hstr)) do
  258. begin
  259. inc(i);
  260. case Hstr[i] of
  261. '0' : OAttr:=7;
  262. '1' : OAttr:=OAttr or $8;
  263. '5' : OAttr:=OAttr or $80;
  264. '3' : begin
  265. inc(i);
  266. j:=pos(Hstr[i],AnsiTbl);
  267. if j>0 then
  268. OAttr:=(OAttr and $f8) or (j-1);
  269. end;
  270. '4' : begin
  271. inc(i);
  272. j:=pos(Hstr[i],AnsiTbl);
  273. if j>0 then
  274. OAttr:=(OAttr and $8f) or ((j-1) shl 4);
  275. end;
  276. 'm' : i:=length(HStr);
  277. end;
  278. end;
  279. Ansi2Attr:=OAttr;
  280. end;
  281. {*****************************************************************************
  282. Buffered StdIn/StdOut IO
  283. *****************************************************************************}
  284. const
  285. ttyIn=0; {Handles for stdin/stdout}
  286. ttyOut=1;
  287. ttyFlush:boolean=true;
  288. {Buffered Input/Output}
  289. InSize=256;
  290. OutSize=1024;
  291. var
  292. InBuf : array[0..InSize-1] of char;
  293. InCnt,
  294. InHead,
  295. InTail : longint;
  296. OutBuf : array[0..OutSize-1] of char;
  297. OutCnt : longint;
  298. {Flush Output Buffer}
  299. procedure ttyFlushOutput;
  300. begin
  301. if OutCnt>0 then
  302. begin
  303. fdWrite(ttyOut,OutBuf,OutCnt);
  304. OutCnt:=0;
  305. end;
  306. end;
  307. Function ttySetFlush(b:boolean):boolean;
  308. begin
  309. ttySetFlush:=ttyFlush;
  310. ttyFlush:=b;
  311. if ttyFlush then
  312. ttyFlushOutput;
  313. end;
  314. {Send Char to Remote}
  315. Procedure ttySendChar(c:char);
  316. Begin
  317. if OutCnt<OutSize then
  318. begin
  319. OutBuf[OutCnt]:=c;
  320. inc(OutCnt);
  321. end;
  322. {Full ?}
  323. if (OutCnt>=OutSize) then
  324. ttyFlushOutput;
  325. End;
  326. {Send String to Remote}
  327. procedure ttySendStr(const hstr:string);
  328. var
  329. i : longint;
  330. begin
  331. for i:=1to length(hstr) do
  332. ttySendChar(hstr[i]);
  333. if ttyFlush then
  334. ttyFlushOutput;
  335. end;
  336. {Get Char from Remote}
  337. function ttyRecvChar:char;
  338. var
  339. Readed,i : longint;
  340. begin
  341. {Buffer Empty? Yes, Input from StdIn}
  342. if (InHead=InTail) then
  343. begin
  344. {Calc Amount of Chars to Read}
  345. i:=InSize-InHead;
  346. if InTail>InHead then
  347. i:=InTail-InHead;
  348. {Read}
  349. Readed:=fdRead(TTYIn,InBuf[InHead],i);
  350. {Increase Counters}
  351. inc(InCnt,Readed);
  352. inc(InHead,Readed);
  353. {Wrap if End has Reached}
  354. if InHead>=InSize then
  355. InHead:=0;
  356. end;
  357. {Check Buffer}
  358. if (InCnt=0) then
  359. ttyRecvChar:=#0
  360. else
  361. begin
  362. ttyRecvChar:=InBuf[InTail];
  363. dec(InCnt);
  364. inc(InTail);
  365. if InTail>=InSize then
  366. InTail:=0;
  367. end;
  368. end;
  369. {*****************************************************************************
  370. Screen Routines not Window Depended
  371. *****************************************************************************}
  372. procedure ttyGotoXY(x,y:longint);
  373. {
  374. Goto XY on the Screen, if a value is 0 the goto the current
  375. postion of that value and always recalc the ansicode for it
  376. }
  377. begin
  378. if x=0 then
  379. begin
  380. x:=CurrX;
  381. CurrX:=$ff;
  382. end;
  383. if y=0 then
  384. begin
  385. y:=CurrY;
  386. CurrY:=$ff;
  387. end;
  388. if Redir then
  389. begin
  390. if longint(y)-longint(CurrY)=1 then
  391. ttySendStr(#10);
  392. end
  393. else
  394. ttySendStr(XY2Ansi(x,y,CurrX,CurrY));
  395. CurrX:=x;
  396. CurrY:=y;
  397. end;
  398. procedure ttyColor(a:longint);
  399. {
  400. Set Attribute to A, only output if not the last attribute is set
  401. }
  402. begin
  403. if a<>TextAttr then
  404. begin
  405. if not Redir then
  406. ttySendStr(Attr2Ansi(a,TextAttr));
  407. TextAttr:=a;
  408. OldTextAttr:=a;
  409. end;
  410. end;
  411. procedure ttyWrite(const s:string);
  412. {
  413. Write a string to the output, memory copy and Current X&Y are also updated
  414. }
  415. var
  416. idx,i : longint;
  417. begin
  418. ttySendStr(s);
  419. {Update MemCopy}
  420. idx:=(CurrY-1)*ScreenWidth-1;
  421. for i:=1to length(s) do
  422. if s[i]=#8 then
  423. begin
  424. if CurrX>1 then
  425. dec(CurrX);
  426. end
  427. else
  428. begin
  429. ConsoleBuf^[idx+CurrX].ch:=s[i];
  430. ConsoleBuf^[idx+CurrX].attr:=TextAttr;
  431. inc(CurrX);
  432. if CurrX>ScreenWidth then
  433. CurrX:=ScreenWidth;
  434. end;
  435. end;
  436. Function WinMinX: Longint;
  437. {
  438. Current Minimum X coordinate
  439. }
  440. Begin
  441. WinMinX:=(WindMin and $ff)+1;
  442. End;
  443. Function WinMinY: Longint;
  444. {
  445. Current Minimum Y Coordinate
  446. }
  447. Begin
  448. WinMinY:=(WindMin shr 8)+1;
  449. End;
  450. Function WinMaxX: Longint;
  451. {
  452. Current Maximum X coordinate
  453. }
  454. Begin
  455. WinMaxX:=(WindMax and $ff)+1;
  456. End;
  457. Function WinMaxY: Longint;
  458. {
  459. Current Maximum Y coordinate;
  460. }
  461. Begin
  462. WinMaxY:=(WindMax shr 8) + 1;
  463. End;
  464. Function FullWin:boolean;
  465. {
  466. Full Screen 80x25? Window(1,1,80,25) is used, allows faster routines
  467. }
  468. begin
  469. FullWin:=(WinMinX=1) and (WinMinY=1) and
  470. (WinMaxX=ScreenWidth) and (WinMaxY=ScreenHeight);
  471. end;
  472. procedure LineWrite(const temp:String);
  473. {
  474. Write a Line to the screen, doesn't write on 80,25 under Dos
  475. the Current CurrX is set to WinMax. NO MEMORY UPDATE!
  476. }
  477. begin
  478. CurrX:=WinMaxX+1;
  479. if (CurrX>=ScreenWidth) then
  480. CurrX:=WinMaxX;
  481. ttySendStr(Temp);
  482. end;
  483. procedure DoEmptyLine(y,xl,xh:longint);
  484. {
  485. Write an Empty line at Row Y from Col Xl to XH, Memory is also updated
  486. }
  487. var
  488. len : longint;
  489. begin
  490. ttyGotoXY(xl,y);
  491. len:=xh-xl+1;
  492. LineWrite(Space(len));
  493. FillWord(ConsoleBuf^[(y-1)*ScreenWidth+xl-1],len,(TextAttr shl 8)+ord(' '));
  494. end;
  495. procedure DoScrollLine(y1,y2,xl,xh:longint);
  496. {
  497. Move Line y1 to y2, use only columns Xl-Xh, Memory is updated also
  498. }
  499. var
  500. Temp : string;
  501. idx,
  502. OldAttr,
  503. x,attr : longint;
  504. begin
  505. ttyGotoXY(xl,y2);
  506. { precalc ConsoleBuf[] y-offset }
  507. idx:=(y1-1)*ScreenWidth-1;
  508. { update screen }
  509. OldAttr:=$ff;
  510. Temp:='';
  511. For x:=xl To xh Do
  512. Begin
  513. attr:=ConsoleBuf^[idx+x].attr;
  514. if (attr<>OldAttr) and (not Redir) then
  515. begin
  516. temp:=temp+Attr2Ansi(Attr,OldAttr);
  517. OldAttr:=Attr;
  518. end;
  519. Temp:=Temp+ConsoleBuf^[idx+x].ch;
  520. if (x=xh) or (length(Temp)>240) then
  521. begin
  522. LineWrite(Temp);
  523. Temp:='';
  524. end;
  525. End;
  526. {Update memory copy}
  527. Move(ConsoleBuf^[(y1-1)*ScreenWidth+xl-1],ConsoleBuf^[(y2-1)*ScreenWidth+xl-1],(xh-xl+1)*2);
  528. end;
  529. Procedure TextColor(Color: Byte);
  530. {
  531. Switch foregroundcolor
  532. }
  533. Begin
  534. ttyColor((Color and $8f) or (TextAttr and $70));
  535. End;
  536. Procedure TextBackground(Color: Byte);
  537. {
  538. Switch backgroundcolor
  539. }
  540. Begin
  541. ttyColor((Color shl 4) or (TextAttr and $0f));
  542. End;
  543. Procedure HighVideo;
  544. {
  545. Set highlighted output.
  546. }
  547. Begin
  548. TextColor(TextAttr Or $08);
  549. End;
  550. Procedure LowVideo;
  551. {
  552. Set normal output
  553. }
  554. Begin
  555. TextColor(TextAttr And $77);
  556. End;
  557. Procedure NormVideo;
  558. {
  559. Set normal back and foregroundcolors.
  560. }
  561. Begin
  562. TextColor(7);
  563. TextBackGround(0);
  564. End;
  565. Procedure GotoXy(X: Byte; Y: Byte);
  566. {
  567. Go to coordinates X,Y in the current window.
  568. }
  569. Begin
  570. If (X>0) and (X<=WinMaxX- WinMinX+1) and
  571. (Y>0) and (Y<=WinMaxY-WinMinY+1) Then
  572. Begin
  573. Inc(X,WinMinX-1);
  574. Inc(Y,WinMinY-1);
  575. ttyGotoXY(x,y);
  576. End;
  577. End;
  578. Procedure Window(X1, Y1, X2, Y2: Byte);
  579. {
  580. Set screen window to the specified coordinates.
  581. }
  582. Begin
  583. if (X1>X2) or (X2>ScreenWidth) or
  584. (Y1>Y2) or (Y2>ScreenHeight) then
  585. exit;
  586. WindMin:=((Y1-1) Shl 8)+(X1-1);
  587. WindMax:=((Y2-1) Shl 8)+(X2-1);
  588. GoToXY(1,1);
  589. End;
  590. Procedure ClrScr;
  591. {
  592. Clear the current window, and set the cursor on x1,y1
  593. }
  594. Var
  595. CY,i : Longint;
  596. oldflush : boolean;
  597. Begin
  598. { See if color has changed }
  599. if OldTextAttr<>TextAttr then
  600. begin
  601. i:=TextAttr;
  602. TextAttr:=OldTextAttr;
  603. ttyColor(i);
  604. end;
  605. oldflush:=ttySetFlush(Flushing);
  606. if FullWin then
  607. begin
  608. if not Redir then
  609. ttySendStr(#27'[H'#27'[2J');
  610. CurrX:=1;
  611. CurrY:=1;
  612. FillWord(ConsoleBuf^,ScreenWidth*ScreenHeight,(TextAttr shl 8)+ord(' '));
  613. end
  614. else
  615. begin
  616. For Cy:=WinMinY To WinMaxY Do
  617. DoEmptyLine(Cy,WinMinX,WinMaxX);
  618. GoToXY(1,1);
  619. end;
  620. ttySetFlush(oldflush);
  621. End;
  622. Procedure ClrEol;
  623. {
  624. Clear from current position to end of line.
  625. }
  626. var
  627. len,i : longint;
  628. IsLastLine : boolean;
  629. Begin
  630. { See if color has changed }
  631. if OldTextAttr<>TextAttr then
  632. begin
  633. i:=TextAttr;
  634. TextAttr:=OldTextAttr;
  635. ttyColor(i);
  636. end;
  637. if FullWin or (WinMaxX = ScreenWidth) then
  638. begin
  639. if not Redir then
  640. ttySendStr(#27'[K');
  641. end
  642. else
  643. begin
  644. { Tweak windmax so no scrolling happends }
  645. len:=WinMaxX-CurrX+1;
  646. IsLastLine:=false;
  647. if CurrY=WinMaxY then
  648. begin
  649. inc(WindMax,$0203);
  650. IsLastLine:=true;
  651. end;
  652. ttySendStr(Space(len));
  653. if IsLastLine then
  654. dec(WindMax,$0203);
  655. ttyGotoXY(0,0);
  656. end;
  657. End;
  658. Function WhereX: Byte;
  659. {
  660. Return current X-position of cursor.
  661. }
  662. Begin
  663. WhereX:=CurrX-WinMinX+1;
  664. End;
  665. Function WhereY: Byte;
  666. {
  667. Return current Y-position of cursor.
  668. }
  669. Begin
  670. WhereY:=CurrY-WinMinY+1;
  671. End;
  672. Procedure ScrollScrnRegionUp(xl,yl,xh,yh, count: longint);
  673. {
  674. Scroll the indicated region count lines up. The empty lines are filled
  675. with blanks in the current color. The screen position is restored
  676. afterwards.
  677. }
  678. Var
  679. y,oldx,oldy : byte;
  680. oldflush : boolean;
  681. Begin
  682. oldflush:=ttySetFlush(Flushing);
  683. oldx:=CurrX;
  684. oldy:=CurrY;
  685. {Scroll}
  686. For y:=yl to yh-count do
  687. DoScrollLine(y+count,y,xl,xh);
  688. {Restore TextAttr}
  689. ttySendStr(Attr2Ansi(TextAttr,$ff));
  690. {Fill the rest with empty lines}
  691. for y:=yh-count+1 to yh do
  692. DoEmptyLine(y,xl,xh);
  693. {Restore current position}
  694. ttyGotoXY(OldX,OldY);
  695. ttySetFlush(oldflush);
  696. End;
  697. Procedure ScrollScrnRegionDown(xl,yl,xh,yh, count: longint);
  698. {
  699. Scroll the indicated region count lines down. The empty lines are filled
  700. with blanks in the current color. The screen position is restored
  701. afterwards.
  702. }
  703. Var
  704. y,oldx,oldy : byte;
  705. oldflush : boolean;
  706. Begin
  707. oldflush:=ttySetFlush(Flushing);
  708. oldx:=CurrX;
  709. oldy:=CurrY;
  710. {Scroll}
  711. for y:=yh downto yl+count do
  712. DoScrollLine(y-count,y,xl,xh);
  713. {Restore TextAttr}
  714. ttySendStr(Attr2Ansi(TextAttr,$ff));
  715. {Fill the rest with empty lines}
  716. for y:=yl to yl+count-1 do
  717. DoEmptyLine(y,xl,xh);
  718. {Restore current position}
  719. ttyGotoXY(OldX,OldY);
  720. ttySetFlush(oldflush);
  721. End;
  722. {*************************************************************************
  723. KeyBoard
  724. *************************************************************************}
  725. Const
  726. KeyBufferSize = 20;
  727. var
  728. KeyBuffer : Array[0..KeyBufferSize-1] of Char;
  729. KeyPut,
  730. KeySend : longint;
  731. Procedure PushKey(Ch:char);
  732. Var
  733. Tmp : Longint;
  734. Begin
  735. Tmp:=KeyPut;
  736. Inc(KeyPut);
  737. If KeyPut>=KeyBufferSize Then
  738. KeyPut:=0;
  739. If KeyPut<>KeySend Then
  740. KeyBuffer[Tmp]:=Ch
  741. Else
  742. KeyPut:=Tmp;
  743. End;
  744. Function PopKey:char;
  745. Begin
  746. If KeyPut<>KeySend Then
  747. Begin
  748. PopKey:=KeyBuffer[KeySend];
  749. Inc(KeySend);
  750. If KeySend>=KeyBufferSize Then
  751. KeySend:=0;
  752. End
  753. Else
  754. PopKey:=#0;
  755. End;
  756. Procedure PushExt(b:byte);
  757. begin
  758. PushKey(#0);
  759. PushKey(chr(b));
  760. end;
  761. const
  762. AltKeyStr : string[38]='qwertyuiopasdfghjklzxcvbnm1234567890-=';
  763. AltCodeStr : string[38]=#016#017#018#019#020#021#022#023#024#025#030#031#032#033#034#035#036#037#038+
  764. #044#045#046#047#048#049#050#120#121#122#123#124#125#126#127#128#129#130#131;
  765. Function FAltKey(ch:char):byte;
  766. var
  767. Idx : longint;
  768. Begin
  769. Idx:=Pos(ch,AltKeyStr);
  770. if Idx>0 then
  771. FAltKey:=byte(AltCodeStr[Idx])
  772. else
  773. FAltKey:=0;
  774. End;
  775. Function KeyPressed:Boolean;
  776. var
  777. fdsin : fdSet;
  778. Begin
  779. if (KeySend<>KeyPut) or (InCnt>0) then
  780. KeyPressed:=true
  781. else
  782. begin
  783. FD_Zero(fdsin);
  784. fd_Set(TTYin,fdsin);
  785. Keypressed:=(Select(TTYIn+1,@fdsin,nil,nil,0)>0);
  786. end;
  787. End;
  788. Function ReadKey:char;
  789. Var
  790. ch : char;
  791. OldState,
  792. State : longint;
  793. Begin
  794. {Check Buffer first}
  795. if KeySend<>KeyPut then
  796. begin
  797. ReadKey:=PopKey;
  798. exit;
  799. end;
  800. {Wait for Key}
  801. repeat
  802. until keypressed;
  803. ch:=ttyRecvChar;
  804. {Esc Found ?}
  805. CASE ch OF
  806. #27: begin
  807. State:=1;
  808. Delay(10);
  809. while (State<>0) and (KeyPressed) do
  810. begin
  811. ch:=ttyRecvChar;
  812. OldState:=State;
  813. State:=0;
  814. case OldState of
  815. 1 : begin {Esc}
  816. case ch of
  817. 'a'..'z',
  818. '0'..'9',
  819. '-','=' : PushExt(FAltKey(ch));
  820. #10 : PushKey(#10);
  821. '[' : State:=2;
  822. else
  823. begin
  824. PushKey(ch);
  825. PushKey(#27);
  826. end;
  827. end;
  828. end;
  829. 2 : begin {Esc[}
  830. case ch of
  831. '[' : State:=3;
  832. 'A' : PushExt(72);
  833. 'B' : PushExt(80);
  834. 'C' : PushExt(77);
  835. 'D' : PushExt(75);
  836. {$IFDEF FREEBSD}
  837. {'E' - Center key, not handled in DOS TP7}
  838. 'F' : PushExt(79); {End}
  839. 'G': PushExt(81); {PageDown}
  840. {$ELSE}
  841. 'G' : PushKey('5'); {Center key, Linux}
  842. {$ENDIF}
  843. 'H' : PushExt(71);
  844. {$IFDEF FREEBSD}
  845. 'I' : PushExt(73); {PageUp}
  846. {$ENDIF}
  847. 'K' : PushExt(79);
  848. {$IFDEF FREEBSD}
  849. 'L' : StoExt(82); {Insert - Deekoo}
  850. 'M' : StoExt(59); {F1-F10 - Deekoo}
  851. 'N' : StoExt(60); {F2}
  852. 'O' : StoExt(61); {F3}
  853. 'P' : StoExt(62); {F4}
  854. 'Q' : StoExt(63); {F5}
  855. 'R' : StoExt(64); {F6}
  856. 'S' : StoExt(65); {F7}
  857. 'T' : StoExt(66); {F8}
  858. 'U' : StoExt(67); {F9}
  859. 'V' : StoExt(68); {F10}
  860. {Not sure if TP/BP handles F11 and F12 like this normally;
  861. In pcemu, a TP7 executable handles 'em this way, though.}
  862. 'W' : StoExt(133); {F11}
  863. 'X' : StoExt(134); {F12}
  864. 'Y' : StoExt(84); {Shift-F1}
  865. 'Z' : StoExt(85); {Shift-F2}
  866. 'a' : StoExt(86); {Shift-F3}
  867. 'b' : StoExt(87); {Shift-F4}
  868. 'c' : StoExt(88); {Shift-F5}
  869. 'd' : StoExt(89); {Shift-F6}
  870. 'e' : StoExt(90); {Shift-F7}
  871. 'f' : StoExt(91); {Shift-F8}
  872. 'g' : StoExt(92); {Shift-F9}
  873. 'h' : StoExt(93); {Shift-F10}
  874. 'i' : StoExt(135); {Shift-F11}
  875. 'j' : StoExt(136); {Shift-F12}
  876. 'k' : StoExt(94); {Ctrl-F1}
  877. 'l' : StoExt(95);
  878. 'm' : StoExt(96);
  879. 'n' : StoExt(97);
  880. 'o' : StoExt(98);
  881. 'p' : StoExt(99);
  882. 'q' : StoExt(100);
  883. 'r' : StoExt(101);
  884. 's' : StoExt(102);
  885. 't' : StoExt(103); {Ctrl-F10}
  886. 'u' : StoExt(137); {Ctrl-F11}
  887. 'v' : StoExt(138); {Ctrl-F12}
  888. {$ENDIF}
  889. '1' : State:=4;
  890. '2' : State:=5;
  891. '3' : State:=6;
  892. '4' : PushExt(79);
  893. '5' : PushExt(73);
  894. '6' : PushExt(81);
  895. else
  896. begin
  897. PushKey(ch);
  898. PushKey('[');
  899. PushKey(#27);
  900. end;
  901. end;
  902. if ch in ['4'..'6'] then
  903. State:=255;
  904. end;
  905. 3 : begin {Esc[[}
  906. case ch of
  907. 'A' : PushExt(59);
  908. 'B' : PushExt(60);
  909. 'C' : PushExt(61);
  910. 'D' : PushExt(62);
  911. 'E' : PushExt(63);
  912. end;
  913. end;
  914. 4 : begin {Esc[1}
  915. case ch of
  916. '~' : PushExt(71);
  917. '7' : PushExt(64);
  918. '8' : PushExt(65);
  919. '9' : PushExt(66);
  920. end;
  921. if (Ch<>'~') then
  922. State:=255;
  923. end;
  924. 5 : begin {Esc[2}
  925. case ch of
  926. '~' : PushExt(82);
  927. '0' : pushExt(67);
  928. '1' : PushExt(68);
  929. '3' : PushExt(133); {F11}
  930. {Esc[23~ is also shift-F1,shift-F11}
  931. '4' : PushExt(134); {F12}
  932. {Esc[24~ is also shift-F2,shift-F12}
  933. '5' : PushExt(86); {Shift-F3}
  934. '6' : PushExt(87); {Shift-F4}
  935. '8' : PushExt(88); {Shift-F5}
  936. '9' : PushExt(89); {Shift-F6}
  937. end;
  938. if (Ch<>'~') then
  939. State:=255;
  940. end;
  941. 6 : begin {Esc[3}
  942. case ch of
  943. '~' : PushExt(83); {Del}
  944. '1' : PushExt(90); {Shift-F7}
  945. '2' : PushExt(91); {Shift-F8}
  946. '3' : PushExt(92); {Shift-F9}
  947. '4' : PushExt(93); {Shift-F10}
  948. end;
  949. if (Ch<>'~') then
  950. State:=255;
  951. end;
  952. 255 : ;
  953. end;
  954. if State<>0 then
  955. Delay(10);
  956. end;
  957. if State=1 then
  958. PushKey(ch);
  959. end;
  960. #127: PushKey(#8);
  961. else PushKey(ch);
  962. End;
  963. ReadKey:=PopKey;
  964. End;
  965. Procedure Delay(DTime: Word);
  966. {
  967. Wait for DTime milliseconds.
  968. }
  969. Begin
  970. Select(0,nil,nil,nil,DTime);
  971. End;
  972. {****************************************************************************
  973. Write(ln)/Read(ln) support
  974. ****************************************************************************}
  975. procedure DoLn;
  976. begin
  977. if CurrY=WinMaxY then
  978. begin
  979. if FullWin then
  980. begin
  981. ttySendStr(#10#13);
  982. CurrX:=WinMinX;
  983. CurrY:=WinMaxY;
  984. end
  985. else
  986. begin
  987. ScrollScrnRegionUp(WinMinX,WinMinY,WinMaxX,WinMaxY,1);
  988. ttyGotoXY(WinMinX,WinMaxY);
  989. end;
  990. end
  991. else
  992. ttyGotoXY(WinMinX,CurrY+1);
  993. end;
  994. var
  995. Lastansi : boolean;
  996. AnsiCode : string;
  997. Procedure DoWrite(const s:String);
  998. {
  999. Write string to screen, parse most common AnsiCodes
  1000. }
  1001. var
  1002. found,
  1003. OldFlush : boolean;
  1004. x,y,
  1005. i,j,
  1006. SendBytes : longint;
  1007. function AnsiPara(var hstr:string):byte;
  1008. var
  1009. k,j : longint;
  1010. code : word;
  1011. begin
  1012. j:=pos(';',hstr);
  1013. if j=0 then
  1014. j:=length(hstr);
  1015. val(copy(hstr,3,j-3),k,code);
  1016. Delete(hstr,3,j-2);
  1017. if k=0 then
  1018. k:=1;
  1019. AnsiPara:=k;
  1020. end;
  1021. procedure SendText;
  1022. var
  1023. LeftX : longint;
  1024. begin
  1025. while (SendBytes>0) do
  1026. begin
  1027. LeftX:=WinMaxX-CurrX+1;
  1028. if (SendBytes>LeftX) or (CurrX+SendBytes=81) then
  1029. begin
  1030. ttyWrite(Copy(s,i-SendBytes,LeftX));
  1031. dec(SendBytes,LeftX);
  1032. DoLn;
  1033. end
  1034. else
  1035. begin
  1036. ttyWrite(Copy(s,i-SendBytes,SendBytes));
  1037. SendBytes:=0;
  1038. end;
  1039. end;
  1040. end;
  1041. begin
  1042. oldflush:=ttySetFlush(Flushing);
  1043. { Support textattr:= changing }
  1044. if OldTextAttr<>TextAttr then
  1045. begin
  1046. i:=TextAttr;
  1047. TextAttr:=OldTextAttr;
  1048. ttyColor(i);
  1049. end;
  1050. { write the stuff }
  1051. SendBytes:=0;
  1052. i:=1;
  1053. while (i<=length(s)) do
  1054. begin
  1055. if (s[i]=#27) or (LastAnsi) then
  1056. begin
  1057. SendText;
  1058. LastAnsi:=false;
  1059. j:=i;
  1060. found:=false;
  1061. while (j<=length(s)) and (not found) do
  1062. begin
  1063. found:=not (s[j] in [#27,'[','0'..'9',';','?']);
  1064. inc(j);
  1065. end;
  1066. Ansicode:=AnsiCode+Copy(s,i,j-i);
  1067. if found then
  1068. begin
  1069. case AnsiCode[length(AnsiCode)] of
  1070. 'm' : ttyColor(Ansi2Attr(AnsiCode,TextAttr));
  1071. 'H' : begin {No other way :( Coz First Para=Y}
  1072. y:=AnsiPara(AnsiCode);
  1073. x:=AnsiPara(AnsiCode);
  1074. GotoXY(y,x);
  1075. end;
  1076. 'J' : if AnsiPara(AnsiCode)=2 then
  1077. ClrScr;
  1078. 'K' : ClrEol;
  1079. 'A' : GotoXY(CurrX,Max(CurrY-AnsiPara(AnsiCode),WinMinY));
  1080. 'B' : GotoXY(CurrX,Min(CurrY+AnsiPara(AnsiCode),WinMaxY));
  1081. 'C' : GotoXY(Min(CurrX+AnsiPara(AnsiCode),WinMaxX),CurrY);
  1082. 'D' : GotoXY(Max(CurrX-AnsiPara(AnsiCode),WinMinX),CurrY);
  1083. 'h' : ; {Stupid Thedraw [?7h Code}
  1084. else
  1085. found:=false;
  1086. end;
  1087. end
  1088. else
  1089. begin
  1090. LastAnsi:=true;
  1091. found:=true;
  1092. end;
  1093. {Clear AnsiCode?}
  1094. if not LastAnsi then
  1095. AnsiCode:='';
  1096. {Increase Idx or SendBytes}
  1097. if found then
  1098. i:=j-1
  1099. else
  1100. inc(SendBytes);
  1101. end
  1102. else
  1103. begin
  1104. LastAnsi:=false;
  1105. case s[i] of
  1106. #13 : begin {CR}
  1107. SendText;
  1108. ttyGotoXY(WinMinX,CurrY);
  1109. end;
  1110. #10 : begin {NL}
  1111. SendText;
  1112. DoLn;
  1113. end;
  1114. #9 : begin {Tab}
  1115. SendText;
  1116. ttyWrite(Space(9-((CurrX-1) and $08)));
  1117. end;
  1118. #8 : begin {BackSpace}
  1119. SendText;
  1120. ttyWrite(#8);
  1121. end;
  1122. else
  1123. inc(SendBytes);
  1124. end;
  1125. end;
  1126. inc(i);
  1127. end;
  1128. if SendBytes>0 then
  1129. SendText;
  1130. ttySetFlush(oldFLush);
  1131. end;
  1132. Function CrtWrite(Var F: TextRec): Integer;
  1133. {
  1134. Top level write function for CRT
  1135. }
  1136. Var
  1137. Temp : String;
  1138. Begin
  1139. Move(F.BufPTR^[0],Temp[1],F.BufPos);
  1140. setlength(temp,F.BufPos);
  1141. DoWrite(Temp);
  1142. F.BufPos:=0;
  1143. CrtWrite:=0;
  1144. End;
  1145. Function CrtRead(Var F: TextRec): Integer;
  1146. {
  1147. Read from CRT associated file.
  1148. }
  1149. var
  1150. i : longint;
  1151. Begin
  1152. F.BufEnd:=fdRead(F.Handle, F.BufPtr^, F.BufSize);
  1153. { fix #13 only's -> #10 to overcome terminal setting }
  1154. for i:=1to F.BufEnd do
  1155. begin
  1156. if (F.BufPtr^[i-1]=#13) and (F.BufPtr^[i]<>#10) then
  1157. F.BufPtr^[i-1]:=#10;
  1158. end;
  1159. F.BufPos:=F.BufEnd;
  1160. CrtWrite(F);
  1161. CrtRead:=0;
  1162. End;
  1163. Function CrtReturn:Integer;
  1164. Begin
  1165. CrtReturn:=0;
  1166. end;
  1167. Function CrtClose(Var F: TextRec): Integer;
  1168. {
  1169. Close CRT associated file.
  1170. }
  1171. Begin
  1172. F.Mode:=fmClosed;
  1173. CrtClose:=0;
  1174. End;
  1175. Function CrtOpen(Var F: TextRec): Integer;
  1176. {
  1177. Open CRT associated file.
  1178. }
  1179. Begin
  1180. If F.Mode=fmOutput Then
  1181. begin
  1182. TextRec(F).InOutFunc:=@CrtWrite;
  1183. TextRec(F).FlushFunc:=@CrtWrite;
  1184. end
  1185. Else
  1186. begin
  1187. F.Mode:=fmInput;
  1188. TextRec(F).InOutFunc:=@CrtRead;
  1189. TextRec(F).FlushFunc:=@CrtReturn;
  1190. end;
  1191. TextRec(F).CloseFunc:=@CrtClose;
  1192. CrtOpen:=0;
  1193. End;
  1194. procedure AssignCrt(var F: Text);
  1195. {
  1196. Assign a file to the console. All output on file goes to console instead.
  1197. }
  1198. begin
  1199. Assign(F,'');
  1200. TextRec(F).OpenFunc:=@CrtOpen;
  1201. end;
  1202. {******************************************************************************
  1203. High Level Functions
  1204. ******************************************************************************}
  1205. Procedure DelLine;
  1206. {
  1207. Delete current line. Scroll subsequent lines up
  1208. }
  1209. Begin
  1210. ScrollScrnRegionUp(WinMinX, CurrY, WinMaxX, WinMaxY, 1);
  1211. End;
  1212. Procedure InsLine;
  1213. {
  1214. Insert line at current cursor position. Scroll subsequent lines down.
  1215. }
  1216. Begin
  1217. ScrollScrnRegionDown(WinMinX, CurrY, WinMaxX, WinMaxY, 1);
  1218. End;
  1219. Procedure Sound(Hz: Word);
  1220. {
  1221. Does nothing under linux
  1222. }
  1223. begin
  1224. end;
  1225. Procedure NoSound;
  1226. {
  1227. Does nothing under linux
  1228. }
  1229. begin
  1230. end;
  1231. Procedure TextMode(Mode: Integer);
  1232. {
  1233. Only Clears Screen under linux
  1234. }
  1235. begin
  1236. ClrScr;
  1237. end;
  1238. {******************************************************************************
  1239. Extra
  1240. ******************************************************************************}
  1241. procedure CursorBig;
  1242. begin
  1243. ttySendStr(#27'[?17;0;64c');
  1244. end;
  1245. procedure CursorOn;
  1246. begin
  1247. ttySendStr(#27'[?2c');
  1248. end;
  1249. procedure CursorOff;
  1250. begin
  1251. ttySendStr(#27'[?1c');
  1252. end;
  1253. {******************************************************************************
  1254. Initialization
  1255. ******************************************************************************}
  1256. var
  1257. OldIO : TermIos;
  1258. Procedure SetRawMode(b:boolean);
  1259. Var
  1260. Tio : Termios;
  1261. Begin
  1262. if b then
  1263. begin
  1264. TCGetAttr(1,Tio);
  1265. OldIO:=Tio;
  1266. CFMakeRaw(Tio);
  1267. end
  1268. else
  1269. Tio:=OldIO;
  1270. TCSetAttr(1,TCSANOW,Tio);
  1271. End;
  1272. procedure GetXY(var x,y:byte);
  1273. var
  1274. fds : fdSet;
  1275. i,j,
  1276. readed : longint;
  1277. buf : array[0..255] of char;
  1278. s : string[16];
  1279. begin
  1280. x:=0;
  1281. y:=0;
  1282. s:=#27'[6n';
  1283. fdWrite(0,s[1],length(s));
  1284. FD_Zero(fds);
  1285. FD_Set(1,fds);
  1286. if (Select(2,@fds,nil,nil,1000)>0) then
  1287. begin
  1288. readed:=fdRead(1,buf,sizeof(buf));
  1289. i:=0;
  1290. while (i+5<readed) and (buf[i]<>#27) and (buf[i+1]<>'[') do
  1291. inc(i);
  1292. if i+5<readed then
  1293. begin
  1294. s:=space(16);
  1295. move(buf[i+2],s[1],16);
  1296. i:=Pos(';',s);
  1297. if i>0 then
  1298. begin
  1299. Val(Copy(s,1,i-1),y);
  1300. j:=Pos('R',s);
  1301. if j=0 then
  1302. j:=length(s);
  1303. Val(Copy(s,i+1,j-(i+1)),x);
  1304. end;
  1305. end;
  1306. end;
  1307. end;
  1308. Procedure GetConsoleBuf;
  1309. var
  1310. WinInfo : TWinSize;
  1311. begin
  1312. if Assigned(ConsoleBuf) then
  1313. FreeMem(ConsoleBuf,ScreenHeight*ScreenWidth*2);
  1314. if (not Redir) and IOCtl(TextRec(Output).Handle,TIOCGWINSZ,@Wininfo) then
  1315. begin
  1316. ScreenWidth:=Wininfo.ws_col;
  1317. ScreenHeight:=Wininfo.ws_row;
  1318. end
  1319. else
  1320. begin
  1321. ScreenWidth:=80;
  1322. ScreenHeight:=25;
  1323. end;
  1324. GetMem(ConsoleBuf,ScreenHeight*ScreenWidth*2);
  1325. FillChar(ConsoleBuf^,ScreenHeight*ScreenWidth*2,0);
  1326. end;
  1327. Procedure CrtExit;
  1328. {
  1329. We need to restore normal keyboard mode upon exit !!
  1330. }
  1331. Begin
  1332. ttyFlushOutput;
  1333. SetRawMode(False);
  1334. { remove console buf }
  1335. if Assigned(ConsoleBuf) then
  1336. FreeMem(ConsoleBuf,ScreenHeight*ScreenWidth*2);
  1337. ExitProc:=ExitSave;
  1338. End;
  1339. Begin
  1340. {Hook Exit}
  1341. ExitSave:=ExitProc;
  1342. ExitProc:=@CrtExit;
  1343. { Redirect the standard output }
  1344. assigncrt(Output);
  1345. Rewrite(Output);
  1346. TextRec(Output).Handle:=StdOutputHandle;
  1347. assigncrt(Input);
  1348. Reset(Input);
  1349. TextRec(Input).Handle:=StdInputHandle;
  1350. { Are we redirected to a file ? }
  1351. Redir:=not IsAtty(TextRec(Output).Handle);
  1352. { Get Size of terminal and set WindMax to the window }
  1353. GetConsoleBuf;
  1354. WindMax:=((ScreenHeight-1) Shl 8)+(ScreenWidth-1);
  1355. {Get Current X&Y or Reset to Home}
  1356. if Redir then
  1357. begin
  1358. CurrX:=1;
  1359. CurrY:=1;
  1360. end
  1361. else
  1362. begin
  1363. { Set default Terminal Settings }
  1364. SetRawMode(True);
  1365. { Get current X,Y if not set already }
  1366. GetXY(CurrX,CurrY);
  1367. if (CurrX=0) then
  1368. begin
  1369. CurrX:=1;
  1370. CurrY:=1;
  1371. ttySendStr(#27'[H');
  1372. end;
  1373. {Reset Attribute (TextAttr=7 at startup)}
  1374. ttySendStr(#27'[m');
  1375. end;
  1376. End.
  1377. {
  1378. $Log$
  1379. Revision 1.15 1999-02-08 10:35:14 peter
  1380. * readkey fixes from the mailinglist
  1381. + cursoron/off/big from the mailinglist
  1382. Revision 1.14 1999/01/15 12:47:16 peter
  1383. * init window size to the size of the console instead of 80,25
  1384. Revision 1.13 1998/11/16 10:21:27 peter
  1385. * fixes for H+
  1386. Revision 1.12 1998/11/10 15:01:01 peter
  1387. * fixed GetXY at startup
  1388. Revision 1.11 1998/10/30 12:11:51 peter
  1389. * fixed fullwi, which did not check for 1,1
  1390. Revision 1.10 1998/10/27 11:13:27 peter
  1391. * fixed ttyWrite() with #8
  1392. Revision 1.9 1998/10/15 08:31:53 peter
  1393. + get winsize at startup
  1394. + ConsoleBuf to interface
  1395. Revision 1.8 1998/08/28 11:00:20 peter
  1396. * fixed #8 writing
  1397. Revision 1.7 1998/07/04 11:17:18 peter
  1398. * fixes for window (from "Heinz Ziegenhorn" <[email protected]>)
  1399. Revision 1.6 1998/06/19 16:51:50 peter
  1400. * added #13 -> #10 translation for CrtRead to overcome readln probs
  1401. Revision 1.5 1998/06/19 14:47:52 michael
  1402. + Enter key maps again to #13
  1403. Revision 1.4 1998/05/06 12:35:26 michael
  1404. + Removed log from before restored version.
  1405. Revision 1.3 1998/04/16 07:49:11 michael
  1406. * fixed bug. Clrscr and Clreol didn't take change in textattr in account.
  1407. Revision 1.2 1998/04/05 13:56:54 peter
  1408. - fixed mouse to compile with $i386_att
  1409. + linux crt supports redirecting (not Esc-codes anymore)
  1410. }