video.pp 19 KB

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