RealMediaWindowlessSite.cpp

00001 /* 
00002  *      Copyright (C) 2003-2005 Gabest
00003  *      http://www.gabest.org
00004  *
00005  *  This Program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2, or (at your option)
00008  *  any later version.
00009  *   
00010  *  This Program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  *  GNU General Public License for more details.
00014  *   
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with GNU Make; see the file COPYING.  If not, write to
00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
00018  *  http://www.gnu.org/copyleft/gpl.html
00019  *
00020  */
00021 
00022 #include "stdafx.h"
00023 #include "mplayerc.h"
00024 #include <math.h>
00025 #include <atlbase.h>
00026 #include <atlcoll.h>
00027 #include "realmediawindowlesssite.h"
00028 #include "..\..\DSUtil\DSUtil.h"
00029 
00030 void DSObjects::ExtractRects(REGION* pRegion)
00031 {
00032         LPRGNDATA lpRgnData;
00033 
00034         DWORD sizeNeeed = GetRegionData((HRGN)pRegion->pOSRegion, 0, NULL); 
00035 
00036         lpRgnData = (LPRGNDATA)new char[sizeNeeed];
00037         DWORD returnValue = GetRegionData((HRGN)pRegion->pOSRegion, sizeNeeed, lpRgnData); 
00038 
00039         PN_VECTOR_DELETE(pRegion->rects);
00040 
00041         pRegion->numRects               = lpRgnData->rdh.nCount;
00042         pRegion->extents.left   = lpRgnData->rdh.rcBound.left;
00043         pRegion->extents.top    = lpRgnData->rdh.rcBound.top;
00044         pRegion->extents.right  = lpRgnData->rdh.rcBound.right;
00045         pRegion->extents.bottom = lpRgnData->rdh.rcBound.bottom;
00046         
00047         if(lpRgnData->rdh.nCount)
00048         {
00049                 pRegion->rects = new PNxRect[lpRgnData->rdh.nCount];
00050 
00051                 // now extract the information.
00052 
00053                 for(int j = 0; j < (int) lpRgnData->rdh.nCount;j++)
00054                 {
00055                         RECT* pRect = (RECT*)lpRgnData->Buffer;
00056                         pRegion->rects[j].left = pRect[j].left;
00057                         pRegion->rects[j].top = pRect[j].top;
00058                         pRegion->rects[j].right = pRect[j].right;
00059                         pRegion->rects[j].bottom = pRect[j].bottom;
00060                 }
00061         }
00062 
00063         PN_VECTOR_DELETE(lpRgnData);
00064 }
00065 REGION* DSObjects::RMACreateRectRegion(int left, int top, int right, int bottom)
00066 {
00067         REGION* retVal = new REGION;
00068         retVal->pOSRegion = (void*)CreateRectRgn(left, top, right, bottom);
00069         ExtractRects(retVal);
00070         return retVal;
00071 }
00072 void DSObjects::RMASubtractRegion(REGION* regM, REGION* regS, REGION* regD)
00073 {
00074         CombineRgn((HRGN)regD->pOSRegion, (HRGN)regM->pOSRegion, (HRGN)regS->pOSRegion, RGN_DIFF);
00075         ExtractRects(regD);
00076 }
00077 void DSObjects::RMAUnionRegion(REGION* reg1, REGION* reg2, REGION* regD)
00078 {
00079         CombineRgn((HRGN)regD->pOSRegion, (HRGN)reg1->pOSRegion, (HRGN)reg2->pOSRegion, RGN_OR);
00080         ExtractRects(regD);
00081 }
00082 void DSObjects::RMAIntersectRegion(REGION* reg1, REGION* reg2, REGION* regD)
00083 {
00084         CombineRgn((HRGN)regD->pOSRegion, (HRGN)reg1->pOSRegion, (HRGN)reg2->pOSRegion, RGN_AND);
00085         ExtractRects(regD);
00086 }
00087 BOOL DSObjects::RMAEqualRegion(REGION* reg1, REGION* reg2)
00088 {
00089         return EqualRgn((HRGN)reg1->pOSRegion, (HRGN)reg2->pOSRegion)
00090                 && !memcmp(&reg1->extents, &reg2->extents, sizeof(PNxRect)) ? TRUE : FALSE;
00091 }
00092 void DSObjects::RMADestroyRegion(REGION* reg)
00093 {
00094         if(reg) DeleteObject((HRGN)reg->pOSRegion),
00095         PN_VECTOR_DELETE(reg->rects);
00096         PN_DELETE(reg);
00097 }
00098 REGION* DSObjects::RMACreateRegion()
00099 {
00100         return RMACreateRectRegion(0,0,0,0);
00101 }
00102 
00103 //
00104 // CRealMediaWindowlessSite
00105 //
00106 
00107 CRealMediaWindowlessSite::CRealMediaWindowlessSite(HRESULT& hr, IUnknown* pContext, CRealMediaWindowlessSite* pParentSite, IUnknown* pUnkOuter)
00108         : CUnknown(NAME("CRealMediaWindowlessSite"), pUnkOuter, &hr)
00109         , m_pContext(pContext)
00110         , m_pParentSite(pParentSite)
00111         , m_pCCF(pContext)
00112         , m_fDamaged(false), m_fInRedraw(false), m_fIsVisible(true)
00113         , m_lZOrder(0)
00114         , m_pRegion(NULL), m_pRegionWithoutChildren(NULL)
00115 {
00116         m_size.cx = m_size.cy = 0;
00117         m_position.x = m_position.y = 0;
00118 
00119         memset(&m_lastBitmapInfo, 0, sizeof(m_lastBitmapInfo));
00120 
00121         hr = S_OK;
00122 
00123         if(!m_pContext || !m_pCCF)
00124         {
00125                 hr = E_POINTER;
00126                 return;
00127         }
00128 
00129         m_pCCF->CreateInstance(CLSID_IRMAValues, (void**)&m_pValues);
00130 }
00131 
00132 CRealMediaWindowlessSite::~CRealMediaWindowlessSite()
00133 {
00134         POSITION pos = m_pChildren.GetHeadPosition();
00135         while(pos) DestroyChild(m_pChildren.GetNext(pos));
00136 
00137         RMADestroyRegion(m_pRegion);
00138         RMADestroyRegion(m_pRegionWithoutChildren);
00139 }
00140 
00141 STDMETHODIMP CRealMediaWindowlessSite::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00142 {
00143         return 
00144                 QI2(IRMASite)
00145                 QI2(IRMASite2)
00146                 QI2(IRMASiteWindowless)
00147                 QI2(IRMAVideoSurface)
00148                 (m_pValues && m_pValues->QueryInterface(riid, ppv) == PNR_OK) ? PNR_OK :
00149                 CUnknown::NonDelegatingQueryInterface(riid, ppv);
00150 }
00151 
00152 // public
00153 
00154 void CRealMediaWindowlessSite::GetTopLeft(PNxPoint* pPoint)
00155 {
00156         pPoint->x += m_position.x;
00157         pPoint->y += m_position.y;
00158 
00159         if(m_pParentSite)
00160                 m_pParentSite->GetTopLeft(pPoint);
00161 }
00162 
00163 REGION* CRealMediaWindowlessSite::GetRegion()
00164 {
00165         return m_pRegion;
00166 }
00167 
00168 // private
00169 
00170 void CRealMediaWindowlessSite::RecomputeRegion()
00171 {
00172         if(m_pParentSite) m_pParentSite->RecomputeRegion();
00173         else InternalRecomputeRegion();
00174 }
00175 
00176 void CRealMediaWindowlessSite::InternalRecomputeRegion()
00177 {
00178         ComputeRegion();
00179 
00180         POSITION pos = m_pChildren.GetHeadPosition();
00181         while(pos)
00182         {
00183                 CRealMediaWindowlessSite* pSite = (CRealMediaWindowlessSite*)(IRMASite*)m_pChildren.GetNext(pos);
00184                 if(pSite) pSite->InternalRecomputeRegion();
00185         }
00186 }
00187 
00188 void CRealMediaWindowlessSite::ComputeRegion()
00189 {
00190         REGION* pTempRegion = NULL;
00191 
00192         if(m_pRegion)
00193         {
00194                 pTempRegion = RMACreateRegion();
00195                 RMAUnionRegion(pTempRegion, m_pRegion, pTempRegion);
00196                 RMADestroyRegion(m_pRegion);
00197         }
00198 
00199         if(m_pRegionWithoutChildren)
00200         {
00201                 RMADestroyRegion(m_pRegionWithoutChildren);
00202         }
00203 
00204         PNxPoint topleft = {0,0};
00205         GetTopLeft(&topleft);
00206 
00207         if(IsSiteVisible())
00208         {
00209                 m_pRegionWithoutChildren = RMACreateRectRegion(topleft.x, topleft.y, topleft.x + m_size.cx, topleft.y + m_size.cy);
00210 
00211                 if(m_pParentSite)
00212                 {
00213                         RMAIntersectRegion(m_pRegionWithoutChildren, m_pParentSite->m_pRegionWithoutChildren, m_pRegionWithoutChildren);
00214 
00215                         POSITION pos = m_pParentSite->m_pChildren.GetHeadPosition();
00216             while(pos)
00217                         {
00218                                 CRealMediaWindowlessSite* pSiblingSite = (CRealMediaWindowlessSite*)(IRMASite*)m_pParentSite->m_pChildren.GetNext(pos);
00219                                 if(pSiblingSite != this)
00220                                 {
00221                                         INT32 zOrder;
00222                                         pSiblingSite->GetZOrder(zOrder);
00223                                         
00224                                         if(zOrder > m_lZOrder && pSiblingSite->IsSiteVisible())
00225                                         {
00226                                                 pSiblingSite->SubtractSite(m_pRegionWithoutChildren);
00227                                         }
00228                                 }
00229                         }
00230                 }
00231 
00232                 m_pRegion = RMACreateRegion();
00233                 RMAUnionRegion(m_pRegion, m_pRegionWithoutChildren, m_pRegion);
00234 
00235                 POSITION pos = m_pChildren.GetHeadPosition();
00236                 while(pos)
00237                 {
00238                         CRealMediaWindowlessSite* pChildSite = (CRealMediaWindowlessSite*)(IRMASite*)m_pChildren.GetNext(pos);
00239                         if(pChildSite->IsSiteVisible()) pChildSite->SubtractSite(m_pRegion);
00240                 }
00241         }
00242         else
00243         {
00244                 m_pRegionWithoutChildren = RMACreateRectRegion(0,0,0,0);
00245                 m_pRegion = RMACreateRectRegion(0,0,0,0);
00246         }
00247 
00248         if(pTempRegion && !RMAEqualRegion(m_pRegion, pTempRegion))
00249         {
00250                 ForceRedraw();
00251         }
00252 
00253         RMADestroyRegion(pTempRegion);
00254 }
00255 
00256 void CRealMediaWindowlessSite::SubtractSite(REGION* pRegion)
00257 {
00258         PNxPoint topLeft;
00259         memset(&topLeft, 0, sizeof(PNxPoint));
00260         GetTopLeft(&topLeft);
00261         
00262         REGION* pTempRegion = RMACreateRectRegion(topLeft.x, topLeft.y, topLeft.x + m_size.cx, topLeft.y + m_size.cy);
00263 
00264         RMASubtractRegion(pRegion, pTempRegion, pRegion);
00265         RMADestroyRegion(pTempRegion);
00266 }
00267 
00268 void CRealMediaWindowlessSite::UpdateZOrder(CRealMediaWindowlessSite* pUpdatedChildSite, INT32 lOldZOrder, INT32 lNewZOrder)
00269 {
00270         POSITION pos = m_pChildren.GetHeadPosition();
00271         while(pos)
00272         {
00273                 CRealMediaWindowlessSite* pSite = (CRealMediaWindowlessSite*)(IRMASite*)m_pChildren.GetNext(pos);
00274 
00275                 INT32 lItsOldZOrder;
00276                 pSite->GetZOrder(lItsOldZOrder);
00277 
00278                 if(pSite != pUpdatedChildSite)
00279                 {
00280                         if(lOldZOrder < lNewZOrder)
00281                         {
00282                                 if(lItsOldZOrder >= lOldZOrder && lItsOldZOrder < lNewZOrder)
00283                                 {
00284                                         pSite->SetInternalZOrder(lItsOldZOrder-1);
00285                                 }
00286                         }
00287                         else
00288                         {
00289                                 if(lItsOldZOrder >= lNewZOrder && lItsOldZOrder < lOldZOrder)
00290                                 {
00291                                         pSite->SetInternalZOrder(lItsOldZOrder+1);
00292                                 }
00293                         }
00294                 }
00295                 else
00296                 {
00297                         pSite->SetInternalZOrder(lNewZOrder);
00298                 }
00299         }
00300 }
00301 
00302 void CRealMediaWindowlessSite::SetInternalZOrder(INT32 lZOrder)
00303 {
00304         m_lZOrder = lZOrder;
00305 }
00306 
00307 // IRMASiteWindowless
00308 
00309 STDMETHODIMP CRealMediaWindowlessSite::EventOccurred(PNxEvent* /*IN*/ pEvent)
00310 {
00311         return PNR_NOTIMPL;  /* not necessary within our implementation */
00312 }
00313 
00314 STDMETHODIMP_(PNxWindow*) CRealMediaWindowlessSite::GetParentWindow()
00315 {
00316         return NULL;
00317 }
00318 
00319 // IRMASite
00320 
00321 STDMETHODIMP CRealMediaWindowlessSite::AttachUser(IRMASiteUser* /*IN*/ pUser)
00322 {
00323         HRESULT hr = PNR_FAIL;
00324 
00325         if(m_pUser) return PNR_UNEXPECTED;
00326 
00327         if(CComQIPtr<IRMASite, &IID_IRMASite> pOuterSite = GetOwner())
00328                 hr = pUser->AttachSite(pOuterSite);
00329         
00330         if(PNR_OK == hr)
00331                 m_pUser = pUser;
00332 
00333         return hr;
00334 }
00335 
00336 STDMETHODIMP CRealMediaWindowlessSite::DetachUser()
00337 {
00338         HRESULT hr = PNR_OK;
00339 
00340         if(!m_pUser) return PNR_UNEXPECTED;
00341 
00342         hr = m_pUser->DetachSite();
00343 
00344         if(PNR_OK == hr)
00345                 m_pUser = NULL;
00346 
00347         return hr;
00348 }
00349 
00350 STDMETHODIMP CRealMediaWindowlessSite::GetUser(REF(IRMASiteUser*) /*OUT*/ pUser)
00351 {
00352         HRESULT hr = PNR_OK;
00353 
00354         if(!m_pUser) return PNR_UNEXPECTED;
00355 
00356         (pUser = m_pUser)->AddRef();
00357 
00358         return hr;
00359 }
00360 
00361 STDMETHODIMP CRealMediaWindowlessSite::CreateChild(REF(IRMASite*) /*OUT*/ pChildSite)
00362 {
00363         HRESULT hr = PNR_OK;
00364 
00365         CComPtr<IRMASite> pSite = 
00366                 (IRMASite*)new CRealMediaWindowlessSite(hr, m_pContext, this);
00367 
00368         if(FAILED(hr) || !pSite)
00369                 return E_FAIL;
00370 
00371         pChildSite = pSite.Detach();
00372 
00373         m_pChildren.AddTail(pChildSite);
00374 
00375         return hr;
00376 }
00377 
00378 STDMETHODIMP CRealMediaWindowlessSite::DestroyChild(IRMASite* /*IN*/ pChildSite)
00379 {
00380         if(POSITION pos = m_pChildren.Find(pChildSite))
00381         {
00382                 m_pChildren.RemoveAt(pos);
00383                 return PNR_OK;
00384         }
00385 
00386         return PNR_UNEXPECTED;
00387 }
00388 
00389 STDMETHODIMP CRealMediaWindowlessSite::AttachWatcher(IRMASiteWatcher* /*IN*/ pWatcher)
00390 {
00391         if(m_pWatcher) return PNR_UNEXPECTED;
00392 
00393         if(m_pWatcher = pWatcher)
00394                 m_pWatcher->AttachSite((IRMASite*)this);
00395 
00396         return PNR_OK;
00397 }
00398 
00399 STDMETHODIMP CRealMediaWindowlessSite::DetachWatcher()
00400 {
00401         if(!m_pWatcher) return PNR_UNEXPECTED;
00402 
00403         m_pWatcher->DetachSite();
00404         m_pWatcher = NULL;
00405 
00406         return PNR_OK;
00407 }
00408 
00409 STDMETHODIMP CRealMediaWindowlessSite::SetPosition(PNxPoint position)
00410 {
00411         HRESULT hr = PNR_OK;
00412 
00413         if(m_pWatcher)
00414         {
00415                 hr = m_pWatcher->ChangingPosition(m_position, position);
00416         }
00417 
00418         if(PNR_OK == hr)
00419         {
00420                 m_position = position;
00421 
00422                 POSITION pos = m_pPassiveWatchers.GetHeadPosition();
00423                 while(pos) m_pPassiveWatchers.GetNext(pos)->PositionChanged(&position);
00424 
00425                 RecomputeRegion();
00426         }
00427 
00428         return hr;
00429 }
00430 
00431 STDMETHODIMP CRealMediaWindowlessSite::GetPosition(REF(PNxPoint) position)
00432 {
00433         position = m_position;
00434         return PNR_OK;
00435 }
00436 
00437 STDMETHODIMP CRealMediaWindowlessSite::SetSize(PNxSize size)
00438 {
00439         HRESULT hr = PNR_OK;
00440 
00441         if(m_pWatcher)
00442         {
00443                 hr = m_pWatcher->ChangingSize(m_size, size);
00444         }
00445 
00446         if(PNR_OK == hr && size.cx != 0 && size.cy != 0)
00447         {
00448                 m_size = size;
00449 
00450                 POSITION pos = m_pPassiveWatchers.GetHeadPosition();
00451                 while(pos) m_pPassiveWatchers.GetNext(pos)->SizeChanged(&size);
00452 
00453                 RecomputeRegion();
00454         }
00455 
00456         return hr;
00457 }
00458 
00459 STDMETHODIMP CRealMediaWindowlessSite::GetSize(REF(PNxSize) size)
00460 {
00461         size = m_size;
00462         return PNR_OK;
00463 }
00464 
00465 STDMETHODIMP CRealMediaWindowlessSite::DamageRect(PNxRect rect)
00466 {
00467         m_fDamaged = TRUE;
00468         return PNR_OK;
00469 }
00470 
00471 STDMETHODIMP CRealMediaWindowlessSite::DamageRegion(PNxRegion region)
00472 {
00473         m_fDamaged = TRUE;
00474         return PNR_OK;
00475 }
00476 
00477 STDMETHODIMP CRealMediaWindowlessSite::ForceRedraw()
00478 {
00479         // make sure we have a visible window and are not re-enterering and we have damage
00480         if(!m_fInRedraw && m_fDamaged && m_fIsVisible)
00481         {
00482                 m_fInRedraw = TRUE; 
00483                 
00484                 PNxEvent event = {RMA_SURFACE_UPDATE, NULL, (IRMAVideoSurface*)this, NULL, 0, 0};
00485                 m_pUser->HandleEvent(&event);
00486                 
00487                 m_fInRedraw = FALSE;
00488                 m_fDamaged = FALSE;
00489         }
00490         
00491         return PNR_OK;
00492 }
00493 
00494 // IRMASite2
00495 
00496 STDMETHODIMP CRealMediaWindowlessSite::UpdateSiteWindow(PNxWindow* /*IN*/ pWindow)
00497 {
00498         return PNR_OK;
00499 }
00500 
00501 STDMETHODIMP CRealMediaWindowlessSite::ShowSite(BOOL bShow)
00502 {
00503         m_fIsVisible = !!bShow;
00504         RecomputeRegion();
00505         return PNR_OK;
00506 }
00507 
00508 STDMETHODIMP_(BOOL) CRealMediaWindowlessSite::IsSiteVisible()
00509 {
00510         BOOL fIsVisible = m_fIsVisible;
00511         if(m_pParentSite) fIsVisible = fIsVisible && m_pParentSite->IsSiteVisible();
00512         return fIsVisible;
00513 }
00514 
00515 STDMETHODIMP CRealMediaWindowlessSite::SetZOrder(INT32 lZOrder)
00516 {
00517         if(!m_pParentSite) return PNR_UNEXPECTED;
00518 
00519         if(lZOrder == -1 || lZOrder >= (INT32)m_pParentSite->GetNumberOfChildSites())
00520                 lZOrder = m_pParentSite->GetNumberOfChildSites() - 1; 
00521         
00522         if(m_lZOrder != lZOrder)
00523                 m_pParentSite->UpdateZOrder(this, m_lZOrder, lZOrder);
00524 
00525         m_lZOrder = lZOrder;
00526 
00527         return PNR_OK;
00528 }
00529 
00530 STDMETHODIMP CRealMediaWindowlessSite::GetZOrder(REF(INT32) lZOrder)
00531 {
00532         if(!m_pParentSite) return PNR_UNEXPECTED;
00533         lZOrder = m_lZOrder;
00534         return PNR_OK;
00535 }
00536 
00537 STDMETHODIMP CRealMediaWindowlessSite::MoveSiteToTop()
00538 {
00539         if(!m_pParentSite) return PNR_UNEXPECTED;
00540         return PNR_NOTIMPL;
00541 }
00542 
00543 STDMETHODIMP CRealMediaWindowlessSite::GetVideoSurface(REF(IRMAVideoSurface*) pSurface)
00544 {
00545         (pSurface = (IRMAVideoSurface*)this)->AddRef();
00546         return PNR_OK;
00547 }
00548 
00549 STDMETHODIMP_(UINT32) CRealMediaWindowlessSite::GetNumberOfChildSites()
00550 {
00551         return (UINT32)m_pChildren.GetCount();
00552 }
00553 
00554 STDMETHODIMP CRealMediaWindowlessSite::AddPassiveSiteWatcher(IRMAPassiveSiteWatcher* pWatcher)
00555 {
00556         m_pPassiveWatchers.AddTail(pWatcher);
00557         return PNR_OK;
00558 }
00559 
00560 STDMETHODIMP CRealMediaWindowlessSite::RemovePassiveSiteWatcher(IRMAPassiveSiteWatcher* pWatcher)
00561 {
00562         if(POSITION pos = m_pPassiveWatchers.Find(pWatcher))
00563         {
00564                 m_pPassiveWatchers.RemoveAt(pos);
00565                 return PNR_OK;
00566         }
00567 
00568         return PNR_UNEXPECTED;
00569 }
00570 
00571 STDMETHODIMP CRealMediaWindowlessSite::SetCursor(PNxCursor cursor, REF(PNxCursor) oldCursor)
00572 {
00573         return PNR_NOTIMPL;
00574 }
00575 
00576 // private
00577 
00578 void CRealMediaWindowlessSite::IntersectRect(PNxRect* pRect, PNxRect* pBox, PNxRect* pRetVal)
00579 {
00580         pRetVal->left   = max(pRect->left, pBox->left);
00581         pRetVal->top    = max(pRect->top, pBox->top);
00582         pRetVal->right  = min(pRect->right, pBox->right);
00583         pRetVal->bottom = min(pRect->bottom, pBox->bottom);
00584 }
00585 
00586 // protected
00587 
00588 bool CRealMediaWindowlessSite::GetBltService(IRMAVideoSurface** ppBltService)
00589 {
00590         bool fRet = false;
00591 
00592         if(ppBltService)
00593         {
00594                 if(m_pParentSite)
00595                 {
00596                         fRet = m_pParentSite->GetBltService(ppBltService);
00597             }
00598             else if(m_pBltService)
00599                 {
00600                         (*ppBltService = m_pBltService)->AddRef();
00601                         fRet = true;
00602                 }
00603         }
00604        
00605         return(fRet);
00606 }
00607 
00608 void CRealMediaWindowlessSite::SetBltService(IRMAVideoSurface* pBltService)
00609 {
00610         m_pBltService = pBltService; 
00611 }
00612 
00613 // IRMAVideoSurface
00614 
00615 STDMETHODIMP CRealMediaWindowlessSite::Blt(UCHAR*       /*IN*/ pImageData, RMABitmapInfoHeader* /*IN*/ pBitmapInfo, REF(PNxRect) /*IN*/ inDestRect, REF(PNxRect) /*IN*/ inSrcRect)
00616 {
00617         BeginOptimizedBlt(pBitmapInfo);
00618         return OptimizedBlt(pImageData, inDestRect, inSrcRect);
00619 }
00620 
00621 STDMETHODIMP CRealMediaWindowlessSite::BeginOptimizedBlt(RMABitmapInfoHeader* /*IN*/ pBitmapInfo)
00622 {
00623         if(memcmp(&m_bitmapInfo, pBitmapInfo, sizeof(RMABitmapInfoHeader)))
00624         {
00625                 memcpy(&m_bitmapInfo, pBitmapInfo, sizeof(RMABitmapInfoHeader));
00626 
00627         // format of image has changed somehow.
00628                 // do something here if this affects you.
00629         }
00630 
00631 /*
00632         CComPtr<IRMAVideoSurface> pBltService;
00633         GetBltService(&pBltService);
00634         if(!pBltService)
00635                 return PNR_UNEXPECTED;
00636 
00637         RMA_COMPRESSION_TYPE ulType = (RMA_COMPRESSION_TYPE)-1;
00638         pBltService->GetPreferredFormat(ulType);
00639 
00640         if(pBitmapInfo->biCompression != ulType)
00641                 return PNR_UNEXPECTED;
00642 */
00643         return PNR_OK;
00644 }
00645 
00646 STDMETHODIMP CRealMediaWindowlessSite::OptimizedBlt(UCHAR* /*IN*/ pImageBits, REF(PNxRect) /*IN*/ rDestRect, REF(PNxRect) /*IN*/ rSrcRect)
00647 {
00648         CComPtr<IRMAVideoSurface> pBltService;
00649         GetBltService(&pBltService);
00650 
00651         REGION* pRegion = GetRegion();
00652 
00653         if(!pBltService || !pRegion)
00654                 return PNR_UNEXPECTED;
00655 
00656         PNxPoint origin;
00657         memset(&origin, 0, sizeof(PNxPoint));
00658         GetTopLeft(&origin);
00659         PNxRect adjustedDestRect;
00660         adjustedDestRect.left   = rDestRect.left + origin.x;
00661         adjustedDestRect.top    = rDestRect.top + origin.y;
00662         adjustedDestRect.right  = rDestRect.right + origin.x;
00663         adjustedDestRect.bottom = rDestRect.bottom + origin.y;
00664 
00665         for(int i = 0; i < pRegion->numRects; i++)
00666         {
00667                 PNxRect* pRect = pRegion->rects+i;
00668                 
00669                 // intersect the dest rect with the rect from the
00670                 // region to get the final dest rect.
00671                 PNxRect finalDestRect;
00672                 IntersectRect(&adjustedDestRect, pRect, &finalDestRect);
00673 
00674         // now compute the src rect for this blt.
00675                 double xStretch = (double) (rDestRect.right - rDestRect.left) / (double) (rSrcRect.right - rSrcRect.left);
00676                 double yStretch = (double) (rDestRect.bottom - rDestRect.top) / (double) (rSrcRect.bottom - rSrcRect.top);
00677 
00678                 PNxRect finalSrcRect;
00679                 finalSrcRect.left   = (INT32)((double)(finalDestRect.left-origin.x) / xStretch + 0.5);
00680                 finalSrcRect.top    = (INT32)((double)(finalDestRect.top-origin.y)      / yStretch + 0.5);
00681                 finalSrcRect.right  = (INT32)((double)(finalDestRect.right-origin.x) / xStretch + 0.5);
00682                 finalSrcRect.bottom = (INT32)((double)(finalDestRect.bottom-origin.y) / yStretch + 0.5);
00683 
00684                 pBltService->Blt(pImageBits, &m_bitmapInfo, finalDestRect, finalSrcRect);
00685         }
00686 
00687         return PNR_OK;
00688 }
00689 
00690 STDMETHODIMP CRealMediaWindowlessSite::EndOptimizedBlt()
00691 {
00692         memset(&m_bitmapInfo, 0, sizeof(m_bitmapInfo));
00693         return PNR_OK;
00694 }
00695 
00696 STDMETHODIMP CRealMediaWindowlessSite::GetOptimizedFormat(REF(RMA_COMPRESSION_TYPE) /*OUT*/ ulType)
00697 {
00698         ulType =  m_bitmapInfo.biCompression;
00699         return PNR_OK;
00700 }
00701 
00702 STDMETHODIMP CRealMediaWindowlessSite::GetPreferredFormat(REF(RMA_COMPRESSION_TYPE) /*OUT*/ ulType)
00703 {
00704         CComPtr<IRMAVideoSurface> pBltService;
00705         GetBltService(&pBltService);
00706         if(!pBltService)
00707                 return PNR_UNEXPECTED;
00708 
00709         return pBltService->GetPreferredFormat(ulType);
00710 }

Generated on Tue Dec 13 14:47:03 2005 for guliverkli by  doxygen 1.4.5