📄 hxmisus.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxcom.h"
#include "hxtypes.h"
#include "hxwintyp.h"
#include "hxslist.h"
#include "hxwin.h"
#include "hxengin.h"
#include "hxsite2.h"
#include "ihxpckts.h"
#include "hxvsurf.h"
#include "hxmisus.h"
#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#endif
/************************************************************************
* Method:
* Constructor
*/
CHXMultiInstanceSiteUserSupplier::CHXMultiInstanceSiteUserSupplier()
: m_lRefCount(0)
, m_pSingleUser(NULL)
, m_bIsAttached(FALSE)
, m_pSurfaceBitmapInfo(NULL)
, m_bSetSizeHasBeenCalled(FALSE)
, m_bSetPositionHasBeenCalled(FALSE)
, m_bSetZOrderHasBeenCalled(FALSE)
, m_zorder(0)
, m_bIsInterrupSafe(FALSE)
{
m_size.cx = 0;
m_size.cy = 0;
m_position.x = 0;
m_position.y = 0;
m_pSurfaceBitmapInfo = 0;
}
/************************************************************************
* Method:
* Destructor
*/
CHXMultiInstanceSiteUserSupplier::~CHXMultiInstanceSiteUserSupplier()
{
CHXSimpleList::Iterator ndx = m_PassiveSiteWatchers.Begin();
for (; ndx != m_PassiveSiteWatchers.End(); ++ndx)
{
IHXPassiveSiteWatcher* pWatcher =
(IHXPassiveSiteWatcher*)(*ndx);
delete pWatcher;
}
m_PassiveSiteWatchers.RemoveAll();
HX_DELETE (m_pSurfaceBitmapInfo);
}
/************************************************************************
* Method:
* IUnknown::QueryInterface
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::QueryInterface(REFIID riid, void** ppvObj)
{
if (IsEqualIID(riid, IID_IHXVideoSurface2))
{
// All of our target site surfaces must support IHXVideoSurface2
// for this QI to succeed; this is required both for the proxy logic
// in this class as well as to signal to the renderer that it's using
// and old or 3rd party site.
CHXSimpleList::Iterator i = m_SiteUsers.Begin();
if (i != m_SiteUsers.End())
{
CHXMultiInstanceSiteUser* pSiteUser = (CHXMultiInstanceSiteUser*)(*i);
if (pSiteUser->m_pSite2)
{
IHXVideoSurface* pFirstSurface;
if (HXR_OK == pSiteUser->m_pSite2->GetVideoSurface(pFirstSurface))
{
IHXVideoSurface* pSecondSurface;
if (HXR_OK == pFirstSurface->QueryInterface(riid, (void**) &pSecondSurface))
{
HX_RELEASE(pFirstSurface);
HX_RELEASE(pSecondSurface);
AddRef();
*ppvObj = (IUnknown*)(IHXVideoSurface2*)this;
return HXR_OK;
}
HX_RELEASE(pFirstSurface);
}
}
}
}
QInterfaceList qiList[] =
{
{ GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXSite*)this },
{ GET_IIDHANDLE(IID_IHXVideoSurface), (IHXVideoSurface*) this },
{ GET_IIDHANDLE(IID_IHXSite), (IHXSite*) this },
{ GET_IIDHANDLE(IID_IHXSite2), (IHXSite2*) this },
{ GET_IIDHANDLE(IID_IHXSiteEnumerator), (IHXSiteEnumerator*) this },
{ GET_IIDHANDLE(IID_IHXSiteUserSupplier), (IHXSiteUserSupplier*) this },
{ GET_IIDHANDLE(IID_IHXMultiInstanceSiteUserSupplier), (IHXMultiInstanceSiteUserSupplier*) this },
{ GET_IIDHANDLE(IID_IHXInterruptSafe), (IHXInterruptSafe*) this },
};
if (QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj) == HXR_OK)
{
return HXR_OK;
}
else if (IsEqualIID(riid, IID_IHXValues)) //XXXCXZ
{
if (m_pSingleUser)
{
return m_pSingleUser->QueryInterface(IID_IHXValues, ppvObj);
}
}
else if (IsEqualIID(riid, IID_IHXSiteWindowless))
{
// check if the underlying implementation is the new one!
CHXSimpleList::Iterator i = m_SiteUsers.Begin();
if(i != m_SiteUsers.End())
{
CHXMultiInstanceSiteUser* pSiteUser =
(CHXMultiInstanceSiteUser*)(*i);
if (pSiteUser->m_pSite)
{
return pSiteUser->m_pSite->QueryInterface(riid, ppvObj);
}
}
}
else if (IsEqualIID(riid, IID_IHXSubRectSite))
{
//Check to see if this site support this new interface....
CHXSimpleList::Iterator i = m_SiteUsers.Begin();
if(i != m_SiteUsers.End())
{
CHXMultiInstanceSiteUser* pSiteUser = (CHXMultiInstanceSiteUser*)(*i);
if(pSiteUser->m_pSite)
{
return pSiteUser->m_pSite->QueryInterface(riid, ppvObj);
}
}
}
else if (IsEqualIID(riid, IID_IHXKeyBoardFocus))
{
CHXSimpleList::Iterator i = m_SiteUsers.Begin();
if(i != m_SiteUsers.End())
{
CHXMultiInstanceSiteUser* pSiteUser = (CHXMultiInstanceSiteUser*)(*i);
if(pSiteUser->m_pSite)
{
// Return fhe first we find:
if (SUCCEEDED(pSiteUser->m_pSite->QueryInterface(riid, ppvObj)))
{
return HXR_OK;
}
}
}
}
*ppvObj = NULL;
return HXR_NOINTERFACE;
}
/************************************************************************
* Method:
* IUnknown::AddRef
*/
STDMETHODIMP_(ULONG32)
CHXMultiInstanceSiteUserSupplier::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
/************************************************************************
* Method:
* IUnknown::Release
*/
STDMETHODIMP_(ULONG32)
CHXMultiInstanceSiteUserSupplier::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
/************************************************************************
* Method:
* IHXSite::AttachUser
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::AttachUser(IHXSiteUser* /*IN*/ pUser)
{
return HXR_NOTIMPL;
}
/************************************************************************
* Method:
* IHXSite::DetachUser
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::DetachUser()
{
return HXR_NOTIMPL;
}
/************************************************************************
* Method:
* IHXSite::GetUser
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::GetUser(REF(IHXSiteUser*) /*OUT*/ pUser)
{
return HXR_NOTIMPL;
}
/************************************************************************
* Method:
* IHXSite::CreateChild
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::CreateChild(REF(IHXSite*) /*OUT*/ pChildSite)
{
return HXR_NOTIMPL;
}
/************************************************************************
* Method:
* IHXSite::DestroyChild
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::DestroyChild(IHXSite* /*IN*/ pChildSite)
{
return HXR_NOTIMPL;
}
/************************************************************************
* Method:
* IHXSite::SetSize
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::SetSize(HXxSize size)
{
m_bSetSizeHasBeenCalled = TRUE;
m_size = size;
CHXSimpleList::Iterator i = m_SiteUsers.Begin();
for ( ; i != m_SiteUsers.End(); ++i)
{
CHXMultiInstanceSiteUser* pSiteUser =
(CHXMultiInstanceSiteUser*)(*i);
pSiteUser->m_pSite->SetSize(size);
}
CHXSimpleList::Iterator ndx = m_PassiveSiteWatchers.Begin();
for (; ndx != m_PassiveSiteWatchers.End(); ++ndx)
{
IHXPassiveSiteWatcher* pWatcher =
(IHXPassiveSiteWatcher*)(*ndx);
pWatcher->SizeChanged(&size);
}
return HXR_OK;
}
/************************************************************************
* Method:
* IHXSite::SetPosition
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::SetPosition(HXxPoint position)
{
m_bSetPositionHasBeenCalled = TRUE;
m_position = position;
CHXSimpleList::Iterator i = m_SiteUsers.Begin();
for ( ; i != m_SiteUsers.End(); ++i)
{
CHXMultiInstanceSiteUser* pSiteUser =
(CHXMultiInstanceSiteUser*)(*i);
pSiteUser->m_pSite->SetPosition(position);
}
CHXSimpleList::Iterator ndx = m_PassiveSiteWatchers.Begin();
for (; ndx != m_PassiveSiteWatchers.End(); ++ndx)
{
IHXPassiveSiteWatcher* pWatcher =
(IHXPassiveSiteWatcher*)(*ndx);
pWatcher->PositionChanged(&position);
}
return HXR_OK;
}
/************************************************************************
* Method:
* IHXSite::GetSize
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::GetSize(REF(HXxSize) size)
{
// We assume the first instance has the correct size and position.
CHXSimpleList::Iterator i = m_SiteUsers.Begin();
if(i != m_SiteUsers.End())
{
CHXMultiInstanceSiteUser* pSiteUser =
(CHXMultiInstanceSiteUser*)(*i);
return pSiteUser->m_pSite->GetSize(size);
}
// If there is no actual instance, then use the cached size.
size = m_size;
return HXR_OK;
}
/************************************************************************
* Method:
* IHXSite::GetPosition
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::GetPosition(REF(HXxPoint) position)
{
// We assume the first instance has the correct size and position.
CHXSimpleList::Iterator i = m_SiteUsers.Begin();
if(i != m_SiteUsers.End())
{
CHXMultiInstanceSiteUser* pSiteUser =
(CHXMultiInstanceSiteUser*)(*i);
return pSiteUser->m_pSite->GetPosition(position);
}
// If there is no actual instance, then use the cached position
position = m_position;
return HXR_OK;
}
/************************************************************************
* Method:
* IHXSite::DamageRect
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::DamageRect(HXxRect rect)
{
/*
* Coding this loop like this instead of using an iterator
* makes things slightly more thread safe. This fixes the known
* repro cases for bug 3787.
*/
LISTPOSITION pos = m_SiteUsers.GetHeadPosition();
while(pos)
{
CHXMultiInstanceSiteUser* pSiteUser =
(CHXMultiInstanceSiteUser*)m_SiteUsers.GetNext(pos);
if (pSiteUser)
pSiteUser->m_pSite->DamageRect(rect);
}
return HXR_OK;
}
/************************************************************************
* Method:
* IHXSite::DamageRegion
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::DamageRegion(HXxRegion region)
{
/*
* Coding this loop like this instead of using an iterator
* makes things slightly more thread safe. This fixes the known
* repro cases for bug 3787.
*/
LISTPOSITION pos = m_SiteUsers.GetHeadPosition();
while(pos)
{
CHXMultiInstanceSiteUser* pSiteUser =
(CHXMultiInstanceSiteUser*)m_SiteUsers.GetNext(pos);
if (pSiteUser)
pSiteUser->m_pSite->DamageRegion(region);
}
return HXR_OK;
}
/************************************************************************
* Method:
* IHXSite::ForceRedraw
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::ForceRedraw()
{
/*
* Coding this loop like this instead of using an iterator
* makes things slightly more thread safe. This fixes the known
* repro cases for bug 3787.
*/
LISTPOSITION pos = m_SiteUsers.GetHeadPosition();
while(pos)
{
CHXMultiInstanceSiteUser* pSiteUser =
(CHXMultiInstanceSiteUser*)m_SiteUsers.GetNext(pos);
if (pSiteUser)
pSiteUser->m_pSite->ForceRedraw();
}
return HXR_OK;
}
/************************************************************************
* Method:
* IHXMultiInstanceSiteUserSupplier::SetSingleSiteUser
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::SetSingleSiteUser(IUnknown* pUnknown)
{
if (HXR_OK != pUnknown->QueryInterface(IID_IHXSiteUser,(void**)&m_pSingleUser))
{
return HXR_INVALID_PARAMETER;
}
return HXR_OK;
}
/************************************************************************
* Method:
* IHXMultiInstanceSiteUserSupplier::ReleaseSingleSiteUser
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::ReleaseSingleSiteUser()
{
HX_RELEASE(m_pSingleUser);
return HXR_OK;
}
/************************************************************************
* Method:
* IHXSiteUserSupplier::CreateSiteUser
*/
STDMETHODIMP
CHXMultiInstanceSiteUserSupplier::CreateSiteUser
(
REF(IHXSiteUser*)/*OUT*/ pSiteUser
)
{
CHXMultiInstanceSiteUser* pMISU = new CHXMultiInstanceSiteUser(this);
if (!pMISU)
{
return HXR_OUTOFMEMORY;
}
// This is our caller's ref.
pMISU->QueryInterface(IID_IHXSiteUser,(void**)&pSiteUser);
m_SiteUsers.AddTail(pSiteUser);
pSiteUser->AddRef(); // this is for the caller
return HXR_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -