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.

645 lines
15 KiB

  1. #include "stdafx.h"
  2. #include "imgutil.h"
  3. #include "ddraw.h"
  4. #include "cddsurf.h"
  5. // Get rid of "synonyms" warning
  6. #pragma warning(disable : 4097)
  7. // Get rid of "unused formal parameters warning"
  8. #pragma warning(disable : 4100)
  9. #undef DEFINE_GUID
  10. #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
  11. EXTERN_C const GUID name \
  12. = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
  13. DEFINE_GUID( IID_IDirectDrawSurface, 0x6C14DB81,0xA733,0x11CE,0xA5,0x21,0x00,
  14. 0x20,0xAF,0x0B,0xE5,0x60 );
  15. DEFINE_GUID( IID_IDirectDrawPalette, 0x6C14DB84,0xA733,0x11CE,0xA5,0x21,0x00,
  16. 0x20,0xAF,0x0B,0xE5,0x60 );
  17. const RGBQUAD g_rgbBgColor = { 0xFF, 0xFF, 0xFF, 0 };
  18. const RGBQUAD g_rgbFgColor = { 0x00, 0x00, 0x00, 0 };
  19. const PALETTEENTRY g_peVga[16] =
  20. {
  21. { 0x00, 0x00, 0x00, 0x00 }, // Black
  22. { 0x80, 0x00, 0x00, 0x00 }, // Dark red
  23. { 0x00, 0x80, 0x00, 0x00 }, // Dark green
  24. { 0x80, 0x80, 0x00, 0x00 }, // Dark yellow
  25. { 0x00, 0x00, 0x80, 0x00 }, // Dark blue
  26. { 0x80, 0x00, 0x80, 0x00 }, // Dark purple
  27. { 0x00, 0x80, 0x80, 0x00 }, // Dark aqua
  28. { 0xC0, 0xC0, 0xC0, 0x00 }, // Light grey
  29. { 0x80, 0x80, 0x80, 0x00 }, // Dark grey
  30. { 0xFF, 0x00, 0x00, 0x00 }, // Light red
  31. { 0x00, 0xFF, 0x00, 0x00 }, // Light green
  32. { 0xFF, 0xFF, 0x00, 0x00 }, // Light yellow
  33. { 0x00, 0x00, 0xFF, 0x00 }, // Light blue
  34. { 0xFF, 0x00, 0xFF, 0x00 }, // Light purple
  35. { 0x00, 0xFF, 0xFF, 0x00 }, // Light aqua
  36. { 0xFF, 0xFF, 0xFF, 0x00 } // White
  37. };
  38. #define Verify(x) (x)
  39. LONG g_lSecondaryObjCount = 0;
  40. #define DecrementSecondaryObjectCount( idCaller ) DecrementSecondaryObjectCount_Actual()
  41. inline void
  42. DecrementSecondaryObjectCount_Actual()
  43. {
  44. InterlockedDecrement(&g_lSecondaryObjCount);
  45. }
  46. #define IncrementSecondaryObjectCount( idCaller ) IncrementSecondaryObjectCount_Actual()
  47. inline void
  48. IncrementSecondaryObjectCount_Actual()
  49. {
  50. Verify(InterlockedIncrement(&g_lSecondaryObjCount) > 0);
  51. }
  52. CBaseFT::CBaseFT(CRITICAL_SECTION * pcs)
  53. {
  54. _ulRefs = 1;
  55. _ulAllRefs = 1;
  56. _pcs = pcs;
  57. IncrementSecondaryObjectCount(10);
  58. }
  59. CBaseFT::~CBaseFT()
  60. {
  61. DecrementSecondaryObjectCount(10);
  62. }
  63. void CBaseFT::Passivate()
  64. {
  65. }
  66. ULONG CBaseFT::Release()
  67. {
  68. ULONG ulRefs = (ULONG)InterlockedDecrement((LONG *)&_ulRefs);
  69. if (ulRefs == 0)
  70. {
  71. Passivate();
  72. SubRelease();
  73. }
  74. return(ulRefs);
  75. }
  76. ULONG CBaseFT::SubRelease()
  77. {
  78. ULONG ulRefs = (ULONG)InterlockedDecrement((LONG *)&_ulAllRefs);
  79. if (ulRefs == 0)
  80. {
  81. delete this;
  82. }
  83. return(ulRefs);
  84. }
  85. void CopyColorsFromPaletteEntries(RGBQUAD *prgb, const PALETTEENTRY *ppe,
  86. UINT uCount)
  87. {
  88. while (uCount--)
  89. {
  90. prgb->rgbRed = ppe->peRed;
  91. prgb->rgbGreen = ppe->peGreen;
  92. prgb->rgbBlue = ppe->peBlue;
  93. prgb->rgbReserved = 0;
  94. prgb++;
  95. ppe++;
  96. }
  97. }
  98. void CopyPaletteEntriesFromColors(PALETTEENTRY *ppe, const RGBQUAD *prgb,
  99. UINT uCount)
  100. {
  101. while (uCount--)
  102. {
  103. ppe->peRed = prgb->rgbRed;
  104. ppe->peGreen = prgb->rgbGreen;
  105. ppe->peBlue = prgb->rgbBlue;
  106. ppe->peFlags = 0;
  107. prgb++;
  108. ppe++;
  109. }
  110. }
  111. #define MASK565_0 0x0000F800
  112. #define MASK565_1 0x000007E0
  113. #define MASK565_2 0x0000001F
  114. HBITMAP ImgCreateDib(LONG xWid, LONG yHei, BOOL fPal, int cBitsPerPix,
  115. int cEnt, PALETTEENTRY * ppe, BYTE ** ppbBits, int * pcbRow)
  116. {
  117. struct {
  118. BITMAPINFOHEADER bmih;
  119. union {
  120. RGBQUAD argb[256];
  121. WORD aw[256];
  122. DWORD adw[3];
  123. } u;
  124. } bmi;
  125. int i;
  126. if (cBitsPerPix != 8)
  127. fPal = FALSE;
  128. bmi.bmih.biSize = sizeof(BITMAPINFOHEADER);
  129. bmi.bmih.biWidth = xWid;
  130. bmi.bmih.biHeight = yHei;
  131. bmi.bmih.biPlanes = 1;
  132. bmi.bmih.biBitCount = (WORD)((cBitsPerPix == 15) ? 16 : cBitsPerPix);
  133. bmi.bmih.biCompression = (cBitsPerPix == 16) ? BI_BITFIELDS : BI_RGB;
  134. bmi.bmih.biSizeImage = 0;
  135. bmi.bmih.biXPelsPerMeter = 0;
  136. bmi.bmih.biYPelsPerMeter = 0;
  137. bmi.bmih.biClrUsed = 0;
  138. bmi.bmih.biClrImportant = 0;
  139. if (cBitsPerPix == 1)
  140. {
  141. bmi.bmih.biClrUsed = 2;
  142. if (cEnt > 2)
  143. cEnt = 2;
  144. if (cEnt > 0)
  145. {
  146. bmi.bmih.biClrImportant = cEnt;
  147. CopyColorsFromPaletteEntries(bmi.u.argb, ppe, cEnt);
  148. }
  149. else
  150. {
  151. bmi.u.argb[0] = g_rgbBgColor;
  152. bmi.u.argb[1] = g_rgbFgColor;
  153. }
  154. }
  155. else if (cBitsPerPix == 4)
  156. {
  157. bmi.bmih.biClrUsed = 16;
  158. if (cEnt > 16)
  159. cEnt = 16;
  160. if (cEnt > 0)
  161. {
  162. bmi.bmih.biClrImportant = cEnt;
  163. CopyColorsFromPaletteEntries(bmi.u.argb, ppe, cEnt);
  164. }
  165. else
  166. {
  167. bmi.bmih.biClrImportant = 16;
  168. CopyColorsFromPaletteEntries(bmi.u.argb, g_peVga, 16);
  169. }
  170. }
  171. else if (cBitsPerPix == 8)
  172. {
  173. if (fPal)
  174. {
  175. bmi.bmih.biClrUsed = 256;
  176. for (i = 0; i < 256; ++i)
  177. bmi.u.aw[i] = (WORD)i;
  178. }
  179. else
  180. {
  181. if (cEnt > 0 && cEnt < 256)
  182. {
  183. bmi.bmih.biClrUsed = cEnt;
  184. bmi.bmih.biClrImportant = cEnt;
  185. }
  186. else
  187. bmi.bmih.biClrUsed = 256;
  188. if (cEnt && ppe)
  189. {
  190. CopyColorsFromPaletteEntries(bmi.u.argb, ppe, cEnt);
  191. }
  192. }
  193. }
  194. else if (cBitsPerPix == 16)
  195. {
  196. bmi.u.adw[0] = MASK565_0;
  197. bmi.u.adw[1] = MASK565_1;
  198. bmi.u.adw[2] = MASK565_2;
  199. }
  200. return ImgCreateDibFromInfo((BITMAPINFO *)&bmi, fPal ? DIB_PAL_COLORS : DIB_RGB_COLORS, ppbBits, pcbRow);
  201. }
  202. HBITMAP ImgCreateDibFromInfo(BITMAPINFO * pbmi, UINT wUsage, BYTE ** ppbBits, int * pcbRow)
  203. {
  204. HDC hdcMem = NULL;
  205. HBITMAP hbm = NULL;
  206. BYTE * pbBits;
  207. int cbRow;
  208. LONG xWid, yHei;
  209. int cBitsPerPix;
  210. xWid = pbmi->bmiHeader.biWidth;
  211. yHei = pbmi->bmiHeader.biHeight;
  212. cBitsPerPix = pbmi->bmiHeader.biBitCount;
  213. cbRow = ((xWid * cBitsPerPix + 31) & ~31) / 8;
  214. if (pcbRow)
  215. {
  216. *pcbRow = cbRow;
  217. }
  218. hdcMem = CreateCompatibleDC(NULL);
  219. if (hdcMem == NULL)
  220. goto Cleanup;
  221. hbm = CreateDIBSection(hdcMem, pbmi, wUsage, (void **)&pbBits, NULL, 0);
  222. if (hbm && ppbBits)
  223. {
  224. *ppbBits = pbBits;
  225. }
  226. Cleanup:
  227. if (hdcMem)
  228. DeleteDC(hdcMem);
  229. return(hbm);
  230. }
  231. CDDrawWrapper::CDDrawWrapper(HBITMAP hbmDib)
  232. {
  233. m_hbmDib = hbmDib;
  234. GetObject(hbmDib, sizeof(DIBSECTION), &m_dsSurface);
  235. m_lPitch = ((m_dsSurface.dsBmih.biWidth * m_dsSurface.dsBmih.biBitCount + 31) & ~31) / 8;
  236. if (m_dsSurface.dsBmih.biHeight > 0)
  237. {
  238. m_pbBits = (BYTE *)m_dsSurface.dsBm.bmBits + (m_dsSurface.dsBm.bmHeight - 1) * m_lPitch;
  239. m_lPitch = -m_lPitch;
  240. }
  241. else
  242. {
  243. m_pbBits = (BYTE *)m_dsSurface.dsBm.bmBits;
  244. }
  245. // left, top already 0
  246. m_rcSurface.right = m_dsSurface.dsBm.bmWidth;
  247. m_rcSurface.bottom = m_dsSurface.dsBm.bmHeight;
  248. // initialize transparent index to -1
  249. m_ddColorKey.dwColorSpaceLowValue = m_ddColorKey.dwColorSpaceHighValue = (DWORD)-1;
  250. }
  251. CDDrawWrapper::~CDDrawWrapper()
  252. {
  253. }
  254. STDMETHODIMP
  255. CDDrawWrapper::QueryInterface(REFIID riid, void ** ppv)
  256. {
  257. if (riid == IID_IDirectDrawSurface)
  258. *ppv = (IUnknown *)(IDirectDrawSurface *)this;
  259. else if (riid == IID_IDirectDrawPalette)
  260. *ppv = (IUnknown *)(IDirectDrawPalette *)this;
  261. else if (riid == IID_IUnknown)
  262. *ppv = (IUnknown *)(IDirectDrawSurface *)this;
  263. else
  264. *ppv = NULL;
  265. if (*ppv)
  266. {
  267. ((LPUNKNOWN)*ppv)->AddRef();
  268. return(S_OK);
  269. }
  270. else
  271. {
  272. return(E_NOINTERFACE);
  273. }
  274. }
  275. STDMETHODIMP_(ULONG)
  276. CDDrawWrapper::AddRef()
  277. {
  278. return(super::AddRef());
  279. }
  280. STDMETHODIMP_(ULONG)
  281. CDDrawWrapper::Release()
  282. {
  283. return(super::Release());
  284. }
  285. STDMETHODIMP CDDrawWrapper::GetColorKey(DWORD dw, LPDDCOLORKEY lpKey)
  286. {
  287. if (dw != DDCKEY_SRCBLT)
  288. return E_INVALIDARG;
  289. if (lpKey == NULL)
  290. return E_POINTER;
  291. memcpy(lpKey, &m_ddColorKey, sizeof(DDCOLORKEY));
  292. return S_OK;
  293. }
  294. STDMETHODIMP CDDrawWrapper::GetPalette(LPDIRECTDRAWPALETTE FAR* ppPal)
  295. {
  296. if (ppPal == NULL)
  297. return E_POINTER;
  298. // Return interface to set color table if DIB section has one
  299. if (m_dsSurface.dsBmih.biBitCount <= 8)
  300. {
  301. *ppPal = (LPDIRECTDRAWPALETTE)this;
  302. ((LPUNKNOWN)*ppPal)->AddRef();
  303. return S_OK;
  304. }
  305. else
  306. {
  307. *ppPal = NULL;
  308. return E_NOINTERFACE;
  309. }
  310. }
  311. STDMETHODIMP CDDrawWrapper::SetColorKey(DWORD dwFlags, LPDDCOLORKEY pDDColorKey)
  312. {
  313. if (dwFlags != DDCKEY_SRCBLT)
  314. return E_INVALIDARG;
  315. if (pDDColorKey == NULL)
  316. return E_POINTER;
  317. memcpy(&m_ddColorKey, pDDColorKey, sizeof(DDCOLORKEY));
  318. return S_OK;
  319. }
  320. STDMETHODIMP CDDrawWrapper::SetEntries(DWORD dwFlags, DWORD dwStart, DWORD dwCount, LPPALETTEENTRY pEntries)
  321. {
  322. RGBQUAD argb[256];
  323. DWORD nColors = (DWORD)(1 << m_dsSurface.dsBmih.biBitCount);
  324. UINT nColorsSet;
  325. HDC hdc;
  326. HBITMAP hbm;
  327. if (dwFlags)
  328. return E_INVALIDARG;
  329. if (dwStart >= nColors || dwStart + dwCount > nColors)
  330. return E_INVALIDARG;
  331. if (pEntries == NULL)
  332. return E_POINTER;
  333. CopyColorsFromPaletteEntries(argb, pEntries, dwCount);
  334. hdc = CreateCompatibleDC(NULL);
  335. if (hdc)
  336. {
  337. hbm = (HBITMAP)SelectObject(hdc, m_hbmDib);
  338. nColorsSet = SetDIBColorTable(hdc, (UINT)dwStart, (UINT)dwCount, argb);
  339. SelectObject(hdc, hbm);
  340. DeleteDC(hdc);
  341. }
  342. else
  343. nColorsSet = 0;
  344. return nColorsSet ? S_OK : E_FAIL;
  345. }
  346. STDMETHODIMP CDDrawWrapper::GetEntries(DWORD dwFlags, DWORD dwStart, DWORD dwCount, LPPALETTEENTRY pEntries)
  347. {
  348. RGBQUAD argb[256];
  349. DWORD nColors = (DWORD)(1 << m_dsSurface.dsBmih.biBitCount);
  350. UINT nColorsGet;
  351. HDC hdc;
  352. HBITMAP hbm;
  353. if (dwFlags)
  354. return E_INVALIDARG;
  355. if (dwStart >= nColors || dwStart + dwCount > nColors)
  356. return E_INVALIDARG;
  357. if (pEntries == NULL)
  358. return E_POINTER;
  359. hdc = CreateCompatibleDC(NULL);
  360. if (hdc)
  361. {
  362. hbm = (HBITMAP)SelectObject(hdc, m_hbmDib);
  363. nColorsGet = GetDIBColorTable(hdc, (UINT)dwStart, (UINT)dwCount, argb);
  364. SelectObject(hdc, hbm);
  365. DeleteDC(hdc);
  366. }
  367. else
  368. return E_FAIL;
  369. if (nColorsGet)
  370. CopyPaletteEntriesFromColors(pEntries, argb, dwCount);
  371. return nColorsGet ? S_OK : E_FAIL;
  372. }
  373. STDMETHODIMP CDDrawWrapper::Lock(LPRECT pRect, LPDDSURFACEDESC pSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
  374. {
  375. RECT rcClip;
  376. if (pRect == NULL || pSurfaceDesc == NULL)
  377. return E_POINTER;
  378. if (pSurfaceDesc->dwSize != sizeof(DDSURFACEDESC))
  379. return E_INVALIDARG;
  380. if (hEvent)
  381. return E_INVALIDARG;
  382. IntersectRect(&rcClip, pRect, &m_rcSurface);
  383. if (!EqualRect(&rcClip, pRect))
  384. return E_INVALIDARG;
  385. pSurfaceDesc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH;
  386. pSurfaceDesc->dwWidth = m_dsSurface.dsBm.bmWidth;
  387. pSurfaceDesc->dwHeight = m_dsSurface.dsBm.bmHeight;
  388. pSurfaceDesc->lPitch = m_lPitch;
  389. pSurfaceDesc->lpSurface = (LPVOID)(m_pbBits
  390. + pRect->top * m_lPitch
  391. + ((pRect->left * m_dsSurface.dsBmih.biBitCount) / 8));
  392. return S_OK;
  393. }
  394. STDMETHODIMP CDDrawWrapper::Unlock(LPVOID pBits)
  395. {
  396. return S_OK;
  397. }
  398. // The remainder of these methods are not needed by the plugin filters
  399. STDMETHODIMP CDDrawWrapper::AddAttachedSurface(LPDIRECTDRAWSURFACE lpdds)
  400. {
  401. return E_NOTIMPL;
  402. }
  403. STDMETHODIMP CDDrawWrapper::AddOverlayDirtyRect(LPRECT lprc)
  404. {
  405. return E_NOTIMPL;
  406. }
  407. STDMETHODIMP CDDrawWrapper::Blt(LPRECT lprcDest, LPDIRECTDRAWSURFACE lpdds, LPRECT lprcSrc, DWORD dw, LPDDBLTFX lpfx)
  408. {
  409. return E_NOTIMPL;
  410. }
  411. STDMETHODIMP CDDrawWrapper::BltBatch(LPDDBLTBATCH lpBlt, DWORD dwCount, DWORD dwFlags)
  412. {
  413. return E_NOTIMPL;
  414. }
  415. STDMETHODIMP CDDrawWrapper::BltFast(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpdds, LPRECT lprcSrc, DWORD dwTrans)
  416. {
  417. return E_NOTIMPL;
  418. }
  419. STDMETHODIMP CDDrawWrapper::DeleteAttachedSurface(DWORD dwFlags, LPDIRECTDRAWSURFACE lpdds)
  420. {
  421. return E_NOTIMPL;
  422. }
  423. STDMETHODIMP CDDrawWrapper::EnumAttachedSurfaces(LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfn)
  424. {
  425. return E_NOTIMPL;
  426. }
  427. STDMETHODIMP CDDrawWrapper::EnumOverlayZOrders(DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfn)
  428. {
  429. return E_NOTIMPL;
  430. }
  431. STDMETHODIMP CDDrawWrapper::Flip(LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags)
  432. {
  433. return E_NOTIMPL;
  434. }
  435. STDMETHODIMP CDDrawWrapper::GetAttachedSurface(LPDDSCAPS lpCaps, LPDIRECTDRAWSURFACE FAR * lpdds)
  436. {
  437. return E_NOTIMPL;
  438. }
  439. STDMETHODIMP CDDrawWrapper::GetBltStatus(DWORD dw)
  440. {
  441. return E_NOTIMPL;
  442. }
  443. STDMETHODIMP CDDrawWrapper::GetCaps(LPDDSCAPS lpCaps)
  444. {
  445. return E_NOTIMPL;
  446. }
  447. STDMETHODIMP CDDrawWrapper::GetClipper(LPDIRECTDRAWCLIPPER FAR* lpClipper)
  448. {
  449. return E_NOTIMPL;
  450. }
  451. STDMETHODIMP CDDrawWrapper::GetDC(HDC FAR * lphdc)
  452. {
  453. return E_NOTIMPL;
  454. }
  455. STDMETHODIMP CDDrawWrapper::GetFlipStatus(DWORD dw)
  456. {
  457. return E_NOTIMPL;
  458. }
  459. STDMETHODIMP CDDrawWrapper::GetOverlayPosition(LPLONG lpl1, LPLONG lpl2)
  460. {
  461. return E_NOTIMPL;
  462. }
  463. STDMETHODIMP CDDrawWrapper::GetPixelFormat(LPDDPIXELFORMAT pPixelFormat)
  464. {
  465. return E_NOTIMPL;
  466. }
  467. STDMETHODIMP CDDrawWrapper::GetSurfaceDesc(LPDDSURFACEDESC pSurfaceDesc)
  468. {
  469. return E_NOTIMPL;
  470. }
  471. STDMETHODIMP CDDrawWrapper::Initialize(LPDIRECTDRAW pDD, LPDDSURFACEDESC pSurfaceDesc)
  472. {
  473. return E_NOTIMPL;
  474. }
  475. STDMETHODIMP CDDrawWrapper::IsLost()
  476. {
  477. return E_NOTIMPL;
  478. }
  479. STDMETHODIMP CDDrawWrapper::ReleaseDC(HDC hdc)
  480. {
  481. return E_NOTIMPL;
  482. }
  483. STDMETHODIMP CDDrawWrapper::Restore()
  484. {
  485. return E_NOTIMPL;
  486. }
  487. STDMETHODIMP CDDrawWrapper::SetClipper(LPDIRECTDRAWCLIPPER pClipper)
  488. {
  489. return E_NOTIMPL;
  490. }
  491. STDMETHODIMP CDDrawWrapper::SetOverlayPosition(LONG x, LONG y)
  492. {
  493. return E_NOTIMPL;
  494. }
  495. STDMETHODIMP CDDrawWrapper::SetPalette(LPDIRECTDRAWPALETTE pDDPal)
  496. {
  497. return E_NOTIMPL;
  498. }
  499. STDMETHODIMP CDDrawWrapper::UpdateOverlay(LPRECT prc, LPDIRECTDRAWSURFACE pdds, LPRECT prc2, DWORD dw, LPDDOVERLAYFX pfx)
  500. {
  501. return E_NOTIMPL;
  502. }
  503. STDMETHODIMP CDDrawWrapper::UpdateOverlayDisplay(DWORD dw)
  504. {
  505. return E_NOTIMPL;
  506. }
  507. STDMETHODIMP CDDrawWrapper::UpdateOverlayZOrder(DWORD dw, LPDIRECTDRAWSURFACE pdds)
  508. {
  509. return E_NOTIMPL;
  510. }
  511. STDMETHODIMP CDDrawWrapper::GetCaps(LPDWORD lpdw)
  512. {
  513. return E_NOTIMPL;
  514. }
  515. STDMETHODIMP CDDrawWrapper::Initialize(LPDIRECTDRAW lpdd, DWORD dwCount, LPPALETTEENTRY pEntries)
  516. {
  517. return E_NOTIMPL;
  518. }