ggigraph.pp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  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 GGIGraph;
  13. interface
  14. { objfpc is needed for array of const support }
  15. {$mode objfpc}
  16. {$i graphh.inc}
  17. Const
  18. { Supported modes }
  19. {(sg) GTEXT deactivated because we need mode #0 as default mode}
  20. {GTEXT = 0; Compatible with VGAlib v1.2 }
  21. G320x200x16 = 1;
  22. G640x200x16 = 2;
  23. G640x350x16 = 3;
  24. G640x480x16 = 4;
  25. G320x200x256 = 5;
  26. G320x240x256 = 6;
  27. G320x400x256 = 7;
  28. G360x480x256 = 8;
  29. G640x480x2 = 9;
  30. G640x480x256 = 10;
  31. G800x600x256 = 11;
  32. G1024x768x256 = 12;
  33. G1280x1024x256 = 13; { Additional modes. }
  34. G320x200x32K = 14;
  35. G320x200x64K = 15;
  36. G320x200x16M = 16;
  37. G640x480x32K = 17;
  38. G640x480x64K = 18;
  39. G640x480x16M = 19;
  40. G800x600x32K = 20;
  41. G800x600x64K = 21;
  42. G800x600x16M = 22;
  43. G1024x768x32K = 23;
  44. G1024x768x64K = 24;
  45. G1024x768x16M = 25;
  46. G1280x1024x32K = 26;
  47. G1280x1024x64K = 27;
  48. G1280x1024x16M = 28;
  49. G800x600x16 = 29;
  50. G1024x768x16 = 30;
  51. G1280x1024x16 = 31;
  52. G720x348x2 = 32; { Hercules emulation mode }
  53. G320x200x16M32 = 33; { 32-bit per pixel modes. }
  54. G640x480x16M32 = 34;
  55. G800x600x16M32 = 35;
  56. G1024x768x16M32 = 36;
  57. G1280x1024x16M32 = 37;
  58. { additional resolutions }
  59. G1152x864x16 = 38;
  60. G1152x864x256 = 39;
  61. G1152x864x32K = 40;
  62. G1152x864x64K = 41;
  63. G1152x864x16M = 42;
  64. G1152x864x16M32 = 43;
  65. G1600x1200x16 = 44;
  66. G1600x1200x256 = 45;
  67. G1600x1200x32K = 46;
  68. G1600x1200x64K = 47;
  69. G1600x1200x16M = 48;
  70. G1600x1200x16M32 = 49;
  71. implementation
  72. uses
  73. linux;
  74. const
  75. InternalDriverName = 'LinuxGGI';
  76. {$i graph.inc}
  77. { ---------------------------------------------------------------------
  78. GGI bindings [(c) 1999 Sebastian Guenther]
  79. ---------------------------------------------------------------------}
  80. {$LINKLIB c}
  81. {$PACKRECORDS C}
  82. const
  83. GLASTMODE = 49;
  84. ModeNames: array[0..GLastMode] of PChar =
  85. ('[]', {Let GGI choose a default mode}
  86. 'S320x200[GT_4BIT]',
  87. 'S640x200[GT_4BIT]',
  88. 'S640x350[GT_4BIT]',
  89. 'S640x480[GT_4BIT]',
  90. 'S320x200[GT_8BIT]',
  91. 'S320x240[GT_8BIT]',
  92. 'S320x400[GT_8BIT]',
  93. 'S360x480[GT_8BIT]',
  94. 'S640x480x[GT_1BIT]',
  95. 'S640x480[GT_8BIT]',
  96. 'S800x600[GT_8BIT]',
  97. 'S1024x768[GT_8BIT]',
  98. 'S1280x1024[GT_8BIT]',
  99. 'S320x200[GT_15BIT]',
  100. 'S320x200[GT_16BIT]',
  101. 'S320x200[GT_24BIT]',
  102. 'S640x480[GT_15BIT]',
  103. 'S640x480[GT_16BIT]',
  104. 'S640x480[GT_24BIT]',
  105. 'S800x600[GT_15BIT]',
  106. 'S800x600[GT_16BIT]',
  107. 'S800x600[GT_24BIT]',
  108. 'S1024x768[GT_15BIT]',
  109. 'S1024x768[GT_16BIT]',
  110. 'S1024x768[GT_24BIT]',
  111. 'S1280x1024[GT_15BIT]',
  112. 'S1280x1024[GT_16BIT]',
  113. 'S1280x1024[GT_24BIT]',
  114. 'S800x600[GT_4BIT]',
  115. 'S1024x768[GT_4BIT]',
  116. 'S1280x1024[GT_4BIT]',
  117. 'S720x348x[GT_1BIT]',
  118. 'S320x200[GT_32BIT]',
  119. 'S640x480[GT_32BIT]',
  120. 'S800x600[GT_32BIT]',
  121. 'S1024x768[GT_32BIT]',
  122. 'S1280x1024[GT_32BIT]',
  123. 'S1152x864[GT_4BIT]',
  124. 'S1152x864[gt_8BIT]',
  125. 'S1152x864[GT_15BIT]',
  126. 'S1152x864[GT_16BIT]',
  127. 'S1152x864[GT_24BIT]',
  128. 'S1152x864[GT_32BIT]',
  129. 'S1600x1200[GT_4BIT]',
  130. 'S1600x1200[gt_8BIT]',
  131. 'S1600x1200[GT_15BIT]',
  132. 'S1600x1200[GT_16BIT]',
  133. 'S1600x1200[GT_24BIT]',
  134. 'S1600x1200[GT_32BIT]');
  135. type
  136. TGGIVisual = Pointer;
  137. TGGIResource = Pointer;
  138. TGGICoord = record
  139. x, y: SmallInt;
  140. end;
  141. TGGIPixel = LongWord;
  142. PGGIColor = ^TGGIColor;
  143. TGGIColor = record
  144. r, g, b, a: Word;
  145. end;
  146. PGGIClut = ^TGGIClut;
  147. TGGIClut = record
  148. size: SmallInt;
  149. data: PGGIColor;
  150. end;
  151. TGGIGraphType = LongWord;
  152. TGGIAttr = LongWord;
  153. TGGIMode = record // requested by user and changed by driver
  154. Frames: LongInt; // frames needed
  155. Visible: TGGICoord; // vis. pixels, may change slightly
  156. Virt: TGGICoord; // virtual pixels, may change
  157. Size: TGGICoord; // size of visible in mm
  158. GraphType: TGGIGraphType; // which mode ?
  159. dpp: TGGICoord; // dots per pixel
  160. end;
  161. const
  162. libggi = 'ggi';
  163. function ggiInit: Longint; cdecl; external libggi;
  164. procedure ggiExit; cdecl; external libggi;
  165. function ggiOpen(display: PChar; args: Array of const): TGGIVisual; cdecl; external libggi;
  166. function ggiClose(vis: TGGIVisual): Longint; cdecl; external libggi;
  167. function ggiParseMode(s: PChar; var m: TGGIMode): Longint; cdecl; external libggi;
  168. function ggiSetMode(visual: TGGIVisual; var tm: TGGIMode): Longint; cdecl; external libggi;
  169. function ggiGetMode(visual: TGGIVisual; var tm: TGGIMode): Longint; cdecl; external libggi;
  170. function ggiCheckMode(visual: TGGIVisual; var tm: TGGIMode): Longint; cdecl; external libggi;
  171. function ggiMapColor(vis: TGGIVisual; Color: TGGIColor): TGGIPixel; cdecl; external libggi;
  172. function ggiPutPixel(vis: TGGIVisual; x, y: Longint; pixel: TGGIPixel): Longint; cdecl; external libggi;
  173. function ggiGetPixel(vis: TGGIVisual; x, y: Longint; var pixel: TGGIPixel): Longint; cdecl; external libggi;
  174. function ggiDrawBox(vis: TGGIVisual; x, y, w, h: Longint): Longint; cdecl; external libggi;
  175. function ggiPutBox(vis: TGGIVisual; x, y, w, h: Longint; var buffer): Longint; cdecl; external libggi;
  176. function ggiGetBox(vis: TGGIVisual; x, y, w, h: Longint; var buffer): Longint; cdecl; external libggi;
  177. function ggiGetPalette(vis: TGGIVisual; s, len: Longint; var cmap: TGGIColor): Longint; cdecl; external libggi;
  178. function ggiSetPalette(vis: TGGIVisual; s, len: Longint; var cmap: TGGIColor): Longint; cdecl; external libggi;
  179. var
  180. Visual: TGGIVisual;
  181. CurrentMode, OldMode: TGGIMode;
  182. procedure ggi_savevideostate;
  183. begin
  184. ggiGetMode(Visual, OldMode);
  185. end;
  186. procedure ggi_restorevideostate;
  187. begin
  188. ggiSetMode(Visual, OldMode);
  189. end;
  190. const
  191. BgiColors: array[0..15] of TGGIColor = (
  192. (r: $0000; g: $0000; b: $0000; a: 0),
  193. (r: $0000; g: $0000; b: $8000; a: 0),
  194. (r: $0000; g: $8000; b: $0000; a: 0),
  195. (r: $0000; g: $8000; b: $8000; a: 0),
  196. (r: $8000; g: $0000; b: $0000; a: 0),
  197. (r: $8000; g: $0000; b: $8000; a: 0),
  198. (r: $8000; g: $8000; b: $0000; a: 0),
  199. (r: $C000; g: $C000; b: $C000; a: 0),
  200. (r: $8000; g: $8000; b: $8000; a: 0),
  201. (r: $0000; g: $0000; b: $FFFF; a: 0),
  202. (r: $0000; g: $FFFF; b: $0000; a: 0),
  203. (r: $0000; g: $FFFF; b: $FFFF; a: 0),
  204. (r: $FFFF; g: $0000; b: $0000; a: 0),
  205. (r: $FFFF; g: $0000; b: $FFFF; a: 0),
  206. (r: $FFFF; g: $FFFF; b: $0000; a: 0),
  207. (r: $FFFF; g: $FFFF; b: $FFFF; a: 0));
  208. procedure ggi_initmodeproc;
  209. begin
  210. ggiParseMode(ModeNames[IntCurrentMode], CurrentMode);
  211. ggiSetMode(Visual, CurrentMode);
  212. end;
  213. function ClipCoords(var x, y: SmallInt): Boolean;
  214. { Adapt to viewport, return TRUE if still in viewport,
  215. false if outside viewport}
  216. begin
  217. x := x + StartXViewPort;
  218. x := y + StartYViewPort;
  219. ClipCoords := not ClipPixels;
  220. if ClipCoords then begin
  221. ClipCoords := (y < StartXViewPort) or (x > (StartXViewPort + ViewWidth));
  222. ClipCoords := ClipCoords or
  223. ((y < StartYViewPort) or (y > (StartYViewPort + ViewHeight)));
  224. ClipCoords := not ClipCoords;
  225. end;
  226. end;
  227. procedure ggi_directpixelproc(X, Y: smallint);
  228. var
  229. Color, CurCol: TGGIPixel;
  230. begin
  231. CurCol := ggiMapColor(Visual, BgiColors[CurrentColor]);
  232. case CurrentWriteMode of
  233. XORPut: begin
  234. { getpixel wants local/relative coordinates }
  235. ggiGetPixel(Visual, x-StartXViewPort, y-StartYViewPort, Color);
  236. Color := CurCol xor Color;
  237. end;
  238. OrPut: begin
  239. { getpixel wants local/relative coordinates }
  240. ggiGetPixel(Visual, x-StartXViewPort, y-StartYViewPort, Color);
  241. Color := CurCol or Color;
  242. end;
  243. AndPut: begin
  244. { getpixel wants local/relative coordinates }
  245. ggiGetPixel(Visual, x-StartXViewPort, y-StartYViewPort, Color);
  246. Color := CurCol and Color;
  247. end;
  248. NotPut:
  249. Color := not Color;
  250. else
  251. Color := CurCol;
  252. end;
  253. ggiPutPixel(Visual, x, y, Color);
  254. end;
  255. procedure ggi_putpixelproc(X,Y: smallint; Color: Word);
  256. begin
  257. If Not ClipCoords(X,Y) Then exit;
  258. ggiputpixel(Visual,x, y, Color);
  259. end;
  260. function ggi_getpixelproc (X,Y: smallint): word;
  261. Var i : TGGIPixel;
  262. begin
  263. ClipCoords(X,Y);
  264. ggigetpixel(Visual,x, y,I);
  265. ggi_getpixelproc:=i;
  266. end;
  267. procedure ggi_clrviewproc;
  268. begin
  269. ggidrawbox(Visual,StartXViewPort,StartYViewPort,ViewWidth,ViewHeight);
  270. end;
  271. { Bitmap utilities }
  272. type
  273. PBitmap = ^TBitmap;
  274. TBitmap = record
  275. Width, Height: longint;
  276. reserved : longint;
  277. Data: record end;
  278. end;
  279. procedure ggi_putimageproc (X,Y: smallint; var Bitmap; BitBlt: Word);
  280. begin
  281. With TBitMap(BitMap) do
  282. ggiputbox(Visual,x, y, width, height, @Data);
  283. end;
  284. procedure ggi_getimageproc (X1,Y1,X2,Y2: smallint; Var Bitmap);
  285. begin
  286. with TBitmap(Bitmap) do
  287. begin
  288. Width := x2 - x1 + 1;
  289. Height := y2 - y1 + 1;
  290. ggigetbox(Visual,x1,y1, x2 - x1 + 1, y2 - y1 + 1, @Data);
  291. end;
  292. end;
  293. function ggi_imagesizeproc (X1,Y1,X2,Y2: smallint): longint;
  294. begin
  295. // 32 bits per pixel -- change ASAP !!
  296. ggi_imagesizeproc := SizeOf(TBitmap) + (x2 - x1 + 1) * (y2 - y1 + 1) * SizeOF(longint);
  297. end;
  298. procedure ggi_hlineproc (x, x2,y : smallint);
  299. begin
  300. end;
  301. procedure ggi_vlineproc (x,y,y2: smallint);
  302. begin
  303. end;
  304. procedure ggi_patternlineproc (x1,x2,y: smallint);
  305. begin
  306. end;
  307. procedure ggi_ellipseproc (X,Y: smallint;XRadius: word;
  308. YRadius:word; stAngle,EndAngle: word; fp: PatternLineProc);
  309. begin
  310. end;
  311. procedure ggi_lineproc (X1, Y1, X2, Y2 : smallint);
  312. begin
  313. end;
  314. procedure ggi_getscanlineproc (X1, X2, Y : smallint; var data);
  315. begin
  316. end;
  317. procedure ggi_setactivepageproc (page: word);
  318. begin
  319. end;
  320. procedure ggi_setvisualpageproc (page: word);
  321. begin
  322. end;
  323. procedure ggi_savestateproc;
  324. begin
  325. end;
  326. procedure ggi_restorestateproc;
  327. begin
  328. end;
  329. procedure ggi_setrgbpaletteproc(ColorNum, RedValue, GreenValue, BlueValue: smallint);
  330. Var Col : TGGIcolor;
  331. begin
  332. col.r:=redvalue;
  333. col.g:=greenvalue;
  334. col.b:=bluevalue;
  335. ggisetpalette(Visual,ColorNum,1,col);
  336. end;
  337. procedure ggi_getrgbpaletteproc (ColorNum: smallint;
  338. var RedValue, GreenValue, BlueValue: smallint);
  339. Var Col : TGGIColor;
  340. begin
  341. ggigetpalette(Visual,ColorNum,1,col);
  342. RedValue:=Col.R;
  343. GreenValue:=Col.G;
  344. BlueValue:=Col.B;
  345. end;
  346. {************************************************************************}
  347. {* General routines *}
  348. {************************************************************************}
  349. procedure CloseGraph;
  350. begin
  351. if not IsGraphMode then
  352. begin
  353. _graphresult := grnoinitgraph;
  354. exit
  355. end;
  356. RestoreVideoState;
  357. isgraphmode := false;
  358. end;
  359. function QueryAdapterInfo:PModeInfo;
  360. { This routine returns the head pointer to the list }
  361. { of supported graphics modes. }
  362. { Returns nil if no graphics mode supported. }
  363. { This list is READ ONLY! }
  364. var
  365. ModeInfo: TGGIMode;
  366. procedure AddGGIMode(i: smallint); // i is the mode number
  367. var
  368. mode: TModeInfo;
  369. begin
  370. InitMode(Mode);
  371. with Mode do begin
  372. ModeNumber := i;
  373. ModeName := ModeNames[i];
  374. // Pretend we're VGA always.
  375. DriverNumber := VGA;
  376. MaxX := ModeInfo.Visible.X;
  377. MaxY := ModeInfo.Visible.Y;
  378. // MaxColor := ModeInfo.colors;
  379. MaxColor := 255;
  380. PaletteSize := MaxColor;
  381. HardwarePages := 0;
  382. // necessary hooks ...
  383. DirectPutPixel := @ggi_DirectPixelProc;
  384. GetPixel := @ggi_GetPixelProc;
  385. PutPixel := @ggi_PutPixelProc;
  386. SetRGBPalette := @ggi_SetRGBPaletteProc;
  387. GetRGBPalette := @ggi_GetRGBPaletteProc;
  388. ClearViewPort := @ggi_ClrViewProc;
  389. PutImage := @ggi_PutImageProc;
  390. GetImage := @ggi_GetImageProc;
  391. ImageSize := @ggi_ImageSizeProc;
  392. { Add later maybe ?
  393. SetVisualPage := SetVisualPageProc;
  394. SetActivePage := SetActivePageProc;
  395. GetScanLine := @ggi_GetScanLineProc;
  396. Line := @ggi_LineProc;
  397. InternalEllipse:= @ggi_EllipseProc;
  398. PatternLine := @ggi_PatternLineProc;
  399. HLine := @ggi_HLineProc;
  400. VLine := @ggi_VLineProc;
  401. }
  402. InitMode := @ggi_InitModeProc;
  403. end;
  404. AddMode(Mode);
  405. end;
  406. var
  407. i: longint;
  408. OldMode: TGGIMode;
  409. begin
  410. QueryAdapterInfo := ModeList;
  411. { If the mode listing already exists... }
  412. { simply return it, without changing }
  413. { anything... }
  414. if Assigned(ModeList) then
  415. exit;
  416. SaveVideoState:=ggi_savevideostate;
  417. RestoreVideoState:=ggi_restorevideostate;
  418. If ggiInit <> 0 then begin
  419. _graphresult := grNoInitGraph;
  420. exit;
  421. end;
  422. Visual := ggiOpen(nil, []); // Use default visual
  423. ggiGetMode(Visual, OldMode);
  424. ggiParseMode('', ModeInfo);
  425. ggiSetMode(Visual, ModeInfo);
  426. ggiGetMode(Visual, ModeInfo);
  427. ggiSetMode(Visual, OldMode);
  428. AddGGIMode(0);
  429. for i := 1 to GLastMode do begin
  430. // WriteLn('Testing mode: ', ModeNames[i]);
  431. ggiParseMode(ModeNames[i], ModeInfo);
  432. If ggiCheckMode(visual, ModeInfo) = 0 then begin
  433. Writeln('OK for mode: ', ModeNames[i]);
  434. AddGGIMode(i);
  435. end;
  436. end;
  437. end;
  438. begin
  439. InitializeGraph;
  440. end.
  441. {
  442. $Log$
  443. Revision 1.1 2000-03-19 11:20:14 peter
  444. * graph unit include is now independent and the dependent part
  445. is now in graph.pp
  446. * ggigraph unit for linux added
  447. }