video.pp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Florian Klaempfl
  5. member of the Free Pascal development team
  6. Video unit for linux
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. unit Video;
  14. interface
  15. {$i videoh.inc}
  16. implementation
  17. uses
  18. Unix, Strings, TermInfo;
  19. {$i video.inc}
  20. var
  21. LastCursorType : byte;
  22. TtyFd: Longint;
  23. Console: Boolean;
  24. OldVideoBuf: PVideoBuf;
  25. {$ifdef logging}
  26. f: file;
  27. const
  28. logstart: string = '';
  29. nl: char = #10;
  30. logend: string = #10#10;
  31. {$endif logging}
  32. {$ifdef I386}
  33. {$ASMMODE ATT}
  34. {$endif I386}
  35. const
  36. can_delete_term : boolean = false;
  37. ACSIn : string = '';
  38. ACSOut : string = '';
  39. InACS : boolean =false;
  40. function IsACS(var ch,ACSchar : char): boolean;
  41. begin
  42. IsACS:=false;
  43. case ch of
  44. #24, #30: {}
  45. ch:='^';
  46. #25, #31: {}
  47. ch:='v';
  48. #26, #16: {Never introduce a ctrl-Z ... }
  49. ch:='>';
  50. {#27,needed in Escape sequences} #17: {}
  51. ch:='<';
  52. #176, #177, #178: {°±²}
  53. begin
  54. IsACS:=true;
  55. ACSChar:='a';
  56. end;
  57. #180, #181, #182, #185: {´µ¶¹}
  58. begin
  59. IsACS:=true;
  60. ACSChar:='u';
  61. end;
  62. #183, #184, #187, #191: {·¸»¿}
  63. begin
  64. IsACS:=true;
  65. ACSChar:='k';
  66. end;
  67. #188, #189, #190, #217: {¼½¾Ù}
  68. begin
  69. IsACS:=true;
  70. ACSChar:='j';
  71. end;
  72. #192, #200, #211, #212: {ÀÈÓÔ}
  73. begin
  74. IsACS:=true;
  75. ACSChar:='m';
  76. end;
  77. #193, #202, #207, #208: {ÁÊÏÐ}
  78. begin
  79. IsACS:=true;
  80. ACSChar:='v';
  81. end;
  82. #194, #203, #209, #210: {ÂËÑÒ}
  83. begin
  84. IsACS:=true;
  85. ACSChar:='w';
  86. end;
  87. #195, #198, #199, #204: {ÃÆÇÌ}
  88. begin
  89. IsACS:=true;
  90. ACSChar:='t';
  91. end;
  92. #196, #205: {ÄÍ}
  93. begin
  94. IsACS:=true;
  95. ACSChar:='q';
  96. end;
  97. #179, #186: {³º}
  98. begin
  99. IsACS:=true;
  100. ACSChar:='x';
  101. end;
  102. #197, #206, #215, #216: {ÅÎר}
  103. begin
  104. IsACS:=true;
  105. ACSChar:='n';
  106. end;
  107. #201, #213, #214, #218: {ÉÕÖÚ}
  108. begin
  109. IsACS:=true;
  110. ACSChar:='l';
  111. end;
  112. #254: { þ }
  113. begin
  114. ch:='*';
  115. end;
  116. { Shadows for Buttons }
  117. #220: { Ü }
  118. begin
  119. IsACS:=true;
  120. ACSChar:='a';
  121. end;
  122. #223: { ß }
  123. begin
  124. IsACS:=true;
  125. ACSChar:='a';
  126. end;
  127. end;
  128. end;
  129. function SendEscapeSeqNdx(Ndx: Word) : boolean;
  130. var
  131. P,pdelay: PChar;
  132. begin
  133. SendEscapeSeqNdx:=false;
  134. if not assigned(cur_term_Strings) then
  135. exit{RunError(219)};
  136. P:=cur_term_Strings^[Ndx];
  137. if assigned(p) then
  138. begin { Do not transmit the delays }
  139. pdelay:=strpos(p,'$<');
  140. if assigned(pdelay) then
  141. pdelay^:=#0;
  142. fdWrite(TTYFd, P^, StrLen(P));
  143. SendEscapeSeqNdx:=true;
  144. if assigned(pdelay) then
  145. pdelay^:='$';
  146. end;
  147. end;
  148. procedure SendEscapeSeq(const S: String);
  149. begin
  150. fdWrite(TTYFd, S[1], Length(S));
  151. end;
  152. Function IntStr(l:longint):string;
  153. var
  154. s : string;
  155. begin
  156. Str(l,s);
  157. IntStr:=s;
  158. end;
  159. Function XY2Ansi(x,y,ox,oy:longint):String;
  160. {
  161. Returns a string with the escape sequences to go to X,Y on the screen
  162. }
  163. Begin
  164. if y=oy then
  165. begin
  166. if x=ox then
  167. begin
  168. XY2Ansi:='';
  169. exit;
  170. end;
  171. if x=1 then
  172. begin
  173. XY2Ansi:=#13;
  174. exit;
  175. end;
  176. if x>ox then
  177. begin
  178. XY2Ansi:=#27'['+IntStr(x-ox)+'C';
  179. exit;
  180. end
  181. else
  182. begin
  183. XY2Ansi:=#27'['+IntStr(ox-x)+'D';
  184. exit;
  185. end;
  186. end;
  187. if x=ox then
  188. begin
  189. if y>oy then
  190. begin
  191. XY2Ansi:=#27'['+IntStr(y-oy)+'B';
  192. exit;
  193. end
  194. else
  195. begin
  196. XY2Ansi:=#27'['+IntStr(oy-y)+'A';
  197. exit;
  198. end;
  199. end;
  200. if (x=1) and (oy+1=y) then
  201. XY2Ansi:=#13#10
  202. else
  203. XY2Ansi:=#27'['+IntStr(y)+';'+IntStr(x)+'H';
  204. End;
  205. const
  206. AnsiTbl : string[8]='04261537';
  207. Function Attr2Ansi(Attr,OAttr:longint):string;
  208. {
  209. Convert Attr to an Ansi String, the Optimal code is calculate
  210. with use of the old OAttr
  211. }
  212. var
  213. hstr : string[16];
  214. OFg,OBg,Fg,Bg : longint;
  215. procedure AddSep(ch:char);
  216. begin
  217. if length(hstr)>0 then
  218. hstr:=hstr+';';
  219. hstr:=hstr+ch;
  220. end;
  221. begin
  222. if Attr=OAttr then
  223. begin
  224. Attr2Ansi:='';
  225. exit;
  226. end;
  227. Hstr:='';
  228. Fg:=Attr and $f;
  229. Bg:=Attr shr 4;
  230. OFg:=OAttr and $f;
  231. OBg:=OAttr shr 4;
  232. if (OFg<>7) or (Fg=7) or ((OFg>7) and (Fg<8)) or ((OBg>7) and (Bg<8)) then
  233. begin
  234. hstr:='0';
  235. OFg:=7;
  236. OBg:=0;
  237. end;
  238. if (Fg>7) and (OFg<8) then
  239. begin
  240. AddSep('1');
  241. OFg:=OFg or 8;
  242. end;
  243. if (Bg and 8)<>(OBg and 8) then
  244. begin
  245. AddSep('5');
  246. OBg:=OBg or 8;
  247. end;
  248. if (Fg<>OFg) then
  249. begin
  250. AddSep('3');
  251. hstr:=hstr+AnsiTbl[(Fg and 7)+1];
  252. end;
  253. if (Bg<>OBg) then
  254. begin
  255. AddSep('4');
  256. hstr:=hstr+AnsiTbl[(Bg and 7)+1];
  257. end;
  258. if hstr='0' then
  259. hstr:='';
  260. Attr2Ansi:=#27'['+hstr+'m';
  261. end;
  262. procedure TransformUsingACS(var st : string);
  263. var
  264. res : string;
  265. i : longint;
  266. ch,ACSch : char;
  267. begin
  268. res:='';
  269. for i:=1 to length(st) do
  270. begin
  271. ch:=st[i];
  272. if IsACS(ch,ACSch) then
  273. begin
  274. if not InACS then
  275. begin
  276. res:=res+ACSIn;
  277. InACS:=true;
  278. end;
  279. res:=res+ACSch;
  280. end
  281. else
  282. begin
  283. if InACS then
  284. begin
  285. res:=res+ACSOut;
  286. InACS:=false;
  287. end;
  288. res:=res+ch;
  289. end;
  290. end;
  291. st:=res;
  292. end;
  293. procedure UpdateTTY(Force:boolean);
  294. type
  295. tchattr=packed record
  296. {$ifdef ENDIAN_LITTLE}
  297. ch : char;
  298. attr : byte;
  299. {$else}
  300. attr : byte;
  301. ch : char;
  302. {$endif}
  303. end;
  304. var
  305. outbuf : array[0..1023+255] of char;
  306. chattr : tchattr;
  307. skipped : boolean;
  308. outptr,
  309. spaces,
  310. eol,
  311. x,y,
  312. LastX,LastY,
  313. SpaceAttr,
  314. LastAttr : longint;
  315. p,pold : pvideocell;
  316. procedure outdata(hstr:string);
  317. begin
  318. while (eol>0) do
  319. begin
  320. hstr:=#13#10+hstr;
  321. dec(eol);
  322. end;
  323. if NoExtendedFrame and (ACSIn<>'') and (ACSOut<>'') then
  324. TransformUsingACS(Hstr);
  325. move(hstr[1],outbuf[outptr],length(hstr));
  326. inc(outptr,length(hstr));
  327. if outptr>=1024 then
  328. begin
  329. {$ifdef logging}
  330. blockwrite(f,logstart[1],length(logstart));
  331. blockwrite(f,nl,1);
  332. blockwrite(f,outptr,sizeof(outptr));
  333. blockwrite(f,nl,1);
  334. blockwrite(f,outbuf,outptr);
  335. blockwrite(f,nl,1);
  336. {$endif logging}
  337. fdWrite(TTYFd,outbuf,outptr);
  338. outptr:=0;
  339. end;
  340. end;
  341. procedure OutClr(c:byte);
  342. begin
  343. if c=LastAttr then
  344. exit;
  345. OutData(Attr2Ansi(c,LastAttr));
  346. LastAttr:=c;
  347. end;
  348. procedure OutSpaces;
  349. begin
  350. if (Spaces=0) then
  351. exit;
  352. OutClr(SpaceAttr);
  353. OutData(Space(Spaces));
  354. LastX:=x;
  355. LastY:=y;
  356. Spaces:=0;
  357. end;
  358. begin
  359. OutPtr:=0;
  360. Eol:=0;
  361. skipped:=true;
  362. p:=PVideoCell(VideoBuf);
  363. pold:=PVideoCell(OldVideoBuf);
  364. { init Attr and X,Y }
  365. SendEscapeSeq(#27'[m'{#27'[H'});
  366. LastAttr:=7;
  367. LastX:=-1;
  368. LastY:=-1;
  369. for y:=1 to ScreenHeight do
  370. begin
  371. SpaceAttr:=0;
  372. Spaces:=0;
  373. for x:=1 to ScreenWidth do
  374. begin
  375. if (not force) and (p^=pold^) then
  376. begin
  377. if (Spaces>0) then
  378. OutSpaces;
  379. skipped:=true;
  380. end
  381. else
  382. begin
  383. if skipped then
  384. begin
  385. OutData(XY2Ansi(x,y,LastX,LastY));
  386. LastX:=x;
  387. LastY:=y;
  388. skipped:=false;
  389. end;
  390. chattr:=tchattr(p^);
  391. if chattr.ch in [#0,#255] then
  392. chattr.ch:=' ';
  393. if chattr.ch=' ' then
  394. begin
  395. if Spaces=0 then
  396. SpaceAttr:=chattr.Attr;
  397. if (chattr.attr and $f0)=(spaceattr and $f0) then
  398. chattr.Attr:=SpaceAttr
  399. else
  400. begin
  401. OutSpaces;
  402. SpaceAttr:=chattr.Attr;
  403. end;
  404. inc(Spaces);
  405. end
  406. else
  407. begin
  408. if (Spaces>0) then
  409. OutSpaces;
  410. if ord(chattr.ch)<32 then
  411. begin
  412. Chattr.Attr:= $ff xor Chattr.Attr;
  413. ChAttr.ch:= chr(ord(chattr.ch)+ord('A')-1);
  414. end;
  415. if LastAttr<>chattr.Attr then
  416. OutClr(chattr.Attr);
  417. OutData(chattr.ch);
  418. LastX:=x+1;
  419. LastY:=y;
  420. end;
  421. p^:=tvideocell(chattr);
  422. end;
  423. inc(p);
  424. inc(pold);
  425. end;
  426. if (Spaces>0) then
  427. OutSpaces;
  428. if force then
  429. inc(eol);
  430. end;
  431. eol:=0;
  432. OutData(XY2Ansi(CursorX,CursorY,LastX,LastY));
  433. {$ifdef logging}
  434. blockwrite(f,logstart[1],length(logstart));
  435. blockwrite(f,nl,1);
  436. blockwrite(f,outptr,sizeof(outptr));
  437. blockwrite(f,nl,1);
  438. blockwrite(f,outbuf,outptr);
  439. blockwrite(f,nl,1);
  440. {$endif logging}
  441. fdWrite(TTYFd,outbuf,outptr);
  442. if InACS then
  443. SendEscapeSeqNdx(exit_alt_charset_mode);
  444. end;
  445. var
  446. InitialVideoTio, preInitVideoTio, postInitVideoTio: Unix.termios;
  447. inputRaw, outputRaw: boolean;
  448. procedure saveRawSettings(const tio: Unix.termios);
  449. Begin
  450. with tio do
  451. begin
  452. inputRaw :=
  453. ((c_iflag and (IGNBRK or BRKINT or PARMRK or ISTRIP or
  454. INLCR or IGNCR or ICRNL or IXON)) = 0) and
  455. ((c_lflag and (ECHO or ECHONL or ICANON or ISIG or IEXTEN)) = 0);
  456. outPutRaw :=
  457. ((c_oflag and OPOST) = 0) and
  458. ((c_cflag and (CSIZE or PARENB)) = 0) and
  459. ((c_cflag and CS8) <> 0);
  460. end;
  461. end;
  462. procedure restoreRawSettings(tio: Unix.termios);
  463. begin
  464. with tio do
  465. begin
  466. if inputRaw then
  467. begin
  468. c_iflag := c_iflag and (not (IGNBRK or BRKINT or PARMRK or ISTRIP or
  469. INLCR or IGNCR or ICRNL or IXON));
  470. c_lflag := c_lflag and
  471. (not (ECHO or ECHONL or ICANON or ISIG or IEXTEN));
  472. end;
  473. if outPutRaw then
  474. begin
  475. c_oflag := c_oflag and not(OPOST);
  476. c_cflag := c_cflag and not(CSIZE or PARENB) or CS8;
  477. end;
  478. end;
  479. TCSetAttr(1,TCSANOW,tio);
  480. end;
  481. procedure TargetEntry;
  482. begin
  483. TCGetAttr(1,InitialVideoTio);
  484. end;
  485. procedure TargetExit;
  486. begin
  487. TCSetAttr(1,TCSANOW,InitialVideoTio);
  488. end;
  489. procedure prepareInitVideo;
  490. begin
  491. TCGetAttr(1,preInitVideoTio);
  492. saveRawSettings(preInitVideoTio);
  493. end;
  494. procedure videoInitDone;
  495. begin
  496. TCGetAttr(1,postInitVideoTio);
  497. restoreRawSettings(postInitVideoTio);
  498. end;
  499. procedure prepareDoneVideo;
  500. var
  501. tio: Unix.termios;
  502. begin
  503. TCGetAttr(1,tio);
  504. saveRawSettings(tio);
  505. TCSetAttr(1,TCSANOW,postInitVideoTio);
  506. end;
  507. procedure doneVideoDone;
  508. begin
  509. restoreRawSettings(preInitVideoTio);
  510. end;
  511. procedure InitVideo;
  512. const
  513. fontstr : string[3]=#27'(K';
  514. var
  515. ThisTTY: String[30];
  516. FName: String;
  517. WS: packed record
  518. ws_row, ws_col, ws_xpixel, ws_ypixel: Word;
  519. end;
  520. Err: Longint;
  521. prev_term : TerminalCommon_ptr1;
  522. begin
  523. {$ifndef CPUI386}
  524. LowAscii:=false;
  525. {$endif CPUI386}
  526. if VideoBufSize<>0 then
  527. begin
  528. clearscreen;
  529. if Console then
  530. SetCursorPos(1,1)
  531. else
  532. begin
  533. if not SendEscapeSeqNdx(cursor_home) then
  534. SendEscapeSeq(#27'[H');
  535. end;
  536. exit;
  537. end;
  538. { check for tty }
  539. ThisTTY:=TTYName(stdinputhandle);
  540. if IsATTY(stdinputhandle) then
  541. begin
  542. { save current terminal characteristics and remove rawness }
  543. prepareInitVideo;
  544. { write code to set a correct font }
  545. fdWrite(stdoutputhandle,fontstr[1],length(fontstr));
  546. { running on a tty, find out whether locally or remotely }
  547. if (Copy(ThisTTY, 1, 8) = '/dev/tty') and
  548. (ThisTTY[9] >= '0') and (ThisTTY[9] <= '9') then
  549. begin
  550. { running on the console }
  551. FName:='/dev/vcsa' + ThisTTY[9];
  552. TTYFd:=fdOpen(FName, Octal(666), Open_RdWr); { open console }
  553. end
  554. else
  555. TTYFd:=-1;
  556. if TTYFd<>-1 then
  557. Console:=true
  558. else
  559. begin
  560. { running on a remote terminal, no error with /dev/vcsa }
  561. Console:=False;
  562. LowAscii:=false;
  563. TTYFd:=stdoutputhandle;
  564. end;
  565. ioctl(stdinputhandle, TIOCGWINSZ, @WS);
  566. if WS.ws_Col=0 then
  567. WS.ws_Col:=80;
  568. if WS.ws_Row=0 then
  569. WS.ws_Row:=25;
  570. ScreenWidth:=WS.ws_Col;
  571. { TDrawBuffer only has FVMaxWidth elements
  572. larger values lead to crashes }
  573. if ScreenWidth> FVMaxWidth then
  574. ScreenWidth:=FVMaxWidth;
  575. ScreenHeight:=WS.ws_Row;
  576. CursorX:=1;
  577. CursorY:=1;
  578. ScreenColor:=True;
  579. { allocate pmode memory buffer }
  580. VideoBufSize:=ScreenWidth*ScreenHeight*2;
  581. GetMem(VideoBuf,VideoBufSize);
  582. GetMem(OldVideoBuf,VideoBufSize);
  583. { Start with a clear screen }
  584. if not Console then
  585. begin
  586. prev_term:=cur_term;
  587. setupterm(nil, stdoutputhandle, err);
  588. can_delete_term:=assigned(prev_term) and (prev_term<>cur_term);
  589. SendEscapeSeqNdx(cursor_home);
  590. SendEscapeSeqNdx(cursor_normal);
  591. SendEscapeSeqNdx(cursor_visible);
  592. SendEscapeSeqNdx(enter_ca_mode);
  593. SetCursorType(crUnderLine);
  594. end
  595. else if not assigned(cur_term) then
  596. begin
  597. setupterm(nil, stdoutputhandle, err);
  598. can_delete_term:=false;
  599. end;
  600. if assigned(cur_term_Strings) then
  601. begin
  602. ACSIn:=StrPas(cur_term_Strings^[enter_alt_charset_mode]);
  603. ACSOut:=StrPas(cur_term_Strings^[exit_alt_charset_mode]);
  604. if (ACSIn<>'') and (ACSOut<>'') then
  605. SendEscapeSeqNdx(ena_acs);
  606. if pos('$<',ACSIn)>0 then
  607. ACSIn:=Copy(ACSIn,1,Pos('$<',ACSIn)-1);
  608. if pos('$<',ACSOut)>0 then
  609. ACSOut:=Copy(ACSOut,1,Pos('$<',ACSOut)-1);
  610. end
  611. else
  612. begin
  613. ACSIn:='';
  614. ACSOut:='';
  615. end;
  616. ClearScreen;
  617. {$ifdef logging}
  618. assign(f,'video.log');
  619. rewrite(f,1);
  620. {$endif logging}
  621. { save new terminal characteristics and possible restore rawness }
  622. videoInitDone;
  623. end
  624. else
  625. ErrorCode:=errVioInit; { not a TTY }
  626. end;
  627. procedure DoneVideo;
  628. begin
  629. if VideoBufSize=0 then
  630. exit;
  631. prepareDoneVideo;
  632. ClearScreen;
  633. if Console then
  634. SetCursorPos(1,1)
  635. else
  636. begin
  637. SendEscapeSeqNdx(exit_ca_mode);
  638. SendEscapeSeqNdx(cursor_home);
  639. SendEscapeSeqNdx(cursor_normal);
  640. SendEscapeSeqNdx(cursor_visible);
  641. SetCursorType(crUnderLine);
  642. SendEscapeSeq(#27'[H');
  643. end;
  644. FreeMem(VideoBuf,VideoBufSize);
  645. FreeMem(OldVideoBuf,VideoBufSize);
  646. VideoBufSize:=0;
  647. ACSIn:='';
  648. ACSOut:='';
  649. doneVideoDone;
  650. if can_delete_term then
  651. begin
  652. del_curterm(cur_term);
  653. can_delete_term:=false;
  654. end;
  655. {$ifdef logging}
  656. close(f);
  657. {$endif logging}
  658. end;
  659. procedure ClearScreen;
  660. begin
  661. FillWord(VideoBuf^,VideoBufSize shr 1,$0720);
  662. if Console then
  663. UpdateScreen(true)
  664. else
  665. begin
  666. SendEscapeSeq(#27'[0m');
  667. SendEscapeSeqNdx(clear_screen);
  668. end;
  669. end;
  670. procedure UpdateScreen(Force: Boolean);
  671. var
  672. DoUpdate : boolean;
  673. i : longint;
  674. p1,p2 : plongint;
  675. begin
  676. if LockUpdateScreen<>0 then
  677. exit;
  678. if not force then
  679. begin
  680. {$ifdef i386}
  681. asm
  682. movl VideoBuf,%esi
  683. movl OldVideoBuf,%edi
  684. movl VideoBufSize,%ecx
  685. shrl $2,%ecx
  686. repe
  687. cmpsl
  688. setne DoUpdate
  689. end;
  690. {$else not i386}
  691. p1:=plongint(VideoBuf);
  692. p2:=plongint(OldVideoBuf);
  693. for i:=0 to VideoBufSize div 2 do
  694. if (p1^<>p2^) then
  695. begin
  696. DoUpdate:=true;
  697. break;
  698. end
  699. else
  700. begin
  701. { Inc does add sizeof(longint) to both pointer values }
  702. inc(p1);
  703. inc(p2);
  704. end;
  705. {$endif not i386}
  706. end
  707. else
  708. DoUpdate:=true;
  709. if not DoUpdate then
  710. exit;
  711. if Console then
  712. begin
  713. fdSeek(TTYFd, 4, Seek_Set);
  714. fdWrite(TTYFd, VideoBuf^,VideoBufSize);
  715. end
  716. else
  717. begin
  718. UpdateTTY(force);
  719. end;
  720. Move(VideoBuf^, OldVideoBuf^, VideoBufSize);
  721. end;
  722. function GetCapabilities: Word;
  723. begin
  724. { about cpColor... we should check the terminfo database... }
  725. GetCapabilities:=cpUnderLine + cpBlink + cpColor;
  726. end;
  727. procedure SetCursorPos(NewCursorX, NewCursorY: Word);
  728. var
  729. Pos : array [1..2] of Byte;
  730. begin
  731. if Console then
  732. begin
  733. fdSeek(TTYFd, 2, Seek_Set);
  734. Pos[1]:=NewCursorX;
  735. Pos[2]:=NewCursorY;
  736. fdWrite(TTYFd, Pos, 2);
  737. end
  738. else
  739. begin
  740. { newcursorx,y is 0 based ! }
  741. SendEscapeSeq(XY2Ansi(NewCursorX+1,NewCursorY+1,0,0));
  742. end;
  743. CursorX:=NewCursorX+1;
  744. CursorY:=NewCursorY+1;
  745. end;
  746. function GetCursorType: Word;
  747. begin
  748. GetCursorType:=LastCursorType;
  749. end;
  750. procedure SetCursorType(NewType: Word);
  751. begin
  752. LastCursorType:=NewType;
  753. case NewType of
  754. crBlock :
  755. Begin
  756. If not SendEscapeSeqNdx(cursor_visible) then
  757. SendEscapeSeq(#27'[?17;0;64c');
  758. End;
  759. crHidden :
  760. Begin
  761. If not SendEscapeSeqNdx(cursor_invisible) then
  762. SendEscapeSeq(#27'[?1c');
  763. End;
  764. else
  765. begin
  766. If not SendEscapeSeqNdx(cursor_normal) then
  767. SendEscapeSeq(#27'[?2c');
  768. end;
  769. end;
  770. end;
  771. function DefaultVideoModeSelector(const VideoMode: TVideoMode; Params: Longint): Boolean;
  772. begin
  773. DefaultVideoModeSelector:=false;
  774. end;
  775. procedure RegisterVideoModes;
  776. begin
  777. end;
  778. initialization
  779. RegisterVideoModes;
  780. finalization
  781. UnRegisterVideoModes;
  782. end.
  783. {
  784. $Log$
  785. Revision 1.6 2001-08-01 21:42:05 peter
  786. * m68k warning fix (merged)
  787. Revision 1.5 2001/07/31 19:33:46 peter
  788. * make tchattr record endian dependant (merged)
  789. Revision 1.4 2001/07/30 21:38:55 peter
  790. * m68k updates merged
  791. Revision 1.3 2001/07/13 22:05:09 peter
  792. * cygwin updates
  793. Revision 1.2 2001/01/21 20:21:41 marco
  794. * Rename fest II. Rtl OK
  795. Revision 1.1 2001/01/13 11:03:58 peter
  796. * API 2 RTL commit
  797. }