ggigraph.pp 14 KB

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