Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

667 lines
17 KiB

  1. #include <windows.h>
  2. #include <windowsx.h>
  3. #include "lockbm.h"
  4. //////////////////////////////////////////////////////////////////////////////
  5. //////////////////////////////////////////////////////////////////////////////
  6. #ifndef BI_BITFIELDS
  7. #define BI_BITFIELDS 3
  8. #endif
  9. #ifndef BI_BITMAP
  10. #define BI_BITMAP 0x4D544942 // 'BITM'
  11. #endif
  12. //////////////////////////////////////////////////////////////////////////////
  13. //////////////////////////////////////////////////////////////////////////////
  14. //
  15. // GDI!GDIInit2() GDI.403
  16. //
  17. // this GDI function does the following:
  18. //
  19. // GetSetBitmapHandle(hbm, 0) - will return global handle of bitmap
  20. //
  21. // GetSetBitmapHandle(hbm, h) - will set global handle to <h>
  22. //
  23. // GetSetBitmapHandle(hbm, -1) - will set global handle to NULL
  24. //
  25. static HANDLE (FAR PASCAL *GetSetBitmapHandle)(HBITMAP hbm, HANDLE h);
  26. //////////////////////////////////////////////////////////////////////////////
  27. //////////////////////////////////////////////////////////////////////////////
  28. #define muldiv(a,b,c) (UINT)(((DWORD)(UINT)(a) * (DWORD)(UINT)(b)) / (UINT)(c))
  29. //////////////////////////////////////////////////////////////////////////////
  30. //
  31. // CanLockBitmaps()
  32. //
  33. // determime if we can lock bitmaps on the current display device
  34. //
  35. //////////////////////////////////////////////////////////////////////////////
  36. BOOL FAR CanLockBitmaps(void)
  37. {
  38. return FALSE;
  39. #if 0
  40. UINT w;
  41. UINT rc;
  42. HDC hdc;
  43. BOOL f;
  44. static BOOL fCanLockBitmaps = -1;
  45. if (fCanLockBitmaps == -1)
  46. {
  47. w = (UINT)GetVersion();
  48. w = ((UINT)LOBYTE(w) << 8) | HIBYTE(w);
  49. hdc = GetDC(NULL);
  50. rc = GetDeviceCaps(hdc, RASTERCAPS);
  51. ReleaseDC(NULL, hdc);
  52. (FARPROC)GetSetBitmapHandle =
  53. GetProcAddress(GetModuleHandle("GDI"),MAKEINTATOM(403));
  54. //
  55. // assume we dont need this on windows 4.0?
  56. //
  57. // what about the DIBENG? it does DEVBITS and in win 4.0?
  58. //
  59. // if the display handles device bitmaps, dont do this either
  60. //
  61. f = GetProfileInt("DrawDib", "Bitmaps", TRUE);
  62. #ifdef DEBUG
  63. fCanLockBitmaps = f && GetSetBitmapHandle != NULL;
  64. #else
  65. fCanLockBitmaps = f && /* (w < 0x0400) && */
  66. !(rc & RC_DEVBITS) &&
  67. GetSetBitmapHandle != NULL;
  68. #endif
  69. }
  70. return fCanLockBitmaps;
  71. #endif
  72. }
  73. //////////////////////////////////////////////////////////////////////////////
  74. //
  75. // LockBitmap
  76. //
  77. // return a pointer to the bitmap bits
  78. //
  79. //////////////////////////////////////////////////////////////////////////////
  80. LPVOID FAR LockBitmap(HBITMAP hbm)
  81. {
  82. return GetBitmap(hbm, NULL, 0);
  83. }
  84. //////////////////////////////////////////////////////////////////////////////
  85. //
  86. // GetBitmapDIB
  87. //
  88. //////////////////////////////////////////////////////////////////////////////
  89. LPVOID FAR GetBitmapDIB(LPBITMAPINFOHEADER lpbi, LPVOID lpBits, LPVOID p, int cb)
  90. {
  91. IBITMAP FAR *pbm;
  92. if (lpBits == NULL)
  93. lpBits = (LPBYTE)lpbi + (int)lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD);
  94. if (p == NULL || cb < sizeof(BITMAP))
  95. return lpBits;
  96. pbm = p;
  97. if (lpbi->biCompression == 0)
  98. {
  99. switch ((int)lpbi->biBitCount + (int)lpbi->biPlanes*256)
  100. {
  101. case 0x0101: pbm->bmType = BM_1BIT; break;
  102. case 0x0104: pbm->bmType = BM_4BIT; break;
  103. case 0x0108: pbm->bmType = BM_8BIT; break;
  104. case 0x0110: pbm->bmType = BM_16555; break;
  105. case 0x0118: pbm->bmType = BM_24BGR; break;
  106. case 0x0120: pbm->bmType = BM_32BGR; break;
  107. case 0x0401: pbm->bmType = BM_VGA; break;
  108. default: return NULL;
  109. }
  110. }
  111. else if (lpbi->biCompression == BI_BITFIELDS)
  112. {
  113. switch ((int)lpbi->biBitCount + (int)lpbi->biPlanes*256)
  114. {
  115. //!!! hack: realy should check the bit fields!
  116. case 0x0110: pbm->bmType = BM_16565; break;
  117. case 0x0118: pbm->bmType = BM_24RGB; break;
  118. case 0x0120: pbm->bmType = BM_32RGB; break;
  119. default: return NULL;
  120. }
  121. }
  122. else
  123. return NULL;
  124. pbm->bmWidth = (int)lpbi->biWidth;
  125. pbm->bmHeight = ((int)lpbi->biHeight > 0) ? (int)lpbi->biHeight : -(int)lpbi->biHeight;
  126. pbm->bmWidthBytes = (((int)lpbi->biBitCount * (int)lpbi->biWidth + 31)&~31)/8;
  127. pbm->bmPlanes = (BYTE)lpbi->biPlanes;
  128. pbm->bmBitsPixel = (BYTE)lpbi->biBitCount;
  129. pbm->bmBits = lpBits;
  130. if (cb > sizeof(BITMAP))
  131. {
  132. pbm->bmSegmentIndex = 0;
  133. pbm->bmScanSegment = pbm->bmHeight;
  134. pbm->bmFillBytes = 0;
  135. pbm->bmBitmapInfo = (long)lpbi;
  136. if ((long)lpbi->biHeight < 0)
  137. {
  138. pbm->bmNextScan = -pbm->bmWidthBytes;
  139. pbm->bmOffset = (long)pbm->bmWidthBytes * (pbm->bmHeight-1);
  140. }
  141. else
  142. {
  143. pbm->bmNextScan = pbm->bmWidthBytes;
  144. pbm->bmOffset = 0;
  145. }
  146. }
  147. return lpBits;
  148. }
  149. #if 0
  150. //////////////////////////////////////////////////////////////////////////////
  151. //////////////////////////////////////////////////////////////////////////////
  152. void FAR BitmapXY(IBITMAP FAR *pbm, int x, int y)
  153. {
  154. UINT t;
  155. if (pbm->bmFillBytes)
  156. {
  157. while (y-- > 0)
  158. {
  159. t = (UINT)(pbm->bmOffset & 0xFFFF0000);
  160. pbm->bmOffset += pbm->bmNextScan;
  161. if ((UINT)(pbm->bmOffset & 0xFFFF0000) != t)
  162. pbm->bmOffset += pbm->bmFillBytes;
  163. }
  164. }
  165. else
  166. {
  167. pbm->bmOffset += y * (long)pbm->bmNextScan;
  168. }
  169. pbm->bmOffset += x * pbm->bmBitsPixel / 8;
  170. }
  171. #endif
  172. //////////////////////////////////////////////////////////////////////////////
  173. //
  174. // GetDIBBitmap
  175. //
  176. //////////////////////////////////////////////////////////////////////////////
  177. LPVOID FAR GetDIBBitmap(HBITMAP hbm, LPBITMAPINFOHEADER lpbi)
  178. {
  179. UINT wType;
  180. BITMAP bm;
  181. UINT ScansPerSeg;
  182. UINT FillBytes;
  183. if (hbm)
  184. GetObject(hbm, sizeof(bm), &bm);
  185. wType = GetBitmapType();
  186. if (wType == 0)
  187. return NULL;
  188. lpbi->biSize = sizeof(BITMAPINFOHEADER);
  189. lpbi->biWidth = bm.bmWidth;
  190. lpbi->biHeight = bm.bmHeight;
  191. lpbi->biPlanes = bm.bmPlanes;
  192. lpbi->biBitCount = bm.bmBitsPixel;
  193. lpbi->biCompression = 0;
  194. lpbi->biSizeImage = (DWORD)(bm.bmWidthBytes * bm.bmPlanes) * (DWORD)bm.bmHeight;
  195. lpbi->biXPelsPerMeter = 0;
  196. lpbi->biYPelsPerMeter = 0;
  197. lpbi->biClrUsed = 0;
  198. lpbi->biClrImportant = 0;
  199. switch(wType & BM_TYPE)
  200. {
  201. case BM_VGA:
  202. break;
  203. case BM_1BIT:
  204. case BM_4BIT:
  205. case BM_8BIT:
  206. break;
  207. case BM_16555:
  208. break;
  209. case BM_24BGR:
  210. case BM_32BGR:
  211. break;
  212. case BM_16565:
  213. lpbi->biCompression = BI_BITFIELDS;
  214. ((LPDWORD)(lpbi+1))[0] = 0x00F800;
  215. ((LPDWORD)(lpbi+1))[1] = 0x0007E0;
  216. ((LPDWORD)(lpbi+1))[2] = 0x00001F;
  217. break;
  218. case BM_24RGB:
  219. case BM_32RGB:
  220. lpbi->biCompression = BI_BITFIELDS;
  221. ((LPDWORD)(lpbi+1))[0] = 0x0000FF;
  222. ((LPDWORD)(lpbi+1))[1] = 0x00FF00;
  223. ((LPDWORD)(lpbi+1))[2] = 0xFF0000;
  224. break;
  225. default:
  226. return NULL;
  227. }
  228. //
  229. // make sure WidthBytes is right, dont forget bitmaps are WORD aligned
  230. // and DIBs are DWORD aligned.
  231. //
  232. if (bm.bmWidthBytes != ((bm.bmWidth * bm.bmBitsPixel + 31) & ~31)/8)
  233. {
  234. if (lpbi->biCompression != 0)
  235. return NULL;
  236. lpbi->biCompression = BI_BITMAP;
  237. lpbi->biXPelsPerMeter = bm.bmWidthBytes;
  238. }
  239. if ((wType & BM_HUGE) && (lpbi->biSizeImage > 64*1024l))
  240. {
  241. if (lpbi->biCompression == BI_BITFIELDS)
  242. return NULL;
  243. lpbi->biCompression = BI_BITMAP;
  244. ScansPerSeg = muldiv(64,1024,bm.bmWidthBytes * bm.bmPlanes);
  245. FillBytes = (UINT)(64ul*1024 - bm.bmWidthBytes * bm.bmPlanes * ScansPerSeg);
  246. lpbi->biSizeImage += FillBytes * (bm.bmHeight / ScansPerSeg);
  247. lpbi->biXPelsPerMeter = bm.bmWidthBytes;
  248. lpbi->biYPelsPerMeter = FillBytes;
  249. }
  250. if (!(wType & BM_BOTTOMTOTOP))
  251. lpbi->biHeight = -bm.bmHeight;
  252. return LockBitmap(hbm);
  253. }
  254. //////////////////////////////////////////////////////////////////////////////
  255. //
  256. // GetBitmap
  257. //
  258. //////////////////////////////////////////////////////////////////////////////
  259. LPVOID FAR GetBitmap(HBITMAP hbm, LPVOID p, int cb)
  260. {
  261. HANDLE h;
  262. DWORD dwSize;
  263. IBITMAP FAR *pbm;
  264. HDC hdc = NULL;
  265. HBITMAP hbmT;
  266. if (!CanLockBitmaps())
  267. return NULL;
  268. if (hbm == NULL)
  269. return NULL;
  270. h = GetSetBitmapHandle(hbm, 0);
  271. if (h == NULL)
  272. return NULL;
  273. pbm = (LPVOID)GlobalLock(h);
  274. if (IsBadReadPtr(pbm, sizeof(IBITMAP)))
  275. return NULL;
  276. //
  277. // see if it is realy a bitmap.
  278. //
  279. if (pbm->bmType != 0)
  280. return NULL;
  281. //
  282. // make sure the bmBits pointer is valid.
  283. //
  284. if (pbm->bmBits == NULL)
  285. {
  286. hdc = CreateCompatibleDC(NULL);
  287. hbmT = SelectObject(hdc, hbm);
  288. }
  289. dwSize = (DWORD)pbm->bmHeight * (DWORD)pbm->bmWidthBytes;
  290. if (IsBadHugeWritePtr((LPVOID)pbm->bmBits, dwSize))
  291. {
  292. if (hdc)
  293. {
  294. SelectObject(hdc, hbmT);
  295. DeleteDC(hdc);
  296. }
  297. return NULL;
  298. }
  299. if (p)
  300. {
  301. UINT u;
  302. hmemcpy(p, pbm, min(cb, sizeof(IBITMAP)));
  303. pbm = p;
  304. u = GetBitmapType();
  305. pbm->bmType = u & BM_TYPE;
  306. if (cb > sizeof(BITMAP))
  307. {
  308. pbm->bmBitmapInfo = NULL;
  309. pbm->bmNextScan = pbm->bmWidthBytes * pbm->bmPlanes;
  310. if (u & BM_BOTTOMTOTOP)
  311. {
  312. pbm->bmOffset = 0;
  313. }
  314. else
  315. {
  316. pbm->bmOffset = (long)pbm->bmNextScan * (pbm->bmHeight-1);
  317. pbm->bmNextScan = -pbm->bmNextScan;
  318. pbm->bmFillBytes = -pbm->bmFillBytes;
  319. }
  320. //
  321. // see if this particular bitmap is HUGE
  322. //
  323. if (!(u & BM_HUGE) || (DWORD)pbm->bmHeight * pbm->bmWidthBytes < 64l*1024)
  324. {
  325. pbm->bmFillBytes = 0;
  326. pbm->bmScanSegment = pbm->bmHeight;
  327. }
  328. else
  329. {
  330. if (pbm->bmOffset)
  331. pbm->bmOffset -= (long)((pbm->bmHeight-1) / pbm->bmScanSegment) * pbm->bmFillBytes;
  332. }
  333. }
  334. }
  335. if (hdc)
  336. {
  337. SelectObject(hdc, hbmT);
  338. DeleteDC(hdc);
  339. }
  340. return (LPVOID)pbm->bmBits;
  341. }
  342. /////////////////////////////////////////////////////////////////////////////
  343. //
  344. // SetPixel
  345. //
  346. // some cards cant't seam to do SetPixel right it is amazing they work at all
  347. //
  348. /////////////////////////////////////////////////////////////////////////////
  349. static void SetPixelX(HDC hdc, int x, int y, COLORREF rgb)
  350. {
  351. RECT rc;
  352. rc.left = x;
  353. rc.top = y;
  354. rc.right = x+1;
  355. rc.bottom = y+1;
  356. SetBkColor(hdc, rgb);
  357. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
  358. }
  359. #define SetPixel SetPixelX
  360. ///////////////////////////////////////////////////////////////////////////////
  361. //
  362. // GetSurfaceType
  363. //
  364. ///////////////////////////////////////////////////////////////////////////////
  365. #define BCODE _based(_segname("_CODE"))
  366. static BYTE BCODE bits8[] = {0x00,0xF9,0xFA,0xFC,0xFF};
  367. static WORD BCODE bits555[] = {0x0000,0x7C00,0x03E0,0x001F,0x7FFF};
  368. static WORD BCODE bits5551[]= {0x8000,0xFC00,0x83E0,0x801F,0xFFFF};
  369. static WORD BCODE bits565[] = {0x0000,0xF800,0x07E0,0x001F,0xFFFF};
  370. static BYTE BCODE bitsBGR[] = {0x00,0x00,0x00, 0x00,0x00,0xFF, 0x00,0xFF,0x00, 0xFF,0x00,0x00, 0xFF,0xFF,0xFF};
  371. static BYTE BCODE bitsRGB[] = {0x00,0x00,0x00, 0xFF,0x00,0x00, 0x00,0xFF,0x00, 0x00,0x00,0xFF, 0xFF,0xFF,0xFF};
  372. static DWORD BCODE bitsRGBX[]= {0x000000, 0x0000FF, 0x00FF00, 0xFF0000, 0xFFFFFF};
  373. static DWORD BCODE bitsBGRX[]= {0x000000, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFFFF};
  374. void FAR TestSurfaceType(HDC hdc, int x, int y)
  375. {
  376. PatBlt(hdc, x, y, 5, 1, BLACKNESS);
  377. SetPixel(hdc, x+0, y, RGB(000,000,000));
  378. SetPixel(hdc, x+1, y, RGB(255,000,000));
  379. SetPixel(hdc, x+2, y, RGB(000,255,000));
  380. SetPixel(hdc, x+3, y, RGB(000,000,255));
  381. SetPixel(hdc, x+4, y, RGB(255,255,255));
  382. GetPixel(hdc, x, y);
  383. }
  384. UINT FAR GetSurfaceType(LPVOID lpBits)
  385. {
  386. #define TESTFMT(a,n) \
  387. if (_fmemcmp(lpBits, (LPVOID)a, sizeof(a)) == 0) return n;
  388. TESTFMT(bits8, BM_8BIT);
  389. TESTFMT(bits555, BM_16555);
  390. TESTFMT(bits5551, BM_16555);
  391. TESTFMT(bits565, BM_16565);
  392. TESTFMT(bitsRGB, BM_24RGB);
  393. TESTFMT(bitsBGR, BM_24BGR);
  394. TESTFMT(bitsRGBX, BM_32RGB);
  395. TESTFMT(bitsBGRX, BM_32BGR);
  396. return 0;
  397. }
  398. ///////////////////////////////////////////////////////////////////////////////
  399. //
  400. // GetBitmapType
  401. //
  402. // return the bitmap type that the display driver uses
  403. //
  404. ///////////////////////////////////////////////////////////////////////////////
  405. UINT FAR GetBitmapType()
  406. {
  407. BITMAP bm;
  408. HBITMAP hbm;
  409. HBITMAP hbmT;
  410. HDC hdc;
  411. UINT u;
  412. BYTE bits[20*4*2];
  413. static UINT wBitmapType = 0xFFFF;
  414. if (wBitmapType != 0xFFFF)
  415. return wBitmapType;
  416. //
  417. // create a test bitmap (<64k)
  418. //
  419. hdc = GetDC(NULL);
  420. hbm = CreateCompatibleBitmap(hdc,20,2);
  421. ReleaseDC(NULL, hdc);
  422. hdc = CreateCompatibleDC(NULL);
  423. hbmT = SelectObject(hdc, hbm);
  424. GetObject(hbm, sizeof(bm), &bm);
  425. PatBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, BLACKNESS);
  426. TestSurfaceType(hdc, 0, 0);
  427. GetBitmapBits(hbm, sizeof(bits), bits);
  428. u = GetSurfaceType(bits);
  429. if (u == 0) {
  430. u = GetSurfaceType(bits + bm.bmWidthBytes);
  431. if (u)
  432. u |= BM_BOTTOMTOTOP;
  433. }
  434. #ifndef WIN32
  435. if (u) {
  436. BYTE _huge *pb;
  437. UINT dy,w;
  438. //
  439. // see if bitmap(s) are huge format
  440. //
  441. dy = (UINT)(0x10000l/bm.bmWidthBytes) + 1;
  442. hbm = CreateCompatibleBitmap(hdc,bm.bmWidth,dy);
  443. DeleteObject(SelectObject(hdc, hbm));
  444. PatBlt(hdc, 0, 0, bm.bmWidth, dy, BLACKNESS);
  445. pb = (BYTE _huge *)LockBitmap(hbm);
  446. if (pb == NULL || OFFSETOF(pb) != 0)
  447. ; // cant lock bitmaps
  448. else {
  449. u |= BM_CANLOCK;
  450. w = (dy-1) * bm.bmWidthBytes;
  451. pb[64l*1024] = 0;
  452. pb[w] = 0;
  453. if (u & BM_BOTTOMTOTOP)
  454. SetPixel(hdc, 0, 0, RGB(255,255,255));
  455. else
  456. SetPixel(hdc, 0, dy-1, RGB(255,255,255));
  457. if (pb[64l*1024] != 0 && pb[w] == 0)
  458. u |= BM_HUGE;
  459. else if (pb[64l*1024] == 0 && pb[w] != 0)
  460. ;
  461. else
  462. u = 0;
  463. }
  464. }
  465. #endif
  466. SelectObject(hdc, hbmT);
  467. DeleteObject(hbm);
  468. DeleteDC(hdc);
  469. wBitmapType = u;
  470. return u;
  471. }
  472. //////////////////////////////////////////////////////////////////////////////
  473. //
  474. // returns the PDevice of the given physical or memory DC
  475. //
  476. // return the bitmap type that the display driver uses
  477. //
  478. ///////////////////////////////////////////////////////////////////////////////
  479. LPVOID FAR GetPDevice(HDC hdc)
  480. {
  481. HANDLE h;
  482. HBITMAP hbm;
  483. HBITMAP hbmT;
  484. HDC hdcT=NULL;
  485. IBITMAP FAR *pbm;
  486. LPVOID lpPDevice = NULL;
  487. // GDI.403
  488. static HANDLE (FAR PASCAL *GdiGetBitmapHandle)(HBITMAP hbm, HANDLE h);
  489. if (GdiGetBitmapHandle == NULL)
  490. (FARPROC)GdiGetBitmapHandle = GetProcAddress(GetModuleHandle("GDI"),MAKEINTATOM(403));
  491. if (GdiGetBitmapHandle == NULL)
  492. return NULL;
  493. hbm = CreateBitmap(1,1,1,1,NULL);
  494. //
  495. // first try the passed DC if it is a bitmap/DC
  496. //
  497. hbmT = SelectBitmap(hdc, hbm);
  498. if (hbmT != NULL)
  499. {
  500. //
  501. // it is a memory DC.
  502. //
  503. h = GdiGetBitmapHandle(hbmT, 0);
  504. }
  505. else
  506. {
  507. //
  508. // it is a physical DC.
  509. //
  510. hdcT = CreateCompatibleDC(hdc);
  511. hbmT = SelectBitmap(hdcT, hbm);
  512. h = GdiGetBitmapHandle(hbm, 0);
  513. }
  514. if (h == NULL)
  515. goto exit;
  516. pbm = (IBITMAP FAR *)GlobalLock(h);
  517. if (IsBadReadPtr(pbm, sizeof(IBITMAP)))
  518. goto exit;
  519. if (pbm)
  520. pbm = (IBITMAP FAR *)pbm->bmlpPDevice;
  521. else
  522. pbm = NULL;
  523. if (IsBadReadPtr(pbm, 2))
  524. goto exit;
  525. lpPDevice = (LPVOID)pbm;
  526. exit:
  527. if (hdcT)
  528. {
  529. SelectObject(hdcT, hbmT);
  530. DeleteObject(hdcT);
  531. }
  532. else
  533. {
  534. SelectObject(hdc, hbmT);
  535. }
  536. DeleteObject(hbm);
  537. return lpPDevice;
  538. }
  539.