Source code of Windows XP (NT5)
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.

1018 lines
29 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1997 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: ddrawex.cpp
  6. * Content: new DirectDraw object support
  7. * History:
  8. * Date By Reason
  9. * ==== == ======
  10. * 24-feb-97 ralphl initial implementation
  11. * 25-feb-97 craige minor tweaks for dx checkin; integrated IBitmapSurface
  12. * stuff
  13. * 03-mar-97 craige added palettes to CreateCompatibleBitmapSurface
  14. * 06-mar-97 craige IDirectDrawSurface3 support
  15. * 01-apr-97 jeffort Following changes checked in:
  16. * Attachlist structure added (from ddrawi.h)
  17. * Surface linked list handled
  18. * D3D interfaces added to QueryInterface
  19. * Complex surfaces are handled at CreateSurface calls
  20. * CreatCompatibleBitmap changed to handle > 8bpp bitmaps
  21. * Changed the call to GetPaletteEntries to use a handle to a palette
  22. *
  23. * 04-apr-97 jeffort Trident ifdef's removed
  24. * IDirectDraw3 class implemntation
  25. * paramter changed in recursive handling of attach lists
  26. * 10-apr-97 jeffort Release of pSurface2 in creating a simple surface was incorrect
  27. * this was already being done in surface.cpp
  28. *
  29. * 21-apr-97 jeffort Version Check for DX5 for QI of IDirectDrawSurface3
  30. * 28-apr-97 jeffort Palette wrapping added/DX5 support
  31. * 28-apr-97 jeffort Palette wrapping if CreatePalette fails in our internal
  32. * function, cleanup code added
  33. * 30-apr-97 jeffort No longer addref when querying for IDirect3D (done in ddraw QI)
  34. * AddRef attached surfaces (release done in releasing the surface)
  35. * 02-may-97 jeffort local variable changed from DWORD to WORD
  36. *
  37. * 08-may-97 jeffort Better parameter checking
  38. * 09-may-97 jeffort If GetTransparentIndex has nothing set return OK/COLOR_NO_TRANSPARENT
  39. * 16-may-97 jeffort A surface failing to be created is already released. The release here
  40. * was removed.
  41. * 20-may-97 jeffort GetFormatFromDC checks if this is a surface DC and gets the
  42. * format from the surface instead of GetDeviceCaps
  43. * 27-may-97 jeffort keep ref count on internal object eual to outer object
  44. * 12-jun-97 jeffort reversed R and B fields in 32bpp PIXELFORMAT array
  45. * 20-jun-97 jeffort added debug code to invaliudate objects when freed
  46. * 27-jun-97 jeffort IDirectDrawSurface3 interface support for DX3 was not
  47. * added. We now use an IDirectDrawSurface2 to spoof it
  48. * so we can support SetSurfaceDesc
  49. * 22-jul-97 jeffort Removed IBitmapSurface and associated interfaces
  50. ***************************************************************************/
  51. #define INITGUID
  52. #define CPP_FUNCTIONS
  53. #include "ddfactry.h"
  54. #define m_pDirectDraw (m_DDInt.m_pRealInterface)
  55. #define m_pDirectDraw2 (m_DD2Int.m_pRealInterface)
  56. #define m_pDirectDraw4 (m_DD4Int.m_pRealInterface)
  57. typedef struct _ATTACHLIST
  58. {
  59. DWORD dwFlags;
  60. struct _ATTACHLIST FAR *lpLink; // link to next attached surface
  61. struct _DDRAWI_DDRAWSURFACE_LCL FAR *lpAttached; // attached surface local obj
  62. struct _DDRAWI_DDRAWSURFACE_INT FAR *lpIAttached; // attached surface interface
  63. } ATTACHLIST;
  64. typedef ATTACHLIST FAR *LPATTACHLIST;
  65. /*
  66. * CDirectDrawEx::CDirectDrawEx
  67. *
  68. * Constructor for the new DirectDrawEx class
  69. */
  70. CDirectDrawEx::CDirectDrawEx(IUnknown *pUnkOuter) :
  71. m_cRef(1),
  72. m_pUnkOuter(pUnkOuter != 0 ? pUnkOuter : CAST_TO_IUNKNOWN(this)),
  73. m_pFirstSurface(NULL),
  74. m_pFirstPalette(NULL),
  75. m_pPrimaryPaletteList(NULL)
  76. {
  77. DllAddRef();
  78. m_pDirectDraw = NULL;
  79. m_pDirectDraw2 = NULL;
  80. m_pDirectDraw4 = NULL;
  81. m_DDInt.m_pDirectDrawEx = this;
  82. m_DD2Int.m_pDirectDrawEx = this;
  83. m_DD4Int.m_pDirectDrawEx = this;
  84. } /* CDirectDrawEx::CDirectDrawEx */
  85. /*
  86. * CDirectDrawEx::Init
  87. */
  88. HRESULT CDirectDrawEx::Init(
  89. GUID * pGUID,
  90. HWND hWnd,
  91. DWORD dwCoopLevelFlags,
  92. DWORD dwReserved,
  93. LPDIRECTDRAWCREATE pDirectDrawCreate )
  94. {
  95. HRESULT hr;
  96. if( dwReserved )
  97. {
  98. hr = DDERR_INVALIDPARAMS;
  99. }
  100. else
  101. {
  102. //DDraw will pop a dialog complaining about 4bpp modes, so we need to
  103. //tell it not to. DDraw will sniff SEM and not pop the dialog if
  104. //SEM_FAILCRITICALERRORS is set.
  105. DWORD dw = SetErrorMode(SEM_FAILCRITICALERRORS);
  106. SetErrorMode(dw | SEM_FAILCRITICALERRORS); // retain old flags too
  107. hr = pDirectDrawCreate( pGUID, &m_pDirectDraw, NULL );
  108. SetErrorMode(dw);
  109. if( SUCCEEDED(hr) )
  110. {
  111. hr = m_pDirectDraw->SetCooperativeLevel(hWnd, dwCoopLevelFlags);
  112. if( SUCCEEDED(hr) )
  113. {
  114. if (dwCoopLevelFlags & DDSCL_EXCLUSIVE)
  115. m_bExclusive = TRUE;
  116. else
  117. m_bExclusive = FALSE;
  118. hr = m_pDirectDraw->QueryInterface(IID_IDirectDraw2, (void **)&m_pDirectDraw2);
  119. if( SUCCEEDED(hr) )
  120. {
  121. m_pDirectDraw->QueryInterface(IID_IDirectDraw4, (void **)&m_pDirectDraw4);
  122. InitDirectDrawInterfaces(m_pDirectDraw, &m_DDInt, m_pDirectDraw2, &m_DD2Int, m_pDirectDraw4, &m_DD4Int);
  123. }
  124. }
  125. }
  126. }
  127. return hr;
  128. } /* CDirectDrawEx::Init */
  129. /*
  130. * CDirectDrawEx::~CDirectDrawEx
  131. *
  132. * destructor
  133. */
  134. CDirectDrawEx::~CDirectDrawEx()
  135. {
  136. if( m_pDirectDraw )
  137. {
  138. m_pDirectDraw->Release();
  139. }
  140. if( m_pDirectDraw2 )
  141. {
  142. m_pDirectDraw2->Release();
  143. }
  144. if (m_pDirectDraw4)
  145. {
  146. m_pDirectDraw4->Release();
  147. }
  148. #ifdef DEBUG
  149. DWORD * ptr;
  150. ptr = (DWORD *)this;
  151. for (int i = 0; i < sizeof(CDirectDrawEx) / sizeof(DWORD);i++)
  152. *ptr++ = 0xDEADBEEF;
  153. #endif
  154. DllRelease();
  155. } /* CDirectDrawEx::~CDirectDrawEx */
  156. /*
  157. * CDirectDrawEx::NonDelegatingQueryInterface
  158. * NonDelegatingAddRef
  159. * NonDelegatingRelease
  160. *
  161. * The base IUnknown interface (non-delegating)
  162. */
  163. STDMETHODIMP CDirectDrawEx::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
  164. {
  165. HRESULT hr;
  166. *ppv=NULL;
  167. if( IID_IUnknown == riid )
  168. {
  169. *ppv=(INonDelegatingUnknown *)this;
  170. }
  171. else if (IID_IDirectDraw3 == riid)
  172. {
  173. *ppv=(IDirectDraw3 *)this;
  174. }
  175. else if( IID_IDirectDraw==riid )
  176. {
  177. *ppv=&m_DDInt;
  178. }
  179. else if( IID_IDirectDraw2==riid )
  180. {
  181. *ppv=&m_DD2Int;
  182. }
  183. else if (IID_IDirectDraw4==riid && m_pDirectDraw4)
  184. {
  185. *ppv=&m_DD4Int;
  186. }
  187. else if (IID_IDirect3D == riid)
  188. {
  189. IUnknown* pUnk;
  190. HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
  191. *(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDirectDraw;
  192. hr = lpFunc(&(m_DDInt.lpVtbl), riid, (void **)&pUnk);
  193. if( SUCCEEDED(hr) )
  194. {
  195. *ppv=pUnk;
  196. }
  197. else
  198. {
  199. *ppv = NULL;
  200. }
  201. return hr;
  202. }
  203. else if (IID_IDirect3D2 == riid)
  204. {
  205. IUnknown* pUnk;
  206. HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
  207. *(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDirectDraw;
  208. hr = lpFunc(&(m_DDInt.lpVtbl), riid, (void **)&pUnk);
  209. if( SUCCEEDED(hr) )
  210. {
  211. *ppv=pUnk;
  212. }
  213. else
  214. {
  215. *ppv = NULL;
  216. }
  217. return hr;
  218. }
  219. else if (IID_IDirect3D3 == riid)
  220. {
  221. IUnknown* pUnk;
  222. HRESULT (__stdcall *lpFunc)(IDirectDrawVtbl **,REFIID, void **);
  223. *(DWORD *)(&lpFunc) = *(DWORD *)*(DWORD **)m_pDirectDraw;
  224. hr = lpFunc(&(m_DDInt.lpVtbl), riid, (void **)&pUnk);
  225. if( SUCCEEDED(hr) )
  226. {
  227. *ppv=pUnk;
  228. }
  229. else
  230. {
  231. *ppv = NULL;
  232. }
  233. return hr;
  234. }
  235. else
  236. {
  237. return E_NOINTERFACE;
  238. }
  239. ((LPUNKNOWN)*ppv)->AddRef();
  240. return NOERROR;
  241. } /* CDirectDrawEx::NonDelegatingQueryInterface */
  242. STDMETHODIMP_(ULONG) CDirectDrawEx::NonDelegatingAddRef()
  243. {
  244. m_pDirectDraw->AddRef();
  245. return InterlockedIncrement(&m_cRef);
  246. } /* CDirectDrawEx::NonDelegatingAddRef */
  247. STDMETHODIMP_(ULONG) CDirectDrawEx::NonDelegatingRelease()
  248. {
  249. LONG lRefCount = InterlockedDecrement(&m_cRef);
  250. if (lRefCount)
  251. {
  252. m_pDirectDraw->Release();
  253. return lRefCount;
  254. }
  255. delete this;
  256. return 0;
  257. } /* CDirectDrawEx::NonDelegatingRelease */
  258. /*
  259. * CDirectDrawEx::QueryInterface
  260. * AddRef
  261. * Release
  262. *
  263. * The standard IUnknown that delegates...
  264. */
  265. STDMETHODIMP CDirectDrawEx::QueryInterface(REFIID riid, void ** ppv)
  266. {
  267. return m_pUnkOuter->QueryInterface(riid, ppv);
  268. } /* CDirectDrawEx::QueryInterface */
  269. STDMETHODIMP_(ULONG) CDirectDrawEx::AddRef(void)
  270. {
  271. return m_pUnkOuter->AddRef();
  272. } /* CDirectDrawEx::AddRef */
  273. STDMETHODIMP_(ULONG) CDirectDrawEx::Release(void)
  274. {
  275. return m_pUnkOuter->Release();
  276. } /* CDirectDrawEx::Release */
  277. /*
  278. * CDirectDrawEx::GetSurfaceFromDC
  279. *
  280. * Run the list of surfaces and find which one has this DC.
  281. * Works with OWNDC surfaces only for now.
  282. */
  283. STDMETHODIMP CDirectDrawEx::GetSurfaceFromDC(HDC hdc, IDirectDrawSurface **ppSurface)
  284. {
  285. HRESULT hr = DDERR_NOTFOUND;
  286. if( !ppSurface )
  287. {
  288. hr = E_POINTER;
  289. }
  290. else
  291. {
  292. *ppSurface = NULL;
  293. ENTER_DDEX();
  294. CDDSurface *pSurface = m_pFirstSurface;
  295. while( pSurface )
  296. {
  297. if( (pSurface->m_HDC == hdc) || (pSurface->m_hDCDib == hdc) )
  298. {
  299. hr = pSurface->m_pUnkOuter->QueryInterface(IID_IDirectDrawSurface, (void **)ppSurface);
  300. break;
  301. }
  302. pSurface = pSurface->m_pNext;
  303. }
  304. LEAVE_DDEX();
  305. }
  306. return hr;
  307. } /* CDirectDrawEx::GetSurfaceFromDC */
  308. /*
  309. * CDirectDrawEx::AddSurfaceToList
  310. *
  311. * Adds a surface to our doubly-linked surface list
  312. */
  313. void CDirectDrawEx::AddSurfaceToList(CDDSurface *pSurface)
  314. {
  315. ENTER_DDEX();
  316. if( m_pFirstSurface )
  317. {
  318. m_pFirstSurface->m_pPrev = pSurface;
  319. }
  320. pSurface->m_pPrev = NULL;
  321. pSurface->m_pNext = m_pFirstSurface;
  322. m_pFirstSurface = pSurface;
  323. LEAVE_DDEX();
  324. } /* CDirectDrawEx::AddSurfaceToList */
  325. /*
  326. * CDirectDrawEx::RemoveSurfaceToList
  327. *
  328. * Removes a surface to our doubly-linked surface list
  329. */
  330. void CDirectDrawEx::RemoveSurfaceFromList(CDDSurface *pSurface)
  331. {
  332. ENTER_DDEX();
  333. if( pSurface->m_pPrev )
  334. {
  335. pSurface->m_pPrev->m_pNext = pSurface->m_pNext;
  336. }
  337. else
  338. {
  339. m_pFirstSurface = pSurface->m_pNext;
  340. }
  341. if( pSurface->m_pNext )
  342. {
  343. pSurface->m_pNext->m_pPrev = pSurface->m_pPrev;
  344. }
  345. LEAVE_DDEX();
  346. } /* CDirectDrawEx::RemoveSurfaceToList */
  347. /*
  348. * CDirectDrawEx::AddSurfaceToPrimarList
  349. *
  350. * Adds a surface to our doubly-linked surface list which use the primary palette
  351. */
  352. void CDirectDrawEx::AddSurfaceToPrimaryList(CDDSurface *pSurface)
  353. {
  354. ENTER_DDEX();
  355. if( m_pPrimaryPaletteList )
  356. {
  357. m_pPrimaryPaletteList->m_pPrevPalette = pSurface;
  358. }
  359. pSurface->m_pPrevPalette = NULL;
  360. pSurface->m_pNextPalette = m_pPrimaryPaletteList;
  361. m_pPrimaryPaletteList = pSurface;
  362. pSurface->m_bPrimaryPalette = TRUE;
  363. LEAVE_DDEX();
  364. } /* CDirectDrawEx::AddSurfaceToList */
  365. /*
  366. * CDirectDrawEx::RemoveSurfaceFromPrimaryList
  367. *
  368. * Removes a surface to our doubly-linked surface list which use the primary palette
  369. */
  370. void CDirectDrawEx::RemoveSurfaceFromPrimaryList(CDDSurface *pSurface)
  371. {
  372. ENTER_DDEX();
  373. if( pSurface->m_pPrevPalette )
  374. {
  375. pSurface->m_pPrevPalette->m_pNextPalette = pSurface->m_pNextPalette;
  376. }
  377. else
  378. {
  379. m_pPrimaryPaletteList = pSurface->m_pNextPalette;
  380. }
  381. if( pSurface->m_pNextPalette )
  382. {
  383. pSurface->m_pNextPalette->m_pPrevPalette = pSurface->m_pPrevPalette;
  384. }
  385. pSurface->m_bPrimaryPalette = FALSE;
  386. LEAVE_DDEX();
  387. } /* CDirectDrawEx::RemoveSurfaceToList */
  388. /*
  389. * CDirectDrawEx::AddPaletteToList
  390. *
  391. * Adds a palette to our doubly-linked palette list
  392. */
  393. void CDirectDrawEx::AddPaletteToList(CDDPalette *pPalette)
  394. {
  395. ENTER_DDEX();
  396. if( m_pFirstPalette )
  397. {
  398. m_pFirstPalette->m_pPrev = pPalette;
  399. }
  400. pPalette->m_pPrev = NULL;
  401. pPalette->m_pNext = m_pFirstPalette;
  402. m_pFirstPalette = pPalette;
  403. LEAVE_DDEX();
  404. }
  405. /*
  406. * CDirectDrawEx::RemovePaletteToList
  407. *
  408. * Removes a palette to our doubly-linked palette list
  409. */
  410. void CDirectDrawEx::RemovePaletteFromList(CDDPalette *pPalette)
  411. {
  412. ENTER_DDEX();
  413. if( pPalette->m_pPrev )
  414. {
  415. pPalette->m_pPrev->m_pNext = pPalette->m_pNext;
  416. }
  417. else
  418. {
  419. m_pFirstPalette = pPalette->m_pNext;
  420. }
  421. if( pPalette->m_pNext )
  422. {
  423. pPalette->m_pNext->m_pPrev = pPalette->m_pPrev;
  424. }
  425. LEAVE_DDEX();
  426. }
  427. HRESULT CDirectDrawEx::CreateSimpleSurface(LPDDSURFACEDESC pSurfaceDesc, IUnknown *pUnkOuter, IDirectDrawSurface * pSurface, IDirectDrawSurface **ppNewSurface, DWORD dwFlags)
  428. {
  429. IDirectDrawSurface2 *pSurface2 = NULL;
  430. IDirectDrawSurface3 *pSurface3 = NULL;
  431. HRESULT hr;
  432. hr = pSurface->QueryInterface(IID_IDirectDrawSurface2, (void **)&pSurface2);
  433. if (FAILED(hr))
  434. return hr;
  435. //we only want to do this Query if we are on DX5 or above. On DX3, this is not supported,
  436. //and this call will cause D3D to be loaded
  437. pSurface3 = NULL;
  438. if (m_dwDDVer == WIN95_DX5 || m_dwDDVer == WINNT_DX5)
  439. {
  440. hr = pSurface->QueryInterface(IID_IDirectDrawSurface3, (void **)&pSurface3);
  441. if( FAILED( hr ) )
  442. {
  443. pSurface3 = NULL;
  444. }
  445. }
  446. if (pSurface3 == NULL)
  447. hr = pSurface->QueryInterface(IID_IDirectDrawSurface2, (void **)&pSurface3);
  448. if (FAILED(hr))
  449. return hr;
  450. IDirectDrawSurface4 *pSurface4 = NULL;
  451. //
  452. // It's fine if this does not work... Just ignore return code.
  453. //
  454. pSurface->QueryInterface(IID_IDirectDrawSurface4, (void **)&pSurface4);
  455. hr = CDDSurface::CreateSimpleSurface(
  456. pSurfaceDesc,
  457. pSurface,
  458. pSurface2,
  459. pSurface3,
  460. pSurface4,
  461. pUnkOuter,
  462. this,
  463. ppNewSurface,
  464. dwFlags);
  465. return hr;
  466. }
  467. HRESULT CDirectDrawEx::HandleAttachList(LPDDSURFACEDESC pSurfaceDesc, IUnknown *pUnkOuter,IDirectDrawSurface **ppNewSurface, IDirectDrawSurface * pOrigSurf, DWORD dwFlags)
  468. {
  469. IDirectDrawSurface *pSurface;
  470. IDirectDrawSurface *pSurfaceReturn;
  471. DDSURFACEDESC SurfaceDesc;
  472. HRESULT hr;
  473. //create the necessary SurfaceData here
  474. pSurface = *ppNewSurface;
  475. SurfaceDesc.dwSize = sizeof(DDSURFACEDESC);
  476. //add ref the attached surface here
  477. pSurface->AddRef();
  478. hr = pSurface->GetSurfaceDesc(&SurfaceDesc);
  479. if (!SUCCEEDED(hr))
  480. return hr;
  481. hr = CreateSimpleSurface(&SurfaceDesc, pUnkOuter, pSurface, (IDirectDrawSurface **)&pSurfaceReturn, dwFlags);
  482. if (!SUCCEEDED(hr))
  483. return hr;
  484. //we got here via an attachlist, so we need to recurse into the structure more
  485. LPATTACHLIST lpAttach;
  486. lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList);
  487. while (lpAttach != NULL){
  488. pSurface = (IDirectDrawSurface *)((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList))->lpIAttached;
  489. lpAttach = lpAttach->lpLink;
  490. if (pSurface != pOrigSurf){
  491. hr = HandleAttachList(pSurfaceDesc, pUnkOuter, &pSurface, pOrigSurf, dwFlags);
  492. if (!SUCCEEDED(hr))
  493. return hr;
  494. }
  495. }
  496. return hr;
  497. }
  498. /*
  499. * CDirectDrawEx::CreateSurface
  500. *
  501. * Create a DirectDraw surface that supports OWNDC
  502. */
  503. STDMETHODIMP CDirectDrawEx::CreateSurface(LPDDSURFACEDESC pSurfaceDesc, IDirectDrawSurface **ppNewSurface, IUnknown *pUnkOuter)
  504. {
  505. DWORD origcaps;
  506. DWORD newcaps;
  507. DWORD dwFlags;
  508. IDirectDrawSurface *pSurface;
  509. if (pSurfaceDesc == NULL)
  510. return DDERR_INVALIDPARAMS;
  511. if (ppNewSurface == NULL)
  512. return DDERR_INVALIDPARAMS;
  513. origcaps = pSurfaceDesc->ddsCaps.dwCaps;
  514. newcaps = origcaps;
  515. /*
  516. * If OWNDC is specified, it must be a system memory surface
  517. */
  518. if ((origcaps & (DDSCAPS_OWNDC | DDSCAPS_SYSTEMMEMORY)) == DDSCAPS_OWNDC)
  519. {
  520. return DDERR_INVALIDCAPS;
  521. }
  522. /*
  523. * DATAEXCHANGE has some magic...
  524. */
  525. if( (origcaps & DDSCAPS_DATAEXCHANGE) == DDSCAPS_DATAEXCHANGE )
  526. {
  527. dwFlags = SURFACE_DATAEXCHANGE;
  528. //Do not allow the primary surface with these caps!!!!
  529. if (origcaps & DDSCAPS_PRIMARYSURFACE)
  530. return DDERR_INVALIDCAPS;
  531. newcaps &= ~DDSCAPS_DATAEXCHANGE;
  532. newcaps |= DDSCAPS_SYSTEMMEMORY | DDSCAPS_OWNDC | DDSCAPS_TEXTURE;
  533. if (newcaps & DDSCAPS_OFFSCREENPLAIN)
  534. newcaps &= ~DDSCAPS_OFFSCREENPLAIN;
  535. }
  536. else
  537. dwFlags = 0;
  538. /*
  539. * turn off OWNDC when going to DirectDraw 3
  540. */
  541. if (m_dwDDVer != WIN95_DX5 && m_dwDDVer != WINNT_DX5)
  542. newcaps &= ~DDSCAPS_OWNDC;
  543. /*
  544. * go create the surface (without the OWNDC attribute)
  545. */
  546. pSurfaceDesc->ddsCaps.dwCaps = newcaps;
  547. HRESULT hr = m_pDirectDraw->CreateSurface(pSurfaceDesc, &pSurface, NULL);
  548. pSurfaceDesc->ddsCaps.dwCaps = origcaps;
  549. /*
  550. * once we have the object, get any additional interfaces we need
  551. * to support and then create our surface object
  552. */
  553. if( SUCCEEDED(hr) )
  554. {
  555. hr = CreateSimpleSurface(pSurfaceDesc, pUnkOuter, pSurface, ppNewSurface, dwFlags);
  556. if (!SUCCEEDED(hr))
  557. {
  558. return hr;
  559. }
  560. //we need to worry about attached surfaces, do so here
  561. LPATTACHLIST lpAttach;
  562. //add the current surface to our list of surfaces
  563. IDirectDrawSurface * pOrigSurf = pSurface;
  564. lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList);
  565. while (lpAttach != NULL)
  566. {
  567. lpAttach = lpAttach->lpLink;
  568. pSurface = (IDirectDrawSurface *)((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList))->lpIAttached;
  569. hr = HandleAttachList(pSurfaceDesc, pUnkOuter, &pSurface, pOrigSurf, dwFlags);
  570. if (!SUCCEEDED(hr))
  571. {
  572. //we need to drop out of the loop and clean up
  573. lpAttach = NULL;
  574. }
  575. }
  576. if (!SUCCEEDED(hr))
  577. {
  578. // pSurface = (IDirectDrawSurface *)((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pOrigSurf))->lpLcl->lpAttachList))->lpIAttached;
  579. // lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList);
  580. while (lpAttach != NULL)
  581. {
  582. //clean up these surfaces
  583. lpAttach = lpAttach->lpLink;
  584. }
  585. }
  586. }
  587. return hr;
  588. } /* CDirectDrawEX::CreateSurface */
  589. //
  590. // This is a modified copy of the above except using surfacedesc2 and surface4
  591. //
  592. STDMETHODIMP CDirectDrawEx::CreateSurface(LPDDSURFACEDESC2 pSurfaceDesc2, IDirectDrawSurface4 **ppNewSurface4, IUnknown *pUnkOuter)
  593. {
  594. DWORD origcaps;
  595. DWORD newcaps;
  596. DWORD dwFlags;
  597. IDirectDrawSurface4 *pSurface4;
  598. if (pSurfaceDesc2 == NULL)
  599. return DDERR_INVALIDPARAMS;
  600. if (ppNewSurface4 == NULL)
  601. return DDERR_INVALIDPARAMS;
  602. origcaps = pSurfaceDesc2->ddsCaps.dwCaps;
  603. newcaps = origcaps;
  604. /*
  605. * If OWNDC is specified, it must be a system memory surface
  606. */
  607. if ((origcaps & (DDSCAPS_OWNDC | DDSCAPS_SYSTEMMEMORY)) == DDSCAPS_OWNDC)
  608. {
  609. return DDERR_INVALIDCAPS;
  610. }
  611. /*
  612. * DATAEXCHANGE has some magic...
  613. */
  614. if( (origcaps & DDSCAPS_DATAEXCHANGE) == DDSCAPS_DATAEXCHANGE )
  615. {
  616. dwFlags = SURFACE_DATAEXCHANGE;
  617. //Do not allow the primary surface with these caps!!!!
  618. if (origcaps & DDSCAPS_PRIMARYSURFACE)
  619. return DDERR_INVALIDCAPS;
  620. newcaps &= ~DDSCAPS_DATAEXCHANGE;
  621. newcaps |= DDSCAPS_SYSTEMMEMORY | DDSCAPS_OWNDC | DDSCAPS_TEXTURE;
  622. if (newcaps & DDSCAPS_OFFSCREENPLAIN)
  623. newcaps &= ~DDSCAPS_OFFSCREENPLAIN;
  624. }
  625. else
  626. dwFlags = 0;
  627. /*
  628. * turn off OWNDC when going to DirectDraw 3
  629. */
  630. if (m_dwDDVer != WIN95_DX5 && m_dwDDVer != WINNT_DX5)
  631. newcaps &= ~DDSCAPS_OWNDC;
  632. /*
  633. * go create the surface (without the OWNDC attribute)
  634. */
  635. pSurfaceDesc2->ddsCaps.dwCaps = newcaps;
  636. HRESULT hr = m_pDirectDraw4->CreateSurface(pSurfaceDesc2, &pSurface4, NULL);
  637. pSurfaceDesc2->ddsCaps.dwCaps = origcaps;
  638. /*
  639. * once we have the object, get any additional interfaces we need
  640. * to support and then create our surface object
  641. */
  642. if( SUCCEEDED(hr) )
  643. {
  644. IDirectDrawSurface * pSurface;
  645. pSurface4->QueryInterface(IID_IDirectDrawSurface, (void **)&pSurface);
  646. pSurface4->Release();
  647. DDSURFACEDESC ddsd;
  648. ddsd.dwSize = sizeof(ddsd);
  649. pSurface->GetSurfaceDesc(&ddsd);
  650. ddsd.ddsCaps.dwCaps = origcaps;
  651. IDirectDrawSurface *pNewSurf1;
  652. hr = CreateSimpleSurface(&ddsd, pUnkOuter, pSurface, &pNewSurf1, dwFlags);
  653. if (!SUCCEEDED(hr))
  654. {
  655. return hr;
  656. }
  657. pNewSurf1->QueryInterface(IID_IDirectDrawSurface4, (void **)ppNewSurface4);
  658. pNewSurf1->Release();
  659. //we need to worry about attached surfaces, do so here
  660. LPATTACHLIST lpAttach;
  661. //add the current surface to our list of surfaces
  662. IDirectDrawSurface * pOrigSurf = pSurface;
  663. lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList);
  664. while (lpAttach != NULL)
  665. {
  666. lpAttach = lpAttach->lpLink;
  667. pSurface = (IDirectDrawSurface *)((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList))->lpIAttached;
  668. hr = HandleAttachList(&ddsd, pUnkOuter, &pSurface, pOrigSurf, dwFlags);
  669. if (!SUCCEEDED(hr))
  670. {
  671. //we need to drop out of the loop and clean up
  672. lpAttach = NULL;
  673. }
  674. }
  675. if (!SUCCEEDED(hr))
  676. {
  677. // pSurface = (IDirectDrawSurface *)((LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pOrigSurf))->lpLcl->lpAttachList))->lpIAttached;
  678. // lpAttach = (LPATTACHLIST)(((LPDDRAWI_DDRAWSURFACE_INT)(pSurface))->lpLcl->lpAttachList);
  679. while (lpAttach != NULL)
  680. {
  681. //clean up these surfaces
  682. lpAttach = lpAttach->lpLink;
  683. }
  684. }
  685. }
  686. return hr;
  687. } /* CDirectDrawEX::CreateSurface */
  688. STDMETHODIMP CDirectDrawEx::CreatePalette(DWORD dwFlags, LPPALETTEENTRY pEntries, LPDIRECTDRAWPALETTE FAR * ppPal, IUnknown FAR * pUnkOuter)
  689. {
  690. IDirectDrawPalette *pPalette;
  691. HRESULT hr = m_pDirectDraw->CreatePalette(dwFlags, pEntries, &pPalette, NULL);
  692. if (SUCCEEDED(hr))
  693. {
  694. hr = CDDPalette::CreateSimplePalette(pEntries, pPalette, ppPal, pUnkOuter, this);
  695. if (FAILED(hr))
  696. {
  697. //we were unable to create our palette structure, so we must delete the palette
  698. //we created here and fail
  699. pPalette->Release();
  700. *ppPal = NULL;
  701. }
  702. }
  703. return hr;
  704. }
  705. STDMETHODIMP CDirectDrawEx::SetCooperativeLevel(HWND hwnd, DWORD dwFlags)
  706. {
  707. HRESULT hr = m_pDirectDraw->SetCooperativeLevel(hwnd, dwFlags);
  708. //check for exclusive mode here
  709. if (dwFlags & DDSCL_EXCLUSIVE)
  710. m_bExclusive = TRUE;
  711. else
  712. m_bExclusive = FALSE;
  713. return hr;
  714. }
  715. /*
  716. * some quicky inline fns to get at our object data
  717. */
  718. _inline CDirectDrawEx * PARENTOF(IDirectDraw * pDD)
  719. {
  720. return ((INTSTRUC_IDirectDraw *)pDD)->m_pDirectDrawEx;
  721. }
  722. _inline CDirectDrawEx * PARENTOF(IDirectDraw2 * pDD2)
  723. {
  724. return ((INTSTRUC_IDirectDraw2 *)pDD2)->m_pDirectDrawEx;
  725. }
  726. _inline CDirectDrawEx * PARENTOF(IDirectDraw4 * pDD4)
  727. {
  728. return ((INTSTRUC_IDirectDraw4 *)pDD4)->m_pDirectDrawEx;
  729. }
  730. /*
  731. * the implementation of the functions in IDirectDraw that we are overriding
  732. * (IUnknown and CreateSurface)
  733. */
  734. STDMETHODIMP_(ULONG) IDirectDrawAggAddRef(IDirectDraw *pDD)
  735. {
  736. return PARENTOF(pDD)->m_pUnkOuter->AddRef();
  737. }
  738. STDMETHODIMP_(ULONG) IDirectDrawAggRelease(IDirectDraw *pDD)
  739. {
  740. return PARENTOF(pDD)->m_pUnkOuter->Release();
  741. }
  742. STDMETHODIMP IDirectDrawAggCreateSurface(IDirectDraw *pDD, LPDDSURFACEDESC pSurfaceDesc,
  743. IDirectDrawSurface **ppNewSurface, IUnknown *pUnkOuter)
  744. {
  745. return PARENTOF(pDD)->CreateSurface(pSurfaceDesc, ppNewSurface, pUnkOuter);
  746. }
  747. STDMETHODIMP IDirectDrawAggCreatePalette(IDirectDraw *pDD,DWORD dwFlags, LPPALETTEENTRY pEntries, LPDIRECTDRAWPALETTE FAR * ppPal, IUnknown FAR * pUnkOuter)
  748. {
  749. return PARENTOF(pDD)->CreatePalette( dwFlags, pEntries, ppPal, pUnkOuter);
  750. }
  751. STDMETHODIMP IDirectDrawAggSetCooperativeLevel(IDirectDraw * pDD, HWND hwnd, DWORD dwFlags)
  752. {
  753. return PARENTOF(pDD)->SetCooperativeLevel(hwnd, dwFlags);
  754. }
  755. /*
  756. * the implementation of the functions in IDirectDraw2 that we are overriding
  757. * (IUnknown and CreateSurface)
  758. */
  759. STDMETHODIMP_(ULONG) IDirectDraw2AggAddRef(IDirectDraw2 *pDD)
  760. {
  761. return PARENTOF(pDD)->m_pUnkOuter->AddRef();
  762. }
  763. STDMETHODIMP_(ULONG) IDirectDraw2AggRelease(IDirectDraw2 *pDD)
  764. {
  765. return PARENTOF(pDD)->m_pUnkOuter->Release();
  766. }
  767. STDMETHODIMP IDirectDraw2AggCreateSurface(IDirectDraw2 *pDD, LPDDSURFACEDESC pSurfaceDesc,
  768. IDirectDrawSurface **ppNewSurface, IUnknown *pUnkOuter)
  769. {
  770. return PARENTOF(pDD)->CreateSurface(pSurfaceDesc, ppNewSurface, pUnkOuter);
  771. }
  772. STDMETHODIMP IDirectDraw2AggCreatePalette(IDirectDraw2 *pDD,DWORD dwFlags, LPPALETTEENTRY pEntries, LPDIRECTDRAWPALETTE FAR * ppPal, IUnknown FAR * pUnkOuter)
  773. {
  774. return PARENTOF(pDD)->CreatePalette( dwFlags, pEntries, ppPal, pUnkOuter);
  775. }
  776. STDMETHODIMP IDirectDraw2AggSetCooperativeLevel(IDirectDraw2 * pDD, HWND hwnd, DWORD dwFlags)
  777. {
  778. return PARENTOF(pDD)->SetCooperativeLevel(hwnd, dwFlags);
  779. }
  780. /***************************************************************************
  781. *
  782. *
  783. * IDirectDraw3 stuff follows
  784. *
  785. *
  786. ***************************************************************************/
  787. STDMETHODIMP CDirectDrawEx::Compact()
  788. {
  789. return m_pDirectDraw2->Compact();
  790. }
  791. STDMETHODIMP CDirectDrawEx::CreateClipper(DWORD dwParam, LPDIRECTDRAWCLIPPER FAR* pClip, IUnknown FAR * pIUnk )
  792. {
  793. return m_pDirectDraw2->CreateClipper(dwParam, pClip, pIUnk);
  794. }
  795. STDMETHODIMP CDirectDrawEx::DuplicateSurface(LPDIRECTDRAWSURFACE pSurf, LPDIRECTDRAWSURFACE FAR * ppSurf2)
  796. {
  797. return m_pDirectDraw2->DuplicateSurface(pSurf, ppSurf2);
  798. }
  799. STDMETHODIMP CDirectDrawEx::EnumDisplayModes(DWORD dwParam, LPDDSURFACEDESC pSurfDesc, LPVOID pPtr, LPDDENUMMODESCALLBACK pCallback )
  800. {
  801. return m_pDirectDraw2->EnumDisplayModes(dwParam, pSurfDesc, pPtr, pCallback);
  802. }
  803. STDMETHODIMP CDirectDrawEx::EnumSurfaces(DWORD dwParam, LPDDSURFACEDESC pSurfDesc, LPVOID pPtr,LPDDENUMSURFACESCALLBACK pCallback)
  804. {
  805. return m_pDirectDraw2->EnumSurfaces(dwParam, pSurfDesc, pPtr, pCallback);
  806. }
  807. STDMETHODIMP CDirectDrawEx::FlipToGDISurface()
  808. {
  809. return m_pDirectDraw2->FlipToGDISurface();
  810. }
  811. STDMETHODIMP CDirectDrawEx::GetCaps(LPDDCAPS pDDCaps1, LPDDCAPS pDDCaps2)
  812. {
  813. return m_pDirectDraw2->GetCaps(pDDCaps1, pDDCaps2);
  814. }
  815. STDMETHODIMP CDirectDrawEx::GetDisplayMode(LPDDSURFACEDESC pSurfDesc)
  816. {
  817. return m_pDirectDraw2->GetDisplayMode(pSurfDesc);
  818. }
  819. STDMETHODIMP CDirectDrawEx::GetFourCCCodes(LPDWORD pDW1, LPDWORD pDW2 )
  820. {
  821. return m_pDirectDraw2->GetFourCCCodes(pDW1, pDW2);
  822. }
  823. STDMETHODIMP CDirectDrawEx::GetGDISurface(LPDIRECTDRAWSURFACE FAR * ppSurf)
  824. {
  825. return m_pDirectDraw2->GetGDISurface(ppSurf);
  826. }
  827. STDMETHODIMP CDirectDrawEx::GetMonitorFrequency(LPDWORD pParam)
  828. {
  829. return m_pDirectDraw2->GetMonitorFrequency(pParam);
  830. }
  831. STDMETHODIMP CDirectDrawEx::GetScanLine(LPDWORD pParam)
  832. {
  833. return m_pDirectDraw2->GetScanLine(pParam);
  834. }
  835. STDMETHODIMP CDirectDrawEx::GetVerticalBlankStatus(LPBOOL lpParam )
  836. {
  837. return m_pDirectDraw2->GetVerticalBlankStatus(lpParam);
  838. }
  839. STDMETHODIMP CDirectDrawEx::Initialize(GUID FAR * pGUID)
  840. {
  841. return m_pDirectDraw2->Initialize(pGUID);
  842. }
  843. STDMETHODIMP CDirectDrawEx::RestoreDisplayMode()
  844. {
  845. return m_pDirectDraw2->RestoreDisplayMode();
  846. }
  847. STDMETHODIMP CDirectDrawEx::SetDisplayMode(DWORD dw1, DWORD dw2, DWORD dw3, DWORD dw4, DWORD dw5)
  848. {
  849. return m_pDirectDraw2->SetDisplayMode(dw1, dw2, dw3, dw4, dw5);
  850. }
  851. STDMETHODIMP CDirectDrawEx::WaitForVerticalBlank(DWORD dw1, HANDLE hdl)
  852. {
  853. return m_pDirectDraw2->WaitForVerticalBlank(dw1, hdl);
  854. }
  855. STDMETHODIMP CDirectDrawEx::GetAvailableVidMem(LPDDSCAPS pDDSCaps, LPDWORD pParam1, LPDWORD pParam2)
  856. {
  857. return m_pDirectDraw2->GetAvailableVidMem(pDDSCaps, pParam1, pParam2);
  858. }
  859. /*
  860. * the implementation of the functions in IDirectDraw4 that we are overriding
  861. * (IUnknown and CreateSurface)
  862. */
  863. STDMETHODIMP_(ULONG) IDirectDraw4AggAddRef(IDirectDraw4 *pDD)
  864. {
  865. return PARENTOF(pDD)->m_pUnkOuter->AddRef();
  866. }
  867. STDMETHODIMP_(ULONG) IDirectDraw4AggRelease(IDirectDraw4 *pDD)
  868. {
  869. return PARENTOF(pDD)->m_pUnkOuter->Release();
  870. }
  871. STDMETHODIMP IDirectDraw4AggCreateSurface(IDirectDraw4 *pDD, LPDDSURFACEDESC2 pSurfaceDesc2,
  872. IDirectDrawSurface4 **ppNewSurface4, IUnknown *pUnkOuter)
  873. {
  874. return PARENTOF(pDD)->CreateSurface(pSurfaceDesc2, ppNewSurface4, pUnkOuter);
  875. }
  876. STDMETHODIMP IDirectDraw4AggCreatePalette(IDirectDraw4 *pDD,DWORD dwFlags, LPPALETTEENTRY pEntries, LPDIRECTDRAWPALETTE FAR * ppPal, IUnknown FAR * pUnkOuter)
  877. {
  878. return PARENTOF(pDD)->CreatePalette( dwFlags, pEntries, ppPal, pUnkOuter);
  879. }
  880. STDMETHODIMP IDirectDraw4AggSetCooperativeLevel(IDirectDraw4 * pDD, HWND hwnd, DWORD dwFlags)
  881. {
  882. return PARENTOF(pDD)->SetCooperativeLevel(hwnd, dwFlags);
  883. }