video.pp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911
  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. else
  431. skipped:=true;
  432. end;
  433. eol:=0;
  434. OutData(XY2Ansi(CursorX,CursorY,LastX,LastY));
  435. {$ifdef logging}
  436. blockwrite(f,logstart[1],length(logstart));
  437. blockwrite(f,nl,1);
  438. blockwrite(f,outptr,sizeof(outptr));
  439. blockwrite(f,nl,1);
  440. blockwrite(f,outbuf,outptr);
  441. blockwrite(f,nl,1);
  442. {$endif logging}
  443. fdWrite(TTYFd,outbuf,outptr);
  444. if InACS then
  445. SendEscapeSeqNdx(exit_alt_charset_mode);
  446. end;
  447. var
  448. InitialVideoTio, preInitVideoTio, postInitVideoTio: Unix.termios;
  449. inputRaw, outputRaw: boolean;
  450. procedure saveRawSettings(const tio: Unix.termios);
  451. Begin
  452. with tio do
  453. begin
  454. inputRaw :=
  455. ((c_iflag and (IGNBRK or BRKINT or PARMRK or ISTRIP or
  456. INLCR or IGNCR or ICRNL or IXON)) = 0) and
  457. ((c_lflag and (ECHO or ECHONL or ICANON or ISIG or IEXTEN)) = 0);
  458. outPutRaw :=
  459. ((c_oflag and OPOST) = 0) and
  460. ((c_cflag and (CSIZE or PARENB)) = 0) and
  461. ((c_cflag and CS8) <> 0);
  462. end;
  463. end;
  464. procedure restoreRawSettings(tio: Unix.termios);
  465. begin
  466. with tio do
  467. begin
  468. if inputRaw then
  469. begin
  470. c_iflag := c_iflag and (not (IGNBRK or BRKINT or PARMRK or ISTRIP or
  471. INLCR or IGNCR or ICRNL or IXON));
  472. c_lflag := c_lflag and
  473. (not (ECHO or ECHONL or ICANON or ISIG or IEXTEN));
  474. end;
  475. if outPutRaw then
  476. begin
  477. c_oflag := c_oflag and not(OPOST);
  478. c_cflag := c_cflag and not(CSIZE or PARENB) or CS8;
  479. end;
  480. end;
  481. TCSetAttr(1,TCSANOW,tio);
  482. end;
  483. procedure TargetEntry;
  484. begin
  485. TCGetAttr(1,InitialVideoTio);
  486. end;
  487. procedure TargetExit;
  488. begin
  489. TCSetAttr(1,TCSANOW,InitialVideoTio);
  490. end;
  491. procedure prepareInitVideo;
  492. begin
  493. TCGetAttr(1,preInitVideoTio);
  494. saveRawSettings(preInitVideoTio);
  495. end;
  496. procedure videoInitDone;
  497. begin
  498. TCGetAttr(1,postInitVideoTio);
  499. restoreRawSettings(postInitVideoTio);
  500. end;
  501. procedure prepareDoneVideo;
  502. var
  503. tio: Unix.termios;
  504. begin
  505. TCGetAttr(1,tio);
  506. saveRawSettings(tio);
  507. TCSetAttr(1,TCSANOW,postInitVideoTio);
  508. end;
  509. procedure doneVideoDone;
  510. begin
  511. restoreRawSettings(preInitVideoTio);
  512. end;
  513. procedure SysInitVideo;
  514. const
  515. fontstr : string[3]=#27'(K';
  516. var
  517. ThisTTY: String[30];
  518. FName: String;
  519. WS: packed record
  520. ws_row, ws_col, ws_xpixel, ws_ypixel: Word;
  521. end;
  522. Err: Longint;
  523. prev_term : TerminalCommon_ptr1;
  524. begin
  525. {$ifndef CPUI386}
  526. LowAscii:=false;
  527. {$endif CPUI386}
  528. if VideoBufSize<>0 then
  529. begin
  530. clearscreen;
  531. if Console then
  532. SetCursorPos(1,1)
  533. else
  534. begin
  535. if not SendEscapeSeqNdx(cursor_home) then
  536. SendEscapeSeq(#27'[H');
  537. end;
  538. exit;
  539. end;
  540. { check for tty }
  541. ThisTTY:=TTYName(stdinputhandle);
  542. if IsATTY(stdinputhandle) then
  543. begin
  544. { save current terminal characteristics and remove rawness }
  545. prepareInitVideo;
  546. { write code to set a correct font }
  547. fdWrite(stdoutputhandle,fontstr[1],length(fontstr));
  548. { running on a tty, find out whether locally or remotely }
  549. if (Copy(ThisTTY, 1, 8) = '/dev/tty') and
  550. (ThisTTY[9] >= '0') and (ThisTTY[9] <= '9') then
  551. begin
  552. { running on the console }
  553. FName:='/dev/vcsa' + ThisTTY[9];
  554. TTYFd:=fdOpen(FName, Octal(666), Open_RdWr); { open console }
  555. end
  556. else
  557. TTYFd:=-1;
  558. if TTYFd<>-1 then
  559. Console:=true
  560. else
  561. begin
  562. { running on a remote terminal, no error with /dev/vcsa }
  563. Console:=False;
  564. LowAscii:=false;
  565. TTYFd:=stdoutputhandle;
  566. end;
  567. ioctl(stdinputhandle, TIOCGWINSZ, @WS);
  568. if WS.ws_Col=0 then
  569. WS.ws_Col:=80;
  570. if WS.ws_Row=0 then
  571. WS.ws_Row:=25;
  572. ScreenWidth:=WS.ws_Col;
  573. { TDrawBuffer only has FVMaxWidth elements
  574. larger values lead to crashes }
  575. if ScreenWidth> FVMaxWidth then
  576. ScreenWidth:=FVMaxWidth;
  577. ScreenHeight:=WS.ws_Row;
  578. CursorX:=1;
  579. CursorY:=1;
  580. ScreenColor:=True;
  581. { allocate pmode memory buffer }
  582. VideoBufSize:=ScreenWidth*ScreenHeight*2;
  583. GetMem(VideoBuf,VideoBufSize);
  584. GetMem(OldVideoBuf,VideoBufSize);
  585. { Start with a clear screen }
  586. if not Console then
  587. begin
  588. prev_term:=cur_term;
  589. setupterm(nil, stdoutputhandle, err);
  590. can_delete_term:=assigned(prev_term) and (prev_term<>cur_term);
  591. SendEscapeSeqNdx(cursor_home);
  592. SendEscapeSeqNdx(cursor_normal);
  593. SendEscapeSeqNdx(cursor_visible);
  594. SendEscapeSeqNdx(enter_ca_mode);
  595. SetCursorType(crUnderLine);
  596. end
  597. else if not assigned(cur_term) then
  598. begin
  599. setupterm(nil, stdoutputhandle, err);
  600. can_delete_term:=false;
  601. end;
  602. if assigned(cur_term_Strings) then
  603. begin
  604. ACSIn:=StrPas(cur_term_Strings^[enter_alt_charset_mode]);
  605. ACSOut:=StrPas(cur_term_Strings^[exit_alt_charset_mode]);
  606. if (ACSIn<>'') and (ACSOut<>'') then
  607. SendEscapeSeqNdx(ena_acs);
  608. if pos('$<',ACSIn)>0 then
  609. ACSIn:=Copy(ACSIn,1,Pos('$<',ACSIn)-1);
  610. if pos('$<',ACSOut)>0 then
  611. ACSOut:=Copy(ACSOut,1,Pos('$<',ACSOut)-1);
  612. end
  613. else
  614. begin
  615. ACSIn:='';
  616. ACSOut:='';
  617. end;
  618. ClearScreen;
  619. {$ifdef logging}
  620. assign(f,'video.log');
  621. rewrite(f,1);
  622. {$endif logging}
  623. { save new terminal characteristics and possible restore rawness }
  624. videoInitDone;
  625. end
  626. else
  627. ErrorCode:=errVioInit; { not a TTY }
  628. end;
  629. procedure SysDoneVideo;
  630. begin
  631. if VideoBufSize=0 then
  632. exit;
  633. prepareDoneVideo;
  634. ClearScreen;
  635. if Console then
  636. SetCursorPos(1,1)
  637. else
  638. begin
  639. SendEscapeSeqNdx(exit_ca_mode);
  640. SendEscapeSeqNdx(cursor_home);
  641. SendEscapeSeqNdx(cursor_normal);
  642. SendEscapeSeqNdx(cursor_visible);
  643. SetCursorType(crUnderLine);
  644. SendEscapeSeq(#27'[H');
  645. end;
  646. FreeMem(VideoBuf,VideoBufSize);
  647. FreeMem(OldVideoBuf,VideoBufSize);
  648. VideoBufSize:=0;
  649. ACSIn:='';
  650. ACSOut:='';
  651. doneVideoDone;
  652. if can_delete_term then
  653. begin
  654. del_curterm(cur_term);
  655. can_delete_term:=false;
  656. end;
  657. {$ifdef logging}
  658. close(f);
  659. {$endif logging}
  660. end;
  661. procedure SysClearScreen;
  662. begin
  663. FillWord(VideoBuf^,VideoBufSize shr 1,$0720);
  664. if Console then
  665. UpdateScreen(true)
  666. else
  667. begin
  668. SendEscapeSeq(#27'[0m');
  669. SendEscapeSeqNdx(clear_screen);
  670. end;
  671. end;
  672. procedure SysUpdateScreen(Force: Boolean);
  673. var
  674. DoUpdate : boolean;
  675. i : longint;
  676. p1,p2 : plongint;
  677. begin
  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 SysGetCapabilities: Word;
  723. begin
  724. { about cpColor... we should check the terminfo database... }
  725. SysGetCapabilities:=cpUnderLine + cpBlink + cpColor;
  726. end;
  727. procedure SysSetCursorPos(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 SysGetCursorType: Word;
  747. begin
  748. SysGetCursorType:=LastCursorType;
  749. end;
  750. procedure SysSetCursorType(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. Const
  779. SysVideoDriver : TVideoDriver = (
  780. InitDriver : @SysInitVideo;
  781. DoneDriver : @SysDoneVideo;
  782. UpdateScreen : @SysUpdateScreen;
  783. ClearScreen : @SysClearScreen;
  784. SetVideoMode : Nil;
  785. HasVideoMode : Nil;
  786. SetCursorPos : @SysSetCursorPos;
  787. GetCursorType : @SysGetCursorType;
  788. SetCursorType : @SysSetCursorType;
  789. GetCapabilities : @SysGetCapabilities
  790. );
  791. initialization
  792. SetVideoDriver(SysVideoDriver);
  793. RegisterVideoModes;
  794. finalization
  795. UnRegisterVideoModes;
  796. end.
  797. {
  798. $Log$
  799. Revision 1.8 2001-09-21 19:50:19 michael
  800. + Merged driver support from fixbranch
  801. Revision 1.7 2001/08/30 20:55:08 peter
  802. * v10 merges
  803. Revision 1.6 2001/08/01 21:42:05 peter
  804. * m68k warning fix (merged)
  805. Revision 1.5 2001/07/31 19:33:46 peter
  806. * make tchattr record endian dependant (merged)
  807. Revision 1.4 2001/07/30 21:38:55 peter
  808. * m68k updates merged
  809. Revision 1.2.2.8 2001/09/21 18:42:09 michael
  810. + Implemented support for custom video drivers.
  811. Revision 1.2.2.7 2001/08/28 12:23:15 pierre
  812. * set skipped to true if changing line and force is false to avoid problems if terminal reports less columns as available
  813. Revision 1.2.2.6 2001/08/01 10:50:59 pierre
  814. * avoid warning for m68k cpu
  815. Revision 1.2.2.5 2001/07/30 23:34:51 pierre
  816. * make tchattr record endian dependant
  817. Revision 1.2.2.4 2001/07/29 20:25:18 pierre
  818. * fix wrong deref in generic compare code
  819. Revision 1.2.2.3 2001/07/13 14:49:08 pierre
  820. + implement videobuf comparaison for non i386 cpus
  821. Revision 1.2.2.2 2001/01/30 22:23:44 peter
  822. * unix back to linux
  823. Revision 1.3 2001/07/13 22:05:09 peter
  824. * cygwin updates
  825. Revision 1.2 2001/01/21 20:21:41 marco
  826. * Rename fest II. Rtl OK
  827. Revision 1.1 2001/01/13 11:03:58 peter
  828. * API 2 RTL commit
  829. }