graph.pp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Florian Klaempfl
  5. This file implements the linux GGI support for the graph unit
  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 Graph;
  13. interface
  14. {$i graphh.inc}
  15. Const
  16. { Supported modes }
  17. {(sg) GTEXT deactivated because we need mode #0 as default mode}
  18. {GTEXT = 0; Compatible with VGAlib v1.2 }
  19. G320x200x16 = 1;
  20. G640x200x16 = 2;
  21. G640x350x16 = 3;
  22. G640x480x16 = 4;
  23. G320x200x256 = 5;
  24. G320x240x256 = 6;
  25. G320x400x256 = 7;
  26. G360x480x256 = 8;
  27. G640x480x2 = 9;
  28. G640x480x256 = 10;
  29. G800x600x256 = 11;
  30. G1024x768x256 = 12;
  31. G1280x1024x256 = 13; { Additional modes. }
  32. G320x200x32K = 14;
  33. G320x200x64K = 15;
  34. G320x200x16M = 16;
  35. G640x480x32K = 17;
  36. G640x480x64K = 18;
  37. G640x480x16M = 19;
  38. G800x600x32K = 20;
  39. G800x600x64K = 21;
  40. G800x600x16M = 22;
  41. G1024x768x32K = 23;
  42. G1024x768x64K = 24;
  43. G1024x768x16M = 25;
  44. G1280x1024x32K = 26;
  45. G1280x1024x64K = 27;
  46. G1280x1024x16M = 28;
  47. G800x600x16 = 29;
  48. G1024x768x16 = 30;
  49. G1280x1024x16 = 31;
  50. G720x348x2 = 32; { Hercules emulation mode }
  51. G320x200x16M32 = 33; { 32-bit per pixel modes. }
  52. G640x480x16M32 = 34;
  53. G800x600x16M32 = 35;
  54. G1024x768x16M32 = 36;
  55. G1280x1024x16M32 = 37;
  56. { additional resolutions }
  57. G1152x864x16 = 38;
  58. G1152x864x256 = 39;
  59. G1152x864x32K = 40;
  60. G1152x864x64K = 41;
  61. G1152x864x16M = 42;
  62. G1152x864x16M32 = 43;
  63. G1600x1200x16 = 44;
  64. G1600x1200x256 = 45;
  65. G1600x1200x32K = 46;
  66. G1600x1200x64K = 47;
  67. G1600x1200x16M = 48;
  68. G1600x1200x16M32 = 49;
  69. implementation
  70. uses
  71. linux;
  72. const
  73. InternalDriverName = 'LinuxVGA';
  74. {$i graph.inc}
  75. type
  76. PByte = ^Byte;
  77. PLongInt = ^LongInt;
  78. PByteArray = ^TByteArray;
  79. TByteArray = array [0..MAXINT - 1] of Byte;
  80. { ---------------------------------------------------------------------
  81. SVGA bindings.
  82. ---------------------------------------------------------------------}
  83. { Link with VGA, gl and c libraries }
  84. {$linklib vga}
  85. {$linklib c}
  86. Const
  87. { Text }
  88. WRITEMODE_OVERWRITE = 0;
  89. WRITEMODE_MASKED = 1;
  90. FONT_EXPANDED = 0;
  91. FONT_COMPRESSED = 2;
  92. { Types }
  93. type
  94. pvga_modeinfo = ^vga_modeinfo;
  95. vga_modeinfo = record
  96. width,
  97. height,
  98. bytesperpixel,
  99. colors,
  100. linewidth, { scanline width in bytes }
  101. maxlogicalwidth, { maximum logical scanline width }
  102. startaddressrange, { changeable bits set }
  103. maxpixels, { video memory / bytesperpixel }
  104. haveblit, { mask of blit functions available }
  105. flags: Longint; { other flags }
  106. { Extended fields: }
  107. chiptype, { Chiptype detected }
  108. memory, { videomemory in KB }
  109. linewidth_unit: Longint; { Use only a multiple of this as parameter for set_displaystart }
  110. linear_aperture: PChar; { points to mmap secondary mem aperture of card }
  111. aperture_size: Longint; { size of aperture in KB if size>=videomemory.}
  112. set_aperture_page: procedure (page: Longint);
  113. { if aperture_size<videomemory select a memory page }
  114. extensions: Pointer; { points to copy of eeprom for mach32 }
  115. { depends from actual driver/chiptype.. etc. }
  116. end;
  117. PGraphicsContext = ^TGraphicsContext;
  118. TGraphicsContext = record
  119. ModeType: Byte;
  120. ModeFlags: Byte;
  121. Dummy: Byte;
  122. FlipPage: Byte;
  123. Width: LongInt;
  124. Height: LongInt;
  125. BytesPerPixel: LongInt;
  126. Colors: LongInt;
  127. BitsPerPixel: LongInt;
  128. ByteWidth: LongInt;
  129. VBuf: pointer;
  130. Clip: LongInt;
  131. ClipX1: LongInt;
  132. ClipY1: LongInt;
  133. ClipX2: LongInt;
  134. ClipY2: LongInt;
  135. ff: pointer;
  136. end;
  137. Const
  138. GLASTMODE = 49;
  139. ModeNames : Array[0..GLastMode] of string [18] =
  140. ('Text',
  141. 'G320x200x16',
  142. 'G640x200x16',
  143. 'G640x350x16',
  144. 'G640x480x16',
  145. 'G320x200x256',
  146. 'G320x240x256',
  147. 'G320x400x256',
  148. 'G360x480x256',
  149. 'G640x480x2',
  150. 'G640x480x256',
  151. 'G800x600x256',
  152. 'G1024x768x256',
  153. 'G1280x1024x256',
  154. 'G320x200x32K',
  155. 'G320x200x64K',
  156. 'G320x200x16M',
  157. 'G640x480x32K',
  158. 'G640x480x64K',
  159. 'G640x480x16M',
  160. 'G800x600x32K',
  161. 'G800x600x64K',
  162. 'G800x600x16M',
  163. 'G1024x768x32K',
  164. 'G1024x768x64K',
  165. 'G1024x768x16M',
  166. 'G1280x1024x32K',
  167. 'G1280x1024x64K',
  168. 'G1280x1024x16M',
  169. 'G800x600x16',
  170. '1024x768x16',
  171. '1280x1024x16',
  172. 'G720x348x2',
  173. 'G320x200x16M32',
  174. 'G640x480x16M32',
  175. 'G800x600x16M32',
  176. 'G1024x768x16M32',
  177. 'G1280x1024x16M32',
  178. 'G1152x864x16',
  179. 'G1152x864x256',
  180. 'G1152x864x32K',
  181. 'G1152x864x64K',
  182. 'G1152x864x16M',
  183. 'G1152x864x16M32',
  184. 'G1600x1200x16',
  185. 'G1600x1200x256',
  186. 'G1600x1200x32K',
  187. 'G1600x1200x64K',
  188. 'G1600x1200x16M',
  189. 'G1600x1200x16M32');
  190. var
  191. PhysicalScreen: PGraphicsContext;
  192. { vga functions }
  193. Function vga_init: Longint; Cdecl; External;
  194. Function vga_hasmode(mode: Longint): Boolean; Cdecl; External;
  195. Function vga_getmodeinfo(mode: Longint): pvga_modeinfo; Cdecl; External;
  196. Function vga_setmode(mode: Longint): Longint; Cdecl; External;
  197. Function vga_getcolors: Longint; cdecl;external;
  198. Function vga_setpalette(index: Longint; red: Longint; green: Longint; blue: Longint) : longint; cdecl;external;
  199. Function vga_getpalette(index: Longint; var red: Longint; var green: Longint; var blue: Longint): Longint; cdecl;external;
  200. Function vga_setegacolor(Color: Longint) : longint; cdecl;external;
  201. Function vga_setcolor(color: Longint): Longint; cdecl;external;
  202. Function vga_drawpixel(x, y: Longint): Longint; cdecl;external;
  203. Function vga_getpixel(x, y: Longint): Longint; cdecl;external;
  204. Function vga_drawline(x1, y1, x2, y2: Longint): Longint; cdecl;external;
  205. function vga_screenoff: Longint; Cdecl; External;
  206. function vga_screenon: Longint; Cdecl; External;
  207. function vga_getgraphmem: PByteArray; cdecl; external;
  208. { ---------------------------------------------------------------------
  209. Required procedures
  210. ---------------------------------------------------------------------}
  211. {$INCLUDE vgagraph16.inc} // Include graphic functions for 16 colours modes
  212. var
  213. LastColor: Integer; {Cache the last set color to improve speed}
  214. procedure SetEGAColor(color: Integer);
  215. begin
  216. if color <> LastColor then begin
  217. LastColor := color;
  218. vga_setegacolor(color);
  219. end;
  220. end;
  221. procedure libvga_savevideostate;
  222. begin
  223. end;
  224. procedure libvga_restorevideostate;
  225. begin
  226. vga_setmode(0);
  227. end;
  228. const
  229. BgiColors: array[0..15] of LongInt
  230. = ($000000, $000020, $002000, $002020,
  231. $200000, $200020, $202000, $303030,
  232. $202020, $00003F, $003F00, $003F3F,
  233. $3F0000, $3F003F, $3F3F00, $3F3F3F);
  234. procedure InitColors;
  235. var
  236. i: Integer;
  237. begin
  238. for i:=0 to 15 do
  239. vga_setpalette(I,BgiColors[i] shr 16,
  240. (BgiColors[i] shr 8) and 255,
  241. BgiColors[i] and 255)
  242. end;
  243. procedure libvga_initmodeproc;
  244. Var Nrcolors : Longint;
  245. begin
  246. vga_setmode(IntCurrentMode);
  247. vga_screenon;
  248. VidMem := vga_getgraphmem;
  249. nrColors:=vga_getcolors;
  250. if (nrColors=16) or (nrcolors=256) then
  251. InitColors;
  252. end;
  253. Function ClipCoords (Var X,Y : Integer) : Boolean;
  254. { Adapt to viewport, return TRUE if still in viewport,
  255. false if outside viewport}
  256. begin
  257. X:= X + StartXViewPort;
  258. Y:= Y + StartYViewPort;
  259. ClipCoords:=Not ClipPixels;
  260. if ClipPixels then
  261. Begin
  262. ClipCoords:=(X < StartXViewPort) or (X > (StartXViewPort + ViewWidth));
  263. ClipCoords:=ClipCoords or
  264. ((Y < StartYViewPort) or (Y > (StartYViewPort + ViewHeight)));
  265. ClipCoords:=Not ClipCoords;
  266. end;
  267. end;
  268. procedure libvga_directpixelproc(X,Y: Integer);
  269. Var Color : Word;
  270. begin
  271. case CurrentWriteMode of
  272. XORPut:
  273. begin
  274. { getpixel wants local/relative coordinates }
  275. Color := GetPixel(x-StartXViewPort,y-StartYViewPort);
  276. Color := CurrentColor Xor Color;
  277. end;
  278. OrPut:
  279. begin
  280. { getpixel wants local/relative coordinates }
  281. Color := GetPixel(x-StartXViewPort,y-StartYViewPort);
  282. Color := CurrentColor Or Color;
  283. end;
  284. AndPut:
  285. begin
  286. { getpixel wants local/relative coordinates }
  287. Color := GetPixel(x-StartXViewPort,y-StartYViewPort);
  288. Color := CurrentColor And Color;
  289. end;
  290. NotPut:
  291. begin
  292. Color := Not Color;
  293. end
  294. else
  295. Color:=CurrentColor;
  296. end;
  297. SetEGAColor(Color);
  298. vga_drawpixel(x, y);
  299. end;
  300. procedure libvga_putpixelproc(X,Y: Integer; Color: Word);
  301. begin
  302. If Not ClipCoords(X,Y) Then exit;
  303. SetEGAColor(Color);
  304. vga_drawpixel(x, y);
  305. end;
  306. function libvga_getpixelproc (X,Y: Integer): word;
  307. begin
  308. ClipCoords(X,Y);
  309. libvga_getpixelproc:=vga_getpixel(x, y);
  310. end;
  311. procedure libvga_clrviewproc;
  312. Var I,Xmax : longint;
  313. begin
  314. SetEGAColor(CurrentBkColor);
  315. Xmax:=StartXViewPort+ViewWidth-1;
  316. For i:=StartYViewPort to StartYViewPort+ViewHeight-1 do
  317. vga_drawline(StartXViewPort,I,Xmax,I);
  318. end;
  319. { Bitmap utilities }
  320. type
  321. PBitmap = ^TBitmap;
  322. TBitmap = record
  323. Width, Height: Integer;
  324. Data: record end;
  325. end;
  326. procedure libvga_putimageproc (X,Y: Integer; var Bitmap; BitBlt: Word);
  327. begin
  328. {
  329. With TBitMap(BitMap) do
  330. gl_putbox(x, y, width, height, @Data);
  331. }
  332. end;
  333. procedure libvga_getimageproc (X1,Y1,X2,Y2: Integer; Var Bitmap);
  334. begin
  335. { with TBitmap(Bitmap) do
  336. begin
  337. Width := x2 - x1 + 1;
  338. Height := y2 - y1 + 1;
  339. gl_getbox(x1,y1, x2 - x1 + 1, y2 - y1 + 1, @Data);
  340. end;
  341. }
  342. end;
  343. function libvga_imagesizeproc (X1,Y1,X2,Y2: Integer): longint;
  344. begin
  345. libvga_imagesizeproc := SizeOf(TBitmap) + (x2 - x1 + 1) * (y2 - y1 + 1) * PhysicalScreen^.BytesPerPixel;
  346. end;
  347. procedure libvga_hlineproc (x, x2,y : integer);
  348. begin
  349. end;
  350. procedure libvga_vlineproc (x,y,y2: integer);
  351. begin
  352. end;
  353. procedure libvga_patternlineproc (x1,x2,y: integer);
  354. begin
  355. end;
  356. procedure libvga_ellipseproc (X,Y: Integer;XRadius: word;
  357. YRadius:word; stAngle,EndAngle: word; fp: PatternLineProc);
  358. begin
  359. end;
  360. procedure libvga_lineproc (X1, Y1, X2, Y2 : Integer);
  361. begin
  362. end;
  363. procedure libvga_getscanlineproc (X1,X2,Y : integer; var data);
  364. begin
  365. end;
  366. procedure libvga_setactivepageproc (page: word);
  367. begin
  368. end;
  369. procedure libvga_setvisualpageproc (page: word);
  370. begin
  371. end;
  372. procedure libvga_savestateproc;
  373. begin
  374. end;
  375. procedure libvga_restorestateproc;
  376. begin
  377. end;
  378. procedure libvga_setrgbpaletteproc(ColorNum, RedValue, GreenValue, BlueValue: Integer);
  379. begin
  380. vga_setpalette(ColorNum,RedValue shr 2,GreenValue shr 2,BlueValue shr 2);
  381. end;
  382. procedure libvga_getrgbpaletteproc (ColorNum: integer;
  383. var RedValue, GreenValue, BlueValue: Integer);
  384. Var R,G,B : longint;
  385. begin
  386. vga_getpalette(ColorNum,R,G,B);
  387. RedValue:=R * 255 div 63;
  388. GreenValue:=G * 255 div 63;
  389. BlueValue:=B * 255 div 63;
  390. end;
  391. {************************************************************************}
  392. {* General routines *}
  393. {************************************************************************}
  394. procedure CloseGraph;
  395. Begin
  396. If not isgraphmode then
  397. begin
  398. _graphresult := grnoinitgraph;
  399. exit
  400. end;
  401. RestoreVideoState;
  402. isgraphmode := false;
  403. end;
  404. function QueryAdapterInfo:PModeInfo;
  405. { This routine returns the head pointer to the list }
  406. { of supported graphics modes. }
  407. { Returns nil if no graphics mode supported. }
  408. { This list is READ ONLY! }
  409. var
  410. mode: TModeInfo;
  411. modeinfo : vga_modeinfo;
  412. i : longint;
  413. begin
  414. QueryAdapterInfo := ModeList;
  415. { If the mode listing already exists... }
  416. { simply return it, without changing }
  417. { anything... }
  418. if assigned(ModeList) then
  419. exit;
  420. SaveVideoState:=libvga_savevideostate;
  421. RestoreVideoState:=libvga_restorevideostate;
  422. vga_init;
  423. For I:=0 to GLastMode do
  424. begin
  425. If vga_hasmode(I) then
  426. begin
  427. ModeInfo:=vga_getmodeinfo(i)^;
  428. InitMode(Mode);
  429. With Mode do
  430. begin
  431. ModeNumber:=I;
  432. ModeName:=ModeNames[i];
  433. // Pretend we are VGA always.
  434. DriverNumber := VGA;
  435. // MaxX is number of pixels in X direction - 1
  436. MaxX:=ModeInfo.Width-1;
  437. // same for MaxY
  438. MaxY:=ModeInfo.Height-1;
  439. MaxColor := ModeInfo.colors;
  440. PaletteSize := MaxColor;
  441. HardwarePages := 0;
  442. // necessary hooks ...
  443. if (MaxColor = 16) and (LongInt(MaxX) * LongInt(MaxY) < 65536*4*2) then
  444. begin
  445. // Use optimized graphics routines for 4 bit EGA/VGA modes
  446. ScrWidth := MaxX div 8;
  447. DirectPutPixel := @DirectPutPixel16;
  448. PutPixel := @PutPixel16;
  449. GetPixel := @GetPixel16;
  450. HLine := @HLine16;
  451. VLine := @VLine16;
  452. GetScanLine := @GetScanLine16;
  453. end
  454. else
  455. begin
  456. DirectPutPixel := @libvga_DirectPixelProc;
  457. GetPixel := @libvga_GetPixelProc;
  458. PutPixel := @libvga_PutPixelProc;
  459. { May be implemented later:
  460. HLine := @libvga_HLineProc;
  461. VLine := @libvga_VLineProc;
  462. GetScanLine := @libvga_GetScanLineProc;}
  463. ClearViewPort := @libvga_ClrViewProc;
  464. end;
  465. SetRGBPalette := @libvga_SetRGBPaletteProc;
  466. GetRGBPalette := @libvga_GetRGBPaletteProc;
  467. { These are not really implemented yet:
  468. PutImage := @libvga_PutImageProc;
  469. GetImage := @libvga_GetImageProc;}
  470. ImageSize := @libvga_ImageSizeProc;
  471. { Add later maybe ?
  472. SetVisualPage := SetVisualPageProc;
  473. SetActivePage := SetActivePageProc;
  474. Line := @libvga_LineProc;
  475. InternalEllipse:= @libvga_EllipseProc;
  476. PatternLine := @libvga_PatternLineProc;
  477. }
  478. InitMode := @libvga_InitModeProc;
  479. end;
  480. AddMode(Mode);
  481. end;
  482. end;
  483. end;
  484. begin
  485. InitializeGraph;
  486. end.
  487. {
  488. $Log$
  489. Revision 1.13 2000-03-25 19:12:00 florian
  490. * fixed values of MaxX and MaxY
  491. Revision 1.12 2000/03/19 11:20:14 peter
  492. * graph unit include is now independent and the dependent part
  493. is now in graph.pp
  494. * ggigraph unit for linux added
  495. }