graph.pp 15 KB

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