зеркало из https://github.com/mozilla/gecko-dev.git
Support aggregation (sort of)
This commit is contained in:
Родитель
297b3bbfcf
Коммит
cc9e6f290f
|
@ -155,6 +155,7 @@ protected:
|
|||
nsIContentViewer* mContentViewer;
|
||||
nsIDeviceContext* mDeviceContext;
|
||||
nsIWidget* mWindow;
|
||||
nsISupports* mInnerWindow;
|
||||
nsIDocumentLoader* mDocLoader;
|
||||
|
||||
nsIWebShell* mParent;
|
||||
|
@ -206,6 +207,8 @@ nsWebShell::nsWebShell()
|
|||
|
||||
nsWebShell::~nsWebShell()
|
||||
{
|
||||
NS_IF_RELEASE(mInnerWindow);
|
||||
|
||||
NS_IF_RELEASE(mContentViewer);
|
||||
NS_IF_RELEASE(mContainer);
|
||||
|
||||
|
@ -262,6 +265,9 @@ nsWebShell::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
if (nsnull != mInnerWindow) {
|
||||
return mInnerWindow->QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
@ -324,7 +330,8 @@ nsWebShell::Init(nsNativeWidget aNativeParent,
|
|||
WEB_TRACE(WEB_TRACE_CALLS,
|
||||
("nsWebShell::Init: this=%p", this));
|
||||
|
||||
nsresult rv = NSRepository::CreateInstance(kDocumentLoaderCID, nsnull,
|
||||
nsresult rv = NSRepository::CreateInstance(kDocumentLoaderCID,
|
||||
nsnull,
|
||||
kIDocumentLoaderIID,
|
||||
(void**)&mDocLoader);
|
||||
|
||||
|
@ -347,13 +354,23 @@ nsWebShell::Init(nsNativeWidget aNativeParent,
|
|||
mDeviceContext->SetGamma(1.7f);
|
||||
|
||||
// Create a Native window for the shell container...
|
||||
rv = NSRepository::CreateInstance(kChildCID, nsnull, kIWidgetIID,
|
||||
(void**)&mWindow);
|
||||
rv = NSRepository::CreateInstance(kChildCID,
|
||||
(nsISupports*)((nsIWebShell*)this),
|
||||
kISupportsIID,
|
||||
(void**)&mInnerWindow);
|
||||
if (NS_OK != rv) {
|
||||
goto done;
|
||||
}
|
||||
mInnerWindow->QueryInterface(kIWidgetIID, (void**) &mWindow);
|
||||
if (NS_OK != rv) {
|
||||
NS_RELEASE(mInnerWindow);
|
||||
}
|
||||
else {
|
||||
// Get rid of extra reference count
|
||||
mWindow->Release();
|
||||
mWindow->Create(aNativeParent, aBounds, nsWebShell::HandleEvent,
|
||||
mDeviceContext, nsnull);
|
||||
}
|
||||
|
||||
done:
|
||||
return rv;
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
static NS_DEFINE_IID(kChildCID, NS_CHILD_CID);
|
||||
static NS_DEFINE_IID(kThrobberCID, NS_THROBBER_CID);
|
||||
|
||||
static NS_DEFINE_IID(kIChildWidgetIID, NS_IWIDGET_IID);
|
||||
static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID);
|
||||
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
||||
static NS_DEFINE_IID(kIImageObserverIID, NS_IIMAGEREQUESTOBSERVER_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
@ -46,9 +46,12 @@ static NS_DEFINE_IID(kIThrobberIID, NS_ITHROBBER_IID);
|
|||
|
||||
static nsVoidArray gThrobbers;
|
||||
|
||||
#define INNER_OUTER \
|
||||
((nsThrobber*)((char*)this - offsetof(nsThrobber, mInner)))
|
||||
|
||||
class nsThrobber : public nsIThrobber {
|
||||
public:
|
||||
nsThrobber();
|
||||
nsThrobber(nsISupports* aOuter);
|
||||
|
||||
void* operator new(size_t sz) {
|
||||
void* rv = new char[sz];
|
||||
|
@ -78,11 +81,65 @@ public:
|
|||
PRInt32 mWidth;
|
||||
PRInt32 mHeight;
|
||||
nsIWidget* mWidget;
|
||||
nsISupports* mInnerWidget;
|
||||
nsVoidArray* mImages;
|
||||
PRInt32 mIndex;
|
||||
nsIImageGroup* mImageGroup;
|
||||
nsITimer* mTimer;
|
||||
PRBool mRunning;
|
||||
|
||||
nsISupports *mOuter;
|
||||
|
||||
nsrefcnt AddRefObject() {
|
||||
return ++mRefCnt;
|
||||
}
|
||||
|
||||
nsrefcnt ReleaseObject() {
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release");
|
||||
if (--mRefCnt == 0) {
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
nsresult QueryObject(const nsIID& aIID, void** aInstancePtr) {
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (aIID.Equals(kIThrobberIID)) {
|
||||
*aInstancePtr = (void*)(nsIThrobber*)this;
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(kISupportsIID)) {
|
||||
*aInstancePtr = (void*)(nsISupports*)this;
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
if (nsnull != mInnerWidget) {
|
||||
return mInnerWidget->QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
// This is used when we are not aggregated in
|
||||
class InnerSupport : public nsISupports {
|
||||
public:
|
||||
InnerSupport() {}
|
||||
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr) {
|
||||
return INNER_OUTER->QueryObject(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
NS_IMETHOD_(nsrefcnt) AddRef() {
|
||||
return INNER_OUTER->AddRefObject();
|
||||
}
|
||||
|
||||
NS_IMETHOD_(nsrefcnt) Release() {
|
||||
return INNER_OUTER->ReleaseObject();
|
||||
}
|
||||
} mInner;
|
||||
};
|
||||
|
||||
class ThrobObserver : public nsIImageRequestObserver {
|
||||
|
@ -212,17 +269,40 @@ HandleThrobberEvent(nsGUIEvent *aEvent)
|
|||
//----------------------------------------------------------------------
|
||||
|
||||
// Note: operator new zeros our memory
|
||||
nsThrobber::nsThrobber()
|
||||
nsThrobber::nsThrobber(nsISupports* aOuter)
|
||||
{
|
||||
// assign outer
|
||||
if (aOuter)
|
||||
mOuter = aOuter;
|
||||
else
|
||||
mOuter = &mInner;
|
||||
|
||||
AddThrobber(this);
|
||||
}
|
||||
|
||||
nsThrobber::~nsThrobber()
|
||||
{
|
||||
NS_IF_RELEASE(mInnerWidget);
|
||||
RemoveThrobber(this);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsThrobber, kIThrobberIID);
|
||||
nsrefcnt
|
||||
nsThrobber::AddRef()
|
||||
{
|
||||
return mOuter->AddRef();
|
||||
}
|
||||
|
||||
nsrefcnt
|
||||
nsThrobber::Release()
|
||||
{
|
||||
return mOuter->Release();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThrobber::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
return mOuter->QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThrobber::Init(nsIWidget* aParent, const nsRect& aBounds)
|
||||
|
@ -231,14 +311,22 @@ nsThrobber::Init(nsIWidget* aParent, const nsRect& aBounds)
|
|||
mHeight = aBounds.height;
|
||||
|
||||
// Create widget
|
||||
nsresult rv = NSRepository::CreateInstance(kChildCID, nsnull,
|
||||
kIChildWidgetIID,
|
||||
(void**)&mWidget);
|
||||
nsresult rv = NSRepository::CreateInstance(kChildCID,
|
||||
this,
|
||||
kISupportsIID,
|
||||
(void**)&mInnerWidget);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mInnerWidget->QueryInterface(kIWidgetIID, (void**) &mWidget);
|
||||
if (NS_OK != rv) {
|
||||
NS_RELEASE(mInnerWidget);
|
||||
}
|
||||
else {
|
||||
// Get rid of extra reference count
|
||||
mWidget->Release();
|
||||
mWidget->Create(aParent, aBounds, HandleThrobberEvent, NULL);
|
||||
}
|
||||
|
||||
return LoadThrobberImages();
|
||||
}
|
||||
|
@ -492,12 +580,8 @@ nsThrobberFactory::CreateInstance(nsISupports *aOuter,
|
|||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
*aResult = NULL;
|
||||
if (nsnull != aOuter) {
|
||||
rv = NS_ERROR_NO_AGGREGATION;
|
||||
goto done;
|
||||
}
|
||||
|
||||
inst = new nsThrobber();
|
||||
inst = new nsThrobber(aOuter);
|
||||
if (inst == NULL) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
goto done;
|
||||
|
|
|
@ -155,6 +155,7 @@ protected:
|
|||
nsIContentViewer* mContentViewer;
|
||||
nsIDeviceContext* mDeviceContext;
|
||||
nsIWidget* mWindow;
|
||||
nsISupports* mInnerWindow;
|
||||
nsIDocumentLoader* mDocLoader;
|
||||
|
||||
nsIWebShell* mParent;
|
||||
|
@ -206,6 +207,8 @@ nsWebShell::nsWebShell()
|
|||
|
||||
nsWebShell::~nsWebShell()
|
||||
{
|
||||
NS_IF_RELEASE(mInnerWindow);
|
||||
|
||||
NS_IF_RELEASE(mContentViewer);
|
||||
NS_IF_RELEASE(mContainer);
|
||||
|
||||
|
@ -262,6 +265,9 @@ nsWebShell::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
if (nsnull != mInnerWindow) {
|
||||
return mInnerWindow->QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
@ -324,7 +330,8 @@ nsWebShell::Init(nsNativeWidget aNativeParent,
|
|||
WEB_TRACE(WEB_TRACE_CALLS,
|
||||
("nsWebShell::Init: this=%p", this));
|
||||
|
||||
nsresult rv = NSRepository::CreateInstance(kDocumentLoaderCID, nsnull,
|
||||
nsresult rv = NSRepository::CreateInstance(kDocumentLoaderCID,
|
||||
nsnull,
|
||||
kIDocumentLoaderIID,
|
||||
(void**)&mDocLoader);
|
||||
|
||||
|
@ -347,13 +354,23 @@ nsWebShell::Init(nsNativeWidget aNativeParent,
|
|||
mDeviceContext->SetGamma(1.7f);
|
||||
|
||||
// Create a Native window for the shell container...
|
||||
rv = NSRepository::CreateInstance(kChildCID, nsnull, kIWidgetIID,
|
||||
(void**)&mWindow);
|
||||
rv = NSRepository::CreateInstance(kChildCID,
|
||||
(nsISupports*)((nsIWebShell*)this),
|
||||
kISupportsIID,
|
||||
(void**)&mInnerWindow);
|
||||
if (NS_OK != rv) {
|
||||
goto done;
|
||||
}
|
||||
mInnerWindow->QueryInterface(kIWidgetIID, (void**) &mWindow);
|
||||
if (NS_OK != rv) {
|
||||
NS_RELEASE(mInnerWindow);
|
||||
}
|
||||
else {
|
||||
// Get rid of extra reference count
|
||||
mWindow->Release();
|
||||
mWindow->Create(aNativeParent, aBounds, nsWebShell::HandleEvent,
|
||||
mDeviceContext, nsnull);
|
||||
}
|
||||
|
||||
done:
|
||||
return rv;
|
||||
|
|
Загрузка…
Ссылка в новой задаче