- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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 }