ggigraph.pp 14 KB

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