747 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			747 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								//------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// File: VideoCtl.cpp
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Desc: DirectShow base classes.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
							 | 
						||
| 
								 | 
							
								//------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <streams.h>
							 | 
						||
| 
								 | 
							
								#include "ddmm.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Load a string from the resource file string table. The buffer must be at
							 | 
						||
| 
								 | 
							
								// least STR_MAX_LENGTH bytes. The easiest way to use this is to declare a
							 | 
						||
| 
								 | 
							
								// buffer in the property page class and use it for all string loading. It
							 | 
						||
| 
								 | 
							
								// cannot be static as multiple property pages may be active simultaneously
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								LPCTSTR WINAPI StringFromResource(__out_ecount(STR_MAX_LENGTH) LPTSTR pBuffer, int iResourceID)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (LoadString(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH) == 0) {
							 | 
						||
| 
								 | 
							
								        return TEXT("");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return pBuffer;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef UNICODE
							 | 
						||
| 
								 | 
							
								LPCSTR WINAPI StringFromResource(__out_ecount(STR_MAX_LENGTH) LPSTR pBuffer, int iResourceID)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (LoadStringA(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH) == 0) {
							 | 
						||
| 
								 | 
							
								        return "";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return pBuffer;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Property pages typically are called through their OLE interfaces. These
							 | 
						||
| 
								 | 
							
								// use UNICODE strings regardless of how the binary is built. So when we
							 | 
						||
| 
								 | 
							
								// load strings from the resource file we sometimes want to convert them
							 | 
						||
| 
								 | 
							
								// to UNICODE. This method is passed the target UNICODE buffer and does a
							 | 
						||
| 
								 | 
							
								// convert after loading the string (if built UNICODE this is not needed)
							 | 
						||
| 
								 | 
							
								// On WinNT we can explicitly call LoadStringW which saves two conversions
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef UNICODE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								LPWSTR WINAPI WideStringFromResource(__out_ecount(STR_MAX_LENGTH) LPWSTR pBuffer, int iResourceID)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    *pBuffer = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (g_amPlatform == VER_PLATFORM_WIN32_NT) {
							 | 
						||
| 
								 | 
							
									LoadStringW(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									CHAR szBuffer[STR_MAX_LENGTH];
							 | 
						||
| 
								 | 
							
									DWORD dwStringLength = LoadString(g_hInst,iResourceID,szBuffer,STR_MAX_LENGTH);
							 | 
						||
| 
								 | 
							
									// if we loaded a string convert it to wide characters, ensuring
							 | 
						||
| 
								 | 
							
									// that we also null terminate the result.
							 | 
						||
| 
								 | 
							
									if (dwStringLength++) {
							 | 
						||
| 
								 | 
							
									    MultiByteToWideChar(CP_ACP,0,szBuffer,dwStringLength,pBuffer,STR_MAX_LENGTH);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return pBuffer;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Helper function to calculate the size of the dialog
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL WINAPI GetDialogSize(int iResourceID,
							 | 
						||
| 
								 | 
							
								                          DLGPROC pDlgProc,
							 | 
						||
| 
								 | 
							
								                          LPARAM lParam,
							 | 
						||
| 
								 | 
							
								                          __out SIZE *pResult)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    RECT rc;
							 | 
						||
| 
								 | 
							
								    HWND hwnd;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Create a temporary property page
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    hwnd = CreateDialogParam(g_hInst,
							 | 
						||
| 
								 | 
							
								                             MAKEINTRESOURCE(iResourceID),
							 | 
						||
| 
								 | 
							
								                             GetDesktopWindow(),
							 | 
						||
| 
								 | 
							
								                             pDlgProc,
							 | 
						||
| 
								 | 
							
								                             lParam);
							 | 
						||
| 
								 | 
							
								    if (hwnd == NULL) {
							 | 
						||
| 
								 | 
							
								        return FALSE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    GetWindowRect(hwnd, &rc);
							 | 
						||
| 
								 | 
							
								    pResult->cx = rc.right - rc.left;
							 | 
						||
| 
								 | 
							
								    pResult->cy = rc.bottom - rc.top;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DestroyWindow(hwnd);
							 | 
						||
| 
								 | 
							
								    return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Class that aggregates on the IDirectDraw interface. Although DirectDraw
							 | 
						||
| 
								 | 
							
								// has the ability in its interfaces to be aggregated they're not currently
							 | 
						||
| 
								 | 
							
								// implemented. This makes it difficult for various parts of Quartz that want
							 | 
						||
| 
								 | 
							
								// to aggregate these interfaces. In particular the video renderer passes out
							 | 
						||
| 
								 | 
							
								// media samples that expose IDirectDraw and IDirectDrawSurface. The filter
							 | 
						||
| 
								 | 
							
								// graph manager also exposes IDirectDraw as a plug in distributor. For these
							 | 
						||
| 
								 | 
							
								// objects we provide these aggregation classes that republish the interfaces
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Do we have this interface
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (riid == IID_IDirectDraw) {
							 | 
						||
| 
								 | 
							
								        return GetInterface((IDirectDraw *)this,ppv);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        return CUnknown::NonDelegatingQueryInterface(riid,ppv);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::Compact()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->Compact();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::CreateClipper(DWORD dwFlags, __deref_out LPDIRECTDRAWCLIPPER *lplpDDClipper, __inout_opt IUnknown *pUnkOuter)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->CreateClipper(dwFlags,lplpDDClipper,pUnkOuter);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::CreatePalette(DWORD dwFlags,
							 | 
						||
| 
								 | 
							
								                                           __in LPPALETTEENTRY lpColorTable,
							 | 
						||
| 
								 | 
							
								                                           __deref_out LPDIRECTDRAWPALETTE *lplpDDPalette,
							 | 
						||
| 
								 | 
							
								                                           __inout_opt IUnknown *pUnkOuter)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->CreatePalette(dwFlags,lpColorTable,lplpDDPalette,pUnkOuter);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::CreateSurface(__in LPDDSURFACEDESC lpDDSurfaceDesc,
							 | 
						||
| 
								 | 
							
								                                           __deref_out LPDIRECTDRAWSURFACE *lplpDDSurface,
							 | 
						||
| 
								 | 
							
								                                           __inout_opt IUnknown *pUnkOuter)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->CreateSurface(lpDDSurfaceDesc,lplpDDSurface,pUnkOuter);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::DuplicateSurface(__in LPDIRECTDRAWSURFACE lpDDSurface,
							 | 
						||
| 
								 | 
							
								                                              __deref_out LPDIRECTDRAWSURFACE *lplpDupDDSurface)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->DuplicateSurface(lpDDSurface,lplpDupDDSurface);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::EnumDisplayModes(DWORD dwSurfaceDescCount,
							 | 
						||
| 
								 | 
							
								                                              __in LPDDSURFACEDESC lplpDDSurfaceDescList,
							 | 
						||
| 
								 | 
							
								                                              __in LPVOID lpContext,
							 | 
						||
| 
								 | 
							
								                                              __in LPDDENUMMODESCALLBACK lpEnumCallback)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->EnumDisplayModes(dwSurfaceDescCount,lplpDDSurfaceDescList,lpContext,lpEnumCallback);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::EnumSurfaces(DWORD dwFlags,
							 | 
						||
| 
								 | 
							
								                                          __in LPDDSURFACEDESC lpDDSD,
							 | 
						||
| 
								 | 
							
								                                          __in LPVOID lpContext,
							 | 
						||
| 
								 | 
							
								                                          __in LPDDENUMSURFACESCALLBACK lpEnumCallback)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->EnumSurfaces(dwFlags,lpDDSD,lpContext,lpEnumCallback);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::FlipToGDISurface()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->FlipToGDISurface();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::GetCaps(__out LPDDCAPS lpDDDriverCaps,__out LPDDCAPS lpDDHELCaps)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->GetCaps(lpDDDriverCaps,lpDDHELCaps);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::GetDisplayMode(__out LPDDSURFACEDESC lpDDSurfaceDesc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->GetDisplayMode(lpDDSurfaceDesc);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::GetFourCCCodes(__inout LPDWORD lpNumCodes,__out_ecount(*lpNumCodes) LPDWORD lpCodes)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->GetFourCCCodes(lpNumCodes,lpCodes);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::GetGDISurface(__deref_out LPDIRECTDRAWSURFACE *lplpGDIDDSurface)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->GetGDISurface(lplpGDIDDSurface);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::GetMonitorFrequency(__out LPDWORD lpdwFrequency)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->GetMonitorFrequency(lpdwFrequency);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::GetScanLine(__out LPDWORD lpdwScanLine)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->GetScanLine(lpdwScanLine);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::GetVerticalBlankStatus(__out LPBOOL lpblsInVB)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->GetVerticalBlankStatus(lpblsInVB);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::Initialize(__in GUID *lpGUID)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->Initialize(lpGUID);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::RestoreDisplayMode()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->RestoreDisplayMode();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::SetCooperativeLevel(HWND hWnd,DWORD dwFlags)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->SetCooperativeLevel(hWnd,dwFlags);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::SetDisplayMode(DWORD dwWidth,DWORD dwHeight,DWORD dwBpp)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->SetDisplayMode(dwWidth,dwHeight,dwBpp);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDirectDraw::WaitForVerticalBlank(DWORD dwFlags,HANDLE hEvent)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDraw);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw->WaitForVerticalBlank(dwFlags,hEvent);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Class that aggregates an IDirectDrawSurface interface. Although DirectDraw
							 | 
						||
| 
								 | 
							
								// has the ability in its interfaces to be aggregated they're not currently
							 | 
						||
| 
								 | 
							
								// implemented. This makes it difficult for various parts of Quartz that want
							 | 
						||
| 
								 | 
							
								// to aggregate these interfaces. In particular the video renderer passes out
							 | 
						||
| 
								 | 
							
								// media samples that expose IDirectDraw and IDirectDrawSurface. The filter
							 | 
						||
| 
								 | 
							
								// graph manager also exposes IDirectDraw as a plug in distributor. For these
							 | 
						||
| 
								 | 
							
								// objects we provide these aggregation classes that republish the interfaces
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Do we have this interface
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (riid == IID_IDirectDrawSurface) {
							 | 
						||
| 
								 | 
							
								        return GetInterface((IDirectDrawSurface *)this,ppv);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        return CUnknown::NonDelegatingQueryInterface(riid,ppv);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::AddAttachedSurface(__in LPDIRECTDRAWSURFACE lpDDSAttachedSurface)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->AddAttachedSurface(lpDDSAttachedSurface);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::AddOverlayDirtyRect(__in LPRECT lpRect)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->AddOverlayDirtyRect(lpRect);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::Blt(__in LPRECT lpDestRect,
							 | 
						||
| 
								 | 
							
								                                  __in LPDIRECTDRAWSURFACE lpDDSrcSurface,
							 | 
						||
| 
								 | 
							
								                                  __in LPRECT lpSrcRect,
							 | 
						||
| 
								 | 
							
								                                  DWORD dwFlags,
							 | 
						||
| 
								 | 
							
								                                  __in LPDDBLTFX lpDDBltFx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->Blt(lpDestRect,lpDDSrcSurface,lpSrcRect,dwFlags,lpDDBltFx);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::BltBatch(__in_ecount(dwCount) LPDDBLTBATCH lpDDBltBatch,DWORD dwCount,DWORD dwFlags)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->BltBatch(lpDDBltBatch,dwCount,dwFlags);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::BltFast(DWORD dwX,DWORD dwY,
							 | 
						||
| 
								 | 
							
								                                      __in LPDIRECTDRAWSURFACE lpDDSrcSurface,
							 | 
						||
| 
								 | 
							
								                                      __in LPRECT lpSrcRect,
							 | 
						||
| 
								 | 
							
								                                      DWORD dwTrans)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->BltFast(dwX,dwY,lpDDSrcSurface,lpSrcRect,dwTrans);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::DeleteAttachedSurface(DWORD dwFlags,
							 | 
						||
| 
								 | 
							
								                                                    __in LPDIRECTDRAWSURFACE lpDDSAttachedSurface)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->DeleteAttachedSurface(dwFlags,lpDDSAttachedSurface);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::EnumAttachedSurfaces(__in LPVOID lpContext,
							 | 
						||
| 
								 | 
							
								                                                   __in LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->EnumAttachedSurfaces(lpContext,lpEnumSurfacesCallback);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::EnumOverlayZOrders(DWORD dwFlags,
							 | 
						||
| 
								 | 
							
								                                                 __in LPVOID lpContext,
							 | 
						||
| 
								 | 
							
								                                                 __in LPDDENUMSURFACESCALLBACK lpfnCallback)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->EnumOverlayZOrders(dwFlags,lpContext,lpfnCallback);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::Flip(__in LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride,DWORD dwFlags)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->Flip(lpDDSurfaceTargetOverride,dwFlags);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::GetAttachedSurface(__in LPDDSCAPS lpDDSCaps,
							 | 
						||
| 
								 | 
							
								                                                 __deref_out LPDIRECTDRAWSURFACE *lplpDDAttachedSurface)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->GetAttachedSurface(lpDDSCaps,lplpDDAttachedSurface);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::GetBltStatus(DWORD dwFlags)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->GetBltStatus(dwFlags);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::GetCaps(__out LPDDSCAPS lpDDSCaps)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->GetCaps(lpDDSCaps);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::GetClipper(__deref_out LPDIRECTDRAWCLIPPER *lplpDDClipper)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->GetClipper(lplpDDClipper);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::GetColorKey(DWORD dwFlags,__out LPDDCOLORKEY lpDDColorKey)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->GetColorKey(dwFlags,lpDDColorKey);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::GetDC(__out HDC *lphDC)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->GetDC(lphDC);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::GetFlipStatus(DWORD dwFlags)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->GetFlipStatus(dwFlags);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::GetOverlayPosition(__out LPLONG lpdwX,__out LPLONG lpdwY)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->GetOverlayPosition(lpdwX,lpdwY);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::GetPalette(__deref_out LPDIRECTDRAWPALETTE *lplpDDPalette)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->GetPalette(lplpDDPalette);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::GetPixelFormat(__out LPDDPIXELFORMAT lpDDPixelFormat)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->GetPixelFormat(lpDDPixelFormat);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// A bit of a warning here: Our media samples in DirectShow aggregate on
							 | 
						||
| 
								 | 
							
								// IDirectDraw and IDirectDrawSurface (ie are available through IMediaSample
							 | 
						||
| 
								 | 
							
								// by QueryInterface). Unfortunately the underlying DirectDraw code cannot
							 | 
						||
| 
								 | 
							
								// be aggregated so we have to use these classes. The snag is that when we
							 | 
						||
| 
								 | 
							
								// call a different surface and pass in this interface as perhaps the source
							 | 
						||
| 
								 | 
							
								// surface the call will fail because DirectDraw dereferences the pointer to
							 | 
						||
| 
								 | 
							
								// get at its private data structures. Therefore we supply this workaround to give
							 | 
						||
| 
								 | 
							
								// access to the real IDirectDraw surface. A filter can call GetSurfaceDesc
							 | 
						||
| 
								 | 
							
								// and we will fill in the lpSurface pointer with the real underlying surface
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::GetSurfaceDesc(__out LPDDSURFACEDESC lpDDSurfaceDesc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // First call down to the underlying DirectDraw
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    HRESULT hr = m_pDirectDrawSurface->GetSurfaceDesc(lpDDSurfaceDesc);
							 | 
						||
| 
								 | 
							
								    if (FAILED(hr)) {
							 | 
						||
| 
								 | 
							
								        return hr;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Store the real DirectDrawSurface interface
							 | 
						||
| 
								 | 
							
								    lpDDSurfaceDesc->lpSurface = m_pDirectDrawSurface;
							 | 
						||
| 
								 | 
							
								    return hr;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::Initialize(__in LPDIRECTDRAW lpDD,__in LPDDSURFACEDESC lpDDSurfaceDesc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->Initialize(lpDD,lpDDSurfaceDesc);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::IsLost()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->IsLost();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::Lock(__in LPRECT lpDestRect,
							 | 
						||
| 
								 | 
							
								                                   __inout LPDDSURFACEDESC lpDDSurfaceDesc,
							 | 
						||
| 
								 | 
							
								                                   DWORD dwFlags,
							 | 
						||
| 
								 | 
							
								                                   HANDLE hEvent)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->Lock(lpDestRect,lpDDSurfaceDesc,dwFlags,hEvent);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::ReleaseDC(HDC hDC)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->ReleaseDC(hDC);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::Restore()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->Restore();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::SetClipper(__in LPDIRECTDRAWCLIPPER lpDDClipper)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->SetClipper(lpDDClipper);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::SetColorKey(DWORD dwFlags,__in LPDDCOLORKEY lpDDColorKey)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->SetColorKey(dwFlags,lpDDColorKey);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::SetOverlayPosition(LONG dwX,LONG dwY)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->SetOverlayPosition(dwX,dwY);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::SetPalette(__in LPDIRECTDRAWPALETTE lpDDPalette)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->SetPalette(lpDDPalette);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::Unlock(__in LPVOID lpSurfaceData)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->Unlock(lpSurfaceData);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::UpdateOverlay(__in LPRECT lpSrcRect,
							 | 
						||
| 
								 | 
							
								                                            __in LPDIRECTDRAWSURFACE lpDDDestSurface,
							 | 
						||
| 
								 | 
							
								                                            __in LPRECT lpDestRect,
							 | 
						||
| 
								 | 
							
								                                            DWORD dwFlags,
							 | 
						||
| 
								 | 
							
								                                            __in LPDDOVERLAYFX lpDDOverlayFX)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->UpdateOverlay(lpSrcRect,lpDDDestSurface,lpDestRect,dwFlags,lpDDOverlayFX);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::UpdateOverlayDisplay(DWORD dwFlags)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->UpdateOverlayDisplay(dwFlags);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP CAggDrawSurface::UpdateOverlayZOrder(DWORD dwFlags,__in LPDIRECTDRAWSURFACE lpDDSReference)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ASSERT(m_pDirectDrawSurface);
							 | 
						||
| 
								 | 
							
								    return m_pDirectDrawSurface->UpdateOverlayZOrder(dwFlags,lpDDSReference);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// DirectShow must work on multiple platforms.  In particular, it also runs on
							 | 
						||
| 
								 | 
							
								// Windows NT 3.51 which does not have DirectDraw capabilities. The filters
							 | 
						||
| 
								 | 
							
								// cannot therefore link statically to the DirectDraw library. To make their
							 | 
						||
| 
								 | 
							
								// lives that little bit easier we provide this class that manages loading
							 | 
						||
| 
								 | 
							
								// and unloading the library and creating the initial IDirectDraw interface
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								CLoadDirectDraw::CLoadDirectDraw() :
							 | 
						||
| 
								 | 
							
								    m_pDirectDraw(NULL),
							 | 
						||
| 
								 | 
							
								    m_hDirectDraw(NULL)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Destructor forces unload
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								CLoadDirectDraw::~CLoadDirectDraw()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ReleaseDirectDraw();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (m_hDirectDraw) {
							 | 
						||
| 
								 | 
							
								        NOTE("Unloading library");
							 | 
						||
| 
								 | 
							
								        FreeLibrary(m_hDirectDraw);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// We can't be sure that DirectDraw is always available so we can't statically
							 | 
						||
| 
								 | 
							
								// link to the library. Therefore we load the library, get the function entry
							 | 
						||
| 
								 | 
							
								// point addresses and call them to create the driver objects. We return S_OK
							 | 
						||
| 
								 | 
							
								// if we manage to load DirectDraw correctly otherwise we return E_NOINTERFACE
							 | 
						||
| 
								 | 
							
								// We initialise a DirectDraw instance by explicitely loading the library and
							 | 
						||
| 
								 | 
							
								// calling GetProcAddress on the DirectDrawCreate entry point that it exports
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// On a multi monitor system, we can get the DirectDraw object for any
							 | 
						||
| 
								 | 
							
								// monitor (device) with the optional szDevice parameter
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HRESULT CLoadDirectDraw::LoadDirectDraw(__in LPSTR szDevice)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    PDRAWCREATE pDrawCreate;
							 | 
						||
| 
								 | 
							
								    PDRAWENUM pDrawEnum;
							 | 
						||
| 
								 | 
							
								    LPDIRECTDRAWENUMERATEEXA pDrawEnumEx;
							 | 
						||
| 
								 | 
							
								    HRESULT hr = NOERROR;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    NOTE("Entering DoLoadDirectDraw");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Is DirectDraw already loaded
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (m_pDirectDraw) {
							 | 
						||
| 
								 | 
							
								        NOTE("Already loaded");
							 | 
						||
| 
								 | 
							
								        ASSERT(m_hDirectDraw);
							 | 
						||
| 
								 | 
							
								        return NOERROR;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Make sure the library is available
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(!m_hDirectDraw)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        UINT ErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX);
							 | 
						||
| 
								 | 
							
								        m_hDirectDraw = LoadLibrary(TEXT("DDRAW.DLL"));
							 | 
						||
| 
								 | 
							
								        SetErrorMode(ErrorMode);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (m_hDirectDraw == NULL) {
							 | 
						||
| 
								 | 
							
								            DbgLog((LOG_ERROR,1,TEXT("Can't load DDRAW.DLL")));
							 | 
						||
| 
								 | 
							
								            NOTE("No library");
							 | 
						||
| 
								 | 
							
								            return E_NOINTERFACE;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Get the DLL address for the creator function
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    pDrawCreate = (PDRAWCREATE)GetProcAddress(m_hDirectDraw,"DirectDrawCreate");
							 | 
						||
| 
								 | 
							
								    // force ANSI, we assume it
							 | 
						||
| 
								 | 
							
								    pDrawEnum = (PDRAWENUM)GetProcAddress(m_hDirectDraw,"DirectDrawEnumerateA");
							 | 
						||
| 
								 | 
							
								    pDrawEnumEx = (LPDIRECTDRAWENUMERATEEXA)GetProcAddress(m_hDirectDraw,
							 | 
						||
| 
								 | 
							
														"DirectDrawEnumerateExA");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // We don't NEED DirectDrawEnumerateEx, that's just for multimon stuff
							 | 
						||
| 
								 | 
							
								    if (pDrawCreate == NULL || pDrawEnum == NULL) {
							 | 
						||
| 
								 | 
							
								        DbgLog((LOG_ERROR,1,TEXT("Can't get functions: Create=%x Enum=%x"),
							 | 
						||
| 
								 | 
							
											pDrawCreate, pDrawEnum));
							 | 
						||
| 
								 | 
							
								        NOTE("No entry point");
							 | 
						||
| 
								 | 
							
								        ReleaseDirectDraw();
							 | 
						||
| 
								 | 
							
								        return E_NOINTERFACE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DbgLog((LOG_TRACE,3,TEXT("Creating DDraw for device %s"),
							 | 
						||
| 
								 | 
							
													szDevice ? szDevice : "<NULL>"));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Create a DirectDraw display provider for this device, using the fancy
							 | 
						||
| 
								 | 
							
								    // multimon-aware version, if it exists
							 | 
						||
| 
								 | 
							
								    if (pDrawEnumEx)
							 | 
						||
| 
								 | 
							
								        m_pDirectDraw = DirectDrawCreateFromDeviceEx(szDevice, pDrawCreate,
							 | 
						||
| 
								 | 
							
																pDrawEnumEx);
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								        m_pDirectDraw = DirectDrawCreateFromDevice(szDevice, pDrawCreate,
							 | 
						||
| 
								 | 
							
																pDrawEnum);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (m_pDirectDraw == NULL) {
							 | 
						||
| 
								 | 
							
								            DbgLog((LOG_ERROR,1,TEXT("Can't create DDraw")));
							 | 
						||
| 
								 | 
							
								            NOTE("No instance");
							 | 
						||
| 
								 | 
							
								            ReleaseDirectDraw();
							 | 
						||
| 
								 | 
							
								            return E_NOINTERFACE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return NOERROR;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Called to release any DirectDraw provider we previously loaded. We may be
							 | 
						||
| 
								 | 
							
								// called at any time especially when something goes horribly wrong and when
							 | 
						||
| 
								 | 
							
								// we need to clean up before returning so we can't guarantee that all state
							 | 
						||
| 
								 | 
							
								// variables are consistent so free only those really allocated allocated
							 | 
						||
| 
								 | 
							
								// This should only be called once all reference counts have been released
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void CLoadDirectDraw::ReleaseDirectDraw()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    NOTE("Releasing DirectDraw driver");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Release any DirectDraw provider interface
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (m_pDirectDraw) {
							 | 
						||
| 
								 | 
							
								        NOTE("Releasing instance");
							 | 
						||
| 
								 | 
							
								        m_pDirectDraw->Release();
							 | 
						||
| 
								 | 
							
								        m_pDirectDraw = NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Return NOERROR (S_OK) if DirectDraw has been loaded by this object
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HRESULT CLoadDirectDraw::IsDirectDrawLoaded()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    NOTE("Entering IsDirectDrawLoaded");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (m_pDirectDraw == NULL) {
							 | 
						||
| 
								 | 
							
								        NOTE("DirectDraw not loaded");
							 | 
						||
| 
								 | 
							
								        return S_FALSE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return NOERROR;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Return the IDirectDraw interface we look after
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								LPDIRECTDRAW CLoadDirectDraw::GetDirectDraw()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    NOTE("Entering GetDirectDraw");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (m_pDirectDraw == NULL) {
							 | 
						||
| 
								 | 
							
								        NOTE("No DirectDraw");
							 | 
						||
| 
								 | 
							
								        return NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    NOTE("Returning DirectDraw");
							 | 
						||
| 
								 | 
							
								    m_pDirectDraw->AddRef();
							 | 
						||
| 
								 | 
							
								    return m_pDirectDraw;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Are we running on Direct Draw version 1?  We need to find out as
							 | 
						||
| 
								 | 
							
								// we rely on specific bug fixes in DirectDraw 2 for fullscreen playback. To
							 | 
						||
| 
								 | 
							
								// find out, we simply see if it supports IDirectDraw2.  Only version 2 and
							 | 
						||
| 
								 | 
							
								// higher support this.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOL CLoadDirectDraw::IsDirectDrawVersion1()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (m_pDirectDraw == NULL)
							 | 
						||
| 
								 | 
							
									return FALSE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    IDirectDraw2 *p = NULL;
							 | 
						||
| 
								 | 
							
								    HRESULT hr = m_pDirectDraw->QueryInterface(IID_IDirectDraw2, (void **)&p);
							 | 
						||
| 
								 | 
							
								    if (p)
							 | 
						||
| 
								 | 
							
									p->Release();
							 | 
						||
| 
								 | 
							
								    if (hr == NOERROR) {
							 | 
						||
| 
								 | 
							
								        DbgLog((LOG_TRACE,3,TEXT("Direct Draw Version 2 or greater")));
							 | 
						||
| 
								 | 
							
									return FALSE;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        DbgLog((LOG_TRACE,3,TEXT("Direct Draw Version 1")));
							 | 
						||
| 
								 | 
							
									return TRUE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |