1
0

videoctl.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. //------------------------------------------------------------------------------
  2. // File: VideoCtl.cpp
  3. //
  4. // Desc: DirectShow base classes.
  5. //
  6. // Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
  7. //------------------------------------------------------------------------------
  8. #include <streams.h>
  9. #include "ddmm.h"
  10. // Load a string from the resource file string table. The buffer must be at
  11. // least STR_MAX_LENGTH bytes. The easiest way to use this is to declare a
  12. // buffer in the property page class and use it for all string loading. It
  13. // cannot be static as multiple property pages may be active simultaneously
  14. LPTSTR WINAPI StringFromResource(__out_ecount(STR_MAX_LENGTH) LPTSTR pBuffer, int iResourceID)
  15. {
  16. if (LoadString(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH) == 0) {
  17. return TEXT("");
  18. }
  19. return pBuffer;
  20. }
  21. #ifdef UNICODE
  22. LPSTR WINAPI StringFromResource(__out_ecount(STR_MAX_LENGTH) LPSTR pBuffer, int iResourceID)
  23. {
  24. if (LoadStringA(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH) == 0) {
  25. return "";
  26. }
  27. return pBuffer;
  28. }
  29. #endif
  30. // Property pages typically are called through their OLE interfaces. These
  31. // use UNICODE strings regardless of how the binary is built. So when we
  32. // load strings from the resource file we sometimes want to convert them
  33. // to UNICODE. This method is passed the target UNICODE buffer and does a
  34. // convert after loading the string (if built UNICODE this is not needed)
  35. // On WinNT we can explicitly call LoadStringW which saves two conversions
  36. #ifndef UNICODE
  37. LPWSTR WINAPI WideStringFromResource(__out_ecount(STR_MAX_LENGTH) LPWSTR pBuffer, int iResourceID)
  38. {
  39. *pBuffer = 0;
  40. if (g_amPlatform == VER_PLATFORM_WIN32_NT) {
  41. LoadStringW(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH);
  42. } else {
  43. CHAR szBuffer[STR_MAX_LENGTH];
  44. DWORD dwStringLength = LoadString(g_hInst,iResourceID,szBuffer,STR_MAX_LENGTH);
  45. // if we loaded a string convert it to wide characters, ensuring
  46. // that we also null terminate the result.
  47. if (dwStringLength++) {
  48. MultiByteToWideChar(CP_ACP,0,szBuffer,dwStringLength,pBuffer,STR_MAX_LENGTH);
  49. }
  50. }
  51. return pBuffer;
  52. }
  53. #endif
  54. // Helper function to calculate the size of the dialog
  55. BOOL WINAPI GetDialogSize(int iResourceID,
  56. DLGPROC pDlgProc,
  57. LPARAM lParam,
  58. __out SIZE *pResult)
  59. {
  60. RECT rc;
  61. HWND hwnd;
  62. // Create a temporary property page
  63. hwnd = CreateDialogParam(g_hInst,
  64. MAKEINTRESOURCE(iResourceID),
  65. GetDesktopWindow(),
  66. pDlgProc,
  67. lParam);
  68. if (hwnd == NULL) {
  69. return FALSE;
  70. }
  71. GetWindowRect(hwnd, &rc);
  72. pResult->cx = rc.right - rc.left;
  73. pResult->cy = rc.bottom - rc.top;
  74. DestroyWindow(hwnd);
  75. return TRUE;
  76. }
  77. // Class that aggregates on the IDirectDraw interface. Although DirectDraw
  78. // has the ability in its interfaces to be aggregated they're not currently
  79. // implemented. This makes it difficult for various parts of Quartz that want
  80. // to aggregate these interfaces. In particular the video renderer passes out
  81. // media samples that expose IDirectDraw and IDirectDrawSurface. The filter
  82. // graph manager also exposes IDirectDraw as a plug in distributor. For these
  83. // objects we provide these aggregation classes that republish the interfaces
  84. STDMETHODIMP CAggDirectDraw::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
  85. {
  86. ASSERT(m_pDirectDraw);
  87. // Do we have this interface
  88. if (riid == IID_IDirectDraw) {
  89. return GetInterface((IDirectDraw *)this,ppv);
  90. } else {
  91. return CUnknown::NonDelegatingQueryInterface(riid,ppv);
  92. }
  93. }
  94. STDMETHODIMP CAggDirectDraw::Compact()
  95. {
  96. ASSERT(m_pDirectDraw);
  97. return m_pDirectDraw->Compact();
  98. }
  99. STDMETHODIMP CAggDirectDraw::CreateClipper(DWORD dwFlags, __deref_out LPDIRECTDRAWCLIPPER *lplpDDClipper, __inout_opt IUnknown *pUnkOuter)
  100. {
  101. ASSERT(m_pDirectDraw);
  102. return m_pDirectDraw->CreateClipper(dwFlags,lplpDDClipper,pUnkOuter);
  103. }
  104. STDMETHODIMP CAggDirectDraw::CreatePalette(DWORD dwFlags,
  105. __in LPPALETTEENTRY lpColorTable,
  106. __deref_out LPDIRECTDRAWPALETTE *lplpDDPalette,
  107. __inout_opt IUnknown *pUnkOuter)
  108. {
  109. ASSERT(m_pDirectDraw);
  110. return m_pDirectDraw->CreatePalette(dwFlags,lpColorTable,lplpDDPalette,pUnkOuter);
  111. }
  112. STDMETHODIMP CAggDirectDraw::CreateSurface(__in LPDDSURFACEDESC lpDDSurfaceDesc,
  113. __deref_out LPDIRECTDRAWSURFACE *lplpDDSurface,
  114. __inout_opt IUnknown *pUnkOuter)
  115. {
  116. ASSERT(m_pDirectDraw);
  117. return m_pDirectDraw->CreateSurface(lpDDSurfaceDesc,lplpDDSurface,pUnkOuter);
  118. }
  119. STDMETHODIMP CAggDirectDraw::DuplicateSurface(__in LPDIRECTDRAWSURFACE lpDDSurface,
  120. __deref_out LPDIRECTDRAWSURFACE *lplpDupDDSurface)
  121. {
  122. ASSERT(m_pDirectDraw);
  123. return m_pDirectDraw->DuplicateSurface(lpDDSurface,lplpDupDDSurface);
  124. }
  125. STDMETHODIMP CAggDirectDraw::EnumDisplayModes(DWORD dwSurfaceDescCount,
  126. __in LPDDSURFACEDESC lplpDDSurfaceDescList,
  127. __in LPVOID lpContext,
  128. __in LPDDENUMMODESCALLBACK lpEnumCallback)
  129. {
  130. ASSERT(m_pDirectDraw);
  131. return m_pDirectDraw->EnumDisplayModes(dwSurfaceDescCount,lplpDDSurfaceDescList,lpContext,lpEnumCallback);
  132. }
  133. STDMETHODIMP CAggDirectDraw::EnumSurfaces(DWORD dwFlags,
  134. __in LPDDSURFACEDESC lpDDSD,
  135. __in LPVOID lpContext,
  136. __in LPDDENUMSURFACESCALLBACK lpEnumCallback)
  137. {
  138. ASSERT(m_pDirectDraw);
  139. return m_pDirectDraw->EnumSurfaces(dwFlags,lpDDSD,lpContext,lpEnumCallback);
  140. }
  141. STDMETHODIMP CAggDirectDraw::FlipToGDISurface()
  142. {
  143. ASSERT(m_pDirectDraw);
  144. return m_pDirectDraw->FlipToGDISurface();
  145. }
  146. STDMETHODIMP CAggDirectDraw::GetCaps(__out LPDDCAPS lpDDDriverCaps,__out LPDDCAPS lpDDHELCaps)
  147. {
  148. ASSERT(m_pDirectDraw);
  149. return m_pDirectDraw->GetCaps(lpDDDriverCaps,lpDDHELCaps);
  150. }
  151. STDMETHODIMP CAggDirectDraw::GetDisplayMode(__out LPDDSURFACEDESC lpDDSurfaceDesc)
  152. {
  153. ASSERT(m_pDirectDraw);
  154. return m_pDirectDraw->GetDisplayMode(lpDDSurfaceDesc);
  155. }
  156. STDMETHODIMP CAggDirectDraw::GetFourCCCodes(__inout LPDWORD lpNumCodes,__out_ecount(*lpNumCodes) LPDWORD lpCodes)
  157. {
  158. ASSERT(m_pDirectDraw);
  159. return m_pDirectDraw->GetFourCCCodes(lpNumCodes,lpCodes);
  160. }
  161. STDMETHODIMP CAggDirectDraw::GetGDISurface(__deref_out LPDIRECTDRAWSURFACE *lplpGDIDDSurface)
  162. {
  163. ASSERT(m_pDirectDraw);
  164. return m_pDirectDraw->GetGDISurface(lplpGDIDDSurface);
  165. }
  166. STDMETHODIMP CAggDirectDraw::GetMonitorFrequency(__out LPDWORD lpdwFrequency)
  167. {
  168. ASSERT(m_pDirectDraw);
  169. return m_pDirectDraw->GetMonitorFrequency(lpdwFrequency);
  170. }
  171. STDMETHODIMP CAggDirectDraw::GetScanLine(__out LPDWORD lpdwScanLine)
  172. {
  173. ASSERT(m_pDirectDraw);
  174. return m_pDirectDraw->GetScanLine(lpdwScanLine);
  175. }
  176. STDMETHODIMP CAggDirectDraw::GetVerticalBlankStatus(__out LPBOOL lpblsInVB)
  177. {
  178. ASSERT(m_pDirectDraw);
  179. return m_pDirectDraw->GetVerticalBlankStatus(lpblsInVB);
  180. }
  181. STDMETHODIMP CAggDirectDraw::Initialize(__in GUID *lpGUID)
  182. {
  183. ASSERT(m_pDirectDraw);
  184. return m_pDirectDraw->Initialize(lpGUID);
  185. }
  186. STDMETHODIMP CAggDirectDraw::RestoreDisplayMode()
  187. {
  188. ASSERT(m_pDirectDraw);
  189. return m_pDirectDraw->RestoreDisplayMode();
  190. }
  191. STDMETHODIMP CAggDirectDraw::SetCooperativeLevel(HWND hWnd,DWORD dwFlags)
  192. {
  193. ASSERT(m_pDirectDraw);
  194. return m_pDirectDraw->SetCooperativeLevel(hWnd,dwFlags);
  195. }
  196. STDMETHODIMP CAggDirectDraw::SetDisplayMode(DWORD dwWidth,DWORD dwHeight,DWORD dwBpp)
  197. {
  198. ASSERT(m_pDirectDraw);
  199. return m_pDirectDraw->SetDisplayMode(dwWidth,dwHeight,dwBpp);
  200. }
  201. STDMETHODIMP CAggDirectDraw::WaitForVerticalBlank(DWORD dwFlags,HANDLE hEvent)
  202. {
  203. ASSERT(m_pDirectDraw);
  204. return m_pDirectDraw->WaitForVerticalBlank(dwFlags,hEvent);
  205. }
  206. // Class that aggregates an IDirectDrawSurface interface. Although DirectDraw
  207. // has the ability in its interfaces to be aggregated they're not currently
  208. // implemented. This makes it difficult for various parts of Quartz that want
  209. // to aggregate these interfaces. In particular the video renderer passes out
  210. // media samples that expose IDirectDraw and IDirectDrawSurface. The filter
  211. // graph manager also exposes IDirectDraw as a plug in distributor. For these
  212. // objects we provide these aggregation classes that republish the interfaces
  213. STDMETHODIMP CAggDrawSurface::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
  214. {
  215. ASSERT(m_pDirectDrawSurface);
  216. // Do we have this interface
  217. if (riid == IID_IDirectDrawSurface) {
  218. return GetInterface((IDirectDrawSurface *)this,ppv);
  219. } else {
  220. return CUnknown::NonDelegatingQueryInterface(riid,ppv);
  221. }
  222. }
  223. STDMETHODIMP CAggDrawSurface::AddAttachedSurface(__in LPDIRECTDRAWSURFACE lpDDSAttachedSurface)
  224. {
  225. ASSERT(m_pDirectDrawSurface);
  226. return m_pDirectDrawSurface->AddAttachedSurface(lpDDSAttachedSurface);
  227. }
  228. STDMETHODIMP CAggDrawSurface::AddOverlayDirtyRect(__in LPRECT lpRect)
  229. {
  230. ASSERT(m_pDirectDrawSurface);
  231. return m_pDirectDrawSurface->AddOverlayDirtyRect(lpRect);
  232. }
  233. STDMETHODIMP CAggDrawSurface::Blt(__in LPRECT lpDestRect,
  234. __in LPDIRECTDRAWSURFACE lpDDSrcSurface,
  235. __in LPRECT lpSrcRect,
  236. DWORD dwFlags,
  237. __in LPDDBLTFX lpDDBltFx)
  238. {
  239. ASSERT(m_pDirectDrawSurface);
  240. return m_pDirectDrawSurface->Blt(lpDestRect,lpDDSrcSurface,lpSrcRect,dwFlags,lpDDBltFx);
  241. }
  242. STDMETHODIMP CAggDrawSurface::BltBatch(__in_ecount(dwCount) LPDDBLTBATCH lpDDBltBatch,DWORD dwCount,DWORD dwFlags)
  243. {
  244. ASSERT(m_pDirectDrawSurface);
  245. return m_pDirectDrawSurface->BltBatch(lpDDBltBatch,dwCount,dwFlags);
  246. }
  247. STDMETHODIMP CAggDrawSurface::BltFast(DWORD dwX,DWORD dwY,
  248. __in LPDIRECTDRAWSURFACE lpDDSrcSurface,
  249. __in LPRECT lpSrcRect,
  250. DWORD dwTrans)
  251. {
  252. ASSERT(m_pDirectDrawSurface);
  253. return m_pDirectDrawSurface->BltFast(dwX,dwY,lpDDSrcSurface,lpSrcRect,dwTrans);
  254. }
  255. STDMETHODIMP CAggDrawSurface::DeleteAttachedSurface(DWORD dwFlags,
  256. __in LPDIRECTDRAWSURFACE lpDDSAttachedSurface)
  257. {
  258. ASSERT(m_pDirectDrawSurface);
  259. return m_pDirectDrawSurface->DeleteAttachedSurface(dwFlags,lpDDSAttachedSurface);
  260. }
  261. STDMETHODIMP CAggDrawSurface::EnumAttachedSurfaces(__in LPVOID lpContext,
  262. __in LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
  263. {
  264. ASSERT(m_pDirectDrawSurface);
  265. return m_pDirectDrawSurface->EnumAttachedSurfaces(lpContext,lpEnumSurfacesCallback);
  266. }
  267. STDMETHODIMP CAggDrawSurface::EnumOverlayZOrders(DWORD dwFlags,
  268. __in LPVOID lpContext,
  269. __in LPDDENUMSURFACESCALLBACK lpfnCallback)
  270. {
  271. ASSERT(m_pDirectDrawSurface);
  272. return m_pDirectDrawSurface->EnumOverlayZOrders(dwFlags,lpContext,lpfnCallback);
  273. }
  274. STDMETHODIMP CAggDrawSurface::Flip(__in LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride,DWORD dwFlags)
  275. {
  276. ASSERT(m_pDirectDrawSurface);
  277. return m_pDirectDrawSurface->Flip(lpDDSurfaceTargetOverride,dwFlags);
  278. }
  279. STDMETHODIMP CAggDrawSurface::GetAttachedSurface(__in LPDDSCAPS lpDDSCaps,
  280. __deref_out LPDIRECTDRAWSURFACE *lplpDDAttachedSurface)
  281. {
  282. ASSERT(m_pDirectDrawSurface);
  283. return m_pDirectDrawSurface->GetAttachedSurface(lpDDSCaps,lplpDDAttachedSurface);
  284. }
  285. STDMETHODIMP CAggDrawSurface::GetBltStatus(DWORD dwFlags)
  286. {
  287. ASSERT(m_pDirectDrawSurface);
  288. return m_pDirectDrawSurface->GetBltStatus(dwFlags);
  289. }
  290. STDMETHODIMP CAggDrawSurface::GetCaps(__out LPDDSCAPS lpDDSCaps)
  291. {
  292. ASSERT(m_pDirectDrawSurface);
  293. return m_pDirectDrawSurface->GetCaps(lpDDSCaps);
  294. }
  295. STDMETHODIMP CAggDrawSurface::GetClipper(__deref_out LPDIRECTDRAWCLIPPER *lplpDDClipper)
  296. {
  297. ASSERT(m_pDirectDrawSurface);
  298. return m_pDirectDrawSurface->GetClipper(lplpDDClipper);
  299. }
  300. STDMETHODIMP CAggDrawSurface::GetColorKey(DWORD dwFlags,__out LPDDCOLORKEY lpDDColorKey)
  301. {
  302. ASSERT(m_pDirectDrawSurface);
  303. return m_pDirectDrawSurface->GetColorKey(dwFlags,lpDDColorKey);
  304. }
  305. STDMETHODIMP CAggDrawSurface::GetDC(__out HDC *lphDC)
  306. {
  307. ASSERT(m_pDirectDrawSurface);
  308. return m_pDirectDrawSurface->GetDC(lphDC);
  309. }
  310. STDMETHODIMP CAggDrawSurface::GetFlipStatus(DWORD dwFlags)
  311. {
  312. ASSERT(m_pDirectDrawSurface);
  313. return m_pDirectDrawSurface->GetFlipStatus(dwFlags);
  314. }
  315. STDMETHODIMP CAggDrawSurface::GetOverlayPosition(__out LPLONG lpdwX,__out LPLONG lpdwY)
  316. {
  317. ASSERT(m_pDirectDrawSurface);
  318. return m_pDirectDrawSurface->GetOverlayPosition(lpdwX,lpdwY);
  319. }
  320. STDMETHODIMP CAggDrawSurface::GetPalette(__deref_out LPDIRECTDRAWPALETTE *lplpDDPalette)
  321. {
  322. ASSERT(m_pDirectDrawSurface);
  323. return m_pDirectDrawSurface->GetPalette(lplpDDPalette);
  324. }
  325. STDMETHODIMP CAggDrawSurface::GetPixelFormat(__out LPDDPIXELFORMAT lpDDPixelFormat)
  326. {
  327. ASSERT(m_pDirectDrawSurface);
  328. return m_pDirectDrawSurface->GetPixelFormat(lpDDPixelFormat);
  329. }
  330. // A bit of a warning here: Our media samples in DirectShow aggregate on
  331. // IDirectDraw and IDirectDrawSurface (ie are available through IMediaSample
  332. // by QueryInterface). Unfortunately the underlying DirectDraw code cannot
  333. // be aggregated so we have to use these classes. The snag is that when we
  334. // call a different surface and pass in this interface as perhaps the source
  335. // surface the call will fail because DirectDraw dereferences the pointer to
  336. // get at its private data structures. Therefore we supply this workaround to give
  337. // access to the real IDirectDraw surface. A filter can call GetSurfaceDesc
  338. // and we will fill in the lpSurface pointer with the real underlying surface
  339. STDMETHODIMP CAggDrawSurface::GetSurfaceDesc(__out LPDDSURFACEDESC lpDDSurfaceDesc)
  340. {
  341. ASSERT(m_pDirectDrawSurface);
  342. // First call down to the underlying DirectDraw
  343. HRESULT hr = m_pDirectDrawSurface->GetSurfaceDesc(lpDDSurfaceDesc);
  344. if (FAILED(hr)) {
  345. return hr;
  346. }
  347. // Store the real DirectDrawSurface interface
  348. lpDDSurfaceDesc->lpSurface = m_pDirectDrawSurface;
  349. return hr;
  350. }
  351. STDMETHODIMP CAggDrawSurface::Initialize(__in LPDIRECTDRAW lpDD,__in LPDDSURFACEDESC lpDDSurfaceDesc)
  352. {
  353. ASSERT(m_pDirectDrawSurface);
  354. return m_pDirectDrawSurface->Initialize(lpDD,lpDDSurfaceDesc);
  355. }
  356. STDMETHODIMP CAggDrawSurface::IsLost()
  357. {
  358. ASSERT(m_pDirectDrawSurface);
  359. return m_pDirectDrawSurface->IsLost();
  360. }
  361. STDMETHODIMP CAggDrawSurface::Lock(__in LPRECT lpDestRect,
  362. __inout LPDDSURFACEDESC lpDDSurfaceDesc,
  363. DWORD dwFlags,
  364. HANDLE hEvent)
  365. {
  366. ASSERT(m_pDirectDrawSurface);
  367. return m_pDirectDrawSurface->Lock(lpDestRect,lpDDSurfaceDesc,dwFlags,hEvent);
  368. }
  369. STDMETHODIMP CAggDrawSurface::ReleaseDC(HDC hDC)
  370. {
  371. ASSERT(m_pDirectDrawSurface);
  372. return m_pDirectDrawSurface->ReleaseDC(hDC);
  373. }
  374. STDMETHODIMP CAggDrawSurface::Restore()
  375. {
  376. ASSERT(m_pDirectDrawSurface);
  377. return m_pDirectDrawSurface->Restore();
  378. }
  379. STDMETHODIMP CAggDrawSurface::SetClipper(__in LPDIRECTDRAWCLIPPER lpDDClipper)
  380. {
  381. ASSERT(m_pDirectDrawSurface);
  382. return m_pDirectDrawSurface->SetClipper(lpDDClipper);
  383. }
  384. STDMETHODIMP CAggDrawSurface::SetColorKey(DWORD dwFlags,__in LPDDCOLORKEY lpDDColorKey)
  385. {
  386. ASSERT(m_pDirectDrawSurface);
  387. return m_pDirectDrawSurface->SetColorKey(dwFlags,lpDDColorKey);
  388. }
  389. STDMETHODIMP CAggDrawSurface::SetOverlayPosition(LONG dwX,LONG dwY)
  390. {
  391. ASSERT(m_pDirectDrawSurface);
  392. return m_pDirectDrawSurface->SetOverlayPosition(dwX,dwY);
  393. }
  394. STDMETHODIMP CAggDrawSurface::SetPalette(__in LPDIRECTDRAWPALETTE lpDDPalette)
  395. {
  396. ASSERT(m_pDirectDrawSurface);
  397. return m_pDirectDrawSurface->SetPalette(lpDDPalette);
  398. }
  399. STDMETHODIMP CAggDrawSurface::Unlock(__in LPVOID lpSurfaceData)
  400. {
  401. ASSERT(m_pDirectDrawSurface);
  402. return m_pDirectDrawSurface->Unlock(lpSurfaceData);
  403. }
  404. STDMETHODIMP CAggDrawSurface::UpdateOverlay(__in LPRECT lpSrcRect,
  405. __in LPDIRECTDRAWSURFACE lpDDDestSurface,
  406. __in LPRECT lpDestRect,
  407. DWORD dwFlags,
  408. __in LPDDOVERLAYFX lpDDOverlayFX)
  409. {
  410. ASSERT(m_pDirectDrawSurface);
  411. return m_pDirectDrawSurface->UpdateOverlay(lpSrcRect,lpDDDestSurface,lpDestRect,dwFlags,lpDDOverlayFX);
  412. }
  413. STDMETHODIMP CAggDrawSurface::UpdateOverlayDisplay(DWORD dwFlags)
  414. {
  415. ASSERT(m_pDirectDrawSurface);
  416. return m_pDirectDrawSurface->UpdateOverlayDisplay(dwFlags);
  417. }
  418. STDMETHODIMP CAggDrawSurface::UpdateOverlayZOrder(DWORD dwFlags,__in LPDIRECTDRAWSURFACE lpDDSReference)
  419. {
  420. ASSERT(m_pDirectDrawSurface);
  421. return m_pDirectDrawSurface->UpdateOverlayZOrder(dwFlags,lpDDSReference);
  422. }
  423. // DirectShow must work on multiple platforms. In particular, it also runs on
  424. // Windows NT 3.51 which does not have DirectDraw capabilities. The filters
  425. // cannot therefore link statically to the DirectDraw library. To make their
  426. // lives that little bit easier we provide this class that manages loading
  427. // and unloading the library and creating the initial IDirectDraw interface
  428. CLoadDirectDraw::CLoadDirectDraw() :
  429. m_pDirectDraw(NULL),
  430. m_hDirectDraw(NULL)
  431. {
  432. }
  433. // Destructor forces unload
  434. CLoadDirectDraw::~CLoadDirectDraw()
  435. {
  436. ReleaseDirectDraw();
  437. if (m_hDirectDraw) {
  438. NOTE("Unloading library");
  439. FreeLibrary(m_hDirectDraw);
  440. }
  441. }
  442. // We can't be sure that DirectDraw is always available so we can't statically
  443. // link to the library. Therefore we load the library, get the function entry
  444. // point addresses and call them to create the driver objects. We return S_OK
  445. // if we manage to load DirectDraw correctly otherwise we return E_NOINTERFACE
  446. // We initialise a DirectDraw instance by explicitely loading the library and
  447. // calling GetProcAddress on the DirectDrawCreate entry point that it exports
  448. // On a multi monitor system, we can get the DirectDraw object for any
  449. // monitor (device) with the optional szDevice parameter
  450. HRESULT CLoadDirectDraw::LoadDirectDraw(__in LPSTR szDevice)
  451. {
  452. PDRAWCREATE pDrawCreate;
  453. PDRAWENUM pDrawEnum;
  454. LPDIRECTDRAWENUMERATEEXA pDrawEnumEx;
  455. HRESULT hr = NOERROR;
  456. NOTE("Entering DoLoadDirectDraw");
  457. // Is DirectDraw already loaded
  458. if (m_pDirectDraw) {
  459. NOTE("Already loaded");
  460. ASSERT(m_hDirectDraw);
  461. return NOERROR;
  462. }
  463. // Make sure the library is available
  464. if(!m_hDirectDraw)
  465. {
  466. UINT ErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX);
  467. m_hDirectDraw = LoadLibrary(TEXT("DDRAW.DLL"));
  468. SetErrorMode(ErrorMode);
  469. if (m_hDirectDraw == NULL) {
  470. DbgLog((LOG_ERROR,1,TEXT("Can't load DDRAW.DLL")));
  471. NOTE("No library");
  472. return E_NOINTERFACE;
  473. }
  474. }
  475. // Get the DLL address for the creator function
  476. pDrawCreate = (PDRAWCREATE)GetProcAddress(m_hDirectDraw,"DirectDrawCreate");
  477. // force ANSI, we assume it
  478. pDrawEnum = (PDRAWENUM)GetProcAddress(m_hDirectDraw,"DirectDrawEnumerateW");
  479. pDrawEnumEx = (LPDIRECTDRAWENUMERATEEXA)GetProcAddress(m_hDirectDraw,
  480. "DirectDrawEnumerateExW");
  481. // We don't NEED DirectDrawEnumerateEx, that's just for multimon stuff
  482. if (pDrawCreate == NULL || pDrawEnum == NULL) {
  483. DbgLog((LOG_ERROR,1,TEXT("Can't get functions: Create=%x Enum=%x"),
  484. pDrawCreate, pDrawEnum));
  485. NOTE("No entry point");
  486. ReleaseDirectDraw();
  487. return E_NOINTERFACE;
  488. }
  489. DbgLog((LOG_TRACE,3,TEXT("Creating DDraw for device %s"),
  490. szDevice ? szDevice : "<NULL>"));
  491. // Create a DirectDraw display provider for this device, using the fancy
  492. // multimon-aware version, if it exists
  493. if (pDrawEnumEx)
  494. m_pDirectDraw = DirectDrawCreateFromDeviceEx(szDevice, pDrawCreate,
  495. pDrawEnumEx);
  496. else
  497. m_pDirectDraw = DirectDrawCreateFromDevice(szDevice, pDrawCreate,
  498. pDrawEnum);
  499. if (m_pDirectDraw == NULL) {
  500. DbgLog((LOG_ERROR,1,TEXT("Can't create DDraw")));
  501. NOTE("No instance");
  502. ReleaseDirectDraw();
  503. return E_NOINTERFACE;
  504. }
  505. return NOERROR;
  506. }
  507. // Called to release any DirectDraw provider we previously loaded. We may be
  508. // called at any time especially when something goes horribly wrong and when
  509. // we need to clean up before returning so we can't guarantee that all state
  510. // variables are consistent so free only those really allocated allocated
  511. // This should only be called once all reference counts have been released
  512. void CLoadDirectDraw::ReleaseDirectDraw()
  513. {
  514. NOTE("Releasing DirectDraw driver");
  515. // Release any DirectDraw provider interface
  516. if (m_pDirectDraw) {
  517. NOTE("Releasing instance");
  518. m_pDirectDraw->Release();
  519. m_pDirectDraw = NULL;
  520. }
  521. }
  522. // Return NOERROR (S_OK) if DirectDraw has been loaded by this object
  523. HRESULT CLoadDirectDraw::IsDirectDrawLoaded()
  524. {
  525. NOTE("Entering IsDirectDrawLoaded");
  526. if (m_pDirectDraw == NULL) {
  527. NOTE("DirectDraw not loaded");
  528. return S_FALSE;
  529. }
  530. return NOERROR;
  531. }
  532. // Return the IDirectDraw interface we look after
  533. LPDIRECTDRAW CLoadDirectDraw::GetDirectDraw()
  534. {
  535. NOTE("Entering GetDirectDraw");
  536. if (m_pDirectDraw == NULL) {
  537. NOTE("No DirectDraw");
  538. return NULL;
  539. }
  540. NOTE("Returning DirectDraw");
  541. m_pDirectDraw->AddRef();
  542. return m_pDirectDraw;
  543. }
  544. // Are we running on Direct Draw version 1? We need to find out as
  545. // we rely on specific bug fixes in DirectDraw 2 for fullscreen playback. To
  546. // find out, we simply see if it supports IDirectDraw2. Only version 2 and
  547. // higher support this.
  548. BOOL CLoadDirectDraw::IsDirectDrawVersion1()
  549. {
  550. if (m_pDirectDraw == NULL)
  551. return FALSE;
  552. IDirectDraw2 *p = NULL;
  553. HRESULT hr = m_pDirectDraw->QueryInterface(IID_IDirectDraw2, (void **)&p);
  554. if (p)
  555. p->Release();
  556. if (hr == NOERROR) {
  557. DbgLog((LOG_TRACE,3,TEXT("Direct Draw Version 2 or greater")));
  558. return FALSE;
  559. } else {
  560. DbgLog((LOG_TRACE,3,TEXT("Direct Draw Version 1")));
  561. return TRUE;
  562. }
  563. }