ggigraph.pp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  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. Unix;
  74. var
  75. OldIO : TermIos;
  76. Procedure SetRawMode(b:boolean);
  77. Var
  78. Tio : Termios;
  79. Begin
  80. if b then
  81. begin
  82. TCGetAttr(1,Tio);
  83. OldIO:=Tio;
  84. CFMakeRaw(Tio);
  85. end
  86. else
  87. Tio:=OldIO;
  88. TCSetAttr(1,TCSANOW,Tio);
  89. End;
  90. const
  91. InternalDriverName = 'LinuxGGI';
  92. {$i graph.inc}
  93. { ---------------------------------------------------------------------
  94. GGI bindings [(c) 1999 Sebastian Guenther]
  95. ---------------------------------------------------------------------}
  96. {$LINKLIB c}
  97. {$PACKRECORDS C}
  98. const
  99. GLASTMODE = 49;
  100. ModeNames: array[0..GLastMode] of PChar =
  101. ('[]', {Let GGI choose a default mode}
  102. 'S320x200[GT_4BIT]',
  103. 'S640x200[GT_4BIT]',
  104. 'S640x350[GT_4BIT]',
  105. 'S640x480[GT_4BIT]',
  106. 'S320x200[GT_8BIT]',
  107. 'S320x240[GT_8BIT]',
  108. 'S320x400[GT_8BIT]',
  109. 'S360x480[GT_8BIT]',
  110. 'S640x480x[GT_1BIT]',
  111. 'S640x480[GT_8BIT]',
  112. 'S800x600[GT_8BIT]',
  113. 'S1024x768[GT_8BIT]',
  114. 'S1280x1024[GT_8BIT]',
  115. 'S320x200[GT_15BIT]',
  116. 'S320x200[GT_16BIT]',
  117. 'S320x200[GT_24BIT]',
  118. 'S640x480[GT_15BIT]',
  119. 'S640x480[GT_16BIT]',
  120. 'S640x480[GT_24BIT]',
  121. 'S800x600[GT_15BIT]',
  122. 'S800x600[GT_16BIT]',
  123. 'S800x600[GT_24BIT]',
  124. 'S1024x768[GT_15BIT]',
  125. 'S1024x768[GT_16BIT]',
  126. 'S1024x768[GT_24BIT]',
  127. 'S1280x1024[GT_15BIT]',
  128. 'S1280x1024[GT_16BIT]',
  129. 'S1280x1024[GT_24BIT]',
  130. 'S800x600[GT_4BIT]',
  131. 'S1024x768[GT_4BIT]',
  132. 'S1280x1024[GT_4BIT]',
  133. 'S720x348x[GT_1BIT]',
  134. 'S320x200[GT_32BIT]',
  135. 'S640x480[GT_32BIT]',
  136. 'S800x600[GT_32BIT]',
  137. 'S1024x768[GT_32BIT]',
  138. 'S1280x1024[GT_32BIT]',
  139. 'S1152x864[GT_4BIT]',
  140. 'S1152x864[gt_8BIT]',
  141. 'S1152x864[GT_15BIT]',
  142. 'S1152x864[GT_16BIT]',
  143. 'S1152x864[GT_24BIT]',
  144. 'S1152x864[GT_32BIT]',
  145. 'S1600x1200[GT_4BIT]',
  146. 'S1600x1200[gt_8BIT]',
  147. 'S1600x1200[GT_15BIT]',
  148. 'S1600x1200[GT_16BIT]',
  149. 'S1600x1200[GT_24BIT]',
  150. 'S1600x1200[GT_32BIT]');
  151. type
  152. TGGIVisual = Pointer;
  153. TGGIResource = Pointer;
  154. TGGICoord = record
  155. x, y: SmallInt;
  156. end;
  157. TGGIPixel = LongWord;
  158. PGGIColor = ^TGGIColor;
  159. TGGIColor = record
  160. r, g, b, a: Word;
  161. end;
  162. PGGIClut = ^TGGIClut;
  163. TGGIClut = record
  164. size: SmallInt;
  165. data: PGGIColor;
  166. end;
  167. TGGIGraphType = LongWord;
  168. TGGIAttr = LongWord;
  169. TGGIMode = record // requested by user and changed by driver
  170. Frames: LongInt; // frames needed
  171. Visible: TGGICoord; // vis. pixels, may change slightly
  172. Virt: TGGICoord; // virtual pixels, may change
  173. Size: TGGICoord; // size of visible in mm
  174. GraphType: TGGIGraphType; // which mode ?
  175. dpp: TGGICoord; // dots per pixel
  176. end;
  177. const
  178. libggi = 'ggi';
  179. function ggiInit: Longint; cdecl; external libggi;
  180. procedure ggiExit; cdecl; external libggi;
  181. function ggiOpen(display: PChar; args: Array of const): TGGIVisual; cdecl; external libggi;
  182. function ggiClose(vis: TGGIVisual): Longint; cdecl; external libggi;
  183. function ggiParseMode(s: PChar; var m: TGGIMode): Longint; cdecl; external libggi;
  184. function ggiSetMode(visual: TGGIVisual; var tm: TGGIMode): Longint; cdecl; external libggi;
  185. function ggiGetMode(visual: TGGIVisual; var tm: TGGIMode): Longint; cdecl; external libggi;
  186. function ggiCheckMode(visual: TGGIVisual; var tm: TGGIMode): Longint; cdecl; external libggi;
  187. function ggiMapColor(vis: TGGIVisual; Color: TGGIColor): TGGIPixel; cdecl; external libggi;
  188. function ggiPutPixel(vis: TGGIVisual; x, y: Longint; pixel: TGGIPixel): Longint; cdecl; external libggi;
  189. function ggiGetPixel(vis: TGGIVisual; x, y: Longint; var pixel: TGGIPixel): Longint; cdecl; external libggi;
  190. function ggiDrawBox(vis: TGGIVisual; x, y, w, h: Longint): Longint; cdecl; external libggi;
  191. function ggiPutBox(vis: TGGIVisual; x, y, w, h: Longint; var buffer): Longint; cdecl; external libggi;
  192. function ggiGetBox(vis: TGGIVisual; x, y, w, h: Longint; var buffer): Longint; cdecl; external libggi;
  193. function ggiGetPalette(vis: TGGIVisual; s, len: Longint; var cmap: TGGIColor): Longint; cdecl; external libggi;
  194. function ggiSetPalette(vis: TGGIVisual; s, len: Longint; var cmap: TGGIColor): Longint; cdecl; external libggi;
  195. var
  196. Visual: TGGIVisual;
  197. CurrentMode, OldMode: TGGIMode;
  198. procedure ggi_savevideostate;
  199. begin
  200. ggiGetMode(Visual, OldMode);
  201. end;
  202. procedure ggi_restorevideostate;
  203. begin
  204. ggiSetMode(Visual, OldMode);
  205. end;
  206. const
  207. BgiColors: array[0..15] of TGGIColor = (
  208. (r: $0000; g: $0000; b: $0000; a: 0),
  209. (r: $0000; g: $0000; b: $8000; a: 0),
  210. (r: $0000; g: $8000; b: $0000; a: 0),
  211. (r: $0000; g: $8000; b: $8000; a: 0),
  212. (r: $8000; g: $0000; b: $0000; a: 0),
  213. (r: $8000; g: $0000; b: $8000; a: 0),
  214. (r: $8000; g: $8000; b: $0000; a: 0),
  215. (r: $C000; g: $C000; b: $C000; a: 0),
  216. (r: $8000; g: $8000; b: $8000; a: 0),
  217. (r: $0000; g: $0000; b: $FFFF; a: 0),
  218. (r: $0000; g: $FFFF; b: $0000; a: 0),
  219. (r: $0000; g: $FFFF; b: $FFFF; a: 0),
  220. (r: $FFFF; g: $0000; b: $0000; a: 0),
  221. (r: $FFFF; g: $0000; b: $FFFF; a: 0),
  222. (r: $FFFF; g: $FFFF; b: $0000; a: 0),
  223. (r: $FFFF; g: $FFFF; b: $FFFF; a: 0));
  224. procedure ggi_initmodeproc;
  225. begin
  226. ggiParseMode(ModeNames[IntCurrentMode], CurrentMode);
  227. ggiSetMode(Visual, CurrentMode);
  228. end;
  229. function ClipCoords(var x, y: SmallInt): Boolean;
  230. { Adapt to viewport, return TRUE if still in viewport,
  231. false if outside viewport}
  232. begin
  233. x := x + StartXViewPort;
  234. x := y + StartYViewPort;
  235. ClipCoords := not ClipPixels;
  236. if ClipCoords then begin
  237. ClipCoords := (y < StartXViewPort) or (x > (StartXViewPort + ViewWidth));
  238. ClipCoords := ClipCoords or
  239. ((y < StartYViewPort) or (y > (StartYViewPort + ViewHeight)));
  240. ClipCoords := not ClipCoords;
  241. end;
  242. end;
  243. procedure ggi_directpixelproc(X, Y: smallint);
  244. var
  245. Color, CurCol: TGGIPixel;
  246. begin
  247. CurCol := ggiMapColor(Visual, BgiColors[CurrentColor]);
  248. case CurrentWriteMode of
  249. XORPut: begin
  250. { getpixel wants local/relative coordinates }
  251. ggiGetPixel(Visual, x-StartXViewPort, y-StartYViewPort, Color);
  252. Color := CurCol xor Color;
  253. end;
  254. OrPut: begin
  255. { getpixel wants local/relative coordinates }
  256. ggiGetPixel(Visual, x-StartXViewPort, y-StartYViewPort, Color);
  257. Color := CurCol or Color;
  258. end;
  259. AndPut: begin
  260. { getpixel wants local/relative coordinates }
  261. ggiGetPixel(Visual, x-StartXViewPort, y-StartYViewPort, Color);
  262. Color := CurCol and Color;
  263. end;
  264. NotPut:
  265. Color := not Color;
  266. else
  267. Color := CurCol;
  268. end;
  269. ggiPutPixel(Visual, x, y, Color);
  270. end;
  271. procedure ggi_putpixelproc(X,Y: smallint; Color: Word);
  272. begin
  273. If Not ClipCoords(X,Y) Then exit;
  274. ggiputpixel(Visual,x, y, Color);
  275. end;
  276. function ggi_getpixelproc (X,Y: smallint): word;
  277. Var i : TGGIPixel;
  278. begin
  279. ClipCoords(X,Y);
  280. ggigetpixel(Visual,x, y,I);
  281. ggi_getpixelproc:=i;
  282. end;
  283. procedure ggi_clrviewproc;
  284. begin
  285. ggidrawbox(Visual,StartXViewPort,StartYViewPort,ViewWidth,ViewHeight);
  286. { reset coordinates }
  287. CurrentX := 0;
  288. CurrentY := 0;
  289. end;
  290. { Bitmap utilities }
  291. type
  292. PBitmap = ^TBitmap;
  293. TBitmap = record
  294. Width, Height: longint;
  295. reserved : longint;
  296. Data: record end;
  297. end;
  298. procedure ggi_putimageproc (X,Y: smallint; var Bitmap; BitBlt: Word);
  299. begin
  300. With TBitMap(BitMap) do
  301. ggiputbox(Visual,x, y, width, height, Data);
  302. end;
  303. procedure ggi_getimageproc (X1,Y1,X2,Y2: smallint; Var Bitmap);
  304. begin
  305. with TBitmap(Bitmap) do
  306. begin
  307. Width := x2 - x1 + 1;
  308. Height := y2 - y1 + 1;
  309. ggigetbox(Visual,x1,y1, x2 - x1 + 1, y2 - y1 + 1, Data);
  310. end;
  311. end;
  312. function ggi_imagesizeproc (X1,Y1,X2,Y2: smallint): longint;
  313. begin
  314. // 32 bits per pixel -- change ASAP !!
  315. ggi_imagesizeproc := SizeOf(TBitmap) + (x2 - x1 + 1) * (y2 - y1 + 1) * SizeOF(longint);
  316. end;
  317. procedure ggi_hlineproc (x, x2,y : smallint);
  318. begin
  319. end;
  320. procedure ggi_vlineproc (x,y,y2: smallint);
  321. begin
  322. end;
  323. procedure ggi_patternlineproc (x1,x2,y: smallint);
  324. begin
  325. end;
  326. procedure ggi_ellipseproc (X,Y: smallint;XRadius: word;
  327. YRadius:word; stAngle,EndAngle: word; fp: PatternLineProc);
  328. begin
  329. end;
  330. procedure ggi_lineproc (X1, Y1, X2, Y2 : smallint);
  331. begin
  332. end;
  333. procedure ggi_getscanlineproc (X1, X2, Y : smallint; var data);
  334. begin
  335. end;
  336. procedure ggi_setactivepageproc (page: word);
  337. begin
  338. end;
  339. procedure ggi_setvisualpageproc (page: word);
  340. begin
  341. end;
  342. procedure ggi_savestateproc;
  343. begin
  344. end;
  345. procedure ggi_restorestateproc;
  346. begin
  347. end;
  348. procedure ggi_setrgbpaletteproc(ColorNum, RedValue, GreenValue, BlueValue: smallint);
  349. Var Col : TGGIcolor;
  350. begin
  351. col.r:=redvalue;
  352. col.g:=greenvalue;
  353. col.b:=bluevalue;
  354. ggisetpalette(Visual,ColorNum,1,col);
  355. end;
  356. procedure ggi_getrgbpaletteproc (ColorNum: smallint;
  357. var RedValue, GreenValue, BlueValue: smallint);
  358. Var Col : TGGIColor;
  359. begin
  360. ggigetpalette(Visual,ColorNum,1,col);
  361. RedValue:=Col.R;
  362. GreenValue:=Col.G;
  363. BlueValue:=Col.B;
  364. end;
  365. {************************************************************************}
  366. {* General routines *}
  367. {************************************************************************}
  368. procedure CloseGraph;
  369. begin
  370. if not IsGraphMode then
  371. begin
  372. _graphresult := grnoinitgraph;
  373. exit
  374. end;
  375. RestoreVideoState;
  376. isgraphmode := false;
  377. end;
  378. function QueryAdapterInfo:PModeInfo;
  379. { This routine returns the head pointer to the list }
  380. { of supported graphics modes. }
  381. { Returns nil if no graphics mode supported. }
  382. { This list is READ ONLY! }
  383. var
  384. ModeInfo: TGGIMode;
  385. procedure AddGGIMode(i: smallint); // i is the mode number
  386. var
  387. mode: TModeInfo;
  388. begin
  389. InitMode(Mode);
  390. with Mode do begin
  391. ModeNumber := i;
  392. ModeName := ModeNames[i];
  393. // Pretend we're VGA always.
  394. DriverNumber := VGA;
  395. MaxX := ModeInfo.Visible.X-1;
  396. MaxY := ModeInfo.Visible.Y-1;
  397. MaxColor := 1 shl (ModeInfo.graphtype and $ff);
  398. //MaxColor := 255;
  399. PaletteSize := MaxColor;
  400. HardwarePages := 0;
  401. // necessary hooks ...
  402. DirectPutPixel := @ggi_DirectPixelProc;
  403. GetPixel := @ggi_GetPixelProc;
  404. PutPixel := @ggi_PutPixelProc;
  405. SetRGBPalette := @ggi_SetRGBPaletteProc;
  406. GetRGBPalette := @ggi_GetRGBPaletteProc;
  407. ClearViewPort := @ggi_ClrViewProc;
  408. PutImage := @ggi_PutImageProc;
  409. GetImage := @ggi_GetImageProc;
  410. ImageSize := @ggi_ImageSizeProc;
  411. { Add later maybe ?
  412. SetVisualPage := SetVisualPageProc;
  413. SetActivePage := SetActivePageProc;
  414. GetScanLine := @ggi_GetScanLineProc;
  415. Line := @ggi_LineProc;
  416. InternalEllipse:= @ggi_EllipseProc;
  417. PatternLine := @ggi_PatternLineProc;
  418. HLine := @ggi_HLineProc;
  419. VLine := @ggi_VLineProc;
  420. }
  421. InitMode := @ggi_InitModeProc;
  422. end;
  423. AddMode(Mode);
  424. end;
  425. var
  426. i: longint;
  427. OldMode: TGGIMode;
  428. begin
  429. QueryAdapterInfo := ModeList;
  430. { If the mode listing already exists... }
  431. { simply return it, without changing }
  432. { anything... }
  433. if Assigned(ModeList) then
  434. exit;
  435. SaveVideoState:=@ggi_savevideostate;
  436. RestoreVideoState:=@ggi_restorevideostate;
  437. If ggiInit <> 0 then begin
  438. _graphresult := grNoInitGraph;
  439. exit;
  440. end;
  441. Visual := ggiOpen(nil, []); // Use default visual
  442. ggiGetMode(Visual, OldMode);
  443. ggiParseMode('', ModeInfo);
  444. ggiSetMode(Visual, ModeInfo);
  445. ggiGetMode(Visual, ModeInfo);
  446. ggiSetMode(Visual, OldMode);
  447. AddGGIMode(0);
  448. for i := 1 to GLastMode do begin
  449. // WriteLn('Testing mode: ', ModeNames[i]);
  450. ggiParseMode(ModeNames[i], ModeInfo);
  451. If ggiCheckMode(visual, ModeInfo) = 0 then begin
  452. Writeln('OK for mode ',i,' : ', ModeNames[i]);
  453. AddGGIMode(i);
  454. end;
  455. end;
  456. end;
  457. initialization
  458. InitializeGraph;
  459. SetRawMode(True);
  460. finalization
  461. SetRawMode(False);
  462. end.
  463. {
  464. $Log$
  465. Revision 1.6 2002-09-07 16:01:27 peter
  466. * old logs removed and tabs fixed
  467. }