vesa.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. {
  2. This file is part of the PinGUI - Platform Independent GUI Project
  3. Copyright (c) 1999 by Berczi Gabor
  4. VESA support routines
  5. See the file COPYING.GUI, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit VESA;
  12. {$ifdef DEBUG}
  13. {$define TESTGRAPHIC}
  14. {$endif DEBUG}
  15. interface
  16. uses
  17. Dos,
  18. Objects,Strings,WUtils;
  19. const
  20. { Video Mode Attributes mask constants }
  21. vesa_vma_CanBeSetInCurrentConfig = $0001;
  22. vesa_vma_OptionalBlockPresent = $0002;
  23. vesa_vma_BIOSSupport = $0004;
  24. vesa_vma_ColorMode = $0008; { else mono }
  25. vesa_vma_GraphicsMode = $0010; { else text }
  26. { -- VBE 2.0 --- }
  27. vesa_vma_VGACompatibleMode = $0020;
  28. vesa_vma_VGACompWindowedAvail = $0040;
  29. vesa_vma_LinearFrameBufferAvail = $0080;
  30. { Windows Attributes mask constants }
  31. vesa_wa_Present = $0001;
  32. vesa_wa_Readable = $0002;
  33. vesa_wa_Writeable = $0004;
  34. { Memory Model value constants }
  35. vesa_mm_Text = $0000;
  36. vesa_mm_CGAGraphics = $0001;
  37. vesa_mm_HerculesGraphics = $0002;
  38. vesa_mm_4planePlanar = $0003;
  39. vesa_mm_PackedPixel = $0004;
  40. vesa_mm_NonChain4_256color = $0005;
  41. vesa_mm_DirectColor = $0006;
  42. vesa_mm_YUV = $0007;
  43. { Memory Window value constants }
  44. vesa_mw_WindowA = $0000;
  45. vesa_mw_WindowB = $0001;
  46. type
  47. {$ifdef FPC}tregisters=registers;{$endif}
  48. {$ifdef TP}tregisters=registers;{$endif}
  49. PtrRec16 = record
  50. Ofs,Seg: word;
  51. end;
  52. TVESAInfoBlock = packed record
  53. Signature : longint; { 'VESA' }
  54. Version : word;
  55. OEMString : PString;
  56. Capabilities : longint;
  57. VideoModeList: PWordArray;
  58. TotalMemory : word; { in 64KB blocks }
  59. Fill : array[1..236] of byte;
  60. VBE2Fill : array[1..256] of byte;
  61. end;
  62. TVESAModeInfoBlock = packed record
  63. Attributes : word;
  64. WinAAttrs : byte;
  65. WinBAttrs : byte;
  66. Granularity : word;
  67. Size : word;
  68. ASegment : word;
  69. BSegment : word;
  70. FuncPtr : pointer;
  71. BytesPerLine : word;
  72. { optional }
  73. XResolution : word;
  74. YResolution : word;
  75. XCharSize : byte;
  76. YCharSize : byte;
  77. NumberOfPlanes : byte;
  78. BitsPerPixel : byte;
  79. NumberOfBanks : byte;
  80. MemoryModel : byte;
  81. BankSize : byte;
  82. NumberOfImagePages: byte;
  83. Reserved : byte;
  84. { direct color fields }
  85. RedMaskSize : byte;
  86. RedFieldPosition: byte;
  87. GreenMaskSize : byte;
  88. GreenFieldPosition: byte;
  89. BlueMaskSize : byte;
  90. BlueFieldPosition: byte;
  91. ReservedMaskSize: byte;
  92. ReservedPosition: byte;
  93. DirectColorModeInfo: byte;
  94. { --- VBE 2.0 optional --- }
  95. LinearFrameAddr : longint;
  96. OffScreenAddr : longint;
  97. OffScreenSize : word;
  98. Reserved2 : array[1..216-(4+4+2)] of byte;
  99. end;
  100. TVESAModeList = record
  101. Count : word;
  102. Modes : array[1..256] of word;
  103. end;
  104. function VESAInit: boolean;
  105. function VESAGetInfo(var B: TVESAInfoBlock): boolean;
  106. function VESAGetModeInfo(Mode: word; var B: TVESAModeInfoBlock): boolean;
  107. function VESAGetModeList(var B: TVESAModeList): boolean;
  108. function VESASearchMode(XRes,YRes,BPX: word; LFB: boolean; var Mode: word; var ModeInfo: TVESAModeInfoBlock): boolean;
  109. function VESAGetOemString: string;
  110. function VESASetMode(Mode: word): boolean;
  111. function VESAGetMode(var Mode: word): boolean;
  112. function VESASelectMemoryWindow(Window: byte; Position: word): boolean;
  113. function VESAReturnMemoryWindow(Window: byte; var Position: word): boolean;
  114. function RegisterVesaVideoMode(Mode : word) : boolean;
  115. Procedure FreeVesaModes;
  116. implementation
  117. uses
  118. {$ifdef FPC}
  119. video, mouse,
  120. {$endif FPC}
  121. {$ifdef TESTGRAPHIC}
  122. graph,
  123. {$endif TESTGRAPHIC}
  124. pmode;
  125. type
  126. PVesaVideoMode = ^TVesaVideoMode;
  127. TVesaVideoMode = record
  128. {Col,Row : word;
  129. Color : boolean;}
  130. V : TVideoMode;
  131. Mode : word;
  132. IsGraphic : boolean;
  133. { zero based vesa specific driver count }
  134. VideoIndex : word;
  135. Next : PVesaVideoMode;
  136. end;
  137. CursorBitMap = Record
  138. width,height,size : longint;
  139. colors : array[0..8*8-1] of word;
  140. end;
  141. const
  142. VesaVideoModeHead : PVesaVideoMode = nil;
  143. VesaRegisteredModes : word = 0;
  144. {$ifdef TESTGRAPHIC}
  145. IsGraphicMode : boolean = false;
  146. GraphDriver : integer = 0;
  147. GraphMode : Integer = 0;
  148. FirstCallAfterSetVesaMode : boolean = false;
  149. LastCursorX : word = $ffff;
  150. LastCursorY : word = $ffff;
  151. LastCursorType : word = crHidden;
  152. var
  153. UnderLineImage : CursorBitMap;
  154. BlockImage : CursorBitMap;
  155. HalfBlockImage : CursorBitMap;
  156. {$endif TESTGRAPHIC}
  157. Var
  158. SysGetVideoModeCount : function : word;
  159. SysSetVideoMode : function (Const VideoMode : TVideoMode) : boolean;
  160. SysGetVideoModeData : function (Index : Word; Var Data : TVideoMode) : boolean;
  161. SysUpdateScreen : procedure(Force : Boolean);
  162. SysDoneVideo : procedure;
  163. SysInitVideo : procedure;
  164. SysSetCursorPos : procedure(NewCursorX, NewCursorY: Word);
  165. SysSetCursorType : procedure(NewCurosrType : word);
  166. function VESAGetInfo(var B: TVESAInfoBlock): boolean;
  167. var r: registers;
  168. OK: boolean;
  169. M: MemPtr;
  170. begin
  171. StrToMem('VBE2',B.Signature);
  172. GetDosMem(M,SizeOf(B));
  173. M.MoveDataTo(B,sizeof(B));
  174. r.ah:=$4f; r.al:=0;
  175. r.es:=M.DosSeg; r.di:=M.DosOfs;
  176. realintr($10,r);
  177. M.MoveDataFrom(sizeof(B),B);
  178. FreeDosMem(M);
  179. OK:=(r.ax=$004f){ and (MemToStr(B.Signature,4)='VESA')};
  180. VESAGetInfo:=OK;
  181. end;
  182. function VESAGetModeList(var B: TVESAModeList): boolean;
  183. var OK: boolean;
  184. VI: TVESAInfoBlock;
  185. begin
  186. FillChar(B,SizeOf(B),0);
  187. OK:=VESAGetInfo(VI);
  188. if OK then
  189. begin
  190. OK:=MoveDosToPM(VI.VideoModeList,@B.Modes,sizeof(B.Modes));
  191. if OK then
  192. while (B.Modes[B.Count+1]<>$ffff) and (B.Count<High(B.Modes)) do
  193. Inc(B.Count);
  194. end;
  195. VESAGetModeList:=OK;
  196. end;
  197. function VESASearchMode(XRes,YRes,BPX: word; LFB: boolean; var Mode: word; var ModeInfo: TVESAModeInfoBlock): boolean;
  198. var B: TVESAModeList;
  199. OK: boolean;
  200. I: integer;
  201. MI: TVESAModeInfoBlock;
  202. begin
  203. OK:=VESAGetModeList(B);
  204. I:=1; Mode:=0;
  205. repeat
  206. OK:=VESAGetModeInfo(B.Modes[I],MI);
  207. if OK and (MI.XResolution=XRes) and (MI.YResolution=YRes) and
  208. (MI.BitsPerPixel=BPX) and
  209. ((LFB=false) or ((MI.Attributes and vesa_vma_LinearFrameBufferAvail)<>0)) then
  210. begin Mode:=B.Modes[I]; ModeInfo:=MI; end;
  211. Inc(I);
  212. until (OK=false) or (I>=B.Count) or (Mode<>0);
  213. OK:=Mode<>0;
  214. VESASearchMode:=OK;
  215. end;
  216. function VESAGetOemString: string;
  217. var OK: boolean;
  218. VI: TVESAInfoBlock;
  219. S: array[0..256] of char;
  220. begin
  221. FillChar(S,SizeOf(S),0);
  222. OK:=VESAGetInfo(VI);
  223. if OK then
  224. OK:=MoveDosToPM(VI.OemString,@S,sizeof(S));
  225. VESAGetOemString:=StrPas(@S);
  226. end;
  227. function VESAGetModeInfo(Mode: word; var B: TVESAModeInfoBlock): boolean;
  228. var r : registers;
  229. M : MemPtr;
  230. OK: boolean;
  231. begin
  232. r.ah:=$4f; r.al:=$01; r.cx:=Mode;
  233. GetDosMem(M,sizeof(B));
  234. r.es:=M.DosSeg; r.di:=M.DosOfs; {r.ds:=r.es;}
  235. realintr($10,r);
  236. M.MoveDataFrom(sizeof(B),B);
  237. FreeDosMem(M);
  238. OK:=(r.ax=$004f);
  239. VESAGetModeInfo:=OK;
  240. end;
  241. function RegisterVesaVideoMode(Mode : word) : boolean;
  242. var B: TVESAModeInfoBlock;
  243. VH : PVesaVideoMode;
  244. DoAdd : boolean;
  245. begin
  246. if not VESAGetModeInfo(Mode,B) then
  247. RegisterVesaVideoMode:=false
  248. else
  249. begin
  250. VH:=VesaVideoModeHead;
  251. DoAdd:=true;
  252. RegisterVesaVideoMode:=false;
  253. while assigned(VH) do
  254. begin
  255. if VH^.mode=mode then
  256. DoAdd:=false;
  257. VH:=VH^.next;
  258. end;
  259. if DoAdd then
  260. begin
  261. New(VH);
  262. VH^.next:=VesaVideoModeHead;
  263. VH^.mode:=mode;
  264. VH^.IsGraphic:=(B.Attributes and vesa_vma_GraphicsMode)<>0;
  265. VH^.v.color:=(B.Attributes and vesa_vma_ColorMode)<>0;
  266. if VH^.IsGraphic then
  267. begin
  268. VH^.v.col:=B.XResolution div 8;
  269. VH^.v.row:=B.YResolution div 8;
  270. end
  271. else
  272. begin
  273. VH^.v.col:=B.XResolution;
  274. VH^.v.row:=B.YResolution;
  275. end;
  276. VH^.VideoIndex:=VesaRegisteredModes;
  277. Inc(VesaRegisteredModes);
  278. RegisterVesaVideoMode:=true;
  279. VesaVideoModeHead:=VH;
  280. end;
  281. end;
  282. end;
  283. function VESASetMode(Mode: word): boolean;
  284. var r: registers;
  285. OK: boolean;
  286. begin
  287. r.ah:=$4f; r.al:=$02; r.bx:=Mode;
  288. dos.intr($10,r);
  289. OK:=(r.ax=$004f);
  290. VESASetMode:=OK;
  291. end;
  292. function VESAGetMode(var Mode: word): boolean;
  293. var r : registers;
  294. OK: boolean;
  295. begin
  296. r.ah:=$4f; r.al:=$03;
  297. dos.intr($10,r);
  298. OK:=(r.ax=$004f);
  299. if OK then Mode:=r.bx;
  300. VESAGetMode:=OK;
  301. end;
  302. function VESASelectMemoryWindow(Window: byte; Position: word): boolean;
  303. var r : registers;
  304. OK : boolean;
  305. begin
  306. r.ah:=$4f; r.al:=$05; r.bh:=0; r.bl:=Window; r.dx:=Position;
  307. dos.intr($10,r);
  308. OK:=(r.ax=$004f);
  309. VESASelectMemoryWindow:=OK;
  310. end;
  311. function VESAReturnMemoryWindow(Window: byte; var Position: word): boolean;
  312. var r : registers;
  313. OK : boolean;
  314. begin
  315. r.ah:=$4f; r.al:=$05; r.bh:=1; r.bl:=Window;
  316. dos.intr($10,r);
  317. OK:=(r.ax=$004f);
  318. if OK then Position:=r.dx;
  319. VESAReturnMemoryWindow:=OK;
  320. end;
  321. function VESAInit: boolean;
  322. var OK: boolean;
  323. VI: TVESAInfoBlock;
  324. begin
  325. OK:=VESAGetInfo(VI);
  326. if OK then
  327. VESAInit:=OK;
  328. end;
  329. {$ifdef FPC}
  330. Function VesaGetVideoModeData (Index : Word; Var Data : TVideoMode) : boolean;
  331. Var
  332. PrevCount : word;
  333. VH : PVesaVideoMode;
  334. begin
  335. PrevCount:=SysGetVideoModeCount();
  336. VesaGetVideoModeData:=(Index<PrevCount);
  337. If VesaGetVideoModeData then
  338. begin
  339. VesaGetVideoModeData:=SysGetVideoModeData(Index,Data);
  340. exit;
  341. end;
  342. VesaGetVideoModeData:=(Index-PrevCount)<VesaRegisteredModes;
  343. If VesaGetVideoModeData then
  344. begin
  345. VH:=VesaVideoModeHead;
  346. while assigned(VH) and (VH^.VideoIndex<>Index-PrevCount) do
  347. VH:=VH^.next;
  348. if assigned(VH) then
  349. Data:=VH^.v
  350. else
  351. VesaGetVideoModeData:=false;
  352. end;
  353. end;
  354. function SetVESAMode(const VideoMode: TVideoMode): Boolean;
  355. var
  356. res : boolean;
  357. VH : PVesaVideoMode;
  358. begin
  359. res:=false;
  360. VH:=VesaVideoModeHead;
  361. while assigned(VH) do
  362. begin
  363. if (VideoMode.col=VH^.v.col) and
  364. (VideoMode.row=VH^.v.row) and
  365. (VideoMode.color=VH^.v.color) then
  366. begin
  367. {$ifdef TESTGRAPHIC}
  368. if VH^.IsGraphic then
  369. begin
  370. if IsGraphicMode then
  371. CloseGraph;
  372. GraphDriver:=Graph.Vesa;
  373. if (VideoMode.col = 100) and (VideoMode.row = 75) then
  374. GraphMode:=m800x600x256
  375. else if (VideoMode.col = 80) and (VideoMode.row = 60) then
  376. GraphMode:=m640x480x256
  377. else if (VideoMode.col = 128) and (VideoMode.row = 96) then
  378. GraphMode:=m1024x768x256
  379. else
  380. GraphMode:=Graph.Detect;
  381. InitGraph(GraphDriver,GraphMode,'');
  382. res:=(GraphResult=grOK);
  383. if not res then
  384. begin
  385. SetVesaMode:=false;
  386. exit;
  387. end;
  388. end
  389. else
  390. {$endif TESTGRAPHIC}
  391. res:=VESASetMode(VH^.mode);
  392. if res then
  393. begin
  394. ScreenWidth:=VideoMode.Col;
  395. ScreenHeight:=VideoMode.Row;
  396. ScreenColor:=VideoMode.Color;
  397. {$ifdef TESTGRAPHIC}
  398. IsGraphicMode:=VH^.IsGraphic;
  399. FirstCallAfterSetVesaMode:=true;
  400. LastCursorX:=$ffff;
  401. LastCursorY:=$ffff;
  402. LastCursorType:=crHidden;
  403. if IsGraphicMode then
  404. DoCustomMouse(false)
  405. else
  406. {$endif TESTGRAPHIC}
  407. DoCustomMouse(true);
  408. end;
  409. end;
  410. if res then
  411. begin
  412. SetVesaMode:=true;
  413. exit;
  414. end;
  415. VH:=VH^.next;
  416. end;
  417. SetVESAMode:=SysSetVideoMode(VideoMode);
  418. end;
  419. procedure VesaSetCursorPos(NewCursorX, NewCursorY: Word);
  420. begin
  421. {$ifdef TESTGRAPHIC}
  422. if not IsGraphicMode then
  423. {$endif TESTGRAPHIC}
  424. begin
  425. SysSetCursorPos(NewCursorX,NewCursorY);
  426. exit;
  427. end;
  428. {$ifdef TESTGRAPHIC}
  429. if (NewCursorX<>LastCursorX) or (NewCursorY<>LastCursorY) then
  430. begin
  431. Case GetCursorType of
  432. crHidden : ;
  433. crUnderLine :
  434. Begin
  435. PutImage(LastCursorX*8,LastCursorY*8+7,UnderLineImage,XORPut);
  436. PutImage(NewCursorX*8,NewCursorY*8+7,UnderLineImage,XORPut);
  437. End;
  438. crBlock :
  439. Begin
  440. PutImage(LastCursorX*8,LastCursorY*8,BlockImage,XORPut);
  441. PutImage(NewCursorX*8,NewCursorY*8,BlockImage,XORPut);
  442. End;
  443. crHalfBlock :
  444. Begin
  445. PutImage(LastCursorX*8,LastCursorY*8+4,HalfBlockImage,XORPut);
  446. PutImage(NewCursorX*8,NewCursorY*8+4,HalfBlockImage,XORPut);
  447. End;
  448. end;
  449. LastCursorX:=NewCursorX;
  450. LastCursorY:=NewCursorY;
  451. end;
  452. {$endif TESTGRAPHIC}
  453. end;
  454. procedure VesaSetCursorType(NewType : Word);
  455. begin
  456. {$ifdef TESTGRAPHIC}
  457. if not IsGraphicMode then
  458. {$endif TESTGRAPHIC}
  459. begin
  460. SysSetCursorType(NewType);
  461. exit;
  462. end;
  463. {$ifdef TESTGRAPHIC}
  464. if (NewType<>LastCursorType) then
  465. begin
  466. Case LastCursorType of
  467. crHidden : ;
  468. crUnderLine :
  469. Begin
  470. PutImage(LastCursorX*8,LastCursorY*8+7,UnderLineImage,XORPut);
  471. End;
  472. crBlock :
  473. Begin
  474. PutImage(LastCursorX*8,LastCursorY*8,BlockImage,XORPut);
  475. End;
  476. crHalfBlock :
  477. Begin
  478. PutImage(LastCursorX*8,LastCursorY*8+4,HalfBlockImage,XORPut);
  479. End;
  480. end;
  481. SysSetCursorType(NewType);
  482. Case NewType of
  483. crHidden : ;
  484. crUnderLine :
  485. Begin
  486. PutImage(LastCursorX*8,LastCursorY*8+7,UnderLineImage,XORPut);
  487. End;
  488. crBlock :
  489. Begin
  490. PutImage(LastCursorX*8,LastCursorY*8,BlockImage,XORPut);
  491. End;
  492. crHalfBlock :
  493. Begin
  494. PutImage(LastCursorX*8,LastCursorY*8+4,HalfBlockImage,XORPut);
  495. End;
  496. end;
  497. LastCursorType:=NewType;
  498. end;
  499. {$endif TESTGRAPHIC}
  500. end;
  501. procedure VesaUpdateScreen(Force: Boolean);
  502. {$ifdef TESTGRAPHIC}
  503. var
  504. StoreDrawTextBackground,
  505. MustUpdate : boolean;
  506. x,y : longint;
  507. w, prevcolor,
  508. prevbkcolor, StoreCursorType : word;
  509. Color,BkCol,Col : byte;
  510. Ch : char;
  511. {$endif TESTGRAPHIC}
  512. begin
  513. {$ifdef TESTGRAPHIC}
  514. if not IsGraphicMode then
  515. {$endif TESTGRAPHIC}
  516. begin
  517. SysUpdateScreen(Force);
  518. exit;
  519. end;
  520. {$ifdef TESTGRAPHIC}
  521. if FirstCallAfterSetVesaMode then
  522. begin
  523. { Make sure to redraw all }
  524. Fillchar(OldVideoBuf^,VideoBufSize,#0);
  525. FirstCallAfterSetVesaMode:=false;
  526. end;
  527. if not force then
  528. begin
  529. MustUpdate:=false;
  530. asm
  531. movl VideoBuf,%esi
  532. movl OldVideoBuf,%edi
  533. movl VideoBufSize,%ecx
  534. shrl $2,%ecx
  535. repe
  536. cmpsl
  537. setne MustUpdate
  538. end;
  539. end;
  540. StoreDrawTextBackground:=DrawTextBackground;
  541. DrawTextBackground:=true;
  542. if Force or MustUpdate then
  543. begin
  544. PrevColor:=GetColor;
  545. PrevBkColor:=GetBkColor;
  546. for y:=0 to ScreenHeight-1 do
  547. for x:=0 to Screenwidth-1 do
  548. begin
  549. w:=VideoBuf^[x+y*ScreenWidth];
  550. if Force or
  551. (w<>OldVideoBuf^[x+y*ScreenWidth]) then
  552. Begin
  553. Color:=w shr 8;
  554. Ch:=chr(w and $ff);
  555. Col:=Color and $f;
  556. if (Col = 0) and (GetMaxColor=255) then
  557. Col:=255;
  558. SetColor(Col);
  559. BkCol:=(Color shr 4) and 7;
  560. if (BkCol = 0) and (GetMaxColor=255) then
  561. BkCol:=255;
  562. SetBkColor(BkCol);
  563. if (x=LastCursorX) and (Y=LastCursorY) then
  564. begin
  565. StoreCursorType:=LastCursorType;
  566. VesaSetCursorType(crHidden);
  567. end;
  568. OutTextXY(x*8,y*8,Ch);
  569. if (x=LastCursorX) and (Y=LastCursorY) then
  570. VesaSetCursorType(StoreCursorType);
  571. if not force then
  572. OldVideoBuf^[x+y*ScreenWidth]:=w;
  573. End;
  574. end;
  575. if Force then
  576. move(videobuf^,oldvideobuf^,
  577. VideoBufSize);
  578. SetColor(PrevColor);
  579. SetBkColor(GetBkColor);
  580. end;
  581. DrawTextBackground:=StoreDrawTextBackground;
  582. {$endif TESTGRAPHIC}
  583. end;
  584. procedure VesaDoneVideo;
  585. begin
  586. {$ifdef TESTGRAPHIC}
  587. if IsGraphicMode then
  588. begin
  589. CloseGraph;
  590. IsGraphicMode:=false;
  591. end;
  592. {$endif TESTGRAPHIC}
  593. SysDoneVideo();
  594. end;
  595. procedure VesaInitVideo;
  596. begin
  597. {$ifdef TESTGRAPHIC}
  598. if IsGraphicMode then
  599. begin
  600. SysInitVideo();
  601. InitGraph(GraphDriver,GraphMode,'');
  602. end
  603. else
  604. {$endif TESTGRAPHIC}
  605. SysInitVideo();
  606. end;
  607. Function VesaGetVideoModeCount : Word;
  608. begin
  609. VesaGetVideoModeCount:=SysGetVideoModeCount()+VesaRegisteredModes;
  610. end;
  611. Procedure FreeVesaModes;
  612. var
  613. VH : PVesaVideoMode;
  614. begin
  615. VH:=VesaVideoModeHead;
  616. While assigned(VH) do
  617. begin
  618. VesaVideoModeHead:=VH^.Next;
  619. FreeMem(VH,Sizeof(TVesaVideoMode));
  620. VH:=VesaVideoModeHead;
  621. end;
  622. end;
  623. Var
  624. Driver : TVideoDriver;
  625. {$ifdef TESTGRAPHIC}
  626. i : longint;
  627. {$endif TESTGRAPHIC}
  628. BEGIN
  629. { Get the videodriver to be used }
  630. GetVideoDriver (Driver);
  631. { Change needed functions }
  632. SysGetVideoModeCount:=Driver.GetVideoModeCount;
  633. Driver.GetVideoModeCount:=@VesaGetVideoModeCount;
  634. SysGetVideoModeData:=Driver.GetVideoModeData;
  635. Driver.GetVideoModeData:=@VesaGetVideoModeData;
  636. SysSetVideoMode:=Driver.SetVideoMode;
  637. Driver.SetVideoMode:=@SetVESAMode;
  638. SysSetCursorPos:=Driver.SetCursorPos;
  639. Driver.SetCursorPos:=@VESASetCursorPos;
  640. SysSetCursorType:=Driver.SetCursorType;
  641. Driver.SetCursorType:=@VESASetCursorType;
  642. SysUpdateScreen:=Driver.UpdateScreen;
  643. Driver.UpdateScreen:=@VesaUpdateScreen;
  644. SysDoneVideo:=Driver.DoneDriver;
  645. Driver.DoneDriver:=@VesaDoneVideo;
  646. SysInitVideo:=Driver.InitDriver;
  647. Driver.InitDriver:=@VesaInitVideo;
  648. {$ifdef TESTGRAPHIC}
  649. BlockImage.width:=7;
  650. BlockImage.height:=7;
  651. For i:=0 to 8*8-1 do
  652. BlockImage.colors[i]:=White;
  653. HalfBlockImage:=BlockImage;
  654. HalfBlockImage.height:=3;
  655. UnderLineImage:=BlockImage;
  656. UnderLineImage.height:=0;
  657. {$endif TESTGRAPHIC}
  658. SetVideoDriver (Driver);
  659. {$endif FPC}
  660. END.