home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 25: Programming / pc_actual_25.iso / C_C++ / BorlandCompiler / freecommandLinetools.exe / Include / dxsurfb.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-27  |  14.2 KB  |  517 lines

  1. /*******************************************************************************
  2. * DXSurfB.cpp *
  3. *------------*
  4. *   Description:
  5. *    This module contains the CDXBaseSurface implementaion.
  6. *-------------------------------------------------------------------------------
  7. *  Created By: RAL                                  Date: 02/12/1998
  8. *  Copyright (C) 1998 Microsoft Corporation
  9. *  All Rights Reserved
  10. *
  11. *-------------------------------------------------------------------------------
  12. *  Revisions:
  13. *
  14. *******************************************************************************/
  15. //--- Additional includes
  16. #include "stdafx.h"
  17. #include <DXTrans.h>
  18. #include "DXSurfB.h"
  19. #include "new.h"
  20.  
  21. CDXBaseSurface::CDXBaseSurface() :
  22.     m_ulLocks(0),
  23.     m_ulThreadsWaiting(0),
  24.     m_Height(0),
  25.     m_Width(0),
  26.     m_pFreePtr(NULL),
  27.     m_dwStatusFlags(DXSURF_READONLY),
  28.     m_dwAppData(0)
  29. {
  30.     m_hSemaphore = CreateSemaphore(NULL, 0, MAXLONG, NULL);
  31.     m_ulNumInRequired = m_ulMaxInputs = 0;
  32. }
  33.  
  34. HRESULT CDXBaseSurface::FinalConstruct()
  35. {
  36.     return m_hSemaphore ? S_OK : E_OUTOFMEMORY;
  37. }
  38.  
  39. void CDXBaseSurface::FinalRelease()
  40. {
  41.     while (m_pFreePtr)
  42.     {
  43.         CDXBaseARGBPtr *pNext = m_pFreePtr->m_pNext;
  44.         DeleteARGBPointer(m_pFreePtr);
  45.         m_pFreePtr = pNext;
  46.     }
  47.     if (m_hSemaphore)
  48.     {
  49.         CloseHandle(m_hSemaphore);
  50.     }
  51. }
  52.  
  53. STDMETHODIMP CDXBaseSurface::GetGenerationId(ULONG *pGenerationId)
  54. {
  55.     if (DXIsBadWritePtr(pGenerationId, sizeof(*pGenerationId)))
  56.     {
  57.         return E_POINTER;
  58.     }
  59.     Lock();
  60.     OnUpdateGenerationId();
  61.     *pGenerationId = m_dwGenerationId;
  62.     Unlock();
  63.     return S_OK;
  64. }
  65.  
  66. STDMETHODIMP CDXBaseSurface::IncrementGenerationId(BOOL /*bRefresh */)
  67. {
  68.     Lock();
  69.     m_dwGenerationId++;
  70.     Unlock();
  71.     return S_OK;
  72. }
  73.  
  74.  
  75. STDMETHODIMP CDXBaseSurface::GetObjectSize(ULONG *pcbSize)
  76. {
  77.     HRESULT hr = S_OK;
  78.     if (DXIsBadWritePtr(pcbSize, sizeof(*pcbSize)))
  79.     {
  80.         hr = E_POINTER;
  81.     }
  82.     else
  83.     {
  84.     Lock();
  85.         *pcbSize = OnGetObjectSize();
  86.         Unlock();
  87.     }
  88.     return hr;
  89. }
  90.  
  91. STDMETHODIMP CDXBaseSurface::MapBoundsIn2Out
  92.     (const DXBNDS *pInBounds, ULONG ulNumInBnds, ULONG /*ulOutIndex*/, DXBNDS *pOutBounds)
  93. {
  94.     HRESULT hr = S_OK;
  95.     if (DXIsBadWritePtr(pOutBounds, sizeof(*pOutBounds)))
  96.     {
  97.         hr = E_POINTER;
  98.     }
  99.     else
  100.     {
  101.         Lock();
  102.         new(pOutBounds) CDXDBnds(m_Width, m_Height);
  103.         Unlock();
  104.     }
  105.     return hr;    
  106. }
  107.  
  108. STDMETHODIMP CDXBaseSurface::InitSurface(IUnknown *pDirectDraw,
  109.                                          const DDSURFACEDESC * pDDSurfaceDesc,
  110.                                          const GUID * pFormatId,
  111.                                          const DXBNDS *pBounds,
  112.                                          DWORD dwFlags)
  113. {
  114.     HRESULT hr = S_OK;
  115.     if (pDDSurfaceDesc || DXIsBadReadPtr(pBounds, sizeof(*pBounds)) || pBounds->eType != DXBT_DISCRETE)
  116.     {
  117.         hr = E_INVALIDARG;
  118.     }
  119.     else
  120.     {
  121.         _EnterCritWith0PtrLocks();
  122.         if (m_Width)
  123.         {
  124.             hr = HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED);
  125.         }
  126.         else
  127.         {
  128.             CDXDBnds *pbnds = (CDXDBnds *)pBounds;
  129.             hr = OnSetSize(pbnds->Width(), pbnds->Height());
  130.         }
  131.         Unlock();
  132.     }
  133.     return hr;
  134. }
  135.  
  136.  
  137. STDMETHODIMP CDXBaseSurface::GetPixelFormat(GUID *pFormat, DXSAMPLEFORMATENUM *pSampleFormatEnum)
  138. {
  139.     HRESULT hr = S_OK;
  140.     if (DX_IS_BAD_OPTIONAL_WRITE_PTR(pFormat) ||
  141.         DX_IS_BAD_OPTIONAL_WRITE_PTR(pSampleFormatEnum))
  142.     {
  143.         hr = E_POINTER;
  144.     }
  145.     else
  146.     {
  147.         if (pFormat) *pFormat = SurfaceCLSID();
  148.         if (pSampleFormatEnum) *pSampleFormatEnum = SampleFormatEnum();
  149.     }
  150.     return hr;
  151. }
  152.  
  153. STDMETHODIMP CDXBaseSurface::GetBounds(DXBNDS* pBounds)
  154. {
  155.     HRESULT hr = S_OK;
  156.     if (DXIsBadWritePtr(pBounds, sizeof(*pBounds)))
  157.     {
  158.         hr = E_POINTER;
  159.     }
  160.     else
  161.     {
  162.         Lock();
  163.         new(pBounds) CDXDBnds(m_Width, m_Height);
  164.         Unlock();
  165.     }
  166.     return hr;    
  167.  
  168. STDMETHODIMP CDXBaseSurface::GetStatusFlags(DWORD* pdwStatusFlags)
  169. {
  170.     HRESULT hr = S_OK;
  171.     if (DXIsBadWritePtr(pdwStatusFlags, sizeof(*pdwStatusFlags)))
  172.     {
  173.         hr = E_POINTER;
  174.     }
  175.     else
  176.     {
  177.         Lock();
  178.         *pdwStatusFlags = m_dwStatusFlags;
  179.         Unlock();
  180.     }
  181.     return hr;    
  182.  
  183. STDMETHODIMP CDXBaseSurface::SetStatusFlags(DWORD dwStatusFlags )
  184. {
  185.     _EnterCritWith0PtrLocks();
  186.     // BUGBUG -- Think about this
  187.     m_dwStatusFlags = dwStatusFlags | DXSURF_READONLY;
  188.     m_dwGenerationId++;
  189.     Unlock();
  190.     return S_OK;
  191.  
  192. STDMETHODIMP CDXBaseSurface::GetDirectDrawSurface(REFIID riid, void **ppSurface)
  193. {
  194.     return E_NOTIMPL;
  195. }
  196.  
  197. STDMETHODIMP CDXBaseSurface::LockSurface(const DXBNDS *pBounds, ULONG ulTimeOut,
  198.                                          DWORD dwFlags, REFIID riid, void **ppPointer,
  199.                                          DWORD * pGenerationId)
  200. {
  201.     HRESULT hr = S_OK;
  202.     BOOL bMPLockOnly = m_bInMultiThreadWorkProc;
  203.  
  204.     if (!bMPLockOnly) Lock();
  205.     m_MPWorkProcCrit.Lock();
  206.  
  207.     if (m_Width == 0)
  208.     {
  209.         hr = E_FAIL;    // BUGBUG -- What code??
  210.     }
  211.     else
  212.     {
  213.         RECT r;
  214.         r.top = r.left = 0;
  215.         r.right = m_Width;
  216.         r.bottom = m_Height;
  217.         if (pBounds)
  218.         {
  219.             if (pBounds->eType != DXBT_DISCRETE)
  220.             {
  221.                 hr = DXTERR_INVALID_BOUNDS;
  222.             }
  223.             else
  224.             {
  225.                 ((CDXDBnds *)pBounds)->GetXYRect(r);
  226.                 if (r.top < 0 || r.left < 0 || (ULONG)r.right > m_Width || (ULONG)r.bottom > m_Height || r.bottom <= r.top || r.right <= r.left)
  227.                 {
  228.                     hr = DXTERR_INVALID_BOUNDS;
  229.                 }
  230.             }
  231.         }
  232.         if (SUCCEEDED(hr))
  233.         {
  234.             CDXBaseARGBPtr * pPtr = m_pFreePtr;
  235.             if (pPtr)
  236.             {
  237.                 m_pFreePtr = pPtr->m_pNext;
  238.             }
  239.             else
  240.             {
  241.                 hr = CreateARGBPointer(this, &pPtr);
  242.             }
  243.             if (SUCCEEDED(hr))
  244.             {
  245.                 hr = pPtr->InitFromLock(r, ulTimeOut, dwFlags, riid, ppPointer);
  246.                 if (pGenerationId)
  247.                 {
  248.                     if (DXIsBadWritePtr(pGenerationId, sizeof(*pGenerationId)))
  249.                     {
  250.                         hr = E_POINTER;
  251.                     }
  252.                     else
  253.                     {
  254.                         *pGenerationId = m_dwGenerationId;
  255.                     }
  256.                 }
  257.                 if (SUCCEEDED(hr))
  258.                 {
  259.                     m_ulLocks++;
  260.                 }
  261.                 else
  262.                 {
  263.                     pPtr->m_pNext = m_pFreePtr;
  264.                     m_pFreePtr = pPtr;
  265.                 }
  266.             }
  267.         }
  268.     }
  269.     m_MPWorkProcCrit.Unlock();
  270.     if (!bMPLockOnly) Unlock();
  271.     return hr;
  272. }
  273.  
  274. void CDXBaseSurface::_InternalUnlock(CDXBaseARGBPtr *pPtrToUnlock)
  275. {
  276.     BOOL bMPLockOnly = m_bInMultiThreadWorkProc;
  277.  
  278.     if (!bMPLockOnly) Lock();
  279.     m_MPWorkProcCrit.Lock();
  280.     pPtrToUnlock->m_pNext = m_pFreePtr;
  281.     m_pFreePtr = pPtrToUnlock;
  282.     m_ulLocks--;
  283.     if ((m_ulLocks == 0) && m_ulThreadsWaiting)
  284.     {
  285.         ReleaseSemaphore(m_hSemaphore, m_ulThreadsWaiting, NULL);
  286.         m_ulThreadsWaiting = 0;
  287.     }
  288.     m_MPWorkProcCrit.Unlock();
  289.     if (!bMPLockOnly) Unlock();
  290.  
  291.     IUnknown *punkOuter = GetControllingUnknown();
  292.     punkOuter->Release();   // Release pointer's reference to us
  293.                             // which could kill us!  Don't touch
  294.                             // any members after this point.
  295. }
  296.  
  297. //
  298. //  Picking interface needs to test the appropriate point for hit testing
  299. //
  300. HRESULT CDXBaseSurface::OnSurfacePick(const CDXDBnds & OutPoint, ULONG & ulInputIndex, CDXDVec & InVec)
  301. {
  302.     HRESULT hr;
  303.     IDXARGBReadPtr *pPtr;
  304.     hr = LockSurface(&OutPoint, m_ulLockTimeOut, DXLOCKF_READ, 
  305.                      IID_IDXARGBReadPtr, (void **)&pPtr, NULL);
  306.     if( SUCCEEDED(hr) )
  307.     {
  308.         DXPMSAMPLE val;
  309.         pPtr->UnpackPremult(&val, 1, FALSE);
  310.         pPtr->Release();
  311.         hr = val.Alpha ? DXT_S_HITOUTPUT : S_FALSE;
  312.     }
  313.     else
  314.     {
  315.         if (hr == DXTERR_INVALID_BOUNDS) hr = S_FALSE;
  316.     }
  317.     return hr;
  318. }
  319.  
  320. /*****************************************************************************
  321. * RegisterSurface (STATIC member function)
  322. *-----------------------------------------------------------------------------
  323. *   Description:
  324. *-----------------------------------------------------------------------------
  325. *   Created By: RAL                                 Date: 12/10/97
  326. *-----------------------------------------------------------------------------
  327. *   Parameters:
  328. *****************************************************************************/
  329. HRESULT CDXBaseSurface::
  330. RegisterSurface(REFCLSID rcid, int ResourceId, ULONG cCatImpl, const CATID * pCatImpl,
  331.                 ULONG cCatReq, const CATID * pCatReq, BOOL bRegister)
  332. {
  333.     HRESULT hr = bRegister ? _Module.UpdateRegistryFromResource(ResourceId, bRegister) : S_OK;
  334.     if (SUCCEEDED(hr))
  335.     {
  336.         CComPtr<ICatRegister> pCatRegister;
  337.         HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_ALL, IID_ICatRegister, (void **)&pCatRegister);
  338.         if (SUCCEEDED(hr))
  339.         {
  340.             if (bRegister)
  341.             {
  342.                 hr = pCatRegister->RegisterClassImplCategories(rcid, cCatImpl, (CATID *)pCatImpl);
  343.                 if (SUCCEEDED(hr) && cCatReq && pCatReq) {
  344.                     hr = pCatRegister->RegisterClassReqCategories(rcid, cCatReq, (CATID *)pCatReq);
  345.                 }
  346.             } 
  347.             else
  348.             {
  349.                 pCatRegister->UnRegisterClassImplCategories(rcid, cCatImpl, (CATID *)pCatImpl);
  350.                 if (cCatReq && pCatReq)
  351.                 {
  352.                     pCatRegister->UnRegisterClassReqCategories(rcid, cCatReq, (CATID *)pCatReq);
  353.                 }
  354.             }
  355.         }
  356.     }
  357.     if ((!bRegister) && SUCCEEDED(hr)) 
  358.     { 
  359.         _Module.UpdateRegistryFromResource(ResourceId, bRegister);
  360.     }
  361.     return hr;
  362. }
  363.  
  364. //
  365. //  CDXBaseARGBPtr
  366. //
  367. STDMETHODIMP CDXBaseARGBPtr::QueryInterface(REFIID riid, void ** ppv)
  368. {
  369.     if (IsEqualGUID(riid, IID_IUnknown) ||
  370.         IsEqualGUID(riid, IID_IDXARGBReadPtr))
  371.     {
  372.         *ppv = (IDXARGBReadPtr *)this;
  373.         m_ulRefCount++;
  374.         return S_OK;
  375.     }
  376.     else
  377.     {
  378.         *ppv = NULL;
  379.         return E_NOINTERFACE;
  380.     }
  381. }
  382.  
  383.  
  384. ULONG STDMETHODCALLTYPE CDXBaseARGBPtr::AddRef()
  385. {
  386.     return ++m_ulRefCount;
  387. }
  388.  
  389. ULONG STDMETHODCALLTYPE CDXBaseARGBPtr::Release()
  390. {
  391.     --m_ulRefCount;
  392.     ULONG c = m_ulRefCount;
  393.     if (c == 0)
  394.     {
  395.         m_pSurface->_InternalUnlock(this);  // Don't touch members after this call.
  396.     }
  397.     return c;
  398. }
  399.  
  400. HRESULT STDMETHODCALLTYPE CDXBaseARGBPtr::GetSurface(REFIID riid, void **ppSurface)
  401. {
  402.     return m_pSurface->GetControllingUnknown()->QueryInterface(riid, ppSurface);
  403. }
  404.  
  405.  
  406. DXSAMPLEFORMATENUM STDMETHODCALLTYPE CDXBaseARGBPtr::GetNativeType(DXNATIVETYPEINFO *pInfo)
  407. {
  408.     if (pInfo)
  409.     {
  410.         memset(pInfo, 0, sizeof(pInfo));
  411.     }
  412.     return m_pSurface->SampleFormatEnum();
  413. }
  414.  
  415.  
  416. void STDMETHODCALLTYPE CDXBaseARGBPtr::Move(long cSamples)
  417. {
  418.     m_FillInfo.x += cSamples;
  419.     //--- Moving one column past the end is okay
  420.     _ASSERT((long)m_FillInfo.x <= m_LockedRect.right);
  421. }
  422.  
  423. void STDMETHODCALLTYPE CDXBaseARGBPtr::MoveToRow(ULONG y)
  424. {
  425.     m_FillInfo.x = m_LockedRect.left;
  426.     m_FillInfo.y = y + m_LockedRect.top;
  427.     _ASSERT((long)m_FillInfo.y < m_LockedRect.bottom);
  428. }
  429.  
  430. void STDMETHODCALLTYPE CDXBaseARGBPtr::MoveToXY(ULONG x, ULONG y)
  431. {
  432.     m_FillInfo.x = x + m_LockedRect.left;
  433.     m_FillInfo.y = y + m_LockedRect.top;
  434.     //--- Moving one column past the end is okay
  435.     _ASSERT((long)m_FillInfo.x <= m_LockedRect.right);
  436.     _ASSERT((long)m_FillInfo.y < m_LockedRect.bottom);
  437. }
  438.  
  439. ULONG STDMETHODCALLTYPE CDXBaseARGBPtr::MoveAndGetRunInfo(ULONG Row, const DXRUNINFO ** ppInfo)
  440. {
  441.     m_FillInfo.x = m_LockedRect.left;
  442.     m_FillInfo.y = Row + m_LockedRect.top;
  443.     _ASSERT((long)m_FillInfo.y < m_LockedRect.bottom);
  444.     *ppInfo = &m_RunInfo;
  445.     return 1;
  446. }
  447.  
  448. DXSAMPLE *STDMETHODCALLTYPE CDXBaseARGBPtr::Unpack(DXSAMPLE *pSamples, ULONG cSamples, BOOL bMove)
  449. {
  450.     m_FillInfo.pSamples = pSamples;
  451.     m_FillInfo.cSamples = cSamples;
  452.     m_FillInfo.bPremult = false;
  453.     FillSamples(m_FillInfo);
  454.     if (bMove) m_FillInfo.x += cSamples;
  455.     return pSamples;
  456. }
  457.  
  458. DXPMSAMPLE *STDMETHODCALLTYPE CDXBaseARGBPtr::UnpackPremult(DXPMSAMPLE *pSamples, ULONG cSamples, BOOL bMove)
  459. {
  460.     m_FillInfo.pSamples = pSamples;
  461.     m_FillInfo.cSamples = cSamples;
  462.     m_FillInfo.bPremult = true;
  463.     FillSamples(m_FillInfo);
  464.     if (bMove) m_FillInfo.x += cSamples;
  465.     return pSamples;
  466. }
  467.  
  468. void STDMETHODCALLTYPE CDXBaseARGBPtr::UnpackRect(const DXPACKEDRECTDESC *pDesc)
  469. {
  470.     DXPtrFillInfo FillInfo;
  471.     FillInfo.pSamples = pDesc->pSamples;
  472.     FillInfo.cSamples = pDesc->rect.right - pDesc->rect.left;
  473.     FillInfo.x = pDesc->rect.left + m_LockedRect.left;
  474.     FillInfo.bPremult = pDesc->bPremult;
  475.     ULONG YLimit = pDesc->rect.bottom + m_LockedRect.top;
  476.     for (FillInfo.y = pDesc->rect.top + m_LockedRect.top;
  477.          FillInfo.y < YLimit;
  478.          FillInfo.y++)
  479.     {
  480.         FillSamples(FillInfo);
  481.         FillInfo.pSamples += FillInfo.cSamples;
  482.     }
  483. }
  484.  
  485. HRESULT CDXBaseARGBPtr::InitFromLock(const RECT & rect, ULONG /*ulTimeOut*/, DWORD dwLockFlags, REFIID riid, void ** ppv)
  486. {
  487.     HRESULT hr = S_OK;
  488.     if (dwLockFlags & DXLOCKF_READWRITE)
  489.     {
  490.         hr = E_INVALIDARG;
  491.     }
  492.     else
  493.     {
  494.         m_LockedRect = rect;
  495.         m_RunInfo.Count = rect.right - rect.left;
  496.         if (m_pSurface->SampleFormatEnum() & DXPF_TRANSPARENCY)
  497.         {
  498.             m_RunInfo.Type = DXRUNTYPE_UNKNOWN;
  499.         }
  500.         else
  501.         {
  502.             m_RunInfo.Type = DXRUNTYPE_OPAQUE;
  503.         }
  504.         m_FillInfo.x = rect.left;
  505.         m_FillInfo.y = rect.top;
  506.         hr = QueryInterface(riid, ppv);
  507.         if (SUCCEEDED(hr))
  508.         {
  509.             m_pSurface->GetControllingUnknown()->AddRef();
  510.         }
  511.     }
  512.     return hr;
  513. }
  514.