graph.pp 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532
  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 win32 gui 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 Graph;
  13. interface
  14. uses
  15. windows;
  16. {$i graphh.inc}
  17. var
  18. { this procedure allows to hook keyboard messages }
  19. charmessagehandler : function(Window: hwnd; AMessage, WParam,
  20. LParam: Longint): Longint;
  21. { this procedure allows to hook mouse messages }
  22. mousemessagehandler : function(Window: hwnd; AMessage, WParam,
  23. LParam: Longint): Longint;
  24. mainwindow : HWnd;
  25. const
  26. { predefined window style }
  27. { we shouldn't set CS_DBLCLKS here }
  28. { because most dos applications }
  29. { handle double clicks on it's own }
  30. graphwindowstyle : DWord = cs_hRedraw or cs_vRedraw;
  31. windowtitle : pchar = 'Graph window application';
  32. CONST
  33. m640x200x16 = VGALo;
  34. m640x400x16 = VGAMed;
  35. m640x480x16 = VGAHi;
  36. { VESA Specific video modes. }
  37. m320x200x32k = $10D;
  38. m320x200x64k = $10E;
  39. m640x400x256 = $100;
  40. m640x480x256 = $101;
  41. m640x480x32k = $110;
  42. m640x480x64k = $111;
  43. m800x600x16 = $102;
  44. m800x600x256 = $103;
  45. m800x600x32k = $113;
  46. m800x600x64k = $114;
  47. m1024x768x16 = $104;
  48. m1024x768x256 = $105;
  49. m1024x768x32k = $116;
  50. m1024x768x64k = $117;
  51. m1280x1024x16 = $106;
  52. m1280x1024x256 = $107;
  53. m1280x1024x32k = $119;
  54. m1280x1024x64k = $11A;
  55. { some extra modes which applies only to GUI }
  56. mLargestWindow16 = $f0;
  57. mLargestWindow256 = $f1;
  58. mLargestWindow32k = $f2;
  59. mLargestWindow64k = $f3;
  60. mLargestWindow16M = $f4;
  61. mMaximizedWindow16 = $f5;
  62. mMaximizedWindow256 = $f6;
  63. mMaximizedWindow32k = $f7;
  64. mMaximizedWindow64k = $f8;
  65. mMaximizedWindow16M = $f9;
  66. implementation
  67. uses
  68. strings;
  69. {
  70. Remarks:
  71. Colors in 16 color mode:
  72. ------------------------
  73. - the behavior of xor/or/and put isn't 100%:
  74. it is done using the RGB color getting from windows
  75. instead of the palette index!
  76. - palette operations aren't supported
  77. To solve these drawbacks, setpalette must be implemented
  78. by exchanging the colors in the DCs, further GetPaletteEntry
  79. must be used when doing xor/or/and operations
  80. }
  81. const
  82. InternalDriverName = 'WIN32GUI';
  83. {$i graph.inc}
  84. { used to create a file containing all calls to WM_PAINT
  85. WARNING this probably creates HUGE files PM }
  86. { $define DEBUG_WM_PAINT}
  87. var
  88. savedscreen : hbitmap;
  89. graphrunning : boolean;
  90. graphdrawing : tcriticalsection;
  91. {$ifdef DEBUG_WM_PAINT}
  92. graphdebug : text;
  93. const
  94. wm_paint_count : longint = 0;
  95. var
  96. {$endif DEBUG_WM_PAINT}
  97. bitmapdc : hdc;
  98. oldbitmap : hgdiobj;
  99. pal : ^rgbrec;
  100. // SavePtr : pointer; { we don't use that pointer }
  101. MessageThreadHandle : Handle;
  102. MessageThreadID : DWord;
  103. windc : hdc;
  104. function GetPaletteEntry(r,g,b : word) : word;
  105. var
  106. dist,i,index,currentdist : longint;
  107. begin
  108. dist:=$7fffffff;
  109. index:=0;
  110. for i:=0 to maxcolors do
  111. begin
  112. currentdist:=abs(r-pal[i].red)+abs(g-pal[i].green)+
  113. abs(b-pal[i].blue);
  114. if currentdist<dist then
  115. begin
  116. index:=i;
  117. dist:=currentdist;
  118. if dist=0 then
  119. break;
  120. end;
  121. end;
  122. GetPaletteEntry:=index;
  123. end;
  124. procedure PutPixel16Win32GUI(x,y : integer;pixel : word);
  125. var
  126. c : colorref;
  127. begin
  128. x:=x+startxviewport;
  129. y:=y+startyviewport;
  130. { convert to absolute coordinates and then verify clipping...}
  131. if clippixels then
  132. begin
  133. if (x<startxviewport) or (x>(startxviewport+viewwidth)) or
  134. (y<StartyViewPort) or (y>(startyviewport+viewheight)) then
  135. exit;
  136. end;
  137. if graphrunning then
  138. begin
  139. c:=RGB(pal[pixel].red,pal[pixel].green,pal[pixel].blue);
  140. EnterCriticalSection(graphdrawing);
  141. SetPixel(bitmapdc,x,y,c);
  142. SetPixel(windc,x,y,c);
  143. LeaveCriticalSection(graphdrawing);
  144. end;
  145. end;
  146. function GetPixel16Win32GUI(x,y : integer) : word;
  147. var
  148. c : COLORREF;
  149. begin
  150. x:=x+startxviewport;
  151. y:=y+startyviewport;
  152. { convert to absolute coordinates and then verify clipping...}
  153. if clippixels then
  154. begin
  155. if (x<startxviewport) or (x>(startxviewport+viewwidth)) or
  156. (y<StartyViewPort) or (y>(startyviewport+viewheight)) then
  157. exit;
  158. end;
  159. if graphrunning then
  160. begin
  161. EnterCriticalSection(graphdrawing);
  162. c:=Windows.GetPixel(bitmapdc,x,y);
  163. LeaveCriticalSection(graphdrawing);
  164. GetPixel16Win32GUI:=GetPaletteEntry(GetRValue(c),GetGValue(c),GetBValue(c));
  165. end
  166. else
  167. begin
  168. _graphresult:=grerror;
  169. exit;
  170. end;
  171. end;
  172. procedure DirectPutPixel16Win32GUI(x,y : integer);
  173. var
  174. col : longint;
  175. c,c2 : COLORREF;
  176. begin
  177. if graphrunning then
  178. begin
  179. EnterCriticalSection(graphdrawing);
  180. col:=CurrentColor;
  181. case currentwritemode of
  182. XorPut:
  183. Begin
  184. c2:=Windows.GetPixel(bitmapdc,x,y);
  185. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) xor c2;
  186. SetPixel(bitmapdc,x,y,c);
  187. SetPixel(windc,x,y,c);
  188. End;
  189. AndPut:
  190. Begin
  191. c2:=Windows.GetPixel(bitmapdc,x,y);
  192. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) and c2;
  193. SetPixel(bitmapdc,x,y,c);
  194. SetPixel(windc,x,y,c);
  195. End;
  196. OrPut:
  197. Begin
  198. c2:=Windows.GetPixel(bitmapdc,x,y);
  199. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) or c2;
  200. SetPixel(bitmapdc,x,y,c);
  201. SetPixel(windc,x,y,c);
  202. End
  203. else
  204. Begin
  205. If CurrentWriteMode<>NotPut Then
  206. col:=CurrentColor
  207. Else col := Not(CurrentColor);
  208. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  209. SetPixel(bitmapdc,x,y,c);
  210. SetPixel(windc,x,y,c);
  211. End
  212. end;
  213. LeaveCriticalSection(graphdrawing);
  214. end;
  215. end;
  216. var
  217. bitmapfontcache : array[0..255] of HBITMAP;
  218. procedure DrawBitmapCharHorizWin32GUI(x,y : longint;charsize : word;const s : string);
  219. var
  220. cnt1,cnt2,cnt3,cnt4,j,k,c,xpos,i : longint;
  221. fontbitmap : TBitmapChar;
  222. charbitmap,oldcharbitmap : HBITMAP;
  223. chardc : HDC;
  224. color : longint;
  225. brushwin,oldbrushwin,brushbitmap,oldbrushbitmap : HBRUSH;
  226. bitmaprgn,winrgn : HRGN;
  227. begin
  228. EnterCriticalSection(graphdrawing);
  229. c:=length(s);
  230. chardc:=CreateCompatibleDC(windc);
  231. if currentcolor<>white then
  232. begin
  233. color:=RGB(pal[currentcolor].red,pal[currentcolor].green,
  234. pal[currentcolor].blue);
  235. brushwin:=CreateSolidBrush(color);
  236. oldbrushwin:=SelectObject(windc,brushwin);
  237. brushbitmap:=CreateSolidBrush(color);
  238. oldbrushbitmap:=SelectObject(bitmapdc,brushbitmap);
  239. end;
  240. inc(x,startxviewport);
  241. inc(y,startyviewport);
  242. { let windows do the clipping }
  243. bitmaprgn:=CreateRectRgn(startxviewport,startyviewport,
  244. startxviewport+viewwidth+1,startyviewport+viewheight+1);
  245. winrgn:=CreateRectRgn(startxviewport,startyviewport,
  246. startxviewport+viewwidth+1,startyviewport+viewheight+1);
  247. SelectClipRgn(bitmapdc,bitmaprgn);
  248. SelectClipRgn(windc,winrgn);
  249. for i:=0 to c-1 do
  250. begin
  251. xpos:=x+(i*8)*Charsize;
  252. if bitmapfontcache[byte(s[i+1])]=0 then
  253. begin
  254. charbitmap:=CreateCompatibleBitmap(windc,8,8);
  255. oldcharbitmap:=SelectObject(chardc,charbitmap);
  256. Fontbitmap:=TBitmapChar(DefaultFontData[s[i+1]]);
  257. for j:=0 to 7 do
  258. for k:=0 to 7 do
  259. if Fontbitmap[j,k]<>0 then
  260. SetPixel(chardc,k,j,$ffffff)
  261. else
  262. SetPixel(chardc,k,j,0);
  263. bitmapfontcache[byte(s[i+1])]:=charbitmap;
  264. SelectObject(chardc,oldcharbitmap);
  265. end;
  266. oldcharbitmap:=SelectObject(chardc,bitmapfontcache[byte(s[i+1])]);
  267. if CharSize=1 then
  268. begin
  269. if currentcolor=white then
  270. begin
  271. BitBlt(windc,xpos,y,8,8,chardc,0,0,SRCPAINT);
  272. BitBlt(bitmapdc,xpos,y,8,8,chardc,0,0,SRCPAINT);
  273. end
  274. else
  275. begin
  276. { could we do this with one pattern operation ?? }
  277. { we would need something like DSnaSPao }
  278. // ROP $00220326=DSna
  279. BitBlt(windc,xpos,y,8,8,chardc,0,0,$00220326);
  280. BitBlt(bitmapdc,xpos,y,8,8,chardc,0,0,$00220326);
  281. // ROP $00EA02E9 = DPSao
  282. BitBlt(windc,xpos,y,8,8,chardc,0,0,$00EA02E9);
  283. BitBlt(bitmapdc,xpos,y,8,8,chardc,0,0,$00EA02E9);
  284. end;
  285. end
  286. else
  287. begin
  288. if currentcolor=white then
  289. begin
  290. StretchBlt(windc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,SRCPAINT);
  291. StretchBlt(bitmapdc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,SRCPAINT);
  292. end
  293. else
  294. begin
  295. { could we do this with one pattern operation ?? }
  296. { we would need something like DSnaSPao }
  297. // ROP $00220326=DSna
  298. StretchBlt(windc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,$00220326);
  299. StretchBlt(bitmapdc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,$00220326);
  300. // ROP $00EA02E9 = DPSao
  301. StretchBlt(windc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,$00EA02E9);
  302. StretchBlt(bitmapdc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,$00EA02E9);
  303. end;
  304. end;
  305. SelectObject(chardc,oldcharbitmap);
  306. end;
  307. if currentcolor<>white then
  308. begin
  309. SelectObject(windc,oldbrushwin);
  310. DeleteObject(brushwin);
  311. SelectObject(bitmapdc,oldbrushbitmap);
  312. DeleteObject(brushbitmap);
  313. end;
  314. { release clip regions }
  315. SelectClipRgn(bitmapdc,0);
  316. SelectClipRgn(windc,0);
  317. DeleteObject(bitmaprgn);
  318. DeleteObject(winrgn);
  319. DeleteDC(chardc);
  320. LeaveCriticalSection(graphdrawing);
  321. end;
  322. procedure HLine16Win32GUI(x,x2,y: integer);
  323. var
  324. c,c2 : COLORREF;
  325. col,i : longint;
  326. oldpen,pen : HPEN;
  327. Begin
  328. if graphrunning then
  329. begin
  330. { must we swap the values? }
  331. if x>x2 then
  332. Begin
  333. x:=x xor x2;
  334. x2:=x xor x2;
  335. x:=x xor x2;
  336. end;
  337. { First convert to global coordinates }
  338. X:=X+StartXViewPort;
  339. X2:=X2+StartXViewPort;
  340. Y:=Y+StartYViewPort;
  341. if ClipPixels then
  342. Begin
  343. if LineClipped(x,y,x2,y,StartXViewPort,StartYViewPort,
  344. StartXViewPort+ViewWidth, StartYViewPort+ViewHeight) then
  345. exit;
  346. end;
  347. Case CurrentWriteMode of
  348. AndPut:
  349. Begin
  350. EnterCriticalSection(graphdrawing);
  351. col:=CurrentColor;
  352. for i:=x to x2 do
  353. begin
  354. c2:=Windows.GetPixel(bitmapdc,i,y);
  355. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) and c2;
  356. SetPixel(bitmapdc,i,y,c);
  357. SetPixel(windc,i,y,c);
  358. end;
  359. LeaveCriticalSection(graphdrawing);
  360. End;
  361. XorPut:
  362. Begin
  363. EnterCriticalSection(graphdrawing);
  364. col:=CurrentColor;
  365. for i:=x to x2 do
  366. begin
  367. c2:=Windows.GetPixel(bitmapdc,i,y);
  368. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) xor c2;
  369. SetPixel(bitmapdc,i,y,c);
  370. SetPixel(windc,i,y,c);
  371. end;
  372. LeaveCriticalSection(graphdrawing);
  373. End;
  374. OrPut:
  375. Begin
  376. EnterCriticalSection(graphdrawing);
  377. col:=CurrentColor;
  378. for i:=x to x2 do
  379. begin
  380. c2:=Windows.GetPixel(bitmapdc,i,y);
  381. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) or c2;
  382. SetPixel(bitmapdc,i,y,c);
  383. SetPixel(windc,i,y,c);
  384. end;
  385. LeaveCriticalSection(graphdrawing);
  386. End
  387. Else
  388. Begin
  389. If CurrentWriteMode<>NotPut Then
  390. col:=CurrentColor
  391. Else col:=Not(CurrentColor);
  392. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  393. pen:=CreatePen(PS_SOLID,1,c);
  394. EnterCriticalSection(graphdrawing);
  395. oldpen:=SelectObject(bitmapdc,pen);
  396. Windows.MoveToEx(bitmapdc,x,y,nil);
  397. Windows.LineTo(bitmapdc,x2+1,y);
  398. SelectObject(bitmapdc,oldpen);
  399. oldpen:=SelectObject(windc,pen);
  400. Windows.MoveToEx(windc,x,y,nil);
  401. Windows.LineTo(windc,x2+1,y);
  402. SelectObject(windc,oldpen);
  403. DeleteObject(pen);
  404. LeaveCriticalSection(graphdrawing);
  405. End;
  406. End;
  407. end;
  408. end;
  409. procedure SetRGBPaletteWin32GUI(colorNum,redValue,greenvalue,
  410. bluevalue : integer);
  411. begin
  412. if directcolor or (colornum<0) or (colornum>=maxcolor) then
  413. begin
  414. _graphresult:=grerror;
  415. exit;
  416. end;
  417. pal[colorNum].red:=redValue;
  418. pal[colorNum].green:=greenValue;
  419. pal[colorNum].blue:=blueValue;
  420. end;
  421. procedure GetRGBPaletteWin32GUI(colorNum : integer;
  422. var redValue,greenvalue,bluevalue : integer);
  423. begin
  424. if directcolor or (colornum<0) or (colornum>=maxcolor) then
  425. begin
  426. _graphresult:=grerror;
  427. exit;
  428. end;
  429. redValue:=pal[colorNum].red;
  430. greenValue:=pal[colorNum].green;
  431. blueValue:=pal[colorNum].blue;
  432. end;
  433. procedure savestate;
  434. begin
  435. end;
  436. procedure restorestate;
  437. begin
  438. end;
  439. function WindowProc(Window: HWnd; AMessage, WParam,
  440. LParam: Longint): Longint; stdcall; export;
  441. var
  442. dc : hdc;
  443. ps : paintstruct;
  444. r : rect;
  445. oldbrush : hbrush;
  446. oldpen : hpen;
  447. i : longint;
  448. begin
  449. WindowProc := 0;
  450. case AMessage of
  451. wm_lbuttondown,
  452. wm_rbuttondown,
  453. wm_mbuttondown,
  454. wm_lbuttonup,
  455. wm_rbuttonup,
  456. wm_mbuttonup,
  457. wm_lbuttondblclk,
  458. wm_rbuttondblclk,
  459. wm_mbuttondblclk:
  460. {
  461. This leads to problem, i.e. the menu etc doesn't work any longer
  462. wm_nclbuttondown,
  463. wm_ncrbuttondown,
  464. wm_ncmbuttondown,
  465. wm_nclbuttonup,
  466. wm_ncrbuttonup,
  467. wm_ncmbuttonup,
  468. wm_nclbuttondblclk,
  469. wm_ncrbuttondblclk,
  470. wm_ncmbuttondblclk:
  471. }
  472. if assigned(mousemessagehandler) then
  473. WindowProc:=mousemessagehandler(window,amessage,wparam,lparam);
  474. wm_keydown,
  475. wm_keyup,
  476. wm_char:
  477. if assigned(charmessagehandler) then
  478. WindowProc:=charmessagehandler(window,amessage,wparam,lparam);
  479. wm_paint:
  480. begin
  481. {$ifdef DEBUG_WM_PAINT}
  482. inc(wm_paint_count);
  483. {$endif DEBUG_WM_PAINT}
  484. if not GetUpdateRect(Window,@r,false) then
  485. exit;
  486. EnterCriticalSection(graphdrawing);
  487. graphrunning:=true;
  488. dc:=BeginPaint(Window,@ps);
  489. {$ifdef DEBUG_WM_PAINT}
  490. Writeln(graphdebug,'WM_PAINT in ((',r.left,',',r.top,
  491. '),(',r.right,',',r.bottom,'))');
  492. {$endif def DEBUG_WM_PAINT}
  493. if graphrunning then
  494. {BitBlt(dc,0,0,maxx+1,maxy+1,bitmapdc,0,0,SRCCOPY);}
  495. BitBlt(dc,r.left,r.top,r.right-r.left+1,r.bottom-r.top+1,bitmapdc,r.left,r.top,SRCCOPY);
  496. EndPaint(Window,ps);
  497. LeaveCriticalSection(graphdrawing);
  498. Exit;
  499. end;
  500. wm_create:
  501. begin
  502. {$ifdef DEBUG_WM_PAINT}
  503. assign(graphdebug,'wingraph.log');
  504. rewrite(graphdebug);
  505. {$endif DEBUG_WM_PAINT}
  506. EnterCriticalSection(graphdrawing);
  507. dc:=GetDC(window);
  508. bitmapdc:=CreateCompatibleDC(dc);
  509. savedscreen:=CreateCompatibleBitmap(dc,maxx+1,maxy+1);
  510. ReleaseDC(window,dc);
  511. oldbitmap:=SelectObject(bitmapdc,savedscreen);
  512. windc:=GetDC(window);
  513. // clear everything
  514. oldpen:=SelectObject(bitmapdc,GetStockObject(BLACK_PEN));
  515. oldbrush:=SelectObject(bitmapdc,GetStockObject(BLACK_BRUSH));
  516. Windows.Rectangle(bitmapdc,0,0,maxx,maxy);
  517. SelectObject(bitmapdc,oldpen);
  518. SelectObject(bitmapdc,oldbrush);
  519. // ... the window too
  520. oldpen:=SelectObject(windc,GetStockObject(BLACK_PEN));
  521. oldbrush:=SelectObject(windc,GetStockObject(BLACK_BRUSH));
  522. Windows.Rectangle(windc,0,0,maxx,maxy);
  523. SelectObject(windc,oldpen);
  524. SelectObject(windc,oldbrush);
  525. // clear font cache
  526. fillchar(bitmapfontcache,sizeof(bitmapfontcache),0);
  527. LeaveCriticalSection(graphdrawing);
  528. end;
  529. wm_Destroy:
  530. begin
  531. EnterCriticalSection(graphdrawing);
  532. graphrunning:=false;
  533. ReleaseDC(mainwindow,windc);
  534. SelectObject(bitmapdc,oldbitmap);
  535. DeleteObject(savedscreen);
  536. DeleteDC(bitmapdc);
  537. // release font cache
  538. for i:=0 to 255 do
  539. if bitmapfontcache[i]<>0 then
  540. DeleteObject(bitmapfontcache[i]);
  541. LeaveCriticalSection(graphdrawing);
  542. {$ifdef DEBUG_WM_PAINT}
  543. close(graphdebug);
  544. {$endif DEBUG_WM_PAINT}
  545. PostQuitMessage(0);
  546. Exit;
  547. end
  548. else
  549. WindowProc := DefWindowProc(Window, AMessage, WParam, LParam);
  550. end;
  551. end;
  552. function WinRegister: Boolean;
  553. var
  554. WindowClass: WndClass;
  555. begin
  556. WindowClass.Style := graphwindowstyle;
  557. WindowClass.lpfnWndProc := WndProc(@WindowProc);
  558. WindowClass.cbClsExtra := 0;
  559. WindowClass.cbWndExtra := 0;
  560. WindowClass.hInstance := system.MainInstance;
  561. WindowClass.hIcon := LoadIcon(0, idi_Application);
  562. WindowClass.hCursor := LoadCursor(0, idc_Arrow);
  563. WindowClass.hbrBackground := GetStockObject(BLACK_BRUSH);
  564. WindowClass.lpszMenuName := nil;
  565. WindowClass.lpszClassName := 'FPCGraphWindow';
  566. winregister:=RegisterClass(WindowClass) <> 0;
  567. end;
  568. var
  569. // here we can force the creation of a maximized window }
  570. extrastyle : longint;
  571. { Create the Window Class }
  572. function WinCreate : HWnd;
  573. var
  574. hWindow: HWnd;
  575. begin
  576. hWindow := CreateWindow('FPCGraphWindow', windowtitle,
  577. ws_OverlappedWindow or extrastyle, CW_USEDEFAULT, 0,
  578. maxx+1+2*GetSystemMetrics(SM_CXFRAME),
  579. maxy+1+2*GetSystemMetrics(SM_CYFRAME)+
  580. GetSystemMetrics(SM_CYCAPTION),
  581. 0, 0, system.MainInstance, nil);
  582. if hWindow <> 0 then begin
  583. ShowWindow(hWindow, SW_SHOW);
  584. UpdateWindow(hWindow);
  585. end;
  586. wincreate:=hWindow;
  587. end;
  588. const
  589. winregistered : boolean = false;
  590. function MessageHandleThread(p : pointer) : DWord;StdCall;
  591. var
  592. AMessage: Msg;
  593. begin
  594. if not(winregistered) then
  595. begin
  596. if not WinRegister then
  597. begin
  598. MessageBox(0, 'Window registration failed', nil, mb_Ok);
  599. ExitThread(1);
  600. end;
  601. winregistered:=true;
  602. end;
  603. MainWindow := WinCreate;
  604. if longint(mainwindow) = 0 then begin
  605. MessageBox(0, 'Window creation failed', nil, mb_Ok);
  606. ExitThread(1);
  607. end;
  608. while longint(GetMessage(@AMessage, 0, 0, 0))=longint(true) do
  609. begin
  610. TranslateMessage(AMessage);
  611. DispatchMessage(AMessage);
  612. end;
  613. MessageHandleThread:=0;
  614. end;
  615. procedure InitWin32GUI16colors;
  616. var
  617. threadexitcode : longint;
  618. begin
  619. getmem(pal,sizeof(RGBrec)*maxcolor);
  620. move(DefaultColors,pal^,sizeof(RGBrec)*maxcolor);
  621. if (IntCurrentMode=mMaximizedWindow16) or
  622. (IntCurrentMode=mMaximizedWindow256) or
  623. (IntCurrentMode=mMaximizedWindow32k) or
  624. (IntCurrentMode=mMaximizedWindow64k) or
  625. (IntCurrentMode=mMaximizedWindow16M) then
  626. extrastyle:=ws_maximize
  627. else
  628. extrastyle:=0;
  629. { start graph subsystem }
  630. InitializeCriticalSection(graphdrawing);
  631. graphrunning:=false;
  632. MessageThreadHandle:=CreateThread(nil,0,@MessageHandleThread,
  633. nil,0,MessageThreadID);
  634. repeat
  635. GetExitCodeThread(MessageThreadHandle,@threadexitcode);
  636. until graphrunning or (threadexitcode<>STILL_ACTIVE);
  637. if threadexitcode<>STILL_ACTIVE then
  638. _graphresult := grerror;
  639. end;
  640. procedure CloseGraph;
  641. begin
  642. If not isgraphmode then
  643. begin
  644. _graphresult := grnoinitgraph;
  645. exit
  646. end;
  647. PostMessage(MainWindow,wm_destroy,0,0);
  648. PostThreadMessage(MessageThreadHandle,wm_quit,0,0);
  649. WaitForSingleObject(MessageThreadHandle,Infinite);
  650. CloseHandle(MessageThreadHandle);
  651. DeleteCriticalSection(graphdrawing);
  652. freemem(pal,sizeof(RGBrec)*maxcolor);
  653. end;
  654. procedure LineWin32GUI(X1, Y1, X2, Y2: smallint); {$ifndef fpc}far;{$endif fpc}
  655. var X, Y : smallint;
  656. deltax, deltay : smallint;
  657. d, dinc1, dinc2: smallint;
  658. xinc1 : smallint;
  659. xinc2 : smallint;
  660. yinc1 : smallint;
  661. yinc2 : smallint;
  662. i : smallint;
  663. Flag : Boolean; { determines pixel direction in thick lines }
  664. NumPixels : smallint;
  665. PixelCount : smallint;
  666. OldCurrentColor: Word;
  667. swtmp : smallint;
  668. TmpNumPixels : smallint;
  669. col : longint;
  670. pen,oldpen : hpen;
  671. begin
  672. if graphrunning then
  673. begin
  674. {******************************************}
  675. { SOLID LINES }
  676. {******************************************}
  677. if lineinfo.LineStyle = SolidLn then
  678. Begin
  679. { Convert to global coordinates. }
  680. x1 := x1 + StartXViewPort;
  681. x2 := x2 + StartXViewPort;
  682. y1 := y1 + StartYViewPort;
  683. y2 := y2 + StartYViewPort;
  684. { if fully clipped then exit... }
  685. if ClipPixels then
  686. begin
  687. if LineClipped(x1,y1,x2,y2,StartXViewPort, StartYViewPort,
  688. StartXViewPort+ViewWidth, StartYViewPort+ViewHeight) then
  689. exit;
  690. If LineInfo.Thickness=NormWidth then
  691. Begin
  692. EnterCriticalSection(graphdrawing);
  693. col:=RGB(pal[CurrentColor].red,pal[CurrentColor].green,pal[CurrentColor].blue);
  694. pen:=CreatePen(PS_SOLID,1,col);
  695. OldCurrentColor:=CurrentColor;
  696. oldpen:=SelectObject(windc,pen);
  697. MoveToEx(windc,x1,y1,nil);
  698. Windows.LineTo(windc,x2,y2);
  699. SetPixel(windc,x2,y2,col);
  700. SelectObject(windc,oldpen);
  701. oldpen:=SelectObject(bitmapdc,pen);
  702. MoveToEx(bitmapdc,x1,y1,nil);
  703. Windows.LineTo(bitmapdc,x2,y2);
  704. SetPixel(bitmapdc,x2,y2,col);
  705. SelectObject(bitmapdc,oldpen);
  706. DeleteObject(pen);
  707. CurrentColor:=OldCurrentColor;
  708. LeaveCriticalSection(graphdrawing);
  709. end
  710. else
  711. { Thick width lines }
  712. begin
  713. { Draw the pixels }
  714. for i := 1 to numpixels do
  715. begin
  716. { all depending on the slope, we can determine }
  717. { in what direction the extra width pixels will be put }
  718. If Flag then
  719. Begin
  720. DirectPutPixelClip(x-1,y);
  721. DirectPutPixelClip(x,y);
  722. DirectPutPixelClip(x+1,y);
  723. end
  724. else
  725. Begin
  726. DirectPutPixelClip(x, y-1);
  727. DirectPutPixelClip(x, y);
  728. DirectPutPixelClip(x, y+1);
  729. end;
  730. if d < 0 then
  731. begin
  732. d := d + dinc1;
  733. x := x + xinc1;
  734. y := y + yinc1;
  735. end
  736. else
  737. begin
  738. d := d + dinc2;
  739. x := x + xinc2;
  740. y := y + yinc2;
  741. end;
  742. end;
  743. end;
  744. end;
  745. end
  746. else
  747. {******************************************}
  748. { begin patterned lines }
  749. {******************************************}
  750. Begin
  751. { Convert to global coordinates. }
  752. x1 := x1 + StartXViewPort;
  753. x2 := x2 + StartXViewPort;
  754. y1 := y1 + StartYViewPort;
  755. y2 := y2 + StartYViewPort;
  756. { if fully clipped then exit... }
  757. if ClipPixels then
  758. begin
  759. if LineClipped(x1,y1,x2,y2,StartXViewPort, StartYViewPort,
  760. StartXViewPort+ViewWidth, StartYViewPort+ViewHeight) then
  761. exit;
  762. end;
  763. OldCurrentColor := CurrentColor;
  764. PixelCount:=0;
  765. if y1 = y2 then
  766. Begin
  767. { Check if we must swap }
  768. if x1 >= x2 then
  769. Begin
  770. swtmp := x1;
  771. x1 := x2;
  772. x2 := swtmp;
  773. end;
  774. if LineInfo.Thickness = NormWidth then
  775. Begin
  776. for PixelCount:=x1 to x2 do
  777. { optimization: PixelCount mod 16 }
  778. if LinePatterns[PixelCount and 15] = TRUE then
  779. begin
  780. DirectPutPixel(PixelCount,y2);
  781. end;
  782. end
  783. else
  784. Begin
  785. for i:=-1 to 1 do
  786. Begin
  787. for PixelCount:=x1 to x2 do
  788. { Optimization from Thomas - mod 16 = and 15 }
  789. {this optimization has been performed by the compiler
  790. for while as well (JM)}
  791. if LinePatterns[PixelCount and 15] = TRUE then
  792. begin
  793. DirectPutPixelClip(PixelCount,y2+i);
  794. end;
  795. end;
  796. end;
  797. end
  798. else
  799. if x1 = x2 then
  800. Begin
  801. { Check if we must swap }
  802. if y1 >= y2 then
  803. Begin
  804. swtmp := y1;
  805. y1 := y2;
  806. y2 := swtmp;
  807. end;
  808. if LineInfo.Thickness = NormWidth then
  809. Begin
  810. for PixelCount:=y1 to y2 do
  811. { compare if we should plot a pixel here , compare }
  812. { with predefined line patterns... }
  813. if LinePatterns[PixelCount and 15] = TRUE then
  814. begin
  815. DirectPutPixel(x1,PixelCount);
  816. end;
  817. end
  818. else
  819. Begin
  820. for i:=-1 to 1 do
  821. Begin
  822. for PixelCount:=y1 to y2 do
  823. { compare if we should plot a pixel here , compare }
  824. { with predefined line patterns... }
  825. if LinePatterns[PixelCount and 15] = TRUE then
  826. begin
  827. DirectPutPixelClip(x1+i,PixelCount);
  828. end;
  829. end;
  830. end;
  831. end
  832. else
  833. Begin
  834. oldCurrentColor := CurrentColor;
  835. { Calculate deltax and deltay for initialisation }
  836. deltax := abs(x2 - x1);
  837. deltay := abs(y2 - y1);
  838. { Initialize all vars based on which is the independent variable }
  839. if deltax >= deltay then
  840. begin
  841. Flag := FALSE;
  842. { x is independent variable }
  843. numpixels := deltax + 1;
  844. d := (2 * deltay) - deltax;
  845. dinc1 := deltay Shl 1;
  846. dinc2 := (deltay - deltax) shl 1;
  847. xinc1 := 1;
  848. xinc2 := 1;
  849. yinc1 := 0;
  850. yinc2 := 1;
  851. end
  852. else
  853. begin
  854. Flag := TRUE;
  855. { y is independent variable }
  856. numpixels := deltay + 1;
  857. d := (2 * deltax) - deltay;
  858. dinc1 := deltax Shl 1;
  859. dinc2 := (deltax - deltay) shl 1;
  860. xinc1 := 0;
  861. xinc2 := 1;
  862. yinc1 := 1;
  863. yinc2 := 1;
  864. end;
  865. { Make sure x and y move in the right directions }
  866. if x1 > x2 then
  867. begin
  868. xinc1 := - xinc1;
  869. xinc2 := - xinc2;
  870. end;
  871. if y1 > y2 then
  872. begin
  873. yinc1 := - yinc1;
  874. yinc2 := - yinc2;
  875. end;
  876. { Start drawing at <x1, y1> }
  877. x := x1;
  878. y := y1;
  879. If LineInfo.Thickness=ThickWidth then
  880. Begin
  881. TmpNumPixels := NumPixels-1;
  882. { Draw the pixels }
  883. for i := 0 to TmpNumPixels do
  884. begin
  885. { all depending on the slope, we can determine }
  886. { in what direction the extra width pixels will be put }
  887. If Flag then
  888. Begin
  889. { compare if we should plot a pixel here , compare }
  890. { with predefined line patterns... }
  891. if LinePatterns[i and 15] = TRUE then
  892. begin
  893. DirectPutPixelClip(x-1,y);
  894. DirectPutPixelClip(x,y);
  895. DirectPutPixelClip(x+1,y);
  896. end;
  897. end
  898. else
  899. Begin
  900. { compare if we should plot a pixel here , compare }
  901. { with predefined line patterns... }
  902. if LinePatterns[i and 15] = TRUE then
  903. begin
  904. DirectPutPixelClip(x,y-1);
  905. DirectPutPixelClip(x,y);
  906. DirectPutPixelClip(x,y+1);
  907. end;
  908. end;
  909. if d < 0 then
  910. begin
  911. d := d + dinc1;
  912. x := x + xinc1;
  913. y := y + yinc1;
  914. end
  915. else
  916. begin
  917. d := d + dinc2;
  918. x := x + xinc2;
  919. y := y + yinc2;
  920. end;
  921. end;
  922. end
  923. else
  924. Begin
  925. { instead of putting in loop , substract by one now }
  926. TmpNumPixels := NumPixels-1;
  927. { NormWidth }
  928. for i := 0 to TmpNumPixels do
  929. begin
  930. if LinePatterns[i and 15] = TRUE then
  931. begin
  932. DirectPutPixel(x,y);
  933. end;
  934. if d < 0 then
  935. begin
  936. d := d + dinc1;
  937. x := x + xinc1;
  938. y := y + yinc1;
  939. end
  940. else
  941. begin
  942. d := d + dinc2;
  943. x := x + xinc2;
  944. y := y + yinc2;
  945. end;
  946. end;
  947. end
  948. end;
  949. {******************************************}
  950. { end patterned lines }
  951. {******************************************}
  952. { restore color }
  953. CurrentColor:=OldCurrentColor;
  954. end;
  955. end;
  956. end; { Line }
  957. { multipage support could be done by using more than one background bitmap }
  958. procedure SetVisualWin32GUI(page: word);
  959. begin
  960. end;
  961. procedure SetActiveWin32GUI(page: word);
  962. begin
  963. end;
  964. function queryadapterinfo : pmodeinfo;
  965. var
  966. mode: TModeInfo;
  967. ScreenWidth,ScreenHeight : longint;
  968. ScreenWidthMaximized,ScreenHeightMaximized : longint;
  969. begin
  970. SaveVideoState:=savestate;
  971. RestoreVideoState:=restorestate;
  972. { we must take care of the border and caption }
  973. ScreenWidth:=GetSystemMetrics(SM_CXSCREEN)-
  974. 2*GetSystemMetrics(SM_CXFRAME);
  975. ScreenHeight:=GetSystemMetrics(SM_CYSCREEN)-
  976. 2*GetSystemMetrics(SM_CYFRAME)-
  977. GetSystemMetrics(SM_CYCAPTION);
  978. { for maximozed windows it's again different }
  979. { here we've only a caption }
  980. ScreenWidthMaximized:=GetSystemMetrics(SM_CXFULLSCREEN);
  981. { neither GetSystemMetrics(SM_CYFULLSCREEN nor }
  982. { SystemParametersInfo(SPI_GETWORKAREA) }
  983. { takes a hidden try into account :( FK }
  984. ScreenHeightMaximized:=GetSystemMetrics(SM_CYFULLSCREEN);
  985. QueryAdapterInfo := ModeList;
  986. { If the mode listing already exists... }
  987. { simply return it, without changing }
  988. { anything... }
  989. if assigned(ModeList) then
  990. exit;
  991. { the first one becomes the standard mode }
  992. if (ScreenWidth>=640) and (ScreenHeight>=480) then
  993. begin
  994. InitMode(mode);
  995. mode.DriverNumber:= VGA;
  996. mode.HardwarePages:= 0;
  997. mode.ModeNumber:=VGAHi;
  998. mode.ModeName:='640 x 480 x 16 Win32GUI';
  999. mode.MaxColor := 16;
  1000. mode.PaletteSize := mode.MaxColor;
  1001. mode.DirectColor := FALSE;
  1002. mode.MaxX := 639;
  1003. mode.MaxY := 479;
  1004. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1005. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1006. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1007. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1008. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1009. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1010. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1011. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1012. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1013. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1014. // mode.Line:={$ifdef fpc}@{$endif}LineWin32GUI;
  1015. mode.XAspect := 10000;
  1016. mode.YAspect := 10000;
  1017. AddMode(mode);
  1018. end;
  1019. if (ScreenWidth>=640) and (ScreenHeight>=200) then
  1020. begin
  1021. InitMode(mode);
  1022. { now add all standard VGA modes... }
  1023. mode.DriverNumber:= VGA;
  1024. mode.HardwarePages:= 0;
  1025. mode.ModeNumber:=VGALo;
  1026. mode.ModeName:='640 x 200 x 16 Win32GUI';
  1027. mode.MaxColor := 16;
  1028. mode.PaletteSize := mode.MaxColor;
  1029. mode.DirectColor := FALSE;
  1030. mode.MaxX := 639;
  1031. mode.MaxY := 199;
  1032. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1033. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1034. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1035. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1036. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1037. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1038. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1039. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1040. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1041. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1042. mode.XAspect := 10000;
  1043. mode.YAspect := 10000;
  1044. AddMode(mode);
  1045. end;
  1046. if (ScreenWidth>=640) and (ScreenHeight>=350) then
  1047. begin
  1048. InitMode(mode);
  1049. mode.DriverNumber:= VGA;
  1050. mode.HardwarePages:= 0;
  1051. mode.ModeNumber:=VGAMed;
  1052. mode.ModeName:='640 x 350 x 16 Win32GUI';
  1053. mode.MaxColor := 16;
  1054. mode.PaletteSize := mode.MaxColor;
  1055. mode.DirectColor := FALSE;
  1056. mode.MaxX := 639;
  1057. mode.MaxY := 349;
  1058. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1059. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1060. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1061. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1062. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1063. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1064. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1065. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1066. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1067. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1068. mode.XAspect := 10000;
  1069. mode.YAspect := 10000;
  1070. AddMode(mode);
  1071. end;
  1072. if (ScreenWidth>=640) and (ScreenHeight>=400) then
  1073. begin
  1074. InitMode(mode);
  1075. mode.DriverNumber:= VESA;
  1076. mode.HardwarePages:= 0;
  1077. mode.ModeNumber:=m640x400x256;
  1078. mode.ModeName:='640 x 400 x 256 Win32GUI';
  1079. mode.MaxColor := 256;
  1080. mode.PaletteSize := mode.MaxColor;
  1081. mode.DirectColor := FALSE;
  1082. mode.MaxX := 639;
  1083. mode.MaxY := 399;
  1084. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1085. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1086. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1087. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1088. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1089. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1090. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1091. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1092. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1093. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1094. mode.XAspect := 10000;
  1095. mode.YAspect := 10000;
  1096. AddMode(mode);
  1097. end;
  1098. if (ScreenWidth>=640) and (ScreenHeight>=480) then
  1099. begin
  1100. InitMode(mode);
  1101. mode.DriverNumber:= VESA;
  1102. mode.HardwarePages:= 0;
  1103. mode.ModeNumber:=m640x480x256;
  1104. mode.ModeName:='640 x 480 x 256 Win32GUI';
  1105. mode.MaxColor := 256;
  1106. mode.PaletteSize := mode.MaxColor;
  1107. mode.DirectColor := FALSE;
  1108. mode.MaxX := 639;
  1109. mode.MaxY := 479;
  1110. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1111. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1112. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1113. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1114. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1115. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1116. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1117. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1118. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1119. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1120. mode.XAspect := 10000;
  1121. mode.YAspect := 10000;
  1122. AddMode(mode);
  1123. end;
  1124. { add 800x600 only if screen is large enough }
  1125. If (ScreenWidth>=800) and (ScreenHeight>=600) then
  1126. begin
  1127. InitMode(mode);
  1128. mode.DriverNumber:= VESA;
  1129. mode.HardwarePages:= 0;
  1130. mode.ModeNumber:=m800x600x16;
  1131. mode.ModeName:='800 x 600 x 16 Win32GUI';
  1132. mode.MaxColor := 16;
  1133. mode.PaletteSize := mode.MaxColor;
  1134. mode.DirectColor := FALSE;
  1135. mode.MaxX := 799;
  1136. mode.MaxY := 599;
  1137. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1138. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1139. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1140. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1141. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1142. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1143. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1144. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1145. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1146. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1147. mode.XAspect := 10000;
  1148. mode.YAspect := 10000;
  1149. AddMode(mode);
  1150. InitMode(mode);
  1151. mode.DriverNumber:= VESA;
  1152. mode.HardwarePages:= 0;
  1153. mode.ModeNumber:=m800x600x256;
  1154. mode.ModeName:='800 x 600 x 256 Win32GUI';
  1155. mode.MaxColor := 256;
  1156. mode.PaletteSize := mode.MaxColor;
  1157. mode.DirectColor := FALSE;
  1158. mode.MaxX := 799;
  1159. mode.MaxY := 599;
  1160. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1161. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1162. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1163. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1164. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1165. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1166. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1167. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1168. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1169. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1170. mode.XAspect := 10000;
  1171. mode.YAspect := 10000;
  1172. AddMode(mode);
  1173. end;
  1174. { add 1024x768 only if screen is large enough }
  1175. If (ScreenWidth>=1024) and (ScreenHeight>=768) then
  1176. begin
  1177. InitMode(mode);
  1178. mode.DriverNumber:= VESA;
  1179. mode.HardwarePages:= 0;
  1180. mode.ModeNumber:=m1024x768x16;
  1181. mode.ModeName:='1024 x 768 x 16 Win32GUI';
  1182. mode.MaxColor := 16;
  1183. mode.PaletteSize := mode.MaxColor;
  1184. mode.DirectColor := FALSE;
  1185. mode.MaxX := 1023;
  1186. mode.MaxY := 767;
  1187. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1188. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1189. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1190. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1191. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1192. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1193. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1194. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1195. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1196. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1197. mode.XAspect := 10000;
  1198. mode.YAspect := 10000;
  1199. AddMode(mode);
  1200. InitMode(mode);
  1201. mode.DriverNumber:= VESA;
  1202. mode.HardwarePages:= 0;
  1203. mode.ModeNumber:=m1024x768x256;
  1204. mode.ModeName:='1024 x 768 x 256 Win32GUI';
  1205. mode.MaxColor := 256;
  1206. mode.PaletteSize := mode.MaxColor;
  1207. mode.DirectColor := FALSE;
  1208. mode.MaxX := 1023;
  1209. mode.MaxY := 768;
  1210. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1211. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1212. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1213. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1214. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1215. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1216. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1217. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1218. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1219. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1220. mode.XAspect := 10000;
  1221. mode.YAspect := 10000;
  1222. AddMode(mode);
  1223. end;
  1224. { add 1280x1024 only if screen is large enough }
  1225. If (ScreenWidth>=1280) and (ScreenHeight>=1024) then
  1226. begin
  1227. InitMode(mode);
  1228. mode.DriverNumber:= VESA;
  1229. mode.HardwarePages:= 0;
  1230. mode.ModeNumber:=m1280x1024x16;
  1231. mode.ModeName:='1280 x 1024 x 16 Win32GUI';
  1232. mode.MaxColor := 16;
  1233. mode.PaletteSize := mode.MaxColor;
  1234. mode.DirectColor := FALSE;
  1235. mode.MaxX := 1279;
  1236. mode.MaxY := 1023;
  1237. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1238. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1239. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1240. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1241. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1242. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1243. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1244. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1245. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1246. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1247. mode.XAspect := 10000;
  1248. mode.YAspect := 10000;
  1249. AddMode(mode);
  1250. InitMode(mode);
  1251. mode.DriverNumber:= VESA;
  1252. mode.HardwarePages:= 0;
  1253. mode.ModeNumber:=m1280x1024x256;
  1254. mode.ModeName:='1280 x 1024 x 256 Win32GUI';
  1255. mode.MaxColor := 256;
  1256. mode.PaletteSize := mode.MaxColor;
  1257. mode.DirectColor := FALSE;
  1258. mode.MaxX := 1279;
  1259. mode.MaxY := 1023;
  1260. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1261. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1262. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1263. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1264. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1265. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1266. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1267. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1268. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1269. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1270. mode.XAspect := 10000;
  1271. mode.YAspect := 10000;
  1272. AddMode(mode);
  1273. end;
  1274. { at least we add a mode with the largest possible window }
  1275. InitMode(mode);
  1276. mode.DriverNumber:= VESA;
  1277. mode.HardwarePages:= 0;
  1278. mode.ModeNumber:=mLargestWindow16;
  1279. mode.ModeName:='Largest Window x 16';
  1280. mode.MaxColor := 16;
  1281. mode.PaletteSize := mode.MaxColor;
  1282. mode.DirectColor := FALSE;
  1283. mode.MaxX := ScreenWidth-1;
  1284. mode.MaxY := ScreenHeight-1;
  1285. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1286. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1287. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1288. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1289. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1290. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1291. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1292. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1293. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1294. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1295. mode.XAspect := 10000;
  1296. mode.YAspect := 10000;
  1297. AddMode(mode);
  1298. InitMode(mode);
  1299. mode.DriverNumber:= VESA;
  1300. mode.HardwarePages:= 0;
  1301. mode.ModeNumber:=mLargestWindow256;
  1302. mode.ModeName:='Largest Window x 256';
  1303. mode.MaxColor := 256;
  1304. mode.PaletteSize := mode.MaxColor;
  1305. mode.DirectColor := FALSE;
  1306. mode.MaxX := ScreenWidth-1;
  1307. mode.MaxY := ScreenHeight-1;
  1308. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1309. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1310. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1311. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1312. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1313. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1314. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1315. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1316. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1317. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1318. mode.XAspect := 10000;
  1319. mode.YAspect := 10000;
  1320. AddMode(mode);
  1321. { .. and a maximized window }
  1322. InitMode(mode);
  1323. mode.DriverNumber:= VESA;
  1324. mode.HardwarePages:= 0;
  1325. mode.ModeNumber:=mMaximizedWindow16;
  1326. mode.ModeName:='Maximized Window x 16';
  1327. mode.MaxColor := 16;
  1328. mode.PaletteSize := mode.MaxColor;
  1329. mode.DirectColor := FALSE;
  1330. mode.MaxX := ScreenWidthMaximized-1;
  1331. mode.MaxY := ScreenHeightMaximized-1;
  1332. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1333. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1334. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1335. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1336. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1337. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1338. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1339. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1340. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1341. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1342. mode.XAspect := 10000;
  1343. mode.YAspect := 10000;
  1344. AddMode(mode);
  1345. InitMode(mode);
  1346. mode.DriverNumber:= VESA;
  1347. mode.HardwarePages:= 0;
  1348. mode.ModeNumber:=mMaximizedWindow256;
  1349. mode.ModeName:='Maximized Window x 256';
  1350. mode.MaxColor := 256;
  1351. mode.PaletteSize := mode.MaxColor;
  1352. mode.DirectColor := FALSE;
  1353. mode.MaxX := ScreenWidthMaximized-1;
  1354. mode.MaxY := ScreenHeightMaximized-1;
  1355. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1356. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1357. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1358. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1359. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1360. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1361. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1362. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1363. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1364. mode.DrawBitmapCharHoriz:={$ifdef fpc}@{$endif}DrawBitmapCharHorizWin32GUI;
  1365. mode.XAspect := 10000;
  1366. mode.YAspect := 10000;
  1367. AddMode(mode);
  1368. end;
  1369. begin
  1370. InitializeGraph;
  1371. end.
  1372. {
  1373. $Log$
  1374. Revision 1.6 2000-03-27 12:57:30 florian
  1375. * some "resource leaks" fixed
  1376. Revision 1.5 2000/03/25 19:10:11 florian
  1377. * colored bitmap font drawing fixed: the color brush
  1378. was selected for the recovery bitmap
  1379. Revision 1.4 2000/03/24 18:18:15 florian
  1380. * accelerated output of bitmap fonts
  1381. Revision 1.3 2000/03/24 12:57:41 florian
  1382. * the window is now cleared by wm_create
  1383. * default mode is again 640x480x16
  1384. Revision 1.2 2000/03/24 10:49:17 florian
  1385. * the mode detection takes now care of window caption and border
  1386. + 1024x768 and 1280x1024 modes added
  1387. + special gui modes added: largest window and maximized window to
  1388. use the desktop as much as possible
  1389. * Hline fixed: the windows function LineTo doesn't draw the last pixel!
  1390. Revision 1.1 2000/03/19 11:20:14 peter
  1391. * graph unit include is now independent and the dependent part
  1392. is now in graph.pp
  1393. * ggigraph unit for linux added
  1394. Revision 1.8 2000/03/17 22:53:20 florian
  1395. * window class is registered only once => multible init/closegraphs are possible
  1396. * calling cleardevice when creating the window
  1397. Revision 1.7 2000/03/05 13:06:32 florian
  1398. * the title can be user defined
  1399. Revision 1.6 2000/01/07 16:41:52 daniel
  1400. * copyright 2000
  1401. Revision 1.5 1999/12/08 09:09:34 pierre
  1402. + add VESA compatible mode in 16 and 256 colors
  1403. Revision 1.4 1999/12/02 00:24:36 pierre
  1404. * local var col was undefined
  1405. + 640x200 and 640x350 modes added (VGALo and VGAMed)
  1406. * WM_PAINT better handled (only requested region written)
  1407. Revision 1.3 1999/11/30 22:36:53 florian
  1408. * the wm_nc... messages aren't handled anymore it leads to too mch problems ...
  1409. Revision 1.2 1999/11/29 22:03:39 florian
  1410. * first implementation of winmouse unit
  1411. Revision 1.1 1999/11/08 11:15:22 peter
  1412. * move graph.inc to the target dir
  1413. Revision 1.1 1999/11/03 20:23:02 florian
  1414. + first release of win32 gui support
  1415. }