1 //------------------------------------------------------------------------------
4 // Desc: DirectShow base classes.
6 // Copyright (c) 1992-2002 Microsoft Corporation. All rights reserved.
7 //------------------------------------------------------------------------------
13 // Load a string from the resource file string table. The buffer must be at
14 // least STR_MAX_LENGTH bytes. The easiest way to use this is to declare a
15 // buffer in the property page class and use it for all string loading. It
16 // cannot be static as multiple property pages may be active simultaneously
18 TCHAR
*WINAPI
StringFromResource(TCHAR
*pBuffer
, int iResourceID
)
20 if (LoadString(g_hInst
,iResourceID
,pBuffer
,STR_MAX_LENGTH
) == 0) {
27 char *WINAPI
StringFromResource(char *pBuffer
, int iResourceID
)
29 if (LoadStringA(g_hInst
,iResourceID
,pBuffer
,STR_MAX_LENGTH
) == 0) {
38 // Property pages typically are called through their OLE interfaces. These
39 // use UNICODE strings regardless of how the binary is built. So when we
40 // load strings from the resource file we sometimes want to convert them
41 // to UNICODE. This method is passed the target UNICODE buffer and does a
42 // convert after loading the string (if built UNICODE this is not needed)
43 // On WinNT we can explicitly call LoadStringW which saves two conversions
47 WCHAR
* WINAPI
WideStringFromResource(WCHAR
*pBuffer
, int iResourceID
)
51 if (g_amPlatform
== VER_PLATFORM_WIN32_NT
) {
52 LoadStringW(g_hInst
,iResourceID
,pBuffer
,STR_MAX_LENGTH
);
55 CHAR szBuffer
[STR_MAX_LENGTH
];
56 DWORD dwStringLength
= LoadString(g_hInst
,iResourceID
,szBuffer
,STR_MAX_LENGTH
);
57 // if we loaded a string convert it to wide characters, ensuring
58 // that we also null terminate the result.
59 if (dwStringLength
++) {
60 MultiByteToWideChar(CP_ACP
,0,szBuffer
,dwStringLength
,pBuffer
,STR_MAX_LENGTH
);
69 // Helper function to calculate the size of the dialog
71 BOOL WINAPI
GetDialogSize(int iResourceID
,
79 // Create a temporary property page
81 hwnd
= CreateDialogParam(g_hInst
,
82 MAKEINTRESOURCE(iResourceID
),
90 GetWindowRect(hwnd
, &rc
);
91 pResult
->cx
= rc
.right
- rc
.left
;
92 pResult
->cy
= rc
.bottom
- rc
.top
;
99 // Class that aggregates on the IDirectDraw interface. Although DirectDraw
100 // has the ability in its interfaces to be aggregated they're not currently
101 // implemented. This makes it difficult for various parts of Quartz that want
102 // to aggregate these interfaces. In particular the video renderer passes out
103 // media samples that expose IDirectDraw and IDirectDrawSurface. The filter
104 // graph manager also exposes IDirectDraw as a plug in distributor. For these
105 // objects we provide these aggregation classes that republish the interfaces
107 STDMETHODIMP
CAggDirectDraw::NonDelegatingQueryInterface(REFIID riid
, void **ppv
)
109 ASSERT(m_pDirectDraw
);
111 // Do we have this interface
113 if (riid
== IID_IDirectDraw
) {
114 return GetInterface((IDirectDraw
*)this,ppv
);
116 return CUnknown::NonDelegatingQueryInterface(riid
,ppv
);
121 STDMETHODIMP
CAggDirectDraw::Compact()
123 ASSERT(m_pDirectDraw
);
124 return m_pDirectDraw
->Compact();
128 STDMETHODIMP
CAggDirectDraw::CreateClipper(DWORD dwFlags
,LPDIRECTDRAWCLIPPER
*lplpDDClipper
,IUnknown
*pUnkOuter
)
130 ASSERT(m_pDirectDraw
);
131 return m_pDirectDraw
->CreateClipper(dwFlags
,lplpDDClipper
,pUnkOuter
);
135 STDMETHODIMP
CAggDirectDraw::CreatePalette(DWORD dwFlags
,LPPALETTEENTRY lpColorTable
,LPDIRECTDRAWPALETTE
*lplpDDPalette
,IUnknown
*pUnkOuter
)
137 ASSERT(m_pDirectDraw
);
138 return m_pDirectDraw
->CreatePalette(dwFlags
,lpColorTable
,lplpDDPalette
,pUnkOuter
);
142 STDMETHODIMP
CAggDirectDraw::CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc
,LPDIRECTDRAWSURFACE
*lplpDDSurface
,IUnknown
*pUnkOuter
)
144 ASSERT(m_pDirectDraw
);
145 return m_pDirectDraw
->CreateSurface(lpDDSurfaceDesc
,lplpDDSurface
,pUnkOuter
);
149 STDMETHODIMP
CAggDirectDraw::DuplicateSurface(LPDIRECTDRAWSURFACE lpDDSurface
,LPDIRECTDRAWSURFACE
*lplpDupDDSurface
)
151 ASSERT(m_pDirectDraw
);
152 return m_pDirectDraw
->DuplicateSurface(lpDDSurface
,lplpDupDDSurface
);
156 STDMETHODIMP
CAggDirectDraw::EnumDisplayModes(DWORD dwSurfaceDescCount
,LPDDSURFACEDESC lplpDDSurfaceDescList
,LPVOID lpContext
,LPDDENUMMODESCALLBACK lpEnumCallback
)
158 ASSERT(m_pDirectDraw
);
159 return m_pDirectDraw
->EnumDisplayModes(dwSurfaceDescCount
,lplpDDSurfaceDescList
,lpContext
,lpEnumCallback
);
163 STDMETHODIMP
CAggDirectDraw::EnumSurfaces(DWORD dwFlags
,LPDDSURFACEDESC lpDDSD
,LPVOID lpContext
,LPDDENUMSURFACESCALLBACK lpEnumCallback
)
165 ASSERT(m_pDirectDraw
);
166 return m_pDirectDraw
->EnumSurfaces(dwFlags
,lpDDSD
,lpContext
,lpEnumCallback
);
170 STDMETHODIMP
CAggDirectDraw::FlipToGDISurface()
172 ASSERT(m_pDirectDraw
);
173 return m_pDirectDraw
->FlipToGDISurface();
177 STDMETHODIMP
CAggDirectDraw::GetCaps(LPDDCAPS lpDDDriverCaps
,LPDDCAPS lpDDHELCaps
)
179 ASSERT(m_pDirectDraw
);
180 return m_pDirectDraw
->GetCaps(lpDDDriverCaps
,lpDDHELCaps
);
184 STDMETHODIMP
CAggDirectDraw::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc
)
186 ASSERT(m_pDirectDraw
);
187 return m_pDirectDraw
->GetDisplayMode(lpDDSurfaceDesc
);
191 STDMETHODIMP
CAggDirectDraw::GetFourCCCodes(LPDWORD lpNumCodes
,LPDWORD lpCodes
)
193 ASSERT(m_pDirectDraw
);
194 return m_pDirectDraw
->GetFourCCCodes(lpNumCodes
,lpCodes
);
198 STDMETHODIMP
CAggDirectDraw::GetGDISurface(LPDIRECTDRAWSURFACE
*lplpGDIDDSurface
)
200 ASSERT(m_pDirectDraw
);
201 return m_pDirectDraw
->GetGDISurface(lplpGDIDDSurface
);
205 STDMETHODIMP
CAggDirectDraw::GetMonitorFrequency(LPDWORD lpdwFrequency
)
207 ASSERT(m_pDirectDraw
);
208 return m_pDirectDraw
->GetMonitorFrequency(lpdwFrequency
);
212 STDMETHODIMP
CAggDirectDraw::GetScanLine(LPDWORD lpdwScanLine
)
214 ASSERT(m_pDirectDraw
);
215 return m_pDirectDraw
->GetScanLine(lpdwScanLine
);
219 STDMETHODIMP
CAggDirectDraw::GetVerticalBlankStatus(LPBOOL lpblsInVB
)
221 ASSERT(m_pDirectDraw
);
222 return m_pDirectDraw
->GetVerticalBlankStatus(lpblsInVB
);
226 STDMETHODIMP
CAggDirectDraw::Initialize(GUID
*lpGUID
)
228 ASSERT(m_pDirectDraw
);
229 return m_pDirectDraw
->Initialize(lpGUID
);
233 STDMETHODIMP
CAggDirectDraw::RestoreDisplayMode()
235 ASSERT(m_pDirectDraw
);
236 return m_pDirectDraw
->RestoreDisplayMode();
240 STDMETHODIMP
CAggDirectDraw::SetCooperativeLevel(HWND hWnd
,DWORD dwFlags
)
242 ASSERT(m_pDirectDraw
);
243 return m_pDirectDraw
->SetCooperativeLevel(hWnd
,dwFlags
);
247 STDMETHODIMP
CAggDirectDraw::SetDisplayMode(DWORD dwWidth
,DWORD dwHeight
,DWORD dwBpp
)
249 ASSERT(m_pDirectDraw
);
250 return m_pDirectDraw
->SetDisplayMode(dwWidth
,dwHeight
,dwBpp
);
254 STDMETHODIMP
CAggDirectDraw::WaitForVerticalBlank(DWORD dwFlags
,HANDLE hEvent
)
256 ASSERT(m_pDirectDraw
);
257 return m_pDirectDraw
->WaitForVerticalBlank(dwFlags
,hEvent
);
261 // Class that aggregates an IDirectDrawSurface interface. Although DirectDraw
262 // has the ability in its interfaces to be aggregated they're not currently
263 // implemented. This makes it difficult for various parts of Quartz that want
264 // to aggregate these interfaces. In particular the video renderer passes out
265 // media samples that expose IDirectDraw and IDirectDrawSurface. The filter
266 // graph manager also exposes IDirectDraw as a plug in distributor. For these
267 // objects we provide these aggregation classes that republish the interfaces
269 STDMETHODIMP
CAggDrawSurface::NonDelegatingQueryInterface(REFIID riid
, void **ppv
)
271 ASSERT(m_pDirectDrawSurface
);
273 // Do we have this interface
275 if (riid
== IID_IDirectDrawSurface
) {
276 return GetInterface((IDirectDrawSurface
*)this,ppv
);
278 return CUnknown::NonDelegatingQueryInterface(riid
,ppv
);
283 STDMETHODIMP
CAggDrawSurface::AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface
)
285 ASSERT(m_pDirectDrawSurface
);
286 return m_pDirectDrawSurface
->AddAttachedSurface(lpDDSAttachedSurface
);
290 STDMETHODIMP
CAggDrawSurface::AddOverlayDirtyRect(LPRECT lpRect
)
292 ASSERT(m_pDirectDrawSurface
);
293 return m_pDirectDrawSurface
->AddOverlayDirtyRect(lpRect
);
297 STDMETHODIMP
CAggDrawSurface::Blt(LPRECT lpDestRect
,LPDIRECTDRAWSURFACE lpDDSrcSurface
,LPRECT lpSrcRect
,DWORD dwFlags
,LPDDBLTFX lpDDBltFx
)
299 ASSERT(m_pDirectDrawSurface
);
300 return m_pDirectDrawSurface
->Blt(lpDestRect
,lpDDSrcSurface
,lpSrcRect
,dwFlags
,lpDDBltFx
);
304 STDMETHODIMP
CAggDrawSurface::BltBatch(LPDDBLTBATCH lpDDBltBatch
,DWORD dwCount
,DWORD dwFlags
)
306 ASSERT(m_pDirectDrawSurface
);
307 return m_pDirectDrawSurface
->BltBatch(lpDDBltBatch
,dwCount
,dwFlags
);
311 STDMETHODIMP
CAggDrawSurface::BltFast(DWORD dwX
,DWORD dwY
,LPDIRECTDRAWSURFACE lpDDSrcSurface
,LPRECT lpSrcRect
,DWORD dwTrans
)
313 ASSERT(m_pDirectDrawSurface
);
314 return m_pDirectDrawSurface
->BltFast(dwX
,dwY
,lpDDSrcSurface
,lpSrcRect
,dwTrans
);
318 STDMETHODIMP
CAggDrawSurface::DeleteAttachedSurface(DWORD dwFlags
,LPDIRECTDRAWSURFACE lpDDSAttachedSurface
)
320 ASSERT(m_pDirectDrawSurface
);
321 return m_pDirectDrawSurface
->DeleteAttachedSurface(dwFlags
,lpDDSAttachedSurface
);
325 STDMETHODIMP
CAggDrawSurface::EnumAttachedSurfaces(LPVOID lpContext
,LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback
)
327 ASSERT(m_pDirectDrawSurface
);
328 return m_pDirectDrawSurface
->EnumAttachedSurfaces(lpContext
,lpEnumSurfacesCallback
);
332 STDMETHODIMP
CAggDrawSurface::EnumOverlayZOrders(DWORD dwFlags
,LPVOID lpContext
,LPDDENUMSURFACESCALLBACK lpfnCallback
)
334 ASSERT(m_pDirectDrawSurface
);
335 return m_pDirectDrawSurface
->EnumOverlayZOrders(dwFlags
,lpContext
,lpfnCallback
);
339 STDMETHODIMP
CAggDrawSurface::Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride
,DWORD dwFlags
)
341 ASSERT(m_pDirectDrawSurface
);
342 return m_pDirectDrawSurface
->Flip(lpDDSurfaceTargetOverride
,dwFlags
);
346 STDMETHODIMP
CAggDrawSurface::GetAttachedSurface(LPDDSCAPS lpDDSCaps
,LPDIRECTDRAWSURFACE
*lplpDDAttachedSurface
)
348 ASSERT(m_pDirectDrawSurface
);
349 return m_pDirectDrawSurface
->GetAttachedSurface(lpDDSCaps
,lplpDDAttachedSurface
);
353 STDMETHODIMP
CAggDrawSurface::GetBltStatus(DWORD dwFlags
)
355 ASSERT(m_pDirectDrawSurface
);
356 return m_pDirectDrawSurface
->GetBltStatus(dwFlags
);
360 STDMETHODIMP
CAggDrawSurface::GetCaps(LPDDSCAPS lpDDSCaps
)
362 ASSERT(m_pDirectDrawSurface
);
363 return m_pDirectDrawSurface
->GetCaps(lpDDSCaps
);
367 STDMETHODIMP
CAggDrawSurface::GetClipper(LPDIRECTDRAWCLIPPER
*lplpDDClipper
)
369 ASSERT(m_pDirectDrawSurface
);
370 return m_pDirectDrawSurface
->GetClipper(lplpDDClipper
);
374 STDMETHODIMP
CAggDrawSurface::GetColorKey(DWORD dwFlags
,LPDDCOLORKEY lpDDColorKey
)
376 ASSERT(m_pDirectDrawSurface
);
377 return m_pDirectDrawSurface
->GetColorKey(dwFlags
,lpDDColorKey
);
381 STDMETHODIMP
CAggDrawSurface::GetDC(HDC
*lphDC
)
383 ASSERT(m_pDirectDrawSurface
);
384 return m_pDirectDrawSurface
->GetDC(lphDC
);
388 STDMETHODIMP
CAggDrawSurface::GetFlipStatus(DWORD dwFlags
)
390 ASSERT(m_pDirectDrawSurface
);
391 return m_pDirectDrawSurface
->GetFlipStatus(dwFlags
);
395 STDMETHODIMP
CAggDrawSurface::GetOverlayPosition(LPLONG lpdwX
,LPLONG lpdwY
)
397 ASSERT(m_pDirectDrawSurface
);
398 return m_pDirectDrawSurface
->GetOverlayPosition(lpdwX
,lpdwY
);
402 STDMETHODIMP
CAggDrawSurface::GetPalette(LPDIRECTDRAWPALETTE
*lplpDDPalette
)
404 ASSERT(m_pDirectDrawSurface
);
405 return m_pDirectDrawSurface
->GetPalette(lplpDDPalette
);
409 STDMETHODIMP
CAggDrawSurface::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat
)
411 ASSERT(m_pDirectDrawSurface
);
412 return m_pDirectDrawSurface
->GetPixelFormat(lpDDPixelFormat
);
416 // A bit of a warning here: Our media samples in DirectShow aggregate on
417 // IDirectDraw and IDirectDrawSurface (ie are available through IMediaSample
418 // by QueryInterface). Unfortunately the underlying DirectDraw code cannot
419 // be aggregated so we have to use these classes. The snag is that when we
420 // call a different surface and pass in this interface as perhaps the source
421 // surface the call will fail because DirectDraw dereferences the pointer to
422 // get at its private data structures. Therefore we supply this workaround to give
423 // access to the real IDirectDraw surface. A filter can call GetSurfaceDesc
424 // and we will fill in the lpSurface pointer with the real underlying surface
426 STDMETHODIMP
CAggDrawSurface::GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc
)
428 ASSERT(m_pDirectDrawSurface
);
430 // First call down to the underlying DirectDraw
432 HRESULT hr
= m_pDirectDrawSurface
->GetSurfaceDesc(lpDDSurfaceDesc
);
437 // Store the real DirectDrawSurface interface
438 lpDDSurfaceDesc
->lpSurface
= m_pDirectDrawSurface
;
443 STDMETHODIMP
CAggDrawSurface::Initialize(LPDIRECTDRAW lpDD
,LPDDSURFACEDESC lpDDSurfaceDesc
)
445 ASSERT(m_pDirectDrawSurface
);
446 return m_pDirectDrawSurface
->Initialize(lpDD
,lpDDSurfaceDesc
);
450 STDMETHODIMP
CAggDrawSurface::IsLost()
452 ASSERT(m_pDirectDrawSurface
);
453 return m_pDirectDrawSurface
->IsLost();
457 STDMETHODIMP
CAggDrawSurface::Lock(LPRECT lpDestRect
,LPDDSURFACEDESC lpDDSurfaceDesc
,DWORD dwFlags
,HANDLE hEvent
)
459 ASSERT(m_pDirectDrawSurface
);
460 return m_pDirectDrawSurface
->Lock(lpDestRect
,lpDDSurfaceDesc
,dwFlags
,hEvent
);
464 STDMETHODIMP
CAggDrawSurface::ReleaseDC(HDC hDC
)
466 ASSERT(m_pDirectDrawSurface
);
467 return m_pDirectDrawSurface
->ReleaseDC(hDC
);
471 STDMETHODIMP
CAggDrawSurface::Restore()
473 ASSERT(m_pDirectDrawSurface
);
474 return m_pDirectDrawSurface
->Restore();
478 STDMETHODIMP
CAggDrawSurface::SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper
)
480 ASSERT(m_pDirectDrawSurface
);
481 return m_pDirectDrawSurface
->SetClipper(lpDDClipper
);
485 STDMETHODIMP
CAggDrawSurface::SetColorKey(DWORD dwFlags
,LPDDCOLORKEY lpDDColorKey
)
487 ASSERT(m_pDirectDrawSurface
);
488 return m_pDirectDrawSurface
->SetColorKey(dwFlags
,lpDDColorKey
);
492 STDMETHODIMP
CAggDrawSurface::SetOverlayPosition(LONG dwX
,LONG dwY
)
494 ASSERT(m_pDirectDrawSurface
);
495 return m_pDirectDrawSurface
->SetOverlayPosition(dwX
,dwY
);
499 STDMETHODIMP
CAggDrawSurface::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette
)
501 ASSERT(m_pDirectDrawSurface
);
502 return m_pDirectDrawSurface
->SetPalette(lpDDPalette
);
506 STDMETHODIMP
CAggDrawSurface::Unlock(LPVOID lpSurfaceData
)
508 ASSERT(m_pDirectDrawSurface
);
509 return m_pDirectDrawSurface
->Unlock(lpSurfaceData
);
513 STDMETHODIMP
CAggDrawSurface::UpdateOverlay(LPRECT lpSrcRect
,LPDIRECTDRAWSURFACE lpDDDestSurface
,LPRECT lpDestRect
,DWORD dwFlags
,LPDDOVERLAYFX lpDDOverlayFX
)
515 ASSERT(m_pDirectDrawSurface
);
516 return m_pDirectDrawSurface
->UpdateOverlay(lpSrcRect
,lpDDDestSurface
,lpDestRect
,dwFlags
,lpDDOverlayFX
);
520 STDMETHODIMP
CAggDrawSurface::UpdateOverlayDisplay(DWORD dwFlags
)
522 ASSERT(m_pDirectDrawSurface
);
523 return m_pDirectDrawSurface
->UpdateOverlayDisplay(dwFlags
);
527 STDMETHODIMP
CAggDrawSurface::UpdateOverlayZOrder(DWORD dwFlags
,LPDIRECTDRAWSURFACE lpDDSReference
)
529 ASSERT(m_pDirectDrawSurface
);
530 return m_pDirectDrawSurface
->UpdateOverlayZOrder(dwFlags
,lpDDSReference
);
534 // DirectShow must work on multiple platforms. In particular, it also runs on
535 // Windows NT 3.51 which does not have DirectDraw capabilities. The filters
536 // cannot therefore link statically to the DirectDraw library. To make their
537 // lives that little bit easier we provide this class that manages loading
538 // and unloading the library and creating the initial IDirectDraw interface
540 CLoadDirectDraw::CLoadDirectDraw() :
547 // Destructor forces unload
549 CLoadDirectDraw::~CLoadDirectDraw()
554 NOTE("Unloading library");
555 FreeLibrary(m_hDirectDraw
);
560 // We can't be sure that DirectDraw is always available so we can't statically
561 // link to the library. Therefore we load the library, get the function entry
562 // point addresses and call them to create the driver objects. We return S_OK
563 // if we manage to load DirectDraw correctly otherwise we return E_NOINTERFACE
564 // We initialise a DirectDraw instance by explicitely loading the library and
565 // calling GetProcAddress on the DirectDrawCreate entry point that it exports
567 // On a multi monitor system, we can get the DirectDraw object for any
568 // monitor (device) with the optional szDevice parameter
570 HRESULT
CLoadDirectDraw::LoadDirectDraw(LPSTR szDevice
)
572 PDRAWCREATE pDrawCreate
;
574 LPDIRECTDRAWENUMERATEEXA pDrawEnumEx
;
575 HRESULT hr
= NOERROR
;
577 NOTE("Entering DoLoadDirectDraw");
579 // Is DirectDraw already loaded
582 NOTE("Already loaded");
583 ASSERT(m_hDirectDraw
);
587 // Make sure the library is available
591 UINT ErrorMode
= SetErrorMode(SEM_NOOPENFILEERRORBOX
);
592 m_hDirectDraw
= LoadLibrary(TEXT("DDRAW.DLL"));
593 SetErrorMode(ErrorMode
);
595 if (m_hDirectDraw
== NULL
) {
596 DbgLog((LOG_ERROR
,1,TEXT("Can't load DDRAW.DLL")));
598 return E_NOINTERFACE
;
602 // Get the DLL address for the creator function
604 pDrawCreate
= (PDRAWCREATE
)GetProcAddress(m_hDirectDraw
,"DirectDrawCreate");
605 // force ANSI, we assume it
606 pDrawEnum
= (PDRAWENUM
)GetProcAddress(m_hDirectDraw
,"DirectDrawEnumerateA");
607 pDrawEnumEx
= (LPDIRECTDRAWENUMERATEEXA
)GetProcAddress(m_hDirectDraw
,
608 "DirectDrawEnumerateExA");
610 // We don't NEED DirectDrawEnumerateEx, that's just for multimon stuff
611 if (pDrawCreate
== NULL
|| pDrawEnum
== NULL
) {
612 DbgLog((LOG_ERROR
,1,TEXT("Can't get functions: Create=%x Enum=%x"),
613 pDrawCreate
, pDrawEnum
));
614 NOTE("No entry point");
616 return E_NOINTERFACE
;
619 DbgLog((LOG_TRACE
,3,TEXT("Creating DDraw for device %s"),
620 szDevice
? szDevice
: "<NULL>"));
622 // Create a DirectDraw display provider for this device, using the fancy
623 // multimon-aware version, if it exists
625 m_pDirectDraw
= DirectDrawCreateFromDeviceEx(szDevice
, pDrawCreate
,
628 m_pDirectDraw
= DirectDrawCreateFromDevice(szDevice
, pDrawCreate
,
631 if (m_pDirectDraw
== NULL
) {
632 DbgLog((LOG_ERROR
,1,TEXT("Can't create DDraw")));
635 return E_NOINTERFACE
;
641 // Called to release any DirectDraw provider we previously loaded. We may be
642 // called at any time especially when something goes horribly wrong and when
643 // we need to clean up before returning so we can't guarantee that all state
644 // variables are consistent so free only those really allocated allocated
645 // This should only be called once all reference counts have been released
647 void CLoadDirectDraw::ReleaseDirectDraw()
649 NOTE("Releasing DirectDraw driver");
651 // Release any DirectDraw provider interface
654 NOTE("Releasing instance");
655 m_pDirectDraw
->Release();
656 m_pDirectDraw
= NULL
;
662 // Return NOERROR (S_OK) if DirectDraw has been loaded by this object
664 HRESULT
CLoadDirectDraw::IsDirectDrawLoaded()
666 NOTE("Entering IsDirectDrawLoaded");
668 if (m_pDirectDraw
== NULL
) {
669 NOTE("DirectDraw not loaded");
676 // Return the IDirectDraw interface we look after
678 LPDIRECTDRAW
CLoadDirectDraw::GetDirectDraw()
680 NOTE("Entering GetDirectDraw");
682 if (m_pDirectDraw
== NULL
) {
683 NOTE("No DirectDraw");
687 NOTE("Returning DirectDraw");
688 m_pDirectDraw
->AddRef();
689 return m_pDirectDraw
;
693 // Are we running on Direct Draw version 1? We need to find out as
694 // we rely on specific bug fixes in DirectDraw 2 for fullscreen playback. To
695 // find out, we simply see if it supports IDirectDraw2. Only version 2 and
696 // higher support this.
698 BOOL
CLoadDirectDraw::IsDirectDrawVersion1()
701 if (m_pDirectDraw
== NULL
)
704 IDirectDraw2
*p
= NULL
;
705 HRESULT hr
= m_pDirectDraw
->QueryInterface(IID_IDirectDraw2
, (void **)&p
);
709 DbgLog((LOG_TRACE
,3,TEXT("Direct Draw Version 2 or greater")));
712 DbgLog((LOG_TRACE
,3,TEXT("Direct Draw Version 1")));