home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / mac / SiteBldr / AMOVIE / SDK / _SETUP / COMMON.Z / videoctl.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-11  |  22.4 KB  |  748 lines

  1. //==========================================================================;
  2. //
  3. //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. //  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. //  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. //  PURPOSE.
  7. //
  8. //  Copyright (c) 1992 - 1996  Microsoft Corporation.  All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------;
  11.  
  12. #include <streams.h>
  13.  
  14. // Load a string from the resource file string table. The buffer must be at
  15. // least STR_MAX_LENGTH bytes. The easiest way to use this is to declare a
  16. // buffer in the property page class and use it for all string loading. It
  17. // cannot be static as multiple property pages may be active simultaneously
  18.  
  19. TCHAR *StringFromResource(TCHAR *pBuffer, int iResourceID)
  20. {
  21.     if (LoadString(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH) == 0) {
  22.         return TEXT("");
  23.     }
  24.     return pBuffer;
  25. }
  26.  
  27.  
  28. // Property pages typically are called through their OLE interfaces. These
  29. // use UNICODE strings regardless of how the binary is built. So when we
  30. // load strings from the resource file we sometimes want to convert them
  31. // to UNICODE. This method is passed the target UNICODE buffer and does a
  32. // convert after loading the string (if built UNICODE this is not needed)
  33. // On WinNT we can explicitly call LoadStringW which saves two conversions
  34.  
  35. #ifndef UNICODE
  36.  
  37. WCHAR *WideStringFromResource(WCHAR *pBuffer, int iResourceID)
  38. {
  39.     *pBuffer = 0;
  40.  
  41.     if (g_amPlatform == VER_PLATFORM_WIN32_NT) {
  42.     LoadStringW(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH);
  43.     } else {
  44.  
  45.     CHAR szBuffer[STR_MAX_LENGTH];
  46.     DWORD dwStringLength = LoadString(g_hInst,iResourceID,szBuffer,STR_MAX_LENGTH);
  47.     // if we loaded a string convert it to wide characters, ensuring
  48.     // that we also null terminate the result.
  49.     if (dwStringLength++) {
  50.         MultiByteToWideChar(CP_ACP,0,szBuffer,dwStringLength,pBuffer,STR_MAX_LENGTH);
  51.     }
  52.     }
  53.     return pBuffer;
  54. }
  55.  
  56. #endif
  57.  
  58.  
  59. // Helper function to calculate the size of the dialog
  60.  
  61. BOOL GetDialogSize(int iResourceID,
  62.                    DLGPROC pDlgProc,
  63.                    LPARAM lParam,
  64.                    SIZE *pResult)
  65. {
  66.     RECT rc;
  67.     HWND hwnd;
  68.  
  69.     // Create a temporary property page
  70.  
  71.     hwnd = CreateDialogParam(g_hInst,
  72.                              MAKEINTRESOURCE(iResourceID),
  73.                              GetDesktopWindow(),
  74.                              pDlgProc,
  75.                              lParam);
  76.     if (hwnd == NULL) {
  77.         return FALSE;
  78.     }
  79.  
  80.     GetWindowRect(hwnd, &rc);
  81.     pResult->cx = rc.right - rc.left;
  82.     pResult->cy = rc.bottom - rc.top;
  83.  
  84.     DestroyWindow(hwnd);
  85.     return TRUE;
  86. }
  87.  
  88.  
  89. // Class that aggregates on the IDirectDraw interface. Although DirectDraw
  90. // has the ability in its interfaces to be aggregated they're not currently
  91. // implemented. This makes it difficult for various parts of Quartz that want
  92. // to aggregate these interfaces. In particular the video renderer passes out
  93. // media samples that expose IDirectDraw and IDirectDrawSurface. The filter
  94. // graph manager also exposes IDirectDraw as a plug in distributor. For these
  95. // objects we provide these aggregation classes that republish the interfaces
  96.  
  97. STDMETHODIMP CAggDirectDraw::NonDelegatingQueryInterface(REFIID riid, void **ppv)
  98. {
  99.     ASSERT(m_pDirectDraw);
  100.     CheckPointer(ppv,E_POINTER);
  101.  
  102.     // Do we have this interface
  103.  
  104.     if (riid == IID_IDirectDraw) {
  105.         return GetInterface((IDirectDraw *)this,ppv);
  106.     } else {
  107.         return CUnknown::NonDelegatingQueryInterface(riid,ppv);
  108.     }
  109. }
  110.  
  111.  
  112. STDMETHODIMP CAggDirectDraw::Compact()
  113. {
  114.     ASSERT(m_pDirectDraw);
  115.     return m_pDirectDraw->Compact();
  116. }
  117.  
  118.  
  119. STDMETHODIMP CAggDirectDraw::CreateClipper(DWORD dwFlags,LPDIRECTDRAWCLIPPER *lplpDDClipper,IUnknown *pUnkOuter)
  120. {
  121.     ASSERT(m_pDirectDraw);
  122.     return m_pDirectDraw->CreateClipper(dwFlags,lplpDDClipper,pUnkOuter);
  123. }
  124.  
  125.  
  126. STDMETHODIMP CAggDirectDraw::CreatePalette(DWORD dwFlags,LPPALETTEENTRY lpColorTable,LPDIRECTDRAWPALETTE *lplpDDPalette,IUnknown *pUnkOuter)
  127. {
  128.     ASSERT(m_pDirectDraw);
  129.     return m_pDirectDraw->CreatePalette(dwFlags,lpColorTable,lplpDDPalette,pUnkOuter);
  130. }
  131.  
  132.  
  133. STDMETHODIMP CAggDirectDraw::CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc,LPDIRECTDRAWSURFACE *lplpDDSurface,IUnknown *pUnkOuter)
  134. {
  135.     ASSERT(m_pDirectDraw);
  136.     return m_pDirectDraw->CreateSurface(lpDDSurfaceDesc,lplpDDSurface,pUnkOuter);
  137. }
  138.  
  139.  
  140. STDMETHODIMP CAggDirectDraw::DuplicateSurface(LPDIRECTDRAWSURFACE lpDDSurface,LPDIRECTDRAWSURFACE *lplpDupDDSurface)
  141. {
  142.     ASSERT(m_pDirectDraw);
  143.     return m_pDirectDraw->DuplicateSurface(lpDDSurface,lplpDupDDSurface);
  144. }
  145.  
  146.  
  147. STDMETHODIMP CAggDirectDraw::EnumDisplayModes(DWORD dwSurfaceDescCount,LPDDSURFACEDESC lplpDDSurfaceDescList,LPVOID lpContext,LPDDENUMMODESCALLBACK lpEnumCallback)
  148. {
  149.     ASSERT(m_pDirectDraw);
  150.     return m_pDirectDraw->EnumDisplayModes(dwSurfaceDescCount,lplpDDSurfaceDescList,lpContext,lpEnumCallback);
  151. }
  152.  
  153.  
  154. STDMETHODIMP CAggDirectDraw::EnumSurfaces(DWORD dwFlags,LPDDSURFACEDESC lpDDSD,LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpEnumCallback)
  155. {
  156.     ASSERT(m_pDirectDraw);
  157.     return m_pDirectDraw->EnumSurfaces(dwFlags,lpDDSD,lpContext,lpEnumCallback);
  158. }
  159.  
  160.  
  161. STDMETHODIMP CAggDirectDraw::FlipToGDISurface()
  162. {
  163.     ASSERT(m_pDirectDraw);
  164.     return m_pDirectDraw->FlipToGDISurface();
  165. }
  166.  
  167.  
  168. STDMETHODIMP CAggDirectDraw::GetCaps(LPDDCAPS lpDDDriverCaps,LPDDCAPS lpDDHELCaps)
  169. {
  170.     ASSERT(m_pDirectDraw);
  171.     return m_pDirectDraw->GetCaps(lpDDDriverCaps,lpDDHELCaps);
  172. }
  173.  
  174.  
  175. STDMETHODIMP CAggDirectDraw::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc)
  176. {
  177.     ASSERT(m_pDirectDraw);
  178.     return m_pDirectDraw->GetDisplayMode(lpDDSurfaceDesc);
  179. }
  180.  
  181.  
  182. STDMETHODIMP CAggDirectDraw::GetFourCCCodes(LPDWORD lpNumCodes,LPDWORD lpCodes)
  183. {
  184.     ASSERT(m_pDirectDraw);
  185.     return m_pDirectDraw->GetFourCCCodes(lpNumCodes,lpCodes);
  186. }
  187.  
  188.  
  189. STDMETHODIMP CAggDirectDraw::GetGDISurface(LPDIRECTDRAWSURFACE *lplpGDIDDSurface)
  190. {
  191.     ASSERT(m_pDirectDraw);
  192.     return m_pDirectDraw->GetGDISurface(lplpGDIDDSurface);
  193. }
  194.  
  195.  
  196. STDMETHODIMP CAggDirectDraw::GetMonitorFrequency(LPDWORD lpdwFrequency)
  197. {
  198.     ASSERT(m_pDirectDraw);
  199.     return m_pDirectDraw->GetMonitorFrequency(lpdwFrequency);
  200. }
  201.  
  202.  
  203. STDMETHODIMP CAggDirectDraw::GetScanLine(LPDWORD lpdwScanLine)
  204. {
  205.     ASSERT(m_pDirectDraw);
  206.     return m_pDirectDraw->GetScanLine(lpdwScanLine);
  207. }
  208.  
  209.  
  210. STDMETHODIMP CAggDirectDraw::GetVerticalBlankStatus(LPBOOL lpblsInVB)
  211. {
  212.     ASSERT(m_pDirectDraw);
  213.     return m_pDirectDraw->GetVerticalBlankStatus(lpblsInVB);
  214. }
  215.  
  216.  
  217. STDMETHODIMP CAggDirectDraw::Initialize(GUID *lpGUID)
  218. {
  219.     ASSERT(m_pDirectDraw);
  220.     return m_pDirectDraw->Initialize(lpGUID);
  221. }
  222.  
  223.  
  224. STDMETHODIMP CAggDirectDraw::RestoreDisplayMode()
  225. {
  226.     ASSERT(m_pDirectDraw);
  227.     return m_pDirectDraw->RestoreDisplayMode();
  228. }
  229.  
  230.  
  231. STDMETHODIMP CAggDirectDraw::SetCooperativeLevel(HWND hWnd,DWORD dwFlags)
  232. {
  233.     ASSERT(m_pDirectDraw);
  234.     return m_pDirectDraw->SetCooperativeLevel(hWnd,dwFlags);
  235. }
  236.  
  237.  
  238. STDMETHODIMP CAggDirectDraw::SetDisplayMode(DWORD dwWidth,DWORD dwHeight,DWORD dwBpp)
  239. {
  240.     ASSERT(m_pDirectDraw);
  241.     return m_pDirectDraw->SetDisplayMode(dwWidth,dwHeight,dwBpp);
  242. }
  243.  
  244.  
  245. STDMETHODIMP CAggDirectDraw::WaitForVerticalBlank(DWORD dwFlags,HANDLE hEvent)
  246. {
  247.     ASSERT(m_pDirectDraw);
  248.     return m_pDirectDraw->WaitForVerticalBlank(dwFlags,hEvent);
  249. }
  250.  
  251.  
  252. // Class that aggregates an IDirectDrawSurface interface. Although DirectDraw
  253. // has the ability in its interfaces to be aggregated they're not currently
  254. // implemented. This makes it difficult for various parts of Quartz that want
  255. // to aggregate these interfaces. In particular the video renderer passes out
  256. // media samples that expose IDirectDraw and IDirectDrawSurface. The filter
  257. // graph manager also exposes IDirectDraw as a plug in distributor. For these
  258. // objects we provide these aggregation classes that republish the interfaces
  259.  
  260. STDMETHODIMP CAggDrawSurface::NonDelegatingQueryInterface(REFIID riid, void **ppv)
  261. {
  262.     ASSERT(m_pDirectDrawSurface);
  263.     CheckPointer(ppv,E_POINTER);
  264.  
  265.     // Do we have this interface
  266.  
  267.     if (riid == IID_IDirectDrawSurface) {
  268.         return GetInterface((IDirectDrawSurface *)this,ppv);
  269.     } else {
  270.         return CUnknown::NonDelegatingQueryInterface(riid,ppv);
  271.     }
  272. }
  273.  
  274.  
  275. STDMETHODIMP CAggDrawSurface::AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface)
  276. {
  277.     ASSERT(m_pDirectDrawSurface);
  278.     return m_pDirectDrawSurface->AddAttachedSurface(lpDDSAttachedSurface);
  279. }
  280.  
  281.  
  282. STDMETHODIMP CAggDrawSurface::AddOverlayDirtyRect(LPRECT lpRect)
  283. {
  284.     ASSERT(m_pDirectDrawSurface);
  285.     return m_pDirectDrawSurface->AddOverlayDirtyRect(lpRect);
  286. }
  287.  
  288.  
  289. STDMETHODIMP CAggDrawSurface::Blt(LPRECT lpDestRect,LPDIRECTDRAWSURFACE lpDDSrcSurface,LPRECT lpSrcRect,DWORD dwFlags,LPDDBLTFX lpDDBltFx)
  290. {
  291.     ASSERT(m_pDirectDrawSurface);
  292.     return m_pDirectDrawSurface->Blt(lpDestRect,lpDDSrcSurface,lpSrcRect,dwFlags,lpDDBltFx);
  293. }
  294.  
  295.  
  296. STDMETHODIMP CAggDrawSurface::BltBatch(LPDDBLTBATCH lpDDBltBatch,DWORD dwCount,DWORD dwFlags)
  297. {
  298.     ASSERT(m_pDirectDrawSurface);
  299.     return m_pDirectDrawSurface->BltBatch(lpDDBltBatch,dwCount,dwFlags);
  300. }
  301.  
  302.  
  303. STDMETHODIMP CAggDrawSurface::BltFast(DWORD dwX,DWORD dwY,LPDIRECTDRAWSURFACE lpDDSrcSurface,LPRECT lpSrcRect,DWORD dwTrans)
  304. {
  305.     ASSERT(m_pDirectDrawSurface);
  306.     return m_pDirectDrawSurface->BltFast(dwX,dwY,lpDDSrcSurface,lpSrcRect,dwTrans);
  307. }
  308.  
  309.  
  310. STDMETHODIMP CAggDrawSurface::DeleteAttachedSurface(DWORD dwFlags,LPDIRECTDRAWSURFACE lpDDSAttachedSurface)
  311. {
  312.     ASSERT(m_pDirectDrawSurface);
  313.     return m_pDirectDrawSurface->DeleteAttachedSurface(dwFlags,lpDDSAttachedSurface);
  314. }
  315.  
  316.  
  317. STDMETHODIMP CAggDrawSurface::EnumAttachedSurfaces(LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
  318. {
  319.     ASSERT(m_pDirectDrawSurface);
  320.     return m_pDirectDrawSurface->EnumAttachedSurfaces(lpContext,lpEnumSurfacesCallback);
  321. }
  322.  
  323.  
  324. STDMETHODIMP CAggDrawSurface::EnumOverlayZOrders(DWORD dwFlags,LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpfnCallback)
  325. {
  326.     ASSERT(m_pDirectDrawSurface);
  327.     return m_pDirectDrawSurface->EnumOverlayZOrders(dwFlags,lpContext,lpfnCallback);
  328. }
  329.  
  330.  
  331. STDMETHODIMP CAggDrawSurface::Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride,DWORD dwFlags)
  332. {
  333.     ASSERT(m_pDirectDrawSurface);
  334.     return m_pDirectDrawSurface->Flip(lpDDSurfaceTargetOverride,dwFlags);
  335. }
  336.  
  337.  
  338. STDMETHODIMP CAggDrawSurface::GetAttachedSurface(LPDDSCAPS lpDDSCaps,LPDIRECTDRAWSURFACE *lplpDDAttachedSurface)
  339. {
  340.     ASSERT(m_pDirectDrawSurface);
  341.     return m_pDirectDrawSurface->GetAttachedSurface(lpDDSCaps,lplpDDAttachedSurface);
  342. }
  343.  
  344.  
  345. STDMETHODIMP CAggDrawSurface::GetBltStatus(DWORD dwFlags)
  346. {
  347.     ASSERT(m_pDirectDrawSurface);
  348.     return m_pDirectDrawSurface->GetBltStatus(dwFlags);
  349. }
  350.  
  351.  
  352. STDMETHODIMP CAggDrawSurface::GetCaps(LPDDSCAPS lpDDSCaps)
  353. {
  354.     ASSERT(m_pDirectDrawSurface);
  355.     return m_pDirectDrawSurface->GetCaps(lpDDSCaps);
  356. }
  357.  
  358.  
  359. STDMETHODIMP CAggDrawSurface::GetClipper(LPDIRECTDRAWCLIPPER *lplpDDClipper)
  360. {
  361.     ASSERT(m_pDirectDrawSurface);
  362.     return m_pDirectDrawSurface->GetClipper(lplpDDClipper);
  363. }
  364.  
  365.  
  366. STDMETHODIMP CAggDrawSurface::GetColorKey(DWORD dwFlags,LPDDCOLORKEY lpDDColorKey)
  367. {
  368.     ASSERT(m_pDirectDrawSurface);
  369.     return m_pDirectDrawSurface->GetColorKey(dwFlags,lpDDColorKey);
  370. }
  371.  
  372.  
  373. STDMETHODIMP CAggDrawSurface::GetDC(HDC *lphDC)
  374. {
  375.     ASSERT(m_pDirectDrawSurface);
  376.     return m_pDirectDrawSurface->GetDC(lphDC);
  377. }
  378.  
  379.  
  380. STDMETHODIMP CAggDrawSurface::GetFlipStatus(DWORD dwFlags)
  381. {
  382.     ASSERT(m_pDirectDrawSurface);
  383.     return m_pDirectDrawSurface->GetFlipStatus(dwFlags);
  384. }
  385.  
  386.  
  387. STDMETHODIMP CAggDrawSurface::GetOverlayPosition(LPLONG lpdwX,LPLONG lpdwY)
  388. {
  389.     ASSERT(m_pDirectDrawSurface);
  390.     return m_pDirectDrawSurface->GetOverlayPosition(lpdwX,lpdwY);
  391. }
  392.  
  393.  
  394. STDMETHODIMP CAggDrawSurface::GetPalette(LPDIRECTDRAWPALETTE *lplpDDPalette)
  395. {
  396.     ASSERT(m_pDirectDrawSurface);
  397.     return m_pDirectDrawSurface->GetPalette(lplpDDPalette);
  398. }
  399.  
  400.  
  401. STDMETHODIMP CAggDrawSurface::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat)
  402. {
  403.     ASSERT(m_pDirectDrawSurface);
  404.     return m_pDirectDrawSurface->GetPixelFormat(lpDDPixelFormat);
  405. }
  406.  
  407.  
  408. // A bit of a hack alert here. Our media samples in ActiveMovie aggregate on
  409. // IDirectDraw and IDirectDrawSurface (ie are available through IMediaSample
  410. // by QueryInterface). Unfortunately the underlying DirectDraw code cannot
  411. // be aggregated so we have to use these classes. The snag is that when we
  412. // call a different surface and pass in this interface as perhaps the source
  413. // surface the call will fail because DirectDraw dereferences the pointer to
  414. // get at its private data structures. Therefore we supply this hack to give
  415. // access to the real IDirectDraw surface. A filter can call GetSurfaceDesc
  416. // and we will fill in the lpSurface pointer with the real underlying surface
  417.  
  418. STDMETHODIMP CAggDrawSurface::GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc)
  419. {
  420.     ASSERT(m_pDirectDrawSurface);
  421.  
  422.     // First call down to the underlying DirectDraw
  423.  
  424.     HRESULT hr = m_pDirectDrawSurface->GetSurfaceDesc(lpDDSurfaceDesc);
  425.     if (FAILED(hr)) {
  426.         return hr;
  427.     }
  428.  
  429.     // Store the real DirectDrawSurface interface
  430.     lpDDSurfaceDesc->lpSurface = m_pDirectDrawSurface;
  431.     return hr;
  432. }
  433.  
  434.  
  435. STDMETHODIMP CAggDrawSurface::Initialize(LPDIRECTDRAW lpDD,LPDDSURFACEDESC lpDDSurfaceDesc)
  436. {
  437.     ASSERT(m_pDirectDrawSurface);
  438.     return m_pDirectDrawSurface->Initialize(lpDD,lpDDSurfaceDesc);
  439. }
  440.  
  441.  
  442. STDMETHODIMP CAggDrawSurface::IsLost()
  443. {
  444.     ASSERT(m_pDirectDrawSurface);
  445.     return m_pDirectDrawSurface->IsLost();
  446. }
  447.  
  448.  
  449. STDMETHODIMP CAggDrawSurface::Lock(LPRECT lpDestRect,LPDDSURFACEDESC lpDDSurfaceDesc,DWORD dwFlags,HANDLE hEvent)
  450. {
  451.     ASSERT(m_pDirectDrawSurface);
  452.     return m_pDirectDrawSurface->Lock(lpDestRect,lpDDSurfaceDesc,dwFlags,hEvent);
  453. }
  454.  
  455.  
  456. STDMETHODIMP CAggDrawSurface::ReleaseDC(HDC hDC)
  457. {
  458.     ASSERT(m_pDirectDrawSurface);
  459.     return m_pDirectDrawSurface->ReleaseDC(hDC);
  460. }
  461.  
  462.  
  463. STDMETHODIMP CAggDrawSurface::Restore()
  464. {
  465.     ASSERT(m_pDirectDrawSurface);
  466.     return m_pDirectDrawSurface->Restore();
  467. }
  468.  
  469.  
  470. STDMETHODIMP CAggDrawSurface::SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper)
  471. {
  472.     ASSERT(m_pDirectDrawSurface);
  473.     return m_pDirectDrawSurface->SetClipper(lpDDClipper);
  474. }
  475.  
  476.  
  477. STDMETHODIMP CAggDrawSurface::SetColorKey(DWORD dwFlags,LPDDCOLORKEY lpDDColorKey)
  478. {
  479.     ASSERT(m_pDirectDrawSurface);
  480.     return m_pDirectDrawSurface->SetColorKey(dwFlags,lpDDColorKey);
  481. }
  482.  
  483.  
  484. STDMETHODIMP CAggDrawSurface::SetOverlayPosition(LONG dwX,LONG dwY)
  485. {
  486.     ASSERT(m_pDirectDrawSurface);
  487.     return m_pDirectDrawSurface->SetOverlayPosition(dwX,dwY);
  488. }
  489.  
  490.  
  491. STDMETHODIMP CAggDrawSurface::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette)
  492. {
  493.     ASSERT(m_pDirectDrawSurface);
  494.     return m_pDirectDrawSurface->SetPalette(lpDDPalette);
  495. }
  496.  
  497.  
  498. STDMETHODIMP CAggDrawSurface::Unlock(LPVOID lpSurfaceData)
  499. {
  500.     ASSERT(m_pDirectDrawSurface);
  501.     return m_pDirectDrawSurface->Unlock(lpSurfaceData);
  502. }
  503.  
  504.  
  505. STDMETHODIMP CAggDrawSurface::UpdateOverlay(LPRECT lpSrcRect,LPDIRECTDRAWSURFACE lpDDDestSurface,LPRECT lpDestRect,DWORD dwFlags,LPDDOVERLAYFX lpDDOverlayFX)
  506. {
  507.     ASSERT(m_pDirectDrawSurface);
  508.     return m_pDirectDrawSurface->UpdateOverlay(lpSrcRect,lpDDDestSurface,lpDestRect,dwFlags,lpDDOverlayFX);
  509. }
  510.  
  511.  
  512. STDMETHODIMP CAggDrawSurface::UpdateOverlayDisplay(DWORD dwFlags)
  513. {
  514.     ASSERT(m_pDirectDrawSurface);
  515.     return m_pDirectDrawSurface->UpdateOverlayDisplay(dwFlags);
  516. }
  517.  
  518.  
  519. STDMETHODIMP CAggDrawSurface::UpdateOverlayZOrder(DWORD dwFlags,LPDIRECTDRAWSURFACE lpDDSReference)
  520. {
  521.     ASSERT(m_pDirectDrawSurface);
  522.     return m_pDirectDrawSurface->UpdateOverlayZOrder(dwFlags,lpDDSReference);
  523. }
  524.  
  525.  
  526. // ActiveMovie must work on multiple platforms, in particular it also runs on
  527. // Windows NT 3.51 which does not have DirectDraw capabilities. The filters
  528. // cannot therefore link statically to the DirectDraw library. To make their
  529. // lives that little bit easier we provide this class that manages loading
  530. // and unloading the library and creating the initial IDirectDraw interface
  531.  
  532. CLoadDirectDraw::CLoadDirectDraw() :
  533.     m_pDirectDraw(NULL),
  534.     m_hDirectDraw(NULL)
  535. {
  536. }
  537.  
  538.  
  539. // Destructor forces unload
  540.  
  541. CLoadDirectDraw::~CLoadDirectDraw()
  542. {
  543.     ReleaseDirectDraw();
  544. }
  545.  
  546.  
  547. // We can't be sure that DirectDraw is always available so we can't statically
  548. // link to the library. Therefore we load the library, get the function entry
  549. // point addresses and call them to create the driver objects. We return S_OK
  550. // if we manage to load DirectDraw correctly otherwise we return E_NOINTERFACE
  551. // We initialise a DirectDraw instance by explicitely loading the library and
  552. // calling GetProcAddress on the DirectDrawCreate entry point that it exports
  553.  
  554. HRESULT CLoadDirectDraw::LoadDirectDraw()
  555. {
  556.     PDRAWCREATE pDrawCreate;
  557.     HRESULT hr = NOERROR;
  558.     FARPROC pFarProc;
  559.  
  560.     NOTE("Entering DoLoadDirectDraw");
  561.  
  562.     // Is DirectDraw already loaded
  563.  
  564.     if (m_pDirectDraw) {
  565.         NOTE("Already loaded");
  566.         ASSERT(m_hDirectDraw);
  567.         return NOERROR;
  568.     }
  569.  
  570.     // Make sure the library is available
  571.  
  572.     UINT currenterrormode = SetErrorMode(SEM_NOOPENFILEERRORBOX);
  573.     m_hDirectDraw = LoadLibrary(TEXT("DDRAW.DLL"));
  574.     SetErrorMode(currenterrormode);
  575.     if (m_hDirectDraw == NULL) {
  576.         NOTE("No library");
  577.         return E_NOINTERFACE;
  578.     }
  579.  
  580.     // Get the DLL address for the creator function
  581.  
  582.     pFarProc = GetProcAddress(m_hDirectDraw,"DirectDrawCreate");
  583.     if (pFarProc == NULL) {
  584.         NOTE("No entry point");
  585.         ReleaseDirectDraw();
  586.         return E_NOINTERFACE;
  587.     }
  588.  
  589.     pDrawCreate = (PDRAWCREATE) pFarProc;
  590.  
  591.     // Create a default DirectDraw display provider
  592.  
  593.     hr = pDrawCreate(NULL,&m_pDirectDraw,NULL);
  594.     if (FAILED(hr)) {
  595.         NOTE("No instance");
  596.         ReleaseDirectDraw();
  597.         return E_NOINTERFACE;
  598.     }
  599.     return NOERROR;
  600. }
  601.  
  602.  
  603. // Called to release any DirectDraw provider we previously loaded. We may be
  604. // called at any time especially when something goes horribly wrong and when
  605. // we need to clean up before returning so we can't guarantee that all state
  606. // variables are consistent so free only those really allocated allocated
  607. // This should only be called once all reference counts have been released
  608.  
  609. void CLoadDirectDraw::ReleaseDirectDraw()
  610. {
  611.     NOTE("Releasing DirectDraw driver");
  612.  
  613.     // Release any DirectDraw provider interface
  614.  
  615.     if (m_pDirectDraw) {
  616.         NOTE("Releasing instance");
  617.         m_pDirectDraw->Release();
  618.         m_pDirectDraw = NULL;
  619.     }
  620.  
  621.     // Decrement module load count
  622.  
  623.     if (m_hDirectDraw) {
  624.         NOTE("Unloading library");
  625.         FreeLibrary(m_hDirectDraw);
  626.         m_hDirectDraw = NULL;
  627.     }
  628. }
  629.  
  630.  
  631. // Return NOERROR (S_OK) if DirectDraw has been loaded by this object
  632.  
  633. HRESULT CLoadDirectDraw::IsDirectDrawLoaded()
  634. {
  635.     NOTE("Entering IsDirectDrawLoaded");
  636.  
  637.     if (m_pDirectDraw == NULL) {
  638.         NOTE("DirectDraw not loaded");
  639.         return S_FALSE;
  640.     }
  641.     return NOERROR;
  642. }
  643.  
  644.  
  645. // Return the IDirectDraw interface we look after
  646.  
  647. LPDIRECTDRAW CLoadDirectDraw::GetDirectDraw()
  648. {
  649.     NOTE("Entering GetDirectDraw");
  650.  
  651.     if (m_pDirectDraw == NULL) {
  652.         NOTE("No DirectDraw");
  653.         return NULL;
  654.     }
  655.  
  656.     NOTE("Returning DirectDraw");
  657.     m_pDirectDraw->AddRef();
  658.     return m_pDirectDraw;
  659. }
  660.  
  661.  
  662. // Return the version of DirectDraw we can find. We need to find versions as
  663. // we rely on specific bug fixes in DirectDraw 2 for fullscreen playback. To
  664. // get the DirectDraw version we go and get DDRAW.DLLs file version data and
  665. // extract the product version. This saves loading and creating a DirectDraw
  666. // instance (which is expensive) to decide what capabilities we can support
  667.  
  668. DWORD CLoadDirectDraw::GetDirectDrawVersion()
  669. {
  670.     VS_FIXEDFILEINFO *pVersionInfo;
  671.     DWORD VersionHandle;
  672.     DWORD VersionSize;
  673.     BOOL bVersion;
  674.  
  675.     // Find out how big the version data is
  676.  
  677.     VersionSize = GetFileVersionInfoSize(TEXT("DDRAW.DLL"),&VersionHandle);
  678.     if (VersionSize == 0) {
  679.         NOTE("No file version size");
  680.         return DWORD(0);
  681.     }
  682.  
  683.     // Allocate the memory for the version data
  684.  
  685.     BYTE *pVersionData = new BYTE[VersionSize];
  686.     if (pVersionData == NULL) {
  687.         NOTE("No version memory");
  688.         return DWORD(0);
  689.     }
  690.  
  691.     // Now get the version data block
  692.  
  693.     bVersion = GetFileVersionInfo(TEXT("DDRAW.DLL"),
  694.                                   (DWORD) 0,
  695.                                   VersionSize,
  696.                                   pVersionData);
  697.     if (bVersion == FALSE) {
  698.         NOTE("No file information");
  699.         delete[] pVersionData;
  700.         return DWORD(0);
  701.     }
  702.  
  703.     // Get the VS_VERSION_INFO from the data block
  704.  
  705.     bVersion = VerQueryValue((const LPVOID) pVersionData,
  706.                              (LPTSTR) TEXT("\\"),
  707.                              (PVOID *) &pVersionInfo,
  708.                              (PUINT) &VersionSize);
  709.  
  710.     if (bVersion == FALSE) {
  711.         NOTE("No VS_VERSION_INFO");
  712.         delete[] pVersionData;
  713.         return DWORD(0);
  714.     }
  715.  
  716.     NOTE1("dwSignature %x",pVersionInfo->dwSignature);
  717.     NOTE1("dwStrucVersion %x",pVersionInfo->dwStrucVersion);
  718.     NOTE1("dwFileVersionMS %x",pVersionInfo->dwFileVersionMS);
  719.     NOTE1("dwFileVersionLS %x",pVersionInfo->dwFileVersionLS);
  720.     NOTE1("dwProductVersionMS %x",pVersionInfo->dwProductVersionMS);
  721.     NOTE1("dwProductVersionLS %x",pVersionInfo->dwProductVersionLS);
  722.     NOTE1("dwFileFlagsMask %x",pVersionInfo->dwFileFlagsMask);
  723.     NOTE1("dwFileFlags %x",pVersionInfo->dwFileFlags);
  724.     NOTE1("dwFileOS %x",pVersionInfo->dwFileOS);
  725.     NOTE1("dwFileType %x",pVersionInfo->dwFileType);
  726.     NOTE1("dwFileSubtype %x",pVersionInfo->dwFileSubtype);
  727.     NOTE1("dwFileDateMS %x",pVersionInfo->dwFileDateMS);
  728.     NOTE1("dwFileDateLS %x",pVersionInfo->dwFileDateLS);
  729.  
  730.     // NT SUR Beta hack which has no DDRAW version set
  731.  
  732.     if ((pVersionInfo->dwProductVersionMS & 0xFF) == 0) {
  733.         NOTE("DirectDraw on NT SUR Beta");
  734.         pVersionInfo->dwProductVersionMS = 0x40003;
  735.     }
  736.  
  737.     // Rip off the Windows version to get the product
  738.  
  739.     DWORD DirectDrawVersion = pVersionInfo->dwProductVersionMS;
  740.     DirectDrawVersion = ((DirectDrawVersion & 0xFF) - 1);
  741.     delete[] pVersionData;
  742.     NOTE1("Version is %d",DirectDrawVersion);
  743.     ASSERT(DirectDrawVersion != 1);
  744.  
  745.     return DirectDrawVersion;
  746. }
  747.  
  748.