mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-30 21:55:31 +00:00
923 lines
22 KiB
C++
923 lines
22 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "License"); you may not use this file except in
|
|
* compliance with the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS"
|
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
|
* the License for the specific language governing rights and limitations
|
|
* under the License.
|
|
*
|
|
* The Original Code is Mozilla Communicator client code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
|
* Netscape Communications Corporation. All Rights Reserved.
|
|
*/
|
|
#include "nscore.h"
|
|
#include "nsCRT.h"
|
|
#include "nsIContentViewer.h"
|
|
#include "nsIContentViewerContainer.h"
|
|
#include "nsIPluginHost.h"
|
|
#include "nsIPluginInstance.h"
|
|
#include "nsIStreamListener.h"
|
|
#include "nsIURL.h"
|
|
#ifdef NECKO
|
|
#include "nsIChannel.h"
|
|
#include "nsNeckoUtil.h"
|
|
#endif // NECKO
|
|
#include "nsIComponentManager.h"
|
|
#include "nsWidgetsCID.h"
|
|
#include "nsILinkHandler.h"
|
|
#include "nsIWebShell.h"
|
|
#include "nsIBrowserWindow.h"
|
|
#include "nsIContent.h"
|
|
#include "nsIDocument.h"
|
|
|
|
// Class IDs
|
|
static NS_DEFINE_IID(kChildWindowCID, NS_CHILD_CID);
|
|
static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID);
|
|
|
|
// Interface IDs
|
|
static NS_DEFINE_IID(kIContentViewerIID, NS_ICONTENT_VIEWER_IID);
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
static NS_DEFINE_IID(kIPluginHostIID, NS_IPLUGINHOST_IID);
|
|
static NS_DEFINE_IID(kIPluginInstanceOwnerIID, NS_IPLUGININSTANCEOWNER_IID);
|
|
static NS_DEFINE_IID(kILinkHandlerIID, NS_ILINKHANDLER_IID);
|
|
static NS_DEFINE_IID(kIStreamListenerIID, NS_ISTREAMLISTENER_IID);
|
|
static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID);
|
|
static NS_DEFINE_IID(kIBrowserWindowIID, NS_IBROWSER_WINDOW_IID);
|
|
static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
|
|
|
|
|
|
class PluginViewerImpl;
|
|
|
|
class PluginListener : public nsIStreamListener {
|
|
public:
|
|
PluginListener(PluginViewerImpl* aViewer);
|
|
virtual ~PluginListener();
|
|
|
|
// nsISupports
|
|
NS_DECL_ISUPPORTS
|
|
|
|
#ifdef NECKO
|
|
// nsIStreamObserver methods:
|
|
NS_IMETHOD OnStartRequest(nsIChannel* channel, nsISupports *ctxt);
|
|
NS_IMETHOD OnStopRequest(nsIChannel* channel, nsISupports *ctxt, nsresult status, const PRUnichar *errorMsg);
|
|
// nsIStreamListener methods:
|
|
NS_IMETHOD OnDataAvailable(nsIChannel* channel, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count);
|
|
#else
|
|
// nsIStreamListener
|
|
NS_IMETHOD OnStartRequest(nsIURI* aURL, const char *aContentType);
|
|
NS_IMETHOD OnProgress(nsIURI* aURL, PRUint32 aProgress, PRUint32 aProgressMax);
|
|
NS_IMETHOD OnStatus(nsIURI* aURL, const PRUnichar* aMsg);
|
|
NS_IMETHOD OnStopRequest(nsIURI* aURL, nsresult aStatus,
|
|
const PRUnichar* aMsg);
|
|
NS_IMETHOD GetBindInfo(nsIURI* aURL, nsStreamBindingInfo* aInfo);
|
|
NS_IMETHOD OnDataAvailable(nsIURI* aURL, nsIInputStream* aStream,
|
|
PRUint32 aCount);
|
|
#endif
|
|
|
|
PluginViewerImpl* mViewer;
|
|
nsIStreamListener* mNextStream;
|
|
};
|
|
|
|
class pluginInstanceOwner : public nsIPluginInstanceOwner {
|
|
public:
|
|
pluginInstanceOwner();
|
|
virtual ~pluginInstanceOwner();
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
//nsIPluginInstanceOwner interface
|
|
|
|
NS_IMETHOD SetInstance(nsIPluginInstance *aInstance);
|
|
|
|
NS_IMETHOD GetInstance(nsIPluginInstance *&aInstance);
|
|
|
|
NS_IMETHOD GetWindow(nsPluginWindow *&aWindow);
|
|
|
|
NS_IMETHOD GetMode(nsPluginMode *aMode);
|
|
|
|
NS_IMETHOD CreateWidget(void);
|
|
|
|
NS_IMETHOD GetURL(const char *aURL, const char *aTarget, void *aPostData);
|
|
|
|
NS_IMETHOD ShowStatus(const char *aStatusMsg);
|
|
|
|
NS_IMETHOD GetDocument(nsIDocument* *aDocument);
|
|
|
|
//locals
|
|
|
|
NS_IMETHOD Init(PluginViewerImpl *aViewer, nsIWidget *aWindow);
|
|
|
|
private:
|
|
nsPluginWindow mPluginWindow;
|
|
nsIPluginInstance *mInstance;
|
|
nsIWidget *mWindow; //we do not addref this...
|
|
PluginViewerImpl *mViewer; //we do not addref this...
|
|
};
|
|
|
|
class PluginViewerImpl : public nsIContentViewer
|
|
{
|
|
public:
|
|
PluginViewerImpl(const char* aCommand, nsIStreamListener** aDocListener);
|
|
|
|
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
|
|
|
// nsISupports
|
|
NS_DECL_ISUPPORTS
|
|
|
|
// nsIContentViewer
|
|
NS_IMETHOD Init(nsNativeWidget aParent,
|
|
nsIDeviceContext* aDeviceContext,
|
|
nsIPref* aPrefs,
|
|
const nsRect& aBounds,
|
|
nsScrollPreference aScrolling = nsScrollPreference_kAuto);
|
|
NS_IMETHOD BindToDocument(nsISupports* aDoc, const char* aCommand);
|
|
NS_IMETHOD SetContainer(nsIContentViewerContainer* aContainer);
|
|
NS_IMETHOD GetContainer(nsIContentViewerContainer*& aContainerResult);
|
|
NS_IMETHOD Stop(void);
|
|
NS_IMETHOD GetBounds(nsRect& aResult);
|
|
NS_IMETHOD SetBounds(const nsRect& aBounds);
|
|
NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
|
|
NS_IMETHOD Show();
|
|
NS_IMETHOD Hide();
|
|
NS_IMETHOD Print();
|
|
NS_IMETHOD PrintContent(nsIWebShell *aParent,nsIDeviceContext *aDContext);
|
|
NS_IMETHOD SetEnableRendering(PRBool aOn);
|
|
NS_IMETHOD GetEnableRendering(PRBool* aResult);
|
|
|
|
virtual ~PluginViewerImpl();
|
|
|
|
nsresult CreatePlugin(nsIPluginHost* aHost, const nsRect& aBounds,
|
|
nsIStreamListener*& aResult);
|
|
|
|
nsresult MakeWindow(nsNativeWidget aParent,
|
|
nsIDeviceContext* aDeviceContext,
|
|
const nsRect& aBounds);
|
|
|
|
#ifdef NECKO
|
|
nsresult StartLoad(nsIChannel* channel, nsIStreamListener*& aResult);
|
|
#else
|
|
nsresult StartLoad(nsIURI* aURL, const char* aContentType,
|
|
nsIStreamListener*& aResult);
|
|
#endif
|
|
|
|
void ForceRefresh(void);
|
|
|
|
#ifdef NECKO
|
|
nsresult GetURI(nsIURI* *aURI);
|
|
#else
|
|
nsresult GetURL(nsIURI *&aURL);
|
|
#endif
|
|
|
|
nsresult GetDocument(nsIDocument* *aDocument);
|
|
|
|
nsIWidget* mWindow;
|
|
nsIDocument* mDocument;
|
|
nsIContentViewerContainer* mContainer;
|
|
#ifdef NECKO
|
|
nsIChannel* mChannel;
|
|
#else
|
|
nsIURI* mURL;
|
|
nsString mContentType;
|
|
#endif
|
|
pluginInstanceOwner *mOwner;
|
|
PRBool mEnableRendering;
|
|
};
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
nsresult
|
|
NS_NewPluginContentViewer(const char* aCommand,
|
|
nsIStreamListener** aDocListener,
|
|
nsIContentViewer** aDocViewer)
|
|
{
|
|
PluginViewerImpl* it = new PluginViewerImpl(aCommand, aDocListener);
|
|
if (nsnull == it) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
return it->QueryInterface(kIContentViewerIID, (void**) aDocViewer);
|
|
}
|
|
|
|
// Note: operator new zeros our memory
|
|
PluginViewerImpl::PluginViewerImpl(const char* aCommand,
|
|
nsIStreamListener** aDocListener)
|
|
{
|
|
NS_INIT_REFCNT();
|
|
nsIStreamListener* it = new PluginListener(this);
|
|
*aDocListener = it;
|
|
mEnableRendering = PR_TRUE;
|
|
}
|
|
|
|
// ISupports implementation...
|
|
NS_IMPL_ADDREF(PluginViewerImpl)
|
|
NS_IMPL_RELEASE(PluginViewerImpl)
|
|
|
|
nsresult
|
|
PluginViewerImpl::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
{
|
|
if (NULL == aInstancePtr) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
if (aIID.Equals(kIContentViewerIID)) {
|
|
nsIContentViewer* tmp = this;
|
|
*aInstancePtr = (void*)tmp;
|
|
NS_ADDREF_THIS();
|
|
return NS_OK;
|
|
}
|
|
if (aIID.Equals(kISupportsIID)) {
|
|
nsISupports* tmp = this;
|
|
*aInstancePtr = (void*)tmp;
|
|
NS_ADDREF_THIS();
|
|
return NS_OK;
|
|
}
|
|
return NS_NOINTERFACE;
|
|
}
|
|
|
|
PluginViewerImpl::~PluginViewerImpl()
|
|
{
|
|
NS_IF_RELEASE(mOwner);
|
|
if (nsnull != mWindow) {
|
|
mWindow->Destroy();
|
|
NS_RELEASE(mWindow);
|
|
}
|
|
NS_IF_RELEASE(mDocument);
|
|
NS_IF_RELEASE(mContainer);
|
|
#ifdef NECKO
|
|
NS_IF_RELEASE(mChannel);
|
|
#else
|
|
NS_IF_RELEASE(mURL);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* This method is called by the Document Loader once a document has
|
|
* been created for a particular data stream... The content viewer
|
|
* must cache this document for later use when Init(...) is called.
|
|
*/
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::BindToDocument(nsISupports *aDoc, const char *aCommand)
|
|
{
|
|
#ifdef NS_DEBUG
|
|
printf("PluginViewerImpl::BindToDocument\n");
|
|
#endif
|
|
return aDoc->QueryInterface(kIDocumentIID, (void**)&mDocument);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::SetContainer(nsIContentViewerContainer* aContainer)
|
|
{
|
|
NS_IF_RELEASE(mContainer);
|
|
mContainer = aContainer;
|
|
NS_IF_ADDREF(mContainer);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::GetContainer(nsIContentViewerContainer*& aResult)
|
|
{
|
|
aResult = mContainer;
|
|
NS_IF_ADDREF(mContainer);
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Init(nsNativeWidget aNativeParent,
|
|
nsIDeviceContext* aDeviceContext,
|
|
nsIPref* aPrefs,
|
|
const nsRect& aBounds,
|
|
nsScrollPreference aScrolling)
|
|
{
|
|
nsresult rv = MakeWindow(aNativeParent, aDeviceContext, aBounds);
|
|
if (NS_OK == rv) {
|
|
mOwner = new pluginInstanceOwner();
|
|
if (nsnull != mOwner) {
|
|
NS_ADDREF(mOwner);
|
|
rv = mOwner->Init(this, mWindow);
|
|
}
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
#ifdef NECKO
|
|
PluginViewerImpl::StartLoad(nsIChannel* channel, nsIStreamListener*& aResult)
|
|
#else
|
|
PluginViewerImpl::StartLoad(nsIURI* aURL, const char* aContentType,
|
|
nsIStreamListener*& aResult)
|
|
#endif
|
|
{
|
|
#ifdef NECKO
|
|
NS_IF_RELEASE(mChannel);
|
|
mChannel = channel;
|
|
NS_ADDREF(mChannel);
|
|
|
|
#ifdef DEBUG
|
|
char* contentType;
|
|
mChannel->GetContentType(&contentType);
|
|
printf("PluginViewerImpl::StartLoad: content-type=%s\n", contentType);
|
|
nsCRT::free(contentType);
|
|
#endif
|
|
|
|
#else
|
|
printf("PluginViewerImpl::StartLoad: content-type=%s\n", aContentType);
|
|
|
|
NS_IF_RELEASE(mURL);
|
|
mURL = aURL;
|
|
NS_IF_ADDREF(aURL);
|
|
mContentType = aContentType;
|
|
#endif
|
|
|
|
aResult = nsnull;
|
|
|
|
// Only instantiate the plugin if our container can host it
|
|
nsIPluginHost* host;
|
|
nsresult rv = mContainer->QueryCapability(kIPluginHostIID, (void **)&host);
|
|
if (NS_OK == rv) {
|
|
nsRect r;
|
|
mWindow->GetClientBounds(r);
|
|
rv = CreatePlugin(host, nsRect(0, 0, r.width, r.height), aResult);
|
|
NS_RELEASE(host);
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
PluginViewerImpl::CreatePlugin(nsIPluginHost* aHost, const nsRect& aBounds,
|
|
nsIStreamListener*& aResult)
|
|
{
|
|
nsresult rv = NS_OK;
|
|
|
|
if (nsnull != mOwner) {
|
|
nsPluginWindow *win;
|
|
|
|
mOwner->GetWindow(win);
|
|
|
|
win->x = aBounds.x;
|
|
win->y = aBounds.y;
|
|
win->width = aBounds.width;
|
|
win->height = aBounds.height;
|
|
win->clipRect.top = aBounds.y;
|
|
win->clipRect.left = aBounds.x;
|
|
win->clipRect.bottom = aBounds.YMost();
|
|
win->clipRect.right = aBounds.XMost();
|
|
#ifdef XP_UNIX
|
|
win->ws_info = nsnull; //XXX need to figure out what this is. MMP
|
|
#endif
|
|
|
|
#ifdef NECKO
|
|
nsIURI* uri;
|
|
rv = mChannel->GetURI(&uri);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
char* spec;
|
|
rv = uri->GetSpec(&spec);
|
|
NS_RELEASE(uri);
|
|
if (NS_FAILED(rv)) return rv;
|
|
nsAutoString str(spec);
|
|
nsCRT::free(spec);
|
|
|
|
char* ct;
|
|
rv = mChannel->GetContentType(&ct);
|
|
if (NS_FAILED(rv)) return rv;
|
|
rv = aHost->InstantiateFullPagePlugin(ct, str, aResult, mOwner);
|
|
#else
|
|
PRUnichar* fullurl;
|
|
mURL->ToString(&fullurl);
|
|
char* ct = mContentType.ToNewCString();
|
|
nsAutoString str = fullurl;
|
|
rv = aHost->InstantiateFullPagePlugin(ct, str, aResult, mOwner);
|
|
delete fullurl;
|
|
#endif
|
|
delete[] ct;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Stop(void)
|
|
{
|
|
// XXX write this
|
|
return NS_OK;
|
|
}
|
|
|
|
static nsEventStatus PR_CALLBACK
|
|
HandlePluginEvent(nsGUIEvent *aEvent)
|
|
{
|
|
return nsEventStatus_eIgnore;
|
|
}
|
|
|
|
nsresult
|
|
PluginViewerImpl::MakeWindow(nsNativeWidget aParent,
|
|
nsIDeviceContext* aDeviceContext,
|
|
const nsRect& aBounds)
|
|
{
|
|
nsresult rv =
|
|
nsComponentManager::CreateInstance(kChildWindowCID, nsnull, kIWidgetIID,
|
|
(void**)&mWindow);
|
|
if (NS_OK != rv) {
|
|
return rv;
|
|
}
|
|
mWindow->Create(aParent, aBounds, HandlePluginEvent, aDeviceContext);
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::GetBounds(nsRect& aResult)
|
|
{
|
|
NS_PRECONDITION(nsnull != mWindow, "null window");
|
|
if (nsnull != mWindow) {
|
|
mWindow->GetBounds(aResult);
|
|
}
|
|
else {
|
|
aResult.SetRect(0, 0, 0, 0);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::SetBounds(const nsRect& aBounds)
|
|
{
|
|
NS_PRECONDITION(nsnull != mWindow, "null window");
|
|
if (nsnull != mWindow) {
|
|
// Don't have the widget repaint. Layout will generate repaint requests
|
|
// during reflow
|
|
nsIPluginInstance *inst;
|
|
mWindow->Resize(aBounds.x, aBounds.y, aBounds.width, aBounds.height, PR_FALSE);
|
|
if ((nsnull != mOwner) && (NS_OK == mOwner->GetInstance(inst)) && (nsnull != inst)) {
|
|
nsPluginWindow *win;
|
|
if (NS_OK == mOwner->GetWindow(win)) {
|
|
win->x = aBounds.x;
|
|
win->y = aBounds.y;
|
|
win->width = aBounds.width;
|
|
win->height = aBounds.height;
|
|
win->clipRect.top = aBounds.y;
|
|
win->clipRect.left = aBounds.x;
|
|
win->clipRect.bottom = aBounds.YMost();
|
|
win->clipRect.right = aBounds.XMost();
|
|
|
|
inst->SetWindow(win);
|
|
}
|
|
NS_RELEASE(inst);
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Move(PRInt32 aX, PRInt32 aY)
|
|
{
|
|
NS_PRECONDITION(nsnull != mWindow, "null window");
|
|
if (nsnull != mWindow) {
|
|
nsIPluginInstance *inst;
|
|
mWindow->Move(aX, aY);
|
|
if ((nsnull != mOwner) && (NS_OK == mOwner->GetInstance(inst)) && (nsnull != inst)) {
|
|
nsPluginWindow *win;
|
|
if (NS_OK == mOwner->GetWindow(win)) {
|
|
win->x = aX;
|
|
win->y = aY;
|
|
win->clipRect.bottom = (win->clipRect.bottom - win->clipRect.top) + aY;
|
|
win->clipRect.right = (win->clipRect.right - win->clipRect.left) + aX;
|
|
win->clipRect.top = aY;
|
|
win->clipRect.left = aX;
|
|
|
|
inst->SetWindow(win);
|
|
}
|
|
NS_RELEASE(inst);
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Show()
|
|
{
|
|
NS_PRECONDITION(nsnull != mWindow, "null window");
|
|
if (nsnull != mWindow) {
|
|
mWindow->Show(PR_TRUE);
|
|
}
|
|
|
|
// XXX should we call SetWindow here?
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Hide()
|
|
{
|
|
NS_PRECONDITION(nsnull != mWindow, "null window");
|
|
if (nsnull != mWindow) {
|
|
mWindow->Show(PR_FALSE);
|
|
}
|
|
|
|
// should we call SetWindow(nsnull) here?
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::Print(void)
|
|
{
|
|
// need to call the plugin from here somehow
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::PrintContent(nsIWebShell *aParent,nsIDeviceContext *aDContext)
|
|
{
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::SetEnableRendering(PRBool aOn)
|
|
{
|
|
mEnableRendering = aOn;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginViewerImpl::GetEnableRendering(PRBool* aResult)
|
|
{
|
|
NS_PRECONDITION(nsnull != aResult, "null OUT ptr");
|
|
if (aResult) {
|
|
*aResult = mEnableRendering;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
PluginViewerImpl::ForceRefresh()
|
|
{
|
|
mWindow->Invalidate(PR_TRUE);
|
|
}
|
|
|
|
#ifdef NECKO
|
|
nsresult PluginViewerImpl::GetURI(nsIURI* *aURI)
|
|
{
|
|
return mChannel->GetURI(aURI);
|
|
}
|
|
#else
|
|
nsresult PluginViewerImpl::GetURL(nsIURI *&aURL)
|
|
{
|
|
NS_IF_ADDREF(mURL);
|
|
aURL = mURL;
|
|
return NS_OK;
|
|
}
|
|
#endif
|
|
|
|
nsresult PluginViewerImpl::GetDocument(nsIDocument* *aDocument)
|
|
{
|
|
NS_IF_ADDREF(mDocument);
|
|
*aDocument = mDocument;
|
|
return NS_OK;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
PluginListener::PluginListener(PluginViewerImpl* aViewer)
|
|
{
|
|
NS_INIT_REFCNT();
|
|
mViewer = aViewer;
|
|
NS_ADDREF(aViewer);
|
|
mRefCnt = 1;
|
|
}
|
|
|
|
PluginListener::~PluginListener()
|
|
{
|
|
NS_RELEASE(mViewer);
|
|
NS_IF_RELEASE(mNextStream);
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS(PluginListener, kIStreamListenerIID)
|
|
|
|
NS_IMETHODIMP
|
|
#ifdef NECKO
|
|
PluginListener::OnStartRequest(nsIChannel* channel, nsISupports *ctxt)
|
|
#else
|
|
PluginListener::OnStartRequest(nsIURI* aURL, const char *contentType)
|
|
#endif
|
|
{
|
|
#ifdef NECKO
|
|
nsresult rv;
|
|
char* contentType = nsnull;
|
|
|
|
rv = channel->GetContentType(&contentType);
|
|
if (NS_FAILED(rv)) {
|
|
NS_RELEASE(channel);
|
|
return rv;
|
|
}
|
|
rv = mViewer->StartLoad(channel, mNextStream);
|
|
NS_RELEASE(channel);
|
|
if (NS_FAILED(rv)) return rv;
|
|
#else
|
|
mViewer->StartLoad(aURL, contentType, mNextStream);
|
|
#endif
|
|
if (nsnull == mNextStream) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
#ifdef NECKO
|
|
return mNextStream->OnStartRequest(channel, ctxt);
|
|
#else
|
|
return mNextStream->OnStartRequest(aURL, contentType);
|
|
#endif
|
|
}
|
|
|
|
#ifndef NECKO
|
|
NS_IMETHODIMP
|
|
PluginListener::OnProgress(nsIURI* aURL, PRUint32 aProgress,
|
|
PRUint32 aProgressMax)
|
|
{
|
|
if (nsnull == mNextStream) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
return mNextStream->OnProgress(aURL, aProgress, aProgressMax);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PluginListener::OnStatus(nsIURI* aURL, const PRUnichar* aMsg)
|
|
{
|
|
if (nsnull == mNextStream) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
return mNextStream->OnStatus(aURL, aMsg);
|
|
}
|
|
#endif
|
|
|
|
NS_IMETHODIMP
|
|
#ifdef NECKO
|
|
PluginListener::OnStopRequest(nsIChannel* channel, nsISupports *ctxt,
|
|
nsresult status, const PRUnichar *errorMsg)
|
|
#else
|
|
PluginListener::OnStopRequest(nsIURI* aURL, nsresult aStatus,
|
|
const PRUnichar* aMsg)
|
|
#endif
|
|
{
|
|
if (nsnull == mNextStream) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
#ifdef NECKO
|
|
return mNextStream->OnStopRequest(channel, ctxt, status, errorMsg);
|
|
#else
|
|
return mNextStream->OnStopRequest(aURL, aStatus, aMsg);
|
|
#endif
|
|
}
|
|
|
|
#ifndef NECKO
|
|
NS_IMETHODIMP
|
|
PluginListener::GetBindInfo(nsIURI* aURL, nsStreamBindingInfo* aInfo)
|
|
{
|
|
if (nsnull == mNextStream) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
return mNextStream->GetBindInfo(aURL, aInfo);
|
|
}
|
|
#endif
|
|
|
|
NS_IMETHODIMP
|
|
#ifdef NECKO
|
|
PluginListener::OnDataAvailable(nsIChannel* channel, nsISupports *ctxt,
|
|
nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count)
|
|
#else
|
|
PluginListener::OnDataAvailable(nsIURI* aURL, nsIInputStream* aStream,
|
|
PRUint32 aCount)
|
|
#endif
|
|
{
|
|
if (nsnull == mNextStream) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
#ifdef NECKO
|
|
return mNextStream->OnDataAvailable(channel, ctxt, inStr, sourceOffset, count);
|
|
#else
|
|
return mNextStream->OnDataAvailable(aURL, aStream, aCount);
|
|
#endif
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
pluginInstanceOwner :: pluginInstanceOwner()
|
|
{
|
|
NS_INIT_REFCNT();
|
|
|
|
memset(&mPluginWindow, 0, sizeof(mPluginWindow));
|
|
mInstance = nsnull;
|
|
mWindow = nsnull;
|
|
mViewer = nsnull;
|
|
}
|
|
|
|
pluginInstanceOwner :: ~pluginInstanceOwner()
|
|
{
|
|
if (nsnull != mInstance)
|
|
{
|
|
mInstance->Stop();
|
|
mInstance->Destroy();
|
|
NS_RELEASE(mInstance);
|
|
}
|
|
|
|
mWindow = nsnull;
|
|
mViewer = nsnull;
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS(pluginInstanceOwner, kIPluginInstanceOwnerIID);
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: SetInstance(nsIPluginInstance *aInstance)
|
|
{
|
|
NS_IF_RELEASE(mInstance);
|
|
mInstance = aInstance;
|
|
NS_IF_ADDREF(mInstance);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: GetInstance(nsIPluginInstance *&aInstance)
|
|
{
|
|
NS_IF_ADDREF(mInstance);
|
|
aInstance = mInstance;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: GetWindow(nsPluginWindow *&aWindow)
|
|
{
|
|
aWindow = &mPluginWindow;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: GetMode(nsPluginMode *aMode)
|
|
{
|
|
*aMode = nsPluginMode_Full;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: CreateWidget(void)
|
|
{
|
|
PRBool windowless;
|
|
|
|
if (nsnull != mInstance)
|
|
{
|
|
mInstance->GetValue(nsPluginInstanceVariable_WindowlessBool, (void *)&windowless);
|
|
|
|
if (PR_TRUE == windowless)
|
|
{
|
|
mPluginWindow.window = nsnull; //XXX this needs to be a HDC
|
|
mPluginWindow.type = nsPluginWindowType_Drawable;
|
|
}
|
|
else if (nsnull != mWindow)
|
|
{
|
|
mPluginWindow.window = (nsPluginPort *)mWindow->GetNativeData(NS_NATIVE_WINDOW);
|
|
mPluginWindow.type = nsPluginWindowType_Window;
|
|
}
|
|
else
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
else
|
|
return NS_ERROR_FAILURE;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: GetURL(const char *aURL, const char *aTarget, void *aPostData)
|
|
{
|
|
nsresult rv;
|
|
|
|
if (nsnull != mViewer)
|
|
{
|
|
nsIContentViewerContainer *cont;
|
|
|
|
rv = mViewer->GetContainer(cont);
|
|
|
|
if (NS_OK == rv)
|
|
{
|
|
nsILinkHandler *lh;
|
|
|
|
rv = cont->QueryInterface(kILinkHandlerIID, (void **)&lh);
|
|
|
|
if (NS_OK == rv)
|
|
{
|
|
#ifdef NECKO
|
|
nsIURI *uri;
|
|
rv = mViewer->GetURI(&uri);
|
|
#else
|
|
nsIURI *url;
|
|
rv = mViewer->GetURL(url);
|
|
#endif
|
|
|
|
if (NS_OK == rv)
|
|
{
|
|
// Create an absolute URL
|
|
#ifdef NECKO
|
|
char* absURIStr;
|
|
rv = NS_MakeAbsoluteURI(aURL, uri, &absURIStr);
|
|
NS_RELEASE(uri);
|
|
nsAutoString fullurl(absURIStr);
|
|
nsCRT::free(absURIStr);
|
|
#else
|
|
nsAutoString uniurl = nsAutoString(aURL);
|
|
const char* spec;
|
|
(void)url->GetSpec(&spec);
|
|
nsAutoString base = nsAutoString(spec);
|
|
nsAutoString fullurl;
|
|
rv = NS_MakeAbsoluteURL(url, base, uniurl, fullurl);
|
|
NS_RELEASE(url);
|
|
#endif
|
|
|
|
if (NS_OK == rv) {
|
|
nsAutoString unitarget = nsAutoString(aTarget);
|
|
rv = lh->OnLinkClick(nsnull, eLinkVerb_Replace, fullurl.GetUnicode(), unitarget.GetUnicode(), nsnull);
|
|
}
|
|
}
|
|
|
|
NS_RELEASE(lh);
|
|
}
|
|
|
|
NS_RELEASE(cont);
|
|
}
|
|
}
|
|
else
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: ShowStatus(const char *aStatusMsg)
|
|
{
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
|
|
if (nsnull != mViewer)
|
|
{
|
|
nsIContentViewerContainer *cont;
|
|
|
|
rv = mViewer->GetContainer(cont);
|
|
|
|
if ((NS_OK == rv) && (nsnull != cont))
|
|
{
|
|
nsIWebShell *ws;
|
|
|
|
rv = cont->QueryInterface(kIWebShellIID, (void **)&ws);
|
|
|
|
if (NS_OK == rv)
|
|
{
|
|
nsIWebShell *rootWebShell;
|
|
|
|
ws->GetRootWebShell(rootWebShell);
|
|
|
|
if (nsnull != rootWebShell)
|
|
{
|
|
nsIWebShellContainer *rootContainer;
|
|
|
|
rv = rootWebShell->GetContainer(rootContainer);
|
|
|
|
if (nsnull != rootContainer)
|
|
{
|
|
nsIBrowserWindow *browserWindow;
|
|
|
|
if (NS_OK == rootContainer->QueryInterface(kIBrowserWindowIID, (void**)&browserWindow))
|
|
{
|
|
nsAutoString msg = nsAutoString(aStatusMsg);
|
|
|
|
rv = browserWindow->SetStatus(msg.GetUnicode());
|
|
NS_RELEASE(browserWindow);
|
|
}
|
|
|
|
NS_RELEASE(rootContainer);
|
|
}
|
|
|
|
NS_RELEASE(rootWebShell);
|
|
}
|
|
|
|
NS_RELEASE(ws);
|
|
}
|
|
|
|
NS_RELEASE(cont);
|
|
}
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: GetDocument(nsIDocument* *aDocument)
|
|
{
|
|
return mViewer->GetDocument(aDocument);
|
|
}
|
|
|
|
NS_IMETHODIMP pluginInstanceOwner :: Init(PluginViewerImpl *aViewer, nsIWidget *aWindow)
|
|
{
|
|
//do not addref
|
|
mWindow = aWindow;
|
|
mViewer = aViewer;
|
|
|
|
return NS_OK;
|
|
}
|